From ee778d6eea54935fd05022e0ba8c49456003381a Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:48:24 +0100 Subject: unslug ko: move --- files/ko/web/api/ambient_light_events/index.html | 64 + files/ko/web/api/battery_status_api/index.html | 75 + .../api/broadcastchannel/message_event/index.html | 152 ++ .../api/canvas_api/a_basic_ray-caster/index.html | 53 + files/ko/web/api/canvas_api/index.html | 135 ++ .../manipulating_video_using_canvas/index.html | 164 ++ .../tutorial/advanced_animations/index.html | 376 +++++ .../tutorial/applying_styles_and_colors/index.html | 732 +++++++++ .../tutorial/basic_animations/index.html | 310 ++++ .../api/canvas_api/tutorial/basic_usage/index.html | 154 ++ .../tutorial/compositing/example/index.html | 293 ++++ .../api/canvas_api/tutorial/compositing/index.html | 106 ++ .../canvas_api/tutorial/drawing_shapes/index.html | 577 +++++++ .../canvas_api/tutorial/drawing_text/index.html | 164 ++ .../web/api/canvas_api/tutorial/finale/index.html | 51 + .../hit_regions_and_accessibility/index.html | 97 ++ files/ko/web/api/canvas_api/tutorial/index.html | 62 + .../tutorial/optimizing_canvas/index.html | 110 ++ .../canvas_api/tutorial/transformations/index.html | 286 ++++ .../canvas_api/tutorial/using_images/index.html | 347 +++++ .../index.html | 28 + .../managing_screen_orientation/index.html | 136 ++ .../api/detecting_device_orientation/index.html | 273 ++++ files/ko/web/api/document/createevent/index.html | 30 + files/ko/web/api/document/getselection/index.html | 9 - .../document_object_model/introduction/index.html | 239 +++ .../\354\206\214\352\260\234/index.html" | 239 --- .../documentorshadowroot/getselection/index.html | 9 + files/ko/web/api/element/accesskey/index.html | 35 - files/ko/web/api/element/blur_event/index.html | 154 ++ .../web/api/elementcssinlinestyle/style/index.html | 41 + files/ko/web/api/event/createevent/index.html | 30 - .../index.html" | 419 ----- files/ko/web/api/fetch_api/using_fetch/index.html | 419 +++++ files/ko/web/api/fullscreen_api/index.html | 198 +++ .../using_the_geolocation_api/index.html | 165 ++ .../drag_operations/index.html | 343 ++++ files/ko/web/api/html_drag_and_drop_api/index.html | 303 ++++ .../drag_operations/index.html" | 343 ---- .../index.html" | 303 ---- files/ko/web/api/htmlelement/accesskey/index.html | 35 + files/ko/web/api/htmlelement/dataset/index.html | 127 -- files/ko/web/api/htmlelement/innertext/index.html | 88 ++ files/ko/web/api/htmlelement/style/index.html | 41 - files/ko/web/api/htmlelement/tabindex/index.html | 26 - .../api/htmlmediaelement/abort_event/index.html | 74 + .../api/htmlorforeignelement/dataset/index.html | 127 ++ .../api/htmlorforeignelement/tabindex/index.html | 26 + files/ko/web/api/navigation_timing_api/index.html | 137 ++ files/ko/web/api/navigator/connection/index.html | 105 ++ .../ko/web/api/network_information_api/index.html | 46 + .../api/networkinformation/connection/index.html | 105 -- files/ko/web/api/node/innertext/index.html | 88 -- .../using_the_notifications_api/index.html | 265 ++++ files/ko/web/api/proximity_events/index.html | 119 ++ .../web/api/screen.onorientationchange/index.html | 85 - .../web/api/screen/onorientationchange/index.html | 85 + files/ko/web/api/streams_api/concepts/index.html | 115 ++ .../\354\273\250\354\205\211/index.html" | 115 -- files/ko/web/api/vibration_api/index.html | 100 ++ .../web/api/web_workers_api/basic_usage/index.html | 908 ----------- .../web_workers_api/using_web_workers/index.html | 908 +++++++++++ .../api/webgl_api/cross-domain_textures/index.html | 34 - files/ko/web/api/websockets_api/index.html | 172 ++ .../index.html | 191 +++ .../writing_websocket_servers/index.html | 258 +++ .../api/window/domcontentloaded_event/index.html | 77 + files/ko/web/api/window/load_event/index.html | 128 ++ .../settimeout/index.html | 429 +++++ .../ko/web/api/windowtimers/settimeout/index.html | 429 ----- files/ko/web/api/xmlhttprequest/timeout/index.html | 123 -- .../api/xmlhttprequest/timeout_event/index.html | 123 ++ .../web/api/xsltprocessor/basic_example/index.html | 49 + .../xsltprocessor/browser_differences/index.html | 8 + .../api/xsltprocessor/generating_html/index.html | 174 +++ files/ko/web/api/xsltprocessor/index.html | 15 + .../web/api/xsltprocessor/introduction/index.html | 13 + .../ko/web/api/xsltprocessor/resources/index.html | 14 + files/ko/web/css/@viewport/height/index.html | 76 - files/ko/web/css/@viewport/viewport-fit/index.html | 73 - files/ko/web/css/@viewport/zoom/index.html | 71 - .../web/css/adjacent_sibling_combinator/index.html | 83 + .../css/all_about_the_containing_block/index.html | 263 ---- files/ko/web/css/common_css_questions/index.html | 199 --- files/ko/web/css/containing_block/index.html | 263 ++++ .../using_css_multiple_backgrounds/index.html | 56 - .../resizing_background_images/index.html | 137 ++ .../scaling_background_images/index.html | 137 -- .../index.html | 70 + .../using_multi-column_layouts/index.html | 204 +++ .../basic_concepts_of_flexbox/index.html | 236 +++ .../index.html" | 236 --- .../typical_use_cases_of_flexbox/index.html | 141 ++ .../index.html" | 141 -- .../index.html | 122 ++ .../flow_layout_and_overflow/index.html | 73 + .../flow_layout_and_writing_modes/index.html | 92 ++ .../in_flow_and_out_of_flow/index.html | 72 + .../index.html" | 72 - .../index.html" | 122 -- .../index.html" | 92 -- .../index.html" | 73 - .../consistent_list_indentation/index.html | 106 ++ files/ko/web/css/css_masking/index.html | 68 + files/ko/web/css/css_masks/index.html | 68 - files/ko/web/css/css_values_and_units/index.html | 497 ++++++ .../index.html" | 497 ------ .../index.html | 70 - .../web/css/getting_started/javascript/index.html | 145 -- .../css/getting_started/svg_graphics/index.html | 195 --- files/ko/web/css/index/index.html | 10 - .../media_queries/using_media_queries/index.html | 386 +++++ .../web/css/reference/property_template/index.html | 131 -- files/ko/web/css/url()/index.html | 80 + files/ko/web/css/url/index.html | 80 - .../ko/web/css/visual_formatting_model/index.html | 223 +++ .../index.html" | 245 --- .../index.html" | 346 ---- .../\353\260\260\354\271\230/index.html" | 370 ----- .../\354\203\201\354\236\220/index.html" | 331 ---- .../index.html" | 127 -- .../index.html" | 475 ------ .../index.html" | 150 -- .../index.html" | 83 - files/ko/web/events/abort/index.html | 74 - files/ko/web/events/blur/index.html | 154 -- files/ko/web/events/domcontentloaded/index.html | 77 - files/ko/web/events/load/index.html | 128 -- files/ko/web/events/message/index.html | 152 -- .../web/guide/api/vibration/vibration/index.html | 100 -- files/ko/web/guide/css/media_queries/index.html | 386 ----- .../guide/css/visual_formatting_model/index.html | 223 --- files/ko/web/guide/dom/index.html | 22 - .../guide/dom/using_full_screen_mode/index.html | 198 --- files/ko/web/guide/graphics/index.html | 48 + .../ko/web/guide/html/content_editable/index.html | 65 - .../ko/web/guide/html/editable_content/index.html | 65 + files/ko/web/guide/html/html5/index.html | 122 ++ .../html/html5/introduction_to_html5/index.html | 40 + .../using_html_sections_and_outlines/index.html | 367 +++++ .../guide/parsing_and_serializing_xml/index.html | 141 ++ .../index.html" | 141 -- .../index.html" | 48 - files/ko/web/html/canvas/index.html | 135 -- .../manipulating_video_using_canvas/index.html | 164 -- .../canvas/tutorial/advanced_animations/index.html | 376 ----- .../tutorial/applying_styles_and_colors/index.html | 732 --------- .../canvas/tutorial/basic_animations/index.html | 310 ---- .../html/canvas/tutorial/basic_usage/index.html | 154 -- .../canvas/tutorial/compositing/example/index.html | 293 ---- .../html/canvas/tutorial/compositing/index.html | 106 -- .../html/canvas/tutorial/drawing_shapes/index.html | 577 ------- .../ko/web/html/canvas/tutorial/finale/index.html | 51 - .../hit_regions_and_accessibility/index.html | 97 -- files/ko/web/html/canvas/tutorial/index.html | 62 - .../canvas/tutorial/optimizing_canvas/index.html | 110 -- .../html/canvas/tutorial/using_images/index.html | 347 ----- .../tutorial/\353\263\200\355\230\225/index.html" | 286 ---- files/ko/web/html/element/command/index.html | 111 -- files/ko/web/html/element/element/index.html | 57 - .../ko/web/html/global_attributes/class/index.html | 64 + .../web/html/global_attributes/dropzone/index.html | 53 - .../index.html" | 64 - files/ko/web/html/html5/index.html | 122 -- .../html/html5/introduction_to_html5/index.html | 40 - .../index.html" | 367 ----- .../index.html | 296 ++++ .../index.html" | 296 ---- .../a_re-introduction_to_javascript/index.html | 1038 ++++++++++++ files/ko/web/javascript/about/index.html | 58 - .../ko/web/javascript/about_javascript/index.html | 58 + files/ko/web/javascript/closures/index.html | 454 ++++++ .../index.html | 63 - files/ko/web/javascript/guide/closures/index.html | 454 ------ .../guide/details_of_the_object_model/index.html | 714 +++++++++ files/ko/web/javascript/guide/functions/index.html | 658 ++++++++ .../javascript/guide/grammar_and_types/index.html | 708 +++++++++ .../inheritance_and_the_prototype_chain/index.html | 531 ------- .../web/javascript/guide/introduction/index.html | 153 ++ .../javascript/guide/meta_programming/index.html | 258 +++ .../core_javascript_1.5_guide/about/index.html | 109 -- .../index.html | 26 - .../core_javascript_1.5_guide/constants/index.html | 29 - .../creating_a_regular_expression/index.html | 35 - .../defining_getters_and_setters/index.html | 84 - .../defining_methods/index.html | 43 - .../index.html | 11 - .../deleting_properties/index.html | 20 - .../creating_new_objects/index.html | 6 - .../indexing_object_properties/index.html | 9 - .../using_a_constructor_function/index.html | 58 - .../using_this_for_object_references/index.html | 25 - .../expressions/index.html | 16 - .../javascript_overview/index.html | 44 - .../core_javascript_1.5_guide/literals/index.html | 175 --- .../objects_and_properties/index.html | 39 - .../operators/arithmetic_operators/index.html | 45 - .../operators/assignment_operators/index.html | 62 - .../operators/bitwise_operators/index.html | 102 -- .../core_javascript_1.5_guide/operators/index.html | 108 -- .../operators/logical_operators/index.html | 69 - .../operators/special_operators/index.html | 229 --- .../operators/string_operators/index.html | 12 - .../array_object/index.html | 133 -- .../predefined_core_objects/index.html | 21 - .../core_javascript_1.5_guide/unicode/index.html | 110 -- .../core_javascript_1.5_guide/values/index.html | 40 - .../core_javascript_1.5_guide/variables/index.html | 65 - .../regular_expressions/assertions/index.html | 244 +++ .../groups_and_ranges/index.html | 91 ++ .../guide/regular_expressions/index.html | 666 ++++++++ .../values,_variables,_and_literals/index.html | 708 --------- .../index.html" | 714 --------- .../index.html" | 258 --- .../guide/\354\206\214\352\260\234/index.html" | 153 -- .../assertions/index.html" | 244 --- .../groups_and_ranges/index.html" | 91 -- .../index.html" | 666 -------- .../guide/\355\225\250\354\210\230/index.html" | 658 -------- .../inheritance_and_the_prototype_chain/index.html | 531 +++++++ .../index.html | 290 ---- .../web/javascript/language_resources/index.html | 155 ++ .../reference/classes/class_fields/index.html | 396 ----- .../classes/public_class_fields/index.html | 396 +++++ .../reference/functions/arrow_functions/index.html | 465 ++++++ .../index.html" | 465 ------ .../global_objects/bigint/prototype/index.html | 59 - .../global_objects/boolean/prototype/index.html | 82 - .../global_objects/date/prototype/index.html | 183 --- .../internalerror/prototype/index.html | 101 -- .../intl/datetimeformat/prototype/index.html | 87 -- .../intl/numberformat/prototype/index.html | 86 - .../global_objects/map/prototype/index.html | 87 -- .../global_objects/number/prototype/index.html | 91 -- .../global_objects/object/prototype/index.html | 219 --- .../global_objects/promise/prototype/index.html | 72 - .../global_objects/proxy/handler/apply/index.html | 154 -- .../global_objects/proxy/handler/index.html | 82 - .../global_objects/proxy/proxy/apply/index.html | 154 ++ .../global_objects/proxy/proxy/index.html | 82 + .../global_objects/set/prototype/index.html | 87 -- .../sharedarraybuffer/prototype/index.html | 66 - .../global_objects/string/prototype/index.html | 219 --- .../syntaxerror/prototype/index.html | 127 -- .../global_objects/typedarray/prototype/index.html | 176 --- .../global_objects/weakmap/prototype/index.html | 143 -- .../global_objects/weakset/prototype/index.html | 142 -- .../webassembly/global/prototype/index.html | 70 - .../operators/arithmetic_operators/index.html | 291 ---- .../operators/assignment_operators/index.html | 395 ----- .../operators/bitwise_operators/index.html | 541 ------- .../operators/comparison_operators/index.html | 216 --- .../operators/operator_precedence/index.html | 462 ++++++ .../index.html" | 250 --- .../index.html" | 462 ------ .../reference/statements/default/index.html | 122 -- files/ko/web/javascript/shells/index.html | 40 + "files/ko/web/javascript/\354\211\230/index.html" | 40 - .../index.html" | 328 ---- .../index.html" | 155 -- .../web/media/formats/codecs_parameter/index.html | 971 ++++++++++++ files/ko/web/media/formats/containers/index.html | 1279 +++++++++++++++ files/ko/web/media/formats/video_codecs/index.html | 1646 ++++++++++++++++++++ .../index.html" | 1646 -------------------- .../index.html" | 1279 --------------- .../index.html" | 971 ------------ .../performance/critical_rendering_path/index.html | 60 + .../web/performance/how_browsers_work/index.html | 204 +++ .../index.html" | 204 --- .../index.html" | 60 - .../progressive_web_apps/introduction/index.html | 92 ++ .../responsive/media_types/index.html | 346 ++++ .../\354\206\214\352\260\234/index.html" | 92 -- files/ko/web/reference/api/index.html | 65 + files/ko/web/reference/index.html | 30 + .../index.html" | 28 - files/ko/web/svg/element/rect/index.html | 95 ++ .../index.html" | 95 -- .../web/svg/svg_1.1_support_in_firefox/index.html | 845 ++++++++++ files/ko/web/svg/tutorial/basic_shapes/index.html | 141 ++ .../ko/web/svg/tutorial/getting_started/index.html | 94 ++ files/ko/web/svg/tutorial/positions/index.html | 45 + files/ko/web/svg/tutorial/svg_and_css/index.html | 195 +++ .../index.html" | 141 -- .../index.html" | 94 -- .../tutorial/\354\234\204\354\271\230/index.html" | 45 - .../index.html | 367 +++++ files/ko/web/xslt/apply-imports/index.html | 22 - files/ko/web/xslt/apply-templates/index.html | 33 - files/ko/web/xslt/attribute-set/index.html | 33 - files/ko/web/xslt/attribute/index.html | 33 - files/ko/web/xslt/call-template/index.html | 29 - files/ko/web/xslt/choose/index.html | 24 - files/ko/web/xslt/comment/index.html | 23 - files/ko/web/xslt/copy-of/index.html | 26 - files/ko/web/xslt/copy/index.html | 28 - files/ko/web/xslt/decimal-format/index.html | 100 -- files/ko/web/xslt/element/apply-imports/index.html | 22 + .../ko/web/xslt/element/apply-templates/index.html | 33 + files/ko/web/xslt/element/attribute-set/index.html | 33 + files/ko/web/xslt/element/attribute/index.html | 33 + files/ko/web/xslt/element/call-template/index.html | 29 + files/ko/web/xslt/element/choose/index.html | 24 + files/ko/web/xslt/element/comment/index.html | 23 + files/ko/web/xslt/element/copy-of/index.html | 26 + files/ko/web/xslt/element/copy/index.html | 28 + .../ko/web/xslt/element/decimal-format/index.html | 100 ++ files/ko/web/xslt/element/fallback/index.html | 23 + files/ko/web/xslt/element/for-each/index.html | 29 + files/ko/web/xslt/element/if/index.html | 28 + files/ko/web/xslt/element/import/index.html | 26 + files/ko/web/xslt/element/include/index.html | 26 + files/ko/web/xslt/element/key/index.html | 35 + files/ko/web/xslt/element/message/index.html | 28 + .../ko/web/xslt/element/namespace-alias/index.html | 30 + files/ko/web/xslt/element/number/index.html | 173 ++ files/ko/web/xslt/element/otherwise/index.html | 23 + files/ko/web/xslt/element/output/index.html | 90 ++ files/ko/web/xslt/element/param/index.html | 33 + .../ko/web/xslt/element/preserve-space/index.html | 26 + .../xslt/element/processing-instruction/index.html | 26 + files/ko/web/xslt/element/sort/index.html | 55 + files/ko/web/xslt/element/strip-space/index.html | 26 + files/ko/web/xslt/element/stylesheet/index.html | 52 + files/ko/web/xslt/element/template/index.html | 51 + files/ko/web/xslt/element/text/index.html | 28 + files/ko/web/xslt/element/transform/index.html | 11 + files/ko/web/xslt/element/value-of/index.html | 31 + files/ko/web/xslt/element/variable/index.html | 33 + files/ko/web/xslt/element/when/index.html | 28 + files/ko/web/xslt/element/with-param/index.html | 33 + files/ko/web/xslt/fallback/index.html | 23 - files/ko/web/xslt/for-each/index.html | 29 - files/ko/web/xslt/if/index.html | 28 - files/ko/web/xslt/import/index.html | 26 - files/ko/web/xslt/include/index.html | 26 - files/ko/web/xslt/key/index.html | 35 - files/ko/web/xslt/message/index.html | 28 - files/ko/web/xslt/namespace-alias/index.html | 30 - files/ko/web/xslt/number/index.html | 173 -- files/ko/web/xslt/otherwise/index.html | 23 - files/ko/web/xslt/output/index.html | 90 -- files/ko/web/xslt/param/index.html | 33 - files/ko/web/xslt/preserve-space/index.html | 26 - .../ko/web/xslt/processing-instruction/index.html | 26 - files/ko/web/xslt/sort/index.html | 55 - files/ko/web/xslt/strip-space/index.html | 26 - files/ko/web/xslt/stylesheet/index.html | 52 - files/ko/web/xslt/template/index.html | 51 - files/ko/web/xslt/text/index.html | 28 - .../index.html | 17 - .../introduction/index.html | 10 - .../setting_parameters/index.html | 23 - files/ko/web/xslt/transform/index.html | 11 - files/ko/web/xslt/value-of/index.html | 31 - files/ko/web/xslt/variable/index.html | 33 - files/ko/web/xslt/when/index.html | 28 - files/ko/web/xslt/with-param/index.html | 33 - .../web/xslt/xslt_js_interface_in_gecko/index.html | 17 + .../introduction/index.html | 10 + .../setting_parameters/index.html | 23 + .../web/\354\260\270\354\241\260/api/index.html" | 65 - "files/ko/web/\354\260\270\354\241\260/index.html" | 30 - 363 files changed, 29670 insertions(+), 33773 deletions(-) create mode 100644 files/ko/web/api/ambient_light_events/index.html create mode 100644 files/ko/web/api/battery_status_api/index.html create mode 100644 files/ko/web/api/broadcastchannel/message_event/index.html create mode 100644 files/ko/web/api/canvas_api/a_basic_ray-caster/index.html create mode 100644 files/ko/web/api/canvas_api/index.html create mode 100644 files/ko/web/api/canvas_api/manipulating_video_using_canvas/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/advanced_animations/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/basic_animations/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/basic_usage/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/compositing/example/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/compositing/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/drawing_shapes/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/drawing_text/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/finale/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/hit_regions_and_accessibility/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/optimizing_canvas/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/transformations/index.html create mode 100644 files/ko/web/api/canvas_api/tutorial/using_images/index.html create mode 100644 files/ko/web/api/css_object_model/determining_the_dimensions_of_elements/index.html create mode 100644 files/ko/web/api/css_object_model/managing_screen_orientation/index.html create mode 100644 files/ko/web/api/detecting_device_orientation/index.html create mode 100644 files/ko/web/api/document/createevent/index.html delete mode 100644 files/ko/web/api/document/getselection/index.html create mode 100644 files/ko/web/api/document_object_model/introduction/index.html delete mode 100644 "files/ko/web/api/document_object_model/\354\206\214\352\260\234/index.html" create mode 100644 files/ko/web/api/documentorshadowroot/getselection/index.html delete mode 100644 files/ko/web/api/element/accesskey/index.html create mode 100644 files/ko/web/api/element/blur_event/index.html create mode 100644 files/ko/web/api/elementcssinlinestyle/style/index.html delete mode 100644 files/ko/web/api/event/createevent/index.html delete mode 100644 "files/ko/web/api/fetch_api/fetch\354\235\230_\354\202\254\354\232\251\353\262\225/index.html" create mode 100644 files/ko/web/api/fetch_api/using_fetch/index.html create mode 100644 files/ko/web/api/fullscreen_api/index.html create mode 100644 files/ko/web/api/geolocation_api/using_the_geolocation_api/index.html create mode 100644 files/ko/web/api/html_drag_and_drop_api/drag_operations/index.html create mode 100644 files/ko/web/api/html_drag_and_drop_api/index.html delete mode 100644 "files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/drag_operations/index.html" delete mode 100644 "files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/index.html" create mode 100644 files/ko/web/api/htmlelement/accesskey/index.html delete mode 100644 files/ko/web/api/htmlelement/dataset/index.html create mode 100644 files/ko/web/api/htmlelement/innertext/index.html delete mode 100644 files/ko/web/api/htmlelement/style/index.html delete mode 100644 files/ko/web/api/htmlelement/tabindex/index.html create mode 100644 files/ko/web/api/htmlmediaelement/abort_event/index.html create mode 100644 files/ko/web/api/htmlorforeignelement/dataset/index.html create mode 100644 files/ko/web/api/htmlorforeignelement/tabindex/index.html create mode 100644 files/ko/web/api/navigation_timing_api/index.html create mode 100644 files/ko/web/api/navigator/connection/index.html create mode 100644 files/ko/web/api/network_information_api/index.html delete mode 100644 files/ko/web/api/networkinformation/connection/index.html delete mode 100644 files/ko/web/api/node/innertext/index.html create mode 100644 files/ko/web/api/notifications_api/using_the_notifications_api/index.html create mode 100644 files/ko/web/api/proximity_events/index.html delete mode 100644 files/ko/web/api/screen.onorientationchange/index.html create mode 100644 files/ko/web/api/screen/onorientationchange/index.html create mode 100644 files/ko/web/api/streams_api/concepts/index.html delete mode 100644 "files/ko/web/api/streams_api/\354\273\250\354\205\211/index.html" create mode 100644 files/ko/web/api/vibration_api/index.html delete mode 100644 files/ko/web/api/web_workers_api/basic_usage/index.html create mode 100644 files/ko/web/api/web_workers_api/using_web_workers/index.html delete mode 100644 files/ko/web/api/webgl_api/cross-domain_textures/index.html create mode 100644 files/ko/web/api/websockets_api/index.html create mode 100644 files/ko/web/api/websockets_api/writing_websocket_client_applications/index.html create mode 100644 files/ko/web/api/websockets_api/writing_websocket_servers/index.html create mode 100644 files/ko/web/api/window/domcontentloaded_event/index.html create mode 100644 files/ko/web/api/window/load_event/index.html create mode 100644 files/ko/web/api/windoworworkerglobalscope/settimeout/index.html delete mode 100644 files/ko/web/api/windowtimers/settimeout/index.html delete mode 100644 files/ko/web/api/xmlhttprequest/timeout/index.html create mode 100644 files/ko/web/api/xmlhttprequest/timeout_event/index.html create mode 100644 files/ko/web/api/xsltprocessor/basic_example/index.html create mode 100644 files/ko/web/api/xsltprocessor/browser_differences/index.html create mode 100644 files/ko/web/api/xsltprocessor/generating_html/index.html create mode 100644 files/ko/web/api/xsltprocessor/index.html create mode 100644 files/ko/web/api/xsltprocessor/introduction/index.html create mode 100644 files/ko/web/api/xsltprocessor/resources/index.html delete mode 100644 files/ko/web/css/@viewport/height/index.html delete mode 100644 files/ko/web/css/@viewport/viewport-fit/index.html delete mode 100644 files/ko/web/css/@viewport/zoom/index.html create mode 100644 files/ko/web/css/adjacent_sibling_combinator/index.html delete mode 100644 files/ko/web/css/all_about_the_containing_block/index.html delete mode 100644 files/ko/web/css/common_css_questions/index.html create mode 100644 files/ko/web/css/containing_block/index.html delete mode 100644 files/ko/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html create mode 100644 files/ko/web/css/css_backgrounds_and_borders/resizing_background_images/index.html delete mode 100644 files/ko/web/css/css_backgrounds_and_borders/scaling_background_images/index.html create mode 100644 files/ko/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html create mode 100644 files/ko/web/css/css_columns/using_multi-column_layouts/index.html create mode 100644 files/ko/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html delete mode 100644 "files/ko/web/css/css_flexible_box_layout/flexbox\354\235\230_\352\270\260\353\263\270_\352\260\234\353\205\220/index.html" create mode 100644 files/ko/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html delete mode 100644 "files/ko/web/css/css_flexible_box_layout/\352\260\200\353\263\200\354\203\201\354\236\220\354\235\230_\353\214\200\355\221\234\354\240\201\354\235\270_\354\202\254\354\232\251\353\241\200/index.html" create mode 100644 files/ko/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html create mode 100644 files/ko/web/css/css_flow_layout/flow_layout_and_overflow/index.html create mode 100644 files/ko/web/css/css_flow_layout/flow_layout_and_writing_modes/index.html create mode 100644 files/ko/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html delete mode 100644 "files/ko/web/css/css_flow_layout/\353\214\200\354\227\264\352\263\274_\355\203\210\353\214\200\354\227\264/index.html" delete mode 100644 "files/ko/web/css/css_flow_layout/\354\235\274\353\260\230_\355\235\220\353\246\204_\354\206\215_\353\270\224\353\241\235_\353\260\217_\354\235\270\353\235\274\354\235\270_\353\240\210\354\235\264\354\225\204\354\233\203/index.html" delete mode 100644 "files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\223\260\352\270\260_\353\252\250\353\223\234/index.html" delete mode 100644 "files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\230\244\353\262\204\355\224\214\353\241\234/index.html" create mode 100644 files/ko/web/css/css_lists_and_counters/consistent_list_indentation/index.html create mode 100644 files/ko/web/css/css_masking/index.html delete mode 100644 files/ko/web/css/css_masks/index.html create mode 100644 files/ko/web/css/css_values_and_units/index.html delete mode 100644 "files/ko/web/css/css_\353\213\250\354\234\204\354\231\200_\352\260\222/index.html" delete mode 100644 files/ko/web/css/cursor/using_url_values_for_the_cursor_property/index.html delete mode 100644 files/ko/web/css/getting_started/javascript/index.html delete mode 100644 files/ko/web/css/getting_started/svg_graphics/index.html delete mode 100644 files/ko/web/css/index/index.html create mode 100644 files/ko/web/css/media_queries/using_media_queries/index.html delete mode 100644 files/ko/web/css/reference/property_template/index.html create mode 100644 files/ko/web/css/url()/index.html delete mode 100644 files/ko/web/css/url/index.html create mode 100644 files/ko/web/css/visual_formatting_model/index.html delete mode 100644 "files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\246\254\354\212\244\355\212\270/index.html" delete mode 100644 "files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\257\270\353\224\224\354\226\264/index.html" delete mode 100644 "files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\260\260\354\271\230/index.html" delete mode 100644 "files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\203\201\354\236\220/index.html" delete mode 100644 "files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\242\205\354\206\215\352\263\274_\354\203\201\354\206\215/index.html" delete mode 100644 "files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\214\354\235\264\353\270\224/index.html" delete mode 100644 "files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\215\354\212\244\355\212\270_\354\212\244\355\203\200\354\235\274/index.html" delete mode 100644 "files/ko/web/css/\354\235\270\354\240\221_\355\230\225\354\240\234_\354\204\240\355\203\235\354\236\220/index.html" delete mode 100644 files/ko/web/events/abort/index.html delete mode 100644 files/ko/web/events/blur/index.html delete mode 100644 files/ko/web/events/domcontentloaded/index.html delete mode 100644 files/ko/web/events/load/index.html delete mode 100644 files/ko/web/events/message/index.html delete mode 100644 files/ko/web/guide/api/vibration/vibration/index.html delete mode 100644 files/ko/web/guide/css/media_queries/index.html delete mode 100644 files/ko/web/guide/css/visual_formatting_model/index.html delete mode 100644 files/ko/web/guide/dom/index.html delete mode 100644 files/ko/web/guide/dom/using_full_screen_mode/index.html create mode 100644 files/ko/web/guide/graphics/index.html delete mode 100644 files/ko/web/guide/html/content_editable/index.html create mode 100644 files/ko/web/guide/html/editable_content/index.html create mode 100644 files/ko/web/guide/html/html5/index.html create mode 100644 files/ko/web/guide/html/html5/introduction_to_html5/index.html create mode 100644 files/ko/web/guide/html/using_html_sections_and_outlines/index.html create mode 100644 files/ko/web/guide/parsing_and_serializing_xml/index.html delete mode 100644 "files/ko/web/guide/xml_\355\214\214\354\213\261_\353\260\217_\354\247\201\353\240\254\355\231\224/index.html" delete mode 100644 "files/ko/web/guide/\352\267\270\353\236\230\355\224\275/index.html" delete mode 100644 files/ko/web/html/canvas/index.html delete mode 100644 files/ko/web/html/canvas/manipulating_video_using_canvas/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/advanced_animations/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/applying_styles_and_colors/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/basic_animations/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/basic_usage/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/compositing/example/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/compositing/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/drawing_shapes/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/finale/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/hit_regions_and_accessibility/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/optimizing_canvas/index.html delete mode 100644 files/ko/web/html/canvas/tutorial/using_images/index.html delete mode 100644 "files/ko/web/html/canvas/tutorial/\353\263\200\355\230\225/index.html" delete mode 100644 files/ko/web/html/element/command/index.html delete mode 100644 files/ko/web/html/element/element/index.html create mode 100644 files/ko/web/html/global_attributes/class/index.html delete mode 100644 files/ko/web/html/global_attributes/dropzone/index.html delete mode 100644 "files/ko/web/html/global_attributes/\355\201\264\353\236\230\354\212\244/index.html" delete mode 100644 files/ko/web/html/html5/index.html delete mode 100644 files/ko/web/html/html5/introduction_to_html5/index.html delete mode 100644 "files/ko/web/html/html5_\353\254\270\354\204\234\354\235\230_\354\204\271\354\205\230\352\263\274_\354\234\244\352\263\275/index.html" create mode 100644 files/ko/web/http/browser_detection_using_the_user_agent/index.html delete mode 100644 "files/ko/web/http/user_agent\353\245\274_\354\235\264\354\232\251\355\225\234_\353\270\214\353\235\274\354\232\260\354\240\200_\352\260\220\354\247\200/index.html" create mode 100644 files/ko/web/javascript/a_re-introduction_to_javascript/index.html delete mode 100644 files/ko/web/javascript/about/index.html create mode 100644 files/ko/web/javascript/about_javascript/index.html create mode 100644 files/ko/web/javascript/closures/index.html delete mode 100644 files/ko/web/javascript/differential_inheritance_in_javascript/index.html delete mode 100644 files/ko/web/javascript/guide/closures/index.html create mode 100644 files/ko/web/javascript/guide/details_of_the_object_model/index.html create mode 100644 files/ko/web/javascript/guide/functions/index.html create mode 100644 files/ko/web/javascript/guide/grammar_and_types/index.html delete mode 100644 files/ko/web/javascript/guide/inheritance_and_the_prototype_chain/index.html create mode 100644 files/ko/web/javascript/guide/introduction/index.html create mode 100644 files/ko/web/javascript/guide/meta_programming/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/about/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/class-based_vs._prototype-based_languages/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/constants/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_a_regular_expression/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_getters_and_setters/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_methods/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_properties_for_an_object_type/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/deleting_properties/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/indexing_object_properties/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_a_constructor_function/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_this_for_object_references/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/expressions/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/javascript_overview/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/literals/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/objects_and_properties/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/arithmetic_operators/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/assignment_operators/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/bitwise_operators/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/logical_operators/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/special_operators/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/string_operators/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/array_object/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/unicode/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/values/index.html delete mode 100644 files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/variables/index.html create mode 100644 files/ko/web/javascript/guide/regular_expressions/assertions/index.html create mode 100644 files/ko/web/javascript/guide/regular_expressions/groups_and_ranges/index.html create mode 100644 files/ko/web/javascript/guide/regular_expressions/index.html delete mode 100644 files/ko/web/javascript/guide/values,_variables,_and_literals/index.html delete mode 100644 "files/ko/web/javascript/guide/\352\260\235\354\262\264_\353\252\250\353\215\270\354\235\230_\354\204\270\353\266\200\354\202\254\355\225\255/index.html" delete mode 100644 "files/ko/web/javascript/guide/\353\251\224\355\203\200_\355\224\204\353\241\234\352\267\270\353\236\230\353\260\215/index.html" delete mode 100644 "files/ko/web/javascript/guide/\354\206\214\352\260\234/index.html" delete mode 100644 "files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/assertions/index.html" delete mode 100644 "files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/groups_and_ranges/index.html" delete mode 100644 "files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/index.html" delete mode 100644 "files/ko/web/javascript/guide/\355\225\250\354\210\230/index.html" create mode 100644 files/ko/web/javascript/inheritance_and_the_prototype_chain/index.html delete mode 100644 files/ko/web/javascript/introduction_to_object-oriented_javascript/index.html create mode 100644 files/ko/web/javascript/language_resources/index.html delete mode 100644 files/ko/web/javascript/reference/classes/class_fields/index.html create mode 100644 files/ko/web/javascript/reference/classes/public_class_fields/index.html create mode 100644 files/ko/web/javascript/reference/functions/arrow_functions/index.html delete mode 100644 "files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" delete mode 100644 files/ko/web/javascript/reference/global_objects/bigint/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/boolean/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/date/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/internalerror/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/map/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/number/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/object/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/promise/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/proxy/handler/apply/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/proxy/handler/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/proxy/proxy/apply/index.html create mode 100644 files/ko/web/javascript/reference/global_objects/proxy/proxy/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/set/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/string/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/syntaxerror/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/typedarray/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/weakmap/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/weakset/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/global_objects/webassembly/global/prototype/index.html delete mode 100644 files/ko/web/javascript/reference/operators/arithmetic_operators/index.html delete mode 100644 files/ko/web/javascript/reference/operators/assignment_operators/index.html delete mode 100644 files/ko/web/javascript/reference/operators/bitwise_operators/index.html delete mode 100644 files/ko/web/javascript/reference/operators/comparison_operators/index.html create mode 100644 files/ko/web/javascript/reference/operators/operator_precedence/index.html delete mode 100644 "files/ko/web/javascript/reference/operators/\353\205\274\353\246\254_\354\227\260\354\202\260\354\236\220(logical_operators)/index.html" delete mode 100644 "files/ko/web/javascript/reference/operators/\354\227\260\354\202\260\354\236\220_\354\232\260\354\204\240\354\210\234\354\234\204/index.html" delete mode 100644 files/ko/web/javascript/reference/statements/default/index.html create mode 100644 files/ko/web/javascript/shells/index.html delete mode 100644 "files/ko/web/javascript/\354\211\230/index.html" delete mode 100644 "files/ko/web/javascript/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" delete mode 100644 "files/ko/web/javascript/\354\226\270\354\226\264_\353\246\254\354\206\214\354\212\244/index.html" create mode 100644 files/ko/web/media/formats/codecs_parameter/index.html create mode 100644 files/ko/web/media/formats/containers/index.html create mode 100644 files/ko/web/media/formats/video_codecs/index.html delete mode 100644 "files/ko/web/media/formats/\353\271\204\353\224\224\354\230\244\354\275\224\353\215\261/index.html" delete mode 100644 "files/ko/web/media/formats/\354\273\250\355\205\214\354\235\264\353\204\210/index.html" delete mode 100644 "files/ko/web/media/formats/\354\275\224\353\215\261\355\214\214\353\235\274\353\257\270\355\204\260/index.html" create mode 100644 files/ko/web/performance/critical_rendering_path/index.html create mode 100644 files/ko/web/performance/how_browsers_work/index.html delete mode 100644 "files/ko/web/performance/\353\270\214\353\235\274\354\232\260\354\240\200\353\212\224_\354\226\264\353\226\273\352\262\214_\353\217\231\354\236\221\355\225\230\353\212\224\352\260\200/index.html" delete mode 100644 "files/ko/web/performance/\354\244\221\354\232\224_\353\240\214\353\215\224\353\247\201_\352\262\275\353\241\234/index.html" create mode 100644 files/ko/web/progressive_web_apps/introduction/index.html create mode 100644 files/ko/web/progressive_web_apps/responsive/media_types/index.html delete mode 100644 "files/ko/web/progressive_web_apps/\354\206\214\352\260\234/index.html" create mode 100644 files/ko/web/reference/api/index.html create mode 100644 files/ko/web/reference/index.html delete mode 100644 "files/ko/web/security/\354\240\225\353\263\264_\353\263\264\354\225\210_\352\270\260\353\263\270/index.html" create mode 100644 files/ko/web/svg/element/rect/index.html delete mode 100644 "files/ko/web/svg/element/\354\202\254\352\260\201\355\230\225/index.html" create mode 100644 files/ko/web/svg/svg_1.1_support_in_firefox/index.html create mode 100644 files/ko/web/svg/tutorial/basic_shapes/index.html create mode 100644 files/ko/web/svg/tutorial/getting_started/index.html create mode 100644 files/ko/web/svg/tutorial/positions/index.html create mode 100644 files/ko/web/svg/tutorial/svg_and_css/index.html delete mode 100644 "files/ko/web/svg/tutorial/\352\270\260\353\263\270_\353\217\204\355\230\225/index.html" delete mode 100644 "files/ko/web/svg/tutorial/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" delete mode 100644 "files/ko/web/svg/tutorial/\354\234\204\354\271\230/index.html" create mode 100644 files/ko/web/xpath/introduction_to_using_xpath_in_javascript/index.html delete mode 100644 files/ko/web/xslt/apply-imports/index.html delete mode 100644 files/ko/web/xslt/apply-templates/index.html delete mode 100644 files/ko/web/xslt/attribute-set/index.html delete mode 100644 files/ko/web/xslt/attribute/index.html delete mode 100644 files/ko/web/xslt/call-template/index.html delete mode 100644 files/ko/web/xslt/choose/index.html delete mode 100644 files/ko/web/xslt/comment/index.html delete mode 100644 files/ko/web/xslt/copy-of/index.html delete mode 100644 files/ko/web/xslt/copy/index.html delete mode 100644 files/ko/web/xslt/decimal-format/index.html create mode 100644 files/ko/web/xslt/element/apply-imports/index.html create mode 100644 files/ko/web/xslt/element/apply-templates/index.html create mode 100644 files/ko/web/xslt/element/attribute-set/index.html create mode 100644 files/ko/web/xslt/element/attribute/index.html create mode 100644 files/ko/web/xslt/element/call-template/index.html create mode 100644 files/ko/web/xslt/element/choose/index.html create mode 100644 files/ko/web/xslt/element/comment/index.html create mode 100644 files/ko/web/xslt/element/copy-of/index.html create mode 100644 files/ko/web/xslt/element/copy/index.html create mode 100644 files/ko/web/xslt/element/decimal-format/index.html create mode 100644 files/ko/web/xslt/element/fallback/index.html create mode 100644 files/ko/web/xslt/element/for-each/index.html create mode 100644 files/ko/web/xslt/element/if/index.html create mode 100644 files/ko/web/xslt/element/import/index.html create mode 100644 files/ko/web/xslt/element/include/index.html create mode 100644 files/ko/web/xslt/element/key/index.html create mode 100644 files/ko/web/xslt/element/message/index.html create mode 100644 files/ko/web/xslt/element/namespace-alias/index.html create mode 100644 files/ko/web/xslt/element/number/index.html create mode 100644 files/ko/web/xslt/element/otherwise/index.html create mode 100644 files/ko/web/xslt/element/output/index.html create mode 100644 files/ko/web/xslt/element/param/index.html create mode 100644 files/ko/web/xslt/element/preserve-space/index.html create mode 100644 files/ko/web/xslt/element/processing-instruction/index.html create mode 100644 files/ko/web/xslt/element/sort/index.html create mode 100644 files/ko/web/xslt/element/strip-space/index.html create mode 100644 files/ko/web/xslt/element/stylesheet/index.html create mode 100644 files/ko/web/xslt/element/template/index.html create mode 100644 files/ko/web/xslt/element/text/index.html create mode 100644 files/ko/web/xslt/element/transform/index.html create mode 100644 files/ko/web/xslt/element/value-of/index.html create mode 100644 files/ko/web/xslt/element/variable/index.html create mode 100644 files/ko/web/xslt/element/when/index.html create mode 100644 files/ko/web/xslt/element/with-param/index.html delete mode 100644 files/ko/web/xslt/fallback/index.html delete mode 100644 files/ko/web/xslt/for-each/index.html delete mode 100644 files/ko/web/xslt/if/index.html delete mode 100644 files/ko/web/xslt/import/index.html delete mode 100644 files/ko/web/xslt/include/index.html delete mode 100644 files/ko/web/xslt/key/index.html delete mode 100644 files/ko/web/xslt/message/index.html delete mode 100644 files/ko/web/xslt/namespace-alias/index.html delete mode 100644 files/ko/web/xslt/number/index.html delete mode 100644 files/ko/web/xslt/otherwise/index.html delete mode 100644 files/ko/web/xslt/output/index.html delete mode 100644 files/ko/web/xslt/param/index.html delete mode 100644 files/ko/web/xslt/preserve-space/index.html delete mode 100644 files/ko/web/xslt/processing-instruction/index.html delete mode 100644 files/ko/web/xslt/sort/index.html delete mode 100644 files/ko/web/xslt/strip-space/index.html delete mode 100644 files/ko/web/xslt/stylesheet/index.html delete mode 100644 files/ko/web/xslt/template/index.html delete mode 100644 files/ko/web/xslt/text/index.html delete mode 100644 files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/index.html delete mode 100644 files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/introduction/index.html delete mode 100644 files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/setting_parameters/index.html delete mode 100644 files/ko/web/xslt/transform/index.html delete mode 100644 files/ko/web/xslt/value-of/index.html delete mode 100644 files/ko/web/xslt/variable/index.html delete mode 100644 files/ko/web/xslt/when/index.html delete mode 100644 files/ko/web/xslt/with-param/index.html create mode 100644 files/ko/web/xslt/xslt_js_interface_in_gecko/index.html create mode 100644 files/ko/web/xslt/xslt_js_interface_in_gecko/introduction/index.html create mode 100644 files/ko/web/xslt/xslt_js_interface_in_gecko/setting_parameters/index.html delete mode 100644 "files/ko/web/\354\260\270\354\241\260/api/index.html" delete mode 100644 "files/ko/web/\354\260\270\354\241\260/index.html" (limited to 'files/ko/web') diff --git a/files/ko/web/api/ambient_light_events/index.html b/files/ko/web/api/ambient_light_events/index.html new file mode 100644 index 0000000000..b033d4f80d --- /dev/null +++ b/files/ko/web/api/ambient_light_events/index.html @@ -0,0 +1,64 @@ +--- +title: Using Light Events +slug: WebAPI/Using_Light_Events +tags: + - Ambient Light +translation_of: Web/API/Ambient_Light_Events +--- +
{{DefaultAPISidebar("Ambient Light Events")}}{{SeeCompatTable}}
+ +

주변의 빛을 감지하는 이벤트를 활용해서 웹페이지나 어플리케이션이 주변 빛의 세기를 감지할 수 있습니다. 사용자 인터페이스의 색상 대비나 사진의 노출을 변경하는 용도로 사용할 수 있습니다.

+ +

빛 이벤트

+ +

기기의 빛 센서가 빛의 변화를 감지하면 브라우저에 변화를 전달합니다. 브라우저가 이러한 알림을 받으면 정확한 빛의 세기를 알려주는 {{domxref("DeviceLightEvent")}} 이벤트를 발생시킵니다.

+ +

이 이벤트는 {{domxref("EventTarget.addEventListener","addEventListener")}} 메서드 ({{event("devicelight")}} 이벤트 이름 사용)를 사용하거나 {{domxref("window.ondevicelight")}} 속성에 이벤트 핸들러를 사용함으로서 window 객체 수준에서 캡춰됩니다.

+ +

캡춰가 되면 이벤트 객체의 {{domxref("DeviceLightEvent.value")}} 속성을 통해서 럭스(lux) 단위의 빛의 세기를 사용할 수 있습니다.

+ +

예제

+ +
window.addEventListener('devicelight', function(event) {
+  var html = document.getElementsByTagName('html')[0];
+
+  if (event.value < 50) {
+    html.classList.add('darklight');
+    html.classList.remove('brightlight');
+  } else {
+    html.classList.add('brightlight');
+    html.classList.remove('darklight');
+  }
+});
+ +

명세

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('AmbientLight', '', 'Ambient Light Events') }}{{ Spec2('AmbientLight') }}Initial specification
+ +

브라우저 호환성

+ + + +

{{Compat("api.DeviceLightEvent")}}

+ +

같이 보기

+ + diff --git a/files/ko/web/api/battery_status_api/index.html b/files/ko/web/api/battery_status_api/index.html new file mode 100644 index 0000000000..12347b0f20 --- /dev/null +++ b/files/ko/web/api/battery_status_api/index.html @@ -0,0 +1,75 @@ +--- +title: Battery Status API +slug: WebAPI/Battery_Status +tags: + - API + - Apps + - Battery API + - Battery Status API + - Obsolete + - 가이드 + - 개요 + - 모바일 + - 배터리 + - 어플리케이션 +translation_of: Web/API/Battery_Status_API +--- +
{{DefaultAPISidebar("Battery API")}}{{Obsolete_Header}}
+ +

Battery API 만큼이나 자주 언급되는 Battery Status API는 시스템의 배터리 충전 상태에 대한 정보를 제공하고, 배터리 상태에 따라 발생하는 이벤트를 다룰 수 있도록 해 줍니다. 배터리가 얼마남지 않은 상황에서, 앱에서 배터리의 소모를 줄인다거나 배터리가 방전되기 전에 데이터를 저장하거나 하는 것들이 가능합니다.

+ +

Battery Status API 는 {{domxref("window.navigator.battery")}} 를 제공 합니다. 이는 {{domxref("BatteryManager")}} 객체이며 배터리 상태를 감시하고 전달받아 처리할 수 있는 이벤트를 가지고 있습니다.

+ +

예제

+ +

아래 예제에서는 배터리가 충전중인 상태 (전원 케이블을 연결하여 충전 중인지) 와 배터리 수준의 변화를 감시합니다. 각각 {{event("chargingchange")}} 와 {{event("levelchange")}} 이벤트가 발생하면 완료 됩니다.

+ +
var battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery;
+
+function updateBatteryStatus() {
+  console.log("Battery status: " + battery.level * 100 + " %");
+
+  if (battery.charging) {
+    console.log("Battery is charging");
+  }
+}
+
+battery.addEventListener("chargingchange", updateBatteryStatus);
+battery.addEventListener("levelchange", updateBatteryStatus);
+updateBatteryStatus();
+
+ +

명세서의 예제도 확인해보세요.

+ +

사양

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("Battery API")}}{{Spec2("Battery API")}}Initial definition.
+ +

브라우저 호환성

+ + + +

{{Compat("api.BatteryManager")}}

+ +

더보기

+ + diff --git a/files/ko/web/api/broadcastchannel/message_event/index.html b/files/ko/web/api/broadcastchannel/message_event/index.html new file mode 100644 index 0000000000..1796b8ee0c --- /dev/null +++ b/files/ko/web/api/broadcastchannel/message_event/index.html @@ -0,0 +1,152 @@ +--- +title: message +slug: Web/Events/message +translation_of: Web/API/BroadcastChannel/message_event +--- +

메시지 이벤트는 메시지가 수신되었음을 알리는 메시지, {{domxref("WebSocket")}}, {{domxref("RTCDataConnection")}} 또는 {{domxref("BroadcastChannel")}} 개체를 알려 줍니다.

+ +

대상이 {{domxref("RTCDataConnection")}}, 인 경우 이 이벤트에 대한 이벤트 핸들러를 {{domxref("RTCDataConnection.onmessage")}}속성을 통해 추가할 수 있습니다.

+ +

대상이 {{domxref("BroadcastChannel")}}인 경우, 이 이벤트에 대한 이벤트 핸들러를 {{domxref("BroadcastChannel.onmessage")}} 속성을 통해 추가할 수 있습니다.

+ +

일반 정보

+ +
+
인터페이스
+
+ +
+
{{domxref("MessageEvent")}}
+
Bubbles
+
No
+
Cancelable
+
No
+
Target
+
{{domxref("RTCDataChannelEvent")}}, {{domxref("WebSocket")}}, {{domxref("BroadcastChannel")}}
+
Default Action
+
None
+
+ +

특성

+ +

{{domxref("Event")}}가 진행되는 동안  {{domxref("MessageEvent")}} 이러한 속성을 구현합니다.

+ +
+
data {{readOnlyInline}}
+
수신된 메시지를 포함하는 {{domxref("DOMString")}} 가 있습니다.
+
+ +

방법

+ +

{{domxref("Event")}}가 진행되는 동안  {{domxref("MessageEvent")}} 이러한 속성을 구현합니다.

+ +

관련 자료

+ + + +

사양

+ + + + + + + + + + + + + + + + + + + +
사양상황Comment
{{ SpecName('WebRTC 1.0', '#event-datachannel-message', 'message on RTCDataChannel') }}{{Spec2('WebRTC 1.0')}}{{domxref("RTCDataChannel")}} 를 {{domxref("EventTarget")}}로 추가하고 이 이벤트가 전송될 시기를 정의합니다.
{{SpecName('HTML WHATWG', '#', 'message on BroadcastChannel')}}{{Spec2('HTML WHATWG')}}{{domxref("RTCDataChannel")}} 를 {{domxref("EventTarget")}}로 추가하고 이 이벤트가 전송될 시기를 정의합니다.
+ +

브라우저 호환성

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown }}{{ CompatNo() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
on {{domxref("BroadcastChannel")}} {{experimental_inline}}{{CompatNo}}{{CompatNo}}{{CompatGeckoDesktop(38)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
on {{domxref("BroadcastChannel")}}  {{experimental_inline}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile(38)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
+
+ +

보기

+ + diff --git a/files/ko/web/api/canvas_api/a_basic_ray-caster/index.html b/files/ko/web/api/canvas_api/a_basic_ray-caster/index.html new file mode 100644 index 0000000000..950b0f5366 --- /dev/null +++ b/files/ko/web/api/canvas_api/a_basic_ray-caster/index.html @@ -0,0 +1,53 @@ +--- +title: A basic ray-caster +slug: A_Basic_RayCaster +tags: + - Advanced + - Canvas + - Example + - Graphics + - HTML + - Web +translation_of: Web/API/Canvas_API/A_basic_ray-caster +--- +
{{CanvasSidebar}}
+ +

This article provides an interesting real-world example of using the {{HTMLElement("canvas")}} element to do software rendering of a 3D environment using ray-casting.

+ +

{{EmbedGHLiveSample("canvas-raycaster/index.html", 900, 300)}}

+ +

Open in new window

+ +

Why?

+ +

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

+ +

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

+ +

How?

+ +

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

+ +

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

+ +

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

+ +

Results

+ +

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

+ +

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

+ +

The ray-caster

+ +

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

+ +

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

+ +

See also

+ + diff --git a/files/ko/web/api/canvas_api/index.html b/files/ko/web/api/canvas_api/index.html new file mode 100644 index 0000000000..bbe466e58d --- /dev/null +++ b/files/ko/web/api/canvas_api/index.html @@ -0,0 +1,135 @@ +--- +title: Canvas API +slug: Web/HTML/Canvas +tags: + - API + - Canvas + - JavaScript + - 개요 + - 레퍼런스 +translation_of: Web/API/Canvas_API +--- +
{{CanvasSidebar}}
+ +

Canvas API는 JavaScript와 HTML {{HtmlElement("canvas")}} 엘리먼트를 통해 그래픽을 그리기위한 수단을 제공합니다. 무엇보다도 애니메이션, 게임 그래픽, 데이터 시각화, 사진 조작 및 실시간 비디오 처리를 위해 사용됩니다.

+ +

Canvas API는 주로 2D 그래픽에 중점을 두고 있습니다. WebGL API 또한 <canvas> 엘리먼트를 사용하며, 하드웨어 가속 2D 및 3D 그래픽을 그립니다.

+ +

기본 예시

+ +

canvas에 초록색 사각형을 그리는 간단한 예시입니다.

+ +

HTML

+ +
<canvas id="canvas"></canvas>
+
+ +

JavaScript

+ +

{{domxref("Document.getElementById()")}} 메소드는 HTML <canvas> 엘리먼트에 대한 참조를 얻습니다. 그 다음, {{domxref("HTMLCanvasElement.getContext()")}} 메소드는 엘리먼트의 컨텍스트(렌더링될 그리기의 대상)를 얻습니다.

+ +

실제 그리기는 {{domxref("CanvasRenderingContext2D")}} 인터페이스를 사용해 수행됩니다. {{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle")}} 프로퍼티는 사각형을 초록색으로 만듭니다. {{domxref("CanvasRenderingContext2D.fillRect()", "fillRect()")}} 메소드는 좌측 상단 코너를 (10, 10) 위치에 놓으며, 너비를 150, 높이를 100으로 지정합니다.

+ +
const canvas = document.getElementById('canvas');
+const ctx = canvas.getContext('2d');
+
+ctx.fillStyle = 'green';
+ctx.fillRect(10, 10, 150, 100);
+
+ +

결과

+ +

{{ EmbedLiveSample('기본_예시', 700, 180) }}

+ +

레퍼런스

+ +
+ +
+ +
+

노트: WebGLRenderingContext에 관련된 인터페이스는 WebGL 하위에 참조되어있습니다.

+
+ +

{{domxref("CanvasCaptureMediaStream")}}은 관련된 인터페이스입니다.

+ +

가이드 및 튜토리얼

+ +
+
Canvas 튜토리얼
+
Canvas API의 기본적인 사용과 고급 기능 모두를 다루는 이해하기 쉬운 튜토리얼.
+
HTML5 Canvas 깊이 살펴보기
+
Canvas API 및 WebGL의 실습, 자세한 소개.
+
Canvas 핸드북
+
Canvas API에 대한 유용한 레퍼런스.
+
데모: A basic ray-caster
+
Canvas를 사용한 ray-tracing 애니메이션 데모.
+
Canvas를 사용하여 비디오 조작
+
{{HTMLElement("video")}}와 {{HTMLElement("canvas")}}를 조합하여 실시간으로 비디오 데이터를 조작.
+
+ +

라이브러리

+ +

Canvas API는 굉장히 강력하지만, 사용하는 것이 항상 간단하지 않습니다. 아래에 나열된 라이브러리들은 캔버스 기반 프로젝트를 더 빠르고 더 쉽게 생성할 수 있게 해줍니다.

+ + + +
+

노트: WebGL을 사용하는 2D 및 3D를 위한 WebGL API를 확인하세요.

+
+ +

명세

+ + + + + + + + + + + + + + + + +
명세상태코멘트
{{SpecName('HTML WHATWG', '#2dcontext', 'the 2D rendering context')}}{{Spec2('HTML WHATWG')}}
+ +

브라우저 호환성

+ +

Mozilla 애플리케이션은 Gecko 1.8(Firefox 1.5)을 시작으로 <canvas>에 대한 지원을 받았습니다. OS X Dashboard 및 Safari를 위해 Apple이 소개한 것이 캔버스 엘리먼트의 기원입니다. Internet Explorer는 9버전부터 <canvas>를 지원하며, 이전 버전의 IE에서는 Google의 Explorer Canvas 프로젝트의 스크립트를 추가하여 <canvas>에 대한 지원을 효과적으로 추가할 수 있습니다. Google Chrome 및 Opera 9 또한 <canvas>를 지원합니다.

+ +

함께 보기

+ + diff --git a/files/ko/web/api/canvas_api/manipulating_video_using_canvas/index.html b/files/ko/web/api/canvas_api/manipulating_video_using_canvas/index.html new file mode 100644 index 0000000000..7851f86154 --- /dev/null +++ b/files/ko/web/api/canvas_api/manipulating_video_using_canvas/index.html @@ -0,0 +1,164 @@ +--- +title: 캔버스(canvas)를 이용한 비디오 조작하기 +slug: Web/HTML/Canvas/Manipulating_video_using_canvas +tags: + - Canvas + - Video + - 비디오 + - 캔버스 +translation_of: Web/API/Canvas_API/Manipulating_video_using_canvas +--- +
{{CanvasSidebar}}
+ +
+

비디오에서 다양한 시각적 효과를 보여주기 위해, 캔버스비디오의 기능을 결합하여 실시간으로 비디오 데이터를 조작할 수 있습니다. 이 튜토리얼에서는 자바스크립트 코드로 어떻게 크로마 키잉(chroma-keying, 또한 "녹색 스크린 효과, green screen effect")을 구현할 수 있는지 보여줍니다. 

+
+ +

라이브 예제 보기

+ +

문서(document) 내용

+ +

이 내용을 보여주기 위한 XHTML 문서는 아래와 같습니다.

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      body {
+        background: black;
+        color:#CCCCCC;
+      }
+      #c2 {
+        background-image: url(foo.png);
+        background-repeat: no-repeat;
+      }
+      div {
+        float: left;
+        border :1px solid #444444;
+        padding:10px;
+        margin: 10px;
+        background:#3B3B3B;
+      }
+    </style>
+    <script type="text/javascript" src="main.js"></script>
+  </head>
+
+  <body onload="processor.doLoad()">
+    <div>
+      <video id="video" src="video.ogv" controls="true"/>
+    </div>
+    <div>
+      <canvas id="c1" width="160" height="96"></canvas>
+      <canvas id="c2" width="160" height="96"></canvas>
+    </div>
+  </body>
+</html>
+
+ +

여기에서 중요한 요소는:

+ +
    +
  1. 이 문서에는 ID가 c1, c2인 두 개의  캔버스가 있습니다. 캔버스 c1은 비디오 원본의 현재 프레임을 보여주기 위해 사용되고, c2는 크로마 키잉 효과를 수행한 결과를 보여줍니다. c2에서 비디오의 녹색 배경을 대체할 정지 이미지를 미리 로드합니다.
  2. +
  3. 자바스크립트 코드는 main.js에서 가져옵니다. 이 스크립트는 자바스크립트 1.8 기능을 사용했기 때문에 스크립트를 가져오는 22번째 줄에서 버전이 명시됩니다(원문: this script uses JavaScript 1.8 features, so that version is specified in line 22 when importing the script).
  4. +
  5. 문서가 로드되면, processor.doLoad() 메서드가 실행됩니다.
  6. +
+ +

자바스크립트 코드

+ +

main.js에 있는 자바스크립트 코드는 3개의 메서드로 구성됩니다.

+ +

크로마 키잉 플레이어 초기화

+ +

doLoad() 메서드는 문서가 최초에 로드될 때 호출됩니다. 이 메서드가 하는 일은 크로마 키잉 처리에서 쓰일 변수를 준비하고, 이벤트 리스너를 등록함으로써 사용자가 비디오 재생을 시작할 때 감지할 수 있도록 해줍니다. 

+ +
  var processor;
+
+  processor.doLoad = function doLoad() {
+    this.video = document.getElementById('video');
+    this.c1 = document.getElementById('c1');
+    this.ctx1 = this.c1.getContext('2d');
+    this.c2 = document.getElementById('c2');
+    this.ctx2 = this.c2.getContext('2d');
+    let self = this;
+    this.video.addEventListener('play', function() {
+        self.width = self.video.videoWidth / 2;
+        self.height = self.video.videoHeight / 2;
+        self.timerCallback();
+      }, false);
+  },
+
+ +

이코드는 XHTML에서 중요한 요소인 비디오와 캔버스의 참조를 가져옵니다. 두 개의 캔버스에 대한 그래픽 컨텍스트의 참조도 가져옵니다. 이 참조들은 뒤에서 크로마 키잉 효과를 구현할 때 사용됩니다.

+ +

그리고 addEventListener()는 비디오가 재생을 시작하기 위해 호출되기 때문에 사용자가 재생 버튼을 누를 때 알림을 받습니다. 재생이 시작되면 이 코드는 비디오의 가로, 세로를 이등분 한 값을 가져오고(크로마 키잉 효과를 수행할 때 이등분 함), timerCallback() 메서드를 호출하여 비디오를 보고 시각적 효과를 계산하기 시작합니다.

+ +

타이머 콜백

+ +

타이머 콜백은 비디오가 재생되기 시작("재생" 이벤트가 발생)할 때 호출되는데, 매 프레임마다 키잉 효과를 주기 위해 주기적으로 호출 될 수 있도록 설정해 주어야 합니다.

+ +
  processor.timerCallback = function timerCallback() {
+    if (this.video.paused || this.video.ended) {
+      return;
+    }
+    this.computeFrame();
+    let self = this;
+    setTimeout(function() {
+        self.timerCallback();
+      }, 0);
+  },
+
+ +

콜백에서 하는 첫 번 째 일은 비디오가 재생되고 있는지 확인하는 것인데, 만약 그렇지 않다면 콜백은 아무 일도 하지 않고 즉시 반환됩니다.

+ +

그 후에 현재 비디오 프레임에서 크로마 키잉 효과를 주기 위한 computeFrame() 메서드를 호출합니다.

+ +

콜백에서 마지막으로 하는 일은 setTimeout()을 호출하여 가능한 한 빨리 timerCallback() 메서드를 다시 호출할 수 있도록 하는 것입니다. 실제로는, 비디오 프레임 속도에 대한 기반 지식으로 호출할 수 있도록 합니다. 

+ +

비디오 프레임 데이터 조작

+ +

아래의 computeFrame() 메서드는 프레임 데이터를 가져와서 크로마 키잉 효과를 수행하는 역할을 합니다. 

+ +
  processor.computeFrame = function computeFrame() {
+    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
+    let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
+    let l = frame.data.length / 4;
+
+    for (let i = 0; i < l; i++) {
+      let r = frame.data[i * 4 + 0];
+      let g = frame.data[i * 4 + 1];
+      let b = frame.data[i * 4 + 2];
+      if (g > 100 && r > 100 && b < 43)
+        frame.data[i * 4 + 3] = 0;
+    }
+    this.ctx2.putImageData(frame, 0, 0);
+    return;
+  }
+
+ +

위 과정이 계속 호출 되면, 아래와 같이 비디오 요소에 가장 최근 프레임의 비디오 데이터가 표출됩니다.

+ +

video.png

+ +

2번째 줄에서, 첫 번째 캔버스의 그래픽 컨텍스트 ctx1에 비디오 프레임이 복사 되는데, 원본의 절반 크기로 프레임을 그리기 위해 이전에 저장한 가로, 세로 값으로 지정합니다. 컨텍스트의 drawImage() 메서드에 비디오 요소를 전달하기만 하면 현재 비디오 프레임을 그릴 수 있습니다. 결과는 아래와 같습니다: 

+ +

sourcectx.png

+ +

3번째 줄에서는 첫 번째 컨텍스트의 getImageData() 메서드를 호출해서 현재 비디오 프레임의 원시 그래픽 데이터 복사본을 가져옵니다. 이것은 조작할 수 있는 원시 32비트 픽셀 이미지 데이터를 제공합니다. 4번째 줄에서는 프레임의 이미지 데이터 전체 크기를 4로 나누어 이미지의 픽셀 수를 계산합니다.

+ +

6번째 줄에서 시작하는 for 문은 프레임의 픽셀을 스캔하여, 빨간색, 녹색, 파란색 값을 추출하여 사전에 정의된 숫자와 비교합니다. 이 숫자는 foo.png에서 가져온 배경 이미지로 대체될 녹색 스크린 영역을 감지합니다.

+ +

녹색 스크린이라고 간주된 매개변수 내의 프레임 이미지 데이터의 모든 픽셀은 투명해질 수 있도록 알파값이 0으로 대체됩니다. 결과적으로 최종 이미지는 100% 투명해진 녹색 스크린 영역을 갖게 되고, 13번째 줄에서 대상 컨텍스트에 고정된 배경 위로 올려져 그려집니다.

+ +

결과 이미지는 아래와 같습니다:

+ +

output.png

+ +

이 과정은 비디오가 재생될 때마다 반복되므로, 매 프레임마다 처리되어 크로마 키잉 효과가 나타나는 것입니다.

+ +

라이브 예제 보기

+ +

더 보기

+ + diff --git a/files/ko/web/api/canvas_api/tutorial/advanced_animations/index.html b/files/ko/web/api/canvas_api/tutorial/advanced_animations/index.html new file mode 100644 index 0000000000..1779e63b2c --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/advanced_animations/index.html @@ -0,0 +1,376 @@ +--- +title: 발전된 애니메이션 +slug: Web/HTML/Canvas/Tutorial/Advanced_animations +translation_of: Web/API/Canvas_API/Tutorial/Advanced_animations +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}
+ +
+

마지막 챕터에서 우리는 몇가지 간단한 애니메이션들을 만들었고 이제 이것들을 어떻게 움직이게 하는지 안다. 이 챕터에서 우리는 각각의 모션들을 자세히 살펴보고 애니메이션을 더 발전시키기 위해 몇가지 물리 동작을 추가할 것이다.

+
+ +

공 그리기

+ +

우리는 애니메이션 공부를 위해 공을 사용할 것이다. 먼저 캔버스에 공을 그려보자. 다음 코드를 통해 준비해보자.

+ +
<canvas id="canvas" width="600" height="300"></canvas>
+
+ +

언제나처럼, 우리는 context를 먼저 그려야 한다. 공을 그리기 위해 우리는 캔버스에 그림을 그리기 위한 프로퍼티와 draw() 메소드를 가진 ball 오브젝트를 생성할 것이다.

+ +
var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+var ball = {
+  x: 100,
+  y: 100,
+  radius: 25,
+  color: 'blue',
+  draw: function() {
+    ctx.beginPath();
+    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+    ctx.closePath();
+    ctx.fillStyle = this.color;
+    ctx.fill();
+  }
+};
+
+ball.draw();
+ +

특이할 건 없다. 이공은 사실상 간단한 원이고 그리는 방법은 다음{{domxref("CanvasRenderingContext2D.arc()", "arc()")}} 메소드에서 참고할 수 있다.

+ +

속도 추가하기

+ +

우리한테는 이제 공이 있다. 이제 이 튜토리얼 마지막 챕터에서 배웠던 것과 같은 기본 애니메이션을 추가할 준비가 되었다. 다시 한 번, 애니메이션 컨트롤은 {{domxref("window.requestAnimationFrame()")}}가 도와주 것이다. 공은 위치에 속도 벡터를 추가하여 움직일 수 있게 된다.  각각의 프레임에, 우리는{{domxref("CanvasRenderingContext2D.clearRect", "clear", "", 1)}}를 캔버스에 주어 오래된 원을 이전 프래임에서 지운다.

+ +
var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+var raf;
+
+var ball = {
+  x: 100,
+  y: 100,
+  vx: 5,
+  vy: 2,
+  radius: 25,
+  color: 'blue',
+  draw: function() {
+    ctx.beginPath();
+    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+    ctx.closePath();
+    ctx.fillStyle = this.color;
+    ctx.fill();
+  }
+};
+
+function draw() {
+  ctx.clearRect(0,0, canvas.width, canvas.height);
+  ball.draw();
+  ball.x += ball.vx;
+  ball.y += ball.vy;
+  raf = window.requestAnimationFrame(draw);
+}
+
+canvas.addEventListener('mouseover', function(e) {
+  raf = window.requestAnimationFrame(draw);
+});
+
+canvas.addEventListener('mouseout', function(e) {
+  window.cancelAnimationFrame(raf);
+});
+
+ball.draw();
+
+ +

경계

+ +

경게 충돌 테스트의 필요 없이 우리가 만든 공은 캔버스 밖으로 빠르게 빠져나갈 것입니다. 우리는 공의 xy 위치가 캔버스 차원을 빠져나갔는지 체크해서 방향과 속도를 바꿔주어야 합니다. 그러기 위해서 우리는 draw 메소드에 다음 확인사항을 추가할 것입니다.:

+ +
if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
+  ball.vy = -ball.vy;
+}
+if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
+  ball.vx = -ball.vx;
+}
+ +

First demo

+ +

이제 동작을 확인해 봅시다. 시작하려먼 마우스를 캔버스 안으로 움직여 주세요.

+ + + +

{{EmbedLiveSample("First_demo", "610", "310")}}

+ +

가속

+ +

움직임을 좀 더 리얼하게 만들기 위해, 우리는 속도를 다음과 같이 줄 겁니다. 예를들어:

+ +
ball.vy *= .99;
+ball.vy += .25;
+ +

이것은 각 프레임의 세로 속도를 줄여주어, 공이 결국 바닥에서 튀게 만듭니다.

+ + + +

{{EmbedLiveSample("Second_demo", "610", "310")}}

+ +

후행 효과

+ +

지금까지 우리는 {{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}}메소드를 사용해서 이전 프레임을 지웠다. 만약 당신이 {{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}}르 사용하여 약간 투명도를 준다면, 쉽게 후행 효과(Trailing effect)를 만들 수 있을 것이다.

+ +
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
+ctx.fillRect(0, 0, canvas.width, canvas.height);
+ + + +

{{EmbedLiveSample("Third_demo", "610", "310")}}

+ +

마우스 컨트롤 추가하기

+ +

공을 컨트롤 하기 위해, 우리는 mousemove 이벤트를 사용하여 마우스를 따라오게 할 것이다. click 이벤트를 통해 공을 놓으면 다시 공이 튀도록 할 것이다.

+ + + +
var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+var raf;
+var running = false;
+
+var ball = {
+  x: 100,
+  y: 100,
+  vx: 5,
+  vy: 1,
+  radius: 25,
+  color: 'blue',
+  draw: function() {
+    ctx.beginPath();
+    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
+    ctx.closePath();
+    ctx.fillStyle = this.color;
+    ctx.fill();
+  }
+};
+
+function clear() {
+  ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
+  ctx.fillRect(0,0,canvas.width,canvas.height);
+}
+
+function draw() {
+  clear();
+  ball.draw();
+  ball.x += ball.vx;
+  ball.y += ball.vy;
+
+  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
+    ball.vy = -ball.vy;
+  }
+  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
+    ball.vx = -ball.vx;
+  }
+
+  raf = window.requestAnimationFrame(draw);
+}
+
+canvas.addEventListener('mousemove', function(e) {
+  if (!running) {
+    clear();
+    ball.x = e.clientX;
+    ball.y = e.clientY;
+    ball.draw();
+  }
+});
+
+canvas.addEventListener('click', function(e) {
+  if (!running) {
+    raf = window.requestAnimationFrame(draw);
+    running = true;
+  }
+});
+
+canvas.addEventListener('mouseout', function(e) {
+  window.cancelAnimationFrame(raf);
+  running = false;
+});
+
+ball.draw();
+
+ +

마우스로 공을 움직이고, 클릭을 통해 놓아보자.

+ +

{{EmbedLiveSample("Adding_mouse_control", "610", "310")}}

+ +

Breakout

+ +

이 짧은 챕터는 발전된 애니메이션을 만들기 위한 조금의 기술을 설명했다. 여기에 더 많은 것들이 있다! 노나 벽돌을 추가해서 이 튜토리얼을  Breakout 으로 발전시키는 건 어떨까?  Game development에서 게임에 관련된 글들을 찾아보자.

+ +

더보기

+ + + +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html b/files/ko/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html new file mode 100644 index 0000000000..df094acb71 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/applying_styles_and_colors/index.html @@ -0,0 +1,732 @@ +--- +title: 스타일과 색 적용하기 +slug: Web/HTML/Canvas/Tutorial/Applying_styles_and_colors +tags: + - HTML5 + - 그래픽 + - 캔버스 +translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
+ +
+

도형 그리기 장에서는 기본 선과 채우기 스타일만 사용했습니다. 여기서 우리는 그리기를 조금 더 매력적으로 만들 수있는 캔버스 옵션을 살펴볼 것입니다. 그리기에 다른 색상, 선 스타일, 그라디언트, 패턴 및 그림자를 추가하는 방법을 배우게됩니다.

+
+ +

색상

+ +

지금까지는 그리기 메소드만 살펴봤습니다. 도형에 색을 적용하고자 하면, fillStyle과  strokeStyle 두 가지 중요한 속성을 사용할 수 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}
+
도형을 채우는 색을 설정합니다.
+
{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}
+
도형의 윤곽선 색을 설정합니다.
+
+ +

여기서의 color는 CSS의 {{cssxref("<color>")}}, 그라디언트 객체, 패턴 객체를 뜻합니다. 그라디언트 객체와 패턴 객체는 페이지 아래에서 설명합니다. 윤곽선과 채움 색의 초기 설정값은 검은색입니다. (CSS 색상 값 #000000)

+ +
+

참고: strokeStyle 또는 fillStyle 속성을 설정하면, 새로 설정된 값이 앞으로 그려질 도형의 기본 값이 됩니다. 각 도형에 다른 색을 적용하려면 fillStyle 또는 strokeStyle 속성을 다시 적용해야 합니다.

+
+ +

색의 올바른 값은 CSS3 사양에 나오는 {{cssxref("<color>")}} 값입니다. 아래에 나오는 색은 모두 한가지 색을 다르게 표현한 것입니다.

+ +
// fillStyle에 적용되는 색은 모두 '오렌지'
+
+ctx.fillStyle = "orange";
+ctx.fillStyle = "#FFA500";
+ctx.fillStyle = "rgb(255, 165, 0)";
+ctx.fillStyle = "rgba(255, 165, 0, 1)";
+
+ +

fillStyle 예제

+ +

이 예제에서 for 반복문을 두 번 사용하여 사각형 격자를 그릴 것입니다. 결과는 스크린샷과 같을 것입니다. 결과가 그리 대단한 것은 아닙니다. 각 사각형의 RGB 색상값에서 붉은색과 녹색 값만을 변수 ij를 사용하여 변경합니다. 파란색 채널은 고정된 값입니다. 채널 값들을 변경함으로써, 모든 종류의 팔레트를 생성할 수 있습니다. 단계를 늘리면 Photoshop에서 사용하는 색상 팔레트와 비슷한 모양을 얻을 수 있습니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i = 0; i < 6; i++){
+    for (var j = 0; j < 6; j++){
+      ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ', ' +
+                       Math.floor(255 - 42.5 * j) + ', 0)';
+      ctx.fillRect(j*25,i*25,25,25);
+    }
+  }
+}
+ + + +

결과는 아래와 같습니다.

+ +

{{EmbedLiveSample("A_fillStyle_example", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}

+ +

strokeStyle 예제

+ +

이번 예제는 위에 나온 예제와 비슷하지만, strokeStyle 속성을 사용하여 윤곽선의 색을 바꿉니다. 사각형 대신, 원을 그리는 arc() 메소드를 사용합니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i = 0; i < 6; i++) {
+    for (var j = 0; j < 6; j++) {
+      ctx.strokeStyle = 'rgb(0, ' + Math.floor(255 - 42.5 * i) + ', ' +
+                       Math.floor(255 - 42.5 * j) + ')';
+      ctx.beginPath();
+      ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
+      ctx.stroke();
+    }
+  }
+}
+ + + +

결과는 아래와 같습니다.

+ +

{{EmbedLiveSample("A_strokeStyle_example", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}

+ +

투명도

+ +

캔버스에는 불투명한 도형을 그릴 수도 있고, 반투명한 도형도 그릴 수도 있습니다. globalAlpha 값을 설정하거나 윤곽선 또는 채움 스타일에 반투명 색을 적용하면 됩니다.

+ +
+
{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}
+
투명도 값이 설정되면 이후 캔버스에 그려지는 모든 도형들의 투명도가 바뀝니다. 설정하는 값은 0.0(완전히 투명)과 1.0(완전히 불투명) 사이에 있어야 하며, 초기 설정값은 1.0(완전히 투명)입니다.
+
+ +

globalAlpha는 모두 같은 투명도로 캔버스에 많은 도형을 그릴 때 유용합니다. 하지만, 보통은 각각의 도형마다 투명도를 설정하는 것이 더 유용할 것입니다.

+ +

strokeStylefillStyle 값에 CSS rgba 색상값을 적용할 수 있으므로, 투명한 색을 적용하려면 아래와 같은 표기법을 사용할 수 있습니다.

+ +
// 외곽선과 채움 스타일에 투명 적용
+
+ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
+ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
+
+ +

rgba() 함수는 rgb() 함수와 비슷하지만, 인자가 하나 더 있습니다. 마지막 인자는 투명도 값을 설정하는 인자입니다. 올바른 범위는 0.0(완전히 투명)에서 1.0(완전히 불투명)입니다.

+ +

globalAlpha 예제

+ +

이 예제에서, 네 가지 다른 색을 가진 사각형을 배경에 그릴 것입니다. 그 위에, 반투명한 원을 여러 개 그릴 것입니다. globalAlpha 값을 0.2로 설정하면 이후 그려질 도형은 이 값을 사용합니다. for 반복문을 사용하여 점점 큰 반지름의 원을 그립니다. 최종 결과물은 원형 그레이디언트가 됩니다. 원이 겹쳐지면서 점점 불투명해지는 것을 볼 수 있으며, 최종적으로 한 가운데에 있는 원에서는 뒷 배경이 거의 보이지 않게 됩니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  // 배경을 그린다
+  ctx.fillStyle = '#FD0';
+  ctx.fillRect(0, 0, 75, 75);
+  ctx.fillStyle = '#6C0';
+  ctx.fillRect(75, 0, 75, 75);
+  ctx.fillStyle = '#09F';
+  ctx.fillRect(0, 75, 75, 75);
+  ctx.fillStyle = '#F30';
+  ctx.fillRect(75, 75, 75, 75);
+  ctx.fillStyle = '#FFF';
+
+  // 투명값을 설정한다
+  ctx.globalAlpha = 0.2;
+
+  // 반투명한 원을 그린다
+  for (var i = 0; i < 7; i++){
+    ctx.beginPath();
+    ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
+    ctx.fill();
+  }
+}
+ + + +

{{EmbedLiveSample("A_globalAlpha_example", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}

+ +

rgba()를 사용한 예제

+ +

두번째 예제에서는 위의 예제와 비슷한 일을 하지만, 겹쳐진 원을 그리는 대신, 불투명도가 증가하는 작은 사각형을 그릴 것입니다. 각각의 도형마다 윤곽선이나 채움 스타일을 따로따로 설정할 수 있기 때문에, rgba()를 사용할 때는 조금 더 제어가 쉽고 융통성도 있습니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // 배경을 그린다
+  ctx.fillStyle = 'rgb(255,221,0)';
+  ctx.fillRect(0,0,150,37.5);
+  ctx.fillStyle = 'rgb(102,204,0)';
+  ctx.fillRect(0,37.5,150,37.5);
+  ctx.fillStyle = 'rgb(0,153,255)';
+  ctx.fillRect(0,75,150,37.5);
+  ctx.fillStyle = 'rgb(255,51,0)';
+  ctx.fillRect(0,112.5,150,37.5);
+
+  // 반투명한 사각형을 그린다
+  for (var i=0;i<10;i++){
+    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
+    for (var j=0;j<4;j++){
+      ctx.fillRect(5+i*14,5+j*37.5,14,27.5)
+    }
+  }
+}
+ + + +

{{EmbedLiveSample("An_example_using_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}

+ +

선 모양

+ +

선의 스타일을 바꾸는 방법이 몇가지 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}
+
이후 그려질 선의 두께를 설정합니다.
+
{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}
+
선의 끝 모양을 설정합니다.
+
{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}
+
선들이 만나는 "모서리"의 모양을 설정합니다.
+
{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}
+
두 선이 예각으로 만날 때 접합점의 두께를 제어할 수 있도록, 연결부위의 크기를 제한하는 값을 설정합니다.
+
{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}
+
음수가 아닌 짝수를 포함하는 현재 선의 대시 패턴 배열을 반환합니다.
+
{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}
+
현재 선의 대시 패턴을 설정합니다.
+
{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}
+
선의 대시 배열이 어디서 시작될지 지정합니다.
+
+ +

아래 예제들을 보면 어떻게 동작하는지 이해할 수 있을 것입니다.

+ +

lineWidth 예제

+ +

현재 선의 두께를 설정합니다. 설정값은 반드시 양수이어야 하며, 초기 설정값은 1.0 단위입니다.

+ +

선의 두께는 지정된 경로의 가운데에 있는 획의 두께입니다. 이 말의 뜻은, 경로의 좌우로, 설정된 두께 반 만큼의 폭 영역이 그려진다는 것입니다. 캔버스 좌표는 픽셀을 직접 참조하지 않으므로, 선명한 수평 및 수직선을 얻기 위해 특별히 주의를 기울여야 합니다.

+ +

아래에 나오는 예제에서는, 선의 두께가 점점 증가하는 10개의 직선이 그려집니다. 가장 왼쪽의 선은 1.0 단위 폭입니다. 그러나, 경로의 위치 때문에 가장 왼쪽과 다른 모든 홀수 폭 두께 선은 선명하게 보이지 않습니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i = 0; i < 10; i++){
+    ctx.lineWidth = 1 + i;
+    ctx.beginPath();
+    ctx.moveTo(5 + i * 14, 5);
+    ctx.lineTo(5 + i * 14, 140);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_lineWidth_example", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}

+ +

선명한 선을 얻으려면 경로에 획을 어떻게 그려지는지 이해해야 합니다. 아래의 이미지를 보면, 격자는 캔버스의 좌표 격자를 나타냅니다. 격자선 사이에 있는 사각형은 실제 픽셀과 딱 맞아 떨어집니다. 아래에 있는 첫번째 이미지를 보면, (2,1)에서 (5,5)로 사각형이 채워져 있습니다. 사각형의 전체 영역(연한 붉은 색)은 픽셀 경계선 사이에 딱 맞아 떨어지기 때문에 채워진 사각형은 선명한 가장자리를 갖습니다.

+ +

+ +

만일 (3,1)에서 (3,5)로 그리는 직선의 두께가 1.0이라면, 두번째 이미지와 같은 상황이 됩니다. 채워진 실제 영역 (진한 파란색)은 패스의 양쪽에있는 픽셀의 절반까지만 확장됩니다. 이것은 1 픽셀을 채우는 것이 아니므로 근사값으로 화면에 그려지게 됩니다. 그래서 양옆의 영역(연한 파란색과 짙은 파란 색)으로, 실제 설정한 색과는 다른 흐릿한 색으로 채워지는 것입니다. 이전 예제에서 보듯이 선 두께가 1.0인 선에서 일어난 일입니다.

+ +

이렇게 되는 것을 막으려면, 경로를 아주 정밀하게 생성해야 합니다. 선의 두께가 1.0이면 경로의 양쪽으로 0.5 단위만큼이라는 것을 알고 있으니, (3.5,1)에서 (3.5,5)로 그리는 경로를 생성하는 세번째 이미지의 결과는 완벽히 정밀하게 1 픽셀 두께의 수직선이 됩니다.

+ +
+

참고: 위에 나온 수직선 그리기 예제를 살펴보면, Y 위치는 정수로 된 격자선 위치를 참조하고 있습니다. 그렇지 않았다면, 끝점에서 픽셀의 반을 차지한 상태로 보였을 것입니다. (초기값이 buttlineCap 스타일의 설정값에 따라 다르게 보입니다. 홀수 두께 선들의 좌표를 0.5 픽셀씩 조정하여 다시 계산하고 싶을지도 모릅니다. lineCap 스타일을 square로 설정함으로써, 끝점에서 선의 외곽 경계선은 픽셀에 딱 맞게 자동적으로 확장될 것입니다.)

+ +

경로의 시작 지점과 종료 지점의 끝점만이 영향을 받는다는 것에 주목하세요. 만약 closePath()로 경로가 닫힌다면, 시작 지점과 종료 지점은 없는 것입니다. 그 대신, 경로 안에 있는 모든 끝점들은, 초기 설정값이 miterlineJoin 스타일의 설정값을 사용하여 이전 부분 및 다음 부분과 이어지는데, 교차되는 점들로 이어진 부분들의 외곽 경계선을 자동적으로 확장하는 효과가 생깁니다. 그렇기 때문에 만약 이들 이어진 부분들이 수직 또는 수평이라면, 그려지는 선들은 각 끝점의 중심에 놓인 픽셀을 가득 채우게 될 것입니다. 이들 선 스타일에 대한 예제는 아래에 나옵니다.

+
+ +

짝수 두께의 선들은 반으로 나누어도 각각의 반은 정수의 양만큼이기 때문에 픽셀을 조정할 필요가 없습니다.

+ +

비트맵이 아닌 벡터 2D 그래픽으로 작업할 때, 작업을 시작할 때는 약간 힘들겠지만, 격자와 경로의 위치에 주의를 기울인다면, 크기를 키우거나 줄이거나 또는 어떠한 변형을 하더라도 그리려는 이미지는 똑바로 보일 것입니다. 1.0 두께의 수직선은 2배로 크기를 키웠을 때, 정확히 2 픽셀 두께의 선이 되며, 올바른 위치에 나타날 것입니다.

+ +

lineCap 예제

+ +

lineCap 속성은 그리려는 모든 선의 끝점 모양을 결정합니다. butt, round, square라는 세 가지 값을 가지며, 초기 설정값은 butt입니다.

+ +

+ +
+
butt
+
선의 끝이 좌표에 딱맞게 잘립니다.
+
round
+
선의 끝이 동그랗습니다.
+
square
+
선 끝에, 선 두께 반만큼의 사각형 영역이 더해집니다.
+
+ +

이 예제에서는, 각기 다른 lineCap 속성 값을 가진 선 세개가 그려집니다. 또한 각 선들의 차이점을 정확히 보이기 위한 안내선이 추가로 그려집니다. 세개의 선 모두, 이 안내선 위에 시작과 종료 좌표가 있습니다.

+ +

맨 왼쪽에 있는 선은 초기 설정값인 butt을 사용합니다. 안내선에 딱 맞게 선이 시작되고 끝이 납니다. 가운데에 있는 선은 round를 사용합니다. 선 두께의 반을 반지름으로 하는 반원이 끝에 붙습니다. 맨 오른쪽에 있는 선은 square를 사용합니다. 선 두께 만큼의 너비와 선 두께 반 만큼의 높이를 가진 네모 상자가 끝에 붙습니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var lineCap = ['butt','round','square'];
+
+  // 안내선을 그린다
+  ctx.strokeStyle = '#09f';
+  ctx.beginPath();
+  ctx.moveTo(10, 10);
+  ctx.lineTo(140, 10);
+  ctx.moveTo(10, 140);
+  ctx.lineTo(140, 140);
+  ctx.stroke();
+
+  // 선을 그린다
+  ctx.strokeStyle = 'black';
+  for (var i=0;i<lineCap.length;i++){
+    ctx.lineWidth = 15;
+    ctx.lineCap = lineCap[i];
+    ctx.beginPath();
+    ctx.moveTo(25 + i * 50, 10);
+    ctx.lineTo(25 + i * 50,140);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_lineCap_example", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}

+ +

lineJoin 예제

+ +

lineJoin 속성은, 도형을 이루는 선이나 호나 곡선들이 연결되는 지점의 모양을 결정합니다. 끝점과 제어점이 정확히 같은 위치인, 길이가 0인 부분들은 제외된다.

+ +

이 속성에는 세 가지 값이 있는데, round, bevel, miter이며, 초기 설정값은 miter입니다. 두 부분들이 같은 방향으로 연결되어 있는 경우에는, lineJoin을 설정해도 아무런 효과가 나타나지 않습니다.

+ +

+ +
+
round
+
도형의 모서리를, 연결되는 부분들의 공통 끝점을 중심으로 하는 원 모양으로 만듭니다. 이때 원의 반지름은 선의 두께와 같습니다.
+
bevel
+
도형의 모서리를, 연결되는 부분들의 공통 끝점에서 세모 모양으로 만듭니다.
+
miter
+
도형의 모서리를, 두 부분의 바깥쪽 테두리 선을 각각 연장하여 교차된 점으로 생긴 마름모꼴 모양으로 만듭니다. miterLimit 속성값에 따라 모양이 달라집니다.
+
+ +

아래 예제에서 세 개의 경로를 그릴 것입니다. 세 경로는 각각 다른 lineJoin 속성값을 가집니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var lineJoin = ['round', 'bevel', 'miter'];
+  ctx.lineWidth = 10;
+  for (var i=0;i<lineJoin.length;i++){
+    ctx.lineJoin = lineJoin[i];
+    ctx.beginPath();
+    ctx.moveTo(-5, 5 + i * 40);
+    ctx.lineTo(35, 45 + i * 40);
+    ctx.lineTo(75, 5 + i * 40);
+    ctx.lineTo(115, 45 + i * 40);
+    ctx.lineTo(155, 5 + i * 40);
+    ctx.stroke();
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_lineJoin_example", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}

+ +

miterLimit 속성 예제

+ +

위의 예제에서 볼 수 있듯이, 속성값을 miter로 하여 두 선이 연결되면, 연결되는 두 선의 바깥쪽 테두리는 연장선이 만나는 지점까지 확장됩니다. 연결된 두 선이 이루는 각도가 크면, 확장되는 영역이 크지 않지만, 각도가 작아짐(끝이 뾰족해짐)에 따라서 이 영역이 기하급수적으로 커질 수도 있습니다.

+ +

miterLimit 속성은 끝점이 만나는 지점과 테두리 연장선이 만나는 지점이 얼마나 떨어져 있을지를 결정합니다. 두 선이 이 값을 넘게 되면, lineJoin 속성의 bevel 값 모양이 적용됩니다. miterLimit 속성값(HTML {{HTMLElement("canvas")}}에서, 초기 설정값은 10.0)에 의해, 현재 좌표 방식 안에서, 선의 두께에 따라, 어느 정도까지 뾰족해질 수 있는지가 계산됩니다. 그래서 miterLimit은 현재 디스플레이 비율이나 경로의 변형 같은 것으로 각각 설정될 수 있습니다. 그렇게 하여 선의 모서리에만 영향을 줍니다.

+ +

더 자세히 얘기하자면, 뾰족함 제한(miter limit)은, 선 두께의 반과 확장되는 길이(HTML 캔버스에서, 선이 연결되는 바깥쪽 끝부분과, 경로에서 연결되는 두 부분의 공통 끝점 사이로 측정합니다.)의 최대 허용 비율입니다. 이것은 두 부분의 외곽선이 만나는 안쪽 점과 바깥쪽 점 사이 거리와, 선 두께의 최대 허용 비율과 같습니다. miter 값 모양이 아닌 bevel 값 모양으로 연결되는 지점의 최소 안쪽 각 반 만큼의 값과 같은 것입니다.

+ + + +

다음 예제에서는 miterLimit 값을 바꾸고 그 결과가 어떤지 바로 확인할 수 있습니다. 파란색 선은 지그재그 무늬 안에서 선들의 시작 지점과 종료 지점을 나타냅니다.

+ +

이 예제에서 miterLimit 값을 4.2보다 낮게 설정하면, 모든 연결 지점은 bevel 값 모양이 되어 파란색 선에 붙을 것입니다. miterLimit 값이 10보다 높다면, 거의 모든 연결 지점들이 파란색 선 바깥쪽에 있을 것입니다. 왼쪽으로 갈수록 파란색 선에서 더 많이 튀어나오는데, 왼쪽으로 갈수록 연결되는 각이 더 작아지기 때문입니다. 값을 5로 설정하면, 반은 bevel 값 모양으로, 반은 miter 값 모양이 됩니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // 캔버스를 비운다
+  ctx.clearRect(0,0,150,150);
+
+  // 안내선을 그린다
+  ctx.strokeStyle = '#09f';
+  ctx.lineWidth   = 2;
+  ctx.strokeRect(-5,50,160,50);
+
+  // 선 스타일을 설정한다
+  ctx.strokeStyle = '#000';
+  ctx.lineWidth = 10;
+
+  // 입력 값을 검사한다
+  if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) {
+    ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value);
+  } else {
+    alert('Value must be a positive number');
+  }
+
+  // 선을 그린다
+  ctx.beginPath();
+  ctx.moveTo(0,100);
+  for (i=0;i<24;i++){
+    var dy = i%2==0 ? 25 : -25 ;
+    ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
+  }
+  ctx.stroke();
+  return false;
+}
+
+ + + +

{{EmbedLiveSample("A_demo_of_the_miterLimit_property", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}

+ +

 

+ +

대시라인 사용하기

+ +

setLineDash 메소드와 lineDashOffset 속성은 선의 대시 패턴을 지정합니다.  setLineDash 메소드는 거리를 지정하는 숫자 목록을 받아 선과 틈을 교대로 그리며 lineDashOffset 속성은 패턴을 시작할 위치를 오프셋으로 설정합니다.

+ +

이 예제에서 우리는 행진하는 개미 효과를 만들고 있습니다. 컴퓨터 그래픽 프로그램의 선택 도구에서 흔히 볼 수있는 애니메이션 기술입니다. 테두리를 애니메이션화하여 사용자가 선택 테두리와 이미지 배경을 구별하는 데 도움이됩니다. 이 튜토리얼의 뒷부분에서 이 작업 및 다른 기본 애니메이션을 수행하는 방법을 배울 수 있습니다.

+ + + +
var ctx = document.getElementById('canvas').getContext('2d');
+var offset = 0;
+
+function draw() {
+  ctx.clearRect(0, 0, canvas.width, canvas.height);
+  ctx.setLineDash([4, 2]);
+  ctx.lineDashOffset = -offset;
+  ctx.strokeRect(10, 10, 100, 100);
+}
+
+function march() {
+  offset++;
+  if (offset > 16) {
+    offset = 0;
+  }
+  draw();
+  setTimeout(march, 20);
+}
+
+march();
+ +

{{EmbedLiveSample("Using_line_dashes", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}

+ +

그라디언트(Gradient)

+ +

다른 그래픽 프로그램들과 마찬가지로, 선형 및 원형의 그레이디언트를 사용할 수 있습니다. 다음 메소드 중 하나를 사용하여 {{domxref("CanvasGradient")}} 객체를 생성합니다. 그런 다음 이 객체를 fillStyle 또는 strokeStyle 속성에 할당 할 수 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}
+
시작점 좌표를 (x1, y1)로 하고, 종료점 좌표를 (x2, y2)로 하는 선형 그라디언트 오브젝트를 생성합니다.
+
{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}
+
반지름이 r1이고 좌표 (x1, y1)을 중심으로 하는 원과, 반지름이 r2이고 좌표 (x2, y2)를 중심으로 하는 원을 사용하여 그라디언트가 생성됩니다.
+
+ +

예를 들면 다음과 같습니다.

+ +
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
+
+ +

CanvasGradient 객체를 만들었다면, addColorStop() 메소드를 사용하여, 오브젝트에 색을 적용할 수 있습니다.

+ +
+
{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}
+
gradient 오브젝트에 새로운 색 중단점(color stop)을 생성합니다. position은 0.0에서 1.0 사이의 숫자이고 그라디언트에서 색상의 상대적인 위치를 정의합니다. color 인자는 CSS {{cssxref("<color>")}}를 나타내는 문자열이어야하고, 그라디언트가 (전환효과로) 진행되면서 도달한 지점의 색상을 의미합니다.
+
+ +

색 중단점은 원하는 만큼 마음대로 추가할 수 있습니다. 흰 색에서 검은 색으로 변하는 선형 그레이디언트를 만들려면 아래와 같이 합니다.

+ +
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+lineargradient.addColorStop(0, 'white');
+lineargradient.addColorStop(1, 'black');
+
+ +

createLinearGradient 예제

+ +

이 예제에서 그레이디언트 두 개를 만들 것입니다. 예제에서 볼 수 있듯이, strokeStylefillStyle 속성 모두 canvasGradient 오브젝트를 속성 값으로 가질 수 있습니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // 그레이디언트를 생성한다
+  var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
+  lingrad.addColorStop(0, '#00ABEB');
+  lingrad.addColorStop(0.5, '#fff');
+  lingrad.addColorStop(0.5, '#26C000');
+  lingrad.addColorStop(1, '#fff');
+
+  var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95);
+  lingrad2.addColorStop(0.5, '#000');
+  lingrad2.addColorStop(1, 'rgba(0, 0, 0, 0)');
+
+  // 외곽선과 채움 스타일에 그레이디언트를 적용한다
+  ctx.fillStyle = lingrad;
+  ctx.strokeStyle = lingrad2;
+
+  // 도형을 그린다
+  ctx.fillRect(10, 10, 130, 130);
+  ctx.strokeRect(50, 50, 50, 50);
+
+}
+
+ + + +

첫번째 그라디언트는 배경 그라디언트입니다. 보시다시피 같은 위치에 두 가지 색상을 지정했습니다. 매우 선명한 색상 전환을 만들기 위해 이 작업을 수행합니다(이 경우 흰색에서 녹색으로). 일반적으로 색상 중단점을 정의하는 순서는 중요하지 않지만, 이 특별한 경우에는 의미가 있습니다.

+ +

두 번째 그래디언트에서는 시작 색상 (위치 0.0)을 지정하지 않았는데, 자동으로 다음 색상 중단점의 색상으로 가정하기 때문에 반드시 필요하지는 않기 때문입니다. 따라서 위치 0.5에 검은색을 지정하면 시작부터 중단점까지 자동으로 검정색 그라이언트를 만듭니다.

+ +

{{EmbedLiveSample("A_createLinearGradient_example", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}

+ +

createRadialGradient 예제

+ +

이 예제에서는 원형 그레이디언트를 4개 만들 것입니다. 포토샵같은 프로그램에서 원형 그레이디언트를 만들 때는 하나의 점을 중심으로 그레이디언트를 만드는데, 캔버스의 원형 그레이디언트에서는 시작과 종료 지점 두군데를 제어할 수 있기 때문에, 기존의 프로그램에서 볼 수 있는 원형 그레이디언트보다는 더 복잡한 효과를 만들어 낼 수 있습니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // 그라디언트를 생성한다
+  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
+  radgrad.addColorStop(0, '#A7D30C');
+  radgrad.addColorStop(0.9, '#019F62');
+  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
+
+  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
+  radgrad2.addColorStop(0, '#FF5F98');
+  radgrad2.addColorStop(0.75, '#FF0188');
+  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
+
+  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
+  radgrad3.addColorStop(0, '#00C9FF');
+  radgrad3.addColorStop(0.8, '#00B5E2');
+  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
+
+  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
+  radgrad4.addColorStop(0, '#F4F201');
+  radgrad4.addColorStop(0.8, '#E4C700');
+  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
+
+  // 도형을 그린다
+  ctx.fillStyle = radgrad4;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad3;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad2;
+  ctx.fillRect(0,0,150,150);
+  ctx.fillStyle = radgrad;
+  ctx.fillRect(0,0,150,150);
+}
+
+ + + +

이 예제에서는 원형 그레이디언트에 사용되는 두 원의 중심을 달리하여 입체적인 공처럼 보이게 했습니다. 안쪽 원과 바깥쪽 원은 겹치지 않게 하는 것이 좋습니다. 왜냐하면 예상하기 힘든 이상한 결과가 나타날 수 있기 때문입니다.

+ +

그레이디언트의 마지막 색 적용 지점에서는 투명도를 적용하였습니다. 투명도가 적용된 지점에서 이전 지점까지의 색 변화를 보기 좋게 만들려면, 두 지점에 똑같은 색을 적용하면 되는데, 이 예제에서는 색의 값을 다른 방식으로 입력하여 헷갈릴 수도 있습니다. 첫번째 그레이디언트에 사용된 #019F62rgba(1,159,98,1)은 같은 색입니다.

+ +

{{EmbedLiveSample("A_createRadialGradient_example", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}

+ +

패턴(Patterns)

+ +

이전 페이지의 예제 중 하나에서 일련의 루프를 사용하여 이미지 패턴을 만들었습니다. 그러나 훨씬 간단한 메소드 인 createPattern () 메소드가 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}
+
새 캔버스 패턴 객체를 만들어 반환합니다. image는 {{domxref("CanvasImageSource")}}(즉, {{domxref("HTMLImageElement")}}, 다른 캔버스, {{HTMLElement("video")}} 요소 등등)입니다. type은 이미지 사용 방법을 나타내는 문자열입니다.
+
+ +

type은 패턴을 만들기 위해 이미지를 사용하는 방법을 지정하며, 다음 문자열 값 중 하나 여야합니다.

+ +
+
repeat
+
수직 및 수평 방향으로 이미지를 이어 붙입니다.
+
repeat-x
+
수평 방향으로만 이미지를 이어 붙입니다.
+
repeat-y
+
수직 방향으로만 이미지를 이어 붙입니다.
+
no-repeat
+
이미지를 이어 붙이지 않습니다. 이미지는 한번만 사용됩니다.
+
+ +

이 메소드를 사용하여 위에서 본 그라디언트 메소드와 매우 유사한 {{domxref ( "CanvasPattern")}} 객체를 생성합니다. 패턴을 생성하면 fillStyle 또는 strokeStyle 속성에 패턴을 할당 할 수 있습니다. 예를 들면 다음과 같습니다.

+ +
var img = new Image();
+img.src = 'someimage.png';
+var ptrn = ctx.createPattern(img, 'repeat');
+
+ +
+

참고: drawImage () 메서드와 마찬가지로 이 메소드를 호출하기 전에 이미지가 로드되었는지 확인해야합니다. 그렇지 않으면 패턴이 잘못 그려 질 수 있습니다.

+
+ +

createPattern 예제

+ +

이 마지막 예제에서, fillStyle 속성에 적용할 패턴을 만들 것입니다. 한 가지 눈여겨 볼 것은, 이미지 onload 핸들러 사용한다는 것입니다. 이미지를 패턴에 적용하기 전에 불러오기가 완료되었는지 확인하는 것입니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // 패턴으로 사용할 이미지 오브젝트를 생성한다
+  var img = new Image();
+  img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
+  img.onload = function() {
+
+    // 패턴을 생성한다
+    var ptrn = ctx.createPattern(img,'repeat');
+    ctx.fillStyle = ptrn;
+    ctx.fillRect(0,0,150,150);
+
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_createPattern_example", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}

+ +

그림자

+ +

그림자 사용에는 네 개의 속성이 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}
+
그림자가 객체에서 연장되어야하는 수평 거리를 나타냅니다. 이 값은 변환 행렬의 영향을 받지 않습니다. 기본값은 0입니다.
+
{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}
+
그림자가 객체에서 연장되어야하는 수직 거리를 나타냅니다. 이 값은 변환 행렬의 영향을 받지 않습니다. 기본값은 0입니다.
+
{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}
+
흐림(blur) 효과의 크기를 나타냅니다. 이 값은 픽셀 수와 일치하지 않으며 현재 변환 행렬의 영향을 받지 않습니다. 기본값은 0입니다.
+
{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}
+
그림자 효과의 색상을 나타내는 표준 CSS 색상 값. 기본적으로 완전 검은색입니다.
+
+ +

shadowOffsetXshadowOffsetY 속성은 그림자가 X 및 Y 방향으로 객체에서 얼마나 멀리 떨어져야하는지 나타냅니다. 이 값은 현재 변환 행렬의 영향을받지 않습니다. 음수값을 사용하면 그림자가 위로 또는 왼쪽으로 확장되고 양수값을 사용하면 그림자가 아래로 또는 오른쪽으로 확장됩니다. 기본값은 모두 0입니다.

+ +

shadowBlur 속성은 흐림 효과의 크기를 나타냅니다. 이 값은 픽셀 수와 일치하지 않으며 현재 변환 행렬의 영향을받지 않습니다. 기본값은 0입니다.

+ +

shadowColor 속성은 그림자 효과의 색상을 나타내는 표준 CSS 색상 값입니다. 기본값은 완전 검은색입니다.

+ +
+

알아둘 것: 음영은 source-over 합성 작업에만 사용됩니다.

+
+ +

그림자 있는 글자 예제

+ +

이 예제에서는 그림자가 있는 글자를 그립니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.shadowOffsetX = 2;
+  ctx.shadowOffsetY = 2;
+  ctx.shadowBlur = 2;
+  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
+
+  ctx.font = "20px Times New Roman";
+  ctx.fillStyle = "Black";
+  ctx.fillText("Sample String", 5, 30);
+}
+
+ + + +

{{EmbedLiveSample("A_shadowed_text_example", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}

+ +

다음 장에서 텍스트 그리기에 대한 font 속성과 fillText 메소드를 살펴 보겠습니다.

+ +

캔버스 채우기 규칙

+ +

fill (혹은 {{domxref("CanvasRenderingContext2D.clip", "clip")}} 및 {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}})을 사용할 때 한 점이 경로 안쪽 또는 바깥에 있는지 그리고 따라서 채워지는지 여부를 결정하기 위한 채우기 규칙 알고리즘을 선택적으로 제공 할 수 있습니다. 경로가 교차하거나 중첩 된 경우에 유용합니다.
+
+ 다음 두가지 값을 사용할 수 있습니다:

+ + + +

In this example we are using the evenodd rule.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.beginPath();
+  ctx.arc(50, 50, 30, 0, Math.PI * 2, true);
+  ctx.arc(50, 50, 15, 0, Math.PI * 2, true);
+  ctx.fill('evenodd');
+}
+ + + +

{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/basic_animations/index.html b/files/ko/web/api/canvas_api/tutorial/basic_animations/index.html new file mode 100644 index 0000000000..457d658172 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/basic_animations/index.html @@ -0,0 +1,310 @@ +--- +title: 기본 애니메이션 +slug: Web/HTML/Canvas/Tutorial/Basic_animations +tags: + - HTML5 + - 그래픽 + - 캔버스 +translation_of: Web/API/Canvas_API/Tutorial/Basic_animations +--- +

{{HTMLElement("canvas")}} 요소는 자바스크립트로 제어하는 것이므로, 애니메이션도 쉽게 만들 수 있습니다. 복잡한 애니메이션을 만드는 것은 추가 작업이 더 필요하고, 앞으로 그에 대한 페이지도 머지 않아 추가되기를 기대합니다.

+

도형은 한번 만들어 놓으면 그 모습 그대로 있다는 것이 애니메이션을 만들 때의 가장 큰 제약일 것입니다. 그 도형을 움직이고자 하면 그 도형뿐만이 아니라 그 도형이 그려지기 전에 그려진 모든 것을 다시 그려야 합니다. 복잡한 장면을 다시 그리는 것은 시간도 많이 걸리며, 코드를 실행하는 컴퓨터의 능력에 따라 달라집니다.

+

기본 애니메이션 단계

+

한 장면을 그리려면 아래와 같은 단계를 밟습니다.

+
    +
  1. 캔버스를 비웁니다.
    + 그리려는 도형이 (배경 이미지를 만들 때처럼) 캔버스를 가득 채우는 것이 아니라면, 이전에 그려진 모든 도형을 지울 필요가 있습니다. 가장 쉬운 방법은 clearRect() 메소드를 사용하는 것입니다.
  2. +
  3. 캔버스 상태를 저장합니다.
    + 캔버스 상태에 영향을 주는 (스타일 변경, 모양 변형 등의) 설정값을 바꾸려고 하고, 바뀐 값을 각 장면마다 사용하려고 한다면, 원래 상태를 저장할 필요가 있습니다.
  4. +
  5. 애니메이션할 도형을 그립니다.
    + 실제 장면을 그리는 단계입니다.
  6. +
  7. 캔버스 상태를 복원합니다.
    + 새로운 장면을 그리기 전에 저장된 상태를 복원합니다.
  8. +
+

애니메이션 제어하기

+

캔버스 메소드를 사용하거나 사용자 함수를 사용하여 캔버스에 도형들을 그립니다. 보통의 경우에서는, 코드 실행이 완료되면 캔버스에 나타나는 결과만을 보게 됩니다. 예를 들어,  for 반복문 안에서 애니메이션을 실행하는 것은 불가능합니다.

+

그래서 정해진 시간마다 그리기 함수를 실행하는 방법이 필요한 것입니다. 아래와 같이 애니메이션을 제어하는 두 가지 방법이 있습니다.

+

예정된 변경

+

정해진 시간마다 특정 함수를 부를 때 사용할 수 있는  {{domxref("window.setInterval()")}}과 {{domxref("window.setTimeout()")}} 함수가 있습니다.

+
+

알아둘 것: 현재는 애니메이션을 만드는 방법으로  {{domxref("window.requestAnimationFrame()")}} 메소드를 추천합니다. 이에 대한 튜토리얼은 곧 업데이트할 것입니다.

+
+
+
+ setInterval(function, delay)
+
+ delay 밀리세컨드(1,000분의 1초)마다 function 함수 반복 실행을 시작합니다.
+
+ setTimeout(function, delay)
+
+ delay 밀리세컨드(1,000분의 1초) 경과후, function 함수를 실행합니다.
+
+

사용자의 제어를  필요로 하지 않는 반복 실행에는  setInterval() 함수가 알맞을 것입니다.

+

사용자 상호 작용 변경

+

애니메이션을 제어하는 두번째 방법은 사용자 입력입니다. 게임을 만들려고 한다면, 애니메이션을 제어하기 위해 키보드나 마우스 이벤트를 사용할 수 있을 것입니다.  {{domxref("EventListener")}}를 설정하여, 사용자와 상호 작용하여 애니메이션 함수를 실행합니다.

+

사용자 상호 작용이 필요하다면, 우리가 만든 애니메이션용 프레임웍(framework)최소 기능 버전 또는 최대 기능 버전을 사용할 수 있을 것입니다.

+
var myAnimation = new MiniDaemon(null, animateShape, 500, Infinity);
+

또는

+
var myAnimation = new Daemon(null, animateShape, 500, Infinity);
+

아래 예제에서는, 애니메이션을 제어하기 위해 {{domxref("window.setInterval()")}}을 사용할 것입니다. 페이지 제일 아래쪽에 {{domxref("window.setTimeout()")}}을 사용한 예제 링크도 있습니다.

+

태양계 애니메이션

+

이 예제에서는 달이 지구를 돌고 지구가 태양을 도는 애니메이션을 만듭니다.

+
var sun = new Image();
+var moon = new Image();
+var earth = new Image();
+function init(){
+  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
+  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
+  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
+  setInterval(draw,100);
+}
+
+function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.globalCompositeOperation = 'destination-over';
+  ctx.clearRect(0,0,300,300); // 캔버스를 비운다
+
+  ctx.fillStyle = 'rgba(0,0,0,0.4)';
+  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
+  ctx.save();
+  ctx.translate(150,150);
+
+  // 지구
+  var time = new Date();
+  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
+  ctx.translate(105,0);
+  ctx.fillRect(0,-12,50,24); // Shadow
+  ctx.drawImage(earth,-12,-12);
+
+  // 달
+  ctx.save();
+  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
+  ctx.translate(0,28.5);
+  ctx.drawImage(moon,-3.5,-3.5);
+  ctx.restore();
+
+  ctx.restore();
+
+  ctx.beginPath();
+  ctx.arc(150,150,105,0,Math.PI*2,false); // 지구 궤도
+  ctx.stroke();
+
+  ctx.drawImage(sun,0,0,300,300);
+}
+
+ +

{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

+

시계 애니메이션

+

이 예제에서는, 현재 시각을 보여주는 움직이는 시계를 만듭니다.

+
function init(){
+  clock();
+  setInterval(clock,1000);
+}
+
+function clock(){
+  var now = new Date();
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.save();
+  ctx.clearRect(0,0,150,150);
+  ctx.translate(75,75);
+  ctx.scale(0.4,0.4);
+  ctx.rotate(-Math.PI/2);
+  ctx.strokeStyle = "black";
+  ctx.fillStyle = "white";
+  ctx.lineWidth = 8;
+  ctx.lineCap = "round";
+
+  // 시계판 - 시
+  ctx.save();
+  for (var i=0;i<12;i++){
+    ctx.beginPath();
+    ctx.rotate(Math.PI/6);
+    ctx.moveTo(100,0);
+    ctx.lineTo(120,0);
+    ctx.stroke();
+  }
+  ctx.restore();
+
+  // 시계판 - 분
+  ctx.save();
+  ctx.lineWidth = 5;
+  for (i=0;i<60;i++){
+    if (i%5!=0) {
+      ctx.beginPath();
+      ctx.moveTo(117,0);
+      ctx.lineTo(120,0);
+      ctx.stroke();
+    }
+    ctx.rotate(Math.PI/30);
+  }
+  ctx.restore();
+
+  var sec = now.getSeconds();
+  var min = now.getMinutes();
+  var hr  = now.getHours();
+  hr = hr>=12 ? hr-12 : hr;
+
+  ctx.fillStyle = "black";
+
+  // 시간 표시 - 시
+  ctx.save();
+  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
+  ctx.lineWidth = 14;
+  ctx.beginPath();
+  ctx.moveTo(-20,0);
+  ctx.lineTo(80,0);
+  ctx.stroke();
+  ctx.restore();
+
+  // 시간 표시 - 분
+  ctx.save();
+  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
+  ctx.lineWidth = 10;
+  ctx.beginPath();
+  ctx.moveTo(-28,0);
+  ctx.lineTo(112,0);
+  ctx.stroke();
+  ctx.restore();
+
+  // 시간 표시 - 초
+  ctx.save();
+  ctx.rotate(sec * Math.PI/30);
+  ctx.strokeStyle = "#D40000";
+  ctx.fillStyle = "#D40000";
+  ctx.lineWidth = 6;
+  ctx.beginPath();
+  ctx.moveTo(-30,0);
+  ctx.lineTo(83,0);
+  ctx.stroke();
+  ctx.beginPath();
+  ctx.arc(0,0,10,0,Math.PI*2,true);
+  ctx.fill();
+  ctx.beginPath();
+  ctx.arc(95,0,10,0,Math.PI*2,true);
+  ctx.stroke();
+  ctx.fillStyle = "rgba(0,0,0,0)";
+  ctx.arc(0,0,3,0,Math.PI*2,true);
+  ctx.fill();
+  ctx.restore();
+
+  ctx.beginPath();
+  ctx.lineWidth = 14;
+  ctx.strokeStyle = '#325FA2';
+  ctx.arc(0,0,142,0,Math.PI*2,true);
+  ctx.stroke();
+
+  ctx.restore();
+}
+ +

{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

+

움직이는 파노라마 사진

+

이 예제에서는, 움직이는 파노라마 사진을 만듭니다. 사용할 그림은 위키피디어(Wikipedia)에서 구한 요세미티 국립공원입니다. 캔버스보다 큰 그림을 사용할 수도 있습니다.

+
var img = new Image();
+
+// 변수
+// 스크롤될 이미지, 방향, 속도를 바꾸려면 변수값을 바꾼다.
+
+img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
+var CanvasXSize = 800;
+var CanvasYSize = 200;
+var speed = 30; // 값이 작을 수록 빨라진다
+var scale = 1.05;
+var y = -4.5; // 수직 옵셋
+
+// 주요 프로그램
+
+var dx = 0.75;
+var imgW;
+var imgH;
+var x = 0;
+var clearX;
+var clearY;
+var ctx;
+
+img.onload = function() {
+    imgW = img.width*scale;
+    imgH = img.height*scale;
+    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // 캔버스보다 큰 이미지
+    if (imgW > CanvasXSize) { clearX = imgW; } // 캔버스보다 큰 이미지
+    else { clearX = CanvasXSize; }
+    if (imgH > CanvasYSize) { clearY = imgH; } // 캔버스보다 큰 이미지
+    else { clearY = CanvasYSize; }
+    // 캔버스 요소 얻기
+    ctx = document.getElementById('canvas').getContext('2d');
+    // 새로 그리기 속도 설정
+    return setInterval(draw, speed);
+}
+
+function draw() {
+    // 캔버스를 비운다
+    ctx.clearRect(0,0,clearX,clearY);
+    // 이미지가 캔버스보다 작거나 같다면 (If image is <= Canvas Size)
+    if (imgW <= CanvasXSize) {
+        // 재설정, 처음부터 시작
+        if (x > (CanvasXSize)) { x = 0; }
+        // 추가 이미지 그리기
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
+    }
+    // 이미지가 캔버스보다 크다면 (If image is > Canvas Size)
+    else {
+        // 재설정, 처음부터 시작
+        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
+        // 추가 이미지 그리기
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
+    }
+    // 이미지 그리기
+    ctx.drawImage(img,x,y,imgW,imgH);
+    // 움직임 정도
+    x += dx;
+}
+
+

예제에 사용된 {{HTMLElement("canvas")}}의 크기는 아래와 같다. 캔버스의 너비가 변수 CanvasXSize값과 같고, 캔버스의 높이는 변수 CanvasYSize값과 같다는 것에 주목하라.

+
<canvas id="canvas" width="800" height="200"></canvas>
+

Live sample

+

{{EmbedLiveSample("A_looping_panorama", "830", "230")}}

+

또 다른 예제들

+
+
+ Gartic
+
+ 다중 사용자 지원 그리기 놀이.
+
+ Canvascape
+
+ 3D 어드벤처 게임 (1인칭 슈팅).
+
+ A basic ray-caster
+
+ 키보드를 사용한 애니메이션 제어 방법에 대한 좋은 예제.
+
+ canvas adventure
+
+ 키보드 제어를 사용하는 또다른 좋은 예제.
+
+ An interactive Blob
+
+ 물방울 갖고 놀기.
+
+ Flying through a starfield
+
+ 별, 동그라미, 네모가 떠다니는 우주를 누벼라.
+
+ iGrapher
+
+ 주식 시장 자료 차트 예제.
+
+

이것도 보세요

+ +

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Compositing", "Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/basic_usage/index.html b/files/ko/web/api/canvas_api/tutorial/basic_usage/index.html new file mode 100644 index 0000000000..f455563e87 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/basic_usage/index.html @@ -0,0 +1,154 @@ +--- +title: 캔버스(Canvas) 기본 사용법 +slug: Web/HTML/Canvas/Tutorial/Basic_usage +translation_of: Web/API/Canvas_API/Tutorial/Basic_usage +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}
+ +
+

{{HTMLElement ( "canvas")}} {{Glossary ( "HTML")}} 엘리먼트를 살펴보는 것으로 이 튜토리얼을 시작해 보겠습니다. 이 페이지의 끝에서 캔버스 2D 컨텍스트를 설정하는 방법을 알게되고, 여러분의 브라우저에서 첫 번째 예제를 그리게 될 것입니다.

+
+ +

<canvas> 요소

+ +
<canvas id="tutorial" width="150" height="150"></canvas>
+
+ +

{{HTMLElement ( "canvas")}}는 처음에는 src 및 alt 속성이 없다는 점만 제외하면 {{HTMLElement ( "img")}} 요소처럼 보입니다. 실제로 <canvas> 요소에는 {{htmlattrxref ( "width", "canvas")}}와 {{htmlattrxref ( "height", "canvas")}}의 두 속성만 있습니다. 이것들은 모두 선택사항이며 {{Glossary ( "DOM")}} 프로퍼티를 사용하여 설정할 수도 있습니다. width 및 height 속성을 지정하지 않으면 캔버스의 처음 너비는 300 픽셀이고 높이는 150 픽셀입니다. 요소는 {{Glossary ( "CSS")}}에 의해 임의로 크기를 정할 수 있지만 렌더링하는 동안 이미지는 레이아웃 크기에 맞게 크기가 조정됩니다. CSS 크기 지정이 초기 캔버스의 비율을 고려하지 않으면 왜곡되어 나타납니다 .

+ +
+

노트: 만약 렌더링이 왜곡된 것처럼 보이는 경우 CSS를 사용하지 않고 <canvas> 속성에서 widthheight 속성을 명시적으로 지정하십시오.

+
+ +

 

+ +

id 속성(어트리뷰트)는  <canvas> 요소에 국한되지 않는 글로벌HTML 속성 (global HTML attributes )중 하나로,  모든 HTML 요소에 적용 ( class 등등)될 수 있습니다.  대체로 항상 id 속성을 사용해 주는것이 좋은데, 이는 스크립트 내에서 구분을 쉽게 해 줄 수 있기 때문입니다.

+ +

<canvas>요소는 일반적인 이미지 ({{cssxref("margin")}}, {{cssxref("border")}}, {{cssxref("background")}}…) 처럼 스타일을 적용시킬 수 있습니다. 하지만 이 방법은 실제 캔버스 위에 그리는 것에는 영향을 끼치지 않습니다.  이 방법이 어떻게 사용되는지는 해당 챕터에서 확인 할 수 있습니다.  캔버스에 스타일링이 따로 지정 되있지 않았다면, 캔버스 스타일은 투명으로 설정되어있습니다.

+ +
+

대체 콘텐츠

+ +

<canvas> 요소는 {{HTMLElement("video")}}, {{HTMLElement("audio")}} 혹은 {{HTMLElement("picture")}}처럼 {{HTMLElement("img")}}와는 달리, 인터넷 익스플로러 9 이하의 버전이나 텍스트기반 브라우저 등과 같은, 캔버스를 지원하지 않는 오래된 브라우저들을 위한 대체 컨텐츠를 정의하기 쉽습니다. 여러분은 그러한 브라우저들을 위한 대체 컨텐츠를 제공해야 합니다.

+ +

대체 컨텐츠를 제공하는 것은 매우 간단합니다. <canvas>태그 안에  대체 컨텐츠를 삽입합니다. <canvas>태그 를 지원하지 않는 브라우저는 컨테이너를 무시하고 컨테이너 내부의 대체 콘텐츠를 렌더링 합니다. <canvas>를 지원하는 브라우저는 컨테이너 내부의 내용을 무시하고 캔버스를 정상적으로 렌더링합니다.

+ +

예를 들어, 캔버스 내용에 대한 텍스트 설명을 제공하거나 동적으로 렌더링 된 내용의 정적 이미지를 제공 할 수 있습니다. 이것은 다음과 같이 보일 수있습니다:

+ +
<canvas id="stockGraph" width="150" height="150">
+  current stock price: $3.15 +0.15
+</canvas>
+
+<canvas id="clock" width="150" height="150">
+  <img src="images/clock.png" width="150" height="150" alt=""/>
+</canvas>
+
+ +

사용자에게 캔버스를 지원하는 다른 브라우저를 사용하도록 하는 것은 캔버스를 해석하지 못하는 사용자에게 전혀 도움이 되지 않습니다. 유용한 대체 텍스트나 하위 DOM을 제공하는 것이 캔버스에 더 쉽게 접근할수 있도록 도움이 될 것입니다.

+ +

</canvas> 태그 필수

+ +

대체 컨텐츠가 제공되는 방식때문에, {{HTMLElement("img")}} 요소와 달리, {{HTMLElement("canvas")}} 요소는 닫는 태그(</canvas>)가 필요합니다. 닫는 태그가 없다면, 문서의 나머지 부분이 대체 컨텐츠로 간주되고 보이지 않을 것입니다.

+ +

대체 컨텐츠가 필요하지 않다면, 단순히 <canvas id="foo" ...></canvas>가 모든 미지원 브라우저에서 완전하게 호환됩니다.

+ +

렌더링 컨텍스트

+ +

{{HTMLElement("canvas")}} 엘리먼트는 고정 크기의 드로잉 영역을 생성하고 하나 이상의 렌더링 컨텍스(rendering contexts)를 노출하여, 출력할 컨텐츠를 생성하고 다루게 됩니다. 본 튜토리얼에서는, 2D 렌더링 컨텍스트를 집중적으로 다룹니다. 다른 컨텍스트는 다른 렌더링 타입을 제공합니다. 예를 들어, WebGL은 OpenGL ES 을 기반으로 하는 3D 컨텍스트를 사용합니다.

+ +

캔버스는 처음에 비어있습니다. 무언가를 표시하기 위해서, 어떤 스크립트가 랜더링 컨텍스트에 접근하여 그리도록 할 필요가 있습니다. {{HTMLElement("canvas")}} 요소는 {{domxref("HTMLCanvasElement.getContext", "getContext()")}} 메서드를 이용해서, 랜더링 컨텍스트와 (렌더링 컨텍스트의) 그리기 함수들을 사용할 수 있습니다.  getContext() 메서드는 렌더링 컨텍스트 타입을 지정하는 하나의 파라메터를 가집니다. 본 튜토리얼에서 다루고 있는 2D 그래픽의 경우, {{domxref("CanvasRenderingContext2D")}}을 얻기위해 "2d"로 지정합니다.

+ +
var canvas = document.getElementById('tutorial');
+var ctx = canvas.getContext('2d');
+
+ +

첫 번째 줄의 스크립트는  {{domxref ( "document.getElementById()")}} 메서드를 호출하여 {{HTMLElement ( "canvas")}} 요소를 표시할 DOM을 검색합니다.  요소가 있으면 getContext() 메서드를 사용하여 드로잉 컨텍스트에 액세스 할 수 있습니다.

+ +
+

지원여부 검사

+ +

대체 콘텐츠는 {{HTMLElement ( "canvas")}}를 지원하지 않는 브라우저에 표시됩니다. 스크립트 역시 간단하게 getContext() 메소드의 존재 여부를 테스트함으로써 프로그래밍 방식으로 지원하는지를 확인할 수 있습니다. 위의 코드 예제는 다음과 같이 될 수 있습니다:

+ +
var canvas = document.getElementById('tutorial');
+
+if (canvas.getContext){
+  var ctx = canvas.getContext('2d');
+  // drawing code here
+} else {
+  // canvas-unsupported code here
+}
+
+
+
+ +

템플릿 뼈대

+ +

다음은 이후의 예제들에서 시작점으로 사용될 수 있는 가장 최소한의 템플릿입니다.

+ +
+

알아두기: HTML 내에 스크립트(script)를 사용하는것은 좋은 연습 방법이 아닙니다. 다음의 예시에서는 간결하게 나타내기 위해 사용 한 것입니다.

+
+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8"/>
+    <title>Canvas tutorial</title>
+    <script type="text/javascript">
+      function draw(){
+        var canvas = document.getElementById('tutorial');
+        if (canvas.getContext){
+          var ctx = canvas.getContext('2d');
+        }
+      }
+    </script>
+    <style type="text/css">
+      canvas { border: 1px solid black; }
+    </style>
+  </head>
+  <body onload="draw();">
+    <canvas id="tutorial" width="150" height="150"></canvas>
+  </body>
+</html>
+
+ +

위 스크립트에 draw() 함수 문서가 호출되었는데, 이는 문서가 {{event("load")}} 이벤트를 수신하여 페이지 로딩이 완료될 때 한번 실행됩니다. 이 함수 혹은 이와 유사한 함수는, 페이지가 처음 로딩되는 한, {{domxref("WindowTimers.setTimeout", "window.setTimeout()")}}, {{domxref("WindowTimers.setInterval", "window.setInterval()")}}, 혹은 또 다른 이벤트 핸들러 등을 이용하여 호출될 수 있습니다.

+ +

다음은 템플릿이 실제로 어떻게 실행되는지를 보여줍니다. 보이는 바와 같이, 초기에 blank 로 보여집니다.

+ +

{{EmbedLiveSample("A_skeleton_template", 160, 160)}}

+ +

기본 예제

+ +

먼저 두 개의 직사각형을 그린 간단한 예제를 보도록하겠습니다. 그 중 하나는 투명도(alpha transparency)를가집니다. 나중에 이 예제가 어떻게 작동하는지 자세히 살펴 보겠습니다.

+ +
<!DOCTYPE html>
+<html>
+ <head>
+  <meta charset="utf-8"/>
+  <script type="application/javascript">
+    function draw() {
+      var canvas = document.getElementById("canvas");
+      if (canvas.getContext) {
+        var ctx = canvas.getContext("2d");
+
+        ctx.fillStyle = "rgb(200,0,0)";
+        ctx.fillRect (10, 10, 50, 50);
+
+        ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
+        ctx.fillRect (30, 30, 50, 50);
+      }
+    }
+  </script>
+ </head>
+ <body onload="draw();">
+   <canvas id="canvas" width="150" height="150"></canvas>
+ </body>
+</html>
+
+ +

이 예제는 다음과 같습니다.

+ +

{{EmbedLiveSample("A_simple_example", 160, 160, "https://mdn.mozillademos.org/files/228/canvas_ex1.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/compositing/example/index.html b/files/ko/web/api/canvas_api/tutorial/compositing/example/index.html new file mode 100644 index 0000000000..e3d74f5220 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/compositing/example/index.html @@ -0,0 +1,293 @@ +--- +title: 도형 합성 예제 +slug: Web/HTML/Canvas/Tutorial/Compositing/Example +tags: + - HTML5 + - 그래픽 + - 예제 + - 캔버스 +translation_of: Web/API/Canvas_API/Tutorial/Compositing/Example +--- +
{{CanvasSidebar}}
+ +

이 샘플 프로그램에서는 여러 가지 도형 합성 방법을 보여줍니다. 출력은 다음과 같습니다:

+ +

{{ EmbedLiveSample('도형_합성_예제', '100%', '7250', '', 'Web/HTML/Canvas/Tutorial/Compositing/Example') }}

+ +

도형 합성 예제

+ +

다음 코드에서는 프로그램의 나머지 부분에서 사용할 전역 값을 설정합니다.

+ +
var canvas1 = document.createElement("canvas");
+var canvas2 = document.createElement("canvas");
+var gco = [ 'source-over','source-in','source-out','source-atop',
+            'destination-over','destination-in','destination-out','destination-atop',
+            'lighter', 'copy','xor', 'multiply', 'screen', 'overlay', 'darken',
+            'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
+            'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
+          ].reverse();
+var gcoText = [
+'기본 설정으로, 새로운 도형이 원래 도형 위에 그려집니다.',
+'새로운 도형이 원래 도형과 겹치는 부분에만 그려지며, 나머지는 투명하게 설정됩니다.',
+'새로운 도형이 원래 도형과 겹치지 않는 부분에만 그려집니다.',
+'새로운 도형이 원래 도형과 겹치는 부분에만 그려집니다.',
+'새로운 도형이 원래 도형 아래에 그려집니다.',
+'원래 도형 중 새로운 도형과 겹치는 부분이 유지되며, 나머지는 투명하게 설정됩니다.',
+'원래 도형 중 새로운 도형과 겹치지 않는 부분이 유지됩니다.',
+'원래 도형 중 새로운 도형과 겹치는 부분만 유지됩니다. 새로운 도형은 원래 도형 아래에 그려집니다.',
+'두 도형이 겹치는 곳의 색상이 두 색상값을 합한 값으로 결정됩니다.',
+'새로운 도형만 그려집니다.',
+'두 도형이 겹치는 곳이 투명하게 변하며, 나머지는 평범하게 그려집니다.',
+'위쪽 레이어의 픽셀값이 아래쪽 레이어의 해당하는 픽셀값과 곱해지며, 결과적으로 어두운 이미지가 생성됩니다.',
+'픽셀값을 뒤집고 곱한 다음 도로 뒤집습니다. 결과적으로 밝은 이미지가 생성됩니다(multiply의 반대).',
+'multiply와 screen의 조합입니다. 아래쪽 레이어의 어두운 부분은 더 어두워지고, 밝은 부분은 더 밝아집니다.',
+'두 레이어 중 어두운 픽셀값을 취합니다.',
+'두 레이어 중 밝은 픽셀값을 취합니다.',
+'아래쪽 레이어의 픽셀값을 위쪽 레이어의 뒤집힌 픽셀값으로 나눕니다.',
+'아래쪽 레이어의 뒤집힌 픽셀값을 위쪽 레이어의 픽셀값으로 나누고, 그 값을 도로 뒤집습니다.',
+'overlay와 같이 multiply와 screen의 조합이지만, 위아래 레이어의 순서가 바뀐 상태입니다.',
+'조금 더 부드러운 hard-light입니다. 완전한 검은색/흰색에서 무조건 완전한 검은색/흰색이 나오지 않습니다.',
+'한쪽 레이어의 픽셀값에서 다른 쪽 레이어의 픽셀값을 뺍니다. 빼는 순서는 결과값이 양수가 나오는 순서입니다.',
+'difference와 비슷하지만 대비가 덜합니다.',
+'아래쪽 레이어의 채도(chroma)와 명도(luma)를 보존하고 위쪽 레이어의 색상(hue)을 적용합니다.',
+'아래쪽 레이어의 색상과 명도를 보존하고 위쪽 레이어의 채도를 적용합니다.',
+'아래쪽 레이어의 명도를 보존하고 위쪽 레이어의 색상과 채도를 적용합니다.',
+'아래쪽 레이어의 색상과 채도를 보존하고 위쪽 레이어의 명도를 적용합니다.'
+          ].reverse();
+var width = 320;
+var height = 340;
+
+ +

메인 프로그램

+ +

페이지를 불러오고 나면 다음 코드에서 예제를 준비하고 실행합니다:

+ +
window.onload = function() {
+    // lum in sRGB
+    var lum = {
+        r: 0.33,
+        g: 0.33,
+        b: 0.33
+    };
+    // 캔버스 크기 변경
+    canvas1.width = width;
+    canvas1.height = height;
+    canvas2.width = width;
+    canvas2.height = height;
+    lightMix()
+    colorSphere();
+    runComposite();
+    return;
+};
+
+ +

또한 다음 코드의 runComposite()가 여러 가지 작업을 처리하며, 어려운 부분은 보조 함수를 사용합니다.

+ +
function createCanvas() {
+    var canvas = document.createElement("canvas");
+    canvas.style.background = "url("+op_8x8.data+")";
+    canvas.style.border = "1px solid #000";
+    canvas.style.margin = "5px";
+    canvas.width = width/2;
+    canvas.height = height/2;
+    return canvas;
+}
+
+function runComposite() {
+    var dl = document.createElement("dl");
+    document.body.appendChild(dl);
+    while(gco.length) {
+        var pop = gco.pop();
+        var dt = document.createElement("dt");
+        dt.textContent = pop;
+        dl.appendChild(dt);
+        var dd = document.createElement("dd");
+        var p = document.createElement("p");
+        p.textContent = gcoText.pop();
+        dd.appendChild(p);
+
+        var canvasToDrawOn = createCanvas();
+        var canvasToDrawFrom = createCanvas();
+        var canvasToDrawResult = createCanvas();
+
+        var ctx = canvasToDrawResult.getContext('2d');
+        ctx.clearRect(0, 0, width, height)
+        ctx.save();
+        ctx.drawImage(canvas1, 0, 0, width/2, height/2);
+        ctx.globalCompositeOperation = pop;
+        ctx.drawImage(canvas2, 0, 0, width/2, height/2);
+        ctx.globalCompositeOperation = "source-over";
+        ctx.fillStyle = "rgba(0,0,0,0.8)";
+        ctx.fillRect(0, height/2 - 20, width/2, 20);
+        ctx.fillStyle = "#FFF";
+        ctx.font = "14px arial";
+        ctx.fillText(pop, 5, height/2 - 5);
+        ctx.restore();
+
+        var ctx = canvasToDrawOn.getContext('2d');
+        ctx.clearRect(0, 0, width, height)
+        ctx.save();
+        ctx.drawImage(canvas1, 0, 0, width/2, height/2);
+        ctx.fillStyle = "rgba(0,0,0,0.8)";
+        ctx.fillRect(0, height/2 - 20, width/2, 20);
+        ctx.fillStyle = "#FFF";
+        ctx.font = "14px arial";
+        ctx.fillText('기존 도형', 5, height/2 - 5);
+        ctx.restore();
+
+        var ctx = canvasToDrawFrom.getContext('2d');
+        ctx.clearRect(0, 0, width, height)
+        ctx.save();
+        ctx.drawImage(canvas2, 0, 0, width/2, height/2);
+        ctx.fillStyle = "rgba(0,0,0,0.8)";
+        ctx.fillRect(0, height/2 - 20, width/2, 20);
+        ctx.fillStyle = "#FFF";
+        ctx.font = "14px arial";
+        ctx.fillText('새로운 도형', 5, height/2 - 5);
+        ctx.restore();
+
+        dd.appendChild(canvasToDrawOn);
+        dd.appendChild(canvasToDrawFrom);
+        dd.appendChild(canvasToDrawResult);
+
+        dl.appendChild(dd);
+    }
+};
+
+ +

보조 함수

+ +

이 프로그램에서는 몇몇 보조 함수를 사용합니다.

+ +
var lightMix = function() {
+    var ctx = canvas2.getContext("2d");
+    ctx.save();
+    ctx.globalCompositeOperation = "lighter";
+    ctx.beginPath();
+    ctx.fillStyle = "rgba(255,0,0,1)";
+    ctx.arc(100, 200, 100, Math.PI*2, 0, false);
+    ctx.fill()
+    ctx.beginPath();
+    ctx.fillStyle = "rgba(0,0,255,1)";
+    ctx.arc(220, 200, 100, Math.PI*2, 0, false);
+    ctx.fill()
+    ctx.beginPath();
+    ctx.fillStyle = "rgba(0,255,0,1)";
+    ctx.arc(160, 100, 100, Math.PI*2, 0, false);
+    ctx.fill();
+    ctx.restore();
+    ctx.beginPath();
+    ctx.fillStyle = "#f00";
+    ctx.fillRect(0,0,30,30)
+    ctx.fill();
+};
+
+ +
var colorSphere = function(element) {
+    var ctx = canvas1.getContext("2d");
+    var width = 360;
+    var halfWidth = width / 2;
+    var rotate = (1 / 360) * Math.PI * 2; // per degree
+    var offset = 0; // scrollbar offset
+    var oleft = -20;
+    var otop = -20;
+    for (var n = 0; n <= 359; n ++) {
+        var gradient = ctx.createLinearGradient(oleft + halfWidth, otop, oleft + halfWidth, otop + halfWidth);
+        var color = Color.HSV_RGB({ H: (n + 300) % 360, S: 100, V: 100 });
+        gradient.addColorStop(0, "rgba(0,0,0,0)");
+        gradient.addColorStop(0.7, "rgba("+color.R+","+color.G+","+color.B+",1)");
+        gradient.addColorStop(1, "rgba(255,255,255,1)");
+        ctx.beginPath();
+        ctx.moveTo(oleft + halfWidth, otop);
+        ctx.lineTo(oleft + halfWidth, otop + halfWidth);
+        ctx.lineTo(oleft + halfWidth + 6, otop);
+        ctx.fillStyle = gradient;
+        ctx.fill();
+        ctx.translate(oleft + halfWidth, otop + halfWidth);
+        ctx.rotate(rotate);
+        ctx.translate(-(oleft + halfWidth), -(otop + halfWidth));
+    }
+    ctx.beginPath();
+    ctx.fillStyle = "#00f";
+    ctx.fillRect(15,15,30,30)
+    ctx.fill();
+    return ctx.canvas;
+};
+
+ +
// HSV (1978) = H: Hue / S: Saturation / V: Value
+Color = {};
+Color.HSV_RGB = function (o) {
+    var H = o.H / 360,
+        S = o.S / 100,
+        V = o.V / 100,
+        R, G, B;
+    var A, B, C, D;
+    if (S == 0) {
+        R = G = B = Math.round(V * 255);
+    } else {
+        if (H >= 1) H = 0;
+        H = 6 * H;
+        D = H - Math.floor(H);
+        A = Math.round(255 * V * (1 - S));
+        B = Math.round(255 * V * (1 - (S * D)));
+        C = Math.round(255 * V * (1 - (S * (1 - D))));
+        V = Math.round(255 * V);
+        switch (Math.floor(H)) {
+            case 0:
+                R = V;
+                G = C;
+                B = A;
+                break;
+            case 1:
+                R = B;
+                G = V;
+                B = A;
+                break;
+            case 2:
+                R = A;
+                G = V;
+                B = C;
+                break;
+            case 3:
+                R = A;
+                G = B;
+                B = V;
+                break;
+            case 4:
+                R = C;
+                G = A;
+                B = V;
+                break;
+            case 5:
+                R = V;
+                G = A;
+                B = B;
+                break;
+        }
+    }
+    return {
+        R: R,
+        G: G,
+        B: B
+    };
+};
+
+var createInterlace = function (size, color1, color2) {
+    var proto = document.createElement("canvas").getContext("2d");
+    proto.canvas.width = size * 2;
+    proto.canvas.height = size * 2;
+    proto.fillStyle = color1; // top-left
+    proto.fillRect(0, 0, size, size);
+    proto.fillStyle = color2; // top-right
+    proto.fillRect(size, 0, size, size);
+    proto.fillStyle = color2; // bottom-left
+    proto.fillRect(0, size, size, size);
+    proto.fillStyle = color1; // bottom-right
+    proto.fillRect(size, size, size, size);
+    var pattern = proto.createPattern(proto.canvas, "repeat");
+    pattern.data = proto.canvas.toDataURL();
+    return pattern;
+};
+
+var op_8x8 = createInterlace(8, "#FFF", "#eee");
diff --git a/files/ko/web/api/canvas_api/tutorial/compositing/index.html b/files/ko/web/api/canvas_api/tutorial/compositing/index.html new file mode 100644 index 0000000000..108c493d9d --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/compositing/index.html @@ -0,0 +1,106 @@ +--- +title: 도형 합성 +slug: Web/HTML/Canvas/Tutorial/Compositing +tags: + - HTML5 + - 그래픽 + - 캔버스 +translation_of: Web/API/Canvas_API/Tutorial/Compositing +--- +

이전 페이지들에서 나온 모든 예제에서, 새로 그리는 도형은 언제나 이미 그려진 도형의 위에 그려졌습니다. 대부분의 상황에서는 이렇게 하는 것이 적절하지만, 도형을 합성하기 위한 순서를 제한하게 되는데,  globalCompositeOperation 속성을 설정함으로써 이러한 상태를 바꿀 수 있습니다.

+ +

globalCompositeOperation

+ +

기존 도형 뒤에 새로운 도형을 그릴 수 있을 뿐만 아니라, 도형의 일정 영역을 가려 보이지 않게 하거나 캔버스의 특정 부분을 지우는 (clearRect() 메소드는 사각형의 영역만을 지우지만, 이같은 제한도 없다.) 등의 효과를 얻을 수도 있습니다.

+ +
+
globalCompositeOperation = type
+
새로운 도형을 그릴 때, 도형 합성 방법을 설정합니다. type은 다음 26종류의 합성 방법 중에서 선택할 수 있습니다.
+
+ +

다음 예제의 코드를 확인하려면 도형 합성 예제를 확인해 주세요.

+ +

{{ EmbedLiveSample('도형_합성_예제', 750, 6750, '', 'Web/HTML/Canvas/Tutorial/Compositing/Example') }}

+ +

잘라내기 경로(Clipping path)

+ +

 잘라내기 경로는 다른 캔버스 도형과 비슷하지만, 다른 도형에서 원하지 않는 부분을 가리는 가면과 같은 역할을 합니다. 오른쪽에 있는 그림을 보면 어떤 역할을 하는지 알 수 있을 것입니다. 붉은 별 모양이 잘라내기 경로입니다. 이 경로 밖에 있는 모든 것은 캔버스에 그려지지 않을 것입니다.

+ +

잘라내기 경로와 위에서 살펴본  globalCompositeOperation 속성을 비교해 보면,   source-insource-atop에서 비슷한 효과가 보입니다. 이들과 잘라내기 경로와의 가장 중요한 차이점은, 잘라내기 경로 자체는 캔버스에 전혀 그려지지 않는다는 것입니다. 잘라내기 경로는 제한된 영역 안에서 여러 가지 도형을 그리는 데에 적합합니다.

+ +

캔버스에 도형 그리기에서는 stroke()fill() 메소드만을 설명했었는데, clip()이라는 세 번째 메소드도 있습니다.

+ +
+
clip()
+
현재 그려지는 경로를 현재 잘라내기 경로로 만듭니다.
+
+ +

경로를 닫기 위해 closePath() 대신 clip()을 사용하고, 경로를 채우거나 윤곽선을 만드는 대신 잘라내기 경로로 만들 수 있습니다.

+ +

{{HTMLElement("canvas")}} 요소의 초기 설정값으로써, 캔버스는 캔버스와 똑같은 크기의 잘라내기 경로를 가집니다. 크기가 똑같기 때문에 잘라내기 효과는 나타나지 않습니다.

+ +

clip 예제

+ +

다음 예제에서는 특정 영역의 별들만 보이도록 동그란 모양의 잘라내기 경로를 사용할 것입니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.fillRect(0,0,150,150);
+  ctx.translate(75,75);
+
+  // 동그란 모양의 잘라내기 경로를 생성한다
+  ctx.beginPath();
+  ctx.arc(0,0,60,0,Math.PI*2,true);
+  ctx.clip();
+
+  // 배경을 그린다
+  var lingrad = ctx.createLinearGradient(0,-75,0,75);
+  lingrad.addColorStop(0, '#232256');
+  lingrad.addColorStop(1, '#143778');
+
+  ctx.fillStyle = lingrad;
+  ctx.fillRect(-75,-75,150,150);
+
+  // 별을 그린다
+  for (var j=1;j<50;j++){
+    ctx.save();
+    ctx.fillStyle = '#fff';
+    ctx.translate(75-Math.floor(Math.random()*150),
+                  75-Math.floor(Math.random()*150));
+    drawStar(ctx,Math.floor(Math.random()*4)+2);
+    ctx.restore();
+  }
+
+}
+
+function drawStar(ctx,r){
+  ctx.save();
+  ctx.beginPath()
+  ctx.moveTo(r,0);
+  for (var i=0;i<9;i++){
+    ctx.rotate(Math.PI/5);
+    if(i%2 == 0) {
+      ctx.lineTo((r/0.525731)*0.200811,0);
+    } else {
+      ctx.lineTo(r,0);
+    }
+  }
+  ctx.closePath();
+  ctx.fill();
+  ctx.restore();
+}
+
+ + + +

코드의 위쪽 몇 줄에서는 배경으로 캔버스 크기와 같은 검은색 네모를 그리고, 가운데로 원점을 옮깁니다. 그런 다음 호를 그리고 clip()을 사용하여 동그란 모양의 잘라내기 경로를 생성합니다. 캔버스 상태를 저장할 때 잘라내기 경로도 같이 저장됩니다. 이전의 잘라내기 경로를 보존하려면, 새로운 잘라내기 경로를 만들기 전에 캔버스 상태를 저장하면 됩니다.

+ +

잘라내기 경로를 만든 후에 그려지는 모든 것들은, 그 경로의 안쪽에서만 보입니다. 이는 그 다음에 그려지는 선형 그라디언트에서 확실히 볼 수 있습니다. 이렇게 하고 나서, drawStar() 함수를 사용하여 위치와 크기가 모두 다른 50개의 별을 그립니다. 이 별들은 잘라내기 경로 안쪽에만 나타납니다.

+ +

{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}

+ +

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Transformations", "Web/Guide/HTML/Canvas_tutorial/Basic_animations")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/drawing_shapes/index.html b/files/ko/web/api/canvas_api/tutorial/drawing_shapes/index.html new file mode 100644 index 0000000000..09df4b829d --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/drawing_shapes/index.html @@ -0,0 +1,577 @@ +--- +title: 캔버스(canvas)를 이용한 도형 그리기 +slug: Web/HTML/Canvas/Tutorial/Drawing_shapes +tags: + - Canvas + - 그래픽 + - 중급 + - 캔버스 + - 튜토리얼 +translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
+ +
+

앞서 캔버스 환경 설정(canvas environment)을 완료 하였다면, 이제 어떻게 캔버스에 그릴수 있는지에 대하여 자세하게 알아봅시다. 이 글을 끝내고 난 후, 여러분은 어떻게 사각형, 삼각형, 선, 아치, 곡선 등 의 기본적인 도형을 그릴수 있는지 익히실 수 있을 것 입니다.  캔버스 위에 물체를 그릴 때에는 path를 사용하는것이 필수적이므로 우리는 이것이 어떻게 사용되는지 볼 것입니다.

+
+ +

그리드

+ +

드로잉을 시작 하기에 앞서, 캔버스 그리드 혹은 좌표공간 (coordinate space) 에 대하여 이야기 해보겠습니다. 이전 페이지에서 이야기 했던 HTML 골격(skeleton)는 가로 세로 각각 150 픽셀의 캔버스 요소를 가지고 있습니다. 오른쪽에 보시면, 캔버스와 기본 그리드가 놓인것을 보실 수 있습니다. 기본적으로 그리드의 1단위는 캔버스의 1픽셀과 같습니다. 이 그리드의 원점은 좌측상단의 (0,0) 입니다. 모든 요소들은 이 원점을 기준으로 위치됩니다. 그렇기 때문에, 파란 사각형의 좌측상단은 왼쪽에서 x 픽셀, 위에서 y 픽셀 떨어진 것이라 볼 수 있고, 이 사각형의 좌표는 (x,y)가 됩니다. 이 튜토리얼 후반부에서 어떻게 원점을 이동하며, 그리드를 회전하고 같은 비율로 확대/축소할 수 있는지 살펴볼 것이지만, 지금은 기본에 충실하도록 합시다.

+ +

직사각형 그리기

+ +

{{Glossary("SVG")}} 와는 다르게, {{HTMLElement("canvas")}}는 오직 하나의 원시적인 도형만을 제공합니다. 바로 직사각형 입니다. 다른 모든 도형들은 무조건 하나 혹은 하나 이상의 path 와 여러 점으로 이어진 선으로 만들어집니다. 다행히도, 우리는 여러 path drawing 함수(function)들을 통해 아주 어려운 도형들도 그릴수 있습니다.

+ +

첫번째로, 직사각형을 봅시다. 캔버스 위에 직사각형을 그리는데에는 세가지 함수(function)가 있습니다:

+ +
+
{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}
+
색칠된 직사각형을 그립니다.
+
{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}
+
직사각형 윤곽선을 그립니다.
+
{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}
+
특정 부분을 지우는 직사각형이며, 이 지워진 부분은 완전히 투명해집니다.
+
+ +

각각의 세 함수는 모두 같은 변수를 가집니다. xy는 캔버스의 좌측상단에서 사각형의 (원점으로부터 상대적인) 위치를 뜻하며,  width 와 height는 사각형의 크기를 뜻하게 됩니다.

+ +

전 페이지에서 보여드렸던 draw() 함수(function)를 이용하여 위의 세가지 함수를 아래의 예제에 적용해 보았습니다.

+ +

직사각형 도형 예제

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    ctx.fillRect(25, 25, 100, 100);
+    ctx.clearRect(45, 45, 60, 60);
+    ctx.strokeRect(50, 50, 50, 50);
+  }
+}
+ +

위 예제의 결과는 다음과 같습니다.

+ +

{{EmbedLiveSample("Rectangular_shape_example", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}

+ +

fillRect() 함수는 가로 세로 100 픽셀 사이즈의 검정 사각형을 그립니다. 이후 clearRect() 함수가 60x60 픽셀의 사각형 크기로 도형 중앙을 지우게 되고, strokeRect()은 이 빈 사각형 공간 안에 50x50 픽셀 사이즈의 윤곽선만 있는 사각형을 만들게 됩니다.

+ +

다음 페이지에서, 우리는 clearRect()를 대신하는 두개의 함수에 대해 살펴보고, 만들어진 도형의 색이나 윤곽선의 스타일을 바꾸는 방법들에 대하여 알아보도록 하겠습니다.

+ +

우리가 다음 섹션에서 보게될 path 함수와 다르게 세개의 직사각형 함수는 캔버스에 바로 그릴 수 있습니다.

+ +

경로 그리기

+ +

경로(path)는 직사각형 이외의 유일한 원시적인(primitive) 도형입니다. 경로는 점들의 집합이며, 선의 한 부분으로 연결되어 여러가지 도형, 곡선을 이루고 두께와 색을 나타내게 됩니다. 경로나 하위 경로(sub-path)는 닫힐 수 있습니다. 경로를 이용하여 도형을 만들 때에는 몇가지 추가적인 단계를 거쳐야 합니다:

+ +
    +
  1. 경로를 생성합니다.
  2. +
  3. 그리기 명령어를 사용하여 경로상에 그립니다.
  4. +
  5. 경로가 한번 만들어졌다면, 경로를 렌더링 하기 위해서 윤곽선을 그리거나 도형 내부를 채울수 있습니다.
  6. +
+ +

다음은 위의 단계들을 실행하기 위해 사용되는 함수입니다:

+ +
+
{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}
+
새로운 경로를 만듭니다. 경로가 생성됬다면, 이후 그리기 명령들은 경로를 구성하고 만드는데 사용하게 됩니다.
+
Path 메소드 (Path methods)
+
물체를 구성할 때 필요한 여러 경로를 설정하는데 사용하는 함수입니다.
+
{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}
+
현재 하위 경로의 시작 부분과 연결된 직선을 추가합니다.
+
{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}
+
윤곽선을 이용하여 도형을 그립니다.
+
{{domxref("CanvasRenderingContext2D.fill", "fill()")}}
+
경로의 내부를 채워서 내부가 채워진 도형을 그립니다.
+
+ +

경로를 만들기 위한 첫번째 단계는 beginPath() 메소드를 사용하는 것 입니다. 내부적으로, 경로는 도형을 이루는 하위경로(선, 아치 등)들의 집합으로 이루어져있습니다. 이 메소드가 호출될 때 마다, 하위 경로의 모음은 초기화되며, 우리는 새로운 도형을 그릴 수 있게 됩니다.

+ +
참고:  현재 열린 path가  비어있는 경우 ( beginPath() 메소드를 사용한 직 후, 혹은캔버스를 새로 생성한 직후), 첫 경로 생성 명령은 실제 동작에 상관 없이 moveTo()로 여겨지게 됩니다. 그렇기 때문에 경로를 초기화한 직후에는 항상 명확하게 시작 위치를 설정해 두는것이 좋습니다.
+ +

두번째 단계는 실제로 경로가 그려지는 위치를 설정하는 메소드를 호출하는 것 입니다. 이 내용에 대해서는 곧 보실수 있습니다.

+ +

세번째 단계는 선택사항으로 closePath() 메소드를 호출하는 것 입니다. 이 메소드는 현재 점 위치와 시작점 위치를 직선으로 이어서 도형을 닫습니다. 이미 도형이 닫혔거나 한 점만 존재한다면, 이 메소드는 아무것도 하지 않습니다.

+ +
참고:  fill() 메소드 호출 시, 열린 도형은 자동으로 닫히게 되므로  closePath()메소드를 호출하지 않아도 됩니다. 이것은 stroke() 메소드에는 적용되지 않습니다.
+ +

삼각형 그리기

+ +

예를 들어, 삼각형을 그리기 위한 코드는 다음과 같습니다:

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    ctx.beginPath();
+    ctx.moveTo(75, 50);
+    ctx.lineTo(100, 75);
+    ctx.lineTo(100, 25);
+    ctx.fill();
+  }
+}
+
+ +

위 코드의 실행 결과는 다음과 같습니다:

+ +

{{EmbedLiveSample("Drawing_a_triangle", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}

+ +

펜(pen) 이동하기

+ +

가장 유용한 함수중에 실제로 어떤 것도 그리지 않지만 위에서 언급한 경로의 일부가 되는  moveTo() 함수가 있습니다. 이는 펜이나 연필을 종이위에서 들어 옆으로 옮기는것이라고 보시면 됩니다.

+ +
+
{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}
+
펜을  x와 y 로 지정된 좌표로 옮깁니다.
+
+ +

캔버스가 초기화 되었거나 beginPath() 메소드가 호출되었을 때, 특정 시작점 설정을 위해 moveTo() 함수를 사용하는것이 좋습니다. 또한 moveTo()  함수는 연결되지 않은 경로를 그리는데에도 사용 할 수 있습니다. 아래의 스마일 아이콘을 봅시다.

+ +

코드 snippet을 사용해하여 직접 시도하여 보세요. 앞에서 보았던 draw() 함수(function)를 붙혀넣기 해 보세요.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+     var ctx = canvas.getContext('2d');
+
+    ctx.beginPath();
+    ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
+    ctx.moveTo(110, 75);
+    ctx.arc(75, 75, 35, 0, Math.PI, false);  // Mouth (clockwise)
+    ctx.moveTo(65, 65);
+    ctx.arc(60, 65, 5, 0, Math.PI * 2, true);  // Left eye
+    ctx.moveTo(95, 65);
+    ctx.arc(90, 65, 5, 0, Math.PI * 2, true);  // Right eye
+    ctx.stroke();
+  }
+}
+
+ +

결과는 다음과 같습니다:

+ +

{{EmbedLiveSample("Moving_the_pen", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}

+ +

 moveTo()를 사용한 코드라인을 지우면 연결된 선들을 확인 할 수 있습니다

+ +
+

참고: arc() function에 대하여 더 알아보고 싶다면 아래의  {{anch("Arcs")}} 를 확인하세요.

+
+ +

+ +

직선을 그리기 위해서는 lineTo() 메소드를 사용할 수 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}
+
현재의 드로잉 위치에서 x와 y로 지정된 위치까지 선을 그립니다.
+
+ +

이 메소드는 선의 끝점의 좌표가 되는 x와 y의 두개의 인자가 필요합니다. 시작점은 이전에 그려진 경로에 의해 결정 되며, 이전 경로의 끝점이 다음 그려지는 경로의 시작점이 됩니다. 또한 시작점은 moveTo() 메소드를 통해 변경될 수 있습니다.

+ +

아래의 예시는 하나의 두 삼각형 (윤곽선 삼각형, 색칠된 삼각형)을 그립니다.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    // Filled triangle
+    ctx.beginPath();
+    ctx.moveTo(25, 25);
+    ctx.lineTo(105, 25);
+    ctx.lineTo(25, 105);
+    ctx.fill();
+
+    // Stroked triangle
+    ctx.beginPath();
+    ctx.moveTo(125, 125);
+    ctx.lineTo(125, 45);
+    ctx.lineTo(45, 125);
+    ctx.closePath();
+    ctx.stroke();
+  }
+}
+
+ +

새로운 경로를 지정하기 위해 beginPath() 메소드를 먼저 실행합니다. 그 다음 moveTo() 메소드를 가지고 시작점을 원하는 위치로 새롭게 지정 해 줍니다. 다음은, 두선을 그어 삼각형의 두 면을 그려줍니다.

+ +

{{EmbedLiveSample("Lines", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}

+ +

여러분은 채워진 삼각형과 윤곽선 삼각형의 차이를 확인 하셨을 겁니다. 위에 언급했던 것 처럼, 경로가 채워지게 되면 그 도형은 자동으로 닫히게 되지만 윤곽선 삼각형에서는 그렇지 않기 때문입니다. 만약에 closePath() 메소드를 윤곽선 삼각형 코드에서 지운다면, 오직 두 선만 그려지게 되며 완벽한 삼각형으로 만들어지지 않습니다.

+ +

호(arc)

+ +

호나 원을 그리기위해서는 arc() 혹은 arcTo() 메소드를 사용합니다..

+ +
+
{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}
+
(x, y) 위치에 원점을 두면서, 반지름 r을 가지고,  startAngle 에서 시작하여 endAngle 에서 끝나며 주어진 anticlockwise 방향으로 향하는 (기본값은 시계방향 회전) 호를 그리게 됩니다.
+
{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}
+
주어진 제어점들과 반지름으로 호를 그리고,  이전 점과 직선으로 연결합니다.
+
+ +

arc 메소드의 여섯개의 매개변수에 대하여 좀 더 자세하게 알아봅시다: xy는 호를 그릴 때 필요한 원점 좌표입니다. 반지름(radius) 은 말 그대로 호의 반지름을 뜻합니다. startAngleendAngle 매개 변수는 원의 커브를 따라 호의 시작점과 끝점을 라디안 단위로 정의합니다. 이 변수들은 x축을 기준으로 계산됩니다. Boolean 값을 가지는 anticlockwise 변수는 true일 때 호를 반시계 방향으로 그리게 되며, 그렇지 않을 경우에는 시계 방향으로 그리게 됩니다.

+ +
+

참고: arc 함수에서 각도는 각이 아닌 라디안 값을 사용합니다. 각도를 라디안으로 바꾸려면 다음의 자바스크립트(JavaScript) 코드를 사용하실 수 있습니다: radians = (Math.PI/180)*degrees.

+
+ +

다음의 예제는 우리가 이제껏 봐 왔던 예제들 보다 약간 더 복잡합니다. 이 예제는 12가지의 다양한 각도로 채워진 각기 다른 호를 그립니다.

+ +

두개의  for loops은 루프를 통해 호(arc)들의 행과 열을 읽기 위해 사용되었습니다. beginPath()를 사용해 각 호의 새로운 경로를 만듭니다. 코드 내에서, 각각의 매개변수들을 명확하게 보여주기 위해 변수로 정의 하였지만, 실제로 사용할때 꼭 필요한 것은 아닙니다.

+ +

xy 좌표는 충분히 명확하게 표기되어야 합니다.  radius 와 startAngle은 고정되어 있습니다. endAngle는 처음 180도 (반원) 에서 시작하고 이후 매번 90도씩 증가하다가 마지막 열에서 완벽한 원을 그립니다.

+ +

clockwise 매개 변수를 지정한 결과로 첫번째와 세번째 줄은 시계방향으로 원호들이 그려졌고 두번째와 네번째 줄에는 반시계방향의 원호들이 그려졌습니다. 마지막으로 if 문은 위 반쪽이 윤곽선으로, 아래 반쪽이 색으로 채워진 호들을 만들어 냅니다.

+ +
+

참고: 이 예제는 다른 예제들 보다 더 큰사이즈의 캔버스가 필요합니다: 150 x 200 픽셀

+
+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    for (var i = 0; i < 4; i++) {
+      for (var j = 0; j < 3; j++) {
+        ctx.beginPath();
+        var x = 25 + j * 50; // x coordinate
+        var y = 25 + i * 50; // y coordinate
+        var radius = 20; // Arc radius
+        var startAngle = 0; // Starting point on circle
+        var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
+        var anticlockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
+
+        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
+
+        if (i > 1) {
+          ctx.fill();
+        } else {
+          ctx.stroke();
+        }
+      }
+    }
+  }
+}
+
+ +

{{EmbedLiveSample("Arcs", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}

+ +

베지어(Bezier) 곡선과 이차(Quadratic )곡선

+ +

다음 경로 타입은 베지어 곡선 (Bézier curves)으로, 삼차(cubic)와 이차(quadric) 변수가 모두 가능합니다. 이 타입은 대게 복잡한 유기체적 형태 (organic shape)를 그리는데 사용됩니다.

+ +
+
{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}
+
cp1xcp1y로 지정된 제어점을 사용하여 현재 펜의 위치에서 x와 y로 지정된 끝점까지 이차 베지어 곡선을 그립니다.
+
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}
+
(cp1x, cp1y) 및 (cp2x, cp2y)로 지정된 제어점을 사용하여 현재 펜 위치에서 xy로 지정된 끝점까지 삼차 베지어 곡선을 그립니다.
+
+ +

오른쪽의 사진은 두 곡선의 차이를 가장 잘 설명해주고 있습니다. 이차 베지에 곡선은 시작점과 끝점 (파란색 점) 그리고 하나의 제어점 (control point, 빨간 점으로 표시)을 가지고 있지만, 삼차 베지에 곡선은 두개의 제어점을 사용하고 있습니다.

+ +

두 메소드에 모두 사용되는 xy 변수는 모두 끝점의 좌표를 나타냅니다. 첫번째 제어점은 cp1x 와 cp1y 좌표로, 두번째 제어점은 cp2x 와 cp2y  좌표로 표시되었습니다.

+ +

이차 및 삼차 베지어 곡선을 사용하는 것은 매우 어려울 수 있습니다. Adobe Illustrator와 같은 벡터 드로잉 소프트웨어와는 달리, 우리는 현재 수행중인 작업에 대해 직접적인 시각적 피드백을 받을 수 없기 때문입니다. 이런 점은 복잡한 모양을 그리기 어렵도록 합니다. 다음 예제에서 우리는 간단한 유기체적 형태만 그리도록 하겠지만, 여러분이 연습과 시간을 투자 하신다면, 이후에 더욱 복잡한 도형을 그릴수 있게 될 것입니다.

+ +

이 예제는 아주 어려운 점은 없습니다. 두 경우 모두 연속된 곡선이 그려지면서 최종 모양이 완성됩니다.

+ +

이차 베지에 곡선(Quadratic Bezier curves)

+ +

이 예제는 여러개의 이차 베지어 곡선을 이용해 말풍선을 만들어 냅니다.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    // Quadratric curves example
+    ctx.beginPath();
+    ctx.moveTo(75, 25);
+    ctx.quadraticCurveTo(25, 25, 25, 62.5);
+    ctx.quadraticCurveTo(25, 100, 50, 100);
+    ctx.quadraticCurveTo(50, 120, 30, 125);
+    ctx.quadraticCurveTo(60, 120, 65, 100);
+    ctx.quadraticCurveTo(125, 100, 125, 62.5);
+    ctx.quadraticCurveTo(125, 25, 75, 25);
+    ctx.stroke();
+  }
+}
+
+ +

{{EmbedLiveSample("Quadratic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}

+ +

삼차 베지어 곡선 (Cubic Bezier curves)

+ +

이 예제는 삼차 곡선을 이용하여 하트를 그립니다.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    // Cubic curves example
+    ctx.beginPath();
+    ctx.moveTo(75, 40);
+    ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
+    ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
+    ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
+    ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
+    ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
+    ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
+    ctx.fill();
+  }
+}
+
+ +

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}

+ +

직사각형

+ +

직사각형을 캔버스에 직접 그리는 {{anch("직사각형 그리기")}}에서 본 세 가지 메소드 외에 rect() 메소드도 있습니다. 이 메소드는 현재 열린 패스에 직사각형 경로를 추가합니다.

+ +
+
{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}
+
좌측상단이 (x, y)이고 폭과 높이가 widthheight인 직사각형을 그립니다.
+
+ +

이 메소드가 실행되기 전에, (x,y) 매개변수를 가진 moveTo() 메소드가 자동으로 호출됩니다. 즉, 현재의 펜위치가 자동으로 기본 좌표로 초기화 됩니다.

+ +

조합하기

+ +

이제까지 이 페이지의 예제들은 각각의 도형마다 하나의 path 함수를 가지고 있었습니다. 하지만 도형을 만드는데에 사용되는 경로의 종류와 개수는 제한이 없습니다. 그렇기 때문에 이 마지막 예제에서는 모든 경로 함수를 합쳐 여러 게임 캐릭터들을 그려보도록 하겠습니다.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    roundedRect(ctx, 12, 12, 150, 150, 15);
+    roundedRect(ctx, 19, 19, 150, 150, 9);
+    roundedRect(ctx, 53, 53, 49, 33, 10);
+    roundedRect(ctx, 53, 119, 49, 16, 6);
+    roundedRect(ctx, 135, 53, 49, 33, 10);
+    roundedRect(ctx, 135, 119, 25, 49, 10);
+
+    ctx.beginPath();
+    ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false);
+    ctx.lineTo(31, 37);
+    ctx.fill();
+
+    for (var i = 0; i < 8; i++) {
+      ctx.fillRect(51 + i * 16, 35, 4, 4);
+    }
+
+    for (i = 0; i < 6; i++) {
+      ctx.fillRect(115, 51 + i * 16, 4, 4);
+    }
+
+    for (i = 0; i < 8; i++) {
+      ctx.fillRect(51 + i * 16, 99, 4, 4);
+    }
+
+    ctx.beginPath();
+    ctx.moveTo(83, 116);
+    ctx.lineTo(83, 102);
+    ctx.bezierCurveTo(83, 94, 89, 88, 97, 88);
+    ctx.bezierCurveTo(105, 88, 111, 94, 111, 102);
+    ctx.lineTo(111, 116);
+    ctx.lineTo(106.333, 111.333);
+    ctx.lineTo(101.666, 116);
+    ctx.lineTo(97, 111.333);
+    ctx.lineTo(92.333, 116);
+    ctx.lineTo(87.666, 111.333);
+    ctx.lineTo(83, 116);
+    ctx.fill();
+
+    ctx.fillStyle = 'white';
+    ctx.beginPath();
+    ctx.moveTo(91, 96);
+    ctx.bezierCurveTo(88, 96, 87, 99, 87, 101);
+    ctx.bezierCurveTo(87, 103, 88, 106, 91, 106);
+    ctx.bezierCurveTo(94, 106, 95, 103, 95, 101);
+    ctx.bezierCurveTo(95, 99, 94, 96, 91, 96);
+    ctx.moveTo(103, 96);
+    ctx.bezierCurveTo(100, 96, 99, 99, 99, 101);
+    ctx.bezierCurveTo(99, 103, 100, 106, 103, 106);
+    ctx.bezierCurveTo(106, 106, 107, 103, 107, 101);
+    ctx.bezierCurveTo(107, 99, 106, 96, 103, 96);
+    ctx.fill();
+
+    ctx.fillStyle = 'black';
+    ctx.beginPath();
+    ctx.arc(101, 102, 2, 0, Math.PI * 2, true);
+    ctx.fill();
+
+    ctx.beginPath();
+    ctx.arc(89, 102, 2, 0, Math.PI * 2, true);
+    ctx.fill();
+  }
+}
+
+// A utility function to draw a rectangle with rounded corners.
+
+function roundedRect(ctx, x, y, width, height, radius) {
+  ctx.beginPath();
+  ctx.moveTo(x, y + radius);
+  ctx.lineTo(x, y + height - radius);
+  ctx.arcTo(x, y + height, x + radius, y + height, radius);
+  ctx.lineTo(x + width - radius, y + height);
+  ctx.arcTo(x + width, y + height, x + width, y + height-radius, radius);
+  ctx.lineTo(x + width, y + radius);
+  ctx.arcTo(x + width, y, x + width - radius, y, radius);
+  ctx.lineTo(x + radius, y);
+  ctx.arcTo(x, y, x, y + radius, radius);
+  ctx.stroke();
+}
+
+ +

결과 이미지는 다음과 같습니다:

+ +

{{EmbedLiveSample("Making_combinations", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}

+ +

이 예제는 보기보다 아주 간단하기 때문에 자세한 설명은 생략하겠습니다. 알아 두어야할 가장 중요한 부분은 fillStyle  코드와 사용된 유틸리티 함수 (roundedRect() 부분) 입니다. 유틸리티 함수를 사용하게 되면, 사용해야 할 코드의 양과 복잡함을 줄여주는데 도움을 줍니다.

+ +

이 튜토리얼에서 나중에 fillStyle에 대하여 조금 더 자세하게 알아보도록 하겠지만, 지금은 경로의 채우는 색을 기본값(흑백)에서 바꾸었다가 다시 기본값으로 바꾸는 정도로만 사용하였습니다.

+ +

Path2D 오브젝트 (Path2D objects)

+ +

마지막 예제에서 보았 듯이, 캔버스에 객체를 그리는 일련의 경로와 그리기 명령이 있을 수 있습니다. 코드를 단순화하고 성능을 향상시키기 위해 최근 버전의 브라우저에서 사용할 수있는 {{domxref("Path2D")}} 객체를 사용하여 이러한 드로잉 명령을 캐시하거나 기록 할 수 있습니다. 이로써 여러분은 경로를 빠르게 다시 실행 시킬 수 있습니다.

+ +

어떻게 Path2D object를 생성 할 수 있는지 확인해 봅시다:

+ +
+
{{domxref("Path2D.Path2D", "Path2D()")}}
+
Path2D() 생성자는 새로운 Path2D 객체를 반환합니다. 선택적으로 다른 경로를 인수로 받거나(복사본을 생성), SVG 경로 데이터로 구성된 문자열을 받아서 객체로 반환합니다.
+
+ +
new Path2D();     // empty path object
+new Path2D(path); // copy from another Path2D object
+new Path2D(d);    // path from SVG path data
+ +

moveTo, rect, arc 혹은 quadraticCurveTo 등과 같은 모든 경로 메소드 (path methods)들은  Path2D 객체에서 사용 가능합니다.

+ +

Path2D API는 또한 addPath 메소드를 사용하여 경로를 결합하는 방법을 추가합니다. 예를 들자면, 여러 요소를 사용하는 오브젝트를 만들 때 유용하게 사용 될 수 있습니다.

+ +
+
{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}
+
옵션으로 변환 행렬(transformation matrix)을 사용하여 현재 경로에 경로를 추가합니다.
+
+ +

Path2D 예제

+ +

이 예제에서는, 직사각형과 원을 만들어 볼 것입니다. 나중에 사용할 것을 고려하여, 두 도형 모두 Path2D object로 저장 될 것입니다. 새로운 버전의 Path2D API에서는 여러 메소드들이 지금 사용하고있는 path가 아닌 Path2D object를 옵션으로 선택하여 사용 할 수 있도록 업데이트 되었습니다. 아래의 예제에서 보시면, stroke 와 fill 메소드가 오브젝트를 캔버스 위에 그리도록 path 변수와 함께 사용되었습니다.

+ + + +
function draw() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    var rectangle = new Path2D();
+    rectangle.rect(10, 10, 50, 50);
+
+    var circle = new Path2D();
+    circle.moveTo(125, 35);
+    circle.arc(100, 35, 25, 0, 2 * Math.PI);
+
+    ctx.stroke(rectangle);
+    ctx.fill(circle);
+  }
+}
+
+ +

{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}

+ +

SVG paths 사용하기

+ +

새로운 캔버스 path2D API 또다른 강력한 특징 중 하나는, 캔버스의 path를 초기화 하기 위해 SVG path data를 사용한다는 것입니다. 이는 path 데이터를 이동시키며, SVG와 canvas 에서 재사용 할 수 있도록 해줍니다. 

+ +

path는 (M10 10) 점으로 이동한 다음, 수평하게 오른쪽으로 으로 80 포인트 (h 80)  만큼 이동합니다. 이후 수직으로 80포인트 (v 80) 내려간 다음, 80 포인트 왼쪽으로 (h -80) 수평하게 이동하고 다시 시작점 (z)으로 돌아갑니다. 예시는 이곳( Path2D constructor )에서 확인하실 수 있습니다.

+ +
var p = new Path2D('M10 10 h 80 v 80 h -80 Z');
+ +
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
diff --git a/files/ko/web/api/canvas_api/tutorial/drawing_text/index.html b/files/ko/web/api/canvas_api/tutorial/drawing_text/index.html new file mode 100644 index 0000000000..2c789e85a4 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/drawing_text/index.html @@ -0,0 +1,164 @@ +--- +title: 텍스트 그리기 +slug: Drawing_text_using_a_canvas +tags: + - HTML + - 'HTML:Canvas' + - NeedsContent +translation_of: Web/API/Canvas_API/Tutorial/Drawing_text +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}
+ +
+

이전 챕터에서 스타일과 컬러를 적용하는 방법에 대해서 보았고 이번에는 캔버스에 텍스트를 그리는 방법에 대해서 볼 예정입니다.

+
+ +

텍스트 그리기

+ +

캔버스 렌더링 컨텍스트(canvas rendering context)는 텍스트를 렌더링하는 두 가지 방법을 제공합니다.

+ +
+
{{domxref("CanvasRenderingContext2D.fillText", "fillText(text, x, y [, maxWidth])")}}
+
주어진 (x, y) 위치에 주어진 텍스트를 채웁니다. 최대 폭(width)은 옵션 값 입니다.
+
{{domxref("CanvasRenderingContext2D.strokeText", "strokeText(text, x, y [, maxWidth])")}}
+
주어진 (x, y) 위치에 주어진 텍스트를 칠(stroke)합니다. 최대 폭(width)은 옵션 값 입니다.
+
+ +

fillText 예제

+ +

텍스트는 현재의 fillStyle을 사용하여 채워집니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.font = '48px serif';
+  ctx.fillText('Hello world', 10, 50);
+}
+ + + +

{{EmbedLiveSample("A_fillText_example", 310, 110)}}

+ +

strokeText 예제

+ +

텍스트는 현재의 strokeStyle을 이용하여 채워집니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  ctx.font = '48px serif';
+  ctx.strokeText('Hello world', 10, 50);
+}
+ + + +

{{EmbedLiveSample("A_strokeText_example", 310, 110)}}

+ +

텍스트 스타일 적용하기

+ +

 위의 예제에서 우리는 이미 텍스트를 기본 사이즈를 키우기 위하여 font 프로퍼티를 사용하였습니다. 그리고 캔버스에 표시되는 텍스트를 조정할 수 있는 속성이 더 있습니다. 

+ +
+
{{domxref("CanvasRenderingContext2D.font", "font = value")}}
+
텍스트를 그릴 때 사용되는 현재 텍스트 스타일. 이 문자열은 CSS {{cssxref("font")}} 프로퍼티와 동일한구문을 사용합니다. 기본값으로 sans-serif의 10px가 설정되어 있습니다.
+
{{domxref("CanvasRenderingContext2D.textAlign", "textAlign = value")}}
+
텍스트 정렬 설정. 사용가능한 값: start, end, left, rightcenter. 기본 값은 start 입니다.
+
{{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline = value")}}
+
베이스라인 정렬 설정. 사용가능한 값: top, hanging, middle, alphabetic, ideographic, bottom. 기본 값은 alphabetic 입니다
+
{{domxref("CanvasRenderingContext2D.direction", "direction = value")}}
+
글자 방향. 사용가능한 값: ltr, rtl, inherit. 기본 값은 inherit 입니다.
+
+ +

만약 CSS를 다뤄보신적이 있다면 이러한 프로퍼티들은 익숙하실겁니다.

+ +

다음에 나오는  WHATWG 예제 다이어그램은 textBaseline를 이용하여 다양한 베이스라인 설정을 보여줍니다.The top of the em square is
+roughly at the top of the glyphs in a font, the hanging baseline is
+where some glyphs like आ are anchored, the middle is half-way
+between the top of the em square and the bottom of the em square,
+the alphabetic baseline is where characters like Á, ÿ,
+f, and Ω are anchored, the ideographic baseline is
+where glyphs like 私 and 達 are anchored, and the bottom
+of the em square is roughly at the bottom of the glyphs in a
+font. The top and bottom of the bounding box can be far from these
+baselines, due to glyphs extending far outside the em square.

+ +

textBaseline 예제

+ +

아래의 코드를 수정하여 캔버스에서 어떻게 바뀌는지 실시간으로 확인해 보세요.

+ +
ctx.font = '48px serif';
+ctx.textBaseline = 'hanging';
+ctx.strokeText('Hello world', 0, 100);
+
+ + + +

{{ EmbedLiveSample('Playable_code', 700, 360) }}

+ +

어드밴스드 텍스트 측정

+ +

만약 텍스트에대해 조금 더 디테일한 것들을 얻고 싶다면 다음의 메소드를 이용해보세요.

+ +
+
{{domxref("CanvasRenderingContext2D.measureText", "measureText()")}}
+
현재 스타일로 특정 텍스트가 그려질 때의 폭, 픽셀 등을 포함하는 {{domxref("TextMetrics")}} 객체 리턴. 
+
+ +

다음의 코드는 어떻게 텍스트를 측정하는 지, 그리고 폭을 구하는 예제입니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var text = ctx.measureText('foo'); // TextMetrics object
+  text.width; // 16;
+}
+
+ +

Gecko 사용시 주의점

+ +

Gecko(Firefox, Firefox OS외 Mozilla 기반의 에플리케이션 렌더링 엔진)에서는 캔버스에 텍스트를 그리기 위한 몇몇의 prefixed APIs가 구현되어 있습니다. 그리고 지금은 사용되지 않아 제거되었거나 작동을 보장하지 않는 것들도 있습니다. 

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/finale/index.html b/files/ko/web/api/canvas_api/tutorial/finale/index.html new file mode 100644 index 0000000000..1241680c5c --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/finale/index.html @@ -0,0 +1,51 @@ +--- +title: Finale +slug: Web/HTML/Canvas/Tutorial/Finale +tags: + - 그래픽 + - 캔버스 + - 튜토리얼 +translation_of: Web/API/Canvas_API/Tutorial/Finale +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Optimizing_canvas")}}
+ +
+

축하합니다 Canvas 튜토리얼을 모두 끝마쳤습니다! 이 정보는 웹에서 더 나은 2D 그래픽을 만드는데 도움이 됩니다.

+
+ +

더 많은 예시와 튜토리얼

+ +

이 사이트에는 다양한 데모와 canvas에 대한 추가 설명이 있다.

+ +
+
Codepen.io
+
프론트 엔드 개발자 playground 및 브라우저의 코드 편집기.
+
HTML5 Canvas Tutorials
+
대부분 canvas API의 예시
+
Game development
+
게임은 가장 인기있는 컴퓨터 활동 중 하나이다. 어떤 표준 규격의 웹 브라우저에서도 실행할 수 있는 더 나은 게임을 개발할 수 있도록 하기 위한 신기술이 끊임없이 등장하고 있다.
+
+ +

기타 웹API

+ +

이 API들는 canvas 및 그래픽으로 작업할 때 유용하다.

+ +
+
WebGL
+
3D를 포함한 복잡한 그래픽 렌더링을 위한 고급 API.
+
SVG
+
확장 가능한 Vector Graphics는 이미지를 벡터(선)과 형태의 집합으로 묘사하여 이미지를 그리는 크기에 상관없이 원활하게 확장할 수 있다.
+
Web Audio
+
Web Audio API는 개발자들이 오디오 소스 선택, 오디오에 효과 추가, 오디오 시각화 생성, 공간 효과 적용(예: 패닝)등을 할 수 있도록 웹 상에서 오디오를 제어하기 위한 다양하고 좋은 시스템을 제공한다.
+
+ +

문의사항

+ +
+
Stack Overflow
+
"canvas"가 태그된 문의사항.
+
Comments about this tutorial – the MDN documentation community
+
이 튜토리얼에 대해 의견이 있으시거나 저희에게 감사를 표하고 싶다면 언제든지 연락해주세요!
+
+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Optimizing_canvas")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/hit_regions_and_accessibility/index.html b/files/ko/web/api/canvas_api/tutorial/hit_regions_and_accessibility/index.html new file mode 100644 index 0000000000..e720af3159 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/hit_regions_and_accessibility/index.html @@ -0,0 +1,97 @@ +--- +title: 히트(Hit) 영역과 접근성 +slug: Web/HTML/Canvas/Tutorial/Hit_regions_and_accessibility +translation_of: Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility +--- +
{{CanvasSidebar}} {{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}
+ +
{{HTMLElement("canvas")}} 엘리먼트는 비트맵이며 그려진 객체에 대한 정보는 제공하지 않습니다. 캔버스 컨텐츠는 시멘틱 HTML과 같은 접근성 도구에 노출되지 않습니다. 일반적으로 접근성을 위한 웹 사이트 또는 앱에서는 캔버스를 사용하지 않는 것이 좋습니다. 본 가이드라인은 접근성이 향상된 캔버스를 만드는데 도움이 될 것입니다.
+ +

대체 컨텐츠

+ +

<canvas> ... </ canvas> 태그 안의 내용은 캔버스 렌더링을 지원하지 않는 브라우저의 대체 컨텐츠로 사용할 수 있습니다. 또한 하위 DOM을 읽고 해석 할 수있는 보조 기술 사용자 (스크린 리더와 같은)에게도 매우 유용합니다. html5accessibility.com의 좋은 예가 이를 수행 할 수있는 방법을 보여줍니다.

+ +
<canvas>
+  <h2>Shapes</h2>
+  <p>A rectangle with a black border.
+   In the background is a pink circle.
+   Partially overlaying the <a href="http://en.wikipedia.org/wiki/Circle" onfocus="drawCircle();" onblur="drawPicture();">circle</a>.
+   Partially overlaying the circle is a green
+   <a href="http://en.wikipedia.org/wiki/Square" onfocus="drawSquare();" onblur="drawPicture();">square</a>
+   and a purple <a href="http://en.wikipedia.org/wiki/Triangle" onfocus="drawTriangle();" onblur="drawPicture();">triangle</a>,
+   both of which are semi-opaque, so the full circle can be seen underneath.</p>
+</canvas> 
+ +

Steve Faulkner의 NVDA가 이 예제를 어떻게 읽는지를 보여주는 동영상을 참고하시기 바랍니다.

+ +

ARIA 규칙

+ +

ARIA(Accessible Rich Internet Application)는 장애인이 사용자가 웹 콘텐츠 및 웹 응용 프로그램을보다 쉽게 사용할 수 있도록하는 방법을 정의합니다. ARIA 속성을 사용하여 캔버스 엘리먼트의 동작 및 용도를 설명 할 수 있습니다. 자세한 내용은 ARIAARIA 기술을 참조하십시오.

+ +
<canvas id="button" tabindex="0" role="button" aria-pressed="false" aria-label="Start game"></canvas>
+
+ +

히트(Hit) 영역

+ +

마우스 좌표가 캔버스의 특정 영역 내에 있는지 여부는 문제를 해결하는 데 공통적입니다. 히트 영역 API를 사용하면 캔버스 영역을 정의 할 수 있으며 캔버스에 대화형 컨텐츠를 접근성 도구에 표시 할 수 있습니다. 히트 영역 API는 여러분이 히트 감지를 쉽게 할 수 있도록 하며 DOM 엘리먼트에 이벤트를 전달할 수 있도록 합니다. API에는 다음 세 가지 메소드가 있습니다 (현재 웹 브라우저에서는 아직 실험 중이며 브라우저 호환성 테이블을 확인하십시오).

+ +
+
{{domxref("CanvasRenderingContext2D.addHitRegion()")}} {{experimental_inline}}
+
히트 영역을 캔버스에 추가합니다.
+
{{domxref("CanvasRenderingContext2D.removeHitRegion()")}} {{experimental_inline}}
+
캔버스에서 해당 id를 가진 히트 영역을 제거합니다.
+
{{domxref("CanvasRenderingContext2D.clearHitRegions()")}} {{experimental_inline}}
+
캔버스에서 모든 히트 영역을 제거합니다.
+
+ +

경로에 히트 영역을 추가하고 {{domxref("MouseEvent.region")}} 속성을 확인하여 마우스가 영역을 히트하는지 테스트 할 수 있습니다.

+ +
<canvas id="canvas"></canvas>
+<script>
+var canvas = document.getElementById('canvas');
+var ctx = canvas.getContext('2d');
+
+ctx.beginPath();
+ctx.arc(70, 80, 10, 0, 2 * Math.PI, false);
+ctx.fill();
+ctx.addHitRegion({id: 'circle'});
+
+canvas.addEventListener('mousemove', function(event) {
+  if (event.region) {
+    alert('hit region: ' + event.region);
+  }
+});
+</script>
+ +

addHitRegion() 메소드는 control 옵션을 이용하여 이벤트를 엘리먼트(즉, 캔버스의 자식으로)로 전달합니다.

+ +
ctx.addHitRegion({control: element});
+ +

예를 들어 {{HTMLElement("input")}} 엘리먼트로 전달하는 데 유용 할 수 있습니다. codepen 데모를 참조하십시오.

+ +

포커스 링(Focus rings)

+ +

키보드로 작업 할 때 포커스 링은 페이지 탐색에 도움이되는 편리한 표시기입니다. 캔버스 드로잉에 포커스 링을 그리려면 drawFocusIfNeeded 속성을 사용할 수 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.drawFocusIfNeeded()")}} {{experimental_inline}}
+
지정된 엘리먼트에 포커스가있는 경우,이 메소드는 현재 경로 주위에 포커스 링을 그립니다.
+
+ +

또한 scrollPathIntoView() 메서드를 사용하여 포커스가있는 경우 엘리먼트를 화면에 표시 할 수 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.scrollPathIntoView()")}} {{experimental_inline}}
+
현재 경로 또는 지정된 경로를 뷰로 스크롤합니다.
+
+ +

See also

+ + + +
{{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}
diff --git a/files/ko/web/api/canvas_api/tutorial/index.html b/files/ko/web/api/canvas_api/tutorial/index.html new file mode 100644 index 0000000000..03077163aa --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/index.html @@ -0,0 +1,62 @@ +--- +title: 캔버스 튜토리얼 +slug: Web/HTML/Canvas/Tutorial +tags: + - Canvas + - Graphic + - Guide + - HTML + - HTML5 + - Intermediate + - Web +translation_of: Web/API/Canvas_API/Tutorial +--- +
{{CanvasSidebar}}
+ +
+ +
+

<canvas>는 HTML 요소 중 하나로서, 스크립트(보통은 자바스크립트)를 사용하여 그림을 그리는 데에 사용됩니다. 예를 들면, 그래프를 그리거나 사진을 합성하거나, 간단한(혹은 복잡할 수도 있는) 애니메이션을 만드는 데에 사용될 수 있습니다. 오른쪽에 보이는 이미지들은 앞으로 설명하게 될 <canvas>를 사용하여 만들 수 있는 것들의 일부입니다.

+
+ +

이 튜토리얼은 <canvas> 요소를 사용하여 2D 그래픽을 어떻게 그리는지 기초부터 설명합니다. 예제들을 통하여 캔버스로 할 수 있는 것이 무엇인지 알려주며, 바로 사용할 수 있도록 코드도 제공합니다.

+ +

<canvas>는 Apple의 Webkit에 처음 도입되어 Mac OS X 대시보드(Dashboard)에 사용되었고, 이후 다른 브라우저에도 구현되어 왔습니다. 현재 대부분의 주요 브라우저에서 지원됩니다.

+ +

시작하기 전 알아두어야 할 것

+ +

<canvas> 요소를 사용하는 것이 어려운 일은 아니지만, HTML자바스크립트에 대한 기본 지식을 갖추고 있어야 합니다. 몇몇 오래된 브라우저는 <canvas> 요소를 지원하지 않지만, 최근 버전의 주요 브라우저들은 모두 지원하고 있습니다. 캔버스의 크기는 300px * 150px (너비 * 높이)가 초기 설정값이며, HTML heightwidth 속성을 사용하여 바꿀 수 있습니다. 캔버스에 그림을 그리려면 자바스크립트 컨텍스트 오브젝트를 사용하며, 즉석에서 그림을 생성할 수 있습니다.

+ +

튜토리얼 내용

+ + + +

같이 보기

+ + + + + +
{{ Next("Web/API/Canvas_API/Tutorial/Basic_usage") }}
diff --git a/files/ko/web/api/canvas_api/tutorial/optimizing_canvas/index.html b/files/ko/web/api/canvas_api/tutorial/optimizing_canvas/index.html new file mode 100644 index 0000000000..460b5e893f --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/optimizing_canvas/index.html @@ -0,0 +1,110 @@ +--- +title: 캔버스 최적화 +slug: Web/HTML/Canvas/Tutorial/Optimizing_canvas +translation_of: Web/API/Canvas_API/Tutorial/Optimizing_canvas +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}
+ +
+

{{HTMLElement("canvas")}} 엘리먼트는 웹에서 2D 그래픽을 렌더링하는 데 가장 널리 사용되는 도구 중 하나입니다. 그러나 웹 사이트와 앱이 Canvas API를 최대한으로 밀면 성능이 저하되기 시작합니다. 그러나 웹 사이트 및 앱이 Canvas API를 한계치까지 사용하면 성능이 저하되기 시작합니다. 이 글에서는 그래픽이 잘 동작하도록 보장하기 위해 캔버스 엘리먼트의 사용을 최적화하기위한 제안 사항을 제공합니다.

+
+ +

성능 팁

+ +

다음은 캔버스 성능을 개선하기 위한 팁 모음입니다.

+ +

캔버스에 표시되지 않는 비슷한 원시 혹은 반복 객체를 미리 그려라

+ +

만약 당신이 캔버스에 애니메이션 프레임을 그리면서 반복적인 작업이 발견된다면, 눈에 보이지 않는 숨겨진 캔버스 요소를 새로 만들고 그 캔버스에 미리 그려 넣는 방법을 고려하세요. 그렇게 하면 필요한 순간에 숨긴 캔버스에 그려진 이미지를 다시 주 캔버스 이미지에 그려넣어, 불필요한 렌더링 반복 작업을 줄여 성능 향상을 꾀할 수 있습니다.

+ +
myCanvas.offscreenCanvas = document.createElement('canvas');
+myCanvas.offscreenCanvas.width = myCanvas.width;
+myCanvas.offscreenCanvas.height = myCanvas.height;
+
+myCanvas.getContext('2d').drawImage(myCanvas.offScreenCanvas, 0, 0);
+ +

부동 소수점 좌표를 피하고 대신 정수를 사용하라.

+ +

정수값들 없이 캔버스 상의 객체를 렌더링할 때 부가적인 픽셀 렌더링이 발생합니다.

+ +
ctx.drawImage(myImage, 0.3, 0.5);
+
+ +

이렇게하면 앤티 앨리어싱(anti-aliasing) 효과를 만들기 위해 브라우저에서 추가 연산을 수행해야합니다. 예제에서 이를 방지하려면 {{jsxref("Math.floor()")}}를 사용하여 {{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}} 호출에 사용된 모든 좌표를 반올림해야합니다.

+ +

drawImage에서 이미지 크기를 조정하지 마라.

+ +

{{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}에서 즉시 크기를 조정하지 말고 다양한 이미지 크기를 오프스크린(offscreen) 캔버스에 캐시하십시오.

+ +

복잡한 장면에 여러 개의 레이어 캔버스를 사용하라.

+ +

어플리케이션에서 일부 객체는 자주 이동하거나 변경해야하지만 다른 객체는 상대적으로 고정 위치에 남아야 합니다. 이런 상황에서 대응 가능한 최적화는 여러 <canvas> 엘리먼트를 사용하여 항목을 겹쳐서 만드는 것입니다.

+ +

예를 들어 상단에 UI, 중간에 게임 플레이 액션, 하단에 정적 배경이있는 게임이 있다고 가정 해 보겠습니다. 이 경우 게임을 세 개의 <canvas> 레이어로 나눌 수 있습니다. UI는 사용자 입력시에만 변경되며 게임 플레이 레이어는 모든 새 프레임마다 변경되며 배경은 일반적으로 변경되지 않습니다.

+ +
<div id="stage">
+  <canvas id="ui-layer" width="480" height="320"></canvas>
+  <canvas id="game-layer" width="480" height="320"></canvas>
+  <canvas id="background-layer" width="480" height="320"></canvas>
+</div>
+
+<style>
+  #stage {
+    width: 480px;
+    height: 320px;
+    position: relative;
+    border: 2px solid black;
+  }
+
+  canvas { position: absolute; }
+  #ui-layer { z-index: 3; }
+  #game-layer { z-index: 2; }
+  #background-layer { z-index: 1; }
+</style>
+
+ +

큰 배경 이미지는 일반 CSS를 사용하라.

+ +

정적 배경 이미지가있는 경우 CSS {{cssxref("background")}} 속성을 사용하여 일반 {{HTMLElement("div")}} 요소에 그릴 수 있으며 캔버스 아래에 배치 할 수 있습니다. 이렇게하면 모든 틱 마다 배경을 캔버스에 렌더링 할 필요가 없어집니다.

+ +

CSS 변환(transform)을 사용하여 캔버스 크기 조정하라.

+ +

CSS 변환(transform)은 GPU를 사용하기 때문에 더 빠릅니다. 가장 좋은 경우는 캔버스를 스케일링하지 않거나, 큰 캔버스를 축소하기보다 작은 캔버스를 확대하는 것입니다.

+ +
var scaleX = window.innerWidth / canvas.width;
+var scaleY = window.innerHeight / canvas.height;
+
+var scaleToFit = Math.min(scaleX, scaleY);
+var scaleToCover = Math.max(scaleX, scaleY);
+
+stage.style.transformOrigin = '0 0'; //scale from top left
+stage.style.transform = 'scale(' + scaleToFit + ')';
+
+ +

투명도를 사용하지 마라.

+ +

응용 프로그램이 캔버스를 사용하고 투명 배경을 필요로하지 않는 경우 HTMLCanvasElement.getContext()를 사용하여 드로잉 컨텍스트를 만들 때 alpha 옵션을 false로 설정합니다. 이 정보는 렌더링을 최적화하기 위해 브라우저에서 내부적으로 사용할 수 있습니다.

+ +
var ctx = canvas.getContext('2d', { alpha: false });
+ +

추가 팁들

+ + + +

See also

+ + + +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/transformations/index.html b/files/ko/web/api/canvas_api/tutorial/transformations/index.html new file mode 100644 index 0000000000..b93747b581 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/transformations/index.html @@ -0,0 +1,286 @@ +--- +title: 변형 (transformations) +slug: Web/HTML/Canvas/Tutorial/변형 +tags: + - CSS + - HTML + - 이동 + - 축소 + - 캔버스 + - 크기변형 + - 트랜스폼 + - 확대 +translation_of: Web/API/Canvas_API/Tutorial/Transformations +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}
+ +
이 튜토리얼에 앞서 canvas 그리드좌표 공간에 대해 알아 보았습니다. 지금까지는 기본적인 그리드를 사용해 요구에 맞추어 전체 canvas의 크기를 바꾸기만 했습니다. Transformation(변형)에는 그리드를 원점에서 다른 위치로 옮기고, 회전하며, 확대·축소까지 하는 더 강력한 방법들이 있습니다.
+ +

상태(state)의 저장과 복원

+ +

변형(transformation) 메소드을 살펴보기 전에 두 가지 다른 메소드를 보도록 하지요. 일단 여러분이 더 복잡한 그림(drawings)을 그리기 시작하면 반드시 있어야 하는 메소드들입니다.

+ +
+
{{domxref("CanvasRenderingContext2D.save", "save()")}}
+
canvas의 모든 상태를 저장합니다.
+
{{domxref("CanvasRenderingContext2D.restore", "restore()")}}
+
가장 최근에 저장된 canvas 상태를 복원합니다.
+
+ +

Canvas 상태는 스택(stack)에 쌓입니다. save() 메소드가 호출될 때마다 현재 drawing 상태가 스택 위로 푸시됩니다. drawing 상태는 다음과 같이 이루어집니다.

+ + + +

여러분은 원하는 만큼 save() 메소드를 많이 호출할 수 있습니다. restore() 메소드를 호출할 때마다 마지막으로 저장된 상태가 스택에서 튀어나와 저장된 설정들을 모두 복원시킵니다.

+ +

save와 restore canvas 상태(state) 예제

+ +

사각형 세트를 연이어 그려서 drawing 상태를 가진 스택이 어떻게 기능하는지를 이 예제에서 설명하고자 합니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  ctx.fillRect(0, 0, 150, 150);   // 기본 설정으로 사각형을 그리기
+  ctx.save();                  // 기본 상태를 저장하기
+
+  ctx.fillStyle = '#09F';      // 설정 변경하기
+  ctx.fillRect(15, 15, 120, 120); // 새로운 설정으로 사각형 그리기
+
+  ctx.save();                  // 현재 상태 저장하기
+  ctx.fillStyle = '#FFF';      // 설정 변경하기
+  ctx.globalAlpha = 0.5;
+  ctx.fillRect(30, 30, 90, 90);   // 새로운 설정으로 사각형 그리기
+
+  ctx.restore();               // 이전 상태 복원하기
+  ctx.fillRect(45, 45, 60, 60);   // 복원된 설정으로 사각형 그리기
+
+  ctx.restore();               // 초기 상태를 복원하기
+  ctx.fillRect(60, 60, 30, 30);   // 복원된 설정으로 사각형 그리기
+}
+ + + +

첫 단계로 기본 설정으로 커다란 사각형을 그립니다. 그다음에는 이 상태를 저장하고 fill color를 바꿉니다. 그런 후에 두 번째이자 크기가 더 작은 파란 사각형을 그리고 그 상태를 저장합니다. 다시 한번 일부 drawing 설정을 바꾸고 세 번째 반투명한 흰 사각형을 그립니다. 

+ +

여기까지는 이전 섹션에서 했던 작업과 매우 유사합니다. 하지만 일단 첫 번째 restore() 문을 호출하면 스택에서 맨 위의 drawing 상태가 지워지고 설정이 복원됩니다. 만일 save()로 저장하지 않았다면, 이전 상태로 되돌리기 위해 fill color와 투명도를 일일이 바꿔주어야 했을 것입니다. 두 속성이라서 간단했을 테지만 그보다 더 많았으면 코드가 급속히 길어졌겠지요. 

+ +

두 번째 restore()문이 호출될 때, 초기 상태( 처음으로 save를 호출하기 전에 설정한 상태)가 복원되고 마지막 사각형은 한번 더 검게 그려집니다.

+ +

{{EmbedLiveSample("A_save_and_restore_canvas_state_example", "180", "180", "https://mdn.mozillademos.org/files/249/Canvas_savestate.png")}}

+ +

이동(translating)

+ +

우리가 살펴볼 첫 번째 변형 메소드는 translate()입니다.  이 메소드는 그리드에서 canvas를 원점에서 다른 점으로 옮기는 데 사용됩니다. 

+ +
+
{{domxref("CanvasRenderingContext2D.translate", "translate(x, y)")}}
+
그리드에서 canvas와 그 원점을 이동합니다. x는 이동시킬 수평 거리를 가리키고, y는 그리드에서 수직으로 얼마나 멀리 떨어지는지를 표시합니다. 
+
+ +

변형하기 전에 canvas 상태를 저장하는 것이 좋습니다. 대다수의 경우, 원래 상태로 되돌리려고 역이동(reverse translation)을 시키는 것보다 restore 메소드를 호출하는 것이 더욱 간편합니다. 게다가 루프(loop) 안에서 이동하는 거라면 canvas 상태를 저장하고 복원하지 마세요. canvas 모서리 밖에서 그려지는 바람에 drawing의 일부를 잃어버리게 될지 모릅니다. 

+ +

translate 예제

+ +

이 예제에서 canvas 원점의 이동에 관한 좋은 점을 일부 보여드리겠습니다. translate() 메소드를 쓰지 않으면 모든 사각형은 같은 위치 (0, 0)에 그려집니다. 또한, translate() 메소드는 사각형을 fillRect() function에서 좌표를 일일이 적으며 바꾸지 않아도 어디에나 위치할 수 있게 해줍니다. 이렇게 하면 이해하고 사용하기가 좀 더 쉽습니다. 

+ +

 draw() function에서 두 개의 루프(loops)를 이용해 fillRect() function을 아홉 번 호출합니다. 루프마다 canvas가 이동하고 사각형이 그려지며, canvas는 원래 상태로 되돌아 갑니다. fillRect()로의 호출이 translate()에 의지해 drawing 위치를 바꾸는데 어떻게 매번 같은 좌표를 사용하는지 눈여겨 보세요.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  for (var i = 0; i < 3; i++) {
+    for (var j = 0; j < 3; j++) {
+      ctx.save();
+      ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)';
+      ctx.translate(10 + j * 50, 10 + i * 50);
+      ctx.fillRect(0, 0, 25, 25);
+      ctx.restore();
+    }
+  }
+}
+
+ + + +

{{EmbedLiveSample("A_translate_example", "160", "160", "https://mdn.mozillademos.org/files/9857/translate.png")}}

+ +

회전(rotating)

+ +

두 번째 변형 메소드는 rotate()입니다. canvas를 현재의 원점 둘레로 회전하는 데 사용합니다.

+ +
+
{{domxref("CanvasRenderingContext2D.rotate", "rotate(angle)")}}
+
canvas를 현재 원점을 기준으로 라디안의 angle 숫자만큼 시계방향으로 회전시킵니다.
+
+ +

회전의 중심점은 언제나 canvas 원점입니다. 중심점을 바꾸려면 translate() 메소드를 써서 canvas를 이동해야 합니다.

+ +

rotate 예제

+ +

이 예제는 사각형을 canvas 원점에서 먼저 회전하고 그다음에 translate()의 도움을 받아 사각형 자체의 중심에서 회전하는 데 rotate()를 사용합니다.

+ +
+

주의: 각도의 단위는 도(degree)가 아닌 라디안(radian)입니다.   변환하려면 radians = (Math.PI/180)*degrees.를 사용합니다.

+
+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // 좌측 사각형, canvas 원점에서 회전하기
+  ctx.save();
+  // 파란 사각형
+  ctx.fillStyle = '#0095DD';
+  ctx.fillRect(30, 30, 100, 100);
+  ctx.rotate((Math.PI / 180) * 25);
+  // 회색 사각형
+  ctx.fillStyle = '#4D4E53';
+  ctx.fillRect(30, 30, 100, 100);
+  ctx.restore();
+
+  // 우측 사각형, 사각형 중심에서 회전하기
+  // 파란 사각형 그리기
+  ctx.fillStyle = '#0095DD';
+  ctx.fillRect(150, 30, 100, 100);
+
+  ctx.translate(200, 80); // 사각형 중심으로 이동하기
+                          // x = x + 0.5 * width
+                          // y = y + 0.5 * height
+  ctx.rotate((Math.PI / 180) * 25); // 회전
+  ctx.translate(-200, -80); // 예전 위치로 이동하기
+
+  // 회색 사각형 그리기
+  ctx.fillStyle = '#4D4E53';
+  ctx.fillRect(150, 30, 100, 100);
+}
+
+ +

사각형 자체의 중심 둘레로 회전하려면 사각형의 중심으로 canvas를 옮기세요. 그런 후에 canvas를 회전하고, 그 canvas를 0, 0로 되돌려 이동합니다. 그다음에 사각형을 그리세요.

+ + + +

{{EmbedLiveSample("A_rotate_example", "310", "210", "https://mdn.mozillademos.org/files/9859/rotate.png")}}

+ +

확대·축소(scaling)

+ +

다음 변형 메소드는 확대·축소(scaling)입니다. canvas 그리드에서 단위(units)를 키우거나 줄이는 데 사용합니다. 이는 벡터 모양과 비트맵(bitmaps) 요소를 축소하거나 확대해서 그리는 데 사용될 수 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.scale", "scale(x, y)")}}
+
canvas 단위를 수평으로 x만큼, 수직으로 y만큼 크기를 확대·축소합니다. 둘의 매개 변수는 실수입니다. 1.0보다 작은 값이면 단위의 크기를 축소하고, 1.0보다 큰 값이면 단위의 크기를 확대합니다. 값이 1.0이면 단위의 크기는 그대로입니다.
+
+ +

음수를 이용해서 축을 대칭 시킬 수 있습니다(가령 translate(0,canvas.height); scale(1,-1);로 쓰는 것처럼 말이죠. 좌측 하단 모서리에 있는 원점을 이용한, 잘 알려진 카르테시안 좌표계(Cartesian coordinate)인 것이지요.

+ +

기본적으로 canvas에서 하나의 단위는 정확히 1픽셀입니다. 예를 들어 0.5라는 확대·축소 비율을 적용한다면, 결과로 나오는 단위는 0.5 픽셀이 될 것이고, 고로 모양도 절반 크기로 그려질 것입니다. 이런 방식으로 크기 비율을 2.0으로 잡으면 단위 크기가 확대되어 하나의 단위는 이제 2픽셀이 되겠지요. 이 결과로 모양은 그만큼 2배로 커집니다.

+ +

scale 예제

+ +

마지막 예제로 다양한 확대·축소 비율을 이용해 모양을 그려보겠습니다.

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  // 간단하지만 확대·축소 비율을 적용한 사각형 그리기
+  ctx.save();
+  ctx.scale(10, 3);
+  ctx.fillRect(1, 10, 10, 10);
+  ctx.restore();
+
+  // 수평으로 대칭하기
+  ctx.scale(-1, 1);
+  ctx.font = '48px serif';
+  ctx.fillText('MDN', -135, 120);
+}
+
+
+ + + +

{{EmbedLiveSample("A_scale_example", "160", "160", "https://mdn.mozillademos.org/files/9861/scale.png")}}

+ +

변형(transforms)

+ +

마지막으로, 다음의 변형(transform) 메소드들은 변환 행렬(transformation matrix)로 변경할 사항을 즉시 적용할 수 있습니다.

+ +
+
{{domxref("CanvasRenderingContext2D.transform", "transform(a, b, c, d, e, f)")}}
+
인수(arguments)에 표시된 행렬을 이용해 현재 변환 행렬을 곱합니다. 변환 행렬은 다음과 같이 작성됩니다. 
+ [acebdf001]\left[ \begin{array}{ccc} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{array} \right]
+
+ +
+
만일 인수 중에 Infinity가 있다면, 변환 행렬은 예외 처리하는 메소드 대신에 반드시 infinite로 표시되어야 합니다.
+
+ +

이 function의 매개 변수들은 다음과 같습니다.

+ +
+
a (m11)
+
수평으로 확대·축소하기
+
b (m12)
+
수평으로 비스듬히 기울이기
+
c (m21)
+
수직으로 비스듬히 기울이기
+
d (m22)
+
수직으로 확대·축소하기
+
e (dx)
+
수평으로 이동하기
+
f (dy)
+
수직으로 이동하기
+
{{domxref("CanvasRenderingContext2D.setTransform", "setTransform(a, b, c, d, e, f)")}}
+
현재 변형 상태를 단위 행렬로 재설정하고 나서 동일한 인수로 transform() 메소드를 적용합니다. 이는 기본적으로 현재의 변형을 무효로 한 후에 명시된 변형으로 바뀌는데, 한번에 모든 게 진행됩니다.
+
{{domxref("CanvasRenderingContext2D.resetTransform", "resetTransform()")}}
+
현재 변형 상태를 단위 행렬로 재설정합니다. 이는 ctx.setTransform(1, 0, 0, 1, 0, 0); 호출과 같습니다.
+
+ +

transform과 setTransform 예제

+ +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+
+  var sin = Math.sin(Math.PI / 6);
+  var cos = Math.cos(Math.PI / 6);
+  ctx.translate(100, 100);
+  var c = 0;
+  for (var i = 0; i <= 12; i++) {
+    c = Math.floor(255 / 12 * i);
+    ctx.fillStyle = 'rgb(' + c + ', ' + c + ', ' + c + ')';
+    ctx.fillRect(0, 0, 100, 10);
+    ctx.transform(cos, sin, -sin, cos, 0, 0);
+  }
+
+  ctx.setTransform(-1, 0, 0, 1, 100, 100);
+  ctx.fillStyle = 'rgba(255, 128, 255, 0.5)';
+  ctx.fillRect(0, 50, 100, 100);
+}
+
+ + + +

{{EmbedLiveSample("Example_for_transform_and_setTransform", "230", "280", "https://mdn.mozillademos.org/files/255/Canvas_transform.png")}}

+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}

diff --git a/files/ko/web/api/canvas_api/tutorial/using_images/index.html b/files/ko/web/api/canvas_api/tutorial/using_images/index.html new file mode 100644 index 0000000000..d9aae1c993 --- /dev/null +++ b/files/ko/web/api/canvas_api/tutorial/using_images/index.html @@ -0,0 +1,347 @@ +--- +title: Using images +slug: Web/HTML/Canvas/Tutorial/Using_images +tags: + - Advanced + - Canvas + - Graphics + - HTML + - Tutorial +translation_of: Web/API/Canvas_API/Tutorial/Using_images +--- +
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations" )}}
+ +
+

지금까지 우리는 Canvas를 가지고 스스로 도형을 만들고 그 도형에 스타일 적용 해 보았습니다. 이미지를 사용 하는 기능은 {{HTMLElement("canvas")}}의 가장 흥미로운 기능중 하나입니다. 이 기능은 게임의 그래픽 배경이나 혹은 다이나믹한 사진 도음들을 위해 사용 될 수 있습니다. PNG,GIF, JPEG등 브라우저에서 지원되는 포맷형태라면 어떠한 외부 이미지라도 사용 될 수 있습니다. 같은 페이지 소스에서 다른 Canvas요소로 만들어진 이미지 또한 사용할수 있습니다!

+
+ +

이미지를 캔버스로 불러오는것은 기본적으로 두 단계를 필요로 합니다:

+ +
    +
  1. {{domxref("HTMLImageElement")}} object를 참조하거나 다른 캔버스 요소를 소스로 사용합니다. 이는 URL을 가지고 이미지를 사용 할 수 있습니다.
  2. +
  3. drawImage() function을 사용하여 캔버스에 나타난 이미지 위에 그림을 그립니다.
  4. +
+ +

이 과정이 어떻게 되는지 봅시다.

+ +

이미지 불러오기

+ +

canvas API는 아래의 데이터 타입을 이미지 소스로 사용 할 수 있습니다:

+ +
+
{{domxref("HTMLImageElement")}}
+
{{HTMLElement("img")}} element와 마찬가지로, Image() constructor를 통해 만들어진 이미지입니다.
+
+ +
+
{{domxref("SVGImageElement")}}
+
{{SVGElement("image")}} element 를 사용해 불러온 이미지입니다.
+
+ + + +
+
{{domxref("HTMLVideoElement")}}
+
HTML {{HTMLElement("video")}} 요소를 이미지 소스로 사용하여 비디오의 현재 프레임을 이미지로 불러옵니다.
+
{{domxref("HTMLCanvasElement")}}
+
다른 {{HTMLElement("canvas")}} 요소를 이미지 소스로 사용합니다.
+
+ +

이렇게 얻은 소스들은 {{domxref("CanvasImageSource")}}.를 사용하여 불러 올 수 있습니다.

+ +

다음은 캔버스에 놓인 이미지를 사용하는 여러가지 방법입니다.

+ +

같은 페이지의 이미지 사용하기

+ +

우리는 다음을 사용하여 같은 페이지에 있는 캔버스나 이미지를 참고 할 수 있습니다.

+ + + +

다른 도메인의 이미지 사용하기

+ +

Using the {{htmlattrxref("crossorigin", "img")}} attribute of an {{HTMLElement("img")}} element (reflected by the {{domxref("HTMLImageElement.crossOrigin")}} property), you can request permission to load an image from another domain for use in your call to drawImage(). If the hosting domain permits cross-domain access to the image, the image can be used in your canvas without tainting it; otherwise using the image will taint the canvas.

+ +

다른 캔버스 요소 (canvas elements) 사용하기

+ +

Just as with normal images, we access other canvas elements using either the {{domxref("document.getElementsByTagName()")}} or {{domxref("document.getElementById()")}} method. Be sure you've drawn something to the source canvas before using it in your target canvas.

+ +

One of the more practical uses of this would be to use a second canvas element as a thumbnail view of the other larger canvas.

+ +

처음부터 이미지 만들기

+ +

Another option is to create new {{domxref("HTMLImageElement")}} objects in our script. To do this, you can use the convenient Image() constructor:

+ +
var img = new Image();   // Create new img element
+img.src = 'myImage.png'; // Set source path
+
+ +

When this script gets executed, the image starts loading.

+ +

If you try to call drawImage() before the image has finished loading, it won't do anything (or, in older browsers, may even throw an exception). So you need to be sure to use the load event so you don't try this before the image has loaded:

+ +
var img = new Image();   // Create new img element
+img.addEventListener('load', function() {
+  // execute drawImage statements here
+}, false);
+img.src = 'myImage.png'; // Set source path
+
+ +

If you're only using one external image this can be a good approach, but once you need to track more than one we need to resort to something more clever. It's beyond the scope of this tutorial to look at image pre-loading tactics, but you should keep that in mind.

+ +

데이터를 사용하여 이미지 불러오기Embedding an image via data: URL

+ +

Another possible way to include images is via the data: url. Data URLs allow you to completely define an image as a Base64 encoded string of characters directly in your code.

+ +
var img = new Image();   // Create new img element
+img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
+
+ +

One advantage of data URLs is that the resulting image is available immediately without another round trip to the server. Another potential advantage is that it is also possible to encapsulate in one file all of your CSS, JavaScript, HTML, and images, making it more portable to other locations.

+ +

Some disadvantages of this method are that your image is not cached, and for larger images the encoded url can become quite long.

+ +

비디오 프레임 사용하기Using frames from a video

+ +

You can also use frames from a video being presented by a {{HTMLElement("video")}} element (even if the video is not visible). For example, if you have a {{HTMLElement("video")}} element with the ID "myvideo", you can do this:

+ +
function getMyVideo() {
+  var canvas = document.getElementById('canvas');
+  if (canvas.getContext) {
+    var ctx = canvas.getContext('2d');
+
+    return document.getElementById('myvideo');
+  }
+}
+
+ +

This returns the {{domxref("HTMLVideoElement")}} object for the video, which, as covered earlier, is one of the objects that can be used as a CanvasImageSource.

+ +

이미지 그리기

+ +

Once we have a reference to our source image object we can use the drawImage() method to render it to the canvas. As we will see later the drawImage() method is overloaded and has several variants. In its most basic form it looks like this:

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}
+
Draws the CanvasImageSource specified by the image parameter at the coordinates (x, y).
+
+ +
+

SVG images must specify a width and height in the root <svg> element.

+
+ +

예제: 기본 선 그래프

+ +

In the following example, we will use an external image as the backdrop for a small line graph. Using backdrops can make your script considerably smaller because we can avoid the need for code to generate the background. In this example, we're only using one image, so I use the image object's load event handler to execute the drawing statements. The drawImage() method places the backdrop at the coordinate (0, 0), which is the top-left corner of the canvas.

+ + + +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function() {
+    ctx.drawImage(img, 0, 0);
+    ctx.beginPath();
+    ctx.moveTo(30, 96);
+    ctx.lineTo(70, 66);
+    ctx.lineTo(103, 76);
+    ctx.lineTo(170, 15);
+    ctx.stroke();
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
+}
+ +

The resulting graph looks like this:

+ +

{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}

+ +

비례 크기 조정

+ +

The second variant of the drawImage() method adds two new parameters and lets us place scaled images on the canvas.

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y, width, height)")}}
+
This adds the width and height parameters, which indicate the size to which to scale the image when drawing it onto the canvas.
+
+ +

예제: 이미지를 타일처럼 배치

+ +

In this example, we'll use an image as a wallpaper and repeat it several times on the canvas. This is done simply by looping and placing the scaled images at different positions. In the code below, the first for loop iterates over the rows. The second for loop iterates over the columns. The image is scaled to one third of its original size, which is 50x38 pixels.

+ +
+

Note: Images can become blurry when scaling up or grainy if they're scaled down too much. Scaling is probably best not done if you've got some text in it which needs to remain legible.

+
+ + + +
function draw() {
+  var ctx = document.getElementById('canvas').getContext('2d');
+  var img = new Image();
+  img.onload = function() {
+    for (var i = 0; i < 4; i++) {
+      for (var j = 0; j < 3; j++) {
+        ctx.drawImage(img, j * 50, i * 38, 50, 38);
+      }
+    }
+  };
+  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
+}
+ +

The resulting canvas looks like this:

+ +

{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}

+ +

이미지 자르기

+ +

The third and last variant of the drawImage() method has eight parameters in addition to the image source. It lets us cut out a section of the source image, then scale and draw it on our canvas.

+ +
+
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}
+
Given an image, this function takes the area of the source image specified by the rectangle whose top-left corner is (sx, sy) and whose width and height are sWidth and sHeight and draws it into the canvas, placing it on the canvas at (dx, dy) and scaling it to the size specified by dWidth and dHeight.
+
+ +

To really understand what this does, it may help to look at the image to the right. The first four parameters define the location and size of the slice on the source image. The last four parameters define the rectangle into which to draw the image on the destination canvas.

+ +

Slicing can be a useful tool when you want to make compositions. You could have all elements in a single image file and use this method to composite a complete drawing. For instance, if you want to make a chart you could have a PNG image containing all the necessary text in a single file and depending on your data could change the scale of your chart fairly easily. Another advantage is that you don't need to load every image individually, which can improve load performance.

+ +

예제: 이미지 프레임 넣기

+ +

In this example, we'll use the same rhino as in the previous example, but we'll slice out its head and composite it into a picture frame. The picture frame image is a 24-bit PNG which includes a drop shadow. Because 24-bit PNG images include a full 8-bit alpha channel, unlike GIF and 8-bit PNG images, it can be placed onto any background without worrying about a matte color.

+ +
<html>
+ <body onload="draw();">
+   <canvas id="canvas" width="150" height="150"></canvas>
+   <div style="display:none;">
+     <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227">
+     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
+   </div>
+ </body>
+</html>
+
+ +
function draw() {
+  var canvas = document.getElementById('canvas');
+  var ctx = canvas.getContext('2d');
+
+  // Draw slice
+  ctx.drawImage(document.getElementById('source'),
+                33, 71, 104, 124, 21, 20, 87, 104);
+
+  // Draw frame
+  ctx.drawImage(document.getElementById('frame'), 0, 0);
+}
+ +

We took a different approach to loading the images this time. Instead of loading them by creating new {{domxref("HTMLImageElement")}} objects, we included them as {{HTMLElement("img")}} tags directly in our HTML source and retrieved the images from those. The images are hidden from output by setting the CSS property {{cssxref("display")}} to none for those images.

+ +

{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}

+ +

The script itself is very simple. Each {{HTMLElement("img")}} is assigned an ID attribute, which makes them easy to select using {{domxref("document.getElementById()")}}. We then simply use drawImage() to slice the rhino out of the first image and scale him onto the canvas, then draw the frame on top using a second drawImage() call.

+ +

아트 갤러리 예제

+ +

In the final example of this chapter, we'll build a little art gallery. The gallery consists of a table containing several images. When the page is loaded, a {{HTMLElement("canvas")}}  element is inserted for each image and a frame is drawn around it.

+ +

In this case, every image has a fixed width and height, as does the frame that's drawn around them. You could enhance the script so that it uses the image's width and height to make the frame fit perfectly around it.

+ +

The code below should be self-explanatory. We loop through the {{domxref("document.images")}} container and add new canvas elements accordingly. Probably the only thing to note, for those not so familiar with the DOM, is the use of the {{domxref("Node.insertBefore")}} method. insertBefore() is a method of the parent node (a table cell) of the element (the image) before which we want to insert our new node (the canvas element).

+ +
<html>
+ <body onload="draw();">
+     <table>
+      <tr>
+        <td><img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"></td>
+      </tr>
+      <tr>
+        <td><img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"></td>
+        <td><img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"></td>
+      </tr>
+     </table>
+     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
+ </body>
+</html>
+
+ +

And here's some CSS to make things look nice:

+ +
body {
+  background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A;
+  margin: 10px;
+}
+
+img {
+  display: none;
+}
+
+table {
+  margin: 0 auto;
+}
+
+td {
+  padding: 15px;
+}
+
+ +

Tying it all together is the JavaScript to draw our framed images:

+ +
function draw() {
+
+  // Loop through all images
+  for (var i = 0; i < document.images.length; i++) {
+
+    // Don't add a canvas for the frame image
+    if (document.images[i].getAttribute('id') != 'frame') {
+
+      // Create canvas element
+      canvas = document.createElement('canvas');
+      canvas.setAttribute('width', 132);
+      canvas.setAttribute('height', 150);
+
+      // Insert before the image
+      document.images[i].parentNode.insertBefore(canvas,document.images[i]);
+
+      ctx = canvas.getContext('2d');
+
+      // Draw image to canvas
+      ctx.drawImage(document.images[i], 15, 20);
+
+      // Add frame
+      ctx.drawImage(document.getElementById('frame'), 0, 0);
+    }
+  }
+}
+ +

{{EmbedLiveSample("Art_gallery_example", 725, 400)}}

+ +

이미지 비율 습성(scaling behavior) 제어하기

+ +

As mentioned previously, scaling images can result in fuzzy or blocky artifacts due to the scaling process. You can use the drawing context's {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} property to control the use of image smoothing algorithms when scaling images within your context. By default, this is true, meaning images will be smoothed when scaled. You can disable this feature like this:

+ +
ctx.mozImageSmoothingEnabled = false;
+ctx.webkitImageSmoothingEnabled = false;
+ctx.msImageSmoothingEnabled = false;
+ctx.imageSmoothingEnabled = false;
+
+ +

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations")}}

diff --git a/files/ko/web/api/css_object_model/determining_the_dimensions_of_elements/index.html b/files/ko/web/api/css_object_model/determining_the_dimensions_of_elements/index.html new file mode 100644 index 0000000000..c9bb8b32ba --- /dev/null +++ b/files/ko/web/api/css_object_model/determining_the_dimensions_of_elements/index.html @@ -0,0 +1,28 @@ +--- +title: Determining the dimensions of elements +slug: Determining_the_dimensions_of_elements +translation_of: Web/API/CSS_Object_Model/Determining_the_dimensions_of_elements +--- +

엘리먼트의 너비와 높이를 알기 위해 살펴볼 수 있는 여러 속성이 있습니다. 또한, 요구하는 사항에 딱 맞는 것을 고르기 다소 까다로울 수도 있습니다. 이 글은 여러분이 필요에 맞는 속성을 고르는데 도움을 주기 위해 작성했습니다.

+ +

공간을 얼마나 차지하나요?

+ +

표시된 컨텐트의 너비, 스크롤바, 패딩까지 포함해서 엘리먼트가 차지하는 전체 공간을 알고 싶다면, offsetWidthoffsetHeight 속성을 사용하세요:

+ +

Image:Dimensions-offset.png

+ +

보이는 컨텐트의 크기는요?

+ +

패딩은 포함하되 경계선, 여백, 스크롤바는 포함시키지 않고 보이는 컨텐트가 실제로 차지하는 공간이 알고 싶다면, clientWidthclientHeight 속성을 사용하세요:

+ +

Image:Dimensions-client.png

+ +

컨텐트는 얼마나 크나요?

+ +

컨텐트의 실제 크기를 알고 싶다면(보여지는 부분만이 아닌 전체 컨텐트 크기), scrollWidthscrollHeight 속성을 사용하세요. 이 속성들은 엘리먼트 컨텐트의 전체 크기에 해당하는 너비와 높이를 반환합니다. 보여지는 영역이 작아서 스크롤바를 사용하고 있다해도 관계없습니다.

+ +

예를 들어, 600x400 픽셀 크기의 엘리먼트가 300x300 픽셀의 스크롤박스에서 보여진다면 scrollWidth는 600을, scrollHeight는 400을 각각 반환합니다.

+ +

참고자료

+ +

MSDN: Measuring Element Dimension and Location

diff --git a/files/ko/web/api/css_object_model/managing_screen_orientation/index.html b/files/ko/web/api/css_object_model/managing_screen_orientation/index.html new file mode 100644 index 0000000000..934384d0bf --- /dev/null +++ b/files/ko/web/api/css_object_model/managing_screen_orientation/index.html @@ -0,0 +1,136 @@ +--- +title: Managing screen orientation +slug: WebAPI/Managing_screen_orientation +translation_of: Web/API/CSS_Object_Model/Managing_screen_orientation +--- +

{{SeeCompatTable}}

+

Summary

+

Screen orientation 은 device orientation 과는 조금 다르다. 비록 장치가 방향을 감지 못하더라도 화면은 언제나 방향을 가지고 있다. 그리고 만약 장치가 방향을 알 수 있더라도 웹 어플리케이션의 인터페이스를 유지하거나 적응하기 위해 화면의 방향을 조정하는 능력을 갖는게 좋다.

+

화면의 방향을 다루기 위한 여러 방법이 있는데, CSS 와 JavaScript 이다. 첫 번째는 orientation media query 이다. 이것은 내용이 CSS를 사용해서 레이아웃을 조정하게 하는데,  브라우저 창이 가로 모드 (너비가 높이보다 큼) 또는 세로모드 (높이가 너비보다 큼) 여부에 달려 있다.

+

두번째 방법은 JavaScript Screen orientation API 인데 이것은 화면의 현재 방향을 구하고 잠그는데 사용할 수 있다.

+

Adjusting layout based on the orientation

+

방향 변환에서 가장 흔한 케이스 중 하나는 장치의 방향에 따라 내용의 레이아웃을 조정 하는 것이다. 예를 들자면, 당신은 버튼바를 장치 화면의 가장 긴 크기로 펼치고 싶어 할 수 있는데, media query를 이용해서 쉽고 자동으로 할 수 있다.

+

다음의 HTML code 예제를 보자

+
<ul id="toolbar">
+  <li>A</li>
+  <li>B</li>
+  <li>C</li>
+</ul>
+
+<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis lacinia nisi nec sem viverra vitae fringilla nulla ultricies. In ac est dolor, quis tincidunt leo. Cras commodo quam non tortor consectetur eget rutrum dolor ultricies. Ut interdum tristique dapibus. Nullam quis malesuada est.</p>
+
+

CSS 는 화면 방향에 따라 특정 스타일을 을 다루기 위해 orientation media query 에 의존한다

+
/* First let's define some common styles */
+
+html, body {
+  width : 100%;
+  height: 100%;
+}
+
+body {
+  border: 1px solid black;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+
+p {
+  font   : 1em sans-serif;
+  margin : 0;
+  padding: .5em;
+}
+
+ul {
+  list-style: none;
+
+  font   : 1em monospace;
+  margin : 0;
+  padding: .5em;
+
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+
+  background: black;
+}
+
+li {
+  display: inline-block;
+  margin : 0;
+  padding: 0.5em;
+  background: white;
+}
+
+

Once we have some common styles we can start defining a special case for the orientation

+
/* For portrait, we want the tool bar on top */
+
+@media screen and (orientation: portrait) {
+  #toolbar {
+    width: 100%;
+  }
+}
+
+/* For landscape, we want the tool bar stick on the left */
+
+@media screen and (orientation: landscape) {
+  #toolbar {
+    position: fixed;
+    width: 2.65em;
+    height: 100%;
+  }
+
+  p {
+    margin-left: 2em;
+  }
+
+  li + li {
+    margin-top: .5em;
+  }
+}
+
+

실행 결과를 보자

+ + + + + + + + + + + + + +
PortraitLandscape
{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 180, 350) }}{{ EmbedLiveSample('Adjusting_layout_based_on_the_orientation', 350, 180) }}
+
+

Note: orientation media query 는 실제로 브라우저 창 (또는 iframe) 의 방향에 따라 적용한다. 장치의 방향이 아니다.

+
+

Locking the screen orientation

+
+

Warning: 이 API 는 실험적이며 현재 Firefox OS 와 Firefox for Android 에서 moz 접두사를 이용하여 사용할 수 있다.

+
+

몇몇 장치들은 (주로 모바일 장치) 사용자가 언제나 화면을 읽을 수 있게 장치의 방향에 따라 동적으로 화면의 방향을 변화시킬 수 있다. 만약 이러한 행위가 텍스트 컨텐츠에 적합하다면, 이러한 변화 때문에 고통 받을 수 있는 켄텐츠도 있다. 예를 들어, 장치의 방향에 따른 게임들은 이러한 방향전환 때문에 혼란스러울 수 있다.

+

Screen Orientation API 는 정확히 그러한 변화를 방지하기 위해 만들어졌다.

+

Listening orientation change

+

{{event("orientationchange")}} 이벤트는 장치가 화면의 방향을 변환할 때와 방향이  {{domxref("window.screen.orientation","screen.orientation")}} 속성과 함께 읽혀질 때 마다 불려 진다.  

+
screen.addEventListener("orientationchange", function () {
+  console.log("The orientation of the screen is: " + screen.orientation);
+});
+
+

Preventing orientation change

+

모든 웹 어플리케이션은 필요에 따라 스크린을 잠굴 수 있다. 화면은 {{domxref("window.screen.lockOrientation","screen.lockOrientation()")}} 함수를 사용하여 잠그고 {{domxref("window.screen.unlockOrientation","screen.unlockOrientation()")}}. 함수로 잠금 해제 한다.

+

{{domxref("window.screen.lockOrientation","screen.lockOrientation()")}} 는 적용 할 잠금의 종류를 정의하는 문자열  (또는 일련의 문자열) 을 수용한다. 수용하는 값들: portrait-primary, portrait-secondary, landscape-primary, landscape-secondary, portrait, landscape (각각의 값들에 대해 좀 더 알려면  {{domxref("window.screen.lockOrientation","lockOrientation")}}  를 보라).

+
screen.lockOrientation('landscape');
+
+

Note: 화면 잠금은 웹 어플리케이션에 따라 다르다. 어플레케이션 A이 가로모드로 잠겨 있고 어플레케이션 B가 세로모드로 잠겨 있을 때, 어플리케이션을 A 에서 B 로 또는 B 에서 A 로 전환하면 {{event("orientationchange")}} 를 호출하지 않는다. 왜냐하면 각 어플리케이션은 각자의 방향을 유지 하기 때문이다.

+

그러나, 만약 잠금요구를 만족하기 위해 방향이 바뀌어야한다면 화면잠금은 {{event("orientationchange")}} 이벤트를 호출 할 수 있다.

+
+

See also

+ diff --git a/files/ko/web/api/detecting_device_orientation/index.html b/files/ko/web/api/detecting_device_orientation/index.html new file mode 100644 index 0000000000..664842f66d --- /dev/null +++ b/files/ko/web/api/detecting_device_orientation/index.html @@ -0,0 +1,273 @@ +--- +title: 기기 방향 감지하기 +slug: WebAPI/Detecting_device_orientation +translation_of: Web/API/Detecting_device_orientation +--- +
{{SeeCompatTable}}
+ +

요약

+ +

웹을 이용 가능한 기기들은 자신들의 방향을 알 수 있게 되었다. 즉, 중력과의 관계에서 자신의 방향의 변화를 나타내는 데이터를 알 수 있다는 뜻이다. 특히, 휴대 전화와 같이 손에 쥐고 쓸 수 있는 기기들은 이 정보를 화면을 수직으로 유지하기 위해 자동으로 회전시키는데 사용할 수 있고, 기기가 회전되어서 폭이 높이보다 길 때는 와이드 스크린으로 표시할 수 있게 된다.

+ +

방향 정보를 다루는 두 가지 방법의 JavaScript 이벤트가 있다. 첫 번째는 {{domxref("DeviceOrientationEvent")}}로 가속도계가 기기의 방향의 변화를 감지했을 때 발생한다.  이 방향 이벤트들에 의해 보고되는 데이터를 받아서 처리함으로써, 사용자들이 기기를 움직이여서 생기는 방향과 높이의 변화를 상호 작용적으로 응답할 수 있게 된다.

+ +

두 번째 이벤트는 {{domxref("DeviceMotionEvent")}}로 가속도에 변화가 일어났을 때 발생한다. 이 이벤트는 {{domxref("DeviceOrientationEvent")}}와는 방향이 아닌 가속도를 감지하고 있다는 점에서 다르다. 일반적으로{{domxref("DeviceMotionEvent")}}를 감지할 수 있는 센서들은 저장 장치들을 충격으로부터 보호하기 위해 노트북에서 사용되는 센서들을 포함한다. {{domxref("DeviceOrientationEvent")}}는 모바일 기기에서 주로 더 많이 나타난다.

+ +

방향 이벤트 처리하기

+ +

방향의 변화를 받기 위해 여러분이 해야하는 것은 {{ event("deviceorientation") }} 이벤트에 리스너를 등록하는 것 뿐이다:

+ +
window.addEventListener("deviceorientation", handleOrientation, true);
+
+ +

이벤트 리스너를 등록한 후에는 (여기에서는 JavaScript 함수 handleOrientation()), 리스너 함수가 업데이트 된 방향 데이터와 함께 주기적으로 호출된다.

+ +

방향 이벤트는 다음 네 개의 값을 가진다:

+ + + +

이벤트 핸들러 함수는 보통 다음과 같다:

+ +
function handleOrientation(event) {
+  var absolute = event.absolute;
+  var alpha    = event.alpha;
+  var beta     = event.beta;
+  var gamma    = event.gamma;
+
+  // Do stuff with the new orientation data
+}
+
+ +

방향 값 설명

+ +

각 축으로부터 보고된 값은 표준 좌표계 축을 중심으로 회전한 양을 가리킨다. 더 자세한 내용은 Orientation and motion data explained 문서에 나와있으며, 다음은 이를 간략하게 요약한 것이다.

+ + + +

방향 예제

+ +

이 예제는 {{event("deviceorientation")}} 이벤트를 지원하고 방향을 감지할 수 있는 기기에서 실행중인 모든 브라우저에서 작동한다.

+ +

자 그럼, 정원에 공이 하나 있다고 상상해보자:

+ +
<div class="garden">
+  <div class="ball"></div>
+</div>
+
+<pre class="output"></pre>
+
+ +

이 정원은 가로 세로 200 픽셀이고(그렇다, 작은 정원이다), 정 중앙에 공이 있다:

+ +
.garden {
+  position: relative;
+  width : 200px;
+  height: 200px;
+  border: 5px solid #CCC;
+  border-radius: 10px;
+}
+
+.ball {
+  position: absolute;
+  top   : 90px;
+  left  : 90px;
+  width : 20px;
+  height: 20px;
+  background: green;
+  border-radius: 100%;
+}
+
+ +

이제, 우리가 기기를 움직이면 공도 따라서 움직일 것이다:

+ +
var ball   = document.querySelector('.ball');
+var garden = document.querySelector('.garden');
+var output = document.querySelector('.output');
+
+var maxX = garden.clientWidth  - ball.clientWidth;
+var maxY = garden.clientHeight - ball.clientHeight;
+
+function handleOrientation(event) {
+  var x = event.beta;  // In degree in the range [-180,180]
+  var y = event.gamma; // In degree in the range [-90,90]
+
+  output.innerHTML  = "beta : " + x + "\n";
+  output.innerHTML += "gamma: " + y + "\n";
+
+  // Because we don't want to have the device upside down
+  // We constrain the x value to the range [-90,90]
+  if (x >  90) { x =  90};
+  if (x < -90) { x = -90};
+
+  // To make computation easier we shift the range of
+  // x and y to [0,180]
+  x += 90;
+  y += 90;
+
+  // 10 is half the size of the ball
+  // It center the positionning point to the center of the ball
+  ball.style.top  = (maxX*x/180 - 10) + "px";
+  ball.style.left = (maxY*y/180 - 10) + "px";
+}
+
+window.addEventListener('deviceorientation', handleOrientation);
+
+ +

여기 실제로 실행해 볼 수 있는 예제이다:

+ +
{{ EmbedLiveSample('Orientation_example', '230', '260') }}
+ +
+

경고: Chrome과 Firefox는 동일한 방식으로 각을 다루지 않습니다. 그래서 어떤 축의 방향은 반대가 됩니다.

+
+ +

모션 이벤트 처리하기

+ +

모션 이벤트는 이벤트 이름이 {{ event("devicemotion") }}으로 다르다는 점을 제외하면, 방향 이벤트를 처리하는 방법과 동일하다.

+ +
window.addEventListener("devicemotion", handleMotion, true);
+ +

HandleMotion 함수의 파라미터로 넘겨진 {{ domxref("DeviceMotionEvent") }} 객체에 실제로 변화된 정보들이 담겨져 있다.

+ +

모션 이벤트는 다음 네 가지 속성을 가진다:

+ + + +

모션 값 설명

+ +

{{ domxref("DeviceMotionEvent") }} 객체는 웹 개발자들에게 기기의 위치와 방향의 변화 속도에 관한 정보를 제공한다. 세 개의 축에 따라 변화한 정보가 제공된다 (자세한 내용은 Orientation and motion data explained 문서를 참조).

+ +

{{domxref("DeviceMotionEvent.acceleration","acceleration")}}과 {{domxref("DeviceMotionEvent.accelerationIncludingGravity","accelerationIncludingGravity")}}에서, 각 축은 다음에 해당된다:

+ + + +

{{domxref("DeviceMotionEvent.rotationRate","rotationRate")}}에서, 조금은 다르게, 각 값들은 다음에 해당된다:

+ + + +

마지막으로, {{domxref("DeviceMotionEvent.interval","interval")}}은 기기에서 데이터를 얻을 수 있는 시간 간격(단위는 밀리초)을 의미한다.

+ +

스펙

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Device Orientation')}}{{Spec2('Device Orientation')}}Initial specification.
+ +

브라우저 호환성

+ +

{{ CompatibilityTable() }}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
{{domxref("DeviceOrientationEvent")}}7.03.6[1]
+ 6
{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
{{domxref("DeviceMotionEvent")}}{{ CompatVersionUnknown() }}6{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
{{domxref("DeviceOrientationEvent")}}3.03.6[1]
+ 6
{{ CompatNo() }}{{ CompatNo() }}4.2
{{domxref("DeviceMotionEvent")}}{{ CompatVersionUnknown() }}6{{ CompatUnknown() }}{{ CompatUnknown() }}4.2
+
+ +

Gecko 구현 참고 사항

+ +
    +
  1. Firefox 3.6, 4, 5는 표준인 {{domxref("DeviceOrientationEvent")}} 이벤트가 아닌 mozOrientation 을 지원한다
  2. +
+ +

참고 자료

+ + diff --git a/files/ko/web/api/document/createevent/index.html b/files/ko/web/api/document/createevent/index.html new file mode 100644 index 0000000000..549a51bfdc --- /dev/null +++ b/files/ko/web/api/document/createevent/index.html @@ -0,0 +1,30 @@ +--- +title: Event.createEvent() +slug: Web/API/Event/createEvent +translation_of: Web/API/Document/createEvent +translation_of_original: Web/API/Event/createEvent +--- +

{{APIRef("DOM")}}

+ +

새로운 event를 생성합니다, 새로 만들어진 event는 반드시 자신의 init() method를 호출함으로써 초기화되어야만 합니다.

+ +

Syntax

+ +
document.createEvent(type) 
+ +
+
type
+
A string indicating the event type to create.
+
+ +

이 method는 명시된 타입인 새로운 DOM {{ domxref("Event") }} 객체를 반환하며 이는 반드시 사용 전에 초기화되어야만 합니다.

+ +

Example

+ +
var newEvent = document.createEvent("UIEvents");
+ +

Specification

+ + diff --git a/files/ko/web/api/document/getselection/index.html b/files/ko/web/api/document/getselection/index.html deleted file mode 100644 index c4d219fbde..0000000000 --- a/files/ko/web/api/document/getselection/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Document.getSelection() -slug: Web/API/Document/getSelection -translation_of: Web/API/DocumentOrShadowRoot/getSelection -translation_of_original: Web/API/Document/getSelection ---- -

{{APIRef("DOM")}}

- -

이 메소드는 {{domxref("Window.getSelection()")}} 와 동일합니다. 이 메소드는 {{domxref("Selection")}} 형의 객체를 반환하는데, 이 객체는 현재 페이지에서 선택된 영역의 정보를 반영합니다.

diff --git a/files/ko/web/api/document_object_model/introduction/index.html b/files/ko/web/api/document_object_model/introduction/index.html new file mode 100644 index 0000000000..b31dbc43d9 --- /dev/null +++ b/files/ko/web/api/document_object_model/introduction/index.html @@ -0,0 +1,239 @@ +--- +title: DOM 소개 +slug: Web/API/Document_Object_Model/소개 +tags: + - DOM + - 가이드 + - 문서 +translation_of: Web/API/Document_Object_Model/Introduction +--- +

이 문서는 {{glossary("DOM")}}에 대한 개념을 간략하게 소개하는 문서이다: DOM 이 무엇이며, 그것이 어떻게 {{glossary("HTML")}}, {{glossary("XML")}} 문서들을 위한 구조를 제공하는지, 어떻게 DOM 에 접근하는지, API 가 어떻게 사용되는지에 대한 참조 정보와 예제들을 제공한다. 

+ +

DOM 이란?

+ +

문서 객체 모델(The Document Object Model, 이하 DOM) 은 HTML, XML 문서의 프로그래밍 interface 이다. DOM은 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다. DOM 은 구조화된 nodes와 property 와 method 를 갖고 있는 objects로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.

+ +

웹 페이지는 일종의 문서(document)다.  이 문서는 웹 브라우저를 통해 그 내용이 해석되어 웹 브라우저 화면에 나타나거나 HTML 소스 자체로 나타나기도 한다. 동일한 문서를 사용하여 이처럼 다른 형태로 나타날 수 있다는 점에 주목할 필요가 있다. DOM 은 동일한 문서를 표현하고, 저장하고, 조작하는 방법을 제공한다. DOM 은 웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM 을 수정할 수 있다.

+ +

W3C DOMWHATWG DOM 표준은 대부분의 브라우저에서 DOM 을 구현하는 기준이다. 많은 브라우저들이 표준 규약에서 제공하는 기능 외에도 추가적인 기능들을 제공하기 때문에 사용자가 작성한 문서들이 각기 다른 DOM 이 적용된 다양한 브라우저 환경에서 동작할 수 있다는 사실을 항상 인지하고 있어야 한다.

+ +

예를 들어, 표준 DOM 에서는 문서 안에서 모든 <P> elements 에 대한 list 를 리턴하는 getElementsByTagName method 를 정의하고 있다:

+ +
var paragraphs = document.getElementsByTagName("P");
+// paragraphs[0] is the first <p> element
+// paragraphs[1] is the second <p> element, etc.
+alert(paragraphs[0].nodeName);
+
+ +

웹 페이지를 수정하거나 생성하는데 사용되는 모든 property, method, event 들은 objects 로 구성된다. 예를 들어 document object 는 document 자체를 의미하며, table object 는 HTML table 에 접근하기 위한 HTMLTableElement DOM 인터페이스를 구현한 것이다. 이 문서는 Gecko 기반의 브라우저에서 구현된 DOM 에 대한 object-by-object reference 를 제공한다.

+ +

DOM 과 자바스크립트

+ +

이 문서의 대부분의 예제와 같이, 위에서 사용된 예제는 {{glossary("JavaScript")}}이다. 위의 예제는 자바스크립트로 작성되었지만 문서(document) 와 문서의 요소(element) 에 접근하기 위해 DOM 이 사용되었다. DOM 은 프로그래밍 언어는 아니지만 DOM 이 없다면 자바스크립트 언어는 웹 페이지 또는 XML 페이지 및 요소들과 관련된 모델이나 개념들에 대한 정보를 갖지 못하게 된다. 문서의 모든 element - 전체 문서, 헤드, 문서 안의 table, table header, table cell 안의 text - 는 문서를 위한 document object model 의 한 부분이다. 때문에, 이러한 요소들을 DOM 과 자바스크립트와 같은 스크립팅 언어를 통해 접근하고 조작할 수 있는 것이다.  

+ +

초창기에는 자바스크립트와 DOM 가 밀접하게 연결되어 있었지만,  나중에는 각각 분리되어 발전해왔다. 페이지 콘텐츠(the page content)는 DOM 에 저장되고 자바스크립트를 통해 접근하거나 조작할 수 있다. 이것을 방정식으로 표현하면 아래와 같다:

+ +

API (web or XML page) = DOM + JS (scripting language)

+ +

DOM 은 프로그래밍 언어와 독립적으로 디자인되었다. 때문에 문서의 구조적인 표현은 단일 API 를 통해 이용가능하다.  이 문서에서는 자바스크립트를 주로 사용하였지만, DOM 의 구현은 어떠한 언어에서도 가능하다. 아래는 파이썬을 사용한 예제이다:

+ +
# Python DOM example
+import xml.dom.minidom as m
+doc = m.parse("C:\\Projects\\Py\\chap1.xml");
+doc.nodeName # DOM property of document object;
+p_list = doc.getElementsByTagName("para");
+
+ +

웹에서 자바스크립트 사용하기와 관련된 기술에 대한 추가정보는 자바스크립트 기술 개요 문서를 참조하라.

+ +

DOM 에 어떻게 접근할 수 있는가?

+ +

DOM 을 사용하기 위해 특별히 해야할 일은 없다. 각각의 브라우저는 자신만의 방법으로 DOM 구현하였으며, 이로 인해 실제 DOM 기준을 따르는지 확인해야 하는 번거로움이 발생하였다. (이 문제는 이 문서에서 피하고 싶어하는 주제이기도 하다.) 모든 웹 브라우저는 스크립트가 접근할 수 있는 웹 페이지를 만들기 위해 어느 정도의 DOM 을 항상 사용한다. 

+ +

스크립트를 작성할 때(인라인 <script> 요소를 사용하거나 웹 페이지 안에 있는 스크립트 로딩 명령을 사용하여), 문서 자체를 조작하거나 문서의 children 을 얻기 위해 {{domxref("document")}} 또는 window elements 를 위한 API 를 즉시 사용할 수 있다. DOM 프로그래밍은 아래처럼 window object 로 부터 alert() 함수를 사용하여 alert message 를 표시하는 매우 간단한 것일 수도 있고 다음번 예제처럼 새로운 content 를 작성하는 복잡한 DOM 이 될 수도 있다.

+ +
<body onload="window.alert('welcome to my home page!');">
+
+ +

아래의 자바스크립트는 문서가 로드될 때(모든 DOM을 사용할 수 있게 되는 때임) 실행되는 함수를 정의하였다. 이 함수는 새로운 H1 element 를 생성하고, element 에 text 를 추가하며, H1 을 이 문서의 트리에 추가한다.

+ +
<html>
+  <head>
+    <script>
+       // run this function when the document is loaded
+       window.onload = function() {
+
+         // create a couple of elements in an otherwise empty HTML page
+         var heading = document.createElement("h1");
+         var heading_text = document.createTextNode("Big Head!");
+         heading.appendChild(heading_text);
+         document.body.appendChild(heading);
+      }
+    </script>
+  </head>
+  <body>
+  </body>
+</html>
+
+ +

중요한 데이터 타입들

+ +

이 문서는 objects 와 types 을 최대한 간단하게 설명하려 한다. API 에는 우리가 반드시 알고 있어야 할 수많은 data types 이 있다는 사실을 염두해 두기 바란다.  이 문서에서는 nodes 는 elements 로, 노드의 arrays 는 nodeLists(또는 elements), attribute 노드들은 attributes 로 표현하였다.

+ +

아래의 표는 이러한 data types 에 대한 간략한 설명이다.

+ + + + + + + + + + + + + + + + + + + + + + + + +
document +

member 가 document type 의 object 를 리턴할 때(예를 들어 element의 ownerDocument property 는 그것이 속해 있는 document 를 return 한다. ), 이 object 는 root document object 자체이다. 는 document object 에 대한 설명은 DOM document Reference 챕터를 참조하라.

+
element +

element 는 DOM API 의 member 에 의해 return 된 element 또는 element type 의 node 를 의미한다. document.createElement() method 가 node 를 참조하는 object 를 리턴한다고 말하는 대신, 이 method 가 DOM 안에서 생생되는 element 를 리턴한다고 좀 더 단순하게 말할 수 있다. element 객체들은 DOM Element interface 와 함께 좀 더 기본적인 Node interface 를 구현한 것이기 때문에 이 reference 에는 두 가지가 모두 포함되었다고 생각하면 된다.

+
nodeList +

nodeList 는 elements 의 배열이다. (document.getElementsByTagName() method 에 의해 리턴된 것과 같은) nodeList의 Items 은 index 를 통해 접근 가능하며, 다음과 같이 두 가지 방식이 있다:

+ +
    +
  • list.item(1)
  • +
  • list[1]
  • +
+ 위의 방식들은 동일한 것이다. item()method는 nodeList object 의 단일 method 이다. 두번째 방식은 list 에서 두번째 item 을 fetch 하는 전형적인 array syntax 이다.  
attribute +

attribute 가 member 에 의해 리턴되는 것은(예를 들어 createAttribute() method 호출에 의한 리턴), attribute 에 대한 특별한 인터페이스를 노출하는 object reference 이다. attributes 는 DOM 에서 elements 와 같은 nodes 이다. elements 만큼 많이 사용되지는 않는다.

+
namedNodeMap +

namedNodeMap 는 array 와 유사하지만 items 은 name 또는 index 에 의해 접근 가능하다. 리스트는 특별한 정렬이 적용되지 않았기 enumeration 할 때 index 를 주로 사용한다. namedNodeMap 는 이를 위해 item() method 가 있으며, namedNodeMap 에 item 을 추가하거나 삭제할 수 있다.

+
+ +

DOM interfaces

+ +

이 문서는 objects 와 DOM 에서 조작가능한 것들에 대해 설명하고 있다. 사람들은 HTML FORM element 가 HTMLFormElement interface 로부터 name property 를 얻고, className property 는  HTMLElement interface 로부터 얻는 것에 대해 별로 관심을 보이지 않는 것 같다. 두가지 경우 모두, property 는 form object 안에 있는 것이다. 

+ +

하지만 DOM 안에 구현된 objects 와 interfaces 사이의 관계는 혼동될 수 있다. 이 섹션에서는 DOM specification 안의 실제  interfaces 와 그들을 어떻게 활용할 수 있는지에 대해 살펴보도록 하겠다.

+ +

Interfaces 와 Objects

+ +

많은 objects 가 여러 개의 다른 interfaces 와 연관되어 있다.  예를 들어, table object 는 createCaption, insertRow method 들이 포함된 {{domxref("HTMLTableElement")}} 을 구현한 것이다. table object 는 HTML element 이기도 하기 때문에, table 은 Element interface(DOM {{domxref("Element")}} Reference 챕터 참조)도 구현한다. 마지막으로, HTML element 는 DOM 이 연관되어 있는 한 nodes 트리(tree)에서 하나의 node 이다. nodes 트리는 웹 페이지 또는 XML 페이지를 위한 object model 을 구성한다. 때문에 table element 는 보다 기본적인 Element 에서 파생된 Node interface 를 구현하고 있다.

+ +

아래의 예제처럼, table object 를 참조하게 되면, 기본적으로 이들 3 가지 interfaces 를 사용할 수 있게 된다.

+ +
var table = document.getElementById("table");
+var tableAttrs = table.attributes; // Node/Element interface
+for (var i = 0; i < tableAttrs.length; i++) {
+  // HTMLTableElement interface: border attribute
+  if(tableAttrs[i].nodeName.toLowerCase() == "border")
+    table.border = "1";
+}
+// HTMLTableElement interface: summary attribute
+table.summary = "note: increased border";
+
+ +

DOM 의 핵심 Interfaces

+ +

이 섹션은 DOM 에서 가장 많이 사용되는 interfaces 를 정리해보았다. 여기에서는 이들 API 가 실제로 어떤 일을 하는지 설명하는 대신 DOM 을 사용하면서 자주 만나게 되는 methods 와 properties 를 보여줄 것이다.  이들 API 는 이 책의 마지막에 소개된 DOM 예제에서도 사용되었다.

+ +

Documentwindow objects 는 DOM 프로그래밍에서 가장 자주 사용하는 objects 이다.  간단하게 설명하자면, window object 는 브라우저와 같다고 할 수 있으며, document object 는 root document 자체라고 할 수 있다. generic Node interface 로부터 상속받은 ElementNodeElement interfaces 가 협력하여 각각의 elements 에서 사용할 수 있는 수많은 methods 와 properties 를 제공한다. 이러한 elements 는 이전 섹션에서 설명한 table object 예제에서도 살펴봤듯이, elements 가 보유한 데이터를 처리할 수 있는 특정한 interfaces 도 가지고 있다.

+ +

아래는 웹 페이지, XML 페이지 스크립팅에서 DOM 을 사용하는 공통적인 API 들의 간략한 목록이다. 

+ + + +

DOM API 테스팅

+ +

이 문서는 사용자가 웹 개발에 사용할 수 있는 모든 interface 에 대한 예제를 제공한다. 예제는 <script> element 안에서 DOM 에 접근하는 완벽한 HTML 페이지 형태인 것도 있고, form 에서 script 를 실행하기 위해 버튼과 같은 interface 가 필요한 경우도 있으며, DOM 이 목록화되어 수행되는 HTML elements 도 있을 것이다. 사용자들은 이러한 예제를 새로운 HTML 문서에 복사하여 브라우저에서 실행할 수 있다. 

+ +

어떤 예제는 매우 간단할 수도 있다. HTML elements 에 대한 interface의 기본적인 관계만 보여주는 이러한 예제를 실행할 때는, 스크립트에서 쉽게 접근할 수 있는 test page 를 설정할 수도 있다. 아래의 예제는 interface를 테스트 할 수 있는 함수가 위치할 수 있는 header 안에  <script> element 제공한다. 이 함수는 retrieve, set, 조작할 수 있는 attributes 가 포함된 HTML elements 가 사용되었으며, 브라우저에서 이들 함수를 호출하기 위해 웹 UI 를 제공한다.

+ +

사용자는 자신이 관심있어 하는 DOM interfaces 를 테스트 하기 위해, 이 test page 를 사용하거나 이와 비슷한 것을 만들어 브라우저에서 어떻게 동작하는지 확인할 수 있다. 사용자는 test() 함수 내용을 필요에 따라 업데이트할 수 있다. (버튼 추가, elements 추가 등)

+ +
<html>
+  <head>
+    <title>DOM Tests</title>
+    <script type="application/javascript">
+    function setBodyAttr(attr,value){
+      if (document.body) eval('document.body.'+attr+'="'+value+'"');
+      else notSupported();
+    }
+    </script>
+  </head>
+  <body>
+    <div style="margin: .5in; height: 400;">
+      <p><b><tt>text</tt>color</b></p>
+      <form>
+        <select onChange="setBodyAttr('text',
+        this.options[this.selectedIndex].value);">
+          <option value="black">black
+          <option value="darkblue">darkblue
+        </select>
+        <p><b><tt>bgColor</tt></b></p>
+        <select onChange="setBodyAttr('bgColor',
+        this.options[this.selectedIndex].value);">
+          <option value="white">white
+          <option value="lightgrey">gray
+        </select>
+        <p><b><tt>link</tt></b></p>
+        <select onChange="setBodyAttr('link',
+        this.options[this.selectedIndex].value);">
+          <option value="blue">blue
+          <option value="green">green
+        </select>  <small>
+        <a href="http://www.brownhen.com/dom_api_top.html" id="sample">
+        (sample link)</a></small><br>
+      </form>
+      <form>
+        <input type="button" value="version" onclick="ver()" />
+      </form>
+    </div>
+  </body>
+</html>
+
+ +

단일 페이지(예를 들어, 웹 페이지의 색상에 영향을 주는 property 설정하는) 안의 수많은 interfaces 를 테스트하기 위해 설정 버튼, textfield, 또는 다른 HTML elements를 사용하여 유사한 테스트 페이지를 만들 수 있다. 아래의 스크린샷은 테스트를 위해 어떻게 interfaces를 그룹화하는지에 대한 아이디어를 제공하고 있다.  

+ +
+
Figure 0.1 Sample DOM Test Page
+Image:DOM_Ref_Introduction_to_the_DOM.gif
+ +

이 예제에서 드롭다운 메뉴는 웹 페이지에서 DOM 접근가능한 배경색상(bgColor), 하이퍼링크 색상(aLink), 텍스트 색상(text)을 동적으로 업데이트한다. 어떻게 자신의 test pages 를 디자인하더라도, interface 테스트는 DOM 을 효과적으로 사용하는 법을 배우는 데 매우 중요한 수단임을 명심하라.

+ + + + + +
{{DefaultAPISidebar("DOM")}}
diff --git "a/files/ko/web/api/document_object_model/\354\206\214\352\260\234/index.html" "b/files/ko/web/api/document_object_model/\354\206\214\352\260\234/index.html" deleted file mode 100644 index b31dbc43d9..0000000000 --- "a/files/ko/web/api/document_object_model/\354\206\214\352\260\234/index.html" +++ /dev/null @@ -1,239 +0,0 @@ ---- -title: DOM 소개 -slug: Web/API/Document_Object_Model/소개 -tags: - - DOM - - 가이드 - - 문서 -translation_of: Web/API/Document_Object_Model/Introduction ---- -

이 문서는 {{glossary("DOM")}}에 대한 개념을 간략하게 소개하는 문서이다: DOM 이 무엇이며, 그것이 어떻게 {{glossary("HTML")}}, {{glossary("XML")}} 문서들을 위한 구조를 제공하는지, 어떻게 DOM 에 접근하는지, API 가 어떻게 사용되는지에 대한 참조 정보와 예제들을 제공한다. 

- -

DOM 이란?

- -

문서 객체 모델(The Document Object Model, 이하 DOM) 은 HTML, XML 문서의 프로그래밍 interface 이다. DOM은 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다. DOM 은 구조화된 nodes와 property 와 method 를 갖고 있는 objects로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.

- -

웹 페이지는 일종의 문서(document)다.  이 문서는 웹 브라우저를 통해 그 내용이 해석되어 웹 브라우저 화면에 나타나거나 HTML 소스 자체로 나타나기도 한다. 동일한 문서를 사용하여 이처럼 다른 형태로 나타날 수 있다는 점에 주목할 필요가 있다. DOM 은 동일한 문서를 표현하고, 저장하고, 조작하는 방법을 제공한다. DOM 은 웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM 을 수정할 수 있다.

- -

W3C DOMWHATWG DOM 표준은 대부분의 브라우저에서 DOM 을 구현하는 기준이다. 많은 브라우저들이 표준 규약에서 제공하는 기능 외에도 추가적인 기능들을 제공하기 때문에 사용자가 작성한 문서들이 각기 다른 DOM 이 적용된 다양한 브라우저 환경에서 동작할 수 있다는 사실을 항상 인지하고 있어야 한다.

- -

예를 들어, 표준 DOM 에서는 문서 안에서 모든 <P> elements 에 대한 list 를 리턴하는 getElementsByTagName method 를 정의하고 있다:

- -
var paragraphs = document.getElementsByTagName("P");
-// paragraphs[0] is the first <p> element
-// paragraphs[1] is the second <p> element, etc.
-alert(paragraphs[0].nodeName);
-
- -

웹 페이지를 수정하거나 생성하는데 사용되는 모든 property, method, event 들은 objects 로 구성된다. 예를 들어 document object 는 document 자체를 의미하며, table object 는 HTML table 에 접근하기 위한 HTMLTableElement DOM 인터페이스를 구현한 것이다. 이 문서는 Gecko 기반의 브라우저에서 구현된 DOM 에 대한 object-by-object reference 를 제공한다.

- -

DOM 과 자바스크립트

- -

이 문서의 대부분의 예제와 같이, 위에서 사용된 예제는 {{glossary("JavaScript")}}이다. 위의 예제는 자바스크립트로 작성되었지만 문서(document) 와 문서의 요소(element) 에 접근하기 위해 DOM 이 사용되었다. DOM 은 프로그래밍 언어는 아니지만 DOM 이 없다면 자바스크립트 언어는 웹 페이지 또는 XML 페이지 및 요소들과 관련된 모델이나 개념들에 대한 정보를 갖지 못하게 된다. 문서의 모든 element - 전체 문서, 헤드, 문서 안의 table, table header, table cell 안의 text - 는 문서를 위한 document object model 의 한 부분이다. 때문에, 이러한 요소들을 DOM 과 자바스크립트와 같은 스크립팅 언어를 통해 접근하고 조작할 수 있는 것이다.  

- -

초창기에는 자바스크립트와 DOM 가 밀접하게 연결되어 있었지만,  나중에는 각각 분리되어 발전해왔다. 페이지 콘텐츠(the page content)는 DOM 에 저장되고 자바스크립트를 통해 접근하거나 조작할 수 있다. 이것을 방정식으로 표현하면 아래와 같다:

- -

API (web or XML page) = DOM + JS (scripting language)

- -

DOM 은 프로그래밍 언어와 독립적으로 디자인되었다. 때문에 문서의 구조적인 표현은 단일 API 를 통해 이용가능하다.  이 문서에서는 자바스크립트를 주로 사용하였지만, DOM 의 구현은 어떠한 언어에서도 가능하다. 아래는 파이썬을 사용한 예제이다:

- -
# Python DOM example
-import xml.dom.minidom as m
-doc = m.parse("C:\\Projects\\Py\\chap1.xml");
-doc.nodeName # DOM property of document object;
-p_list = doc.getElementsByTagName("para");
-
- -

웹에서 자바스크립트 사용하기와 관련된 기술에 대한 추가정보는 자바스크립트 기술 개요 문서를 참조하라.

- -

DOM 에 어떻게 접근할 수 있는가?

- -

DOM 을 사용하기 위해 특별히 해야할 일은 없다. 각각의 브라우저는 자신만의 방법으로 DOM 구현하였으며, 이로 인해 실제 DOM 기준을 따르는지 확인해야 하는 번거로움이 발생하였다. (이 문제는 이 문서에서 피하고 싶어하는 주제이기도 하다.) 모든 웹 브라우저는 스크립트가 접근할 수 있는 웹 페이지를 만들기 위해 어느 정도의 DOM 을 항상 사용한다. 

- -

스크립트를 작성할 때(인라인 <script> 요소를 사용하거나 웹 페이지 안에 있는 스크립트 로딩 명령을 사용하여), 문서 자체를 조작하거나 문서의 children 을 얻기 위해 {{domxref("document")}} 또는 window elements 를 위한 API 를 즉시 사용할 수 있다. DOM 프로그래밍은 아래처럼 window object 로 부터 alert() 함수를 사용하여 alert message 를 표시하는 매우 간단한 것일 수도 있고 다음번 예제처럼 새로운 content 를 작성하는 복잡한 DOM 이 될 수도 있다.

- -
<body onload="window.alert('welcome to my home page!');">
-
- -

아래의 자바스크립트는 문서가 로드될 때(모든 DOM을 사용할 수 있게 되는 때임) 실행되는 함수를 정의하였다. 이 함수는 새로운 H1 element 를 생성하고, element 에 text 를 추가하며, H1 을 이 문서의 트리에 추가한다.

- -
<html>
-  <head>
-    <script>
-       // run this function when the document is loaded
-       window.onload = function() {
-
-         // create a couple of elements in an otherwise empty HTML page
-         var heading = document.createElement("h1");
-         var heading_text = document.createTextNode("Big Head!");
-         heading.appendChild(heading_text);
-         document.body.appendChild(heading);
-      }
-    </script>
-  </head>
-  <body>
-  </body>
-</html>
-
- -

중요한 데이터 타입들

- -

이 문서는 objects 와 types 을 최대한 간단하게 설명하려 한다. API 에는 우리가 반드시 알고 있어야 할 수많은 data types 이 있다는 사실을 염두해 두기 바란다.  이 문서에서는 nodes 는 elements 로, 노드의 arrays 는 nodeLists(또는 elements), attribute 노드들은 attributes 로 표현하였다.

- -

아래의 표는 이러한 data types 에 대한 간략한 설명이다.

- - - - - - - - - - - - - - - - - - - - - - - - -
document -

member 가 document type 의 object 를 리턴할 때(예를 들어 element의 ownerDocument property 는 그것이 속해 있는 document 를 return 한다. ), 이 object 는 root document object 자체이다. 는 document object 에 대한 설명은 DOM document Reference 챕터를 참조하라.

-
element -

element 는 DOM API 의 member 에 의해 return 된 element 또는 element type 의 node 를 의미한다. document.createElement() method 가 node 를 참조하는 object 를 리턴한다고 말하는 대신, 이 method 가 DOM 안에서 생생되는 element 를 리턴한다고 좀 더 단순하게 말할 수 있다. element 객체들은 DOM Element interface 와 함께 좀 더 기본적인 Node interface 를 구현한 것이기 때문에 이 reference 에는 두 가지가 모두 포함되었다고 생각하면 된다.

-
nodeList -

nodeList 는 elements 의 배열이다. (document.getElementsByTagName() method 에 의해 리턴된 것과 같은) nodeList의 Items 은 index 를 통해 접근 가능하며, 다음과 같이 두 가지 방식이 있다:

- -
    -
  • list.item(1)
  • -
  • list[1]
  • -
- 위의 방식들은 동일한 것이다. item()method는 nodeList object 의 단일 method 이다. 두번째 방식은 list 에서 두번째 item 을 fetch 하는 전형적인 array syntax 이다.  
attribute -

attribute 가 member 에 의해 리턴되는 것은(예를 들어 createAttribute() method 호출에 의한 리턴), attribute 에 대한 특별한 인터페이스를 노출하는 object reference 이다. attributes 는 DOM 에서 elements 와 같은 nodes 이다. elements 만큼 많이 사용되지는 않는다.

-
namedNodeMap -

namedNodeMap 는 array 와 유사하지만 items 은 name 또는 index 에 의해 접근 가능하다. 리스트는 특별한 정렬이 적용되지 않았기 enumeration 할 때 index 를 주로 사용한다. namedNodeMap 는 이를 위해 item() method 가 있으며, namedNodeMap 에 item 을 추가하거나 삭제할 수 있다.

-
- -

DOM interfaces

- -

이 문서는 objects 와 DOM 에서 조작가능한 것들에 대해 설명하고 있다. 사람들은 HTML FORM element 가 HTMLFormElement interface 로부터 name property 를 얻고, className property 는  HTMLElement interface 로부터 얻는 것에 대해 별로 관심을 보이지 않는 것 같다. 두가지 경우 모두, property 는 form object 안에 있는 것이다. 

- -

하지만 DOM 안에 구현된 objects 와 interfaces 사이의 관계는 혼동될 수 있다. 이 섹션에서는 DOM specification 안의 실제  interfaces 와 그들을 어떻게 활용할 수 있는지에 대해 살펴보도록 하겠다.

- -

Interfaces 와 Objects

- -

많은 objects 가 여러 개의 다른 interfaces 와 연관되어 있다.  예를 들어, table object 는 createCaption, insertRow method 들이 포함된 {{domxref("HTMLTableElement")}} 을 구현한 것이다. table object 는 HTML element 이기도 하기 때문에, table 은 Element interface(DOM {{domxref("Element")}} Reference 챕터 참조)도 구현한다. 마지막으로, HTML element 는 DOM 이 연관되어 있는 한 nodes 트리(tree)에서 하나의 node 이다. nodes 트리는 웹 페이지 또는 XML 페이지를 위한 object model 을 구성한다. 때문에 table element 는 보다 기본적인 Element 에서 파생된 Node interface 를 구현하고 있다.

- -

아래의 예제처럼, table object 를 참조하게 되면, 기본적으로 이들 3 가지 interfaces 를 사용할 수 있게 된다.

- -
var table = document.getElementById("table");
-var tableAttrs = table.attributes; // Node/Element interface
-for (var i = 0; i < tableAttrs.length; i++) {
-  // HTMLTableElement interface: border attribute
-  if(tableAttrs[i].nodeName.toLowerCase() == "border")
-    table.border = "1";
-}
-// HTMLTableElement interface: summary attribute
-table.summary = "note: increased border";
-
- -

DOM 의 핵심 Interfaces

- -

이 섹션은 DOM 에서 가장 많이 사용되는 interfaces 를 정리해보았다. 여기에서는 이들 API 가 실제로 어떤 일을 하는지 설명하는 대신 DOM 을 사용하면서 자주 만나게 되는 methods 와 properties 를 보여줄 것이다.  이들 API 는 이 책의 마지막에 소개된 DOM 예제에서도 사용되었다.

- -

Documentwindow objects 는 DOM 프로그래밍에서 가장 자주 사용하는 objects 이다.  간단하게 설명하자면, window object 는 브라우저와 같다고 할 수 있으며, document object 는 root document 자체라고 할 수 있다. generic Node interface 로부터 상속받은 ElementNodeElement interfaces 가 협력하여 각각의 elements 에서 사용할 수 있는 수많은 methods 와 properties 를 제공한다. 이러한 elements 는 이전 섹션에서 설명한 table object 예제에서도 살펴봤듯이, elements 가 보유한 데이터를 처리할 수 있는 특정한 interfaces 도 가지고 있다.

- -

아래는 웹 페이지, XML 페이지 스크립팅에서 DOM 을 사용하는 공통적인 API 들의 간략한 목록이다. 

- - - -

DOM API 테스팅

- -

이 문서는 사용자가 웹 개발에 사용할 수 있는 모든 interface 에 대한 예제를 제공한다. 예제는 <script> element 안에서 DOM 에 접근하는 완벽한 HTML 페이지 형태인 것도 있고, form 에서 script 를 실행하기 위해 버튼과 같은 interface 가 필요한 경우도 있으며, DOM 이 목록화되어 수행되는 HTML elements 도 있을 것이다. 사용자들은 이러한 예제를 새로운 HTML 문서에 복사하여 브라우저에서 실행할 수 있다. 

- -

어떤 예제는 매우 간단할 수도 있다. HTML elements 에 대한 interface의 기본적인 관계만 보여주는 이러한 예제를 실행할 때는, 스크립트에서 쉽게 접근할 수 있는 test page 를 설정할 수도 있다. 아래의 예제는 interface를 테스트 할 수 있는 함수가 위치할 수 있는 header 안에  <script> element 제공한다. 이 함수는 retrieve, set, 조작할 수 있는 attributes 가 포함된 HTML elements 가 사용되었으며, 브라우저에서 이들 함수를 호출하기 위해 웹 UI 를 제공한다.

- -

사용자는 자신이 관심있어 하는 DOM interfaces 를 테스트 하기 위해, 이 test page 를 사용하거나 이와 비슷한 것을 만들어 브라우저에서 어떻게 동작하는지 확인할 수 있다. 사용자는 test() 함수 내용을 필요에 따라 업데이트할 수 있다. (버튼 추가, elements 추가 등)

- -
<html>
-  <head>
-    <title>DOM Tests</title>
-    <script type="application/javascript">
-    function setBodyAttr(attr,value){
-      if (document.body) eval('document.body.'+attr+'="'+value+'"');
-      else notSupported();
-    }
-    </script>
-  </head>
-  <body>
-    <div style="margin: .5in; height: 400;">
-      <p><b><tt>text</tt>color</b></p>
-      <form>
-        <select onChange="setBodyAttr('text',
-        this.options[this.selectedIndex].value);">
-          <option value="black">black
-          <option value="darkblue">darkblue
-        </select>
-        <p><b><tt>bgColor</tt></b></p>
-        <select onChange="setBodyAttr('bgColor',
-        this.options[this.selectedIndex].value);">
-          <option value="white">white
-          <option value="lightgrey">gray
-        </select>
-        <p><b><tt>link</tt></b></p>
-        <select onChange="setBodyAttr('link',
-        this.options[this.selectedIndex].value);">
-          <option value="blue">blue
-          <option value="green">green
-        </select>  <small>
-        <a href="http://www.brownhen.com/dom_api_top.html" id="sample">
-        (sample link)</a></small><br>
-      </form>
-      <form>
-        <input type="button" value="version" onclick="ver()" />
-      </form>
-    </div>
-  </body>
-</html>
-
- -

단일 페이지(예를 들어, 웹 페이지의 색상에 영향을 주는 property 설정하는) 안의 수많은 interfaces 를 테스트하기 위해 설정 버튼, textfield, 또는 다른 HTML elements를 사용하여 유사한 테스트 페이지를 만들 수 있다. 아래의 스크린샷은 테스트를 위해 어떻게 interfaces를 그룹화하는지에 대한 아이디어를 제공하고 있다.  

- -
-
Figure 0.1 Sample DOM Test Page
-Image:DOM_Ref_Introduction_to_the_DOM.gif
- -

이 예제에서 드롭다운 메뉴는 웹 페이지에서 DOM 접근가능한 배경색상(bgColor), 하이퍼링크 색상(aLink), 텍스트 색상(text)을 동적으로 업데이트한다. 어떻게 자신의 test pages 를 디자인하더라도, interface 테스트는 DOM 을 효과적으로 사용하는 법을 배우는 데 매우 중요한 수단임을 명심하라.

- - - - - -
{{DefaultAPISidebar("DOM")}}
diff --git a/files/ko/web/api/documentorshadowroot/getselection/index.html b/files/ko/web/api/documentorshadowroot/getselection/index.html new file mode 100644 index 0000000000..c4d219fbde --- /dev/null +++ b/files/ko/web/api/documentorshadowroot/getselection/index.html @@ -0,0 +1,9 @@ +--- +title: Document.getSelection() +slug: Web/API/Document/getSelection +translation_of: Web/API/DocumentOrShadowRoot/getSelection +translation_of_original: Web/API/Document/getSelection +--- +

{{APIRef("DOM")}}

+ +

이 메소드는 {{domxref("Window.getSelection()")}} 와 동일합니다. 이 메소드는 {{domxref("Selection")}} 형의 객체를 반환하는데, 이 객체는 현재 페이지에서 선택된 영역의 정보를 반영합니다.

diff --git a/files/ko/web/api/element/accesskey/index.html b/files/ko/web/api/element/accesskey/index.html deleted file mode 100644 index 0fc48bd749..0000000000 --- a/files/ko/web/api/element/accesskey/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Element.accessKey -slug: Web/API/Element/accessKey -tags: - - API - - Access Keys - - DOM - - Hotkeys - - NeedsContent - - 레퍼런스 - - 속성 - - 엘리먼트 - - 키보드 단축키 -translation_of: Web/API/HTMLElement/accessKey -translation_of_original: Web/API/Element/accessKey ---- -
{{APIRef("DOM")}}
- -

Element.accessKey 속성은 주어진 사용자가 눌러 주어진 엘리먼트로 이동할 수 있는 키 입력 세트입니다.

- -
-

Element.accessKey 속성은 브라우저에 이미 바인딩 된 키와의 여러 충돌로 인해 거의 사용되지 않습니다. 이를 해결하기 위해, 브라우저는 다른 "적절한" 키(예, Alt + accesskey)와 함께 키가 눌렸을 때동작하도록 구현하였습니다.

-
- -

브라우저 호환성

- - - -

{{Compat("api.Element.accessKey")}}

- -

함께 보기

- - diff --git a/files/ko/web/api/element/blur_event/index.html b/files/ko/web/api/element/blur_event/index.html new file mode 100644 index 0000000000..3bbcc6acb0 --- /dev/null +++ b/files/ko/web/api/element/blur_event/index.html @@ -0,0 +1,154 @@ +--- +title: blur +slug: Web/Events/blur +translation_of: Web/API/Element/blur_event +--- +

blur 이벤트는 엘리먼트의 포커스가 해제되었을때 발생합니다. 이 이벤트와 focusout 이벤트의 가장 다른점은 focusout 은 이벤트 버블링이 발생합니다.

+ +

General info

+ +
+
Specification
+
DOM L3
+
Interface
+
{{domxref("FocusEvent")}}
+
Bubbles
+
No
+
Cancelable
+
No
+
Target
+
Element
+
Default Action
+
None.
+
+ +

{{NoteStart}} 이 이벤트가 처리될때 {{domxref("Document.activeElement")}}의 값이 브라우저마다 다릅니다 ({{bug(452307)}}): IE10은 이 값을 포커스가 옮겨가는 엘리먼트에 추가하지만, 파이어폭스와 크롬은 도큐먼트의 body 에 추가합니다.{{NoteEnd}}

+ +

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target (DOM element)
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)null
+ +

이벤트 위임

+ +

이 이벤트에 이벤트 위임을 적용하는 방법은 두가지가 있습니다 : 브라우저가 지원한다면 focusout 이벤트를 사용하거나,   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')}}

+ +

Browser compatibility

+ +
{{CompatibilityTable}}
+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatVersionUnknown}}{{CompatVersionUnknown}}[1]612.15.1
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.053{{CompatVersionUnknown}}{{CompatUnknown}}10.012.15.1
+
+ +

[1] Prior to Gecko 24 {{geckoRelease(24)}} the interface for this event was {{domxref("Event")}}, not {{domxref("FocusEvent")}}. See ({{bug(855741)}}).

+ + + + diff --git a/files/ko/web/api/elementcssinlinestyle/style/index.html b/files/ko/web/api/elementcssinlinestyle/style/index.html new file mode 100644 index 0000000000..5976dd66bc --- /dev/null +++ b/files/ko/web/api/elementcssinlinestyle/style/index.html @@ -0,0 +1,41 @@ +--- +title: element.style +slug: Web/API/HTMLElement/style +tags: + - API + - HTML DOM + - HTMLElement + - Property + - Reference + - Style +translation_of: Web/API/ElementCSSInlineStyle/style +--- +
{{ APIRef("HTML DOM") }}
+ +

HTMLElement.style 속성은 요소의 인라인 스타일에 접근하거나 설정할 때 사용할 수 있습니다. 접근자로서는 요소의 인라인 style 속성이 포함한 CSS 선언을 담은 {{domxref("CSSStyleDeclaration")}} 객체를 반환합니다

+ +

예제

+ +
// Set multiple styles in a single statement
+elt.style.cssText = "color: blue; border: 1px solid black";
+// Or
+elt.setAttribute("style", "color:red; border: 1px solid blue;");
+
+// Set specific style while leaving other inline style values untouched
+elt.style.color = "blue";
+ +

명세

+ +

DOM Level 2 Style: ElementCSSInlineStyle.style

+ +

CSSOM: ElementCSSInlineStyle

+ +

브라우저 호환성

+ +

{{Compat("api.HTMLElement.style")}}

+ +

같이 보기

+ + diff --git a/files/ko/web/api/event/createevent/index.html b/files/ko/web/api/event/createevent/index.html deleted file mode 100644 index 549a51bfdc..0000000000 --- a/files/ko/web/api/event/createevent/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Event.createEvent() -slug: Web/API/Event/createEvent -translation_of: Web/API/Document/createEvent -translation_of_original: Web/API/Event/createEvent ---- -

{{APIRef("DOM")}}

- -

새로운 event를 생성합니다, 새로 만들어진 event는 반드시 자신의 init() method를 호출함으로써 초기화되어야만 합니다.

- -

Syntax

- -
document.createEvent(type) 
- -
-
type
-
A string indicating the event type to create.
-
- -

이 method는 명시된 타입인 새로운 DOM {{ domxref("Event") }} 객체를 반환하며 이는 반드시 사용 전에 초기화되어야만 합니다.

- -

Example

- -
var newEvent = document.createEvent("UIEvents");
- -

Specification

- - diff --git "a/files/ko/web/api/fetch_api/fetch\354\235\230_\354\202\254\354\232\251\353\262\225/index.html" "b/files/ko/web/api/fetch_api/fetch\354\235\230_\354\202\254\354\232\251\353\262\225/index.html" deleted file mode 100644 index 403c340413..0000000000 --- "a/files/ko/web/api/fetch_api/fetch\354\235\230_\354\202\254\354\232\251\353\262\225/index.html" +++ /dev/null @@ -1,419 +0,0 @@ ---- -title: Using Fetch -slug: Web/API/Fetch_API/Fetch의_사용법 -translation_of: Web/API/Fetch_API/Using_Fetch ---- -

Fetch API를 이용하면 Request나 Response와 같은 HTTP의 파이프라인을 구성하는 요소를 조작하는것이 가능합니다. 또한 {{domxref("GlobalFetch.fetch","fetch()")}} 메서드를 이용하는 것으로 비동기 네트워크 통신을 알기쉽게 기술할 수 있습니다.

- -

이전에 이러한 기능을  {{domxref("XMLHttpRequest")}}에서 제공하고 있었습니다. Fetch는 이러한 API의 대체제로 {{domxref("ServiceWorker_API", "Service Workers")}}같은 기술로 간단히 이용하는것이 가능합니다. 또한 CORS나 HTTP확장같은  HTTP에 관련한 개념을 모아 정의하고 있습니다.

- -

Fetch의 기본 스펙은jQuery.ajax()와 기본적으로 두가지가 다르다는 사실에 유념해야합니다.

- - - -

기본적인 fetch는 누구라도 알기쉽고 간단하게 작성할 수 있습니다. 아래의 코드를 봐주시기 바랍니다.

- -
fetch('http://example.com/movies.json')
-  .then(function(response) {
-    return response.json();
-  })
-  .then(function(myJson) {
-    console.log(JSON.stringify(myJson));
-  });
- -

네트워크에서 JSON 파일을 가져 와서 콘솔에 인쇄합니다. 간단한 fetch() 사용 흐름은 인수 한개(가져올 자원의 경로)를 가져오고 응답을 포함하는 약속 ({{domxref ( "Response")}} 개체)을 반환하는 것입니다.

- -

이것은 단순한 HTTP Response이며, 실제 JSON이 아닙니다. response 객체로부터 사진을 가져오기 위해서는 {{domxref("Body.json","json()")}} 메서드를 사용할 필요가 있습니다. ({{domxref("Body")}}의 믹스인 (역주:php의 트레이드와 같은것입니다. )으로 정의되어, 이것은 {{domxref("Request")}} 객체와 {{domxref("Response")}} 객체의 쌍방에 구현되어 있습니다.

- -
-

노트: http Request와 http Response의 Body mixin은 Body 컨텐츠를 다른 mine 타입으로 사용하는 비슷한 메서드를 제공하고 있습니다.  상세한 내용은 {{anch("Body")}} 섹션을 참고해 주시기 바랍니다.

-
- -

Fetch Reqeust는 검색된 리소스로부터의 지시가 아닌 CSPconnect-src의 디렉티브(directive)에 의해 제어됩니다.

- -

리퀘스트의 옵션 적용

- -

fetch() 메서드에 두번째 파라미터를 적용하는것도 가능합니다. init 오브젝트는 다른 여러 세팅을 컨트롤 할 수 있게 해줍니다.

- -

모든 설정 가능한 옵션의 상세 설명은 {{domxref("GlobalFetch.fetch","fetch()")}}를 참고해주시기 바랍니다.

- -
// Example POST method implementation:
-
-postData('http://example.com/answer', {answer: 42})
-  .then(data => console.log(JSON.stringify(data))) // JSON-string from `response.json()` call
-  .catch(error => console.error(error));
-
-function postData(url = '', data = {}) {
-  // Default options are marked with *
-    return fetch(url, {
-        method: 'POST', // *GET, POST, PUT, DELETE, etc.
-        mode: 'cors', // no-cors, cors, *same-origin
-        cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
-        credentials: 'same-origin', // include, *same-origin, omit
-        headers: {
-            'Content-Type': 'application/json',
-            // 'Content-Type': 'application/x-www-form-urlencoded',
-        },
-        redirect: 'follow', // manual, *follow, error
-        referrer: 'no-referrer', // no-referrer, *client
-        body: JSON.stringify(data), // body data type must match "Content-Type" header
-    })
-    .then(response => response.json()); // parses JSON response into native JavaScript objects
-}
-
- -

자격 증명(credentials)이 포함된 Request 요청

- -

자격 증명이 포함된 인증서를 보내도록 하려면 fetch() 메서드에 credentials: 'include'를 추가하도록 합니다. 이것은 cross-origin 요청에서도 사용됩니다.

- -
fetch('https://example.com', {
-  credentials: 'include'
-})
- -

요청하려는 URL이 호출 스크립트와 동일한 origin을 가지고 있을때만 자격증명을 전송하려면 credentials: 'same-origin'를 추가해 주시기 바랍니다.

- -
// The calling script is on the origin 'https://example.com'
-
-fetch('https://example.com', {
-  credentials: 'same-origin'
-})
- -

브라우저의 보안을 유지하는것 대신 자격증명을 포함하지 않는것을 원한다면 credentials: 'omit'를 작성해 주시기 바랍니다.

- -
fetch('https://example.com', {
-  credentials: 'omit'
-})
-
- -

Uploading JSON data

- -

POST프로토콜로 JSON인코딩된 데이터를 보내기 위해 {{domxref("GlobalFetch.fetch","fetch()")}}를 사용합니다.

- -
var url = 'https://example.com/profile';
-var data = {username: 'example'};
-
-fetch(url, {
-  method: 'POST', // or 'PUT'
-  body: JSON.stringify(data), // data can be `string` or {object}!
-  headers:{
-    'Content-Type': 'application/json'
-  }
-}).then(res => res.json())
-.then(response => console.log('Success:', JSON.stringify(response)))
-.catch(error => console.error('Error:', error));
- -

Uploading a file

- -

<input type="file" /> input엘리먼트, {{domxref("FormData.FormData","FormData()")}}, {{domxref("WindowOrWorkerGlobalScope/fetch","fetch()")}}를 사용하여 파일을 업로드 할 수 있습니다.

- -
var formData = new FormData();
-var fileField = document.querySelector('input[type="file"]');
-
-formData.append('username', 'abc123');
-formData.append('avatar', fileField.files[0]);
-
-fetch('https://example.com/profile/avatar', {
-  method: 'PUT',
-  body: formData
-})
-.then(response => response.json())
-.catch(error => console.error('Error:', error))
-.then(response => console.log('Success:', JSON.stringify(response)));
- -

Uploading multiple files

- -

<input type="file" multiple /> input엘리먼트와{{domxref("FormData.FormData","FormData()")}}, {{domxref("GlobalFetch.fetch","fetch()")}}를 사용하여 파일 다중업로드를 할 수 있습니다.

- -
var formData = new FormData();
-var photos = document.querySelector('input[type="file"][multiple]');
-
-formData.append('title', 'My Vegas Vacation');
-for (var i = 0; i < photos.files.length; i++) {
-  formData.append('photos', photos.files[i]);
-}
-
-fetch('https://example.com/posts', {
-  method: 'POST',
-  body: formData
-})
-.then(response => response.json())
-.then(response => console.log('Success:', JSON.stringify(response)))
-.catch(error => console.error('Error:', error));
- -

문서 파일을 열단위로 처리하기

- -

응답하는 곳에서 읽는 덩어리들은 줄 단위로 깔끔하게 떨어지지 않으며 문자열이 아니라 Uint8Arrys(8비트 부호 없는 정수)입니다. 만약 텍스트 파일은 fetch하고 이것을 줄 단위로 처리하고자 한다면, 이런 복잡함을 다루는 것은 사용자에게 달려있습니다. 아래의 예시는 line iterator를 생성하여 처리하는 한가지 방법을 보여주고 있습니다. (간단하게 하기위해, 텍스트는 UTF-8이라고 가정하며,  fetch errors를 다루지 않는다고 합시다).

- -
async function* makeTextFileLineIterator(fileURL) {
-  const utf8Decoder = new TextDecoder("utf-8");
-  let response = await fetch(fileURL);
-  let reader = response.body.getReader();
-  let {value: chunk, done: readerDone} = await reader.read();
-  chunk = chunk ? utf8Decoder.decode(chunk) : "";
-
-  let re = /\n|\r|\r\n/gm;
-  let startIndex = 0;
-  let result;
-
-  for (;;) {
-    let result = re.exec(chunk);
-    if (!result) {
-      if (readerDone) {
-        break;
-      }
-      let remainder = chunk.substr(startIndex);
-      ({value: chunk, done: readerDone} = await reader.read());
-      chunk = remainder + (chunk ? utf8Decoder.decode(chunk) : "");
-      startIndex = re.lastIndex = 0;
-      continue;
-    }
-    yield chunk.substring(startIndex, result.index);
-    startIndex = re.lastIndex;
-  }
-  if (startIndex < chunk.length) {
-    // last line didn't end in a newline char
-    yield chunk.substr(startIndex);
-  }
-}
-
-for await (let line of makeTextFileLineIterator(urlOfFile)) {
-  processLine(line);
-}
- -

fetch의 성공 여부를 체크

- -

한가지 예를 들자면, 네트워크 error가 발생했을때 또는 CORS 가 서버단에서 잘못 설정되어있다면 {{domxref("GlobalFetch.fetch","fetch()")}} promise 객체는 {{jsxref("TypeError")}} 메시지와 함께 반려 할것입니다. 비록 이 현상은 보통 허가 이슈나 그와 비슷한 것을 의미할지라도, 404 는 네트워크 error를 구성하지는 않습니다.  성공적인 fetch() 를 체크하는 정확한 방법은 promise 객체가 해결되었는지를 체크하는 것을 포함합니다. 그리고 {{domxref("Response.ok")}} property 가 "true"의 값을 가지고 있는지 확인하는 것입니다. 코드는 아래와 같이 구현될겁니다:

- -
fetch('flowers.jpg').then(function(response) {
-  if(response.ok) {
-    return response.blob();
-  }
-  throw new Error('Network response was not ok.');
-}).then(function(myBlob) {
-  var objectURL = URL.createObjectURL(myBlob);
-  myImage.src = objectURL;
-}).catch(function(error) {
-  console.log('There has been a problem with your fetch operation: ', error.message);
-});
- -

request 객체를 fetch로 전달

- -

fetch()를 사용해 요청한 리소스의 경로를 전달하는것 대신{{domxref("Request.Request","Request()")}} 생성자를 사용해 Request 객체를 작성하여 fetch() 메서드를 인수로 전달하는것도 가능합니다.

- -
var myHeaders = new Headers();
-
-var myInit = { method: 'GET',
-               headers: myHeaders,
-               mode: 'cors',
-               cache: 'default' };
-
-var myRequest = new Request('flowers.jpg', myInit);
-
-fetch(myRequest).then(function(response) {
-  return response.blob();
-}).then(function(myBlob) {
-  var objectURL = URL.createObjectURL(myBlob);
-  myImage.src = objectURL;
-});
- -

fetch()메서드의 인수와 똑같은 인수를 Request()객체에 전달하여 적용하는것이 가능합니다. 또한 Request 객체의 클론을 생성하기 위해 이미 존재하는 Request 객체를 전달하는것도 가능합니다.

- -
var anotherRequest = new Request(myRequest,myInit);
- -

이것은 Request와 Resposne의 Body를 하나만 사용하고 있으므로 사용성이 높습니다.필요하면 init 객체를 변화시켜 Response나 Request를 재사용할 수 있도록 복사합니다. The copy must be made before the body is read, and reading the body in the copy will also mark it as read in the original request.

- -
-

노트: {{domxref("Request.clone","clone()")}} 메서드를 사용해 Request 객체의 클론을 생성할 수 있습니다. 다른 카피 메서드와 약간 다른 의미가 있습니다. 이전 요청의 body가 이미 읽어들여진 경우 전자는  실패하지만 clone()메서드는 실패하지 않습니다. 이 기능은 Response와 동일합니다.

-
- -

Headers

- -

{{domxref("Headers")}} 인터페이스에서  {{domxref("Headers.Headers","Headers()")}} 생성자를 사용해 헤더 객체를 생성할 수 있습니다. 헤더 객체는 Key와 Value로 이루어진 간단한 multi-map입니다.

- -
var content = "Hello World";
-var myHeaders = new Headers();
-myHeaders.append("Content-Type", "text/plain");
-myHeaders.append("Content-Length", content.length.toString());
-myHeaders.append("X-Custom-Header", "ProcessThisImmediately");
- -

똑같이 배열을 전달하거나 객체 리터럴을 생성자에 전달하는것으로 생성할 수 있습니다.

- -
myHeaders = new Headers({
-  "Content-Type": "text/plain",
-  "Content-Length": content.length.toString(),
-  "X-Custom-Header": "ProcessThisImmediately",
-});
- -

다음과 같은 코드로 헤더의 내용을 들여다 볼 수 있습니다.

- -
console.log(myHeaders.has("Content-Type")); // true
-console.log(myHeaders.has("Set-Cookie")); // false
-myHeaders.set("Content-Type", "text/html");
-myHeaders.append("X-Custom-Header", "AnotherValue");
-
-console.log(myHeaders.get("Content-Length")); // 11
-console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
-
-myHeaders.delete("X-Custom-Header");
-console.log(myHeaders.getAll("X-Custom-Header")); // [ ]
- -

이러한 몇몇개의 조작법은 {{domxref("ServiceWorker_API","ServiceWorkers")}}에서밖에 도움되지 않지만 헤더를 조작하기 위해서 보다 나은 API를 제공하고 있습니다.

- -

모든 Header 메서드는 유효한 HTTP 헤더가 전달되지 않았을 경우 TypeError을 반환합니다. immutable Guard(다음 섹션 참고)가 설정되어 있는 경우에도 TypeError를 반환합니다. TypeError를 반환하지 않고 실패하는 경우도 있습니다. 다음 예를 참고해주시기 바랍니다.

- -
var myResponse = Response.error();
-try {
-  myResponse.headers.set("Origin", "http://mybank.com");
-} catch(e) {
-  console.log("은행이 아니잖아요!!");
-}
- -

헤더의 좋은 사용법으로 처리하기 전에 컨텐츠 타입으로 올바른가의 여부를 판별하는 방법이 있습니다. 예를 들어,

- -
fetch(myRequest).then(function(response) {
-    var contentType = response.headers.get('content-type');
-    if(contentType && contentType.includes('application/json')) {
-      return response.json();
-    }
-    throw new TypeError("Oops, we haven't got JSON!");
-  })
-  .then(function(json) { /* process your JSON further */ })
-  .catch(function(error) { console.log(error); });
- -

가드

- -

헤더는 리퀘스트를 송신할 수 있으며 리스폰스를 수신할 수 있습니다. 어떤 정보를 수정할 수 있게 하기 위해, 혹은 수정하기 위해 여러 종류의 제어가 가능합니다. 헤더는 guard 프로퍼티는 이것을 가능하게 합니다. 가드는 Request나 Response에 포함되지 않지만  헤더 객체에서 조작 가능한 여러 메서드들의 사용 가능 여부에 영향을 미칩니다.

- -

가드의 설정값은 다음과 같습니다.

- - - -
-

메모: request에서 가드된 헤더의Content-Length 헤더는 추가나 변경할 수 없는 가능성이 있습니다.  마찬가지로 리스폰스 헤더에 Set-Cookie를 삽입하는것은 불가능합니다.ServiceWorker는 동기 Reponse를 추출하여 쿠키를 설정합니다.

-
- -

Response 객체

- -

위에서 본 바와 같이 {{domxref("Response")}} 인스턴스들은 fetch() promise가 resolve됬을때 반환됩니다.

- -

아래는 어떤 리스폰스 객체라도 공통으로 사용되는 리스폰스 프로퍼티입니다.

- - - -

Response 객체는 개발자의 손에 의해 동적으로 만드는것이 가능합니다. 이 방법은 {{domxref("ServiceWorker_API", "ServiceWorkers")}}내에서 활약할 때가 많습니다. 예를들어 Request를 획득했을 때  {{domxref("FetchEvent.respondWith","respondWith()")}}메서드에 의해 커스텀된 리스폰스를 반환하는 경우가 있습니다.

- -
var myBody = new Blob();
-
-addEventListener('fetch', function(event) {
-  event.respondWith(
-    new Response(myBody, {
-      headers: { "Content-Type" : "text/plain" }
-    })
-  );
-});
- -

{{domxref("Response.Response","Response()")}} 생성자는 파라미터로써 두개의 객체를 전달하는것이 가능합니다.첫번째는 Response Body, 두번째는 초기화 객체({{domxref("Request.Request","Request()")}}의 클론을 생성하는 방법과 비슷합니다.) 입니다.

- - - -
-

付記: 정적 메서드 {{domxref("Response.error","error()")}}는 단순한 에러 Response를 반환합니다. {{domxref("Response.redirect","redirect()")}} 메서드 또한 지정한 URL에 리다이렉트할 Response를 반환합니다. 이것들은 Service Workers에서만 사용되고 있습니다.

-
- -

Body

- -

Request, Response 둘다 Body를 가지고 있습니다. body는 아래에서 기술한 타입들 중 하나의 인스턴스입니다.

- - - -

{{domxref("Body")}} 믹스인은 {{domxref("Request")}}나{{domxref("Response")}}에 구현되어, 콘텐츠를 추출하기 위해 아래의 메서드가 정의되어 있습니다. 이러한 메서드들은 전부 최종적으로 요청으로 반환된 값을 내장하고 있는 promise를 반환합니다.

- - - -

이것들은 비 텍스트 데이터를 XHR보다 훨씬 간단하게 사용하는것을 도와줍니다.

- -

Request 바디는 body 파라미터를 전달하는 것으로 설정할 수 있습니다.

- -
var form = new FormData(document.getElementById('login-form'));
-fetch("/login", {
-  method: "POST",
-  body: form
-})
- -

Both request and response (and by extension the fetch() function), will try to intelligently determine the content type. A request will also automatically set a Content-Type header if none is set in the dictionary.

- -

Feature detection(특징 추출)

- -

Fetch API support는{{domxref("Headers")}}, {{domxref("Request")}}, {{domxref("Response")}} or {{domxref("GlobalFetch.fetch","fetch()")}} on the {{domxref("Window")}} or {{domxref("Worker")}}로 존재여부를 확인함으로써 추출할 수 있습니다. 예를 들어:

- -
if (window.fetch) {
-    // run my fetch request here
-} else {
-    // do something with XMLHttpRequest?
- -

Polyfill

- -

Fetch를 지원하지 않는 브라우저를 위해 미지원 브라우저를 위한 Fetch Polyfill이 지원되고 있습니다.

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Fetch')}}{{Spec2('Fetch')}}Initial definition
- -

Browser compatibility

- -

{{Compat("api.WindowOrWorkerGlobalScope.fetch")}}

- -

관련항목

- -
- - - -

{{DefaultAPISidebar("Fetch API")}} 

diff --git a/files/ko/web/api/fetch_api/using_fetch/index.html b/files/ko/web/api/fetch_api/using_fetch/index.html new file mode 100644 index 0000000000..403c340413 --- /dev/null +++ b/files/ko/web/api/fetch_api/using_fetch/index.html @@ -0,0 +1,419 @@ +--- +title: Using Fetch +slug: Web/API/Fetch_API/Fetch의_사용법 +translation_of: Web/API/Fetch_API/Using_Fetch +--- +

Fetch API를 이용하면 Request나 Response와 같은 HTTP의 파이프라인을 구성하는 요소를 조작하는것이 가능합니다. 또한 {{domxref("GlobalFetch.fetch","fetch()")}} 메서드를 이용하는 것으로 비동기 네트워크 통신을 알기쉽게 기술할 수 있습니다.

+ +

이전에 이러한 기능을  {{domxref("XMLHttpRequest")}}에서 제공하고 있었습니다. Fetch는 이러한 API의 대체제로 {{domxref("ServiceWorker_API", "Service Workers")}}같은 기술로 간단히 이용하는것이 가능합니다. 또한 CORS나 HTTP확장같은  HTTP에 관련한 개념을 모아 정의하고 있습니다.

+ +

Fetch의 기본 스펙은jQuery.ajax()와 기본적으로 두가지가 다르다는 사실에 유념해야합니다.

+ + + +

기본적인 fetch는 누구라도 알기쉽고 간단하게 작성할 수 있습니다. 아래의 코드를 봐주시기 바랍니다.

+ +
fetch('http://example.com/movies.json')
+  .then(function(response) {
+    return response.json();
+  })
+  .then(function(myJson) {
+    console.log(JSON.stringify(myJson));
+  });
+ +

네트워크에서 JSON 파일을 가져 와서 콘솔에 인쇄합니다. 간단한 fetch() 사용 흐름은 인수 한개(가져올 자원의 경로)를 가져오고 응답을 포함하는 약속 ({{domxref ( "Response")}} 개체)을 반환하는 것입니다.

+ +

이것은 단순한 HTTP Response이며, 실제 JSON이 아닙니다. response 객체로부터 사진을 가져오기 위해서는 {{domxref("Body.json","json()")}} 메서드를 사용할 필요가 있습니다. ({{domxref("Body")}}의 믹스인 (역주:php의 트레이드와 같은것입니다. )으로 정의되어, 이것은 {{domxref("Request")}} 객체와 {{domxref("Response")}} 객체의 쌍방에 구현되어 있습니다.

+ +
+

노트: http Request와 http Response의 Body mixin은 Body 컨텐츠를 다른 mine 타입으로 사용하는 비슷한 메서드를 제공하고 있습니다.  상세한 내용은 {{anch("Body")}} 섹션을 참고해 주시기 바랍니다.

+
+ +

Fetch Reqeust는 검색된 리소스로부터의 지시가 아닌 CSPconnect-src의 디렉티브(directive)에 의해 제어됩니다.

+ +

리퀘스트의 옵션 적용

+ +

fetch() 메서드에 두번째 파라미터를 적용하는것도 가능합니다. init 오브젝트는 다른 여러 세팅을 컨트롤 할 수 있게 해줍니다.

+ +

모든 설정 가능한 옵션의 상세 설명은 {{domxref("GlobalFetch.fetch","fetch()")}}를 참고해주시기 바랍니다.

+ +
// Example POST method implementation:
+
+postData('http://example.com/answer', {answer: 42})
+  .then(data => console.log(JSON.stringify(data))) // JSON-string from `response.json()` call
+  .catch(error => console.error(error));
+
+function postData(url = '', data = {}) {
+  // Default options are marked with *
+    return fetch(url, {
+        method: 'POST', // *GET, POST, PUT, DELETE, etc.
+        mode: 'cors', // no-cors, cors, *same-origin
+        cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
+        credentials: 'same-origin', // include, *same-origin, omit
+        headers: {
+            'Content-Type': 'application/json',
+            // 'Content-Type': 'application/x-www-form-urlencoded',
+        },
+        redirect: 'follow', // manual, *follow, error
+        referrer: 'no-referrer', // no-referrer, *client
+        body: JSON.stringify(data), // body data type must match "Content-Type" header
+    })
+    .then(response => response.json()); // parses JSON response into native JavaScript objects
+}
+
+ +

자격 증명(credentials)이 포함된 Request 요청

+ +

자격 증명이 포함된 인증서를 보내도록 하려면 fetch() 메서드에 credentials: 'include'를 추가하도록 합니다. 이것은 cross-origin 요청에서도 사용됩니다.

+ +
fetch('https://example.com', {
+  credentials: 'include'
+})
+ +

요청하려는 URL이 호출 스크립트와 동일한 origin을 가지고 있을때만 자격증명을 전송하려면 credentials: 'same-origin'를 추가해 주시기 바랍니다.

+ +
// The calling script is on the origin 'https://example.com'
+
+fetch('https://example.com', {
+  credentials: 'same-origin'
+})
+ +

브라우저의 보안을 유지하는것 대신 자격증명을 포함하지 않는것을 원한다면 credentials: 'omit'를 작성해 주시기 바랍니다.

+ +
fetch('https://example.com', {
+  credentials: 'omit'
+})
+
+ +

Uploading JSON data

+ +

POST프로토콜로 JSON인코딩된 데이터를 보내기 위해 {{domxref("GlobalFetch.fetch","fetch()")}}를 사용합니다.

+ +
var url = 'https://example.com/profile';
+var data = {username: 'example'};
+
+fetch(url, {
+  method: 'POST', // or 'PUT'
+  body: JSON.stringify(data), // data can be `string` or {object}!
+  headers:{
+    'Content-Type': 'application/json'
+  }
+}).then(res => res.json())
+.then(response => console.log('Success:', JSON.stringify(response)))
+.catch(error => console.error('Error:', error));
+ +

Uploading a file

+ +

<input type="file" /> input엘리먼트, {{domxref("FormData.FormData","FormData()")}}, {{domxref("WindowOrWorkerGlobalScope/fetch","fetch()")}}를 사용하여 파일을 업로드 할 수 있습니다.

+ +
var formData = new FormData();
+var fileField = document.querySelector('input[type="file"]');
+
+formData.append('username', 'abc123');
+formData.append('avatar', fileField.files[0]);
+
+fetch('https://example.com/profile/avatar', {
+  method: 'PUT',
+  body: formData
+})
+.then(response => response.json())
+.catch(error => console.error('Error:', error))
+.then(response => console.log('Success:', JSON.stringify(response)));
+ +

Uploading multiple files

+ +

<input type="file" multiple /> input엘리먼트와{{domxref("FormData.FormData","FormData()")}}, {{domxref("GlobalFetch.fetch","fetch()")}}를 사용하여 파일 다중업로드를 할 수 있습니다.

+ +
var formData = new FormData();
+var photos = document.querySelector('input[type="file"][multiple]');
+
+formData.append('title', 'My Vegas Vacation');
+for (var i = 0; i < photos.files.length; i++) {
+  formData.append('photos', photos.files[i]);
+}
+
+fetch('https://example.com/posts', {
+  method: 'POST',
+  body: formData
+})
+.then(response => response.json())
+.then(response => console.log('Success:', JSON.stringify(response)))
+.catch(error => console.error('Error:', error));
+ +

문서 파일을 열단위로 처리하기

+ +

응답하는 곳에서 읽는 덩어리들은 줄 단위로 깔끔하게 떨어지지 않으며 문자열이 아니라 Uint8Arrys(8비트 부호 없는 정수)입니다. 만약 텍스트 파일은 fetch하고 이것을 줄 단위로 처리하고자 한다면, 이런 복잡함을 다루는 것은 사용자에게 달려있습니다. 아래의 예시는 line iterator를 생성하여 처리하는 한가지 방법을 보여주고 있습니다. (간단하게 하기위해, 텍스트는 UTF-8이라고 가정하며,  fetch errors를 다루지 않는다고 합시다).

+ +
async function* makeTextFileLineIterator(fileURL) {
+  const utf8Decoder = new TextDecoder("utf-8");
+  let response = await fetch(fileURL);
+  let reader = response.body.getReader();
+  let {value: chunk, done: readerDone} = await reader.read();
+  chunk = chunk ? utf8Decoder.decode(chunk) : "";
+
+  let re = /\n|\r|\r\n/gm;
+  let startIndex = 0;
+  let result;
+
+  for (;;) {
+    let result = re.exec(chunk);
+    if (!result) {
+      if (readerDone) {
+        break;
+      }
+      let remainder = chunk.substr(startIndex);
+      ({value: chunk, done: readerDone} = await reader.read());
+      chunk = remainder + (chunk ? utf8Decoder.decode(chunk) : "");
+      startIndex = re.lastIndex = 0;
+      continue;
+    }
+    yield chunk.substring(startIndex, result.index);
+    startIndex = re.lastIndex;
+  }
+  if (startIndex < chunk.length) {
+    // last line didn't end in a newline char
+    yield chunk.substr(startIndex);
+  }
+}
+
+for await (let line of makeTextFileLineIterator(urlOfFile)) {
+  processLine(line);
+}
+ +

fetch의 성공 여부를 체크

+ +

한가지 예를 들자면, 네트워크 error가 발생했을때 또는 CORS 가 서버단에서 잘못 설정되어있다면 {{domxref("GlobalFetch.fetch","fetch()")}} promise 객체는 {{jsxref("TypeError")}} 메시지와 함께 반려 할것입니다. 비록 이 현상은 보통 허가 이슈나 그와 비슷한 것을 의미할지라도, 404 는 네트워크 error를 구성하지는 않습니다.  성공적인 fetch() 를 체크하는 정확한 방법은 promise 객체가 해결되었는지를 체크하는 것을 포함합니다. 그리고 {{domxref("Response.ok")}} property 가 "true"의 값을 가지고 있는지 확인하는 것입니다. 코드는 아래와 같이 구현될겁니다:

+ +
fetch('flowers.jpg').then(function(response) {
+  if(response.ok) {
+    return response.blob();
+  }
+  throw new Error('Network response was not ok.');
+}).then(function(myBlob) {
+  var objectURL = URL.createObjectURL(myBlob);
+  myImage.src = objectURL;
+}).catch(function(error) {
+  console.log('There has been a problem with your fetch operation: ', error.message);
+});
+ +

request 객체를 fetch로 전달

+ +

fetch()를 사용해 요청한 리소스의 경로를 전달하는것 대신{{domxref("Request.Request","Request()")}} 생성자를 사용해 Request 객체를 작성하여 fetch() 메서드를 인수로 전달하는것도 가능합니다.

+ +
var myHeaders = new Headers();
+
+var myInit = { method: 'GET',
+               headers: myHeaders,
+               mode: 'cors',
+               cache: 'default' };
+
+var myRequest = new Request('flowers.jpg', myInit);
+
+fetch(myRequest).then(function(response) {
+  return response.blob();
+}).then(function(myBlob) {
+  var objectURL = URL.createObjectURL(myBlob);
+  myImage.src = objectURL;
+});
+ +

fetch()메서드의 인수와 똑같은 인수를 Request()객체에 전달하여 적용하는것이 가능합니다. 또한 Request 객체의 클론을 생성하기 위해 이미 존재하는 Request 객체를 전달하는것도 가능합니다.

+ +
var anotherRequest = new Request(myRequest,myInit);
+ +

이것은 Request와 Resposne의 Body를 하나만 사용하고 있으므로 사용성이 높습니다.필요하면 init 객체를 변화시켜 Response나 Request를 재사용할 수 있도록 복사합니다. The copy must be made before the body is read, and reading the body in the copy will also mark it as read in the original request.

+ +
+

노트: {{domxref("Request.clone","clone()")}} 메서드를 사용해 Request 객체의 클론을 생성할 수 있습니다. 다른 카피 메서드와 약간 다른 의미가 있습니다. 이전 요청의 body가 이미 읽어들여진 경우 전자는  실패하지만 clone()메서드는 실패하지 않습니다. 이 기능은 Response와 동일합니다.

+
+ +

Headers

+ +

{{domxref("Headers")}} 인터페이스에서  {{domxref("Headers.Headers","Headers()")}} 생성자를 사용해 헤더 객체를 생성할 수 있습니다. 헤더 객체는 Key와 Value로 이루어진 간단한 multi-map입니다.

+ +
var content = "Hello World";
+var myHeaders = new Headers();
+myHeaders.append("Content-Type", "text/plain");
+myHeaders.append("Content-Length", content.length.toString());
+myHeaders.append("X-Custom-Header", "ProcessThisImmediately");
+ +

똑같이 배열을 전달하거나 객체 리터럴을 생성자에 전달하는것으로 생성할 수 있습니다.

+ +
myHeaders = new Headers({
+  "Content-Type": "text/plain",
+  "Content-Length": content.length.toString(),
+  "X-Custom-Header": "ProcessThisImmediately",
+});
+ +

다음과 같은 코드로 헤더의 내용을 들여다 볼 수 있습니다.

+ +
console.log(myHeaders.has("Content-Type")); // true
+console.log(myHeaders.has("Set-Cookie")); // false
+myHeaders.set("Content-Type", "text/html");
+myHeaders.append("X-Custom-Header", "AnotherValue");
+
+console.log(myHeaders.get("Content-Length")); // 11
+console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]
+
+myHeaders.delete("X-Custom-Header");
+console.log(myHeaders.getAll("X-Custom-Header")); // [ ]
+ +

이러한 몇몇개의 조작법은 {{domxref("ServiceWorker_API","ServiceWorkers")}}에서밖에 도움되지 않지만 헤더를 조작하기 위해서 보다 나은 API를 제공하고 있습니다.

+ +

모든 Header 메서드는 유효한 HTTP 헤더가 전달되지 않았을 경우 TypeError을 반환합니다. immutable Guard(다음 섹션 참고)가 설정되어 있는 경우에도 TypeError를 반환합니다. TypeError를 반환하지 않고 실패하는 경우도 있습니다. 다음 예를 참고해주시기 바랍니다.

+ +
var myResponse = Response.error();
+try {
+  myResponse.headers.set("Origin", "http://mybank.com");
+} catch(e) {
+  console.log("은행이 아니잖아요!!");
+}
+ +

헤더의 좋은 사용법으로 처리하기 전에 컨텐츠 타입으로 올바른가의 여부를 판별하는 방법이 있습니다. 예를 들어,

+ +
fetch(myRequest).then(function(response) {
+    var contentType = response.headers.get('content-type');
+    if(contentType && contentType.includes('application/json')) {
+      return response.json();
+    }
+    throw new TypeError("Oops, we haven't got JSON!");
+  })
+  .then(function(json) { /* process your JSON further */ })
+  .catch(function(error) { console.log(error); });
+ +

가드

+ +

헤더는 리퀘스트를 송신할 수 있으며 리스폰스를 수신할 수 있습니다. 어떤 정보를 수정할 수 있게 하기 위해, 혹은 수정하기 위해 여러 종류의 제어가 가능합니다. 헤더는 guard 프로퍼티는 이것을 가능하게 합니다. 가드는 Request나 Response에 포함되지 않지만  헤더 객체에서 조작 가능한 여러 메서드들의 사용 가능 여부에 영향을 미칩니다.

+ +

가드의 설정값은 다음과 같습니다.

+ + + +
+

메모: request에서 가드된 헤더의Content-Length 헤더는 추가나 변경할 수 없는 가능성이 있습니다.  마찬가지로 리스폰스 헤더에 Set-Cookie를 삽입하는것은 불가능합니다.ServiceWorker는 동기 Reponse를 추출하여 쿠키를 설정합니다.

+
+ +

Response 객체

+ +

위에서 본 바와 같이 {{domxref("Response")}} 인스턴스들은 fetch() promise가 resolve됬을때 반환됩니다.

+ +

아래는 어떤 리스폰스 객체라도 공통으로 사용되는 리스폰스 프로퍼티입니다.

+ + + +

Response 객체는 개발자의 손에 의해 동적으로 만드는것이 가능합니다. 이 방법은 {{domxref("ServiceWorker_API", "ServiceWorkers")}}내에서 활약할 때가 많습니다. 예를들어 Request를 획득했을 때  {{domxref("FetchEvent.respondWith","respondWith()")}}메서드에 의해 커스텀된 리스폰스를 반환하는 경우가 있습니다.

+ +
var myBody = new Blob();
+
+addEventListener('fetch', function(event) {
+  event.respondWith(
+    new Response(myBody, {
+      headers: { "Content-Type" : "text/plain" }
+    })
+  );
+});
+ +

{{domxref("Response.Response","Response()")}} 생성자는 파라미터로써 두개의 객체를 전달하는것이 가능합니다.첫번째는 Response Body, 두번째는 초기화 객체({{domxref("Request.Request","Request()")}}의 클론을 생성하는 방법과 비슷합니다.) 입니다.

+ + + +
+

付記: 정적 메서드 {{domxref("Response.error","error()")}}는 단순한 에러 Response를 반환합니다. {{domxref("Response.redirect","redirect()")}} 메서드 또한 지정한 URL에 리다이렉트할 Response를 반환합니다. 이것들은 Service Workers에서만 사용되고 있습니다.

+
+ +

Body

+ +

Request, Response 둘다 Body를 가지고 있습니다. body는 아래에서 기술한 타입들 중 하나의 인스턴스입니다.

+ + + +

{{domxref("Body")}} 믹스인은 {{domxref("Request")}}나{{domxref("Response")}}에 구현되어, 콘텐츠를 추출하기 위해 아래의 메서드가 정의되어 있습니다. 이러한 메서드들은 전부 최종적으로 요청으로 반환된 값을 내장하고 있는 promise를 반환합니다.

+ + + +

이것들은 비 텍스트 데이터를 XHR보다 훨씬 간단하게 사용하는것을 도와줍니다.

+ +

Request 바디는 body 파라미터를 전달하는 것으로 설정할 수 있습니다.

+ +
var form = new FormData(document.getElementById('login-form'));
+fetch("/login", {
+  method: "POST",
+  body: form
+})
+ +

Both request and response (and by extension the fetch() function), will try to intelligently determine the content type. A request will also automatically set a Content-Type header if none is set in the dictionary.

+ +

Feature detection(특징 추출)

+ +

Fetch API support는{{domxref("Headers")}}, {{domxref("Request")}}, {{domxref("Response")}} or {{domxref("GlobalFetch.fetch","fetch()")}} on the {{domxref("Window")}} or {{domxref("Worker")}}로 존재여부를 확인함으로써 추출할 수 있습니다. 예를 들어:

+ +
if (window.fetch) {
+    // run my fetch request here
+} else {
+    // do something with XMLHttpRequest?
+ +

Polyfill

+ +

Fetch를 지원하지 않는 브라우저를 위해 미지원 브라우저를 위한 Fetch Polyfill이 지원되고 있습니다.

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Fetch')}}{{Spec2('Fetch')}}Initial definition
+ +

Browser compatibility

+ +

{{Compat("api.WindowOrWorkerGlobalScope.fetch")}}

+ +

관련항목

+ +
+ + + +

{{DefaultAPISidebar("Fetch API")}} 

diff --git a/files/ko/web/api/fullscreen_api/index.html b/files/ko/web/api/fullscreen_api/index.html new file mode 100644 index 0000000000..d7f561a95c --- /dev/null +++ b/files/ko/web/api/fullscreen_api/index.html @@ -0,0 +1,198 @@ +--- +title: Using fullscreen mode +slug: Web/Guide/DOM/Using_full_screen_mode +translation_of: Web/API/Fullscreen_API +--- +
{{DefaultAPISidebar("Fullscreen API")}}
+ +

Fullscreen API 는 특정 요소{{DOMxRef("Element")}}(와 해당 자손들을)를 full-screen mode로 표시하고, 더 이상 필요하지 않으면 full-screen mode를 종료하는 메서드를 추가합니다. 이렇게 하면 사용자의 전체 화면을 사용하여, 온라인 게임과 같은 원하는 내용을 표시할 수 있습니다. full-screen mode가 종료될 때까지 화면에서 브라우저의 모든 유저 인터페이스 요소와 기타 응용 프로그램을 제거할 수 있습니다.

+ +

API 사용 방법에 대한 자세한 내용은 Guide to the Fullscreen API 문서를 참조하세요.

+ +
+

주의: 이 API에 대한 지원은 여러 브라우저에서 이루어지며, 다양한 업체의 접두사(prefix)가 필요하거나, 최신 사양을 구현하지 않는 경우가 많습니다. 이 API 지원에 대한 자세한 내용은 아래에 있는 {{anch("Browser compatibility")}} 섹션을 참조하세요. Fullscreen API를 지원하지 않는 업체의 경우, Fscreen 과 같은 라이브러리를 사용할 수 있습니다.

+
+ +

Interfaces

+ +

Fullscreen API 에는 자체 인터페이스가 없습니다. 대신에, full-screen 기능을 제공하는데 필요한 메서드, 속성(property), 이벤트 핸들러를 추가하기 위해, 다음 섹션에 나열된 것과 같은 몇 가지 다른 인터페이스를 추가합니다.

+ +

Methods

+ +

Fullscreen API 는 {{DOMxRef("Document")}}, {{DOMxRef("Element")}} 인터페이스에 메서드를 추가하여 full-screen mode를 설정하거나 해제할 수 있습니다.

+ +

Methods on the Document interface

+ +
+
{{DOMxRef("Document.exitFullscreen()")}}
+
{{Glossary("user agent")}} 가 full-screen mode에서 창 모드로 다시 전환되도록 요청합니다. full-screen mode가 완전히 종료되면 {{jsxref("Promise")}} resolved 를 반환합니다.
+
+ +

Methods on the Element interface

+ +
+
{{DOMxRef("Element.requestFullscreen()")}}
+
유저 에이전트가 지정한 요소(그리고 그 자손들까지)를 full-screen mode로 설정하고, 브라우저의 모든 UI 요소와 다른 모든 애플리케이션을 화면에서 제거하도록 요구합니다. full-screen mode가 활성화되면 {{jsxref("Promise")}} resolved를 반환합니다.
+
+ +

Properties

+ +

{{DOMxRef("Document")}} 인터페이스는 full-screen mode가 지원되고 사용 가능한지, full-screen mode가 현재 활성화 되어있는지, 어떤 요소가 스크린을 사용하고 있는지 확인하는데 사용할 수 있는 속성(property)을 제공합니다.

+ +
+
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
+
fullscreenElement 속성은 DOM(혹은 shadow DOM)에서 현재 full-screen mode로 표시되는 요소{{DOMxRef("Element")}}를 알려줍니다. 이것이 null인 경우, document는 full-screen mode가 아닙니다.
+
{{DOMxRef("Document.fullscreenEnabled")}}
+
fullscreenEnabled 속성(property)은 full-screen mode를 사용할 수 있는지 여부를 알려줍니다. 이유가 어떻든(예를들어, "fullscreen" 기능이 허락되지 않거나, full-screen mode가 지원되지 않는 경우) full-screen mode를 사용할 수 없으면 false 입니다.
+
+ +

Event handlers

+ +

Fullscreen API는 full-screen mode를 켜고 끌 때 혹은, full-screen mode와 window mode간에 변경하는 과정에서 오류가 발생하는 것을 감지하는데 사용할 수 있는 두 가지 이벤트를 정의합니다. 이러한 이벤트에 대한 이벤트 핸들러는 {{DOMxRef("Document")}} 와{{DOMxRef("Element")}} 인터페이스 에서 사용할 수 있습니다.

+ +
+

주의: 이러한 이벤트 핸들러 속성(property)은 HTML 컨텐트 속성(attribute)으로 사용할 수 없습니다. 즉, HTML 컨텐트에서 {{Event("fullscreenchange")}} 및 {{Event("fullscreenerror")}} 이벤트를 지정할 수 없습니다. 자바스크립트 코드로 추가해야만 합니다.

+
+ +

Event handlers on documents

+ +
+
{{DOMxRef("Document.onfullscreenchange")}}
+
문서(document)가 full-screen mode로 전환되거나 full-screen mode를 종료할 때 {{DOMxRef("Document")}}로 보내지는 {{Event("fullscreenchange")}} 이벤트에 대한 이벤트 핸들러 입니다. 이 핸들러는 오직 전체 문서가 full-screen mode로 표시될 때만 호출됩니다.
+
{{DOMxRef("Document.onfullscreenerror")}}
+
전체 문서에 대해 full-screen mode를 사용하거나, 사용하지 않도록 설정하는 동안 오류가 발생하면, {{DOMxRef("Document")}}로 보내지는 {{Event("fullscreenerror")}} 이벤트의 이벤트 핸들러입니다.
+
+ +

Event handlers on elements

+ +
+
{{DOMxRef("Element.onfullscreenchange")}}
+
{{Event("fullscreenchange")}} 이벤트가 요소(element)로 전송되면, 요소가 full-screen mode로 배치되거나 제거되었음을 나타내는 이벤트 핸들러입니다.
+
{{DOMxRef("Element.onfullscreenerror")}}
+
full-screen mode 를 사용하거나, 사용하지 않도록 설정하는 동안 오류가 발생하면 요소로 보내지는 {{Event("fullscreenerror")}} 이벤트의 이벤트 핸들러입니다.
+
+ +

Obsolete properties

+ +
+
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}
+
문서에 현재 full-screen mode로 표시되는 요소가 있는 경우 true, 그렇지 않으면 false의 Boolean 값입니다. +
주의: 대신에 {{DOMxRef("Document")}} 나 {{DOMxRef("ShadowRoot")}} 에서 {{DOMxRef("Document.fullscreenElement", "fullscreenElement")}} 속성(property)을 사용하세요. 그것이 null이 아닌 경우 {{DOMxRef("Element")}}가 full-screen mode로 표시됩니다.
+
+
+ +

Events

+ +

Fullscreen API는 full-screen mode를 켜고 끌 때 혹은, full-screen mode와 window mode간에 변경하는 과정에서 오류가 발생하는 것을 감지하는데 사용할 수 있는 두 가지 이벤트를 정의합니다.

+ +
+
{{Event("fullscreenchange")}}
+
full-screen mode를 사용하거나, 사용하지 않도록 전환할 때 {{DOMxRef("Document")}} 혹은{{DOMxRef("Element")}} 로 보냅니다.
+
{{Event("fullscreenerror")}}
+
full-screen mode를 사용하거나, 사용하지 않도록 전환하려고 시도하는 중에 오류가 발생하면 Document 또는 Element 로 보냅니다.
+
+ +

Dictionaries

+ +
+
{{DOMxRef("FullscreenOptions")}}
+
{{DOMxRef("Element.requestFullscreen", "requestFullscreen()")}}을 호출할 때 지정할 수 있는 옵션 설정을 제공합니다.
+
+ +

Controlling access

+ +

Feature Policy을 사용하여 full-screen mode의 유효성을 제어할 수 있습니다. full-screen mode는 "fullscreen"으로 식별되고, 기본 허용 목록 값은 "self" 입니다. 이는 최상위(top-level) 문서 컨텍스트에서 full-screen mode가 허용된다는 것을 의미하며, 최상위(top-most) 문서와 같은 출처에서 로드 된 중첩 된 컨텍스트에도 적용됩니다.

+ +

기능 정책을 사용하여 API에 대한 액세스를 제어하는 자세한 내용은 Using Feature Policy을 참조하세요.

+ +

Usage notes

+ +

사용자는 ESC (혹은 F11) 키를 누르기만하면 사이트 또는 앱이 프로그래밍 방식으로 기다리는 대신에, full-screen mode를 종료하도록 선택할 수 있습니다. 유저 인터페이스의 어딘가에 사용자에게 이 옵션을 사용할 수 있음을 알리는, 적절한 유저 인터페이스 요소를 제공해야 합니다.

+ +
+

주의: 다른 페이지로 이동하거나, 탭을 변경하거나, 응용 프로그램 전환기(또는 Alt-Tab)를 사용하여, 다른 응용 프로그램으로 전환하면 마찬가지로 full-screen mode가 종료됩니다.

+
+ +

Example

+ +

이 예제에서는 비디오가 웹 페이지에 표시됩니다. Return 또는 Enter 키를 누르면, 사용자가 비디오의 창과 full-screen 표시를 전환할 수 있습니다.

+ +

View Live Examples

+ +

Watching for the Enter key

+ +

페이지가 로드되면, 이 코드가 실행되어 Enter 키 를 주시하는 이벤트 리스너를 설정합니다.

+ +
document.addEventListener("keypress", function(e) {
+  if (e.keyCode === 13) {
+    toggleFullScreen();
+  }
+}, false);
+
+ +

Toggling full-screen mode

+ +

이 코드는 사용자가 Enter 키를 누를 때, 위의 이벤트 핸들러에 의해 호출됩니다.

+ +
function toggleFullScreen() {
+  if (!document.fullscreenElement) {
+    document.documentElement.requestFullscreen();
+  } else {
+    if (document.exitFullscreen) {
+      document.exitFullscreen();
+    }
+  }
+}
+ +

먼저 {{DOMxRef("Document", "document")}}의 fullscreenElement 속성(attribute)값을 살펴보겠습니다. 실제 배포 시에는 이 시점에 접두어가 붙은 버전(예를들어, mozFullscreenElement, msFullscreenElement, webkitFullscreenElement)을 확인해야 합니다. 값이 null인 경우, 문서는 현재 window mode에 있으므로, full-screen mode로 전환해야 합니다. 그렇지 않으면, 이 요소는 지금 full-screen mode 상태입니다. full-screen mode로 전환하는 작업은, {{HTMLElement("video")}}요소에서 {{DOMxRef("Element.requestFullscreen()")}}을 호출하여 수행합니다.

+ +

full-screen mode가 이미 활성화 된 경우(fullscreenElement 가 null이 아닌 경우), document에서 {{DOMxRef("Document.exitFullscreen", "exitFullscreen()")}}을 호출하여 full-screen mode를 종료합니다.

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}Initial version.
+ +

Browser compatibility

+ +

Document.fullscreen

+ +
+ + +

{{Compat("api.Document.fullscreen")}}

+ +

Document.fullscreenEnabled

+ +
+ + +

{{Compat("api.Document.fullscreenEnabled")}}

+
+
+ +

See also

+ + diff --git a/files/ko/web/api/geolocation_api/using_the_geolocation_api/index.html b/files/ko/web/api/geolocation_api/using_the_geolocation_api/index.html new file mode 100644 index 0000000000..e5f9913376 --- /dev/null +++ b/files/ko/web/api/geolocation_api/using_the_geolocation_api/index.html @@ -0,0 +1,165 @@ +--- +title: Geolocation API 사용하기 +slug: WebAPI/Using_geolocation +tags: + - Geolocation API + - Guide + - Intermediate +translation_of: Web/API/Geolocation_API/Using_the_Geolocation_API +--- +

{{securecontext_header}}{{APIRef("Geolocation API")}}
+ Geolocation API는 사용자의 현재 위치를 가져오는 API로, 지도에 사용자 위치를 표시하는 등 다양한 용도로 사용할 수 있습니다. 이 안내서는 Geolocation API의 기초적 사용법을 설명합니다.

+ +

geolocation 객체

+ +

Geolocation API는 {{domxref("navigator.geolocation")}} 객체를 통해 사용할 수 있습니다.

+ +

geolocation 객체가 존재하는 경우 위치 정보 서비스를 지원하는 것입니다. 존재 여부는 다음과 같이 알아낼 수 있습니다.

+ +
if('geolocation' in navigator) {
+  /* 위치정보 사용 가능 */
+} else {
+  /* 위치정보 사용 불가능 */
+}
+
+ +

현재 위치 가져오기

+ +

{{domxref("Geolocation.getCurrentPosition()","getCurrentPosition()")}} 메서드를 호출해서 사용자의 현재 위치를 얻을 수 있습니다. getCurrentPosition()은 사용자의 위치를 탐지하는 비동기 요청을 초기화하고, 위치 관련 하드웨어에 최신 정보를 요청합니다. 위치를 알아낸 후에는 지정한 콜백 함수를 호출합니다. 선택적으로, 이 과정 중 오류가 발생하면 호출할 오류 콜백을 두 번째 매개변수로 지정할 수도 있습니다. 세 번째 매개변수 역시 선택 항목이며, 위치 정보의 최대 수명, 요청의 최대 대기시간, 고정밀 위치정보 여부 등의 옵션을 담은 객체입니다.

+ +
+

참고: {{domxref("Geolocation.getCurrentPosition", "getCurrentPosition()")}}의 기본값에서는 최대한 빠르게 낮은 정밀도의 응답을 반환합니다. 정확하지 않더라도 빠른 정보가 필요한 상황에서 유용합니다. 예를 들어, GPS 기능을 가진 장비는 보정 과정에 수 분이 걸릴 수도 있으므로 IP 위치와 WiFi 등 정확하지 않은 출처에 기반한 위치 정보를 반환할 수 있습니다.

+
+ +
navigator.geolocation.getCurrentPosition((position) => {
+  doSomething(position.coords.latitude, position.coords.longitude);
+});
+ +

위의 예제는 사용자 위치가 확인되면 doSomething() 함수를 실행합니다.

+ +

현재 위치 추적하기

+ +

장치가 이동했거나 더 정확한 정보를 사용할 수 있어서 위치 정보가 바뀐 경우 호출할 콜백 함수를 {{domxref("Geolocation.watchPosition","watchPosition()")}} 메서드로 설정할 수 있으며, {{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}}과 같은 매개변수를 받습니다. 콜백은 계속해서 호출될 수 있으므로, 브라우저가 사용자의 이동 시, 또는 고정밀 위치 기술을 사용할 수 있는 시점에 새로운 위치 정보를 제공할 수 있습니다. getCurrentPosition()과 마찬가지로 선택 사항인 오류 콜백 역시 여러 번 호출할 수 있습니다.

+ +
+

참고: {{domxref("Geolocation.getCurrentPosition", "getCurrentPosition()")}}을 먼저 호출하지 않고도 {{domxref("Geolocation.watchPosition", "watchPosition()")}}을 사용할 수 있습니다.

+
+ +
const watchID = navigator.geolocation.watchPosition((position) => {
+  doSomething(position.coords.latitude, position.coords.longitude);
+});
+ +

{{domxref("Geolocation.watchPosition","watchPosition()")}} 메서드는 위치 추적 요청의 고유 식별자를 나타내는 숫자값을 반환합니다. 해당 식별자를 {{domxref("Geolocation.clearWatch","clearWatch()")}} 메서드에 전달해서 추적을 종료할 수 있습니다.

+ +
navigator.geolocation.clearWatch(watchID);
+
+ +

응답 미세 조정

+ +

{{domxref("Geolocation.getCurrentPosition","getCurrentPosition()")}}과 {{domxref("Geolocation.watchPosition","watchPosition()")}} 둘 다 성공 콜백, 실패 콜백 외에도 PositionOptions 객체를 받을 수 있습니다.

+ +

PositionsOptions 객체를 사용하면 고정밀도 활성화 여부, 위치 정보의 캐시 수명(수명이 끝나기 전까지는 이전에 반환한 위치 정보를 저장해뒀다가, 같은 요청을 또 받을 경우 그대로 반환합니다), 그리고 위치 정보 요청의 응답을 대기할 최대 대기시간을 지정할 수 있습니다.

+ +

옵션 객체를 사용한 {{domxref("Geolocation.watchPosition","watchPosition")}}의 호출 예시는 다음과 같습니다.

+ +
function success(position) {
+  doSomething(position.coords.latitude, position.coords.longitude);
+}
+
+function error() {
+  alert('Sorry, no position available.');
+}
+
+const options = {
+  enableHighAccuracy: true,
+  maximumAge: 30000,
+  timeout: 27000
+};
+
+const watchID = navigator.geolocation.watchPosition(success, error, options);
+ +

위치 표현

+ +

사용자의 위치는 {{domxref("GeolocationPosition")}} 객체를 담은 {{domxref("GeolocationCoordinates")}} 객체를 사용하여 표현합니다.

+ +

GeolocationPosition은 단 두 가지만 가집니다. 하나는 GeolocationCoordinates 인스턴스를 가진 coords 속성이고, 다른 하나는 위치 정보의 기록 시점을 나타내는 {{domxref("DOMTimeStamp")}} 인스턴스입니다.

+ +

GeolocationCoordinates 인스턴스는 다수의 속성을 갖지만, 그 중 가장 많이 쓰게 될 항목은 지도의 지점을 가리킬 때 사용할 latitudelongitude입니다. 따라서 대부분의 Geolocation 성공 콜백은 아래와 같이 꽤 간단한 형태입니다.

+ +
function success(position) {
+  const latitude  = position.coords.latitude;
+  const longitude = position.coords.longitude;
+
+  // Do something with your latitude and longitude
+}
+ +

그러나 GeolocationCoordinates 객체에서 고도, 속도, 장치의 방향, 위경도와 고도의 정확도 등 다른 다양한 정보도 가져올 수 있습니다.

+ +

오류 처리

+ +

getCurrentPosition() 또는 watchPosition()에 오류 콜백을 제공한 경우, 콜백은 첫 번째 매개변수로 GeolocationPositionError 객체를 받습니다. 해당 객체는 오류의 유형을 나타내는 code 속성과, 사람이 읽을 수 있는 형태로 오류 코드의 뜻을 설명한 message 속성을 갖습니다.

+ +

다음 형태로 사용할 수 있습니다.

+ +
function errorCallback(error) {
+  alert(`ERROR(${error.code}): ${error.message}`);
+};
+ +

예제

+ +

다음 예제는 Geolocation API를 사용해 사용자의 위경도를 가져옵니다. 성공한 경우, 사용자의 위치를 가리키는 openstreetmap.org 링크를 생성해 하이퍼링크에 할당합니다.

+ + + +

HTML

+ +
<button id = "find-me">Show my location</button><br/>
+<p id = "status"></p>
+<a id = "map-link" target="_blank"></a>
+ +

JavaScript

+ +
function geoFindMe() {
+
+  const status = document.querySelector('#status');
+  const mapLink = document.querySelector('#map-link');
+
+  mapLink.href = '';
+  mapLink.textContent = '';
+
+  function success(position) {
+    const latitude  = position.coords.latitude;
+    const longitude = position.coords.longitude;
+
+    status.textContent = '';
+    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
+    mapLink.textContent = `Latitude: ${latitude} °, Longitude: ${longitude} °`;
+  }
+
+  function error() {
+    status.textContent = 'Unable to retrieve your location';
+  }
+
+  if(!navigator.geolocation) {
+    status.textContent = 'Geolocation is not supported by your browser';
+  } else {
+    status.textContent = 'Locating…';
+    navigator.geolocation.getCurrentPosition(success, error);
+  }
+
+}
+
+document.querySelector('#find-me').addEventListener('click', geoFindMe);
+ +

결과

+ +

{{EmbedLiveSample('예제', 350, 150)}}

diff --git a/files/ko/web/api/html_drag_and_drop_api/drag_operations/index.html b/files/ko/web/api/html_drag_and_drop_api/drag_operations/index.html new file mode 100644 index 0000000000..122e835b75 --- /dev/null +++ b/files/ko/web/api/html_drag_and_drop_api/drag_operations/index.html @@ -0,0 +1,343 @@ +--- +title: Drag Operations +slug: Web/API/HTML_드래그_앤_드롭_API/Drag_operations +translation_of: Web/API/HTML_Drag_and_Drop_API/Drag_operations +--- +

{{DefaultAPISidebar("HTML Drag and Drop API")}}

+ +

다음은 드래그 & 드랍(drag & drop) 동작 실행 시 각 단계에 대한 설명입니다.

+ +

이 문서에 설명된 드래그 동작은 {{domxref("DataTransfer")}} 인터페이스를 사용합니다. 이 문서에서는 {{domxref("DataTransferItem")}} 인터페이스나 {{domxref("DataTransferItemList")}} 인터페이스를 사용하지 않습니다.

+ +

Draggable 속성

+ +

웹 페이지 안에서 특정 상황에 기본 드래그(default drag) 행위가 사용될 경우가 있습니다. 선택된 텍스트(text selections), 이미지 또는 링크가 여기에 포함됩니다. 이미지나 링크가 드래그될 때, 이미지나 링크의 URL이 드래그 데이터(drag data)로 설정되고 드래그가 시작됩니다. 다른 요소의 경우, 기본 드래그가 발생할 선택(selections)에 포함되어 있어야 합니다(For other elements, they must be part of a selection for a default drag to occur). 이 효과를 보기 위해서는 웹 페이지의 어떤 영역을 선택하고 마우스를 클릭한 채로 드래그하면 됩니다. 드래그가 발생할 때 마우스 포인터로 선택 영역에 대한 OS별 렌더링이 표시됩니다. 이 행위는 기본 드래그 행위인 경우에만 발생하는 것으로 드래그되는 데이터를 조정할 리스너가 없는 경우에는 작동하지 않습니다.

+ +

HTML에서 이미지나 링크 그리고 선택(selections)에 대한 기본 행위를 제외한 나머지 요소는 기본적으로 드래그되지 않습니다. XUL에서는 모든 요소가 드래그 가능합니다.

+ +

다른 HTML 요소를 드래그할 수 있게 하려면 세 가지가 이루어져야 합니다:

+ + + +

컨텐츠의 일부 영역을 드래그할 수 있도록 만드는 예제는 다음과 같습니다.

+ +
<div draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
+  This text <strong>may</strong> be dragged.
+</div>
+
+ +

요소를 드래그할 수 있게 하기 위해서는 {{htmlattrxref("draggable")}} 속성이 true로 설정되어야 합니다. 이 속성이 생략되거나 false로 설정되면 해당 요소는 드래그할 수 없으며, 대신 텍스트가 선택됩니다. {{htmlattrxref("draggable")}} 속성은 이미지나 링크를 포함한 어떤 요소에서도 사용할 수 있습니다. 하지만, 이미지나 링크에 대해서는 기본값이 true로 설정되어 있으므로 이들 요소에 대해 드래깅할 수 없게 만들 경우에만 {{htmlattrxref("draggable")}} 속성의 값을 false로 설정하면 됩니다.

+ +

어떤 요소가 드래그 가능한 경우, 해당 요소 내의 텍스트나 다른 요소는 마우스를 클릭하고 드래그하는 통상적인 방식으로는 선택할 수 없게 됩니다. 대신, 사용자가 alt 키를 누른채로 마우스로 텍스트를 선택하거나 키보드를 이용해 선택할 수 있습니다.

+ +

XUL 요소에 대해서는 {{htmlattrxref("draggable")}} 속성을 사용할 필요가 없으며, 모든 XUL 요소는 드래그가 가능합니다.

+ +
<button label="Drag Me" ondragstart="event.dataTransfer.setData('text/plain', 'Drag Me Button');">
+
+ +

드래그 작업 시작

+ +

이 예제에서는 {{domxref("GlobalEventHandlers.ondragstart","ondragstart")}} 속성을 이용하여 {{event("dragstart")}} 이벤트에 대한 리스너를 추가합니다.

+ +
<div draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
+  This text <strong>may</strong> be dragged.
+</div>
+
+ +

사용자가 드래그를 시작할 때, {{event("dragstart")}} 이벤트가 발생합니다. 이 예제에서는 드래그할 요소에 {{event("dragstart")}} 리스너가 추가되었습니다; 하지만, 대부분의 다른 이벤트가 그렇듯이 상위 요소에서 드래그 이벤트를 포착할 수 있습니다. {{event("dragstart")}} 이벤트 내에서 아래에서 설명하는 바와 같이 피드백 이미지(feedback image)나 드래그 효과와 그리고 드래그 데이터를 명시할 수 있습니다. 기본 이미지나 드래그 효과는 대부분의 상황에 적합하게 되어 있으며, 드래그 데이터만 필요합니다.

+ +

데이터 드래그

+ +

모든 {{domxref("DragEvent","drag events")}}는 드래그 데이터를 가지고 있는 {{domxref("DragEvent.dataTransfer","dataTransfer")}}라는 속성이 존재합니다 (dataTransfer는 {{domxref("DataTransfer")}} 객체입니다).

+ +

드래그가 발생할 때, 데이터는 어떤 것이 드래그되는지를 구분할 수 있는 드래그와 연관되어야 합니다(When a drag occurs, data must be associated with the drag which identifies what is being dragged). 예를 들어, 선택된 텍스트가 드래그될 경우 드래그 데이터 항목에 연관된 데이터는 텍스트 자체입니다. 이와 유사하게, 웹 페이지 상의 링크가 드래그될 경우에 드래그 데이터 항목은 링크의 URL이됩니다.

+ +

{{domxref("DataTransfer","drag data")}}는 두 가지 정보를 담고 있는데, 데이터의 유형(또는 형식)과 데이터 값입니다. 형식은 (텍스트 데이터에 해당하는 text/plain과 같은) 형식 문자열(type string) 값이고, 값은 텍스트의 문자열입니다. 드래그가 시작되면, 데이터와 형식을 제공하는 데이터를 추가해야 합니다. 드래그되는 동안, {{event("dragenter")}} 이벤트와 {{event("dragover")}} 이벤트에 대한 이벤트 리스너에서 드래그되는 데이터의 형식을 사용해 드랍이 허용되는지 확인할 수 있습니다. 예를 들어, 링크가 허용되는 드랍 대상(drop target)은 text/uri-list 형식의 링크인지 확인합니다. 드랍 이벤트 동안 리스너는 드래그 대상(being dragged)으로부터 데이터를 추출해 드랍되는 위치에 삽입합니다.

+ +

{{domxref("DataTransfer","drag data's")}}의 {{domxref("DataTransfer.types","types")}} 속성은 text/plain or image/jpeg과 같은 {{domxref("DOMString")}} MIME-type 목록을 반환홥니다. 여러분은 자신만의 형식을 만들 수도 있습니다. 가장 흔하게 사용되는 형식은 권장 드래그 데이터 형식(Recommended Drag Types)에서 소개하고 있습니다.

+ +

드래그에는 여러 가지 다른 형식의 데이터 항목이 포함될 수 있습니다. 이를 통해 사용자 정의 형식(custom types)과 같은 보다 특정한 형식의 데이터를 주로 제공하지만, 특정한 유형을 지원하지 않는 드롭 대상에 대해 대체 데이터(fallback data)를 제공할 수도 있습니다. text/plain 형식의 일반적인 텍스트 데이터가 가장 단순한 형식의 데이터일 것입니다.이 형식의 데이터는 단순히 텍스트 형식으로 표시될 것입니다.

+ +

{{domxref("DragEvent.dataTransfer","dataTransfer")}} 내에 드래그 데이터 항목(drag data item)을 설정하기 위해서는 {{domxref("DataTransfer.setData","setData()")}} 메서드를 이용합니다. 이 메서드는 각각 데이터 형식과 데이터 값인 두 개의 인자가 필요합니다. 예를 들어:

+ +
event.dataTransfer.setData("text/plain", "Text to drag");
+
+ +

이 경우, 데이터 값은 "Text to drag"이고 형식은 text/plain입니다.

+ +

여러 형식의 데이터를 제공할 수도 있습니다. 이를 위해서는 서로 다른 형식으로 {{domxref("DataTransfer.setData","setData()")}} 메서드를 여러 번 호출합니다. 이 때, 가장 세부적인 형식에서 덜 세부적인 형식의 순으로 호출해야 합니다.

+ +
var dt = event.dataTransfer;
+dt.setData("application/x-bookmark", bookmarkString);
+dt.setData("text/uri-list", "http://www.mozilla.org");
+dt.setData("text/plain", "http://www.mozilla.org");
+
+ +

여기서 데이터는 세가지 유형으로 추가됩니다. 첫번째 형식의 'application2x-bookmark'는 사용자 지정 형식입니다. 다른 응용 프로그램에서는 이 형식을 지원하지 않지만 동일한 사이트 또는 응용 프로그램의 영역 간 드래그할 경우, 이 사용자 지정 형식을 사용할 수 있습니다. 또한 다른 형식의 데이터를 제공함으로써 덜 세부적인 형태로 다른 애플리케이션으로의 드래그도 지원할 수 있습니다. 다른 형식이 하나의 URL또는 텍스트 형식만 제공할 때, 'application2x-bookmark' 형식은 해당 어플리케이션 내에서 사용될 경우 더 상세한 데이터를 제공할 수 있습니다

+ +

이 예제에서 text/uri-listtext/plain은 동일한 데이터를 담고있음에 주목하시기 바랍니다. 이렇게 해도 되지만, 꼭 이럴 필요는 없습니다.

+ +

동일한 형식으로 데이터를 두 번 추가하려고 하면 새로운 데이터가 기존 데이터를 대체하지만 형식 목록 내에서 이전 데이터(old data)와 같은 위치에 있게 됩니다.

+ +

{{domxref("DataTransfer.clearData","clearData()")}} 메서드를 이용해 해당 데이터를 지울 수 있는데, 이 메서드는 지우고자 하는 데이터의 형식을 인자로 가집니다.

+ +
event.dataTransfer.clearData("text/uri-list");
+
+ +

{{domxref("DataTransfer.clearData","clearData()")}} 메서드에 대한 형식 인자는 선택적입니다. 형식을 지정하지 않으면 모든 형식과 연관된 데이터가 지워집니다. 드래그할 때, 드래그 데이터 항목이 없거나 이후에 모든 항목이 삭제되면 드래그가 발생하지 않습니다.

+ +

드래그 피드백 이미지 설정

+ +

드래그가 발생할 때, 드래그 대상("{{event("dragstart")}}" 이벤트가 발생한 요소)으로부터 반투명한 이미지가 생성되고 드래그 하는 동안 마우스 포인터를 따라 움직입니다. 이 이미지는 자동으로 생성되며, 따로 생성할 필요가 없습니다. 하지만, {{domxref("DataTransfer.setDragImage","setDragImage()")}}를 이용해 사용자 정의 드래그 피드백 이미지를 지정할 수 있습니다.

+ +
event.dataTransfer.setDragImage(image, xOffset, yOffset);
+
+ +

세 개의 인자는 필수입니다. 첫 번째 인자는 이미지에 대한 참조(reference)입니다. 이 참조는 일반적으로 이미지에 대한 참조이나 캔버스(canvas)나 다른 요소를 지정할 수도 있습니다. 피드백 이미지는 단순하게 화면에 표시된 이미지의 모양으로부터 생성되지만, 이미지의 경우 원래 크기로 그려집니다. {{domxref("DataTransfer.setDragImage","setDragImage()")}} 메서드의 두 번째와 세 번째 인자는 마우스 포인터에 대해 상대적인 옵셋(offsets)으로 이미지가 나타날 위치를 의미합니다.

+ +

문서 내에 있지 않은 이미지나 캔버스를 사용하는 것 역시 가능합니다. 이 기법은 다음의 예제와 같이 캔버스 요소를 이용해 드래그 이미지를 사용자 정의 형태로 그리고자 할 때 유용합니다:

+ +
function dragWithCustomImage(event) {
+  var canvas = document.createElementNS("http://www.w3.org/1999/xhtml","canvas");
+  canvas.width = canvas.height = 50;
+
+  var ctx = canvas.getContext("2d");
+  ctx.lineWidth = 4;
+  ctx.moveTo(0, 0);
+  ctx.lineTo(50, 50);
+  ctx.moveTo(0, 50);
+  ctx.lineTo(50, 0);
+  ctx.stroke();
+
+  var dt = event.dataTransfer;
+  dt.setData('text/plain', 'Data to Drag');
+  dt.setDragImage(canvas, 25, 25);
+}
+
+ +

이 예제에서, 드래그 이미지를 표시할 캔버스를 하나 생성합니다. 캔버스는 너비가 와 높이가 모두 50 픽셀이고, 마우스 포인터가 이미지의 중앙에 위치하도록 옵셋(offsets)을 너비와 높이의 절반(25)으로 설정했습니다.

+ +

{{h2_gecko_minversion("Using XUL panels as drag images", "9.0")}}

+ +

Gecko 개발자일 경우 (Mozilla 어플리케이션 개발자든 add-on 개발자든 상관 없이), Gecko 9.0 {{geckoRelease("9.0")}}에 드래그 피드백 이미지로 XUL {{XULElem("panel")}} 요소를 사용할 수 있도록 하는 지원이 추가되었습니다. 간단히 {{XULElem("panel")}} 요소를 {{domxref("DataTransfer.setDragImage","setDragImage()")}} 메서드로 전달하기만 하면 됩니다.

+ +

다음 XUL {{XULElem("panel")}}를 살펴보시기 바랍니다:

+ +
<panel id="panel" style="opacity: 0.6">
+  <description id="pb">Drag Me</description>
+</panel>
+
+<vbox align="start" style="border: 1px solid black;" ondragstart="startDrag(event)">
+  <description>Drag Me</description>
+</vbox>
+
+ +

위의 예에서 사용자가 {{XULElem("vbox")}}를 클릭하고 드래그하기 시작하면, 아래의 startDrag() 함수가 호출됩니다.

+ +
function startDrag(event) {
+  event.dataTransfer.setData("text/plain", "<strong>Body</strong>");
+  event.dataTransfer.setDragImage(document.getElementById("panel"), 20, 20);
+}
+
+ +

이 함수는 해당 패널을 드래그 이미지로 사용하고, HTML 형식의 "<strong>Body</strong>"을 데이터로 가집니다. 텍스트 편집기에 패널을 드랍하면 "Body"라는 텍스트가 드랍된 위치에 삽입됩니다.

+ +

드래그 효과

+ +

드래그할 때, 여러 가지 작업이 수행될 수 있습니다. copy 작업은 드래그되는 데이터가 현재 위치에서 드랍되는 위치로 복사될 것임을 나타냅니다. move 작업은 드래그되는 데이터가 이동될 것임을 나타내고, link 작업은 특정 형태의 관계(relationship)나 연결(connection)이 소스와 드랍되는 위치 사이에 생성될 것임을 나타냅니다.

+ +

드래그 소스(drag source)에 대해 {{event("dragstart")}} 이벤트 리스너의 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 설정함으로써, 이 세 가지 작업 중 어떤 것을 허용할 것인지를 지정할 수 있습니다.

+ +
event.dataTransfer.effectAllowed = "copy";
+
+ +

이 예제에서는, 복사만 허용됩니다. 다양한 방식으로 값을 조합할 수 있습니다:

+ +
+
none
+
어떤 작업도 허용하지 않음.
+
copy
+
복사만 허용
+
move
+
이동만 허용
+
link
+
연결만 허용
+
copyMove
+
복사 또는 이동만 허용
+
copyLink
+
복사 또는 연결만 허용
+
linkMove
+
연결 또는 이동만 허용
+
all
+
복사, 이동 및 연결 모두 허용
+
+ +

이 값들은 반드시 위에 나열한 것과 정확하게 일치해야 함에 유의하시기 바랍니다. 예를 들어, {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 copyMove로 설정하면 복사와 이동 작업이 허용되나 연결(link) 작업은 금지됩니다. {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 변경하지 않으면 'all' 값과 마찬가지로 어떤 작업도 허용됩니다. 따라서, 특정한 유형의 작업을 제외시키고 싶지 않다면 이 속성을 조정할 필요가 없습니다.

+ +

드래그 작업 중에 {{event("dragenter")}} 또는 {{event("dragover")}} 이벤트에 대한 리스너는 어떤 작업이 허용되어 있는지 알기 위해 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 확인할 수 있습니다. 관련된 속성으로, {{domxref("DataTransfer.dropEffect","dropEffect")}}는 이들 이벤트 중 하나에서 수행되어야 하는 단일 작업을 지정하기 위해 설정되어야 할 속성입니다. {{domxref("DataTransfer.dropEffect","dropEffect")}}에 유효한 값은 none, copy, move, 또는 link입니다. 이 속성에 값의 조합은 허용되지 않습니다.

+ +

{{event("dragenter")}}나 {{event("dragover")}} 이벤트가 발생하면 사용자가 요청하는 효과로 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성이 초기화됩니다. 사용자는 한정자 키를 눌러 원하는 효과로 수정할 수 있습니다. 플랫폼에 따라 정확한 키가 달라질 수 있지만, 일반적으로 쉬프트(Shift)와 컨트롤(Control) 키가 복사하기, 이동하기, 연결하기 간 전환에 사용됩니다. 마우스 포인터를 원하는 작업을 나타내도록 변경할 수 있습니다; 예를 들어, 복사 작업에 대해서는 마우스 포인터 옆에 더하기 기호가 표시된 커서가 나타날 수 있습니다.

+ +

{{event("dragenter")}} 또는 {{event("dragover")}} 이벤트가 발생하는 동안 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 변경할 수 있는데, 예를 들자면, 특정 작업만 지원되는 특수한 드랍 대상(drop target)일 경우가 그렇습니다. {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 수정하여 사용자 효과(user effect)를 오버라이드하여 특정한 드랍 작업이 발생하게 할 수 있습니다. 이 효과는 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성에 열거된 것 중의 하나 이어야 함에 유의하시기 바랍니다. 그렇지 않을 경우, 허용되는 대체 값으로 설정되게 됩니다.

+ +
event.dataTransfer.dropEffect = "copy";
+
+ +

이 예제에서는 복사가 수행될 효과입니다.

+ +

이 경우에는 이벤트를 취소하지 않는 것이 좋지만 none 값을 사용하여 이 위치에서 드롭이 허용되지 않음을 나타낼 수 있습니다.

+ +

{{event("drop")}}{{event("dragend")}} 이벤트 내에서{{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 확인하면 최종적으로 어떤 효과가 선택되었는지를 알 수 있습니다. 선택된 효과가 "move"였다면, {{event("dragend")}} 이벤트 내에서 드래그 소스의 원본 데이터가 삭제되어야 합니다.

+ +

드랍 대상 지정하기

+ +

{{event("dragenter")}}{{event("dragover")}} 이벤트에 대한 리스너는 유효한 드랍 대상인지, 즉 드래그된 아이템이 드랍될 수 있는 곳인지를 나타내는데 사용할 수 있습니다. 웹 페이지 또는 어플리케이션의 대부분의 영역은 데이터를 드랍할 수 있는 유효한 영역이 아닙니다. 따라서, 이들 이벤트에 대한 기본적인 처리는 드랍을 허용하지 않는 것입니다.

+ +

드랍을 허용하길 원한다면, 해당 이벤트를 취소하는 기본 처리를 막아야 합니다. 속성 정의(attribute-defined) 이벤트 리스너로부터 false를 반환 받거나 해당 이벤트의 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하면 됩니다. 후자는 별도의 스크립트에 정의된 함수에 더 적합합니다.

+ +
<div ondragover="return false">
+<div ondragover="event.preventDefault()">
+
+ +

{{event("dragenter")}} and {{event("dragover")}} 두 이벤트 모두에서 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하는 것은 그 위치에 드랍이 허용되는 것을 나타냅니다. 하지만, 일반적으로 특정한 상황에서만, 예를 들자면 링크가 드래그될 때만 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하길 원할 것입니다. 이렇게 하기 위해서는 조건을 확인하여 조건이 충족될 때에만 해당 이벤트를 취소하는 함수를 호출합니다. 조건이 충족되지 않을 경우, 이벤트를 취소하지 않으면 사용자가 마우스 버튼을 놓더라도 드랍은 발생하지 않을 것입니다.

+ +

data transfer의 드래그 데이터 형식에 따라 드랍을 허용하거나 기각하는 경우가 대부분일 것입니다(예를 들어, 이미지나 링크를 허용하거나 둘 다 허용하는 경우). 이렇게 하기 위해서는 이벤트의 {{domxref("DragEvent.dataTransfer","dataTransfer")}} 속성의 {{domxref("DataTransfer.types","types")}} 속성을 확인합니다. {{domxref("DataTransfer.types","types")}} 속성은 드래그가 시작될 때 추가된 형식 문자열의 배열을 반환하는데, 그 순서는 가장 세부적인 형식에서 가장 덜 세부적인 형식의 순서입니다.

+ +
function contains(list, value) {
+    for( var i = 0; i < list.length; ++i ) {
+        if(list[i] === value) return true;
+    }
+    return false;
+}
+
+function doDragOver(event) {
+  var isLink = contains( event.dataTransfer.types, "text/uri-list");
+  if (isLink) {
+    event.preventDefault();
+  }
+}
+ +

이 예제에서 형식 목록 내에 text/uri-list 형식이 존재하는지 확인하기 위해 contains 메서드를사용합니다. 존재할 경우에는 드랍을 허용하기 위해 이벤트가 취소될 것입니다. 드래그 데이터가 링크를 포함하지 않았다면, 해당 이벤트는 취소되지 않을 것이고 그 위치에 대한 드랍이 발생하지 않을 것입니다.

+ +

수행되어야 하는 작업 형식을 더 세부적으로 설정하길 원한다면, {{domxref("DataTransfer.effectAllowed","effectAllowed")}}나 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 각각 설정하거나 동시에 둘 다를 설정하고 싶을 것입니다. 두 속성을 변경하더라도 해당 이벤트를 취소하지 않으면 아무런 영향이 없을 것입니다.

+ +

Updates to DataTransfer.types

+ +

최신 스펙에는 {{domxref("DataTransfer.types")}}이 {{domxref("DOMStringList")}}(이 속성은 Fiirefox 52 이상에서 지원됨)이 아닌 {{domxref("DOMString")}} 형식의 고정배열(fronzen array)을 반환하도록 명시하고 있음에 유의하시기 바랍니다.

+ +

그 결과로, contains 메서드는 해당 속성에 대해 더 이상 동작하지 않으며; 특정 형식의 데이터가 제공되는지 확인하기 위해서는 다음 코드와 같이 includes 메서드를 사용해야 합니다:

+ +
if ([...event.dataTransfer.types].includes('text/html')) {
+  // Do something
+}
+ +

일부 특성 검출(feature detection)을 이용해 types에 대해 어떤 메서드가 지원되는지를 판별하고 적절하게 코드를 실행할 수 있습니다.

+ +

Drop Feedback

+ +

There are several ways in which you can indicate to the user that a drop is allowed at a certain location. The mouse pointer will update as necessary depending on the value of the {{domxref("DataTransfer.dropEffect","dropEffect")}} property. Although the exact appearance depends on the user's platform, typically a plus sign icon will appear for a 'copy' for example, and a 'cannot drop here' icon will appear when a drop is not allowed. This mouse pointer feedback is sufficient in many cases.

+ +

However, you can also update the user interface with an insertion point or highlight as needed. For simple highlighting, you can use the -moz-drag-over CSS pseudoclass on a drop target.

+ +
.droparea:-moz-drag-over {
+  border: 1px solid black;
+}
+
+ +

In this example, the element with the class droparea will receive a 1 pixel black border while it is a valid drop target, that is, if the {{domxref("Event.preventDefault","preventDefault()")}} method was called during the {{event("dragenter")}} event. Note that you must cancel the {{event("dragenter")}} event for this pseudoclass to apply, as this state is not checked for the {{event("dragover")}} event.

+ +

For more complex visual effects, you can also perform other operations during the {{event("dragenter")}} event, for example, by inserting an element at the location where the drop will occur. For example, this might be an insertion marker or an element that represents the dragged element in its new location. To do this, you could create an image or separator element, for example, and simply insert it into the document during the {{event("dragenter")}} event.

+ +

The {{event("dragover")}} event will fire at the element the mouse is pointing at. Naturally, you may need to move the insertion marker around a {{event("dragover")}} event as well. You can use the event's {{domxref("MouseEvent.clientX","clientX")}} and {{domxref("MouseEvent.clientY","clientY")}} properties as with other mouse events to determine the location of the mouse pointer.

+ +

Finally, the {{event("dragleave")}} event will fire at an element when the drag leaves the element. This is the time when you should remove any insertion markers or highlighting. You do not need to cancel this event. Any highlighting or other visual effects specified using the -moz-drag-over pseudoclass will be removed automatically. The {{event("dragleave")}} event will always fire, even if the drag is cancelled, so you can always ensure that any insertion point cleanup can be done during this event.

+ +

Performing a Drop

+ +

When the user releases the mouse, the drag and drop operation ends. If the mouse was released over an element that is a valid drop target, that is, one that cancelled the last {{event("dragenter")}} or {{event("dragover")}} event, and then the drop will be successful, and a {{event("drop")}} event will fire at the target. Otherwise, the drag operation is cancelled, and no {{event("drop")}} event is fired.

+ +

During the {{event("drop")}} event, you should retrieve that data that was dropped from the event and insert it at the drop location. You can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine which drag operation was desired.

+ +

As with all drag-related events, the event's {{domxref("DataTransfer","dataTransfer")}} property will hold the data that is being dragged. The {{domxref("DataTransfer.getData","getData()")}} method may be used to retrieve the data again.

+ +
function onDrop(event) {
+  var data = event.dataTransfer.getData("text/plain");
+  event.target.textContent = data;
+  event.preventDefault();
+}
+
+ +

The {{domxref("DataTransfer.getData","getData()")}} method takes one argument, the type of data to retrieve. It will return the string value that was set when {{domxref("DataTransfer.setData","setData()")}} was called at the beginning of the drag operation. An empty string will be returned if data of that type does not exist. Naturally, though, you would likely know that the right type of data was available, as it was previously checked during a {{event("dragover")}} event.

+ +

In the example here, once we have retrieved the data, we insert the string as the textual content of the target. This has the effect of inserting the dragged text where it was dropped, assuming that the drop target is an area of text such as a p or div element.

+ +

In a web page, you should call the {{domxref("Event.preventDefault","preventDefault()")}} method of the event if you have accepted the drop so that the default browser handling does not handle the dropped data as well. For example, when a link is dragged to a web page, Firefox will open the link. By cancelling the event, this behavior will be prevented.

+ +

You can retrieve other types of data as well. If the data is a link, it should have the type text/uri-list. You could then insert a link into the content.

+ +
function doDrop(event) {
+  var lines = event.dataTransfer.getData("text/uri-list").split("\n");
+  for (let line of lines) {
+    if (line.startsWith("#"))
+      continue;
+
+    let link = document.createElement("a");
+    link.href = line;
+    link.textContent = line;
+    event.target.appendChild(link);
+  }
+  event.preventDefault();
+}
+
+ +

This example inserts a link from the dragged data. As you might be able to guess from the name, the text/uri-list type actually may contain a list of URLs, each on a separate line. In this code, we use the split to split the string into lines, then iterate over the list of lines, inserting each as a link into the document. Note also that we skip links starting with a number sign (#) as these are comments.

+ +

For simple cases, you can use the special type URL just to retrieve the first valid URL in the list. For example:

+ +
var link = event.dataTransfer.getData("URL");
+
+ +

This eliminates the need to check for comments or iterate through lines yourself; however, it is limited to only the first URL in the list.

+ +

The URL type is a special type used only as a shorthand, and it does not appear within the list of types specified in the {{domxref("DataTransfer.types","types")}} property.

+ +

Sometimes you may support some different formats, and you want to retrieve the data that is most specific that is supported. In this example, three formats are supported by a drop target.

+ +

The following example returns the data associated with the best-supported format:

+ +
function doDrop(event) {
+  var types = event.dataTransfer.types;
+  var supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"];
+  types = supportedTypes.filter((value) => types.includes(value));
+  if (types.length)
+    var data = event.dataTransfer.getData(types[0]);
+  event.preventDefault();
+}
+
+ +

This method relies on JavaScript functionality available in Firefox 3. However, the code could be adjusted to support other platforms.

+ +

Finishing a Drag

+ +

Once the drag is complete, a {{event("dragend")}} event is fired at the source of the drag (the same element that received the {{event("dragstart")}} event). This event will fire if the drag was successful[1] or if it was cancelled. However, you can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine what drop operation occurred.

+ +

If the {{domxref("DataTransfer.dropEffect","dropEffect")}} property has the value none during a {{event("dragend")}}, then the drag was cancelled. Otherwise, the effect specifies which operation was performed. The source can use this information after a move operation to remove the dragged item from the old location. The {{domxref("DataTransfer.mozUserCancelled","mozUserCancelled")}} property will be set to true if the user cancelled the drag (by pressing Escape), and false if the drag was cancelled for other reasons such as an invalid drop target, or if it was successful.

+ +

A drop can occur inside the same window or over another application. The {{event("dragend")}} event will always fire regardless. The event's {{domxref("MouseEvent.screenX","screenX")}} and {{domxref("MouseEvent.screenY","screenY")}} properties will be set to the screen coordinate where the drop occurred.

+ +

After the {{event("dragend")}} event has finished propagating, the drag and drop operation is complete.

+ +

[1] In Gecko, {{event("dragend")}} is not dispatched if the source node is moved or removed during the drag (e.g. on drop or {{event("dragover")}}).  bug 460801

+ +

See also

+ + diff --git a/files/ko/web/api/html_drag_and_drop_api/index.html b/files/ko/web/api/html_drag_and_drop_api/index.html new file mode 100644 index 0000000000..70a4295284 --- /dev/null +++ b/files/ko/web/api/html_drag_and_drop_api/index.html @@ -0,0 +1,303 @@ +--- +title: HTML 드래그 앤 드롭 API +slug: Web/API/HTML_드래그_앤_드롭_API +tags: + - HTML5 + - XUL + - 가이드 + - 개요 + - 고급 + - 드래그 앤 드롭 + - 이벤트 +translation_of: Web/API/HTML_Drag_and_Drop_API +--- +

{{DefaultAPISidebar("HTML 드래그 앤 드롭 API")}}

+ +

HTML 드래그 앤 드롭 인터페이스는 파이어폭스와 다른 브라우저에서 어플리케이션이 드래그 앤 드롭 기능을 사용하게 해줍니다. 이 기능을 이용해 사용자는 draggable 요소를 마우스로 선택해 droppable 요소로 드래그하고, 마우스 버튼에서 손을 뗌으로써 요소를 드롭할 수 있습니다. 드래그하는 동안 draggable 요소는 반투명한 채로 마우스 포인터를 따라다닙니다.

+ +

웹 사이트나 확장 기능, XUL 어플리케이션을 위해, 다양한 요소를 draggable 요소로 만들 수 있고, 이벤트에 대한 draggable 요소의 반응들을 만들어내거나 droppable 요소를 자유자재로 만들 수 있습니다.

+ +

이 문서는 HTML 드래그 앤 드롭에 대한 전반적인 개요입니다. 인터페이스에 대한 설명과 드래그 앤 드롭 기능을 어플리케이션에서 사용하기 위한 기본적인 절차, 인터페이스의 상호 운용성에 대한 요약 등이 이 문서에 담겨있습니다.

+ +

드래그 이벤트

+ +

HTML 드래그 앤 드롭은 {{domxref("Event","DOM event model")}} 과 {{domxref("DragEvent","drag events")}}   {{domxref("MouseEvent","mouse events")}} 로부터 상속받습니다. 보통 드래그는 사용자가 draggable 요소를 마우스로 선택하고, 마우스 포인터를 droppable 요소로 가져가 마우스 버튼을 때는 것으로 이루어집니다. 드래그하는 도중에 많은 이벤트가 발생하고, 몇몇 이벤트는 여러번 발생하기도 합니다. ( {{event("drag")}}와 {{event("dragover")}}).

+ +

모든 드래그 이벤트글로벌 이벤트 핸들러와 연결되어 있습니다. 각 드래그 이벤트와 드래그 전역 속성은 참조 문서를 가지고 있습니다. 아래 표는 각 이벤트에 대한 간략한 설명과 참조 문서로의 링크를 담고 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
이벤트이벤트 핸들러설명
{{domxref('Document/drag_이벤트', 'drag')}}{{domxref('GlobalEventHandlers.ondrag','ondrag')}}요소나 텍스트 블록을 드래그 할 때 발생한다.
{{event('dragend')}}{{domxref('GlobalEventHandlers.ondragend','ondragend')}} +

드래그를 끝냈을 때 발생한다. (마우스 버튼을 떼거나 ESC 키를 누를 때) (드래그 끝내기를 보시오)

+
{{event('dragenter')}}{{domxref('GlobalEventHandlers.ondragenter','ondragenter')}} +

드래그한 요소나 텍스트 블록을 적합한 드롭 대상위에 올라갔을 때 발생한다. (드롭 대상 지정하기를 보시오.)

+
{{event('dragexit')}}{{domxref('GlobalEventHandlers.ondragexit','ondragexit')}} +

요소가 더 이상 드래그의 직접적인 대상이 아닐 때 발생한다.

+
{{event('dragleave')}}{{domxref('GlobalEventHandlers.ondragleave','ondragleave')}} +

드래그하는 요소나 텍스트 블록이 적합한 드롭 대상에서 벗어났을 때 발생한다.

+
{{event('dragover')}}{{domxref('GlobalEventHandlers.ondragover','ondragover')}} +

요소나 텍스트 블록을 적합한 드롭 대상 위로 지나갈 때 발생한다. (매 수백 밀리초마다 발생한다.)

+
{{event('dragstart')}}{{domxref('GlobalEventHandlers.ondragstart','ondragstart')}} +

사용자가 요소나 텍스트 블록을 드래그하기 시작했을 때 발생한다. (드래그 시작하기를 보시오.)

+
{{event('drop')}}{{domxref('GlobalEventHandlers.ondrop','ondrop')}} +

요소나 텍스트 블록을 적합한 드롭 대상에 드롭했을 때 발생한다. (드롭하기를 보시오.)

+
+ +

참고: dragstartdragend 이벤트는 파일을 브라우저로 드래그할 때는 발생하지 않습니다.

+ +

인터페이스

+ +

HTML 드래그와 드롭 인터페이스는 {{domxref("DragEvent")}}, {{domxref("DataTransfer")}}, {{domxref("DataTransferItem")}}, {{domxref("DataTransferItemList")}} 입니다.

+ +

{{domxref("DataTransfer")}} 객체는 드래그 형태나 드래그 데이터 (하나 이상의 아이템), 각 드래그 아이템의 종류 (MIME 종류) 와 같은 드래그 이벤트의 상태를 담고 있습니다. {{domxref("DataTransfer")}} 는 또한 드래그 데이터에 아이템을 추가하거나 제거하는 메소드를 가지고 있습니다. The {{domxref("DragEvent")}} 와 {{domxref("DataTransfer")}} 인터페이스만 있으면 어플리케이션에 HTML 드래그 앤 드롭 기능을 추가할 수 있습니다. 참고로 파이어폭스는 {{domxref("DataTransfer")}}에 {{anch("Gecko specific interfaces","Gecko-specific extensions")}} 와 같은 파이어폭스에서만 동작하는 추가적인 확장을 제공합니다. 

+ +

{{domxref("DataTransfer")}}는 {{domxref("DataTransferItem")}}의 {{domxref("DataTransferItemList","목록")}} 인 {{domxref("DataTransfer.items","items")}} 프로퍼티를 가지고 있습니다. 각 {{domxref("DataTransferItem")}} 는 하나의 드래그 아이템을 나타내고 각 아이템은 데이터의 종류 (string 혹은 file) 를 나타내는 {{domxref("DataTransferItem.kind","kind")}} 프로퍼티와 데이터 아이템의 종류 (MIME 종류) 를 나타내는 {{domxref("DataTransferItem.type","type")}} 프로퍼티를 가집니다. {{domxref("DataTransferItem")}}은 드래그 아이템의 데이터를 가져오는 메소드를 제공합니다.

+ +

{{domxref("DataTransferItemList")}} 객체는 {{domxref("DataTransferItem")}}의 리스트입니다. 이 리스트 객체는 세 개의 메소드 - 드래그 아이템을 리스트에 추가하거나, 리스트에서 아이템을 삭제하거나, 모든 드래그 아이템을 리스트에서 삭제하는 메소드 - 를 가집니다.

+ +

A key difference between the {{domxref("DataTransfer")}} and {{domxref("DataTransferItem")}} interfaces is that the former uses the synchronous {{domxref("DataTransfer.getData","getData()")}} method to access a drag item's data, whereas the later uses the asynchronous {{domxref("DataTransferItem.getAsString","getAsString()")}} method to access a drag item's data.

+ +

{{domxref("DataTransfer")}}와 {{domxref("DataTransferItem")}}의 가장 중요한 차이점은 전자는 드래그 아이템의 데이터에 접근하기 위해 동기 메소드인 {{domxref("DataTransfer.getData","getData()")}}를 사용하는데 반해, 후자는 비동기 메소드인 {{domxref("DataTransferItem.getAsString","getAsString()")}}를 사용한다는 점입니다.

+ +

참고: {{domxref("DragEvent")}} and {{domxref("DataTransfer")}}는 여러 데스크탑 브라우저에서 폭넓게 지원하고 있습니다. 하지만 {{domxref("DataTransferItem")}}와 {{domxref("DataTransferItemList")}}는 제한적으로 사용 가능합니다. 드래그 앤 드롭의 상호 운용성에 대한 더 많은 정보를 찾아보기 위해 {{anch("Interoperability")}}를 보십시오.

+ +

Gecko 한정 인터페이스

+ +

모질라와 파이어폭스는 표준 드래그 앤 드롭 모델에서 제공하지 않는 몇가지 기능들을 추가로 제공합니다. 여러 개의 아이템을 동시에 드래그하거나 파일과 같이 문자열이 아닌 데이터를 드래그 하기 위한 여러 편리한 기능을 제공합니다. 더 많은 정보를 찾아보기 위해, Dragging and Dropping Multiple Items을 보십시오. 덧붙여, 모든 Gecko 한정 프로퍼티나 Gecko 한정 메소드를 찾아보기 위해 {{domxref("DataTransfer")}} 참조 페이지도 보시기 바랍니다.

+ +

기본

+ +

이번 절은 드래그 앤 드롭 기능을 추가하기 위한 기본적인 방법을 요약하고 있습니다. 각 절은 단계를 설명하고, 짧은 코드 예제와 추가적인 정보를 위한 링크를 포함합니다.

+ +

어떤 것이 draggable인지 확인하기

+ +

하나의 요소를 draggable로 만들기 위해서는 {{htmlattrxref("draggable")}}와 {{domxref("GlobalEventHandlers.ondragstart","ondragstart")}} 전역 이벤트 핸들러를 아래 예제 코드와 같이 추가해야합니다.

+ +
function dragstart_handler(ev) {
+ console.log("dragStart");
+ // 데이터 전달 객체에 대상 요소의 id를 추가합니다.
+ ev.dataTransfer.setData("text/plain", ev.target.id);
+}
+
+
+ +
<script>
+  function dragstart_handler(ev) {
+    // 데이터 전달 객체에 대상 요소의 id를 추가합니다.
+    ev.dataTransfer.setData("text/plain", ev.target.id);
+  }
+
+  window.addEventListener('DOMContentLoaded', () => {
+    // id를 통해 element를 가져옵니다.
+    const element = document.getElementById("p1");
+    // 'dragstart' 이벤트 리스터를 추가합니다.
+    element.addEventListener("dragstart", dragstart_handler);
+  });
+</script>
+
+<p id="p1" draggable="true">This element is draggable.</p>
+ +

추가 정보를 위해 draggable attribute referenceDrag operations guide를 참고하세요.

+ +

드래그 데이터 정의하기

+ +

드래그할 때 자유롭게 데이터 아이템을 포함할 수 있습니다. 각 데이터 아이템은 특정 type의 {{domxref("DOMString","문자열")}}이며, 보통 text/html와 같은 MIME type입니다.

+ +

각 {{domxref("DragEvent","drag event")}} 은 이벤트 데이터를 가지고 있는 {{domxref("DragEvent.dataTransfer","dataTransfer")}} 를 가집니다. 이 프로퍼티는 ({{domxref("DataTransfer")}} 객체) 드래그 데이터를 관리하는 메소드를 가집니다. {{domxref("DataTransfer.setData","setData()")}} 는 아래 코드 예제와 같이 아이템을 드래그 데이터에 추가할 때 사용합니다.

+ +
function dragstart_handler(ev) {
+  // 드래그 데이터를 추가합니다.
+  ev.dataTransfer.setData("text/plain", ev.target.id);
+  ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>");
+  ev.dataTransfer.setData("text/uri-list", "http://developer.mozilla.org");
+}
+
+ +

드래그 앤 드롭에 사용할 수 있는 공통 데이터 타입 (텍스트, HTML, 링크, 파일 등) 의 목록을 보려면, Recommended Drag Types를 참고하십시오. 드래그 데이터에 대한 추가적인 정보를 위해서는 Drag Data를 참고하십시오.

+ +

드래그 이미지 정의하기

+ +

브라우저는 드래그 하는 동안 마우스 포인터 옆에 나타나는 이미지를 기본적으로 제공합니다. 어플리케이션에서 다른 이미지를 사용하기 원한다면 아래 예제와 같이 {{domxref("DataTransfer.setDragImage","setDragImage()")}}를 사용할 수 있습니다.

+ +
function dragstart_handler(ev) {
+  // 드래그 이미지로 사용할 이미지를 만듭니다.
+  // 참고: "example.gif"를 존재하는 이미지로 바꾸지 않으면 기본 드래그 이미지를 사용합니다.
+  var img = new Image();
+  img.src = 'example.gif';
+  ev.dataTransfer.setDragImage(img, 10, 10);
+}
+
+ +

드래그 이미지에 대해 더 알아보려면, Setting the Drag Feedback Image를 참고하세요.

+ +

드래그 효과 정의하기

+ +

{{domxref("DataTransfer.dropEffect","dropEffect")}} 프로퍼티는 드래그 앤 드롭 도중에 사용자에게 피드백 (보통 시각적인) 을 제공하기 위해 사용합니다. 브라우저가 드래그 하는 동안 어떤 마우스 포인터를 보여줄 지 결정합니다. 사용자가 마우스 포인터를 대상 드롭 요소에 올려놓으면, 브라우저는 드래그 효과에 적합한 마우스 포인터를 보여줄 것입니다.

+ +

세 개의 효과가 정의되어 있습니다:

+ +

copy는 현재 위치에서 드롭하는 위치로 데이터가 복사될 것을 암시합니다.

+ +

move는 현재 위치에서 드롭하는 위치로 데이터가 이동할 것을 암시합니다.

+ +

link는 드래그하는 위치와 드롭하는 위치 간의 일종의 관계나 연결이 맺어진 다는 것을 암시합니다.

+ +

특정 위치에서는 특정 효과가 허용된다는 것을 알려주기 위해 드래그 하는 도중에 효과가 변할 수 있습니다. 허용되는 경우에만 해당 위치에 드롭할 수 있습니다.

+ +

다음 예제는 어떻게 이 프로퍼티를 사용하는지 보여줍니다.

+ +
function dragstart_handler(ev) {
+  // 드래그 효과를 copy로 지정합니다.
+  ev.dataTransfer.dropEffect = "copy";
+}
+
+ +

더 자세한 설명은 Drag Effects를 참고하세요.

+ +

드롭 지역 정의하기

+ +

기본적으로는 브라우저는 HTML 요소에 뭔가를 드롭했을 때 아무 일도 일어나지 않도록 합니다. 특정 요소가 드롭 지역 혹은 droppable로 만들기 위해서는 해당 요소가 {{domxref("GlobalEventHandlers.ondragover","ondragover")}}와 {{domxref("GlobalEventHandlers.ondrop","ondrop")}} 이벤트 핸들러 속성을 가져야합니다. 아래 예제는 두 요소를 어떻게 사용하고, 각 요소에 포함된 기본적인 이벤트 핸들러를 보여줍니다.

+ +
<script>
+function dragover_handler(ev) {
+ ev.preventDefault();
+ // dropEffect를 move로 설정.
+ ev.dataTransfer.dropEffect = "move";
+}
+function drop_handler(ev) {
+ ev.preventDefault();
+ // 대상의 id를 가져와 대상 DOM에 움직인 요소를 추가합니다.
+ const data = ev.dataTransfer.getData("text/plain");
+ ev.target.appendChild(document.getElementById(data));
+}
+</script>
+
+<p id="target" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Zone</p>
+ +

각 핸들러는 {{domxref("Event.preventDefault","preventDefault()")}} 를 호출해 추가적인 이벤트 (터치 이벤트나 포인터 이벤트) 가 일어나지 않도록 합니다.

+ +

추가적인 정보는, Specifying Drop Targets를 참고하세요.

+ +

드롭 효과 다루기

+ +

{{event("drop")}} 이벤트 핸들러는 자유롭게 드래그 데이터를 가공할 수 있습니다. 보통, 드래그 아이템과 각 아이템을 가공하기 위해 {{domxref("DataTransfer.getData","getData()")}}를 사용합니다. 추가로, {{domxref("DataTransfer.dropEffect","dropEffect")}} 값이나 보조키 상태에 따라 어플리케이션이 어떻게 동작할지를 결정할 수 있습니다.

+ +

아래 예제는 드롭 핸들러가 드래그 데이터로부터 드래그하는 요소의 id를 가져와 드래그하는 요소를 드롭하는 요소로 옮기기위해 사용합니다.

+ +
<script>
+function dragstart_handler(ev) {
+ // 데이터 전달 객체에 대상 요소의 id를 추가합니다.
+ ev.dataTransfer.setData("application/my-app", ev.target.id);
+ ev.dataTransfer.dropEffect = "move";
+}
+function dragover_handler(ev) {
+ ev.preventDefault();
+ ev.dataTransfer.dropEffect = "move"
+}
+function drop_handler(ev) {
+ ev.preventDefault();
+ // 대상의 id를 가져와 이동한 대상 DOM 요소를 추가합니다.
+ // Get the id of the target and add the moved element to the target's DOM
+ const data = ev.dataTransfer.getData("application/my-app");
+ ev.target.appendChild(document.getElementById(data));
+}
+</script>
+
+<p id="p1" draggable="true" ondragstart="dragstart_handler(event)">This element is draggable.</p>
+<div id="target" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Zone</div>
+ +

더 많은 정보를 위해 Performing a Drop을 보십시오.

+ +

드래그가 끝나면

+ +

드래그가 끝나면 드래그한 요소에 {{event("dragend")}} 이벤트가 발생합니다. 이 이벤트는 드래그가 완료되거나 중간에 취소되어도 발생합니다. {{event("dragend")}} 이벤트 핸들러는 {{domxref("DataTransfer.dropEffect","dropEffect")}} 프로퍼티를 확인해 드래그가 성공했는지를 확인할 수 있습니다.

+ +

드래그 끝을 다루기 위한 더 많은 정보는 Finishing a Drag를 참고하세요. 

+ +

상호 운용성

+ +

DataTransferItem interface's Browser Compatibility table에 나온 대로, 드래그 앤 드롭은 상대적으로 여러 데스크톱 브라우저에서 폭넓게 사용할 수 있습니다 ({{domxref("DataTransferItem")}}는 {{domxref("DataTransferItemList")}} 덜 지원하지만). 또한 모바일 브라우저에서는 매우 한정적으로 사용할 수 있습니다.

+ +

예제와 데모

+ + + +

명세서 

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "#dnd")}}{{Spec2('HTML WHATWG')}}
+ +

더보기

+ + diff --git "a/files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/drag_operations/index.html" "b/files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/drag_operations/index.html" deleted file mode 100644 index 122e835b75..0000000000 --- "a/files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/drag_operations/index.html" +++ /dev/null @@ -1,343 +0,0 @@ ---- -title: Drag Operations -slug: Web/API/HTML_드래그_앤_드롭_API/Drag_operations -translation_of: Web/API/HTML_Drag_and_Drop_API/Drag_operations ---- -

{{DefaultAPISidebar("HTML Drag and Drop API")}}

- -

다음은 드래그 & 드랍(drag & drop) 동작 실행 시 각 단계에 대한 설명입니다.

- -

이 문서에 설명된 드래그 동작은 {{domxref("DataTransfer")}} 인터페이스를 사용합니다. 이 문서에서는 {{domxref("DataTransferItem")}} 인터페이스나 {{domxref("DataTransferItemList")}} 인터페이스를 사용하지 않습니다.

- -

Draggable 속성

- -

웹 페이지 안에서 특정 상황에 기본 드래그(default drag) 행위가 사용될 경우가 있습니다. 선택된 텍스트(text selections), 이미지 또는 링크가 여기에 포함됩니다. 이미지나 링크가 드래그될 때, 이미지나 링크의 URL이 드래그 데이터(drag data)로 설정되고 드래그가 시작됩니다. 다른 요소의 경우, 기본 드래그가 발생할 선택(selections)에 포함되어 있어야 합니다(For other elements, they must be part of a selection for a default drag to occur). 이 효과를 보기 위해서는 웹 페이지의 어떤 영역을 선택하고 마우스를 클릭한 채로 드래그하면 됩니다. 드래그가 발생할 때 마우스 포인터로 선택 영역에 대한 OS별 렌더링이 표시됩니다. 이 행위는 기본 드래그 행위인 경우에만 발생하는 것으로 드래그되는 데이터를 조정할 리스너가 없는 경우에는 작동하지 않습니다.

- -

HTML에서 이미지나 링크 그리고 선택(selections)에 대한 기본 행위를 제외한 나머지 요소는 기본적으로 드래그되지 않습니다. XUL에서는 모든 요소가 드래그 가능합니다.

- -

다른 HTML 요소를 드래그할 수 있게 하려면 세 가지가 이루어져야 합니다:

- - - -

컨텐츠의 일부 영역을 드래그할 수 있도록 만드는 예제는 다음과 같습니다.

- -
<div draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
-  This text <strong>may</strong> be dragged.
-</div>
-
- -

요소를 드래그할 수 있게 하기 위해서는 {{htmlattrxref("draggable")}} 속성이 true로 설정되어야 합니다. 이 속성이 생략되거나 false로 설정되면 해당 요소는 드래그할 수 없으며, 대신 텍스트가 선택됩니다. {{htmlattrxref("draggable")}} 속성은 이미지나 링크를 포함한 어떤 요소에서도 사용할 수 있습니다. 하지만, 이미지나 링크에 대해서는 기본값이 true로 설정되어 있으므로 이들 요소에 대해 드래깅할 수 없게 만들 경우에만 {{htmlattrxref("draggable")}} 속성의 값을 false로 설정하면 됩니다.

- -

어떤 요소가 드래그 가능한 경우, 해당 요소 내의 텍스트나 다른 요소는 마우스를 클릭하고 드래그하는 통상적인 방식으로는 선택할 수 없게 됩니다. 대신, 사용자가 alt 키를 누른채로 마우스로 텍스트를 선택하거나 키보드를 이용해 선택할 수 있습니다.

- -

XUL 요소에 대해서는 {{htmlattrxref("draggable")}} 속성을 사용할 필요가 없으며, 모든 XUL 요소는 드래그가 가능합니다.

- -
<button label="Drag Me" ondragstart="event.dataTransfer.setData('text/plain', 'Drag Me Button');">
-
- -

드래그 작업 시작

- -

이 예제에서는 {{domxref("GlobalEventHandlers.ondragstart","ondragstart")}} 속성을 이용하여 {{event("dragstart")}} 이벤트에 대한 리스너를 추가합니다.

- -
<div draggable="true" ondragstart="event.dataTransfer.setData('text/plain', 'This text may be dragged')">
-  This text <strong>may</strong> be dragged.
-</div>
-
- -

사용자가 드래그를 시작할 때, {{event("dragstart")}} 이벤트가 발생합니다. 이 예제에서는 드래그할 요소에 {{event("dragstart")}} 리스너가 추가되었습니다; 하지만, 대부분의 다른 이벤트가 그렇듯이 상위 요소에서 드래그 이벤트를 포착할 수 있습니다. {{event("dragstart")}} 이벤트 내에서 아래에서 설명하는 바와 같이 피드백 이미지(feedback image)나 드래그 효과와 그리고 드래그 데이터를 명시할 수 있습니다. 기본 이미지나 드래그 효과는 대부분의 상황에 적합하게 되어 있으며, 드래그 데이터만 필요합니다.

- -

데이터 드래그

- -

모든 {{domxref("DragEvent","drag events")}}는 드래그 데이터를 가지고 있는 {{domxref("DragEvent.dataTransfer","dataTransfer")}}라는 속성이 존재합니다 (dataTransfer는 {{domxref("DataTransfer")}} 객체입니다).

- -

드래그가 발생할 때, 데이터는 어떤 것이 드래그되는지를 구분할 수 있는 드래그와 연관되어야 합니다(When a drag occurs, data must be associated with the drag which identifies what is being dragged). 예를 들어, 선택된 텍스트가 드래그될 경우 드래그 데이터 항목에 연관된 데이터는 텍스트 자체입니다. 이와 유사하게, 웹 페이지 상의 링크가 드래그될 경우에 드래그 데이터 항목은 링크의 URL이됩니다.

- -

{{domxref("DataTransfer","drag data")}}는 두 가지 정보를 담고 있는데, 데이터의 유형(또는 형식)과 데이터 값입니다. 형식은 (텍스트 데이터에 해당하는 text/plain과 같은) 형식 문자열(type string) 값이고, 값은 텍스트의 문자열입니다. 드래그가 시작되면, 데이터와 형식을 제공하는 데이터를 추가해야 합니다. 드래그되는 동안, {{event("dragenter")}} 이벤트와 {{event("dragover")}} 이벤트에 대한 이벤트 리스너에서 드래그되는 데이터의 형식을 사용해 드랍이 허용되는지 확인할 수 있습니다. 예를 들어, 링크가 허용되는 드랍 대상(drop target)은 text/uri-list 형식의 링크인지 확인합니다. 드랍 이벤트 동안 리스너는 드래그 대상(being dragged)으로부터 데이터를 추출해 드랍되는 위치에 삽입합니다.

- -

{{domxref("DataTransfer","drag data's")}}의 {{domxref("DataTransfer.types","types")}} 속성은 text/plain or image/jpeg과 같은 {{domxref("DOMString")}} MIME-type 목록을 반환홥니다. 여러분은 자신만의 형식을 만들 수도 있습니다. 가장 흔하게 사용되는 형식은 권장 드래그 데이터 형식(Recommended Drag Types)에서 소개하고 있습니다.

- -

드래그에는 여러 가지 다른 형식의 데이터 항목이 포함될 수 있습니다. 이를 통해 사용자 정의 형식(custom types)과 같은 보다 특정한 형식의 데이터를 주로 제공하지만, 특정한 유형을 지원하지 않는 드롭 대상에 대해 대체 데이터(fallback data)를 제공할 수도 있습니다. text/plain 형식의 일반적인 텍스트 데이터가 가장 단순한 형식의 데이터일 것입니다.이 형식의 데이터는 단순히 텍스트 형식으로 표시될 것입니다.

- -

{{domxref("DragEvent.dataTransfer","dataTransfer")}} 내에 드래그 데이터 항목(drag data item)을 설정하기 위해서는 {{domxref("DataTransfer.setData","setData()")}} 메서드를 이용합니다. 이 메서드는 각각 데이터 형식과 데이터 값인 두 개의 인자가 필요합니다. 예를 들어:

- -
event.dataTransfer.setData("text/plain", "Text to drag");
-
- -

이 경우, 데이터 값은 "Text to drag"이고 형식은 text/plain입니다.

- -

여러 형식의 데이터를 제공할 수도 있습니다. 이를 위해서는 서로 다른 형식으로 {{domxref("DataTransfer.setData","setData()")}} 메서드를 여러 번 호출합니다. 이 때, 가장 세부적인 형식에서 덜 세부적인 형식의 순으로 호출해야 합니다.

- -
var dt = event.dataTransfer;
-dt.setData("application/x-bookmark", bookmarkString);
-dt.setData("text/uri-list", "http://www.mozilla.org");
-dt.setData("text/plain", "http://www.mozilla.org");
-
- -

여기서 데이터는 세가지 유형으로 추가됩니다. 첫번째 형식의 'application2x-bookmark'는 사용자 지정 형식입니다. 다른 응용 프로그램에서는 이 형식을 지원하지 않지만 동일한 사이트 또는 응용 프로그램의 영역 간 드래그할 경우, 이 사용자 지정 형식을 사용할 수 있습니다. 또한 다른 형식의 데이터를 제공함으로써 덜 세부적인 형태로 다른 애플리케이션으로의 드래그도 지원할 수 있습니다. 다른 형식이 하나의 URL또는 텍스트 형식만 제공할 때, 'application2x-bookmark' 형식은 해당 어플리케이션 내에서 사용될 경우 더 상세한 데이터를 제공할 수 있습니다

- -

이 예제에서 text/uri-listtext/plain은 동일한 데이터를 담고있음에 주목하시기 바랍니다. 이렇게 해도 되지만, 꼭 이럴 필요는 없습니다.

- -

동일한 형식으로 데이터를 두 번 추가하려고 하면 새로운 데이터가 기존 데이터를 대체하지만 형식 목록 내에서 이전 데이터(old data)와 같은 위치에 있게 됩니다.

- -

{{domxref("DataTransfer.clearData","clearData()")}} 메서드를 이용해 해당 데이터를 지울 수 있는데, 이 메서드는 지우고자 하는 데이터의 형식을 인자로 가집니다.

- -
event.dataTransfer.clearData("text/uri-list");
-
- -

{{domxref("DataTransfer.clearData","clearData()")}} 메서드에 대한 형식 인자는 선택적입니다. 형식을 지정하지 않으면 모든 형식과 연관된 데이터가 지워집니다. 드래그할 때, 드래그 데이터 항목이 없거나 이후에 모든 항목이 삭제되면 드래그가 발생하지 않습니다.

- -

드래그 피드백 이미지 설정

- -

드래그가 발생할 때, 드래그 대상("{{event("dragstart")}}" 이벤트가 발생한 요소)으로부터 반투명한 이미지가 생성되고 드래그 하는 동안 마우스 포인터를 따라 움직입니다. 이 이미지는 자동으로 생성되며, 따로 생성할 필요가 없습니다. 하지만, {{domxref("DataTransfer.setDragImage","setDragImage()")}}를 이용해 사용자 정의 드래그 피드백 이미지를 지정할 수 있습니다.

- -
event.dataTransfer.setDragImage(image, xOffset, yOffset);
-
- -

세 개의 인자는 필수입니다. 첫 번째 인자는 이미지에 대한 참조(reference)입니다. 이 참조는 일반적으로 이미지에 대한 참조이나 캔버스(canvas)나 다른 요소를 지정할 수도 있습니다. 피드백 이미지는 단순하게 화면에 표시된 이미지의 모양으로부터 생성되지만, 이미지의 경우 원래 크기로 그려집니다. {{domxref("DataTransfer.setDragImage","setDragImage()")}} 메서드의 두 번째와 세 번째 인자는 마우스 포인터에 대해 상대적인 옵셋(offsets)으로 이미지가 나타날 위치를 의미합니다.

- -

문서 내에 있지 않은 이미지나 캔버스를 사용하는 것 역시 가능합니다. 이 기법은 다음의 예제와 같이 캔버스 요소를 이용해 드래그 이미지를 사용자 정의 형태로 그리고자 할 때 유용합니다:

- -
function dragWithCustomImage(event) {
-  var canvas = document.createElementNS("http://www.w3.org/1999/xhtml","canvas");
-  canvas.width = canvas.height = 50;
-
-  var ctx = canvas.getContext("2d");
-  ctx.lineWidth = 4;
-  ctx.moveTo(0, 0);
-  ctx.lineTo(50, 50);
-  ctx.moveTo(0, 50);
-  ctx.lineTo(50, 0);
-  ctx.stroke();
-
-  var dt = event.dataTransfer;
-  dt.setData('text/plain', 'Data to Drag');
-  dt.setDragImage(canvas, 25, 25);
-}
-
- -

이 예제에서, 드래그 이미지를 표시할 캔버스를 하나 생성합니다. 캔버스는 너비가 와 높이가 모두 50 픽셀이고, 마우스 포인터가 이미지의 중앙에 위치하도록 옵셋(offsets)을 너비와 높이의 절반(25)으로 설정했습니다.

- -

{{h2_gecko_minversion("Using XUL panels as drag images", "9.0")}}

- -

Gecko 개발자일 경우 (Mozilla 어플리케이션 개발자든 add-on 개발자든 상관 없이), Gecko 9.0 {{geckoRelease("9.0")}}에 드래그 피드백 이미지로 XUL {{XULElem("panel")}} 요소를 사용할 수 있도록 하는 지원이 추가되었습니다. 간단히 {{XULElem("panel")}} 요소를 {{domxref("DataTransfer.setDragImage","setDragImage()")}} 메서드로 전달하기만 하면 됩니다.

- -

다음 XUL {{XULElem("panel")}}를 살펴보시기 바랍니다:

- -
<panel id="panel" style="opacity: 0.6">
-  <description id="pb">Drag Me</description>
-</panel>
-
-<vbox align="start" style="border: 1px solid black;" ondragstart="startDrag(event)">
-  <description>Drag Me</description>
-</vbox>
-
- -

위의 예에서 사용자가 {{XULElem("vbox")}}를 클릭하고 드래그하기 시작하면, 아래의 startDrag() 함수가 호출됩니다.

- -
function startDrag(event) {
-  event.dataTransfer.setData("text/plain", "<strong>Body</strong>");
-  event.dataTransfer.setDragImage(document.getElementById("panel"), 20, 20);
-}
-
- -

이 함수는 해당 패널을 드래그 이미지로 사용하고, HTML 형식의 "<strong>Body</strong>"을 데이터로 가집니다. 텍스트 편집기에 패널을 드랍하면 "Body"라는 텍스트가 드랍된 위치에 삽입됩니다.

- -

드래그 효과

- -

드래그할 때, 여러 가지 작업이 수행될 수 있습니다. copy 작업은 드래그되는 데이터가 현재 위치에서 드랍되는 위치로 복사될 것임을 나타냅니다. move 작업은 드래그되는 데이터가 이동될 것임을 나타내고, link 작업은 특정 형태의 관계(relationship)나 연결(connection)이 소스와 드랍되는 위치 사이에 생성될 것임을 나타냅니다.

- -

드래그 소스(drag source)에 대해 {{event("dragstart")}} 이벤트 리스너의 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 설정함으로써, 이 세 가지 작업 중 어떤 것을 허용할 것인지를 지정할 수 있습니다.

- -
event.dataTransfer.effectAllowed = "copy";
-
- -

이 예제에서는, 복사만 허용됩니다. 다양한 방식으로 값을 조합할 수 있습니다:

- -
-
none
-
어떤 작업도 허용하지 않음.
-
copy
-
복사만 허용
-
move
-
이동만 허용
-
link
-
연결만 허용
-
copyMove
-
복사 또는 이동만 허용
-
copyLink
-
복사 또는 연결만 허용
-
linkMove
-
연결 또는 이동만 허용
-
all
-
복사, 이동 및 연결 모두 허용
-
- -

이 값들은 반드시 위에 나열한 것과 정확하게 일치해야 함에 유의하시기 바랍니다. 예를 들어, {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 copyMove로 설정하면 복사와 이동 작업이 허용되나 연결(link) 작업은 금지됩니다. {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 변경하지 않으면 'all' 값과 마찬가지로 어떤 작업도 허용됩니다. 따라서, 특정한 유형의 작업을 제외시키고 싶지 않다면 이 속성을 조정할 필요가 없습니다.

- -

드래그 작업 중에 {{event("dragenter")}} 또는 {{event("dragover")}} 이벤트에 대한 리스너는 어떤 작업이 허용되어 있는지 알기 위해 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성을 확인할 수 있습니다. 관련된 속성으로, {{domxref("DataTransfer.dropEffect","dropEffect")}}는 이들 이벤트 중 하나에서 수행되어야 하는 단일 작업을 지정하기 위해 설정되어야 할 속성입니다. {{domxref("DataTransfer.dropEffect","dropEffect")}}에 유효한 값은 none, copy, move, 또는 link입니다. 이 속성에 값의 조합은 허용되지 않습니다.

- -

{{event("dragenter")}}나 {{event("dragover")}} 이벤트가 발생하면 사용자가 요청하는 효과로 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성이 초기화됩니다. 사용자는 한정자 키를 눌러 원하는 효과로 수정할 수 있습니다. 플랫폼에 따라 정확한 키가 달라질 수 있지만, 일반적으로 쉬프트(Shift)와 컨트롤(Control) 키가 복사하기, 이동하기, 연결하기 간 전환에 사용됩니다. 마우스 포인터를 원하는 작업을 나타내도록 변경할 수 있습니다; 예를 들어, 복사 작업에 대해서는 마우스 포인터 옆에 더하기 기호가 표시된 커서가 나타날 수 있습니다.

- -

{{event("dragenter")}} 또는 {{event("dragover")}} 이벤트가 발생하는 동안 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 변경할 수 있는데, 예를 들자면, 특정 작업만 지원되는 특수한 드랍 대상(drop target)일 경우가 그렇습니다. {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 수정하여 사용자 효과(user effect)를 오버라이드하여 특정한 드랍 작업이 발생하게 할 수 있습니다. 이 효과는 {{domxref("DataTransfer.effectAllowed","effectAllowed")}} 속성에 열거된 것 중의 하나 이어야 함에 유의하시기 바랍니다. 그렇지 않을 경우, 허용되는 대체 값으로 설정되게 됩니다.

- -
event.dataTransfer.dropEffect = "copy";
-
- -

이 예제에서는 복사가 수행될 효과입니다.

- -

이 경우에는 이벤트를 취소하지 않는 것이 좋지만 none 값을 사용하여 이 위치에서 드롭이 허용되지 않음을 나타낼 수 있습니다.

- -

{{event("drop")}}{{event("dragend")}} 이벤트 내에서{{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 확인하면 최종적으로 어떤 효과가 선택되었는지를 알 수 있습니다. 선택된 효과가 "move"였다면, {{event("dragend")}} 이벤트 내에서 드래그 소스의 원본 데이터가 삭제되어야 합니다.

- -

드랍 대상 지정하기

- -

{{event("dragenter")}}{{event("dragover")}} 이벤트에 대한 리스너는 유효한 드랍 대상인지, 즉 드래그된 아이템이 드랍될 수 있는 곳인지를 나타내는데 사용할 수 있습니다. 웹 페이지 또는 어플리케이션의 대부분의 영역은 데이터를 드랍할 수 있는 유효한 영역이 아닙니다. 따라서, 이들 이벤트에 대한 기본적인 처리는 드랍을 허용하지 않는 것입니다.

- -

드랍을 허용하길 원한다면, 해당 이벤트를 취소하는 기본 처리를 막아야 합니다. 속성 정의(attribute-defined) 이벤트 리스너로부터 false를 반환 받거나 해당 이벤트의 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하면 됩니다. 후자는 별도의 스크립트에 정의된 함수에 더 적합합니다.

- -
<div ondragover="return false">
-<div ondragover="event.preventDefault()">
-
- -

{{event("dragenter")}} and {{event("dragover")}} 두 이벤트 모두에서 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하는 것은 그 위치에 드랍이 허용되는 것을 나타냅니다. 하지만, 일반적으로 특정한 상황에서만, 예를 들자면 링크가 드래그될 때만 {{domxref("Event.preventDefault","preventDefault()")}} 메서드를 호출하길 원할 것입니다. 이렇게 하기 위해서는 조건을 확인하여 조건이 충족될 때에만 해당 이벤트를 취소하는 함수를 호출합니다. 조건이 충족되지 않을 경우, 이벤트를 취소하지 않으면 사용자가 마우스 버튼을 놓더라도 드랍은 발생하지 않을 것입니다.

- -

data transfer의 드래그 데이터 형식에 따라 드랍을 허용하거나 기각하는 경우가 대부분일 것입니다(예를 들어, 이미지나 링크를 허용하거나 둘 다 허용하는 경우). 이렇게 하기 위해서는 이벤트의 {{domxref("DragEvent.dataTransfer","dataTransfer")}} 속성의 {{domxref("DataTransfer.types","types")}} 속성을 확인합니다. {{domxref("DataTransfer.types","types")}} 속성은 드래그가 시작될 때 추가된 형식 문자열의 배열을 반환하는데, 그 순서는 가장 세부적인 형식에서 가장 덜 세부적인 형식의 순서입니다.

- -
function contains(list, value) {
-    for( var i = 0; i < list.length; ++i ) {
-        if(list[i] === value) return true;
-    }
-    return false;
-}
-
-function doDragOver(event) {
-  var isLink = contains( event.dataTransfer.types, "text/uri-list");
-  if (isLink) {
-    event.preventDefault();
-  }
-}
- -

이 예제에서 형식 목록 내에 text/uri-list 형식이 존재하는지 확인하기 위해 contains 메서드를사용합니다. 존재할 경우에는 드랍을 허용하기 위해 이벤트가 취소될 것입니다. 드래그 데이터가 링크를 포함하지 않았다면, 해당 이벤트는 취소되지 않을 것이고 그 위치에 대한 드랍이 발생하지 않을 것입니다.

- -

수행되어야 하는 작업 형식을 더 세부적으로 설정하길 원한다면, {{domxref("DataTransfer.effectAllowed","effectAllowed")}}나 {{domxref("DataTransfer.dropEffect","dropEffect")}} 속성을 각각 설정하거나 동시에 둘 다를 설정하고 싶을 것입니다. 두 속성을 변경하더라도 해당 이벤트를 취소하지 않으면 아무런 영향이 없을 것입니다.

- -

Updates to DataTransfer.types

- -

최신 스펙에는 {{domxref("DataTransfer.types")}}이 {{domxref("DOMStringList")}}(이 속성은 Fiirefox 52 이상에서 지원됨)이 아닌 {{domxref("DOMString")}} 형식의 고정배열(fronzen array)을 반환하도록 명시하고 있음에 유의하시기 바랍니다.

- -

그 결과로, contains 메서드는 해당 속성에 대해 더 이상 동작하지 않으며; 특정 형식의 데이터가 제공되는지 확인하기 위해서는 다음 코드와 같이 includes 메서드를 사용해야 합니다:

- -
if ([...event.dataTransfer.types].includes('text/html')) {
-  // Do something
-}
- -

일부 특성 검출(feature detection)을 이용해 types에 대해 어떤 메서드가 지원되는지를 판별하고 적절하게 코드를 실행할 수 있습니다.

- -

Drop Feedback

- -

There are several ways in which you can indicate to the user that a drop is allowed at a certain location. The mouse pointer will update as necessary depending on the value of the {{domxref("DataTransfer.dropEffect","dropEffect")}} property. Although the exact appearance depends on the user's platform, typically a plus sign icon will appear for a 'copy' for example, and a 'cannot drop here' icon will appear when a drop is not allowed. This mouse pointer feedback is sufficient in many cases.

- -

However, you can also update the user interface with an insertion point or highlight as needed. For simple highlighting, you can use the -moz-drag-over CSS pseudoclass on a drop target.

- -
.droparea:-moz-drag-over {
-  border: 1px solid black;
-}
-
- -

In this example, the element with the class droparea will receive a 1 pixel black border while it is a valid drop target, that is, if the {{domxref("Event.preventDefault","preventDefault()")}} method was called during the {{event("dragenter")}} event. Note that you must cancel the {{event("dragenter")}} event for this pseudoclass to apply, as this state is not checked for the {{event("dragover")}} event.

- -

For more complex visual effects, you can also perform other operations during the {{event("dragenter")}} event, for example, by inserting an element at the location where the drop will occur. For example, this might be an insertion marker or an element that represents the dragged element in its new location. To do this, you could create an image or separator element, for example, and simply insert it into the document during the {{event("dragenter")}} event.

- -

The {{event("dragover")}} event will fire at the element the mouse is pointing at. Naturally, you may need to move the insertion marker around a {{event("dragover")}} event as well. You can use the event's {{domxref("MouseEvent.clientX","clientX")}} and {{domxref("MouseEvent.clientY","clientY")}} properties as with other mouse events to determine the location of the mouse pointer.

- -

Finally, the {{event("dragleave")}} event will fire at an element when the drag leaves the element. This is the time when you should remove any insertion markers or highlighting. You do not need to cancel this event. Any highlighting or other visual effects specified using the -moz-drag-over pseudoclass will be removed automatically. The {{event("dragleave")}} event will always fire, even if the drag is cancelled, so you can always ensure that any insertion point cleanup can be done during this event.

- -

Performing a Drop

- -

When the user releases the mouse, the drag and drop operation ends. If the mouse was released over an element that is a valid drop target, that is, one that cancelled the last {{event("dragenter")}} or {{event("dragover")}} event, and then the drop will be successful, and a {{event("drop")}} event will fire at the target. Otherwise, the drag operation is cancelled, and no {{event("drop")}} event is fired.

- -

During the {{event("drop")}} event, you should retrieve that data that was dropped from the event and insert it at the drop location. You can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine which drag operation was desired.

- -

As with all drag-related events, the event's {{domxref("DataTransfer","dataTransfer")}} property will hold the data that is being dragged. The {{domxref("DataTransfer.getData","getData()")}} method may be used to retrieve the data again.

- -
function onDrop(event) {
-  var data = event.dataTransfer.getData("text/plain");
-  event.target.textContent = data;
-  event.preventDefault();
-}
-
- -

The {{domxref("DataTransfer.getData","getData()")}} method takes one argument, the type of data to retrieve. It will return the string value that was set when {{domxref("DataTransfer.setData","setData()")}} was called at the beginning of the drag operation. An empty string will be returned if data of that type does not exist. Naturally, though, you would likely know that the right type of data was available, as it was previously checked during a {{event("dragover")}} event.

- -

In the example here, once we have retrieved the data, we insert the string as the textual content of the target. This has the effect of inserting the dragged text where it was dropped, assuming that the drop target is an area of text such as a p or div element.

- -

In a web page, you should call the {{domxref("Event.preventDefault","preventDefault()")}} method of the event if you have accepted the drop so that the default browser handling does not handle the dropped data as well. For example, when a link is dragged to a web page, Firefox will open the link. By cancelling the event, this behavior will be prevented.

- -

You can retrieve other types of data as well. If the data is a link, it should have the type text/uri-list. You could then insert a link into the content.

- -
function doDrop(event) {
-  var lines = event.dataTransfer.getData("text/uri-list").split("\n");
-  for (let line of lines) {
-    if (line.startsWith("#"))
-      continue;
-
-    let link = document.createElement("a");
-    link.href = line;
-    link.textContent = line;
-    event.target.appendChild(link);
-  }
-  event.preventDefault();
-}
-
- -

This example inserts a link from the dragged data. As you might be able to guess from the name, the text/uri-list type actually may contain a list of URLs, each on a separate line. In this code, we use the split to split the string into lines, then iterate over the list of lines, inserting each as a link into the document. Note also that we skip links starting with a number sign (#) as these are comments.

- -

For simple cases, you can use the special type URL just to retrieve the first valid URL in the list. For example:

- -
var link = event.dataTransfer.getData("URL");
-
- -

This eliminates the need to check for comments or iterate through lines yourself; however, it is limited to only the first URL in the list.

- -

The URL type is a special type used only as a shorthand, and it does not appear within the list of types specified in the {{domxref("DataTransfer.types","types")}} property.

- -

Sometimes you may support some different formats, and you want to retrieve the data that is most specific that is supported. In this example, three formats are supported by a drop target.

- -

The following example returns the data associated with the best-supported format:

- -
function doDrop(event) {
-  var types = event.dataTransfer.types;
-  var supportedTypes = ["application/x-moz-file", "text/uri-list", "text/plain"];
-  types = supportedTypes.filter((value) => types.includes(value));
-  if (types.length)
-    var data = event.dataTransfer.getData(types[0]);
-  event.preventDefault();
-}
-
- -

This method relies on JavaScript functionality available in Firefox 3. However, the code could be adjusted to support other platforms.

- -

Finishing a Drag

- -

Once the drag is complete, a {{event("dragend")}} event is fired at the source of the drag (the same element that received the {{event("dragstart")}} event). This event will fire if the drag was successful[1] or if it was cancelled. However, you can use the {{domxref("DataTransfer.dropEffect","dropEffect")}} property to determine what drop operation occurred.

- -

If the {{domxref("DataTransfer.dropEffect","dropEffect")}} property has the value none during a {{event("dragend")}}, then the drag was cancelled. Otherwise, the effect specifies which operation was performed. The source can use this information after a move operation to remove the dragged item from the old location. The {{domxref("DataTransfer.mozUserCancelled","mozUserCancelled")}} property will be set to true if the user cancelled the drag (by pressing Escape), and false if the drag was cancelled for other reasons such as an invalid drop target, or if it was successful.

- -

A drop can occur inside the same window or over another application. The {{event("dragend")}} event will always fire regardless. The event's {{domxref("MouseEvent.screenX","screenX")}} and {{domxref("MouseEvent.screenY","screenY")}} properties will be set to the screen coordinate where the drop occurred.

- -

After the {{event("dragend")}} event has finished propagating, the drag and drop operation is complete.

- -

[1] In Gecko, {{event("dragend")}} is not dispatched if the source node is moved or removed during the drag (e.g. on drop or {{event("dragover")}}).  bug 460801

- -

See also

- - diff --git "a/files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/index.html" "b/files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/index.html" deleted file mode 100644 index 70a4295284..0000000000 --- "a/files/ko/web/api/html_\353\223\234\353\236\230\352\267\270_\354\225\244_\353\223\234\353\241\255_api/index.html" +++ /dev/null @@ -1,303 +0,0 @@ ---- -title: HTML 드래그 앤 드롭 API -slug: Web/API/HTML_드래그_앤_드롭_API -tags: - - HTML5 - - XUL - - 가이드 - - 개요 - - 고급 - - 드래그 앤 드롭 - - 이벤트 -translation_of: Web/API/HTML_Drag_and_Drop_API ---- -

{{DefaultAPISidebar("HTML 드래그 앤 드롭 API")}}

- -

HTML 드래그 앤 드롭 인터페이스는 파이어폭스와 다른 브라우저에서 어플리케이션이 드래그 앤 드롭 기능을 사용하게 해줍니다. 이 기능을 이용해 사용자는 draggable 요소를 마우스로 선택해 droppable 요소로 드래그하고, 마우스 버튼에서 손을 뗌으로써 요소를 드롭할 수 있습니다. 드래그하는 동안 draggable 요소는 반투명한 채로 마우스 포인터를 따라다닙니다.

- -

웹 사이트나 확장 기능, XUL 어플리케이션을 위해, 다양한 요소를 draggable 요소로 만들 수 있고, 이벤트에 대한 draggable 요소의 반응들을 만들어내거나 droppable 요소를 자유자재로 만들 수 있습니다.

- -

이 문서는 HTML 드래그 앤 드롭에 대한 전반적인 개요입니다. 인터페이스에 대한 설명과 드래그 앤 드롭 기능을 어플리케이션에서 사용하기 위한 기본적인 절차, 인터페이스의 상호 운용성에 대한 요약 등이 이 문서에 담겨있습니다.

- -

드래그 이벤트

- -

HTML 드래그 앤 드롭은 {{domxref("Event","DOM event model")}} 과 {{domxref("DragEvent","drag events")}}   {{domxref("MouseEvent","mouse events")}} 로부터 상속받습니다. 보통 드래그는 사용자가 draggable 요소를 마우스로 선택하고, 마우스 포인터를 droppable 요소로 가져가 마우스 버튼을 때는 것으로 이루어집니다. 드래그하는 도중에 많은 이벤트가 발생하고, 몇몇 이벤트는 여러번 발생하기도 합니다. ( {{event("drag")}}와 {{event("dragover")}}).

- -

모든 드래그 이벤트글로벌 이벤트 핸들러와 연결되어 있습니다. 각 드래그 이벤트와 드래그 전역 속성은 참조 문서를 가지고 있습니다. 아래 표는 각 이벤트에 대한 간략한 설명과 참조 문서로의 링크를 담고 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
이벤트이벤트 핸들러설명
{{domxref('Document/drag_이벤트', 'drag')}}{{domxref('GlobalEventHandlers.ondrag','ondrag')}}요소나 텍스트 블록을 드래그 할 때 발생한다.
{{event('dragend')}}{{domxref('GlobalEventHandlers.ondragend','ondragend')}} -

드래그를 끝냈을 때 발생한다. (마우스 버튼을 떼거나 ESC 키를 누를 때) (드래그 끝내기를 보시오)

-
{{event('dragenter')}}{{domxref('GlobalEventHandlers.ondragenter','ondragenter')}} -

드래그한 요소나 텍스트 블록을 적합한 드롭 대상위에 올라갔을 때 발생한다. (드롭 대상 지정하기를 보시오.)

-
{{event('dragexit')}}{{domxref('GlobalEventHandlers.ondragexit','ondragexit')}} -

요소가 더 이상 드래그의 직접적인 대상이 아닐 때 발생한다.

-
{{event('dragleave')}}{{domxref('GlobalEventHandlers.ondragleave','ondragleave')}} -

드래그하는 요소나 텍스트 블록이 적합한 드롭 대상에서 벗어났을 때 발생한다.

-
{{event('dragover')}}{{domxref('GlobalEventHandlers.ondragover','ondragover')}} -

요소나 텍스트 블록을 적합한 드롭 대상 위로 지나갈 때 발생한다. (매 수백 밀리초마다 발생한다.)

-
{{event('dragstart')}}{{domxref('GlobalEventHandlers.ondragstart','ondragstart')}} -

사용자가 요소나 텍스트 블록을 드래그하기 시작했을 때 발생한다. (드래그 시작하기를 보시오.)

-
{{event('drop')}}{{domxref('GlobalEventHandlers.ondrop','ondrop')}} -

요소나 텍스트 블록을 적합한 드롭 대상에 드롭했을 때 발생한다. (드롭하기를 보시오.)

-
- -

참고: dragstartdragend 이벤트는 파일을 브라우저로 드래그할 때는 발생하지 않습니다.

- -

인터페이스

- -

HTML 드래그와 드롭 인터페이스는 {{domxref("DragEvent")}}, {{domxref("DataTransfer")}}, {{domxref("DataTransferItem")}}, {{domxref("DataTransferItemList")}} 입니다.

- -

{{domxref("DataTransfer")}} 객체는 드래그 형태나 드래그 데이터 (하나 이상의 아이템), 각 드래그 아이템의 종류 (MIME 종류) 와 같은 드래그 이벤트의 상태를 담고 있습니다. {{domxref("DataTransfer")}} 는 또한 드래그 데이터에 아이템을 추가하거나 제거하는 메소드를 가지고 있습니다. The {{domxref("DragEvent")}} 와 {{domxref("DataTransfer")}} 인터페이스만 있으면 어플리케이션에 HTML 드래그 앤 드롭 기능을 추가할 수 있습니다. 참고로 파이어폭스는 {{domxref("DataTransfer")}}에 {{anch("Gecko specific interfaces","Gecko-specific extensions")}} 와 같은 파이어폭스에서만 동작하는 추가적인 확장을 제공합니다. 

- -

{{domxref("DataTransfer")}}는 {{domxref("DataTransferItem")}}의 {{domxref("DataTransferItemList","목록")}} 인 {{domxref("DataTransfer.items","items")}} 프로퍼티를 가지고 있습니다. 각 {{domxref("DataTransferItem")}} 는 하나의 드래그 아이템을 나타내고 각 아이템은 데이터의 종류 (string 혹은 file) 를 나타내는 {{domxref("DataTransferItem.kind","kind")}} 프로퍼티와 데이터 아이템의 종류 (MIME 종류) 를 나타내는 {{domxref("DataTransferItem.type","type")}} 프로퍼티를 가집니다. {{domxref("DataTransferItem")}}은 드래그 아이템의 데이터를 가져오는 메소드를 제공합니다.

- -

{{domxref("DataTransferItemList")}} 객체는 {{domxref("DataTransferItem")}}의 리스트입니다. 이 리스트 객체는 세 개의 메소드 - 드래그 아이템을 리스트에 추가하거나, 리스트에서 아이템을 삭제하거나, 모든 드래그 아이템을 리스트에서 삭제하는 메소드 - 를 가집니다.

- -

A key difference between the {{domxref("DataTransfer")}} and {{domxref("DataTransferItem")}} interfaces is that the former uses the synchronous {{domxref("DataTransfer.getData","getData()")}} method to access a drag item's data, whereas the later uses the asynchronous {{domxref("DataTransferItem.getAsString","getAsString()")}} method to access a drag item's data.

- -

{{domxref("DataTransfer")}}와 {{domxref("DataTransferItem")}}의 가장 중요한 차이점은 전자는 드래그 아이템의 데이터에 접근하기 위해 동기 메소드인 {{domxref("DataTransfer.getData","getData()")}}를 사용하는데 반해, 후자는 비동기 메소드인 {{domxref("DataTransferItem.getAsString","getAsString()")}}를 사용한다는 점입니다.

- -

참고: {{domxref("DragEvent")}} and {{domxref("DataTransfer")}}는 여러 데스크탑 브라우저에서 폭넓게 지원하고 있습니다. 하지만 {{domxref("DataTransferItem")}}와 {{domxref("DataTransferItemList")}}는 제한적으로 사용 가능합니다. 드래그 앤 드롭의 상호 운용성에 대한 더 많은 정보를 찾아보기 위해 {{anch("Interoperability")}}를 보십시오.

- -

Gecko 한정 인터페이스

- -

모질라와 파이어폭스는 표준 드래그 앤 드롭 모델에서 제공하지 않는 몇가지 기능들을 추가로 제공합니다. 여러 개의 아이템을 동시에 드래그하거나 파일과 같이 문자열이 아닌 데이터를 드래그 하기 위한 여러 편리한 기능을 제공합니다. 더 많은 정보를 찾아보기 위해, Dragging and Dropping Multiple Items을 보십시오. 덧붙여, 모든 Gecko 한정 프로퍼티나 Gecko 한정 메소드를 찾아보기 위해 {{domxref("DataTransfer")}} 참조 페이지도 보시기 바랍니다.

- -

기본

- -

이번 절은 드래그 앤 드롭 기능을 추가하기 위한 기본적인 방법을 요약하고 있습니다. 각 절은 단계를 설명하고, 짧은 코드 예제와 추가적인 정보를 위한 링크를 포함합니다.

- -

어떤 것이 draggable인지 확인하기

- -

하나의 요소를 draggable로 만들기 위해서는 {{htmlattrxref("draggable")}}와 {{domxref("GlobalEventHandlers.ondragstart","ondragstart")}} 전역 이벤트 핸들러를 아래 예제 코드와 같이 추가해야합니다.

- -
function dragstart_handler(ev) {
- console.log("dragStart");
- // 데이터 전달 객체에 대상 요소의 id를 추가합니다.
- ev.dataTransfer.setData("text/plain", ev.target.id);
-}
-
-
- -
<script>
-  function dragstart_handler(ev) {
-    // 데이터 전달 객체에 대상 요소의 id를 추가합니다.
-    ev.dataTransfer.setData("text/plain", ev.target.id);
-  }
-
-  window.addEventListener('DOMContentLoaded', () => {
-    // id를 통해 element를 가져옵니다.
-    const element = document.getElementById("p1");
-    // 'dragstart' 이벤트 리스터를 추가합니다.
-    element.addEventListener("dragstart", dragstart_handler);
-  });
-</script>
-
-<p id="p1" draggable="true">This element is draggable.</p>
- -

추가 정보를 위해 draggable attribute referenceDrag operations guide를 참고하세요.

- -

드래그 데이터 정의하기

- -

드래그할 때 자유롭게 데이터 아이템을 포함할 수 있습니다. 각 데이터 아이템은 특정 type의 {{domxref("DOMString","문자열")}}이며, 보통 text/html와 같은 MIME type입니다.

- -

각 {{domxref("DragEvent","drag event")}} 은 이벤트 데이터를 가지고 있는 {{domxref("DragEvent.dataTransfer","dataTransfer")}} 를 가집니다. 이 프로퍼티는 ({{domxref("DataTransfer")}} 객체) 드래그 데이터를 관리하는 메소드를 가집니다. {{domxref("DataTransfer.setData","setData()")}} 는 아래 코드 예제와 같이 아이템을 드래그 데이터에 추가할 때 사용합니다.

- -
function dragstart_handler(ev) {
-  // 드래그 데이터를 추가합니다.
-  ev.dataTransfer.setData("text/plain", ev.target.id);
-  ev.dataTransfer.setData("text/html", "<p>Example paragraph</p>");
-  ev.dataTransfer.setData("text/uri-list", "http://developer.mozilla.org");
-}
-
- -

드래그 앤 드롭에 사용할 수 있는 공통 데이터 타입 (텍스트, HTML, 링크, 파일 등) 의 목록을 보려면, Recommended Drag Types를 참고하십시오. 드래그 데이터에 대한 추가적인 정보를 위해서는 Drag Data를 참고하십시오.

- -

드래그 이미지 정의하기

- -

브라우저는 드래그 하는 동안 마우스 포인터 옆에 나타나는 이미지를 기본적으로 제공합니다. 어플리케이션에서 다른 이미지를 사용하기 원한다면 아래 예제와 같이 {{domxref("DataTransfer.setDragImage","setDragImage()")}}를 사용할 수 있습니다.

- -
function dragstart_handler(ev) {
-  // 드래그 이미지로 사용할 이미지를 만듭니다.
-  // 참고: "example.gif"를 존재하는 이미지로 바꾸지 않으면 기본 드래그 이미지를 사용합니다.
-  var img = new Image();
-  img.src = 'example.gif';
-  ev.dataTransfer.setDragImage(img, 10, 10);
-}
-
- -

드래그 이미지에 대해 더 알아보려면, Setting the Drag Feedback Image를 참고하세요.

- -

드래그 효과 정의하기

- -

{{domxref("DataTransfer.dropEffect","dropEffect")}} 프로퍼티는 드래그 앤 드롭 도중에 사용자에게 피드백 (보통 시각적인) 을 제공하기 위해 사용합니다. 브라우저가 드래그 하는 동안 어떤 마우스 포인터를 보여줄 지 결정합니다. 사용자가 마우스 포인터를 대상 드롭 요소에 올려놓으면, 브라우저는 드래그 효과에 적합한 마우스 포인터를 보여줄 것입니다.

- -

세 개의 효과가 정의되어 있습니다:

- -

copy는 현재 위치에서 드롭하는 위치로 데이터가 복사될 것을 암시합니다.

- -

move는 현재 위치에서 드롭하는 위치로 데이터가 이동할 것을 암시합니다.

- -

link는 드래그하는 위치와 드롭하는 위치 간의 일종의 관계나 연결이 맺어진 다는 것을 암시합니다.

- -

특정 위치에서는 특정 효과가 허용된다는 것을 알려주기 위해 드래그 하는 도중에 효과가 변할 수 있습니다. 허용되는 경우에만 해당 위치에 드롭할 수 있습니다.

- -

다음 예제는 어떻게 이 프로퍼티를 사용하는지 보여줍니다.

- -
function dragstart_handler(ev) {
-  // 드래그 효과를 copy로 지정합니다.
-  ev.dataTransfer.dropEffect = "copy";
-}
-
- -

더 자세한 설명은 Drag Effects를 참고하세요.

- -

드롭 지역 정의하기

- -

기본적으로는 브라우저는 HTML 요소에 뭔가를 드롭했을 때 아무 일도 일어나지 않도록 합니다. 특정 요소가 드롭 지역 혹은 droppable로 만들기 위해서는 해당 요소가 {{domxref("GlobalEventHandlers.ondragover","ondragover")}}와 {{domxref("GlobalEventHandlers.ondrop","ondrop")}} 이벤트 핸들러 속성을 가져야합니다. 아래 예제는 두 요소를 어떻게 사용하고, 각 요소에 포함된 기본적인 이벤트 핸들러를 보여줍니다.

- -
<script>
-function dragover_handler(ev) {
- ev.preventDefault();
- // dropEffect를 move로 설정.
- ev.dataTransfer.dropEffect = "move";
-}
-function drop_handler(ev) {
- ev.preventDefault();
- // 대상의 id를 가져와 대상 DOM에 움직인 요소를 추가합니다.
- const data = ev.dataTransfer.getData("text/plain");
- ev.target.appendChild(document.getElementById(data));
-}
-</script>
-
-<p id="target" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Zone</p>
- -

각 핸들러는 {{domxref("Event.preventDefault","preventDefault()")}} 를 호출해 추가적인 이벤트 (터치 이벤트나 포인터 이벤트) 가 일어나지 않도록 합니다.

- -

추가적인 정보는, Specifying Drop Targets를 참고하세요.

- -

드롭 효과 다루기

- -

{{event("drop")}} 이벤트 핸들러는 자유롭게 드래그 데이터를 가공할 수 있습니다. 보통, 드래그 아이템과 각 아이템을 가공하기 위해 {{domxref("DataTransfer.getData","getData()")}}를 사용합니다. 추가로, {{domxref("DataTransfer.dropEffect","dropEffect")}} 값이나 보조키 상태에 따라 어플리케이션이 어떻게 동작할지를 결정할 수 있습니다.

- -

아래 예제는 드롭 핸들러가 드래그 데이터로부터 드래그하는 요소의 id를 가져와 드래그하는 요소를 드롭하는 요소로 옮기기위해 사용합니다.

- -
<script>
-function dragstart_handler(ev) {
- // 데이터 전달 객체에 대상 요소의 id를 추가합니다.
- ev.dataTransfer.setData("application/my-app", ev.target.id);
- ev.dataTransfer.dropEffect = "move";
-}
-function dragover_handler(ev) {
- ev.preventDefault();
- ev.dataTransfer.dropEffect = "move"
-}
-function drop_handler(ev) {
- ev.preventDefault();
- // 대상의 id를 가져와 이동한 대상 DOM 요소를 추가합니다.
- // Get the id of the target and add the moved element to the target's DOM
- const data = ev.dataTransfer.getData("application/my-app");
- ev.target.appendChild(document.getElementById(data));
-}
-</script>
-
-<p id="p1" draggable="true" ondragstart="dragstart_handler(event)">This element is draggable.</p>
-<div id="target" ondrop="drop_handler(event)" ondragover="dragover_handler(event)">Drop Zone</div>
- -

더 많은 정보를 위해 Performing a Drop을 보십시오.

- -

드래그가 끝나면

- -

드래그가 끝나면 드래그한 요소에 {{event("dragend")}} 이벤트가 발생합니다. 이 이벤트는 드래그가 완료되거나 중간에 취소되어도 발생합니다. {{event("dragend")}} 이벤트 핸들러는 {{domxref("DataTransfer.dropEffect","dropEffect")}} 프로퍼티를 확인해 드래그가 성공했는지를 확인할 수 있습니다.

- -

드래그 끝을 다루기 위한 더 많은 정보는 Finishing a Drag를 참고하세요. 

- -

상호 운용성

- -

DataTransferItem interface's Browser Compatibility table에 나온 대로, 드래그 앤 드롭은 상대적으로 여러 데스크톱 브라우저에서 폭넓게 사용할 수 있습니다 ({{domxref("DataTransferItem")}}는 {{domxref("DataTransferItemList")}} 덜 지원하지만). 또한 모바일 브라우저에서는 매우 한정적으로 사용할 수 있습니다.

- -

예제와 데모

- - - -

명세서 

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "#dnd")}}{{Spec2('HTML WHATWG')}}
- -

더보기

- - diff --git a/files/ko/web/api/htmlelement/accesskey/index.html b/files/ko/web/api/htmlelement/accesskey/index.html new file mode 100644 index 0000000000..0fc48bd749 --- /dev/null +++ b/files/ko/web/api/htmlelement/accesskey/index.html @@ -0,0 +1,35 @@ +--- +title: Element.accessKey +slug: Web/API/Element/accessKey +tags: + - API + - Access Keys + - DOM + - Hotkeys + - NeedsContent + - 레퍼런스 + - 속성 + - 엘리먼트 + - 키보드 단축키 +translation_of: Web/API/HTMLElement/accessKey +translation_of_original: Web/API/Element/accessKey +--- +
{{APIRef("DOM")}}
+ +

Element.accessKey 속성은 주어진 사용자가 눌러 주어진 엘리먼트로 이동할 수 있는 키 입력 세트입니다.

+ +
+

Element.accessKey 속성은 브라우저에 이미 바인딩 된 키와의 여러 충돌로 인해 거의 사용되지 않습니다. 이를 해결하기 위해, 브라우저는 다른 "적절한" 키(예, Alt + accesskey)와 함께 키가 눌렸을 때동작하도록 구현하였습니다.

+
+ +

브라우저 호환성

+ + + +

{{Compat("api.Element.accessKey")}}

+ +

함께 보기

+ + diff --git a/files/ko/web/api/htmlelement/dataset/index.html b/files/ko/web/api/htmlelement/dataset/index.html deleted file mode 100644 index 2b2a891dca..0000000000 --- a/files/ko/web/api/htmlelement/dataset/index.html +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: HTMLElement.dataset -slug: Web/API/HTMLElement/dataset -tags: - - API - - HTML DOM - - HTMLElement - - HTMLOrForeignElement - - Property - - Read-only - - Reference -translation_of: Web/API/HTMLOrForeignElement/dataset ---- -
{{APIRef("HTML DOM")}}
- -

HTMLElement.dataset 읽기 전용 속성은 요소의 사용자 지정 데이터 특성(data-*)에 대한 읽기와 쓰기 접근 방법을 HTML과 DOM 양측에 제공합니다. 반환하는 값은 {{domxref("DOMStringMap")}}으로, 각 데이터 특성마다 하나의 항목을 가집니다. dataset 속성 자체는 읽기 전용이라는 점에 주의하세요. 모든 쓰기 작업은 dataset 안의, 데이터 특성을 나타내는 각각의 속성에 수행해야 합니다. 또한 HTML의 data-이름과, 이에 대응하는 DOM dataset['이름']이름은 서로 일치하지 않으나, 다음 규칙에 따라 유사함을 기억하세요.

- - - -

아래의 내용과 함께, Using data attributes 아티클에서는 HTML 데이터 속성을 어떻게 쓰는지 안내를 찾을 수 있습니다. 

- -

Name conversion

- -

dash-style 에서 camelCase로 변환: 커스텀 데이터 속성의 이름은 아래의 규칙에 따라 {{ domxref("DOMStringMap") }}의 key로 변환됩니다. 

- - - -

camelCase 에서 dash-style로 변환: key를 속성 이름으로 매핑하는 반대의 변환은 아래의 규칙을 따릅니다.:

- - - -

이러한 제약 조건은 반드시 두 변환이 서로의 역이 되도록 합니다.

- -

예를 들어, data-abc-def 라는 이름의 속성은 abcDef 라는 키에 대응합니다.

- -

Accessing values

- - - -

Syntax

- - - -

예시

- -
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
- -
const el = document.querySelector('#user');
-
-// el.id === 'user'
-// el.dataset.id === '1234567890'
-// el.dataset.user === 'johndoe'
-// el.dataset.dateOfBirth === ''
-
-// set the data attribute
-el.dataset.dateOfBirth = '1960-10-03';
-// Result: el.dataset.dateOfBirth === 1960-10-03
-
-delete el.dataset.dateOfBirth;
-// Result: el.dataset.dateOfBirth === undefined
-
-// 'someDataAttr' in el.dataset === false
-el.dataset.someDataAttr = 'mydata';
-// Result: 'someDataAttr' in el.dataset === true
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5 W3C')}}Snapshot of  {{SpecName('HTML WHATWG')}}, initial definition.
- -

브라우저 호환성

- -

{{Compat("api.HTMLElement.dataset")}}

- -

See also

- - diff --git a/files/ko/web/api/htmlelement/innertext/index.html b/files/ko/web/api/htmlelement/innertext/index.html new file mode 100644 index 0000000000..414fab5c00 --- /dev/null +++ b/files/ko/web/api/htmlelement/innertext/index.html @@ -0,0 +1,88 @@ +--- +title: Node.innerText +slug: Web/API/Node/innerText +tags: + - API + - DOM + - HTMLElement + - Property + - Reference +translation_of: Web/API/HTMLElement/innerText +--- +
{{APIRef("HTML DOM")}}
+ +

{{domxref("HTMLElement")}} 인터페이스의 innerText 속성은 요소와 그 자손의 렌더링 된 텍스트 콘텐츠를 나타냅니다. innerText는 사용자가 커서를 이용해 요소의 콘텐츠를 선택하고 클립보드에 복사했을 때 얻을 수 있는 텍스트의 근삿값을 제공합니다.

+ +
+

참고: innerText는 {{domxref("Node.textContent")}}와 혼동하기 쉬우나 중요한 차이점을 가지고 있습니다. 기본적으로, innerText는 텍스트의 렌더링 후 모습을 인식할 수 있지만 textContent는 그렇지 않습니다.

+
+ +

구문

+ +
const renderedText = htmlElement.innerText
+htmlElement.innerText = string
+
+ +

+ +

요소의 렌더링 된 텍스트 콘텐츠를 나타내는 {{domxref("DOMString")}}. 요소 자체가 렌더링 중이 아니라면 {{domxref("Node.textContent")}} 속성의 값과 동일합니다.

+ +

예제

+ +

다음 예제는 innerText와 {{domxref("Node.textContent")}}를 비교합니다. innerText가 {{htmlElement("br")}} 태그를 인식하고, 숨겨진 요소를 무시하는 점에 주목하세요.

+ +

HTML

+ +
<h3>원본 요소:</h3>
+<p id="source">
+  <style>#source { color: red; }</style>
+아래에서<br>이 글을<br>어떻게 인식하는지 살펴보세요.
+  <span style="display:none">숨겨진 글</span>
+</p>
+<h3>textContent 결과:</h3>
+<textarea id="textContentOutput" rows="6" cols="30" readonly>...</textarea>
+<h3>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("예제", 700, 450)}}

+ +

명세

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{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")}}

+ +

같이 보기

+ + diff --git a/files/ko/web/api/htmlelement/style/index.html b/files/ko/web/api/htmlelement/style/index.html deleted file mode 100644 index 5976dd66bc..0000000000 --- a/files/ko/web/api/htmlelement/style/index.html +++ /dev/null @@ -1,41 +0,0 @@ ---- -title: element.style -slug: Web/API/HTMLElement/style -tags: - - API - - HTML DOM - - HTMLElement - - Property - - Reference - - Style -translation_of: Web/API/ElementCSSInlineStyle/style ---- -
{{ APIRef("HTML DOM") }}
- -

HTMLElement.style 속성은 요소의 인라인 스타일에 접근하거나 설정할 때 사용할 수 있습니다. 접근자로서는 요소의 인라인 style 속성이 포함한 CSS 선언을 담은 {{domxref("CSSStyleDeclaration")}} 객체를 반환합니다

- -

예제

- -
// Set multiple styles in a single statement
-elt.style.cssText = "color: blue; border: 1px solid black";
-// Or
-elt.setAttribute("style", "color:red; border: 1px solid blue;");
-
-// Set specific style while leaving other inline style values untouched
-elt.style.color = "blue";
- -

명세

- -

DOM Level 2 Style: ElementCSSInlineStyle.style

- -

CSSOM: ElementCSSInlineStyle

- -

브라우저 호환성

- -

{{Compat("api.HTMLElement.style")}}

- -

같이 보기

- - diff --git a/files/ko/web/api/htmlelement/tabindex/index.html b/files/ko/web/api/htmlelement/tabindex/index.html deleted file mode 100644 index 7cbb0fa1f0..0000000000 --- a/files/ko/web/api/htmlelement/tabindex/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: element.tabIndex -slug: Web/API/HTMLElement/tabIndex -tags: - - DOM - - Gecko - - Gecko DOM Reference -translation_of: Web/API/HTMLOrForeignElement/tabIndex ---- -

{{ ApiRef() }}

-

요약

-

현재 요소의 탭 순서를 get/set.

-

구문

-
element.tabIndex =iIndex
-
-

매개변수

- -

-
b1 = document.getElementById("button1");
-b1.tabIndex = 1;
-
-

명세

-

tabIndex

-

{{ languages( { "en": "en/DOM/element.tabIndex", "pl": "pl/DOM/element.tabIndex" } ) }}

diff --git a/files/ko/web/api/htmlmediaelement/abort_event/index.html b/files/ko/web/api/htmlmediaelement/abort_event/index.html new file mode 100644 index 0000000000..2278a24c24 --- /dev/null +++ b/files/ko/web/api/htmlmediaelement/abort_event/index.html @@ -0,0 +1,74 @@ +--- +title: abort +slug: Web/Events/abort +tags: + - DOM + - Event + - Reference + - 레퍼런스 + - 이벤트 +translation_of: Web/API/HTMLMediaElement/abort_event +translation_of_original: Web/Events/abort +--- +

abort 이벤트는 리소스의 로딩이 중단되었을 때, 발생합니다.

+ +

개요

+ +
+
스펙
+
DOM L3
+
인터페이스
+
유저 인터페이스에서 발생하면 UIEvent, 그렇지 않으면 Event.
+
버블
+
안됨
+
취소 가능
+
안됨
+
타겟
+
Element
+
디폴트 액션
+
없음
+
+ +

속성

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
속성타입설명
target {{readonlyInline}}EventTarget이벤트 타겟 (DOM tree의 최상위 타겟).
type {{readonlyInline}}DOMString이벤트의 타입
bubbles {{readonlyInline}}Boolean이벤트가 버블링 되는지 안되는지
cancelable {{readonlyInline}}Boolean이벤트가 취소 가능한지 아닌지
view {{readonlyInline}}WindowProxydocument.defaultView (document의 window )
detail {{readonlyInline}}long (float)0.
diff --git a/files/ko/web/api/htmlorforeignelement/dataset/index.html b/files/ko/web/api/htmlorforeignelement/dataset/index.html new file mode 100644 index 0000000000..2b2a891dca --- /dev/null +++ b/files/ko/web/api/htmlorforeignelement/dataset/index.html @@ -0,0 +1,127 @@ +--- +title: HTMLElement.dataset +slug: Web/API/HTMLElement/dataset +tags: + - API + - HTML DOM + - HTMLElement + - HTMLOrForeignElement + - Property + - Read-only + - Reference +translation_of: Web/API/HTMLOrForeignElement/dataset +--- +
{{APIRef("HTML DOM")}}
+ +

HTMLElement.dataset 읽기 전용 속성은 요소의 사용자 지정 데이터 특성(data-*)에 대한 읽기와 쓰기 접근 방법을 HTML과 DOM 양측에 제공합니다. 반환하는 값은 {{domxref("DOMStringMap")}}으로, 각 데이터 특성마다 하나의 항목을 가집니다. dataset 속성 자체는 읽기 전용이라는 점에 주의하세요. 모든 쓰기 작업은 dataset 안의, 데이터 특성을 나타내는 각각의 속성에 수행해야 합니다. 또한 HTML의 data-이름과, 이에 대응하는 DOM dataset['이름']이름은 서로 일치하지 않으나, 다음 규칙에 따라 유사함을 기억하세요.

+ + + +

아래의 내용과 함께, Using data attributes 아티클에서는 HTML 데이터 속성을 어떻게 쓰는지 안내를 찾을 수 있습니다. 

+ +

Name conversion

+ +

dash-style 에서 camelCase로 변환: 커스텀 데이터 속성의 이름은 아래의 규칙에 따라 {{ domxref("DOMStringMap") }}의 key로 변환됩니다. 

+ + + +

camelCase 에서 dash-style로 변환: key를 속성 이름으로 매핑하는 반대의 변환은 아래의 규칙을 따릅니다.:

+ + + +

이러한 제약 조건은 반드시 두 변환이 서로의 역이 되도록 합니다.

+ +

예를 들어, data-abc-def 라는 이름의 속성은 abcDef 라는 키에 대응합니다.

+ +

Accessing values

+ + + +

Syntax

+ + + +

예시

+ +
<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>John Doe</div>
+ +
const el = document.querySelector('#user');
+
+// el.id === 'user'
+// el.dataset.id === '1234567890'
+// el.dataset.user === 'johndoe'
+// el.dataset.dateOfBirth === ''
+
+// set the data attribute
+el.dataset.dateOfBirth = '1960-10-03';
+// Result: el.dataset.dateOfBirth === 1960-10-03
+
+delete el.dataset.dateOfBirth;
+// Result: el.dataset.dateOfBirth === undefined
+
+// 'someDataAttr' in el.dataset === false
+el.dataset.someDataAttr = 'mydata';
+// Result: 'someDataAttr' in el.dataset === true
+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "dom.html#dom-dataset", "HTMLElement.dataset")}}{{Spec2('HTML5 W3C')}}Snapshot of  {{SpecName('HTML WHATWG')}}, initial definition.
+ +

브라우저 호환성

+ +

{{Compat("api.HTMLElement.dataset")}}

+ +

See also

+ + diff --git a/files/ko/web/api/htmlorforeignelement/tabindex/index.html b/files/ko/web/api/htmlorforeignelement/tabindex/index.html new file mode 100644 index 0000000000..7cbb0fa1f0 --- /dev/null +++ b/files/ko/web/api/htmlorforeignelement/tabindex/index.html @@ -0,0 +1,26 @@ +--- +title: element.tabIndex +slug: Web/API/HTMLElement/tabIndex +tags: + - DOM + - Gecko + - Gecko DOM Reference +translation_of: Web/API/HTMLOrForeignElement/tabIndex +--- +

{{ ApiRef() }}

+

요약

+

현재 요소의 탭 순서를 get/set.

+

구문

+
element.tabIndex =iIndex
+
+

매개변수

+ +

+
b1 = document.getElementById("button1");
+b1.tabIndex = 1;
+
+

명세

+

tabIndex

+

{{ languages( { "en": "en/DOM/element.tabIndex", "pl": "pl/DOM/element.tabIndex" } ) }}

diff --git a/files/ko/web/api/navigation_timing_api/index.html b/files/ko/web/api/navigation_timing_api/index.html new file mode 100644 index 0000000000..c9a0c1465b --- /dev/null +++ b/files/ko/web/api/navigation_timing_api/index.html @@ -0,0 +1,137 @@ +--- +title: 내비게이션 타이밍(Navigation Timing) +slug: Navigation_timing +translation_of: Web/API/Navigation_timing_API +--- +

Navigation Timing API는 웹 사이트의 성능을 측정하는 데 사용할 수 있는 데이터를 제공합니다. 같은 목적에 사용했던 다른 JavaScript 기반 메커니즘과 다르게 이 API는 더 유용하고 정확한 종단 간(end-to-end) 대기 시간(latency)을 제공할 수 있습니다.

+

다음 예제는 지각하는(perceived) 로딩 시간을 측정하는 법을 보여줍니다.

+
function onLoad() {
+  var now = new Date().getTime();
+  var page_load_time = now - performance.timing.navigationStart;
+  console.log("User-perceived page loading time: " + page_load_time);
+}
+
+

{{domxref("PerformanceTiming")}} 인터페이스로 접근할 수 있는 밀리 초 단위로 주어진 측정된 이벤트가 많이 있습니다. 발생하는 순서로 된 이벤트 목록입니다.

+ +

window.performance.navigation 객체는 리다이렉트(redirect), 앞/뒤 버튼, 혹은 보통의 URL 로딩이 어떤 페이지 로드를 일으키는지(trigger) 아는 데 사용할 수 있는 두 속성을 저장합니다.

+

window.performance.navigation.type:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
상수설명
TYPE_NAVIGATENEXT0아래 목록의 TYPE_RELOAD과 TYPE_BACK_FORWARD가 사용하는 것 외에, 링크 클릭하기, 사용자 에이전트(UA) 주소 바에 URL 입력하기, 폼 전송, 스크립트 연산으로 초기화하기로 시작한 내비게이션.
TYPE_RELOAD1리로드(reload) 연산 혹은 location.reload() 메소드를 통한 내비게이션.
TYPE_BACK_FORWARD2히스토리 순회(traversal) 연산을 통한 내비게이션
TYPE_UNDEFINED255위 값으로 정의되지 않는 어떠한 내비게이션 타입.
+

window.performance.navigation.redirectCount는 마지막 페이지에 도달할 때까지, 만일 있다면 몇 번의 리다이렉션이 일어났는지를 나타냅니다.

+

Navigation Timing API는 XHR로 서버에 보낸 클라이언트 쪽 성능 데이터를 모을 뿐 아니라 이전 페이지 언로드(unload) 시간, 도메인 룩업(look up) 시간, window.onload 전체 시간 등 다른 방법으로 측정하기 매우 어려운 데이터를 측정하는 데 사용할 수 있습니다.

+

예제

+

어떤 페이지를 로딩하는 데 필요한 전체 시간 계산하기.

+
var perfData = window.performance.timing;
+var pageLoadTime = perfData.loadEventEnd - perfData.navigationStart;
+
+

요청 응답 시간 계산하기.

+
var connectTime = perfData.responseEnd - perfData.requestStart;
+

링크

+ +

브라우저 호환

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChrome**Firefox (Gecko)*Internet ExplorerOpera*Safari (WebKit)
Basic support +

6

+
+

7

+

 

+
915{{ CompatNo() }}
+
+
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support4.015.0{{ CompatUnknown() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
+
+

 

diff --git a/files/ko/web/api/navigator/connection/index.html b/files/ko/web/api/navigator/connection/index.html new file mode 100644 index 0000000000..1afa39d9c1 --- /dev/null +++ b/files/ko/web/api/navigator/connection/index.html @@ -0,0 +1,105 @@ +--- +title: window.navigator.connection +slug: Web/API/NetworkInformation/connection +translation_of: Web/API/Navigator/connection +--- +

{{ Apiref() }}

+

{{ SeeCompatTable() }}

+

요약

+

네트워크 정보 API는 사용자 기기의 현재 대역폭이나 연결이 과금되는 지와 같은 정보를 알려줍니다. 이를 이용해서 사용자의 연결에 기반해서 높은 품질의 콘텐츠를 제공할지 낮은 품질의 콘텐츠를 제공할지 선택할 수 있습니다.

+

속성

+
+
+ {{domxref("window.navigator.connection.bandwidth", "connection.bandwidth")}} {{ReadOnlyInline}}
+
+ 현재 연결에 대한 다운로드 대역폭을 MB/s 단위의 double 형태로 알려줍니다. 사용자가 오프라인일 경우는 0이고 알 수 없을 경우에는 infinity로 나옵니다.
+
+ {{domxref("window.navigator.connection.metered", "connection.metered")}} {{ReadOnlyInline}}
+
+ 연결이 과금이 되는 경우(예를 들어 pay-per-use) Boolean 형의 true가 반환됩니다.
+
+

이벤트 핸들러

+
+
+ {{domxref("window.navigator.connection.onchange", "connection.onchange")}}
+
+ {{event("change")}} 이벤트에 대한 이벤트 핸들러 속성입니다. 연결 정보가 변경될 때 이벤트가 발생합니다.
+
+
+

주의: connection 객체는 이벤트를 다루기 위한 {{domxref("EventTarget.addEventListener","addEventListener")}} 메서드를 사용할 수 있는 {{domxref("EventTarget")}}을 상속받습니다.

+
+

명세

+ + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('Network Information', '', 'Network Information API') }}{{ Spec2('Network Information') }}Initial specification
+

브라우저 호환성

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support20? {{ property_prefix("webkit") }}12.0 {{ property_prefix("moz") }} (see notes){{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+
+ + + + + + + + + + + + + + + + + + + +
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}12.0 {{ property_prefix("moz") }} (see notes){{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+

Gecko 관련 내용

+ +

관련 내용

+ diff --git a/files/ko/web/api/network_information_api/index.html b/files/ko/web/api/network_information_api/index.html new file mode 100644 index 0000000000..9526bd2d5f --- /dev/null +++ b/files/ko/web/api/network_information_api/index.html @@ -0,0 +1,46 @@ +--- +title: Network Information API +slug: WebAPI/Network_Information +translation_of: Web/API/Network_Information_API +--- +

{{ SeeCompatTable() }}

+

네트워크 정보 API는 사용자 기기의 현재 대역폭이나 과금이 되는 연결인지와 같은 시스템의 연결 정보를 알려줍니다. 이를 이용해서 사용자에게 높은 용량의 콘텐츠를 제공할지 낮은 용량의 콘텐츠를 제공할지 사용자의 연결 상태에 따라서 제공할 수 있습니다. 전체 API는 DOM에 추가된 단일한 객체로 구성되어 있습니다: {{domxref("window.navigator.connection")}}.

+

연결상태 변경 감지

+

이 예제는 사용자의 연결상태 변화를 감시합니다. 사용자가 비싼 망에서 싼 망으로 이동할 때 사용자가 추가적인 비용을 지불하지 않게 하기 위해서 전송량을 감소시키는 등과 같은 행동을 할 수 있게 앱이 경고를 하는 일과 비슷합니다.

+
var connection = navigator.connection || navigator.mozConnection || navigator.webkitConnection;
+
+function updateConnectionStatus() {
+  alert("Connection bandwidth: " + connection.bandwidth + " MB/s");
+  if (connection.metered) {
+    alert("The connection is metered!");
+  }
+}
+
+connection.addEventListener("change", updateConnectionStatus);
+updateConnectionStatus();
+
+

명세

+ + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('Network Information', '', 'Network Information API') }}{{ Spec2('Network Information') }}Initial specification
+

브라우저 호환성

+

{{Page('/en-US/docs/Web/API/window.navigator.connection','Browser compatibility')}}

+

관련 내용

+ diff --git a/files/ko/web/api/networkinformation/connection/index.html b/files/ko/web/api/networkinformation/connection/index.html deleted file mode 100644 index 1afa39d9c1..0000000000 --- a/files/ko/web/api/networkinformation/connection/index.html +++ /dev/null @@ -1,105 +0,0 @@ ---- -title: window.navigator.connection -slug: Web/API/NetworkInformation/connection -translation_of: Web/API/Navigator/connection ---- -

{{ Apiref() }}

-

{{ SeeCompatTable() }}

-

요약

-

네트워크 정보 API는 사용자 기기의 현재 대역폭이나 연결이 과금되는 지와 같은 정보를 알려줍니다. 이를 이용해서 사용자의 연결에 기반해서 높은 품질의 콘텐츠를 제공할지 낮은 품질의 콘텐츠를 제공할지 선택할 수 있습니다.

-

속성

-
-
- {{domxref("window.navigator.connection.bandwidth", "connection.bandwidth")}} {{ReadOnlyInline}}
-
- 현재 연결에 대한 다운로드 대역폭을 MB/s 단위의 double 형태로 알려줍니다. 사용자가 오프라인일 경우는 0이고 알 수 없을 경우에는 infinity로 나옵니다.
-
- {{domxref("window.navigator.connection.metered", "connection.metered")}} {{ReadOnlyInline}}
-
- 연결이 과금이 되는 경우(예를 들어 pay-per-use) Boolean 형의 true가 반환됩니다.
-
-

이벤트 핸들러

-
-
- {{domxref("window.navigator.connection.onchange", "connection.onchange")}}
-
- {{event("change")}} 이벤트에 대한 이벤트 핸들러 속성입니다. 연결 정보가 변경될 때 이벤트가 발생합니다.
-
-
-

주의: connection 객체는 이벤트를 다루기 위한 {{domxref("EventTarget.addEventListener","addEventListener")}} 메서드를 사용할 수 있는 {{domxref("EventTarget")}}을 상속받습니다.

-
-

명세

- - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('Network Information', '', 'Network Information API') }}{{ Spec2('Network Information') }}Initial specification
-

브라우저 호환성

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support20? {{ property_prefix("webkit") }}12.0 {{ property_prefix("moz") }} (see notes){{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
-
- - - - - - - - - - - - - - - - - - - -
FeatureAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}12.0 {{ property_prefix("moz") }} (see notes){{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
-

Gecko 관련 내용

- -

관련 내용

- diff --git a/files/ko/web/api/node/innertext/index.html b/files/ko/web/api/node/innertext/index.html deleted file mode 100644 index 414fab5c00..0000000000 --- a/files/ko/web/api/node/innertext/index.html +++ /dev/null @@ -1,88 +0,0 @@ ---- -title: Node.innerText -slug: Web/API/Node/innerText -tags: - - API - - DOM - - HTMLElement - - Property - - Reference -translation_of: Web/API/HTMLElement/innerText ---- -
{{APIRef("HTML DOM")}}
- -

{{domxref("HTMLElement")}} 인터페이스의 innerText 속성은 요소와 그 자손의 렌더링 된 텍스트 콘텐츠를 나타냅니다. innerText는 사용자가 커서를 이용해 요소의 콘텐츠를 선택하고 클립보드에 복사했을 때 얻을 수 있는 텍스트의 근삿값을 제공합니다.

- -
-

참고: innerText는 {{domxref("Node.textContent")}}와 혼동하기 쉬우나 중요한 차이점을 가지고 있습니다. 기본적으로, innerText는 텍스트의 렌더링 후 모습을 인식할 수 있지만 textContent는 그렇지 않습니다.

-
- -

구문

- -
const renderedText = htmlElement.innerText
-htmlElement.innerText = string
-
- -

- -

요소의 렌더링 된 텍스트 콘텐츠를 나타내는 {{domxref("DOMString")}}. 요소 자체가 렌더링 중이 아니라면 {{domxref("Node.textContent")}} 속성의 값과 동일합니다.

- -

예제

- -

다음 예제는 innerText와 {{domxref("Node.textContent")}}를 비교합니다. innerText가 {{htmlElement("br")}} 태그를 인식하고, 숨겨진 요소를 무시하는 점에 주목하세요.

- -

HTML

- -
<h3>원본 요소:</h3>
-<p id="source">
-  <style>#source { color: red; }</style>
-아래에서<br>이 글을<br>어떻게 인식하는지 살펴보세요.
-  <span style="display:none">숨겨진 글</span>
-</p>
-<h3>textContent 결과:</h3>
-<textarea id="textContentOutput" rows="6" cols="30" readonly>...</textarea>
-<h3>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("예제", 700, 450)}}

- -

명세

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{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")}}

- -

같이 보기

- - diff --git a/files/ko/web/api/notifications_api/using_the_notifications_api/index.html b/files/ko/web/api/notifications_api/using_the_notifications_api/index.html new file mode 100644 index 0000000000..351361d2af --- /dev/null +++ b/files/ko/web/api/notifications_api/using_the_notifications_api/index.html @@ -0,0 +1,265 @@ +--- +title: 알림 API 사용하기 +slug: WebAPI/Using_Web_Notifications +translation_of: Web/API/Notifications_API/Using_the_Notifications_API +--- +

{{APIRef("Web Notifications")}}{{AvailableInWorkers}}{{securecontext_header}}

+ +

웹 페이지나 앱에서 알림(Notifications) API를 사용하면 페이지 외부에 표시되는 알림을 보낼 수 있습니다. 이것은 시스템 레벨에서 처리되는 것으로 애플리케이션이 유휴 상태거나 백그라운드에 있더라도 웹 앱이 사용자에게 정보를 보낼 수 있습니다. 이 글에서는 여러분의 앱에서 이 API를 사용하기 위한 기초를 알아봅니다.

+ +

일반적으로 시스템 알림은 운영 체계의 표준 알림 메커니즘을 말합니다. 예를 들어 일반적인 데스크톱 시스템이나 모바일 장치의 브로드캐스트 알림을 생각해봅시다.

+ +

+ +

물론 시스템 알림 시스템은 플랫폼 및 브라우저에 따라 다양하지만 괜찮습니다. 알림 API는 범용적으로 작성돼서 대부분의 시스템 알림 시스템과 호환됩니다.

+ +

예시

+ +

웹 알림의 대표적인 사용 사례는 웹 기반 메일이나 IRC 애플리케이션입니다. 새 메시지가 도착하면 사용자가 다른 애플리케이션으로 다른 일을 하더라도 사용자에게 알릴 필요가 있습니다. 요즘은 Slack 등 이러한 사례를 많이 찾아볼 수 있습니다.

+ +

우리는 웹 알림을 사용하는 방법을 좀더 잘 알 수 있도록 실제적인 예시 — 할 일 목록 앱 —를 작성했습니다. 데이터는 로컬에서 IndexedDB로 저장하고 사용자 알림은 할 일 기한이 됐을 때 시스템 알림을 사용합니다. 할 일 목록 코드를 다운로드하거나, 앱의 라이브 실행을 보세요.

+ +

권한 요청하기

+ +

앱이 알림을 보내려면 먼저 사용자가 애플리케이션에 해당 권한을 허용해줘야 합니다. 이는 API가 웹페이지 외부와 상호작용할 때 통상적인  요구 사항입니다. 최소 한번은 사용자가 해당 애플리케이션이 알림을 표시할 수 있는 권한을 허용해줄 필요가 있으며 이로써 사용자는 어떤 앱/사이트가 알림을 보일 수 있는지 제어할 수 있습니다.

+ +

과거에 푸시 알림에 대한 악용 때문에 웹 브라우저와 개발자는 그런 문제를 완화할 수 있는 전략을 구현하게 되었습니다. 알림을 발생시키려면 사용자 제스처(예: 단추 클릭)에 대한 응답으로만 가능합니다. 이것은 모범적인 방식일 뿐 아니라 — 사용자에게 미동의 알림으로 스팸을 보내면 안됩니다 — 실제로도 전향적인 브라우저는 사용자 제스처에 대한 응답으로 촉발되지 않은 알림은 명시적으로 불허합니다. 파이어폭스는 이미 72 버전부터 이렇게 하고 있으며 사파리도 하고 있습니다.

+ +

또한 크롬과 파이어폭스에서는 사이트가 보안 콘텍스트(즉, HTTPS)가 아니면 알림을 아예 요청할 수 없으며 크로스 오리진 {{htmlelement("iframe")}}으로부터의 알림 권한은 요청할 수 없게 되었습니다. 

+ +

현재 권한 상태 확인하기

+ +

권한을 이미 가지고 있는지 확인하려면 {{domxref("Notification.permission")}} 읽기 전용 속성의 값을 확인하면 됩니다. 다음 세 가지 값이 있을 수 있습니다.

+ +
+
default
+
사용자에게 아직 권한을 요구하지 않았으며 따라서 알림을 표시하지 않습니다.
+
granted
+
사용자에게 알림 표시 권한을 요구했으며 사용자는 권한을 허용했습니다.
+
denied
+
사용자가 명시적으로 알림 표시 권한을 거부했습니다.
+
+ +

권한 획득하기

+ +

아직 알림 표시 권한이 허용되지 않았다면 애플리케이션은 {{domxref("Notification.requestPermission()")}} 메서드를 사용하여 사용자에게 권한을 요청할 필요가 있습니다. 간단하게는 아래와 같이 넣습니다.

+ +
Notification.requestPermission().then(function(result) {
+  console.log(result);
+});
+ +

여기서는 프로미스 방식의 메서드 버전을 사용합니다. 과거 버전을 지원하려면 아래와 같이 과거의 콜백 버전을 사용해야 할 수 있습니다.

+ +
Notification.requestPermission();
+ +

콜백 버전은 콜백 함수를 옵셔널하게 받을 수 있으며 사용자가 표시 권한 요청에 응답한 후에 호출됩니다.

+ +

예시

+ +

우리가 만드는 할 일 데모에서는 "알림 허용" 단추를 둬서 누르면 앱의 알림 권한을 요청합니다.

+ +
<button id="enable">알림 허용</button>
+ +

누르면 다음 askNotificationPermission() 함수를 호출합니다.

+ +
function askNotificationPermission() {
+  // 권한을 실제로 요구하는 함수
+  function handlePermission(permission) {
+    // 사용자의 응답에 관계 없이 크롬이 정보를 저장할 수 있도록 함
+    if(!('permission' in Notification)) {
+      Notification.permission = permission;
+    }
+
+    // 사용자 응답에 따라 단추를 보이거나 숨기도록 설정
+    if(Notification.permission === 'denied' || Notification.permission === 'default') {
+      notificationBtn.style.display = 'block';
+    } else {
+      notificationBtn.style.display = 'none';
+    }
+  }
+
+  // 브라우저가 알림을 지원하는지 확인
+  if (!('Notification' in window)) {
+    console.log("이 브라우저는 알림을 지원하지 않습니다.");
+  } else {
+    if(checkNotificationPromise()) {
+      Notification.requestPermission()
+      .then((permission) => {
+        handlePermission(permission);
+      })
+    } else {
+      Notification.requestPermission(function(permission) {
+        handlePermission(permission);
+      });
+    }
+  }
+}
+ +

두 번째 메인 블록을 먼저 보면 알림이 지원되는지 확인하는 것을 알 수 있습니다. 지원하는 경우 그에 따라 Notification.requestPermission()의 프로미스 기반 버전이 지원되는지 보는 확인을 실행합니다. 맞다면 프로미스 기반 버전을 실행하고(사파리 외에는 전부 지원됨) 아니라면 과거의 콜백 기반 버전을 실행합니다(사파리에서 지원).

+ +

코드 중복을 피하기 위해 뒷 처리 수행 코드를 handlePermission() 함수에 넣었는데 이 함수가 코드에서 첫 번째 메인 블록입니다. 그 안에서는 Notification.permission 값을 명시적으로 설정하고(크롬의 일부 과거 버전에서는 이게 자동으로 안됩니다) 사용자가 권한 대화창에서 선택한 결과에 따라 단추를 보이거나 숨깁니다. 권한이 이미 허용됐는지 보여주려는 것은 아니고 사용자가 권한을 거부한 경우 나중에 다시 선택할 수 있도록 해주는 것입니다.

+ +

참고: 크롬 37 버전 전에는 load 이벤트 핸들러에서 {{domxref("Notification.requestPermission()")}}을 호출할 수 없었습니다(이슈 274284 참고).

+ +

requestPermission() 프로미스 기능 알아내기

+ +

위에서 우리는 브라우저가 Notification.requestPermission()의 프로미스 버전을 지원하는지 확인해야 한다고 했습니다. 아래와 같이 했습니다.

+ +
function checkNotificationPromise() {
+    try {
+      Notification.requestPermission().then();
+    } catch(e) {
+      return false;
+    }
+
+    return true;
+  }
+ +

기본적으로 requestPermission()에 .then() 메서드가 있는지 알아보는 것입니다. 맞다면 계속 진행하고 true를 반환합니다. 실패라면 catch() {} 블록에서 false를 반환합니다.

+ +

알림 만들기 

+ +

알림 만들기는 쉬워서 {{domxref("Notification")}} 생성자만 사용하면 됩니다. 이 생성자는 알림에 표시할 제목과 {{domxref("Notification.icon","icon")}}이나 텍스트 {{domxref("Notification.body","body")}} 같은 알림 조작 옵션 몇 가지를 받도록 돼 있습니다.

+ +

예를 들어 할일 목록 예시에서 아래 코드로 필요시 알림을 만듭니다(createNotification() 함수에서 찾을 수 있음).

+ +
var img = '/to-do-notifications/img/icon-128.png';
+var text = '아! "' + title + '" 작업 기한이 만료됐습니다.';
+var notification = new Notification('할 일 목록', { body: text, icon: img });
+
+ +

알림 닫기

+ +

파이어폭스와 사파리는 알림을 자동으로 금방(약 4초) 닫습니다. 이것은 운영 체계 수준에서도 발생합니다. 그런데 크롬 같은 다른 브라우저는 그렇지 않습니다. 모든 브라우저에서 알림이 닫히게 하려면 {{domxref("WindowTimers.setTimeout","setTimeout()")}} 함수에서 {{domxref("Notification.close")}} 함수를 호출하여 알림을 4초 후에 닫으면 됩니다. bind()를 사용하여 close() 호출이 알림에 연동되게 하는 것도 해줘야 합니다.

+ +
setTimeout(notification.close.bind(notification), 4000);
+ +
+

참고: "close" 이벤트를 받았을 때 알림을 닫은 것이 사용자인지는 보장할 수 없습니다. 이것은 규격과도 일치합니다. 규격에서는 "알림이 닫힐 때 그것이 기반 알림 플랫폼에 의한 것이든지 사용자에 의한 것이든지 닫기 절차가 실행돼야 한다."고 기술하고 있습니다.

+
+ +

알림 이벤트

+ +

{{domxref("Notification")}} 인스턴스에 촉발되는 이벤트는 다음 네 가지입니다.

+ +
+
click
+
사용자가 알림을 클릭하면 촉발됩니다.
+
close
+
알림이 닫힌 후 촉발됩니다.
+
error
+
알림에 문제가 있을 경우 촉발되며 대개 어떤 이유에 의해 알림을 표시할 수 없는 경우입니다.
+
show
+
알림이 사용자에게 표시되면 촉발됩니다.
+
+ +

이 이벤트들은 {{domxref("Notification.onclick","onclick")}}, {{domxref("Notification.onclose","onclose")}}, {{domxref("Notification.onerror","onerror")}}, {{domxref("Notification.onshow","onshow")}} 핸들러로 추적할 수 있습니다. {{domxref("Notification")}}이 {{domxref("EventTarget")}}을 상속하기 때문에 {{domxref("EventTarget.addEventListener","addEventListener()")}} 메서드를 사용할 수 있습니다.

+ +

기존 알림 대체하기

+ +

사용자가 잠깐 사이에 알림을 많이 받는 것은 바람직하지 않습니다. 예를 들어 메신저 애플리케이션이 모든 수신 메시지를 사용자에게 알리는데 그게 아주 많다면요? 사용자가 알림 때문에 대량 스팸을 받지 않도록 알림 대기열(큐)을 수정해서 걸려 있는 알림 하나나 여럿을 새로운 알림 하나로 대체할 수 있습니다.

+ +

이를 위해 새 알림에 태그를 붙일 수 있습니다. 알림에 이미 같은 태그가 있고 표시되지 않았다면 새 알림으로 이전 알림을 대체하는 것입니다. 같은 태그의 알림이 이미 표시됐다면 이전 알림을 닫고 새 알림을 표시합니다.

+ +

태그 예시

+ +

다음과 같은 간단한 HTML을 봅시다.

+ +
<button>알림 실행!</button>
+ +

다수의 알림을 아래 방법으로 처리할 수 있습니다.

+ +
window.addEventListener('load', function () {
+  // 처음에는 알림 권한이 있는지 확인함
+  // 없으면 권한 요구
+  if (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 (Notification && Notification.permission === "granted") {
+      var i = 0;
+      // 어떤 브라우저(파이어폭스 등)는 일정 시간 동안 알림이 너무 많은 경우 차단하기 때문에 인터벌 사용.
+      var interval = window.setInterval(function () {
+        // 태그 덕분에 "안녕! 9" 알림만 보여야 함
+        var n = new Notification("안녕! " + i, {tag: '알림너무많음'});
+        if (i++ == 9) {
+          window.clearInterval(interval);
+        }
+      }, 200);
+    }
+
+    // 사용자가 알림을 받을지 말지 답하지 않은 경우
+    // 참고: 크롬 때문에 권한 속성이 설정됐는지 알 수 없으므로
+    // "기본" 값을 확인하는 것은 안전하지 않음
+    else if (Notification && Notification.permission !== "denied") {
+      Notification.requestPermission(function (status) {
+        // 사용자가 ok한 경우
+        if (status === "granted") {
+          var i = 0;
+          // 어떤 브라우저(파이어폭스 등)는 일정 시간 동안 알림이 너무 많은 경우 차단하기 때문에 인터벌 사용.
+          var interval = window.setInterval(function () {
+            // 태그 덕분에 "안녕! 9" 알림만 보여야 함
+            var n = new Notification("안녕! " + i, {tag: '알림너무많음'});
+            if (i++ == 9) {
+              window.clearInterval(interval);
+            }
+          }, 200);
+        }
+
+        // 그 외의 경우 일반적인 모달 alert로 폴백
+        else {
+          alert("안녕!");
+        }
+      });
+    }
+
+    // 사용자가 알림을 거부한 경우
+    else {
+      // 일반적인 모달 alert로 폴백
+      alert("안녕!");
+    }
+  });
+});
+ +

라이브 결과는 아래에서 보세요.

+ +

{{ EmbedLiveSample('Tag_example', '100%', 30) }}

+ +

규격

+ + + + + + + + + + + + + + + + +
규격상태비고
{{SpecName('Web Notifications')}}{{Spec2('Web Notifications')}}현행 표준
+ +

브라우저 호환성

+ +

{{page("/en-US/Web/API/Notification","Browser compatibility")}}

+ +

참고

+ + diff --git a/files/ko/web/api/proximity_events/index.html b/files/ko/web/api/proximity_events/index.html new file mode 100644 index 0000000000..ad1687ddd2 --- /dev/null +++ b/files/ko/web/api/proximity_events/index.html @@ -0,0 +1,119 @@ +--- +title: Proximity +slug: WebAPI/Proximity +translation_of: Web/API/Proximity_Events +--- +

{{ SeeCompatTable }}

+

Summary

+

근접 이벤트는 사용자가 디바이스에 가까이 갔을때를 알 수 있는 간단한 벙법이다.

+

예를 들어,  사용자가 전화가 걸려왔을 때 디바이스에 귀를 가까이 하면, 근접 이벤트들은 스마트폰의 화면이 꺼지게 하여 이러한 변화에 대응할 수 있게 해준다.

+
+

Note: 당연히 이 API는 근접 센서를 가진 장치를 필요로 하며, 이 근접 센서는 대게 모바일 다비이스들에서만 이용 가능하다. 근접 센서가 없는 장치들에서는 근접 이벤트들을 지원할 수는 있을 지 몰라도 해당 이벤트들은 절대 발생하지 않을 것이다.

+
+

Proximity Events

+

다비이스 근접 센서가 장치와 대상 사이의 변화를 감지했을 때, 센서는 그  변화를 브라우저에게 알린다. 브라우저는 그 알림을 받으면 그 변화에 대해 {{domxref("DeviceProximityEvent")}} 이벤트를 발생시킨다. 그리고 더 대략적인 변화(more rough change)를 알리기 위해  {{domxref("UserProximityEvent")}} 이벤트를 발생시킨다.

+

window object 레벨에서  {{domxref("EventTarget.addEventListener","addEventListener")}} 메소드 ({{event("deviceproximity")}} 또는 {{event("userproximity")}} 이벤트명) 를 이용하여 근접 이벤트를 전달받을 수 있다. 또한 {{domxref("window.ondeviceproximity")}} 또는 {{domxref("window.onuserproximity")}} 프로퍼티에 이벤트 핸들러를 붙이는 방법으로도 이벤트를 전달받을 수 있다.

+

일단 이벤트가 전달되면, 그 이벤트 오브젝트는 다음과 같은 여러 종류의 정보에 접근할 수 있게 해준다:

+ +

Example

+
window.addEventListener('userproximity', function(event) {
+  if (event.near) {
+    // let's power off the screen
+    navigator.mozPower.screenEnabled = false;
+  } else {
+    // Otherwise, let's power on the screen
+    navigator.mozPower.screenEnabled = true;
+  }
+});
+

Specifications

+ + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('Proximity Events', '', 'Proximity Events') }}{{ Spec2('Proximity Events') }}Initial specification
+

Browser compatibility

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
{{domxref("DeviceProximityEvent")}}{{CompatNo()}}{{CompatVersionUnknown()}}{{CompatNo()}}{{CompatNo()}}{{CompatNo()}}
{{domxref("UserProximityEvent")}}{{CompatNo()}}{{CompatVersionUnknown()}}{{CompatNo()}}{{CompatNo()}}{{CompatNo()}}
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
{{domxref("DeviceProximityEvent")}}{{CompatNo()}}{{CompatNo()}}{{ CompatGeckoMobile("15.0") }}{{CompatNo()}}{{CompatNo()}}{{CompatNo()}}
{{domxref("UserProximityEvent")}}{{CompatNo()}}{{CompatNo()}}{{CompatVersionUnknown()}}{{CompatNo()}}{{CompatNo()}}{{CompatNo()}}
+
+

See also

+ diff --git a/files/ko/web/api/screen.onorientationchange/index.html b/files/ko/web/api/screen.onorientationchange/index.html deleted file mode 100644 index dc1a76013f..0000000000 --- a/files/ko/web/api/screen.onorientationchange/index.html +++ /dev/null @@ -1,85 +0,0 @@ ---- -title: window.screen.onorientationchange -slug: Web/API/Screen.onorientationchange -translation_of: Web/API/Screen/onorientationchange ---- -

{{ ApiRef() }}

-

{{SeeCompatTable}}

-

Summary

-

{{ event("orientationchange")}} 이벤트를 화면 객체로 보내는 이벤트 핸들러이다.

-

Syntax

-
screen.onorientationchange = funcRef;
-
-

funcRef 는 함수로의 참조 이다.

-

Specifications

- - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Screen Orientation')}}{{Spec2('Screen Orientation')}}Draft specification.
-

Browser compatibility

-

{{ CompatibilityTable() }}

-
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatVersionUnknown() }} {{ property_prefix("moz") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
-
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatVersionUnknown() }} {{ property_prefix("moz") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
-
-

Gecko notes

-

이 API 는 현재 초안형태이다. 오직 B2G 와 안드로이드용 Firefox 에서 prefixed method (onmozorientationchange) 형태로만 구현된다.

-

See also

- diff --git a/files/ko/web/api/screen/onorientationchange/index.html b/files/ko/web/api/screen/onorientationchange/index.html new file mode 100644 index 0000000000..dc1a76013f --- /dev/null +++ b/files/ko/web/api/screen/onorientationchange/index.html @@ -0,0 +1,85 @@ +--- +title: window.screen.onorientationchange +slug: Web/API/Screen.onorientationchange +translation_of: Web/API/Screen/onorientationchange +--- +

{{ ApiRef() }}

+

{{SeeCompatTable}}

+

Summary

+

{{ event("orientationchange")}} 이벤트를 화면 객체로 보내는 이벤트 핸들러이다.

+

Syntax

+
screen.onorientationchange = funcRef;
+
+

funcRef 는 함수로의 참조 이다.

+

Specifications

+ + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Screen Orientation')}}{{Spec2('Screen Orientation')}}Draft specification.
+

Browser compatibility

+

{{ CompatibilityTable() }}

+
+ + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatNo() }}{{ CompatVersionUnknown() }} {{ property_prefix("moz") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+
+ + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatNo() }}{{ CompatNo() }}{{ CompatVersionUnknown() }} {{ property_prefix("moz") }}{{ CompatNo() }}{{ CompatNo() }}{{ CompatNo() }}
+
+

Gecko notes

+

이 API 는 현재 초안형태이다. 오직 B2G 와 안드로이드용 Firefox 에서 prefixed method (onmozorientationchange) 형태로만 구현된다.

+

See also

+ diff --git a/files/ko/web/api/streams_api/concepts/index.html b/files/ko/web/api/streams_api/concepts/index.html new file mode 100644 index 0000000000..9c993b81a3 --- /dev/null +++ b/files/ko/web/api/streams_api/concepts/index.html @@ -0,0 +1,115 @@ +--- +title: Streams API 컨셉 +slug: Web/API/Streams_API/컨셉 +translation_of: Web/API/Streams_API/Concepts +--- +
{{apiref("Streams")}}
+ +

The Streams API adds a very useful set of tools to the web platform, providing objects allowing JavaScript to programmatically access streams of data received over the network and process them as desired by the developer. Some of the concepts and terminology associated with streams might be new to you — this article explains all you need to know.

+ +

Readable streams

+ +

A readable stream is a data source represented in JavaScript by a {{domxref("ReadableStream")}} object that flows from an underlying source — this is a resource somewhere on the network or elsewhere on your domain that you want to get data from.

+ +

There are two types of underlying source:

+ + + +

컨The data is read sequentially in small pieces called chunks. A chunk can be a single byte, or it can be something larger such as a typed array of a certain size. A single stream can contain chunks of different sizes and types.

+ +

+ +

The chunks placed in a stream are said to be enqueued — this means they are waiting in a queue ready to be read. An internal queue keeps track of the chunks that have not yet been read (see the Internal queues and queueing strategies section below).

+ +

The chunks inside the stream are read by a reader — this processes the data one chunk at a time, allowing you to do whatever kind of operation you want to do on it. The reader plus the other processing code that goes along with it is called a consumer.

+ +

There is also a construct you’ll use called a controller — each reader has an associated controller that allows you to control the stream (for example, to cancel it if wished).

+ +

Only one reader can read a stream at a time; when a reader is created and starts reading a stream (an active reader), we say it is locked to it. If you want another reader to start reading your stream, you typically need to cancel the first reader before you do anything else (although you can tee streams, see the Teeing section below)

+ +

Note that there are two different types of readable stream. As well as the conventional readable stream there is a type called a byte stream — this is an extended version of a conventional stream for reading underlying byte sources (otherwise known as BYOB, or “bring your own buffer”) sources. These allow streams to be read straight into a buffer supplied by the developer, minimizing the copying required. Which underlying stream (and by extension, reader and controller) your code will use depends on how the stream was created in the first place (see the {{domxref("ReadableStream.ReadableStream()")}} constructor page).

+ +
+

Important: Byte streams are not implemented anywhere as yet, and questions have been raised as to whether the spec details are in a finished enough state for them to be implemented. This may change over time.

+
+ +

You can make use of ready-made readable streams via mechanisms like a {{domxref("Response.body")}} from a fetch request, or roll your own streams using the {{domxref("ReadableStream.ReadableStream()")}} constructor.

+ +

Teeing

+ +

Even though only a single reader can read a stream at once, it is possible to split a stream into two identical copies, which can then be read by two separate readers. This is called teeing.

+ +

In JavaScript, 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 ServiceWorker 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.

+ +

+ +

Writable streams

+ +

A writable stream is a destination into which you can write data, represented in JavaScript by a {{domxref("WritableStream")}} object. This serves as an abstraction over the top of an underlying sink — a lower-level I/O sink into which raw data is written.

+ +

The data is written to the stream via a writer, one chunk at a time. A chunk can take a multitude of forms, just like the chunks in a reader. You can use whatever code you like to produce the chunks ready for writing; the writer plus the associated code is called a 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()")}} 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:

+ + + +

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

+ +

An important concept in streams is backpressure — this is the process by which a single stream or a pipe chain regulates the speed of reading/writing. When a stream later in the chain is still busy and isn't yet ready to accept more chunks, it sends a signal backwards through the chain to tell earlier transform streams (or the original source) to slow down delivery as appropriate so that you don't end up with a bottleneck anywhere.

+ +

To use backpressure in a ReadableStream, we can ask the controller for the chunk size  desired by the consumer by querying the {{domxref("ReadableStreamDefaultController.desiredSize")}} attribute on the controller. If it is too low, our ReadableStream can tell its underlying source to stop sending data, and we backpressure along the stream chain.

+ +

If later on the consumer again wants to receive data, we can use the pull method in the stream creation to tell our underlying source to feed our stream with data.

+ +

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.

+ + + +

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/ko/web/api/streams_api/\354\273\250\354\205\211/index.html" "b/files/ko/web/api/streams_api/\354\273\250\354\205\211/index.html" deleted file mode 100644 index 9c993b81a3..0000000000 --- "a/files/ko/web/api/streams_api/\354\273\250\354\205\211/index.html" +++ /dev/null @@ -1,115 +0,0 @@ ---- -title: Streams API 컨셉 -slug: Web/API/Streams_API/컨셉 -translation_of: Web/API/Streams_API/Concepts ---- -
{{apiref("Streams")}}
- -

The Streams API adds a very useful set of tools to the web platform, providing objects allowing JavaScript to programmatically access streams of data received over the network and process them as desired by the developer. Some of the concepts and terminology associated with streams might be new to you — this article explains all you need to know.

- -

Readable streams

- -

A readable stream is a data source represented in JavaScript by a {{domxref("ReadableStream")}} object that flows from an underlying source — this is a resource somewhere on the network or elsewhere on your domain that you want to get data from.

- -

There are two types of underlying source:

- - - -

컨The data is read sequentially in small pieces called chunks. A chunk can be a single byte, or it can be something larger such as a typed array of a certain size. A single stream can contain chunks of different sizes and types.

- -

- -

The chunks placed in a stream are said to be enqueued — this means they are waiting in a queue ready to be read. An internal queue keeps track of the chunks that have not yet been read (see the Internal queues and queueing strategies section below).

- -

The chunks inside the stream are read by a reader — this processes the data one chunk at a time, allowing you to do whatever kind of operation you want to do on it. The reader plus the other processing code that goes along with it is called a consumer.

- -

There is also a construct you’ll use called a controller — each reader has an associated controller that allows you to control the stream (for example, to cancel it if wished).

- -

Only one reader can read a stream at a time; when a reader is created and starts reading a stream (an active reader), we say it is locked to it. If you want another reader to start reading your stream, you typically need to cancel the first reader before you do anything else (although you can tee streams, see the Teeing section below)

- -

Note that there are two different types of readable stream. As well as the conventional readable stream there is a type called a byte stream — this is an extended version of a conventional stream for reading underlying byte sources (otherwise known as BYOB, or “bring your own buffer”) sources. These allow streams to be read straight into a buffer supplied by the developer, minimizing the copying required. Which underlying stream (and by extension, reader and controller) your code will use depends on how the stream was created in the first place (see the {{domxref("ReadableStream.ReadableStream()")}} constructor page).

- -
-

Important: Byte streams are not implemented anywhere as yet, and questions have been raised as to whether the spec details are in a finished enough state for them to be implemented. This may change over time.

-
- -

You can make use of ready-made readable streams via mechanisms like a {{domxref("Response.body")}} from a fetch request, or roll your own streams using the {{domxref("ReadableStream.ReadableStream()")}} constructor.

- -

Teeing

- -

Even though only a single reader can read a stream at once, it is possible to split a stream into two identical copies, which can then be read by two separate readers. This is called teeing.

- -

In JavaScript, 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 ServiceWorker 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.

- -

- -

Writable streams

- -

A writable stream is a destination into which you can write data, represented in JavaScript by a {{domxref("WritableStream")}} object. This serves as an abstraction over the top of an underlying sink — a lower-level I/O sink into which raw data is written.

- -

The data is written to the stream via a writer, one chunk at a time. A chunk can take a multitude of forms, just like the chunks in a reader. You can use whatever code you like to produce the chunks ready for writing; the writer plus the associated code is called a 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()")}} 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:

- - - -

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

- -

An important concept in streams is backpressure — this is the process by which a single stream or a pipe chain regulates the speed of reading/writing. When a stream later in the chain is still busy and isn't yet ready to accept more chunks, it sends a signal backwards through the chain to tell earlier transform streams (or the original source) to slow down delivery as appropriate so that you don't end up with a bottleneck anywhere.

- -

To use backpressure in a ReadableStream, we can ask the controller for the chunk size  desired by the consumer by querying the {{domxref("ReadableStreamDefaultController.desiredSize")}} attribute on the controller. If it is too low, our ReadableStream can tell its underlying source to stop sending data, and we backpressure along the stream chain.

- -

If later on the consumer again wants to receive data, we can use the pull method in the stream creation to tell our underlying source to feed our stream with data.

- -

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.

- - - -

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/ko/web/api/vibration_api/index.html b/files/ko/web/api/vibration_api/index.html new file mode 100644 index 0000000000..16271ff248 --- /dev/null +++ b/files/ko/web/api/vibration_api/index.html @@ -0,0 +1,100 @@ +--- +title: Vibration API +slug: Web/Guide/API/Vibration/Vibration +translation_of: Web/API/Vibration_API +--- +
{{DefaultAPISidebar("Vibration API")}}
+ +

요즘 나오는 대부분은 모바일 디바이스는 바이브레이션 하드웨어를 포함하고 있다. 소프트웨어 코드를 이용해 바이브레이션 하드웨어를 제어하면, 모바일 디바이스를 흔들리게 만들어 사용자에게 물리적인 피드백을 제공할 수 있다.

+ +

Vibration API는 웹앱들이 기기에 장착된 물리 진동장치를 통해 진동을 전달할 수 있도록 해줍니다. 하지만 대응하는 진동 장치가 없는 기기일 경우 아무일도 일어나지 않습니다.

+ +

Describing vibrations

+ +

바이브레이션은 온오프 펄스들의 패턴이라고 할 수 있는데, 이 펄스들은 아마도 다양한 길이를 가질 것이다. 이 패턴은 아마 하나의 정수값으로 구성될 수 있는데 이 정수값은 진동이 일어날 밀리세컨드 수를 의미한다. 또한 이 패턴은 정수 배열이 될 수도 있는데 이것은 진동과 정지들의 패턴을 의미한다. 바이브레이션은 {{domxref("window.navigator.vibrate()")}} 라는 하나의 메소드로 제어된다.

+ +

한번 진동시키기

+ +

여러분은 다음과 같이 하나의 값 또는 하나의 값으로 구성된 배열을 명시함으로써 바이브레이션 하드웨어를 1회 진동시킬 수 있을 것이다.

+ +
window.navigator.vibrate(200);
+window.navigator.vibrate([200]);
+
+ +

이 두 가지 예제들은 디바이스를 200ms 동안 진동시킨다.

+ +

패턴이 있는 진동 만들기

+ +

배 열에 있는 값들은 다바이스가 진동해야 하는 시간과 진동하지 않아야 하는 시간을 번갈아가며 적어놓은 것이다. 배열에 있는 각 값은 하나의 정수로 변환된 후 차례대로 장치가 진동해야 하는 시간, 장치가 진동하지 않아야 하는 시간으로 해석된다. 다음 예제를 보자.

+ +
window.navigator.vibrate([200, 100, 200]);
+
+ +

이 예제는 장치를 200ms 동안 진동시킨 후 100ms 동안 멈추게 하고 그 후 다시 200ms 동안 장치를 진동시킨다.

+ +

여 러분은 여러분이 원하는 진동/정지 페어를 명시할 수 있다. 그리고 배열 내에 홀수 또는 짝수개의 값들을 명시할 수도 있다. 이렇게 하는 이유는 각각의 진동 시간이 끝나면 디바이스의 진동은 자동적으로 멈추게 되므로 배열의 마지막 값이 정지에 해당하는 값이라면 그 값은 아무 의미가 없기 때문이다.

+ +

이미 실행중인 진동 캔슬하기

+ +

{{domxref("window.navigator.vibrate()")}} 메소드를 0값을 호출하거나, 빈 배열, 0값으로 구성된 배열로 호출하면 현재 진행중인 진동패턴은 취소될 것이다.

+ +

지속적인 진동 내보내기

+ +

Some basic setInterval and clearInterval action will allow you to create persistent vibration:

+ +
var vibrateInterval;
+
+// Starts vibration at passed in level
+function startVibrate(duration) {
+    navigator.vibrate(duration);
+}
+
+// Stops vibration
+function stopVibrate() {
+    // Clear interval and stop persistent vibrating
+    if(vibrateInterval) clearInterval(vibrateInterval);
+    navigator.vibrate(0);
+}
+
+// Start persistent vibration at given duration and interval
+// Assumes a number value is given
+function startPeristentVibrate(duration, interval) {
+    vibrateInterval = setInterval(function() {
+        startVibrate(duration);
+    }, interval);
+}
+ +

Of course the snippet above doesn't take into account the array method of vibration; persistent array-based vibration will require calculating the sum of the array items and creating an interval based on that number (with an additional delay, probably).

+ +

Why use Vibration API?

+ +

This API is clearly targeted toward mobile devices. The Vibration API would be good for alerts within mobile web applications, and would be especially awesome when used in games or media-heavy applications. Imagine watching a video on your mobile device, and during an explosion scene, your phone got a bit of a shake. Or playing Bomberman and feeling a gentle kick when a block explodes!

+ +

Specifications

+ + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('Vibration API')}}{{Spec2('Vibration API')}}Initial specification.
+ +

브라우저 호환성

+ +
{{Compat("api.Navigator.vibrate")}}
+ +

같이 보기

+ + diff --git a/files/ko/web/api/web_workers_api/basic_usage/index.html b/files/ko/web/api/web_workers_api/basic_usage/index.html deleted file mode 100644 index eb0e309e8e..0000000000 --- a/files/ko/web/api/web_workers_api/basic_usage/index.html +++ /dev/null @@ -1,908 +0,0 @@ ---- -title: 웹 워커 사용하기 -slug: Web/API/Web_Workers_API/basic_usage -translation_of: Web/API/Web_Workers_API/Using_web_workers ---- -
-

웹 워커는 웹 컨텐츠를 위해서 백그라운드 스레드에서 스크립트를 실행할 간편한 방법을 제공합니다. 워커 스레드는 사용자 인터페이스(UI)를 방해하지 않고 작업을 수행할 수 있습니다. 또한 워커는 ( responseXML 과 channel속성이 언제나 null이지만) XMLHttpRequest 를 사용하여 I/O작업을 수행할 수도 있습니다. 워커는 생성이 된 후에 생성자가 명시한 이벤트 핸들러로 메세지를 올려서 자신의 하위 작업(spawning task)에 메세지를 전달할 수 도 있습니다. 본 글에서 전용 워커와 공유 워커에 대하여 소개합니다.

-
- -

Web Workers API

- -

Worker는 생성자(예를 들면 {{domxref("Worker.Worker", "Worker()")}})를 사용하여 생성된 객체이며 이름있는 자바스크립트 파일(이 파일은 Worker 스레드에서 실행하는 코드를 가집니다)을 실행합니다. 또한 Worker는 현재의 {{domxref("window")}}와는 다른 글로벌 컨텍스트에서 실행됩니다. 따라서 {{domxref("Worker")}} 내에서 현재의 글로벌 스코프를 접근하기 위해 ({{domxref("window.self","self")}} 대신에) {{domxref("window")}}를 사용해도 오류가 돌아옵니다.

- -

Worker의 콘텍스트는 Dedicated Workers(한 개의 스크립트가 이용하는 표준적인 Workers)일 경우{{domxref("DedicatedWorkerGlobalScope")}} 객체로 제공됩니다. (Shared Workers의 경우는 {{domxref("SharedWorkerGlobalScope")}}). Dedicated Worker 는 Worker 를 처음에 생성한 스크립트만 액세스 할 수 있습니다. 반면에 Shared Worker는, 복수의 스크립트에서 액세스 할 수 있습니다.

- -
-

메모: Worker 의 레퍼런스 문서나 추가적인 가이드에 대해서는 The Web Workers API landing page를 봐 주세요.

-
- -

Worker Thread에서는 몇 가지 제한 하에서 어떤 코드라도 실행할 수 있습니다. 예를 들어, Worker내에서는 직접 DOM 를 조작할 수 없습니다. 그리고 {{domxref("window")}} 객체의 기본 메서드나 속성에서 사용할 수 없는 것들이 있습니다. 그럼에도 WebSockets과 IndexedDB, Data Store API(Firefox OS 한정)와 같은 데이터 스토리지 메커니즘 등, window에 있는 다수의 아이템을 사용할 수 있습니다.자세한 것은 Functions and classes available to workers를 봐 주세요.

- -

Worker와 메인 스레드 사이에서는 메시지 시스템을 통해 데이터를 발송합니다. 양쪽 모두 postMessage() 메서드를 사용하여 메시지를 발송하고, onmessage이벤트 핸들러에 의해 메시지에 응답합니다(메시지는 {{event("Message")}}이벤트의 data 속성에 들어갑니다). 데이터는 공유되지 않고 복사됩니다.

- -

Worker 는 새로운 Worker 를 작성할 수 있습니다만, 생성된 Worker는 같은 부모 페이지일 경우에 한합니다. 추가적으로 Worker는 네트워크 I/O를 위한 XMLHttpRequest를 사용할 수 있으나,  responseXML의 exception과 channel속성의 XMLHttpRequest는 항상 null을 반환합니다.

- -

Dedicated workers

- -

As mentioned above, a dedicated worker is only accessible by the script that called it. In this section we'll discuss the JavaScript found in our Basic dedicated worker example (run dedicated worker): This allows you to enter two numbers to be multiplied together. The numbers are sent to a dedicated worker, multiplied together, and the result is returned to the page and displayed.

- -

This example is rather trivial, but we decided to keep it simple while introducing you to basic worker concepts. More advanced details are covered later on in the article.

- -

Worker feature detection

- -

For slightly more controlled error handling and backwards compatibility, it is a good idea to wrap your worker accessing code in the following (main.js):

- -
if (window.Worker) {
-
-  ...
-
-}
- -

Spawning a dedicated worker

- -

Creating a new worker is simple. All you need to do is call the {{domxref("Worker.Worker", "Worker()")}} constructor, specifying the URI of a script to execute in the worker thread (main.js):

- -
var myWorker = new Worker("worker.js");
- -

Sending messages to and from a dedicated worker

- -

The magic of workers happens via the {{domxref("Worker.postMessage", "postMessage()")}} method and the {{domxref("Worker.onmessage", "onmessage")}} event handler. When you want to send a message to the worker, you post messages to it like this (main.js):

- -
first.onchange = function() {
-  myWorker.postMessage([first.value,second.value]);
-  console.log('Message posted to worker');
-}
-
-second.onchange = function() {
-  myWorker.postMessage([first.value,second.value]);
-  console.log('Message posted to worker');
-}
- -

So here we have two {{htmlelement("input")}} elements represented by the variables first and second; when the value of either is changed, myWorker.postMessage([first.value,second.value]) is used to send the value inside both to the worker, as an array. You can send pretty much anything you like in the message.

- -

In the worker, we can respond when the message is received by writing an event handler block like this (worker.js):

- -
onmessage = function(e) {
-  console.log('Message received from main script');
-  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
-  console.log('Posting message back to main script');
-  postMessage(workerResult);
-}
- -

The onmessage handler allows us to run some code whenever a message is received, with the message itself being available in the message event's data attribute. Here we simply multiply together the two numbers then use postMessage() again, to post the result back to the main thread.

- -

Back in the main thread, we use onmessage again, to respond to the message sent back from the worker:

- -
myWorker.onmessage = function(e) {
-  result.textContent = e.data;
-  console.log('Message received from worker');
-}
- -

Here we grab the message event data and set it as the textContent of the result paragraph, so the user can see the result of the calculation.

- -
-

Note: The URI passed as a parameter to the Worker constructor must obey the same-origin policy .

- -

There is currently disagreement among browsers vendors on what URIs are of the same-origin; Gecko 10.0 {{geckoRelease("10.0")}} and later do allow data URIs and Internet Explorer 10 does not allow Blob URIs as a valid script for workers.

-
- -
-

Note: Notice that onmessage and postMessage() need to be hung off the Worker object when used in the main script thread, but not when used in the worker. This is because, inside the worker, the worker is effectively the global scope.

-
- -
-

Note: When a message is passed between the main thread and worker, it is copied or "transferred" (moved), not shared. Read {{anch("Transferring data to and from workers further details", "Transferring data to and from workers: further details")}} for a much more thorough explanation.

-
- -

Terminating a worker

- -

If you need to immediately terminate a running worker from the main thread, you can do so by calling the worker's {{domxref("Worker", "terminate")}} method:

- -
myWorker.terminate();
- -

The worker thread is killed immediately without an opportunity to complete its operations or clean up after itself.

- -

In the worker thread, workers may close themselves by calling their own {{domxref("WorkerGlobalScope", "close")}} method:

- -
close();
- -

Handling errors

- -

When a runtime error occurs in the worker, its onerror event handler is called. It receives an event named error which implements the ErrorEvent interface.

- -

The event doesn't bubble and is cancelable; to prevent the default action from taking place, the worker can call the error event's preventDefault() method.

- -

The error event has the following three fields that are of interest:

- -
-
message
-
A human-readable error message.
-
filename
-
The name of the script file in which the error occurred.
-
lineno
-
The line number of the script file on which the error occurred.
-
- -

Spawning subworkers

- -

Workers may spawn more workers if they wish. So-called sub-workers must be hosted within the same origin as the parent page. Also, the URIs for subworkers are resolved relative to the parent worker's location rather than that of the owning page. This makes it easier for workers to keep track of where their dependencies are.

- -

Importing scripts and libraries

- -

Worker threads have access to a global function, importScripts(), which lets them import scripts. It accepts zero or more URIs as parameters to resources to import; all of the following examples are valid:

- -
importScripts();                         /* imports nothing */
-importScripts('foo.js');                 /* imports just "foo.js" */
-importScripts('foo.js', 'bar.js');       /* imports two scripts */
-importScripts('//example.com/hello.js'); /* You can import scripts from other origins */
- -

The browser loads each listed script and executes it. Any global objects from each script may then be used by the worker. If the script can't be loaded, NETWORK_ERROR is thrown, and subsequent code will not be executed. Previously executed code (including code deferred using {{domxref("window.setTimeout()")}}) will still be functional though. Function declarations after the importScripts()method are also kept, since these are always evaluated before the rest of the code.

- -
-

Note: Scripts may be downloaded in any order, but will be executed in the order in which you pass the filenames into importScripts() . This is done synchronously; importScripts() does not return until all the scripts have been loaded and executed.

-
- -

Shared workers

- -

A shared worker is accessible by multiple scripts — even if they are being accessed by different windows, iframes or even workers. In this section we'll discuss the JavaScript found in our Basic shared worker example (run shared worker): This is very similar to the basic dedicated worker example, except that it has two functions available handled by different script files: multiplying two numbers, or squaring a number. Both scripts use the same worker to do the actual calculation required.

- -

Here we'll concentrate on the differences between dedicated and shared workers. Note that in this example we have two HTML pages, each with JavaScript applied that uses the same single worker file.

- -
-

Note: If SharedWorker can be accessed from several browsing contexts, all those browsing contexts must share the exact same origin (same protocol, host, and port).

-
- -
-

Note: In Firefox, shared workers cannot be shared between documents loaded in private and non-private windows ({{bug(1177621)}}).

-
- -

Spawning a shared worker

- -

Spawning a new worker is pretty much the same as with a dedicated worker, but with a different constructor name (see index.html and index2.html) — each one has to spin up the worker using code like the following:

- -
var myWorker = new SharedWorker("worker.js");
- -

One big difference is that with a shared worker you have to communicate via a port object — an explicit port is opened that the scripts can use to communicate with the worker (this is done implicitly in the case of dedicated workers).

- -

The port connection needs to be started either implicitly by use of the onmessage event handler or explicitly with the start()method before any messages can be posted. Although the multiply.js and worker.js files in the demo currently call the start()method, those calls are not necessary since the onmessage event handler is being used. Calling start() is only needed if the message event is wired up via the addEventListener() method.

- -

When using the start() method to open the port connection, it needs to be called from both the parent thread and the worker thread if two-way communication is needed.

- -
myWorker.port.start();  // called in parent thread
- -
port.start(); // called in worker thread, assuming the port variable references a port
- -

Sending messages to and from a shared worker

- -

Now messages can be sent to the worker as before, but the postMessage() method has to be invoked through the port object (again, you'll see similar constructs in both multiply.js and square.js):

- -
squareNumber.onchange = function() {
-  myWorker.port.postMessage([squareNumber.value,squareNumber.value]);
-  console.log('Message posted to worker');
-}
- -

Now, on to the worker. There is a bit more complexity here as well (worker.js):

- -
onconnect = function(e) {
-  var port = e.ports[0];
-
-  port.onmessage = function(e) {
-    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
-    port.postMessage(workerResult);
-  }
-}
- -

First, we use an onconnect handler to fire code when a connection to the port happens (i.e. when the onmessage event handler in the parent thread is setup, or when the start() method is explicitly called in the parent thread).

- -

We use the ports attribute of this event object to grab the port and store it in a variable.

- -

Next, we add a message handler on the port to do the calculation and return the result to the main thread. Setting up this messagehandler in the worker thread also implicitly opens the port connection back to the parent thread, so the call to port.start() is not actually needed, as noted above.

- -

Finally, back in the main script, we deal with the message (again, you'll see similar constructs in both multiply.js and square.js):

- -
myWorker.port.onmessage = function(e) {
-  result2.textContent = e.data;
-  console.log('Message received from worker');
-}
- -

When a message comes back through the port from the worker, we check what result type it is, then insert the calculation result inside the appropriate result paragraph.

- -

About thread safety

- -

The {{domxref("Worker")}} interface spawns real OS-level threads, and mindful programmers may be concerned that concurrency can cause “interesting” effects in your code if you aren't careful.

- -

However, since web workers have carefully controlled communication points with other threads, it's actually very hard to cause concurrency problems. There's no access to non-threadsafe components or the DOM. And you have to pass specific data in and out of a thread through serialized objects. So you have to work really hard to cause problems in your code.

- -

Content security policy

- -

Workers are considered to have their own execution context, distinct from the document that created them. For this reasons they are, in general, not governed by the content security policy of the document (or parent worker) that created them. So for example, suppose a document is served with the following header:

- -
Content-Security-Policy: script-src 'self'
- -

Among other things, this will prevent any scripts it includes from using eval(). However, if the script constructs a worker, code running in the worker's context will be allowed to use eval().
-
- To specify a content security policy for the worker, set a Content-Security-Policy response header for the request which delivered the worker script itself.
-
- The exception to this is if the worker script's origin is a globally unique identifier (for example, if its URL has a scheme of data or blob). In this case, the worker does inherit the CSP of the document or worker than created it.

- -

Transferring data to and from workers: further details

- -

Data passed between the main page and workers is copied, not shared. Objects are serialized as they're handed to the worker, and subsequently, de-serialized on the other end. The page and worker do not share the same instance, so the end result is that a duplicate is created on each end. Most browsers implement this feature as structured cloning.

- -

To illustrate this, let's create for didactical purpose a function named emulateMessage(), which will simulate the behavior of a value that is cloned and not shared during the passage from a worker to the main page or vice versa:

- -
function emulateMessage (vVal) {
-    return eval("(" + JSON.stringify(vVal) + ")");
-}
-
-// Tests
-
-// test #1
-var example1 = new Number(3);
-console.log(typeof example1); // object
-console.log(typeof emulateMessage(example1)); // number
-
-// test #2
-var example2 = true;
-console.log(typeof example2); // boolean
-console.log(typeof emulateMessage(example2)); // boolean
-
-// test #3
-var example3 = new String("Hello World");
-console.log(typeof example3); // object
-console.log(typeof emulateMessage(example3)); // string
-
-// test #4
-var example4 = {
-    "name": "John Smith",
-    "age": 43
-};
-console.log(typeof example4); // object
-console.log(typeof emulateMessage(example4)); // object
-
-// test #5
-function Animal (sType, nAge) {
-    this.type = sType;
-    this.age = nAge;
-}
-var example5 = new Animal("Cat", 3);
-alert(example5.constructor); // Animal
-alert(emulateMessage(example5).constructor); // Object
- -

A value that is cloned and not shared is called message. As you will probably know by now, messages can be sent to and from the main thread by using postMessage(), and the message event's {{domxref("MessageEvent.data", "data")}} attribute contains data passed back from the worker.

- -

example.html: (the main page):

- -
var myWorker = new Worker("my_task.js");
-
-myWorker.onmessage = function (oEvent) {
-  console.log("Worker said : " + oEvent.data);
-};
-
-myWorker.postMessage("ali");
- -

my_task.js (the worker):

- -
postMessage("I\'m working before postMessage(\'ali\').");
-
-onmessage = function (oEvent) {
-  postMessage("Hi " + oEvent.data);
-};
- -

The structured cloning algorithm can accept JSON and a few things that JSON can't — like circular references.

- -

Passing data examples

- -

Example #1: Create a generic "asynchronous eval()"

- -

The following example shows how to use a worker in order to asynchronously execute any JavaScript code allowed in a worker, through eval() within the worker:

- -
// Syntax: asyncEval(code[, listener])
-
-var asyncEval = (function () {
-  var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D");
-
-  oParser.onmessage = function (oEvent) {
-    if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); }
-    delete aListeners[oEvent.data.id];
-  };
-
-  return function (sCode, fListener) {
-    aListeners.push(fListener || null);
-    oParser.postMessage({
-      "id": aListeners.length - 1,
-      "code": sCode
-    });
-  };
-})();
- -

The data URL is equivalent to a network request, with the following response:

- -
onmessage = function (oEvent) {
-  postMessage({
-    "id": oEvent.data.id,
-    "evaluated": eval(oEvent.data.code)
-  });
-}
- -

Sample usage:

- -
// asynchronous alert message...
-asyncEval("3 + 2", function (sMessage) {
-    alert("3 + 2 = " + sMessage);
-});
-
-// asynchronous print message...
-asyncEval("\"Hello World!!!\"", function (sHTML) {
-    document.body.appendChild(document.createTextNode(sHTML));
-});
-
-// asynchronous void...
-asyncEval("(function () {\n\tvar oReq = new XMLHttpRequest();\n\toReq.open(\"get\", \"http://www.mozilla.org/\", false);\n\toReq.send(null);\n\treturn oReq.responseText;\n})()");
- -

Example #2: Advanced passing JSON Data and creating a switching system

- -

If you have to pass some complex data and have to call many different functions both on the main page and in the Worker, you can create a system which groups everything together.

- -

First, we create a QueryableWorker class that takes the url of the worker, a default listener, and an error handler, and this class is gonna keep track of a list of listeners and help us communicate wirh the worker:

- -
function QueryableWorker(url, defaultListener, onError){
-    var instance = this,
-        worker = new Worker(url),
-        listeners = {};
-
-    this.defaultListener = defaultListener || function(){};
-
-    if (onError) {worker.onerror = onError;}
-
-    this.postMessage = function(message){
-        worker.postMessage(message);
-    }
-
-    this.terminate = function(){
-        worker.terminate();
-    }
-}
- -

Then we add the methods of adding/removing listeners:

- -
this.addListeners = function(name, listener){
-    listeners[name] = listener;
-}
-
-this.removeListeners = function(name){
-    delete listeners[name];
-}
- -

Here we let the worker handle two simple operations for illuatration: getting the difference of two numbers and making an alert after three seconds. In order to acheieve that we first implement a sendQuery method which queries if the worker actually has the corresponding methods to do what we want.

- -
/*
-  This functions takes at least one argument, the method name we want to query.
-  Then we can pass in the arguments that the method needs.
- */
-this.sendQuery = function(){
-    if (arguments.length < 1){
-         throw new TypeError("QueryableWorker.sendQuery takes at least one argument");
-         return;
-    }
-    worker.postMessage({
-        "queryMethod": arguments[0],
-        "queryArguments": Array.prototype.slice.call(arguments, 1)
-    });
-}
- -

We finish QueryableWorker with the onmessage method. If the worker has the corresponding methods we queried, it should return the name of the corresponding listener and the arguments it needs, we just need to find it in listeners.:

- -
worker.onmessage = function(event){
-    if (event.data instanceof Object &&
-        event.data.hasOwnProperty("queryMethodListener") &&
-        event.data.hasOwnProperty("queryMethodArguments")){
-        listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
-    } else {
-        this.defaultListener.call(instance, event.data);
-    }
-}
- -

Now onto the worker.  First we need to have the methods to handle the two simple operations:

- -
var queryableFunctions = {
-    getDifference: function(a, b){
-        reply("printStuff", a - b);
-    },
-    waitSomeTime: function(){
-        setTimeout(function(){
-            reply("doAlert", 3, "seconds");
-        }, 3000);
-    }
-}
-
-function reply(){
-    if (arguments.length < 1) {
-        throw new TypeError("reply - takes at least one argument");
-        return;
-    }
-    postMessage({
-        queryMethodListener: arguments[0],
-        queryMethodArguments: Array.prototype.slice.call(arguments, 1)
-    });
-}
-
-/* This method is called when main page calls QueryWorker's postMessage method directly*/
-function defaultReply(message){
-    // do something
-}
- -

And the onmessage method is now trivial:

- -
onmessage = function(event){
-    if (event.data instanceof Object &&
-        event.data.hasOwnProperty("queryMethod") &&
-        event.data.hasOwnProperty("queryMethodArguments")){
-        queryableFunctions[event.data.queryMethod]
-            .apply(self, event.data.queryMethodArguments);
-    } else {
-        defaultReply(event.data);
-    }
-}
- -

Here are the full implementation:

- -

example.html (the main page):

- -
<!doctype html>
-  <html>
-    <head>
-      <meta charset="UTF-8"  />
-      <title>MDN Example - Queryable worker</title>
-    <script type="text/javascript">
-    /*
-      QueryableWorker instances methods:
-        * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
-        * postMessage(string or JSON Data): see Worker.prototype.postMessage()
-        * terminate(): terminates the Worker
-        * addListener(name, function): adds a listener
-        * removeListener(name): removes a listener
-      QueryableWorker instances properties:
-        * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
-     */
-    function QueryableWorker(url, defaultListener, onError){
-      var instance = this,
-      worker = new Worker(url),
-      listeners = {};
-
-      this.defaultListener = defaultListener || function(){};
-
-      if (onError) {worker.onerror = onError;}
-
-      this.postMessage = function(message){
-        worker.postMessage(message);
-      }
-
-      this.terminate = function(){
-        worker.terminate();
-      }
-
-      this.addListeners = function(name, listener){
-        listeners[name] = listener;
-      }
-
-      this.removeListeners = function(name){
-        delete listeners[name];
-      }
-
-      worker.onmessage = function(event){
-        if (event.data instanceof Object &&
-          event.data.hasOwnProperty("queryMethodListener") &&
-          event.data.hasOwnProperty("queryMethodArguments")){
-          listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
-        } else {
-          this.defaultListener.call(instance, event.data);
-        }
-      }
-    }
-
-    // your custom "queryable" worker
-    var myTask = new QueryableWorker("my_task.js");
-
-    // your custom "listeners"
-    myTask.addListener("printStuff", function (result) {
-      document.getElementById("firstLink").parentNode.appendChild(document.createTextNode(" The difference is " + result + "!"));
-    });
-
-    myTask.addListener("doAlert", function (time, unit) {
-      alert("Worker waited for " + time + " " + unit + " :-)");
-    });
-</script>
-</head>
-<body>
-  <ul>
-    <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li>
-    <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li>
-    <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li>
-  </ul>
-</body>
-</html>
- -

my_task.js (the worker):

- -
var queryableFunctions = {
-  // example #1: get the difference between two numbers:
-  getDifference: function (nMinuend, nSubtrahend) {
-      reply("printSomething", nMinuend - nSubtrahend);
-  },
-  // example #2: wait three seconds
-  waitSomeTime: function () {
-      setTimeout(function() { reply("doAlert", 3, "seconds"); }, 3000);
-  }
-};
-
-// system functions
-
-function defaultReply (message) {
-  // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
-  // do something
-}
-
-function reply () {
-  if (arguments.length < 1) { throw new TypeError("reply - not enough arguments"); return; }
-  postMessage({ "queryMethodListener": arguments[0], "queryMethodArguments": Array.prototype.slice.call(arguments, 1) });
-}
-
-onmessage = function (oEvent) {
-  if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty("queryMethod") && oEvent.data.hasOwnProperty("queryMethodArguments")) {
-    queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments);
-  } else {
-    defaultReply(oEvent.data);
-  }
-};
- -

It is possible to switch the content of each mainpage -> worker and worker -> mainpage message. And the property names "queryMethod", "queryMethodListeners", "queryMethodArguments" can be anything as long as they are consistent in QueryableWorker and the worker.

- -

Passing data by transferring ownership (transferable objects)

- -

Google Chrome 17+ and Firefox 18+ contain an additional way to pass certain types of objects (transferable objects, that is objects implementing the {{domxref("Transferable")}} interface) to or from a worker with high performance. Transferable objects are transferred from one context to another with a zero-copy operation, which results in a vast performance improvement when sending large data sets. Think of it as pass-by-reference if you're from the C/C++ world. However, unlike pass-by-reference, the 'version' from the calling context is no longer available once transferred. Its ownership is transferred to the new context. For example, when transferring an {{domxref("ArrayBuffer")}} from your main app to a worker script, the original {{domxref("ArrayBuffer")}} is cleared and no longer usable. Its content is (quite literally) transferred to the worker context.

- -
// Create a 32MB "file" and fill it.
-var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
-for (var i = 0; i < uInt8Array.length; ++i) {
-  uInt8Array[i] = i;
-}
-
-worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
- -
-

Note: For more information on transferable objects, performance, and feature-detection for this method, read Transferable Objects: Lightning Fast! on HTML5 Rocks.

-
- -

Embedded workers

- -

There is not an "official" way to embed the code of a worker within a web page, like {{HTMLElement("script")}} elements do for normal scripts. But a {{HTMLElement("script")}} element that does not have a src attribute and has a type attribute that does not identify an executable MIME type can be considered a data block element that JavaScript could use. "Data blocks" is a more general feature of HTML5 that can carry almost any textual data. So, a worker could be embedded in this way:

- -
<!DOCTYPE html>
-<html>
-<head>
-<meta charset="UTF-8" />
-<title>MDN Example - Embedded worker</title>
-<script type="text/js-worker">
-  // This script WON'T be parsed by JS engines because its MIME type is text/js-worker.
-  var myVar = "Hello World!";
-  // Rest of your worker code goes here.
-</script>
-<script type="text/javascript">
-  // This script WILL be parsed by JS engines because its MIME type is text/javascript.
-  function pageLog (sMsg) {
-    // Use a fragment: browser will only render/reflow once.
-    var oFragm = document.createDocumentFragment();
-    oFragm.appendChild(document.createTextNode(sMsg));
-    oFragm.appendChild(document.createElement("br"));
-    document.querySelector("#logDisplay").appendChild(oFragm);
-  }
-</script>
-<script type="text/js-worker">
-  // This script WON'T be parsed by JS engines because its MIME type is text/js-worker.
-  onmessage = function (oEvent) {
-    postMessage(myVar);
-  };
-  // Rest of your worker code goes here.
-</script>
-<script type="text/javascript">
-  // This script WILL be parsed by JS engines because its MIME type is text/javascript.
-
-  // In the past...:
-  // blob builder existed
-  // ...but now we use Blob...:
-  var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"});
-
-  // Creating a new document.worker property containing all our "text/js-worker" scripts.
-  document.worker = new Worker(window.URL.createObjectURL(blob));
-
-  document.worker.onmessage = function (oEvent) {
-    pageLog("Received: " + oEvent.data);
-  };
-
-  // Start the worker.
-  window.onload = function() { document.worker.postMessage(""); };
-</script>
-</head>
-<body><div id="logDisplay"></div></body>
-</html>
- -

The embedded worker is now nested into a new custom document.worker property.

- -

It is also worth noting that you can also convert a function into a Blob, then generate an object URL from that blob. For example:

- -
function fn2workerURL(fn) {
-  var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'})
-  return URL.createObjectURL(blob)
-}
- -

Further examples

- -

This section provides further examples of how to use web workers.

- -

Performing computations in the background

- -

Workers are mainly useful for allowing your code to perform processor-intensive calculations without blocking the user interface thread. In this example, a worker is used to calculate Fibonacci numbers.

- -

The JavaScript code

- -

The following JavaScript code is stored in the "fibonacci.js" file referenced by the HTML in the next section.

- -
var results = [];
-
-function resultReceiver(event) {
-  results.push(parseInt(event.data));
-  if (results.length == 2) {
-    postMessage(results[0] + results[1]);
-  }
-}
-
-function errorReceiver(event) {
-  throw event.data;
-}
-
-onmessage = function(event) {
-  var n = parseInt(event.data);
-
-  if (n == 0 || n == 1) {
-    postMessage(n);
-    return;
-  }
-
-  for (var i = 1; i <= 2; i++) {
-    var worker = new Worker("fibonacci.js");
-    worker.onmessage = resultReceiver;
-    worker.onerror = errorReceiver;
-    worker.postMessage(n - i);
-  }
- };
- -

The worker sets the property onmessage to a function which will receive messages sent when the worker object's postMessage() is called (note that this differs from defining a global variable of that name, or defining a function with that name. var onmessage and function onmessage will define global properties with those names, but they will not register the function to receive messages sent by the web page that created the worker). This starts the recursion, spawning new copies of itself to handle each iteration of the calculation.

- -

The HTML code

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="UTF-8"  />
-    <title>Test threads fibonacci</title>
-  </head>
-  <body>
-
-  <div id="result"></div>
-
-  <script language="javascript">
-
-    var worker = new Worker("fibonacci.js");
-
-    worker.onmessage = function(event) {
-      document.getElementById("result").textContent = event.data;
-      dump("Got: " + event.data + "\n");
-    };
-
-    worker.onerror = function(error) {
-      dump("Worker error: " + error.message + "\n");
-      throw error;
-    };
-
-    worker.postMessage("5");
-
-  </script>
-  </body>
-</html>
- -

The web page creates a div element with the ID result , which gets used to display the result, then spawns the worker. After spawning the worker, the onmessage handler is configured to display the results by setting the contents of the div element, and the onerror handler is set to dump the error message.

- -

Finally, a message is sent to the worker to start it.

- -

Try this example.

- -

Performing web I/O in the background

- -

You can find an example of this in the article Using workers in extensions .

- -

Dividing tasks among multiple workers

- -

As multi-core computers become increasingly common, it's often useful to divide computationally complex tasks among multiple workers, which may then perform those tasks on multiple-processor cores.

- -

Other types of worker

- -

In addition to dedicated and shared web workers, there are other types of worker available:

- - - -

Functions and interfaces available in workers

- -

You can use most standard JavaScript features inside a web worker, including:

- - - -

The main thing you can't do in a Worker is directly affect the parent page. This includes manipulating the DOM and using that page's objects. You have to do it indirectly, by sending a message back to the main script via {{domxref("DedicatedWorkerGlobalScope.postMessage")}}, then actioning the changes from there.

- -
-

Note: For a complete list of functions available to workers, see Functions and interfaces available to workers.

-
- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#toc-workers')}}{{Spec2('HTML WHATWG')}}No change from {{SpecName("Web Workers")}}.
{{SpecName('Web Workers')}}{{Spec2('Web Workers')}}Initial definition.
- -

Browser compatibility

- -

{{CompatibilityTable}}

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support4[1]{{CompatGeckoDesktop("1.9.1")}}10.010.6[1]4[2]
Shared workers4[1]{{CompatGeckoDesktop(29)}}{{CompatNo}}10.65
- {{CompatNo}} 6.1[4]
Passing data using structured cloning13{{CompatGeckoDesktop(8)}}10.011.56
Passing data using transferable objects17 {{property_prefix("webkit")}}
- 21
{{CompatGeckoDesktop(18)}}{{CompatNo}}156
Global {{domxref("window.URL", "URL")}}10[3]
- 23
{{CompatGeckoDesktop(21)}}11156[3]
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support4.44[1]3.51.0.110.011.5[1]5.1[2]
Shared workers{{CompatNo}}4[1]81.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using structured cloning{{CompatNo}}481.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using transferable objects{{CompatNo}}{{CompatNo}}181.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
- -

[1] Chrome and Opera give an error "Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///Path/to/worker.js' cannot be accessed from origin 'null'." when you try to run a worker locally. It needs to be on a proper domain.

- -

[2] As of Safari 7.1.2, you can call console.log from inside a worker, but it won't print anything to the console. Older versions of Safari don't allow you to call console.log from inside a worker.

- -

[3] This feature is implemented prefixed as webkitURL.

- -

[4] Safari removed SharedWorker support.

- -

See also

- - diff --git a/files/ko/web/api/web_workers_api/using_web_workers/index.html b/files/ko/web/api/web_workers_api/using_web_workers/index.html new file mode 100644 index 0000000000..eb0e309e8e --- /dev/null +++ b/files/ko/web/api/web_workers_api/using_web_workers/index.html @@ -0,0 +1,908 @@ +--- +title: 웹 워커 사용하기 +slug: Web/API/Web_Workers_API/basic_usage +translation_of: Web/API/Web_Workers_API/Using_web_workers +--- +
+

웹 워커는 웹 컨텐츠를 위해서 백그라운드 스레드에서 스크립트를 실행할 간편한 방법을 제공합니다. 워커 스레드는 사용자 인터페이스(UI)를 방해하지 않고 작업을 수행할 수 있습니다. 또한 워커는 ( responseXML 과 channel속성이 언제나 null이지만) XMLHttpRequest 를 사용하여 I/O작업을 수행할 수도 있습니다. 워커는 생성이 된 후에 생성자가 명시한 이벤트 핸들러로 메세지를 올려서 자신의 하위 작업(spawning task)에 메세지를 전달할 수 도 있습니다. 본 글에서 전용 워커와 공유 워커에 대하여 소개합니다.

+
+ +

Web Workers API

+ +

Worker는 생성자(예를 들면 {{domxref("Worker.Worker", "Worker()")}})를 사용하여 생성된 객체이며 이름있는 자바스크립트 파일(이 파일은 Worker 스레드에서 실행하는 코드를 가집니다)을 실행합니다. 또한 Worker는 현재의 {{domxref("window")}}와는 다른 글로벌 컨텍스트에서 실행됩니다. 따라서 {{domxref("Worker")}} 내에서 현재의 글로벌 스코프를 접근하기 위해 ({{domxref("window.self","self")}} 대신에) {{domxref("window")}}를 사용해도 오류가 돌아옵니다.

+ +

Worker의 콘텍스트는 Dedicated Workers(한 개의 스크립트가 이용하는 표준적인 Workers)일 경우{{domxref("DedicatedWorkerGlobalScope")}} 객체로 제공됩니다. (Shared Workers의 경우는 {{domxref("SharedWorkerGlobalScope")}}). Dedicated Worker 는 Worker 를 처음에 생성한 스크립트만 액세스 할 수 있습니다. 반면에 Shared Worker는, 복수의 스크립트에서 액세스 할 수 있습니다.

+ +
+

메모: Worker 의 레퍼런스 문서나 추가적인 가이드에 대해서는 The Web Workers API landing page를 봐 주세요.

+
+ +

Worker Thread에서는 몇 가지 제한 하에서 어떤 코드라도 실행할 수 있습니다. 예를 들어, Worker내에서는 직접 DOM 를 조작할 수 없습니다. 그리고 {{domxref("window")}} 객체의 기본 메서드나 속성에서 사용할 수 없는 것들이 있습니다. 그럼에도 WebSockets과 IndexedDB, Data Store API(Firefox OS 한정)와 같은 데이터 스토리지 메커니즘 등, window에 있는 다수의 아이템을 사용할 수 있습니다.자세한 것은 Functions and classes available to workers를 봐 주세요.

+ +

Worker와 메인 스레드 사이에서는 메시지 시스템을 통해 데이터를 발송합니다. 양쪽 모두 postMessage() 메서드를 사용하여 메시지를 발송하고, onmessage이벤트 핸들러에 의해 메시지에 응답합니다(메시지는 {{event("Message")}}이벤트의 data 속성에 들어갑니다). 데이터는 공유되지 않고 복사됩니다.

+ +

Worker 는 새로운 Worker 를 작성할 수 있습니다만, 생성된 Worker는 같은 부모 페이지일 경우에 한합니다. 추가적으로 Worker는 네트워크 I/O를 위한 XMLHttpRequest를 사용할 수 있으나,  responseXML의 exception과 channel속성의 XMLHttpRequest는 항상 null을 반환합니다.

+ +

Dedicated workers

+ +

As mentioned above, a dedicated worker is only accessible by the script that called it. In this section we'll discuss the JavaScript found in our Basic dedicated worker example (run dedicated worker): This allows you to enter two numbers to be multiplied together. The numbers are sent to a dedicated worker, multiplied together, and the result is returned to the page and displayed.

+ +

This example is rather trivial, but we decided to keep it simple while introducing you to basic worker concepts. More advanced details are covered later on in the article.

+ +

Worker feature detection

+ +

For slightly more controlled error handling and backwards compatibility, it is a good idea to wrap your worker accessing code in the following (main.js):

+ +
if (window.Worker) {
+
+  ...
+
+}
+ +

Spawning a dedicated worker

+ +

Creating a new worker is simple. All you need to do is call the {{domxref("Worker.Worker", "Worker()")}} constructor, specifying the URI of a script to execute in the worker thread (main.js):

+ +
var myWorker = new Worker("worker.js");
+ +

Sending messages to and from a dedicated worker

+ +

The magic of workers happens via the {{domxref("Worker.postMessage", "postMessage()")}} method and the {{domxref("Worker.onmessage", "onmessage")}} event handler. When you want to send a message to the worker, you post messages to it like this (main.js):

+ +
first.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+
+second.onchange = function() {
+  myWorker.postMessage([first.value,second.value]);
+  console.log('Message posted to worker');
+}
+ +

So here we have two {{htmlelement("input")}} elements represented by the variables first and second; when the value of either is changed, myWorker.postMessage([first.value,second.value]) is used to send the value inside both to the worker, as an array. You can send pretty much anything you like in the message.

+ +

In the worker, we can respond when the message is received by writing an event handler block like this (worker.js):

+ +
onmessage = function(e) {
+  console.log('Message received from main script');
+  var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+  console.log('Posting message back to main script');
+  postMessage(workerResult);
+}
+ +

The onmessage handler allows us to run some code whenever a message is received, with the message itself being available in the message event's data attribute. Here we simply multiply together the two numbers then use postMessage() again, to post the result back to the main thread.

+ +

Back in the main thread, we use onmessage again, to respond to the message sent back from the worker:

+ +
myWorker.onmessage = function(e) {
+  result.textContent = e.data;
+  console.log('Message received from worker');
+}
+ +

Here we grab the message event data and set it as the textContent of the result paragraph, so the user can see the result of the calculation.

+ +
+

Note: The URI passed as a parameter to the Worker constructor must obey the same-origin policy .

+ +

There is currently disagreement among browsers vendors on what URIs are of the same-origin; Gecko 10.0 {{geckoRelease("10.0")}} and later do allow data URIs and Internet Explorer 10 does not allow Blob URIs as a valid script for workers.

+
+ +
+

Note: Notice that onmessage and postMessage() need to be hung off the Worker object when used in the main script thread, but not when used in the worker. This is because, inside the worker, the worker is effectively the global scope.

+
+ +
+

Note: When a message is passed between the main thread and worker, it is copied or "transferred" (moved), not shared. Read {{anch("Transferring data to and from workers further details", "Transferring data to and from workers: further details")}} for a much more thorough explanation.

+
+ +

Terminating a worker

+ +

If you need to immediately terminate a running worker from the main thread, you can do so by calling the worker's {{domxref("Worker", "terminate")}} method:

+ +
myWorker.terminate();
+ +

The worker thread is killed immediately without an opportunity to complete its operations or clean up after itself.

+ +

In the worker thread, workers may close themselves by calling their own {{domxref("WorkerGlobalScope", "close")}} method:

+ +
close();
+ +

Handling errors

+ +

When a runtime error occurs in the worker, its onerror event handler is called. It receives an event named error which implements the ErrorEvent interface.

+ +

The event doesn't bubble and is cancelable; to prevent the default action from taking place, the worker can call the error event's preventDefault() method.

+ +

The error event has the following three fields that are of interest:

+ +
+
message
+
A human-readable error message.
+
filename
+
The name of the script file in which the error occurred.
+
lineno
+
The line number of the script file on which the error occurred.
+
+ +

Spawning subworkers

+ +

Workers may spawn more workers if they wish. So-called sub-workers must be hosted within the same origin as the parent page. Also, the URIs for subworkers are resolved relative to the parent worker's location rather than that of the owning page. This makes it easier for workers to keep track of where their dependencies are.

+ +

Importing scripts and libraries

+ +

Worker threads have access to a global function, importScripts(), which lets them import scripts. It accepts zero or more URIs as parameters to resources to import; all of the following examples are valid:

+ +
importScripts();                         /* imports nothing */
+importScripts('foo.js');                 /* imports just "foo.js" */
+importScripts('foo.js', 'bar.js');       /* imports two scripts */
+importScripts('//example.com/hello.js'); /* You can import scripts from other origins */
+ +

The browser loads each listed script and executes it. Any global objects from each script may then be used by the worker. If the script can't be loaded, NETWORK_ERROR is thrown, and subsequent code will not be executed. Previously executed code (including code deferred using {{domxref("window.setTimeout()")}}) will still be functional though. Function declarations after the importScripts()method are also kept, since these are always evaluated before the rest of the code.

+ +
+

Note: Scripts may be downloaded in any order, but will be executed in the order in which you pass the filenames into importScripts() . This is done synchronously; importScripts() does not return until all the scripts have been loaded and executed.

+
+ +

Shared workers

+ +

A shared worker is accessible by multiple scripts — even if they are being accessed by different windows, iframes or even workers. In this section we'll discuss the JavaScript found in our Basic shared worker example (run shared worker): This is very similar to the basic dedicated worker example, except that it has two functions available handled by different script files: multiplying two numbers, or squaring a number. Both scripts use the same worker to do the actual calculation required.

+ +

Here we'll concentrate on the differences between dedicated and shared workers. Note that in this example we have two HTML pages, each with JavaScript applied that uses the same single worker file.

+ +
+

Note: If SharedWorker can be accessed from several browsing contexts, all those browsing contexts must share the exact same origin (same protocol, host, and port).

+
+ +
+

Note: In Firefox, shared workers cannot be shared between documents loaded in private and non-private windows ({{bug(1177621)}}).

+
+ +

Spawning a shared worker

+ +

Spawning a new worker is pretty much the same as with a dedicated worker, but with a different constructor name (see index.html and index2.html) — each one has to spin up the worker using code like the following:

+ +
var myWorker = new SharedWorker("worker.js");
+ +

One big difference is that with a shared worker you have to communicate via a port object — an explicit port is opened that the scripts can use to communicate with the worker (this is done implicitly in the case of dedicated workers).

+ +

The port connection needs to be started either implicitly by use of the onmessage event handler or explicitly with the start()method before any messages can be posted. Although the multiply.js and worker.js files in the demo currently call the start()method, those calls are not necessary since the onmessage event handler is being used. Calling start() is only needed if the message event is wired up via the addEventListener() method.

+ +

When using the start() method to open the port connection, it needs to be called from both the parent thread and the worker thread if two-way communication is needed.

+ +
myWorker.port.start();  // called in parent thread
+ +
port.start(); // called in worker thread, assuming the port variable references a port
+ +

Sending messages to and from a shared worker

+ +

Now messages can be sent to the worker as before, but the postMessage() method has to be invoked through the port object (again, you'll see similar constructs in both multiply.js and square.js):

+ +
squareNumber.onchange = function() {
+  myWorker.port.postMessage([squareNumber.value,squareNumber.value]);
+  console.log('Message posted to worker');
+}
+ +

Now, on to the worker. There is a bit more complexity here as well (worker.js):

+ +
onconnect = function(e) {
+  var port = e.ports[0];
+
+  port.onmessage = function(e) {
+    var workerResult = 'Result: ' + (e.data[0] * e.data[1]);
+    port.postMessage(workerResult);
+  }
+}
+ +

First, we use an onconnect handler to fire code when a connection to the port happens (i.e. when the onmessage event handler in the parent thread is setup, or when the start() method is explicitly called in the parent thread).

+ +

We use the ports attribute of this event object to grab the port and store it in a variable.

+ +

Next, we add a message handler on the port to do the calculation and return the result to the main thread. Setting up this messagehandler in the worker thread also implicitly opens the port connection back to the parent thread, so the call to port.start() is not actually needed, as noted above.

+ +

Finally, back in the main script, we deal with the message (again, you'll see similar constructs in both multiply.js and square.js):

+ +
myWorker.port.onmessage = function(e) {
+  result2.textContent = e.data;
+  console.log('Message received from worker');
+}
+ +

When a message comes back through the port from the worker, we check what result type it is, then insert the calculation result inside the appropriate result paragraph.

+ +

About thread safety

+ +

The {{domxref("Worker")}} interface spawns real OS-level threads, and mindful programmers may be concerned that concurrency can cause “interesting” effects in your code if you aren't careful.

+ +

However, since web workers have carefully controlled communication points with other threads, it's actually very hard to cause concurrency problems. There's no access to non-threadsafe components or the DOM. And you have to pass specific data in and out of a thread through serialized objects. So you have to work really hard to cause problems in your code.

+ +

Content security policy

+ +

Workers are considered to have their own execution context, distinct from the document that created them. For this reasons they are, in general, not governed by the content security policy of the document (or parent worker) that created them. So for example, suppose a document is served with the following header:

+ +
Content-Security-Policy: script-src 'self'
+ +

Among other things, this will prevent any scripts it includes from using eval(). However, if the script constructs a worker, code running in the worker's context will be allowed to use eval().
+
+ To specify a content security policy for the worker, set a Content-Security-Policy response header for the request which delivered the worker script itself.
+
+ The exception to this is if the worker script's origin is a globally unique identifier (for example, if its URL has a scheme of data or blob). In this case, the worker does inherit the CSP of the document or worker than created it.

+ +

Transferring data to and from workers: further details

+ +

Data passed between the main page and workers is copied, not shared. Objects are serialized as they're handed to the worker, and subsequently, de-serialized on the other end. The page and worker do not share the same instance, so the end result is that a duplicate is created on each end. Most browsers implement this feature as structured cloning.

+ +

To illustrate this, let's create for didactical purpose a function named emulateMessage(), which will simulate the behavior of a value that is cloned and not shared during the passage from a worker to the main page or vice versa:

+ +
function emulateMessage (vVal) {
+    return eval("(" + JSON.stringify(vVal) + ")");
+}
+
+// Tests
+
+// test #1
+var example1 = new Number(3);
+console.log(typeof example1); // object
+console.log(typeof emulateMessage(example1)); // number
+
+// test #2
+var example2 = true;
+console.log(typeof example2); // boolean
+console.log(typeof emulateMessage(example2)); // boolean
+
+// test #3
+var example3 = new String("Hello World");
+console.log(typeof example3); // object
+console.log(typeof emulateMessage(example3)); // string
+
+// test #4
+var example4 = {
+    "name": "John Smith",
+    "age": 43
+};
+console.log(typeof example4); // object
+console.log(typeof emulateMessage(example4)); // object
+
+// test #5
+function Animal (sType, nAge) {
+    this.type = sType;
+    this.age = nAge;
+}
+var example5 = new Animal("Cat", 3);
+alert(example5.constructor); // Animal
+alert(emulateMessage(example5).constructor); // Object
+ +

A value that is cloned and not shared is called message. As you will probably know by now, messages can be sent to and from the main thread by using postMessage(), and the message event's {{domxref("MessageEvent.data", "data")}} attribute contains data passed back from the worker.

+ +

example.html: (the main page):

+ +
var myWorker = new Worker("my_task.js");
+
+myWorker.onmessage = function (oEvent) {
+  console.log("Worker said : " + oEvent.data);
+};
+
+myWorker.postMessage("ali");
+ +

my_task.js (the worker):

+ +
postMessage("I\'m working before postMessage(\'ali\').");
+
+onmessage = function (oEvent) {
+  postMessage("Hi " + oEvent.data);
+};
+ +

The structured cloning algorithm can accept JSON and a few things that JSON can't — like circular references.

+ +

Passing data examples

+ +

Example #1: Create a generic "asynchronous eval()"

+ +

The following example shows how to use a worker in order to asynchronously execute any JavaScript code allowed in a worker, through eval() within the worker:

+ +
// Syntax: asyncEval(code[, listener])
+
+var asyncEval = (function () {
+  var aListeners = [], oParser = new Worker("data:text/javascript;charset=US-ASCII,onmessage%20%3D%20function%20%28oEvent%29%20%7B%0A%09postMessage%28%7B%0A%09%09%22id%22%3A%20oEvent.data.id%2C%0A%09%09%22evaluated%22%3A%20eval%28oEvent.data.code%29%0A%09%7D%29%3B%0A%7D");
+
+  oParser.onmessage = function (oEvent) {
+    if (aListeners[oEvent.data.id]) { aListeners[oEvent.data.id](oEvent.data.evaluated); }
+    delete aListeners[oEvent.data.id];
+  };
+
+  return function (sCode, fListener) {
+    aListeners.push(fListener || null);
+    oParser.postMessage({
+      "id": aListeners.length - 1,
+      "code": sCode
+    });
+  };
+})();
+ +

The data URL is equivalent to a network request, with the following response:

+ +
onmessage = function (oEvent) {
+  postMessage({
+    "id": oEvent.data.id,
+    "evaluated": eval(oEvent.data.code)
+  });
+}
+ +

Sample usage:

+ +
// asynchronous alert message...
+asyncEval("3 + 2", function (sMessage) {
+    alert("3 + 2 = " + sMessage);
+});
+
+// asynchronous print message...
+asyncEval("\"Hello World!!!\"", function (sHTML) {
+    document.body.appendChild(document.createTextNode(sHTML));
+});
+
+// asynchronous void...
+asyncEval("(function () {\n\tvar oReq = new XMLHttpRequest();\n\toReq.open(\"get\", \"http://www.mozilla.org/\", false);\n\toReq.send(null);\n\treturn oReq.responseText;\n})()");
+ +

Example #2: Advanced passing JSON Data and creating a switching system

+ +

If you have to pass some complex data and have to call many different functions both on the main page and in the Worker, you can create a system which groups everything together.

+ +

First, we create a QueryableWorker class that takes the url of the worker, a default listener, and an error handler, and this class is gonna keep track of a list of listeners and help us communicate wirh the worker:

+ +
function QueryableWorker(url, defaultListener, onError){
+    var instance = this,
+        worker = new Worker(url),
+        listeners = {};
+
+    this.defaultListener = defaultListener || function(){};
+
+    if (onError) {worker.onerror = onError;}
+
+    this.postMessage = function(message){
+        worker.postMessage(message);
+    }
+
+    this.terminate = function(){
+        worker.terminate();
+    }
+}
+ +

Then we add the methods of adding/removing listeners:

+ +
this.addListeners = function(name, listener){
+    listeners[name] = listener;
+}
+
+this.removeListeners = function(name){
+    delete listeners[name];
+}
+ +

Here we let the worker handle two simple operations for illuatration: getting the difference of two numbers and making an alert after three seconds. In order to acheieve that we first implement a sendQuery method which queries if the worker actually has the corresponding methods to do what we want.

+ +
/*
+  This functions takes at least one argument, the method name we want to query.
+  Then we can pass in the arguments that the method needs.
+ */
+this.sendQuery = function(){
+    if (arguments.length < 1){
+         throw new TypeError("QueryableWorker.sendQuery takes at least one argument");
+         return;
+    }
+    worker.postMessage({
+        "queryMethod": arguments[0],
+        "queryArguments": Array.prototype.slice.call(arguments, 1)
+    });
+}
+ +

We finish QueryableWorker with the onmessage method. If the worker has the corresponding methods we queried, it should return the name of the corresponding listener and the arguments it needs, we just need to find it in listeners.:

+ +
worker.onmessage = function(event){
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty("queryMethodListener") &&
+        event.data.hasOwnProperty("queryMethodArguments")){
+        listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+    } else {
+        this.defaultListener.call(instance, event.data);
+    }
+}
+ +

Now onto the worker.  First we need to have the methods to handle the two simple operations:

+ +
var queryableFunctions = {
+    getDifference: function(a, b){
+        reply("printStuff", a - b);
+    },
+    waitSomeTime: function(){
+        setTimeout(function(){
+            reply("doAlert", 3, "seconds");
+        }, 3000);
+    }
+}
+
+function reply(){
+    if (arguments.length < 1) {
+        throw new TypeError("reply - takes at least one argument");
+        return;
+    }
+    postMessage({
+        queryMethodListener: arguments[0],
+        queryMethodArguments: Array.prototype.slice.call(arguments, 1)
+    });
+}
+
+/* This method is called when main page calls QueryWorker's postMessage method directly*/
+function defaultReply(message){
+    // do something
+}
+ +

And the onmessage method is now trivial:

+ +
onmessage = function(event){
+    if (event.data instanceof Object &&
+        event.data.hasOwnProperty("queryMethod") &&
+        event.data.hasOwnProperty("queryMethodArguments")){
+        queryableFunctions[event.data.queryMethod]
+            .apply(self, event.data.queryMethodArguments);
+    } else {
+        defaultReply(event.data);
+    }
+}
+ +

Here are the full implementation:

+ +

example.html (the main page):

+ +
<!doctype html>
+  <html>
+    <head>
+      <meta charset="UTF-8"  />
+      <title>MDN Example - Queryable worker</title>
+    <script type="text/javascript">
+    /*
+      QueryableWorker instances methods:
+        * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc): calls a Worker's queryable function
+        * postMessage(string or JSON Data): see Worker.prototype.postMessage()
+        * terminate(): terminates the Worker
+        * addListener(name, function): adds a listener
+        * removeListener(name): removes a listener
+      QueryableWorker instances properties:
+        * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
+     */
+    function QueryableWorker(url, defaultListener, onError){
+      var instance = this,
+      worker = new Worker(url),
+      listeners = {};
+
+      this.defaultListener = defaultListener || function(){};
+
+      if (onError) {worker.onerror = onError;}
+
+      this.postMessage = function(message){
+        worker.postMessage(message);
+      }
+
+      this.terminate = function(){
+        worker.terminate();
+      }
+
+      this.addListeners = function(name, listener){
+        listeners[name] = listener;
+      }
+
+      this.removeListeners = function(name){
+        delete listeners[name];
+      }
+
+      worker.onmessage = function(event){
+        if (event.data instanceof Object &&
+          event.data.hasOwnProperty("queryMethodListener") &&
+          event.data.hasOwnProperty("queryMethodArguments")){
+          listeners[event.data.queryMethodListener].apply(instance, event.data.queryMethodArguments);
+        } else {
+          this.defaultListener.call(instance, event.data);
+        }
+      }
+    }
+
+    // your custom "queryable" worker
+    var myTask = new QueryableWorker("my_task.js");
+
+    // your custom "listeners"
+    myTask.addListener("printStuff", function (result) {
+      document.getElementById("firstLink").parentNode.appendChild(document.createTextNode(" The difference is " + result + "!"));
+    });
+
+    myTask.addListener("doAlert", function (time, unit) {
+      alert("Worker waited for " + time + " " + unit + " :-)");
+    });
+</script>
+</head>
+<body>
+  <ul>
+    <li><a id="firstLink" href="javascript:myTask.sendQuery('getDifference', 5, 3);">What is the difference between 5 and 3?</a></li>
+    <li><a href="javascript:myTask.sendQuery('waitSomeTime');">Wait 3 seconds</a></li>
+    <li><a href="javascript:myTask.terminate();">terminate() the Worker</a></li>
+  </ul>
+</body>
+</html>
+ +

my_task.js (the worker):

+ +
var queryableFunctions = {
+  // example #1: get the difference between two numbers:
+  getDifference: function (nMinuend, nSubtrahend) {
+      reply("printSomething", nMinuend - nSubtrahend);
+  },
+  // example #2: wait three seconds
+  waitSomeTime: function () {
+      setTimeout(function() { reply("doAlert", 3, "seconds"); }, 3000);
+  }
+};
+
+// system functions
+
+function defaultReply (message) {
+  // your default PUBLIC function executed only when main page calls the queryableWorker.postMessage() method directly
+  // do something
+}
+
+function reply () {
+  if (arguments.length < 1) { throw new TypeError("reply - not enough arguments"); return; }
+  postMessage({ "queryMethodListener": arguments[0], "queryMethodArguments": Array.prototype.slice.call(arguments, 1) });
+}
+
+onmessage = function (oEvent) {
+  if (oEvent.data instanceof Object && oEvent.data.hasOwnProperty("queryMethod") && oEvent.data.hasOwnProperty("queryMethodArguments")) {
+    queryableFunctions[oEvent.data.queryMethod].apply(self, oEvent.data.queryMethodArguments);
+  } else {
+    defaultReply(oEvent.data);
+  }
+};
+ +

It is possible to switch the content of each mainpage -> worker and worker -> mainpage message. And the property names "queryMethod", "queryMethodListeners", "queryMethodArguments" can be anything as long as they are consistent in QueryableWorker and the worker.

+ +

Passing data by transferring ownership (transferable objects)

+ +

Google Chrome 17+ and Firefox 18+ contain an additional way to pass certain types of objects (transferable objects, that is objects implementing the {{domxref("Transferable")}} interface) to or from a worker with high performance. Transferable objects are transferred from one context to another with a zero-copy operation, which results in a vast performance improvement when sending large data sets. Think of it as pass-by-reference if you're from the C/C++ world. However, unlike pass-by-reference, the 'version' from the calling context is no longer available once transferred. Its ownership is transferred to the new context. For example, when transferring an {{domxref("ArrayBuffer")}} from your main app to a worker script, the original {{domxref("ArrayBuffer")}} is cleared and no longer usable. Its content is (quite literally) transferred to the worker context.

+ +
// Create a 32MB "file" and fill it.
+var uInt8Array = new Uint8Array(1024*1024*32); // 32MB
+for (var i = 0; i < uInt8Array.length; ++i) {
+  uInt8Array[i] = i;
+}
+
+worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
+ +
+

Note: For more information on transferable objects, performance, and feature-detection for this method, read Transferable Objects: Lightning Fast! on HTML5 Rocks.

+
+ +

Embedded workers

+ +

There is not an "official" way to embed the code of a worker within a web page, like {{HTMLElement("script")}} elements do for normal scripts. But a {{HTMLElement("script")}} element that does not have a src attribute and has a type attribute that does not identify an executable MIME type can be considered a data block element that JavaScript could use. "Data blocks" is a more general feature of HTML5 that can carry almost any textual data. So, a worker could be embedded in this way:

+ +
<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8" />
+<title>MDN Example - Embedded worker</title>
+<script type="text/js-worker">
+  // This script WON'T be parsed by JS engines because its MIME type is text/js-worker.
+  var myVar = "Hello World!";
+  // Rest of your worker code goes here.
+</script>
+<script type="text/javascript">
+  // This script WILL be parsed by JS engines because its MIME type is text/javascript.
+  function pageLog (sMsg) {
+    // Use a fragment: browser will only render/reflow once.
+    var oFragm = document.createDocumentFragment();
+    oFragm.appendChild(document.createTextNode(sMsg));
+    oFragm.appendChild(document.createElement("br"));
+    document.querySelector("#logDisplay").appendChild(oFragm);
+  }
+</script>
+<script type="text/js-worker">
+  // This script WON'T be parsed by JS engines because its MIME type is text/js-worker.
+  onmessage = function (oEvent) {
+    postMessage(myVar);
+  };
+  // Rest of your worker code goes here.
+</script>
+<script type="text/javascript">
+  // This script WILL be parsed by JS engines because its MIME type is text/javascript.
+
+  // In the past...:
+  // blob builder existed
+  // ...but now we use Blob...:
+  var blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) { return oScript.textContent; }),{type: "text/javascript"});
+
+  // Creating a new document.worker property containing all our "text/js-worker" scripts.
+  document.worker = new Worker(window.URL.createObjectURL(blob));
+
+  document.worker.onmessage = function (oEvent) {
+    pageLog("Received: " + oEvent.data);
+  };
+
+  // Start the worker.
+  window.onload = function() { document.worker.postMessage(""); };
+</script>
+</head>
+<body><div id="logDisplay"></div></body>
+</html>
+ +

The embedded worker is now nested into a new custom document.worker property.

+ +

It is also worth noting that you can also convert a function into a Blob, then generate an object URL from that blob. For example:

+ +
function fn2workerURL(fn) {
+  var blob = new Blob(['('+fn.toString()+')()'], {type: 'application/javascript'})
+  return URL.createObjectURL(blob)
+}
+ +

Further examples

+ +

This section provides further examples of how to use web workers.

+ +

Performing computations in the background

+ +

Workers are mainly useful for allowing your code to perform processor-intensive calculations without blocking the user interface thread. In this example, a worker is used to calculate Fibonacci numbers.

+ +

The JavaScript code

+ +

The following JavaScript code is stored in the "fibonacci.js" file referenced by the HTML in the next section.

+ +
var results = [];
+
+function resultReceiver(event) {
+  results.push(parseInt(event.data));
+  if (results.length == 2) {
+    postMessage(results[0] + results[1]);
+  }
+}
+
+function errorReceiver(event) {
+  throw event.data;
+}
+
+onmessage = function(event) {
+  var n = parseInt(event.data);
+
+  if (n == 0 || n == 1) {
+    postMessage(n);
+    return;
+  }
+
+  for (var i = 1; i <= 2; i++) {
+    var worker = new Worker("fibonacci.js");
+    worker.onmessage = resultReceiver;
+    worker.onerror = errorReceiver;
+    worker.postMessage(n - i);
+  }
+ };
+ +

The worker sets the property onmessage to a function which will receive messages sent when the worker object's postMessage() is called (note that this differs from defining a global variable of that name, or defining a function with that name. var onmessage and function onmessage will define global properties with those names, but they will not register the function to receive messages sent by the web page that created the worker). This starts the recursion, spawning new copies of itself to handle each iteration of the calculation.

+ +

The HTML code

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="UTF-8"  />
+    <title>Test threads fibonacci</title>
+  </head>
+  <body>
+
+  <div id="result"></div>
+
+  <script language="javascript">
+
+    var worker = new Worker("fibonacci.js");
+
+    worker.onmessage = function(event) {
+      document.getElementById("result").textContent = event.data;
+      dump("Got: " + event.data + "\n");
+    };
+
+    worker.onerror = function(error) {
+      dump("Worker error: " + error.message + "\n");
+      throw error;
+    };
+
+    worker.postMessage("5");
+
+  </script>
+  </body>
+</html>
+ +

The web page creates a div element with the ID result , which gets used to display the result, then spawns the worker. After spawning the worker, the onmessage handler is configured to display the results by setting the contents of the div element, and the onerror handler is set to dump the error message.

+ +

Finally, a message is sent to the worker to start it.

+ +

Try this example.

+ +

Performing web I/O in the background

+ +

You can find an example of this in the article Using workers in extensions .

+ +

Dividing tasks among multiple workers

+ +

As multi-core computers become increasingly common, it's often useful to divide computationally complex tasks among multiple workers, which may then perform those tasks on multiple-processor cores.

+ +

Other types of worker

+ +

In addition to dedicated and shared web workers, there are other types of worker available:

+ + + +

Functions and interfaces available in workers

+ +

You can use most standard JavaScript features inside a web worker, including:

+ + + +

The main thing you can't do in a Worker is directly affect the parent page. This includes manipulating the DOM and using that page's objects. You have to do it indirectly, by sending a message back to the main script via {{domxref("DedicatedWorkerGlobalScope.postMessage")}}, then actioning the changes from there.

+ +
+

Note: For a complete list of functions available to workers, see Functions and interfaces available to workers.

+
+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#toc-workers')}}{{Spec2('HTML WHATWG')}}No change from {{SpecName("Web Workers")}}.
{{SpecName('Web Workers')}}{{Spec2('Web Workers')}}Initial definition.
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari (WebKit)
Basic support4[1]{{CompatGeckoDesktop("1.9.1")}}10.010.6[1]4[2]
Shared workers4[1]{{CompatGeckoDesktop(29)}}{{CompatNo}}10.65
+ {{CompatNo}} 6.1[4]
Passing data using structured cloning13{{CompatGeckoDesktop(8)}}10.011.56
Passing data using transferable objects17 {{property_prefix("webkit")}}
+ 21
{{CompatGeckoDesktop(18)}}{{CompatNo}}156
Global {{domxref("window.URL", "URL")}}10[3]
+ 23
{{CompatGeckoDesktop(21)}}11156[3]
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)Firefox OS (Gecko)IE PhoneOpera MobileSafari Mobile
Basic support4.44[1]3.51.0.110.011.5[1]5.1[2]
Shared workers{{CompatNo}}4[1]81.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using structured cloning{{CompatNo}}481.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
Passing data using transferable objects{{CompatNo}}{{CompatNo}}181.0.1{{CompatNo}}{{CompatNo}}{{CompatNo}}
+ +

[1] Chrome and Opera give an error "Uncaught SecurityError: Failed to construct 'Worker': Script at 'file:///Path/to/worker.js' cannot be accessed from origin 'null'." when you try to run a worker locally. It needs to be on a proper domain.

+ +

[2] As of Safari 7.1.2, you can call console.log from inside a worker, but it won't print anything to the console. Older versions of Safari don't allow you to call console.log from inside a worker.

+ +

[3] This feature is implemented prefixed as webkitURL.

+ +

[4] Safari removed SharedWorker support.

+ +

See also

+ + diff --git a/files/ko/web/api/webgl_api/cross-domain_textures/index.html b/files/ko/web/api/webgl_api/cross-domain_textures/index.html deleted file mode 100644 index 94e969e37a..0000000000 --- a/files/ko/web/api/webgl_api/cross-domain_textures/index.html +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: 크로스-도메인 텍스쳐 -slug: Web/API/WebGL_API/Cross-Domain_Textures -tags: - - WebGL - - 웹지엘 - - 크로스 도메인 - - 텍스쳐 -translation_of: Web/API/WebGL_API/Tutorial/Using_textures_in_WebGL#Cross-domain_textures -translation_of_original: Web/API/WebGL_API/Cross-Domain_Textures ---- -

WebGL 텍스쳐 로딩은 크로스-도메인 접근 규칙에 따라 제약을 받습니다. 여러분이 만든 컨텐츠에서 다른 도메인의 텍스쳐, 즉, 크로스-도메인 텍스쳐를 로딩하려면 CORS 승인이 필요합니다. CORS에 대한 자세한 내용은 HTTP access control을 참고하시기 바랍니다.

- -

CORS 승인된 이미지를 WebGL 텍스쳐에 사용하는 방법에 대한 설명은 hacks.mozilla.org 문서예제를 참고하시기 바랍니다.

- -
-

역자 주 : 예제 링크가 깨져있는데, 원문에도 깨진 링크가 포함되어 있습니다.

-
- -
-

Note: WebGL 텍스쳐에 대한 CORS 지원과 이미지 요소의 crossOrigin 속성이 {{Gecko("8.0")}}에 구현되어 있습니다.

-
- -

내용이 변경되어 오염된(tainted) 쓰기 전용의 2D 캔버스는 WebGL 텍스쳐로 사용될 수 없습니다. 예를 들어 크로스-도메인 이미지가 그려진 2D {{ HTMLElement("canvas") }}는 오염된 2D 캔버스라고 할 수 있습니다.

- -
-

Note: 캔버스 2D의 drawImage에 대한 CORS 지원은 {{Gecko("9.0")}}에 구현되어 있습니다. 따라서 {{Gecko("9.0")}}에서부터는, CORS 승인된 크로스-도메인 이미지는 2D 캔버스를 오염시키지 않으며, CORS 승인된 크로스-도메인 이미지가 그려진 2D 캔버스도 WebGL 텍스쳐로 사용할 수 있습니다.

-
- -
-

Note: 크로스-도메인 비디오에 대한 CORS 지원과 {{ HTMLElement("video") }}요소의 crossorigin 속성은 {{Gecko("12.0")}}에 구현되어 있습니다.

-
- -

{{ languages( { "ja": "ja/WebGL/Cross-Domain_Textures", "ko": "ko/Web/WebGL/Cross-Domain_Textures"} ) }}

diff --git a/files/ko/web/api/websockets_api/index.html b/files/ko/web/api/websockets_api/index.html new file mode 100644 index 0000000000..8b6fd20b1a --- /dev/null +++ b/files/ko/web/api/websockets_api/index.html @@ -0,0 +1,172 @@ +--- +title: 웹 소켓 +slug: WebSockets +translation_of: Web/API/WebSockets_API +--- +

웹 소켓은 사용자의 브라우저와 서버 사이의 인터액티브 통신 세션을 설정할 수 있게 하는 고급 기술입니다. 개발자는 웹 소켓 API를 통해 서버로 메시지를 보내고 서버의 응답을 위해 서버를 폴링하지 않고도 이벤트 중심 응답을 받는 것이 가능합니다.

+ +
+

인터페이스

+ +
+
WebSocket
+
웹 소켓 서버로 연결하고 연결을 통해 데이터를 보내고 받는 기본 인터페이스
+
CloseEvent
+
연결이 종료 되었을 때 웹 소켓 객체에 의해 전달된 이벤트
+
MessageEvent
+
서버로 부터 메시지가 수신 되었을 때 웹 소켓 객체에 의해 전달된 이벤트
+
+
+ +
+

도구

+ + + + + + +
+ +

같이 보기

+ + + +

브라우저 호환성

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
기능ChromeFirefox (Gecko)Internet ExplorerOperaSafari
버전 76 지원 {{obsolete_inline}}6{{CompatGeckoDesktop("2.0")}}{{CompatNo}}11.00 (disabled)5.0.1
버전 7 지원 {{obsolete_inline}}{{CompatNo}}{{CompatGeckoDesktop("6.0")}}
+ {{property_prefix("Moz")}}
{{CompatNo}}{{CompatNo}}{{CompatNo}}
버전 10 지원 {{obsolete_inline}}14{{CompatGeckoDesktop("7.0")}}
+ {{property_prefix("Moz")}}
HTML5 Labs{{CompatUnknown}}{{CompatUnknown}}
표준 - RFC 6455 지원16{{CompatGeckoDesktop("11.0")}}1012.106.0
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
기능AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
버전 76 지원 {{obsolete_inline}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
버전 7 지원 {{obsolete_inline}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
버전 8 지원 (IETF draft 10) {{obsolete_inline}}{{CompatUnknown}}{{CompatGeckoMobile("7.0")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
표준 - RFC 6455 지원16 (Chrome){{CompatGeckoDesktop("11.0")}}{{CompatUnknown}}12.106.0
+
+ +

Gecko

+ +

파이어폭스는 발전하는 웹 소켓 규격을 지속적으로 지원하고 있습니다. 파이어폭스 6은 웹 소켓 프로토콜 버전 7을, 파이어폭스 7은 버전 8을 지원합니다. (IETF 초안 10) 파이어폭스 모바일은 7.0부터 웹 소켓을 지원합니다.

+ +

Gecko 6.0

+ +

Gecko 6.0 {{geckoRelease("6.0")}} 이전엔 WebSocket 객체가 존재하였으며, 일부 사이트가 WebSocket 서비스는 접두어가 붙지 않는 것이라고 생각하기도 했습니다. 이 객체는 MozWebSocket으로 개명되었습니다.

+ +

Gecko 7.0

+ +

Gecko 7.0 {{geckoRelease("7.0")}} 이후로 고급 환경 설정의 network.websocket.max-connections 항목을 통해 동시에 열릴 수 있는 웹 소켓 연결의 최대값을 지정할 수 있습니다. 기본값은 200입니다.

+ +

Gecko 8.0

+ +

Gecko 8.0 {{geckoRelease("8.0")}} 이후로 웹 소켓 규격 초안의 변경에 따라 웹 소켓의 deflate 스트림 확장이 비활성화 되었습니다. 이는 일부 사이트의 호환성 문제를 해결합니다.

+ +

Gecko 11.0

+ +

Gecko 11.0 이전에는 모든 메시지가 16 MB를 넘을 수 없었으나, 지금은 최대 2 GB까지 가능합니다. 그러나 (특히 모바일에서) 권장되는 방법은 아닙니다. 충분한 메모리를 가지지 못한 장치에서는 통신이 실패하게 될 것입니다.

+ +

추가적으로 바이너리 데이터를 위한 ArrayBuffer 지원이 구현되었습니다.

+ +

Gecko 11.0부터 웹 소켓 API는 더이상 접두사가 붙지 않습니다.

+ +
주의: 파이어폭스 4, 5에서 웹 소켓이 비활성화 돼있었던 가장 주요한 이유는 프로토콜 설계의 보안성 문제 때문이었습니다. 이는 파이어폭스 6에서 상위 버전의 프로토콜을 구현함으로써 해결되었습니다.
+ +
{{HTML5ArticleTOC}}
diff --git a/files/ko/web/api/websockets_api/writing_websocket_client_applications/index.html b/files/ko/web/api/websockets_api/writing_websocket_client_applications/index.html new file mode 100644 index 0000000000..e7826d8595 --- /dev/null +++ b/files/ko/web/api/websockets_api/writing_websocket_client_applications/index.html @@ -0,0 +1,191 @@ +--- +title: WebSocket을 이용하여 클라이언트 애플리케이션 작성하기 +slug: WebSockets/Writing_WebSocket_client_applications +tags: + - 가이드 + - 네트워킹 + - 예제 + - 웹소켓 + - 웹소켓API + - 클라이언트 +translation_of: Web/API/WebSockets_API/Writing_WebSocket_client_applications +--- +

WebSocket은 ws 프로토콜을 기반으로 클라이언트와 서버 사이에 지속적인 완전 양방향 연결 스트림을 만들어 주는 기술입니다. 일반적인 웹소켓 클라이언트는 사용자의 브라우저일 것이지만, 그렇다고 해서 이 프로토콜이 플랫폼에 종속적이지는 않습니다.

+ +
Note: 우리에게는 작동하는 chat/server 시스템 예제 코드 조각이 있습니다. 이는 우리의 인프라가 WebSocket 예제들을 제대로 호스팅할 수 있는 환경이 되면 공유할 것입니다.
+ +

{{AvailableInWorkers}}

+ +

WebSocket 객체 생성하기

+ +

WebSocket 프로토콜을 사용하여 통신하기 위해서는 WebSocket객체를 생성해야 합니다. 이 객체는 자동으로 서버로의 연결을 열려고 할 것입니다.

+ +

WebSocket 생성자는 하나의 필수 파라미터와 하나의 선택 파라미터를 받습니다.

+ +
WebSocket WebSocket(
+  in DOMString url,
+  in optional DOMString protocols
+);
+
+ +
+
url
+
연결할 URL으로, 이것은 WebSocket 서버가 응답할 URL이어야 합니다.
+
protocols {{ optional_inline() }}
+
하나의 프로토콜 문자열, 또는 프로토콜 문자열의 배열입니다. 이 문자열들은 서브 프로토콜을 지정하는데 사용되어, 하나의 서버가 여러 개의 WebSocket 서브 프로토콜을 구현할 수 있도록 해줍니다. 예를 들어, 하나의 서버가 처리하는 상호작용이 지정된 protocols에 따라 달라지도록 할 수 있습니다. 만약 프로토콜 문자열을 지정하지 않으면 빈 문자열을 넣은 것으로 간주됩니다.
+
+ +

생성자는 예외를 발생시킬 수 있습니다:

+ +
+
SECURITY_ERR
+
접속을 시도하고 있는 포트가 차단되었습니다.
+
+ +
+
+ +

연결 에러

+ +

만약 연결 시도 중 에러가 발생하면, 먼저 "error"란 이름의 이벤트가 WebSocket 오브젝트로 전달되고, 그로 인해 onerror 핸들러가 실행됩니다. 그 후에 연결이 종료되는 이유를 가리키는 CloseEvent 이벤트가 WebSocket 오브젝트로 전달되고, 그로 인해 onclose 핸들러가 실행됩니다.

+ +

Firefox 11부터는 보통 에러 메세지에 대한 설명이 Mozillia 플랫폼의 콘솔에 표시되며, CloseEvent로부터는 RFC 6455, Section 7.4에 정의되어 있는 연결 종료 코드를 받게 됩니다.

+ +

예제

+ +

이 간단한 예제는 새 웹소켓 오브젝트를 생성하여 ws://www.example.com/socketserver 서버에 접속하는것을 보여줍니다. 이 예제에서는 커스텀 프로토콜인 "protocolOne" 을 리퀘스트에 같이 지정합니다. (이 프로토콜을 지정하는 부분은 생략될 수 있습니다.)

+ +
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");
+
+ +

반환된 exampleSocket 오브젝트의 exampleSocket.readyState 값은 CONNECTING 입니다. readyState 값은 연결이 수립되어 데이터가 전송 가능한 상태가 되면 OPEN 으로 변경됩니다.

+ +

만약 여러개의 프로토콜을 유연하게 대응할 수 있는 구조를 가지고 있다면, 연결 시에 배열을 통해 프로토콜의 목록을 지정할 수 있습니다.

+ +
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", ["protocolOne", "protocolTwo"]);
+
+ +

연결이 수립되면(readyState 가 OPEN 이 되었을 때), exampleSocket.protocol 값을 조사하여 서버가 어떤 프로토콜을 선택했는지 알아낼 수 있습니다.

+ +

위의 예제에서 ws 는 http 를 대체합니다. 비슷하게 wss 는 https 를 대체합니다. 웹소켓 연결은 HTTP 업그레이드 메카니즘에 의해 수행되기 때문에 HTTP 서버 주소 지정에 대한 프로토콜 업그레이드 요청은 암시적입니다.  (ws://www.example.com 또는 wss://www.example.com. 같이)

+ +

서버에 데이터 전송하기

+ +

한번 연결이 수립되면 이제부터는 서버로 데이터를 전송할 수 있습니다. 이것을 하기 위해서는 단순히 WebSocket 오브젝트의 send() 호출하여 보내고 싶은 메세지를 지정하기만 하면 됩니다.:

+ +
exampleSocket.send("Here's some text that the server is urgently awaiting!");
+
+ +

보낼 수 있는 데이터는 String , {{ domxref("Blob") }},  또는 ArrayBuffer 입니다.

+ +
Note: 버전 11 아래의 파이어폭스는 String 데이터 전송만을 지원합니다.
+ +

연결을 맺는것은 비동기 작업이고 실패하기 쉬운 작업이기 때문에, WebSocket 오브젝트를 생성하자마자  send() 로 데이터 전송을 시도하는것은 성공하지 않을 가능성이 있습니다. 우리는 연결이 수립된 이후에만 데이터를 전송하도록 하기 위해 onopen 핸들러를 정의하고, 이 위에서 작업합니다.

+ +
exampleSocket.onopen = function (event) {
+  exampleSocket.send("Here's some text that the server is urgently awaiting!");
+};
+
+ +

데이터 전송에 JSON 사용하기

+ +

JSON 을 사용하면 서버에 복잡한 데이터를 편리하게 보낼 수 있습니다. 예를 들어, 채팅 프로그램이 서버와 JSON으로 캡슐화된 패킷 데이터를 주고받는 프로토콜을 구현한것을 상상해 볼 수 있습니다.:

+ +
// Send text to all users through the server
+function sendText() {
+  // Construct a msg object containing the data the server needs to process the message from the chat client.
+  var msg = {
+    type: "message",
+    text: document.getElementById("text").value,
+    id:   clientID,
+    date: Date.now()
+  };
+
+  // Send the msg object as a JSON-formatted string.
+  exampleSocket.send(JSON.stringify(msg));
+
+  // Blank the text input element, ready to receive the next line of text from the user.
+  document.getElementById("text").value = "";
+}
+
+ +

서버로부터 데이터 수신하기

+ +

WebSockets는 event-driven API 입니다; 메세지가 수신되면 "message" 이벤트가 onmessage 함수로 전달되게 됩니다. 아래와 같은 코드를 작성하여 수신되는 데이터를 받아볼 수 있습니다.:

+ +
exampleSocket.onmessage = function (event) {
+  console.log(event.data);
+}
+
+ +

JSON 오브젝트를 받아서 처리하기

+ +

상단의 {{ anch("데이터 전송에 JSON 사용하기") }} 에서 작업한 코드와 연관되는 클라이언트를 생각해 봅시다. 클라이언트에서 받을 수 있는 패킷들의 목록은 다음과 같을 것 입니다.:

+ + + +

위의 메세지들을 받아서 처리하는 코드는 아래와 같을 것 입니다.:

+ +
exampleSocket.onmessage = function(event) {
+  var f = document.getElementById("chatbox").contentDocument;
+  var text = "";
+  var msg = JSON.parse(event.data);
+  var time = new Date(msg.date);
+  var timeStr = time.toLocaleTimeString();
+
+  switch(msg.type) {
+    case "id":
+      clientID = msg.id;
+      setUsername();
+      break;
+    case "username":
+      text = "<b>User <em>" + msg.name + "</em> signed in at " + timeStr + "</b><br>";
+      break;
+    case "message":
+      text = "(" + timeStr + ") <b>" + msg.name + "</b>: " + msg.text + "<br>";
+      break;
+    case "rejectusername":
+      text = "<b>Your username has been set to <em>" + msg.name + "</em> because the name you chose is in use.</b><br>"
+      break;
+    case "userlist":
+      var ul = "";
+      for (i=0; i < msg.users.length; i++) {
+        ul += msg.users[i] + "<br>";
+      }
+      document.getElementById("userlistbox").innerHTML = ul;
+      break;
+  }
+
+  if (text.length) {
+    f.write(text);
+    document.getElementById("chatbox").contentWindow.scrollByPages(1);
+  }
+};
+
+ +

여기서 우리는 JSON.parse() 를 통해 JSON 오브젝트를 자바스크립트 오브젝트로 변환합니다. 그 다음 콘텐츠에 따라 분기하고 처리하는 로직을 가집니다.

+ +

Text data format

+ +

웹소켓을 통해 전달되는 텍스트들은 UTF-8 포멧을 가집니다.

+ +

Gecko 9.0 {{ geckoRelease("9.0") }} 먼저 버전들은 유효한 UTF-8 텍스트가 아닌 문자가 들어올 경우 연결이 종료되었습니다. 지금은 이 값들을 정상적으로 허용합니다.

+ +

연결을 종료하기

+ +

웹 소켓 사용을 마쳤다면 close() 메소드를 호출해 연결을 종료합니다.:

+ +
exampleSocket.close();
+
+ +

연결을 닫아버리기 전에 bufferedAmount 어트리뷰트를 조사하여 아직 네트워크에 전달되지 않은 데이터가 있는지 검사하는것도 좋은 방법입니다.

+ +

보안에 대한 고려 사항

+ +

웹소켓은 혼합된 연결 환경에서 이용되어서는안됩니다. 예를들어 HTTPS를 이용해 로드된 페이지에서 non-secure 웹소켓 연결을 수립하는것(또는 반대) 처럼 말입니다. 몇몇 브라우저들은 이를 강제로 금지하고 있습니다. 파이어폭스 버전 8이상도 이를 금지합니다.

+ +

{{ languages ( {"zh-tw": "zh_tw/WebSockets/Writing_WebSocket_client_applications"} ) }}

diff --git a/files/ko/web/api/websockets_api/writing_websocket_servers/index.html b/files/ko/web/api/websockets_api/writing_websocket_servers/index.html new file mode 100644 index 0000000000..24c3cbe6c0 --- /dev/null +++ b/files/ko/web/api/websockets_api/writing_websocket_servers/index.html @@ -0,0 +1,258 @@ +--- +title: 웹소켓 서버 작성하기 +slug: WebSockets/Writing_WebSocket_servers +translation_of: Web/API/WebSockets_API/Writing_WebSocket_servers +--- +

{{gecko_minversion_header("2")}}

+ +

개요

+ +

웹 소켓 서버는 특정한 프로토콜을 따르는 서버의 임의 포트를 리스닝하고 있는 TCP 어플리케이션입니다. 사용자 서버를 만드는 작업은 두려운 일일수도 있습니다. 하지만, 당신이 선택한 플랫폼상에서 간단한 웹 소켓 서버를 구현하는것은 쉬울것입니다.  

+ +

웹 소켓 서버는 C(++), Python, PHP, server-side JavaScript등과 같은 Berkeley sockets을 지원하는 어떠한 server-side 프로그래밍 언어로도 개발될 수 있습니다. 이것은 어느 특정한 언어의 자습서는 아니지만, 당신 자신의 서버를 개발하는것을 용이하게 하는 지침으로써의 역할을 합니다.

+ +

당신은 HTTP가 작동하는 방식과 중간정도의 개발 경험이 있어야만 합니다. 개발언어에서 제공하는 TCP 소켓에 대한 지식이 요구될 수도 있습니다. 이 지침의 범위는 당신이 웹 소켓서버를 개발하기위해 필요한 최소한의 지식에 대해 소개하는것입니다.

+ +
+

최신의 공식 웹 소켓 문서인 RFC 6455를 읽으세요. 1과 4-7 섹션이 특별히 서버개발자에게 흥미로운 부분입니다. 10 섹션에서는 보안에 대해 논의하며, 당신의 서버를 공개하기전 해당 부분을 반드시 정독하여 읽어보셔야만합니다.

+
+ +

이 페이지에서 웹 소켓 서버는 매우 약간만 설명되어 있습니다. 웹 소켓 서버는 종종 다른 특정한 이유로 인해 분리되거나 전문화됩니다. 따라서 웹 소켓과의 핸드 쉐이크를 감지하거나 미리 처리하거나 또는 클라이언트들을 실제 웹 소켓 서버에 보내기위해 일반적으로 HTTP 서버와 같은 reverse proxy를 사용합니다. 이는 쿠키나 인증을 처리하기 위해 당신의 서버 코드를 잔뜩 작성하지 않아도 된다는 것을 의미합니다.

+ +

Step 1: The WebSocket Handshake

+ +

먼저 서버는 표준 TCP 소켓을 사용하여 연결하려는 소켓을 위해 반드시 듣고 있어야 합니다. 당신의 플랫폼에 따라 서버는 이미 준비가 되어있을수도 있습니다. 예를들어, 당신의 서버가 example.com에 port가 8000인 채로 듣고 있다고 가정해봅시다. 

+ +
+

경고: 서버에서 아무 포트나 선택하여 연결할 수 있지만, 80 또는 443 포트가 아닌 다른 연결은 방화벽/프록시에 의해 문제를 일으킬 수 있습니다. TLS/SSL 보안 연결인 443 포트와의 연결이 가장 쉬울 것입니다. 현재 대부분의 브라우저(특히 Firefox 8+)는 안전한 페이지라 할지라도 보안 연결이 아닌 웹소켓 연결은 허용되지 않습니다.

+
+ +

웹소켓의 핸드셰이크 과정은 HTTP를 바탕으로 이루어집니다. 자세한 연결 과정은 다루지 않으나, 각 요청자는 연결 과정이 제대로 이루어질때까지 요청을 보류합니다. 서버는 클라이언트가 요청하는 모든 것을 주의깊게 이해해야 하고, 그렇지 않을 경우 보안 이슈가 일어날 수 있습니다.

+ +

클라이언트 핸드쉐이크 요청

+ +

당신이 웹 소켓 서버를 개발 중이라도, 클라이언트는 여전히 웹 소켓 핸드쉐이킹 과정을 시작합니다. 따라서, 당신은 클라이언트의 요청을 이해하기 위한 방법을 이해해야합니다. 클라이언트는 아래와 같아 보이는 매우 표준적인 HTTP 요청을 보낼것입니다.(HTTP 버전은 반드시 1.1. 혹은 그 이상이어하며, 반드시 GET방식이어야합니다.)

+ +
GET /chat HTTP/1.1
+Host: example.com:8000
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
+Sec-WebSocket-Version: 13
+
+
+ +

이외에도 클라이언트는 여러 메세지나 서브프로토콜을 추가해 보낼 수도 있습니다. User-Agent, RefererCookie와 같은 공통 헤더나, 인증 헤더도 말이죠. 자세한 사항은 다음을 참조하세요. 원하는 대로 요청에 무엇이든지 첨부하여 보낼 수 있으며 웹소켓과 관련이 없을 경우 무시합니다. 통상적으로, 리버스 프록시가 이미 그런 기능을 담당하고 있을 겁니다.

+ +

잘못된 값을 가지거나 형식이 잘못된 헤더의 경우, 서버는 "400 Bad Request" 응답을 보내 즉시 소켓을 종료시켜야 합니다. HTTP 응답 바디에 핸드셰이크에 실패한 이유가 명시되어 있지만, 브라우저 상에서 명시적으로 나타내진 않습니다. 서버가 웹소켓의 버전 인식을 실패할 경우, 인식 가능한 버전을 명시해 Sec-WebSocket-Version 요청을 보내야 합니다. (최신 가이드 v13에서 설명되어 있습니다) 이제, 가장 흥미로운 헤더인 Sec-WebSocket-Key을 살펴봅니다.

+ +
+

팁: 모든 브라우저는 Origin header를 보냅니다. 이 헤더는 보안을 위해 활용되며, (checking for same origin, whitelisting/ blacklisting, etc.) 활용하고 싶지 않다면 403 Forbidden을 보냅니다. 하지만 non-browser 에이전트가 위조된 Origin을 보낼수도 있다는 것을 명심해야 합니다. 따라서 대부분의 애플리케이션은 이 헤더가 없는 요청을 거부합니다.

+
+ +
+

Tip: The request-uri (/chat here) has no defined meaning in the spec. So many people cleverly use it to let one server handle multiple WebSocket applications. For example, example.com/chat could invoke a multiuser chat app, while /game on the same server might invoke a multiplayer game.

+
+ +
+

Note: Regular HTTP status codes can only be used before the handshake. After the handshake succeeds, you have to use a different set of codes (defined in section 7.4 of the spec).

+
+ +

서버가 보내는 핸드쉐이크 응답

+ +

위와 같은 요청을 받으면 서버 역시도 HTTP 구조의 응답을 보내주어야 합니다. 자세한 내용은 아래와 같습니다.(각각의 헤더 끝에는 \r\n을 그리고 가장 마지막에는 한번 더 \r\n을 넣는걸 잊지 마세요.)

+ +
HTTP/1.1 101 Switching Protocols
+Upgrade: websocket
+Connection: Upgrade
+Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
+
+
+ +

Additionally, the server can decide on extension/subprotocol requests here; see Miscellaneous for details. The Sec-WebSocket-Accept part is interesting. The server must derive it from the Sec-WebSocket-Key that the client sent. To get it, concatenate the client's Sec-WebSocket-Key and "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" together (it's a "magic string"), take the SHA-1 hash of the result, and return the base64 encoding of the hash.

+ +
+

FYI: This seemingly overcomplicated process exists so that it's obvious to the client whether or not the server supports WebSockets. This is important because security issues might arise if the server accepts a WebSockets connection but interprets the data as a HTTP request.

+
+ +

So if the Key was "dGhlIHNhbXBsZSBub25jZQ==", the Accept will be "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=". Once the server sends these headers, the handshake is complete and you can start swapping data!

+ +
+

The server can send other headers like Set-Cookie, or ask for authentication or redirects via other status codes, before sending the reply handshake.

+
+ +

클라이언트 추적

+ +

웹소켓 프로토콜과 직접적인 연관은 없지만, 이 항목에서 언급할만한 의미가 있습니다. 웹소켓 서버는 이미 연결된 클라이언트들의 반복적인 연결(hand shaking)을 막기위해 클라이언트의 소켓 상태를 추적해야합니다. 같은 IP 주소를 가지는 클라이언트는 여러번 연결을 시도 할 수 있습니다.(하지만, 서버는 Denial-of-Service attacks 을 위해 너무 많은 연결 요청을 거부할 수 있습니다).

+ +

Step 2: 데이터 프레임 교환

+ +

Either the client or the server can choose to send a message at any time — that's the magic of WebSockets. However, extracting information from these so-called "frames" of data is a not-so-magical experience. Although all frames follow the same specific format, data going from the client to the server is masked using XOR encryption (with a 32-bit key). Section 5 of the specification describes this in detail.

+ +

데이터 프레임 포멧

+ +

모든 데이터 프레임 (서버->클라이언트 / 클라이언트 -> 서버) 은 아래의 구조를 따릅니다:

+ +
 0               1               2               3
+ 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
++-+-+-+-+-------+-+-------------+-------------------------------+
+|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
+|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
+|N|V|V|V|       |S|             |   (if payload len==126/127)   |
+| |1|2|3|       |K|             |                               |
++-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
+ 4               5               6               7
++ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+|     Extended payload length continued, if payload len == 127  |
++ - - - - - - - - - - - - - - - +-------------------------------+
+ 8               9               10              11
++ - - - - - - - - - - - - - - - +-------------------------------+
+|                               |Masking-key, if MASK set to 1  |
++-------------------------------+-------------------------------+
+ 12              13              14              15
++-------------------------------+-------------------------------+
+| Masking-key (continued)       |          Payload Data         |
++-------------------------------- - - - - - - - - - - - - - - - +
+:                     Payload Data continued ...                :
++ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+|                     Payload Data continued ...                |
++---------------------------------------------------------------+
+ +

RSV1-3 는 사용되지 않습니다. 이 필드들은 확장 프로토콜 또는 미래를 위해 예약되었습니다.

+ +

MASK 비트는 메세지가 인코딩되어있는지의 여부를 나타냅니다.클라이언트가 서버로 보내는 메세지는 항상 마스킹되어야합니다. 따라서 서버는 클라이언트로부터 받은 이 필드가 항상 1임을 기대할 수 있습니다. (만약 클라이언트가 마스킹되지 않은 메세지를 보낸다면 서버는 연결을 종료해야 합니다. 참고 : section 5.1 of the spec ).
+ 서버가 클라이언트에게 보내는 메세지는 MASK 필드가 항상 0이고 데이터는 마스킹되지 않은 상태여야 합니다. 마스킹이 어떻게 이루어지는지 / 마스킹된 메세지를 어떻게 디코딩하는지는 나중에 설명합니다.
+ (주의: wss 연결이라고 하더라도 클라이언트가 보내는 패킷은 항상 마스킹되어야 합니다.)

+ +

opcode 필드는 뒤따라오는 payload 데이터가 어떠한 포멧인지를 나타냅니다. 0x0은 continuation, 0x1은 텍스트(항상 UTF-8), 0x2는 바이너리 데이터 / 나머지 값은 "컨트롤 코드"에 사용됩니다. (컨트롤 코드에 대해서는 나중에 다루게 됩니다.) 현재 버전의 웹소켓 프로토콜에서는 0x3 / 0x7 / 0xB~0xF는 아무런 의미도 지니고있지 않습니다.

+ +

FIN 비트는 이 메세지가 마지막임을 나타냅니다. 만약 FIN 비트가 0이라면 서버는 뒤에 더 따라오게 될 메세지들까지 수신해야 합니다. FIN 비트가 1일 경우에는 전체 메세지가 수신되었으므로 이를 처리합니다. 이 부분에 대해서는 뒤에 다시 설명합니다.

+ +

Payload 길이 알아내기

+ +

수신한 프레임으로부터 payload 데이터를 읽기 위해서는 payload length 필드를 읽어야 합니다. 불행히도 이는 약간 복잡한 작업을 거치는데 아래 순서대로 처리해 주세요.

+ +
    +
  1. 9번째부터 15번재까지의 비트를 읽습니다. 이를 unsigned integer로 취급한 다음 값이 125거나 이보다 작을 경우 이 자체가 payload length 입니다. 이 경우에는 2, 3 과정은 필요 없습니다. 하지만 126이면 2번으로, 127일 경우 3번으로 가주세요
  2. +
  3. 다음 16비트를 읽습니다. 이를 unsigned integer로 처리하고 payload length 값으로 사용합니다.
  4. +
  5. 다음 64비트를 읽습니다. 이를 unsigned integer로 처리하고 payload length 값으로 사용합니다. (최상위 비트는 항상 0이어야 합니다.)
  6. +
+ +

마스킹된 Payload 데이터 디코딩하기

+ +

MASK 비트가 설정되어 있디만 32비트 사이즈의 Masking-Key 필드 또한 존재하게 됩니다. 
+ 아래 의사코드는 Payload 데이터를 ENCODED / Masking-Key 필드를 MASK 라고 가정하고 데이터를 디코딩하는 방법을 보여줍니다. ENCODED값을 0부터 순회하면서 MASK의 i % 4에 해당하는 1바이트와 XOR 연산을 수행합니다.

+ +

If the MASK bit was set (and it should be, for client-to-server messages), read the next 4 octets (32 bits); this is the masking key. Once the payload length and masking key is decoded, you can go ahead and read that number of bytes from the socket. Let's call the data ENCODED, and the key MASK. To get DECODED, loop through the octets (bytes a.k.a. characters for text data) of ENCODED and XOR the octet with the (i modulo 4)th octet of MASK. In pseudo-code (that happens to be valid JavaScript):

+ +
var DECODED = "";
+for (var i = 0; i < ENCODED.length; i++) {
+    DECODED[i] = ENCODED[i] ^ MASK[i % 4];
+}
+ +

이제 DECODED 데이터를 가지고 프로토콜에 맞게 활용하면 됩니다.

+ +

Message Fragmentation

+ +

The FIN and opcode fields work together to send a message split up into separate frames.  This is called message fragmentation. Fragmentation is only available on opcodes 0x0 to 0x2.

+ +

Recall that the opcode tells what a frame is meant to do. If it's 0x1, the payload is text. If it's 0x2, the payload is binary data. However, if it's 0x0, the frame is a continuation frame. This means the server should concatenate the frame's payload to the last frame it received from that client. Here is a rough sketch, in which a server reacts to a client sending text messages. The first message is sent in a single frame, while the second message is sent across three frames. FIN and opcode details are shown only for the client:

+ +
Client: FIN=1, opcode=0x1, msg="hello"
+Server: (process complete message immediately) Hi.
+Client: FIN=0, opcode=0x1, msg="and a"
+Server: (listening, new message containing text started)
+Client: FIN=0, opcode=0x0, msg="happy new"
+Server: (listening, payload concatenated to previous message)
+Client: FIN=1, opcode=0x0, msg="year!"
+Server: (process complete message) Happy new year to you too!
+ +

Notice the first frame contains an entire message (has FIN=1 and opcode!=0x0), so the server can process or respond as it sees fit. The second frame sent by the client has a text payload (opcode=0x1), but the entire message has not arrived yet (FIN=0). All remaining parts of that message are sent with continuation frames (opcode=0x0), and the final frame of the message is marked by FIN=1. Section 5.4 of the spec describes message fragmentation.

+ +

Pings and Pongs: The Heartbeat of WebSockets

+ +

핸드쉐이크가 끝난 시점부터 서버 혹은 클라이언트는 언제든지 ping 패킷을 보낼 수 있습니다. 만약 ping 패킷이 수신되면 수신자는 가능한 빨리 응답으로 pong 패킷을 보내야 합니다. (ping에서 전달된 payload와 동일한 payload를 붙여서 pong을 보냅니다. 이 경우 최대 payload length는 125입니다.) 서버는 주기적으로 ping을 보내 클라이언트가 아직 살아있는 상태인지 체크할 수 있습니다.

+ +

A ping or pong is just a regular frame, but it's a control frame. Pings have an opcode of 0x9, and pongs have an opcode of 0xA. When you get a ping, send back a pong with the exact same Payload Data as the ping (for pings and pongs, the max payload length is 125). You might also get a pong without ever sending a ping; ignore this if it happens.

+ +
+

If you have gotten more than one ping before you get the chance to send a pong, you only send one pong.

+
+ +

Step 4: Closing the connection

+ +

To close a connection either the client or server can send a control frame with data containing a specified control sequence to begin the closing handshake (detailed in Section 5.5.1). Upon receiving such a frame, the other peer sends a Close frame in response. The first peer then closes the connection. Any further data received after closing of connection is then discarded. 

+ +

Miscellaneous

+ +
+

WebSocket codes, extensions, subprotocols, etc. are registered at the IANA WebSocket Protocol Registry.

+
+ +

WebSocket extensions and subprotocols are negotiated via headers during the handshake. Sometimes extensions and subprotocols seem too similar to be different things, but there is a clear distinction. Extensions control the WebSocket frame and modify the payload, while subprotocols structure the WebSocket payload and never modify anything. Extensions are optional and generalized (like compression); subprotocols are mandatory and localized (like ones for chat and for MMORPG games).

+ +

Extensions

+ +
+

This section needs expansion. Please edit if you are equipped to do so.

+
+ +

Think of an extension as compressing a file before e-mailing it to someone. Whatever you do, you're sending the same data in different forms. The recipient will eventually be able to get the same data as your local copy, but it is sent differently. That's what an extension does. WebSockets defines a protocol and a simple way to send data, but an extension such as compression could allow sending the same data but in a shorter format.

+ +
+

Extensions are explained in sections 5.8, 9, 11.3.2, and 11.4 of the spec.

+
+ +

TODO

+ +

서브프로토콜

+ +

Think of a subprotocol as a custom XML schema or doctype declaration. You're still using XML and its syntax, but you're additionally restricted by a structure you agreed on. WebSocket subprotocols are just like that. They do not introduce anything fancy, they just establish structure. Like a doctype or schema, both parties must agree on the subprotocol; unlike a doctype or schema, the subprotocol is implemented on the server and cannot be externally refered to by the client.

+ +
+

Subprotocols are explained in sections 1.9, 4.2, 11.3.4, and 11.5 of the spec.

+
+ +

클라이언트는 핸드쉐이크 요청 시에 특정한 서브프로콜의 목록을 같이 보낼 수 있습니다. Sec-WebSocket-Protocol 헤더에 사용하기를 원하는 서브프로토콜의 목록을 같이 보냅니다.

+ +
GET /chat HTTP/1.1
+...
+Sec-WebSocket-Protocol: soap, wamp
+
+
+ +

또는 아래와 같이 보낼 수도 있습니다.:

+ +
...
+Sec-WebSocket-Protocol: soap
+Sec-WebSocket-Protocol: wamp
+
+
+ +

클라이언트로부터 서브프로토콜 요청을 받으면, 서버는 그 중에서 자신이 지원할 수 있는 서브프로토콜을 하나 골라야 합니다. 만약 클라이언트가 보낸 목록 중, 여러개를 지원할 수 있다면 지원하는 목록 중 가장 첫번째 서브프로토콜을 보내주세요. 

+ +

Imagine our server can use both soap and wamp. Then, in the response handshake, it'll send:

+ +
Sec-WebSocket-Protocol: soap
+
+
+ +
+

서버는 반드시 하나의 Sec-Websocket-Protocol 헤더만을 송신해야 합니다.
+ 만약 서버가 어떠한 서브프로토콜도 지원하고 싶지 않다면 Sec-Websocket-Protocol 헤더를 빼고 보내주세요. 빈 값을 넣어서 보내도 안됩니다.
+ 서버가 아무 서브프로토콜을 지원하지 않겠다고 한다면 클라이언트는 연결을 닫아버릴수도 있습니다.

+
+ +

If you want your server to obey certain subprotocols, then naturally you'll need extra code on the server. Let's imagine we're using a subprotocol json. In this subprotocol, all data is passed as JSON. If the client solicits this protocol and the server wants to use it, the server will need to have a JSON parser. Practically speaking, this will be part of a library, but the server will need to pass the data around.

+ +
+

Tip: To avoid name conflict, it's recommended to make your subprotocol name part of a domain string. If you are building a custom chat app that uses a proprietary format exclusive to Example Inc., then you might use this: Sec-WebSocket-Protocol: chat.example.com. For different versions, a widely-used method is to add a / followed by the version number, like chat.example.com/2.0. Note that this isn't required, it's just an optional convention, and you can use any string you wish.

+
+ +

같이 보기

+ + diff --git a/files/ko/web/api/window/domcontentloaded_event/index.html b/files/ko/web/api/window/domcontentloaded_event/index.html new file mode 100644 index 0000000000..24db56aa91 --- /dev/null +++ b/files/ko/web/api/window/domcontentloaded_event/index.html @@ -0,0 +1,77 @@ +--- +title: DOMContentLoaded +slug: Web/Events/DOMContentLoaded +tags: + - Event + - Reference + - Web + - Window +translation_of: Web/API/Window/DOMContentLoaded_event +--- +
{{APIRef}}
+ +

DOMContentLoaded 이벤트는 초기 HTML 문서를 완전히 불러오고 분석했을 때 발생합니다. 스타일 시트, 이미지, 하위 프레임의 로딩은 기다리지 않습니다.

+ + + + + + + + + + + + + + + + + + + + +
확산
취소 가능예 (although specified as a simple event that isn't cancelable)
인터페이스{{domxref("Event")}}
이벤트 처리기 속성아니오
+ +

DOMContentLoaded의 원본 대상은 다 불러온 {{domxref("Document")}}입니다. You can listen for this event on the Window interface to handle it in the capture or bubbling phases. For full details on this event please see the page on the Document: {{domxref("Document/DOMContentLoaded_event", "DOMContentLoaded")}} event.

+ +

A different event, {{domxref("Window/load_event", "load")}}, should be used only to detect a fully-loaded page. It is a common mistake to use load where DOMContentLoaded would be more appropriate.

+ +

예제

+ +

기본 용도

+ +
window.addEventListener('DOMContentLoaded', (event) => {
+    console.log('DOM fully loaded and parsed');
+});
+
+ +

사양

+ + + + + + + + + + + + + + +
사양상태
{{SpecName('HTML WHATWG', 'indices.html#event-domcontentloaded')}}{{Spec2('HTML WHATWG')}}
+ +

브라우저 호환성

+ + + +

{{Compat("api.Window.DOMContentLoaded_event")}}

+ +

같이 보기

+ + diff --git a/files/ko/web/api/window/load_event/index.html b/files/ko/web/api/window/load_event/index.html new file mode 100644 index 0000000000..baef50af25 --- /dev/null +++ b/files/ko/web/api/window/load_event/index.html @@ -0,0 +1,128 @@ +--- +title: load +slug: Web/Events/load +tags: + - Event + - 이벤트 +translation_of: Web/API/Window/load_event +--- +

load 이벤트는 리소스와 그것에 의존하는 리소스들의 로딩이 완료되면 실행됩니다.

+ +

 

+ +

예제

+ +

Window

+ +
<script>
+  window.addEventListener("load", function(event) {
+    console.log("All resources finished loading!");
+  });
+</script>
+ +

script 엘리먼트

+ +
<script>
+  var script = document.createElement("script");
+  script.addEventListener("load", function(event) {
+    console.log("Script finished loading and executing");
+  });
+  script.src = "http://example.com/example.js";
+  script.async = true;
+  document.getElementsByTagName("script")[0].parentNode.appendChild(script);
+</script>
+ +

일반 정보

+ +
+
스펙
+
DOM L3
+
인터페이스
+
UIEvent
+
Bubbles
+
No
+
취소가능 여부
+
No
+
타겟
+
Window,Document,Element
+
기본 동작
+
None.
+
+ +

속성

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
속성타입설명
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{domxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{domxref("Boolean")}}Whether the event is cancellable or not.
view {{readonlyInline}}{{domxref("WindowProxy")}}{{domxref("Document.defaultView", "document.defaultView")}} (window of the document)
detail {{readonlyInline}}long (float)0.
+ +

스펙 정보

+ + + + + + + + + + + + + + + + + + + +
스펙상태코멘트
{{SpecName('UI Events', '#event-type-load', 'load')}}{{Spec2('UI Events')}} 
{{SpecName('HTML WHATWG', 'parsing.html#the-end:event-load', 'Load event')}}{{Spec2('HTML WHATWG')}} +

이것은 문서 로딩이 끝날때 수행되는 단계와 연결되는 섹션과 연결됩니다. 'load' 이벤트는 많은 엘리먼트들에서도 발생합니다. 그리고 스펙 문서에서는 많은 곳에서 "load이벤트를 지연할 수 있는" 것들을 언급한다는 것을 주의하십시오.

+
+ +

관련 이벤트

+ + diff --git a/files/ko/web/api/windoworworkerglobalscope/settimeout/index.html b/files/ko/web/api/windoworworkerglobalscope/settimeout/index.html new file mode 100644 index 0000000000..7b338a83fa --- /dev/null +++ b/files/ko/web/api/windoworworkerglobalscope/settimeout/index.html @@ -0,0 +1,429 @@ +--- +title: WindowTimers.setTimeout() +slug: Web/API/WindowTimers/setTimeout +tags: + - setTimeout +translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout +--- +
{{APIRef("HTML DOM")}}
+ +

타이머가 만료된 뒤 함수나 지정된 코드를 실행하는 타이머를 설정합니다.

+ +

문법

+ +
var timeoutID = window.setTimeout(func[, delay, param1, param2, ...]);
+var timeoutID = window.setTimeout(code[, delay]);
+window.setTimeout(function, milliseconds);
+
+ +

매개변수

+ +
+
func
+
{{jsxref("function")}}이 타이머가 만료된 뒤 실행됩니다.
+
code
+
선택적 구문으로 함수 대신에 문자열을 넣을 수 있는데, 이것은 타이머가 만료된 뒤 해석되고 실행됩니다.
+ 이 구문은 {{jsxref("Global_Objects/eval", "eval()")}}을 사용하는 것과 같은 보안 위험성을 이유로 권장되지 않습니다.
+
delay {{optional_inline}}
+
타이머가 지정된 함수나 코드를 실행시키기 전에 기다려야할 ms(1000분의 1초) 단위의 시간입니다.
+ 만약 이 매개변수를 생략하면, 0이 값으로 사용됩니다. 실제 지연시간은 더 길어질 수 있습니다;
+ 아래 {{anch("Reasons for delays longer than specified")}}를 참고하세요.
+
param1, ..., paramN {{optional_inline}}
+
타이머가 만료되고 {{anch("func")}}에 전달되는 추가적인 매개변수들입니다.
+
+ +
+

Internet Explorer 9 이하에서는 함수에 추가적인 매개변수들을 전달하는 기능이 동작하지 않습니다.
+ 만약 브라우저에서 이 기능을 사용하고 싶다면, {{anch("polyfill")}}을 사용하세요. (Callback arguments를 봐주세요)

+
+ +

반환 값

+ +

반환되는 timeoutID는 숫자이고, setTimeout()을 호출하여 만들어진 타이머를 식별할 수 있는 0이 아닌 값 입니다;
+ 이 값은 타이머를 취소시키기 위해 {{domxref("WindowTimers.clearTimeout()")}}에 전달할 수도 있습니다.

+ +

setTimeout()과 {{domxref("WindowTimers.setInterval", "setInterval()")}}는 같은 ID 공간을 공유하기 때문에, clearTimeout()과 {{domxref("WindowTimers.clearInterval", "clearInterval()")}} 둘 중 어느 것을 사용해도 기술적으로 동일하게 동작합니다.
+ 하지만 명확성을 위해, 코드를 유지보수할 때 혼란을 피하기 위해 항상 일치시켜야 합니다.

+ +

예제

+ +

다음 예제는 웹 페이지에 2개의 간단한 버튼을 설정하고 setTimeout()과 clearTimeout()에 연결합니다.
+ 첫 번째 버튼이 눌려지면 2초 뒤에 호출되는 타임아웃이 설정되고 clearTimeout()에 사용되는 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('Example')}}
+ clearTimeout() 예제도 봐주세요.

+ +

Polyfill

+ +

하나 이상의 매개변수를 콜백 함수에 넘겨야 하는데, setTimeout() 또는 setInterval()을 사용하여 추가적인 매개변수를 보내는 것을 브라우저에서 지원하지 않는다면(e.g. Internet Explorer 9 이하), HTML5 표준 매개변수 전달 기능을 사용 가능하게 하는 이 polyfill을 넣을 수 있습니다. 그저 아래 코드를 스크립트를 상단에 작성해주시면 됩니다.

+ +
/*\
+|*|
+|*|  임의의 매개변수를 자바스크립트 타이머의 콜백함수에 전달하기 위한 Polyfill (HTML5 표준 명세).
+|*|
+|*|  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 이하를 포함하는 모든 모바일/데스크톱 브라우저에서 자바스크립트를 남용하지 않는 완벽한 해결책으로 , 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]-->
+
+ +

예시

+ +

다른 해결책으로는 익명 함수를 callback으로 호출하여 사용할 수 있으나, 이 방법은 비용이 더 비쌉니다.

+ +
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
+
+ +

위 예제는 arrow function으로도 작성하실 수 있습니다.

+ +
var intervalID = setTimeout(() => { myFunc("one", "two", "three"); }, 1000);
+
+ +

다른 하나는 function's bind를 이용하는 것 입니다.

+ +
setTimeout(function(arg1){}.bind(undefined, 10), 1000);
+
+ +

"this" 문제

+ +

setTimeout()에 매개변수(혹은 다른 함수)를 전달할 때, 당신의 기대와는 다르게 this의 값이 호출될 것이다. 해당 이슈에 대한 자세한 사항은 JavaScript reference를 참고해주세요.

+ +

설명

+ +

setTimeout()에 의해 실행된 코드는 별도의 실행 컨텍스트에서 setTimeout이 호출된 함수로 호출됩니다.  호출된 함수에 대해서는 this 키워드를 설정하는 일반적인 규칙이 적용되며, this를 설정 혹은 할당하지 않은 경우, non-strict 모드에서 전역(혹은 window) 객체, strict모드에서 undefined를 기본 값으로 합니다. 다음 예제를 봐주세요: 

+ +
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"
+ +

위와 같이 동작하는 이유는 myMethod 호출될 때, this는 myArray로 설정되므로, 함수 내에서의 this[속성]은 myArray[속성]와 같습니다. 하지만, 다음 예제를 보면:

+ +
setTimeout(myArray.myMethod, 1000); // 1초 뒤 "[Window 객체]" 출력
+setTimeout(myArray.myMethod, 1500, "1"); // 1.5초 뒤 "undefined" 출력
+ +

myArray.myMethod 함수는 setTimeout에 전달되고, 호출될 때 this는 설정되어 있지 않아 window 객체를 기본값으로 합니다. forEach, reduce 등 Array 메서드 같이 this를 매개변수로 넘길 수 있는 옵션 또한 없습니다. 그리고 아래에서 보다시피, 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 설정이 필요한 곳을 함수로 감싸는 것(Wrapper Function) 입니다:

+ +
setTimeout(function(){myArray.myMethod()}, 2000); // 2초 뒤"zero,one,two" 출력
+setTimeout(function(){myArray.myMethod('1')}, 2500); // 2.5초 뒤"one" 출력
+ +

화살표 함수(Arrow Function) 역시 가능한 대안입니다:

+ +
setTimeout(() => {myArray.myMethod()}, 2000); // 2초 뒤 "zero,one,two" 출력
+setTimeout(() => {myArray.myMethod('1')}, 2500); // 2.5초 뒤 "one" after 2.5 출력
+ +

this 문제를 해결하는 또다른 방법은 전역함수 setTimeout()과 setInterval()를 this 객체를 전달할 수 있는 전역함수로 대체하고 Function.prototype.call을 사용하여 콜백을 설정합니다:

+ +
// Enable setting 'this' in 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);
+};
+ +
위 2개의 대안들은 IE의 타이 콜백함수에 임의의 매개변수를 전달하는 HTML5 표준 또한 가능하게 합니다.
+ +

새로운 기능 테스트:

+ +
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은 주어진 함수에 대한 모든 호출의 this 값을 설정하기 위한 Function.prototype.bind() 메서드를 도입하였습니다. 이렇게 하면 wrapper 함수를 사용하지 않고 콜백에 this 값을 설정할 수 있습니다.
+ +

bind()를 사용한 예제:

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

참고

+ +

Timeout은 {{domxref("WindowOrWorkerGlobalScope.clearTimeout()")}}을 사용하면 취소됩니다. 함수를 반복해서 호출해야 한다면 (e.g., N 밀리초마다), {{domxref("WindowOrWorkerGlobalScope.setInterval()")}} 사용을 고려해보세요.

+ +

setTimeout()을 호출한 쓰레드가 종료될 때까지 함수나 코드 조각이 실행될 수 없다는 점에 유의해야합니다. 예를들어:

+ +
function foo(){
+  console.log('foo has been called');
+}
+setTimeout(foo, 0);
+console.log('After setTimeout');
+ +

콘솔에 이렇게 쓰여질겁니다:

+ +
After setTimeout
+foo has been called
+ +

그 이유는 setTimeout가 지연시간 0으로 호출되었지만, queue에 배치되어 다음 기회에 실행되도록 예정되기 때문입니다. 현재 실행중인 코드는 queue에 있는 함수들이 실행되기 전에 완료되고, 실행 순서가 예상과 다를 수 있습니다.

+ +

문자열을 넘길경우

+ +

 setTimeout() 함수대신 문자열을 넘기면 eval 사용했을 때와 같은 위험성을 가집니다.

+ +
// 권장
+window.setTimeout(function() {
+    alert("Hello World!");
+}, 500);
+
+// 비권장
+window.setTimeout("alert('Hello World!');", 500);
+
+ +

setTimeout에 전달된 문자열은 전역 context에서 해석하므로, setTimeout()이 호출된 로컬 context의 Symbol은 문자열이 코드로 해석될 때 사용할 수 없습니다.

+ +

지정된 것보다 더 오래 지연되는 이유

+ +

타임아웃이 예상보다 더 늦게까지 지연되는 데는 여러가지 이유가 있습니다. 이 문단에서는 일반적인 이유에 대해서 설명합니다.

+ +

중첩된 타임아웃이 4ms 이하일 경우

+ +

역사적으로 브라우저들은 setTimeout() "clamping"을 구현했습니다: "최소 지연" 한계보다 작은 지연을 가진 setTimeout() 호출은 최소 지연을 사용하도록 강제됩니다.

+ +

실제로, 4ms는 HTML5 스펙에 명시되어 있고 2010년 이후에 출시된 브라우저들은 일관성을 유지하고 있습니다. {{geckoRelease("5.0")}} 이전에 출시된 브라우저들은, 타임아웃(중첩 5이상)의 최소 지연시간은 10ms였습니다.

+ +

최신 브라우저에서 0ms 타임아웃을 구현하려면, 이곳에 설명된 {{domxref("window.postMessage()")}}를 사용할 수 있습니다.

+ +

비활성 탭에서 타임아웃이1000ms에 여러 번 일어날 경우

+ +

부하와 배터리 사용양을 줄이기 위해서, 비활성화 탭들에서 타임아웃이 1초에 여러번 일어나지 않도록 "clamping" 됩니다.

+ +

Firefox는 5버전부터 이 동작을 구현했습니다. ({{bug(633421)}}참고, 1000ms 상수는  dom.min_background_timeout_value 설정을 통해 수정할 수 있습니다)
+ Chrome은  11버전부터 구현했습니다 (crbug.com/66078).

+ +

Android용 Firefox는 {{bug(736602)}} 이후 버전 14부터 백그라운드 탭에 15분의 타임아웃을 사용하고, 완전히 unload도 할 수 있습니다.

+ +

타임아웃 지연

+ +

"clamping"과 더불어, 타임아웃은 다른 작업들로 인해 바쁜 페이지에서 늦게 실행될 수 있습니다.

+ +

최대 지연 값

+ +

Internet Explorer, Chrome, Safari, and Firefox 포함하는 브라우저들은 내부적으로 32-bit 부호있는 정수로 지연 값을 저장합니다. 이로 인해 2147483647보다 더 큰 지연을 사용할 때 정수 오버플로우가 발생하여, 타임아웃이 즉시 실행됩니다.

+ +

사양

+ + + + + + + + + + + + + + +
사양상태주석
{{SpecName("HTML WHATWG", "webappapis.html#dom-settimeout", "WindowTimers.setTimeout()")}}{{Spec2("HTML WHATWG")}}Initial definition (DOM Level 0)
+ +

지원 브라우저

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
기능ChromeFirefox (Gecko)Internet ExplorerOperaSafari
기본1.0{{CompatGeckoDesktop("1")}}4.04.01.0
Callback 매개변수 지원[1]{{CompatVersionUnknown}}{{CompatVersionUnknown}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
기능AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
기본1.01.0{{CompatGeckoMobile("1")}}6.06.01.0
Callback 매개변수 지원[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
+
+ +

[1] 첫번째 form에서 매개변수를 지원하는지에 대한 여부.

+ +

더 알아보기

+ + diff --git a/files/ko/web/api/windowtimers/settimeout/index.html b/files/ko/web/api/windowtimers/settimeout/index.html deleted file mode 100644 index 7b338a83fa..0000000000 --- a/files/ko/web/api/windowtimers/settimeout/index.html +++ /dev/null @@ -1,429 +0,0 @@ ---- -title: WindowTimers.setTimeout() -slug: Web/API/WindowTimers/setTimeout -tags: - - setTimeout -translation_of: Web/API/WindowOrWorkerGlobalScope/setTimeout ---- -
{{APIRef("HTML DOM")}}
- -

타이머가 만료된 뒤 함수나 지정된 코드를 실행하는 타이머를 설정합니다.

- -

문법

- -
var timeoutID = window.setTimeout(func[, delay, param1, param2, ...]);
-var timeoutID = window.setTimeout(code[, delay]);
-window.setTimeout(function, milliseconds);
-
- -

매개변수

- -
-
func
-
{{jsxref("function")}}이 타이머가 만료된 뒤 실행됩니다.
-
code
-
선택적 구문으로 함수 대신에 문자열을 넣을 수 있는데, 이것은 타이머가 만료된 뒤 해석되고 실행됩니다.
- 이 구문은 {{jsxref("Global_Objects/eval", "eval()")}}을 사용하는 것과 같은 보안 위험성을 이유로 권장되지 않습니다.
-
delay {{optional_inline}}
-
타이머가 지정된 함수나 코드를 실행시키기 전에 기다려야할 ms(1000분의 1초) 단위의 시간입니다.
- 만약 이 매개변수를 생략하면, 0이 값으로 사용됩니다. 실제 지연시간은 더 길어질 수 있습니다;
- 아래 {{anch("Reasons for delays longer than specified")}}를 참고하세요.
-
param1, ..., paramN {{optional_inline}}
-
타이머가 만료되고 {{anch("func")}}에 전달되는 추가적인 매개변수들입니다.
-
- -
-

Internet Explorer 9 이하에서는 함수에 추가적인 매개변수들을 전달하는 기능이 동작하지 않습니다.
- 만약 브라우저에서 이 기능을 사용하고 싶다면, {{anch("polyfill")}}을 사용하세요. (Callback arguments를 봐주세요)

-
- -

반환 값

- -

반환되는 timeoutID는 숫자이고, setTimeout()을 호출하여 만들어진 타이머를 식별할 수 있는 0이 아닌 값 입니다;
- 이 값은 타이머를 취소시키기 위해 {{domxref("WindowTimers.clearTimeout()")}}에 전달할 수도 있습니다.

- -

setTimeout()과 {{domxref("WindowTimers.setInterval", "setInterval()")}}는 같은 ID 공간을 공유하기 때문에, clearTimeout()과 {{domxref("WindowTimers.clearInterval", "clearInterval()")}} 둘 중 어느 것을 사용해도 기술적으로 동일하게 동작합니다.
- 하지만 명확성을 위해, 코드를 유지보수할 때 혼란을 피하기 위해 항상 일치시켜야 합니다.

- -

예제

- -

다음 예제는 웹 페이지에 2개의 간단한 버튼을 설정하고 setTimeout()과 clearTimeout()에 연결합니다.
- 첫 번째 버튼이 눌려지면 2초 뒤에 호출되는 타임아웃이 설정되고 clearTimeout()에 사용되는 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('Example')}}
- clearTimeout() 예제도 봐주세요.

- -

Polyfill

- -

하나 이상의 매개변수를 콜백 함수에 넘겨야 하는데, setTimeout() 또는 setInterval()을 사용하여 추가적인 매개변수를 보내는 것을 브라우저에서 지원하지 않는다면(e.g. Internet Explorer 9 이하), HTML5 표준 매개변수 전달 기능을 사용 가능하게 하는 이 polyfill을 넣을 수 있습니다. 그저 아래 코드를 스크립트를 상단에 작성해주시면 됩니다.

- -
/*\
-|*|
-|*|  임의의 매개변수를 자바스크립트 타이머의 콜백함수에 전달하기 위한 Polyfill (HTML5 표준 명세).
-|*|
-|*|  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 이하를 포함하는 모든 모바일/데스크톱 브라우저에서 자바스크립트를 남용하지 않는 완벽한 해결책으로 , 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]-->
-
- -

예시

- -

다른 해결책으로는 익명 함수를 callback으로 호출하여 사용할 수 있으나, 이 방법은 비용이 더 비쌉니다.

- -
var intervalID = setTimeout(function() { myFunc("one", "two", "three"); }, 1000);
-
- -

위 예제는 arrow function으로도 작성하실 수 있습니다.

- -
var intervalID = setTimeout(() => { myFunc("one", "two", "three"); }, 1000);
-
- -

다른 하나는 function's bind를 이용하는 것 입니다.

- -
setTimeout(function(arg1){}.bind(undefined, 10), 1000);
-
- -

"this" 문제

- -

setTimeout()에 매개변수(혹은 다른 함수)를 전달할 때, 당신의 기대와는 다르게 this의 값이 호출될 것이다. 해당 이슈에 대한 자세한 사항은 JavaScript reference를 참고해주세요.

- -

설명

- -

setTimeout()에 의해 실행된 코드는 별도의 실행 컨텍스트에서 setTimeout이 호출된 함수로 호출됩니다.  호출된 함수에 대해서는 this 키워드를 설정하는 일반적인 규칙이 적용되며, this를 설정 혹은 할당하지 않은 경우, non-strict 모드에서 전역(혹은 window) 객체, strict모드에서 undefined를 기본 값으로 합니다. 다음 예제를 봐주세요: 

- -
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"
- -

위와 같이 동작하는 이유는 myMethod 호출될 때, this는 myArray로 설정되므로, 함수 내에서의 this[속성]은 myArray[속성]와 같습니다. 하지만, 다음 예제를 보면:

- -
setTimeout(myArray.myMethod, 1000); // 1초 뒤 "[Window 객체]" 출력
-setTimeout(myArray.myMethod, 1500, "1"); // 1.5초 뒤 "undefined" 출력
- -

myArray.myMethod 함수는 setTimeout에 전달되고, 호출될 때 this는 설정되어 있지 않아 window 객체를 기본값으로 합니다. forEach, reduce 등 Array 메서드 같이 this를 매개변수로 넘길 수 있는 옵션 또한 없습니다. 그리고 아래에서 보다시피, 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 설정이 필요한 곳을 함수로 감싸는 것(Wrapper Function) 입니다:

- -
setTimeout(function(){myArray.myMethod()}, 2000); // 2초 뒤"zero,one,two" 출력
-setTimeout(function(){myArray.myMethod('1')}, 2500); // 2.5초 뒤"one" 출력
- -

화살표 함수(Arrow Function) 역시 가능한 대안입니다:

- -
setTimeout(() => {myArray.myMethod()}, 2000); // 2초 뒤 "zero,one,two" 출력
-setTimeout(() => {myArray.myMethod('1')}, 2500); // 2.5초 뒤 "one" after 2.5 출력
- -

this 문제를 해결하는 또다른 방법은 전역함수 setTimeout()과 setInterval()를 this 객체를 전달할 수 있는 전역함수로 대체하고 Function.prototype.call을 사용하여 콜백을 설정합니다:

- -
// Enable setting 'this' in 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);
-};
- -
위 2개의 대안들은 IE의 타이 콜백함수에 임의의 매개변수를 전달하는 HTML5 표준 또한 가능하게 합니다.
- -

새로운 기능 테스트:

- -
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은 주어진 함수에 대한 모든 호출의 this 값을 설정하기 위한 Function.prototype.bind() 메서드를 도입하였습니다. 이렇게 하면 wrapper 함수를 사용하지 않고 콜백에 this 값을 설정할 수 있습니다.
- -

bind()를 사용한 예제:

- -
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
-
- -

참고

- -

Timeout은 {{domxref("WindowOrWorkerGlobalScope.clearTimeout()")}}을 사용하면 취소됩니다. 함수를 반복해서 호출해야 한다면 (e.g., N 밀리초마다), {{domxref("WindowOrWorkerGlobalScope.setInterval()")}} 사용을 고려해보세요.

- -

setTimeout()을 호출한 쓰레드가 종료될 때까지 함수나 코드 조각이 실행될 수 없다는 점에 유의해야합니다. 예를들어:

- -
function foo(){
-  console.log('foo has been called');
-}
-setTimeout(foo, 0);
-console.log('After setTimeout');
- -

콘솔에 이렇게 쓰여질겁니다:

- -
After setTimeout
-foo has been called
- -

그 이유는 setTimeout가 지연시간 0으로 호출되었지만, queue에 배치되어 다음 기회에 실행되도록 예정되기 때문입니다. 현재 실행중인 코드는 queue에 있는 함수들이 실행되기 전에 완료되고, 실행 순서가 예상과 다를 수 있습니다.

- -

문자열을 넘길경우

- -

 setTimeout() 함수대신 문자열을 넘기면 eval 사용했을 때와 같은 위험성을 가집니다.

- -
// 권장
-window.setTimeout(function() {
-    alert("Hello World!");
-}, 500);
-
-// 비권장
-window.setTimeout("alert('Hello World!');", 500);
-
- -

setTimeout에 전달된 문자열은 전역 context에서 해석하므로, setTimeout()이 호출된 로컬 context의 Symbol은 문자열이 코드로 해석될 때 사용할 수 없습니다.

- -

지정된 것보다 더 오래 지연되는 이유

- -

타임아웃이 예상보다 더 늦게까지 지연되는 데는 여러가지 이유가 있습니다. 이 문단에서는 일반적인 이유에 대해서 설명합니다.

- -

중첩된 타임아웃이 4ms 이하일 경우

- -

역사적으로 브라우저들은 setTimeout() "clamping"을 구현했습니다: "최소 지연" 한계보다 작은 지연을 가진 setTimeout() 호출은 최소 지연을 사용하도록 강제됩니다.

- -

실제로, 4ms는 HTML5 스펙에 명시되어 있고 2010년 이후에 출시된 브라우저들은 일관성을 유지하고 있습니다. {{geckoRelease("5.0")}} 이전에 출시된 브라우저들은, 타임아웃(중첩 5이상)의 최소 지연시간은 10ms였습니다.

- -

최신 브라우저에서 0ms 타임아웃을 구현하려면, 이곳에 설명된 {{domxref("window.postMessage()")}}를 사용할 수 있습니다.

- -

비활성 탭에서 타임아웃이1000ms에 여러 번 일어날 경우

- -

부하와 배터리 사용양을 줄이기 위해서, 비활성화 탭들에서 타임아웃이 1초에 여러번 일어나지 않도록 "clamping" 됩니다.

- -

Firefox는 5버전부터 이 동작을 구현했습니다. ({{bug(633421)}}참고, 1000ms 상수는  dom.min_background_timeout_value 설정을 통해 수정할 수 있습니다)
- Chrome은  11버전부터 구현했습니다 (crbug.com/66078).

- -

Android용 Firefox는 {{bug(736602)}} 이후 버전 14부터 백그라운드 탭에 15분의 타임아웃을 사용하고, 완전히 unload도 할 수 있습니다.

- -

타임아웃 지연

- -

"clamping"과 더불어, 타임아웃은 다른 작업들로 인해 바쁜 페이지에서 늦게 실행될 수 있습니다.

- -

최대 지연 값

- -

Internet Explorer, Chrome, Safari, and Firefox 포함하는 브라우저들은 내부적으로 32-bit 부호있는 정수로 지연 값을 저장합니다. 이로 인해 2147483647보다 더 큰 지연을 사용할 때 정수 오버플로우가 발생하여, 타임아웃이 즉시 실행됩니다.

- -

사양

- - - - - - - - - - - - - - -
사양상태주석
{{SpecName("HTML WHATWG", "webappapis.html#dom-settimeout", "WindowTimers.setTimeout()")}}{{Spec2("HTML WHATWG")}}Initial definition (DOM Level 0)
- -

지원 브라우저

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
기능ChromeFirefox (Gecko)Internet ExplorerOperaSafari
기본1.0{{CompatGeckoDesktop("1")}}4.04.01.0
Callback 매개변수 지원[1]{{CompatVersionUnknown}}{{CompatVersionUnknown}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
기능AndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
기본1.01.0{{CompatGeckoMobile("1")}}6.06.01.0
Callback 매개변수 지원[1]{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

[1] 첫번째 form에서 매개변수를 지원하는지에 대한 여부.

- -

더 알아보기

- - diff --git a/files/ko/web/api/xmlhttprequest/timeout/index.html b/files/ko/web/api/xmlhttprequest/timeout/index.html deleted file mode 100644 index 4ecc599f9d..0000000000 --- a/files/ko/web/api/xmlhttprequest/timeout/index.html +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: timeout -slug: Web/API/XMLHttpRequest/timeout -translation_of: Web/API/XMLHttpRequest/timeout_event ---- -
-

timeout 이벤트는 미리 설정한 시간이 만료되어 진행이 종료되면 시작합니다.

-
- - - - - - - - - - - - - - - - - - - - -
BubblesNo
CancelableNo
Target objects{{domxref("XMLHttpRequest")}}
Interface{{domxref("ProgressEvent")}}
- -

Examples

- -
var client = new XMLHttpRequest();
-client.open("GET", "http://www.example.org/example.txt");
-client.ontimeout = function(e) {
-  console.error("Timeout!!");
-}
-client.send();
- -

Inheritance

- -

timeout 이벤트는 {{domxref("Event")}}에서 상속받은 {{domxref("ProgressEvent")}} 인터페이스를 구현합니다. 이 인터페이스에 선언된 속성(property)과 메서드를 사용할 수 있습니다.

- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('XMLHttpRequest')}}{{Spec2('XMLHttpRequest')}} 
- -

Browser compatibility

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.9.1")}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidAndroid WebviewEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.9.1")}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
-
- -

See also

- - diff --git a/files/ko/web/api/xmlhttprequest/timeout_event/index.html b/files/ko/web/api/xmlhttprequest/timeout_event/index.html new file mode 100644 index 0000000000..4ecc599f9d --- /dev/null +++ b/files/ko/web/api/xmlhttprequest/timeout_event/index.html @@ -0,0 +1,123 @@ +--- +title: timeout +slug: Web/API/XMLHttpRequest/timeout +translation_of: Web/API/XMLHttpRequest/timeout_event +--- +
+

timeout 이벤트는 미리 설정한 시간이 만료되어 진행이 종료되면 시작합니다.

+
+ + + + + + + + + + + + + + + + + + + + +
BubblesNo
CancelableNo
Target objects{{domxref("XMLHttpRequest")}}
Interface{{domxref("ProgressEvent")}}
+ +

Examples

+ +
var client = new XMLHttpRequest();
+client.open("GET", "http://www.example.org/example.txt");
+client.ontimeout = function(e) {
+  console.error("Timeout!!");
+}
+client.send();
+ +

Inheritance

+ +

timeout 이벤트는 {{domxref("Event")}}에서 상속받은 {{domxref("ProgressEvent")}} 인터페이스를 구현합니다. 이 인터페이스에 선언된 속성(property)과 메서드를 사용할 수 있습니다.

+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('XMLHttpRequest')}}{{Spec2('XMLHttpRequest')}} 
+ +

Browser compatibility

+ +

{{CompatibilityTable}}

+ +
+ + + + + + + + + + + + + + + + + + + + + +
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support1.0{{CompatVersionUnknown}}{{CompatGeckoDesktop("1.9.1")}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + +
FeatureAndroidAndroid WebviewEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari MobileChrome for Android
Basic support{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatGeckoMobile("1.9.1")}}10.0{{CompatVersionUnknown}}{{CompatVersionUnknown}}{{CompatVersionUnknown}}
+
+ +

See also

+ + diff --git a/files/ko/web/api/xsltprocessor/basic_example/index.html b/files/ko/web/api/xsltprocessor/basic_example/index.html new file mode 100644 index 0000000000..cb96c52c55 --- /dev/null +++ b/files/ko/web/api/xsltprocessor/basic_example/index.html @@ -0,0 +1,49 @@ +--- +title: Basic Example +slug: XSLT_in_Gecko/Basic_Example +translation_of: Web/API/XSLTProcessor/Basic_Example +--- +

기본 예

+

이 첫 예는 브라우저에서 XSLT 변환 설정의 기본을 보여준다. 이 예는 Article에 대한 정보(Title, Author 목록과 Body 글)를 포함한 XML 문서를 얻어 그것을 사람이 읽을 수 있는 형식으로 나타낸다. +

그림1은 기본 XSLT예의 소스를 보여준다. XML문서(example.xml)은 글의 정보를 포함한다. ?xml-stylesheet? 처리명령을 써서, 그것의 href 속성을 통해 XSLT 스타일쉬트(example.xsl)에 연결한다. +

XSLT 스타일쉬트는 xsl:stylesheet 요소로 시작하는데, 이것은 최종 출력을 생성하는데 쓰이는 모든 템플리트를 포함한다. 그림1의 예는 템플리트 2개를 가진다 - 하나는 root 노드에 하나는 Author 노드에 대응한다. root 노드에 대응하는 템플리트는 글의 제목을 출력하고 Authors 노드의 자식노드인 Author 노드에 대응하는 모든 템플리트를 처리하기 위해 말한다. +

그림1 : 간단한 XSLT예 +

XML 문서 (example.xml) : +

+
  <?xml version="1.0"?>
+  <?xml-stylesheet type="text/xsl" href="example.xsl"?>
+  <Article>
+    <Title>My Article</Title>
+    <Authors>
+      <Author>Mr. Foo</Author>
+      <Author>Mr. Bar</Author>
+    </Authors>
+    <Body>This is my article text.</Body>
+  </Article>
+
+

XSL 스타일쉬트 (example.xsl) : +

+
  <?xml version="1.0"?>
+  <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+    <xsl:output method="text"/>
+
+    <xsl:template match="/">
+      Article - <xsl:value-of select="/Article/Title"/>
+      Authors: <xsl:apply-templates select="/Article/Authors/Author"/>
+    </xsl:template>
+
+    <xsl:template match="Author">
+      - <xsl:value-of select="." />
+    </xsl:template>
+
+  </xsl:stylesheet>
+
+

브라우저 출력: +

+
  Article - My Article
+  Authors:
+  - Mr. Foo
+  - Mr. Bar
+
+{{ languages( { "en": "en/XSLT_in_Gecko/Basic_Example" } ) }} diff --git a/files/ko/web/api/xsltprocessor/browser_differences/index.html b/files/ko/web/api/xsltprocessor/browser_differences/index.html new file mode 100644 index 0000000000..0d22a5b825 --- /dev/null +++ b/files/ko/web/api/xsltprocessor/browser_differences/index.html @@ -0,0 +1,8 @@ +--- +title: Browser Differences +slug: XSLT_in_Gecko/Browser_Differences +translation_of: Web/API/XSLTProcessor/Browser_Differences +--- +

브라우저 차이

+

Netscape 7.x (모든 플랫폼)과 Internet Explorer 6(윈도즈)는 W3C XSLT 1.0 표준( http://www.w3.org/TR/xslt )을 지원합니다. IE 5.0과 5.5 (둘 다 윈도즈)는 XSLT의 초안만 지원하므로 XSLT 1.0 스타일쉬트와는 호환하지 않습니다. Netscape 6.x는 XSLT 1.0을 부분적으로만 지원합니다. +

{{ languages( { "en": "en/XSLT_in_Gecko/Browser_Differences" } ) }} diff --git a/files/ko/web/api/xsltprocessor/generating_html/index.html b/files/ko/web/api/xsltprocessor/generating_html/index.html new file mode 100644 index 0000000000..5bb284bdb8 --- /dev/null +++ b/files/ko/web/api/xsltprocessor/generating_html/index.html @@ -0,0 +1,174 @@ +--- +title: Generating HTML +slug: XSLT_in_Gecko/Generating_HTML +translation_of: Web/API/XSLTProcessor/Generating_HTML +--- +

HTML 생성하기

+

브라우저에서 XSLT의 공통 응용은 XML을 클라이언트의 안에 변환해 넣는 것이다. 두번째 예는 입력문서(example2.xml)를 변환하는데, 이것은 또 글의 정보를 포함하고 HTML문서 안에 들어간다. +

Article의 <body> 요소는 지금 HTML의 요소 (<b><u> 태그, 그림 2)를 포함한다. XML 문서는 HTML요소와 XML 요소 모두 포함하지만, 단 하나의 namespace 즉 XML 요소만 필요하다. HTML namespace가 없으므로, 그리고 XHTML namespace를 사용하여 XSL에서 an XML document를 생성하고 그것은 HTML문서와 같은 양상은 아닐 것이고, XSL Stylesheet 의xsl:output는 결과문서는 HTML처럼 다루어질 것을 보장한다 . XML 요소에 대해, 우리 자신의 namespace http://devedge.netscape.com/2002/de 는 필요하고, 그것은 접두어 myNS (xmlns:myNS="http://devedge.netscape.com/2002/de)에 주어진다. +

그림 2 XML 파일 (example2.xml) +XML Document (example2.xml): +

+
<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="example2.xsl"?>
+<myNS:Article xmlns:myNS="http://devedge.netscape.com/2002/de">
+<myNS:Title>My Article</myNS:Title>
+<myNS:Authors>
+<myNS:Author company="Foopy Corp.">Mr. Foo</myNS:Author>
+<myNS:Author>Mr. Bar</myNS:Author>
+</myNS:Authors>
+<myNS:Body>
+The <b>rain</b> in <u>Spain</u> stays mainly in the plains.
+</myNS:Body>
+</myNS:Article>
+
+

The XSL Stylesheet used will need to have two namespaces - one for the XSLT elements and one for our own XML elements used in the XML document. The output of the XSL Stylesheet is set to HTML by using the xsl:output element. By setting the output to be HTML and not having a namespace on the resulting elements (colored in blue), those elements will be treated as HTML elements. +

그림 3 : 두 namespaces를 가진 XSL Stylesheet (example2.xsl) +XSL Stylesheet (example2.xsl): +

+
<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+xmlns:myNS="http://devedge.netscape.com/2002/de">
+
+<xsl:output method="html"/>
+...
+</xsl:stylesheet version="1.0">
+
+

A template matching the root node of the XML document is created and used to create the basic structure of the HTML page. +

Figure 4 : Creating the basic HTML document +XSL Stylesheet (example2.xsl): +

+
...
+<xsl:template match="/">
+<html>
+
+<head>
+
+<title>
+<xsl:value-of select="/myNS:Article/myNS:Title"/>
+</title>
+
+<style type="text/css">
+.myBox {margin:10px 155px 0 50px; border: 1px dotted #639ACE; padding:0 5px 0 5px;}
+</style>
+
+</head>
+
+<body>
+<p class="myBox">
+<span class="title">
+<xsl:value-of select="/myNS:Article/myNS:Title"/>
+</span> </br>
+
+Authors: <br />
+<xsl:apply-templates select="/myNS:Article/myNS:Authors/myNS:Author"/>
+</p>
+
+<p class="myBox">
+<xsl:apply-templates select="//myNS:Body"/>
+</p>
+
+</body>
+
+</html>
+</xsl:template>
+...
+
+

Three more xsl:template's are needed to complete the example. The first xsl:template is used for the author nodes, while the second one processes the body node. The third template has a general matching rule which will match any node and any attribute. It is needed in order to preserve the html elements in the XML document, since it matches all of them and copies them out into the HTML document the transformation creates. +

그림 5 : 최종 3개 템플리트 +XSL Stylesheet(example2.xsl): +

+
...
+<xsl:template match="myNS:Author">
+-- <xsl:value-of select="." />
+
+<xsl:if test="@company">
+:: <b> <xsl:value-of select="@company" /> </b>
+</xsl:if>
+
+<br />
+</xsl:template>
+
+<xsl:template match="myNS:Body">
+<xsl:copy>
+<xsl:apply-templates select="@*|node()"/>
+</xsl:copy>
+</xsl:template>
+
+<xsl:template match="@*|node()">
+<xsl:copy>
+<xsl:apply-templates select="@*|node()"/>
+</xsl:copy>
+</xsl:template>
+...
+
+

The final XSLT stylesheet looks as follows: +

그림 6 : 최종 XSLT Stylesheetview example | view source +XSL Stylesheet: +

+
<?xml version="1.0"?>
+<xsl:stylesheet version="1.0"
+xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+xmlns:myNS="http://devedge.netscape.com/2002/de">
+
+<xsl:output method="html" />
+
+<xsl:template match="/">
+<html>
+
+<head>
+
+<title>
+<xsl:value-of select="/myNS:Article/myNS:Title"/>
+</title>
+
+<style type="text/css">
+.myBox {margin:10px 155px 0 50px; border: 1px dotted #639ACE; padding:0 5px 0 5px;}
+</style>
+
+</head>
+
+<body>
+<p class="myBox">
+<span class="title">
+<xsl:value-of select="/myNS:Article/myNS:Title"/>
+</span> <br />
+
+Authors: <br />
+<xsl:apply-templates select="/myNS:Article/myNS:Authors/myNS:Author"/>
+</p>
+
+<p class="myBox">
+<xsl:apply-templates select="//myNS:Body"/>
+</p>
+
+</body>
+
+</html>
+</xsl:template>
+
+<xsl:template match="myNS:Author">
+-- <xsl:value-of select="." />
+
+<xsl:if test="@company">
+:: <b> <xsl:value-of select="@company" /> </b>
+</xsl:if>
+
+<br />
+</xsl:template>
+
+<xsl:template match="myNS:Body">
+<xsl:copy>
+<xsl:apply-templates select="@*|node()"/>
+</xsl:copy>
+</xsl:template>
+
+<xsl:template match="@*|node()">
+<xsl:copy>
+<xsl:apply-templates select="@*|node()"/>
+</xsl:copy>
+</xsl:template>
+</xsl:stylesheet>
+
+{{ languages( { "en": "en/XSLT_in_Gecko/Generating_HTML" } ) }} diff --git a/files/ko/web/api/xsltprocessor/index.html b/files/ko/web/api/xsltprocessor/index.html new file mode 100644 index 0000000000..84d5198c58 --- /dev/null +++ b/files/ko/web/api/xsltprocessor/index.html @@ -0,0 +1,15 @@ +--- +title: XSLT in Gecko +slug: XSLT_in_Gecko +tags: + - XSLT +translation_of: Web/API/XSLTProcessor +translation_of_original: XSLT_in_Gecko +--- +
  1. 개요 +
  2. 기본 예제 +
  3. HTML 생성 +
  4. 브라우저 차이 +
  5. 자원 +
+{{ languages( { "en": "en/XSLT_in_Gecko" } ) }} diff --git a/files/ko/web/api/xsltprocessor/introduction/index.html b/files/ko/web/api/xsltprocessor/introduction/index.html new file mode 100644 index 0000000000..bfb103b98f --- /dev/null +++ b/files/ko/web/api/xsltprocessor/introduction/index.html @@ -0,0 +1,13 @@ +--- +title: Introduction +slug: XSLT_in_Gecko/Introduction +translation_of: Web/API/XSLTProcessor/Introduction +--- +

개요

+

W3표준 안에서 주목할만한 하나의 흐름은 스타일로부터 내용을 분리하려는 노력이다. +

이것은 같은 스타일이 여러 내용에서 재사용되는 것을 허용할 뿐 아니라 유지보수를 쉽게 하고 (하나의 파일만 바꾸어서) 내용의 외관을 빠르게 바꾸는 방법을 허용한다. +

CSS (Cascade Style Sheets)는 W3C에서 제안된 첫번째 방법이다. CSS는 스타일규칙을 웹문서에 적용하는 간단한 방법이다. 이 스타일규칙은 어떻게 문서(내용)가 놓일지 정의한다. 그러나, 여러 제한이 있다. 프로그램 구조와 복잡한 레이아웃 모델을 만드는 가능성의 부족. CSS는 요소의 위치 변화제공에 제한된다. +

XSL (Extensible Stylesheet Language)변환은 두 부분으로 구성된다. XML트리를 다른 마크업 트리로 변환하는 XSL요소, 트리를 위한 선택언어 XPath. +XSLT는 XML문서를 얻어서 XSL스타일쉬트안의 규칙에 기반한 새 문서를 생성한다. 이것은 XSLT가 원 XML문서로부터 요소를 추가, 제거, 재구성하는 것을 허용하고 따라서 결과문서구조의 좀더 세분된 제어를 허용한다. +

XSLT의 변환은 template로 구성된 규칙에 기반한다. 각 template은 입력 XML문서의 조각에 대응하고 대응하는 부분을 새 결과문서에 적용한다. +

{{ languages( { "en": "en/XSLT_in_Gecko/Introduction" } ) }} diff --git a/files/ko/web/api/xsltprocessor/resources/index.html b/files/ko/web/api/xsltprocessor/resources/index.html new file mode 100644 index 0000000000..bcdb54116f --- /dev/null +++ b/files/ko/web/api/xsltprocessor/resources/index.html @@ -0,0 +1,14 @@ +--- +title: Resources +slug: XSLT_in_Gecko/Resources +translation_of: Web/API/XSLTProcessor/Resources +--- +

자원

+ diff --git a/files/ko/web/css/@viewport/height/index.html b/files/ko/web/css/@viewport/height/index.html deleted file mode 100644 index 96dd3182ad..0000000000 --- a/files/ko/web/css/@viewport/height/index.html +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: height -slug: Web/CSS/@viewport/height -tags: - - '@viewport' - - CSS - - CSS Descriptor - - Reference -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/height ---- -
{{CSSRef}}
- -

height CSS 서술자(descriptor)는 뷰포트의 {{cssxref("@viewport/min-height", "min-height")}} 및 {{cssxref("@viewport/max-height", "max-height")}} 둘 다 설정하기 위한 단축(shorthand) 설명자입니다. 뷰포트 길이 값 하나를 주어 최소 높이 및 최대 높이 둘 다를 주어진 값으로 설정합니다.

- -

뷰포트 값이 두 개 주어진 경우, 첫 번째 값은 최소 높이로 두 번째 값은 최대 높이로 설정합니다.

- -

{{cssinfo}}

- -

구문

- -
/* 한 값 */
-height: auto;
-height: 320px;
-height: 15em;
-
-/* 두 값 */
-height: 320px 200px;
-
- -

- -
-
auto
-
다른 CSS 설명자의 값에서 계산된 사용값(used value).
-
<length>
-
음이 아닌 절대 또는 상대 길이.
-
<percentage>
-
가로 및 세로 길이 각각을 위한 줌 배율(factor) 1.0에서 초기 뷰포트의 너비 또는 높이에 대한 퍼센트 값. 음이 아니어야 합니다.
-
- -

형식 구문

- -
{{csssyntax}}
-
- -

예제

- -
@viewport {
-  height: 500px;
-}
- -

명세

- - - - - - - - - - - - - - - - -
명세상태설명
{{SpecName('CSS3 Device', '#descdef-viewport-height', '"height" descriptor')}}{{Spec2('CSS3 Device')}}초기 정의
- -

브라우저 호환성

- - - -

{{Compat("css.at-rules.viewport.height")}}

diff --git a/files/ko/web/css/@viewport/viewport-fit/index.html b/files/ko/web/css/@viewport/viewport-fit/index.html deleted file mode 100644 index 7dab19acbd..0000000000 --- a/files/ko/web/css/@viewport/viewport-fit/index.html +++ /dev/null @@ -1,73 +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)", "설명자")}}는 문서의 뷰포트가 화면을 채우는 방법을 제어합니다.

- -

Syntax

- -
/* Keyword values */
-viewport-fit: auto;
-viewport-fit: contain;
-viewport-fit: cover;
-
- -

Values

- -
-
auto
-
이 값은 초기 레이아웃 뷰포트에 영향을 미치지 않으며 전체 웹 페이지가 보여집니다.
-
contain
-
뷰포트 크기가 디스플레이 내에 새겨진 가장 큰 직사각형에 들어맞게 조정됩니다.
-
- -
-
cover
-
뷰포트 크기가 기기 디스플레이를 모두 채우도록 조정됩니다. 이때 중요한 내용이 디스플레이 바깥 영역으로 밀려나지 않도록 safe area inset 변수를 함께 사용할 것을 권장합니다.
-
- -

Formal syntax

- -
auto | contain | 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")}}

- -

See also

- - diff --git a/files/ko/web/css/@viewport/zoom/index.html b/files/ko/web/css/@viewport/zoom/index.html deleted file mode 100644 index 699b60921e..0000000000 --- a/files/ko/web/css/@viewport/zoom/index.html +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: zoom -slug: Web/CSS/@viewport/zoom -tags: - - CSS - - CSS Descriptor - - Graphics - - Layout - - NeedsExample - - Reference -translation_of: Web/CSS/@viewport -translation_of_original: Web/CSS/@viewport/zoom ---- -
{{ CSSRef }}
- -

zoom CSS 설명자(descriptor)는 {{cssxref("@viewport")}}에 의해 정의된 문서의 초기 줌 배율(factor)을 설정합니다.

- -

1.0 또는 100%줌 배율은 줌이 없음에 해당합니다. 큰 값은 확대. 작은 값은 축소.

- -

{{cssinfo}}

- -

구문

- -
/* 키워드 값 */
-zoom: auto;
-
-/* <number> 값 */
-zoom: 0.8;
-zoom: 2.0;
-
-/* <percentage> 값 */
-zoom: 150%;
-
- -

- -
-
auto
-
사용자 에이전트가 문서의 초기 줌 배율을 설정합니다. 사용자 에이전트는 문서가 그 배율을 찾기 위해 렌더링되는 캔버스 영역의 크기를 사용할 수 있습니다.
-
<number>
-
줌 배율로 사용되는 음이 아닌 수. 배율 1.0은 줌이 수행되지 않음을 뜻합니다. 1.0보다 큰 값은 확대 작은 값은 축소 효과가 됩니다.
-
<percentage>
-
줌 배율로 사용되는 음이 아닌 퍼센트 값. 배율 100%는 줌이 수행되지 않음을 뜻합니다. 100%보다 큰 값은 확대 작은 값은 축소 효과가 됩니다.
-
- -

형식 구문

- -
{{csssyntax}}
- -

명세

- - - - - - - - - - - - - - - - -
명세상태설명
{{SpecName('CSS3 Device', '#the-lsquozoomrsquo-descriptor', '"zoom" descriptor')}}{{Spec2('CSS3 Device')}}초기 스펙
- -

브라우저 호환성

- -

{{Compat("css.at-rules.viewport.zoom")}}

diff --git a/files/ko/web/css/adjacent_sibling_combinator/index.html b/files/ko/web/css/adjacent_sibling_combinator/index.html new file mode 100644 index 0000000000..4446172ab3 --- /dev/null +++ b/files/ko/web/css/adjacent_sibling_combinator/index.html @@ -0,0 +1,83 @@ +--- +title: 인접 형제 결합자 +slug: Web/CSS/인접_형제_선택자 +tags: + - CSS + - Reference + - Selectors +translation_of: Web/CSS/Adjacent_sibling_combinator +--- +
{{CSSRef("Selectors")}}
+ +

인접 형제 결합자(+)는 앞에서 지정한 요소의 바로 다음에 위치하는 형제 요소만 선택합니다.

+ +
/* Paragraphs that come immediately after any image */
+img + p {
+  font-weight: bold;
+}
+
+ +

구문

+ +
former_element + target_element { style properties }
+
+ +

예제

+ +

CSS

+ +
li:first-of-type + li {
+  color: red;
+}
+
+ +

HTML

+ +
<ul>
+  <li>One</li>
+  <li>Two!</li>
+  <li>Three</li>
+</ul>
+ +

결과

+ +

{{EmbedLiveSample("예제", "100%", 100)}}

+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('CSS4 Selectors', '#adjacent-sibling-combinators', 'next-sibling combinator')}}{{Spec2('CSS4 Selectors')}}
{{SpecName('CSS3 Selectors', '#adjacent-sibling-combinators', 'Adjacent sibling combinator')}}{{Spec2('CSS3 Selectors')}}
{{SpecName('CSS2.1', 'selector.html#adjacent-selectors', 'Adjacent sibling selectors')}}{{Spec2('CSS2.1')}}Initial definition
+ +

브라우저 호환성

+ +

{{Compat("css.selectors.adjacent_sibling")}}

+ +

같이 보기

+ + diff --git a/files/ko/web/css/all_about_the_containing_block/index.html b/files/ko/web/css/all_about_the_containing_block/index.html deleted file mode 100644 index 35c6bf56cb..0000000000 --- a/files/ko/web/css/all_about_the_containing_block/index.html +++ /dev/null @@ -1,263 +0,0 @@ ---- -title: 컨테이닝 블록의 모든 것 -slug: Web/CSS/All_About_The_Containing_Block -tags: - - CSS - - Guide - - Layout - - Position -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")}} 속성의 값과 절대적 위치(absolutefixed 등)로 설정된 요소의 오프셋 속성 값은 자신의 컨테이닝 블록으로부터 계산됩니다.

- -

컨테이닝 블록 식별

- -

컨테이닝 블록의 식별 과정은 {{cssxref("position")}} 속성에 따라 완전히 달라집니다.

- -
    -
  1. position 속성이 static, relative, sticky 중 하나이면, 컨테이닝 블록은 가장 가까운 조상 블록 컨테이너(inline-block, block, list-item 등의 요소), 또는 가장 가까우면서 서식 맥락을 형성하는 조상 요소(table, flex, grid, 아니면 블록 컨테이너 자기 자신)의 콘텐츠 영역 경계를 따라 형성됩니다.
  2. -
  3. position 속성이 absolute인 경우, 컨테이닝 블록은 position 속성 값이 static이 아닌(fixed, absolute, relative, sticky) 가장 가까운 조상의 내부 여백 영역입니다.
  4. -
  5. position 속성이 fixed인 경우, 컨테이닝 블록은 {{glossary("viewport", "뷰포트")}}나 페이지 영역(페이지로 나뉘는 매체인 경우)입니다.
  6. -
  7. position 속성이 absolutefixed인 경우, 다음 조건 중 하나를 만족하는 가장 가까운 조상의 내부 여백 영역이 컨테이닝 블록이 될 수도 있습니다. -
      -
    1. {{cssxref("transform")}}이나 {{cssxref("perspective")}} 속성이 none이 아님.
    2. -
    3. {{cssxref("will-change")}} 속성이 transform이나 perspective임.
    4. -
    5. {{cssxref("filter")}} 속성이 none임. (Firefox에선 will-changefilter일 때도 적용)
    6. -
    7. {{cssxref("contain")}} 속성이 paint임.
    8. -
    -
  8. -
- -
-

참고: 루트 요소({{HTMLElement("html")}})의 컨테이닝 블록은 초기 컨테이닝 블록이라고 불리는 사각형입니다. 초기 컨테이닝 블록은 뷰포트 또는 (페이지로 나뉘는 매체에선) 페이지 영역의 크기와 같습니다.

-
- -

컨테이닝 블록으로부터 백분율 값 계산하기

- -

앞서 언급했듯, 특정 속성의 값이 백분율이라면 그 계산값은 요소의 컨테이닝 블록에 의해 결정됩니다. 이렇게 동작하는 속성으로 박스 모델 속성오프셋 속성이 있습니다.

- -
    -
  1. {{cssxref("height")}}, {{cssxref("top")}}, {{cssxref("bottom")}} 속성은 컨테이닝 블록의 height를 사용해 백분율을 계산합니다. 컨테이닝 블록의 height가 콘텐츠의 크기에 따라 달라질 수 있고, 컨테이닝 블록의 positionrelative거나 static이면 계산값은 0이 됩니다.
  2. -
  3. {{cssxref("width")}}, {{cssxref("left")}}, {{cssxref("right")}}, {{cssxref("padding")}}, {{cssxref("margin")}} 속성은 컨테이닝 블록의 width를 사용해 백분율을 계산합니다.
  4. -
- -

예제

- -

모든 예제의 HTML코드는 다음과 같습니다.

- -
<body>
-  <section>
-    <p>문단입니다!</p>
-  </section>
-</body>
-
- -

이하 예제는 모두 CSS만 변경합니다.

- -

예제 1

- -

다음 예제에서 문단은 정적 위치를 가지고, 가장 가까운 블록 컨테이너는 {{HTMLElement("section")}}이므로 문단의 컨테이닝 블록도 <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('예제_1','100%','300')}}

- -

예제 2

- -

다음 예제에서 <section>display: inline으로 인해 블록 컨테이너가 아니고, 서식 문맥도 형성하지 않으므로 문단의 컨테이닝 블록은 {{HTMLElement("body")}} 요소입니다.

- - - -
body {
-  background: beige;
-}
-
-section {
-  display: inline;
-  background: lightgray;
-}
-
-p {
-  width: 50%;     /* == body 너비의 절반 */
-  height: 200px;  /* 참고: 백분율 값이었으면 0 */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('예제_2','100%','300')}}

- -

예제 3

- -

다음 예제에서는 <section>positionabsolute이기 때문에 문단의 컨테이닝 블록은 <section>입니다. 문단의 백분율 값은 컨테이닝 블록의 {{cssxref("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('예제_3','100%','300')}}

- -

예제 4

- -

다음 예제에서는 문단의 positionfixed이므로 컨테이닝 블록은 초기 컨테이닝 블록(화면 매체에서는 뷰포트)입니다. 따라서 문단의 크기는 브라우저 창의 크기에 따라 변합니다.

- - - -
body {
-  background: beige;
-}
-
-section {
-  width: 400px;
-  height: 480px;
-  margin: 30px;
-  padding: 15px;
-  background: lightgray;
-}
-
-p {
-  position: fixed;
-  width: 50%;   /* == (50vw - (세로 스크롤바 너비)) */
-  height: 50%;  /* == (50vh - (가로 스크롤바 높이)) */
-  margin: 5%;   /* == (5vw - (세로 스크롤바 너비)) */
-  padding: 5%;  /* == (5vw - (세로 스크롤바 너비)) */
-  background: cyan;
-}
-
- -

{{EmbedLiveSample('예제_4','100%','300')}}

- -

예제 5

- -

다음 예제에서는 문단의 positionabsolute이므로, 컨테이닝 블록은 {{cssxref("transform")}} 속성이 none이 아닌 가장 가까운 조상, <section>입니다.

- - - -
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('예제_5','100%','300')}}

- -

같이 보기

- - diff --git a/files/ko/web/css/common_css_questions/index.html b/files/ko/web/css/common_css_questions/index.html deleted file mode 100644 index 604448f6c3..0000000000 --- a/files/ko/web/css/common_css_questions/index.html +++ /dev/null @@ -1,199 +0,0 @@ ---- -title: 공통된 CSS 질문들 -slug: Web/CSS/Common_CSS_Questions -translation_of: Learn/CSS/Howto/CSS_FAQ ---- -

왜 유효한 내 CSS가 왜 올바르게 그려지지 않는가?

- -

Browsers use the DOCTYPE declaration to choose whether to show the document using a mode that is more compatible  with Web standards or with old browser bugs. Using a correct and modern DOCTYPE declaration at the start of your HTML will improve browser standards compliance.

- -

Modern browsers have two main rendering modes:

- - - -

Gecko-based browsers, have a third Almost Standards Mode that has only a few minor quirks.

- -

This is a list of the most commonly used DOCTYPE declarations that will trigger Standards or Almost Standards mode:

- -
<!DOCTYPE html> /* This is the HTML5 doctype. Given that each modern browser uses an HTML5
-                   parser, this is the recommended doctype */
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
-"http://www.w3.org/TR/html4/loose.dtd">
-
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
-"http://www.w3.org/TR/html4/strict.dtd">
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-
- -

왜 유효한 내 CSS는 모두 랜더링 되지 않는가?

- -

원인은 다음과 같다:

- - - -

id 와 css는 무엇이 다른가?

- -

HTML elements can have an id and/or class attribute. The id attribute assigns a name to the element it is applied to, and for valid markup, there can be only one element with that name. The class attribute assigns a class name to the element, and that name can be used on many elements within the page. CSS allows you to apply styles to particular id and/or class names.
-
- Use an id-specific style when you want to restrict the applied styling rules to one specific block or element. This style will only be used by the element with that particular id.
-
- Use a class-specific style when you want to apply the styling rules to many blocks and elements within the page.

- -

Stylesheets with fewer rules are usually more performant. It is therefore recommended to use classes as much as possible, and to reserve the use of id for specific uses (like to connect label and form elements or for styling elements that must be semantically unique).

- -

See CSS selectors

- -

 프로퍼티(property)에 기본값(default value)으로 복귀 시키는 방법은?

- -

 

- -

본래 CSS는 "default" 키워드를 제공하지 않으며 속성의 기본값을 복원하는 유일한 방법은 해당 속성을 명시 적으로 다시 선언하는 것이다.

- -
/* Heading default color is black */
-h1 { color: red; }
-h1 { color: black; }
- -

이것은 CSS 2에서 변경되었다. 키워드 initial은 이제 CSS 속성에서 유효한 값이다. 지정된 속성의 CSS 사양에 정의 된 기본값으로 재설정된다.

- -
/* Heading default color is black */
-h1 { color: red; }
-h1 { color: initial; }
- -

 

- -

어떻게 하면 한 스타일(style)로 부터 다른 스타일을 파생시킬 수 있는가?

- -

CSS는 한 스타일 안에서 다른 조건을 정의하는 것을 허용하지 않는다. (See Eric Meyer's note about the Working Group's stance).  그러나 여러개의 클래스(class)들을 한 엘리먼트(element)에 할당하면 같은 효과를 제공받을 수 있다.

- -

어떻게 하면 한 요소(element)에 여러 클래스(class)를 할당할 수 있는가?

- -

HTML elements can be assigned multiple classes by listing the classes in the class attribute, with a blank space to separate them.

- -
<style type="text/css">
-.news { background: black; color: white; }
-.today { font-weight: bold; }
-</style>
-
-<div class="news today">
-... content of today's news ...
-</div>
-
- -

If the same property is declared in both rules, the conflict is resolved first through specificity, then according to the order of the CSS declarations. The order of classes in the class attribute is not relevant.

- -

왜 내 스타일 룰(style rule)은 올바르게 동작하지 않는가?

- -

Style rules that are syntactically correct may not apply in certain situations. You can use DOM Inspector's CSS Style Rules view to debug problems of this kind, but the most frequent instances of ignored style rules are listed below.

- -

HTML 요소(element) 계층(hierarchy)

- -

The way CSS styles are applied to HTML elements depends also on the elements hierarchy. It is important to remember that a rule applied to a descendent overrides the style of the parent, in spite of any specificity or priority of CSS rules.

- -
.news { color: black; }
-.corpName { font-weight: bold; color: red; }
-
-<!-- news item text is black, but corporate name is red and in bold -->
-<div class="news">
-   (Reuters) <span class="corpName">General Electric</span> (GE.NYS) announced on Thursday...
-</div>
-
- -

In case of complex HTML hierarchies, if a rule seems to be ignored, check if the element is inside another element with a different style.

- -

명확한 스타일 룰 재정의

- -

CSS 스타일시트 안에서 순서가 중요하다. 만약 룰을 정의하고 같은 룰을 재정의 한다면 마지막 정의가 적용된다.

- -
#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>
-
- -

위와 같은 종류의 오류를 방지하려면 특정 선택자에 대해 규칙을 한 번만 정의하고 해당 선택자에 속하는 모든 규칙을 그룹화 하는 것이 좋다.

- -

프로퍼티(property) 축약형의 사용

- -

Using shorthand properties for defining style rules is good because it uses a very compact syntax. Using shorthand with only some attributes is possible and correct, but it must be remembered that undeclared attributes are automatically reset to default. This means that a previous rule for a single attribute could be implicitly overridden.

- -
#stockTicker { font-size: 12px; font-family: Verdana; font-weight: bold; }
-.stockSymbol { font: 14px Arial; color: red; }
-
-<div id="stockTicker">
-   NYS: <span class="stockSymbol">GE</span> +1.0 ...
-</div>
-
- -

In the previous example the problem occurred on rules belonging to different elements, but it could happen also for the same element, because rule order is important.

- -
#stockTicker {
-   font-weight: bold;
-   font: 12px Verdana;  /* font-weight is now normal */
-}
-
- -

* 셀렉터(selector)의 사용

- -

* 와일드카드 셀렉터는 모든 엘리먼트에 적용되고, 이것은 특별히 주의를 기울여 사용해야 한다.

- -
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-* and -khtml-* 프로퍼티(property)들이 하는 것은?

- -

These properties, called prefixed properties, are extensions to the CSS standard. They are used to use experimental and non-standard features without polluting the regular namespace, preventing future incompatibilities to arise when the standard is extended.

- -

The use of such properties on production websites is not recommended. If nevertheless needed, you are hinted to make a plan for the website evolution: these prefixed properties can be modified or even suppressed when the standard evolves.

- -

Please see the Mozilla CSS Extensions page for more information on the Mozilla-prefixed CSS properties.

- -

z-index는 어떻게 포지셔닝을 하는가?

- -

The z-index property specifies the stack order of elements.

- -

An element with a higher z-index/stack order is always in front of an element with a lower z-index/stack order.

- -

Z-index will only work on elements that have a specified position (position:absolute, position:relative, or position:fixed).

diff --git a/files/ko/web/css/containing_block/index.html b/files/ko/web/css/containing_block/index.html new file mode 100644 index 0000000000..35c6bf56cb --- /dev/null +++ b/files/ko/web/css/containing_block/index.html @@ -0,0 +1,263 @@ +--- +title: 컨테이닝 블록의 모든 것 +slug: Web/CSS/All_About_The_Containing_Block +tags: + - CSS + - Guide + - Layout + - Position +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")}} 속성의 값과 절대적 위치(absolutefixed 등)로 설정된 요소의 오프셋 속성 값은 자신의 컨테이닝 블록으로부터 계산됩니다.

+ +

컨테이닝 블록 식별

+ +

컨테이닝 블록의 식별 과정은 {{cssxref("position")}} 속성에 따라 완전히 달라집니다.

+ +
    +
  1. position 속성이 static, relative, sticky 중 하나이면, 컨테이닝 블록은 가장 가까운 조상 블록 컨테이너(inline-block, block, list-item 등의 요소), 또는 가장 가까우면서 서식 맥락을 형성하는 조상 요소(table, flex, grid, 아니면 블록 컨테이너 자기 자신)의 콘텐츠 영역 경계를 따라 형성됩니다.
  2. +
  3. position 속성이 absolute인 경우, 컨테이닝 블록은 position 속성 값이 static이 아닌(fixed, absolute, relative, sticky) 가장 가까운 조상의 내부 여백 영역입니다.
  4. +
  5. position 속성이 fixed인 경우, 컨테이닝 블록은 {{glossary("viewport", "뷰포트")}}나 페이지 영역(페이지로 나뉘는 매체인 경우)입니다.
  6. +
  7. position 속성이 absolutefixed인 경우, 다음 조건 중 하나를 만족하는 가장 가까운 조상의 내부 여백 영역이 컨테이닝 블록이 될 수도 있습니다. +
      +
    1. {{cssxref("transform")}}이나 {{cssxref("perspective")}} 속성이 none이 아님.
    2. +
    3. {{cssxref("will-change")}} 속성이 transform이나 perspective임.
    4. +
    5. {{cssxref("filter")}} 속성이 none임. (Firefox에선 will-changefilter일 때도 적용)
    6. +
    7. {{cssxref("contain")}} 속성이 paint임.
    8. +
    +
  8. +
+ +
+

참고: 루트 요소({{HTMLElement("html")}})의 컨테이닝 블록은 초기 컨테이닝 블록이라고 불리는 사각형입니다. 초기 컨테이닝 블록은 뷰포트 또는 (페이지로 나뉘는 매체에선) 페이지 영역의 크기와 같습니다.

+
+ +

컨테이닝 블록으로부터 백분율 값 계산하기

+ +

앞서 언급했듯, 특정 속성의 값이 백분율이라면 그 계산값은 요소의 컨테이닝 블록에 의해 결정됩니다. 이렇게 동작하는 속성으로 박스 모델 속성오프셋 속성이 있습니다.

+ +
    +
  1. {{cssxref("height")}}, {{cssxref("top")}}, {{cssxref("bottom")}} 속성은 컨테이닝 블록의 height를 사용해 백분율을 계산합니다. 컨테이닝 블록의 height가 콘텐츠의 크기에 따라 달라질 수 있고, 컨테이닝 블록의 positionrelative거나 static이면 계산값은 0이 됩니다.
  2. +
  3. {{cssxref("width")}}, {{cssxref("left")}}, {{cssxref("right")}}, {{cssxref("padding")}}, {{cssxref("margin")}} 속성은 컨테이닝 블록의 width를 사용해 백분율을 계산합니다.
  4. +
+ +

예제

+ +

모든 예제의 HTML코드는 다음과 같습니다.

+ +
<body>
+  <section>
+    <p>문단입니다!</p>
+  </section>
+</body>
+
+ +

이하 예제는 모두 CSS만 변경합니다.

+ +

예제 1

+ +

다음 예제에서 문단은 정적 위치를 가지고, 가장 가까운 블록 컨테이너는 {{HTMLElement("section")}}이므로 문단의 컨테이닝 블록도 <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('예제_1','100%','300')}}

+ +

예제 2

+ +

다음 예제에서 <section>display: inline으로 인해 블록 컨테이너가 아니고, 서식 문맥도 형성하지 않으므로 문단의 컨테이닝 블록은 {{HTMLElement("body")}} 요소입니다.

+ + + +
body {
+  background: beige;
+}
+
+section {
+  display: inline;
+  background: lightgray;
+}
+
+p {
+  width: 50%;     /* == body 너비의 절반 */
+  height: 200px;  /* 참고: 백분율 값이었으면 0 */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('예제_2','100%','300')}}

+ +

예제 3

+ +

다음 예제에서는 <section>positionabsolute이기 때문에 문단의 컨테이닝 블록은 <section>입니다. 문단의 백분율 값은 컨테이닝 블록의 {{cssxref("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('예제_3','100%','300')}}

+ +

예제 4

+ +

다음 예제에서는 문단의 positionfixed이므로 컨테이닝 블록은 초기 컨테이닝 블록(화면 매체에서는 뷰포트)입니다. 따라서 문단의 크기는 브라우저 창의 크기에 따라 변합니다.

+ + + +
body {
+  background: beige;
+}
+
+section {
+  width: 400px;
+  height: 480px;
+  margin: 30px;
+  padding: 15px;
+  background: lightgray;
+}
+
+p {
+  position: fixed;
+  width: 50%;   /* == (50vw - (세로 스크롤바 너비)) */
+  height: 50%;  /* == (50vh - (가로 스크롤바 높이)) */
+  margin: 5%;   /* == (5vw - (세로 스크롤바 너비)) */
+  padding: 5%;  /* == (5vw - (세로 스크롤바 너비)) */
+  background: cyan;
+}
+
+ +

{{EmbedLiveSample('예제_4','100%','300')}}

+ +

예제 5

+ +

다음 예제에서는 문단의 positionabsolute이므로, 컨테이닝 블록은 {{cssxref("transform")}} 속성이 none이 아닌 가장 가까운 조상, <section>입니다.

+ + + +
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('예제_5','100%','300')}}

+ +

같이 보기

+ + diff --git a/files/ko/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html b/files/ko/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html deleted file mode 100644 index 69d4320e3c..0000000000 --- a/files/ko/web/css/css_background_and_borders/using_css_multiple_backgrounds/index.html +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: 여러개의 배경 지정하기 -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를 사용하면 엘리먼트에 여러개의 배경을 지정할 수 있다. 첫 번째로 지정한 배경이 가장 앞에 보이고 나중에 지정한 배경이 뒤에 보인다. 배경 색상({{ cssxref("color") }})는 맨 마지막에만 지정할 수 있다. 

- -

여러개의 배경을 지정하는건 간단하다.

- -
.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;
-}
-
- - - - - - - - - - -
Result
css_multibg.png
- -

첫 번째 배경으로 지정한(리스트에서 첫번째) 파이어폭스 로고가 맨 위에 보이고 선형 그라디언트, 꽃이 그려진 사진 순서대로 보인다. {{ cssxref("background-repeat") }} 와 {{ cssxref("background-position") }}) 속성들도 리스트 형태로 지정되었는데 순서대로 해당하는 배경에 적용된다. 예를 들어 {{ cssxref("background-repeat") }} 속성 중 첫 번째 no-repeat는 첫 번째 배경인 파이어폭스 로고에 적용된다.

- -

더 보기

- - diff --git a/files/ko/web/css/css_backgrounds_and_borders/resizing_background_images/index.html b/files/ko/web/css/css_backgrounds_and_borders/resizing_background_images/index.html new file mode 100644 index 0000000000..f3f0d6529b --- /dev/null +++ b/files/ko/web/css/css_backgrounds_and_borders/resizing_background_images/index.html @@ -0,0 +1,137 @@ +--- +title: 배경 이미지 크기 조정하기 +slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images +tags: + - CSS + - CSS Background + - Example + - Guide + - Intermediate + - Reference + - Web +translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images +--- +
{{cssref}}
+ +

CSS 배경 이미지의 기본 설정값에서는 원본 이미지가 크기 변화 없이 바둑판식으로 배열됩니다. {{cssxref("background-size")}} 속성에 가로와 세로 크기를 지정해 크기를 바꿀 수 있습니다. 이미지는 원하는대로 확대할 수도, 줄일 수도 있습니다.

+ +

큰 이미지 바둑판식 배열

+ +

2982x2808의 커다란 Firefox 이미지를 가지고 있다고 해보겠습니다. 모종의 이유(끔찍하게 잘못된 사이트 디자인 등)로 300x300 픽셀 요소에 저 이미지 4개를 바둑판식으로 보여야 합니다. background-size와 고정값 150 픽셀로 목표를 달성할 수 있습니다.

+ +

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("큰_이미지_바둑판식_배열", 340, 340)}}

+ +

이미지 늘리기

+ +

가로와 세로 크기를 각각 지정할 수도 있습니다.

+ +
background-size: 300px 150px;
+
+ +

결과는 다음과 같습니다.

+ +

+ +

작은 이미지 키우기

+ +

반대로 배경 이미지를 키울 수도 있습니다. 다음 코드는 32x32 픽셀 파비콘을 300x300 픽셀로 늘린 결과입니다.

+ +

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

보시다시피 CSS는 이미지 파일 이름을 제외하면 동일합니다.

+ +

특별한 값: "contain" 과 "cover"

+ +

길이를 나타내는 {{cssxref("<length>")}} 값 대신, {{ cssxref("background-size") }} CSS 속성에 contain 과 cover 두개의 특별한 값을 지정할 수 있습니다. 살펴봅시다.

+ +

contain

+ +

contain 값을 지정하면, 배경 이미지의 가로, 세로 모두 요소보다 작다는 조건하에 가능한 크게 조정됩니다. 이미지의 가로, 세로 비율은 유지됩니다. 따라서 배경 이미지의 크기는 요소의 크기보다 항상 작거나 같습니다. 아래 예제의 크기를 조절해서 실제로 어떻게 동작하는지 확인해보세요.

+ +

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

결과

+ +

{{ EmbedLiveSample('contain', 250, 250) }}

+ +

cover

+ +

값을 cover 로 지정하면 배경이미지의 가로, 세로 길이 모두 요소보다 크다는 조건하에 가능한 배경 이미지를 작게 조정합니다. 가로, 세로 비율은 유지됩니다. 따라서 배경 이미지의 크기는 요소의 크기보다 항상 크거나 같습니다. 아래 예제의 크기를 조절해서 실제로 어떻게 동작하는지 확인해보세요.

+ +

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

결과

+ +

{{ EmbedLiveSample('cover', 250, 250) }}

+ +

같이 보기

+ + diff --git a/files/ko/web/css/css_backgrounds_and_borders/scaling_background_images/index.html b/files/ko/web/css/css_backgrounds_and_borders/scaling_background_images/index.html deleted file mode 100644 index f3f0d6529b..0000000000 --- a/files/ko/web/css/css_backgrounds_and_borders/scaling_background_images/index.html +++ /dev/null @@ -1,137 +0,0 @@ ---- -title: 배경 이미지 크기 조정하기 -slug: Web/CSS/CSS_Backgrounds_and_Borders/Scaling_background_images -tags: - - CSS - - CSS Background - - Example - - Guide - - Intermediate - - Reference - - Web -translation_of: Web/CSS/CSS_Backgrounds_and_Borders/Resizing_background_images ---- -
{{cssref}}
- -

CSS 배경 이미지의 기본 설정값에서는 원본 이미지가 크기 변화 없이 바둑판식으로 배열됩니다. {{cssxref("background-size")}} 속성에 가로와 세로 크기를 지정해 크기를 바꿀 수 있습니다. 이미지는 원하는대로 확대할 수도, 줄일 수도 있습니다.

- -

큰 이미지 바둑판식 배열

- -

2982x2808의 커다란 Firefox 이미지를 가지고 있다고 해보겠습니다. 모종의 이유(끔찍하게 잘못된 사이트 디자인 등)로 300x300 픽셀 요소에 저 이미지 4개를 바둑판식으로 보여야 합니다. background-size와 고정값 150 픽셀로 목표를 달성할 수 있습니다.

- -

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("큰_이미지_바둑판식_배열", 340, 340)}}

- -

이미지 늘리기

- -

가로와 세로 크기를 각각 지정할 수도 있습니다.

- -
background-size: 300px 150px;
-
- -

결과는 다음과 같습니다.

- -

- -

작은 이미지 키우기

- -

반대로 배경 이미지를 키울 수도 있습니다. 다음 코드는 32x32 픽셀 파비콘을 300x300 픽셀로 늘린 결과입니다.

- -

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

보시다시피 CSS는 이미지 파일 이름을 제외하면 동일합니다.

- -

특별한 값: "contain" 과 "cover"

- -

길이를 나타내는 {{cssxref("<length>")}} 값 대신, {{ cssxref("background-size") }} CSS 속성에 contain 과 cover 두개의 특별한 값을 지정할 수 있습니다. 살펴봅시다.

- -

contain

- -

contain 값을 지정하면, 배경 이미지의 가로, 세로 모두 요소보다 작다는 조건하에 가능한 크게 조정됩니다. 이미지의 가로, 세로 비율은 유지됩니다. 따라서 배경 이미지의 크기는 요소의 크기보다 항상 작거나 같습니다. 아래 예제의 크기를 조절해서 실제로 어떻게 동작하는지 확인해보세요.

- -

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;
-}
- -

결과

- -

{{ EmbedLiveSample('contain', 250, 250) }}

- -

cover

- -

값을 cover 로 지정하면 배경이미지의 가로, 세로 길이 모두 요소보다 크다는 조건하에 가능한 배경 이미지를 작게 조정합니다. 가로, 세로 비율은 유지됩니다. 따라서 배경 이미지의 크기는 요소의 크기보다 항상 크거나 같습니다. 아래 예제의 크기를 조절해서 실제로 어떻게 동작하는지 확인해보세요.

- -

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;
-}
- -

결과

- -

{{ EmbedLiveSample('cover', 250, 250) }}

- -

같이 보기

- - diff --git a/files/ko/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html b/files/ko/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html new file mode 100644 index 0000000000..416718c17f --- /dev/null +++ b/files/ko/web/css/css_basic_user_interface/using_url_values_for_the_cursor_property/index.html @@ -0,0 +1,70 @@ +--- +title: cursor 속성값에 URL 사용 +slug: Web/CSS/cursor/Using_URL_values_for_the_cursor_property +tags: + - CSS + - CSS_2.1 + - Cross-browser_Development + - Web Development +translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property +--- +

Gecko 1.8 (Firefox 1.5, SeaMonkey 1.0)은 URL 값을 CSS2 커서 속성값으로 사용하는 것을 지원합니다. 이 기능은 마우스 커서 모양으로 임의의 이미지 를 지정할 수 있게 해줍니다 — Gecko가 지원하는 모든 이미지 포맷을 사용할 수 있습니다.

+ +

문법

+ +

이 속성의 문법은 다음과 같습니다:

+ +
cursor: [<url>,]* keyword;
+
+ +

즉, URL을 지정하지 않거나 혹은 다수의 콤마로 분리된 URL값들을 지정할 수 있으며, 이 값들 뒤엔 반드시 CSS규정에 정의된 autopointer같은 키워드들이 따라와야 합니다.

+ +

예를 들면, 다음과 같은 값이 지정될 수 있습니다:

+ +
cursor: url(foo.cur), url(http://www.example.com/bar.gif), auto;
+
+ +

우선 foo.cur의 로딩이 시도 되고, 만약 이 파일이 없거나 어떤 다른 이유로 파일이 부적합할 경우, bar.gif를 로드하게 되고 이것 마저 사용할 수 없게 되면, auto가 사용될 것입니다.

+ +

커서 값에 대한 CSS3 syntax 지원은 Gecko 1.8beta3에 부가되었으며, 따라서 Firefox 1.5에서 사용할 수 있습니다. 이 기능은 커서 이미지의 바운더리에 부착시킬 커서의 핫스팟의 좌표를 지정할 수 있게 해줍니다. 만일 아무것도 지정되지 않을 경우, 핫스팟의 좌표는 이미지 파일 자체에서 (CUR 와 XBN 파일의 경우) 읽어 들이거나 이미지의 좌측 상단 코너로 지정됩니다. CSS3 문법의 예문은 다음과 같습니다:

+ +
cursor: url(foo.png) 4 12, auto;
+
+ +

첫번째 숫자는 x좌표이며, 두번째 숫자는 y좌표입니다. 이 예문은 이미지의 왼쪽 위 (0,0)로부터 (4, 12)의 위치의 픽셀을 핫스팟으로 지정할 것입니다.

+ +

제약 사항

+ +

Gecko가 지원하는 모든 이미지 포팻이 사용가능합니다. 즉, BMP, JPG, CUR, GIF 등의 이미지를 사용할 수 있습니다. 그러나, ANI는 지원되지 않습니다. animated GIF 이미지로 지정해도, 커서는 animated 커서가 되지는 않을 것입니다. 이런 문제점은 향후 릴리즈에서 제거될 것입니다.

+ +

Gecko는 커서의 크기에 관해서 어떤 제약을 두고 있지는 않습니다만, 다른 운영체제나 플랫폼들과의 최대의 호환성을 유지하기 위해 커서 크기를 32x32로 제한할것을 권장합니다. 특히, 이보다 큰 커서는 윈도우 9x (95, 98, ME) 에서 작동하지 않을 것입니다.

+ +

투명 커서는 XP보다 이전 윈도우 릴리즈에서는 지원되지 않으며, 이는 운영체제의 제약사항입니다. 투명기능은 모든 플랫폼에서 작동합니다.

+ +

모질라의 윈도우, OS/2 그리고 리눅스(GTK+ 2.4 나 그 이후 버전 사용) 릴리즈에서만 커서로 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) }})

+ +

다른 브라우저들과의 호환성

+ +

마이크로소프트 인터넷 익스플로러(MSIE)도 cursor속성으로 URL 값을 지원합니다. 그러나, CUR 과 ANI 포맷만을 지원합니다.

+ +

cursor속성 문법도 또한 제약이 덜한 관계로

+ +
cursor: url(foo.cur);
+
+ +

이나

+ +
cursor: url(foo.cur), pointer, url(bar.cur), auto;
+
+ +

와 같은 값도 MSIE에선 작동할 것입니다. 그러나 이런 값은 Gecko에선 작동하지 않을 것입니다. Gecko와의 호환성을 위해서 또 CSS규약에 따라, 항상 URL 리스트를 먼저 나열하시고, 정확히 하나의 키워드 값을 그 뒤에 사용하십시오.

+ +

To-do

+ +
+
To-do: document what MSIE does with CSS 3 hotspot locations
+
+ +

Interwiki Language Links

+ +

{{ languages( { "ja": "ja/Using_URL_values_for_the_cursor_property" } ) }}

diff --git a/files/ko/web/css/css_columns/using_multi-column_layouts/index.html b/files/ko/web/css/css_columns/using_multi-column_layouts/index.html new file mode 100644 index 0000000000..47d363969c --- /dev/null +++ b/files/ko/web/css/css_columns/using_multi-column_layouts/index.html @@ -0,0 +1,204 @@ +--- +title: CSS 다단 레이아웃 사용 +slug: CSS3_Columns +tags: + - Advanced + - CSS + - Guide + - Multi-columns +translation_of: Web/CSS/CSS_Columns/Using_multi-column_layouts +--- +

{{CSSRef("CSS Multi-columns")}}

+ +

CSS 다단(multi-column) 레이아웃은 다단 텍스트 정의가 쉽도록 블록 레이아웃 모드를 확장합니다. 사람들은 줄이 너무 긴 경우 텍스트 읽는데 어려움이 있습니다; 한 줄 끝에서 다음 줄 시작까지 눈에 옮기기 너무 긴 경우, 어느 줄을 읽고 있었는 지를 잊어버립니다. 그러므로, 큰 화면을 최대로 쓰기 위해서는, 너비가 제한된 텍스트 단을 나란히 놓아야 합니다, 바로 신문이 하는 것처럼.

+ +

불행하게도 이는 CSS 및 HTML로 하기는 고정 위치에서 강제 단 바꿈 또는 텍스트에 허용되는 마크업의 심한 제한 혹은 위대한(heroic) 스크립팅 사용 없이는 불가능합니다. 이 제한은 전통 블록 레이아웃 모드를 확장하는 새로운 CSS 속성 추가로 해결됐습니다.

+ +

단 사용

+ +

단 수와 너비

+ +

두 CSS 속성은 많은 단을 보일 지 여부와 방법을 제어합니다: {{ Cssxref("column-count") }} 및 {{ Cssxref("column-width") }}.

+ +

column-count 속성은 단 수를 특정한 수로 설정합니다. 가령,

+ +

예 1

+ +

HTML

+ +
+
<div id="col">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>
+
+ +

CSS

+ +
#col {
+-moz-column-count: 2;
+-webkit-column-count: 2;
+column-count: 2;
+}
+
+
+ +

결과

+ +

두 단에 콘텐츠를 표시합니다 (다단 준수 브라우저를 사용 중인 경우):

+ +

{{EmbedLiveSample('column_count','700px', '', '')}}

+ +

column-width 속성은 희망 최소 단 너비를 설정합니다. column-count도 설정되지 않은 경우, 그러면 브라우저는 자동으로 이용 가능한 너비에 맞게 많은 단을 만듭니다.

+ +

예 2

+ +

HTML

+ +
+
<div id="wid">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>
+
+ +

CSS

+ +
#wid {
+-moz-column-width: 100px;
+-webkit-column-width: 100px;
+column-width: 100px;
+}
+
+
+ +

결과

+ +

{{ EmbedLiveSample('column_width','700px', '', '') }}

+ +

정확한 세부사항은 CSS3 스펙에 설명되어 있습니다.

+ +

다단 블록에서, 콘텐츠는 필요에 따라 한 단에서 다음 단으로 자동으로 흐릅니다. 모든 HTML, CSS 및 DOM 기능은 단 내에서 지원됩니다, 편집 및 인쇄 중일 때.

+ +

columns 단축

+ +

대부분, 웹 디자이너는 두 CSS 속성({{ cssxref("column-count") }} 또는 {{ cssxref("column-width") }}) 중 하나를 사용합니다. 이러한 속성에 대한 값이 겹치지 않기에, 종종 {{ cssxref("columns") }} 단축을 쓰는 게 편리합니다. 가령.

+ +

column-width:12em CSS 선언은 다음으로 대체될 수 있습니다:

+ +

예 3

+ +

HTML

+ +
+
<div id="col_short">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>
+
+ +

CSS

+ +
#col_short {
+-moz-column-width: 12em;
+-moz-columns: 12em;
+-webkit-columns: 12em;
+columns: 12em;
+}
+
+
+ +

결과

+ +

{{EmbedLiveSample('column_short','700px', '', '')}}

+ +

column-count:4 CSS 선언은 다음으로 대체될 수 있습니다:

+ +

예 4

+ +

HTML

+ +
+
<div id="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>
+
+ +

CSS

+ +
#columns_4{
+-moz-column-count: 4;
+-moz-columns: 4;
+-webkit-columns: 4;
+columns: 4;
+}
+
+
+ +

결과

+ +

{{ EmbedLiveSample('four_columns','700px', '', '') }}

+ +

column-width:8emcolumn-count:12 두 CSS 선언은 다음으로 대체될 수 있습니다:

+ +

예 5

+ +

HTML

+ +
+
<div id="columns_12">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>
+
+ +

CSS

+ +
#columns_12 {
+-moz-columns: 12 8em;
+-webkit-columns: 12 8em;
+columns: 12 8em;
+}
+
+
+ +

결과

+ +

{{ EmbedLiveSample('twelve_columns','700px', '', '') }}

+ +

높이 균형

+ +

CSS3 Column 스펙은 단 높이는 균형을 이루어야 함을 요구합니다: 즉, 브라우저는 각 단의 콘텐츠 높이가 거의 같도록 자동으로 최대 단 높이를 설정합니다. Firefox는 이를 행합니다.

+ +

그러나, 일부 상황에서는 최대 단 높이를 명시해서 설정하는 것도 유용하고 그 다음 첫 단에서 시작하여 필요한 만큼 많은 단을 생성하며, 어쩌면 오른쪽으로 넘치는 콘텐츠를 배치합니다. 따라서, 높이가 제한되는 경우, 다단 블록에 CSS {{ cssxref("height") }} 또는 {{ cssxref("max-height") }} 속성을 설정하여, 각 단은 그 높이 및 더 이상 새로운 단을 추가하기 전까지 늘 수 있습니다. 이 모드 역시 레이아웃에 대해서 훨씬 더 효율이 좋습니다.

+ +

단 간격

+ +

단 사이 간격이 있습니다. 기본 권장값은 1em입니다. 이 크기는 {{ Cssxref("column-gap") }} 속성을 다단 블록에 적용하여 바꿀 수 있습니다:

+ +

예 6

+ +

HTML

+ +
+
<div id="column_gap">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>
+
+ +

CSS

+ +
#column_gap {
+-webkit-column-count: 5;
+-moz-column-count: 5;
+column-count: 5;
+-moz-column-gap: 2em;
+-webkit-column-gap: 2em;
+column-gap: 2em;
+}
+
+
+ +

결과

+ +

{{ EmbedLiveSample('col_gap','700px', '', '') }}

+ +

우아한 강등

+ +

단 속성은 단을 지원하지 않는 브라우저에 의해 그냥 무시됩니다. 따라서 비지원 브라우저에서는 1단으로 표시하고 지원하는 브라우저에서는 다단을 사용하는 레이아웃을 만드는 게 그런 대로 쉽습니다.

+ +

모든 브라우저가 이러한 접두어 없는 속성을 지원하는 것은 아님을 주의하세요. 오늘날 대부분의 브라우저에서 이 기능을 사용하기 위해서, 각 속성은 세 번({{ property_prefix("-moz") }} 접두어로 한 번, {{ property_prefix("-webkit") }} 접두어로 한 번 그리고 접두어 없이 한 번) 작성되어야 합니다.

+ +

결론

+ +

CSS3 단(column)은 웹 개발자가 화면 영역(real estate)을 최대한 쓸 수 있게 돕는 원시(primitive) 레이아웃입니다. 상상력이 풍부한 개발자는 많은 단 사용법을 찾을 지도 모릅니다, 특히 자동 높이 균형 기능 가지고.

+ +

참조

+ + diff --git a/files/ko/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html b/files/ko/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html new file mode 100644 index 0000000000..1966114608 --- /dev/null +++ b/files/ko/web/css/css_flexible_box_layout/basic_concepts_of_flexbox/index.html @@ -0,0 +1,236 @@ +--- +title: flexbox의 기본 개념 +slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox의_기본_개념 +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox +--- +
{{CSSRef}}
+ +

일명 flexbox라 불리는 Flexible Box module은 flexbox 인터페이스 내의 아이템 간 공간 배분과 강력한 정렬 기능을 제공하기 위한 1차원 레이아웃 모델 로 설계되었습니다. 이 글에서는 flexbox의 주요 기능에 대한 개요를 다룹니다. 더 자세한 내용은 가이드의 다른 글에서 탐구하게 될 것입니다.

+ +

flexbox를 1차원이라 칭하는 것은, 레이아웃을 다룰 때 한 번에 하나의 차원(행이나 열)만을 다룬다는 뜻입니다. 이는 행과 열을 함께 조절하는 CSS 그리드 레이아웃의 2차원 모델과는 대조됩니다.

+ +

flexbox의 두 개의 축

+ +

flexbox를 다루려면 주축과 교차축이라는 두 개의 축에 대한 정의를 알아야 합니다. 주축은 {{cssxref("flex-direction")}} 속성을 사용하여 지정하며 교차축은 이에 수직인 축으로 결정됩니다. flexbox의 동작은 결국 이 두 개의 축에 대한 문제로 환원되기 때문에 이들이 어떻게 동작하는지 처음부터 이해하는 것이 중요합니다.

+ +

주축

+ +

주축은 flex-direction에 의해 정의되며 4개의 값을 가질 수 있습니다:

+ + + +

row 혹은 row-reverse를 선택하면 주축은 인라인 방향으로 행을 따릅니다.

+ +

If flex-direction is set to row the main axis runs along the row in the inline direction.

+ +

column 혹은 column-reverse 을 선택하면 주축은 페이지 상단에서 하단으로 블록 방향을 따릅니다.

+ +

If flex-direction is set to column the main axis runs in the block direction.

+ +

교차축

+ +

교차축은 주축에 수직하므로, 만약 flex-direction(주축)이 row 나 row-reverse 라면 교차축은 열 방향을 따릅니다.

+ +

If flex-direction is set to row then the cross axis runs in the block direction.

+ +

주축이 column 혹은 column-reverse 라면 교차축은 행 방향을 따릅니다.

+ +

If flex-direction is set to column then the cross axis runs in the inline direction.

+ +

flex 요소를 정렬하고 끝을 맞추(justify)려면 어느 축이 어느 방향인지 이해하는 것이 중요합니다; flexbox는 주축, 교차축을 따라 항목을 정렬하고 끝을 맞추는 각종 속성들을 적용하는 방식으로 동작합니다.

+ +

시작선과 끝선

+ +

flexbox가 쓰기 방법(writing mode)을 가정하지 않는다는 것은 상당히 중요합니다. 과거의 CSS는 왼쪽에서 오른쪽으로 향하는 가로 방향의 쓰기 방법에 치우쳐 있었습니다. 하지만 현대의 레이아웃은 다양한 쓰기 방법을 포괄해야 하므로, 더이상 텍스트가 문서의 왼쪽 상단에서 시작해서 오른쪽으로 향한다고 가정하지 않습니다. 새 라인이 항상 아래에 쌓인다고 가정하지도 않습니다.

+ +

다른 글에서 flexbox와 쓰기 방법 명세(writing mode spec.)가 어떤 관련이 있는지 알아볼 수 있습니다. 그 전에, 이 글에서 flex 요소의 정렬 방향에 "왼쪽, 오른쪽, 위, 아래"를  사용하지 않는 이유를 알 수 있었으면 합니다.

+ +

flex-direction이 row고 영어 문장을 문서에 쓰고 있다면, 주축의 시작선은 왼쪽 끝, 끝선은 오른쪽 끝이 될 것입니다.

+ +

Working in English the start edge is on the left.

+ +

아랍어 문장을 쓰고 있다면, 주축의 시작선은 오른쪽 끝, 끝 선은 왼쪽 끝이 될 것입니다.

+ +

The start edge in a RTL language is on the right.

+ +

영어와 아랍어는 모두 가로 쓰기를 채택하고 있으므로 두 예시에서 교차축의 시작선은 flex 컨테이너의 위 끝이며 끝선은 아래 끝입니다.

+ +

조금만 지나면 왼쪽-오른쪽으로 생각하는 것보다 시작선-끝선으로 생각하는 것이 금새 자연스러워질 것입니다. 동일한 패턴을 따르는 CSS 그리드 레이아웃 같은 방법을 다룰 때도 쉽게 적응할 수 있을 것입니다.

+ +

flex 컨테이너

+ +

문서의 영역 중에서 flexbox가 놓여있는 영역을 flex 컨테이너라고 부릅니다. flex 컨테이너를 생성하려면 영역 내의 컨테이너 요소의 {{cssxref("display")}} 값을 flex 혹은 inline-flex로 지정합니다. 이 값이 지정된 컨테이너의 일차 자식(direct children) 요소가 flex 항목이 됩니다. display 속성만 지정하여 flex 컨테이너를 생성하면 다른 flex 관련 속성들은 아래처럼 기본 값이 지정됩니다.

+ + + +

이렇게되면 flex 항목들은 각 항목 별 내부 요소의 크기로 주축을 따라 정렬됩니다. 컨테이너의 크기보다 더 많은 항목이 있을 경우 행을 바꾸지 않고 주축 방향으로 흘러 넘치게 됩니다. 어떤 항목이 다른 항목보다 높이 값이 크다면 나머지 모든 항목들은 그에 맞게 교차축을 따라 늘어나게 됩니다.

+ +

다음의 라이브 예시를 통해 어떻게 보여지는지 확인할 수 있습니다. flexbox의 초기 동작을 시험해보려면 항목을 추가하거나 수정해보시기 바랍니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/basics/the-flex-container.html", '100%', 480)}} 

+ +

flex-direction 지정

+ +

flex 컨테이너에 {{cssxref("flex-direction")}} 속성을 지정하면 flex 항목이 나열되는 방향을 변경할 수 있습니다. flex-direction: row-reverse 라고 지정하면 행으로 나열되는 것은 그대로지만 시작 선과 끝 선이 서로 바뀌게 됩니다.

+ +

flex-direction을 column으로 지정하면 주축이 변경되고 항목들은 열로 나열됩니다. column-reverse로 지정하면 그에 더해 시작 선과 끝 선이 서로 바뀌게 됩니다.

+ +

다음의 라이브 예시는 flex-direction이 row-reverse로 지정되어 있습니다. row, columncolumn-reverse와 같은 값을 지정해서 어떻게 되는지 확인해보시기 바랍니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-direction.html", '100%', 350)}}

+ +

flex-wrap을 이용한 복수 행 flex 컨테이너 지정

+ +

flexbox는 1차원 모델이지만 flex 항목이 여러 행에 나열되도록 할 수 있습니다. 그 경우 각 행이 새로운 flex 컨테이너라고 생각해야 합니다. 공간 배분은 해당 행에서만 이루어지며 다른 행은 영향을 받지 않습니다.

+ +

항목이 여러 행에 나열되도록 하려면 {{cssxref("flex-wrap")}} 속성의 값을 wrap으로 지정합니다. 그러면 항목이 하나의 행에 들어가지 않을 정도로 클 경우 다른 행에 배치됩니다. 아래의 라이브 예시에 있는 flex 항목은 폭이 지정되어 있으며 항목들의 폭의 합은 flex 컨테이너에 들어가기에는 너무 넓습니다. flex-wrap속성이 wrap으로 지정되어 있으므로 항목은 여러 행에 나열됩니다. 초깃값과 동일한 nowrap을 지정하고 flex항목에 대한 확대/축소 방식을 별도로 지정하지 않으면 flex 항목들은 컨테이너의 폭에 맞게 줄어듭니다.  nowrap을 지정하면 항목이 전혀 줄어들 수 없거나 충분히 줄어들 수 없을 때 흘러넘치게 됩니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-wrap.html", '100%', 400)}}

+ +

Mastering Wrapping of Flex Items 가이드에서 더 자세한 내용을 확인할 수 있습니다.

+ +

축약형 속성 flex-flow

+ +

flex-direction 속성과 flex-wrap 속성을 {{cssxref("flex-flow")}}라는 축약 속성으로 합칠 수 있습니다. 첫 번째 값은 flex-direction이고 두 번째 값은 flex-wrap입니다.

+ +

다음의 라이브 예시에서 첫 번째 값을 flex-direction에 지정 가능한 값들(row, row-reverse, column or column-reverse)로 바꿔보시기 바랍니다. 두 번째 값도 wrap이나 nowrap으로 바꿔보시기 바랍니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-flow.html", '100%', 400)}}

+ +

flex 항목에 지정 가능한 속성들

+ +

flex 항목에 적용할 수 있는 속성은 다음과 같습니다.

+ + + +

이 글에서는 위의 속성들에 대해 간략하게 살펴보겠습니다. 자세한 내용은 Controlling Ratios of Flex Items on the Main Axis에서 다룹니다.

+ +

500 픽셀의 크기를 갖는 flex 컨테이너 내에 100 픽셀 크기의 자식 세 개가 존재할 때, 사용가능한 공간 200 픽셀이 남게 됩니다. 기본적으로 flexbox는 이 공간을 마지막 자식 요소 다음에 빈공간으로 남겨둡니다.

+ +

This flex container has available space after laying out the items.

+ +

위의 세 가지 속성을 변경한다는 것은 flex 항목에게 사용가능한 공간을 분배하는 방식을 변경하는 것입니다. 사용가능한 공간 개념은 flex 항목을 정렬할 때 특히 중요합니다.

+ +

flex-basis 속성

+ +

flex-basis 속성은 항목의 크기를 결정합니다. 이 속성의 기본값은 auto이며, 이 경우 브라우저는 항목이 크기를 갖는지 확인합니다. 위의 사진 예시의 경우 항목의 크기가 100 픽셀이므로 flex-basis의 값으로 100 픽셀이 사용됩니다.

+ +

flex 항목에 크기가 지정되어 있지 않으면, flex 항목의 내용물 크기가 flex-basis 값으로 사용됩니다. 따라서 flex 컨테이너에서 display: flex 속성만을 지정하면 flex항목들이 각 내용물 크기만큼 공간을 차지하게 됩니다.

+ +

flex-grow 속성

+ +

flex-grow값을 양수로 지정하면 flex 항목별로 주축 방향 크기가 flex-basis 값 이상으로 늘어날 수 있게 됩니다. 위의 사진 예시에서 모든 항목의 flex-grow 값을 1로 지정하면 사용가능한 공간은 각 항목에게 동일하게 분배되며, 각 항목은 주축을 따라 분배받은 값만큼 사이즈를 늘려 공간을 차지합니다.

+ +

첫 항목의 flex-grow 값을 2로 지정하고 나머지 두 개의 항목을 1로 지정한다면 각 항목에 지정된 flex-grow 값의 비율에 따라 남은 공간이 분배됩니다. 각 항목의 flex-grow 비율이 2:1:1 이므로 첫 항목에게 100 픽셀, 두 번째와 세 번째 항목에게 50 픽셀씩 분배됩니다.

+ +

flex-shrink 속성

+ +

flex-grow 속성이 주축에서 남는 공간을 항목들에게 분배하는 방법을 결정한다면 flex-shrink 속성은 주축의 공간이 부족할때 각 항목의 사이즈를 줄이는 방법을 정의합니다. 만약 flex 컨테이너flex 항목을 모두 포함할 만큼 넉넉한 공간을 갖고 있지 않고 flex-shrink 값이 양수이면 flex 항목은 flex-basis에 지정된 크기보다 작아집니다. 또한, flex-grow 속성과 마찬가지로 더 큰 flex-shrink 값을 갖는 항목의 사이즈가 더 빨리 줄어듭니다.

+ +

항목의 최소 크기는 실제 축소량을 계산할 때 고려되기 때문에 flex-shrink 속성이 flex-grow 속성에 비해 덜 일관된 모습을 보여줄지도 모릅니다. flex-shrink 속성이 항목의 사이즈를 결정하는 알고리즘에 관해서는 Controlling Ratios of Flex Items on the Main Axis에서 자세히 살펴히보겠습니다.

+ +
+

flex-grow 와 flex-shrink의 값이 비율임을 유의하세요.  flex 항목의 flex 속성을 모두 1 1 200px 로 지정하고 한 항목만 크기가 늘어나는 비율을 타 항목의 두배로 하고 싶으면 해당 flex 항목의 flex 속성을 2 1 200px로 지정하면 되지만, flex 속성 값을 모두  10 1 200px로 지정하고 늘어나는 비율을 두 배로 하고 싶은 항목의 flex 속성 값만 20 1 200px로 지정해도 동일하게 동작합니다.

+
+ +

축약형 속성 flex

+ +

보통은 flex-grow, flex-shrinkflex-basis  값을 각각 사용하지 않고 이 세 속성을 한번에 지정하는 {{cssxref("flex")}} 축약형을 많이 사용합니다. flex 축약형의 값은 flex-grow, flex-shrink, flex-basis 순서로 지정됩니다.

+ +

다음의 라이브 예시에서 flex 축약형의 값들을 조절하면서 시험해 볼 수 있습니다. 첫 값이 flex-grow를 지정하며,  이 첫 값을 양수로 하면 flex 항목이 넓어질 수 있습니다. 두 번째 값은 flex-shrink 를 지정하며 이 두 번째 값에 양수를 지정하면 flex 항목이 좁아질 수 있습니다. 세 번째 값은 flex-basis를 지정하며 이 값은 flex 항목이 넓어지거나 좁아질 때 고려하는 기준 값입니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-properties.html", '100%', 510)}}

+ +

flex 축약형 표현에 사용할 수 있는 미리 정의된 축약 값들이 아래에 나열되어 있습니다. 이 값들 만으로도 대부분의 경우(use-case)에 대응할 수 있을 것 입니다.

+ + + +

flex 항목을 flex: initial로 지정하면  flex: 0 1 auto 로 지정한 것과 동일하게 동작합니다. 이 경우, flex 항목들은  flex-grow가 0이므로  flex-basis값보다 커지지 않고  flex-shrink가 1이므로 flex 컨테이너 공간이 모자라면 크기가 줄어듭니다. 또, flex-basis가 auto이므로 flex 항목은 주축 방향으로 지정된 크기 또는 자기 내부 요소 크기 만큼 공간을 차지합니다.

+ +

flex: auto 로 지정하면 flex: 1 1 auto로 지정한 것과 동일하며, flex:initial 과는 주축 방향 여유 공간이 있을 때 flex 항목들이 늘어나서 주축 방향 여유 공간을 채우는 점만 다릅니다.

+ +

flex: none으로 지정하면 flex: 0 0 auto으로 지정한 것과 동일하며 flex 컨테이너의 크기 변화에도 flex 항목 크기는 변하지 않고 flex-basis를 auto로 지정했을 때 정해지는 크기로 결정됩니다.  

+ +

이 축약형은 더 축약해서 flex: 1 이나 flex: 2처럼 쓸수도 있는데, 이는 flex-grow 만 지정하고 나머지는 1 0으로 사용한다는 뜻이다. 따라서 flex: 2는 flex: 2 1 0와 동일하게 처리됩니다.

+ +

다음 라이브 예제에서 이 축약 값들을 시험해 볼 수 있습니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-shorthands.html", '100%', 510)}}

+ +

정렬, 끝 맞추기(justification), flex 항목간 여유 공간 분배

+ +

flexbox의 주 기능 중 하나는 (주축과 교차축으로 표현되는) flex 컨테이너 공간 안에 flex 항목들을 정렬하고 끝 마추며 여유 공간을 항목 간에 분배하는 것입니다. 

+ +

역주) 이 절의 내용은 편의상 flex 컨테이너의 flex-direction를 row로 가정하고 '행'과 '열'로 표기했습니다.

+ +

align-items

+ +

{{cssxref("align-items")}}는 flex 컨테이너에 지정하는 속성이며, 교차축을 따라 flex 항목 열을 정렬하는 방식을 지정합니다. 

+ +

이 속성의 (아무것도 지정하지 않았을 때 적용되는)초기 값은 stretch이며 이 값을 지정하면 flex 항목의 높이는 flex 컨테이너flex 항목 행의 최대 높이로 지정됩니다. 따라서, flex 항목 행이 하나 일 때는 flex 항목은 교차축 방향으로 flex 컨테이너를 가득 채우게 됩니다.

+ +

이 속성을 flex-start로 지정하면 flex 항목의 첫 열이 교차축 방향의 시작선에 정렬됩니다. flex-end로 지정하면 flex 항목의 첫 열이 교차축 방향의 끝선에 정렬됩니다. center로 지정하면 flex 항목 행에 배분된 공간의 가운데 라인에 정렬됩니다.

+ +

다음 라이브 예제에서 이 값들을 시험해 볼 수 있습니다. - 이 시험을 위해 의도적으로 flex 컨테이너에 높이를 지정해 두었습니다.

+ + + +

{{EmbedGHLiveSample("css-examples/flexbox/basics/align-items.html", '100%', 520)}}

+ +

justify-content

+ +

{{cssxref("justify-content")}} 속성은 주축을 따라 flex 항목 행을 정렬하는 방식을 지정합니다.

+ +

이 속성의 (아무것도 지정하지 않았을 때 적용되는)초기 값은 flex-start이며 이 값을 지정하면 flex 항목 행 내의 항목들은 flex 컨테이너의 시작선에서 부터 정렬됩니다. flex-end로 지정하면 flex 항목 행의 마지막 항목이 flex 컨테이너의 끝선에서 정렬됩니다. center로 지정하면 flex 항목들이 flex 항목 행의 가운데 정렬됩니다.

+ +

space-between을 지정하면 주죽 방향 여유 공간을 flex 항목 사이의 공간에 균등 배분합니다. 

+ +

space-around는 시작선 및 끝선과 flex 항목간 공간도 균등 배분에 고려하므로 시작선 및 끝선과 flex 항목 간의 공간의 크기를 1로 배분한다면 flex 항목 사이의 공간은 2로 배분합니다. 

+ +

space-evenly로 지정하면 여유 공간을 flex 항목 사이의 공간 및 시작선 및 끝선과 flex 항목 간의 공간에 모두 균등하게 배분합니다.

+ +

다음 라이브 예제에서 justify-content에 지정할 수 있는 다음 값들을 시험해 볼 수 있습니다.

+ + + +

{{EmbedGHLiveSample("css-examples/flexbox/basics/justify-content.html", '100%', 380)}}

+ +

이 절에서 설명한 내용으로 대부분의 경우에 대응할 수 있지만,  Aligning Items in a Flex Container 에서 이 속성들을 더 자세히 살펴볼 것입니다.

+ +

Next steps

+ +

Flexbox의 개요를 살펴보았습니다. 다음 글 how this specification relates to other parts of CSS에서 이 규격이 다른 CSS 규격과 어떻게 연관되어 있는지 말씀드리겠습니다.

diff --git "a/files/ko/web/css/css_flexible_box_layout/flexbox\354\235\230_\352\270\260\353\263\270_\352\260\234\353\205\220/index.html" "b/files/ko/web/css/css_flexible_box_layout/flexbox\354\235\230_\352\270\260\353\263\270_\352\260\234\353\205\220/index.html" deleted file mode 100644 index 1966114608..0000000000 --- "a/files/ko/web/css/css_flexible_box_layout/flexbox\354\235\230_\352\270\260\353\263\270_\352\260\234\353\205\220/index.html" +++ /dev/null @@ -1,236 +0,0 @@ ---- -title: flexbox의 기본 개념 -slug: Web/CSS/CSS_Flexible_Box_Layout/Flexbox의_기본_개념 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox ---- -
{{CSSRef}}
- -

일명 flexbox라 불리는 Flexible Box module은 flexbox 인터페이스 내의 아이템 간 공간 배분과 강력한 정렬 기능을 제공하기 위한 1차원 레이아웃 모델 로 설계되었습니다. 이 글에서는 flexbox의 주요 기능에 대한 개요를 다룹니다. 더 자세한 내용은 가이드의 다른 글에서 탐구하게 될 것입니다.

- -

flexbox를 1차원이라 칭하는 것은, 레이아웃을 다룰 때 한 번에 하나의 차원(행이나 열)만을 다룬다는 뜻입니다. 이는 행과 열을 함께 조절하는 CSS 그리드 레이아웃의 2차원 모델과는 대조됩니다.

- -

flexbox의 두 개의 축

- -

flexbox를 다루려면 주축과 교차축이라는 두 개의 축에 대한 정의를 알아야 합니다. 주축은 {{cssxref("flex-direction")}} 속성을 사용하여 지정하며 교차축은 이에 수직인 축으로 결정됩니다. flexbox의 동작은 결국 이 두 개의 축에 대한 문제로 환원되기 때문에 이들이 어떻게 동작하는지 처음부터 이해하는 것이 중요합니다.

- -

주축

- -

주축은 flex-direction에 의해 정의되며 4개의 값을 가질 수 있습니다:

- - - -

row 혹은 row-reverse를 선택하면 주축은 인라인 방향으로 행을 따릅니다.

- -

If flex-direction is set to row the main axis runs along the row in the inline direction.

- -

column 혹은 column-reverse 을 선택하면 주축은 페이지 상단에서 하단으로 블록 방향을 따릅니다.

- -

If flex-direction is set to column the main axis runs in the block direction.

- -

교차축

- -

교차축은 주축에 수직하므로, 만약 flex-direction(주축)이 row 나 row-reverse 라면 교차축은 열 방향을 따릅니다.

- -

If flex-direction is set to row then the cross axis runs in the block direction.

- -

주축이 column 혹은 column-reverse 라면 교차축은 행 방향을 따릅니다.

- -

If flex-direction is set to column then the cross axis runs in the inline direction.

- -

flex 요소를 정렬하고 끝을 맞추(justify)려면 어느 축이 어느 방향인지 이해하는 것이 중요합니다; flexbox는 주축, 교차축을 따라 항목을 정렬하고 끝을 맞추는 각종 속성들을 적용하는 방식으로 동작합니다.

- -

시작선과 끝선

- -

flexbox가 쓰기 방법(writing mode)을 가정하지 않는다는 것은 상당히 중요합니다. 과거의 CSS는 왼쪽에서 오른쪽으로 향하는 가로 방향의 쓰기 방법에 치우쳐 있었습니다. 하지만 현대의 레이아웃은 다양한 쓰기 방법을 포괄해야 하므로, 더이상 텍스트가 문서의 왼쪽 상단에서 시작해서 오른쪽으로 향한다고 가정하지 않습니다. 새 라인이 항상 아래에 쌓인다고 가정하지도 않습니다.

- -

다른 글에서 flexbox와 쓰기 방법 명세(writing mode spec.)가 어떤 관련이 있는지 알아볼 수 있습니다. 그 전에, 이 글에서 flex 요소의 정렬 방향에 "왼쪽, 오른쪽, 위, 아래"를  사용하지 않는 이유를 알 수 있었으면 합니다.

- -

flex-direction이 row고 영어 문장을 문서에 쓰고 있다면, 주축의 시작선은 왼쪽 끝, 끝선은 오른쪽 끝이 될 것입니다.

- -

Working in English the start edge is on the left.

- -

아랍어 문장을 쓰고 있다면, 주축의 시작선은 오른쪽 끝, 끝 선은 왼쪽 끝이 될 것입니다.

- -

The start edge in a RTL language is on the right.

- -

영어와 아랍어는 모두 가로 쓰기를 채택하고 있으므로 두 예시에서 교차축의 시작선은 flex 컨테이너의 위 끝이며 끝선은 아래 끝입니다.

- -

조금만 지나면 왼쪽-오른쪽으로 생각하는 것보다 시작선-끝선으로 생각하는 것이 금새 자연스러워질 것입니다. 동일한 패턴을 따르는 CSS 그리드 레이아웃 같은 방법을 다룰 때도 쉽게 적응할 수 있을 것입니다.

- -

flex 컨테이너

- -

문서의 영역 중에서 flexbox가 놓여있는 영역을 flex 컨테이너라고 부릅니다. flex 컨테이너를 생성하려면 영역 내의 컨테이너 요소의 {{cssxref("display")}} 값을 flex 혹은 inline-flex로 지정합니다. 이 값이 지정된 컨테이너의 일차 자식(direct children) 요소가 flex 항목이 됩니다. display 속성만 지정하여 flex 컨테이너를 생성하면 다른 flex 관련 속성들은 아래처럼 기본 값이 지정됩니다.

- - - -

이렇게되면 flex 항목들은 각 항목 별 내부 요소의 크기로 주축을 따라 정렬됩니다. 컨테이너의 크기보다 더 많은 항목이 있을 경우 행을 바꾸지 않고 주축 방향으로 흘러 넘치게 됩니다. 어떤 항목이 다른 항목보다 높이 값이 크다면 나머지 모든 항목들은 그에 맞게 교차축을 따라 늘어나게 됩니다.

- -

다음의 라이브 예시를 통해 어떻게 보여지는지 확인할 수 있습니다. flexbox의 초기 동작을 시험해보려면 항목을 추가하거나 수정해보시기 바랍니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/basics/the-flex-container.html", '100%', 480)}} 

- -

flex-direction 지정

- -

flex 컨테이너에 {{cssxref("flex-direction")}} 속성을 지정하면 flex 항목이 나열되는 방향을 변경할 수 있습니다. flex-direction: row-reverse 라고 지정하면 행으로 나열되는 것은 그대로지만 시작 선과 끝 선이 서로 바뀌게 됩니다.

- -

flex-direction을 column으로 지정하면 주축이 변경되고 항목들은 열로 나열됩니다. column-reverse로 지정하면 그에 더해 시작 선과 끝 선이 서로 바뀌게 됩니다.

- -

다음의 라이브 예시는 flex-direction이 row-reverse로 지정되어 있습니다. row, columncolumn-reverse와 같은 값을 지정해서 어떻게 되는지 확인해보시기 바랍니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-direction.html", '100%', 350)}}

- -

flex-wrap을 이용한 복수 행 flex 컨테이너 지정

- -

flexbox는 1차원 모델이지만 flex 항목이 여러 행에 나열되도록 할 수 있습니다. 그 경우 각 행이 새로운 flex 컨테이너라고 생각해야 합니다. 공간 배분은 해당 행에서만 이루어지며 다른 행은 영향을 받지 않습니다.

- -

항목이 여러 행에 나열되도록 하려면 {{cssxref("flex-wrap")}} 속성의 값을 wrap으로 지정합니다. 그러면 항목이 하나의 행에 들어가지 않을 정도로 클 경우 다른 행에 배치됩니다. 아래의 라이브 예시에 있는 flex 항목은 폭이 지정되어 있으며 항목들의 폭의 합은 flex 컨테이너에 들어가기에는 너무 넓습니다. flex-wrap속성이 wrap으로 지정되어 있으므로 항목은 여러 행에 나열됩니다. 초깃값과 동일한 nowrap을 지정하고 flex항목에 대한 확대/축소 방식을 별도로 지정하지 않으면 flex 항목들은 컨테이너의 폭에 맞게 줄어듭니다.  nowrap을 지정하면 항목이 전혀 줄어들 수 없거나 충분히 줄어들 수 없을 때 흘러넘치게 됩니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-wrap.html", '100%', 400)}}

- -

Mastering Wrapping of Flex Items 가이드에서 더 자세한 내용을 확인할 수 있습니다.

- -

축약형 속성 flex-flow

- -

flex-direction 속성과 flex-wrap 속성을 {{cssxref("flex-flow")}}라는 축약 속성으로 합칠 수 있습니다. 첫 번째 값은 flex-direction이고 두 번째 값은 flex-wrap입니다.

- -

다음의 라이브 예시에서 첫 번째 값을 flex-direction에 지정 가능한 값들(row, row-reverse, column or column-reverse)로 바꿔보시기 바랍니다. 두 번째 값도 wrap이나 nowrap으로 바꿔보시기 바랍니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-flow.html", '100%', 400)}}

- -

flex 항목에 지정 가능한 속성들

- -

flex 항목에 적용할 수 있는 속성은 다음과 같습니다.

- - - -

이 글에서는 위의 속성들에 대해 간략하게 살펴보겠습니다. 자세한 내용은 Controlling Ratios of Flex Items on the Main Axis에서 다룹니다.

- -

500 픽셀의 크기를 갖는 flex 컨테이너 내에 100 픽셀 크기의 자식 세 개가 존재할 때, 사용가능한 공간 200 픽셀이 남게 됩니다. 기본적으로 flexbox는 이 공간을 마지막 자식 요소 다음에 빈공간으로 남겨둡니다.

- -

This flex container has available space after laying out the items.

- -

위의 세 가지 속성을 변경한다는 것은 flex 항목에게 사용가능한 공간을 분배하는 방식을 변경하는 것입니다. 사용가능한 공간 개념은 flex 항목을 정렬할 때 특히 중요합니다.

- -

flex-basis 속성

- -

flex-basis 속성은 항목의 크기를 결정합니다. 이 속성의 기본값은 auto이며, 이 경우 브라우저는 항목이 크기를 갖는지 확인합니다. 위의 사진 예시의 경우 항목의 크기가 100 픽셀이므로 flex-basis의 값으로 100 픽셀이 사용됩니다.

- -

flex 항목에 크기가 지정되어 있지 않으면, flex 항목의 내용물 크기가 flex-basis 값으로 사용됩니다. 따라서 flex 컨테이너에서 display: flex 속성만을 지정하면 flex항목들이 각 내용물 크기만큼 공간을 차지하게 됩니다.

- -

flex-grow 속성

- -

flex-grow값을 양수로 지정하면 flex 항목별로 주축 방향 크기가 flex-basis 값 이상으로 늘어날 수 있게 됩니다. 위의 사진 예시에서 모든 항목의 flex-grow 값을 1로 지정하면 사용가능한 공간은 각 항목에게 동일하게 분배되며, 각 항목은 주축을 따라 분배받은 값만큼 사이즈를 늘려 공간을 차지합니다.

- -

첫 항목의 flex-grow 값을 2로 지정하고 나머지 두 개의 항목을 1로 지정한다면 각 항목에 지정된 flex-grow 값의 비율에 따라 남은 공간이 분배됩니다. 각 항목의 flex-grow 비율이 2:1:1 이므로 첫 항목에게 100 픽셀, 두 번째와 세 번째 항목에게 50 픽셀씩 분배됩니다.

- -

flex-shrink 속성

- -

flex-grow 속성이 주축에서 남는 공간을 항목들에게 분배하는 방법을 결정한다면 flex-shrink 속성은 주축의 공간이 부족할때 각 항목의 사이즈를 줄이는 방법을 정의합니다. 만약 flex 컨테이너flex 항목을 모두 포함할 만큼 넉넉한 공간을 갖고 있지 않고 flex-shrink 값이 양수이면 flex 항목은 flex-basis에 지정된 크기보다 작아집니다. 또한, flex-grow 속성과 마찬가지로 더 큰 flex-shrink 값을 갖는 항목의 사이즈가 더 빨리 줄어듭니다.

- -

항목의 최소 크기는 실제 축소량을 계산할 때 고려되기 때문에 flex-shrink 속성이 flex-grow 속성에 비해 덜 일관된 모습을 보여줄지도 모릅니다. flex-shrink 속성이 항목의 사이즈를 결정하는 알고리즘에 관해서는 Controlling Ratios of Flex Items on the Main Axis에서 자세히 살펴히보겠습니다.

- -
-

flex-grow 와 flex-shrink의 값이 비율임을 유의하세요.  flex 항목의 flex 속성을 모두 1 1 200px 로 지정하고 한 항목만 크기가 늘어나는 비율을 타 항목의 두배로 하고 싶으면 해당 flex 항목의 flex 속성을 2 1 200px로 지정하면 되지만, flex 속성 값을 모두  10 1 200px로 지정하고 늘어나는 비율을 두 배로 하고 싶은 항목의 flex 속성 값만 20 1 200px로 지정해도 동일하게 동작합니다.

-
- -

축약형 속성 flex

- -

보통은 flex-grow, flex-shrinkflex-basis  값을 각각 사용하지 않고 이 세 속성을 한번에 지정하는 {{cssxref("flex")}} 축약형을 많이 사용합니다. flex 축약형의 값은 flex-grow, flex-shrink, flex-basis 순서로 지정됩니다.

- -

다음의 라이브 예시에서 flex 축약형의 값들을 조절하면서 시험해 볼 수 있습니다. 첫 값이 flex-grow를 지정하며,  이 첫 값을 양수로 하면 flex 항목이 넓어질 수 있습니다. 두 번째 값은 flex-shrink 를 지정하며 이 두 번째 값에 양수를 지정하면 flex 항목이 좁아질 수 있습니다. 세 번째 값은 flex-basis를 지정하며 이 값은 flex 항목이 넓어지거나 좁아질 때 고려하는 기준 값입니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-properties.html", '100%', 510)}}

- -

flex 축약형 표현에 사용할 수 있는 미리 정의된 축약 값들이 아래에 나열되어 있습니다. 이 값들 만으로도 대부분의 경우(use-case)에 대응할 수 있을 것 입니다.

- - - -

flex 항목을 flex: initial로 지정하면  flex: 0 1 auto 로 지정한 것과 동일하게 동작합니다. 이 경우, flex 항목들은  flex-grow가 0이므로  flex-basis값보다 커지지 않고  flex-shrink가 1이므로 flex 컨테이너 공간이 모자라면 크기가 줄어듭니다. 또, flex-basis가 auto이므로 flex 항목은 주축 방향으로 지정된 크기 또는 자기 내부 요소 크기 만큼 공간을 차지합니다.

- -

flex: auto 로 지정하면 flex: 1 1 auto로 지정한 것과 동일하며, flex:initial 과는 주축 방향 여유 공간이 있을 때 flex 항목들이 늘어나서 주축 방향 여유 공간을 채우는 점만 다릅니다.

- -

flex: none으로 지정하면 flex: 0 0 auto으로 지정한 것과 동일하며 flex 컨테이너의 크기 변화에도 flex 항목 크기는 변하지 않고 flex-basis를 auto로 지정했을 때 정해지는 크기로 결정됩니다.  

- -

이 축약형은 더 축약해서 flex: 1 이나 flex: 2처럼 쓸수도 있는데, 이는 flex-grow 만 지정하고 나머지는 1 0으로 사용한다는 뜻이다. 따라서 flex: 2는 flex: 2 1 0와 동일하게 처리됩니다.

- -

다음 라이브 예제에서 이 축약 값들을 시험해 볼 수 있습니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/basics/flex-shorthands.html", '100%', 510)}}

- -

정렬, 끝 맞추기(justification), flex 항목간 여유 공간 분배

- -

flexbox의 주 기능 중 하나는 (주축과 교차축으로 표현되는) flex 컨테이너 공간 안에 flex 항목들을 정렬하고 끝 마추며 여유 공간을 항목 간에 분배하는 것입니다. 

- -

역주) 이 절의 내용은 편의상 flex 컨테이너의 flex-direction를 row로 가정하고 '행'과 '열'로 표기했습니다.

- -

align-items

- -

{{cssxref("align-items")}}는 flex 컨테이너에 지정하는 속성이며, 교차축을 따라 flex 항목 열을 정렬하는 방식을 지정합니다. 

- -

이 속성의 (아무것도 지정하지 않았을 때 적용되는)초기 값은 stretch이며 이 값을 지정하면 flex 항목의 높이는 flex 컨테이너flex 항목 행의 최대 높이로 지정됩니다. 따라서, flex 항목 행이 하나 일 때는 flex 항목은 교차축 방향으로 flex 컨테이너를 가득 채우게 됩니다.

- -

이 속성을 flex-start로 지정하면 flex 항목의 첫 열이 교차축 방향의 시작선에 정렬됩니다. flex-end로 지정하면 flex 항목의 첫 열이 교차축 방향의 끝선에 정렬됩니다. center로 지정하면 flex 항목 행에 배분된 공간의 가운데 라인에 정렬됩니다.

- -

다음 라이브 예제에서 이 값들을 시험해 볼 수 있습니다. - 이 시험을 위해 의도적으로 flex 컨테이너에 높이를 지정해 두었습니다.

- - - -

{{EmbedGHLiveSample("css-examples/flexbox/basics/align-items.html", '100%', 520)}}

- -

justify-content

- -

{{cssxref("justify-content")}} 속성은 주축을 따라 flex 항목 행을 정렬하는 방식을 지정합니다.

- -

이 속성의 (아무것도 지정하지 않았을 때 적용되는)초기 값은 flex-start이며 이 값을 지정하면 flex 항목 행 내의 항목들은 flex 컨테이너의 시작선에서 부터 정렬됩니다. flex-end로 지정하면 flex 항목 행의 마지막 항목이 flex 컨테이너의 끝선에서 정렬됩니다. center로 지정하면 flex 항목들이 flex 항목 행의 가운데 정렬됩니다.

- -

space-between을 지정하면 주죽 방향 여유 공간을 flex 항목 사이의 공간에 균등 배분합니다. 

- -

space-around는 시작선 및 끝선과 flex 항목간 공간도 균등 배분에 고려하므로 시작선 및 끝선과 flex 항목 간의 공간의 크기를 1로 배분한다면 flex 항목 사이의 공간은 2로 배분합니다. 

- -

space-evenly로 지정하면 여유 공간을 flex 항목 사이의 공간 및 시작선 및 끝선과 flex 항목 간의 공간에 모두 균등하게 배분합니다.

- -

다음 라이브 예제에서 justify-content에 지정할 수 있는 다음 값들을 시험해 볼 수 있습니다.

- - - -

{{EmbedGHLiveSample("css-examples/flexbox/basics/justify-content.html", '100%', 380)}}

- -

이 절에서 설명한 내용으로 대부분의 경우에 대응할 수 있지만,  Aligning Items in a Flex Container 에서 이 속성들을 더 자세히 살펴볼 것입니다.

- -

Next steps

- -

Flexbox의 개요를 살펴보았습니다. 다음 글 how this specification relates to other parts of CSS에서 이 규격이 다른 CSS 규격과 어떻게 연관되어 있는지 말씀드리겠습니다.

diff --git a/files/ko/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html b/files/ko/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html new file mode 100644 index 0000000000..a9f75246aa --- /dev/null +++ b/files/ko/web/css/css_flexible_box_layout/typical_use_cases_of_flexbox/index.html @@ -0,0 +1,141 @@ +--- +title: 가변상자의 대표적인 사용례 +slug: Web/CSS/CSS_Flexible_Box_Layout/가변상자의_대표적인_사용례 +tags: + - 가변상자 + - 씨에스에스 + - 안내서 + - 용례 + - 패턴 +translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox +--- +

{{CSSRef}}

+ +

이번 안내서에서는 흔히 볼 수 있는 가변상자 사용 사례 중 일부를 살펴 보겠습니다. 가변상자의 사용이 다른 조판 메서드보다 더 적합한 사례입니다.

+ +

왜 가변상자를 선택?

+ +

완벽한 브라우저 지원 환경에서 가변상자를 사용하기로 선택한 이유는 항목 모음을 한 방향 또는 다른 방향으로 배치하길 원하기 때문입니다. 우리가 항목을 배치할 때 해당 일차원의 항목 크기를 제어하거나 항목 간 간격을 제어하려고 합니다. 이것이 가변상자를 설계한 목적에 맞는 용도입니다. 가변상자와 여타 씨에스에스 조판 메서드의 관계에서 가변상자와 씨에스에스 격자 조판의 차이점에 대해 자세히 읽을 수 있습니다. 그곳에선 가변상자가 씨에스에스 조판의 전체 그림에서 어떤 역할을 하고 있는지에 대해 논의합니다.

+ +

실제로 격자 조판에 의해 더 잘 수행 될 수있는 작업이나 격자에 대한 대체품 및 정렬 기능을 얻기 위해 가변상자를 종종 사용합니다. 당 사용례는 블록 조판에서 상자 정렬 (Box Alignment) 이 구현되고 나면 변경될 수 있습니다. 이 안내서에서는 오늘날 가변상자가 쓰일 수 있는 몇 가지 대표적인 사용례를 살펴봅니다.

+ +

탐색 메뉴

+ +

탐색 메뉴의 일반적인 패턴은 항목 목록을 가로 막대로 표시하는 것입니다. 이 패턴은 기본적으로 가변상자 이전에는 달성하기 어려웠습니다. 이는(탐색 가로 막대) 가장 간단한 가변상자 예제를 형성하며 이상적인 가변상자 사용 사례로 간주될 수 있습니다.

+ +

가로로 표시하려는 항목 집합이 있으면 잉여 공간이 생길 수밖에 없습니다. 우리는 그 공간으로 무엇을 해야할지 결정해야 하며 몇 가지 선택 옵션이 있습니다. 일번 선택은 우리가 항목 무리 이외의 공간을 표시합니다. 따라서 그 사이 또는 그 주변에 공백이 생깁니다. 또는 항목 내부 여분의 공간을 흡수하려면 항목 집합이 이 공간을 확장하고 점유할 수 있는 메소드가 필요합니다.

+ +

항목 외부에 공간 분배

+ +

항목 사이 또는 주위에 공간을 분배시키기 위해 가변상자의 정렬 속성과 {{cssxref("justify-content")}} 속성을 사용합니다. 이 속성에 대한 자세한 내용은 기본 축을 기준으로 항목 정렬을 처리하는 가변 컨테이너의 항목 정렬에서 확인할 수 있습니다.

+ +

아래 실제 예에서 우리는 항목을 원래 크기로 표시하고 justify-content: space-between를 사용하여 항목 사이의 간격을 동일하게 만듭니다. space-around 값을 사용하거나, 지원이 될 경우 space-evenly를 사용해 공간이 분배되는 방식을 변경할 수 있습니다. flex-start를 사용하여 항목 끝에 공간을 배치하거나 flex-end를 사용하여 항목 앞에 배치하거나 center를 사용해 탐색 항목 중앙에 배치할 수 있습니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation.html", '100%', 550)}}

+ +

항목 내부에 공간 분배

+ +

탐색 메뉴를 위한 다른 패턴은 항목 사이에 공간을 만드는 것이 아니라 항목 자체 내에 사용 가능한 공간을 분배하는 것입니다. 이 경우, 주축을 따라 가변 항목의 비율 제어에서 설명된대로 가변 속성을 사용하여 항목이 서로 비례하여 확대 및 축소되도록 합니다.

+ +

모든 탐색 메뉴 항목의 너비를 동일하게 하려면 flex: auto를 사용하면 됩니다. 그것은 flex: 1 1 auto의 약칭으로 모든 항목이 자동이란 가변 기반에 따라 확대되거나 축소됩니다. 여기서 자동이란 항목이 길수록 더 많은 공간이 생긴다는 말입니다.

+ +

아래의 실제 예제에서 flex: autoflex: 1로 변경해보십시요. 이것은 flex: 1 1 0의 약칭입니다. 모든 항목이 0의 가변 기반에서 작동하여 모든 공간을 고르게 배분할 수 있기 때문에 모든 항목이 동일한 너비가 됩니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation-flex.html", '100%', 550)}}

+ +

탐색 메뉴 분할

+ +

주축에서 항목을 정렬하는 또 다른 방법은 자동 여백을 사용하는 것입니다. 이를 통해 한 그룹의 항목이 왼쪽으로 정렬되고 다른 그룹이 오른쪽으로 정렬되는 탐색 모음(메뉴)의 디자인 패턴이 가능합니다.

+ +

여기에서는 주축 정렬에 대한 자동 여백 사용에서 설명된 자동 여백 기술을 사용합니다. 항목 무리는 flex-start를 사용해 주축에 정렬됩니다. 그것이 가변상자의 초기값 동작이며, 우리가 항목을 오른쪽으로 정렬하려면 왼쪽 여백을 자동으로 지정합니다. 클래스 지정을 한 항목에서 다른 항목으로 이동하여 분할이 발생하는 위치를 변경할 수 있습니다.

+ +

또한 이 예제에서는 가변 항목에 여백을 사용하여 항목 사이에 간격을 만들고 컨테이너에 음의 여백을 사용하여 항목이 여전히 오른쪽 및 왼쪽 가장자리와 맞붙도록 합니다. 박스 정렬 (Box Alignment) 규격의 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)}}

+ +

박스 정렬 (Box Alignment) 속성은 궁극적으로 블록 조판의 내용으로 구현될 예정이므로 미래에는 단일 아이템을 중앙에 배치하기 위해 컨테이너를 가변 컨테이너로 만들 필요는 없습니다. 그러나 당장은 하나의 것을 다른 것의 중심에 올바로 배치해야하는 경우 가변상자를 사용하는 게 맞습니다. 위의 예에서와 같이 컨테이너를 가변 컨테이너로 만든 다음 상위 요소에 대해 align-items을 사용하거나 가변 항목 자체를 align-self로 공략합니다.

+ +

바닥글을 아래로 밀어내는 카드 조판

+ +

가변상자 또는 씨에스에스 격자를 사용하여 카드 구성 요소의 목록을 조판하더라도, 이들 조판 메서드는 가변 또는 격자 구성 요소의 직계 자식에서만 작동합니다. 즉, 콘텐츠의 크기가 가변적이면 카드가 격자 영역의 높이나 가변 컨테이너의 높이까지 늘어납니다. 모든 내부 콘텐츠는 친숙한 블록 조판을 사용합니다. 즉, 콘텐츠가 적은 카드에서는 바닥글이 카드의 아래쪽에 고정되지 않고 콘텐츠의 밑단까지 차오릅니다.

+ +

구성 요소의 내부가 (상위) 랩퍼와 함께 늘어나지 않음을 표시하는 두 개의 카드 구성 요소.

+ +

가변상자가 이를 해결할 수 있습니다. 우리는 {{cssxref("flex-direction")}}: column 속성를 가진 카드를 가변 컨테이너로 만듭니다. 그런 다음 컨텐츠 영역을 flex: 1로 설정합니다. 이는 flex: 1 1 0의 축약형입니다. — 항목이 0의 가변 기준에서 커지거나 줄어들 수 있습니다. 이것이(컨텐츠 영역이) 커질 수 있는 유일한 항목이므로 가변 컨테이너에 있는 잉여 공간을 차지하고 바닥글을 바닥으로 밉니다. 라이브 예제에서 flex 속성을 제거하면 바닥글이 컨텐츠 바로 아래로 이동하는 방식을 볼 수 있습니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/cards.html", '100%', 800)}}

+ +

미디어 객체

+ +

미디어 객체는 웹 디자인에서 일반적인 패턴입니다. 이 패턴에는 한쪽에 이미지 나 다른 요소가 있고 오른쪽에 텍스트가 있습니다. 이상적으로 미디어 개체를 반대쪽으로 돌릴 수 있어야 합니다. 말하자면 이미지를 왼쪽에서 오른쪽으로 이동시키는 겁니다.

+ +

이 패턴은 어디에서나 볼 수 있으며, 주석 상자용으로 쓰이기도 하고, 이미지와 설명을 표시해야하는 모든 곳에서 볼 수 있습니다. 가변상자를 사용하면 이미지를 포함하는 미디어 객체의 일부가 이미지에서 크기 정보를 가져온 다음 미디어 객체의 본문이 가변적으로 남은 공간을 차지할 수 있습니다.

+ +

여러분은 아래 실제 예제에서 미디어 객체를 볼 수 있습니다. 정렬 속성을 사용하여 십자축의 항목을 flex-start로 정렬한 다음 .content 가변 항목을 flex: 1로 설정했습니다. 위의 열 조판 카드 패턴에서와 같이 flex: 1를 사용하면 카드가 커질 수 있습니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media.html", '100%', 600)}}

+ +

이 라이브 예제에서 시도할 수 있는 것은 디자인에서 미디어 개체를 제약하려는 여러 가지 방법과 관련이 있습니다.

+ +

이미지가 너무 커지는 것을 방지하려면 이미지에 {{cssxref("max-width")}}를 추가하십시오. 미디어 객체의 그쪽 측면이 가변상자의 초기값(예: 100px)을 사용함에 따라 줄어들지만 커질 수는 없으며 flex-basis는 자동을 사용합니다. 이미지에 적용된 모든 {{cssxref("width")}} 또는 최대 너비는 flex-basis (가변 기준) 이 됩니다.

+ +
.image img {
+  max-width: 100px;
+}
+
+ +

또한 양쪽이 비례하여 커지거나 줄어들 수 있습니다. 양면을 flex: 1로 설정하면 0의 {{cssxref("flex-basis")}}에서 커지거나 줄어들기 때문에 두 개의 동일한 크기의 열이 생깁니다. 컨텐츠를 기준으로 사용하여 (컨텐츠와 이미지) 둘 다에 flex: auto로 설정하면 컨텐츠의 크기에 따라, 또는 이미지의 너비와 같은 가변 항목에 직접 적용되는 크기에 따라 커지거나 줄어들 수 있습니다.

+ +
.media .content {
+  flex: 1;
+  padding: 10px;
+}
+
+.image {
+  flex: 1;
+}
+ +

예를 들어 이미지가 있는 쪽을 flex: 1로 설정하고 콘텐츠 쪽을 flex: 3으로 설정하는 등 각면에 서로 다른 {{cssxref("flex-grow")}}를 부여할 수 있습니다. 즉, flex-basis0으로 사용하지만 해당 공간을 flex-grow 인수에 맞춰 서로 다르게 공간을 할당합니다. 그런 용도로 사용하는 가변 속성은 주축을 따라 가변 항목의 비율 제어 안내서에서 자세히 설명되어 있습니다.

+ +
.media .content {
+  flex: 3;
+  padding: 10px;
+}
+
+.image {
+  flex: 1;
+}
+ +

미디어 객체 방향 돌리기

+ +

이미지가 오른쪽에 있고 콘텐츠가 왼쪽에 있도록 미디어 객체의 표시를 전환하려면 flex-direction 속성을 이용해 row-reverse로 설정할 수 있습니다. 미디어 개체가 이제 다른 방향으로 표시됩니다. 저는 그걸 달성하기 위해 라이브 예제에서 기존 .media 클래스와 함께 flipped 클래스를 추가했습니다. 즉, 에이치티엠엘에서 해당 클래스를 제거하여 디스플레이가 어떻게 변경되는지 확인할 수 있습니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media-flipped.html", '100%', 650)}}

+ +

양식 컨트롤

+ +

가변상자는 양식 컨트롤에 스타일을 적용할 때 특히 유용합니다. 양식에는 일반적으로 서로 정렬하고 싶은 다수의 마크업과 다수의 작은 요소를 포함할 수 있습니다. 일반적인 패턴은 {{htmlelement("input")}} 요소가 {{htmlelement("button")}}과 짝을 이루는 검색 양식의 경우나 방문자가 단순히 전자 메일 주소를 입력하도록 하려는 경우입니다.

+ +

가변상자를 사용하면 이러한 유형의 조판을 쉽게 달성할 수 있습니다. 테두리를 지정하고 표시하도록 설정한 래퍼 클래스에 <button><input> 필드가 포함되어 있습니다. 거기에 테두리를 부여하고 display: flex를 설정했습니다. 그런 다음 가변 속성을 사용하여 <input> 필드가 커지도록 했고, 버튼은 그렇지 않습니다. 이것은 사용 가능한 공간이 변함에 따라 텍스트 필드가 커지거나 작아지는 한 쌍의 필드가 있음을 의미합니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/input-button.html", '100%', 550)}}

+ +

버튼을 오른쪽에 올려 놓은 것처럼 레이블이나 아이콘을 왼쪽에 쉽게 추가 할 수 있습니다. 나는 레이블을 추가했으며 배경색에 대한 스타일링 이외에 조판을 변경할 필요가 없었습니다. 신축성있는 입력 필드는 이제 맘대로 이용할 공간이 조금 줄어들지만 두 항목의 지분이 고려된 후 남은 공간을 사용합니다.

+ +

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/label-input-button.html", '100%', 550)}}

+ +

이와 같은 패턴을 사용하면 디자인에 추가할 요소를 쉽게 수용할 수 있는 양식 요소 라이브러리를 훨씬 쉽게 만들 수 있습니다. 커지지 않는 항목과 커지는 항목을 혼합하는 식으로 가변상자의 유연성을 활용하고 있습니다.

+ +

결론

+ +

위의 패턴을 살펴보면서 가변 상자를 사용하여 원하는 결과를 얻는 가장 좋은 방법을 여러분이 생각을 통해 파악되기 시작했길 희망해봅니다. 종종 하나 이상의 선택이 있습니다. 늘릴 수 없는 항목을 늘릴 수 있는 것과 혼합하거나, 콘텐츠를 사용하여 크기를 알리거나, 가변상자가 공간을 비례적으로 공유할 수 있도록 하십시오. 그것은 당신에게 달려 있습니다.

+ +

보유 컨텐츠를 제시하는 가장 좋은 방법을 생각한 다음 가변상자 또는 기타 조판 방법이 컨텐츠를 선보이는 데 어떻게 도움이 되는지 살펴보십시오.

diff --git "a/files/ko/web/css/css_flexible_box_layout/\352\260\200\353\263\200\354\203\201\354\236\220\354\235\230_\353\214\200\355\221\234\354\240\201\354\235\270_\354\202\254\354\232\251\353\241\200/index.html" "b/files/ko/web/css/css_flexible_box_layout/\352\260\200\353\263\200\354\203\201\354\236\220\354\235\230_\353\214\200\355\221\234\354\240\201\354\235\270_\354\202\254\354\232\251\353\241\200/index.html" deleted file mode 100644 index a9f75246aa..0000000000 --- "a/files/ko/web/css/css_flexible_box_layout/\352\260\200\353\263\200\354\203\201\354\236\220\354\235\230_\353\214\200\355\221\234\354\240\201\354\235\270_\354\202\254\354\232\251\353\241\200/index.html" +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: 가변상자의 대표적인 사용례 -slug: Web/CSS/CSS_Flexible_Box_Layout/가변상자의_대표적인_사용례 -tags: - - 가변상자 - - 씨에스에스 - - 안내서 - - 용례 - - 패턴 -translation_of: Web/CSS/CSS_Flexible_Box_Layout/Typical_Use_Cases_of_Flexbox ---- -

{{CSSRef}}

- -

이번 안내서에서는 흔히 볼 수 있는 가변상자 사용 사례 중 일부를 살펴 보겠습니다. 가변상자의 사용이 다른 조판 메서드보다 더 적합한 사례입니다.

- -

왜 가변상자를 선택?

- -

완벽한 브라우저 지원 환경에서 가변상자를 사용하기로 선택한 이유는 항목 모음을 한 방향 또는 다른 방향으로 배치하길 원하기 때문입니다. 우리가 항목을 배치할 때 해당 일차원의 항목 크기를 제어하거나 항목 간 간격을 제어하려고 합니다. 이것이 가변상자를 설계한 목적에 맞는 용도입니다. 가변상자와 여타 씨에스에스 조판 메서드의 관계에서 가변상자와 씨에스에스 격자 조판의 차이점에 대해 자세히 읽을 수 있습니다. 그곳에선 가변상자가 씨에스에스 조판의 전체 그림에서 어떤 역할을 하고 있는지에 대해 논의합니다.

- -

실제로 격자 조판에 의해 더 잘 수행 될 수있는 작업이나 격자에 대한 대체품 및 정렬 기능을 얻기 위해 가변상자를 종종 사용합니다. 당 사용례는 블록 조판에서 상자 정렬 (Box Alignment) 이 구현되고 나면 변경될 수 있습니다. 이 안내서에서는 오늘날 가변상자가 쓰일 수 있는 몇 가지 대표적인 사용례를 살펴봅니다.

- -

탐색 메뉴

- -

탐색 메뉴의 일반적인 패턴은 항목 목록을 가로 막대로 표시하는 것입니다. 이 패턴은 기본적으로 가변상자 이전에는 달성하기 어려웠습니다. 이는(탐색 가로 막대) 가장 간단한 가변상자 예제를 형성하며 이상적인 가변상자 사용 사례로 간주될 수 있습니다.

- -

가로로 표시하려는 항목 집합이 있으면 잉여 공간이 생길 수밖에 없습니다. 우리는 그 공간으로 무엇을 해야할지 결정해야 하며 몇 가지 선택 옵션이 있습니다. 일번 선택은 우리가 항목 무리 이외의 공간을 표시합니다. 따라서 그 사이 또는 그 주변에 공백이 생깁니다. 또는 항목 내부 여분의 공간을 흡수하려면 항목 집합이 이 공간을 확장하고 점유할 수 있는 메소드가 필요합니다.

- -

항목 외부에 공간 분배

- -

항목 사이 또는 주위에 공간을 분배시키기 위해 가변상자의 정렬 속성과 {{cssxref("justify-content")}} 속성을 사용합니다. 이 속성에 대한 자세한 내용은 기본 축을 기준으로 항목 정렬을 처리하는 가변 컨테이너의 항목 정렬에서 확인할 수 있습니다.

- -

아래 실제 예에서 우리는 항목을 원래 크기로 표시하고 justify-content: space-between를 사용하여 항목 사이의 간격을 동일하게 만듭니다. space-around 값을 사용하거나, 지원이 될 경우 space-evenly를 사용해 공간이 분배되는 방식을 변경할 수 있습니다. flex-start를 사용하여 항목 끝에 공간을 배치하거나 flex-end를 사용하여 항목 앞에 배치하거나 center를 사용해 탐색 항목 중앙에 배치할 수 있습니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation.html", '100%', 550)}}

- -

항목 내부에 공간 분배

- -

탐색 메뉴를 위한 다른 패턴은 항목 사이에 공간을 만드는 것이 아니라 항목 자체 내에 사용 가능한 공간을 분배하는 것입니다. 이 경우, 주축을 따라 가변 항목의 비율 제어에서 설명된대로 가변 속성을 사용하여 항목이 서로 비례하여 확대 및 축소되도록 합니다.

- -

모든 탐색 메뉴 항목의 너비를 동일하게 하려면 flex: auto를 사용하면 됩니다. 그것은 flex: 1 1 auto의 약칭으로 모든 항목이 자동이란 가변 기반에 따라 확대되거나 축소됩니다. 여기서 자동이란 항목이 길수록 더 많은 공간이 생긴다는 말입니다.

- -

아래의 실제 예제에서 flex: autoflex: 1로 변경해보십시요. 이것은 flex: 1 1 0의 약칭입니다. 모든 항목이 0의 가변 기반에서 작동하여 모든 공간을 고르게 배분할 수 있기 때문에 모든 항목이 동일한 너비가 됩니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/navigation-flex.html", '100%', 550)}}

- -

탐색 메뉴 분할

- -

주축에서 항목을 정렬하는 또 다른 방법은 자동 여백을 사용하는 것입니다. 이를 통해 한 그룹의 항목이 왼쪽으로 정렬되고 다른 그룹이 오른쪽으로 정렬되는 탐색 모음(메뉴)의 디자인 패턴이 가능합니다.

- -

여기에서는 주축 정렬에 대한 자동 여백 사용에서 설명된 자동 여백 기술을 사용합니다. 항목 무리는 flex-start를 사용해 주축에 정렬됩니다. 그것이 가변상자의 초기값 동작이며, 우리가 항목을 오른쪽으로 정렬하려면 왼쪽 여백을 자동으로 지정합니다. 클래스 지정을 한 항목에서 다른 항목으로 이동하여 분할이 발생하는 위치를 변경할 수 있습니다.

- -

또한 이 예제에서는 가변 항목에 여백을 사용하여 항목 사이에 간격을 만들고 컨테이너에 음의 여백을 사용하여 항목이 여전히 오른쪽 및 왼쪽 가장자리와 맞붙도록 합니다. 박스 정렬 (Box Alignment) 규격의 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)}}

- -

박스 정렬 (Box Alignment) 속성은 궁극적으로 블록 조판의 내용으로 구현될 예정이므로 미래에는 단일 아이템을 중앙에 배치하기 위해 컨테이너를 가변 컨테이너로 만들 필요는 없습니다. 그러나 당장은 하나의 것을 다른 것의 중심에 올바로 배치해야하는 경우 가변상자를 사용하는 게 맞습니다. 위의 예에서와 같이 컨테이너를 가변 컨테이너로 만든 다음 상위 요소에 대해 align-items을 사용하거나 가변 항목 자체를 align-self로 공략합니다.

- -

바닥글을 아래로 밀어내는 카드 조판

- -

가변상자 또는 씨에스에스 격자를 사용하여 카드 구성 요소의 목록을 조판하더라도, 이들 조판 메서드는 가변 또는 격자 구성 요소의 직계 자식에서만 작동합니다. 즉, 콘텐츠의 크기가 가변적이면 카드가 격자 영역의 높이나 가변 컨테이너의 높이까지 늘어납니다. 모든 내부 콘텐츠는 친숙한 블록 조판을 사용합니다. 즉, 콘텐츠가 적은 카드에서는 바닥글이 카드의 아래쪽에 고정되지 않고 콘텐츠의 밑단까지 차오릅니다.

- -

구성 요소의 내부가 (상위) 랩퍼와 함께 늘어나지 않음을 표시하는 두 개의 카드 구성 요소.

- -

가변상자가 이를 해결할 수 있습니다. 우리는 {{cssxref("flex-direction")}}: column 속성를 가진 카드를 가변 컨테이너로 만듭니다. 그런 다음 컨텐츠 영역을 flex: 1로 설정합니다. 이는 flex: 1 1 0의 축약형입니다. — 항목이 0의 가변 기준에서 커지거나 줄어들 수 있습니다. 이것이(컨텐츠 영역이) 커질 수 있는 유일한 항목이므로 가변 컨테이너에 있는 잉여 공간을 차지하고 바닥글을 바닥으로 밉니다. 라이브 예제에서 flex 속성을 제거하면 바닥글이 컨텐츠 바로 아래로 이동하는 방식을 볼 수 있습니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/cards.html", '100%', 800)}}

- -

미디어 객체

- -

미디어 객체는 웹 디자인에서 일반적인 패턴입니다. 이 패턴에는 한쪽에 이미지 나 다른 요소가 있고 오른쪽에 텍스트가 있습니다. 이상적으로 미디어 개체를 반대쪽으로 돌릴 수 있어야 합니다. 말하자면 이미지를 왼쪽에서 오른쪽으로 이동시키는 겁니다.

- -

이 패턴은 어디에서나 볼 수 있으며, 주석 상자용으로 쓰이기도 하고, 이미지와 설명을 표시해야하는 모든 곳에서 볼 수 있습니다. 가변상자를 사용하면 이미지를 포함하는 미디어 객체의 일부가 이미지에서 크기 정보를 가져온 다음 미디어 객체의 본문이 가변적으로 남은 공간을 차지할 수 있습니다.

- -

여러분은 아래 실제 예제에서 미디어 객체를 볼 수 있습니다. 정렬 속성을 사용하여 십자축의 항목을 flex-start로 정렬한 다음 .content 가변 항목을 flex: 1로 설정했습니다. 위의 열 조판 카드 패턴에서와 같이 flex: 1를 사용하면 카드가 커질 수 있습니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media.html", '100%', 600)}}

- -

이 라이브 예제에서 시도할 수 있는 것은 디자인에서 미디어 개체를 제약하려는 여러 가지 방법과 관련이 있습니다.

- -

이미지가 너무 커지는 것을 방지하려면 이미지에 {{cssxref("max-width")}}를 추가하십시오. 미디어 객체의 그쪽 측면이 가변상자의 초기값(예: 100px)을 사용함에 따라 줄어들지만 커질 수는 없으며 flex-basis는 자동을 사용합니다. 이미지에 적용된 모든 {{cssxref("width")}} 또는 최대 너비는 flex-basis (가변 기준) 이 됩니다.

- -
.image img {
-  max-width: 100px;
-}
-
- -

또한 양쪽이 비례하여 커지거나 줄어들 수 있습니다. 양면을 flex: 1로 설정하면 0의 {{cssxref("flex-basis")}}에서 커지거나 줄어들기 때문에 두 개의 동일한 크기의 열이 생깁니다. 컨텐츠를 기준으로 사용하여 (컨텐츠와 이미지) 둘 다에 flex: auto로 설정하면 컨텐츠의 크기에 따라, 또는 이미지의 너비와 같은 가변 항목에 직접 적용되는 크기에 따라 커지거나 줄어들 수 있습니다.

- -
.media .content {
-  flex: 1;
-  padding: 10px;
-}
-
-.image {
-  flex: 1;
-}
- -

예를 들어 이미지가 있는 쪽을 flex: 1로 설정하고 콘텐츠 쪽을 flex: 3으로 설정하는 등 각면에 서로 다른 {{cssxref("flex-grow")}}를 부여할 수 있습니다. 즉, flex-basis0으로 사용하지만 해당 공간을 flex-grow 인수에 맞춰 서로 다르게 공간을 할당합니다. 그런 용도로 사용하는 가변 속성은 주축을 따라 가변 항목의 비율 제어 안내서에서 자세히 설명되어 있습니다.

- -
.media .content {
-  flex: 3;
-  padding: 10px;
-}
-
-.image {
-  flex: 1;
-}
- -

미디어 객체 방향 돌리기

- -

이미지가 오른쪽에 있고 콘텐츠가 왼쪽에 있도록 미디어 객체의 표시를 전환하려면 flex-direction 속성을 이용해 row-reverse로 설정할 수 있습니다. 미디어 개체가 이제 다른 방향으로 표시됩니다. 저는 그걸 달성하기 위해 라이브 예제에서 기존 .media 클래스와 함께 flipped 클래스를 추가했습니다. 즉, 에이치티엠엘에서 해당 클래스를 제거하여 디스플레이가 어떻게 변경되는지 확인할 수 있습니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/media-flipped.html", '100%', 650)}}

- -

양식 컨트롤

- -

가변상자는 양식 컨트롤에 스타일을 적용할 때 특히 유용합니다. 양식에는 일반적으로 서로 정렬하고 싶은 다수의 마크업과 다수의 작은 요소를 포함할 수 있습니다. 일반적인 패턴은 {{htmlelement("input")}} 요소가 {{htmlelement("button")}}과 짝을 이루는 검색 양식의 경우나 방문자가 단순히 전자 메일 주소를 입력하도록 하려는 경우입니다.

- -

가변상자를 사용하면 이러한 유형의 조판을 쉽게 달성할 수 있습니다. 테두리를 지정하고 표시하도록 설정한 래퍼 클래스에 <button><input> 필드가 포함되어 있습니다. 거기에 테두리를 부여하고 display: flex를 설정했습니다. 그런 다음 가변 속성을 사용하여 <input> 필드가 커지도록 했고, 버튼은 그렇지 않습니다. 이것은 사용 가능한 공간이 변함에 따라 텍스트 필드가 커지거나 작아지는 한 쌍의 필드가 있음을 의미합니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/input-button.html", '100%', 550)}}

- -

버튼을 오른쪽에 올려 놓은 것처럼 레이블이나 아이콘을 왼쪽에 쉽게 추가 할 수 있습니다. 나는 레이블을 추가했으며 배경색에 대한 스타일링 이외에 조판을 변경할 필요가 없었습니다. 신축성있는 입력 필드는 이제 맘대로 이용할 공간이 조금 줄어들지만 두 항목의 지분이 고려된 후 남은 공간을 사용합니다.

- -

{{EmbedGHLiveSample("css-examples/flexbox/use-cases/label-input-button.html", '100%', 550)}}

- -

이와 같은 패턴을 사용하면 디자인에 추가할 요소를 쉽게 수용할 수 있는 양식 요소 라이브러리를 훨씬 쉽게 만들 수 있습니다. 커지지 않는 항목과 커지는 항목을 혼합하는 식으로 가변상자의 유연성을 활용하고 있습니다.

- -

결론

- -

위의 패턴을 살펴보면서 가변 상자를 사용하여 원하는 결과를 얻는 가장 좋은 방법을 여러분이 생각을 통해 파악되기 시작했길 희망해봅니다. 종종 하나 이상의 선택이 있습니다. 늘릴 수 없는 항목을 늘릴 수 있는 것과 혼합하거나, 콘텐츠를 사용하여 크기를 알리거나, 가변상자가 공간을 비례적으로 공유할 수 있도록 하십시오. 그것은 당신에게 달려 있습니다.

- -

보유 컨텐츠를 제시하는 가장 좋은 방법을 생각한 다음 가변상자 또는 기타 조판 방법이 컨텐츠를 선보이는 데 어떻게 도움이 되는지 살펴보십시오.

diff --git a/files/ko/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html b/files/ko/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html new file mode 100644 index 0000000000..cc7753cb70 --- /dev/null +++ b/files/ko/web/css/css_flow_layout/block_and_inline_layout_in_normal_flow/index.html @@ -0,0 +1,122 @@ +--- +title: 일반 대열 속 블록 및 인라인 조판 +slug: Web/CSS/CSS_Flow_Layout/일반_흐름_속_블록_및_인라인_레이아웃 +tags: + - 대열 + - 씨에스에스 + - 씨에스에스 대열 조판 + - 안내서 + - 여백 + - 조판 + - 중급 +translation_of: Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow +--- +
{{CSSRef}}
+ +

이번 안내서에서는 블록 및 인라인 요소가 일반 대열의 일부일 때 어떻게 동작하는지에 대한 기본 사항을 살펴본다.

+ +

일반 대열은 씨에스에스 2.1규격에 정의되어 있으며, 이는 일반 대열에 소속된 상자가 서식 상황의 일부가 된다는 것을 설명한다. 그 상자는 블록 또는 인라인이 될 수 있지만 동시에 양수겸장이 될 수는 없다. 블록 수준 상자는 블록 서식 상황에 참여하는 것으로, 인라인 수준 상자는 인라인 서식 상황에 참여하는 것으로 기술한다.

+ +

블록 또는 인라인 서식 상황에 해당하는 요소의 동작은 이(CSS2.1) 규격에서 정의한다. 블록 형식 상황에 해당하는 요소의 경우 규격은 다음과 같다:

+ +
+

블록 서식 상황에서 상자는 컨테이너 블록의 맨 위에서 시작하여 수직으로 하나씩 배치된다. 두 형제(동급) 상자 사이 수직 간격은 '여백' 속성에 의해 결정된다. 블록 서식 상황에 속하는 인접하는 블록 수준 상자 사이 수직 여백은 축소된다.
+ 블록 서식 지정 상황에 속하는 각 상자의 왼쪽 바깥족 가장자리는 콘테이너 블록의 왼쪽 가장자리를 접한다. (오른쪽에서 왼쪽[아랍어] 방향 서식의 경우는 우측 가장자리를 접한다.)" - 9.4.1

+
+ +

인라인 서식 상황에 해당하는 요소의 경우:

+ +
+

인라인 서식 상황에서 상자는 콘테이너 블록의 상단에서 하나씩 차례로 수평으로 배치된다. 이 상자들 사이 수평 여백, 테두리 및 패딩은 준수된다. 상자는 다양한 방법으로 수직으로 정렬될 수 있다. 상자의 하단이나 상단에 맞춰 정렬되거나 텍스트의 기준선에 맞춰 정렬될 수 있다. 라인 형태를 띠는 여러 상자를 가두는 직사각형 영역을 라인 상자라고 한다. "- 9.4.2

+
+ +

씨에스에스 2.1 규격은 문서를 가로쓰기와 세로 쓰기 모드로 기술하고 있다. 예를 들어 블록 상자 사이의 수직 거리를 기술한다. 블록 및 인라인 요소의 동작 방식은 세로 쓰기 모드에서 동작할 때와 동일하다. 앞으로 게시될 대열 조판과 쓰기 모드에 관한 안내서에서 세로 쓰기 모드의 경우를 살펴볼 예정이다.

+ +

블록 서식 상황에 참여하는 요소

+ +

영어와 같은 가로쓰기 모드에서 블록 요소는 수직으로 다른 대상 요소 바로 밑에 배치된다.

+ +

+ +

세로 쓰기 모드에서는 수평으로 배치된다.

+ +

+ +

이 안내서에서 우리는 영어로 작업할 것이기 때문에 가로쓰기 모드를 다룬다. 그러나 기술된 내용 전체는 세로 쓰기 모드에서도 당연히 동일한 방식으로 작동한다.

+ +

씨에스에스 규격에 정의된 대로 2개의 블록 상자 사이 여백이 바로 상자 요소 사이를 구분해주는 것이다. 우리는 그점을 눈으로 확인하기 위해 2개의 단락으로 매우 간단한 하나의 조판에 테두리를 추가했다. 기본 브라우저의 스타일시트는 상하 요소에 여백을 더하는 방식으로 단락 사이 간격을 추가한다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow.html", '100%', 700)}}

+ +

단락 요소의 여백을 0으로 설정하면, 테두리는 접촉한다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-margin-zero.html", '100%', 700)}}

+ +

기본 설정에 따라 블록 요소는 인라인 방향에 포함된 모든 빈공간을 차지하므로 당해 단락은 펼쳐지면서 콘테이너 블록 내부를 최대한 차지할 수 있게 된다. 블록 너비를 적시하게 되면 옆 공간에 나란히 배치될 공간이 있다손치더라도 다른 대상 요소 바로 밑에 배치된다. 각 블록은 콘테이너 블록의 시작 가장자리에 맞춰 시작되며, 그 위치에 맞춰 해당 쓰기 모드에 포함되는 문장이 시작된다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-width.html", '100%', 700)}}

+ +

여백 축소

+ +

씨에스에스 규격에 따라 블록 요소 사이의 여백이 축소된다. 즉, 하단 여백이 있는 요소 바로 뒤에 상단 여백을 가진 요소가 있으면 두 여백의 합이 전체 공간이 되는게 아니라 여백이 축소되는데, 본질적으로 두 여백 중 더 큰 것으로 갈음한다.

+ +

아래의 예에 포함된 단락들은 20px의 상부 여백과 40px의 하부 여백을 갖고 있다. 단락 사이 여백의 크기는 40px이다. 왜냐면 두번째 단락의 상대적으로 작은 상부 여백이 첫번째 단락의 상대적으로 큰 하부 여백에 맞춰 축소되었기 때문이다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-collapsing.html", '100%', 500)}}

+ +

여백 축소에 관해선 여백 축소 정복 안내서에서 자세한 내용을 파악할 수 있다.

+ +
+

참고: 여백의 축소 여부가 불확실할 경우 브라우저 개발툴에 나오는 상자 모델 값을 확인하십시오. 이렇게 하면 현재 일어나고 일을 파악하는 데 도움이 될 수 있는 실제 여백 크기를 알 수 있습니다.

+ +

+
+ +

인라인 서식 상황에 참여하는 요소

+ +

인라인 요소는 특정 쓰기 모드에서 문장이 진행하는 방향으로 하나씩 차례대로 표시한다. 인라인 요소를 상자로 간주하지 않는 경향이 있지만 씨에스에스에 속하는 모든 요소처럼 그들도 상자로 간주된다. 이 인라인 상자들은 하나씩 차례대로 배열되어 있다. 컨테이너 블락에 상자 전체를 위한 충분한 공간이 없으면 새 줄로 넘어간다. 생성된 라인은 라인 상자라고 통용된다.

+ +

다음 예에서는 스트롱(strong) 요소를 내부에 포함하는 단락의 형태로 생성된 세개의 인라인 상자가 있다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/inline.html", '100%', 500)}}

+ +

strong 요소 전후로 단어를 감싼 상자들은 무명 상자라고 하며 모든 것이 상자로 둘러쳐 있음을 담보하기 위해 상자가 도입된 것이되 직접 대상화할 수 없는 요소이다.

+ +

블록 방향의 라인 상자의 크기는(영어 단락 작업시 글 높이의 경우)는 내부에 있는 가장 큰 상자에 의해 정의된다. 다음 예에서 나는 스트롱 요소의 크기를 300%로 만들었고, 이제 그 콘텐츠가 해당 선상의 라인 상자 높이를 정의한다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/line-box.html", '100%', 500)}}

+ +

블락과 인라인 상자의 동작 방식에 대해 자세한 내용은 시각적 서식 모델 안내서를 찾아보십시요.

+ +

display속성 및 대열 조판

+ +

씨에스에스 2.1에 존재하는 규칙 외에도 새로운 수준의 씨에스에스는 블록 및 인라인 상자의 동작을 추가로 기술한다. display 속성은 상자와 상자 속 상자의 동작 방법을 정의한다. 씨에스에스 디스플레이 모델 수준 3 내용을 보면 디스플레이 속성이 상자의 동작과 생성된 상자에 변화를 주는 방법에 대해 더 자세히 알 수 있다.

+ +

요소의 디스플레이 유형은 외부 디스플레이 유형을 정의하며, 이 외부 디스플레이 유형은 상자가 동일 서식 상황에 속한 다른 요소와 어떻게 병행 표시되는지를 지정한다. 또한, (씨에스에스 디스플레이 모델 수준 3을 보면) 이 요소 내부에 속한 상자가 작동하는 방식을 지정하는 내부 디스플레이 유형도 정의한다. 이런 내용은 가변(flex) 조판를 고려할 때 명확하게 확인할 수 있다. 아래 예제에서 나에게 display: flex를 적용한 div 요소 하나가 있다. 가변 컨테이너는 블록 요소처럼 동작한다. 새 줄에 표시되고 인라인 진행 방향에서 차지할 수 있는 모든 공간을을 차지한다. 이것은 block의 외부 디스플레이 유형이다.

+ +

그러나 가변 항목("Flex Item" 문자열 2개)은 가변 서식 상황에 참여하고 있다. 왜냐면 부모(class container)가 display: flex가 지정된 요소이고, 따라서 (상속에 의해) 내부 디스플레이 유형이 가변이므로 직계 자식의 경우 가변 서식 상황이 수립된다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/flex.html", '100%', 500)}}

+ +

따라서 씨에스에스에 포함된 모든 상자가 이런 식으로 작동한다고 간주할 수 있다. 상자 자체는 외부 디스플레이 유형도 갖고있기 때문에 다른 상자와 병행 동작하는 방법을 알고 있다. 그리고 상자는 내부 디스플레이 유형도 갖고있어 자식의 동작 방식도 변경한다. 이어 해당 자식은 외부 및 내부 디스플레이 유형도 갖게된다. 앞 예제에서 가변 항목("Flex Item" 문자열 2개)은 가변 수준 상자가 되며, 따라서 그것의 외부 디스플레이 유형은 그것들이 가변 서식 상황의 일부가 되는 방식에 의해 결정된다. 그들 항목은 대열 디스플레이 유형을 갖게 되는데, 그 의미는 자식이 일반 대열에 참여한다는 것을 의미한다. 당해 가변 항목 내부에 중첩된 항목('children' 'are in' 'normal flow')은 디스플레이 유형이 바뀌지 않는한 블록 및 인라인 요소로 배치된다.

+ +

외부 및 내부 디스플레이 유형이란 개념은 Flexbox(display: flex)와 Grid Layout(display: grid)과 같은 조판 메서드를 사용하는 컨테이너가 해당 메서드의 외부 디스플레이 유형이 block인 관계로 블록 및 인라인 조판에 계속해서 참여하고 있다는 것을 알려준다는 점에서 중요하다.

+ +

하나의 요소가 참여하는 대상의 서식 상황 변경

+ +

브라우저는 해당 요소의 통상적 타당성 여하에 따라 항목을 블록 또는 인라인 서식 맥락의 일부로 표시한다. 예들들면 단어를 강조를 강조하기 위해 스트롱 요소를 사용하며, 브라우저에 굵게 표시됩니다. 스트롱 요소가 블록 수준 요소로 표시되어 새 줄로 밀려나는 것은 일반적으로 타당하지 않다. 당신이 모든 스트롱 요소를 블록 요소로 표시하기를 원하면 당신은 strong 요소에 display: block를 설정함으로써 그렇게 할 수 있다. 즉, 항상 가장 의미론적으로 타당한 HTML 요소를 사용하여 콘텐츠를 표시한 다음 씨에스에스를 사용하여 표시되는 방식을 변경할 수 있다.

+ +

{{EmbedGHLiveSample("css-examples/flow/block-inline/change-formatting.html", '100%', 500)}}

+ +

요약정리

+ +

이번 안내서에서 우리는 블록 요소나 인라인 요소일 경우처럼 일반 대열속에서 요소가 어떻게 표시되는지 살펴보았다. 이러한 요소에 정해진 기본 동작이 있는 관계로 씨에스에스 스타일 지정이 전혀 없는 에이치티엠엘 문서가 읽기 가능한 방식으로 표시된다. 일반 대열의 작동 방식을 이해하면 조판이 더 쉬워지는 데 그 이유는 요소가 표시되는 방식을 변경하는 출발점을 이해하는 것이기 때문이다.

+ +

참조 항목

+ + diff --git a/files/ko/web/css/css_flow_layout/flow_layout_and_overflow/index.html b/files/ko/web/css/css_flow_layout/flow_layout_and_overflow/index.html new file mode 100644 index 0000000000..697bdfacde --- /dev/null +++ b/files/ko/web/css/css_flow_layout/flow_layout_and_overflow/index.html @@ -0,0 +1,73 @@ +--- +title: 대열 조판과 대열이탈 +slug: Web/CSS/CSS_Flow_Layout/흐름_레이아웃과_오버플로 +tags: + - 가시성 + - 대열 조판 + - 대열이탈 + - 씨에스에스 + - 안내서 + - 조판 + - 중급 + - 텍스트 대열이탈 +translation_of: Web/CSS/CSS_Flow_Layout/Flow_Layout_and_Overflow +--- +

컨테이너에 채울 수 없을 만큼 더 많은 내용물이 있을 때 오버플로 상황이 발생한다. CSS에서 크기 제한이 있는 요소를 다루려면 오버플로의 동작 방식을 이해하는 것이 중요하다. 이 안내서는 일반 플로우에 해당하는 작업 중에 오버플로이 작동하는 방식을 설명한다.

+ +

오버플로은 무엇인가?

+ +

어떤 요소에 고정 높이 및 너비를 부여한 다음, 상자에 상당한 내용물을 추가하면 기본적인 오버플로 사례가 만들어 진다.

+ +

{{EmbedGHLiveSample("css-examples/flow/overflow/overflow.html", '100%', 700)}}

+ +

내용물이 상자 안으로 들어간다. 상자가 채워지면, 눈에 보이게 오버플로이 계속되면서 상자 밖으로 내용물이 표시되고, 후속 내용물 아래에 표시될 가능성까지 있다. 오버플로 동작 방식을 통제하는 속성은 오버플로 속성으로 초기값은 visible로 되어 있다. 그런 까닭에 오버플로한 내용물를 볼 수 있다.

+ +

오버플로 통제

+ +

오버플로된 내용물이 동작하는 방식을 통제하는 그 밖의 값들이 있다. 오버플로된 내용물을 감추려면 hidden 값을 사용한다. 이 값은 내용물을 보이지 않게 만들 수도 있다.

+ +

{{EmbedGHLiveSample("css-examples/flow/overflow/hidden.html", '100%', 700)}}

+ +

scroll 값을 사용해서 상자의 내용물을 상자 안에 가둬두고 내용물을 볼 수 있게 스크롤 막대를 추가할 수 있다. 스크롤 막대는 내용물이 상자에 들어맞더라도 추가될 것이다.

+ +

{{EmbedGHLiveSample("css-examples/flow/overflow/scroll.html", '100%', 700)}}

+ +

auto 값을 사용하면 상자안에 내용물이 들어맞을 경우 스크롤 막대 없이 내용물을 표시하게 된다. 만일 내용물이 들어맞지 않는다면 스크롤 막대가 추가되게 된다. 다음 예를 overflow: scroll 경우의 예와 비교하면 수직 스크롤 막대가 필요할 경우에도 overflow scroll의 예는 수평 및 수직 스크롤 막대가 있음을 알수 있다. 아래 auto 예제에서는 우리가 스크롤이 필요한 방향으로만 스크롤 막대를 추가한다.

+ +

{{EmbedGHLiveSample("css-examples/flow/overflow/auto.html", '100%', 700)}}

+ +

이미 배운 바와 같이 기본값인 visible 이외에 살펴본 값 중의 어떤 값을 사용하게 되면 새로운 블록 서식 상황을 생성하게 된다.

+ +

참고: 작업 초안 오버플로 수준 3을 보면 추가적인 속성 값으로 overflow: clip이 있다. 이것은 overflow: hidden와 같이 작용하지만, 프로그래밍 방식의 스크롤이 불용되어 스크롤 할 수 상자가 된다. 또한, 이것은 블록 서식 상황을 생성하지 못한다.

+ +

오버플로 속성은 실제로는 overflow-xoverflow-y 속성의 약칭이다. 오버플로 값을 하나만 지정하면 이 값은 가로 세로 양 축에 모두 사용된다. 그러나 두 가지 값 모두를 지정할 수 있다. 첫번 째 경우에는 overflow-x를 수평 방향 값으로 두번째 경우에는 overflow-y를 수직 방향 값으로 사용하면 된다. 아래 예에서 나는 overflow-y: scroll만 지정함으로써 원치 않는 가로 스크롤 막대가 나타나지 않도록 했다.

+ +

{{EmbedGHLiveSample("css-examples/flow/overflow/overflow-y.html", '100%', 700)}}

+ +

상대적 플로우 속성

+ +

우리는 쓰기 모드와 플로우 레이아웃 안내서에서 block-sizeinline-size라는 새로운 속성를 살펴보았는데, 이 속성은 물리적인 화면 크기에 레이아웃을 구속하기보다는 다양한 쓰기 모드에서 작업할 경우에 적합하다. 수준 3 오버플로 모듈에는 플로우에 상대적인 오버플로 속성들overflow-blockoverflow-inline도 포함되어 있다. 그것들은 overflow-xoverflow-y에 대응하지만, 매핑은 문서의 쓰기 모드 여하에 달려 있다.

+ +

이들 속성은 현재 브라우저에 구현이 되어 있지 않으므로, 현 시점에는 물리적인 속성을 사용하고 쓰기 모드에 맞게 조정해야 한다.

+ +

오버플로 표시

+ +

수준 3 오버플로 규격에서 우리는 콘텐츠가 오버플로 상황에서 내용물이 보여지는 방식을 개선하도록 도움을 줄 수 있는 몇 가지 속성을 보유하고 있다.

+ +

인라인축 오버플로

+ +

text-overflow 속성은 인라인 방향의 텍스트 오버플로을 처리한다. 이 속성에는 두 가지 값 중에서 택일한다. clip의 경우는 오버플로하면 내용물이 잘려나간다. 이것이 초기값이므로 기본 동작이다. 또한, ellipsis의 경우는 줄임표를 렌더링하는 것인데, 사용 중인 언어와 쓰기 모드에 따라서는 더 나은 문자로 대체될 수도 있다.

+ +

{{EmbedGHLiveSample("css-examples/flow/overflow/text-overflow.html", '100%', 500)}}

+ +

블록축 오버플로

+ +

이 글의 작성 시점에 명칭을 두고 아직 논의의 여지가 있지만, block-overflow란 속성도 있다. 이 제안으로 텍스트가 블록 크기를 오버플로할 때 줄임표를 추가할 수 있게 된다.

+ +

이것은 예를 들어 문서 목록이 있고 제한된 양의 텍스트만 취하는 고정 높이 상자에 목록을 표시하는 경우에 유용하다. 상자나 제목을 클릭할 때 클릭할 내용이 더 많다는 것을 독자들이 인지하지 못할 수도 있다. 줄임표는 더 많은 내용이 있다는 사실을 분명하게 보여준다. 이 규격은 일련의 내용 또는 규칙적인 줄임표를 삽입할 수 있게 한다.

+ +

요약정리

+ +

웹 상의 연속적인 미디어에 있는지 또는 인쇄 또는 EPUB와 같은 페이징 미디어 형식에 있는지 여부는 어떤 레이아웃 메서드를 처리할 때 어떻게 내용물이 오버플로하게 되는지 이해를 돕는데 유용하다. 일반 대열에서 오버플로이 어떻게 작동하는지 이해함으로써 격자나 가변상자 같은 레이아웃 방식에 포함된 오버플로 내용물의 파장을 더 쉽게 이해할 수 있어야 한다.

+ +
{{QuickLinksWithSubpages("/ko/docs/Web/CSS/CSS_Flow_Layout/")}}
diff --git a/files/ko/web/css/css_flow_layout/flow_layout_and_writing_modes/index.html b/files/ko/web/css/css_flow_layout/flow_layout_and_writing_modes/index.html new file mode 100644 index 0000000000..4d35855ee5 --- /dev/null +++ b/files/ko/web/css/css_flow_layout/flow_layout_and_writing_modes/index.html @@ -0,0 +1,92 @@ +--- +title: 대열 조판과 쓰기 모드 +slug: Web/CSS/CSS_Flow_Layout/흐름_레이아웃과_쓰기_모드 +tags: + - 대열 조판 + - 쓰기모드 + - 씨에스에스 + - 안내서 + - 지향 +translation_of: Web/CSS/CSS_Flow_Layout/Flow_Layout_and_Writing_Modes +--- +

어떻게 일반 대열이 동작하는지 자세히 설명하는 씨에스에스 2.1 규격은 가로쓰기 모드라고 가정한다. 조판 속성은 세로 쓰기 모드에서 동일한 방식으로 작동해야 한다. 이 안내서는 서로 다른 문서 작성 모드에서 사용될 때 대열 조판이 어떻게 작동하는지 살펴 봅니다.

+ +

이것은 씨에스에스(CSS)에 포함된 쓰기 모드 사용에 대한 종합적인 안내서가 아니다. 이 글의 목적은 대열 조판이 쓰기 모드와 예상치 못한 방식으로 상호 작용하는 지점을 문서화하는 것이다. 이 문서의 참조 항목외부 리소스 섹션은 쓰기 모드 관련 더 많은 링크를 제공하고 있다.

+ +

쓰기 모드 규격

+ +

씨에스에스 쓰기 모드 수준 3 규격은 문서의 쓰기 모드가 대열 조판에 미치는 영향을 정의한다. 씨에스에스 쓰기 모드 소개란에서 전하는 규격은 다음과 같다.

+ +
+

씨에스에스에 포함되는 쓰기 모드는 {{cssxref("writing-mode")}}, {{cssxref("direction")}}, and {{cssxref("text-orientation")}} 속성에 의해 결정된다. 쓰기 모드는 주로 인라인 기준 방향과 블록 대열 방향 여하에 따라 정의된다."

+
+ +

쓰기 모드 규격은 내용물이 라인에 정렬되는 방향에 따라 인라인 기준 방향을 정의한다. 기준 방향이 인라인 방향의 시작과 끝을 정의한다. 인라인 방향의 시작은 문장이 시작되는 곳이고, 인라인 방향의 끝은 새 줄로 넘어가기 전에 텍스트가 끝나는 곳이 끝나는 곳이다.

+ +

블록 대열 방향은 예로 단락의 경우처럼 블록 쓰기 모드에서 상자를 쌓는 방향이다. 씨에스에스 쓰기 모드 속성은 블록 대열 방향을 제어한다. 페이지 또는 페이지의 일부를 vertical-lr로 변경하고 싶다면, 대상 요소에 writing-mode: vertical-lr를 설정할 수 있고, 이로써 블록의 방향을 변경하는 것이고 아울러 인라인 방향도 변경된다.

+ +

특정 언어일 경우 특정 쓰기 모드나 텍스트 방향을 사용하겠지만, 제목을 세로로 돌리는 등 창의적인 효과를 위해 그러한 속성을 사용할 수도 있다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/creative-use.html", '100%', 720)}}

+ +

writing-mode 속성 및 블록 대열

+ +

{{cssxref("writing-mode")}} 속성은 horizontal-tbvertical-rl, vertical-lr를 속성값으로 받는다. 이들 속성값은 페이지 상에 블록의 대열 방향을 제어한다. 초기 값은 horizontal-tb,로써 가로 인라인 방향이 포함된 상단에서 하단으로 가는 블록 대열 방향이다. 영어와 같이 왼쪽에서 오른쪽 방향 언어과 오른쪽에서 왼쪽 방향 언어인 아랍어의 경우든 모두가 horizontal-tb이다.

+ +

다음 예는 horizontal-tb를 사용하는 블록을 보여준다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/horizontal-tb.html", '100%', 720)}}

+ +

속성값 vertical-rl는 다음 예와 같이 세로 인라인 방향을 포함하는 오른쪽에서 왼쪽으로 가는 블록 대열 방향을 제공한다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/vertical-rl.html", '100%', 720)}}

+ +

마지막 예는 vertical-lr로써 세번 째로 가능한 writing-mode 속성값을 시연하고 있다. 이렇게 하면 왼쪽에서 오른쪽 블록 대열 방향과 세로 인라인 방향을 얻을 수 있다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/vertical-lr.html", '100%', 720)}}

+ +

부모와 다른 쓰기 모드를 가진 상자

+ +

중첩된 상자에 부모와 다른 쓰기 모드가 할당된 경우 인라인 수준 상자는 display: inline-block이 적용된 듯이 표시된다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/inline-change-mode.html", '100%', 720)}}

+ +

블록 수준 박스는 새로운 블록 서식 상황을 설정하게 되는데, 내부 디스플레이 유형이 flow일 경우 계산에 따른 디스플레이 유형인 flow-root를 얻게 된다는 뜻이다. 이것은 다음 예에서 보다시피 horizontal-tb 속성에 따라 표시되는 상자가 부동 요소를 포함하고 있는데, 그것이 포함된 까닭은 부모가 새로운 블록 대열 상황을 수립했기 때문이다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/block-change-mode.html", '100%', 720)}}

+ +

대체 요소

+ +

이미지와 같은 대체 요소는 writing-mode에 주어진 속성에 근거하여 (가로 세로) 쓰기 방향를 바꾸지 않는다. 그러나 텍스트를 포함하는 양식 컨트롤과 같은 대체 요소는 사용중인 쓰기 모드와 일치해야 한다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/replaced.html", '100%', 720)}}

+ +

논리적 속성 및 속성값

+ +

당신이 horizontal-tb 이외의 쓰기 모드에서 작업하게 될 경우, 스크린의 물리적 크기에 매핑되는 많은 속성 및 속성값들이 이상하게 보일 것이다. 예를 들면 상자에 100px을 부여하면 쓰기 모드가 horizontal-tb일 경우에 인라인 방향의 크기(100px)를 통제하게 된다. 쓰기 모드가 vertical-lr일 상황에서 상자가 텍스트에 맞춰 회전하지 않기 때문에 블록 방향 크기를 상자가 제어한다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/width.html", '100%', 720)}}

+ +

따라서 우리에게 {{cssxref("블록 크기")}} 및 {{cssxref("인라인 크기")}}라는 새로운 속성이 주어진다. 당해 블록에 inline-size를 100px 부여할 경우 가로쓰기 또는 세로 쓰기 모드 여부는 상관없어지며, inline-size일 경우 항상 인라인 방향의 크기를 의미하게 된다.

+ +

{{EmbedGHLiveSample("css-examples/flow/writing-modes/inline-size.html", '100%', 720)}}

+ +

씨에스에스 논리적 속성 규격은 여백, 패딩 및 테두리를 제어하는 속성의 논리적 버전뿐만 아니라 일반적으로 물리적 방향 지정을 위해 대상 요소에 전형적으로 사용되는 다른 매핑을 포함하고 있다.

+ +

요약정리

+ +

대부분의 경우, 문서의 쓰기 모드 또는 문서의 일부를 변경할 때 당신이 대상 요소에 기대하는 대로 대열 조판이 작동한다. 쓰기 모드는 세로 쓰기 언어를 올바르게 조판하거나 ​​독창적 표현을 이유로 사용할 수 있다. 씨에스에스는 세로 쓰기 모드에서 작업할 때 크기의 척도를 요소의 인라인과 블록 크기에 기초할 수 있도록 논리적 속성과 속성값을 도입하는 방식으로 간편한 설정을 가능케 해준다. 이런 내용은 다른 쓰기 모드에서 작동할 수 있는 구성 요소를 만들 경우에 유용할 것이다.

+ +

참조 항목

+ + + +

외부 리소스

+ + + +
{{QuickLinksWithSubpages("/ko/docs/Web/CSS/CSS_Flow_Layout/")}}
diff --git a/files/ko/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html b/files/ko/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html new file mode 100644 index 0000000000..2b05d99f39 --- /dev/null +++ b/files/ko/web/css/css_flow_layout/in_flow_and_out_of_flow/index.html @@ -0,0 +1,72 @@ +--- +title: 대열과 탈대열 +slug: Web/CSS/CSS_Flow_Layout/대열과_탈대열 +tags: + - 대열 + - 대열 조판 + - 씨에스에스 + - 씨에스에스 대열 조판 + - 안내서 + - 조판 + - 중급 +translation_of: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow +--- +
{{CSSRef}}
+ +

이전 안내서에서 제가 일반 대열 속 블록 및 인라인 조판에 대해 설명하였습니다. 대열에 속한 모든 요소는 이 메서드를 사용하여 배치됩니다.

+ +

다음 예제에서는 머리글, 단락, 목록 및 strong 요소가 포함된 마지막 단락이 있습니다. 머리글과 단락은 블록 레벨이며, strong 요소는 인라인입니다. 목록은 가변상자를 사용하여 항목을 행 내부로 정렬하지만 블록 및 인라인 조판에도 참여하고 있습니다. 컨테이너는 외곽에 display 유형이 block 대열에 참여하고 있습니다.

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/in-flow.html", '100%', 800)}}

+ +

요소 무리 전체는 대열에 속해 있다고 말할 수 있습니다. 에이치티엠엘 소스에 나타나는 순서대로 요소 무리들이 웹페이지에 등장합니다.

+ +

항목을 대열 밖으로 빼내기

+ +

대열에 속한 모든 요소는 다음과 구분된다:

+ + + +

대열에서 벗어난 항목은 새로운 블록 서식 상황(BFC)를 생성하므로, 그 안에 있는 모든 것은 페이지의 나머지 부분과는 구분되는 소형 조판으로 볼 수 있다. 따라서 뿌리 요소는 우리 문서의 모든 내용에 해당하는 컨테이너이기 때문에 대열을 벗어나 있으며 당 문서에 대한 블록 서식 상황을 수립합니다.

+ +

부동 항목

+ +

이 예제에서 나는 div를 가지고 있고, 그 다음 두 단락을 갖고 있다. 문단에 배경색을 추가한 다음 div 요소를 왼쪽으로 부동시켰다. 이제 div는 대열에서 벗어났다.

+ +

부동체는 우선 일반 대열에 속했던 애초의 위치를 기준으로 배치되었고, 그 뒤 대열에서 벗어나 최대한 왼쪽으로 이동합니다.

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/float.html", '100%', 800)}}

+ +

여러분은 부동체 밑에 펼쳐지고 있는 다음 단락의 배경색을 볼 수 있습니다. 동 단락의 라인 상자 무리만 부동체 주변 콘텐츠를 둘러싸는 효과를 위해 축소되었습니다. 우리 단락 형태의 상자는 여전히 일반 대열이라는 규칙에 따라 표시되고 있습니다. 바로 그런 까닭에 부동 항목 주위에 공간을 만들려면 동 항목에 여백을 추가해서 그 여백으로부터 라인 상자 무리를 밀려나도록 해야하는 겁니다. 대열에 속한 다음 순번 콘텐츠에는 그 어떤 것을 적용한다고 해도 그런 효과를 달성할 수 없습니다.

+ +

절대 위치잡기

+ +

어떤 항목에 position: absoluteposition: fixed를 부여하면 동 항목이 대열에서 제거되며, 그것이 점유하고 있던 모든 공간이 제거됩니다. 다음 예제에서 나는 세 개의 단락 요소를 가지고 있으며, 두 번째 요소는 positionabsolute임에 더해 간격띄우기 값이 top: 30pxright: 30px 해당됩니다. 그 (두 번째) 요소는 문서 대열에서 제거되었습니다.

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/abspos.html", '100%', 700)}}

+ +

position: fixed를 사용해 대열에서 항목을 제거하지만, 간격띄우기는 컨테이너 블록이 아닌 브라우저 뷰포트가 기준입니다.

+ +

위치잡기를 통해 대열에서 항목을 빼내면 콘텐츠의 중복 가능성을 관리해야 합니다. 대열에서 벗어나면 페이지의 다른 요소는 더 이상 요소가 존재한다는 것을 알지 못하므로 이에 반응하지 않습니다.

+ +

상대 위치잡기와 대열

+ +

어떤 항목에 position: relative 위치잡기를 부여하면 그것은 대열에 잔류하지만, 당신은 간격띄우기 값을 사용하여 동 항목을 주변으로 밀어낼 수 있습니다. 그러나 아래 예제에서 볼 수 있듯이 그것이 일반 대열 위치에 그대로 남아 있게 됩니다.

+ +

{{EmbedGHLiveSample("css-examples/flow/in-flow/relative.html", '100%', 800)}}

+ +

일반 대열에 속해 있었던 어떤 항목을 제거하거나 이동할 때, 해당 항목 주변의 콘텐츠를 겹치지 않도록 관리해야 할 필요성이 있다는 것을 예상할 수밖에 없을 겁니다. 말하자면 부동체를 정리하거나 position: absolute가 적용된 요소가 여타 콘텐츠에 올라타지 않도록 담보해야 합니다. 이러한 이유로 요소 무리를 대열 속에서 제거하는 메서드는 그들 메서드가 가져올 영향을 파악한 상태에서 사용되어야 합니다.

+ +

요약정리

+ +

이번 안내서에서는 매우 구체적인 유형의 위치잡기를 달성하기 위해 요소를 일반 대열에서 빼내는 여러 방법을 다루었습니다. 다음 안내서에서는 서식 상황 해설 가운데에서 블록 서식 상황을 생성하는 등의 관련 이슈를 살펴볼 겁니다.

+ +

참조 항목

+ + diff --git "a/files/ko/web/css/css_flow_layout/\353\214\200\354\227\264\352\263\274_\355\203\210\353\214\200\354\227\264/index.html" "b/files/ko/web/css/css_flow_layout/\353\214\200\354\227\264\352\263\274_\355\203\210\353\214\200\354\227\264/index.html" deleted file mode 100644 index 2b05d99f39..0000000000 --- "a/files/ko/web/css/css_flow_layout/\353\214\200\354\227\264\352\263\274_\355\203\210\353\214\200\354\227\264/index.html" +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: 대열과 탈대열 -slug: Web/CSS/CSS_Flow_Layout/대열과_탈대열 -tags: - - 대열 - - 대열 조판 - - 씨에스에스 - - 씨에스에스 대열 조판 - - 안내서 - - 조판 - - 중급 -translation_of: Web/CSS/CSS_Flow_Layout/In_Flow_and_Out_of_Flow ---- -
{{CSSRef}}
- -

이전 안내서에서 제가 일반 대열 속 블록 및 인라인 조판에 대해 설명하였습니다. 대열에 속한 모든 요소는 이 메서드를 사용하여 배치됩니다.

- -

다음 예제에서는 머리글, 단락, 목록 및 strong 요소가 포함된 마지막 단락이 있습니다. 머리글과 단락은 블록 레벨이며, strong 요소는 인라인입니다. 목록은 가변상자를 사용하여 항목을 행 내부로 정렬하지만 블록 및 인라인 조판에도 참여하고 있습니다. 컨테이너는 외곽에 display 유형이 block 대열에 참여하고 있습니다.

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/in-flow.html", '100%', 800)}}

- -

요소 무리 전체는 대열에 속해 있다고 말할 수 있습니다. 에이치티엠엘 소스에 나타나는 순서대로 요소 무리들이 웹페이지에 등장합니다.

- -

항목을 대열 밖으로 빼내기

- -

대열에 속한 모든 요소는 다음과 구분된다:

- - - -

대열에서 벗어난 항목은 새로운 블록 서식 상황(BFC)를 생성하므로, 그 안에 있는 모든 것은 페이지의 나머지 부분과는 구분되는 소형 조판으로 볼 수 있다. 따라서 뿌리 요소는 우리 문서의 모든 내용에 해당하는 컨테이너이기 때문에 대열을 벗어나 있으며 당 문서에 대한 블록 서식 상황을 수립합니다.

- -

부동 항목

- -

이 예제에서 나는 div를 가지고 있고, 그 다음 두 단락을 갖고 있다. 문단에 배경색을 추가한 다음 div 요소를 왼쪽으로 부동시켰다. 이제 div는 대열에서 벗어났다.

- -

부동체는 우선 일반 대열에 속했던 애초의 위치를 기준으로 배치되었고, 그 뒤 대열에서 벗어나 최대한 왼쪽으로 이동합니다.

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/float.html", '100%', 800)}}

- -

여러분은 부동체 밑에 펼쳐지고 있는 다음 단락의 배경색을 볼 수 있습니다. 동 단락의 라인 상자 무리만 부동체 주변 콘텐츠를 둘러싸는 효과를 위해 축소되었습니다. 우리 단락 형태의 상자는 여전히 일반 대열이라는 규칙에 따라 표시되고 있습니다. 바로 그런 까닭에 부동 항목 주위에 공간을 만들려면 동 항목에 여백을 추가해서 그 여백으로부터 라인 상자 무리를 밀려나도록 해야하는 겁니다. 대열에 속한 다음 순번 콘텐츠에는 그 어떤 것을 적용한다고 해도 그런 효과를 달성할 수 없습니다.

- -

절대 위치잡기

- -

어떤 항목에 position: absoluteposition: fixed를 부여하면 동 항목이 대열에서 제거되며, 그것이 점유하고 있던 모든 공간이 제거됩니다. 다음 예제에서 나는 세 개의 단락 요소를 가지고 있으며, 두 번째 요소는 positionabsolute임에 더해 간격띄우기 값이 top: 30pxright: 30px 해당됩니다. 그 (두 번째) 요소는 문서 대열에서 제거되었습니다.

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/abspos.html", '100%', 700)}}

- -

position: fixed를 사용해 대열에서 항목을 제거하지만, 간격띄우기는 컨테이너 블록이 아닌 브라우저 뷰포트가 기준입니다.

- -

위치잡기를 통해 대열에서 항목을 빼내면 콘텐츠의 중복 가능성을 관리해야 합니다. 대열에서 벗어나면 페이지의 다른 요소는 더 이상 요소가 존재한다는 것을 알지 못하므로 이에 반응하지 않습니다.

- -

상대 위치잡기와 대열

- -

어떤 항목에 position: relative 위치잡기를 부여하면 그것은 대열에 잔류하지만, 당신은 간격띄우기 값을 사용하여 동 항목을 주변으로 밀어낼 수 있습니다. 그러나 아래 예제에서 볼 수 있듯이 그것이 일반 대열 위치에 그대로 남아 있게 됩니다.

- -

{{EmbedGHLiveSample("css-examples/flow/in-flow/relative.html", '100%', 800)}}

- -

일반 대열에 속해 있었던 어떤 항목을 제거하거나 이동할 때, 해당 항목 주변의 콘텐츠를 겹치지 않도록 관리해야 할 필요성이 있다는 것을 예상할 수밖에 없을 겁니다. 말하자면 부동체를 정리하거나 position: absolute가 적용된 요소가 여타 콘텐츠에 올라타지 않도록 담보해야 합니다. 이러한 이유로 요소 무리를 대열 속에서 제거하는 메서드는 그들 메서드가 가져올 영향을 파악한 상태에서 사용되어야 합니다.

- -

요약정리

- -

이번 안내서에서는 매우 구체적인 유형의 위치잡기를 달성하기 위해 요소를 일반 대열에서 빼내는 여러 방법을 다루었습니다. 다음 안내서에서는 서식 상황 해설 가운데에서 블록 서식 상황을 생성하는 등의 관련 이슈를 살펴볼 겁니다.

- -

참조 항목

- - diff --git "a/files/ko/web/css/css_flow_layout/\354\235\274\353\260\230_\355\235\220\353\246\204_\354\206\215_\353\270\224\353\241\235_\353\260\217_\354\235\270\353\235\274\354\235\270_\353\240\210\354\235\264\354\225\204\354\233\203/index.html" "b/files/ko/web/css/css_flow_layout/\354\235\274\353\260\230_\355\235\220\353\246\204_\354\206\215_\353\270\224\353\241\235_\353\260\217_\354\235\270\353\235\274\354\235\270_\353\240\210\354\235\264\354\225\204\354\233\203/index.html" deleted file mode 100644 index cc7753cb70..0000000000 --- "a/files/ko/web/css/css_flow_layout/\354\235\274\353\260\230_\355\235\220\353\246\204_\354\206\215_\353\270\224\353\241\235_\353\260\217_\354\235\270\353\235\274\354\235\270_\353\240\210\354\235\264\354\225\204\354\233\203/index.html" +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: 일반 대열 속 블록 및 인라인 조판 -slug: Web/CSS/CSS_Flow_Layout/일반_흐름_속_블록_및_인라인_레이아웃 -tags: - - 대열 - - 씨에스에스 - - 씨에스에스 대열 조판 - - 안내서 - - 여백 - - 조판 - - 중급 -translation_of: Web/CSS/CSS_Flow_Layout/Block_and_Inline_Layout_in_Normal_Flow ---- -
{{CSSRef}}
- -

이번 안내서에서는 블록 및 인라인 요소가 일반 대열의 일부일 때 어떻게 동작하는지에 대한 기본 사항을 살펴본다.

- -

일반 대열은 씨에스에스 2.1규격에 정의되어 있으며, 이는 일반 대열에 소속된 상자가 서식 상황의 일부가 된다는 것을 설명한다. 그 상자는 블록 또는 인라인이 될 수 있지만 동시에 양수겸장이 될 수는 없다. 블록 수준 상자는 블록 서식 상황에 참여하는 것으로, 인라인 수준 상자는 인라인 서식 상황에 참여하는 것으로 기술한다.

- -

블록 또는 인라인 서식 상황에 해당하는 요소의 동작은 이(CSS2.1) 규격에서 정의한다. 블록 형식 상황에 해당하는 요소의 경우 규격은 다음과 같다:

- -
-

블록 서식 상황에서 상자는 컨테이너 블록의 맨 위에서 시작하여 수직으로 하나씩 배치된다. 두 형제(동급) 상자 사이 수직 간격은 '여백' 속성에 의해 결정된다. 블록 서식 상황에 속하는 인접하는 블록 수준 상자 사이 수직 여백은 축소된다.
- 블록 서식 지정 상황에 속하는 각 상자의 왼쪽 바깥족 가장자리는 콘테이너 블록의 왼쪽 가장자리를 접한다. (오른쪽에서 왼쪽[아랍어] 방향 서식의 경우는 우측 가장자리를 접한다.)" - 9.4.1

-
- -

인라인 서식 상황에 해당하는 요소의 경우:

- -
-

인라인 서식 상황에서 상자는 콘테이너 블록의 상단에서 하나씩 차례로 수평으로 배치된다. 이 상자들 사이 수평 여백, 테두리 및 패딩은 준수된다. 상자는 다양한 방법으로 수직으로 정렬될 수 있다. 상자의 하단이나 상단에 맞춰 정렬되거나 텍스트의 기준선에 맞춰 정렬될 수 있다. 라인 형태를 띠는 여러 상자를 가두는 직사각형 영역을 라인 상자라고 한다. "- 9.4.2

-
- -

씨에스에스 2.1 규격은 문서를 가로쓰기와 세로 쓰기 모드로 기술하고 있다. 예를 들어 블록 상자 사이의 수직 거리를 기술한다. 블록 및 인라인 요소의 동작 방식은 세로 쓰기 모드에서 동작할 때와 동일하다. 앞으로 게시될 대열 조판과 쓰기 모드에 관한 안내서에서 세로 쓰기 모드의 경우를 살펴볼 예정이다.

- -

블록 서식 상황에 참여하는 요소

- -

영어와 같은 가로쓰기 모드에서 블록 요소는 수직으로 다른 대상 요소 바로 밑에 배치된다.

- -

- -

세로 쓰기 모드에서는 수평으로 배치된다.

- -

- -

이 안내서에서 우리는 영어로 작업할 것이기 때문에 가로쓰기 모드를 다룬다. 그러나 기술된 내용 전체는 세로 쓰기 모드에서도 당연히 동일한 방식으로 작동한다.

- -

씨에스에스 규격에 정의된 대로 2개의 블록 상자 사이 여백이 바로 상자 요소 사이를 구분해주는 것이다. 우리는 그점을 눈으로 확인하기 위해 2개의 단락으로 매우 간단한 하나의 조판에 테두리를 추가했다. 기본 브라우저의 스타일시트는 상하 요소에 여백을 더하는 방식으로 단락 사이 간격을 추가한다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow.html", '100%', 700)}}

- -

단락 요소의 여백을 0으로 설정하면, 테두리는 접촉한다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-margin-zero.html", '100%', 700)}}

- -

기본 설정에 따라 블록 요소는 인라인 방향에 포함된 모든 빈공간을 차지하므로 당해 단락은 펼쳐지면서 콘테이너 블록 내부를 최대한 차지할 수 있게 된다. 블록 너비를 적시하게 되면 옆 공간에 나란히 배치될 공간이 있다손치더라도 다른 대상 요소 바로 밑에 배치된다. 각 블록은 콘테이너 블록의 시작 가장자리에 맞춰 시작되며, 그 위치에 맞춰 해당 쓰기 모드에 포함되는 문장이 시작된다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-width.html", '100%', 700)}}

- -

여백 축소

- -

씨에스에스 규격에 따라 블록 요소 사이의 여백이 축소된다. 즉, 하단 여백이 있는 요소 바로 뒤에 상단 여백을 가진 요소가 있으면 두 여백의 합이 전체 공간이 되는게 아니라 여백이 축소되는데, 본질적으로 두 여백 중 더 큰 것으로 갈음한다.

- -

아래의 예에 포함된 단락들은 20px의 상부 여백과 40px의 하부 여백을 갖고 있다. 단락 사이 여백의 크기는 40px이다. 왜냐면 두번째 단락의 상대적으로 작은 상부 여백이 첫번째 단락의 상대적으로 큰 하부 여백에 맞춰 축소되었기 때문이다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/normal-flow-collapsing.html", '100%', 500)}}

- -

여백 축소에 관해선 여백 축소 정복 안내서에서 자세한 내용을 파악할 수 있다.

- -
-

참고: 여백의 축소 여부가 불확실할 경우 브라우저 개발툴에 나오는 상자 모델 값을 확인하십시오. 이렇게 하면 현재 일어나고 일을 파악하는 데 도움이 될 수 있는 실제 여백 크기를 알 수 있습니다.

- -

-
- -

인라인 서식 상황에 참여하는 요소

- -

인라인 요소는 특정 쓰기 모드에서 문장이 진행하는 방향으로 하나씩 차례대로 표시한다. 인라인 요소를 상자로 간주하지 않는 경향이 있지만 씨에스에스에 속하는 모든 요소처럼 그들도 상자로 간주된다. 이 인라인 상자들은 하나씩 차례대로 배열되어 있다. 컨테이너 블락에 상자 전체를 위한 충분한 공간이 없으면 새 줄로 넘어간다. 생성된 라인은 라인 상자라고 통용된다.

- -

다음 예에서는 스트롱(strong) 요소를 내부에 포함하는 단락의 형태로 생성된 세개의 인라인 상자가 있다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/inline.html", '100%', 500)}}

- -

strong 요소 전후로 단어를 감싼 상자들은 무명 상자라고 하며 모든 것이 상자로 둘러쳐 있음을 담보하기 위해 상자가 도입된 것이되 직접 대상화할 수 없는 요소이다.

- -

블록 방향의 라인 상자의 크기는(영어 단락 작업시 글 높이의 경우)는 내부에 있는 가장 큰 상자에 의해 정의된다. 다음 예에서 나는 스트롱 요소의 크기를 300%로 만들었고, 이제 그 콘텐츠가 해당 선상의 라인 상자 높이를 정의한다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/line-box.html", '100%', 500)}}

- -

블락과 인라인 상자의 동작 방식에 대해 자세한 내용은 시각적 서식 모델 안내서를 찾아보십시요.

- -

display속성 및 대열 조판

- -

씨에스에스 2.1에 존재하는 규칙 외에도 새로운 수준의 씨에스에스는 블록 및 인라인 상자의 동작을 추가로 기술한다. display 속성은 상자와 상자 속 상자의 동작 방법을 정의한다. 씨에스에스 디스플레이 모델 수준 3 내용을 보면 디스플레이 속성이 상자의 동작과 생성된 상자에 변화를 주는 방법에 대해 더 자세히 알 수 있다.

- -

요소의 디스플레이 유형은 외부 디스플레이 유형을 정의하며, 이 외부 디스플레이 유형은 상자가 동일 서식 상황에 속한 다른 요소와 어떻게 병행 표시되는지를 지정한다. 또한, (씨에스에스 디스플레이 모델 수준 3을 보면) 이 요소 내부에 속한 상자가 작동하는 방식을 지정하는 내부 디스플레이 유형도 정의한다. 이런 내용은 가변(flex) 조판를 고려할 때 명확하게 확인할 수 있다. 아래 예제에서 나에게 display: flex를 적용한 div 요소 하나가 있다. 가변 컨테이너는 블록 요소처럼 동작한다. 새 줄에 표시되고 인라인 진행 방향에서 차지할 수 있는 모든 공간을을 차지한다. 이것은 block의 외부 디스플레이 유형이다.

- -

그러나 가변 항목("Flex Item" 문자열 2개)은 가변 서식 상황에 참여하고 있다. 왜냐면 부모(class container)가 display: flex가 지정된 요소이고, 따라서 (상속에 의해) 내부 디스플레이 유형이 가변이므로 직계 자식의 경우 가변 서식 상황이 수립된다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/flex.html", '100%', 500)}}

- -

따라서 씨에스에스에 포함된 모든 상자가 이런 식으로 작동한다고 간주할 수 있다. 상자 자체는 외부 디스플레이 유형도 갖고있기 때문에 다른 상자와 병행 동작하는 방법을 알고 있다. 그리고 상자는 내부 디스플레이 유형도 갖고있어 자식의 동작 방식도 변경한다. 이어 해당 자식은 외부 및 내부 디스플레이 유형도 갖게된다. 앞 예제에서 가변 항목("Flex Item" 문자열 2개)은 가변 수준 상자가 되며, 따라서 그것의 외부 디스플레이 유형은 그것들이 가변 서식 상황의 일부가 되는 방식에 의해 결정된다. 그들 항목은 대열 디스플레이 유형을 갖게 되는데, 그 의미는 자식이 일반 대열에 참여한다는 것을 의미한다. 당해 가변 항목 내부에 중첩된 항목('children' 'are in' 'normal flow')은 디스플레이 유형이 바뀌지 않는한 블록 및 인라인 요소로 배치된다.

- -

외부 및 내부 디스플레이 유형이란 개념은 Flexbox(display: flex)와 Grid Layout(display: grid)과 같은 조판 메서드를 사용하는 컨테이너가 해당 메서드의 외부 디스플레이 유형이 block인 관계로 블록 및 인라인 조판에 계속해서 참여하고 있다는 것을 알려준다는 점에서 중요하다.

- -

하나의 요소가 참여하는 대상의 서식 상황 변경

- -

브라우저는 해당 요소의 통상적 타당성 여하에 따라 항목을 블록 또는 인라인 서식 맥락의 일부로 표시한다. 예들들면 단어를 강조를 강조하기 위해 스트롱 요소를 사용하며, 브라우저에 굵게 표시됩니다. 스트롱 요소가 블록 수준 요소로 표시되어 새 줄로 밀려나는 것은 일반적으로 타당하지 않다. 당신이 모든 스트롱 요소를 블록 요소로 표시하기를 원하면 당신은 strong 요소에 display: block를 설정함으로써 그렇게 할 수 있다. 즉, 항상 가장 의미론적으로 타당한 HTML 요소를 사용하여 콘텐츠를 표시한 다음 씨에스에스를 사용하여 표시되는 방식을 변경할 수 있다.

- -

{{EmbedGHLiveSample("css-examples/flow/block-inline/change-formatting.html", '100%', 500)}}

- -

요약정리

- -

이번 안내서에서 우리는 블록 요소나 인라인 요소일 경우처럼 일반 대열속에서 요소가 어떻게 표시되는지 살펴보았다. 이러한 요소에 정해진 기본 동작이 있는 관계로 씨에스에스 스타일 지정이 전혀 없는 에이치티엠엘 문서가 읽기 가능한 방식으로 표시된다. 일반 대열의 작동 방식을 이해하면 조판이 더 쉬워지는 데 그 이유는 요소가 표시되는 방식을 변경하는 출발점을 이해하는 것이기 때문이다.

- -

참조 항목

- - diff --git "a/files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\223\260\352\270\260_\353\252\250\353\223\234/index.html" "b/files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\223\260\352\270\260_\353\252\250\353\223\234/index.html" deleted file mode 100644 index 4d35855ee5..0000000000 --- "a/files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\223\260\352\270\260_\353\252\250\353\223\234/index.html" +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: 대열 조판과 쓰기 모드 -slug: Web/CSS/CSS_Flow_Layout/흐름_레이아웃과_쓰기_모드 -tags: - - 대열 조판 - - 쓰기모드 - - 씨에스에스 - - 안내서 - - 지향 -translation_of: Web/CSS/CSS_Flow_Layout/Flow_Layout_and_Writing_Modes ---- -

어떻게 일반 대열이 동작하는지 자세히 설명하는 씨에스에스 2.1 규격은 가로쓰기 모드라고 가정한다. 조판 속성은 세로 쓰기 모드에서 동일한 방식으로 작동해야 한다. 이 안내서는 서로 다른 문서 작성 모드에서 사용될 때 대열 조판이 어떻게 작동하는지 살펴 봅니다.

- -

이것은 씨에스에스(CSS)에 포함된 쓰기 모드 사용에 대한 종합적인 안내서가 아니다. 이 글의 목적은 대열 조판이 쓰기 모드와 예상치 못한 방식으로 상호 작용하는 지점을 문서화하는 것이다. 이 문서의 참조 항목외부 리소스 섹션은 쓰기 모드 관련 더 많은 링크를 제공하고 있다.

- -

쓰기 모드 규격

- -

씨에스에스 쓰기 모드 수준 3 규격은 문서의 쓰기 모드가 대열 조판에 미치는 영향을 정의한다. 씨에스에스 쓰기 모드 소개란에서 전하는 규격은 다음과 같다.

- -
-

씨에스에스에 포함되는 쓰기 모드는 {{cssxref("writing-mode")}}, {{cssxref("direction")}}, and {{cssxref("text-orientation")}} 속성에 의해 결정된다. 쓰기 모드는 주로 인라인 기준 방향과 블록 대열 방향 여하에 따라 정의된다."

-
- -

쓰기 모드 규격은 내용물이 라인에 정렬되는 방향에 따라 인라인 기준 방향을 정의한다. 기준 방향이 인라인 방향의 시작과 끝을 정의한다. 인라인 방향의 시작은 문장이 시작되는 곳이고, 인라인 방향의 끝은 새 줄로 넘어가기 전에 텍스트가 끝나는 곳이 끝나는 곳이다.

- -

블록 대열 방향은 예로 단락의 경우처럼 블록 쓰기 모드에서 상자를 쌓는 방향이다. 씨에스에스 쓰기 모드 속성은 블록 대열 방향을 제어한다. 페이지 또는 페이지의 일부를 vertical-lr로 변경하고 싶다면, 대상 요소에 writing-mode: vertical-lr를 설정할 수 있고, 이로써 블록의 방향을 변경하는 것이고 아울러 인라인 방향도 변경된다.

- -

특정 언어일 경우 특정 쓰기 모드나 텍스트 방향을 사용하겠지만, 제목을 세로로 돌리는 등 창의적인 효과를 위해 그러한 속성을 사용할 수도 있다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/creative-use.html", '100%', 720)}}

- -

writing-mode 속성 및 블록 대열

- -

{{cssxref("writing-mode")}} 속성은 horizontal-tbvertical-rl, vertical-lr를 속성값으로 받는다. 이들 속성값은 페이지 상에 블록의 대열 방향을 제어한다. 초기 값은 horizontal-tb,로써 가로 인라인 방향이 포함된 상단에서 하단으로 가는 블록 대열 방향이다. 영어와 같이 왼쪽에서 오른쪽 방향 언어과 오른쪽에서 왼쪽 방향 언어인 아랍어의 경우든 모두가 horizontal-tb이다.

- -

다음 예는 horizontal-tb를 사용하는 블록을 보여준다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/horizontal-tb.html", '100%', 720)}}

- -

속성값 vertical-rl는 다음 예와 같이 세로 인라인 방향을 포함하는 오른쪽에서 왼쪽으로 가는 블록 대열 방향을 제공한다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/vertical-rl.html", '100%', 720)}}

- -

마지막 예는 vertical-lr로써 세번 째로 가능한 writing-mode 속성값을 시연하고 있다. 이렇게 하면 왼쪽에서 오른쪽 블록 대열 방향과 세로 인라인 방향을 얻을 수 있다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/vertical-lr.html", '100%', 720)}}

- -

부모와 다른 쓰기 모드를 가진 상자

- -

중첩된 상자에 부모와 다른 쓰기 모드가 할당된 경우 인라인 수준 상자는 display: inline-block이 적용된 듯이 표시된다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/inline-change-mode.html", '100%', 720)}}

- -

블록 수준 박스는 새로운 블록 서식 상황을 설정하게 되는데, 내부 디스플레이 유형이 flow일 경우 계산에 따른 디스플레이 유형인 flow-root를 얻게 된다는 뜻이다. 이것은 다음 예에서 보다시피 horizontal-tb 속성에 따라 표시되는 상자가 부동 요소를 포함하고 있는데, 그것이 포함된 까닭은 부모가 새로운 블록 대열 상황을 수립했기 때문이다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/block-change-mode.html", '100%', 720)}}

- -

대체 요소

- -

이미지와 같은 대체 요소는 writing-mode에 주어진 속성에 근거하여 (가로 세로) 쓰기 방향를 바꾸지 않는다. 그러나 텍스트를 포함하는 양식 컨트롤과 같은 대체 요소는 사용중인 쓰기 모드와 일치해야 한다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/replaced.html", '100%', 720)}}

- -

논리적 속성 및 속성값

- -

당신이 horizontal-tb 이외의 쓰기 모드에서 작업하게 될 경우, 스크린의 물리적 크기에 매핑되는 많은 속성 및 속성값들이 이상하게 보일 것이다. 예를 들면 상자에 100px을 부여하면 쓰기 모드가 horizontal-tb일 경우에 인라인 방향의 크기(100px)를 통제하게 된다. 쓰기 모드가 vertical-lr일 상황에서 상자가 텍스트에 맞춰 회전하지 않기 때문에 블록 방향 크기를 상자가 제어한다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/width.html", '100%', 720)}}

- -

따라서 우리에게 {{cssxref("블록 크기")}} 및 {{cssxref("인라인 크기")}}라는 새로운 속성이 주어진다. 당해 블록에 inline-size를 100px 부여할 경우 가로쓰기 또는 세로 쓰기 모드 여부는 상관없어지며, inline-size일 경우 항상 인라인 방향의 크기를 의미하게 된다.

- -

{{EmbedGHLiveSample("css-examples/flow/writing-modes/inline-size.html", '100%', 720)}}

- -

씨에스에스 논리적 속성 규격은 여백, 패딩 및 테두리를 제어하는 속성의 논리적 버전뿐만 아니라 일반적으로 물리적 방향 지정을 위해 대상 요소에 전형적으로 사용되는 다른 매핑을 포함하고 있다.

- -

요약정리

- -

대부분의 경우, 문서의 쓰기 모드 또는 문서의 일부를 변경할 때 당신이 대상 요소에 기대하는 대로 대열 조판이 작동한다. 쓰기 모드는 세로 쓰기 언어를 올바르게 조판하거나 ​​독창적 표현을 이유로 사용할 수 있다. 씨에스에스는 세로 쓰기 모드에서 작업할 때 크기의 척도를 요소의 인라인과 블록 크기에 기초할 수 있도록 논리적 속성과 속성값을 도입하는 방식으로 간편한 설정을 가능케 해준다. 이런 내용은 다른 쓰기 모드에서 작동할 수 있는 구성 요소를 만들 경우에 유용할 것이다.

- -

참조 항목

- - - -

외부 리소스

- - - -
{{QuickLinksWithSubpages("/ko/docs/Web/CSS/CSS_Flow_Layout/")}}
diff --git "a/files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\230\244\353\262\204\355\224\214\353\241\234/index.html" "b/files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\230\244\353\262\204\355\224\214\353\241\234/index.html" deleted file mode 100644 index 697bdfacde..0000000000 --- "a/files/ko/web/css/css_flow_layout/\355\235\220\353\246\204_\353\240\210\354\235\264\354\225\204\354\233\203\352\263\274_\354\230\244\353\262\204\355\224\214\353\241\234/index.html" +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: 대열 조판과 대열이탈 -slug: Web/CSS/CSS_Flow_Layout/흐름_레이아웃과_오버플로 -tags: - - 가시성 - - 대열 조판 - - 대열이탈 - - 씨에스에스 - - 안내서 - - 조판 - - 중급 - - 텍스트 대열이탈 -translation_of: Web/CSS/CSS_Flow_Layout/Flow_Layout_and_Overflow ---- -

컨테이너에 채울 수 없을 만큼 더 많은 내용물이 있을 때 오버플로 상황이 발생한다. CSS에서 크기 제한이 있는 요소를 다루려면 오버플로의 동작 방식을 이해하는 것이 중요하다. 이 안내서는 일반 플로우에 해당하는 작업 중에 오버플로이 작동하는 방식을 설명한다.

- -

오버플로은 무엇인가?

- -

어떤 요소에 고정 높이 및 너비를 부여한 다음, 상자에 상당한 내용물을 추가하면 기본적인 오버플로 사례가 만들어 진다.

- -

{{EmbedGHLiveSample("css-examples/flow/overflow/overflow.html", '100%', 700)}}

- -

내용물이 상자 안으로 들어간다. 상자가 채워지면, 눈에 보이게 오버플로이 계속되면서 상자 밖으로 내용물이 표시되고, 후속 내용물 아래에 표시될 가능성까지 있다. 오버플로 동작 방식을 통제하는 속성은 오버플로 속성으로 초기값은 visible로 되어 있다. 그런 까닭에 오버플로한 내용물를 볼 수 있다.

- -

오버플로 통제

- -

오버플로된 내용물이 동작하는 방식을 통제하는 그 밖의 값들이 있다. 오버플로된 내용물을 감추려면 hidden 값을 사용한다. 이 값은 내용물을 보이지 않게 만들 수도 있다.

- -

{{EmbedGHLiveSample("css-examples/flow/overflow/hidden.html", '100%', 700)}}

- -

scroll 값을 사용해서 상자의 내용물을 상자 안에 가둬두고 내용물을 볼 수 있게 스크롤 막대를 추가할 수 있다. 스크롤 막대는 내용물이 상자에 들어맞더라도 추가될 것이다.

- -

{{EmbedGHLiveSample("css-examples/flow/overflow/scroll.html", '100%', 700)}}

- -

auto 값을 사용하면 상자안에 내용물이 들어맞을 경우 스크롤 막대 없이 내용물을 표시하게 된다. 만일 내용물이 들어맞지 않는다면 스크롤 막대가 추가되게 된다. 다음 예를 overflow: scroll 경우의 예와 비교하면 수직 스크롤 막대가 필요할 경우에도 overflow scroll의 예는 수평 및 수직 스크롤 막대가 있음을 알수 있다. 아래 auto 예제에서는 우리가 스크롤이 필요한 방향으로만 스크롤 막대를 추가한다.

- -

{{EmbedGHLiveSample("css-examples/flow/overflow/auto.html", '100%', 700)}}

- -

이미 배운 바와 같이 기본값인 visible 이외에 살펴본 값 중의 어떤 값을 사용하게 되면 새로운 블록 서식 상황을 생성하게 된다.

- -

참고: 작업 초안 오버플로 수준 3을 보면 추가적인 속성 값으로 overflow: clip이 있다. 이것은 overflow: hidden와 같이 작용하지만, 프로그래밍 방식의 스크롤이 불용되어 스크롤 할 수 상자가 된다. 또한, 이것은 블록 서식 상황을 생성하지 못한다.

- -

오버플로 속성은 실제로는 overflow-xoverflow-y 속성의 약칭이다. 오버플로 값을 하나만 지정하면 이 값은 가로 세로 양 축에 모두 사용된다. 그러나 두 가지 값 모두를 지정할 수 있다. 첫번 째 경우에는 overflow-x를 수평 방향 값으로 두번째 경우에는 overflow-y를 수직 방향 값으로 사용하면 된다. 아래 예에서 나는 overflow-y: scroll만 지정함으로써 원치 않는 가로 스크롤 막대가 나타나지 않도록 했다.

- -

{{EmbedGHLiveSample("css-examples/flow/overflow/overflow-y.html", '100%', 700)}}

- -

상대적 플로우 속성

- -

우리는 쓰기 모드와 플로우 레이아웃 안내서에서 block-sizeinline-size라는 새로운 속성를 살펴보았는데, 이 속성은 물리적인 화면 크기에 레이아웃을 구속하기보다는 다양한 쓰기 모드에서 작업할 경우에 적합하다. 수준 3 오버플로 모듈에는 플로우에 상대적인 오버플로 속성들overflow-blockoverflow-inline도 포함되어 있다. 그것들은 overflow-xoverflow-y에 대응하지만, 매핑은 문서의 쓰기 모드 여하에 달려 있다.

- -

이들 속성은 현재 브라우저에 구현이 되어 있지 않으므로, 현 시점에는 물리적인 속성을 사용하고 쓰기 모드에 맞게 조정해야 한다.

- -

오버플로 표시

- -

수준 3 오버플로 규격에서 우리는 콘텐츠가 오버플로 상황에서 내용물이 보여지는 방식을 개선하도록 도움을 줄 수 있는 몇 가지 속성을 보유하고 있다.

- -

인라인축 오버플로

- -

text-overflow 속성은 인라인 방향의 텍스트 오버플로을 처리한다. 이 속성에는 두 가지 값 중에서 택일한다. clip의 경우는 오버플로하면 내용물이 잘려나간다. 이것이 초기값이므로 기본 동작이다. 또한, ellipsis의 경우는 줄임표를 렌더링하는 것인데, 사용 중인 언어와 쓰기 모드에 따라서는 더 나은 문자로 대체될 수도 있다.

- -

{{EmbedGHLiveSample("css-examples/flow/overflow/text-overflow.html", '100%', 500)}}

- -

블록축 오버플로

- -

이 글의 작성 시점에 명칭을 두고 아직 논의의 여지가 있지만, block-overflow란 속성도 있다. 이 제안으로 텍스트가 블록 크기를 오버플로할 때 줄임표를 추가할 수 있게 된다.

- -

이것은 예를 들어 문서 목록이 있고 제한된 양의 텍스트만 취하는 고정 높이 상자에 목록을 표시하는 경우에 유용하다. 상자나 제목을 클릭할 때 클릭할 내용이 더 많다는 것을 독자들이 인지하지 못할 수도 있다. 줄임표는 더 많은 내용이 있다는 사실을 분명하게 보여준다. 이 규격은 일련의 내용 또는 규칙적인 줄임표를 삽입할 수 있게 한다.

- -

요약정리

- -

웹 상의 연속적인 미디어에 있는지 또는 인쇄 또는 EPUB와 같은 페이징 미디어 형식에 있는지 여부는 어떤 레이아웃 메서드를 처리할 때 어떻게 내용물이 오버플로하게 되는지 이해를 돕는데 유용하다. 일반 대열에서 오버플로이 어떻게 작동하는지 이해함으로써 격자나 가변상자 같은 레이아웃 방식에 포함된 오버플로 내용물의 파장을 더 쉽게 이해할 수 있어야 한다.

- -
{{QuickLinksWithSubpages("/ko/docs/Web/CSS/CSS_Flow_Layout/")}}
diff --git a/files/ko/web/css/css_lists_and_counters/consistent_list_indentation/index.html b/files/ko/web/css/css_lists_and_counters/consistent_list_indentation/index.html new file mode 100644 index 0000000000..675b5127f3 --- /dev/null +++ b/files/ko/web/css/css_lists_and_counters/consistent_list_indentation/index.html @@ -0,0 +1,106 @@ +--- +title: Consistent List Indentation +slug: Consistent_List_Indentation +tags: + - CSS + - Guide + - NeedsUpdate +translation_of: Web/CSS/CSS_Lists_and_Counters/Consistent_list_indentation +--- +
{{CSSRef}}
+ +

가장 흔하게 리스트에 적용되는 스타일 변경은 들여쓰기(indentation)거리의 변경입니다 -- 즉, 리스트 아이텡을 오른쪽으로 얼마나 멀리 들여쓸것인가 라는것입니다. 이 작업은 가끔 한 브라우저에서 나오던 효과가 다른 브라우저에서는 같은 효과를 내지 못해서 애를 먹게하곤 합니다. 예를들면, 리스트가 왼쪽 마진을 갖지 못하도록 선언할 경우, 익스플로러에선 이동이되지만, Gecko기반의 브라우저에선 고집스럽게도 꼼짝않고 제 자리를 지키며 있는 그런 경우 입니다.

+ +

왜 이런 일이 일어나는 가를 이해하고 더 나아가 이러한 문제점을 피해나갈 방법을 이해하기 위해서, 리스트 형성에대한 세부과정을 검토하는 것이 필요합니다.

+ +

리스트 만들기

+ +

먼저, 한개의 단순한 리스트 아이템을 생각해봅시다. 이 리스트 아이템엔 아무런 마커(불렛이라고도 알려져 있습니다)도 없고, 아직 그자체로 어떤 리스트의 부분이 아닙니다. 그림 1에서 보이는 바와같이, 단순하고 아무 치장도 없는 채로 그냥 혼자 허공에 떠 있는 상태라고 할 수 있습니다.

+ +

Figure 1

+ +

빨간 점선으로된 경계선은 리스트 아이템의 내용물-지역의 바깥 경계를 나타내고 있습니다. 이 시점에서 리스트 아이템은 패딩이나 보더(경계)를 가지고 있지 않다는 점을 상기하십시오. 만약 2개의 리스트 아이템을 더 추가 한다면, 그림 2에 보여진 것과같은 결과를 얻게 될 것입니다.

+ +

Figure 2

+ +

이제 이 아이템들을 부모 엘리먼트로 랩핑(포장)합니다; 이 경우, 우리는 아이템들을 순서없는 리스트로 (즉, <ul>) 랩핑합니다. CSS 상자(박스) 모델에 의하면, 리스트 아이템들의 상자들은 부모 엘리먼트의 내용물-지역안에 디스플레이 되어야만 합니다. 이 부모 엘리먼트에 패딩이나 마진이 아직 없으므로 우리는 그림 3에 보여진 것과 같은 상황을 맞이하게 됩니다.

+ +

Figure 3

+ +

여기서, 푸른 점선 경계선은 <ul>엘리먼트의 내용물 지역의 경계를 보여줍니다. <ul>엘리먼트에 패딩이 없으므로 엘리먼트의 내용물은 세 리스트 아이템들을 촘촘하게 랩핑하게 됩니다.

+ +

이제, 리스트 아이템 마커를 추가합니다. 이 리스트는 순서가 없는 리스트이므로, 그림 4에 보여긴 것 같은 전통적인 채워진 원 불렛을 추가합니다.

+ +

Figure 4

+ +

보여지는 것으론, 마커들은 <ul>의 내용물-지역의바깥 에 있으나, 여기서 이점은 그다지 중요하지 않습니다. 중요한 점은 마커들이 <li>엘리먼트들의 "principal 상자"의 밖에 놓여진다는 점입니다. 이 마커들은 <lt>의 내용물-지역의 밖에 매달려 있으나 여전히 <li>에 부착되어있는 일종의 리스트 아이템들의 꼬리표같다고 할 수 있습니다.

+ +


+ 바로 이런 이유로, 윈도우의 익스플로러을 제외한 모든 브라우저에서, 마커들이 <li>엘리먼트에 지정된 보더밖에 놓이며, list-sytle-position값으로 outside를 취하게 되는 것입니다. 만일 값이 inside로 바뀌게 되면, 마커들은, 비록 <li>의 바로 시작부분에 놓여진 inline 상자임에도 불구하고, <li> 안쪽으로 옯겨지게 됩니다.

+ +

두번 들여쓰기

+ +

그럼 이 모든게 문서에서는 어떻게 나타날까요? 현재, 우리는 아래의 스타일들에 비견되는 상황에 있다고 할 수 있습니다.

+ +
ul, li {margin-left: 0; padding-left: 0;}
+ +

만일 이 리스트를 있는 그대로 문서에 삽입할 경우, 가시적 들여쓰기 효과는 나타나지 않고, 마커들은 브라우저 윈도우의 왼쪽끝으로 잘려나갈 상황에 처하게 될것입니다.

+ +

이를 피하고 들여쓰기효과를 얻을 목적으로 브라우저 개발자들에게 사용가능한 옵션은 다음의 세가지밖에 없습니다.

+ +
    +
  1. <li> 엘리먼트에 왼쪽 마진을 준다.
  2. +
  3. <ul> 엘리먼트에 왼쪽 마진을 준다.
  4. +
  5. <ul> 엘리먼트에 왼쪽 패딩을 준다.
  6. +
+ +

결과론적으로, 누구도 첫번째 옵션을 사용하지는 않는것 같습니다. 두번째 옵션은 윈도우 익스플로러, 매킨토쉬, 그리고 오페라에서 적용되었습니다. 세번째 옵션은 Gecko 와 범주상 이를 임베드해서 사용하는 모든 브라우저들에 적용되었다고 할 수 있습니다.

+ +

이 두 접근법에 대해서 잠깐 살펴봅시다. 익스플로러와 오페라의 경우, 리스트들은 <ul>에 40 픽셀의 왼쪽 마진을 줌으로써 들여쓰여지게 됩니다. 만일 <ul> 엘리먼트에 배경색을 적용하고 리스트 아이템과 <ul> 보더들을 그냥 놔둘 경우, 그림 5에서 보이는 것과 같은 결과를 얻게 됩니다.

+ +

Figure 5

+ +

반면, Gecko는 <ul> 엘리먼트에 대해서 40픽셀의 왼쪽패딩 을 줍니다. 따라서 그림 5를 만들어내는데 사용된 것과 똑 같은 스타일을 적용하게 된다고 가정하면, Gecko기반 브라우저로 예제를 로딩했을때 그림 6과 같은 그림을 보게 됩니다.

+ +

Figure 6

+ +

보이는 바와 같이, 마커들은, 어디에 있게 되건간에, <li> 엘리먼트에 붙여진 채로 남아 있습니다. 차이점은 전적으로 <ul>가 어떤식으로 스타일을 갖추게 되는가에 달려있습니다. 이 차이점은 <ul> 엘리먼트에 배경색이나 보더를 지정하려고 할 경우에만 나타나게 됩니다.

+ +

일관성 찾기

+ +

모든것을 정리해보면 이런 결론에 도달하게 됩니다. 즉, Gecko, 익스플로러, 그리고 오페라 간에 리스트을 일관성있게 렌더링하고 싶으면, <ul> 엘리먼트의 왼쪽 마진 그리고 왼쪽 패딩둘다 지정해야 한다는 것입니다. 이런 목적으로 <li> 을 아예 무시해 버릴 수도 있습니다. 넷스케이프 6.x 에서 디폴트 디스플레이로 돌아가고 싶다면:

+ +
ul {margin-left: 0; padding-left: 40px;}
+ +

만약, 익스플로러/오페라 모델을 따르길 원한다면:

+ +
ul {margin-left: 40px; padding-left: 0;}
+ +

라고 쓰면 됩니다.

+ +

물론, 자기 자신이 선호하는 값을 써 넣을 수도 있습니다. 원한다면 둘다 1.25em로 정해 줄 수도 있습니다 -- 픽셀에 기반한 들여쓰기에만 묶여있을 이유는 없습니다. 만일 리스트들이 들여쓰기를 하지 않도록 리셋하고 싶으면, 패딩과 마진 값을 0으로 정해 주어야만 합니다.

+ +
ul {margin-left: 0; padding-left: 0;}
+ +

하지만, 그렇게 하면, 불렛들이 리스트와 부모 엘리먼트의 바깥쪽에 매달려 있게 된다는 점을 기억하세요. 만일 body가 부모일 경우, 불렛이 브라우저 윈도우 밖으로 완전히 나가있게 되서, 보이지 않게 될 가능성이 아주 높습니다.

+ +

결론

+ +

결국, 여기에 언급된 브라우져들이 리스트를 레이아웃하는 방식에있어서 올바르거나 그르거나 하지 않다는 것을 알 수 있습니다. 각 브라우저는 다른 디폴트 스타일을 사용하고 있으며, 거기서 문제점들이 기어들어 오게 되는 것입니다. 리스트의 왼쪽 패딩과 왼쪽 마진 둘다를 확실하게 스타일 지정 함으로써 리스트 들여쓰기에 있어서 브라우저간 일관성을 보다 획기적으로 유지할 수 있게 되는 것입니다.

+ +

권장 사항

+ + + +
+

Original Document Information

+ + +
diff --git a/files/ko/web/css/css_masking/index.html b/files/ko/web/css/css_masking/index.html new file mode 100644 index 0000000000..5a48e0af6e --- /dev/null +++ b/files/ko/web/css/css_masking/index.html @@ -0,0 +1,68 @@ +--- +title: CSS Masking +slug: Web/CSS/CSS_Masks +tags: + - CSS + - CSS Masking + - Overview + - Reference +translation_of: Web/CSS/CSS_Masking +--- +
{{CSSRef}}
+ +

CSS Masking은 마스킹 및 클리핑을 포함해 시각 요소의 부분 또는 전체를 숨기기 위한 수단을 정의하는 CSS 모듈입니다.

+ +

참고서

+ +

속성

+ +
+ +
+ +

명세

+ + + + + + + + + + + + + + + + + + + + + +
명세상태설명
{{SpecName("CSS Masks")}}{{Spec2("CSS Masks")}} 
{{SpecName('SVG1.1', 'masking.html#MaskProperty', 'mask')}}{{Spec2('SVG1.1')}}초기 정의
+ +
 
diff --git a/files/ko/web/css/css_masks/index.html b/files/ko/web/css/css_masks/index.html deleted file mode 100644 index 5a48e0af6e..0000000000 --- a/files/ko/web/css/css_masks/index.html +++ /dev/null @@ -1,68 +0,0 @@ ---- -title: CSS Masking -slug: Web/CSS/CSS_Masks -tags: - - CSS - - CSS Masking - - Overview - - Reference -translation_of: Web/CSS/CSS_Masking ---- -
{{CSSRef}}
- -

CSS Masking은 마스킹 및 클리핑을 포함해 시각 요소의 부분 또는 전체를 숨기기 위한 수단을 정의하는 CSS 모듈입니다.

- -

참고서

- -

속성

- -
- -
- -

명세

- - - - - - - - - - - - - - - - - - - - - -
명세상태설명
{{SpecName("CSS Masks")}}{{Spec2("CSS Masks")}} 
{{SpecName('SVG1.1', 'masking.html#MaskProperty', 'mask')}}{{Spec2('SVG1.1')}}초기 정의
- -
 
diff --git a/files/ko/web/css/css_values_and_units/index.html b/files/ko/web/css/css_values_and_units/index.html new file mode 100644 index 0000000000..94d8ceabd6 --- /dev/null +++ b/files/ko/web/css/css_values_and_units/index.html @@ -0,0 +1,497 @@ +--- +title: CSS 단위와 값 +slug: Web/CSS/CSS_단위와_값 +tags: + - CSS + - 값과 단위 + - 안내서 + - 참조 +translation_of: Web/CSS/CSS_Values_and_Units +--- +
{{CSSRef}}
+ +

모든 CSS 선언은 속성 / 값 쌍을 포함합니다. 속성에 따라 값은 하나의 정수 또는 키워드, 여러 개의 키워드, 단위가 있거나 없는 값의 나열이 될 수 있습니다. CSS 속성에 허용되는 공통적인 자료형(단위와 값)의 집합이 있습니다. 아래는 이들 자료형 대부분에 대한 개요입니다. 더 자세한 정보를 보려면 각 자료형의 페이지를 참고하세요.

+ +

텍스트 자료형

+ + + +

텍스트 자료형은 <string>이거나, 연속된 문자를 따옴표로 감싼 것, 또는 따옴표로 감싸지 않은 "CSS 식별자"인 <ident>가 될 수 있습니다. <string>은 작은따옴표 또는 큰따옴표로 감싸져야 합니다. 사양에서 <ident> 또는 <custom-ident>의 목록에 포함되어 있는 CSS 식별자는 따옴표로 감싸서는 안 됩니다.

+ +

CSS 사양에서는 웹 개발자가 정의할 수 있는 값들, 가령 키프레임 애니메이션이나 서체 가족의 이름, 그리드 영역 같은 것들을 {{cssxref("<custom-ident>")}}, {{cssxref("<string>")}}, 또는 둘 다로서 목록에 표시합니다.

+ +

사용자가 정의한 텍스트 값을 따옴표로 감싸는 것과 감싸지 않는 것 모두가 허용되는 경우, 사양에서는 <custom-ident> | <string>로서 이를 목록에 표시하며, 이는 따옴표가 선택 사항임을 의미합니다. 애니메이션 이름이 바로 그런 경우입니다:

+ +
@keyframe validIdent {
+  /* keyframes go here */
+}
+@keyframe 'validString' {
+  /* keyframes go here */
+}
+ +

몇몇 텍스트 값은 따옴표로 감싸지 않는 경우 유효하지 않습니다. 예를 들어, {{cssxref("grid-area")}}의 값은 <custom-ident>일 수 있으므로, 만약 content라는 이름의 그리드 영역이 있을 때 아래처럼 이를 따옴표 없이 사용할 수 있습니다:

+ +
.item {
+  grid-area: content;
+}
+
+ +

반면, {{cssxref("<string>")}}인 자료형의 경우, 예를 들어 {{cssxref("content")}} 속성의 문자열 값은 따옴표로 감싸져야 합니다:

+ +
.item::after {
+    content: "This is my content.";
+}
+
+ +

일반적으로 이모지를 포함해 여러분이 원하는 아무 이름이나 만들 수 있지만, none, unset, initial, inherit, 숫자 또는 2개의 대시로 시작하는 이름은 식별자가 될 수 없으며, 대부분의 경우 미리 정의된 다른 CSS 키워드와 동일한 이름을 사용하고 싶지는 않을 것입니다. 더 자세한 내용을 보려면 {{cssxref("<custom-ident>")}}와 {{cssxref("<string>")}}의 참조 페이지를 확인하세요.

+ +

미리 정의된 키워드 값

+ +

미리 정의된 키워드 값은 특정 속성의 사양에 정의된 텍스트 값입니다. 이 키워드들은 CSS 식별자이기도 해서 따옴표 없이 사용됩니다.

+ +

CSS 사양 또는 MDN의 속성 페이지에서 CSS 속성의 값에 대한 문법을 보면, 허용되는 키워드가 아래와 같은 형태로 나열됩니다. 아래는 {{cssxref("float")}}에 허용되는 미리 정의된 키워드 값입니다.

+ +
left | right | none | inline-start | inline-end
+ +

이런 값들은 따옴표 없이 사용됩니다:

+ +
.box {
+    float: left;
+}
+
+ +

CSS 전체에 공유되는 값

+ +

한 속성의 사양의 일부로서 존재하는 미리 정의된 키워드와 더불어, 모든 CSS 속성은 CSS 전체에 걸쳐 공유되는 값인 {{cssxref("initial")}}, {{cssxref("inherit")}}, {{cssxref("unset")}}을 받아들일 수 있으며, 이들은 기본 동작을 명시적으로 지정합니다.

+ +

initial 키워드는 속성의 초기 값으로 지정된 값을 표현합니다. inherit 키워드는 해당 요소의 부모에 적용된 동일 속성의 계산값을 표현하며, 해당 속성이 상속된다고 가정합니다.

+ +

unset 키워드는 inherit 또는 initial처럼 동작하는데, 해당 속성이 상속되는 경우 전자, 아닌 경우 후자로 동작합니다.

+ +

네번째 값으로 {{cssxref("revert")}}가 Cascade Level 4 사양에 추가되었지만, 지금은 브라우저 지원 상태가 좋지 않습니다.

+ +

URL

+ +

{{cssxref("<url>")}} 자료형은 함수 표기법을 사용하며, 함수가 URL에 해당하는 <string>을 받는 형태입니다. 이것은 절대 URL 또는 상대 URL일 수 있습니다. 예를 들어, 배경 이미지를 넣고 싶을 때 다음 중 아무거나 사용할 수 있습니다.

+ +
.box {
+  background-image: url("images/my-background.png");
+}
+
+.box {
+  background-image: url("https://www.exammple.com/images/my-background.png");
+}
+
+ +

url() 의 매개변수는 따옴표로 감싸거나 감싸지 않을 수 있습니다. 감싸지 않는 경우, 이는 <url-token>으로 해석되어 특정 문자를 이스케이프하는 등의 추가적인 할 일이 생깁니다. 더 자세한 내용을 보려면 {{cssxref("<url>")}}를 확인하세요.

+ +

숫자 자료형

+ + + +

정수

+ +

정수는 1개 이상의 10진수 숫자(0부터 9)로, 예를 들어 1024나 -55가 이에 속합니다. 정수 앞에는 + 또는 - 기호를 덧붙일 수 있는데, 기호와 정수 사이에 공백이 없어야 합니다.

+ +

숫자

+ +

{{cssxref("<number>")}}는 실수를 나타내며, 소수점과 소수부분을 포함할 수도 있고 포함하지 않을 수도 있습니다. 예를 들어 0.255, 128-1.2가 이에 속합니다. 숫자 앞에도 +나 - 기호를 덧붙일 수 있습니다.

+ +

치수

+ +

{{cssxref("<dimension>")}}은 <number>에 단위를 붙인 것으로, 예를 들면 45deg, 100ms10px가 이에 속합니다. 덧붙인 단위 식별자는 대소문자를 구별하지 않습니다. 숫자와 단위 식별자 사이에는 공백 또는 다른 문자가 들어갈 수 없습니다: 즉, 1 cm는 유효하지 않습니다.

+ +

CSS는 치수를 사용해 아래와 같은 것들을 표시합니다:

+ + + +

다음 절에서 이것들을 다룹니다.

+ +

거리 단위

+ +

거리 단위, 또는 길이가 값으로 허용되는 속성은 {{cssxref("<length>")}} 자료형으로 표시됩니다. CSS에는 2가지 종류의 길이가 있습니다: 상대적 길이와 절대적 길이입니다.

+ +

상대적 길이 단위는 다른 무언가와 비교해 상대적인 길이를 나타냅니다. 예를 들어, em은 해당 요소의 폰트 크기에 상대적이며 vh는 뷰포트의 높이에 상대적입니다.

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

상대적 길이 단위들

+
단위비교의 대상
em해당 요소의 폰트 크기
ex해당 요소의 폰트의 x높이
cap해당 요소의 폰트의 대문자 높이(대문자의 공칭 높이)
ch해당 요소의 폰트의 좁은 문자가 평균적으로 나아가는 길이, “0” (ZERO, U+0030) 문자로 대표됨.
ic해당 요소의 폰트의 전각 문자가 평균적으로 나아가는 길이, “水” (CJK 물 표의 문자, U+6C34) 문자로 대표됨.
rem루트 요소의 폰트 크기
lh해당 요소의 줄 높이
rlh루트 요소의 줄 높이
vw뷰포트 너비의 1%
vh뷰포트 높이의 1%
vi루트 요소의 인라인 축 방향으로 뷰포트 길이의 1%
vb루트 요소의 블록 축 방향으로 뷰포트 길이의 1%
vmin뷰포트의 길이 중 더 짧은 것의 1%
vmax뷰포트의 길이 중 더 긴 것의 1%
+ +

절대적 길이 단위는 인치 또는 센티미터의 물리적 길이로 고정적입니다. 그래서 이 단위들의 다수는 인쇄물과 같은 고정된 크기의 매체로 출력되는 경우에 유용합니다. 예를 들어, mm는 물리적인 밀리미터, 즉 센티미터의 1/10입니다.

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

절대적 길이 단위

+
단위이름다음과 동일함
cm센티미터1cm = 96px/2.54
mm밀리미터1mm = 1cm의 1/10
Q쿼터-밀리미터1Q = 1cm의 1/40
in인치1in = 2.54cm = 96px
pc피카1pc = 1in의 1/16
pt포인트1pt = 1in의 1/72
px픽셀1px = 1in의 1/96
+ +

길이 값을 포함할 때 길이가 0이면, 단위 식별자가 필요하지 않습니다. 그 외의 경우 단위 식별자가 필요합니다. 단위 식별자는 대소문자를 구별하지 않으며, 값의 숫자 부분 이후에 공백 없이 바로 나와야 합니다.

+ +

각도 단위

+ +

각도 값은 {{cssxref("<angle>")}} 자료형으로 표시되며 다음의 값이 허용됩니다:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
단위이름설명
deg360도가 완전한 원을 이룹니다.
grad그라디안400 그라디안이 완전한 원을 이룹니다.
rad라디안2π 라디안이 완전한 원을 이룹니다.
turn1턴이 완전한 원을 이룹니다.
+ +

시간 단위

+ +

시간 단위는 {{cssxref("<time>")}} 자료형으로 표시됩니다. 시간 단위를 포함할 때는 단위 식별자인 s 또는 ms가 반드시 필요합니다. 아래의 값이 허용됩니다.

+ + + + + + + + + + + + + + + + + + + + + +
단위이름설명
s
ms밀리초1,000 밀리초는 1초와 같습니다.
+ +

진동수 단위

+ +

진동수 단위는 {{cssxref("<frequency>")}} 자료형으로 표시됩니다. 아래 값이 허용됩니다.

+ + + + + + + + + + + + + + + + + + + + + +
단위이름설명
Hz헤르츠1초당 발생한 횟수를 나타냅니다.
kHz킬로헤르츠1 킬로헤르츠는 1000 헤르츠와 같습니다.
+ +

1Hz, 또는 1hz1HZ는 초당 진동수입니다.

+ +

해상도 단위

+ +

해상도 단위는 {{cssxref("<resolution>")}}로 표시됩니다. 이것들은 스크린과 같은 그래픽 표시에서 CSS 인치당, 센티미터당, 픽셀당 몇 개의 점을 포함할 수 있는지를 나타냄으로써 점 1개의 크기를 표현합니다. 다음의 값이 허용됩니다:

+ + + + + + + + + + + + + + + + + + + + + + +
단위설명
dpi인치당 점의 수.
dpcm센티미터당 점의 수.
dppx, x픽셀당 점의 수.
+ +

퍼센트

+ +

{{cssxref("<percentage>")}}는 다른 값의 일부분을 표현하는 자료형입니다.

+ +

퍼센트 값은 언제나 다른 양, 예컨대 길이와 같은 것에 상대적입니다. 퍼센트를 허용하는 속성은 그 퍼센트가 참조하는 양 또한 정의합니다. 이 양은 같은 요소가 갖는 다른 속성의 값이거나, 조상 요소가 갖는 속성의 값이거나, 이 요소를 포함하는 블록의 치수 등이 될 수 있습니다.

+ +

예를 들면, 어떤 박스의 {{cssxref("width")}}를 퍼센트로 지정한 경우, 그 박스의 부모의 계산된 너비의 퍼센트를 참조합니다:

+ +
.box {
+  width: 50%;
+}
+ +

퍼센트와 치수 함께 사용하기

+ +

일부 속성은 두 자료형 중 하나를 선택해서, 예를 들면 <length> 또는 <percentage>를 골라서 치수를 지정할 수 있습니다. 이 경우 사양에는 허용되는 값이 {{cssxref("<length-percentage>")}}처럼 조합된 단위로 기술됩니다. 다음은 가능한 다른 조합입니다:

+ + + +

특별한 자료형 (다른 사양에서 정의된 것들)

+ + + +

색깔

+ +

{{cssxref("<color>")}} 값은 요소의 외관 색깔(예: 배경색)을 지정하며, CSS Color Module에 정의되어 있습니다.

+ +

이미지

+ +

{{cssxref("<image>")}} 값은 CSS에서 사용될 수 있는 다양한 종류의 이미지를 지정하며, CSS Image Values and Replaced Content Module에 정의되어 있습니다.

+ +

위치

+ +

{{cssxref("<position>")}} 자료형은 배치 영역 안에서 객체의 2D 위치를, 예컨대 컨테이너 안에서 배경 이미지의 위치 같은 것을 정의합니다. 이 자료형은 {{cssxref("background-position")}}으로 해석되므로 CSS Backgrounds and Borders specification에 명시되어 있습니다.

+ +

함수 표기법

+ + + +

함수 표기법은 더 복잡한 자료형을 표현하거나 CSS가 특별한 처리를 하도록 지시하는 자료형의 값입니다. 이 문법은 함수의 이름으로 시작해서 바로 왼쪽 괄호 (가 뒤따르고, 함수의 인자를 나열한 다음, 오른쪽 괄호 )로 끝납니다. 함수는 여러 개의 인자를 받을 수 있으며, CSS 속성 값과 비슷한 형식을 가집니다.

+ +

공백 문자는 허용되지만, 괄호 안에서는 선택 사항입니다. (단 min(), max()clamp() 함수 페이지의 주의 사항에서 공백 문자에 대한 내용을 확인하세요.)

+ +

rgba()와 같은 몇몇 레거시 함수 표기법이 콤마를 사용하지만, 일반적으로 콤마는 목록에서 아이템을 구분하기 위해 사용됩니다. 콤마가 인자를 구분하기 위해 사용된 경우, 콤마 전후의 공백 문자는 선택 사항입니다.

+ +

사양

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
사양상태비고
{{SpecName("CSS4 Values")}}{{Spec2("CSS4 Values")}}vi, vb, ic, cap, lhrlh 단위 추가.
+ min(), max()clamp() 함수 표기법 추가
+ toggle() 추가
{{SpecName("CSS3 Values")}}{{Spec2("CSS3 Values")}}calc()chremvwvwvminvmaxQ 추가
{{SpecName("CSS4 Colors")}}{{Spec2("CSS4 Colors")}}rgb()rgba()hsl()hsla() 함수에 콤마 없는 문법 추가. rgb()와 hsl()에 알파 값 허용하며 rgba()와 hsla()를 그것들의 (지원이 중단된) 별칭으로 전환.
+ 색깔 키워드 rebeccapurple 추가. 4자리와 8자리의 16진수 색깔 값 추가, 마지막 숫자(들)이 알파 값을 의미함.
+ hwb()device-cmyk()color() 함수 추가.
{{SpecName("CSS3 Colors")}}{{Spec2("CSS3 Colors")}}system-colors를 지원 중단으로 표시. SVG 색깔 추가. rgba()hsl()hsla() 함수 추가.
{{SpecName("CSS4 Images")}}{{Spec2("CSS4 Images")}} +

element(), image(), image-set(), conic-gradient() 추가

+
{{SpecName("CSS3 Images")}}{{Spec2("CSS3 Images")}}이미지를 처음으로 정의함.
{{SpecName("CSS2.1")}}{{Spec2("CSS2.1")}}
{{SpecName("CSS1")}}{{Spec2("CSS1")}}첫번째 정의.
+ +

같이 보기

+ + diff --git "a/files/ko/web/css/css_\353\213\250\354\234\204\354\231\200_\352\260\222/index.html" "b/files/ko/web/css/css_\353\213\250\354\234\204\354\231\200_\352\260\222/index.html" deleted file mode 100644 index 94d8ceabd6..0000000000 --- "a/files/ko/web/css/css_\353\213\250\354\234\204\354\231\200_\352\260\222/index.html" +++ /dev/null @@ -1,497 +0,0 @@ ---- -title: CSS 단위와 값 -slug: Web/CSS/CSS_단위와_값 -tags: - - CSS - - 값과 단위 - - 안내서 - - 참조 -translation_of: Web/CSS/CSS_Values_and_Units ---- -
{{CSSRef}}
- -

모든 CSS 선언은 속성 / 값 쌍을 포함합니다. 속성에 따라 값은 하나의 정수 또는 키워드, 여러 개의 키워드, 단위가 있거나 없는 값의 나열이 될 수 있습니다. CSS 속성에 허용되는 공통적인 자료형(단위와 값)의 집합이 있습니다. 아래는 이들 자료형 대부분에 대한 개요입니다. 더 자세한 정보를 보려면 각 자료형의 페이지를 참고하세요.

- -

텍스트 자료형

- - - -

텍스트 자료형은 <string>이거나, 연속된 문자를 따옴표로 감싼 것, 또는 따옴표로 감싸지 않은 "CSS 식별자"인 <ident>가 될 수 있습니다. <string>은 작은따옴표 또는 큰따옴표로 감싸져야 합니다. 사양에서 <ident> 또는 <custom-ident>의 목록에 포함되어 있는 CSS 식별자는 따옴표로 감싸서는 안 됩니다.

- -

CSS 사양에서는 웹 개발자가 정의할 수 있는 값들, 가령 키프레임 애니메이션이나 서체 가족의 이름, 그리드 영역 같은 것들을 {{cssxref("<custom-ident>")}}, {{cssxref("<string>")}}, 또는 둘 다로서 목록에 표시합니다.

- -

사용자가 정의한 텍스트 값을 따옴표로 감싸는 것과 감싸지 않는 것 모두가 허용되는 경우, 사양에서는 <custom-ident> | <string>로서 이를 목록에 표시하며, 이는 따옴표가 선택 사항임을 의미합니다. 애니메이션 이름이 바로 그런 경우입니다:

- -
@keyframe validIdent {
-  /* keyframes go here */
-}
-@keyframe 'validString' {
-  /* keyframes go here */
-}
- -

몇몇 텍스트 값은 따옴표로 감싸지 않는 경우 유효하지 않습니다. 예를 들어, {{cssxref("grid-area")}}의 값은 <custom-ident>일 수 있으므로, 만약 content라는 이름의 그리드 영역이 있을 때 아래처럼 이를 따옴표 없이 사용할 수 있습니다:

- -
.item {
-  grid-area: content;
-}
-
- -

반면, {{cssxref("<string>")}}인 자료형의 경우, 예를 들어 {{cssxref("content")}} 속성의 문자열 값은 따옴표로 감싸져야 합니다:

- -
.item::after {
-    content: "This is my content.";
-}
-
- -

일반적으로 이모지를 포함해 여러분이 원하는 아무 이름이나 만들 수 있지만, none, unset, initial, inherit, 숫자 또는 2개의 대시로 시작하는 이름은 식별자가 될 수 없으며, 대부분의 경우 미리 정의된 다른 CSS 키워드와 동일한 이름을 사용하고 싶지는 않을 것입니다. 더 자세한 내용을 보려면 {{cssxref("<custom-ident>")}}와 {{cssxref("<string>")}}의 참조 페이지를 확인하세요.

- -

미리 정의된 키워드 값

- -

미리 정의된 키워드 값은 특정 속성의 사양에 정의된 텍스트 값입니다. 이 키워드들은 CSS 식별자이기도 해서 따옴표 없이 사용됩니다.

- -

CSS 사양 또는 MDN의 속성 페이지에서 CSS 속성의 값에 대한 문법을 보면, 허용되는 키워드가 아래와 같은 형태로 나열됩니다. 아래는 {{cssxref("float")}}에 허용되는 미리 정의된 키워드 값입니다.

- -
left | right | none | inline-start | inline-end
- -

이런 값들은 따옴표 없이 사용됩니다:

- -
.box {
-    float: left;
-}
-
- -

CSS 전체에 공유되는 값

- -

한 속성의 사양의 일부로서 존재하는 미리 정의된 키워드와 더불어, 모든 CSS 속성은 CSS 전체에 걸쳐 공유되는 값인 {{cssxref("initial")}}, {{cssxref("inherit")}}, {{cssxref("unset")}}을 받아들일 수 있으며, 이들은 기본 동작을 명시적으로 지정합니다.

- -

initial 키워드는 속성의 초기 값으로 지정된 값을 표현합니다. inherit 키워드는 해당 요소의 부모에 적용된 동일 속성의 계산값을 표현하며, 해당 속성이 상속된다고 가정합니다.

- -

unset 키워드는 inherit 또는 initial처럼 동작하는데, 해당 속성이 상속되는 경우 전자, 아닌 경우 후자로 동작합니다.

- -

네번째 값으로 {{cssxref("revert")}}가 Cascade Level 4 사양에 추가되었지만, 지금은 브라우저 지원 상태가 좋지 않습니다.

- -

URL

- -

{{cssxref("<url>")}} 자료형은 함수 표기법을 사용하며, 함수가 URL에 해당하는 <string>을 받는 형태입니다. 이것은 절대 URL 또는 상대 URL일 수 있습니다. 예를 들어, 배경 이미지를 넣고 싶을 때 다음 중 아무거나 사용할 수 있습니다.

- -
.box {
-  background-image: url("images/my-background.png");
-}
-
-.box {
-  background-image: url("https://www.exammple.com/images/my-background.png");
-}
-
- -

url() 의 매개변수는 따옴표로 감싸거나 감싸지 않을 수 있습니다. 감싸지 않는 경우, 이는 <url-token>으로 해석되어 특정 문자를 이스케이프하는 등의 추가적인 할 일이 생깁니다. 더 자세한 내용을 보려면 {{cssxref("<url>")}}를 확인하세요.

- -

숫자 자료형

- - - -

정수

- -

정수는 1개 이상의 10진수 숫자(0부터 9)로, 예를 들어 1024나 -55가 이에 속합니다. 정수 앞에는 + 또는 - 기호를 덧붙일 수 있는데, 기호와 정수 사이에 공백이 없어야 합니다.

- -

숫자

- -

{{cssxref("<number>")}}는 실수를 나타내며, 소수점과 소수부분을 포함할 수도 있고 포함하지 않을 수도 있습니다. 예를 들어 0.255, 128-1.2가 이에 속합니다. 숫자 앞에도 +나 - 기호를 덧붙일 수 있습니다.

- -

치수

- -

{{cssxref("<dimension>")}}은 <number>에 단위를 붙인 것으로, 예를 들면 45deg, 100ms10px가 이에 속합니다. 덧붙인 단위 식별자는 대소문자를 구별하지 않습니다. 숫자와 단위 식별자 사이에는 공백 또는 다른 문자가 들어갈 수 없습니다: 즉, 1 cm는 유효하지 않습니다.

- -

CSS는 치수를 사용해 아래와 같은 것들을 표시합니다:

- - - -

다음 절에서 이것들을 다룹니다.

- -

거리 단위

- -

거리 단위, 또는 길이가 값으로 허용되는 속성은 {{cssxref("<length>")}} 자료형으로 표시됩니다. CSS에는 2가지 종류의 길이가 있습니다: 상대적 길이와 절대적 길이입니다.

- -

상대적 길이 단위는 다른 무언가와 비교해 상대적인 길이를 나타냅니다. 예를 들어, em은 해당 요소의 폰트 크기에 상대적이며 vh는 뷰포트의 높이에 상대적입니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

상대적 길이 단위들

-
단위비교의 대상
em해당 요소의 폰트 크기
ex해당 요소의 폰트의 x높이
cap해당 요소의 폰트의 대문자 높이(대문자의 공칭 높이)
ch해당 요소의 폰트의 좁은 문자가 평균적으로 나아가는 길이, “0” (ZERO, U+0030) 문자로 대표됨.
ic해당 요소의 폰트의 전각 문자가 평균적으로 나아가는 길이, “水” (CJK 물 표의 문자, U+6C34) 문자로 대표됨.
rem루트 요소의 폰트 크기
lh해당 요소의 줄 높이
rlh루트 요소의 줄 높이
vw뷰포트 너비의 1%
vh뷰포트 높이의 1%
vi루트 요소의 인라인 축 방향으로 뷰포트 길이의 1%
vb루트 요소의 블록 축 방향으로 뷰포트 길이의 1%
vmin뷰포트의 길이 중 더 짧은 것의 1%
vmax뷰포트의 길이 중 더 긴 것의 1%
- -

절대적 길이 단위는 인치 또는 센티미터의 물리적 길이로 고정적입니다. 그래서 이 단위들의 다수는 인쇄물과 같은 고정된 크기의 매체로 출력되는 경우에 유용합니다. 예를 들어, mm는 물리적인 밀리미터, 즉 센티미터의 1/10입니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-

절대적 길이 단위

-
단위이름다음과 동일함
cm센티미터1cm = 96px/2.54
mm밀리미터1mm = 1cm의 1/10
Q쿼터-밀리미터1Q = 1cm의 1/40
in인치1in = 2.54cm = 96px
pc피카1pc = 1in의 1/16
pt포인트1pt = 1in의 1/72
px픽셀1px = 1in의 1/96
- -

길이 값을 포함할 때 길이가 0이면, 단위 식별자가 필요하지 않습니다. 그 외의 경우 단위 식별자가 필요합니다. 단위 식별자는 대소문자를 구별하지 않으며, 값의 숫자 부분 이후에 공백 없이 바로 나와야 합니다.

- -

각도 단위

- -

각도 값은 {{cssxref("<angle>")}} 자료형으로 표시되며 다음의 값이 허용됩니다:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
단위이름설명
deg360도가 완전한 원을 이룹니다.
grad그라디안400 그라디안이 완전한 원을 이룹니다.
rad라디안2π 라디안이 완전한 원을 이룹니다.
turn1턴이 완전한 원을 이룹니다.
- -

시간 단위

- -

시간 단위는 {{cssxref("<time>")}} 자료형으로 표시됩니다. 시간 단위를 포함할 때는 단위 식별자인 s 또는 ms가 반드시 필요합니다. 아래의 값이 허용됩니다.

- - - - - - - - - - - - - - - - - - - - - -
단위이름설명
s
ms밀리초1,000 밀리초는 1초와 같습니다.
- -

진동수 단위

- -

진동수 단위는 {{cssxref("<frequency>")}} 자료형으로 표시됩니다. 아래 값이 허용됩니다.

- - - - - - - - - - - - - - - - - - - - - -
단위이름설명
Hz헤르츠1초당 발생한 횟수를 나타냅니다.
kHz킬로헤르츠1 킬로헤르츠는 1000 헤르츠와 같습니다.
- -

1Hz, 또는 1hz1HZ는 초당 진동수입니다.

- -

해상도 단위

- -

해상도 단위는 {{cssxref("<resolution>")}}로 표시됩니다. 이것들은 스크린과 같은 그래픽 표시에서 CSS 인치당, 센티미터당, 픽셀당 몇 개의 점을 포함할 수 있는지를 나타냄으로써 점 1개의 크기를 표현합니다. 다음의 값이 허용됩니다:

- - - - - - - - - - - - - - - - - - - - - - -
단위설명
dpi인치당 점의 수.
dpcm센티미터당 점의 수.
dppx, x픽셀당 점의 수.
- -

퍼센트

- -

{{cssxref("<percentage>")}}는 다른 값의 일부분을 표현하는 자료형입니다.

- -

퍼센트 값은 언제나 다른 양, 예컨대 길이와 같은 것에 상대적입니다. 퍼센트를 허용하는 속성은 그 퍼센트가 참조하는 양 또한 정의합니다. 이 양은 같은 요소가 갖는 다른 속성의 값이거나, 조상 요소가 갖는 속성의 값이거나, 이 요소를 포함하는 블록의 치수 등이 될 수 있습니다.

- -

예를 들면, 어떤 박스의 {{cssxref("width")}}를 퍼센트로 지정한 경우, 그 박스의 부모의 계산된 너비의 퍼센트를 참조합니다:

- -
.box {
-  width: 50%;
-}
- -

퍼센트와 치수 함께 사용하기

- -

일부 속성은 두 자료형 중 하나를 선택해서, 예를 들면 <length> 또는 <percentage>를 골라서 치수를 지정할 수 있습니다. 이 경우 사양에는 허용되는 값이 {{cssxref("<length-percentage>")}}처럼 조합된 단위로 기술됩니다. 다음은 가능한 다른 조합입니다:

- - - -

특별한 자료형 (다른 사양에서 정의된 것들)

- - - -

색깔

- -

{{cssxref("<color>")}} 값은 요소의 외관 색깔(예: 배경색)을 지정하며, CSS Color Module에 정의되어 있습니다.

- -

이미지

- -

{{cssxref("<image>")}} 값은 CSS에서 사용될 수 있는 다양한 종류의 이미지를 지정하며, CSS Image Values and Replaced Content Module에 정의되어 있습니다.

- -

위치

- -

{{cssxref("<position>")}} 자료형은 배치 영역 안에서 객체의 2D 위치를, 예컨대 컨테이너 안에서 배경 이미지의 위치 같은 것을 정의합니다. 이 자료형은 {{cssxref("background-position")}}으로 해석되므로 CSS Backgrounds and Borders specification에 명시되어 있습니다.

- -

함수 표기법

- - - -

함수 표기법은 더 복잡한 자료형을 표현하거나 CSS가 특별한 처리를 하도록 지시하는 자료형의 값입니다. 이 문법은 함수의 이름으로 시작해서 바로 왼쪽 괄호 (가 뒤따르고, 함수의 인자를 나열한 다음, 오른쪽 괄호 )로 끝납니다. 함수는 여러 개의 인자를 받을 수 있으며, CSS 속성 값과 비슷한 형식을 가집니다.

- -

공백 문자는 허용되지만, 괄호 안에서는 선택 사항입니다. (단 min(), max()clamp() 함수 페이지의 주의 사항에서 공백 문자에 대한 내용을 확인하세요.)

- -

rgba()와 같은 몇몇 레거시 함수 표기법이 콤마를 사용하지만, 일반적으로 콤마는 목록에서 아이템을 구분하기 위해 사용됩니다. 콤마가 인자를 구분하기 위해 사용된 경우, 콤마 전후의 공백 문자는 선택 사항입니다.

- -

사양

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
사양상태비고
{{SpecName("CSS4 Values")}}{{Spec2("CSS4 Values")}}vi, vb, ic, cap, lhrlh 단위 추가.
- min(), max()clamp() 함수 표기법 추가
- toggle() 추가
{{SpecName("CSS3 Values")}}{{Spec2("CSS3 Values")}}calc()chremvwvwvminvmaxQ 추가
{{SpecName("CSS4 Colors")}}{{Spec2("CSS4 Colors")}}rgb()rgba()hsl()hsla() 함수에 콤마 없는 문법 추가. rgb()와 hsl()에 알파 값 허용하며 rgba()와 hsla()를 그것들의 (지원이 중단된) 별칭으로 전환.
- 색깔 키워드 rebeccapurple 추가. 4자리와 8자리의 16진수 색깔 값 추가, 마지막 숫자(들)이 알파 값을 의미함.
- hwb()device-cmyk()color() 함수 추가.
{{SpecName("CSS3 Colors")}}{{Spec2("CSS3 Colors")}}system-colors를 지원 중단으로 표시. SVG 색깔 추가. rgba()hsl()hsla() 함수 추가.
{{SpecName("CSS4 Images")}}{{Spec2("CSS4 Images")}} -

element(), image(), image-set(), conic-gradient() 추가

-
{{SpecName("CSS3 Images")}}{{Spec2("CSS3 Images")}}이미지를 처음으로 정의함.
{{SpecName("CSS2.1")}}{{Spec2("CSS2.1")}}
{{SpecName("CSS1")}}{{Spec2("CSS1")}}첫번째 정의.
- -

같이 보기

- - diff --git a/files/ko/web/css/cursor/using_url_values_for_the_cursor_property/index.html b/files/ko/web/css/cursor/using_url_values_for_the_cursor_property/index.html deleted file mode 100644 index 416718c17f..0000000000 --- a/files/ko/web/css/cursor/using_url_values_for_the_cursor_property/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: cursor 속성값에 URL 사용 -slug: Web/CSS/cursor/Using_URL_values_for_the_cursor_property -tags: - - CSS - - CSS_2.1 - - Cross-browser_Development - - Web Development -translation_of: Web/CSS/CSS_Basic_User_Interface/Using_URL_values_for_the_cursor_property ---- -

Gecko 1.8 (Firefox 1.5, SeaMonkey 1.0)은 URL 값을 CSS2 커서 속성값으로 사용하는 것을 지원합니다. 이 기능은 마우스 커서 모양으로 임의의 이미지 를 지정할 수 있게 해줍니다 — Gecko가 지원하는 모든 이미지 포맷을 사용할 수 있습니다.

- -

문법

- -

이 속성의 문법은 다음과 같습니다:

- -
cursor: [<url>,]* keyword;
-
- -

즉, URL을 지정하지 않거나 혹은 다수의 콤마로 분리된 URL값들을 지정할 수 있으며, 이 값들 뒤엔 반드시 CSS규정에 정의된 autopointer같은 키워드들이 따라와야 합니다.

- -

예를 들면, 다음과 같은 값이 지정될 수 있습니다:

- -
cursor: url(foo.cur), url(http://www.example.com/bar.gif), auto;
-
- -

우선 foo.cur의 로딩이 시도 되고, 만약 이 파일이 없거나 어떤 다른 이유로 파일이 부적합할 경우, bar.gif를 로드하게 되고 이것 마저 사용할 수 없게 되면, auto가 사용될 것입니다.

- -

커서 값에 대한 CSS3 syntax 지원은 Gecko 1.8beta3에 부가되었으며, 따라서 Firefox 1.5에서 사용할 수 있습니다. 이 기능은 커서 이미지의 바운더리에 부착시킬 커서의 핫스팟의 좌표를 지정할 수 있게 해줍니다. 만일 아무것도 지정되지 않을 경우, 핫스팟의 좌표는 이미지 파일 자체에서 (CUR 와 XBN 파일의 경우) 읽어 들이거나 이미지의 좌측 상단 코너로 지정됩니다. CSS3 문법의 예문은 다음과 같습니다:

- -
cursor: url(foo.png) 4 12, auto;
-
- -

첫번째 숫자는 x좌표이며, 두번째 숫자는 y좌표입니다. 이 예문은 이미지의 왼쪽 위 (0,0)로부터 (4, 12)의 위치의 픽셀을 핫스팟으로 지정할 것입니다.

- -

제약 사항

- -

Gecko가 지원하는 모든 이미지 포팻이 사용가능합니다. 즉, BMP, JPG, CUR, GIF 등의 이미지를 사용할 수 있습니다. 그러나, ANI는 지원되지 않습니다. animated GIF 이미지로 지정해도, 커서는 animated 커서가 되지는 않을 것입니다. 이런 문제점은 향후 릴리즈에서 제거될 것입니다.

- -

Gecko는 커서의 크기에 관해서 어떤 제약을 두고 있지는 않습니다만, 다른 운영체제나 플랫폼들과의 최대의 호환성을 유지하기 위해 커서 크기를 32x32로 제한할것을 권장합니다. 특히, 이보다 큰 커서는 윈도우 9x (95, 98, ME) 에서 작동하지 않을 것입니다.

- -

투명 커서는 XP보다 이전 윈도우 릴리즈에서는 지원되지 않으며, 이는 운영체제의 제약사항입니다. 투명기능은 모든 플랫폼에서 작동합니다.

- -

모질라의 윈도우, OS/2 그리고 리눅스(GTK+ 2.4 나 그 이후 버전 사용) 릴리즈에서만 커서로 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) }})

- -

다른 브라우저들과의 호환성

- -

마이크로소프트 인터넷 익스플로러(MSIE)도 cursor속성으로 URL 값을 지원합니다. 그러나, CUR 과 ANI 포맷만을 지원합니다.

- -

cursor속성 문법도 또한 제약이 덜한 관계로

- -
cursor: url(foo.cur);
-
- -

이나

- -
cursor: url(foo.cur), pointer, url(bar.cur), auto;
-
- -

와 같은 값도 MSIE에선 작동할 것입니다. 그러나 이런 값은 Gecko에선 작동하지 않을 것입니다. Gecko와의 호환성을 위해서 또 CSS규약에 따라, 항상 URL 리스트를 먼저 나열하시고, 정확히 하나의 키워드 값을 그 뒤에 사용하십시오.

- -

To-do

- -
-
To-do: document what MSIE does with CSS 3 hotspot locations
-
- -

Interwiki Language Links

- -

{{ languages( { "ja": "ja/Using_URL_values_for_the_cursor_property" } ) }}

diff --git a/files/ko/web/css/getting_started/javascript/index.html b/files/ko/web/css/getting_started/javascript/index.html deleted file mode 100644 index 94759e21bf..0000000000 --- a/files/ko/web/css/getting_started/javascript/index.html +++ /dev/null @@ -1,145 +0,0 @@ ---- -title: JavaScript -slug: Web/CSS/Getting_Started/JavaScript -tags: - - 'CSS:Getting_Started' -translation_of: Learn/JavaScript/Client-side_web_APIs/Manipulating_documents -translation_of_original: Web/Guide/CSS/Getting_started/JavaScript ---- -

이 페이지는 입문서의 II 부입니다. II 부는 모질라에서의 CSS의 범위(scope)를 보여주는 예제들을 포함하고 있습니다.

-

II 부의 각 페이지는 CSS 가 다른 기술(technologies)들과 어떻게 상호작용하는지 설명하고 있습니다. 이 페이지들은 이들 다른 기술들을 사용하는 방법들을 가르치기위해서 디자인 되지는 않았습니다. 이 들 기술들을 자세히 배우려면 다른 입문서를 보세요.

-

대신 이 페이지들은 CSS의 다양한 사용법을 설명하기 위해서 디자인되었습니다. 이들 페이지들을 사용하려면, CSS에 대해 좀 알고 있어야만 합니다, 그러나, 다른 분야 기술들에대한 어떤 지식을 필요로하지는 않습니다.

-

정보: 자바스크립트(JavaScript)

-

자바스크립트(JavaScript)는 - - 프로그래밍 언어 - 입니다. 모질라 애플리케이션( 예를 들면, 모질라 브라우저) 사용할 때, 컴퓨터가 실행시키는 코드의 많은 부분이 자바스크립트로 쓰여져 있습니다.

-

자바스크립트는 스타일 시트와 상호작용하여, 문서 스타일을 동적으로 변화시키는 프로그램을 쓸 수 있게 해줍니다.

-

이렇게 하는데 세가지 방법이 있습니다:

- - - - - - - - -
- More details
모질라에서의 자바스트립트에 대해 더 많은 정보를 원하시면, 이 위키(wiki)에 있는 JavaScript페이지를 보세요.
-

액션: 자바스크립트 예제(demonstration)

-

새로은 HTML 문서 doc5.html를 만드세요. 아래의 내용물을 복사해서 붙여넣되 스크롤해서 전체를 다 넣을 수 있도록 하세요:

-
-
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
-<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 type="button" onclick="doDemo(this);">Click Me</BUTTON>
-
-</BODY>
-</HTML>
-
-
-

새로운 CSS 파일 style5.css을 만드세요. 아래의 내용물을 복사해서 붙여넣으세요:

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

새로운 텍스트 파일 script5.js을 만드세요. 아래의 내용물을 복사해서 붙여넣으세요:

-
-
// JavaScript demonstration
-function doDemo (button) {
-  var square = document.getElementById("square")
-  square.style.backgroundColor = "#fa4"
-  button.setAttribute("disabled", "true")
-  setTimeout(clearDemo, 2000, button)
-  }
-
-function clearDemo (button) {
-  var square = document.getElementById("square")
-  square.style.backgroundColor = "transparent"
-  button.removeAttribute("disabled")
-  }
-
-
-

브라우저에서 문서을 열고 버튼을 누르세요.

-

이 위키페이지는 자바스크립트를 지원하지 않습니다. 따라서 예제가 어떻게 실행되는 지 보여드릴 수 없습니다. 버튼을 누른 전과 후가 대략 다음과 같이 보입니다:

- - - - - - - -
- - - - - - -
-

JavaScript demonstration

-
-
-  
-
-
-
- - - - - - -
-

JavaScript demonstration

-
-
-  
-
-
-
-

이 예제에서 주의할 점:

- - - - - - - - -
- Challenge
스크립트를 변경해서 사각형(square)이 색이 변할 때 오른쪽으로 20em 점프했다가 이후 되 돌아오게 만드세요.
-

그럼 다음은?

-

If you had difficulty understanding this page, or if you have other comments about it, please contribute to its Discussion page.

-

이 예제에서 HTML 문서가 단지 버튼 엘리먼트만이 스크립트를 사용함에도 불구하고 스크립트에 링크를 가지고 있었습니다. 모질라는 CSS를 확장해서 자바스크립트 코드를 (내용물과 다른 스타일 시트들도) 선택된 엘리먼트에 링크할 수 있게 합니다. 다음 페이지에서는 다음을 실행해 봅니다: XBL bindings

diff --git a/files/ko/web/css/getting_started/svg_graphics/index.html b/files/ko/web/css/getting_started/svg_graphics/index.html deleted file mode 100644 index d8ca001fb2..0000000000 --- a/files/ko/web/css/getting_started/svg_graphics/index.html +++ /dev/null @@ -1,195 +0,0 @@ ---- -title: SVG graphics -slug: Web/CSS/Getting_Started/SVG_graphics -tags: - - 'CSS:Getting_Started' -translation_of: Web/SVG/Tutorial/SVG_and_CSS ---- -

이 페이지는 그래픽을 만들기 위한 특별한 언어 SVG를 설명합니다.

-

SVG 기능이 있는 모질라 브라우저에서 작동하는 간단한 예제를 만듭니다.

-

정보: SVG

-

- - SVG - (Scalable Vector Graphics, 스케일러블 벡터 그래픽)은 그래픽을 만들어내기 위한 XML-기반 언어입니다.

-

움직이지 않는 이미지(static image)를 위해 사용될 수 있으며, 또한 애니메이션 과 사용자 인터페이스를 위해서도 사용될 수 있습니다.

-

다른 XML-기반 언어들과 같이, SVG는 CSS 스타일 시트를 지원하여 그래픽에 사용되는 스타일을 그래픽의 내용물과 분리시킬 수 있게 합니다.

-

또한, 다른 문서 마크업 언어들과 함께 사용되는 스타일 시트들도 이미지가 요구되는 곳에 SVG 그래픽의 URL을 지정할 수 있습니다. 예를들면, HTML 문서와 함께 사용하는 스타일 시트에서 background 속성 값에 SVG값의 URL을 지정할 수 있습니다.

- - - - - - - -
- More details
이글을 쓰는 시점에서(2005년 중반), 모질라 브라우저의 몇몇 최근 빌드만이 SVG 지원을 내장하고 있었습니다. -

Adobe에서 제공되는 것 같은 플럭인(plugin)을 인스톨하면 다른 버전에서도 SVG 지원을 추가할 수 있습니다.

-

모질라에서의 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 기능이 있는(SVG-enabled) 브라우저에서 여세요. 마우스 포인터(mouse pointer)를 그래픽위로 움직여 보세요.

-

이 위키페이지는 SVG를 지원하지 않습니다. 따라서 예제가 어떻게 실행되는 지 보여드릴 수 없습니다. 다음과 같이 보입니다:

- - - - - - -
SVG demonstration
-

이 예제에서 주의할 점:

- - - - - - - - -
- Challenge
스타일 시트를 변경해서, 마우스 포인터가 안쪽 꽃잎들 중 한개 위에 오게 되면, 바깥 쪽 꽃잎이 작동하는 방식은 바뀌지 않은채 모든 안쪽꽃잎 색이 핑크(pink)색으로 변하게 하세요
-

그럼 다음은?

-

If you had difficulty understanding this page, or if you have other comments about it, please contribute to its Discussion page.

-

이 예제에서 SVG 기능이 있는(SVG enabled) 브라우저는 이미 SVG 엘리먼트를 디스플레이하는 방법을 알고 있습니다. 스타일 시트는 단지 그 디스플레이를 특정 방식으로 수정할 뿐 입니다. 그러나 디스플레이하는 방식이 미리 지정되어 있지 않은 범용(general-purpose) XML 문서를 위해서 CSS를 사용할 수있습니다. 다음 페이지에서는 이를 실행해 봅니다: XML data

-

{{ languages( { "fr": "fr/CSS/Premiers_pas/Graphiques_SVG", "pl": "pl/CSS/Na_pocz\u0105tek/Grafika_SVG" } ) }}

diff --git a/files/ko/web/css/index/index.html b/files/ko/web/css/index/index.html deleted file mode 100644 index 953130cd26..0000000000 --- a/files/ko/web/css/index/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: CSS documentation index -slug: Web/CSS/Index -tags: - - CSS - - Index - - MDN Meta -translation_of: Web/CSS/Index ---- -

{{Index("/ko/docs/Web/CSS")}}

diff --git a/files/ko/web/css/media_queries/using_media_queries/index.html b/files/ko/web/css/media_queries/using_media_queries/index.html new file mode 100644 index 0000000000..559b5805c6 --- /dev/null +++ b/files/ko/web/css/media_queries/using_media_queries/index.html @@ -0,0 +1,386 @@ +--- +title: 미디어 쿼리 사용하기 +slug: Web/Guide/CSS/Media_queries +tags: + - Advanced + - CSS + - Guide + - Media + - Media Queries + - Responsive Design + - Web +translation_of: Web/CSS/Media_Queries/Using_media_queries +--- +
{{cssref}}
+ +

미디어 쿼리는 단말기의 유형(출력물 vs. 화면)과, 어떤 특성이나 수치(화면 해상도, {{glossary("viewport", "뷰포트")}} 너비 등)에 따라 웹 사이트나 앱의 스타일을 수정할 때 유용합니다.

+ +

미디어 쿼리는 다음과 같은 상황에 사용할 수 있습니다.

+ + + +
+

참고: 이 페이지의 CSS는 시연용으로 @media를 사용했지만, 기본적인 구문은 모든 미디어 쿼리가 동일합니다.

+
+ +

구문

+ +

미디어 쿼리는 선택 사항인 미디어 유형과, 자유로운 수의 미디어 특성 표현식으로 이루어집니다. 논리 연산자를 사용해 다수의 쿼리를 다양한 방법으로 결합할 수도 있습니다. 미디어 쿼리는 대소문자를 구분하지 않습니다.

+ +

미디어 쿼리는 (유형을 지정했다면) 문서를 보여주는 미디어의 유형이 일치하고 모든 미디어 특성 표현식의 계산값이 참일 때 참으로 계산됩니다.

+ +
+

참고: {{HTMLElement("link")}}의 미디어 쿼리가 거짓을 반환하더라도 스타일시트는 다운로드됩니다. 그렇지만 그 안의 내용은 쿼리가 참이 되어야 적용됩니다.

+
+ +

미디어 유형

+ +

미디어 유형은 장치의 일반적인 범주를 나타냅니다. 미디어 유형은 not이나 only 논리연산자를 사용할 때를 제외하면 선택사항이며 지정하지 않으면 all을 사용합니다.

+ +
+
all
+
모든 장치에 적합합니다.
+
print
+
인쇄 결과물 및 출력 미리보기 화면에 표시 중인 문서입니다.
+ (인쇄 미디어 문서를 방문해 print 형식에서 발생 가능한 서식 문제의 정보를 확인해주세요.)
+
screen
+
주로 화면이 대상입니다.
+
speech
+
음성 합성장치 대상입니다.
+
+ +
+

사용하지 않는 미디어 유형: CSS2.1과 Media Queries 3 모듈은 여러가지 추가 유형(tty, tv, projection, handheld, braille, embossed, aural)을 정의했으나 Media Queries 4에서 제거됐으므로 사용해선 안됩니다. aural은 유사한 유형인 speech로 대체됐습니다.

+
+ +

미디어 특성

+ +

미디어 특성은 {{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")}}뷰포트의 가로세로비
{{cssxref("@media/color", "color")}}출력 장치의 색상 채널별 비트 수, 흑백일 땐 0
{{cssxref("@media/color-gamut", "color-gamut")}}사용자 에이전트와 출력 장치가 지원하는 색상의 대략적인 범위Media Queries Level 4에서 추가
{{cssxref("@media/color-index", "color-index")}}출력 장치의 색상 검색 테이블(LUT) 항목 수, 존재하지 않을 땐 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")}}웹 앱 매니페스트의 display 항목이 정의한 애플리케이션의 표시 모드Web App Manifest 명세에서 정의
{{cssxref("@media/forced-colors", "forced-colors")}}사용자 에이전트가 색상 팔레트를 제한하는지 여부Media Queries Level 5에서 추가
{{cssxref("@media/grid", "grid")}}장치가 그리드와 비트맵 스크린 중 어느 것을 사용하나?
{{cssxref("@media/height", "height")}}뷰포트의 높이
{{cssxref("@media/hover", "hover")}}주 입력 방식으로 사용자가 요소 위에 호버할 수 있는가?Media Queries Level 4에서 제거
{{cssxref("@media/inverted-colors", "inverted-colors")}}사용자 에이전트나 운영 체제가 색상을 반전 중인가?Media Queries Level 5에서 추가
{{cssxref("@media/light-level", "light-level")}}주변 환경의 광도Media Queries Level 5에서 추가
{{cssxref("@media/monochrome", "monochrome")}}출력 장치의, 모노크롬 프레임 버퍼의 픽셀 당 비트 수. 단색을 사용하지 않으면 0
{{cssxref("@media/orientation", "orientation")}}뷰포트의 방향
{{cssxref("@media/overflow-block", "overflow-block")}}콘텐츠가 블록 축 방향으로 뷰포트를 오버플로 할 경우 출력 장치가 어떻게 처리하는가?Media Queries Level 4에서 추가
{{cssxref("@media/overflow-inline", "overflow-inline")}}콘텐츠가 인라인 축 방향으로 뷰포트를 오버플로 할 경우 스크롤 가능한가?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")}}스크롤바를 포함한 뷰포트 너비
+ +

논리 연산자

+ +

not, and, only와 같은 논리 연산자를 사용해 복잡한 쿼리를 조합할 수 있습니다. 여러 미디어 쿼리를 쉼표로 구분해서 하나의 규칙으로 만들 수도 있습니다.

+ +

and

+ +

and 연산자는 다수의 미디어 특성을 조합하여 하나의 미디어 쿼리를 만들 때 사용합니다. 쿼리가 참이려면 모든 구성 특성이 참을 반환해야 합니다. 미디어 특성과 미디어 유형을 같이 사용할 때도 쓰입니다.

+ +

not

+ +

not 연산자는 미디어 쿼리를 부정하여, 쿼리가 거짓일 때만 참을 반환합니다. 쉼표로 구분한 쿼리 목록 중 하나에서 사용한 경우 전체 쿼리가 아닌 해당하는 하나의 쿼리에만 적용됩니다. not 연산자를 사용할 경우 반드시 미디어 유형도 지정해야 합니다.

+ +
+

참고: Level 3 모듈에서는 not 키워드를 사용해 단일 미디어 기능을 부정할 수 없으며 전체 쿼리만 부정 가능합니다.

+
+ +

only

+ +

only 연산자는 전체 쿼리가 일치할 때만 스타일을 적용할 때 사용하며 오래 된 브라우저가 스타일을 잘못 적용하지 못하도록 방지할 때 유용합니다. only를 사용하지 않은 screen and (max-width: 500px) 쿼리를 가정했을 때, 구형 브라우저는 쿼리를 단순히 screen으로만 읽고 뒷부분은 무시한 채 스타일을 적용해버립니다. only 연산자를 사용할 경우 반드시 미디어 유형도 지정해야 합니다.

+ +

, (쉼표)

+ +

쉼표는 다수의 미디어 쿼리를 하나의 규칙으로 조합할 때 사용합니다. 쉼표 목록 내의 쿼리 각각은 나머지와 별개로 취급하므로, 단 하나의 쿼리만 참을 반환해도 규칙 전체가 참이 됩니다. 즉 쉼표는 논리 or 연산자처럼 동작합니다.

+ +

미디어 유형 특정하기

+ +

미디어 유형은 주어진 장치의 일반적인 분류를 설명합니다. 비록 웹사이트는 보통 스크린을 염두에 놓고 디자인하지만, 프린터나 오디오 기반 스크린 리더처럼 특정 장치를 대상으로 하는 스타일을 만들고 싶을 때가 있을지도 모릅니다. 예를 들어 다음의 CSS는 프린터를 특정합니다.

+ +
@media print { ... }
+ +

다수의 장치를 특정할 수도 있습니다. 예컨대 아래 @media 규칙은 두 개의 미디어 쿼리를 사용해 스크린과 인쇄 장치 모두 특정합니다.

+ +
@media screen, print { ... }
+ +

미디어 유형 구획으로 올라가서 가능한 미디어 유형의 목록을 확인해보세요. 미디어 유형은 굉장히 넓은 범위에서 장치를 설명하기 때문에 적은 수만 존재합니다. 더 세부적인 특성을 특정하려면 미디어 기능을 사용하세요.

+ +

미디어 기능 특정하기

+ +

미디어 기능은 주어진 {{glossary("user agent", "사용자 에이전트")}}, 출력 장치, 주변 환경의 특징을 설명합니다. 예를 들어 어떤 스타일을 와이드스크린 모니터에만, 마우스를 사용하는 컴퓨터에만, 저광도 환경에서 사용 중인 장치에서만 적용할 수 있습니다. 다음의 예제는 사용자의 주 입력 방식(마우스 등)이 요소 위에 호버할 수 있으면 스타일을 적용합니다.

+ +
@media (hover: hover) { ... }
+ +

많은 미디어 기능은 범위 기능으로, "min-" 또는 "max-"를 앞에 붙여 각각 "최소 조건"과 "최대 조건" 제약을 나타낼 수 있습니다. 다음의 CSS는 브라우저의 {{glossary("viewport", "뷰포트")}} 너비가 12450px 이하인 경우에만 스타일을 적용합니다.

+ +
@media (max-width: 12450px) { ... }
+ +

미디어 기능 쿼리를 값 없이 생성할 경우 주어진 기능의 값이 0이 아닐 때 (Level 4부터는 0none이 아닐 때) 중첩 스타일을 적용합니다. 그러므로 다음 CSS는 흑백이 아닌 모든 장치에 해당합니다.

+ +
@media (color) { ... }
+ +

어떤 기능이 현재 브라우저가 가동 중인 장치에 적용되지 않으면, 해당 미디어 기능을 포함한 표현식은 항상 거짓입니다. 예를 들어, 음성 출력 전용 장치에 화면 가로세로비는 존재하지 않으므로 다음 쿼리에 중첩된 스타일은 절대 적용되지 않습니다.

+ +
@media speech and (aspect-ratio: 11/5) { ... }
+ +

미디어 특성 각각의 참고서 문서를 방문해 더 많은 예제를 확인하세요.

+ +

복잡한 미디어 쿼리 생성

+ +

때로는 사용자가 다수의 조건으로 구성된 쿼리를 생성하기 원할 수도 있습니다. 이때 논리연산자인 : not, and, 그리고 only를 사용하면 됩니다.  더 나아가 , 사용자는 복수의 미디어쿼리를 쉼표로 연결하여 리스트를 작성할수도 있습니다. 이렇게 함으로써 사용자는 다양한 상황에서 같은 스타일을 적용할 수 있습니다.

+ +

앞서 예와 같이,  and 연산자를 사용하여 미디어유형과 미디어기능을 그룹지을 수 있습니다. 또한 and 를 사용하여 복수의 미디어 기능을 하나의 미디어 쿼리로 결합해낼수도 있습니다. 하지만 not 연산자는 미디어쿼리 자체를 부정시키는데, 근본적으로 원래의 의미를 반전시킵니다. only 연산자는 구형 브라우저가 스타일을 적용시키지 못하게 합니다.

+ +
+

Note: 대부분의 경우,  all 미디어유형은 다른 유형이 특정되지 않았을 때 디폴트로 적용됩니다. 하지만, 사용자가 not 이나 only 연산자를 사용하면, 사용자는 반드시 미디어유형을 특정해야 합니다.

+
+ +

다수의 유형과 기능 조합하기

+ +

The and 연산자는 미디어기능과 미디어유형 혹은 다른 미디어 기능들과 연결해줍니다. 이 예에서는 두개의 미디어기능을 기기의 랜스케입(가로방향화면)방향으로 제한시키고 최소폭을 30 ems로 지정합니다:

+ +
@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) { ... }
+ +

위에 예에서 보면, 만일 사용자가 페이지높이가 800px인 프린터를 사용한다면, 첫번째 쿼리가 적용되기에 참 (true)값을 반환할 것입니다. 마찬가지로, 만일 사용자가 화면 높이가 480px인 스마트폰을 사용한다면 두번째 쿼리가 적용될 것이고, 미디어 문은 참값을 반환하게 됩니다.

+ +

쿼리의 뜻 반전하기

+ +

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

Level 4의 구문 향상

+ +

미디어쿼리 Level 4 사양은 향상된 구문을 포함하는데 그를 통해 미디어쿼리가 '범위' 유형을 가진 기능을 사용할 수 있습니다. 예를 들면, 폭, 높이 처럼 말보다는 숫자에 관련된 것들입니다. Level 4 는 그러한 쿼리들을 작성하는데에 필요한 범위 구문을 제공합니다. 예를 들면, adds a range context for writing such queries. 폭을 표현하기 위해 max- 함수를 써서 사용자는 다음과 같이 쓸 수 있습니다:

+ +
+

Note: 미디어쿼리 Level 4 사양에는 상당수의 최신 브라우저를 지원하지만,  몇몇 미디어기능들은 잘 지원되지 않습니다. 자세한 사항은 @media browser compatibility table 를 참조해 주십시요. 

+
+ +
@media (max-width: 30em) { ... }
+ +

미디어 쿼리 Level 4 에서는 다음과 같이 쓸 수 있습니다:

+ +
@media (width <= 30em) { ... }
+ +

min- 과 max- 를 사용하여 사용자가 두 값 사이에서 폭 값을 시험해 보고 싶은 상황이라면:

+ +
@media (min-width: 30em) and (max-width: 50em) { ... }
+ +

Level 4 구문에서는 이렇게 표현할 수 있습니다:

+ +
@media (30em <= width <= 50em ) { ... }
+
+ +

 Level 4 미디어쿼리는 또한 완전한 불리언 대수법을 사용하는 미디어쿼리들과 and, not, or.연산자를 결합할 수 있습니다. 

+ +

not으로 기능 부정

+ +

미디어기능에 not() 을 사용하면 쿼리에 있는 기능을 부정합니다. 예를 들어, hover를 할 수 없는 장치를 사용할 때 not(hover) 를 사용할 수 있습니다.

+ +
@media (not(hover)) { ... }
+ +

or로 다수의 기능 판별

+ +

or 를 사용하면 다수의 기능 가운데 맞는 것이 하나라도 있는지를 테스트하여, 그중에 맞는 것이 하나라도 있으면 true 값을 반환하게 할 수 있습니다. 예를 들어, 다음에 보이는 쿼리에서는 흑백화면인지 혹은 hover가 가능한 지를 시험하고 있습니다.

+ +
@media (not (color)) or (hover) { ... }
+
+ +

같이 보기

+ + diff --git a/files/ko/web/css/reference/property_template/index.html b/files/ko/web/css/reference/property_template/index.html deleted file mode 100644 index 9df3680b49..0000000000 --- a/files/ko/web/css/reference/property_template/index.html +++ /dev/null @@ -1,131 +0,0 @@ ---- -title: Property Template -slug: Web/CSS/Reference/Property_Template -tags: - - CSS - - MDN Meta -translation_of: MDN/Contribute/Howto/Document_a_CSS_property/Property_template ---- -

{{MDNSidebar}}

- -
-

This is a template page for CSS property. Please use this as a raw template when you create a new CSS property page.
- Comment in italics are information about how to use part of the template

-
- -

{{CSSRef}}

- -

Add the non-standard header if the property is not on the standard track. In the summary section, in a note, describe how to achieve its effect using standard Open Web technologies.

- -

{{Non-standard_Header}}

- -

Add the experimental header if in your judgement the property's behavior is likely to change in future, for example because of very immature specifications or competing incompatible implementations.

- -

{{SeeCompatTable}}

- -

Description of the property. It must start by "The xyz CSS property" followed by a one-sentence description. The first paragraph of this introduction will be used by default as the description of the page.

- -
-

Note: Placeholder for any special messages.

-
- -

But don't add several notes. It should be really important, or be part of the description!

- -

Syntax

- -
/* Keyword values */
-property: value1;
-property: value2;
-
-/* <length> values */
-property: 12.8em;   /* A valid length */
-
-/* Global values */
-property: inherit;  /* <-- To remember those are a possible values */
-property: initial;
-property: unset;
-
- -

The second part of the is a simple translation of the what the formal syntax tells. It is aimed at medium-level users that will not understand well the formal syntax.

- -

Values

- -

Each element of the formal syntax must be explained

- -
-
value_1
-
Is a keyword meaning...
-
value_2 {{Non-standard_Inline}} {{Experimental_Inline}}
-
Is a keyword meaning
-
- -

Formal syntax

- -

The formal syntax must be taken from the spec and added to the MDN data repository. It is an important tool to get precise syntax information for advanced users.

- -
{{CSSSyntax}}
- -

Examples

- -

Add this only if there is such an example. No dead link here.

- -

CSS

- -
elementName {
-  property: value;
-  thisis: "example";
-  dream: 10000000mm;
-  love: "danger";
-}
- -

HTML

- -
<elementName>foo bar</elementName>
- -

Result

- -

{{EmbedLiveSample("Examples")}}

- -

Specifications

- -

Exclusively use this standard table. Place older spec on the bottom. Use the templates SpecName() for the name and Spec2() for the status. That way, when the spec progress on the standard track, or move, the table content will be automatically adapted.

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("CSS3 Animations", "#fake-link", "fake-value")}}{{Spec2("CSS3 Animations")}}No change from CSS 2.1
{{SpecName("CSS2.1", "#fake-link", "fake value")}}{{Spec2("CSS2.1")}}Initial definition
- -

{{CSSInfo}}

- -

Browser compatibility

- -

(See Compatibility tables for more information)

- - - -

{{Compat("css.property.property-name")}}

- -

See also

- - diff --git a/files/ko/web/css/url()/index.html b/files/ko/web/css/url()/index.html new file mode 100644 index 0000000000..76904ccd73 --- /dev/null +++ b/files/ko/web/css/url()/index.html @@ -0,0 +1,80 @@ +--- +title: +slug: Web/CSS/url +tags: + - CSS + - CSS Data Type + - Layout + - Reference +translation_of: Web/CSS/url() +translation_of_original: Web/CSS/url +--- +
{{ CssRef() }}
+ +

<url> CSS 자료형은 이미지나 글꼴 등 리소스를 가리키는 문자열을 나타냅니다. URL은 {{ Cssxref("background-image") }}, {{ Cssxref("cursor") }}, {{ cssxref("list-style") }} 등 다양한 속성에서 사용할 수 있습니다.

+ +
+

URI와 URL URI와 URL은 다릅니다. URI는 단순히 리소스의 식별자입니다. URL은 URI의 종류 중 하나로, 리소스의 위치를 표현합니다. URI는 URL일 수도 있고, 리소스의 이름(URN)일 수도 있습니다.

+ +

CSS Level 1의 url() 함수형 표기법은 순수 URL을 나타낼 때만 사용했고, CSS Level 2에서 범위가 늘어나 URL이나 URN 등 어떤 URI도 사용할 수 있도록 바뀌었습니다. 이로써 url()을 사용해 <uri> CSS 자료형을 표현할 수 있었는데, 이상한 방식인데다 실제 CSS에서 URN은 거의 사용하지 않았으므로 불필요하다고 생각할만한 점이었습니다. CSS3에서는 혼란을 잠재우기 위해 초기의 더 좁은 정의로 돌아갔기 때문에 이제 url()<url>만을 나타낼 수 있습니다.

+
+ +

구문

+ +

<url> 자료형은 url() 함수형 표기법을 사용해 설정합니다. 따옴표는 선택사항으로 작은따옴표, 큰따옴표 둘 다 사용할 수 있습니다. 상대 URL도 사용할 수 있으며, 웹페이지의 URL이 아닌 스타일시트의 URL을 기준으로 사용합니다.

+ +
<a_css_property>: url("http://mysite.example.com/mycursor.png")
+<a_css_property>: url('http://mysite.example.com/mycursor.png')
+<a_css_property>: url(http://mysite.example.com/mycursor.png)
+
+ +
+

참고: Firefox 15부터, 0x7e을 초과하는 제어 문자는 URL을 따옴표로 둘러싸야 유요합니다. 자세한 내용은 {{Bug(752230)}}을 참고하세요.

+
+ +

예제

+ +
.topbanner {
+  background: url("topbanner.png") #00D no-repeat fixed;
+}
+
+ +
ul {
+  list-style: square url(http://www.example.com/redball.png);
+}
+
+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{ SpecName('CSS3 Values', '#urls', '<url>') }}{{ Spec2('CSS3 Values') }}No significant change from CSS Level 2 (Revision 1).
{{ Specname('CSS2.1', 'syndata.html#uri', '<uri>') }}{{ Spec2('CSS2.1') }}No significant change from CSS Level 1.
{{ SpecName('CSS1', '#url', '<url>') }}{{ Spec2('CSS1') }}Initial definition.
+ +

브라우저 호환성

+ + + +

{{Compat("css.types.url")}}

diff --git a/files/ko/web/css/url/index.html b/files/ko/web/css/url/index.html deleted file mode 100644 index 76904ccd73..0000000000 --- a/files/ko/web/css/url/index.html +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: -slug: Web/CSS/url -tags: - - CSS - - CSS Data Type - - Layout - - Reference -translation_of: Web/CSS/url() -translation_of_original: Web/CSS/url ---- -
{{ CssRef() }}
- -

<url> CSS 자료형은 이미지나 글꼴 등 리소스를 가리키는 문자열을 나타냅니다. URL은 {{ Cssxref("background-image") }}, {{ Cssxref("cursor") }}, {{ cssxref("list-style") }} 등 다양한 속성에서 사용할 수 있습니다.

- -
-

URI와 URL URI와 URL은 다릅니다. URI는 단순히 리소스의 식별자입니다. URL은 URI의 종류 중 하나로, 리소스의 위치를 표현합니다. URI는 URL일 수도 있고, 리소스의 이름(URN)일 수도 있습니다.

- -

CSS Level 1의 url() 함수형 표기법은 순수 URL을 나타낼 때만 사용했고, CSS Level 2에서 범위가 늘어나 URL이나 URN 등 어떤 URI도 사용할 수 있도록 바뀌었습니다. 이로써 url()을 사용해 <uri> CSS 자료형을 표현할 수 있었는데, 이상한 방식인데다 실제 CSS에서 URN은 거의 사용하지 않았으므로 불필요하다고 생각할만한 점이었습니다. CSS3에서는 혼란을 잠재우기 위해 초기의 더 좁은 정의로 돌아갔기 때문에 이제 url()<url>만을 나타낼 수 있습니다.

-
- -

구문

- -

<url> 자료형은 url() 함수형 표기법을 사용해 설정합니다. 따옴표는 선택사항으로 작은따옴표, 큰따옴표 둘 다 사용할 수 있습니다. 상대 URL도 사용할 수 있으며, 웹페이지의 URL이 아닌 스타일시트의 URL을 기준으로 사용합니다.

- -
<a_css_property>: url("http://mysite.example.com/mycursor.png")
-<a_css_property>: url('http://mysite.example.com/mycursor.png')
-<a_css_property>: url(http://mysite.example.com/mycursor.png)
-
- -
-

참고: Firefox 15부터, 0x7e을 초과하는 제어 문자는 URL을 따옴표로 둘러싸야 유요합니다. 자세한 내용은 {{Bug(752230)}}을 참고하세요.

-
- -

예제

- -
.topbanner {
-  background: url("topbanner.png") #00D no-repeat fixed;
-}
-
- -
ul {
-  list-style: square url(http://www.example.com/redball.png);
-}
-
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{ SpecName('CSS3 Values', '#urls', '<url>') }}{{ Spec2('CSS3 Values') }}No significant change from CSS Level 2 (Revision 1).
{{ Specname('CSS2.1', 'syndata.html#uri', '<uri>') }}{{ Spec2('CSS2.1') }}No significant change from CSS Level 1.
{{ SpecName('CSS1', '#url', '<url>') }}{{ Spec2('CSS1') }}Initial definition.
- -

브라우저 호환성

- - - -

{{Compat("css.types.url")}}

diff --git a/files/ko/web/css/visual_formatting_model/index.html b/files/ko/web/css/visual_formatting_model/index.html new file mode 100644 index 0000000000..4b32d08a30 --- /dev/null +++ b/files/ko/web/css/visual_formatting_model/index.html @@ -0,0 +1,223 @@ +--- +title: 시각적 서식 모델 +slug: Web/Guide/CSS/Visual_formatting_model +tags: + - 씨에스에스 + - 씨에스에스 상자 모델 + - 참조 +translation_of: Web/CSS/Visual_formatting_model +--- +
{{CSSRef}}
+ +

씨에스에스 시각적 서식 모델 (visual formatting model) 은 문서를 처리하여 그것을 시각적 매체에 표시하는 알고리즘입니다. 이 모델은 씨에스에스의 기본 개념입니다.

+ +

시각적 서식 모델은 문서의 각 요소를 변환하여, 씨에스에스 상자 모델에 부합하는 0, 1 또는 여러 상자를 생성합니다. 각 상자의 조판은 다음과 같이 정의됩니다:

+ +
    +
  • 상자의 면적: 정확히 정의하거나 제약을 받거나, 아에 정의하지 않습니다.
  • +
  • 상자의 유형: 인라인, 인라인수준, 원자 인라인수준, 블록.
  • +
  • 위치잡기 기법: 일반 대열 소속, 부동체, 또는 절대 위치잡기.
  • +
  • 트리 구조에 속한 다른 요소 무리: 그것의 자녀와 이웃.
  • +
  • {{glossary("viewport")}} 크기와 위치.
  • +
  • 컨테이너에 속한 이미지의 고유한 면적.
  • +
  • 다른 외부 정보
  • +
+ +

동 모델은 컨테이너 블록의 모서리 기준과 비례하여 상자를 렌더링합니다. 보통, 하나의 상자는 자기 자손들을 위한 컨테이너 블록을 수립합니다. 그러나 상자는 자신의 상위 컨테이너 블록에 구속되지 않습니다. 상자 조판이 상위 컨테이너 블록을 벗어나면 대열이탈 (overflow) 했다고 말합니다..

+ +

상자 생성

+ +

상자 생성은 해당 문서의 요소로부터 상자를 생성하는 씨에스에스 시각적 서식 모델의 일부입니다. 생성된 상자는 다양한 유형으로, 이 유형은 시각적 서식이 이뤄지는 방식에 영향을 미칩니다. 생성되는 상자 유형은 {{ cssxref("display") }} 씨에스에스 속성의 값 여하에 따라 달라집니다.

+ +

블록수준 요소와 블록 상자

+ +

어떤 요소를 블록수준이라고 말하려면 계산된 {{ cssxref("display") }} 씨에스에스 속성값이 block, list-item, 또는 table일 때입니다. 블록수준 요소는 사실상 하나의 블록으로 취급되어 시각적으로 서식되며, 수직적으로 겹겹이 포개집니다.

+ +

각각의 블록수준 상자는 블록 서식 상황에 참여합니다. 각 블록수준 요소는 적어도 하나의 블록수준 상자를 생성하며 이를 일컬어 수석 블록수준 상자 (principal block-level box) 라고 합니다. 일부 요소 무리는 목록항목 요소와 같이 목록 항목을 안내하는 글머리표와 서로 다른 타이포그래픽 요소를 처리하기 위한 상자를 추가적으로 생성하듯 더 많은 상자 무리를 생성할 수 있습니다. 대다수는 수석 블록 수준 상자만을 생성합니다.

+ +

수석 블록수준 상자는 자손이 생성한 상자 및 콘텐츠를 포함합니다. 상자는 위치잡기 기법에도 관여하고 있습니다.

+ +

venn_blocks.png블록 수준 상자는 역시 블록 콘테이너 상자도 될 수 있습니다. 블록 컨테이너 상자는 다른 블록수준 상자만을 포함하고 인라인 서식 상황을 생성하므로 인라인 상자 무리만을 포함합니다.

+ +

중요한 점은 블록수준 상자와 블록 컨테이너 상자의 개념은 별개라는 점에 유의해야 한다는 것입니다. 첫째, 상자가 자기 부모와 형제자매과 함께하는 행동 방식을 설명합니다. 둘째, 상자가 자기 자손과는 어떻게 상호작용하는지 설명합니다. 테이블과 같은 블록 수준의 상자 무리는 블록 컨테이너 상자가 아닙니다. 마찬가지로 비객원 (non-replaced) 인라인 블록과 비객원 테이블 셀과 같은 일부 블록 컨테이너 상자는 블록 수준 상자가 아닙니다.

+ +

또한, 블록 컨테이너 상자이며 동시에 블록수준 상자를 일컬어 우리는 블록 상자 (block boxes) 라고 부릅니다.

+ +

무명 블록 상자

+ +

경우에 따라서는 시각적 서식 알고리즘은 보충 상자를 추가할 알고리즘도 필요합니다

+ +

씨에스에스 선택기는 해당 상자에 이름을 부여하거나 스타일링을 할 수 없기 때문에 이를 일컬어무명 상자라고 합니다.

+ +

선택기는 무명 상자와 협력하지 않기 때문에 스타일시트를 통해 스타일링이 적용될 수 없습니다. 즉, 상속할 수 있는 모든 씨에스에스 속성은 inherit 값을 갖고 상속할 수 없는 씨에스에스 속성은 initial 값을 가집니다.

+ +

상자를 포함하는 블록은 인라인수준 상자 또는 블록수준 상자만을 포함합니다. 그러나 문서는 두 가지 모두를 혼합해 포함합니다. 그 경우 무명 블록 상자는 인접 인라인수준 상자 주변에 생성됩니다.

+ +

예제

+ +

아래와 같은 ({{ HTMLElement("div") }}와 {{ HTMLElement("p") }}에 기본값 스타일링이 적용된 에이치티엠엘 코드가 display: block 속성을 갖고 있다면:

+ +
<div>약간의 인라인 텍스트 <p>뒤를 잇는 단락 하나</p> 그 뒤를 잇는 인라인 텍스트.</div>
+ +

두 개의 무명 블록 상자가 만들어집니다: 하나는 단락 이전 텍스트(약간의 인라인 텍스트) 나머지 하나는 단락 이후 텍스트(그 뒤를 잇는 인라인 텍스트). 이는 다음과 같은 블록 구조를 구축합니다:

+ +

anonymous_block-level_boxes.png

+ +

결과는:

+ +
약간의 인라인 텍스트
+뒤를 잇는 단락 하나
+그 뒤를 잇는 인라인 텍스트.
+
+ +

{{ HTMLElement("p") }} 요소인 상자와 달리 웹 개발자는 두 개의 무명 상자 스타일을 제어할 수 없습니다. 상속 가능한 속성은 (마치 텍스트의 색상을 정의하기 위한 {{ cssxref("color") }}와 같이) {{ HTMLElement("div") }}의 속성 값에서 값을 취하고, 나머지는 초기(initial)값으로 설정합니다. 예를 들어, 무명 상자는 {{ cssxref("background-color") }}를 갖지 않을 것이라, 항상 해당 속성의 초기(initial)값을 가지며 투명합니다. 따라서 <div>의 배경이 보여집니다. 특정 배경색은 <p> 상자에 적용할 수 있습니다. 마찬가지로 두 무명 상자는 항상 같은 색을 텍스트에 사용합니다.

+ +

무명 블록 상자를 만드는 또 다른 사례는 하나 또는 여러 개의 블록 상자를 포함하는 인라인 상자입니다. 이 경우 블록 상자가 들어있는 상자는 두 개의 인라인 상자로 쪼개집니다. 하나는 블록 상자 이전에, 다른 하나는 뒤에 옵니다. 블록 상자 이전의 모든 인라인 상자는 무명 블록 상자로 포섭되며, 블록 상자 뒤에 있는 인라인 상자도 마찬가지입니다. 따라서 블록 상자는 인라인 요소를 포함하는 두 개의 무명 블록 상자의 형제가 됩니다.

+ +

중간에 인라인 콘텐츠가 없이 여러 블록 상자가 있는 경우 무명 블록 상자가 해당 상자 집합 이전과 이후에 생성됩니다.

+ +

예제

+ +

아래 에이치티엠엘 코드를 보면 {{ HTMLElement("p") }}는 display: inline 속성을 갖고 있고 {{ HTMLElement("span") }}는 display:block 속성을 갖고 있습니다:

+ +
<p>일부 <em>인라인</em> 텍스트 <span>그 뒤를 잇는 단락</span> 그 뒤를 잇는 추가 인라인 텍스트.</p>
+ +

두 개의 무명 블록 상자가 생성되었습니다. 스팬 요소 이전의 텍스트(일부 인라인 텍스트) 하나와 그 뒤의 텍스트(그 뒤를 잇는 추가 인라인 텍스트) 하나가 있는데 이로써 다음과 같은 블록 구조가 주어졌습니다:

+ +

+ +

이 것의 결과는:

+ +
약간의 인라인 텍스트
+뒤를 잇는 단락 하나
+그 뒤를 잇는 인라인 텍스트.
+
+ +

인라인수준 요소와 인라인 상자

+ +

어떤 요소가 인라인수준이라고 말하려면 자신의 계산된 {{ cssxref("display") }} 씨에스에스 속성 값이 inline, inline-block 또는 inline-table일 때입니다. 시각적으로는 이것은 콘텐츠로 이뤄진 블록 무리를 구성하지 않고 다른 인라인수준 콘텐츠와 함께 라인의 형태로 배포됩니다. 일반적으로 강조 또는 이미지와 같이 서로 다른 서식을 가진 단락의 콘텐츠는 인라인수준 요소로 만들어집니다.

+ +

venn_inlines.png

+ +
+

이 도식은 구식 용어를 사용합니다: 아래 참조 사항을 보세요. 그것 이외에도 오른쪽의 노란색 타원은 정의에 따르면 왼쪽의 타원형과 동일하거나 그보다 크기 때문에(수학적 상위집합일 수 있어) 그림이 틀렀습니다, 왜냐하면 해당 씨에스에스 스펙을 보면 "인라인수준 요소는 인라인 서식 상황에 참여하는 상자인 인라인수준 상자를 생성한다"라고 쓰여있기 때문입니다. 씨에스에스 2.2, 9.2.2장 참조

+
+ +

인라인 수준 요소는 인라인 서식 상황에 참여하는 상자로 정의되는 인라인수준 상자를 생성합니다. 인라인 상자는 상자와 인라인 수준 상자 모두가 해당합니다. 다만 이들 상자의 콘텐츠는 인라인 서식 상황에 참여해야 합니다. 예를 들어, display: inline 속성을 가진 모든 비객원 상자의 경우가 인라인입니다. 인라인 서식 상황에 참여하지 않는 인라인수준 상자를 원자 인라인수준 상자 (atomic inline-level boxes) 라고 합니다. 객원 인라인수준 요소 또는 계산된 {{ cssxref("display") }} 값이 inline-block인 요소에 의해 생성된 해당 상자 무리는 인라인 상자에서 가능했던 것처럼 여러 상자로 쪼개지지 않습니다.

+ +
참고: 처음에는 원자 인라인수준 상자를 원자 인라인 상자라고 불렀습니다. 그 명명은 불행한 일입니다. 인라인 상자가 아니기 때문입니다. 이건 씨에스에스 규격 상에 오타로 시정된 겁니다. 그렇긴 하지만, 문장 속에서 원자 인라인 상자를 마주칠 때마다 무리없이 원자 인라인 수준 상자로 읽을 수 있습니다. 그냥 이름 변경에 불과하기 때문입니다.
+ +
원자 일라인 상자는 인라인 서식 상황 속에서 여러 라인에 걸쳐 분할될 수 없습니다. +
+
<style>
+  span {
+    display:inline; /* default value*/
+  }
+</style>
+<div style="width:20em;">
+   스팬 요소에 포함된 택스트는 <span> 몇 개의 라인으로 분할 될 수
+   있습니다. 왜냐면 </span> 그것이 인라인 상자이기 때문입니다.
+</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;">
+   스팬 요소에 포함된 텍스트는 <span>몇 라인으로 분할 될 수
+   없 습니다. 왜냐면 </span> 그것이 인라인 블록이기 때문입니다.
+</div>
+
+ +

이 것의 결과는:

+ +
스팬 요소에 포함된 텍스트는 분할될 수 없습니다. 왜냐면 인라인 블록 상자이기 때문입니다.
+
+
+ +

무명 인라인 상자

+ +

블록상자처럼 씨에스에스 엔진에 의해 자동적으로 인라인상자가 생성되는 경우가 몇 개 있습니다. 이들 인라인 상자는 무명으로, 선택기가 이름을 특정할 수 없습니다. 무명 인라인 상자의 속성은, 상속 가능한 것은 상속된 값을, 그 이외는 initial 값을 가집니다.

+ +

무명의 인라인 상자가 만들어지는 흔한 경우는 인라인 서식 상황을 만드는 블록상자의 직계 자식 요소로 파악되는 텍스트가 있는 경우입니다. 이 경우, 동 텍스트는 최대한 큰 무명 인라인 상자에 넣을 수 있습니다. 또한, 씨에스에스의 {{ cssxref("white-space") }} 속성으로 지정된 동작에 의해 제거되는 공백의 콘텐츠는 결국 공백이 될 것이기 때문에 무명 인라인 상자를 생성하지 않습니다.

+ +
예제 TBD
+ +

다른 유형의 상자

+ +

라인 상자

+ +

라인 상자는 텍스트 라인을 표현하기 위해 인라인 서식 상황에 의해 생성되는 상자입니다. 블록 상자 내부의 라인 상자는 상자의 한쪽 테두리로부터 반대측의 테두리까지 넓어집니다. 부동체가 있을 경우 라인 상자 구역은 왼쪽 부동체의 맨우측 테두리에서 시작해 우측 부동체의 맨좌측 테두리에서 끝납니다.

+ +

이들 상자는 기술적인 것으로, 보통 웹 저술가가 이것에 대해 고민할 필요는 없습니다.

+ +

내부진행 상자

+ +

display: run-in을 사용하도록 정의되는 내부진행 상자 (Run-in boxes) 는 후속 상자의 유형 여하에 따라 블록 상자이거나 인라인 상자입니다. 그들은 가능할 경우 자신의 첫 단락 내부에 진행하는 글 제목을 생성하는 데 사용될 수 있습니다.

+ +
참고: 내부진행 상자는 씨에스에스 2.1 규격에서 제외되었다. 상호운용 실현 가능성을 불충분하게 명시했기 때문입니다. 그들이 씨에스에스 3 (CSS 3) 에선 다시 등장할 수도 있지만, 현재로선 실험 상태로 간주합니다. 그들을 완성품에선 사용하지 말아야 합니다.
+ +

모델유인 상자

+ +

인라인 및 블록 서식 상황 외에도 씨에스에스는 요소에 적용할 수 있는 몇 가지 추가 콘텐츠 모델을 지정할 수 있습니다. 특정 레이아웃을 설명하는 데 사용되는 이러한 추가 모델은 추가 상자 유형을 정의할 수 있습니다.

+ +
    +
  • 테이블 콘텐츠 모델테이블 래퍼 상자테이블 상자를 생성할 수 있을뿐만 아니라 캡션 상자같은 특정 상자도 생성할 수 있습니다.
  • +
  • The 다단 콘텐츠 모델 은 컨테이너 상자와 컨텐츠 사이에 열 상자 (column boxes) 를 생성할 수 있습니다.
  • +
  • 실험적인 격자 또는 가변상자 콘텐츠 모델, 또는 추가적인 유형의 상자를 생성할 수 있습니다.
  • +
+ +

위치잡기 기법

+ +

상자를 생성하고 나면 씨에스에스 엔진은 그것들을 조판에 위치시켜야 합니다. 그렇게 하려면 다음과 같은 알고리즘 중의 하나를 사용합니다.

+ +
    +
  • 일반 대열 (normal flow) - 하나씩 차례대로 상자를 위치시킵니다.
  • +
  • 부동체 (floats) 알고리즘 - 일반 대열에서 상자를 빼내어 상위 컨테이너 상자 옆에 놓습니다.
  • +
  • 절대 위치잡기 기법 - 자신의 상위 컨테이너 요소가 수립한 절대 좌표 시스템 내부에 상자를 위치시킵니다. 절대적으로 위치잡기한 요소는 다른 요소를 덮을 수 있습니다.
  • +
+ +

일반 대열

+ +

일반 대열 속 상자 무리는 하나씩 차례대로 배치됩니다. 블록 서식 상황 속에서 그들은 수직으로 배치됩니다. 반면에 인라인 서식 상황 속에서 그들은 수평으로 배치됩니다. 일반 대열은 CSS {{ cssxref("position") }}이 static 또는 relative 값으로 설정될 경우와 {{ cssxref("float") }}가 none으로 설정되면 발동됩니다.

+ +

예제

+ +
일반 대열 속에서는 블록 서식 상황에 포함된 상자는 수직으로 하나씩 차례대로 배치됩니다.
+
+일반 대열 속에서는 인라인 서식 상황에 포함된 상자는 수평으로 하나씩 차례대로 배치됩니다.
+ +
+

일반 대열에는 두 가지 하위 사례가 있습니다. 정적 위치잡기와 상대 위치잡기:

+ +
    +
  • 정적 위치잡기에서는 {{ cssxref("position") }} 속성이 static 값일 경우에 발동됩니다. 상자 무리는 일반 대열 조판에 정의된 정확한 위치에 그려집니다.
  • +
  • 상대 위치잡기에서는 {{ cssxref("position") }} 속성이 relative 값일 경우 발동합니다. 상자는 씨에스에스 속성 무리인 {{ cssxref("top") }}, {{ cssxref("bottom") }}과 {{ cssxref("left") }}, {{ cssxref("right") }}에 의해 정의된 간격띄우기 값을 기준으로 그려집니다.
  • +
+
+ +

부동체

+ +

부동 위치잡기 기법 (float positioning scheme) 에서는 특정 상자(부동 상자 또는 단순 부동체라고 일컬음)를 현재 라인의 시작 또는 끝에 위치시킵니다. 이는 텍스트(그리고 더 일반적으로 일반 대열 내의 모든 것)은 부동 상자의 가장자리를 따라 대열을 맞추는 속성으로 귀결됩니다. 다만 씨에스에스 {{ cssxref("clear") }} 속성에 의해 다른 예기가 나올 경우는 예외입니다.

+ +

상자에 대해 부동 위치잡기 기법을 선택하려면 해당 상대에 대해 씨에스에스 {{ cssxref("float") }} 속성을 none 이외의 값으로 설정하거나 {{ cssxref("position") }} 속성에 static이나 relative가 아닌 값으로 설정할 때 이뤄진다. 만일 {{ cssxref("float") }}가 left로 설정되면 부동체는 라인 상자의 시작 부분에 위치합니다. 만일 right으로 설정되면 동 부동체는 라인 상자의 끝에 위치합니다. 어떤 경우든 라인 상자는 부동체에 들어맞게 축소됩니다.

+ +

절대 위치잡기

+ +

절대 위치잡기 기법 (absolute positioning scheme) 에 포함된 상자는 대열에서 제거되어 대열과는 어떤 상호작용도 하지 않습니다. 그들은 {{ cssxref("top") }}과 {{ cssxref("bottom") }}, {{ cssxref("left") }}와 {{ cssxref("right") }}를 사용해서 상위 컨테이너 블록 기준으로 비례해서 위치잡기합니다.

+ +

하나의 요소를 절대 위치잡기하려면 {{ cssxref("position") }}이 absolute 또는 fixed로 설정하면 됩니다.

+ +

고정 위치잡기한 요소의 경우 상위 컨테이너 블록이 뷰포트입니다. 동 요소의 위치는 뷰포트 내부에서 절대적 위치가 됩니다. 스크롤링은 동 요소의 위치를 변경시키지 않습니다.

+ +

참조 항목

+ +
    +
  • {{css_key_concepts}}
  • +
diff --git "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\246\254\354\212\244\355\212\270/index.html" "b/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\246\254\354\212\244\355\212\270/index.html" deleted file mode 100644 index 0e0e215006..0000000000 --- "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\246\254\354\212\244\355\212\270/index.html" +++ /dev/null @@ -1,245 +0,0 @@ ---- -title: 리스트 -slug: Web/CSS/시작하기/리스트 -translation_of: Learn/CSS/Styling_text/Styling_lists -translation_of_original: Web/Guide/CSS/Getting_started/Lists ---- -

{{ CSSTutorialTOC() }}

-
- 중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/18)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
-

{{ previousPage("/en-US/docs/CSS/Getting_Started/Content", "내용물") }}CSS 시작하기 안내서 10번째 장; 이번 장에서는 CSS에서 리스트를 어떻게 보여줄 것인지  설정하는 법에 대해 알아보자. 리스트를 포함하는 새로운 예제 Document를 생성하고, 리스트 스타일을 위한 새로운 stylesheet도 생성하라.

-

정보: 리스트

-

지난 섹션에서 도전과제를 해결했다면, 어떤 elememt 앞에 리스트 아이템처럼 보여지는 내용물을 추가 하는 법을 보았을 것이다.

-

CSS는 리스트를 위한 특별한 속성을 제공한다. 이는 무엇보다도 사용하기 편리한 방법이다.

-

리스트 속성을 지정 하려면, {{ cssxref("list-style") }} 속성을 통해 마커 타입을 지정하라.

-

CSS에 있는 설렉터 규칙은 리스트 아이템 element를 선택 할 수도 있고(예를 들면, {{ HTMLElement("li") }}) 부모 리스트 element도 선택 가능하다. (예를 들면 {{ HTMLElement ("ul") }}) 리스트 element도 스타일을 상속 받는다.

-

무순서 리스트

-

무순서 리스트에서는, 각 리스트 아이템들이 같은 방식으로 mark된다.

-

CSS는 세가지 방법의 마커가 있다. 브라우저에서는 다음과 같이 보여진다.

-
    -
  • disc
  • -
  • circle
  • -
  • square
  • -
-

다른 이미지도 URL로 설정 가능하다.

-
-
- 예제
-

아래 규칙은 서로 다른 class의 리스트 아이템에 서로 다른 마커를 사용하고 있다.

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

When these classes are used in a list, they distinguish between open and closed items (for example, in a to-do list):

-
<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' class의 {{ HTMLElement("ol") }} elements에서, 아이템들이 대문자 순차 마커로 표시된다.

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

아래 리스트 내의 {{ HTMLElement("li") }} element는 위의 스타일을 상속한다.

- - - - - - -
-
    -
  • Lorem ipsum
  • -
  • Dolor sit
  • -
  • Amet consectetuer
  • -
  • Magna aliquam
  • -
  • Autem veleum
  • -
-
-
-
-
- 좀더 자세히
-

{{ cssxref("list-style") }}속성은 약어이다. 다소 복잡한 stylesheet에서는 속성과 그 값을 분리해서 사용하기를 원할 수 있다. 이 분리된 속성을 연결하는 방법이나 CSS에서 리스트에 더 자세한 설정법을 알려면{{ cssxref("list-style") }} 참조 페이지를 확인하라.

-

만약 HTML같은 관습적인 태그 비순차 리스트 아이템({{ HTMLElement("ul") }})와 순차 리스트 아이템({{ HTMLElement("ol") }})를 제공하는 마크업 언어를 사용한다면, 그 태그를 써서 쉽게 연습 해 볼 수 있다. 어쨌던 CSS써서 {{ HTMLElement("ul") }}를 순차 표시 할수 있고 {{ HTMLElement("ol") }} 를 통해 비순차를 원한다면 표시 할 수도 있다.

-

브라우저마다 리스트 스타일을 보여주는 자체 방식이 있다. Stylesheet로 모든 브라우저에서 동일하게 보여지는 것을 기대하지는 마라.

-
-

카운터

-
-

참고:  일부 브라우저는 카운터를 지원하지 않는다. Quirks Mode site의 CSS 내용물과 브라우저 호환성 페이지에 브라우저 호환 차트와 CSS의 다른 기능에 대한 호환성을 확인 할 수 있다. 이 사이트 CSS 참조Reference의 individual page(?)에는 브라우저 호환성 테이블도 확인 할 수 있다.

-
-

리스트 아이템 나열 뿐 아니라 Element를 순위매김 하기 위해 카운터를 사용할 수 있다. 예를 들어, documents내에서 머릿말니아 단락의 순서를 표시 하고 싶을때 사용 가능하다.

-

순위 매김을 사용하려면 카운터에 이름을 할당하여 사용하면 된다.

-

element에 순위메김 추가를 시작하기 전에 {{ cssxref("counter-reset") }}속성으로 초기화 하고 사용하고자 하는 카운터 이름을 쓰라. 카운터를 사용하는 elements의 부모에다 초기화 과정을 적용하는 것이 좋다. 그러나, 리스트 아이템 시작하기 전 어느 element에서든 초기화를 사용해도 된다.

-

카운터가 증가하는 각 element에서, {{ cssxref("counter-increment") }} 속성을 사용하여 증가 하고 증가 하고자 하는 이름도 표시하라.

-

카운터를 표시하기 위해서는 {{ cssxref(":before") }}나 {{ cssxref(":after") }} 설렉터를 써서 content속성을 사용하여라.(이전 페이지에서, Content사용에 대해 참고하라).

-

content 속성 값에 counter()카운터 이름과 함께 사용하라. 선택적으로 타입도 명시 가능하다. 타입은 위에서 언급한 Ordered lists 섹션에 나온것과 같다.

-

보통 카운터를 표시하는 element도 하나씩 카운터 값이 증가 한다.

-
-
- 예제
-

이 규칙은 class가 'numbered'인 모든 {{ HTMLElement("h3") }} element의 카운터를 초기화 한다.

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

 

-

이 아래 규칙은 모든 'numbered' class의 {{ HTMLELement("p") }} element에 카운터 값을 표시하고 그 값을 증가 시킨다.

-
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

-
-
-
-
- 좀더 자세히
-

카운터가 지원되지 않는 브라우저에서는 카운터를 사용 할 수 없다.

-

카운터가 사용 가능하다면 카운터로 리스트아이템에서 지원 되는 것처럼 별도로 다른 내용물에 순위매김을 사용 할 수 있다. 예를 들면 위에서 처럼, 카운터는 굵은 글씨로 그외 아이템은 정상 글씨로 가능하다.

-

좀더 다양한 방법으로 카운터를 사용 할 수 있는데 —예를 들면, 형식적인 Document의 순서 섹션, 머릿말, 보조 머릿말과 단락등에서 사용 가능하다. 자세한 사항은 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

-
-
-
- 도전
-

예제 stylesheet에 대양 표시 앞에 로마숫자로 i에서 v까지 나타나도록 추가 해 보라.

- - - - - - -
-

The oceans

-
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
-
-

 

-

예제 stylesheet를 아래와 같이 대문자가 단락앞에 나오도록 만들어 보라.

- - - - - - -
-

(A) The oceans

-

. . .

-

(B) Numbered paragraphs

-

. . .

-
-
-

정답 확인.

-

다음에는?

-

{{ nextPage("/en-US/docs/CSS/Getting_Started/Boxes", "상자") }}브라우저에서 예제 Document를 표시할때, element를 페이지에 element 주변으로 공간을 만든다. 다음장에서는 CSS가 어떻게 element아래쪽에 놓인 박스 모양과 동작하는지 설명한다(boxes.xm).

diff --git "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\257\270\353\224\224\354\226\264/index.html" "b/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\257\270\353\224\224\354\226\264/index.html" deleted file mode 100644 index 2c9fceaca0..0000000000 --- "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\257\270\353\224\224\354\226\264/index.html" +++ /dev/null @@ -1,346 +0,0 @@ ---- -title: 미디어 -slug: Web/CSS/시작하기/미디어 -translation_of: Web/Progressive_web_apps/Responsive/Media_types ---- -

{{ CSSTutorialTOC() }}

-
- 중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/21)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
-

{{ previousPage("/en-US/docs/CSS/Getting_Started/Tables", "테이블") }}CSS 시작하기 안내서의 14번쨰 장. 지금까지 이번 안내서에서는 많은 부분을 Document를 어떻게 보여 줄것인지 결정하는 CSS의 속성과 변수에 관해 소개 했다. 이번에는 Stylesheet의 구조와 목적에 대해 다시 살펴 보자.

-

정보 : 미디어

-

CSS의 목적은 Document가 사용자에게 어떻게 보여질 것인가를 설정하는 것이다. 전시되는 형태는 하나 이상의 형식이 있다.

-

예를 들면, 아마도 이 페이지도 화면 표시 장치를 통해 보여질 것이다. 그러나 큰 화면용으로 프로젝터나 프린트해서 보는 경우도 있을 것이다. 이런 다양한 미디어의 경우 그 고유의 문자셋같은 특징이 있을 것이다. CSS는 document를 각각의 미디어에 표시하기 위한 다양한 방법을 제공한다.

-

미디어의 특정 타입을 정하는 규칙을 추가 하려면 {{ CSSXref("@media") }} 다음에 미디어 타입 넣고, 그 다음에 대괄호({})로 해당 규칙을 추가 하라.

-
-
- 예제
-

웹사이트에 있는 document는 그 사이트 전체를 살펴볼수 있도록 조절 할 수 있는 영역을 제공한다.

-

마크업 언어에서는, 조정영역의 부모 element의 idnav-area이다. ({{ HTMLVersionInline(5) }}에서는 id 속성이 포함된 {{ HTMLElement("div") }}대신에 {{ HTMLElement("nav") }} element로 사용 할 수 있다.)

-

Document가 프린트 될 경우는 이 조정 영역이 필요 없으므로 stylesheet에서는 완전히 이 영역을 제거한다.

-
@media print {
-  #nav-area {display: none;}
-  }
-
-
-

일반적인 미디어 타입은 아래와 같다.

- - - - - - - - - - - - - - - - - - - -
screen컬러 컴퓨터 표시 장치
print출력 장치
projection프로젝트 출력 장치
all그외 모든 미디어 장치(기본 설정)
-
-
- 좀더 자세히
-

한 무리의 규칙들의 미디어 타입을 설정하는데는 다른 방법들도 있다.

-

Stylesheet가 document로 연결되어 있을때 document의 마크업 언어는 미디어 타입을 설정하는 것을 허용한다. 예를 들면, HTML내의 LINK 태그에서 media속성으로 옵션항목으로 미디어 타입을 설정 할 수 있다.

-

CSS에서 stylesheet의 앞부분에 {{ CSSXref("@import") }}로 URL로 부터 다른 stylesheet를 불러 올 수 있다. 추가적으로 미디어 타입도 사용 가능하다.

-

이와 같은 규직으로, 미디어 타입별로 다른 파일에 분리하여 관리 가능하다. 이렇게 함으로써 stylesheet를 구조화하는데 유용하게 사용한다.

-

좀더 자세한 미디어 타입에 대해서는 CSS의 사양서중 Media를 참고하라.

-

{{ cssxref("display") }}속성에 대해서 좀더 자세한 사항은 이 안내서 나중에 소개될 XML data를 참고하라.

-
-

출력

-

CSS에는 인쇄 매체나 프린터 출력을 위한 특별 지원을 한다

-

{{ cssxref("@page") }} 규칙을 통해 여백을 설정할 수 있다. 양면출력을 위해서는 @page:left@page:right로 각각의 여백을 개별로 설정 할 수 있다.

-

출력 매체를 위해 사용되는 단위는 인치 (in), 포인트(pt = 1/72 inch), 센티미터(cm)와 밀리미터(mm)등을 사용 할 수 있다. 글자 크기 설정과 맞추기 위해 사용하는 ems(em)과 퍼센트(%)도 사용하기에 적절하다.

-

Document의 내용중 페이지 분할을 위해서는 { cssxref("page-break-before") }}나 {{ cssxref("page-break-after") }}, {{ cssxref("page-break-inside") }}속성을 사용할 수 있다.

-
-
- 예제
-

아래 예제는 페이지 여백 4방향 모두를 1인치로 설정한다.

-
@page {margin: 1in;}
-
-

 

-

아래 규칙은 모든 H1 element는 새 페이지에서 시작하도록 한다.

-
h1 {page-break-before: always;}
-
-
-
-
- 좀더 자세히
-

CSS의 출판 매체 지원에 대한 사항은 CSS사양서의 Paged media를 확인 하라.

-

CSS의 다른 특징처럼 프린트 출력도 브라우저의 설정에 따라 다르다. 예를 들어 모질라 브라주저는 프린트 출력시 기본 바깥 여백과 머릿말, 꼬릿말이 지원된다. 사용자가 어떤 브라우저를 사용하는지, 그 브라우저의 설정값 또한 알수 없기 때문에 해당 페이지 출력물 결과를 알수 없다.

-
-

사용자 인터페이스

-

CSS는 컴퓨터 모니터같은 표시장치를 위한 특별한 사용자 인터페이스를 지원한다. 이 속성으로 Document를 동적으로 사용자가 사용자 인터페이스로 동작 할 수 있도록 변경한다.

-

사용자 인터페이스 장치에 대한 특별한 미디어 타입은 없다.

-

단지 5가지 설렉터가 있을 뿐이다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
설렉터선택
E{{ cssxref(":hover") }}포인터가 E로 명시된 element위에 놓일 경우
E{{ cssxref(":focus") }}키보드 포커스를 가진 E element
E{{ cssxref(":active") }}사용자 현재 동작에 개임된 E element
E{{ cssxref(":link") }}최근에 방문하지 않은 URL을 가진 Hyperlink인 E element
E{{ cssxref(":visited") }}최근에 방문한 URL을 가진 Hyperlink인 E element
-
-

주의: :visited 설렉터에서 획득한 정보는 {{ gecko("2.0") }}에만 해당된다. 좀더 자세한 사항은 Privacy and the :visited selector을 보라.

-
-

{{ cssxref("cursor") }}속성은 포인터의 모양을 설정한다. 몇몇 일반적인 모양은 다음과 같다. 브라우저에서 마우스를 아래 리스트에 각각 아이템으로 옮기면 그 모양을 확인 할 수 있다.

- - - - - - - - - - - - - - - - - - - - - - - -
설렉터선택
pointer링크임을 나타낼때
wait프로그램이 실행중이라 입력을 받지 못하는 상태일때
progress프로그램이 작업을 수행하고 있지만 입력을 받을 수 있는 상태
default기본 상태(보통 화살표 모양)
-

{{ cssxref("outline") }}속성은 키보드 포커스를 가리키는 외곽선을 생성할때 사용한다. 그 값은 사용자가 방향을 설정할 수 없다는 것을 제외하고는 {{ cssxref("border") }}속성과 유사하다.

-

Some other features of user interfaces are implemented using attributes, in the normal way. For example, an element that is disabled or read-only has the disabled attribute or the readonly attribute. Selectors can specify these attributes like any other attributes, by using square brackets: {{ mediawiki.external('disabled') }} or {{ mediawiki.external('readonly') }}.

-
-
- Example
-

These rules specify styles for a button that changes dynamically as the user interacts with it:

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

 

-

This wiki does not support a user interface on the page, so these buttons do not "click". Here are some static images to illustrate the idea:

- - - - - - -
- - - - - - - - - - - - - - - - -
Click MeClick MeClick Me
 
disablednormalactive
-
-

 

-

A fully functional button also has a dark outline around the entire button when it is the default, and a dotted outline on the face of the button when it has keyboard focus. It might also have a hover effect when the pointer is over it.

-
-
-
- More details
-

For more information about user interfaces in CSS, see User interface in the CSS Specification.

-

There is an example of Mozilla's markup language for user interfaces, XUL, in Part II of this tutorial.

-
-

Action: Printing a document

-
    -
  1. Make a new HTML document, doc4.html. Copy and paste the content from here: -
    <!DOCTYPE html>
    -<html>
    -  <head>
    -    <title>Print sample</title>
    -    <link rel="stylesheet" href="style4.css">
    -  </head>
    -  <body>
    -    <h1>Section A</h11>
    -    <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. Make a new stylesheet, style4.css. Copy and paste the content from here: -
    /*** 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. View this document in your browser; it uses your browser's default style.
  6. -
  7. Print (or print preview) the document; the stylesheet places each section on a separate page, and it adds a header and footer to each page. If your browser supports counters, it adds a page number in the footer. - - - - - - - -
    - - - - - - -
    - - - - - - -
    -
    - 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. -
- - - - - - - -
- Challenges
Move the print-specific style rules to a separate CSS file. -

Read the {{ CSSXref("@import") }} reference page to find details of how to import the new print-specific CSS file into your style4.css stylesheet.

-

Make the headings turn blue when the mouse pointer is over them.

-
-

 See solutions to these challenges.

-

What next?

-

If you had difficulty understanding this page, or if you have other comments about it, please contribute to its Discussion page.

-

So far, all the style rules in this tutorial have been specified in files. The rules and their values are fixed. The next page describes how you can change rules dynamically by using a programming language: JavaScript

diff --git "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\260\260\354\271\230/index.html" "b/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\260\260\354\271\230/index.html" deleted file mode 100644 index 86ea912bb7..0000000000 --- "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\353\260\260\354\271\230/index.html" +++ /dev/null @@ -1,370 +0,0 @@ ---- -title: 배치 -slug: Web/CSS/시작하기/배치 -translation_of: Learn/CSS/CSS_layout -translation_of_original: Web/Guide/CSS/Getting_started/Layout ---- -

{{ CSSTutorialTOC() }}

- -
중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/19)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
- -

{{ previousPage("/en-US/docs/CSS/Getting_Started/Boxes", "상자")}}CSS 시작하기 안내서 12번째 장; 여기서는 Document의 배치를 정하는 몇몇 방법에 대해 알아본다. 예제 document를 좀 바꿔 보자.

- -

정보: 배치

- -

Document의 배치를 바꾸기 위해 CSS는 다양한 방법을 제공한다. 어떤 고급 기술은 여기 초급안내서의 범주를 훨씬 넘어서는 고급 기술이다.

- -

여러 브라우저에서의 결과물이 비슷하게 나오게 하기 위해, stylesheet값은 브라우저의 기본 stylesheet값과 배치값을 사용한다. 이 주제 또한 여기서의 초급과정보다 더 고급 과정이다.

- -

여기서는 간단한 기술에 대해 연습 해 보자.

- -

Document 구조

- -

만약 Document의 배치를 변경하려 한다면 이떤 경우에는 document 구조를 바꿔야 할지 모른다.

- -

document의 마크업 언어는 구조 생성을 위한 용도의 일반적인 태그를 가지고 있다. 예를 들면 HTML에서 구조를 생성 하기 위해 {{ HTMLElement("div") }} element를 사용 할 수 있다.

- -
-
예제
- -

예제 Document에서 Numbered paragraphs가 표시된 단락은 컨테이너 구조가 아니다.

- -

따라서 이 단락 주변에는 설렉터에서 이 element에 대해 정의 한 것이 없으므로 경계 박스를 그릴 수 없다.

- -

이 구조적 문제를 해결 하기 위해, {{ 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>
-
- -

이제 예제 stylesheet 에 두 리스트에 주변의 경계 표시를 위한 규칙 하나를 아래와 같이 추가 하자.

- -
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

-
-
-
- -

크기 단위

- -

지금까지 이 안내서에서는 크기를 픽셀(px)단위로 표시 해왔다. 컴퓨터 화면과 같은 출력장치에서는 어느 정도 적절한 표시 방법이다. 그러나, 사용자가 글씨 크기를 바꿔 버리면 화면 출력은 이상하게 엉켜버릴 수 있다.

- -

다양한 용도를 위해 크기는 백분위(%)값이나, 고정넓이폰트 값(em)으료 표시하는 것이 더 좋은 방법이다.  고정 넓이 폰트 값(em)은 현재 사용되는 글씨체중 'm'에 해당하는 넓이를 기준으로 하고 있다.(영문에서는 'm'이 가장 넓은 폰트이다). 사용자가 글씨 크기를 바꾸면 배치는 자동적으로 맞추어 질 것이다.

- -
-
예제
- -

아래 텍스트의 왼쪽에 있는 경계는 픽셀로 크기를 지정 했다.

- -

오른쪽은 고정 넓이 폰트값(aka ems)으로 지정 했다.

- -

브라우저에서 글씨 크기를 변경하고 확인 해보면 오른쪽은 적당한 크기를 유지하지만, 왼쪽은 그렇지 않다는 것을 확인 할 수 있을 것이다.

- - - - - - - -
-
RESIZE ME PLEASE
-
-
- -
-
좀더 자세히
- -

다른 기기에서는 다른 단위가 적절할 수 있다.

- -

이 안내서 나중 페이지에 이에 대해 좀더 자세히 알아 보도록 하자.

- -

변수 값과 단위에 대해 상세하게 확인 하고 싶다면 CSS 사양서의 Values 부분을 참고 하라.

-
- -

텍스트 배치

- -

element 내용물을 배치하는데는 두가지 속성이 있다. 이 두가지를 통해 간단하게 배치/정열을 조절 할 수 있다.

- -
-
{{ cssxref("text-align") }}
-
left, right, center, justify값로 할당하여 정열 할 수 있다.
-
{{ cssxref("text-indent") }}
-
들여쓰기를 위해 적당한 값을 명시하여 사용 한다.
-
- -

이 두 속성은 실제 텍스트 외에도 모든 텍스트 같은(text-like) element에도 영향을 미친다. 속성들은 부모로부터 자식까지 상송되므로, 자식 element에서 부모로 부터 받지 않으려는 속성에 대해서 정확하게 제거 하는 규칙을 추가 하지 않는다면 원하는 결과를 얻지 못할지 모른다.

- -
-
예제
- -

헤더를 가운데 정렬하려면

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

결과는 아래와 같다.

- - - - - - - -
-

(A) The oceans

-
- -

HTML document에서, 헤더 아래쪽에 보여지는 내용물(content)는 헤더에서 구조적으로 포함된 사항이 아니다. 그러므로 이와 같은 헤더를 정렬하려면 헤더 아래쪽 테그는 그 스타일을 상속 받아서는 안된다.

-
- -

부유(Floats)

- -

{{ cssxref("float") }}속성은 element를 강제로 왼쪽 혹은 오른쪽으로 정렬시킨다. 이것이 element의 위치와 크기를 조정하는 가장 간단한 방법이다.

- -

나머지 document의 내용물(content)는 부유 속성의 element 주변으로 떠있게 된다. {{ cssxref("clear") }} 속성을 통해서 element들을 부유 element로 부터 떨어져 고정 위치하도록 한다.

- -
-
예제
- -

예제 document에서 리스트는 윈도우의 크기에 맞게 늘어난다. 이를 방지하기 위해서는 부유속성으로 왼쪽으로 정렬되도록 하면 된다.

- -

아래 예로 헤더를 왼쪽 한곳에 고정 시키려면 clear속성과 left를 함께 선언 해 주어야 한다.

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

The result looks like:

- - - - - - - -
-

(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

-
-
- -

(텍스트가 경계선에 바짝 붙어 있다면 박스의 오른편에 약간의 내부 여백 필요할듯 하다.)

- -

위치잡기

- -

{{ cssxref("position") }}속성에 아래 4가지 방법으로 값을 선언하여 위치를 잡을 수 있다.

- -

더 많은 속성이 있지만 아래와 같은 간단한 방법으로(여기서는 초급 안내서이므로) 위치를 조정 할 수 있다. 그러나 아래 방법을 조합해서 쓴다면 다소 어려워 질 것이다.

- -
-
relative
-
element의 위치는 상대적으로 정해진다. 어느 정도 값을 지정 함으로 element를 위치 시킬 수 있다. element의 바깥 여백값을 설정함으로 이와 동일한 설정 효과를 볼 수도 있다.
-
fixed
-
고정 위치 설정법. document window에서의 상대적 위치를 지정하는 방법이다. document의 나머지 부분이 스크롤 되어야 할지라도 해당 element는 고정 값을 가진다.
-
absolute
-
부모 element의 위치에 상대적으로 위치가 고정된다. 그 부모 element는 위치 지정 방법이 relative, fixed or absolute 중 하나이어야 한다. element의 위치 속성을 releative로 설정 한다면 방향 표시를 하지 않더라도 어떠한 속성을 가진 부모 element에도 잘 동작 할 것이다.
-
static
-
기본 설정 값이다. 명확하게 상속받은 위치 지정을 해제하려면 이 값으로 선언 해야 한다.
-
- -

이 위치 지정 속성과 함께(static은 제외) 방향(top, right, bottom, left), 높이(width), 넓이(height) 크기(size)도 같이 지정 해야 한다.

- -
-
예제
- -

아래 두 element의 Top정렬을 동일한 위치에 설정 하려면 예제 Document의 두 element에 부모 container를 만들어라.

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

예제 stylesheet에서 부모 element의 위치 속성을 relative로 하라. 방향 속성까지 같이 할 필요는 없다.자식 element의 위치는 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;
-}
-
- -

결과는 아래처럼 백슬레쉬(\)와 슬레쉬(/)가 겹쳐서 위치 되도록 하였다.

- -
-

/

- -

\

-
- - - - - - - -
 
-
- -
-
좀더 자세히
- -

위치 지정에 대한 모든 내용은 CSS 사양서의 Visual formatting modelVisual formatting model details의 두 챕터에 나와 있다.

- -

다양한 브라우저에서 동작하도록 stylesheet를 설계하고자 한다면, 브라우저별로 표준을 다르게 해석하는 것과 특정 버전의 브라우저에 있는 버그에 대해서도 고려해야 한다.

-
- -

액션: 배치 선언

- -
    -
  1. doc2.html와 style2.css를 수정 하여 위에 나온Document structureFloats를 연습 해 보자.
  2. -
  3. Floats예제에서 텍스트를 오른쪽 경계와의 안쪽 여백을 0.5 em로 설정 하라.
  4. -
- -
-
도전
- -

doc2.html의 아래쪽 </body> 바로 위에 아래 태그를 추가하라.

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

아래 이미지를 다운로드 하지 않았다면 지금 다운로드 하고, 위의 예제 파일이 있는 곳으로 저장하라.

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

Document내에서 위의 이미지가 어느 위치에 표시될지 예상 해 보라. 그리고 브라우저에서 읽어들여 그 결과를 확인 해 보라.

- -

Document의 오른쪽 위에 자리 잡을 수 있도록 예제 stylesheet에 규칙을 추가 해 보라.

- -

브라우저에서 다시 읽어 보고 윈도우를 작게 조절 해 보라. 윈도우 크기를 조절 할때에도 Document가 Scroll될지라도 위의 이미지가 오른쪽 위에 계속 자리 하는지를 확인 해 보라.

- -
-
-

(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("/en-US/docs/CSS/Getting_Started/Tables", "테이블") }}이제까지 CSS의 초급 안내서에 나온 주제를 다 확인 해 보았다. 다음장에서 부터는 CSS 설렉터의 고급 기술과 테이블의 스타일을 설정하는 방법에 대해 알아보자.

diff --git "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\203\201\354\236\220/index.html" "b/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\203\201\354\236\220/index.html" deleted file mode 100644 index cc6b499241..0000000000 --- "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\203\201\354\236\220/index.html" +++ /dev/null @@ -1,331 +0,0 @@ ---- -title: 상자 -slug: Web/CSS/시작하기/상자 -translation_of: Learn/CSS/Building_blocks -translation_of_original: Web/Guide/CSS/Getting_started/Boxes ---- -

{{ CSSTutorialTOC() }}

- -
중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/19)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
- -

{{ previousPage("/en-US/docs/CSS/Getting_Started/Lists", "리스트") }}CSS 시작하기 안내서 11번째 장; 여기서는 CSS를 통해 element들이 보여질때 page의 공간을 어떻게 배치하는지에 대해 알아본다. 예제 documnet에서 각 element의 여백 조절과 꾸미기에 대해 배워 보자.

- -

정보: 상자

- -

Element를 브라우저에서 표시할때 그 Element는 공간을 자치 한다. 차지하는 공간에는 4가지 요소가 있다.

- -

가운데는, element의 내용물을 표시가는 공간이며, 주변은 안쪽 여백이 있고, 그 주변에 경계가 있으며, 다른 element와의 간격이 있다.

- - - - - - - - -
-
-

margin

- -

border

- -
-

padding

- -
-

element

-
-
-
- -

옅은 회색은 레이아웃의 구성을 보여준다.

-
-
-

 

- -

 

- -
-

 

- -
-

element

-
-
-
- -

브라우저에서는 위와 같이 보여준다.

-
- -

안쪽 여백, 경계 그리고 바깥 여백은 element에 대해 각각 top, right, bottom, left의 크기를 가진다. 이것들은 크기가 0이 될 수도 있다.

- -

색상입히기

- -

안쪽 여백 색상은 element의 배경과 항상 동일하게 유지된다. 배경색을 바꾼다면 element경과 안쪽 여백 색이 바뀌는 것을 확인 할 수 있을 것이다. 바깥 여백은 항상 투명하다.

- - - - - - - - -
-
-

margin

- -

border

- -
-

padding

- -
-

element

-
-
-
- -

element는 녹색 배경색이다..

-
-
-

 

- -

 

- -
-

 

- -
-

element

-
-
-
- -

브라우저에서 보면 위와 같다.

-
- -

경계

- -

라인이나 상자를 통해 element의 경계를 치장 할 수 있다.

- -

경계를 설정 하려면 {{ cssxref("border") }}속성을 이용하라. 두께(보통 표시 화면의 픽셀 두께), 스타일, 색상등을 설정 하라.

- -

스타일은 아래와 같다.

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

스타일을 none이라 hidden으로 설정하면 경계가 사라진다. 다른 방법으로는 경계 색상을 투명으로 설정하여 레이아웃을 변경하지 않고도 경계를 보이지 않게 할 수도 있다.

- -

경계를 각각 별개로 설정하기 위해서는{{ cssxref("border-top") }}, {{ cssxref("border-right") }}, {{cssxref("border-bottom")}}, {{cssxref("border-left")}}등으로 할  수 있다. 각 top, right, bottom, left는 개별적으로 설정이 가능하다.

- -
-
예제
- -

아래 규칙은 헤더 element의 윗쪽 경계와 배경색에 대한 속성을 지정 한다.

- -
h3 {
-  border-top: 4px solid #7c7; /* mid green */
-  background-color: #efe;     /* pale green */
-  color: #050;                /* dark green */
-  }
-
- -

결과는 아래와 같다.

- - - - - - - -
-

Stylish heading

-
- -

아래 규칙은 이미지 주변에 회색띠를 둘러서 경계를 구분하기 편하게 하고 있다.

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

결과는 아래와 같다.

- - - - - - - - -
Image:Image:Blue-rule.png
- -

내/외부 여백

- -

내/외부 여백을 이용하여(margins and padding) element의 위치와 그 주변의 여백을 설정 할 수 있다.

- -

바깥 여백은 {{ cssxref("margin") }}속성을 사용하며 내부여백은 {{ cssxref("padding") }}속성을 각각 사용한다.

- -

위의 속성으로 넓이 값을 하나 선언하면 element의 4방향(top, right, bottom and left) 모두 바뀐다.

- -

넓이 값을 두개 선언하면, 첫번째 값으로는 top, bottom값이 적용되고, 두번째 값으로는 right, left값이 바뀐다.

- -

4개 값을 각각 주기 위해서는 각 값을 top, right, bottom, left의 순서로 나열 하면 된다.

- -
-
예제
- -

아래는 p class가 remark인 단락을 빨간 경계박스로 만드는 규칙이다.

- -

안쪽 여백 값은 4픽셀으로 둘러져 있으며, 왼쪽 바깥 여백은 24픽셀이므로 들여쓰기 효과로 보여진다.

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

결과는 아래와 같다.

- - - - - - - -
-

Here is a normal paragraph.

- -

Here is a remark.

-
-
- -
-
좀더 자세히
- -

내/외부 여백으로 element의 배치를 할때는 브라우저에서 제공하는 기본 값과 사용자가 정의한 값을 바탕으로 정해지므로 조금 복잡할 수도 있다.

- -

브라우저에 따라 보이는 내용이 다를 수 있다. stylesheet에 내용을 많이 추가 할 수록 브라우저 기본값보단 설정된 값을 많이 사용하므로 더욱더 비슷한 결과물을 볼수 있을 것이다.

- -

원하는 결과물을 얻기 위해서는, Document의 마크업들을 바꿔야 할지도 모른다. 다음장에서는 이에 대해 좀더 자세히 알아보자.

- -

내/외부 여백과 경계선등에 대해 좀더 자세히 알아보려면 Box model를 참조하라.

-
- -

액션: 경계선 추가

- -

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

-
- -
-
도전
- -

예제 stylesheet에 하나의 규칙을 추가하여 아래처럼 바다가 연생되는 색으로 모든 경계를 두껍게 만들어 보라.

- - - - - - - -
-

(A) The oceans

- -
-
    -
  • Arctic
  • -
  • Atlantic
  • -
  • Pacific
  • -
  • Indian
  • -
  • Southern
  • -
-
- -

(B) Numbered paragraphs

- -

. . .

-
- -

 

- -

(여기 보이는 예제와 똑같은 두께나 색상으로 바꿀 필요는 없다.)

-
- -

결과 확인.

- -

다음에는?

- -

{{ nextPage("/en-US/docs/CSS/Getting_Started/Layout", "배치") }}지금까지 내/외부 여백을 설정하여 Document의 배치를 수정 해 보았다. 다음 장에서는 Document의 배치를 바꾸는 다른 방법에 대해 알아보자.

diff --git "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\242\205\354\206\215\352\263\274_\354\203\201\354\206\215/index.html" "b/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\242\205\354\206\215\352\263\274_\354\203\201\354\206\215/index.html" deleted file mode 100644 index 5c58432ad2..0000000000 --- "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\354\242\205\354\206\215\352\263\274_\354\203\201\354\206\215/index.html" +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: 종속과 상속 -slug: Web/CSS/시작하기/종속과_상속 -translation_of: Learn/CSS/Building_blocks/Cascade_and_inheritance -translation_of_original: Web/Guide/CSS/Getting_started/Cascading_and_inheritance ---- -

{{ CSSTutorialTOC() }}

- -
중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/14)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
- -

{{ previousPage("/en-US/docs/CSS/Getting_Started/How_CSS_works", "CSS 동작 원리")}}CSS 시작하기 안내서의 4번쨰 섹션; stylesheets가 종속적으로 동작하는 것과 element가 부모로 부터 style을 상속 받는 것에 대해 서술해 본다. 단순하게 document의 많은 Style중 어떤 Style을 사용할 것인지 한단계 상속만으로 하나의 Style을 stylesheet에 추가 할 수 있다.

- -

정보: 종속과 상속

- -

element의 최종 style은 다양한 상호작용을 통해 여러 장소에서 선언된 것을 사용할 수 있다. 이런 다양한 상호작용을 통해 CSS는 강력해 질 수 있으며, 반대로 디버그 하기에는 복잡하고 어려워 진다.

- -

종속의 세가지 주요 원천은 아래와 같다.

- -
    -
  • 마크업 언어를 위한 브라우저의 기본 style들
  • -
  • document를 읽는 사용자가 정의하는 styles
  • -
  • 만든이에 의해 Style은 Document와 연결된다. 다음 3곳에서 그 내용을 명시할 수 있다.These can be specified in three places: -
      -
    • 외부 파일: 이 안내서에서 주로 취급하는 Style에 대한 정의하는 법.
    • -
    • Document의 시작 부분에 정의하는 법: 선언한 Style은 선언된 Document의 페이지에서만 사용된다.
    • -
    • Document body의 특정 element에: 유지 보수가 가장 불편한 방법이며, 주로 테스트 용도로 쓴다.
    • -
    -
  • -
- -

사용자 Style은 브라우저의 기본 Style을 변경 할수 있다. document 만든이의 style 에서 더 수정 변경 될 수도 있다. 이 안내서에서는, 예제 Document에서 만든 자신만의 stylesheets를 만들 수 있다.

- -
-
예제
- -

이 문서를 브라우저로 보면, 일부 style은 브라우저의 기본 값을 사용한다.

- -

일부는 브라우저 셋팅에서 수정한 style이 저장된 파일에서 가져온다. 파이어 폭스 브라우저에서 "설정" 메뉴나, 브라우저 폴더에 있는 userContent.css 직접 수정하여 변경 가능하다.

- -

일부 style은 wiki server에 의해 Stylesheet에 정의된 값을 사용한다.

-
- -

예제 Document를 브라우저에서 열면, {{ HTMLElement("strong") }} elements로 지정된 문자는 다른 문자들 보다 두껍다. 이 Style은 기본 Style로 설정된 값에서 나온다.

- -

{{ HTMLElement("strong") }} elements의 색상은 red이다. 이 값은 예제 stylesheet에서 값을 가져 온다.

- -

{{ HTMLElement("strong") }} elements는 {{ HTMLElement("p") }} element의 자식 style이므로 대부분의 {{ HTMLElement("p") }} element의 style을 상속한다. 같은 방식으로, {{ HTMLElement("p") }} element는 {{ HTMLElement("body") }} element의 대부분의 style을 상속한다.

- -

종속적인 면에서 style은, 제작자(author)의 stylesheets가 사용자(reader) stylesheet보다도 브라우저의 기본 값보다도 우선 순위가 높다.

- -

상속적인 면에서는, 자식 노드의 자체 Style이 부모의 Style보다 우선 순위가 높다.

- -

우선 순위만 적용되는 것은 아니다. 페이지 아래부분에 좀더 자세히 설명 하도록 하자.

- -
-
좀더 자세히
- -

CSS는 !important 키워드를 써서 사용자(reader)가 document 제작자(author)의 style을 덮어 쓰는 방법도 제공힌다.

- -

이는 Document 제작자에게 사용자가 항상 제작자가 만든 내용을 그대로 본다는 것을 보장 하지 않는 다는 것을 의미한다.

- -

종속과 상속에 대해 자세히 알고 싶다면, CSS의 상세 사양서 중 속성 값 할당, 종속 및 상속 부분을 보라.

-
- -

액션: 상속 사용하기

- -
    -
  1. CSS 예제 파일을 편집해 보자.
  2. -
  3. 아래 라인을 추가 하라. 이미 문서 내에 존재하는 다른 내용이 있더라도 문서의 어디에 추가하든 상관 없다. 그러나, 맨 위에 추가 할수록 Document에 있는{{ HTMLElement("p") }} element가 {{ HTMLElement("strong") }} element의 부모가 되므로 지역적으로 영향을 미친다. -
    p {color: blue; text-decoration: underline;}
    -
    -
  4. -
  5. 이제 브라우저를 갱신하여 적용된 사항을 보라. 첫글자를 포함한 모든 문자들에 밑출이 그어져 있다. {{ HTMLElement("strong") }} elements는 부모{{ HTMLElement("p") }} element의 밑줄 속성을 상속 받았다.
    - -

    그러나 {{ HTMLElement("strong") }} elements는 여전히 붉은색이다. 붉은색 속성은 자체 속성이므로 부모인 {{ HTMLElement("p") }} element의 파란색 속성보다 우선한다.

    -
  6. -
- - -
- - - - - - - - -
Before
Cascading Style Sheets
- - - - - - - - -
After
Cascading Style Sheets
- -
-
도전
-Stylesheet를 변경하여 아래와 같이 붉은 글자만 밑줄 속성을 가지도록 수정 해 보라. - - - - - - - -
Cascading Style Sheets
- -
-
Possible solution
- -

Move the declaration for underlining from the rule for {{ HTMLElement("p") }} to the one for {{ HTMLElement("strong") }}. The resulting file looks like this:

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

 

-Hide solution
-정답 확인
- -

다음에는?

- -

{{ nextPage("/en-US/docs/CSS/Getting_Started/Selectors", "설렉터")}}예제 Stylesheet의 <p><strong> 태그를 원하는 style로 임으로 바꾸어 보라. 다음 장에는 설렉터를 사용하는 법에 대해 알아보자.

diff --git "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\214\354\235\264\353\270\224/index.html" "b/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\214\354\235\264\353\270\224/index.html" deleted file mode 100644 index 17a57d49e9..0000000000 --- "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\214\354\235\264\353\270\224/index.html" +++ /dev/null @@ -1,475 +0,0 @@ ---- -title: 테이블 -slug: Web/CSS/시작하기/테이블 -translation_of: Learn/CSS/Building_blocks/Styling_tables -translation_of_original: Web/Guide/CSS/Getting_started/Tables ---- -

{{ CSSTutorialTOC() }}

-
- 중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/20)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
-

{{ previousPage("/en-US/docs/CSS/Getting_Started/Layout", "배치") }}CSS 시작하기 안내서 13번째; 여기서는 고급 설렉터에 대해 알아보고, 테이블을 사용하는 특별한 방법에 대해 확인 해 보자. 테이블이 포함된 예제 Document와 여기서 사용될 Stylesheet를 만들어 보자.

-

정보 : 테이블

-

테이블이란 정보를 사각 격자 형태로 배치하는 것을 말한다. 어떤 테이블은 복잡하게 구성 될 수 있으며 그 복잡한 테이블은 브라우저마나 다르게 보여줄 수도 있다.

-

Document를 디자인 할때, 테이블을 이용하여 내용들 간의 관개정보들을 표시 할 수 있다. 브라우저별로 테이블을 조금 다르게 표시하여도 정보를 보여주는데는 크게 문제 되지 않는다.

-

시각적인 표시의 사용목적으로 테이블을 사용하는 것은 좋지 않다. 테이블 보다는 이전 페이지에 소개한 배치(Layout)를 사용하는 것이 더 좋은 방법이다.

-

테이블 구조

-

테이블에서는 각 내용들이 각 테이블 블럭에 표시된다.

-

테이블의 같은 줄의 블럭은 하나의 행을 구성한다.

-

몇몇 테이블에서는 행은 하나의 그룹으로 구성된다. 테이블의 첫 행의 그룹은 머릿말(header)로 사용된다.  테이블의 마지막 행의 그룹은 꼬릿말(footer)로 사용되기도 한다. 테이블의 다른 행들은 본문(body)이 되고 한 덩어리의 그룹으로 간주된다.

-

아래에 있는 블럭은 하나의 열(column)로 구성되었고 제한적으로 사용되는 CSS테이블 이다.

-
-
- 예제
-

설렉터페이지 내의 연관관계로 본 설렉터의 테이블은 10개의 셀 블럭으로 구성된 5행 테이블이다.

-

첫번째 행은 머릿말이고 나머지 4개행은 본문이다. 꼬릿말은 없다.

-

열은 2개이다.

-
-

여기 안내서는 간단한 예제만을 다루고 있으며, 그 결과물은 쉽게 예상 가능한 수준이다. 간단한 테이블에서는 모든 셀블럭들은 하나의 행/열만을 차지한다. 셀이 하나 이상의 행이나 열을 차지하는 복잡한 테이블 구성 방법도 CSS를 통해 표현 가능하다. 그러나 이런 고급기술은 초급 안내서의 범주를 벗어난다.

-

경계

-

셀 블럭은 바깥 여백이 없다.

-

셀블럭은 바깥 여백과 들여쓰기 공간이 없다. 기본적으로 경계는 테이블 내용과의 같격을 {{ cssxref("border-spacing") }}속성으로 조절 가능하다. 테이블의 {{ cssxref("border-collapse") }}속성을 collapse로 설정하면 이 여백을 없앨 수 있다.

-
-
- 예제
-

여기 세가지 테이블을 확인 해 보자.

-

왼쪽 테이블은 0.5 em 경계 여백을 가지고 있다. 가운데는 경계 여백을 0으로 했으며, 오른쪽은 collapse속성을 사용 하였다.

- - - - - - - - -
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
- - - - - - - - - - - -
ClubsHearts
DiamondsSpades
-
-
-

캡션

-

캡션({{ HTMLElement("caption") }}) elemen전체 테이블에 적용되는 라벨이다. 기본적으로 테이블 위쪽에 표시된다.

-

캡션을 아래쪽에 두고 싶다면 {{ cssxref("caption-side") }}속성 값을 bottom으로 설정하라. 속성은 상속되므로 상속받은 테이블들에 선택적으로 속성값 재설정도 가능하다.

-

캡션의 텍스트 스타일을 조정 하려면 텍스트 속성을 사용하면 된다.

-
-
- 예제
-

이 테이블은 아래쪽에 캡션을 가지고 있다.

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

빈 셀블럭

-

테이블 element에 {{ cssxref("empty-cells") }}: show로 설정 함으로 빈 셀블럭을 표시 할 수 있다.

-

empty-cells: hide로 설정하여 해당 셀블럭을 안보이도록 감출 수 있다. 셀의 부모 element가 배경색을 가지고 있다면 그 배경색이 보이게 될 것이다.

-
-
- 예제
-

이 테이블은 옅은 녹색 배경을 가지고 있으며, 셀은 진한 회색의 테두리와 회색 배경을 가지고 이다.

-

아래 테이블의 왼쪽은 빈 셀을 보여주고, 오른쪽은 셀감추기의 결과를 확인 할 수 있다.

- - - - - - - -
- - - - - - - - - - - -
 Hearts
DiamondsSpades
-
- - - - - - - - - - - -
 Hearts
DiamondsSpades
-
-
-
-
- 자세히
-

CSS 사양서의 테이블에서 좀더 자세한 테이블에 대한 사항을 확인 하라.

-

여기에서 보다 더 자세한 테이블에 관한 내용을 확인 할 수 있지만, 브라우저별로 다르게 보여지는 복잡한 테이블에 대한 사항은 포함하고 있지 않다.

-
-

액션 : 테이블 꾸미기

-
    -
  1. 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. 화면에 보여지는 테이블과 stylesheet에 추가한 규칙과 비교하여 각 규칙이 어떻게 적용되었는지 확인해 보라. 원하는 방향으로 적용되지 않은 규칙이 있다면 해당 규칙을 주석 처리해서 저장한 후 브라우저로 다시 읽어 확인 해 보라. 아래는 위의 테이블에 관해 확인 해볼 사항이다. -
      -
    • 캡션은 테이블 바깥 경계에 표시된다.
    • -
    • 옵션에 최소 포인트 크기 세트가 있다면 km2에 있는 '2'처럼 어깨 글자에 적용 될 것이다.
    • -
    • 테이블은 세가지 빈 셀 블럭을 가지고 있다. 그중 둘은 테이블 배경색을 그대로 보여줄 수 있도록 설정되어 있다. 세번째 빈 셀블럭은 자체 색상과 위쪽에 경계선을 가지고 있다.
    • -
    • 콜론은 Stylesheet에서 추가 되었다.
    • -
    -
  8. -
-
-
- 도전
-

아래처럼 보이도록 Stylesheet를 바꿔 보라

- - - - - - -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 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("/en-US/docs/CSS/Getting_Started/Media", "미디어") }}이 장이 CSS의 속성과 그 변수에 대해 설명하는 마지막 장이다. 전체 속성 및 변수에 대해 확인 하려면 CSS 사양서의 Full property table를 보라.

-

다음에는 CSS의 Stylesheet구조와 목적에 대해 다시한번 살펴보자.

diff --git "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\215\354\212\244\355\212\270_\354\212\244\355\203\200\354\235\274/index.html" "b/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\215\354\212\244\355\212\270_\354\212\244\355\203\200\354\235\274/index.html" deleted file mode 100644 index 8866132472..0000000000 --- "a/files/ko/web/css/\354\213\234\354\236\221\355\225\230\352\270\260/\355\205\215\354\212\244\355\212\270_\354\212\244\355\203\200\354\235\274/index.html" +++ /dev/null @@ -1,150 +0,0 @@ ---- -title: 텍스트 스타일 -slug: Web/CSS/시작하기/텍스트_스타일 -translation_of: Learn/CSS/Styling_text/Fundamentals -translation_of_original: Web/Guide/CSS/Getting_started/Text_styles ---- -

{{ CSSTutorialTOC() }}

- -
중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/18)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
- -

{{previousPage("/en-US/docs/CSS/Getting_Started/Readable_CSS", "알기 쉬운 CSS")}}CSS 시작하기 안내서 7번째 장; 여기서는 텍스트 스타일에 대해 좀더 많은 예를 살펴 보자. 예제 Stylesheet를 다른 글씨체로 바꿔 보자.

- -

정보: 텍스트 스타일

- -

CSS는 몇가지 텍스트 스타일에 대한 속성이 있다.

- -

여러가지에 대해 한번에 편리하게 사용할 수 있는 {{ cssxref("font") }}라는 속성에 대해 알아보자. 예를 들면

- -
    -
  • 굵게, 기울기, 작은 대문자체
  • -
  • 크기
  • -
  • 라인 높이
  • -
  • 글씨체
  • -
- -
-
예제
- -
p {font: italic 75%/125% "Comic Sans MS", cursive;}
-
- -

위의 규칙은 모든 단락내용을 italic폰트로 설정 하는 등의 다양한 설정을 한다.

- -

폰트 크기를 부모 element의 단락 크기의 3/4크기로 하고 라인 크기를 보통보다 좀 큰 125%크기로 한다.

- -

글자체는 Comic Sans MS이다. 하지만 이 글씨체가 유효하지 않다면 브라우저는 기본 글씨체인 손글씨체를 사용 할 것이다.

- -

이 규칙에는 굵기와 작은 대문자 속성을 무력화 하는 오류를 포함하고 있다.

-
- -

글씨체

- -

보통 Document에서 가용한 글씨체에는 어떤 것이 있는지 알고 작성할 수는 없다. 대체 가능한 글씨체를 같이 설정 해 주는 것도 좋은 방법이다.

- -

맨 마지막에는 기본 글씨체(serif, sans-serif, cursive, fantasy or monospace)를 추가 설정 해 주는 것이 좋다.

- -

만약 document에서 지원 하지 않는 글씨체라면 브라우저가 다른 글씨체로 대체 할 것이다. 예를 들면, Document내에는 설정된 글씨체에서 지원 되지 않는 특수 문자를 포함 하는 경우 같은 것을 말한다. 브라우저는 자동적으로 다른 글씨체에서 위의 특수문자를 지원 한다면 그 글씨체를 사용하여 표시 할 것이다.

- -

글씨체를 설정 하기 위해서는 {{ cssxref("font-family") }}속성을 사용 하라.

- -

글씨 크기

- -

브라우저는 보여지고 있는 페이지의 기본 글씨체의 크기와 텍스트의 크기를 바꿀 수 있어서 사용자에 맞는 것을 사용 할 수 있게 해준다.

- -

폰트 크기는 small, medium, large등 정해진 사이즈도 사용할 수 있다. 또한 부모 글씨체 크기와 비교된(smaller, larger, 150%, 1.5 em) 값으로 설정 가능하다. 'em'은 'm'자의 폭을 말한다. 따라서 부모 element보다 1.5배 크기의 글씨크기를 말한다.

- -

14px (14 pixels)와 같이 표시장치나 출력장치의 실체 크기로 지정 할 수도 있다. 이 경우는 크기를 바꿀수 없으므로 시각장애인들에게 불편할 수 있다. 이런 경우를 위해서는 document의 최 상위 element에서부터 정해진 크기 값중 하나인 'medium'으로 해 놓으면 하위 element는 그와 비교해 상대적인 값으로 크기를 설정 할 수 있다.

- -

글씨 크기를 설정 하려면 {{ cssxref("font-size") }}를 사용하라.

- -

줄 높이

- -

Line height는 줄간 높이를 말한다. 단락이 여러줄로 구성되었다면 보통보다 큰(larger-than-normal) 간격이 특히 작은 글씨라면 읽기 편하다.

- -

줄 높이 설정은 {{ cssxref("line-height") }}속성을 사용하라.

- -

장식(Decoration)

- -

별도의 {{ cssxref("text-decoration") }} 속성으로 밑줄, 취소선 같은 다른 스타일 설정 할 수 있다. 설정된 장식(Decoration)속성을 없애기 위해서 값을 none을 쓸 수 있다.

- -

다른 속성

- -

기울기 속성 {{ cssxref("font-style") }}: italic;
- 굵은 속성 {{ cssxref("font-weight") }}: bold;
- 작은 대문자 {{ cssxref("font-variant") }}: small-caps;

- -

위의 속성을 해제하려면 normal 또는 inherit로 설정하라.

- -
-
좀더 자세히
- -

텍스트 스타일은 다양한 방법으로 설정 가능하다.

- -

예를 들면, 위에 언급한 속성들에 다른 사용 가능한 값들이 더 있다.

- -

복잡한 stylesheet에서는, 원치 않는 오류(설정 값이 다르게 나타나는 오류) 방지를 위해 약칭 font 속성 사용을 피하라.

- -

글씨체에 관한 모든 속성을 보려면, CSS 사양서의 Fonts부분을 보라. 다양한 텍스트 효과를 위해서는 Text 부분을 참고 하라.

- -

사용자 시스템 환경에 설치된 폰트 외에 다른 폰트를 설정하려면 @font-face로 온라인에 있는 폰트 설정 할 수 있다. 이를 위해서는 브라우저에서 해당 규칙을 지원해야 한다.

-
- -

액션: 글씨체 설정

- -

간단한 document에서는, {{ HTMLElement("body") }} element의 글씨체를 설정 할 수 있으며, 그 이후에서는 이 속성을 상속한다.

- -
    -
  1. 예제 CSS 편집 해 보자.
  2. -
  3. 예제의 Document에 아래 규칙을 추가 하라. CSS파일의 위쪽은 논리적인 곳(?)이다. 하지만 어디에 추가하든 그 속성은 적용 될 것이다. -
    body {font: 16px "Comic Sans MS", cursive;}
    -
    -
  4. -
  5. 주석을 탭이나 공백과 함께 잘 배치해 보라.
  6. -
  7. 저장하고 브라우저를 다시 읽어보라. 해당 기기에 italic 스타일이 지원되지 않는 Comic Sans MS나 손글씨체 글씨체가 있다면 브라우저는 다음 예제의 첫출과 같이 italic이 지원되는 다른 글씨체로 바꿔서 보여 줄 것이다. - - - - - - - - - -
    Cascading Style Sheets
    Cascading Style Sheets
    -
  8. -
  9. 브라우저 메뉴에서 View > Text Size > Increase (or View > Zoom > Zoom In)을 선택 해 보라. 위에 16 pixels로 스타일 속성을 주었더라도, 화면에는 그 글씨 크기가 바뀔 것이다.
  10. -
- -
-
도전
- -

다른것은 그대로 두고, 단어 앞 첫 글자 6개만 기본 sarif글씨체로 바꾸고 브라우저 기본 사이즈의 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("/en-US/docs/CSS/Getting_Started/Color", "색상")}}이미 예제에서 몇가지 색상을 사용 해 왔다. 다음 장에서는 기본 색생과 다른 색상 표현 법에 대해 알아본다.

diff --git "a/files/ko/web/css/\354\235\270\354\240\221_\355\230\225\354\240\234_\354\204\240\355\203\235\354\236\220/index.html" "b/files/ko/web/css/\354\235\270\354\240\221_\355\230\225\354\240\234_\354\204\240\355\203\235\354\236\220/index.html" deleted file mode 100644 index 4446172ab3..0000000000 --- "a/files/ko/web/css/\354\235\270\354\240\221_\355\230\225\354\240\234_\354\204\240\355\203\235\354\236\220/index.html" +++ /dev/null @@ -1,83 +0,0 @@ ---- -title: 인접 형제 결합자 -slug: Web/CSS/인접_형제_선택자 -tags: - - CSS - - Reference - - Selectors -translation_of: Web/CSS/Adjacent_sibling_combinator ---- -
{{CSSRef("Selectors")}}
- -

인접 형제 결합자(+)는 앞에서 지정한 요소의 바로 다음에 위치하는 형제 요소만 선택합니다.

- -
/* Paragraphs that come immediately after any image */
-img + p {
-  font-weight: bold;
-}
-
- -

구문

- -
former_element + target_element { style properties }
-
- -

예제

- -

CSS

- -
li:first-of-type + li {
-  color: red;
-}
-
- -

HTML

- -
<ul>
-  <li>One</li>
-  <li>Two!</li>
-  <li>Three</li>
-</ul>
- -

결과

- -

{{EmbedLiveSample("예제", "100%", 100)}}

- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('CSS4 Selectors', '#adjacent-sibling-combinators', 'next-sibling combinator')}}{{Spec2('CSS4 Selectors')}}
{{SpecName('CSS3 Selectors', '#adjacent-sibling-combinators', 'Adjacent sibling combinator')}}{{Spec2('CSS3 Selectors')}}
{{SpecName('CSS2.1', 'selector.html#adjacent-selectors', 'Adjacent sibling selectors')}}{{Spec2('CSS2.1')}}Initial definition
- -

브라우저 호환성

- -

{{Compat("css.selectors.adjacent_sibling")}}

- -

같이 보기

- - diff --git a/files/ko/web/events/abort/index.html b/files/ko/web/events/abort/index.html deleted file mode 100644 index 2278a24c24..0000000000 --- a/files/ko/web/events/abort/index.html +++ /dev/null @@ -1,74 +0,0 @@ ---- -title: abort -slug: Web/Events/abort -tags: - - DOM - - Event - - Reference - - 레퍼런스 - - 이벤트 -translation_of: Web/API/HTMLMediaElement/abort_event -translation_of_original: Web/Events/abort ---- -

abort 이벤트는 리소스의 로딩이 중단되었을 때, 발생합니다.

- -

개요

- -
-
스펙
-
DOM L3
-
인터페이스
-
유저 인터페이스에서 발생하면 UIEvent, 그렇지 않으면 Event.
-
버블
-
안됨
-
취소 가능
-
안됨
-
타겟
-
Element
-
디폴트 액션
-
없음
-
- -

속성

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
속성타입설명
target {{readonlyInline}}EventTarget이벤트 타겟 (DOM tree의 최상위 타겟).
type {{readonlyInline}}DOMString이벤트의 타입
bubbles {{readonlyInline}}Boolean이벤트가 버블링 되는지 안되는지
cancelable {{readonlyInline}}Boolean이벤트가 취소 가능한지 아닌지
view {{readonlyInline}}WindowProxydocument.defaultView (document의 window )
detail {{readonlyInline}}long (float)0.
diff --git a/files/ko/web/events/blur/index.html b/files/ko/web/events/blur/index.html deleted file mode 100644 index 3bbcc6acb0..0000000000 --- a/files/ko/web/events/blur/index.html +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: blur -slug: Web/Events/blur -translation_of: Web/API/Element/blur_event ---- -

blur 이벤트는 엘리먼트의 포커스가 해제되었을때 발생합니다. 이 이벤트와 focusout 이벤트의 가장 다른점은 focusout 은 이벤트 버블링이 발생합니다.

- -

General info

- -
-
Specification
-
DOM L3
-
Interface
-
{{domxref("FocusEvent")}}
-
Bubbles
-
No
-
Cancelable
-
No
-
Target
-
Element
-
Default Action
-
None.
-
- -

{{NoteStart}} 이 이벤트가 처리될때 {{domxref("Document.activeElement")}}의 값이 브라우저마다 다릅니다 ({{bug(452307)}}): IE10은 이 값을 포커스가 옮겨가는 엘리먼트에 추가하지만, 파이어폭스와 크롬은 도큐먼트의 body 에 추가합니다.{{NoteEnd}}

- -

Properties

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PropertyTypeDescription
target {{readonlyInline}}{{domxref("EventTarget")}}Event target (DOM element)
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{jsxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{jsxref("Boolean")}}Whether the event is cancellable or not.
relatedTarget {{readonlyInline}}{{domxref("EventTarget")}} (DOM element)null
- -

이벤트 위임

- -

이 이벤트에 이벤트 위임을 적용하는 방법은 두가지가 있습니다 : 브라우저가 지원한다면 focusout 이벤트를 사용하거나,   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')}}

- -

Browser compatibility

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support5{{CompatVersionUnknown}}{{CompatVersionUnknown}}[1]612.15.1
-
- -
- - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support4.053{{CompatVersionUnknown}}{{CompatUnknown}}10.012.15.1
-
- -

[1] Prior to Gecko 24 {{geckoRelease(24)}} the interface for this event was {{domxref("Event")}}, not {{domxref("FocusEvent")}}. See ({{bug(855741)}}).

- - - -
    -
  • {{event("focus")}}
  • -
  • {{event("blur")}}
  • -
  • {{event("focusin")}}
  • -
  • {{event("focusout")}}
  • -
diff --git a/files/ko/web/events/domcontentloaded/index.html b/files/ko/web/events/domcontentloaded/index.html deleted file mode 100644 index 24db56aa91..0000000000 --- a/files/ko/web/events/domcontentloaded/index.html +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: DOMContentLoaded -slug: Web/Events/DOMContentLoaded -tags: - - Event - - Reference - - Web - - Window -translation_of: Web/API/Window/DOMContentLoaded_event ---- -
{{APIRef}}
- -

DOMContentLoaded 이벤트는 초기 HTML 문서를 완전히 불러오고 분석했을 때 발생합니다. 스타일 시트, 이미지, 하위 프레임의 로딩은 기다리지 않습니다.

- - - - - - - - - - - - - - - - - - - - -
확산
취소 가능예 (although specified as a simple event that isn't cancelable)
인터페이스{{domxref("Event")}}
이벤트 처리기 속성아니오
- -

DOMContentLoaded의 원본 대상은 다 불러온 {{domxref("Document")}}입니다. You can listen for this event on the Window interface to handle it in the capture or bubbling phases. For full details on this event please see the page on the Document: {{domxref("Document/DOMContentLoaded_event", "DOMContentLoaded")}} event.

- -

A different event, {{domxref("Window/load_event", "load")}}, should be used only to detect a fully-loaded page. It is a common mistake to use load where DOMContentLoaded would be more appropriate.

- -

예제

- -

기본 용도

- -
window.addEventListener('DOMContentLoaded', (event) => {
-    console.log('DOM fully loaded and parsed');
-});
-
- -

사양

- - - - - - - - - - - - - - -
사양상태
{{SpecName('HTML WHATWG', 'indices.html#event-domcontentloaded')}}{{Spec2('HTML WHATWG')}}
- -

브라우저 호환성

- - - -

{{Compat("api.Window.DOMContentLoaded_event")}}

- -

같이 보기

- -
    -
  • Related events: {{domxref("Window/load_event", "load")}}, {{domxref("Document/readystatechange_event", "readystatechange")}}, {{domxref("Window/beforeunload_event", "beforeunload")}}, {{domxref("Window/unload_event", "unload")}}
  • -
  • This event on {{domxref("Document")}} targets: {{domxref("Document/DOMContentLoaded_event", "DOMContentLoaded")}}
  • -
diff --git a/files/ko/web/events/load/index.html b/files/ko/web/events/load/index.html deleted file mode 100644 index baef50af25..0000000000 --- a/files/ko/web/events/load/index.html +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: load -slug: Web/Events/load -tags: - - Event - - 이벤트 -translation_of: Web/API/Window/load_event ---- -

load 이벤트는 리소스와 그것에 의존하는 리소스들의 로딩이 완료되면 실행됩니다.

- -

 

- -

예제

- -

Window

- -
<script>
-  window.addEventListener("load", function(event) {
-    console.log("All resources finished loading!");
-  });
-</script>
- -

script 엘리먼트

- -
<script>
-  var script = document.createElement("script");
-  script.addEventListener("load", function(event) {
-    console.log("Script finished loading and executing");
-  });
-  script.src = "http://example.com/example.js";
-  script.async = true;
-  document.getElementsByTagName("script")[0].parentNode.appendChild(script);
-</script>
- -

일반 정보

- -
-
스펙
-
DOM L3
-
인터페이스
-
UIEvent
-
Bubbles
-
No
-
취소가능 여부
-
No
-
타겟
-
Window,Document,Element
-
기본 동작
-
None.
-
- -

속성

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
속성타입설명
target {{readonlyInline}}{{domxref("EventTarget")}}The event target (the topmost target in the DOM tree).
type {{readonlyInline}}{{domxref("DOMString")}}The type of event.
bubbles {{readonlyInline}}{{domxref("Boolean")}}Whether the event normally bubbles or not.
cancelable {{readonlyInline}}{{domxref("Boolean")}}Whether the event is cancellable or not.
view {{readonlyInline}}{{domxref("WindowProxy")}}{{domxref("Document.defaultView", "document.defaultView")}} (window of the document)
detail {{readonlyInline}}long (float)0.
- -

스펙 정보

- - - - - - - - - - - - - - - - - - - -
스펙상태코멘트
{{SpecName('UI Events', '#event-type-load', 'load')}}{{Spec2('UI Events')}} 
{{SpecName('HTML WHATWG', 'parsing.html#the-end:event-load', 'Load event')}}{{Spec2('HTML WHATWG')}} -

이것은 문서 로딩이 끝날때 수행되는 단계와 연결되는 섹션과 연결됩니다. 'load' 이벤트는 많은 엘리먼트들에서도 발생합니다. 그리고 스펙 문서에서는 많은 곳에서 "load이벤트를 지연할 수 있는" 것들을 언급한다는 것을 주의하십시오.

-
- -

관련 이벤트

- -
    -
  • {{event("DOMContentLoaded")}}
  • -
  • {{event("readystatechange")}}
  • -
  • {{event("load")}}
  • -
  • {{event("beforeunload")}}
  • -
  • {{event("unload")}}
  • -
diff --git a/files/ko/web/events/message/index.html b/files/ko/web/events/message/index.html deleted file mode 100644 index 1796b8ee0c..0000000000 --- a/files/ko/web/events/message/index.html +++ /dev/null @@ -1,152 +0,0 @@ ---- -title: message -slug: Web/Events/message -translation_of: Web/API/BroadcastChannel/message_event ---- -

메시지 이벤트는 메시지가 수신되었음을 알리는 메시지, {{domxref("WebSocket")}}, {{domxref("RTCDataConnection")}} 또는 {{domxref("BroadcastChannel")}} 개체를 알려 줍니다.

- -

대상이 {{domxref("RTCDataConnection")}}, 인 경우 이 이벤트에 대한 이벤트 핸들러를 {{domxref("RTCDataConnection.onmessage")}}속성을 통해 추가할 수 있습니다.

- -

대상이 {{domxref("BroadcastChannel")}}인 경우, 이 이벤트에 대한 이벤트 핸들러를 {{domxref("BroadcastChannel.onmessage")}} 속성을 통해 추가할 수 있습니다.

- -

일반 정보

- -
-
인터페이스
-
- -
-
{{domxref("MessageEvent")}}
-
Bubbles
-
No
-
Cancelable
-
No
-
Target
-
{{domxref("RTCDataChannelEvent")}}, {{domxref("WebSocket")}}, {{domxref("BroadcastChannel")}}
-
Default Action
-
None
-
- -

특성

- -

{{domxref("Event")}}가 진행되는 동안  {{domxref("MessageEvent")}} 이러한 속성을 구현합니다.

- -
-
data {{readOnlyInline}}
-
수신된 메시지를 포함하는 {{domxref("DOMString")}} 가 있습니다.
-
- -

방법

- -

{{domxref("Event")}}가 진행되는 동안  {{domxref("MessageEvent")}} 이러한 속성을 구현합니다.

- -

관련 자료

- -
    -
  • {{event("open")}}, {{event("close")}}.
  • -
- -

사양

- - - - - - - - - - - - - - - - - - - -
사양상황Comment
{{ SpecName('WebRTC 1.0', '#event-datachannel-message', 'message on RTCDataChannel') }}{{Spec2('WebRTC 1.0')}}{{domxref("RTCDataChannel")}} 를 {{domxref("EventTarget")}}로 추가하고 이 이벤트가 전송될 시기를 정의합니다.
{{SpecName('HTML WHATWG', '#', 'message on BroadcastChannel')}}{{Spec2('HTML WHATWG')}}{{domxref("RTCDataChannel")}} 를 {{domxref("EventTarget")}}로 추가하고 이 이벤트가 전송될 시기를 정의합니다.
- -

브라우저 호환성

- -

{{ CompatibilityTable() }}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeEdgeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{ CompatVersionUnknown() }}{{CompatVersionUnknown}}{{ CompatVersionUnknown }}{{ CompatNo() }}{{ CompatVersionUnknown() }}{{ CompatUnknown() }}
on {{domxref("BroadcastChannel")}} {{experimental_inline}}{{CompatNo}}{{CompatNo}}{{CompatGeckoDesktop(38)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidEdgeFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{ CompatUnknown() }}{{ CompatUnknown() }}{{CompatVersionUnknown}}{{ CompatUnknown() }}{{ CompatNo() }}{{ CompatUnknown() }}{{ CompatUnknown() }}
on {{domxref("BroadcastChannel")}}  {{experimental_inline}}{{CompatNo}}{{CompatNo}}{{CompatNo}}{{CompatGeckoMobile(38)}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

보기

- -
    -
  • WebRTC
  • -
  • BroadcastChannel API
  • -
  • WebSockets
  • -
diff --git a/files/ko/web/guide/api/vibration/vibration/index.html b/files/ko/web/guide/api/vibration/vibration/index.html deleted file mode 100644 index 16271ff248..0000000000 --- a/files/ko/web/guide/api/vibration/vibration/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: Vibration API -slug: Web/Guide/API/Vibration/Vibration -translation_of: Web/API/Vibration_API ---- -
{{DefaultAPISidebar("Vibration API")}}
- -

요즘 나오는 대부분은 모바일 디바이스는 바이브레이션 하드웨어를 포함하고 있다. 소프트웨어 코드를 이용해 바이브레이션 하드웨어를 제어하면, 모바일 디바이스를 흔들리게 만들어 사용자에게 물리적인 피드백을 제공할 수 있다.

- -

Vibration API는 웹앱들이 기기에 장착된 물리 진동장치를 통해 진동을 전달할 수 있도록 해줍니다. 하지만 대응하는 진동 장치가 없는 기기일 경우 아무일도 일어나지 않습니다.

- -

Describing vibrations

- -

바이브레이션은 온오프 펄스들의 패턴이라고 할 수 있는데, 이 펄스들은 아마도 다양한 길이를 가질 것이다. 이 패턴은 아마 하나의 정수값으로 구성될 수 있는데 이 정수값은 진동이 일어날 밀리세컨드 수를 의미한다. 또한 이 패턴은 정수 배열이 될 수도 있는데 이것은 진동과 정지들의 패턴을 의미한다. 바이브레이션은 {{domxref("window.navigator.vibrate()")}} 라는 하나의 메소드로 제어된다.

- -

한번 진동시키기

- -

여러분은 다음과 같이 하나의 값 또는 하나의 값으로 구성된 배열을 명시함으로써 바이브레이션 하드웨어를 1회 진동시킬 수 있을 것이다.

- -
window.navigator.vibrate(200);
-window.navigator.vibrate([200]);
-
- -

이 두 가지 예제들은 디바이스를 200ms 동안 진동시킨다.

- -

패턴이 있는 진동 만들기

- -

배 열에 있는 값들은 다바이스가 진동해야 하는 시간과 진동하지 않아야 하는 시간을 번갈아가며 적어놓은 것이다. 배열에 있는 각 값은 하나의 정수로 변환된 후 차례대로 장치가 진동해야 하는 시간, 장치가 진동하지 않아야 하는 시간으로 해석된다. 다음 예제를 보자.

- -
window.navigator.vibrate([200, 100, 200]);
-
- -

이 예제는 장치를 200ms 동안 진동시킨 후 100ms 동안 멈추게 하고 그 후 다시 200ms 동안 장치를 진동시킨다.

- -

여 러분은 여러분이 원하는 진동/정지 페어를 명시할 수 있다. 그리고 배열 내에 홀수 또는 짝수개의 값들을 명시할 수도 있다. 이렇게 하는 이유는 각각의 진동 시간이 끝나면 디바이스의 진동은 자동적으로 멈추게 되므로 배열의 마지막 값이 정지에 해당하는 값이라면 그 값은 아무 의미가 없기 때문이다.

- -

이미 실행중인 진동 캔슬하기

- -

{{domxref("window.navigator.vibrate()")}} 메소드를 0값을 호출하거나, 빈 배열, 0값으로 구성된 배열로 호출하면 현재 진행중인 진동패턴은 취소될 것이다.

- -

지속적인 진동 내보내기

- -

Some basic setInterval and clearInterval action will allow you to create persistent vibration:

- -
var vibrateInterval;
-
-// Starts vibration at passed in level
-function startVibrate(duration) {
-    navigator.vibrate(duration);
-}
-
-// Stops vibration
-function stopVibrate() {
-    // Clear interval and stop persistent vibrating
-    if(vibrateInterval) clearInterval(vibrateInterval);
-    navigator.vibrate(0);
-}
-
-// Start persistent vibration at given duration and interval
-// Assumes a number value is given
-function startPeristentVibrate(duration, interval) {
-    vibrateInterval = setInterval(function() {
-        startVibrate(duration);
-    }, interval);
-}
- -

Of course the snippet above doesn't take into account the array method of vibration; persistent array-based vibration will require calculating the sum of the array items and creating an interval based on that number (with an additional delay, probably).

- -

Why use Vibration API?

- -

This API is clearly targeted toward mobile devices. The Vibration API would be good for alerts within mobile web applications, and would be especially awesome when used in games or media-heavy applications. Imagine watching a video on your mobile device, and during an explosion scene, your phone got a bit of a shake. Or playing Bomberman and feeling a gentle kick when a block explodes!

- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('Vibration API')}}{{Spec2('Vibration API')}}Initial specification.
- -

브라우저 호환성

- -
{{Compat("api.Navigator.vibrate")}}
- -

같이 보기

- -
    -
  • {{domxref("window.navigator.vibrate()")}}
  • -
diff --git a/files/ko/web/guide/css/media_queries/index.html b/files/ko/web/guide/css/media_queries/index.html deleted file mode 100644 index 559b5805c6..0000000000 --- a/files/ko/web/guide/css/media_queries/index.html +++ /dev/null @@ -1,386 +0,0 @@ ---- -title: 미디어 쿼리 사용하기 -slug: Web/Guide/CSS/Media_queries -tags: - - Advanced - - CSS - - Guide - - Media - - Media Queries - - Responsive Design - - Web -translation_of: Web/CSS/Media_Queries/Using_media_queries ---- -
{{cssref}}
- -

미디어 쿼리는 단말기의 유형(출력물 vs. 화면)과, 어떤 특성이나 수치(화면 해상도, {{glossary("viewport", "뷰포트")}} 너비 등)에 따라 웹 사이트나 앱의 스타일을 수정할 때 유용합니다.

- -

미디어 쿼리는 다음과 같은 상황에 사용할 수 있습니다.

- -
    -
  • CSS {{cssxref("@media")}}와 {{cssxref("@import")}} @규칙을 사용해 특정 조건에 따라 스타일을 적용할 때.
  • -
  • {{htmlelement("style")}}, {{htmlelement("link")}}, {{htmlelement("source")}}, 기타 다른 HTML 요소에 media 특성을 사용해 특정 매체만 가리키게 할 때.
  • -
  • {{domxref("Window.matchMedia()")}}와 {{domxref("MediaQueryList.addListener()")}} JavaScript 메서드를 사용해 미디어 상태를 판별하고 관측할 때.
  • -
- -
-

참고: 이 페이지의 CSS는 시연용으로 @media를 사용했지만, 기본적인 구문은 모든 미디어 쿼리가 동일합니다.

-
- -

구문

- -

미디어 쿼리는 선택 사항인 미디어 유형과, 자유로운 수의 미디어 특성 표현식으로 이루어집니다. 논리 연산자를 사용해 다수의 쿼리를 다양한 방법으로 결합할 수도 있습니다. 미디어 쿼리는 대소문자를 구분하지 않습니다.

- -

미디어 쿼리는 (유형을 지정했다면) 문서를 보여주는 미디어의 유형이 일치하고 모든 미디어 특성 표현식의 계산값이 참일 때 참으로 계산됩니다.

- -
-

참고: {{HTMLElement("link")}}의 미디어 쿼리가 거짓을 반환하더라도 스타일시트는 다운로드됩니다. 그렇지만 그 안의 내용은 쿼리가 참이 되어야 적용됩니다.

-
- -

미디어 유형

- -

미디어 유형은 장치의 일반적인 범주를 나타냅니다. 미디어 유형은 not이나 only 논리연산자를 사용할 때를 제외하면 선택사항이며 지정하지 않으면 all을 사용합니다.

- -
-
all
-
모든 장치에 적합합니다.
-
print
-
인쇄 결과물 및 출력 미리보기 화면에 표시 중인 문서입니다.
- (인쇄 미디어 문서를 방문해 print 형식에서 발생 가능한 서식 문제의 정보를 확인해주세요.)
-
screen
-
주로 화면이 대상입니다.
-
speech
-
음성 합성장치 대상입니다.
-
- -
-

사용하지 않는 미디어 유형: CSS2.1과 Media Queries 3 모듈은 여러가지 추가 유형(tty, tv, projection, handheld, braille, embossed, aural)을 정의했으나 Media Queries 4에서 제거됐으므로 사용해선 안됩니다. aural은 유사한 유형인 speech로 대체됐습니다.

-
- -

미디어 특성

- -

미디어 특성은 {{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")}}뷰포트의 가로세로비
{{cssxref("@media/color", "color")}}출력 장치의 색상 채널별 비트 수, 흑백일 땐 0
{{cssxref("@media/color-gamut", "color-gamut")}}사용자 에이전트와 출력 장치가 지원하는 색상의 대략적인 범위Media Queries Level 4에서 추가
{{cssxref("@media/color-index", "color-index")}}출력 장치의 색상 검색 테이블(LUT) 항목 수, 존재하지 않을 땐 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")}}웹 앱 매니페스트의 display 항목이 정의한 애플리케이션의 표시 모드Web App Manifest 명세에서 정의
{{cssxref("@media/forced-colors", "forced-colors")}}사용자 에이전트가 색상 팔레트를 제한하는지 여부Media Queries Level 5에서 추가
{{cssxref("@media/grid", "grid")}}장치가 그리드와 비트맵 스크린 중 어느 것을 사용하나?
{{cssxref("@media/height", "height")}}뷰포트의 높이
{{cssxref("@media/hover", "hover")}}주 입력 방식으로 사용자가 요소 위에 호버할 수 있는가?Media Queries Level 4에서 제거
{{cssxref("@media/inverted-colors", "inverted-colors")}}사용자 에이전트나 운영 체제가 색상을 반전 중인가?Media Queries Level 5에서 추가
{{cssxref("@media/light-level", "light-level")}}주변 환경의 광도Media Queries Level 5에서 추가
{{cssxref("@media/monochrome", "monochrome")}}출력 장치의, 모노크롬 프레임 버퍼의 픽셀 당 비트 수. 단색을 사용하지 않으면 0
{{cssxref("@media/orientation", "orientation")}}뷰포트의 방향
{{cssxref("@media/overflow-block", "overflow-block")}}콘텐츠가 블록 축 방향으로 뷰포트를 오버플로 할 경우 출력 장치가 어떻게 처리하는가?Media Queries Level 4에서 추가
{{cssxref("@media/overflow-inline", "overflow-inline")}}콘텐츠가 인라인 축 방향으로 뷰포트를 오버플로 할 경우 스크롤 가능한가?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")}}스크롤바를 포함한 뷰포트 너비
- -

논리 연산자

- -

not, and, only와 같은 논리 연산자를 사용해 복잡한 쿼리를 조합할 수 있습니다. 여러 미디어 쿼리를 쉼표로 구분해서 하나의 규칙으로 만들 수도 있습니다.

- -

and

- -

and 연산자는 다수의 미디어 특성을 조합하여 하나의 미디어 쿼리를 만들 때 사용합니다. 쿼리가 참이려면 모든 구성 특성이 참을 반환해야 합니다. 미디어 특성과 미디어 유형을 같이 사용할 때도 쓰입니다.

- -

not

- -

not 연산자는 미디어 쿼리를 부정하여, 쿼리가 거짓일 때만 참을 반환합니다. 쉼표로 구분한 쿼리 목록 중 하나에서 사용한 경우 전체 쿼리가 아닌 해당하는 하나의 쿼리에만 적용됩니다. not 연산자를 사용할 경우 반드시 미디어 유형도 지정해야 합니다.

- -
-

참고: Level 3 모듈에서는 not 키워드를 사용해 단일 미디어 기능을 부정할 수 없으며 전체 쿼리만 부정 가능합니다.

-
- -

only

- -

only 연산자는 전체 쿼리가 일치할 때만 스타일을 적용할 때 사용하며 오래 된 브라우저가 스타일을 잘못 적용하지 못하도록 방지할 때 유용합니다. only를 사용하지 않은 screen and (max-width: 500px) 쿼리를 가정했을 때, 구형 브라우저는 쿼리를 단순히 screen으로만 읽고 뒷부분은 무시한 채 스타일을 적용해버립니다. only 연산자를 사용할 경우 반드시 미디어 유형도 지정해야 합니다.

- -

, (쉼표)

- -

쉼표는 다수의 미디어 쿼리를 하나의 규칙으로 조합할 때 사용합니다. 쉼표 목록 내의 쿼리 각각은 나머지와 별개로 취급하므로, 단 하나의 쿼리만 참을 반환해도 규칙 전체가 참이 됩니다. 즉 쉼표는 논리 or 연산자처럼 동작합니다.

- -

미디어 유형 특정하기

- -

미디어 유형은 주어진 장치의 일반적인 분류를 설명합니다. 비록 웹사이트는 보통 스크린을 염두에 놓고 디자인하지만, 프린터나 오디오 기반 스크린 리더처럼 특정 장치를 대상으로 하는 스타일을 만들고 싶을 때가 있을지도 모릅니다. 예를 들어 다음의 CSS는 프린터를 특정합니다.

- -
@media print { ... }
- -

다수의 장치를 특정할 수도 있습니다. 예컨대 아래 @media 규칙은 두 개의 미디어 쿼리를 사용해 스크린과 인쇄 장치 모두 특정합니다.

- -
@media screen, print { ... }
- -

미디어 유형 구획으로 올라가서 가능한 미디어 유형의 목록을 확인해보세요. 미디어 유형은 굉장히 넓은 범위에서 장치를 설명하기 때문에 적은 수만 존재합니다. 더 세부적인 특성을 특정하려면 미디어 기능을 사용하세요.

- -

미디어 기능 특정하기

- -

미디어 기능은 주어진 {{glossary("user agent", "사용자 에이전트")}}, 출력 장치, 주변 환경의 특징을 설명합니다. 예를 들어 어떤 스타일을 와이드스크린 모니터에만, 마우스를 사용하는 컴퓨터에만, 저광도 환경에서 사용 중인 장치에서만 적용할 수 있습니다. 다음의 예제는 사용자의 주 입력 방식(마우스 등)이 요소 위에 호버할 수 있으면 스타일을 적용합니다.

- -
@media (hover: hover) { ... }
- -

많은 미디어 기능은 범위 기능으로, "min-" 또는 "max-"를 앞에 붙여 각각 "최소 조건"과 "최대 조건" 제약을 나타낼 수 있습니다. 다음의 CSS는 브라우저의 {{glossary("viewport", "뷰포트")}} 너비가 12450px 이하인 경우에만 스타일을 적용합니다.

- -
@media (max-width: 12450px) { ... }
- -

미디어 기능 쿼리를 값 없이 생성할 경우 주어진 기능의 값이 0이 아닐 때 (Level 4부터는 0none이 아닐 때) 중첩 스타일을 적용합니다. 그러므로 다음 CSS는 흑백이 아닌 모든 장치에 해당합니다.

- -
@media (color) { ... }
- -

어떤 기능이 현재 브라우저가 가동 중인 장치에 적용되지 않으면, 해당 미디어 기능을 포함한 표현식은 항상 거짓입니다. 예를 들어, 음성 출력 전용 장치에 화면 가로세로비는 존재하지 않으므로 다음 쿼리에 중첩된 스타일은 절대 적용되지 않습니다.

- -
@media speech and (aspect-ratio: 11/5) { ... }
- -

미디어 특성 각각의 참고서 문서를 방문해 더 많은 예제를 확인하세요.

- -

복잡한 미디어 쿼리 생성

- -

때로는 사용자가 다수의 조건으로 구성된 쿼리를 생성하기 원할 수도 있습니다. 이때 논리연산자인 : not, and, 그리고 only를 사용하면 됩니다.  더 나아가 , 사용자는 복수의 미디어쿼리를 쉼표로 연결하여 리스트를 작성할수도 있습니다. 이렇게 함으로써 사용자는 다양한 상황에서 같은 스타일을 적용할 수 있습니다.

- -

앞서 예와 같이,  and 연산자를 사용하여 미디어유형과 미디어기능을 그룹지을 수 있습니다. 또한 and 를 사용하여 복수의 미디어 기능을 하나의 미디어 쿼리로 결합해낼수도 있습니다. 하지만 not 연산자는 미디어쿼리 자체를 부정시키는데, 근본적으로 원래의 의미를 반전시킵니다. only 연산자는 구형 브라우저가 스타일을 적용시키지 못하게 합니다.

- -
-

Note: 대부분의 경우,  all 미디어유형은 다른 유형이 특정되지 않았을 때 디폴트로 적용됩니다. 하지만, 사용자가 not 이나 only 연산자를 사용하면, 사용자는 반드시 미디어유형을 특정해야 합니다.

-
- -

다수의 유형과 기능 조합하기

- -

The and 연산자는 미디어기능과 미디어유형 혹은 다른 미디어 기능들과 연결해줍니다. 이 예에서는 두개의 미디어기능을 기기의 랜스케입(가로방향화면)방향으로 제한시키고 최소폭을 30 ems로 지정합니다:

- -
@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) { ... }
- -

위에 예에서 보면, 만일 사용자가 페이지높이가 800px인 프린터를 사용한다면, 첫번째 쿼리가 적용되기에 참 (true)값을 반환할 것입니다. 마찬가지로, 만일 사용자가 화면 높이가 480px인 스마트폰을 사용한다면 두번째 쿼리가 적용될 것이고, 미디어 문은 참값을 반환하게 됩니다.

- -

쿼리의 뜻 반전하기

- -

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) { ... }
-
- -

Level 4의 구문 향상

- -

미디어쿼리 Level 4 사양은 향상된 구문을 포함하는데 그를 통해 미디어쿼리가 '범위' 유형을 가진 기능을 사용할 수 있습니다. 예를 들면, 폭, 높이 처럼 말보다는 숫자에 관련된 것들입니다. Level 4 는 그러한 쿼리들을 작성하는데에 필요한 범위 구문을 제공합니다. 예를 들면, adds a range context for writing such queries. 폭을 표현하기 위해 max- 함수를 써서 사용자는 다음과 같이 쓸 수 있습니다:

- -
-

Note: 미디어쿼리 Level 4 사양에는 상당수의 최신 브라우저를 지원하지만,  몇몇 미디어기능들은 잘 지원되지 않습니다. 자세한 사항은 @media browser compatibility table 를 참조해 주십시요. 

-
- -
@media (max-width: 30em) { ... }
- -

미디어 쿼리 Level 4 에서는 다음과 같이 쓸 수 있습니다:

- -
@media (width <= 30em) { ... }
- -

min- 과 max- 를 사용하여 사용자가 두 값 사이에서 폭 값을 시험해 보고 싶은 상황이라면:

- -
@media (min-width: 30em) and (max-width: 50em) { ... }
- -

Level 4 구문에서는 이렇게 표현할 수 있습니다:

- -
@media (30em <= width <= 50em ) { ... }
-
- -

 Level 4 미디어쿼리는 또한 완전한 불리언 대수법을 사용하는 미디어쿼리들과 and, not, or.연산자를 결합할 수 있습니다. 

- -

not으로 기능 부정

- -

미디어기능에 not() 을 사용하면 쿼리에 있는 기능을 부정합니다. 예를 들어, hover를 할 수 없는 장치를 사용할 때 not(hover) 를 사용할 수 있습니다.

- -
@media (not(hover)) { ... }
- -

or로 다수의 기능 판별

- -

or 를 사용하면 다수의 기능 가운데 맞는 것이 하나라도 있는지를 테스트하여, 그중에 맞는 것이 하나라도 있으면 true 값을 반환하게 할 수 있습니다. 예를 들어, 다음에 보이는 쿼리에서는 흑백화면인지 혹은 hover가 가능한 지를 시험하고 있습니다.

- -
@media (not (color)) or (hover) { ... }
-
- -

같이 보기

- - diff --git a/files/ko/web/guide/css/visual_formatting_model/index.html b/files/ko/web/guide/css/visual_formatting_model/index.html deleted file mode 100644 index 4b32d08a30..0000000000 --- a/files/ko/web/guide/css/visual_formatting_model/index.html +++ /dev/null @@ -1,223 +0,0 @@ ---- -title: 시각적 서식 모델 -slug: Web/Guide/CSS/Visual_formatting_model -tags: - - 씨에스에스 - - 씨에스에스 상자 모델 - - 참조 -translation_of: Web/CSS/Visual_formatting_model ---- -
{{CSSRef}}
- -

씨에스에스 시각적 서식 모델 (visual formatting model) 은 문서를 처리하여 그것을 시각적 매체에 표시하는 알고리즘입니다. 이 모델은 씨에스에스의 기본 개념입니다.

- -

시각적 서식 모델은 문서의 각 요소를 변환하여, 씨에스에스 상자 모델에 부합하는 0, 1 또는 여러 상자를 생성합니다. 각 상자의 조판은 다음과 같이 정의됩니다:

- -
    -
  • 상자의 면적: 정확히 정의하거나 제약을 받거나, 아에 정의하지 않습니다.
  • -
  • 상자의 유형: 인라인, 인라인수준, 원자 인라인수준, 블록.
  • -
  • 위치잡기 기법: 일반 대열 소속, 부동체, 또는 절대 위치잡기.
  • -
  • 트리 구조에 속한 다른 요소 무리: 그것의 자녀와 이웃.
  • -
  • {{glossary("viewport")}} 크기와 위치.
  • -
  • 컨테이너에 속한 이미지의 고유한 면적.
  • -
  • 다른 외부 정보
  • -
- -

동 모델은 컨테이너 블록의 모서리 기준과 비례하여 상자를 렌더링합니다. 보통, 하나의 상자는 자기 자손들을 위한 컨테이너 블록을 수립합니다. 그러나 상자는 자신의 상위 컨테이너 블록에 구속되지 않습니다. 상자 조판이 상위 컨테이너 블록을 벗어나면 대열이탈 (overflow) 했다고 말합니다..

- -

상자 생성

- -

상자 생성은 해당 문서의 요소로부터 상자를 생성하는 씨에스에스 시각적 서식 모델의 일부입니다. 생성된 상자는 다양한 유형으로, 이 유형은 시각적 서식이 이뤄지는 방식에 영향을 미칩니다. 생성되는 상자 유형은 {{ cssxref("display") }} 씨에스에스 속성의 값 여하에 따라 달라집니다.

- -

블록수준 요소와 블록 상자

- -

어떤 요소를 블록수준이라고 말하려면 계산된 {{ cssxref("display") }} 씨에스에스 속성값이 block, list-item, 또는 table일 때입니다. 블록수준 요소는 사실상 하나의 블록으로 취급되어 시각적으로 서식되며, 수직적으로 겹겹이 포개집니다.

- -

각각의 블록수준 상자는 블록 서식 상황에 참여합니다. 각 블록수준 요소는 적어도 하나의 블록수준 상자를 생성하며 이를 일컬어 수석 블록수준 상자 (principal block-level box) 라고 합니다. 일부 요소 무리는 목록항목 요소와 같이 목록 항목을 안내하는 글머리표와 서로 다른 타이포그래픽 요소를 처리하기 위한 상자를 추가적으로 생성하듯 더 많은 상자 무리를 생성할 수 있습니다. 대다수는 수석 블록 수준 상자만을 생성합니다.

- -

수석 블록수준 상자는 자손이 생성한 상자 및 콘텐츠를 포함합니다. 상자는 위치잡기 기법에도 관여하고 있습니다.

- -

venn_blocks.png블록 수준 상자는 역시 블록 콘테이너 상자도 될 수 있습니다. 블록 컨테이너 상자는 다른 블록수준 상자만을 포함하고 인라인 서식 상황을 생성하므로 인라인 상자 무리만을 포함합니다.

- -

중요한 점은 블록수준 상자와 블록 컨테이너 상자의 개념은 별개라는 점에 유의해야 한다는 것입니다. 첫째, 상자가 자기 부모와 형제자매과 함께하는 행동 방식을 설명합니다. 둘째, 상자가 자기 자손과는 어떻게 상호작용하는지 설명합니다. 테이블과 같은 블록 수준의 상자 무리는 블록 컨테이너 상자가 아닙니다. 마찬가지로 비객원 (non-replaced) 인라인 블록과 비객원 테이블 셀과 같은 일부 블록 컨테이너 상자는 블록 수준 상자가 아닙니다.

- -

또한, 블록 컨테이너 상자이며 동시에 블록수준 상자를 일컬어 우리는 블록 상자 (block boxes) 라고 부릅니다.

- -

무명 블록 상자

- -

경우에 따라서는 시각적 서식 알고리즘은 보충 상자를 추가할 알고리즘도 필요합니다

- -

씨에스에스 선택기는 해당 상자에 이름을 부여하거나 스타일링을 할 수 없기 때문에 이를 일컬어무명 상자라고 합니다.

- -

선택기는 무명 상자와 협력하지 않기 때문에 스타일시트를 통해 스타일링이 적용될 수 없습니다. 즉, 상속할 수 있는 모든 씨에스에스 속성은 inherit 값을 갖고 상속할 수 없는 씨에스에스 속성은 initial 값을 가집니다.

- -

상자를 포함하는 블록은 인라인수준 상자 또는 블록수준 상자만을 포함합니다. 그러나 문서는 두 가지 모두를 혼합해 포함합니다. 그 경우 무명 블록 상자는 인접 인라인수준 상자 주변에 생성됩니다.

- -

예제

- -

아래와 같은 ({{ HTMLElement("div") }}와 {{ HTMLElement("p") }}에 기본값 스타일링이 적용된 에이치티엠엘 코드가 display: block 속성을 갖고 있다면:

- -
<div>약간의 인라인 텍스트 <p>뒤를 잇는 단락 하나</p> 그 뒤를 잇는 인라인 텍스트.</div>
- -

두 개의 무명 블록 상자가 만들어집니다: 하나는 단락 이전 텍스트(약간의 인라인 텍스트) 나머지 하나는 단락 이후 텍스트(그 뒤를 잇는 인라인 텍스트). 이는 다음과 같은 블록 구조를 구축합니다:

- -

anonymous_block-level_boxes.png

- -

결과는:

- -
약간의 인라인 텍스트
-뒤를 잇는 단락 하나
-그 뒤를 잇는 인라인 텍스트.
-
- -

{{ HTMLElement("p") }} 요소인 상자와 달리 웹 개발자는 두 개의 무명 상자 스타일을 제어할 수 없습니다. 상속 가능한 속성은 (마치 텍스트의 색상을 정의하기 위한 {{ cssxref("color") }}와 같이) {{ HTMLElement("div") }}의 속성 값에서 값을 취하고, 나머지는 초기(initial)값으로 설정합니다. 예를 들어, 무명 상자는 {{ cssxref("background-color") }}를 갖지 않을 것이라, 항상 해당 속성의 초기(initial)값을 가지며 투명합니다. 따라서 <div>의 배경이 보여집니다. 특정 배경색은 <p> 상자에 적용할 수 있습니다. 마찬가지로 두 무명 상자는 항상 같은 색을 텍스트에 사용합니다.

- -

무명 블록 상자를 만드는 또 다른 사례는 하나 또는 여러 개의 블록 상자를 포함하는 인라인 상자입니다. 이 경우 블록 상자가 들어있는 상자는 두 개의 인라인 상자로 쪼개집니다. 하나는 블록 상자 이전에, 다른 하나는 뒤에 옵니다. 블록 상자 이전의 모든 인라인 상자는 무명 블록 상자로 포섭되며, 블록 상자 뒤에 있는 인라인 상자도 마찬가지입니다. 따라서 블록 상자는 인라인 요소를 포함하는 두 개의 무명 블록 상자의 형제가 됩니다.

- -

중간에 인라인 콘텐츠가 없이 여러 블록 상자가 있는 경우 무명 블록 상자가 해당 상자 집합 이전과 이후에 생성됩니다.

- -

예제

- -

아래 에이치티엠엘 코드를 보면 {{ HTMLElement("p") }}는 display: inline 속성을 갖고 있고 {{ HTMLElement("span") }}는 display:block 속성을 갖고 있습니다:

- -
<p>일부 <em>인라인</em> 텍스트 <span>그 뒤를 잇는 단락</span> 그 뒤를 잇는 추가 인라인 텍스트.</p>
- -

두 개의 무명 블록 상자가 생성되었습니다. 스팬 요소 이전의 텍스트(일부 인라인 텍스트) 하나와 그 뒤의 텍스트(그 뒤를 잇는 추가 인라인 텍스트) 하나가 있는데 이로써 다음과 같은 블록 구조가 주어졌습니다:

- -

- -

이 것의 결과는:

- -
약간의 인라인 텍스트
-뒤를 잇는 단락 하나
-그 뒤를 잇는 인라인 텍스트.
-
- -

인라인수준 요소와 인라인 상자

- -

어떤 요소가 인라인수준이라고 말하려면 자신의 계산된 {{ cssxref("display") }} 씨에스에스 속성 값이 inline, inline-block 또는 inline-table일 때입니다. 시각적으로는 이것은 콘텐츠로 이뤄진 블록 무리를 구성하지 않고 다른 인라인수준 콘텐츠와 함께 라인의 형태로 배포됩니다. 일반적으로 강조 또는 이미지와 같이 서로 다른 서식을 가진 단락의 콘텐츠는 인라인수준 요소로 만들어집니다.

- -

venn_inlines.png

- -
-

이 도식은 구식 용어를 사용합니다: 아래 참조 사항을 보세요. 그것 이외에도 오른쪽의 노란색 타원은 정의에 따르면 왼쪽의 타원형과 동일하거나 그보다 크기 때문에(수학적 상위집합일 수 있어) 그림이 틀렀습니다, 왜냐하면 해당 씨에스에스 스펙을 보면 "인라인수준 요소는 인라인 서식 상황에 참여하는 상자인 인라인수준 상자를 생성한다"라고 쓰여있기 때문입니다. 씨에스에스 2.2, 9.2.2장 참조

-
- -

인라인 수준 요소는 인라인 서식 상황에 참여하는 상자로 정의되는 인라인수준 상자를 생성합니다. 인라인 상자는 상자와 인라인 수준 상자 모두가 해당합니다. 다만 이들 상자의 콘텐츠는 인라인 서식 상황에 참여해야 합니다. 예를 들어, display: inline 속성을 가진 모든 비객원 상자의 경우가 인라인입니다. 인라인 서식 상황에 참여하지 않는 인라인수준 상자를 원자 인라인수준 상자 (atomic inline-level boxes) 라고 합니다. 객원 인라인수준 요소 또는 계산된 {{ cssxref("display") }} 값이 inline-block인 요소에 의해 생성된 해당 상자 무리는 인라인 상자에서 가능했던 것처럼 여러 상자로 쪼개지지 않습니다.

- -
참고: 처음에는 원자 인라인수준 상자를 원자 인라인 상자라고 불렀습니다. 그 명명은 불행한 일입니다. 인라인 상자가 아니기 때문입니다. 이건 씨에스에스 규격 상에 오타로 시정된 겁니다. 그렇긴 하지만, 문장 속에서 원자 인라인 상자를 마주칠 때마다 무리없이 원자 인라인 수준 상자로 읽을 수 있습니다. 그냥 이름 변경에 불과하기 때문입니다.
- -
원자 일라인 상자는 인라인 서식 상황 속에서 여러 라인에 걸쳐 분할될 수 없습니다. -
-
<style>
-  span {
-    display:inline; /* default value*/
-  }
-</style>
-<div style="width:20em;">
-   스팬 요소에 포함된 택스트는 <span> 몇 개의 라인으로 분할 될 수
-   있습니다. 왜냐면 </span> 그것이 인라인 상자이기 때문입니다.
-</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;">
-   스팬 요소에 포함된 텍스트는 <span>몇 라인으로 분할 될 수
-   없 습니다. 왜냐면 </span> 그것이 인라인 블록이기 때문입니다.
-</div>
-
- -

이 것의 결과는:

- -
스팬 요소에 포함된 텍스트는 분할될 수 없습니다. 왜냐면 인라인 블록 상자이기 때문입니다.
-
-
- -

무명 인라인 상자

- -

블록상자처럼 씨에스에스 엔진에 의해 자동적으로 인라인상자가 생성되는 경우가 몇 개 있습니다. 이들 인라인 상자는 무명으로, 선택기가 이름을 특정할 수 없습니다. 무명 인라인 상자의 속성은, 상속 가능한 것은 상속된 값을, 그 이외는 initial 값을 가집니다.

- -

무명의 인라인 상자가 만들어지는 흔한 경우는 인라인 서식 상황을 만드는 블록상자의 직계 자식 요소로 파악되는 텍스트가 있는 경우입니다. 이 경우, 동 텍스트는 최대한 큰 무명 인라인 상자에 넣을 수 있습니다. 또한, 씨에스에스의 {{ cssxref("white-space") }} 속성으로 지정된 동작에 의해 제거되는 공백의 콘텐츠는 결국 공백이 될 것이기 때문에 무명 인라인 상자를 생성하지 않습니다.

- -
예제 TBD
- -

다른 유형의 상자

- -

라인 상자

- -

라인 상자는 텍스트 라인을 표현하기 위해 인라인 서식 상황에 의해 생성되는 상자입니다. 블록 상자 내부의 라인 상자는 상자의 한쪽 테두리로부터 반대측의 테두리까지 넓어집니다. 부동체가 있을 경우 라인 상자 구역은 왼쪽 부동체의 맨우측 테두리에서 시작해 우측 부동체의 맨좌측 테두리에서 끝납니다.

- -

이들 상자는 기술적인 것으로, 보통 웹 저술가가 이것에 대해 고민할 필요는 없습니다.

- -

내부진행 상자

- -

display: run-in을 사용하도록 정의되는 내부진행 상자 (Run-in boxes) 는 후속 상자의 유형 여하에 따라 블록 상자이거나 인라인 상자입니다. 그들은 가능할 경우 자신의 첫 단락 내부에 진행하는 글 제목을 생성하는 데 사용될 수 있습니다.

- -
참고: 내부진행 상자는 씨에스에스 2.1 규격에서 제외되었다. 상호운용 실현 가능성을 불충분하게 명시했기 때문입니다. 그들이 씨에스에스 3 (CSS 3) 에선 다시 등장할 수도 있지만, 현재로선 실험 상태로 간주합니다. 그들을 완성품에선 사용하지 말아야 합니다.
- -

모델유인 상자

- -

인라인 및 블록 서식 상황 외에도 씨에스에스는 요소에 적용할 수 있는 몇 가지 추가 콘텐츠 모델을 지정할 수 있습니다. 특정 레이아웃을 설명하는 데 사용되는 이러한 추가 모델은 추가 상자 유형을 정의할 수 있습니다.

- -
    -
  • 테이블 콘텐츠 모델테이블 래퍼 상자테이블 상자를 생성할 수 있을뿐만 아니라 캡션 상자같은 특정 상자도 생성할 수 있습니다.
  • -
  • The 다단 콘텐츠 모델 은 컨테이너 상자와 컨텐츠 사이에 열 상자 (column boxes) 를 생성할 수 있습니다.
  • -
  • 실험적인 격자 또는 가변상자 콘텐츠 모델, 또는 추가적인 유형의 상자를 생성할 수 있습니다.
  • -
- -

위치잡기 기법

- -

상자를 생성하고 나면 씨에스에스 엔진은 그것들을 조판에 위치시켜야 합니다. 그렇게 하려면 다음과 같은 알고리즘 중의 하나를 사용합니다.

- -
    -
  • 일반 대열 (normal flow) - 하나씩 차례대로 상자를 위치시킵니다.
  • -
  • 부동체 (floats) 알고리즘 - 일반 대열에서 상자를 빼내어 상위 컨테이너 상자 옆에 놓습니다.
  • -
  • 절대 위치잡기 기법 - 자신의 상위 컨테이너 요소가 수립한 절대 좌표 시스템 내부에 상자를 위치시킵니다. 절대적으로 위치잡기한 요소는 다른 요소를 덮을 수 있습니다.
  • -
- -

일반 대열

- -

일반 대열 속 상자 무리는 하나씩 차례대로 배치됩니다. 블록 서식 상황 속에서 그들은 수직으로 배치됩니다. 반면에 인라인 서식 상황 속에서 그들은 수평으로 배치됩니다. 일반 대열은 CSS {{ cssxref("position") }}이 static 또는 relative 값으로 설정될 경우와 {{ cssxref("float") }}가 none으로 설정되면 발동됩니다.

- -

예제

- -
일반 대열 속에서는 블록 서식 상황에 포함된 상자는 수직으로 하나씩 차례대로 배치됩니다.
-
-일반 대열 속에서는 인라인 서식 상황에 포함된 상자는 수평으로 하나씩 차례대로 배치됩니다.
- -
-

일반 대열에는 두 가지 하위 사례가 있습니다. 정적 위치잡기와 상대 위치잡기:

- -
    -
  • 정적 위치잡기에서는 {{ cssxref("position") }} 속성이 static 값일 경우에 발동됩니다. 상자 무리는 일반 대열 조판에 정의된 정확한 위치에 그려집니다.
  • -
  • 상대 위치잡기에서는 {{ cssxref("position") }} 속성이 relative 값일 경우 발동합니다. 상자는 씨에스에스 속성 무리인 {{ cssxref("top") }}, {{ cssxref("bottom") }}과 {{ cssxref("left") }}, {{ cssxref("right") }}에 의해 정의된 간격띄우기 값을 기준으로 그려집니다.
  • -
-
- -

부동체

- -

부동 위치잡기 기법 (float positioning scheme) 에서는 특정 상자(부동 상자 또는 단순 부동체라고 일컬음)를 현재 라인의 시작 또는 끝에 위치시킵니다. 이는 텍스트(그리고 더 일반적으로 일반 대열 내의 모든 것)은 부동 상자의 가장자리를 따라 대열을 맞추는 속성으로 귀결됩니다. 다만 씨에스에스 {{ cssxref("clear") }} 속성에 의해 다른 예기가 나올 경우는 예외입니다.

- -

상자에 대해 부동 위치잡기 기법을 선택하려면 해당 상대에 대해 씨에스에스 {{ cssxref("float") }} 속성을 none 이외의 값으로 설정하거나 {{ cssxref("position") }} 속성에 static이나 relative가 아닌 값으로 설정할 때 이뤄진다. 만일 {{ cssxref("float") }}가 left로 설정되면 부동체는 라인 상자의 시작 부분에 위치합니다. 만일 right으로 설정되면 동 부동체는 라인 상자의 끝에 위치합니다. 어떤 경우든 라인 상자는 부동체에 들어맞게 축소됩니다.

- -

절대 위치잡기

- -

절대 위치잡기 기법 (absolute positioning scheme) 에 포함된 상자는 대열에서 제거되어 대열과는 어떤 상호작용도 하지 않습니다. 그들은 {{ cssxref("top") }}과 {{ cssxref("bottom") }}, {{ cssxref("left") }}와 {{ cssxref("right") }}를 사용해서 상위 컨테이너 블록 기준으로 비례해서 위치잡기합니다.

- -

하나의 요소를 절대 위치잡기하려면 {{ cssxref("position") }}이 absolute 또는 fixed로 설정하면 됩니다.

- -

고정 위치잡기한 요소의 경우 상위 컨테이너 블록이 뷰포트입니다. 동 요소의 위치는 뷰포트 내부에서 절대적 위치가 됩니다. 스크롤링은 동 요소의 위치를 변경시키지 않습니다.

- -

참조 항목

- -
    -
  • {{css_key_concepts}}
  • -
diff --git a/files/ko/web/guide/dom/index.html b/files/ko/web/guide/dom/index.html deleted file mode 100644 index fc26bc0bee..0000000000 --- a/files/ko/web/guide/dom/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: DOM developer guide -slug: Web/Guide/DOM -tags: - - API - - DOM - - Guide - - NeedsTranslation - - TopicStub -translation_of: Web/API/Document_Object_Model -translation_of_original: Web/Guide/API/DOM ---- -

{{draft}}

-

The Document Object Model is an API for HTML and XML documents. It provides a structural representation of the document, enabling the developer to modify its content and visual presentation. Essentially, it connects web pages to scripts or programming languages.

-

All of the properties, methods, and events available to the web developer for manipulating and creating web pages are organized into objects (e.g., the document object that represents the document itself, the table object that represents a HTML table element, and so forth). Those objects are accessible via scripting languages in most recent web browsers.

-

The DOM is most often used in conjunction with JavaScript. However, the DOM was designed to be independent of any particular programming language, making the structural representation of the document available from a single, consistent API. Though we focus on JavaScript throughout this site, implementations of the DOM can be built for any language.

-

The World Wide Web Consortium establishes a standard for the DOM, called the W3C DOM. It should, now that the most important browsers correctly implement it, enable powerful cross-browser applications.

-

Why is the DOM important?

-

"Dynamic HTML" (DHTML) is a term used by some vendors to describe the combination of HTML, style sheets and scripts that allows documents to be animated. The W3C DOM Working Group is working hard to make sure interoperable and language-neutral solutions are agreed upon (see also the W3C FAQ). As Mozilla claims the title of "Web Application Platform", support for the DOM is one of the most requested features, and a necessary one if Mozilla wants to be a viable alternative to the other browsers.

-

Even more important is the fact that the user interface of Mozilla (also Firefox and Thunderbird) is built using XUL, using the DOM to manipulate its own UI.

-

More about the DOM

-

{{LandingPageListSubpages}}

diff --git a/files/ko/web/guide/dom/using_full_screen_mode/index.html b/files/ko/web/guide/dom/using_full_screen_mode/index.html deleted file mode 100644 index d7f561a95c..0000000000 --- a/files/ko/web/guide/dom/using_full_screen_mode/index.html +++ /dev/null @@ -1,198 +0,0 @@ ---- -title: Using fullscreen mode -slug: Web/Guide/DOM/Using_full_screen_mode -translation_of: Web/API/Fullscreen_API ---- -
{{DefaultAPISidebar("Fullscreen API")}}
- -

Fullscreen API 는 특정 요소{{DOMxRef("Element")}}(와 해당 자손들을)를 full-screen mode로 표시하고, 더 이상 필요하지 않으면 full-screen mode를 종료하는 메서드를 추가합니다. 이렇게 하면 사용자의 전체 화면을 사용하여, 온라인 게임과 같은 원하는 내용을 표시할 수 있습니다. full-screen mode가 종료될 때까지 화면에서 브라우저의 모든 유저 인터페이스 요소와 기타 응용 프로그램을 제거할 수 있습니다.

- -

API 사용 방법에 대한 자세한 내용은 Guide to the Fullscreen API 문서를 참조하세요.

- -
-

주의: 이 API에 대한 지원은 여러 브라우저에서 이루어지며, 다양한 업체의 접두사(prefix)가 필요하거나, 최신 사양을 구현하지 않는 경우가 많습니다. 이 API 지원에 대한 자세한 내용은 아래에 있는 {{anch("Browser compatibility")}} 섹션을 참조하세요. Fullscreen API를 지원하지 않는 업체의 경우, Fscreen 과 같은 라이브러리를 사용할 수 있습니다.

-
- -

Interfaces

- -

Fullscreen API 에는 자체 인터페이스가 없습니다. 대신에, full-screen 기능을 제공하는데 필요한 메서드, 속성(property), 이벤트 핸들러를 추가하기 위해, 다음 섹션에 나열된 것과 같은 몇 가지 다른 인터페이스를 추가합니다.

- -

Methods

- -

Fullscreen API 는 {{DOMxRef("Document")}}, {{DOMxRef("Element")}} 인터페이스에 메서드를 추가하여 full-screen mode를 설정하거나 해제할 수 있습니다.

- -

Methods on the Document interface

- -
-
{{DOMxRef("Document.exitFullscreen()")}}
-
{{Glossary("user agent")}} 가 full-screen mode에서 창 모드로 다시 전환되도록 요청합니다. full-screen mode가 완전히 종료되면 {{jsxref("Promise")}} resolved 를 반환합니다.
-
- -

Methods on the Element interface

- -
-
{{DOMxRef("Element.requestFullscreen()")}}
-
유저 에이전트가 지정한 요소(그리고 그 자손들까지)를 full-screen mode로 설정하고, 브라우저의 모든 UI 요소와 다른 모든 애플리케이션을 화면에서 제거하도록 요구합니다. full-screen mode가 활성화되면 {{jsxref("Promise")}} resolved를 반환합니다.
-
- -

Properties

- -

{{DOMxRef("Document")}} 인터페이스는 full-screen mode가 지원되고 사용 가능한지, full-screen mode가 현재 활성화 되어있는지, 어떤 요소가 스크린을 사용하고 있는지 확인하는데 사용할 수 있는 속성(property)을 제공합니다.

- -
-
{{DOMxRef("DocumentOrShadowRoot.fullscreenElement")}}
-
fullscreenElement 속성은 DOM(혹은 shadow DOM)에서 현재 full-screen mode로 표시되는 요소{{DOMxRef("Element")}}를 알려줍니다. 이것이 null인 경우, document는 full-screen mode가 아닙니다.
-
{{DOMxRef("Document.fullscreenEnabled")}}
-
fullscreenEnabled 속성(property)은 full-screen mode를 사용할 수 있는지 여부를 알려줍니다. 이유가 어떻든(예를들어, "fullscreen" 기능이 허락되지 않거나, full-screen mode가 지원되지 않는 경우) full-screen mode를 사용할 수 없으면 false 입니다.
-
- -

Event handlers

- -

Fullscreen API는 full-screen mode를 켜고 끌 때 혹은, full-screen mode와 window mode간에 변경하는 과정에서 오류가 발생하는 것을 감지하는데 사용할 수 있는 두 가지 이벤트를 정의합니다. 이러한 이벤트에 대한 이벤트 핸들러는 {{DOMxRef("Document")}} 와{{DOMxRef("Element")}} 인터페이스 에서 사용할 수 있습니다.

- -
-

주의: 이러한 이벤트 핸들러 속성(property)은 HTML 컨텐트 속성(attribute)으로 사용할 수 없습니다. 즉, HTML 컨텐트에서 {{Event("fullscreenchange")}} 및 {{Event("fullscreenerror")}} 이벤트를 지정할 수 없습니다. 자바스크립트 코드로 추가해야만 합니다.

-
- -

Event handlers on documents

- -
-
{{DOMxRef("Document.onfullscreenchange")}}
-
문서(document)가 full-screen mode로 전환되거나 full-screen mode를 종료할 때 {{DOMxRef("Document")}}로 보내지는 {{Event("fullscreenchange")}} 이벤트에 대한 이벤트 핸들러 입니다. 이 핸들러는 오직 전체 문서가 full-screen mode로 표시될 때만 호출됩니다.
-
{{DOMxRef("Document.onfullscreenerror")}}
-
전체 문서에 대해 full-screen mode를 사용하거나, 사용하지 않도록 설정하는 동안 오류가 발생하면, {{DOMxRef("Document")}}로 보내지는 {{Event("fullscreenerror")}} 이벤트의 이벤트 핸들러입니다.
-
- -

Event handlers on elements

- -
-
{{DOMxRef("Element.onfullscreenchange")}}
-
{{Event("fullscreenchange")}} 이벤트가 요소(element)로 전송되면, 요소가 full-screen mode로 배치되거나 제거되었음을 나타내는 이벤트 핸들러입니다.
-
{{DOMxRef("Element.onfullscreenerror")}}
-
full-screen mode 를 사용하거나, 사용하지 않도록 설정하는 동안 오류가 발생하면 요소로 보내지는 {{Event("fullscreenerror")}} 이벤트의 이벤트 핸들러입니다.
-
- -

Obsolete properties

- -
-
{{DOMxRef("Document.fullscreen")}} {{Deprecated_Inline}}
-
문서에 현재 full-screen mode로 표시되는 요소가 있는 경우 true, 그렇지 않으면 false의 Boolean 값입니다. -
주의: 대신에 {{DOMxRef("Document")}} 나 {{DOMxRef("ShadowRoot")}} 에서 {{DOMxRef("Document.fullscreenElement", "fullscreenElement")}} 속성(property)을 사용하세요. 그것이 null이 아닌 경우 {{DOMxRef("Element")}}가 full-screen mode로 표시됩니다.
-
-
- -

Events

- -

Fullscreen API는 full-screen mode를 켜고 끌 때 혹은, full-screen mode와 window mode간에 변경하는 과정에서 오류가 발생하는 것을 감지하는데 사용할 수 있는 두 가지 이벤트를 정의합니다.

- -
-
{{Event("fullscreenchange")}}
-
full-screen mode를 사용하거나, 사용하지 않도록 전환할 때 {{DOMxRef("Document")}} 혹은{{DOMxRef("Element")}} 로 보냅니다.
-
{{Event("fullscreenerror")}}
-
full-screen mode를 사용하거나, 사용하지 않도록 전환하려고 시도하는 중에 오류가 발생하면 Document 또는 Element 로 보냅니다.
-
- -

Dictionaries

- -
-
{{DOMxRef("FullscreenOptions")}}
-
{{DOMxRef("Element.requestFullscreen", "requestFullscreen()")}}을 호출할 때 지정할 수 있는 옵션 설정을 제공합니다.
-
- -

Controlling access

- -

Feature Policy을 사용하여 full-screen mode의 유효성을 제어할 수 있습니다. full-screen mode는 "fullscreen"으로 식별되고, 기본 허용 목록 값은 "self" 입니다. 이는 최상위(top-level) 문서 컨텍스트에서 full-screen mode가 허용된다는 것을 의미하며, 최상위(top-most) 문서와 같은 출처에서 로드 된 중첩 된 컨텍스트에도 적용됩니다.

- -

기능 정책을 사용하여 API에 대한 액세스를 제어하는 자세한 내용은 Using Feature Policy을 참조하세요.

- -

Usage notes

- -

사용자는 ESC (혹은 F11) 키를 누르기만하면 사이트 또는 앱이 프로그래밍 방식으로 기다리는 대신에, full-screen mode를 종료하도록 선택할 수 있습니다. 유저 인터페이스의 어딘가에 사용자에게 이 옵션을 사용할 수 있음을 알리는, 적절한 유저 인터페이스 요소를 제공해야 합니다.

- -
-

주의: 다른 페이지로 이동하거나, 탭을 변경하거나, 응용 프로그램 전환기(또는 Alt-Tab)를 사용하여, 다른 응용 프로그램으로 전환하면 마찬가지로 full-screen mode가 종료됩니다.

-
- -

Example

- -

이 예제에서는 비디오가 웹 페이지에 표시됩니다. Return 또는 Enter 키를 누르면, 사용자가 비디오의 창과 full-screen 표시를 전환할 수 있습니다.

- -

View Live Examples

- -

Watching for the Enter key

- -

페이지가 로드되면, 이 코드가 실행되어 Enter 키 를 주시하는 이벤트 리스너를 설정합니다.

- -
document.addEventListener("keypress", function(e) {
-  if (e.keyCode === 13) {
-    toggleFullScreen();
-  }
-}, false);
-
- -

Toggling full-screen mode

- -

이 코드는 사용자가 Enter 키를 누를 때, 위의 이벤트 핸들러에 의해 호출됩니다.

- -
function toggleFullScreen() {
-  if (!document.fullscreenElement) {
-    document.documentElement.requestFullscreen();
-  } else {
-    if (document.exitFullscreen) {
-      document.exitFullscreen();
-    }
-  }
-}
- -

먼저 {{DOMxRef("Document", "document")}}의 fullscreenElement 속성(attribute)값을 살펴보겠습니다. 실제 배포 시에는 이 시점에 접두어가 붙은 버전(예를들어, mozFullscreenElement, msFullscreenElement, webkitFullscreenElement)을 확인해야 합니다. 값이 null인 경우, 문서는 현재 window mode에 있으므로, full-screen mode로 전환해야 합니다. 그렇지 않으면, 이 요소는 지금 full-screen mode 상태입니다. full-screen mode로 전환하는 작업은, {{HTMLElement("video")}}요소에서 {{DOMxRef("Element.requestFullscreen()")}}을 호출하여 수행합니다.

- -

full-screen mode가 이미 활성화 된 경우(fullscreenElement 가 null이 아닌 경우), document에서 {{DOMxRef("Document.exitFullscreen", "exitFullscreen()")}}을 호출하여 full-screen mode를 종료합니다.

- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName("Fullscreen")}}{{Spec2("Fullscreen")}}Initial version.
- -

Browser compatibility

- -

Document.fullscreen

- -
- - -

{{Compat("api.Document.fullscreen")}}

- -

Document.fullscreenEnabled

- -
- - -

{{Compat("api.Document.fullscreenEnabled")}}

-
-
- -

See also

- -
    -
  • Using full-screen mode
  • -
  • {{DOMxRef("Element.requestFullscreen()")}}
  • -
  • {{DOMxRef("Document.exitFullscreen()")}}
  • -
  • {{DOMxRef("Document.fullscreen")}}
  • -
  • {{DOMxRef("Document.fullscreenElement")}}
  • -
  • {{CSSxRef(":fullscreen")}}, {{CSSxRef("::backdrop")}}
  • -
  • {{HTMLAttrXRef("allowfullscreen", "iframe")}}
  • -
diff --git a/files/ko/web/guide/graphics/index.html b/files/ko/web/guide/graphics/index.html new file mode 100644 index 0000000000..cb7cd6f873 --- /dev/null +++ b/files/ko/web/guide/graphics/index.html @@ -0,0 +1,48 @@ +--- +title: 웹 상 그래픽 +slug: Web/Guide/그래픽 +tags: + - 2D + - 3D + - Canvas + - Graphics + - HTML5 + - SVG + - WebGL + - WebRTC +translation_of: Web/Guide/Graphics +--- +

웹 사이트 및 응용 프로그램은 종종 그래픽을 보일 필요가 있습니다. 정지 이미지는 {{HTMLElement("img")}} 요소 사용이나 {{cssxref("background-image")}} 속성을 사용한 HTML 요소의 배경 설정으로 쉽게 표시할 수 있습니다. 또한 그래픽을 그때그때 생성하거나 사후에 이미지를 조작할 수도 있습니다. 여기서는 이를 수행할 수 있는 법을 주의 깊게 살펴봅니다.

+ +
+
+

2D 그래픽

+ +
+
Canvas
+
{{HTMLElement("canvas")}} 요소는 JavaScript를 사용하여 2D 그래픽을 그리는 API를 제공합니다.
+
SVG
+
Scalable Vector Graphics (SVG)는 그래픽을 묘사하기 위해 선, 곡선 및 그 밖의 기하학 도형을 사용할 수 있습니다. 벡터로, 어떤 크기로든 깔끔하게 크기 조정하는 이미지를 만들 수 있습니다.
+
+ +

모두 보기...

+
+ +
+

3D 그래픽

+ +
+
WebGL
+
웹을 위한 3D 그래픽인 WebGL 시작 안내서. 이 기술로 웹 콘텐츠에 표준 OpenGL ES를 사용할 수 있습니다.
+
+ +

비디오

+ +
+
HTML5 audio 및 video 사용
+
웹 페이지 내 비디오 및/또는 오디오 삽입 및 그 재생 제어.
+
WebRTC
+
WebRTC에서 RTC는 실시간 통신(Real-Time Communications)을 뜻하며, 오디오/비디오 스트리밍 및 브라우저 클라이언트(peer) 간 데이터 공유를 가능하게 하는 기술입니다.
+
+
+
diff --git a/files/ko/web/guide/html/content_editable/index.html b/files/ko/web/guide/html/content_editable/index.html deleted file mode 100644 index 2e039ea976..0000000000 --- a/files/ko/web/guide/html/content_editable/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Content Editable -slug: Web/Guide/HTML/Content_Editable -tags: - - HTML - - HTML5 - - 가이드 - - 고급 - - 예제 - - 웹 - - 필요컨텐트 -translation_of: Web/Guide/HTML/Editable_content ---- -

HTML5 에서는 어떤 엘러먼트라도 수정이 가능하다. 약간의 JavaScript 이벤트 핸들러들을 사용하는 것만로 당신은 웹페이지를 완전하고 빠른 리치-텍스트 에디터로 변형할 수 있다. 이 문서는 이런 기능성에 대하여 대략의 정보를 제공 한다.

- -

호환성

- -

Content editable 은 현재 브라우저들과 완전히 호환된다.

- -
    -
  • Firefox 3.5+
  • -
  • Firefox for Android 19+
  • -
  • Chrome 4.0+
  • -
  • Internet Explorer 5.5+ *
  • -
  • Safari 3.1+
  • -
  • Opera 9+
  • -
  • iOS Safari 5.0+
  • -
  • Android Browser 3.0+
  • -
  • Opera Mobile 12.1+
  • -
  • Chrome for Android 25+
  • -
- -

Opera Mini 는 아직 지원되지 않는다.

- -
-

*대부분의 html elements 를 지원 하지 않는다.

-
- -

어떻게 작동 하는가?

- -

{{DOMXRef("HTMLElement.contentEditable", "contentEditable")}} 속성을 HTML element 에서 true 로 설정하라. 이 속성은 대부분의 HTML elements 에 사용될 수 있다.

- -

예제들

- -

간단한 예제:

- -
<!DOCTYPE html>
-<html>
-  <body>
-    <div contentEditable="true">
-      This text can be edited by the user.
-    </div>
-  </body>
-</html> 
- -

LocalStorage 를 이용한 JavaScript 와 합쳐진 작동 예제를 여기에서 볼 수 있다. 소스는 이곳에 있다.

- -

더 보기

- -
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");
- -

컨텐트와 상호 작용하는 방법  (오래된 IE 스타일 API) 그리고 이곳

diff --git a/files/ko/web/guide/html/editable_content/index.html b/files/ko/web/guide/html/editable_content/index.html new file mode 100644 index 0000000000..2e039ea976 --- /dev/null +++ b/files/ko/web/guide/html/editable_content/index.html @@ -0,0 +1,65 @@ +--- +title: Content Editable +slug: Web/Guide/HTML/Content_Editable +tags: + - HTML + - HTML5 + - 가이드 + - 고급 + - 예제 + - 웹 + - 필요컨텐트 +translation_of: Web/Guide/HTML/Editable_content +--- +

HTML5 에서는 어떤 엘러먼트라도 수정이 가능하다. 약간의 JavaScript 이벤트 핸들러들을 사용하는 것만로 당신은 웹페이지를 완전하고 빠른 리치-텍스트 에디터로 변형할 수 있다. 이 문서는 이런 기능성에 대하여 대략의 정보를 제공 한다.

+ +

호환성

+ +

Content editable 은 현재 브라우저들과 완전히 호환된다.

+ +
    +
  • Firefox 3.5+
  • +
  • Firefox for Android 19+
  • +
  • Chrome 4.0+
  • +
  • Internet Explorer 5.5+ *
  • +
  • Safari 3.1+
  • +
  • Opera 9+
  • +
  • iOS Safari 5.0+
  • +
  • Android Browser 3.0+
  • +
  • Opera Mobile 12.1+
  • +
  • Chrome for Android 25+
  • +
+ +

Opera Mini 는 아직 지원되지 않는다.

+ +
+

*대부분의 html elements 를 지원 하지 않는다.

+
+ +

어떻게 작동 하는가?

+ +

{{DOMXRef("HTMLElement.contentEditable", "contentEditable")}} 속성을 HTML element 에서 true 로 설정하라. 이 속성은 대부분의 HTML elements 에 사용될 수 있다.

+ +

예제들

+ +

간단한 예제:

+ +
<!DOCTYPE html>
+<html>
+  <body>
+    <div contentEditable="true">
+      This text can be edited by the user.
+    </div>
+  </body>
+</html> 
+ +

LocalStorage 를 이용한 JavaScript 와 합쳐진 작동 예제를 여기에서 볼 수 있다. 소스는 이곳에 있다.

+ +

더 보기

+ +
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");
+ +

컨텐트와 상호 작용하는 방법  (오래된 IE 스타일 API) 그리고 이곳

diff --git a/files/ko/web/guide/html/html5/index.html b/files/ko/web/guide/html/html5/index.html new file mode 100644 index 0000000000..2d64ce56d6 --- /dev/null +++ b/files/ko/web/guide/html/html5/index.html @@ -0,0 +1,122 @@ +--- +title: HTML5 +slug: Web/HTML/HTML5 +translation_of: Web/Guide/HTML/HTML5 +--- +

HTML5는 HTML를 정의하는 표준화에 있어서의 최신 표준 명세입니다. HTML5 명세는 아직도 표준 지정이 완료되지 않았고 변경이 계속 진행 중입니다. 하지만, Mozilla 및 다른 웹 브라우저 벤더는 이미 사양 중  많은 부분에 대한 구현을 시작하고 있습니다. 여기에 링크 하고 있는 문서에서는 Firefox다른 많은 제품으로 사용되어 있는 Mozilla의 Gecko 엔진에 있어서 이미 기술 지원되어 있는 HTML5의 기능에 대해 설명하고 있습니다. 각각의 기능을 기술 지원하고 있는 Gecko 버전 및 다른 브라우저 엔진에 대해서는 지정된 페이지를 참조해 주십시오.

+ +

(HTML5의 문서에 대한 다른 분류도 참고하세요.)

+ +

HTML5 소개

+ +
+
HTML5의 소개
+
이 문서에서는 웹 디자인이나 웹 애플리케이션으로 HTML5 이용 방법을 소개합니다.
+
+ +

HTML5의 요소

+ +
+
HTML5 요소·태그의 목록
+
현재 사양 초안에 근거한 HTML5 요소(태그)의 목록표입니다.
+
오디오/비디오 사용하기
+
Firefox 3.5이상에서  HTML5의 {{ HTMLElement("audio") }} 요소와 {{ HTMLElement("video") }} 요소의 기술 지원이 추가되었습니다.
+
HTML5 웹 폼양식
+
HTML5에서는 웹 폼양식이 개선됩니다. {{ HTMLElement("input") }} 요소의 {{ htmlattrxref("type", "input") }} 속성에 새로운 값이나 새 요소인 {{ HTMLElement("output") }} 요소 등이 새롭게 추가되었습니다.
+
HTML5 섹션과 아웃라인
+
HTML5 에서는 아웃라인과 섹션에 관한 요소가 추가되었습니다.: {{ HTMLElement("section") }}, {{ HTMLElement("article") }}, {{ HTMLElement("nav") }}, {{ HTMLElement("header") }}, {{ HTMLElement("footer") }}, {{ HTMLElement("aside") }}, {{ HTMLElement("hgroup") }}.
+
{{ HTMLElement("mark") }} 요소
+
mark 요소는 텍스트중에서의 특별한 관련성을 강조시키기 위해서 이용합니다.
+
{{ HTMLElement("figure") }} 및 {{ HTMLElement("figcaption") }} 요소
+
주로 사용된 문장과 느슨하게 연결된, 최종 캡션을 수반한 도식이나 그림을 추가할 수 있습니다.
+
+ +

Canvas 기술 지원

+ +
+
Canvas 튜토리얼
+
새로운 요소인 {{ HTMLElement("canvas") }} 요소와 그것을 사용하여 Firefox에 그래프나 다른 객체를 재생 하는 방법에 대해 배웁니다.
+
canvas 요소의 HTML5 text API
+
{{ HTMLElement("canvas") }} 요소가 HTML5 text API를 기술 지원합니다.
+
+ +

웹 애플리케이션 기능

+ +
+
Firefox 오프 라인 자원
+
Firefox는 HTML5의 오프 라인 자원 사양을 완전하게 구현 및 지원하고 있습니다. 대다수 브라우저의 몇 가지 레벨로 오프 라인 자원을 기술 지원하고 있습니다.
+
Online 이벤트와 Offline 이벤트
+
Firefox 3은 WHATWG의 online 및 offline 이벤트를 기술 지원하고 있습니다. 이러한 이벤트는 애플리케이션이나 확장 기능에 현재 인터넷 접속 상태의 연결 여부를 확인할 수 있습니다.
+
WHATWG 클라이언트 사이드 세션 스토리지 및 영구 스토리지 (DOM Storage)
+
클라이언트 사이드 세션 스토리지와 영구 스토리지에 의하고 웹 애플리케이션이 구조화 데이터를 클라이언트 측에 저장할 수 있도록 합니다.
+
contentEditable 속성: 웹 사이트 및 위키 편집 용이성
+
HTML5 에서는 contentEditable 속성이 표준화 되었습니다. 이 기능에 대해 살펴봅니다.
+
로컬 파일 사용하기
+
새로운 HTML5 File API 지원이 Gecko에 추가되었습니다. 이 API는 웹 애플리케이션이 사용자가 선택한 로컬 파일에 접근 하는 것을 가능하게 합니다. 이것에는 type 속성의 값에 file를 지정한 {{ HTMLElement("input") }} 요소에 새롭게 추가된 multiple 속성을 이용하는 것으로 복수 파일을 선택할 수 있게 되는 기술 지원가 포함되어 있습니다.
+
+ +

DOM 주요 기능

+ +
+
getElementsByClassName
+
Document 및 Element 노드에 있어서의 getElementsByClassName 메소드가 지원되어 있습니다. 이러한 메소드를 이용하는 것으로 지정한 클래스 또는 지정한 클래스의 목록를 가지는 요소를 찾아낼 수 있습니다.
+
드래그 앤 드롭
+
HTML5의 드래그앤 드롭 API는 웹 사이트간에 있어서의 아이템의 끌어오기 및 놓기 기능을 지원합니다. 또, 확장 기능이나 Mozilla 기반의 애플리케이션으로 사용할 수 있는 단순한 API 도 제공합니다.
+
HTML 내 포커스 관리
+
HTML5가 새로운 activeElement 속성과 hasFocus 속성이 지원되어 있습니다.
+
웹 기반 프로토콜 핸들러
+
navigator.registerProtocolHandler()메소드를 사용하여, 웹 애플리케이션을 프로토콜 핸들러로서 등록할 수 있게 되었습니다.
+
+ +

HTML 파서

+ +

Gecko의 HTML5 표준 파서(HTML 문서를  DOM으로 변환하는 엔진)는 2010 년 3 월에 기본적으로 사용됩니다(Gecko 1.9.2 / Firefox 3.6에 탑재되어 있는 시점의 HTML5 파서는 매우 불안정한 버전이며 실제 이용하는 것을 추천 하지 않습니다).{{ fx_minversion_inline(4.0) }}

+ +

추가 변경사항

+ +
    +
  • HTML 문서에 있어서의 localNamenamespaceURI는 XML 문서 때와 같은 행동을 하게 되었습니다. 예를 들면, localName는 소문자를 돌려주어, HTML 요소의 namespaceURI"http://www.w3.org/1999/xhtml"를 돌려줍니다.
  • +
  • 페이지 URI 문서 단편 식별자 ("#" (해시) 문자에서 후의 부분)가 변경되었을 때, 새로운 hashchange 이벤트가 페이지에 보내집니다. 자세한 것은 window.onhashchange를 참조해 주십시오.
  • +
  • class 속성을 보다 간단하게 취급할 수 있도록 HTML5의 element.classList이 기술 지원되었습니다.
  • +
  • 문서에 즉시 생성되는 이벤트에 응하는 document.onreadystatechangedocument.readyState가 기술 지원되었습니다.
  • +
  • 표시에 관련하는 속성으로 지정한 색은 HTML5의 사양에 따라서 해석됩니다.
  • +
+ +

HTML5의 일부로서 포함된 기술

+ +

아래 기술들은 "HTML5"의 광의의 영역에 포함되어 있습니다만 W3C의 HTML5 사양에 없는 것들입니다.

+ + + +

관련 문서

+ +

웹 발자에게 영향이 있는 Firefox 출시 버전에 따른 변경점:

+ + diff --git a/files/ko/web/guide/html/html5/introduction_to_html5/index.html b/files/ko/web/guide/html/html5/introduction_to_html5/index.html new file mode 100644 index 0000000000..8b9698dc53 --- /dev/null +++ b/files/ko/web/guide/html/html5/introduction_to_html5/index.html @@ -0,0 +1,40 @@ +--- +title: HTML5 소개 +slug: Web/HTML/HTML5/Introduction_to_HTML5 +tags: + - HTML5 + - 웹개발 +translation_of: Web/Guide/HTML/HTML5/Introduction_to_HTML5 +--- +

HTML5는 HTML 표준의 가장 새로운 버전입니다. HTML5를 통해 리치 미디어의 기술 지원 뿐만이 아니라, 사용자 및 로컬 데이터를 웹 서버 사이에 보다 간편하면서도 효과적으로 교환할 수 있는 웹 애플리케이션을 개발하기 위한 확장 기술 지원를 제공하는 새로운 기능도 제공됩니다.

+ +

HTML5는 아직 표준 제정 단계에 있기 때문에 현재 사양에 대한 변경이 있을 것입니다. 따라서 모든 브라우저에 HTML5 기능 모든 것이 기술 지원되어 있는 것은 아닙니다. 하지만, Gecko (그리고 이를 사용하는 Firefox)에는 훌륭하게 HTML5의 최초 단계 기술 지원이 포함되어 있어 새로운 기능에 대한 대처를 계속하고 있습니다. Gecko는 버전 1.8.1에서 HTML5의 기능을 기술 지원하기 시작했습니다. HTML5의 메인 페이지에 Gecko가 기술 지원하고 있는 HTML5기능 목록이 있습니다. 여러 브라우저의 기술 지원 상황의 상세한 정보에 대해서는 CanIUse 웹 사이트를 참조해 주십시오.

+ +

HTML5 DOCTYPE

+ +

HTML5의 DOCTYPE는 매우 간단합니다. HTML 콘텐트로 HTML5를 사용하는 것을 나타내려면 단순하게 아래와 같이 합니다:

+ +
<!DOCTYPE html>
+
+ +

이  DOCTYPE은 현재 HTML5를 기술 지원하고 있지 않는 브라우저조차, HTML의 호환성을 유지함과 동시에 HTML5의 규격 대로 기능이 지원되지 않더라도 신기능을 무시하는 것을 의미하는 표준 모드로 전환합니다.

+ +

이것은 이전의 doctype들 보다 훨씬 간단하고 짧으며, 기억하기 쉽고, 다운로드 받아야 하는 바이트의 양을 줄여줍니다.

+ +

<meta charset>으로 문자셋 정의하기

+ +

보통 문서의 처음에는 사용된 문자셋을 정의합니다. 이전 버전의 HTML에서는 매우 복잡한 {{HTMLElement("meta")}} 엘리먼트를 통해서 문자셋을 정의했습니다. 이제는 이렇게 간단해졌습니다.

+ +
<meta charset="UTF-8">
+ +

이것을 {{HTMLElement("head") }} 뒤에 가져다 놓으세요. 몇몇 브라우저는 HTML에 기대했던것과 다른 문자셋이 정의되어 있으면 문서를 다시 해석합니다. 또한, 여러분이 현재 다른 문자셋을 사용하고 있다면 UTF-8로 여러분 웹 페이지의 문자셋을 변경하는것을 추천합니다. 이것이 여러 스크립트를 사용한 문서의 문자 처리를 단순화시켜줍니다.

+ +

HTML5는 ASCII와 호환되며 적어도 8비트의 크기를 가지는 문자셋만을 지원합니다. 이렇게 함으로서 보안을 강화하고 특정형태의 공격을 방지할수 있습니다.

+ +

새로운 HTML5 해석기의 사용

+ +

HTML5에서는 마크업의 의미를 분석하는 해석 룰이 더 정확하게 정의 되었습니다. HTML5가 나오기 전까지는 단지 유효한 마크업의 의미만 정의되었기 때문에 마크업에 작은 에러라도 있을 때 문서를 어떻게 해석해야 할지는 정의되지 않았습니다. 결국 모든 브라우저가 서로 다르게 작동했습니다. 이제는 그렇지 않습니다. 이제 마크업에 에러가 있을 때는 모든 호환 브라우저가 똑같이 반응해야 합니다.

+ +

이 요구사항이 웹 개발자들의 삶을 꽤 편하게 해줍니다. 이제 모든 최신 브라우저가 HTML5의 해석 룰을 따르지만 HTML5-비호환 브라우저들도 여전히 사용되고 있습니다. 유효한 마크업을 사용하면 읽기 편하고 유지보수에 좋을 뿐 아니라, 여러 오래된 브라우저에서 호환되지 않을 가능성을 매우 줄여주기 때문에 이를 매우 추천합니다.

+ +

걱정하지 마세요 — 여러분 웹사이트를 손 댈 필요는 없습니다 — 웹브라우저 개발자들이 여러분을 위해 모두 준비해놓았습니다!

diff --git a/files/ko/web/guide/html/using_html_sections_and_outlines/index.html b/files/ko/web/guide/html/using_html_sections_and_outlines/index.html new file mode 100644 index 0000000000..87cae41ebd --- /dev/null +++ b/files/ko/web/guide/html/using_html_sections_and_outlines/index.html @@ -0,0 +1,367 @@ +--- +title: HTML 구획과 개요 사용하기 +slug: Web/HTML/HTML5_문서의_섹션과_윤곽 +tags: + - HTML + - HTML5 +translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines +--- +
{{HTMLSidebar}}
+ +
+

중요: 개요 알고리즘은 W3C의 최종 명세에 포함된 적이 없고, 브라우저와 보조 기술 중 알고리즘을 구현한 경우도 없습니다. 따라서 개요 알고리즘을 사용해 사용자에게 문서 구조를 나타내서는 안됩니다. 문서 작성자는 대신 제목 순위(h1-h6)를 사용해 문서 구조를 나타내는 것이 좋습니다.

+
+ +

HTML5 표준 명세서에서는 웹 개발자가 표준화된 의미론적 체계를 가지고 웹 문서의 구조를 표현할 수 있게 해주는 몇 개의 새로운 요소들을 선보였습니다. 이 문서에서는 이 새로운 요소들과 문서의 아웃라인을 의도한 대로 정의하는 법을 설명하고 있습니다.

+ +

예를 들면 <div>는 콘텐츠에 대한 어떠한 내용도 포함하지 않지만, <figcaption>은 콘텐츠에 어떤 내용을 포함하고 있는지를 명확하게 포함합니다.

+ +

새로운 의미론적 요소들은 HTML5에서 웹사이트의 내용을 구분하는 것을 향상시키기 위해 추가되었습니다. 개발자들은 표시된 목적 이외의 용도로 의미론적 요소를 사용하지 않도록 하는 것이 중요합니다.

+ +

HTML4에서의 문서 구조

+ +

문서의 구조, 즉 <body></body> 사이에 있는 것의 의미론적 구조는, 페이지 내용을 사용자에게 전달하는 데 중요한 토대가 됩니다. HTML4에선 일종의 섹션과 그 하위 섹션으로 구분하는 개념을 써서 문서의 구조를 표현합니다. 섹션은 HTML 구획({{HTMLElement("div")}})요소와 함께 그 안에 있는 제목을 정의하는 HTML 제목 요소({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, 혹은 {{HTMLElement("h6")}})를 써서 정의됩니다. 이런 HTML 구획 요소와 HTML 제목 요소의 관계가 문서의 구조와 그 아웃라인을 결정짓게 됩니다.

+ +

그래서 다음과 같은 마크업은:

+ +
<div class="section" id="forest-elephants">
+  <h1>둥근귀코끼리</h1>
+  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 대해 알아보겠습니다.
+  ...섹션 내용 진행 중...
+  <div class="subsection" id="forest-habitat">
+    <h2>서식지</h2>
+    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
+    ...하위 섹션 내용 진행 중...
+  </div>
+</div>
+ +

다음과 같은 문서 아웃라인을 가지게 됩니다:

+ +
1. 둥근귀코끼리
+   1.1 서식지
+
+ +

새로운 섹션을 정의할 때 {{HTMLElement("div")}} 요소가 꼭 필요한 것은 아닙니다. 단순히 HTML 제목 요소만 있으면 새로운 섹션이 시작됨을 자동으로 암시해 줍니다. 그래서,

+ +
<h1>둥근귀코끼리</h1>
+<p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 대해 알아보겠습니다.
+...섹션 내용 진행 중...
+<h2>서식지</h2>
+<p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
+...하위 섹션 내용 진행 중...
+<h2>먹이</h2>
+<h1>몽골 게르빌루스쥐</h1>
+ +

앞의 문서는 다음과 같은 아웃라인을 가지게 됩니다:

+ +
1. 둥근귀코끼리
+   1.1 서식지
+   1.2 먹이
+2. 몽골 게르빌루스쥐
+
+ +

HTML5에서 해결한 문제들

+ +

HTML4에서의 문서 구조에 대한 정의와 여기에 내포된 암묵적인 문서 알고리듬은 매우 투박해서 다음과 같은 많은 문제점을 가지고 있습니다:

+ +
    +
  1. 의미론적으로 섹션을 정의하는데 {{HTMLElement("div")}}을 사용하면, 특히나 class 속성에 어떠한 값도 지정하지 않았을 땐, 문서의 아웃라인을 파악하는 알고리듬을 자동화하는 것은 불가능합니다("사용된 {{HTMLElement("div")}}이 문서 아웃라인에 포함되는가, 만약 포함된다면 섹션인가 아니면 하위 섹션인가?" 혹은 "오로지 스타일 목적으로만 쓰인 표상적인 {{HTMLElement("div")}}일 뿐인가?"). 바꾸어 말하면, HTML4 표준 명세서에는 무엇이 섹션이고 어떻게 그 범위를 구분 짓는지에 대해 매우 모호하게 정의해 놓았습니다. 문서의 윤곽을 자동으로 생성하는 작업은 매우 중요하며, 특히나 보조 장비에 사용되는 기술에선 더욱 그러한데, 이를 이용해서 파악된 문서의 구조를 바탕으로 사용자에게 정보를 전달해 주게 된다는 것을 고려하면 그 중요성은 더욱 명확해집니다. HTML5에선 HTML 섹션 요소로 새롭게 {{HTMLElement("section")}} 요소를 도입하면서 문서 아웃라인 알고리듬에서 {{HTMLElement("div")}} 요소의 사용 필요성을 없애버렸습니다.
  2. +
  3. 여러 문서를 하나로 합치는 일은 복잡하고 어려운 일입니다: 주 문서에 어떤 하위 문서를 추가할 때 원래 문서의 아웃라인을 온전히 보전하려면 HTML 제목 요소의 계급을 고쳐야만 하는 일이 생깁니다. HTML5에서 새로 소개된 섹션을 구분 짓는 요소들({{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("nav")}} 그리?고 {{HTMLElement("aside")}})은, 내부에 포함된 제목 요소와 관계없이, 항상 그들이 속한 가장 가까운 상위 섹션의 바로 밑 하위 섹션으로 자리 잡게 되면서 이 문제를 해결하였습니다.
  4. +
  5. HTML4에선 모든 섹션이 문서 아웃라인에 영향을 주게 됩니다. 하지만 문서?가 언제나 그렇게 선형적이지만은 않지요. 문서에는 가령 광고 표시 문구를 담고 있는 구역이나 설명 문구를 담은 구획처럼 주 내용의 흐름에는 포함되진 않지만, 간접적으로 연관되는 정보를 가진 특별한 섹션이 포함될 수도 있습니다. HTML5에선 이렇게 문서의 주요 내용 윤곽에는 포함되지 않는 {{HTMLElement("aside")}} 요소가 소개되었습니다.
  6. +
  7. 반복되는 얘기지만, HTML4에선 모든 섹션이 문서의 아웃라인에 포함되기 때문에 로고나 메뉴, 문서의 목차, 혹은 저작권 정보나 법률적 고지처럼 특정 문서가 아닌 사이트 전체와 관련된 정보를 포함하는 섹션을 표현할 수가 없었습니다. 이러한 목적으로, HTML5에서 다음과 같은 세 가지 특수 목적의 섹션 요소를 소개하였습니다: 예를 들어 콘텐츠의 목차처럼 링크들의 모음을 감싸줄 때 쓰는 {{HTMLElement("nav")}} 그리고 사이트와 관련된 정보 표시를 위한 {{HTMLElement("footer")}}와 {{HTMLElement("header")}}가 있습니다.
  8. +
+ +

좀 더 포괄적으로 말하면 HTML5에선 문서를 구획하고 이들에게 제목을 부여하는 방법이 좀 더 세밀해지면서, 문서의 아웃라인 파악이 좀 더 예측 가능해지고 덩달아 이를 이용한 브라우저를 통해서 사용자 경험도 향상됩니다.

+ +

HTML5 문서 아웃라인 알고리즘

+ +

HTML이 섹션과 문서 아웃라인을 다루는 방식에 기반한 알고리즘을 생각해 보겠습니다.

+ +

HTML5에서의 섹션 정의

+ +

우선 {{HTMLElement("body")}} 요소 안에 배치된 콘텐츠는 모두 적어도 하나의 섹션 안에 포함되어 자리하게 됩니다. 그리고 HTML5에서 섹션은 서로 중첩되서 표시될 수도 있습니다. {{HTMLElement("body")}} 요소에 의해 정의된 주요 섹션을 제외하고, 모든 섹션은 명시적으로나 혹은 은연중 자동으로 구분되어 정의될 수 있습니다. 명시적으로 정의되는 섹션은 {{HTMLElement("body")}}, {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("footer")}}, {{HTMLElement("header")}}, 그리고 {{HTMLElement("nav")}} 태그들 안에 포함된 콘텐츠입니다.

+ +
각 섹션은 자기들만의 제목 계층을 가질 수 있습니다. 그래서, 중첩된 섹션이라도 {{HTMLElement("h1")}} 제목을 가질 수 있습니다. HTML5에서 제목 지정하는 법을 보십시오.
+ +

보기:

+ +
<section>
+  <h1>둥근귀코끼리</h1>
+  <section>
+    <h1>소개</h1>
+    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
+  </section>
+  <section>
+    <h1>서식지</h1>
+    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.</p>
+  </section>
+  <aside>
+    <p>광고 구역</p>
+  </aside>
+</section>
+<footer>
+  <p>(c) 2013 회사 이름</p>
+</footer>
+ +

위에 있는 HTML 코드에선 가장 윗 단계에 두 개의 섹션이 정의되었습니다:

+ +
<section>
+  <h1>둥근귀코끼리</h1>
+  <section>
+    <h1>소개</h1>
+    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
+  </section>
+  <section>
+    <h1>서식지</h1>
+    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.</p>
+  </section>
+  <aside>
+    <p>광고 구역</p>
+  </aside>
+</section>
+
+<footer>
+  <p>(c) 2013 회사 이름?</p>
+</footer>
+ +

첫 번째 섹션에선 세 개의 하위 섹션이 존재합니다:

+ +
<section>
+  <h1>둥근귀코끼리</h1>
+
+  <section>
+    <h1>소개</h1>
+    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
+  </section>
+
+  <section>
+    <h1>서식지</h1>
+    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.</p>
+  </section>
+
+  <aside>
+    <p>광고 구역</p>
+  </aside>
+</section>
+
+<footer>
+  <p>(c) 2013 회사 이름</p>
+</footer>
+ +

그래서 다음과 같은 구조를 가지게 됩니다:

+ +
1. 둥근귀코끼리
+   1.1 소개
+   1.2 서식지
+   1.3 광고 구역 (aside)
+
+ +

HTML5에서 제목 지정하는 법

+ +

비록 명시적 HTML 섹션 요소가 문서의 전체 구조를 정해주기는 하지만, 그 아웃라인을 좀 더 명확하게 표현하려면 제목의 사용도 중요합니다. 기본 규칙은 단순합니다: 처음 쓰인 HTML 제목 요소({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}} 중 하나)가 해당 섹션의 제목으로 정해집니다.

+ +

제목 요소엔 요소 이름에 붙은 숫자를 가지고 계급을 매기는데, {{HTMLElement("h1")}}이 최상위 계급이며 {{HTMLElement("h6")}}는 최하위 계급이 됩니다. 제목 간 계급의 상대적 등급은 오로지 같은 섹션 안에서만 중요해집니다; 이 말은 섹션의 구조가 문서의 아웃라인을 결정짓는 데 중요한 변수로 작용하지만, 섹션 안에서 사용된 제목의 계급은 여기에 아무런 관련이 없다는 얘기입니다. 예를 들어, 아래와 같은 코드를 살펴보면:

+ +
<section>
+  <h1>둥근귀코끼리</h1>
+  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
+    ...계속 된 섹션 내용...
+  <section>
+    <h2>서식지</h2>
+    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
+    ...계속 된 하위 섹션 내용...
+  </section>
+</section>
+<section>
+  <h3>몽골 게르빌루스쥐</h3>
+  <p>이번 섹션에선, 잘 알려진 몽골 게르빌루스쥐에 관해 알아보겠습니다.
+    ...계속 된 섹션 내용...
+</section>
+ +

이는 다음과 같은 아웃라인을 갖게 됩니다:

+ +
1. 둥근귀코끼리
+   1.1 서식지
+2. 몽골 게르빌루스쥐
+ +

여기서 쓰인 제목 요소의 계급(위 보기에선 처음 최상위 섹션의 {{HTMLElement("h1")}}, 그 하위 섹션의 {{HTMLElement("h2")}} 그리고 두 번째 최상위 섹션에서 사용된 {{HTMLElement("h3")}})은 중요하지 않다는 점을 주목하십시오. (명시적으로 정의된 섹션의 제목으로 어떠한 계급을 써도 상관은 없지만, 이 방식이 권장되는 것은 아닙니다.)

+ +

은연중 자동으로 정의되는 섹션

+ +

HTML5에서 소개된 명시적 섹션 요소들만이 문서의 아웃라인을 정의하는 데 절대적으로 필요한 요소는 아니므로, 기존 웹에서 지배적으로 사용되는 HTML4와의 호환성을 지키려는 노력의 일환으로, 이들 없이도 섹션을 정의하는 또 하나의 방법이 있습니다. 이를 은연중 자동으로 정의되는 섹션이라 하겠습니다.

+ +

HTML 제목 요소({{HTMLElement("h1")}}부터 {{HTMLElement("h6")}})는 만약에 그들이 속한 상위 명시적 섹션의 첫 번째 제목으로 사용되지 않았다면, 자동으로 또 하나의 새로운 암묵적인 섹션으로 분류/정의되어 집니다. 이들 암묵적 섹션이 문서 아웃라인에서 위치하게 되는 기준은 기존 이들 제목을 포함하고 있는 상위 섹션에서 사용된 제목과의 상대적 계급에 따라 결정됩니다. 만약 전에 사용된 제목보다 계급이 더 낮다면, 은연중으로 해당 섹션의 하위 섹션으로 자리 잡게 됩니다. 아래 코드를 살펴보면:

+ +
<section>
+  <h1>둥근귀코끼리</h1>
+  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
+    ...섹션 내용 진행 중...
+  <h3 class="implicit subsection">서식지</h3>
+  <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
+    ...하위 섹션 내용 진행 중...
+</section>
+ +

이는 다음과 같은 문서 아웃라인을 갖게 됩니다:

+ +
1. 둥근귀코끼리
+   1.1 서식지 (h3 요소에 의해 은연중 자동으로 정의됨)
+
+ +

만약에 이전에 사용된 제목과 같은 계급이라면, (명시적으로 정의되었을 수도 있지요!) 바로 이전 섹션과 구분되면서 같은 계급의 또 하나의 새로운 암묵적 섹션으로 자리하게 됩니다:

+ +
<section>
+  <h1>둥근귀코끼리</h1>
+  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
+    ...섹션 내용 진행 중...
+  <h1 class="implicit section">몽골 게르빌루스쥐</h1>
+  <p>몽골 게르빌루스쥐는 귀엽고 작은 포유 동물입니다.
+    ...섹션 내용 진행 중...
+</section>
+ +

위 코드는 다음과 같은 문서 아웃라인을 갖게 됩니다:

+ +
1. 둥근귀코끼리
+2. 몽골 게르빌루스쥐 (h1 요소에 의해 자동으로 정의됨과 동시에 이전 섹션과 구분되어 짐)
+
+ +

만약에 이전에 사용된 제목보다 더 높은 계급의 제목이 사용되었다면, 이전 섹션과 구분되면서 더 높은 제목의 계급을 가진 또 하나의 새로운 암묵적 섹션으로 자리하게 됩니다:

+ +
<body>
+  <h1>포유 동물</h1>
+  <h2>고래</h2>
+  <p>이번 섹션에선, 유영하는 고래에 관해 알아보겠습니다.
+    ...섹션 내용 진행 중...
+  <section>
+    <h3>둥근귀코끼리</h3>
+    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
+      ...섹션 내용 진행 중...
+    <h3>몽골 게르빌루스쥐</h3>
+      <p>몽골 게르빌루스쥐의 무리는 몽골을 훨씬 벗어나는 구역까지 퍼져있습니다.
+         ...하위 섹션 내용 진행 중...
+    <h2>파충류</h2>
+      <p>파충류는 냉혈 동물입니다.
+          ...하위 섹션 내용 진행 중...
+  </section>
+</body>
+ +

위 코드는 다음과 같은 문서 아웃라인을 갖게 됩니다:

+ +
1. 포유 동물
+   1.1 고래 (h2 요소에 의해 자동으로 정의됨)
+   1.2 둥근귀코끼리 (섹션 요소에 의해 명시적으로 정의됨)
+   1.3 몽골 게르빌루스쥐 (h3 요소에 의해 자동으로 정의됨과 동시에 이전 섹션과 구분되어 짐)
+2. 파충류 (h2 요소에 의해 자동으로 정의됨과 동시에 이전 섹션과 구분되어 짐)
+ +

단순히 써진 제목의 태그들만 살펴본다면, 이것은 결코 예상했던 문서의 아웃라인은 아닐 것입니다. 그래서 작성한 마크업이 다른 사람에게도 쉽게 이해되도록 하려면, 섹션을 구분할 때 명시적 섹션 요소의 태그들을 쓰는 것이 바람직하며, 원래 의도하는 섹션의 중첩 수준을 고려해서 그에 어울리는 제목의 계급을 써야 합니다. 그런데 이것이 꼭 HTML5 명세서에서 요구하는 필수 준수 사항은 아닙니다. 만약에 작성한 문서의 아웃라인을 브라우저가 원래 의도한 방향으로 표시해 주지 못한다면, 혹시 사용한 제목 요소가 은연중 자동으로 기존 섹션과 구분되게 사용되었는지 확인해 보시기 바랍니다.

+ +

제목의 계급은 항상 해당 섹션의 중첩 수준과 일치하도록 쓰라는 규칙의 예외도 있을 수 있는데, 그 중 하나 여러 문서에서 공통으로 재사용되는 섹션의 경우가 있습니다. 예를 들면, 섹션 내용이 어떤 콘텐츠 관리 시스템에 저장되어 실시간으로 여러 다른 저장된 내용과 함께 조합되어 문서에 표시될 때가 있습니다. 이 경우엔, 재사용되는 섹션의 가장 최상위 제목으로 {{HTMLElement("h1")}}부터 시작해서 사용하실 것을 권장합니다. 그러면 재사용되는 섹션의 중첩 수준은 문서의 섹션 계층 중 해당 섹션이 삽입되어 보이는 위치에 따라 자동으로 결정될 것입니다. 이 경우에도 명시적 섹션 태그가 문서 아웃라인을 명확히 하는 데 도움을 줍니다.

+ +

섹션 구분의 근원점

+ +

섹션 구분의 근원점은 HTML 요소 중 자기만의 아웃라인을 가질 수는 있지만, 그 안의 섹션이나 제목이 자기 위에 있는 요소의 아웃라인에는 어떠한 영향도 끼치지 않는 것들을 가리킵니다. 논리적으로 따지면 당연히 문서의 섹션을 구분하는데 그 근본이 되는 {{HTMLElement("body")}}가 여기에 포함되고, 이 외에도 종종 외부 콘텐츠를 페이지에 표시하는 데 사용되는 다음과 같은 요소들도 있습니다: {{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} 마지막으로 {{HTMLElement("td")}}.

+ +

보기:

+ +
<section>
+  <h1>숲 코끼리</h1>
+  <section>
+    <h2>소개</h2>
+    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
+  </section>
+  <section>
+    <h2>서식지</h2>
+    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
+      과학자들은 "<cite>보르네오 섬의 둥근귀코끼리</cite>"라는 제목의 책에서 다음과 같이 서술하고 있습니다:</p>
+    <blockquote>
+       <h1>보르네오 섬</h1>
+       <p>보르네오 섬에 서식하는 둥근귀코끼리...</p>
+    </blockquote>
+  </section>
+</section>
+
+ +

위의 보기에선 다음과 같은 문서 아웃라인을 가지게 됩니다:

+ +
1. 숲 코끼리
+   1.1 소개
+   1.2 서식지
+ +

이 문서의 아웃라인을 살펴보면 외부 인용 문구로 사용된 {{HTMLElement("blockquote")}} 요소의 경우, 섹션 구분의 근원이 되는 요소 중 하나로서 자기가 포함하고 있는 내부 내용의 아웃라인이 외부의 것과 완전히 차단되면서, 전체 문서의 아웃라인에는 포함되지 않았습니다.

+ +

문서의 아웃라인 밖에 존재하는 섹션

+ +

HTML5에선 웹 문서의 주요 아웃라인에 속하지 않는 섹션을 정의할 수 있도록 하는 새로운 네 가지의 요소들을 소개하고 있습니다:

+ +
    +
  1. HTML Aside 섹션 요소({{HTMLElement("aside")}})는 주요 문맥을 담은 요소와 어떤 관련성을 지니고 있지만, 어떤 부연 설명 표시 영역이나 광고처럼 문맥의 주요 흐름 줄기엔 속하지 않는 섹션을 나타냅니다. 물론 자기만의 아웃라인을 가지고 있어서, 문서의 주요 아웃라인엔 포함되지 않습니다.
  2. +
  3. HTML Navigational 섹션 요소({{HTMLElement("nav")}})는 내비게이션 링크들을 포함하고 있는 섹션입니다. 이런 링크들은 문서에 여러 개가 있을 수 있는데, 예를 들어, 콘텐츠 목차와 같은 페이지 내부 링크나 사이트의 내비게이션 링크가 있습니다. 이런 링크는 문서의 주요 문맥과 아웃라인에 포함되지 않아서 보통 처음에는 스크린 리더나 비슷한 보조 기술을 사용하는 장치에서 읽어드리지 않을 수도 있습니다.
  4. +
  5. HTML Header 섹션 요소({{HTMLElement("header")}})는 페이지의 도입부로서 보통 로고나 사이트 이름 그리고 수평 메뉴를 포함하고 있습니다. 이름에서 풍기는 느낌과는 달리 꼭 페이지 처음에 있을 필요는 없습니다.
  6. +
  7. HTML Footer 섹션 요소({{HTMLElement("footer")}})는 페이지의 종결부로서 보통 저작권이나 법률적 고지 혹은 약간의 링크들을 포함하고 있습니다. 이것도 역시 이름이 가진 직설적 의미와 달리 페이지 끝에 있을 필요는 없습니다.
  8. +
+ +

섹션을 구분짓는 요소의 주소와 발행 시간

+ +

문서를 작성하다 보면 종종 저자의 이름이나 주소와 같은 연락 정보를 공개하고 싶을 때가 있습니다. HTML4에선 이런 목적으로 {{HTMLElement("address")}} 요소가 쓰였는데, HTML5에선 여기에 더 보완된 내용이 추가되었습니다.

+ +

가끔 문서에는 여러 명의 저자가 작성한 여러 개의 섹션이 포함되어 있을 수도 있습니다. 메인 페이지의 저자와 다른 또 다른 사람?이 작성한 콘텐츠가 포함된 섹션은 {{HTMLElement("article")}} 요소를 써서 정의합니다. 이렇게 하면, {{HTMLElement("address")}} 요소는 지정?된 위치에 따라 가장 가까운 상위의 {{HTMLElement("body")}} 혹은 {{HTMLElement("article")}}과 연관된 정보로 표시됩니다.

+ +

비슷하게, HTML5의 새 {{HTMLElement("time")}} 요소에 pubdate boolean 속성이 지정되었다면 문서 전체의 발행 날짜를 표시해 주는데, article에서처럼, 가장 가까운 상위의 {{HTMLElement("body")}} 혹은 {{HTMLElement("article")}} 과 연관된 정보로 표시됩니다.

+ +

HTML5 미지원 브라우저에서 HTML5 요소를 사용하는 법

+ +

섹션과 제목 요소들은 대부분의 HTML5 미지원 브라우저에서도 정상적으로 사용하실 수 있습니다. 지원하진 않더라도, 어떤 특별한 DOM 인터페이스가 필요한 것은 아니고 단지 인식하지 못하는 요소는 기본적으로 display:inline 으로 표시되기 때문에 다음과 같이 특별한 CSS 스타일을 지정해 주어야 합니다:

+ +
section, article, aside, footer, header, nav, hgroup {
+  display:block;
+}
+
+ +

물론 웹 개발자가 이들의 스타일을 달리 표시해 줄 수도 있는데, HTML5 미지원 브라우저에선 해당 요소들의 기본 표시 스타일이 원래의 정상적인 것과 다르다는 점을 명심해야 합니다. 또한, 여기엔 {{HTMLElement("time")}} 요소가 포함되지 않았는데, 그 이유는 기본 스타일이 HTML5 미지원 브라우저의 것과 HTML5 호환 브라우저의 것과 서로 같기 때문입니다.

+ +
그런데 이 방법도 약간의 제약이 있어서, 어떤 브라우저에선 지원하지 않은 요소의 스타일을 애초에 지정할 수도 없게 되어 있습니다. Internet Explorer(버전 8 이하)가 여기에 해당하는데, 제대로 스타일을 지정해 주려면 다음과 같은 스크립트가 필요합니다:
+ +
<!--[if lt IE 9]>
+  <script>
+    document.createElement("header" );
+    document.createElement("footer" );
+    document.createElement("section");
+    document.createElement("aside"  );
+    document.createElement("nav"    );
+    document.createElement("article");
+    document.createElement("hgroup" );
+    document.createElement("time"   );
+  </script>
+<![endif]-->
+ +

이 스크립트가 하는 일은, Internet Explorer(8 혹은 그 이하)일 경우, HTML5의 섹션 요소와 제목 요소가 제대로 표시될 수 있도록 실행됩니다. 여기에 언급된 요소들은 전체 페이지의 구조를 정의하는 데 필요한 아주 중요한 요소이기 때문에, 만약에 스크립트의 힘을 빌리지 않다면 표시조차 되지 않게 되면서 문제 될 수 있습니다. 그래서 이런 때를 대비해서 명시적으로 다음과 같은 {{HTMLElement("noscript")}} 요소도 추가되어야 합니다:

+ +
<noscript>
+   <strong>주의 !</strong>
+   귀하가 사용하고 계신 브라우저는 HTML5를 지원하고 있지 않아서, 할 수 없이 JScript를 써서 몇몇 요소가 제대로 보이도록 구현했습니다.
+   그런데 안타깝게도 귀하의 브라우저에선 스크립트 기능이 꺼져있습니다. 이 페이지가 제대로 표시되려면 스크립트 기능을 켜주셔야만 합니다.
+</noscript>
+ +

그래서 결국, Internet Explorer(8 혹은 그 이하)처럼 HTML5 미지원 브라우저에서도 HTML5의 섹션과 제목 요소를 제대로 지원하도록 하고, 또 만약을 대비해 이런 미지원 브라우저에서 스크립팅 기능이 꺼져있을 때를 대비해서 다음과 같은 코드를 추가해 줘야 합니다:

+ +
<!--[if lt IE 9]>
+  <script>
+    document.createElement("header" );
+    document.createElement("footer" );
+    document.createElement("section");
+    document.createElement("aside"  );
+    document.createElement("nav"    );
+    document.createElement("article");
+    document.createElement("hgroup" );
+    document.createElement("time"   );
+  </script>
+  <noscript>
+     <strong>주의 !</strong>
+     귀하가 사용하고 계신 브라우저는 HTML5를 지원하고 있지 않아서, 할 수 없이 JScript를 써서 몇몇 요소가 제대로 보이도록 구현했습니다.
+     그런데 안타깝게도 귀하의 브라우저에선 스크리트 기능이 꺼져있습니다. 이 페이지가 제대로 표시되려면 스크립트 기능을 켜주셔야만 합니다.
+   </noscript>
+<![endif]-->
+
+ +

맺음말

+ +

HTML5에서 소개된 새로운 섹션과 제목 요소는 웹 문서의 구조와 아웃라인을 표준화된 방법으로 작성할 수 있게 도와줍니다. 또한, HTML5를 지원하는 브라우저 사용자나 페이지 내용을 제대로 전달하는데 그 구조 파악이 중요한, 예를 들어 보조 지원 기술의 도움으로 페이지의 내용을 파악하는, 사용자 모두에게 커다란 이득을 안겨다 줍니다. 새로 소개된 의미가 담긴 요소들은, 약간의 노력만 기울인다면, 사용이 간편해서 HTML5 미지원 브라우저에서도 온전히 사용하실 수 있습니다. 그러므로 아무런 제약 없이 마음 놓고 사용하시기 바랍니다.

diff --git a/files/ko/web/guide/parsing_and_serializing_xml/index.html b/files/ko/web/guide/parsing_and_serializing_xml/index.html new file mode 100644 index 0000000000..872dfffaa3 --- /dev/null +++ b/files/ko/web/guide/parsing_and_serializing_xml/index.html @@ -0,0 +1,141 @@ +--- +title: XML 파싱 및 직렬화 +slug: Web/Guide/XML_파싱_및_직렬화 +tags: + - AJAX + - Add-ons + - DOM + - Extensions + - JSON + - JXON + - XML + - XMLHttpRequest + - 가이드 +translation_of: Web/Guide/Parsing_and_serializing_XML +--- +

웹 상에서 XML을 파싱하고 직렬화할 때 사용할 수 있는 객체는 다음과 같습니다.

+ +
    +
  • DOM 트리를 문자열로 직렬화하는 XMLSerializer
  • +
  • XML 문서 상의 각기 다른 부분들을 (비 XML 문법을 사용하여) 문자열로 직렬화하는 XPath
  • +
  • XML을 파싱하여 문자열을 DOM 트리로 변환하는 DOMParser
  • +
  • URL을 사용하여 주소화 가능한(URL-addressable) 리소스를 DOM 트리로 파싱하는 XMLHttpRequest
  • +
+ +

Part 1: XML 문서 생성법

+ +

XML 문서 생성법은 다음과 같습니다. (XML 문서는 Document의 인스턴스 입니다.)

+ +

문자열을 DOM 트리로 파싱

+ +
+
var sMyString = '<a id="a"><b id="b">hey!</b></a>';
+var oParser = new DOMParser();
+var oDOM = oParser.parseFromString(sMyString, "text/xml");
+// 루트 요소의 이름, 또는 에러 메시지를 출력합니다.
+dump(oDOM.documentElement.nodeName == "parsererror" ? "error while parsing" : oDOM.documentElement.nodeName);
+
+
+ +

자바스크립트 객체 트리를 시작점으로 하여 XML 문서를 생성(JXON)

+ +

JXON 역(reverse) 알고리즘을 참고하세요.

+ +

URL 주소화 가능한(URL-addressable) 리소스를 DOM 트리로 파싱

+ +

XMLHttpRequest를 사용합니다

+ +

다음은 URL 주소화 가능한 XML 파일을 DOM 트리로 읽어들인 후 파싱하는 예시 코드입니다.

+ +
var xhr = new XMLHttpRequest();
+xhr.onload = function() {
+  dump(xhr.responseXML.documentElement.nodeName);
+}
+xhr.onerror = function() {
+  dump("Error while getting XML.");
+}
+xhr.open("GET", "example.xml");
+xhr.responseType = "document";
+xhr.send();
+
+ +

xhr.responseXML는 {{domxref("Document")}}의 인스턴스입니다.

+ +

Part 2: 특정 XML 문서의 콘텐츠를 직렬화하는 방법

+ +

Part 1에서 생성한 XML 문서의 콘텐츠를 직렬화할 수 있는 방법은 다음과 같습니다.

+ +

DOM 트리를 문자열로 직렬화

+ +

제일 먼저 DOM 트리 생성법에 나와 있는 대로 DOM 트리를 생성합니다. 다른 방법으로는 {{ domxref("XMLHttpRequest") }}에서 얻어낸 DOM 트리를 사용하는 방법이 있습니다.

+ +

이제 doc(DOM 트리)를 문자열로 직렬화 해 봅시다.

+ +
var oSerializer = new XMLSerializer();
+var sXML = oSerializer.serializeToString(doc);
+ +

new XMLSerializer() 생성자는 JS XPCOM 컴포넌트(혹은 JS module) 내에서는 사용이 불가능합니다. 대신, 다음과 같은 코드를 작성하세요.

+ +
var oSerializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
+                            .createInstance(Components.interfaces.nsIDOMSerializer);
+var sXML = oSerializer.serializeToString(doc);
+
+ +

DOM 트리를 문자열로 "예쁘게(pretty)" 직렬화

+ +

XMLSerializer E4X를 사용하면 DOM 트리를 예쁘게 출력(pretty print) 할 수 있습니다. 우선, DOM 트리 생성법 글을 참고하여 DOM 트리를 생성합니다. 혹은 {{ domxref("XMLHttpRequest") }}를 통해 DOM 트리를 뽑아내는 방법도 있습니다. 아래 코드에서 변수 doc는 DOM 트리를 가지고 있습니다.

+ +
var oSerializer = new XMLSerializer();
+var sPrettyXML = XML(oSerializer.serializeToString(doc)).toXMLString();
+ +

들여쓰기는 두 번 스페이스가 들어간 것과 같게 되어 있습니다. 좀 더 효율적인 코드를 작성하거나 들여쓰기 문자열을 임의로 설정하고 싶다면 {{ domxref("treeWalker") }}를 사용하십시오.

+ +
Note: E4X toXMLString 메소드를 쓴다면, CDATA 요소가 없어지거나, 요소 안에 담긴 텍스트만 남을 수 있습니다. 그러므로 만약 XML 내에 CDATA 요소가 들어 있다면, 위에 나온 메소드는 그다지 유용하지 않을 수도 있습니다.
+ +
<content><![CDATA[This is the content]]></content>
+
+ +

위의 코드는 다음과 같이 변환됩니다.

+ +
<content>This is the content</content>
+ +

DOM 트리를 자바스크립트 객체 트리로 직렬화 (JXON)

+ +

JXON (lossless JavaScript XML Object Notation, 무손실 자바스크립트 XML 객체 표기법)은 XML을 사용하여 자바스크립트 객체를 표현하는 방법입니다. XML 문서의 일부분만 나오게 하고 싶다면, 문서 전체를 JSON으로 변환하지 말고 XPath를 사용하세요! 이 외의 상황이라면 JSON에 관한 글을 참조하세요.

+ +

DOM 트리를 파일로 직렬화

+ +

먼저, DOM 트리 생성법 글에 나와 있는 대로 DOM 트리를 생성하세요. 만약 {{ domxref("XMLHttpRequest") }}를 사용하여 이미 DOM 트리가 존재한다면 이 절의 마지막 부분으로 건너 뛰십시오.

+ +

이제 DOM 트리인 doc를 파일로 직렬화 해봅시다. 파일에 대해 더 알아보고 싶다면, 모질라에서 파일 사용과 관련하여를 참조하세요.

+ +
var oFOStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+var oFile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsILocalFile); // get profile folder
+oFile.append("extensions"); // extensions sub-directory
+oFile.append("{5872365E-67D1-4AFD-9480-FD293BEBD20D}"); // GUID of your extension
+oFile.append("myXMLFile.xml"); // filename
+oFOStream.init(oFile, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
+(new XMLSerializer()).serializeToStream(doc, oFOStream, ""); // rememeber, doc is the DOM tree
+oFOStream.close();
+
+ +

XMLHttpRequest 객체를 파일로 직렬화

+ +

이미 {{ domxref("XMLHttpRequest") }}를 사용하여 DOM 트리를 보유한 상태라면, 위의 코드를 사용하되 serializer.serializeToStream(doc, oFOStream, "") 부분을 serializer.serializeToStream(xmlHttpRequest.responseXML.documentElement, oFOStream, "")로 대체하십시오. xmlHttpRequest은 XMLHttpRequest의 인스턴스입니다.

+ +

위 코드는 서버에서 XML을 찾아낸 후 문자열 스트림으로 재직렬화(re-serialize)한다는 것을 알아두세요. 필요에 따라 xmlHttpRequest.responseText를 곧장 건너뛸 수 있습니다.

+ +

HTML 문서를 직렬화

+ +

만약 보유한 DOM이 HTML 문서라면 다음과 같이 간단하게 직렬화할 수 있습니다.

+ +
var serialized = document.documentElement.innerHTML;
+
+ +

참고 자료

+ + diff --git "a/files/ko/web/guide/xml_\355\214\214\354\213\261_\353\260\217_\354\247\201\353\240\254\355\231\224/index.html" "b/files/ko/web/guide/xml_\355\214\214\354\213\261_\353\260\217_\354\247\201\353\240\254\355\231\224/index.html" deleted file mode 100644 index 872dfffaa3..0000000000 --- "a/files/ko/web/guide/xml_\355\214\214\354\213\261_\353\260\217_\354\247\201\353\240\254\355\231\224/index.html" +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: XML 파싱 및 직렬화 -slug: Web/Guide/XML_파싱_및_직렬화 -tags: - - AJAX - - Add-ons - - DOM - - Extensions - - JSON - - JXON - - XML - - XMLHttpRequest - - 가이드 -translation_of: Web/Guide/Parsing_and_serializing_XML ---- -

웹 상에서 XML을 파싱하고 직렬화할 때 사용할 수 있는 객체는 다음과 같습니다.

- -
    -
  • DOM 트리를 문자열로 직렬화하는 XMLSerializer
  • -
  • XML 문서 상의 각기 다른 부분들을 (비 XML 문법을 사용하여) 문자열로 직렬화하는 XPath
  • -
  • XML을 파싱하여 문자열을 DOM 트리로 변환하는 DOMParser
  • -
  • URL을 사용하여 주소화 가능한(URL-addressable) 리소스를 DOM 트리로 파싱하는 XMLHttpRequest
  • -
- -

Part 1: XML 문서 생성법

- -

XML 문서 생성법은 다음과 같습니다. (XML 문서는 Document의 인스턴스 입니다.)

- -

문자열을 DOM 트리로 파싱

- -
-
var sMyString = '<a id="a"><b id="b">hey!</b></a>';
-var oParser = new DOMParser();
-var oDOM = oParser.parseFromString(sMyString, "text/xml");
-// 루트 요소의 이름, 또는 에러 메시지를 출력합니다.
-dump(oDOM.documentElement.nodeName == "parsererror" ? "error while parsing" : oDOM.documentElement.nodeName);
-
-
- -

자바스크립트 객체 트리를 시작점으로 하여 XML 문서를 생성(JXON)

- -

JXON 역(reverse) 알고리즘을 참고하세요.

- -

URL 주소화 가능한(URL-addressable) 리소스를 DOM 트리로 파싱

- -

XMLHttpRequest를 사용합니다

- -

다음은 URL 주소화 가능한 XML 파일을 DOM 트리로 읽어들인 후 파싱하는 예시 코드입니다.

- -
var xhr = new XMLHttpRequest();
-xhr.onload = function() {
-  dump(xhr.responseXML.documentElement.nodeName);
-}
-xhr.onerror = function() {
-  dump("Error while getting XML.");
-}
-xhr.open("GET", "example.xml");
-xhr.responseType = "document";
-xhr.send();
-
- -

xhr.responseXML는 {{domxref("Document")}}의 인스턴스입니다.

- -

Part 2: 특정 XML 문서의 콘텐츠를 직렬화하는 방법

- -

Part 1에서 생성한 XML 문서의 콘텐츠를 직렬화할 수 있는 방법은 다음과 같습니다.

- -

DOM 트리를 문자열로 직렬화

- -

제일 먼저 DOM 트리 생성법에 나와 있는 대로 DOM 트리를 생성합니다. 다른 방법으로는 {{ domxref("XMLHttpRequest") }}에서 얻어낸 DOM 트리를 사용하는 방법이 있습니다.

- -

이제 doc(DOM 트리)를 문자열로 직렬화 해 봅시다.

- -
var oSerializer = new XMLSerializer();
-var sXML = oSerializer.serializeToString(doc);
- -

new XMLSerializer() 생성자는 JS XPCOM 컴포넌트(혹은 JS module) 내에서는 사용이 불가능합니다. 대신, 다음과 같은 코드를 작성하세요.

- -
var oSerializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
-                            .createInstance(Components.interfaces.nsIDOMSerializer);
-var sXML = oSerializer.serializeToString(doc);
-
- -

DOM 트리를 문자열로 "예쁘게(pretty)" 직렬화

- -

XMLSerializer E4X를 사용하면 DOM 트리를 예쁘게 출력(pretty print) 할 수 있습니다. 우선, DOM 트리 생성법 글을 참고하여 DOM 트리를 생성합니다. 혹은 {{ domxref("XMLHttpRequest") }}를 통해 DOM 트리를 뽑아내는 방법도 있습니다. 아래 코드에서 변수 doc는 DOM 트리를 가지고 있습니다.

- -
var oSerializer = new XMLSerializer();
-var sPrettyXML = XML(oSerializer.serializeToString(doc)).toXMLString();
- -

들여쓰기는 두 번 스페이스가 들어간 것과 같게 되어 있습니다. 좀 더 효율적인 코드를 작성하거나 들여쓰기 문자열을 임의로 설정하고 싶다면 {{ domxref("treeWalker") }}를 사용하십시오.

- -
Note: E4X toXMLString 메소드를 쓴다면, CDATA 요소가 없어지거나, 요소 안에 담긴 텍스트만 남을 수 있습니다. 그러므로 만약 XML 내에 CDATA 요소가 들어 있다면, 위에 나온 메소드는 그다지 유용하지 않을 수도 있습니다.
- -
<content><![CDATA[This is the content]]></content>
-
- -

위의 코드는 다음과 같이 변환됩니다.

- -
<content>This is the content</content>
- -

DOM 트리를 자바스크립트 객체 트리로 직렬화 (JXON)

- -

JXON (lossless JavaScript XML Object Notation, 무손실 자바스크립트 XML 객체 표기법)은 XML을 사용하여 자바스크립트 객체를 표현하는 방법입니다. XML 문서의 일부분만 나오게 하고 싶다면, 문서 전체를 JSON으로 변환하지 말고 XPath를 사용하세요! 이 외의 상황이라면 JSON에 관한 글을 참조하세요.

- -

DOM 트리를 파일로 직렬화

- -

먼저, DOM 트리 생성법 글에 나와 있는 대로 DOM 트리를 생성하세요. 만약 {{ domxref("XMLHttpRequest") }}를 사용하여 이미 DOM 트리가 존재한다면 이 절의 마지막 부분으로 건너 뛰십시오.

- -

이제 DOM 트리인 doc를 파일로 직렬화 해봅시다. 파일에 대해 더 알아보고 싶다면, 모질라에서 파일 사용과 관련하여를 참조하세요.

- -
var oFOStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
-var oFile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsILocalFile); // get profile folder
-oFile.append("extensions"); // extensions sub-directory
-oFile.append("{5872365E-67D1-4AFD-9480-FD293BEBD20D}"); // GUID of your extension
-oFile.append("myXMLFile.xml"); // filename
-oFOStream.init(oFile, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
-(new XMLSerializer()).serializeToStream(doc, oFOStream, ""); // rememeber, doc is the DOM tree
-oFOStream.close();
-
- -

XMLHttpRequest 객체를 파일로 직렬화

- -

이미 {{ domxref("XMLHttpRequest") }}를 사용하여 DOM 트리를 보유한 상태라면, 위의 코드를 사용하되 serializer.serializeToStream(doc, oFOStream, "") 부분을 serializer.serializeToStream(xmlHttpRequest.responseXML.documentElement, oFOStream, "")로 대체하십시오. xmlHttpRequest은 XMLHttpRequest의 인스턴스입니다.

- -

위 코드는 서버에서 XML을 찾아낸 후 문자열 스트림으로 재직렬화(re-serialize)한다는 것을 알아두세요. 필요에 따라 xmlHttpRequest.responseText를 곧장 건너뛸 수 있습니다.

- -

HTML 문서를 직렬화

- -

만약 보유한 DOM이 HTML 문서라면 다음과 같이 간단하게 직렬화할 수 있습니다.

- -
var serialized = document.documentElement.innerHTML;
-
- -

참고 자료

- - diff --git "a/files/ko/web/guide/\352\267\270\353\236\230\355\224\275/index.html" "b/files/ko/web/guide/\352\267\270\353\236\230\355\224\275/index.html" deleted file mode 100644 index cb7cd6f873..0000000000 --- "a/files/ko/web/guide/\352\267\270\353\236\230\355\224\275/index.html" +++ /dev/null @@ -1,48 +0,0 @@ ---- -title: 웹 상 그래픽 -slug: Web/Guide/그래픽 -tags: - - 2D - - 3D - - Canvas - - Graphics - - HTML5 - - SVG - - WebGL - - WebRTC -translation_of: Web/Guide/Graphics ---- -

웹 사이트 및 응용 프로그램은 종종 그래픽을 보일 필요가 있습니다. 정지 이미지는 {{HTMLElement("img")}} 요소 사용이나 {{cssxref("background-image")}} 속성을 사용한 HTML 요소의 배경 설정으로 쉽게 표시할 수 있습니다. 또한 그래픽을 그때그때 생성하거나 사후에 이미지를 조작할 수도 있습니다. 여기서는 이를 수행할 수 있는 법을 주의 깊게 살펴봅니다.

- -
-
-

2D 그래픽

- -
-
Canvas
-
{{HTMLElement("canvas")}} 요소는 JavaScript를 사용하여 2D 그래픽을 그리는 API를 제공합니다.
-
SVG
-
Scalable Vector Graphics (SVG)는 그래픽을 묘사하기 위해 선, 곡선 및 그 밖의 기하학 도형을 사용할 수 있습니다. 벡터로, 어떤 크기로든 깔끔하게 크기 조정하는 이미지를 만들 수 있습니다.
-
- -

모두 보기...

-
- -
-

3D 그래픽

- -
-
WebGL
-
웹을 위한 3D 그래픽인 WebGL 시작 안내서. 이 기술로 웹 콘텐츠에 표준 OpenGL ES를 사용할 수 있습니다.
-
- -

비디오

- -
-
HTML5 audio 및 video 사용
-
웹 페이지 내 비디오 및/또는 오디오 삽입 및 그 재생 제어.
-
WebRTC
-
WebRTC에서 RTC는 실시간 통신(Real-Time Communications)을 뜻하며, 오디오/비디오 스트리밍 및 브라우저 클라이언트(peer) 간 데이터 공유를 가능하게 하는 기술입니다.
-
-
-
diff --git a/files/ko/web/html/canvas/index.html b/files/ko/web/html/canvas/index.html deleted file mode 100644 index bbe466e58d..0000000000 --- a/files/ko/web/html/canvas/index.html +++ /dev/null @@ -1,135 +0,0 @@ ---- -title: Canvas API -slug: Web/HTML/Canvas -tags: - - API - - Canvas - - JavaScript - - 개요 - - 레퍼런스 -translation_of: Web/API/Canvas_API ---- -
{{CanvasSidebar}}
- -

Canvas API는 JavaScript와 HTML {{HtmlElement("canvas")}} 엘리먼트를 통해 그래픽을 그리기위한 수단을 제공합니다. 무엇보다도 애니메이션, 게임 그래픽, 데이터 시각화, 사진 조작 및 실시간 비디오 처리를 위해 사용됩니다.

- -

Canvas API는 주로 2D 그래픽에 중점을 두고 있습니다. WebGL API 또한 <canvas> 엘리먼트를 사용하며, 하드웨어 가속 2D 및 3D 그래픽을 그립니다.

- -

기본 예시

- -

canvas에 초록색 사각형을 그리는 간단한 예시입니다.

- -

HTML

- -
<canvas id="canvas"></canvas>
-
- -

JavaScript

- -

{{domxref("Document.getElementById()")}} 메소드는 HTML <canvas> 엘리먼트에 대한 참조를 얻습니다. 그 다음, {{domxref("HTMLCanvasElement.getContext()")}} 메소드는 엘리먼트의 컨텍스트(렌더링될 그리기의 대상)를 얻습니다.

- -

실제 그리기는 {{domxref("CanvasRenderingContext2D")}} 인터페이스를 사용해 수행됩니다. {{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle")}} 프로퍼티는 사각형을 초록색으로 만듭니다. {{domxref("CanvasRenderingContext2D.fillRect()", "fillRect()")}} 메소드는 좌측 상단 코너를 (10, 10) 위치에 놓으며, 너비를 150, 높이를 100으로 지정합니다.

- -
const canvas = document.getElementById('canvas');
-const ctx = canvas.getContext('2d');
-
-ctx.fillStyle = 'green';
-ctx.fillRect(10, 10, 150, 100);
-
- -

결과

- -

{{ EmbedLiveSample('기본_예시', 700, 180) }}

- -

레퍼런스

- -
-
    -
  • {{domxref("HTMLCanvasElement")}}
  • -
  • {{domxref("CanvasRenderingContext2D")}}
  • -
  • {{domxref("CanvasGradient")}}
  • -
  • {{domxref("CanvasImageSource")}}
  • -
  • {{domxref("CanvasPattern")}}
  • -
  • {{domxref("ImageBitmap")}}
  • -
  • {{domxref("ImageData")}}
  • -
  • {{domxref("RenderingContext")}}
  • -
  • {{domxref("TextMetrics")}}
  • -
  • {{domxref("OffscreenCanvas")}} {{experimental_inline}}
  • -
  • {{domxref("Path2D")}} {{experimental_inline}}
  • -
  • {{domxref("ImageBitmapRenderingContext")}} {{experimental_inline}}
  • -
-
- -
-

노트: WebGLRenderingContext에 관련된 인터페이스는 WebGL 하위에 참조되어있습니다.

-
- -

{{domxref("CanvasCaptureMediaStream")}}은 관련된 인터페이스입니다.

- -

가이드 및 튜토리얼

- -
-
Canvas 튜토리얼
-
Canvas API의 기본적인 사용과 고급 기능 모두를 다루는 이해하기 쉬운 튜토리얼.
-
HTML5 Canvas 깊이 살펴보기
-
Canvas API 및 WebGL의 실습, 자세한 소개.
-
Canvas 핸드북
-
Canvas API에 대한 유용한 레퍼런스.
-
데모: A basic ray-caster
-
Canvas를 사용한 ray-tracing 애니메이션 데모.
-
Canvas를 사용하여 비디오 조작
-
{{HTMLElement("video")}}와 {{HTMLElement("canvas")}}를 조합하여 실시간으로 비디오 데이터를 조작.
-
- -

라이브러리

- -

Canvas API는 굉장히 강력하지만, 사용하는 것이 항상 간단하지 않습니다. 아래에 나열된 라이브러리들은 캔버스 기반 프로젝트를 더 빠르고 더 쉽게 생성할 수 있게 해줍니다.

- -
    -
  • EaselJS는 게임, 생성 예술 및 기타 고도의 그래픽 경험을 쉽게 생성할 수 있게 해주는 오픈소스 캔버스 라이브러리입니다.
  • -
  • Fabric.js는 SVG 파싱 기능을 갖춘 오픈소스 캔버스 라이브러리입니다.
  • -
  • heatmap.js는 캔버스 기반 데이터 열지도를 생성하기위한 오픈소스 라이브러리입니다.
  • -
  • JavaScript InfoVis Toolkit은 인터렉티브한 데이터 시각화를 생성합니다.
  • -
  • Konva.js는 데스크탑 및 모바일 애플리케이션을 위한 2D 캔버스 라이브러리입니다.
  • -
  • p5.js는 예술가, 디자이너, 교육자 및 입문자를 위한 캔버스 그리기 기능의 모든 세트를 포함하고 있습니다.
  • -
  • Paper.js는 HTML5 Canvas 위에서 실행되는 오픈소스 벡터 그래픽 스크립팅 프레임워크입니다.
  • -
  • Phaser는 Canvas 및 WebGL 기반의 브라우저 게임을 위한 빠르고, 자유롭고, 재미있는 오픈소스 프레임워크입니다.
  • -
  • Processing.js는 Processing 시각화 언어의 포트입니다.
  • -
  • Pts.js는 canvas 및 SVG를 사용한 창의적인 코딩 및 시각화를 위한 라이브러리입니다.
  • -
  • Rekapi는 Canvas를 위한 애니메이션 키 프레임 API입니다.
  • -
  • Scrawl-canvas는 2D 캔버스 엘리먼트를 생성하고 조작하기위한 오픈소스 JavaScript 라이브러리입니다.
  • -
  • ZIM 프레임워크는 canvas에서의 창의적인 코딩을 위한 편의성, 컴포넌트 및 컨트롤을 제공하는 프레임워크입니다. 접근성 및 다채로운 튜토리얼을 포함합니다.
  • -
- -
-

노트: WebGL을 사용하는 2D 및 3D를 위한 WebGL API를 확인하세요.

-
- -

명세

- - - - - - - - - - - - - - - - -
명세상태코멘트
{{SpecName('HTML WHATWG', '#2dcontext', 'the 2D rendering context')}}{{Spec2('HTML WHATWG')}}
- -

브라우저 호환성

- -

Mozilla 애플리케이션은 Gecko 1.8(Firefox 1.5)을 시작으로 <canvas>에 대한 지원을 받았습니다. OS X Dashboard 및 Safari를 위해 Apple이 소개한 것이 캔버스 엘리먼트의 기원입니다. Internet Explorer는 9버전부터 <canvas>를 지원하며, 이전 버전의 IE에서는 Google의 Explorer Canvas 프로젝트의 스크립트를 추가하여 <canvas>에 대한 지원을 효과적으로 추가할 수 있습니다. Google Chrome 및 Opera 9 또한 <canvas>를 지원합니다.

- -

함께 보기

- - diff --git a/files/ko/web/html/canvas/manipulating_video_using_canvas/index.html b/files/ko/web/html/canvas/manipulating_video_using_canvas/index.html deleted file mode 100644 index 7851f86154..0000000000 --- a/files/ko/web/html/canvas/manipulating_video_using_canvas/index.html +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: 캔버스(canvas)를 이용한 비디오 조작하기 -slug: Web/HTML/Canvas/Manipulating_video_using_canvas -tags: - - Canvas - - Video - - 비디오 - - 캔버스 -translation_of: Web/API/Canvas_API/Manipulating_video_using_canvas ---- -
{{CanvasSidebar}}
- -
-

비디오에서 다양한 시각적 효과를 보여주기 위해, 캔버스비디오의 기능을 결합하여 실시간으로 비디오 데이터를 조작할 수 있습니다. 이 튜토리얼에서는 자바스크립트 코드로 어떻게 크로마 키잉(chroma-keying, 또한 "녹색 스크린 효과, green screen effect")을 구현할 수 있는지 보여줍니다. 

-
- -

라이브 예제 보기

- -

문서(document) 내용

- -

이 내용을 보여주기 위한 XHTML 문서는 아래와 같습니다.

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      body {
-        background: black;
-        color:#CCCCCC;
-      }
-      #c2 {
-        background-image: url(foo.png);
-        background-repeat: no-repeat;
-      }
-      div {
-        float: left;
-        border :1px solid #444444;
-        padding:10px;
-        margin: 10px;
-        background:#3B3B3B;
-      }
-    </style>
-    <script type="text/javascript" src="main.js"></script>
-  </head>
-
-  <body onload="processor.doLoad()">
-    <div>
-      <video id="video" src="video.ogv" controls="true"/>
-    </div>
-    <div>
-      <canvas id="c1" width="160" height="96"></canvas>
-      <canvas id="c2" width="160" height="96"></canvas>
-    </div>
-  </body>
-</html>
-
- -

여기에서 중요한 요소는:

- -
    -
  1. 이 문서에는 ID가 c1, c2인 두 개의  캔버스가 있습니다. 캔버스 c1은 비디오 원본의 현재 프레임을 보여주기 위해 사용되고, c2는 크로마 키잉 효과를 수행한 결과를 보여줍니다. c2에서 비디오의 녹색 배경을 대체할 정지 이미지를 미리 로드합니다.
  2. -
  3. 자바스크립트 코드는 main.js에서 가져옵니다. 이 스크립트는 자바스크립트 1.8 기능을 사용했기 때문에 스크립트를 가져오는 22번째 줄에서 버전이 명시됩니다(원문: this script uses JavaScript 1.8 features, so that version is specified in line 22 when importing the script).
  4. -
  5. 문서가 로드되면, processor.doLoad() 메서드가 실행됩니다.
  6. -
- -

자바스크립트 코드

- -

main.js에 있는 자바스크립트 코드는 3개의 메서드로 구성됩니다.

- -

크로마 키잉 플레이어 초기화

- -

doLoad() 메서드는 문서가 최초에 로드될 때 호출됩니다. 이 메서드가 하는 일은 크로마 키잉 처리에서 쓰일 변수를 준비하고, 이벤트 리스너를 등록함으로써 사용자가 비디오 재생을 시작할 때 감지할 수 있도록 해줍니다. 

- -
  var processor;
-
-  processor.doLoad = function doLoad() {
-    this.video = document.getElementById('video');
-    this.c1 = document.getElementById('c1');
-    this.ctx1 = this.c1.getContext('2d');
-    this.c2 = document.getElementById('c2');
-    this.ctx2 = this.c2.getContext('2d');
-    let self = this;
-    this.video.addEventListener('play', function() {
-        self.width = self.video.videoWidth / 2;
-        self.height = self.video.videoHeight / 2;
-        self.timerCallback();
-      }, false);
-  },
-
- -

이코드는 XHTML에서 중요한 요소인 비디오와 캔버스의 참조를 가져옵니다. 두 개의 캔버스에 대한 그래픽 컨텍스트의 참조도 가져옵니다. 이 참조들은 뒤에서 크로마 키잉 효과를 구현할 때 사용됩니다.

- -

그리고 addEventListener()는 비디오가 재생을 시작하기 위해 호출되기 때문에 사용자가 재생 버튼을 누를 때 알림을 받습니다. 재생이 시작되면 이 코드는 비디오의 가로, 세로를 이등분 한 값을 가져오고(크로마 키잉 효과를 수행할 때 이등분 함), timerCallback() 메서드를 호출하여 비디오를 보고 시각적 효과를 계산하기 시작합니다.

- -

타이머 콜백

- -

타이머 콜백은 비디오가 재생되기 시작("재생" 이벤트가 발생)할 때 호출되는데, 매 프레임마다 키잉 효과를 주기 위해 주기적으로 호출 될 수 있도록 설정해 주어야 합니다.

- -
  processor.timerCallback = function timerCallback() {
-    if (this.video.paused || this.video.ended) {
-      return;
-    }
-    this.computeFrame();
-    let self = this;
-    setTimeout(function() {
-        self.timerCallback();
-      }, 0);
-  },
-
- -

콜백에서 하는 첫 번 째 일은 비디오가 재생되고 있는지 확인하는 것인데, 만약 그렇지 않다면 콜백은 아무 일도 하지 않고 즉시 반환됩니다.

- -

그 후에 현재 비디오 프레임에서 크로마 키잉 효과를 주기 위한 computeFrame() 메서드를 호출합니다.

- -

콜백에서 마지막으로 하는 일은 setTimeout()을 호출하여 가능한 한 빨리 timerCallback() 메서드를 다시 호출할 수 있도록 하는 것입니다. 실제로는, 비디오 프레임 속도에 대한 기반 지식으로 호출할 수 있도록 합니다. 

- -

비디오 프레임 데이터 조작

- -

아래의 computeFrame() 메서드는 프레임 데이터를 가져와서 크로마 키잉 효과를 수행하는 역할을 합니다. 

- -
  processor.computeFrame = function computeFrame() {
-    this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
-    let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
-    let l = frame.data.length / 4;
-
-    for (let i = 0; i < l; i++) {
-      let r = frame.data[i * 4 + 0];
-      let g = frame.data[i * 4 + 1];
-      let b = frame.data[i * 4 + 2];
-      if (g > 100 && r > 100 && b < 43)
-        frame.data[i * 4 + 3] = 0;
-    }
-    this.ctx2.putImageData(frame, 0, 0);
-    return;
-  }
-
- -

위 과정이 계속 호출 되면, 아래와 같이 비디오 요소에 가장 최근 프레임의 비디오 데이터가 표출됩니다.

- -

video.png

- -

2번째 줄에서, 첫 번째 캔버스의 그래픽 컨텍스트 ctx1에 비디오 프레임이 복사 되는데, 원본의 절반 크기로 프레임을 그리기 위해 이전에 저장한 가로, 세로 값으로 지정합니다. 컨텍스트의 drawImage() 메서드에 비디오 요소를 전달하기만 하면 현재 비디오 프레임을 그릴 수 있습니다. 결과는 아래와 같습니다: 

- -

sourcectx.png

- -

3번째 줄에서는 첫 번째 컨텍스트의 getImageData() 메서드를 호출해서 현재 비디오 프레임의 원시 그래픽 데이터 복사본을 가져옵니다. 이것은 조작할 수 있는 원시 32비트 픽셀 이미지 데이터를 제공합니다. 4번째 줄에서는 프레임의 이미지 데이터 전체 크기를 4로 나누어 이미지의 픽셀 수를 계산합니다.

- -

6번째 줄에서 시작하는 for 문은 프레임의 픽셀을 스캔하여, 빨간색, 녹색, 파란색 값을 추출하여 사전에 정의된 숫자와 비교합니다. 이 숫자는 foo.png에서 가져온 배경 이미지로 대체될 녹색 스크린 영역을 감지합니다.

- -

녹색 스크린이라고 간주된 매개변수 내의 프레임 이미지 데이터의 모든 픽셀은 투명해질 수 있도록 알파값이 0으로 대체됩니다. 결과적으로 최종 이미지는 100% 투명해진 녹색 스크린 영역을 갖게 되고, 13번째 줄에서 대상 컨텍스트에 고정된 배경 위로 올려져 그려집니다.

- -

결과 이미지는 아래와 같습니다:

- -

output.png

- -

이 과정은 비디오가 재생될 때마다 반복되므로, 매 프레임마다 처리되어 크로마 키잉 효과가 나타나는 것입니다.

- -

라이브 예제 보기

- -

더 보기

- - diff --git a/files/ko/web/html/canvas/tutorial/advanced_animations/index.html b/files/ko/web/html/canvas/tutorial/advanced_animations/index.html deleted file mode 100644 index 1779e63b2c..0000000000 --- a/files/ko/web/html/canvas/tutorial/advanced_animations/index.html +++ /dev/null @@ -1,376 +0,0 @@ ---- -title: 발전된 애니메이션 -slug: Web/HTML/Canvas/Tutorial/Advanced_animations -translation_of: Web/API/Canvas_API/Tutorial/Advanced_animations ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}
- -
-

마지막 챕터에서 우리는 몇가지 간단한 애니메이션들을 만들었고 이제 이것들을 어떻게 움직이게 하는지 안다. 이 챕터에서 우리는 각각의 모션들을 자세히 살펴보고 애니메이션을 더 발전시키기 위해 몇가지 물리 동작을 추가할 것이다.

-
- -

공 그리기

- -

우리는 애니메이션 공부를 위해 공을 사용할 것이다. 먼저 캔버스에 공을 그려보자. 다음 코드를 통해 준비해보자.

- -
<canvas id="canvas" width="600" height="300"></canvas>
-
- -

언제나처럼, 우리는 context를 먼저 그려야 한다. 공을 그리기 위해 우리는 캔버스에 그림을 그리기 위한 프로퍼티와 draw() 메소드를 가진 ball 오브젝트를 생성할 것이다.

- -
var canvas = document.getElementById('canvas');
-var ctx = canvas.getContext('2d');
-
-var ball = {
-  x: 100,
-  y: 100,
-  radius: 25,
-  color: 'blue',
-  draw: function() {
-    ctx.beginPath();
-    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
-    ctx.closePath();
-    ctx.fillStyle = this.color;
-    ctx.fill();
-  }
-};
-
-ball.draw();
- -

특이할 건 없다. 이공은 사실상 간단한 원이고 그리는 방법은 다음{{domxref("CanvasRenderingContext2D.arc()", "arc()")}} 메소드에서 참고할 수 있다.

- -

속도 추가하기

- -

우리한테는 이제 공이 있다. 이제 이 튜토리얼 마지막 챕터에서 배웠던 것과 같은 기본 애니메이션을 추가할 준비가 되었다. 다시 한 번, 애니메이션 컨트롤은 {{domxref("window.requestAnimationFrame()")}}가 도와주 것이다. 공은 위치에 속도 벡터를 추가하여 움직일 수 있게 된다.  각각의 프레임에, 우리는{{domxref("CanvasRenderingContext2D.clearRect", "clear", "", 1)}}를 캔버스에 주어 오래된 원을 이전 프래임에서 지운다.

- -
var canvas = document.getElementById('canvas');
-var ctx = canvas.getContext('2d');
-var raf;
-
-var ball = {
-  x: 100,
-  y: 100,
-  vx: 5,
-  vy: 2,
-  radius: 25,
-  color: 'blue',
-  draw: function() {
-    ctx.beginPath();
-    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
-    ctx.closePath();
-    ctx.fillStyle = this.color;
-    ctx.fill();
-  }
-};
-
-function draw() {
-  ctx.clearRect(0,0, canvas.width, canvas.height);
-  ball.draw();
-  ball.x += ball.vx;
-  ball.y += ball.vy;
-  raf = window.requestAnimationFrame(draw);
-}
-
-canvas.addEventListener('mouseover', function(e) {
-  raf = window.requestAnimationFrame(draw);
-});
-
-canvas.addEventListener('mouseout', function(e) {
-  window.cancelAnimationFrame(raf);
-});
-
-ball.draw();
-
- -

경계

- -

경게 충돌 테스트의 필요 없이 우리가 만든 공은 캔버스 밖으로 빠르게 빠져나갈 것입니다. 우리는 공의 xy 위치가 캔버스 차원을 빠져나갔는지 체크해서 방향과 속도를 바꿔주어야 합니다. 그러기 위해서 우리는 draw 메소드에 다음 확인사항을 추가할 것입니다.:

- -
if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
-  ball.vy = -ball.vy;
-}
-if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
-  ball.vx = -ball.vx;
-}
- -

First demo

- -

이제 동작을 확인해 봅시다. 시작하려먼 마우스를 캔버스 안으로 움직여 주세요.

- - - -

{{EmbedLiveSample("First_demo", "610", "310")}}

- -

가속

- -

움직임을 좀 더 리얼하게 만들기 위해, 우리는 속도를 다음과 같이 줄 겁니다. 예를들어:

- -
ball.vy *= .99;
-ball.vy += .25;
- -

이것은 각 프레임의 세로 속도를 줄여주어, 공이 결국 바닥에서 튀게 만듭니다.

- - - -

{{EmbedLiveSample("Second_demo", "610", "310")}}

- -

후행 효과

- -

지금까지 우리는 {{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}}메소드를 사용해서 이전 프레임을 지웠다. 만약 당신이 {{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}}르 사용하여 약간 투명도를 준다면, 쉽게 후행 효과(Trailing effect)를 만들 수 있을 것이다.

- -
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
-ctx.fillRect(0, 0, canvas.width, canvas.height);
- - - -

{{EmbedLiveSample("Third_demo", "610", "310")}}

- -

마우스 컨트롤 추가하기

- -

공을 컨트롤 하기 위해, 우리는 mousemove 이벤트를 사용하여 마우스를 따라오게 할 것이다. click 이벤트를 통해 공을 놓으면 다시 공이 튀도록 할 것이다.

- - - -
var canvas = document.getElementById('canvas');
-var ctx = canvas.getContext('2d');
-var raf;
-var running = false;
-
-var ball = {
-  x: 100,
-  y: 100,
-  vx: 5,
-  vy: 1,
-  radius: 25,
-  color: 'blue',
-  draw: function() {
-    ctx.beginPath();
-    ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
-    ctx.closePath();
-    ctx.fillStyle = this.color;
-    ctx.fill();
-  }
-};
-
-function clear() {
-  ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
-  ctx.fillRect(0,0,canvas.width,canvas.height);
-}
-
-function draw() {
-  clear();
-  ball.draw();
-  ball.x += ball.vx;
-  ball.y += ball.vy;
-
-  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
-    ball.vy = -ball.vy;
-  }
-  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
-    ball.vx = -ball.vx;
-  }
-
-  raf = window.requestAnimationFrame(draw);
-}
-
-canvas.addEventListener('mousemove', function(e) {
-  if (!running) {
-    clear();
-    ball.x = e.clientX;
-    ball.y = e.clientY;
-    ball.draw();
-  }
-});
-
-canvas.addEventListener('click', function(e) {
-  if (!running) {
-    raf = window.requestAnimationFrame(draw);
-    running = true;
-  }
-});
-
-canvas.addEventListener('mouseout', function(e) {
-  window.cancelAnimationFrame(raf);
-  running = false;
-});
-
-ball.draw();
-
- -

마우스로 공을 움직이고, 클릭을 통해 놓아보자.

- -

{{EmbedLiveSample("Adding_mouse_control", "610", "310")}}

- -

Breakout

- -

이 짧은 챕터는 발전된 애니메이션을 만들기 위한 조금의 기술을 설명했다. 여기에 더 많은 것들이 있다! 노나 벽돌을 추가해서 이 튜토리얼을  Breakout 으로 발전시키는 건 어떨까?  Game development에서 게임에 관련된 글들을 찾아보자.

- -

더보기

- - - -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}

diff --git a/files/ko/web/html/canvas/tutorial/applying_styles_and_colors/index.html b/files/ko/web/html/canvas/tutorial/applying_styles_and_colors/index.html deleted file mode 100644 index df094acb71..0000000000 --- a/files/ko/web/html/canvas/tutorial/applying_styles_and_colors/index.html +++ /dev/null @@ -1,732 +0,0 @@ ---- -title: 스타일과 색 적용하기 -slug: Web/HTML/Canvas/Tutorial/Applying_styles_and_colors -tags: - - HTML5 - - 그래픽 - - 캔버스 -translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
- -
-

도형 그리기 장에서는 기본 선과 채우기 스타일만 사용했습니다. 여기서 우리는 그리기를 조금 더 매력적으로 만들 수있는 캔버스 옵션을 살펴볼 것입니다. 그리기에 다른 색상, 선 스타일, 그라디언트, 패턴 및 그림자를 추가하는 방법을 배우게됩니다.

-
- -

색상

- -

지금까지는 그리기 메소드만 살펴봤습니다. 도형에 색을 적용하고자 하면, fillStyle과  strokeStyle 두 가지 중요한 속성을 사용할 수 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}
-
도형을 채우는 색을 설정합니다.
-
{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}
-
도형의 윤곽선 색을 설정합니다.
-
- -

여기서의 color는 CSS의 {{cssxref("<color>")}}, 그라디언트 객체, 패턴 객체를 뜻합니다. 그라디언트 객체와 패턴 객체는 페이지 아래에서 설명합니다. 윤곽선과 채움 색의 초기 설정값은 검은색입니다. (CSS 색상 값 #000000)

- -
-

참고: strokeStyle 또는 fillStyle 속성을 설정하면, 새로 설정된 값이 앞으로 그려질 도형의 기본 값이 됩니다. 각 도형에 다른 색을 적용하려면 fillStyle 또는 strokeStyle 속성을 다시 적용해야 합니다.

-
- -

색의 올바른 값은 CSS3 사양에 나오는 {{cssxref("<color>")}} 값입니다. 아래에 나오는 색은 모두 한가지 색을 다르게 표현한 것입니다.

- -
// fillStyle에 적용되는 색은 모두 '오렌지'
-
-ctx.fillStyle = "orange";
-ctx.fillStyle = "#FFA500";
-ctx.fillStyle = "rgb(255, 165, 0)";
-ctx.fillStyle = "rgba(255, 165, 0, 1)";
-
- -

fillStyle 예제

- -

이 예제에서 for 반복문을 두 번 사용하여 사각형 격자를 그릴 것입니다. 결과는 스크린샷과 같을 것입니다. 결과가 그리 대단한 것은 아닙니다. 각 사각형의 RGB 색상값에서 붉은색과 녹색 값만을 변수 ij를 사용하여 변경합니다. 파란색 채널은 고정된 값입니다. 채널 값들을 변경함으로써, 모든 종류의 팔레트를 생성할 수 있습니다. 단계를 늘리면 Photoshop에서 사용하는 색상 팔레트와 비슷한 모양을 얻을 수 있습니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i = 0; i < 6; i++){
-    for (var j = 0; j < 6; j++){
-      ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ', ' +
-                       Math.floor(255 - 42.5 * j) + ', 0)';
-      ctx.fillRect(j*25,i*25,25,25);
-    }
-  }
-}
- - - -

결과는 아래와 같습니다.

- -

{{EmbedLiveSample("A_fillStyle_example", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}

- -

strokeStyle 예제

- -

이번 예제는 위에 나온 예제와 비슷하지만, strokeStyle 속성을 사용하여 윤곽선의 색을 바꿉니다. 사각형 대신, 원을 그리는 arc() 메소드를 사용합니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i = 0; i < 6; i++) {
-    for (var j = 0; j < 6; j++) {
-      ctx.strokeStyle = 'rgb(0, ' + Math.floor(255 - 42.5 * i) + ', ' +
-                       Math.floor(255 - 42.5 * j) + ')';
-      ctx.beginPath();
-      ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
-      ctx.stroke();
-    }
-  }
-}
- - - -

결과는 아래와 같습니다.

- -

{{EmbedLiveSample("A_strokeStyle_example", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}

- -

투명도

- -

캔버스에는 불투명한 도형을 그릴 수도 있고, 반투명한 도형도 그릴 수도 있습니다. globalAlpha 값을 설정하거나 윤곽선 또는 채움 스타일에 반투명 색을 적용하면 됩니다.

- -
-
{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}
-
투명도 값이 설정되면 이후 캔버스에 그려지는 모든 도형들의 투명도가 바뀝니다. 설정하는 값은 0.0(완전히 투명)과 1.0(완전히 불투명) 사이에 있어야 하며, 초기 설정값은 1.0(완전히 투명)입니다.
-
- -

globalAlpha는 모두 같은 투명도로 캔버스에 많은 도형을 그릴 때 유용합니다. 하지만, 보통은 각각의 도형마다 투명도를 설정하는 것이 더 유용할 것입니다.

- -

strokeStylefillStyle 값에 CSS rgba 색상값을 적용할 수 있으므로, 투명한 색을 적용하려면 아래와 같은 표기법을 사용할 수 있습니다.

- -
// 외곽선과 채움 스타일에 투명 적용
-
-ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
-ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';
-
- -

rgba() 함수는 rgb() 함수와 비슷하지만, 인자가 하나 더 있습니다. 마지막 인자는 투명도 값을 설정하는 인자입니다. 올바른 범위는 0.0(완전히 투명)에서 1.0(완전히 불투명)입니다.

- -

globalAlpha 예제

- -

이 예제에서, 네 가지 다른 색을 가진 사각형을 배경에 그릴 것입니다. 그 위에, 반투명한 원을 여러 개 그릴 것입니다. globalAlpha 값을 0.2로 설정하면 이후 그려질 도형은 이 값을 사용합니다. for 반복문을 사용하여 점점 큰 반지름의 원을 그립니다. 최종 결과물은 원형 그레이디언트가 됩니다. 원이 겹쳐지면서 점점 불투명해지는 것을 볼 수 있으며, 최종적으로 한 가운데에 있는 원에서는 뒷 배경이 거의 보이지 않게 됩니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  // 배경을 그린다
-  ctx.fillStyle = '#FD0';
-  ctx.fillRect(0, 0, 75, 75);
-  ctx.fillStyle = '#6C0';
-  ctx.fillRect(75, 0, 75, 75);
-  ctx.fillStyle = '#09F';
-  ctx.fillRect(0, 75, 75, 75);
-  ctx.fillStyle = '#F30';
-  ctx.fillRect(75, 75, 75, 75);
-  ctx.fillStyle = '#FFF';
-
-  // 투명값을 설정한다
-  ctx.globalAlpha = 0.2;
-
-  // 반투명한 원을 그린다
-  for (var i = 0; i < 7; i++){
-    ctx.beginPath();
-    ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
-    ctx.fill();
-  }
-}
- - - -

{{EmbedLiveSample("A_globalAlpha_example", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}

- -

rgba()를 사용한 예제

- -

두번째 예제에서는 위의 예제와 비슷한 일을 하지만, 겹쳐진 원을 그리는 대신, 불투명도가 증가하는 작은 사각형을 그릴 것입니다. 각각의 도형마다 윤곽선이나 채움 스타일을 따로따로 설정할 수 있기 때문에, rgba()를 사용할 때는 조금 더 제어가 쉽고 융통성도 있습니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // 배경을 그린다
-  ctx.fillStyle = 'rgb(255,221,0)';
-  ctx.fillRect(0,0,150,37.5);
-  ctx.fillStyle = 'rgb(102,204,0)';
-  ctx.fillRect(0,37.5,150,37.5);
-  ctx.fillStyle = 'rgb(0,153,255)';
-  ctx.fillRect(0,75,150,37.5);
-  ctx.fillStyle = 'rgb(255,51,0)';
-  ctx.fillRect(0,112.5,150,37.5);
-
-  // 반투명한 사각형을 그린다
-  for (var i=0;i<10;i++){
-    ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
-    for (var j=0;j<4;j++){
-      ctx.fillRect(5+i*14,5+j*37.5,14,27.5)
-    }
-  }
-}
- - - -

{{EmbedLiveSample("An_example_using_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}

- -

선 모양

- -

선의 스타일을 바꾸는 방법이 몇가지 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}
-
이후 그려질 선의 두께를 설정합니다.
-
{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}
-
선의 끝 모양을 설정합니다.
-
{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}
-
선들이 만나는 "모서리"의 모양을 설정합니다.
-
{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}
-
두 선이 예각으로 만날 때 접합점의 두께를 제어할 수 있도록, 연결부위의 크기를 제한하는 값을 설정합니다.
-
{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}
-
음수가 아닌 짝수를 포함하는 현재 선의 대시 패턴 배열을 반환합니다.
-
{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}
-
현재 선의 대시 패턴을 설정합니다.
-
{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}
-
선의 대시 배열이 어디서 시작될지 지정합니다.
-
- -

아래 예제들을 보면 어떻게 동작하는지 이해할 수 있을 것입니다.

- -

lineWidth 예제

- -

현재 선의 두께를 설정합니다. 설정값은 반드시 양수이어야 하며, 초기 설정값은 1.0 단위입니다.

- -

선의 두께는 지정된 경로의 가운데에 있는 획의 두께입니다. 이 말의 뜻은, 경로의 좌우로, 설정된 두께 반 만큼의 폭 영역이 그려진다는 것입니다. 캔버스 좌표는 픽셀을 직접 참조하지 않으므로, 선명한 수평 및 수직선을 얻기 위해 특별히 주의를 기울여야 합니다.

- -

아래에 나오는 예제에서는, 선의 두께가 점점 증가하는 10개의 직선이 그려집니다. 가장 왼쪽의 선은 1.0 단위 폭입니다. 그러나, 경로의 위치 때문에 가장 왼쪽과 다른 모든 홀수 폭 두께 선은 선명하게 보이지 않습니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i = 0; i < 10; i++){
-    ctx.lineWidth = 1 + i;
-    ctx.beginPath();
-    ctx.moveTo(5 + i * 14, 5);
-    ctx.lineTo(5 + i * 14, 140);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("A_lineWidth_example", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}

- -

선명한 선을 얻으려면 경로에 획을 어떻게 그려지는지 이해해야 합니다. 아래의 이미지를 보면, 격자는 캔버스의 좌표 격자를 나타냅니다. 격자선 사이에 있는 사각형은 실제 픽셀과 딱 맞아 떨어집니다. 아래에 있는 첫번째 이미지를 보면, (2,1)에서 (5,5)로 사각형이 채워져 있습니다. 사각형의 전체 영역(연한 붉은 색)은 픽셀 경계선 사이에 딱 맞아 떨어지기 때문에 채워진 사각형은 선명한 가장자리를 갖습니다.

- -

- -

만일 (3,1)에서 (3,5)로 그리는 직선의 두께가 1.0이라면, 두번째 이미지와 같은 상황이 됩니다. 채워진 실제 영역 (진한 파란색)은 패스의 양쪽에있는 픽셀의 절반까지만 확장됩니다. 이것은 1 픽셀을 채우는 것이 아니므로 근사값으로 화면에 그려지게 됩니다. 그래서 양옆의 영역(연한 파란색과 짙은 파란 색)으로, 실제 설정한 색과는 다른 흐릿한 색으로 채워지는 것입니다. 이전 예제에서 보듯이 선 두께가 1.0인 선에서 일어난 일입니다.

- -

이렇게 되는 것을 막으려면, 경로를 아주 정밀하게 생성해야 합니다. 선의 두께가 1.0이면 경로의 양쪽으로 0.5 단위만큼이라는 것을 알고 있으니, (3.5,1)에서 (3.5,5)로 그리는 경로를 생성하는 세번째 이미지의 결과는 완벽히 정밀하게 1 픽셀 두께의 수직선이 됩니다.

- -
-

참고: 위에 나온 수직선 그리기 예제를 살펴보면, Y 위치는 정수로 된 격자선 위치를 참조하고 있습니다. 그렇지 않았다면, 끝점에서 픽셀의 반을 차지한 상태로 보였을 것입니다. (초기값이 buttlineCap 스타일의 설정값에 따라 다르게 보입니다. 홀수 두께 선들의 좌표를 0.5 픽셀씩 조정하여 다시 계산하고 싶을지도 모릅니다. lineCap 스타일을 square로 설정함으로써, 끝점에서 선의 외곽 경계선은 픽셀에 딱 맞게 자동적으로 확장될 것입니다.)

- -

경로의 시작 지점과 종료 지점의 끝점만이 영향을 받는다는 것에 주목하세요. 만약 closePath()로 경로가 닫힌다면, 시작 지점과 종료 지점은 없는 것입니다. 그 대신, 경로 안에 있는 모든 끝점들은, 초기 설정값이 miterlineJoin 스타일의 설정값을 사용하여 이전 부분 및 다음 부분과 이어지는데, 교차되는 점들로 이어진 부분들의 외곽 경계선을 자동적으로 확장하는 효과가 생깁니다. 그렇기 때문에 만약 이들 이어진 부분들이 수직 또는 수평이라면, 그려지는 선들은 각 끝점의 중심에 놓인 픽셀을 가득 채우게 될 것입니다. 이들 선 스타일에 대한 예제는 아래에 나옵니다.

-
- -

짝수 두께의 선들은 반으로 나누어도 각각의 반은 정수의 양만큼이기 때문에 픽셀을 조정할 필요가 없습니다.

- -

비트맵이 아닌 벡터 2D 그래픽으로 작업할 때, 작업을 시작할 때는 약간 힘들겠지만, 격자와 경로의 위치에 주의를 기울인다면, 크기를 키우거나 줄이거나 또는 어떠한 변형을 하더라도 그리려는 이미지는 똑바로 보일 것입니다. 1.0 두께의 수직선은 2배로 크기를 키웠을 때, 정확히 2 픽셀 두께의 선이 되며, 올바른 위치에 나타날 것입니다.

- -

lineCap 예제

- -

lineCap 속성은 그리려는 모든 선의 끝점 모양을 결정합니다. butt, round, square라는 세 가지 값을 가지며, 초기 설정값은 butt입니다.

- -

- -
-
butt
-
선의 끝이 좌표에 딱맞게 잘립니다.
-
round
-
선의 끝이 동그랗습니다.
-
square
-
선 끝에, 선 두께 반만큼의 사각형 영역이 더해집니다.
-
- -

이 예제에서는, 각기 다른 lineCap 속성 값을 가진 선 세개가 그려집니다. 또한 각 선들의 차이점을 정확히 보이기 위한 안내선이 추가로 그려집니다. 세개의 선 모두, 이 안내선 위에 시작과 종료 좌표가 있습니다.

- -

맨 왼쪽에 있는 선은 초기 설정값인 butt을 사용합니다. 안내선에 딱 맞게 선이 시작되고 끝이 납니다. 가운데에 있는 선은 round를 사용합니다. 선 두께의 반을 반지름으로 하는 반원이 끝에 붙습니다. 맨 오른쪽에 있는 선은 square를 사용합니다. 선 두께 만큼의 너비와 선 두께 반 만큼의 높이를 가진 네모 상자가 끝에 붙습니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var lineCap = ['butt','round','square'];
-
-  // 안내선을 그린다
-  ctx.strokeStyle = '#09f';
-  ctx.beginPath();
-  ctx.moveTo(10, 10);
-  ctx.lineTo(140, 10);
-  ctx.moveTo(10, 140);
-  ctx.lineTo(140, 140);
-  ctx.stroke();
-
-  // 선을 그린다
-  ctx.strokeStyle = 'black';
-  for (var i=0;i<lineCap.length;i++){
-    ctx.lineWidth = 15;
-    ctx.lineCap = lineCap[i];
-    ctx.beginPath();
-    ctx.moveTo(25 + i * 50, 10);
-    ctx.lineTo(25 + i * 50,140);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("A_lineCap_example", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}

- -

lineJoin 예제

- -

lineJoin 속성은, 도형을 이루는 선이나 호나 곡선들이 연결되는 지점의 모양을 결정합니다. 끝점과 제어점이 정확히 같은 위치인, 길이가 0인 부분들은 제외된다.

- -

이 속성에는 세 가지 값이 있는데, round, bevel, miter이며, 초기 설정값은 miter입니다. 두 부분들이 같은 방향으로 연결되어 있는 경우에는, lineJoin을 설정해도 아무런 효과가 나타나지 않습니다.

- -

- -
-
round
-
도형의 모서리를, 연결되는 부분들의 공통 끝점을 중심으로 하는 원 모양으로 만듭니다. 이때 원의 반지름은 선의 두께와 같습니다.
-
bevel
-
도형의 모서리를, 연결되는 부분들의 공통 끝점에서 세모 모양으로 만듭니다.
-
miter
-
도형의 모서리를, 두 부분의 바깥쪽 테두리 선을 각각 연장하여 교차된 점으로 생긴 마름모꼴 모양으로 만듭니다. miterLimit 속성값에 따라 모양이 달라집니다.
-
- -

아래 예제에서 세 개의 경로를 그릴 것입니다. 세 경로는 각각 다른 lineJoin 속성값을 가집니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var lineJoin = ['round', 'bevel', 'miter'];
-  ctx.lineWidth = 10;
-  for (var i=0;i<lineJoin.length;i++){
-    ctx.lineJoin = lineJoin[i];
-    ctx.beginPath();
-    ctx.moveTo(-5, 5 + i * 40);
-    ctx.lineTo(35, 45 + i * 40);
-    ctx.lineTo(75, 5 + i * 40);
-    ctx.lineTo(115, 45 + i * 40);
-    ctx.lineTo(155, 5 + i * 40);
-    ctx.stroke();
-  }
-}
-
- - - -

{{EmbedLiveSample("A_lineJoin_example", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}

- -

miterLimit 속성 예제

- -

위의 예제에서 볼 수 있듯이, 속성값을 miter로 하여 두 선이 연결되면, 연결되는 두 선의 바깥쪽 테두리는 연장선이 만나는 지점까지 확장됩니다. 연결된 두 선이 이루는 각도가 크면, 확장되는 영역이 크지 않지만, 각도가 작아짐(끝이 뾰족해짐)에 따라서 이 영역이 기하급수적으로 커질 수도 있습니다.

- -

miterLimit 속성은 끝점이 만나는 지점과 테두리 연장선이 만나는 지점이 얼마나 떨어져 있을지를 결정합니다. 두 선이 이 값을 넘게 되면, lineJoin 속성의 bevel 값 모양이 적용됩니다. miterLimit 속성값(HTML {{HTMLElement("canvas")}}에서, 초기 설정값은 10.0)에 의해, 현재 좌표 방식 안에서, 선의 두께에 따라, 어느 정도까지 뾰족해질 수 있는지가 계산됩니다. 그래서 miterLimit은 현재 디스플레이 비율이나 경로의 변형 같은 것으로 각각 설정될 수 있습니다. 그렇게 하여 선의 모서리에만 영향을 줍니다.

- -

더 자세히 얘기하자면, 뾰족함 제한(miter limit)은, 선 두께의 반과 확장되는 길이(HTML 캔버스에서, 선이 연결되는 바깥쪽 끝부분과, 경로에서 연결되는 두 부분의 공통 끝점 사이로 측정합니다.)의 최대 허용 비율입니다. 이것은 두 부분의 외곽선이 만나는 안쪽 점과 바깥쪽 점 사이 거리와, 선 두께의 최대 허용 비율과 같습니다. miter 값 모양이 아닌 bevel 값 모양으로 연결되는 지점의 최소 안쪽 각 반 만큼의 값과 같은 것입니다.

- -
    -
  • miterLimit = max miterLength / lineWidth = 1 / sin ( min θ / 2 )
  • -
  • 초기 설정값이 10.0인 뾰족함 제한(miter limit)값은 약 11도보다 낮은 예각인 곳을 bevel 값 모양으로 만듭니다.
  • -
  • 뾰족함 제한 값이 √2 ≈ 1.4142136(반올림)과 같다면 연결되는 곳이 둔각이거나 직각인 곳을 제외한 모든 곳을 bevel 값 모양으로 만듭니다.
  • -
  • 뾰족함 제한 값이 1.0과 같다면 모든 곳을 bevel 값 모양으로 만듭니다.
  • -
  • 뾰족함 제한 값에는 1.0보다 작은 값이 올 수 없습니다.
  • -
- -

다음 예제에서는 miterLimit 값을 바꾸고 그 결과가 어떤지 바로 확인할 수 있습니다. 파란색 선은 지그재그 무늬 안에서 선들의 시작 지점과 종료 지점을 나타냅니다.

- -

이 예제에서 miterLimit 값을 4.2보다 낮게 설정하면, 모든 연결 지점은 bevel 값 모양이 되어 파란색 선에 붙을 것입니다. miterLimit 값이 10보다 높다면, 거의 모든 연결 지점들이 파란색 선 바깥쪽에 있을 것입니다. 왼쪽으로 갈수록 파란색 선에서 더 많이 튀어나오는데, 왼쪽으로 갈수록 연결되는 각이 더 작아지기 때문입니다. 값을 5로 설정하면, 반은 bevel 값 모양으로, 반은 miter 값 모양이 됩니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // 캔버스를 비운다
-  ctx.clearRect(0,0,150,150);
-
-  // 안내선을 그린다
-  ctx.strokeStyle = '#09f';
-  ctx.lineWidth   = 2;
-  ctx.strokeRect(-5,50,160,50);
-
-  // 선 스타일을 설정한다
-  ctx.strokeStyle = '#000';
-  ctx.lineWidth = 10;
-
-  // 입력 값을 검사한다
-  if (document.getElementById('miterLimit').value.match(/\d+(\.\d+)?/)) {
-    ctx.miterLimit = parseFloat(document.getElementById('miterLimit').value);
-  } else {
-    alert('Value must be a positive number');
-  }
-
-  // 선을 그린다
-  ctx.beginPath();
-  ctx.moveTo(0,100);
-  for (i=0;i<24;i++){
-    var dy = i%2==0 ? 25 : -25 ;
-    ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
-  }
-  ctx.stroke();
-  return false;
-}
-
- - - -

{{EmbedLiveSample("A_demo_of_the_miterLimit_property", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}

- -

 

- -

대시라인 사용하기

- -

setLineDash 메소드와 lineDashOffset 속성은 선의 대시 패턴을 지정합니다.  setLineDash 메소드는 거리를 지정하는 숫자 목록을 받아 선과 틈을 교대로 그리며 lineDashOffset 속성은 패턴을 시작할 위치를 오프셋으로 설정합니다.

- -

이 예제에서 우리는 행진하는 개미 효과를 만들고 있습니다. 컴퓨터 그래픽 프로그램의 선택 도구에서 흔히 볼 수있는 애니메이션 기술입니다. 테두리를 애니메이션화하여 사용자가 선택 테두리와 이미지 배경을 구별하는 데 도움이됩니다. 이 튜토리얼의 뒷부분에서 이 작업 및 다른 기본 애니메이션을 수행하는 방법을 배울 수 있습니다.

- - - -
var ctx = document.getElementById('canvas').getContext('2d');
-var offset = 0;
-
-function draw() {
-  ctx.clearRect(0, 0, canvas.width, canvas.height);
-  ctx.setLineDash([4, 2]);
-  ctx.lineDashOffset = -offset;
-  ctx.strokeRect(10, 10, 100, 100);
-}
-
-function march() {
-  offset++;
-  if (offset > 16) {
-    offset = 0;
-  }
-  draw();
-  setTimeout(march, 20);
-}
-
-march();
- -

{{EmbedLiveSample("Using_line_dashes", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}

- -

그라디언트(Gradient)

- -

다른 그래픽 프로그램들과 마찬가지로, 선형 및 원형의 그레이디언트를 사용할 수 있습니다. 다음 메소드 중 하나를 사용하여 {{domxref("CanvasGradient")}} 객체를 생성합니다. 그런 다음 이 객체를 fillStyle 또는 strokeStyle 속성에 할당 할 수 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}
-
시작점 좌표를 (x1, y1)로 하고, 종료점 좌표를 (x2, y2)로 하는 선형 그라디언트 오브젝트를 생성합니다.
-
{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}
-
반지름이 r1이고 좌표 (x1, y1)을 중심으로 하는 원과, 반지름이 r2이고 좌표 (x2, y2)를 중심으로 하는 원을 사용하여 그라디언트가 생성됩니다.
-
- -

예를 들면 다음과 같습니다.

- -
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
-var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);
-
- -

CanvasGradient 객체를 만들었다면, addColorStop() 메소드를 사용하여, 오브젝트에 색을 적용할 수 있습니다.

- -
-
{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}
-
gradient 오브젝트에 새로운 색 중단점(color stop)을 생성합니다. position은 0.0에서 1.0 사이의 숫자이고 그라디언트에서 색상의 상대적인 위치를 정의합니다. color 인자는 CSS {{cssxref("<color>")}}를 나타내는 문자열이어야하고, 그라디언트가 (전환효과로) 진행되면서 도달한 지점의 색상을 의미합니다.
-
- -

색 중단점은 원하는 만큼 마음대로 추가할 수 있습니다. 흰 색에서 검은 색으로 변하는 선형 그레이디언트를 만들려면 아래와 같이 합니다.

- -
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
-lineargradient.addColorStop(0, 'white');
-lineargradient.addColorStop(1, 'black');
-
- -

createLinearGradient 예제

- -

이 예제에서 그레이디언트 두 개를 만들 것입니다. 예제에서 볼 수 있듯이, strokeStylefillStyle 속성 모두 canvasGradient 오브젝트를 속성 값으로 가질 수 있습니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // 그레이디언트를 생성한다
-  var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
-  lingrad.addColorStop(0, '#00ABEB');
-  lingrad.addColorStop(0.5, '#fff');
-  lingrad.addColorStop(0.5, '#26C000');
-  lingrad.addColorStop(1, '#fff');
-
-  var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95);
-  lingrad2.addColorStop(0.5, '#000');
-  lingrad2.addColorStop(1, 'rgba(0, 0, 0, 0)');
-
-  // 외곽선과 채움 스타일에 그레이디언트를 적용한다
-  ctx.fillStyle = lingrad;
-  ctx.strokeStyle = lingrad2;
-
-  // 도형을 그린다
-  ctx.fillRect(10, 10, 130, 130);
-  ctx.strokeRect(50, 50, 50, 50);
-
-}
-
- - - -

첫번째 그라디언트는 배경 그라디언트입니다. 보시다시피 같은 위치에 두 가지 색상을 지정했습니다. 매우 선명한 색상 전환을 만들기 위해 이 작업을 수행합니다(이 경우 흰색에서 녹색으로). 일반적으로 색상 중단점을 정의하는 순서는 중요하지 않지만, 이 특별한 경우에는 의미가 있습니다.

- -

두 번째 그래디언트에서는 시작 색상 (위치 0.0)을 지정하지 않았는데, 자동으로 다음 색상 중단점의 색상으로 가정하기 때문에 반드시 필요하지는 않기 때문입니다. 따라서 위치 0.5에 검은색을 지정하면 시작부터 중단점까지 자동으로 검정색 그라이언트를 만듭니다.

- -

{{EmbedLiveSample("A_createLinearGradient_example", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}

- -

createRadialGradient 예제

- -

이 예제에서는 원형 그레이디언트를 4개 만들 것입니다. 포토샵같은 프로그램에서 원형 그레이디언트를 만들 때는 하나의 점을 중심으로 그레이디언트를 만드는데, 캔버스의 원형 그레이디언트에서는 시작과 종료 지점 두군데를 제어할 수 있기 때문에, 기존의 프로그램에서 볼 수 있는 원형 그레이디언트보다는 더 복잡한 효과를 만들어 낼 수 있습니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // 그라디언트를 생성한다
-  var radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
-  radgrad.addColorStop(0, '#A7D30C');
-  radgrad.addColorStop(0.9, '#019F62');
-  radgrad.addColorStop(1, 'rgba(1,159,98,0)');
-
-  var radgrad2 = ctx.createRadialGradient(105,105,20,112,120,50);
-  radgrad2.addColorStop(0, '#FF5F98');
-  radgrad2.addColorStop(0.75, '#FF0188');
-  radgrad2.addColorStop(1, 'rgba(255,1,136,0)');
-
-  var radgrad3 = ctx.createRadialGradient(95,15,15,102,20,40);
-  radgrad3.addColorStop(0, '#00C9FF');
-  radgrad3.addColorStop(0.8, '#00B5E2');
-  radgrad3.addColorStop(1, 'rgba(0,201,255,0)');
-
-  var radgrad4 = ctx.createRadialGradient(0,150,50,0,140,90);
-  radgrad4.addColorStop(0, '#F4F201');
-  radgrad4.addColorStop(0.8, '#E4C700');
-  radgrad4.addColorStop(1, 'rgba(228,199,0,0)');
-
-  // 도형을 그린다
-  ctx.fillStyle = radgrad4;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad3;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad2;
-  ctx.fillRect(0,0,150,150);
-  ctx.fillStyle = radgrad;
-  ctx.fillRect(0,0,150,150);
-}
-
- - - -

이 예제에서는 원형 그레이디언트에 사용되는 두 원의 중심을 달리하여 입체적인 공처럼 보이게 했습니다. 안쪽 원과 바깥쪽 원은 겹치지 않게 하는 것이 좋습니다. 왜냐하면 예상하기 힘든 이상한 결과가 나타날 수 있기 때문입니다.

- -

그레이디언트의 마지막 색 적용 지점에서는 투명도를 적용하였습니다. 투명도가 적용된 지점에서 이전 지점까지의 색 변화를 보기 좋게 만들려면, 두 지점에 똑같은 색을 적용하면 되는데, 이 예제에서는 색의 값을 다른 방식으로 입력하여 헷갈릴 수도 있습니다. 첫번째 그레이디언트에 사용된 #019F62rgba(1,159,98,1)은 같은 색입니다.

- -

{{EmbedLiveSample("A_createRadialGradient_example", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}

- -

패턴(Patterns)

- -

이전 페이지의 예제 중 하나에서 일련의 루프를 사용하여 이미지 패턴을 만들었습니다. 그러나 훨씬 간단한 메소드 인 createPattern () 메소드가 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}
-
새 캔버스 패턴 객체를 만들어 반환합니다. image는 {{domxref("CanvasImageSource")}}(즉, {{domxref("HTMLImageElement")}}, 다른 캔버스, {{HTMLElement("video")}} 요소 등등)입니다. type은 이미지 사용 방법을 나타내는 문자열입니다.
-
- -

type은 패턴을 만들기 위해 이미지를 사용하는 방법을 지정하며, 다음 문자열 값 중 하나 여야합니다.

- -
-
repeat
-
수직 및 수평 방향으로 이미지를 이어 붙입니다.
-
repeat-x
-
수평 방향으로만 이미지를 이어 붙입니다.
-
repeat-y
-
수직 방향으로만 이미지를 이어 붙입니다.
-
no-repeat
-
이미지를 이어 붙이지 않습니다. 이미지는 한번만 사용됩니다.
-
- -

이 메소드를 사용하여 위에서 본 그라디언트 메소드와 매우 유사한 {{domxref ( "CanvasPattern")}} 객체를 생성합니다. 패턴을 생성하면 fillStyle 또는 strokeStyle 속성에 패턴을 할당 할 수 있습니다. 예를 들면 다음과 같습니다.

- -
var img = new Image();
-img.src = 'someimage.png';
-var ptrn = ctx.createPattern(img, 'repeat');
-
- -
-

참고: drawImage () 메서드와 마찬가지로 이 메소드를 호출하기 전에 이미지가 로드되었는지 확인해야합니다. 그렇지 않으면 패턴이 잘못 그려 질 수 있습니다.

-
- -

createPattern 예제

- -

이 마지막 예제에서, fillStyle 속성에 적용할 패턴을 만들 것입니다. 한 가지 눈여겨 볼 것은, 이미지 onload 핸들러 사용한다는 것입니다. 이미지를 패턴에 적용하기 전에 불러오기가 완료되었는지 확인하는 것입니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // 패턴으로 사용할 이미지 오브젝트를 생성한다
-  var img = new Image();
-  img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
-  img.onload = function() {
-
-    // 패턴을 생성한다
-    var ptrn = ctx.createPattern(img,'repeat');
-    ctx.fillStyle = ptrn;
-    ctx.fillRect(0,0,150,150);
-
-  }
-}
-
- - - -

{{EmbedLiveSample("A_createPattern_example", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}

- -

그림자

- -

그림자 사용에는 네 개의 속성이 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}
-
그림자가 객체에서 연장되어야하는 수평 거리를 나타냅니다. 이 값은 변환 행렬의 영향을 받지 않습니다. 기본값은 0입니다.
-
{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}
-
그림자가 객체에서 연장되어야하는 수직 거리를 나타냅니다. 이 값은 변환 행렬의 영향을 받지 않습니다. 기본값은 0입니다.
-
{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}
-
흐림(blur) 효과의 크기를 나타냅니다. 이 값은 픽셀 수와 일치하지 않으며 현재 변환 행렬의 영향을 받지 않습니다. 기본값은 0입니다.
-
{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}
-
그림자 효과의 색상을 나타내는 표준 CSS 색상 값. 기본적으로 완전 검은색입니다.
-
- -

shadowOffsetXshadowOffsetY 속성은 그림자가 X 및 Y 방향으로 객체에서 얼마나 멀리 떨어져야하는지 나타냅니다. 이 값은 현재 변환 행렬의 영향을받지 않습니다. 음수값을 사용하면 그림자가 위로 또는 왼쪽으로 확장되고 양수값을 사용하면 그림자가 아래로 또는 오른쪽으로 확장됩니다. 기본값은 모두 0입니다.

- -

shadowBlur 속성은 흐림 효과의 크기를 나타냅니다. 이 값은 픽셀 수와 일치하지 않으며 현재 변환 행렬의 영향을받지 않습니다. 기본값은 0입니다.

- -

shadowColor 속성은 그림자 효과의 색상을 나타내는 표준 CSS 색상 값입니다. 기본값은 완전 검은색입니다.

- -
-

알아둘 것: 음영은 source-over 합성 작업에만 사용됩니다.

-
- -

그림자 있는 글자 예제

- -

이 예제에서는 그림자가 있는 글자를 그립니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.shadowOffsetX = 2;
-  ctx.shadowOffsetY = 2;
-  ctx.shadowBlur = 2;
-  ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
-
-  ctx.font = "20px Times New Roman";
-  ctx.fillStyle = "Black";
-  ctx.fillText("Sample String", 5, 30);
-}
-
- - - -

{{EmbedLiveSample("A_shadowed_text_example", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}

- -

다음 장에서 텍스트 그리기에 대한 font 속성과 fillText 메소드를 살펴 보겠습니다.

- -

캔버스 채우기 규칙

- -

fill (혹은 {{domxref("CanvasRenderingContext2D.clip", "clip")}} 및 {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}})을 사용할 때 한 점이 경로 안쪽 또는 바깥에 있는지 그리고 따라서 채워지는지 여부를 결정하기 위한 채우기 규칙 알고리즘을 선택적으로 제공 할 수 있습니다. 경로가 교차하거나 중첩 된 경우에 유용합니다.
-
- 다음 두가지 값을 사용할 수 있습니다:

- - - -

In this example we are using the evenodd rule.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.beginPath();
-  ctx.arc(50, 50, 30, 0, Math.PI * 2, true);
-  ctx.arc(50, 50, 15, 0, Math.PI * 2, true);
-  ctx.fill('evenodd');
-}
- - - -

{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}

diff --git a/files/ko/web/html/canvas/tutorial/basic_animations/index.html b/files/ko/web/html/canvas/tutorial/basic_animations/index.html deleted file mode 100644 index 457d658172..0000000000 --- a/files/ko/web/html/canvas/tutorial/basic_animations/index.html +++ /dev/null @@ -1,310 +0,0 @@ ---- -title: 기본 애니메이션 -slug: Web/HTML/Canvas/Tutorial/Basic_animations -tags: - - HTML5 - - 그래픽 - - 캔버스 -translation_of: Web/API/Canvas_API/Tutorial/Basic_animations ---- -

{{HTMLElement("canvas")}} 요소는 자바스크립트로 제어하는 것이므로, 애니메이션도 쉽게 만들 수 있습니다. 복잡한 애니메이션을 만드는 것은 추가 작업이 더 필요하고, 앞으로 그에 대한 페이지도 머지 않아 추가되기를 기대합니다.

-

도형은 한번 만들어 놓으면 그 모습 그대로 있다는 것이 애니메이션을 만들 때의 가장 큰 제약일 것입니다. 그 도형을 움직이고자 하면 그 도형뿐만이 아니라 그 도형이 그려지기 전에 그려진 모든 것을 다시 그려야 합니다. 복잡한 장면을 다시 그리는 것은 시간도 많이 걸리며, 코드를 실행하는 컴퓨터의 능력에 따라 달라집니다.

-

기본 애니메이션 단계

-

한 장면을 그리려면 아래와 같은 단계를 밟습니다.

-
    -
  1. 캔버스를 비웁니다.
    - 그리려는 도형이 (배경 이미지를 만들 때처럼) 캔버스를 가득 채우는 것이 아니라면, 이전에 그려진 모든 도형을 지울 필요가 있습니다. 가장 쉬운 방법은 clearRect() 메소드를 사용하는 것입니다.
  2. -
  3. 캔버스 상태를 저장합니다.
    - 캔버스 상태에 영향을 주는 (스타일 변경, 모양 변형 등의) 설정값을 바꾸려고 하고, 바뀐 값을 각 장면마다 사용하려고 한다면, 원래 상태를 저장할 필요가 있습니다.
  4. -
  5. 애니메이션할 도형을 그립니다.
    - 실제 장면을 그리는 단계입니다.
  6. -
  7. 캔버스 상태를 복원합니다.
    - 새로운 장면을 그리기 전에 저장된 상태를 복원합니다.
  8. -
-

애니메이션 제어하기

-

캔버스 메소드를 사용하거나 사용자 함수를 사용하여 캔버스에 도형들을 그립니다. 보통의 경우에서는, 코드 실행이 완료되면 캔버스에 나타나는 결과만을 보게 됩니다. 예를 들어,  for 반복문 안에서 애니메이션을 실행하는 것은 불가능합니다.

-

그래서 정해진 시간마다 그리기 함수를 실행하는 방법이 필요한 것입니다. 아래와 같이 애니메이션을 제어하는 두 가지 방법이 있습니다.

-

예정된 변경

-

정해진 시간마다 특정 함수를 부를 때 사용할 수 있는  {{domxref("window.setInterval()")}}과 {{domxref("window.setTimeout()")}} 함수가 있습니다.

-
-

알아둘 것: 현재는 애니메이션을 만드는 방법으로  {{domxref("window.requestAnimationFrame()")}} 메소드를 추천합니다. 이에 대한 튜토리얼은 곧 업데이트할 것입니다.

-
-
-
- setInterval(function, delay)
-
- delay 밀리세컨드(1,000분의 1초)마다 function 함수 반복 실행을 시작합니다.
-
- setTimeout(function, delay)
-
- delay 밀리세컨드(1,000분의 1초) 경과후, function 함수를 실행합니다.
-
-

사용자의 제어를  필요로 하지 않는 반복 실행에는  setInterval() 함수가 알맞을 것입니다.

-

사용자 상호 작용 변경

-

애니메이션을 제어하는 두번째 방법은 사용자 입력입니다. 게임을 만들려고 한다면, 애니메이션을 제어하기 위해 키보드나 마우스 이벤트를 사용할 수 있을 것입니다.  {{domxref("EventListener")}}를 설정하여, 사용자와 상호 작용하여 애니메이션 함수를 실행합니다.

-

사용자 상호 작용이 필요하다면, 우리가 만든 애니메이션용 프레임웍(framework)최소 기능 버전 또는 최대 기능 버전을 사용할 수 있을 것입니다.

-
var myAnimation = new MiniDaemon(null, animateShape, 500, Infinity);
-

또는

-
var myAnimation = new Daemon(null, animateShape, 500, Infinity);
-

아래 예제에서는, 애니메이션을 제어하기 위해 {{domxref("window.setInterval()")}}을 사용할 것입니다. 페이지 제일 아래쪽에 {{domxref("window.setTimeout()")}}을 사용한 예제 링크도 있습니다.

-

태양계 애니메이션

-

이 예제에서는 달이 지구를 돌고 지구가 태양을 도는 애니메이션을 만듭니다.

-
var sun = new Image();
-var moon = new Image();
-var earth = new Image();
-function init(){
-  sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
-  moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
-  earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
-  setInterval(draw,100);
-}
-
-function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.globalCompositeOperation = 'destination-over';
-  ctx.clearRect(0,0,300,300); // 캔버스를 비운다
-
-  ctx.fillStyle = 'rgba(0,0,0,0.4)';
-  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
-  ctx.save();
-  ctx.translate(150,150);
-
-  // 지구
-  var time = new Date();
-  ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
-  ctx.translate(105,0);
-  ctx.fillRect(0,-12,50,24); // Shadow
-  ctx.drawImage(earth,-12,-12);
-
-  // 달
-  ctx.save();
-  ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
-  ctx.translate(0,28.5);
-  ctx.drawImage(moon,-3.5,-3.5);
-  ctx.restore();
-
-  ctx.restore();
-
-  ctx.beginPath();
-  ctx.arc(150,150,105,0,Math.PI*2,false); // 지구 궤도
-  ctx.stroke();
-
-  ctx.drawImage(sun,0,0,300,300);
-}
-
- -

{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

-

시계 애니메이션

-

이 예제에서는, 현재 시각을 보여주는 움직이는 시계를 만듭니다.

-
function init(){
-  clock();
-  setInterval(clock,1000);
-}
-
-function clock(){
-  var now = new Date();
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.save();
-  ctx.clearRect(0,0,150,150);
-  ctx.translate(75,75);
-  ctx.scale(0.4,0.4);
-  ctx.rotate(-Math.PI/2);
-  ctx.strokeStyle = "black";
-  ctx.fillStyle = "white";
-  ctx.lineWidth = 8;
-  ctx.lineCap = "round";
-
-  // 시계판 - 시
-  ctx.save();
-  for (var i=0;i<12;i++){
-    ctx.beginPath();
-    ctx.rotate(Math.PI/6);
-    ctx.moveTo(100,0);
-    ctx.lineTo(120,0);
-    ctx.stroke();
-  }
-  ctx.restore();
-
-  // 시계판 - 분
-  ctx.save();
-  ctx.lineWidth = 5;
-  for (i=0;i<60;i++){
-    if (i%5!=0) {
-      ctx.beginPath();
-      ctx.moveTo(117,0);
-      ctx.lineTo(120,0);
-      ctx.stroke();
-    }
-    ctx.rotate(Math.PI/30);
-  }
-  ctx.restore();
-
-  var sec = now.getSeconds();
-  var min = now.getMinutes();
-  var hr  = now.getHours();
-  hr = hr>=12 ? hr-12 : hr;
-
-  ctx.fillStyle = "black";
-
-  // 시간 표시 - 시
-  ctx.save();
-  ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
-  ctx.lineWidth = 14;
-  ctx.beginPath();
-  ctx.moveTo(-20,0);
-  ctx.lineTo(80,0);
-  ctx.stroke();
-  ctx.restore();
-
-  // 시간 표시 - 분
-  ctx.save();
-  ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
-  ctx.lineWidth = 10;
-  ctx.beginPath();
-  ctx.moveTo(-28,0);
-  ctx.lineTo(112,0);
-  ctx.stroke();
-  ctx.restore();
-
-  // 시간 표시 - 초
-  ctx.save();
-  ctx.rotate(sec * Math.PI/30);
-  ctx.strokeStyle = "#D40000";
-  ctx.fillStyle = "#D40000";
-  ctx.lineWidth = 6;
-  ctx.beginPath();
-  ctx.moveTo(-30,0);
-  ctx.lineTo(83,0);
-  ctx.stroke();
-  ctx.beginPath();
-  ctx.arc(0,0,10,0,Math.PI*2,true);
-  ctx.fill();
-  ctx.beginPath();
-  ctx.arc(95,0,10,0,Math.PI*2,true);
-  ctx.stroke();
-  ctx.fillStyle = "rgba(0,0,0,0)";
-  ctx.arc(0,0,3,0,Math.PI*2,true);
-  ctx.fill();
-  ctx.restore();
-
-  ctx.beginPath();
-  ctx.lineWidth = 14;
-  ctx.strokeStyle = '#325FA2';
-  ctx.arc(0,0,142,0,Math.PI*2,true);
-  ctx.stroke();
-
-  ctx.restore();
-}
- -

{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

-

움직이는 파노라마 사진

-

이 예제에서는, 움직이는 파노라마 사진을 만듭니다. 사용할 그림은 위키피디어(Wikipedia)에서 구한 요세미티 국립공원입니다. 캔버스보다 큰 그림을 사용할 수도 있습니다.

-
var img = new Image();
-
-// 변수
-// 스크롤될 이미지, 방향, 속도를 바꾸려면 변수값을 바꾼다.
-
-img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
-var CanvasXSize = 800;
-var CanvasYSize = 200;
-var speed = 30; // 값이 작을 수록 빨라진다
-var scale = 1.05;
-var y = -4.5; // 수직 옵셋
-
-// 주요 프로그램
-
-var dx = 0.75;
-var imgW;
-var imgH;
-var x = 0;
-var clearX;
-var clearY;
-var ctx;
-
-img.onload = function() {
-    imgW = img.width*scale;
-    imgH = img.height*scale;
-    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // 캔버스보다 큰 이미지
-    if (imgW > CanvasXSize) { clearX = imgW; } // 캔버스보다 큰 이미지
-    else { clearX = CanvasXSize; }
-    if (imgH > CanvasYSize) { clearY = imgH; } // 캔버스보다 큰 이미지
-    else { clearY = CanvasYSize; }
-    // 캔버스 요소 얻기
-    ctx = document.getElementById('canvas').getContext('2d');
-    // 새로 그리기 속도 설정
-    return setInterval(draw, speed);
-}
-
-function draw() {
-    // 캔버스를 비운다
-    ctx.clearRect(0,0,clearX,clearY);
-    // 이미지가 캔버스보다 작거나 같다면 (If image is <= Canvas Size)
-    if (imgW <= CanvasXSize) {
-        // 재설정, 처음부터 시작
-        if (x > (CanvasXSize)) { x = 0; }
-        // 추가 이미지 그리기
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
-    }
-    // 이미지가 캔버스보다 크다면 (If image is > Canvas Size)
-    else {
-        // 재설정, 처음부터 시작
-        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
-        // 추가 이미지 그리기
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
-    }
-    // 이미지 그리기
-    ctx.drawImage(img,x,y,imgW,imgH);
-    // 움직임 정도
-    x += dx;
-}
-
-

예제에 사용된 {{HTMLElement("canvas")}}의 크기는 아래와 같다. 캔버스의 너비가 변수 CanvasXSize값과 같고, 캔버스의 높이는 변수 CanvasYSize값과 같다는 것에 주목하라.

-
<canvas id="canvas" width="800" height="200"></canvas>
-

Live sample

-

{{EmbedLiveSample("A_looping_panorama", "830", "230")}}

-

또 다른 예제들

-
-
- Gartic
-
- 다중 사용자 지원 그리기 놀이.
-
- Canvascape
-
- 3D 어드벤처 게임 (1인칭 슈팅).
-
- A basic ray-caster
-
- 키보드를 사용한 애니메이션 제어 방법에 대한 좋은 예제.
-
- canvas adventure
-
- 키보드 제어를 사용하는 또다른 좋은 예제.
-
- An interactive Blob
-
- 물방울 갖고 놀기.
-
- Flying through a starfield
-
- 별, 동그라미, 네모가 떠다니는 우주를 누벼라.
-
- iGrapher
-
- 주식 시장 자료 차트 예제.
-
-

이것도 보세요

- -

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Compositing", "Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas")}}

diff --git a/files/ko/web/html/canvas/tutorial/basic_usage/index.html b/files/ko/web/html/canvas/tutorial/basic_usage/index.html deleted file mode 100644 index f455563e87..0000000000 --- a/files/ko/web/html/canvas/tutorial/basic_usage/index.html +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: 캔버스(Canvas) 기본 사용법 -slug: Web/HTML/Canvas/Tutorial/Basic_usage -translation_of: Web/API/Canvas_API/Tutorial/Basic_usage ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}
- -
-

{{HTMLElement ( "canvas")}} {{Glossary ( "HTML")}} 엘리먼트를 살펴보는 것으로 이 튜토리얼을 시작해 보겠습니다. 이 페이지의 끝에서 캔버스 2D 컨텍스트를 설정하는 방법을 알게되고, 여러분의 브라우저에서 첫 번째 예제를 그리게 될 것입니다.

-
- -

<canvas> 요소

- -
<canvas id="tutorial" width="150" height="150"></canvas>
-
- -

{{HTMLElement ( "canvas")}}는 처음에는 src 및 alt 속성이 없다는 점만 제외하면 {{HTMLElement ( "img")}} 요소처럼 보입니다. 실제로 <canvas> 요소에는 {{htmlattrxref ( "width", "canvas")}}와 {{htmlattrxref ( "height", "canvas")}}의 두 속성만 있습니다. 이것들은 모두 선택사항이며 {{Glossary ( "DOM")}} 프로퍼티를 사용하여 설정할 수도 있습니다. width 및 height 속성을 지정하지 않으면 캔버스의 처음 너비는 300 픽셀이고 높이는 150 픽셀입니다. 요소는 {{Glossary ( "CSS")}}에 의해 임의로 크기를 정할 수 있지만 렌더링하는 동안 이미지는 레이아웃 크기에 맞게 크기가 조정됩니다. CSS 크기 지정이 초기 캔버스의 비율을 고려하지 않으면 왜곡되어 나타납니다 .

- -
-

노트: 만약 렌더링이 왜곡된 것처럼 보이는 경우 CSS를 사용하지 않고 <canvas> 속성에서 widthheight 속성을 명시적으로 지정하십시오.

-
- -

 

- -

id 속성(어트리뷰트)는  <canvas> 요소에 국한되지 않는 글로벌HTML 속성 (global HTML attributes )중 하나로,  모든 HTML 요소에 적용 ( class 등등)될 수 있습니다.  대체로 항상 id 속성을 사용해 주는것이 좋은데, 이는 스크립트 내에서 구분을 쉽게 해 줄 수 있기 때문입니다.

- -

<canvas>요소는 일반적인 이미지 ({{cssxref("margin")}}, {{cssxref("border")}}, {{cssxref("background")}}…) 처럼 스타일을 적용시킬 수 있습니다. 하지만 이 방법은 실제 캔버스 위에 그리는 것에는 영향을 끼치지 않습니다.  이 방법이 어떻게 사용되는지는 해당 챕터에서 확인 할 수 있습니다.  캔버스에 스타일링이 따로 지정 되있지 않았다면, 캔버스 스타일은 투명으로 설정되어있습니다.

- -
-

대체 콘텐츠

- -

<canvas> 요소는 {{HTMLElement("video")}}, {{HTMLElement("audio")}} 혹은 {{HTMLElement("picture")}}처럼 {{HTMLElement("img")}}와는 달리, 인터넷 익스플로러 9 이하의 버전이나 텍스트기반 브라우저 등과 같은, 캔버스를 지원하지 않는 오래된 브라우저들을 위한 대체 컨텐츠를 정의하기 쉽습니다. 여러분은 그러한 브라우저들을 위한 대체 컨텐츠를 제공해야 합니다.

- -

대체 컨텐츠를 제공하는 것은 매우 간단합니다. <canvas>태그 안에  대체 컨텐츠를 삽입합니다. <canvas>태그 를 지원하지 않는 브라우저는 컨테이너를 무시하고 컨테이너 내부의 대체 콘텐츠를 렌더링 합니다. <canvas>를 지원하는 브라우저는 컨테이너 내부의 내용을 무시하고 캔버스를 정상적으로 렌더링합니다.

- -

예를 들어, 캔버스 내용에 대한 텍스트 설명을 제공하거나 동적으로 렌더링 된 내용의 정적 이미지를 제공 할 수 있습니다. 이것은 다음과 같이 보일 수있습니다:

- -
<canvas id="stockGraph" width="150" height="150">
-  current stock price: $3.15 +0.15
-</canvas>
-
-<canvas id="clock" width="150" height="150">
-  <img src="images/clock.png" width="150" height="150" alt=""/>
-</canvas>
-
- -

사용자에게 캔버스를 지원하는 다른 브라우저를 사용하도록 하는 것은 캔버스를 해석하지 못하는 사용자에게 전혀 도움이 되지 않습니다. 유용한 대체 텍스트나 하위 DOM을 제공하는 것이 캔버스에 더 쉽게 접근할수 있도록 도움이 될 것입니다.

- -

</canvas> 태그 필수

- -

대체 컨텐츠가 제공되는 방식때문에, {{HTMLElement("img")}} 요소와 달리, {{HTMLElement("canvas")}} 요소는 닫는 태그(</canvas>)가 필요합니다. 닫는 태그가 없다면, 문서의 나머지 부분이 대체 컨텐츠로 간주되고 보이지 않을 것입니다.

- -

대체 컨텐츠가 필요하지 않다면, 단순히 <canvas id="foo" ...></canvas>가 모든 미지원 브라우저에서 완전하게 호환됩니다.

- -

렌더링 컨텍스트

- -

{{HTMLElement("canvas")}} 엘리먼트는 고정 크기의 드로잉 영역을 생성하고 하나 이상의 렌더링 컨텍스(rendering contexts)를 노출하여, 출력할 컨텐츠를 생성하고 다루게 됩니다. 본 튜토리얼에서는, 2D 렌더링 컨텍스트를 집중적으로 다룹니다. 다른 컨텍스트는 다른 렌더링 타입을 제공합니다. 예를 들어, WebGL은 OpenGL ES 을 기반으로 하는 3D 컨텍스트를 사용합니다.

- -

캔버스는 처음에 비어있습니다. 무언가를 표시하기 위해서, 어떤 스크립트가 랜더링 컨텍스트에 접근하여 그리도록 할 필요가 있습니다. {{HTMLElement("canvas")}} 요소는 {{domxref("HTMLCanvasElement.getContext", "getContext()")}} 메서드를 이용해서, 랜더링 컨텍스트와 (렌더링 컨텍스트의) 그리기 함수들을 사용할 수 있습니다.  getContext() 메서드는 렌더링 컨텍스트 타입을 지정하는 하나의 파라메터를 가집니다. 본 튜토리얼에서 다루고 있는 2D 그래픽의 경우, {{domxref("CanvasRenderingContext2D")}}을 얻기위해 "2d"로 지정합니다.

- -
var canvas = document.getElementById('tutorial');
-var ctx = canvas.getContext('2d');
-
- -

첫 번째 줄의 스크립트는  {{domxref ( "document.getElementById()")}} 메서드를 호출하여 {{HTMLElement ( "canvas")}} 요소를 표시할 DOM을 검색합니다.  요소가 있으면 getContext() 메서드를 사용하여 드로잉 컨텍스트에 액세스 할 수 있습니다.

- -
-

지원여부 검사

- -

대체 콘텐츠는 {{HTMLElement ( "canvas")}}를 지원하지 않는 브라우저에 표시됩니다. 스크립트 역시 간단하게 getContext() 메소드의 존재 여부를 테스트함으로써 프로그래밍 방식으로 지원하는지를 확인할 수 있습니다. 위의 코드 예제는 다음과 같이 될 수 있습니다:

- -
var canvas = document.getElementById('tutorial');
-
-if (canvas.getContext){
-  var ctx = canvas.getContext('2d');
-  // drawing code here
-} else {
-  // canvas-unsupported code here
-}
-
-
-
- -

템플릿 뼈대

- -

다음은 이후의 예제들에서 시작점으로 사용될 수 있는 가장 최소한의 템플릿입니다.

- -
-

알아두기: HTML 내에 스크립트(script)를 사용하는것은 좋은 연습 방법이 아닙니다. 다음의 예시에서는 간결하게 나타내기 위해 사용 한 것입니다.

-
- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta charset="utf-8"/>
-    <title>Canvas tutorial</title>
-    <script type="text/javascript">
-      function draw(){
-        var canvas = document.getElementById('tutorial');
-        if (canvas.getContext){
-          var ctx = canvas.getContext('2d');
-        }
-      }
-    </script>
-    <style type="text/css">
-      canvas { border: 1px solid black; }
-    </style>
-  </head>
-  <body onload="draw();">
-    <canvas id="tutorial" width="150" height="150"></canvas>
-  </body>
-</html>
-
- -

위 스크립트에 draw() 함수 문서가 호출되었는데, 이는 문서가 {{event("load")}} 이벤트를 수신하여 페이지 로딩이 완료될 때 한번 실행됩니다. 이 함수 혹은 이와 유사한 함수는, 페이지가 처음 로딩되는 한, {{domxref("WindowTimers.setTimeout", "window.setTimeout()")}}, {{domxref("WindowTimers.setInterval", "window.setInterval()")}}, 혹은 또 다른 이벤트 핸들러 등을 이용하여 호출될 수 있습니다.

- -

다음은 템플릿이 실제로 어떻게 실행되는지를 보여줍니다. 보이는 바와 같이, 초기에 blank 로 보여집니다.

- -

{{EmbedLiveSample("A_skeleton_template", 160, 160)}}

- -

기본 예제

- -

먼저 두 개의 직사각형을 그린 간단한 예제를 보도록하겠습니다. 그 중 하나는 투명도(alpha transparency)를가집니다. 나중에 이 예제가 어떻게 작동하는지 자세히 살펴 보겠습니다.

- -
<!DOCTYPE html>
-<html>
- <head>
-  <meta charset="utf-8"/>
-  <script type="application/javascript">
-    function draw() {
-      var canvas = document.getElementById("canvas");
-      if (canvas.getContext) {
-        var ctx = canvas.getContext("2d");
-
-        ctx.fillStyle = "rgb(200,0,0)";
-        ctx.fillRect (10, 10, 50, 50);
-
-        ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
-        ctx.fillRect (30, 30, 50, 50);
-      }
-    }
-  </script>
- </head>
- <body onload="draw();">
-   <canvas id="canvas" width="150" height="150"></canvas>
- </body>
-</html>
-
- -

이 예제는 다음과 같습니다.

- -

{{EmbedLiveSample("A_simple_example", 160, 160, "https://mdn.mozillademos.org/files/228/canvas_ex1.png")}}

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}

diff --git a/files/ko/web/html/canvas/tutorial/compositing/example/index.html b/files/ko/web/html/canvas/tutorial/compositing/example/index.html deleted file mode 100644 index e3d74f5220..0000000000 --- a/files/ko/web/html/canvas/tutorial/compositing/example/index.html +++ /dev/null @@ -1,293 +0,0 @@ ---- -title: 도형 합성 예제 -slug: Web/HTML/Canvas/Tutorial/Compositing/Example -tags: - - HTML5 - - 그래픽 - - 예제 - - 캔버스 -translation_of: Web/API/Canvas_API/Tutorial/Compositing/Example ---- -
{{CanvasSidebar}}
- -

이 샘플 프로그램에서는 여러 가지 도형 합성 방법을 보여줍니다. 출력은 다음과 같습니다:

- -

{{ EmbedLiveSample('도형_합성_예제', '100%', '7250', '', 'Web/HTML/Canvas/Tutorial/Compositing/Example') }}

- -

도형 합성 예제

- -

다음 코드에서는 프로그램의 나머지 부분에서 사용할 전역 값을 설정합니다.

- -
var canvas1 = document.createElement("canvas");
-var canvas2 = document.createElement("canvas");
-var gco = [ 'source-over','source-in','source-out','source-atop',
-            'destination-over','destination-in','destination-out','destination-atop',
-            'lighter', 'copy','xor', 'multiply', 'screen', 'overlay', 'darken',
-            'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light',
-            'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity'
-          ].reverse();
-var gcoText = [
-'기본 설정으로, 새로운 도형이 원래 도형 위에 그려집니다.',
-'새로운 도형이 원래 도형과 겹치는 부분에만 그려지며, 나머지는 투명하게 설정됩니다.',
-'새로운 도형이 원래 도형과 겹치지 않는 부분에만 그려집니다.',
-'새로운 도형이 원래 도형과 겹치는 부분에만 그려집니다.',
-'새로운 도형이 원래 도형 아래에 그려집니다.',
-'원래 도형 중 새로운 도형과 겹치는 부분이 유지되며, 나머지는 투명하게 설정됩니다.',
-'원래 도형 중 새로운 도형과 겹치지 않는 부분이 유지됩니다.',
-'원래 도형 중 새로운 도형과 겹치는 부분만 유지됩니다. 새로운 도형은 원래 도형 아래에 그려집니다.',
-'두 도형이 겹치는 곳의 색상이 두 색상값을 합한 값으로 결정됩니다.',
-'새로운 도형만 그려집니다.',
-'두 도형이 겹치는 곳이 투명하게 변하며, 나머지는 평범하게 그려집니다.',
-'위쪽 레이어의 픽셀값이 아래쪽 레이어의 해당하는 픽셀값과 곱해지며, 결과적으로 어두운 이미지가 생성됩니다.',
-'픽셀값을 뒤집고 곱한 다음 도로 뒤집습니다. 결과적으로 밝은 이미지가 생성됩니다(multiply의 반대).',
-'multiply와 screen의 조합입니다. 아래쪽 레이어의 어두운 부분은 더 어두워지고, 밝은 부분은 더 밝아집니다.',
-'두 레이어 중 어두운 픽셀값을 취합니다.',
-'두 레이어 중 밝은 픽셀값을 취합니다.',
-'아래쪽 레이어의 픽셀값을 위쪽 레이어의 뒤집힌 픽셀값으로 나눕니다.',
-'아래쪽 레이어의 뒤집힌 픽셀값을 위쪽 레이어의 픽셀값으로 나누고, 그 값을 도로 뒤집습니다.',
-'overlay와 같이 multiply와 screen의 조합이지만, 위아래 레이어의 순서가 바뀐 상태입니다.',
-'조금 더 부드러운 hard-light입니다. 완전한 검은색/흰색에서 무조건 완전한 검은색/흰색이 나오지 않습니다.',
-'한쪽 레이어의 픽셀값에서 다른 쪽 레이어의 픽셀값을 뺍니다. 빼는 순서는 결과값이 양수가 나오는 순서입니다.',
-'difference와 비슷하지만 대비가 덜합니다.',
-'아래쪽 레이어의 채도(chroma)와 명도(luma)를 보존하고 위쪽 레이어의 색상(hue)을 적용합니다.',
-'아래쪽 레이어의 색상과 명도를 보존하고 위쪽 레이어의 채도를 적용합니다.',
-'아래쪽 레이어의 명도를 보존하고 위쪽 레이어의 색상과 채도를 적용합니다.',
-'아래쪽 레이어의 색상과 채도를 보존하고 위쪽 레이어의 명도를 적용합니다.'
-          ].reverse();
-var width = 320;
-var height = 340;
-
- -

메인 프로그램

- -

페이지를 불러오고 나면 다음 코드에서 예제를 준비하고 실행합니다:

- -
window.onload = function() {
-    // lum in sRGB
-    var lum = {
-        r: 0.33,
-        g: 0.33,
-        b: 0.33
-    };
-    // 캔버스 크기 변경
-    canvas1.width = width;
-    canvas1.height = height;
-    canvas2.width = width;
-    canvas2.height = height;
-    lightMix()
-    colorSphere();
-    runComposite();
-    return;
-};
-
- -

또한 다음 코드의 runComposite()가 여러 가지 작업을 처리하며, 어려운 부분은 보조 함수를 사용합니다.

- -
function createCanvas() {
-    var canvas = document.createElement("canvas");
-    canvas.style.background = "url("+op_8x8.data+")";
-    canvas.style.border = "1px solid #000";
-    canvas.style.margin = "5px";
-    canvas.width = width/2;
-    canvas.height = height/2;
-    return canvas;
-}
-
-function runComposite() {
-    var dl = document.createElement("dl");
-    document.body.appendChild(dl);
-    while(gco.length) {
-        var pop = gco.pop();
-        var dt = document.createElement("dt");
-        dt.textContent = pop;
-        dl.appendChild(dt);
-        var dd = document.createElement("dd");
-        var p = document.createElement("p");
-        p.textContent = gcoText.pop();
-        dd.appendChild(p);
-
-        var canvasToDrawOn = createCanvas();
-        var canvasToDrawFrom = createCanvas();
-        var canvasToDrawResult = createCanvas();
-
-        var ctx = canvasToDrawResult.getContext('2d');
-        ctx.clearRect(0, 0, width, height)
-        ctx.save();
-        ctx.drawImage(canvas1, 0, 0, width/2, height/2);
-        ctx.globalCompositeOperation = pop;
-        ctx.drawImage(canvas2, 0, 0, width/2, height/2);
-        ctx.globalCompositeOperation = "source-over";
-        ctx.fillStyle = "rgba(0,0,0,0.8)";
-        ctx.fillRect(0, height/2 - 20, width/2, 20);
-        ctx.fillStyle = "#FFF";
-        ctx.font = "14px arial";
-        ctx.fillText(pop, 5, height/2 - 5);
-        ctx.restore();
-
-        var ctx = canvasToDrawOn.getContext('2d');
-        ctx.clearRect(0, 0, width, height)
-        ctx.save();
-        ctx.drawImage(canvas1, 0, 0, width/2, height/2);
-        ctx.fillStyle = "rgba(0,0,0,0.8)";
-        ctx.fillRect(0, height/2 - 20, width/2, 20);
-        ctx.fillStyle = "#FFF";
-        ctx.font = "14px arial";
-        ctx.fillText('기존 도형', 5, height/2 - 5);
-        ctx.restore();
-
-        var ctx = canvasToDrawFrom.getContext('2d');
-        ctx.clearRect(0, 0, width, height)
-        ctx.save();
-        ctx.drawImage(canvas2, 0, 0, width/2, height/2);
-        ctx.fillStyle = "rgba(0,0,0,0.8)";
-        ctx.fillRect(0, height/2 - 20, width/2, 20);
-        ctx.fillStyle = "#FFF";
-        ctx.font = "14px arial";
-        ctx.fillText('새로운 도형', 5, height/2 - 5);
-        ctx.restore();
-
-        dd.appendChild(canvasToDrawOn);
-        dd.appendChild(canvasToDrawFrom);
-        dd.appendChild(canvasToDrawResult);
-
-        dl.appendChild(dd);
-    }
-};
-
- -

보조 함수

- -

이 프로그램에서는 몇몇 보조 함수를 사용합니다.

- -
var lightMix = function() {
-    var ctx = canvas2.getContext("2d");
-    ctx.save();
-    ctx.globalCompositeOperation = "lighter";
-    ctx.beginPath();
-    ctx.fillStyle = "rgba(255,0,0,1)";
-    ctx.arc(100, 200, 100, Math.PI*2, 0, false);
-    ctx.fill()
-    ctx.beginPath();
-    ctx.fillStyle = "rgba(0,0,255,1)";
-    ctx.arc(220, 200, 100, Math.PI*2, 0, false);
-    ctx.fill()
-    ctx.beginPath();
-    ctx.fillStyle = "rgba(0,255,0,1)";
-    ctx.arc(160, 100, 100, Math.PI*2, 0, false);
-    ctx.fill();
-    ctx.restore();
-    ctx.beginPath();
-    ctx.fillStyle = "#f00";
-    ctx.fillRect(0,0,30,30)
-    ctx.fill();
-};
-
- -
var colorSphere = function(element) {
-    var ctx = canvas1.getContext("2d");
-    var width = 360;
-    var halfWidth = width / 2;
-    var rotate = (1 / 360) * Math.PI * 2; // per degree
-    var offset = 0; // scrollbar offset
-    var oleft = -20;
-    var otop = -20;
-    for (var n = 0; n <= 359; n ++) {
-        var gradient = ctx.createLinearGradient(oleft + halfWidth, otop, oleft + halfWidth, otop + halfWidth);
-        var color = Color.HSV_RGB({ H: (n + 300) % 360, S: 100, V: 100 });
-        gradient.addColorStop(0, "rgba(0,0,0,0)");
-        gradient.addColorStop(0.7, "rgba("+color.R+","+color.G+","+color.B+",1)");
-        gradient.addColorStop(1, "rgba(255,255,255,1)");
-        ctx.beginPath();
-        ctx.moveTo(oleft + halfWidth, otop);
-        ctx.lineTo(oleft + halfWidth, otop + halfWidth);
-        ctx.lineTo(oleft + halfWidth + 6, otop);
-        ctx.fillStyle = gradient;
-        ctx.fill();
-        ctx.translate(oleft + halfWidth, otop + halfWidth);
-        ctx.rotate(rotate);
-        ctx.translate(-(oleft + halfWidth), -(otop + halfWidth));
-    }
-    ctx.beginPath();
-    ctx.fillStyle = "#00f";
-    ctx.fillRect(15,15,30,30)
-    ctx.fill();
-    return ctx.canvas;
-};
-
- -
// HSV (1978) = H: Hue / S: Saturation / V: Value
-Color = {};
-Color.HSV_RGB = function (o) {
-    var H = o.H / 360,
-        S = o.S / 100,
-        V = o.V / 100,
-        R, G, B;
-    var A, B, C, D;
-    if (S == 0) {
-        R = G = B = Math.round(V * 255);
-    } else {
-        if (H >= 1) H = 0;
-        H = 6 * H;
-        D = H - Math.floor(H);
-        A = Math.round(255 * V * (1 - S));
-        B = Math.round(255 * V * (1 - (S * D)));
-        C = Math.round(255 * V * (1 - (S * (1 - D))));
-        V = Math.round(255 * V);
-        switch (Math.floor(H)) {
-            case 0:
-                R = V;
-                G = C;
-                B = A;
-                break;
-            case 1:
-                R = B;
-                G = V;
-                B = A;
-                break;
-            case 2:
-                R = A;
-                G = V;
-                B = C;
-                break;
-            case 3:
-                R = A;
-                G = B;
-                B = V;
-                break;
-            case 4:
-                R = C;
-                G = A;
-                B = V;
-                break;
-            case 5:
-                R = V;
-                G = A;
-                B = B;
-                break;
-        }
-    }
-    return {
-        R: R,
-        G: G,
-        B: B
-    };
-};
-
-var createInterlace = function (size, color1, color2) {
-    var proto = document.createElement("canvas").getContext("2d");
-    proto.canvas.width = size * 2;
-    proto.canvas.height = size * 2;
-    proto.fillStyle = color1; // top-left
-    proto.fillRect(0, 0, size, size);
-    proto.fillStyle = color2; // top-right
-    proto.fillRect(size, 0, size, size);
-    proto.fillStyle = color2; // bottom-left
-    proto.fillRect(0, size, size, size);
-    proto.fillStyle = color1; // bottom-right
-    proto.fillRect(size, size, size, size);
-    var pattern = proto.createPattern(proto.canvas, "repeat");
-    pattern.data = proto.canvas.toDataURL();
-    return pattern;
-};
-
-var op_8x8 = createInterlace(8, "#FFF", "#eee");
diff --git a/files/ko/web/html/canvas/tutorial/compositing/index.html b/files/ko/web/html/canvas/tutorial/compositing/index.html deleted file mode 100644 index 108c493d9d..0000000000 --- a/files/ko/web/html/canvas/tutorial/compositing/index.html +++ /dev/null @@ -1,106 +0,0 @@ ---- -title: 도형 합성 -slug: Web/HTML/Canvas/Tutorial/Compositing -tags: - - HTML5 - - 그래픽 - - 캔버스 -translation_of: Web/API/Canvas_API/Tutorial/Compositing ---- -

이전 페이지들에서 나온 모든 예제에서, 새로 그리는 도형은 언제나 이미 그려진 도형의 위에 그려졌습니다. 대부분의 상황에서는 이렇게 하는 것이 적절하지만, 도형을 합성하기 위한 순서를 제한하게 되는데,  globalCompositeOperation 속성을 설정함으로써 이러한 상태를 바꿀 수 있습니다.

- -

globalCompositeOperation

- -

기존 도형 뒤에 새로운 도형을 그릴 수 있을 뿐만 아니라, 도형의 일정 영역을 가려 보이지 않게 하거나 캔버스의 특정 부분을 지우는 (clearRect() 메소드는 사각형의 영역만을 지우지만, 이같은 제한도 없다.) 등의 효과를 얻을 수도 있습니다.

- -
-
globalCompositeOperation = type
-
새로운 도형을 그릴 때, 도형 합성 방법을 설정합니다. type은 다음 26종류의 합성 방법 중에서 선택할 수 있습니다.
-
- -

다음 예제의 코드를 확인하려면 도형 합성 예제를 확인해 주세요.

- -

{{ EmbedLiveSample('도형_합성_예제', 750, 6750, '', 'Web/HTML/Canvas/Tutorial/Compositing/Example') }}

- -

잘라내기 경로(Clipping path)

- -

 잘라내기 경로는 다른 캔버스 도형과 비슷하지만, 다른 도형에서 원하지 않는 부분을 가리는 가면과 같은 역할을 합니다. 오른쪽에 있는 그림을 보면 어떤 역할을 하는지 알 수 있을 것입니다. 붉은 별 모양이 잘라내기 경로입니다. 이 경로 밖에 있는 모든 것은 캔버스에 그려지지 않을 것입니다.

- -

잘라내기 경로와 위에서 살펴본  globalCompositeOperation 속성을 비교해 보면,   source-insource-atop에서 비슷한 효과가 보입니다. 이들과 잘라내기 경로와의 가장 중요한 차이점은, 잘라내기 경로 자체는 캔버스에 전혀 그려지지 않는다는 것입니다. 잘라내기 경로는 제한된 영역 안에서 여러 가지 도형을 그리는 데에 적합합니다.

- -

캔버스에 도형 그리기에서는 stroke()fill() 메소드만을 설명했었는데, clip()이라는 세 번째 메소드도 있습니다.

- -
-
clip()
-
현재 그려지는 경로를 현재 잘라내기 경로로 만듭니다.
-
- -

경로를 닫기 위해 closePath() 대신 clip()을 사용하고, 경로를 채우거나 윤곽선을 만드는 대신 잘라내기 경로로 만들 수 있습니다.

- -

{{HTMLElement("canvas")}} 요소의 초기 설정값으로써, 캔버스는 캔버스와 똑같은 크기의 잘라내기 경로를 가집니다. 크기가 똑같기 때문에 잘라내기 효과는 나타나지 않습니다.

- -

clip 예제

- -

다음 예제에서는 특정 영역의 별들만 보이도록 동그란 모양의 잘라내기 경로를 사용할 것입니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  ctx.fillRect(0,0,150,150);
-  ctx.translate(75,75);
-
-  // 동그란 모양의 잘라내기 경로를 생성한다
-  ctx.beginPath();
-  ctx.arc(0,0,60,0,Math.PI*2,true);
-  ctx.clip();
-
-  // 배경을 그린다
-  var lingrad = ctx.createLinearGradient(0,-75,0,75);
-  lingrad.addColorStop(0, '#232256');
-  lingrad.addColorStop(1, '#143778');
-
-  ctx.fillStyle = lingrad;
-  ctx.fillRect(-75,-75,150,150);
-
-  // 별을 그린다
-  for (var j=1;j<50;j++){
-    ctx.save();
-    ctx.fillStyle = '#fff';
-    ctx.translate(75-Math.floor(Math.random()*150),
-                  75-Math.floor(Math.random()*150));
-    drawStar(ctx,Math.floor(Math.random()*4)+2);
-    ctx.restore();
-  }
-
-}
-
-function drawStar(ctx,r){
-  ctx.save();
-  ctx.beginPath()
-  ctx.moveTo(r,0);
-  for (var i=0;i<9;i++){
-    ctx.rotate(Math.PI/5);
-    if(i%2 == 0) {
-      ctx.lineTo((r/0.525731)*0.200811,0);
-    } else {
-      ctx.lineTo(r,0);
-    }
-  }
-  ctx.closePath();
-  ctx.fill();
-  ctx.restore();
-}
-
- - - -

코드의 위쪽 몇 줄에서는 배경으로 캔버스 크기와 같은 검은색 네모를 그리고, 가운데로 원점을 옮깁니다. 그런 다음 호를 그리고 clip()을 사용하여 동그란 모양의 잘라내기 경로를 생성합니다. 캔버스 상태를 저장할 때 잘라내기 경로도 같이 저장됩니다. 이전의 잘라내기 경로를 보존하려면, 새로운 잘라내기 경로를 만들기 전에 캔버스 상태를 저장하면 됩니다.

- -

잘라내기 경로를 만든 후에 그려지는 모든 것들은, 그 경로의 안쪽에서만 보입니다. 이는 그 다음에 그려지는 선형 그라디언트에서 확실히 볼 수 있습니다. 이렇게 하고 나서, drawStar() 함수를 사용하여 위치와 크기가 모두 다른 50개의 별을 그립니다. 이 별들은 잘라내기 경로 안쪽에만 나타납니다.

- -

{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}

- -

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Transformations", "Web/Guide/HTML/Canvas_tutorial/Basic_animations")}}

diff --git a/files/ko/web/html/canvas/tutorial/drawing_shapes/index.html b/files/ko/web/html/canvas/tutorial/drawing_shapes/index.html deleted file mode 100644 index 09df4b829d..0000000000 --- a/files/ko/web/html/canvas/tutorial/drawing_shapes/index.html +++ /dev/null @@ -1,577 +0,0 @@ ---- -title: 캔버스(canvas)를 이용한 도형 그리기 -slug: Web/HTML/Canvas/Tutorial/Drawing_shapes -tags: - - Canvas - - 그래픽 - - 중급 - - 캔버스 - - 튜토리얼 -translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
- -
-

앞서 캔버스 환경 설정(canvas environment)을 완료 하였다면, 이제 어떻게 캔버스에 그릴수 있는지에 대하여 자세하게 알아봅시다. 이 글을 끝내고 난 후, 여러분은 어떻게 사각형, 삼각형, 선, 아치, 곡선 등 의 기본적인 도형을 그릴수 있는지 익히실 수 있을 것 입니다.  캔버스 위에 물체를 그릴 때에는 path를 사용하는것이 필수적이므로 우리는 이것이 어떻게 사용되는지 볼 것입니다.

-
- -

그리드

- -

드로잉을 시작 하기에 앞서, 캔버스 그리드 혹은 좌표공간 (coordinate space) 에 대하여 이야기 해보겠습니다. 이전 페이지에서 이야기 했던 HTML 골격(skeleton)는 가로 세로 각각 150 픽셀의 캔버스 요소를 가지고 있습니다. 오른쪽에 보시면, 캔버스와 기본 그리드가 놓인것을 보실 수 있습니다. 기본적으로 그리드의 1단위는 캔버스의 1픽셀과 같습니다. 이 그리드의 원점은 좌측상단의 (0,0) 입니다. 모든 요소들은 이 원점을 기준으로 위치됩니다. 그렇기 때문에, 파란 사각형의 좌측상단은 왼쪽에서 x 픽셀, 위에서 y 픽셀 떨어진 것이라 볼 수 있고, 이 사각형의 좌표는 (x,y)가 됩니다. 이 튜토리얼 후반부에서 어떻게 원점을 이동하며, 그리드를 회전하고 같은 비율로 확대/축소할 수 있는지 살펴볼 것이지만, 지금은 기본에 충실하도록 합시다.

- -

직사각형 그리기

- -

{{Glossary("SVG")}} 와는 다르게, {{HTMLElement("canvas")}}는 오직 하나의 원시적인 도형만을 제공합니다. 바로 직사각형 입니다. 다른 모든 도형들은 무조건 하나 혹은 하나 이상의 path 와 여러 점으로 이어진 선으로 만들어집니다. 다행히도, 우리는 여러 path drawing 함수(function)들을 통해 아주 어려운 도형들도 그릴수 있습니다.

- -

첫번째로, 직사각형을 봅시다. 캔버스 위에 직사각형을 그리는데에는 세가지 함수(function)가 있습니다:

- -
-
{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}
-
색칠된 직사각형을 그립니다.
-
{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}
-
직사각형 윤곽선을 그립니다.
-
{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}
-
특정 부분을 지우는 직사각형이며, 이 지워진 부분은 완전히 투명해집니다.
-
- -

각각의 세 함수는 모두 같은 변수를 가집니다. xy는 캔버스의 좌측상단에서 사각형의 (원점으로부터 상대적인) 위치를 뜻하며,  width 와 height는 사각형의 크기를 뜻하게 됩니다.

- -

전 페이지에서 보여드렸던 draw() 함수(function)를 이용하여 위의 세가지 함수를 아래의 예제에 적용해 보았습니다.

- -

직사각형 도형 예제

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    ctx.fillRect(25, 25, 100, 100);
-    ctx.clearRect(45, 45, 60, 60);
-    ctx.strokeRect(50, 50, 50, 50);
-  }
-}
- -

위 예제의 결과는 다음과 같습니다.

- -

{{EmbedLiveSample("Rectangular_shape_example", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}

- -

fillRect() 함수는 가로 세로 100 픽셀 사이즈의 검정 사각형을 그립니다. 이후 clearRect() 함수가 60x60 픽셀의 사각형 크기로 도형 중앙을 지우게 되고, strokeRect()은 이 빈 사각형 공간 안에 50x50 픽셀 사이즈의 윤곽선만 있는 사각형을 만들게 됩니다.

- -

다음 페이지에서, 우리는 clearRect()를 대신하는 두개의 함수에 대해 살펴보고, 만들어진 도형의 색이나 윤곽선의 스타일을 바꾸는 방법들에 대하여 알아보도록 하겠습니다.

- -

우리가 다음 섹션에서 보게될 path 함수와 다르게 세개의 직사각형 함수는 캔버스에 바로 그릴 수 있습니다.

- -

경로 그리기

- -

경로(path)는 직사각형 이외의 유일한 원시적인(primitive) 도형입니다. 경로는 점들의 집합이며, 선의 한 부분으로 연결되어 여러가지 도형, 곡선을 이루고 두께와 색을 나타내게 됩니다. 경로나 하위 경로(sub-path)는 닫힐 수 있습니다. 경로를 이용하여 도형을 만들 때에는 몇가지 추가적인 단계를 거쳐야 합니다:

- -
    -
  1. 경로를 생성합니다.
  2. -
  3. 그리기 명령어를 사용하여 경로상에 그립니다.
  4. -
  5. 경로가 한번 만들어졌다면, 경로를 렌더링 하기 위해서 윤곽선을 그리거나 도형 내부를 채울수 있습니다.
  6. -
- -

다음은 위의 단계들을 실행하기 위해 사용되는 함수입니다:

- -
-
{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}
-
새로운 경로를 만듭니다. 경로가 생성됬다면, 이후 그리기 명령들은 경로를 구성하고 만드는데 사용하게 됩니다.
-
Path 메소드 (Path methods)
-
물체를 구성할 때 필요한 여러 경로를 설정하는데 사용하는 함수입니다.
-
{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}
-
현재 하위 경로의 시작 부분과 연결된 직선을 추가합니다.
-
{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}
-
윤곽선을 이용하여 도형을 그립니다.
-
{{domxref("CanvasRenderingContext2D.fill", "fill()")}}
-
경로의 내부를 채워서 내부가 채워진 도형을 그립니다.
-
- -

경로를 만들기 위한 첫번째 단계는 beginPath() 메소드를 사용하는 것 입니다. 내부적으로, 경로는 도형을 이루는 하위경로(선, 아치 등)들의 집합으로 이루어져있습니다. 이 메소드가 호출될 때 마다, 하위 경로의 모음은 초기화되며, 우리는 새로운 도형을 그릴 수 있게 됩니다.

- -
참고:  현재 열린 path가  비어있는 경우 ( beginPath() 메소드를 사용한 직 후, 혹은캔버스를 새로 생성한 직후), 첫 경로 생성 명령은 실제 동작에 상관 없이 moveTo()로 여겨지게 됩니다. 그렇기 때문에 경로를 초기화한 직후에는 항상 명확하게 시작 위치를 설정해 두는것이 좋습니다.
- -

두번째 단계는 실제로 경로가 그려지는 위치를 설정하는 메소드를 호출하는 것 입니다. 이 내용에 대해서는 곧 보실수 있습니다.

- -

세번째 단계는 선택사항으로 closePath() 메소드를 호출하는 것 입니다. 이 메소드는 현재 점 위치와 시작점 위치를 직선으로 이어서 도형을 닫습니다. 이미 도형이 닫혔거나 한 점만 존재한다면, 이 메소드는 아무것도 하지 않습니다.

- -
참고:  fill() 메소드 호출 시, 열린 도형은 자동으로 닫히게 되므로  closePath()메소드를 호출하지 않아도 됩니다. 이것은 stroke() 메소드에는 적용되지 않습니다.
- -

삼각형 그리기

- -

예를 들어, 삼각형을 그리기 위한 코드는 다음과 같습니다:

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    ctx.beginPath();
-    ctx.moveTo(75, 50);
-    ctx.lineTo(100, 75);
-    ctx.lineTo(100, 25);
-    ctx.fill();
-  }
-}
-
- -

위 코드의 실행 결과는 다음과 같습니다:

- -

{{EmbedLiveSample("Drawing_a_triangle", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}

- -

펜(pen) 이동하기

- -

가장 유용한 함수중에 실제로 어떤 것도 그리지 않지만 위에서 언급한 경로의 일부가 되는  moveTo() 함수가 있습니다. 이는 펜이나 연필을 종이위에서 들어 옆으로 옮기는것이라고 보시면 됩니다.

- -
-
{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}
-
펜을  x와 y 로 지정된 좌표로 옮깁니다.
-
- -

캔버스가 초기화 되었거나 beginPath() 메소드가 호출되었을 때, 특정 시작점 설정을 위해 moveTo() 함수를 사용하는것이 좋습니다. 또한 moveTo()  함수는 연결되지 않은 경로를 그리는데에도 사용 할 수 있습니다. 아래의 스마일 아이콘을 봅시다.

- -

코드 snippet을 사용해하여 직접 시도하여 보세요. 앞에서 보았던 draw() 함수(function)를 붙혀넣기 해 보세요.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-     var ctx = canvas.getContext('2d');
-
-    ctx.beginPath();
-    ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
-    ctx.moveTo(110, 75);
-    ctx.arc(75, 75, 35, 0, Math.PI, false);  // Mouth (clockwise)
-    ctx.moveTo(65, 65);
-    ctx.arc(60, 65, 5, 0, Math.PI * 2, true);  // Left eye
-    ctx.moveTo(95, 65);
-    ctx.arc(90, 65, 5, 0, Math.PI * 2, true);  // Right eye
-    ctx.stroke();
-  }
-}
-
- -

결과는 다음과 같습니다:

- -

{{EmbedLiveSample("Moving_the_pen", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}

- -

 moveTo()를 사용한 코드라인을 지우면 연결된 선들을 확인 할 수 있습니다

- -
-

참고: arc() function에 대하여 더 알아보고 싶다면 아래의  {{anch("Arcs")}} 를 확인하세요.

-
- -

- -

직선을 그리기 위해서는 lineTo() 메소드를 사용할 수 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}
-
현재의 드로잉 위치에서 x와 y로 지정된 위치까지 선을 그립니다.
-
- -

이 메소드는 선의 끝점의 좌표가 되는 x와 y의 두개의 인자가 필요합니다. 시작점은 이전에 그려진 경로에 의해 결정 되며, 이전 경로의 끝점이 다음 그려지는 경로의 시작점이 됩니다. 또한 시작점은 moveTo() 메소드를 통해 변경될 수 있습니다.

- -

아래의 예시는 하나의 두 삼각형 (윤곽선 삼각형, 색칠된 삼각형)을 그립니다.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    // Filled triangle
-    ctx.beginPath();
-    ctx.moveTo(25, 25);
-    ctx.lineTo(105, 25);
-    ctx.lineTo(25, 105);
-    ctx.fill();
-
-    // Stroked triangle
-    ctx.beginPath();
-    ctx.moveTo(125, 125);
-    ctx.lineTo(125, 45);
-    ctx.lineTo(45, 125);
-    ctx.closePath();
-    ctx.stroke();
-  }
-}
-
- -

새로운 경로를 지정하기 위해 beginPath() 메소드를 먼저 실행합니다. 그 다음 moveTo() 메소드를 가지고 시작점을 원하는 위치로 새롭게 지정 해 줍니다. 다음은, 두선을 그어 삼각형의 두 면을 그려줍니다.

- -

{{EmbedLiveSample("Lines", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}

- -

여러분은 채워진 삼각형과 윤곽선 삼각형의 차이를 확인 하셨을 겁니다. 위에 언급했던 것 처럼, 경로가 채워지게 되면 그 도형은 자동으로 닫히게 되지만 윤곽선 삼각형에서는 그렇지 않기 때문입니다. 만약에 closePath() 메소드를 윤곽선 삼각형 코드에서 지운다면, 오직 두 선만 그려지게 되며 완벽한 삼각형으로 만들어지지 않습니다.

- -

호(arc)

- -

호나 원을 그리기위해서는 arc() 혹은 arcTo() 메소드를 사용합니다..

- -
-
{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}
-
(x, y) 위치에 원점을 두면서, 반지름 r을 가지고,  startAngle 에서 시작하여 endAngle 에서 끝나며 주어진 anticlockwise 방향으로 향하는 (기본값은 시계방향 회전) 호를 그리게 됩니다.
-
{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}
-
주어진 제어점들과 반지름으로 호를 그리고,  이전 점과 직선으로 연결합니다.
-
- -

arc 메소드의 여섯개의 매개변수에 대하여 좀 더 자세하게 알아봅시다: xy는 호를 그릴 때 필요한 원점 좌표입니다. 반지름(radius) 은 말 그대로 호의 반지름을 뜻합니다. startAngleendAngle 매개 변수는 원의 커브를 따라 호의 시작점과 끝점을 라디안 단위로 정의합니다. 이 변수들은 x축을 기준으로 계산됩니다. Boolean 값을 가지는 anticlockwise 변수는 true일 때 호를 반시계 방향으로 그리게 되며, 그렇지 않을 경우에는 시계 방향으로 그리게 됩니다.

- -
-

참고: arc 함수에서 각도는 각이 아닌 라디안 값을 사용합니다. 각도를 라디안으로 바꾸려면 다음의 자바스크립트(JavaScript) 코드를 사용하실 수 있습니다: radians = (Math.PI/180)*degrees.

-
- -

다음의 예제는 우리가 이제껏 봐 왔던 예제들 보다 약간 더 복잡합니다. 이 예제는 12가지의 다양한 각도로 채워진 각기 다른 호를 그립니다.

- -

두개의  for loops은 루프를 통해 호(arc)들의 행과 열을 읽기 위해 사용되었습니다. beginPath()를 사용해 각 호의 새로운 경로를 만듭니다. 코드 내에서, 각각의 매개변수들을 명확하게 보여주기 위해 변수로 정의 하였지만, 실제로 사용할때 꼭 필요한 것은 아닙니다.

- -

xy 좌표는 충분히 명확하게 표기되어야 합니다.  radius 와 startAngle은 고정되어 있습니다. endAngle는 처음 180도 (반원) 에서 시작하고 이후 매번 90도씩 증가하다가 마지막 열에서 완벽한 원을 그립니다.

- -

clockwise 매개 변수를 지정한 결과로 첫번째와 세번째 줄은 시계방향으로 원호들이 그려졌고 두번째와 네번째 줄에는 반시계방향의 원호들이 그려졌습니다. 마지막으로 if 문은 위 반쪽이 윤곽선으로, 아래 반쪽이 색으로 채워진 호들을 만들어 냅니다.

- -
-

참고: 이 예제는 다른 예제들 보다 더 큰사이즈의 캔버스가 필요합니다: 150 x 200 픽셀

-
- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    for (var i = 0; i < 4; i++) {
-      for (var j = 0; j < 3; j++) {
-        ctx.beginPath();
-        var x = 25 + j * 50; // x coordinate
-        var y = 25 + i * 50; // y coordinate
-        var radius = 20; // Arc radius
-        var startAngle = 0; // Starting point on circle
-        var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
-        var anticlockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
-
-        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
-
-        if (i > 1) {
-          ctx.fill();
-        } else {
-          ctx.stroke();
-        }
-      }
-    }
-  }
-}
-
- -

{{EmbedLiveSample("Arcs", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}

- -

베지어(Bezier) 곡선과 이차(Quadratic )곡선

- -

다음 경로 타입은 베지어 곡선 (Bézier curves)으로, 삼차(cubic)와 이차(quadric) 변수가 모두 가능합니다. 이 타입은 대게 복잡한 유기체적 형태 (organic shape)를 그리는데 사용됩니다.

- -
-
{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}
-
cp1xcp1y로 지정된 제어점을 사용하여 현재 펜의 위치에서 x와 y로 지정된 끝점까지 이차 베지어 곡선을 그립니다.
-
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}
-
(cp1x, cp1y) 및 (cp2x, cp2y)로 지정된 제어점을 사용하여 현재 펜 위치에서 xy로 지정된 끝점까지 삼차 베지어 곡선을 그립니다.
-
- -

오른쪽의 사진은 두 곡선의 차이를 가장 잘 설명해주고 있습니다. 이차 베지에 곡선은 시작점과 끝점 (파란색 점) 그리고 하나의 제어점 (control point, 빨간 점으로 표시)을 가지고 있지만, 삼차 베지에 곡선은 두개의 제어점을 사용하고 있습니다.

- -

두 메소드에 모두 사용되는 xy 변수는 모두 끝점의 좌표를 나타냅니다. 첫번째 제어점은 cp1x 와 cp1y 좌표로, 두번째 제어점은 cp2x 와 cp2y  좌표로 표시되었습니다.

- -

이차 및 삼차 베지어 곡선을 사용하는 것은 매우 어려울 수 있습니다. Adobe Illustrator와 같은 벡터 드로잉 소프트웨어와는 달리, 우리는 현재 수행중인 작업에 대해 직접적인 시각적 피드백을 받을 수 없기 때문입니다. 이런 점은 복잡한 모양을 그리기 어렵도록 합니다. 다음 예제에서 우리는 간단한 유기체적 형태만 그리도록 하겠지만, 여러분이 연습과 시간을 투자 하신다면, 이후에 더욱 복잡한 도형을 그릴수 있게 될 것입니다.

- -

이 예제는 아주 어려운 점은 없습니다. 두 경우 모두 연속된 곡선이 그려지면서 최종 모양이 완성됩니다.

- -

이차 베지에 곡선(Quadratic Bezier curves)

- -

이 예제는 여러개의 이차 베지어 곡선을 이용해 말풍선을 만들어 냅니다.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    // Quadratric curves example
-    ctx.beginPath();
-    ctx.moveTo(75, 25);
-    ctx.quadraticCurveTo(25, 25, 25, 62.5);
-    ctx.quadraticCurveTo(25, 100, 50, 100);
-    ctx.quadraticCurveTo(50, 120, 30, 125);
-    ctx.quadraticCurveTo(60, 120, 65, 100);
-    ctx.quadraticCurveTo(125, 100, 125, 62.5);
-    ctx.quadraticCurveTo(125, 25, 75, 25);
-    ctx.stroke();
-  }
-}
-
- -

{{EmbedLiveSample("Quadratic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}

- -

삼차 베지어 곡선 (Cubic Bezier curves)

- -

이 예제는 삼차 곡선을 이용하여 하트를 그립니다.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    // Cubic curves example
-    ctx.beginPath();
-    ctx.moveTo(75, 40);
-    ctx.bezierCurveTo(75, 37, 70, 25, 50, 25);
-    ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5);
-    ctx.bezierCurveTo(20, 80, 40, 102, 75, 120);
-    ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5);
-    ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25);
-    ctx.bezierCurveTo(85, 25, 75, 37, 75, 40);
-    ctx.fill();
-  }
-}
-
- -

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}

- -

직사각형

- -

직사각형을 캔버스에 직접 그리는 {{anch("직사각형 그리기")}}에서 본 세 가지 메소드 외에 rect() 메소드도 있습니다. 이 메소드는 현재 열린 패스에 직사각형 경로를 추가합니다.

- -
-
{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}
-
좌측상단이 (x, y)이고 폭과 높이가 widthheight인 직사각형을 그립니다.
-
- -

이 메소드가 실행되기 전에, (x,y) 매개변수를 가진 moveTo() 메소드가 자동으로 호출됩니다. 즉, 현재의 펜위치가 자동으로 기본 좌표로 초기화 됩니다.

- -

조합하기

- -

이제까지 이 페이지의 예제들은 각각의 도형마다 하나의 path 함수를 가지고 있었습니다. 하지만 도형을 만드는데에 사용되는 경로의 종류와 개수는 제한이 없습니다. 그렇기 때문에 이 마지막 예제에서는 모든 경로 함수를 합쳐 여러 게임 캐릭터들을 그려보도록 하겠습니다.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    roundedRect(ctx, 12, 12, 150, 150, 15);
-    roundedRect(ctx, 19, 19, 150, 150, 9);
-    roundedRect(ctx, 53, 53, 49, 33, 10);
-    roundedRect(ctx, 53, 119, 49, 16, 6);
-    roundedRect(ctx, 135, 53, 49, 33, 10);
-    roundedRect(ctx, 135, 119, 25, 49, 10);
-
-    ctx.beginPath();
-    ctx.arc(37, 37, 13, Math.PI / 7, -Math.PI / 7, false);
-    ctx.lineTo(31, 37);
-    ctx.fill();
-
-    for (var i = 0; i < 8; i++) {
-      ctx.fillRect(51 + i * 16, 35, 4, 4);
-    }
-
-    for (i = 0; i < 6; i++) {
-      ctx.fillRect(115, 51 + i * 16, 4, 4);
-    }
-
-    for (i = 0; i < 8; i++) {
-      ctx.fillRect(51 + i * 16, 99, 4, 4);
-    }
-
-    ctx.beginPath();
-    ctx.moveTo(83, 116);
-    ctx.lineTo(83, 102);
-    ctx.bezierCurveTo(83, 94, 89, 88, 97, 88);
-    ctx.bezierCurveTo(105, 88, 111, 94, 111, 102);
-    ctx.lineTo(111, 116);
-    ctx.lineTo(106.333, 111.333);
-    ctx.lineTo(101.666, 116);
-    ctx.lineTo(97, 111.333);
-    ctx.lineTo(92.333, 116);
-    ctx.lineTo(87.666, 111.333);
-    ctx.lineTo(83, 116);
-    ctx.fill();
-
-    ctx.fillStyle = 'white';
-    ctx.beginPath();
-    ctx.moveTo(91, 96);
-    ctx.bezierCurveTo(88, 96, 87, 99, 87, 101);
-    ctx.bezierCurveTo(87, 103, 88, 106, 91, 106);
-    ctx.bezierCurveTo(94, 106, 95, 103, 95, 101);
-    ctx.bezierCurveTo(95, 99, 94, 96, 91, 96);
-    ctx.moveTo(103, 96);
-    ctx.bezierCurveTo(100, 96, 99, 99, 99, 101);
-    ctx.bezierCurveTo(99, 103, 100, 106, 103, 106);
-    ctx.bezierCurveTo(106, 106, 107, 103, 107, 101);
-    ctx.bezierCurveTo(107, 99, 106, 96, 103, 96);
-    ctx.fill();
-
-    ctx.fillStyle = 'black';
-    ctx.beginPath();
-    ctx.arc(101, 102, 2, 0, Math.PI * 2, true);
-    ctx.fill();
-
-    ctx.beginPath();
-    ctx.arc(89, 102, 2, 0, Math.PI * 2, true);
-    ctx.fill();
-  }
-}
-
-// A utility function to draw a rectangle with rounded corners.
-
-function roundedRect(ctx, x, y, width, height, radius) {
-  ctx.beginPath();
-  ctx.moveTo(x, y + radius);
-  ctx.lineTo(x, y + height - radius);
-  ctx.arcTo(x, y + height, x + radius, y + height, radius);
-  ctx.lineTo(x + width - radius, y + height);
-  ctx.arcTo(x + width, y + height, x + width, y + height-radius, radius);
-  ctx.lineTo(x + width, y + radius);
-  ctx.arcTo(x + width, y, x + width - radius, y, radius);
-  ctx.lineTo(x + radius, y);
-  ctx.arcTo(x, y, x, y + radius, radius);
-  ctx.stroke();
-}
-
- -

결과 이미지는 다음과 같습니다:

- -

{{EmbedLiveSample("Making_combinations", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}

- -

이 예제는 보기보다 아주 간단하기 때문에 자세한 설명은 생략하겠습니다. 알아 두어야할 가장 중요한 부분은 fillStyle  코드와 사용된 유틸리티 함수 (roundedRect() 부분) 입니다. 유틸리티 함수를 사용하게 되면, 사용해야 할 코드의 양과 복잡함을 줄여주는데 도움을 줍니다.

- -

이 튜토리얼에서 나중에 fillStyle에 대하여 조금 더 자세하게 알아보도록 하겠지만, 지금은 경로의 채우는 색을 기본값(흑백)에서 바꾸었다가 다시 기본값으로 바꾸는 정도로만 사용하였습니다.

- -

Path2D 오브젝트 (Path2D objects)

- -

마지막 예제에서 보았 듯이, 캔버스에 객체를 그리는 일련의 경로와 그리기 명령이 있을 수 있습니다. 코드를 단순화하고 성능을 향상시키기 위해 최근 버전의 브라우저에서 사용할 수있는 {{domxref("Path2D")}} 객체를 사용하여 이러한 드로잉 명령을 캐시하거나 기록 할 수 있습니다. 이로써 여러분은 경로를 빠르게 다시 실행 시킬 수 있습니다.

- -

어떻게 Path2D object를 생성 할 수 있는지 확인해 봅시다:

- -
-
{{domxref("Path2D.Path2D", "Path2D()")}}
-
Path2D() 생성자는 새로운 Path2D 객체를 반환합니다. 선택적으로 다른 경로를 인수로 받거나(복사본을 생성), SVG 경로 데이터로 구성된 문자열을 받아서 객체로 반환합니다.
-
- -
new Path2D();     // empty path object
-new Path2D(path); // copy from another Path2D object
-new Path2D(d);    // path from SVG path data
- -

moveTo, rect, arc 혹은 quadraticCurveTo 등과 같은 모든 경로 메소드 (path methods)들은  Path2D 객체에서 사용 가능합니다.

- -

Path2D API는 또한 addPath 메소드를 사용하여 경로를 결합하는 방법을 추가합니다. 예를 들자면, 여러 요소를 사용하는 오브젝트를 만들 때 유용하게 사용 될 수 있습니다.

- -
-
{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}
-
옵션으로 변환 행렬(transformation matrix)을 사용하여 현재 경로에 경로를 추가합니다.
-
- -

Path2D 예제

- -

이 예제에서는, 직사각형과 원을 만들어 볼 것입니다. 나중에 사용할 것을 고려하여, 두 도형 모두 Path2D object로 저장 될 것입니다. 새로운 버전의 Path2D API에서는 여러 메소드들이 지금 사용하고있는 path가 아닌 Path2D object를 옵션으로 선택하여 사용 할 수 있도록 업데이트 되었습니다. 아래의 예제에서 보시면, stroke 와 fill 메소드가 오브젝트를 캔버스 위에 그리도록 path 변수와 함께 사용되었습니다.

- - - -
function draw() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    var rectangle = new Path2D();
-    rectangle.rect(10, 10, 50, 50);
-
-    var circle = new Path2D();
-    circle.moveTo(125, 35);
-    circle.arc(100, 35, 25, 0, 2 * Math.PI);
-
-    ctx.stroke(rectangle);
-    ctx.fill(circle);
-  }
-}
-
- -

{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}

- -

SVG paths 사용하기

- -

새로운 캔버스 path2D API 또다른 강력한 특징 중 하나는, 캔버스의 path를 초기화 하기 위해 SVG path data를 사용한다는 것입니다. 이는 path 데이터를 이동시키며, SVG와 canvas 에서 재사용 할 수 있도록 해줍니다. 

- -

path는 (M10 10) 점으로 이동한 다음, 수평하게 오른쪽으로 으로 80 포인트 (h 80)  만큼 이동합니다. 이후 수직으로 80포인트 (v 80) 내려간 다음, 80 포인트 왼쪽으로 (h -80) 수평하게 이동하고 다시 시작점 (z)으로 돌아갑니다. 예시는 이곳( Path2D constructor )에서 확인하실 수 있습니다.

- -
var p = new Path2D('M10 10 h 80 v 80 h -80 Z');
- -
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
diff --git a/files/ko/web/html/canvas/tutorial/finale/index.html b/files/ko/web/html/canvas/tutorial/finale/index.html deleted file mode 100644 index 1241680c5c..0000000000 --- a/files/ko/web/html/canvas/tutorial/finale/index.html +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: Finale -slug: Web/HTML/Canvas/Tutorial/Finale -tags: - - 그래픽 - - 캔버스 - - 튜토리얼 -translation_of: Web/API/Canvas_API/Tutorial/Finale ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Optimizing_canvas")}}
- -
-

축하합니다 Canvas 튜토리얼을 모두 끝마쳤습니다! 이 정보는 웹에서 더 나은 2D 그래픽을 만드는데 도움이 됩니다.

-
- -

더 많은 예시와 튜토리얼

- -

이 사이트에는 다양한 데모와 canvas에 대한 추가 설명이 있다.

- -
-
Codepen.io
-
프론트 엔드 개발자 playground 및 브라우저의 코드 편집기.
-
HTML5 Canvas Tutorials
-
대부분 canvas API의 예시
-
Game development
-
게임은 가장 인기있는 컴퓨터 활동 중 하나이다. 어떤 표준 규격의 웹 브라우저에서도 실행할 수 있는 더 나은 게임을 개발할 수 있도록 하기 위한 신기술이 끊임없이 등장하고 있다.
-
- -

기타 웹API

- -

이 API들는 canvas 및 그래픽으로 작업할 때 유용하다.

- -
-
WebGL
-
3D를 포함한 복잡한 그래픽 렌더링을 위한 고급 API.
-
SVG
-
확장 가능한 Vector Graphics는 이미지를 벡터(선)과 형태의 집합으로 묘사하여 이미지를 그리는 크기에 상관없이 원활하게 확장할 수 있다.
-
Web Audio
-
Web Audio API는 개발자들이 오디오 소스 선택, 오디오에 효과 추가, 오디오 시각화 생성, 공간 효과 적용(예: 패닝)등을 할 수 있도록 웹 상에서 오디오를 제어하기 위한 다양하고 좋은 시스템을 제공한다.
-
- -

문의사항

- -
-
Stack Overflow
-
"canvas"가 태그된 문의사항.
-
Comments about this tutorial – the MDN documentation community
-
이 튜토리얼에 대해 의견이 있으시거나 저희에게 감사를 표하고 싶다면 언제든지 연락해주세요!
-
- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Optimizing_canvas")}}

diff --git a/files/ko/web/html/canvas/tutorial/hit_regions_and_accessibility/index.html b/files/ko/web/html/canvas/tutorial/hit_regions_and_accessibility/index.html deleted file mode 100644 index e720af3159..0000000000 --- a/files/ko/web/html/canvas/tutorial/hit_regions_and_accessibility/index.html +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: 히트(Hit) 영역과 접근성 -slug: Web/HTML/Canvas/Tutorial/Hit_regions_and_accessibility -translation_of: Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility ---- -
{{CanvasSidebar}} {{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}
- -
{{HTMLElement("canvas")}} 엘리먼트는 비트맵이며 그려진 객체에 대한 정보는 제공하지 않습니다. 캔버스 컨텐츠는 시멘틱 HTML과 같은 접근성 도구에 노출되지 않습니다. 일반적으로 접근성을 위한 웹 사이트 또는 앱에서는 캔버스를 사용하지 않는 것이 좋습니다. 본 가이드라인은 접근성이 향상된 캔버스를 만드는데 도움이 될 것입니다.
- -

대체 컨텐츠

- -

<canvas> ... </ canvas> 태그 안의 내용은 캔버스 렌더링을 지원하지 않는 브라우저의 대체 컨텐츠로 사용할 수 있습니다. 또한 하위 DOM을 읽고 해석 할 수있는 보조 기술 사용자 (스크린 리더와 같은)에게도 매우 유용합니다. html5accessibility.com의 좋은 예가 이를 수행 할 수있는 방법을 보여줍니다.

- -
<canvas>
-  <h2>Shapes</h2>
-  <p>A rectangle with a black border.
-   In the background is a pink circle.
-   Partially overlaying the <a href="http://en.wikipedia.org/wiki/Circle" onfocus="drawCircle();" onblur="drawPicture();">circle</a>.
-   Partially overlaying the circle is a green
-   <a href="http://en.wikipedia.org/wiki/Square" onfocus="drawSquare();" onblur="drawPicture();">square</a>
-   and a purple <a href="http://en.wikipedia.org/wiki/Triangle" onfocus="drawTriangle();" onblur="drawPicture();">triangle</a>,
-   both of which are semi-opaque, so the full circle can be seen underneath.</p>
-</canvas> 
- -

Steve Faulkner의 NVDA가 이 예제를 어떻게 읽는지를 보여주는 동영상을 참고하시기 바랍니다.

- -

ARIA 규칙

- -

ARIA(Accessible Rich Internet Application)는 장애인이 사용자가 웹 콘텐츠 및 웹 응용 프로그램을보다 쉽게 사용할 수 있도록하는 방법을 정의합니다. ARIA 속성을 사용하여 캔버스 엘리먼트의 동작 및 용도를 설명 할 수 있습니다. 자세한 내용은 ARIAARIA 기술을 참조하십시오.

- -
<canvas id="button" tabindex="0" role="button" aria-pressed="false" aria-label="Start game"></canvas>
-
- -

히트(Hit) 영역

- -

마우스 좌표가 캔버스의 특정 영역 내에 있는지 여부는 문제를 해결하는 데 공통적입니다. 히트 영역 API를 사용하면 캔버스 영역을 정의 할 수 있으며 캔버스에 대화형 컨텐츠를 접근성 도구에 표시 할 수 있습니다. 히트 영역 API는 여러분이 히트 감지를 쉽게 할 수 있도록 하며 DOM 엘리먼트에 이벤트를 전달할 수 있도록 합니다. API에는 다음 세 가지 메소드가 있습니다 (현재 웹 브라우저에서는 아직 실험 중이며 브라우저 호환성 테이블을 확인하십시오).

- -
-
{{domxref("CanvasRenderingContext2D.addHitRegion()")}} {{experimental_inline}}
-
히트 영역을 캔버스에 추가합니다.
-
{{domxref("CanvasRenderingContext2D.removeHitRegion()")}} {{experimental_inline}}
-
캔버스에서 해당 id를 가진 히트 영역을 제거합니다.
-
{{domxref("CanvasRenderingContext2D.clearHitRegions()")}} {{experimental_inline}}
-
캔버스에서 모든 히트 영역을 제거합니다.
-
- -

경로에 히트 영역을 추가하고 {{domxref("MouseEvent.region")}} 속성을 확인하여 마우스가 영역을 히트하는지 테스트 할 수 있습니다.

- -
<canvas id="canvas"></canvas>
-<script>
-var canvas = document.getElementById('canvas');
-var ctx = canvas.getContext('2d');
-
-ctx.beginPath();
-ctx.arc(70, 80, 10, 0, 2 * Math.PI, false);
-ctx.fill();
-ctx.addHitRegion({id: 'circle'});
-
-canvas.addEventListener('mousemove', function(event) {
-  if (event.region) {
-    alert('hit region: ' + event.region);
-  }
-});
-</script>
- -

addHitRegion() 메소드는 control 옵션을 이용하여 이벤트를 엘리먼트(즉, 캔버스의 자식으로)로 전달합니다.

- -
ctx.addHitRegion({control: element});
- -

예를 들어 {{HTMLElement("input")}} 엘리먼트로 전달하는 데 유용 할 수 있습니다. codepen 데모를 참조하십시오.

- -

포커스 링(Focus rings)

- -

키보드로 작업 할 때 포커스 링은 페이지 탐색에 도움이되는 편리한 표시기입니다. 캔버스 드로잉에 포커스 링을 그리려면 drawFocusIfNeeded 속성을 사용할 수 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.drawFocusIfNeeded()")}} {{experimental_inline}}
-
지정된 엘리먼트에 포커스가있는 경우,이 메소드는 현재 경로 주위에 포커스 링을 그립니다.
-
- -

또한 scrollPathIntoView() 메서드를 사용하여 포커스가있는 경우 엘리먼트를 화면에 표시 할 수 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.scrollPathIntoView()")}} {{experimental_inline}}
-
현재 경로 또는 지정된 경로를 뷰로 스크롤합니다.
-
- -

See also

- - - -
{{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}
diff --git a/files/ko/web/html/canvas/tutorial/index.html b/files/ko/web/html/canvas/tutorial/index.html deleted file mode 100644 index 03077163aa..0000000000 --- a/files/ko/web/html/canvas/tutorial/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: 캔버스 튜토리얼 -slug: Web/HTML/Canvas/Tutorial -tags: - - Canvas - - Graphic - - Guide - - HTML - - HTML5 - - Intermediate - - Web -translation_of: Web/API/Canvas_API/Tutorial ---- -
{{CanvasSidebar}}
- -
- -
-

<canvas>는 HTML 요소 중 하나로서, 스크립트(보통은 자바스크립트)를 사용하여 그림을 그리는 데에 사용됩니다. 예를 들면, 그래프를 그리거나 사진을 합성하거나, 간단한(혹은 복잡할 수도 있는) 애니메이션을 만드는 데에 사용될 수 있습니다. 오른쪽에 보이는 이미지들은 앞으로 설명하게 될 <canvas>를 사용하여 만들 수 있는 것들의 일부입니다.

-
- -

이 튜토리얼은 <canvas> 요소를 사용하여 2D 그래픽을 어떻게 그리는지 기초부터 설명합니다. 예제들을 통하여 캔버스로 할 수 있는 것이 무엇인지 알려주며, 바로 사용할 수 있도록 코드도 제공합니다.

- -

<canvas>는 Apple의 Webkit에 처음 도입되어 Mac OS X 대시보드(Dashboard)에 사용되었고, 이후 다른 브라우저에도 구현되어 왔습니다. 현재 대부분의 주요 브라우저에서 지원됩니다.

- -

시작하기 전 알아두어야 할 것

- -

<canvas> 요소를 사용하는 것이 어려운 일은 아니지만, HTML자바스크립트에 대한 기본 지식을 갖추고 있어야 합니다. 몇몇 오래된 브라우저는 <canvas> 요소를 지원하지 않지만, 최근 버전의 주요 브라우저들은 모두 지원하고 있습니다. 캔버스의 크기는 300px * 150px (너비 * 높이)가 초기 설정값이며, HTML heightwidth 속성을 사용하여 바꿀 수 있습니다. 캔버스에 그림을 그리려면 자바스크립트 컨텍스트 오브젝트를 사용하며, 즉석에서 그림을 생성할 수 있습니다.

- -

튜토리얼 내용

- - - -

같이 보기

- - - - - -
{{ Next("Web/API/Canvas_API/Tutorial/Basic_usage") }}
diff --git a/files/ko/web/html/canvas/tutorial/optimizing_canvas/index.html b/files/ko/web/html/canvas/tutorial/optimizing_canvas/index.html deleted file mode 100644 index 460b5e893f..0000000000 --- a/files/ko/web/html/canvas/tutorial/optimizing_canvas/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: 캔버스 최적화 -slug: Web/HTML/Canvas/Tutorial/Optimizing_canvas -translation_of: Web/API/Canvas_API/Tutorial/Optimizing_canvas ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}
- -
-

{{HTMLElement("canvas")}} 엘리먼트는 웹에서 2D 그래픽을 렌더링하는 데 가장 널리 사용되는 도구 중 하나입니다. 그러나 웹 사이트와 앱이 Canvas API를 최대한으로 밀면 성능이 저하되기 시작합니다. 그러나 웹 사이트 및 앱이 Canvas API를 한계치까지 사용하면 성능이 저하되기 시작합니다. 이 글에서는 그래픽이 잘 동작하도록 보장하기 위해 캔버스 엘리먼트의 사용을 최적화하기위한 제안 사항을 제공합니다.

-
- -

성능 팁

- -

다음은 캔버스 성능을 개선하기 위한 팁 모음입니다.

- -

캔버스에 표시되지 않는 비슷한 원시 혹은 반복 객체를 미리 그려라

- -

만약 당신이 캔버스에 애니메이션 프레임을 그리면서 반복적인 작업이 발견된다면, 눈에 보이지 않는 숨겨진 캔버스 요소를 새로 만들고 그 캔버스에 미리 그려 넣는 방법을 고려하세요. 그렇게 하면 필요한 순간에 숨긴 캔버스에 그려진 이미지를 다시 주 캔버스 이미지에 그려넣어, 불필요한 렌더링 반복 작업을 줄여 성능 향상을 꾀할 수 있습니다.

- -
myCanvas.offscreenCanvas = document.createElement('canvas');
-myCanvas.offscreenCanvas.width = myCanvas.width;
-myCanvas.offscreenCanvas.height = myCanvas.height;
-
-myCanvas.getContext('2d').drawImage(myCanvas.offScreenCanvas, 0, 0);
- -

부동 소수점 좌표를 피하고 대신 정수를 사용하라.

- -

정수값들 없이 캔버스 상의 객체를 렌더링할 때 부가적인 픽셀 렌더링이 발생합니다.

- -
ctx.drawImage(myImage, 0.3, 0.5);
-
- -

이렇게하면 앤티 앨리어싱(anti-aliasing) 효과를 만들기 위해 브라우저에서 추가 연산을 수행해야합니다. 예제에서 이를 방지하려면 {{jsxref("Math.floor()")}}를 사용하여 {{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}} 호출에 사용된 모든 좌표를 반올림해야합니다.

- -

drawImage에서 이미지 크기를 조정하지 마라.

- -

{{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}에서 즉시 크기를 조정하지 말고 다양한 이미지 크기를 오프스크린(offscreen) 캔버스에 캐시하십시오.

- -

복잡한 장면에 여러 개의 레이어 캔버스를 사용하라.

- -

어플리케이션에서 일부 객체는 자주 이동하거나 변경해야하지만 다른 객체는 상대적으로 고정 위치에 남아야 합니다. 이런 상황에서 대응 가능한 최적화는 여러 <canvas> 엘리먼트를 사용하여 항목을 겹쳐서 만드는 것입니다.

- -

예를 들어 상단에 UI, 중간에 게임 플레이 액션, 하단에 정적 배경이있는 게임이 있다고 가정 해 보겠습니다. 이 경우 게임을 세 개의 <canvas> 레이어로 나눌 수 있습니다. UI는 사용자 입력시에만 변경되며 게임 플레이 레이어는 모든 새 프레임마다 변경되며 배경은 일반적으로 변경되지 않습니다.

- -
<div id="stage">
-  <canvas id="ui-layer" width="480" height="320"></canvas>
-  <canvas id="game-layer" width="480" height="320"></canvas>
-  <canvas id="background-layer" width="480" height="320"></canvas>
-</div>
-
-<style>
-  #stage {
-    width: 480px;
-    height: 320px;
-    position: relative;
-    border: 2px solid black;
-  }
-
-  canvas { position: absolute; }
-  #ui-layer { z-index: 3; }
-  #game-layer { z-index: 2; }
-  #background-layer { z-index: 1; }
-</style>
-
- -

큰 배경 이미지는 일반 CSS를 사용하라.

- -

정적 배경 이미지가있는 경우 CSS {{cssxref("background")}} 속성을 사용하여 일반 {{HTMLElement("div")}} 요소에 그릴 수 있으며 캔버스 아래에 배치 할 수 있습니다. 이렇게하면 모든 틱 마다 배경을 캔버스에 렌더링 할 필요가 없어집니다.

- -

CSS 변환(transform)을 사용하여 캔버스 크기 조정하라.

- -

CSS 변환(transform)은 GPU를 사용하기 때문에 더 빠릅니다. 가장 좋은 경우는 캔버스를 스케일링하지 않거나, 큰 캔버스를 축소하기보다 작은 캔버스를 확대하는 것입니다.

- -
var scaleX = window.innerWidth / canvas.width;
-var scaleY = window.innerHeight / canvas.height;
-
-var scaleToFit = Math.min(scaleX, scaleY);
-var scaleToCover = Math.max(scaleX, scaleY);
-
-stage.style.transformOrigin = '0 0'; //scale from top left
-stage.style.transform = 'scale(' + scaleToFit + ')';
-
- -

투명도를 사용하지 마라.

- -

응용 프로그램이 캔버스를 사용하고 투명 배경을 필요로하지 않는 경우 HTMLCanvasElement.getContext()를 사용하여 드로잉 컨텍스트를 만들 때 alpha 옵션을 false로 설정합니다. 이 정보는 렌더링을 최적화하기 위해 브라우저에서 내부적으로 사용할 수 있습니다.

- -
var ctx = canvas.getContext('2d', { alpha: false });
- -

추가 팁들

- -
    -
  • 배치 캔버스를 함께 호출합니다. 예를 들어 여러 개의 개별 선 대신 다각형 선을 그립니다.
  • -
  • 불필요한 캔버스 상태 변경을 피하십시오.
  • -
  • 화면의 차이만 렌더링하고 완전히 새로운 상태로 렌더링하지 마십시오.
  • -
  • 가능하면 {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}} 속성을 사용하지 마십시오.
  • -
  • 가능하면 텍스트 렌더링을 피하십시오.
  • -
  • 캔버스를 지우는 여러 가지 방법을 시도해보십시오 ({{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} vs. {{domxref("CanvasRenderingContext2D.fillRect", "fillRect()")}} vs. 캔버스 크기 조정).
  • -
  • 애니메이션에서는 {{domxref("window.setInterval()")}} 대신 {{domxref("window.requestAnimationFrame()")}}을 사용하십시오.
  • -
  • 무거운 물리 연산 라이브러리를 주의하십시오.
  • -
- -

See also

- - - -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}

diff --git a/files/ko/web/html/canvas/tutorial/using_images/index.html b/files/ko/web/html/canvas/tutorial/using_images/index.html deleted file mode 100644 index d9aae1c993..0000000000 --- a/files/ko/web/html/canvas/tutorial/using_images/index.html +++ /dev/null @@ -1,347 +0,0 @@ ---- -title: Using images -slug: Web/HTML/Canvas/Tutorial/Using_images -tags: - - Advanced - - Canvas - - Graphics - - HTML - - Tutorial -translation_of: Web/API/Canvas_API/Tutorial/Using_images ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations" )}}
- -
-

지금까지 우리는 Canvas를 가지고 스스로 도형을 만들고 그 도형에 스타일 적용 해 보았습니다. 이미지를 사용 하는 기능은 {{HTMLElement("canvas")}}의 가장 흥미로운 기능중 하나입니다. 이 기능은 게임의 그래픽 배경이나 혹은 다이나믹한 사진 도음들을 위해 사용 될 수 있습니다. PNG,GIF, JPEG등 브라우저에서 지원되는 포맷형태라면 어떠한 외부 이미지라도 사용 될 수 있습니다. 같은 페이지 소스에서 다른 Canvas요소로 만들어진 이미지 또한 사용할수 있습니다!

-
- -

이미지를 캔버스로 불러오는것은 기본적으로 두 단계를 필요로 합니다:

- -
    -
  1. {{domxref("HTMLImageElement")}} object를 참조하거나 다른 캔버스 요소를 소스로 사용합니다. 이는 URL을 가지고 이미지를 사용 할 수 있습니다.
  2. -
  3. drawImage() function을 사용하여 캔버스에 나타난 이미지 위에 그림을 그립니다.
  4. -
- -

이 과정이 어떻게 되는지 봅시다.

- -

이미지 불러오기

- -

canvas API는 아래의 데이터 타입을 이미지 소스로 사용 할 수 있습니다:

- -
-
{{domxref("HTMLImageElement")}}
-
{{HTMLElement("img")}} element와 마찬가지로, Image() constructor를 통해 만들어진 이미지입니다.
-
- -
-
{{domxref("SVGImageElement")}}
-
{{SVGElement("image")}} element 를 사용해 불러온 이미지입니다.
-
- - - -
-
{{domxref("HTMLVideoElement")}}
-
HTML {{HTMLElement("video")}} 요소를 이미지 소스로 사용하여 비디오의 현재 프레임을 이미지로 불러옵니다.
-
{{domxref("HTMLCanvasElement")}}
-
다른 {{HTMLElement("canvas")}} 요소를 이미지 소스로 사용합니다.
-
- -

이렇게 얻은 소스들은 {{domxref("CanvasImageSource")}}.를 사용하여 불러 올 수 있습니다.

- -

다음은 캔버스에 놓인 이미지를 사용하는 여러가지 방법입니다.

- -

같은 페이지의 이미지 사용하기

- -

우리는 다음을 사용하여 같은 페이지에 있는 캔버스나 이미지를 참고 할 수 있습니다.

- -
    -
  • {{domxref("document.images")}} 모음
  • -
  • {{domxref("document.getElementsByTagName()")}} 메소드
  • -
  • 사용 하고자 하는 특정한 이미지의 ID를 알고 있다면, {{domxref("document.getElementById()")}} 를 사용하여 특정한 이미지를 참고할 수 있습니다.
  • -
- -

다른 도메인의 이미지 사용하기

- -

Using the {{htmlattrxref("crossorigin", "img")}} attribute of an {{HTMLElement("img")}} element (reflected by the {{domxref("HTMLImageElement.crossOrigin")}} property), you can request permission to load an image from another domain for use in your call to drawImage(). If the hosting domain permits cross-domain access to the image, the image can be used in your canvas without tainting it; otherwise using the image will taint the canvas.

- -

다른 캔버스 요소 (canvas elements) 사용하기

- -

Just as with normal images, we access other canvas elements using either the {{domxref("document.getElementsByTagName()")}} or {{domxref("document.getElementById()")}} method. Be sure you've drawn something to the source canvas before using it in your target canvas.

- -

One of the more practical uses of this would be to use a second canvas element as a thumbnail view of the other larger canvas.

- -

처음부터 이미지 만들기

- -

Another option is to create new {{domxref("HTMLImageElement")}} objects in our script. To do this, you can use the convenient Image() constructor:

- -
var img = new Image();   // Create new img element
-img.src = 'myImage.png'; // Set source path
-
- -

When this script gets executed, the image starts loading.

- -

If you try to call drawImage() before the image has finished loading, it won't do anything (or, in older browsers, may even throw an exception). So you need to be sure to use the load event so you don't try this before the image has loaded:

- -
var img = new Image();   // Create new img element
-img.addEventListener('load', function() {
-  // execute drawImage statements here
-}, false);
-img.src = 'myImage.png'; // Set source path
-
- -

If you're only using one external image this can be a good approach, but once you need to track more than one we need to resort to something more clever. It's beyond the scope of this tutorial to look at image pre-loading tactics, but you should keep that in mind.

- -

데이터를 사용하여 이미지 불러오기Embedding an image via data: URL

- -

Another possible way to include images is via the data: url. Data URLs allow you to completely define an image as a Base64 encoded string of characters directly in your code.

- -
var img = new Image();   // Create new img element
-img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
-
- -

One advantage of data URLs is that the resulting image is available immediately without another round trip to the server. Another potential advantage is that it is also possible to encapsulate in one file all of your CSS, JavaScript, HTML, and images, making it more portable to other locations.

- -

Some disadvantages of this method are that your image is not cached, and for larger images the encoded url can become quite long.

- -

비디오 프레임 사용하기Using frames from a video

- -

You can also use frames from a video being presented by a {{HTMLElement("video")}} element (even if the video is not visible). For example, if you have a {{HTMLElement("video")}} element with the ID "myvideo", you can do this:

- -
function getMyVideo() {
-  var canvas = document.getElementById('canvas');
-  if (canvas.getContext) {
-    var ctx = canvas.getContext('2d');
-
-    return document.getElementById('myvideo');
-  }
-}
-
- -

This returns the {{domxref("HTMLVideoElement")}} object for the video, which, as covered earlier, is one of the objects that can be used as a CanvasImageSource.

- -

이미지 그리기

- -

Once we have a reference to our source image object we can use the drawImage() method to render it to the canvas. As we will see later the drawImage() method is overloaded and has several variants. In its most basic form it looks like this:

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}
-
Draws the CanvasImageSource specified by the image parameter at the coordinates (x, y).
-
- -
-

SVG images must specify a width and height in the root <svg> element.

-
- -

예제: 기본 선 그래프

- -

In the following example, we will use an external image as the backdrop for a small line graph. Using backdrops can make your script considerably smaller because we can avoid the need for code to generate the background. In this example, we're only using one image, so I use the image object's load event handler to execute the drawing statements. The drawImage() method places the backdrop at the coordinate (0, 0), which is the top-left corner of the canvas.

- - - -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var img = new Image();
-  img.onload = function() {
-    ctx.drawImage(img, 0, 0);
-    ctx.beginPath();
-    ctx.moveTo(30, 96);
-    ctx.lineTo(70, 66);
-    ctx.lineTo(103, 76);
-    ctx.lineTo(170, 15);
-    ctx.stroke();
-  };
-  img.src = 'https://mdn.mozillademos.org/files/5395/backdrop.png';
-}
- -

The resulting graph looks like this:

- -

{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}

- -

비례 크기 조정

- -

The second variant of the drawImage() method adds two new parameters and lets us place scaled images on the canvas.

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y, width, height)")}}
-
This adds the width and height parameters, which indicate the size to which to scale the image when drawing it onto the canvas.
-
- -

예제: 이미지를 타일처럼 배치

- -

In this example, we'll use an image as a wallpaper and repeat it several times on the canvas. This is done simply by looping and placing the scaled images at different positions. In the code below, the first for loop iterates over the rows. The second for loop iterates over the columns. The image is scaled to one third of its original size, which is 50x38 pixels.

- -
-

Note: Images can become blurry when scaling up or grainy if they're scaled down too much. Scaling is probably best not done if you've got some text in it which needs to remain legible.

-
- - - -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  var img = new Image();
-  img.onload = function() {
-    for (var i = 0; i < 4; i++) {
-      for (var j = 0; j < 3; j++) {
-        ctx.drawImage(img, j * 50, i * 38, 50, 38);
-      }
-    }
-  };
-  img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
-}
- -

The resulting canvas looks like this:

- -

{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}

- -

이미지 자르기

- -

The third and last variant of the drawImage() method has eight parameters in addition to the image source. It lets us cut out a section of the source image, then scale and draw it on our canvas.

- -
-
{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}
-
Given an image, this function takes the area of the source image specified by the rectangle whose top-left corner is (sx, sy) and whose width and height are sWidth and sHeight and draws it into the canvas, placing it on the canvas at (dx, dy) and scaling it to the size specified by dWidth and dHeight.
-
- -

To really understand what this does, it may help to look at the image to the right. The first four parameters define the location and size of the slice on the source image. The last four parameters define the rectangle into which to draw the image on the destination canvas.

- -

Slicing can be a useful tool when you want to make compositions. You could have all elements in a single image file and use this method to composite a complete drawing. For instance, if you want to make a chart you could have a PNG image containing all the necessary text in a single file and depending on your data could change the scale of your chart fairly easily. Another advantage is that you don't need to load every image individually, which can improve load performance.

- -

예제: 이미지 프레임 넣기

- -

In this example, we'll use the same rhino as in the previous example, but we'll slice out its head and composite it into a picture frame. The picture frame image is a 24-bit PNG which includes a drop shadow. Because 24-bit PNG images include a full 8-bit alpha channel, unlike GIF and 8-bit PNG images, it can be placed onto any background without worrying about a matte color.

- -
<html>
- <body onload="draw();">
-   <canvas id="canvas" width="150" height="150"></canvas>
-   <div style="display:none;">
-     <img id="source" src="https://mdn.mozillademos.org/files/5397/rhino.jpg" width="300" height="227">
-     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
-   </div>
- </body>
-</html>
-
- -
function draw() {
-  var canvas = document.getElementById('canvas');
-  var ctx = canvas.getContext('2d');
-
-  // Draw slice
-  ctx.drawImage(document.getElementById('source'),
-                33, 71, 104, 124, 21, 20, 87, 104);
-
-  // Draw frame
-  ctx.drawImage(document.getElementById('frame'), 0, 0);
-}
- -

We took a different approach to loading the images this time. Instead of loading them by creating new {{domxref("HTMLImageElement")}} objects, we included them as {{HTMLElement("img")}} tags directly in our HTML source and retrieved the images from those. The images are hidden from output by setting the CSS property {{cssxref("display")}} to none for those images.

- -

{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}

- -

The script itself is very simple. Each {{HTMLElement("img")}} is assigned an ID attribute, which makes them easy to select using {{domxref("document.getElementById()")}}. We then simply use drawImage() to slice the rhino out of the first image and scale him onto the canvas, then draw the frame on top using a second drawImage() call.

- -

아트 갤러리 예제

- -

In the final example of this chapter, we'll build a little art gallery. The gallery consists of a table containing several images. When the page is loaded, a {{HTMLElement("canvas")}}  element is inserted for each image and a frame is drawn around it.

- -

In this case, every image has a fixed width and height, as does the frame that's drawn around them. You could enhance the script so that it uses the image's width and height to make the frame fit perfectly around it.

- -

The code below should be self-explanatory. We loop through the {{domxref("document.images")}} container and add new canvas elements accordingly. Probably the only thing to note, for those not so familiar with the DOM, is the use of the {{domxref("Node.insertBefore")}} method. insertBefore() is a method of the parent node (a table cell) of the element (the image) before which we want to insert our new node (the canvas element).

- -
<html>
- <body onload="draw();">
-     <table>
-      <tr>
-        <td><img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"></td>
-      </tr>
-      <tr>
-        <td><img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"></td>
-        <td><img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"></td>
-      </tr>
-     </table>
-     <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150">
- </body>
-</html>
-
- -

And here's some CSS to make things look nice:

- -
body {
-  background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A;
-  margin: 10px;
-}
-
-img {
-  display: none;
-}
-
-table {
-  margin: 0 auto;
-}
-
-td {
-  padding: 15px;
-}
-
- -

Tying it all together is the JavaScript to draw our framed images:

- -
function draw() {
-
-  // Loop through all images
-  for (var i = 0; i < document.images.length; i++) {
-
-    // Don't add a canvas for the frame image
-    if (document.images[i].getAttribute('id') != 'frame') {
-
-      // Create canvas element
-      canvas = document.createElement('canvas');
-      canvas.setAttribute('width', 132);
-      canvas.setAttribute('height', 150);
-
-      // Insert before the image
-      document.images[i].parentNode.insertBefore(canvas,document.images[i]);
-
-      ctx = canvas.getContext('2d');
-
-      // Draw image to canvas
-      ctx.drawImage(document.images[i], 15, 20);
-
-      // Add frame
-      ctx.drawImage(document.getElementById('frame'), 0, 0);
-    }
-  }
-}
- -

{{EmbedLiveSample("Art_gallery_example", 725, 400)}}

- -

이미지 비율 습성(scaling behavior) 제어하기

- -

As mentioned previously, scaling images can result in fuzzy or blocky artifacts due to the scaling process. You can use the drawing context's {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} property to control the use of image smoothing algorithms when scaling images within your context. By default, this is true, meaning images will be smoothed when scaled. You can disable this feature like this:

- -
ctx.mozImageSmoothingEnabled = false;
-ctx.webkitImageSmoothingEnabled = false;
-ctx.msImageSmoothingEnabled = false;
-ctx.imageSmoothingEnabled = false;
-
- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_text", "Web/API/Canvas_API/Tutorial/Transformations")}}

diff --git "a/files/ko/web/html/canvas/tutorial/\353\263\200\355\230\225/index.html" "b/files/ko/web/html/canvas/tutorial/\353\263\200\355\230\225/index.html" deleted file mode 100644 index b93747b581..0000000000 --- "a/files/ko/web/html/canvas/tutorial/\353\263\200\355\230\225/index.html" +++ /dev/null @@ -1,286 +0,0 @@ ---- -title: 변형 (transformations) -slug: Web/HTML/Canvas/Tutorial/변형 -tags: - - CSS - - HTML - - 이동 - - 축소 - - 캔버스 - - 크기변형 - - 트랜스폼 - - 확대 -translation_of: Web/API/Canvas_API/Tutorial/Transformations ---- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}
- -
이 튜토리얼에 앞서 canvas 그리드좌표 공간에 대해 알아 보았습니다. 지금까지는 기본적인 그리드를 사용해 요구에 맞추어 전체 canvas의 크기를 바꾸기만 했습니다. Transformation(변형)에는 그리드를 원점에서 다른 위치로 옮기고, 회전하며, 확대·축소까지 하는 더 강력한 방법들이 있습니다.
- -

상태(state)의 저장과 복원

- -

변형(transformation) 메소드을 살펴보기 전에 두 가지 다른 메소드를 보도록 하지요. 일단 여러분이 더 복잡한 그림(drawings)을 그리기 시작하면 반드시 있어야 하는 메소드들입니다.

- -
-
{{domxref("CanvasRenderingContext2D.save", "save()")}}
-
canvas의 모든 상태를 저장합니다.
-
{{domxref("CanvasRenderingContext2D.restore", "restore()")}}
-
가장 최근에 저장된 canvas 상태를 복원합니다.
-
- -

Canvas 상태는 스택(stack)에 쌓입니다. save() 메소드가 호출될 때마다 현재 drawing 상태가 스택 위로 푸시됩니다. drawing 상태는 다음과 같이 이루어집니다.

- -
    -
  • 이전부터 적용된 변형(가령,  translate과 rotate와 scale 같은 – 아래의 내용을 보세요).
  • -
  • 다음 속성(attributes)의 현재 값:
    - {{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle")}}, {{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle")}}, {{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha")}}, {{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth")}}, {{domxref("CanvasRenderingContext2D.lineCap", "lineCap")}}, {{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin")}}, {{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit")}}, {{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset")}}, {{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX")}}, {{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY")}}, {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}}, {{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor")}}, {{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation")}}, {{domxref("CanvasRenderingContext2D.font", "font")}}, {{domxref("CanvasRenderingContext2D.textAlign", "textAlign")}}, {{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline")}}, {{domxref("CanvasRenderingContext2D.direction", "direction")}}, {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}}.
  • -
  • 현재의 clipping path, 이것은 다음 섹션에서 다루겠습니다.
  • -
- -

여러분은 원하는 만큼 save() 메소드를 많이 호출할 수 있습니다. restore() 메소드를 호출할 때마다 마지막으로 저장된 상태가 스택에서 튀어나와 저장된 설정들을 모두 복원시킵니다.

- -

save와 restore canvas 상태(state) 예제

- -

사각형 세트를 연이어 그려서 drawing 상태를 가진 스택이 어떻게 기능하는지를 이 예제에서 설명하고자 합니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  ctx.fillRect(0, 0, 150, 150);   // 기본 설정으로 사각형을 그리기
-  ctx.save();                  // 기본 상태를 저장하기
-
-  ctx.fillStyle = '#09F';      // 설정 변경하기
-  ctx.fillRect(15, 15, 120, 120); // 새로운 설정으로 사각형 그리기
-
-  ctx.save();                  // 현재 상태 저장하기
-  ctx.fillStyle = '#FFF';      // 설정 변경하기
-  ctx.globalAlpha = 0.5;
-  ctx.fillRect(30, 30, 90, 90);   // 새로운 설정으로 사각형 그리기
-
-  ctx.restore();               // 이전 상태 복원하기
-  ctx.fillRect(45, 45, 60, 60);   // 복원된 설정으로 사각형 그리기
-
-  ctx.restore();               // 초기 상태를 복원하기
-  ctx.fillRect(60, 60, 30, 30);   // 복원된 설정으로 사각형 그리기
-}
- - - -

첫 단계로 기본 설정으로 커다란 사각형을 그립니다. 그다음에는 이 상태를 저장하고 fill color를 바꿉니다. 그런 후에 두 번째이자 크기가 더 작은 파란 사각형을 그리고 그 상태를 저장합니다. 다시 한번 일부 drawing 설정을 바꾸고 세 번째 반투명한 흰 사각형을 그립니다. 

- -

여기까지는 이전 섹션에서 했던 작업과 매우 유사합니다. 하지만 일단 첫 번째 restore() 문을 호출하면 스택에서 맨 위의 drawing 상태가 지워지고 설정이 복원됩니다. 만일 save()로 저장하지 않았다면, 이전 상태로 되돌리기 위해 fill color와 투명도를 일일이 바꿔주어야 했을 것입니다. 두 속성이라서 간단했을 테지만 그보다 더 많았으면 코드가 급속히 길어졌겠지요. 

- -

두 번째 restore()문이 호출될 때, 초기 상태( 처음으로 save를 호출하기 전에 설정한 상태)가 복원되고 마지막 사각형은 한번 더 검게 그려집니다.

- -

{{EmbedLiveSample("A_save_and_restore_canvas_state_example", "180", "180", "https://mdn.mozillademos.org/files/249/Canvas_savestate.png")}}

- -

이동(translating)

- -

우리가 살펴볼 첫 번째 변형 메소드는 translate()입니다.  이 메소드는 그리드에서 canvas를 원점에서 다른 점으로 옮기는 데 사용됩니다. 

- -
-
{{domxref("CanvasRenderingContext2D.translate", "translate(x, y)")}}
-
그리드에서 canvas와 그 원점을 이동합니다. x는 이동시킬 수평 거리를 가리키고, y는 그리드에서 수직으로 얼마나 멀리 떨어지는지를 표시합니다. 
-
- -

변형하기 전에 canvas 상태를 저장하는 것이 좋습니다. 대다수의 경우, 원래 상태로 되돌리려고 역이동(reverse translation)을 시키는 것보다 restore 메소드를 호출하는 것이 더욱 간편합니다. 게다가 루프(loop) 안에서 이동하는 거라면 canvas 상태를 저장하고 복원하지 마세요. canvas 모서리 밖에서 그려지는 바람에 drawing의 일부를 잃어버리게 될지 모릅니다. 

- -

translate 예제

- -

이 예제에서 canvas 원점의 이동에 관한 좋은 점을 일부 보여드리겠습니다. translate() 메소드를 쓰지 않으면 모든 사각형은 같은 위치 (0, 0)에 그려집니다. 또한, translate() 메소드는 사각형을 fillRect() function에서 좌표를 일일이 적으며 바꾸지 않아도 어디에나 위치할 수 있게 해줍니다. 이렇게 하면 이해하고 사용하기가 좀 더 쉽습니다. 

- -

 draw() function에서 두 개의 루프(loops)를 이용해 fillRect() function을 아홉 번 호출합니다. 루프마다 canvas가 이동하고 사각형이 그려지며, canvas는 원래 상태로 되돌아 갑니다. fillRect()로의 호출이 translate()에 의지해 drawing 위치를 바꾸는데 어떻게 매번 같은 좌표를 사용하는지 눈여겨 보세요.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i = 0; i < 3; i++) {
-    for (var j = 0; j < 3; j++) {
-      ctx.save();
-      ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)';
-      ctx.translate(10 + j * 50, 10 + i * 50);
-      ctx.fillRect(0, 0, 25, 25);
-      ctx.restore();
-    }
-  }
-}
-
- - - -

{{EmbedLiveSample("A_translate_example", "160", "160", "https://mdn.mozillademos.org/files/9857/translate.png")}}

- -

회전(rotating)

- -

두 번째 변형 메소드는 rotate()입니다. canvas를 현재의 원점 둘레로 회전하는 데 사용합니다.

- -
-
{{domxref("CanvasRenderingContext2D.rotate", "rotate(angle)")}}
-
canvas를 현재 원점을 기준으로 라디안의 angle 숫자만큼 시계방향으로 회전시킵니다.
-
- -

회전의 중심점은 언제나 canvas 원점입니다. 중심점을 바꾸려면 translate() 메소드를 써서 canvas를 이동해야 합니다.

- -

rotate 예제

- -

이 예제는 사각형을 canvas 원점에서 먼저 회전하고 그다음에 translate()의 도움을 받아 사각형 자체의 중심에서 회전하는 데 rotate()를 사용합니다.

- -
-

주의: 각도의 단위는 도(degree)가 아닌 라디안(radian)입니다.   변환하려면 radians = (Math.PI/180)*degrees.를 사용합니다.

-
- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // 좌측 사각형, canvas 원점에서 회전하기
-  ctx.save();
-  // 파란 사각형
-  ctx.fillStyle = '#0095DD';
-  ctx.fillRect(30, 30, 100, 100);
-  ctx.rotate((Math.PI / 180) * 25);
-  // 회색 사각형
-  ctx.fillStyle = '#4D4E53';
-  ctx.fillRect(30, 30, 100, 100);
-  ctx.restore();
-
-  // 우측 사각형, 사각형 중심에서 회전하기
-  // 파란 사각형 그리기
-  ctx.fillStyle = '#0095DD';
-  ctx.fillRect(150, 30, 100, 100);
-
-  ctx.translate(200, 80); // 사각형 중심으로 이동하기
-                          // x = x + 0.5 * width
-                          // y = y + 0.5 * height
-  ctx.rotate((Math.PI / 180) * 25); // 회전
-  ctx.translate(-200, -80); // 예전 위치로 이동하기
-
-  // 회색 사각형 그리기
-  ctx.fillStyle = '#4D4E53';
-  ctx.fillRect(150, 30, 100, 100);
-}
-
- -

사각형 자체의 중심 둘레로 회전하려면 사각형의 중심으로 canvas를 옮기세요. 그런 후에 canvas를 회전하고, 그 canvas를 0, 0로 되돌려 이동합니다. 그다음에 사각형을 그리세요.

- - - -

{{EmbedLiveSample("A_rotate_example", "310", "210", "https://mdn.mozillademos.org/files/9859/rotate.png")}}

- -

확대·축소(scaling)

- -

다음 변형 메소드는 확대·축소(scaling)입니다. canvas 그리드에서 단위(units)를 키우거나 줄이는 데 사용합니다. 이는 벡터 모양과 비트맵(bitmaps) 요소를 축소하거나 확대해서 그리는 데 사용될 수 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.scale", "scale(x, y)")}}
-
canvas 단위를 수평으로 x만큼, 수직으로 y만큼 크기를 확대·축소합니다. 둘의 매개 변수는 실수입니다. 1.0보다 작은 값이면 단위의 크기를 축소하고, 1.0보다 큰 값이면 단위의 크기를 확대합니다. 값이 1.0이면 단위의 크기는 그대로입니다.
-
- -

음수를 이용해서 축을 대칭 시킬 수 있습니다(가령 translate(0,canvas.height); scale(1,-1);로 쓰는 것처럼 말이죠. 좌측 하단 모서리에 있는 원점을 이용한, 잘 알려진 카르테시안 좌표계(Cartesian coordinate)인 것이지요.

- -

기본적으로 canvas에서 하나의 단위는 정확히 1픽셀입니다. 예를 들어 0.5라는 확대·축소 비율을 적용한다면, 결과로 나오는 단위는 0.5 픽셀이 될 것이고, 고로 모양도 절반 크기로 그려질 것입니다. 이런 방식으로 크기 비율을 2.0으로 잡으면 단위 크기가 확대되어 하나의 단위는 이제 2픽셀이 되겠지요. 이 결과로 모양은 그만큼 2배로 커집니다.

- -

scale 예제

- -

마지막 예제로 다양한 확대·축소 비율을 이용해 모양을 그려보겠습니다.

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  // 간단하지만 확대·축소 비율을 적용한 사각형 그리기
-  ctx.save();
-  ctx.scale(10, 3);
-  ctx.fillRect(1, 10, 10, 10);
-  ctx.restore();
-
-  // 수평으로 대칭하기
-  ctx.scale(-1, 1);
-  ctx.font = '48px serif';
-  ctx.fillText('MDN', -135, 120);
-}
-
-
- - - -

{{EmbedLiveSample("A_scale_example", "160", "160", "https://mdn.mozillademos.org/files/9861/scale.png")}}

- -

변형(transforms)

- -

마지막으로, 다음의 변형(transform) 메소드들은 변환 행렬(transformation matrix)로 변경할 사항을 즉시 적용할 수 있습니다.

- -
-
{{domxref("CanvasRenderingContext2D.transform", "transform(a, b, c, d, e, f)")}}
-
인수(arguments)에 표시된 행렬을 이용해 현재 변환 행렬을 곱합니다. 변환 행렬은 다음과 같이 작성됩니다. 
- [acebdf001]\left[ \begin{array}{ccc} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{array} \right]
-
- -
-
만일 인수 중에 Infinity가 있다면, 변환 행렬은 예외 처리하는 메소드 대신에 반드시 infinite로 표시되어야 합니다.
-
- -

이 function의 매개 변수들은 다음과 같습니다.

- -
-
a (m11)
-
수평으로 확대·축소하기
-
b (m12)
-
수평으로 비스듬히 기울이기
-
c (m21)
-
수직으로 비스듬히 기울이기
-
d (m22)
-
수직으로 확대·축소하기
-
e (dx)
-
수평으로 이동하기
-
f (dy)
-
수직으로 이동하기
-
{{domxref("CanvasRenderingContext2D.setTransform", "setTransform(a, b, c, d, e, f)")}}
-
현재 변형 상태를 단위 행렬로 재설정하고 나서 동일한 인수로 transform() 메소드를 적용합니다. 이는 기본적으로 현재의 변형을 무효로 한 후에 명시된 변형으로 바뀌는데, 한번에 모든 게 진행됩니다.
-
{{domxref("CanvasRenderingContext2D.resetTransform", "resetTransform()")}}
-
현재 변형 상태를 단위 행렬로 재설정합니다. 이는 ctx.setTransform(1, 0, 0, 1, 0, 0); 호출과 같습니다.
-
- -

transform과 setTransform 예제

- -
function draw() {
-  var ctx = document.getElementById('canvas').getContext('2d');
-
-  var sin = Math.sin(Math.PI / 6);
-  var cos = Math.cos(Math.PI / 6);
-  ctx.translate(100, 100);
-  var c = 0;
-  for (var i = 0; i <= 12; i++) {
-    c = Math.floor(255 / 12 * i);
-    ctx.fillStyle = 'rgb(' + c + ', ' + c + ', ' + c + ')';
-    ctx.fillRect(0, 0, 100, 10);
-    ctx.transform(cos, sin, -sin, cos, 0, 0);
-  }
-
-  ctx.setTransform(-1, 0, 0, 1, 100, 100);
-  ctx.fillStyle = 'rgba(255, 128, 255, 0.5)';
-  ctx.fillRect(0, 50, 100, 100);
-}
-
- - - -

{{EmbedLiveSample("Example_for_transform_and_setTransform", "230", "280", "https://mdn.mozillademos.org/files/255/Canvas_transform.png")}}

- -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}

diff --git a/files/ko/web/html/element/command/index.html b/files/ko/web/html/element/command/index.html deleted file mode 100644 index 8353384f2a..0000000000 --- a/files/ko/web/html/element/command/index.html +++ /dev/null @@ -1,111 +0,0 @@ ---- -title: -slug: Web/HTML/Element/command -tags: - - HTML - - Obsolete - - Reference - - Web -translation_of: Web/HTML/Element/command ---- -
{{obsolete_header()}}
- -

The HTML Command element (<command>) represents a command which the user can invoke. Commands are often used as part of a context menu or toolbar. However, they can be used anywhere on the page.

- -
-

The <command> element is included in the W3C specification, but not in the WHATWG specification, and browser support is nonexistent. You should use the {{HTMLElement("menuitem")}} element instead, although that element is non-standard and only supported in Edge and Firefox.

-
- - - - - - - - - - - - - - - - - - - - - - - - -
Content categoriesFlow content, phrasing content, metadata content.
Permitted contentNone, it is an {{Glossary("empty element")}}.
Tag omissionThe start tag is mandatory, but, as it is a void element, the use of an end tag is forbidden.
Permitted parent elements{{HTMLElement("colgroup")}} only, though it can be implicitly defined as its start tag is not mandatory. The {{HTMLElement("colgroup")}} must not have a {{HTMLElement("span")}} as child.
DOM interface{{domxref("HTMLCommandElement")}}
- -

Attributes

- -

This element includes the global attributes.

- -
-
{{htmlattrdef("checked")}}
-
Indicates whether the command is selected. Must be omitted unless the type attribute is checkbox or radio.
-
{{htmlattrdef("disabled")}}
-
Iindicates that the command is not available.
-
{{htmlattrdef("icon")}}
-
Gives a picture which represents the command.
-
{{htmlattrdef("label")}}
-
The name of the command as shown to the user.
-
{{htmlattrdef("radiogroup")}}
-
This attribute gives the name of the group of commands, with a type of radio, that will be toggled when the command itself is toggled. This attribute must be omitted unless the type attribute is radio.
-
{{htmlattrdef("type")}}
-
This attribute indicates the kind of command. This can be one of three values. -
    -
  • -

    command or empty which is the default state and indicates that this is a normal command.

    -
  • -
  • -

    checkbox indicates that the command can be toggled using a checkbox.

    -
  • -
  • -

    radio indicates that the command can be toggled using a radio button.

    -
  • -
-
-
- -

Examples

- -
<command type="command" label="Save"
-    icon="icons/save.png" onclick="save()">
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', '#commands')}}{{Spec2('HTML WHATWG')}} 
{{SpecName('HTML5 W3C', 'semantics.html#the-command-element', '<command>')}}{{Spec2('HTML5 W3C')}} 
- -

Browser compatibility

- - - -

{{Compat("html.elements.command")}}

- -

{{ HTMLRef }}

diff --git a/files/ko/web/html/element/element/index.html b/files/ko/web/html/element/element/index.html deleted file mode 100644 index be045093a5..0000000000 --- a/files/ko/web/html/element/element/index.html +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: -slug: Web/HTML/Element/element -translation_of: Web/HTML/Element/element ---- -
{{HTMLRef}}{{obsolete_header}}
- -

The obsolete HTML <element> element was part of the Web Components specification; it was intended to be used to define new custom DOM elements. It was removed in favor of a JavaScript-driven approach for creating new custom elements.

- -
-

Note: This element has been removed from the specification. See this for more information from the editor of the specification.

-
- - - - - - - - - - - - - - - - - - - - - - - - -
Content categoriesTransparent content.
Permitted content???
Tag omission{{no_tag_omission}}
Permitted parent elements???
DOM interface{{domxref("HTMLElement")}}
- -

Attributes

- -

This element includes the global attributes.

- -

Specifications

- -

The <element> element was formerly in a draft specification of Custom Elements but it has been removed.

- -

Browser compatibility

- - - -

{{Compat("html.elements.element")}}

- -

See also

- -
    -
  • Web components: {{HTMLElement("content")}}, {{HTMLElement("shadow")}}, {{HTMLElement("slot")}}, and {{HTMLElement("template")}}
  • -
diff --git a/files/ko/web/html/global_attributes/class/index.html b/files/ko/web/html/global_attributes/class/index.html new file mode 100644 index 0000000000..d0aa89b606 --- /dev/null +++ b/files/ko/web/html/global_attributes/class/index.html @@ -0,0 +1,64 @@ +--- +title: class +slug: Web/HTML/Global_attributes/클래스 +tags: + - Global attributes + - HTML + - Reference +translation_of: Web/HTML/Global_attributes/class +--- +
{{HTMLSidebar("Global_attributes")}}
+ +

class 전역 특성은 공백으로 구분한 요소 클래스의 목록으로, 대소문자를 구분하지 않습니다. 클래스는 CSS나 JavaScript에서 클래스 선택자나 DOM 메서드의 {{domxref("document.getElementsByClassName()")}}과 같은 메서드를 통해 요소에 접근할 수 있는 방법입니다.

+ +
{{EmbedInteractiveExample("pages/tabbed/attribute-class.html","tabbed-standard")}}
+ + + +

명세서가 클래스의 명칭에 대한 요구사항을 제시하지는 않았지만, 웹 개발자는 해당 요소의 표시 방식보다는 요소의 의미와 목적을 설명하는 명칭을 사용하는 것이 좋습니다. 예를 들어, 클래스 특성을 가진 어떤 요소가 기울임꼴로 나타난다 하더라도, 클래스 이름은 "기울임꼴"을 설명하는 것이 아니라 요소를 설명하는 것입니다. 의미를 가진 이름은 해당 페이지의 표현 방식이 바뀌더라도 논리성을 잃지 않습니다.

+ +

명세

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('HTML WHATWG', "elements.html#classes", "class")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "elements.html#classes", "class")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "elements.html#classes", "class")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName('HTML WHATWG')}}. From {{SpecName('HTML4.01')}}, class is now a true global attribute.
{{SpecName('HTML4.01', "struct/global.html#h-7.5.2", "class")}}{{Spec2('HTML4.01')}}Supported on all elements but {{HTMLElement("base")}}, {{HTMLElement("basefont")}}, {{HTMLElement("head")}}, {{HTMLElement("html")}}, {{HTMLElement("meta")}}, {{HTMLElement("param")}}, {{HTMLElement("script")}}, {{HTMLElement("style")}}, and {{HTMLElement("title")}}.
+ +

브라우저 호환성

+ + + +

{{Compat("html.global_attributes.class")}}

+ +

같이 보기

+ +
    +
  • 모든 전역 특성.
  • +
  • {{domxref("element.className")}}
  • +
  • {{domxref("element.classList")}}
  • +
diff --git a/files/ko/web/html/global_attributes/dropzone/index.html b/files/ko/web/html/global_attributes/dropzone/index.html deleted file mode 100644 index 15d26aad15..0000000000 --- a/files/ko/web/html/global_attributes/dropzone/index.html +++ /dev/null @@ -1,53 +0,0 @@ ---- -title: dropzone -slug: Web/HTML/Global_attributes/dropzone -tags: - - Deprecated - - Global attributes - - HTML - - Reference -translation_of: Web/HTML/Global_attributes/dropzone ---- -
{{HTMLSidebar("Global_attributes")}}{{deprecated_header}}
- -

dropzone 전역 특성은 열거형 속성으로 한 요소에 어떤 형식의 컨텐츠가 Drag and Drop API를 이용해 드랍될 수 있는지를 나타냅니다. 이 속성은 다음의 값을 가질 수 있습니다:

- -
    -
  • copy, 드랍할 때 드래그되는 요소의 사본이 생성됨을 나타냅니다.
  • -
  • move, 드래그되는 요소가 새로운 위치로 이동할 것임을 나타냅니다.
  • -
  • link, 드래그되는 데이터에 대한 링크가 생성될 것임을 나타냅니다.
  • -
- -

명세

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "interaction.html#the-dropzone-attribute", "dropzone")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "editing.html#the-dropzone-attribute", "dropzone")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, initial definition
- -

브라우저 호환성

- - - -

{{Compat("html.global_attributes.dropzone")}}

- -

같이 보기

- - diff --git "a/files/ko/web/html/global_attributes/\355\201\264\353\236\230\354\212\244/index.html" "b/files/ko/web/html/global_attributes/\355\201\264\353\236\230\354\212\244/index.html" deleted file mode 100644 index d0aa89b606..0000000000 --- "a/files/ko/web/html/global_attributes/\355\201\264\353\236\230\354\212\244/index.html" +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: class -slug: Web/HTML/Global_attributes/클래스 -tags: - - Global attributes - - HTML - - Reference -translation_of: Web/HTML/Global_attributes/class ---- -
{{HTMLSidebar("Global_attributes")}}
- -

class 전역 특성은 공백으로 구분한 요소 클래스의 목록으로, 대소문자를 구분하지 않습니다. 클래스는 CSS나 JavaScript에서 클래스 선택자나 DOM 메서드의 {{domxref("document.getElementsByClassName()")}}과 같은 메서드를 통해 요소에 접근할 수 있는 방법입니다.

- -
{{EmbedInteractiveExample("pages/tabbed/attribute-class.html","tabbed-standard")}}
- - - -

명세서가 클래스의 명칭에 대한 요구사항을 제시하지는 않았지만, 웹 개발자는 해당 요소의 표시 방식보다는 요소의 의미와 목적을 설명하는 명칭을 사용하는 것이 좋습니다. 예를 들어, 클래스 특성을 가진 어떤 요소가 기울임꼴로 나타난다 하더라도, 클래스 이름은 "기울임꼴"을 설명하는 것이 아니라 요소를 설명하는 것입니다. 의미를 가진 이름은 해당 페이지의 표현 방식이 바뀌더라도 논리성을 잃지 않습니다.

- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('HTML WHATWG', "elements.html#classes", "class")}}{{Spec2('HTML WHATWG')}}No change from latest snapshot, {{SpecName('HTML5.1')}}
{{SpecName('HTML5.1', "elements.html#classes", "class")}}{{Spec2('HTML5.1')}}Snapshot of {{SpecName('HTML WHATWG')}}, no change from {{SpecName('HTML5 W3C')}}
{{SpecName('HTML5 W3C', "elements.html#classes", "class")}}{{Spec2('HTML5 W3C')}}Snapshot of {{SpecName('HTML WHATWG')}}. From {{SpecName('HTML4.01')}}, class is now a true global attribute.
{{SpecName('HTML4.01', "struct/global.html#h-7.5.2", "class")}}{{Spec2('HTML4.01')}}Supported on all elements but {{HTMLElement("base")}}, {{HTMLElement("basefont")}}, {{HTMLElement("head")}}, {{HTMLElement("html")}}, {{HTMLElement("meta")}}, {{HTMLElement("param")}}, {{HTMLElement("script")}}, {{HTMLElement("style")}}, and {{HTMLElement("title")}}.
- -

브라우저 호환성

- - - -

{{Compat("html.global_attributes.class")}}

- -

같이 보기

- -
    -
  • 모든 전역 특성.
  • -
  • {{domxref("element.className")}}
  • -
  • {{domxref("element.classList")}}
  • -
diff --git a/files/ko/web/html/html5/index.html b/files/ko/web/html/html5/index.html deleted file mode 100644 index 2d64ce56d6..0000000000 --- a/files/ko/web/html/html5/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: HTML5 -slug: Web/HTML/HTML5 -translation_of: Web/Guide/HTML/HTML5 ---- -

HTML5는 HTML를 정의하는 표준화에 있어서의 최신 표준 명세입니다. HTML5 명세는 아직도 표준 지정이 완료되지 않았고 변경이 계속 진행 중입니다. 하지만, Mozilla 및 다른 웹 브라우저 벤더는 이미 사양 중  많은 부분에 대한 구현을 시작하고 있습니다. 여기에 링크 하고 있는 문서에서는 Firefox다른 많은 제품으로 사용되어 있는 Mozilla의 Gecko 엔진에 있어서 이미 기술 지원되어 있는 HTML5의 기능에 대해 설명하고 있습니다. 각각의 기능을 기술 지원하고 있는 Gecko 버전 및 다른 브라우저 엔진에 대해서는 지정된 페이지를 참조해 주십시오.

- -

(HTML5의 문서에 대한 다른 분류도 참고하세요.)

- -

HTML5 소개

- -
-
HTML5의 소개
-
이 문서에서는 웹 디자인이나 웹 애플리케이션으로 HTML5 이용 방법을 소개합니다.
-
- -

HTML5의 요소

- -
-
HTML5 요소·태그의 목록
-
현재 사양 초안에 근거한 HTML5 요소(태그)의 목록표입니다.
-
오디오/비디오 사용하기
-
Firefox 3.5이상에서  HTML5의 {{ HTMLElement("audio") }} 요소와 {{ HTMLElement("video") }} 요소의 기술 지원이 추가되었습니다.
-
HTML5 웹 폼양식
-
HTML5에서는 웹 폼양식이 개선됩니다. {{ HTMLElement("input") }} 요소의 {{ htmlattrxref("type", "input") }} 속성에 새로운 값이나 새 요소인 {{ HTMLElement("output") }} 요소 등이 새롭게 추가되었습니다.
-
HTML5 섹션과 아웃라인
-
HTML5 에서는 아웃라인과 섹션에 관한 요소가 추가되었습니다.: {{ HTMLElement("section") }}, {{ HTMLElement("article") }}, {{ HTMLElement("nav") }}, {{ HTMLElement("header") }}, {{ HTMLElement("footer") }}, {{ HTMLElement("aside") }}, {{ HTMLElement("hgroup") }}.
-
{{ HTMLElement("mark") }} 요소
-
mark 요소는 텍스트중에서의 특별한 관련성을 강조시키기 위해서 이용합니다.
-
{{ HTMLElement("figure") }} 및 {{ HTMLElement("figcaption") }} 요소
-
주로 사용된 문장과 느슨하게 연결된, 최종 캡션을 수반한 도식이나 그림을 추가할 수 있습니다.
-
- -

Canvas 기술 지원

- -
-
Canvas 튜토리얼
-
새로운 요소인 {{ HTMLElement("canvas") }} 요소와 그것을 사용하여 Firefox에 그래프나 다른 객체를 재생 하는 방법에 대해 배웁니다.
-
canvas 요소의 HTML5 text API
-
{{ HTMLElement("canvas") }} 요소가 HTML5 text API를 기술 지원합니다.
-
- -

웹 애플리케이션 기능

- -
-
Firefox 오프 라인 자원
-
Firefox는 HTML5의 오프 라인 자원 사양을 완전하게 구현 및 지원하고 있습니다. 대다수 브라우저의 몇 가지 레벨로 오프 라인 자원을 기술 지원하고 있습니다.
-
Online 이벤트와 Offline 이벤트
-
Firefox 3은 WHATWG의 online 및 offline 이벤트를 기술 지원하고 있습니다. 이러한 이벤트는 애플리케이션이나 확장 기능에 현재 인터넷 접속 상태의 연결 여부를 확인할 수 있습니다.
-
WHATWG 클라이언트 사이드 세션 스토리지 및 영구 스토리지 (DOM Storage)
-
클라이언트 사이드 세션 스토리지와 영구 스토리지에 의하고 웹 애플리케이션이 구조화 데이터를 클라이언트 측에 저장할 수 있도록 합니다.
-
contentEditable 속성: 웹 사이트 및 위키 편집 용이성
-
HTML5 에서는 contentEditable 속성이 표준화 되었습니다. 이 기능에 대해 살펴봅니다.
-
로컬 파일 사용하기
-
새로운 HTML5 File API 지원이 Gecko에 추가되었습니다. 이 API는 웹 애플리케이션이 사용자가 선택한 로컬 파일에 접근 하는 것을 가능하게 합니다. 이것에는 type 속성의 값에 file를 지정한 {{ HTMLElement("input") }} 요소에 새롭게 추가된 multiple 속성을 이용하는 것으로 복수 파일을 선택할 수 있게 되는 기술 지원가 포함되어 있습니다.
-
- -

DOM 주요 기능

- -
-
getElementsByClassName
-
Document 및 Element 노드에 있어서의 getElementsByClassName 메소드가 지원되어 있습니다. 이러한 메소드를 이용하는 것으로 지정한 클래스 또는 지정한 클래스의 목록를 가지는 요소를 찾아낼 수 있습니다.
-
드래그 앤 드롭
-
HTML5의 드래그앤 드롭 API는 웹 사이트간에 있어서의 아이템의 끌어오기 및 놓기 기능을 지원합니다. 또, 확장 기능이나 Mozilla 기반의 애플리케이션으로 사용할 수 있는 단순한 API 도 제공합니다.
-
HTML 내 포커스 관리
-
HTML5가 새로운 activeElement 속성과 hasFocus 속성이 지원되어 있습니다.
-
웹 기반 프로토콜 핸들러
-
navigator.registerProtocolHandler()메소드를 사용하여, 웹 애플리케이션을 프로토콜 핸들러로서 등록할 수 있게 되었습니다.
-
- -

HTML 파서

- -

Gecko의 HTML5 표준 파서(HTML 문서를  DOM으로 변환하는 엔진)는 2010 년 3 월에 기본적으로 사용됩니다(Gecko 1.9.2 / Firefox 3.6에 탑재되어 있는 시점의 HTML5 파서는 매우 불안정한 버전이며 실제 이용하는 것을 추천 하지 않습니다).{{ fx_minversion_inline(4.0) }}

- -

추가 변경사항

- -
    -
  • HTML 문서에 있어서의 localNamenamespaceURI는 XML 문서 때와 같은 행동을 하게 되었습니다. 예를 들면, localName는 소문자를 돌려주어, HTML 요소의 namespaceURI"http://www.w3.org/1999/xhtml"를 돌려줍니다.
  • -
  • 페이지 URI 문서 단편 식별자 ("#" (해시) 문자에서 후의 부분)가 변경되었을 때, 새로운 hashchange 이벤트가 페이지에 보내집니다. 자세한 것은 window.onhashchange를 참조해 주십시오.
  • -
  • class 속성을 보다 간단하게 취급할 수 있도록 HTML5의 element.classList이 기술 지원되었습니다.
  • -
  • 문서에 즉시 생성되는 이벤트에 응하는 document.onreadystatechangedocument.readyState가 기술 지원되었습니다.
  • -
  • 표시에 관련하는 속성으로 지정한 색은 HTML5의 사양에 따라서 해석됩니다.
  • -
- -

HTML5의 일부로서 포함된 기술

- -

아래 기술들은 "HTML5"의 광의의 영역에 포함되어 있습니다만 W3C의 HTML5 사양에 없는 것들입니다.

- - - -

관련 문서

- -

웹 발자에게 영향이 있는 Firefox 출시 버전에 따른 변경점:

- - diff --git a/files/ko/web/html/html5/introduction_to_html5/index.html b/files/ko/web/html/html5/introduction_to_html5/index.html deleted file mode 100644 index 8b9698dc53..0000000000 --- a/files/ko/web/html/html5/introduction_to_html5/index.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: HTML5 소개 -slug: Web/HTML/HTML5/Introduction_to_HTML5 -tags: - - HTML5 - - 웹개발 -translation_of: Web/Guide/HTML/HTML5/Introduction_to_HTML5 ---- -

HTML5는 HTML 표준의 가장 새로운 버전입니다. HTML5를 통해 리치 미디어의 기술 지원 뿐만이 아니라, 사용자 및 로컬 데이터를 웹 서버 사이에 보다 간편하면서도 효과적으로 교환할 수 있는 웹 애플리케이션을 개발하기 위한 확장 기술 지원를 제공하는 새로운 기능도 제공됩니다.

- -

HTML5는 아직 표준 제정 단계에 있기 때문에 현재 사양에 대한 변경이 있을 것입니다. 따라서 모든 브라우저에 HTML5 기능 모든 것이 기술 지원되어 있는 것은 아닙니다. 하지만, Gecko (그리고 이를 사용하는 Firefox)에는 훌륭하게 HTML5의 최초 단계 기술 지원이 포함되어 있어 새로운 기능에 대한 대처를 계속하고 있습니다. Gecko는 버전 1.8.1에서 HTML5의 기능을 기술 지원하기 시작했습니다. HTML5의 메인 페이지에 Gecko가 기술 지원하고 있는 HTML5기능 목록이 있습니다. 여러 브라우저의 기술 지원 상황의 상세한 정보에 대해서는 CanIUse 웹 사이트를 참조해 주십시오.

- -

HTML5 DOCTYPE

- -

HTML5의 DOCTYPE는 매우 간단합니다. HTML 콘텐트로 HTML5를 사용하는 것을 나타내려면 단순하게 아래와 같이 합니다:

- -
<!DOCTYPE html>
-
- -

이  DOCTYPE은 현재 HTML5를 기술 지원하고 있지 않는 브라우저조차, HTML의 호환성을 유지함과 동시에 HTML5의 규격 대로 기능이 지원되지 않더라도 신기능을 무시하는 것을 의미하는 표준 모드로 전환합니다.

- -

이것은 이전의 doctype들 보다 훨씬 간단하고 짧으며, 기억하기 쉽고, 다운로드 받아야 하는 바이트의 양을 줄여줍니다.

- -

<meta charset>으로 문자셋 정의하기

- -

보통 문서의 처음에는 사용된 문자셋을 정의합니다. 이전 버전의 HTML에서는 매우 복잡한 {{HTMLElement("meta")}} 엘리먼트를 통해서 문자셋을 정의했습니다. 이제는 이렇게 간단해졌습니다.

- -
<meta charset="UTF-8">
- -

이것을 {{HTMLElement("head") }} 뒤에 가져다 놓으세요. 몇몇 브라우저는 HTML에 기대했던것과 다른 문자셋이 정의되어 있으면 문서를 다시 해석합니다. 또한, 여러분이 현재 다른 문자셋을 사용하고 있다면 UTF-8로 여러분 웹 페이지의 문자셋을 변경하는것을 추천합니다. 이것이 여러 스크립트를 사용한 문서의 문자 처리를 단순화시켜줍니다.

- -

HTML5는 ASCII와 호환되며 적어도 8비트의 크기를 가지는 문자셋만을 지원합니다. 이렇게 함으로서 보안을 강화하고 특정형태의 공격을 방지할수 있습니다.

- -

새로운 HTML5 해석기의 사용

- -

HTML5에서는 마크업의 의미를 분석하는 해석 룰이 더 정확하게 정의 되었습니다. HTML5가 나오기 전까지는 단지 유효한 마크업의 의미만 정의되었기 때문에 마크업에 작은 에러라도 있을 때 문서를 어떻게 해석해야 할지는 정의되지 않았습니다. 결국 모든 브라우저가 서로 다르게 작동했습니다. 이제는 그렇지 않습니다. 이제 마크업에 에러가 있을 때는 모든 호환 브라우저가 똑같이 반응해야 합니다.

- -

이 요구사항이 웹 개발자들의 삶을 꽤 편하게 해줍니다. 이제 모든 최신 브라우저가 HTML5의 해석 룰을 따르지만 HTML5-비호환 브라우저들도 여전히 사용되고 있습니다. 유효한 마크업을 사용하면 읽기 편하고 유지보수에 좋을 뿐 아니라, 여러 오래된 브라우저에서 호환되지 않을 가능성을 매우 줄여주기 때문에 이를 매우 추천합니다.

- -

걱정하지 마세요 — 여러분 웹사이트를 손 댈 필요는 없습니다 — 웹브라우저 개발자들이 여러분을 위해 모두 준비해놓았습니다!

diff --git "a/files/ko/web/html/html5_\353\254\270\354\204\234\354\235\230_\354\204\271\354\205\230\352\263\274_\354\234\244\352\263\275/index.html" "b/files/ko/web/html/html5_\353\254\270\354\204\234\354\235\230_\354\204\271\354\205\230\352\263\274_\354\234\244\352\263\275/index.html" deleted file mode 100644 index 87cae41ebd..0000000000 --- "a/files/ko/web/html/html5_\353\254\270\354\204\234\354\235\230_\354\204\271\354\205\230\352\263\274_\354\234\244\352\263\275/index.html" +++ /dev/null @@ -1,367 +0,0 @@ ---- -title: HTML 구획과 개요 사용하기 -slug: Web/HTML/HTML5_문서의_섹션과_윤곽 -tags: - - HTML - - HTML5 -translation_of: Web/Guide/HTML/Using_HTML_sections_and_outlines ---- -
{{HTMLSidebar}}
- -
-

중요: 개요 알고리즘은 W3C의 최종 명세에 포함된 적이 없고, 브라우저와 보조 기술 중 알고리즘을 구현한 경우도 없습니다. 따라서 개요 알고리즘을 사용해 사용자에게 문서 구조를 나타내서는 안됩니다. 문서 작성자는 대신 제목 순위(h1-h6)를 사용해 문서 구조를 나타내는 것이 좋습니다.

-
- -

HTML5 표준 명세서에서는 웹 개발자가 표준화된 의미론적 체계를 가지고 웹 문서의 구조를 표현할 수 있게 해주는 몇 개의 새로운 요소들을 선보였습니다. 이 문서에서는 이 새로운 요소들과 문서의 아웃라인을 의도한 대로 정의하는 법을 설명하고 있습니다.

- -

예를 들면 <div>는 콘텐츠에 대한 어떠한 내용도 포함하지 않지만, <figcaption>은 콘텐츠에 어떤 내용을 포함하고 있는지를 명확하게 포함합니다.

- -

새로운 의미론적 요소들은 HTML5에서 웹사이트의 내용을 구분하는 것을 향상시키기 위해 추가되었습니다. 개발자들은 표시된 목적 이외의 용도로 의미론적 요소를 사용하지 않도록 하는 것이 중요합니다.

- -

HTML4에서의 문서 구조

- -

문서의 구조, 즉 <body></body> 사이에 있는 것의 의미론적 구조는, 페이지 내용을 사용자에게 전달하는 데 중요한 토대가 됩니다. HTML4에선 일종의 섹션과 그 하위 섹션으로 구분하는 개념을 써서 문서의 구조를 표현합니다. 섹션은 HTML 구획({{HTMLElement("div")}})요소와 함께 그 안에 있는 제목을 정의하는 HTML 제목 요소({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, 혹은 {{HTMLElement("h6")}})를 써서 정의됩니다. 이런 HTML 구획 요소와 HTML 제목 요소의 관계가 문서의 구조와 그 아웃라인을 결정짓게 됩니다.

- -

그래서 다음과 같은 마크업은:

- -
<div class="section" id="forest-elephants">
-  <h1>둥근귀코끼리</h1>
-  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 대해 알아보겠습니다.
-  ...섹션 내용 진행 중...
-  <div class="subsection" id="forest-habitat">
-    <h2>서식지</h2>
-    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
-    ...하위 섹션 내용 진행 중...
-  </div>
-</div>
- -

다음과 같은 문서 아웃라인을 가지게 됩니다:

- -
1. 둥근귀코끼리
-   1.1 서식지
-
- -

새로운 섹션을 정의할 때 {{HTMLElement("div")}} 요소가 꼭 필요한 것은 아닙니다. 단순히 HTML 제목 요소만 있으면 새로운 섹션이 시작됨을 자동으로 암시해 줍니다. 그래서,

- -
<h1>둥근귀코끼리</h1>
-<p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 대해 알아보겠습니다.
-...섹션 내용 진행 중...
-<h2>서식지</h2>
-<p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
-...하위 섹션 내용 진행 중...
-<h2>먹이</h2>
-<h1>몽골 게르빌루스쥐</h1>
- -

앞의 문서는 다음과 같은 아웃라인을 가지게 됩니다:

- -
1. 둥근귀코끼리
-   1.1 서식지
-   1.2 먹이
-2. 몽골 게르빌루스쥐
-
- -

HTML5에서 해결한 문제들

- -

HTML4에서의 문서 구조에 대한 정의와 여기에 내포된 암묵적인 문서 알고리듬은 매우 투박해서 다음과 같은 많은 문제점을 가지고 있습니다:

- -
    -
  1. 의미론적으로 섹션을 정의하는데 {{HTMLElement("div")}}을 사용하면, 특히나 class 속성에 어떠한 값도 지정하지 않았을 땐, 문서의 아웃라인을 파악하는 알고리듬을 자동화하는 것은 불가능합니다("사용된 {{HTMLElement("div")}}이 문서 아웃라인에 포함되는가, 만약 포함된다면 섹션인가 아니면 하위 섹션인가?" 혹은 "오로지 스타일 목적으로만 쓰인 표상적인 {{HTMLElement("div")}}일 뿐인가?"). 바꾸어 말하면, HTML4 표준 명세서에는 무엇이 섹션이고 어떻게 그 범위를 구분 짓는지에 대해 매우 모호하게 정의해 놓았습니다. 문서의 윤곽을 자동으로 생성하는 작업은 매우 중요하며, 특히나 보조 장비에 사용되는 기술에선 더욱 그러한데, 이를 이용해서 파악된 문서의 구조를 바탕으로 사용자에게 정보를 전달해 주게 된다는 것을 고려하면 그 중요성은 더욱 명확해집니다. HTML5에선 HTML 섹션 요소로 새롭게 {{HTMLElement("section")}} 요소를 도입하면서 문서 아웃라인 알고리듬에서 {{HTMLElement("div")}} 요소의 사용 필요성을 없애버렸습니다.
  2. -
  3. 여러 문서를 하나로 합치는 일은 복잡하고 어려운 일입니다: 주 문서에 어떤 하위 문서를 추가할 때 원래 문서의 아웃라인을 온전히 보전하려면 HTML 제목 요소의 계급을 고쳐야만 하는 일이 생깁니다. HTML5에서 새로 소개된 섹션을 구분 짓는 요소들({{HTMLElement("article")}}, {{HTMLElement("section")}}, {{HTMLElement("nav")}} 그리?고 {{HTMLElement("aside")}})은, 내부에 포함된 제목 요소와 관계없이, 항상 그들이 속한 가장 가까운 상위 섹션의 바로 밑 하위 섹션으로 자리 잡게 되면서 이 문제를 해결하였습니다.
  4. -
  5. HTML4에선 모든 섹션이 문서 아웃라인에 영향을 주게 됩니다. 하지만 문서?가 언제나 그렇게 선형적이지만은 않지요. 문서에는 가령 광고 표시 문구를 담고 있는 구역이나 설명 문구를 담은 구획처럼 주 내용의 흐름에는 포함되진 않지만, 간접적으로 연관되는 정보를 가진 특별한 섹션이 포함될 수도 있습니다. HTML5에선 이렇게 문서의 주요 내용 윤곽에는 포함되지 않는 {{HTMLElement("aside")}} 요소가 소개되었습니다.
  6. -
  7. 반복되는 얘기지만, HTML4에선 모든 섹션이 문서의 아웃라인에 포함되기 때문에 로고나 메뉴, 문서의 목차, 혹은 저작권 정보나 법률적 고지처럼 특정 문서가 아닌 사이트 전체와 관련된 정보를 포함하는 섹션을 표현할 수가 없었습니다. 이러한 목적으로, HTML5에서 다음과 같은 세 가지 특수 목적의 섹션 요소를 소개하였습니다: 예를 들어 콘텐츠의 목차처럼 링크들의 모음을 감싸줄 때 쓰는 {{HTMLElement("nav")}} 그리고 사이트와 관련된 정보 표시를 위한 {{HTMLElement("footer")}}와 {{HTMLElement("header")}}가 있습니다.
  8. -
- -

좀 더 포괄적으로 말하면 HTML5에선 문서를 구획하고 이들에게 제목을 부여하는 방법이 좀 더 세밀해지면서, 문서의 아웃라인 파악이 좀 더 예측 가능해지고 덩달아 이를 이용한 브라우저를 통해서 사용자 경험도 향상됩니다.

- -

HTML5 문서 아웃라인 알고리즘

- -

HTML이 섹션과 문서 아웃라인을 다루는 방식에 기반한 알고리즘을 생각해 보겠습니다.

- -

HTML5에서의 섹션 정의

- -

우선 {{HTMLElement("body")}} 요소 안에 배치된 콘텐츠는 모두 적어도 하나의 섹션 안에 포함되어 자리하게 됩니다. 그리고 HTML5에서 섹션은 서로 중첩되서 표시될 수도 있습니다. {{HTMLElement("body")}} 요소에 의해 정의된 주요 섹션을 제외하고, 모든 섹션은 명시적으로나 혹은 은연중 자동으로 구분되어 정의될 수 있습니다. 명시적으로 정의되는 섹션은 {{HTMLElement("body")}}, {{HTMLElement("section")}}, {{HTMLElement("article")}}, {{HTMLElement("aside")}}, {{HTMLElement("footer")}}, {{HTMLElement("header")}}, 그리고 {{HTMLElement("nav")}} 태그들 안에 포함된 콘텐츠입니다.

- -
각 섹션은 자기들만의 제목 계층을 가질 수 있습니다. 그래서, 중첩된 섹션이라도 {{HTMLElement("h1")}} 제목을 가질 수 있습니다. HTML5에서 제목 지정하는 법을 보십시오.
- -

보기:

- -
<section>
-  <h1>둥근귀코끼리</h1>
-  <section>
-    <h1>소개</h1>
-    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
-  </section>
-  <section>
-    <h1>서식지</h1>
-    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.</p>
-  </section>
-  <aside>
-    <p>광고 구역</p>
-  </aside>
-</section>
-<footer>
-  <p>(c) 2013 회사 이름</p>
-</footer>
- -

위에 있는 HTML 코드에선 가장 윗 단계에 두 개의 섹션이 정의되었습니다:

- -
<section>
-  <h1>둥근귀코끼리</h1>
-  <section>
-    <h1>소개</h1>
-    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
-  </section>
-  <section>
-    <h1>서식지</h1>
-    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.</p>
-  </section>
-  <aside>
-    <p>광고 구역</p>
-  </aside>
-</section>
-
-<footer>
-  <p>(c) 2013 회사 이름?</p>
-</footer>
- -

첫 번째 섹션에선 세 개의 하위 섹션이 존재합니다:

- -
<section>
-  <h1>둥근귀코끼리</h1>
-
-  <section>
-    <h1>소개</h1>
-    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
-  </section>
-
-  <section>
-    <h1>서식지</h1>
-    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.</p>
-  </section>
-
-  <aside>
-    <p>광고 구역</p>
-  </aside>
-</section>
-
-<footer>
-  <p>(c) 2013 회사 이름</p>
-</footer>
- -

그래서 다음과 같은 구조를 가지게 됩니다:

- -
1. 둥근귀코끼리
-   1.1 소개
-   1.2 서식지
-   1.3 광고 구역 (aside)
-
- -

HTML5에서 제목 지정하는 법

- -

비록 명시적 HTML 섹션 요소가 문서의 전체 구조를 정해주기는 하지만, 그 아웃라인을 좀 더 명확하게 표현하려면 제목의 사용도 중요합니다. 기본 규칙은 단순합니다: 처음 쓰인 HTML 제목 요소({{HTMLElement("h1")}}, {{HTMLElement("h2")}}, {{HTMLElement("h3")}}, {{HTMLElement("h4")}}, {{HTMLElement("h5")}}, {{HTMLElement("h6")}} 중 하나)가 해당 섹션의 제목으로 정해집니다.

- -

제목 요소엔 요소 이름에 붙은 숫자를 가지고 계급을 매기는데, {{HTMLElement("h1")}}이 최상위 계급이며 {{HTMLElement("h6")}}는 최하위 계급이 됩니다. 제목 간 계급의 상대적 등급은 오로지 같은 섹션 안에서만 중요해집니다; 이 말은 섹션의 구조가 문서의 아웃라인을 결정짓는 데 중요한 변수로 작용하지만, 섹션 안에서 사용된 제목의 계급은 여기에 아무런 관련이 없다는 얘기입니다. 예를 들어, 아래와 같은 코드를 살펴보면:

- -
<section>
-  <h1>둥근귀코끼리</h1>
-  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
-    ...계속 된 섹션 내용...
-  <section>
-    <h2>서식지</h2>
-    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
-    ...계속 된 하위 섹션 내용...
-  </section>
-</section>
-<section>
-  <h3>몽골 게르빌루스쥐</h3>
-  <p>이번 섹션에선, 잘 알려진 몽골 게르빌루스쥐에 관해 알아보겠습니다.
-    ...계속 된 섹션 내용...
-</section>
- -

이는 다음과 같은 아웃라인을 갖게 됩니다:

- -
1. 둥근귀코끼리
-   1.1 서식지
-2. 몽골 게르빌루스쥐
- -

여기서 쓰인 제목 요소의 계급(위 보기에선 처음 최상위 섹션의 {{HTMLElement("h1")}}, 그 하위 섹션의 {{HTMLElement("h2")}} 그리고 두 번째 최상위 섹션에서 사용된 {{HTMLElement("h3")}})은 중요하지 않다는 점을 주목하십시오. (명시적으로 정의된 섹션의 제목으로 어떠한 계급을 써도 상관은 없지만, 이 방식이 권장되는 것은 아닙니다.)

- -

은연중 자동으로 정의되는 섹션

- -

HTML5에서 소개된 명시적 섹션 요소들만이 문서의 아웃라인을 정의하는 데 절대적으로 필요한 요소는 아니므로, 기존 웹에서 지배적으로 사용되는 HTML4와의 호환성을 지키려는 노력의 일환으로, 이들 없이도 섹션을 정의하는 또 하나의 방법이 있습니다. 이를 은연중 자동으로 정의되는 섹션이라 하겠습니다.

- -

HTML 제목 요소({{HTMLElement("h1")}}부터 {{HTMLElement("h6")}})는 만약에 그들이 속한 상위 명시적 섹션의 첫 번째 제목으로 사용되지 않았다면, 자동으로 또 하나의 새로운 암묵적인 섹션으로 분류/정의되어 집니다. 이들 암묵적 섹션이 문서 아웃라인에서 위치하게 되는 기준은 기존 이들 제목을 포함하고 있는 상위 섹션에서 사용된 제목과의 상대적 계급에 따라 결정됩니다. 만약 전에 사용된 제목보다 계급이 더 낮다면, 은연중으로 해당 섹션의 하위 섹션으로 자리 잡게 됩니다. 아래 코드를 살펴보면:

- -
<section>
-  <h1>둥근귀코끼리</h1>
-  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
-    ...섹션 내용 진행 중...
-  <h3 class="implicit subsection">서식지</h3>
-  <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
-    ...하위 섹션 내용 진행 중...
-</section>
- -

이는 다음과 같은 문서 아웃라인을 갖게 됩니다:

- -
1. 둥근귀코끼리
-   1.1 서식지 (h3 요소에 의해 은연중 자동으로 정의됨)
-
- -

만약에 이전에 사용된 제목과 같은 계급이라면, (명시적으로 정의되었을 수도 있지요!) 바로 이전 섹션과 구분되면서 같은 계급의 또 하나의 새로운 암묵적 섹션으로 자리하게 됩니다:

- -
<section>
-  <h1>둥근귀코끼리</h1>
-  <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
-    ...섹션 내용 진행 중...
-  <h1 class="implicit section">몽골 게르빌루스쥐</h1>
-  <p>몽골 게르빌루스쥐는 귀엽고 작은 포유 동물입니다.
-    ...섹션 내용 진행 중...
-</section>
- -

위 코드는 다음과 같은 문서 아웃라인을 갖게 됩니다:

- -
1. 둥근귀코끼리
-2. 몽골 게르빌루스쥐 (h1 요소에 의해 자동으로 정의됨과 동시에 이전 섹션과 구분되어 짐)
-
- -

만약에 이전에 사용된 제목보다 더 높은 계급의 제목이 사용되었다면, 이전 섹션과 구분되면서 더 높은 제목의 계급을 가진 또 하나의 새로운 암묵적 섹션으로 자리하게 됩니다:

- -
<body>
-  <h1>포유 동물</h1>
-  <h2>고래</h2>
-  <p>이번 섹션에선, 유영하는 고래에 관해 알아보겠습니다.
-    ...섹션 내용 진행 중...
-  <section>
-    <h3>둥근귀코끼리</h3>
-    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.
-      ...섹션 내용 진행 중...
-    <h3>몽골 게르빌루스쥐</h3>
-      <p>몽골 게르빌루스쥐의 무리는 몽골을 훨씬 벗어나는 구역까지 퍼져있습니다.
-         ...하위 섹션 내용 진행 중...
-    <h2>파충류</h2>
-      <p>파충류는 냉혈 동물입니다.
-          ...하위 섹션 내용 진행 중...
-  </section>
-</body>
- -

위 코드는 다음과 같은 문서 아웃라인을 갖게 됩니다:

- -
1. 포유 동물
-   1.1 고래 (h2 요소에 의해 자동으로 정의됨)
-   1.2 둥근귀코끼리 (섹션 요소에 의해 명시적으로 정의됨)
-   1.3 몽골 게르빌루스쥐 (h3 요소에 의해 자동으로 정의됨과 동시에 이전 섹션과 구분되어 짐)
-2. 파충류 (h2 요소에 의해 자동으로 정의됨과 동시에 이전 섹션과 구분되어 짐)
- -

단순히 써진 제목의 태그들만 살펴본다면, 이것은 결코 예상했던 문서의 아웃라인은 아닐 것입니다. 그래서 작성한 마크업이 다른 사람에게도 쉽게 이해되도록 하려면, 섹션을 구분할 때 명시적 섹션 요소의 태그들을 쓰는 것이 바람직하며, 원래 의도하는 섹션의 중첩 수준을 고려해서 그에 어울리는 제목의 계급을 써야 합니다. 그런데 이것이 꼭 HTML5 명세서에서 요구하는 필수 준수 사항은 아닙니다. 만약에 작성한 문서의 아웃라인을 브라우저가 원래 의도한 방향으로 표시해 주지 못한다면, 혹시 사용한 제목 요소가 은연중 자동으로 기존 섹션과 구분되게 사용되었는지 확인해 보시기 바랍니다.

- -

제목의 계급은 항상 해당 섹션의 중첩 수준과 일치하도록 쓰라는 규칙의 예외도 있을 수 있는데, 그 중 하나 여러 문서에서 공통으로 재사용되는 섹션의 경우가 있습니다. 예를 들면, 섹션 내용이 어떤 콘텐츠 관리 시스템에 저장되어 실시간으로 여러 다른 저장된 내용과 함께 조합되어 문서에 표시될 때가 있습니다. 이 경우엔, 재사용되는 섹션의 가장 최상위 제목으로 {{HTMLElement("h1")}}부터 시작해서 사용하실 것을 권장합니다. 그러면 재사용되는 섹션의 중첩 수준은 문서의 섹션 계층 중 해당 섹션이 삽입되어 보이는 위치에 따라 자동으로 결정될 것입니다. 이 경우에도 명시적 섹션 태그가 문서 아웃라인을 명확히 하는 데 도움을 줍니다.

- -

섹션 구분의 근원점

- -

섹션 구분의 근원점은 HTML 요소 중 자기만의 아웃라인을 가질 수는 있지만, 그 안의 섹션이나 제목이 자기 위에 있는 요소의 아웃라인에는 어떠한 영향도 끼치지 않는 것들을 가리킵니다. 논리적으로 따지면 당연히 문서의 섹션을 구분하는데 그 근본이 되는 {{HTMLElement("body")}}가 여기에 포함되고, 이 외에도 종종 외부 콘텐츠를 페이지에 표시하는 데 사용되는 다음과 같은 요소들도 있습니다: {{HTMLElement("blockquote")}}, {{HTMLElement("details")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("figure")}} 마지막으로 {{HTMLElement("td")}}.

- -

보기:

- -
<section>
-  <h1>숲 코끼리</h1>
-  <section>
-    <h2>소개</h2>
-    <p>이번 섹션에선, 잘 알려지지 않은 둥근귀코끼리에 관해 알아보겠습니다.</p>
-  </section>
-  <section>
-    <h2>서식지</h2>
-    <p>둥근귀코끼리는 나무에 살지는 않고 나무들 사이에 그 서식지를 이루고 있습니다.
-      과학자들은 "<cite>보르네오 섬의 둥근귀코끼리</cite>"라는 제목의 책에서 다음과 같이 서술하고 있습니다:</p>
-    <blockquote>
-       <h1>보르네오 섬</h1>
-       <p>보르네오 섬에 서식하는 둥근귀코끼리...</p>
-    </blockquote>
-  </section>
-</section>
-
- -

위의 보기에선 다음과 같은 문서 아웃라인을 가지게 됩니다:

- -
1. 숲 코끼리
-   1.1 소개
-   1.2 서식지
- -

이 문서의 아웃라인을 살펴보면 외부 인용 문구로 사용된 {{HTMLElement("blockquote")}} 요소의 경우, 섹션 구분의 근원이 되는 요소 중 하나로서 자기가 포함하고 있는 내부 내용의 아웃라인이 외부의 것과 완전히 차단되면서, 전체 문서의 아웃라인에는 포함되지 않았습니다.

- -

문서의 아웃라인 밖에 존재하는 섹션

- -

HTML5에선 웹 문서의 주요 아웃라인에 속하지 않는 섹션을 정의할 수 있도록 하는 새로운 네 가지의 요소들을 소개하고 있습니다:

- -
    -
  1. HTML Aside 섹션 요소({{HTMLElement("aside")}})는 주요 문맥을 담은 요소와 어떤 관련성을 지니고 있지만, 어떤 부연 설명 표시 영역이나 광고처럼 문맥의 주요 흐름 줄기엔 속하지 않는 섹션을 나타냅니다. 물론 자기만의 아웃라인을 가지고 있어서, 문서의 주요 아웃라인엔 포함되지 않습니다.
  2. -
  3. HTML Navigational 섹션 요소({{HTMLElement("nav")}})는 내비게이션 링크들을 포함하고 있는 섹션입니다. 이런 링크들은 문서에 여러 개가 있을 수 있는데, 예를 들어, 콘텐츠 목차와 같은 페이지 내부 링크나 사이트의 내비게이션 링크가 있습니다. 이런 링크는 문서의 주요 문맥과 아웃라인에 포함되지 않아서 보통 처음에는 스크린 리더나 비슷한 보조 기술을 사용하는 장치에서 읽어드리지 않을 수도 있습니다.
  4. -
  5. HTML Header 섹션 요소({{HTMLElement("header")}})는 페이지의 도입부로서 보통 로고나 사이트 이름 그리고 수평 메뉴를 포함하고 있습니다. 이름에서 풍기는 느낌과는 달리 꼭 페이지 처음에 있을 필요는 없습니다.
  6. -
  7. HTML Footer 섹션 요소({{HTMLElement("footer")}})는 페이지의 종결부로서 보통 저작권이나 법률적 고지 혹은 약간의 링크들을 포함하고 있습니다. 이것도 역시 이름이 가진 직설적 의미와 달리 페이지 끝에 있을 필요는 없습니다.
  8. -
- -

섹션을 구분짓는 요소의 주소와 발행 시간

- -

문서를 작성하다 보면 종종 저자의 이름이나 주소와 같은 연락 정보를 공개하고 싶을 때가 있습니다. HTML4에선 이런 목적으로 {{HTMLElement("address")}} 요소가 쓰였는데, HTML5에선 여기에 더 보완된 내용이 추가되었습니다.

- -

가끔 문서에는 여러 명의 저자가 작성한 여러 개의 섹션이 포함되어 있을 수도 있습니다. 메인 페이지의 저자와 다른 또 다른 사람?이 작성한 콘텐츠가 포함된 섹션은 {{HTMLElement("article")}} 요소를 써서 정의합니다. 이렇게 하면, {{HTMLElement("address")}} 요소는 지정?된 위치에 따라 가장 가까운 상위의 {{HTMLElement("body")}} 혹은 {{HTMLElement("article")}}과 연관된 정보로 표시됩니다.

- -

비슷하게, HTML5의 새 {{HTMLElement("time")}} 요소에 pubdate boolean 속성이 지정되었다면 문서 전체의 발행 날짜를 표시해 주는데, article에서처럼, 가장 가까운 상위의 {{HTMLElement("body")}} 혹은 {{HTMLElement("article")}} 과 연관된 정보로 표시됩니다.

- -

HTML5 미지원 브라우저에서 HTML5 요소를 사용하는 법

- -

섹션과 제목 요소들은 대부분의 HTML5 미지원 브라우저에서도 정상적으로 사용하실 수 있습니다. 지원하진 않더라도, 어떤 특별한 DOM 인터페이스가 필요한 것은 아니고 단지 인식하지 못하는 요소는 기본적으로 display:inline 으로 표시되기 때문에 다음과 같이 특별한 CSS 스타일을 지정해 주어야 합니다:

- -
section, article, aside, footer, header, nav, hgroup {
-  display:block;
-}
-
- -

물론 웹 개발자가 이들의 스타일을 달리 표시해 줄 수도 있는데, HTML5 미지원 브라우저에선 해당 요소들의 기본 표시 스타일이 원래의 정상적인 것과 다르다는 점을 명심해야 합니다. 또한, 여기엔 {{HTMLElement("time")}} 요소가 포함되지 않았는데, 그 이유는 기본 스타일이 HTML5 미지원 브라우저의 것과 HTML5 호환 브라우저의 것과 서로 같기 때문입니다.

- -
그런데 이 방법도 약간의 제약이 있어서, 어떤 브라우저에선 지원하지 않은 요소의 스타일을 애초에 지정할 수도 없게 되어 있습니다. Internet Explorer(버전 8 이하)가 여기에 해당하는데, 제대로 스타일을 지정해 주려면 다음과 같은 스크립트가 필요합니다:
- -
<!--[if lt IE 9]>
-  <script>
-    document.createElement("header" );
-    document.createElement("footer" );
-    document.createElement("section");
-    document.createElement("aside"  );
-    document.createElement("nav"    );
-    document.createElement("article");
-    document.createElement("hgroup" );
-    document.createElement("time"   );
-  </script>
-<![endif]-->
- -

이 스크립트가 하는 일은, Internet Explorer(8 혹은 그 이하)일 경우, HTML5의 섹션 요소와 제목 요소가 제대로 표시될 수 있도록 실행됩니다. 여기에 언급된 요소들은 전체 페이지의 구조를 정의하는 데 필요한 아주 중요한 요소이기 때문에, 만약에 스크립트의 힘을 빌리지 않다면 표시조차 되지 않게 되면서 문제 될 수 있습니다. 그래서 이런 때를 대비해서 명시적으로 다음과 같은 {{HTMLElement("noscript")}} 요소도 추가되어야 합니다:

- -
<noscript>
-   <strong>주의 !</strong>
-   귀하가 사용하고 계신 브라우저는 HTML5를 지원하고 있지 않아서, 할 수 없이 JScript를 써서 몇몇 요소가 제대로 보이도록 구현했습니다.
-   그런데 안타깝게도 귀하의 브라우저에선 스크립트 기능이 꺼져있습니다. 이 페이지가 제대로 표시되려면 스크립트 기능을 켜주셔야만 합니다.
-</noscript>
- -

그래서 결국, Internet Explorer(8 혹은 그 이하)처럼 HTML5 미지원 브라우저에서도 HTML5의 섹션과 제목 요소를 제대로 지원하도록 하고, 또 만약을 대비해 이런 미지원 브라우저에서 스크립팅 기능이 꺼져있을 때를 대비해서 다음과 같은 코드를 추가해 줘야 합니다:

- -
<!--[if lt IE 9]>
-  <script>
-    document.createElement("header" );
-    document.createElement("footer" );
-    document.createElement("section");
-    document.createElement("aside"  );
-    document.createElement("nav"    );
-    document.createElement("article");
-    document.createElement("hgroup" );
-    document.createElement("time"   );
-  </script>
-  <noscript>
-     <strong>주의 !</strong>
-     귀하가 사용하고 계신 브라우저는 HTML5를 지원하고 있지 않아서, 할 수 없이 JScript를 써서 몇몇 요소가 제대로 보이도록 구현했습니다.
-     그런데 안타깝게도 귀하의 브라우저에선 스크리트 기능이 꺼져있습니다. 이 페이지가 제대로 표시되려면 스크립트 기능을 켜주셔야만 합니다.
-   </noscript>
-<![endif]-->
-
- -

맺음말

- -

HTML5에서 소개된 새로운 섹션과 제목 요소는 웹 문서의 구조와 아웃라인을 표준화된 방법으로 작성할 수 있게 도와줍니다. 또한, HTML5를 지원하는 브라우저 사용자나 페이지 내용을 제대로 전달하는데 그 구조 파악이 중요한, 예를 들어 보조 지원 기술의 도움으로 페이지의 내용을 파악하는, 사용자 모두에게 커다란 이득을 안겨다 줍니다. 새로 소개된 의미가 담긴 요소들은, 약간의 노력만 기울인다면, 사용이 간편해서 HTML5 미지원 브라우저에서도 온전히 사용하실 수 있습니다. 그러므로 아무런 제약 없이 마음 놓고 사용하시기 바랍니다.

diff --git a/files/ko/web/http/browser_detection_using_the_user_agent/index.html b/files/ko/web/http/browser_detection_using_the_user_agent/index.html new file mode 100644 index 0000000000..8ffc0ff0b5 --- /dev/null +++ b/files/ko/web/http/browser_detection_using_the_user_agent/index.html @@ -0,0 +1,296 @@ +--- +title: 사용자 에이전트를 이용한 브라우저 감지 +slug: Web/HTTP/User_agent를_이용한_브라우저_감지 +tags: + - Compatibility + - HTTP + - Web Development +translation_of: Web/HTTP/Browser_detection_using_the_user_agent +--- +
{{HTTPSidebar}}
+ +

보통 브라우저마다 다른 웹 페이지 또는 서비스를 제공하는 것은 나쁜 생각입니다. 웹은 사용자가 어떤 브라우저나 디바이스를 사용하고 있는지 개의치 않고 모두에게 접근성이 용이해야 하기 때문입니다. 따라서 특정 브라우저를 타겟으로 개발하는 것보다 가용적인 기능들 (예를 들어 Web API 등)을 이용하여 당신의 웹 사이트를 개선하는 것을 추천합니다.

+ +

하지만 브라우저와 웹 표준은 완벽하지 않고 그 간극은 여전히 브라우저 감지 기능을 필요로 합니다. User-Agent를 사용하여 브라우저를 감지하는 것은 간단해 보이지만, 사실 그것을 잘 이용하는 것은 무척 힘든 일입니다. 이 문서는 사용자 에이전트를 이용하여 브라우저를 바르게 감지하도록 안내합니다.

+ +
+

주의하세요! user agent 정보를 가로채는 것은 좋은 아이디어가 아닙니다. 대부분의 경우 호환성이 뛰어난 좋은 다른 해결방안을 찾을 수 있을 것입니다.

+
+ +

브라우저 감지를 하기 전 고려할 것

+ +

사용자 에이전트 문자열을 이용해 브라우저를 감지하기 전에 가능하다면 이것을 사용하지 않는 것이 첫 번째입니다. 내가 이 기능을 원하는지 다시 한 번 스스로 확인하길 바랍니다.

+ +
+
특정 브라우저 버전의 버그를 고치려고 하나요?
+
포럼에서 찾아보십시오. 만약 이 버그를 당신이 처음 발견했다면 포럼에 질문을 하십시오. 또한 전문가나 다른 견해를 가진 이들이 이 버그를 해결하는데 도움을 줄 것입니다. 만약 버그가 좀처럼 없는 문제라면 브라우저 제공자의 버그 추적 시스템(MozillaWebKitBlinkOpera)에 보고된 버그인지 확인하세요.
+
특정 기능의 존재를 확인하려고 하나요?
+
당신의 사이트에 몇몇 브라우저에서 아직 지원하지 않은 기능을 사용해야 하고, 해당 유저들을 이전 버전의 웹사이트로 보내고 싶어 하지만 당신은 후에 해당 브라우저에서 해당 기능이 동작할 것이라는걸 압니다. 이것이 사용자 에이전트 탐지를 사용하는 가장 나쁜 이유인데, 결국 다른 브라우저들이 그 문제를 따라잡을 것이기 때문입니다. 이러한 시나리오에서 당신은 가능한 유저 에이전트 탐지를 절대 피해야 하고, 대신 언제나 기능탐지를 하는데 최선을 다해야 합니다. 대신 언제든지 기능 탐지를 할 수 있는 대체방안이 존재합니다
+
사용하는 브라우저에 따라 다른 HTML을 제공해야 하나요?
+
이는 권해드리고 싶지 않지만, 필요에 따른 몇가지 방법이 있습니다. 이러한 상황들일 경우, 우선 브라우저에 따른 다양한 HTML을 사용해야 하는지 결정하기 위해 당신의 상황을 분석할 필요가 있습니다. 당신은 non-semantic인  {{ HTMLElement("div") }} 나 {{ HTMLElement("span") }}  요소를 추가함으로써 이를 방지할 수 있나요? user Agent 감지를 성공적으로 하는 것의 어려움은 몇몇 혼란스러운 HTML을 깨끗하게 바꾸는데 가치가 있습니다. 또한 당신의 디자인에 대해 다시한번 생각해보세요. 브라우저별로 다른 HTML을 사용할 필요성을 없애기 위해 점진적 향상(progressive enhancement)이나 가변 레이아웃(fluid layout)을 사용할 수 있나요?
+
+ +

사용자 에이전트를 대신할 방법

+ +

user agent 감지를 피하는 몇 가지 방법이 있습니다!

+ +
+
기능 탐지
+
기능 탐지는 어떤 브라우저가 당신의 페이지를 렌더링하는지를 알아내려고 할 때가 아니라, 어떤 특정한 기능을 당신이 사용가능한지를 확인할 때 사용합니다. 그렇지 않다면, 대비책을 사용하세요. 브라우저 간의 차이점을 찾는 몇 안되는 경우에서는 user agent 문자열을 사용하는 대신, 브라우저가 API를 구현하는 방법을 탐지하고 API를 사용하는 방법을 결정하는 테스트를 구현하는 것이 좋습니다. 아래는 기능탐지의 좋은 최신 예시 입니다. 최근 크롬은 experimental lookbehind support to regular expressions을 추가했지만, 다른 브라우저들은 이를 지원하지 않습니다. 그러므로 당신은 이와 같이 해야 한다고 잘못 생각하고 있을 것입니다.
+
+
// 아래 코드 조각은 한 문자열을 특별한 표기법으로 쪼갭니다.
+
+if (navigator.userAgent.indexOf("Chrome") !== -1){
+    // 네! 이 사용자가 정규표현식의 look-behind 기능을 사용하려는 것
+    //  같습니다.
+    // /(?<=[A-Z])/를 사용하지 마십시오. 정규표현식의
+    //  look-behind 기능을 지원하지 않는 브라우저에서는 문법오류가
+    //  발생할 것입니다. 왜냐하면, 모든 브라우저들은 실제로 실행되지
+    //  않는 부분을 포함한 전체 스크립트를 해석하기 때문입니다.
+    var camelCaseExpression = new RegExp("(?<=[A-Z])");
+    var splitUpString = function(str) {
+        return (""+str).split(camelCaseExpression);
+    };
+} else {
+    /*아래 fallback 코드는 성능이 떨어지지만 작동하긴 합니다.*/
+    var splitUpString = function(str){
+        return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g);
+    };
+}
+console.log(splitUpString("fooBare")); // ["fooB", "are"]
+console.log(splitUpString("jQWhy")); // ["jQ", "W", "hy"]
+ +

위의 코드는 다음과 같은 몇 가지 잘못된 가정을 했습니다.

+ +
    +
  • 하위 문자열 "Chrome"을 포함하는 모든 사용자 에이전트 문자열은 크롬이라고 가정했습니다. UA 문자열은 틀릴 가능성이 매우 높습니다.
  • +
  • 정규표현식의 look-behind 기능이 크롬 브라우저에서는 항상 지원될 것이라고 가정했습니다. 하지만 agent가 해당 기능이 지원되기 전인 옛 버전의 크롬일 수도 있고, 당시에는 look-behind는 실험적 기능이었기 때문에, 이를 제거한 버전의 크롬일 수도 있습니다.
  • +
  • 가장 중요한 점은, 다른 모든 브라우저들이 look-behind를 지원할 것이라고 가정했습니다. 다른 브라우저들도 look-behind 기능을 지원하는 버전이 모두 다를텐데, 이 코드는 이를 무시하고 코드를 진행합니다.
  • +
+ +

look-behind 지원여부 자체를 테스트함으로써 이 문제들을 회피할 수 있습니다.

+ +
var isLookBehindSupported = false;
+
+try {
+    new RegExp("(?<=)");
+    isLookBehindSupported = true;
+} catch (err) {
+    // agent가 look-behind 기능을 지원하지 않는다면, 위 문법을 사용한
+    // RegExp 객체의 생성이 에러를 던질 것이고, isLookBehindSupported는
+    // 여전히 false일 것입니다.
+}
+
+var splitUpString = isLookBehindSupported ? function(str) {
+    return (""+str).split(new RegExp("(?<=[A-Z])"));
+} : function(str) {
+    return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g);
+};
+
+ +

위의 코드가 시범을 보였듯이, user agent를 살펴보지 않고도 어떤 기능에 대한 브라우저 지원 여부를 시험할 수 있는 방법이 항상 존재합니다. 기능 지원 여부를 확인하기 위해 user agent 문자열을 확인할 필요가 전혀 없습니다.

+ +

마지막으로, 위의 코드 조각은 크로스 브라우저 코딩과 관련하여 항상 염두에 두어야만 하는 중요한 이슈를 시사합니다.테스트 중인 API를 해당 기능이 지원되지 않는 브라우저에서 실수로 사용하지 마십시오. 확실하고 단순한 이야기 같지만, 때때로 그렇지 않습니다. 예를 들어, 위의 코드 조각에서, lookbehind 기능을 short-regexp 표기법(예를 들어, /reg/igm)으로 사용한다면, 지원되지 않는 브라우저에서는 파싱 에러가 발생할 것입니다. 따라서, 위의 예제에서, /(?<=look_behind_stuff)/ 대신에 new RegExp("(?<=look_behind_stuff)")를 사용하는 것이 좋습니다. 심지어 lookbehind가 지원되는 조건분기의 코드에서도 말입니다.

+
+
점진적 향상
+
이 디자인 테크닉은 여러분의 사이트를 상향식 접근방법으로 "레이어" 형태 개발할 수 있게 해줍니다. 간단한 레이어로 시작하여, 각각이 더 많은 기능을 이용하는 연속적인 레이어를 가진 사이트로 성능을 개선할 수 있습니다.
+
부드러운 하향
+
이는 여러분이 원하는 모든 기능이 포함된 최선의 사이트를 만들고 나서 오래된 브라우저들도 지원하게 수정하는 하향식 접근입니다. 점진적 상향 방식보다는 조금 더 어렵기도 하고 덜 효과적이기도 하지만, 몇몇 케이스에서는 유용할 것입니다.
+
모바일 장치 감지
+
Arguably the most common use and misuse of user agent sniffing is to detect if the device is a mobile device. However, what is failed to be accountable is what they're really after. People use user agent sniffing to detect if the users' device is touch-friendly and has a small screen so they can optimize their website accordingly. While user agent sniffing can sometimes detect these, not all devices are the same. Some mobile devices have big screen sizes, some desktops have a small touchscreen, some people use smart TV's which are an entirely different ballgame altogether, some people can dynamically change the width and height of their screen by flipping their tablet on its side! So, user agent sniffing is definitely not the way to go. But, there are much better alternatives. Use Navigator.maxTouchPoints to detect if the user's device has a touchscreen. Then, default back to checking the user agent screen only if (!("maxTouchPoints" in Navigator)) { /*Code here*/}. Using this information of whether the device has a touchscreen, do not change the entire layout of the website just for touch devices: you will only create more work and maintenance for yourself. Rather, add in touch conveniences such as bigger, more easily clickable buttons (you can do this using CSS by simply increasing the font size). As for the screen size, simply use window.innerWidth and window.addEventListener("resize", function(){ /*refresh screen size dependent things*/ }). What you want to do for screen size is not slash off information on smaller screens. That will only annoy people because it will force them to use the desktop version. Rather, try to have fewer columns of information in a longer page on smaller screens while having more columns with a shorter page on larger screen sizes. This effect can be easily achieved using CSS flexboxes. Next, always make your code dynamic. The user can flip their mobile device on its side, changing the width and height of the page. Never be satisfied with your webpage until you can open up the dev tools side panel and resize the screen while the webpage looks smooth, fluid, and dynamically resized.
+
+ +

Which part of the user agent contains the information you are looking for

+ +

As there is no uniformity of the different part of the user agent string, this is the tricky part.

+ +

브라우저 이름

+ +

사람들이 "브라우저 감시(browser detection)"을 원한다고 말할 때, 실제로 대부분 그들은 "렌더링 엔진 탐지(rendering engine detection)"를 원합니다. Do you actually want to detect Firefox, as opposed to SeaMonkey, or Chrome as opposed to Chromium? Or do you actually simply want to see if the browser is using the Gecko or the WebKit rendering engine? If this is what you need, see further down the page.

+ +

Most browser set the name and version in the format BrowserName/VersionNumber, with the notable exception of Internet Explorer. But as the name is not the only information in a user agent string that is in that format, you can not discover the name of the browser, you can only check if the name you are looking for. But note that some browsers are lying: Chrome for example reports both as Chrome and Safari. So to detect Safari you have to check for the Safari string and the absence of the Chrome string, Chromium often reports itself as Chrome too or Seamonkey sometimes reports itself as Firefox.

+ +

Also pay attention not to use a simple regular expression on the BrowserName, user agents also contain strings outside the Keyword/Value syntax. Safari & Chrome contain the string 'like Gecko', for instance.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
반드시 포함반드시 포함하지 않음
FirefoxFirefox/xyzSeamonkey/xyz
SeamonkeySeamonkey/xyz
ChromeChrome/xyzChromium/xyz
ChromiumChromium/xyz
SafariSafari/xyzChrome/xyz or Chromium/xyzSafari gives two version number, one technical in the Safari/xyz token, one user-friendly in a Version/xyz token
Opera +

OPR/xyz [1]

+ +

Opera/xyz [2]

+
+

[1]  Opera 15+ (Blink-based engine) 

+ +

[2] Opera 12- (Presto-based engine)

+
Internet Explorer; MSIE xyz;Internet Explorer doesn't put its name in the BrowserName/VersionNumber format
+ +

Of course, there is absolutely no guarantee that another browser will not hijack some of these things (like Chrome hijacked the Safari string in the past). That's why browser detection using the user agent string is unreliable and should be done only with the check of version number (hijacking of past versions is less likely).

+ +

브라우저 버전

+ +

The browser version is often, but not always, put in the value part of the BrowserName/VersionNumber token in the User Agent String. This is of course not the case for Internet Explorer (which puts the version number right after the MSIE token), and for Opera after version 10, which has added a Version/VersionNumber token.

+ +

Here again, be sure to take the right token for the browser you are looking for, as there is no guarantee that others will contain a valid number.

+ +

렌더링 엔진

+ +

As seen earlier, in most cases, looking for the rendering engine is a better way to go. This will help to not exclude lesser known browsers. Browsers sharing a common rendering engine will display a page in the same way: it is often a fair assumption that what will work in one will work in the other.

+ +

There are five major rendering engines: Trident, Gecko, Presto, Blink and WebKit. As sniffing the rendering engines names is common, a lot of user agents added other rendering names to trigger detection. It is therefore important to pay attention not to trigger false-positives when detecting the rendering engine.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
반드시 포함
GeckoGecko/xyz
WebKitAppleWebKit/xyzPay attention, WebKit browsers add a 'like Gecko' string that may trigger false positive for Gecko if the detection is not careful.
PrestoOpera/xyzNote: Presto is no longer used in Opera browser builds >= version 15 (see 'Blink')
TridentTrident/xyzInternet Explorer put this token in the comment part of the User Agent String
BlinkChrome/xyz
+ +

렌더링 엔진 버전

+ +

Most rendering engine put the version number in the RenderingEngine/VersionNumber token, with the notable exception of Gecko. Gecko puts the Gecko version number in the comment part of the User Agent after the rv: string. From Gecko 14 for the mobile version and Gecko 17 for the desktop version, it also puts this value in the Gecko/version token (previous version put there the build date, then a fixed date called the GeckoTrail).

+ +

운영체제

+ +

The Operating System is given in most User Agent strings (although not web-focussed platforms like Firefox OS), but the format varies a lot. It is a fixed string between two semi-colons, in the comment part of the User Agent. These strings are specific for each browsers. They indicates the OS, but also often its version and information on the relying hardware (32 or 64 bits, or Intel/PPC for Mac).

+ +

Like in all cases, these strings may change in the future, one should use them only in conjunction for the detection of already released browsers. A technological survey must be in place to adapt the script when new browser versions are coming out.

+ +

모바일, 태블릿, 데스크톱

+ +

The most common reason to perform user agent sniffing is to determine which type of device the browser runs on. The goal is to serve different HTML to different device types.

+ +
    +
  • Never assume that a browser or a rendering engine only runs on one type of device. Especially don't make different defaults for different browsers or rendering engines.
  • +
  • Never use the OS token to define if a browser is on mobile, tablet or desktop. The OS may run on more than one type of (for example, Android runs on tablets as well as phones).
  • +
+ +

The following table summarizes the way major browser vendors indicate that their browsers are running on a mobile device:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Common browsers User Agent strings
브라우저규칙예제
Mozilla (Gecko, Firefox)Mobile or Tablet token in the comment.Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0
WebKit-based (Android, Safari)Mobile Safari token outside the comment.Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Blink-based (Chromium, Google Chrome, Opera 15+)Mobile Safari token outside the commentMozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047
Presto-based (Opera 12-) +

Opera Mobi/xyz token in the comment (Opera 12-)

+
+

Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50

+
Internet ExplorerIEMobile/xyz token in the comment.Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)
+ +

In summary, we recommend looking for the string “Mobi” anywhere in the User Agent to detect a mobile device.

+ +
+

If the device is large enough that it's not marked with “Mobi”, you should serve your desktop site (which, as a best practice, should support touch input anyway, as more desktop machines are appearing with touchscreens).

+
diff --git "a/files/ko/web/http/user_agent\353\245\274_\354\235\264\354\232\251\355\225\234_\353\270\214\353\235\274\354\232\260\354\240\200_\352\260\220\354\247\200/index.html" "b/files/ko/web/http/user_agent\353\245\274_\354\235\264\354\232\251\355\225\234_\353\270\214\353\235\274\354\232\260\354\240\200_\352\260\220\354\247\200/index.html" deleted file mode 100644 index 8ffc0ff0b5..0000000000 --- "a/files/ko/web/http/user_agent\353\245\274_\354\235\264\354\232\251\355\225\234_\353\270\214\353\235\274\354\232\260\354\240\200_\352\260\220\354\247\200/index.html" +++ /dev/null @@ -1,296 +0,0 @@ ---- -title: 사용자 에이전트를 이용한 브라우저 감지 -slug: Web/HTTP/User_agent를_이용한_브라우저_감지 -tags: - - Compatibility - - HTTP - - Web Development -translation_of: Web/HTTP/Browser_detection_using_the_user_agent ---- -
{{HTTPSidebar}}
- -

보통 브라우저마다 다른 웹 페이지 또는 서비스를 제공하는 것은 나쁜 생각입니다. 웹은 사용자가 어떤 브라우저나 디바이스를 사용하고 있는지 개의치 않고 모두에게 접근성이 용이해야 하기 때문입니다. 따라서 특정 브라우저를 타겟으로 개발하는 것보다 가용적인 기능들 (예를 들어 Web API 등)을 이용하여 당신의 웹 사이트를 개선하는 것을 추천합니다.

- -

하지만 브라우저와 웹 표준은 완벽하지 않고 그 간극은 여전히 브라우저 감지 기능을 필요로 합니다. User-Agent를 사용하여 브라우저를 감지하는 것은 간단해 보이지만, 사실 그것을 잘 이용하는 것은 무척 힘든 일입니다. 이 문서는 사용자 에이전트를 이용하여 브라우저를 바르게 감지하도록 안내합니다.

- -
-

주의하세요! user agent 정보를 가로채는 것은 좋은 아이디어가 아닙니다. 대부분의 경우 호환성이 뛰어난 좋은 다른 해결방안을 찾을 수 있을 것입니다.

-
- -

브라우저 감지를 하기 전 고려할 것

- -

사용자 에이전트 문자열을 이용해 브라우저를 감지하기 전에 가능하다면 이것을 사용하지 않는 것이 첫 번째입니다. 내가 이 기능을 원하는지 다시 한 번 스스로 확인하길 바랍니다.

- -
-
특정 브라우저 버전의 버그를 고치려고 하나요?
-
포럼에서 찾아보십시오. 만약 이 버그를 당신이 처음 발견했다면 포럼에 질문을 하십시오. 또한 전문가나 다른 견해를 가진 이들이 이 버그를 해결하는데 도움을 줄 것입니다. 만약 버그가 좀처럼 없는 문제라면 브라우저 제공자의 버그 추적 시스템(MozillaWebKitBlinkOpera)에 보고된 버그인지 확인하세요.
-
특정 기능의 존재를 확인하려고 하나요?
-
당신의 사이트에 몇몇 브라우저에서 아직 지원하지 않은 기능을 사용해야 하고, 해당 유저들을 이전 버전의 웹사이트로 보내고 싶어 하지만 당신은 후에 해당 브라우저에서 해당 기능이 동작할 것이라는걸 압니다. 이것이 사용자 에이전트 탐지를 사용하는 가장 나쁜 이유인데, 결국 다른 브라우저들이 그 문제를 따라잡을 것이기 때문입니다. 이러한 시나리오에서 당신은 가능한 유저 에이전트 탐지를 절대 피해야 하고, 대신 언제나 기능탐지를 하는데 최선을 다해야 합니다. 대신 언제든지 기능 탐지를 할 수 있는 대체방안이 존재합니다
-
사용하는 브라우저에 따라 다른 HTML을 제공해야 하나요?
-
이는 권해드리고 싶지 않지만, 필요에 따른 몇가지 방법이 있습니다. 이러한 상황들일 경우, 우선 브라우저에 따른 다양한 HTML을 사용해야 하는지 결정하기 위해 당신의 상황을 분석할 필요가 있습니다. 당신은 non-semantic인  {{ HTMLElement("div") }} 나 {{ HTMLElement("span") }}  요소를 추가함으로써 이를 방지할 수 있나요? user Agent 감지를 성공적으로 하는 것의 어려움은 몇몇 혼란스러운 HTML을 깨끗하게 바꾸는데 가치가 있습니다. 또한 당신의 디자인에 대해 다시한번 생각해보세요. 브라우저별로 다른 HTML을 사용할 필요성을 없애기 위해 점진적 향상(progressive enhancement)이나 가변 레이아웃(fluid layout)을 사용할 수 있나요?
-
- -

사용자 에이전트를 대신할 방법

- -

user agent 감지를 피하는 몇 가지 방법이 있습니다!

- -
-
기능 탐지
-
기능 탐지는 어떤 브라우저가 당신의 페이지를 렌더링하는지를 알아내려고 할 때가 아니라, 어떤 특정한 기능을 당신이 사용가능한지를 확인할 때 사용합니다. 그렇지 않다면, 대비책을 사용하세요. 브라우저 간의 차이점을 찾는 몇 안되는 경우에서는 user agent 문자열을 사용하는 대신, 브라우저가 API를 구현하는 방법을 탐지하고 API를 사용하는 방법을 결정하는 테스트를 구현하는 것이 좋습니다. 아래는 기능탐지의 좋은 최신 예시 입니다. 최근 크롬은 experimental lookbehind support to regular expressions을 추가했지만, 다른 브라우저들은 이를 지원하지 않습니다. 그러므로 당신은 이와 같이 해야 한다고 잘못 생각하고 있을 것입니다.
-
-
// 아래 코드 조각은 한 문자열을 특별한 표기법으로 쪼갭니다.
-
-if (navigator.userAgent.indexOf("Chrome") !== -1){
-    // 네! 이 사용자가 정규표현식의 look-behind 기능을 사용하려는 것
-    //  같습니다.
-    // /(?<=[A-Z])/를 사용하지 마십시오. 정규표현식의
-    //  look-behind 기능을 지원하지 않는 브라우저에서는 문법오류가
-    //  발생할 것입니다. 왜냐하면, 모든 브라우저들은 실제로 실행되지
-    //  않는 부분을 포함한 전체 스크립트를 해석하기 때문입니다.
-    var camelCaseExpression = new RegExp("(?<=[A-Z])");
-    var splitUpString = function(str) {
-        return (""+str).split(camelCaseExpression);
-    };
-} else {
-    /*아래 fallback 코드는 성능이 떨어지지만 작동하긴 합니다.*/
-    var splitUpString = function(str){
-        return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g);
-    };
-}
-console.log(splitUpString("fooBare")); // ["fooB", "are"]
-console.log(splitUpString("jQWhy")); // ["jQ", "W", "hy"]
- -

위의 코드는 다음과 같은 몇 가지 잘못된 가정을 했습니다.

- -
    -
  • 하위 문자열 "Chrome"을 포함하는 모든 사용자 에이전트 문자열은 크롬이라고 가정했습니다. UA 문자열은 틀릴 가능성이 매우 높습니다.
  • -
  • 정규표현식의 look-behind 기능이 크롬 브라우저에서는 항상 지원될 것이라고 가정했습니다. 하지만 agent가 해당 기능이 지원되기 전인 옛 버전의 크롬일 수도 있고, 당시에는 look-behind는 실험적 기능이었기 때문에, 이를 제거한 버전의 크롬일 수도 있습니다.
  • -
  • 가장 중요한 점은, 다른 모든 브라우저들이 look-behind를 지원할 것이라고 가정했습니다. 다른 브라우저들도 look-behind 기능을 지원하는 버전이 모두 다를텐데, 이 코드는 이를 무시하고 코드를 진행합니다.
  • -
- -

look-behind 지원여부 자체를 테스트함으로써 이 문제들을 회피할 수 있습니다.

- -
var isLookBehindSupported = false;
-
-try {
-    new RegExp("(?<=)");
-    isLookBehindSupported = true;
-} catch (err) {
-    // agent가 look-behind 기능을 지원하지 않는다면, 위 문법을 사용한
-    // RegExp 객체의 생성이 에러를 던질 것이고, isLookBehindSupported는
-    // 여전히 false일 것입니다.
-}
-
-var splitUpString = isLookBehindSupported ? function(str) {
-    return (""+str).split(new RegExp("(?<=[A-Z])"));
-} : function(str) {
-    return str.replace(/[A-Z]/g,"z$1").split(/z(?=[A-Z])/g);
-};
-
- -

위의 코드가 시범을 보였듯이, user agent를 살펴보지 않고도 어떤 기능에 대한 브라우저 지원 여부를 시험할 수 있는 방법이 항상 존재합니다. 기능 지원 여부를 확인하기 위해 user agent 문자열을 확인할 필요가 전혀 없습니다.

- -

마지막으로, 위의 코드 조각은 크로스 브라우저 코딩과 관련하여 항상 염두에 두어야만 하는 중요한 이슈를 시사합니다.테스트 중인 API를 해당 기능이 지원되지 않는 브라우저에서 실수로 사용하지 마십시오. 확실하고 단순한 이야기 같지만, 때때로 그렇지 않습니다. 예를 들어, 위의 코드 조각에서, lookbehind 기능을 short-regexp 표기법(예를 들어, /reg/igm)으로 사용한다면, 지원되지 않는 브라우저에서는 파싱 에러가 발생할 것입니다. 따라서, 위의 예제에서, /(?<=look_behind_stuff)/ 대신에 new RegExp("(?<=look_behind_stuff)")를 사용하는 것이 좋습니다. 심지어 lookbehind가 지원되는 조건분기의 코드에서도 말입니다.

-
-
점진적 향상
-
이 디자인 테크닉은 여러분의 사이트를 상향식 접근방법으로 "레이어" 형태 개발할 수 있게 해줍니다. 간단한 레이어로 시작하여, 각각이 더 많은 기능을 이용하는 연속적인 레이어를 가진 사이트로 성능을 개선할 수 있습니다.
-
부드러운 하향
-
이는 여러분이 원하는 모든 기능이 포함된 최선의 사이트를 만들고 나서 오래된 브라우저들도 지원하게 수정하는 하향식 접근입니다. 점진적 상향 방식보다는 조금 더 어렵기도 하고 덜 효과적이기도 하지만, 몇몇 케이스에서는 유용할 것입니다.
-
모바일 장치 감지
-
Arguably the most common use and misuse of user agent sniffing is to detect if the device is a mobile device. However, what is failed to be accountable is what they're really after. People use user agent sniffing to detect if the users' device is touch-friendly and has a small screen so they can optimize their website accordingly. While user agent sniffing can sometimes detect these, not all devices are the same. Some mobile devices have big screen sizes, some desktops have a small touchscreen, some people use smart TV's which are an entirely different ballgame altogether, some people can dynamically change the width and height of their screen by flipping their tablet on its side! So, user agent sniffing is definitely not the way to go. But, there are much better alternatives. Use Navigator.maxTouchPoints to detect if the user's device has a touchscreen. Then, default back to checking the user agent screen only if (!("maxTouchPoints" in Navigator)) { /*Code here*/}. Using this information of whether the device has a touchscreen, do not change the entire layout of the website just for touch devices: you will only create more work and maintenance for yourself. Rather, add in touch conveniences such as bigger, more easily clickable buttons (you can do this using CSS by simply increasing the font size). As for the screen size, simply use window.innerWidth and window.addEventListener("resize", function(){ /*refresh screen size dependent things*/ }). What you want to do for screen size is not slash off information on smaller screens. That will only annoy people because it will force them to use the desktop version. Rather, try to have fewer columns of information in a longer page on smaller screens while having more columns with a shorter page on larger screen sizes. This effect can be easily achieved using CSS flexboxes. Next, always make your code dynamic. The user can flip their mobile device on its side, changing the width and height of the page. Never be satisfied with your webpage until you can open up the dev tools side panel and resize the screen while the webpage looks smooth, fluid, and dynamically resized.
-
- -

Which part of the user agent contains the information you are looking for

- -

As there is no uniformity of the different part of the user agent string, this is the tricky part.

- -

브라우저 이름

- -

사람들이 "브라우저 감시(browser detection)"을 원한다고 말할 때, 실제로 대부분 그들은 "렌더링 엔진 탐지(rendering engine detection)"를 원합니다. Do you actually want to detect Firefox, as opposed to SeaMonkey, or Chrome as opposed to Chromium? Or do you actually simply want to see if the browser is using the Gecko or the WebKit rendering engine? If this is what you need, see further down the page.

- -

Most browser set the name and version in the format BrowserName/VersionNumber, with the notable exception of Internet Explorer. But as the name is not the only information in a user agent string that is in that format, you can not discover the name of the browser, you can only check if the name you are looking for. But note that some browsers are lying: Chrome for example reports both as Chrome and Safari. So to detect Safari you have to check for the Safari string and the absence of the Chrome string, Chromium often reports itself as Chrome too or Seamonkey sometimes reports itself as Firefox.

- -

Also pay attention not to use a simple regular expression on the BrowserName, user agents also contain strings outside the Keyword/Value syntax. Safari & Chrome contain the string 'like Gecko', for instance.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
반드시 포함반드시 포함하지 않음
FirefoxFirefox/xyzSeamonkey/xyz
SeamonkeySeamonkey/xyz
ChromeChrome/xyzChromium/xyz
ChromiumChromium/xyz
SafariSafari/xyzChrome/xyz or Chromium/xyzSafari gives two version number, one technical in the Safari/xyz token, one user-friendly in a Version/xyz token
Opera -

OPR/xyz [1]

- -

Opera/xyz [2]

-
-

[1]  Opera 15+ (Blink-based engine) 

- -

[2] Opera 12- (Presto-based engine)

-
Internet Explorer; MSIE xyz;Internet Explorer doesn't put its name in the BrowserName/VersionNumber format
- -

Of course, there is absolutely no guarantee that another browser will not hijack some of these things (like Chrome hijacked the Safari string in the past). That's why browser detection using the user agent string is unreliable and should be done only with the check of version number (hijacking of past versions is less likely).

- -

브라우저 버전

- -

The browser version is often, but not always, put in the value part of the BrowserName/VersionNumber token in the User Agent String. This is of course not the case for Internet Explorer (which puts the version number right after the MSIE token), and for Opera after version 10, which has added a Version/VersionNumber token.

- -

Here again, be sure to take the right token for the browser you are looking for, as there is no guarantee that others will contain a valid number.

- -

렌더링 엔진

- -

As seen earlier, in most cases, looking for the rendering engine is a better way to go. This will help to not exclude lesser known browsers. Browsers sharing a common rendering engine will display a page in the same way: it is often a fair assumption that what will work in one will work in the other.

- -

There are five major rendering engines: Trident, Gecko, Presto, Blink and WebKit. As sniffing the rendering engines names is common, a lot of user agents added other rendering names to trigger detection. It is therefore important to pay attention not to trigger false-positives when detecting the rendering engine.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
반드시 포함
GeckoGecko/xyz
WebKitAppleWebKit/xyzPay attention, WebKit browsers add a 'like Gecko' string that may trigger false positive for Gecko if the detection is not careful.
PrestoOpera/xyzNote: Presto is no longer used in Opera browser builds >= version 15 (see 'Blink')
TridentTrident/xyzInternet Explorer put this token in the comment part of the User Agent String
BlinkChrome/xyz
- -

렌더링 엔진 버전

- -

Most rendering engine put the version number in the RenderingEngine/VersionNumber token, with the notable exception of Gecko. Gecko puts the Gecko version number in the comment part of the User Agent after the rv: string. From Gecko 14 for the mobile version and Gecko 17 for the desktop version, it also puts this value in the Gecko/version token (previous version put there the build date, then a fixed date called the GeckoTrail).

- -

운영체제

- -

The Operating System is given in most User Agent strings (although not web-focussed platforms like Firefox OS), but the format varies a lot. It is a fixed string between two semi-colons, in the comment part of the User Agent. These strings are specific for each browsers. They indicates the OS, but also often its version and information on the relying hardware (32 or 64 bits, or Intel/PPC for Mac).

- -

Like in all cases, these strings may change in the future, one should use them only in conjunction for the detection of already released browsers. A technological survey must be in place to adapt the script when new browser versions are coming out.

- -

모바일, 태블릿, 데스크톱

- -

The most common reason to perform user agent sniffing is to determine which type of device the browser runs on. The goal is to serve different HTML to different device types.

- -
    -
  • Never assume that a browser or a rendering engine only runs on one type of device. Especially don't make different defaults for different browsers or rendering engines.
  • -
  • Never use the OS token to define if a browser is on mobile, tablet or desktop. The OS may run on more than one type of (for example, Android runs on tablets as well as phones).
  • -
- -

The following table summarizes the way major browser vendors indicate that their browsers are running on a mobile device:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Common browsers User Agent strings
브라우저규칙예제
Mozilla (Gecko, Firefox)Mobile or Tablet token in the comment.Mozilla/5.0 (Android; Mobile; rv:13.0) Gecko/13.0 Firefox/13.0
WebKit-based (Android, Safari)Mobile Safari token outside the comment.Mozilla/5.0 (Linux; U; Android 4.0.3; de-ch; HTC Sensation Build/IML74K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
Blink-based (Chromium, Google Chrome, Opera 15+)Mobile Safari token outside the commentMozilla/5.0 (Linux; Android 4.4.2); Nexus 5 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.117 Mobile Safari/537.36 OPR/20.0.1396.72047
Presto-based (Opera 12-) -

Opera Mobi/xyz token in the comment (Opera 12-)

-
-

Opera/9.80 (Android 2.3.3; Linux; Opera Mobi/ADR-1111101157; U; es-ES) Presto/2.9.201 Version/11.50

-
Internet ExplorerIEMobile/xyz token in the comment.Mozilla/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident/5.0; IEMobile/9.0)
- -

In summary, we recommend looking for the string “Mobi” anywhere in the User Agent to detect a mobile device.

- -
-

If the device is large enough that it's not marked with “Mobi”, you should serve your desktop site (which, as a best practice, should support touch input anyway, as more desktop machines are appearing with touchscreens).

-
diff --git a/files/ko/web/javascript/a_re-introduction_to_javascript/index.html b/files/ko/web/javascript/a_re-introduction_to_javascript/index.html new file mode 100644 index 0000000000..7206716138 --- /dev/null +++ b/files/ko/web/javascript/a_re-introduction_to_javascript/index.html @@ -0,0 +1,1038 @@ +--- +title: JavaScript 재입문하기 (JS ​튜토리얼) +slug: A_re-introduction_to_JavaScript +tags: + - CodingScripting + - Intermediate + - Intro + - JavaScript + - Learn + - Tutorial +translation_of: Web/JavaScript/A_re-introduction_to_JavaScript +--- +
{{jsSidebar}}
+ +

어째서 재입문일까요? 왜냐하면, JavaScript세계에서 가장 오해받고 있는 프로그래밍 언어로 악명이 높기 때문입니다. 종종 장난감같다고 조롱당하기도했지만, 이 거짓말같은 단순함 아래에는 몇 가지의 강력한 언어 기능이 숨어 있습니다. Javascript는 현재 엄청나게 많은, 요즘 가장 뜨고있는 애플리케이션들에 사용되고 있어서, 웹 또는 모바일 개발자 누구에게라도 이 기술에 대한 깊은 지식이 중요한 기량이 된다는 것을 보여주고 있습니다.

+ +

이 이야기를 이해하는데는 이 언어의 역사를 먼저 보는 것이 도움이 됩니다. JavaScript는 1995년 Netscape의 엔지니어 Brendan Eich에 의해 만들어졌고, 1996년 초에 Netscape 2와 함께 처음 릴리즈 되었습니다. 이것은 원래 LiveScript로 불리기로 되어 있었습니다만 Sun Microsystem의 Java 언어의 성공에 편승해보려고 -두 언어 사이의 공통점이 매우 적음에도 불구하고- 불행이 예견된 마케팅 결정에 따라 이름이 바뀌게 됩니다. 이 결정은 역사상 유래가 없는 혼란의 근원이 되어버립니다.

+ +

몇 달 후, Microsoft는 IE3와 함께 JScript를 발표했습니다. 이 JScript는 Javascript를 정말 닮았고 호환성이 좋았습니다. 몇 달 뒤에, Netscape는 1997년에 ECMAScript 표준의 첫번째 판이 되는 JavaScript를 유럽 표준화 단체인 Ecma International에 보냅니다. 이 표준은 1999년에 ECMAScript edition 3에 따라 큰 규모의 개정을 거친 후, 유례없이 아주 안정된 상태로 계속 유지되고 있습니다. 4번째 판은 중도 포기되었는데, 언어의 복잡성 증가에 관련한 정치적 문제 때문이었습니다. 이 4번째 판의 많은 파트들은 ECMAScript edition 5 (2009년 12월에 출간)와 6번째 개정판 규격(2015년에 출간)의 근간을 형성하고 있습니다. 

+ +
+

 이제부터는 ECMAScript를 우리에게 좀 더 친근한 말인  "JavaScript"라고 부르겠습니다.

+
+ +

대부분의 프로그래밍 언어와는 달리, JavaScript 언어는 입출력 개념이 없습니다. 이 언어는 호스트 환경 아래에서 스크립트 언어로서 동작하도록 디자인 되어있고, 따라서 외부 세계와 통신하기위해 호스트 환경이 제공하는 메커니즘에 의존합니다. 대부분의 경우 일반적인 호스트 환경은 브라우저이지만 JavaScript 인터프리터는 Adobe Acrobat, Photoshop, SVG images, Yahoo! 위젯 엔진 등의 제품에서도 발견할 수 있고, node.js 와 같은 서버 측 환경에서도 찾을 수 있습니다. 하지만 JavaScript가 사용되는 분야는 계속 더 넓혀지고 있습니다. NoSQL 데이터베이스, Apache CouchDB, 임베디드 컴퓨터, GNU/Linux OS의 가장 유명한 GUI 인 GNOME 과 같은 데스크톱 환경에서도 JavaScript가 사용됩니다.

+ +

개요

+ +

JavaScript는 유형 및 연산자, 표준 내장 객체 및 메소드가 있는 다중 패러다임, 동적 언어입니다. 구문은 Java 및 C 언어를 기반으로합니다. 이러한 언어의 많은 구조가 JavaScript에도 적용됩니다. JavaScript는 클래스 대신 객체 프로토 타입을 사용하여 객체 지향 프로그래밍을 지원합니다 (프로토 타입 상속 및 ES2015 {{jsxref("Classes")}}). JavaScript는 함수형 프로그래밍도 지원합니다. 함수는 객체이며, 함수는 실행 가능한 코드를 유지하고 다른 객체와 마찬가지로 전달 될 수 있습니다.

+ +

어떤 언어에서라도 기초가 되는 부분인 타입을 살펴보는 것부터 시작해봅시다. JavaScript 프로그램은 값을 다루고 해당 값은 모두 타입을 가지고 있습니다. JavaScript의 타입은 다음과 같습니다:

+ + + +

... 오, 그리고 약간 특별한 타입인 정의되지 않음(Undefined) 과 널(Null) 이 있습니다. 또한 객체의 특별한 종류인 배열(Array) 객체. 그리고 자유롭게 사용할 수 있는 날짜(Date) 객체정규식(RegExp) 객체가 있습니다. 그리고 기술적으로 정확히 말해 함수(Function)는 단지 객체의 특별한 타입으로 취급됩니다. 따라서 타입 구조도를 정리해보면 다음과 같습니다:

+ + + +

그리고 또 몇 가지 오류 타입이 내장되어 있습니다. 그렇지만 처음 구조도를 기억하고만 있으면 다른 것들도 아주 쉽게 이해할 수 있을 것입니다.

+ +

수 (Numbers)

+ +

설계 명세서에 의하면 JavaScript에서 수는 "이중정밀도 64비트 형식 IEEE 754 값"으로 정의됩니다. 이것은 몇가지 흥미로운 결과를 가져옵니다. JavaScript에는 정수와 같은 것이 존재하지 않으므로 ({{jsxref("BigInt")}} 제외), 조금 조심해야 합니다. 이 예제를 보세요:

+ +
console.log(3 / 2);             // 1이 아닌, 1.5
+console.log(Math.floor(3 / 2)); // 1
+ +

명백한 정수는 사실 암묵적으로 실수입니다.

+ +

또한, 다음과 같은 것들을 주의하세요:

+ +
0.1 + 0.2 = 0.30000000000000004
+
+ +

실제로 정수 값은 32 비트 정수로 처리되며 일부 구현은 32 비트 정수가 아닌 숫자에 유효한 명령어를 수행 할 때까지 이러한 방식으로 저장합니다. 이는 비트 단위 작업에 중요 할 수 있습니다.

+ +

덧셈, 뺄셈, 계수 (또는 나머지) 연산을 포함하는 표준 산술 연산자가 지원됩니다. 또한 앞에서 언급하는 것을 깜박 잊은 고급 수학 함수와 상수를 다루기 위한 수학(Math)으로 불리는 내장 객체가 있습니다:

+ +
Math.sin(3.5);
+var circumference = 2 * Math.PI * r;
+ +

내장 parseInt() 함수를 사용하여 문자열을 정수로 변환할 수 있습니다. 이는 다음과 같이 옵션으로 주어지는 두번째 매개변수를 밑으로 하여 수행할 수 있습니다:

+ +
parseInt('123', 10); // 123
+parseInt('010', 10); // 10
+ +

구형 브라우저에서 "0"으로 시작하는 문자열은 8 진수 (기수 8)로 가정되지만, 2013 년 이후에는 그렇지 않습니다. 문자열 형식이 확실하지 않으면 이전 브라우저에서 놀라운 결과를 얻을 수 있습니다.

+ +
parseInt('010');  //  8
+parseInt('0x10'); // 16
+ +

이 같은 결과는 {{jsxref("Global_Objects/parseInt", "parseInt()")}} 함수가 0으로 시작되는 문자열을 8진수로, "0x"로 시작하는 문자열은 16진수로 취급하기 때문에 발생합니다. 16진수 표기법이 그대로 유지됩니다. 8진수는 제거되었습니다.

+ +

만약 이진수를 정수로 변환하고 싶다면, 밑을 바꾸기만하면 됩니다:

+ +
parseInt('11', 2); // 3
+
+ +

이와 비슷하게, 내장 함수 {{jsxref("Global_Objects/parseFloat", "parseFloat()")}}를 사용하여 부동 소수점 숫자를 파싱 할 수 있습니다. {{jsxref("Global_Objects/parseInt", "parseInt()")}}과 달리 parseFloat()는 항상 10진수를 사용합니다.

+ +

단항 연산자 + 를 사용하여 값을 숫자로 변환 할 수도 있습니다:

+ +
+ '42';   // 42
++ '010';  // 10
++ '0x10'; // 16
+ +

문자열이 수가 아닌 경우 NaN ("Not a Number" (수가 아님)을 줄인 약자)로 불리는 특별한 값을 돌려줍니다:

+ +
parseInt('hello', 10); // NaN
+
+ +

NaN 는 독성을 가지고 있습니다: 어떤 수학 연산의 입력값으로써 주어지면 그 결과는 역시 NaN가 되기 때문입니다:

+ +
NaN + 5; // NaN
+
+ +

내장 isNaN() 함수를 사용해서 NaN 인지 여부를 검사할 수 있습니다:

+ +
isNaN(NaN); // true
+
+ +

JavaScript는 또 특별한 값 Infinity-Infinity를 가지고 있습니다:

+ +
 1 / 0; //  Infinity
+-1 / 0; // -Infinity
+ +

내장 함수 {{jsxref("Global_Objects/isFinite", "isFinite()")}}를 사용하여 Infinity, -Infinity 및 NaN 값을 테스트 할 수 있습니다.

+ +
isFinite(1 / 0);     // false
+isFinite(-Infinity); // false
+isFinite(NaN);       // false
+ +
+

{{jsxref("Global_Objects/parseInt", "parseInt()")}} 와 {{jsxref("Global_Objects/parseFloat", "parseFloat()")}} 함수는 숫자로 아닌 문자가 나올때까지 문자열을 파싱하고, 그 지점까지 파싱된 숫자를 반환합니다. 그런데 "+"연산자는 중간에 유효하지 않은 문자가 있으면 그대로 문자열을 NaN 으로 그냥 변환해버립니다. console에서 "10.2abc"를 파싱해보면 어떤점이 다른지 더 쉽게 이해할 수 있습니다.

+
+ +

문자열 (Strings)

+ +

JavaScript에서 문자열은 유니코드 문자들이 연결되어 만들어진 것입니다. 이는 국제화(i18n, internationalization) 하려하는 누구에게라도 환영받을만한 소식입니다. 좀 더 정확히 말하자면, 각각이 16비트 숫자로 표현된 UTF-16 코드 유닛이 길게 이어져있는 것입니다. 각 유니코드 문자는 1개나 2개의 코드 유닛으로 표현됩니다.

+ +

한 개의 문자를 나타내려면 길이가 1인 문자열을 사용하면 됩니다.

+ +

문자열의 길이를 알고싶다면, 해당 문자열의 length 속성(해당 객체가 소유하고 있는 성질을 나타내는 값)에 접근하면 됩니다:

+ +
'hello'.length; // 5
+
+ +

우리의 첫 JavaScript 객체입니다! 문자열도 역시 객체로 취급된다고 언급했던적이 있죠? 다음과 같이 메소드까지 있는 확실한 녀석입니다:

+ +
'hello'.charAt(0); // "h"
+'hello, world'.replace('hello', 'goodbye'); // "goodbye, world"
+'hello'.toUpperCase(); // "HELLO"
+ +

이외의 타입들

+ +

JavaScript는 의도적으로 값이 없음을 가리키는 '객체' 타입의 객체인 null과 초기화되지 않은 값 — 아직 어떤 값도 주어지않은(할당되지않은) 변수임을 가리키는 '정의되지 않음' 타입의 객체인 undefined로 구분됩니다. 값에 대해서 나중에 언급할 것이지만 JavaScript에서 변수에 값을 주지않고 선언하는 것이 가능합니다. 이럴 경우, 변수의 타입은 undefined이 되는 것입니다.

+ +

JavaScript는 truefalse 값 (둘은 모두 키워드로 예약되어있는 값)을 가질 수 있는 부울 타입을 가지고 있습니다. 다음과 같은 규칙에 따라 어떤 임의의 값을 부울값으로 변환할 수 있습니다:

+ +
    +
  1. false, 0, 빈 문자열 (""), 수가 아님을 뜻하는 NaN, null, 와 undefined은 모두 false가 됩니다.
  2. +
  3. 다른 모든 값은 true가 됩니다.
  4. +
+ +

이 변환은 Boolean() 함수를 써서 명시적으로 이 작업을 수행하실 수 있습니다:

+ +
Boolean('');  // false
+Boolean(234); // true
+ +

하지만 반드시 이렇게 할 필요는 거의 없습니다. JavaScript는 이러한 변환 작업을 if 문 (아래를 보세요)과 같이 부울값이 필요한 경우를 만나게되면 자동으로 사용자가 모르는 사이에 처리해버리기 때문입니다. 이러한 이유로 인해 우리는 가끔 부울 타입으로 변환되었을 때, truefalse이 됨을 의미하는 값들을 각각 "참 값"과 "거짓 값"으로 부를 것입니다. 또는 각각 "참으로 취급되다"와 "거짓으로 취급되다"라는 식으로 불릴 수도 있습니다.

+ +

부울 연산자는 && (논리적와, 그리고 ), || (논리적또는 ), 그리고 ! (논리적부정 )이 지원됩니다. 아래에서 다시 언급하겠습니다.

+ +

변수 (Variables)

+ +

JavaScript에서 새로운 변수는 let, constvar 키워드로 선언됩니다.

+ +

let을 사용하면 블록 유효 범위 변수를 선언 할 수 있습니다. 선언 된 변수는 변수가 포함 된 함수 블록에서 사용할 수 있습니다.

+ +
let a;
+let name = 'Simon';
+ +

아래는 let으로 선언한 변수가 가지는 유효 범위의 예제입니다. 

+ +
// myLetVariable는 여기에서 보이지 *않습니다*
+
+for (let myLetVariable = 0; myLetVariable < 5; myLetVariable++) {
+  // myLetVariable는 여기에서 유효합니다
+}
+
+// myLetVariable는 여기에서 보이지 *않습니다*
+ +

const는 값이 변경되지 않는 변수를 선언 할 수 있게 합니다. 변수는 변수가 선언 된 함수 블록에서 사용할 수 있습니다.

+ +
const Pi = 3.14; // 변수 Pi 설정
+Pi = 1; // 상수로 설정된 변수는 변경 할 수 없기 때문에 애러 발생.
+ +

var은 가장 일반적인 변수 선언 키워드입니다. let, const 키워드가 가지는 제한을 var은 갖지 않습니다. 이는 자바스크립트에서 변수를 선언하는 전통적인 유일한 방법이었기 때문입니다. var 키워드로 선언 된 변수는 변수가 선언 된 함수 블록에서 사용 할 수 있습니다.

+ +
var a;
+var name = 'Simon';
+ +

var로 선언한 변수의 유효 범위 예제입니다.

+ +
// myVarVariable는 여기에서 사용 할 수 *있습니다*
+
+for (var myVarVariable = 0; myVarVariable < 5; myVarVariable++) {
+  // myVarVariable는 함수 전체에서 사용 할 수 있습니다.
+}
+
+// myVarVariable는 여기에서 사용 할 수 *있습니다*
+ +

변수에 값을 지정하지 않고 변수를 선언하면, 타입은 undefined로 지정 됩니다.

+ +

자바스크립트와 자바 같은 다른 언어 사이의 중요한 차이점은 자바스크립트는 블록에 범위가 없다는 것입니다. 함수에만 범위가 있습니다. 변수가 복합 문에서 (예를 들어 if 제어 구조 내에서) var를 사용하여 정의 된 경우 전체 함수에서 볼 수 있습니다. 그러나 ECMAScript 2015부터 letconst 선언을 사용하면 블록 범위 변수를 만들 수 있습니다.

+ +

연산자 (Operators)

+ +

JavaScript의 산술 연산자로는 +, -, *, /, %(나머지 연산자)가 있습니다. 값은 = 연산자로 할당할 수 있고, +=-=처럼 다른 연산자를 같이사용해서 할당할 수 있습니다. 이렇게 쓰인 연산자는 x = x연산자 y와 같은 결과를 나타냅니다.

+ +
x += 5;
+x = x + 5;
+
+ +

++-- 를 각각 점진적인 증가와 감소에 사용할 수 있습니다. 이들은 또한 전처리 또는 후처리 연산자로 사용될 수 있습니다.

+ +

+ 연산자는 문자열 이어붙이기도 합니다:

+ +
'hello' + ' world'; // "hello world"
+
+ +

문자열에 어떤 수 (또는 다른 값)를 더하면 일단 모두 문자열로 바뀌게 됩니다. 다음 예를 보시면 무슨 말씀인지 아실 수 있을겁니다:

+ +
'3' + 4 + 5;  // "345"
+ 3 + 4 + '5'; // "75"
+ +

빈 문자열에 어떤 값을 더하는 것은 해당 값을 문자열로 바꾸는 요령입니다.

+ +

JavaScript에서 비교<, >, <=>= 를 통해 가능합니다. 이 연산자들은 문자열과 수 양쪽 모두에서 동작합니다. 상동은 약간 직관성이 떨어지는데 이중 등호 (==) 연산자는 서로 다른 타입을 줄 경우 타입 강제 변환을 수행하기 때문에 다음과 같이 때때로 기대하지 않은 결과를 내보내기 때문입니다:

+ +
123 == '123'; // true
+1 == true;    // true
+
+ +

타입 강제 변환을 하지 않게 하려면, 삼중 등호 연산자 (===)를 사용해야합니다:

+ +
123 === '123'; // false
+1 === true;    // false
+
+ +

이와 비슷하게 !=!== 연산자가 있습니다.

+ +

JavaScript는 값을 비트로 취급하는 연산자도 가지고 있습니다. 사용하고 싶을 때 언제라도 사용할 수 있도록 말이죠.

+ +

제어 구조

+ +

JavaScript는 C 계열의 다른 언어들과 비슷한 제어 구조를 가지고 있습니다. 조건문은 ifelse를 지원하는데, 원하시는대로 얼마든지 중첩 시켜서 사용할 수 있습니다:

+ +
var name = 'kittens';
+if (name == 'puppies') {
+  name += ' woof';
+} else if (name == 'kittens') {
+  name += ' meow';
+} else {
+  name += '!';
+}
+name == 'kittens meow';
+
+ +

JavaScript는 while 반복문과 do-while 반복문도 사용할 수 있습니다. 첫번째 것은 단순 반복에 유용하게 사용할 수 있고, 두번째 것은 반복문이 반드시 적어도 한번이상 실행 되도록 하고 싶을 때 사용할 수 있습니다:

+ +
while (true) {
+  // 무한루프!
+}
+
+var input;
+do {
+  input = get_input();
+} while (inputIsNotValid(input));
+
+ +

JavaScript의 for 반복문은 C 와 Java의 반복문과 같습니다. 말하자면, 반복문에 필요한 제어 정보를 한 줄에 표현할 수 있다는 이야기지요.

+ +
for (var i = 0; i < 5; i++) {
+  // 내부 동작을 5번 반복합니다
+}
+
+ +

JavaScript에는 두개의 중요한 for 반복문 또한 포함됩니다. 첫번째로 for...of 입니다.

+ +
for (let value of array) {
+  // value로 작업을 실행합니다
+}
+
+ +

그리고 for ... in 입니다.

+ +
for (let property in object) {
+  // object의 항목(property)으로 작업을 실행합니다
+}
+
+ +

&&|| 연산자는 첫번째 식을 평가한 결과에 따라서 두번째 식을 평가를 실행하는 단축평가(short-circuit) 논리를 사용합니다. 이는 다음과 같이 객체에 접근하기 전에 null 객체인지, 아닌지를 검사하는데 유용하게 사용될 수 있습니다:

+ +
var name = o && o.getName();
+
+ +

또는 (틀린값이 유효하지 않은 값일때) 캐싱 값에 대해서도 사용합니다.:

+ +
var name = cachedName || (cachedName = getName());
+
+ +

JavaScript는 한줄로 조건문을 쓸 수 있게 해주는 삼중 연산자도 가지고 있습니다:

+ +
var allowed = (age > 18) ? "yes" : "no";
+
+ +

switch 문은 숫자나 문자열을 기반으로 다중 분기되는 문장을 작성하는데 사용될 수 있습니다:

+ +
switch(action) {
+    case 'draw':
+        drawIt();
+        break;
+    case 'eat':
+        eatIt();
+        break;
+    default:
+        doNothing();
+}
+
+ +

break 문장을 추가하지 않았다면, 다음 단계로 "넘어가서" 실행합니다. 이렇게 되는 것을 기대하는 것은 매우 드문경우 입니다. 실은 디버깅하는데 용이하도록 하기위해 주석으로서 일부러 붙여놓은 넘어가기 이름표 입니다:

+ +
switch(a) {
+    case 1: // fallthrough
+    case 2:
+        eatIt();
+        break;
+    default:
+        doNothing();
+}
+
+ +

default 구문의 적용은 선택사항입니다. switch와 case 부분에서 둘다 표현식을 사용할 수도 있습니다. switch부분과 case 부분의 표현식은  === 연산자로 비교됩니다.

+ +
switch(1 + 3){
+    case 2 + 2:
+        yay();
+        break;
+    default:
+        neverhappens();
+}
+
+ +

객체 (Objects)

+ +

JavaScript 객체는 간단히 이름-값 쌍(name-value pairs)의 모임입니다. 그렇기 때문에, JavaScript의 객체의 모임은 다음과 비슷하다고 할 수 있습니다:

+ +
    +
  • Python의 Dictionaries
  • +
  • Perl 과 Ruby의 Hashes
  • +
  • C 와 C++ 의 Hash tables
  • +
  • Java 의 HashMaps
  • +
  • PHP의 Associative arrays
  • +
+ +

이 데이터 구조가 매우 광범위하게 사용된다는 사실은 활용 방도가 다양함을 입증합니다. JavaScript내 모든 것 (코어 타입들은 제외)은 객체로 취급되기 때문에 어떤 JavaScript 프로그램도 기본적으로 해쉬 테이블을 검색하는데 필요한 출중한 성능을 가지고 있습니다. 매우 빠르기 때문에 장점이 됩니다!

+ +

값은 객체를 포함하여 아무 JavaScript 값이 될 수 있는 반면, "이름" 부분은 JavaScript 문자열 입니다. 이는 무작위적인 복잡성을 가지는 데이터 구조를 만들 수 있도록 해줍니다.

+ +

빈 객체를 생성하는데 두가지 방법이 있습니다:

+ +
var obj = new Object();
+
+ +

와:

+ +
var obj = {};
+
+ +

이들은 의미적으로 동치입니다. 두번째 방법은 객체 리터럴 구문이라고 부르며 더 편리합니다. 객체 리터럴 구문은 JSON 구문의 핵심이며 이 방법을 사용한 코드를 더 많이 볼 수 있습니다.

+ +

객체 리터럴 구문으로 객체의 전체적인 구조를 초기화 할 수 있습니다:

+ +
var obj = {
+    name: "Carrot",
+    "for": "Max",
+    details: {
+        color: "orange",
+        size: 12
+    }
+}
+
+ +

속성에 연속적으로 접근할 수 있습니다:

+ +
obj.details.color; // orange
+obj["details"]["size"]; // 12
+
+ +

아래 예제는 객체 프로토타입(Person)과 프로토타입의 인스턴스(you)를 생성합니다.

+ +
function Person(name, age) {
+  this.name = name;
+  this.age = age;
+}
+
+// 객체를 정의한다
+var you = new Person('You', 24);
+// "You"라는 이름의 24세인 새로운 사람을 생성중이다.
+
+ +

일단 생성되면, 객체의 속성에 다음의 두가지 방법들 중 한가지로 접근할 수 있습니다:

+ +
// dot 표기법
+obj.name = "Simon"
+var name = obj.name;
+
+ +

그리고...

+ +
// bracket 표기법
+obj["name"] = "Simon";
+var name = obj["name"];
+// key를 정의하기 위해 변수도 쓸수 있습니다.
+var user = prompt('what is your key?')
+obj[user] = prompt('what is its value?')
+
+ +

이들은 의미적으로 역시 같습니다. 두번째 방법은 속성의 이름이 실행시간(run-time)에 계산될 수 있는 문자열로 주어집니다. 하지만 이방법을 사용하면 일부 JavaScript엔진과 압축기 최적화(minifier optimizations)를 적용할수 없습니다.또한 예약된 단어(키워드)로 되어있는 이름으로 객체의 속성을 설정하거나 얻어낼 수 있습니다:

+ +
obj.for = "Simon"; // 구문 오류, for 가 예약된 단어(키워드)이기 때문에
+obj["for"] = "Simon"; // 정상 동작
+
+ +
+

ECMAScript 5 이래로, 예약어는  객체 항목의 이름으로 "덧붙임없이" 사용할수도 있습니다. 이말은 객체 리터럴을 정의할때 따옴표로 "둘러쌀" 필요가 없다는 의미입니다.  ES5 Spec을 참고해 보십시오.

+
+ +

객체나 프로토타입에 대한 좀더 상세한 내용은 Object.prototype 을 참조하십시오. 객체 프로토타입과 객체 프로토타입 체인에 대한 설명은 상속과 프로토타입 체인 을 참조하십시오.

+ +
+

ECMAScript 2015 이래로, 객체의 key는 생성시의 대괄호 표기법(bracket notation)으로 정의될수 있습니다. 그냥 var userPhone = {}; userPhone[phoneType] = 12345. 처럼 표기하는 방법 대신 {[phoneType]: 12345} 와 같은 사용법도 가능합니다.

+
+ +

배열 (Arrays)

+ +

JavaScript에서 배열은 실제로는 특별한 타입의 객체입니다. (숫자로 나타낸 속성은 자연스럽게 [] 구문만을 사용해서 접근하게 되므로) 일반 객체와 많이 비슷하게 동작하지만, 이 객체는 'length'라는 한가지 마법적인 속성을 가집니다. 이는 항상 배열에서 가장 큰 인덱스보다 하나 더 큰 값으로 존재합니다.

+ +

배열을 생성하는 예전 방법은 다음과 같습니다:

+ +
var a = new Array();
+a[0] = "dog";
+a[1] = "cat";
+a[2] = "hen";
+a.length // 3
+
+ +

한가지 더 편리한 배열 표현 방법은 배열 리터럴을 사용하는 것입니다:

+ +
> var a = ["dog", "cat", "hen"];
+> a.length
+3
+
+ +

배열 리터럴 끝에 콤마(",")를 꼬리로 남겨두는 것은 브라우저마다 다르게 처리하므로 그렇게 하지는 마시기 바랍니다.

+ +

array.length 는 배열에 들어있는 항목의 수를 반드시 반영하지는 않는다는 점을 주의하시기 바랍니다. 다음과 같은 경우를 고려해보겠습니다:

+ +
> var a = ["dog", "cat", "hen"];
+> a[100] = "fox";
+> a.length
+101
+
+ +

기억해두세요 - 배열의 length 속성은 최대 인덱스에 하나를 더한 값일 뿐입니다.

+ +

존재하지 않는 배열 인덱스를 참조하려고하면 다음과 같이 undefined 을 얻게됩니다:

+ +
> typeof(a[90])
+undefined
+
+ +

[]length에 관한 위의 사항들을 감안하면 배열을 for 반복문으로 처리할 때 다음과 같은 방법으로 처리하실 수 있을 것입니다:

+ +
for (var i = 0; i < a.length; i++) {
+    // a[i] 로 뭔가를 수행
+}
+
+ +

ES2015는 배열과 같은 이터러블 객체를 위해 좀더 간결한 for...of 루프를 소개했습니다.

+ +
for (const currentValue of a) {
+    // currentValue 로 뭔가를 수행
+}
+ +

또한 for...in 루프를 이용하여 배열에 루프를 돌릴수도 있지만, 이 방법은 배열 요소를 반복하는게 아니라 배열 인덱스를 반복합니다. 뿐만 아니라, 누군가 Array.prototype에 새로운 속성을 추가하면, 그 속성들 또한 이런 루프로 반복됩니다. 따라서 이런 반복 형태는 배열에는 추천되지 않습니다.

+ +

배열에 대한 또다른 반복방법은 ECMAScript 5에 추가된 forEach() 입니다:

+ +
['dog', 'cat', 'hen'].forEach(function(currentValue, index, array) {
+    // currentValue나 array[index]로 뭔가를 수행
+}
+
+ +

배열에 항목 하나를 추가하길 원한다면 이렇게 하면 됩니다:

+ +
a.push(item);
+ +

배열은 몇가지 메서드가 제공됩니다. 배열 메서드에 대한 전체 문서를 참조하십시오.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
메서드 이름설명
a.toString()각 항목에 대한 toString()의 출력이 콤마로 구분된 한개의 문자열을 반환합니다.
a.toLocaleString()각 항목에 대한 toLocaleString()의 출력이 콤마로 구분된 한개의 문자열을 반환합니다.
a.concat(item1[, item2[, ...[, itemN]]])item들이 덧붙여진 한개의 배열을 반환합니다.
a.join(sep)배열의 값들을 sep 인자로 구분하여 합친 한개의 문자열로 변환합니다.
a.pop()배열의 마지막 항목을 반환하면서 제거합니다.
a.push(item1, ..., itemN)배열의 끝에 item들을 덧붙입니다.
a.shift()배열의 첫번째 항목을 반환하면서 제거합니다.
a.unshift(item1[, item2[, ...[, itemN]]])배열의 앞쪽에 item들을 덧붙입니다.
a.slice(start[, end])배열의 일부분을 새배열로 반환합니다.
a.sort([cmpfn])옵션으로 비교용도의 함수를 입력받습니다.
a.splice(start, delcount[, item1[, ...[, itemN]]])배열의 일부분을 제거하고 다른 항목으로 대체하여 배열을 변경합니다..
a.reverse()배열의 순서를 거꾸로 배열합니다.
+ +

함수 (Functions)

+ +

객체와 마찬가지로, 함수는 JavaScript를 이해하는데 핵심이 되는 컴포넌트입니다. 가장 기본적인 함수의 예는 다음과 같습니다:

+ +
function add(x, y) {
+    var total = x + y;
+    return total;
+}
+
+ +

이 예는 기본 함수에 대해 알아야 할 모든 것을 보여주고 있습니다. JavaScript 함수는 0 이상의 이름이 있는 매개변수를 가질 수 있습니다. 함수의 본체는 갯수 제한없이 구문을 포함할 수 있고 해당 함수에 지역적으로 변수를 보유하도록 선언할 수 있습니다. return 문은 언제나 값을 돌려주고 함수의 실행을 끝내는데 사용될 수 있습니다. 리턴 문이 없으면 (혹은 값이 없는 리턴이 사용되면), JavaScript는 undefined을 돌려줍니다.

+ +

이름 붙여진 매개변수들은 다른 어떤 것보다도 해당 함수가 어떤 함수인지 설명해주는 좋은 역할을 할 수 있습니다. 해당 함수가 원하는 매개변수를 주지않고 함수를 호출할 수 있지만 그럴 경우 해당 변수들은 undefined로 설정됩니다.

+ +
add(); //NaN
+// undefined에 대해 덧셈을 수행할 수 없습니다
+
+ +

함수가 기대하는 원래의 매개변수보다 많은 매개변수를 넘겨줄 수도 있습니다:

+ +
add(2, 3, 4); // 5
+// 처음의 두 수가 더해집니다. 4는 무시됨
+
+ +

이 예는 조금 어리석어 보이지만, 함수는 추가적으로 주어진 매개변수를 함수 내부에서 접근할수 있습니다. 이 객체는 arguments라고 하며, 해당 함수에  매개변수로 넘겨진 모든 값을 가지고 있는 배열과 비슷한 객체입니다. 우리가 원하는만큼 값을 취하는 add 함수를 다시 써보겠습니다:

+ +
function add() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum;
+}
+
+add(2, 3, 4, 5); // 14
+
+ +

확실히 2 + 3 + 4 + 5를 직접쓰는 것보다 유용한 함수는아닙니다. 평균계산 함수를 만들어 보겠습니다:

+ +
function avg() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum / arguments.length;
+}
+
+avg(2, 3, 4, 5); // 3.5
+
+ +

이건 매우 유용합니다만, 좀 번잡해보입니다. 코드 크기를 다소 줄이기 위해, arguments 배열의 사용을 Rest 파라미터 문법으로 대체해볼 필요가 있습니다. 이 방법으로, 코드 크기는 최소한으로 유지 하면서, 갯수 제한없이 함수로 인자를 전달할수 있습니다. Rest 파라미터 연산자는 다음과 같은 포맷(...variable)으로 함수 파라미터 목록에 사용됩니다. 이 varaible 인자는 함수가 호출될때 전달되는 모든 인자를 포함합니다. variable 인자에서 반환되는 값을 사용하기 위해 위 코드에서 for 루프를 for..of 루프로 변경합니다.

+ +
function avg(...args) {
+    var sum = 0;
+    for (let value of args) {
+        sum += value;
+    }
+    return sum / arr.length;
+}
+
+avg(2, 3, 4, 5); // 3.5
+
+ +
+

위 코드에서,변수 args 는 함수로 전달된  모든 값을 가지고 있습니다.
+
+ rest 파라미터 연산자가 함수 선언의 어느곳에 위치하든 선언 위치 이후에 모든 인자를 저장하는것이며, 이전이 아니라는 것이 중요합니다. 즉 , function avg(firstValue, ...args) 에서 함수로 전달된 첫번째 값은 firstValue 변수에 저장되며, 남은 변수들은 args에 저장됩니다.

+
+ +

이건 또다른 유용한 언어 특성입니다만 우리를 새로운 문제점으로 인도합니다. avg() 함수는 콤마로 구분된 인자목록을 받지만, 배열의 평균을 알고싶은 경우라면요? 함수를 다음과 같이 재작성 하면 됩니다 :

+ +
function avgArray(arr) {
+  var sum = 0;
+  for (var i = 0, j = arr.length; i < j; i++) {
+    sum += arr[i];
+  }
+  return sum / arr.length;
+}
+
+avgArray([2, 3, 4, 5]); // 3.5
+ +

하지만 우리가 이미 만든 함수를 다시 사용할 수 있다면 좋을 것입니다. 운이 좋게도 JavaScript는 함수 객체라면 모두 가지게 되는 apply() 메소드를 사용해서 임의의 매개변수 배열을 함수에 넘겨줄 수 있습니다.

+ +
> avg.apply(null, [2, 3, 4, 5])
+3.5
+
+ +

apply()의 두번째 매개변수는 '매개변수들'로 사용하고자 하는 배열입니다. 첫번째 매개변수는 나중에 설명하도록 하겠습니다. 이는 함수가 역시 객체임을 명확히 해주는 사실입니다.

+ +
+

함수 호출시 전개 연산자(spread operator) 를 이용하여 똑같은 결과를 얻을수 있습니다.

+ +

예를 들면: avg(...numbers)

+
+ +

JavaScript는 익명의 함수를 만들 수 있도록 허용하고 있습니다.

+ +
var avg = function() {
+    var sum = 0;
+    for (var i = 0, j = arguments.length; i < j; i++) {
+        sum += arguments[i];
+    }
+    return sum / arguments.length;
+}
+
+ +

이것은 의미적으로 function avg() 형식과 같습니다. 이 특징은 매우 강력한데, 일반적인 표현식(expression)을 사용할 수있는 어디에서나 완전한 함수 정의를 넣을 수 있도록 허용하는 것이기 때문입니다. 이 특징은 다양한 요령을 부릴 수 있게합니다. 다음 예는 C에서 블록 유효 범위를 적용 시킨 것 처럼 지역 변수를 "숨기는" 요령을 보여줍니다:

+ +
var a = 1;
+var b = 2;
+
+(function() {
+    var b = 3;
+    a += b;
+})();
+
+a; // 4
+b; // 2
+
+ +

JavaScript는 재귀적으로 함수를 부를 수 있습니다. 이는 브라우저 DOM 등에서 볼수 있는 트리 구조를 다루는데 유용합니다.

+ +
function countChars(elm) {
+  if (elm.nodeType == 3) { // TEXT_NODE
+    return elm.nodeValue.length;
+  }
+  var count = 0;
+  for (var i = 0, child; child = elm.childNodes[i]; i++) {
+    count += countChars(child);
+  }
+  return count;
+}
+
+ +

다음의 예는 익명 함수를 사용함에 있어 잠재적인 문제점을 보여줍니다: 이름이 없으면 어떻게 재귀적으로 부를 수 있을까요? JavaScript는 함수 표현식을 이렇게 이름붙이도록 지원합니다. 이름붙은 IIFEs (Immediately Invoked Function Expressions: 즉시 실행 함수 표현) 를 다음과 같이 사용할 수 있습니다:

+ +
var charsInBody = (function counter(elm) {
+  if (elm.nodeType == 3) { // TEXT_NODE
+    return elm.nodeValue.length;
+  }
+  var count = 0;
+  for (var i = 0, child; child = elm.childNodes[i]; i++) {
+    count += counter(child);
+  }
+  return count;
+})(document.body);
+
+ +

위와 같이 함수 표현식에 제공된 이름은 함수 자체 범위에서만 유효합니다. 이 특징은 엔진에 의한 최적화뿐만 아니라 코드 가독성을 높이는데 도움을 줍니다. 이 이름은 디버거와 스택 추적에서도 나타나므로 디버깅시간을 줄일수 있게합니다.

+ +

JavaScript 함수는 - JavsScript 내의 다른 모든 것들과 마찬가지로 -  그 자체가 객체이며, 객체 섹션에서 이미 확인한 것처럼, 속성을 추가하거나 변경할수 있다는 점을 명심하십시오

+ +

사용자 정의 객체

+ +
+

JavaScript에서 객체 지향 프로그래밍에 대한 더 자세한 논의는 객체 지향 JavaScript 소개를 참조하십시오.

+
+ +

고전 객체지향 프로그래밍에서 객체는 데이터와 해당 데이터들을 다루는 메소드의 집합이었습니다. JavaScript는 프로토타입 기반 언어로, C++ 이나 Java에서 발견할 수 있는 class 구문이 없습니다(이런 이유로 class 구문에 익숙한 프로그래머들이 때때로 혼란을 경험합니다). 그 대신, JavaScrip는 function을 class로 사용합니다. 이름과 성을 필드로 가지고 있는 'person' 객체를 고려해보도록 합시다. 이름을 표시하는 두가지 방법이 있을 수 있습니다. 예를 들어, "이름 성" 또는 "성, 이름" 이런 식으로 말이죠. 이전에 다룬 함수와 객체를 사용해서 이를 표현하면 다음과 같습니다:

+ +
function makePerson(first, last) {
+  return {
+    first: first,
+    last: last
+  }
+}
+function personFullName(person) {
+  return person.first + ' ' + person.last;
+}
+function personFullNameReversed(person) {
+  return person.last + ', ' + person.first
+}
+
+var s = makePerson("Simon", "Willison");
+personFullName(s); // "Simon Willison"
+personFullNameReversed(s); // "Willison, Simon"
+
+ +

이렇게 하면 작동하긴 하지만, 보기 안좋습니다. 이런 방법이라면 전역 이름공간(global namespace)에 관련 함수가 너무 많아집니다. 정말 우리에게 필요한 것은 객체에 함수를 붙여놓는 것입니다. 함수는 객체이기 때문에 이건 별로 어렵지 않습니다.

+ +
function makePerson(first, last) {
+  return {
+    first: first,
+    last: last,
+    fullName: function() {
+      return this.first + ' ' + this.last;
+    },
+    fullNameReversed: function() {
+      return this.last + ', ' + this.first;
+    }
+  };
+}
+
+var s = makePerson('Simon', 'Willison');
+s.fullName(); // "Simon Willison"
+s.fullNameReversed(); // "Willison, Simon"
+
+ +

this 키워드에 주목해 주십시오. 함수 안쪽에서 사용되면서, this는 현재 객체를 참조합니다. 그것이 실제로 의미하는 바는 당신이 부른 바로 그 함수를 지정하는 것입니다. 객체에서 dot 표기법이나 bracket 표기법을 사용해서 부른 경우, 해당 객체는 this가 됩니다. 해당 호출에서 dot 표기법을 사용하지 않은 경우, this는 전역 객체를 참조하게 됩니다.

+ +

this가 실수의 잦은 원인이 된다는 것을 명심하십시오 . 예를 들면:

+ +
var s = makePerson('Simon', 'Willison');
+var fullName = s.fullName;
+fullName(); // undefined undefined
+
+ +

s.fullName()을 이용하지 않고 fullName()을 단독으로 호출하면, 'this'는 전역 객체로 묶이게(bind) 됩니다. first 또는 last 로 명명된 전역 변수가 없기 때문에, 각각에 대해 undefined 결과를 얻게됩니다.

+ +

makePerson 함수를 개선하는데 'this' 키워드의 이점을 취할 수 있습니다:

+ +
function Person(first, last) {
+  this.first = first;
+  this.last = last;
+  this.fullName = function() {
+    return this.first + ' ' + this.last;
+  };
+  this.fullNameReversed = function() {
+    return this.last + ', ' + this.first;
+  };
+}
+var s = new Person('Simon', 'Willison');
+
+ +

여기서 new라는 또다른 키워드를 도입했습니다. newthis와 깊게 연관되어 있습니다. 새로운 빈 객체를 만든 다음 지정된 함수를 불러 새로운 객체를 this 에 설정합니다. this로 지정된 함수는 값을 반환하지 않고 단지 this 객체를 수정한다는 것을 명심하세요. this 객체를 호출하는 곳으로 반환하는 것은  new 입니다. 'new' 에 의해 호출되도록 설계된 함수는 컨스트럭터 함수라고 불립니다. 일반적으로 이러한 함수의 첫자를 대문자로 써서 new로 불릴 컨스트럭터 함수임을 나타냅니다.

+ +

개선된 함수는 여전히 fullName() 을 단독으로 호출할 때의 함정이 존재합니다.

+ +

우리의 person 객체가 점점 개선되고 있지만, 아직 좀 보기 안좋은 면이 있습니다. 매번 person 계열의 객체를 만들 때마다 내부에서 2개의 새로운 함수 객체를 만들고 있습니다. 이 코드가 객체간에 공유된다면 더 낫지 않을까요?

+ +
function personFullName() {
+  return this.first + ' ' + this.last;
+}
+function personFullNameReversed() {
+  return this.last + ', ' + this.first;
+}
+function Person(first, last) {
+  this.first = first;
+  this.last = last;
+  this.fullName = personFullName;
+  this.fullNameReversed = personFullNameReversed;
+}
+
+ +

더 좋아 보이네요: 메소드 함수를 한번만 만들고, 컨스트럭터 내에 해당 메소드들을 참조하도록 할당합니다. 이보다 더 개선 할 수 있을까요? 네, 그렇게 할 수 있습니다:

+ +
function Person(first, last) {
+  this.first = first;
+  this.last = last;
+}
+Person.prototype.fullName = function() {
+  return this.first + ' ' + this.last;
+};
+Person.prototype.fullNameReversed = function() {
+  return this.last + ', ' + this.first;
+};
+
+ +

Person.prototype은 모든 Person 인스턴스들간에 공유되는 객체입니다. 이는 lookup(찾아보기) 체인의 한 부분을 이룹니다. (이건 "prototype chain"이라는 특수한 이름을 따로 가지고 있습니다) 다시 말해, Person 객체의 설정되지 않은 속성에 접근을 시도할 때마다, 그것의 대체용도로 JavaScript는 Person.prototype에 그 속성이 존재하는지 살펴봅니다.그 결과,  Person.prototype에 할당된 모든 것은 this 객체를 통해 해당 컨스트럭터에 속한 모든 인스턴스들간에 사용 가능하게 됩니다.

+ +

이것은 정말 강력한 도구입니다. JavaScript에서는 임의의 prototype을 프로그램 내에서 언제든 변형할 수 있습니다. 이미 존재하는 객체에 추가적인 메소드를 실시간으로 추가가할 수 있다는 이야기입니다:

+ +
var s = new Person("Simon", "Willison");
+s.firstNameCaps(); //TypeError on line 1: s.firstNameCaps is not a function
+
+Person.prototype.firstNameCaps = function() {
+    return this.first.toUpperCase()
+};
+s.firstNameCaps(); // "SIMON"
+
+ +

흥미롭게도, JavaScript의 빌트인 객체의 prototype에도 뭔가를 더 추가할 수 있습니다. String 객체에 문자열 순서를 거꾸로 배열하여 돌려주는 메소드를 추가해 봅시다.

+ +
var s = "Simon";
+s.reversed(); // TypeError on line 1: s.reversed is not a function
+
+String.prototype.reversed = function() {
+    var r = "";
+    for (var i = this.length - 1; i >= 0; i--) {
+        r += this[i];
+    }
+    return r;
+};
+
+s.reversed(); // nomiS
+
+ +

우리가 추가한 새로운 메소드는 심지어 문자열 상수에서도 동작합니다!

+ +
"This can now be reversed".reversed(); // desrever eb won nac sihT
+
+ +

기존에 언급한 바와같이, prototype은 체인의 한 부분을 이룹니다. 해당 체인의 루트는 Object.prototype 이며 toString() 메소드를 포함합니다. 이 메소드는 객체를 문자열로 나타내려할 때 호출됩니다. 이 메소드는 우리의 Person 객체의 디버깅에 유용합니다:

+ +
var s = new Person("Simon", "Willison");
+s.toString(); // [object Object]
+
+Person.prototype.toString = function() {
+  return '<Person: ' + this.fullName() + '>';
+}
+
+s.toString(); // "<Person: Simon Willison>"
+
+ +

avg.apply()의 첫번째 매개변수가 null 이었던걸 기억해봅시다. apply()에 적용되는 첫번째 인자는 당연히 `this'로 간주되는 객체입니다. 여기에 new 의 간단한 구현을 보시죠:

+ +
function trivialNew(constructor, ...args) {
+    var o = {}; // 빈 객체를 생성
+    constructor.apply(o, args);
+    return o;
+}
+
+ +

이것은 prototype 체인을 설정하지 않으므로 new의 완벽한 대체물이 될 수 없습니다.(이 부분은 설명하기 어렵습니다). 이 내용은 자주 사용하지는 않겠지만 알아두면 좋습니다. 이 부분에서 ...args (생략 부호를 포함해서)는 "rest arguments" 라고 불립니다. 이름이 암시하는 것처럼 매개변수의 나머지를 포함합니다.

+ +

그러므로 이렇게 호출하는 것은

+ +
var bill = trivialNew(Person, 'William', 'Orange');
+ +

아래와 거의 동일합니다.

+ +
var bill = new Person('William', 'Orange');
+ +

apply() 와 비슷하게 this를 다시 설정할 수 있게 하는, call이라는 이름의 자매 함수가 있는데, 인자로 단일 배열이 아니라 확장된 인자 목록을 입력받습니다.

+ +
function lastNameCaps() {
+  return this.last.toUpperCase();
+}
+var s = new Person('Simon', 'Willison');
+lastNameCaps.call(s);
+// 위의 구문은 다음과 같습니다:
+s.lastNameCaps = lastNameCaps;
+s.lastNameCaps();
+
+ +

내장 함수 (Inner functions)

+ +

다른 함수의 내부에서 JavaScript 함수를 선언할 수 있습니다. 우리는 makePerson() 함수 초기 버전에서 이것을 한번 본적이 있습니다. JavaScript에서 중첩 함수(nested functions)의 중요한 세부사항은 부모 함수 범위의 변수에 접근할 수 있다는 사실입니다:

+ +
function parentFunc() {
+    var a = 1;
+
+    function nestedFunc() {
+        var b = 4; // parentFunc은 사용할 수 없는 변수
+        return a + b;
+    }
+    return nestedFunc();  // 5
+}
+
+ +

좀 더 유지관리가 쉬운 코드를 작성하고자 할때 이 특성이 굉장히 유용합니다. 한개 혹은 두개의 정도의 함수에서만 호출되며 전체 코드중 다른 부분에서는 사용처가 없는 함수라면 그 함수내에 해당 함수를 중첩시키는 것이 좋습니다. 이렇게 전역 범위 함수의 갯수를 늘리지 않도록 하는 것은 언제나 좋은 습관입니다.

+ +

이것은 또한 전역 변수에 대한 유혹을 뿌리칠 수 있는 좋은 대안이 됩니다. 복잡한 코드를 쓸 때, 다양한 함수들간에 값을 공유할 수 있도록 전역 변수를 사용하고 싶어집니다 - 전역 변수는 코드 유지 보수를 어렵게 만듭니다. 중첩 함수는 그 부모 함수의 범위에서 변수를 공유할 수 있으므로, 이 방법을 사용하면 전역 변수 이름공간을 건드리지 않고도 적절한 경우에 함수들을 연동시킬수 있습니다. - '지역 전역'이라고 불러도 괜찮겠네요. 이 기술을 사용할 때는 주의를 요하겠지만, 반드시 알아둬야할 유용한 기술입니다.

+ +

클로져 (Closures)

+ +

클로져 (역자주: 글자 그대로 한국어로 해석하면 닫힌 주머니)는 JavaScript가 제공해야만 하는 가장 막강한 추상 개념으로 우리를 이끕니다 - 하지만 동시에 잠재적으로 가장 혼란스럽기도 합니다. 다음 함수는 무엇을 하는 걸까요?

+ +
function makeAdder(a) {
+  return function(b) {
+    return a + b;
+  };
+}
+var add5 = makeAdder(5);
+var add20 = makeAdder(20);
+add5(6); // ?
+add20(7); // ?
+
+ +

makeAdder 함수의 이름은 다음과 같은 과정을 거쳐 반드시 없어집니다: 해당 함수가 한 매개변수를 받아 호출됐을 때, 생성될 때 주어진 매개변수를 더하는 새 'adder' 함수를 생성합니다.

+ +

여기서 일어나는 일은 다른 함수의 내에 정의된 어떤 함수가 외부 함수의 변수에 액세스한다는 점에서 앞에 언급한 내장 함수에서 일어나는 일과 매우 비슷합니다. 한가지 다른 점은 외부 함수가 리턴 된다는 점인데, 상식적으로 그것에 들어 있는 변수는 사라진다고 볼 수 있습니다. 하지만 그들은 여전히존재합니다 - 그렇지 않으면 adder 함수는 동작하지 않겠지요. 게다가, makeAdder 지역 변수의 서로 다른 두 "복사본"이 존재합니다 - 하나의 a는 5이고, 다른 하나의 a는 20이죠. 따라서 해당 함수를 부른 결과는 다음과 같습니다:

+ +
x(6) // 11을 돌려줌
+y(7) // 27을 돌려줌
+
+ +

이건 실제로 일어나는 일입니다. JavaScript 함수가 실행될 때는 언제나, '범위' 객체가 생성되어 해당 함수내에서 생성된 지역 변수를 여기에 저장하고 있습니다. 함수 매개변수로서 넘겨진 어떤 변수라도 여기에 초기값으로 저장하고 있습니다. 이것은 모든 전역 변수와 함수가 들어있는 전역 객체와 비슷하지만, 두가지 중요한 차이점이 있습니다. 첫번째로, 함수가 실행될 때마다 새로운 범위 객체가 생성된다는 점과, 두번째로, (브라우저에서 window로 접근가능한) 전역 객체와 달리 범위 객체는 JavaScript 코드에서 직접적으로 액세스할 수 없다는 점입니다. 예를 들자면 현재 범위 객체의 속성에 반복 접근할 수 있는 수단이 없습니다.

+ +

따라서 makeAdder 가 호출되면, 범위 객체는 makeAdder 함수에 매개변수로 넘겨진 하나의 속성 a를 가진 상태로 생성됩니다. 일반적으로 JavaScript의 가비지 컬렉터가 이때 makeAdder에 의해 생성된 범위 객체를 청소해야겠지만, 리턴된 함수가 여전히 범위 객체를 참조하고 있습니다. 결과적으로 범위 객체는 makeAdder에 의해 리턴된 함수 객체가 더는 참조되지 않을 때까지 가비지 컬렉터에 의해 정리되지 않게됩니다.

+ +

범위 객체는 JavaScript 객체 체계에서 사용되는 prototype 사슬과 비슷한 범위 사슬이라고 불리는 사슬을 형성합니다.

+ +

클로져는 함수와 함수에 의해 생성되는 범위 객체를 함께 지칭하는 용어입니다.

+ +

또한 클로져는 상태를 저장할 수 있도록 허용합니다 - 그렇기 때문에, 객체의 내부에서 자주 사용될 수 있는 것입니다.

+ +

메모리 누출

+ +

클로져의 부작용은 Internet Explorer에서 심각하지는 않지만 쉽게 메모리 누출이 된다는 것입니다. JavaScript는 가비지 컬렉트를 하는 언어 입니다. 객체가 생성됨에 따라서 메모리가 할당되고, 사용하고난 메모리는 더 참조하는 다른 객체가 없을 때 되돌아가는 방식으로 동작하는 언어란 말이죠. 호스트 환경에서 제공되는 객체들은 해당 환경에 의해 다뤄집니다.

+ +

브라우저 호스트는 HTML 페이지에 DOM 객체로서 표현되어있는 많은 수의 객체를 다뤄야 합니다. 이 객체들을 어떻게 할당하고 다시 거둬들일지는 브라우저 책임이죠.

+ +

Internet Explorer는 이를 위해 자신만의 고유한, JavaScript의 그것과는 다른 가비지 컬렉션 방식을 사용합니다. 두 언어간에 상호작용이 일어날 수 있고 이 과정에서 메모리 누출이 발생할 수 있습니다.

+ +

IE에서 메모리 누출은 JavaScript 객체와 고유 객체간에 참조하는 중 자기 자신을 참조 (circular reference, 순환 참조)하게 되는 일이 발생할 경우라면 언제든지 발생하게 됩니다. 다음을 고려해 보도록 합시다:

+ +
function leakMemory() {
+    var el = document.getElementById('el');
+    var o = { 'el': el };
+    el.o = o;
+}
+
+ +

위의 코드는 순환 참조로서 메모리 누출을 일으킵니다. IE는 완전히 다시 시작되기 전까지는 elo에 의해 사용되는 메모리를 반환하지 못합니다.

+ +

위의 경우는 알아채지 못하고 지나갈 확률이 높습니다. 메모리 누출은 사실 오랫동안 실행되거나 큰 데이터 구조나 반복, 순환에 의해 누출된는 메모리 양이 많은 경우에서 실질적으로 고려할만한 가치가 생깁니다.

+ +

누출이 이처럼 명확한 경우는 드뭅니다. 누출을 일으키는 데이터 구조는 수차례에 걸친 참조 구조를 가지고 있어서 순환 참조를 하고있는지 명확하지 않은 경우가 더 많습니다.

+ +

클로져는 그렇게 되도록 하지않아도 간단하게 메모리 누출을 일으킬 수 있습니다. 다음을 고려해 봅시다:

+ +
function addHandler() {
+    var el = document.getElementById('el');
+    el.onclick = function() {
+        this.style.backgroundColor = 'red';
+    }
+}
+
+ +

위의 코드는 클릭했을때 배경색이 빨강으로 바뀌는 엘레멘트를 설정합니다. 그리고 메모리 누출도 일으킵니다. 어째서냐고요? el을 참조하면 의도와는 달리 익명 내부 함수 때문에 생성된 클로져 내에 붙잡혀 있게 되기 때문입니다. 이는 JavaScript 객체 (내부 함수)와 원시 객체 (el)간에 순환 참조를 만듭니다.

+ +

이 문제를 피할 수 있는 많은 방법이 있습니다. 가장 간단한 건 이겁니다:

+ +
function addHandler() {
+    var el = document.getElementById('el');
+    el.onclick = function() {
+        this.style.backgroundColor = 'red';
+    }
+    el = null;
+}
+
+ +

이렇게 하면 순환 참조 고리를 끊을 수 있습니다.

+ +

놀랍게도, 클로져에 의해 발생된 순환 참조를 고리를 끊기 위한 한 요령은 또다른 클로져를 추가하는 것입니다:

+ +
function addHandler() {
+    var clickHandler = function() {
+        this.style.backgroundColor = 'red';
+    }
+    (function() {
+        var el = document.getElementById('el');
+        el.onclick = clickHandler;
+    })();
+}
+
+ +

내부 함수는 실행되고 바로 사라지므로서, clickHandler와 함께 생성된 클로져로부터 그 내용을 숨깁니다.

+ +

클로져를 피할 수 있는 또다른 좋은 요령은 window.onunload 이벤트가 발생하는 동안 순환 참조를 끊는 것입니다. 많은 이벤트 라이브러리가 이렇게 동작합니다. 주의할 것은 그렇게 하도록하면 Firefox 1.5의 bfcache를 비활성화 하게 되므로, 별 다른 이유가 없다면 Firefox에서 unload listener를 등록해서는 안 된다는 것입니다.

+ +
+

원본 문서 정보

+ +
    +
  • 저자: Simon Willison
  • +
  • 최근 갱신 날짜: March 7, 2006
  • +
  • 저작권: © 2006 Simon Willison, contributed under the Creative Commons: Attribute-Sharealike 2.0 license.
  • +
  • 추가 정보: For more information about this tutorial (and for links to the original talk's slides), see Simon's Etech weblog post.
  • +
+
+ +
+ +

{{ languages( { "en": "en/A_re-introduction_to_JavaScript", "fr": "fr/Une_reintroduction_a_JavaScript", "it": "it/Una_re-introduzione_a_Javascript", "ja": "ja/A_re-introduction_to_JavaScript", "pl": "pl/JavaScript/Na_pocz?tek", "zh-cn": "cn/A_re-introduction_to_JavaScript" } ) }}

diff --git a/files/ko/web/javascript/about/index.html b/files/ko/web/javascript/about/index.html deleted file mode 100644 index c7ec0f9f28..0000000000 --- a/files/ko/web/javascript/about/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: JavaScript에 대하여 -slug: Web/JavaScript/About -tags: - - 비기너 - - 소개 - - 자바스크립트 -translation_of: Web/JavaScript/About_JavaScript ---- -

{{JsSidebar}}

- -

JavaScript란 무엇인가?

- -

JavaScript® (줄여서 JS)는 일급 함수를 사용하는 가벼운 객체 지향 인터프리터 언어이며 웹페이지의 스크립트 언어로 잘 알려져 있지만, 브라우저가 아닌 환경에서도 많이 사용된다. 프로토타입 기반, 다중 패러다임 스크립트 언어이며, 동적이고 명령어, 객체 지향, 함수 프로그래밍 스타일을 지원한다.

- -

자바스크립트는 클라이언트 측 웹(브라우저)에서 실행 되고, 웹 페이지가 이벤트 발생시 어떻게 작동하는 지 디자인 / 프로그래밍할 수 있다. 자바스크립트는 쉽게 배울 수 있고 강력한 스크립트 언어로 웹 페이지 동작을 제어하는 데 널리 사용된다.

- -

대중적인 오해와 달리, Javascript는 인터프리트 형태 자바가 아니다. 간단히 말하면, Javascript는 프로토 타입 기반 객체 생성을 지원하는 동적 스크립트 언어이다.  기본적인 문법은  언어 학습에 필요한 새로운 개념을 줄이기 위해 Java와 C++의 if문, for와 while문, switch문과 try...catch 구문을 사용하는 언어구조를 사용하며, 그와 같은 (거의 가까운) 동작을 한다.

- -

Javascript는 절차지향 (procedural) 언어와  객체지향 (object oriented) 언어 두가지 형태로 만들수 있다. 자바스크립트에서 객체는 실시간으로 빈 객체를 오버라이딩하여 메소드와 프로퍼티를 연결하는 (프로그래밍)방식으로 생성된다. C++ 및 Java와 같은 컴파일 언어에서 공통적인 구문 클래스 정의와 반대되는 개념이다. 한번 객체가 생성하면, 비슷한 객체를 생성할 때 프로토타입으로 사용할 수 있다.

- -

JavaScript의 동적인 성질은, 실행시의 오브젝트 구축, 가변 인수 리스트, 함수 변수, (eval 에 의한)동적 스크립트 작성, (for ... in 에 의한) 오브젝트의 내부참조, 또는 소스코드 복원 (JavaScript 의 프로그램은 함수본체를 소스텍스트에 역컴파일할 수 있다.) 을 포함하고 있다.

- -

자바스크립트 프로그래밍에 대한 더 자세한 설명은 아래의 자바스크립트 리소스 링크를 참조하면 된다.

- -

어떠한 JavaScript 구현이 유용한가?

- -

Mozilla 프로젝트는 두 가지 자바스크립트 구현을 제공한다. 최초의 Javascript는 Netscape의 Brendan Eich에 의해 만들었다. 이후 ECMA-262 에디션 5 와 최신 버전을 준수하도록 업데이트되었다. SpiderMonkey 라는 이름의 엔진은 C/C++로 구현되었다. Rhino 엔진은 주로 Norris Boys(또한 Netscape)가 만들었고 Java로 작성된 Javascript 구현체이다. SpiderMonkey와 마찬가지로 Rhino도 ECMA-262 에디션 5를 준거한다.

- -

TraceMonkey (Firefox 3.5), JägerMonkey (Firefox 4) 그리고 IonMonkey와 같은 몇가지 주요한 실시간 최적화는 차츰 SpiderMonkey 자바스크립트 엔진에 추가되었다. 자바스크립트 실행 성능 향상을 위한 작업은 지금도 진행 중이다.

- -

위의 구현 이외에도 다음과 같은 다른 인기있는 자바스크립트 엔진이 있다.

- -
    -
  • 구글의 V8 은 크롬 브라우저와 최신 버전의 오페라 브라우저에 사용된다. 또 Node.js의 엔진으로 사용된다.
  • -
  • JavaScriptCore (SquirrelFish/Nitro) 는 Apple 사파리와 같은 일부 WebKit 브라우저에서 사용된다.
  • -
  • Carakan 는 오페라의 예전 버전안에 있다.
  • -
  • Chakra 엔진은 Internet Explorer에서 사용된다. (상표권 문제를 피하기 위해 공식적으로 "JScript"라고 불린다.)
  • -
- -

mozilla.org의 각 JavaScript 엔진은, 애플리케이션이 JavaScript를 지원하기 위해 부를 수 있는 공개 API를 공개하고 있다. JavaScript 를 지원하는 가장 일반적인 호스트환경은 웹브라우저이다. 웹 브라우저는 일반적으로 공개 API를 사용하여 DOM을 Javascript로 반영하는 호스트 객체를 만든다.

- -

JavaScript 의 또 다른 일반적인 애플리케이션은 (웹) 서버사이드 스크립팅 언어이다. 자바스크립트 웹 서버는 HTTP 요청 및 응답 객체를 나타내는 호스트 객체를 공개하며 자바 스크립트 프로그램에 의해 조작되어 웹 페이지를 동적으로 생성 할 수 있다. Node.js는 이에 대한 대중적인 예이다.

- -

JavaScript 자원

- -
-
SpiderMonkey
-
애플리케이션에 임베드하는 방법을 포함하는, C/C++ 엔진(SpiderMonkey)으로 구현된 Mozilla의 JavaScript 구현체에 관한 정보.
-
Rhino
-
Java(Rhino)로 작성된 자바스크립트 구현체에 관련 정보.
-
Language resources
-
자바스크립트 표준을 출판하기 위한 포인터들.
-
A re-introduction to JavaScript
-
자바스크립트 가이드자바스크립트 레퍼런스.
-
- -

JavaScript® 는 미국 및 여러 나라의 Oracle 트레이드마크 또는 등록된 트레이드마크입니다.

diff --git a/files/ko/web/javascript/about_javascript/index.html b/files/ko/web/javascript/about_javascript/index.html new file mode 100644 index 0000000000..c7ec0f9f28 --- /dev/null +++ b/files/ko/web/javascript/about_javascript/index.html @@ -0,0 +1,58 @@ +--- +title: JavaScript에 대하여 +slug: Web/JavaScript/About +tags: + - 비기너 + - 소개 + - 자바스크립트 +translation_of: Web/JavaScript/About_JavaScript +--- +

{{JsSidebar}}

+ +

JavaScript란 무엇인가?

+ +

JavaScript® (줄여서 JS)는 일급 함수를 사용하는 가벼운 객체 지향 인터프리터 언어이며 웹페이지의 스크립트 언어로 잘 알려져 있지만, 브라우저가 아닌 환경에서도 많이 사용된다. 프로토타입 기반, 다중 패러다임 스크립트 언어이며, 동적이고 명령어, 객체 지향, 함수 프로그래밍 스타일을 지원한다.

+ +

자바스크립트는 클라이언트 측 웹(브라우저)에서 실행 되고, 웹 페이지가 이벤트 발생시 어떻게 작동하는 지 디자인 / 프로그래밍할 수 있다. 자바스크립트는 쉽게 배울 수 있고 강력한 스크립트 언어로 웹 페이지 동작을 제어하는 데 널리 사용된다.

+ +

대중적인 오해와 달리, Javascript는 인터프리트 형태 자바가 아니다. 간단히 말하면, Javascript는 프로토 타입 기반 객체 생성을 지원하는 동적 스크립트 언어이다.  기본적인 문법은  언어 학습에 필요한 새로운 개념을 줄이기 위해 Java와 C++의 if문, for와 while문, switch문과 try...catch 구문을 사용하는 언어구조를 사용하며, 그와 같은 (거의 가까운) 동작을 한다.

+ +

Javascript는 절차지향 (procedural) 언어와  객체지향 (object oriented) 언어 두가지 형태로 만들수 있다. 자바스크립트에서 객체는 실시간으로 빈 객체를 오버라이딩하여 메소드와 프로퍼티를 연결하는 (프로그래밍)방식으로 생성된다. C++ 및 Java와 같은 컴파일 언어에서 공통적인 구문 클래스 정의와 반대되는 개념이다. 한번 객체가 생성하면, 비슷한 객체를 생성할 때 프로토타입으로 사용할 수 있다.

+ +

JavaScript의 동적인 성질은, 실행시의 오브젝트 구축, 가변 인수 리스트, 함수 변수, (eval 에 의한)동적 스크립트 작성, (for ... in 에 의한) 오브젝트의 내부참조, 또는 소스코드 복원 (JavaScript 의 프로그램은 함수본체를 소스텍스트에 역컴파일할 수 있다.) 을 포함하고 있다.

+ +

자바스크립트 프로그래밍에 대한 더 자세한 설명은 아래의 자바스크립트 리소스 링크를 참조하면 된다.

+ +

어떠한 JavaScript 구현이 유용한가?

+ +

Mozilla 프로젝트는 두 가지 자바스크립트 구현을 제공한다. 최초의 Javascript는 Netscape의 Brendan Eich에 의해 만들었다. 이후 ECMA-262 에디션 5 와 최신 버전을 준수하도록 업데이트되었다. SpiderMonkey 라는 이름의 엔진은 C/C++로 구현되었다. Rhino 엔진은 주로 Norris Boys(또한 Netscape)가 만들었고 Java로 작성된 Javascript 구현체이다. SpiderMonkey와 마찬가지로 Rhino도 ECMA-262 에디션 5를 준거한다.

+ +

TraceMonkey (Firefox 3.5), JägerMonkey (Firefox 4) 그리고 IonMonkey와 같은 몇가지 주요한 실시간 최적화는 차츰 SpiderMonkey 자바스크립트 엔진에 추가되었다. 자바스크립트 실행 성능 향상을 위한 작업은 지금도 진행 중이다.

+ +

위의 구현 이외에도 다음과 같은 다른 인기있는 자바스크립트 엔진이 있다.

+ +
    +
  • 구글의 V8 은 크롬 브라우저와 최신 버전의 오페라 브라우저에 사용된다. 또 Node.js의 엔진으로 사용된다.
  • +
  • JavaScriptCore (SquirrelFish/Nitro) 는 Apple 사파리와 같은 일부 WebKit 브라우저에서 사용된다.
  • +
  • Carakan 는 오페라의 예전 버전안에 있다.
  • +
  • Chakra 엔진은 Internet Explorer에서 사용된다. (상표권 문제를 피하기 위해 공식적으로 "JScript"라고 불린다.)
  • +
+ +

mozilla.org의 각 JavaScript 엔진은, 애플리케이션이 JavaScript를 지원하기 위해 부를 수 있는 공개 API를 공개하고 있다. JavaScript 를 지원하는 가장 일반적인 호스트환경은 웹브라우저이다. 웹 브라우저는 일반적으로 공개 API를 사용하여 DOM을 Javascript로 반영하는 호스트 객체를 만든다.

+ +

JavaScript 의 또 다른 일반적인 애플리케이션은 (웹) 서버사이드 스크립팅 언어이다. 자바스크립트 웹 서버는 HTTP 요청 및 응답 객체를 나타내는 호스트 객체를 공개하며 자바 스크립트 프로그램에 의해 조작되어 웹 페이지를 동적으로 생성 할 수 있다. Node.js는 이에 대한 대중적인 예이다.

+ +

JavaScript 자원

+ +
+
SpiderMonkey
+
애플리케이션에 임베드하는 방법을 포함하는, C/C++ 엔진(SpiderMonkey)으로 구현된 Mozilla의 JavaScript 구현체에 관한 정보.
+
Rhino
+
Java(Rhino)로 작성된 자바스크립트 구현체에 관련 정보.
+
Language resources
+
자바스크립트 표준을 출판하기 위한 포인터들.
+
A re-introduction to JavaScript
+
자바스크립트 가이드자바스크립트 레퍼런스.
+
+ +

JavaScript® 는 미국 및 여러 나라의 Oracle 트레이드마크 또는 등록된 트레이드마크입니다.

diff --git a/files/ko/web/javascript/closures/index.html b/files/ko/web/javascript/closures/index.html new file mode 100644 index 0000000000..b56d843b2b --- /dev/null +++ b/files/ko/web/javascript/closures/index.html @@ -0,0 +1,454 @@ +--- +title: 클로저 +slug: Web/JavaScript/Guide/Closures +tags: + - Closure + - ES5 + - Intermediate + - JavaScript + - Reference +translation_of: Web/JavaScript/Closures +--- +
{{jsSidebar("Intermediate")}}
+ +

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

+ +

어휘적 범위 지정(Lexical scoping)

+ +

다음을 보자:

+ +
function init() {
+  var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
+  function displayName() { // displayName() 은 내부 함수이며, 클로저다.
+    alert(name); // 부모 함수에서 선언된 변수를 사용한다.
+  }
+  displayName();
+}
+init();
+ +

init()은 지역 변수 name과 함수 displayName()을 생성한다. displayName()init() 안에 정의된 내부 함수이며 init() 함수 본문에서만 사용할 수 있다. 여기서 주의할 점은 displayName() 내부엔 자신만의 지역 변수가 없다는 점이다. 그런데 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에 displayName() 역시 부모 함수 init()에서 선언된 변수 name에 접근할 수 있다. 만약 displayName()가 자신만의 name변수를 가지고 있었다면, name대신 this.name을 사용했을 것이다.

+ +

{{JSFiddleEmbed("https://jsfiddle.net/78dg25ax/", "js,result", 250)}}

+ +

위 코드를 실행하면 displayName() 함수 내의 alert()문이 부모 함수에서 정의한 변수 name의 값을 성공적으로 출력한다. 이 예시를 통해 함수가 중첩된 상황에서 파서가 어떻게 변수를 처리하는지 알 수 있다. 이는 어휘적 범위 지정(lexical scoping)의 한 예이다. 여기서 "lexical"이란, 어휘적 범위 지정(lexical scoping) 과정에서 변수가 어디에서 사용 가능한지 알기 위해 그 변수가 소스코드 내 어디에서 선언되었는지 고려한다는 것을 의미한다. 단어 "lexical"은 이런 사실을 나타낸다. 중첩된 함수는 외부 범위(scope)에서 선언한 변수에도 접근할 수 있다.

+ +

클로저(Closure)

+ +

이제 다음 예제를 보자:

+ +
function makeFunc() {
+  var name = "Mozilla";
+  function displayName() {
+    alert(name);
+  }
+  return displayName;
+}
+
+var myFunc = makeFunc();
+//myFunc변수에 displayName을 리턴함
+//유효범위의 어휘적 환경을 유지
+myFunc();
+//리턴된 displayName 함수를 실행(name 변수에 접근)
+ +

이 코드는 바로 전의 예제와 완전히 동일한 결과가 실행된다. 하지만 흥미로운 차이는 displayName()함수가 실행되기 전에 외부함수인 makeFunc()로부터 리턴되어 myFunc 변수에 저장된다는 것이다.

+ +

한 눈에 봐서는 이 코드가 여전히 작동하는 것이 직관적으로 보이지 않을 수 있다. 몇몇 프로그래밍 언어에서, 함수 안의 지역 변수들은 그 함수가 처리되는 동안에만 존재한다. makeFunc() 실행이 끝나면(displayName함수가 리턴되고 나면) name 변수에 더 이상 접근할 수 없게 될 것으로 예상하는 것이 일반적이다.

+ +

하지만 위의 예시와 자바스크립트의 경우는 다르다. 그 이유는 자바스크립트는 함수를 리턴하고, 리턴하는 함수가 클로저를 형성하기 때문이다. 클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다. 첫 번째 예시의 경우, myFuncmakeFunc이 실행될 때 생성된 displayName 함수의 인스턴스에 대한 참조다. displayName의 인스턴스는 변수 name 이 있는 어휘적 환경에 대한 참조를 유지한다. 이런 이유로 myFunc가 호출될 때 변수 name은 사용할 수 있는 상태로 남게 되고 "Mozilla" 가 alert 에 전달된다.

+ +

다음은 조금 더 흥미로운 예제인 makeAdder 함수이다:

+ +
function makeAdder(x) {
+  var y = 1;
+  return function(z) {
+    y = 100;
+    return x + y + z;
+  };
+}
+
+var add5 = makeAdder(5);
+var add10 = makeAdder(10);
+//클로저에 x와 y의 환경이 저장됨
+
+console.log(add5(2));  // 107 (x:5 + y:100 + z:2)
+console.log(add10(2)); // 112 (x:10 + y:100 + z:2)
+//함수 실행 시 클로저에 저장된 x, y값에 접근하여 값을 계산
+
+
+ +

이 예제에서 단일 인자 x를 받아서 새 함수를 반환하는 함수 makeAdder(x)를 정의했다. 반환되는 함수는 단일 인자 z를 받아서 x와 y와 z의 합을 반환한다.

+ +

본질적으로 makeAdder는 함수를 만들어내는 공장이다. 이는 makeAdder함수가 특정한 값을 인자로 가질 수 있는 함수들을 리턴한다는 것을 의미한다. 위의 예제에서 add5, add10 두 개의 새로운 함수들을 만들기 위해 makeAdder함수 공장을 사용했다. 하나는 매개변수 x에 5를 더하고 다른 하나는 매개변수 x에 10을 더한다.

+ +

add5add10은 둘 다 클로저이다. 이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장한다. 함수 실행 시 add5의 맥락적 환경에서 클로저 내부의 x는 5 이지만 add10의 맥락적 환경에서 x는 10이다. 또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다. (물론 x값도 동일하게 변경 가능하다.) 이는 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며 클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미한다.

+ +

실용적인 클로저

+ +

클로저는 어떤 데이터(어휘적 환경)와 그 데이터를 조작하는 함수를 연관시켜주기 때문에 유용하다. 이것은 객체가 어떤 데이터와(그 객체의 속성) 하나 혹은 그 이상의 메소드들을 연관시킨다는 점에서 객체지향 프로그래밍과 분명히 같은 맥락에 있다.

+ +

결론적으로 오직 하나의 메소드를 가지고 있는 객체를 일반적으로 사용하는 모든 곳에 클로저를 사용할 수 있다.

+ +

이렇게 할 수 있는 상황은 특히 웹에서 일반적이다. 프론트 엔드 자바스크립트에서 우리가 쓰는 많은 코드가 이벤트 기반이다. 우리는 몇 가지 동작을 정의한 다음 사용자에 의한 이벤트에(클릭 혹은 키 누르기 같은) 연결한다. 우리의 코드는 일반적으로 콜백으로 첨부된다: 이벤트에 응답하여 실행되는 단일 함수다.

+ +

예를 들면 페이지의 글자 크기를 조정하는 몇 개의 버튼을 추가한다고 가정하자. 이 작업을 수행하는 한 가지 방법은 body 요소의 font-size를 픽셀 단위로 지정하고 상대적인 em 단위를 사용하여 페이지의 다른 요소들의 (예: 헤더) 크기를 설정하는 것이다.

+ +
body {
+  font-family: Helvetica, Arial, sans-serif;
+  font-size: 12px;
+}
+
+h1 {
+  font-size: 1.5em;
+}
+
+h2 {
+  font-size: 1.2em;
+}
+
+ +

우리의 대화식 글자 크기 버튼들은 body 요소의 font-size 속성을 변경할 수 있고 이런 조정은 상대적 단위들 덕분에 페이지의 다른 요소에 의해 선택된다.

+ +

여기 자바스크립트 코드가 있다.

+ +
function makeSizer(size) {
+  return function() {
+    document.body.style.fontSize = size + 'px';
+  };
+}
+
+var size12 = makeSizer(12);
+var size14 = makeSizer(14);
+var size16 = makeSizer(16);
+
+ +

size12, size14, size16은 body 요소의 글자 크기를 각각 12, 14, 16 픽셀로 바꾸는 함수이다. 이 함수들을 아래처럼 버튼들에(이 경우에는 링크) 연결할 수 있다.

+ +
document.getElementById('size-12').onclick = size12;
+document.getElementById('size-14').onclick = size14;
+document.getElementById('size-16').onclick = size16;
+
+ +
<a href="#" id="size-12">12</a>
+<a href="#" id="size-14">14</a>
+<a href="#" id="size-16">16</a>
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/vnkuZ/","","200")}}

+ +

클로저를 이용해서 프라이빗 메소드 (private method) 흉내내기

+ +

자바와 같은 몇몇 언어들은 메소드를 프라이빗으로 선언할 수 있는 기능을 제공한다. 이는 같은 클래스 내부의 다른 메소드에서만 그 메소드들을 호출할 수 있다는 의미이다.

+ +

자바스크립트는 태생적으로는 이런 방법을 제공하지 않지만 클로저를 이용하여 프라이빗 메소드를 흉내내는 것이 가능하다. 프라이빗 메소드는 코드에 제한적인 접근만을 허용한다는 점 뿐만 아니라 전역 네임 스페이스를 관리하는 강력한 방법을 제공하여 불필요한 메소드가 공용 인터페이스를 혼란스럽게 만들지 않도록 한다.

+ +

아래 코드는 프라이빗 함수와 변수에 접근하는 퍼블릭 함수를 정의하기 위해 클로저를 사용하는 방법을 보여준다. 이렇게 클로저를 사용하는 것을 모듈 패턴이라 한다.

+ +
var counter = (function() {
+  var privateCounter = 0;
+  function changeBy(val) {
+    privateCounter += val;
+  }
+  return {
+    increment: function() {
+      changeBy(1);
+    },
+    decrement: function() {
+      changeBy(-1);
+    },
+    value: function() {
+      return privateCounter;
+    }
+  };
+})();
+
+console.log(counter.value()); // logs 0
+counter.increment();
+counter.increment();
+console.log(counter.value()); // logs 2
+counter.decrement();
+console.log(counter.value()); // logs 1
+
+ +

이전 예제에서 각 클로저들이 고유한 문법적 환경을 가졌지만 여기서 우리는 counter.increment, counter.decrement, counter.value 세 함수에 의해 공유되는 하나의 어휘적 환경을 만든다.

+ +

공유되는 어휘적 환경은 실행되는 익명 함수 안에서 만들어진다. 이 익명 함수는 정의되는 즉시 실행된다. 이 어휘적 환경은 두 개의 프라이빗 아이템을 포함한다. 하나는 privateCounter라는 변수이고 나머지 하나는 changeBy라는 함수이다. 둘 다 익명 함수 외부에서 접근될 수 없다. 대신에 익명 래퍼에서 반환된 세 개의 퍼블릭 함수를 통해서만 접근되어야만 한다.

+ +

위의 세 가지 퍼블릭 함수는 같은 환경을 공유하는 클로저다. 자바스크립트의 어휘적 유효 범위 덕분에 세 함수 각각 privateCounter 변수와 changeBy 함수에 접근할 수 있다.

+ +

카운터를 생성하는 익명 함수를 정의하고 그 함수를 즉시 호출하고 결과를 counter 변수에 할당하는 것을 알아차렸을 것이다. 이 함수를 별도의 변수 makeCounter 저장하고 이 변수를 이용해 여러 개의 카운터를 만들 수 있다.

+ +
var makeCounter = function() {
+  var privateCounter = 0;
+  function changeBy(val) {
+    privateCounter += val;
+  }
+  return {
+    increment: function() {
+      changeBy(1);
+    },
+    decrement: function() {
+      changeBy(-1);
+    },
+    value: function() {
+      return privateCounter;
+    }
+  }
+};
+
+var counter1 = makeCounter();
+var counter2 = makeCounter();
+alert(counter1.value()); /* 0 */
+counter1.increment();
+counter1.increment();
+alert(counter1.value()); /* 2 */
+counter1.decrement();
+alert(counter1.value()); /* 1 */
+alert(counter2.value()); /* 0 */
+
+ +

두 개의 카운터가 어떻게 다른 카운터와 독립성을 유지하는지 주목해보자. 각 클로저는 그들 고유의 클로저를 통한 privateCounter 변수의 다른 버전을 참조한다. 각 카운터가 호출될 때마다; 하나의 클로저에서 변수 값을 변경해도 다른 클로저의 값에는 영향을 주지 않는다.

+ +

이런 방식으로 클로저를 사용하여 객체지향 프로그래밍의 정보 은닉과 캡슐화 같은 이점들을 얻을 수 있다.

+ +

클로저 스코프 체인

+ +

모든 클로저에는 세가지 스코프(범위)가 있다:-

+ +
    +
  • 지역 범위 (Local Scope, Own scope)
  • +
  • 외부 함수 범위 (Outer Functions Scope)
  • +
  • 전역 범위 (Global Scope)
  • +
+ +

따라서, 우리는 클로저에 대해 세가지 범위 모두 접근할 수 있지만, 중첩된 내부 함수가 있는 경우 종종 실수를 저지른다. 아래 예제를 확인해보자:

+ +
// 전역 범위 (global scope)
+var e = 10;
+function sum(a){
+  return function(b){
+    return function(c){
+      // 외부 함수 범위 (outer functions scope)
+      return function(d){
+        // 지역 범위 (local scope)
+        return a + b + c + d + e;
+      }
+    }
+  }
+}
+
+console.log(sum(1)(2)(3)(4)); // log 20
+
+// 익명 함수 없이 작성할 수도 있다.
+
+// 전역 범위 (global scope)
+var e = 10;
+function sum(a){
+  return function sum2(b){
+    return function sum3(c){
+      // 외부 함수 범위 (outer functions scope)
+      return function sum4(d){
+        // 지역 범위 (local scope)
+        return a + b + c + d + e;
+      }
+    }
+  }
+}
+
+var s = sum(1);
+var s1 = s(2);
+var s2 = s1(3);
+var s3 = s2(4);
+console.log(s3) //log 20
+ +

위의 예제를 보면 일련의 중첩된 함수들을 확인할 수 있다. 이 함수들은 전부 외부 함수의 스코프에 접근할 수 있다. 그런데 문제는 즉각적인 외부 함수의 스코프만을 추측한다는 것이다. 이 문맥에서는 모든 클로저가 선언된 외부 함수의 스코프에 접근한다라고 말할 수 있다.

+ +

루프에서 클로저 생성하기: 일반적인 실수

+ +

ECMAScript 2015의 let 키워드 소개 전에는 클로저와 관련된 일반적인 문제는 루프 안에서 클로저가 생성되었을 때 발생한다.다음 예제를 보자.

+ +
<p id="help">Helpful notes will appear here</p>
+<p>E-mail: <input type="text" id="email" name="email"></p>
+<p>Name: <input type="text" id="name" name="name"></p>
+<p>Age: <input type="text" id="age" name="age"></p>
+
+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    var item = helpText[i];
+    document.getElementById(item.id).onfocus = function() {
+      showHelp(item.help);
+    }
+  }
+}
+
+setupHelp();
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/", "", 200)}}

+ +

helpText 배열은 세 개의 도움말 힌트를 정의한다. 각 도움말은 문서의 입력 필드의 ID와 연관된다. 루프를 돌면서 각 입력 필드 ID에 해당하는 엘리먼트의 onfocus 이벤트에 관련된 도움말을 보여주는 메소드에 연결한다.

+ +

이 코드를 사용하면 제대로 동작하지 않는 것을 알게 된다. 어떤 필드에 포커스를 주더라도 나이에 관한 도움말이 표시된다.

+ +

onfocus 이벤트에 연결된 함수가 클로저이기 때문이다. 이 클로저는 함수 정의와 setupHelp 함수 범위에서 캡처된 환경으로 구성된다. 루프에서 세 개의 클로저가 만들어졌지만 각 클로저는 값이 변하는 변수가 (item.help) 있는 같은 단일 환경을 공유한다. onfocus 콜백이 실행될 때 콜백의 환경에서 item 변수는 (세개의 클로저가 공유한다) helpText 리스트의 마지막 요소를 가리키고 있을 것이다.

+ +

이 경우 한 가지 해결책은 더 많은 클로저를 사용하는 것이다: 특히 앞에서 설명한 함수 팩토리를 사용하는 것이다.

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function makeHelpCallback(help) {
+  return function() {
+    showHelp(help);
+  };
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    var item = helpText[i];
+    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
+  }
+}
+
+setupHelp();
+
+ +

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/1/", "", 300)}}

+ +

이것은 예상대로 동작한다. 모두 단일 환경을 공유하는 콜백대신, makeHelpCallback 함수는 각각의 콜백에 새로운 어휘적 환경을 생성한다. 여기서 help는 helpText 배열의 해당 문자열을 나타낸다.

+ +

익명 클로저를 사용하여 위 코드를 작성하는 또 다른 방법은 다음과 같다.

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    (function() {
+       var item = helpText[i];
+       document.getElementById(item.id).onfocus = function() {
+         showHelp(item.help);
+       }
+    })(); // Immediate event listener attachment with the current value of item (preserved until iteration).
+  }
+}
+
+setupHelp();
+ +

더 많은 클로저를 사용하는 것이 싫다면 ES2015의 let 키워드를 사용할 수 있다.

+ +
function showHelp(help) {
+  document.getElementById('help').innerHTML = help;
+}
+
+function setupHelp() {
+  var helpText = [
+      {'id': 'email', 'help': 'Your e-mail address'},
+      {'id': 'name', 'help': 'Your full name'},
+      {'id': 'age', 'help': 'Your age (you must be over 16)'}
+    ];
+
+  for (var i = 0; i < helpText.length; i++) {
+    let item = helpText[i];
+    document.getElementById(item.id).onfocus = function() {
+      showHelp(item.help);
+    }
+  }
+}
+
+setupHelp();
+ +

위의 경우 var 대신 let을 사용하여 모든 클로저가 블록 범위 변수를 바인딩할 것이므로 추가적인 클로저를 사용하지 않아도 완벽하게 동작할 것이다.

+ +

성능 관련 고려 사항

+ +

특정 작업에 클로저가 필요하지 않는데 다른 함수 내에서 함수를 불필요하게 작성하는 것은 현명하지 않다. 이것은 처리 속도와 메모리 소비 측면에서 스크립트 성능에 부정적인 영향을 미칠 것이다.

+ +

예를 들어, 새로운 객체/클래스를 생성 할 때, 메소드는 일반적으로 객체 생성자에 정의되기보다는 객체의 프로토타입에 연결되어야 한다. 그 이유는 생성자가 호출 될 때마다 메서드가 다시 할당되기 때문이다 (즉, 모든 개체가 생성 될 때마다).

+ +

비실용적이지만 시범적인 다음 예를 고려하라:

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+  this.getName = function() {
+    return this.name;
+  };
+
+  this.getMessage = function() {
+    return this.message;
+  };
+}
+
+ +

앞의 코드는 클로저의 이점을 이용하지 않음으로 다음과 같이 다시 쓸 수 있다.

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+}
+MyObject.prototype = {
+  getName: function() {
+    return this.name;
+  },
+  getMessage: function() {
+    return this.message;
+  }
+};
+
+ +

그러나 프로토타입을 다시 정의하는 것은 권장되지 않음으로 기존 프로토타입에 추가하는 다음 예제가 더 좋다.

+ +
function MyObject(name, message) {
+  this.name = name.toString();
+  this.message = message.toString();
+}
+MyObject.prototype.getName = function() {
+  return this.name;
+};
+MyObject.prototype.getMessage = function() {
+  return this.message;
+};
+
+ +

위의 코드는 같은 결과를 가진 더 깨끗한 방법으로 작성할 수도 있다:

+ +
function MyObject(name, message) {
+    this.name = name.toString();
+    this.message = message.toString();
+}
+(function() {
+    this.getName = function() {
+        return this.name;
+    };
+    this.getMessage = function() {
+        return this.message;
+    };
+}).call(MyObject.prototype);
+
+ +

앞의 두 가지 예제에서 상속된 프로토타입은 모든 객체에서 공유될 수 있으며 메소드 정의는 모든 객체 생성시 발생할 필요가 없다. 객체 모델의 세부 사항을 참고하라.

diff --git a/files/ko/web/javascript/differential_inheritance_in_javascript/index.html b/files/ko/web/javascript/differential_inheritance_in_javascript/index.html deleted file mode 100644 index 70fd4256c3..0000000000 --- a/files/ko/web/javascript/differential_inheritance_in_javascript/index.html +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: Differential inheritance in JavaScript -slug: Web/JavaScript/Differential_inheritance_in_JavaScript -translation_of: Web/JavaScript/Differential_inheritance_in_JavaScript ---- -

Introduction

- -

차등 상속(Differential Inheritance)은 자바 스크립트와 같은 프로토 타입 기반 프로그래밍 언어에서 사용되는 일반적인 상속 모델입니다. 대부분의 객체는 다른 일반적인 객체에서 파생되고 몇 가지 작은 측면에서만 차이가 있다는 원칙에 따라 동작합니다. 일반적으로 객체가 다른 다른 객체에 대한 포인터 목록을 내부적으로 유지합니다.

- -

Example

- - - -

다음 코드는 개체를 "상속"하는 간단한 메서드 예제입니다.

- -
Object.prototype.inherit = function(){
-  // Create a new object with this as its prototype
-  var p = Object.create(this);
-
-  /* actually not necessary:
-  // Apply the constructor on the new object
-  this.constructor.apply(p, arguments);
-  */
-
-  return p;
-};
-
- -

상속(inherit)을 사용하면 일반 프로토 타입에서보다 구체적인 개체를 간단히 파생시킬 수 있습니다. 다음은 상속 방법 및 차등 상속을 사용하여 점점 더 구체적인 객체를 구성하는 간단한 예입니다.

- -
var root = {}; // Could be any object with any prototype object
-
-var record = root.inherit();
-record.toString = function(){ return "a Record"; };
-
-var person = root.inherit();
-person.firstName = false;
-person.lastName = false;
-person.toString = function(){
-    if (this.firstName) {
-        if (this.lastName) {
-            return this.firstName + " " + this.lastName;
-        } else {
-            return this.firstName;
-        }
-    } else if (this.lastName) {
-        return this.lastName;
-    } else {
-        return "a Person";
-    }
-};
-
-JoePerson = person.inherit();
-JoePerson.firstName = "Joe";
-alert( JoePerson.toString() );
-
- -

See also

- - diff --git a/files/ko/web/javascript/guide/closures/index.html b/files/ko/web/javascript/guide/closures/index.html deleted file mode 100644 index b56d843b2b..0000000000 --- a/files/ko/web/javascript/guide/closures/index.html +++ /dev/null @@ -1,454 +0,0 @@ ---- -title: 클로저 -slug: Web/JavaScript/Guide/Closures -tags: - - Closure - - ES5 - - Intermediate - - JavaScript - - Reference -translation_of: Web/JavaScript/Closures ---- -
{{jsSidebar("Intermediate")}}
- -

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

- -

어휘적 범위 지정(Lexical scoping)

- -

다음을 보자:

- -
function init() {
-  var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
-  function displayName() { // displayName() 은 내부 함수이며, 클로저다.
-    alert(name); // 부모 함수에서 선언된 변수를 사용한다.
-  }
-  displayName();
-}
-init();
- -

init()은 지역 변수 name과 함수 displayName()을 생성한다. displayName()init() 안에 정의된 내부 함수이며 init() 함수 본문에서만 사용할 수 있다. 여기서 주의할 점은 displayName() 내부엔 자신만의 지역 변수가 없다는 점이다. 그런데 함수 내부에서 외부 함수의 변수에 접근할 수 있기 때문에 displayName() 역시 부모 함수 init()에서 선언된 변수 name에 접근할 수 있다. 만약 displayName()가 자신만의 name변수를 가지고 있었다면, name대신 this.name을 사용했을 것이다.

- -

{{JSFiddleEmbed("https://jsfiddle.net/78dg25ax/", "js,result", 250)}}

- -

위 코드를 실행하면 displayName() 함수 내의 alert()문이 부모 함수에서 정의한 변수 name의 값을 성공적으로 출력한다. 이 예시를 통해 함수가 중첩된 상황에서 파서가 어떻게 변수를 처리하는지 알 수 있다. 이는 어휘적 범위 지정(lexical scoping)의 한 예이다. 여기서 "lexical"이란, 어휘적 범위 지정(lexical scoping) 과정에서 변수가 어디에서 사용 가능한지 알기 위해 그 변수가 소스코드 내 어디에서 선언되었는지 고려한다는 것을 의미한다. 단어 "lexical"은 이런 사실을 나타낸다. 중첩된 함수는 외부 범위(scope)에서 선언한 변수에도 접근할 수 있다.

- -

클로저(Closure)

- -

이제 다음 예제를 보자:

- -
function makeFunc() {
-  var name = "Mozilla";
-  function displayName() {
-    alert(name);
-  }
-  return displayName;
-}
-
-var myFunc = makeFunc();
-//myFunc변수에 displayName을 리턴함
-//유효범위의 어휘적 환경을 유지
-myFunc();
-//리턴된 displayName 함수를 실행(name 변수에 접근)
- -

이 코드는 바로 전의 예제와 완전히 동일한 결과가 실행된다. 하지만 흥미로운 차이는 displayName()함수가 실행되기 전에 외부함수인 makeFunc()로부터 리턴되어 myFunc 변수에 저장된다는 것이다.

- -

한 눈에 봐서는 이 코드가 여전히 작동하는 것이 직관적으로 보이지 않을 수 있다. 몇몇 프로그래밍 언어에서, 함수 안의 지역 변수들은 그 함수가 처리되는 동안에만 존재한다. makeFunc() 실행이 끝나면(displayName함수가 리턴되고 나면) name 변수에 더 이상 접근할 수 없게 될 것으로 예상하는 것이 일반적이다.

- -

하지만 위의 예시와 자바스크립트의 경우는 다르다. 그 이유는 자바스크립트는 함수를 리턴하고, 리턴하는 함수가 클로저를 형성하기 때문이다. 클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 이 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역 변수로 구성된다. 첫 번째 예시의 경우, myFuncmakeFunc이 실행될 때 생성된 displayName 함수의 인스턴스에 대한 참조다. displayName의 인스턴스는 변수 name 이 있는 어휘적 환경에 대한 참조를 유지한다. 이런 이유로 myFunc가 호출될 때 변수 name은 사용할 수 있는 상태로 남게 되고 "Mozilla" 가 alert 에 전달된다.

- -

다음은 조금 더 흥미로운 예제인 makeAdder 함수이다:

- -
function makeAdder(x) {
-  var y = 1;
-  return function(z) {
-    y = 100;
-    return x + y + z;
-  };
-}
-
-var add5 = makeAdder(5);
-var add10 = makeAdder(10);
-//클로저에 x와 y의 환경이 저장됨
-
-console.log(add5(2));  // 107 (x:5 + y:100 + z:2)
-console.log(add10(2)); // 112 (x:10 + y:100 + z:2)
-//함수 실행 시 클로저에 저장된 x, y값에 접근하여 값을 계산
-
-
- -

이 예제에서 단일 인자 x를 받아서 새 함수를 반환하는 함수 makeAdder(x)를 정의했다. 반환되는 함수는 단일 인자 z를 받아서 x와 y와 z의 합을 반환한다.

- -

본질적으로 makeAdder는 함수를 만들어내는 공장이다. 이는 makeAdder함수가 특정한 값을 인자로 가질 수 있는 함수들을 리턴한다는 것을 의미한다. 위의 예제에서 add5, add10 두 개의 새로운 함수들을 만들기 위해 makeAdder함수 공장을 사용했다. 하나는 매개변수 x에 5를 더하고 다른 하나는 매개변수 x에 10을 더한다.

- -

add5add10은 둘 다 클로저이다. 이들은 같은 함수 본문 정의를 공유하지만 서로 다른 맥락(어휘)적 환경을 저장한다. 함수 실행 시 add5의 맥락적 환경에서 클로저 내부의 x는 5 이지만 add10의 맥락적 환경에서 x는 10이다. 또한 리턴되는 함수에서 초기값이 1로 할당된 y에 접근하여 y값을 100으로 변경한 것을 볼 수 있다. (물론 x값도 동일하게 변경 가능하다.) 이는 클로저가 리턴된 후에도 외부함수의 변수들에 접근 가능하다는 것을 보여주는 포인트이며 클로저에 단순히 값 형태로 전달되는 것이 아니라는 것을 의미한다.

- -

실용적인 클로저

- -

클로저는 어떤 데이터(어휘적 환경)와 그 데이터를 조작하는 함수를 연관시켜주기 때문에 유용하다. 이것은 객체가 어떤 데이터와(그 객체의 속성) 하나 혹은 그 이상의 메소드들을 연관시킨다는 점에서 객체지향 프로그래밍과 분명히 같은 맥락에 있다.

- -

결론적으로 오직 하나의 메소드를 가지고 있는 객체를 일반적으로 사용하는 모든 곳에 클로저를 사용할 수 있다.

- -

이렇게 할 수 있는 상황은 특히 웹에서 일반적이다. 프론트 엔드 자바스크립트에서 우리가 쓰는 많은 코드가 이벤트 기반이다. 우리는 몇 가지 동작을 정의한 다음 사용자에 의한 이벤트에(클릭 혹은 키 누르기 같은) 연결한다. 우리의 코드는 일반적으로 콜백으로 첨부된다: 이벤트에 응답하여 실행되는 단일 함수다.

- -

예를 들면 페이지의 글자 크기를 조정하는 몇 개의 버튼을 추가한다고 가정하자. 이 작업을 수행하는 한 가지 방법은 body 요소의 font-size를 픽셀 단위로 지정하고 상대적인 em 단위를 사용하여 페이지의 다른 요소들의 (예: 헤더) 크기를 설정하는 것이다.

- -
body {
-  font-family: Helvetica, Arial, sans-serif;
-  font-size: 12px;
-}
-
-h1 {
-  font-size: 1.5em;
-}
-
-h2 {
-  font-size: 1.2em;
-}
-
- -

우리의 대화식 글자 크기 버튼들은 body 요소의 font-size 속성을 변경할 수 있고 이런 조정은 상대적 단위들 덕분에 페이지의 다른 요소에 의해 선택된다.

- -

여기 자바스크립트 코드가 있다.

- -
function makeSizer(size) {
-  return function() {
-    document.body.style.fontSize = size + 'px';
-  };
-}
-
-var size12 = makeSizer(12);
-var size14 = makeSizer(14);
-var size16 = makeSizer(16);
-
- -

size12, size14, size16은 body 요소의 글자 크기를 각각 12, 14, 16 픽셀로 바꾸는 함수이다. 이 함수들을 아래처럼 버튼들에(이 경우에는 링크) 연결할 수 있다.

- -
document.getElementById('size-12').onclick = size12;
-document.getElementById('size-14').onclick = size14;
-document.getElementById('size-16').onclick = size16;
-
- -
<a href="#" id="size-12">12</a>
-<a href="#" id="size-14">14</a>
-<a href="#" id="size-16">16</a>
-
- -

{{JSFiddleEmbed("https://jsfiddle.net/vnkuZ/","","200")}}

- -

클로저를 이용해서 프라이빗 메소드 (private method) 흉내내기

- -

자바와 같은 몇몇 언어들은 메소드를 프라이빗으로 선언할 수 있는 기능을 제공한다. 이는 같은 클래스 내부의 다른 메소드에서만 그 메소드들을 호출할 수 있다는 의미이다.

- -

자바스크립트는 태생적으로는 이런 방법을 제공하지 않지만 클로저를 이용하여 프라이빗 메소드를 흉내내는 것이 가능하다. 프라이빗 메소드는 코드에 제한적인 접근만을 허용한다는 점 뿐만 아니라 전역 네임 스페이스를 관리하는 강력한 방법을 제공하여 불필요한 메소드가 공용 인터페이스를 혼란스럽게 만들지 않도록 한다.

- -

아래 코드는 프라이빗 함수와 변수에 접근하는 퍼블릭 함수를 정의하기 위해 클로저를 사용하는 방법을 보여준다. 이렇게 클로저를 사용하는 것을 모듈 패턴이라 한다.

- -
var counter = (function() {
-  var privateCounter = 0;
-  function changeBy(val) {
-    privateCounter += val;
-  }
-  return {
-    increment: function() {
-      changeBy(1);
-    },
-    decrement: function() {
-      changeBy(-1);
-    },
-    value: function() {
-      return privateCounter;
-    }
-  };
-})();
-
-console.log(counter.value()); // logs 0
-counter.increment();
-counter.increment();
-console.log(counter.value()); // logs 2
-counter.decrement();
-console.log(counter.value()); // logs 1
-
- -

이전 예제에서 각 클로저들이 고유한 문법적 환경을 가졌지만 여기서 우리는 counter.increment, counter.decrement, counter.value 세 함수에 의해 공유되는 하나의 어휘적 환경을 만든다.

- -

공유되는 어휘적 환경은 실행되는 익명 함수 안에서 만들어진다. 이 익명 함수는 정의되는 즉시 실행된다. 이 어휘적 환경은 두 개의 프라이빗 아이템을 포함한다. 하나는 privateCounter라는 변수이고 나머지 하나는 changeBy라는 함수이다. 둘 다 익명 함수 외부에서 접근될 수 없다. 대신에 익명 래퍼에서 반환된 세 개의 퍼블릭 함수를 통해서만 접근되어야만 한다.

- -

위의 세 가지 퍼블릭 함수는 같은 환경을 공유하는 클로저다. 자바스크립트의 어휘적 유효 범위 덕분에 세 함수 각각 privateCounter 변수와 changeBy 함수에 접근할 수 있다.

- -

카운터를 생성하는 익명 함수를 정의하고 그 함수를 즉시 호출하고 결과를 counter 변수에 할당하는 것을 알아차렸을 것이다. 이 함수를 별도의 변수 makeCounter 저장하고 이 변수를 이용해 여러 개의 카운터를 만들 수 있다.

- -
var makeCounter = function() {
-  var privateCounter = 0;
-  function changeBy(val) {
-    privateCounter += val;
-  }
-  return {
-    increment: function() {
-      changeBy(1);
-    },
-    decrement: function() {
-      changeBy(-1);
-    },
-    value: function() {
-      return privateCounter;
-    }
-  }
-};
-
-var counter1 = makeCounter();
-var counter2 = makeCounter();
-alert(counter1.value()); /* 0 */
-counter1.increment();
-counter1.increment();
-alert(counter1.value()); /* 2 */
-counter1.decrement();
-alert(counter1.value()); /* 1 */
-alert(counter2.value()); /* 0 */
-
- -

두 개의 카운터가 어떻게 다른 카운터와 독립성을 유지하는지 주목해보자. 각 클로저는 그들 고유의 클로저를 통한 privateCounter 변수의 다른 버전을 참조한다. 각 카운터가 호출될 때마다; 하나의 클로저에서 변수 값을 변경해도 다른 클로저의 값에는 영향을 주지 않는다.

- -

이런 방식으로 클로저를 사용하여 객체지향 프로그래밍의 정보 은닉과 캡슐화 같은 이점들을 얻을 수 있다.

- -

클로저 스코프 체인

- -

모든 클로저에는 세가지 스코프(범위)가 있다:-

- -
    -
  • 지역 범위 (Local Scope, Own scope)
  • -
  • 외부 함수 범위 (Outer Functions Scope)
  • -
  • 전역 범위 (Global Scope)
  • -
- -

따라서, 우리는 클로저에 대해 세가지 범위 모두 접근할 수 있지만, 중첩된 내부 함수가 있는 경우 종종 실수를 저지른다. 아래 예제를 확인해보자:

- -
// 전역 범위 (global scope)
-var e = 10;
-function sum(a){
-  return function(b){
-    return function(c){
-      // 외부 함수 범위 (outer functions scope)
-      return function(d){
-        // 지역 범위 (local scope)
-        return a + b + c + d + e;
-      }
-    }
-  }
-}
-
-console.log(sum(1)(2)(3)(4)); // log 20
-
-// 익명 함수 없이 작성할 수도 있다.
-
-// 전역 범위 (global scope)
-var e = 10;
-function sum(a){
-  return function sum2(b){
-    return function sum3(c){
-      // 외부 함수 범위 (outer functions scope)
-      return function sum4(d){
-        // 지역 범위 (local scope)
-        return a + b + c + d + e;
-      }
-    }
-  }
-}
-
-var s = sum(1);
-var s1 = s(2);
-var s2 = s1(3);
-var s3 = s2(4);
-console.log(s3) //log 20
- -

위의 예제를 보면 일련의 중첩된 함수들을 확인할 수 있다. 이 함수들은 전부 외부 함수의 스코프에 접근할 수 있다. 그런데 문제는 즉각적인 외부 함수의 스코프만을 추측한다는 것이다. 이 문맥에서는 모든 클로저가 선언된 외부 함수의 스코프에 접근한다라고 말할 수 있다.

- -

루프에서 클로저 생성하기: 일반적인 실수

- -

ECMAScript 2015의 let 키워드 소개 전에는 클로저와 관련된 일반적인 문제는 루프 안에서 클로저가 생성되었을 때 발생한다.다음 예제를 보자.

- -
<p id="help">Helpful notes will appear here</p>
-<p>E-mail: <input type="text" id="email" name="email"></p>
-<p>Name: <input type="text" id="name" name="name"></p>
-<p>Age: <input type="text" id="age" name="age"></p>
-
- -
function showHelp(help) {
-  document.getElementById('help').innerHTML = help;
-}
-
-function setupHelp() {
-  var helpText = [
-      {'id': 'email', 'help': 'Your e-mail address'},
-      {'id': 'name', 'help': 'Your full name'},
-      {'id': 'age', 'help': 'Your age (you must be over 16)'}
-    ];
-
-  for (var i = 0; i < helpText.length; i++) {
-    var item = helpText[i];
-    document.getElementById(item.id).onfocus = function() {
-      showHelp(item.help);
-    }
-  }
-}
-
-setupHelp();
-
- -

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/", "", 200)}}

- -

helpText 배열은 세 개의 도움말 힌트를 정의한다. 각 도움말은 문서의 입력 필드의 ID와 연관된다. 루프를 돌면서 각 입력 필드 ID에 해당하는 엘리먼트의 onfocus 이벤트에 관련된 도움말을 보여주는 메소드에 연결한다.

- -

이 코드를 사용하면 제대로 동작하지 않는 것을 알게 된다. 어떤 필드에 포커스를 주더라도 나이에 관한 도움말이 표시된다.

- -

onfocus 이벤트에 연결된 함수가 클로저이기 때문이다. 이 클로저는 함수 정의와 setupHelp 함수 범위에서 캡처된 환경으로 구성된다. 루프에서 세 개의 클로저가 만들어졌지만 각 클로저는 값이 변하는 변수가 (item.help) 있는 같은 단일 환경을 공유한다. onfocus 콜백이 실행될 때 콜백의 환경에서 item 변수는 (세개의 클로저가 공유한다) helpText 리스트의 마지막 요소를 가리키고 있을 것이다.

- -

이 경우 한 가지 해결책은 더 많은 클로저를 사용하는 것이다: 특히 앞에서 설명한 함수 팩토리를 사용하는 것이다.

- -
function showHelp(help) {
-  document.getElementById('help').innerHTML = help;
-}
-
-function makeHelpCallback(help) {
-  return function() {
-    showHelp(help);
-  };
-}
-
-function setupHelp() {
-  var helpText = [
-      {'id': 'email', 'help': 'Your e-mail address'},
-      {'id': 'name', 'help': 'Your full name'},
-      {'id': 'age', 'help': 'Your age (you must be over 16)'}
-    ];
-
-  for (var i = 0; i < helpText.length; i++) {
-    var item = helpText[i];
-    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);
-  }
-}
-
-setupHelp();
-
- -

{{JSFiddleEmbed("https://jsfiddle.net/v7gjv/1/", "", 300)}}

- -

이것은 예상대로 동작한다. 모두 단일 환경을 공유하는 콜백대신, makeHelpCallback 함수는 각각의 콜백에 새로운 어휘적 환경을 생성한다. 여기서 help는 helpText 배열의 해당 문자열을 나타낸다.

- -

익명 클로저를 사용하여 위 코드를 작성하는 또 다른 방법은 다음과 같다.

- -
function showHelp(help) {
-  document.getElementById('help').innerHTML = help;
-}
-
-function setupHelp() {
-  var helpText = [
-      {'id': 'email', 'help': 'Your e-mail address'},
-      {'id': 'name', 'help': 'Your full name'},
-      {'id': 'age', 'help': 'Your age (you must be over 16)'}
-    ];
-
-  for (var i = 0; i < helpText.length; i++) {
-    (function() {
-       var item = helpText[i];
-       document.getElementById(item.id).onfocus = function() {
-         showHelp(item.help);
-       }
-    })(); // Immediate event listener attachment with the current value of item (preserved until iteration).
-  }
-}
-
-setupHelp();
- -

더 많은 클로저를 사용하는 것이 싫다면 ES2015의 let 키워드를 사용할 수 있다.

- -
function showHelp(help) {
-  document.getElementById('help').innerHTML = help;
-}
-
-function setupHelp() {
-  var helpText = [
-      {'id': 'email', 'help': 'Your e-mail address'},
-      {'id': 'name', 'help': 'Your full name'},
-      {'id': 'age', 'help': 'Your age (you must be over 16)'}
-    ];
-
-  for (var i = 0; i < helpText.length; i++) {
-    let item = helpText[i];
-    document.getElementById(item.id).onfocus = function() {
-      showHelp(item.help);
-    }
-  }
-}
-
-setupHelp();
- -

위의 경우 var 대신 let을 사용하여 모든 클로저가 블록 범위 변수를 바인딩할 것이므로 추가적인 클로저를 사용하지 않아도 완벽하게 동작할 것이다.

- -

성능 관련 고려 사항

- -

특정 작업에 클로저가 필요하지 않는데 다른 함수 내에서 함수를 불필요하게 작성하는 것은 현명하지 않다. 이것은 처리 속도와 메모리 소비 측면에서 스크립트 성능에 부정적인 영향을 미칠 것이다.

- -

예를 들어, 새로운 객체/클래스를 생성 할 때, 메소드는 일반적으로 객체 생성자에 정의되기보다는 객체의 프로토타입에 연결되어야 한다. 그 이유는 생성자가 호출 될 때마다 메서드가 다시 할당되기 때문이다 (즉, 모든 개체가 생성 될 때마다).

- -

비실용적이지만 시범적인 다음 예를 고려하라:

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-  this.getName = function() {
-    return this.name;
-  };
-
-  this.getMessage = function() {
-    return this.message;
-  };
-}
-
- -

앞의 코드는 클로저의 이점을 이용하지 않음으로 다음과 같이 다시 쓸 수 있다.

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-}
-MyObject.prototype = {
-  getName: function() {
-    return this.name;
-  },
-  getMessage: function() {
-    return this.message;
-  }
-};
-
- -

그러나 프로토타입을 다시 정의하는 것은 권장되지 않음으로 기존 프로토타입에 추가하는 다음 예제가 더 좋다.

- -
function MyObject(name, message) {
-  this.name = name.toString();
-  this.message = message.toString();
-}
-MyObject.prototype.getName = function() {
-  return this.name;
-};
-MyObject.prototype.getMessage = function() {
-  return this.message;
-};
-
- -

위의 코드는 같은 결과를 가진 더 깨끗한 방법으로 작성할 수도 있다:

- -
function MyObject(name, message) {
-    this.name = name.toString();
-    this.message = message.toString();
-}
-(function() {
-    this.getName = function() {
-        return this.name;
-    };
-    this.getMessage = function() {
-        return this.message;
-    };
-}).call(MyObject.prototype);
-
- -

앞의 두 가지 예제에서 상속된 프로토타입은 모든 객체에서 공유될 수 있으며 메소드 정의는 모든 객체 생성시 발생할 필요가 없다. 객체 모델의 세부 사항을 참고하라.

diff --git a/files/ko/web/javascript/guide/details_of_the_object_model/index.html b/files/ko/web/javascript/guide/details_of_the_object_model/index.html new file mode 100644 index 0000000000..230d5cb9e1 --- /dev/null +++ b/files/ko/web/javascript/guide/details_of_the_object_model/index.html @@ -0,0 +1,714 @@ +--- +title: 객체 모델의 세부 사항 +slug: Web/JavaScript/Guide/객체_모델의_세부사항 +translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
+ +

자바스크립트는 클래스 기반이 아닌 prototype에 기초한 객체 기반 언어 입니다. 이런 차이점으로 인해, 객체들의 계층 구조의 생성과 속성 및 속성 값의 상속을 어떻게 구현해야 하는지에 대한 부분이 덜 분명할 수 있습니다. 이번 장에서는 이런 상황을 명확하게 하고자 합니다. 

+ +

이번 장에선 이미 자바스크립트를 어느 정도 알고 있고, 간단한 객체를 생성하는 함수들을 사용해보았다는 가정하에 진행합니다.

+ +

클래스 기반 언어 대 프로토타입 기반 언어

+ +

Java와 C++같은 클래스 기반의 언어들은 두개의 구별되는 개념에 기반을 두고 있습니다: 그건 바로 클래스와 인스턴스입니다.

+ +
    +
  • 클래스는  특정 객체군을 특징 짓는 모든 속성들(Java에서는 메서드들과 필드들을 , C++에서는  멤버들을 속성으로 간주합니다. )을 정의합니다.클래스는 해당 객체군을 표현할 수 있는 특정 멤버를 지칭하는 것이 아닌 그보다 더 추상적인 것입니다. 예를 들어, 직원클래스는 직원들을 대표할 수 있습니다.
  • +
  • 반면 인스턴스는 클래스를 기반으로 실체화된 것입니다. 예를 들어, 빅토리아는 특정 직원 개인을 나타내는 직원클래스의 인스턴스가 될 수 있습니다. 인스턴스는 부모 클래스의 속성과 동일한 속성들을 가집니다.
  • +
+ +

자바스크립트같은 프로토타입기반의 언어들은 위와 같은 클래스와 인스턴스의 차이를 두지 않습니다. 간단하게 객체들을 가질 뿐입니다. prototype기반의 언어는 원형(프로토타입)의 객체 개념을 가지고 있습니다. 하나의 객체는 새로운 객체를 생성했을 때 초기 속성을 가질 수 있도록 하는 형판(template)으로 사용됩니다. 객체는 생성될 때 혹은 실행 시에 자기 자신의 속성을 명시할 수 있습니다. 추가적으로, 객체들은 또 다른 객체를 생성하기 위한 프로토타입으로 연관지어 질 수 있으며 프로토타입으로부터 생성된 두번째 객체가 프로토타입인 첫번째 객체의 속성을 공유(혹은 접근)하는 것을 허용합니다. 

+ +

클래스 정의

+ +

클래스 기반의 언어들에서, 별도의 클래스를 생성하고 그 안에서 해당 클래스를 정의 할 수 있습니다. 해당 정의에서 클래스의 인스턴스를 생성할 수 있는 생성자라고하는 특별한 메서드를 명시할 수 있습니다. 생성자는 해당 인스턴스의 초기 속성 값을 지정할 수 있고, 생성 시점에, 다른 적절한 처리를 수행 할 수 있습니다. 클래스의 인스턴스를 생성하기 위해서 new 연산자와 함께 생성자를 호출해야 합니다. 

+ +

자바스크립트는 위와 비슷한 방법을 취합니다. 하지만 생성자이외에 따로 클래스 정의를 가지고 있지는 않습니다. 대신, 특정 속성및 속성값들을 가지고 객체를 생성하는 생성자 함수를 정의할 수 있습니다. 특정 자바스크립트 함수는 생성자로 사용 될 수 있습니다. 새로운 객체를 생성할려면 new연산자와 함께 생성자 함수를 사용해야 합니다.

+ +
+

ECMAScript 2015에 클래스 선언이 새롭게 소개되었습니다.

+ +
+

ECMAScript 2015에서 소개된 자바스크립트 클래스는 주로 문법적 설탕으로 기존 자바스크립트 프로토타입 기반 상속에  읽기 좋은 형식으로 바뀌었습니다. 이 클래스 문법이 자바스크립트에 새로운 객체 중심 상속 모델을 소개한 것은 아닙니다.

+
+
+ +

하위 클래스와 상속

+ +

클래스 기반 언어에서는 클래스 정의를 통해 클래스 계층구조를 생성합니다. 클래스를 정의할 때 이미 존재하는 클래스의 하위 클래스를 새로운 클래스로 지정할 수 있습니다. 이 하위 클래스는 부모 클래스의 모든 속성을 상속받으며 추가로 새로운 속성을 추가하거나 상속받은 속성을 수정할 수 있습니다. 예를 들어  이름(name)과 부서(dept)을 가진 직원(Employee) 클래스와 그 하위 클래스에 보고(reports) 속성을 추가한 관리자(Manager) 클래스가 있다고 해봅시다. 이 경우 관리자(Manager)의 인스턴스는 다음과 같이 세가지 속성을 모두 가질 수 있습니다 - 이름(name),  부서(dept),  보고(reports).

+ +

자바스크립트는 생성자 함수와 프로토타입 객체를 연결해 상속을 구현합니다. 이런 식으로 직원(Employee) — 관리자(Manager) 예제를 똑같이 구현할 수 있지만 조금 다른 * 사용합니다. 먼저, 이름(name),  부서(dept) 속성을 명시하여 직원(Employee) 생성자 함수를 정의합니다. 그런 다음, 직원(Employee)의 생성자를 호출한 후 보고(reports) 속성을 명시해 관리자(Manager) 생성자 함수를 정의합니다. 마지막으로 Employee.prototype 에서 파생된 새로운 객체를  관리자(Manager) 생성자 함수의 프로토타입으로 지정합니다. 그런 다음 새로운 관리자(Manager)를 만들면 관리자(Manager) 객체를 직원(Employee) 객체로부터 이름(name),  부서(dept) 속성을 상속받습니다. 

+ +

속성의 추가 삭제

+ +

클래스 기반의 언어들에서는, 일반적으로 컴파일 시점에 클래스를 생성한 후에 컴파일 시점 혹은 실행 시에 해당 클래스의 인스턴스를 생성합니다. 클래스가 한번 정의된 후에 클래스를 다시 컴파일 하지 않는다면, 속성의 갯수나 형식을 변경할 수 없습니다. 하지만 자바스크립트에서느 실행 시에 객체의 속성을 추가 혹은 삭제 할 수 있습니다.  만약 객체군의 프로토타입으로 사용되는 객체에 속성을 추가하면, 프로토타입이 되는 객체들에도 새로운 속성이 추가가 됩니다.

+ +

차이점들에 대한 정리

+ +

다음 표는 이런 차이점들에 대한 간략한 요약을 포함하고 있습니다. 이번 장의 다음 내용들은 객체의 계층 구조를 생성하기 위한 자바스크립트 생성자와 프로토타입들의 사용에 대한 세부 사항에 대해 기술합니다. 그리고 동일한 작업을 자바에서 어떻게 처리해야 하는지도 비교해서 살펴보겠습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
클래스 기반(자바)과 프로토타입(prototype)기반(자바스크립트) 객체 시스템의 비교
클래스 기반(자바)원형 기반(자바스크립트)
클래스와 인스턴스는 별개입니다.모든 객체는 다른 객체로부터 상속을 받습니다.
클래스 정의를 가지고 클래스를 생성하고 생성자 메서드로 인스턴스를 생성합니다.생성자 함수를 가지고 객체군을 정의 및 생성합니다.
new 연산자로 하나의 객체(인스턴스)를 생성합니다.동일합니다.
이미 존재하는 클래스에 대한 하위 클래스를 정의함으로써 객체의 계층구조를 생성합니다.하나의 객체를 생성자 함수와 결합된 프로토타입에 할당함으로써 객체의 계층구조를 생성 합니다.
클래스의 상속 구조에 따라 속성을 상속 받습니다.프로토타입 체인에 따라  속성을 상속 받습니다.
클래스 정의는 모든 인스턴스의 모든 속성을 명시합니다. 실행시에 동적으로 속성을 추가할 수 없습니다.생성자 함수 혹은 프로토타입은 초기 속성들을 명시합니다. 개별 객체 혹은 전체 객체군에 동적으로 속성을 추가 삭제할 수 있습니다.
+ +

직원 예제

+ +

이장의 나머지 부분에서는 다음과 같은 직원 객체의 계층구조를 사용합니다. 

+ +
+

직원 객체의 계층 구조.

+ +

+ +
    +
  • 직원(Employee) 객체는 빈 문자열을 기본값으로 가지는 이름(name) 그리고 "일반(general)"을 기본 값으로 가지는 부서(dept)를 속성으로 가집니다.
  • +
  • 관리자(Manager)객체는 직원(Employee) 객체를 근간으로 하며, 직원 객체들을 포함하기 위한 빈 배열을 기본 값으로 하는 보고(reports)속성을 가지고 있습니다.
  • +
  • 근로자(WorkerBee)객체 또한 직원(Employee) 객체를 근간으로 하며, 문자열들을 포함하기 위한 빈 배열을 기본 값으로 하는 프로젝트(projects)속성을 가집니다.
  • +
  • 영업사원(SalesPerson)객체는 또한 근로자(WorkerBee) 객체를 근간으로 하며, 100을 기본값으로 하는 할당량(quota)를 속성으로 가집니다. 또한 같은 부서내의 모든 영업사원을 지칭하기 위한 부서 속성을 "판매부서"로 재정의 합니다. 
  • +
  • 엔지니어(Engineer)객체도 근로자(WorkerBee) 객체를 근간으로 하며, 빈 문자열을 기본값으로 가지는 장비(machine) 속성을 가집니다.그리고 엔지니어링(engineering)이라는 값으로 부서 속성을 재정의 합니다.
  • +
+
+ +

계층 구조 생성

+ +

직원 계층 구조를 구현하기 위한 적절한 생성자 함수를 정의하는 방법에는 여러가지가 있습니다. 개발하려고 하는 어플리케이션에 따라 생성자 함수를 정의 하는 방법은 달라질 수 있습니다. 

+ +

이번 절에서는 상속을 구현하기 위한 간단한 (비교적 유연하지는 않은) 정의 방법을 보여 줄 것입니다. 이런 정의 방법을 사용하게되면, 객체를 생성할 때 어떤 속성 값도 지정을 할 수 없습니다. 새로이 생성된 객체들은 기본값들을 가지고 있으며, 나중에 해당 속성 값들을 변경할 수 있습니다.

+ +

실제 어플리케이션에서는, 객체를 생성할때, 해당 객체가 가져야할 속성을 인자로 받는 생성자를 정의 할수 있습니다.(보다 자세한 사항은 다음을 참조하세요. More flexible constructors). 지금 당장은, 상속이 어떻게 작동하는지를 보여주기 위한 간단한 예제를 사용합니다. 

+ +

다음의 자바와 자바스크립트로 작성된 직원 정의는 비슷합니다. 차이점은 자바언어에서는 개별 속성에 대한 타입(type)을 일일이 지정을 해야 하지만  자바스크립트에서는 일일이 개별 속성에 대한 타입(type)을 지정할 필요가 없다는 것입니다.(이런 이유로 자바스크립트가 약하게 형식화된 언어로 불리는 반면 자바는 강력하게 형식화된 언어로 불립니다.)

+ + + + + + + + +
+

자바스크립트

+ +
+function Employee() {
+  this.name = "";
+  this.dept = "general";
+}
+
+

자바

+ +
+public class Employee {
+   public String name = "";
+   public String dept = "general";
+}
+
+
+ +

관리자와 근로자 정의는 계층 구조상에서 상위에 위치하는 객체를 어떻게 표시하는지에 대한 차이점을 보여 줍니다. 자바스크립트에서는 생성자 함수 정의 이후에 언제든 생성자 함수의 프로토타입(prototype) 속성의 값으로 프로토타입 인스턴스를 추가할 수 있습니다.  자바에서는 클래스 정의에 상위 클래스를 명시해야 합니다. 클래스 정의 이후에는 상위 클래스를 변경할 수 없습니다.

+ +
+

자바스크립트

+ +
function Manager() {
+  Employee.call(this);
+  this.reports = [];
+}
+Manager.prototype = Object.create(Employee.prototype);
+
+function WorkerBee() {
+  Employee.call(this);
+  this.projects = [];
+}
+WorkerBee.prototype = Object.create(Employee.prototype);
+
+ +

자바

+ +
public class Manager extends Employee {
+   public Employee[] reports = new Employee[0];
+}
+
+
+
+public class WorkerBee extends Employee {
+   public String[] projects = new String[0];
+}
+
+
+
+
+ +

엔지니어와 영업사원 정의들은 객체들을 생성합니다. 생성된 객체는 근로자 객체의 하위 객체이고 따라서 직원 객체의 하위 객체가 됩니다. 상속 관계에 따라 엔지니어와 영업사원 객체들은 근로자와 직원객체의 속성을 가지게 됩니다. 게다가, 상속받은 부서 속성은 엔지니어와 영업사원에서 재정되어 새로운 값을 가지게 됩니다. 

+ +
+

자바스크립트

+ +
function SalesPerson() {
+   WorkerBee.call(this);
+   this.dept = "sales";
+   this.quota = 100;
+}
+SalesPerson.prototype = Object.create(WorkerBee.prototype);
+
+function Engineer() {
+   WorkerBee.call(this);
+   this.dept = "engineering";
+   this.machine = "";
+}
+Engineer.prototype = Object.create(WorkerBee.prototype);
+
+ +

Java

+ +
public class SalesPerson extends WorkerBee {
+   public double quota;
+   public dept = "sales";
+   public quota = 100.0;
+}
+
+
+public class Engineer extends WorkerBee {
+   public String machine;
+   public dept = "engineering";
+   public machine = "";
+}
+
+
+ +

이런 정의 방법을 통해, 기본값을 가지는 각각의 속성을 포함하는 객체의 인스턴스를 생성할 수 있습니다. 다음 그림은 새로운 객체를 생성하고 새로운 객체에 대한 속성값들을 보여 표시하기 위한 자바스크립트의 정의들을 보여 줍니다.

+ +
+

유의사항: 클래스 기반 언어들에서 인스턴스라는 용어는 특정한 기술적 의미를 가지고 있습니다. 이러한 언어들에서,  하나의 인스턴스란 하나의 클래스의 개별적인  실체이며 클래스와는 근본적으로 다릅니다. 자바스크립트에서는 클래스와 인스턴스 간의 차이가 없기 때문에, "인스턴스"가 이런 기술적 의미를 갖지 않습니다. 하지만, 자바스크립트에 대해서 얘기하자면, 비공식적으로 "인스턴스"는 특정한 생성자 함수를 이용하여 생성된 오브젝트를  의미합니다. 그래서 이번 예제에서는 jane Engineer 의 인스턴스라고 할 수 있습니다. 이와 유사하게, 부모, 자식, 상위, 하위의 용어들은 자바스크립트에서 공식적인 의미를 갖지 않습니다; 다만 프로토타입 체인 상의 상위 또는 하위 객체를 지칭하기 위해서 비공식적으로 사용할 수 있습니다.

+
+ +

간단한 정의로 객체 생성

+ +
+

객체의 계층구조

+ +

오른쪽에 보이는 코드로 생성된 객체의 계층 구조는 아래와 같습니다.

+ +

+ +

개별 객체들

+ +
var jim = new Employee;
+// jim.name is ''
+// jim.dept is 'general'
+
+var sally = new Manager;
+// sally.name is ''
+// sally.dept is 'general'
+// sally.reports is []
+
+var mark = new WorkerBee;
+// mark.name is ''
+// mark.dept is 'general'
+// mark.projects is []
+
+var fred = new SalesPerson;
+// fred.name is ''
+// fred.dept is 'sales'
+// fred.projects is []
+// fred.quota is 100
+
+var jane = new Engineer;
+// jane.name is ''
+// jane.dept is 'engineering'
+// jane.projects is []
+// jane.machine is ''
+
+
+ +

객체 속성들

+ +

이번 장에서는 객체가 프로토타입체인 상의 다른 객체로부터 특성을 상속받는 방법과 런타임 상에서 프로퍼티를 추가하면 무슨 일이 일어나는 지 살펴봅니다.

+ +

속성 상속

+ +

아래 구문처럼 WorkerBee 생성자로 mark 객체를 생성했다고 가정합니다.

+ +
var mark = new WorkerBee;
+
+ +

new 연산자를 만나면, 자바스크립트는 새로운 일반 객체를 생성하고 암묵적으로 내부의 [[Prototype]](__proto__) 속성의 값을 WorkerBee.prototype 의 값으로 할당하며, 해당 객체를 this 키워드의 값으로써 생성자 함수 WorkerBee에 전달합니다. 내부의 [[Prototype]] 속성은 속성값을 반환하기 위해 사용할 프로토타입 체인을 결정합니다. 이런 속성들이 할당되면, 자바스크립트는 새 객체를 반환하고, 할당 구문에 의해 변수 mark를 객체에 할당합니다.

+ +

이러한 절차는 mark가 프로토타입 체인으로부터 상속받는  속성의 값을 mark 객체 내부에(local values) 명시적으로 부여하진 않습니다. 당신이 속성의 값을 요청하면, 자바스크립트는 먼저 해당 객체에 값이 존재하는지 확인합니다. 존재한다면, 해당 값이 반환됩니다. 만약 해당 객체에 값이 없다면, 프로토타입 체인을 (내장 [[Prototype]] 속성;__proto__을 이용하여)확인합니다. 체인 상의 어떤 객체가 해당 속성의 값을 가지고 있다면 그 값이 반환됩니다. 그런 속성이 발견되지 않는다면, 자바스크립트는 객체가 속성을 가지고있지 않다고 할 것입니다. 이런 식으로, mark 객체는 다음의 속성과 값을 가집니다.

+ +
mark.name = "";
+mark.dept = "general";
+mark.projects = [];
+ +

mark 객체는 mark.__proto__로 연결되어 있는 원형의 객체로부터 이름(name)과 부서(dept)에 대한 값을 상속 받습니다. 근로자(WorkerBee) 생성자로부터 projects속성에 대한 값을 할당을 받습니다.이것들이 자바스크립트내에서 속성과 속성 값의 상속입니다. 이런 과정의 몇몇 세부 사항들은 Property inheritance revisited에서 다룹니다. 

+ +

이런 생성자들은 당신이 직접 인스턴스에만 해당 하는 값을 설정하도록 하지 않기때문에, 객체에 대한 이런 정보들은 일반적으로 적용됩니다. 근로자(WorkerBee)로부터 생성된 모든 새로운 객체들은 기본값이 적용된 속성 값들을 가지게 됩니다. 물론, 속성 값들을 변경할 수 있습니다. 아래처럼 특정 인스턴스에만 해당하는 값을 설정할 수 있습니다. 

+ +
mark.name = "Doe, Mark";
+mark.dept = "admin";
+mark.projects = ["navigator"];
+ +

속성 추가

+ +

자바스크립트에선, 실행 시점에 특정 객체에 속성들을 추가 할 수 있습니다.생성자 함수가 제공하는 속성외에 다른 속성을 추가할 수 있습니다. 특정 단일 객체에 속성을 추가하기 위해선, 다음과 같이 해당 객체에 값을 할당 하면 됩니다:

+ +
mark.bonus = 3000;
+
+ +

이렇게 하면 mark객체는 보너스(bonus)속성을 가지게 됩니다. 하지만 mark객체를 제외한 나머지 근로자(WorkerBee)객체들은 보너스 속성을 가지지 않습니다. 

+ +

만약 생성자 함수의 원형으로 사용되는 객체에 새로운 속성을 추가한다면,  해당 프로토타입 객체(prototype)의 속성을 상속받는 모든 객체에 해당 속성이 추가됩니다. 예를 들면, 전문분야(specialty)속성을 모든 직원 객체에 다음과 같은 구문으로 추가할 수 있습니다:

+ +
Employee.prototype.specialty = "none";
+
+ +

위의 구문을 실행한 직후, mark객체는 "none"이라는 값을 가지는 전문분야(specialty)속성을 가지게 됩니다.아래의 그림들은 해당 속성을 추가한 후 엔지니어(Engineer) 프로토타입에 대해 해당 속성을 재정의 했을 경우 각 객체에 미치는 영향을 보여줍니다.

+ +


+ 속성의 추가

+ +

좀 더 유연한 생성자들

+ +

지금까지 살펴 본 생성자 함수들은 인스턴스를 생성하면서 동시에 속성값을 지정할 수 없었습니다. 자바의 경우, 인스턴스를 생성 시 생성자에 인자들을 넘겨주어 인스턴스의 속성들을 초기화 할 수 있습니다. 다음의 예제 그림들은 자바처럼 인스턴스 생성 시 속성값을 설정하는 방법을 보여줍니다.

+ +


+ Specifying properties in a constructor, take 1

+ +

다음의 표는 자바와 자바스크립트 각각의 생성자와 객체에 대한 정의를 보여 줍니다. 

+ +
+

자바스크립트

+ +

자바

+
+ +
+
function Employee (name, dept) {
+  this.name = name || "";
+  this.dept = dept || "general";
+}
+
+ +
public class Employee {
+   public String name;
+   public String dept;
+   public Employee () {
+      this("", "general");
+   }
+   public Employee (String name) {
+      this(name, "general");
+   }
+   public Employee (String name, String dept) {
+      this.name = name;
+      this.dept = dept;
+   }
+}
+
+
+ +
+
function WorkerBee (projs) {
+
+ this.projects = projs || [];
+}
+WorkerBee.prototype = new Employee;
+
+ +
public class WorkerBee extends Employee {
+   public String[] projects;
+   public WorkerBee () {
+      this(new String[0]);
+   }
+   public WorkerBee (String[] projs) {
+      projects = projs;
+   }
+}
+
+
+ +
+
+function Engineer (mach) {
+   this.dept = "engineering";
+   this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+
+ +
public class Engineer extends WorkerBee {
+   public String machine;
+   public Engineer () {
+      dept = "engineering";
+      machine = "";
+   }
+   public Engineer (String mach) {
+      dept = "engineering";
+      machine = mach;
+   }
+}
+
+
+ +

자바스크립트의 속성값을 설정하는 방법은 기본값을 설정하기 위한 관용구를 사용합니다.

+ +
this.name = name || "";
+
+ +

자바스크립트의 OR 논리 연산자(||) 첫번째 인자를 평가합니다. 첫번째 인자가 참이면 첫번째 인자를 반환하고 그렇지 않은 경우는 두번째 인자를 반환합니다. 그러므로, 위의 코드는 name인자가 name 속성에 사용 가능한 값을 가지고 있는지 확인합니다. 확인 결과 name속성에 사용가능한 값을 가지고 있을 경우, 해당 값을 this.name에 설정하게 됩니다. 반대로 그렇지 않은 경우는 빈 문자열을 this.name에 설정합니다.얼핏 보면 헛갈리지만 보다 짧은 관용구를 사용하였습니다.

+ +
+

주의: 만약 인자로 false와 빈 문자열 값을 줄 경우 해당 구문은 예상한 대로 작동하지 않을 수 있습니다.

+
+ +

이런 정의들을 가지고, 객체의 인스턴스를 생성할때, 객체 자신만의 속성에 대한 값을 지정할 수 있습니다. 새로운 Engineer를 생성하기 위해서 다음과 같은 구문을 사용할 수 있습니다:

+ +
var jane = new Engineer("belau");
+
+ +

Jane의 속성들은 다음과 같습니다:

+ +
jane.name == "";
+jane.dept == "engineering";
+jane.projects == [];
+jane.machine == "belau"
+
+ +

위와 같은 코드 구문으로는 name과 같이 상속받은 속성에 대한 초기값을 지정할 수 없습니다.만약 상속 받은 속성의 초기값을 설정하고자 한다면, 생성자 함수의 코드를 변경해야 합니다.

+ +

지금까지, 원형 객체를 생성한 후, 그 새로운 객체 자신의 속성과 속성 값을 지정하는 것을 살펴 보았습니다. 프로토타입 체인상에서 해당 생성자가 상위 객체에 대한 생성자를 직접 호출 함으로써 더 많은 속성을 추가하도록 할 수 있습니다. 다음의 그림은 새로운 정의 방법을 보여 줍니다.

+ +


+ 생성자내에서 속성들 정의, 그림 2

+ +

그럼 좀 더 상세하게 생성자 내에서 속성들을 정의하는 것을 살펴 보겠습니다. 다음은 엔지니어(Engineer) 생성자의 새로운 정의입니다:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+ +

다음과 같이 새로운 엔지니어(Engineer)객체를 생성할 수 있습니다:

+ +
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+
+ +

다음과 같은 순서에 따라 객체를 생성하고 속성을 정의하게 됩니다:

+ +
    +
  1. new 연산자는 프로토타입 객체를 생성하고 생성된 객체의 __proto__속성을 Engineer.prototype으로 설정합니다.
  2. +
  3. new 연산자는 새로이 생성된 객체를 엔지니어(Engineer)생성자에 this 키워드의 값으로 전달합니다.
  4. +
  5. 생성자는 생성한 객체에 대한 base라는 새로운 속성을 생성하고 근로자(WorkerBee) 생성자의 값을 base 속성에 할당합니다. 이런 과정은 근로자(WorkerBee) 생성자를 엔지니어(Engineer)객체의 메서드로 만듭니다. base 속성의 이름은 그리 특별하지 않습니다. 다른 어떤 속성명을 사용해도 무방합니다. base 속성명은 단지 해당 속성의 목적을 환기시키기 위한 것입니다.
  6. +
  7. +

    생성자는 base 메서드에 필요한 인자들 ("Doe, Jane" and ["navigator", "javascript"])을 주어 호출합니다.명시적으로 생성자에서 사용한 "engineering"은 모든 엔지니어(Engineer)객체들이 상속받은 부서 속성에 대한 동일한 값을 가지며, 직원(Employee)으로부터 상속받은 값을 재정의 하는 것을 나타냅니다.

    +
  8. +
  9. base가 엔지니어(Engineer)의 메서드이기때문에 base메서드 내에서 this키워드를 스텝1에서 생성한 객체를 지칭하도록 해줍니다. 따라서, 근로자(WorkerBee) 함수는 차례대로 "Doe, Jane""engineering" 인자를 직원(Employee)생성자에 전달합니다. 직원(Employee)생성자로부터 반환 시, 근로자(WorkerBee)함수는 남은 인자들을 프로젝트(projects)속성을 설정하기 위해 사용합니다. 
  10. +
  11. base메서드로부터 반환 시, 엔지니어(Engineer) 생성자는 해당 객체의 장비(machine)속성을 "belau"로 초기화 합니다.
  12. +
  13. 생성자로부터 반환 시, 새롭게 생성된 객체를 jane변수에 할당 합니다.
  14. +
+ +

엔지니어(Engineer) 생성자내에서 근로자(WorkerBee)생성자를 호출하면, 엔지니어(Engineer)에 대한 상송을 적절하게 설정할 수 도 있을 것이라고 생각할 수 있을 것입니다.하지만 그렇지 않습니다. 근로자(WorkerBee)생성자를 호출하는 것은 엔지니어(Engineer)객체로 하여금 호출되는 모든 생성자 함수내에서 열거된 속성들을 가지고도록 보장합니다.그러나, 나중에 직원(Employee)혹은 근로자(WorkerBee) 원형에 속성을 추가한다면, 엔지니어(Engineer)객체에 의해 추가된 속성들은 상속이 되지 않습니다. 예를 들어, 아래와 같은 구문을 작성하였다고 가정합니다:

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+Employee.prototype.specialty = "none";
+
+ +

jane객체는 전문분야(specialty)속성을 상속받지 않습니다.

+ +
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
+Employee.prototype.specialty = "none";
+
+ +

이제 jane객체의 전문분야(specialty)속성은 "none"이 되었습니다.

+ +

call() 혹은 apply() 메서드를 사용는 것은 상속을 구현하는 또 다른 방법입니다. 다음의 두 예제는 동일한 결과를 보여줍니다. 

+ +
+
function Engineer (name, projs, mach) {
+  this.base = WorkerBee;
+  this.base(name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+ +
function Engineer (name, projs, mach) {
+  WorkerBee.call(this, name, "engineering", projs);
+  this.machine = mach || "";
+}
+
+
+ +

base를 사용하지 않고 구현을 하기 때문에, call() 메서드를 사용하여 상속을 구현하는 것이 보다 깔끔합니다.

+ +

속성 상속의 재고

+ +

이전 절에서 자바스크립트의 생성자와 원형(prototype)이 어떤 방식으로 상속과 객체의 계층 구조를 제공하는지를 살펴 보았습니다. 이번장에서는 이전 절에서 반드시 명백하게 짚고 넘어가지 않은 일부 미묘한 점들에 대해 살펴보겠습니다.

+ +

객체 자신의 값과 상속받은 값

+ +

이번 장에서 이미 설명된 것 처럼, 객체의 속성에 접근할 때, 자바스크립트는 아래와 같은 절차를 따릅니다.

+ +
    +
  1. 해당 속성에 대한 객체 자신의 값이 있는지 확인하고 있으면 그 값을 반환한다.
  2. +
  3. 객체 자신의 값이 없으면 __proto__ 속성을 사용하여 프로토타입 체인을 확인한다.
  4. +
  5. 프로토타입 체인상의 특정 객체가 해당 속성에 대한 값을 가지고 있다면 해당 객체의 값을 반환한다.
  6. +
  7. 해당 속성을 가진 어떤 객체도 발견하지 못하면 해당 객체는 그 속성을 가지고 있지 않은 것으로 판단한다.
  8. +
+ +

이런 단계들의 결과는 생성자 및 프로토타입 체인등의 것들을 어떻게 정의 하느냐에 따라 달라집니다. 아래와 같은 원래의 예제는 이런 정의들을 가지고 있습니다:

+ +
function Employee () {
+  this.name = "";
+  this.dept = "general";
+}
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+ +

이런 정의들을 가지고, amy라는 근로자(WorkerBee)인스턴스를 아래와 같이 생성하였다고 가정합니다.

+ +
var amy = new WorkerBee;
+
+ +

amy객체는 프로젝트라는 자신만의 속성을 가집니다.이름과 부서 속성들은 amy 자신의 속성이 아닌 amy객체의 __proto__속성을 통해 가지고 온 속성들입니다. 따라서 amy는 이런 속성들의 값을 가지게 됩니다.

+ +
amy.name == "";
+amy.dept == "general";
+amy.projects == [];
+
+ +

직원(Employee)과 연관되어 있는 프로토타입내의 이름 속성의 값을 아래와 같이 변경하였다고 가정합니다.

+ +
Employee.prototype.name = "Unknown"
+
+ +

얼핏보기에, 새로운 값이 모든 직원 인스턴스에 적용이 될것으로 예상하겠지만 그렇지 않습니다. 

+ +

직원 객체의 인스턴스를 생성할때, 해당 인스턴스는 이름 속성에 대해 자신이 가지고 있는 값(빈 문자열)을 취하게 됩니다.이것이 의미하는 것은 새로운 직원 객체를 생성하여 근로자(WorkerBee)의 프로토타입에 설정을 할때, WorkerBee.prototype이 이름 속성에 대한 자신만의 값을 가지고 있다는 것입니다.그러므로, amy객체(근로자 인스턴스)의 이름 속성에 대해 검색할때, WorkerBee.prototype내에서 이름 속성에 대한 amy 객체 자신의 값을 찾게됩니다. 그렇기때문에 Employee.prototype까지의 프로토타입 체인을 검색하지 않게 됩니다.

+ +

실행시에 객체의 속성 값을 변경하고 새로운 값이 모든 하위 객체들에게도 적용되도록 할려면, 객체의 생성자함수에서는 속성을 정의할 수 없습니다. 대신에, 생성자와 연결된 프로토타입에 추가할 수 있습니다. 예를 들어, 이전의 코드를 아래와 같이 변경하였다고 가정합니다:

+ +
function Employee () {
+  this.dept = "general";
+}
+Employee.prototype.name = "";
+
+function WorkerBee () {
+  this.projects = [];
+}
+WorkerBee.prototype = new Employee;
+
+var amy = new WorkerBee;
+
+Employee.prototype.name = "Unknown";
+
+ +

이 경우 amy 객체의 이름 속성의 값은 "Unknown"이 됩니다.

+ +

위의 예제에서처럼, 객체 생성 시에 객체의 속성에 대한 기본 값을 설정하고 실행 시에 해당 속성의 값을 변경하기를 원한다면, 해당 속성들을 생성자 함수 자체안에가 아닌 생성자의 프로토타입에 설정 하여야 합니다.

+ +

인스턴스 관계 결정

+ +

자바스크립트에서의 속성 검색은 객체 자신의 속성들을 먼저 살펴보고 해당 속성명을 찾지 못할 경우, 객체의 특별한 속성인 __proto__내에서 찾게 됩니다. 이런 검색은 재귀적으로 진행되며, 이런 과정을 "프로토타입 체인에서의 검색"이라고 합니다.

+ +

특별한 속성인 __proto__객체가 생성이 될때 설정이 됩니다. __proto__속성은 생성자의 프로토타입 속성의 값으로 설정이 됩니다. 따라서 new Foo() 표현식은 __proto__ == Foo.prototype인 객체를 생성합니다. 결과적으로 Foo.prototype의 속성들에 대한 변경은 new Foo() 표현식으로 생성한 모든 객체에 대한 속성 검색을 변경하게 됩니다.

+ +

모든 객체는 __proto__라는 객체 속성을 가집니다.(예외: Object). 모든 함수들은 prototype이라는 객체 속성을 가집니다. 따라서 객체들은 '프로토타입 상속'에 의해 다른 객체들과의 관계를 가지게 됩니다.객체의 __proto__속성과 함수의 prototype 객체를 비교하여 상속을 테스트 해볼 수 있습니다. 자바스크립트는 특정 객체가 함수 prototype으로부터 상속 받는 객체일 경우 참(true)를 반환하는  instanceof라는 연산자를 제공합니다. 예를 들면,

+ +
var f = new Foo();
+var isTrue = (f instanceof Foo);
+ +

Inheriting properties에 나오는 예제와 동일한 정의들을 작성해 놓았을 경우, 보다 상세한 예제는 아래와 같습니다.엔지니어(Engineer)객체를 아래와 같이 생성합니다:

+ +
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
+
+ +

생성된 객체를 가지고 아래와 같은 구문을 실행할 경우 각 구문에 대한 결과는 모두 참(true)입니다.

+ +
chris.__proto__ == Engineer.prototype;
+chris.__proto__.__proto__ == WorkerBee.prototype;
+chris.__proto__.__proto__.__proto__ == Employee.prototype;
+chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
+chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
+
+ +

주어진 이런 상황에서, instanceOf를 다음과 같이 직접 작성할 수 있을 것입니다:

+ +
function instanceOf(object, constructor) {
+   object = object.__proto__;
+   while (object != null) {
+      if (object == constructor.prototype)
+         return true;
+      if (typeof object == 'xml') {
+        return constructor.prototype == XML.prototype;
+      }
+      object = object.__proto__;
+   }
+   return false;
+}
+
+ +
+

주의: 위의 구현내용은 최신 버전의 자바스크립트에서 XML객체들이 표현되는 방법의 특질을 해결하기 위해 해당 객체의 타입이 "xml"인지 확인합니다. 핵심적인 세부 사항을 확인하려면 {{ bug(634150) }}를 참조하세요.

+
+ +

위의 instanceOf함수를 사용하면 아래의 표현들은 모두 참(true)입니다:

+ +
instanceOf (chris, Engineer)
+instanceOf (chris, WorkerBee)
+instanceOf (chris, Employee)
+instanceOf (chris, Object)
+
+ +

하지만 아래의 표현식은 거짓(false)가 됩니다:

+ +
instanceOf (chris, SalesPerson)
+
+ +

생성자내에서의 전역 정보

+ +

생성자를 생성할때, 생성자내에서 전역 정보를 설정할 경우, 주의를 해야 합니다. 예를 들어, 각각의 새로운 직원에게 자동으로 고유한 ID값을 할당하기를 원한다고 했을 때, 다음과 같은 직원(Employee) 정의를 사용할 수 있을 것입니다:

+ +
var idCounter = 1;
+
+function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   this.id = idCounter++;
+}
+
+ +

이런 정의 내용을 가지고, 새로운 직원을 생성했을 때, 생성자는 다음의 고유한 ID값을 새로운 직원객체에 할당하고 전역 ID 카운터를 증가 시킵니다. 따라서 다음과 같은 구문으로 각각의 객체를 생성한다면, 결과는 victoria.id는 1 그리고 harry.id는 2가 됩니다:

+ +
var victoria = new Employee("Pigbert, Victoria", "pubs")
+var harry = new Employee("Tschopik, Harry", "sales")
+
+ +

얼핏보면 괜찮아 보입니다. 하지만 이유를 불문하고 직원 객체가 생성될때마다 idCounter는 증가분을 가지게 됩니다.이번장에서 나온 예제에서처럼 전체 직원(Employee) 객체의 계층 구조를 생성하였다면, 프로토타입을 설정할때마다 직원 생성자는 매번 호출 됩니다.다음과 같은 코드를 작성하였다고 가정합니다:

+ +
var idCounter = 1;
+
+function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   this.id = idCounter++;
+}
+
+function Manager (name, dept, reports) {...}
+Manager.prototype = new Employee;
+
+function WorkerBee (name, dept, projs) {...}
+WorkerBee.prototype = new Employee;
+
+function Engineer (name, projs, mach) {...}
+Engineer.prototype = new WorkerBee;
+
+function SalesPerson (name, projs, quota) {...}
+SalesPerson.prototype = new WorkerBee;
+
+var mac = new Engineer("Wood, Mac");
+
+ +

여기서 생략된 정의가 base속성을 가지고 해당 생성자를 프로토타입 체인내의 상위 생성자들을 호출한닥고 좀 더 가정하면, 이런 경우, 생성된 mac객체의 id값은 5가 됩니다.

+ +

어플리케이셔네 따라, 카운터가 이렇게 추가적으로 증가된 것은 문제가 될 수도 그렇지 않을 수 도 있습니다. 카운터에 정확한 값이 설정되기를 원한다면, 사용가능한 해결적은 아래와 같은 생성자를 대신 사용하는 것입니다:

+ +
function Employee (name, dept) {
+   this.name = name || "";
+   this.dept = dept || "general";
+   if (name)
+      this.id = idCounter++;
+}
+
+ +

prototype으로 사용할 직원 인스턴스를 생성할 때, 생성자에 인자들을 주어선 안됩니다. 이 생성자 정의를 사용하여, 인자들을 주지 않을 경우, 생성자는 id에 값을 할당하지 않으며 카운터를 갱신하지 않습니다. 따라서, id값을 가지는 직원 객체에 대해, 반드시 해당 직원의 이름을 명시해야 합니다. 이 예제의 경우 mac인스턴스의 id값은 1이 됩니다.

+ +

다중상속 금지

+ +

몇몇 객체 지향언어들은 다중 상속을 허용합니다. 그것은, 관련이 없는 부모 객체들로 부터 속성들과 값들을 상속 받을 수 있는 것을 말합니다. 자바스크립트는 다중 상속을 지원하지 않습니다.

+ +

속성 값의 상속은 속성에 대한 값을 찾기 위한 프로토타입 체인을 검색에 의해 실행 시점에 이루어 집니다. 하나의 객체는 오로지 하나의 결합된 prototype만을 가지기 때문에, 자바스크립트는 동적으로 하나 이상의 프로토타입 체인으로 부터 상속을 할 수 없습니다. 

+ +

자바스크립트에서, 하나 이상의 다른 생성자 함수를 호출하는 생성자를 사용할 수 있습니다. 이것은 다중 상속처럼 보여질 수 있습니다. 예를 들어, 다음과 같은 구문들을 살펴보세요:

+ +
function Hobbyist (hobby) {
+   this.hobby = hobby || "scuba";
+}
+
+function Engineer (name, projs, mach, hobby) {
+   this.base1 = WorkerBee;
+   this.base1(name, "engineering", projs);
+   this.base2 = Hobbyist;
+   this.base2(hobby);
+   this.machine = mach || "";
+}
+Engineer.prototype = new WorkerBee;
+
+var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")
+
+ +

WorkerBee의 정의는 이번 장의 이전에 사용된 것과 동일하다고 가정합니다.이런 경우, dennis객체는 다음과 같은 속성들을 가지게 됩니다:

+ +
dennis.name == "Doe, Dennis"
+dennis.dept == "engineering"
+dennis.projects == ["collabra"]
+dennis.machine == "hugo"
+dennis.hobby == "scuba"
+
+ +

 따라서 dennis객체는 Hobbyist 생성자로부터 취미(hobby)속성을 받아 오지 않습니다. 그런데 Hobbyist생성자의 프로토타입에 속성을 추가 했다고 가정하면 

+ +
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
+
+ +

dennis객체는 새로이 추가된 속성을 상속받지 않습니다.

+ +
{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
diff --git a/files/ko/web/javascript/guide/functions/index.html b/files/ko/web/javascript/guide/functions/index.html new file mode 100644 index 0000000000..cf9d928eb3 --- /dev/null +++ b/files/ko/web/javascript/guide/functions/index.html @@ -0,0 +1,658 @@ +--- +title: 함수 +slug: Web/JavaScript/Guide/함수 +translation_of: Web/JavaScript/Guide/Functions +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
+ +

함수는 JavaScript에서 기본적인 구성 블록 중의 하나입니다. 함수는 작업을 수행하거나 값을 계산하는 문장 집합 같은 자바스크립트 절차입니다. 함수를 사용하려면 함수를 호출하고자 하는 범위 내에서 함수를 정의해야만 합니다.

+ +

세부 사항에 대해서는 exhaustive reference chapter about JavaScript functions를 참조하세요.

+ +

함수 정의

+ +

함수 선언

+ +

함수 정의(또는 함수 선언)는 다음과 같은 함수 키워드로 구성되어 있습니다:

+ +
    +
  • 함수의 이름
  • +
  • 괄호 안에서 쉼표로 분리된 함수의 매개변수 목록 
  • +
  • 중괄호 { } 안에서 함수를 정의하는 자바스크립트 표현
  • +
+ +

예를 들어, 다음의 코드는 square라는 간단한 함수를 정의하였습니다:

+ +
function square(number) {
+  return number * number;
+}
+ +

함수 squarenumber라는 하나의 매개변수를 가집니다. 이 함수는 인수 (즉, number) 자체를 곱하여 반환하는 하나의 문장으로 구성되어 있습니다. return 문은 함수에 의해 반환된 값을 지정합니다.

+ +
return number * number;
+ +

기본 자료형인 매개변수(number와 같은)는 값으로 함수에 전달됩니다; 즉, 값이 함수로 전달됩니다. 그러나 함수가 매개변수의 값을 바꾸더라도 이는 전역적으로 또는 함수를 호출하는 곳에는 반영되지 않습니다.

+ +

만약 여러분이 매개변수로 (예: {{jsxref("Array")}}이나 사용자가 정의한 객체와 같이 기본 자료형이 아닌 경우)를 전달하거나 함수가 객체의 속성을 변하게 하는 경우, 다음의 예처럼 그 변화는 함수 외부에서 볼 수 있습니다:

+ +
function myFunc(theObject) {
+  theObject.make = "Toyota";
+}
+
+var mycar = {make: "Honda", model: "Accord", year: 1998};
+var x, y;
+
+x = mycar.make; // x 의 값은 "Honda" 입니다.
+
+myFunc(mycar);
+y = mycar.make; // y 의 값은 "Toyota" 입니다.
+                // (make 속성은 myFunc에서 변경되었습니다.)
+
+ +

함수 표현식

+ +

위에서 함수 선언은 구문적인 문(statement)이지만, 함수 표현식( function expression)에 의해서 함수가 만들어 질 수도 있습니다. 이 같은 함수를 익명이라고 합니다. 이 말은 모든 함수가 이름을 가질 필요는 없다는 것을 뜻합니다. 예를 들어, 함수 square은 다음과 같이 정의 될 수도 있습니다:

+ +
var square = function(number) { return number * number };
+var x = square(4) // x 의 값은 16 입니다.
+ +

하지만, 함수 표현식에서 함수의 이름을 지정 할 수 있으며, 함수내에서 자신을 참조하는데 사용되거나, 디버거 내 스택 추적에서 함수를 식별하는 데 사용될 수 있습니다.

+ +
var factorial = function fac(n) { return n<2 ? 1 : n*fac(n-1) };
+
+console.log(factorial(3));
+
+ +

함수 표현식은 함수를 다른 함수의 매개변수로 전달할 때 편리합니다. 다음 예는 첫 번째 인자로로 함수를, 두 번째 인자로 배열을 받는 map 함수를 보여줍니다.

+ +
function map(f,a) {
+  var result = [], // Create a new Array
+      i;
+  for (i = 0; i != a.length; i++)
+    result[i] = f(a[i]);
+  return result;
+}
+
+ +

다음 코드에서, 함수 표현식으로 정의된 함수를 인자로 받아, 2번 째 인자인 배열의 모든 요소에 대해 그 함수를 실행합니다.

+ +
function map(f, a) {
+  var result = []; // Create a new Array
+  var i; // Declare variable
+  for (i = 0; i != a.length; i++)
+    result[i] = f(a[i]);
+      return result;
+}
+var f = function(x) {
+   return x * x * x;
+}
+var numbers = [0, 1, 2, 5, 10];
+var cube = map(f,numbers);
+console.log(cube);
+ +

함수는 [0, 1, 8, 125, 1000] 을 반환합니다.

+ +

JavaScript에서 함수는 조건에 의해 정의될 수 있습니다. 예를 들어, 다음 함수 정의는 오직 num이 0일 때 경우에 만 myFunc을 정의합니다.

+ +
var myFunc;
+if (num == 0){
+  myFunc = function(theObject) {
+    theObject.make = "Toyota"
+  }
+}
+ +

여기에 기술된 바와 같이 함수를 정의하는것에 더하여 {{jsxref("eval", "eval()")}} 과 같이 런타임에 문자열에서 함수들을 만들기위해 {{jsxref("Function")}} 생성자를 사용할 수 있습니다.

+ +

객체내의 한 속성이 함수인 경우 메서드라고 합니다. Working with objects에서 객체와 방법에 대해 자세히 알아보세요.

+ +

함수 호출

+ +

함수를 정의하는 것은 함수를 실행하는 것이 아닙니다. 함수를 정의하는 것은 간단히 함수의 이름을 지어주고, 함수가 호출될 때 무엇을 할지 지정 해주는 것입니다. 사실 함수를 호출하는 것은 나타나있는 매개변수를 가지고 지정된 행위를 수행하는 것입니다. 예를 들어, 만약 여러분이 함수 square를 정의한다면, 함수를 다음과 같이 호출할 수 있습니다.

+ +
square(5);
+
+ +

위의 문장은 5라는 인수를 가지고 함수를 호출합니다. 함수는 이 함수의 실행문을 실행하고 값 25를 반환합니다.

+ +

함수는 호출될 때 범위 내에 있어야 합니다. 그러나 함수의 선언은 이 예에서와 같이, 호이스팅 될 수 있습니다. (코드에서 호출 아래에 선언문이 있습니다.):

+ +
console.log(square(5));
+/* ... */
+function square(n) { return n*n }
+
+ +

함수의 범위는 함수가 선언된 곳이거나, 전체 프로그램 에서의 최상위 레벨(전역)에 선언된 곳입니다.

+ +
+

비고: 위에 구문을 사용하여 함수를 정의하는 경우에만 작동합니다 (즉, function funcName(){} ). 아래와 같은 코드는 작동되지 않습니다. 이것이 의미하는 바는, 함수 호이스팅은 오직 함수 선언과 함께 작동하고, 함수 표현식에서는 동작하지 않습니다.

+
+ +
console.log(square);   // square는 초기값으로 undefined를 가지고 호이스트된다.
+console.log(square(5));  // TypeError: square는 함수가 아니다.
+square = function (n) {
+  return n * n;
+}
+
+ +

함수의 인수는 문자열과 숫자에 제한되지 않습니다. 여러분은 함수에 전체 객체를 전달할 수 있습니다. show_props() 함수(Working with objects에서 정의된)는 인수로 객체를 취하는 함수의 예입니다.

+ +

함수는 자신을 호출할 수 있습니다. 예를 들어, 팩토리얼을 재귀적으로 계산하는 함수가 있습니다:

+ +
function factorial(n){
+  if ((n == 0) || (n == 1))
+    return 1;
+  else
+    return (n * factorial(n - 1));
+}
+
+ +

여러분은 다음과 같이 1부터 5까지의 팩토리얼을 계산할 수 있습니다.

+ +
var a, b, c, d, e;
+a = factorial(1); // a gets the value 1
+b = factorial(2); // b gets the value 2
+c = factorial(3); // c gets the value 6
+d = factorial(4); // d gets the value 24
+e = factorial(5); // e gets the value 120
+
+ +

함수를 호출하는 다른 방법들이 있습니다. 함수를 동적 호출해야 하거나, 함수의 인수의 수가 달라져야 하거나, 함수 호출의 맥락이 런타임에서 결정된 특정한 객체로 설정될 필요가 있는 경우가 자주 있습니다. 함수가 그 자체로 객체이고 이들 객체는 차례로 메서드를({{jsxref("Function")}} 객체를 참조) 가지고 있습니다. 이들 중 하나인 {{jsxref("Function.apply", "apply()")}} 메서드는 이러한 목표를 달성하기 위해 사용될 수 있습니다.

+ +

함수의 범위

+ +

함수 내에서 정의된 변수는 변수가 함수의 범위에서만 정의되어 있기 때문에, 함수 외부의 어느 곳에서든 액세스할 수 없습니다. 그러나, 함수가 정의된 범위 내에서 정의된 모든 변수나 함수는 액세스할 수 있습니다. 즉, 전역함수는 모든 전역 변수를 액세스할 수 있습니다. 다른 함수 내에서 정의 된 함수는 부모 함수와 부모 함수가 액세스 할 수 있는 다른 변수에 정의된 모든 변수를 액세스할 수 있습니다.

+ +
// The following variables are defined in the global scope
+var num1 = 20,
+    num2 = 3,
+    name = "Chamahk";
+
+// This function is defined in the global scope
+function multiply() {
+  return num1 * num2;
+}
+
+multiply(); // Returns 60
+
+// A nested function example
+function getScore () {
+  var num1 = 2,
+      num2 = 3;
+
+  function add() {
+    return name + " scored " + (num1 + num2);
+  }
+
+  return add();
+}
+
+getScore(); // Returns "Chamahk scored 5"
+
+ +

범위와 함수 스택

+ +

재귀

+ +

함수는 자신을 참조하고 호출할 수 있습니다. 함수가 자신을 참조하는 방법은 세 가지가 있습니다.

+ +
    +
  1. 함수의 이름
  2. +
  3. arguments.callee
  4. +
  5. 함수를 참조하는 범위 내 변수
  6. +
+ +

예를 들어, 다음 함수의 정의를 고려해보세요.

+ +
var foo = function bar() {
+   // statements go here
+};
+
+ +

함수 본문 내에서 다음은 모두 동일합니다.

+ +
    +
  1. bar()
  2. +
  3. arguments.callee()
  4. +
  5. foo()
  6. +
+ +

자신을 호출하는 함수를 재귀 함수라고 합니다. 어떤 면에서, 재귀는 루프와 유사합니다. 둘 다 동일한 코드를 여러 번 실행하고, 조건(무한 루프를 방지하거나, 이 경우에는 오히려 무한 재귀하는)을 요구합니다. 예를 들어, 다음 루프는:

+ +
var x = 0;
+while (x < 10) { // "x < 10" is the loop condition
+   // do stuff
+   x++;
+}
+
+ +

아래와 같이 재귀 함수와 그 함수에 대한 호출로 변환될 수 있습니다.

+ +
function loop(x) {
+  if (x >= 10) // "x >= 10" 는 탈출 조건 ("!(x < 10)"와 동등)
+    return;
+  // do stuff
+  loop(x + 1); // the recursive call
+}
+loop(0);
+
+ +

그러나 일부 알고리즘은 단순 재귀 루프로 변환할 수 없습니다. 예를 들어, 트리 구조(가령, DOM)의 모든 노드를 얻는 것은 재귀를 사용하여 보다 쉽게 할 수 있습니다:

+ +
function walkTree(node) {
+  if (node == null) //
+    return;
+  // do something with node
+  for (var i = 0; i < node.childNodes.length; i++) {
+    walkTree(node.childNodes[i]);
+  }
+}
+
+ +

함수  loop 와 비교하여, 각 재귀 호출 자체는 여기에 많은 재귀 호출을 만듭니다.

+ +

재귀적 알고리즘은 비 재귀적인 알고리즘으로 변환 할 수 있습니다. 그러나 변환된 알고리즘이 훨씬 더 복잡하며 그렇게 함으로써 스택의 사용을 요구합니다. 사실, 재귀 자체가 함수 스택을 사용 합니다.

+ +

스택형 동작은 다음의 예에서 볼 수 있습니다:

+ +
function foo(i) {
+  if (i < 0)
+    return;
+  console.log('begin:' + i);
+  foo(i - 1);
+  console.log('end:' + i);
+}
+foo(3);
+
+// Output:
+
+// begin:3
+// begin:2
+// begin:1
+// begin:0
+// end:0
+// end:1
+// end:2
+// end:3
+ +

중첩된 함수와 클로저

+ +

여러분은 함수 내에 함수를 끼워 넣을 수 있습니다. 중첩 된 (내부) 함수는 그것을 포함하는 (외부) 함수와 별개입니다. 그것은 또한 클로저를 형성합니다. 클로저는 그 변수(“폐쇄”라는 표현)를 결합하는 환경을 자유롭게 변수와 함께 가질 수 있는 표현(전형적인 함수)입니다.

+ +

중첩 함수는 클로저이므로, 중첩된 함수는 그것을 포함하는 함수의 인수와 변수를 “상속”할 수 있는 것을 의미합니다. 즉, 내부 함수는 외부 함수의 범위를 포함합니다.

+ +

요약하면:

+ +
    +
  • 내부 함수는 외부 함수의 명령문에서만 액세스할 수 있습니다.
  • +
+ +
    +
  • 내부 함수는 클로저를 형성합니다: 외부 함수는 내부 함수의 인수와 변수를 사용할 수 없는 반면에, 내부 함수는 외부 함수의 인수와 변수를 사용할 수 있습니다.
  • +
+ +

다음 예는 중첩된 함수를 보여줍니다:

+ +
function addSquares(a,b) {
+  function square(x) {
+    return x * x;
+  }
+  return square(a) + square(b);
+}
+a = addSquares(2,3); // returns 13
+b = addSquares(3,4); // returns 25
+c = addSquares(4,5); // returns 41
+
+ +

내부 함수는 클로저를 형성하기 때문에, 여러분은 외부 함수를 호출하고, 외부 및 내부 함수 모두에 인수를 지정할 수 있습니다.

+ +
function outside(x) {
+  function inside(y) {
+    return x + y;
+  }
+  return inside;
+}
+fn_inside = outside(3); // Think of it like: give me a function that adds 3 to whatever you give it
+result = fn_inside(5); // returns 8
+
+result1 = outside(3)(5); // returns 8
+
+ +

변수의 보존

+ +

중첩된 내부 함수가 반환될 때 외부 함수의 인수 x가 보존된다는 점을 알 수 있습니다. 클로저는 그것을 참조하는 모든 범위에서 인수와 변수를 보존해두어야 합니다. 매번 호출될 때마다 잠재적으로 다른 인수를 제공할 수 있기 때문에, 클로저는 외부 함수에 대하여 매번 새로 생성됩니다. 메모리는 그 무엇도 내부 함수에 접근하지 않을 때만 해제됩니다.

+ +

변수의 보존은 일반 객체에서 참조를 저장해두는 것과 다르지 않지만, 사용자가 직접 참조를 설정하는 것이 아니고 자세히 들여다볼 수 없어서 종종 명확하지 않습니다.

+ +

다중 중첩 함수

+ +

함수는 다중 중첩될 수 있습니다. 즉, 함수 (C)를 포함하는 함수 (B)를 포함하는 함수 (A). 여기에서 두 함수 B와 C는 모두 클로저를 형성합니다. 그래서 B는 A를 엑세스할 수 있고, C는 B를 액세스 할 수 있습니다. 이와 같이, 클로저는 다중 범위를 포함 할 수 있습니다; 그들은 재귀적으로 그것을 포함하는 함수의 범위를 포함합니다. 이것을 범위 체이닝이라 합니다.(그것을 “체이닝”이라 하는 이유는 추후에 설명할 것입니다.)

+ +

다음 예를 살펴 보겠습니다:

+ +
function A(x) {
+  function B(y) {
+    function C(z) {
+      console.log(x + y + z);
+    }
+    C(3);
+  }
+  B(2);
+}
+A(1); // logs 6 (1 + 2 + 3)
+
+ +

이 예에서, C는 B의 y와 A의 x를 엑세스 합니다. 이 때문에 수행할 수 있습니다:

+ +
    +
  1. B는 A를 포함하는 클로저를 형성합니다. 즉, B는 A의 인수와 변수를 엑세스할 수 있습니다.
  2. +
  3. C는 B를 포함하는 클로저를 형성합니다.
  4. +
  5. B의 클로저는 A를 포함하고, C의 클로저는 A를 포함하기 때문에, C는 B와 A의 인수와 변수를 엑세스할 수 있습니다. 즉, 순서대로 C는 A와 B의 범위를 체이닝합니다.
  6. +
+ +

그러나 역은 사실이 아닙니다. A는 C에 접근 할 수 없습니다. 왜냐하면 A는 B의 인수와 변수(C는 B변수)에 접근할수 없기 때문입니다. 그래서 C는 B에게만 사적으로 남게됩니다.

+ +

이름 충돌

+ +

클로저의 범위에서 두 개의 인수 또는 변수의 이름이 같은 경우, 이름 충돌이 있습니다. 더 안쪽 범위가 우선순위를 갖습니다. 그래서 가장 바깥 범위는 우선순위가 가장 낮은 반면에, 가장 안쪽 범위는 가장 높은 우선순위를 갖습니다. 이것이 범위 체인(scope chaini)입니다. 체인에서 첫번째는 가장 안쪽 범위이고, 마지막 가장 바깥 쪽의 범위입니다. 다음 사항을 고려하세요:

+ +
function outside() {
+  var x = 10;
+  function inside(x) {
+    return x;
+  }
+  return inside;
+}
+result = outside()(20); // returns 20 instead of 10
+
+ +

이름 충돌이 x를 반환하는 문과 내부의 매개 변수 x와 외부 변수 x 사이에서 발생합니다. 여기에서 범위 체이닝은 {내부, 외부, 전역 객체}입니다. 따라서 내부의 x는 외부의 x보다 높은 우선순위를 갖게 되고, 20(내부의 x)이 10(외부의 x) 대신에 반환됩니다.

+ +

클로저

+ +

클로저는 자바스크립트의 강력한 기능 중 하나입니다. 자바스크립트는 함수의 중첩(함수 안에 함수를 정의하는것)을 허용하고, 내부함수가 외부 함수 안에서 정의된 모든 변수와 함수들을 완전하게 접근 할 수 있도록 승인해줍니다.(그리고 외부함수가 접근할수 있는 모든 다른 변수와 함수들까지) 그러나 외부 함수는 내부 함수 안에서 정의된 변수와 함수들에 접근 할 수 없습니다. 이는 내부 함수의 변수에 대한 일종의 캡슐화를 제공합니다. 또한, 내부함수는 외부함수의 범위에 접근할 수 있기 때문에, 내부 함수가 외부 함수의 수명을 초과하여 생존하는 경우, 외부함수에서 선언된 변수나 함수는 외부함수의 실행 기간보다 오래갑니다. 클로저는 내부 함수가 어떻게든 외부 함수 범위 밖의 모든 범위에서 사용 가능해지면 생성됩니다.

+ +
var pet = function(name) {   // 외부 함수는 'name'이라 불리는 변수를 정의합니다.
+  var getName = function() {
+    return name;             // 내부 함수는 외부 함수의 'name' 변수에 접근합니다.
+  }
+  return getName;            // 내부 함수를 리턴함으로써, 외부 범위에 노출됩니다.
+},
+myPet = pet("Vivie");
+
+myPet();                     // "Vivie"로 리턴합니다.
+
+ +

클로저는 위 코드보다 더 복잡해 질 수도 있습니다. 외부 함수의 내부 변수를 다루는 메서드를 포함한 객체도 반환될 수도 있습니다.

+ +
var createPet = function(name) {
+  var sex;
+
+  return {
+    setName: function(newName) {
+      name = newName;
+    },
+
+    getName: function() {
+      return name;
+    },
+
+    getSex: function() {
+      return sex;
+    },
+
+    setSex: function(newSex) {
+      if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
+        sex = newSex;
+      }
+    }
+  }
+}
+
+var pet = createPet("Vivie");
+pet.getName();                  // Vivie
+
+pet.setName("Oliver");
+pet.setSex("male");
+pet.getSex();                   // male
+pet.getName();                  // Oliver
+
+ +

위 코드에서, 외부 함수의 'name' 이란 변수는 내부 함수에서 접근이 가능합니다. 그리고 그 내장 함수를 통하는 방법 말고는 내부 변수로 접근할 수 없습니다. 내부 함수의 내부 변수는 외부 인수와 변수를 안전하게 저장합니다. 내부 변수는 내부 함수가 작동하기 위해 '지속적'이고 '갭슐화된' 데이터를 보유합니다. 함수는 변수로 할당되거나, 이름을 가질 필요가 없습니다.

+ +
var getCode = (function(){
+  var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
+
+  return function () {
+    return secureCode;
+  };
+})();
+
+getCode();    // Returns the secureCode
+
+ +

그러나 클로저를 쓰면서 조심해야 할 위험이 많이 있습니다. 만약 내부 함수가 외부 함수의 범위에 있는 이름과 같은 변수를 정의하였을 경우, 다시는 외부 함수 범위의 변수를 참조(접근)할 방법이 없습니다.

+ +
var createPet = function(name) {  // 외부 함수가 "name" 이라는 변수를 정의하였다
+  return {
+    setName: function(name) {    // 내부 함수 또한 "name" 이라는 변수를 정의하였다
+      name = name;               // ??? 어떻게 우리는 외부 함수에 정의된 "name"에 접근할까???
+    }
+  }
+}
+
+ +

인수(arguments) 객체 사용하기

+ +

함수의 인수는 배열과 비슷한 객체로 처리가 됩니다. 함수 내에서는, 전달 된 인수를 다음과 같이 다룰 수 있습니다. :

+ +
arguments[i]
+
+ +

i 는 0 으로 시작하는 순서 번호입니다. 따라서 함수에 전달된 첫 번째 인수는 arguments[0] 입니다. 총 인수의 개수는 arguments.length 에서 얻을 수 있습니다.

+ +

인수(arguments) 객체를 이용하면, 보통 함수에 정의된 개수보다 많은 인수를 넘겨주면서 함수를 호출할 수 있습니다. 이것은 얼마나 많은 인수가 함수로 넘겨질지 모르는 상황에서 유용합니다. arguments.length를 함수에 실제로 넘겨받은 인수의 수를 알아낼 때 사용할 수 있고 , 각각의 인수에 인수(arguments) 객체를  이용하여 접근 할 수 있습니다.

+ +

예를 들어, 몇 개의 문자열을 연결하는 함수를 생각해 봅시다. 이 함수의 유일한 형식 인수는 각 문자열을 구분해주는 문자를 나타내는 문자열입니다 . 이 함수는 다음과 같이 정의됩니다:

+ +
function myConcat(separator) {
+   var result = ""; // 리스트를 초기화한다
+   var i;
+   // arguments를 이용하여 반복한다
+   for (i = 1; i < arguments.length; i++) {
+      result += arguments[i] + separator;
+   }
+   return result;
+}
+
+ +

어떤 개수의 인수도 이 함수로 넘겨줄 수 있고, 이 함수는 각각의 인수를 하나의 문자열 "리스트" 로 연결합니다. :

+ +
// returns "red, orange, blue, "
+myConcat(", ", "red", "orange", "blue");
+
+// returns "elephant; giraffe; lion; cheetah; "
+myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
+
+// returns "sage. basil. oregano. pepper. parsley. "
+myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
+
+ +
+

Note: 인수(arguments) 객체는 배열과 닮은 것이지 배열이 아닙니다. 인수(arguments) 객체는 번호 붙여진 인덱스와 길이 속성을 가지고 있다는 점에서 배열과 닮은 것입니다. 인수(arguments) 객체는 배열을 다루는 모든 메서드를 가지고 있지 않습니다.

+
+ +

더 자세한 정보를 얻고 싶으면 자바스크립트 참조문의 {{jsxref("Function")}}객체에 대하여 보세요.

+ +

함수의 매개변수

+ +

 ECMAScript 2015와 함께 시작된,두 종류의 매개변수가 있습니다 : 디폴트 매개변수 , 나머지 매개변수.

+ +

디폴트 매개변수

+ +

자바스크립트에서, 함수의 매개변수는 undefined 가 기본으로 설정됩니다. 그러나, 어떤 상황에서는 다른 값을 기본값으로 가진 것이 유용할 때가 있습니다. 이때가 디폴트 매개변수가 도움을 줄 수 있는 상황입니다.

+ +

옛날엔, 기본값을 설정하는 보편적인 전략은 함수의 본문에서 매개변수 값을 테스트하여 그 값이 undefined 인 경우에 값을 할당하는 것이었습니다. 다음과 같은 예제에서, 함수호출 시 b 매개변수에 아무 값을 주지 않으면, a*b 계산 시 b 매개변수의 값은 undefined 일 것이므로 multiply 함수 호출은 NaN을 리턴할 것입니다. 그러나 이런 것은 이 예제의 2번째 줄에서 걸립니다:

+ +
function multiply(a, b) {
+  b = typeof b !== 'undefined' ?  b : 1;
+
+  return a*b;
+}
+
+multiply(5); // 5
+
+ +

디폴트 매개변수와 함께라면, 함수 본문에서 검사하는 부분은 필요가 없습니다. 이제 , 함수 머리에서 b 의 기본값에 간단히 1을 넣어주면 됩니다:

+ +
function multiply(a, b = 1) {
+  return a*b;
+}
+
+multiply(5); // 5
+ +

더 자세한 내용을 보고 싶으시면,  default parameters 문서를 참조하세요.

+ +

나머지 매개변수

+ +

 나머지 매개변수 구문을 사용하면 배열로 불확실한 개수의 인수를 나타낼 수 있습니다. 이 예제에서, 우리는 나머지 매개변수를 2번째 인수부터 마지막 인수까지 얻기 위하여 사용하였습니다. 그리고 우리는 첫번째 값으로 나머지 매개변수에 곱하였습니다. 이 예제는 다음 섹션에서 소개할  화살표(arrow) 함수 입니다.

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(x => multiplier * x);
+}
+
+var arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

화살표 함수

+ +

 화살표 함수 표현 (뚱뚱한 화살표(fat arrow) 함수라고 알려진)은 함수 표현과 비교하였을때 짧은 문법을 가지고 있고 사전적으로 this 값을 묶습니다. 화살표 함수는 언제나 익명입니다. hacks.mozilla.org 블로그 포스트 "ES6 In Depth: Arrow functions" 를 참조하세요.

+ +

화살표  함수 소개에 영향을 주는 두 요소: 더 짧은 함수와 바인딩 되지않은 this.

+ +

더 짧은 함수

+ +

어떤 함수적 패턴에서는, 더 짧은 함수가 환영받습니다. 다음을 비교해 보세요:

+ +
var a = [
+  "Hydrogen",
+  "Helium",
+  "Lithium",
+  "Beryl­lium"
+];
+
+var a2 = a.map(function(s){ return s.length });
+
+console.log(a2); // logs [8, 6, 7, 9]
+
+var a3 = a.map( s => s.length );
+
+console.log(a3); // logs [8, 6, 7, 9]
+ +

사전적 this

+ +

화살표 함수에서, 모든 new함수들은  그들의  this 값을 정의합니다 (생성자로서의 새로운 객체, 정의되지 않은 strict mode의 함수 호출,   함수가 "object method"로 호출했을때의 context object ,등등.). 이런 것은 객체지향 프로그래밍 스타일에서 짜증을 불러 일으킵니다.

+ +
function Person() {
+  // The Person() constructor defines `this` as itself.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // In nonstrict mode, the growUp() function defines `this`
+    // as the global object, which is different from the `this`
+    // defined by the Person() constructor.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

IECMAScript 3/5 에서는, 이 문제는 this 안의 값을 뒤덮을 수 있는변수에 할당하면서 고쳐졌습니다.

+ +
function Person() {
+  var self = this; // Some choose `that` instead of `self`.
+                   // Choose one and be consistent.
+  self.age = 0;
+
+  setInterval(function growUp() {
+    // The callback refers to the `self` variable of which
+    // the value is the expected object.
+    self.age++;
+  }, 1000);
+}
+ +

또는, 적절한 this 값이 growUp() 함수에 전달되도록, 바인딩된 함수가 생성될 수 있습니다.

+ + + +

화살표 함수에는 this;가 없습니다. 화살표 함수를 포함하는 객체 값이 사용됩니다. 따라서 다음 코드에서 setInterval에 전달 된 함수 내의 this 값은 화살표 함수를 둘러싼 함수의 this와 같은 값을 갖습니다.

+ +
function Person() {
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| properly refers to the person object
+  }, 1000);
+}
+
+var p = new Person();
+ +

미리 정의된 함수들

+ +

자바스크립트에는 최고 등급의 몇가지 내장함수가 있습니다:

+ +
+
{{jsxref("Global_Objects/eval", "eval()")}}
+
+

eval() 메소드는 문자열로 표현된 자바스크립트 코드를 수행합니다.

+
+
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
+
+

uneval() 메소드는  {{jsxref("Object")}}의 소스코드를 표현하는 문자열을 만듭니다.

+
+
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
+
+

전역 isFinite() 함수는 전달받은 값이 유한한지 결정합니다. 만약 필요하다면, 매개변수는 첫번째로 숫자로 변환됩니다.

+
+
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
+
+

isNaN() 함수는 {{jsxref("Global_Objects/NaN", "NaN")}}인지 아닌지 결정합니다. Note:  isNaN 함수 안의 강제 변환은  흥미로운 규칙을 가지고 있습니다;  {{jsxref("Number.isNaN()")}}을 대신 사용하고 싶을것입니다, ECMAScript 6 에서 정의된,또는 값이 숫자값이 아닐때,  typeof 를 사용할 수도 있습니다 .

+
+
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
+
+

parseFloat() 함수는  문자열 인수 값을 해석하여 부동소숫점 수를 반환합니다.

+
+
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
+
+

parseInt() 함수는 문자열 인수 값을 해석하여 특정한 진법의 정수를 반환합니다  (수학적 수 체계를 기반으로 해서).

+
+
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
+
+

decodeURI() 함수는  사전에 {{jsxref("Global_Objects/encodeURI", "encodeURI")}}을 통해 만들어지거나 비슷한 과정을 통해 만들어진 URI(Uniform Resource Identifier)  를 해독합니다.

+
+
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
+
+

decodeURIComponent() 메소드는 사전에{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}}를 통하여 만들어 지거나 또는 비슷한 과정을 통해 만들어진 URI (Uniform Resource Identifier) 컴포넌트를 해독합니다.

+
+
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
+
+

encodeURI() 메소드는  URI(Uniform Resource Identifier)를  각 인스턴스의 특정한 문자를 한개, 두개,세개, 또는 네개의 UTF-8인코딩으로 나타내어지는 연속된 확장문자들과 바꾸는 방법으로 부호화 합니다 .(두"surrogate"문자로 구성된 문자들은 오직 네개의 연속된 확장문자 입니다. ).

+
+
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
+
+

encodeURIComponent() 메소드는  URI(Uniform Resource Identifier) 컴포넌트를  각 인스턴스의 특정한 문자를 한개, 두개,세개, 또는 네개의 UTF-8인코딩으로 나타내어지는 연속된 확장문자들과 바꾸는 방법으로 부호화 합니다 .(두"surrogate"문자로 구성된 문자들은 오직 네개의 연속된 확장문자 입니다. ).).

+
+
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
+
+

곧 사라질 escape() 메소드는 한 문자열에서 특정 문자들이 16진 확장 비트열로 바뀌어진 문자열로 계산합니다.  {{jsxref("Global_Objects/encodeURI", "encodeURI")}} 또는 {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} 를 사용하세요.

+
+
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
+
+

곧 사라질 unescape() 메소드는 문자열에서 확장 비트열이 확장 비트열이 나타내는 문자로 바뀌어진 문자열로 계산합니다.  {{jsxref("Global_Objects/escape", "escape")}}에서 확장 비트열이 소개될 것입니다.  unescape() 메소드가 곧 사라지기 때문에,  {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} or {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} 를 대신 사용하세요.

+
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

+ + + + diff --git a/files/ko/web/javascript/guide/grammar_and_types/index.html b/files/ko/web/javascript/guide/grammar_and_types/index.html new file mode 100644 index 0000000000..629cbd069a --- /dev/null +++ b/files/ko/web/javascript/guide/grammar_and_types/index.html @@ -0,0 +1,708 @@ +--- +title: 문법과 자료형 +slug: 'Web/JavaScript/Guide/Values,_variables,_and_literals' +tags: + - Guide + - JavaScript + - 'l10n:priority' +translation_of: Web/JavaScript/Guide/Grammar_and_types +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/소개", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}
+ +

이 장은 JavaScript의 기본 문법과 변수 선언, 자료형 및 리터럴을 다룹니다.

+ +

기본

+ +

JavaScript는 문법의 대부분을 Java와 C, C++로부터 차용하고 있으며, Awk, Perl, Python의 영향도 받았습니다.

+ +

JavaScript는 대소문자를 구별하며 유니코드 문자셋을 이용합니다. 따라서 다음과 같은 코드도 유효합니다.

+ +
var 갑을 = "병정";
+var Früh = "foobar"; // Früh: 독일어로 "이른"
+
+ +

하지만 Frühfrüh와 다릅니다. 대소문자를 구분하기 때문입니다.

+ +

JavaScript에서는 명령을 {{Glossary("Statement", "명령문(statement)")}}이라고 부르며, 세미콜론(;)으로 구분합니다.

+ +

명령문이 한 줄을 다 차지할 경우에는 세미콜론이 필요하지 않습니다. 그러나 한 줄에 두 개 이상의 명령문이 필요하다면 세미콜론으로 구분해야 합니다. ECMAScript는 세미콜론을 자동으로 삽입해 명령문을 끝내는 규칙(ASI)도 가지고 있습니다. (더 많은 정보는 JavaScript의 어휘 문법 에 대한 자세한 참고서를 참고하세요) 하지만, 세미콜론이 필요하지 않은 경우라도 항상 세미콜론으로 끝마치는 편이 버그 예방 차원에서 더 좋은 습관이라고 여겨집니다.

+ +

JavaScript의 스크립트 소스는 왼쪽에서 오른쪽으로 탐색하면서 토큰, 제어 문자, 줄바꿈 문자, 주석이나 공백으로 이루어진 입력 element의 시퀀스로 변환됩니다. 스페이스, 탭, 줄바꿈 문자는 공백으로 간주됩니다.

+ +

주석

+ +

주석의 구문은 C++ 및 다른 많은 언어와 똑같습니다.

+ +
// 한 줄 주석
+
+/* 이건 더 긴,
+ * 여러 줄 주석입니다.
+ */
+
+/* 그러나, /* 중첩된 주석은 쓸 수 없습니다 */ SyntaxError */
+ +

주석은 공백처럼 행동하며 스크립트 실행 시 버려집니다.

+ +
+

참고: 몇몇 자바스크립트 파일의 시작부에 #!/usr/bin/env node와 같은 형태의 주석 문법이 쓰이는 것을 볼 수 있습니다. 이것은 해시백 주석 문법이라고 하는데, 이 특별한 주석은 스크립트를 실행할 때 쓸 특별한 자바스크립트 인터프리터의 경로를 설정할 때 쓰입니다.  해시백 주석을 참고하여 자세한 내용을 확인할 수 있습니다.

+
+ +

선언

+ +

JavaScript의 선언에는 3가지 방법이 있습니다.

+ +
+
{{jsxref("Statements/var", "var")}}
+
변수를 선언. 추가로 동시에 값을 초기화.
+
{{jsxref("Statements/let", "let")}}
+
블록 범위(scope) 지역 변수를 선언. 추가로 동시에 값을 초기화.
+
{{jsxref("Statements/const", "const")}}
+
블록 범위 읽기 전용 상수를 선언.
+
+ +

변수

+ +

어플리케이션에서 값에 상징적인 이름으로 변수를 사용합니다. 변수명은 {{Glossary("식별자(identifier)")}}라고 불리며 특정 규칙을 따릅니다.

+ +

JavaScript 식별자는 문자, 밑줄(_) 혹은 달러 기호($)로 시작해야 하는 반면 이후는 숫자(0-9)일 수도 있습니다. JavaScript가 대소문자를 구분하기에, 문자는 "A"부터 "Z"(대문자)와 "a"부터 "z"(소문자)까지 모두 포함합니다.

+ +

ISO 8859-1 혹은 Unicode 문자(가령 å 나 ü)도 식별자에 사용할 수 있습니다(좀 더 상세한 내용은 이 블로그 글을 참고). 또한 Unicode escape sequences도 식별자에 문자로 사용할 수 있습니다.

+ +

적절한 이름으로는 Number_hits, temp99, $credit_name등입니다.

+ +

변수 선언

+ +

변수 선언은 아래 3가지 방법으로 가능합니다.

+ +
    +
  • {{jsxref("Statements/var", "var")}} 키워드로. 예를 들어, var x = 42. 이 구문은 지역 및 전역 변수를 선언하는데 모두 사용될 수 있습니다.
  • +
  • {{jsxref("Statements/let", "let")}} 키워드로. 예를 들어, let y = 13. 이 구문은 블록 범위 지역 변수를 선언하는데 사용될 수 있습니다. 아래 변수 범위 참고하세요.
  • +
+ +

간단히 변수에 값을 할당 할 수도 있습니다. 예를 들어, x = 42 와 같은 구문은 선언되지 않는 전역변수 를 만듭니다. 뿐만 아니라, 자바스크립트의 엄격한 경고를 만들어냅니다. 선언되지 않은 전역변수는 의도되지 않은 동작을 만들어내고는 합니다. 따라서 선언되지 않는 전역변수를 사용하면 안됩니다.

+ +

변수 할당

+ +

지정된 초기값 없이 var 혹은 let 문을 사용해서 선언된 변수는 {{jsxref("undefined")}} 값을 갖습니다.

+ +

선언되지 않은 변수에 접근을 시도하는 경우 {{jsxref("ReferenceError")}} 예외가 발생합니다.

+ +
var a;
+console.log("a 값은 " + a); // "a 값은 undefined"로 로그가 남음.
+
+console.log('b 값은 ' + b); // b 값은 undefined
+var b;
+
+console.log("c 값은 " + c); // ReferenceError 예외 던짐
+
+let x;
+console.log('x 값은 ' + x); // x 값은 undefined
+
+console.oog('y 값은 ' + y); // ReferenceError 예외 던짐
+let y;
+
+ +

undefined를 사용하여 변수값이 있는지 확인할 수 있습니다. 아래 코드에서, input 변수는 값이 할당되지 않았고 if문은 true로 평가합니다.

+ +
var input;
+if(input === undefined) {
+  doThis();
+} else {
+  doThat();
+}
+
+ +

undefined 값은 boolean 문맥(context)에서 사용될 때 false로 동작합니다. 예를 들어, 아래 코드는 myArray 요소가 undefined이므로 myFunction 함수를 실행합니다.

+ +
var myArray = [];
+if (!myArray[0]) myFunction();
+
+ +

undefined 값은 수치 문맥에서 사용될 때 NaN으로 변환됩니다.

+ +
var a;
+a + 2; // NaN으로 평가
+ +

{{jsxref("null")}} 값을 평가할 때, 수치 문맥에서는 0으로, boolean 문맥에서는 false로 동작합니다. 예를 들면,

+ +
var n = null;
+console.log(n * 32); // 콘솔에 0 으로 로그가 남음.
+
+ +

변수 범위

+ +

어떤 함수의 바깥에 변수를 선언하면, 현재 문서의 다른 코드에 해당 변수를 사용할 수 있기에 전역 변수라고 합니다. 만약 함수 내부에 변수를 선언하면, 오직 그 함수 내에서만 사용할 수 있기에 지역 변수라고 부릅니다.

+ +

ECMAScript 6 이전의 JavaScript는 block 문 범위가 없습니다. 그래서 오히려, 블록 내에 선언된 변수는 그 블록 내에 존재하는 함수(혹은 전역 범위)에 지역적입니다. 예를 들어서 아래의 코드는 5라는 로그를 남깁니다. x의 범위가 이 경우 if문 블록이 아니라 x가 선언된 함수(나 전역 문맥)이기 때문입니다.

+ +
if (true) {
+  var x = 5;
+}
+console.log(x); // 5
+
+ +

ECMAScript 6에 도입된 let 선언을 사용했을 때, 이 동작은 바뀌었습니다.

+ +
if (true) {
+  let y = 5;
+}
+console.log(y); // ReferenceError: y is not defined
+ +

변수 호이스팅

+ +

또 다른 JavaScript 변수의 특이한 점은 예외를 받지 않고도, 나중에 선언된 변수를 참조할 수 있다는 것입니다. 이 개념은 호이스팅(hoisting)으로 알려져 있습니다. 즉 JavaScript 변수가 어떤 의미에서 "끌어올려지거"나 함수나 문의 최상단으로 올려지는 것을 말합니다. 하지만, 끌어올려진 변수는 undefined 값을 반환합니다. 그래서 심지어 이 변수를 사용 혹은 참조한 후에 선언 및 초기화하더라도, 여전히 undefined를 반환합니다.

+ +
/**
+ * Example 1
+ */
+console.log(x === undefined); // logs "true"
+var x = 3;
+
+
+/**
+ * Example 2
+ */
+// undefined 값을 반환함.
+var myvar = "my value";
+
+(function() {
+  console.log(myvar); // undefined
+  var myvar = "local value";
+})();
+
+ +

위 예제는 아래 예제와 동일하게 볼 수 있습니다.

+ +
/**
+ * Example 1
+ */
+var x;
+console.log(x === undefined); // logs "true"
+x = 3;
+
+/**
+ * Example 2
+ */
+var myvar = "my value";
+
+(function() {
+  var myvar;
+  console.log(myvar); // undefined
+  myvar = "local value";
+})();
+ +

호이스팅 때문에, 함수 내의 모든 var 문은 가능한 함수 상단 근처에 두는 것이 좋습니다. 이 방법은 코드를 더욱 명확하게 만들어줍니다.

+ +

ECMAScript 2015의 let (const)는 변수를 블록의 상단으로 올리지 않습니다.
+ 변수가 선언되기 전에 블록 안에서 변수를 참조하게 되면 {{jsxref("ReferenceError")}}를 발생시키게 됩니다.
+ 변수는 블록 시작부터 선언이 처리될 때까지 'temporal dead zone'에 위치하게 됩니다.

+ +
console.log(x); // ReferenceError
+let x = 3;
+
+ +

함수 호이스팅

+ +

함수에서는 단지 함수 선언만 상단으로 끌어올려집니다. 함수 표현식은 그렇지 않습니다.

+ +
/* 함수 선언 */
+
+foo(); // "bar"
+
+function foo() {
+  console.log('bar');
+}
+
+
+/* 함수 표현식 */
+
+baz(); // TypeError: baz is not a function
+
+var baz = function() {
+  console.log('bar2');
+};
+ +

전역 변수

+ +

전역 변수는 사실 global 객체의 속성(property)입니다. 웹 페이지에서 global 객체는 {{domxref("window")}} 이므로, windows.variable 구문을 통해 전역 변수를 설정하고 접근할 수 있습니다.

+ +

그 결과, window 혹은 frame의 이름을 지정하여 한 window 혹은 frame에서 다른 window 혹은 frame에 선언된 전역 변수에 접근할 수 있습니다. 예를 들어, phoneNumber 라는 변수가 문서에 선언된 경우, iframe에서 parent.phoneNumber로 이 변수를 참조할 수 있습니다.

+ +

상수

+ +

{{jsxref("Statements/const", "const")}} 키워드로 읽기 전용 상수를 만들 수 있습니다. 상수 식별자의 구문은 변수 식별자와 같습니다. 문자, 밑줄이나 달러 기호로 시작해야 하고 문자, 숫자나 밑줄을 포함할 수 있습니다.

+ +
const PI = 3.14;
+
+ +

상수는 스크립트가 실행 중인 동안 대입을 통해 값을 바꾸거나 재선언될 수 없습니다. 값으로 초기화해야 합니다.

+ +

상수에 대한 범위 규칙은 let 블록 범위 변수와 동일합니다. 만약 const 키워드가 생략된 경우에는, 식별자는 변수를 나타내는 것으로 간주됩니다.

+ +

상수는 같은 범위에 있는 함수나 변수와 동일한 이름으로 선언할 수 없습니다. 예를 들어,

+ +
// 오류가 발생합니다
+function f() {};
+const f = 5;
+
+// 역시 오류가 발생합니다
+function f() {
+  const g = 5;
+  var g;
+
+  //statements
+}
+
+ +

그러나, 상수에 할당된 객체의 속성은 보호되지 않아서 다음의 문은 문제없이 실행됩니다.

+ +
const MY_OBJECT = {'key': 'value'};
+MY_OBJECT.key = 'otherValue';
+
+ +

또한, 배열의 내용도 보호되지 않아서 다음의 문도 문제없이 실행됩니다.

+ +
const MY_ARRAY = ['HTML','CSS'];
+MY_ARRAY.push('JAVASCRIPT');
+console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT'];
+
+ +

데이터 구조 및 형

+ +

데이터 형

+ +

최신 ECMAScript 표준은 7가지 데이터 형을 정의합니다.

+ +
    +
  • 6가지 {{Glossary("Primitive", "원시")}} 데이터 형 +
      +
    • {{Glossary("Boolean")}}. true와 false
    • +
    • {{Glossary("null")}}. null 값을 나타내는 특별한 키워드. JavaScript는 대소문자를 구분하므로, null은 Null, NULL 혹은 다른 변형과도 다릅니다.
    • +
    • {{Glossary("undefined")}}. 값이 저장되어 있지 않은 최상위 속성.
    • +
    • {{Glossary("Number")}}. 정수 또는 실수형 숫자. 예:42 혹은 3.14159.
    • +
    • {{Glossary("String")}}. 문자열. 예:"안녕"
    • +
    • {{Glossary("Symbol")}}. (ECMAScript 6에 도입) 인스턴스가 고유하고 불변인 데이터 형.
    • +
    +
  • +
  • 그리고 {{Glossary("Object")}}
  • +
+ +

이 데이터 형이 비교적 많지 않지만, 어플리케이션에 유용한 기능을 수행할 수 있습니다. {{jsxref("Object", "객체")}}와 {{jsxref("Function", "함수")}}는 언어의 다른 기본 요소입니다. 객체는 값을 위한 컨테이너, 함수는 어플리케이션이 수행할 수 있는 절차(procedure)로 생각할 수 있습니다.

+ +

자료형 변환

+ +

JavaScript는 동적 형지정(정형) 언어입니다. 이는 변수를 선언할 때 데이터 형을 지정할 필요가 없음을 의미합니다. 또한 데이터 형이 스크립트 실행 도중 필요에 의해 자동으로 변환됨을 뜻합니다. 그래서, 예를 들어, 다음과 같이 변수를 정의할 수 있습니다.

+ +
var answer = 42;
+ +

그리고 나중에, 동일한 변수에 문자열 값을 할당할 수도 있습니다. 아래와 같이,

+ +
answer = "Thanks for all the fish...";
+
+ +

JavaScript는 동적 형지정 언어이므로, 이 할당은 오류 메시지가 발생하지 않습니다.

+ +

숫자와 문자열 값 사이에 + 연산자를 포함한 식에서, JavaScript는 숫자 값을 문자열로 변환합니다. 예를 들어, 아래와 같은 문이 있습니다.

+ +
x = "The answer is " + 42 // "The answer is 42"
+y = 42 + " is the answer" // "42 is the answer"
+ +

다른 연산자를 포함한 식의 경우, JavaScript는 숫자 값을 문자열로 변환하지 않습니다. 예를 들면,

+ +
"37" - 7 // 30
+"37" + 7 // 377
+
+ +

문자열을 숫자로 변환하기

+ +

숫자를 나타내는 값이 문자열로 메모리에 있는 경우, 변환을 위한 메서드가 있습니다.

+ +
    +
  • {{jsxref("parseInt", "parseInt()")}}
  • +
  • {{jsxref("parseFloat", "parseFloat()")}}
  • +
+ +

parseInt는 오직 정수만 반환하므로, 소수에서는 사용성이 떨어집니다. 게다가 parseInt를 잘 사용하기 위해서는 항상 진법(Radix) 매개변수를 포함해야 합니다. 진법 매개변수는 변환에 사용될 진법을 지정하는데 사용됩니다.

+ +

문자열을 숫자로 변환하는 대안은 +(단항 더하기) 연산자입니다.

+ +
"1.1" + "1.1" = "1.11.1"
+(+"1.1") + (+"1.1") = 2.2
+// 참고: 괄호는 명확성을 위해 추가, 필요한 것은 아닙니다.
+
+ +

리터럴

+ +

JavaScript에서 값을 나타내기 위해 리터럴을 사용합니다. 이는 말 그대로 스크립트에 부여한 고정값으로, 변수가 아닙니다. 이 절에서는 다음과 같은 형태의 리터럴을 설명합니다.

+ +
    +
  • {{anch("배열_리터럴", "배열 리터럴")}}
  • +
  • {{anch("불린_리터럴", "불린 리터럴")}}
  • +
  • {{anch("부동_소수점_리터럴", "부동 소수점 리터럴")}}
  • +
  • {{anch("정수", "정수")}}
  • +
  • {{anch("객체_리터럴", "객체 리터럴")}}
  • +
  • {{anch("정규식_리터럴", "정규식 리터럴")}}
  • +
  • {{anch("문자열_리터럴", "문자열 리터럴")}}
  • +
+ +

배열 리터럴

+ +

배열 리터럴은 0개 이상의 식(expression) 목록입니다. 각 식은 배열 요소를 나타내고 대괄호([])로 묶입니다. 배열 리터럴을 사용하여 배열을 만들 때, 그 요소로 지정된 값으로 초기화되고, 그 길이는 지정된 인수의 갯수로 설정됩니다.

+ +

아래 예제는 요소가 3개로 길이가 3인 coffees 배열을 만듭니다.

+ +
var coffees = ["French Roast", "Colombian", "Kona"];
+
+ +
+

참고: 배열 리터럴은 일종의 객체 이니셜라이저(initialiizer)입니다. Using Object Initializers 참고.

+
+ +

배열이 최상단 스크립트에서 리터럴을 사용하여 만들어진 경우, JavaScript는 배열 리터럴을 포함한 식을 평가할 때마다 배열로 해석합니다. 게다가, 함수에서 사용되는 리터럴은 함수가 호출될 때마다 생성됩니다.

+ +

배열 리터럴은 배열 객체입니다. 배열 객체에 대한 자세한 내용은 {{jsxref("Array")}}와 Indexed collections 참고.

+ +

배열 리터럴의 추가 쉼표

+ +

배열 리터럴에서 모든 요소를 지정할 필요는 없습니다. 만약 잇달아 두 개의 쉼표를 두면, 배열은 지정되지 않은 요소를 undefined로 만듭니다. 다음 예제는 fish 배열을 만듭니다.

+ +
var fish = ["Lion", , "Angel"];
+
+ +

이 배열은 값이 있는 두 요소와 빈 요소 하나를 가집니다(fish[0]은 "Lion", fish[1]undefined, fish[2]는 "Angel").

+ +

만약 요소 목록을 후행(trailing) 쉼표로 끝낸다면, 그 쉼표는 무시됩니다. 다음 예제에서, 배열의 길이는 3입니다. myList[3]은 없습니다. 목록의 다른 모든 쉼표는 새로운 요소를 나타냅니다.

+ +
+

참고: 후행 쉼표는 구버전 브라우저에서 오류를 유발할 수 있으므로 제거하는게 최선입니다.

+
+ +
var myList = ['home', , 'school', ];
+
+ +

아래 예제에서, 배열의 길이는 4이며, myList[0]myList[2]는 값이 빠졌습니다.

+ +
var myList = [ , 'home', , 'school'];
+
+ +

아래 예제에서, 배열의 길이는 4이며, myList[1]myList[3]은 값이 빠졌습니다. 마지막 쉼표는 무시됩니다.

+ +
var myList = ['home', , 'school', , ];
+
+ +

추가 쉼표의 동작을 이해하는 것은 JavaScript를 언어로서 이해하는데 중요하지만, 코드를 작성할 때는 빠진 요소의 값을 명시적으로 undefined로 선언하는 것이 코드의 명확성과 유지보수성을 높입니다.

+ +

불리언 리터럴

+ +

불리언 형은 truefalse의 리터럴 값을 가집니다.

+ +

원시 불린 값 truefalse와 Boolean 객체의 true 및 false 값을 혼동하지 마세요. Boolean 객체는 원시 불린 데이터 형을 감싸는 래퍼(wrapper)입니다. 더 많은 정보는 {{jsxref("Boolean")}}을 참고하세요.

+ +

정수 리터럴

+ +

정수는 10진, 16진, 8진 및 2진수로 표현될 수 있습니다.

+ +
    +
  • 10진 정수 리터럴은 선행 0(zero)이 아닌 숫자열로 이루어집니다.
  • +
  • 정수 리터럴에서 선행 0(zero)이나 선행 0o(혹은 0O)은 8진수임을 나타냅니다. 8진 정수는 오직 숫자 0-7만 포함할 수 있습니다.
  • +
  • 선행 0x(나 0X)는 16진수임을 나타냅니다. 16진 정수는 숫자 0-9 및 문자 a-f, A-F를 포함할 수 있습니다.
  • +
  • 선행 0b(나 0B)는 2진수임을 나타냅니다. 2진 정수는 오직 숫자 0과 1만 포함할 수 있습니다.
  • +
+ +

다음은 정수 리터럴 예제입니다.

+ +
0, 117 및 -345 (10진수)
+015, 0001 및 -0o77 (8진수)
+0x1123, 0x00111 및 -0xF1A7 (16진수)
+0b11, 0b0011 및 -0b11 (2진수)
+
+ +

더 많은 정보는 Lexical grammar reference의 Numeric literals를 참고하세요.

+ +

부동 소수점 리터럴

+ +

부동 소수점 리터럴은 아래와 같은 부분으로 이루어집니다.

+ +
    +
  • 부호("+"나 "-")가 달릴 수 있는 10진 정수,
  • +
  • 소수점("."),
  • +
  • 소수(또 다른 10진수),
  • +
  • 지수.
  • +
+ +

지수부는 "e"나 "E" 다음에 오며 부호("+"나 "-")가 달릴 수 있는 정수입니다. 부동 소수점 리터럴은 적어도 숫자 하나와 소수점 혹은 "e"(나 "E")가 있어야 합니다.

+ +

더 간결하게 설명하면, 구문은 다음과 같습니다.

+ +
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]
+
+ +

예를 들면,

+ +
3.1415926
+-.123456789
+-3.1E+12
+.1e-23
+
+ +

객체 리터럴

+ +

객체 리터럴은 중괄호({})로 묶인 0개 이상인 객체의 속성명과 관련 값 쌍 목록입니다. 문의 시작에 객체 리터럴을 사용해서는 안됩니다. 이는 {가 블록의 시작으로 해석되기 때문에 오류를 이끌거나 의도한 대로 동작하지 않습니다.

+ +

아래는 객체 리터럴의 예제입니다. car 객체의 첫째 요소는 myCar 속성을 정의하고 문자열 "Saturn"을 할당합니다. 반면 둘째 요소인 getCar 속성은 function (carTypes("Honda"))을 호출한 결과가 즉시 할당됩니다. 셋째 요소 special 속성은 기존 변수 sales를 사용합니다.

+ +
var sales = "Toyota";
+
+function carTypes(name) {
+  if (name === "Honda") {
+    return name;
+  } else {
+
+  }
+    return "Sorry, we don't sell " + name + ".";
+}
+
+var car = { myCar: "Saturn", getCar: carTypes("Honda"), special: sales };
+
+console.log(car.myCar);   // Saturn
+console.log(car.getCar);  // Honda
+console.log(car.special); // Toyota
+
+ +

게다가, 속성명으로 숫자나 문자열 리터럴을 사용하거나 또다른 객체 리터럴 내부에 객체를 중첩할 수도 있습니다. 아래 예제는 이 옵션을 사용합니다.

+ +
var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
+
+console.log(car.manyCars.b); // Jeep
+console.log(car[7]); // Mazda
+
+ +

객체 속성명은 빈 문자열 포함 어떤 문자열도 될 수 있습니다. 속성명이 유효한 JavaScript {{Glossary("식별자")}}나 숫자가 아닌 경우, 따옴표로 묶여야 합니다. 또한 유효한 식별자가 아닌 속성명은 점(.) 속성으로 접근할 수 없습니다. 대신 배열 같은 표기법("[]")으로 접근하고 값을 설정할 수 있습니다.

+ +
var unusualPropertyNames = {
+  "": "An empty string",
+  "!": "Bang!"
+}
+console.log(unusualPropertyNames."");   // SyntaxError: Unexpected string
+console.log(unusualPropertyNames[""]);  // An empty string
+console.log(unusualPropertyNames.!);    // SyntaxError: Unexpected token !
+console.log(unusualPropertyNames["!"]); // Bang!
+
+ +

향상된 객체 리터럴

+ +

ES2015에서, 객체 리터럴은 구성에서 프로토타입 설정, foo: foo 할당을 위한 단축 표기, 메서드 정의, super 클래스 호출 및 식으로 동적인 속성명 계산을 지원하기 위해 확장됐습니다. 그에 따라 객체 리터럴 및 클래스 선언이 함께 더 가까워지고, 객체 기반 설계는 같은 일부 편의기능으로 득을 볼 수 있습니다.

+ +
var obj = {
+    // __proto__
+    __proto__: theProtoObj,
+    // ‘handler: handler’의 단축 표기
+    handler,
+    // Methods
+    toString() {
+     // Super calls
+     return "d " + super.toString();
+    },
+    // Computed (dynamic) property names
+    [ 'prop_' + (() => 42)() ]: 42
+};
+ +

아래를 참고하세요.

+ +
var foo = {a: "alpha", 2: "two"};
+console.log(foo.a);    // alpha
+console.log(foo[2]);   // two
+//console.log(foo.2);  // Error: missing ) after argument list
+//console.log(foo[a]); // Error: a is not defined
+console.log(foo["a"]); // alpha
+console.log(foo["2"]); // two
+
+ +

정규식 리터럴

+ +

정규식 리터럴은 (정규식 상세) 슬래시 사이에 감싸인 패턴입니다. 다음은 정규식 리터럴 예제입니다.

+ +
var re = /ab+c/;
+ +

문자열 리터럴

+ +

문자열 리터럴은 큰 따옴표(") 혹은 작은 따옴표(')로 묶인 0개 이상의 문자입니다. 문자열은 같은 형 따옴표, 즉 큰 따옴표 쌍이나 작은 따옴표 쌍으로 구분되어야 합니다. 아래는 문자열 리터럴의 예제입니다.

+ +
"foo"
+'bar'
+"1234"
+"one line \n another line"
+"John's cat"
+
+ +

문자열 리터럴 값은 문자열 객체의 모든 메서드를 호출할 수 있습니다. JavaScript는 자동으로 문자열 리터럴을 임시 문자열 객체로 변환, 메서드를 호출하고 나서 임시 문자열 객체를 폐기합니다. 또한 문자열 리터럴에서도 String.length 속성을 사용할 수 있습니다.

+ +
console.log("John's cat".length)
+// 공백을 포함한 문자열 내 심볼 갯수가 출력됩니다.
+// 여기서는, 10.
+
+ +

ES2015에서는, 템플릿 리터럴도 사용할 수 있습니다. 템플릿 문자열은 문자열 구성을 위한 달콤한 구문을 제공합니다. 이는 Perl, Python 등에 있는 문자열 삽입(interpolation) 기능과 비슷합니다. 마음대로, 문자열 구성을 사용자 정의하고 인젝션 공격을 피하거나 문자열 콘텐츠로 더 고레벨 데이터 구조를 구성하기 위한 태그가 추가될 수 있습니다.

+ +
// 기본적인 문자열 리터럴 생성
+`In JavaScript '\n' is a line-feed.`
+
+// 여러 줄 문자열
+`In JavaScript this is
+ not legal.`
+
+// 문자열 삽입
+var name = "Bob", time = "today";
+`Hello ${name}, how are you ${time}?`
+
+// Construct an HTTP request prefix is used to interpret the replacements and construction
+POST`http://foo.org/bar?a=${a}&b=${b}
+     Content-Type: application/json
+     X-Credentials: ${credentials}
+     { "foo": ${foo},
+       "bar": ${bar}}`(myOnReadyStateChangeHandler);
+ +

꼭 문자열 객체를 사용할 필요가 없는 경우 문자열 리터럴을 사용해야 합니다. 문자열 객체에 대해 자세한 사항은 {{jsxref("String")}}을 참고하세요.

+ +

문자열에서 특수 문자 사용

+ +

보통 문자에 더해서, 문자열에 아래 예제와 같이 특수 문자도 포함할 수 있습니다.

+ +
"one line \n another line"
+
+ +

다음 표는 JavaScript 문자열에 사용할 수 있는 특수 문자 목록입니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
표: JavaScript 특수 문자
문자
\0Null Byte
\bBackspace
\fForm feed
\nNew line
\rCarriage return
\tTab
\vVertical tab
\'Apostrophe 혹은 작은 따옴표
\"큰 따옴표
\\백슬래시
\XXXLatin-1 인코딩 문자는 0 - 377 사이 8진수 3자리까지 지정될 수 있습니다. 예를 들어, \251은 copyright 심볼을 표현하는 8진수 시퀀스입니다.
\xXXLatin-1 인코딩 문자는 00 - FF 사이의 16진수 2자리로 지정될 수 있습니다. 예를 들어, \xA9는 copyright 심볼을 표현하는 16진수 시퀀스입니다.
\uXXXX유니코드 문자는 16진수 4자리로 지정될 수 있습니다. 예를 들어, \u00A9는 copyright 심볼을 표현하는 유니코드 열입니다. Unicode escape sequences를 참고하세요.
\u{XXXXX}유니코드 코드 포인트 이스케이프. 예를 들어, \u{2F804}는 간단한 유니코드 이스케이프 \uD87E\uDC04와 같습니다.
+ +

문자 이스케이프

+ +

표에 없는 문자의 경우 전행 백슬래시는 무시되지만, 이 용법은 더 이상 사용되지 않으며, 사용을 피해야 합니다.

+ +

전행 백슬래시와 함께 문자열 안에 따옴표를 사용할 수 있습니다. 이것을 따옴표 이스케이프라고 합니다. 예를 들어,

+ +
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
+console.log(quote);
+
+ +

이 코드의 결과는,

+ +
He read "The Cremation of Sam McGee" by R.W. Service.
+
+ +

백슬래시를 문자열 내에 포함시키기 위해서는, 백슬래시 문자를 이스케이프 해야 합니다. 예를 들어, 파일 경로 c:\temp를 문자열에 할당하기 위해서는 아래와 같이 사용합니다.

+ +
var home = "c:\\temp";
+
+ +

또한 줄바꿈 역시 전행 백슬래시로 이스케이프할 수 있습니다. 백슬래시와 줄바꿈 모두 문자열 값에서는 사라집니다.

+ +
var str = "this string \
+is broken \
+across multiple\
+lines."
+console.log(str);   // this string is broken across multiplelines.
+
+ +

JavaScript에는 "heredoc" 구문은 없지만, 줄바꿈 이스케이프와 각 줄 끝 이스케이프된 줄바꿈을 추가하여 흉내낼 수 있습니다.

+ +
var poem =
+"Roses are red,\n\
+Violets are blue.\n\
+I'm schizophrenic,\n\
+And so am I."
+
+ +

ECMAScript 2015에서는 템플릿 리터럴(template literals)이라는 새로운 리터럴이 소개되었습니다. 이 것은 다중 문자열을 포함한 많은 새로운 기능을 가지고 있습니다!

+ +
var poem =
+`Roses are red,
+Violets are blue.
+Sugar is sweet,
+and so is foo.`
+
+ +

추가 정보

+ +

이 장은 선언과 형에 대한 기본 구문에 초점을 맞춥니다. JavaScript 언어 구조에 대해 더 많이 배우려면, 다음 장을 참고하세요.

+ + + +

다음 장에서는, 흐름 제어 구조와 오류 처리를 살핍니다.

+ +

{{PreviousNext("Web/JavaScript/Guide/소개", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git a/files/ko/web/javascript/guide/inheritance_and_the_prototype_chain/index.html b/files/ko/web/javascript/guide/inheritance_and_the_prototype_chain/index.html deleted file mode 100644 index e05bab3102..0000000000 --- a/files/ko/web/javascript/guide/inheritance_and_the_prototype_chain/index.html +++ /dev/null @@ -1,531 +0,0 @@ ---- -title: 상속과 프로토타입 -slug: Web/JavaScript/Guide/Inheritance_and_the_prototype_chain -tags: - - JavaScript - - 객체지향 - - 상속 - - 중급 -translation_of: Web/JavaScript/Inheritance_and_the_prototype_chain ---- -

{{jsSidebar("Advanced")}}

- -

Java 나 C++ 같이 클래스 기반의 언어를 사용하던 프로그래머는 자바스크립트가 동적인 언어라는 점과 클래스가 없다는 것에서 혼란스러워 한다. (ES2015부터 class 키워드를 지원하기 시작했으나, 문법적인 양념일 뿐이며 자바스크립트는 여전히 프로토타입 기반의 언어다.)

- -

상속 관점에서 자바스크립트의 유일한 생성자는 객체뿐이다. 각각의 객체는 [[Prototype]]이라는 은닉(private) 속성을 가지는데 자신의 프로토타입이 되는 다른 객체를 가리킨다. 그 객체의 프로토타입 또한 프로토타입을 가지고 있고 이것이 반복되다, 결국 null을 프로토타입으로 가지는 오브젝트에서 끝난다. null은 더 이상의 프로토타입이 없다고 정의되며, 프로토타입 체인의 종점 역할을 한다.

- -

종종 이러한 점이 자바스크립트의 약점이라고 지적되지만, 프로토타입적 상속 모델은 사실 고전적인 방법보다 좀 더 강력한 방법이다. 그 말은, 예를 들자면, 프로토타입적 모델에서 고전적인 방식을 구현하는 건 꽤나 사소한 일이지만, 그 반대는 훨씬 더 어려운 일이기 때문이다.

- -

프로토타입 체인을 이용한 상속

- -

속성 상속

- -

자바스크립트 객체는 속성을 저장하는 동적인 "가방"과 (자기만의 속성이라고 부른다) 프로토타입 객체에 대한 링크를 가진다. 객체의 어떤 속성에 접근하려할 때 그 객체 자체 속성 뿐만 아니라 객체의 프로토타입, 그 프로토타입의 프로토타입 등 프로토타입 체인의 종단에 이를 때까지 그 속성을 탐색한다.

- -
ECMAScript 표준은 someObject.[[Prototype]]을 객체 someObject의 프로토타입을 지시하도록 명시하였다. ECMAScript 2015부터 [[Prototype]]에 조상 {{jsxref("Object.getPrototypeOf()")}}과 {{jsxref("Object.setPrototypeOf()")}}을 이용하여 접근하기 때문이다. 이것은 자바스크립트의 표준은 아니나 많은 브라우저에 구현되어 사실상의 표준이 된 속성 __proto__과 동일하다.
- -

아래 코드에는 어떤 속성에 접근 하려할 때 일어나는 상황이다.

- -
// o라는 객체가 있고, 속성 'a' 와 'b'를 갖고 있다고 하자.
-let f = function () {
-    this.a = 1;
-    this.b = 2;
-}
-let o = new f(); // {a: 1, b: 2}
-
-// f 함수의 prototype 속성 값들을 추가 하자.
-f.prototype.b = 3;
-f.prototype.c = 4;
-
-// f.prototype = {b: 3, c: 4}; 라고 하지 마라, 해당 코드는 prototype chain 을 망가뜨린다.
-// o.[[Prototype]]은 속성 'b'와 'c'를 가지고 있다.
-// o.[[Prototype]].[[Prototype]] 은 Object.prototype 이다.
-// 마지막으로 o.[[Prototype]].[[Prototype]].[[Prototype]]은 null이다.
-// null은 프로토타입의 종단을 말하며 정의에 의해서 추가 [[Prototype]]은 없다.
-// {a: 1, b: 2} ---> {b: 3, c: 4} ---> Object.prototype ---> null
-
-console.log(o.a); // 1
-// o는 'a'라는 속성을 가지는가? 그렇다. 속성의 값은 1이다.
-
-console.log(o.b); // 2
-// o는 'b'라는 속성을 가지는가? 그렇다. 속성의 값은 2이다.
-// 프로토타입 역시 'b'라는 속성을 가지지만 이 값은 쓰이지 않는다. 이것을 "속성의 가려짐(property shadowing)" 이라고 부른다.
-
-console.log(o.c); // 4
-// o는 'c'라는 속성을 가지는가? 아니다. 프로토타입을 확인해보자.
-// o.[[Prototype]]은 'c'라는 속성을 가지는가? 가지고 값은 4이다.
-
-console.log(o.d); // undefined
-// o는 'd'라는 속성을 가지는가? 아니다. 프로토타입을 확인해보자.
-// o.[[Prototype]]은 'd'라는 속성을 가지는가? 아니다. 다시 프로토타입을 확인해보자.
-// o.[[Prototype]].[[Prototype]]은 null이다. 찾는 것을 그만두자.
-// 속성이 발견되지 않았기 때문에 undefined를 반환한다.
-
- -

객체의 속성에 값을 지정하면 "자기만의 속성"이 생긴다.  단, getter or a setter가 적용되는 속성이 상속되는 경우 예외적인 규칙이 적용된다.

- -

메소드 상속

- -

자바스크립트에 "메소드"라는건 없다. 하지만 자바스크립트는 객체의 속성으로 함수를 지정할 수 있고 속성 값을 사용하듯 쓸 수 있다. 속성 값으로 지정한 함수의 상속 역시 위에서 본 속성의 상속과 동일하다. (단 위에서 언급한 "속성의 가려짐" 대신 "메소드 오버라이딩, method overriding" 라는 용어를 사용한다)

- -

상속된 함수가 실행 될 때,  this 라는 변수는 상속된 오브젝트를 가르킨다. 그 함수가 프로토타입의 속성으로 지정되었다고 해도 말이다.

- -
var o = {
-  a: 2,
-  m: function(b){
-    return this.a + 1;
-  }
-};
-
-console.log(o.m()); // 3
-// o.m을 호출하면 'this' 는 o를 가리킨다.
-
-var p = Object.create(o);
-// p 는 프로토타입을 o로 가지는 오브젝트이다.
-
-p.a = 12; // p 에 'a'라는 새로운 속성을 만들었다.
-console.log(p.m()); // 13
-// p.m이 호출 될 때 'this' 는 'p'를 가리킨다.
-// 따라서 o의 함수 m을 상속 받으며,
-// 'this.a'는 p.a를 나타내며 p의 개인 속성 'a'가 된다.
-
- -

Javascript 에서 프로토타입을 사용하는 방법

- -

뒤에서 일어나는 일을 좀 더 자세히 파헤쳐보자.

- -

위에서 언급했듯이, 자바스크립트에서 함수는 속성을 가질 수 있다. 모든 함수에는 prototype이라는 특수한 속성이 있다. 아래의 예제 코드는 독립적이라는 것에 유의하자. (아래의 코드 이외에는 웹페이지에 다른 자바스크립트가 없다고 가정하는 것이 좋다.)

- -

최적의 실습을 위해서 콘솔을 열고 "Console" 탭으로 이동하여 아래의 JavaScript 코드를 복사하여 붙여넣은 다음 , 엔터키를 눌러 실행할 것을 적극 권한다. (콘솔은 대부분 웹 브라우저의 Developer Tools에 포함되어있다. 자세한 내용은 Firefox Developer ToolsChrome DevTools, Edge DevTools 에서 확인할 수 있다. )

- -
- -
function doSomething(){}
-console.log( doSomething.prototype );
-// It does not matter how you declare the function, a
-//  function in JavaScript will always have a default
-//  prototype property.
-var doSomething = function(){};
-console.log( doSomething.prototype );
- -

위 내용을 토대로, 콘솔을 보면  doSomething() 은 기본 prototype 속성을 가진다. 코드를 실행한 뒤에 콘솔에서는 다음과 유사한 형태의 객체가 표시되어야한다.

- -
{
-    constructor: ƒ doSomething(),
-    __proto__: {
-        constructor: ƒ Object(),
-        hasOwnProperty: ƒ hasOwnProperty(),
-        isPrototypeOf: ƒ isPrototypeOf(),
-        propertyIsEnumerable: ƒ propertyIsEnumerable(),
-        toLocaleString: ƒ toLocaleString(),
-        toString: ƒ toString(),
-        valueOf: ƒ valueOf()
-    }
-}
- -

우리는 아래에 보이는 것과 같이 doSomething() 프로토타입에 속성을 추가할 수 있다.

- -
function doSomething(){}
-doSomething.prototype.foo = "bar";
-console.log( doSomething.prototype );
- -

결과:

- -
{
-    foo: "bar",
-    constructor: ƒ doSomething(),
-    __proto__: {
-        constructor: ƒ Object(),
-        hasOwnProperty: ƒ hasOwnProperty(),
-        isPrototypeOf: ƒ isPrototypeOf(),
-        propertyIsEnumerable: ƒ propertyIsEnumerable(),
-        toLocaleString: ƒ toLocaleString(),
-        toString: ƒ toString(),
-        valueOf: ƒ valueOf()
-    }
-}
-
- -

이제 new 연산자를 사용해서 프로토타입 기반의 doSomething() 인스턴스를 생성할 수 있다. new 연산자를 사용하려면 함수 호출 형식에 new 접두사를 붙이기만하면 된다. new 연산자로 함수를 호출하면 해당 함수의 인스턴스 객체를 반환받는다. 그러면 속성들을 이 객체에 추가할 수 있다.

- -

다음의 코드를 실행해보자.

- -
function doSomething(){}
-doSomething.prototype.foo = "bar"; // add a property onto the prototype
-var doSomeInstancing = new doSomething();
-doSomeInstancing.prop = "some value"; // add a property onto the object
-console.log( doSomeInstancing );
- -

실행하고나면 결과는 다음과 비슷할 것이다.

- -
{
-    prop: "some value",
-    __proto__: {
-        foo: "bar",
-        constructor: ƒ doSomething(),
-        __proto__: {
-            constructor: ƒ Object(),
-            hasOwnProperty: ƒ hasOwnProperty(),
-            isPrototypeOf: ƒ isPrototypeOf(),
-            propertyIsEnumerable: ƒ propertyIsEnumerable(),
-            toLocaleString: ƒ toLocaleString(),
-            toString: ƒ toString(),
-            valueOf: ƒ valueOf()
-        }
-    }
-}
-
- -

위에서 본 것과 같이, doSomeInstancing 객체의 __proto__ 는 doSomething.prototype 이다.
- 그래서 도대체 __proto__는 무엇을 하는것인지 알아보자.
- 우리가 doSomeInstancing의 속성에 접근할때 브라우저는 우선 doSomeInstancing이 그 속성을 갖고있는지 확인한다.
- 만약 doSomeInstancing이 속성을 갖고있지 않다면, 브라우저는 doSomeInstancing의 __proto__(doSomething.prototype)가 그 속성을 갖고있는지 확인한다.
- 만약 doSomeInstancing의 __proto__가 브라우저가 찾던 속성을 갖고 있다면, doSomething의 __proto__가 갖고있는 그 속성을 사용한다.

- -

그렇지 않고, doSomeInstancing의 __proto__가 그 속성을 갖고있지 않을때에는
- doSomeInstancing의 __proto__의 __proto__가 그 속성을 갖는지 확인한다.
- 기본적으로, 어떠한 함수던지 그 함수의 prototype 속성의 __proto__는 window.Object.prototype이다.
- 그러므로 브라우저는 doSomeInstancing의 __proto__의 __proto__(doSomething.prototype의 __proto__(다시말해, Object.prototype))  에서 그 속성을 찾아본다.
- 만약 그 속성을 doSomeInstancing의 __proto__의 __proto__에서 찾을 수 없다면 그다음엔 doSomeInstancing의 __proto__의 __proto__의 __proto__에서 찾을것이다.
- 하지만 여기서 문제가 발생한다.
- doSomeInstancing의 __proto__의 __proto__의 __proto__는 존재할 수 없다(window.Object.prototype의 __proto__는 null이기 때문).
- 그제서야, 오직 모든 프로토타입 체인이 검사 되고 브라우저가 더이상  검사할 __proto__가 없을때에서야 브라우저는 우리가 찾던 값이 undefined라고 결론짓는다.

- -

콘솔에 코드를 조금 더 추가해보자.

- -
function doSomething(){}
-doSomething.prototype.foo = "bar";
-var doSomeInstancing = new doSomething();
-doSomeInstancing.prop = "some value";
-console.log("doSomeInstancing.prop:      " + doSomeInstancing.prop);
-console.log("doSomeInstancing.foo:       " + doSomeInstancing.foo);
-console.log("doSomething.prop:           " + doSomething.prop);
-console.log("doSomething.foo:            " + doSomething.foo);
-console.log("doSomething.prototype.prop: " + doSomething.prototype.prop);
-console.log("doSomething.prototype.foo:  " + doSomething.prototype.foo);
-
- -

이 코드의 결과는 아래와 같다.

- -
doSomeInstancing.prop:      some value
-doSomeInstancing.foo:       bar
-doSomething.prop:           undefined
-doSomething.foo:            undefined
-doSomething.prototype.prop: undefined
-doSomething.prototype.foo:  bar
-
- -

객체를 생성하는 여러 방법과 프로토타입 체인 결과

- -

문법 생성자로 객체 생성

- -
var o = {a: 1};
-
-// o 객체는 프로토타입으로 Object.prototype 을 가진다.
-// 이로 인해 o.hasOwnProperty('a') 같은 코드를 사용할 수 있다.
-// hasOwnProperty 라는 속성은 Object.prototype 의 속성이다.
-// Object.prototype 의 프로토타입은 null 이다.
-// o ---> Object.prototype ---> null
-
-var a = ["yo", "whadup", "?"];
-
-// Array.prototype을 상속받은 배열도 마찬가지다.
-// (이번에는 indexOf, forEach 등의 메소드를 가진다)
-// 프로토타입 체인은 다음과 같다.
-// a ---> Array.prototype ---> Object.prototype ---> null
-
-function f(){
-  return 2;
-}
-
-// 함수는 Function.prototype 을 상속받는다.
-// (이 프로토타입은 call, bind 같은 메소드를 가진다)
-// f ---> Function.prototype ---> Object.prototype ---> null
-
- -

생성자를 이용

- -

자바스크립트에서 생성자는 단지 new 연산자를  사용해 함수를 호출하면 된다.

- -
function Graph() {
-  this.vertexes = [];
-  this.edges = [];
-}
-
-Graph.prototype = {
-  addVertex: function(v){
-    this.vertexes.push(v);
-  }
-};
-
-var g = new Graph();
-// g 'vertexes' 와 'edges'를 속성으로 가지는 객체이다.
-// 생성시 g.[[Prototype]]은 Graph.prototype의 값과 같은 값을 가진다.
-
- -

Object.create 이용

- -

ECMAScript 5는 새로운 방법을 도입했다. Object.create라는 메소드를 호출하여 새로운 객체를 만들 수 있다. 생성된 객체의 프로토타입은 이 메소드의 첫 번째 인수로 지정된다.

- -
var a = {a: 1};
-// a ---> Object.prototype ---> null
-
-var b = Object.create(a);
-// b ---> a ---> Object.prototype ---> null
-console.log(b.a); // 1 (상속됨)
-
-var c = Object.create(b);
-// c ---> b ---> a ---> Object.prototype ---> null
-
-var d = Object.create(null);
-// d ---> null
-console.log(d.hasOwnProperty); // undefined이다. 왜냐하면 d는 Object.prototype을 상속받지 않기 때문이다.
-
- -
-

class 키워드 이용

- -

ECMAScript2015에는 몇 가지 키워드가 도입되어 class를 구현하였다. 이런 생성 방식은 클래서 기반 언어의 개발자들에게 친숙하게 다가오나 동작 방식이 같지는 않다. 자바스크립트는 여전히 프로토타입 기반으로 남아있다. 새로 도입된 키워드는 {{jsxref("Statements/class", "class")}}, {{jsxref("Classes/constructor", "constructor")}}, {{jsxref("Classes/static", "static")}}, {{jsxref("Classes/extends", "extends")}}, 그리고 {{jsxref("Operators/super", "super")}}가 있다.

- -
'use strict';
-
-class Polygon {
-  constructor(height, width) {
-    this.height = height;
-    this.width = width;
-  }
-}
-
-class Square extends Polygon {
-  constructor(sideLength) {
-    super(sideLength, sideLength);
-  }
-  get area() {
-    return this.height * this.width;
-  }
-  set sideLength(newLength) {
-    this.height = newLength;
-    this.width = newLength;
-  }
-}
-
-var square = new Square(2);
-
- -

성능

- -

프로토타입 체인에 걸친 속성 검색으로 성능에 나쁜 영향을 줄 수 있으며, 때때로 치명적일 수 있다. 또한 존재하지도 않는 속성에 접근하려는 시도는 항상 모든 프로토타입 체인인 전체를 탐색해서 확인하게 만든다.

- -

객체의 속성에 걸쳐 루프를 수행 하는 경우 프로토타입 체인 전체의 모든 열거자 속성에 대하여 적용된다. 객체 개인 속성인지 프로토타입 체인상 어딘가에 있는지 확인하기 위해서는 Object.prototype에서 모든 오브젝트로 상속된 hasOwnProperty 메소드를 이용할 필요가 있다. 다음 코드를 통하여 구체적인 예를 확인하여 보자.

- -
console.log(g.hasOwnProperty('vertices'));
-// true
-
-console.log(g.hasOwnProperty('nope'));
-// false
-
-console.log(g.hasOwnProperty('addVertex'));
-// false
-
-console.log(g.__proto__.hasOwnProperty('addVertex'));
-// true
-
- -

hasOwnProperty 메소드만이 속성을 확인하고 프로토타입 체인 전체를 훑지 않게 할 수 있다.

- -

참고: undefined인지 여부만 확인하는 것으로는 충분하지 않다. 여전히 속성이 존재할 수도 있는데 단지 그 값에 undefined가 할당되어 있을 수도 있기 때문이다.

- -

좋지 않은 사례: 기본 프로타입의 확장 변형

- -

Object.prototype 혹은 빌트인 프로토타입의 확장은 종종 이용되지만 오용이다.

- -

이 기법은 Monkey patching으로 불리며 캡슐화를 망가뜨린다. Prototype.js와 같은 유명한 프레임워크에서도 사용되지만, 빌트인 타입에 비표준 기능을 추가하는 것은 좋은 생각이 아니다.

- -

유일하게 좋은 사용 예라면, 새로운 자바스크립트 엔진에 Array.forEach등의 새로운 기능을 추가하면서 빌트인 프로토타입을 확장하는 것 정도다. 

- -

- -

B는 A를 상속한다:

- -
function A(a) {
-  this.varA = a;
-}
-
-// A의 정의에서 this.varA는 항상 A.prototype.varA가 가려버리는데
-// prototype에 varA를 다시 넣는 이유는 무엇인가?
-A.prototype = {
-  varA: null,  // 아무것도 안하면서 varA를 쓰는 이유가 있을까?
-      // 아마도 숨겨진 클래스의 할당 구조를 최적화 하려는 것인가?
-      // https://developers.google.com/speed/articles/optimizing-javascript#Initializing-instance-variables
-      // 모든 객체의 varA가 동일하게 초기화 되어야 상기 링크 내용이 유효할 수 있다.
-  doSomething: function() {
-    // ...
-  }
-};
-
-function B(a, b) {
-  A.call(this, a);
-  this.varB = b;
-}
-B.prototype = Object.create(A.prototype, {
-  varB: {
-    value: null,
-    enumerable: true,
-    configurable: true,
-    writable: true
-  },
-  doSomething: {
-    value: function() { // override
-      A.prototype.doSomething.apply(this, arguments); // call super
-      // ...
-    },
-    enumerable: true,
-    configurable: true,
-    writable: true
-  }
-});
-B.prototype.constructor = B;
-
-var b = new B();
-b.doSomething();
-
- -

중요한 점은:

- -
    -
  • .prototype에 타입이 정의되어 있다.
  • -
  • Object.create()을 이용하여 상속한다.
  • -
- -

prototype 그리고 Object.getPrototypeOf

- -

Java나 C++에 익숙한 개발자는 클래스라는 것도 없고, 모든 것이 동적이고 실행 시 결정되는 자바스크립트의 특징 때문에 어려움을 겪을 수도 있다. 모든 것은 객체이고, 심지의 "class"를 흉내내는 방식도 단지 함수 오브젝트를 이용하는 것 뿐이다.

- -

이미 알아챘겠지만 우리의 함수 A도 특별한 속성 prototype를 가지고 있다. 이 특별한 속성은 자바스크립트의 new 연산자와 함께 쓰인다. 프로토타입 객체는 새로 만들어진 인스턴스의 내부 [[Prototype]] 속성에 복사되어 참조된다. 가령, var a1 = new A()를 수행할 때, this를 포함하고 있는 함수을 수행하기 전, 메모리에 새로 생성된 객체를 생성한 직후 자바스크립트는 a1.[[Prototype]] = A.prototype를 수행한다. 그 인스턴스의 속성에 접근하려 할 때 자바스크립트는 그 객체의 개인 속성인지 우선 확인하고 그렇지 않은 경우에 [[Prototype]]에서 찾는다. 이것은 prototype에 정의한 모든 것은 모든 인스턴스가 효과적으로 공유한다는 뜻이며, 심지어 프로토타입의 일부를 나중에 변경하다고 해도 이미 생성되어 있는 인스턴스는 필요한 경우 그 변경 사항에 접근할 수 있다.

- -

위의 예에서, 만일 var a1 = new A(); var a2 = new A(); 그 후 a1.doSomethingObject.getPrototypeOf(a1).doSomething를 가리키게 되는 것은A.prototype.doSomething으로 정의한 것과 같게 된다. 즉, Object.getPrototypeOf(a1).doSomething == Object.getPrototypeOf(a2).doSomething == A.prototype.doSomething.

- -

요약 하자면, prototype은 타입 정의를 위한 것이고, Object.getPrototypeOf()는 모든 인스턴스가 공유한다.

- -

[[Prototype]]은 재귀적으로 탐색된다. 즉, a1.doSomething, Object.getPrototypeOf(a1).doSomething,Object.getPrototypeOf(Object.getPrototypeOf(a1)).doSomething 등등, 이미 발견했거나 Object.getPrototypeOfnull을 반환할 때까지 반복된다.

- -

따라서 다음 호출에 대하여

- -
var o = new Foo();
- -

자바스크립트는 실제로 다음 작업을 수행한다.

- -
var o = new Object();
-o.[[Prototype]] = Foo.prototype;
-Foo.call(o);
- -

(혹은 그런 비슷한 작업, 내부 구현은 다를 수 있다) 그리고 나중에 다음을 수행하면

- -
o.someProp;
- -

자바스크립트는 o가 속성 someProp을 가졌는지 확인하고, 아니면 Object.getPrototypeOf(o).someProp, 또 아니면 Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp 등으로 계속 된다.

- -

프로토타입 상속의 종류

- -

프로토타입 상속에는 3가지 종류가 있다 : 위임형 상속, 연결형 상속, 함수형 상속.

- -

위임형 상속(Delegation inheritance)

- -

위임형 상속에서 프로토타입 객체는 다른 객체의 기반이 된다. 위임 프로토타입을 상속받을 경우 새 객체는 해당 프로토타입에 대한 참조를 가지고 있다.

- -

새 객체의 속성에 접근할 때, 해당 객체가 직접적으로 속성을 소유하고 있는지 먼저 체크한다. 없다면 다음 순서로 [[Prototype]]을 체크한다. 이 과정은 프로토타입 체인을 따라서 모든 객체의 프로토타입 체인의 최상위에 있는 객체인 Object.prototype에 도달할 때 까지 반복된다.

- -

메소드를 위임 상속할 경우 모든 객체가 각 메소드에에 대해 하나의 코드를 공유하므로 메모리를 절약할 수 있다.

- -

Javascript에서 이를 구현하는 방법은 여러가지가 있는데 ES6에서는 아래와 같은 방식이 흔하다:

- -
class Greeter {
-  constructor (name) {
-    this.name = name || 'John Doe';
-  }
-  hello () {
-    return `Hello, my name is ${ this.name }`;
-  }
-}
-
-const george = new Greeter('George');
-const msg = george.hello();
-console.log(msg); // Hello, my name is George
-
- -

Object.create(null). 을 통해 프로토타입을 {{jsxref("null")}}로 지정하여 속성 위임 없이 객체를 생성할 수 있다..

- -

이 방법의 큰 단점 중 하나는 상태를 저장하는데 그리 좋은 방법이 아니라는 것이다. 객체나 배열의 상태를 변경하게 되면 같은 프로토타입을 공유하는 모든 객체의 상태가 변경된다.

- -

상태 변경이 전파되는 것을 막으려면 각 객체마다 상태 값의 복사본을 만들어야 한다.

- -

연결형 상속(Concatenative inheritance)

- -

연결형 상속은 한 객체의 속성을 다른 객체에 모두 복사함으로써 상속을 구현하는 방법이다.

- -

이 상속법은 Javascript 객체의 동적 확장성을 이용한 방법이다. 객체 복사는 속성의 초기값을 저장하기 위한 좋은 방법이다: 이 방식은 {{jsxref("Object.assign()")}}을 통해 구현하는 것이 보통이며 ES6 이전에 Lodash, Underscore, jQuery등의 라이브러리들이 .extend() 와 비슷한 메소드로 제공한 방법이다.

- -
const proto = {
-  hello: function hello() {
-    return `Hello, my name is ${ this.name }`;
-  }
-};
-
-const george = Object.assign({}, proto, {name: 'George'});
-const msg = george.hello();
-console.log(msg); // Hello, my name is George
-
- -

연결형 상속은 매우 좋은 방법이며 클로져와 같이 사용한다면 훨씬 효과적인 상속 방식입니다..

- -

함수형 상속(Functional inheritance)

- -

함수형 상속(Functional inheritance)이라는 단어는 Douglas Crockford가 자신의 저서 “JavaScript: The Good Parts”에서 창조한 단어이다. 이 방법은 새 속성들을 연결형 상속으로 쌓되 상속 기능을 Factory 함수로 만들어 사용하는 방식이다.

- -

기존의 객체를 확장하는데 쓰이는 함수를 일반적으로 믹스인 함수라 칭한다. 객체 확장에 함수를 사용하는 가장 큰 이점은 Private Data를 클로져를 통해 캡슐화 시킬 수 있다는 점이다.

- -

다르게 말하자면 Private 상태를 지정할 수 있다는 의미이다.

- -

특정 함수를 통할 필요 없이 public 접근이 가능한 속성에 대해 접근 제한을 거는 것은 문제가 있다. 따라서 private 클로져에 속성 값을 숨겨야 하며 이는 아래와 같이 구현한다:

- -
// import Events from 'eventemitter3';
-
-const rawMixin = function () {
-  const attrs = {};
-  return Object.assign(this, {
-    set (name, value) {
-      attrs[name] = value;
-      this.emit('change', {
-        prop: name,
-        value: value
-      });
-    },
-    get (name) {
-      return attrs[name];
-    }
-  }, Events.prototype);
-};
-
-const mixinModel = (target) => rawMixin.call(target);
-const george = { name: 'george' };
-const model = mixinModel(george);
-model.on('change', data => console.log(data));
-model.set('name', 'Sam');
-/*
-{
-  prop: 'name',
-  value: 'Sam'
-}
-*/
-
- -

attrs 을 public 속성에서 private 영역으로 옮겨서 public API를 통한 접근을 차단할 수 있다. // 접근할 수 있는 유일한 방법은 Privileged 메소드 뿐이다. Privileged 메소드는 클로져 영역에 정의된 함수로 private data에 접근 가능한 함수들을 일컫는다.

- -

위 예제를 보면 믹스인 함수 rawMixin().에 대한 래퍼로 mixinModel() 을 선언한 것을 알 수 있다. 이는 예제에서 {{jsxref("Function.prototype.call()")}} 을 사용했듯이 함수 내에서 this의 값을 설정해야 하기 때문이다. Wrapper를 생략하고 호출자가 알아서 하도록 놔둘 수 있지만 그럴 경우 혼동될 가능성이 있다.

- -
-

결론

- -

복잡한 코드를 작성하여 이용하기 전에 프로토타입 기반의 상속 모델을 이해하는 것이 중요하다. 또한 프로토타입 체인의 길이는 성능을 저해하지 않도록 줄이는 방법을 고안해야 한다. 또한 빌트인 프로토타입은 새로운 자바스크립트 기능과 호환성을 갖기 위한 이유가 아닌 이상 절대 확장해서는 안된다.

-
-
diff --git a/files/ko/web/javascript/guide/introduction/index.html b/files/ko/web/javascript/guide/introduction/index.html new file mode 100644 index 0000000000..cac0779ee0 --- /dev/null +++ b/files/ko/web/javascript/guide/introduction/index.html @@ -0,0 +1,153 @@ +--- +title: Introduction +slug: Web/JavaScript/Guide/소개 +tags: + - JavaScript + - 가이드 + - 안내서 + - 자바스크립트 +translation_of: Web/JavaScript/Guide/Introduction +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}
+ +

이 장은 JavaScript를 소개하고 그 일부 기초 개념을 다룹니다.

+ +

무엇을 미리 알고 있어야 하나요?

+ +

이 안내서는 당신이 다음의 기본적인 배경지식이 있다고 가정합니다.

+ +
    +
  • 인터넷과 월드 와이드 웹({{Glossary("WWW")}})에 대한 전반적인 이해.
  • +
  • HyperText 마크업 언어({{Glossary("HTML")}})에 대한 괜찮은 실무 지식.
  • +
  • 약간의 프로그래밍 경험. 만약 프로그래밍이 처음이라면, JavaScript 메인 페이지에 링크된 tutorial 중 하나를 따라하세요.
  • +
+ +

어디서 JavaScript 정보를 찾을 수 있을까

+ +

MDN에 있는 JavaScript 문서는 다음 세가지 파트로 되어있습니다.

+ +
    +
  • Learning the Web은 입문자를 위한 정보를 제공하며, 프로그래밍과 인터넷에 대한 기본 개념을 소개합니다.
  • +
  • JavaScript Guide (이 안내서)는 JavaScript 언어와 객체에 대한 개요를 제공합니다.
  • +
  • JavaScript Reference JavaScript에 관련된 자세한 참고 자료를 제공합니다.
  • +
+ +

JavaScript가 처음이라면, learning areaJavaScript Guide에 있는 문서를 먼저 보세요. 일단 기초를 확실히 파악한 후에는, 각 객체와 문(statement)에 대한 더 자세한 정보를 JavaScript Reference에서 확인할 수 있습니다.

+ +

JavaScript는 무엇인가?

+ +

JavaScript는 크로스-플랫폼, 객체지향 스크립트 언어입니다. 작고 가벼운 언어입니다. 호스트 환경(가령, 웹 브라우저) 내에서, JavaScript는 프로그램 제어를 제공하기 위해 그 환경의 객체에 연결될 수 있습니다. Node.Js와 같은 자바 스크립트의 고급 서버언어로 사용 할 수도 있습니다.이것을 사용하면 단순히 파일을 다운로드하는 것 (예 : 여러 컴퓨터 간의 실시간 공동 작업)보다 웹 사이트에 더 많은 기능을 추가 할 수 있습니다. 호스트 환경 (예 : 웹 브라우저) 내에서 JavaScript는 해당 환경의 객체에 연결되어 프로그래밍 방식으로 제어 할 수 있습니다.

+ +

JavaScript는 Array, Date, Math와 같은 객체에 대한 표준 라이브러리와 연산자(operator), 제어 구조, 문과 같은 언어 요소의 코어 집합을 포함합니다. 코어 JavaScript는 거기에 추가 객체를 보충하여 다양한 목적으로 확장될 수 있습니다. 예를 들면:

+ +
    +
  • 클라이언트 측 JavaScript는 브라우저와 문서 객체 모델(DOM) 을 제어하는 객체를 제공하여 코어 언어를 확장합니다. 예를 들어, 클라이언트 측 확장은 어플리케이션이 요소(element)를 HTML 폼에 두고, 마우스 클릭, 폼 입력 및 페이지 탐색 같은 사용자 이벤트에 응답하게 해줍니다.
  • +
  • 서버 측 JavaScript는 서버에서 JavaScript 실행에 관련된 객체를 제공하여 코어 언어를 확장합니다. 예를 들어, 서버 측 확장은 어플리케이션이 데이터베이스와 통신하고, 한 번의 호출 정보의 연속성을 어플리케이션의 다른 곳에 제공하거나, 서버에서 파일 조작을 수행할 수 있도록 해줍니다.
  • +
+ +

이것은 브라우저에서 JavaScript가 웹 페이지 (DOM)의 모양을 바꿀 수 있음을 의미합니다. 또한 서버의 Node.js JavaScript는 브라우저에 작성된 코드의 사용자 정의 요청에 응답 할 수 있습니다.

+ +

JavaScript 와 Java

+ +

JavaScript 와 Java는 여러 면에서 비슷하지만 어떤 면에서는 근본적으로 다릅니다. JavaScript 언어는 Java를 닮았지만 Java의 정적 형지정(static typing)과 강한 형 검사(strong type checking)가 없습니다. JavaScript는 대부분의 Java 식 구문, 명명 규칙 및 기본적인 흐름 제어 구조를 따릅니다. 그것이 LiveScript에서 JavaScript로 이름이 바뀐 이유였습니다.

+ +

Java의 선언에 의해 생성되는 클래스의 컴파일-타임 시스템과는 달리, JavaScript는 숫자, 불리언, 그리고 문자열 값을 표현하는 적은 수의 자료 형을 기반으로 한 런타임 시스템을 지원합니다. JavaScript 는 더 일반적인 클래스 기반 객체 모델 대신에 프로토타입 기반 객체 모델을 갖습니다. 프로토타입 기반 모델은 동적 상속을 제공합니다. 즉, 상속된 대상은 각각의 객체에 따라 다양할 수 있습니다. JavaScript는 또한 어떤 특정한 선언을 요구하지 않는 함수도 지원합니다. 함수는 객체의 속성이나, 타입이 느슨하게 형지정된 채 실행되는 메소드가 될 수 있습니다.

+ +

JavaScript는 Java에 비해 매우 자유로운 형태의 언어입니다. 여러분은 모든 변수, 클래스, 및 메소드를 선언하지 않아도 됩니다. 여러분은 메소드가 public, private, 또는 protected 인지 염려할 필요가 없고 인터페이스를 구현하지 않아도 됩니다. 변수, 매개변수(parameter), 및 함수의 반환 형은 명시적으로 지정되지 않습니다.

+ +

Java는 빠른 실행과 형 안전성(type safety)을 위해 설계된 클래스 기반 프로그래밍 언어입니다. 형 안전성은, 예를 들어, 여러분이 Java 정수를 객체의 레퍼런스로 형변환(cast)하거나 Java 바이트코드를 변경하여 private 메모리에 접근할 수 없음을 의미합니다. Java의 클래스 기반 모델은 프로그램이 오로지 클래스와 그 메소드로만 구성된다는 것을 뜻합니다. Java의 클래스 상속과 강한 형지정은 보통 단단하게 결합된 객체 계층구조를 요구합니다. 이러한 요구는 Java 프로그래밍을 JavaScript 프로그래밍보다 더 복잡하게 만듭니다.

+ +

반면에, JavaScript는 HyperTalk 과 dBASE 같은 더 작고 동적 형지정이 가능한 언어들의 정신을 계승했습니다. 이러한 스크립팅 언어는 더 쉬운 구문과 특별한 내장(built-in) 기능 및 객체 생성을 위한 최소 요구사항으로 인해 훨씬 더 많은 사람들에게 프로그래밍 도구를 제공합니다.

+ + + + + + + + + + + + + + + + + + + + + + + +
Java와 비교한 JavaScript
JavaScriptJava
객체 지향. 객체의 형 간에 차이 없음. 프로토타입 메커니즘을 통한 상속, 그리고 속성과 메서드는 어떤 객체든 동적으로 추가될 수 있음.클래스 기반. 객체는 클래스 계층구조를 통한 모든 상속과 함께 클래스와 인스턴스로 나뉨. 클래스와 인스턴스는 동적으로 추가된 속성이나 메소드를 가질 수 없음.
변수 자료형이 선언되지 않음(dynamic typing, loosely typed).변수 자료형은 반드시 선언되어야 함(정적 형지정, static typing).
하드 디스크에 자동으로 작성 불가.하드 디스크에 자동으로 작성 가능.
+ +

JavaScript와 Java의 차이에 대한 더 많은 정보는, 객체 모델의 세부사항 장을 보세요.

+ +

JavaScript 와 ECMAScript 명세

+ +

JavaScript는 JavaScript에 기반한 표준화된 국제 프로그래밍 언어를 제공하기 위해Ecma International 에서 표준화 됩니다 — European association for standardizing information and communication systems (ECMA는 이전에 European Computer Manufacturers Association의 두문자어였습니다). ECMAScript라 불리는 이 JavaScript의 표준화 버전은 표준을 지원하는 모든 어플리케이션에서 같은 방식으로 동작합니다. 회사들은 그들의 JavaScript 구현을 개발하기 위해 공개 표준 언어를 사용할 수 있습니다. ECMAScript 표준은 ECMA-262 명세(specification)에서 문서화되었습니다. JavaScript와 ECMAScript 명세 판의 여러 버전에 대한 더 많은 것을 배우려면 New in JavaScript 을 보세요.

+ +

ECMA-262 표준은 또한 IOS-16262로서 ISO (국제 표준화 기구) 에 의해 승인되었습니다. Ecma International website 에서 그 명세를 찾을 수 있습니다. ECMAScript 명세는 World Wide Web Consortium (W3C) 나  WHATWG (Web Hypertext Application Technology Working Group)에 의해 표준화된 Document Object Model (DOM)을 설명하지 않습니다. DOM은 여러분의 스크립트에 HTML 문서 객체를 드러내는 방법을 정의합니다. JavaScript로 프로그래밍을 할 때 사용되는 여러 기술들에 대한 정보를 얻으 시려면, JavaScript technologies overview 를 참고하세요.

+ +

JavaScript 문서 vs ECMAScript 명세

+ +

ECMAScript 명세는 ECMAScript 구현을 위한 요구사항의 집합입니다; 여러분이 여러분의 ECMAScript 구현이나 엔진(가령 Firefox의 SpiderMonkey, 또는 Chrome의 v8)에서 표준을 따르는 언어의 기능을 구현하길 원할 때 유용합니다.

+ +

ECMAScript 문서는 스크립트 프로그래머를 돕기 위함이 아닙니다; 스크립트 작성을 위한 정보는 JavaScript 문서를 사용하세요.

+ +

ECMAScript 명세는 JavaScript 프로그래머에게 익숙하지 않을 수 있는 용어와 문법을 사용합니다. 언어의 기술이 ECMAScript 에서 다를 수 있지만, 언어 그 자체는 같습니다. JavaScript는 ECMAScript 명세에 서술된 모든 기능을 지원합니다.

+ +

JavaScript 문서는 JavaScript 프로그래머에게 적합한 언어의 측면을 설명합니다.

+ +

JavaScript 시작하기

+ +

JavaScript 시작은 쉽습니다: 최신 웹 브라우저만 있으면 됩니다. 이 안내서는 현재 Firefox의 최신 버전에서만 사용 가능한 약간의 JavaScript 기능을 포함하므로, 가장 최신 버전의 Firefox를 사용하기를 권합니다.

+ +

JavaScript를 실험하기 유용한 두 도구가 Firefox에 내장되어 있습니다: Web Console과 Scratchpad.

+ +

웹 콘솔

+ +

웹 콘솔은 현재 로드된 페이지에 대한 정보를 보이고, 또한 여러분이 현재 페이지에서 JavaScript 식을 실행해볼 수 있는 명령어 입력줄(command line)을 제공합니다.

+ +

웹 콘솔을 열기 위해서는, Firefox의 "도구" 메뉴 하위에 있는 "개발자" 메뉴의 "웹 콘솔"을 선택(윈도우와 리눅스에서는 Ctrl+Shift+I, 맥에서는  Cmd-Option-K)합니다. 브라우저 창의 아래에 웹 콘솔이 나타납니다. 콘솔의 바닥을 따라 나온 것이 여러분이 JavaScript를 입력할 수 있는 명령어 입력줄이고, 실행 결과는 바로 위 공간에 표시됩니다:

+ +

+ +

이 콘솔은 eval과 완전히 동일하게 동작합니다:마지막 입력된 표현식이 반환되죠. 간단하게 생각해서, 콘솔에 뭔가 입력할 때마다 eval로 감싼 console.log로 둘러싸인 형태라고 보시면 됩니다.

+ +
function greetMe(yourName) { alert('Hello ' + yourName); } console.log(eval('3 + 5'));
+ +

Scratchpad

+ +

Web Console은 한 줄 JavaScript를 실행하기에 훌륭합니다. 하지만 비록 여러 줄을 실행할 수 있지만, 아주 불편하고 Web Console을 사용해 여러분의 샘플 코드를 저장할 수도 없습니다. 그러므로 좀 더 복잡한 예제를 위해서는 Scratchpad가 더 나은 도구입니다.

+ +

Scratchpad를 열기 위해, Firefox의 메뉴 "Tools" 의 하위에 있는 "Web Developer" 메뉴의 "Scratchpad" 를 선택합니다(단축키: Shift+F4). 이것은 분리된 창에서 열리고 브라우저에서 JavaScript를 작성하고 실행하기 위해 사용할 수 있는 에디터입니다. 여러분은 또한 디스크로부터 스크립트를 부르거나 저장할 수도 있습니다.

+ +

+ +

Hello world

+ +

JavaScript 작성을 시작하기 위해서, Scratchpad를 열고 첫 JavaScript 코드 "Hello World" 를 작성하세요.

+ +
(function(){
+  "use strict";
+  /* Start of your code */
+  function greetMe(yourName) {
+    alert('Hello ' + yourName);
+  }
+
+  greetMe('World');
+  /* End of your code */
+})();
+ +

패드에서 코드를 선택하고 Ctrl + R 키를 눌러 브라우저에서 펼쳐지는 것을 지켜보십시오! 다음 페이지에서 이 가이드는 JavaScript 구문 및 언어 기능을 소개하므로보다 복잡한 응용 프로그램을 작성할 수 있습니다. 그러나 당분간은 (function () { "use strict"를 코드 앞에 추가하고}}) ();를 코드마지막에 추가하세요. 아직은 이코드가 뭔지 잘 모르겠지만 나중에 이 코드가 의미하는 것을 배울 것입니다, 지금은 간단히 다음과 같다고 생각하세요.

+ +
    +
  1. 성능을 크게 개선합니다.
  2. +
  3. 초보자가 실수하게 만드는 Javascript의 일부 시맨틱을 막습니다.
  4. +
  5. 콘솔에서 실행되는 코드 스니펫이 서로 상호 작용하지 못하도록합니다 (예 : 한 콘솔 실행에서 생성 된 내용을 다른 콘솔 실행에 사용하는 경우).
  6. +
+ +

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}

diff --git a/files/ko/web/javascript/guide/meta_programming/index.html b/files/ko/web/javascript/guide/meta_programming/index.html new file mode 100644 index 0000000000..fe4fa13f83 --- /dev/null +++ b/files/ko/web/javascript/guide/meta_programming/index.html @@ -0,0 +1,258 @@ +--- +title: 메타 프로그래밍 +slug: Web/JavaScript/Guide/메타_프로그래밍 +translation_of: Web/JavaScript/Guide/Meta_programming +--- +
{{jsSidebar("JavaScript Guide")}} {{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}
+ +

Starting with ECMAScript 2015, JavaScript gains support for the {{jsxref("Proxy")}} and {{jsxref("Reflect")}} objects allowing you to intercept and define custom behavior for fundamental language operations (e.g. property lookup, assignment, enumeration, function invocation, etc). With the help of these two objects you are able to program at the meta level of JavaScript.

+ +

Proxies

+ +

 ECMAScript 6에서 소개되었습니다, {{jsxref("Proxy")}} 객체는  특정 작업을 가로막는것과  사용자 정의 행위를 시행하는것을 허용합니다.예를 들면 객체가 속성을 가지는 것입니다:

+ +
var handler = {
+  get: function(target, name){
+    return name in target ? target[name] : 42;
+  }
+};
+var p = new Proxy({}, handler);
+p.a = 1;
+console.log(p.a, p.b); // 1, 42
+
+ +

The Proxy object defines a target (an empty object here) and a handler object in which a get trap is implemented. Here, an object that is proxied will not return undefined when getting undefined properties, but will instead return the number 42.

+ +

Additional examples are available on the {{jsxref("Proxy")}} reference page.

+ +

Terminology

+ +

The following terms are used when talking about the functionality of proxies.

+ +
+
{{jsxref("Global_Objects/Proxy/handler","handler","","true")}}
+
Placeholder object which contains traps.
+
traps
+
The methods that provide property access. This is analogous to the concept of traps in operating systems.
+
target
+
Object which the proxy virtualizes. It is often used as storage backend for the proxy. Invariants (semantics that remain unchanged) regarding object non-extensibility or non-configurable properties are verified against the target.
+
invariants
+
Semantics that remain unchanged when implementing custom operations are called invariants. If you violate the invariants of a handler, a {{jsxref("TypeError")}} will be thrown.
+
+ +

Handlers and traps

+ +

The following table summarizes the available traps available to Proxy objects. See the reference pages for detailed explanations and examples.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Handler / trapInterceptionsInvariants
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}{{jsxref("Object.getPrototypeOf()")}}
+ {{jsxref("Reflect.getPrototypeOf()")}}
+ {{jsxref("Object/proto", "__proto__")}}
+ {{jsxref("Object.prototype.isPrototypeOf()")}}
+ {{jsxref("Operators/instanceof", "instanceof")}}
+
    +
  • getPrototypeOf method must return an object or null.
  • +
  • If target is not extensible, Object.getPrototypeOf(proxy) method must return the same value as Object.getPrototypeOf(target).
  • +
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}{{jsxref("Object.setPrototypeOf()")}}
+ {{jsxref("Reflect.setPrototypeOf()")}}
If target is not extensible, the prototype parameter must be the same value as Object.getPrototypeOf(target).
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}{{jsxref("Object.isExtensible()")}}
+ {{jsxref("Reflect.isExtensible()")}}
Object.isExtensible(proxy) must return the same value as Object.isExtensible(target).
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}{{jsxref("Object.preventExtensions()")}}
+ {{jsxref("Reflect.preventExtensions()")}}
Object.preventExtensions(proxy) only returns true if Object.isExtensible(proxy) is false.
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}{{jsxref("Object.getOwnPropertyDescriptor()")}}
+ {{jsxref("Reflect.getOwnPropertyDescriptor()")}}
+
    +
  • getOwnPropertyDescriptor must return an object or undefined.
  • +
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • +
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
  • +
  • A property cannot be reported as existent, if it does not exists as an own property of the target object and the target object is not extensible.
  • +
  • A property cannot be reported as non-configurable, if it does not exists as an own property of the target object or if it exists as a configurable own property of the target object.
  • +
  • The result of Object.getOwnPropertyDescriptor(target)can be applied to the target object using Object.defineProperty and will not throw an exception.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}{{jsxref("Object.defineProperty()")}}
+ {{jsxref("Reflect.defineProperty()")}}
+
    +
  • A property cannot be added, if the target object is not extensible.
  • +
  • A property cannot be added as or modified to be non-configurable, if it does not exists as a non-configurable own property of the target object.
  • +
  • A property may not be non-configurable, if a corresponding configurable property of the target object exists.
  • +
  • If a property has a corresponding target object property then Object.defineProperty(target, prop, descriptor) will not throw an exception.
  • +
  • In strict mode, a false return value from the defineProperty handler will throw a {{jsxref("TypeError")}} exception.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}Property query: foo in proxy
+ Inherited property query: foo in Object.create(proxy)
+ {{jsxref("Reflect.has()")}}
+
    +
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • +
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}Property access: proxy[foo]and proxy.bar
+ Inherited property access: Object.create(proxy)[foo]
+ {{jsxref("Reflect.get()")}}
+
    +
  • The value reported for a property must be the same as the value of the corresponding target object property if the target object property is a non-writable, non-configurable data property.
  • +
  • The value reported for a property must be undefined if the corresponding target object property is non-configurable accessor property that has undefined as its [[Get]] attribute.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}Property assignment: proxy[foo] = barand proxy.foo = bar
+ Inherited property assignment: Object.create(proxy)[foo] = bar
+ {{jsxref("Reflect.set()")}}
+
    +
  • Cannot change the value of a property to be different from the value of the corresponding target object property if the corresponding target object property is a non-writable, non-configurable data property.
  • +
  • Cannot set the value of a property if the corresponding target object property is a non-configurable accessor property that has undefined as its [[Set]] attribute.
  • +
  • In strict mode, a false return value from the sethandler will throw a {{jsxref("TypeError")}} exception.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}Property deletion: delete proxy[foo] and delete proxy.foo
+ {{jsxref("Reflect.deleteProperty()")}}
A property cannot be deleted, if it exists as a non-configurable own property of the target object.
{{jsxref("Global_Objects/Proxy/handler/enumerate", "handler.enumerate()")}}Property enumeration / for...in: for (var name in proxy) {...}
+ {{jsxref("Reflect.enumerate()")}}
The enumerate method must return an object.
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}{{jsxref("Object.getOwnPropertyNames()")}}
+ {{jsxref("Object.getOwnPropertySymbols()")}}
+ {{jsxref("Object.keys()")}}
+ {{jsxref("Reflect.ownKeys()")}}
+
    +
  • The result of ownKeys is a List.
  • +
  • The Type of each result List element is either {{jsxref("String")}} or {{jsxref("Symbol")}}.
  • +
  • The result List must contain the keys of all non-configurable own properties of the target object.
  • +
  • If the target object is not extensible, then the result List must contain all the keys of the own properties of the target object and no other values.
  • +
+
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}proxy(..args)
+ {{jsxref("Function.prototype.apply()")}} and {{jsxref("Function.prototype.call()")}}
+ {{jsxref("Reflect.apply()")}}
There are no invariants for the handler.applymethod.
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}new proxy(...args)
+ {{jsxref("Reflect.construct()")}}
The result must be an Object.
+ +

Revocable Proxy

+ +

The {{jsxref("Proxy.revocable()")}} method is used to create a revocable Proxy object. This means that the proxy can be revoked via the function revoke and switches the proxy off. Afterwards, any operation on the proxy leads to a {{jsxref("TypeError")}}

+ +
var revocable = Proxy.revocable({}, {
+  get: function(target, name) {
+    return '[[' + name + ']]';
+  }
+});
+var proxy = revocable.proxy;
+console.log(proxy.foo); // "[[foo]]"
+
+revocable.revoke();
+
+console.log(proxy.foo);  // TypeError is thrown
+proxy.foo = 1;           // TypeError again
+delete proxy.foo;        // still TypeError
+typeof proxy;            // "object", typeof doesn't trigger any trap
+ +

Reflection

+ +

{{jsxref("Reflect")}} is a built-in object that provides methods for interceptable JavaScript operations. The methods are the same as those of the {{jsxref("Global_Objects/Proxy/handler","proxy handlers","","true")}}. Reflect is not a function object.

+ +

Reflect helps with forwarding default operations from the handler to the target.

+ +

With {{jsxref("Reflect.has()")}} for example, you get the in operator as a function:

+ +
Reflect.has(Object, 'assign'); // true
+ +

A better apply function

+ +

In ES5, you typically use the {{jsxref("Function.prototype.apply()")}} method to call a function with a given this value and arguments provided as an array (or an array-like object).

+ +
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
+ +

With {{jsxref("Reflect.apply")}} this becomes less verbose and easier to understand:

+ +
Reflect.apply(Math.floor, undefined, [1.75]);
+// 1;
+
+Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
+// "hello"
+
+Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index;
+// 4
+
+Reflect.apply(''.charAt, 'ponies', [3]);
+// "i"
+ +

Checking if property definition has been successful

+ +

With {{jsxref("Object.defineProperty")}}, which returns an object if successful, or throws a {{jsxref("TypeError")}} otherwise, you would use a {{jsxref("Statements/try...catch","try...catch")}} block to catch any error that occurred while defining a property. Because {{jsxref("Reflect.defineProperty")}} returns a Boolean success status, you can just use an {{jsxref("Statements/if...else","if...else")}} block here:

+ +
if (Reflect.defineProperty(target, property, attributes)) {
+  // success
+} else {
+  // failure
+}
+ +

{{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}

+ +

 

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/about/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/about/index.html deleted file mode 100644 index 05deb2017f..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/about/index.html +++ /dev/null @@ -1,109 +0,0 @@ ---- -title: About -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/About ---- -

이번 릴리즈의 새 기능

-

JavaScript 버전 1.5는 다음과 같은 개선과 새 기능을 제공합니다: -

런타임 오류
-런타임 오류가 예외로서 보고됩니다. -

숫자 표현 서식 개선
-숫자를 표현하는 서식이 Number.prototype.toExponential, Number.prototype.toFixed, Number.prototype.toPrecision 메소드를 포함함으로서 개선되었습니다. Number 개체 페이지를 보십시오. -

정규 표현식 개선
-정규표현식이 다음과 같이 개선되었습니다: -

- -

조건부 함수 선언
-함수를 if 조건안에서 선언할 수 있습니다. 함수 정의 페이지를 참고하세요. -

함수 표현식
-함수를 표현식 안에서 선언할 수 있습니다. 함수 정의 페이지를 참고하세요. -

Multiple catch clauses
-Multiple catch clauses in a try...catch statement are supported. See The catch Block page. -

Getters와 Setters
-JavaScript writers can now add getters and setters to their objects. This feature is available only in the C implementation of JavaScript. See the Defining Getters and Setters page. -

상수
-읽기전용의 상수가 지원됩니다. This feature is available only in the C implementation of JavaScript. See the Constants page. -

-

미리 알고 있어야 할 것

-

이 안내서는 당신이 다음과 같은 배경지식을 지녔다고 가정합니다: -

-
  • 인터넷과 World Wide Web (WWW)에 대한 상식적인 이해 -
  • HyperText Markup Language (HTML)에 대한 충분한 지식
    -
-

C 혹은 Visual Basic에 대한 프로그래밍 경험이 있으면 좋지만, 필수사항은 아닙니다. -

-

JavaScript 버전

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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
모질라 (오픈소스 브라우저)
-

표1: JavaScript와 Navigator 버전
-
-Each version of the Netscape Enterprise Server also supports a different version of JavaScript. To help you write scripts that are compatible with multiple versions of the Enterprise Server, this manual uses an abbreviation to indicate the server version in which each feature was implemented. -

- - - - - - - - - - - - - -
AbbreviationEnterprise Server version
NES 2.0Netscape Enterprise Server 2.0
NES 3.0Netscape Enterprise Server 3.0
-

Table 2: Abbreviations of Netscape Enterprise Server versions -

-

JavaScript 정보를 찾을 수 있는 곳

-

The core JavaScript documentation includes the following books: -

- -

If you are new to JavaScript, start with the Core JavaScript Guide. Once you have a firm grasp of the fundamentals, you can use the Core JavaScript Reference to get more details on individual objects and statements. -

-

문서 규약

-

JavaScript 응용프로그램은 많은 운영체제에서 실행됩니다. 이 책에 있는 정보는 모든 운영체제에 적용됩니다. 파일과 디렉토리 경로는 Windows 형식(디렉토리 이름을 구분하는데 역슬래시를 사용)으로 썼습니다. Unix에서는 역슬래시를 슬래시로 바꾸어 사용하면 됩니다. -

이 안내서에서 URL은 다음과 같은 형태로 씁니다. -

http://server.domain/path/file.html -

이 URL에서 "server"는 우리가 응용프로그램을 실행하는 서버 이름(research1이나 www 등)이고, "domain"은 인터넷 도메인 이름(netscape.com이나 uiuc.edu 등)입니다. "path"는 서버의 디렉토리 구조를 나타내고, "file.html"은 파일 이름입니다. 일반적으로 URL에서 이탤릭체로 쓴 부분은 알맞은 내용으로 바꿔써야 할 내용(placeholder)이고, 평범한 고정폭 글꼴은 그대로 쓰면 되는 내용입니다. Secure Socket Layer(SSL)을 사용하는 서버라면 http 대신 https를 쓰면 됩니다. -

이 안내서는 다음과 같은 관례를 따릅니다. -

-
  • 고정폭 글꼴은 샘플 코드, API, 언어 요소(메소드 이름, 속성 이름 등), 파일 이름, 경로, 디렉토리 이름, HTML 태그, 화면에 입력해야 할 텍스트를 나타내는 데 쓰입니다. (고정폭 이탤릭체는 코드 내용 중에서 적당히 알맞은 내용으로 바꿔써야 할 부분을 나타내는 데 씁니다.) -
  • 이탤릭체는 책 제목, 강조, 변수, 뜻 그대로 쓰인 단어(words in the literal sense)에 씁니다. -
  • 굵은 글씨는 용어에 씁니다. -
-

{{ PreviousNext("Core_JavaScript_1.5_Guide", "Core_JavaScript_1.5_Guide:JavaScript_Overview") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/About", "fr": "fr/Guide_JavaScript_1.5/\u00c0_propos", "ja": "ja/Core_JavaScript_1.5_Guide/About", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/O" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/class-based_vs._prototype-based_languages/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/class-based_vs._prototype-based_languages/index.html deleted file mode 100644 index 20601a0e81..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/class-based_vs._prototype-based_languages/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: Class-Based vs. Prototype-Based Languages -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Class-Based_vs._Prototype-Based_Languages ---- -

클래스 기반언어와 프로토타입 기반언어

-

Java와 C++이라는 클래스 기반의 객체지향언어는 클래스와 인스턴스라는 2개의 다른 실체가 있다는 개념에 기초하고 있습니다.

-
  • 클래스는 어떤 객체의 집합을 특징짓는 모든 속성(Java에서는 메소드와 필드를, C++에서는 멤버를 프로퍼티로 간주)을 정의합니다. 클래스란 그것이 나타내는 객체집합의 특정멤버가 아닌, 추상적인것입니다. 예를들어, Employee클래스는 모든 종업원의 집합을 나타냅니다.
  • 한편, 인스턴스는 클래스를 실례로 한것입니다. 즉, 그 멤버중 하나인것입니다. 예를들어, Victoria는 Employee클래스의 인스턴스가 될 수 있습니다. 이 클래스는 특정 개인을 종업원으로서 표현하고 있는것입니다. 인스턴스는 그 부모클래스의 속성을 정확하게 유지하고 있습니다.
  • -
-

JavaScript のようなプロトタイプベース言語はこの区別がありません。単にオブジェクトがあるだけです。プロトタイプベース言語には原型的なオブジェクトという概念があります。このオブジェクトは新しいオブジェクトの初期プロパティを取得する元になるテンプレートとして使用されます。どのオブジェクトもそれ独自のプロパティを指定できます。オブジェクト作成時にも実行時にも可能です。さらに、どのオブジェクトも別のオブジェクトに対するプロトタイプとして関連付けることができます。2 つ目のオブジェクトが 1 つ目のオブジェクトのプロトタイプを共有するということもできます。

-

クラスの定義

-

クラスベース言語ではクラス定義ごとにクラスを定義します。定義では特殊なメソッドを指定してそのクラスのインスタンスを作成することができます。そのようなメソッドはコンストラクタと呼びます。コンストラクタメソッドはインスタンスのプロパティに対する初期値を指定することができます。また、作成時に他の適当な処理を実行することもできます。new 演算子をコンストラクタメソッドと一緒に用いることでクラスのインスタンスを作成できます。

-

JavaScript は同様のモデルに従っていますが、コンストラクタと別になっているクラス定義がありません。その代わりに、プロパティと値からなる特定の初期的なセットを持つオブジェクトを作成するコンストラクタ関数を定義します。どの JavaScript 関数もコンストラクタとして使用できます。new 演算子をコンストラクタ関数とともに使用することで新しいオブジェクトを作成します。

-

サブクラスと継承

-

クラスベース言語ではクラス定義を通じてクラスの階層を作ります。クラス定義では新しいクラスがある既存のクラスのサブクラスになるように指定することができます。サブクラスはスーパークラスの全プロパティを継承します。さらに新しくプロパティを追加したり継承したものを変更することもできます。例えば、Employee クラスが name および dept プロパティのみを含んでおり、Manager は reports プロパティを追加する Employee のサブクラスであるとします。この場合、Manager クラスのインスタンスは name、dept、reports という 3 つのプロパティをすべて持つことになります。

-

JavaScript では、原型的なオブジェクトをどのコンストラクタ関数にも結びつけることができるようにして継承を実装しています。そのため、全く同じような Employee と Manager の例を作成することができますが、使用する用語が若干異なります。まず、Employee コンストラクタ関数を定義します。これは name および dept プロパティを指定します。次に Manager コンストラクタ関数を定義します。これは reports プロパティを指定します。最後に新しい Employee オブジェクトを Manager コンストラクタ関数に対するプロトタイプとして代入します。そして新しい Manager を作成すると、このオブジェクトは Employee オブジェクトから name および dept プロパティを継承します。

-

プロパティの追加と削除

-

クラスベース言語では一般的にクラスをコンパイル時に生成し、コンパイル時または実行時にクラスのインスタンスを作成します。クラス定義後にそのクラスのプロパティの数や型を変更することはできません。しかし、JavaScript ではどんなオブジェクトでも実行時にプロパティを追加したり削除したりすることができます。あるオブジェクトのセットでプロトタイプとして使用されているオブジェクトにプロパティを追加すると、そのプロトタイプの使用元であるオブジェクトにも新しいプロパティが追加されます。

-

違いの概要

-

次の表でこれらの違いをいくつか短くまとめてみます。この章の残りで、JavaScript のコンストラクタとプロトタイプを用いてオブジェクト階層を作成することについての詳細を説明していきます。また、この方法が Java ではどう変わるかという比較もします。

- -
クラスベース (Java) プロトタイプベース (JavaScript)
クラスとインスタンスは異なる実体である。 すべてのオブジェクトはインスタンスである。
クラス定義を用いてクラスを定義する。また、コンストラクタメソッドを用いてクラスをインスタンス化する。 コンストラクタ関数を用いてオブジェクトのセットを定義し、作成する。
new 演算子を用いて単一のオブジェクトを作成する。 同じ。
既存のクラスのサブクラスを定義するクラス定義を用いてオブジェクト階層を構築する。 コンストラクタ関数に結びつけられたプロトタイプとしてオブジェクトを代入することでオブジェクト階層を構築する。
クラスチェーンに従ってプロパティを継承する。 プロトタイプチェーンに従ってプロパティを継承する。
クラス定義がクラスの全インスタンスの全プロパティを指定する。実行時に動的にプロパティを追加することはできない。 コンストラクタ関数またはプロトタイプがプロパティの初期セットを指定する。個々のオブジェクトやオブジェクトの全体のセットに動的にプロパティを追加したり、それらからプロパティを除去したりできる。
-
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Predefined_Core_Objects:String_Object", "Core_JavaScript_1.5_Guide:The_Employee_Example") }}

-
-

{{ languages( { "zh-tw": "zh_tw/Core_JavaScript_1.5_教學/以類別為基礎的語言_vs._以原型為基礎的語言", "en": "en/Core_JavaScript_1.5_Guide/Class-Based_vs._Prototype-Based_Languages", "es": "es/Gu\u00eda_JavaScript_1.5/Lenguajes_basados_en_clases_frente_a_basados_en_prototipos", "fr": "fr/Guide_JavaScript_1.5/Langages_bas\u00e9s_sur_les_classes_et_langages_bas\u00e9s_sur_les_prototypes", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/J\u0119zyki_oparte_na_klasach_vs._oparte_na_prototypach", "zh-cn": "cn/Core_JavaScript_1.5_Guide/Class-Based_vs._Prototype-Based_Languages" } ) }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/constants/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/constants/index.html deleted file mode 100644 index 7b5f5c577c..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/constants/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Constants -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Constants -translation_of: Web/JavaScript/Guide/Grammar_and_types -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Constants ---- -

상수

-

const 키워드를 이용하면 읽기 전용의 이름 있는 상수를 만들 수 있습니다. 상수 식별자(const identifier)는 변수의 식별자와 동일합니다. 문자나 밑줄로 시작해야 하고, 알파벳, 숫자, 밑줄 문자를 사용할 수 있습니다. -

-
const prefix = '212';
-
-

상수는 스크립트 실행 중에 값을 대입하거나 다시 선언하여 값을 바꿀 수 없습니다. -

전역 상수인 경우에도 항상 const 키워드를 붙여야 한다는 점만 제외하면, 상수의 범위 규칙은 변수의 경우와 동일합니다. const 키워드가 없으면 변수라고 판정됩니다. -

같은 범위에 있는 함수나 변수의 이름과 같은 이름으로 상수를 만들 수 없습니다. 예를 들어, -

-
//이 코드는 에러를 낼 것입니다
-function f() {};
-  const f = 5;
-
-//이 코드 또한 에러를 냅니다.
-function f() {
-  const g = 5;
-  var g;
-
-  //그 외 코드...
-
-}
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Variables", "Core_JavaScript_1.5_Guide:Literals") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Constants", "fr": "fr/Guide_JavaScript_1.5/Constantes", "ja": "ja/Core_JavaScript_1.5_Guide/Constants", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Sta\u0142e" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_a_regular_expression/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_a_regular_expression/index.html deleted file mode 100644 index d969b378f4..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_a_regular_expression/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Creating a Regular Expression -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_a_Regular_Expression ---- -

정규표현식 만들기

-

정규표현식은 다음의 두 가지 방법으로 만들 수 있습니다.

-
    -
  • 정규표현식 상수값을 이용하여 만들기
  • -
-
 re = /ab+c/; 
-
-
-
-
- 정규표현식 상수값은 스크립트가 실행될 때 컴파일됩니다. 따라서 정규표현식의 값이 변하지 않을 경우, 이 방법을 사용하면 좀 더 나은 성능을 얻을 수 있습니다.
-
-
-
-
    -
  • RegExp 객체의 생성자를 호출하여 만들기
  • -
-
 re = new RegExp("ab+c"); 
-
-
-
-
- 생성자를 이용하면 실행 시간에 정규표현식이 컴파일됩니다. 정규표현식 패턴이 바뀔 것을 알고 있거나, 또는 패턴을 사용자의 입력 등을 통해 외부에서 가져오려고 할 때 이 방법을 사용하십시오.
-
-
-
-
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Operators:Special_Operators", "Core_JavaScript_1.5_Guide:Writing_a_Regular_Expression_Pattern") }}

-
-

 

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_getters_and_setters/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_getters_and_setters/index.html deleted file mode 100644 index 3238e19b0f..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_getters_and_setters/index.html +++ /dev/null @@ -1,84 +0,0 @@ ---- -title: Defining Getters and Setters -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Getters_and_Setters ---- -

getter/setter 정의하기

- -

getter는 속성의 값을 얻어오는 메소드이고, setter는 속성의 값을 설정하는 메소드입니다. 우리는 언어에서 미리 정의한 핵심 개체들과 사용자 정의 개체에 getter/setter를 정의할 수 있습니다. getter와 setter를 정의할 때 쓰이는 문법은 개체 상수값 문법입니다.

- -

다음의 JS 쉘 세션은 사용자가 정의한 개체 o에 대해서 getter와 setter가 어떻게 동작하는지 보여줍니다. JS 쉘은 JavaScript를 한 번에 실행(batch)하거나 대화식으로(interactively) 실행할 수 있게 해주는 응용프로그램입니다.

- -

o 개체에는 이런 속성이 있습니다.

- -
    -
  • o.a - 수
  • -
  • o.b - o.a 더하기 1을 반환하는 getter
  • -
  • o.c - 받은 값을 2로 나누어서 o.a에 설정하는 setter
  • -
- -
js> o = new Object;
-[object Object]
-js> o = {a:7, get b() {return this.a+1; }, set c(x) {this.a = x/2}};
-[object Object]
-js> o.a
-7
-js> o.b
-8
-js> o.c = 50
-js> o.a
-25
-js>
-
- -

다음 JavaScript 쉘 세션은 이미 정의된 Date 모든 인스턴스에 year 속성을 추가하기 위해서 getter/setter가 어떻게 Date 프로토타입을 확장하는지 보여줍니다. 이 세션에서는 year 속성의 getter와 setter를 지원하기 위해서 Date에 있는 getFullYear 메소드와 setFullYear 메소드를 사용하고 있습니다.

- -

이 문장들은 year 속성에 대한 getter와 setter를 정의합니다.

- -
js> var d = Date.prototype;
-js> d.__defineGetter__("year", function() { return this.getFullYear(); });
-js> d.__defineSetter__("year", function(y) { this.setFullYear(y); });
-
- -

이 문장들은 Date의 getter/setter를 사용합니다.

- -
js> var now = new Date;
-js> print(now.year);
-2000
-js> now.year=2001;
-987617605170
-js> print(now);
-Wed Apr 18 11:13:25 GMT-0700 (Pacific Daylight Time) 2001
-
- -
JavaScript 1.5를 개발하는 동안 이미 존재하는 개체에 getter/setter를 추가할 때 getter =, setter =이라는 식의 문법을 사용하던 때가 잠깐 있었습니다. 이 문법은 이제 사용하지 말아야 합니다. 현재의 JS 1.5 엔진에서는 경고를 발생시키고, 더 나중의 버전에서는 문법 에러를 발생시키게 될 것입니다.
- -

 

- -

요약

- -

getter/setter를

- -
    -
  • 개체 초기화 지정자를 이용해서 정의하거나,
  • -
  • 개체가 만들어진 이후에 getter/setter 추가 메소드를 이용해서 언제든지 추가할 수 있습니다.
  • -
- -

개체 초기화 지정자를 이용할 때는 단순히 getter 메소드 앞에는 get을 써주고 setter 메소드 앞에는 set을 써주기만 하면됩니다. 물론 getter 메소드에는 매개변수가 없어야 하고 setter에는 정확히 하나만 있어야 합니다. 다음 예제에서와 같이 말입니다.

- -
o = {
-  a:7,
-  get b() { return this.a+1; },
-  set c(x) { this.a = x/2; }
-};
-
- -

개체가 생성된 이후에 어느 때라도 __defineGetter____defineSetter__라는 메소드를 이용하면 getter/setter를 정의할 수 있습니다. 두 메소드 모두 첫 번째 매개변수에 getter/setter 이름을 나타내는 문자열을 받습니다. 두 번째 매개변수는 getter/setter로서 호출될 함수를 받습니다. 예제를 보십시오.

- -
o.__defineGetter__("b", function() { return this.a+1; });
-o.__defineSetter__("c", function(x) { this.a = x/2; });
-
- -

두 가지 중에서 어떤 방식을 택할지는 프로그래밍 스타일이나 해야할 작업에 달려있습니다. 프로토타입을 정의하는데 이미 개체 초기화 지정자를 사용하고 있다면 거의 첫 번째 방식을 사용할 것입니다. 첫 번째가 좀 더 단순하고 자연스러운 방식입니다. 그러나 우리가 직접 프로토토입을 만들거나 개체를 생성할 수 없어서 나중에 getter/setter를 추가해야 하는 상황이라면 두 번째 방식을 사용할 수 밖에 없습니다. 두 번째 방식은 JavaScript의 동적인 특성을 잘 보여주는 방식입니다. 하지만 코드를 읽고 이해하기 어렵게 만들 수도 있습니다.

- -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Using_this_for_Object_References", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Deleting_Properties") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_methods/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_methods/index.html deleted file mode 100644 index 8e91a2007f..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_methods/index.html +++ /dev/null @@ -1,43 +0,0 @@ ---- -title: Defining Methods -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Methods ---- -

메소드 정의

-

- - 메소드 - 는 개체와 연관되어 있는 함수입니다. 일반적인 함수를 정의하는 것과 같은 방법으로 메소드를 정의합니다. 그 후에, 존재하는 개체와 함수를 연관시키기 위해서 다음과 같은 문법을 사용합니다.

-
object.methodname = function_name
-
-

object는 존재하는 개체중에 하나이고, methodname은 지금 추가하려는 메소드 이름이며, function_name은 함수 이름입니다.

-

이제 우리는 개체의 메소드를 호출할 때 다음과 같이 할 수 있습니다.

-
object.methodname(params);
-
-

개체 생성자 함수에 메소드 정의를 포함시켜서 개체 타입에 대한 메소드를 정의할 수 있습니다. 예를 들어, 미리 정의된 car 개체의 속성을 출력해주는 함수를 정의할 수 있습니다.

-
function displayCar() {
-   var result = "A Beautiful " + this.year + " " + this.make
-      + " " + this.model;
-   pretty_print(result);
-}
-
-

pretty_print는 가로선과 문자열을 출력하는 함수입니다. 이 메소드가 포함된 개체를 참조하기 위해서 this를 사용하고 있다는 것을 주의해서 보십시오.

-

아래 문장을 개체 정의에 추가함으로써 이 함수를 car의 메소드로 만들 수 있습니다.

-
this.displayCar = displayCar;
-
-

그러므로 car 개체의 완벽한 정의는 아래와 같은 모습이 될 것입니다.

-
function car(make, model, year, owner) {
-   this.make = make;
-   this.model = model;
-   this.year = year;
-   this.owner = owner;
-   this.displayCar = displayCar;
-}
-
-

그러면 우리는 모든 car 개체에 대해서 이런 식으로 displayCar 메소드를 호출할 수 있게됩니다.

-
car1.displayCar()
-car2.displayCar()
-
-

이 코드는 다음 그림과 같은 내용을 만들어냅니다.

-

Image:obja.gif 그림 7.1: 메소드 출력 결과

-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Defining_Properties_for_an_Object_Type", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Using_this_for_Object_References") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_properties_for_an_object_type/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_properties_for_an_object_type/index.html deleted file mode 100644 index 17c2aa7de8..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/defining_properties_for_an_object_type/index.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: Defining Properties for an Object Type -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects/Defining_Properties_for_an_Object_Type ---- -

개체 형식에 속성 정의하기

-

prototype 속성을 이용하면 이미 정의해 놓은 개체 형식에 속성을 추가할 수 있습니다. 이 방법을 사용하면 개체의 인스턴스 하나에만 속성이 추가되는 것이 아니라 같은 타입의 모든 개체가 공유하는 속성을 정의합니다. 다음 코드는 car 형식의 모든 개체에 color 속성을 추가하고, car1 개체의 color 속성에 값을 할당하는 코드입니다.

-
Car.prototype.color=null;
-car1.color="black";
-
-

더 많은 정보를 얻으려면 기본 JavaScript 레퍼런스에 있는 Function 개체의 prototype 속성을 보십시오. {{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Indexing_Object_Properties", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Defining_Methods") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/deleting_properties/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/deleting_properties/index.html deleted file mode 100644 index 1b6f50cc11..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/deleting_properties/index.html +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Deleting Properties -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects/Deleting_Properties ---- -

속성 제거

-

delete 연산자를 사용하여 속성을 제거할 수 있습니다. 어떻게 속성을 제거하는지 코드를 보십시오.

-
//a와 b라는 속성을 가지는 새 개체를 만듭니다.
-myobj = new Object;
-myobj.a = 5;
-myobj.b = 12;
-
-//myobj가 속성 b만을 가지도록 속성 a를 지웁니다.
-delete myobj.a;
-
-

전역 변수를 선언할 때 var 키워드를 사용하지 않았다면 그 전역 변수를 제거하는데 delete 연산자를 사용할 수 있습니다.

-
g = 17;
-delete g;
-
-

더 많은 정보를 얻으려면 delete를 보십시오. {{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Defining_Getters_and_Setters", "Core_JavaScript_1.5_Guide:Predefined_Core_Objects") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/index.html deleted file mode 100644 index 8345ba1478..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/index.html +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: Creating New Objects -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects ---- -{{wiki.localize('System.API.page-generated-for-subpage')}} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/indexing_object_properties/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/indexing_object_properties/index.html deleted file mode 100644 index 84b9df2c2d..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/indexing_object_properties/index.html +++ /dev/null @@ -1,9 +0,0 @@ ---- -title: Indexing Object Properties -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects/Indexing_Object_Properties ---- -

개체 속성 접근하기

-

JavaScript 1.0에서는 개체의 속성을 참조할 때 개체 이름이나 순서 인덱스를 사용할 수 있습니다. 그러나 JavaScript 1.1과 그 이후 버전에서는 처음에 속성을 정의할 때 이름으로 정의했으면 항상 이름으로만 참조해야 하고, 인덱스로 정의했으면 인덱스로만 참조해야 합니다.

-

이런 제한은 앞 페이지 예제의 car 개체 형식처럼 생성자 함수로 개체와 개체 속성을 만들 때나 명시적으로 개별 속성을 만들 때(예를 들어 myCar.color = "red" 같은 식으로 속성을 추가할 때) 모두 적용됩니다. 그러므로 myCar{{ mediawiki.external(5) }} = "25 mpg"라고 인덱스를 이용해서 속성을 정의하면 그 이후로는 항상 myCar{{ mediawiki.external(5) }}로 참조할 수 있습니다.

-

이 규칙은 forms 배열 같이 HTML을 반영하여 생성된 개체에는 예외입니다. 이 배열에 있는 개체를 참조할 때는 순서(문서에 기록된 순서)를 나타내는 숫자나 이름(이름을 정의한 경우에만)을 이용하여 참조할 수 있습니다. 예를 들어, 문서에 있는 두 번째 <FORM> 태그가 "myForm"이라는 값을 가진 NAME 속성을 갖고 있다면 이 폼은 document.forms{{ mediawiki.external(1) }}, document.forms{{ mediawiki.external('\"myForm\"') }}, document.myForm으로 접근할 수 있습니다. {{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Using_a_Constructor_Function", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Defining_Properties_for_an_Object_Type") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_a_constructor_function/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_a_constructor_function/index.html deleted file mode 100644 index 552347b70e..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_a_constructor_function/index.html +++ /dev/null @@ -1,58 +0,0 @@ ---- -title: Using a Constructor Function -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_a_Constructor_Function ---- -

생성자 함수 사용하기

-

다른 방법으로, 다음 두 단계를 거쳐서 개체를 만들 수도 있습니다.

-
    -
  1. 생성자 함수를 작성함으로써 개체를 정의합니다.
  2. -
  3. new 키워드를 사용하여 개체의 인스턴스를 만듭니다.
  4. -
-

개체 형식을 정의하기 위해서, 개체의 이름, 속성, 메소드를 지정하는 함수를 만듭니다. 자동차를 나타내기 위한 개체를 만들고 싶다고 해봅시다. 그렇다면 이 형식이 car라고 불리길 원할 것이고, make, model, year라는 속성이 있기를 원할 것입니다. 원하는 것을 이루기 위해서 이런 함수를 작성합니다.

-
function car(make, model, year) {
-   this.make = make;
-   this.model = model;
-   this.year = year;
-}
-
-

함수의 인자로 전달받은 값을 개체의 속성에 할당하기 위해서 this를 사용했다는 것을 명심하십시오.

-

이제 우리는 mycar라는 개체를 이렇게 만들 수 있습니다.

-
mycar = new car("Eagle", "Talon TSi", 1993);
-
-

이 문장은 mycar를 만들고, 지정된 값을 mycar의 속성에 할당합니다. 그러면 mycar.make는 "Eagle"이라는 문자열 값을 가지고, mycar.year는 1993이라는 정수를 가질 것입니다.

-

우리는 new를 써서 car 개체를 몇 개라도 만들 수 있습니다.

-
kenscar = new car("Nissan", "300ZX", 1992);
-vpgscar = new car("Mazda", "Miata", 1990);
-
-

개체는 다른 개체를 속성으로 가질 수 있습니다. 예를 들어, person 개체를 다음과 같이 정의했다고 합시다.

-
function person(name, age, sex) {
-   this.name = name;
-   this.age = age;
-   this.sex = sex;
-}
-
-

그리고나서 person 개체의 인스턴스 두 개를 만듭니다.

-
rand = new person("Rand McKinnon", 33, "M");
-ken = new person("Ken Jones", 39, "M");
-
-

이제 우리는 car가 owner라는 속성으로 person 개체를 가지도록 car의 정의를 바꿀 수 있습니다.

-
function car(make, model, year, owner) {
-   this.make = make;
-   this.model = model;
-   this.year = year;
-   this.owner = owner;
-}
-
-

새 개체 인스턴스를 만들 때 이렇게 쓸 수 있습니다.

-
car1 = new car("Eagle", "Talon TSi", 1993, rand);
-car2 = new car("Nissan", "300ZX", 1992, ken);
-
-

위 문장에서 owner 인자로 문자열 상수값이나 정수값을 전달하는 대신 randken이라는 개체를 전달했다는 사실에 주의하십시오. 이제 car2의 소유자 이름을 알고 싶으면 이런식으로 접근할 수 있습니다.

-
car2.owner.name
-
-

정의된 개체에 아무때나 속성을 추가할 수 있다는 사실을 기억하십시오.

-
car1.color = "black"
-
-

이 문장은 car1에 color 속성을 추가하고 "black"이라는 값을 할당합니다. 그러나 이 문장이 다른 개체에 영향을 미치지는 않습니다. 같은 형식을 가지는 모든 개체에 새 속성을 추가하고 싶으면 car 개체 형식의 정의에 속성을 추가해야 합니다.

-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Using_Object_Initializers", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Indexing_Object_Properties") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_this_for_object_references/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_this_for_object_references/index.html deleted file mode 100644 index 0ed663ae1f..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/creating_new_objects/using_this_for_object_references/index.html +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Using this for Object References -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Creating_New_Objects/Using_this_for_Object_References ---- -

this를 사용한 개체 참조

-

JavaScript에는 this라는 키워드가 있는데, 메소드 안에서 현재 개체를 참조하기 위해서 이 키워드를 사용할 수 있습니다. 예를 들어, 개체의 값 속성을 검증하는 validate라는 함수가 있다고 해봅시다.

-
function validate(obj, lowval, hival) {
-   if ((obj.value < lowval) || (obj.value > hival))
-      alert("Invalid Value!");
-}
-
-

그러면 폼의 각 요소의 onchange 이벤트 핸들러에서 validate를 호출할 때, 다음 예제와 같은 방법으로 this를 사용해서 폼 요소를 validate에 전달할 수 있습니다.

-
<input type="text" name="age" size="3"
-   onChange="validate(this, 18, 99)">
-
-

form 속성과 같이 사용하면, this는 현재 개체의 부모 폼을 참조할 수 있습니다. 다음 예제에서, myForm이라는 폼은 Text 개체와 버튼을 포함하고 있습니다. 사용자가 버튼을 클릭하면 Text 개체의 값을 폼 이름으로 바꿉니다. 버튼의 onclick 이벤트 핸들러에서 부모 폼인 myForm을 참조하기 위해서 this.form을 사용하고 있습니다.

-
<form name="myForm">
-<p><label>Form name:<input type="text" name="text1" value="Beluga"></label>
-<p><input name="button1" type="button" value="Show Form Name"
-      onclick="this.form.text1.value=this.form.name">
-</p>
-</form>
-
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Defining_Methods", "Core_JavaScript_1.5_Guide:Creating_New_Objects:Defining_Getters_and_Setters") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/expressions/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/expressions/index.html deleted file mode 100644 index d9f8bb0bf9..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/expressions/index.html +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Expressions -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Expressions ---- -

표현식

-

표현식은 상수(literals), 변수, 연산자 그리고 단일값을 반환하는 계산식(값은 숫자, 문자열, 논리값이 가능)이 알맞게 조합된 집합체다. -

개념적으로 보면 표현식에는 두가지 타입이 있다: 하나는 변수에 값을 할당하는 것이고 다른 하나는 단순히 값을 가지고 있는 것이다. 예를 들어, x = 7 이라는 표현식은 x 에 7이라는 값을 할당하는 표현식이다. 이 표현식은 스스로 7이라는 값을 부여한다. 이런 표현식들은 할당 연산자를 사용한다. 반면에, 3 + 4 라는 표현식은 단순히 7이라는 값을 계산할 뿐이다; 할당하지 않는다. 이런 표현식에서 사용되는 연산자는 그냥 단순히 연산자라고만 한다. -

JavaScript에는 다음과 같은 타입의 표현식이 있다: -

-
  • 산술형 : 3.14159와 같이 숫자를 표현(evaluate). (일반적으로 산술 연산자를 사용) -
  • 문자열형: "Fred"나 "234"와 같이 문자열을 표현(evaluate). (일반적으로 문자열 연산자를 사용) -
  • 논리형: 참(true) 혹은 거짓(false)을 표현(evaluate). (종종 논리 연산자와 함께 사용) -
  • 객체형: 객체를 표현(evaluate). (객체표현식에 사용하는 다양한 연산자는 특수 연산자를 참고) -
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Unicode", "Core_JavaScript_1.5_Guide:Operators") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Expressions", "fr": "fr/Guide_JavaScript_1.5/Expressions", "ja": "ja/Core_JavaScript_1.5_Guide/Expressions", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Wyra\u017cenia" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/javascript_overview/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/javascript_overview/index.html deleted file mode 100644 index 310ab25c67..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/javascript_overview/index.html +++ /dev/null @@ -1,44 +0,0 @@ ---- -title: JavaScript Overview -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/JavaScript_Overview ---- -

JavaScript란 무엇인가?

-

JavaScript는 크로스 플랫폼, 객체 지향 스크립트 언어입니다. JavaScript는 작고, 가벼운 언어입니다; JavaScript는 단독으로 쓰이는 언어로는 유용하지 않지만, 웹 브라우져 같은 다른 제품이나 프로그램에 포함하기 쉽습니다. 호스트 환경에서 JavaScript는 그 환경의 다른 개체(object)들을 프로그램적으로 제어하기 위해서 그들과 연결될 수 있습니다.

-

기본 JavaScript(core JavaScript)는 Array, Date, Math등 기본이 되는 개체들(core set of objects)과 연산자, 제어 구조, 문장등 언어의 기본 요소들(core set of language elements)을 포함하고 있습니다. 기본 JavaScript는 다른 개체를 추가함으로써 다양한 목적을 위해 확장될 수 있습니다. 예를 들면 다음과 같은 것들입니다.

-
  • "클라이언트쪽 JavaScript"는 브라우저(Navigatore 또는 다른 브라우저들)와 브라우저의 Document Object Model(DOM)을 제어할 수 있는 개체들을 제공함으로써 기본 언어를 확장합니다. 예를 들어, 클라이언트쪽 확장 기능은 응용프로그램이 HTML 폼에 요소를 두어 마우스 클릭이나 폼 입력, 페이지 이동 같은 사용자 이벤트에 반응할 수 있게 합니다.
  • "서버쪽 JavaScript"는 서버에서 JavaScript를 실행하는 데 연관되는 개체들을 제공함으로써 기본 언어를 확장합니다. 예를 들어, 서버쪽 확장 기능은 응용프로그램이 관계형 데이터베이스와 통신할 수 있게 하고, 응용프로그램의 호출들 사이에 연속성을 제공하거나, 서버에서 파일 조작을 수행할 수 있도록 해줍니다.
  • -
-

JavaScript의 LiveConnect 기능을 통해서, Java와 JavaScript 코드가 서로 통신할 수 있습니다. JavaScript에서 Java 개체를 초기화하여 개체의 공개 메소드와 필드에 접근할 수 있습니다. Java에서 JavaScript 개체, 속성(property), 메소드에 접근할 수 있습니다.

-

Netscape가 JavaScript를 개발했고 Netscape 브라우저에서 JavaScript가 가장 먼저 사용되었습니다.

-

JavaScript와 Java

-

JavaScript 와 Java 는 여러가지 면에서 비슷하지만 본질적으로 다릅니다. JavaScript는 Java 와 공통점이 있지만 Java 처럼 형(type)을 검사하지 않습니다. JavaScript는 Java 문법의 대부분과 제어흐름의 기본적인 개념들을 지원합니다.

-

Java의 클래스 선언으로 이루어지는 컴파일 타임 시스템에 대조적으로, JavaScript는 수, 불리언, 문자열 값을 나타내는 작은 규모의 자료형에 기반한 런타임 시스템을 지원합니다. JavaScript는 클래스 기반 개체 모델이 아닌 프로토타입 기반(prototype-based) 개체 모델을 갖고 있습니다. 프로토타입 기반 개체 모델은 동적인 상속을 제공합니다. 즉, 각각의 개체를 상속할 수 있는 것입니다. JavaScript는 또 특별히 선언시의 요구사항이 없는 함수도 지원합니다. 함수는 느슨하게 타입된 메소드로 실행됨으로써 개체의 속성이 될 수 있습니다.(Functions can be properties of objects, executing as loosely typed methods.)

-

Java에 비해 JavaScript는 형식이 자유로운 언어입니다. 모든 변수, 클래스, 메소드들을 꼭 선언 할 필요는 없습니다. 메소드가 public, private, protected 인지 고민해야할 필요가 없고, interface를 구현할 필요도 없습니다. 변수, 매개변수(parameter), 함수의 반환 형식도 명시적으로 지정할 필요가 없습니다.

-

Java는 클래스 기반 프로그래밍 언어로서, 빠른 실행과 형 안정성(type safety)을 위해 설계되었습니다. 형 안정성이란 예를 들면 Java에서 정수를 개체 참조로 변환할 수 없고, Java 바이트코드에 오류를 일으켜서 사적인(private) 메모리 공간에 접근할 수 없다는 말입니다. 자바의 클래스 기반 모델은 프로그램이 클래스와 클래스의 메소드로만 이루어진다는 의미입니다. Java의 클래스 상속과 엄격한 형 검사(strong typing)는 일반적으로 단단히 결합된 개체의 계층 구조를 필요로 합니다. 이런 요구사항이 JavaScript 프로그래밍에 비해 Java 프로그래밍을 더 복잡하게 만듭니다.

-

반면 JavaScript는 HyperTalk나 dBASE 같이 적은 줄수의 동적 타입 언어를 계승한 것입니다. 이런 스크립트 언어는 더 많은 사람들을 위한 프로그래밍 도구로서 제공되는데, 이 언어들이 문법이 쉽고, 내장되기에 쉬우며, 개체 생성에 요구 사항이 단순하기 때문입니다.

- -
JavaScript Java
개체 지향. 개체의 형식 사이에 구분이 없음. 프로토타입 메커니즘을 통해 상속을 지원하고, 어떤 개체에든지 동적으로 속성과 메소드를 추가할 수 있습니다. 클래스 기반. 개체는 클래스 계층 구조를 관통하는 상속을 통해서 클래스와 인스턴스(instance)로 나뉩니다. 클래스와 인스턴스에는 동적으로 속성과 메소드를 추가할 수 없습니다.
변수의 자료형을 선언하지 않음(동적 형 검사) 변수의 자료형을 반드시 선언해야 함(정적 형 검사)
Cannot automatically write to hard disk. Cannot automatically write to hard disk.
-

표(Table) 1.1: JavaScript 와 Java 비교
-
-Java와 JavaScript 사이의 차이점에 대해서 더 알고 싶으시면 개체 모델의 상세 내용을 보시기 바랍니다.

JavaScript와 ECMAScript 명세

-

Netscape가 JavaScript를 개발했고, Netscape 브라우저에서 가장 처음으로 사용되었습니다. 그러나 Ecma International - 정보와 통신 시스템을 표준화하기 위한 유럽 기구(공식적으로 ECMA - the European Computer Manufacturers Association으로 알려짐) - 과 Netscape가 공동으로 작업하여 기본 JavaScript에 기반하여 표준화되고 국제적인 프로그래밍 언어를 만들어냈습니다. JavaScript의 표준화된 버전은 ECMAScript라고 부르고, 표준을 지원하는 응용프로그램에서는 모두 동일하게 동작합니다. 회사들은 그들의 JavaScript 구현을 개발하기 위해서 공개된 표준 언어를 사용할 수 있습니다. ECMAScript 표준은 ECMA-262 명세에 문서화되어 있습니다.

-

ECMA-262 표준은 ISO (International Organization for Standardization, 국제 표준화기구)의 승인을 받아 ISO-16262가 되었습니다. Mozilla 웹사이트에서 ECMA-262의 PDF 문서를 얻을 수 있습니다. the Ecma International 웹사이트 에서도 명세를 찾을 수 있습니다. ECMAScript 명세는 World Wide Web Consortium (W3C)에서 표준화 한 Document Object Model(DOM)에 대해서는 설명하지 않습니다. DOM은 HTML 문서 개체들이 스크립트에 노출되는 방식을 정의합니다.

-

JavaScript 버전과 ECMAScript 판본 사이의 관계

-

Netscape는 ECMA와 밀접하게 작업하여 ECMAScript Specification(ECMA-262)를 만들었습니다. JavaScript 버전과 ECMAScript 판본(edition)들 사이의 관계가 아래 표에 설명되어 있습니다.

- -
JavaScript 버전 ECMAScript 판본과의 관계
JavaScript 1.1 ECMA-262, 1판은 JavaScript 1.1에 기초합니다.
JavaScript 1.2 JavaScript 1.2가 발표됐을 때 ECMA-262가 아직 완성되지 않았습니다. 다음과 같은 이유때문에 JavaScript 1.2는 ECMA-262 1판과 완벽하게 호환되지 않습니다.
  • Netscape는 JavaScript 1.2에 몇 가지 기능을 추가했으나, ECMA-262에서 고려하지 못했습니다.
  • ECMA-262는 두 가지 새 기능을 추가했습니다. 유니코드를 이용한 국제화, 모든 플랫폼에서의 동일한 동작. Date 개체 같은 JavaScript 1.2의 몇 가지 기능이 플랫폼에 의존적이었습니다.

JavaScript 1.3

JavaScript 1.3은 ECMA-262 1판과 완벽하게 호환됩니다.

JavaScript 1.3은 ==와 !=연산자를 제외하고는 JavaScript 1.2의 추가적인 기능을 그대로 유지하면서 JavaScript 1.2가 ECMA-262와 어긋나던 점들을 해결했습니다. ==, != 연산자는 ECMA-262에 맞추기 위해 수정되었습니다.

JavaScript 1.4

JavaScript 1.4는 ECMA-262 1판과 완벽하게 호환됩니다.

JavaScript 1.4가 발표되었을 때 ECMAScript 명세의 세 번째 버전이 아직 완성되지 않았습니다.

JavaScript 1.5 JavaScript 1.5는 ECMA-262 3판과 완벽하게 호환됩니다.
-

표 1.2: JavaScript 버전과 ECMAScript 판본
-
-참고: ECMA-262 2판은 1판에 편집상 사소한 변경과 버그 수정을 가한 판본입니다. 현재 ECMA의 TC39 워킹그룹에서 ECMAScript 4판을 작업하고 있습니다. 4판은 JavaScript 2.0과 대응될 것입니다.

-

JavaScript 기본 레퍼런스에서 ECMAScript 호환 기능을 보여줍니다.

-

JavaScript는 항상 ECMAScript Specification에 포함되지 않은 기능들을 포함할 것입니다. JavaScript는 추가적인 기능을 제공하지만 ECMAScript와 호환됩니다.

-

JavaScript 문서 vs ECMAScript 명세서

-

ECMAScript 명세는 ECMAScript를 구현하는데 필요한 요구사항을 모아놓은 것입니다. 이것은 우리가 JavaScript의 한 기능이 다른 ECMAScript 구현에서도 지원될 것인지 결정하는데 유용합니다. ECMAScript에서 지원하는 기능만을 사용하는 JavaScript 코드를 작성할 계획이라면 ECMAScript 명세를 살펴볼 필요가 있을 것입니다.

-

ECMAScript 문서는 스크립트 프로그래머를 돕기위해 작성된 것이 아닙니다. 스크립트 작성에 대한 정보를 얻으려면 JavaScript 문서를 보십시오.

-

JavaScript와 ECMAScript 용어

-

ECMAScript 명세는 JavaScript 프로그래머에게는 친숙하지 않은 용어와 문법을 사용하여 작성되었습니다. 비록 ECMAScript의 언어 설명이 다르긴 하지만 언어는 똑같습니다. JavaScript는 ECMAScript 명세에서 설명하는 모든 기능을 지원합니다.

-

JavaScript 문서는 JavaScript 프로그래머에게 적당한 언어의 측면을 설명합니다. 예를 들면 이렇습니다.

-
  • 전역 개체(Global Object)는 JavaScript 문서에서는 논의되지 않는데, 그것은 우리가 그 개체를 직접 사용할 일이 없기 때문입니다. 전역 개체에서 우리가 사용할 만한 메소드와 속성은 JavaScript 문서에서 논의되고 있기는 하지만 최상위(top-level) 함수와 속성이라고 부릅니다.
  • JavaScript 문서에서 매개변수가 없는 NumberString 개체 생성자는 논의되지 않고 있는데, 그것은 거의 사용할 일이 없기 때문입니다. Number의 인자없는 생성자는 +0을 반환하고, String의 인자없는 생성자는 ""(빈 문자열)을 반환합니다.
  • -
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:About", "Core_JavaScript_1.5_Guide:Values") }}

-

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/JavaScript_Overview", "fr": "fr/Guide_JavaScript_1.5/Aper\u00e7u_de_JavaScript", "ja": "ja/Core_JavaScript_1.5_Guide/JavaScript_Overview", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Podgl\u0105d_JavaScriptu" } ) }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/literals/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/literals/index.html deleted file mode 100644 index ee62d0cecf..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/literals/index.html +++ /dev/null @@ -1,175 +0,0 @@ ---- -title: Literals -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Literals -translation_of: Web/JavaScript/Guide/Grammar_and_types -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Literals ---- -

상수값(Literal)

-

JavaScript에서 값을 표현하기 위해 상수값을 사용할 수 있습니다. 그것은 변수가 아니라 고정된 값으로서 "문자 그대로(literally)" 스크립트에 값을 제공하는 것입니다. 이 절에서 다음과 같은 상수값에 대해서 설명하겠습니다.

-
    -
  • {{ Anch("배열 상수값") }}
  • -
  • {{ Anch("불리언 상수값") }}
  • -
  • {{ Anch("소수 상수값") }}
  • -
  • {{ Anch("정수") }}
  • -
  • {{ Anch("개체 상수값") }}
  • -
  • {{ Anch("문자열 상수값") }}
  • -
-

배열 상수값

-

배열 상수값은 대괄호([])안에 배열의 원소(element)를 0개 이상 나열한 것입니다. 배열 상수값으로 배열을 만드면 배열은 지정된 원소를 가지도록 초기화되고, 지정된 원소의 개수만큼의 길이를 갖게 됩니다.

-

다음 예제는 세 개의 원소를 가지고 길이가 3인 coffees 배열을 만드는 예제입니다.

-
coffees = ["French Roast", "Colombian", "Kona"]
-

참고 배열 상수값은 개체 초기화지정자(object initializer) 중의 하나입니다. 개체 초기화지정자 사용하기를 보십시오.

-

최상위 스크립트에서 상수값을 이용하여 배열을 만들면 JavaScript는 배열 상수값을 포함하는 표현식을 평가(evaluate)할 때마다 배열을 만듭니다. 또한, 함수 안에서 사용된 상수값은 함수가 호출될 때마다 생성됩니다.

-

배열 상수값은 Array 개체입니다. Array 개체에 대한 상세한 내용은 Array 개체를 보십시오.

-

배열 상수값의 추가적인 쉼표

-

배열 상수값에 모든 원소를 지정할 필요는 없습니다. 쉼표만 찍어 두면 값이 할당되지 않은 빈 공간을 가진 배열이 만들어집니다. 다음 예제는 fish 배열을 만듭니다.

-
fish = ["Lion", , "Angel"]
-

이 배열은 값을 가진 원소 두 개와 빈 원소 하나를 갖게됩니다. (fish{{ mediawiki.external(0) }}은 "Lion", fish{{ mediawiki.external(1) }}undefined, fish{{ mediawiki.external(2) }}는 "Angel"이라는 값을 가집니다.)

-

원소 목록 끝에 남겨둔 쉼표는 무시됩니다. 다음 예제에서 배열 길이는 3입니다. myList{{ mediawiki.external(3) }}은 만들어지지 않습니다. 그외에 목록에 있는 다른 쉼표들은 각각 새로운 원소를 나타냅니다.

-
myList = ['home', , 'school', ];
-

다음 예제에서 배열 길이는 4이고, myList{{ mediawiki.external(0) }}myList{{ mediawiki.external(2) }}는 비게 됩니다.

-
myList = [ , 'home', , 'school'];
-

다음 예제에서 배열 길이는 4이고 myList{{ mediawiki.external(1) }}myList{{ mediawiki.external(3) }}이 비게 됩니다. 오직 마지막 쉼표만 무시됩니다.

-
myList = ['home', , 'school', , ];
-

불리언 상수값

-

불리언 형은 두 가지 상수값을 가질 수 있는데, 그것은 truefalse입니다.

-

true, false라는 기본(primitive) 불리언 값과 true, false 값의 불리언 개체를 혼동하지 마십시오. 불리언 개체는 기본 불리언 데이터 형을 감싸는 역할을 할 뿐입니다. 더 많은 정보는 불리언 개체를 참조하십시오.

-

정수

-

10진수, 16진수, 8진수 정수를 쓸 수 있습니다. 10진수 정수 상수값은 0(영)으로 시작하지 않는 숫자의 나열입니다. 0(영)으로 시작하는 정수 상수값은 8진수입니다. 0x(또는 0X)로 시작하면 16진수입니다. 16진수는 0부터 9까지의 숫자와 a부터 f나 A부터 F까지의 문자를 포함할 수 있습니다. 8진수에는 0부터 7까지만 쓸 수 있습니다.

-

8진수 정수 상수값은 사용하지 말기를 추천하고 있으며, ECMA-262 표준 3판에서는 아예 제거되었습니다. 하위 호환성을 위해 JavaScript 1.5에서는 여전히 8진수 정수 상수값을 지원하고 있습니다.

-

몇 가지 정수 상수값을 예를 보여드리겠습니다.

-
0, 117, -345 (10진수)
-015, 0001, -077 (8진수)
-0x1123, 0x00111, -0xF1A7 (16진수 또는 "hex")
-
-

소수 상수값

-

소수 상수값은 이런 부분으로 이뤄집니다.

-
    -
  • 부호를 가질 수 있는(즉, "+"나 "-"로 시작할 수 있는) 10진수 정수,
  • -
  • 소수점("."),
  • -
  • 소수 부분(10진수),
  • -
  • 지수 부분
  • -
-

지수 부분은 "e"나 "E" 뒤에 숫자가 붙은 형태입니다. 숫자 앞에는 부호("+"나 "-")를 붙일 수도 있습니다. 소수 상수값은 적어도 하나의 숫자에 소수점 또는 지수 부분을 가져야 합니다.

-

소수 상수값의 몇 가지 예제를 보여드리겠습니다. 3.1415, -3.1E12, .1e12, 2E-12

-

개체 상수값

-

개체 상수값은 중괄호({}) 안에 특성(property) 이름과 그에 해당하는 값의 쌍을 나열한 것입니다. 문장(statement)의 시작 부분에 개체 상수값을 사용해서는 안됩니다. { 가 블럭의 시작을 나타내기 때문에, 에러가 나거나 의도하지 않은 동작을 보일 것입니다.

-

다음은 개체 상수값의 예입니다. car 개체의 첫 번째 원소는 myCar라는 특성을 정의하고 있습니다. 두 번째 원소는 getCar 특성을 정의하는데, (CarTypes("Honda"));라는 함수를 호출하고 있습니다. 세 번째 원소는 special 특성을 정의하는데에 Sales라는 변수를 사용합니다.

-
var Sales = "Toyota";
-
-function CarTypes(name) {
-   if(name == "Honda")
-      return name;
-   else
-      return "Sorry, we don't sell " + name + ".";
-}
-
-car = {myCar: "Saturn", getCar: CarTypes("Honda"), special: Sales}
-
-document.write(car.myCar); // Saturn
-document.write(car.getCar); // Honda
-document.write(car.special); // Toyota
-

개체 특성 이름에 정수 상수값이나 문자열 상수값을 사용할 수 있고, 개체 안에 다른 개체를 포함시킬 수도 있습니다. 다음 예제를 보십시오.

-
car = {manyCars: {a: "Saab", b: "Jeep"}, 7: "Mazda"}
-
-document.write(car.manyCars.b); // Jeep
-document.write(car[7]); // Mazda
-
-

다음 사항을 참고하십시오.

-
foo = {a: "alpha", 2: "two"}
-document.write (foo.a)    // alpha
-document.write (foo[2])   // two
-//document.write (foo.2)  // Error: missing ) after argument list
-//document.write (foo[a]) // Error: a is not defined
-document.write (foo["a"]) // alpha
-document.write (foo["2"]) // two
-
-

문자열 상수값

-

문자열 상수값은 큰따옴표(")나 작은따옴표(')로 둘러싸인 0개 이상의 문자들 입니다. 문자열은 같은 종류의 따옴표로 묶어야 합니다. 즉, 작은따옴표 둘로 묶거나, 큰따옴표 둘로 묶어야 한다는 말입니다. 문자열 상수값의 예를 보여드리겠습니다.

-
    -
  • "blah"
  • -
  • 'blah'
  • -
  • "1234"
  • -
  • "one line \n another line"
  • -
  • "John's cat"
  • -
-

우 리는 문자열 상수값에 String 개체의 모든 메소드를 호출할 수 있습니다. JavaScript는 자동으로 문자열 상수값을 임시 String 개체로 만들어서 메소드를 호출한 후, 임시 String 개체를 제거합니다. 문자열 상수값에 String.length 특성을 사용할 수도 있습니다. 이렇게 말입니다.

-
    -
  • "John's cat".length
  • -
-

우리가 특별하게 String 개체를 필요로 하는 경우가 아니라면 문자열 상수값을 사용해야만 합니다. String 개체에 대한 자세한 내용은 String 개체를 보십시오.

-
문자열에서 특수문자 사용하기
-

다음 예제에서 볼 수 있듯이 일반적인 문자뿐만 아니라 특수문자도 문자열에 쓸 수 있습니다.

-
"one line \n another line"
-

JavaScript 문자열에 사용할 수 있는 특수문자를 표로 나타낸 것입니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
문자의미
\bBackspace
\fForm feed
\nNew line
\rCarriage return
\tTab
\vVertical tab
\'Apostrophe or single quote
\"Double quote
\\Backslash character (\).
\XXX세 자리 까지의 8진수 "XXX"로 지정하는 Latin-1 인코딩의 문자. 0부터 377 사이. 예를 들어, \251은 저작권 기호의 8진수 표현입니다.
\xXX두 자리 까지의 16진수 "XX"로 지정하는 Latin-1 인코딩의 문자. 00부터 FF 사이. 예를 들어, \xA9는 저작권 기호의 16진수 표현입니다.
\uXXXX네 자리의 16진수 "XXXX"로 지정하는 유니코드 문자. 예를 들어, \u00A9는 저작권 기호의 유니코드 표현입니다. 유니코드 이스케이프 시퀀스를 보십시오.
-

표 2.1: JavaScript 특수문자

-
문자 이스케이프
-

표 2.1에 없는 문자에 대해서는 역슬래시가 무시됩니다. 그러나 이러한 기능은 사용하지 않기를 권장하므로 사용을 피해야만 합니다.

-

역슬래시를 앞에 붙이면 문자열 안에 따옴표를 넣을 수 있습니다. 이것은 따옴표 "이스케이프(escaping)"라고 알려져 있습니다.

-
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service."
-document.write(quote)
-
-

이 코드의 결과는 다음과 같습니다.

-
He read "The Cremation of Sam McGee" by R.W. Service.
-
-

문자열 안에 역슬래시 문자를 넣고 싶으면 역슬래시 문자를 이스케이프시켜야 합니다. 예를 들어, c:\temp 라는 경로를 문자열에 할당하고 싶으면 다음과 같이 하면 됩니다.

-
var home = "c:\\temp"
-
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Constants", "Core_JavaScript_1.5_Guide:Unicode") }}

-

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Literals", "fr": "fr/Guide_JavaScript_1.5/Constantes_litt\u00e9rales", "ja": "ja/Core_JavaScript_1.5_Guide/Literals", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Litera\u0142y" } ) }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/objects_and_properties/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/objects_and_properties/index.html deleted file mode 100644 index abe9ff83f4..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/objects_and_properties/index.html +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: Objects and Properties -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Objects_and_Properties ---- -

객체와 속성

-

자바스크립트 객체는 객체를 구성하는 속성을 가지고 있습니다. 속성에는 간단한 방법으로 접근할 수 있습니다.: -

-
객체이름.속성이름
-
-

객체 이름과 속성 이름 두 가지 모두에 대해 알기쉬운 예가 있습니다. 속성은 값을 지정하여 정의합니다. 예를 들어 myCar라는 객체가 있다면(객체가 이미 존재한다고 가정합니다.), make, model, year라는 속성에 다음과 같이 값을 지정할 수 있습니다. -

-
myCar.make = "Ford";
-myCar.model = "Mustang";
-myCar.year = 1969;
-
-

배열은 한 가지 변수 이름으로 결합되어 있는 연속된 값의 집합입니다. 자바스크립트에서 속성과 배열은 밀접한 관련이 있습니다; 말하자면 그 두 가지는 같은 데이터 구조에 다른 인터페이스라는 뜻입니다. 예를 들면 myCar 객체에 다음과 같이 접근할 수도 있습니다: -

-
myCar["make"] = "Ford";
-myCar["model"] = "Mustang";
-myCar["year"] = 1967;
-
-

이러한 배열의 종류는 연관 배열이라고 부릅니다. 왜냐하면 각각의 인덱스 요소가 문자열 값과 연관되어 있기 때문입니다. 이러한 방식에 대한 설명은 다음의 함수에 객체와 객체의 이름을 입력했을 때 객체의 속성을 표시해주는 다음과 같은 함수에서 알아볼 수 있습니다: -

-
function show_props(obj, obj_name) {
-   var result = "";
-   for (var i in obj)
-      result += obj_name + "." + i + " = " + obj[i] + "\n";
-   return result;
-}
-
-

결과적으로 call show_props(myCar, "myCar")라는 함수 호출은 다음과 같은 값을 반환합니다: -

-
myCar.make = Ford
-myCar.model = Mustang
-myCar.year = 1967
-
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Predefined_Functions:escape_and_unescape_Functions", "Core_JavaScript_1.5_Guide:Creating_New_Objects") }} -

{{ languages( { "fr": "fr/Guide_JavaScript_1.5/Objets_et_propri\u00e9t\u00e9s", "ja": "ja/Core_JavaScript_1.5_Guide/Objects_and_Properties", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Obiekty_i_w\u0142a\u015bciwo\u015bci" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/arithmetic_operators/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/arithmetic_operators/index.html deleted file mode 100644 index f8793b4cbc..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/arithmetic_operators/index.html +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: Arithmetic Operators -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Operators/Arithmetic_Operators -translation_of: Web/JavaScript/Guide/Expressions_and_Operators -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Operators/Arithmetic_Operators ---- -

산술 연산자

-

산술 연산자는 수(상수값이든지 변수든지)를 받아서 하나의 수를 반환합니다. 표준 산술 연산자는 더하기(+), 빼기(-), 곱하기(*), 나누기(/)입니다. 이 연산자들은 대부분의 다른 프로그래밍 언어에서 처럼 동작합니다. 예외적으로 / 연산자는 JavaScript에서 소수를 반환합니다. C나 Java 같은 다른 언어에서는 / 연산자가 소수 부분은 잘라버립니다. 예를 들면 이렇습니다. -

-
1/2 //returns 0.5 in JavaScript
-1/2 //returns 0 in Java
-
-

JavaScript는 다음 표에 나오는 산술 연산자를 제공합니다. -

- - - - - - - - - - - - - - - - - - - - - - - - - - -
연산자설명예제
%
(나머지)
2항(binary) 연산자. 두 피연산자의 나눗셈에서 나온 나머지를 반환합니다.12 % 5 returns 2.
++
(증가)
단항(unary) 연산자. 피연산자에 1을 더함. 전위 연산자(++x)를 사용하면 피연산자에 1을 더한 후 그 값을 반환합니다. 후위 연산자(x++)를 사용하면 피연산자에 1을 더하기 전에 피연산자의 값을 반환합니다.x가 3일 때, ++xx를 4로 만들고 4를 반환합니다. 반면 x++x를 4로 만들고 3을 반환합니다.
--
(감소)
단항 연산자. 피연산자에서 1을 뺌. 반환값은 증가 연산자와 동일한 방식으로 결정됩니다.x가 3일 때, --xx를 2로 만들고 2를 반환합니다. 반면 x--x를 2로 만들고 3을 반환합니다.
-
(단항 부정)
단항 연산자. 피연산자의 부호를 바꾼 값을 반환합니다.x가 3이면 -x는 -3을 반환합니다.
-

표 3.4: 산술 연산자 -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Operators:Comparison_Operators", "Core_JavaScript_1.5_Guide:Operators:Bitwise_Operators") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Operators/Arithmetic_Operators", "fr": "fr/Guide_JavaScript_1.5/Op\u00e9rateurs/Op\u00e9rateurs_arithm\u00e9tiques", "ja": "ja/Core_JavaScript_1.5_Guide/Operators/Arithmetic_Operators", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Operatory/Operatory_arytmetyczne" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/assignment_operators/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/assignment_operators/index.html deleted file mode 100644 index dbc284f12f..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/assignment_operators/index.html +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: Assignment Operators -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Operators/Assignment_Operators ---- -

할당 연산자

-

할당 연산자는 왼쪽 피연산자에 오른쪽 피연산자의 값을 할당합니다. 가장 기본적인 할당 연산자에는 등호(=)가 있는데, 왼쪽 피연산자의 값을 오른쪽 연산자에 할당합니다. 즉, x = y 라고 하면 y의 값이 x에 할당되는 것입니다.

-

다른 할당 연산자는 다음 표에서 보듯이 표준연산을 약식으로 쓰는 것입니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
약식 연산자의미
x += yx = x + y
x -= yx = x - y
x *= yx = x * y
x /= yx = x / y
x %= yx = x % y
x <<= yx = x << y
x >>= yx = x >> y
x >>>= yx = x >>> y
x &= yx = x & y
x ^= yx = x ^ y
x |= yx = x | y
-

표: 할당 연산자

-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Operators", "Core_JavaScript_1.5_Guide:Operators:Comparison_Operators") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/bitwise_operators/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/bitwise_operators/index.html deleted file mode 100644 index 3aed13da65..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/bitwise_operators/index.html +++ /dev/null @@ -1,102 +0,0 @@ ---- -title: Bitwise Operators -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Operators/Bitwise_Operators -translation_of: Web/JavaScript/Guide/Expressions_and_Operators -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Operators/Bitwise_Operators ---- -


-

-

비트 연산자

-

비트 연산자는 피연산자를 10진수나 16진수, 8진수로 다루지 않고 32개의 비트 집합으로 다룹니다. 예를 들어, 10진수 9는 2진수로 1001입니다. 비트 연산자는 2진수 표현으로 연산을 하지만 반환값은 JavaScript 표준 수 값으로 반환합니다. -

JavaScript의 비트 연산자를 다음 표에 요약했습니다. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
연산자사용법설명
비트 ANDa & b두 피연산자의 대응되는 비트가 모두 1이면 1을 반환.
비트 ORa | b두 피연산자의 대응되는 비트에서 둘 중 하나가 1이거나 모두 1인 경우 1을 반환.
비트 XORa ^ b두 피연산자의 대응되는 비트에서 둘 중 하나가 1이고, 둘 다 1이 아닐 경우 1을 반환.
비트 NOT~ a피연산자의 비트를 뒤집음.
왼쪽으로 이동a << ba의 2진수 표현을 b 비트만큼 왼쪽으로 이동함. 오른쪽은 0으로 채움.
부호 비트로 채우는 오른쪽 이동a >> ba의 2진수 표현을 b 비트만큼 오른쪽으로 이동함. 오른쪽 남는 비트는 버림.
0으로 채우는 오른쪽 이동a >>> ba의 2진수 표현을 b 비트만큼 오른쪽으로 이동함. 오른쪽 남는 비트는 버리고, 왼쪽은 0으로 채움.
-

표 3.5: 비트 연산자 -

-

비트 논리 연산자

-

개념적으로 비트 논리 연산자는 다음과 같이 동작합니다. -

-
  • 피연산자는 32비트 정수로 변환되어 비트의 나열로 표현됩니다. -
  • 두 피연산자의 비트를 같은 위치에 있는 것 끼리 짝을 짓습니다. -
  • 짝 지어진 각각의 쌍에 대해서 연산자를 적용하여 결과를 만들어냅니다. -
-

예를 들어, 9를 2진수로 쓰면 1001이고 15를 2진수로 표현하면 1111입니다. 두 값에 비트 연산을 적용하면 결과는 다음과 같습니다. -

-
  • 15 & 9 yields 9 (1111 & 1001 = 1001) -
  • 15 | 9 yields 15 (1111 | 1001 = 1111) -
  • 15 ^ 9 yields 6 (1111 ^ 1001 = 0110) -
-

비트 이동 연산자

-

비트 이동 연산자는 피연산자 두 개를 받습니다. 첫 번째는 이동하려는 수이고, 두 번째는 첫 번째 피연산자를 몇 비트나 이동시킬지 나타내는 비트 수입니다. 이동 방향은 사용된 연산자에 따라 다릅니다. -

이동 연산자는 피연산자를 32비트 정수로 변환하여 연산하고, 왼쪽 연산자와 같은 자료형으로 반환합니다. -

이동 연산자는 다음 표에 있습니다. -

- - - - - - - - - - - - - - - - - - - - -
연산자설명예제
<<
-(왼쪽 이동)
이 연산자는 첫 번째 피연산자의 비트를 지정된 수만큼 왼쪽으로 옮깁니다. 왼쪽으로 넘친 비트는 버립니다. 오른쪽 빈 자리는 0으로 채웁니다. 9<<2는 36을 반환합니다. 1001을 왼쪽으로 2비트 이동하면 100100이 되고 이것은 36이기 때문입니다.
>>
-(부호 비트로 채우는 오른쪽 이동)
이 연산자는 첫 번째 피연산자의 비트를 지정된 수 만큼 오른쪽으로 옮깁니다. 오른쪽으로 넘친 비트는 버립니다. 왼쪽 빈 자리는 원래 가장 왼쪽에 있던 비트 값으로 채웁니다.9>>2는 2를 반환합니다. 1001을 2비트 오른쪽으로 이동하면 10이 되는데 이것은 2이기 때문입니다. 비슷하게 -9>>2는 -3을 반환하는데, 부호가 유지되기 때문입니다.
>>>
-(0으로 채우는 오른쪽 이동)
이 연산자는 첫 번째 피연산자의 비트를 지정된 수 만큼 오른쪽으로 옮깁니다. 오른쪽으로 넘친 비트는 버립니다. 왼쪽 빈 자리는 0으로 채웁니다.19>>>2는 4를 반환합니다. 10011을 2비트 오른쪽으로 이동하면 100이 되기 때문입니다. 음수가 아닌 수에 대해서는 0을 채우는 오른쪽 이동이나 부호 비트로 채우는 오른쪽 이동이 똑같은 결과를 반환합니다.
-

표 3.6: 비트 이동 연산자 -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Operators:Arithmetic_Operators", "Core_JavaScript_1.5_Guide:Operators:Logical_Operators") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Operators/Bitwise_Operators", "fr": "fr/Guide_JavaScript_1.5/Op\u00e9rateurs/Op\u00e9rateurs_bit-\u00e0-bit", "ja": "ja/Core_JavaScript_1.5_Guide/Operators/Bitwise_Operators", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Operatory/Operatory_bitowe" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/index.html deleted file mode 100644 index 53b8e67492..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/index.html +++ /dev/null @@ -1,108 +0,0 @@ ---- -title: Operators -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Operators ---- -

연산자

-

JavaScript에는 다음과 같은 연산자 타입이 있습니다. 이 섹션은 연산자에 대해 기술하고 연산자 우선순위에 대한 정보를 제공합니다. -

- -

JavaScript는 이항연산자와 단항연산자를 모두 사용할 수 있습니다. 이항연산자는 두개의 피연산자(operand)를 가지며, 하나의 피연산자는 연산자 앞에 나머지 하나는 뒤에 위치합니다: -

-
operand1 operator operand2
-
-

예를 들자면, 3+4 혹은 x*y와 같은 것입니다. -

단항연산자는 연산자 앞 혹은 뒤쪽에 하나의 피연산자만 있으면 됩니다: -

-
operator operand
-
-

혹은 -

-
operand operator
-
-

예를 들자면, x++ 혹은 ++x와 같은 것입니다. -

덧붙여, JavaScript는 한개의 삼항연산자, 조건 연산자를 가지고 있습니다. 삼항 연산자는 세개의 피연산자가 필요합니다. -

-

연산자 우선순위

-

관련된 논의에 따라서, 아래의 표는 우선순위 순으로 내림차순 정렬되었습니다. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
연산자 타입사용하는 연산자
멤버 .  []
호출 / 인스턴스 생성 ()  new
부정/증감 !  ~  -  +  ++  --  typeof  void  delete
곱하기/나누기 *  /  %
더하기/빼기 +  -
비트 이동 <<  >>  >>>
관계 <  <=  >  >=  in  instanceof
같음 ==  !=  ===  !==
비트연산-and &
비트연산-xor ^
비트연산-or |
논리연산-and &&
논리연산-or ||
조건 ?:
할당 =  +=  -=  *=  /=  %=  <<=  >>=  >>>=  &=  ^=  |=
컴마,
-

표: 연산자 우선순위 -

이 표의 보다 자세한 버전은 레퍼런스 섹션에 있는 각 연산자별 상세한 추가 설명 링크를 참고하세요. -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Expressions", "Core_JavaScript_1.5_Guide:Operators:Assignment_Operators") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Operators", "fr": "fr/Guide_JavaScript_1.5/Op\u00e9rateurs", "ja": "ja/Core_JavaScript_1.5_Guide/Operators", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Operatory" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/logical_operators/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/logical_operators/index.html deleted file mode 100644 index edf5f640a5..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/logical_operators/index.html +++ /dev/null @@ -1,69 +0,0 @@ ---- -title: Logical Operators -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Operators/Logical_Operators -translation_of: Web/JavaScript/Guide/Expressions_and_Operators -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Operators/Logical_Operators ---- -

논리 연산자

-

논리 연산자는 주로 불리언(논리적) 값과 함께 사용됩니다. 그때 논리 연산자는 불리언 값을 반환합니다. 그러나 &&와 || 연산자는 실제로는 피연산자 중에 하나의 값을 반환하기 때문에, 이 연산자가 불리언 값이 아닌 값과 함께 사용되면 불리언 값이 아닌 값을 반환할 것입니다. 다음 표에 논리 연산자에 대해서 설명했습니다. -

- - - - - - - - - - - - - - - - - - - - - -
연산자사용법설명
&&expr1 && expr2(논리적 AND) expr1이 false로 변환될 수 있으면 expr1을 반환하고, 그렇지 않으면 expr2를 반환합니다. 그러므로 불리언 값과 같이 사용하면 피연산자 둘 모두가 true일 때 &&는 true를 반환하고 그렇지 않을 때는 false를 반환합니다.
||expr1 || expr2(논리적 OR) expr1이 true로 변환될 수 있으면 expr1을 반환하고 그렇지 않으면 expr2를 반환합니다. 그러므로 불리언 값과 같이 사용하면 ||는 피연산자 중에서 하나만 true이면 true를 반환합니다. 둘 다 false이면 false를 반환합니다.
!!expr(논리적 NOT) 피연산자가 true로 변환될 수 있으면 false를 반환합니다. 그렇지 않으면 true를 반환합니다.
-

표 3.7: 논리 연산자 -

false로 변환될 수 있는 표현식은 null, 0, 빈 문자열(""), undefined로 평가될 수 있는 표현식들입니다. -

다음 코드는 && 연산자를 사용하는 예를 보여줍니다. -

-
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
-
-

다음 코드는 || 연산자를 사용하는 예를 보여줍니다. -

-
o1=true || true       // t || t returns true
-o2=false || true      // f || t returns true
-o3=true || false      // t || f returns true
-o4=false || (3 == 4)  // f || f returns false
-o5="Cat" || "Dog"     // t || t returns Cat
-o6=false || "Cat"     // f || t returns Cat
-o7="Cat" || false     // t || f returns Cat
-
-

다음 코드는 ! 연산자를 사용하는 예를 보여줍니다. -

-
n1=!true              // !t returns false
-n2=!false             // !f returns true
-n3=!"Cat"             // !t returns false
-
-

단축 평가

-

논리 표현식이 왼쪽부터 오른쪽으로 평가되기 때문에 다음 규칙을 이용해서 "단축(short-circuit)" 평가를 할 수 있습니다. -

-
  • false && 아무 표현식은 false로 단축 평가 됩니다. -
  • true || 아무 표현식은 true로 단축 평가 됩니다. -
-

이 규칙을 따라 평가를 수행한다고 해서 피연산자를 모두 평가할 때와 결과가 달라지지 않습니다. 아무 표현식 부분은 평가되지 않기 때문에 아무런 부수 효과(side effect)도 일어나지 않는다는 것에 주의하십시오. -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Operators:Bitwise_Operators", "Core_JavaScript_1.5_Guide:Operators:String_Operators") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Operators/Logical_Operators", "fr": "fr/Guide_JavaScript_1.5/Op\u00e9rateurs/Op\u00e9rateurs_logiques", "ja": "ja/Core_JavaScript_1.5_Guide/Operators/Logical_Operators", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Operatory/Operatory_logiczne" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/special_operators/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/special_operators/index.html deleted file mode 100644 index f238901cab..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/special_operators/index.html +++ /dev/null @@ -1,229 +0,0 @@ ---- -title: Special Operators -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Operators/Special_Operators -translation_of: Web/JavaScript/Guide/Expressions_and_Operators -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Operators/Special_Operators ---- -

특수 연산자

-

JavaScript 다음과 같은 특별한 연산자를 제공합니다. -

-
  • {{ Anch("조건 연산자") }} -
  • {{ Anch("쉼표 연산자") }} -
  • {{ Anch("delete") }} -
  • {{ Anch("in") }} -
  • {{ Anch("instanceof") }} -
  • {{ Anch("new") }} -
  • {{ Anch("this") }} -
  • {{ Anch("typeof") }} -
  • {{ Anch("void") }} -
-

조건 연산자

-

조건 연산자는 JavaScript에서 유일하게 세 개의 피연산자를 사용하는 연산자입니다. 연산자는 조건에 따라 둘 중에 하나의 값을 가질 수 있습니다. 문법은 이렇습니다. -

-
condition ? val1 : val2
-
-

condition이 true이면 연산자는 val1의 값을 갖습니다. 그렇지 않으면 val2의 값을 갖습니다. 다른 표준 연산자를 사용할 수 있는 곳이면 어디든지 조건 연산자를 사용할 수 있습니다. -

-
status = (age >= 18) ? "adult" : "minor"
-
-

이 문장은 age가 18이거나 더 큰 경우에 status 변수에 "adult"라는 값을 할당합니다. 그렇지 않으면 "minor"라는 값을 할당합니다. -

-

쉼표 연산자

-

쉼표 연산자(,)는 단순히 피연산자 둘을 모두 평가하고 두 번째 피연산자의 값을 반환하는 연산자입니다. 이 연산자는 주로 for 반복문에서 변수 여러 개가 매번 업데이트 되게 하는데 쓰입니다. -

예를 들어 a가 각각 10줄의 원소를 가지는 2차원 배열일 때, 다음 코드에서는 변수 두 개를 한 번에 바꾸기 위해서 쉼표 연산자를 사용하고 있습니다. 이 코드는 배열의 대각선 원소를 출력합니다. -

-
for (var i=0, j=9; i <= 9; i++, j--)
-   document.writeln("a["+i+"]["+j+"]= " + a[i][j])
-
-

delete

-

delete는 개체(object), 개체의 속성(property), 배열의 특정 인덱스에 있는 원소(element)를 지우는 연산자입니다. 문법은 이렇습니다. -

-
delete objectName
-delete objectName.property
-delete objectName[index]
-delete property // with 문장 안에서만 유효합니다
-
-

objectName은 개체 이름이고, property는 개체에 존재하는 속성이고, index는 배열의 원소 위치를 나타내는 정수입니다. -

네 번째 형식은 개체의 속성을 지우는 코드인데, with 문장 안에서만 사용할 수 있습니다. -

암시적으로 선언된 변수를 지울 때는 delete 연산자를 사용할 수 있지만 var 문장을 이용해서 선언된 변수는 지울 수 없습니다. -

delete 연산자 실행이 성공하면, 속성이나 원소가 undefined로 설정됩니다. delete 연산자는 실행이 가능하면 true를 반환하고, 불가능하면 false를 반환합니다. -

-
x=42
-var y= 43
-myobj=new Number()
-myobj.h=4      // h라는 속성을 만듭니다
-delete x       // returns true (암시적으로 선언된 변수는 지울 수 있습니다)
-delete y       // returns false (var로 선언한 변수는 지울 수 없습니다)
-delete Math.PI // returns false (미리 정의된 속성은 지울 수 없습니다)
-delete myobj.h // returns true (사용자 정의 속성은 지울 수 있습니다)
-delete myobj   // returns true (암시적으로 선언되었으므로 지울 수 있습니다)
-
-

배열의 원소를 지우기
-배열의 원소를 지울 때, 배열의 길이에는 변화가 없습니다. 예를 들어, a{{ mediawiki.external(3) }}, a{{ mediawiki.external(4) }}를 지우더라도 a{{ mediawiki.external(4) }}와 a{{ mediawiki.external(3) }}은 여전히 정의되지 않습니다. -

delete 연산자가 배열 원소를 제거할 때 원소는 더이상 배열에 존재하지 않습니다. 아래 예제에서 trees{{ mediawiki.external(3) }}은 delete로 제거되었습니다. -

-
trees=new Array("redwood","bay","cedar","oak","maple")
-delete trees[3]
-if (3 in trees) {
-   // 이 블록은 실행되지 않습니다.
-}
-
-

배열 원소가 존재하긴 하지만 정의되지 않은 값을 가지도록 하고 싶다면 delete 연산자 대신 undefined 키워드를 사용하십시오. 다음 예제에서 trees{{ mediawiki.external(3) }}undefined 값을 할당했지만 배열 요소는 여전히 존재합니다. -

-
trees=new Array("redwood","bay","cedar","oak","maple")
-trees[3]=undefined
-if (3 in trees) {
-   // 이 블록은 실행됩니다.
-}
-
-

in

-

in 연산자는 지정된 속성이 지정된 개체에 있으면 true를 반환합니다. 문법은 이렇습니다. -

-
propNameOrNumber in objectName
-
-

propNameOrNumber은 속성 이름을 나타내는 문자열이나 배열 인덱스를 나타내는 수이고, objectName은 개체 이름입니다. -

다음 예제는 in 연산자의 몇 가지 사용법을 보여줍니다. -

-
// 배열
-trees=new Array("redwood","bay","cedar","oak","maple")
-0 in trees        // returns true
-3 in trees        // returns true
-6 in trees        // returns false
-"bay" in trees    // returns false (원하는 인덱스를 지정해야 하는데,
-                  // 그 인덱스에 있는 값을 지정하면 안됩니다.)
-"length" in trees // returns true (length는 배열의 속성입니다.)
-
-// 미리 정의된 개체
-"PI" in Math          // returns true
-myString=new String("coral")
-"length" in myString  // returns true
-
-// 사용자 개체
-mycar = {make:"Honda",model:"Accord",year:1998}
-"make" in mycar  // returns true
-"model" in mycar // returns true
-
-

instanceof

-

instanceof는 지정된 개체가 지정된 개체 형식이면 true를 반환합니다. 문법은 이렇습니다. -

-
objectName instanceof objectType
-
-

objectNameobjectType과 비교할 개체의 이름이고, objectType은 개체 형식으로 DateArray 같은 것입니다. -

실행중에 개체의 형식을 알고 싶으면 instanceof를 사용하면 됩니다. 예를 들어 예외를 처리할 때, 발생한 예외의 형식에 따라 서로 다른 예외 처리 코드를 실행할 수 있습니다. -

다음 코드에서 theDayDate 개체인지 결정하기 위해서 instanceof를 사용합니다. theDayDate 개체이기 때문에 if문 안에 있는 문장이 실행됩니다. -

-
theDay=new Date(1995, 12, 17)
-if (theDay instanceof Date) {
-   // 실행할 문장
-}
-
-

new

-

사용자 정의 개체 형식이나 Array, Boolean, Date, Function, Image, Number, Object, Option, RegExp, String 같이 미리 정의된 개체 형식의 인스턴스를 만들 때 new 연산자를 사용합니다. 서버에서는 DbPool, Lock, File, SendMail 등을 만들 때 사용할 수 있습니다. new는 다음과 같이 사용합니다. -

-
objectName = new objectType ( param1 [,param2] ...[,paramN] )
-
-

개체 초기화 지정자 사용하기에 설명한 것처럼 개체 초기화 지정자를 이용해서 개체를 만들 수도 있습니다. -

더 많은 정보를 얻으려면 JavaScript 레퍼런스의 new 연산자 페이지를 보시기 바랍니다. -

-

this

-

현재 개체를 참조할 때 this 키워드를 사용합니다. 일반적으로 this는 메소드를 호출하는 개체를 참조합니다. 다음과 같이 사용하면 됩니다. -

-
this[.propertyName]
-
-

예제 1.
-개체의 value 속성이 높거나 낮은 값을 가지는지 검증하는 validate라는 함수가 있다고 가정합시다. -

-
function validate(obj, lowval, hival) {
-   if ((obj.value < lowval) || (obj.value > hival))
-      alert("Invalid Value!")
-}
-
-

이제 우리는 폼의 각 요소의 onChange 이벤트 핸들러에서 validate 함수를 호출하면서, this를 이용하여 스스로를 함수에 전달할 수 있습니다. -

-
<B>Enter a number between 18 and 99:</B>
-<INPUT TYPE = "text" NAME = "age" SIZE = 3
-   onChange="validate(this, 18, 99)">
-
-

예제 2.
-form 속성과 결합되면, this는 현재 개체가 포함된 폼을 참조할 수 있습니다. 다음 예제에서 myForm 폼은 Text 개체와 버튼을 포함하고 있습니다. 사용자가 버튼을 클릭하면 Text 개체의 값이 폼 이름으로 설정됩니다. 버튼의 onClick 이벤트 핸들러는 부모 폼인 myForm을 참조하기 위해서 this.form을 사용하고 있습니다. -

-
<FORM NAME="myForm">
-Form name:<INPUT TYPE="text" NAME="text1" VALUE="Beluga">
-<P>
-<INPUT NAME="button1" TYPE="button" VALUE="Show Form Name"
-   onClick="this.form.text1.value=this.form.name">
-</FORM>
-
-

typeof

-

typeof 연산자는 둘 중 한 가지 방법으로 사용할 수 있습니다. -

-
1. typeof operand
-2. typeof (operand)
-
-

typeof 연산자는 피연산자의 평가되지 않은 형식을 나타내는 문자열을 반환합니다. 피연산자는 string, variable, keyword, object 등의 타입을 반환하게 됩니다. 괄호는 선택적입니다. -

우리가 이런 변수를 정의했다고 해봅시다. -

-
var myFun = new Function("5+2")
-var shape="round"
-var size=1
-var today=new Date()
-
-

typeof는 이 변수들에 대해서 다음과 같은 결과를 반환할 것입니다. -

-
typeof myFun is function
-typeof shape is string
-typeof size is number
-typeof today is object
-typeof dontExist is undefined
-
-

truenull 키워드에 대해서 typeof 연산자는 다음과 같은 결과를 반환합니다. -

-
typeof true is boolean
-typeof null is object
-
-

수와 문자열에 대해서 typeof 연산자는 다음과 같은 결과를 반환합니다. -

-
typeof 62 is number
-typeof 'Hello world' is string
-
-

속성 값에 대해서 typeof 연산자는 속성이 포함하고 있는 값의 형식을 반환합니다. -

-
typeof document.lastModified is string
-typeof window.length is number
-typeof Math.LN2 is number
-
-

메소드와 함수에 사용하면 typeof 연산자는 다음과 같은 결과를 반환합니다. -

-
typeof blur is function
-typeof eval is function
-typeof parseInt is function
-typeof shape.split is function
-
-

미리 정의된 개체들에 대해서 typeof 연산자는 다음과 같은 결과를 반환합니다. -

-
typeof Date is function
-typeof Function is function
-typeof Math is function
-typeof Option is function
-typeof String is function
-
-

void

-

void 연산자는 다음과 같이 사용할 수 있습니다. -

-
1. void (expression)
-2. void expression
-
-

void 연산자는 표현식이 값을 반환하지 않으면서 평가되어야 한다고 지정하는데 사용됩니다. expression은 평가하려는 JavaScript 표현식입니다. 표현식을 감싸는 괄호는 선택적이지만 사용하는 쪽이 더 좋은 스타일입니다. -

표현식을 하이퍼텍스트 링크로 지정하기 위해서 void 연산자를 사용할 수 있습니다. 표현식이 평가되기는 하지만 현재 문서 대신 로드되지는 않습니다. -

아래 코드는 사용자가 클릭할 때 아무 동작도 하지 않는 하이퍼텍스트 링크를 만듭니다. 사용자가 링크를 클릭하면 void(0)는 정의되지 않은 것(undefined)으로 평가되고 JavaScript에서 아무런 효과가 없습니다. -

-
<A HREF="javascript:void(0)">Click here to do nothing</A>
-
-

다음 코드는 클릭하면 폼을 제출하는 하이퍼텍스트 링크를 만듭니다. -

-
<A HREF="javascript:void(document.form.submit())">
-Click here to submit</A>
-
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Operators:String_Operators", "Core_JavaScript_1.5_Guide:Creating_a_Regular_Expression") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Operators/Special_Operators", "fr": "fr/Guide_JavaScript_1.5/Op\u00e9rateurs/Op\u00e9rateurs_sp\u00e9ciaux", "ja": "ja/Core_JavaScript_1.5_Guide/Operators/Special_Operators", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Operatory/Operatory_specjalne" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/string_operators/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/string_operators/index.html deleted file mode 100644 index fc39b5a34f..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/operators/string_operators/index.html +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: String Operators -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Operators/String_Operators -translation_of: Web/JavaScript/Guide/Expressions_and_Operators -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Operators/String_Operators ---- -

문자열 연산자

-

문자열 값에 사용할 수 있는 비교 연산자 외에도 연결 연산자(+)가 있는데, 이 연산자는 두 문자열 값을 연결한 새로운 문자열 값을 반환합니다. 예를 들어, "my " + "string""my string"라는 문자열을 반환합니다. -

축약된 할당 연산자인 += 또한 문자열 연결에 사용할 수 있습니다. 예를 들어 mystring 변수가 "alpha"라는 값을 가지고 있을 때, mystring += "bet"은 "alphabet"으로 평가되고, 그 값이 mystring에 할당됩니다. -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Operators:Logical_Operators", "Core_JavaScript_1.5_Guide:Operators:Special_Operators") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Operators/String_Operators", "fr": "fr/Guide_JavaScript_1.5/Op\u00e9rateurs/Op\u00e9rateurs_li\u00e9s_aux_cha\u00eenes", "ja": "ja/Core_JavaScript_1.5_Guide/Operators/String_Operators", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Operatory/Operacje_na_\u0142a\u0144cuchach" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/array_object/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/array_object/index.html deleted file mode 100644 index 1f6ef48f3a..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/array_object/index.html +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: Array Object -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Predefined_Core_Objects/Array_Object ---- -

Array 개체

-

JavaScript에는 명시적인 배열 자료형이 없습니다. 하지만 배열을 다루기 위해서 Array 개체와 그 개체의 메소드를 이용할 수 있습니다. Array 개체에는 다양한 방법으로 배열을 다루기 위한 메소드들이 있는데, 배열을 합치거나, 순서를 뒤집거나, 정렬하는 등의 작업을 할 수 있습니다. 배열 길이를 알 수 있는 속성과 정규 표현식에 사용할 수 있는 속성들이 있습니다. - - 배열 - 은 이름이나 색인으로 참조할 수 있는 값들을 모아놓은, 값의 순서가 유지되는 집합입니다. 예를 들어, 우리는 고용 번호로 색인된 고용인의 이름을 담고 있는 emp라는 배열을 만들 수 있습니다. 이 때 emp{{ mediawiki.external(1) }}는 1번 고용인, emp{{ mediawiki.external(2) }} 2번 고용인이 되는 것입니다.

-

 

-

배열 만들기

-

Array 개체는 이렇게 만들 수 있습니다.

-
1. arrayObjectName = new Array(element0, element1, ..., elementN)
-2. arrayObjectName = new Array(arrayLength)
-
-

arrayObjectName은 새 개체의 이름이거나 존재하는 다른 개체의 속성 이름입니다. Array 개체의 속성이나 메소드를 이용할 때는 arrayObjectName은 존재하는 Array 개체 이름이거나 존재하는 다른 개체의 속성입니다.

-

element0, element1, ..., elementN는 배열의 원소(element)가 될 값들입니다. 이런 식으로 지정하면, 나열한 값들을 원소로 가지고, 길이는 값의 개수인 배열이 만들어집니다.

-

arrayLength는 배열의 초기 길이입니다. 다음 코드는 원소 다섯 개를 가지는 배열을 만듭니다.

-
billingMethod = new Array(5)
-
-

배열 상수값 또한 Array 개체입니다. 예를 들어, 다음과 같은 상수값은 Array 개체입니다. 배열 상수값에 대한 자세한 내용은 배열 상수값을 보시기 바랍니다.

-
coffees = ["French Roast", "Columbian", "Kona"]
-
-

배열에 원소 넣기

-

원소에 값을 할당함으로써 배열에 값을 넣을 수 있습니다.

-
emp[1] = "Casey Jones"
-emp[2] = "Phil Lesh"
-emp[3] = "August West"
-
-

배열을 만들 때 값을 넣을 수도 있습니다.

-
myArray = new Array("Hello", myVar, 3.14159)
-
-

배열 원소 참조하기

-

배열 원소의 순서를 나타내는 숫자로 원소를 참조할 수 있습니다. 예를 들어 다음과 같은 배열을 만들었다고 해봅시다.

-
myArray = new Array("Wind","Rain","Fire")
-
-

그러면 첫 번째 원소는 myArray{{ mediawiki.external(0) }}으로 참조할 수 있고, 두 번째 원소는 myArray{{ mediawiki.external(1) }}로 참조할 수 있습니다.

-

원소의 색인은 영(0)부터 시작하지만 배열 길이(예를 들면 myArray.length)는 배열의 원소 개수를 나타냅니다.

-

 

-

Array 개체의 메소드

-

Array 개체는 다음과 같은 메소드들을 가지고 있습니다.

-
    -
  • concat 메소드는 두 배열을 합쳐서 새 배열 하나를 반환합니다.
  • -
-
myArray = new Array("1","2","3")
-myArray = myArray.concat("a", "b", "c"); // myArray는 ["1", "2", "3", "a", "b", "c"]이 되었습니다.
-
-
    -
  • join(deliminator = ",") 메소드는 배열의 모든 원소를 문자열로 바꿔서 하나의 문자열을 만들어줍니다.
  • -
-
myArray = new Array("Wind","Rain","Fire")
-list = myArray.join(" - "); // list는 "Wind - Rain - Fire"입니다.
-
-
    -
  • pop 메소드는 배열의 마지막 원소를 배열에서 제거하고 그 원소를 반환합니다.
  • -
-
myArray = new Array("1", "2", "3");
-last=myArray.pop(); // MyArray는 ["1", "2"], last = "3"이 되었습니다.
-
-
    -
  • push 메소드는 하나 또는 그 이상의 원소를 배열 끝에 추가하고, 추가된 마지막 원소를 반환합니다.
  • -
-
myArray = new Array("1", "2");
-myArray.push("3"); // MyArray는 ["1", "2", "3"]이 되었습니다.
-
-
    -
  • reverse 메소드는 원소의 순서를 뒤집어서 첫 번째 원소가 마지막 원소가 되고, 마지막 원소가 첫 번째 원소가 되도록 합니다.
  • -
-
myArray = new Array ("1", "2", "3");
-myArray.reverse(); // myArray = [ "3", "2", "1" ]이 되었습니다.
-
-
    -
  • shift 메소드는 첫 번째 요소를 배열에서 제거하고, 그 원소를 반환합니다.
  • -
-
myArray = new Array ("1", "2", "3");
-first=myArray.shift(); // MyArray는 ["2", "3"], first는 "1"이 되었습니다.
-
-
    -
  • slice (start_index, upto_index) 메소드는 배열의 일부분을 추출하여 새 배열을 반환합니다.
  • -
-
myArray = new Array ("a", "b", "c", "d", "e");
-myArray = myArray.slice(1,4); //색인 1부터 색인 4 바로 앞까지의 원소를 추출해서 [ "b", "c", "d" ]를 반환합니다.
-
-
    -
  • splice(index, count_to_remove, addelement1, addelement2, ...) 메소드는 배열에 원소를 추가하거나 배열에서 원소를 제거합니다.
  • -
-
myArray = new Array ("1", "2", "3", "4", "5");
-myArray.splice(1,3,"a","b","c", "d"); // MyArray는 ["1", "a", "b", "c", "d", "5"]가 되었습니다.
-// 이 코드는 색인 1(즉 "2")부터 원소 세 개를 제거하고, 그 자리에 원소를 추가합니다.
-
-
    -
  • sort 메소드는 원소를 정렬합니다.
  • -
-
myArray = new Array("Wind","Rain","Fire")
-myArray.sort(); // 배열을 정렬했으므로 myArrray = [ "Fire", "Rain", "Wind" ]가 되었습니다.
-
-

sort 메소드에 배열을 어떻게 정렬할지 결정하는 콜백 함수를 전해줄 수 있습니다. 그 함수는 두 값을 비교해서 다음 셋 중 하나를 반환해야 합니다.

-
    -
  • 정렬할 때 a가 b보다 작다면 -1(또는 임의의 음수)를 반환
  • -
  • 정렬할 때 a가 b보다 크다면 1(또는 임의의 양수)를 반환
  • -
  • a와 b가 같으면 0을 반환
  • -
-

예를 들어 다음 코드는 원소의 마지막 글자를 기준으로 배열을 정렬합니다.

-
var sortFn = function(a,b){
-    if (a[a.length - 1] < b[b.length - 1]) return -1;
-    if (a[a.length - 1] > b[b.length - 1]) return 1;
-    if (a[a.length - 1] == b[b.length - 1]) return 0;
-    }
-myArray.sort(sortFn); // 배열을 정렬했으므로 myArray = ["Wind","Fire","Rain"]가 되었습니다.
-
-
    -
  • unshift 메소드는 하나 또는 그 이상의 원소를 배열 앞에 추가하고 배열의 새 길이를 반환합니다.
  • -
-

2차원 배열

-

다음 코드는 2차원 배열을 만듭니다.

-
a = new Array(4)
-for (i=0; i < 4; i++) {
-   a[i] = new Array(4)
-   for (j=0; j < 4; j++) {
-      a[i][j] = "["+i+","+j+"]"
-   }
-}
-
-

바로 위 코드는 이런 배열을 만들어냅니다.

-
Row 0:[0,0][0,1][0,2][0,3]
-Row 1:[1,0][1,1][1,2][1,3]
-Row 2:[2,0][2,1][2,2][2,3]
-Row 3:[3,0][3,1][3,2][3,3]
-
-

배열과 정규 표현식

-

배열이 정규 표현식과 문자열을 매치한 결과로 생성되었을 때, 그 배열은 매치에 대한 정보를 제공하는 속성과 원소를 포함하고 있습니다. RegExp.exec, String.match, String.split의 반환 값은 배열입니다. 정규 표현식과 관련된 배열 사용에 대한 정보를 얻으려면 4장 정규 표현식을 보십시오.

-

{{ PreviousNext("Core_JavaScript_1.5_Guide:Predefined_Core_Objects", "Core_JavaScript_1.5_Guide:Predefined_Core_Objects:Boolean_Object") }}

diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/index.html deleted file mode 100644 index d8d0156dc2..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/predefined_core_objects/index.html +++ /dev/null @@ -1,21 +0,0 @@ ---- -title: Predefined Core Objects -slug: >- - Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Predefined_Core_Objects -translation_of: Web/JavaScript/Guide -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Predefined_Core_Objects ---- -

미리 정의된 기본 개체

-

이 절에서는 기본 JavaScrip에 미리 정의된 개체에 대해서 설명하겠습니다. -

- -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Creating_New_Objects:Deleting_Properties", "Core_JavaScript_1.5_Guide:Predefined_Core_Objects:Array_Object") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Predefined_Core_Objects", "fr": "fr/Guide_JavaScript_1.5/Objets_pr\u00e9d\u00e9finis", "ja": "ja/Core_JavaScript_1.5_Guide/Predefined_Core_Objects", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Obiekty_predefiniowane" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/unicode/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/unicode/index.html deleted file mode 100644 index 9c97d9cf82..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/unicode/index.html +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Unicode -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Unicode -translation_of: Web/JavaScript/Guide/Grammar_and_types -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Unicode ---- -

유니코드

-

유니코드는 세계의 주요한 문자 언어를 교환하고 표현하기 위한 문자-코딩 표준입니다. 유니코드는 아메리카, 유럽, 중동, 아프리카, 인도, 아시아, 태평양 지역(Pacifica)의 언어를 포함하며 고문자와 기술 분야 기호들도 포함합니다. 유니코드는 공통적인 기술 분야, 수학 분야 기호 뿐만 아니라 여러 언어를 포함한 텍스트의 교환, 처리, 표현을 지원합니다. 유니코드는 나라마다 서로 다른 문자 표준으로 인해서 여러 언어를 포함했을 때 발생하는 국제화 문제를 해결할 수 있기를 희망합니다. 하지만 아직은 모든 현대 문자, 고대 문자를 지원하지는 못합니다. -

유니코드 문자 집합은 알려진 모든 인코딩을 위해 사용될 수 있습니다. 유니코드는 ASCII (American Standard Code for Information Interchange, 정보 교환을 위한 미국 표준 코드) 문자 집합을 본떠 만들어졌습니다. 각각의 문자에 숫자와 이름을 부여한 것입니다. 문자 인코딩은 문자의 정체성(identity)과 숫자 값(코드 위치)와 함께 숫자 값의 비트 표현을 명시합니다. 16비트 숫자 값(코드 값)은 U+0041처럼 접두어 U뒤에 16진수를 붙여서 표시합니다. 이 값의 유일한 이름은 LATIN CAPITAL LETTER A입니다. -

JavaScript 1.3 이전 버전은 유니코드를 지원하지 않습니다. -

-

유니코드와 ASCII 및 ISO 사이의 호환성

-

유니코드는 ISO 10646의 부분집합인 국제 표준 ISO/IEC 10646-1; 1993과 완벽하게 호환됩니다. -

몇몇 인코딩 표준(UTF-8, UTF-16, ISO UCS-2를 포함하는)들이 실제 비트 값으로 유니코드를 표현하기 위해 사용됩니다. -

UTF-8 인코딩은 ASCII 문자와 호환되며 많은 프로그램이 UTF-8을 지원합니다. 앞쪽 128개의 유니코드 문자는 ASCII 문자에 대응되며 같은 바이트 값을 가지고 있습니다. U+0020부터 U+007E 까지의 유니코드 문자는 ASCII 문자 0x20 부터 0x7E 까지와 동일합니다. 라틴 알파벳을 지원하고 7비트 문자 집합을 사용하는 ASCII와는 달리, UTF-8은 한 문자를 위해서 한 개부터 네 개 사이의 8진수(octet)를 사용합니다. ("8진수"는 바이트 또는 8비트를 의미합니다.) 이 방법으로 수백만개의 문자를 표현할 수 있습니다. 다른 인코딩 표준인 UTF-16은 유니코드 문자를 표현하기 위해 2바이트를 사용합니다. 이스케이프 시퀀스를 이용하여 UTF-16은 4바이트를 써서 모든 유니코드 범위를 표현합니다. ISO UCS-2 (Universal Character Set, 세계 문자 집합)은 2바이트를 사용합니다. -

JavaScript와 Navigator가 UTF-8/유니코드를 지원한다는 것은 우리가 비 라틴 문자와 국제화되고 지역화된 문자에다 특수한 기술 분야 기호까지 JavaScript 프로그램에 쓸 수 있다는 것을 의미합니다. 유니코드는 여러 언어를 포함한 텍스트를 인코딩할 수 있는 표준적인 방법을 제공합니다. UTF-8 인코딩이 ASCII와 호환되기 때문에, ASCII 문자를 프로그램에 사용할 수 있습니다. 우리는 JavaScript의 주석, 문자열 리터럴, 식별자(identifier), 정규 표현식에 비 ASCII 유니코드 문자를 쓸 수 있습니다. -

-

유니코드 이스케이프 시퀀스

-

우리는 문자열 리터럴, 정규 표현식, 식별자에 유니코드 이스케이프 시퀀스를 사용할 수 있습니다. 이스케이프 시퀀스는 ASCII 문자 여섯 개로 이루어지는데, \u 뒤에 16진수를 표현하는 숫자 네 개가 붙은 모양입니다. 예를 들어 \u00A9는 저작권 기호를 나타냅니다. JavaScript에서 모든 유니코드 이스케이프 시퀀스는 문자 한 개로 인식됩니다. -

다음의 코드는 저작권 문자와 "Netscape Communications"라는 문자열을 반환합니다. -

-
x="\u00A9 Netscape Communications"
-

다음의 표는 자주 사용되는 특수 문자의 유니코드 값을 모은 것입니다. -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
분류유니코드 값이름형식화된 이름(Format name)
공백 문자\u0009Tab<TAB>
 \u000BVertical Tab<VT>
 \u000CForm Feed<FF>
 \u0020Space<SP>
줄 끝 문자\u000ALine Feed<LF>
 \u000DCarriage Return<CR>
그 외 유니코드 이스케이프 시퀀스\u0008Backspace<BS>
 \u0009Horizontal Tab<HT>
 \u0022Double Quote"
 \u0027Single Quote'
 \u005C Backslash\
-

표 2.2: 특수 문자의 유니코드 값 -

JavaScript에서 유니코드 이스케이프 시퀀스는 Java와 다릅니다. JavaScript에서, 이스케이프 시퀀스가 특수 문자로 먼저 해석되지 않습니다. 예를 들어, 줄 끝 이스케이프 시퀀스가 문자열에 포함되어 있어도 함수에 의해 해석되기 전까지는 문자열을 자르지 않습니다. 주석에 포함된 이스케이프 시퀀스는 모두 무시됩니다. Java에서는 한 줄 주석에 이스케이프 시퀀스가 있으면 유니코드 문자로 해석됩니다. 문자열 리터럴에서 Java 컴파일러는 이스케이프 시퀀스를 먼저 해석합니다. 예를 들어 줄 끝 이스케이프 문자(즉 \u000A)가 Java에서 사용되면 문자열 리터럴을 끝나게 합니다. Java에서는 줄 끝 문자가 문자열 리터럴에 포함될 수 없으므로, 에러가 발생합니다. 문자열 리터럴에 개행 문자를 넣으려면 반드시 \n을 사용해야 합니다. JavaScript에서 이스케이프 시퀀스는 \n과 같은 방식으로 동작합니다. -

-
참고: 긴 문자열을 변환하는 웹 프로그램 Hot-Tips' Unicode Converter, by Bob Foley.
-

JavaScript 파일에서 유니코드 문자

-

초기 버전의 Gecko는 XUL에서 로드되는 JavaScript 파일의 인코딩이 Latin-1일 것이라고 가정했습니다. Gecko 1.8부터는 XUL 파일의 인코딩으로 부터 JavaScript 파일의 인코딩을 유추하도록 변경되었습니다. 더 많은 정보는 International characters in XUL JavaScript 페이지를 참고하시기 바랍니다. -

-

유니코드로 문자 표시하기

-

우리는 다른 언어나 기술 분야 기호를 표시하기 위해서 유니코드를 사용할 수 있습니다. 문자를 제대로 표시하기 위해서는 Mozilla Firefox나 Netscape 같은 클라이언트가 유니코드를 지원해야 합니다. 게다가 클라이언트에서 사용할 수 있는 적절한 유니코드 글꼴이 필요하고, 클라이언트 플랫폼이 유니코드를 지원해야 합니다. 종종 유니코드 글꼴이 모든 유니코드 문자를 표시하지 못하는 경우가 있습니다. Windows 95 같은 몇몇 플랫폼은 유니코드를 부분적으로만 지원합니다. -

비 ASCII 문자 입력을 받기 위해서는 클라이언트가 유니코드로 입력을 보내야 합니다. 표준 확장 키보드(standard enhanced keyborad)를 사용하면 클라이언트에서 유니코드가 지원하는 추가적인 문자를 쉽게 입력할 수 없습니다. 때때로 유니코드 문자를 입력하려면 유니코드 이스케이프를 사용하는 방법 밖에 없을 때도 있습니다. -

유니코드에 대한 더 많은 정보를 얻으려면 유니코드 홈페이지나 The Unicode Standard, Version 2.0, published by Addison-Wesley, 1996 를 보시기 바랍니다. -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Literals", "Core_JavaScript_1.5_Guide:Expressions") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Unicode", "fr": "fr/Guide_JavaScript_1.5/Unicode", "ja": "ja/Core_JavaScript_1.5_Guide/Unicode", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Unicode" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/values/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/values/index.html deleted file mode 100644 index e5c40d23bf..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/values/index.html +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Values -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Values -translation_of: Web/JavaScript/Guide/Grammar_and_types -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Values ---- -

-

JavaScript는 다음과 같은 값 형식을 인식합니다. -

-
  • , 42나 3.14159 -
  • 논리적(불리언) 값, truefalse -
  • 문자열, "안녕!" -
  • null, null 값을 나타내는 특별한 키워드. null은 또한 기본(primitive) 값이기도 합니다. JavaScript는 대소문자를 구분하므로, nullNull이나 NULL과는 다릅니다. -
  • undefined, 값이 정의되지 않은 최상위 속성. undefined도 기본(primitive) 값입니다. -
-

이렇게 조금 적어보이는 값 형식 또는 "자료형"이지만 훌륭한 기능을 작성할 수 있습니다. 정수와 실수 사이에 엄격한 구분은 없습니다. JavaScript에는 명시적인 날짜 자료형은 없습니다. 하지만 Date 개체를 이용하면 됩니다. -Object함수는 언어의 또다른 기초 요소입니다. 개체는 값을 포함할 수 있는 이름 붙은 어떤 것이라고 생각하면 되고, 함수는 프로그램이 수행할 수 있는 실행 절차라고 생각하면 됩니다. -

-

자료형 변환

-

JavaScript는 동적 타입 언어입니다. 이 말은 변수를 선언할 때 타입을 지정하지 않아도 되고, 스크립트 실행중에 필요에 따라 자동으로 자료형이 바뀐다는 말입니다. 예를 들어 다음과 같이 변수를 선언할 수 있습니다. -

-
var answer = 42
-
-

그 후에 이 변수에 문자열 값을 할당할 수 있습니다. -

-
answer = "Thanks for all the fish..."
-
-

JavaScript는 동적 타입 언어이기 때문에, 이렇게 대입하더라도 에러를 내지 않습니다. -

숫자와 문자열 값을 + 연산자로 계산하는 표현식에서, JavaScript는 숫자를 문자열로 변환합니다. 예를 들어 다음과 같은 문장을 생각해봅시다. -

-
x = "The answer is " + 42 // returns "The answer is 42"
-y = 42 + " is the answer" // returns "42 is the answer"
-
-

다른 연산자를 사용하는 문장에서는 숫자를 문자열로 변환하지 않습니다. -

-
"37" - 7 // returns 30
-"37" + 7 // returns "377"
-
-

{{ PreviousNext("Core_JavaScript_1.5_Guide:JavaScript_Overview", "Core_JavaScript_1.5_Guide:Variables") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Values", "fr": "fr/Guide_JavaScript_1.5/Valeurs", "ja": "ja/Core_JavaScript_1.5_Guide/Values", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Warto\u015bci" } ) }} diff --git a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/variables/index.html b/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/variables/index.html deleted file mode 100644 index c9260414d3..0000000000 --- a/files/ko/web/javascript/guide/obsolete_pages/core_javascript_1.5_guide/variables/index.html +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Variables -slug: Web/JavaScript/Guide/Obsolete_Pages/Core_JavaScript_1.5_Guide/Variables -translation_of: Web/JavaScript/Guide/Grammar_and_types -translation_of_original: Web/JavaScript/Guide/Obsolete_Pages/Variables ---- -

변수

-

우리는 프로그램 내에서 값에 이름을 부여하기 위해서 변수를 사용할 수 있습니다. 변수의 이름은 "식별자(identifier)"라고 불리며, 몇 가지 규칙을 따라야 합니다. -

JavaScript 의 식별자는 문자(letter)나 밑줄(_)이나 달러 기호($)로 시작해야 합니다. 그 뒤에는 숫자(0-9)도 올 수 있습니다. JavaScript는 대소문자를 구별하기 때문에, 문자는 대문자 "A"부터 "Z"까지와 소문자 "a"부터 "z"까지를 사용할 수 있습니다. -

JavaScript 1.5부터, 식별자에 å나 ü같은 ISO 8859-1이나 유니코드 문자를 사용할 수 있습니다. 또한 유니코드 이스케이프 시퀀스 페이지에 나열된 \uXXXX 형식 유니코드 이스케이프 시퀀스를 식별자에 쓸 수도 있습니다. -

규칙에 맞는 이름 몇 가지는 이런 것입니다. Number_hits, temp99, _name. -

-

변수 선언

-

변수를 선언하는 방법에는 두 가지가 있습니다. -

-
  • var 키워드를 이용하는 방법. 예를 들면 var x = 42 같은 식입니다. 이 문법은 지역, 전역 변수를 선언하는데 모두 사용할 수 있습니다. -
  • 그냥 값을 대입하는 방법. x = 42 같은 식입니다. 이 방법은 항상 전역 변수를 선언하고, strict JavaScript 경고를 냅니다. 이 방법은 절대 사용하지 맙시다. -
-

변수를 평가하기(Evaluating)

-

초기값을 지정하지 않고 var 문장을 이용해서 선언한 변수는 undefined라는 값을 갖습니다. -

선언하지 않은 변수에 접근하려고 하면 ReferenceError 예외가 발생합니다. -

-
var a;
-print("The value of a is " + a); // prints "The value of a is undefined"
-print("The value of b is " + b); // throws ReferenceError exception
-
-

변수가 값을 갖고 있는지 결정하기 위해서 undefined를 사용할 수 있습니다. 다음 코드에서 input에는 값을 할당하지 않아서 if문은 true로 평가됩니다. -

-
var input;
-if(input === undefined){
-   doThis();
-} else {
-   doThat();
-}
-

Not sure how the following is related to "Variables" section -undefined값을 참/거짓을 판별하는 구문에 쓰면 false로 평가됩니다. 예를 들어 다음 코드에서는 myArray의 원소가 정의되지 않았기 때문에 myFunction 함수가 실행됩니다. -

-
myArray=new Array()
-if (!myArray[0])
-   myFunction();
-

숫자가 필요한 문맥에서 null 변수를 평가하면 null 값은 0으로 평가되고, 참/거짓이 필요한 문맥에서는 false로 평가됩니다. -When you evaluate a null variable, the null value behaves as 0 in numeric contexts and as false in boolean contexts. For example: -

-
var n = null;
-n * 32; //0을 반환합니다
-

변수 범위

-

함 수 외부에서 선언한 변수는 "전역(global)" 변수라고 부릅니다. 그 변수는 현재 문서의 모든 코드에서 접근할 수 있기 때문입니다. 함수 안에서 선언한 변수는 "지역(local)" 변수라고 부릅니다. 그 변수는 함수 안에서만 접근할 수 있기 때문입니다. -

JavaScript에는 블록 문장 범위가 없습니다. 대신 그 블록이 포함된 코드의 지역 범위에 포함됩니다. 예를 들어 다음 코드에서는 conditionfalse이면 예외를 발생시키는 대신 0을 출력합니다. -

-
if (condition) {
-  var x = 5;
-}
-print(x ? x : 0);
-
-

JavaScript의 변수와 관련해서 또다른 색다른 점은 나중에 선언될 변수에 예외 발생없이 접근할 수 있다는 것입니다. -

-
print(x === undefined); // prints "true"
-var x = 3;
-
-

전역 변수

-

need links to pages discussing scope chains and the global object -전역 변수는, 실제로는 "전역 개체(global object)"의 속성(property)입니다. 웹 페이지에서 전역 개체는 window이므로, window.variable 문장을 이용해서 전역 변수에 접근할 수 있습니다. -

그러므로, window나 frame 이름을 이용하면 다른 window나 frame에 정의된 전역 변수에 접근할 수 있습니다. 예를 들어 phoneNumber라는 변수를 FRAMESET 문서에 정의했다면, 자식 frame에서 parent.phoneNumber로 그 변수에 접근할 수 있습니다. -

{{ PreviousNext("Core_JavaScript_1.5_Guide:Values", "Core_JavaScript_1.5_Guide:Constants") }} -

{{ languages( { "en": "en/Core_JavaScript_1.5_Guide/Variables", "fr": "fr/Guide_JavaScript_1.5/Variables", "ja": "ja/Core_JavaScript_1.5_Guide/Variables", "pl": "pl/Przewodnik_po_j\u0119zyku_JavaScript_1.5/Zmienne" } ) }} diff --git a/files/ko/web/javascript/guide/regular_expressions/assertions/index.html b/files/ko/web/javascript/guide/regular_expressions/assertions/index.html new file mode 100644 index 0000000000..350c50f8f9 --- /dev/null +++ b/files/ko/web/javascript/guide/regular_expressions/assertions/index.html @@ -0,0 +1,244 @@ +--- +title: Assertions +slug: Web/JavaScript/Guide/정규식/Assertions +translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions +--- +

{{jsSidebar("JavaScript Guide")}}

+ +

Assertions에는 행이나 단어의 시작 · 끝을 나타내는 경계와 (앞, 뒤 읽고 조건식을 포함한) 어떤 식 으로든 매치가 가능한 것을 나타내는 다른 패턴이 포함됩니다.

+ +
{{EmbedInteractiveExample("pages/js/regexp-assertions.html", "taller")}}
+ +

Types

+ +

Boundary-type assertions

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CharactersMeaning
^ +

Matches the beginning of input. If the multiline flag is set to true, also matches immediately after a line break character. For example, /^A/ does not match the "A" in "an A", but does match the first "A" in "An A".

+ +
+

This character has a different meaning when it appears at the start of a group.

+
+
$ +

Matches the end of input. If the multiline flag is set to true, also matches immediately before a line break character. For example, /t$/ does not match the "t" in "eater", but does match it in "eat".

+
\b +

Matches a word boundary. This is the position where a word character is not followed or preceded by another word-character, such as between a letter and a space. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero.

+ +

Examples:

+ +
    +
  • /\bm/ matches the "m" in "moon".
  • +
  • /oo\b/ does not match the "oo" in "moon", because "oo" is followed by "n" which is a word character.
  • +
  • /oon\b/ matches the "oon" in "moon", because "oon" is the end of the string, thus not followed by a word character.
  • +
  • /\w\b\w/ will never match anything, because a word character can never be followed by both a non-word and a word character.
  • +
+ +

To match a backspace character ([\b]), see Character Classes.

+
\B +

Matches a non-word boundary. This is a position where the previous and next character are of the same type: Either both must be words, or both must be non-words, for example between two letters or between two spaces. The beginning and end of a string are considered non-words. Same as the matched word boundary, the matched non-word boundary is also not included in the match. For example, /\Bon/ matches "on" in "at noon", and /ye\B/ matches "ye" in "possibly yesterday".

+
+ +

Other assertions

+ +
+

Note: The ? character may also be used as a quantifier.

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
CharactersMeaning
x(?=y) +

Lookahead assertion: Matches "x" only if "x" is followed by "y". For example, /Jack(?=Sprat)/ matches "Jack" only if it is followed by "Sprat".
+ /Jack(?=Sprat|Frost)/ matches "Jack" only if it is followed by "Sprat" or "Frost". However, neither "Sprat" nor "Frost" is part of the match results.

+
x(?!y) +

Negative lookahead assertion: Matches "x" only if "x" is not followed by "y". For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. /\d+(?!\.)/.exec('3.141') matches "141" but not "3.

+
(?<=y)x +

Lookbehind assertion: Matches "x" only if "x" is preceded by "y". For example, /(?<=Jack)Sprat/ matches "Sprat" only if it is preceded by "Jack". /(?<=Jack|Tom)Sprat/ matches "Sprat" only if it is preceded by "Jack" or "Tom". However, neither "Jack" nor "Tom" is part of the match results.

+
(?<!y)x +

Negative lookbehind assertion: Matches "x" only if "x" is not preceded by "y". For example, /(?<!-)\d+/ matches a number only if it is not preceded by a minus sign. /(?<!-)\d+/.exec('3') matches "3". /(?<!-)\d+/.exec('-3')  match is not found because the number is preceded by the minus sign.

+
+ +

Examples

+ +

General boundary-type overview example

+ +
// Using Regex boundaries to fix buggy string.
+buggyMultiline = `tey, ihe light-greon apple
+tangs on ihe greon traa`;
+
+// 1) Use ^ to fix the matching at the begining of the string, and right after newline.
+buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
+console.log(1, buggyMultiline); // fix 'tey', 'tangs' => 'hey', 'hangs'. Avoid 'traa'.
+
+// 2) Use $ to fix matching at the end of the text.
+buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
+console.log(2, buggyMultiline); // fix  'traa' => 'tree'.
+
+// 3) Use \b to match characters right on border between a word and a space.
+buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
+console.log(3, buggyMultiline); // fix  'ihe' but does not touch 'light'.
+
+// 4) Use \B to match characters inside borders of an entity.
+fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
+console.log(4, fixedMultiline); // fix  'greon' but does not touch 'on'.
+
+ +

Matching the beginning of an input using a ^ control character

+ +

입력 시작시 일치를 위해 ^를 사용하십시오. 이 예에서는 /^A/ regex로 'A'로 시작하는 결과를 얻습니다. 여기서 ^는 한 가지 역할 만합니다. 적절한 결과를 보기위해 화살표 함수가있는 필터 메소드를 사용합니다.

+ +
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// Select fruits started with 'A' by /^A/ Regex.
+// Here '^' control symbol used only in one role: Matching begining of an input.
+
+let fruitsStartsWithA = fruits.filter(fruit => /^A/.test(fruit));
+console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]
+
+ +

두 번째 예제에서 ^는 두 가지 모두에 사용됩니다 : 입력의 일치 시작점, 그룹에서 사용될 때 부정 또는 보완 문자 세트.

+ +
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
+
+// Selecting fruits that dose not start by 'A' by a /^[^A]/ regex.
+// In this example, two meanings of '^' control symbol are represented:
+// 1) Matching begining of the input
+// 2) A negated or complemented character set: [^A]
+// That is, it matches anything that is not enclosed in the brackets.
+
+let fruitsStartsWithNotA = fruits.filter(fruit => /^[^A]/.test(fruit));
+
+console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]
+ +

Matching a word boundary

+ +
let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
+
+// Select descriptions that contains 'en' or 'ed' words endings:
+let enEdSelection = fruitsWithDescription.filter(descr => /(en|ed)\b/.test(descr));
+
+console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
+ +

Lookahead assertion

+ +
// JS Lookahead assertion x(?=y)
+
+let regex = /First(?= test)/g;
+
+console.log('First test'.match(regex)); // [ 'First' ]
+console.log('First peach'.match(regex)); // null
+console.log('This is a First test in a year.'.match(regex)); // [ 'First' ]
+console.log('This is a First peach in a month.'.match(regex)); // null
+
+ +

Basic negative lookahead assertion

+ +

For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. /\d+(?!\.)/.exec('3.141') matches "141" but not "3.

+ +
console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]
+
+ +

Different meaning of '?!' combination usage in Assertions and  Ranges 

+ +

Different meaning of ?! combination usage in Assertions /x(?!y)/ and Ranges [^?!].

+ +
let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";
+
+// Different meaning of '?!' combination usage in Assertions /x(?!y)/ and  Ranges /[^?!]/
+let selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
+
+let selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi
+console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]
+
+ +

Lookbehind assertion

+ +
let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
+
+let ripe_oranges = oranges.filter( fruit => fruit.match(/(?<=ripe )orange/));
+console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-assertion', 'RegExp: Assertions')}}{{Spec2('ESDraft')}}
+ +

Browser compatibility

+ +

For browser compatibility information, check out the main Regular Expressions compatibility table.

+ +

See also

+ + diff --git a/files/ko/web/javascript/guide/regular_expressions/groups_and_ranges/index.html b/files/ko/web/javascript/guide/regular_expressions/groups_and_ranges/index.html new file mode 100644 index 0000000000..2e2109b4ed --- /dev/null +++ b/files/ko/web/javascript/guide/regular_expressions/groups_and_ranges/index.html @@ -0,0 +1,91 @@ +--- +title: Groups and Ranges +slug: Web/JavaScript/Guide/정규식/Groups_and_Ranges +translation_of: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges +--- +

{{jsSidebar("JavaScript Guide")}}{{draft}}

+ +

그룹(Groups)과 범위(ranges)는 표현 문자의 그룹과 범위를 나타냅니다.

+ +

Types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CharactersMeaning
x|y +

x또는 y와 매칭되는 경우. 예를들면 /green|red/ 은 "green apple"의 "green"과 매치되고 "red apple"의 "red"와 매치됩니다.

+
[xyz]
+ [a-c]
+

A character set. Matches any one of the enclosed characters. You can specify a range of characters by using a hyphen, but if the hyphen appears as the first or last character enclosed in the square brackets it is taken as a literal hyphen to be included in the character set as a normal character. It is also possible to include a character class in a character set.

+ +

For example, [abcd] is the same as [a-d]. They match the "b" in "brisket" and the "c" in "chop".

+ +

For example, [abcd-] and [-abcd] match the "b" in "brisket", the "c" in "chop" and the "-" (hyphen) in "non-profit".

+ +

For example, [\w-] is the same as [A-Za-z0-9_-]. They match the "b" in "brisket", the "c" in "chop" and the "n" in "non-profit".

+
+

[^xyz]
+ [^a-c]

+
+

A negated or complemented character set. That is, it matches anything that is not enclosed in the brackets. You can specify a range of characters by using a hyphen, but if the hyphen appears as the first or last character enclosed in the square brackets it is taken as a literal hyphen to be included in the character set as a normal character. For example, [^abc] is the same as [^a-c]. They initially match "o" in "bacon" and "h" in "chop".

+ +
+

The ^ character may also indicate the beginning of input.

+
+
(x) +

Capturing group: Matches x and remembers the match. For example, /(foo)/ matches and remembers "foo" in "foo bar". 

+ +

A regular expression may have multiple capturing groups. In results, matches to capturing groups typically in an array whose members are in the same order as the left parentheses in the capturing group. This is usually just the order of the capturing groups themselves. This becomes important when capturing groups are nested. Matches are accessed using the index of the the result's elements ([1], ..., [n]) or from the predefined RegExp object's properties ($1, ..., $9).

+ +

Capturing groups have a performance penalty. If you don't need the matched substring to be recalled, prefer non-capturing parentheses (see below).

+ +

String.match() won't return groups if the /.../g flag is set. However, you can still use String.matchAll() to get all matches.

+
\n +

Where n is a positive integer. A back reference to the last substring matching the n parenthetical in the regular expression (counting left parentheses). For example, /apple(,)\sorange\1/ matches "apple, orange," in "apple, orange, cherry, peach". A complete example follows this table.

+
(?<Name>x) +

Named capturing group: Matches x and stores it on the groups property of the returned matches under the name specified by <Name>. The angle brackets ('<' and '>') are required for group name.

+ +

For example, to extract the United States area code from a phone number, I could use /\((?<area>\d\d\d)\)/. The resulting number would appear under matches.groups.area.

+
(?:x)Non-capturing group: Matches x but does not remember the match. The matched substring cannot be recalled from the resulting array's elements ([1], ..., [n]) or from the predefined RegExp object's properties ($1, ..., $9).
+ +

Examples

+ +

Browser support

+ +

Firefox currently doesn't support named groups. See corresponding issue.

+ +

See also

diff --git a/files/ko/web/javascript/guide/regular_expressions/index.html b/files/ko/web/javascript/guide/regular_expressions/index.html new file mode 100644 index 0000000000..5fbbcef0a0 --- /dev/null +++ b/files/ko/web/javascript/guide/regular_expressions/index.html @@ -0,0 +1,666 @@ +--- +title: 정규 표현식 +slug: Web/JavaScript/Guide/정규식 +tags: + - 자바스크립트 + - 정규식 +translation_of: Web/JavaScript/Guide/Regular_Expressions +--- +
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}
+ +

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 {{jsxref("RegExp")}}의 {{jsxref("RegExp.exec", "exec")}} 메소드와 {{jsxref("RegExp.test", "test")}} 메소드  ,그리고 {{jsxref("String")}}의  {{jsxref("String.match", "match")}}메소드 , {{jsxref("String.replace", "replace")}}메소드 , {{jsxref("String.search", "search")}}메소드 ,  {{jsxref("String.split", "split")}} 메소드와 함께 쓰입니다 . 이 장에서는 자바스크립트의 정규식에 대하여 설명합니다.

+ +

정규 표현식 만들기

+ +

(역주: 정규 표현식을 줄여서 '정규식'이라고 하기도 합니다. 아래 부분부터 '정규식'이라는 용어를 사용하겠습니다.)

+ +

정규식을 만드는 방법에는 두 가지가 있습니다.

+ +

정규식 리터럴(슬래쉬"/"로 감싸는 패턴)을 사용하는 방법은 다음과 같습니다.

+ +
var re = /ab+c/;
+
+ +

정규식 리터럴은 스크립트가 불러와질 때 컴파일됩니다. 만약 정규식이 상수라면, 이렇게 사용하는 것이 성능을 향상시킬 수 있습니다.

+ +

다른 방법으로는,  {{jsxref("RegExp")}} 객체의 생성자 함수를 호출하는 방법도 있습니다:

+ +
var re = new RegExp("ab+c");
+
+ +

생성자 함수를 사용하면 정규식이 실행 시점에 컴파일됩니다. 정규식의 패턴이 변경될 수 있는 경우, 혹은 사용자 입력과 같이 다른 출처로부터 패턴을 가져와야 하는 경우에는 생성자 함수를 사용하세요.

+ +

정규식 패턴 작성하기

+ +

정규식 패턴은 /abc/ 같이 단순 문자로 구성될 수도 있고, /ab*c/ 또는 /Chapter (\d+)\.\d*/와 같이 단순 문자와 특수 문자의 조합으로 구성될 수도 있습니다. 마지막 예제는 기억장치처럼 쓰이는 괄호를 포함하고 있습니다. {{web.link("#.ED.8C.A8.ED.84.B4.ED.99.94.EB.90.9C_.EB.B6.80.EB.B6.84_.EB.AC.B8.EC.9E.90.EC.97.B4_.EC.9D.BC.EC.B9.98_.EC.82.AC.EC.9A.A9.ED.95.98.EA.B8.B0", "패턴화된 부분 문자열 일치 사용하기") }}에서 설명하는것 처럼 패턴에서 괄호를 포함한 부분은 나중에 사용하기 위하여 저장됩니다.

+ +

단순 패턴 사용하기

+ +

단순 패턴은 문자열을 있는 그대로 대응시키고자 할 때 사용됩니다. 예를 들어, /abc/라는 패턴은 문자열에서 정확히 'abc' 라는 문자들이 모두 함께 순서대로 나타나야 대응됩니다. 위의 패턴은 "Hi, do you know your abc's?" 와 "The latest airplane designs evolved from slabcraft." 두가지 예에서 부분 문자열 'abc'에 대응될 것입니다.  'Grab crab' 이라는 문자열에서 'ab c' 라는 부분 문자열을 포함하고 있지만, 'abc'를 정확하게 포함하고 있지 않기 때문에 대응되지 않습니다.

+ +

특수 문자 사용하기

+ +

검색에서 하나 이상의 b들을 찾거나, 혹은 공백을 찾는 것과 같이 '있는 그대로의 대응' 이상의 대응을 필요로 할 경우, 패턴에 특수한 문자를 포함시킵니다. 예를 들어, /ab*c/ 패턴은  'a' 문자 뒤에 0개 이상의 'b' 문자(* 문자는 바로 앞의 문자가 0개 이상이라는 것을 의미합니다)가 나타나고 바로 뒤에 'c' 문자가 나타나는 문자 조합에 대응됩니다. 문자열 "cbbabbbbcdebc," 에서 위의 패턴은 부분 문자열 'abbbbc' 와 대응됩니다.

+ +

아래 표는 정규식에서 사용되는 모든 특수문자 목록 및 그에 대한 설명입니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
정규식에서의 특수문자
CharacterMeaning
\ +

다음의 규칙에 따라 일치합니다:
+
+ 특수 문자가 아닌 문자(non-special character) 앞에서 사용된 백슬래시는 '해당 문자는 특별하고, 문자 그대로 해석되면 안된다'는 사실을 가리킵니다. 예를 들어, 앞에 \가 없는 'b'는 보통 소문자 b가 나오는 패턴과 대응됩니다. 그러나 '\b' 자체는 어떤 문자와도 대응되지 않습니다; 이 문자는 특별한 단어 경계 문자를 형성합니다.
+
+ 특수 문자 앞에 위치한 백슬래시는 '다음에 나오는 문자는 특별하지않고, 문자 그대로 해석되어야 한다'는 사실을 가리킵니다. 예를 들어, 패턴 /a*/ 에서의 특수문자 '*'는 0개 이상의 'a' 문자가 등장함을 나타냅니다. 이와는 다르게, 패턴 /a\*/ 는 '*'이 특별하지 않다는 것을 나타내며, 'a*'와 같은 문자열과 대응될 수 있습니다.
+
+ RegExp("pattern") 표기를 쓰면서 \ 자체를 이스케이프 하는 것을 잊지 마세요. 왜냐하면 \ 는 문자열에서도 이스케이프 문자이기 때문입니다. (역주: /a\*/ 와 같은 패턴을 생성자로 만들려면 new RegExp('a\\*')와 같이 백슬래시 자체를 이스케이프 시켜주어야 합니다.)

+
^입력의 시작 부분에 대응됩니다. 만약 다중행 플래그가 참으로 설정되어 있다면, 줄 바꿈 문자 바로 다음 부분과도 대응됩니다.
+
+ 예를 들어, /^A/ 는 "an A" 의 'A'와는 대응되지 않습니다, 그러나 "An E" 의 'A'와는 대응됩니다.
+
+ '^' 가 문자셋([abc]) 패턴의 첫 글자로 쓰인다면, 그 때는 전혀 다른 의미를 가집니다. 자세한 내용은 역 문자셋을 참고하세요.
$ +

입력의 끝 부분과 대응됩니다. 만약 다중행 플래그가 참으로 설정되어 있다면, 줄 바꿈 문자의 바로 앞 부분과도 대응됩니다.

+ +

예를 들어, /t$/ 는 "eater" 의 't'에는 대응되지 않습니다, 그러나 "eat" 과는 대응됩니다.

+
* +

앞의 표현식이 0회 이상 연속으로 반복되는 부분과 대응됩니다. {0,} 와 같은 의미입니다.

+ +

예를 들어, /bo*/ 는 "A ghost booooed" 의 'boooo' 와 대응되고, "A bird warbled" 의 'b'에 대응되지만 "A goat grunted" 내의 어느 부분과도 대응되지 않습니다.

+
+ +

앞의 표현식이 1회 이상 연속으로 반복되는 부분과 대응됩니다. {1,} 와 같은 의미입니다.

+ +

예를 들어, /a+/ 는 "candy"의 'a'에 대응되고 "caaaaaaandy" 의 모든 'a'들에 대응되지만, "cndy" 내의 어느 부분과도 대응되지 않습니다.

+
?앞의 표현식이 0 또는 1회 등장하는 부분과 대응됩니다. {0,1} 와 같은 의미입니다.
+
+ 예를 들어, /e?le?/ 는 "angel"의 'el' 에 대응되고, "angle"의 'le' 에 대응되고 또한 "oslo" 의 'l'에도 대응됩니다.
+
+ 만약 수량자 *, +, ?, {} 바로 뒤에 사용하면, 기본적으로 탐욕스럽던(가능한 한 많이 대응시킴) 수량자를 탐욕스럽지 않게(가능한 가장 적은 문자들에 대응시킴) 만듭니다. 예를 들어, /\d+/를 "123abc"에 적용시키면 "123"과 대응됩니다. 그러나 /\d+?/를 같은 문자열에 적용시키면 오직 "1"과만 대응됩니다.
+
+ 또한 이 문자는 x(?=y)x(?!y) 항목에서 설명하는 바와 같이 사전 검증(lookahead assertion)을 위해서도 쓰입니다.
+  
. +

개행 문자를 제외한 모든 단일 문자와 대응됩니다.

+ +

예를 들어, /.n/는 "nay, an apple is on the tree"에서 'an'과 'on'에 대응되지만, 'nay' 에는 대응되지 않습니다.

+
(x) +

다음의 예제가 보여주는것 처럼 'x'에 대응되고, 그것을 기억합니다. 괄호는 포획 괄호(capturing parentheses)라 불립니다.
+
+ 패턴 /(foo) (bar) \1 \2/ 안의 '(foo)' 와 '(bar)'는 문자열"foo bar foo bar"에서 처음의 두 단어에 대응되고 이를 기억합니다. 패턴 내부의 \1\2는 문자열의 마지막 두 단어에 대응됩니다. (역주: \n 패턴은 앞의 n번째 포획괄호에 대응된 문자열과 똑같은 문자열에 대응됩니다.) \1, \2, \n과 같은 문법은 정규식의 패턴 부분에서 사용됩니다. 정규식의 치환 부분에서는 $1, $2, $n과 같은 문법이 사용되어야 합니다. 예를 들어, 'bar foo'.replace( /(...) (...)/, '$2 $1')와 같이 사용되어야 합니다. $& 패턴은 앞에서 대응된 전체 문자열을 가리킵니다.

+
(?:x)'x'에 대응되지만 대응된 것을 기억하지 않습니다. 괄호는 비포획 괄호(non-capturing parentheses)라고 불리우고, 정규식 연산자가 같이 동작할 수 있게 하위 표현을 정의할 수 있습니다. 정규식 예제 /(?:foo){1,2}/을 생각해보세요. 만약 정규식이 /foo{1,2}/라면, {1,2}는 'foo'의 마지막 'o' 에만 적용됩니다. 비포획 괄호과 같이 쓰인다면, {1,2}는 단어 'foo' 전체에 적용됩니다.
x(?=y) +

오직 'y'가 뒤따라오는 'x'에만 대응됩니다. 이것은 lookahead 라고 불립니다.

+ +

예를 들어, /Jack(?=Sprat)/ 는 'Sprat'가 뒤따라오는 'Jack' 에만 대응됩니다. /Jack(?=Sprat|Frost)/는 'Sprat' 또는 'Frost'가 뒤따라오는 'Jack'에만 대응됩니다. 그러나, 'Sprat' 및 'Frost' 는 대응 결과의 일부가 아닙니다.

+
x(?!y) +

'x'뒤에  'y'가 없는경우에만 'x'에 일치합니다. 이것은 negated lookahead 라고 불립니다.

+ +

예를 들어, /\d+(?!\.)/는 소숫점이 뒤따라오지 않는 숫자에 일치합니다. 정규식 /\d+(?!\.)/.exec("3.141")는 '3.141' 이 아닌 '141'에 일치합니다.

+
x|y +

'x' 또는 'y'에 대응됩니다.

+ +

예를 들어, /green|red/는 "green apple"의 'green'에 대응되고, "red apple."의 'red'에 대응됩니다.

+
{n}앞 표현식이 n번 나타나는 부분에 대응됩니다. n은 반드시 양의 정수여야 합니다.
+
+ 예를 들어, /a{2}/는 "candy,"의 'a'에는 대응되지 않지만, "caandy,"의 모든 a 와, "caaandy."의 첫 두 a 에는 대응됩니다.
{n,m} +

nm은 양의 정수이고, n <= m를 만족해야 합니다. 앞 문자가 최소 n개, 최대 m개가 나타나는 부분에 대응됩니다. m이 생략된다면, m은 ∞로 취급됩니다.

+ +

예를 들어, /a{1,3}/는 "cndy"에서 아무것에도 대응되지 않지만, "caandy,"의 첫 두 a 와 "caaaaaaandy"의 첫 세 a 에 대응됩니다. "caaaaaaandy"에서 더 많은 a 들이 있지만, "aaa"에만 대응된다는 점에 주목하세요.

+
[xyz]문자셋(Character set) 입니다. 이 패턴 타입은 괄호 안의 어떤 문자(이스케이프 시퀀스까지 포함)와도 대응됩니다. 점(.) 이나 별표 (*) 같은 특수 문자는 문자셋 내부에서는 특수 문자가 아닙니다. 따라서 이스케이프시킬 필요가 없습니다. 하이픈을 이용하여 문자의 범위를 지정해줄 수 있습니다.
+
+ 예를 들어, 패턴 [a-d] 는 패턴 [abcd] 와 똑같이 동작하며, "brisket"의 'b' 에 일치하고, "city"의 'c' 에 일치합니다. 패턴 /[a-z.]+/ /[\w.]+/ 는 "test.i.ng" 전체 문자열이 일치합니다.
[^xyz] +

부정 문자셋(negated character set) 또는 보충 문자셋(complemented character set)입니다. 괄호 내부에 등장하지 않는 어떤 문자와도 대응됩니다. 하이픈을 이용하여 문자의 범위를 지정할 수 있습니다. 일반적인 문자셋에서 작동하는 모든 것은 여기에서도 작동합니다.

+ +

예를 들어, 패턴[^abc]는 패턴[^a-c]와 동일합니다. 두 패턴은 "brisket"의 'r', "chop."의 'h' 에 대응됩니다.

+
[\b]백스페이스(U+0008)에 대응됩니다. 이와 같이, 백스페이스 문자 리터럴에 대응시키려면, 대괄호("[]")를 이용해야만 합니다. (\b와 혼동하지 마세요.)
\b +

단어 경계에 대응됩니다. 단어 경계는 다른 '단어 문자'가 앞이나 뒤에 등장하지 않는 위치에 대응됩니다. 단어의 경계는 대응 결과에 포함되지 않는다는 사실에 주의하세요. 다른 말로는, 단어의 경계에 대응되는 문자열의 길이는 항상 0입니다. (패턴 [\b]와 혼동하지 마세요.)

+ +

예제:
+ /\bm/는 "moon"의 'm'에 대응됩니다;
+ /oo\b/ 는 "moon"의 'oo' 부분에 대응되지 않는데, 왜냐하면 'oo'를 뒤따라오는 'n'이 단어 문자이기 때문입니다;
+ /oon\b/는 "moon"의 'oon'에 대응됩니다. 왜냐하면, 'oon'은 문자열의 끝이라서, 뒤따라오는 단어 문자가 없기 때문입니다 ;
+ /\w\b\w/는 어떤 것에도 일치하지 않습니다. 왜냐하면, 단어 문자는 절대로 비 단어 문자와 단어 문자 두개가 뒤따라올수 없기 때문입니다.

+ +
+

숙지하세요: 자바스크립트의 정규식 엔진은 특정 문자 집합을 '단어 문자'로 정의합니다. 이 집단에 속하지 않는 모든 문자는 단어 분리(word break) 로 여겨집니다. 단어 문자로 간주되는 문자들은 얼마 없습니다: 오로지 로마자 소문자와 대문자, 10진수 숫자, 밑줄 문자로 구성되어 있습니다. "é" 또는 "ü" 같이, 강세 표시 문자들은 안타깝게도 단어 분리(word breaks) 로 취급됩니다.

+
+
\B +

단어 경계가 아닌 부분에 대응됩니다. 아래와 같은 경우들이 있습니다:

+ +
    +
  • 문자열의 첫 번째 문자가 단어 문자가 아닌 경우, 해당 문자의 앞 부분에 대응됩니다.
  • +
  • 문자열의 마지막 문자가 단어 문자가 아닌 경우, 해당 문자의 뒷 부분에 대응됩니다.
  • +
  • 두 단어 문자의 사이에 대응됩니다.
  • +
  • 단어 문자가 아닌 두 문자 사이에 대응됩니다.
  • +
  • 빈 문자열에 대응됩니다.
  • +
+ +

문자열의 시작 부분과 끝 부분은 단어가 아닌 것으로 간주됩니다.

+ +

예를 들어, /\B../ 는 "noonday"의 'oo'와 대응되며, /y\B./ 는 "possibly yesterday."의 'ye'와 대응됩니다.

+
\cX +

문자열 내부의 제어 문자에 대응됩니다. 여기서 X는 A에서 Z까지의 문자 중 하나입니다.

+ +

예를 들어, /\cM/는 문자열에서 control-M (U+000D)에 대응됩니다.

+
\d +

숫자 문자에 대응됩니다. [0-9]와 동일합니다.

+ +

예를 들어, /\d/ 또는 /[0-9]/는 "B2 is the suite number."에서 '2'에 대응됩니다.

+
\D +

숫자 문자가 아닌 문자에 대응됩니다. [^0-9]와 동일합니다.

+ +

예를 들어, /\D/ 또는 /[^0-9]/는 "B2 is the suite number."의 'B'에 대응됩니다.

+
\f폼피드 (U+000C) 문자에 대응됩니다.
\n줄 바꿈 (U+000A) 문자에 대응됩니다.
\r캐리지 리턴(U+000D) 문자에 대응됩니다.
\s +

스페이스, 탭, 폼피드, 줄 바꿈 문자등을 포함한 하나의 공백 문자에 대응됩니다. [ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].와 동일합니다.

+ +

예를 들어, /\s\w*/는 "foo bar."의 ' bar'에 대응됩니다.

+
\S +

공백 문자가 아닌 하나의 문자에 대응됩니다. [^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]. 와 동일합니다.

+ +

예를 들어, /\S\w*/는 "foo bar."의 'foo' 에 대응됩니다.

+
\t탭 (U+0009) 문자에 대응됩니다.
\v수직 탭(U+000B) 문자에 대응됩니다.
\w +

밑줄 문자를 포함한 영숫자 문자에 대응됩니다. [A-Za-z0-9_] 와 동일합니다. (역주: 여기에 대응되는 문자를 단어 문자라고 합니다.)

+ +

예를 들어, /\w/는 "apple,"의 'a' 에 대응되고, "$5.28,"의 '5'에 대응되고,"3D."의 '3'에 대응됩니다.

+
\W +

단어 문자가 아닌 문자에 대응됩니다. [^A-Za-z0-9_] 와 동일합니다.

+ +

예를 들어, /\W/ 또는 /[^A-Za-z0-9_]/는 "50%."의 '%' 에 대응됩니다.

+
\n +

정규식 내부의 n번째 괄호에서 대응된 부분에 대한 역참조 입니다. 여기서, n은 양의 정수입니다.

+ +

예를 들어, /apple(,)\sorange\1/는 "apple, orange, cherry, peach."의 'apple, orange,' 에 일치합니다.

+
\0널 (U+0000)문자에 대응합니다. 이 때 다른 숫자를 뒤에 쓰지 마세요. 왜냐하면 \0<digits>는 8진 이스케이프 시퀀스이기 때문입니다.
\xhh코드가 hh(두 16진 숫자)인 문자에 일치합니다.
\uhhhh코드가 hhhh(네개의 16진 숫자)인 문자에 일치합니다.
+ +

사용자 입력을 이스케이프해서 정규식 내부에서 문자 그대로 취급해야 하는 경우, 간단히 치환을 하면 됩니다:

+ +
function escapeRegExp(string){
+  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $&는 일치한 전체 문자열을 의미합니다.
+}
+ +

괄호를 사용하기

+ +

정규식 내부의 일부를 둘러싼 괄호는, 해당 부분에서 대응된 문자열을 기억하는 효과를 갖습니다. 기억된 문자열은 이후 {{ web.link("#.ED.8C.A8.ED.84.B4.ED.99.94.EB.90.9C_.EB.B6.80.EB.B6.84_.EB.AC.B8.EC.9E.90.EC.97.B4_.EC.9D.BC.EC.B9.98_.EC.82.AC.EC.9A.A9.ED.95.98.EA.B8.B0", "패턴화된 부분 문자열 일치 사용하기") }}에서 설명한 것처럼 다른 곳에서 사용하기 위하여 불러와질 수 있습니다.

+ +

예를 들면, 패턴 /Chapter (\d+)\.\d*/는 패턴의 일부분이 기억될 거라는 사실을 나타냅니다. 이 패턴은 하나 이상의 숫자(\d는 숫자를 의미하고 +는 1개 이상을 의미합니다.) 이후에 하나의 소숫점(\가 앞에 붙은 소숫점은 문자 그대로의 문자 '.' 에 대응됨을 나타냅니다), 그뒤 0개 이상의 숫자(\d 는 숫자, * 는 0개 이상을 의미합니다.)가 뒤따라오는 'Chapter ' 문자열에 대응됩니다. 더해서, 괄호는 처음으로 일치하는 숫자 문자들을 기억하기 위하여 사용되었습니다.

+ +

이 패턴은 "Open Chapter 4.3, paragraph 6"에 나타나며, '4'가 기억됩니다. 이 패턴은 "Chapter 3 and 4"에는 나타나지 않습니다. 왜냐하면 문자열이 '3'이후에 마침표를 가지고 있지 않기 때문입니다.

+ +

부분 문자열을 대응시키면서도 해당 부분을 기억하지 않으려면, 괄호의 첫머리에 ?:패턴을 사용하세요. 예를 들어, (?:\d+)는 1개 이상의 숫자에 대응되지만 해당 문자들을 기억하지 않습니다.

+ +

정규식 사용하기

+ +

정규식은 RegExp, test, exec, String, match, replace, search, split 메소드와 함께 쓰입니다. 이 메소드는 JavaScript reference에서 잘 설명되어 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
정규식에서 쓰이는 메소드
MethodDescription
{{jsxref("RegExp.exec", "exec")}}대응되는 문자열을 찾는 RegExp 메소드입니다. 정보를 가지고 있는 배열을 반환합니다. 대응되는 문자열을 찾지 못했다면 null을 반환합니다.
{{jsxref("RegExp.test", "test")}}대응되는 문자열이 있는지 검사하는 RegExp 메소드 입니다. true 나 false를 반환합니다.
{{jsxref("String.match", "match")}}대응되는 문자열을 찾는 RegExp 메소드입니다. 정보를 가지고 있는 배열을 반환합니다. 대응되는 문자열을 찾지 못했다면 null을 반환합니다.
{{jsxref("String.search", "search")}} +

대응되는 문자열이 있는지 검사하는 String 메소드 입니다. 대응된 부분의 인덱스를 반환합니다. 대응되는 문자열을 찾지 못했다면 -1을 반환합니다.

+
{{jsxref("String.replace", "replace")}}대응되는 문자열을 찾아 다른 문자열로 치환하는 String 메소드입니다.
{{jsxref("String.split", "split")}}정규식 혹은 문자열로 대상 문자열을 나누어 배열로 반환하는 String 메소드입니다.
+ +

문자열 내부에 패턴과 대응되는 부분이 있는지 알고 싶다면, test 나 search 메소드를 사용하세요; 좀 더 많은 정보를 원하면 (대신 실행이 느림)  exec 나 match 메소드를 사용하세요. 만약 exec 나 match 메소드를 사용했는데 대응되는 부분이 있다면, 이 메소드는 배열을 반환하고 정규식 객체의 속성을 업데이트 합니다. 만약 대응되는 부분이 없다면, exec 메소드는 null 을 반환합니다. (즉, false와 같은 의미로 사용될 수 있습니다.).

+ +

아래의 예에서는, 문자열 내부에서 대응되는 부분을 찾기 위해 exec 메소드를 사용했습니다.

+ +
var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+
+ +

만약 정규식 속성에 접근할 필요가 없다면, 아래와 같이 myArray를 만드는 다른 방법도 있습니다:

+ +
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+
+ +

문자열로부터 정규식을 만들고 싶다면, 이런 방법도 있습니다:

+ +
var myRe = new RegExp("d(b+)d", "g");
+var myArray = myRe.exec("cdbbdbsbz");
+
+ +

위의 스크립트에서는, 대응되는 부분이 발견되었고 아래의 표에서 설명하는 대로 배열을 반환하며 속성을 갱신합니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
정규식 실행결과
ObjectProperty or indexDescriptionIn this example
myArray대응된 문자열 및 기억한 모든 부분 문자열['dbbd', 'bb', index: 1, input: 'cdbbdbsbz']
index입력된 문자열에서 대응된 부분에 해당하는 인덱스 (0부터 시작)1
input입력된 원본 문자열"cdbbdbsbz"
[0]마지막으로 대응된 문자열"dbbd"
myRelastIndex다음 검색 시 검색을 시작할 인덱스 (이 속성은 g 옵션을 설정한 정규식에 대해서만 설정됩니다. 자세한 사항은 {{ web.link("#Advanced_searching_with_flags", "Advanced Searching With Flags") }} 부분을 참고하세요.)5
source패턴 문자열. 정규식이 생성될 때 갱신됩니다. 실행 시점에는 갱신되지 않습니다."d(b+)d"
+ +

위 예제에서의 두 번째 형태처럼, 정규식 객체를 변수에 대입하지 않고도 사용할 수 있습니다. 하지만, 이렇게 하면 정규식 객체가 매번 새로 생성됩니다. 이러한 이유로, 만약 변수에 대입하지 않는 형태를 사용하는 경우 나중에 그 정규식의 속성에 접근할 수 없게 됩니다. 예를 들어, 이러한 스크립트가 있을 수 있습니다:

+ +
var myRe = /d(b+)d/g;
+var myArray = myRe.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + myRe.lastIndex);
+
+// "The value of lastIndex is 5"
+
+ +

그러나, 만약 이러한 스크립트가 있으면:

+ +
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
+console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
+
+// "The value of lastIndex is 0"
+
+ +

두 구문에서의 /d(b+)d/g 는 서로 다른  정규식 객체이고, 따라서 별개의 lastIndex 속성을 갖게 됩니다. 정규식 객체의 속성을 사용해야 하는 경우라면, 먼저 변수에 대입하세요.

+ +

괄호로 둘러싼 패턴 사용하기

+ +

정규식 패턴에 괄호를 사용하면, 그 부분을 별도로 대응시키면서 대응된 부분을 기억합니다. 예를 들면, /a(b)c/ 는 'abc' 와 대응되면서 'b'를 기억합니다. 괄호로 감싸진 문자열을 불러오려면, 배열 요소 [1], ..., [n] 를 사용하세요.

+ +

괄호로 감쌀 수 있는 문자의 개수에는 제한이 없습니다. 반환된 배열은 찾아낸 모든 것들을 갖고 있습니다. 다음의 예는 괄호로 둘러싸진 부분이 어떻게 대응되는지 보여줍니다.

+ +

다음의 예는 문자열 내부의 단어를 바꾸기 위해 {{jsxref("String.replace", "replace()")}} 메소드를 이용하고 있습니다. 치환 문자열로는 $1$2 를 사용하고 있는데, 이는 각각 첫 번째와 두 번째 괄호가 쳐진 부분에 대응된 문자열을 가리킵니다.

+ +
var re = /(\w+)\s(\w+)/;
+var str = "John Smith";
+var newstr = str.replace(re, "$2, $1");
+console.log(newstr);
+
+// "Smith, John"
+
+ +

플래그를 사용한 고급검색

+ +

정규식은 여섯 개의 플래그를 설정해줄 수 있으며, 이를 통해 전역 검색 또는 대소문자 구분 없는 검색을 수행할 수 있습니다. 이 플래그들은 각기 사용될 수도 있고 함께 사용될 수도 있고 순서에 구분이 없습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Regular expression flags
FlagDescription
g전역 검색
i대소문자 구분 없는 검색
m다중행(multi-line) 검색
s.에 개행 문자도 매칭(ES2018)
u유니코드; 패턴을 유니코드 코드 포인트의 나열로 취급합니다.
y"sticky" 검색을 수행. 문자열의 현재 위치부터 검색을 수행합니다. {{jsxref("RegExp.sticky", "sticky")}} 문서를 확인하세요.
+ +

정규식에 플래그를 포함시키려면, 아래 문법을 사용하세요:

+ +
var re = /pattern/flags;
+
+ +

혹은 아래와 같이 할 수도 있습니다:

+ +
var re = new RegExp("pattern", "flags");
+
+ +

이 플래그는 정규식에 합쳐지는 정보임을 기억하는게 좋습니다. 이것들은 나중에 추가되거나 제거될 수 없습니다.

+ +

예를 들어, re = /\w+\s/g 는 한 개 이상의 문자열 뒤에 공백이 하나 있는 패턴을 찾는 정규식을 생성합니다. 그리고 문자열 전체에 걸쳐 이 조합을 검색합니다.

+ +
var re = /\w+\s/g;
+var str = "fee fi fo fum";
+var myArray = str.match(re);
+console.log(myArray);
+
+// ["fee ", "fi ", "fo "]
+
+ +

아래 코드는:

+ +
var re = /\w+\s/g;
+
+ +

이렇게 바꿔쓸 수 있습니다:

+ +
var re = new RegExp("\\w+\\s", "g");
+
+ +

그리고 똑같은 결과를 얻습니다.

+ +

 .exec() 메소드를 사용할 때에는 'g' 플래그에 대한 동작이 다릅니다.  ("클래스"와 "인수"의 역할이 뒤바뀝니다:  .match()를 사용할 때는, string 클래스가 메소드를 갖고 정규식은 인수였던 것에 반해, .exec()를 사용할 때는 정규식이 메소드를 갖고 문자열이 인수가 됩니다. str.match(re) 과 re.exec(str)를 비교해보세요.)  'g' 플래그와  .exec() 메소드가 함께 사용되면 진행상황에 대한 정보가 반환됩니다.

+ +
var xArray; while(xArray = re.exec(str)) console.log(xArray);
+// 다음과 같이 출력됩니다:
+// ["fee ", index: 0, input: "fee fi fo fum"]
+// ["fi ", index: 4, input: "fee fi fo fum"]
+// ["fo ", index: 7, input: "fee fi fo fum"]
+ +

m 플래그는 여러 줄의 입력 문자열이 실제로 여러 줄로서 다뤄져야 하는 경우에 쓰입니다. 만약 m 플래그가 사용되면, ^$ 문자는 전체 문자열의 시작과 끝에 대응되는 것이 아니라 각 라인의 시작과 끝에 대응됩니다.

+ +

예시

+ +

다음의 예는 정규 표현식의 몇 가지 사용법을 보여줍니다.

+ +

입력 문자열에서 순서를 변경하기

+ +

다음 예는 정규식의 , string.split()과 string.replace()의 사용을 설명합니다. 그것은 공백, 탭과 정확히 하나의 세미콜론의 구분으로 이름(이름을 먼저)이 포함된 대략 형식의 입력 문자열을 정리합니다. 마지막으로, 순서(성을 먼저)를 뒤바꾸고 목록을 정렬합니다.

+ +
// The name string contains multiple spaces and tabs,
+// and may have multiple spaces between first and last names.
+var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
+
+var output = ["---------- Original String\n", names + "\n"];
+
+// Prepare two regular expression patterns and array storage.
+// Split the string into array elements.
+
+// pattern: possible white space then semicolon then possible white space
+var pattern = /\s*;\s*/;
+
+// Break the string into pieces separated by the pattern above and
+// store the pieces in an array called nameList
+var nameList = names.split(pattern);
+
+// new pattern: one or more characters then spaces then characters.
+// Use parentheses to "memorize" portions of the pattern.
+// The memorized portions are referred to later.
+pattern = /(\w+)\s+(\w+)/;
+
+// New array for holding names being processed.
+var bySurnameList = [];
+
+// Display the name array and populate the new array
+// with comma-separated names, last first.
+//
+// The replace method removes anything matching the pattern
+// and replaces it with the memorized string—second memorized portion
+// followed by comma space followed by first memorized portion.
+//
+// The variables $1 and $2 refer to the portions
+// memorized while matching the pattern.
+
+output.push("---------- After Split by Regular Expression");
+
+var i, len;
+for (i = 0, len = nameList.length; i < len; i++){
+  output.push(nameList[i]);
+  bySurnameList[i] = nameList[i].replace(pattern, "$2, $1");
+}
+
+// Display the new array.
+output.push("---------- Names Reversed");
+for (i = 0, len = bySurnameList.length; i < len; i++){
+  output.push(bySurnameList[i]);
+}
+
+// Sort by last name, then display the sorted array.
+bySurnameList.sort();
+output.push("---------- Sorted");
+for (i = 0, len = bySurnameList.length; i < len; i++){
+  output.push(bySurnameList[i]);
+}
+
+output.push("---------- End");
+
+console.log(output.join("\n"));
+
+ +

입력을 확인하기 위해 특수 문자를 사용하기

+ +

다음 예에서, 사용자는 전화번호를 입력 할 것으로 예상됩니다. 사용자가 "Check" 버튼을 누를 때, 스크립트는 번호의 유효성을 검사합니다. 번호가 유효한 경우(정규식에 의해 지정된 문자 시퀀스와 일치합니다), 스크립트는 사용자에게 감사하는 메시지와 번호를 확인하는 메시지를 나타냅니다. 번호가 유효하지 않은 경우, 스크립트는 전화번호가 유효하지 않다는 것을 사용자에게 알립니다.

+ +

비 캡처링 괄호 (?: , 정규식은 세 자리 숫자를 찾습니다 \d{3} OR | 왼쪽 괄호\( 세 자리 숫자 다음에 \d{3}, 닫는 괄호 다음에 \), (비 캡처링 괄호를 종료)) 안에, 하나의 대시, 슬래시, 또는 소수점을 다음과 같이 발견했을 때,  세 자리 숫자 다음에 d{3}, 대시의 기억 매치, 슬래시, 또는 소수점 다음에 \1, 네 자리 숫자 다음에 \d{4} 문자를 기억합니다([-\/\.]).

+ +

사용자가 <Enter> 키를 누를 때 활성화 변경 이벤트는 RegExp.input의 값을 설정합니다.

+ +
<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+    <meta http-equiv="Content-Script-Type" content="text/javascript">
+    <script type="text/javascript">
+      var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/;
+      function testInfo(phoneInput){
+        var OK = re.exec(phoneInput.value);
+        if (!OK)
+          window.alert(OK.input + " isn't a phone number with area code!");
+        else
+          window.alert("Thanks, your phone number is " + OK[0]);
+      }
+    </script>
+  </head>
+  <body>
+    <p>Enter your phone number (with area code) and then click "Check".
+        <br>The expected format is like ###-###-####.</p>
+    <form action="#">
+      <input id="phone"><button onclick="testInfo(document.getElementById('phone'));">Check</button>
+    </form>
+  </body>
+</html>
+
+ +

{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}

diff --git a/files/ko/web/javascript/guide/values,_variables,_and_literals/index.html b/files/ko/web/javascript/guide/values,_variables,_and_literals/index.html deleted file mode 100644 index 629cbd069a..0000000000 --- a/files/ko/web/javascript/guide/values,_variables,_and_literals/index.html +++ /dev/null @@ -1,708 +0,0 @@ ---- -title: 문법과 자료형 -slug: 'Web/JavaScript/Guide/Values,_variables,_and_literals' -tags: - - Guide - - JavaScript - - 'l10n:priority' -translation_of: Web/JavaScript/Guide/Grammar_and_types ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/소개", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}
- -

이 장은 JavaScript의 기본 문법과 변수 선언, 자료형 및 리터럴을 다룹니다.

- -

기본

- -

JavaScript는 문법의 대부분을 Java와 C, C++로부터 차용하고 있으며, Awk, Perl, Python의 영향도 받았습니다.

- -

JavaScript는 대소문자를 구별하며 유니코드 문자셋을 이용합니다. 따라서 다음과 같은 코드도 유효합니다.

- -
var 갑을 = "병정";
-var Früh = "foobar"; // Früh: 독일어로 "이른"
-
- -

하지만 Frühfrüh와 다릅니다. 대소문자를 구분하기 때문입니다.

- -

JavaScript에서는 명령을 {{Glossary("Statement", "명령문(statement)")}}이라고 부르며, 세미콜론(;)으로 구분합니다.

- -

명령문이 한 줄을 다 차지할 경우에는 세미콜론이 필요하지 않습니다. 그러나 한 줄에 두 개 이상의 명령문이 필요하다면 세미콜론으로 구분해야 합니다. ECMAScript는 세미콜론을 자동으로 삽입해 명령문을 끝내는 규칙(ASI)도 가지고 있습니다. (더 많은 정보는 JavaScript의 어휘 문법 에 대한 자세한 참고서를 참고하세요) 하지만, 세미콜론이 필요하지 않은 경우라도 항상 세미콜론으로 끝마치는 편이 버그 예방 차원에서 더 좋은 습관이라고 여겨집니다.

- -

JavaScript의 스크립트 소스는 왼쪽에서 오른쪽으로 탐색하면서 토큰, 제어 문자, 줄바꿈 문자, 주석이나 공백으로 이루어진 입력 element의 시퀀스로 변환됩니다. 스페이스, 탭, 줄바꿈 문자는 공백으로 간주됩니다.

- -

주석

- -

주석의 구문은 C++ 및 다른 많은 언어와 똑같습니다.

- -
// 한 줄 주석
-
-/* 이건 더 긴,
- * 여러 줄 주석입니다.
- */
-
-/* 그러나, /* 중첩된 주석은 쓸 수 없습니다 */ SyntaxError */
- -

주석은 공백처럼 행동하며 스크립트 실행 시 버려집니다.

- -
-

참고: 몇몇 자바스크립트 파일의 시작부에 #!/usr/bin/env node와 같은 형태의 주석 문법이 쓰이는 것을 볼 수 있습니다. 이것은 해시백 주석 문법이라고 하는데, 이 특별한 주석은 스크립트를 실행할 때 쓸 특별한 자바스크립트 인터프리터의 경로를 설정할 때 쓰입니다.  해시백 주석을 참고하여 자세한 내용을 확인할 수 있습니다.

-
- -

선언

- -

JavaScript의 선언에는 3가지 방법이 있습니다.

- -
-
{{jsxref("Statements/var", "var")}}
-
변수를 선언. 추가로 동시에 값을 초기화.
-
{{jsxref("Statements/let", "let")}}
-
블록 범위(scope) 지역 변수를 선언. 추가로 동시에 값을 초기화.
-
{{jsxref("Statements/const", "const")}}
-
블록 범위 읽기 전용 상수를 선언.
-
- -

변수

- -

어플리케이션에서 값에 상징적인 이름으로 변수를 사용합니다. 변수명은 {{Glossary("식별자(identifier)")}}라고 불리며 특정 규칙을 따릅니다.

- -

JavaScript 식별자는 문자, 밑줄(_) 혹은 달러 기호($)로 시작해야 하는 반면 이후는 숫자(0-9)일 수도 있습니다. JavaScript가 대소문자를 구분하기에, 문자는 "A"부터 "Z"(대문자)와 "a"부터 "z"(소문자)까지 모두 포함합니다.

- -

ISO 8859-1 혹은 Unicode 문자(가령 å 나 ü)도 식별자에 사용할 수 있습니다(좀 더 상세한 내용은 이 블로그 글을 참고). 또한 Unicode escape sequences도 식별자에 문자로 사용할 수 있습니다.

- -

적절한 이름으로는 Number_hits, temp99, $credit_name등입니다.

- -

변수 선언

- -

변수 선언은 아래 3가지 방법으로 가능합니다.

- -
    -
  • {{jsxref("Statements/var", "var")}} 키워드로. 예를 들어, var x = 42. 이 구문은 지역 및 전역 변수를 선언하는데 모두 사용될 수 있습니다.
  • -
  • {{jsxref("Statements/let", "let")}} 키워드로. 예를 들어, let y = 13. 이 구문은 블록 범위 지역 변수를 선언하는데 사용될 수 있습니다. 아래 변수 범위 참고하세요.
  • -
- -

간단히 변수에 값을 할당 할 수도 있습니다. 예를 들어, x = 42 와 같은 구문은 선언되지 않는 전역변수 를 만듭니다. 뿐만 아니라, 자바스크립트의 엄격한 경고를 만들어냅니다. 선언되지 않은 전역변수는 의도되지 않은 동작을 만들어내고는 합니다. 따라서 선언되지 않는 전역변수를 사용하면 안됩니다.

- -

변수 할당

- -

지정된 초기값 없이 var 혹은 let 문을 사용해서 선언된 변수는 {{jsxref("undefined")}} 값을 갖습니다.

- -

선언되지 않은 변수에 접근을 시도하는 경우 {{jsxref("ReferenceError")}} 예외가 발생합니다.

- -
var a;
-console.log("a 값은 " + a); // "a 값은 undefined"로 로그가 남음.
-
-console.log('b 값은 ' + b); // b 값은 undefined
-var b;
-
-console.log("c 값은 " + c); // ReferenceError 예외 던짐
-
-let x;
-console.log('x 값은 ' + x); // x 값은 undefined
-
-console.oog('y 값은 ' + y); // ReferenceError 예외 던짐
-let y;
-
- -

undefined를 사용하여 변수값이 있는지 확인할 수 있습니다. 아래 코드에서, input 변수는 값이 할당되지 않았고 if문은 true로 평가합니다.

- -
var input;
-if(input === undefined) {
-  doThis();
-} else {
-  doThat();
-}
-
- -

undefined 값은 boolean 문맥(context)에서 사용될 때 false로 동작합니다. 예를 들어, 아래 코드는 myArray 요소가 undefined이므로 myFunction 함수를 실행합니다.

- -
var myArray = [];
-if (!myArray[0]) myFunction();
-
- -

undefined 값은 수치 문맥에서 사용될 때 NaN으로 변환됩니다.

- -
var a;
-a + 2; // NaN으로 평가
- -

{{jsxref("null")}} 값을 평가할 때, 수치 문맥에서는 0으로, boolean 문맥에서는 false로 동작합니다. 예를 들면,

- -
var n = null;
-console.log(n * 32); // 콘솔에 0 으로 로그가 남음.
-
- -

변수 범위

- -

어떤 함수의 바깥에 변수를 선언하면, 현재 문서의 다른 코드에 해당 변수를 사용할 수 있기에 전역 변수라고 합니다. 만약 함수 내부에 변수를 선언하면, 오직 그 함수 내에서만 사용할 수 있기에 지역 변수라고 부릅니다.

- -

ECMAScript 6 이전의 JavaScript는 block 문 범위가 없습니다. 그래서 오히려, 블록 내에 선언된 변수는 그 블록 내에 존재하는 함수(혹은 전역 범위)에 지역적입니다. 예를 들어서 아래의 코드는 5라는 로그를 남깁니다. x의 범위가 이 경우 if문 블록이 아니라 x가 선언된 함수(나 전역 문맥)이기 때문입니다.

- -
if (true) {
-  var x = 5;
-}
-console.log(x); // 5
-
- -

ECMAScript 6에 도입된 let 선언을 사용했을 때, 이 동작은 바뀌었습니다.

- -
if (true) {
-  let y = 5;
-}
-console.log(y); // ReferenceError: y is not defined
- -

변수 호이스팅

- -

또 다른 JavaScript 변수의 특이한 점은 예외를 받지 않고도, 나중에 선언된 변수를 참조할 수 있다는 것입니다. 이 개념은 호이스팅(hoisting)으로 알려져 있습니다. 즉 JavaScript 변수가 어떤 의미에서 "끌어올려지거"나 함수나 문의 최상단으로 올려지는 것을 말합니다. 하지만, 끌어올려진 변수는 undefined 값을 반환합니다. 그래서 심지어 이 변수를 사용 혹은 참조한 후에 선언 및 초기화하더라도, 여전히 undefined를 반환합니다.

- -
/**
- * Example 1
- */
-console.log(x === undefined); // logs "true"
-var x = 3;
-
-
-/**
- * Example 2
- */
-// undefined 값을 반환함.
-var myvar = "my value";
-
-(function() {
-  console.log(myvar); // undefined
-  var myvar = "local value";
-})();
-
- -

위 예제는 아래 예제와 동일하게 볼 수 있습니다.

- -
/**
- * Example 1
- */
-var x;
-console.log(x === undefined); // logs "true"
-x = 3;
-
-/**
- * Example 2
- */
-var myvar = "my value";
-
-(function() {
-  var myvar;
-  console.log(myvar); // undefined
-  myvar = "local value";
-})();
- -

호이스팅 때문에, 함수 내의 모든 var 문은 가능한 함수 상단 근처에 두는 것이 좋습니다. 이 방법은 코드를 더욱 명확하게 만들어줍니다.

- -

ECMAScript 2015의 let (const)는 변수를 블록의 상단으로 올리지 않습니다.
- 변수가 선언되기 전에 블록 안에서 변수를 참조하게 되면 {{jsxref("ReferenceError")}}를 발생시키게 됩니다.
- 변수는 블록 시작부터 선언이 처리될 때까지 'temporal dead zone'에 위치하게 됩니다.

- -
console.log(x); // ReferenceError
-let x = 3;
-
- -

함수 호이스팅

- -

함수에서는 단지 함수 선언만 상단으로 끌어올려집니다. 함수 표현식은 그렇지 않습니다.

- -
/* 함수 선언 */
-
-foo(); // "bar"
-
-function foo() {
-  console.log('bar');
-}
-
-
-/* 함수 표현식 */
-
-baz(); // TypeError: baz is not a function
-
-var baz = function() {
-  console.log('bar2');
-};
- -

전역 변수

- -

전역 변수는 사실 global 객체의 속성(property)입니다. 웹 페이지에서 global 객체는 {{domxref("window")}} 이므로, windows.variable 구문을 통해 전역 변수를 설정하고 접근할 수 있습니다.

- -

그 결과, window 혹은 frame의 이름을 지정하여 한 window 혹은 frame에서 다른 window 혹은 frame에 선언된 전역 변수에 접근할 수 있습니다. 예를 들어, phoneNumber 라는 변수가 문서에 선언된 경우, iframe에서 parent.phoneNumber로 이 변수를 참조할 수 있습니다.

- -

상수

- -

{{jsxref("Statements/const", "const")}} 키워드로 읽기 전용 상수를 만들 수 있습니다. 상수 식별자의 구문은 변수 식별자와 같습니다. 문자, 밑줄이나 달러 기호로 시작해야 하고 문자, 숫자나 밑줄을 포함할 수 있습니다.

- -
const PI = 3.14;
-
- -

상수는 스크립트가 실행 중인 동안 대입을 통해 값을 바꾸거나 재선언될 수 없습니다. 값으로 초기화해야 합니다.

- -

상수에 대한 범위 규칙은 let 블록 범위 변수와 동일합니다. 만약 const 키워드가 생략된 경우에는, 식별자는 변수를 나타내는 것으로 간주됩니다.

- -

상수는 같은 범위에 있는 함수나 변수와 동일한 이름으로 선언할 수 없습니다. 예를 들어,

- -
// 오류가 발생합니다
-function f() {};
-const f = 5;
-
-// 역시 오류가 발생합니다
-function f() {
-  const g = 5;
-  var g;
-
-  //statements
-}
-
- -

그러나, 상수에 할당된 객체의 속성은 보호되지 않아서 다음의 문은 문제없이 실행됩니다.

- -
const MY_OBJECT = {'key': 'value'};
-MY_OBJECT.key = 'otherValue';
-
- -

또한, 배열의 내용도 보호되지 않아서 다음의 문도 문제없이 실행됩니다.

- -
const MY_ARRAY = ['HTML','CSS'];
-MY_ARRAY.push('JAVASCRIPT');
-console.log(MY_ARRAY); //logs ['HTML','CSS','JAVASCRIPT'];
-
- -

데이터 구조 및 형

- -

데이터 형

- -

최신 ECMAScript 표준은 7가지 데이터 형을 정의합니다.

- -
    -
  • 6가지 {{Glossary("Primitive", "원시")}} 데이터 형 -
      -
    • {{Glossary("Boolean")}}. true와 false
    • -
    • {{Glossary("null")}}. null 값을 나타내는 특별한 키워드. JavaScript는 대소문자를 구분하므로, null은 Null, NULL 혹은 다른 변형과도 다릅니다.
    • -
    • {{Glossary("undefined")}}. 값이 저장되어 있지 않은 최상위 속성.
    • -
    • {{Glossary("Number")}}. 정수 또는 실수형 숫자. 예:42 혹은 3.14159.
    • -
    • {{Glossary("String")}}. 문자열. 예:"안녕"
    • -
    • {{Glossary("Symbol")}}. (ECMAScript 6에 도입) 인스턴스가 고유하고 불변인 데이터 형.
    • -
    -
  • -
  • 그리고 {{Glossary("Object")}}
  • -
- -

이 데이터 형이 비교적 많지 않지만, 어플리케이션에 유용한 기능을 수행할 수 있습니다. {{jsxref("Object", "객체")}}와 {{jsxref("Function", "함수")}}는 언어의 다른 기본 요소입니다. 객체는 값을 위한 컨테이너, 함수는 어플리케이션이 수행할 수 있는 절차(procedure)로 생각할 수 있습니다.

- -

자료형 변환

- -

JavaScript는 동적 형지정(정형) 언어입니다. 이는 변수를 선언할 때 데이터 형을 지정할 필요가 없음을 의미합니다. 또한 데이터 형이 스크립트 실행 도중 필요에 의해 자동으로 변환됨을 뜻합니다. 그래서, 예를 들어, 다음과 같이 변수를 정의할 수 있습니다.

- -
var answer = 42;
- -

그리고 나중에, 동일한 변수에 문자열 값을 할당할 수도 있습니다. 아래와 같이,

- -
answer = "Thanks for all the fish...";
-
- -

JavaScript는 동적 형지정 언어이므로, 이 할당은 오류 메시지가 발생하지 않습니다.

- -

숫자와 문자열 값 사이에 + 연산자를 포함한 식에서, JavaScript는 숫자 값을 문자열로 변환합니다. 예를 들어, 아래와 같은 문이 있습니다.

- -
x = "The answer is " + 42 // "The answer is 42"
-y = 42 + " is the answer" // "42 is the answer"
- -

다른 연산자를 포함한 식의 경우, JavaScript는 숫자 값을 문자열로 변환하지 않습니다. 예를 들면,

- -
"37" - 7 // 30
-"37" + 7 // 377
-
- -

문자열을 숫자로 변환하기

- -

숫자를 나타내는 값이 문자열로 메모리에 있는 경우, 변환을 위한 메서드가 있습니다.

- -
    -
  • {{jsxref("parseInt", "parseInt()")}}
  • -
  • {{jsxref("parseFloat", "parseFloat()")}}
  • -
- -

parseInt는 오직 정수만 반환하므로, 소수에서는 사용성이 떨어집니다. 게다가 parseInt를 잘 사용하기 위해서는 항상 진법(Radix) 매개변수를 포함해야 합니다. 진법 매개변수는 변환에 사용될 진법을 지정하는데 사용됩니다.

- -

문자열을 숫자로 변환하는 대안은 +(단항 더하기) 연산자입니다.

- -
"1.1" + "1.1" = "1.11.1"
-(+"1.1") + (+"1.1") = 2.2
-// 참고: 괄호는 명확성을 위해 추가, 필요한 것은 아닙니다.
-
- -

리터럴

- -

JavaScript에서 값을 나타내기 위해 리터럴을 사용합니다. 이는 말 그대로 스크립트에 부여한 고정값으로, 변수가 아닙니다. 이 절에서는 다음과 같은 형태의 리터럴을 설명합니다.

- -
    -
  • {{anch("배열_리터럴", "배열 리터럴")}}
  • -
  • {{anch("불린_리터럴", "불린 리터럴")}}
  • -
  • {{anch("부동_소수점_리터럴", "부동 소수점 리터럴")}}
  • -
  • {{anch("정수", "정수")}}
  • -
  • {{anch("객체_리터럴", "객체 리터럴")}}
  • -
  • {{anch("정규식_리터럴", "정규식 리터럴")}}
  • -
  • {{anch("문자열_리터럴", "문자열 리터럴")}}
  • -
- -

배열 리터럴

- -

배열 리터럴은 0개 이상의 식(expression) 목록입니다. 각 식은 배열 요소를 나타내고 대괄호([])로 묶입니다. 배열 리터럴을 사용하여 배열을 만들 때, 그 요소로 지정된 값으로 초기화되고, 그 길이는 지정된 인수의 갯수로 설정됩니다.

- -

아래 예제는 요소가 3개로 길이가 3인 coffees 배열을 만듭니다.

- -
var coffees = ["French Roast", "Colombian", "Kona"];
-
- -
-

참고: 배열 리터럴은 일종의 객체 이니셜라이저(initialiizer)입니다. Using Object Initializers 참고.

-
- -

배열이 최상단 스크립트에서 리터럴을 사용하여 만들어진 경우, JavaScript는 배열 리터럴을 포함한 식을 평가할 때마다 배열로 해석합니다. 게다가, 함수에서 사용되는 리터럴은 함수가 호출될 때마다 생성됩니다.

- -

배열 리터럴은 배열 객체입니다. 배열 객체에 대한 자세한 내용은 {{jsxref("Array")}}와 Indexed collections 참고.

- -

배열 리터럴의 추가 쉼표

- -

배열 리터럴에서 모든 요소를 지정할 필요는 없습니다. 만약 잇달아 두 개의 쉼표를 두면, 배열은 지정되지 않은 요소를 undefined로 만듭니다. 다음 예제는 fish 배열을 만듭니다.

- -
var fish = ["Lion", , "Angel"];
-
- -

이 배열은 값이 있는 두 요소와 빈 요소 하나를 가집니다(fish[0]은 "Lion", fish[1]undefined, fish[2]는 "Angel").

- -

만약 요소 목록을 후행(trailing) 쉼표로 끝낸다면, 그 쉼표는 무시됩니다. 다음 예제에서, 배열의 길이는 3입니다. myList[3]은 없습니다. 목록의 다른 모든 쉼표는 새로운 요소를 나타냅니다.

- -
-

참고: 후행 쉼표는 구버전 브라우저에서 오류를 유발할 수 있으므로 제거하는게 최선입니다.

-
- -
var myList = ['home', , 'school', ];
-
- -

아래 예제에서, 배열의 길이는 4이며, myList[0]myList[2]는 값이 빠졌습니다.

- -
var myList = [ , 'home', , 'school'];
-
- -

아래 예제에서, 배열의 길이는 4이며, myList[1]myList[3]은 값이 빠졌습니다. 마지막 쉼표는 무시됩니다.

- -
var myList = ['home', , 'school', , ];
-
- -

추가 쉼표의 동작을 이해하는 것은 JavaScript를 언어로서 이해하는데 중요하지만, 코드를 작성할 때는 빠진 요소의 값을 명시적으로 undefined로 선언하는 것이 코드의 명확성과 유지보수성을 높입니다.

- -

불리언 리터럴

- -

불리언 형은 truefalse의 리터럴 값을 가집니다.

- -

원시 불린 값 truefalse와 Boolean 객체의 true 및 false 값을 혼동하지 마세요. Boolean 객체는 원시 불린 데이터 형을 감싸는 래퍼(wrapper)입니다. 더 많은 정보는 {{jsxref("Boolean")}}을 참고하세요.

- -

정수 리터럴

- -

정수는 10진, 16진, 8진 및 2진수로 표현될 수 있습니다.

- -
    -
  • 10진 정수 리터럴은 선행 0(zero)이 아닌 숫자열로 이루어집니다.
  • -
  • 정수 리터럴에서 선행 0(zero)이나 선행 0o(혹은 0O)은 8진수임을 나타냅니다. 8진 정수는 오직 숫자 0-7만 포함할 수 있습니다.
  • -
  • 선행 0x(나 0X)는 16진수임을 나타냅니다. 16진 정수는 숫자 0-9 및 문자 a-f, A-F를 포함할 수 있습니다.
  • -
  • 선행 0b(나 0B)는 2진수임을 나타냅니다. 2진 정수는 오직 숫자 0과 1만 포함할 수 있습니다.
  • -
- -

다음은 정수 리터럴 예제입니다.

- -
0, 117 및 -345 (10진수)
-015, 0001 및 -0o77 (8진수)
-0x1123, 0x00111 및 -0xF1A7 (16진수)
-0b11, 0b0011 및 -0b11 (2진수)
-
- -

더 많은 정보는 Lexical grammar reference의 Numeric literals를 참고하세요.

- -

부동 소수점 리터럴

- -

부동 소수점 리터럴은 아래와 같은 부분으로 이루어집니다.

- -
    -
  • 부호("+"나 "-")가 달릴 수 있는 10진 정수,
  • -
  • 소수점("."),
  • -
  • 소수(또 다른 10진수),
  • -
  • 지수.
  • -
- -

지수부는 "e"나 "E" 다음에 오며 부호("+"나 "-")가 달릴 수 있는 정수입니다. 부동 소수점 리터럴은 적어도 숫자 하나와 소수점 혹은 "e"(나 "E")가 있어야 합니다.

- -

더 간결하게 설명하면, 구문은 다음과 같습니다.

- -
[(+|-)][digits][.digits][(E|e)[(+|-)]digits]
-
- -

예를 들면,

- -
3.1415926
--.123456789
--3.1E+12
-.1e-23
-
- -

객체 리터럴

- -

객체 리터럴은 중괄호({})로 묶인 0개 이상인 객체의 속성명과 관련 값 쌍 목록입니다. 문의 시작에 객체 리터럴을 사용해서는 안됩니다. 이는 {가 블록의 시작으로 해석되기 때문에 오류를 이끌거나 의도한 대로 동작하지 않습니다.

- -

아래는 객체 리터럴의 예제입니다. car 객체의 첫째 요소는 myCar 속성을 정의하고 문자열 "Saturn"을 할당합니다. 반면 둘째 요소인 getCar 속성은 function (carTypes("Honda"))을 호출한 결과가 즉시 할당됩니다. 셋째 요소 special 속성은 기존 변수 sales를 사용합니다.

- -
var sales = "Toyota";
-
-function carTypes(name) {
-  if (name === "Honda") {
-    return name;
-  } else {
-
-  }
-    return "Sorry, we don't sell " + name + ".";
-}
-
-var car = { myCar: "Saturn", getCar: carTypes("Honda"), special: sales };
-
-console.log(car.myCar);   // Saturn
-console.log(car.getCar);  // Honda
-console.log(car.special); // Toyota
-
- -

게다가, 속성명으로 숫자나 문자열 리터럴을 사용하거나 또다른 객체 리터럴 내부에 객체를 중첩할 수도 있습니다. 아래 예제는 이 옵션을 사용합니다.

- -
var car = { manyCars: {a: "Saab", "b": "Jeep"}, 7: "Mazda" };
-
-console.log(car.manyCars.b); // Jeep
-console.log(car[7]); // Mazda
-
- -

객체 속성명은 빈 문자열 포함 어떤 문자열도 될 수 있습니다. 속성명이 유효한 JavaScript {{Glossary("식별자")}}나 숫자가 아닌 경우, 따옴표로 묶여야 합니다. 또한 유효한 식별자가 아닌 속성명은 점(.) 속성으로 접근할 수 없습니다. 대신 배열 같은 표기법("[]")으로 접근하고 값을 설정할 수 있습니다.

- -
var unusualPropertyNames = {
-  "": "An empty string",
-  "!": "Bang!"
-}
-console.log(unusualPropertyNames."");   // SyntaxError: Unexpected string
-console.log(unusualPropertyNames[""]);  // An empty string
-console.log(unusualPropertyNames.!);    // SyntaxError: Unexpected token !
-console.log(unusualPropertyNames["!"]); // Bang!
-
- -

향상된 객체 리터럴

- -

ES2015에서, 객체 리터럴은 구성에서 프로토타입 설정, foo: foo 할당을 위한 단축 표기, 메서드 정의, super 클래스 호출 및 식으로 동적인 속성명 계산을 지원하기 위해 확장됐습니다. 그에 따라 객체 리터럴 및 클래스 선언이 함께 더 가까워지고, 객체 기반 설계는 같은 일부 편의기능으로 득을 볼 수 있습니다.

- -
var obj = {
-    // __proto__
-    __proto__: theProtoObj,
-    // ‘handler: handler’의 단축 표기
-    handler,
-    // Methods
-    toString() {
-     // Super calls
-     return "d " + super.toString();
-    },
-    // Computed (dynamic) property names
-    [ 'prop_' + (() => 42)() ]: 42
-};
- -

아래를 참고하세요.

- -
var foo = {a: "alpha", 2: "two"};
-console.log(foo.a);    // alpha
-console.log(foo[2]);   // two
-//console.log(foo.2);  // Error: missing ) after argument list
-//console.log(foo[a]); // Error: a is not defined
-console.log(foo["a"]); // alpha
-console.log(foo["2"]); // two
-
- -

정규식 리터럴

- -

정규식 리터럴은 (정규식 상세) 슬래시 사이에 감싸인 패턴입니다. 다음은 정규식 리터럴 예제입니다.

- -
var re = /ab+c/;
- -

문자열 리터럴

- -

문자열 리터럴은 큰 따옴표(") 혹은 작은 따옴표(')로 묶인 0개 이상의 문자입니다. 문자열은 같은 형 따옴표, 즉 큰 따옴표 쌍이나 작은 따옴표 쌍으로 구분되어야 합니다. 아래는 문자열 리터럴의 예제입니다.

- -
"foo"
-'bar'
-"1234"
-"one line \n another line"
-"John's cat"
-
- -

문자열 리터럴 값은 문자열 객체의 모든 메서드를 호출할 수 있습니다. JavaScript는 자동으로 문자열 리터럴을 임시 문자열 객체로 변환, 메서드를 호출하고 나서 임시 문자열 객체를 폐기합니다. 또한 문자열 리터럴에서도 String.length 속성을 사용할 수 있습니다.

- -
console.log("John's cat".length)
-// 공백을 포함한 문자열 내 심볼 갯수가 출력됩니다.
-// 여기서는, 10.
-
- -

ES2015에서는, 템플릿 리터럴도 사용할 수 있습니다. 템플릿 문자열은 문자열 구성을 위한 달콤한 구문을 제공합니다. 이는 Perl, Python 등에 있는 문자열 삽입(interpolation) 기능과 비슷합니다. 마음대로, 문자열 구성을 사용자 정의하고 인젝션 공격을 피하거나 문자열 콘텐츠로 더 고레벨 데이터 구조를 구성하기 위한 태그가 추가될 수 있습니다.

- -
// 기본적인 문자열 리터럴 생성
-`In JavaScript '\n' is a line-feed.`
-
-// 여러 줄 문자열
-`In JavaScript this is
- not legal.`
-
-// 문자열 삽입
-var name = "Bob", time = "today";
-`Hello ${name}, how are you ${time}?`
-
-// Construct an HTTP request prefix is used to interpret the replacements and construction
-POST`http://foo.org/bar?a=${a}&b=${b}
-     Content-Type: application/json
-     X-Credentials: ${credentials}
-     { "foo": ${foo},
-       "bar": ${bar}}`(myOnReadyStateChangeHandler);
- -

꼭 문자열 객체를 사용할 필요가 없는 경우 문자열 리터럴을 사용해야 합니다. 문자열 객체에 대해 자세한 사항은 {{jsxref("String")}}을 참고하세요.

- -

문자열에서 특수 문자 사용

- -

보통 문자에 더해서, 문자열에 아래 예제와 같이 특수 문자도 포함할 수 있습니다.

- -
"one line \n another line"
-
- -

다음 표는 JavaScript 문자열에 사용할 수 있는 특수 문자 목록입니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
표: JavaScript 특수 문자
문자
\0Null Byte
\bBackspace
\fForm feed
\nNew line
\rCarriage return
\tTab
\vVertical tab
\'Apostrophe 혹은 작은 따옴표
\"큰 따옴표
\\백슬래시
\XXXLatin-1 인코딩 문자는 0 - 377 사이 8진수 3자리까지 지정될 수 있습니다. 예를 들어, \251은 copyright 심볼을 표현하는 8진수 시퀀스입니다.
\xXXLatin-1 인코딩 문자는 00 - FF 사이의 16진수 2자리로 지정될 수 있습니다. 예를 들어, \xA9는 copyright 심볼을 표현하는 16진수 시퀀스입니다.
\uXXXX유니코드 문자는 16진수 4자리로 지정될 수 있습니다. 예를 들어, \u00A9는 copyright 심볼을 표현하는 유니코드 열입니다. Unicode escape sequences를 참고하세요.
\u{XXXXX}유니코드 코드 포인트 이스케이프. 예를 들어, \u{2F804}는 간단한 유니코드 이스케이프 \uD87E\uDC04와 같습니다.
- -

문자 이스케이프

- -

표에 없는 문자의 경우 전행 백슬래시는 무시되지만, 이 용법은 더 이상 사용되지 않으며, 사용을 피해야 합니다.

- -

전행 백슬래시와 함께 문자열 안에 따옴표를 사용할 수 있습니다. 이것을 따옴표 이스케이프라고 합니다. 예를 들어,

- -
var quote = "He read \"The Cremation of Sam McGee\" by R.W. Service.";
-console.log(quote);
-
- -

이 코드의 결과는,

- -
He read "The Cremation of Sam McGee" by R.W. Service.
-
- -

백슬래시를 문자열 내에 포함시키기 위해서는, 백슬래시 문자를 이스케이프 해야 합니다. 예를 들어, 파일 경로 c:\temp를 문자열에 할당하기 위해서는 아래와 같이 사용합니다.

- -
var home = "c:\\temp";
-
- -

또한 줄바꿈 역시 전행 백슬래시로 이스케이프할 수 있습니다. 백슬래시와 줄바꿈 모두 문자열 값에서는 사라집니다.

- -
var str = "this string \
-is broken \
-across multiple\
-lines."
-console.log(str);   // this string is broken across multiplelines.
-
- -

JavaScript에는 "heredoc" 구문은 없지만, 줄바꿈 이스케이프와 각 줄 끝 이스케이프된 줄바꿈을 추가하여 흉내낼 수 있습니다.

- -
var poem =
-"Roses are red,\n\
-Violets are blue.\n\
-I'm schizophrenic,\n\
-And so am I."
-
- -

ECMAScript 2015에서는 템플릿 리터럴(template literals)이라는 새로운 리터럴이 소개되었습니다. 이 것은 다중 문자열을 포함한 많은 새로운 기능을 가지고 있습니다!

- -
var poem =
-`Roses are red,
-Violets are blue.
-Sugar is sweet,
-and so is foo.`
-
- -

추가 정보

- -

이 장은 선언과 형에 대한 기본 구문에 초점을 맞춥니다. JavaScript 언어 구조에 대해 더 많이 배우려면, 다음 장을 참고하세요.

- - - -

다음 장에서는, 흐름 제어 구조와 오류 처리를 살핍니다.

- -

{{PreviousNext("Web/JavaScript/Guide/소개", "Web/JavaScript/Guide/Control_flow_and_error_handling")}}

diff --git "a/files/ko/web/javascript/guide/\352\260\235\354\262\264_\353\252\250\353\215\270\354\235\230_\354\204\270\353\266\200\354\202\254\355\225\255/index.html" "b/files/ko/web/javascript/guide/\352\260\235\354\262\264_\353\252\250\353\215\270\354\235\230_\354\204\270\353\266\200\354\202\254\355\225\255/index.html" deleted file mode 100644 index 230d5cb9e1..0000000000 --- "a/files/ko/web/javascript/guide/\352\260\235\354\262\264_\353\252\250\353\215\270\354\235\230_\354\204\270\353\266\200\354\202\254\355\225\255/index.html" +++ /dev/null @@ -1,714 +0,0 @@ ---- -title: 객체 모델의 세부 사항 -slug: Web/JavaScript/Guide/객체_모델의_세부사항 -translation_of: Web/JavaScript/Guide/Details_of_the_Object_Model ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
- -

자바스크립트는 클래스 기반이 아닌 prototype에 기초한 객체 기반 언어 입니다. 이런 차이점으로 인해, 객체들의 계층 구조의 생성과 속성 및 속성 값의 상속을 어떻게 구현해야 하는지에 대한 부분이 덜 분명할 수 있습니다. 이번 장에서는 이런 상황을 명확하게 하고자 합니다. 

- -

이번 장에선 이미 자바스크립트를 어느 정도 알고 있고, 간단한 객체를 생성하는 함수들을 사용해보았다는 가정하에 진행합니다.

- -

클래스 기반 언어 대 프로토타입 기반 언어

- -

Java와 C++같은 클래스 기반의 언어들은 두개의 구별되는 개념에 기반을 두고 있습니다: 그건 바로 클래스와 인스턴스입니다.

- -
    -
  • 클래스는  특정 객체군을 특징 짓는 모든 속성들(Java에서는 메서드들과 필드들을 , C++에서는  멤버들을 속성으로 간주합니다. )을 정의합니다.클래스는 해당 객체군을 표현할 수 있는 특정 멤버를 지칭하는 것이 아닌 그보다 더 추상적인 것입니다. 예를 들어, 직원클래스는 직원들을 대표할 수 있습니다.
  • -
  • 반면 인스턴스는 클래스를 기반으로 실체화된 것입니다. 예를 들어, 빅토리아는 특정 직원 개인을 나타내는 직원클래스의 인스턴스가 될 수 있습니다. 인스턴스는 부모 클래스의 속성과 동일한 속성들을 가집니다.
  • -
- -

자바스크립트같은 프로토타입기반의 언어들은 위와 같은 클래스와 인스턴스의 차이를 두지 않습니다. 간단하게 객체들을 가질 뿐입니다. prototype기반의 언어는 원형(프로토타입)의 객체 개념을 가지고 있습니다. 하나의 객체는 새로운 객체를 생성했을 때 초기 속성을 가질 수 있도록 하는 형판(template)으로 사용됩니다. 객체는 생성될 때 혹은 실행 시에 자기 자신의 속성을 명시할 수 있습니다. 추가적으로, 객체들은 또 다른 객체를 생성하기 위한 프로토타입으로 연관지어 질 수 있으며 프로토타입으로부터 생성된 두번째 객체가 프로토타입인 첫번째 객체의 속성을 공유(혹은 접근)하는 것을 허용합니다. 

- -

클래스 정의

- -

클래스 기반의 언어들에서, 별도의 클래스를 생성하고 그 안에서 해당 클래스를 정의 할 수 있습니다. 해당 정의에서 클래스의 인스턴스를 생성할 수 있는 생성자라고하는 특별한 메서드를 명시할 수 있습니다. 생성자는 해당 인스턴스의 초기 속성 값을 지정할 수 있고, 생성 시점에, 다른 적절한 처리를 수행 할 수 있습니다. 클래스의 인스턴스를 생성하기 위해서 new 연산자와 함께 생성자를 호출해야 합니다. 

- -

자바스크립트는 위와 비슷한 방법을 취합니다. 하지만 생성자이외에 따로 클래스 정의를 가지고 있지는 않습니다. 대신, 특정 속성및 속성값들을 가지고 객체를 생성하는 생성자 함수를 정의할 수 있습니다. 특정 자바스크립트 함수는 생성자로 사용 될 수 있습니다. 새로운 객체를 생성할려면 new연산자와 함께 생성자 함수를 사용해야 합니다.

- -
-

ECMAScript 2015에 클래스 선언이 새롭게 소개되었습니다.

- -
-

ECMAScript 2015에서 소개된 자바스크립트 클래스는 주로 문법적 설탕으로 기존 자바스크립트 프로토타입 기반 상속에  읽기 좋은 형식으로 바뀌었습니다. 이 클래스 문법이 자바스크립트에 새로운 객체 중심 상속 모델을 소개한 것은 아닙니다.

-
-
- -

하위 클래스와 상속

- -

클래스 기반 언어에서는 클래스 정의를 통해 클래스 계층구조를 생성합니다. 클래스를 정의할 때 이미 존재하는 클래스의 하위 클래스를 새로운 클래스로 지정할 수 있습니다. 이 하위 클래스는 부모 클래스의 모든 속성을 상속받으며 추가로 새로운 속성을 추가하거나 상속받은 속성을 수정할 수 있습니다. 예를 들어  이름(name)과 부서(dept)을 가진 직원(Employee) 클래스와 그 하위 클래스에 보고(reports) 속성을 추가한 관리자(Manager) 클래스가 있다고 해봅시다. 이 경우 관리자(Manager)의 인스턴스는 다음과 같이 세가지 속성을 모두 가질 수 있습니다 - 이름(name),  부서(dept),  보고(reports).

- -

자바스크립트는 생성자 함수와 프로토타입 객체를 연결해 상속을 구현합니다. 이런 식으로 직원(Employee) — 관리자(Manager) 예제를 똑같이 구현할 수 있지만 조금 다른 * 사용합니다. 먼저, 이름(name),  부서(dept) 속성을 명시하여 직원(Employee) 생성자 함수를 정의합니다. 그런 다음, 직원(Employee)의 생성자를 호출한 후 보고(reports) 속성을 명시해 관리자(Manager) 생성자 함수를 정의합니다. 마지막으로 Employee.prototype 에서 파생된 새로운 객체를  관리자(Manager) 생성자 함수의 프로토타입으로 지정합니다. 그런 다음 새로운 관리자(Manager)를 만들면 관리자(Manager) 객체를 직원(Employee) 객체로부터 이름(name),  부서(dept) 속성을 상속받습니다. 

- -

속성의 추가 삭제

- -

클래스 기반의 언어들에서는, 일반적으로 컴파일 시점에 클래스를 생성한 후에 컴파일 시점 혹은 실행 시에 해당 클래스의 인스턴스를 생성합니다. 클래스가 한번 정의된 후에 클래스를 다시 컴파일 하지 않는다면, 속성의 갯수나 형식을 변경할 수 없습니다. 하지만 자바스크립트에서느 실행 시에 객체의 속성을 추가 혹은 삭제 할 수 있습니다.  만약 객체군의 프로토타입으로 사용되는 객체에 속성을 추가하면, 프로토타입이 되는 객체들에도 새로운 속성이 추가가 됩니다.

- -

차이점들에 대한 정리

- -

다음 표는 이런 차이점들에 대한 간략한 요약을 포함하고 있습니다. 이번 장의 다음 내용들은 객체의 계층 구조를 생성하기 위한 자바스크립트 생성자와 프로토타입들의 사용에 대한 세부 사항에 대해 기술합니다. 그리고 동일한 작업을 자바에서 어떻게 처리해야 하는지도 비교해서 살펴보겠습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
클래스 기반(자바)과 프로토타입(prototype)기반(자바스크립트) 객체 시스템의 비교
클래스 기반(자바)원형 기반(자바스크립트)
클래스와 인스턴스는 별개입니다.모든 객체는 다른 객체로부터 상속을 받습니다.
클래스 정의를 가지고 클래스를 생성하고 생성자 메서드로 인스턴스를 생성합니다.생성자 함수를 가지고 객체군을 정의 및 생성합니다.
new 연산자로 하나의 객체(인스턴스)를 생성합니다.동일합니다.
이미 존재하는 클래스에 대한 하위 클래스를 정의함으로써 객체의 계층구조를 생성합니다.하나의 객체를 생성자 함수와 결합된 프로토타입에 할당함으로써 객체의 계층구조를 생성 합니다.
클래스의 상속 구조에 따라 속성을 상속 받습니다.프로토타입 체인에 따라  속성을 상속 받습니다.
클래스 정의는 모든 인스턴스의 모든 속성을 명시합니다. 실행시에 동적으로 속성을 추가할 수 없습니다.생성자 함수 혹은 프로토타입은 초기 속성들을 명시합니다. 개별 객체 혹은 전체 객체군에 동적으로 속성을 추가 삭제할 수 있습니다.
- -

직원 예제

- -

이장의 나머지 부분에서는 다음과 같은 직원 객체의 계층구조를 사용합니다. 

- -
-

직원 객체의 계층 구조.

- -

- -
    -
  • 직원(Employee) 객체는 빈 문자열을 기본값으로 가지는 이름(name) 그리고 "일반(general)"을 기본 값으로 가지는 부서(dept)를 속성으로 가집니다.
  • -
  • 관리자(Manager)객체는 직원(Employee) 객체를 근간으로 하며, 직원 객체들을 포함하기 위한 빈 배열을 기본 값으로 하는 보고(reports)속성을 가지고 있습니다.
  • -
  • 근로자(WorkerBee)객체 또한 직원(Employee) 객체를 근간으로 하며, 문자열들을 포함하기 위한 빈 배열을 기본 값으로 하는 프로젝트(projects)속성을 가집니다.
  • -
  • 영업사원(SalesPerson)객체는 또한 근로자(WorkerBee) 객체를 근간으로 하며, 100을 기본값으로 하는 할당량(quota)를 속성으로 가집니다. 또한 같은 부서내의 모든 영업사원을 지칭하기 위한 부서 속성을 "판매부서"로 재정의 합니다. 
  • -
  • 엔지니어(Engineer)객체도 근로자(WorkerBee) 객체를 근간으로 하며, 빈 문자열을 기본값으로 가지는 장비(machine) 속성을 가집니다.그리고 엔지니어링(engineering)이라는 값으로 부서 속성을 재정의 합니다.
  • -
-
- -

계층 구조 생성

- -

직원 계층 구조를 구현하기 위한 적절한 생성자 함수를 정의하는 방법에는 여러가지가 있습니다. 개발하려고 하는 어플리케이션에 따라 생성자 함수를 정의 하는 방법은 달라질 수 있습니다. 

- -

이번 절에서는 상속을 구현하기 위한 간단한 (비교적 유연하지는 않은) 정의 방법을 보여 줄 것입니다. 이런 정의 방법을 사용하게되면, 객체를 생성할 때 어떤 속성 값도 지정을 할 수 없습니다. 새로이 생성된 객체들은 기본값들을 가지고 있으며, 나중에 해당 속성 값들을 변경할 수 있습니다.

- -

실제 어플리케이션에서는, 객체를 생성할때, 해당 객체가 가져야할 속성을 인자로 받는 생성자를 정의 할수 있습니다.(보다 자세한 사항은 다음을 참조하세요. More flexible constructors). 지금 당장은, 상속이 어떻게 작동하는지를 보여주기 위한 간단한 예제를 사용합니다. 

- -

다음의 자바와 자바스크립트로 작성된 직원 정의는 비슷합니다. 차이점은 자바언어에서는 개별 속성에 대한 타입(type)을 일일이 지정을 해야 하지만  자바스크립트에서는 일일이 개별 속성에 대한 타입(type)을 지정할 필요가 없다는 것입니다.(이런 이유로 자바스크립트가 약하게 형식화된 언어로 불리는 반면 자바는 강력하게 형식화된 언어로 불립니다.)

- - - - - - - - -
-

자바스크립트

- -
-function Employee() {
-  this.name = "";
-  this.dept = "general";
-}
-
-

자바

- -
-public class Employee {
-   public String name = "";
-   public String dept = "general";
-}
-
-
- -

관리자와 근로자 정의는 계층 구조상에서 상위에 위치하는 객체를 어떻게 표시하는지에 대한 차이점을 보여 줍니다. 자바스크립트에서는 생성자 함수 정의 이후에 언제든 생성자 함수의 프로토타입(prototype) 속성의 값으로 프로토타입 인스턴스를 추가할 수 있습니다.  자바에서는 클래스 정의에 상위 클래스를 명시해야 합니다. 클래스 정의 이후에는 상위 클래스를 변경할 수 없습니다.

- -
-

자바스크립트

- -
function Manager() {
-  Employee.call(this);
-  this.reports = [];
-}
-Manager.prototype = Object.create(Employee.prototype);
-
-function WorkerBee() {
-  Employee.call(this);
-  this.projects = [];
-}
-WorkerBee.prototype = Object.create(Employee.prototype);
-
- -

자바

- -
public class Manager extends Employee {
-   public Employee[] reports = new Employee[0];
-}
-
-
-
-public class WorkerBee extends Employee {
-   public String[] projects = new String[0];
-}
-
-
-
-
- -

엔지니어와 영업사원 정의들은 객체들을 생성합니다. 생성된 객체는 근로자 객체의 하위 객체이고 따라서 직원 객체의 하위 객체가 됩니다. 상속 관계에 따라 엔지니어와 영업사원 객체들은 근로자와 직원객체의 속성을 가지게 됩니다. 게다가, 상속받은 부서 속성은 엔지니어와 영업사원에서 재정되어 새로운 값을 가지게 됩니다. 

- -
-

자바스크립트

- -
function SalesPerson() {
-   WorkerBee.call(this);
-   this.dept = "sales";
-   this.quota = 100;
-}
-SalesPerson.prototype = Object.create(WorkerBee.prototype);
-
-function Engineer() {
-   WorkerBee.call(this);
-   this.dept = "engineering";
-   this.machine = "";
-}
-Engineer.prototype = Object.create(WorkerBee.prototype);
-
- -

Java

- -
public class SalesPerson extends WorkerBee {
-   public double quota;
-   public dept = "sales";
-   public quota = 100.0;
-}
-
-
-public class Engineer extends WorkerBee {
-   public String machine;
-   public dept = "engineering";
-   public machine = "";
-}
-
-
- -

이런 정의 방법을 통해, 기본값을 가지는 각각의 속성을 포함하는 객체의 인스턴스를 생성할 수 있습니다. 다음 그림은 새로운 객체를 생성하고 새로운 객체에 대한 속성값들을 보여 표시하기 위한 자바스크립트의 정의들을 보여 줍니다.

- -
-

유의사항: 클래스 기반 언어들에서 인스턴스라는 용어는 특정한 기술적 의미를 가지고 있습니다. 이러한 언어들에서,  하나의 인스턴스란 하나의 클래스의 개별적인  실체이며 클래스와는 근본적으로 다릅니다. 자바스크립트에서는 클래스와 인스턴스 간의 차이가 없기 때문에, "인스턴스"가 이런 기술적 의미를 갖지 않습니다. 하지만, 자바스크립트에 대해서 얘기하자면, 비공식적으로 "인스턴스"는 특정한 생성자 함수를 이용하여 생성된 오브젝트를  의미합니다. 그래서 이번 예제에서는 jane Engineer 의 인스턴스라고 할 수 있습니다. 이와 유사하게, 부모, 자식, 상위, 하위의 용어들은 자바스크립트에서 공식적인 의미를 갖지 않습니다; 다만 프로토타입 체인 상의 상위 또는 하위 객체를 지칭하기 위해서 비공식적으로 사용할 수 있습니다.

-
- -

간단한 정의로 객체 생성

- -
-

객체의 계층구조

- -

오른쪽에 보이는 코드로 생성된 객체의 계층 구조는 아래와 같습니다.

- -

- -

개별 객체들

- -
var jim = new Employee;
-// jim.name is ''
-// jim.dept is 'general'
-
-var sally = new Manager;
-// sally.name is ''
-// sally.dept is 'general'
-// sally.reports is []
-
-var mark = new WorkerBee;
-// mark.name is ''
-// mark.dept is 'general'
-// mark.projects is []
-
-var fred = new SalesPerson;
-// fred.name is ''
-// fred.dept is 'sales'
-// fred.projects is []
-// fred.quota is 100
-
-var jane = new Engineer;
-// jane.name is ''
-// jane.dept is 'engineering'
-// jane.projects is []
-// jane.machine is ''
-
-
- -

객체 속성들

- -

이번 장에서는 객체가 프로토타입체인 상의 다른 객체로부터 특성을 상속받는 방법과 런타임 상에서 프로퍼티를 추가하면 무슨 일이 일어나는 지 살펴봅니다.

- -

속성 상속

- -

아래 구문처럼 WorkerBee 생성자로 mark 객체를 생성했다고 가정합니다.

- -
var mark = new WorkerBee;
-
- -

new 연산자를 만나면, 자바스크립트는 새로운 일반 객체를 생성하고 암묵적으로 내부의 [[Prototype]](__proto__) 속성의 값을 WorkerBee.prototype 의 값으로 할당하며, 해당 객체를 this 키워드의 값으로써 생성자 함수 WorkerBee에 전달합니다. 내부의 [[Prototype]] 속성은 속성값을 반환하기 위해 사용할 프로토타입 체인을 결정합니다. 이런 속성들이 할당되면, 자바스크립트는 새 객체를 반환하고, 할당 구문에 의해 변수 mark를 객체에 할당합니다.

- -

이러한 절차는 mark가 프로토타입 체인으로부터 상속받는  속성의 값을 mark 객체 내부에(local values) 명시적으로 부여하진 않습니다. 당신이 속성의 값을 요청하면, 자바스크립트는 먼저 해당 객체에 값이 존재하는지 확인합니다. 존재한다면, 해당 값이 반환됩니다. 만약 해당 객체에 값이 없다면, 프로토타입 체인을 (내장 [[Prototype]] 속성;__proto__을 이용하여)확인합니다. 체인 상의 어떤 객체가 해당 속성의 값을 가지고 있다면 그 값이 반환됩니다. 그런 속성이 발견되지 않는다면, 자바스크립트는 객체가 속성을 가지고있지 않다고 할 것입니다. 이런 식으로, mark 객체는 다음의 속성과 값을 가집니다.

- -
mark.name = "";
-mark.dept = "general";
-mark.projects = [];
- -

mark 객체는 mark.__proto__로 연결되어 있는 원형의 객체로부터 이름(name)과 부서(dept)에 대한 값을 상속 받습니다. 근로자(WorkerBee) 생성자로부터 projects속성에 대한 값을 할당을 받습니다.이것들이 자바스크립트내에서 속성과 속성 값의 상속입니다. 이런 과정의 몇몇 세부 사항들은 Property inheritance revisited에서 다룹니다. 

- -

이런 생성자들은 당신이 직접 인스턴스에만 해당 하는 값을 설정하도록 하지 않기때문에, 객체에 대한 이런 정보들은 일반적으로 적용됩니다. 근로자(WorkerBee)로부터 생성된 모든 새로운 객체들은 기본값이 적용된 속성 값들을 가지게 됩니다. 물론, 속성 값들을 변경할 수 있습니다. 아래처럼 특정 인스턴스에만 해당하는 값을 설정할 수 있습니다. 

- -
mark.name = "Doe, Mark";
-mark.dept = "admin";
-mark.projects = ["navigator"];
- -

속성 추가

- -

자바스크립트에선, 실행 시점에 특정 객체에 속성들을 추가 할 수 있습니다.생성자 함수가 제공하는 속성외에 다른 속성을 추가할 수 있습니다. 특정 단일 객체에 속성을 추가하기 위해선, 다음과 같이 해당 객체에 값을 할당 하면 됩니다:

- -
mark.bonus = 3000;
-
- -

이렇게 하면 mark객체는 보너스(bonus)속성을 가지게 됩니다. 하지만 mark객체를 제외한 나머지 근로자(WorkerBee)객체들은 보너스 속성을 가지지 않습니다. 

- -

만약 생성자 함수의 원형으로 사용되는 객체에 새로운 속성을 추가한다면,  해당 프로토타입 객체(prototype)의 속성을 상속받는 모든 객체에 해당 속성이 추가됩니다. 예를 들면, 전문분야(specialty)속성을 모든 직원 객체에 다음과 같은 구문으로 추가할 수 있습니다:

- -
Employee.prototype.specialty = "none";
-
- -

위의 구문을 실행한 직후, mark객체는 "none"이라는 값을 가지는 전문분야(specialty)속성을 가지게 됩니다.아래의 그림들은 해당 속성을 추가한 후 엔지니어(Engineer) 프로토타입에 대해 해당 속성을 재정의 했을 경우 각 객체에 미치는 영향을 보여줍니다.

- -


- 속성의 추가

- -

좀 더 유연한 생성자들

- -

지금까지 살펴 본 생성자 함수들은 인스턴스를 생성하면서 동시에 속성값을 지정할 수 없었습니다. 자바의 경우, 인스턴스를 생성 시 생성자에 인자들을 넘겨주어 인스턴스의 속성들을 초기화 할 수 있습니다. 다음의 예제 그림들은 자바처럼 인스턴스 생성 시 속성값을 설정하는 방법을 보여줍니다.

- -


- Specifying properties in a constructor, take 1

- -

다음의 표는 자바와 자바스크립트 각각의 생성자와 객체에 대한 정의를 보여 줍니다. 

- -
-

자바스크립트

- -

자바

-
- -
-
function Employee (name, dept) {
-  this.name = name || "";
-  this.dept = dept || "general";
-}
-
- -
public class Employee {
-   public String name;
-   public String dept;
-   public Employee () {
-      this("", "general");
-   }
-   public Employee (String name) {
-      this(name, "general");
-   }
-   public Employee (String name, String dept) {
-      this.name = name;
-      this.dept = dept;
-   }
-}
-
-
- -
-
function WorkerBee (projs) {
-
- this.projects = projs || [];
-}
-WorkerBee.prototype = new Employee;
-
- -
public class WorkerBee extends Employee {
-   public String[] projects;
-   public WorkerBee () {
-      this(new String[0]);
-   }
-   public WorkerBee (String[] projs) {
-      projects = projs;
-   }
-}
-
-
- -
-
-function Engineer (mach) {
-   this.dept = "engineering";
-   this.machine = mach || "";
-}
-Engineer.prototype = new WorkerBee;
-
- -
public class Engineer extends WorkerBee {
-   public String machine;
-   public Engineer () {
-      dept = "engineering";
-      machine = "";
-   }
-   public Engineer (String mach) {
-      dept = "engineering";
-      machine = mach;
-   }
-}
-
-
- -

자바스크립트의 속성값을 설정하는 방법은 기본값을 설정하기 위한 관용구를 사용합니다.

- -
this.name = name || "";
-
- -

자바스크립트의 OR 논리 연산자(||) 첫번째 인자를 평가합니다. 첫번째 인자가 참이면 첫번째 인자를 반환하고 그렇지 않은 경우는 두번째 인자를 반환합니다. 그러므로, 위의 코드는 name인자가 name 속성에 사용 가능한 값을 가지고 있는지 확인합니다. 확인 결과 name속성에 사용가능한 값을 가지고 있을 경우, 해당 값을 this.name에 설정하게 됩니다. 반대로 그렇지 않은 경우는 빈 문자열을 this.name에 설정합니다.얼핏 보면 헛갈리지만 보다 짧은 관용구를 사용하였습니다.

- -
-

주의: 만약 인자로 false와 빈 문자열 값을 줄 경우 해당 구문은 예상한 대로 작동하지 않을 수 있습니다.

-
- -

이런 정의들을 가지고, 객체의 인스턴스를 생성할때, 객체 자신만의 속성에 대한 값을 지정할 수 있습니다. 새로운 Engineer를 생성하기 위해서 다음과 같은 구문을 사용할 수 있습니다:

- -
var jane = new Engineer("belau");
-
- -

Jane의 속성들은 다음과 같습니다:

- -
jane.name == "";
-jane.dept == "engineering";
-jane.projects == [];
-jane.machine == "belau"
-
- -

위와 같은 코드 구문으로는 name과 같이 상속받은 속성에 대한 초기값을 지정할 수 없습니다.만약 상속 받은 속성의 초기값을 설정하고자 한다면, 생성자 함수의 코드를 변경해야 합니다.

- -

지금까지, 원형 객체를 생성한 후, 그 새로운 객체 자신의 속성과 속성 값을 지정하는 것을 살펴 보았습니다. 프로토타입 체인상에서 해당 생성자가 상위 객체에 대한 생성자를 직접 호출 함으로써 더 많은 속성을 추가하도록 할 수 있습니다. 다음의 그림은 새로운 정의 방법을 보여 줍니다.

- -


- 생성자내에서 속성들 정의, 그림 2

- -

그럼 좀 더 상세하게 생성자 내에서 속성들을 정의하는 것을 살펴 보겠습니다. 다음은 엔지니어(Engineer) 생성자의 새로운 정의입니다:

- -
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-
- -

다음과 같이 새로운 엔지니어(Engineer)객체를 생성할 수 있습니다:

- -
var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-
- -

다음과 같은 순서에 따라 객체를 생성하고 속성을 정의하게 됩니다:

- -
    -
  1. new 연산자는 프로토타입 객체를 생성하고 생성된 객체의 __proto__속성을 Engineer.prototype으로 설정합니다.
  2. -
  3. new 연산자는 새로이 생성된 객체를 엔지니어(Engineer)생성자에 this 키워드의 값으로 전달합니다.
  4. -
  5. 생성자는 생성한 객체에 대한 base라는 새로운 속성을 생성하고 근로자(WorkerBee) 생성자의 값을 base 속성에 할당합니다. 이런 과정은 근로자(WorkerBee) 생성자를 엔지니어(Engineer)객체의 메서드로 만듭니다. base 속성의 이름은 그리 특별하지 않습니다. 다른 어떤 속성명을 사용해도 무방합니다. base 속성명은 단지 해당 속성의 목적을 환기시키기 위한 것입니다.
  6. -
  7. -

    생성자는 base 메서드에 필요한 인자들 ("Doe, Jane" and ["navigator", "javascript"])을 주어 호출합니다.명시적으로 생성자에서 사용한 "engineering"은 모든 엔지니어(Engineer)객체들이 상속받은 부서 속성에 대한 동일한 값을 가지며, 직원(Employee)으로부터 상속받은 값을 재정의 하는 것을 나타냅니다.

    -
  8. -
  9. base가 엔지니어(Engineer)의 메서드이기때문에 base메서드 내에서 this키워드를 스텝1에서 생성한 객체를 지칭하도록 해줍니다. 따라서, 근로자(WorkerBee) 함수는 차례대로 "Doe, Jane""engineering" 인자를 직원(Employee)생성자에 전달합니다. 직원(Employee)생성자로부터 반환 시, 근로자(WorkerBee)함수는 남은 인자들을 프로젝트(projects)속성을 설정하기 위해 사용합니다. 
  10. -
  11. base메서드로부터 반환 시, 엔지니어(Engineer) 생성자는 해당 객체의 장비(machine)속성을 "belau"로 초기화 합니다.
  12. -
  13. 생성자로부터 반환 시, 새롭게 생성된 객체를 jane변수에 할당 합니다.
  14. -
- -

엔지니어(Engineer) 생성자내에서 근로자(WorkerBee)생성자를 호출하면, 엔지니어(Engineer)에 대한 상송을 적절하게 설정할 수 도 있을 것이라고 생각할 수 있을 것입니다.하지만 그렇지 않습니다. 근로자(WorkerBee)생성자를 호출하는 것은 엔지니어(Engineer)객체로 하여금 호출되는 모든 생성자 함수내에서 열거된 속성들을 가지고도록 보장합니다.그러나, 나중에 직원(Employee)혹은 근로자(WorkerBee) 원형에 속성을 추가한다면, 엔지니어(Engineer)객체에 의해 추가된 속성들은 상속이 되지 않습니다. 예를 들어, 아래와 같은 구문을 작성하였다고 가정합니다:

- -
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-Employee.prototype.specialty = "none";
-
- -

jane객체는 전문분야(specialty)속성을 상속받지 않습니다.

- -
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-Engineer.prototype = new WorkerBee;
-var jane = new Engineer("Doe, Jane", ["navigator", "javascript"], "belau");
-Employee.prototype.specialty = "none";
-
- -

이제 jane객체의 전문분야(specialty)속성은 "none"이 되었습니다.

- -

call() 혹은 apply() 메서드를 사용는 것은 상속을 구현하는 또 다른 방법입니다. 다음의 두 예제는 동일한 결과를 보여줍니다. 

- -
-
function Engineer (name, projs, mach) {
-  this.base = WorkerBee;
-  this.base(name, "engineering", projs);
-  this.machine = mach || "";
-}
-
- -
function Engineer (name, projs, mach) {
-  WorkerBee.call(this, name, "engineering", projs);
-  this.machine = mach || "";
-}
-
-
- -

base를 사용하지 않고 구현을 하기 때문에, call() 메서드를 사용하여 상속을 구현하는 것이 보다 깔끔합니다.

- -

속성 상속의 재고

- -

이전 절에서 자바스크립트의 생성자와 원형(prototype)이 어떤 방식으로 상속과 객체의 계층 구조를 제공하는지를 살펴 보았습니다. 이번장에서는 이전 절에서 반드시 명백하게 짚고 넘어가지 않은 일부 미묘한 점들에 대해 살펴보겠습니다.

- -

객체 자신의 값과 상속받은 값

- -

이번 장에서 이미 설명된 것 처럼, 객체의 속성에 접근할 때, 자바스크립트는 아래와 같은 절차를 따릅니다.

- -
    -
  1. 해당 속성에 대한 객체 자신의 값이 있는지 확인하고 있으면 그 값을 반환한다.
  2. -
  3. 객체 자신의 값이 없으면 __proto__ 속성을 사용하여 프로토타입 체인을 확인한다.
  4. -
  5. 프로토타입 체인상의 특정 객체가 해당 속성에 대한 값을 가지고 있다면 해당 객체의 값을 반환한다.
  6. -
  7. 해당 속성을 가진 어떤 객체도 발견하지 못하면 해당 객체는 그 속성을 가지고 있지 않은 것으로 판단한다.
  8. -
- -

이런 단계들의 결과는 생성자 및 프로토타입 체인등의 것들을 어떻게 정의 하느냐에 따라 달라집니다. 아래와 같은 원래의 예제는 이런 정의들을 가지고 있습니다:

- -
function Employee () {
-  this.name = "";
-  this.dept = "general";
-}
-
-function WorkerBee () {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
- -

이런 정의들을 가지고, amy라는 근로자(WorkerBee)인스턴스를 아래와 같이 생성하였다고 가정합니다.

- -
var amy = new WorkerBee;
-
- -

amy객체는 프로젝트라는 자신만의 속성을 가집니다.이름과 부서 속성들은 amy 자신의 속성이 아닌 amy객체의 __proto__속성을 통해 가지고 온 속성들입니다. 따라서 amy는 이런 속성들의 값을 가지게 됩니다.

- -
amy.name == "";
-amy.dept == "general";
-amy.projects == [];
-
- -

직원(Employee)과 연관되어 있는 프로토타입내의 이름 속성의 값을 아래와 같이 변경하였다고 가정합니다.

- -
Employee.prototype.name = "Unknown"
-
- -

얼핏보기에, 새로운 값이 모든 직원 인스턴스에 적용이 될것으로 예상하겠지만 그렇지 않습니다. 

- -

직원 객체의 인스턴스를 생성할때, 해당 인스턴스는 이름 속성에 대해 자신이 가지고 있는 값(빈 문자열)을 취하게 됩니다.이것이 의미하는 것은 새로운 직원 객체를 생성하여 근로자(WorkerBee)의 프로토타입에 설정을 할때, WorkerBee.prototype이 이름 속성에 대한 자신만의 값을 가지고 있다는 것입니다.그러므로, amy객체(근로자 인스턴스)의 이름 속성에 대해 검색할때, WorkerBee.prototype내에서 이름 속성에 대한 amy 객체 자신의 값을 찾게됩니다. 그렇기때문에 Employee.prototype까지의 프로토타입 체인을 검색하지 않게 됩니다.

- -

실행시에 객체의 속성 값을 변경하고 새로운 값이 모든 하위 객체들에게도 적용되도록 할려면, 객체의 생성자함수에서는 속성을 정의할 수 없습니다. 대신에, 생성자와 연결된 프로토타입에 추가할 수 있습니다. 예를 들어, 이전의 코드를 아래와 같이 변경하였다고 가정합니다:

- -
function Employee () {
-  this.dept = "general";
-}
-Employee.prototype.name = "";
-
-function WorkerBee () {
-  this.projects = [];
-}
-WorkerBee.prototype = new Employee;
-
-var amy = new WorkerBee;
-
-Employee.prototype.name = "Unknown";
-
- -

이 경우 amy 객체의 이름 속성의 값은 "Unknown"이 됩니다.

- -

위의 예제에서처럼, 객체 생성 시에 객체의 속성에 대한 기본 값을 설정하고 실행 시에 해당 속성의 값을 변경하기를 원한다면, 해당 속성들을 생성자 함수 자체안에가 아닌 생성자의 프로토타입에 설정 하여야 합니다.

- -

인스턴스 관계 결정

- -

자바스크립트에서의 속성 검색은 객체 자신의 속성들을 먼저 살펴보고 해당 속성명을 찾지 못할 경우, 객체의 특별한 속성인 __proto__내에서 찾게 됩니다. 이런 검색은 재귀적으로 진행되며, 이런 과정을 "프로토타입 체인에서의 검색"이라고 합니다.

- -

특별한 속성인 __proto__객체가 생성이 될때 설정이 됩니다. __proto__속성은 생성자의 프로토타입 속성의 값으로 설정이 됩니다. 따라서 new Foo() 표현식은 __proto__ == Foo.prototype인 객체를 생성합니다. 결과적으로 Foo.prototype의 속성들에 대한 변경은 new Foo() 표현식으로 생성한 모든 객체에 대한 속성 검색을 변경하게 됩니다.

- -

모든 객체는 __proto__라는 객체 속성을 가집니다.(예외: Object). 모든 함수들은 prototype이라는 객체 속성을 가집니다. 따라서 객체들은 '프로토타입 상속'에 의해 다른 객체들과의 관계를 가지게 됩니다.객체의 __proto__속성과 함수의 prototype 객체를 비교하여 상속을 테스트 해볼 수 있습니다. 자바스크립트는 특정 객체가 함수 prototype으로부터 상속 받는 객체일 경우 참(true)를 반환하는  instanceof라는 연산자를 제공합니다. 예를 들면,

- -
var f = new Foo();
-var isTrue = (f instanceof Foo);
- -

Inheriting properties에 나오는 예제와 동일한 정의들을 작성해 놓았을 경우, 보다 상세한 예제는 아래와 같습니다.엔지니어(Engineer)객체를 아래와 같이 생성합니다:

- -
var chris = new Engineer("Pigman, Chris", ["jsd"], "fiji");
-
- -

생성된 객체를 가지고 아래와 같은 구문을 실행할 경우 각 구문에 대한 결과는 모두 참(true)입니다.

- -
chris.__proto__ == Engineer.prototype;
-chris.__proto__.__proto__ == WorkerBee.prototype;
-chris.__proto__.__proto__.__proto__ == Employee.prototype;
-chris.__proto__.__proto__.__proto__.__proto__ == Object.prototype;
-chris.__proto__.__proto__.__proto__.__proto__.__proto__ == null;
-
- -

주어진 이런 상황에서, instanceOf를 다음과 같이 직접 작성할 수 있을 것입니다:

- -
function instanceOf(object, constructor) {
-   object = object.__proto__;
-   while (object != null) {
-      if (object == constructor.prototype)
-         return true;
-      if (typeof object == 'xml') {
-        return constructor.prototype == XML.prototype;
-      }
-      object = object.__proto__;
-   }
-   return false;
-}
-
- -
-

주의: 위의 구현내용은 최신 버전의 자바스크립트에서 XML객체들이 표현되는 방법의 특질을 해결하기 위해 해당 객체의 타입이 "xml"인지 확인합니다. 핵심적인 세부 사항을 확인하려면 {{ bug(634150) }}를 참조하세요.

-
- -

위의 instanceOf함수를 사용하면 아래의 표현들은 모두 참(true)입니다:

- -
instanceOf (chris, Engineer)
-instanceOf (chris, WorkerBee)
-instanceOf (chris, Employee)
-instanceOf (chris, Object)
-
- -

하지만 아래의 표현식은 거짓(false)가 됩니다:

- -
instanceOf (chris, SalesPerson)
-
- -

생성자내에서의 전역 정보

- -

생성자를 생성할때, 생성자내에서 전역 정보를 설정할 경우, 주의를 해야 합니다. 예를 들어, 각각의 새로운 직원에게 자동으로 고유한 ID값을 할당하기를 원한다고 했을 때, 다음과 같은 직원(Employee) 정의를 사용할 수 있을 것입니다:

- -
var idCounter = 1;
-
-function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   this.id = idCounter++;
-}
-
- -

이런 정의 내용을 가지고, 새로운 직원을 생성했을 때, 생성자는 다음의 고유한 ID값을 새로운 직원객체에 할당하고 전역 ID 카운터를 증가 시킵니다. 따라서 다음과 같은 구문으로 각각의 객체를 생성한다면, 결과는 victoria.id는 1 그리고 harry.id는 2가 됩니다:

- -
var victoria = new Employee("Pigbert, Victoria", "pubs")
-var harry = new Employee("Tschopik, Harry", "sales")
-
- -

얼핏보면 괜찮아 보입니다. 하지만 이유를 불문하고 직원 객체가 생성될때마다 idCounter는 증가분을 가지게 됩니다.이번장에서 나온 예제에서처럼 전체 직원(Employee) 객체의 계층 구조를 생성하였다면, 프로토타입을 설정할때마다 직원 생성자는 매번 호출 됩니다.다음과 같은 코드를 작성하였다고 가정합니다:

- -
var idCounter = 1;
-
-function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   this.id = idCounter++;
-}
-
-function Manager (name, dept, reports) {...}
-Manager.prototype = new Employee;
-
-function WorkerBee (name, dept, projs) {...}
-WorkerBee.prototype = new Employee;
-
-function Engineer (name, projs, mach) {...}
-Engineer.prototype = new WorkerBee;
-
-function SalesPerson (name, projs, quota) {...}
-SalesPerson.prototype = new WorkerBee;
-
-var mac = new Engineer("Wood, Mac");
-
- -

여기서 생략된 정의가 base속성을 가지고 해당 생성자를 프로토타입 체인내의 상위 생성자들을 호출한닥고 좀 더 가정하면, 이런 경우, 생성된 mac객체의 id값은 5가 됩니다.

- -

어플리케이셔네 따라, 카운터가 이렇게 추가적으로 증가된 것은 문제가 될 수도 그렇지 않을 수 도 있습니다. 카운터에 정확한 값이 설정되기를 원한다면, 사용가능한 해결적은 아래와 같은 생성자를 대신 사용하는 것입니다:

- -
function Employee (name, dept) {
-   this.name = name || "";
-   this.dept = dept || "general";
-   if (name)
-      this.id = idCounter++;
-}
-
- -

prototype으로 사용할 직원 인스턴스를 생성할 때, 생성자에 인자들을 주어선 안됩니다. 이 생성자 정의를 사용하여, 인자들을 주지 않을 경우, 생성자는 id에 값을 할당하지 않으며 카운터를 갱신하지 않습니다. 따라서, id값을 가지는 직원 객체에 대해, 반드시 해당 직원의 이름을 명시해야 합니다. 이 예제의 경우 mac인스턴스의 id값은 1이 됩니다.

- -

다중상속 금지

- -

몇몇 객체 지향언어들은 다중 상속을 허용합니다. 그것은, 관련이 없는 부모 객체들로 부터 속성들과 값들을 상속 받을 수 있는 것을 말합니다. 자바스크립트는 다중 상속을 지원하지 않습니다.

- -

속성 값의 상속은 속성에 대한 값을 찾기 위한 프로토타입 체인을 검색에 의해 실행 시점에 이루어 집니다. 하나의 객체는 오로지 하나의 결합된 prototype만을 가지기 때문에, 자바스크립트는 동적으로 하나 이상의 프로토타입 체인으로 부터 상속을 할 수 없습니다. 

- -

자바스크립트에서, 하나 이상의 다른 생성자 함수를 호출하는 생성자를 사용할 수 있습니다. 이것은 다중 상속처럼 보여질 수 있습니다. 예를 들어, 다음과 같은 구문들을 살펴보세요:

- -
function Hobbyist (hobby) {
-   this.hobby = hobby || "scuba";
-}
-
-function Engineer (name, projs, mach, hobby) {
-   this.base1 = WorkerBee;
-   this.base1(name, "engineering", projs);
-   this.base2 = Hobbyist;
-   this.base2(hobby);
-   this.machine = mach || "";
-}
-Engineer.prototype = new WorkerBee;
-
-var dennis = new Engineer("Doe, Dennis", ["collabra"], "hugo")
-
- -

WorkerBee의 정의는 이번 장의 이전에 사용된 것과 동일하다고 가정합니다.이런 경우, dennis객체는 다음과 같은 속성들을 가지게 됩니다:

- -
dennis.name == "Doe, Dennis"
-dennis.dept == "engineering"
-dennis.projects == ["collabra"]
-dennis.machine == "hugo"
-dennis.hobby == "scuba"
-
- -

 따라서 dennis객체는 Hobbyist 생성자로부터 취미(hobby)속성을 받아 오지 않습니다. 그런데 Hobbyist생성자의 프로토타입에 속성을 추가 했다고 가정하면 

- -
Hobbyist.prototype.equipment = ["mask", "fins", "regulator", "bcd"]
-
- -

dennis객체는 새로이 추가된 속성을 상속받지 않습니다.

- -
{{PreviousNext("Web/JavaScript/Guide/Working_with_Objects", "Web/JavaScript/Guide/Iterators_and_Generators")}}
diff --git "a/files/ko/web/javascript/guide/\353\251\224\355\203\200_\355\224\204\353\241\234\352\267\270\353\236\230\353\260\215/index.html" "b/files/ko/web/javascript/guide/\353\251\224\355\203\200_\355\224\204\353\241\234\352\267\270\353\236\230\353\260\215/index.html" deleted file mode 100644 index fe4fa13f83..0000000000 --- "a/files/ko/web/javascript/guide/\353\251\224\355\203\200_\355\224\204\353\241\234\352\267\270\353\236\230\353\260\215/index.html" +++ /dev/null @@ -1,258 +0,0 @@ ---- -title: 메타 프로그래밍 -slug: Web/JavaScript/Guide/메타_프로그래밍 -translation_of: Web/JavaScript/Guide/Meta_programming ---- -
{{jsSidebar("JavaScript Guide")}} {{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}
- -

Starting with ECMAScript 2015, JavaScript gains support for the {{jsxref("Proxy")}} and {{jsxref("Reflect")}} objects allowing you to intercept and define custom behavior for fundamental language operations (e.g. property lookup, assignment, enumeration, function invocation, etc). With the help of these two objects you are able to program at the meta level of JavaScript.

- -

Proxies

- -

 ECMAScript 6에서 소개되었습니다, {{jsxref("Proxy")}} 객체는  특정 작업을 가로막는것과  사용자 정의 행위를 시행하는것을 허용합니다.예를 들면 객체가 속성을 가지는 것입니다:

- -
var handler = {
-  get: function(target, name){
-    return name in target ? target[name] : 42;
-  }
-};
-var p = new Proxy({}, handler);
-p.a = 1;
-console.log(p.a, p.b); // 1, 42
-
- -

The Proxy object defines a target (an empty object here) and a handler object in which a get trap is implemented. Here, an object that is proxied will not return undefined when getting undefined properties, but will instead return the number 42.

- -

Additional examples are available on the {{jsxref("Proxy")}} reference page.

- -

Terminology

- -

The following terms are used when talking about the functionality of proxies.

- -
-
{{jsxref("Global_Objects/Proxy/handler","handler","","true")}}
-
Placeholder object which contains traps.
-
traps
-
The methods that provide property access. This is analogous to the concept of traps in operating systems.
-
target
-
Object which the proxy virtualizes. It is often used as storage backend for the proxy. Invariants (semantics that remain unchanged) regarding object non-extensibility or non-configurable properties are verified against the target.
-
invariants
-
Semantics that remain unchanged when implementing custom operations are called invariants. If you violate the invariants of a handler, a {{jsxref("TypeError")}} will be thrown.
-
- -

Handlers and traps

- -

The following table summarizes the available traps available to Proxy objects. See the reference pages for detailed explanations and examples.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Handler / trapInterceptionsInvariants
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}{{jsxref("Object.getPrototypeOf()")}}
- {{jsxref("Reflect.getPrototypeOf()")}}
- {{jsxref("Object/proto", "__proto__")}}
- {{jsxref("Object.prototype.isPrototypeOf()")}}
- {{jsxref("Operators/instanceof", "instanceof")}}
-
    -
  • getPrototypeOf method must return an object or null.
  • -
  • If target is not extensible, Object.getPrototypeOf(proxy) method must return the same value as Object.getPrototypeOf(target).
  • -
-
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}{{jsxref("Object.setPrototypeOf()")}}
- {{jsxref("Reflect.setPrototypeOf()")}}
If target is not extensible, the prototype parameter must be the same value as Object.getPrototypeOf(target).
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}{{jsxref("Object.isExtensible()")}}
- {{jsxref("Reflect.isExtensible()")}}
Object.isExtensible(proxy) must return the same value as Object.isExtensible(target).
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}{{jsxref("Object.preventExtensions()")}}
- {{jsxref("Reflect.preventExtensions()")}}
Object.preventExtensions(proxy) only returns true if Object.isExtensible(proxy) is false.
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}{{jsxref("Object.getOwnPropertyDescriptor()")}}
- {{jsxref("Reflect.getOwnPropertyDescriptor()")}}
-
    -
  • getOwnPropertyDescriptor must return an object or undefined.
  • -
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • -
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
  • -
  • A property cannot be reported as existent, if it does not exists as an own property of the target object and the target object is not extensible.
  • -
  • A property cannot be reported as non-configurable, if it does not exists as an own property of the target object or if it exists as a configurable own property of the target object.
  • -
  • The result of Object.getOwnPropertyDescriptor(target)can be applied to the target object using Object.defineProperty and will not throw an exception.
  • -
-
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}{{jsxref("Object.defineProperty()")}}
- {{jsxref("Reflect.defineProperty()")}}
-
    -
  • A property cannot be added, if the target object is not extensible.
  • -
  • A property cannot be added as or modified to be non-configurable, if it does not exists as a non-configurable own property of the target object.
  • -
  • A property may not be non-configurable, if a corresponding configurable property of the target object exists.
  • -
  • If a property has a corresponding target object property then Object.defineProperty(target, prop, descriptor) will not throw an exception.
  • -
  • In strict mode, a false return value from the defineProperty handler will throw a {{jsxref("TypeError")}} exception.
  • -
-
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}Property query: foo in proxy
- Inherited property query: foo in Object.create(proxy)
- {{jsxref("Reflect.has()")}}
-
    -
  • A property cannot be reported as non-existent, if it exists as a non-configurable own property of the target object.
  • -
  • A property cannot be reported as non-existent, if it exists as an own property of the target object and the target object is not extensible.
  • -
-
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}Property access: proxy[foo]and proxy.bar
- Inherited property access: Object.create(proxy)[foo]
- {{jsxref("Reflect.get()")}}
-
    -
  • The value reported for a property must be the same as the value of the corresponding target object property if the target object property is a non-writable, non-configurable data property.
  • -
  • The value reported for a property must be undefined if the corresponding target object property is non-configurable accessor property that has undefined as its [[Get]] attribute.
  • -
-
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}Property assignment: proxy[foo] = barand proxy.foo = bar
- Inherited property assignment: Object.create(proxy)[foo] = bar
- {{jsxref("Reflect.set()")}}
-
    -
  • Cannot change the value of a property to be different from the value of the corresponding target object property if the corresponding target object property is a non-writable, non-configurable data property.
  • -
  • Cannot set the value of a property if the corresponding target object property is a non-configurable accessor property that has undefined as its [[Set]] attribute.
  • -
  • In strict mode, a false return value from the sethandler will throw a {{jsxref("TypeError")}} exception.
  • -
-
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}Property deletion: delete proxy[foo] and delete proxy.foo
- {{jsxref("Reflect.deleteProperty()")}}
A property cannot be deleted, if it exists as a non-configurable own property of the target object.
{{jsxref("Global_Objects/Proxy/handler/enumerate", "handler.enumerate()")}}Property enumeration / for...in: for (var name in proxy) {...}
- {{jsxref("Reflect.enumerate()")}}
The enumerate method must return an object.
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}{{jsxref("Object.getOwnPropertyNames()")}}
- {{jsxref("Object.getOwnPropertySymbols()")}}
- {{jsxref("Object.keys()")}}
- {{jsxref("Reflect.ownKeys()")}}
-
    -
  • The result of ownKeys is a List.
  • -
  • The Type of each result List element is either {{jsxref("String")}} or {{jsxref("Symbol")}}.
  • -
  • The result List must contain the keys of all non-configurable own properties of the target object.
  • -
  • If the target object is not extensible, then the result List must contain all the keys of the own properties of the target object and no other values.
  • -
-
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}proxy(..args)
- {{jsxref("Function.prototype.apply()")}} and {{jsxref("Function.prototype.call()")}}
- {{jsxref("Reflect.apply()")}}
There are no invariants for the handler.applymethod.
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}new proxy(...args)
- {{jsxref("Reflect.construct()")}}
The result must be an Object.
- -

Revocable Proxy

- -

The {{jsxref("Proxy.revocable()")}} method is used to create a revocable Proxy object. This means that the proxy can be revoked via the function revoke and switches the proxy off. Afterwards, any operation on the proxy leads to a {{jsxref("TypeError")}}

- -
var revocable = Proxy.revocable({}, {
-  get: function(target, name) {
-    return '[[' + name + ']]';
-  }
-});
-var proxy = revocable.proxy;
-console.log(proxy.foo); // "[[foo]]"
-
-revocable.revoke();
-
-console.log(proxy.foo);  // TypeError is thrown
-proxy.foo = 1;           // TypeError again
-delete proxy.foo;        // still TypeError
-typeof proxy;            // "object", typeof doesn't trigger any trap
- -

Reflection

- -

{{jsxref("Reflect")}} is a built-in object that provides methods for interceptable JavaScript operations. The methods are the same as those of the {{jsxref("Global_Objects/Proxy/handler","proxy handlers","","true")}}. Reflect is not a function object.

- -

Reflect helps with forwarding default operations from the handler to the target.

- -

With {{jsxref("Reflect.has()")}} for example, you get the in operator as a function:

- -
Reflect.has(Object, 'assign'); // true
- -

A better apply function

- -

In ES5, you typically use the {{jsxref("Function.prototype.apply()")}} method to call a function with a given this value and arguments provided as an array (or an array-like object).

- -
Function.prototype.apply.call(Math.floor, undefined, [1.75]);
- -

With {{jsxref("Reflect.apply")}} this becomes less verbose and easier to understand:

- -
Reflect.apply(Math.floor, undefined, [1.75]);
-// 1;
-
-Reflect.apply(String.fromCharCode, undefined, [104, 101, 108, 108, 111]);
-// "hello"
-
-Reflect.apply(RegExp.prototype.exec, /ab/, ['confabulation']).index;
-// 4
-
-Reflect.apply(''.charAt, 'ponies', [3]);
-// "i"
- -

Checking if property definition has been successful

- -

With {{jsxref("Object.defineProperty")}}, which returns an object if successful, or throws a {{jsxref("TypeError")}} otherwise, you would use a {{jsxref("Statements/try...catch","try...catch")}} block to catch any error that occurred while defining a property. Because {{jsxref("Reflect.defineProperty")}} returns a Boolean success status, you can just use an {{jsxref("Statements/if...else","if...else")}} block here:

- -
if (Reflect.defineProperty(target, property, attributes)) {
-  // success
-} else {
-  // failure
-}
- -

{{Previous("Web/JavaScript/Guide/Iterators_and_Generators")}}

- -

 

diff --git "a/files/ko/web/javascript/guide/\354\206\214\352\260\234/index.html" "b/files/ko/web/javascript/guide/\354\206\214\352\260\234/index.html" deleted file mode 100644 index cac0779ee0..0000000000 --- "a/files/ko/web/javascript/guide/\354\206\214\352\260\234/index.html" +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: Introduction -slug: Web/JavaScript/Guide/소개 -tags: - - JavaScript - - 가이드 - - 안내서 - - 자바스크립트 -translation_of: Web/JavaScript/Guide/Introduction ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}
- -

이 장은 JavaScript를 소개하고 그 일부 기초 개념을 다룹니다.

- -

무엇을 미리 알고 있어야 하나요?

- -

이 안내서는 당신이 다음의 기본적인 배경지식이 있다고 가정합니다.

- -
    -
  • 인터넷과 월드 와이드 웹({{Glossary("WWW")}})에 대한 전반적인 이해.
  • -
  • HyperText 마크업 언어({{Glossary("HTML")}})에 대한 괜찮은 실무 지식.
  • -
  • 약간의 프로그래밍 경험. 만약 프로그래밍이 처음이라면, JavaScript 메인 페이지에 링크된 tutorial 중 하나를 따라하세요.
  • -
- -

어디서 JavaScript 정보를 찾을 수 있을까

- -

MDN에 있는 JavaScript 문서는 다음 세가지 파트로 되어있습니다.

- -
    -
  • Learning the Web은 입문자를 위한 정보를 제공하며, 프로그래밍과 인터넷에 대한 기본 개념을 소개합니다.
  • -
  • JavaScript Guide (이 안내서)는 JavaScript 언어와 객체에 대한 개요를 제공합니다.
  • -
  • JavaScript Reference JavaScript에 관련된 자세한 참고 자료를 제공합니다.
  • -
- -

JavaScript가 처음이라면, learning areaJavaScript Guide에 있는 문서를 먼저 보세요. 일단 기초를 확실히 파악한 후에는, 각 객체와 문(statement)에 대한 더 자세한 정보를 JavaScript Reference에서 확인할 수 있습니다.

- -

JavaScript는 무엇인가?

- -

JavaScript는 크로스-플랫폼, 객체지향 스크립트 언어입니다. 작고 가벼운 언어입니다. 호스트 환경(가령, 웹 브라우저) 내에서, JavaScript는 프로그램 제어를 제공하기 위해 그 환경의 객체에 연결될 수 있습니다. Node.Js와 같은 자바 스크립트의 고급 서버언어로 사용 할 수도 있습니다.이것을 사용하면 단순히 파일을 다운로드하는 것 (예 : 여러 컴퓨터 간의 실시간 공동 작업)보다 웹 사이트에 더 많은 기능을 추가 할 수 있습니다. 호스트 환경 (예 : 웹 브라우저) 내에서 JavaScript는 해당 환경의 객체에 연결되어 프로그래밍 방식으로 제어 할 수 있습니다.

- -

JavaScript는 Array, Date, Math와 같은 객체에 대한 표준 라이브러리와 연산자(operator), 제어 구조, 문과 같은 언어 요소의 코어 집합을 포함합니다. 코어 JavaScript는 거기에 추가 객체를 보충하여 다양한 목적으로 확장될 수 있습니다. 예를 들면:

- -
    -
  • 클라이언트 측 JavaScript는 브라우저와 문서 객체 모델(DOM) 을 제어하는 객체를 제공하여 코어 언어를 확장합니다. 예를 들어, 클라이언트 측 확장은 어플리케이션이 요소(element)를 HTML 폼에 두고, 마우스 클릭, 폼 입력 및 페이지 탐색 같은 사용자 이벤트에 응답하게 해줍니다.
  • -
  • 서버 측 JavaScript는 서버에서 JavaScript 실행에 관련된 객체를 제공하여 코어 언어를 확장합니다. 예를 들어, 서버 측 확장은 어플리케이션이 데이터베이스와 통신하고, 한 번의 호출 정보의 연속성을 어플리케이션의 다른 곳에 제공하거나, 서버에서 파일 조작을 수행할 수 있도록 해줍니다.
  • -
- -

이것은 브라우저에서 JavaScript가 웹 페이지 (DOM)의 모양을 바꿀 수 있음을 의미합니다. 또한 서버의 Node.js JavaScript는 브라우저에 작성된 코드의 사용자 정의 요청에 응답 할 수 있습니다.

- -

JavaScript 와 Java

- -

JavaScript 와 Java는 여러 면에서 비슷하지만 어떤 면에서는 근본적으로 다릅니다. JavaScript 언어는 Java를 닮았지만 Java의 정적 형지정(static typing)과 강한 형 검사(strong type checking)가 없습니다. JavaScript는 대부분의 Java 식 구문, 명명 규칙 및 기본적인 흐름 제어 구조를 따릅니다. 그것이 LiveScript에서 JavaScript로 이름이 바뀐 이유였습니다.

- -

Java의 선언에 의해 생성되는 클래스의 컴파일-타임 시스템과는 달리, JavaScript는 숫자, 불리언, 그리고 문자열 값을 표현하는 적은 수의 자료 형을 기반으로 한 런타임 시스템을 지원합니다. JavaScript 는 더 일반적인 클래스 기반 객체 모델 대신에 프로토타입 기반 객체 모델을 갖습니다. 프로토타입 기반 모델은 동적 상속을 제공합니다. 즉, 상속된 대상은 각각의 객체에 따라 다양할 수 있습니다. JavaScript는 또한 어떤 특정한 선언을 요구하지 않는 함수도 지원합니다. 함수는 객체의 속성이나, 타입이 느슨하게 형지정된 채 실행되는 메소드가 될 수 있습니다.

- -

JavaScript는 Java에 비해 매우 자유로운 형태의 언어입니다. 여러분은 모든 변수, 클래스, 및 메소드를 선언하지 않아도 됩니다. 여러분은 메소드가 public, private, 또는 protected 인지 염려할 필요가 없고 인터페이스를 구현하지 않아도 됩니다. 변수, 매개변수(parameter), 및 함수의 반환 형은 명시적으로 지정되지 않습니다.

- -

Java는 빠른 실행과 형 안전성(type safety)을 위해 설계된 클래스 기반 프로그래밍 언어입니다. 형 안전성은, 예를 들어, 여러분이 Java 정수를 객체의 레퍼런스로 형변환(cast)하거나 Java 바이트코드를 변경하여 private 메모리에 접근할 수 없음을 의미합니다. Java의 클래스 기반 모델은 프로그램이 오로지 클래스와 그 메소드로만 구성된다는 것을 뜻합니다. Java의 클래스 상속과 강한 형지정은 보통 단단하게 결합된 객체 계층구조를 요구합니다. 이러한 요구는 Java 프로그래밍을 JavaScript 프로그래밍보다 더 복잡하게 만듭니다.

- -

반면에, JavaScript는 HyperTalk 과 dBASE 같은 더 작고 동적 형지정이 가능한 언어들의 정신을 계승했습니다. 이러한 스크립팅 언어는 더 쉬운 구문과 특별한 내장(built-in) 기능 및 객체 생성을 위한 최소 요구사항으로 인해 훨씬 더 많은 사람들에게 프로그래밍 도구를 제공합니다.

- - - - - - - - - - - - - - - - - - - - - - - -
Java와 비교한 JavaScript
JavaScriptJava
객체 지향. 객체의 형 간에 차이 없음. 프로토타입 메커니즘을 통한 상속, 그리고 속성과 메서드는 어떤 객체든 동적으로 추가될 수 있음.클래스 기반. 객체는 클래스 계층구조를 통한 모든 상속과 함께 클래스와 인스턴스로 나뉨. 클래스와 인스턴스는 동적으로 추가된 속성이나 메소드를 가질 수 없음.
변수 자료형이 선언되지 않음(dynamic typing, loosely typed).변수 자료형은 반드시 선언되어야 함(정적 형지정, static typing).
하드 디스크에 자동으로 작성 불가.하드 디스크에 자동으로 작성 가능.
- -

JavaScript와 Java의 차이에 대한 더 많은 정보는, 객체 모델의 세부사항 장을 보세요.

- -

JavaScript 와 ECMAScript 명세

- -

JavaScript는 JavaScript에 기반한 표준화된 국제 프로그래밍 언어를 제공하기 위해Ecma International 에서 표준화 됩니다 — European association for standardizing information and communication systems (ECMA는 이전에 European Computer Manufacturers Association의 두문자어였습니다). ECMAScript라 불리는 이 JavaScript의 표준화 버전은 표준을 지원하는 모든 어플리케이션에서 같은 방식으로 동작합니다. 회사들은 그들의 JavaScript 구현을 개발하기 위해 공개 표준 언어를 사용할 수 있습니다. ECMAScript 표준은 ECMA-262 명세(specification)에서 문서화되었습니다. JavaScript와 ECMAScript 명세 판의 여러 버전에 대한 더 많은 것을 배우려면 New in JavaScript 을 보세요.

- -

ECMA-262 표준은 또한 IOS-16262로서 ISO (국제 표준화 기구) 에 의해 승인되었습니다. Ecma International website 에서 그 명세를 찾을 수 있습니다. ECMAScript 명세는 World Wide Web Consortium (W3C) 나  WHATWG (Web Hypertext Application Technology Working Group)에 의해 표준화된 Document Object Model (DOM)을 설명하지 않습니다. DOM은 여러분의 스크립트에 HTML 문서 객체를 드러내는 방법을 정의합니다. JavaScript로 프로그래밍을 할 때 사용되는 여러 기술들에 대한 정보를 얻으 시려면, JavaScript technologies overview 를 참고하세요.

- -

JavaScript 문서 vs ECMAScript 명세

- -

ECMAScript 명세는 ECMAScript 구현을 위한 요구사항의 집합입니다; 여러분이 여러분의 ECMAScript 구현이나 엔진(가령 Firefox의 SpiderMonkey, 또는 Chrome의 v8)에서 표준을 따르는 언어의 기능을 구현하길 원할 때 유용합니다.

- -

ECMAScript 문서는 스크립트 프로그래머를 돕기 위함이 아닙니다; 스크립트 작성을 위한 정보는 JavaScript 문서를 사용하세요.

- -

ECMAScript 명세는 JavaScript 프로그래머에게 익숙하지 않을 수 있는 용어와 문법을 사용합니다. 언어의 기술이 ECMAScript 에서 다를 수 있지만, 언어 그 자체는 같습니다. JavaScript는 ECMAScript 명세에 서술된 모든 기능을 지원합니다.

- -

JavaScript 문서는 JavaScript 프로그래머에게 적합한 언어의 측면을 설명합니다.

- -

JavaScript 시작하기

- -

JavaScript 시작은 쉽습니다: 최신 웹 브라우저만 있으면 됩니다. 이 안내서는 현재 Firefox의 최신 버전에서만 사용 가능한 약간의 JavaScript 기능을 포함하므로, 가장 최신 버전의 Firefox를 사용하기를 권합니다.

- -

JavaScript를 실험하기 유용한 두 도구가 Firefox에 내장되어 있습니다: Web Console과 Scratchpad.

- -

웹 콘솔

- -

웹 콘솔은 현재 로드된 페이지에 대한 정보를 보이고, 또한 여러분이 현재 페이지에서 JavaScript 식을 실행해볼 수 있는 명령어 입력줄(command line)을 제공합니다.

- -

웹 콘솔을 열기 위해서는, Firefox의 "도구" 메뉴 하위에 있는 "개발자" 메뉴의 "웹 콘솔"을 선택(윈도우와 리눅스에서는 Ctrl+Shift+I, 맥에서는  Cmd-Option-K)합니다. 브라우저 창의 아래에 웹 콘솔이 나타납니다. 콘솔의 바닥을 따라 나온 것이 여러분이 JavaScript를 입력할 수 있는 명령어 입력줄이고, 실행 결과는 바로 위 공간에 표시됩니다:

- -

- -

이 콘솔은 eval과 완전히 동일하게 동작합니다:마지막 입력된 표현식이 반환되죠. 간단하게 생각해서, 콘솔에 뭔가 입력할 때마다 eval로 감싼 console.log로 둘러싸인 형태라고 보시면 됩니다.

- -
function greetMe(yourName) { alert('Hello ' + yourName); } console.log(eval('3 + 5'));
- -

Scratchpad

- -

Web Console은 한 줄 JavaScript를 실행하기에 훌륭합니다. 하지만 비록 여러 줄을 실행할 수 있지만, 아주 불편하고 Web Console을 사용해 여러분의 샘플 코드를 저장할 수도 없습니다. 그러므로 좀 더 복잡한 예제를 위해서는 Scratchpad가 더 나은 도구입니다.

- -

Scratchpad를 열기 위해, Firefox의 메뉴 "Tools" 의 하위에 있는 "Web Developer" 메뉴의 "Scratchpad" 를 선택합니다(단축키: Shift+F4). 이것은 분리된 창에서 열리고 브라우저에서 JavaScript를 작성하고 실행하기 위해 사용할 수 있는 에디터입니다. 여러분은 또한 디스크로부터 스크립트를 부르거나 저장할 수도 있습니다.

- -

- -

Hello world

- -

JavaScript 작성을 시작하기 위해서, Scratchpad를 열고 첫 JavaScript 코드 "Hello World" 를 작성하세요.

- -
(function(){
-  "use strict";
-  /* Start of your code */
-  function greetMe(yourName) {
-    alert('Hello ' + yourName);
-  }
-
-  greetMe('World');
-  /* End of your code */
-})();
- -

패드에서 코드를 선택하고 Ctrl + R 키를 눌러 브라우저에서 펼쳐지는 것을 지켜보십시오! 다음 페이지에서 이 가이드는 JavaScript 구문 및 언어 기능을 소개하므로보다 복잡한 응용 프로그램을 작성할 수 있습니다. 그러나 당분간은 (function () { "use strict"를 코드 앞에 추가하고}}) ();를 코드마지막에 추가하세요. 아직은 이코드가 뭔지 잘 모르겠지만 나중에 이 코드가 의미하는 것을 배울 것입니다, 지금은 간단히 다음과 같다고 생각하세요.

- -
    -
  1. 성능을 크게 개선합니다.
  2. -
  3. 초보자가 실수하게 만드는 Javascript의 일부 시맨틱을 막습니다.
  4. -
  5. 콘솔에서 실행되는 코드 스니펫이 서로 상호 작용하지 못하도록합니다 (예 : 한 콘솔 실행에서 생성 된 내용을 다른 콘솔 실행에 사용하는 경우).
  6. -
- -

{{PreviousNext("Web/JavaScript/Guide", "Web/JavaScript/Guide/Grammar_and_types")}}

diff --git "a/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/assertions/index.html" "b/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/assertions/index.html" deleted file mode 100644 index 350c50f8f9..0000000000 --- "a/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/assertions/index.html" +++ /dev/null @@ -1,244 +0,0 @@ ---- -title: Assertions -slug: Web/JavaScript/Guide/정규식/Assertions -translation_of: Web/JavaScript/Guide/Regular_Expressions/Assertions ---- -

{{jsSidebar("JavaScript Guide")}}

- -

Assertions에는 행이나 단어의 시작 · 끝을 나타내는 경계와 (앞, 뒤 읽고 조건식을 포함한) 어떤 식 으로든 매치가 가능한 것을 나타내는 다른 패턴이 포함됩니다.

- -
{{EmbedInteractiveExample("pages/js/regexp-assertions.html", "taller")}}
- -

Types

- -

Boundary-type assertions

- - - - - - - - - - - - - - - - - - - - - - - - - - -
CharactersMeaning
^ -

Matches the beginning of input. If the multiline flag is set to true, also matches immediately after a line break character. For example, /^A/ does not match the "A" in "an A", but does match the first "A" in "An A".

- -
-

This character has a different meaning when it appears at the start of a group.

-
-
$ -

Matches the end of input. If the multiline flag is set to true, also matches immediately before a line break character. For example, /t$/ does not match the "t" in "eater", but does match it in "eat".

-
\b -

Matches a word boundary. This is the position where a word character is not followed or preceded by another word-character, such as between a letter and a space. Note that a matched word boundary is not included in the match. In other words, the length of a matched word boundary is zero.

- -

Examples:

- -
    -
  • /\bm/ matches the "m" in "moon".
  • -
  • /oo\b/ does not match the "oo" in "moon", because "oo" is followed by "n" which is a word character.
  • -
  • /oon\b/ matches the "oon" in "moon", because "oon" is the end of the string, thus not followed by a word character.
  • -
  • /\w\b\w/ will never match anything, because a word character can never be followed by both a non-word and a word character.
  • -
- -

To match a backspace character ([\b]), see Character Classes.

-
\B -

Matches a non-word boundary. This is a position where the previous and next character are of the same type: Either both must be words, or both must be non-words, for example between two letters or between two spaces. The beginning and end of a string are considered non-words. Same as the matched word boundary, the matched non-word boundary is also not included in the match. For example, /\Bon/ matches "on" in "at noon", and /ye\B/ matches "ye" in "possibly yesterday".

-
- -

Other assertions

- -
-

Note: The ? character may also be used as a quantifier.

-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
CharactersMeaning
x(?=y) -

Lookahead assertion: Matches "x" only if "x" is followed by "y". For example, /Jack(?=Sprat)/ matches "Jack" only if it is followed by "Sprat".
- /Jack(?=Sprat|Frost)/ matches "Jack" only if it is followed by "Sprat" or "Frost". However, neither "Sprat" nor "Frost" is part of the match results.

-
x(?!y) -

Negative lookahead assertion: Matches "x" only if "x" is not followed by "y". For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. /\d+(?!\.)/.exec('3.141') matches "141" but not "3.

-
(?<=y)x -

Lookbehind assertion: Matches "x" only if "x" is preceded by "y". For example, /(?<=Jack)Sprat/ matches "Sprat" only if it is preceded by "Jack". /(?<=Jack|Tom)Sprat/ matches "Sprat" only if it is preceded by "Jack" or "Tom". However, neither "Jack" nor "Tom" is part of the match results.

-
(?<!y)x -

Negative lookbehind assertion: Matches "x" only if "x" is not preceded by "y". For example, /(?<!-)\d+/ matches a number only if it is not preceded by a minus sign. /(?<!-)\d+/.exec('3') matches "3". /(?<!-)\d+/.exec('-3')  match is not found because the number is preceded by the minus sign.

-
- -

Examples

- -

General boundary-type overview example

- -
// Using Regex boundaries to fix buggy string.
-buggyMultiline = `tey, ihe light-greon apple
-tangs on ihe greon traa`;
-
-// 1) Use ^ to fix the matching at the begining of the string, and right after newline.
-buggyMultiline = buggyMultiline.replace(/^t/gim,'h');
-console.log(1, buggyMultiline); // fix 'tey', 'tangs' => 'hey', 'hangs'. Avoid 'traa'.
-
-// 2) Use $ to fix matching at the end of the text.
-buggyMultiline = buggyMultiline.replace(/aa$/gim,'ee.');
-console.log(2, buggyMultiline); // fix  'traa' => 'tree'.
-
-// 3) Use \b to match characters right on border between a word and a space.
-buggyMultiline = buggyMultiline.replace(/\bi/gim,'t');
-console.log(3, buggyMultiline); // fix  'ihe' but does not touch 'light'.
-
-// 4) Use \B to match characters inside borders of an entity.
-fixedMultiline = buggyMultiline.replace(/\Bo/gim,'e');
-console.log(4, fixedMultiline); // fix  'greon' but does not touch 'on'.
-
- -

Matching the beginning of an input using a ^ control character

- -

입력 시작시 일치를 위해 ^를 사용하십시오. 이 예에서는 /^A/ regex로 'A'로 시작하는 결과를 얻습니다. 여기서 ^는 한 가지 역할 만합니다. 적절한 결과를 보기위해 화살표 함수가있는 필터 메소드를 사용합니다.

- -
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
-
-// Select fruits started with 'A' by /^A/ Regex.
-// Here '^' control symbol used only in one role: Matching begining of an input.
-
-let fruitsStartsWithA = fruits.filter(fruit => /^A/.test(fruit));
-console.log(fruitsStartsWithA); // [ 'Apple', 'Avocado' ]
-
- -

두 번째 예제에서 ^는 두 가지 모두에 사용됩니다 : 입력의 일치 시작점, 그룹에서 사용될 때 부정 또는 보완 문자 세트.

- -
let fruits = ["Apple", "Watermelon", "Orange", "Avocado", "Strawberry"];
-
-// Selecting fruits that dose not start by 'A' by a /^[^A]/ regex.
-// In this example, two meanings of '^' control symbol are represented:
-// 1) Matching begining of the input
-// 2) A negated or complemented character set: [^A]
-// That is, it matches anything that is not enclosed in the brackets.
-
-let fruitsStartsWithNotA = fruits.filter(fruit => /^[^A]/.test(fruit));
-
-console.log(fruitsStartsWithNotA); // [ 'Watermelon', 'Orange', 'Strawberry' ]
- -

Matching a word boundary

- -
let fruitsWithDescription = ["Red apple", "Orange orange", "Green Avocado"];
-
-// Select descriptions that contains 'en' or 'ed' words endings:
-let enEdSelection = fruitsWithDescription.filter(descr => /(en|ed)\b/.test(descr));
-
-console.log(enEdSelection); // [ 'Red apple', 'Green Avocado' ]
- -

Lookahead assertion

- -
// JS Lookahead assertion x(?=y)
-
-let regex = /First(?= test)/g;
-
-console.log('First test'.match(regex)); // [ 'First' ]
-console.log('First peach'.match(regex)); // null
-console.log('This is a First test in a year.'.match(regex)); // [ 'First' ]
-console.log('This is a First peach in a month.'.match(regex)); // null
-
- -

Basic negative lookahead assertion

- -

For example, /\d+(?!\.)/ matches a number only if it is not followed by a decimal point. /\d+(?!\.)/.exec('3.141') matches "141" but not "3.

- -
console.log(/\d+(?!\.)/g.exec('3.141')); // [ '141', index: 2, input: '3.141' ]
-
- -

Different meaning of '?!' combination usage in Assertions and  Ranges 

- -

Different meaning of ?! combination usage in Assertions /x(?!y)/ and Ranges [^?!].

- -
let orangeNotLemon = "Do you want to have an orange? Yes, I do not want to have a lemon!";
-
-// Different meaning of '?!' combination usage in Assertions /x(?!y)/ and  Ranges /[^?!]/
-let selectNotLemonRegex = /[^?!]+have(?! a lemon)[^?!]+[?!]/gi
-console.log(orangeNotLemon.match(selectNotLemonRegex)); // [ 'Do you want to have an orange?' ]
-
-let selectNotOrangeRegex = /[^?!]+have(?! an orange)[^?!]+[?!]/gi
-console.log(orangeNotLemon.match(selectNotOrangeRegex)); // [ ' Yes, I do not want to have a lemon!' ]
-
- -

Lookbehind assertion

- -
let oranges = ['ripe orange A ', 'green orange B', 'ripe orange C',];
-
-let ripe_oranges = oranges.filter( fruit => fruit.match(/(?<=ripe )orange/));
-console.log(ripe_oranges); // [ 'ripe orange A ', 'ripe orange C' ]
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ESDraft', '#sec-assertion', 'RegExp: Assertions')}}{{Spec2('ESDraft')}}
- -

Browser compatibility

- -

For browser compatibility information, check out the main Regular Expressions compatibility table.

- -

See also

- - diff --git "a/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/groups_and_ranges/index.html" "b/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/groups_and_ranges/index.html" deleted file mode 100644 index 2e2109b4ed..0000000000 --- "a/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/groups_and_ranges/index.html" +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Groups and Ranges -slug: Web/JavaScript/Guide/정규식/Groups_and_Ranges -translation_of: Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges ---- -

{{jsSidebar("JavaScript Guide")}}{{draft}}

- -

그룹(Groups)과 범위(ranges)는 표현 문자의 그룹과 범위를 나타냅니다.

- -

Types

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
CharactersMeaning
x|y -

x또는 y와 매칭되는 경우. 예를들면 /green|red/ 은 "green apple"의 "green"과 매치되고 "red apple"의 "red"와 매치됩니다.

-
[xyz]
- [a-c]
-

A character set. Matches any one of the enclosed characters. You can specify a range of characters by using a hyphen, but if the hyphen appears as the first or last character enclosed in the square brackets it is taken as a literal hyphen to be included in the character set as a normal character. It is also possible to include a character class in a character set.

- -

For example, [abcd] is the same as [a-d]. They match the "b" in "brisket" and the "c" in "chop".

- -

For example, [abcd-] and [-abcd] match the "b" in "brisket", the "c" in "chop" and the "-" (hyphen) in "non-profit".

- -

For example, [\w-] is the same as [A-Za-z0-9_-]. They match the "b" in "brisket", the "c" in "chop" and the "n" in "non-profit".

-
-

[^xyz]
- [^a-c]

-
-

A negated or complemented character set. That is, it matches anything that is not enclosed in the brackets. You can specify a range of characters by using a hyphen, but if the hyphen appears as the first or last character enclosed in the square brackets it is taken as a literal hyphen to be included in the character set as a normal character. For example, [^abc] is the same as [^a-c]. They initially match "o" in "bacon" and "h" in "chop".

- -
-

The ^ character may also indicate the beginning of input.

-
-
(x) -

Capturing group: Matches x and remembers the match. For example, /(foo)/ matches and remembers "foo" in "foo bar". 

- -

A regular expression may have multiple capturing groups. In results, matches to capturing groups typically in an array whose members are in the same order as the left parentheses in the capturing group. This is usually just the order of the capturing groups themselves. This becomes important when capturing groups are nested. Matches are accessed using the index of the the result's elements ([1], ..., [n]) or from the predefined RegExp object's properties ($1, ..., $9).

- -

Capturing groups have a performance penalty. If you don't need the matched substring to be recalled, prefer non-capturing parentheses (see below).

- -

String.match() won't return groups if the /.../g flag is set. However, you can still use String.matchAll() to get all matches.

-
\n -

Where n is a positive integer. A back reference to the last substring matching the n parenthetical in the regular expression (counting left parentheses). For example, /apple(,)\sorange\1/ matches "apple, orange," in "apple, orange, cherry, peach". A complete example follows this table.

-
(?<Name>x) -

Named capturing group: Matches x and stores it on the groups property of the returned matches under the name specified by <Name>. The angle brackets ('<' and '>') are required for group name.

- -

For example, to extract the United States area code from a phone number, I could use /\((?<area>\d\d\d)\)/. The resulting number would appear under matches.groups.area.

-
(?:x)Non-capturing group: Matches x but does not remember the match. The matched substring cannot be recalled from the resulting array's elements ([1], ..., [n]) or from the predefined RegExp object's properties ($1, ..., $9).
- -

Examples

- -

Browser support

- -

Firefox currently doesn't support named groups. See corresponding issue.

- -

See also

diff --git "a/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/index.html" "b/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/index.html" deleted file mode 100644 index 5fbbcef0a0..0000000000 --- "a/files/ko/web/javascript/guide/\354\240\225\352\267\234\354\213\235/index.html" +++ /dev/null @@ -1,666 +0,0 @@ ---- -title: 정규 표현식 -slug: Web/JavaScript/Guide/정규식 -tags: - - 자바스크립트 - - 정규식 -translation_of: Web/JavaScript/Guide/Regular_Expressions ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}
- -

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 {{jsxref("RegExp")}}의 {{jsxref("RegExp.exec", "exec")}} 메소드와 {{jsxref("RegExp.test", "test")}} 메소드  ,그리고 {{jsxref("String")}}의  {{jsxref("String.match", "match")}}메소드 , {{jsxref("String.replace", "replace")}}메소드 , {{jsxref("String.search", "search")}}메소드 ,  {{jsxref("String.split", "split")}} 메소드와 함께 쓰입니다 . 이 장에서는 자바스크립트의 정규식에 대하여 설명합니다.

- -

정규 표현식 만들기

- -

(역주: 정규 표현식을 줄여서 '정규식'이라고 하기도 합니다. 아래 부분부터 '정규식'이라는 용어를 사용하겠습니다.)

- -

정규식을 만드는 방법에는 두 가지가 있습니다.

- -

정규식 리터럴(슬래쉬"/"로 감싸는 패턴)을 사용하는 방법은 다음과 같습니다.

- -
var re = /ab+c/;
-
- -

정규식 리터럴은 스크립트가 불러와질 때 컴파일됩니다. 만약 정규식이 상수라면, 이렇게 사용하는 것이 성능을 향상시킬 수 있습니다.

- -

다른 방법으로는,  {{jsxref("RegExp")}} 객체의 생성자 함수를 호출하는 방법도 있습니다:

- -
var re = new RegExp("ab+c");
-
- -

생성자 함수를 사용하면 정규식이 실행 시점에 컴파일됩니다. 정규식의 패턴이 변경될 수 있는 경우, 혹은 사용자 입력과 같이 다른 출처로부터 패턴을 가져와야 하는 경우에는 생성자 함수를 사용하세요.

- -

정규식 패턴 작성하기

- -

정규식 패턴은 /abc/ 같이 단순 문자로 구성될 수도 있고, /ab*c/ 또는 /Chapter (\d+)\.\d*/와 같이 단순 문자와 특수 문자의 조합으로 구성될 수도 있습니다. 마지막 예제는 기억장치처럼 쓰이는 괄호를 포함하고 있습니다. {{web.link("#.ED.8C.A8.ED.84.B4.ED.99.94.EB.90.9C_.EB.B6.80.EB.B6.84_.EB.AC.B8.EC.9E.90.EC.97.B4_.EC.9D.BC.EC.B9.98_.EC.82.AC.EC.9A.A9.ED.95.98.EA.B8.B0", "패턴화된 부분 문자열 일치 사용하기") }}에서 설명하는것 처럼 패턴에서 괄호를 포함한 부분은 나중에 사용하기 위하여 저장됩니다.

- -

단순 패턴 사용하기

- -

단순 패턴은 문자열을 있는 그대로 대응시키고자 할 때 사용됩니다. 예를 들어, /abc/라는 패턴은 문자열에서 정확히 'abc' 라는 문자들이 모두 함께 순서대로 나타나야 대응됩니다. 위의 패턴은 "Hi, do you know your abc's?" 와 "The latest airplane designs evolved from slabcraft." 두가지 예에서 부분 문자열 'abc'에 대응될 것입니다.  'Grab crab' 이라는 문자열에서 'ab c' 라는 부분 문자열을 포함하고 있지만, 'abc'를 정확하게 포함하고 있지 않기 때문에 대응되지 않습니다.

- -

특수 문자 사용하기

- -

검색에서 하나 이상의 b들을 찾거나, 혹은 공백을 찾는 것과 같이 '있는 그대로의 대응' 이상의 대응을 필요로 할 경우, 패턴에 특수한 문자를 포함시킵니다. 예를 들어, /ab*c/ 패턴은  'a' 문자 뒤에 0개 이상의 'b' 문자(* 문자는 바로 앞의 문자가 0개 이상이라는 것을 의미합니다)가 나타나고 바로 뒤에 'c' 문자가 나타나는 문자 조합에 대응됩니다. 문자열 "cbbabbbbcdebc," 에서 위의 패턴은 부분 문자열 'abbbbc' 와 대응됩니다.

- -

아래 표는 정규식에서 사용되는 모든 특수문자 목록 및 그에 대한 설명입니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
정규식에서의 특수문자
CharacterMeaning
\ -

다음의 규칙에 따라 일치합니다:
-
- 특수 문자가 아닌 문자(non-special character) 앞에서 사용된 백슬래시는 '해당 문자는 특별하고, 문자 그대로 해석되면 안된다'는 사실을 가리킵니다. 예를 들어, 앞에 \가 없는 'b'는 보통 소문자 b가 나오는 패턴과 대응됩니다. 그러나 '\b' 자체는 어떤 문자와도 대응되지 않습니다; 이 문자는 특별한 단어 경계 문자를 형성합니다.
-
- 특수 문자 앞에 위치한 백슬래시는 '다음에 나오는 문자는 특별하지않고, 문자 그대로 해석되어야 한다'는 사실을 가리킵니다. 예를 들어, 패턴 /a*/ 에서의 특수문자 '*'는 0개 이상의 'a' 문자가 등장함을 나타냅니다. 이와는 다르게, 패턴 /a\*/ 는 '*'이 특별하지 않다는 것을 나타내며, 'a*'와 같은 문자열과 대응될 수 있습니다.
-
- RegExp("pattern") 표기를 쓰면서 \ 자체를 이스케이프 하는 것을 잊지 마세요. 왜냐하면 \ 는 문자열에서도 이스케이프 문자이기 때문입니다. (역주: /a\*/ 와 같은 패턴을 생성자로 만들려면 new RegExp('a\\*')와 같이 백슬래시 자체를 이스케이프 시켜주어야 합니다.)

-
^입력의 시작 부분에 대응됩니다. 만약 다중행 플래그가 참으로 설정되어 있다면, 줄 바꿈 문자 바로 다음 부분과도 대응됩니다.
-
- 예를 들어, /^A/ 는 "an A" 의 'A'와는 대응되지 않습니다, 그러나 "An E" 의 'A'와는 대응됩니다.
-
- '^' 가 문자셋([abc]) 패턴의 첫 글자로 쓰인다면, 그 때는 전혀 다른 의미를 가집니다. 자세한 내용은 역 문자셋을 참고하세요.
$ -

입력의 끝 부분과 대응됩니다. 만약 다중행 플래그가 참으로 설정되어 있다면, 줄 바꿈 문자의 바로 앞 부분과도 대응됩니다.

- -

예를 들어, /t$/ 는 "eater" 의 't'에는 대응되지 않습니다, 그러나 "eat" 과는 대응됩니다.

-
* -

앞의 표현식이 0회 이상 연속으로 반복되는 부분과 대응됩니다. {0,} 와 같은 의미입니다.

- -

예를 들어, /bo*/ 는 "A ghost booooed" 의 'boooo' 와 대응되고, "A bird warbled" 의 'b'에 대응되지만 "A goat grunted" 내의 어느 부분과도 대응되지 않습니다.

-
+ -

앞의 표현식이 1회 이상 연속으로 반복되는 부분과 대응됩니다. {1,} 와 같은 의미입니다.

- -

예를 들어, /a+/ 는 "candy"의 'a'에 대응되고 "caaaaaaandy" 의 모든 'a'들에 대응되지만, "cndy" 내의 어느 부분과도 대응되지 않습니다.

-
?앞의 표현식이 0 또는 1회 등장하는 부분과 대응됩니다. {0,1} 와 같은 의미입니다.
-
- 예를 들어, /e?le?/ 는 "angel"의 'el' 에 대응되고, "angle"의 'le' 에 대응되고 또한 "oslo" 의 'l'에도 대응됩니다.
-
- 만약 수량자 *, +, ?, {} 바로 뒤에 사용하면, 기본적으로 탐욕스럽던(가능한 한 많이 대응시킴) 수량자를 탐욕스럽지 않게(가능한 가장 적은 문자들에 대응시킴) 만듭니다. 예를 들어, /\d+/를 "123abc"에 적용시키면 "123"과 대응됩니다. 그러나 /\d+?/를 같은 문자열에 적용시키면 오직 "1"과만 대응됩니다.
-
- 또한 이 문자는 x(?=y)x(?!y) 항목에서 설명하는 바와 같이 사전 검증(lookahead assertion)을 위해서도 쓰입니다.
-  
. -

개행 문자를 제외한 모든 단일 문자와 대응됩니다.

- -

예를 들어, /.n/는 "nay, an apple is on the tree"에서 'an'과 'on'에 대응되지만, 'nay' 에는 대응되지 않습니다.

-
(x) -

다음의 예제가 보여주는것 처럼 'x'에 대응되고, 그것을 기억합니다. 괄호는 포획 괄호(capturing parentheses)라 불립니다.
-
- 패턴 /(foo) (bar) \1 \2/ 안의 '(foo)' 와 '(bar)'는 문자열"foo bar foo bar"에서 처음의 두 단어에 대응되고 이를 기억합니다. 패턴 내부의 \1\2는 문자열의 마지막 두 단어에 대응됩니다. (역주: \n 패턴은 앞의 n번째 포획괄호에 대응된 문자열과 똑같은 문자열에 대응됩니다.) \1, \2, \n과 같은 문법은 정규식의 패턴 부분에서 사용됩니다. 정규식의 치환 부분에서는 $1, $2, $n과 같은 문법이 사용되어야 합니다. 예를 들어, 'bar foo'.replace( /(...) (...)/, '$2 $1')와 같이 사용되어야 합니다. $& 패턴은 앞에서 대응된 전체 문자열을 가리킵니다.

-
(?:x)'x'에 대응되지만 대응된 것을 기억하지 않습니다. 괄호는 비포획 괄호(non-capturing parentheses)라고 불리우고, 정규식 연산자가 같이 동작할 수 있게 하위 표현을 정의할 수 있습니다. 정규식 예제 /(?:foo){1,2}/을 생각해보세요. 만약 정규식이 /foo{1,2}/라면, {1,2}는 'foo'의 마지막 'o' 에만 적용됩니다. 비포획 괄호과 같이 쓰인다면, {1,2}는 단어 'foo' 전체에 적용됩니다.
x(?=y) -

오직 'y'가 뒤따라오는 'x'에만 대응됩니다. 이것은 lookahead 라고 불립니다.

- -

예를 들어, /Jack(?=Sprat)/ 는 'Sprat'가 뒤따라오는 'Jack' 에만 대응됩니다. /Jack(?=Sprat|Frost)/는 'Sprat' 또는 'Frost'가 뒤따라오는 'Jack'에만 대응됩니다. 그러나, 'Sprat' 및 'Frost' 는 대응 결과의 일부가 아닙니다.

-
x(?!y) -

'x'뒤에  'y'가 없는경우에만 'x'에 일치합니다. 이것은 negated lookahead 라고 불립니다.

- -

예를 들어, /\d+(?!\.)/는 소숫점이 뒤따라오지 않는 숫자에 일치합니다. 정규식 /\d+(?!\.)/.exec("3.141")는 '3.141' 이 아닌 '141'에 일치합니다.

-
x|y -

'x' 또는 'y'에 대응됩니다.

- -

예를 들어, /green|red/는 "green apple"의 'green'에 대응되고, "red apple."의 'red'에 대응됩니다.

-
{n}앞 표현식이 n번 나타나는 부분에 대응됩니다. n은 반드시 양의 정수여야 합니다.
-
- 예를 들어, /a{2}/는 "candy,"의 'a'에는 대응되지 않지만, "caandy,"의 모든 a 와, "caaandy."의 첫 두 a 에는 대응됩니다.
{n,m} -

nm은 양의 정수이고, n <= m를 만족해야 합니다. 앞 문자가 최소 n개, 최대 m개가 나타나는 부분에 대응됩니다. m이 생략된다면, m은 ∞로 취급됩니다.

- -

예를 들어, /a{1,3}/는 "cndy"에서 아무것에도 대응되지 않지만, "caandy,"의 첫 두 a 와 "caaaaaaandy"의 첫 세 a 에 대응됩니다. "caaaaaaandy"에서 더 많은 a 들이 있지만, "aaa"에만 대응된다는 점에 주목하세요.

-
[xyz]문자셋(Character set) 입니다. 이 패턴 타입은 괄호 안의 어떤 문자(이스케이프 시퀀스까지 포함)와도 대응됩니다. 점(.) 이나 별표 (*) 같은 특수 문자는 문자셋 내부에서는 특수 문자가 아닙니다. 따라서 이스케이프시킬 필요가 없습니다. 하이픈을 이용하여 문자의 범위를 지정해줄 수 있습니다.
-
- 예를 들어, 패턴 [a-d] 는 패턴 [abcd] 와 똑같이 동작하며, "brisket"의 'b' 에 일치하고, "city"의 'c' 에 일치합니다. 패턴 /[a-z.]+/ /[\w.]+/ 는 "test.i.ng" 전체 문자열이 일치합니다.
[^xyz] -

부정 문자셋(negated character set) 또는 보충 문자셋(complemented character set)입니다. 괄호 내부에 등장하지 않는 어떤 문자와도 대응됩니다. 하이픈을 이용하여 문자의 범위를 지정할 수 있습니다. 일반적인 문자셋에서 작동하는 모든 것은 여기에서도 작동합니다.

- -

예를 들어, 패턴[^abc]는 패턴[^a-c]와 동일합니다. 두 패턴은 "brisket"의 'r', "chop."의 'h' 에 대응됩니다.

-
[\b]백스페이스(U+0008)에 대응됩니다. 이와 같이, 백스페이스 문자 리터럴에 대응시키려면, 대괄호("[]")를 이용해야만 합니다. (\b와 혼동하지 마세요.)
\b -

단어 경계에 대응됩니다. 단어 경계는 다른 '단어 문자'가 앞이나 뒤에 등장하지 않는 위치에 대응됩니다. 단어의 경계는 대응 결과에 포함되지 않는다는 사실에 주의하세요. 다른 말로는, 단어의 경계에 대응되는 문자열의 길이는 항상 0입니다. (패턴 [\b]와 혼동하지 마세요.)

- -

예제:
- /\bm/는 "moon"의 'm'에 대응됩니다;
- /oo\b/ 는 "moon"의 'oo' 부분에 대응되지 않는데, 왜냐하면 'oo'를 뒤따라오는 'n'이 단어 문자이기 때문입니다;
- /oon\b/는 "moon"의 'oon'에 대응됩니다. 왜냐하면, 'oon'은 문자열의 끝이라서, 뒤따라오는 단어 문자가 없기 때문입니다 ;
- /\w\b\w/는 어떤 것에도 일치하지 않습니다. 왜냐하면, 단어 문자는 절대로 비 단어 문자와 단어 문자 두개가 뒤따라올수 없기 때문입니다.

- -
-

숙지하세요: 자바스크립트의 정규식 엔진은 특정 문자 집합을 '단어 문자'로 정의합니다. 이 집단에 속하지 않는 모든 문자는 단어 분리(word break) 로 여겨집니다. 단어 문자로 간주되는 문자들은 얼마 없습니다: 오로지 로마자 소문자와 대문자, 10진수 숫자, 밑줄 문자로 구성되어 있습니다. "é" 또는 "ü" 같이, 강세 표시 문자들은 안타깝게도 단어 분리(word breaks) 로 취급됩니다.

-
-
\B -

단어 경계가 아닌 부분에 대응됩니다. 아래와 같은 경우들이 있습니다:

- -
    -
  • 문자열의 첫 번째 문자가 단어 문자가 아닌 경우, 해당 문자의 앞 부분에 대응됩니다.
  • -
  • 문자열의 마지막 문자가 단어 문자가 아닌 경우, 해당 문자의 뒷 부분에 대응됩니다.
  • -
  • 두 단어 문자의 사이에 대응됩니다.
  • -
  • 단어 문자가 아닌 두 문자 사이에 대응됩니다.
  • -
  • 빈 문자열에 대응됩니다.
  • -
- -

문자열의 시작 부분과 끝 부분은 단어가 아닌 것으로 간주됩니다.

- -

예를 들어, /\B../ 는 "noonday"의 'oo'와 대응되며, /y\B./ 는 "possibly yesterday."의 'ye'와 대응됩니다.

-
\cX -

문자열 내부의 제어 문자에 대응됩니다. 여기서 X는 A에서 Z까지의 문자 중 하나입니다.

- -

예를 들어, /\cM/는 문자열에서 control-M (U+000D)에 대응됩니다.

-
\d -

숫자 문자에 대응됩니다. [0-9]와 동일합니다.

- -

예를 들어, /\d/ 또는 /[0-9]/는 "B2 is the suite number."에서 '2'에 대응됩니다.

-
\D -

숫자 문자가 아닌 문자에 대응됩니다. [^0-9]와 동일합니다.

- -

예를 들어, /\D/ 또는 /[^0-9]/는 "B2 is the suite number."의 'B'에 대응됩니다.

-
\f폼피드 (U+000C) 문자에 대응됩니다.
\n줄 바꿈 (U+000A) 문자에 대응됩니다.
\r캐리지 리턴(U+000D) 문자에 대응됩니다.
\s -

스페이스, 탭, 폼피드, 줄 바꿈 문자등을 포함한 하나의 공백 문자에 대응됩니다. [ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].와 동일합니다.

- -

예를 들어, /\s\w*/는 "foo bar."의 ' bar'에 대응됩니다.

-
\S -

공백 문자가 아닌 하나의 문자에 대응됩니다. [^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]. 와 동일합니다.

- -

예를 들어, /\S\w*/는 "foo bar."의 'foo' 에 대응됩니다.

-
\t탭 (U+0009) 문자에 대응됩니다.
\v수직 탭(U+000B) 문자에 대응됩니다.
\w -

밑줄 문자를 포함한 영숫자 문자에 대응됩니다. [A-Za-z0-9_] 와 동일합니다. (역주: 여기에 대응되는 문자를 단어 문자라고 합니다.)

- -

예를 들어, /\w/는 "apple,"의 'a' 에 대응되고, "$5.28,"의 '5'에 대응되고,"3D."의 '3'에 대응됩니다.

-
\W -

단어 문자가 아닌 문자에 대응됩니다. [^A-Za-z0-9_] 와 동일합니다.

- -

예를 들어, /\W/ 또는 /[^A-Za-z0-9_]/는 "50%."의 '%' 에 대응됩니다.

-
\n -

정규식 내부의 n번째 괄호에서 대응된 부분에 대한 역참조 입니다. 여기서, n은 양의 정수입니다.

- -

예를 들어, /apple(,)\sorange\1/는 "apple, orange, cherry, peach."의 'apple, orange,' 에 일치합니다.

-
\0널 (U+0000)문자에 대응합니다. 이 때 다른 숫자를 뒤에 쓰지 마세요. 왜냐하면 \0<digits>는 8진 이스케이프 시퀀스이기 때문입니다.
\xhh코드가 hh(두 16진 숫자)인 문자에 일치합니다.
\uhhhh코드가 hhhh(네개의 16진 숫자)인 문자에 일치합니다.
- -

사용자 입력을 이스케이프해서 정규식 내부에서 문자 그대로 취급해야 하는 경우, 간단히 치환을 하면 됩니다:

- -
function escapeRegExp(string){
-  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $&는 일치한 전체 문자열을 의미합니다.
-}
- -

괄호를 사용하기

- -

정규식 내부의 일부를 둘러싼 괄호는, 해당 부분에서 대응된 문자열을 기억하는 효과를 갖습니다. 기억된 문자열은 이후 {{ web.link("#.ED.8C.A8.ED.84.B4.ED.99.94.EB.90.9C_.EB.B6.80.EB.B6.84_.EB.AC.B8.EC.9E.90.EC.97.B4_.EC.9D.BC.EC.B9.98_.EC.82.AC.EC.9A.A9.ED.95.98.EA.B8.B0", "패턴화된 부분 문자열 일치 사용하기") }}에서 설명한 것처럼 다른 곳에서 사용하기 위하여 불러와질 수 있습니다.

- -

예를 들면, 패턴 /Chapter (\d+)\.\d*/는 패턴의 일부분이 기억될 거라는 사실을 나타냅니다. 이 패턴은 하나 이상의 숫자(\d는 숫자를 의미하고 +는 1개 이상을 의미합니다.) 이후에 하나의 소숫점(\가 앞에 붙은 소숫점은 문자 그대로의 문자 '.' 에 대응됨을 나타냅니다), 그뒤 0개 이상의 숫자(\d 는 숫자, * 는 0개 이상을 의미합니다.)가 뒤따라오는 'Chapter ' 문자열에 대응됩니다. 더해서, 괄호는 처음으로 일치하는 숫자 문자들을 기억하기 위하여 사용되었습니다.

- -

이 패턴은 "Open Chapter 4.3, paragraph 6"에 나타나며, '4'가 기억됩니다. 이 패턴은 "Chapter 3 and 4"에는 나타나지 않습니다. 왜냐하면 문자열이 '3'이후에 마침표를 가지고 있지 않기 때문입니다.

- -

부분 문자열을 대응시키면서도 해당 부분을 기억하지 않으려면, 괄호의 첫머리에 ?:패턴을 사용하세요. 예를 들어, (?:\d+)는 1개 이상의 숫자에 대응되지만 해당 문자들을 기억하지 않습니다.

- -

정규식 사용하기

- -

정규식은 RegExp, test, exec, String, match, replace, search, split 메소드와 함께 쓰입니다. 이 메소드는 JavaScript reference에서 잘 설명되어 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
정규식에서 쓰이는 메소드
MethodDescription
{{jsxref("RegExp.exec", "exec")}}대응되는 문자열을 찾는 RegExp 메소드입니다. 정보를 가지고 있는 배열을 반환합니다. 대응되는 문자열을 찾지 못했다면 null을 반환합니다.
{{jsxref("RegExp.test", "test")}}대응되는 문자열이 있는지 검사하는 RegExp 메소드 입니다. true 나 false를 반환합니다.
{{jsxref("String.match", "match")}}대응되는 문자열을 찾는 RegExp 메소드입니다. 정보를 가지고 있는 배열을 반환합니다. 대응되는 문자열을 찾지 못했다면 null을 반환합니다.
{{jsxref("String.search", "search")}} -

대응되는 문자열이 있는지 검사하는 String 메소드 입니다. 대응된 부분의 인덱스를 반환합니다. 대응되는 문자열을 찾지 못했다면 -1을 반환합니다.

-
{{jsxref("String.replace", "replace")}}대응되는 문자열을 찾아 다른 문자열로 치환하는 String 메소드입니다.
{{jsxref("String.split", "split")}}정규식 혹은 문자열로 대상 문자열을 나누어 배열로 반환하는 String 메소드입니다.
- -

문자열 내부에 패턴과 대응되는 부분이 있는지 알고 싶다면, test 나 search 메소드를 사용하세요; 좀 더 많은 정보를 원하면 (대신 실행이 느림)  exec 나 match 메소드를 사용하세요. 만약 exec 나 match 메소드를 사용했는데 대응되는 부분이 있다면, 이 메소드는 배열을 반환하고 정규식 객체의 속성을 업데이트 합니다. 만약 대응되는 부분이 없다면, exec 메소드는 null 을 반환합니다. (즉, false와 같은 의미로 사용될 수 있습니다.).

- -

아래의 예에서는, 문자열 내부에서 대응되는 부분을 찾기 위해 exec 메소드를 사용했습니다.

- -
var myRe = /d(b+)d/g;
-var myArray = myRe.exec("cdbbdbsbz");
-
- -

만약 정규식 속성에 접근할 필요가 없다면, 아래와 같이 myArray를 만드는 다른 방법도 있습니다:

- -
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
-
- -

문자열로부터 정규식을 만들고 싶다면, 이런 방법도 있습니다:

- -
var myRe = new RegExp("d(b+)d", "g");
-var myArray = myRe.exec("cdbbdbsbz");
-
- -

위의 스크립트에서는, 대응되는 부분이 발견되었고 아래의 표에서 설명하는 대로 배열을 반환하며 속성을 갱신합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
정규식 실행결과
ObjectProperty or indexDescriptionIn this example
myArray대응된 문자열 및 기억한 모든 부분 문자열['dbbd', 'bb', index: 1, input: 'cdbbdbsbz']
index입력된 문자열에서 대응된 부분에 해당하는 인덱스 (0부터 시작)1
input입력된 원본 문자열"cdbbdbsbz"
[0]마지막으로 대응된 문자열"dbbd"
myRelastIndex다음 검색 시 검색을 시작할 인덱스 (이 속성은 g 옵션을 설정한 정규식에 대해서만 설정됩니다. 자세한 사항은 {{ web.link("#Advanced_searching_with_flags", "Advanced Searching With Flags") }} 부분을 참고하세요.)5
source패턴 문자열. 정규식이 생성될 때 갱신됩니다. 실행 시점에는 갱신되지 않습니다."d(b+)d"
- -

위 예제에서의 두 번째 형태처럼, 정규식 객체를 변수에 대입하지 않고도 사용할 수 있습니다. 하지만, 이렇게 하면 정규식 객체가 매번 새로 생성됩니다. 이러한 이유로, 만약 변수에 대입하지 않는 형태를 사용하는 경우 나중에 그 정규식의 속성에 접근할 수 없게 됩니다. 예를 들어, 이러한 스크립트가 있을 수 있습니다:

- -
var myRe = /d(b+)d/g;
-var myArray = myRe.exec("cdbbdbsbz");
-console.log("The value of lastIndex is " + myRe.lastIndex);
-
-// "The value of lastIndex is 5"
-
- -

그러나, 만약 이러한 스크립트가 있으면:

- -
var myArray = /d(b+)d/g.exec("cdbbdbsbz");
-console.log("The value of lastIndex is " + /d(b+)d/g.lastIndex);
-
-// "The value of lastIndex is 0"
-
- -

두 구문에서의 /d(b+)d/g 는 서로 다른  정규식 객체이고, 따라서 별개의 lastIndex 속성을 갖게 됩니다. 정규식 객체의 속성을 사용해야 하는 경우라면, 먼저 변수에 대입하세요.

- -

괄호로 둘러싼 패턴 사용하기

- -

정규식 패턴에 괄호를 사용하면, 그 부분을 별도로 대응시키면서 대응된 부분을 기억합니다. 예를 들면, /a(b)c/ 는 'abc' 와 대응되면서 'b'를 기억합니다. 괄호로 감싸진 문자열을 불러오려면, 배열 요소 [1], ..., [n] 를 사용하세요.

- -

괄호로 감쌀 수 있는 문자의 개수에는 제한이 없습니다. 반환된 배열은 찾아낸 모든 것들을 갖고 있습니다. 다음의 예는 괄호로 둘러싸진 부분이 어떻게 대응되는지 보여줍니다.

- -

다음의 예는 문자열 내부의 단어를 바꾸기 위해 {{jsxref("String.replace", "replace()")}} 메소드를 이용하고 있습니다. 치환 문자열로는 $1$2 를 사용하고 있는데, 이는 각각 첫 번째와 두 번째 괄호가 쳐진 부분에 대응된 문자열을 가리킵니다.

- -
var re = /(\w+)\s(\w+)/;
-var str = "John Smith";
-var newstr = str.replace(re, "$2, $1");
-console.log(newstr);
-
-// "Smith, John"
-
- -

플래그를 사용한 고급검색

- -

정규식은 여섯 개의 플래그를 설정해줄 수 있으며, 이를 통해 전역 검색 또는 대소문자 구분 없는 검색을 수행할 수 있습니다. 이 플래그들은 각기 사용될 수도 있고 함께 사용될 수도 있고 순서에 구분이 없습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Regular expression flags
FlagDescription
g전역 검색
i대소문자 구분 없는 검색
m다중행(multi-line) 검색
s.에 개행 문자도 매칭(ES2018)
u유니코드; 패턴을 유니코드 코드 포인트의 나열로 취급합니다.
y"sticky" 검색을 수행. 문자열의 현재 위치부터 검색을 수행합니다. {{jsxref("RegExp.sticky", "sticky")}} 문서를 확인하세요.
- -

정규식에 플래그를 포함시키려면, 아래 문법을 사용하세요:

- -
var re = /pattern/flags;
-
- -

혹은 아래와 같이 할 수도 있습니다:

- -
var re = new RegExp("pattern", "flags");
-
- -

이 플래그는 정규식에 합쳐지는 정보임을 기억하는게 좋습니다. 이것들은 나중에 추가되거나 제거될 수 없습니다.

- -

예를 들어, re = /\w+\s/g 는 한 개 이상의 문자열 뒤에 공백이 하나 있는 패턴을 찾는 정규식을 생성합니다. 그리고 문자열 전체에 걸쳐 이 조합을 검색합니다.

- -
var re = /\w+\s/g;
-var str = "fee fi fo fum";
-var myArray = str.match(re);
-console.log(myArray);
-
-// ["fee ", "fi ", "fo "]
-
- -

아래 코드는:

- -
var re = /\w+\s/g;
-
- -

이렇게 바꿔쓸 수 있습니다:

- -
var re = new RegExp("\\w+\\s", "g");
-
- -

그리고 똑같은 결과를 얻습니다.

- -

 .exec() 메소드를 사용할 때에는 'g' 플래그에 대한 동작이 다릅니다.  ("클래스"와 "인수"의 역할이 뒤바뀝니다:  .match()를 사용할 때는, string 클래스가 메소드를 갖고 정규식은 인수였던 것에 반해, .exec()를 사용할 때는 정규식이 메소드를 갖고 문자열이 인수가 됩니다. str.match(re) 과 re.exec(str)를 비교해보세요.)  'g' 플래그와  .exec() 메소드가 함께 사용되면 진행상황에 대한 정보가 반환됩니다.

- -
var xArray; while(xArray = re.exec(str)) console.log(xArray);
-// 다음과 같이 출력됩니다:
-// ["fee ", index: 0, input: "fee fi fo fum"]
-// ["fi ", index: 4, input: "fee fi fo fum"]
-// ["fo ", index: 7, input: "fee fi fo fum"]
- -

m 플래그는 여러 줄의 입력 문자열이 실제로 여러 줄로서 다뤄져야 하는 경우에 쓰입니다. 만약 m 플래그가 사용되면, ^$ 문자는 전체 문자열의 시작과 끝에 대응되는 것이 아니라 각 라인의 시작과 끝에 대응됩니다.

- -

예시

- -

다음의 예는 정규 표현식의 몇 가지 사용법을 보여줍니다.

- -

입력 문자열에서 순서를 변경하기

- -

다음 예는 정규식의 , string.split()과 string.replace()의 사용을 설명합니다. 그것은 공백, 탭과 정확히 하나의 세미콜론의 구분으로 이름(이름을 먼저)이 포함된 대략 형식의 입력 문자열을 정리합니다. 마지막으로, 순서(성을 먼저)를 뒤바꾸고 목록을 정렬합니다.

- -
// The name string contains multiple spaces and tabs,
-// and may have multiple spaces between first and last names.
-var names = "Harry Trump ;Fred Barney; Helen Rigby ; Bill Abel ; Chris Hand ";
-
-var output = ["---------- Original String\n", names + "\n"];
-
-// Prepare two regular expression patterns and array storage.
-// Split the string into array elements.
-
-// pattern: possible white space then semicolon then possible white space
-var pattern = /\s*;\s*/;
-
-// Break the string into pieces separated by the pattern above and
-// store the pieces in an array called nameList
-var nameList = names.split(pattern);
-
-// new pattern: one or more characters then spaces then characters.
-// Use parentheses to "memorize" portions of the pattern.
-// The memorized portions are referred to later.
-pattern = /(\w+)\s+(\w+)/;
-
-// New array for holding names being processed.
-var bySurnameList = [];
-
-// Display the name array and populate the new array
-// with comma-separated names, last first.
-//
-// The replace method removes anything matching the pattern
-// and replaces it with the memorized string—second memorized portion
-// followed by comma space followed by first memorized portion.
-//
-// The variables $1 and $2 refer to the portions
-// memorized while matching the pattern.
-
-output.push("---------- After Split by Regular Expression");
-
-var i, len;
-for (i = 0, len = nameList.length; i < len; i++){
-  output.push(nameList[i]);
-  bySurnameList[i] = nameList[i].replace(pattern, "$2, $1");
-}
-
-// Display the new array.
-output.push("---------- Names Reversed");
-for (i = 0, len = bySurnameList.length; i < len; i++){
-  output.push(bySurnameList[i]);
-}
-
-// Sort by last name, then display the sorted array.
-bySurnameList.sort();
-output.push("---------- Sorted");
-for (i = 0, len = bySurnameList.length; i < len; i++){
-  output.push(bySurnameList[i]);
-}
-
-output.push("---------- End");
-
-console.log(output.join("\n"));
-
- -

입력을 확인하기 위해 특수 문자를 사용하기

- -

다음 예에서, 사용자는 전화번호를 입력 할 것으로 예상됩니다. 사용자가 "Check" 버튼을 누를 때, 스크립트는 번호의 유효성을 검사합니다. 번호가 유효한 경우(정규식에 의해 지정된 문자 시퀀스와 일치합니다), 스크립트는 사용자에게 감사하는 메시지와 번호를 확인하는 메시지를 나타냅니다. 번호가 유효하지 않은 경우, 스크립트는 전화번호가 유효하지 않다는 것을 사용자에게 알립니다.

- -

비 캡처링 괄호 (?: , 정규식은 세 자리 숫자를 찾습니다 \d{3} OR | 왼쪽 괄호\( 세 자리 숫자 다음에 \d{3}, 닫는 괄호 다음에 \), (비 캡처링 괄호를 종료)) 안에, 하나의 대시, 슬래시, 또는 소수점을 다음과 같이 발견했을 때,  세 자리 숫자 다음에 d{3}, 대시의 기억 매치, 슬래시, 또는 소수점 다음에 \1, 네 자리 숫자 다음에 \d{4} 문자를 기억합니다([-\/\.]).

- -

사용자가 <Enter> 키를 누를 때 활성화 변경 이벤트는 RegExp.input의 값을 설정합니다.

- -
<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
-    <meta http-equiv="Content-Script-Type" content="text/javascript">
-    <script type="text/javascript">
-      var re = /(?:\d{3}|\(\d{3}\))([-\/\.])\d{3}\1\d{4}/;
-      function testInfo(phoneInput){
-        var OK = re.exec(phoneInput.value);
-        if (!OK)
-          window.alert(OK.input + " isn't a phone number with area code!");
-        else
-          window.alert("Thanks, your phone number is " + OK[0]);
-      }
-    </script>
-  </head>
-  <body>
-    <p>Enter your phone number (with area code) and then click "Check".
-        <br>The expected format is like ###-###-####.</p>
-    <form action="#">
-      <input id="phone"><button onclick="testInfo(document.getElementById('phone'));">Check</button>
-    </form>
-  </body>
-</html>
-
- -

{{PreviousNext("Web/JavaScript/Guide/Text_formatting", "Web/JavaScript/Guide/Indexed_collections")}}

diff --git "a/files/ko/web/javascript/guide/\355\225\250\354\210\230/index.html" "b/files/ko/web/javascript/guide/\355\225\250\354\210\230/index.html" deleted file mode 100644 index cf9d928eb3..0000000000 --- "a/files/ko/web/javascript/guide/\355\225\250\354\210\230/index.html" +++ /dev/null @@ -1,658 +0,0 @@ ---- -title: 함수 -slug: Web/JavaScript/Guide/함수 -translation_of: Web/JavaScript/Guide/Functions ---- -
{{jsSidebar("JavaScript Guide")}} {{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}
- -

함수는 JavaScript에서 기본적인 구성 블록 중의 하나입니다. 함수는 작업을 수행하거나 값을 계산하는 문장 집합 같은 자바스크립트 절차입니다. 함수를 사용하려면 함수를 호출하고자 하는 범위 내에서 함수를 정의해야만 합니다.

- -

세부 사항에 대해서는 exhaustive reference chapter about JavaScript functions를 참조하세요.

- -

함수 정의

- -

함수 선언

- -

함수 정의(또는 함수 선언)는 다음과 같은 함수 키워드로 구성되어 있습니다:

- -
    -
  • 함수의 이름
  • -
  • 괄호 안에서 쉼표로 분리된 함수의 매개변수 목록 
  • -
  • 중괄호 { } 안에서 함수를 정의하는 자바스크립트 표현
  • -
- -

예를 들어, 다음의 코드는 square라는 간단한 함수를 정의하였습니다:

- -
function square(number) {
-  return number * number;
-}
- -

함수 squarenumber라는 하나의 매개변수를 가집니다. 이 함수는 인수 (즉, number) 자체를 곱하여 반환하는 하나의 문장으로 구성되어 있습니다. return 문은 함수에 의해 반환된 값을 지정합니다.

- -
return number * number;
- -

기본 자료형인 매개변수(number와 같은)는 값으로 함수에 전달됩니다; 즉, 값이 함수로 전달됩니다. 그러나 함수가 매개변수의 값을 바꾸더라도 이는 전역적으로 또는 함수를 호출하는 곳에는 반영되지 않습니다.

- -

만약 여러분이 매개변수로 (예: {{jsxref("Array")}}이나 사용자가 정의한 객체와 같이 기본 자료형이 아닌 경우)를 전달하거나 함수가 객체의 속성을 변하게 하는 경우, 다음의 예처럼 그 변화는 함수 외부에서 볼 수 있습니다:

- -
function myFunc(theObject) {
-  theObject.make = "Toyota";
-}
-
-var mycar = {make: "Honda", model: "Accord", year: 1998};
-var x, y;
-
-x = mycar.make; // x 의 값은 "Honda" 입니다.
-
-myFunc(mycar);
-y = mycar.make; // y 의 값은 "Toyota" 입니다.
-                // (make 속성은 myFunc에서 변경되었습니다.)
-
- -

함수 표현식

- -

위에서 함수 선언은 구문적인 문(statement)이지만, 함수 표현식( function expression)에 의해서 함수가 만들어 질 수도 있습니다. 이 같은 함수를 익명이라고 합니다. 이 말은 모든 함수가 이름을 가질 필요는 없다는 것을 뜻합니다. 예를 들어, 함수 square은 다음과 같이 정의 될 수도 있습니다:

- -
var square = function(number) { return number * number };
-var x = square(4) // x 의 값은 16 입니다.
- -

하지만, 함수 표현식에서 함수의 이름을 지정 할 수 있으며, 함수내에서 자신을 참조하는데 사용되거나, 디버거 내 스택 추적에서 함수를 식별하는 데 사용될 수 있습니다.

- -
var factorial = function fac(n) { return n<2 ? 1 : n*fac(n-1) };
-
-console.log(factorial(3));
-
- -

함수 표현식은 함수를 다른 함수의 매개변수로 전달할 때 편리합니다. 다음 예는 첫 번째 인자로로 함수를, 두 번째 인자로 배열을 받는 map 함수를 보여줍니다.

- -
function map(f,a) {
-  var result = [], // Create a new Array
-      i;
-  for (i = 0; i != a.length; i++)
-    result[i] = f(a[i]);
-  return result;
-}
-
- -

다음 코드에서, 함수 표현식으로 정의된 함수를 인자로 받아, 2번 째 인자인 배열의 모든 요소에 대해 그 함수를 실행합니다.

- -
function map(f, a) {
-  var result = []; // Create a new Array
-  var i; // Declare variable
-  for (i = 0; i != a.length; i++)
-    result[i] = f(a[i]);
-      return result;
-}
-var f = function(x) {
-   return x * x * x;
-}
-var numbers = [0, 1, 2, 5, 10];
-var cube = map(f,numbers);
-console.log(cube);
- -

함수는 [0, 1, 8, 125, 1000] 을 반환합니다.

- -

JavaScript에서 함수는 조건에 의해 정의될 수 있습니다. 예를 들어, 다음 함수 정의는 오직 num이 0일 때 경우에 만 myFunc을 정의합니다.

- -
var myFunc;
-if (num == 0){
-  myFunc = function(theObject) {
-    theObject.make = "Toyota"
-  }
-}
- -

여기에 기술된 바와 같이 함수를 정의하는것에 더하여 {{jsxref("eval", "eval()")}} 과 같이 런타임에 문자열에서 함수들을 만들기위해 {{jsxref("Function")}} 생성자를 사용할 수 있습니다.

- -

객체내의 한 속성이 함수인 경우 메서드라고 합니다. Working with objects에서 객체와 방법에 대해 자세히 알아보세요.

- -

함수 호출

- -

함수를 정의하는 것은 함수를 실행하는 것이 아닙니다. 함수를 정의하는 것은 간단히 함수의 이름을 지어주고, 함수가 호출될 때 무엇을 할지 지정 해주는 것입니다. 사실 함수를 호출하는 것은 나타나있는 매개변수를 가지고 지정된 행위를 수행하는 것입니다. 예를 들어, 만약 여러분이 함수 square를 정의한다면, 함수를 다음과 같이 호출할 수 있습니다.

- -
square(5);
-
- -

위의 문장은 5라는 인수를 가지고 함수를 호출합니다. 함수는 이 함수의 실행문을 실행하고 값 25를 반환합니다.

- -

함수는 호출될 때 범위 내에 있어야 합니다. 그러나 함수의 선언은 이 예에서와 같이, 호이스팅 될 수 있습니다. (코드에서 호출 아래에 선언문이 있습니다.):

- -
console.log(square(5));
-/* ... */
-function square(n) { return n*n }
-
- -

함수의 범위는 함수가 선언된 곳이거나, 전체 프로그램 에서의 최상위 레벨(전역)에 선언된 곳입니다.

- -
-

비고: 위에 구문을 사용하여 함수를 정의하는 경우에만 작동합니다 (즉, function funcName(){} ). 아래와 같은 코드는 작동되지 않습니다. 이것이 의미하는 바는, 함수 호이스팅은 오직 함수 선언과 함께 작동하고, 함수 표현식에서는 동작하지 않습니다.

-
- -
console.log(square);   // square는 초기값으로 undefined를 가지고 호이스트된다.
-console.log(square(5));  // TypeError: square는 함수가 아니다.
-square = function (n) {
-  return n * n;
-}
-
- -

함수의 인수는 문자열과 숫자에 제한되지 않습니다. 여러분은 함수에 전체 객체를 전달할 수 있습니다. show_props() 함수(Working with objects에서 정의된)는 인수로 객체를 취하는 함수의 예입니다.

- -

함수는 자신을 호출할 수 있습니다. 예를 들어, 팩토리얼을 재귀적으로 계산하는 함수가 있습니다:

- -
function factorial(n){
-  if ((n == 0) || (n == 1))
-    return 1;
-  else
-    return (n * factorial(n - 1));
-}
-
- -

여러분은 다음과 같이 1부터 5까지의 팩토리얼을 계산할 수 있습니다.

- -
var a, b, c, d, e;
-a = factorial(1); // a gets the value 1
-b = factorial(2); // b gets the value 2
-c = factorial(3); // c gets the value 6
-d = factorial(4); // d gets the value 24
-e = factorial(5); // e gets the value 120
-
- -

함수를 호출하는 다른 방법들이 있습니다. 함수를 동적 호출해야 하거나, 함수의 인수의 수가 달라져야 하거나, 함수 호출의 맥락이 런타임에서 결정된 특정한 객체로 설정될 필요가 있는 경우가 자주 있습니다. 함수가 그 자체로 객체이고 이들 객체는 차례로 메서드를({{jsxref("Function")}} 객체를 참조) 가지고 있습니다. 이들 중 하나인 {{jsxref("Function.apply", "apply()")}} 메서드는 이러한 목표를 달성하기 위해 사용될 수 있습니다.

- -

함수의 범위

- -

함수 내에서 정의된 변수는 변수가 함수의 범위에서만 정의되어 있기 때문에, 함수 외부의 어느 곳에서든 액세스할 수 없습니다. 그러나, 함수가 정의된 범위 내에서 정의된 모든 변수나 함수는 액세스할 수 있습니다. 즉, 전역함수는 모든 전역 변수를 액세스할 수 있습니다. 다른 함수 내에서 정의 된 함수는 부모 함수와 부모 함수가 액세스 할 수 있는 다른 변수에 정의된 모든 변수를 액세스할 수 있습니다.

- -
// The following variables are defined in the global scope
-var num1 = 20,
-    num2 = 3,
-    name = "Chamahk";
-
-// This function is defined in the global scope
-function multiply() {
-  return num1 * num2;
-}
-
-multiply(); // Returns 60
-
-// A nested function example
-function getScore () {
-  var num1 = 2,
-      num2 = 3;
-
-  function add() {
-    return name + " scored " + (num1 + num2);
-  }
-
-  return add();
-}
-
-getScore(); // Returns "Chamahk scored 5"
-
- -

범위와 함수 스택

- -

재귀

- -

함수는 자신을 참조하고 호출할 수 있습니다. 함수가 자신을 참조하는 방법은 세 가지가 있습니다.

- -
    -
  1. 함수의 이름
  2. -
  3. arguments.callee
  4. -
  5. 함수를 참조하는 범위 내 변수
  6. -
- -

예를 들어, 다음 함수의 정의를 고려해보세요.

- -
var foo = function bar() {
-   // statements go here
-};
-
- -

함수 본문 내에서 다음은 모두 동일합니다.

- -
    -
  1. bar()
  2. -
  3. arguments.callee()
  4. -
  5. foo()
  6. -
- -

자신을 호출하는 함수를 재귀 함수라고 합니다. 어떤 면에서, 재귀는 루프와 유사합니다. 둘 다 동일한 코드를 여러 번 실행하고, 조건(무한 루프를 방지하거나, 이 경우에는 오히려 무한 재귀하는)을 요구합니다. 예를 들어, 다음 루프는:

- -
var x = 0;
-while (x < 10) { // "x < 10" is the loop condition
-   // do stuff
-   x++;
-}
-
- -

아래와 같이 재귀 함수와 그 함수에 대한 호출로 변환될 수 있습니다.

- -
function loop(x) {
-  if (x >= 10) // "x >= 10" 는 탈출 조건 ("!(x < 10)"와 동등)
-    return;
-  // do stuff
-  loop(x + 1); // the recursive call
-}
-loop(0);
-
- -

그러나 일부 알고리즘은 단순 재귀 루프로 변환할 수 없습니다. 예를 들어, 트리 구조(가령, DOM)의 모든 노드를 얻는 것은 재귀를 사용하여 보다 쉽게 할 수 있습니다:

- -
function walkTree(node) {
-  if (node == null) //
-    return;
-  // do something with node
-  for (var i = 0; i < node.childNodes.length; i++) {
-    walkTree(node.childNodes[i]);
-  }
-}
-
- -

함수  loop 와 비교하여, 각 재귀 호출 자체는 여기에 많은 재귀 호출을 만듭니다.

- -

재귀적 알고리즘은 비 재귀적인 알고리즘으로 변환 할 수 있습니다. 그러나 변환된 알고리즘이 훨씬 더 복잡하며 그렇게 함으로써 스택의 사용을 요구합니다. 사실, 재귀 자체가 함수 스택을 사용 합니다.

- -

스택형 동작은 다음의 예에서 볼 수 있습니다:

- -
function foo(i) {
-  if (i < 0)
-    return;
-  console.log('begin:' + i);
-  foo(i - 1);
-  console.log('end:' + i);
-}
-foo(3);
-
-// Output:
-
-// begin:3
-// begin:2
-// begin:1
-// begin:0
-// end:0
-// end:1
-// end:2
-// end:3
- -

중첩된 함수와 클로저

- -

여러분은 함수 내에 함수를 끼워 넣을 수 있습니다. 중첩 된 (내부) 함수는 그것을 포함하는 (외부) 함수와 별개입니다. 그것은 또한 클로저를 형성합니다. 클로저는 그 변수(“폐쇄”라는 표현)를 결합하는 환경을 자유롭게 변수와 함께 가질 수 있는 표현(전형적인 함수)입니다.

- -

중첩 함수는 클로저이므로, 중첩된 함수는 그것을 포함하는 함수의 인수와 변수를 “상속”할 수 있는 것을 의미합니다. 즉, 내부 함수는 외부 함수의 범위를 포함합니다.

- -

요약하면:

- -
    -
  • 내부 함수는 외부 함수의 명령문에서만 액세스할 수 있습니다.
  • -
- -
    -
  • 내부 함수는 클로저를 형성합니다: 외부 함수는 내부 함수의 인수와 변수를 사용할 수 없는 반면에, 내부 함수는 외부 함수의 인수와 변수를 사용할 수 있습니다.
  • -
- -

다음 예는 중첩된 함수를 보여줍니다:

- -
function addSquares(a,b) {
-  function square(x) {
-    return x * x;
-  }
-  return square(a) + square(b);
-}
-a = addSquares(2,3); // returns 13
-b = addSquares(3,4); // returns 25
-c = addSquares(4,5); // returns 41
-
- -

내부 함수는 클로저를 형성하기 때문에, 여러분은 외부 함수를 호출하고, 외부 및 내부 함수 모두에 인수를 지정할 수 있습니다.

- -
function outside(x) {
-  function inside(y) {
-    return x + y;
-  }
-  return inside;
-}
-fn_inside = outside(3); // Think of it like: give me a function that adds 3 to whatever you give it
-result = fn_inside(5); // returns 8
-
-result1 = outside(3)(5); // returns 8
-
- -

변수의 보존

- -

중첩된 내부 함수가 반환될 때 외부 함수의 인수 x가 보존된다는 점을 알 수 있습니다. 클로저는 그것을 참조하는 모든 범위에서 인수와 변수를 보존해두어야 합니다. 매번 호출될 때마다 잠재적으로 다른 인수를 제공할 수 있기 때문에, 클로저는 외부 함수에 대하여 매번 새로 생성됩니다. 메모리는 그 무엇도 내부 함수에 접근하지 않을 때만 해제됩니다.

- -

변수의 보존은 일반 객체에서 참조를 저장해두는 것과 다르지 않지만, 사용자가 직접 참조를 설정하는 것이 아니고 자세히 들여다볼 수 없어서 종종 명확하지 않습니다.

- -

다중 중첩 함수

- -

함수는 다중 중첩될 수 있습니다. 즉, 함수 (C)를 포함하는 함수 (B)를 포함하는 함수 (A). 여기에서 두 함수 B와 C는 모두 클로저를 형성합니다. 그래서 B는 A를 엑세스할 수 있고, C는 B를 액세스 할 수 있습니다. 이와 같이, 클로저는 다중 범위를 포함 할 수 있습니다; 그들은 재귀적으로 그것을 포함하는 함수의 범위를 포함합니다. 이것을 범위 체이닝이라 합니다.(그것을 “체이닝”이라 하는 이유는 추후에 설명할 것입니다.)

- -

다음 예를 살펴 보겠습니다:

- -
function A(x) {
-  function B(y) {
-    function C(z) {
-      console.log(x + y + z);
-    }
-    C(3);
-  }
-  B(2);
-}
-A(1); // logs 6 (1 + 2 + 3)
-
- -

이 예에서, C는 B의 y와 A의 x를 엑세스 합니다. 이 때문에 수행할 수 있습니다:

- -
    -
  1. B는 A를 포함하는 클로저를 형성합니다. 즉, B는 A의 인수와 변수를 엑세스할 수 있습니다.
  2. -
  3. C는 B를 포함하는 클로저를 형성합니다.
  4. -
  5. B의 클로저는 A를 포함하고, C의 클로저는 A를 포함하기 때문에, C는 B와 A의 인수와 변수를 엑세스할 수 있습니다. 즉, 순서대로 C는 A와 B의 범위를 체이닝합니다.
  6. -
- -

그러나 역은 사실이 아닙니다. A는 C에 접근 할 수 없습니다. 왜냐하면 A는 B의 인수와 변수(C는 B변수)에 접근할수 없기 때문입니다. 그래서 C는 B에게만 사적으로 남게됩니다.

- -

이름 충돌

- -

클로저의 범위에서 두 개의 인수 또는 변수의 이름이 같은 경우, 이름 충돌이 있습니다. 더 안쪽 범위가 우선순위를 갖습니다. 그래서 가장 바깥 범위는 우선순위가 가장 낮은 반면에, 가장 안쪽 범위는 가장 높은 우선순위를 갖습니다. 이것이 범위 체인(scope chaini)입니다. 체인에서 첫번째는 가장 안쪽 범위이고, 마지막 가장 바깥 쪽의 범위입니다. 다음 사항을 고려하세요:

- -
function outside() {
-  var x = 10;
-  function inside(x) {
-    return x;
-  }
-  return inside;
-}
-result = outside()(20); // returns 20 instead of 10
-
- -

이름 충돌이 x를 반환하는 문과 내부의 매개 변수 x와 외부 변수 x 사이에서 발생합니다. 여기에서 범위 체이닝은 {내부, 외부, 전역 객체}입니다. 따라서 내부의 x는 외부의 x보다 높은 우선순위를 갖게 되고, 20(내부의 x)이 10(외부의 x) 대신에 반환됩니다.

- -

클로저

- -

클로저는 자바스크립트의 강력한 기능 중 하나입니다. 자바스크립트는 함수의 중첩(함수 안에 함수를 정의하는것)을 허용하고, 내부함수가 외부 함수 안에서 정의된 모든 변수와 함수들을 완전하게 접근 할 수 있도록 승인해줍니다.(그리고 외부함수가 접근할수 있는 모든 다른 변수와 함수들까지) 그러나 외부 함수는 내부 함수 안에서 정의된 변수와 함수들에 접근 할 수 없습니다. 이는 내부 함수의 변수에 대한 일종의 캡슐화를 제공합니다. 또한, 내부함수는 외부함수의 범위에 접근할 수 있기 때문에, 내부 함수가 외부 함수의 수명을 초과하여 생존하는 경우, 외부함수에서 선언된 변수나 함수는 외부함수의 실행 기간보다 오래갑니다. 클로저는 내부 함수가 어떻게든 외부 함수 범위 밖의 모든 범위에서 사용 가능해지면 생성됩니다.

- -
var pet = function(name) {   // 외부 함수는 'name'이라 불리는 변수를 정의합니다.
-  var getName = function() {
-    return name;             // 내부 함수는 외부 함수의 'name' 변수에 접근합니다.
-  }
-  return getName;            // 내부 함수를 리턴함으로써, 외부 범위에 노출됩니다.
-},
-myPet = pet("Vivie");
-
-myPet();                     // "Vivie"로 리턴합니다.
-
- -

클로저는 위 코드보다 더 복잡해 질 수도 있습니다. 외부 함수의 내부 변수를 다루는 메서드를 포함한 객체도 반환될 수도 있습니다.

- -
var createPet = function(name) {
-  var sex;
-
-  return {
-    setName: function(newName) {
-      name = newName;
-    },
-
-    getName: function() {
-      return name;
-    },
-
-    getSex: function() {
-      return sex;
-    },
-
-    setSex: function(newSex) {
-      if(typeof newSex == "string" && (newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
-        sex = newSex;
-      }
-    }
-  }
-}
-
-var pet = createPet("Vivie");
-pet.getName();                  // Vivie
-
-pet.setName("Oliver");
-pet.setSex("male");
-pet.getSex();                   // male
-pet.getName();                  // Oliver
-
- -

위 코드에서, 외부 함수의 'name' 이란 변수는 내부 함수에서 접근이 가능합니다. 그리고 그 내장 함수를 통하는 방법 말고는 내부 변수로 접근할 수 없습니다. 내부 함수의 내부 변수는 외부 인수와 변수를 안전하게 저장합니다. 내부 변수는 내부 함수가 작동하기 위해 '지속적'이고 '갭슐화된' 데이터를 보유합니다. 함수는 변수로 할당되거나, 이름을 가질 필요가 없습니다.

- -
var getCode = (function(){
-  var secureCode = "0]Eal(eh&2";    // A code we do not want outsiders to be able to modify...
-
-  return function () {
-    return secureCode;
-  };
-})();
-
-getCode();    // Returns the secureCode
-
- -

그러나 클로저를 쓰면서 조심해야 할 위험이 많이 있습니다. 만약 내부 함수가 외부 함수의 범위에 있는 이름과 같은 변수를 정의하였을 경우, 다시는 외부 함수 범위의 변수를 참조(접근)할 방법이 없습니다.

- -
var createPet = function(name) {  // 외부 함수가 "name" 이라는 변수를 정의하였다
-  return {
-    setName: function(name) {    // 내부 함수 또한 "name" 이라는 변수를 정의하였다
-      name = name;               // ??? 어떻게 우리는 외부 함수에 정의된 "name"에 접근할까???
-    }
-  }
-}
-
- -

인수(arguments) 객체 사용하기

- -

함수의 인수는 배열과 비슷한 객체로 처리가 됩니다. 함수 내에서는, 전달 된 인수를 다음과 같이 다룰 수 있습니다. :

- -
arguments[i]
-
- -

i 는 0 으로 시작하는 순서 번호입니다. 따라서 함수에 전달된 첫 번째 인수는 arguments[0] 입니다. 총 인수의 개수는 arguments.length 에서 얻을 수 있습니다.

- -

인수(arguments) 객체를 이용하면, 보통 함수에 정의된 개수보다 많은 인수를 넘겨주면서 함수를 호출할 수 있습니다. 이것은 얼마나 많은 인수가 함수로 넘겨질지 모르는 상황에서 유용합니다. arguments.length를 함수에 실제로 넘겨받은 인수의 수를 알아낼 때 사용할 수 있고 , 각각의 인수에 인수(arguments) 객체를  이용하여 접근 할 수 있습니다.

- -

예를 들어, 몇 개의 문자열을 연결하는 함수를 생각해 봅시다. 이 함수의 유일한 형식 인수는 각 문자열을 구분해주는 문자를 나타내는 문자열입니다 . 이 함수는 다음과 같이 정의됩니다:

- -
function myConcat(separator) {
-   var result = ""; // 리스트를 초기화한다
-   var i;
-   // arguments를 이용하여 반복한다
-   for (i = 1; i < arguments.length; i++) {
-      result += arguments[i] + separator;
-   }
-   return result;
-}
-
- -

어떤 개수의 인수도 이 함수로 넘겨줄 수 있고, 이 함수는 각각의 인수를 하나의 문자열 "리스트" 로 연결합니다. :

- -
// returns "red, orange, blue, "
-myConcat(", ", "red", "orange", "blue");
-
-// returns "elephant; giraffe; lion; cheetah; "
-myConcat("; ", "elephant", "giraffe", "lion", "cheetah");
-
-// returns "sage. basil. oregano. pepper. parsley. "
-myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");
-
- -
-

Note: 인수(arguments) 객체는 배열과 닮은 것이지 배열이 아닙니다. 인수(arguments) 객체는 번호 붙여진 인덱스와 길이 속성을 가지고 있다는 점에서 배열과 닮은 것입니다. 인수(arguments) 객체는 배열을 다루는 모든 메서드를 가지고 있지 않습니다.

-
- -

더 자세한 정보를 얻고 싶으면 자바스크립트 참조문의 {{jsxref("Function")}}객체에 대하여 보세요.

- -

함수의 매개변수

- -

 ECMAScript 2015와 함께 시작된,두 종류의 매개변수가 있습니다 : 디폴트 매개변수 , 나머지 매개변수.

- -

디폴트 매개변수

- -

자바스크립트에서, 함수의 매개변수는 undefined 가 기본으로 설정됩니다. 그러나, 어떤 상황에서는 다른 값을 기본값으로 가진 것이 유용할 때가 있습니다. 이때가 디폴트 매개변수가 도움을 줄 수 있는 상황입니다.

- -

옛날엔, 기본값을 설정하는 보편적인 전략은 함수의 본문에서 매개변수 값을 테스트하여 그 값이 undefined 인 경우에 값을 할당하는 것이었습니다. 다음과 같은 예제에서, 함수호출 시 b 매개변수에 아무 값을 주지 않으면, a*b 계산 시 b 매개변수의 값은 undefined 일 것이므로 multiply 함수 호출은 NaN을 리턴할 것입니다. 그러나 이런 것은 이 예제의 2번째 줄에서 걸립니다:

- -
function multiply(a, b) {
-  b = typeof b !== 'undefined' ?  b : 1;
-
-  return a*b;
-}
-
-multiply(5); // 5
-
- -

디폴트 매개변수와 함께라면, 함수 본문에서 검사하는 부분은 필요가 없습니다. 이제 , 함수 머리에서 b 의 기본값에 간단히 1을 넣어주면 됩니다:

- -
function multiply(a, b = 1) {
-  return a*b;
-}
-
-multiply(5); // 5
- -

더 자세한 내용을 보고 싶으시면,  default parameters 문서를 참조하세요.

- -

나머지 매개변수

- -

 나머지 매개변수 구문을 사용하면 배열로 불확실한 개수의 인수를 나타낼 수 있습니다. 이 예제에서, 우리는 나머지 매개변수를 2번째 인수부터 마지막 인수까지 얻기 위하여 사용하였습니다. 그리고 우리는 첫번째 값으로 나머지 매개변수에 곱하였습니다. 이 예제는 다음 섹션에서 소개할  화살표(arrow) 함수 입니다.

- -
function multiply(multiplier, ...theArgs) {
-  return theArgs.map(x => multiplier * x);
-}
-
-var arr = multiply(2, 1, 2, 3);
-console.log(arr); // [2, 4, 6]
- -

화살표 함수

- -

 화살표 함수 표현 (뚱뚱한 화살표(fat arrow) 함수라고 알려진)은 함수 표현과 비교하였을때 짧은 문법을 가지고 있고 사전적으로 this 값을 묶습니다. 화살표 함수는 언제나 익명입니다. hacks.mozilla.org 블로그 포스트 "ES6 In Depth: Arrow functions" 를 참조하세요.

- -

화살표  함수 소개에 영향을 주는 두 요소: 더 짧은 함수와 바인딩 되지않은 this.

- -

더 짧은 함수

- -

어떤 함수적 패턴에서는, 더 짧은 함수가 환영받습니다. 다음을 비교해 보세요:

- -
var a = [
-  "Hydrogen",
-  "Helium",
-  "Lithium",
-  "Beryl­lium"
-];
-
-var a2 = a.map(function(s){ return s.length });
-
-console.log(a2); // logs [8, 6, 7, 9]
-
-var a3 = a.map( s => s.length );
-
-console.log(a3); // logs [8, 6, 7, 9]
- -

사전적 this

- -

화살표 함수에서, 모든 new함수들은  그들의  this 값을 정의합니다 (생성자로서의 새로운 객체, 정의되지 않은 strict mode의 함수 호출,   함수가 "object method"로 호출했을때의 context object ,등등.). 이런 것은 객체지향 프로그래밍 스타일에서 짜증을 불러 일으킵니다.

- -
function Person() {
-  // The Person() constructor defines `this` as itself.
-  this.age = 0;
-
-  setInterval(function growUp() {
-    // In nonstrict mode, the growUp() function defines `this`
-    // as the global object, which is different from the `this`
-    // defined by the Person() constructor.
-    this.age++;
-  }, 1000);
-}
-
-var p = new Person();
- -

IECMAScript 3/5 에서는, 이 문제는 this 안의 값을 뒤덮을 수 있는변수에 할당하면서 고쳐졌습니다.

- -
function Person() {
-  var self = this; // Some choose `that` instead of `self`.
-                   // Choose one and be consistent.
-  self.age = 0;
-
-  setInterval(function growUp() {
-    // The callback refers to the `self` variable of which
-    // the value is the expected object.
-    self.age++;
-  }, 1000);
-}
- -

또는, 적절한 this 값이 growUp() 함수에 전달되도록, 바인딩된 함수가 생성될 수 있습니다.

- - - -

화살표 함수에는 this;가 없습니다. 화살표 함수를 포함하는 객체 값이 사용됩니다. 따라서 다음 코드에서 setInterval에 전달 된 함수 내의 this 값은 화살표 함수를 둘러싼 함수의 this와 같은 값을 갖습니다.

- -
function Person() {
-  this.age = 0;
-
-  setInterval(() => {
-    this.age++; // |this| properly refers to the person object
-  }, 1000);
-}
-
-var p = new Person();
- -

미리 정의된 함수들

- -

자바스크립트에는 최고 등급의 몇가지 내장함수가 있습니다:

- -
-
{{jsxref("Global_Objects/eval", "eval()")}}
-
-

eval() 메소드는 문자열로 표현된 자바스크립트 코드를 수행합니다.

-
-
{{jsxref("Global_Objects/uneval", "uneval()")}} {{non-standard_inline}}
-
-

uneval() 메소드는  {{jsxref("Object")}}의 소스코드를 표현하는 문자열을 만듭니다.

-
-
{{jsxref("Global_Objects/isFinite", "isFinite()")}}
-
-

전역 isFinite() 함수는 전달받은 값이 유한한지 결정합니다. 만약 필요하다면, 매개변수는 첫번째로 숫자로 변환됩니다.

-
-
{{jsxref("Global_Objects/isNaN", "isNaN()")}}
-
-

isNaN() 함수는 {{jsxref("Global_Objects/NaN", "NaN")}}인지 아닌지 결정합니다. Note:  isNaN 함수 안의 강제 변환은  흥미로운 규칙을 가지고 있습니다;  {{jsxref("Number.isNaN()")}}을 대신 사용하고 싶을것입니다, ECMAScript 6 에서 정의된,또는 값이 숫자값이 아닐때,  typeof 를 사용할 수도 있습니다 .

-
-
{{jsxref("Global_Objects/parseFloat", "parseFloat()")}}
-
-

parseFloat() 함수는  문자열 인수 값을 해석하여 부동소숫점 수를 반환합니다.

-
-
{{jsxref("Global_Objects/parseInt", "parseInt()")}}
-
-

parseInt() 함수는 문자열 인수 값을 해석하여 특정한 진법의 정수를 반환합니다  (수학적 수 체계를 기반으로 해서).

-
-
{{jsxref("Global_Objects/decodeURI", "decodeURI()")}}
-
-

decodeURI() 함수는  사전에 {{jsxref("Global_Objects/encodeURI", "encodeURI")}}을 통해 만들어지거나 비슷한 과정을 통해 만들어진 URI(Uniform Resource Identifier)  를 해독합니다.

-
-
{{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent()")}}
-
-

decodeURIComponent() 메소드는 사전에{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}}를 통하여 만들어 지거나 또는 비슷한 과정을 통해 만들어진 URI (Uniform Resource Identifier) 컴포넌트를 해독합니다.

-
-
{{jsxref("Global_Objects/encodeURI", "encodeURI()")}}
-
-

encodeURI() 메소드는  URI(Uniform Resource Identifier)를  각 인스턴스의 특정한 문자를 한개, 두개,세개, 또는 네개의 UTF-8인코딩으로 나타내어지는 연속된 확장문자들과 바꾸는 방법으로 부호화 합니다 .(두"surrogate"문자로 구성된 문자들은 오직 네개의 연속된 확장문자 입니다. ).

-
-
{{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent()")}}
-
-

encodeURIComponent() 메소드는  URI(Uniform Resource Identifier) 컴포넌트를  각 인스턴스의 특정한 문자를 한개, 두개,세개, 또는 네개의 UTF-8인코딩으로 나타내어지는 연속된 확장문자들과 바꾸는 방법으로 부호화 합니다 .(두"surrogate"문자로 구성된 문자들은 오직 네개의 연속된 확장문자 입니다. ).).

-
-
{{jsxref("Global_Objects/escape", "escape()")}} {{deprecated_inline}}
-
-

곧 사라질 escape() 메소드는 한 문자열에서 특정 문자들이 16진 확장 비트열로 바뀌어진 문자열로 계산합니다.  {{jsxref("Global_Objects/encodeURI", "encodeURI")}} 또는 {{jsxref("Global_Objects/encodeURIComponent", "encodeURIComponent")}} 를 사용하세요.

-
-
{{jsxref("Global_Objects/unescape", "unescape()")}} {{deprecated_inline}}
-
-

곧 사라질 unescape() 메소드는 문자열에서 확장 비트열이 확장 비트열이 나타내는 문자로 바뀌어진 문자열로 계산합니다.  {{jsxref("Global_Objects/escape", "escape")}}에서 확장 비트열이 소개될 것입니다.  unescape() 메소드가 곧 사라지기 때문에,  {{jsxref("Global_Objects/decodeURI", "decodeURI()")}} or {{jsxref("Global_Objects/decodeURIComponent", "decodeURIComponent")}} 를 대신 사용하세요.

-
-
- -

{{PreviousNext("Web/JavaScript/Guide/Loops_and_iteration", "Web/JavaScript/Guide/Expressions_and_Operators")}}

- - - - diff --git a/files/ko/web/javascript/inheritance_and_the_prototype_chain/index.html b/files/ko/web/javascript/inheritance_and_the_prototype_chain/index.html new file mode 100644 index 0000000000..e05bab3102 --- /dev/null +++ b/files/ko/web/javascript/inheritance_and_the_prototype_chain/index.html @@ -0,0 +1,531 @@ +--- +title: 상속과 프로토타입 +slug: Web/JavaScript/Guide/Inheritance_and_the_prototype_chain +tags: + - JavaScript + - 객체지향 + - 상속 + - 중급 +translation_of: Web/JavaScript/Inheritance_and_the_prototype_chain +--- +

{{jsSidebar("Advanced")}}

+ +

Java 나 C++ 같이 클래스 기반의 언어를 사용하던 프로그래머는 자바스크립트가 동적인 언어라는 점과 클래스가 없다는 것에서 혼란스러워 한다. (ES2015부터 class 키워드를 지원하기 시작했으나, 문법적인 양념일 뿐이며 자바스크립트는 여전히 프로토타입 기반의 언어다.)

+ +

상속 관점에서 자바스크립트의 유일한 생성자는 객체뿐이다. 각각의 객체는 [[Prototype]]이라는 은닉(private) 속성을 가지는데 자신의 프로토타입이 되는 다른 객체를 가리킨다. 그 객체의 프로토타입 또한 프로토타입을 가지고 있고 이것이 반복되다, 결국 null을 프로토타입으로 가지는 오브젝트에서 끝난다. null은 더 이상의 프로토타입이 없다고 정의되며, 프로토타입 체인의 종점 역할을 한다.

+ +

종종 이러한 점이 자바스크립트의 약점이라고 지적되지만, 프로토타입적 상속 모델은 사실 고전적인 방법보다 좀 더 강력한 방법이다. 그 말은, 예를 들자면, 프로토타입적 모델에서 고전적인 방식을 구현하는 건 꽤나 사소한 일이지만, 그 반대는 훨씬 더 어려운 일이기 때문이다.

+ +

프로토타입 체인을 이용한 상속

+ +

속성 상속

+ +

자바스크립트 객체는 속성을 저장하는 동적인 "가방"과 (자기만의 속성이라고 부른다) 프로토타입 객체에 대한 링크를 가진다. 객체의 어떤 속성에 접근하려할 때 그 객체 자체 속성 뿐만 아니라 객체의 프로토타입, 그 프로토타입의 프로토타입 등 프로토타입 체인의 종단에 이를 때까지 그 속성을 탐색한다.

+ +
ECMAScript 표준은 someObject.[[Prototype]]을 객체 someObject의 프로토타입을 지시하도록 명시하였다. ECMAScript 2015부터 [[Prototype]]에 조상 {{jsxref("Object.getPrototypeOf()")}}과 {{jsxref("Object.setPrototypeOf()")}}을 이용하여 접근하기 때문이다. 이것은 자바스크립트의 표준은 아니나 많은 브라우저에 구현되어 사실상의 표준이 된 속성 __proto__과 동일하다.
+ +

아래 코드에는 어떤 속성에 접근 하려할 때 일어나는 상황이다.

+ +
// o라는 객체가 있고, 속성 'a' 와 'b'를 갖고 있다고 하자.
+let f = function () {
+    this.a = 1;
+    this.b = 2;
+}
+let o = new f(); // {a: 1, b: 2}
+
+// f 함수의 prototype 속성 값들을 추가 하자.
+f.prototype.b = 3;
+f.prototype.c = 4;
+
+// f.prototype = {b: 3, c: 4}; 라고 하지 마라, 해당 코드는 prototype chain 을 망가뜨린다.
+// o.[[Prototype]]은 속성 'b'와 'c'를 가지고 있다.
+// o.[[Prototype]].[[Prototype]] 은 Object.prototype 이다.
+// 마지막으로 o.[[Prototype]].[[Prototype]].[[Prototype]]은 null이다.
+// null은 프로토타입의 종단을 말하며 정의에 의해서 추가 [[Prototype]]은 없다.
+// {a: 1, b: 2} ---> {b: 3, c: 4} ---> Object.prototype ---> null
+
+console.log(o.a); // 1
+// o는 'a'라는 속성을 가지는가? 그렇다. 속성의 값은 1이다.
+
+console.log(o.b); // 2
+// o는 'b'라는 속성을 가지는가? 그렇다. 속성의 값은 2이다.
+// 프로토타입 역시 'b'라는 속성을 가지지만 이 값은 쓰이지 않는다. 이것을 "속성의 가려짐(property shadowing)" 이라고 부른다.
+
+console.log(o.c); // 4
+// o는 'c'라는 속성을 가지는가? 아니다. 프로토타입을 확인해보자.
+// o.[[Prototype]]은 'c'라는 속성을 가지는가? 가지고 값은 4이다.
+
+console.log(o.d); // undefined
+// o는 'd'라는 속성을 가지는가? 아니다. 프로토타입을 확인해보자.
+// o.[[Prototype]]은 'd'라는 속성을 가지는가? 아니다. 다시 프로토타입을 확인해보자.
+// o.[[Prototype]].[[Prototype]]은 null이다. 찾는 것을 그만두자.
+// 속성이 발견되지 않았기 때문에 undefined를 반환한다.
+
+ +

객체의 속성에 값을 지정하면 "자기만의 속성"이 생긴다.  단, getter or a setter가 적용되는 속성이 상속되는 경우 예외적인 규칙이 적용된다.

+ +

메소드 상속

+ +

자바스크립트에 "메소드"라는건 없다. 하지만 자바스크립트는 객체의 속성으로 함수를 지정할 수 있고 속성 값을 사용하듯 쓸 수 있다. 속성 값으로 지정한 함수의 상속 역시 위에서 본 속성의 상속과 동일하다. (단 위에서 언급한 "속성의 가려짐" 대신 "메소드 오버라이딩, method overriding" 라는 용어를 사용한다)

+ +

상속된 함수가 실행 될 때,  this 라는 변수는 상속된 오브젝트를 가르킨다. 그 함수가 프로토타입의 속성으로 지정되었다고 해도 말이다.

+ +
var o = {
+  a: 2,
+  m: function(b){
+    return this.a + 1;
+  }
+};
+
+console.log(o.m()); // 3
+// o.m을 호출하면 'this' 는 o를 가리킨다.
+
+var p = Object.create(o);
+// p 는 프로토타입을 o로 가지는 오브젝트이다.
+
+p.a = 12; // p 에 'a'라는 새로운 속성을 만들었다.
+console.log(p.m()); // 13
+// p.m이 호출 될 때 'this' 는 'p'를 가리킨다.
+// 따라서 o의 함수 m을 상속 받으며,
+// 'this.a'는 p.a를 나타내며 p의 개인 속성 'a'가 된다.
+
+ +

Javascript 에서 프로토타입을 사용하는 방법

+ +

뒤에서 일어나는 일을 좀 더 자세히 파헤쳐보자.

+ +

위에서 언급했듯이, 자바스크립트에서 함수는 속성을 가질 수 있다. 모든 함수에는 prototype이라는 특수한 속성이 있다. 아래의 예제 코드는 독립적이라는 것에 유의하자. (아래의 코드 이외에는 웹페이지에 다른 자바스크립트가 없다고 가정하는 것이 좋다.)

+ +

최적의 실습을 위해서 콘솔을 열고 "Console" 탭으로 이동하여 아래의 JavaScript 코드를 복사하여 붙여넣은 다음 , 엔터키를 눌러 실행할 것을 적극 권한다. (콘솔은 대부분 웹 브라우저의 Developer Tools에 포함되어있다. 자세한 내용은 Firefox Developer ToolsChrome DevTools, Edge DevTools 에서 확인할 수 있다. )

+ +
+ +
function doSomething(){}
+console.log( doSomething.prototype );
+// It does not matter how you declare the function, a
+//  function in JavaScript will always have a default
+//  prototype property.
+var doSomething = function(){};
+console.log( doSomething.prototype );
+ +

위 내용을 토대로, 콘솔을 보면  doSomething() 은 기본 prototype 속성을 가진다. 코드를 실행한 뒤에 콘솔에서는 다음과 유사한 형태의 객체가 표시되어야한다.

+ +
{
+    constructor: ƒ doSomething(),
+    __proto__: {
+        constructor: ƒ Object(),
+        hasOwnProperty: ƒ hasOwnProperty(),
+        isPrototypeOf: ƒ isPrototypeOf(),
+        propertyIsEnumerable: ƒ propertyIsEnumerable(),
+        toLocaleString: ƒ toLocaleString(),
+        toString: ƒ toString(),
+        valueOf: ƒ valueOf()
+    }
+}
+ +

우리는 아래에 보이는 것과 같이 doSomething() 프로토타입에 속성을 추가할 수 있다.

+ +
function doSomething(){}
+doSomething.prototype.foo = "bar";
+console.log( doSomething.prototype );
+ +

결과:

+ +
{
+    foo: "bar",
+    constructor: ƒ doSomething(),
+    __proto__: {
+        constructor: ƒ Object(),
+        hasOwnProperty: ƒ hasOwnProperty(),
+        isPrototypeOf: ƒ isPrototypeOf(),
+        propertyIsEnumerable: ƒ propertyIsEnumerable(),
+        toLocaleString: ƒ toLocaleString(),
+        toString: ƒ toString(),
+        valueOf: ƒ valueOf()
+    }
+}
+
+ +

이제 new 연산자를 사용해서 프로토타입 기반의 doSomething() 인스턴스를 생성할 수 있다. new 연산자를 사용하려면 함수 호출 형식에 new 접두사를 붙이기만하면 된다. new 연산자로 함수를 호출하면 해당 함수의 인스턴스 객체를 반환받는다. 그러면 속성들을 이 객체에 추가할 수 있다.

+ +

다음의 코드를 실행해보자.

+ +
function doSomething(){}
+doSomething.prototype.foo = "bar"; // add a property onto the prototype
+var doSomeInstancing = new doSomething();
+doSomeInstancing.prop = "some value"; // add a property onto the object
+console.log( doSomeInstancing );
+ +

실행하고나면 결과는 다음과 비슷할 것이다.

+ +
{
+    prop: "some value",
+    __proto__: {
+        foo: "bar",
+        constructor: ƒ doSomething(),
+        __proto__: {
+            constructor: ƒ Object(),
+            hasOwnProperty: ƒ hasOwnProperty(),
+            isPrototypeOf: ƒ isPrototypeOf(),
+            propertyIsEnumerable: ƒ propertyIsEnumerable(),
+            toLocaleString: ƒ toLocaleString(),
+            toString: ƒ toString(),
+            valueOf: ƒ valueOf()
+        }
+    }
+}
+
+ +

위에서 본 것과 같이, doSomeInstancing 객체의 __proto__ 는 doSomething.prototype 이다.
+ 그래서 도대체 __proto__는 무엇을 하는것인지 알아보자.
+ 우리가 doSomeInstancing의 속성에 접근할때 브라우저는 우선 doSomeInstancing이 그 속성을 갖고있는지 확인한다.
+ 만약 doSomeInstancing이 속성을 갖고있지 않다면, 브라우저는 doSomeInstancing의 __proto__(doSomething.prototype)가 그 속성을 갖고있는지 확인한다.
+ 만약 doSomeInstancing의 __proto__가 브라우저가 찾던 속성을 갖고 있다면, doSomething의 __proto__가 갖고있는 그 속성을 사용한다.

+ +

그렇지 않고, doSomeInstancing의 __proto__가 그 속성을 갖고있지 않을때에는
+ doSomeInstancing의 __proto__의 __proto__가 그 속성을 갖는지 확인한다.
+ 기본적으로, 어떠한 함수던지 그 함수의 prototype 속성의 __proto__는 window.Object.prototype이다.
+ 그러므로 브라우저는 doSomeInstancing의 __proto__의 __proto__(doSomething.prototype의 __proto__(다시말해, Object.prototype))  에서 그 속성을 찾아본다.
+ 만약 그 속성을 doSomeInstancing의 __proto__의 __proto__에서 찾을 수 없다면 그다음엔 doSomeInstancing의 __proto__의 __proto__의 __proto__에서 찾을것이다.
+ 하지만 여기서 문제가 발생한다.
+ doSomeInstancing의 __proto__의 __proto__의 __proto__는 존재할 수 없다(window.Object.prototype의 __proto__는 null이기 때문).
+ 그제서야, 오직 모든 프로토타입 체인이 검사 되고 브라우저가 더이상  검사할 __proto__가 없을때에서야 브라우저는 우리가 찾던 값이 undefined라고 결론짓는다.

+ +

콘솔에 코드를 조금 더 추가해보자.

+ +
function doSomething(){}
+doSomething.prototype.foo = "bar";
+var doSomeInstancing = new doSomething();
+doSomeInstancing.prop = "some value";
+console.log("doSomeInstancing.prop:      " + doSomeInstancing.prop);
+console.log("doSomeInstancing.foo:       " + doSomeInstancing.foo);
+console.log("doSomething.prop:           " + doSomething.prop);
+console.log("doSomething.foo:            " + doSomething.foo);
+console.log("doSomething.prototype.prop: " + doSomething.prototype.prop);
+console.log("doSomething.prototype.foo:  " + doSomething.prototype.foo);
+
+ +

이 코드의 결과는 아래와 같다.

+ +
doSomeInstancing.prop:      some value
+doSomeInstancing.foo:       bar
+doSomething.prop:           undefined
+doSomething.foo:            undefined
+doSomething.prototype.prop: undefined
+doSomething.prototype.foo:  bar
+
+ +

객체를 생성하는 여러 방법과 프로토타입 체인 결과

+ +

문법 생성자로 객체 생성

+ +
var o = {a: 1};
+
+// o 객체는 프로토타입으로 Object.prototype 을 가진다.
+// 이로 인해 o.hasOwnProperty('a') 같은 코드를 사용할 수 있다.
+// hasOwnProperty 라는 속성은 Object.prototype 의 속성이다.
+// Object.prototype 의 프로토타입은 null 이다.
+// o ---> Object.prototype ---> null
+
+var a = ["yo", "whadup", "?"];
+
+// Array.prototype을 상속받은 배열도 마찬가지다.
+// (이번에는 indexOf, forEach 등의 메소드를 가진다)
+// 프로토타입 체인은 다음과 같다.
+// a ---> Array.prototype ---> Object.prototype ---> null
+
+function f(){
+  return 2;
+}
+
+// 함수는 Function.prototype 을 상속받는다.
+// (이 프로토타입은 call, bind 같은 메소드를 가진다)
+// f ---> Function.prototype ---> Object.prototype ---> null
+
+ +

생성자를 이용

+ +

자바스크립트에서 생성자는 단지 new 연산자를  사용해 함수를 호출하면 된다.

+ +
function Graph() {
+  this.vertexes = [];
+  this.edges = [];
+}
+
+Graph.prototype = {
+  addVertex: function(v){
+    this.vertexes.push(v);
+  }
+};
+
+var g = new Graph();
+// g 'vertexes' 와 'edges'를 속성으로 가지는 객체이다.
+// 생성시 g.[[Prototype]]은 Graph.prototype의 값과 같은 값을 가진다.
+
+ +

Object.create 이용

+ +

ECMAScript 5는 새로운 방법을 도입했다. Object.create라는 메소드를 호출하여 새로운 객체를 만들 수 있다. 생성된 객체의 프로토타입은 이 메소드의 첫 번째 인수로 지정된다.

+ +
var a = {a: 1};
+// a ---> Object.prototype ---> null
+
+var b = Object.create(a);
+// b ---> a ---> Object.prototype ---> null
+console.log(b.a); // 1 (상속됨)
+
+var c = Object.create(b);
+// c ---> b ---> a ---> Object.prototype ---> null
+
+var d = Object.create(null);
+// d ---> null
+console.log(d.hasOwnProperty); // undefined이다. 왜냐하면 d는 Object.prototype을 상속받지 않기 때문이다.
+
+ +
+

class 키워드 이용

+ +

ECMAScript2015에는 몇 가지 키워드가 도입되어 class를 구현하였다. 이런 생성 방식은 클래서 기반 언어의 개발자들에게 친숙하게 다가오나 동작 방식이 같지는 않다. 자바스크립트는 여전히 프로토타입 기반으로 남아있다. 새로 도입된 키워드는 {{jsxref("Statements/class", "class")}}, {{jsxref("Classes/constructor", "constructor")}}, {{jsxref("Classes/static", "static")}}, {{jsxref("Classes/extends", "extends")}}, 그리고 {{jsxref("Operators/super", "super")}}가 있다.

+ +
'use strict';
+
+class Polygon {
+  constructor(height, width) {
+    this.height = height;
+    this.width = width;
+  }
+}
+
+class Square extends Polygon {
+  constructor(sideLength) {
+    super(sideLength, sideLength);
+  }
+  get area() {
+    return this.height * this.width;
+  }
+  set sideLength(newLength) {
+    this.height = newLength;
+    this.width = newLength;
+  }
+}
+
+var square = new Square(2);
+
+ +

성능

+ +

프로토타입 체인에 걸친 속성 검색으로 성능에 나쁜 영향을 줄 수 있으며, 때때로 치명적일 수 있다. 또한 존재하지도 않는 속성에 접근하려는 시도는 항상 모든 프로토타입 체인인 전체를 탐색해서 확인하게 만든다.

+ +

객체의 속성에 걸쳐 루프를 수행 하는 경우 프로토타입 체인 전체의 모든 열거자 속성에 대하여 적용된다. 객체 개인 속성인지 프로토타입 체인상 어딘가에 있는지 확인하기 위해서는 Object.prototype에서 모든 오브젝트로 상속된 hasOwnProperty 메소드를 이용할 필요가 있다. 다음 코드를 통하여 구체적인 예를 확인하여 보자.

+ +
console.log(g.hasOwnProperty('vertices'));
+// true
+
+console.log(g.hasOwnProperty('nope'));
+// false
+
+console.log(g.hasOwnProperty('addVertex'));
+// false
+
+console.log(g.__proto__.hasOwnProperty('addVertex'));
+// true
+
+ +

hasOwnProperty 메소드만이 속성을 확인하고 프로토타입 체인 전체를 훑지 않게 할 수 있다.

+ +

참고: undefined인지 여부만 확인하는 것으로는 충분하지 않다. 여전히 속성이 존재할 수도 있는데 단지 그 값에 undefined가 할당되어 있을 수도 있기 때문이다.

+ +

좋지 않은 사례: 기본 프로타입의 확장 변형

+ +

Object.prototype 혹은 빌트인 프로토타입의 확장은 종종 이용되지만 오용이다.

+ +

이 기법은 Monkey patching으로 불리며 캡슐화를 망가뜨린다. Prototype.js와 같은 유명한 프레임워크에서도 사용되지만, 빌트인 타입에 비표준 기능을 추가하는 것은 좋은 생각이 아니다.

+ +

유일하게 좋은 사용 예라면, 새로운 자바스크립트 엔진에 Array.forEach등의 새로운 기능을 추가하면서 빌트인 프로토타입을 확장하는 것 정도다. 

+ +

+ +

B는 A를 상속한다:

+ +
function A(a) {
+  this.varA = a;
+}
+
+// A의 정의에서 this.varA는 항상 A.prototype.varA가 가려버리는데
+// prototype에 varA를 다시 넣는 이유는 무엇인가?
+A.prototype = {
+  varA: null,  // 아무것도 안하면서 varA를 쓰는 이유가 있을까?
+      // 아마도 숨겨진 클래스의 할당 구조를 최적화 하려는 것인가?
+      // https://developers.google.com/speed/articles/optimizing-javascript#Initializing-instance-variables
+      // 모든 객체의 varA가 동일하게 초기화 되어야 상기 링크 내용이 유효할 수 있다.
+  doSomething: function() {
+    // ...
+  }
+};
+
+function B(a, b) {
+  A.call(this, a);
+  this.varB = b;
+}
+B.prototype = Object.create(A.prototype, {
+  varB: {
+    value: null,
+    enumerable: true,
+    configurable: true,
+    writable: true
+  },
+  doSomething: {
+    value: function() { // override
+      A.prototype.doSomething.apply(this, arguments); // call super
+      // ...
+    },
+    enumerable: true,
+    configurable: true,
+    writable: true
+  }
+});
+B.prototype.constructor = B;
+
+var b = new B();
+b.doSomething();
+
+ +

중요한 점은:

+ +
    +
  • .prototype에 타입이 정의되어 있다.
  • +
  • Object.create()을 이용하여 상속한다.
  • +
+ +

prototype 그리고 Object.getPrototypeOf

+ +

Java나 C++에 익숙한 개발자는 클래스라는 것도 없고, 모든 것이 동적이고 실행 시 결정되는 자바스크립트의 특징 때문에 어려움을 겪을 수도 있다. 모든 것은 객체이고, 심지의 "class"를 흉내내는 방식도 단지 함수 오브젝트를 이용하는 것 뿐이다.

+ +

이미 알아챘겠지만 우리의 함수 A도 특별한 속성 prototype를 가지고 있다. 이 특별한 속성은 자바스크립트의 new 연산자와 함께 쓰인다. 프로토타입 객체는 새로 만들어진 인스턴스의 내부 [[Prototype]] 속성에 복사되어 참조된다. 가령, var a1 = new A()를 수행할 때, this를 포함하고 있는 함수을 수행하기 전, 메모리에 새로 생성된 객체를 생성한 직후 자바스크립트는 a1.[[Prototype]] = A.prototype를 수행한다. 그 인스턴스의 속성에 접근하려 할 때 자바스크립트는 그 객체의 개인 속성인지 우선 확인하고 그렇지 않은 경우에 [[Prototype]]에서 찾는다. 이것은 prototype에 정의한 모든 것은 모든 인스턴스가 효과적으로 공유한다는 뜻이며, 심지어 프로토타입의 일부를 나중에 변경하다고 해도 이미 생성되어 있는 인스턴스는 필요한 경우 그 변경 사항에 접근할 수 있다.

+ +

위의 예에서, 만일 var a1 = new A(); var a2 = new A(); 그 후 a1.doSomethingObject.getPrototypeOf(a1).doSomething를 가리키게 되는 것은A.prototype.doSomething으로 정의한 것과 같게 된다. 즉, Object.getPrototypeOf(a1).doSomething == Object.getPrototypeOf(a2).doSomething == A.prototype.doSomething.

+ +

요약 하자면, prototype은 타입 정의를 위한 것이고, Object.getPrototypeOf()는 모든 인스턴스가 공유한다.

+ +

[[Prototype]]은 재귀적으로 탐색된다. 즉, a1.doSomething, Object.getPrototypeOf(a1).doSomething,Object.getPrototypeOf(Object.getPrototypeOf(a1)).doSomething 등등, 이미 발견했거나 Object.getPrototypeOfnull을 반환할 때까지 반복된다.

+ +

따라서 다음 호출에 대하여

+ +
var o = new Foo();
+ +

자바스크립트는 실제로 다음 작업을 수행한다.

+ +
var o = new Object();
+o.[[Prototype]] = Foo.prototype;
+Foo.call(o);
+ +

(혹은 그런 비슷한 작업, 내부 구현은 다를 수 있다) 그리고 나중에 다음을 수행하면

+ +
o.someProp;
+ +

자바스크립트는 o가 속성 someProp을 가졌는지 확인하고, 아니면 Object.getPrototypeOf(o).someProp, 또 아니면 Object.getPrototypeOf(Object.getPrototypeOf(o)).someProp 등으로 계속 된다.

+ +

프로토타입 상속의 종류

+ +

프로토타입 상속에는 3가지 종류가 있다 : 위임형 상속, 연결형 상속, 함수형 상속.

+ +

위임형 상속(Delegation inheritance)

+ +

위임형 상속에서 프로토타입 객체는 다른 객체의 기반이 된다. 위임 프로토타입을 상속받을 경우 새 객체는 해당 프로토타입에 대한 참조를 가지고 있다.

+ +

새 객체의 속성에 접근할 때, 해당 객체가 직접적으로 속성을 소유하고 있는지 먼저 체크한다. 없다면 다음 순서로 [[Prototype]]을 체크한다. 이 과정은 프로토타입 체인을 따라서 모든 객체의 프로토타입 체인의 최상위에 있는 객체인 Object.prototype에 도달할 때 까지 반복된다.

+ +

메소드를 위임 상속할 경우 모든 객체가 각 메소드에에 대해 하나의 코드를 공유하므로 메모리를 절약할 수 있다.

+ +

Javascript에서 이를 구현하는 방법은 여러가지가 있는데 ES6에서는 아래와 같은 방식이 흔하다:

+ +
class Greeter {
+  constructor (name) {
+    this.name = name || 'John Doe';
+  }
+  hello () {
+    return `Hello, my name is ${ this.name }`;
+  }
+}
+
+const george = new Greeter('George');
+const msg = george.hello();
+console.log(msg); // Hello, my name is George
+
+ +

Object.create(null). 을 통해 프로토타입을 {{jsxref("null")}}로 지정하여 속성 위임 없이 객체를 생성할 수 있다..

+ +

이 방법의 큰 단점 중 하나는 상태를 저장하는데 그리 좋은 방법이 아니라는 것이다. 객체나 배열의 상태를 변경하게 되면 같은 프로토타입을 공유하는 모든 객체의 상태가 변경된다.

+ +

상태 변경이 전파되는 것을 막으려면 각 객체마다 상태 값의 복사본을 만들어야 한다.

+ +

연결형 상속(Concatenative inheritance)

+ +

연결형 상속은 한 객체의 속성을 다른 객체에 모두 복사함으로써 상속을 구현하는 방법이다.

+ +

이 상속법은 Javascript 객체의 동적 확장성을 이용한 방법이다. 객체 복사는 속성의 초기값을 저장하기 위한 좋은 방법이다: 이 방식은 {{jsxref("Object.assign()")}}을 통해 구현하는 것이 보통이며 ES6 이전에 Lodash, Underscore, jQuery등의 라이브러리들이 .extend() 와 비슷한 메소드로 제공한 방법이다.

+ +
const proto = {
+  hello: function hello() {
+    return `Hello, my name is ${ this.name }`;
+  }
+};
+
+const george = Object.assign({}, proto, {name: 'George'});
+const msg = george.hello();
+console.log(msg); // Hello, my name is George
+
+ +

연결형 상속은 매우 좋은 방법이며 클로져와 같이 사용한다면 훨씬 효과적인 상속 방식입니다..

+ +

함수형 상속(Functional inheritance)

+ +

함수형 상속(Functional inheritance)이라는 단어는 Douglas Crockford가 자신의 저서 “JavaScript: The Good Parts”에서 창조한 단어이다. 이 방법은 새 속성들을 연결형 상속으로 쌓되 상속 기능을 Factory 함수로 만들어 사용하는 방식이다.

+ +

기존의 객체를 확장하는데 쓰이는 함수를 일반적으로 믹스인 함수라 칭한다. 객체 확장에 함수를 사용하는 가장 큰 이점은 Private Data를 클로져를 통해 캡슐화 시킬 수 있다는 점이다.

+ +

다르게 말하자면 Private 상태를 지정할 수 있다는 의미이다.

+ +

특정 함수를 통할 필요 없이 public 접근이 가능한 속성에 대해 접근 제한을 거는 것은 문제가 있다. 따라서 private 클로져에 속성 값을 숨겨야 하며 이는 아래와 같이 구현한다:

+ +
// import Events from 'eventemitter3';
+
+const rawMixin = function () {
+  const attrs = {};
+  return Object.assign(this, {
+    set (name, value) {
+      attrs[name] = value;
+      this.emit('change', {
+        prop: name,
+        value: value
+      });
+    },
+    get (name) {
+      return attrs[name];
+    }
+  }, Events.prototype);
+};
+
+const mixinModel = (target) => rawMixin.call(target);
+const george = { name: 'george' };
+const model = mixinModel(george);
+model.on('change', data => console.log(data));
+model.set('name', 'Sam');
+/*
+{
+  prop: 'name',
+  value: 'Sam'
+}
+*/
+
+ +

attrs 을 public 속성에서 private 영역으로 옮겨서 public API를 통한 접근을 차단할 수 있다. // 접근할 수 있는 유일한 방법은 Privileged 메소드 뿐이다. Privileged 메소드는 클로져 영역에 정의된 함수로 private data에 접근 가능한 함수들을 일컫는다.

+ +

위 예제를 보면 믹스인 함수 rawMixin().에 대한 래퍼로 mixinModel() 을 선언한 것을 알 수 있다. 이는 예제에서 {{jsxref("Function.prototype.call()")}} 을 사용했듯이 함수 내에서 this의 값을 설정해야 하기 때문이다. Wrapper를 생략하고 호출자가 알아서 하도록 놔둘 수 있지만 그럴 경우 혼동될 가능성이 있다.

+ +
+

결론

+ +

복잡한 코드를 작성하여 이용하기 전에 프로토타입 기반의 상속 모델을 이해하는 것이 중요하다. 또한 프로토타입 체인의 길이는 성능을 저해하지 않도록 줄이는 방법을 고안해야 한다. 또한 빌트인 프로토타입은 새로운 자바스크립트 기능과 호환성을 갖기 위한 이유가 아닌 이상 절대 확장해서는 안된다.

+
+
diff --git a/files/ko/web/javascript/introduction_to_object-oriented_javascript/index.html b/files/ko/web/javascript/introduction_to_object-oriented_javascript/index.html deleted file mode 100644 index 03015b1407..0000000000 --- a/files/ko/web/javascript/introduction_to_object-oriented_javascript/index.html +++ /dev/null @@ -1,290 +0,0 @@ ---- -title: 객체지향 자바스크립트 개요 -slug: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript -translation_of: Learn/JavaScript/Objects -translation_of_original: Web/JavaScript/Introduction_to_Object-Oriented_JavaScript ---- -

비록 다른 객체지향적인 언어들과의 차이점에 대한 논쟁들이 있긴 하지만, JavaScript는 강력한 객체지향 프로그래밍 능력들을 지니고 있다.

- -

이 글에서는 객체지향 프로그래밍에 대해 소개하는 것으로 시작해서 자바스크립트의 객체 모델, 그리고 자바스크립트에서의 객체지향 프로그래밍 개념에 대해 간단한 예제로 살펴볼 것이다.

- -

자바스크립트 리뷰(JavaScript review)

- -

만약 변수, 형, 함수, 스코프 등 자바스크립트의 개념에 대해 명확히 이해하고 있지 못하다면, A re-introduction to JavaScript를 참고해 보자. Core JavaScript 1.5 Guide라는 글도 도움이 될 것이다.

- -

객체지향 프로그래밍(Object-oriented programming)

- -

객체지향 프로그래밍은 실제 세계에 기반한 모델을 만들기 위해 추상화를 사용하는 프로그래밍 패러다임이다. 객체지향 프로그래밍은 modularity, polymorphism, encapsulation을 포함하여 이전에 정립된 패러다임들부터 여러가지 테크닉들을 사용한다. 오늘날 많은 유명한 프로그래밍 언어(자바, 자바스크립트, C#, C++, 파이썬, PHP, 루비, 오브젝트C)는 객체지향 프로그래밍을 지원한다.

- -

객체지향 프로그래밍은 함수들의 집합 혹은 단순한 컴퓨터의 명령어들의 목록 이라는 기존의 프로그래밍에 대한 전통적인 관점에 반하여, 관계성있는 객체들의 집합이라는 관점으로 접근하는 소프트웨어 디자인으로 볼 수 있다. 객체지향 프로그래밍에서, 각 객체는 메시지를 받을 수도 있고, 데이터를 처리할 수도 있으며, 또다른 객체에게 메시지를 전달할 수도 있다. 각 객체는 별도의 역할이나 책임을 갖는 작은 독립적인 기계로 볼 수 있는 것이다.

- -

객체지향 프로그래밍은 보다 유연하고 유지보수성이 높은 프로그래밍을 하도록 의도되었고, 대규모 소프트웨어 공학에서 널리 알려져 있다. 객체지향 프로그래밍이 갖는 modularity에 기반한 강력한 힘에 의해, 객체지향적인 코드는 개발을 보다 단순하게 했고, 시간이 흐른 뒤에도 보다 쉽게 이해할 수 있도록 했으며, 복잡한 상황이나 절차들을 덜 모듈화된 프로그래밍 방법들보다 더 직접적으로 분석하고, 코딩하고, 이해할 수 있도록 만들었다.2

- -

용어(Terminology)

- -
-
Class
-
객체의 특성을 정의
-
Object
-
Class의 인스턴스
-
Property
-
객체의 특성(예: 색깔)
-
Method
-
객체의 능력(예: 걷기)
-
Constructor
-
인스턴스화 되는 시점에서 호출되는 메서드
-
Inheritance
-
클래스는 다른 클래스로부터 특성들을 상속받을 수 있다.
-
Encapsulation
-
클래스는 해당 객체의 특성들만을 정의할 수 있고, 메서드는 그 메서드가 어떻게 실행되는지만 정의할 수 있다. (외부 접근 불가)
-
Abstraction
-
복잡한 상속, 메서드, 객체의 속성의 결합은 반드시 현실 세계를 시뮬레이션할 수 있어야 한다.
-
Polymorphism
-
다른 클래스들이 같은 메서드나 속성으로 정의될 수 있다.
-
- -

객체지향 프로그래밍에 대한 보다 확장된 설명은 Object-oriented programming를 참고하면 된다.

- -

프로토타입기반 프로그래밍(Prototype-based programming)

- -

프로토타입 기반 프로그래밍은 클래스가 존재하지 않는 객체지향 프로그래밍의 한가지 스타일로, 동작 재사용(behavior reuse, 클래스기반 언어에서는 상속이라고함)은 프로토타입으로서 존재하는 객체를 데코레이팅하는 과정을 통해 수행된다.

- -

프로토타입 기반 언어의 원형적인 예는 David Ungar과 Randall Smith가 개발한 'Self'라는 프로그래밍 언어이다. 그러나 클래스가 없는 프로그래밍 스타일이 최근 인기를 얻으며 성장하였고, 자바스크립트, Cecil, NewtonScript, Io, MOO, REBOL, Kevo, Squeak 등의 언어에서 채택되어 왔다.2

- -

자바스크립트 객체지향 프로그래밍(JavaScript Object Oriented Programming)

- -

Core Objects

- -

자바스크립트는 코어(core)에 몇 개의 객체를 갖고 있다. 예를들면, Math, Object, Array, String과 같은 객체가 있다. 아래의 예제는 Math 객체를 사용해서 무작위 숫자를 만들어내는 것을 보여준다.

- -
alert(Math.random());
-
- -
Note: 여기와 다른 예제들 모두 alert 이라는 함수가 전역에 선언되어 있다고 가정하고 있다. alert 함수는 실제로 자바스크립트 그 자체에 포함되진 않았지만, 대부분의 브라우저에서 지원하고 있다.
- -

자바스크립트의 core object들의 리스트는 Core JavaScript 1.5 Reference:Global Objects라는 글을 참고하면 자세히 알 수 있다.

- -

자바스크립트의 모든 객체는 Object 객체의 인스턴스이므로 Object의 모든 속성과 메서드를 상속받는다.

- -

Custom Objects

- -

The Class

- -

class문을 흔하게 볼 수 있는 C++이나 자바와는 달리 자바스크립트는 class문이 포함되지 않은 프로토타입 기반 언어이다. 이로인해 때때로 class 기반 언어에 익숙한 프로그래머들은 혼란을 일으킨다. 자바스크립트에서는 function을 class로서 사용한다. 클래스를 정의하는 것은 function을 정의하는 것만큼 쉽다. 아래 예제에서는 Person이라는 이름의 클래스를 새로 정의하고 있다.

- -
function Person() { }
-
- -

The Object (Class Instance)

- -

obj라는 이름의 객체의 새로운 인스턴스를 만들 때에는 new obj라는 statement를 사용하고, 차후에 접근할 수 있도록 변수에 결과를 받는다.

- -

아래의 예제에서 Person이라는 이름의 클래스를 정의한 후에, 두 개의 인스턴스를 생성하고 있다.

- -
function Person() { }
-var person1 = new Person();
-var person2 = new Person();
-
- -
Object.create 메서드 역시 새로운 인스턴스를 만들 때 사용할 수 있다.
- -

The Constructor

- -

생성자는 인스턴스화되는 순간(객체 인스턴스가 생성되는 순간) 호출된다. 생성자는 해당 클래스의 메서드이다. 자바스크립트에서는 함수 자체가 그 객체의 생성자 역할을 하기 때문에 특별히 생성자 메서드를 정의할 필요가 없다. 클래스 안에 선언된 모든 내역은 인스턴스화되는 그 시간에 실행된다. 생성자는 주로 객체의 속성을 설정하거나 사용하기 위해 객체를 준비시키는 메서드를 호출할 때 주로 사용된다. 클래스 메서드를 추가하고 정의하는 것은 나중에 설명한다.

- -
아래의 예제에서, Person 클래스의 생성자는 Person 이 인스턴스화되었을 때 alert 을 보여주게 된다.
- -
function Person() {
-  alert('Person instantiated');
-}
-
-var person1 = new Person();
-var person2 = new Person();
-
- -

The Property (object attribute)

- -
속성은 클래스 안에 있는 변수들을 말한다. 객체의 모든 인스턴스는 그 인스턴스의 속성을 갖는다. 속성들의 상속이 바르게 이루어지려면 해당 클래스(function)의 프로토타입에 선언되어 있어야 한다.
- -
 
- -
클래스 내에서 속성 작업은 현재 객체를 가리키는 this 키워드에 의해 이루어진다. 클래스의 외부에서 속성에 접근(읽기 혹은 쓰기)하는 것은 "인스턴스명.속성명" 의 형식으로 이루어진다. 이러한 문법은 C++, 자바나 다른 수많은 언어에서와 동일한 방식이다. (클래스 내부에서 "this.속성명" 은 해당 속성의 값을 읽거나 쓸 때 주로 사용된다)
- -
 
- -
아래의 예제에서 Person 클래스에 gender라는 속성을 정의하고 인스턴스화할 때 그 값을 설정한다.
- -
function Person(gender) {
-  this.gender = gender;
-  alert('Person instantiated');
-}
-
-var person1 = new Person('Male');
-var person2 = new Person('Female');
-
-//display the person1 gender
-alert('person1 is a ' + person1.gender); // person1 is a Male
-
- -

메서드(The methods)

- -

메서드는 앞서 살펴본 속성과 같은 방식을 따른다. 차이점이 있다면 메서드는 function이기 때문에 function 형태로 정의된다는 것입니다. 메서드를 호출하는 것은 속성에 접근하는 것과 매우 유사한데 단지 끝에 ()를 추가하면 된다. argument가 있다면 괄호 안에 입력해준다. 메서드를 정의하기 위해서는 클래스의 prototype에 명명된 속성에 함수를 할당하면 된다. 이때 할당된 이름은 해당 객체의 메서드를 호출할 때 사용되는 이름이다.

- -

아래의 예에서는 Person 클래스에 sayHello()라는 메서드를 정의하고 사용하고 있다.

- -
function Person(gender) {
-  this.gender = gender;
-  alert('Person instantiated');
-}
-
-Person.prototype.sayHello = function()
-{
-  alert ('hello');
-};
-
-var person1 = new Person('Male');
-var person2 = new Person('Female');
-
-// call the Person sayHello method.
-person1.sayHello(); // hello
-
- -

자바스크립트에서 메서드는 "컨텍스트에 관계 없이" 호출될 수 있는 속성으로서 클래스/객체에 연결되어 있다. 다음 예제의 코드를 살펴보자.

- -
function Person(gender) {
-  this.gender = gender;
-}
-
-Person.prototype.sayGender = function()
-{
-  alert(this.gender);
-};
-
-var person1 = new Person('Male');
-var genderTeller = person1.sayGender;
-
-person1.sayGender(); // alerts 'Male'
-genderTeller(); // alerts undefined
-alert(genderTeller === person1.sayGender); // alerts true
-alert(genderTeller === Person.prototype.sayGender); // alerts true
-
- -

위의 예제는 많은 개념들을 한꺼번에 보여주고 있다. 

- -
먼저 이 예제는 자바스크립트에 "per-object methods" 가 존재하지 않는다는 것을 보여준다. JavaScript는 메서드에 대한 레퍼런스가 모두 똑같은 (프로토타입에 처음 정의한) 함수를 참조하고 있기 때문이다.
- -
 
- -
자바스크립트는 어떤 객체의 메서드로서 함수가 호출될 때 현재 "객체의 컨텍스트"를 특별한 "this" 변수에 "연결한다". 이는 아래와 같이 function 객체의 call 메서드를 호출하는 것과 동일하다.
- -
 
- -
(역자주: 참고로, genderTeller() 만 호출했을 때 undefined 가 나타난 것은 해당 메서드가 호출될 때 컨텍스트가 window 로 잡혔기 때문에 window.gender 는 존재하지 않으므로 undefined 가 나타난 것이다.)
- -
 
- -
genderTeller.call(person1); //alerts 'Male'
-
- -
더 자세한 것은 Function.callFunction.apply 를 참고하자.
- -

상속(Inheritance)

- -

상속은 하나 이상의 클래스를 특별한 버전의 클래스로 생성하는 하나의 방법이다. (다만 자바스크립트는 오직 하나의 클래스를 상속받는 것만 지원한다.) 이 특별한 클래스는 흔히 자식 클래스(child)라고 불리우고 원본 클래스는 흔히 부모 클래스(parent)라고 불리운다. 자바스크립트에서는 부모 클래스의 인스턴스를 자식 클래스에 할당함으로써 상속이 이루어진다. 최신 브라우저에서는 Object.create 메서드를 사용해서 상속을 수행할 수도 있다.

- -
-

Core JavaScript 1.5 Reference:Global Objects:Object:prototype 에 나와있는 설명과 같이 자바스크립트는 자식 클래스의 prototype.constructor 를 검색하지 않으므로 직접 명시해주어야 한다.

-
- -

아래의 예제에서는, Student라는 클래스를 Person 클래스의 자식 클래스로 정의한다. 그 후에 우리는 sayHello() 메서드를 재정의하고 sayGoodBye() 메서드를 추가한다.

- -
// define the Person Class
-function Person() {}
-
-Person.prototype.walk = function(){
-  alert ('I am walking!');
-};
-Person.prototype.sayHello = function(){
-  alert ('hello');
-};
-
-// define the Student class
-function Student() {
-  // Call the parent constructor
-  Person.call(this);
-}
-
-// inherit Person
-Student.prototype = new Person();
-
-// correct the constructor pointer because it points to Person
-Student.prototype.constructor = Student;
-
-// replace the sayHello method
-Student.prototype.sayHello = function(){
-  alert('hi, I am a student');
-}
-
-// add sayGoodBye method
-Student.prototype.sayGoodBye = function(){
-  alert('goodBye');
-}
-
-var student1 = new Student();
-student1.sayHello();
-student1.walk();
-student1.sayGoodBye();
-
-// check inheritance
-alert(student1 instanceof Person); // true
-alert(student1 instanceof Student); // true
-
- -

Object.create 를 사용하면 상속을 아래와 같이 수행할 수 있다.

- -
Student.prototype = Object.create(Person.prototype);
- -

캡슐화(Encapsulation)

- -

이전의 예제에서, Student 클래스는 Person 클래스의 walk() 메서드가 어떻게 실행되는지에 대해 알 필요가 없고, walk() 메서드를 사용하는데에도 전혀 문제가 없다. 또 Student 클래스에서는 walk() 메서드의 내용을 바꾸려는게 아니라면 walk() 메서드를 특별히 정의할 필요도 없다. 자식 클래스는 부모 클래스의 모든 메서드를 상속받고, 상속받은 메서드중 일부를 수정하고 싶은 경우에만 해당 메서드를 정의하는 것을 우리는 캡슐화(encapsulation)이라고 부른다.

- -

추상화(Abstraction)

- -

추상화는 작업 문제의 현재 부분을 모델링할 수 있도록 하는 매커니즘이다. 추상화는 상속(specialization, 추상의 수준을 낮추는 것)과 합성으로 구현할 수 있다. 자바스크립트는 상속에 의해 특별화(specialization)를, 클래스들의 인스턴스를 다른 객체의 속성값이 되게 함으로써 합성을 구현한다.

- -

자바스크립트 Function 클래스는 Object 클래스를 상속받고(이는 모델의 특별화를 보여준다), Function.prototype 속성은 Object의 인스턴스이다(이는 합성을 보여준다).

- -
var foo = function(){};
-alert( 'foo is a Function: ' + (foo instanceof Function) );
-alert( 'foo.prototype is an Object: ' + (foo.prototype instanceof Object) );
-
- -

다형성(Polymorphism)

- -

모든 메서드와 속성들은 prototype 속성에 선언되어 있고, 클래스가 다르다면 같은 이름의 메서드도 선언할 수 있다. 메서드들은 메서드가 선언된 클래스로 그 실행 영역이 한정된다. 물론 이건 두 개의 클래스들이 서로 부모-자식 관계가 아닐때에만 성립한다. 즉 다시 말해 부모-자식 관계의 상속 관계로 하나가 다른 하나에게서 상속받지 않았을 때에만 성립한다.

- -

Notes

- -

객체지향 프로그래밍을 구현하는데 있어서 자바스크립트는 매우 유연하기 때문에, 이 글에서 선보인 테크닉들은 자바스크립트에서 객체지향을 구현하는 유일한 방법들 중 일부일 뿐이다.

- -

또, 여기에서 선보인 테크닉들은 어떤 hack도 사용하지 않았고 또한 다른 언어의 객체 이론 구현물들을 모방하지도 않았다.

- -

자바스크립트의 객체지향 프로그래밍에 있어서 다른 보다 깊이있는 테크닉들이 많이 있지만, 소개하는 글이라는 이 글의 특성상 다루지 않기로 한다.

- -

References

- -
    -
  1. Mozilla. "Core JavaScript 1.5 Guide", http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Guide
  2. -
  3. Wikipedia. "Object-oriented programming", http://en.wikipedia.org/wiki/Object-...ed_programming
  4. -
- -
-

Original Document Information

- -
    -
  • Author(s): Fernando Trasviña <f_trasvina at hotmail dot com>
  • -
  • Copyright Information: © 1998-2005 by individual mozilla.org contributors; content available under a Creative Commons license
  • -
-
- -

 

diff --git a/files/ko/web/javascript/language_resources/index.html b/files/ko/web/javascript/language_resources/index.html new file mode 100644 index 0000000000..5743a54e24 --- /dev/null +++ b/files/ko/web/javascript/language_resources/index.html @@ -0,0 +1,155 @@ +--- +title: 자바스크립트 언어 자료 +slug: Web/JavaScript/언어_리소스 +tags: + - Advanced + - 자바스크립트 +translation_of: Web/JavaScript/Language_Resources +--- +
{{JsSidebar}}
+ +

ECMAScript자바스크립트의 토대를 구성하는 스크립트 언어입니다. ECMAScript는 ECMA International 표준화 기구에 의해서 ECMA-262 및 ECMA-402 스펙에서 표준화되었습니다. 다음은 현재까지 승인됐거나 작업 중인 ECMAScript 표준입니다:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
이름링크출시 날짜설명
현재판
ECMA-262 10th EditionWorking draft2019ECMAScript 2019 (제 10판), 명세 작업 중
ECMA-262 9th EditionPDFHTML
+ Working draftrepository
2018ECMAScript 2018 (제 9판)
ECMA-402 5th EditionWorking draft, repository2018ECMAScript 2018 국제화 API 표준
폐기(Obsolete)/역사판
ECMA-262 (ES 1)PDFJune 1997ECMAScript 표준 원본.
ECMA-262 (ES 2)PDFAugust 1998ECMAScript 표준 제2판; 또한 ISO 표준 16262.
ECMA-262 (ES 3)PDFDecember 1999ECMAScript 표준 제3판; JavaScript 1.5에 해당.
+ errata 참조
ECMA-262 (ES 5)PDFDecember 2009ECMAScript 제5판
+ ES5 errata 및 ECMAScript 5 support in Mozilla 참조
ECMA-357PDFJune 2004ECMAScript for XML (E4X).
+ E4X errata 참조.
ECMA-357 Edition 2PDFDecember 2005ECMAScript for XML (E4X).
ECMA-262 (ES 5.1)PDF, HTMLJune 2011이 판은 국제화 표준 ISO/IEC 16262:2011 제3판과 완전히 정렬됨.
+ ES5 errata 수정 포함, 새로운 기능은 없음.
ECMA-402 1.0PDF, HTMLDecember 2012ECMAScript 국제화 API 1.0.
ECMA-262 2015 (ES 6)PDF, HTMLJune 2015ECMAScript 2015 (제6판).
ECMA-402 2.0PDFJune 2015ECMAScript 국제화 API 2.0.
ECMA-262 2016 (ES 7)HTMLJune 2016ECMAScript 2016 (제7판).
ECMA-402 3.0HTMLJune 2016ECMAScript 국제화 API 3.0. 나중(올해 6월)에 승인될.
ECMA-262 2017 (ES 8)HTMLJune 2017ECMAScript 2017 (제8판).
ECMA-402 4th EditionHTMLJune 2017ECMAScript 국제화 API 4.0.
+ +

ECMAScript의 역사에 대한 자세한 정보는 Wikipedia ECMAScript entry를 살펴보세요.

+ +

여러분은 코드네임 "Harmony"로 불리우는 ECMAScript의 다음 개정에 참여하거나 그냥 진행상황을 확인할 수도 있습니다.  또한 ECMAScript 국제화 API 스펙도 공개 위키와 ecmascript.org 에 연결된 es-discuss mailing list에서도 확인할 수 있습니다.

+ +

구현

+ +
    +
  • SpiderMonkey - 파이어폭스 포함 여러 Mozilla 제품에 사용되는 자바스크립트 엔진;
  • +
  • Rhino - 자바로 작성된 자바스크립트 엔진;
  • +
  • Tamarin - (어도비® 플래쉬® 재생기에서 사용되는) 액션스크립트 가상머신;
  • +
  • Other implementations (위키피디아).
  • +
+ +

관련 항목

+ + diff --git a/files/ko/web/javascript/reference/classes/class_fields/index.html b/files/ko/web/javascript/reference/classes/class_fields/index.html deleted file mode 100644 index 959c65fada..0000000000 --- a/files/ko/web/javascript/reference/classes/class_fields/index.html +++ /dev/null @@ -1,396 +0,0 @@ ---- -title: Class fields -slug: Web/JavaScript/Reference/Classes/Class_fields -translation_of: Web/JavaScript/Reference/Classes/Public_class_fields ---- -
{{JsSidebar("Classes")}}
- -
-

This page describes experimental features.

- -

Both Public and private field declarations are an experimental feature (stage 3) proposed at TC39, the JavaScript standards committee.

- -

Support in browsers is limited, but the feature can be used through a build step with systems like Babel. See the compat information below.

-
- -

Public fields

- -

static fields와 instance의 public fields 는 둘 다 writable, enumerable, configurable 한 프로퍼티들이다. 예를들면, 정 반대인 private 과는 다르게, unlike their private counterparts, static fields는 프로토타입 상속에 관여한다.

- -

Public static fields

- -

Public static fields 는 클래스에서 생성하는 모든 인스턴스에 대한 필드가 아닌, 클래스마다 단 한개의 필드가 존재하기를 원할 때 유용하게 사용할 수 있다. Public fields는 캐시, 고정된 설정값, 또는 인스턴스 간 복제할 필요가 없는 어떤 데이터 등에 유용하게 쓰일 수 있다.

- -

Public static fields are declared using the static keyword. They are added to the class constructor at the time of class evaluation using {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}}. They are accessed again from the class constructor.

- -
class ClassWithStaticField {
-  static staticField = 'static field'
-}
-
-console.log(ClassWithStaticField.staticField)
-// expected output: "static field"​
-
- -

Fields without initializers are initialized to undefined.

- -
class ClassWithStaticField {
-  static staticField
-}
-
-console.assert(ClassWithStaticField.hasOwnProperty('staticField'))
-console.log(ClassWithStaticField.staticField)
-// expected output: "undefined"
- -

Public static fields are not reinitialized on subclasses, but can be accessed via the prototype chain.

- -
class ClassWithStaticField {
-  static baseStaticField = 'base field'
-}
-
-class SubClassWithStaticField extends ClassWithStaticField {
-  static subStaticField = 'sub class field'
-}
-
-console.log(SubClassWithStaticField.subStaticField)
-// expected output: "sub class field"
-
-console.log(SubClassWithStaticField.baseStaticField)
-// expected output: "base field"
- -

When initializing fields, this refers to the class constructor. You can also reference it by name, and use super to get the superclass constructor (if one exists).

- -
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)
-// expected output: "base static field"
-
-console.log(SubClassWithStaticField.subStaticField)
-// expected output: "base static method output"
-
- -

Public instance fields

- -

Public instance fields exist on every created instance of a class. By declaring a public field, you can ensure the field is always present, and the class definition is more self-documenting.

- -

Public instance fields are added with {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} either at construction time in the base class (before the constructor body runs), or just after super() returns in a subclass.

- -
class ClassWithInstanceField {
-  instanceField = 'instance field'
-}
-
-const instance = new ClassWithInstanceField()
-console.log(instance.instanceField)
-// expected output: "instance field"
- -

Fields without initializers are initialized to undefined.

- -
class ClassWithInstanceField {
-  instanceField
-}
-
-const instance = new ClassWithInstanceField()
-console.assert(instance.hasOwnProperty('instanceField'))
-console.log(instance.instanceField)
-// expected output: "undefined"
- -

Like properties, field names may be computed.

- -
const PREFIX = 'prefix'
-
-class ClassWithComputedFieldName {
-    [`${PREFIX}Field`] = 'prefixed field'
-}
-
-const instance = new ClassWithComputedFieldName()
-console.log(instance.prefixField)
-// expected output: "prefixed field"
- -

When initializing fields this refers to the class instance under construction. Just as in public instance methods, if you're in a subclass you can access the superclass prototype using 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)
-// expected output: "base field"
-
-console.log(sub.subInstanceField)
-// expected output: "base method output"
- -

Public methods

- -

Public static methods

- -

The static keyword defines a static method for a class. Static methods aren't called on instances of the class. Instead, they're called on the class itself. These are often utility functions, such as functions to create or clone objects.

- -

{{EmbedInteractiveExample("pages/js/classes-static.html")}}

- - - -

The static methods are added to the class constructor with {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} at class evaluation time. These methods are writable, non-enumerable, and configurable.

- -

Public instance methods

- -

As the name implies, public instance methods are methods available on class instances.

- -
class ClassWithPublicInstanceMethod {
-  publicMethod() {
-    return 'hello world'
-  }
-}
-
-const instance = new ClassWithPublicInstanceMethod()
-console.log(instance.publicMethod())
-// expected output: "hello worl​d"
- -

Public instance methods are added to the class prototype at the time of class evaluation using {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}}. They are writable, non-enumerable, and configurable.

- -

You may make use of generator, async, and async generator functions.

- -
class ClassWithFancyMethods {
-  *generatorMethod() { }
-  async asyncMethod() { }
-  async *asyncGeneratorMethod() { }
-}
- -

Inside instance methods, this refers to the instance itself. In subclasses, super lets you access the superclass prototype, allowing you to call methods from the superclass.

- -
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())
-// expected output: "hello worl​d"
-
- -

Getters and setters are special methods that bind to a class property and are called when that property is accessed or set. Use the get and set syntax to declare a public instance getter or setter.

- -
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)
-// expected output: "hello cake"
-
- -

Private fields

- -

Private static fields 

- -

Private fields are accessible on the class constructor from inside the class declaration itself.

- -

The limitation of static variables being called by only static methods still holds. 

- -
class ClassWithPrivateStaticField {
-  static #PRIVATE_STATIC_FIELD
-
-  static publicStaticMethod() {
-    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42
-    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD
-  }
-}
-
-assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)
- -

Private static fields are added to the class constructor at class evaluation time.

- -

There is a provenance restriction on private static fields. Only the class which defines the private static field can access the field.

- -

This can lead to unexpected behaviour when using 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)
-
- -

Private instance fields

- -

Private instance fields are declared with # names (pronounced "hash names"), which are identifiers prefixed with #. The # is a part of the name itself. It is used for declaration and accessing as well.

- -

The encapsulation is enforced by the language. It is a syntax error to refer to # names from out of scope.

- -
class ClassWithPrivateField {
-  #privateField
-
-  constructor() {
-    this.#privateField = 42
-    this.#randomField = 666 // Syntax error
-  }
-}
-
-const instance = new ClassWithPrivateField()
-instance.#privateField === 42 // Syntax error
-
- -

Private Methods

- -

Private static methods

- -

Like their public equivalent, private static methods are called on the class itself, not instances of the class. Like private static fields, they are only accessible from inside the class declaration.

- -

Private static methods may be generator, async, and async generator functions.

- -
class ClassWithPrivateStaticMethod {
-    static #privateStaticMethod() {
-        return 42
-    }
-
-    static publicStaticMethod1() {
-        return ClassWithPrivateStaticMethod.#privateStaticMethod();
-    }
-
-    static publicStaticMethod2() {
-        return this.#privateStaticMethod();
-    }
-}
-
-assert(ClassWithPrivateStaticField.publicStaticMethod1() === 42);
-assert(ClassWithPrivateStaticField.publicStaticMethod2() === 42);
-
- -

This can lead to unexpected behaviour when using this(because this binding rule applies).

- -
class Base {
-    static #privateStaticMethod() {
-        return 42;
-    }
-    static publicStaticMethod1() {
-        return Base.#privateStaticMethod();
-    }
-    static publicStaticMethod2() {
-        return this.#privateStaticMethod();
-    }
-}
-
-class Derived extends Base {}
-
-console.log(Derived.publicStaticMethod1()); // 42
-console.log(Derived.publicStaticMethod2()); // TypeError
-
- -

Private instance methods

- -

Private instance methods are methods available on class instances whose access is restricted in the same manner as private instance fields.

- -
class ClassWithPrivateMethod {
-  #privateMethod() {
-    return 'hello world'
-  }
-
-  getPrivateMessage() {
-      return this.#privateMethod()
-  }
-}
-
-const instance = new ClassWithPrivateMethod()
-console.log(instance.getPrivateMessage())
-// expected output: "hello worl​d"
- -

Private instance methods may be generator, async, or async generator functions. Private getters and setters are also possible:

- -
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();
-// expected output: "✨hello worl​d✨"
-
- -

Specifications

- - - - - - - - - - - - - - -
SpecificationStatusComment
FieldDefinition productionStage 3
- -

Browser compatibility

- -

Public class fields

- - - -

{{Compat("javascript.classes.public_class_fields")}}

- -

Private class fields

- - - -

{{Compat("javascript.classes.private_class_fields")}}

- -

See also

- - diff --git a/files/ko/web/javascript/reference/classes/public_class_fields/index.html b/files/ko/web/javascript/reference/classes/public_class_fields/index.html new file mode 100644 index 0000000000..959c65fada --- /dev/null +++ b/files/ko/web/javascript/reference/classes/public_class_fields/index.html @@ -0,0 +1,396 @@ +--- +title: Class fields +slug: Web/JavaScript/Reference/Classes/Class_fields +translation_of: Web/JavaScript/Reference/Classes/Public_class_fields +--- +
{{JsSidebar("Classes")}}
+ +
+

This page describes experimental features.

+ +

Both Public and private field declarations are an experimental feature (stage 3) proposed at TC39, the JavaScript standards committee.

+ +

Support in browsers is limited, but the feature can be used through a build step with systems like Babel. See the compat information below.

+
+ +

Public fields

+ +

static fields와 instance의 public fields 는 둘 다 writable, enumerable, configurable 한 프로퍼티들이다. 예를들면, 정 반대인 private 과는 다르게, unlike their private counterparts, static fields는 프로토타입 상속에 관여한다.

+ +

Public static fields

+ +

Public static fields 는 클래스에서 생성하는 모든 인스턴스에 대한 필드가 아닌, 클래스마다 단 한개의 필드가 존재하기를 원할 때 유용하게 사용할 수 있다. Public fields는 캐시, 고정된 설정값, 또는 인스턴스 간 복제할 필요가 없는 어떤 데이터 등에 유용하게 쓰일 수 있다.

+ +

Public static fields are declared using the static keyword. They are added to the class constructor at the time of class evaluation using {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}}. They are accessed again from the class constructor.

+ +
class ClassWithStaticField {
+  static staticField = 'static field'
+}
+
+console.log(ClassWithStaticField.staticField)
+// expected output: "static field"​
+
+ +

Fields without initializers are initialized to undefined.

+ +
class ClassWithStaticField {
+  static staticField
+}
+
+console.assert(ClassWithStaticField.hasOwnProperty('staticField'))
+console.log(ClassWithStaticField.staticField)
+// expected output: "undefined"
+ +

Public static fields are not reinitialized on subclasses, but can be accessed via the prototype chain.

+ +
class ClassWithStaticField {
+  static baseStaticField = 'base field'
+}
+
+class SubClassWithStaticField extends ClassWithStaticField {
+  static subStaticField = 'sub class field'
+}
+
+console.log(SubClassWithStaticField.subStaticField)
+// expected output: "sub class field"
+
+console.log(SubClassWithStaticField.baseStaticField)
+// expected output: "base field"
+ +

When initializing fields, this refers to the class constructor. You can also reference it by name, and use super to get the superclass constructor (if one exists).

+ +
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)
+// expected output: "base static field"
+
+console.log(SubClassWithStaticField.subStaticField)
+// expected output: "base static method output"
+
+ +

Public instance fields

+ +

Public instance fields exist on every created instance of a class. By declaring a public field, you can ensure the field is always present, and the class definition is more self-documenting.

+ +

Public instance fields are added with {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} either at construction time in the base class (before the constructor body runs), or just after super() returns in a subclass.

+ +
class ClassWithInstanceField {
+  instanceField = 'instance field'
+}
+
+const instance = new ClassWithInstanceField()
+console.log(instance.instanceField)
+// expected output: "instance field"
+ +

Fields without initializers are initialized to undefined.

+ +
class ClassWithInstanceField {
+  instanceField
+}
+
+const instance = new ClassWithInstanceField()
+console.assert(instance.hasOwnProperty('instanceField'))
+console.log(instance.instanceField)
+// expected output: "undefined"
+ +

Like properties, field names may be computed.

+ +
const PREFIX = 'prefix'
+
+class ClassWithComputedFieldName {
+    [`${PREFIX}Field`] = 'prefixed field'
+}
+
+const instance = new ClassWithComputedFieldName()
+console.log(instance.prefixField)
+// expected output: "prefixed field"
+ +

When initializing fields this refers to the class instance under construction. Just as in public instance methods, if you're in a subclass you can access the superclass prototype using 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)
+// expected output: "base field"
+
+console.log(sub.subInstanceField)
+// expected output: "base method output"
+ +

Public methods

+ +

Public static methods

+ +

The static keyword defines a static method for a class. Static methods aren't called on instances of the class. Instead, they're called on the class itself. These are often utility functions, such as functions to create or clone objects.

+ +

{{EmbedInteractiveExample("pages/js/classes-static.html")}}

+ + + +

The static methods are added to the class constructor with {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}} at class evaluation time. These methods are writable, non-enumerable, and configurable.

+ +

Public instance methods

+ +

As the name implies, public instance methods are methods available on class instances.

+ +
class ClassWithPublicInstanceMethod {
+  publicMethod() {
+    return 'hello world'
+  }
+}
+
+const instance = new ClassWithPublicInstanceMethod()
+console.log(instance.publicMethod())
+// expected output: "hello worl​d"
+ +

Public instance methods are added to the class prototype at the time of class evaluation using {{jsxref("Global_Objects/Object/defineProperty", "Object.defineProperty()")}}. They are writable, non-enumerable, and configurable.

+ +

You may make use of generator, async, and async generator functions.

+ +
class ClassWithFancyMethods {
+  *generatorMethod() { }
+  async asyncMethod() { }
+  async *asyncGeneratorMethod() { }
+}
+ +

Inside instance methods, this refers to the instance itself. In subclasses, super lets you access the superclass prototype, allowing you to call methods from the superclass.

+ +
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())
+// expected output: "hello worl​d"
+
+ +

Getters and setters are special methods that bind to a class property and are called when that property is accessed or set. Use the get and set syntax to declare a public instance getter or setter.

+ +
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)
+// expected output: "hello cake"
+
+ +

Private fields

+ +

Private static fields 

+ +

Private fields are accessible on the class constructor from inside the class declaration itself.

+ +

The limitation of static variables being called by only static methods still holds. 

+ +
class ClassWithPrivateStaticField {
+  static #PRIVATE_STATIC_FIELD
+
+  static publicStaticMethod() {
+    ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD = 42
+    return ClassWithPrivateStaticField.#PRIVATE_STATIC_FIELD
+  }
+}
+
+assert(ClassWithPrivateStaticField.publicStaticMethod() === 42)
+ +

Private static fields are added to the class constructor at class evaluation time.

+ +

There is a provenance restriction on private static fields. Only the class which defines the private static field can access the field.

+ +

This can lead to unexpected behaviour when using 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)
+
+ +

Private instance fields

+ +

Private instance fields are declared with # names (pronounced "hash names"), which are identifiers prefixed with #. The # is a part of the name itself. It is used for declaration and accessing as well.

+ +

The encapsulation is enforced by the language. It is a syntax error to refer to # names from out of scope.

+ +
class ClassWithPrivateField {
+  #privateField
+
+  constructor() {
+    this.#privateField = 42
+    this.#randomField = 666 // Syntax error
+  }
+}
+
+const instance = new ClassWithPrivateField()
+instance.#privateField === 42 // Syntax error
+
+ +

Private Methods

+ +

Private static methods

+ +

Like their public equivalent, private static methods are called on the class itself, not instances of the class. Like private static fields, they are only accessible from inside the class declaration.

+ +

Private static methods may be generator, async, and async generator functions.

+ +
class ClassWithPrivateStaticMethod {
+    static #privateStaticMethod() {
+        return 42
+    }
+
+    static publicStaticMethod1() {
+        return ClassWithPrivateStaticMethod.#privateStaticMethod();
+    }
+
+    static publicStaticMethod2() {
+        return this.#privateStaticMethod();
+    }
+}
+
+assert(ClassWithPrivateStaticField.publicStaticMethod1() === 42);
+assert(ClassWithPrivateStaticField.publicStaticMethod2() === 42);
+
+ +

This can lead to unexpected behaviour when using this(because this binding rule applies).

+ +
class Base {
+    static #privateStaticMethod() {
+        return 42;
+    }
+    static publicStaticMethod1() {
+        return Base.#privateStaticMethod();
+    }
+    static publicStaticMethod2() {
+        return this.#privateStaticMethod();
+    }
+}
+
+class Derived extends Base {}
+
+console.log(Derived.publicStaticMethod1()); // 42
+console.log(Derived.publicStaticMethod2()); // TypeError
+
+ +

Private instance methods

+ +

Private instance methods are methods available on class instances whose access is restricted in the same manner as private instance fields.

+ +
class ClassWithPrivateMethod {
+  #privateMethod() {
+    return 'hello world'
+  }
+
+  getPrivateMessage() {
+      return this.#privateMethod()
+  }
+}
+
+const instance = new ClassWithPrivateMethod()
+console.log(instance.getPrivateMessage())
+// expected output: "hello worl​d"
+ +

Private instance methods may be generator, async, or async generator functions. Private getters and setters are also possible:

+ +
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();
+// expected output: "✨hello worl​d✨"
+
+ +

Specifications

+ + + + + + + + + + + + + + +
SpecificationStatusComment
FieldDefinition productionStage 3
+ +

Browser compatibility

+ +

Public class fields

+ + + +

{{Compat("javascript.classes.public_class_fields")}}

+ +

Private class fields

+ + + +

{{Compat("javascript.classes.private_class_fields")}}

+ +

See also

+ + diff --git a/files/ko/web/javascript/reference/functions/arrow_functions/index.html b/files/ko/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..02dc0d55e4 --- /dev/null +++ b/files/ko/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,465 @@ +--- +title: 화살표 함수 +slug: Web/JavaScript/Reference/Functions/애로우_펑션 +tags: + - ECMAScript6 + - Functions + - Intermediate + - JavaScript + - Reference +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +
{{jsSidebar("Functions")}}
+ +

화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고  자신의 this, arguments, super 또는 new.target을 바인딩 하지 않습니다. 화살표 함수는 항상 익명입니다. 이  함수 표현은 메소드 함수가 아닌 곳에 가장 적합합니다. 그래서 생성자로서 사용할 수 없습니다.

+ +

{{EmbedInteractiveExample("pages/js/functions-arrow.html")}}

+ +

구문

+ +

기본 구문

+ +
(param1, param2, …, paramN) => { statements }
+(param1, param2, …, paramN) => expression
+// 다음과 동일함:  => { return expression; }
+
+// 매개변수가 하나뿐인 경우 괄호는 선택사항:
+(singleParam) => { statements }
+singleParam => { statements }
+
+// 매개변수가 없는 함수는 괄호가 필요:
+() => { statements }
+ +

고급 구문

+ +
// 객체 리터럴 표현을 반환하기 위해서는 함수 본문(body)을 괄호 속에 넣음:
+params => ({foo: bar})
+
+// 나머지 매개변수기본 매개변수를 지원함
+(param1, param2, ...rest) => { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
+
+// 매개변수 목록 내 구조분해할당도 지원됨
+var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
+f();  // 6
+
+ +

상세한 구문 예는 여기에서 볼 수 있습니다.

+ +

설명

+ +

Hacks 블로그 "ES6 In Depth: Arrow functions" 포스트 참조.

+ +

화살표 함수 도입에 영향을 준 두 요소: 보다 짧아진 함수 및  바인딩하지 않은 this.

+ +

짧은 함수

+ +

일부 함수 패턴에서는, 짧은 함수가 환영받습니다. 비교해 보세요:

+ +
var elements = [
+  'Hydrogen',
+  'Helium',
+  'Lithium',
+  'Beryllium'
+];
+
+// 이 문장은 배열을 반환함: [8, 6, 7, 9]
+elements.map(function(element) {
+  return element.length;
+});
+
+// 위의 일반적인 함수 표현은 아래 화살표 함수로 쓸 수 있다.
+elements.map((element) => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// 파라미터가 하나만 있을 때는 주변 괄호를 생략할 수 있다.
+elements.map(element => {
+  return element.length;
+}); // [8, 6, 7, 9]
+
+// 화살표 함수의 유일한 문장이 'return'일 때 'return'과
+// 중괄호({})를 생략할 수 있다.
+elements.map(element => element.length); // [8, 6, 7, 9]
+
+// 이 경우 length 속성만 필요하므로 destructuring 매개변수를 사용할 수 있다.
+// 'length'는 우리가 얻고자 하는 속성에 해당하는 반면,
+// lengthFooBArX'는 변경 가능한 변수의 이름일 뿐이므로
+// 원하는 유효한 변수명으로 변경할 수 있다.
+elements.map(({ length: lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
+
+// destructuring 파라미터 할당도 아래와 같이 작성할 수 있습니다.
+// 이 예에서 정의한 객체내의 'length'에 값을 지정하지 않은 점에 주목하세요. 대신, "length" 변수의
+// 리터럴 이름은 우리가 해당 객체에서 꺼내오고 싶은 속성이름 자체로 사용됩니다.
+elements.map(({ length }) => length); // [8, 6, 7, 9] 
+ +

바인딩 되지 않은 this

+ +

화살표 함수가 나오기 전까지는, 모든 새로운 함수는, 어떻게 그 함수가 호출되는지에 따라  자신의 this 값을 정의했습니다:

+ +
    +
  • 이 함수가 생성자인 경우는 새로운 객체
  • +
  • 엄격 모드 함수 호출에서는 undefined 
  • +
  • 함수가 "객체 메서드"로서 호출된 경우 문맥 객체
  • +
  • 등등
  • +
+ +

이는 객체 지향 스타일로 프로그래밍할 때 별로 좋지않습니다.

+ +
function Person() {
+  // Person() 생성자는 `this`를 자신의 인스턴스로 정의.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // 비엄격 모드에서, growUp() 함수는 `this`를
+    // 전역 객체로 정의하고, 이는 Person() 생성자에
+    // 정의된 `this`와 다름.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

ECMAScript 3/5 에서는, 이 문제를 this 값을 폐쇄될 수 있는 (비전역) 변수에 할당하여 해결했습니다.

+ +
function Person() {
+  var that = this;
+  that.age = 0;
+
+  setInterval(function growUp() {
+    // 콜백은  `that` 변수를 참조하고 이것은 값이 기대한 객체이다.
+    that.age++;
+  }, 1000);
+}
+ +

이렇게 하는 대신에, 바인딩한 함수는 적절한 this 값이 growUp() 함수에 전달될 수 있도록 생성될 수 있습니다.

+ +

화살표 함수는 자신의 this가 없습니다.  대신 화살표 함수를 둘러싸는 렉시컬 범위(lexical scope)의 this가 사용됩니다; 화살표 함수는 일반 변수 조회 규칙(normal variable lookup rules)을 따릅니다. 때문에 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수는 바로 바깥 범위에서 this를 찾는것으로 검색을 끝내게 됩니다.

+ +

따라서 다음 코드에서 setInterval에 전달 된 함수 내부의 thissetInterval을 포함한 function의 this와 동일한 값을 갖습니다.

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this|는 Person 객체를 참조
+  }, 1000);
+}
+
+var p = new Person();
+ +

엄격 모드와의 관계

+ +

this가 렉시컬(lexical, 정적)임을 감안하면, this에 관한 엄격 모드 규칙은 그냥 무시됩니다.

+ +
var f = () => { 'use strict'; return this; };
+f() === window; // 혹은 전역객체
+ +

엄격 모드의 나머지 규칙은 평소대로 적용합니다.

+ +

CORRECTION: START

+ +

NOTE: the previous statement seems false.

+ +

Strict mode should prevent creating global variables when assigning to an undeclared identifier in a function.

+ +

This code sample using Chrome 81 demonstrates that arrow functions allow the creation of global variables in such situations (both for a concise body and for a normal function body):

+ +
> f1 = x => { y = x; console.log(`x: ${x}, y: ${y}`); return x + 1; }
+x => { y = x; console.log(`x: ${x}, y: ${y}`); return x + 1; }
+
+> y
+VM51587:1 Uncaught ReferenceError: y is not defined
+    at <anonymous>:1:1
+(anonymous) @ VM51587:1
+
+> f1(3)
+VM51533:1 x: 3, y: 3
+4
+
+> y
+3
+
+> f2 = x => { 'use strict'; z = x; console.log(`x: ${x}, z: ${z}`); return x + 1; }
+x => { 'use strict'; z = x; console.log(`x: ${x}, z: ${z}`); return x + 1; }
+
+> z
+VM51757:1 Uncaught ReferenceError: z is not defined
+    at <anonymous>:1:1
+(anonymous) @ VM51757:1
+
+> f2(4)
+VM51712:1 Uncaught ReferenceError: z is not defined
+    at f2 (<anonymous>:1:29)
+    at <anonymous>:1:1
+f2 @ VM51712:1
+(anonymous) @ VM51800:1
+
+> f3 = x => (z1 = x + 1)
+x => (z1 = x + 1)
+
+> z1
+VM51891:1 Uncaught ReferenceError: z1 is not defined
+    at <anonymous>:1:1
+(anonymous) @ VM51891:1
+
+> f3(10)
+11
+
+> z1
+11
+
+ +

f2 illustrates that when explicitly setting the arrow function to apply strict mode, it does throw an error when attempting to assign an undeclared variable.

+ +

https://www.ecma-international.org/ecma-262/10.0/index.html#sec-strict-mode-code

+ +

https://www.ecma-international.org/ecma-262/10.0/index.html#sec-arrow-function-definitions-runtime-semantics-evaluation

+ +

CORRECTION: END

+ +

call 또는 apply를 통한 피호출

+ +

화살표 함수에서는 this가 바인딩되지 않았기 때문에, call() 또는 apply() 메서드는  인자만 전달 할 수 있습니다. this는 무시됩니다.

+ +
var adder = {
+  base : 1,
+
+  add : function(a) {
+    var f = v => v + this.base;
+    return f(a);
+  },
+
+  addThruCall: function(a) {
+    var f = v => v + this.base;
+    var b = {
+      base : 2
+    };
+
+    return f.call(b, a);
+  }
+};
+
+console.log(adder.add(1));         // 이는 2가 콘솔에 출력될 것임
+console.log(adder.addThruCall(1)); // 이도 2가 콘솔에 출력될 것임
+ +

바인딩 되지 않은 arguments

+ +

화살표 함수는 arguments 객체를 바인드 하지 않습니다.  때문에, arguments는  그저 둘러싸는 범위(scope) 내 이름에 대한 참조입니다.

+ +
var arguments = [1, 2, 3];
+var arr = () => arguments[0];
+
+arr(); // 1
+
+function foo(n) {
+  var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
+  return f();
+}
+
+foo(1); // 2
+ +

화살표 함수는 자신의 arguments 객체가 없지만, 대부분의 경우에 나머지 매개변수가 좋은 대안입니다:

+ +
function foo(n) {
+  var f = (...args) => args[0] + n;
+  return f(2);
+}
+
+foo(1); // 3
+ +

메소드로 사용되는 화살표 함수

+ +

이야기 했듯이, 화살표 함수 표현은 메소드 함수가 아닌 형태로 사용 할 수 있습니다. 메소드로 사용하려고 한면 무슨일이 발생하는지 봅시다.

+ +
'use strict';
+
+var obj = { // does not create a new scope
+  i: 10,
+  b: () => console.log(this.i, this),
+  c: function() {
+    console.log( this.i, this)
+  }
+}
+obj.b(); // prints undefined, Window {...} (or the global object)
+obj.c(); // prints 10, Object {...}
+
+ +

화살표 함수는 자신의 this를 가지고("bind" 바인드)있지 않습니다.{{jsxref("Object.defineProperty()")}}

+ +
'use strict';
+
+var obj = {
+  a: 10
+};
+
+Object.defineProperty(obj, 'b', {
+  get: () => {
+    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object)
+    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
+  }
+});
+ +

new 연산자 사용

+ +

화살표 함수는 생성자로서 사용될 수 없으며 new와 함께 사용하면 오류가 발생합니다.

+ +
var Foo = () => {};
+var foo = new Foo(); // TypeError: Foo is not a constructor
+ +

prototype 속성 사용

+ +

화살표 함수는 prototype 속성이 없습니다.

+ +
var Foo = () => {};
+console.log(Foo.prototype); // undefined
+ +

yield 키워드 사용

+ +

yield 키워드는 화살표 함수의 본문(그 안에 더 중첩된 함수 내에서 허용한 경우를 제외하고)에 사용될 수 없습니다. 그 결과, 화살표 함수는 생성기(generator)로서 사용될 수 없습니다.

+ +

함수 본문

+ +

화살표 함수는 "concise 바디"든 보통 "block 바디"든 하나를 가질 수 있습니다.

+ +
+

concise바디는 중괄호'{}'로 묶이지않은 한줄짜리 바디이고 block바디는 중괄호로 묶인 바디입니다. 보통 여러줄 쓸때 block바디를 사용합니다.

+
+ +

block바디는 자동으로 값을 반환하지 않습니다. return을 사용해서 값을 반환해야 합니다.

+ +
var func = x => x * x;                  // concise 바디, 생략된 "return" 여기서는 x * x
+var func = (x, y) => { return x + y; }; // block 바디, "return"이 필요
+
+ +

객체 리터럴 반환

+ +

간결한 구문 params => {object:literal}을 사용한 객체 리터럴 반환은 예상대로 작동하지 않음을 명심하세요:

+ +
var func = () => {  foo: 1  };
+// func() 호출은 undefined를 반환!
+
+var func = () => {  foo: function() {}  };
+// SyntaxError: function 문은 이름이 필요함
+ +

이는 중괄호({}) 안 코드가 일련의 문(즉 foo는 라벨처럼 취급됩니다, 객체 리터럴 내 키가 아니라)으로 파싱(parse, 구문 분석)되기 때문입니다.

+ +

객체 리터럴를 괄호로 감싸는 것을 기억하세요:

+ +
var func = () => ({ foo: 1 });
+ +

줄바꿈

+ +

화살표 함수는 파라메터와 화살표 사이에 개행 문자를 포함 할 수 없습니다.

+ +
var func = (a, b, c)
+           => 1;
+// SyntaxError: expected expression, got '=>'
+ +

하지만, 보기 좋은 코드를 유지하고 싶다면, 아래에 보는 것처럼 괄호나 개행을 둠으로써 이를 수정할 수 있습니다.

+ +
var func = (a, b, c) =>
+  1;
+
+var func = (a, b, c) => (
+  1
+);
+
+var func = (a, b, c) => {
+  return 1
+};
+
+var func = (
+  a,
+  b,
+  c
+) => 1;
+
+// SyntaxError가 발생하지 않습니다.
+ +

파싱순서

+ +

화살표 함수 내의 화살표는 연산자가 아닙니다. 그러나 화살표 함수는 평범한 함수와 비교했을 때 operator precedence와 다르게 반응하는 특별한 파싱룰을 가지고 있습니다.

+ +
let callback;
+
+callback = callback || function() {}; // ok
+
+callback = callback || () => {};
+// SyntaxError: invalid arrow-function arguments
+
+callback = callback || (() => {});    // ok
+
+ +

다른 예

+ +

기본 사용법

+ +
//  empty 화살표 함수는 undefined를 반환 
+let empty = () => {};
+
+(() => 'foobar')();
+// "foobar" 반환
+// (this is an Immediately Invoked Function Expression
+
+var simple = a => a > 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) => a > b ? a : b;
+
+// Easy array filtering, mapping, ...
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+
+var sum = arr.reduce((a, b) => a + b);
+// 66
+
+var even = arr.filter(v => v % 2 == 0);
+// [6, 0, 18]
+
+var double = arr.map(v => v * 2);
+// [10, 12, 26, 0, 2, 36, 46]
+
+// 더 간결한 promise 체인
+promise.then(a => {
+  // ...
+}).then(b => {
+  // ...
+});
+
+// 매개변수가 없는 경우에도 더 읽기 쉬움
+setTimeout( () => {
+  console.log('I happen sooner');
+  setTimeout( () => {
+    // deeper code
+    console.log('I happen later');
+  }, 1);
+}, 1);
+ +

스펙

+ + + + + + + + + + +
Specification
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}
+ +

브라우저 호환성

+ + + +

{{Compat("javascript.functions.arrow_functions")}}

+ +

참조

+ + diff --git "a/files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" "b/files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" deleted file mode 100644 index 02dc0d55e4..0000000000 --- "a/files/ko/web/javascript/reference/functions/\354\225\240\353\241\234\354\232\260_\355\216\221\354\205\230/index.html" +++ /dev/null @@ -1,465 +0,0 @@ ---- -title: 화살표 함수 -slug: Web/JavaScript/Reference/Functions/애로우_펑션 -tags: - - ECMAScript6 - - Functions - - Intermediate - - JavaScript - - Reference -translation_of: Web/JavaScript/Reference/Functions/Arrow_functions ---- -
{{jsSidebar("Functions")}}
- -

화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고  자신의 this, arguments, super 또는 new.target을 바인딩 하지 않습니다. 화살표 함수는 항상 익명입니다. 이  함수 표현은 메소드 함수가 아닌 곳에 가장 적합합니다. 그래서 생성자로서 사용할 수 없습니다.

- -

{{EmbedInteractiveExample("pages/js/functions-arrow.html")}}

- -

구문

- -

기본 구문

- -
(param1, param2, …, paramN) => { statements }
-(param1, param2, …, paramN) => expression
-// 다음과 동일함:  => { return expression; }
-
-// 매개변수가 하나뿐인 경우 괄호는 선택사항:
-(singleParam) => { statements }
-singleParam => { statements }
-
-// 매개변수가 없는 함수는 괄호가 필요:
-() => { statements }
- -

고급 구문

- -
// 객체 리터럴 표현을 반환하기 위해서는 함수 본문(body)을 괄호 속에 넣음:
-params => ({foo: bar})
-
-// 나머지 매개변수기본 매개변수를 지원함
-(param1, param2, ...rest) => { statements }
-(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }
-
-// 매개변수 목록 내 구조분해할당도 지원됨
-var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
-f();  // 6
-
- -

상세한 구문 예는 여기에서 볼 수 있습니다.

- -

설명

- -

Hacks 블로그 "ES6 In Depth: Arrow functions" 포스트 참조.

- -

화살표 함수 도입에 영향을 준 두 요소: 보다 짧아진 함수 및  바인딩하지 않은 this.

- -

짧은 함수

- -

일부 함수 패턴에서는, 짧은 함수가 환영받습니다. 비교해 보세요:

- -
var elements = [
-  'Hydrogen',
-  'Helium',
-  'Lithium',
-  'Beryllium'
-];
-
-// 이 문장은 배열을 반환함: [8, 6, 7, 9]
-elements.map(function(element) {
-  return element.length;
-});
-
-// 위의 일반적인 함수 표현은 아래 화살표 함수로 쓸 수 있다.
-elements.map((element) => {
-  return element.length;
-}); // [8, 6, 7, 9]
-
-// 파라미터가 하나만 있을 때는 주변 괄호를 생략할 수 있다.
-elements.map(element => {
-  return element.length;
-}); // [8, 6, 7, 9]
-
-// 화살표 함수의 유일한 문장이 'return'일 때 'return'과
-// 중괄호({})를 생략할 수 있다.
-elements.map(element => element.length); // [8, 6, 7, 9]
-
-// 이 경우 length 속성만 필요하므로 destructuring 매개변수를 사용할 수 있다.
-// 'length'는 우리가 얻고자 하는 속성에 해당하는 반면,
-// lengthFooBArX'는 변경 가능한 변수의 이름일 뿐이므로
-// 원하는 유효한 변수명으로 변경할 수 있다.
-elements.map(({ length: lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9]
-
-// destructuring 파라미터 할당도 아래와 같이 작성할 수 있습니다.
-// 이 예에서 정의한 객체내의 'length'에 값을 지정하지 않은 점에 주목하세요. 대신, "length" 변수의
-// 리터럴 이름은 우리가 해당 객체에서 꺼내오고 싶은 속성이름 자체로 사용됩니다.
-elements.map(({ length }) => length); // [8, 6, 7, 9] 
- -

바인딩 되지 않은 this

- -

화살표 함수가 나오기 전까지는, 모든 새로운 함수는, 어떻게 그 함수가 호출되는지에 따라  자신의 this 값을 정의했습니다:

- -
    -
  • 이 함수가 생성자인 경우는 새로운 객체
  • -
  • 엄격 모드 함수 호출에서는 undefined 
  • -
  • 함수가 "객체 메서드"로서 호출된 경우 문맥 객체
  • -
  • 등등
  • -
- -

이는 객체 지향 스타일로 프로그래밍할 때 별로 좋지않습니다.

- -
function Person() {
-  // Person() 생성자는 `this`를 자신의 인스턴스로 정의.
-  this.age = 0;
-
-  setInterval(function growUp() {
-    // 비엄격 모드에서, growUp() 함수는 `this`를
-    // 전역 객체로 정의하고, 이는 Person() 생성자에
-    // 정의된 `this`와 다름.
-    this.age++;
-  }, 1000);
-}
-
-var p = new Person();
- -

ECMAScript 3/5 에서는, 이 문제를 this 값을 폐쇄될 수 있는 (비전역) 변수에 할당하여 해결했습니다.

- -
function Person() {
-  var that = this;
-  that.age = 0;
-
-  setInterval(function growUp() {
-    // 콜백은  `that` 변수를 참조하고 이것은 값이 기대한 객체이다.
-    that.age++;
-  }, 1000);
-}
- -

이렇게 하는 대신에, 바인딩한 함수는 적절한 this 값이 growUp() 함수에 전달될 수 있도록 생성될 수 있습니다.

- -

화살표 함수는 자신의 this가 없습니다.  대신 화살표 함수를 둘러싸는 렉시컬 범위(lexical scope)의 this가 사용됩니다; 화살표 함수는 일반 변수 조회 규칙(normal variable lookup rules)을 따릅니다. 때문에 현재 범위에서 존재하지 않는 this를 찾을 때, 화살표 함수는 바로 바깥 범위에서 this를 찾는것으로 검색을 끝내게 됩니다.

- -

따라서 다음 코드에서 setInterval에 전달 된 함수 내부의 thissetInterval을 포함한 function의 this와 동일한 값을 갖습니다.

- -
function Person(){
-  this.age = 0;
-
-  setInterval(() => {
-    this.age++; // |this|는 Person 객체를 참조
-  }, 1000);
-}
-
-var p = new Person();
- -

엄격 모드와의 관계

- -

this가 렉시컬(lexical, 정적)임을 감안하면, this에 관한 엄격 모드 규칙은 그냥 무시됩니다.

- -
var f = () => { 'use strict'; return this; };
-f() === window; // 혹은 전역객체
- -

엄격 모드의 나머지 규칙은 평소대로 적용합니다.

- -

CORRECTION: START

- -

NOTE: the previous statement seems false.

- -

Strict mode should prevent creating global variables when assigning to an undeclared identifier in a function.

- -

This code sample using Chrome 81 demonstrates that arrow functions allow the creation of global variables in such situations (both for a concise body and for a normal function body):

- -
> f1 = x => { y = x; console.log(`x: ${x}, y: ${y}`); return x + 1; }
-x => { y = x; console.log(`x: ${x}, y: ${y}`); return x + 1; }
-
-> y
-VM51587:1 Uncaught ReferenceError: y is not defined
-    at <anonymous>:1:1
-(anonymous) @ VM51587:1
-
-> f1(3)
-VM51533:1 x: 3, y: 3
-4
-
-> y
-3
-
-> f2 = x => { 'use strict'; z = x; console.log(`x: ${x}, z: ${z}`); return x + 1; }
-x => { 'use strict'; z = x; console.log(`x: ${x}, z: ${z}`); return x + 1; }
-
-> z
-VM51757:1 Uncaught ReferenceError: z is not defined
-    at <anonymous>:1:1
-(anonymous) @ VM51757:1
-
-> f2(4)
-VM51712:1 Uncaught ReferenceError: z is not defined
-    at f2 (<anonymous>:1:29)
-    at <anonymous>:1:1
-f2 @ VM51712:1
-(anonymous) @ VM51800:1
-
-> f3 = x => (z1 = x + 1)
-x => (z1 = x + 1)
-
-> z1
-VM51891:1 Uncaught ReferenceError: z1 is not defined
-    at <anonymous>:1:1
-(anonymous) @ VM51891:1
-
-> f3(10)
-11
-
-> z1
-11
-
- -

f2 illustrates that when explicitly setting the arrow function to apply strict mode, it does throw an error when attempting to assign an undeclared variable.

- -

https://www.ecma-international.org/ecma-262/10.0/index.html#sec-strict-mode-code

- -

https://www.ecma-international.org/ecma-262/10.0/index.html#sec-arrow-function-definitions-runtime-semantics-evaluation

- -

CORRECTION: END

- -

call 또는 apply를 통한 피호출

- -

화살표 함수에서는 this가 바인딩되지 않았기 때문에, call() 또는 apply() 메서드는  인자만 전달 할 수 있습니다. this는 무시됩니다.

- -
var adder = {
-  base : 1,
-
-  add : function(a) {
-    var f = v => v + this.base;
-    return f(a);
-  },
-
-  addThruCall: function(a) {
-    var f = v => v + this.base;
-    var b = {
-      base : 2
-    };
-
-    return f.call(b, a);
-  }
-};
-
-console.log(adder.add(1));         // 이는 2가 콘솔에 출력될 것임
-console.log(adder.addThruCall(1)); // 이도 2가 콘솔에 출력될 것임
- -

바인딩 되지 않은 arguments

- -

화살표 함수는 arguments 객체를 바인드 하지 않습니다.  때문에, arguments는  그저 둘러싸는 범위(scope) 내 이름에 대한 참조입니다.

- -
var arguments = [1, 2, 3];
-var arr = () => arguments[0];
-
-arr(); // 1
-
-function foo(n) {
-  var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
-  return f();
-}
-
-foo(1); // 2
- -

화살표 함수는 자신의 arguments 객체가 없지만, 대부분의 경우에 나머지 매개변수가 좋은 대안입니다:

- -
function foo(n) {
-  var f = (...args) => args[0] + n;
-  return f(2);
-}
-
-foo(1); // 3
- -

메소드로 사용되는 화살표 함수

- -

이야기 했듯이, 화살표 함수 표현은 메소드 함수가 아닌 형태로 사용 할 수 있습니다. 메소드로 사용하려고 한면 무슨일이 발생하는지 봅시다.

- -
'use strict';
-
-var obj = { // does not create a new scope
-  i: 10,
-  b: () => console.log(this.i, this),
-  c: function() {
-    console.log( this.i, this)
-  }
-}
-obj.b(); // prints undefined, Window {...} (or the global object)
-obj.c(); // prints 10, Object {...}
-
- -

화살표 함수는 자신의 this를 가지고("bind" 바인드)있지 않습니다.{{jsxref("Object.defineProperty()")}}

- -
'use strict';
-
-var obj = {
-  a: 10
-};
-
-Object.defineProperty(obj, 'b', {
-  get: () => {
-    console.log(this.a, typeof this.a, this); // undefined 'undefined' Window {...} (or the global object)
-    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
-  }
-});
- -

new 연산자 사용

- -

화살표 함수는 생성자로서 사용될 수 없으며 new와 함께 사용하면 오류가 발생합니다.

- -
var Foo = () => {};
-var foo = new Foo(); // TypeError: Foo is not a constructor
- -

prototype 속성 사용

- -

화살표 함수는 prototype 속성이 없습니다.

- -
var Foo = () => {};
-console.log(Foo.prototype); // undefined
- -

yield 키워드 사용

- -

yield 키워드는 화살표 함수의 본문(그 안에 더 중첩된 함수 내에서 허용한 경우를 제외하고)에 사용될 수 없습니다. 그 결과, 화살표 함수는 생성기(generator)로서 사용될 수 없습니다.

- -

함수 본문

- -

화살표 함수는 "concise 바디"든 보통 "block 바디"든 하나를 가질 수 있습니다.

- -
-

concise바디는 중괄호'{}'로 묶이지않은 한줄짜리 바디이고 block바디는 중괄호로 묶인 바디입니다. 보통 여러줄 쓸때 block바디를 사용합니다.

-
- -

block바디는 자동으로 값을 반환하지 않습니다. return을 사용해서 값을 반환해야 합니다.

- -
var func = x => x * x;                  // concise 바디, 생략된 "return" 여기서는 x * x
-var func = (x, y) => { return x + y; }; // block 바디, "return"이 필요
-
- -

객체 리터럴 반환

- -

간결한 구문 params => {object:literal}을 사용한 객체 리터럴 반환은 예상대로 작동하지 않음을 명심하세요:

- -
var func = () => {  foo: 1  };
-// func() 호출은 undefined를 반환!
-
-var func = () => {  foo: function() {}  };
-// SyntaxError: function 문은 이름이 필요함
- -

이는 중괄호({}) 안 코드가 일련의 문(즉 foo는 라벨처럼 취급됩니다, 객체 리터럴 내 키가 아니라)으로 파싱(parse, 구문 분석)되기 때문입니다.

- -

객체 리터럴를 괄호로 감싸는 것을 기억하세요:

- -
var func = () => ({ foo: 1 });
- -

줄바꿈

- -

화살표 함수는 파라메터와 화살표 사이에 개행 문자를 포함 할 수 없습니다.

- -
var func = (a, b, c)
-           => 1;
-// SyntaxError: expected expression, got '=>'
- -

하지만, 보기 좋은 코드를 유지하고 싶다면, 아래에 보는 것처럼 괄호나 개행을 둠으로써 이를 수정할 수 있습니다.

- -
var func = (a, b, c) =>
-  1;
-
-var func = (a, b, c) => (
-  1
-);
-
-var func = (a, b, c) => {
-  return 1
-};
-
-var func = (
-  a,
-  b,
-  c
-) => 1;
-
-// SyntaxError가 발생하지 않습니다.
- -

파싱순서

- -

화살표 함수 내의 화살표는 연산자가 아닙니다. 그러나 화살표 함수는 평범한 함수와 비교했을 때 operator precedence와 다르게 반응하는 특별한 파싱룰을 가지고 있습니다.

- -
let callback;
-
-callback = callback || function() {}; // ok
-
-callback = callback || () => {};
-// SyntaxError: invalid arrow-function arguments
-
-callback = callback || (() => {});    // ok
-
- -

다른 예

- -

기본 사용법

- -
//  empty 화살표 함수는 undefined를 반환 
-let empty = () => {};
-
-(() => 'foobar')();
-// "foobar" 반환
-// (this is an Immediately Invoked Function Expression
-
-var simple = a => a > 15 ? 15 : a;
-simple(16); // 15
-simple(10); // 10
-
-let max = (a, b) => a > b ? a : b;
-
-// Easy array filtering, mapping, ...
-
-var arr = [5, 6, 13, 0, 1, 18, 23];
-
-var sum = arr.reduce((a, b) => a + b);
-// 66
-
-var even = arr.filter(v => v % 2 == 0);
-// [6, 0, 18]
-
-var double = arr.map(v => v * 2);
-// [10, 12, 26, 0, 2, 36, 46]
-
-// 더 간결한 promise 체인
-promise.then(a => {
-  // ...
-}).then(b => {
-  // ...
-});
-
-// 매개변수가 없는 경우에도 더 읽기 쉬움
-setTimeout( () => {
-  console.log('I happen sooner');
-  setTimeout( () => {
-    // deeper code
-    console.log('I happen later');
-  }, 1);
-}, 1);
- -

스펙

- - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}
- -

브라우저 호환성

- - - -

{{Compat("javascript.functions.arrow_functions")}}

- -

참조

- - diff --git a/files/ko/web/javascript/reference/global_objects/bigint/prototype/index.html b/files/ko/web/javascript/reference/global_objects/bigint/prototype/index.html deleted file mode 100644 index 6ba56eb37e..0000000000 --- a/files/ko/web/javascript/reference/global_objects/bigint/prototype/index.html +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: BigInt.prototype -slug: Web/JavaScript/Reference/Global_Objects/BigInt/prototype -tags: - - BigInt - - JavaScript - - Property - - Prototype - - Reference -translation_of: Web/JavaScript/Reference/Global_Objects/BigInt/prototype ---- -
{{JSRef}}
- -

BigInt.prototype 속성은 {{jsxref("BigInt")}} 생성자의 프로토타입을 나타냅니다.

- -

{{js_property_attributes(0, 0, 0)}}

- -

설명

- -

모든 {{jsxref("BigInt")}} 인스턴스는 BigInt.prototype을 상속합니다. BigInt 생성자의 프로토타입 객체를 변형해 모든 BigInt 인스턴스에 영향을 줄 수 있습니다.

- -

속성

- -
-
BigInt.prototype.constructor
-
이 객체의 인스턴스를 만들 때 사용한 함수를 반환합니다. 기본값은 {{jsxref("BigInt")}} 객체입니다.
-
- -

메서드

- -
-
BigInt.prototype.toLocaleString()
-
BigInt를 주어진 언어에 적합한 형태를 가진 문자열로 변환해 반환합니다. {{jsxref("Object.prototype.toLocaleString()")}} 메서드를 재정의합니다.
-
BigInt.prototype.toString()
-
BigInt의 값을 주어진 진수로 표현한 문자열을 반환합니다. {{jsxref("Object.prototype.toString()")}} 메서드를 재정의합니다.
-
BigInt.prototype.valueOf()
-
BigInt 객체의 원시 값 표현을 반환합니다. {{jsxref("Object.prototype.valueOf()")}} 메서드를 재정의합니다.
-
- -

명세

- - - - - - - - - - - - -
SpecificationStatus
BigInt.prototypeStage 3
- -

브라우저 호환성

- - - -

{{Compat("javascript.builtins.BigInt.prototype")}}

diff --git a/files/ko/web/javascript/reference/global_objects/boolean/prototype/index.html b/files/ko/web/javascript/reference/global_objects/boolean/prototype/index.html deleted file mode 100644 index 6e90207661..0000000000 --- a/files/ko/web/javascript/reference/global_objects/boolean/prototype/index.html +++ /dev/null @@ -1,82 +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)}}
- -
{{EmbedInteractiveExample("pages/js/boolean-constructor.html")}}
- - - -

설명

- -

{{jsxref("Boolean")}} 인스턴스는 Boolean.prototype을 상속받습니다. 생성자의 프로토타입 객체를 사용해 모든 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/ko/web/javascript/reference/global_objects/date/prototype/index.html b/files/ko/web/javascript/reference/global_objects/date/prototype/index.html deleted file mode 100644 index 06e1bba5f7..0000000000 --- a/files/ko/web/javascript/reference/global_objects/date/prototype/index.html +++ /dev/null @@ -1,183 +0,0 @@ ---- -title: Date.prototype -slug: Web/JavaScript/Reference/Global_Objects/Date/prototype -tags: - - Date - - JavaScript - - Property - - Prototype - - Reference -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)}}
- -

설명

- -

JavaScript {{jsxref("Date")}} 인스턴스는 Date.prototype을 상속합니다. 생성자의 프로토타입을 변경해 모든 Date 인스턴스의 속성과 메서드를 수정할 수 있습니다.

- -

2000년대 달력과의 호환성을 위해 연도는 언제나 완전하게 네 자리 숫자로 작성해야 합니다. 즉 98 대신 1998이 올바른 작성법입니다. Date는 완전한 연도 설정에 도움이 될 {{jsxref("Date.prototype.getFullYear()", "getFullYear()")}}, {{jsxref("Date.prototype.setFullYear()", "setFullYear()")}}, {{jsxref("Date.prototype.getUTCFullYear()", "getUTCFullYear()")}}, {{jsxref("Date.prototype.setUTCFullYear()", "setUTCFullYear()")}} 메서드를 가지고 있습니다.

- -

ECMAScript 6부터 Date.prototype은 {{jsxref("Date")}} 인스턴스가 아닌 평범한 객체입니다.

- -

속성

- -
-
Date.prototype.constructor
-
인스턴스 생성에 사용한 생성자를 반환합니다. 기본값은 {{jsxref("Date")}}입니다.
-
- -

메서드

- -

접근자

- -
-
{{jsxref("Date.prototype.getDate()")}}
-
주어진 날짜의 일(1-31)을 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getDay()")}}
-
주어진 날짜의 요일(0-6)을 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getFullYear()")}}
-
주어진 날짜의 연도(4자리 수)를 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getHours()")}}
-
주어진 날짜의 시(0-23)를 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getMilliseconds()")}}
-
주어진 날짜의 밀리초(0-999)를 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getMinutes()")}}
-
주어진 날짜의 분(0-59)을 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getMonth()")}}
-
주어진 날짜의 월(0-11)을 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getSeconds()")}}
-
주어진 날짜의 초(0-59)를 현지 시간에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getTime()")}}
-
주어진 날짜와 1970년 1월 1일 0시 0분(UTC)의 차이를 밀리초로 반환합니다.
-
{{jsxref("Date.prototype.getTimezoneOffset()")}}
-
현재 로케일의 시간대 차이를 분으로 환산해 반환합니다.
-
{{jsxref("Date.prototype.getUTCDate()")}}
-
주어진 날짜의 일(1-31)을 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getUTCDay()")}}
-
주어진 날짜의 요일(0-6)을 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getUTCFullYear()")}}
-
주어진 날짜의 연도(4자리 수)를 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getUTCHours()")}}
-
주어진 날짜의 시(0-23)를 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getUTCMilliseconds()")}}
-
주어진 날짜의 밀리초(0-999)를 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getUTCMinutes()")}}
-
주어진 날짜의 분(0-59)을 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getUTCMonth()")}}
-
주어진 날짜의 월(0-11)을 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getUTCSeconds()")}}
-
주어진 날짜의 초(0-59)를 UTC에 맞춰 반환합니다.
-
{{jsxref("Date.prototype.getYear()")}} {{deprecated_inline}}
-
주어진 날짜의 연도(주로 두세자리 숫자)를 현지 시간에 맞춰 반환합니다. {{jsxref("Date.prototype.getFullYear()", "getFullYear()")}}를 사용하세요.
-
- -

설정자

- -
-
{{jsxref("Date.prototype.setDate()")}}
-
Sets the day of the month for a specified date according to local time.
-
{{jsxref("Date.prototype.setFullYear()")}}
-
Sets the full year (e.g. 4 digits for 4-digit years) for a specified date according to local time.
-
{{jsxref("Date.prototype.setHours()")}}
-
Sets the hours for a specified date according to local time.
-
{{jsxref("Date.prototype.setMilliseconds()")}}
-
Sets the milliseconds for a specified date according to local time.
-
{{jsxref("Date.prototype.setMinutes()")}}
-
Sets the minutes for a specified date according to local time.
-
{{jsxref("Date.prototype.setMonth()")}}
-
Sets the month for a specified date according to local time.
-
{{jsxref("Date.prototype.setSeconds()")}}
-
Sets the seconds for a specified date according to local time.
-
{{jsxref("Date.prototype.setTime()")}}
-
Sets the {{jsxref("Date")}} object to the time represented by a number of milliseconds since January 1, 1970, 00:00:00 UTC, allowing for negative numbers for times prior.
-
{{jsxref("Date.prototype.setUTCDate()")}}
-
Sets the day of the month for a specified date according to universal time.
-
{{jsxref("Date.prototype.setUTCFullYear()")}}
-
Sets the full year (e.g. 4 digits for 4-digit years) for a specified date according to universal time.
-
{{jsxref("Date.prototype.setUTCHours()")}}
-
Sets the hour for a specified date according to universal time.
-
{{jsxref("Date.prototype.setUTCMilliseconds()")}}
-
Sets the milliseconds for a specified date according to universal time.
-
{{jsxref("Date.prototype.setUTCMinutes()")}}
-
Sets the minutes for a specified date according to universal time.
-
{{jsxref("Date.prototype.setUTCMonth()")}}
-
Sets the month for a specified date according to universal time.
-
{{jsxref("Date.prototype.setUTCSeconds()")}}
-
Sets the seconds for a specified date according to universal time.
-
{{jsxref("Date.prototype.setYear()")}} {{deprecated_inline}}
-
Sets the year (usually 2-3 digits) for a specified date according to local time. Use {{jsxref("Date.prototype.setFullYear()", "setFullYear()")}} instead.
-
- -

변환 접근자

- -
-
{{jsxref("Date.prototype.toDateString()")}}
-
Returns the "date" portion of the {{jsxref("Date")}} as a human-readable string like 'Thu Apr 12 2018'
-
{{jsxref("Date.prototype.toISOString()")}}
-
Converts a date to a string following the ISO 8601 Extended Format.
-
{{jsxref("Date.prototype.toJSON()")}}
-
Returns a string representing the {{jsxref("Date")}} using {{jsxref("Date.prototype.toISOString()", "toISOString()")}}. Intended for use by {{jsxref("JSON.stringify()")}}.
-
{{jsxref("Date.prototype.toGMTString()")}} {{deprecated_inline}}
-
Returns a string representing the {{jsxref("Date")}} based on the GMT (UT) time zone. Use {{jsxref("Date.prototype.toUTCString()", "toUTCString()")}} instead.
-
{{jsxref("Date.prototype.toLocaleDateString()")}}
-
Returns a string with a locality sensitive representation of the date portion of this date based on system settings.
-
{{jsxref("Date.prototype.toLocaleFormat()")}} {{non-standard_inline}}
-
Converts a date to a string, using a format string.
-
{{jsxref("Date.prototype.toLocaleString()")}}
-
Returns a string with a locality sensitive representation of this date. Overrides the {{jsxref("Object.prototype.toLocaleString()")}} method.
-
{{jsxref("Date.prototype.toLocaleTimeString()")}}
-
Returns a string with a locality sensitive representation of the time portion of this date based on system settings.
-
{{jsxref("Date.prototype.toSource()")}} {{non-standard_inline}}
-
Returns a string representing the source for an equivalent {{jsxref("Date")}} object; you can use this value to create a new object. Overrides the {{jsxref("Object.prototype.toSource()")}} method.
-
{{jsxref("Date.prototype.toString()")}}
-
Returns a string representing the specified {{jsxref("Date")}} object. Overrides the {{jsxref("Object.prototype.toString()")}} method.
-
{{jsxref("Date.prototype.toTimeString()")}}
-
Returns the "time" portion of the {{jsxref("Date")}} as a human-readable string.
-
{{jsxref("Date.prototype.toUTCString()")}}
-
Converts a date to a string using the UTC timezone.
-
{{jsxref("Date.prototype.valueOf()")}}
-
Returns the primitive value of a {{jsxref("Date")}} object. Overrides the {{jsxref("Object.prototype.valueOf()")}} method.
-
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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/ko/web/javascript/reference/global_objects/internalerror/prototype/index.html b/files/ko/web/javascript/reference/global_objects/internalerror/prototype/index.html deleted file mode 100644 index 6e13afb6db..0000000000 --- a/files/ko/web/javascript/reference/global_objects/internalerror/prototype/index.html +++ /dev/null @@ -1,101 +0,0 @@ ---- -title: InternalError.prototype -slug: Web/JavaScript/Reference/Global_Objects/InternalError/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/InternalError -translation_of_original: Web/JavaScript/Reference/Global_Objects/InternalError/prototype ---- -
{{JSRef}} {{non-standard_header}}
- -

InternalError.prototype 속성은 {{jsxref("InternalError")}} 생성자의 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0, 0, 0)}}
- -

설명

- -

모든 {{jsxref("InternalError")}} 인스턴스는 InternalError.prototype 으로부터 상속받습니다. 프로토타입은 모든 인스턴스에 속성이나 메소드를 추가하거나 하는 데에 사용할 수 있습니다.

- -

속성

- -
-
InternalError.prototype.constructor
-
인스턴스의 프로토타입을 생성하는 함수를 명시합니다. 
-
{{jsxref("Error.prototype.message", "InternalError.prototype.message")}}
-
에러 메시지. {{jsxref("Error")}} 로부터 상속받습니다. 
-
{{jsxref("Error.prototype.name", "InternalError.prototype.name")}}
-
에러명. {{jsxref("Error")}} 로부터 상속받습니다.
-
{{jsxref("Error.prototype.fileName", "InternalError.prototype.fileName")}}
-
에러를 발생시킨 파일의 경로. {{jsxref("Error")}} 로부터 상속받습니다.
-
{{jsxref("Error.prototype.lineNumber", "InternalError.prototype.lineNumber")}}
-
에러를 발생시킨 파일의 라인 넘버. {{jsxref("Error")}} 로부터 상속받습니다.
-
{{jsxref("Error.prototype.columnNumber", "InternalError.prototype.columnNumber")}}
-
에러를 발생 시킨 라인의 컬럼 넘버. {{jsxref("Error")}} 로부터 상속받습니다.
-
{{jsxref("Error.prototype.stack", "InternalError.prototype.stack")}}
-
스택 트레이스. {{jsxref("Error")}} 로부터 상속받습니다. 
-
- -

메소드

- -

비록 {{jsxref("InternalError")}}의 프로토타입 객체는 고유의 메소드를 가지고 있지는 않습니다. 하지만, {{jsxref("InternalError")}} 인스턴스는 프로토타입 체인을 통해 몇 가지의 메소드를 상속 받습니다.

- -

스펙

- -

Not part of any specifications.

- -

브라우저 호환성

- -
{{CompatibilityTable}}
- -
- - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -
- - - - - - - - - - - - - - - - - - - - - -
FeatureAndroidChrome for AndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{CompatVersionUnknown}}{{CompatNo}}{{CompatNo}}{{CompatNo}}
-
- -

참조

- -
    -
  • {{jsxref("Error.prototype")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html b/files/ko/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html deleted file mode 100644 index 2f1b031b39..0000000000 --- a/files/ko/web/javascript/reference/global_objects/intl/datetimeformat/prototype/index.html +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Intl.DateTimeFormat.prototype -slug: Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat/prototype -tags: - - DateTimeFormat - - Internationalization - - Intl - - JavaScript - - Property - - Prototype - - Reference -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)}}
- -

설명

- -

Intl.DateTimeFormat 인스턴스에 대한 설명은 {{jsxref("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()")}}
-
주어진 날짜에 {{jsxref("DateTimeFormat")}} 객체의 로케일과 서식 설정을 적용해 반환합니다.
-
- -
-
{{jsxref("DateTimeFormat.formatToParts", "Intl.DateTimeFormat.prototype.formatToParts()")}}
-
서식을 적용한 날짜 문자열의 각 부분을 객체로 표현해서 {{jsxref("Array")}}로 반환합니다. 반환 값은 로케일별 커스텀 서식에 사용할 수 있습니다.
-
{{jsxref("DateTimeFormat.resolvedOptions", "Intl.DateTimeFormat.prototype.resolvedOptions()")}}
-
객체 인스턴스 생성 때 주어진 로케일과 서식 설정이 어떻게 반영되었나 나타내는 새로운 객체를 반환합니다.
-
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES Int 1.0', '#sec-12.2.1', 'Intl.DateTimeFormat.prototype')}}{{Spec2('ES Int 1.0')}}Initial definition.
{{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')}}
- -

브라우저 호환성

- -
- - -

{{Compat("javascript.builtins.Intl.DateTimeFormat.prototype")}}

-
- -

같이 보기

- -
    -
  • {{jsxref("DateTimeFormat", "Intl.DateTimeFormat")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html b/files/ko/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html deleted file mode 100644 index fcbaa6c247..0000000000 --- a/files/ko/web/javascript/reference/global_objects/intl/numberformat/prototype/index.html +++ /dev/null @@ -1,86 +0,0 @@ ---- -title: Intl.NumberFormat.prototype -slug: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/prototype -tags: - - Internationalization - - Intl - - JavaScript - - NumberFormat - - Property - - Prototype -translation_of: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat -translation_of_original: Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/prototype ---- -
{{JSRef}}
- -

Intl.NumberFormat.prototype 속성은 {{jsxref("NumberFormat", "Intl.NumberFormat")}} 생성자의 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0, 0, 0)}}
- -

설명

- -

Intl.NumberFormat 인스턴스에 대한 설명은 {{jsxref("NumberFormat")}} 문서를 참고하세요.

- -

{{jsxref("NumberFormat", "Intl.NumberFormat")}} 인스턴스는 Intl.NumberFormat.prototype을 상속합니다. 프로토타입 객체를 변형하면 모든 {{jsxref("NumberFormat", "Intl.NumberFormat")}} 인스턴스가 영향을 받습니다.

- -

속성

- -
-
Intl.NumberFormat.prototype.constructor
-
Intl.NumberFormat에 대한 참조입니다.
-
- -

메서드

- -
-
{{jsxref("NumberFormat.format", "Intl.NumberFormat.prototype.format()")}}
-
주어진 숫자에 {{jsxref("NumberFormat")}} 객체의 로케일과 서식 설정을 적용해 반환합니다.
-
- -
-
{{jsxref("NumberFormat.formatToParts", "Intl.NumberFormat.prototype.formatToParts()")}}
-
서식을 적용한 숫자의 각 부분을 객체로 표현해서 {{jsxref("Array")}}로 반환합니다. 반환 값은 로케일별 커스텀 서식에 사용할 수 있습니다.
-
{{jsxref("NumberFormat.resolvedOptions", "Intl.NumberFormat.prototype.resolvedOptions()")}}
-
객체 인스턴스 생성 때 주어진 로케일과 콜레이션 설정이 어떻게 반영되었나 나타내는 새로운 객체를 반환합니다.
-
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES Int 1.0', '#sec-11.2.1', 'Intl.NumberFormat.prototype')}}{{Spec2('ES Int 1.0')}}Initial definition.
{{SpecName('ES Int 2.0', '#sec-11.2.1', 'Intl.NumberFormat.prototype')}}{{Spec2('ES Int 2.0')}}
{{SpecName('ES Int Draft', '#sec-Intl.NumberFormat.prototype', 'Intl.NumberFormat.prototype')}}{{Spec2('ES Int Draft')}}
- -

브라우저 호환성

- -
- - -

{{Compat("javascript.builtins.Intl.NumberFormat.prototype")}}

-
- -

같이 보기

- -
    -
  • {{jsxref("NumberFormat", "Intl.NumberFormat")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/map/prototype/index.html b/files/ko/web/javascript/reference/global_objects/map/prototype/index.html deleted file mode 100644 index 3445bf2847..0000000000 --- a/files/ko/web/javascript/reference/global_objects/map/prototype/index.html +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Map.prototype -slug: Web/JavaScript/Reference/Global_Objects/Map/prototype -tags: - - ECMAScript 2015 - - JavaScript - - Map - - Property - - Reference -translation_of: Web/JavaScript/Reference/Global_Objects/Map -translation_of_original: Web/JavaScript/Reference/Global_Objects/Map/prototype ---- -
{{JSRef}}
- -

Map.prototype property는 {{jsxref("Map")}}의 프로토 타입을 나타낸다.

- -
{{js_property_attributes(0,0,0)}}
- -

Description

- -

{{jsxref("Map")}} instance는 {{jsxref("Map.prototype")}}를 상속한다. Constructor의 프로토타입에 property와 method를 추가함으로써 모든 Map 인스턴스에서 사용 가능하게끔 만들 수 있다.

- -

Properties

- -
-
Map.prototype.constructor
-
인스턴스의 프로토타입을 만드는 함수를 반환한다. 이것 {{jsxref("Map")}} 함수의 기본 값이다.
-
{{jsxref("Map.prototype.size")}}
-
Map 객체에 들어있는 key/value pair의 수를 반환한다.
-
- -

Methods

- -
-
{{jsxref("Map.prototype.clear()")}}
-
Map 객체의 모든 key/value pair를 제거한다.
-
{{jsxref("Map.delete", "Map.prototype.delete(key)")}}
-
주어진 키(Key)와 해당되는 값(Value)를 제거하고 제거하기 전에 Map.prototype.has(key)가 반환했던 값을 반환한다. 그 후의 Map.prototype.has(key)는 false를 반환한다.
-
{{jsxref("Map.prototype.entries()")}}
-
Map 객체 안의 모든 요소들을 [key, value] 형태의 array 로 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.
-
{{jsxref("Map.forEach", "Map.prototype.forEach(callbackFn[, thisArg])")}}
-
Map 객체 안에 존재하는 각각의 key/value pair에 집어넣은 순서대로 callbackFn을 부른다. 만약 thisArg 매개변수가 제공되면, 이것이 각 callback의 this 값으로 사용된다.
-
{{jsxref("Map.get", "Map.prototype.get(key)")}}
-
주어진 키(Key)에 해당되는 값(value)을 반환하고, 만약 없으면 undefined를 반환한다.
-
{{jsxref("Map.has", "Map.prototype.has(key)")}}
-
Map 객체 안에 주어진 key/value pair가 있는지 검사하고 Boolean 값을 반환한다.
-
{{jsxref("Map.prototype.keys()")}}
-
Map 객체 안의 모든 키(Key)들을 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.
-
{{jsxref("Map.set", "Map.prototype.set(key, value)")}}
-
Map 객체에 주어진 키(Key)에 값(Value)를 집어넣고, Map 객체를 반환한다.
-
{{jsxref("Map.prototype.values()")}}
-
Map 객체 안의 모든 (Value)들을 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.
-
{{jsxref("Map.@@iterator", "Map.prototype[@@iterator]()")}}
-
Map 객체 안의 모든 요소들을 [key, value] 형태의 array 로 집어넣은 순서대로 가지고 있는 Iterator 객체를 반환한다.
-
- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-map.prototype', 'Map.prototype')}}{{Spec2('ESDraft')}} 
- -

Browser compatibility

- -

{{Compat("javascript.builtins.Map.prototype")}}

- -

See also

- -
    -
  • {{jsxref("Set.prototype")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/number/prototype/index.html b/files/ko/web/javascript/reference/global_objects/number/prototype/index.html deleted file mode 100644 index 2bf39d20f9..0000000000 --- a/files/ko/web/javascript/reference/global_objects/number/prototype/index.html +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Number.prototype -slug: Web/JavaScript/Reference/Global_Objects/Number/prototype -tags: - - JavaScript - - Number - - Property - - Prototype - - Reference -translation_of: Web/JavaScript/Reference/Global_Objects/Number -translation_of_original: Web/JavaScript/Reference/Global_Objects/Number/prototype ---- -
{{JSRef}}
- -

Number.prototype 속성은 {{jsxref("Number")}} 생성자의 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0, 0, 0)}}
- -

설명

- -

모든 {{jsxref("Number")}} 인스턴스는 Number.prototype을 상속합니다. {{jsxref("Number")}} 생성자의 프로토타입 객체는 모든 {{jsxref( "Number")}} 인스턴스에 영향을 미치도록 수정할 수 있습니다.

- -

속성

- -
-
Number.prototype.constructor
-
이 객체의 인스턴스를 생성한 함수를 반환합니다. 기본적으로 {{jsxref("Number")}} 객체 입니다.
-
- -

메서드

- -
-
{{jsxref("Number.prototype.toExponential()")}}
-
숫자의 지수표기법 표현을 문자열로 반환합니다.
-
{{jsxref("Number.prototype.toFixed()")}}
-
숫자의 고정소수점 표현을 문자열로 반환합니다.
-
{{jsxref("Number.prototype.toLocaleString()")}}
-
숫자의 표현을 특정 언어에 맞춘 형식의 문자열로 반환합니다. {{jsxref("Object.prototype.toLocaleString()")}} 메서드를 오버라이드 합니다.
-
{{jsxref("Number.prototype.toPrecision()")}}
-
지정한 정밀도로 숫자를 나타내는 문자열을 반환합니다. 고정소수점 혹은 지수표기법으로 표현합니다.
-
{{jsxref("Number.prototype.toSource()")}} {{non-standard_inline}}
-
지정한 {{jsxref("Number")}} 객체를 나타내는 객체 리터럴을 반환합니다. 이 값을 사용하여 새 객체를 만들 수 있습니다. {{jsxref("Object.prototype.toSource()")}} 메서드를 오버라이드 합니다.
-
{{jsxref("Number.prototype.toString()")}}
-
지정된 기수(기본 10진수)로 지정된 객체를 문자열로 반환합니다. {{jsxref("Object.prototype.toString()")}} 메서드를 오버라이드 합니다.
-
{{jsxref("Number.prototype.valueOf()")}}
-
지정한 객체의 기본 자료형(primitive) 값을 반환합니다. {{jsxref("Object.prototype.valueOf()")}} 메서드를 오버라이드 합니다.
-
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES1')}}{{Spec2('ES1')}}Initial definition. Implemented in JavaScript 1.1.
{{SpecName('ES5.1', '#sec-15.7.4', 'Number')}}{{Spec2('ES5.1')}} 
{{SpecName('ES6', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ES6')}} 
{{SpecName('ESDraft', '#sec-properties-of-the-number-prototype-object', 'Number')}}{{Spec2('ESDraft')}} 
- -

브라우저 호환성

- - - -

{{Compat("javascript.builtins.Number.prototype")}}

- -

같이 보기

- -
    -
  • {{jsxref("Number")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/object/prototype/index.html b/files/ko/web/javascript/reference/global_objects/object/prototype/index.html deleted file mode 100644 index 8f7b08793f..0000000000 --- a/files/ko/web/javascript/reference/global_objects/object/prototype/index.html +++ /dev/null @@ -1,219 +0,0 @@ ---- -title: Object.prototype -slug: Web/JavaScript/Reference/Global_Objects/Object/prototype -tags: - - JavaScript - - Object - - Property - - Reference - - 프로토타입 -translation_of: Web/JavaScript/Reference/Global_Objects/Object -translation_of_original: Web/JavaScript/Reference/Global_Objects/Object/prototype ---- -
{{JSRef}}
- -

Object.prototype 속성은 {{jsxref("Object")}} 프로토타입(원형) 객체를
- 나타냅니다.

- -
{{js_property_attributes(0, 0, 0)}}
- -

설명

- -

JavaScript에서 거의 모든 객체는 {{jsxref("Object")}}의 인스턴스입니다. 일반적인 객체는 Object.prototype 에서 속성과 메서드를 상속받으며, 그 중 일부는 (오버라이드 등으로 인해) 숨겨질 수 있습니다. 그러나, 의도적으로 Object를 생성할 때 ({{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__")}} {{obsolete_inline}}
-
정의되지 않은 객체 멤버가 메소드로서 호출될 때 실행되는 함수를 정의하는 데 쓰였지만 제거되었습니다.
-
{{jsxref("Object.prototype.count","Object.prototype.__count__")}} {{obsolete_inline}}
-
사용자 정의 객체 상에 직접 있는 열거가능 속성의 수를 반환하는 데 쓰였지만 제거되었습니다.
-
{{jsxref("Object.prototype.parent","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.prototype.__defineGetter__()", "__defineGetter__()")}} 메소드에 의해 지정된 속성과 관련된 함수를 반환합니다.
-
{{jsxref("Object.prototype.__lookupSetter__()")}} {{non-standard_inline}} {{deprecated_inline}}
-
{{jsxref("Object.prototype.__defineSetter__()", "__defineSetter__()")}} 메소드에 의해 지정된 속성과 관련된 함수를 반환합니다.
-
{{jsxref("Object.prototype.hasOwnProperty()")}}
-
객체가 지정된 속성을 프로토타입 체인을 통해 상속되지 않은 그 객체의 직접 속성으로 포함하는지를 나타내는 boolean을 반환합니다.
-
{{jsxref("Object.prototype.isPrototypeOf()")}}
-
지정된 객체가 이 메소드가 호출된 객체의 프로토타입 체인 내에 있는지를 나타내는 boolean을 반환합니다.
-
{{jsxref("Object.prototype.propertyIsEnumerable()")}}
-
내부 ECMAScript [[Enumerable]] attribute가 설정된 경우를 나타내는 boolean을 반환합니다.
-
{{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의 기본 메서드를 변경할 때, 기존 조직의 앞 또는 후에 확장(extension) 을 포장하여 코드를 주입시키는 것을 고려하자. 예를 들어서, 이 (시험받지
- 않은) 코드는 내장된 로직 또는 어떤 다른 확장이 실행되기 전에 커스텀 로직을 전제조건적으로 실행시킬 것이다.

- -

함수가 호출되었을 때, 불러온 매개변수들은 배열과 같은 형태로 '변수' arguments에 보관된다. 예를 들어 myFn(a, b, c) 라는 함수를 부를 때, 이 함수 내부에 배열형태로 매개변수 (a, b, c) 를 담게 된다. prototype을 훅을 이용해 수정할 때, 함수에서 apply()를 호출하여 단순하게 this와 arguments(호출 상태)에 현재 동작을 전달하면 된다. 이 패턴은 Node.prototype, Function.prototype등 prototype에도 사용할 수 있다.

- -
var current = Object.prototype.valueOf;
-
-// 현재 설정한 "-prop-value" 속성은 cross-cutting 이고 
-// 항상 같은 prototype chain이 아니기 때문에, 이 Object.prototype을 바꾸고 싶다.
-Object.prototype.valueOf = function() {
-  if (this.hasOwnProperty('-prop-value')) {
-    return this['-prop-value'];
-  } else {
-    // 이 객체 내 속성(property)이 하나가 아니라면, 현재 동작을 재구성한 것으로부터
-    // 기본 동작으로 되돌리자(복구). 
-    // apply 동작은 다른 언어에서의 "super"와 유사하다.
-    // 비록 valueOf()가 매개변수를 받지못하더라도, 다른 훅에서 있을 것이다.
-    return current.apply(this, arguments);
-  }
-}
-
- -

JavaScript는 엄밀히 말해서 하위클래스(sub-class) 객체가 없기에, prototype은 객체 역할을 하는 특정 함수의 "기반 클래스" 객체를 만드는 유용한 차선책입니다. 예를 들어:

- -
var Person = function() {
-  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);
-  this.name = name;
-  this.title = title;
-};
-
-Employee.prototype = Object.create(Person.prototype);
-Employee.prototype.constructor = Employee;
-
-Employee.prototype.greet = function() {
-  if (this.canTalk) {
-    console.log('Hi, I am ' + this.name + ', the ' + this.title);
-  }
-};
-
-var Customer = function(name) {
-  Person.call(this);
-  this.name = name;
-};
-
-Customer.prototype = Object.create(Person.prototype);
-Customer.prototype.constructor = Customer;
-
-var Mime = function(name) {
-  Person.call(this);
-  this.name = name;
-  this.canTalk = false;
-};
-
-Mime.prototype = Object.create(Person.prototype);
-Mime.prototype.constructor = Mime;
-
-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();
-
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
스펙상태설명
{{SpecName('ES1')}}{{Spec2('ES1')}}초기 정의. 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")}}

- -

참조

- - - -
-
<dicword style="user-select: text;">Even though valueOf() doesn't take arguments, some other hook may.</dicword><dicword style="user-select: text;"><dicimg id="play" style="background-image: url(chrome-extension://bmbdcffdhebhecemcchbkfnjlmdiiepe/play.gif);"></dicimg> Eng<dicimg id="copy" style="background-image: url(chrome-extension://bmbdcffdhebhecemcchbkfnjlmdiiepe/copy.png);" title="copy"></dicimg></dicword>
-
-
-
-valueOf ()가 인수를받지 않더라도 다른 후크가있을 수 있습니다.
- -
-
- - - -
diff --git a/files/ko/web/javascript/reference/global_objects/promise/prototype/index.html b/files/ko/web/javascript/reference/global_objects/promise/prototype/index.html deleted file mode 100644 index 2e393d68d3..0000000000 --- a/files/ko/web/javascript/reference/global_objects/promise/prototype/index.html +++ /dev/null @@ -1,72 +0,0 @@ ---- -title: Promise.prototype -slug: Web/JavaScript/Reference/Global_Objects/Promise/prototype -tags: - - JavaScript - - Promise - - Property - - Reference -translation_of: Web/JavaScript/Reference/Global_Objects/Promise -translation_of_original: Web/JavaScript/Reference/Global_Objects/Promise/prototype ---- -
{{JSRef}}
- -

Promise.prototype 속성은 {{jsxref("Promise")}} 생성자의 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0,0,0)}}
- -

설명

- -

{{jsxref("Promise")}} 인스턴스는 {{jsxref("Promise.prototype")}}을 상속합니다. 모든 Promise 인스턴스에 속성 또는 메서드를 추가하기 위해 생성자의 프로토타입 객체를 사용할 수 있습니다.

- -

속성

- -
-
Promise.prototype.constructor
-
인스턴스의 프로토타입을 만드는 함수를 반환합니다. 기본값은 {{jsxref("Promise")}} 함수입니다.
-
- -

메서드

- -
-
{{jsxref("Promise.prototype.catch()")}}
-
프로미스(promise)에 거부 처리기 콜백을 추가하고 호출된 경우 콜백의 반환값 또는 프로미스가 대신 이행된 경우 그 원래 이행(fulfillment)값으로 결정하는(resolving) 새 프로미스를 반환합니다.
-
{{jsxref("Promise.prototype.then()")}}
-
프로미스에 이행 또는 거부 처리기를 추가하고 호출된 처리기의 반환값 또는 프로미스가 처리되지 않은 경우 그 원래 처리된(settled) 값으로 결정하는 새 프로미스를 반환합니다 (즉 관련 처리기 onFulfilled 또는 onRejectedundefined인 경우).
-
{{jsxref("Promise.prototype.finally()")}}
-
Appends a handler to the promise, and returns a new promise which is resolved when the original promise is resolved. The handler is called when the promise is settled, whether fulfilled or rejected.
-
- -

명세

- - - - - - - - - - - - - - - - - - - -
명세상태설명
{{SpecName('ES6', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ESDraft', '#sec-promise.prototype', 'Promise.prototype')}}{{Spec2('ESDraft')}} 
- -

브라우저 호환성

- - - -

{{Compat("javascript.builtins.Promise.prototype")}}

- -

같이 보기

- -
    -
  • {{jsxref("Promise")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/proxy/handler/apply/index.html b/files/ko/web/javascript/reference/global_objects/proxy/handler/apply/index.html deleted file mode 100644 index b4928da1d8..0000000000 --- a/files/ko/web/javascript/reference/global_objects/proxy/handler/apply/index.html +++ /dev/null @@ -1,154 +0,0 @@ ---- -title: handler.apply() -slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply -tags: - - apply트랩 - - 트랩 - - 프록시 -translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply ---- -
{{JSRef}}
- -

handler.apply() 메소드는 함수호출 시를 위한 트랩(trap)이다.

- -

문법

- -
var p = new Proxy(target, {
-  apply: function(target, thisArg, argumentsList) {
-  }
-});
-
- -

인자

- -

apply 메소드에는 다음과 같은 인자가 들어온다.. this는 handler를 가리킨다.

- -
-
target
-
대상이 되는 객체(함수)
-
thisArg
-
호출 시 바인딩 된 this
-
argumentsList
-
호출 시 전달된 인자목록.
-
- -

반환 값

- -

apply 메소드는 어떤 값이든 반환할 수 있다.

- -

설명

- -

handler.apply 메소드는 함수호출 시를 위한 트랩이다.

- -

가로채기

- -

이 트랩은 다음과 같은 것들을 가로챌 수 있다:

- -
    -
  • proxy(...args)
  • -
  • {{jsxref("Function.prototype.apply()")}} 와 {{jsxref("Function.prototype.call()")}}
  • -
  • {{jsxref("Reflect.apply()")}}
  • -
- -

기본(불변)조건

- -

handler.apply 메소드에 대한 특별히 지켜야 할 기본조건은 없다.

- -

예제

- -

다음의 코드는 함수 호출 시에 트랩을 건다.

- -
var p = new Proxy(function() {}, {
-  apply: function(target, thisArg, argumentsList) {
-    console.log('호출됨: ' + argumentsList.join(', '));
-    return argumentsList[0] + argumentsList[1] + argumentsList[2];
-  }
-});
-
-console.log(p(1, 2, 3)); // "호출됨: 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')}} 
- -

브라우저별 호환성

- -
{{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("Function.prototype.apply")}}
  • -
  • {{jsxref("Function.prototype.call")}}
  • -
  • {{jsxref("Reflect.apply()")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/proxy/handler/index.html b/files/ko/web/javascript/reference/global_objects/proxy/handler/index.html deleted file mode 100644 index d153c621c6..0000000000 --- a/files/ko/web/javascript/reference/global_objects/proxy/handler/index.html +++ /dev/null @@ -1,82 +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}}
- -

The proxy's handler object is a placeholder object which contains traps for {{jsxref("Proxy", "proxies", "", 1)}}.

- -

Methods

- -

All traps are optional. If a trap has not been defined, the default behavior is to forward the operation to the target.

- -
-
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
-
A trap for {{jsxref("Object.getPrototypeOf")}}.
-
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
-
A trap for {{jsxref("Object.setPrototypeOf")}}.
-
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
-
A trap for {{jsxref("Object.isExtensible")}}.
-
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
-
A trap for {{jsxref("Object.preventExtensions")}}.
-
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
-
A trap for {{jsxref("Object.getOwnPropertyDescriptor")}}.
-
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
-
A trap for {{jsxref("Object.defineProperty")}}.
-
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
-
A trap for the {{jsxref("Operators/in", "in")}} operator.
-
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
-
A trap for getting property values.
-
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
-
A trap for setting property values.
-
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
-
A trap for the {{jsxref("Operators/delete", "delete")}} operator.
-
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
-
A trap for {{jsxref("Object.getOwnPropertyNames")}} and {{jsxref("Object.getOwnPropertySymbols")}}.
-
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
-
A trap for a function call.
-
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
-
A trap for the {{jsxref("Operators/new", "new")}} operator.
-
- -

Some non-standard traps are obsolete and have been removed.

- -

Specifications

- - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ESDraft')}}The enumerate handler has been removed.
- -

Browser compatibility

- - - -

{{Compat("javascript.builtins.Proxy.handler")}}

- -

See also

- -
    -
  • {{jsxref("Proxy")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/proxy/proxy/apply/index.html b/files/ko/web/javascript/reference/global_objects/proxy/proxy/apply/index.html new file mode 100644 index 0000000000..b4928da1d8 --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/proxy/proxy/apply/index.html @@ -0,0 +1,154 @@ +--- +title: handler.apply() +slug: Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply +tags: + - apply트랩 + - 트랩 + - 프록시 +translation_of: Web/JavaScript/Reference/Global_Objects/Proxy/Proxy/apply +--- +
{{JSRef}}
+ +

handler.apply() 메소드는 함수호출 시를 위한 트랩(trap)이다.

+ +

문법

+ +
var p = new Proxy(target, {
+  apply: function(target, thisArg, argumentsList) {
+  }
+});
+
+ +

인자

+ +

apply 메소드에는 다음과 같은 인자가 들어온다.. this는 handler를 가리킨다.

+ +
+
target
+
대상이 되는 객체(함수)
+
thisArg
+
호출 시 바인딩 된 this
+
argumentsList
+
호출 시 전달된 인자목록.
+
+ +

반환 값

+ +

apply 메소드는 어떤 값이든 반환할 수 있다.

+ +

설명

+ +

handler.apply 메소드는 함수호출 시를 위한 트랩이다.

+ +

가로채기

+ +

이 트랩은 다음과 같은 것들을 가로챌 수 있다:

+ +
    +
  • proxy(...args)
  • +
  • {{jsxref("Function.prototype.apply()")}} 와 {{jsxref("Function.prototype.call()")}}
  • +
  • {{jsxref("Reflect.apply()")}}
  • +
+ +

기본(불변)조건

+ +

handler.apply 메소드에 대한 특별히 지켜야 할 기본조건은 없다.

+ +

예제

+ +

다음의 코드는 함수 호출 시에 트랩을 건다.

+ +
var p = new Proxy(function() {}, {
+  apply: function(target, thisArg, argumentsList) {
+    console.log('호출됨: ' + argumentsList.join(', '));
+    return argumentsList[0] + argumentsList[1] + argumentsList[2];
+  }
+});
+
+console.log(p(1, 2, 3)); // "호출됨: 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')}} 
+ +

브라우저별 호환성

+ +
{{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("Function.prototype.apply")}}
  • +
  • {{jsxref("Function.prototype.call")}}
  • +
  • {{jsxref("Reflect.apply()")}}
  • +
diff --git a/files/ko/web/javascript/reference/global_objects/proxy/proxy/index.html b/files/ko/web/javascript/reference/global_objects/proxy/proxy/index.html new file mode 100644 index 0000000000..d153c621c6 --- /dev/null +++ b/files/ko/web/javascript/reference/global_objects/proxy/proxy/index.html @@ -0,0 +1,82 @@ +--- +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}}
+ +

The proxy's handler object is a placeholder object which contains traps for {{jsxref("Proxy", "proxies", "", 1)}}.

+ +

Methods

+ +

All traps are optional. If a trap has not been defined, the default behavior is to forward the operation to the target.

+ +
+
{{jsxref("Global_Objects/Proxy/handler/getPrototypeOf", "handler.getPrototypeOf()")}}
+
A trap for {{jsxref("Object.getPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/setPrototypeOf", "handler.setPrototypeOf()")}}
+
A trap for {{jsxref("Object.setPrototypeOf")}}.
+
{{jsxref("Global_Objects/Proxy/handler/isExtensible", "handler.isExtensible()")}}
+
A trap for {{jsxref("Object.isExtensible")}}.
+
{{jsxref("Global_Objects/Proxy/handler/preventExtensions", "handler.preventExtensions()")}}
+
A trap for {{jsxref("Object.preventExtensions")}}.
+
{{jsxref("Global_Objects/Proxy/handler/getOwnPropertyDescriptor", "handler.getOwnPropertyDescriptor()")}}
+
A trap for {{jsxref("Object.getOwnPropertyDescriptor")}}.
+
{{jsxref("Global_Objects/Proxy/handler/defineProperty", "handler.defineProperty()")}}
+
A trap for {{jsxref("Object.defineProperty")}}.
+
{{jsxref("Global_Objects/Proxy/handler/has", "handler.has()")}}
+
A trap for the {{jsxref("Operators/in", "in")}} operator.
+
{{jsxref("Global_Objects/Proxy/handler/get", "handler.get()")}}
+
A trap for getting property values.
+
{{jsxref("Global_Objects/Proxy/handler/set", "handler.set()")}}
+
A trap for setting property values.
+
{{jsxref("Global_Objects/Proxy/handler/deleteProperty", "handler.deleteProperty()")}}
+
A trap for the {{jsxref("Operators/delete", "delete")}} operator.
+
{{jsxref("Global_Objects/Proxy/handler/ownKeys", "handler.ownKeys()")}}
+
A trap for {{jsxref("Object.getOwnPropertyNames")}} and {{jsxref("Object.getOwnPropertySymbols")}}.
+
{{jsxref("Global_Objects/Proxy/handler/apply", "handler.apply()")}}
+
A trap for a function call.
+
{{jsxref("Global_Objects/Proxy/handler/construct", "handler.construct()")}}
+
A trap for the {{jsxref("Operators/new", "new")}} operator.
+
+ +

Some non-standard traps are obsolete and have been removed.

+ +

Specifications

+ + + + + + + + + + + + + + + + + + + +
SpecificationStatusComment
{{SpecName('ES2015', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ES2015')}}Initial definition.
{{SpecName('ESDraft', '#sec-proxy-object-internal-methods-and-internal-slots', 'Proxy Object Internal Methods and Internal Slots')}}{{Spec2('ESDraft')}}The enumerate handler has been removed.
+ +

Browser compatibility

+ + + +

{{Compat("javascript.builtins.Proxy.handler")}}

+ +

See also

+ +
    +
  • {{jsxref("Proxy")}}
  • +
diff --git a/files/ko/web/javascript/reference/global_objects/set/prototype/index.html b/files/ko/web/javascript/reference/global_objects/set/prototype/index.html deleted file mode 100644 index 8183d348a9..0000000000 --- a/files/ko/web/javascript/reference/global_objects/set/prototype/index.html +++ /dev/null @@ -1,87 +0,0 @@ ---- -title: Set.prototype -slug: Web/JavaScript/Reference/Global_Objects/Set/prototype -tags: - - ECMAScript 2015 - - JavaScript - - Property - - Reference - - set -translation_of: Web/JavaScript/Reference/Global_Objects/Set -translation_of_original: Web/JavaScript/Reference/Global_Objects/Set/prototype ---- -
{{JSRef}}
- -

Set.prototype 속성은 {{jsxref("Set")}} 생성자의 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0,0,0)}}
- -

설명

- -

{{jsxref("Set")}} 인스턴스는 {{jsxref("Set.prototype")}}에서 상속합니다. 모든 Set 인스턴스에 속성 또는 메서드를 추가하기 위해 생성자의 프로토타입 객체를 사용할 수 있습니다.

- -

속성

- -
-
Set.prototype.constructor
-
인스턴스의 프로토타입을 만든 함수를 반환합니다. 이는 기본으로 {{jsxref("Set")}} 함수입니다.
-
{{jsxref("Set.prototype.size")}}
-
Set 객체 내 값의 개수를 반환합니다.
-
- -

메서드

- -
-
{{jsxref("Set.add", "Set.prototype.add(value)")}}
-
Set 객체에 주어진 값을 갖는 새로운 요소를 추가합니다. Set 객체를 반환합니다.
-
{{jsxref("Set.prototype.clear()")}}
-
Set 객체에서 모든 요소를 제거합니다.
-
{{jsxref("Set.delete", "Set.prototype.delete(value)")}}
-
value와 관련된 요소를 제거하고 Set.prototype.has(value)가 이전에 반환했던 값을 반환합니다. Set.prototype.has(value)는 그 뒤에 false를 반환합니다.
-
{{jsxref("Set.prototype.entries()")}}
-
삽입 순으로 Set 객체 내 각 값에 대한 [value, value] 배열을 포함하는 새로운 Iterator 객체를 반환합니다. 이는 Map 객체와 비슷하게 유지되므로 여기서 각 항목은 그 keyvalue에 대해 같은 값을 갖습니다.
-
{{jsxref("Set.forEach", "Set.prototype.forEach(callbackFn[, thisArg])")}}
-
삽입 순으로 Set 객체 내에 있는 각 값에 대해 한 번 callbackFn을 호출합니다. thisArg 매개변수가 forEach에 제공된 경우, 이는 각 콜백에 대해 this 값으로 사용됩니다.
-
{{jsxref("Set.has", "Set.prototype.has(value)")}}
-
Set 객체 내 주어진 값을 갖는 요소가 있는지를 주장하는(asserting, 나타내는) boolean을 반환합니다.
-
{{jsxref("Set.prototype.keys()")}}
-
values() 함수와 같은 함수로 삽입 순으로 Set 객체 내 각 요소에 대한 값을 포함하는 새로운 Iterator 객체를 반환합니다.
-
{{jsxref("Set.prototype.values()")}}
-
삽입 순으로 Set 객체 내 각 요소에 대한 을 포함하는 새로운 Iterator 객체를 반환합니다.
-
{{jsxref("Set.prototype.@@iterator()", "Set.prototype[@@iterator]()")}}
-
삽입 순으로 Set 객체 내 각 요소에 대한 을 포함하는 새로운 Iterator 객체를 반환합니다.
-
- -

명세

- - - - - - - - - - - - - - - - - - - -
명세상태설명
{{SpecName('ES6', '#sec-set.prototype', 'Set.prototype')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ESDraft', '#sec-set.prototype', 'Set.prototype')}}{{Spec2('ESDraft')}} 
- -

브라우저 호환성

- - - -

{{Compat("javascript.builtins.Set.prototype")}}

- -

같이 보기

- -
    -
  • {{jsxref("Map.prototype")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html b/files/ko/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html deleted file mode 100644 index 849b70c1c6..0000000000 --- a/files/ko/web/javascript/reference/global_objects/sharedarraybuffer/prototype/index.html +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: SharedArrayBuffer.prototype -slug: Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/prototype -tags: - - JavaScript - - SharedArrayBuffer - - TypedArrays - - 공유 메모리 - - 속성 -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)")}}
-
begin 부터 end 까지의 모든 것을 포함하는 SharedArrayBuffer 바이트의 복사본을 컨텐츠로 갖는 새로운 SharedArrayBuffer 를 반환합니다. begin 또는 end 가 음수인 경우, 인덱스는 배열의 끝에서부터이고 반대인 경우 시작부터입니다.
-
- -

명세

- - - - - - - - - - - - - - -
명세상태코멘트
{{SpecName('ESDraft', '#sec-sharedarraybuffer.prototype', 'SharedArrayBuffer.prototype')}}{{Spec2('ESDraft')}}ES2017 에서 초기 정의.
- -

브라우저 호환성

- - - -

{{Compat("javascript.builtins.SharedArrayBuffer.prototype")}}

- -

함께 보기

- -
    -
  • {{jsxref("SharedArrayBuffer")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/string/prototype/index.html b/files/ko/web/javascript/reference/global_objects/string/prototype/index.html deleted file mode 100644 index fa32999954..0000000000 --- a/files/ko/web/javascript/reference/global_objects/string/prototype/index.html +++ /dev/null @@ -1,219 +0,0 @@ ---- -title: String.prototype -slug: Web/JavaScript/Reference/Global_Objects/String/prototype -tags: - - JavaScript - - Property - - Prototype - - String -translation_of: Web/JavaScript/Reference/Global_Objects/String -translation_of_original: Web/JavaScript/Reference/Global_Objects/String/prototype ---- -
{{JSRef("Global_Objects", "String")}}
- -

요약

- -

String.prototype 프라퍼티는 {{jsxref("Global_Objects/String", "String")}} 프로토타입 오브젝트를 표현하고 있습니다.

- -
{{js_property_attributes(0, 0, 0)}}
- -

설명

- -

모든 {{jsxref("Global_Objects/String", "String")}} 인스턴스들은 String.prototype를 상속합니다. String 프라퍼티 오브젝트를 변경하면, 그 변경은 모든 {{jsxref("Global_Objects/String", "String")}} 인스턴스들에 영향을 주게 됩니다.

- -

Properties

- -
-
String.prototype.constructor
-
오브젝트의 프로토타입을 생성하는 함수를 명세합니다.
-
{{jsxref("String.prototype.length")}}
-
문자열의 길이를 반영합니다.
-
N
-
N번째 위치에 있는 문자에 접근하기 위해 사용합니다.  N 은 0과 {{jsxref("String.length", "length")}}보다 작은 값 사이에 있는 양의 정수입니다. 이 퍼라퍼티들은 읽기 전용(read-only) 속성을 가지고 있습니다. 
-
- -

메서드

- -

HTML과 관련이 없는 메서드

- -
-
{{jsxref("String.prototype.charAt()")}}
-
문자열 내 특정 위치(index)에 있는 문자를 반환합니다.
-
{{jsxref("String.prototype.charCodeAt()")}}
-
문자열 내 주어진 위치(index)에 있는 문자의 유니코드 값을 반환합니다.
-
{{jsxref("String.prototype.codePointAt()")}} {{experimental_inline}}
-
주어진 위치에 있는 UTF-16으로 인코딩된 코드 포인터값인 음수가 아닌 정수값을 반환합니다. 
-
{{jsxref("String.prototype.concat()")}}
-
두 문자열의 문자를 합쳐서 새로운 문자열로 만든 다음, 그 새로운 문자열을 반환합니다. 
-
{{jsxref("String.prototype.includes()")}} {{experimental_inline}}
-
문자열 내에 찾고자 하는 문자열이 있는지를 확인합니다. 
-
{{jsxref("String.prototype.endsWith()")}} {{experimental_inline}}
-
문자열에서 특정 문자열로 끝나는지를 확인할 수 있습니다.
-
{{jsxref("String.prototype.indexOf()")}}
-
{{jsxref("Global_Objects/String", "String")}} 오브젝트에 있는 특정 값이 일치하는 첫 번째 인덱스 값을 반환하며, 일치하는 값이 없을 경우에는 -1을 반환합니다.
-
{{jsxref("String.prototype.lastIndexOf()")}}
-
String 오브젝트에서 fromIndex로부터 반대방향으로 찾기 시작하여 특정 값이 일치하는 마지막 인덱스를 반환합니다. 문자열에서 일치하는 특정 값이 없으면 -1을 리턴합니다.
-
{{jsxref("String.prototype.localeCompare()")}}
-
Returns a number indicating whether a reference string comes before or after or is the same as the given string in sort order.
-
{{jsxref("String.prototype.match()")}}
-
Used to match a regular expression against a string.
-
{{jsxref("String.prototype.normalize()")}} {{experimental_inline}}
-
Returns the Unicode Normalization Form of the calling string value.
-
{{jsxref("String.prototype.quote()")}} {{obsolete_inline}}
-
Wraps the string in double quotes (""").
-
{{jsxref("String.prototype.repeat()")}} {{experimental_inline}}
-
Returns a string consisting of the elements of the object repeated the given times.
-
{{jsxref("String.prototype.replace()")}}
-
Used to find a match between a regular expression and a string, and to replace the matched substring with a new substring.
-
{{jsxref("String.prototype.search()")}}
-
Executes the search for a match between a regular expression and a specified string.
-
{{jsxref("String.prototype.slice()")}}
-
Extracts a section of a string and returns a new string.
-
{{jsxref("String.prototype.split()")}}
-
Splits a {{jsxref("Global_Objects/String", "String")}} object into an array of strings by separating the string into substrings.
-
{{jsxref("String.prototype.startsWith()")}} {{experimental_inline}}
-
Determines whether a string begins with the characters of another string.
-
{{jsxref("String.prototype.substr()")}}
-
Returns the characters in a string beginning at the specified location through the specified number of characters.
-
{{jsxref("String.prototype.substring()")}}
-
Returns the characters in a string between two indexes into the string.
-
{{jsxref("String.prototype.toLocaleLowerCase()")}}
-
The characters within a string are converted to lower case while respecting the current locale. For most languages, this will return the same as {{jsxref("String.prototype.toLowerCase()", "toLowerCase()")}}.
-
{{jsxref("String.prototype.toLocaleUpperCase()")}}
-
The characters within a string are converted to upper case while respecting the current locale. For most languages, this will return the same as {{jsxref("String.prototype.toUpperCase()", "toUpperCase()")}}.
-
{{jsxref("String.prototype.toLowerCase()")}}
-
Returns the calling string value converted to lower case.
-
{{jsxref("String.prototype.toSource()")}} {{non-standard_inline}}
-
Returns an object literal representing the specified object; you can use this value to create a new object. Overrides the {{jsxref("Object.prototype.toSource()")}} method.
-
{{jsxref("String.prototype.toString()")}}
-
Returns a string representing the specified object. Overrides the {{jsxref("Object.prototype.toString()")}} method.
-
{{jsxref("String.prototype.toUpperCase()")}}
-
Returns the calling string value converted to uppercase.
-
{{jsxref("String.prototype.trim()")}}
-
Trims whitespace from the beginning and end of the string. Part of the ECMAScript 5 standard.
-
{{jsxref("String.prototype.trimLeft()")}} {{non-standard_inline}}
-
Trims whitespace from the left side of the string.
-
{{jsxref("String.prototype.trimRight()")}} {{non-standard_inline}}
-
Trims whitespace from the right side of the string.
-
{{jsxref("String.prototype.valueOf()")}}
-
Returns the primitive value of the specified object. Overrides the {{jsxref("Object.prototype.valueOf()")}} method.
-
{{jsxref("String.prototype.@@iterator()", "String.prototype[@@iterator]()")}} {{experimental_inline}}
-
Returns a new Iterator object that iterates over the code points of a String value, returning each code point as a String value.
-
- -

HTML wrapper methods

- -

These methods are of limited use, as they provide only a subset of the available HTML tags and attributes.

- -
-
{{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}}
-
{{htmlattrxref("color", "font", "<font color=\"color\">")}}
-
{{jsxref("String.prototype.fontsize()")}} {{deprecated_inline}}
-
{{htmlattrxref("size", "font", "<font size=\"size\">")}}
-
{{jsxref("String.prototype.italics()")}} {{deprecated_inline}}
-
{{HTMLElement("i")}}
-
{{jsxref("String.prototype.link()")}}
-
{{htmlattrxref("href", "a", "<a href=\"rul\">")}} (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

- - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
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')}}
- -

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

- -
    -
  • {{jsxref("Global_Objects/String", "String")}}
  • -
  • {{jsxref("Function.prototype")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/syntaxerror/prototype/index.html b/files/ko/web/javascript/reference/global_objects/syntaxerror/prototype/index.html deleted file mode 100644 index aa38e80799..0000000000 --- a/files/ko/web/javascript/reference/global_objects/syntaxerror/prototype/index.html +++ /dev/null @@ -1,127 +0,0 @@ ---- -title: SyntaxError.prototype -slug: Web/JavaScript/Reference/Global_Objects/SyntaxError/prototype -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")}} 가 고유의 message 속성을 제공해야 한다고 명시하고 있지만, SpiderMonkey 에서는, {{jsxref("Error.prototype.message")}}를 상속 받습니다. 
-
{{jsxref("Error.prototype.name", "SyntaxError.prototype.name")}}
-
에러명. {{jsxref("Error")}}로부터 상속 받습니다.
-
{{jsxref("Error.prototype.fileName", "SyntaxError.prototype.fileName")}}
-
에러를 발생시킨 파일의 경로. {{jsxref("Error")}}로부터 상속 받습니다.
-
{{jsxref("Error.prototype.lineNumber", "SyntaxError.prototype.lineNumber")}}
-
에러가 발생한 파일의 코드 라인 넘버. {{jsxref("Error")}}로부터 상속 받습니다.
-
{{jsxref("Error.prototype.columnNumber", "SyntaxError.prototype.columnNumber")}}
-
에러가 발생된 라인의 컬럼 넘버. {{jsxref("Error")}}로부터 상속 받습니다.
-
{{jsxref("Error.prototype.stack", "SyntaxError.prototype.stack")}}
-
스택 트레이스. {{jsxref("Error")}}로부터 상속 받습니다.
-
- -

메소드

- -

비록 {{jsxref("SyntaxError")}} 프로토타입 객체는 고유의 메소드를 가지고 있지는 않지만, {{jsxref("SyntaxError")}} 인스턴스는 몇 가지의 메소드를 프로토타입 체인을 통하여 상속 받습니다.

- -

스펙

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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로 정의.
- -

브라우저 호환성

- -
{{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/ko/web/javascript/reference/global_objects/typedarray/prototype/index.html b/files/ko/web/javascript/reference/global_objects/typedarray/prototype/index.html deleted file mode 100644 index 75f63010bf..0000000000 --- a/files/ko/web/javascript/reference/global_objects/typedarray/prototype/index.html +++ /dev/null @@ -1,176 +0,0 @@ ---- -title: TypedArray.prototype -slug: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype -tags: - - JavaScript - - Property - - TypedArray -translation_of: Web/JavaScript/Reference/Global_Objects/TypedArray -translation_of_original: Web/JavaScript/Reference/Global_Objects/TypedArray/prototype ---- -
{{JSRef}}
- -

TypedArray.prototype 속성(property)은 {{jsxref("TypedArray")}} 생성자에 대한 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0,0,0)}}
- -

설명

- -

{{jsxref("TypedArray")}} 인스턴스는 {{jsxref("TypedArray.prototype")}}을 상속합니다. 모든 TypedArray 인스턴스에 속성 또는 메서드를 추가하기 위해 생성자의 프로토타입 객체를 사용할 수 있으며, TypedArrayTypedArray 객체 유형 중 하나입니다.

- -

상속에 관한 자세한 정보를 위해 TypedArray에 대한 설명도 참조하세요.

- -

속성

- -
-
TypedArray.prototype.constructor
-
인스턴스의 프로토타입을 만든 함수를 반환합니다. 이는 기본으로 해당 TypedArray 객체 유형 함수 중 하나입니다.
-
{{jsxref("TypedArray.prototype.buffer")}} {{readonlyInline}}
-
형식화 배열에 의해 참조되는 {{jsxref("ArrayBuffer")}}를 반환합니다. 생성 시에 고정되기에 읽기 전용.
-
{{jsxref("TypedArray.prototype.byteLength")}} {{readonlyInline}}
-
{{jsxref("ArrayBuffer")}}의 시작점부터 형식화 배열의 길이(단위 바이트)를 반환합니다. 생성 시에 고정되기에 읽기 전용.
-
{{jsxref("TypedArray.prototype.byteOffset")}} {{readonlyInline}}
-
{{jsxref("ArrayBuffer")}}의 시작점부터 형식화 배열의 오프셋(단위 바이트)을 반환합니다. 생성 시에 고정되기에 읽기 전용.
-
{{jsxref("TypedArray.prototype.length")}} {{readonlyInline}}
-
형식화 배열 내 보유한 요소의 수를 반환합니다. 생성 시에 고정되기에 읽기 전용.
-
- -

메서드

- -
-
{{jsxref("TypedArray.prototype.copyWithin()")}}
-
배열 내부 일련의 배열 요소를 복사합니다. {{jsxref("Array.prototype.copyWithin()")}}도 참조.
-
{{jsxref("TypedArray.prototype.entries()")}}
-
배열 내 각 인덱스에 대한 키/값 쌍을 포함하는 새로운 Array Iterator 객체를 반환합니다. {{jsxref("Array.prototype.entries()")}}도 참조.
-
{{jsxref("TypedArray.prototype.every()")}}
-
배열의 모든 요소가 함수로 제공되는 테스트를 통과하는지를 테스트합니다. {{jsxref("Array.prototype.every()")}}도 참조.
-
{{jsxref("TypedArray.prototype.fill()")}}
-
시작 인덱스부터 끝 인덱스까지 배열의 모든 요소를 고정값으로 채웁니다. {{jsxref("Array.prototype.fill()")}}도 참조.
-
{{jsxref("TypedArray.prototype.filter()")}}
-
제공되는 필터링 함수가 true를 반환하는 이 배열의 모든 요소를 갖는 새로운 배열을 생성합니다. {{jsxref("Array.prototype.filter()")}}도 참조.
-
{{jsxref("TypedArray.prototype.find()")}}
-
배열 내 요소가 제공되는 테스트 함수를 만족하는 경우 배열 내 찾은 값 또는 못 찾은 경우 undefined를 반환합니다. {{jsxref("Array.prototype.find()")}}도 참조.
-
{{jsxref("TypedArray.prototype.findIndex()")}}
-
배열 내 요소가 제공되는 테스트 함수를 만족하는 경우 배열 내 찾은 인덱스 또는 못 찾은 경우 -1을 반환합니다. {{jsxref("Array.prototype.findIndex()")}}도 참조.
-
{{jsxref("TypedArray.prototype.forEach()")}}
-
배열 내 각 요소에 대해 함수를 호출합니다. {{jsxref("Array.prototype.forEach()")}}도 참조.
-
{{jsxref("TypedArray.prototype.includes()")}} {{experimental_inline}}
-
형식화 배열이 특정 요소를 포함하는지를 판단해, 적절히 true 또는 false를 반환합니다. {{jsxref("Array.prototype.includes()")}}도 참조.
-
{{jsxref("TypedArray.prototype.indexOf()")}}
-
지정된 값과 같은 배열 내부 요소의 첫(최소) 인덱스 또는 못 찾은 경우 -1을 반환합니다. {{jsxref("Array.prototype.indexOf()")}}도 참조.
-
{{jsxref("TypedArray.prototype.join()")}}
-
배열의 모든 요소를 문자열로 합칩니다. {{jsxref("Array.prototype.join()")}}도 참조.
-
{{jsxref("TypedArray.prototype.keys()")}}
-
배열의 각 인덱스에 대한 키를 포함하는 새로운 Array Iterator를 반환합니다. {{jsxref("Array.prototype.keys()")}}도 참조.
-
{{jsxref("TypedArray.prototype.lastIndexOf()")}}
-
지정된 값과 같은 배열 내부 요소의 끝(최대) 인덱스 또는 못 찾은 경우 -1을 반환합니다. {{jsxref("Array.prototype.lastIndexOf()")}}도 참조.
-
{{jsxref("TypedArray.prototype.map()")}}
-
이 배열의 모든 요소에 제공된 함수를 호출한 결과를 갖는 새로운 배열을 생성합니다. {{jsxref("Array.prototype.map()")}}도 참조.
-
{{jsxref("TypedArray.prototype.move()")}} {{non-standard_inline}} {{unimplemented_inline}}
-
{{jsxref("TypedArray.prototype.copyWithin()")}}의 이전 비표준 버전.
-
{{jsxref("TypedArray.prototype.reduce()")}}
-
누산기(accumulator) 및 배열의 각 값(좌에서 우로)에 대해 한 값으로 줄도록 함수를 적용합니다. {{jsxref("Array.prototype.reduce()")}}도 참조.
-
{{jsxref("TypedArray.prototype.reduceRight()")}}
-
누산기 및 배열의 각 값(우에서 좌로)에 대해 한 값으로 줄도록 함수를 적용합니다. {{jsxref("Array.prototype.reduceRight()")}}도 참조.
-
{{jsxref("TypedArray.prototype.reverse()")}}
-
배열 요소의 순서를 뒤집습니다 — 처음이 마지막이 되고 마지막이 처음이 됩니다. {{jsxref("Array.prototype.reverse()")}}도 참조.
-
{{jsxref("TypedArray.prototype.set()")}}
-
형식화 배열에 여러 값을 저장합니다, 지정된 배열에서 입력 값을 읽어.
-
{{jsxref("TypedArray.prototype.slice()")}}
-
배열의 한 부분을 추출하여 새로운 배열을 반환합니다. {{jsxref("Array.prototype.slice()")}}도 참조.
-
{{jsxref("TypedArray.prototype.some()")}}
-
이 배열의 적어도 한 요소가 제공된 테스트 함수를 만족하는 경우 true를 반환합니다. {{jsxref("Array.prototype.some()")}}도 참조.
-
{{jsxref("TypedArray.prototype.sort()")}}
-
배열의 요소를 적소에 정렬해 그 배열을 반환합니다. {{jsxref("Array.prototype.sort()")}}도 참조.
-
{{jsxref("TypedArray.prototype.subarray()")}}
-
주어진 시작 및 끝 요소 인덱스로부터 새로운 TypedArray를 반환합니다.
-
{{jsxref("TypedArray.prototype.values()")}}
-
배열의 각 인덱스에 대한 값을 포함하는 새로운 Array Iterator 객체를 반환합니다. {{jsxref("Array.prototype.values()")}}도 참조.
-
{{jsxref("TypedArray.prototype.toLocaleString()")}}
-
배열 및 그 요소를 나타내는 지역화된 문자열을 반환합니다. {{jsxref("Array.prototype.toLocaleString()")}}도 참조.
-
{{jsxref("TypedArray.prototype.toString()")}}
-
배열 및 그 요소를 나타내는 문자열을 반환합니다. {{jsxref("Array.prototype.toString()")}}도 참조.
-
{{jsxref("TypedArray.prototype.@@iterator()", "TypedArray.prototype[@@iterator]()")}}
-
배열의 각 인덱스에 대한 값을 포함하는 새로운 Array Iterator 객체를 반환합니다.
-
- -

스펙

- - - - - - - - - - - - - - - - - - - -
스펙상태설명
{{SpecName('ES6', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ESDraft', '#sec-properties-of-the-%typedarrayprototype%-object', 'TypedArray prototype')}}{{Spec2('ESDraft')}} 
- -

브라우저 호환성

- -

{{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/ko/web/javascript/reference/global_objects/weakmap/prototype/index.html b/files/ko/web/javascript/reference/global_objects/weakmap/prototype/index.html deleted file mode 100644 index fa2ad9691d..0000000000 --- a/files/ko/web/javascript/reference/global_objects/weakmap/prototype/index.html +++ /dev/null @@ -1,143 +0,0 @@ ---- -title: WeakMap.prototype -slug: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype -tags: - - ECMAScript6 - - JavaScript - - Property - - WeakMap -translation_of: Web/JavaScript/Reference/Global_Objects/WeakMap -translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakMap/prototype ---- -
{{JSRef}}
- -

WeakMap.prototype 속성(property)은 {{jsxref("WeakMap")}} 생성자에 대한 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0,0,0)}}
- -

설명

- -

{{jsxref("WeakMap")}} 인스턴스는 {{jsxref("WeakMap.prototype")}}에서 상속합니다. 모든 WeakMap 인스턴스에 속성 또는 메서드를 추가하기 위해 생성자의 프로토타입 객체를 사용할 수 있습니다.

- -

WeakMap.prototype은 그 자체로 그냥 평범한 객체입니다:

- -
Object.prototype.toString.call(WeakMap.prototype); // "[object Object]"
- -

속성

- -
-
WeakMap.prototype.constructor
-
인스턴스의 프로토타입을 생성한 함수를 반환합니다. 이는 기본으로 {{jsxref("WeakMap")}} 함수입니다.
-
- -

메서드

- -
-
{{jsxref("WeakMap.delete", "WeakMap.prototype.delete(key)")}}
-
key와 관련된 모든 값을 제거합니다. WeakMap.prototype.has(key)는 그 뒤에 false를 반환합니다.
-
{{jsxref("WeakMap.get", "WeakMap.prototype.get(key)")}}
-
key와 관련된 값 또는 관련 값이 없는 경우 undefined를 반환합니다.
-
{{jsxref("WeakMap.has", "WeakMap.prototype.has(key)")}}
-
WeakMap 객체 내 key와 관련된 값이 있는지 여부를 주장하는(asserting, 나타내는) boolean을 반환합니다.
-
{{jsxref("WeakMap.set", "WeakMap.prototype.set(key, value)")}}
-
WeakMap 객체 내 key에 대해 값을 설정합니다. WeakMap 객체를 반환합니다.
-
{{jsxref("WeakMap.prototype.clear()")}} {{obsolete_inline}}
-
WeakMap 객체에서 모든 키/값 쌍을 제거합니다. 메서드가 없는 WeakMap 객체를 캡슐화하여 .clear() 메서드가 있는 WeakMap 같은 객체 구현이 가능함을 주의하세요 ({{jsxref("WeakMap")}} 페이지 예 참조)
-
- -

스펙

- - - - - - - - - - - - - - - - - - - -
스펙상태설명
{{SpecName('ES6', '#sec-weakmap.prototype', 'WeakMap.prototype')}}{{Spec2('ES6')}}초기 정의.
{{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/ko/web/javascript/reference/global_objects/weakset/prototype/index.html b/files/ko/web/javascript/reference/global_objects/weakset/prototype/index.html deleted file mode 100644 index 0c75408df5..0000000000 --- a/files/ko/web/javascript/reference/global_objects/weakset/prototype/index.html +++ /dev/null @@ -1,142 +0,0 @@ ---- -title: WeakSet.prototype -slug: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype -tags: - - ECMAScript6 - - JavaScript - - Property - - WeakSet -translation_of: Web/JavaScript/Reference/Global_Objects/WeakSet -translation_of_original: Web/JavaScript/Reference/Global_Objects/WeakSet/prototype ---- -
{{JSRef}}
- -

WeakSet.prototype 속성(property)은 {{jsxref("WeakSet")}} 생성자에 대한 프로토타입을 나타냅니다.

- -
{{js_property_attributes(0,0,0)}}
- -

설명

- -

{{jsxref("WeakSet")}} 인스턴스는 {{jsxref("WeakSet.prototype")}}에서 상속합니다. 모든 WeakSet 인스턴스에 속성 또는 메서드를 추가하기 위해 생성자의 프로토타입 객체를 사용할 수 있습니다.

- -

WeakSet.prototype은 그 자체로 그냥 평범한 객체입니다:

- -
Object.prototype.toString.call(WeakSet.prototype); // "[object Object]"
- -

속성

- -
-
WeakSet.prototype.constructor
-
인스턴스의 프로토타입을 생성한 함수를 반환합니다. 이는 기본으로 {{jsxref("WeakSet")}} 함수입니다.
-
- -

메서드

- -
-
{{jsxref("WeakSet.add", "WeakSet.prototype.add(value)")}}
-
WeakSet 객체에 주어진 값을 갖는 새로운 객체를 추가합니다.
-
{{jsxref("WeakSet.delete", "WeakSet.prototype.delete(value)")}}
-
value와 관련된 요소를 제거합니다. WeakSet.prototype.has(value)는 그 뒤에 false를 반환합니다.
-
{{jsxref("WeakSet.has", "WeakSet.prototype.has(value)")}}
-
WeakSet 객체 내 주어진 값을 갖는 요소가 존재하는 지 여부를 주장하는(asserting, 나타내는) boolean을 반환합니다.
-
{{jsxref("WeakSet.prototype.clear()")}} {{obsolete_inline}}
-
WeakSet 객체에서 모든 요소를 제거합니다.
-
- -

스펙

- - - - - - - - - - - - - - - - - - - -
스펙상태설명
{{SpecName('ES6', '#sec-weakset.prototype', 'WeakSet.prototype')}}{{Spec2('ES6')}}초기 정의.
{{SpecName('ESDraft', '#sec-weakset.prototype', 'WeakSet.prototype')}}{{Spec2('ESDraft')}} 
- -

브라우저 호환성

- -

{{CompatibilityTable}}

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChromeFirefox (Gecko)Internet ExplorerOperaSafari
Basic support36{{ CompatGeckoDesktop(34) }}{{CompatNo}}23{{CompatNo}}
Ordinary object{{CompatUnknown}}{{CompatGeckoDesktop("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FeatureChrome for AndroidAndroidFirefox Mobile (Gecko)IE MobileOpera MobileSafari Mobile
Basic support{{CompatNo}}{{CompatNo}}{{ CompatGeckoMobile(34) }}{{CompatNo}}{{CompatNo}}{{CompatNo}}
Ordinary object{{CompatUnknown}}{{CompatUnknown}}{{CompatGeckoMobile("40")}}{{CompatUnknown}}{{CompatUnknown}}{{CompatUnknown}}
-
- -

참조

- -
    -
  • {{jsxref("Set.prototype")}}
  • -
  • {{jsxref("WeakMap.prototype")}}
  • -
diff --git a/files/ko/web/javascript/reference/global_objects/webassembly/global/prototype/index.html b/files/ko/web/javascript/reference/global_objects/webassembly/global/prototype/index.html deleted file mode 100644 index c7c1c54bab..0000000000 --- a/files/ko/web/javascript/reference/global_objects/webassembly/global/prototype/index.html +++ /dev/null @@ -1,70 +0,0 @@ ---- -title: WebAssembly.Global.prototype -slug: Web/JavaScript/Reference/Global_Objects/WebAssembly/Global/prototype -translation_of: Web/JavaScript/Reference/Global_Objects/WebAssembly/Global -translation_of_original: Web/JavaScript/Reference/Global_Objects/WebAssembly/Global/prototype ---- -
{{JSRef}}
- -

WebAssembly.Global.prototype 속성은 {{jsxref("WebAssembly.Global()")}} 생성자의 프로토 타입을 나타냅니다.

- -
{{js_property_attributes(0, 0, 0)}}
- -

Description

- -

모든 {{jsxref("WebAssembly.Global")}} 인스턴스는 Global.prototype에서 상속받습니다. {{jsxref("WebAssembly.Global()")}} 생성자의 프로토 타입 객체는 모든 {{jsxref( "WebAssembly.Global")}} 인스턴스에 영향을 미치도록 수정할 수 있습니다.

- -

Properties

- -
-
Global.prototype.constructor
-
이 객체의 인스턴스를 생성 한 함수를 돌려줍니다. 기본적으로 이것은 {{jsxref("WebAssembly.Global()")}} 생성자입니다.
-
Global.prototype[@@toStringTag]
-
@@toStringTag 속성의 초기 값은 String 값인 "WebAssembly.Global"입니다.
-
Global.prototype.value
-
전역 변수에 포함 된 값 - 전역 값을 직접 설정하고 가져 오는 데 사용할 수 있습니다.
-
- -

Methods

- -
-
Global.prototype.valueOf()
-
전역 변수에 포함 된 값을 반환하는 Old-style 메서드입니다.
-
- -

Specifications

- - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{SpecName('WebAssembly JS', '#globals', 'WebAssembly.Global()')}}{{Spec2('WebAssembly JS')}}Initial draft definition.
- -

Browser compatibility

- -
- - -

{{Compat("javascript.builtins.WebAssembly.Global.prototype")}}

-
- -
- -
- -

See also

- -
    -
  • {{jsxref("WebAssembly.Global()")}}
  • -
diff --git a/files/ko/web/javascript/reference/operators/arithmetic_operators/index.html b/files/ko/web/javascript/reference/operators/arithmetic_operators/index.html deleted file mode 100644 index 3e61415550..0000000000 --- a/files/ko/web/javascript/reference/operators/arithmetic_operators/index.html +++ /dev/null @@ -1,291 +0,0 @@ ---- -title: 산술 연산자 -slug: Web/JavaScript/Reference/Operators/Arithmetic_Operators -tags: - - JavaScript - - Operator - - Reference -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
-
- -

예제

- -
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 ** ca ** (b ** c)와 같습니다.

- -

구문

- -
연산자: var1 ** var2
-
- -

참고

- -

PHP와 Python 등 거듭제곱 연산자를 가진 대부분의 언어는 거듭제곱 연산자의 우선순위가 +와 - 등 단항 연산자보다 높습니다. 그러나 Bash는 단항 연산자가 거듭제곱 연산자보다 우선순위가 높은 등 일부 예외도 있습니다. JavaScript는 단항 연산자(+/-/~/!/delete/void/typeof)를 왼쪽 피연산자 앞에 배치할 수 없으므로, 모호한 표현도 작성할 수 없습니다.

- -
-2 ** 2;
-// Bash에서 4, 다른 언어에서는 -4.
-// 모호한 표현이므로 JavaScript에서는 유효하지 않음
-
-
--(2 ** 2);
-// JavaScript에서 -4, 작성자의 의도가 명확함
-
- -

예제

- -
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
-
- -
-

참고: JavaScript는 비트 연산자 ^ (논리 XOR)도 가지고 있습니다. **^는 다릅니다. (예 : 2 ** 3 === 8이지만 2 ^ 3 === 1)

-
- -

증가 (++)

- -

증가 연산자는 피연산자를 증가(1을 덧셈)시키고, 그 값을 반환합니다.

- -
    -
  • 피연산자 뒤에 붙여(예: x++) 접미사로 사용한 경우 증가하기 전의 값을 반환합니다.
  • -
  • 피연산자 앞에 붙여(예: ++x) 접두사로 사용한 경우 증가한 후의 값을 반환합니다.
  • -
- -

구문

- -
연산자: x++ or ++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
-
-// 단항 부정 연산자는 숫자가 아닌 값을 숫자로 변환함
-var x = "4";
-y = -x; // y = -4
- -

단항 양부호 (+)

- -

단항 양부호 연산자는 피연산자의 앞에 위치하며 피연산자의 값 그대로 평가되지만, 값이 숫자가 아닐 경우 숫자로 변환을 시도합니다. 단항 부정(-) 연산자도 숫자가 아닌 값을 변환할 수 있지만, 단항 양부호가 속도도 제일 빠르고 다른 연산도 수행하지 않으므로 선호해야 할 방법입니다. 문자열로 표현한 정수 및 부동소수점 실수, 문자열이 아닌 true, false, null도 변환할 수 있습니다. 10진수와 (앞에 "0x"가 붙은) 16진수 정수 모두 지원합니다. 음수도 지원하지만 16진수 음수에는 사용할 수 없습니다. 어떤 값을 분석할 수 없으면 {{jsxref("NaN")}}으로 평가됩니다.

- -

구문

- -
연산자: +x
-
- -

예제

- -
+3     // 3
-+"3"   // 3
-+true  // 1
-+false // 0
-+null  // 0
-+function(val) { return val } // NaN
-
- -

명세

- - - - - - - - - - - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#sec-additive-operators', 'Additive operators')}}
{{SpecName('ESDraft', '#sec-postfix-expressions', 'Postfix expressions')}}
{{SpecName('ESDraft', '#sec-11.5', 'Multiplicative operators')}}
{{SpecName('ESDraft', '#sec-11.4', 'Unary operator')}}
- -

브라우저 호환성

- - - -

{{Compat("javascript.operators.arithmetic")}}

- -

같이 보기

- - diff --git a/files/ko/web/javascript/reference/operators/assignment_operators/index.html b/files/ko/web/javascript/reference/operators/assignment_operators/index.html deleted file mode 100644 index 93146d63cf..0000000000 --- a/files/ko/web/javascript/reference/operators/assignment_operators/index.html +++ /dev/null @@ -1,395 +0,0 @@ ---- -title: 할당 연산자 -slug: Web/JavaScript/Reference/Operators/Assignment_Operators -tags: - - JavaScript - - Operator - - Reference -translation_of: Web/JavaScript/Reference/Operators#Assignment_operators -translation_of_original: Web/JavaScript/Reference/Operators/Assignment_Operators ---- -
{{jsSidebar("Operators")}}
- -

할당 연산자는 오른쪽 피연산자의 값을 왼쪽 피연산자에 할당합니다.

- -
{{EmbedInteractiveExample("pages/js/expressions-assignment.html")}}
- - - -

개요

- -

기본 할당연산자는 등호(=)로, 오른쪽 피연산자의 값을 왼쪽 피연산자에 할당합니다. 즉, x = yy의 값을 x에 할당힙니다. 다른 할당 연산자는 보통 표준 연산의 축약형으로, 다음 표에서 종류와 예시를 확인할 수 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
이름단축 연산자의미
할당x = yx = y
덧셈 할당x += yx = x + y
뺄셈 할당x -= yx = x - y
곱셈 할당x *= yx = x * y
나눗셈 할당x /= yx = x / y
나머지 연산 할당x %= yx = x % y
지수 연산 할당x **= yx = x ** y
왼쪽 시프트 할당x <<= yx = x << y
오른쪽 시프트 할당x >>= yx = x >> y
부호없는 오른쪽 시프트 할당x >>>= yx = x >>> y
비트 AND 할당x &= yx = x & y
비트 XOR 할당x ^= yx = x ^ y
비트 OR 할당x |= yx = x | y
- -

할당

- -

단순 할당 연산자는 값을 변수에 할당합니다. 할당 연산자는 할당의 결과값으로 평가됩니다. 할당 연산자를 연속해서 사용해, 다수의 변수에 하나의 값을 한꺼번에 할당할 수 있습니다. 예제를 참고하세요.

- -

구문

- -
연산자: x = y
-
- -

예제

- -
// 다음과 같은 변수를 가정
-//  x = 5
-//  y = 10
-//  z = 25
-
-x = y     // x는 10
-x = y = z // x, y, z 모두 25
-
- -

덧셈 할당

- -

덧셈 할당 연산자는 변수에 오른쪽 피연산자의 값을 더하고, 그 결과를 변수에 할당합니다. 두 피연산자의 자료형이 덧셈 할당 연산자의 행동을 결정합니다. 덧셈 연산자처럼 합 또는 연결이 가능합니다. 자세한 내용은 {{jsxref("Operators/Arithmetic_Operators", "덧셈 연산자", "#Addition", 1)}}를 참고하세요.

- -

구문

- -
연산자: x += y
-의미: x = x + y
-
- -

예제

- -
// 다음과 같은 변수를 가정
-//  foo = "foo"
-//  bar = 5
-//  baz = true
-
-
-// Number + Number -> 합
-bar += 2 // 7
-
-// Boolean + Number -> 합
-baz += 1 // 2
-
-// Boolean + Boolean -> 합
-baz += false // 1
-
-// Number + String -> 연결
-bar += 'foo' // "5foo"
-
-// String + Boolean -> 연결
-foo += false // "foofalse"
-
-// String + String -> 연결
-foo += 'bar' // "foobar"
-
- -

뺄셈 할당

- -

뺄셈 할당 연산자는 변수에서 오른쪽 피연산자의 값을 빼고, 그 결과를 변수에 할당합니다. 더 자세한 내용은 {{jsxref("Operators/Arithmetic_Operators", "뺄셈 연산자", "#Subtraction", 1)}}를 참고하세요.

- -

구문

- -
연산자: x -= y
-의미: x = x - y
-
- -

예제

- -
// 다음과 같은 변수를 가정
-//  bar = 5
-
-bar -= 2     // 3
-bar -= "foo" // NaN
-
- -

곱셈 할당

- -

곱셈 할당 연산자는 변수에 오른쪽 피연산자의 값을 곱하고, 그 결과를 변수에 할당합니다. 더 자세한 내용은 {{jsxref("Operators/Arithmetic_Operators", "곱셈 연산자", "#Multiplication", 1)}}를 참고하세요.

- -

구문

- -
연산자: x *= y
-의미: x = x * y
-
- -

예제

- -
// 다음과 같은 변수를 가정
-//  bar = 5
-
-bar *= 2     // 10
-bar *= "foo" // NaN
-
- -

나눗셈 할당

- -

나눗셈 할당 연산자는 변수를 오른쪽 피연산자로 나누고, 그 결과를 변수에 할당합니다. 더 자세한 내용은 {{jsxref("Operators/Arithmetic_Operators", "나눗셈 연산자", "#Division", 1)}}를 참고하세요.

- -

구문

- -
연산자: x /= y
-의미: x = x / y
-
- -

예제

- -
// 다음과 같은 변수를 가정
-//  bar = 5
-
-bar /= 2     // 2.5
-bar /= "foo" // NaN
-bar /= 0     // Infinity
-
- -

나머지 연산 할당

- -

나머지 연산 할당은 변수를 오른쪽 피연산자로 나눈 나머지를 변수에 할당합니다. 더 자세한 내용은 {{jsxref("Operators/Arithmetic_Operators", "나머지 연산자", "#Remainder", 1)}}를 참고하세요.

- -

구문

- -
연산자: x %= y
-의미: x = x % y
-
- -

예제

- -
// 다음과 같은 변수를 가정
-//  bar = 5
-
-bar %= 2     // 1
-bar %= "foo" // NaN
-bar %= 0     // NaN
-
- -

거듭제곱 할당

- -

거듭제곱 할당 연산자는 변수를 오른쪽 피연산자만큼 거듭제곱한 결과를 변수에 할당합니다. 자세한 내용은 {{jsxref("Operators/Arithmetic_Operators", "거듭제곱 연산자", "#Exponentiation", 1)}}를 참고하세요.

- -

구문

- -
연산자: x **= y
-의미: x = x ** y
-
- -

예제

- -
// 다음과 같은 변수를 가정
-//  bar = 5
-
-bar **= 2     // 25
-bar **= "foo" // NaN
- -

왼쪽 시프트 할당

- -

왼쪽 시프트 할당 연산자는 변수의 비트를 오른쪽 피연산자의 값만큼 왼쪽으로 이동하고, 그 결과를 변수에 할당합니다. 더 자세한 내용은 {{jsxref("Operators/Bitwise_Operators", "left shift operator", "#Left_shift", 1)}}를 참고하세요.

- -

구문

- -
연산자: x <<= y
-의미: x = x << y
-
- -

예제

- -
var bar = 5; //  (00000000000000000000000000000101)
-bar <<= 2; // 20 (00000000000000000000000000010100)
-
- -

오른쪽 시프트 할당

- -

오른쪽 시프트 할당 연산자는 변수의 비트를 오른쪽 피연산자의 값만큼 우측으로 이동하고, 그 결과를 변수에 할당합니다. 자세한 내용은 {{jsxref("Operators/Bitwise_Operators", "right shift operator", "#Right_shift", 1)}}를 참고하세요.

- -

구문

- -
연산자: x >>= y
-의미: x = x >> y
-
- -

예제

- -
var bar = 5; //   (00000000000000000000000000000101)
-bar >>= 2;   // 1 (00000000000000000000000000000001)
-
-var bar -5; //    (-00000000000000000000000000000101)
-bar >>= 2;  // -2 (-00000000000000000000000000000010)
-
- -

부호 없는 오른쪽 시프트 할당

- -

부호 없는 오른쪽 시프트 할당 연산자는 변수의 비트를 오른쪽 피연산자의 값만큼 우측으로 이동하고, 그 결과를 변수에 할당합니다. 자세한 내용은 {{jsxref("Operators/Bitwise_Operators", " unsigned right shift operator", "#Unsigned_right_shift", 1)}}을 참고하세요.

- -

구문

- -
연산자: x >>>= y
-의미: x = x >>> y
-
- -

예제

- -
var bar = 5; //   (00000000000000000000000000000101)
-bar >>>= 2;  // 1 (00000000000000000000000000000001)
-
-var bar = -5; // (-00000000000000000000000000000101)
-bar >>>= 2; // 1073741822 (00111111111111111111111111111110)
- -

비트 AND 할당

- -

비트 AND 할당 연산자는 양쪽 피연산자의 이진 표현을 AND 연산한 후, 그 결과를 변수에 할당합니다. 자세한 내용은{{jsxref("Operators/Bitwise_Operators", "bitwise AND operator", "#Bitwise_AND", 1)}}을 참고하세요.

- -

구문

- -
연산자: x &= y
-의미: x = x & y
-
- -

예제

- -
var bar = 5;
-// 5:     00000000000000000000000000000101
-// 2:     00000000000000000000000000000010
-bar &= 2; // 0
-
- -

비트 XOR 할당

- -

비트 XOR 할당 연산자는 양쪽 피연산자의 이진 표현을 XOR 연산한 후, 그 결과를 변수에 할당합니다. 자세한 내용은 {{jsxref("Operators/Bitwise_Operators", "bitwise XOR operator", "#Bitwise_XOR", 1)}}를 참고하세요.

- -

구문

- -
연산자: x ^= y
-의미: x = x ^ y
-
- -

예제

- -
var bar = 5;
-bar ^= 2; // 7
-// 5: 00000000000000000000000000000101
-// 2: 00000000000000000000000000000010
-// -----------------------------------
-// 7: 00000000000000000000000000000111
-
- -

비트 OR 할당

- -

비트 OR 할당 연산자는 양쪽 피연산자의 이진 표현을 OR 연산한 후, 그 결과를 변수에 할당합니다. 자세한 내용은 {{jsxref("Operators/Bitwise_Operators", "bitwise OR operator", "#Bitwise_OR", 1)}}를 참고하세요.

- -

문법

- -
연산자: x |= y
-의미: x = x | y
-
- -

예제

- -
var bar = 5;
-bar |= 2; // 7
-// 5: 00000000000000000000000000000101
-// 2: 00000000000000000000000000000010
-// -----------------------------------
-// 7: 00000000000000000000000000000111
-
- -

예제

- -

다른 할당 연산자를 갖는 왼쪽 피연산자

- -

드물게, 할당 연산자(예: x += y)와 그 의미를 나타낸 표현(x = x + y)이 동일하지 않은 경우가 있습니다. 할당 연산자의 왼쪽 피연산자가 다른 할당 연산자를 포함할 때, 왼쪽 피연산자는 한 번만 평가됩니다. 예를 들면 다음과 같습니다.

- -
a[i++] += 5         // i는 한 번만 평가됨
-a[i++] = a[i++] + 5 // i는 두 번 평가됨
-
- -

명세

- - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#sec-assignment-operators', 'Assignment operators')}}
- -

브라우저 호환성

- - - -

{{Compat("javascript.operators.assignment")}}

- -

같이 보기

- - diff --git a/files/ko/web/javascript/reference/operators/bitwise_operators/index.html b/files/ko/web/javascript/reference/operators/bitwise_operators/index.html deleted file mode 100644 index 4cc5ab7b5a..0000000000 --- a/files/ko/web/javascript/reference/operators/bitwise_operators/index.html +++ /dev/null @@ -1,541 +0,0 @@ ---- -title: 비트 연산자 -slug: Web/JavaScript/Reference/Operators/Bitwise_Operators -tags: - - JavaScript - - Operator - - Reference -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Bitwise_Operators ---- -
{{jsSidebar("Operators")}}
- -

비트 연산자는 피연산자를 10진수, 16진수, 8진수가 아니라, 32개의 비트(0과 1) 집합으로 취급합니다. 예를 들어, 10진수 9의 2진수 표기법은 1001입니다. 이렇게, 비트 연산자는 값의 2진수 표현을 사용해 연산하지만, 결과는 표준 JavaScript 숫자 값으로 반환합니다.

- -
{{EmbedInteractiveExample("pages/js/expressions-bitwiseoperators.html")}}
- - - -

다음은 JavaScript의 비트 연산자를 요약한 표입니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
연산자사용방법설명
비트 ANDa & b피연산자를 비트로 바꿨을 때 각각 대응하는 비트가 모두 1이면 그 비트값에 1을 반환.
비트 ORa | b피연산자를 비트로 바꿨을 때 각각 대응하는 비트가 모두 1이거나 한 쪽이 1이면 1을 반환.
비트 XORa ^ b피연산자를 비트로 바꿨을 때 대응하는 비트가 서로 다르면 1을 반환.
비트 NOT~ a피연산자의 반전된 값을 반환.
왼쪽 시프트a << bShifts a in binary representation b (< 32) bits to the left, shifting in zeros from the right.
부호 유지 오른쪽 시프트a >> bShifts a in binary representation b (< 32) bits to the right, discarding bits shifted off.
부호 버림 오른쪽 시프트a >>> bShifts a in binary representation b (< 32) bits to the right, discarding bits shifted off, and shifting in zeros from the left.
- -

부호 있는 32비트 정수

- -

The operands of all bitwise operators are converted to signed 32-bit integers in two's complement format, except for zero-fill right shift which results in an unsigned 32-bit integer.

- -

Two's complement format means that a number's negative counterpart (e.g. 5 vs. -5) is all the number's bits inverted (bitwise NOT of the number, or ones' complement of the number) plus one.

- -

For example, the following encodes the integer 314:

- -
00000000000000000000000100111010
-
- -

The following encodes ~314, i.e. the one's complement of 314:

- -
11111111111111111111111011000101
-
- -

Finally, the following encodes -314, i.e. the two's complement of 314:

- -
11111111111111111111111011000110
-
- -

The two's complement guarantees that the left-most bit is 0 when the number is positive and 1 when the number is negative. Thus, it is called the sign bit.

- -

The number 0 is the integer that is composed completely of 0 bits.

- -
0 (base 10) = 00000000000000000000000000000000 (base 2)
-
- -

The number -1 is the integer that is composed completely of 1 bits.

- -
-1 (base 10) = 11111111111111111111111111111111 (base 2)
-
- -

The number -2147483648 (hexadecimal representation: -0x80000000) is the integer that is composed completely of 0 bits except the first (left-most) one.

- -
-2147483648 (base 10) = 10000000000000000000000000000000 (base 2)
-
- -

The number 2147483647 (hexadecimal representation: 0x7fffffff) is the integer that is composed completely of 1 bits except the first (left-most) one.

- -
2147483647 (base 10) = 01111111111111111111111111111111 (base 2)
-
- -

The numbers -2147483648 and 2147483647 are the minimum and the maximum integers representable throught a 32bit signed number.

- -

비트 논리 연산자

- -

비트 논리 연산자는 다음과 같이 사용됩니다.

- -
    -
  • 피연산자는 32비트 정수로 변환되고, 이진법으로 표현됩니다 (0과 1).
  • -
  • 이진법으로 표현된 첫 번째 피연산자는 두 번째 피연산자와 쌍을 이룹니다: 첫 번째는 첫 번째 비트끼리, 두 번째는 두 번째 비트끼리...
  • -
  • 연산자는 각각의 비트쌍에 적용되고, 결과 또한 이진법으로 구성됩니다.
  • -
- -

& (비트 AND)

- -

비트 연산자 AND를 비트 쌍으로 실행합니다.

- -

Performs the AND operation on each pair of bits. a AND b yields 1 only if both a and b are 1. The truth table for the AND operation is:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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)
-
- -

Bitwise ANDing any number x with 0 yields 0. Bitwise ANDing any number x with -1 yields x.

- -

| (비트 OR)

- -

Performs the OR operation on each pair of bits. a OR b yields 1 if either a or b is 1. The truth table for the OR operation is:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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)
-
- -

Bitwise ORing any number x with 0 yields x.

- -

Bitwise ORing any number x with -1 yields -1.

- -

^ (비트 XOR)

- -

Performs the XOR operation on each pair of bits. a XOR b yields 1 if a and b are different. The truth table for the XOR operation is:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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)
-
- -

Bitwise XORing any number x with 0 yields x.

- -

Bitwise XORing any number x with -1 yields ~x.

- -

~ (비트 NOT)

- -

Performs the NOT operator on each bit. NOT a yields the inverted value (a.k.a. one's complement) of a. The truth table for the NOT operation is:

- - - - - - - - - - - - - - - - -
aNOT a
01
10
- -
 9 (base 10) = 00000000000000000000000000001001 (base 2)
-               --------------------------------
-~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)
-
- -

Bitwise NOTing any number x yields -(x + 1). For example, ~5 yields -6.

- -

비트 시프트 연산자

- -

The bitwise shift operators take two operands: the first is a quantity to be shifted, and the second specifies the number of bit positions by which the first operand is to be shifted. The direction of the shift operation is controlled by the operator used.

- -

Shift operators convert their operands to 32-bit integers in big-endian order and return a result of the same type as the left operand. The right operand should be less than 32, but if not only the low five bits will be used.

- -

<< (Left shift)

- -

This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.

- -

For example, 9 << 2 yields 36:

- -
     9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 << 2 (base 10): 00000000000000000000000000100100 (base 2) = 36 (base 10)
-
- -

Bitwise shifting any number x to the left by y bits yields x * 2^y.

- -

>> (Sign-propagating right shift)

- -

This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left. Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".

- -

For example, 9 >> 2 yields 2:

- -
     9 (base 10): 00000000000000000000000000001001 (base 2)
-                  --------------------------------
-9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

Likewise, -9 >> 2 yields -3, because the sign is preserved:

- -
     -9 (base 10): 11111111111111111111111111110111 (base 2)
-                   --------------------------------
--9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
-
- -

>>> (Zero-fill right shift)

- -

This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes 0, so the result is always non-negative.

- -

For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result. For example, 9 >>> 2 yields 2, the same as 9 >> 2:

- -
      9 (base 10): 00000000000000000000000000001001 (base 2)
-                   --------------------------------
-9 >>> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
-
- -

However, this is not the case for negative numbers. For example, -9 >>> 2 yields 1073741821, which is different than -9 >> 2 (which yields -3):

- -
      -9 (base 10): 11111111111111111111111111110111 (base 2)
-                    --------------------------------
--9 >>> 2 (base 10): 00111111111111111111111111111101 (base 2) = 1073741821 (base 10)
-
- -

예제

- -

Flags and bitmasks

- -

The bitwise logical operators are often used to create, manipulate, and read sequences of flags, which are like binary variables. Variables could be used instead of these sequences, but binary flags take much less memory (by a factor of 32).

- -

Suppose there are 4 flags:

- -
    -
  • flag A: we have an ant problem
  • -
  • flag B: we own a bat
  • -
  • flag C: we own a cat
  • -
  • flag D: we own a duck
  • -
- -

These flags are represented by a sequence of bits: DCBA. When a flag is set, it has a value of 1. When a flag is cleared, it has a value of 0. Suppose a variable flags has the binary value 0101:

- -
var flags = 5;   // binary 0101
-
- -

This value indicates:

- -
    -
  • flag A is true (we have an ant problem);
  • -
  • flag B is false (we don't own a bat);
  • -
  • flag C is true (we own a cat);
  • -
  • flag D is false (we don't own a duck);
  • -
- -

Since bitwise operators are 32-bit, 0101 is actually 00000000000000000000000000000101, but the preceding zeroes can be neglected since they contain no meaningful information.

- -

A bitmask is a sequence of bits that can manipulate and/or read flags. Typically, a "primitive" bitmask for each flag is defined:

- -
var FLAG_A = 1; // 0001
-var FLAG_B = 2; // 0010
-var FLAG_C = 4; // 0100
-var FLAG_D = 8; // 1000
-
- -

New bitmasks can be created by using the bitwise logical operators on these primitive bitmasks. For example, the bitmask 1011 can be created by ORing FLAG_A, FLAG_B, and FLAG_D:

- -
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
-
- -

Individual flag values can be extracted by ANDing them with a bitmask, where each bit with the value of one will "extract" the corresponding flag. The bitmask masks out the non-relevant flags by ANDing with zeros (hence the term "bitmask"). For example, the bitmask 0100 can be used to see if flag C is set:

- -
// if we own a cat
-if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true
-   // do stuff
-}
-
- -

A bitmask with multiple set flags acts like an "either/or". For example, the following two are equivalent:

- -
// if we own a bat or we own a cat
-if ((flags & FLAG_B) || (flags & FLAG_C)) { // (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true
-   // do stuff
-}
-
- -
// if we own a bat or cat
-var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110
-if (flags & mask) { // 0101 & 0110 => 0100 => true
-   // do stuff
-}
-
- -

Flags can be set by ORing them with a bitmask, where each bit with the value one will set the corresponding flag, if that flag isn't already set. For example, the bitmask 1100 can be used to set flags C and D:

- -
// yes, we own a cat and a duck
-var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100
-flags |= mask;   // 0101 | 1100 => 1101
-
- -

Flags can be cleared by ANDing them with a bitmask, where each bit with the value zero will clear the corresponding flag, if it isn't already cleared. This bitmask can be created by NOTing primitive bitmasks. For example, the bitmask 1010 can be used to clear flags A and C:

- -
// no, we don't have an ant problem or own a cat
-var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

The mask could also have been created with ~FLAG_A & ~FLAG_C (De Morgan's law):

- -
// no, we don't have an ant problem, and we don't own a cat
-var mask = ~FLAG_A & ~FLAG_C;
-flags &= mask;   // 1101 & 1010 => 1000
-
- -

Flags can be toggled by XORing them with a bitmask, where each bit with the value one will toggle the corresponding flag. For example, the bitmask 0110 can be used to toggle flags B and C:

- -
// if we didn't have a bat, we have one now, and if we did have one, bye-bye bat
-// same thing for cats
-var mask = FLAG_B | FLAG_C;
-flags = flags ^ mask;   // 1100 ^ 0110 => 1010
-
- -

Finally, the flags can all be flipped with the NOT operator:

- -
// entering parallel universe...
-flags = ~flags;    // ~1010 => 0101
-
- -

Conversion snippets

- -

Convert a binary string to a decimal number:

- -
var sBinString = "1011";
-var nMyNumber = parseInt(sBinString, 2);
-alert(nMyNumber); // prints 11, i.e. 1011
-
- -

Convert a decimal number to a binary string:

- -
var nMyNumber = 11;
-var sBinString = nMyNumber.toString(2);
-alert(sBinString); // prints 1011, i.e. 11
-
- -

Automate Mask Creation

- -

If you have to create many masks from some boolean values, you can automatize the process:

- -
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); // prints 11, i.e.: 1011
-
- -

Reverse algorithm: an array of booleans from a mask

- -

If you want to create an array of booleans from a mask you can use this code:

- -
function arrayFromMask (nMask) {
-  // nMask must be between -2147483648 and 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(", ") + "]");
-// prints "[true, true, false, true]", i.e.: 11, i.e.: 1011
-
- -

You can test both algorithms at the same time…

- -
var nTest = 19; // our custom mask
-var nResult = createMask.apply(this, arrayFromMask(nTest));
-
-alert(nResult); // 19
-
- -

For didactic purpose only (since there is the Number.toString(2) method), we show how it is possible to modify the arrayFromMask algorithm in order to create a string containing the binary representation of a number, rather than an array of booleans:

- -
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);
-// prints 00000000000000000000000000001011, i.e. 11
-
- -

명세

- - - - - - - - - - - - - - - - -
Specification
{{SpecName('ESDraft', '#sec-bitwise-not-operator', 'Bitwise NOT Operator')}}
{{SpecName('ESDraft', '#sec-binary-bitwise-operators', 'Binary Bitwise Operators')}}
{{SpecName('ESDraft', '#sec-bitwise-shift-operators', 'Bitwise Shift Operators')}}
- -

브라우저 호환성

- -

{{Compat("javascript.operators.bitwise")}}

- -

같이 보기

- - diff --git a/files/ko/web/javascript/reference/operators/comparison_operators/index.html b/files/ko/web/javascript/reference/operators/comparison_operators/index.html deleted file mode 100644 index cf5ae3afa2..0000000000 --- a/files/ko/web/javascript/reference/operators/comparison_operators/index.html +++ /dev/null @@ -1,216 +0,0 @@ ---- -title: 비교 연산자 -slug: Web/JavaScript/Reference/Operators/Comparison_Operators -tags: - - JavaScript - - Operator - - Reference -translation_of: Web/JavaScript/Reference/Operators -translation_of_original: Web/JavaScript/Reference/Operators/Comparison_Operators ---- -
{{jsSidebar("Operators")}}
- -

JavaScript는 엄격한 비교와 형변환 비교 두 가지의 비교 방법을 모두 가지고 있습니다. 엄격(일치) 비교(===)는 두 피연산자가 같은 자료형에, 그 내용도 일치해야만 참입니다. 추상(동등) 비교(==)는 비교 전에 두 피연산자를 동일한 자료형으로 변환합니다. 관계 추상 비교(<=)의 경우 {{glossary("primitive", "원시값")}}으로 바꾸고, 같은 자료형으로 다시 바꾼후 비교를 수행합니다.

- -

문자열의 경우 {{glossary("unicode", "유니코드")}} 값을 사용한 사전순으로 비교합니다.

- -
{{EmbedInteractiveExample("pages/js/expressions-comparisonoperators.html")}}
- - - -

비교 연산의 특징은 다음과 같습니다.

- -
    -
  • 두 문자열이 같은 문자 시퀀스로 구성되고, 같은 길이를 가지며, 같은 위치에 같은 문자가 존재하면 일치합니다.
  • -
  • 두 숫자는 숫자로서 같은 값(같은 숫자 값)이면 일치합니다. {{jsxref("NaN")}}은 자기 자신을 포함한 그 무엇과도 동등하지 않습니다. +0-0은 서로 일치합니다.
  • -
  • 두 불리언은 둘 다 true거나 false이면 일치합니다.
  • -
  • 서로 다른 두 객체는 절대 일치하지도, 동등하지도 않습니다.
  • -
  • 객체를 비교하는 표현식은 두 피연산자가 동일한 객체를 참조하는 경우에만 참입니다.
  • -
  • {{jsxref("null")}}과 {{jsxref("undefined")}}는 자기 자신과 일치하며, 서로 동등합니다.
  • -
- -

동치 연산자

- -

동등 연산자 (==)

- -

동등 연산자는 두 피연산자의 자료형이 같지 않은 경우 같아지도록 변환한 후, 엄격 비교를 수행합니다. 피연산자가 모두 객체라면, JavaScript는 내부 참조를 보고, 둘 다 메모리의 같은 객체를 바라보고 있는지 판별합니다.

- -

구문

- -
x == y
-
- -

예제

- -
  1   ==  1        // true
- "1"  ==  1        // true
-  1   == '1'       // true
-  0   == false     // true
-  0   == null      // false
-
-  0   == undefined // false
-null  == undefined // true
-
- -

부등 연산자 (!=)

- -

부등 연산자는 두 피연산자가 같지 않은 경우 참을 반환합니다. 피연산자의 자료형이 일치하지 않는 경우 적절한 자료형으로의 변환을 시도합니다. 피연산자가 모두 객체라면, JavaScript는 내부 참조를 보고, 서로 메모리의 다른 객체를 바라보고 있는지 판별합니다.

- -

구문

- -
x != y
- -

예제

- -
1 !=   2     // true
-1 !=  "1"    // false
-1 !=  '1'    // false
-1 !=  true   // false
-0 !=  false  // false
-
- -

일치 연산자 (===)

- -

일치 연산자는 자료형 변환 없이 두 연산자가 엄격히 같은지 판별합니다.

- -

구문

- -
x === y
- -

예제

- -
3 === 3   // true
-3 === '3' // false
- -

불일치 연산자 (!==)

- -

일치 연산자는 두 연산자가 같지 않거나, 같은 자료형이 아닐 때 참을 반환합니다.

- -

구문

- -
x !== y
- -

예제

- -
3 !== '3' // true
-4 !== 3   // true
-
- -

관계 연산자

- -

이 항목의 모든 연산자는 비교 전에 피연산자를 {{glossary("primitive", "원시값")}}으로 변환합니다. 둘 다 문자열이 되는 경우 사전순으로 비교하고, 그렇지 않으면 숫자로 변환합니다. {{jsxref("NaN")}}과의 비교는 항상 false를 반환합니다.

- -

초과 연산자 (>)

- -

초과 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 큰 경우 참을 반환합니다.

- -

구문

- -
x > y
- -

예제

- -
4 > 3 // true
-
- -

이상 연산자 (>=)

- -

이상 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 크거나 같으면 참을 반환합니다.

- -

구문

- -
 x >= y
- -

예제

- -
4 >= 3 // true
-3 >= 3 // true
-
- -

미만 연산자 (<)

- -

미만 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 작은 경우 참을 반환합니다.

- -

구문

- -
x < y
- -

예제

- -
3 < 4 // true
- -

이하 연산자 (<=)

- -

이하 연산자는 왼쪽 피연산자가 오른쪽 피연산자보다 작거나 같으면 참을 반환합니다.

- -

구문

- -
 x <= y
- -

예제

- -
3 <= 4 // true
-
- -

동치 연산자 사용하기

- -

표준 동치, 동등 연산자(==, !=)는 두 피연산자를 비교하기 위해 추상 동치 비교 알고리즘(Abstract Equlity Comparison Algorithm)을 사용합니다. 피연산자 간 자료형이 일치하지 않으면 우선 변환을 시도합니다. 예를 들어 표현식 5 == '5'에서는 비교 전 오른쪽 문자열을 {{jsxref("Number")}}로 변환합니다.

- -

엄격 동치, 일치 연산자(===, !==)는 엄격 동치 비교 알고리즘(Strict Equality Comparison Algorithm)을 사용하며, 같은 자료형을 가진 피연산자를 비교하기 위해 사용합니다. 피연산자 간 자료형이 일치하지 않으면 항상 false이므로, 5 !== '5'입니다.

- -

피연산자의 값은 물론 특정 자료형이어야 하는 경우 일치 연산자를 사용하세요. 그렇지 않은 경우 형변환을 자동으로 해주는 동등 연산자를 사용할 수도 있습니다.

- -

비교 과정에 자료형 변환이 필요한 경우 JavaScript는 {{jsxref("String")}}, {{jsxref("Number")}}, {{jsxref("Boolean")}}, {{jsxref("Object")}} 자료형을 다음과 같이 변환합니다.

- -
    -
  • 숫자와 문자열을 비교할 땐 문자열을 숫자로 변환합니다. 우선, 문자열에서 수학적 값을 도출합니다. 그 후 가장 가까운 Number 자료형 값으로 반올림합니다.
  • -
  • 하나의 연산자가 Boolean인 경우, true1, false0으로 변환합니다.
  • -
  • 객체를 문자열이나 숫자와 비교하는 경우, JavaScript는 객체의 기본값을 사용합니다. 연산자는 우선 객체의 valueOf() 또는 toString() 메서드를 사용해 문자열 혹은 숫자 값을 받으려 시도합니다. 실패할 경우 런타임 오류가 발생합니다.
  • -
  • 객체를 원시값과 비교하는 경우에만 객체의 변환이 발생합니다. 두 연산자가 모두 객체인 경우 변환하지 않으며, 둘 다 같은 객체를 참조하는 경우 참을 반환합니다.
  • -
- -
참고: String 객체는 자료형 객체지, 문자열이 아닙니다! String 객체는 거의 쓰이지 않으며, 이런 성질로 인해 아래의 결과는 예상치 못한 값일 수 있습니다.
- -
// 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'
- -

명세

- - - - - - - - - - - - - -
Status
{{SpecName('ESDraft', '#sec-equality-operators', 'Equality Operators')}}
{{SpecName('ESDraft', '#sec-relational-operators', 'Relational Operators')}}
- -

브라우저 호환성

- -

{{Compat("javascript.operators.comparison")}}

- -

같이 보기

- - diff --git a/files/ko/web/javascript/reference/operators/operator_precedence/index.html b/files/ko/web/javascript/reference/operators/operator_precedence/index.html new file mode 100644 index 0000000000..7a82346d09 --- /dev/null +++ b/files/ko/web/javascript/reference/operators/operator_precedence/index.html @@ -0,0 +1,462 @@ +--- +title: 연산자 우선순위 +slug: Web/JavaScript/Reference/Operators/연산자_우선순위 +tags: + - JavaScript + - Operator + - 연산자 + - 우선순위 +translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence +--- +
{{jsSidebar("Operators")}}
+ +

연산자 우선순위는 연산자를 실행하는 순서를 결정합니다. 우선순위가 높은 연산자가 먼저 실행됩니다.

+ +
{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}
+ + + +

우선순위와 결합성

+ +

아래와 같이 표현할 수 있는 표현식을 생각해 봅시다. 연산자1과 연산자2의 자리에는 아무 연산자를 넣을 수 있습니다.

+ +
a 연산자1 b 연산자2 c
+ +

두 연산자의 우선순위(아래 표 참조)가 다를 경우, 우선순위가 높은 연산자가 먼저 실행되고 결합성은 영향을 미치지 않습니다. 아래 예제에서는 덧셈이 곱셈보다 먼저 쓰였음에도 곱셈의 우선순위가 높기 때문에 먼저 실행됩니다.

+ +
console.log(3 + 10 * 2);   // 23을 출력
+console.log(3 + (10 * 2)); // 23을 출력, 괄호는 불필요함
+console.log((3 + 10) * 2); // 26을 출력, 괄호로 인해 실행 순서가 바뀜
+
+ +

좌결합성(왼쪽에서 오른쪽으로)은 표현식이 (a 연산자1 b) 연산자2 c와 같이, 우결합성(오른쪽에서 왼쪽으로)은 a 연산자1 (b 연산자2 c)와 같이 계산된다는 의미입니다. 대입 연산자는 우결합성이므로 다음과 같은 코드를 작성할 수 있습니다.

+ +
a = b = 5; // a = (b = 5);와 같음
+
+ +

이때 대입 연산자는 대입된 값을 반환하므로 ab의 값이 5가 됨을 예상할 수 있습니다. 우선 b의 값이 5로 설정되고, 그 다음에는 a의 값이 우변인 b = 5의 반환값 5로 설정됩니다.

+ +

다른 예시로, 좌결합성인 다른 산술 연산자와 달리 거듭제곱 연산자 (**)만은 우결합성입니다. 흥미로운 점으로 표현식의 평가는 결합성과 무관하게 항상 왼쪽에서 오른쪽으로 진행됩니다.

+ + + + + + + + + + + + + + + + +
코드출력
+
+function echo(name, num) {
+    console.log(name + " 항 평가함");
+    return num;
+}
+// 나눗셈 연산자 (/)에 주목
+console.log(echo("첫째", 6) / echo("둘째", 2));
+
+
+
+첫째 항 평가함
+둘째 항 평가함
+3
+
+
+
+function echo(name, num) {
+    console.log(name + " 항 평가함");
+    return num;
+}
+// 거듭제곱 연산자 (**)에 주목
+console.log(echo("첫째", 2) ** echo("둘째", 3));
+
+
+첫째 항 평가함
+둘째 항 평가함
+8
+
+ +

여러 연산자의 우선순위가 같을 때는 결합성을 고려합니다. 위에서와 같이 연산자가 하나이거나 연산자끼리 우선순위가 다를 경우에는 결합성이 결과에 영향을 미치지 않습니다. 아래의 예제에서 같은 종류의 연산자를 여러 번 사용했을 때 결합성이 결과에 영향을 미치는 것을 확인할 수 있습니다.

+ + + + + + + + + + + + + + + + + + + + +
코드출력
+
+function echo(name, num) {
+    console.log(name + " 항 평가함");
+    return num;
+}
+// 나눗셈 연산자 (/)에 주목
+console.log(echo("첫째", 6) / echo("둘째", 2) / echo("셋째", 3));
+
+
+
+첫째 항 평가함
+둘째 항 평가함
+셋째 항 평가함
+1
+
+
+
+function echo(name, num) {
+    console.log(name + " 항 평가함");
+    return num;
+}
+// 거듭제곱 연산자 (**)에 주목
+console.log(echo("첫째", 2) ** echo("둘째", 3) ** echo("셋째", 2));
+
+
+
+첫째 항 평가함
+둘째 항 평가함
+셋째 항 평가함
+512
+
+
+
+function echo(name, num) {
+    console.log(name + " 항 평가함");
+    return num;
+}
+// 첫 번째 거듭제곱 연산자 주변의 괄호에 주목
+console.log((echo("첫째", 2) ** echo("둘째", 3)) ** echo("셋째", 2));
+
+
+첫째 항 평가함
+둘째 항 평가함
+셋째 항 평가함
+64
+
+ +

위의 예제에서 나눗셈은 좌결합성이므로 6 / 3 / 2(6 / 3) / 2와 같습니다. 한편 거듭제곱은 우결합성이므로 2 ** 3 ** 22 ** (3 ** 2)와 같습니다. 그러므로 (2 ** 3) ** 2는 괄호로 인해 실행 순서가 바뀌기 때문에 위 표와 같이 64로 평가됩니다.

+ +

우선순위는 결합성보다 항상 우선하므로, 거듭제곱과 나눗셈을 같이 사용하면 나눗셈보다 거듭제곱이 먼저 계산됩니다. 예를 들어 2 ** 3 / 3 ** 2는 (2 ** 3) / (3 ** 2)와 같으므로 0.8888888888888888로 계산됩니다.

+ +

예제

+ +
3 > 2 && 2 > 1
+// true를 반환
+
+3 > 2 > 1
+// 3 > 2는 true인데, 부등호 연산자에서 true는 1로 변환되므로
+// true > 1은 1 > 1이 되고, 이는 거짓이다.
+// 괄호를 추가하면 (3 > 2) > 1과 같다.
+ +

+ +

다음 표는 우선순위 내림차순(21부터 1까지)으로 정렬되어 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
우선순위연산자 유형결합성연산자
21{{jsxref("Operators/Grouping", "그룹", "", 1)}}없음( … )
20{{jsxref("Operators/Property_Accessors", "멤버 접근", "#점_표기법", 1)}}좌결합성… . …
{{jsxref("Operators/Property_Accessors", "계산된 멤버 접근","#괄호_표기법", "1")}}좌결합성… [ … ]
{{jsxref("Operators/new","new")}} (매개변수 리스트 존재)없음new … ( … )
+

함수 호출

+
좌결합성… ( )
Optional chaining좌결합성?.
19{{jsxref("Operators/new","new")}} (매개변수 리스트 생략)우결합성new …
18{{jsxref("Operators/Arithmetic_Operators","후위 증가","#Increment", 1)}}없음… ++
{{jsxref("Operators/Arithmetic_Operators","후위 감소","#Decrement", 1)}}… --
17논리 NOT우결합성! …
비트 NOT~ …
단항 양부호+ …
단항 부정- …
전위 증가++ …
전위 감소-- …
{{jsxref("Operators/typeof", "typeof")}}typeof …
{{jsxref("Operators/void", "void")}}void …
{{jsxref("Operators/delete", "delete")}}delete …
{{jsxref("Operators/await", "await")}}await …
16거듭제곱우결합성… ** …
15곱셈좌결합성… * …
나눗셈… / …
나머지… % …
14덧셈좌결합성… + …
뺄셈… - …
13비트 왼쪽 시프트좌결합성… << …
비트 오른쪽 시프트… >> …
비트 부호 없는 오른쪽 시프트… >>> …
12미만좌결합성… < …
이하… <= …
초과… > …
이상… >= …
{{jsxref("Operators/in", "in")}}… in …
{{jsxref("Operators/instanceof", "instanceof")}}… instanceof …
11동등좌결합성… == …
부등… != …
일치… === …
불일치… !== …
10비트 AND좌결합성… & …
9비트 XOR좌결합성… ^ …
8비트 OR좌결합성… | …
7널 병합 연산자좌결합성… ?? …
6논리 AND좌결합성… && …
5논리 OR좌결합성… || …
4조건우결합성… ? … : …
3할당우결합성… = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
2{{jsxref("Operators/yield", "yield")}}우결합성yield …
{{jsxref("Operators/yield*", "yield*")}}yield* …
1쉼표 / 시퀀스좌결합성… , …
diff --git "a/files/ko/web/javascript/reference/operators/\353\205\274\353\246\254_\354\227\260\354\202\260\354\236\220(logical_operators)/index.html" "b/files/ko/web/javascript/reference/operators/\353\205\274\353\246\254_\354\227\260\354\202\260\354\236\220(logical_operators)/index.html" deleted file mode 100644 index b442b1d7bd..0000000000 --- "a/files/ko/web/javascript/reference/operators/\353\205\274\353\246\254_\354\227\260\354\202\260\354\236\220(logical_operators)/index.html" +++ /dev/null @@ -1,250 +0,0 @@ ---- -title: 논리 연산자 -slug: Web/JavaScript/Reference/Operators/논리_연산자(Logical_Operators) -tags: - - JavaScript - - Logic - - Not - - Operator - - Reference - - and - - or - - 논리 -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 && expr2expr1true로 변환할 수 있는 경우 expr2을 반환하고, 그렇지 않으면 expr1을 반환합니다.
논리 OR (||)expr1 || expr2 -

expr1true로 변환할 수 있으면 expr1을 반환하고, 그렇지 않으면 expr2를 반환합니다.

-
논리 NOT (!)!expr단일 피연산자를 true로 변환할 수 있으면 false를 반환합니다. 그렇지 않으면 true를 반환합니다.
- -

값을 true로 변환하면 값이 {{Glossary("truthy", "참")}}인 것입니다.
- 값을 false로 변환할 수 있으면 값이 {{Glossary("falsy", "거짓")}}인 것입니다.

- -

거짓으로 변환할 수 있는 표현의 예는 다음과 같습니다.

- -
    -
  • null
  • -
  • NaN
  • -
  • 0
  • -
  • 빈 문자열 ("", '', ``)
  • -
  • undefined
  • -
- -

&& 연산자와 || 연산자를 불리언 값이 아닌 피연산자와 함께 사용될 수 있지만, 반환 값을 항상 불리언 원시값으로 변환할 수 있으므로 불리언 연산자로 생각할 수 있습니다. 반환 값을 직접 불리언으로 바꾸려면 {{jsxref("Boolean")}} 함수나 이중 부정 연산자를 사용하세요.

- -

단락 평가

- -

논리 표현식을 좌측부터 평가하므로, 아래 규칙에 따라 단락(short-circuit) 평가를 수행합니다.

- -
    -
  • (거짓 표현식) && expr은 거짓 표현식으로 단락 평가됩니다.
  • -
  • (참 표현식) || expr은 참 표현식으로 단락 평가됩니다.
  • -
- -

"단락"이란, 위 규칙에서 expr을 평가하지 않는다는 뜻입니다. 따라서 평가 중 발생해야 할 부작용(예: expr이 함수 호출이면 절대 호출하지 않음)도 나타나지 않습니다. 단락 평가가 발생하는 원인은 첫 번째 피연산자를 평가한 순간 이미 연산자의 결과가 정해지기 때문입니다. 다음 예제를 살펴보세요.

- -
function A(){ console.log('A 호출'); return false; }
-function B(){ console.log('B 호출'); return true; }
-
-console.log( A() && B() );
-// 함수 호출로 인해 콘솔에 "A 호출" 기록
-// 그 후 연산자의 결과값인 "false" 기록
-
-console.log( B() || A() );
-// 함수 호출로 인해 콘솔에 "B 호출" 기록
-// 그 후 연산자의 결과인 "true" 기록
-
- -

연산자 우선순위

- -

다음 두 식은 똑같아 보이지만, && 연산자는 || 이전에 실행되므로 서로 다릅니다. 연산자 우선순위를 참고하세요.

- -
true || false && false      // returns true, because && is executed first
-(true || false) && false    // returns false, because operator precedence cannot apply
- -

논리 AND (&&)

- -

다음은 &&(논리 AND) 연산자의 예제입니다.

- -
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
- -

논리 OR (||)

- -

다음은 ||(논리 OR) 연산자의 예제입니다.

- -
o1 = true  || true       // t || t returns true
-o2 = false || true       // f || t returns true
-o3 = true  || false      // t || f returns true
-o4 = false || (3 == 4)   // f || f returns false
-o5 = 'Cat' || 'Dog'      // t || t returns "Cat"
-o6 = false || 'Cat'      // f || t returns "Cat"
-o7 = 'Cat' || false      // t || f returns "Cat"
-o8 = ''    || false      // f || f returns false
-o9 = false || ''         // f || f returns ""
-o10 = false || varObject // f || object returns varObject
-
- -

논리 NOT (!)

- -

다음은 !(논리 NOT) 연산자의 예제입니다.

- -
n1 = !true               // !t returns false
-n2 = !false              // !f returns true
-n3 = !''                 // !f returns true
-n4 = !'Cat'              // !t returns false
-
- -

이중 NOT (!!)

- -

NOT 연산자 다수를 연속해서 사용하면 아무 값이나 불리언 원시값으로 강제 변환할 수 있습니다. 변환 결과는 피연산자 값의 "참스러움"이나 "거짓스러움"에 따릅니다. ({{Glossary("truthy", "참")}}과 {{Glossary("falsy", "거짓")}}을 참고하세요)

- -

동일한 변환을 {{jsxref("Boolean")}} 함수로도 수행할 수 있습니다.

- -
n1 = !!true                   // !!truthy returns true
-n2 = !!{}                     // !!truthy returns true: any object is truthy...
-n3 = !!(new Boolean(false))   // ...even Boolean objects with a false .valueOf()!
-n4 = !!false                  // !!falsy returns false
-n5 = !!""                     // !!falsy returns false
-n6 = !!Boolean(false)         // !!falsy returns false
-
- -

불리언 변환 규칙

- -

AND에서 OR로 변환

- -

불리언 계산에서, 다음 두 코드는 항상 같습니다.

- -
bCondition1 && bCondition2
-
- -
!(!bCondition1 || !bCondition2)
- -

OR에서 AND로 변환

- -

불리언 계산에서, 다음 두 코드는 항상 같습니다.

- -
bCondition1 || bCondition2
-
- -
!(!bCondition1 && !bCondition2)
- -

NOT 간 변환

- -

불리언 계산에서, 다음 두 코드는 항상 같습니다.

- -
!!bCondition
-
- -
bCondition
- -

중첩 괄호 제거

- -

논리 표현식은 항상 왼쪽에서 오른쪽으로 평가되므로, 몇 가지 규칙을 따르면 복잡한 표현식에서 괄호를 제거할 수 있습니다.

- -

중첩 AND 제거

- -

불리언의 합성 계산에서, 다음 두 코드는 항상 같습니다.

- -
bCondition1 || (bCondition2 && bCondition3)
-
- -
bCondition1 || bCondition2 && bCondition3
- -

중첩 OR 제거

- -

불리언의 합성 계산에서, 다음 두 코드는 항상 같습니다.

- -
bCondition1 && (bCondition2 || bCondition3)
-
- -
!(!bCondition1 || !bCondition2 && !bCondition3)
- -

명세

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationStatusComment
{{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")}}

- -

같이 보기

- -
    -
  • 비트 연산자
  • -
  • {{jsxref("Boolean")}}
  • -
  • {{Glossary("truthy", "참")}}
  • -
  • {{Glossary("falsy", "거짓")}}
  • -
diff --git "a/files/ko/web/javascript/reference/operators/\354\227\260\354\202\260\354\236\220_\354\232\260\354\204\240\354\210\234\354\234\204/index.html" "b/files/ko/web/javascript/reference/operators/\354\227\260\354\202\260\354\236\220_\354\232\260\354\204\240\354\210\234\354\234\204/index.html" deleted file mode 100644 index 7a82346d09..0000000000 --- "a/files/ko/web/javascript/reference/operators/\354\227\260\354\202\260\354\236\220_\354\232\260\354\204\240\354\210\234\354\234\204/index.html" +++ /dev/null @@ -1,462 +0,0 @@ ---- -title: 연산자 우선순위 -slug: Web/JavaScript/Reference/Operators/연산자_우선순위 -tags: - - JavaScript - - Operator - - 연산자 - - 우선순위 -translation_of: Web/JavaScript/Reference/Operators/Operator_Precedence ---- -
{{jsSidebar("Operators")}}
- -

연산자 우선순위는 연산자를 실행하는 순서를 결정합니다. 우선순위가 높은 연산자가 먼저 실행됩니다.

- -
{{EmbedInteractiveExample("pages/js/expressions-operatorprecedence.html")}}
- - - -

우선순위와 결합성

- -

아래와 같이 표현할 수 있는 표현식을 생각해 봅시다. 연산자1과 연산자2의 자리에는 아무 연산자를 넣을 수 있습니다.

- -
a 연산자1 b 연산자2 c
- -

두 연산자의 우선순위(아래 표 참조)가 다를 경우, 우선순위가 높은 연산자가 먼저 실행되고 결합성은 영향을 미치지 않습니다. 아래 예제에서는 덧셈이 곱셈보다 먼저 쓰였음에도 곱셈의 우선순위가 높기 때문에 먼저 실행됩니다.

- -
console.log(3 + 10 * 2);   // 23을 출력
-console.log(3 + (10 * 2)); // 23을 출력, 괄호는 불필요함
-console.log((3 + 10) * 2); // 26을 출력, 괄호로 인해 실행 순서가 바뀜
-
- -

좌결합성(왼쪽에서 오른쪽으로)은 표현식이 (a 연산자1 b) 연산자2 c와 같이, 우결합성(오른쪽에서 왼쪽으로)은 a 연산자1 (b 연산자2 c)와 같이 계산된다는 의미입니다. 대입 연산자는 우결합성이므로 다음과 같은 코드를 작성할 수 있습니다.

- -
a = b = 5; // a = (b = 5);와 같음
-
- -

이때 대입 연산자는 대입된 값을 반환하므로 ab의 값이 5가 됨을 예상할 수 있습니다. 우선 b의 값이 5로 설정되고, 그 다음에는 a의 값이 우변인 b = 5의 반환값 5로 설정됩니다.

- -

다른 예시로, 좌결합성인 다른 산술 연산자와 달리 거듭제곱 연산자 (**)만은 우결합성입니다. 흥미로운 점으로 표현식의 평가는 결합성과 무관하게 항상 왼쪽에서 오른쪽으로 진행됩니다.

- - - - - - - - - - - - - - - - -
코드출력
-
-function echo(name, num) {
-    console.log(name + " 항 평가함");
-    return num;
-}
-// 나눗셈 연산자 (/)에 주목
-console.log(echo("첫째", 6) / echo("둘째", 2));
-
-
-
-첫째 항 평가함
-둘째 항 평가함
-3
-
-
-
-function echo(name, num) {
-    console.log(name + " 항 평가함");
-    return num;
-}
-// 거듭제곱 연산자 (**)에 주목
-console.log(echo("첫째", 2) ** echo("둘째", 3));
-
-
-첫째 항 평가함
-둘째 항 평가함
-8
-
- -

여러 연산자의 우선순위가 같을 때는 결합성을 고려합니다. 위에서와 같이 연산자가 하나이거나 연산자끼리 우선순위가 다를 경우에는 결합성이 결과에 영향을 미치지 않습니다. 아래의 예제에서 같은 종류의 연산자를 여러 번 사용했을 때 결합성이 결과에 영향을 미치는 것을 확인할 수 있습니다.

- - - - - - - - - - - - - - - - - - - - -
코드출력
-
-function echo(name, num) {
-    console.log(name + " 항 평가함");
-    return num;
-}
-// 나눗셈 연산자 (/)에 주목
-console.log(echo("첫째", 6) / echo("둘째", 2) / echo("셋째", 3));
-
-
-
-첫째 항 평가함
-둘째 항 평가함
-셋째 항 평가함
-1
-
-
-
-function echo(name, num) {
-    console.log(name + " 항 평가함");
-    return num;
-}
-// 거듭제곱 연산자 (**)에 주목
-console.log(echo("첫째", 2) ** echo("둘째", 3) ** echo("셋째", 2));
-
-
-
-첫째 항 평가함
-둘째 항 평가함
-셋째 항 평가함
-512
-
-
-
-function echo(name, num) {
-    console.log(name + " 항 평가함");
-    return num;
-}
-// 첫 번째 거듭제곱 연산자 주변의 괄호에 주목
-console.log((echo("첫째", 2) ** echo("둘째", 3)) ** echo("셋째", 2));
-
-
-첫째 항 평가함
-둘째 항 평가함
-셋째 항 평가함
-64
-
- -

위의 예제에서 나눗셈은 좌결합성이므로 6 / 3 / 2(6 / 3) / 2와 같습니다. 한편 거듭제곱은 우결합성이므로 2 ** 3 ** 22 ** (3 ** 2)와 같습니다. 그러므로 (2 ** 3) ** 2는 괄호로 인해 실행 순서가 바뀌기 때문에 위 표와 같이 64로 평가됩니다.

- -

우선순위는 결합성보다 항상 우선하므로, 거듭제곱과 나눗셈을 같이 사용하면 나눗셈보다 거듭제곱이 먼저 계산됩니다. 예를 들어 2 ** 3 / 3 ** 2는 (2 ** 3) / (3 ** 2)와 같으므로 0.8888888888888888로 계산됩니다.

- -

예제

- -
3 > 2 && 2 > 1
-// true를 반환
-
-3 > 2 > 1
-// 3 > 2는 true인데, 부등호 연산자에서 true는 1로 변환되므로
-// true > 1은 1 > 1이 되고, 이는 거짓이다.
-// 괄호를 추가하면 (3 > 2) > 1과 같다.
- -

- -

다음 표는 우선순위 내림차순(21부터 1까지)으로 정렬되어 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
우선순위연산자 유형결합성연산자
21{{jsxref("Operators/Grouping", "그룹", "", 1)}}없음( … )
20{{jsxref("Operators/Property_Accessors", "멤버 접근", "#점_표기법", 1)}}좌결합성… . …
{{jsxref("Operators/Property_Accessors", "계산된 멤버 접근","#괄호_표기법", "1")}}좌결합성… [ … ]
{{jsxref("Operators/new","new")}} (매개변수 리스트 존재)없음new … ( … )
-

함수 호출

-
좌결합성… ( )
Optional chaining좌결합성?.
19{{jsxref("Operators/new","new")}} (매개변수 리스트 생략)우결합성new …
18{{jsxref("Operators/Arithmetic_Operators","후위 증가","#Increment", 1)}}없음… ++
{{jsxref("Operators/Arithmetic_Operators","후위 감소","#Decrement", 1)}}… --
17논리 NOT우결합성! …
비트 NOT~ …
단항 양부호+ …
단항 부정- …
전위 증가++ …
전위 감소-- …
{{jsxref("Operators/typeof", "typeof")}}typeof …
{{jsxref("Operators/void", "void")}}void …
{{jsxref("Operators/delete", "delete")}}delete …
{{jsxref("Operators/await", "await")}}await …
16거듭제곱우결합성… ** …
15곱셈좌결합성… * …
나눗셈… / …
나머지… % …
14덧셈좌결합성… + …
뺄셈… - …
13비트 왼쪽 시프트좌결합성… << …
비트 오른쪽 시프트… >> …
비트 부호 없는 오른쪽 시프트… >>> …
12미만좌결합성… < …
이하… <= …
초과… > …
이상… >= …
{{jsxref("Operators/in", "in")}}… in …
{{jsxref("Operators/instanceof", "instanceof")}}… instanceof …
11동등좌결합성… == …
부등… != …
일치… === …
불일치… !== …
10비트 AND좌결합성… & …
9비트 XOR좌결합성… ^ …
8비트 OR좌결합성… | …
7널 병합 연산자좌결합성… ?? …
6논리 AND좌결합성… && …
5논리 OR좌결합성… || …
4조건우결합성… ? … : …
3할당우결합성… = …
… += …
… -= …
… **= …
… *= …
… /= …
… %= …
… <<= …
… >>= …
… >>>= …
… &= …
… ^= …
… |= …
2{{jsxref("Operators/yield", "yield")}}우결합성yield …
{{jsxref("Operators/yield*", "yield*")}}yield* …
1쉼표 / 시퀀스좌결합성… , …
diff --git a/files/ko/web/javascript/reference/statements/default/index.html b/files/ko/web/javascript/reference/statements/default/index.html deleted file mode 100644 index 4fe127b7db..0000000000 --- a/files/ko/web/javascript/reference/statements/default/index.html +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: default -slug: Web/JavaScript/Reference/Statements/default -tags: - - JavaScript - - Keyword - - Reference -translation_of: Web/JavaScript/Reference/Statements/switch -translation_of_original: Web/JavaScript/Reference/Statements/default ---- -
{{jsSidebar("Statements")}}
- -

default 키워드는 {{jsxref("Statements/switch", "switch")}} 구문과 {{jsxref("Statements/export", "export")}} 구문에서 사용할 수 있습니다.

- -
{{EmbedInteractiveExample("pages/js/statement-default.html")}}
- - - -

구문

- -

{{jsxref("Statements/switch", "switch")}} 구문 내에서는 다음과 같이 사용합니다.

- -
switch (expression) {
-  case value1:
-    //Statements executed when the result of expression matches value1
-    [break;]
-  default:
-    //Statements executed when none of the values match the value of the expression
-    [break;]
-}
- -

{{jsxref("Statements/export", "export")}} 구문 내에서는 다음과 같이 사용합니다.

- -
export default nameN 
- -

설명

- -

세부사항을 보려면,

- -
    -
  • {{jsxref("Statements/switch", "switch")}} 구문,
  • -
  • {{jsxref("Statements/export", "export")}} 구문 페이지를 확인하세요.
  • -
- -

예제

- -

switch에서 default 사용

- -

아래 예제에서 expr 이 "오렌지" 또는 "사과"일 때, 프로그램은 값을 "오렌지" 또는 "사과"와 일치시키고 해당 명령문을 실행합니다. 기본(default) 키워드는 다른 경우에 도움이 되며 연관된 명령문을 실행합니다.

- -
switch (expr) {
-  case '오렌지':
-    console.log('오렌지는 1000원입니다.');
-    break;
-  case '사과':
-    console.log('사과는 500원입니다.');
-    break;
-  default:
-    console.log('죄송합니다. ' + expr + '의 재고가 다 떨어졌습니다.');
-}
- -

export에서 default 사용

- -

단일 값을 내보내거나 모듈의 기본 값이 필요한 경우, 기본 내보내기를 사용할 수 있습니다.

- -
// module "my-module.js"
-let cube = function cube(x) {
-  return x * x * x;
-};
-export default cube;
- -

다른 스크립트에서 가져오는 건 간단합니다.

- -
// module "my-module.js"
-import cube from 'my-module';  //default export gave us the liberty to say import cube, instead of import cube from 'my-module'
-console.log(cube(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")}}

- -

같이 보기

- -
    -
  • {{jsxref("Statements/export", "export")}}
  • -
  • {{jsxref("Statements/switch", "switch")}}
  • -
diff --git a/files/ko/web/javascript/shells/index.html b/files/ko/web/javascript/shells/index.html new file mode 100644 index 0000000000..718fa8bdc2 --- /dev/null +++ b/files/ko/web/javascript/shells/index.html @@ -0,0 +1,40 @@ +--- +title: JavaScript 쉘 +slug: Web/JavaScript/쉘 +translation_of: Web/JavaScript/Shells +--- +
{{JsSidebar}}
+ +

여러분은 JavaScript 쉘을 통해 웹페이지 새로고침하지 않고 빠르게 JavaScript 의 코드를 테스트해볼 수 있습니다. 코드를 개발하고 디버깅하는데 매우 유용한 도구입니다.

+ +

독립적으로 사용할 수 있는 JavaScript 쉘

+ +

아래의 Javascript 쉘은 펄과 파이썬과 같이 독립적인 환경을 제공합니다.

+ +
    +
  • Node.js - Node.js는 빠르고 확장 가능한 네트워크 어플리케이션을 쉽게 만들 수 있는 플랫폼입니다.
  • +
  • JSDB - Windows, Mac, Linux 환경에 맞는 컴파일된 바이너리를 제공하는 독립적인 독립적인 Javascript 쉘입니다.
  • +
  • JavaLikeScript - 네이티브와 JavaScript 라이브러리 모두를 제공하는 독립적이고 확장 가능한 JavaScript 쉘입니다.
  • +
  • GLUEscript - 크로스-플랫폼 JavaScript 어플리케이션을 제작하기 위한 독립적인 JavaScript 쉘입니다. GUI 앱을 위한 wxWidgets(구 wxJavaScript)를 사용할 수 있습니다.
  • +
  • jspl - Perl의 영향을 받은 독립적인 JavaScript 쉘입니다. JavaScript에서 직접 perl 모듈을 사용할 수 있습니다: 데이터베이스 통합을 위한 DBI, GUI 앱을 위한 GTK2, 시스템 프로그래밍을 위한 POSIX, 기타 등등. 현재로서는 JavaScript 프로그래머를 위한 최고의 CPAN입니다.
  • +
  • ShellJS - Node.js를 위한 포터블 Unix 쉘 명령도구입니다.
  • +
+ +

JavaScript 쉘 리스트

+ +

아래는 Mozilla에서 사용할 수 있는 JavaScript Shell입니다.

+ +
    +
  • Firefox는 Scratchpad라 불리는 자바스크립트 내장 콘솔을 가지고있습니다.(version6 이후)
  • +
  • JavaScript Shell (js) - JavaScript를 위한 command line인터프리터입니다.
  • +
  • XPConnect인 xpcshell - Mozilla개발자는 위한 유용한 쉘 입니다. (가끔 필요할거에요.)
  • +
  • Babel REPL - 최신 자바스크립트를 시험해 볼 수 있는 브라우저 기반 REPL입니다.
  • +
  • ES6Console.com - 브라우저에서 ECMAScript 2015 코드를 테스트 해보기위한 open-source JavaScript 콘솔 입니다.
  • +
  • jsconsole.com -- 웹에서 빠른속도록 JavaScript 코드를 테스트 해 볼 수 있는 open-source JavaScript 콘솔 입니다.
  • +
  • JavaScript Shell (web page) - Extension Developer's Extension의 일부 기능으로 사용 가능합니다.
  • +
  • Jash: JavaScript Shell - 웹에서 커맨드라인접속이 가능한 DHTML 기반 쉘 입니다.
  • +
  • MozRepl - Firefox 및 기타 Mozilla 응용 프로그램에 연결하고 코드를 실행하는 중에 코드내용을 다루거나 확인 할 수 있습니다.
  • +
  • Execute JS - (더이상 지원되지않음) - 확장 된 JavaScript 콘솔을 제공하는 Firefox 확장 기능입니다. 임의의 JavaScript 코드 및 수정 기능을 편안하게 입력하고 실행할 수 있습니다.
  • +
  • xqjs - Firefox를 위한 간단한 콘솔
  • +
  • Firebug - 콘솔을 포함한 Firefox 개발자도구입니다.
  • +
diff --git "a/files/ko/web/javascript/\354\211\230/index.html" "b/files/ko/web/javascript/\354\211\230/index.html" deleted file mode 100644 index 718fa8bdc2..0000000000 --- "a/files/ko/web/javascript/\354\211\230/index.html" +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: JavaScript 쉘 -slug: Web/JavaScript/쉘 -translation_of: Web/JavaScript/Shells ---- -
{{JsSidebar}}
- -

여러분은 JavaScript 쉘을 통해 웹페이지 새로고침하지 않고 빠르게 JavaScript 의 코드를 테스트해볼 수 있습니다. 코드를 개발하고 디버깅하는데 매우 유용한 도구입니다.

- -

독립적으로 사용할 수 있는 JavaScript 쉘

- -

아래의 Javascript 쉘은 펄과 파이썬과 같이 독립적인 환경을 제공합니다.

- -
    -
  • Node.js - Node.js는 빠르고 확장 가능한 네트워크 어플리케이션을 쉽게 만들 수 있는 플랫폼입니다.
  • -
  • JSDB - Windows, Mac, Linux 환경에 맞는 컴파일된 바이너리를 제공하는 독립적인 독립적인 Javascript 쉘입니다.
  • -
  • JavaLikeScript - 네이티브와 JavaScript 라이브러리 모두를 제공하는 독립적이고 확장 가능한 JavaScript 쉘입니다.
  • -
  • GLUEscript - 크로스-플랫폼 JavaScript 어플리케이션을 제작하기 위한 독립적인 JavaScript 쉘입니다. GUI 앱을 위한 wxWidgets(구 wxJavaScript)를 사용할 수 있습니다.
  • -
  • jspl - Perl의 영향을 받은 독립적인 JavaScript 쉘입니다. JavaScript에서 직접 perl 모듈을 사용할 수 있습니다: 데이터베이스 통합을 위한 DBI, GUI 앱을 위한 GTK2, 시스템 프로그래밍을 위한 POSIX, 기타 등등. 현재로서는 JavaScript 프로그래머를 위한 최고의 CPAN입니다.
  • -
  • ShellJS - Node.js를 위한 포터블 Unix 쉘 명령도구입니다.
  • -
- -

JavaScript 쉘 리스트

- -

아래는 Mozilla에서 사용할 수 있는 JavaScript Shell입니다.

- -
    -
  • Firefox는 Scratchpad라 불리는 자바스크립트 내장 콘솔을 가지고있습니다.(version6 이후)
  • -
  • JavaScript Shell (js) - JavaScript를 위한 command line인터프리터입니다.
  • -
  • XPConnect인 xpcshell - Mozilla개발자는 위한 유용한 쉘 입니다. (가끔 필요할거에요.)
  • -
  • Babel REPL - 최신 자바스크립트를 시험해 볼 수 있는 브라우저 기반 REPL입니다.
  • -
  • ES6Console.com - 브라우저에서 ECMAScript 2015 코드를 테스트 해보기위한 open-source JavaScript 콘솔 입니다.
  • -
  • jsconsole.com -- 웹에서 빠른속도록 JavaScript 코드를 테스트 해 볼 수 있는 open-source JavaScript 콘솔 입니다.
  • -
  • JavaScript Shell (web page) - Extension Developer's Extension의 일부 기능으로 사용 가능합니다.
  • -
  • Jash: JavaScript Shell - 웹에서 커맨드라인접속이 가능한 DHTML 기반 쉘 입니다.
  • -
  • MozRepl - Firefox 및 기타 Mozilla 응용 프로그램에 연결하고 코드를 실행하는 중에 코드내용을 다루거나 확인 할 수 있습니다.
  • -
  • Execute JS - (더이상 지원되지않음) - 확장 된 JavaScript 콘솔을 제공하는 Firefox 확장 기능입니다. 임의의 JavaScript 코드 및 수정 기능을 편안하게 입력하고 실행할 수 있습니다.
  • -
  • xqjs - Firefox를 위한 간단한 콘솔
  • -
  • Firebug - 콘솔을 포함한 Firefox 개발자도구입니다.
  • -
diff --git "a/files/ko/web/javascript/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" "b/files/ko/web/javascript/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" deleted file mode 100644 index 4eeb42cae2..0000000000 --- "a/files/ko/web/javascript/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" +++ /dev/null @@ -1,328 +0,0 @@ ---- -title: 시작하기 (자바스크립트 튜토리얼) -slug: Web/JavaScript/시작하기 -translation_of: Learn/Getting_started_with_the_web/JavaScript_basics -translation_of_original: Web/JavaScript/Getting_Started ---- -

왜 자바스크립트인가?

-

자바스크립트는 종종 오해할 수 있는 강력하고 복잡한 컴퓨터 언어이다. 사용자가 쉽게 데이터를 입력하고 결과를 볼 수 있게 어플리케이션을 빠르게 개발 할 수 있다.

-

 웹브라우저를 중심으로 또한 ECMAScript로 알려진 자바스크립트의 주요 장점은 이와 같이 브라우저를 지원하는 모든 플랫폼에 동일한 결과를 만들 수 있다. 이 페이지의 예제는 구글 맵스처럼 맥 OS와 윈도우, 리눅스에서 실행한다. 수많은 자바스크립트 라이브러리의 최근 성장과 함께 AJax 어플리케이션을 개발하거나 이벤트 처리하기, 에니메이션 만들기, DOM 엘리먼트 선택하기, 도큐먼트 탐색하기가 이제 더욱 쉬워졌다. 다양한 소유권의 이익에 의해 추진된 다른 기술의 과대 광고와는 달리 자바스크립트는 모두 무료이면서 보편적으로 채택된 클라이언트 사이드 프로그래밍 언어이면서 정말이지 유일한 크로스 플래폼이다.

-

당신이 이미 알아야 하는 것

-

자바스크립트는 프로그래밍을 같이 시작하기 위해 매우 쉬운 언어이다. 시작하기 위해서  당신이 필요한 모든 것은 텍스트 에디터와  웹브라우저이다.  

-

이 문서의 범위를 벗어나는 자바스크립트와 함께 개발되고 통합 할 수 있는 다른 기술은 많이 있다. 첫날부터 구글맵스과 같이 완전한 어플리케이션을 만들 것이라고 기대하지 마라!

-

시작하기

-

자바스크립트로 시작하기는 매우 쉽다. 당신은 복잡한 개발 프로그램 설치가 필요가 없다. 컴파일러를 사용하거나 프로그램 만들기, 쉘을 어떻게 사용하는지 알 필요가 없다. 자바스크립트는 당신의 웹 브라우저에서 해석 된다. 당신이 해야 할 모든 일은 텍스트 파일에 당신의 프로그램을 저장하고 당신의 웹브라우저를 연다. 단지 그 것이다!

-

자바스크립트는 입문 컴퓨터 언어로서 최고의 프로그래밍 언어이다. 새로운 학생에게  즉시 피드백 할 수 있게 하고 그들이 아마도 그들의 실생활에 유용한 것을 발견할 수 있는 도구들에 관한 것을 그들에게 가르친다. 이것은 전용 소프트웨어 개발자를 위해 정말 유용한 C, C++, JAVA 와는 뚜렷하게  대조적이다. 

-

브라우저 호환성 이슈들

-

다른 브라우저에서 사용이 가능한 어떤 기능 중에는 차이가 있다. Mozilla, Chrome, Microsoft IE, Apple Safari, Opera에서 가동하는 것에 따라 변동될 수 있다. 이런 변동사항을 문서화 하려고 한다.  사용 가능한 다양한 크로스 플랫폼 자바스크립트 API 사용하여 이런 이슈들을 완하시킬 수 있다. 이런 API는 공통 기능으로 제공하고 이 브라우저의  변동된 것을 숨긴다. 

-

예제를 시도하는 방법

-

아래의 예제들은  몇가지 샘플 코드를 가지고 있다. 이 예제들을 시도하는 방법은 여러가지가 있다. 만약 당신이 이미 당신의 웹사이트를 가지고 있다면 당신은 당신의 웹사이트에 새로운 웹 페이지로써 이 예제들을 저장할 수 있어야 한다.

-

만약 당신이 당신의 웹사이트를 가지고 있지 않다면 당신의 컴퓨터에 파일로써 이 예제들을 저장할 수 있고 당신이 현재 사용하고 있는 웹브라우저를 통해 예제들을 열 수 있다. 자바스크립트는 이런 이유로 시작하려는 프로그래머가 사용하기 매운 쉬운 언어이다. 당신은 컴파일러 또는 개발 환경이 필요하지 않다. 그리고 당신과 당신의 브라우저가 시작하기 위해서 필요한 모든 것이다!

-

예제 : 마우스 클릭 잡기

-

이벤트 핸들링(이벤트 타입들, 핸들러 등록, 전파 등)의 특성은 이 간단한 예제들을 완전히 적용하기에는 너무 광범위하다. 그런데 이 예제는 자바스크립트 이벤트 시스템에 대한 조금의 탐구도 없이 마우스 클릭을 잡기를 설명할 수 없다. 이 예제는 자바스크립트 이벤트에 관해 전체 자세한 내용을 가볍게 스쳐 지나 갈 것이고 만약 당신이 여기 설명된 기본 기능의 범위를 넘어서고 싶다면 자바스크립트 이벤트 시스템에 관해 더 자세히 읽어야 함을 명심하라.

-

'마우스'이벤트들은 사용자 동작에 반응한 웹브라우저에 의해 발생된 전체 이벤트의  집합이다.다음은 사용자의 마우스 동작에 대한 응답으로 방출되는 이벤트의 목록이다.

-
    -
  • Click - 사용자가 마우스를 클릭했을 때 발생
  • -
  • DblClick - 사용자가 마우스를 더블 클릭했을 때 발생
  • -
  • MouseDown -  사용자가 마우스 버튼을 눌렀을 때 발생(클릭의 전반부)
  • -
  • MouseUp - 사용자가 마우스 버튼을 해제했을 때 발생(클릭의 후반후)
  • -
  • MouseOut - 마우스 포인터가 객체의 그래픽 범위를 떠나려고 할때 발생
  • -
  • MouseOver -  마우스 포인터가 객체의 그래픽 범위를 진입하려고 할때 발생
  • -
  • MouseMove - 마우스 포인터가 객체의 그래픽 범위 안에서 마우스 포인터를 움직이려 할때 발생
  • -
  • ContextMenu - 사용자가 오른쪽 마우스 버튼을 클릭했을 때 발생
  • -
-

인라인 이벤트 핸들러, HTML의 최신버전에서 주의할 것은 다시 말하면 하나가 태그 애트리뷰트들로써 추가 되었다는 것은 모두 소문자 이고 스크립트의 이벤트 핸들러가 항상 모든 소문자이어야 하는 것을 예상된다.

-

이벤트 핸들러를 등록하려는 이러한 이벤트들을 캡처하기 위해 가장 간단한 방법은 HTML을 사용하여 당신의 엘리먼트의 애트리뷰트들로서 개별적인 이벤트들을 지정하는 것이다.

-

예제:

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

당신이 실행하기 원하는 자바스크립트 코드를 애트리뷰트 값으로서 그때마다 처리할 수 있다. 또는 당신은 HTML 페이지안에 <script> 블록에 정의되어진 함수를 호출 할 수 있다 :

-
<script>
-  function clickHandler() {
-     alert("Hello, World!");
-  }
-</script>
-<span onclick="clickHandler();">Click Here</span>
-

또한 발생된 이벤트 객체는 캡처하거나 참조할 수 있으며 객체가 이벤트를 받거나 이벤트 타입 그리고 마우스가 클릭됐을 때 그러한 이벤트에 관한 특성을 접근하는 무언가 개발하는 것을  제공할 수 있다. 인라인 예제를 다시 사용 하라:

-
<script>
-  function clickHandler(event) {
-    var eType = event.type;
-    /* 다음은 호환성을 위한 것이다. */
-    /* Moz는 이벤트 객체의 target 프로퍼티로 채운다. */
-    /* IE는 srcElement 프로퍼티로 채운다.*/
-    var eTarget = event.target || event.srcElement;
-
-    alert( "Captured Event (type=" + eType + ", target=" + eTarget );
-  }
-</script>
-<span onclick="clickHandler(event);">Click Here</span>
-

당신의 HTML안에 이벤트를 수신 등록 이외에 당신은 당신의 자바스크립트에 의해 생성된 어떠한 HTML엘리먼트 객체의 똑같은 이름으로 애트리뷰트들을 마찬가지로 설정할 수 있다. 아래의 예는 span 객체를 인스터트화하고 페이지의 body에  추가하고 mouse-over, mouse-out, mouse-down, mouse-up 이벤트들을 수신하기위해 span 객체를 등록한다. 

-
<body></body>
-<script>
-  function mouseeventHandler(event) {
-    /*다음은 호환성을 위한 것이다. */
-    /* IE는 기본적으로 이벤트 객체를 전달하지 않는다. */
-    if (!event) event = window.event;
-
-    /* 미리 이벤트 타입과 타켓 얻기 */
-    var eType = event.type;
-    var eTarget = event.target || event.srcElement;
-    alert(eType +' event on element with id: '+ eTarget.id);
-  }
-
- function onloadHandler() {
-   /*  페이지의 body 엘리먼트를 참조하여 얻기 */
-   var body = document.body;
-   /* 클릭되기 위한 span 엘리먼트 생성하기 */
-   var span = document.createElement('span');
-   span.id = 'ExampleSpan';
-   span.appendChild(document.createTextNode ('Click Here!'));
-
-   /* 특정 마우스 이벤트를 받기 위해 spna 객체 등록하기 - 이벤트들의 소문자에 유의하라 그러나 당신이 그것을 치환하기 위한 이름의 선택은 자유다.
-   */
-   span.onmousedown = mouseeventHandler;
-   span.onmouseup = mouseeventHandler;
-   span.onmouseover = mouseeventHandler;
-   span.onmouseout = mouseeventHandler;
-
-   /* 페이지에 span 보여주기 */
-   body.appendChild(span);
-}
-
-window.onload = onloadHandler; // 우리가 핸들러를 치환한 이후에는 우리는 함수 이름 뒤에 ()을 붙여서는 안된다.
-</script>
-

예제: 키보드 이벤트 잡기

-

위의 예제인 "마우스 이벤트 잡기"와 유사하게 키보드 이벤트 잡기는 자바스크립트 이벤트 시스템 탐험에 의존한다. 키보드 이벤트들은 어떤 키든 키보드에서 사용될 때마다 발생한다.

-

키보드 동작에 반응하여 방출 가능한 키보드 이벤트 목록들은 마으스로 사용 가능한 것보다 상당히 작다. 

-
    -
  • KeyPress - 키보드를 누르거나 해제할때 발생
  • -
  • KeyDown - 키보드를  눌렀지만 아직 해제 않지 않았을때 발생
  • -
  • KeyUp - 키보드가 해제 되었을때 발생
  • -
  • TextInput (글을 썼던 시점에는 웹킷 브라우저에서만 가능) - 텍스트에 붙여넣기나 말하기를 하거나 또는 키보드로 입력했을 때 발생. 이 이벤트는 이 문서에 포함하지 않을 것이다.
  • -
-

keypress 이벤트는 키를 눌렀을 때의 Unicode값이 keycode나 charCode 프로퍼티에 둘다 저장되어 있다. 만약 키가  문자로 생성되어 눌러졌을때 (예를 들어 'a') charCode는 문자의 경우를 반영하여 문자의 코드를 설정한다.(즉, charCode은 Shift 키를 누르고 있는지 여부를 고려한다)그렇지 않으면, 누른 키의 코드가 keyCode에 저장된다.

-

키보드 이벤트들을 캡쳐하기 위한 가장 간단한 방법은 당신의 엘리먼트를 애트리뷰트들로써 개별적인 이벤트들을 지정한 HTML안에 이벤트 핸들러들을 다시 저장하는 것이다.

-

예:

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

마우스 이벤트들과 마찬가지로 당신이 실행하기 원하는 자바스크립트 코드는 그때마다 처리할 수 있다. 또는 당신은 HTML 페이지안에 <script> 블록에 정의되어진 함수를 호출 할 수 있다 :

-
<script>
-  function keypressHandler() {
-    alert ("Hello, World!");
-  }
-</script>
-
-<input onkeypress="keypressHandler();" />
-
-

타겟을 참조하거나 이벤트를 캡쳐 하는 것은 (즉, 눌러진 실제 키) 마우스 이벤트를 비슷한 방법으로 이룰 수 있다.

-

 <script type="text/javascript">

-
  function keypressHandler(evt) {
-      var eType = evt.type; // 이벤트 타입으로써 "keypress"를 반환할 것이다.
-
-   /*  여기에 우리는 which 나 다른 keyCode로 반환되는 모질라 기반으로 된 브라우저를 크로스 브라우저 방법으로 사용할 필요가 있다. 조건 연산자 또는 삼항식이 좋은 방법이다.
-      var keyCode = evt.which?evt.which:evt.keyCode;
-      var eCode = 'keyCode is ' + keyCode;
-      var eChar = 'charCode is ' + .fromCharCode(keyCode); // 또는 evt.charCode
-      alert ("Captured Event (type=" + eType + ", key Unicode value=" + eCode + ", ASCII value=" + eChar + ")");
-   }
-</script>
-<input onkeypress="keypressHandler(event);" />
-

페이지로 부터 어떤 키 이벤트를  캡처하기 위해서는 문서 레벨에서 이벤트를 등록하거나 함수안에서 처리하여 마칠 수 있다. 

-
<script>
-  document.onkeypress = keypressHandler;
-  document.onkeydown = keypressHandler;
-  document.onkeyup = keypressHandler;
-</script>
-

여기에 키 이벤트 처리하기 보여주는 완벽한 예제가 있다.

-
<!DOCTYPE html>
-<html>
-<head>
-  <script>
-    var metaChar = false;
-    var exampleKey = 16;
-    function keyEvent(event) {
-      var key = event.keyCode || event.which; // alternative to ternary - if there is no keyCode, use 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)">
-    Try pressing any key!
-</body>
-</html>
-

브라우저 버그들과 이상한 점

-

키 이벤트를 통해서 사용 가능하게 만들어진 두개의 프로퍼티들은 keycode와 charCode이다. 단순한 용어로 keyCode는 사용자에 의해 눌러진 실제 키보드 키를 의미하는데 반하여 charCode는 키의 ASCII 값을 반환한다. 이 두 값들은 반드시 동일하지 않을 수 있다. 예를 들어 소문자 'a'와 대문자 'A'는 같은 keyCode를 가지고 있다. 왜냐하면 사용자는 같은 키를 누르기 때문이다. 하지만 다른 charCode를 가지는 것은 왜냐하면 결과 문자가 다르기 때문이다.

-

charCode가 해석되는 브라우저의 방법은 일관되게 적용되는 방법이 아니다. 예를 들어  Internet Explorer 와 Opera는 charCode를 지원하지 않는다. 그런데 그들은 keyCode안에 문자 정보를 준다. onkeypress만 아니라 onkeydown 와 onkeyup의 keyCode가  키 정보를 가지고 있다. Firefox 는 "which",  문자를 구별하기 위해 다른 단어를 사용한다. 

-

더 나아가 키 이벤트들을 다루는 것에 관해서는  Keyboard Events에 대한 Mozilla 문서를 참조하시오.

-

{{ draft() }}

-

예제: 이미지 주변에 드래그하기

-

다음 예제는 페이지 근처의 firefox의 이미지를 이동할 수 있다.

-
<!DOCTYPE html>
-<html>
-<head>
-<style>
-img { position: absolute; }
-</style>
-
-<script>
-window.onload = function() {
-
-  movMeId = document.getElementById("ImgMov");
-  movMeId.style.top = "80px";
-  movMeId.style.left = "80px";
-
-  document.onmousedown = coordinates;
-  document.onmouseup = mouseup;
-
-  function coordinates(e) {
-    if (e == null) { e = window.event;}
-
-    // e.srcElement은 IE에서 타겟 엘리먼트로 가지고 있고 반면 e.target은 firefox에서 타겟 엘리먼트로 가지고 있다.
-// 두 프로퍼티들은 이벤트가 일어난 HTML 엘리먼트를 반환한다.
-    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;
-    }
-    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://placehold.it/100x100&text=JS" width="64" height="64">
-  <p>Drag and drop around the image in this page.</p>
-</body>
-
-</html>
-

예제: 크기 조정하기

-
-

이미지 크기 조정하는 예제(실제 이미지가 크기가 조정되는 것이 아니고,  이미지의 랜더링만 되는 것이다.)

-
  <!DOCTYPE html>
-  <html>
-    <head>
-      <style>
-        #resizeImage {
-          margin-left: 100px;
-        }
-      </style>
-      <script>
-      window.onload = function() {
-
-        var resizeId = document.getElementById("resizeImage");
-        var resizeStartCoordsX,
-            resizeStartCoordsY,
-            resizeEndCoordsX,
-            resizeEndCoordsY;
-
-        var resizeEndCoords;
-        var resizing = false;
-
-        document.onmousedown = coordinatesMousedown;
-        document.onmouseup = coordinatesMouseup;
-
-        function coordinatesMousedown(e) {
-          if (e == null) {
-            e = window.event;
-          }
-
-          var element = (typeof( window.event ) != 'undefined' ) ? e.srcElement : e.target;
-
-          if (element.id == "resizeImage") {
-            resizing = true;
-            resizeStartCoordsX = e.clientX;
-            resizeStartCoordsY = e.clientY;
-          }
-          return false;
-        }
-
-        function coordinatesMouseup(e) {
-          if (e == null) {
-            e = window.event;
-          }
-
-          if (resizing === true) {
-            var currentImageWidth = parseInt(resizeId.width);
-            var currentImageHeight = parseInt(resizeId.height);
-
-            resizeEndCoordsX = e.clientX;
-            resizeEndCoordsY = e.clientY;
-
-            resizeId.style.height = currentImageHeight - (resizeStartCoordsY - resizeEndCoordsY) + 'px';
-            resizeId.style.width = currentImageWidth - (resizeStartCoordsX - resizeEndCoordsX) + 'px';
-
-            resizing = false;
-          }
-          return false;
-        }
-      }
-      </script>
-    </head>
-
-    <body>
-      <img id="resizeImage" src="http://upload.wikimedia.org/wikipedia/commons/e/e7/Mozilla_Firefox_3.5_logo_256.png"
-width="64" height="64">
-      <p>Click on the image and drag for resizing.</p>
-    </body>
-
-  </html>
-
-

예제: 라인 그리기

-
<!DOCTYPE html>
-<html>
-<head>
-<script>
-function linedraw(ax,ay,bx,by)
-{
-    if(ay>by)
-    {
-        bx=ax+bx;
-        ax=bx-ax;
-        bx=bx-ax;
-        by=ay+by;
-        ay=by-ay;
-        by=by-ay;
-    }
-    var calc=Math.atan((ay-by)/(bx-ax));
-    calc=calc*180/Math.PI;
-    var length=Math.sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
-    document.body.innerHTML += "<div id='line' style='height:" + length + "px;width:1px;background-color:black;position:absolute;top:" + (ay) + "px;left:" + (ax) + "px;transform:rotate(" + calc + "deg);-ms-transform:rotate(" + calc + "deg);transform-origin:0% 0%;-moz-transform:rotate(" + calc + "deg);-moz-transform-origin:0% 0%;-webkit-transform:rotate(" + calc  + "deg);-webkit-transform-origin:0% 0%;-o-transform:rotate(" + calc + "deg);-o-transform-origin:0% 0%;'></div>"
-}
-</script>
-</head>
-<body onload="linedraw(200,400,500,900);"> <!--당신의 좌표 교체하기 -->
-</body>
-</html>
-

 

diff --git "a/files/ko/web/javascript/\354\226\270\354\226\264_\353\246\254\354\206\214\354\212\244/index.html" "b/files/ko/web/javascript/\354\226\270\354\226\264_\353\246\254\354\206\214\354\212\244/index.html" deleted file mode 100644 index 5743a54e24..0000000000 --- "a/files/ko/web/javascript/\354\226\270\354\226\264_\353\246\254\354\206\214\354\212\244/index.html" +++ /dev/null @@ -1,155 +0,0 @@ ---- -title: 자바스크립트 언어 자료 -slug: Web/JavaScript/언어_리소스 -tags: - - Advanced - - 자바스크립트 -translation_of: Web/JavaScript/Language_Resources ---- -
{{JsSidebar}}
- -

ECMAScript자바스크립트의 토대를 구성하는 스크립트 언어입니다. ECMAScript는 ECMA International 표준화 기구에 의해서 ECMA-262 및 ECMA-402 스펙에서 표준화되었습니다. 다음은 현재까지 승인됐거나 작업 중인 ECMAScript 표준입니다:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
이름링크출시 날짜설명
현재판
ECMA-262 10th EditionWorking draft2019ECMAScript 2019 (제 10판), 명세 작업 중
ECMA-262 9th EditionPDFHTML
- Working draftrepository
2018ECMAScript 2018 (제 9판)
ECMA-402 5th EditionWorking draft, repository2018ECMAScript 2018 국제화 API 표준
폐기(Obsolete)/역사판
ECMA-262 (ES 1)PDFJune 1997ECMAScript 표준 원본.
ECMA-262 (ES 2)PDFAugust 1998ECMAScript 표준 제2판; 또한 ISO 표준 16262.
ECMA-262 (ES 3)PDFDecember 1999ECMAScript 표준 제3판; JavaScript 1.5에 해당.
- errata 참조
ECMA-262 (ES 5)PDFDecember 2009ECMAScript 제5판
- ES5 errata 및 ECMAScript 5 support in Mozilla 참조
ECMA-357PDFJune 2004ECMAScript for XML (E4X).
- E4X errata 참조.
ECMA-357 Edition 2PDFDecember 2005ECMAScript for XML (E4X).
ECMA-262 (ES 5.1)PDF, HTMLJune 2011이 판은 국제화 표준 ISO/IEC 16262:2011 제3판과 완전히 정렬됨.
- ES5 errata 수정 포함, 새로운 기능은 없음.
ECMA-402 1.0PDF, HTMLDecember 2012ECMAScript 국제화 API 1.0.
ECMA-262 2015 (ES 6)PDF, HTMLJune 2015ECMAScript 2015 (제6판).
ECMA-402 2.0PDFJune 2015ECMAScript 국제화 API 2.0.
ECMA-262 2016 (ES 7)HTMLJune 2016ECMAScript 2016 (제7판).
ECMA-402 3.0HTMLJune 2016ECMAScript 국제화 API 3.0. 나중(올해 6월)에 승인될.
ECMA-262 2017 (ES 8)HTMLJune 2017ECMAScript 2017 (제8판).
ECMA-402 4th EditionHTMLJune 2017ECMAScript 국제화 API 4.0.
- -

ECMAScript의 역사에 대한 자세한 정보는 Wikipedia ECMAScript entry를 살펴보세요.

- -

여러분은 코드네임 "Harmony"로 불리우는 ECMAScript의 다음 개정에 참여하거나 그냥 진행상황을 확인할 수도 있습니다.  또한 ECMAScript 국제화 API 스펙도 공개 위키와 ecmascript.org 에 연결된 es-discuss mailing list에서도 확인할 수 있습니다.

- -

구현

- -
    -
  • SpiderMonkey - 파이어폭스 포함 여러 Mozilla 제품에 사용되는 자바스크립트 엔진;
  • -
  • Rhino - 자바로 작성된 자바스크립트 엔진;
  • -
  • Tamarin - (어도비® 플래쉬® 재생기에서 사용되는) 액션스크립트 가상머신;
  • -
  • Other implementations (위키피디아).
  • -
- -

관련 항목

- - diff --git a/files/ko/web/media/formats/codecs_parameter/index.html b/files/ko/web/media/formats/codecs_parameter/index.html new file mode 100644 index 0000000000..43cce1aa1f --- /dev/null +++ b/files/ko/web/media/formats/codecs_parameter/index.html @@ -0,0 +1,971 @@ +--- +title: 일반 미디어 타입에서 "codecs" 파라미터 사용하기 +slug: Web/Media/Formats/코덱파라미터 +translation_of: Web/Media/Formats/codecs_parameter +--- +
{{QuickLinksWithSubpages("/en-US/docs/Web/Media")}}
+ +

기본적으로, video/mp4audio/mpeg 처럼 {{Glossary("MIME")}} 타입을 통해 미디어 파일 포맷을 명시할 수 있습니다. 하지만 많은 미디어 타입들이-특히 비디오 트랙을 지원하는 경우-가지고 있는 데이터 포맷에 대해 더 상세하고 정확하게 명시할 수 있습니다. 예를들어 MPEG-4 비디오라고 해서 MIME 타입을 video/mp4만 명시한다면 정확히 어떤 미디어를 가지고 있는 지 아무 정보도 알 수 없습니다.

+ +

때문에 MIME 타입에 추가로 미디어 콘텐츠를 기술하기 위해 codecs 파라미터가 추가되었습니다. 이를 통해 컨테이너 특화된 정보를 제공할 수 있게 되었습니다 이 정보에는 비디오 코덱의 프로파일, 오디오 트랙 타입 등을 추가할 수 있습니다.

+ +

이 가이드 문서는 단순히 컨테이너 타입 명시를 넘어 codecs 파라미터의 문법과 MIME 타입에 비디오/오디오 콘텐츠에 대한 상세 정보를 기술하는 방법에 대해 설명합니다.

+ +

일반 문법

+ +

기본적인 MIME 미디어 타입 표현은 미디어 타입(audio, video, 등)으로 시작하며, 슬래쉬 문자 (/) 후 미디어를 포함하고 있는 컨테이너 포맷이름으로 이어집니다:

+ +
+
audio/mpeg
+
MP3 같은 MPEG 파일 타입의 오디오 파일입니다.
+
video/ogg
+
Ogg 파일 타입의 비디오 파일입니다.
+
video/mp4
+
MPEG-4 파일 타입을 사용하는 비디오입니다.
+
video/quicktime
+
애플 QuickTime 포맷을 사용하는 비디오입니다. 다른 곳에서 서술되어 있듯이, 한때는 웹에서 널리 쓰여지던 형식이었지만 현재는 플러그인이 필요하여 더 이상 사용하지 않는 타입입니다.
+
+ +

위 MIME 타입은 아직 모호한 표현입니다. 각 파일 타입들은 많은 수의 코덱을 지원하며 코덱은 각기 프로파일, 레벨과 같은 설정 인자들을 가지고 있습니다. 그래서 codecs 파라미터를 추가하여 명시할 수 있습니다.

+ +

세미콜론 (;)을 붙이고 codecs= 으로 시작하는 문자열을 덧붙여 콘텐츠의 포맷을 서술할 수 있습니다. 일부 미디어 타입은 사용하는 코덱 이름만 명시 가능할 수 있고 다른 미디어 타입은 코덱에 관한 다양한 인자를 기술할 수 있는 경우도 있습니다. 콤마로 구분하여 여러 코덱을 기술할 수도 있습니다.

+ +
+
audio/ogg; codecs=vorbis
+
Vorbis 오디오 트랙을 포함하는 Ogg 컨테이너 파일입니다.
+
video/webm; codecs="vp8, vorbis"
+
VP8 비디오와 Vorbis 오디오를 포함하는 WebM 컨테이너 파일입니다.
+
video/mp4; codecs="avc1.4d002a"
+
AVC (H.264) 코덱에 Main Profile, Level 4.2을 가지는 MPEG-4 컨테이너 파일입니다.
+
+ +

코덱의 속성 중 하나라도 퍼센트-인코딩이 필요한 특수문자{{RFC(2231, "MIME Parameter Value and Encoded Word Extensions", 4)}}를 사용하는 경우 MIME 타입을 기술하는 문자열의 codecs 파라미터를 codecs* (애스터리크(*) 추가됨에 유의)로 변경해야 합니다. JavaScript {{jsxref("Global_Objects/encodeURI", "encodeURI()")}} function으로 파라미터 목록을 인코딩할 수 있습니다; 반대로 {{jsxref("Global_Objects/decodeURI", "decodeURI()")}}를 통해 기인코딩된 파라미터 리스트를 디코딩할 수 있습니다.

+ +
+

codecs 파라미터를 사용한다면, 파일 콘텐츠가 사용한 모든 코덱을 목록에 명시해야합니다. 목록에 파일이 사용하고 있지 않은 코덱을 명시하는 것도 가능합니다.

+
+ +

컨테이너별 코덱 옵션

+ +

아래 컨테이너들은 codecs 파라미터에 확장 옵션을 지원합니다:

+ +
+
    +
  • {{anch("ISO-BMFF", "3GP")}}
  • +
  • {{anch("AV1")}}
  • +
  • {{anch("ISO-BMFF", "ISO BMFF")}}
  • +
  • {{anch("ISO-BMFF", "MPEG-4")}}
  • +
  • {{anch("ISO-BMFF", "QuickTime")}}
  • +
  • {{anch("WebM")}}
  • +
+
+ +

링크를 클릭하면 동일한 섹션으로 이동할텐데요; 위 미디어 타입들은 모두 ISO Base Media File Format (ISO BMFF)를 기반하고 있어, 동일한 문법을 공유하기 때문입니다.

+ +

AV1

+ +

AV1의 codecs 문법은AV1 Codec ISO Media File Format Binding 스펙 문서의, 섹션 5: Codecs Parameter String에 정의되어 있습니다.

+ +
av01.P.LLT.DD[.M[.CCC[.cp[.tc[.mc[.F]]]]]]
+ +

아래 표에서 코덱 파라미터 문자열 구성요소에 대해 자세히 설명하고 있습니다. 각 요소들은 고정된 개수의 문자로 되어 있으며;고정 길이보다 짧은 경우 앞에 0을 붙여서 맞춰야 합니다..

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
AV1 코덱 파라미터 문자열 요소
요소내용
P +

한자리 숫자 프로파일 번호:

+ + + + + + + + + + + + + + + + + + + + + + + +
AV1 프로파일 번호
프로파일 번호설명
0"Main" 프로파일; YUV 4:2:0/모노크롬 크로마 서브샘플링 및 8/10 비트 색 깊이 지원.
1"High" 프로파일 4:4:4 크로마 서브샘플링 추가 지원.
2"Professional" 프로파일, 4:2:2 크로마 서브샘플링 및 12 비트 색 깊이 추가 지원
+
LL두자리 숫자 레벨 번호,  X.Y 형태의 레벨 포맷으로 변환 됨, X = 2 + (LL >> 2)Y = LL & 3. 자세한 내용은 AV1 스펙 문서의 Appendix A, section 3 참조.
T한자리 문자 티어 표시. Main 티어라면 (seq_tier equals 0), 문자는 M. High 티어는 (seq_tier is 1) H. High 티어는 4.0 이상 레벨에서만 가능합니다.
DD두자리 숫자 색 깊이. 8, 10, 12 중 하나여야 하며; 프로파일과 다른 속성에서 지원 가능한 값이여야 합니다.
M한자리 숫자 모노크롬 플래그; 0인 경우 비디오는 U, V, Y 성분을 모두 가지고 있습니다. 아닌 경우 전체 비디오 데이터는 Y(휘도) 성분 뿐으로 모노크롬 이미지를 가집니다. 자세한 내용은 {{SectionOnPage("/en-US/docs/Web/Media/Formats/Video_concepts", "YUV")}}를 참조하여 YUV 컬러 시스템이 어떻게 동작하는지 알아보세요. 기본 값은 0 (모노크롬 아님)입니다.
CCC +

CCC 는 세자리 숫자로 크로마 서브샘플링을 표기합니다. 첫번째 숫자는 subsampling_x, 두 번째 숫자는 subsampling_y. 둘다 1인경우, 세번째 값은 chroma_sample_position; 아닌 경우 세번째 값은 항상 0입니다. M 값과 더불어 크로마 서브샘플링 포맷을 구성하는 요소입니다:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
크로마 서브샘플링 결정 방식
subsampling_xsubsampling_yMonochrome flagChroma subsampling format
000YUV 4:4:4
100YUV 4:2:2
110YUV 4:2:0
111YUV 4:0:0 (Monochrome)
+ +

CCC의 세번째 값은 크로마 샘플 위치(chroma sample position)로, 0은 위치를 알 수 없으며 디코딩 시 개별적으로 제공해야 함을 의미합니다; 1은 샘플이 (0, 0) 휘도 샘플과 동일한 수평선상에 있음을 의미합니다; 2는 샘플이 (0, 0) 휘도 샘플과 동일한 위치에 있음을 의미합니다.

+ +

기본 값은 110 (4:2:0 크로마 서브샘플링)입니다.

+
cp두자리 숫자 color_primaries 값은 미디어의 색 공간을 표시합니다. 예를 들어 HDR 비디오에서 사용하는 BT.2020/BT.2100 색 공간은 09입니다. 자세한 정보-그 외의 색 공간 값을 포함하여-는 AV1 스펙 문서의 Color config semantics section 를 참조하세요. 기본값은 01 (ITU-R BT.709)입니다.
tc두자리 숫자 transfer_characteristics 값. 이 값은 소스에서 디스플레이로 감마를 매핑하는 함수(기술적인 용어로 "opto-electrical transfer function"라 표현)를 정의합니다. 예를 들어 10-bit BT.2020는 14입니다. 기본 값은 01 (ITU-R BT.709)입니다.
mc두자리 숫자 matrix_coefficients 상수는 RGB 컬러 채널을 휘도/색차 신호로 변환 시 사용할 계수 행렬을 선택합니다. 예를 들어 BT.709의 표준 계수 값은 01로 표현합니다. 기본 값은 01 (ITU-R BT.709)입니다.
F한자리 숫자로 색상이 가능한 모든 범위를 표현해야 할지(1), 지정한 색 설정에 의해 적합하다고 여겨지는 범위로 제한하여 표현(studio swing representation이라 표현)해야 할지를 나타내는 값입니다. 기본 값은 0 (studio swing representation 적용)입니다.
+ +

M (모노크롬 플래그)이후의 요소는 모두 비필수입니다; 어느 곳에서부터나 생략할 수 있습니다 (하지만 임의의 중간 요소를 생략할 수는 없습니다). 기본 값은 위 표에 서술하였습니다. AV1 코덱 문자열 예시는 아래와 같습니다:

+ +
+
av01.2.15M.10.0.100.09.16.09.0
+
AV1 Professional 프로파일, 레벨 5.3, Main 티어, 10 비트 색 깊이, 4:2:2 크로마 서브샘플링 ITU-R BT.2100 색 공간, 색 전환 YCbCr 색상 행렬. Studio swing representation 적용.
+
av01.0.15M.10
+
AV1 Main 프로파일, 레벨 5.3, Main 티어, 10 비트 색 깊이. 나머지 요소는 기본 값 사용: 4:2:0 크로마 서브 샘플링, BT.709 색 공간, 색 전환, 계수 행렬 사용. Studio swing representation.
+
+ +

ISO Base Media File Format: MP4, QuickTime, and 3GP

+ +

모든 미디어 타입은 {{interwiki("wikipedia", "ISO Base Media File Format")}} (ISO BMFF)를 기반으로 하며 codecs 문법을 공유합니다. 이들 미디어 타입은 MPEG-4 (또 사실상 MPEG-4를 기반으로 하고 있으므로 QuickTime도 포함)과 3GP를 포함합니다. MIME 타입의 codecs 파라미터를 통해 아래와 같이 비디오/오디오 트랙 둘 다 기술할 수 있습니다.:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ISO BMFF codecs 파라미터를 지원하는 기본 MIME 타입
MIME 타입설명
audio/3gpp3GP 오디오 ({{RFC(3839, "MIME Type Registrations for 3rd generation Partnership Project (3GP) Multimedia files")}})
video/3gpp3GP 비디오 ({{RFC(3839, "MIME Type Registrations for 3rd generation Partnership Project (3GP) Multimedia files")}})
audio/3gp23GP2 오디오 ({{RFC(4393, "MIME Type Registrations for 3GPP2 Multimedia files")}})
video/3gp23GP2 비디오 ({{RFC(4393, "MIME Type Registrations for 3GPP2 Multimedia files")}})
audio/mp4MP4 오디오 ({{RFC(4337, "MIME Type Registration for MPEG-4")}})
video/mp4MP4 비디오 ({{RFC(4337, "MIME Type Registration for MPEG-4")}})
application/mp4오디오/비디오가 아닌 MPEG-4 컨테이너 미디어
+ +

codecs 파라미티에는 간단하게 컨테이너 명(3gp, mp4, quicktime, etc.)만 기술할 수도 있으며 컨테이너 명에 코덱 이름 및 설정 값을 함께 기술할 수도 있습니다. 각 코덱 등은 온점(.)으로 구분된 요소를 다수 가질 수 있습니다.

+ +

codecs 값의 문법은 코덱마다 다릅니다; 하지만 항상 4 글자 코덱 구분자와 온점(.)으로 시작하며 데이터 포맷을 기술하기 위핸 Object Type Indication (OTI) 형식의 문자열이 뒤따릅니다. 대부분의 코덱에서 OTI는 두자리 16진수로 되어 있지만 AVC (H.264)는 6자리 16진수로 구성되어 있습니다.

+ +

따라서 지원하는 코덱 문법은 아래와 유사합니다:

+ +
+
cccc[.pp]* (Generic ISO BMFF)
+
cccc 는 4 글자 코덱 ID이며  pp는 0~2자리 인코딩 된 문자입니다.
+
mp4a.oo[.A] (MPEG-4 audio)
+
oo 는 미디어 콘텐츠를 더 정확하게 기술하는 Object Type Indication 값이며 A 는 한자리 숫자오디오 OTI입니다. OTI로 가능한 값은 MP4 Registration Authority 웹사이트의 Object Types page 페이지에서 확인할 수 있습니다. 예를들어 MP4 파일의 Opus 오디오는 mp4a.ad로 기술합니다. 자세한 내용은 {{anch("MPEG-4 audio")}}를 참조하세요.
+
mp4v.oo[.V] (MPEG-4 video)
+
마찬가지로 oo 는 미디어 콘텐츠를 명시하는 OTI 값이며, V 는 한자리 숫자 비디오 OTI 값입니다.
+
avc1.oo[.PPCCLL] (AVC video)
+
+

oo 는 콘텐츠를 명시하는 OTI 값이며, while PPCCLL 는 6자리 16진수로써 프로파일 넘버 (PP), 제약 플래그 (CC), 레벨 (LL)을 의미합니다. PP로 가능한 값은 {{anch("AVC profiles")}}를 참조하세요.

+ +

제약 플래그는 1 비트 불리언 값이며, MSB는 flag 0(또는 일부에선 constraint_set0_flag)로 취급합니다. 그리고 이어지는 비트는 하나씩 번호가 높게 매겨집니다. 현재로썬 0부터 2번째 비트까지만 사용하며;나머지 5개의 비트는 반드시 0이어야합니다. 각 플래그의 의미는 사용하는 프로파일에 따라 달라집니다.

+ +

레벨 값은 고정 소수점이므로 숫자 14 (10진법 20) 은 레벨 2.0을 의미하며 3D (10진법 61) 은 레벨 6.1을 의미합니다. 일반적으로 레벨 숫자가 높을 수록 스트림 대역폭이 높아 더 큰 크기의 비디오를 지원할 수 있습니다.

+
+
+ +

AVC 프로파일

+ +

아래의 AV 프로파일 넘버는 codecs 파라미터에서 사용하며 제약 요소 값은 CC로 사용할 수 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
codecs  파라미터에서 AVC 프로파일과 제약 요건을 명세하기 위한 값
프로파일넘버(Hex)제약 (byte)
Constrained Baseline Profile (CBP)
+ CBP는 리소스가 제약점이 있거나 재생이 원활하지 못해 발생하는 이상 요소들을 최소화 해야 하는 경우 주요한 해결책입니다.
4240
Baseline Profile (BP)
+ CBP와 유사하나 데이터 손실 방지와 복구 능력을 향상시킨 프로파일입니다.  CBP가 도입된 이후에는 이전만큼 널리 사용하고 있지는 않습니다. CBP 스트림은 모두 BP 스트림으로 간주할 수도 있습니다.
4200
Extended Profile (XP)
+ 고효율 압축과 네트워크 전송시의 데이터 안정성, 스트림 스위칭을 고려한 프로파일입니다.
5800
Main Profile (MP)
+ MPEG-4 포맷으로 전송하는 디지털 표준 TV 방송에서 사용하는 프로파일입니다. 고선명 TV(HDV)에서는 사용하지 않습니다. 2004년 —HDTV에서 사용하기 위해— High Profile이 추가된 이후 중요도가 감소하였습니다.
4D00
High Profile (HiP)
+ 현재로써는 전파방송과 매체기반 HD 비디오에서 사용하는 주요 프로파일입니다. HD TV 방송과 블루레이 미디어에서 사용하고 있습니다.
6400
Progressive High Profile (PHiP)
+ 필드 코딩 지원을 제거한 High Profile입니다.
6408
Constrained High Profile
+ 양방향 예측 슬라이스("B-slices") 지원을 제거한 PHiP입니다.
640C
High 10 Profile (Hi10P)
+ 10 비트 컬러 모드 지원을 제거한 High Profile입니다.
6E00
High 4:2:2 Profile (Hi422P)
+ Hi10P에 4:2:2 크로마 서브샘플링과 최대 10비트 컬러 모드 지원을 추가한 프로파일입니다.
7A00
High 4:4:4 Predictive Profile (Hi444PP)
+ Hi422P 및 Hi444PP에 4:4:4 크로마 서브샘플링(색차 샘플링 소거 없음)을 추가 지원한 프로파일입니다. 또한 최대 14비트 컬러 샘플과 효율적인 무손실 지역 코딩을 추가하였습니다. 각 프레임을 3개의 분리된 컬러 평면(각 평면은 모노크롬 프레임형태로 저장됩니다)으로 인코딩할 수 있는 옵션입니다.
F400
High 10 Intra Profile
+ all-intra-frame에 High 10 제약이 걸린 프로파일입니다. 전문가 용 앱에 주로 쓰입니다.
6E10
High 4:2:2 Intra Profile
+ all-intra-frame에 Hi422를 적용한 프로파일입니다.
7A10
High 4:4:4 Intra Profile
+ all-intra-frame에 High 4:4:4 제약을 건 프로파일입니다.
F410
CAVLC 4:4:4 Intra Profile
+ all-intra-frame에 High 4:4:4 제약, CAVLC 엔트로피 코딩만 사용하는 프로파일입니다.
4400
Scalable Baseline Profile
+ 화상 회의, 감시 카메라 및 모바일 장치에서 쓰이는 프로파일로, {{interwiki("wikipedia", "SVC")}} Baseline Profile은 AVC의 Constrained Baseline profile에 기반하고 있습니다. 스트림의 베이스 레이어는 고품질로 제공되면서, 제약이 걸린 환경에서 대안이 될 수 있는 서브스트림을 다수 제공하는 방식입니다. 서브스트림은 해상도 감소, 낮은 프레임레이트, 압축률 저하 등을 조합하여 구성합니다.
5300
Scalable Constrained Baseline Profile
+ 실시간 양방향 대화형 어플리케이션에서 주요 사용하는 프로파일입니다. WebRTC에서 아직 정식으로 지원하지는 않지만,  SVC를 활성화하여 WebRTC AP 개발 모드에서 사용해 볼 수 있습니다.
5304
Scalable High Profile
+ 방송 및 스트리밍 어플리케이션에서 주로 사용합니다. 베이스(또는 최고 품질) 레이어에는 AVC High Profile이 반드시 포함되어야 합니다.
5600
Scalable Constrained High Profile
+ 실시간 통신을 위한 Scalable High Profile의 서브셋 프로파일입니다.
5604
Scalable High Intra Profile
+ 비디오 제작 어플리케이션을 위한 all-intra-frame 프로파일입니다.
5620
Stereo High Profile
+ 양안 렌더링을 통한 스테레오스코픽(stereoscopic) 비디오를 지원하는 프로파일입니다. 양안 영상이 아닌 경우 High profile과 동일합니다.
8000
Multiview High Profile
+ 시간 및 MVC inter-view 예측을 통한 2개 이상의 뷰를 지원하는 프로파일입니다. 필드 픽쳐 또는 매크로블록-어댑티브한 frame-field 코딩을 지원하지 않습니다.
7600
Multiview Depth High Profile
+ High Profile에 기반하며 메인 서브스트림이 반드시 붙어야 합니다. 나머지 서브스트림들은 Stereo High Profile과 매칭되어야 합니다.
8A00
+ +

MPEG-4 audio

+ +

codecs 목록의 값 항목이 mp4a로 시작한다면, 문법은 아래와 같아야 합니다:

+ +
mp4a.oo[.A]
+ +

oo 는 두자리 16진수 Object Type Indication으로 미디어에 사용된 코덱 클래스를 표시합니다. OTI 값은 MP4 Registration Authority에서 규정하고 있으며 list of the possible OTI values에서 가용한 값을 확인할 수 있습니다. 특수한 값인 40; 이는 미디어가 MPEG-4 audio(ISO/IEC 14496 Part 3)임을 나타냅니다. 조금 더 자세히 말하자면, 세번째 컴포넌트—Audio Object Type—은 OTI 40 을 MPEG-4의 특정 하위 타입으로 범위를 좁히기 위해 추가하였습니다.

+ +

Audio Object Type는 두자리 10진수로 이루어져 있습니다(codecs 파라미터의 다른 값은 대부분 16진수). 예를들어 MPEG-4 AAC-LC의 오디오 오브젝트 타입은 숫자 2이므로 AAC-LC의 전체 codecs 표현 값은 mp4a.40.2 입니다.

+ +

그러므로 오디오 오브젝트 타입이 17인 ER AAC LC의 전체 codecs 값은 mp4a.40.17 입니다. 한자리 숫자는 한자리로 표현하거나(폭넓게 호환되므로 최선) 앞에 0을 붙여 두자리로 표현할 수 있습니다. mp4a.40.02 처럼요.

+ +
+

Note: 원래 Audio Object Type은 한자리 숫자로 규정되었었습니다. 시간이 지나면서 표준을 확장하였고 현재는 한자리 또는 두자리 숫자입니다. 10 미만의 값 앞에 0 을 붙이는건 필수가 아닙니다. 오래된 MPEG-4 코덱 구현체들은 두자리 숫자를 지원하지 못할 수도 있습니다. 따라서 호환성을 높이기 위해선 한자리로 표현해야 합니다.

+
+ +

Audio Object Types는 ISO/IEC 14496-3 subpart 1, section 1.5.1에서 정의하고 있습니다. 아래 표는 Audio Object Type 기본 목록과 지원하는 프로필입니다. MPEG-4 audio type의 내부에 대해서 더 알고 싶다면 레퍼런스를 참조하세요.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MPEG-4 audio object types
IDAudio Object TypeProfile support
0NULL
1AAC MainMain
2AAC LC (Low Complexity)Main, Scalable, HQ, LD v2, AAC, HE-AAC, HE-AAC v2
3AAC SSR (Scalable Sampling Rate)Main
4AAC LTP (Long Term Prediction)Main, Scalable, HQ
5SBR (Spectral Band Replication)HE-AAC, HE-AAC v2
6AAC ScalableMain, Scalable, HQ
7TwinVQ (Coding for ultra-low bit rates)Main, Scalable
8CELP (Code-Excited Linear Prediction)Main, Scalable, Speech, HQ, LD
9HVXC (Harmonic Vector Excitation Coding)Main, Scalable, Speech, LD
10 – 11Reserved
12TTSI (Text to Speech Interface)Main, Scalable, Speech, Synthetic, LD
13Main SyntheticMain, Synthetic
14Wavetable Synthesis
15General MIDI
16Algorithmic Synthesis and Audio Effects
17ER AAC LC (Error Resilient AAC Low-Complexity)HQ, Mobile Internetworking
18Reserved
19ER AAC LTP (Error Resilient AAC Long Term Prediction)HQ
20ER AAC Scalable (Error Resilient AAC Scalable)Mobile Internetworking
21ER TwinVQ (Error Resilient TwinVQ)Mobile Internetworking
22ER BSAC (Error Reslient Bit-Sliced Arithmetic Coding)Mobile Internetworking
23ER AAC LD (Error Resilient AAC Low-Delay; used for two-way communiation)LD, Mobile Internetworking
24ER CELP (Error Resilient Code-Excited Linear Prediction)HQ, LD
25ER HVXC (Error Resilient Harmonic Vector Excitation Coding)LD
26ER HILN (Error Resilient Harmonic and Individual Line plus Noise)
27ER Parametric (Error Resilient Parametric)
28SSC (Sinusoidal Coding)
29PS (Parametric Stereo)HE-AAC v2
30MPEG Surround
31Escape
32MPEG-1 Layer-1
33MPEG-1 Layer-2 (MP2)
34MPEG-1 Layer-3 (MP3)
35DST (Direct Stream Transfer)
36ALS (Audio Lossless)
37SLS (Scalable Lossless)
38SLS Non-core (Scalable Lossless Non-core)
39ER AAC ELD (Error Resilient AAC Enhanced Low Delay)
40SMR Simple (Symbolic Music Representation Simple)
41SMR Main (Symbolic Music Representation Main)
42Reserved
43SAOC (Spatial Audio Object Coding)[1]
44LD MPEG Surround (Low Delay MPEG Surround)[1]
45 and upReserved
+ +

[1] SAOC and LD MPEG Surround are defined in ISO/IEC 14496-3:2009/Amd.2:2010(E).

+ +

WebM

+ +

WebM codecs 파라미터의 기본 형은 4개의 WebM 코덱 중 하나 이상의 이름을 콤마로 구분합니다. 아래 표는 예시입니다.:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WebM MIME codecs 파라미터 예시
MIME 타입설명
video/webm;codecs="vp8"VP8 코덱 WebM 비디오; 오디오 미정의.
video/webm;codecs="vp9"VP9 코덱 WebM 비디오.
audio/webm;codecs="vorbis"Vorbis 오디오 WebM 파일.
audio/webm;codecs="opus"Opus 오디오 WebM 파일.
video/webm;codecs="vp8,vorbis"VP8 비디오 코덱, Vorbis 오디오 코덱 포함된 WebM 파일.
video/webm;codecs="vp9,opus"A WebM container with VP9 video and Opus audio.
+ +

vp8.0vp9.0 문자열도 가능하지만, 비추천합니다.

+ +

ISO Base Media File Format 문법

+ +

codecs 파라미터를 표준화하고 강력한 포맷으로 발전시키기 위해, WebM은 ISO Base Media File Format 에 정의된 문법에 따라 비디오 콘텐츠를 기술하기 시작했습니다. 본 문법은 VP Codec ISO Media File Format Binding의, Codecs Parameter String 섹션에 정의되어 있습니다. 오디오 코덱은 vorbis 또는 opus로 표시되어 있습니다.

+ +

codecs 파리미터는 사용한 코덱을 나타내는 4자리 문자로 시작하고 온점(.)으로 구분된 2자리 숫자가 반복됩니다.

+ +
cccc.PP.LL.DD.CC[.cp[.tc[.mc[.FF]]]]
+ +

처음부터 5개 요소는 필수이며; cp (color primaries) 부터는 옵션입니다.; 이후로는 어디서든 끊을 수 있습니다. 각 요소는 아래 표에 설명하고 있으며 예시가 첨부되어 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WebM codecs parameter components
ComponentDetails
cccc +

4자리 코드로 사용 가능한 코덱을 명시합니다. 가능한 값은 아래와 같습니다:

+ + + + + + + + + + + + + + + + + + + + + + + +
Web-M 지원 코덱 4자리 코드
Four-character codeCodec
vp08VP8
vp09VP9
vp10VP10
+
PP +

2자리 숫자 프로파일 코드. 필요하다면 두자리를 맞추기 위해 앞에 0을 추가합니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
WebM 프로파일 숫자
프로파일설명
00크로마 서브샘플링 4:2:0(수직/수평 서브샘플링)만 허용. 색상 컴포넌트 당 8비트만 허용.
01크로마 서브샘플링 전체 허용. 색상 컴포넌트 당 8비트만 허용.
02크로마 서브샘플링 4:2:0만 허용. 색상 컴포넌트 당 8, 10, 12비트 허용.
03크로마 서브샘플링 전체 허용. 색상 컴포넌트 당 8, 10, 12비트 허용
+
LL두 자리 숫자 레벨 코드. 레벨 넘버는 고정 소수점 표기로 첫번째 숫자가 1의 자리, 두번째 숫자가 소수점 미만 첫번째 자리를 의미합니다. 예를 들어 레벨 3은 30 레벨 6.1은 61.
DD휘도, 색상 컴포넌트의 비트 심도를 표기합니다. 가능한 값은 8, 10, 12입니다.
CC +

크로마 서브샘플링 포맷을 2자리 숫자로 표기합니다. 가능한 값은 아래 표에 있습니다; 자세한 내용은 {{SectionOnPage("en-US/docs/Web/Media/Formats/Video_concepts", "Chroma subsampling")}} 를 참조하세요.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WebM 크로마 서브샘플링 구분자
크로마 서브샘플링 포맷
004:2:0 with the chroma samples sited interstitially between the pixels
014:2:0 chroma subsampling with the samples colocated with luma (0, 0)
024:2:2 chroma subsampling (4 out of each 4 horizontal pixels' luminance are used)
034:4:4 chroma subsampling (every pixel's luminance and chrominance are both retained)
04Reserved
+
cp +

ISO/IEC 23001-8:2016 표준 Section 8.1에 명시되어있는 색 공간을 두자리 숫자로 표현합니다. 본 요소와 이후 요소는 전부 비필수값입니다.

+ +

Color primaries 요소에 가능한 값은 아래와 같습니다.:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ISO/IEC Color primary identifiers
ValueDetails
00ITU과 ISO/IEC에 의해 예약됨
01고선명 화질(HD) TV 표준인 BT.709, sRGB, sYCC. BT.709; sRGB는 컴퓨터 모니터에서 쓰이는 가장 일반적인 색 공간입니다. Broadcast BT.709는 8비트 색 심도를 사용하여 16(Black)부터 235(White)까지 리갈 레인지를 표현합니다.
02알 수 없거나 application에서 활용하기 위해 사용합니다.
03ITU과 ISO/IEC에 의해 예약됨
04BT.470 System M, NTSC (미국 내 표준 화질 TV 표준)
05BT.470 System B, G; BT.601; BT.1358 625; BT.1700 625 PAL and 625 SECAM
06BT.601 525; BT.1358 525 or 625; BT.1700 NTSC; SMPTE 170M. 7과 동일함.
70{{Glossary("SMPTE")}} 240M (historical). Functionally identical to 6과 동일함.
08일반 필름
09BT.2020; BT.2100. UHD (4K) High Dynamic Range (HDR) 영상에서 사용 매우 넓은 색 표현력과 10비트 12비트 색상 컴포넌트 지원.
10SMPTE ST 428 (D-Cinema Distribution Master: Image characteristics). DCDM을 위한 비압축 형식.
11SMPTE RP 431 (D-Cinema Quality: Reference projector and environment). 필름 표현의 지속적 경험을 위한 레퍼런스 프로젝터와 환경 조건에 대해 기술.
12SMPTE EG 432 (Digital Source Processing: Color Processing for D-Cinema). 디지털 영화를 위한 색신호 디코딩의 기술적 가이드라인.
13 – 21ITU과 ISO/IEC에 의해 예약됨
22EBU Tech 3213-E
23 – 255ITU과 ISO/IEC에 의해 예약됨
+
tc비디오의 transferCharacteristics 값을 2자리 숫자로 표현. This value is from Section 8.2 of ISO/IEC 23001-8:2016 Section 8.2에 기술되어 있으며 디코딩된 색상을 렌더링 타겟에 맞출 때 transfer characteristics 을 정의합니다.
mcmatrixCoefficients 속성 값을 2자리 숫자로 표현 ISO/IEC 23001-8:2016 스펙 Section 8.3 표에서 기술. 이 값은 native red, blue, green 색상을 휘도, 색차 신호에 매핑하는데 사용합니다. 이 계수들이 방정식에서 어떻게 사용되는지 같은 섹션에서 확인할 수 있습니다.
FF색상 컴포넌트의 검정 수준과 색상 범위를 리갈 레인지로 제한할지 여부를 표시합니다. 예를들어 8비트 색상의 경우 리갈 레인지는 16~235입니다. 값이 00 인 경우 강제로 제한하며,  01 인 경우 결과물의 색상이 컬러 시스템의 범위를 벗어나더라도 각 컴포넌트 별로 가능한 풀 레인지 값을 허용합니다.
+ +

WebM media type 예시

+ +
+
video/webm;codecs="vp08.00.41.08,vorbis"
+
VP8 비디오, 프로파일 0 레벨 4.1, 8-bit YUV 4:2:0 크로마 서브샘플링, BT.709 색 공간, 변환 함수, 행렬 계수, 휘도 색차 값은 ("studio") 리갈 레인지로 인코딩 됨. 오디오는 Vorbis.
+
video/webm;codecs="vp09.02.10.10.01.09.16.09.01,opus"
+
VP9 비디오, 프로파일 2 레벨?1.0, 10-bit YUV 4:2:0 크로마 서브샘플링, BT.2020 색 공간, ST 2084 EOTF (HDR SMPTE), BT.2020 비상수 휘도 색상 행렬, 풀 레인지 휘도 색차 인코딩non-constant luminance color matrix, and full-range chroma and luma encoding. 오디오는 Opus 포맷.
+
+ +

codecs 파라미터 사용하기

+ +

codecs 파라미터를 여러 상황에서 사용할 수 있습니다. 먼저 {{HTMLElement("audio")}} , {{HTMLElement("video")}} 엘레먼트 생성 시 {{HTMLElement("source")}} 엘레먼트에 사용하여 브라우저로 하여금 사용할 미디어 포맷에 대한 옵션을 제공하는거죠..

+ +

{{domxref("MediaSource.isTypeSupported()")}} 메소드에 MIME 타입을 명시적으로 전달하는데 사용할 수도 있습니다.; 이 메소드는 현재 장치에서 주어진 미디어 포맷을 재생할 수 있는지 여부를 불리언 값으로 반환합니다.

+ +

더 보기

+ + diff --git a/files/ko/web/media/formats/containers/index.html b/files/ko/web/media/formats/containers/index.html new file mode 100644 index 0000000000..d4e45c294a --- /dev/null +++ b/files/ko/web/media/formats/containers/index.html @@ -0,0 +1,1279 @@ +--- +title: 미디어 컨테이너 포맷 (파일 타입) +slug: Web/Media/Formats/컨테이너 +translation_of: Web/Media/Formats/Containers +--- +

오디오와 비디오 파일 포맷은 두 파트에서 정의할 수 있습니다.(오디오 비디오가 한 파일에 있으면 물론 3 파트지요): 오디오/비디오 코덱와 미디어 컨테이너 포맷(도는 파일 타입)입니다. 이 가이드 문서는 웹에서 널리 쓰이는 컨테이너 포맷에 대해 알아보고 기본적인 스펙와 장단점 그리고 적절한 사용법을 설명하고 있습니다.

+ +

WebRTC 는 컨테이너를 사용하지 않습니다. 대신에 각 트랙을 나타내는{{domxref("MediaStreamTrack")}} 객체를 통해 인코딩 된 오디오/비디오 트랙을 한 곳에서 다른 곳으로 직접 스트리밍합니다. WebRTC에서 일반적으로 사용하는 코덱이나 브라우저 호환성을 알아보려면 Codecs used by WebRTC 문서를 참고하세요.

+ +

일반적인 컨테이너 포맷

+ +

미디어 컨테이너 포맷에는 여러 종류가 있지만 여러분들은 보통 아래 나열된 목록의 포맷을 주로 만나게 될 겁니다. 일부는 오디오만 지원하는 것도 있고 오디오와 비디오 모두를 지원하는 포맷도 있죠. MIME 타입과 확장자도 나열되어 있습니다. 웹상에서 가장 많이 쓰이는 컨테이너 포맷은 아마도 MPEG-4 (MP4), Quicktime Movie (MOV), Wavefile Audio File Format (WAV)일겁니다. 또한 MP3, Ogg, WebM, AVI 등의 포맷도 볼 수 있지요. 하지만 모든 브라우저가 이 다양한 포맷들을 지원하는 것은 아닙니다. 사용하기 편하고 다른 조합과의 구분을 위해 특정한 컨테이너와 코덱의 조합은 독자적인 MIME type과 확장자를 가지기도 합니다. 예를들어 Opus 오디오 트랙만을 가진 Ogg파일은 가끔 Opus 파일이라 불리며 .opus 확장자를 가지는 경우도 있습니다. 하지만 실제로는 단순한 Ogg 파일일 뿐이죠.

+ +

반대 케이스로 특정 코덱이 특정 컨테이너에 담긴 형태가 매우 보편적일 경우 독자적인 형식으로 취급하는 경우도 있습니다. MP3 오디오 파일이 대표적인 경우로, MPEG-1 컨테이너에 MPEG-1 Audio Layer III 코덱으로 인코딩 된 오디오 트랙 하나만이 담긴 케이스입니다. 컨테이너는 일반적인 MPEG지만 이 형식은 audio/mp3 MIME 타입과 .mp3 확장자를 사용합니다.

+ +

컨테이너 포맷(파일 타입) 인덱스

+ +

특정 컨테이너 포맷에 대해 더 알아보려면 아래 목록에서 찾아 클릭하세요. 컨테이너 사용법과 지원하는 코덱, 지원하는 브라우저 등을 알 수 있습니다.

+ +
+
    +
  • {{anch("3GP")}}
  • +
  • {{anch("ADTS")}}
  • +
  • {{anch("FLAC")}}
  • +
  • {{anch("MPEG", "MPEG / MPEG-2")}}
  • +
  • {{anch("MP4", "MPEG-4 (MP4)")}}
  • +
  • {{anch("Ogg")}}
  • +
  • {{anch("QuickTime")}}
  • +
  • {{anch("WAVE")}}
  • +
  • {{anch("WebM")}}
  • +
+
+ +

3GP

+ +

3GP 또는 3GPP 컨테이너는 셀룰러 네트워크를 통해 전송하고 모바일 장치에서 사용하기 위해 고안되었습니다. 원래 3G 모바일 폰을 위해 디자인하였지만 현대의 모바일 폰과 네트워크에서도 사용하고 있습니다. 하지만 네트워크 처리량이 늘어나면서 3GP 포맷의 필요성은 점차 줄어들고 있죠. 그러나 여전히 느린 네트워크나 저사양 폰에서는 유용한 컨테이너이기도 합니다.

+ +

이 컨테이너는 ISO Base Media File Format과 MPEG-4 기반이지만 저대역폭 케이스에 최적화되어 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + +
Base 3GP media MIME types
AudioVideo
audio/3gppvideo/3gpp
audio/3gpp2video/3gpp2
audio/3gp2video/3gp2
+ +

위는 3GP 컨테이너의 기본 MIME 타입입니다; 사용하는 코덱에 따라 다른 타입을 사용할 수도 있습니다; 또한 MIME 타입 문자열에 codecs 파라미터를 추가하여 어떠한 오디오/비디오 코덱을 사용했는지 표시할 수 있으며 profile, level, 코덱 설정 값도 추가하여 전달할 수 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
3GP가 지원하는 비디오 코덱.
CodecBrowser support
ChromeEdgeFirefoxSafari
AVC (H.264)Yes1,2
H.263Yes1
MPEG-4 Part 2 (MP4v-es)Yes1
VP8Yes1
+ +

[1] FIrefox only supports 3GP on OpenMAX-based devices, which currently means the Boot to Gecko (B2G) platform.

+ +

[2] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
3GP가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AMR-NBYes1
AMR-WBYes1
AMR-WB+Yes1
AAC-LCYes1,2
HE-AAC v1Yes1,2
HE-AAC v2Yes1,2
MP3Yes1
+ +

[1] FIrefox only supports 3GP on OpenMAX-based devices, which currently means the Boot to Gecko (B2G) platform.

+ +

[2] Firefox support for AAC relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

+ +

ADTS

+ +

Audio Data Transport Stream (ADTS) 는 인터넷 라디오 같은 오디오 스트림을 사용하기 위해 MPEG-4 Part 3로 규정된 컨테이너 포맷입니다. 근본적으로 ACC 오디오 데이터에서 스트림만 깐 것과 거의 동일하며 최소한의 헤더만 담긴 ADTS 프레임으로 구성되어 있습니다.

+ + + + + + + + + + + + + + + + +
ADTS media MIME types
Audio
audio/aac[1]
audio/mpeg[1]
+ +

[1] The MIME type used for ADTS depends on what kind of audio frames are contained within. If ADTS frames are used, the audio/aac MIME type should be used. If the audio frames are in MPEG-1/MPEG-2 Audio Layer I, II, or III format, the MIME type should be audio/mpeg.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ADTS가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AACYes1
MP3Yes
+ +

[1] Firefox support for AAC relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

+ +

FLAC

+ +

Free Lossless Audio Codec (FLAC)은 무손실 오디오 코덱입니다; 이 코덱을 담을 수 있는 컨테이너 역시 FLAC이라 부릅니다. 이 포맷은 어느 특허에도 묶여있지 않아 자유롭게 사용할 수 있습니다. FLAC 파일은 FLAC 오디오 데이터만 담을 수 있습니다.

+ + + + + + + + + + + + + +
FLAC media MIME type
Audio
audio/flac
+ + + + + + + + + + + + + + + + + + + + + + + + +
FLAC이 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
FLACYes
+ +

MPEG/MPEG-2

+ +

{{interwiki("wikipedia", "MPEG-1")}}과 {{interwiki("wikipedia", "MPEG-2")}}은 근본적으로 동일합니다. the Moving Picture Experts Group (MPEG)에서 만들었으며 DVD 등의 물리적 매체에서 널리 쓰이고 있습니다.

+ +

인터넷에서 아마 가장 많이 사용되는 MPEG 파일 포맷은 {{interwiki("wikipedia", "MPEG-1", "Layer_III/MP3", "MPEG-1 Audio Layer 3")}} 일 겁니다; MP3 파일은 전 세계의 디지털 오디오 장치에서 널리 재생되고 있습니다. 반대로 MPEG-1, MPEG-2는 웹에서 별로 사용하고 있지 않죠.

+ +

MPEG-1과 MPEG-2 간의 차이점은 컨테이너 포맷이 아니라 미디어 데이터 포맷에 있습니다. MPEG-1은 1992년 소개되었으며; MPEG-2는 1996년에 소개되었습니다.

+ + + + + + + + + + + + + + + +
MPEG-1과 MPEG-2 media MIME types
AudioVideo
audio/mpegvideo/mpeg
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MPEG-1과 MPEG-2가 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
MPEG-1 Part 2No
MPEG-2 Part 2No
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MPEG-1과 MPEG-2가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
MPEG-1 Audio Layer INo
MPEG-1 Audio Layer IINo
MPEG-1 Audio Layer III (MP3)Yes
+ +

MPEG-4 (MP4)

+ +

{{interwiki("wikipedia", "MPEG-4")}} (MP4) 는 최신 MPEG 파일 포맷입니다. 파트 1과 14 스펙에서 정의된 두 가지 버전의 포맷이 있습니다. MP4는 오늘날 유명한 컨테이너 포맷으로 많이 쓰이는 코덱을 지원하며 널리 사용되고 있습니다.

+ +

최초의 MPEG-4 Part 1 포맷은 1999년 발표되었습니다; Part 14에서 정의된 버전 2 포맷은 2003년 추가되었습니다. MP4 파일 포맷은 Apple이 개발한 {{interwiki("wikipedia", "QuickTime file format")}}에서 파생된 {{interwiki("wikipedia", "ISO base media file format")}}에서 다시 파생되었습니다.

+ +

MPEG-4 미디어 타입을 표기할 때 (audio/mp4 or video/mp4), MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 추가적으로 profile, level, 코덱 설정 등을 명기할 수 있습니다.

+ + + + + + + + + + + + + + + +
기본 MPEG-4 media MIME 타입
AudioVideo
audio/mp4video/mp4
+ +

위는 MPEG-4 미디어 컨테이너의 기본 타입입니다; 어떤 코덱을 쓰느냐에 따라 MIME 타입도 달라질 수 있습니다. 또한 MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 추가적으로 profile, level, 코덱 설정 등을 명기할 수 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MPEG-4가 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AVC (H.264)Yes1
AV1Yes1
H.263No
MPEG-4 Part 2 VisualNo
VP9Yes
+ +

[1] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

+ +

[2] Firefox support for AV1 is currently disabled by default; it can be enabled by setting the preference media.av1.enabled to true.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MPEG-4가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AACYes1
FLACYes
MPEG-1 Audio Layer III (MP3)Yes
OpusYes
+ +

[1] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

+ +

Ogg

+ +

{{interwiki("wikipedia", "Ogg")}}는 Xiph.org Foundation이 운영하는 자유 오픈 컨테이너 포맷입니다. Theora, Vorbis, and Opus등의 Ogg 프레임워크는 특허에 얽매이지 않게 정의되었습니다. 재단 웹사이트에서 Xiph.org documents about the Ogg format를 확인할 수 있습니다.

+ + + + + + + + + + + + + + + +
기본 Ogg media MIME types
AudioVideo
audio/oggvideo/ogg
+ +

MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 트랙의 미디어 포맷에 대한 추가 정보도 기입할 수 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Ogg가 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
TheoraYes
VP8Yes
VP9Yes
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Ogg가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
FLACYes
OpusYes
VorbisYes
+ +

QuickTime

+ +

QuickTime 파일 포맷(QTFF, QTMOV) 는 동일한 이름의 미디어 프레임워크에서 사용하기 위해 애플이 개발했습니다. 확장자 .mov는 최초 영화에서 쓰이기 위해  개발되었다는 의미에서 지어졌으며 보통 "QuickTime movie" 포맷이라 불립니다. QTFF가 MPEG-4 파일 포맷에 기반하였지만 두 포맷에는 분명한 차이점이 있으며 상호 호환되지 않습니다.

+ +

QuickTime 파일은 오디오, 비디오 텍스트 트랙 등 시간축을 가지는 다수의 데이터 타입을 지원합니다. QuickTime 파일은 원래 macOS에서 사용하기 위해 개발되었지만 수 년이 지나면서 윈도우즈 환경에서는 QuickTime for Windows를 통해 사용할 수 있게 되었습니다. 그러나 2016년 초부터 애플은 더 이상 QuickTime for Windows를 유지 보수하지 않으며 알려진 보안 취약점으로 인해 사용해선 안됩니다. 하지만 Windows Media Player 가 현재 QuickTime version 2.0 및 이전 버전을 지원하며; 이후 버전의 QuickTime은 서드파티 플러그인을 통해 지원합니다.

+ +

Mac OS에서 QuickTime 프레임워크는 QuickTime 포맷의 영상 파일 및 코덱 뿐만아니라 널리 쓰이는 오디오/비디오 코덱 상당 수를 지원합니다. 정지 화상 이미지 포맷도 포함해서요. (QuickTime 플러그인이 설치되었거나 QuickTime과 바로 연동된 브라우저를 포함 한)맥 애플리케이션은 QuickTime을 통해서 ACC, AIFF, MP#, PCM, Qualcomm PureVoice 등의 오디오 포맷과 AVI, DV, Pixlet, ProRes, FLAC, Cinepak, 3GP, H.261 through H.265, MJPEG, MPEG-1, MPEG-4 Part 2, Sorenson 등 수 많은 비디오 포맷을 읽고 쓸 수 있습니다.

+ +

추가적인 코덱을 지원하기 위해 QuickTime에 다수의 서드파티 컴포넌트를 설치할 수도 있습니다.

+ +

QuickTime은 처음부터 지금까지 근본적으로 애플 디바이스에서 사용하기 위해 만들어졌기 때문에 인터넷 환경에서 널리 쓰이고 있지는 않습니다. 애플 스스로도 현재는 MP4 비디오를 사용하고 있구요. 게다가 QuickTime 프레임워크마저 deprecated되면서 macOS 10.15 Catalina부터는 사용이 불가능해졌습니다.

+ + + + + + + + + + + + + +
Base QuickTime media MIME type
Video
video/quicktime
+ +

video/quicktime 은 QuickTime 미디어 컨테이너의 기본 MIME 타입입니다. QuickTime (Mac OS의 미디어 프레임워크)이 다양한 컨테이너와 코덱을 지원하므로 다른 많은 MIME 타입 역시 지원합니다.

+ +

MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 추가적으로 profile, level, 코덱 설정 등을 명기할 수 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QuickTime이 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AVC (H.264)No
CinepakNo
Component VideoNo
DVNo
H.261No
H.263No
MPEG-2No
MPEG-4 Part 2 VisualNo
Motion JPEGNo
Sorenson Video 2No
Sorenson Video 3No
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QuickTime이 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AACNo
ALaw 2:1No
Apple Lossless (ALAC)No
HE-AACNo
MPEG-1 Audio Layer III (MP3)No
Microsoft ADPCMNo
µ-Law 2:1 (u-Law)No
+ +

WAVE (WAV)

+ +

Waveform Audio File Format (WAVE)는 보통 줄여서 WAV라 불리며 .wav 확장자를 갖습니다. 오디오 비트스트림 데이터를 담기 위해 Microsoft와 IBM이 개발했습니다. 대부분의 WAV 파일은 linear PCM 포맷의 오디오 데이터를 담고 있습니다.

+ +

이 파일 포맷은 Resource Interchange File Format (RIFF)에서 파생되었으며 애플의 AIFF 같은 다른 파생 형식와 유사합니다..

+ +

WAVE 포맷은 1991년 처음 발표되었습니다.

+ + + + + + + + + + + + + + + + + + + + + + +
WAVE media MIME types
Audio
audio/wave
audio/wav
audio/x-wav
audio/x-pn-wav
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WAVE가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
ADPCM (Adaptive Differential Pulse Code Modulation)No
GSM 06.10No
LPCM (Linear Pulse Code Modulation)Yes
MPEG-1 Audio Layer III (MP3)No
µ-Law (u-Law)No
+ +

WebM

+ +

{{interwiki("wikipedia", "WebM")}} (Web Media)는 {{interwiki("wikipedia", "Matroska")}}에 기반하여 현대 웹 환경에서 사용하기 위해 디자인되었습니다. 특정 제품들은 WebM 컨테이너에 다른 코덱을 사용하기도 하지만 기본적으로는 무료 오픈 코덱을 사용하여 완전한 자유-오픈 기술을 지향하고 있습니다.

+ +

WebM은 2010년 처음 소개되었습니다..

+ + + + + + + + + + + + + + + +
WebM media MIME types
AudioVideo
audio/webmvideo/webm
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WebM이 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AV1Yes1
AVC (H.264)Yes2
VP8Yes
VP:9Yes
+ +

[1] Firefox support for AV1 is currently disabled by default; it can be enabled by setting the preference media.av1.enabled to true.

+ +

[2] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
WebM이 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
OpusYes
VorbisYes
+ +

알맞은 컨테이너 선택하기

+ +

여러분의 미디어 데이터에 알맞은 컨테이너를 선택하고 사용하기 위해서 몇 가지 고려해야 할 점들이 있습니다. 상대적으로 어떤 점이 더 중요한지는 요구사항이나 라이선스, 호환성, 타겟 고객 등에 따라 달라질 수 있습니다.

+ +

가이드라인

+ +

최선책 역시 미디어 데이터로 무엇을 하느냐에 달렸습니다. 미디어를 녹화/편집하는 것은 재생과 전혀 다른 이야기입니다. 최소한 노이즈 축적이라도 방지하려고 무손실 압축을 사용하면 매번 재 압축할 때 마다 압축 데이터가 누적되므로 미디어 데이터를 처리할때는 압축하지 않은 데이터를 사용하는게 퍼포먼스가 좋습니다.

+ +
    +
  • 저사양 단말 또는 저속 네트워크를 사용하는 고객을 대상으로 하고 있다면 3GP 컨테이너와 적절한 압축 코덱을 고려해 볼 수 있습니다.
  • +
  • 인코딩시 필수 사항이 있다면 컨테이너 선택 시 적절한 코덱을 지원하는 지 확인해야 합니다.
  • +
  • 미디어가 상용이 아니며 오픈 포맷일 경우 FLAC(오디오), WebM(비디오) 등의 오픈 컨테이너 포맷을 고려해 보세요.
  • +
  • 어떠한 이유로 미디어를 한가지 포맷으로 제공해야 한다면 많은 디바이스와 브라우저에 널리 쓰여지는 MP3(오디오), MP4(비디오, 오디오)등의 포맷을 선택하세요.
  • +
  • 미디어가 오디오만 있다면 오디오 전용 컨테이너를 사용하는게 합당합니다. 현재는 특허가 모두 만료되어 널리 쓰여지는 MP3가 좋은 선택입니다. WAVE도 좋지만 비압축이므로 대용량 오디오 샘플의 경우에는 사용을 주의하세요. 모든 타겟 브라우저가 지원한다면 무손실 압축을 지원하는 FLAC이 최선입니다.
  • +
+ +

슬픈 일이지만 주요 무손실 압축 포맷 (FLAC, ALAC) 모두 폭넓게 지원되고 있지 않습니다. 둘 중에 FLAC이 그나마 낫지만 macOS에서는 추가적인 소프트웨어 설치 없이는 지원을 안합니다. iOS에서는 아예 불가능하구요. 무손실 오디오를 플랫폼에 무관하게 제공하려면 FLAC과 ALAC 둘 다 지원해야 합니다.

+ +

컨테이너 선택 가이드

+ +

아래의 테이블은 다양한 시나리오에서 사용할 컨테이너에 대한 권고안입니다. 이는 추천일 뿐이며 컨테이너 포맷을 선택할 때에는 여러분의 제품이나 기관의 상황을 고려하여 선택하세요.

+ +

오디오 전용 파일

+ + + + + + + + + + + + + + + + + + + + + + +
만약에...추천 컨테이너 포맷
일반 재생 목적으로 압축 파일 사용MP3 (MPEG-1 Audio Layer III)
무손실 압축 파일FLAC with ALAC fallback
무압축 파일WAV
+ +

이제는 MP3 특허가 모두 만료되었으므로 오디오 파일 선택은 별로 어려운 문제가 아닙니다. 폭넓게 쓰이는 MP3를 사용하면서 특허료를 내야 하느냐에 대한 고민을 할 필요가 없죠.

+ +

비디오 파일

+ + + + + + + + + + + + + + + + + + + + + + + + +
만약에...추천 컨테이너 포맷
가능한 오픈 포맷을 사용한 일반 비디오WebM (MP4 호환 추가)
일반 비디오MP4 (WebM, Ogg 호환 추가)
저속 네트워크상의 고효율 압축3GP (MP4 호환 추가)
구형 단말/브라우저 지원QuickTime (AVI, MPEG-2 호환 추가)
+ +

몇 가지 가정 하의 권고입니다. 최종 결정 전에 여러가지를 따져보아야 하며 인코딩 해야 할 미디어가 많은 경우 특히나 심사숙고해야 합니다.

+ +

다양한 컨테이너간 호환성 극대화

+ +

호환성을 높이려면 한가지 버전 이상의 미디어 파일 제공을 고려해 볼 수 있습니다. {{HTMLElement("audio")}}, {{HTMLElement("video")}} 엘리먼트 아래에 {{HTMLElement("source")}} 엘리먼트를 추가하여 구현할 수 있죠. 예를 들어 Ogg, WebM 비디오를 우선하되 호환성을 위해 MP4 포맷을 추가할 수 있습니다. 레트로하게 QuickTime이나 AVI 호환을 추가하는 것도 좋은 방법입니다.

+ +

구현하려면 우선 {{htmlattrxref("src", "video")}} 어트리뷰트 없이 <video> (또는 <audio>) 엘리먼트를 생성합니다. 그 후 <video> 엘리먼트 아래에 {{HTMLElement("source")}} 엘리먼트를 제공하려는 미디어 포맷별로 추가합니다. 이 방식은 대역폭 상황에 따라 소스를 선택하는 방식으로도 사용할 수 있지만 여기서는 포맷 옵션을 제공하기로 하죠.

+ +

아래 예제에서는 두 포맷 타입의 비디오를 제공합니다: WebM and MP4.

+ +
{{EmbedInteractiveExample("pages/tabbed/source.html", "tabbed-standard")}}
+ + + +

첫번째 비디오는 WebM 포맷입니다({{htmlattrxref("type", "video")}} 어트리뷰트가 video/webm). {{Glossary("user agent")}}는 재생이 불가능 한 경우 type 이 video/mp4 인 다음 옵션으로넘어갑니다. 둘 다 재생이 불가능 할 경우 "This browser does not support the HTML5 video element." 문구가 표시됩니다.

+ +

스펙

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecificationComment
ETSI 3GPP3GP 컨테이너 포맷 정의
ISO/IEC 14496-3 (MPEG-4 Part 3 Audio)ADTS 포함 한 MP4 오디오 정의
FLAC FormatFLAC 포맷 규정
ISO/IEC 11172-1 (MPEG-1 Part 1 Systems)MPEG-1 컨테이너 포맷 정의
ISO/IEC 13818-1 (MPEG-2 Part 1 Systems)MPEG-2 컨테이너 포맷 정의
ISO/IEC 14496-14 (MPEG-4 Part 14: MP4 file format)MPEG-4 (MP4) version 2 컨테이너 포맷 정의
ISO/IEC 14496-1 (MPEG-4 Part 1 Systems)오리지널 MPEG-4 (MP4) 컨테이너 포맷 정의
{{RFC(3533)}}Ogg 컨테이너 포맷 정의
{{RFC(5334)}}Ogg 미디어 타입 및 확장자 정의
QuickTime File Format SpecificationQuickTime movie (MOV) 포맷 정의
Multimedia Programming Interface and Data Specifications 1.0공식 WAVE 스펙에 가까운 문서
Resource Interchange File Format (used by WAV)RIFF 포맷 정의; WAVE는 RIFF의 한 형태
WebM Container GuidelinesWebM 용 Matroska 적용 가이드
Matroska SpecificationsWebM 기반 Matroska 컨테이너 포맷 스펙
WebM Byte Stream FormatMedia Source Extensions를 통한 WebM 바이트 스트림 포맷
+ +

브라우저 호환성

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
컨테이너 포맷 이름오디오비디오
MIME typeExtension(s)Browser supportMIME typeExtension(s)Browser support
3GPaudio/3gpp.3gpFirefoxvideo/3gpp.3gpFirefox
ADTS (Audio Data Transport Stream)audio/aac.aacFirefox
FLACaudio/flac.flacFirefox
MPEG-1 / MPEG-2 (MPG or MPEG)audio/mpeg.mpg
+ .mpeg
Firefoxvideo/mpeg.mpg
+ .mpeg
Firefox
audio/mp3.mp3Firefox
MPEG-4 (MP4)audio/mp4.mp4
+ .m4a
Firefoxvideo/mp4.mp4
+ .m4v
+ .m4p
Firefox
Oggaudio/ogg.oga
+ .ogg
Firefoxvideo/ogg.ogv
+ .ogg
Firefox
QuickTime Movie (MOV)video/quicktime.mov
WAV (Waveform Audiofile)audio/wav.wavFirefox
WebMaudio/webm.webmFirefoxvideo/webm.webmFirefox
+ +

더 보기

+ + diff --git a/files/ko/web/media/formats/video_codecs/index.html b/files/ko/web/media/formats/video_codecs/index.html new file mode 100644 index 0000000000..5cccc89329 --- /dev/null +++ b/files/ko/web/media/formats/video_codecs/index.html @@ -0,0 +1,1646 @@ +--- +title: 웹 비디오 코덱 가이드 +slug: Web/Media/Formats/비디오코덱 +translation_of: Web/Media/Formats/Video_codecs +--- +

압축되지 않은 비디오 데이터는 그 크기가 엄청나기 때문에, 저장하거나 네트워크를 통해 전송하기 위해서는 아주 작게 압축해야 합니다. 압축되지 않은 비디오를 저장하는 과정을 상상해 봅시다:

+ +
    +
  • HD(1920x1080) 풀 컬러(픽셀 당 4바이트) 비디오의 한 프레임은 8,294,400 입니다.
  • +
  • 보통 초당 30프레임이므로 HD 비디오 1초는 248,832,000바이트 (~249 MB)를 잡아 먹습니다.
  • +
  • HD 1분은 1.39 GB가 필요합니다.
  • +
  • 일반적인 30분짜리 비디오 컨퍼런스의 경우 47.1 GB가 필요하며, 2시간짜리 영화는 무려 166 GB입니다.
  • +
+ +

비압축된 비디오 데이터는 스토리지 공간이 많이 필요할 뿐만 아니라 네트워크로 전송할 경우에도 어마어마한 대역폭이 필요합니다. 오디오와 오버헤드를 제외하고도 초당 249 MB가 필요하죠. 여기서 비디오 코덱이 등장합니다. 오디오 코덱이 사운드 데이터를 처리하듯이 비디오 코덱도 비디오 데이터를 압축하고 적절한 포맷으로 인코딩하여, 이후에 디코딩하여 재생 또는 편집할 수 있도록 합니다.

+ +

대부분의 비디오 코덱은 손실 압축입니다. 디코딩해도 원본과 완전히 동일하지 않죠. 디테일한 부분이 사라질 수 있는데; 얼마나 사라지는지는 코덱와 설정에 달렸습니다만 압축율을 높일수록 디테일과 정확도는 감소합니다. 무손실 코덱도 있긴 합니다만, 보통 기록 보존 및 로컬 재생에만 염두에 두고 있는 경우가 많습니다.

+ +

이 문서는 웹에서 흔히 볼 수 있는 비디오 코덱을 소개하고 각각의 기능과 호환성, 사용성에 대해 설명하고 여러분에게 필요한 적절한 코덱을 찾는 법을 안내합니다.

+ +

일반 코덱

+ +

웹에서 널리 쓰이는 비디오 코덱은 아래와 같습니다. 각 코덱마다 해당 코덱을 지원하는 컨테이너(파일 타입)도 나열되어 있습니다. 각 코덱의 링크를 클릭하면 해당 코덱에 대해 세부정보, 기능, 호환성 등 필요한 내용이 추가된 하단 섹션으로 이동합니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
코덱 이름 (축약어)전체 코덱 이름지원하는 컨테이너
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
+ +

인코딩 관여 요소

+ +

어떤 인코더를 사용하든지간에 인코딩된 비디오의 크기와 퀄리티를 결정하는 두 개의 기본적인 요소 그룹이 있습니다: 하나는 소스 비디오의 포맷와 콘텐츠이며 나머지는 인코딩 시 코덱의 특징 및 설정입니다.

+ +

요약하자면 이겁니다:인코딩 된 비디오가 원본에 가까울수록, 압축율은 적고 비디오 파일 크기는 커집니다. 그러므로 사이즈와 퀄리티는 항상 트레이드 오프가 있습니다. 특별한 경우에는 퀄리티 손실을 크게 감수하고서라도 사이즈를  많이 줄여야 할 필요가 있을 수도 있으며;반대로 고용량의 파일을 생성하더라도 퀄리티를 최대한 유지해야 하는 경우도 있습니다.

+ +

인코딩 된 비디오에 영향을 끼치는 소스 포맷

+ +

소스 비디오의 형식이 출력에 영향을 미치는 정도는 코덱과 작동 방식에 따라 다릅니다. 코덱이 미디어를 내장 픽셀 포맷으로 변환하거나 심플 픽셀 이외의 방식으로 이미지를 표현하는 경우에는 원본 포맷에 따른 차이는 거의 없습니다. 하지만 프레임 레이트나 해상도는 반드시 출력 미디어 크기에 영향을 미치게 되죠.

+ +

또한 모든 코덱은 각각 장단점이 있습니다. 어떤 코덱은 특정한 형태와 패턴에 약하거나 엣지 선명도가 약하거나, 암부의 디테일이 떨어지거나 등의 여러가지 문제가 있을 수 있죠. 모든 건 기저의 알고리즘과 수학 공식에 달렸습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
인코딩 된 비디오의 품질과 크기에 영향을 줄 수 있는 비디오 포맷과 콘텐츠
기능품질에 영향크기에 영향
Color depth (bit depth)색 깊이가 높을수록 비디오의 색상 정확도가 높아집니다. Additionally, 이미지의 강렬한 부분 (빛이나 순수한 빨강  [rgba(255, 0, 0, 1)] 등 매우 원색적인 색상), 컴포넌트당 10bit (10-bit color) 이하의 색 깊이에서는 그라데이션 부분이 마치 계단처럼 색상이 분리되는 현상인 컬러 밴딩이 발생할 수 밖에 없습니다.코덱에 따라 다르지만 색 깊이가 높을 수록 압축된 파일 사이즈가 커지게 됩니다. 압축 데이터의 내장 스토리지 포맷에 따라 결정됩니다.
프레임 레이트이미지 상에 보여지는 움직임이 얼마나 부드러운지에 크게 영향을 끼칩니다. 프레임 레이트가 높을 수록 움직임이 더 부드럽고 현실에 가까워 집니다. 계속 높이다보면 압축의 의미가 없어지는 지점에 도달하게 되죠. 아래의 {{anch("Frame rate")}} 절을 참조하세요.인코딩 도중 프레임 레이트를 감소시키지 않는 다면 높을 수록 압축된 결과물이 커집니다.
움직임(Motion)비디오 압축은 일반적으로 프레임을 비교하면서 수행합니다. 두 프레임이 어디가 다른지 찾아낸 후 이전 프레임에서 다음 프레임을 예측하기 위핸 최소한의 정보만을 기록하는 방식입니다. 연속된 프레임이 다른 것들과 다를 수록 차이점도 많아지고 the less effective the compression is at avoiding the introduction of artifacts into the compressed video.움직임이 복잡할 수록 프레임간의 차이점이 많아 지므로 인터프레임이 커지게 됩니다. 이를 비롯한 여러가지 이유로 인해 일반적으로 움직임이 많은 영상일수록 사이즈가 큽니다.
잡음(Noise)픽쳐 노이즈(필름 그레인 효과, 먼지 등 이미지의 불규칙한 점들)는 픽셀간 변화폭을 늘립니다. 증가된 변화폭은 압축을 어렵게 하고 동일한 압축 레벨일 때 디테일을 떨어뜨리는 원흉이 되죠.이미지에 -노이즈 같이- 변화폭이 큰 부분이 많을수록 압축 알고리즘이 비슷한 수준으로 이미지를 압축하기 어렵습니다. 노이즈로 인한 변화폭을 무시하도록 인코더를 세팅하지 않는 한 노이즈가 많을 수록 압축된 비디오 파일 크기도 커질겁니다.
해상도(width, height)압축하는 과정에 특이사항이 발생하지 않는 한 동일한 크기의 스크린에 더 높은 해상도의 비디오가 출력될 수록 원본에 가까운 영상을 볼 수 있습니다.해상도가 높을수록 비디오 크기도 커집니다. 최종 사이즈에 결정적인 요소죠.
+ +

위 요소들이 인코딩 된 비디오에 미치는 정도는 선택한 인코더와 설정 등 정확한 상황에 따라 굉장히 다양합니다. 인코딩 중에 코덱의 일반 옵션에 더해서 프레임 레이트를 줄이거나 노이즈 제거, 비디오 해상도를 줄이는 등 인코더 설정을 추가할 수 있습니다.

+ +

인코딩 결과물에 영향을 끼치는 코덱 설정

+ +

비디오 인코딩에 쓰이는 알고리즘은 보통 여러가지의 기술들로 구성되어 있습니다. 일반적으로 최종 결과물의 크기를 줄이기 위한 설정 옵션은 비디오 퀄리티 하락이나 특정 이슈를 발생시킵니다. 최종 결과물이 매우 커지지만 오리지널 소스를 완벽하게 재생하기 위해 무손실 인코딩을 택할 수도 있습니다.

+ +

또한 각 인코더는 결과물의 품질과 크기에 영향을 끼치는 다양한 바리에이션을 가지고 있기도 합니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
품질과 크기에 영향을 미치는 비디오 인코더 설정
기능품질에 영향크기에 영향
무손실 압축품질 손실 없음손실 압축에 비해 무손실 압축은 전체 비디오 크기를 많이 줄일 수 없습니다; 결과물 파일은 일반적으로 사용하기엔 여전히 매우 거대합니다.
+

손실 압축

+
특정 코덱과 압축을 어떻게 하느냐에 따라 퀄리티 저하에 영향을 끼치는 인자나 기타 요소가 어느 정도 발생하게 됩니다.원본 비디오와 많이 달라져도 된다면 높은 압축률을 달성하는 것은 어렵지 않습니다.
품질 세팅품질 설정을 높게 세팅할수록 인코딩 된 비디오도 원본에 가깝게 보일겁니다.보통은 높은 품질로 설정할 수록 인코딩 된 비디오 파일도 커집니다;그 정도는 코덱에 따라 다르겠지만요.
비트레이트품질을 높이면 보통 비트레이트도 높아집니다.비트레이트가 높으면 결과물 파일도 커지죠.
+ +

인코딩 시 설정 가능한 항목과 값은 코덱마다 다를 뿐만 아니라 사용하는 인코더 소프트웨어에 따라서도 다양합니다. 여러분이 사용하는 인코더 소프트웨어의 가이드 문서에 인코딩 시 영향을 끼치는 옵션에 대해 설명하고 있을겁니다.

+ +

압축 아티팩트

+ +

아티팩트는 는 손실 압축에서 발생할 수 있는 부작용으로 시각적인 데이터의 손실 또는 변경입니다. 비디오 출력 방식 때문에 아티팩트가 한 번 발생하면 생각보다 오래 남습니다. 비디오의 각 프레임은 현재 보여지는 프레임에서 변경된 부분만 적용하는 방식으로 표현됩니다. 이 말은 즉 에러나 아티팩트는 시간이 지날수록 복잡해지고 이미지상의 결함이나 이상한 점, 깨진 부분 등이 한동안 지속된다는 걸 의미하죠.

+ +

이 문제도 해결하고 또 비디오 데이터의 탐색 시간을 개선하기 위해 주기적으로 키 프레임(인트라-프레임 또는 i-프레임)을 비디오 파일에 삽입합니다. 키 프레임은 통짜 프레임으로 현재 보이는 이미지 손상이나 아티팩트를 수정하기 위해 존재합니다.

+ +

위신호(Aliasing)

+ +

위신호는 인코딩 된 데이터가 압축하기 전과 다르게 보이는 현상 전반에 대한 일반 용어입니다. 여러가지 종류의 위신호가 있으며;흔히 보이는 것들은 아래와 같습니다:

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

모아레 현상(Moiré patterns)

+ +

{{interwiki("모아레 현상-Moiré pattern")}}는 소스 이미지의 패턴과 인코더의 동작 방식이 공간적으로 약간 정렬되어 있지 않을 때 발생하는 대규모 공간 간섭 패턴입니다. 인코딩 시 발생한 아티팩트를 디코딩 하면 소스 이미지에 이상한 회오리 무늬가 생깁니다.

+
+

계단 현상

+ +

계단 현상은 공간적 아티팩트의 하나로 부드러워야 할 대각선이나 곡선 경계면이 마치 계단처럼 들쭉날쭉하게 보이는 현상을 의미합니다. "안티-앨리어싱"필터를 사용하면 줄일 수 있습니다.

+
+

마차 바퀴 현상

+ +

마차 바퀴 현상 (또는 {{interwiki("wikipedia", "스트로보 효과")}})은 필름에서 흔히 볼 수 있는 시각적 효과로 프레임 레이트와 압축 알고리즘에 의해 회전하는 바퀴가 느리거나 빠르게 혹은 아예 반대 방향으로 보이는 것을 의미합니다. 이는 철도 노선의 침목이나 도로변의 기둥 등 일정한 패턴으로 움직이는 것이라면 어디서든 볼 수 있습니다. 이는 시간적 위신호 이슈로;압축 또는 인코딩 시 샘플링 레이트가 회선 속도에 간섭하여 발생합니다.

+
+ +

컬러 엣징(Color edging)

+ +

컬러 엣징은 시각적 아티팩트 중 하나로 화면상의 색상을 가진 오브젝트들의 경계면에 잘못된 색상이 나타나는 현상입니다. 나타나는 색상은 프레임의 콘텐츠간에 아무 연관도 없습니다.

+ +

선명도 손실

+ +

비디오 인코딩 중 일부 데이터를 제거하면 필연적으로 디테일 손실이 발생합니다. 충분히 압축하고 나면 일부 또는 전체 이미지에 약간 불분명하거나 흐릿한 부분이 보일 수 있습니다.

+ +

선명도가 떨어지면 이미지 상의 글자를 읽기 어렵습니다. 특히나 작은 글씨들은 디테일에 민감한 콘텐츠로 작은 변화로도 매우 읽기 어려워집니다.

+ +

링잉 효과(Ringing)

+ +

손실 압축 알고리즘은 링잉 효과 {{interwiki("wikipedia", "ringing artifacts", "ringing")}}를 일으킬 수 있습니다. 링잉 효과는 압축 알고리즘에 의해 오브젝트의 경계면에 픽셀이 오염되는 현상을 의미합니다. 압축 알고리즘이 오브젝트와 배경의 경계면이 포함된 블럭을 사용했을 때 발생할 수 있습니다. 보통 압축율이 높을 때 주로 발생합니다.

+ +

Example of the ringing effect

+ +

위 별 모양의 경계 부분에 파랑 및 분홍 부분을 보세요 (계단 현상 등 다른 압축 아티팩트도 나타남). 저 부분이 링잉 효과입니다. 링잉은 어떤 면에서는 {{anch("Mosquito noise", "mosquito noise")}}와 비슷합니다, 다만 모기 효과는 일렁거리거나 움직이는데 반해 링잉 효과는 정지한 채로 변하지 않습니다.

+ +

링잉 효과 역시 이미지 상의 글자를 읽기 어렵게 하는 아티팩트입니다.

+ +

포스터라이징(Posterizing)

+ +

포스터리제이션은 압축된 결과물이 그라디언트 부분에서 색상 디테일을 잃는 현상을 의미합니다. 그라디언트 영역이 부드럽게 색상이 변하지 않고 원본과 비슷한 색상의 블록 형태로 얼룩이 묻은 듯한 이미지로 표현 됩니다.

+ +

+ +

위 이미지상 흰머리 수리의  깃털 부분의 색상이 블록처럼 보이는 것을 보세요(배경의 흰색 올빼미도요). 포스터리제이션 효과로 인해 깃털의 디테일을 상당 부분 잃었습니다.

+ +

컨투어링(Contouring)

+ +

컨투어링 또는 컬러 밴딩은 포스터리제이션의 특별한 형태로 이미지에서 색상 블록이 줄무늬 형태로 나타나는 현상을 의미합니다. 이는 비디오 인코딩 시 양자화 설정이 제대로 이뤄지지 않은 경우 발생할 수 있습니다.  결과적으로 부드럽게 변해야 할 그라디언트 부분에 "층"이 생긴 것처럼 줄무늬가 보입니다.

+ +

Example of an image whose compression has introduced contouring

+ +

위 이미지를 보시면 하늘에서 지평선으로 부드럽게 변해야 하는데 파란색이 층층이 져 있는 것을 볼 수 있습니다. 이 것이 컨투어링 효과입니다.

+ +

모스키토 노이즈(Mosquito noise)

+ +

모스키토 노이즈는 시간적 아티팩트 중 하나로 배경과 물체의 경계면의 차이가 큰 부분에서 노이즈나 edge busyness가 흐릿하게 일렁거리는 현상을 의미합니다. 시각적으로는  {{anch("Ringing", "ringing")}} 효과와 유사합니다.

+ +

+ +

위 이미지상 다리 여러군데의 주변 하늘에서 모스키토 노이즈를 볼 수 있습니다. 우측 상단에 모스키토 노이즈가 발생한 부분을 확대해 놓았습니다.

+ +

모스키토 노이즈는 MPEG 비디오에서 흔히 발견할 수 있지만 이산 코사인 변환(DCT)를 사용한 로직이라면 어디든지 발생할 수 있습니다;JPEG 정지 화상에서도요.

+ +

움직임 보상 블록 경계면 아티팩트

+ +

일반적인 비디오 압축은 두 프레임을 비교한 뒤 프레임간 차이점을 마지막 프레임까지 저장하는 방식으로 진행됩니다. 고정된 카메라에 촬영되는 물체들도 정지해 있다면 이 압축 방식은 매우 잘 동작하겠지만 프레임마다 움직임이 커지면 압축률을 높이기가 쉽지 않습니다.

+ +

{{interwiki("wikipedia", "움직임 보상")}}은 물체가 각각의 방향으로 얼마만큼 많은 픽셀이 이동했는지 움직임(카메라 자체의 이동 또는 프레임 상의 물체의 이동)을 추적하는 기술입니다.  그리고 단순 움직임 만으로는 설명할 수 없는 픽셀의 추가 정보와 함께 움직임을 저장합니다. 요약하자면 인코더가 움직이는 물체를 찾아낸 후 원본과 동일해 보이지만 새로운 위치로 이동한 인터널 프레임을 생성하는 방식입니다. 이론적으로는 새로운 프레임이 나타난 것과 거의 동일합니다. 새 프레임에 남아있는 다른 차이점이 발견된다면 물체의 움직임과 픽셀 차이점을 저장하여 작업을 마무리 합니다. 이렇게 움직임과 픽셀 차이점이 기록된 물체를 residual frame이라 부릅니다.

+ + + + + + + + + + + + + + + + + + + + + + + + +
원본 프레임인터-프레임 차이점움직임 보상 이후 차이점
Original frame of videoDifferences between the frames after shifting two pixels right
시청자에게 보이는 최초 전체 프레임이건 첫번째 프레임과 두번째 프레임간의 차이점만 나타낸 화면입니다. 나머지는 모두 검정이죠. 가까이서 보면 이 움직임들은 단지 카메라가 수평으로 이동했기 때문에 발생한 것을 알 수 있습니다. 움직임 보상을 써먹기에 아주 좋은 후보죠.차이점을 가지는 픽셀 수를 최소화 하기 위해 첫번째 프레임에서 카메라가 오른쪽으로 2픽셀 이동하였다고 가정한 뒤 픽셀 차이점을 계산합니다. 이는 카메라의 움직임을 추적하여 두 프레임간 겹치는 부분이 더 많아지게 합니다.
Images from Wikipedia
+ +

움직임 보상에는 두 가지 형태가 있습니다: 전역 움직임 보상 과 블록 움직임 보상입니다. 전역 움직임 보상은 달리, 트래킹, 선회, 기울이기 및 회전 등의 카메라 변화를 감지합니다. 블록 움직임 보상은 추적 대상이 될만한 움직임의 작은 부분들을 찾아 처리합니다. 블록들은 보통 고정된 크기를 가지고 격자 형태로 배열되어 있지만 다양한 크기의 블록 및 블록이 겹치는 경우도 처리할 수 있도록 여러 형태의 움직임 보상을 지원합니다.

+ +

하지만 움직임 보상에서도 아티팩트가 발생할 수 있습니다. 링잉 효과 등의 현상이 발생할 만큼 선명한 경계면에서 주로 발생합니다. 이는 residual frame을 코딩하는 도중 수학 계산의 결과물로 인해 발생하는 것으로 다음 키프레임에 의해 수정되기 전에 쉽게 발견할 수 있습니다.

+ +

프레임 크기 감소

+ +

특정 상황에서는 비디오 면적을 감소시키는 것이 비디오 파일 최종 사이즈를 줄이는데 도움이 되기도 합니다. 재생 도중 당장의 크기나 부드러움이 줄어드는 건 안 좋은 게 사실이지만 세심하게 조절하면 최종 결과물은 더 좋아질 수 있습니다. 1080p 비디오를 인코딩 전 720p 비디오로 축소한다면 화질을 더 높게 유지한 채로 크기를 훨씬 줄일 수 있습니다; 재생 할 때 스케일업 하더라도 필요한 파일 크기에 맞추어 품질을 조정한 채 전체 크기로 인코딩한 경우보다 화질이 좋습니다.

+ +

프레임 레이트 감소

+ +

비슷하게 전체 비디오에서 프레임을 제거하고 프레임 레이트를 감소시킬 수도 있습니다. 두 가지 장점이 있는데: 전체 비디오를 작게 만들고 움직임 보상 처리가 더 쉬워집니다. 예를 들어 2 픽셀이 차이나는 두 인터 프레임 간의 움직임 차이점을 계산하는 대신에, 프레임을 스킵하여 두 프레임 간 4 픽셀 차이점을 계산하도록 할 수 있습니다. 이러면 전체 카메라 이동을 더 적은 residual frame으로 표현할 수 있습니다.

+ +

사람 눈의 움직이는 것처럼 인식되는 최소한의 프레임 레이트는 약 12입니다. 그보다 적으면 비디오가 아니라 연속된 정지 화상으로 보입니다. 영화 필름은 보통 초당 24 프레임이며 표준 화질 TV(SDTV)는 대략 30 fps(약간 적지만 비슷합니다, 29.97), 고화질 TV(HDTV)는 24-60fps입니다. 24fps이상이면 일반적으로 충분히 부드러워 보입니다;여러분의 필요에 따라 다르지만 30/60fps가 이상적인 목표치죠.

+ +

결론적으로 어떤걸 희생할 지 정하는 것은 여러분의 디자인 팀에 달렸습니다.

+ +

코덱 세부사항

+ +

AV1

+ +

AOMedia Video 1 (AV1) 코덱은 Alliance for Open Media 기관이 인터넷 비디오를 위해 개발한 오픈 포맷입니다. {{anch("VP9")}}, {{anch("HEVC", "H.265/HEVC")}} 보다 압축율이 높으며, AVC보다 50% 이상 압축율이 높습니다. AV1은 완전한 로열티 프리이며 {{HTMLElement("video")}} 엘리먼트와 WebRTC에서 사용하기 위해 설계하였습니다.

+ +

AV1은 현재 세 프로파일을 제공하며:main, high, professional 다양한 색 깊이와 크로마 서브샘플링을 지원합니다. 또한 레벨 역시 정의하여 각 레벨은 비디오 속성의 범위를 제한하고 있습니다. 비디오 속성에는 프레임 면적, 픽셀간 이미지 영역, 출력 및 디코딩 속도, 평균/최대 비트 레이트, 인코딩/디코딩 시 사용하는 타일 개수와 항목 등이 있습니다.

+ +

예를들어 AV1 level 2.0의 최대 프레임 크기는 가로 2048 세로 1152 픽셀이지만 프레임 당 최대 픽셀 개수는 147,456(<= 2048x1152 = 2,359,296)이므로 실제 2048x1152 크기의 프레임을 사용할 수는 없습니다. 하지만 인지해야 할 점은 적어도 파이어폭스와 크롬의 소프트웨어 디코더는 현 시점에서 사실상 레벨은 무시하고 주어진 설정에 맞추어 비디오를 디코딩하는데 최선을 다합니다. 하지만 향후 호한성을 위해 여러분은 선택한 레벨에 맞추어 유지해야 합니다.

+ +

현시점의 AV1의 주요 문제점은 새로운 포맷이며 브라우저에 연동이 아직 진행중에 있다는 것입니다. 또한 인/디코더도 최적화해야 하며 하드웨어 인/디코더는 제품화되지 않아 아직 개발중입니다. 이러한 문제점들이 소프트웨어적으로 해결되기 전까지는 비디오 인코딩을 AV1 포맷으로 전환하는데 시간이 소요될 것입니다.

+ +

위와 같은 이유로 당분간 최우선 비디오 코덱으로 AV1를 사용하기에는 이르지만 미래에는 반드시 선택을 고려해야 합니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트비디오 레벨에 따라 다름;이론적으로 level 6.3에서 최대 800Mbps[2]
지원 프레임 레이트레벨에 따라 다름;예를 들어 level 2.0은 최대 30fps, level 6.3은 최대 120fps
압축손실 DCT 기반 알고리즘
지원 프레임 크기8 x 8 픽셀 에서 65,535 x 65535 픽셀 사이 값
지원 컬러 모드 + + + + + + + + + + + + + + + + + + + + + + + + + +
프로필색 깊이크로마 서브샘플링
Main8 or 104:0:0 (그레이스케일) or 4:2:0
High8 or 104:0:0 (그레이스케일), 4:2:0, or 4:4:4
Professional8, 10, or 124:0:0 (그레이스케일), 4:2:0, 4:2:2, or 4:4:4
+
HDR 지원
가변 프레임 레이트 (VFR) 지원
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
AV1 지원707567No57No
+
지원 컨테이너ISOBMFF[1], MPEG-TS, MP4, WebM
{{Glossary("RTP")}} / WebRTC 호환성
유지 보수 기관Alliance for Open Media
스펙https://aomediacodec.github.io/av1-spec/av1-spec.pdf
라이선스로열티 프리, 공개 포맷
+ +

[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)

+ +

MPEG-4 스펙 집합 중 Advanced Video Coding (AVC) 표준은 ITU H.264 스펙 및 MPEG-4 Part 10 스펙과 동일한 것입니다. TV 방송, 영상회의, 블루레이 디스크 미디어를 포함한 모든 종류의 미디어에 사용되는 움직임 보상에 기반한 코덱이죠.

+ +

AVC는 높은 호환성을 지원하는 여러 프로파일 덕분에 매우 유연합니다; 예를들어 Constrained Baseline Profile은 영상회의와 모바일 환경을 고려하였고 MainProfile(몇몇 지역에서 SDTV로 사용)나 High Profile(블루레이 디스크에서 사용)보다 대역폭을 적게 사용합니다. 대부분의 프로파일은 8-bit 컬러 컴포넌트와 4:2:0 크로마 서브샘플링을 사용합니다; High 10 Profile은 10-bit 컬러를 지원하며 High 10 Advanced form은 4:2:2, 4:4:4 크로마 서브샘플링을 지원합니다.

+ +

AVC에 동일한 장면의 여러 시점을 지원하는 기능도 있습니다.(Multiview Video Coding), 이는 양안 영상 등을 가능하게끔 합니다.

+ +

AVC는 유료 포맷이지만 무수한 특허들이 개입한 여러 단체에 소유권이 나뉘어져있습니다. 상용 목적일때는 AVC 미디어 라이선스가 필요하지만 인터넷 환경에서 최종 사용자에게 비디오가 무료로 스트리밍하는 경우에는 MPEG LA 특허권자가 라이선스를 요구하지 않습니다.

+ +

웹이 아닌 환경에서 WebRTC를 구현한 브라우저(JavaScript API가 없는 제품이라도)는 WebRTC 콜을 위해 AVC를 지원해야합니다. 웹 브라우저는 꼭 그럴필요는 없지만 몇몇은 지원하고 있습니다.

+ +

많은 플랫폼이 웹브라우저의 HTML 콘텐츠 형태로 AVC의 하드웨어 인코딩/디코딩을 지원하고 있습니다. 하지만 AVC를 프로젝트에서 사용하기 전에 라이선스 요구사항을 꼭 읽어보세요!

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트레벨에 따라 다름
지원 프레임레이트레벨에 따라 다름; 300 fps까지 가능
압축손실 DCT 기반 알고리즘, 이미지안에 무손실 매크로 블록 생성 가능
지원 프레임 크기최대 8,192 x 4,320 픽셀
지원 컬러 모드 +

일반적이고 유효한 프로필:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
프로필색 깊이크로마 서브샘플링
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 (그레이스케일) and 4:2:0
Progressive High (ProHiP)84:0:0 (그레이스케일) and 4:2:0
High 10 (Hi10P)8 to 104:0:0 (그레이스케일) and 4:2:0
High 4:2:2 (Hi422P)8 to 104:0:0 (그레이스케일), 4:2:0, and 4:2:2
High 4:4:4 Predictive8 to 144:0:0 (그레이스케일), 4:2:0, 4:2:2, and 4:4:4
+
HDR 지원예; {{interwiki("wikipedia", "Hybrid Log-Gamma")}} 또는 Advanced HDR/SL-HDR; 모두  ATSC의 파트
가변 프레임 레이트 (VFR) 지원
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
AVC/H.265 지원41235[1]9253.2
+
지원 컨테이너3GP, MP4, WebM
{{Glossary("RTP")}} / WebRTC 호환
유지 보수 기관MPEG / ITU
스펙https://mpeg.chiariglione.org/standards/mpeg-4/advanced-video-coding
+ https://www.itu.int/rec/T-REC-H.264
라이선스상용 특허 다수. 상용 사용 시 라이선스 필요. 여러 특허 풀에 영향 가능
+ +

[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의 H.263 코덱은 저대역폭 환경에서 쓰기 위해 설계하였습니다. 특히 PSTN (Public Switched Telephone Networks), {{Glossary("RTSP")}}, SIP (IP-based videoconferencing) 시스템에서의 영상 회의에 초점을 맞추었습니다. 저대역폭 네트워크 환경에 최적화되었음에도 CPU에 영향이 크며 저사양 컴퓨터에서 원할하게 동작하지 않습니다. 데이터 포맷은 MPEG-4 Part2와 유사합니다.

+ +

H.263은 웹에서 널리 쓰인 적이 없습니다. H.263의 변형 포맷이 Flash 비디오나 Sorenson 코덱 같은 상용 소프트웨어에서 사용된 적은 있습니다.  하지만 주요 브라우저 중 H.263를 기본으로 지원하는 제품은 없습니다. 특정 플러그인이 H.263을 지원하고는 있습니다.

+ +

대부분의 코덱과 다르게 H.263은 인코딩 된 비디오의 프레임별 최대 비트레이트(BPPmaxKb)의 기본값을 정의하고 있습니다. 인코딩시에 BPPmaxKb값을 지정하면 각 프레임은 해당 수치를 넘어설 수 없습니다. 최종 프레임은 이 값과 프레임 레이트, 압축, 선택한 해상도와 블록 포맷에 따라 결정됩니다.

+ +

H.263은 H.264로 대체되었으며 가능한한 이전의 미디어 포맷은 사용하지 않아야 합니다. H.263이 최선일 정도로 오래된 장치를 지원해야 하는 프로젝트일 경우에만 H.263을 지원할테죠.

+ +

H.263는 Telenor, Fujitsu, Motorola, Samsung, Hitachi, Polycom, Qualcomm 등 수 많은 기관들이 소유하고 있는 특허에 기반한 상용 포맷입니다. H.263을 사용하려면 필요한 라이선스를 반드시 취득해야합니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트무제한, 단 보통 64kbps 미만
지원 프레임 레이트자유
압축손실 DCT 기반 알고리즘
지원 프레임 크기최대 1408 x 1152 픽셀[2]
지원 컬러 모드YCbCr; 각 픽쳐 포맷 (sub-QCIF, QCIF, CIF, 4CIF, or 16CIF)은 프레임 크기를 픽셀 및 휘도와 색차 샘플의 라인수로 정의하고 있음
HDR 지원아니오
가변 비트레이트 (VFR) 지원아니오
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
H.263 supportNoNoNo[1]NoNoNo
+
컨테이너 지원3GP, MP4, QuickTime
{{Glossary("RTP")}} / WebRTC 호환아니오
유지 보수 기관ITU
스펙https://www.itu.int/rec/T-REC-H.263/
라이선스상용;적절한 라이선스가 필요함. 특허 풀이 여러 곳일 수 있음.
+ +

[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)

+ +

High Efficiency Video Coding (HVEC) 코덱은 ITU의 H.265 및 MPEG-H Part 2 (MPEG-4 후속 작업으로 개발 진행 중). HEVC는 현대 프로세서의 특정점을 십분 활용하여 소프트웨어가 (8K 비디오를 포함한) 초고해상도 비디오 인코딩/디코딩을 효율적으로 할 수 있도록 설계하였습니다. 이론적으로 HEVC는 {{anch("AVC")}}와 유사한 품질을 유지하면서 절반 크기로 압축할 수 있습니다.

+ +

예를들어 각 코딩 트리 유닛(CTU, 이전 세대 코덱의 매크로블록과 유사) 샘플의 휘도 값 트리와 색차 값 트리, 필요한 문법 요소로 구성되어 있습니다. 이는 멀티 코어 환경을 쉽게 활용할 수 있게 합니다.

+ +

메인 프로파일이 컴포넌트당 8비트 컬러와 4:2:0 크로마 서브샘플링을 지원하는 점은 흥미로운 부분입니다. 또한 4:4:4 비디오는 특별 취급합니다. 휘도 샘플(이미지 픽셀을 그레이스케일로 표현)과 Cb Cr 샘플(회색을 색상으로 어떻게 변경할지 표시)을 가지는 대신, 세 채널은 3개의 모노크롬 이미지로 취급하며 렌더링시에 풀컬러 이미지를 만들어 내도록 결합합니다.

+ +

HEVC는 상용 포맷이며 여러 특허로 보호받고 있습니다. MPEG LA하에 라이선스가 관리되고 있으며; 컨텐츠 제작자나 제공자가 아닌 개발자에 청구됩니다. 여러분의 앱/웹사이트에서 HEVC 사용 여부를 결정하기 전에 최신 라이선스와 요구 사항을 점검하는 걸 잊지마세요!

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트최대 800,000 Kbps
지원 프레임 레이트레벨마다 다름; 최대 300 FPS 가능
압축손실 DCT 기반 알고리즘
지원 프레임 크기128 x 96 에서 8,192 x 4,320 픽셀; 프로파일과 레벨마다 다름
지원 컬러 모드 +

아래 표는 주요 프로파일에 한해서입니다. 여기에 포함하지 않는 프로파일도 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
프로파일색 깊이크로마 서브샘플링
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 지원
가변 프레임 레이트 (VFR) 지원
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
HEVC / H.265 supportNo18[1]No[2]11[1]No11
+
지원 컨테이너MP4
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관ITU / MPEG
스펙http://www.itu.int/rec/T-REC-H.265
+ https://www.iso.org/standard/69668.html
라이선스상용;라이선스 요구사항에서 컴플라이언스 확인 다수의 특허 풀이 적용될 수 있음에 유의
+ +

[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

+ +

MPEG-4 Video Elemental Stream (MP4V-ES) 포맷은 MPEG-4 Part 2 시각 표준 중 하나입니다. 일반적으로 MPEG-4 part 2 비디오는 더 이상 사용하지 않는데 다른 코덱에 비해 특장점이 없어 모바일에서도 쓰임새가 없습니다.  MP4V 는 MPEG-4 컨테이너의 H.263 인코딩과 본질적으로 동일합니다.

+ +

원래 목적은 {{Glossary("RTP")}} 세션에서 MPEG-4 오디오 및 비디오 스트림을 사용하기 위해서였습니다. 하지만 3GP를 통한 모바일 통신에서도 쓰이고 있습니다.

+ +

지원하는 주요 브라우저가 없으며 사실상 폐기된 포맷이라 왠만하면 사용할 일이 없을겁니다. 이 컨테이너 파일의 확장자는.mp4v지만 .mp4로 잘못 표기된 경우도 있습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트5 Kbps 에서 1 Gbps 이상
지원 프레임 레이트명시적 제한 없음; 데이터 전송율에 의해 제한
압축손실 DCT 기반 알고리즘
지원 프레임 크기최대 4,096 x 4,096 픽셀
지원 컬러 모드YCrCb 크로마 서브샘플링(4:2:0, 4:2:2, and 4:4:4); 컴포넌트당 12bits 색 깊이
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원Yes
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
MP4V-ES supportNo[2]NoYes[1]NoNoNo
+
지원 컨테이너3GP, MP4
{{Glossary("RTP")}} / WebRTC 호환아니오
Supporting/Maintaining 유지/보수 기관MPEG
스펙{{RFC(6416)}}
라이선스상용; MPEG LA and/or AT&T에서 필수 라이선스 취득 필
+ +

[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는 1990년대 초에 베일을 벗었습니다. 이후 MPEG 비디오 표준과는 다르게 MPEG-1은 {{Glossary("ITU", "ITU's")}}의 개입 없이 순수히 MPEG가 만들었습니다.

+ +

모든 MPEG-2 디코더는 MPEG-1 비디오를 재생할 수 있기 때문에 다양한 소프트웨어와 하드웨어 장치에서 호환 가능합니다. MPEG-1 비디오 특허는 모두 만료되었으며, 라이선스에 대한 걱정에서 자유롭습니다. 하지만 소수의 브라우저만이 플러그인 없이 MPEG-1을 지원하며 플러그인은 deprecated된 경우가 많으므로 일반적으로는 더 이상 사용할 수 없습니다. 때문에 웹사이트/어플리케이션에서 MPEG-1는 좋은 선택이 아닙니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트최대 1.5 Mbps
지원 프레임 레이트23.976 FPS, 24 FPS, 25 FPS, 29.97 FPS, 30 FPS, 50 FPS, 59.94 FPS, 60 FPS
압축손실 DCT 기반 알고리즘
지원 프레임 크기최대 4,095 x 4,095 픽셀
지원 컬러 모드Y'CbCr 4:2:0 크로마 서브샘플링 with up to 12 bits per component
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원아니오
브라우저 호환 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-1 supportNoNoNoNoNoYes
+
지원 컨테이너MPEG
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관MPEG
스펙https://www.iso.org/standard/22411.html
라이선스Proprietary; however, all patents have expired, so MPEG-1 may be used freely
+ +

MPEG-2 Part 2 Video

+ +

MPEG-2 Part 2 {{Glossary("ITU")}}가 설계한 H.262를 참조하여 MPEG-2 스펙에서 정의한 비디오 포맷이며입니다. MPEg-1 비디오와 매우 유사하며 사실 MPEG-2 플레이어는 높은 비트레이트 및 특수 인코딩 옵션 지원을 위한 확장 스펙이 아닌 한 특별한 작업 없이 MPEG-1 비디오를 재생할 수 있습니다.

+ +

MPEG-2의 목적은 표준 TV로 압축하는 것이므로 인터레이스 비디오도 지원합니다. 표준 비디오 결과물의 압축 비율과 품질은 DVD 비디오 미디어의 요구사항도 충족하여 메인 비디오 코덱으로 MPEG-2가 선정되기에 충분하였습니다.

+ +

MPEG-2는 서로 다른 스펙을 가진 여러 프로파일이 있습니다. 각 프로파일은 4개의 레벨을 가지고 있으며 프레임 레이트, 해상도, 비트레이트등의 비디오 속성 값을 증가시킬 수 있습니다. 대부분의 프로파일은 Y'CbCr 4:2:0 크로마 서브샘플링을 쓰지만 더 상위의 프로파일은 4:2:2를 지원한다든가 말입니다. 추가로 대형 프레임 크기 및 비트레이트 지원을 위한 4개의 레벨이 있습니다. 예를 들어 북미 지역의 {{interwiki("wikipedia", "ATSC standards", "ATSC")}} TV 스펙은 Main Profile at high Level을 통해 1920 x 1080 (30 FPS) 및 1280 x 720 (60 FPS)의 고화질을 최대 80 Mbps 비트레이트로 지원합니다.

+ +

그러나 소수의 브라우저만 MPEG-2를 네이티브로 지원하며 플러그인은 대부분 deprecated 되어 더 이상 사용 가능하지 않습니다. 때문에 웹 사이트나 웹앱에서 MPEG-2는 좋은 선택이 아닙니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트최대 100 Mbps; 레벨과 프로파일에 따라 다름
지원 프레임 레이트 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
축약어레벨 이름지원 프레임 레이트
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
+
압축손실 DCT 기반 알고리즘
지원 프레임 크기 + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
축약어레벨 이름최대 프레임 크기
LLLow Level352 x 288 pixels
MLMain Level720 x 576 pixels
H-14High 14401440 x 1152 pixels
HLHigh Level1920 x 1152 pixels
+
지원 컬러 모드대다수 프로파일에서 Y'CbCr 4:2:0 크로마 서브샘플링; "High", "4:2:2" 프로파일에서 4:2:2 크로마 서브샘플링 지원.
HDR 지원아니오
가변 프레임 레이트(VFR) 지원아니오
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-2 supportNoNoNoNoNoYes
+
지원 컨테이너MPEG, MPEG-TS (MPEG Transport Stream), MP4, QuickTime
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관MPEG / ITU
스펙https://www.itu.int/rec/T-REC-H.262
+ https://www.iso.org/standard/61152.html
라이선스상용; 2019년 4월 1일자로 말레이지아와 필리핀을 제외한 모든 지역에서 모든 특허 만료됨, 두 국가 외에서는 자유롭게 사용 가능. MPEG LA에 의해 특허 관리
+ +

Theora

+ +

Xiph.org가 {{interwiki("wikipedia", "Theora")}}는 로열티와 라이선스 없이 사용 가능한 오픈소스 자유 비디오 코덱입니다. Theora의 품질과 압축율은 MPEG-4 Part 2 Visual과 AVC에 견줄만하며, 비디오 인코딩 시 반드시 최고를 고수해야 하는 경우가 아니라면 매우 좋은 선택이 될 수 있습니다. 하지만 라이선스-프리로 특허 문제가 없으며 상대적으로 저사양 CPU에서도 충분히 돌아가는 스펙 덕분에 최근 많은 소프트웨어와 웹프로젝트에서 선택하고 있습니다. 현재로써는 Theroa를 위한 하드웨어 디코더가 없기 때문에 저사양 CPU에서도 원할하다는 점은 아주 중요합니다.

+ +

Theora는 원래 On2 Technologies의 VC3 코덱을 베이스로 하고 있습니다. VC3 코덱과 사양은 Xiph.org 관리 하에 LGPL 라이선스로 등재되어 있으며 이후 Theora 표준으로 인입하였습니다.

+ +

Theora의 단점 중 하나는 오직 8 bit 컬러 모드만을 지원하여 컬러 밴딩을 피하기 위해 10 이상의 컬러 모드를 선택하는 옵션이 없다는 겁니다. 따지자면 현 시점에서 8 bit 컬러가 대부분이기 때문에 큰 문제는 되지 않습니다. 단지 불편할 뿐이죠. 또 Theora는 Ogg 컨테이너에서만 사용할 수 있습니다. 가장 큰 문제는 Safari에서 사용할 수 없다는 것입니다. macOs 뿐만 아니라 수억대의 iPhone과 iPad에서도 사용할 수 없다는 걸 의미합니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트최대 2 Gbps
지원 프레임 레이트임의의 0 이상 값 지원. 유리수 프레임 레이트를 지원하기 위해 32-bit 분자와 분모로 구성되어 있음
압축손실 DCT-기반 알고리즘
지원 프레임 크기최대 1,048,560 x 1,048,560 픽셀 이하 어떠한 가로, 세로 조합이라도 가능
지원 컬러 모드Y'CbCr 4:2:0, 4:2:2, 4:4:4 크로마 서브샘플링, 8 bit 컬러
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원[1]
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
Theora support3Yes[2]3.5No10.5No
+
지원 컨테이너Ogg
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관Xiph.org
스펙https://www.theora.org/doc/
라이선스오픈 프리-로열티
+ +

[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

+ +

Video Processor 8 (VP8) 코덱은 최초 On2 Technologies가 개발했습니다. Google은 On2 인수 후, VP8 관련된 특허와 무관하게 완전한 오픈 로열티-프리 라이선스로 출시했습니다. 압축률과 품질의 면에서 VP8은 {{anch("AVC")}}에 견줄만 합니다.

+ +

브라우저가 지원한다면 V8에서 알파 채널을 쓸 수 있으며 비디오 뒤의 백그라운드 이미지를 알파 채널 픽셀과 겹쳐 볼 수도 있습니다.

+ +

HTML 콘텐츠로써 특히 WebM 파일에 포함된 VP8을 지원하는 좋은 브라우저가 많습니다. 이는 VP8이 여러분의 콘텐츠로 좋은 선택이 될 수 있으며 가능하다면 더 좋은 VP9를 선택할 수도 있습니다. 웹브라우저는 WebRTC를 위해 VP8을 반드시 지원해야 합니다. 하지만 HTML Audio video 엘리먼츠에는 꼭 VP8을 지원할 필요는 없습니다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트level별 제한이 없는 한 무제한 임의의 값
지원 프레임 레이트임의 값
압축손실 DCT-기반 일고리즘
지원 프레임 크기최대 16,384 x 16,384 픽셀
지원 컬러 모드Y'CbCr 4:2:0 크로마 서브샘플링, 8 bit 색 깊이
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원
지원 브라우저 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
VP8 support2514[1]491612.1[2]
+
지원 컨테이너3GP, Ogg, WebM
{{Glossary("RTP")}} / WebRTC 호환예; VP8은 WebRTC의 필수 코덱 중 하나
유지/보수 기관Google
스펙{{RFC(6386)}}
라이선스라이선스 및 로열티로부터 자유로운 오픈 소스
+ +

[1] Edge support for VP8 requires the use of Media Source Extensions.

+ +

[2] Safari only supports VP8 in WebRTC connections.

+ +

VP9

+ +

Video Processor 9 (VP9)는 구글이 VP8 표준의 후속으로 개발하였습니다. VP8과 마찬가지로 VP9는 완전한 로열티-프리 오픈 소스입니다. 인코딩/디코딩 퍼포먼스는 AVC에 비해 더 높은 품질을 유지하면서도 약간 더 빠릅니다. VP9로 인코딩한 비디오의 품질은 비슷한 수준의 비트레이트에서 HEVC에 견줄만합니다.

+ +

VP9의 main profile은 4:2:0 크로마 서브 샘플링에서 8-bit 색 깊이 모드만을 지원합니다. 하지만 더 깊은 색상 모드와 전체 범위의 크로마 서브샘플링을 지원하는 프로파일도 가지고 있습니다. HDR 기능도 있으며 프레임 레이트, 영상 비율, 프레임 사이즈를 자유롭게 선택할 수 있는 오셥도 제공합니다.

+ +

VP9는 광범위한 브라우저가 지원하고 있으며 하드웨어 구현체로 상당히 퍼져있습니다. VP9는 WebM에서만 사용할 수 있는 두 코덱 중 하나입니다(나머지 하나는 {{anch("VP8")}}). 하지만 Safari는 WebM 및 VP9 모두 지원하지 않으므로 VP9를 사용할 경우 iPhone, iPad, Mac에서 AVC나 HEVCS등 다른 포맷을 대체할 수 있도록 만들어야 합니다.

+ +

Safari 지원이 빠져있지만 WebM 컨테이너를 쓸 수 있고 Safari 사용자에게 AVC/HEVC 대체 포맷 제공이 가능하다면 VP9은 좋은 선택입니다. 상용 코덱 대신에 오픈 코덱을 쓰기로 결정했다면 더할 나위 없죠. 호환 포맷을 제공할 수 없지만 Safari 사용자도 잃을 수 없다면 WebM에 VP9는 차선책이 좋을 겁니다. 아니라면 다른 코덱을 고려해 보셔야겠죠.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
지원 비트레이트level 제한이 없는 한 무제한 임의의 값
지원 프레임 레이트임의 값
압축손실 DCT-기반 알고리즘
지원 프레임 크기최대 65,536 x 65,536 픽셀
지원 컬러 모드 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Profile색 깊이크로마 서브샘플링
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
+ +

지원 색 공간: {{interwiki("wikipedia", "Rec. 601")}}, {{interwiki("wikipedia", "Rec. 709")}}, {{interwiki("wikipedia", "Rec. 2020")}}, {{interwiki("wikipedia", "SMPTE C")}}, SMPTE-240M (obsolete; replaced by Rec. 709), {{interwiki("wikipedia", "sRGB")}}.

+
HDR 지원예; HDR10+, HLGPQ
가변 프레임 레이트 (VFR) 지원Yes
브라우저 호환성 + + + + + + + + + + + + + + + + + + + + + +
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
VP9 지원291428No10.6No
+
지원 컨테이너MP4, Ogg, WebM
{{Glossary("RTP")}} / WebRTC 호환
유지/보수 기관Google
스펙https://www.webmproject.org/vp9/
라이선스라이선스 및 로열티-프리 오픈 소스requirements
+ +

코덱 선택하기

+ +

어떤 코덱을 사용할지는 스스로 꼬리에 꼬리를 무는 질문을 던진 끝에 답을 얻을 수 있습니다.:

+ +
    +
  • 오픈 포맷을 사용할건가요? 상용 코덱도 염두에 두고 있나요?
  • +
  • 한 비디오를 여러 포맷으로 생산할 여력이 되나요? fallback 옵션을 제공할 수 있다면 의사 결정 과정을 단순화 할 수 있습니다.
  • +
  • 호환성을 포기할 수 있는 브라우저가 있나요?
  • +
  • 보장하는 커버리지 상 가장 오래된 브라우저는 어떤 것인가요? 예를 들어 지난 5년간 출시된 모든 브라우저를 지원할지, 1년 사이의 브라우저만을 지원할지?
  • +
+ +

아래 섹션에서는 특정 유즈케이스에서 추천할만한 코덱을 명시합니다. 각 유즈케이스마다 최대 두 개의 추천 코덱을 볼 수 있습니다. 특정 유즈케이스에 베스트인 코덱이 상용이거나 로열티 지불이 필요하다면 생각해 볼 두 가지 옵션이 있습니다: 로열티 프리 오픈 코덱을 선택하거나, 상용 라이선스를 따르거나.

+ +

각 비디오당 하나의 포맷만 제공할 수 있다면 필요한 요구사항을 최대한 만족하는 최적의 포맷을 선택해야 합니다. 첫 번째 추천 코덱은 품질과 퍼포먼스, 호환성을 최대한 고려한 것이며 두번째는 품질과 퀄리티, 크기를 조금 희생하더라도 최대한의 호환성을 가지는 옵션입니다.

+ +

Recommendations for everyday videos

+ +

우선 블로그나 정보형 사이트, 소규모 기업 웹사이트 등 상품을 설명하기 위한 비디오(비디오 자체가 상품은 아닌)를 위한 옵션을 알아봅시다.

+ +
    +
  1. +

    WebM 컨테이너에 비디오는 {{anch("VP8")}}, 오디오는 Opus 코덱을 사용합니다. 이들은 로열티-프리 오픈 포맷이지만 최근 브라우저에서만 폭넓게 지원하는 경향이 있어 폴백 지원이 필수적입니다.

    + +
    <video controls src="filename.webm"></video>
    +
    +
  2. +
  3. +

    MP4 컨테이너에 비디오 코덱은 {{anch("AVC")}} (H.264) 오디오 코덱은 AAC 를 사용합니다. MP4 컨테이너에 AVC, AAC 조합은 모든 주요 브라우저에서 폭넓게 지원하는 조합이며 대부분의 유즈케이스에서 좋은 품질을 보여주기 때문입니다. 하지만 라이선스 요구사항에 대해 컴플라이언스 이슈는 없는 지 확인이 필요하죠.

    + +
    <video controls>
    +  <source type="video/webm"
    +          src="filename.webm">
    +  <source type="video/mp4"
    +          src="filename.mp4">
    +</video>
    +
    +
  4. +
+ +
+

Note: {{HTMLElement("<video>")}} 엘리먼트는 자식으로 {{HTMLElement("source")}} 엘리먼트 유무에 상관 없이 </video> 닫기 태그가 필요하다는 것을 잊지 마세요.

+
+ +

고품질 비디오 제공을 위한 추천

+ +

여러분의 목표가 최대한 높은 품질의 비디오를 재생하는 것이라면 가능한한 다양한 포맷으로 제공할 수 있는 방법을 모색해야합니다. 최신의 코덱일수록 고품질 비디오를 지원하지만 반대로 브라우저 호환성은 떨어집니다.

+ +
    +
  1. +

    WebM 컨테이너에 비디오 코덱은 AV1, 오디오 코덱은 Opus. AV1 인코딩 시 6.3 High level 같은 높은 전문 프로파일을 사용할 수 있다면 훌륭한 품질의 비디오를 4K/8K 해상도로 제공할 수 있습니다. 오디오 인코딩 시 Opus Fullband 프로파일로 48 kHz 샘플링 레이트를 사용한다면 사람이 들을 수 있는 거의 모든 주파수를 캡쳐할 수 있죠.

    + +
    <video controls src="filename.webm"></video>
    +
    +
  2. +
  3. +

    MP4 컨테이너에 비디오 코덱으로 {{anch("HEVC")}} 를 쓰되 프로파일은 Main 4:2:2 10/12 bit 색 깊이, 최대 Main 4:4:4 16 bit 색 깊이 수준의 고급 Main 프로파일을 사용합니다. 비트레이트를 높이면 놀라운 색 재현과 훌륭한 그래픽 퀄리티를 보여줄 것입니다. 또한 하이 다이나믹 레인지 비디오를 위한 HDR 메타데이터도 추가할 수 있습니다. 오디오는 ACC 인코딩 시 높은 샘플링 레이트(최소 48 kHz, 96 kHz 권장)에 fast-encoding이 아닌 complex-encoding을 사용합니다.

    + +
    <video controls>
    +  <source type="video/webm"
    +          src="filename.webm">
    +  <source type="video/mp4"
    +          src="filename.mp4">
    +</video>
    +
    +
  4. +
+ +

비디오 보존, 편집, 믹싱을 위한 추천

+ +

웹 브라우저에서 사용 가능한 무손실-아니면 거의 무손실-비디오 코덱은 현재 없습니다. 이유는 간단한데:비디오는 거대합니다. 무손실 압축은 손실 압축에 비해 비효율적입니다. 예를 들어 4:2:0 크로마 서브샘플링의 무압축 1080p 비디오(1920*1080 픽셀)는 최소 비트레이트가 1.5Gbps가 넘죠. FFV1(브라우저 미지원) 같은 무손실 압축 코덱을 사용하면 콘텐츠에 따라 다르지만 600 Mbps 근처로 줄일 수 있습니다. 하지만 네트워크로 보내이겐 여전히 엄청난 크기이며 현실적으로 불가능한 사이즈입니다.

+ +

손실 코덱이 무손실 모드를 가지고 있다 하여도 별 반 다르지 않는데;현재 웹 브라우저에서 무손실 모드를 구현하고 있지 않기 때문입니다. 최선은 손실 압축을 사용하는 코덱 중 최대한 고품질 코덱을 선택한 뒤 최소한의 압축만 수행하도록 설정하는 것입니다. 한가지 방법은 코덱을 설정하기를 "fast" 압축을 선택하는 것입니다. 일반적으로 이는 압축을 최소화합니다.

+ +

외부에 비디오 보존

+ +

여러분의 웹 사이트나 앱 외부 영역에 보존 목적의 비디오라면 무압축 원본 비디오 데이터를 압축하는 유틸리티를 사용하세요. 예를들어 x264 유틸리티는 매우 높은 비트레이트로 {{anch("AVC")}} 인코딩을 할 수 있습니다:

+ +
x264 --crf 18 -preset ultrafast --output outfilename.mp4 infile
+ +

다른 코덱들도 충분한 여유가 있다면 더 나은 최고-품질 압축을 보여줄지도 모릅니다, 단지 그 인코더들은 엄청 느려서 위 압축으로 얻어지는 거의 무손실 비디오가 전체적으로 비슷한 품질을 보여주면서도 상당히 빠를겁니다.

+ +

비디오 녹화

+ +

무손실에 가까운 비디오를 보여줘야 한다는 제약이 있다면, {{anch("AVC")}} 또는 {{anch("AV1")}}를 고려해 볼 필요가 있습니다. 예를들어 비디오를 녹화하기 위해 MediaStream Recording API를 사용한다면, {{domxref("MediaRecorder")}} 객체를 생성하는 코드는 아래와 같습니다:

+ +
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);
+ +

위 예제에서 MediaRecorder를 생성하여 BT.2100 HDR, 12-bit color 4:4:4 크로마 서브샘플링 설정으로 {{anch("AV1")}} 비디오 레코딩을, FLAC으로 무손실 오디오를 레코딩 하고 있습니다. 결과물 파일은 비디오 오디오 트랙 합쳐 800Mbps를 넘지 않을 겁니다. 하드웨어 성능이나 요구사항, 사용하고자 하는 코덱에 따라 설정 값을 변경할 수 있습니다. 위의 비트 레이트 값은 네트워크 실사용 케이스에선 비현실적인 값이며 로컬 장치에서만 가능하겠죠.

+ +

codecs 파라미터 값을 '.' 기준으로 나눠서 의미를 분석해 봅시다:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
설명
av014문자 코드 (4CC-4 Character Code) {{anch("AV1")}} 코덱을 의미합니다.
2프로파일. 2는 Professional profile. 1은 High profile, 0은 Main profile.
19H레벨과 티어. AV 스펙의 A.3의 표에서 설명, Level 6.3의 High tier를 의미합니다
12색 깊이. 컴포넌트당 12bit를 의미. 8, 10도 가능하나 AV1에서 표현할 수 있는 가장 정확한 색 깊이 값이 12입니다.
0모노크롬 모드 플래그. 1로 지정하면 색차 성분은 녹화되지 않으며 휘도 성분만 축적되어 그레이스케일 이미ㅣ지로 표현됩니다. 색상을 사용할 것이므로 0으로 지정하였습니다.
000크로마 서브샘플링 모드. AV1 스펙의 section 6.4.2에 설명. 모노크롬 모드 값이 0일 때 000 값은 4:4:4 크로마 서브샘플링 또는 색상 손실이 없어야 함을 나태냅니다.
09사용할 색 공간. AV1 스펙의 section 6.4.2에서 설명 9는 HDR을 위한 BT.2020 색역을 의미합니다.
16전송시 사용할 색 공간. 마찬가지로 section 6.4.2에서 설명; 16은 BT.2100 PQ 컬러로 전송하겠다는 의미입니다.
09section 6.4.2 에서 설명하는 계수 행렬. 9 값은 유동 휘도 값의 BT.2020 색역을 사용하겠다는 의미입니다. BT.2010 YbCbCr와 동일한 의미입니다.
1"full range" 비디오 플래그. 1은 전체 컬러 영역을 녹화하겠다는 의미입니다.
+ +

선택하고자 하는 코덱 문서에 codecs 파라미터 값이 받아들이는 설정이 설명되어 있습니다.

+ +

더 보기

+ + diff --git "a/files/ko/web/media/formats/\353\271\204\353\224\224\354\230\244\354\275\224\353\215\261/index.html" "b/files/ko/web/media/formats/\353\271\204\353\224\224\354\230\244\354\275\224\353\215\261/index.html" deleted file mode 100644 index 5cccc89329..0000000000 --- "a/files/ko/web/media/formats/\353\271\204\353\224\224\354\230\244\354\275\224\353\215\261/index.html" +++ /dev/null @@ -1,1646 +0,0 @@ ---- -title: 웹 비디오 코덱 가이드 -slug: Web/Media/Formats/비디오코덱 -translation_of: Web/Media/Formats/Video_codecs ---- -

압축되지 않은 비디오 데이터는 그 크기가 엄청나기 때문에, 저장하거나 네트워크를 통해 전송하기 위해서는 아주 작게 압축해야 합니다. 압축되지 않은 비디오를 저장하는 과정을 상상해 봅시다:

- -
    -
  • HD(1920x1080) 풀 컬러(픽셀 당 4바이트) 비디오의 한 프레임은 8,294,400 입니다.
  • -
  • 보통 초당 30프레임이므로 HD 비디오 1초는 248,832,000바이트 (~249 MB)를 잡아 먹습니다.
  • -
  • HD 1분은 1.39 GB가 필요합니다.
  • -
  • 일반적인 30분짜리 비디오 컨퍼런스의 경우 47.1 GB가 필요하며, 2시간짜리 영화는 무려 166 GB입니다.
  • -
- -

비압축된 비디오 데이터는 스토리지 공간이 많이 필요할 뿐만 아니라 네트워크로 전송할 경우에도 어마어마한 대역폭이 필요합니다. 오디오와 오버헤드를 제외하고도 초당 249 MB가 필요하죠. 여기서 비디오 코덱이 등장합니다. 오디오 코덱이 사운드 데이터를 처리하듯이 비디오 코덱도 비디오 데이터를 압축하고 적절한 포맷으로 인코딩하여, 이후에 디코딩하여 재생 또는 편집할 수 있도록 합니다.

- -

대부분의 비디오 코덱은 손실 압축입니다. 디코딩해도 원본과 완전히 동일하지 않죠. 디테일한 부분이 사라질 수 있는데; 얼마나 사라지는지는 코덱와 설정에 달렸습니다만 압축율을 높일수록 디테일과 정확도는 감소합니다. 무손실 코덱도 있긴 합니다만, 보통 기록 보존 및 로컬 재생에만 염두에 두고 있는 경우가 많습니다.

- -

이 문서는 웹에서 흔히 볼 수 있는 비디오 코덱을 소개하고 각각의 기능과 호환성, 사용성에 대해 설명하고 여러분에게 필요한 적절한 코덱을 찾는 법을 안내합니다.

- -

일반 코덱

- -

웹에서 널리 쓰이는 비디오 코덱은 아래와 같습니다. 각 코덱마다 해당 코덱을 지원하는 컨테이너(파일 타입)도 나열되어 있습니다. 각 코덱의 링크를 클릭하면 해당 코덱에 대해 세부정보, 기능, 호환성 등 필요한 내용이 추가된 하단 섹션으로 이동합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
코덱 이름 (축약어)전체 코덱 이름지원하는 컨테이너
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
- -

인코딩 관여 요소

- -

어떤 인코더를 사용하든지간에 인코딩된 비디오의 크기와 퀄리티를 결정하는 두 개의 기본적인 요소 그룹이 있습니다: 하나는 소스 비디오의 포맷와 콘텐츠이며 나머지는 인코딩 시 코덱의 특징 및 설정입니다.

- -

요약하자면 이겁니다:인코딩 된 비디오가 원본에 가까울수록, 압축율은 적고 비디오 파일 크기는 커집니다. 그러므로 사이즈와 퀄리티는 항상 트레이드 오프가 있습니다. 특별한 경우에는 퀄리티 손실을 크게 감수하고서라도 사이즈를  많이 줄여야 할 필요가 있을 수도 있으며;반대로 고용량의 파일을 생성하더라도 퀄리티를 최대한 유지해야 하는 경우도 있습니다.

- -

인코딩 된 비디오에 영향을 끼치는 소스 포맷

- -

소스 비디오의 형식이 출력에 영향을 미치는 정도는 코덱과 작동 방식에 따라 다릅니다. 코덱이 미디어를 내장 픽셀 포맷으로 변환하거나 심플 픽셀 이외의 방식으로 이미지를 표현하는 경우에는 원본 포맷에 따른 차이는 거의 없습니다. 하지만 프레임 레이트나 해상도는 반드시 출력 미디어 크기에 영향을 미치게 되죠.

- -

또한 모든 코덱은 각각 장단점이 있습니다. 어떤 코덱은 특정한 형태와 패턴에 약하거나 엣지 선명도가 약하거나, 암부의 디테일이 떨어지거나 등의 여러가지 문제가 있을 수 있죠. 모든 건 기저의 알고리즘과 수학 공식에 달렸습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
인코딩 된 비디오의 품질과 크기에 영향을 줄 수 있는 비디오 포맷과 콘텐츠
기능품질에 영향크기에 영향
Color depth (bit depth)색 깊이가 높을수록 비디오의 색상 정확도가 높아집니다. Additionally, 이미지의 강렬한 부분 (빛이나 순수한 빨강  [rgba(255, 0, 0, 1)] 등 매우 원색적인 색상), 컴포넌트당 10bit (10-bit color) 이하의 색 깊이에서는 그라데이션 부분이 마치 계단처럼 색상이 분리되는 현상인 컬러 밴딩이 발생할 수 밖에 없습니다.코덱에 따라 다르지만 색 깊이가 높을 수록 압축된 파일 사이즈가 커지게 됩니다. 압축 데이터의 내장 스토리지 포맷에 따라 결정됩니다.
프레임 레이트이미지 상에 보여지는 움직임이 얼마나 부드러운지에 크게 영향을 끼칩니다. 프레임 레이트가 높을 수록 움직임이 더 부드럽고 현실에 가까워 집니다. 계속 높이다보면 압축의 의미가 없어지는 지점에 도달하게 되죠. 아래의 {{anch("Frame rate")}} 절을 참조하세요.인코딩 도중 프레임 레이트를 감소시키지 않는 다면 높을 수록 압축된 결과물이 커집니다.
움직임(Motion)비디오 압축은 일반적으로 프레임을 비교하면서 수행합니다. 두 프레임이 어디가 다른지 찾아낸 후 이전 프레임에서 다음 프레임을 예측하기 위핸 최소한의 정보만을 기록하는 방식입니다. 연속된 프레임이 다른 것들과 다를 수록 차이점도 많아지고 the less effective the compression is at avoiding the introduction of artifacts into the compressed video.움직임이 복잡할 수록 프레임간의 차이점이 많아 지므로 인터프레임이 커지게 됩니다. 이를 비롯한 여러가지 이유로 인해 일반적으로 움직임이 많은 영상일수록 사이즈가 큽니다.
잡음(Noise)픽쳐 노이즈(필름 그레인 효과, 먼지 등 이미지의 불규칙한 점들)는 픽셀간 변화폭을 늘립니다. 증가된 변화폭은 압축을 어렵게 하고 동일한 압축 레벨일 때 디테일을 떨어뜨리는 원흉이 되죠.이미지에 -노이즈 같이- 변화폭이 큰 부분이 많을수록 압축 알고리즘이 비슷한 수준으로 이미지를 압축하기 어렵습니다. 노이즈로 인한 변화폭을 무시하도록 인코더를 세팅하지 않는 한 노이즈가 많을 수록 압축된 비디오 파일 크기도 커질겁니다.
해상도(width, height)압축하는 과정에 특이사항이 발생하지 않는 한 동일한 크기의 스크린에 더 높은 해상도의 비디오가 출력될 수록 원본에 가까운 영상을 볼 수 있습니다.해상도가 높을수록 비디오 크기도 커집니다. 최종 사이즈에 결정적인 요소죠.
- -

위 요소들이 인코딩 된 비디오에 미치는 정도는 선택한 인코더와 설정 등 정확한 상황에 따라 굉장히 다양합니다. 인코딩 중에 코덱의 일반 옵션에 더해서 프레임 레이트를 줄이거나 노이즈 제거, 비디오 해상도를 줄이는 등 인코더 설정을 추가할 수 있습니다.

- -

인코딩 결과물에 영향을 끼치는 코덱 설정

- -

비디오 인코딩에 쓰이는 알고리즘은 보통 여러가지의 기술들로 구성되어 있습니다. 일반적으로 최종 결과물의 크기를 줄이기 위한 설정 옵션은 비디오 퀄리티 하락이나 특정 이슈를 발생시킵니다. 최종 결과물이 매우 커지지만 오리지널 소스를 완벽하게 재생하기 위해 무손실 인코딩을 택할 수도 있습니다.

- -

또한 각 인코더는 결과물의 품질과 크기에 영향을 끼치는 다양한 바리에이션을 가지고 있기도 합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
품질과 크기에 영향을 미치는 비디오 인코더 설정
기능품질에 영향크기에 영향
무손실 압축품질 손실 없음손실 압축에 비해 무손실 압축은 전체 비디오 크기를 많이 줄일 수 없습니다; 결과물 파일은 일반적으로 사용하기엔 여전히 매우 거대합니다.
-

손실 압축

-
특정 코덱과 압축을 어떻게 하느냐에 따라 퀄리티 저하에 영향을 끼치는 인자나 기타 요소가 어느 정도 발생하게 됩니다.원본 비디오와 많이 달라져도 된다면 높은 압축률을 달성하는 것은 어렵지 않습니다.
품질 세팅품질 설정을 높게 세팅할수록 인코딩 된 비디오도 원본에 가깝게 보일겁니다.보통은 높은 품질로 설정할 수록 인코딩 된 비디오 파일도 커집니다;그 정도는 코덱에 따라 다르겠지만요.
비트레이트품질을 높이면 보통 비트레이트도 높아집니다.비트레이트가 높으면 결과물 파일도 커지죠.
- -

인코딩 시 설정 가능한 항목과 값은 코덱마다 다를 뿐만 아니라 사용하는 인코더 소프트웨어에 따라서도 다양합니다. 여러분이 사용하는 인코더 소프트웨어의 가이드 문서에 인코딩 시 영향을 끼치는 옵션에 대해 설명하고 있을겁니다.

- -

압축 아티팩트

- -

아티팩트는 는 손실 압축에서 발생할 수 있는 부작용으로 시각적인 데이터의 손실 또는 변경입니다. 비디오 출력 방식 때문에 아티팩트가 한 번 발생하면 생각보다 오래 남습니다. 비디오의 각 프레임은 현재 보여지는 프레임에서 변경된 부분만 적용하는 방식으로 표현됩니다. 이 말은 즉 에러나 아티팩트는 시간이 지날수록 복잡해지고 이미지상의 결함이나 이상한 점, 깨진 부분 등이 한동안 지속된다는 걸 의미하죠.

- -

이 문제도 해결하고 또 비디오 데이터의 탐색 시간을 개선하기 위해 주기적으로 키 프레임(인트라-프레임 또는 i-프레임)을 비디오 파일에 삽입합니다. 키 프레임은 통짜 프레임으로 현재 보이는 이미지 손상이나 아티팩트를 수정하기 위해 존재합니다.

- -

위신호(Aliasing)

- -

위신호는 인코딩 된 데이터가 압축하기 전과 다르게 보이는 현상 전반에 대한 일반 용어입니다. 여러가지 종류의 위신호가 있으며;흔히 보이는 것들은 아래와 같습니다:

- - - - - - - - - - - - - - - - -
-

모아레 현상(Moiré patterns)

- -

{{interwiki("모아레 현상-Moiré pattern")}}는 소스 이미지의 패턴과 인코더의 동작 방식이 공간적으로 약간 정렬되어 있지 않을 때 발생하는 대규모 공간 간섭 패턴입니다. 인코딩 시 발생한 아티팩트를 디코딩 하면 소스 이미지에 이상한 회오리 무늬가 생깁니다.

-
-

계단 현상

- -

계단 현상은 공간적 아티팩트의 하나로 부드러워야 할 대각선이나 곡선 경계면이 마치 계단처럼 들쭉날쭉하게 보이는 현상을 의미합니다. "안티-앨리어싱"필터를 사용하면 줄일 수 있습니다.

-
-

마차 바퀴 현상

- -

마차 바퀴 현상 (또는 {{interwiki("wikipedia", "스트로보 효과")}})은 필름에서 흔히 볼 수 있는 시각적 효과로 프레임 레이트와 압축 알고리즘에 의해 회전하는 바퀴가 느리거나 빠르게 혹은 아예 반대 방향으로 보이는 것을 의미합니다. 이는 철도 노선의 침목이나 도로변의 기둥 등 일정한 패턴으로 움직이는 것이라면 어디서든 볼 수 있습니다. 이는 시간적 위신호 이슈로;압축 또는 인코딩 시 샘플링 레이트가 회선 속도에 간섭하여 발생합니다.

-
- -

컬러 엣징(Color edging)

- -

컬러 엣징은 시각적 아티팩트 중 하나로 화면상의 색상을 가진 오브젝트들의 경계면에 잘못된 색상이 나타나는 현상입니다. 나타나는 색상은 프레임의 콘텐츠간에 아무 연관도 없습니다.

- -

선명도 손실

- -

비디오 인코딩 중 일부 데이터를 제거하면 필연적으로 디테일 손실이 발생합니다. 충분히 압축하고 나면 일부 또는 전체 이미지에 약간 불분명하거나 흐릿한 부분이 보일 수 있습니다.

- -

선명도가 떨어지면 이미지 상의 글자를 읽기 어렵습니다. 특히나 작은 글씨들은 디테일에 민감한 콘텐츠로 작은 변화로도 매우 읽기 어려워집니다.

- -

링잉 효과(Ringing)

- -

손실 압축 알고리즘은 링잉 효과 {{interwiki("wikipedia", "ringing artifacts", "ringing")}}를 일으킬 수 있습니다. 링잉 효과는 압축 알고리즘에 의해 오브젝트의 경계면에 픽셀이 오염되는 현상을 의미합니다. 압축 알고리즘이 오브젝트와 배경의 경계면이 포함된 블럭을 사용했을 때 발생할 수 있습니다. 보통 압축율이 높을 때 주로 발생합니다.

- -

Example of the ringing effect

- -

위 별 모양의 경계 부분에 파랑 및 분홍 부분을 보세요 (계단 현상 등 다른 압축 아티팩트도 나타남). 저 부분이 링잉 효과입니다. 링잉은 어떤 면에서는 {{anch("Mosquito noise", "mosquito noise")}}와 비슷합니다, 다만 모기 효과는 일렁거리거나 움직이는데 반해 링잉 효과는 정지한 채로 변하지 않습니다.

- -

링잉 효과 역시 이미지 상의 글자를 읽기 어렵게 하는 아티팩트입니다.

- -

포스터라이징(Posterizing)

- -

포스터리제이션은 압축된 결과물이 그라디언트 부분에서 색상 디테일을 잃는 현상을 의미합니다. 그라디언트 영역이 부드럽게 색상이 변하지 않고 원본과 비슷한 색상의 블록 형태로 얼룩이 묻은 듯한 이미지로 표현 됩니다.

- -

- -

위 이미지상 흰머리 수리의  깃털 부분의 색상이 블록처럼 보이는 것을 보세요(배경의 흰색 올빼미도요). 포스터리제이션 효과로 인해 깃털의 디테일을 상당 부분 잃었습니다.

- -

컨투어링(Contouring)

- -

컨투어링 또는 컬러 밴딩은 포스터리제이션의 특별한 형태로 이미지에서 색상 블록이 줄무늬 형태로 나타나는 현상을 의미합니다. 이는 비디오 인코딩 시 양자화 설정이 제대로 이뤄지지 않은 경우 발생할 수 있습니다.  결과적으로 부드럽게 변해야 할 그라디언트 부분에 "층"이 생긴 것처럼 줄무늬가 보입니다.

- -

Example of an image whose compression has introduced contouring

- -

위 이미지를 보시면 하늘에서 지평선으로 부드럽게 변해야 하는데 파란색이 층층이 져 있는 것을 볼 수 있습니다. 이 것이 컨투어링 효과입니다.

- -

모스키토 노이즈(Mosquito noise)

- -

모스키토 노이즈는 시간적 아티팩트 중 하나로 배경과 물체의 경계면의 차이가 큰 부분에서 노이즈나 edge busyness가 흐릿하게 일렁거리는 현상을 의미합니다. 시각적으로는  {{anch("Ringing", "ringing")}} 효과와 유사합니다.

- -

- -

위 이미지상 다리 여러군데의 주변 하늘에서 모스키토 노이즈를 볼 수 있습니다. 우측 상단에 모스키토 노이즈가 발생한 부분을 확대해 놓았습니다.

- -

모스키토 노이즈는 MPEG 비디오에서 흔히 발견할 수 있지만 이산 코사인 변환(DCT)를 사용한 로직이라면 어디든지 발생할 수 있습니다;JPEG 정지 화상에서도요.

- -

움직임 보상 블록 경계면 아티팩트

- -

일반적인 비디오 압축은 두 프레임을 비교한 뒤 프레임간 차이점을 마지막 프레임까지 저장하는 방식으로 진행됩니다. 고정된 카메라에 촬영되는 물체들도 정지해 있다면 이 압축 방식은 매우 잘 동작하겠지만 프레임마다 움직임이 커지면 압축률을 높이기가 쉽지 않습니다.

- -

{{interwiki("wikipedia", "움직임 보상")}}은 물체가 각각의 방향으로 얼마만큼 많은 픽셀이 이동했는지 움직임(카메라 자체의 이동 또는 프레임 상의 물체의 이동)을 추적하는 기술입니다.  그리고 단순 움직임 만으로는 설명할 수 없는 픽셀의 추가 정보와 함께 움직임을 저장합니다. 요약하자면 인코더가 움직이는 물체를 찾아낸 후 원본과 동일해 보이지만 새로운 위치로 이동한 인터널 프레임을 생성하는 방식입니다. 이론적으로는 새로운 프레임이 나타난 것과 거의 동일합니다. 새 프레임에 남아있는 다른 차이점이 발견된다면 물체의 움직임과 픽셀 차이점을 저장하여 작업을 마무리 합니다. 이렇게 움직임과 픽셀 차이점이 기록된 물체를 residual frame이라 부릅니다.

- - - - - - - - - - - - - - - - - - - - - - - - -
원본 프레임인터-프레임 차이점움직임 보상 이후 차이점
Original frame of videoDifferences between the frames after shifting two pixels right
시청자에게 보이는 최초 전체 프레임이건 첫번째 프레임과 두번째 프레임간의 차이점만 나타낸 화면입니다. 나머지는 모두 검정이죠. 가까이서 보면 이 움직임들은 단지 카메라가 수평으로 이동했기 때문에 발생한 것을 알 수 있습니다. 움직임 보상을 써먹기에 아주 좋은 후보죠.차이점을 가지는 픽셀 수를 최소화 하기 위해 첫번째 프레임에서 카메라가 오른쪽으로 2픽셀 이동하였다고 가정한 뒤 픽셀 차이점을 계산합니다. 이는 카메라의 움직임을 추적하여 두 프레임간 겹치는 부분이 더 많아지게 합니다.
Images from Wikipedia
- -

움직임 보상에는 두 가지 형태가 있습니다: 전역 움직임 보상 과 블록 움직임 보상입니다. 전역 움직임 보상은 달리, 트래킹, 선회, 기울이기 및 회전 등의 카메라 변화를 감지합니다. 블록 움직임 보상은 추적 대상이 될만한 움직임의 작은 부분들을 찾아 처리합니다. 블록들은 보통 고정된 크기를 가지고 격자 형태로 배열되어 있지만 다양한 크기의 블록 및 블록이 겹치는 경우도 처리할 수 있도록 여러 형태의 움직임 보상을 지원합니다.

- -

하지만 움직임 보상에서도 아티팩트가 발생할 수 있습니다. 링잉 효과 등의 현상이 발생할 만큼 선명한 경계면에서 주로 발생합니다. 이는 residual frame을 코딩하는 도중 수학 계산의 결과물로 인해 발생하는 것으로 다음 키프레임에 의해 수정되기 전에 쉽게 발견할 수 있습니다.

- -

프레임 크기 감소

- -

특정 상황에서는 비디오 면적을 감소시키는 것이 비디오 파일 최종 사이즈를 줄이는데 도움이 되기도 합니다. 재생 도중 당장의 크기나 부드러움이 줄어드는 건 안 좋은 게 사실이지만 세심하게 조절하면 최종 결과물은 더 좋아질 수 있습니다. 1080p 비디오를 인코딩 전 720p 비디오로 축소한다면 화질을 더 높게 유지한 채로 크기를 훨씬 줄일 수 있습니다; 재생 할 때 스케일업 하더라도 필요한 파일 크기에 맞추어 품질을 조정한 채 전체 크기로 인코딩한 경우보다 화질이 좋습니다.

- -

프레임 레이트 감소

- -

비슷하게 전체 비디오에서 프레임을 제거하고 프레임 레이트를 감소시킬 수도 있습니다. 두 가지 장점이 있는데: 전체 비디오를 작게 만들고 움직임 보상 처리가 더 쉬워집니다. 예를 들어 2 픽셀이 차이나는 두 인터 프레임 간의 움직임 차이점을 계산하는 대신에, 프레임을 스킵하여 두 프레임 간 4 픽셀 차이점을 계산하도록 할 수 있습니다. 이러면 전체 카메라 이동을 더 적은 residual frame으로 표현할 수 있습니다.

- -

사람 눈의 움직이는 것처럼 인식되는 최소한의 프레임 레이트는 약 12입니다. 그보다 적으면 비디오가 아니라 연속된 정지 화상으로 보입니다. 영화 필름은 보통 초당 24 프레임이며 표준 화질 TV(SDTV)는 대략 30 fps(약간 적지만 비슷합니다, 29.97), 고화질 TV(HDTV)는 24-60fps입니다. 24fps이상이면 일반적으로 충분히 부드러워 보입니다;여러분의 필요에 따라 다르지만 30/60fps가 이상적인 목표치죠.

- -

결론적으로 어떤걸 희생할 지 정하는 것은 여러분의 디자인 팀에 달렸습니다.

- -

코덱 세부사항

- -

AV1

- -

AOMedia Video 1 (AV1) 코덱은 Alliance for Open Media 기관이 인터넷 비디오를 위해 개발한 오픈 포맷입니다. {{anch("VP9")}}, {{anch("HEVC", "H.265/HEVC")}} 보다 압축율이 높으며, AVC보다 50% 이상 압축율이 높습니다. AV1은 완전한 로열티 프리이며 {{HTMLElement("video")}} 엘리먼트와 WebRTC에서 사용하기 위해 설계하였습니다.

- -

AV1은 현재 세 프로파일을 제공하며:main, high, professional 다양한 색 깊이와 크로마 서브샘플링을 지원합니다. 또한 레벨 역시 정의하여 각 레벨은 비디오 속성의 범위를 제한하고 있습니다. 비디오 속성에는 프레임 면적, 픽셀간 이미지 영역, 출력 및 디코딩 속도, 평균/최대 비트 레이트, 인코딩/디코딩 시 사용하는 타일 개수와 항목 등이 있습니다.

- -

예를들어 AV1 level 2.0의 최대 프레임 크기는 가로 2048 세로 1152 픽셀이지만 프레임 당 최대 픽셀 개수는 147,456(<= 2048x1152 = 2,359,296)이므로 실제 2048x1152 크기의 프레임을 사용할 수는 없습니다. 하지만 인지해야 할 점은 적어도 파이어폭스와 크롬의 소프트웨어 디코더는 현 시점에서 사실상 레벨은 무시하고 주어진 설정에 맞추어 비디오를 디코딩하는데 최선을 다합니다. 하지만 향후 호한성을 위해 여러분은 선택한 레벨에 맞추어 유지해야 합니다.

- -

현시점의 AV1의 주요 문제점은 새로운 포맷이며 브라우저에 연동이 아직 진행중에 있다는 것입니다. 또한 인/디코더도 최적화해야 하며 하드웨어 인/디코더는 제품화되지 않아 아직 개발중입니다. 이러한 문제점들이 소프트웨어적으로 해결되기 전까지는 비디오 인코딩을 AV1 포맷으로 전환하는데 시간이 소요될 것입니다.

- -

위와 같은 이유로 당분간 최우선 비디오 코덱으로 AV1를 사용하기에는 이르지만 미래에는 반드시 선택을 고려해야 합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트비디오 레벨에 따라 다름;이론적으로 level 6.3에서 최대 800Mbps[2]
지원 프레임 레이트레벨에 따라 다름;예를 들어 level 2.0은 최대 30fps, level 6.3은 최대 120fps
압축손실 DCT 기반 알고리즘
지원 프레임 크기8 x 8 픽셀 에서 65,535 x 65535 픽셀 사이 값
지원 컬러 모드 - - - - - - - - - - - - - - - - - - - - - - - - - -
프로필색 깊이크로마 서브샘플링
Main8 or 104:0:0 (그레이스케일) or 4:2:0
High8 or 104:0:0 (그레이스케일), 4:2:0, or 4:4:4
Professional8, 10, or 124:0:0 (그레이스케일), 4:2:0, 4:2:2, or 4:4:4
-
HDR 지원
가변 프레임 레이트 (VFR) 지원
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
AV1 지원707567No57No
-
지원 컨테이너ISOBMFF[1], MPEG-TS, MP4, WebM
{{Glossary("RTP")}} / WebRTC 호환성
유지 보수 기관Alliance for Open Media
스펙https://aomediacodec.github.io/av1-spec/av1-spec.pdf
라이선스로열티 프리, 공개 포맷
- -

[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)

- -

MPEG-4 스펙 집합 중 Advanced Video Coding (AVC) 표준은 ITU H.264 스펙 및 MPEG-4 Part 10 스펙과 동일한 것입니다. TV 방송, 영상회의, 블루레이 디스크 미디어를 포함한 모든 종류의 미디어에 사용되는 움직임 보상에 기반한 코덱이죠.

- -

AVC는 높은 호환성을 지원하는 여러 프로파일 덕분에 매우 유연합니다; 예를들어 Constrained Baseline Profile은 영상회의와 모바일 환경을 고려하였고 MainProfile(몇몇 지역에서 SDTV로 사용)나 High Profile(블루레이 디스크에서 사용)보다 대역폭을 적게 사용합니다. 대부분의 프로파일은 8-bit 컬러 컴포넌트와 4:2:0 크로마 서브샘플링을 사용합니다; High 10 Profile은 10-bit 컬러를 지원하며 High 10 Advanced form은 4:2:2, 4:4:4 크로마 서브샘플링을 지원합니다.

- -

AVC에 동일한 장면의 여러 시점을 지원하는 기능도 있습니다.(Multiview Video Coding), 이는 양안 영상 등을 가능하게끔 합니다.

- -

AVC는 유료 포맷이지만 무수한 특허들이 개입한 여러 단체에 소유권이 나뉘어져있습니다. 상용 목적일때는 AVC 미디어 라이선스가 필요하지만 인터넷 환경에서 최종 사용자에게 비디오가 무료로 스트리밍하는 경우에는 MPEG LA 특허권자가 라이선스를 요구하지 않습니다.

- -

웹이 아닌 환경에서 WebRTC를 구현한 브라우저(JavaScript API가 없는 제품이라도)는 WebRTC 콜을 위해 AVC를 지원해야합니다. 웹 브라우저는 꼭 그럴필요는 없지만 몇몇은 지원하고 있습니다.

- -

많은 플랫폼이 웹브라우저의 HTML 콘텐츠 형태로 AVC의 하드웨어 인코딩/디코딩을 지원하고 있습니다. 하지만 AVC를 프로젝트에서 사용하기 전에 라이선스 요구사항을 꼭 읽어보세요!

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트레벨에 따라 다름
지원 프레임레이트레벨에 따라 다름; 300 fps까지 가능
압축손실 DCT 기반 알고리즘, 이미지안에 무손실 매크로 블록 생성 가능
지원 프레임 크기최대 8,192 x 4,320 픽셀
지원 컬러 모드 -

일반적이고 유효한 프로필:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
프로필색 깊이크로마 서브샘플링
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 (그레이스케일) and 4:2:0
Progressive High (ProHiP)84:0:0 (그레이스케일) and 4:2:0
High 10 (Hi10P)8 to 104:0:0 (그레이스케일) and 4:2:0
High 4:2:2 (Hi422P)8 to 104:0:0 (그레이스케일), 4:2:0, and 4:2:2
High 4:4:4 Predictive8 to 144:0:0 (그레이스케일), 4:2:0, 4:2:2, and 4:4:4
-
HDR 지원예; {{interwiki("wikipedia", "Hybrid Log-Gamma")}} 또는 Advanced HDR/SL-HDR; 모두  ATSC의 파트
가변 프레임 레이트 (VFR) 지원
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
AVC/H.265 지원41235[1]9253.2
-
지원 컨테이너3GP, MP4, WebM
{{Glossary("RTP")}} / WebRTC 호환
유지 보수 기관MPEG / ITU
스펙https://mpeg.chiariglione.org/standards/mpeg-4/advanced-video-coding
- https://www.itu.int/rec/T-REC-H.264
라이선스상용 특허 다수. 상용 사용 시 라이선스 필요. 여러 특허 풀에 영향 가능
- -

[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의 H.263 코덱은 저대역폭 환경에서 쓰기 위해 설계하였습니다. 특히 PSTN (Public Switched Telephone Networks), {{Glossary("RTSP")}}, SIP (IP-based videoconferencing) 시스템에서의 영상 회의에 초점을 맞추었습니다. 저대역폭 네트워크 환경에 최적화되었음에도 CPU에 영향이 크며 저사양 컴퓨터에서 원할하게 동작하지 않습니다. 데이터 포맷은 MPEG-4 Part2와 유사합니다.

- -

H.263은 웹에서 널리 쓰인 적이 없습니다. H.263의 변형 포맷이 Flash 비디오나 Sorenson 코덱 같은 상용 소프트웨어에서 사용된 적은 있습니다.  하지만 주요 브라우저 중 H.263를 기본으로 지원하는 제품은 없습니다. 특정 플러그인이 H.263을 지원하고는 있습니다.

- -

대부분의 코덱과 다르게 H.263은 인코딩 된 비디오의 프레임별 최대 비트레이트(BPPmaxKb)의 기본값을 정의하고 있습니다. 인코딩시에 BPPmaxKb값을 지정하면 각 프레임은 해당 수치를 넘어설 수 없습니다. 최종 프레임은 이 값과 프레임 레이트, 압축, 선택한 해상도와 블록 포맷에 따라 결정됩니다.

- -

H.263은 H.264로 대체되었으며 가능한한 이전의 미디어 포맷은 사용하지 않아야 합니다. H.263이 최선일 정도로 오래된 장치를 지원해야 하는 프로젝트일 경우에만 H.263을 지원할테죠.

- -

H.263는 Telenor, Fujitsu, Motorola, Samsung, Hitachi, Polycom, Qualcomm 등 수 많은 기관들이 소유하고 있는 특허에 기반한 상용 포맷입니다. H.263을 사용하려면 필요한 라이선스를 반드시 취득해야합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트무제한, 단 보통 64kbps 미만
지원 프레임 레이트자유
압축손실 DCT 기반 알고리즘
지원 프레임 크기최대 1408 x 1152 픽셀[2]
지원 컬러 모드YCbCr; 각 픽쳐 포맷 (sub-QCIF, QCIF, CIF, 4CIF, or 16CIF)은 프레임 크기를 픽셀 및 휘도와 색차 샘플의 라인수로 정의하고 있음
HDR 지원아니오
가변 비트레이트 (VFR) 지원아니오
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
H.263 supportNoNoNo[1]NoNoNo
-
컨테이너 지원3GP, MP4, QuickTime
{{Glossary("RTP")}} / WebRTC 호환아니오
유지 보수 기관ITU
스펙https://www.itu.int/rec/T-REC-H.263/
라이선스상용;적절한 라이선스가 필요함. 특허 풀이 여러 곳일 수 있음.
- -

[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)

- -

High Efficiency Video Coding (HVEC) 코덱은 ITU의 H.265 및 MPEG-H Part 2 (MPEG-4 후속 작업으로 개발 진행 중). HEVC는 현대 프로세서의 특정점을 십분 활용하여 소프트웨어가 (8K 비디오를 포함한) 초고해상도 비디오 인코딩/디코딩을 효율적으로 할 수 있도록 설계하였습니다. 이론적으로 HEVC는 {{anch("AVC")}}와 유사한 품질을 유지하면서 절반 크기로 압축할 수 있습니다.

- -

예를들어 각 코딩 트리 유닛(CTU, 이전 세대 코덱의 매크로블록과 유사) 샘플의 휘도 값 트리와 색차 값 트리, 필요한 문법 요소로 구성되어 있습니다. 이는 멀티 코어 환경을 쉽게 활용할 수 있게 합니다.

- -

메인 프로파일이 컴포넌트당 8비트 컬러와 4:2:0 크로마 서브샘플링을 지원하는 점은 흥미로운 부분입니다. 또한 4:4:4 비디오는 특별 취급합니다. 휘도 샘플(이미지 픽셀을 그레이스케일로 표현)과 Cb Cr 샘플(회색을 색상으로 어떻게 변경할지 표시)을 가지는 대신, 세 채널은 3개의 모노크롬 이미지로 취급하며 렌더링시에 풀컬러 이미지를 만들어 내도록 결합합니다.

- -

HEVC는 상용 포맷이며 여러 특허로 보호받고 있습니다. MPEG LA하에 라이선스가 관리되고 있으며; 컨텐츠 제작자나 제공자가 아닌 개발자에 청구됩니다. 여러분의 앱/웹사이트에서 HEVC 사용 여부를 결정하기 전에 최신 라이선스와 요구 사항을 점검하는 걸 잊지마세요!

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트최대 800,000 Kbps
지원 프레임 레이트레벨마다 다름; 최대 300 FPS 가능
압축손실 DCT 기반 알고리즘
지원 프레임 크기128 x 96 에서 8,192 x 4,320 픽셀; 프로파일과 레벨마다 다름
지원 컬러 모드 -

아래 표는 주요 프로파일에 한해서입니다. 여기에 포함하지 않는 프로파일도 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
프로파일색 깊이크로마 서브샘플링
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 지원
가변 프레임 레이트 (VFR) 지원
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
HEVC / H.265 supportNo18[1]No[2]11[1]No11
-
지원 컨테이너MP4
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관ITU / MPEG
스펙http://www.itu.int/rec/T-REC-H.265
- https://www.iso.org/standard/69668.html
라이선스상용;라이선스 요구사항에서 컴플라이언스 확인 다수의 특허 풀이 적용될 수 있음에 유의
- -

[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

- -

MPEG-4 Video Elemental Stream (MP4V-ES) 포맷은 MPEG-4 Part 2 시각 표준 중 하나입니다. 일반적으로 MPEG-4 part 2 비디오는 더 이상 사용하지 않는데 다른 코덱에 비해 특장점이 없어 모바일에서도 쓰임새가 없습니다.  MP4V 는 MPEG-4 컨테이너의 H.263 인코딩과 본질적으로 동일합니다.

- -

원래 목적은 {{Glossary("RTP")}} 세션에서 MPEG-4 오디오 및 비디오 스트림을 사용하기 위해서였습니다. 하지만 3GP를 통한 모바일 통신에서도 쓰이고 있습니다.

- -

지원하는 주요 브라우저가 없으며 사실상 폐기된 포맷이라 왠만하면 사용할 일이 없을겁니다. 이 컨테이너 파일의 확장자는.mp4v지만 .mp4로 잘못 표기된 경우도 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트5 Kbps 에서 1 Gbps 이상
지원 프레임 레이트명시적 제한 없음; 데이터 전송율에 의해 제한
압축손실 DCT 기반 알고리즘
지원 프레임 크기최대 4,096 x 4,096 픽셀
지원 컬러 모드YCrCb 크로마 서브샘플링(4:2:0, 4:2:2, and 4:4:4); 컴포넌트당 12bits 색 깊이
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원Yes
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
MP4V-ES supportNo[2]NoYes[1]NoNoNo
-
지원 컨테이너3GP, MP4
{{Glossary("RTP")}} / WebRTC 호환아니오
Supporting/Maintaining 유지/보수 기관MPEG
스펙{{RFC(6416)}}
라이선스상용; MPEG LA and/or AT&T에서 필수 라이선스 취득 필
- -

[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는 1990년대 초에 베일을 벗었습니다. 이후 MPEG 비디오 표준과는 다르게 MPEG-1은 {{Glossary("ITU", "ITU's")}}의 개입 없이 순수히 MPEG가 만들었습니다.

- -

모든 MPEG-2 디코더는 MPEG-1 비디오를 재생할 수 있기 때문에 다양한 소프트웨어와 하드웨어 장치에서 호환 가능합니다. MPEG-1 비디오 특허는 모두 만료되었으며, 라이선스에 대한 걱정에서 자유롭습니다. 하지만 소수의 브라우저만이 플러그인 없이 MPEG-1을 지원하며 플러그인은 deprecated된 경우가 많으므로 일반적으로는 더 이상 사용할 수 없습니다. 때문에 웹사이트/어플리케이션에서 MPEG-1는 좋은 선택이 아닙니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트최대 1.5 Mbps
지원 프레임 레이트23.976 FPS, 24 FPS, 25 FPS, 29.97 FPS, 30 FPS, 50 FPS, 59.94 FPS, 60 FPS
압축손실 DCT 기반 알고리즘
지원 프레임 크기최대 4,095 x 4,095 픽셀
지원 컬러 모드Y'CbCr 4:2:0 크로마 서브샘플링 with up to 12 bits per component
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원아니오
브라우저 호환 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-1 supportNoNoNoNoNoYes
-
지원 컨테이너MPEG
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관MPEG
스펙https://www.iso.org/standard/22411.html
라이선스Proprietary; however, all patents have expired, so MPEG-1 may be used freely
- -

MPEG-2 Part 2 Video

- -

MPEG-2 Part 2 {{Glossary("ITU")}}가 설계한 H.262를 참조하여 MPEG-2 스펙에서 정의한 비디오 포맷이며입니다. MPEg-1 비디오와 매우 유사하며 사실 MPEG-2 플레이어는 높은 비트레이트 및 특수 인코딩 옵션 지원을 위한 확장 스펙이 아닌 한 특별한 작업 없이 MPEG-1 비디오를 재생할 수 있습니다.

- -

MPEG-2의 목적은 표준 TV로 압축하는 것이므로 인터레이스 비디오도 지원합니다. 표준 비디오 결과물의 압축 비율과 품질은 DVD 비디오 미디어의 요구사항도 충족하여 메인 비디오 코덱으로 MPEG-2가 선정되기에 충분하였습니다.

- -

MPEG-2는 서로 다른 스펙을 가진 여러 프로파일이 있습니다. 각 프로파일은 4개의 레벨을 가지고 있으며 프레임 레이트, 해상도, 비트레이트등의 비디오 속성 값을 증가시킬 수 있습니다. 대부분의 프로파일은 Y'CbCr 4:2:0 크로마 서브샘플링을 쓰지만 더 상위의 프로파일은 4:2:2를 지원한다든가 말입니다. 추가로 대형 프레임 크기 및 비트레이트 지원을 위한 4개의 레벨이 있습니다. 예를 들어 북미 지역의 {{interwiki("wikipedia", "ATSC standards", "ATSC")}} TV 스펙은 Main Profile at high Level을 통해 1920 x 1080 (30 FPS) 및 1280 x 720 (60 FPS)의 고화질을 최대 80 Mbps 비트레이트로 지원합니다.

- -

그러나 소수의 브라우저만 MPEG-2를 네이티브로 지원하며 플러그인은 대부분 deprecated 되어 더 이상 사용 가능하지 않습니다. 때문에 웹 사이트나 웹앱에서 MPEG-2는 좋은 선택이 아닙니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트최대 100 Mbps; 레벨과 프로파일에 따라 다름
지원 프레임 레이트 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
축약어레벨 이름지원 프레임 레이트
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
-
압축손실 DCT 기반 알고리즘
지원 프레임 크기 - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
축약어레벨 이름최대 프레임 크기
LLLow Level352 x 288 pixels
MLMain Level720 x 576 pixels
H-14High 14401440 x 1152 pixels
HLHigh Level1920 x 1152 pixels
-
지원 컬러 모드대다수 프로파일에서 Y'CbCr 4:2:0 크로마 서브샘플링; "High", "4:2:2" 프로파일에서 4:2:2 크로마 서브샘플링 지원.
HDR 지원아니오
가변 프레임 레이트(VFR) 지원아니오
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
MPEG-2 supportNoNoNoNoNoYes
-
지원 컨테이너MPEG, MPEG-TS (MPEG Transport Stream), MP4, QuickTime
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관MPEG / ITU
스펙https://www.itu.int/rec/T-REC-H.262
- https://www.iso.org/standard/61152.html
라이선스상용; 2019년 4월 1일자로 말레이지아와 필리핀을 제외한 모든 지역에서 모든 특허 만료됨, 두 국가 외에서는 자유롭게 사용 가능. MPEG LA에 의해 특허 관리
- -

Theora

- -

Xiph.org가 {{interwiki("wikipedia", "Theora")}}는 로열티와 라이선스 없이 사용 가능한 오픈소스 자유 비디오 코덱입니다. Theora의 품질과 압축율은 MPEG-4 Part 2 Visual과 AVC에 견줄만하며, 비디오 인코딩 시 반드시 최고를 고수해야 하는 경우가 아니라면 매우 좋은 선택이 될 수 있습니다. 하지만 라이선스-프리로 특허 문제가 없으며 상대적으로 저사양 CPU에서도 충분히 돌아가는 스펙 덕분에 최근 많은 소프트웨어와 웹프로젝트에서 선택하고 있습니다. 현재로써는 Theroa를 위한 하드웨어 디코더가 없기 때문에 저사양 CPU에서도 원할하다는 점은 아주 중요합니다.

- -

Theora는 원래 On2 Technologies의 VC3 코덱을 베이스로 하고 있습니다. VC3 코덱과 사양은 Xiph.org 관리 하에 LGPL 라이선스로 등재되어 있으며 이후 Theora 표준으로 인입하였습니다.

- -

Theora의 단점 중 하나는 오직 8 bit 컬러 모드만을 지원하여 컬러 밴딩을 피하기 위해 10 이상의 컬러 모드를 선택하는 옵션이 없다는 겁니다. 따지자면 현 시점에서 8 bit 컬러가 대부분이기 때문에 큰 문제는 되지 않습니다. 단지 불편할 뿐이죠. 또 Theora는 Ogg 컨테이너에서만 사용할 수 있습니다. 가장 큰 문제는 Safari에서 사용할 수 없다는 것입니다. macOs 뿐만 아니라 수억대의 iPhone과 iPad에서도 사용할 수 없다는 걸 의미합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트최대 2 Gbps
지원 프레임 레이트임의의 0 이상 값 지원. 유리수 프레임 레이트를 지원하기 위해 32-bit 분자와 분모로 구성되어 있음
압축손실 DCT-기반 알고리즘
지원 프레임 크기최대 1,048,560 x 1,048,560 픽셀 이하 어떠한 가로, 세로 조합이라도 가능
지원 컬러 모드Y'CbCr 4:2:0, 4:2:2, 4:4:4 크로마 서브샘플링, 8 bit 컬러
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원[1]
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
Theora support3Yes[2]3.5No10.5No
-
지원 컨테이너Ogg
{{Glossary("RTP")}} / WebRTC 호환아니오
유지/보수 기관Xiph.org
스펙https://www.theora.org/doc/
라이선스오픈 프리-로열티
- -

[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

- -

Video Processor 8 (VP8) 코덱은 최초 On2 Technologies가 개발했습니다. Google은 On2 인수 후, VP8 관련된 특허와 무관하게 완전한 오픈 로열티-프리 라이선스로 출시했습니다. 압축률과 품질의 면에서 VP8은 {{anch("AVC")}}에 견줄만 합니다.

- -

브라우저가 지원한다면 V8에서 알파 채널을 쓸 수 있으며 비디오 뒤의 백그라운드 이미지를 알파 채널 픽셀과 겹쳐 볼 수도 있습니다.

- -

HTML 콘텐츠로써 특히 WebM 파일에 포함된 VP8을 지원하는 좋은 브라우저가 많습니다. 이는 VP8이 여러분의 콘텐츠로 좋은 선택이 될 수 있으며 가능하다면 더 좋은 VP9를 선택할 수도 있습니다. 웹브라우저는 WebRTC를 위해 VP8을 반드시 지원해야 합니다. 하지만 HTML Audio video 엘리먼츠에는 꼭 VP8을 지원할 필요는 없습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트level별 제한이 없는 한 무제한 임의의 값
지원 프레임 레이트임의 값
압축손실 DCT-기반 일고리즘
지원 프레임 크기최대 16,384 x 16,384 픽셀
지원 컬러 모드Y'CbCr 4:2:0 크로마 서브샘플링, 8 bit 색 깊이
HDR 지원아니오
가변 프레임 레이트 (VFR) 지원
지원 브라우저 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
VP8 support2514[1]491612.1[2]
-
지원 컨테이너3GP, Ogg, WebM
{{Glossary("RTP")}} / WebRTC 호환예; VP8은 WebRTC의 필수 코덱 중 하나
유지/보수 기관Google
스펙{{RFC(6386)}}
라이선스라이선스 및 로열티로부터 자유로운 오픈 소스
- -

[1] Edge support for VP8 requires the use of Media Source Extensions.

- -

[2] Safari only supports VP8 in WebRTC connections.

- -

VP9

- -

Video Processor 9 (VP9)는 구글이 VP8 표준의 후속으로 개발하였습니다. VP8과 마찬가지로 VP9는 완전한 로열티-프리 오픈 소스입니다. 인코딩/디코딩 퍼포먼스는 AVC에 비해 더 높은 품질을 유지하면서도 약간 더 빠릅니다. VP9로 인코딩한 비디오의 품질은 비슷한 수준의 비트레이트에서 HEVC에 견줄만합니다.

- -

VP9의 main profile은 4:2:0 크로마 서브 샘플링에서 8-bit 색 깊이 모드만을 지원합니다. 하지만 더 깊은 색상 모드와 전체 범위의 크로마 서브샘플링을 지원하는 프로파일도 가지고 있습니다. HDR 기능도 있으며 프레임 레이트, 영상 비율, 프레임 사이즈를 자유롭게 선택할 수 있는 오셥도 제공합니다.

- -

VP9는 광범위한 브라우저가 지원하고 있으며 하드웨어 구현체로 상당히 퍼져있습니다. VP9는 WebM에서만 사용할 수 있는 두 코덱 중 하나입니다(나머지 하나는 {{anch("VP8")}}). 하지만 Safari는 WebM 및 VP9 모두 지원하지 않으므로 VP9를 사용할 경우 iPhone, iPad, Mac에서 AVC나 HEVCS등 다른 포맷을 대체할 수 있도록 만들어야 합니다.

- -

Safari 지원이 빠져있지만 WebM 컨테이너를 쓸 수 있고 Safari 사용자에게 AVC/HEVC 대체 포맷 제공이 가능하다면 VP9은 좋은 선택입니다. 상용 코덱 대신에 오픈 코덱을 쓰기로 결정했다면 더할 나위 없죠. 호환 포맷을 제공할 수 없지만 Safari 사용자도 잃을 수 없다면 WebM에 VP9는 차선책이 좋을 겁니다. 아니라면 다른 코덱을 고려해 보셔야겠죠.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
지원 비트레이트level 제한이 없는 한 무제한 임의의 값
지원 프레임 레이트임의 값
압축손실 DCT-기반 알고리즘
지원 프레임 크기최대 65,536 x 65,536 픽셀
지원 컬러 모드 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Profile색 깊이크로마 서브샘플링
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
- -

지원 색 공간: {{interwiki("wikipedia", "Rec. 601")}}, {{interwiki("wikipedia", "Rec. 709")}}, {{interwiki("wikipedia", "Rec. 2020")}}, {{interwiki("wikipedia", "SMPTE C")}}, SMPTE-240M (obsolete; replaced by Rec. 709), {{interwiki("wikipedia", "sRGB")}}.

-
HDR 지원예; HDR10+, HLGPQ
가변 프레임 레이트 (VFR) 지원Yes
브라우저 호환성 - - - - - - - - - - - - - - - - - - - - - -
기능ChromeEdgeFirefoxInternet ExplorerOperaSafari
VP9 지원291428No10.6No
-
지원 컨테이너MP4, Ogg, WebM
{{Glossary("RTP")}} / WebRTC 호환
유지/보수 기관Google
스펙https://www.webmproject.org/vp9/
라이선스라이선스 및 로열티-프리 오픈 소스requirements
- -

코덱 선택하기

- -

어떤 코덱을 사용할지는 스스로 꼬리에 꼬리를 무는 질문을 던진 끝에 답을 얻을 수 있습니다.:

- -
    -
  • 오픈 포맷을 사용할건가요? 상용 코덱도 염두에 두고 있나요?
  • -
  • 한 비디오를 여러 포맷으로 생산할 여력이 되나요? fallback 옵션을 제공할 수 있다면 의사 결정 과정을 단순화 할 수 있습니다.
  • -
  • 호환성을 포기할 수 있는 브라우저가 있나요?
  • -
  • 보장하는 커버리지 상 가장 오래된 브라우저는 어떤 것인가요? 예를 들어 지난 5년간 출시된 모든 브라우저를 지원할지, 1년 사이의 브라우저만을 지원할지?
  • -
- -

아래 섹션에서는 특정 유즈케이스에서 추천할만한 코덱을 명시합니다. 각 유즈케이스마다 최대 두 개의 추천 코덱을 볼 수 있습니다. 특정 유즈케이스에 베스트인 코덱이 상용이거나 로열티 지불이 필요하다면 생각해 볼 두 가지 옵션이 있습니다: 로열티 프리 오픈 코덱을 선택하거나, 상용 라이선스를 따르거나.

- -

각 비디오당 하나의 포맷만 제공할 수 있다면 필요한 요구사항을 최대한 만족하는 최적의 포맷을 선택해야 합니다. 첫 번째 추천 코덱은 품질과 퍼포먼스, 호환성을 최대한 고려한 것이며 두번째는 품질과 퀄리티, 크기를 조금 희생하더라도 최대한의 호환성을 가지는 옵션입니다.

- -

Recommendations for everyday videos

- -

우선 블로그나 정보형 사이트, 소규모 기업 웹사이트 등 상품을 설명하기 위한 비디오(비디오 자체가 상품은 아닌)를 위한 옵션을 알아봅시다.

- -
    -
  1. -

    WebM 컨테이너에 비디오는 {{anch("VP8")}}, 오디오는 Opus 코덱을 사용합니다. 이들은 로열티-프리 오픈 포맷이지만 최근 브라우저에서만 폭넓게 지원하는 경향이 있어 폴백 지원이 필수적입니다.

    - -
    <video controls src="filename.webm"></video>
    -
    -
  2. -
  3. -

    MP4 컨테이너에 비디오 코덱은 {{anch("AVC")}} (H.264) 오디오 코덱은 AAC 를 사용합니다. MP4 컨테이너에 AVC, AAC 조합은 모든 주요 브라우저에서 폭넓게 지원하는 조합이며 대부분의 유즈케이스에서 좋은 품질을 보여주기 때문입니다. 하지만 라이선스 요구사항에 대해 컴플라이언스 이슈는 없는 지 확인이 필요하죠.

    - -
    <video controls>
    -  <source type="video/webm"
    -          src="filename.webm">
    -  <source type="video/mp4"
    -          src="filename.mp4">
    -</video>
    -
    -
  4. -
- -
-

Note: {{HTMLElement("<video>")}} 엘리먼트는 자식으로 {{HTMLElement("source")}} 엘리먼트 유무에 상관 없이 </video> 닫기 태그가 필요하다는 것을 잊지 마세요.

-
- -

고품질 비디오 제공을 위한 추천

- -

여러분의 목표가 최대한 높은 품질의 비디오를 재생하는 것이라면 가능한한 다양한 포맷으로 제공할 수 있는 방법을 모색해야합니다. 최신의 코덱일수록 고품질 비디오를 지원하지만 반대로 브라우저 호환성은 떨어집니다.

- -
    -
  1. -

    WebM 컨테이너에 비디오 코덱은 AV1, 오디오 코덱은 Opus. AV1 인코딩 시 6.3 High level 같은 높은 전문 프로파일을 사용할 수 있다면 훌륭한 품질의 비디오를 4K/8K 해상도로 제공할 수 있습니다. 오디오 인코딩 시 Opus Fullband 프로파일로 48 kHz 샘플링 레이트를 사용한다면 사람이 들을 수 있는 거의 모든 주파수를 캡쳐할 수 있죠.

    - -
    <video controls src="filename.webm"></video>
    -
    -
  2. -
  3. -

    MP4 컨테이너에 비디오 코덱으로 {{anch("HEVC")}} 를 쓰되 프로파일은 Main 4:2:2 10/12 bit 색 깊이, 최대 Main 4:4:4 16 bit 색 깊이 수준의 고급 Main 프로파일을 사용합니다. 비트레이트를 높이면 놀라운 색 재현과 훌륭한 그래픽 퀄리티를 보여줄 것입니다. 또한 하이 다이나믹 레인지 비디오를 위한 HDR 메타데이터도 추가할 수 있습니다. 오디오는 ACC 인코딩 시 높은 샘플링 레이트(최소 48 kHz, 96 kHz 권장)에 fast-encoding이 아닌 complex-encoding을 사용합니다.

    - -
    <video controls>
    -  <source type="video/webm"
    -          src="filename.webm">
    -  <source type="video/mp4"
    -          src="filename.mp4">
    -</video>
    -
    -
  4. -
- -

비디오 보존, 편집, 믹싱을 위한 추천

- -

웹 브라우저에서 사용 가능한 무손실-아니면 거의 무손실-비디오 코덱은 현재 없습니다. 이유는 간단한데:비디오는 거대합니다. 무손실 압축은 손실 압축에 비해 비효율적입니다. 예를 들어 4:2:0 크로마 서브샘플링의 무압축 1080p 비디오(1920*1080 픽셀)는 최소 비트레이트가 1.5Gbps가 넘죠. FFV1(브라우저 미지원) 같은 무손실 압축 코덱을 사용하면 콘텐츠에 따라 다르지만 600 Mbps 근처로 줄일 수 있습니다. 하지만 네트워크로 보내이겐 여전히 엄청난 크기이며 현실적으로 불가능한 사이즈입니다.

- -

손실 코덱이 무손실 모드를 가지고 있다 하여도 별 반 다르지 않는데;현재 웹 브라우저에서 무손실 모드를 구현하고 있지 않기 때문입니다. 최선은 손실 압축을 사용하는 코덱 중 최대한 고품질 코덱을 선택한 뒤 최소한의 압축만 수행하도록 설정하는 것입니다. 한가지 방법은 코덱을 설정하기를 "fast" 압축을 선택하는 것입니다. 일반적으로 이는 압축을 최소화합니다.

- -

외부에 비디오 보존

- -

여러분의 웹 사이트나 앱 외부 영역에 보존 목적의 비디오라면 무압축 원본 비디오 데이터를 압축하는 유틸리티를 사용하세요. 예를들어 x264 유틸리티는 매우 높은 비트레이트로 {{anch("AVC")}} 인코딩을 할 수 있습니다:

- -
x264 --crf 18 -preset ultrafast --output outfilename.mp4 infile
- -

다른 코덱들도 충분한 여유가 있다면 더 나은 최고-품질 압축을 보여줄지도 모릅니다, 단지 그 인코더들은 엄청 느려서 위 압축으로 얻어지는 거의 무손실 비디오가 전체적으로 비슷한 품질을 보여주면서도 상당히 빠를겁니다.

- -

비디오 녹화

- -

무손실에 가까운 비디오를 보여줘야 한다는 제약이 있다면, {{anch("AVC")}} 또는 {{anch("AV1")}}를 고려해 볼 필요가 있습니다. 예를들어 비디오를 녹화하기 위해 MediaStream Recording API를 사용한다면, {{domxref("MediaRecorder")}} 객체를 생성하는 코드는 아래와 같습니다:

- -
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);
- -

위 예제에서 MediaRecorder를 생성하여 BT.2100 HDR, 12-bit color 4:4:4 크로마 서브샘플링 설정으로 {{anch("AV1")}} 비디오 레코딩을, FLAC으로 무손실 오디오를 레코딩 하고 있습니다. 결과물 파일은 비디오 오디오 트랙 합쳐 800Mbps를 넘지 않을 겁니다. 하드웨어 성능이나 요구사항, 사용하고자 하는 코덱에 따라 설정 값을 변경할 수 있습니다. 위의 비트 레이트 값은 네트워크 실사용 케이스에선 비현실적인 값이며 로컬 장치에서만 가능하겠죠.

- -

codecs 파라미터 값을 '.' 기준으로 나눠서 의미를 분석해 봅시다:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
설명
av014문자 코드 (4CC-4 Character Code) {{anch("AV1")}} 코덱을 의미합니다.
2프로파일. 2는 Professional profile. 1은 High profile, 0은 Main profile.
19H레벨과 티어. AV 스펙의 A.3의 표에서 설명, Level 6.3의 High tier를 의미합니다
12색 깊이. 컴포넌트당 12bit를 의미. 8, 10도 가능하나 AV1에서 표현할 수 있는 가장 정확한 색 깊이 값이 12입니다.
0모노크롬 모드 플래그. 1로 지정하면 색차 성분은 녹화되지 않으며 휘도 성분만 축적되어 그레이스케일 이미ㅣ지로 표현됩니다. 색상을 사용할 것이므로 0으로 지정하였습니다.
000크로마 서브샘플링 모드. AV1 스펙의 section 6.4.2에 설명. 모노크롬 모드 값이 0일 때 000 값은 4:4:4 크로마 서브샘플링 또는 색상 손실이 없어야 함을 나태냅니다.
09사용할 색 공간. AV1 스펙의 section 6.4.2에서 설명 9는 HDR을 위한 BT.2020 색역을 의미합니다.
16전송시 사용할 색 공간. 마찬가지로 section 6.4.2에서 설명; 16은 BT.2100 PQ 컬러로 전송하겠다는 의미입니다.
09section 6.4.2 에서 설명하는 계수 행렬. 9 값은 유동 휘도 값의 BT.2020 색역을 사용하겠다는 의미입니다. BT.2010 YbCbCr와 동일한 의미입니다.
1"full range" 비디오 플래그. 1은 전체 컬러 영역을 녹화하겠다는 의미입니다.
- -

선택하고자 하는 코덱 문서에 codecs 파라미터 값이 받아들이는 설정이 설명되어 있습니다.

- -

더 보기

- - diff --git "a/files/ko/web/media/formats/\354\273\250\355\205\214\354\235\264\353\204\210/index.html" "b/files/ko/web/media/formats/\354\273\250\355\205\214\354\235\264\353\204\210/index.html" deleted file mode 100644 index d4e45c294a..0000000000 --- "a/files/ko/web/media/formats/\354\273\250\355\205\214\354\235\264\353\204\210/index.html" +++ /dev/null @@ -1,1279 +0,0 @@ ---- -title: 미디어 컨테이너 포맷 (파일 타입) -slug: Web/Media/Formats/컨테이너 -translation_of: Web/Media/Formats/Containers ---- -

오디오와 비디오 파일 포맷은 두 파트에서 정의할 수 있습니다.(오디오 비디오가 한 파일에 있으면 물론 3 파트지요): 오디오/비디오 코덱와 미디어 컨테이너 포맷(도는 파일 타입)입니다. 이 가이드 문서는 웹에서 널리 쓰이는 컨테이너 포맷에 대해 알아보고 기본적인 스펙와 장단점 그리고 적절한 사용법을 설명하고 있습니다.

- -

WebRTC 는 컨테이너를 사용하지 않습니다. 대신에 각 트랙을 나타내는{{domxref("MediaStreamTrack")}} 객체를 통해 인코딩 된 오디오/비디오 트랙을 한 곳에서 다른 곳으로 직접 스트리밍합니다. WebRTC에서 일반적으로 사용하는 코덱이나 브라우저 호환성을 알아보려면 Codecs used by WebRTC 문서를 참고하세요.

- -

일반적인 컨테이너 포맷

- -

미디어 컨테이너 포맷에는 여러 종류가 있지만 여러분들은 보통 아래 나열된 목록의 포맷을 주로 만나게 될 겁니다. 일부는 오디오만 지원하는 것도 있고 오디오와 비디오 모두를 지원하는 포맷도 있죠. MIME 타입과 확장자도 나열되어 있습니다. 웹상에서 가장 많이 쓰이는 컨테이너 포맷은 아마도 MPEG-4 (MP4), Quicktime Movie (MOV), Wavefile Audio File Format (WAV)일겁니다. 또한 MP3, Ogg, WebM, AVI 등의 포맷도 볼 수 있지요. 하지만 모든 브라우저가 이 다양한 포맷들을 지원하는 것은 아닙니다. 사용하기 편하고 다른 조합과의 구분을 위해 특정한 컨테이너와 코덱의 조합은 독자적인 MIME type과 확장자를 가지기도 합니다. 예를들어 Opus 오디오 트랙만을 가진 Ogg파일은 가끔 Opus 파일이라 불리며 .opus 확장자를 가지는 경우도 있습니다. 하지만 실제로는 단순한 Ogg 파일일 뿐이죠.

- -

반대 케이스로 특정 코덱이 특정 컨테이너에 담긴 형태가 매우 보편적일 경우 독자적인 형식으로 취급하는 경우도 있습니다. MP3 오디오 파일이 대표적인 경우로, MPEG-1 컨테이너에 MPEG-1 Audio Layer III 코덱으로 인코딩 된 오디오 트랙 하나만이 담긴 케이스입니다. 컨테이너는 일반적인 MPEG지만 이 형식은 audio/mp3 MIME 타입과 .mp3 확장자를 사용합니다.

- -

컨테이너 포맷(파일 타입) 인덱스

- -

특정 컨테이너 포맷에 대해 더 알아보려면 아래 목록에서 찾아 클릭하세요. 컨테이너 사용법과 지원하는 코덱, 지원하는 브라우저 등을 알 수 있습니다.

- -
-
    -
  • {{anch("3GP")}}
  • -
  • {{anch("ADTS")}}
  • -
  • {{anch("FLAC")}}
  • -
  • {{anch("MPEG", "MPEG / MPEG-2")}}
  • -
  • {{anch("MP4", "MPEG-4 (MP4)")}}
  • -
  • {{anch("Ogg")}}
  • -
  • {{anch("QuickTime")}}
  • -
  • {{anch("WAVE")}}
  • -
  • {{anch("WebM")}}
  • -
-
- -

3GP

- -

3GP 또는 3GPP 컨테이너는 셀룰러 네트워크를 통해 전송하고 모바일 장치에서 사용하기 위해 고안되었습니다. 원래 3G 모바일 폰을 위해 디자인하였지만 현대의 모바일 폰과 네트워크에서도 사용하고 있습니다. 하지만 네트워크 처리량이 늘어나면서 3GP 포맷의 필요성은 점차 줄어들고 있죠. 그러나 여전히 느린 네트워크나 저사양 폰에서는 유용한 컨테이너이기도 합니다.

- -

이 컨테이너는 ISO Base Media File Format과 MPEG-4 기반이지만 저대역폭 케이스에 최적화되어 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - -
Base 3GP media MIME types
AudioVideo
audio/3gppvideo/3gpp
audio/3gpp2video/3gpp2
audio/3gp2video/3gp2
- -

위는 3GP 컨테이너의 기본 MIME 타입입니다; 사용하는 코덱에 따라 다른 타입을 사용할 수도 있습니다; 또한 MIME 타입 문자열에 codecs 파라미터를 추가하여 어떠한 오디오/비디오 코덱을 사용했는지 표시할 수 있으며 profile, level, 코덱 설정 값도 추가하여 전달할 수 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3GP가 지원하는 비디오 코덱.
CodecBrowser support
ChromeEdgeFirefoxSafari
AVC (H.264)Yes1,2
H.263Yes1
MPEG-4 Part 2 (MP4v-es)Yes1
VP8Yes1
- -

[1] FIrefox only supports 3GP on OpenMAX-based devices, which currently means the Boot to Gecko (B2G) platform.

- -

[2] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3GP가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AMR-NBYes1
AMR-WBYes1
AMR-WB+Yes1
AAC-LCYes1,2
HE-AAC v1Yes1,2
HE-AAC v2Yes1,2
MP3Yes1
- -

[1] FIrefox only supports 3GP on OpenMAX-based devices, which currently means the Boot to Gecko (B2G) platform.

- -

[2] Firefox support for AAC relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

- -

ADTS

- -

Audio Data Transport Stream (ADTS) 는 인터넷 라디오 같은 오디오 스트림을 사용하기 위해 MPEG-4 Part 3로 규정된 컨테이너 포맷입니다. 근본적으로 ACC 오디오 데이터에서 스트림만 깐 것과 거의 동일하며 최소한의 헤더만 담긴 ADTS 프레임으로 구성되어 있습니다.

- - - - - - - - - - - - - - - - -
ADTS media MIME types
Audio
audio/aac[1]
audio/mpeg[1]
- -

[1] The MIME type used for ADTS depends on what kind of audio frames are contained within. If ADTS frames are used, the audio/aac MIME type should be used. If the audio frames are in MPEG-1/MPEG-2 Audio Layer I, II, or III format, the MIME type should be audio/mpeg.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ADTS가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AACYes1
MP3Yes
- -

[1] Firefox support for AAC relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

- -

FLAC

- -

Free Lossless Audio Codec (FLAC)은 무손실 오디오 코덱입니다; 이 코덱을 담을 수 있는 컨테이너 역시 FLAC이라 부릅니다. 이 포맷은 어느 특허에도 묶여있지 않아 자유롭게 사용할 수 있습니다. FLAC 파일은 FLAC 오디오 데이터만 담을 수 있습니다.

- - - - - - - - - - - - - -
FLAC media MIME type
Audio
audio/flac
- - - - - - - - - - - - - - - - - - - - - - - - -
FLAC이 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
FLACYes
- -

MPEG/MPEG-2

- -

{{interwiki("wikipedia", "MPEG-1")}}과 {{interwiki("wikipedia", "MPEG-2")}}은 근본적으로 동일합니다. the Moving Picture Experts Group (MPEG)에서 만들었으며 DVD 등의 물리적 매체에서 널리 쓰이고 있습니다.

- -

인터넷에서 아마 가장 많이 사용되는 MPEG 파일 포맷은 {{interwiki("wikipedia", "MPEG-1", "Layer_III/MP3", "MPEG-1 Audio Layer 3")}} 일 겁니다; MP3 파일은 전 세계의 디지털 오디오 장치에서 널리 재생되고 있습니다. 반대로 MPEG-1, MPEG-2는 웹에서 별로 사용하고 있지 않죠.

- -

MPEG-1과 MPEG-2 간의 차이점은 컨테이너 포맷이 아니라 미디어 데이터 포맷에 있습니다. MPEG-1은 1992년 소개되었으며; MPEG-2는 1996년에 소개되었습니다.

- - - - - - - - - - - - - - - -
MPEG-1과 MPEG-2 media MIME types
AudioVideo
audio/mpegvideo/mpeg
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MPEG-1과 MPEG-2가 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
MPEG-1 Part 2No
MPEG-2 Part 2No
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MPEG-1과 MPEG-2가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
MPEG-1 Audio Layer INo
MPEG-1 Audio Layer IINo
MPEG-1 Audio Layer III (MP3)Yes
- -

MPEG-4 (MP4)

- -

{{interwiki("wikipedia", "MPEG-4")}} (MP4) 는 최신 MPEG 파일 포맷입니다. 파트 1과 14 스펙에서 정의된 두 가지 버전의 포맷이 있습니다. MP4는 오늘날 유명한 컨테이너 포맷으로 많이 쓰이는 코덱을 지원하며 널리 사용되고 있습니다.

- -

최초의 MPEG-4 Part 1 포맷은 1999년 발표되었습니다; Part 14에서 정의된 버전 2 포맷은 2003년 추가되었습니다. MP4 파일 포맷은 Apple이 개발한 {{interwiki("wikipedia", "QuickTime file format")}}에서 파생된 {{interwiki("wikipedia", "ISO base media file format")}}에서 다시 파생되었습니다.

- -

MPEG-4 미디어 타입을 표기할 때 (audio/mp4 or video/mp4), MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 추가적으로 profile, level, 코덱 설정 등을 명기할 수 있습니다.

- - - - - - - - - - - - - - - -
기본 MPEG-4 media MIME 타입
AudioVideo
audio/mp4video/mp4
- -

위는 MPEG-4 미디어 컨테이너의 기본 타입입니다; 어떤 코덱을 쓰느냐에 따라 MIME 타입도 달라질 수 있습니다. 또한 MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 추가적으로 profile, level, 코덱 설정 등을 명기할 수 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MPEG-4가 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AVC (H.264)Yes1
AV1Yes1
H.263No
MPEG-4 Part 2 VisualNo
VP9Yes
- -

[1] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

- -

[2] Firefox support for AV1 is currently disabled by default; it can be enabled by setting the preference media.av1.enabled to true.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MPEG-4가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AACYes1
FLACYes
MPEG-1 Audio Layer III (MP3)Yes
OpusYes
- -

[1] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

- -

Ogg

- -

{{interwiki("wikipedia", "Ogg")}}는 Xiph.org Foundation이 운영하는 자유 오픈 컨테이너 포맷입니다. Theora, Vorbis, and Opus등의 Ogg 프레임워크는 특허에 얽매이지 않게 정의되었습니다. 재단 웹사이트에서 Xiph.org documents about the Ogg format를 확인할 수 있습니다.

- - - - - - - - - - - - - - - -
기본 Ogg media MIME types
AudioVideo
audio/oggvideo/ogg
- -

MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 트랙의 미디어 포맷에 대한 추가 정보도 기입할 수 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ogg가 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
TheoraYes
VP8Yes
VP9Yes
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ogg가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
FLACYes
OpusYes
VorbisYes
- -

QuickTime

- -

QuickTime 파일 포맷(QTFF, QTMOV) 는 동일한 이름의 미디어 프레임워크에서 사용하기 위해 애플이 개발했습니다. 확장자 .mov는 최초 영화에서 쓰이기 위해  개발되었다는 의미에서 지어졌으며 보통 "QuickTime movie" 포맷이라 불립니다. QTFF가 MPEG-4 파일 포맷에 기반하였지만 두 포맷에는 분명한 차이점이 있으며 상호 호환되지 않습니다.

- -

QuickTime 파일은 오디오, 비디오 텍스트 트랙 등 시간축을 가지는 다수의 데이터 타입을 지원합니다. QuickTime 파일은 원래 macOS에서 사용하기 위해 개발되었지만 수 년이 지나면서 윈도우즈 환경에서는 QuickTime for Windows를 통해 사용할 수 있게 되었습니다. 그러나 2016년 초부터 애플은 더 이상 QuickTime for Windows를 유지 보수하지 않으며 알려진 보안 취약점으로 인해 사용해선 안됩니다. 하지만 Windows Media Player 가 현재 QuickTime version 2.0 및 이전 버전을 지원하며; 이후 버전의 QuickTime은 서드파티 플러그인을 통해 지원합니다.

- -

Mac OS에서 QuickTime 프레임워크는 QuickTime 포맷의 영상 파일 및 코덱 뿐만아니라 널리 쓰이는 오디오/비디오 코덱 상당 수를 지원합니다. 정지 화상 이미지 포맷도 포함해서요. (QuickTime 플러그인이 설치되었거나 QuickTime과 바로 연동된 브라우저를 포함 한)맥 애플리케이션은 QuickTime을 통해서 ACC, AIFF, MP#, PCM, Qualcomm PureVoice 등의 오디오 포맷과 AVI, DV, Pixlet, ProRes, FLAC, Cinepak, 3GP, H.261 through H.265, MJPEG, MPEG-1, MPEG-4 Part 2, Sorenson 등 수 많은 비디오 포맷을 읽고 쓸 수 있습니다.

- -

추가적인 코덱을 지원하기 위해 QuickTime에 다수의 서드파티 컴포넌트를 설치할 수도 있습니다.

- -

QuickTime은 처음부터 지금까지 근본적으로 애플 디바이스에서 사용하기 위해 만들어졌기 때문에 인터넷 환경에서 널리 쓰이고 있지는 않습니다. 애플 스스로도 현재는 MP4 비디오를 사용하고 있구요. 게다가 QuickTime 프레임워크마저 deprecated되면서 macOS 10.15 Catalina부터는 사용이 불가능해졌습니다.

- - - - - - - - - - - - - -
Base QuickTime media MIME type
Video
video/quicktime
- -

video/quicktime 은 QuickTime 미디어 컨테이너의 기본 MIME 타입입니다. QuickTime (Mac OS의 미디어 프레임워크)이 다양한 컨테이너와 코덱을 지원하므로 다른 많은 MIME 타입 역시 지원합니다.

- -

MIME 타입에 codecs 파라미터를 추가하여 사용하는 오디오/비디오 코덱을 명시할 수 있으며 추가적으로 profile, level, 코덱 설정 등을 명기할 수 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
QuickTime이 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AVC (H.264)No
CinepakNo
Component VideoNo
DVNo
H.261No
H.263No
MPEG-2No
MPEG-4 Part 2 VisualNo
Motion JPEGNo
Sorenson Video 2No
Sorenson Video 3No
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
QuickTime이 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AACNo
ALaw 2:1No
Apple Lossless (ALAC)No
HE-AACNo
MPEG-1 Audio Layer III (MP3)No
Microsoft ADPCMNo
µ-Law 2:1 (u-Law)No
- -

WAVE (WAV)

- -

Waveform Audio File Format (WAVE)는 보통 줄여서 WAV라 불리며 .wav 확장자를 갖습니다. 오디오 비트스트림 데이터를 담기 위해 Microsoft와 IBM이 개발했습니다. 대부분의 WAV 파일은 linear PCM 포맷의 오디오 데이터를 담고 있습니다.

- -

이 파일 포맷은 Resource Interchange File Format (RIFF)에서 파생되었으며 애플의 AIFF 같은 다른 파생 형식와 유사합니다..

- -

WAVE 포맷은 1991년 처음 발표되었습니다.

- - - - - - - - - - - - - - - - - - - - - - -
WAVE media MIME types
Audio
audio/wave
audio/wav
audio/x-wav
audio/x-pn-wav
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WAVE가 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
ADPCM (Adaptive Differential Pulse Code Modulation)No
GSM 06.10No
LPCM (Linear Pulse Code Modulation)Yes
MPEG-1 Audio Layer III (MP3)No
µ-Law (u-Law)No
- -

WebM

- -

{{interwiki("wikipedia", "WebM")}} (Web Media)는 {{interwiki("wikipedia", "Matroska")}}에 기반하여 현대 웹 환경에서 사용하기 위해 디자인되었습니다. 특정 제품들은 WebM 컨테이너에 다른 코덱을 사용하기도 하지만 기본적으로는 무료 오픈 코덱을 사용하여 완전한 자유-오픈 기술을 지향하고 있습니다.

- -

WebM은 2010년 처음 소개되었습니다..

- - - - - - - - - - - - - - - -
WebM media MIME types
AudioVideo
audio/webmvideo/webm
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WebM이 지원하는 비디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
AV1Yes1
AVC (H.264)Yes2
VP8Yes
VP:9Yes
- -

[1] Firefox support for AV1 is currently disabled by default; it can be enabled by setting the preference media.av1.enabled to true.

- -

[2] Firefox support for H.264 relies upon the operating system's media infrastructure, so it is available as long as the OS supports it.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WebM이 지원하는 오디오 코덱
CodecBrowser support
ChromeEdgeFirefoxSafari
OpusYes
VorbisYes
- -

알맞은 컨테이너 선택하기

- -

여러분의 미디어 데이터에 알맞은 컨테이너를 선택하고 사용하기 위해서 몇 가지 고려해야 할 점들이 있습니다. 상대적으로 어떤 점이 더 중요한지는 요구사항이나 라이선스, 호환성, 타겟 고객 등에 따라 달라질 수 있습니다.

- -

가이드라인

- -

최선책 역시 미디어 데이터로 무엇을 하느냐에 달렸습니다. 미디어를 녹화/편집하는 것은 재생과 전혀 다른 이야기입니다. 최소한 노이즈 축적이라도 방지하려고 무손실 압축을 사용하면 매번 재 압축할 때 마다 압축 데이터가 누적되므로 미디어 데이터를 처리할때는 압축하지 않은 데이터를 사용하는게 퍼포먼스가 좋습니다.

- -
    -
  • 저사양 단말 또는 저속 네트워크를 사용하는 고객을 대상으로 하고 있다면 3GP 컨테이너와 적절한 압축 코덱을 고려해 볼 수 있습니다.
  • -
  • 인코딩시 필수 사항이 있다면 컨테이너 선택 시 적절한 코덱을 지원하는 지 확인해야 합니다.
  • -
  • 미디어가 상용이 아니며 오픈 포맷일 경우 FLAC(오디오), WebM(비디오) 등의 오픈 컨테이너 포맷을 고려해 보세요.
  • -
  • 어떠한 이유로 미디어를 한가지 포맷으로 제공해야 한다면 많은 디바이스와 브라우저에 널리 쓰여지는 MP3(오디오), MP4(비디오, 오디오)등의 포맷을 선택하세요.
  • -
  • 미디어가 오디오만 있다면 오디오 전용 컨테이너를 사용하는게 합당합니다. 현재는 특허가 모두 만료되어 널리 쓰여지는 MP3가 좋은 선택입니다. WAVE도 좋지만 비압축이므로 대용량 오디오 샘플의 경우에는 사용을 주의하세요. 모든 타겟 브라우저가 지원한다면 무손실 압축을 지원하는 FLAC이 최선입니다.
  • -
- -

슬픈 일이지만 주요 무손실 압축 포맷 (FLAC, ALAC) 모두 폭넓게 지원되고 있지 않습니다. 둘 중에 FLAC이 그나마 낫지만 macOS에서는 추가적인 소프트웨어 설치 없이는 지원을 안합니다. iOS에서는 아예 불가능하구요. 무손실 오디오를 플랫폼에 무관하게 제공하려면 FLAC과 ALAC 둘 다 지원해야 합니다.

- -

컨테이너 선택 가이드

- -

아래의 테이블은 다양한 시나리오에서 사용할 컨테이너에 대한 권고안입니다. 이는 추천일 뿐이며 컨테이너 포맷을 선택할 때에는 여러분의 제품이나 기관의 상황을 고려하여 선택하세요.

- -

오디오 전용 파일

- - - - - - - - - - - - - - - - - - - - - - -
만약에...추천 컨테이너 포맷
일반 재생 목적으로 압축 파일 사용MP3 (MPEG-1 Audio Layer III)
무손실 압축 파일FLAC with ALAC fallback
무압축 파일WAV
- -

이제는 MP3 특허가 모두 만료되었으므로 오디오 파일 선택은 별로 어려운 문제가 아닙니다. 폭넓게 쓰이는 MP3를 사용하면서 특허료를 내야 하느냐에 대한 고민을 할 필요가 없죠.

- -

비디오 파일

- - - - - - - - - - - - - - - - - - - - - - - - -
만약에...추천 컨테이너 포맷
가능한 오픈 포맷을 사용한 일반 비디오WebM (MP4 호환 추가)
일반 비디오MP4 (WebM, Ogg 호환 추가)
저속 네트워크상의 고효율 압축3GP (MP4 호환 추가)
구형 단말/브라우저 지원QuickTime (AVI, MPEG-2 호환 추가)
- -

몇 가지 가정 하의 권고입니다. 최종 결정 전에 여러가지를 따져보아야 하며 인코딩 해야 할 미디어가 많은 경우 특히나 심사숙고해야 합니다.

- -

다양한 컨테이너간 호환성 극대화

- -

호환성을 높이려면 한가지 버전 이상의 미디어 파일 제공을 고려해 볼 수 있습니다. {{HTMLElement("audio")}}, {{HTMLElement("video")}} 엘리먼트 아래에 {{HTMLElement("source")}} 엘리먼트를 추가하여 구현할 수 있죠. 예를 들어 Ogg, WebM 비디오를 우선하되 호환성을 위해 MP4 포맷을 추가할 수 있습니다. 레트로하게 QuickTime이나 AVI 호환을 추가하는 것도 좋은 방법입니다.

- -

구현하려면 우선 {{htmlattrxref("src", "video")}} 어트리뷰트 없이 <video> (또는 <audio>) 엘리먼트를 생성합니다. 그 후 <video> 엘리먼트 아래에 {{HTMLElement("source")}} 엘리먼트를 제공하려는 미디어 포맷별로 추가합니다. 이 방식은 대역폭 상황에 따라 소스를 선택하는 방식으로도 사용할 수 있지만 여기서는 포맷 옵션을 제공하기로 하죠.

- -

아래 예제에서는 두 포맷 타입의 비디오를 제공합니다: WebM and MP4.

- -
{{EmbedInteractiveExample("pages/tabbed/source.html", "tabbed-standard")}}
- - - -

첫번째 비디오는 WebM 포맷입니다({{htmlattrxref("type", "video")}} 어트리뷰트가 video/webm). {{Glossary("user agent")}}는 재생이 불가능 한 경우 type 이 video/mp4 인 다음 옵션으로넘어갑니다. 둘 다 재생이 불가능 할 경우 "This browser does not support the HTML5 video element." 문구가 표시됩니다.

- -

스펙

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SpecificationComment
ETSI 3GPP3GP 컨테이너 포맷 정의
ISO/IEC 14496-3 (MPEG-4 Part 3 Audio)ADTS 포함 한 MP4 오디오 정의
FLAC FormatFLAC 포맷 규정
ISO/IEC 11172-1 (MPEG-1 Part 1 Systems)MPEG-1 컨테이너 포맷 정의
ISO/IEC 13818-1 (MPEG-2 Part 1 Systems)MPEG-2 컨테이너 포맷 정의
ISO/IEC 14496-14 (MPEG-4 Part 14: MP4 file format)MPEG-4 (MP4) version 2 컨테이너 포맷 정의
ISO/IEC 14496-1 (MPEG-4 Part 1 Systems)오리지널 MPEG-4 (MP4) 컨테이너 포맷 정의
{{RFC(3533)}}Ogg 컨테이너 포맷 정의
{{RFC(5334)}}Ogg 미디어 타입 및 확장자 정의
QuickTime File Format SpecificationQuickTime movie (MOV) 포맷 정의
Multimedia Programming Interface and Data Specifications 1.0공식 WAVE 스펙에 가까운 문서
Resource Interchange File Format (used by WAV)RIFF 포맷 정의; WAVE는 RIFF의 한 형태
WebM Container GuidelinesWebM 용 Matroska 적용 가이드
Matroska SpecificationsWebM 기반 Matroska 컨테이너 포맷 스펙
WebM Byte Stream FormatMedia Source Extensions를 통한 WebM 바이트 스트림 포맷
- -

브라우저 호환성

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
컨테이너 포맷 이름오디오비디오
MIME typeExtension(s)Browser supportMIME typeExtension(s)Browser support
3GPaudio/3gpp.3gpFirefoxvideo/3gpp.3gpFirefox
ADTS (Audio Data Transport Stream)audio/aac.aacFirefox
FLACaudio/flac.flacFirefox
MPEG-1 / MPEG-2 (MPG or MPEG)audio/mpeg.mpg
- .mpeg
Firefoxvideo/mpeg.mpg
- .mpeg
Firefox
audio/mp3.mp3Firefox
MPEG-4 (MP4)audio/mp4.mp4
- .m4a
Firefoxvideo/mp4.mp4
- .m4v
- .m4p
Firefox
Oggaudio/ogg.oga
- .ogg
Firefoxvideo/ogg.ogv
- .ogg
Firefox
QuickTime Movie (MOV)video/quicktime.mov
WAV (Waveform Audiofile)audio/wav.wavFirefox
WebMaudio/webm.webmFirefoxvideo/webm.webmFirefox
- -

더 보기

- - diff --git "a/files/ko/web/media/formats/\354\275\224\353\215\261\355\214\214\353\235\274\353\257\270\355\204\260/index.html" "b/files/ko/web/media/formats/\354\275\224\353\215\261\355\214\214\353\235\274\353\257\270\355\204\260/index.html" deleted file mode 100644 index 43cce1aa1f..0000000000 --- "a/files/ko/web/media/formats/\354\275\224\353\215\261\355\214\214\353\235\274\353\257\270\355\204\260/index.html" +++ /dev/null @@ -1,971 +0,0 @@ ---- -title: 일반 미디어 타입에서 "codecs" 파라미터 사용하기 -slug: Web/Media/Formats/코덱파라미터 -translation_of: Web/Media/Formats/codecs_parameter ---- -
{{QuickLinksWithSubpages("/en-US/docs/Web/Media")}}
- -

기본적으로, video/mp4audio/mpeg 처럼 {{Glossary("MIME")}} 타입을 통해 미디어 파일 포맷을 명시할 수 있습니다. 하지만 많은 미디어 타입들이-특히 비디오 트랙을 지원하는 경우-가지고 있는 데이터 포맷에 대해 더 상세하고 정확하게 명시할 수 있습니다. 예를들어 MPEG-4 비디오라고 해서 MIME 타입을 video/mp4만 명시한다면 정확히 어떤 미디어를 가지고 있는 지 아무 정보도 알 수 없습니다.

- -

때문에 MIME 타입에 추가로 미디어 콘텐츠를 기술하기 위해 codecs 파라미터가 추가되었습니다. 이를 통해 컨테이너 특화된 정보를 제공할 수 있게 되었습니다 이 정보에는 비디오 코덱의 프로파일, 오디오 트랙 타입 등을 추가할 수 있습니다.

- -

이 가이드 문서는 단순히 컨테이너 타입 명시를 넘어 codecs 파라미터의 문법과 MIME 타입에 비디오/오디오 콘텐츠에 대한 상세 정보를 기술하는 방법에 대해 설명합니다.

- -

일반 문법

- -

기본적인 MIME 미디어 타입 표현은 미디어 타입(audio, video, 등)으로 시작하며, 슬래쉬 문자 (/) 후 미디어를 포함하고 있는 컨테이너 포맷이름으로 이어집니다:

- -
-
audio/mpeg
-
MP3 같은 MPEG 파일 타입의 오디오 파일입니다.
-
video/ogg
-
Ogg 파일 타입의 비디오 파일입니다.
-
video/mp4
-
MPEG-4 파일 타입을 사용하는 비디오입니다.
-
video/quicktime
-
애플 QuickTime 포맷을 사용하는 비디오입니다. 다른 곳에서 서술되어 있듯이, 한때는 웹에서 널리 쓰여지던 형식이었지만 현재는 플러그인이 필요하여 더 이상 사용하지 않는 타입입니다.
-
- -

위 MIME 타입은 아직 모호한 표현입니다. 각 파일 타입들은 많은 수의 코덱을 지원하며 코덱은 각기 프로파일, 레벨과 같은 설정 인자들을 가지고 있습니다. 그래서 codecs 파라미터를 추가하여 명시할 수 있습니다.

- -

세미콜론 (;)을 붙이고 codecs= 으로 시작하는 문자열을 덧붙여 콘텐츠의 포맷을 서술할 수 있습니다. 일부 미디어 타입은 사용하는 코덱 이름만 명시 가능할 수 있고 다른 미디어 타입은 코덱에 관한 다양한 인자를 기술할 수 있는 경우도 있습니다. 콤마로 구분하여 여러 코덱을 기술할 수도 있습니다.

- -
-
audio/ogg; codecs=vorbis
-
Vorbis 오디오 트랙을 포함하는 Ogg 컨테이너 파일입니다.
-
video/webm; codecs="vp8, vorbis"
-
VP8 비디오와 Vorbis 오디오를 포함하는 WebM 컨테이너 파일입니다.
-
video/mp4; codecs="avc1.4d002a"
-
AVC (H.264) 코덱에 Main Profile, Level 4.2을 가지는 MPEG-4 컨테이너 파일입니다.
-
- -

코덱의 속성 중 하나라도 퍼센트-인코딩이 필요한 특수문자{{RFC(2231, "MIME Parameter Value and Encoded Word Extensions", 4)}}를 사용하는 경우 MIME 타입을 기술하는 문자열의 codecs 파라미터를 codecs* (애스터리크(*) 추가됨에 유의)로 변경해야 합니다. JavaScript {{jsxref("Global_Objects/encodeURI", "encodeURI()")}} function으로 파라미터 목록을 인코딩할 수 있습니다; 반대로 {{jsxref("Global_Objects/decodeURI", "decodeURI()")}}를 통해 기인코딩된 파라미터 리스트를 디코딩할 수 있습니다.

- -
-

codecs 파라미터를 사용한다면, 파일 콘텐츠가 사용한 모든 코덱을 목록에 명시해야합니다. 목록에 파일이 사용하고 있지 않은 코덱을 명시하는 것도 가능합니다.

-
- -

컨테이너별 코덱 옵션

- -

아래 컨테이너들은 codecs 파라미터에 확장 옵션을 지원합니다:

- -
-
    -
  • {{anch("ISO-BMFF", "3GP")}}
  • -
  • {{anch("AV1")}}
  • -
  • {{anch("ISO-BMFF", "ISO BMFF")}}
  • -
  • {{anch("ISO-BMFF", "MPEG-4")}}
  • -
  • {{anch("ISO-BMFF", "QuickTime")}}
  • -
  • {{anch("WebM")}}
  • -
-
- -

링크를 클릭하면 동일한 섹션으로 이동할텐데요; 위 미디어 타입들은 모두 ISO Base Media File Format (ISO BMFF)를 기반하고 있어, 동일한 문법을 공유하기 때문입니다.

- -

AV1

- -

AV1의 codecs 문법은AV1 Codec ISO Media File Format Binding 스펙 문서의, 섹션 5: Codecs Parameter String에 정의되어 있습니다.

- -
av01.P.LLT.DD[.M[.CCC[.cp[.tc[.mc[.F]]]]]]
- -

아래 표에서 코덱 파라미터 문자열 구성요소에 대해 자세히 설명하고 있습니다. 각 요소들은 고정된 개수의 문자로 되어 있으며;고정 길이보다 짧은 경우 앞에 0을 붙여서 맞춰야 합니다..

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AV1 코덱 파라미터 문자열 요소
요소내용
P -

한자리 숫자 프로파일 번호:

- - - - - - - - - - - - - - - - - - - - - - - -
AV1 프로파일 번호
프로파일 번호설명
0"Main" 프로파일; YUV 4:2:0/모노크롬 크로마 서브샘플링 및 8/10 비트 색 깊이 지원.
1"High" 프로파일 4:4:4 크로마 서브샘플링 추가 지원.
2"Professional" 프로파일, 4:2:2 크로마 서브샘플링 및 12 비트 색 깊이 추가 지원
-
LL두자리 숫자 레벨 번호,  X.Y 형태의 레벨 포맷으로 변환 됨, X = 2 + (LL >> 2)Y = LL & 3. 자세한 내용은 AV1 스펙 문서의 Appendix A, section 3 참조.
T한자리 문자 티어 표시. Main 티어라면 (seq_tier equals 0), 문자는 M. High 티어는 (seq_tier is 1) H. High 티어는 4.0 이상 레벨에서만 가능합니다.
DD두자리 숫자 색 깊이. 8, 10, 12 중 하나여야 하며; 프로파일과 다른 속성에서 지원 가능한 값이여야 합니다.
M한자리 숫자 모노크롬 플래그; 0인 경우 비디오는 U, V, Y 성분을 모두 가지고 있습니다. 아닌 경우 전체 비디오 데이터는 Y(휘도) 성분 뿐으로 모노크롬 이미지를 가집니다. 자세한 내용은 {{SectionOnPage("/en-US/docs/Web/Media/Formats/Video_concepts", "YUV")}}를 참조하여 YUV 컬러 시스템이 어떻게 동작하는지 알아보세요. 기본 값은 0 (모노크롬 아님)입니다.
CCC -

CCC 는 세자리 숫자로 크로마 서브샘플링을 표기합니다. 첫번째 숫자는 subsampling_x, 두 번째 숫자는 subsampling_y. 둘다 1인경우, 세번째 값은 chroma_sample_position; 아닌 경우 세번째 값은 항상 0입니다. M 값과 더불어 크로마 서브샘플링 포맷을 구성하는 요소입니다:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
크로마 서브샘플링 결정 방식
subsampling_xsubsampling_yMonochrome flagChroma subsampling format
000YUV 4:4:4
100YUV 4:2:2
110YUV 4:2:0
111YUV 4:0:0 (Monochrome)
- -

CCC의 세번째 값은 크로마 샘플 위치(chroma sample position)로, 0은 위치를 알 수 없으며 디코딩 시 개별적으로 제공해야 함을 의미합니다; 1은 샘플이 (0, 0) 휘도 샘플과 동일한 수평선상에 있음을 의미합니다; 2는 샘플이 (0, 0) 휘도 샘플과 동일한 위치에 있음을 의미합니다.

- -

기본 값은 110 (4:2:0 크로마 서브샘플링)입니다.

-
cp두자리 숫자 color_primaries 값은 미디어의 색 공간을 표시합니다. 예를 들어 HDR 비디오에서 사용하는 BT.2020/BT.2100 색 공간은 09입니다. 자세한 정보-그 외의 색 공간 값을 포함하여-는 AV1 스펙 문서의 Color config semantics section 를 참조하세요. 기본값은 01 (ITU-R BT.709)입니다.
tc두자리 숫자 transfer_characteristics 값. 이 값은 소스에서 디스플레이로 감마를 매핑하는 함수(기술적인 용어로 "opto-electrical transfer function"라 표현)를 정의합니다. 예를 들어 10-bit BT.2020는 14입니다. 기본 값은 01 (ITU-R BT.709)입니다.
mc두자리 숫자 matrix_coefficients 상수는 RGB 컬러 채널을 휘도/색차 신호로 변환 시 사용할 계수 행렬을 선택합니다. 예를 들어 BT.709의 표준 계수 값은 01로 표현합니다. 기본 값은 01 (ITU-R BT.709)입니다.
F한자리 숫자로 색상이 가능한 모든 범위를 표현해야 할지(1), 지정한 색 설정에 의해 적합하다고 여겨지는 범위로 제한하여 표현(studio swing representation이라 표현)해야 할지를 나타내는 값입니다. 기본 값은 0 (studio swing representation 적용)입니다.
- -

M (모노크롬 플래그)이후의 요소는 모두 비필수입니다; 어느 곳에서부터나 생략할 수 있습니다 (하지만 임의의 중간 요소를 생략할 수는 없습니다). 기본 값은 위 표에 서술하였습니다. AV1 코덱 문자열 예시는 아래와 같습니다:

- -
-
av01.2.15M.10.0.100.09.16.09.0
-
AV1 Professional 프로파일, 레벨 5.3, Main 티어, 10 비트 색 깊이, 4:2:2 크로마 서브샘플링 ITU-R BT.2100 색 공간, 색 전환 YCbCr 색상 행렬. Studio swing representation 적용.
-
av01.0.15M.10
-
AV1 Main 프로파일, 레벨 5.3, Main 티어, 10 비트 색 깊이. 나머지 요소는 기본 값 사용: 4:2:0 크로마 서브 샘플링, BT.709 색 공간, 색 전환, 계수 행렬 사용. Studio swing representation.
-
- -

ISO Base Media File Format: MP4, QuickTime, and 3GP

- -

모든 미디어 타입은 {{interwiki("wikipedia", "ISO Base Media File Format")}} (ISO BMFF)를 기반으로 하며 codecs 문법을 공유합니다. 이들 미디어 타입은 MPEG-4 (또 사실상 MPEG-4를 기반으로 하고 있으므로 QuickTime도 포함)과 3GP를 포함합니다. MIME 타입의 codecs 파라미터를 통해 아래와 같이 비디오/오디오 트랙 둘 다 기술할 수 있습니다.:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ISO BMFF codecs 파라미터를 지원하는 기본 MIME 타입
MIME 타입설명
audio/3gpp3GP 오디오 ({{RFC(3839, "MIME Type Registrations for 3rd generation Partnership Project (3GP) Multimedia files")}})
video/3gpp3GP 비디오 ({{RFC(3839, "MIME Type Registrations for 3rd generation Partnership Project (3GP) Multimedia files")}})
audio/3gp23GP2 오디오 ({{RFC(4393, "MIME Type Registrations for 3GPP2 Multimedia files")}})
video/3gp23GP2 비디오 ({{RFC(4393, "MIME Type Registrations for 3GPP2 Multimedia files")}})
audio/mp4MP4 오디오 ({{RFC(4337, "MIME Type Registration for MPEG-4")}})
video/mp4MP4 비디오 ({{RFC(4337, "MIME Type Registration for MPEG-4")}})
application/mp4오디오/비디오가 아닌 MPEG-4 컨테이너 미디어
- -

codecs 파라미티에는 간단하게 컨테이너 명(3gp, mp4, quicktime, etc.)만 기술할 수도 있으며 컨테이너 명에 코덱 이름 및 설정 값을 함께 기술할 수도 있습니다. 각 코덱 등은 온점(.)으로 구분된 요소를 다수 가질 수 있습니다.

- -

codecs 값의 문법은 코덱마다 다릅니다; 하지만 항상 4 글자 코덱 구분자와 온점(.)으로 시작하며 데이터 포맷을 기술하기 위핸 Object Type Indication (OTI) 형식의 문자열이 뒤따릅니다. 대부분의 코덱에서 OTI는 두자리 16진수로 되어 있지만 AVC (H.264)는 6자리 16진수로 구성되어 있습니다.

- -

따라서 지원하는 코덱 문법은 아래와 유사합니다:

- -
-
cccc[.pp]* (Generic ISO BMFF)
-
cccc 는 4 글자 코덱 ID이며  pp는 0~2자리 인코딩 된 문자입니다.
-
mp4a.oo[.A] (MPEG-4 audio)
-
oo 는 미디어 콘텐츠를 더 정확하게 기술하는 Object Type Indication 값이며 A 는 한자리 숫자오디오 OTI입니다. OTI로 가능한 값은 MP4 Registration Authority 웹사이트의 Object Types page 페이지에서 확인할 수 있습니다. 예를들어 MP4 파일의 Opus 오디오는 mp4a.ad로 기술합니다. 자세한 내용은 {{anch("MPEG-4 audio")}}를 참조하세요.
-
mp4v.oo[.V] (MPEG-4 video)
-
마찬가지로 oo 는 미디어 콘텐츠를 명시하는 OTI 값이며, V 는 한자리 숫자 비디오 OTI 값입니다.
-
avc1.oo[.PPCCLL] (AVC video)
-
-

oo 는 콘텐츠를 명시하는 OTI 값이며, while PPCCLL 는 6자리 16진수로써 프로파일 넘버 (PP), 제약 플래그 (CC), 레벨 (LL)을 의미합니다. PP로 가능한 값은 {{anch("AVC profiles")}}를 참조하세요.

- -

제약 플래그는 1 비트 불리언 값이며, MSB는 flag 0(또는 일부에선 constraint_set0_flag)로 취급합니다. 그리고 이어지는 비트는 하나씩 번호가 높게 매겨집니다. 현재로썬 0부터 2번째 비트까지만 사용하며;나머지 5개의 비트는 반드시 0이어야합니다. 각 플래그의 의미는 사용하는 프로파일에 따라 달라집니다.

- -

레벨 값은 고정 소수점이므로 숫자 14 (10진법 20) 은 레벨 2.0을 의미하며 3D (10진법 61) 은 레벨 6.1을 의미합니다. 일반적으로 레벨 숫자가 높을 수록 스트림 대역폭이 높아 더 큰 크기의 비디오를 지원할 수 있습니다.

-
-
- -

AVC 프로파일

- -

아래의 AV 프로파일 넘버는 codecs 파라미터에서 사용하며 제약 요소 값은 CC로 사용할 수 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
codecs  파라미터에서 AVC 프로파일과 제약 요건을 명세하기 위한 값
프로파일넘버(Hex)제약 (byte)
Constrained Baseline Profile (CBP)
- CBP는 리소스가 제약점이 있거나 재생이 원활하지 못해 발생하는 이상 요소들을 최소화 해야 하는 경우 주요한 해결책입니다.
4240
Baseline Profile (BP)
- CBP와 유사하나 데이터 손실 방지와 복구 능력을 향상시킨 프로파일입니다.  CBP가 도입된 이후에는 이전만큼 널리 사용하고 있지는 않습니다. CBP 스트림은 모두 BP 스트림으로 간주할 수도 있습니다.
4200
Extended Profile (XP)
- 고효율 압축과 네트워크 전송시의 데이터 안정성, 스트림 스위칭을 고려한 프로파일입니다.
5800
Main Profile (MP)
- MPEG-4 포맷으로 전송하는 디지털 표준 TV 방송에서 사용하는 프로파일입니다. 고선명 TV(HDV)에서는 사용하지 않습니다. 2004년 —HDTV에서 사용하기 위해— High Profile이 추가된 이후 중요도가 감소하였습니다.
4D00
High Profile (HiP)
- 현재로써는 전파방송과 매체기반 HD 비디오에서 사용하는 주요 프로파일입니다. HD TV 방송과 블루레이 미디어에서 사용하고 있습니다.
6400
Progressive High Profile (PHiP)
- 필드 코딩 지원을 제거한 High Profile입니다.
6408
Constrained High Profile
- 양방향 예측 슬라이스("B-slices") 지원을 제거한 PHiP입니다.
640C
High 10 Profile (Hi10P)
- 10 비트 컬러 모드 지원을 제거한 High Profile입니다.
6E00
High 4:2:2 Profile (Hi422P)
- Hi10P에 4:2:2 크로마 서브샘플링과 최대 10비트 컬러 모드 지원을 추가한 프로파일입니다.
7A00
High 4:4:4 Predictive Profile (Hi444PP)
- Hi422P 및 Hi444PP에 4:4:4 크로마 서브샘플링(색차 샘플링 소거 없음)을 추가 지원한 프로파일입니다. 또한 최대 14비트 컬러 샘플과 효율적인 무손실 지역 코딩을 추가하였습니다. 각 프레임을 3개의 분리된 컬러 평면(각 평면은 모노크롬 프레임형태로 저장됩니다)으로 인코딩할 수 있는 옵션입니다.
F400
High 10 Intra Profile
- all-intra-frame에 High 10 제약이 걸린 프로파일입니다. 전문가 용 앱에 주로 쓰입니다.
6E10
High 4:2:2 Intra Profile
- all-intra-frame에 Hi422를 적용한 프로파일입니다.
7A10
High 4:4:4 Intra Profile
- all-intra-frame에 High 4:4:4 제약을 건 프로파일입니다.
F410
CAVLC 4:4:4 Intra Profile
- all-intra-frame에 High 4:4:4 제약, CAVLC 엔트로피 코딩만 사용하는 프로파일입니다.
4400
Scalable Baseline Profile
- 화상 회의, 감시 카메라 및 모바일 장치에서 쓰이는 프로파일로, {{interwiki("wikipedia", "SVC")}} Baseline Profile은 AVC의 Constrained Baseline profile에 기반하고 있습니다. 스트림의 베이스 레이어는 고품질로 제공되면서, 제약이 걸린 환경에서 대안이 될 수 있는 서브스트림을 다수 제공하는 방식입니다. 서브스트림은 해상도 감소, 낮은 프레임레이트, 압축률 저하 등을 조합하여 구성합니다.
5300
Scalable Constrained Baseline Profile
- 실시간 양방향 대화형 어플리케이션에서 주요 사용하는 프로파일입니다. WebRTC에서 아직 정식으로 지원하지는 않지만,  SVC를 활성화하여 WebRTC AP 개발 모드에서 사용해 볼 수 있습니다.
5304
Scalable High Profile
- 방송 및 스트리밍 어플리케이션에서 주로 사용합니다. 베이스(또는 최고 품질) 레이어에는 AVC High Profile이 반드시 포함되어야 합니다.
5600
Scalable Constrained High Profile
- 실시간 통신을 위한 Scalable High Profile의 서브셋 프로파일입니다.
5604
Scalable High Intra Profile
- 비디오 제작 어플리케이션을 위한 all-intra-frame 프로파일입니다.
5620
Stereo High Profile
- 양안 렌더링을 통한 스테레오스코픽(stereoscopic) 비디오를 지원하는 프로파일입니다. 양안 영상이 아닌 경우 High profile과 동일합니다.
8000
Multiview High Profile
- 시간 및 MVC inter-view 예측을 통한 2개 이상의 뷰를 지원하는 프로파일입니다. 필드 픽쳐 또는 매크로블록-어댑티브한 frame-field 코딩을 지원하지 않습니다.
7600
Multiview Depth High Profile
- High Profile에 기반하며 메인 서브스트림이 반드시 붙어야 합니다. 나머지 서브스트림들은 Stereo High Profile과 매칭되어야 합니다.
8A00
- -

MPEG-4 audio

- -

codecs 목록의 값 항목이 mp4a로 시작한다면, 문법은 아래와 같아야 합니다:

- -
mp4a.oo[.A]
- -

oo 는 두자리 16진수 Object Type Indication으로 미디어에 사용된 코덱 클래스를 표시합니다. OTI 값은 MP4 Registration Authority에서 규정하고 있으며 list of the possible OTI values에서 가용한 값을 확인할 수 있습니다. 특수한 값인 40; 이는 미디어가 MPEG-4 audio(ISO/IEC 14496 Part 3)임을 나타냅니다. 조금 더 자세히 말하자면, 세번째 컴포넌트—Audio Object Type—은 OTI 40 을 MPEG-4의 특정 하위 타입으로 범위를 좁히기 위해 추가하였습니다.

- -

Audio Object Type는 두자리 10진수로 이루어져 있습니다(codecs 파라미터의 다른 값은 대부분 16진수). 예를들어 MPEG-4 AAC-LC의 오디오 오브젝트 타입은 숫자 2이므로 AAC-LC의 전체 codecs 표현 값은 mp4a.40.2 입니다.

- -

그러므로 오디오 오브젝트 타입이 17인 ER AAC LC의 전체 codecs 값은 mp4a.40.17 입니다. 한자리 숫자는 한자리로 표현하거나(폭넓게 호환되므로 최선) 앞에 0을 붙여 두자리로 표현할 수 있습니다. mp4a.40.02 처럼요.

- -
-

Note: 원래 Audio Object Type은 한자리 숫자로 규정되었었습니다. 시간이 지나면서 표준을 확장하였고 현재는 한자리 또는 두자리 숫자입니다. 10 미만의 값 앞에 0 을 붙이는건 필수가 아닙니다. 오래된 MPEG-4 코덱 구현체들은 두자리 숫자를 지원하지 못할 수도 있습니다. 따라서 호환성을 높이기 위해선 한자리로 표현해야 합니다.

-
- -

Audio Object Types는 ISO/IEC 14496-3 subpart 1, section 1.5.1에서 정의하고 있습니다. 아래 표는 Audio Object Type 기본 목록과 지원하는 프로필입니다. MPEG-4 audio type의 내부에 대해서 더 알고 싶다면 레퍼런스를 참조하세요.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MPEG-4 audio object types
IDAudio Object TypeProfile support
0NULL
1AAC MainMain
2AAC LC (Low Complexity)Main, Scalable, HQ, LD v2, AAC, HE-AAC, HE-AAC v2
3AAC SSR (Scalable Sampling Rate)Main
4AAC LTP (Long Term Prediction)Main, Scalable, HQ
5SBR (Spectral Band Replication)HE-AAC, HE-AAC v2
6AAC ScalableMain, Scalable, HQ
7TwinVQ (Coding for ultra-low bit rates)Main, Scalable
8CELP (Code-Excited Linear Prediction)Main, Scalable, Speech, HQ, LD
9HVXC (Harmonic Vector Excitation Coding)Main, Scalable, Speech, LD
10 – 11Reserved
12TTSI (Text to Speech Interface)Main, Scalable, Speech, Synthetic, LD
13Main SyntheticMain, Synthetic
14Wavetable Synthesis
15General MIDI
16Algorithmic Synthesis and Audio Effects
17ER AAC LC (Error Resilient AAC Low-Complexity)HQ, Mobile Internetworking
18Reserved
19ER AAC LTP (Error Resilient AAC Long Term Prediction)HQ
20ER AAC Scalable (Error Resilient AAC Scalable)Mobile Internetworking
21ER TwinVQ (Error Resilient TwinVQ)Mobile Internetworking
22ER BSAC (Error Reslient Bit-Sliced Arithmetic Coding)Mobile Internetworking
23ER AAC LD (Error Resilient AAC Low-Delay; used for two-way communiation)LD, Mobile Internetworking
24ER CELP (Error Resilient Code-Excited Linear Prediction)HQ, LD
25ER HVXC (Error Resilient Harmonic Vector Excitation Coding)LD
26ER HILN (Error Resilient Harmonic and Individual Line plus Noise)
27ER Parametric (Error Resilient Parametric)
28SSC (Sinusoidal Coding)
29PS (Parametric Stereo)HE-AAC v2
30MPEG Surround
31Escape
32MPEG-1 Layer-1
33MPEG-1 Layer-2 (MP2)
34MPEG-1 Layer-3 (MP3)
35DST (Direct Stream Transfer)
36ALS (Audio Lossless)
37SLS (Scalable Lossless)
38SLS Non-core (Scalable Lossless Non-core)
39ER AAC ELD (Error Resilient AAC Enhanced Low Delay)
40SMR Simple (Symbolic Music Representation Simple)
41SMR Main (Symbolic Music Representation Main)
42Reserved
43SAOC (Spatial Audio Object Coding)[1]
44LD MPEG Surround (Low Delay MPEG Surround)[1]
45 and upReserved
- -

[1] SAOC and LD MPEG Surround are defined in ISO/IEC 14496-3:2009/Amd.2:2010(E).

- -

WebM

- -

WebM codecs 파라미터의 기본 형은 4개의 WebM 코덱 중 하나 이상의 이름을 콤마로 구분합니다. 아래 표는 예시입니다.:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WebM MIME codecs 파라미터 예시
MIME 타입설명
video/webm;codecs="vp8"VP8 코덱 WebM 비디오; 오디오 미정의.
video/webm;codecs="vp9"VP9 코덱 WebM 비디오.
audio/webm;codecs="vorbis"Vorbis 오디오 WebM 파일.
audio/webm;codecs="opus"Opus 오디오 WebM 파일.
video/webm;codecs="vp8,vorbis"VP8 비디오 코덱, Vorbis 오디오 코덱 포함된 WebM 파일.
video/webm;codecs="vp9,opus"A WebM container with VP9 video and Opus audio.
- -

vp8.0vp9.0 문자열도 가능하지만, 비추천합니다.

- -

ISO Base Media File Format 문법

- -

codecs 파라미터를 표준화하고 강력한 포맷으로 발전시키기 위해, WebM은 ISO Base Media File Format 에 정의된 문법에 따라 비디오 콘텐츠를 기술하기 시작했습니다. 본 문법은 VP Codec ISO Media File Format Binding의, Codecs Parameter String 섹션에 정의되어 있습니다. 오디오 코덱은 vorbis 또는 opus로 표시되어 있습니다.

- -

codecs 파리미터는 사용한 코덱을 나타내는 4자리 문자로 시작하고 온점(.)으로 구분된 2자리 숫자가 반복됩니다.

- -
cccc.PP.LL.DD.CC[.cp[.tc[.mc[.FF]]]]
- -

처음부터 5개 요소는 필수이며; cp (color primaries) 부터는 옵션입니다.; 이후로는 어디서든 끊을 수 있습니다. 각 요소는 아래 표에 설명하고 있으며 예시가 첨부되어 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WebM codecs parameter components
ComponentDetails
cccc -

4자리 코드로 사용 가능한 코덱을 명시합니다. 가능한 값은 아래와 같습니다:

- - - - - - - - - - - - - - - - - - - - - - - -
Web-M 지원 코덱 4자리 코드
Four-character codeCodec
vp08VP8
vp09VP9
vp10VP10
-
PP -

2자리 숫자 프로파일 코드. 필요하다면 두자리를 맞추기 위해 앞에 0을 추가합니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - -
WebM 프로파일 숫자
프로파일설명
00크로마 서브샘플링 4:2:0(수직/수평 서브샘플링)만 허용. 색상 컴포넌트 당 8비트만 허용.
01크로마 서브샘플링 전체 허용. 색상 컴포넌트 당 8비트만 허용.
02크로마 서브샘플링 4:2:0만 허용. 색상 컴포넌트 당 8, 10, 12비트 허용.
03크로마 서브샘플링 전체 허용. 색상 컴포넌트 당 8, 10, 12비트 허용
-
LL두 자리 숫자 레벨 코드. 레벨 넘버는 고정 소수점 표기로 첫번째 숫자가 1의 자리, 두번째 숫자가 소수점 미만 첫번째 자리를 의미합니다. 예를 들어 레벨 3은 30 레벨 6.1은 61.
DD휘도, 색상 컴포넌트의 비트 심도를 표기합니다. 가능한 값은 8, 10, 12입니다.
CC -

크로마 서브샘플링 포맷을 2자리 숫자로 표기합니다. 가능한 값은 아래 표에 있습니다; 자세한 내용은 {{SectionOnPage("en-US/docs/Web/Media/Formats/Video_concepts", "Chroma subsampling")}} 를 참조하세요.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
WebM 크로마 서브샘플링 구분자
크로마 서브샘플링 포맷
004:2:0 with the chroma samples sited interstitially between the pixels
014:2:0 chroma subsampling with the samples colocated with luma (0, 0)
024:2:2 chroma subsampling (4 out of each 4 horizontal pixels' luminance are used)
034:4:4 chroma subsampling (every pixel's luminance and chrominance are both retained)
04Reserved
-
cp -

ISO/IEC 23001-8:2016 표준 Section 8.1에 명시되어있는 색 공간을 두자리 숫자로 표현합니다. 본 요소와 이후 요소는 전부 비필수값입니다.

- -

Color primaries 요소에 가능한 값은 아래와 같습니다.:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ISO/IEC Color primary identifiers
ValueDetails
00ITU과 ISO/IEC에 의해 예약됨
01고선명 화질(HD) TV 표준인 BT.709, sRGB, sYCC. BT.709; sRGB는 컴퓨터 모니터에서 쓰이는 가장 일반적인 색 공간입니다. Broadcast BT.709는 8비트 색 심도를 사용하여 16(Black)부터 235(White)까지 리갈 레인지를 표현합니다.
02알 수 없거나 application에서 활용하기 위해 사용합니다.
03ITU과 ISO/IEC에 의해 예약됨
04BT.470 System M, NTSC (미국 내 표준 화질 TV 표준)
05BT.470 System B, G; BT.601; BT.1358 625; BT.1700 625 PAL and 625 SECAM
06BT.601 525; BT.1358 525 or 625; BT.1700 NTSC; SMPTE 170M. 7과 동일함.
70{{Glossary("SMPTE")}} 240M (historical). Functionally identical to 6과 동일함.
08일반 필름
09BT.2020; BT.2100. UHD (4K) High Dynamic Range (HDR) 영상에서 사용 매우 넓은 색 표현력과 10비트 12비트 색상 컴포넌트 지원.
10SMPTE ST 428 (D-Cinema Distribution Master: Image characteristics). DCDM을 위한 비압축 형식.
11SMPTE RP 431 (D-Cinema Quality: Reference projector and environment). 필름 표현의 지속적 경험을 위한 레퍼런스 프로젝터와 환경 조건에 대해 기술.
12SMPTE EG 432 (Digital Source Processing: Color Processing for D-Cinema). 디지털 영화를 위한 색신호 디코딩의 기술적 가이드라인.
13 – 21ITU과 ISO/IEC에 의해 예약됨
22EBU Tech 3213-E
23 – 255ITU과 ISO/IEC에 의해 예약됨
-
tc비디오의 transferCharacteristics 값을 2자리 숫자로 표현. This value is from Section 8.2 of ISO/IEC 23001-8:2016 Section 8.2에 기술되어 있으며 디코딩된 색상을 렌더링 타겟에 맞출 때 transfer characteristics 을 정의합니다.
mcmatrixCoefficients 속성 값을 2자리 숫자로 표현 ISO/IEC 23001-8:2016 스펙 Section 8.3 표에서 기술. 이 값은 native red, blue, green 색상을 휘도, 색차 신호에 매핑하는데 사용합니다. 이 계수들이 방정식에서 어떻게 사용되는지 같은 섹션에서 확인할 수 있습니다.
FF색상 컴포넌트의 검정 수준과 색상 범위를 리갈 레인지로 제한할지 여부를 표시합니다. 예를들어 8비트 색상의 경우 리갈 레인지는 16~235입니다. 값이 00 인 경우 강제로 제한하며,  01 인 경우 결과물의 색상이 컬러 시스템의 범위를 벗어나더라도 각 컴포넌트 별로 가능한 풀 레인지 값을 허용합니다.
- -

WebM media type 예시

- -
-
video/webm;codecs="vp08.00.41.08,vorbis"
-
VP8 비디오, 프로파일 0 레벨 4.1, 8-bit YUV 4:2:0 크로마 서브샘플링, BT.709 색 공간, 변환 함수, 행렬 계수, 휘도 색차 값은 ("studio") 리갈 레인지로 인코딩 됨. 오디오는 Vorbis.
-
video/webm;codecs="vp09.02.10.10.01.09.16.09.01,opus"
-
VP9 비디오, 프로파일 2 레벨?1.0, 10-bit YUV 4:2:0 크로마 서브샘플링, BT.2020 색 공간, ST 2084 EOTF (HDR SMPTE), BT.2020 비상수 휘도 색상 행렬, 풀 레인지 휘도 색차 인코딩non-constant luminance color matrix, and full-range chroma and luma encoding. 오디오는 Opus 포맷.
-
- -

codecs 파라미터 사용하기

- -

codecs 파라미터를 여러 상황에서 사용할 수 있습니다. 먼저 {{HTMLElement("audio")}} , {{HTMLElement("video")}} 엘레먼트 생성 시 {{HTMLElement("source")}} 엘레먼트에 사용하여 브라우저로 하여금 사용할 미디어 포맷에 대한 옵션을 제공하는거죠..

- -

{{domxref("MediaSource.isTypeSupported()")}} 메소드에 MIME 타입을 명시적으로 전달하는데 사용할 수도 있습니다.; 이 메소드는 현재 장치에서 주어진 미디어 포맷을 재생할 수 있는지 여부를 불리언 값으로 반환합니다.

- -

더 보기

- - diff --git a/files/ko/web/performance/critical_rendering_path/index.html b/files/ko/web/performance/critical_rendering_path/index.html new file mode 100644 index 0000000000..0dd28ed81c --- /dev/null +++ b/files/ko/web/performance/critical_rendering_path/index.html @@ -0,0 +1,60 @@ +--- +title: 중요 렌더링 경로 +slug: Web/Performance/중요_렌더링_경로 +translation_of: Web/Performance/Critical_rendering_path +--- +

{{draft}}

+ +

중요 렌더링 경로 (Critical Rendering Path)는 브라우저가 HTML, CSS, Javascipt를 화면에 픽셀로 변화하는 일련의 단계를 말하며 이를 최적화하는 것은 렌더링 성능을 향상시킵니다. 중요 렌더링 경로는 Document Object Model (DOM), CSS Object Model (CSSOM), 렌더 트리 그리고 레이아웃을 포함합니다.

+ +

도큐먼트 오브젝트 모델은 HTML을 분석함으로써 만들어집니다. HTML은 Javascript를 요청할 수 있으며, 이 경우 DOM 이 변경될 수 있습니다. HTML은 차례대로 CSS 오브젝트 모델을 만들기 위한 스타일에 대한 요청을 만들거나 포함합니다. 브라우저 엔진은 이 두가지를 결합하여 렌더 트리를 생성하며 레이아웃은 페이지의 모든 것에 대한 크기와 위치를 결정합니다. 일단 레이아웃이 결정되면 화면에 픽셀을 그립니다.

+ +

중요 렌더링 경로 최적화는 첫번째 렌더링의 시간을 개선시킵니다. 중요 렌더링 경로를 이해하고, 최적화 하는 것은 뛰어난 사용자 상호작용을 보장하며 버벅거림을 피할 수 있도록 하고, 1초당 60 프레임에 리플로우와 리페인트가 발생할 수 있도록 하는데 중요합니다.

+ +

CRP 이해하기

+ +

웹 성능은 서버의 요청과 응답, 로딩, 스크립팅, 렌더링, 레이아웃 그리고 화면에 픽셀 그리기를 포함합니다.

+ +

웹 페이지 또는 어플리케이션에 대한 요청은 HTML 요청으로 시작됩니다. 서버는 응답 헤더 또는 데이터로 HTML을 반환합니다. 그리고 나서 브라우저는 HTML을 분석하고 수신된 바이츠를 DOM 트리로 변환하기 시작합니다. 브라우저는 스타일시트, 스크립트 또는 포함된 이미지 참조인 외부 자원에 대한 링크를 찾을때마다 요청을 시작합니다. 불러온 에셋을 다룰 때까지 나머지 HTML을 분석하는 작업하는 일부 요청은 중단되며 차단됩니다. 브라우저는 CSS 오브젝트 모델을 구축하는 작업이 끝날때까지 요청을 만들고 DOM을 생성하는 HTML을 계속해서 분석합니다. DOM과 CSSOM이 완료되면 브라우저는 렌더 트리를 생성하고 보여지는 컨텐츠를 위해 스타일을 계산합니다. 렌더트리가 완료된 후 모든 렌더 트리 요소들에 대한 위치와 크기가 정의된 레이아웃이 만들어집니다. 일단 완료되면 레이지는 렌더링되거나 또는 화면에 '그려집니다(painted)'.

+ +

Document Object Model

+ +

DOM 구성은 점진적으로 증가합니다. HTML 응답은 토큰으로, 토큰은 노드로, 노드는 DOM 트리로 변환됩니다.1개의 DOM 노드는 시작태그 토큰으로 시작해서 끝태그 토큰으로 끝납니다. 노드들은 HTML 요소에 대한 모두 연관성 있는 정보를 포함하고 있습니다. 그 정보는 토큰을 통해 설명됩니다. 노드들은 토큰의 위계서열을 기반으로 DOM 트리안에 연결됩니다. 만약 또 다른 시작태그와 끝태그의 묶음이 한 세트의 시작태그와 끝태그 사이에 있다면, 여러분은 DOM 트리의 위계서열을 정의하는 방법으로 노드 안에 노드를 가지게 됩니다.

+ +

많은 수의 노드는 중요 렌더링 경로에서 다음의 이벤트를 더 오래 발생시킬 것입니다. 측정하세요! 몇 개의 추가 노드는 차이를 만들지 않지만 전염은 버벅거림을 유발할 수 있습니다.

+ +

CSS Object Model

+ +

DOM은 페이지의 모든 컨텐츠를 포함하고, CSSOM은 DOM을 스타일링 하기 위한 페이지의 모든 스타일 정보를 포함합니다. CSSOM은 DOM과 유사하지만 다릅니다. DOM의 구조는 점진적으로 증가하는 반면에 CSSOM은 그렇지 않습니다. CSS는 렌더링을 막습니다: 브라우저는 모든 CSS를 처리하고 수신할때까지 페이지 렌더링을 막습니다. CSS는 규칙을 덮어쓸수 있기 때문에 렌더링을 막습니다. 그러므로 CSSOM이 완료될때까지 콘텐츠를 렌더링 할 수 없습니다.

+ +

CSS는 유효한 토크들은 인식하기 위해 스스로 규칙 세트를 가지고 있습니다. CSS의 C가 'Cascade(종속 또는 폭포)'라는 의미를 기억해두세요. CSS 규칙은 아래로 종속됩니다. 분석기는 토큰을 노드로 변환할때, 하위 노드가 스타일을 상속합니다. 연속적인 규칙들이 이전의 규칙들에 덮어쓰여질 수 있기 때문에, 증감 처리 기술은 HTML 처럼 CSS에 적용되지는 않습니다. CSS 개체 모델은 CSS를 분석할 때 빌드되지만 나중에 분석되 덮어쓸 스타일들은 화면에 렌더링 할 수 없기 때문에 완전히 분석될 때까지 렌더 트리를 생성하는데 사용할 수 없습니다.

+ +

선택자 성능 측면에서, 덜 구체적인 선택자는 더 구체적인 선택자보다 더 빠릅니다. 예를 들어, 브라우저가 .foo 찾을때, .foo {}.bar .foo {} 보다 빠릅니다. 왜냐하면 두번째 시나리오에서, .foo 가 부모 객체인 .bar 를 가지고 있는지 확인하기 위해 DOM을 거슬러 올라가기 때문입니다. 더 구체적인 태그는 브라우저에게 더 많은 작업을 요구하지만 이러한 패널티는 최적화 할 가치가 없습니다.

+ +

만약 CSS 분석 시간을 측정한다면, 브라우저들이 정말 빠르다는 것에 놀랄 것입니다. 규칙이 구체적일수록 DOM 트리 안에서 더 많은 노드들은 지나야 하기 때문에 더 높은 비용이 듭니다. 그러나 추가적인 비용은 일반적으로 최소입니다. 첫번째는 측정입니다. 필요할때 최적화하세요. 특정 짓는 것은 쉬운 일이 아닙니다. CSS 측면에서, 선택자 성능 최적화와 개선은 오직 microsecond 밖에 되지 않될 것입니다. 축소화와 미디어 쿼리를 사용함으로써 지연된 CSS를 논-블로킹 요청으로 분리하는 것과 같은 CSS 최적화를 위한 다른 방법이 있습니다.

+ +

Render Tree

+ +

렌터 트리는 콘텐츠와 스타일 둘다 캡쳐합니다. DOM과 CSSOM 트리는 렌더 트리에 결합됩니다. 렌더 트리를 구성하기 위해 브라우저는 DOM 트리의 root에서 시작해 모든 노드는 확인하면서 어떤 CSS 규칙들을 첨부할지 결정합니다.

+ +

렌더 트리는 오직 보여지는 콘텐츠만은 캡쳐합니다. (일반적으로) 헤드 섹션은 보여지는 정보를 포함하고 있지 않으므로 렌더트리 안에 포함되지 않습니다. 만약 요소에 display: none 이 적용되어 있다면, 해당 요소 또는 하위 요소는 포함되지 않습니다.

+ +

Layout

+ +

일단 렌더 트리가 생성되고 나면, 레이아웃은 가능해지며 화면의 크기에 의존합니다. 레이아웃 단계는 요소들이 페이지에서 배치되는 위치와 방법, 각 요소의 너비와 높이 그리고 서로 관련된 위치를 결정합니다.

+ +

요소의 너비는 무엇일까요? 정의에 따르면, 블럭 수준의 요소들은 그 부모 너비의 기본 너비값의 100% 입니다. 50%의 너비를 갖는 요소는 부모 요소의 절반일 것입니다. 비록 그렇게 정의되어 있지 않더라고, body 는 뷰포트 너비의 100%를 의미하는 너비 입니다. 디바이스의 너비는 레이아웃에 영향을 미칩니다.

+ +

뷰포트 메타 태그는 레이아웃에 영향을 미치는 뷰포트 레이아웃의 너비로 정의합니다. 이 태그 없다면, 브라우저는 뷰포트 기본값을 사용합니다. 브라우저의 full screen 기본값은 일반적으로 960px 입니다. 기본적으로 브라우저의 full screen에서, 스마트폰의 브라우저와 같은 너비는 <meta name="Viewport" content="width=device-witdh"> 로 세팅함으로써 기본 뷰포트 너비 대신에 디바이스의 너비를 사용합니다. 디바이스 너비는 사용자가 디비이스를 가로(landscapre) 또는 세로(portrait) 모드 사이로 돌릴때마다 바뀝니다. 레이아웃은 디바이스가 회전하거나 브라우저의 사이즈가 조정될 때마다 발생합니다.

+ +

레이아웃 성능은 DOM의 영향을 받습니다. 노드의 수가 많을수록 레이아웃은 더 길어지며 스크롤링 또는 다른 애니메이션들이 필요하다면 레이아웃에 쟁크(jank)를 일으키는 병목현상이 발생할 수 있습니다. 로딩 또는 방향 전환에 20ms 정도 밀릴 수 있지만 애니메이션 또는 스크롤에 쟁크(jank) 유발할 수 있습니다. 노드에 박스 모델 업데이트, 콘텐츠 대체 그리고 노드 추가와 같은 수정은 언제든지 렌더 트리를 수정할 수 있으며 레이아웃을 형성합니다.

+ +

레이아웃 이벤트의 반복과 형성시간을 줄이기 위해서 일괄 업데이트 해야하고, 박스 모델 속성을 애니메이션화 하지 말아야 합니다.

+ +

Paint

+ +

마자믹 단계는 화면에 픽셀을 그리는 것입니다. 일단 렌더 트리가 생성되고 레이아웃나 나타나기 시작하면, 화면에 픽셀을 그릴수 있습니다. 로드시, 전체 화면을 그립니다. 그 후에는 브라우저가 필요한 최소 영역만을 다시 그리도록 최적화되어 있기 때문에 영향을 받는 영역만을 화면에 다시 그립니다. 그리는 시간은 렌터 트리에 적용되는 업데이트의 종류가 무엇있냐에 따라 달라집니다. 페인팅인 매우 빠르게 진행되는 과정이기 때문에 성능 향상에 집중해야 하는 가장 큰 영향있는 부분이 아닐 수 있지만, 애니메이션 프레임 소요시간을 측정할때, 레이아웃과 리페인트 시간을 모두 고려하는 것이 중요합니다. 각 노드에 적용된 스타일은 페인트 시간을 증가시키지만 페인트 시간을 0.001ms 증가시키는 스타일을 제거하는 것은 여러분의 최적화 비용이 매우 커지는 것을 막지 못할 수 있습니다. 첫째는 측정하는 것을 기억하고, 최적화 우선순위를 정해야할지 말지를 결정해야 합니다.

+ +

Optimizing for CRP

+ +

자원 로드 순서를 관리하고, 파일 사이즈를 줄이며 어떤 자원을 먼저 로드할지 정함으로써 페이지 로드 속도를 개선하세요. 성능 팁으로는 1) 자원 다운로드를 연기함으로써 중요 자원들의 수를 최소화하기 , 2) 각 요청에 대한 파일 사이즈에 따라 필수적인 요청 횟수 최적하하기, 3) 다운받을 중요 에셋의 우선순위를 정함으로써 중요 자원 불러오는 순서 최적화하고, 중요 경로 길이 최소화하기

diff --git a/files/ko/web/performance/how_browsers_work/index.html b/files/ko/web/performance/how_browsers_work/index.html new file mode 100644 index 0000000000..473e30980d --- /dev/null +++ b/files/ko/web/performance/how_browsers_work/index.html @@ -0,0 +1,204 @@ +--- +title: '웹페이지를 표시한다는 것: 브라우저는 어떻게 동작하는가' +slug: Web/Performance/브라우저는_어떻게_동작하는가 +translation_of: Web/Performance/How_browsers_work +--- +

Users want web experiences with content that is fast to load and smooth to interact with. Therefore, a developer should strive to achieve these two goals.

+ +

To understand how to improve performance and perceived performance, it helps to understand how the browser works.

+ +

개요

+ +

Fast sites provide better user experiences. Users want and expect web experiences with content that is fast to load and smooth to interact with.

+ +

Two major issues in web performance are understanding issues having to do with latency and issues having to do with the fact that for the most part, browsers are single threaded.

+ +

Latency is our main threat to overcome to ensure a fast load. To be fast to load, the developers’ goals include sending requested information as fast as possible, or at least seem super fast. Network latency is the time it takes to transmit bytes over-the-air to computers. Web performance is what we have to do to make the page load happen as quickly as possible.

+ +

For the most part, browsers are considered single threaded. For smooth interactions, the developer's goal is to ensure performant site interactions, from smooth scrolling to being responsive to touch. Render time is key, with ensuring the main thread can complete all the work we throw at it and still always be available to handle user interactions. Web performance can be improved by understanding the single-threaded nature of the browser and minimizing the main thread's responsibilities, where possible and appropriate, to ensure rendering is smooth and responses to interactions are immediate.

+ +

여정

+ +

Navigation is the first step in loading a web page. It occurs whenever a user requests a page by entering a URL into the address bar, clicking a link, submitting a form, as well as other actions.

+ +

One of the goals of web performance is to minimize the amount of time a navigation takes to complete. In ideal conditions, this usually doesn't take too long, but latency and bandwidth are foes which can cause delays.

+ +

DNS Lookup

+ +

The first step of navigating to a web page is finding where the assets for that page are located. If you navigate to https://example.com, the HTML page is located on the server with IP address of 93.184.216.34. If you’ve never visited this site, a DNS lookup must happen.

+ +

Your browser requests a DNS lookup, which is eventually fielded by a name server, which in turn responds with an IP address. After this initial request, the IP will likely be cached for a time, which speeds up subsequent requests by retrieving the IP address from the cache instead of contacting a name server again.

+ +

DNS lookups usually only need to be done once per hostname for a page load. However, DNS lookups must be done for each unique hostname the requested page references. If your fonts, images, scripts, ads, and metrics all have different hostnames, a DNS lookup will have to be made for each one.

+ +

Mobile requests go first to the cell tower, then to a central phone company computer before being sent to the internet

+ +

This can be problematic for performance, particularly on mobile networks. When a user is on a mobile network, each DNS lookup has to go from the phone to the cell tower to reach an authoritative DNS server. The distance between a phone, a cell tower, and the name server can add significant latency.

+ +

TCP Handshake

+ +

Once the IP address is known, the browser sets up a connection to the server via a {{glossary('TCP handshake','TCP three-way handshake')}}. This mechanism is designed so that two entities attempting to communicate—in this case the browser and web server—can negotiate the parameters of the network TCP socket connection before transmitting data, often over {{glossary('HTTPS')}}.

+ +

TCP's three way handshaking technique is often referred to as "SYN-SYN-ACK"—or more accurately SYN, SYN-ACK, ACK—because there are three messages transmitted by TCP to negotiate and start a TCP session between two computers. Yes, this means three more messages back and forth between each server, and the request has yet to be made.

+ +

TLS Negotiation

+ +

For secure connections established over HTTPS, another "handshake" is required. This handshake, or rather the {{glossary('TLS')}} negotiation, determines which cipher will be used to encrypt the communication, verifies the server, and establishes that a secure connection is in place before beginning the actual transfer of data. This requires three more round trips to the server before the request for content is actually sent.

+ +

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.

+ +

While making the connection secure adds time to the page load, a secure connection is worth the latency expense, as the data transmitted between the browser and the web server cannot be decrypted by a third party.

+ +

After the 8 round trips, the browser is finally able to make the request.

+ +

응답

+ +

Once we have an established connection to a web server, the browser sends an initial HTTP GET request on behalf of the user, which for websites is most often an HTML file. Once the server receives the request, it will reply with relevant response headers and the contents of the 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>
+ +

This response for this initial request contains the first byte of data received. {{glossary('Time to First Byte')}} (TTFB) is the time between when the user made the request—say by clicking on a link—and the receipt of this first packet of HTML. The first chunk of content is usually 14kb of data.

+ +

In our example above, the request is definitely less than 14Kb, but the linked resources aren't requested until the browser encounters the links during parsing, described below.

+ +

TCP Slow Start / 14kb rule

+ +

The first response packet will be 14Kb. This is part of {{glossary('TCP slow start')}}, an algorithm which balances the speed of a network connection. Slow start gradually increases the amount of data transmitted until the network's maximum bandwidth can be determined.

+ +

In {{glossary('TCP slow start')}}, after receipt of the initial packet, the server doubles the size of the next packet to around 28Kb. Subsequent packets increase in size until a predetermined threshold is reached, or congestion is experienced.

+ +

TCP slow start

+ +

If you’ve ever heard of the 14Kb rule for initial page load, TCP slow start is the reason why the initial response is 14Kb, and why web performance optimization calls for focusing optimizations with this initial 14Kb response in mind. TCP slow start gradually builds up transmission speeds appropriate for the network's capabilities to avoid congestion.

+ +

Congestion control

+ +

As the server sends data in TCP packets, the user's client confirms delivery by returning acknowledgements, or ACKs. The connection has a limited capacity depending on hardware and network conditions. If the server sends too many packets too quickly, they will be dropped. Meaning, there will be no acknowledgement. The server registers this as missing ACKs. Congestion control algorithms use this flow of sent packets and ACKs to determine a send rate.

+ +

파싱

+ +

Once the browser receives the first chunk of data, it can begin parsing the information received. {{glossary('speculative parsing', 'Parsing')}} is the step the browser takes to turn the data it receives over the network into the {{glossary('DOM')}} and {{glossary('CSSOM')}}, which is used by the renderer to paint a page to the screen.

+ +

The DOM is the internal representation of the markup for the browser. The DOM is also exposed, and can be manipulated through various APIs in JavaScript.

+ +

Even if the request page's HTML is larger than the initial 14KB packet, the browser will begin parsing and attempting to render an experience based on the data it has. This is why it's important for web performance optimization to include everything the browser needs to start rendering a page, or at least a template of the page - the CSS and HTML needed for the first render -- in the first 14 kilobytes. But before anything is rendered to the screen, the HTML, CSS, and JavaScript have to be parsed.

+ +

Building the DOM tree

+ +

We describe five steps in the critical rendering path.

+ +

The first step is processing the HTML markup and building the DOM tree. HTML parsing involves tokenization and tree construction. HTML tokens include start and end tags, as well as attribute names and values. If the document is well-formed, parsing it is straightforward and faster. The parser parses tokenized input into the document, building up the document tree.

+ +

The DOM tree describes the content of the document. The <html> element is the first tag and root node of the document tree. The tree reflects the relationships and hierarchies between different tags. Tags nested within other tags are child nodes. The greater the number of DOM nodes, the longer it takes to construct the DOM tree.

+ +

The DOM tree for our sample code, showing all the nodes, including text nodes.

+ +

When the parser finds non-blocking resources, such as an image, the browser will request those resources and continue parsing. Parsing can continue when a CSS file is encountered, but <script> tags—particularly those without an async or defer attribute—block rendering, and pause the parsing of HTML. Though the browser's preload scanner hastens this process, excessive scripts can still be a significant bottleneck.

+ +

Preload scanner

+ +

While the browser builds the DOM tree, this process occupies the main thread. As this happens, the preload scanner will parse through the content available and request high priority resources like CSS, JavaScript, and web fonts. Thanks to the preload scanner, we don't have to wait until the parser finds a reference to an external resource to request it. It will retrieve resources in the background so that by the time the main HTML parser reaches requested assets, they may possibly already be in flight, or have been downloaded. The optimizations the preload scanner provides reduce blockages.

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

In this example, while the main thread is parsing the HTML and CSS, the preload scanner will find the scripts and image, and start downloading them as well. To ensure the script doesn't block the process, add the async attribute, or the defer attribute if JavaScript parsing and execution order is not important.

+ +

Waiting to obtain CSS doesn't block HTML parsing or downloading, but it does block JavaScript, because JavaScript is often used to query CSS properties’ impact on elements.

+ +

Building the CSSOM

+ +

The second step in the critical rendering path is processing CSS and building the CSSOM tree. The CSS object model is similar to the DOM. The DOM and CSSOM are both trees. They are independent data structures. The browser converts the CSS rules into a map of styles it can understand and work with. The browser goes through each rule set in the CSS, creating a tree of nodes with parent, child, and sibling relationships based on the CSS selectors.

+ +

As with HTML, the browser needs to convert the received CSS rules into something it can work with. Hence, it repeats the HTML-to-object process, but for the CSS.

+ +

The CSSOM tree includes styles from the user agent style sheet. The browser begins with the most general rule applicable to a node and recursively refines the computed styles by applying more specific rules. In other words, it cascades the property values.

+ +

Building the CSSOM is very, very fast and is not displayed in a unique color in current developer tools. Rather, the "Recalculate Style" in developer tools shows the total time it takes to parse CSS, construct the CSSOM tree, and recursively calculate computed styles. In terms of web performance optimization, there are lower hanging fruit, as the total time to create the CSSOM is generally less than the time it takes for one DNS lookup.

+ +

Other Processes

+ +

JavaScript Compilation

+ +

While the CSS is being parsed and the CSSOM created, other assets, including JavaScript files, are downloading (thanks to the preload scanner). JavaScript is interpreted, compiled, parsed and executed. The scripts are parsed into abstract syntax trees. Some browser engines take the {{glossary('Abstract Syntax Tree')}} and pass it into an interpreter, outputting bytecode which is executed on the main thread. This is known as JavaScript compilation.

+ +

Building the Accessibility Tree

+ +

The browser also builds an accessibility tree that assistive devices use to parse and interpret content. The accessibility object model (AOM) is like a semantic version of the DOM. The browser updates the accessibility tree when the DOM is updated. The accessibility tree is not modifiable by assistive technologies themselves.

+ +

Until the AOM is built, the content is not accessible to screen readers.

+ +

렌더

+ +

Rendering steps include style, layout, paint and, in some cases, compositing. The CSSOM and DOM trees created in the parsing step are combined into a render tree which is then used to compute the layout of every visible element, which is then painted to the screen. In some cases, content can be promoted to their own layers and composited, improving performance by painting portions of the screen on the GPU instead of the CPU, freeing up the main thread.

+ +

Style

+ +

The third step in the critical rendering path is combining the DOM and CSSOM into a render tree.The computed style tree, or render tree, construction starts with the root of the DOM tree, traversing each visible node.

+ +

Tags that aren't going to be displayed, like the <head> and its children and any nodes with display: none, such as the script { display: none; } you will find in user agent stylesheets, are not included in the render tree as they will not appear in the rendered output. Nodes with visibility: hidden applied are included in the render tree, as they do take up space. As we have not given any directives to override the user agent default, the script node in our code example above will not be included in the render tree.

+ +

Each visible node has its CSSOM rules applied to it. The render tree holds all the visible nodes with content and computed styles -- matching up all the relevant styles to every visible node in the DOM tree, and determining, based on the CSS cascade, what the computed styles are for each node.

+ +

Layout

+ +

The fourth step in the critical rending path is running layout on the render tree to compute the geometry of each node. Layout is the process by which the width, height, and location of all the nodes in the render tree are determined, plus the determination of the size and position of each object on the page. Reflow is any subsequent size and position determination of any part of the page or the entire document.

+ +

Once the render tree is built, layout commences. The render tree identified which nodes are displayed (even if invisible) along with their computed styles, but not the dimensions or location of each node. To determine the exact size and location of each object, the browser starts at the root of the render tree and traverses it.

+ +

On the web page, most everything is a box. Different devices and different desktop preferences mean an unlimited number of differing viewport sizes. In this phase, taking the viewport size into consideration, the browser determines what the dimensions of all the different boxes are going to be on the screen. Taking the size of the viewport as its base, layout generally starts with the body, laying out the dimensions of all the body’s descendants, with each element's box model properties, providing placeholder space for replaced elements it doesn’t know the dimensions of, such as our image.

+ +

The first time the size and position of nodes are determined is called layout. Subsequent recalculations of node size and locations are called reflows.  In our example, suppose the initial layout occurs before the image is returned. Since we didn't declare the size of our image, there will be a reflow once the image size is known.

+ +

Paint

+ +

The last step in the critical rendering path is painting the individual nodes to the screen, the first occurence of which is called the first meaningful paint. In the painting or rasterization phase, the browser converts each box calculated in the layout phase to actual pixels on the screen. Painting involves drawing every visual part of an element to the screen, including text, colors, borders, shadows, and replaced elements like buttons and images. The browser needs to do this super quickly.

+ +

To ensure smooth scrolling and animation, everything occupying the main thread, including calculating styles, along with reflow and paint, must take the browser less than 16.67ms to accomplish. At 2048 X 1536, the iPad has over 3,145,000 pixels to be painted to the screen. That is a lot of pixels that have to be painted very quickly. To ensure repainting can be done even faster than the initial paint, the drawing to the screen is generally broken down into several layers. If this occurs, then compositing is necessary.

+ +

Painting can break the elements in the layout tree into layers. Promoting content into layers on the GPU (instead of the main thread on the CPU) improves paint and repaint performance. There are specific properties and elements that instantiate a layer, including <video> and <canvas>, and any element which has the CSS properties of opacity, a 3D transform, will-change, and a few others. These nodes will be painted onto their own layer, along with their descendants, unless a descendant necessitates its own layer for one (or more) of the above reasons.

+ +

Layers do improve performance, but are expensive when it comes to memory management, so should not be overused as part of web performance optimization strategies.

+ +

Compositing

+ +

When sections of the document are drawn in different layers, overlapping each other, compositing is necessary to ensure they are drawn to the screen in the right order and the content is rendered correctly.

+ +

As the page continues to load assets, reflows can happen (recall our example image that arrived late).  A reflow sparks a repaint and a re-composite. Had we defined the size of our image, no reflow would have been necessary, and only the layer that needed to be repainted would be repainted, and composited if necessary. But we didn't include the image size! When the image is obtained from the server, the rendering process goes back to the layout steps and restarts from there.

+ +

상호운용성

+ +

Once the main thread is done painting the page, you would think we would be "all set." That isn't necessarily the case. If the load includes JavaScript, that was correctly deferred, and only executed after the onload event fires, the main thread might be busy, and not available for scrolling, touch, and other interactions.

+ +

{{glossary('Time to Interactive')}} (TTI) is the measurement of how long it took from that first request which led to the DNS lookup and SSL connection to when the page is interactive -- interactive being the point in time after the {{glossary('First Contentful Paint')}} when the page responds to user interactions within 50ms. If the main thread is occupied parsing, compiling, and executing JavaScript, it is not available and therefore not able to responsd to user interactions in a timely (less than 50ms) fashion.

+ +

In our example, maybe the image loaded quickly, but perhaps the anotherscript.js file was 2MB and our user's network connection was slow.  In this case the user would see the page super quickly, but wouldn't be able to scroll without jank until the script was downloaded, parsed and executed. That is not a good user experience. Avoid occupying the main thread, as demonstrated in this WebPageTest example:

+ +

The main thread is occupied by the downloading, parsing and execution of a  javascript file - over a fast connection

+ +

In this example, the DOM content load process took over 1.5 seconds, and the main thread was fully occupied that entire time, unresponsive to click events or screen taps.

+ +

같이 보기

+ + diff --git "a/files/ko/web/performance/\353\270\214\353\235\274\354\232\260\354\240\200\353\212\224_\354\226\264\353\226\273\352\262\214_\353\217\231\354\236\221\355\225\230\353\212\224\352\260\200/index.html" "b/files/ko/web/performance/\353\270\214\353\235\274\354\232\260\354\240\200\353\212\224_\354\226\264\353\226\273\352\262\214_\353\217\231\354\236\221\355\225\230\353\212\224\352\260\200/index.html" deleted file mode 100644 index 473e30980d..0000000000 --- "a/files/ko/web/performance/\353\270\214\353\235\274\354\232\260\354\240\200\353\212\224_\354\226\264\353\226\273\352\262\214_\353\217\231\354\236\221\355\225\230\353\212\224\352\260\200/index.html" +++ /dev/null @@ -1,204 +0,0 @@ ---- -title: '웹페이지를 표시한다는 것: 브라우저는 어떻게 동작하는가' -slug: Web/Performance/브라우저는_어떻게_동작하는가 -translation_of: Web/Performance/How_browsers_work ---- -

Users want web experiences with content that is fast to load and smooth to interact with. Therefore, a developer should strive to achieve these two goals.

- -

To understand how to improve performance and perceived performance, it helps to understand how the browser works.

- -

개요

- -

Fast sites provide better user experiences. Users want and expect web experiences with content that is fast to load and smooth to interact with.

- -

Two major issues in web performance are understanding issues having to do with latency and issues having to do with the fact that for the most part, browsers are single threaded.

- -

Latency is our main threat to overcome to ensure a fast load. To be fast to load, the developers’ goals include sending requested information as fast as possible, or at least seem super fast. Network latency is the time it takes to transmit bytes over-the-air to computers. Web performance is what we have to do to make the page load happen as quickly as possible.

- -

For the most part, browsers are considered single threaded. For smooth interactions, the developer's goal is to ensure performant site interactions, from smooth scrolling to being responsive to touch. Render time is key, with ensuring the main thread can complete all the work we throw at it and still always be available to handle user interactions. Web performance can be improved by understanding the single-threaded nature of the browser and minimizing the main thread's responsibilities, where possible and appropriate, to ensure rendering is smooth and responses to interactions are immediate.

- -

여정

- -

Navigation is the first step in loading a web page. It occurs whenever a user requests a page by entering a URL into the address bar, clicking a link, submitting a form, as well as other actions.

- -

One of the goals of web performance is to minimize the amount of time a navigation takes to complete. In ideal conditions, this usually doesn't take too long, but latency and bandwidth are foes which can cause delays.

- -

DNS Lookup

- -

The first step of navigating to a web page is finding where the assets for that page are located. If you navigate to https://example.com, the HTML page is located on the server with IP address of 93.184.216.34. If you’ve never visited this site, a DNS lookup must happen.

- -

Your browser requests a DNS lookup, which is eventually fielded by a name server, which in turn responds with an IP address. After this initial request, the IP will likely be cached for a time, which speeds up subsequent requests by retrieving the IP address from the cache instead of contacting a name server again.

- -

DNS lookups usually only need to be done once per hostname for a page load. However, DNS lookups must be done for each unique hostname the requested page references. If your fonts, images, scripts, ads, and metrics all have different hostnames, a DNS lookup will have to be made for each one.

- -

Mobile requests go first to the cell tower, then to a central phone company computer before being sent to the internet

- -

This can be problematic for performance, particularly on mobile networks. When a user is on a mobile network, each DNS lookup has to go from the phone to the cell tower to reach an authoritative DNS server. The distance between a phone, a cell tower, and the name server can add significant latency.

- -

TCP Handshake

- -

Once the IP address is known, the browser sets up a connection to the server via a {{glossary('TCP handshake','TCP three-way handshake')}}. This mechanism is designed so that two entities attempting to communicate—in this case the browser and web server—can negotiate the parameters of the network TCP socket connection before transmitting data, often over {{glossary('HTTPS')}}.

- -

TCP's three way handshaking technique is often referred to as "SYN-SYN-ACK"—or more accurately SYN, SYN-ACK, ACK—because there are three messages transmitted by TCP to negotiate and start a TCP session between two computers. Yes, this means three more messages back and forth between each server, and the request has yet to be made.

- -

TLS Negotiation

- -

For secure connections established over HTTPS, another "handshake" is required. This handshake, or rather the {{glossary('TLS')}} negotiation, determines which cipher will be used to encrypt the communication, verifies the server, and establishes that a secure connection is in place before beginning the actual transfer of data. This requires three more round trips to the server before the request for content is actually sent.

- -

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.

- -

While making the connection secure adds time to the page load, a secure connection is worth the latency expense, as the data transmitted between the browser and the web server cannot be decrypted by a third party.

- -

After the 8 round trips, the browser is finally able to make the request.

- -

응답

- -

Once we have an established connection to a web server, the browser sends an initial HTTP GET request on behalf of the user, which for websites is most often an HTML file. Once the server receives the request, it will reply with relevant response headers and the contents of the 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>
- -

This response for this initial request contains the first byte of data received. {{glossary('Time to First Byte')}} (TTFB) is the time between when the user made the request—say by clicking on a link—and the receipt of this first packet of HTML. The first chunk of content is usually 14kb of data.

- -

In our example above, the request is definitely less than 14Kb, but the linked resources aren't requested until the browser encounters the links during parsing, described below.

- -

TCP Slow Start / 14kb rule

- -

The first response packet will be 14Kb. This is part of {{glossary('TCP slow start')}}, an algorithm which balances the speed of a network connection. Slow start gradually increases the amount of data transmitted until the network's maximum bandwidth can be determined.

- -

In {{glossary('TCP slow start')}}, after receipt of the initial packet, the server doubles the size of the next packet to around 28Kb. Subsequent packets increase in size until a predetermined threshold is reached, or congestion is experienced.

- -

TCP slow start

- -

If you’ve ever heard of the 14Kb rule for initial page load, TCP slow start is the reason why the initial response is 14Kb, and why web performance optimization calls for focusing optimizations with this initial 14Kb response in mind. TCP slow start gradually builds up transmission speeds appropriate for the network's capabilities to avoid congestion.

- -

Congestion control

- -

As the server sends data in TCP packets, the user's client confirms delivery by returning acknowledgements, or ACKs. The connection has a limited capacity depending on hardware and network conditions. If the server sends too many packets too quickly, they will be dropped. Meaning, there will be no acknowledgement. The server registers this as missing ACKs. Congestion control algorithms use this flow of sent packets and ACKs to determine a send rate.

- -

파싱

- -

Once the browser receives the first chunk of data, it can begin parsing the information received. {{glossary('speculative parsing', 'Parsing')}} is the step the browser takes to turn the data it receives over the network into the {{glossary('DOM')}} and {{glossary('CSSOM')}}, which is used by the renderer to paint a page to the screen.

- -

The DOM is the internal representation of the markup for the browser. The DOM is also exposed, and can be manipulated through various APIs in JavaScript.

- -

Even if the request page's HTML is larger than the initial 14KB packet, the browser will begin parsing and attempting to render an experience based on the data it has. This is why it's important for web performance optimization to include everything the browser needs to start rendering a page, or at least a template of the page - the CSS and HTML needed for the first render -- in the first 14 kilobytes. But before anything is rendered to the screen, the HTML, CSS, and JavaScript have to be parsed.

- -

Building the DOM tree

- -

We describe five steps in the critical rendering path.

- -

The first step is processing the HTML markup and building the DOM tree. HTML parsing involves tokenization and tree construction. HTML tokens include start and end tags, as well as attribute names and values. If the document is well-formed, parsing it is straightforward and faster. The parser parses tokenized input into the document, building up the document tree.

- -

The DOM tree describes the content of the document. The <html> element is the first tag and root node of the document tree. The tree reflects the relationships and hierarchies between different tags. Tags nested within other tags are child nodes. The greater the number of DOM nodes, the longer it takes to construct the DOM tree.

- -

The DOM tree for our sample code, showing all the nodes, including text nodes.

- -

When the parser finds non-blocking resources, such as an image, the browser will request those resources and continue parsing. Parsing can continue when a CSS file is encountered, but <script> tags—particularly those without an async or defer attribute—block rendering, and pause the parsing of HTML. Though the browser's preload scanner hastens this process, excessive scripts can still be a significant bottleneck.

- -

Preload scanner

- -

While the browser builds the DOM tree, this process occupies the main thread. As this happens, the preload scanner will parse through the content available and request high priority resources like CSS, JavaScript, and web fonts. Thanks to the preload scanner, we don't have to wait until the parser finds a reference to an external resource to request it. It will retrieve resources in the background so that by the time the main HTML parser reaches requested assets, they may possibly already be in flight, or have been downloaded. The optimizations the preload scanner provides reduce blockages.

- -
<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>
-
- -

In this example, while the main thread is parsing the HTML and CSS, the preload scanner will find the scripts and image, and start downloading them as well. To ensure the script doesn't block the process, add the async attribute, or the defer attribute if JavaScript parsing and execution order is not important.

- -

Waiting to obtain CSS doesn't block HTML parsing or downloading, but it does block JavaScript, because JavaScript is often used to query CSS properties’ impact on elements.

- -

Building the CSSOM

- -

The second step in the critical rendering path is processing CSS and building the CSSOM tree. The CSS object model is similar to the DOM. The DOM and CSSOM are both trees. They are independent data structures. The browser converts the CSS rules into a map of styles it can understand and work with. The browser goes through each rule set in the CSS, creating a tree of nodes with parent, child, and sibling relationships based on the CSS selectors.

- -

As with HTML, the browser needs to convert the received CSS rules into something it can work with. Hence, it repeats the HTML-to-object process, but for the CSS.

- -

The CSSOM tree includes styles from the user agent style sheet. The browser begins with the most general rule applicable to a node and recursively refines the computed styles by applying more specific rules. In other words, it cascades the property values.

- -

Building the CSSOM is very, very fast and is not displayed in a unique color in current developer tools. Rather, the "Recalculate Style" in developer tools shows the total time it takes to parse CSS, construct the CSSOM tree, and recursively calculate computed styles. In terms of web performance optimization, there are lower hanging fruit, as the total time to create the CSSOM is generally less than the time it takes for one DNS lookup.

- -

Other Processes

- -

JavaScript Compilation

- -

While the CSS is being parsed and the CSSOM created, other assets, including JavaScript files, are downloading (thanks to the preload scanner). JavaScript is interpreted, compiled, parsed and executed. The scripts are parsed into abstract syntax trees. Some browser engines take the {{glossary('Abstract Syntax Tree')}} and pass it into an interpreter, outputting bytecode which is executed on the main thread. This is known as JavaScript compilation.

- -

Building the Accessibility Tree

- -

The browser also builds an accessibility tree that assistive devices use to parse and interpret content. The accessibility object model (AOM) is like a semantic version of the DOM. The browser updates the accessibility tree when the DOM is updated. The accessibility tree is not modifiable by assistive technologies themselves.

- -

Until the AOM is built, the content is not accessible to screen readers.

- -

렌더

- -

Rendering steps include style, layout, paint and, in some cases, compositing. The CSSOM and DOM trees created in the parsing step are combined into a render tree which is then used to compute the layout of every visible element, which is then painted to the screen. In some cases, content can be promoted to their own layers and composited, improving performance by painting portions of the screen on the GPU instead of the CPU, freeing up the main thread.

- -

Style

- -

The third step in the critical rendering path is combining the DOM and CSSOM into a render tree.The computed style tree, or render tree, construction starts with the root of the DOM tree, traversing each visible node.

- -

Tags that aren't going to be displayed, like the <head> and its children and any nodes with display: none, such as the script { display: none; } you will find in user agent stylesheets, are not included in the render tree as they will not appear in the rendered output. Nodes with visibility: hidden applied are included in the render tree, as they do take up space. As we have not given any directives to override the user agent default, the script node in our code example above will not be included in the render tree.

- -

Each visible node has its CSSOM rules applied to it. The render tree holds all the visible nodes with content and computed styles -- matching up all the relevant styles to every visible node in the DOM tree, and determining, based on the CSS cascade, what the computed styles are for each node.

- -

Layout

- -

The fourth step in the critical rending path is running layout on the render tree to compute the geometry of each node. Layout is the process by which the width, height, and location of all the nodes in the render tree are determined, plus the determination of the size and position of each object on the page. Reflow is any subsequent size and position determination of any part of the page or the entire document.

- -

Once the render tree is built, layout commences. The render tree identified which nodes are displayed (even if invisible) along with their computed styles, but not the dimensions or location of each node. To determine the exact size and location of each object, the browser starts at the root of the render tree and traverses it.

- -

On the web page, most everything is a box. Different devices and different desktop preferences mean an unlimited number of differing viewport sizes. In this phase, taking the viewport size into consideration, the browser determines what the dimensions of all the different boxes are going to be on the screen. Taking the size of the viewport as its base, layout generally starts with the body, laying out the dimensions of all the body’s descendants, with each element's box model properties, providing placeholder space for replaced elements it doesn’t know the dimensions of, such as our image.

- -

The first time the size and position of nodes are determined is called layout. Subsequent recalculations of node size and locations are called reflows.  In our example, suppose the initial layout occurs before the image is returned. Since we didn't declare the size of our image, there will be a reflow once the image size is known.

- -

Paint

- -

The last step in the critical rendering path is painting the individual nodes to the screen, the first occurence of which is called the first meaningful paint. In the painting or rasterization phase, the browser converts each box calculated in the layout phase to actual pixels on the screen. Painting involves drawing every visual part of an element to the screen, including text, colors, borders, shadows, and replaced elements like buttons and images. The browser needs to do this super quickly.

- -

To ensure smooth scrolling and animation, everything occupying the main thread, including calculating styles, along with reflow and paint, must take the browser less than 16.67ms to accomplish. At 2048 X 1536, the iPad has over 3,145,000 pixels to be painted to the screen. That is a lot of pixels that have to be painted very quickly. To ensure repainting can be done even faster than the initial paint, the drawing to the screen is generally broken down into several layers. If this occurs, then compositing is necessary.

- -

Painting can break the elements in the layout tree into layers. Promoting content into layers on the GPU (instead of the main thread on the CPU) improves paint and repaint performance. There are specific properties and elements that instantiate a layer, including <video> and <canvas>, and any element which has the CSS properties of opacity, a 3D transform, will-change, and a few others. These nodes will be painted onto their own layer, along with their descendants, unless a descendant necessitates its own layer for one (or more) of the above reasons.

- -

Layers do improve performance, but are expensive when it comes to memory management, so should not be overused as part of web performance optimization strategies.

- -

Compositing

- -

When sections of the document are drawn in different layers, overlapping each other, compositing is necessary to ensure they are drawn to the screen in the right order and the content is rendered correctly.

- -

As the page continues to load assets, reflows can happen (recall our example image that arrived late).  A reflow sparks a repaint and a re-composite. Had we defined the size of our image, no reflow would have been necessary, and only the layer that needed to be repainted would be repainted, and composited if necessary. But we didn't include the image size! When the image is obtained from the server, the rendering process goes back to the layout steps and restarts from there.

- -

상호운용성

- -

Once the main thread is done painting the page, you would think we would be "all set." That isn't necessarily the case. If the load includes JavaScript, that was correctly deferred, and only executed after the onload event fires, the main thread might be busy, and not available for scrolling, touch, and other interactions.

- -

{{glossary('Time to Interactive')}} (TTI) is the measurement of how long it took from that first request which led to the DNS lookup and SSL connection to when the page is interactive -- interactive being the point in time after the {{glossary('First Contentful Paint')}} when the page responds to user interactions within 50ms. If the main thread is occupied parsing, compiling, and executing JavaScript, it is not available and therefore not able to responsd to user interactions in a timely (less than 50ms) fashion.

- -

In our example, maybe the image loaded quickly, but perhaps the anotherscript.js file was 2MB and our user's network connection was slow.  In this case the user would see the page super quickly, but wouldn't be able to scroll without jank until the script was downloaded, parsed and executed. That is not a good user experience. Avoid occupying the main thread, as demonstrated in this WebPageTest example:

- -

The main thread is occupied by the downloading, parsing and execution of a  javascript file - over a fast connection

- -

In this example, the DOM content load process took over 1.5 seconds, and the main thread was fully occupied that entire time, unresponsive to click events or screen taps.

- -

같이 보기

- - diff --git "a/files/ko/web/performance/\354\244\221\354\232\224_\353\240\214\353\215\224\353\247\201_\352\262\275\353\241\234/index.html" "b/files/ko/web/performance/\354\244\221\354\232\224_\353\240\214\353\215\224\353\247\201_\352\262\275\353\241\234/index.html" deleted file mode 100644 index 0dd28ed81c..0000000000 --- "a/files/ko/web/performance/\354\244\221\354\232\224_\353\240\214\353\215\224\353\247\201_\352\262\275\353\241\234/index.html" +++ /dev/null @@ -1,60 +0,0 @@ ---- -title: 중요 렌더링 경로 -slug: Web/Performance/중요_렌더링_경로 -translation_of: Web/Performance/Critical_rendering_path ---- -

{{draft}}

- -

중요 렌더링 경로 (Critical Rendering Path)는 브라우저가 HTML, CSS, Javascipt를 화면에 픽셀로 변화하는 일련의 단계를 말하며 이를 최적화하는 것은 렌더링 성능을 향상시킵니다. 중요 렌더링 경로는 Document Object Model (DOM), CSS Object Model (CSSOM), 렌더 트리 그리고 레이아웃을 포함합니다.

- -

도큐먼트 오브젝트 모델은 HTML을 분석함으로써 만들어집니다. HTML은 Javascript를 요청할 수 있으며, 이 경우 DOM 이 변경될 수 있습니다. HTML은 차례대로 CSS 오브젝트 모델을 만들기 위한 스타일에 대한 요청을 만들거나 포함합니다. 브라우저 엔진은 이 두가지를 결합하여 렌더 트리를 생성하며 레이아웃은 페이지의 모든 것에 대한 크기와 위치를 결정합니다. 일단 레이아웃이 결정되면 화면에 픽셀을 그립니다.

- -

중요 렌더링 경로 최적화는 첫번째 렌더링의 시간을 개선시킵니다. 중요 렌더링 경로를 이해하고, 최적화 하는 것은 뛰어난 사용자 상호작용을 보장하며 버벅거림을 피할 수 있도록 하고, 1초당 60 프레임에 리플로우와 리페인트가 발생할 수 있도록 하는데 중요합니다.

- -

CRP 이해하기

- -

웹 성능은 서버의 요청과 응답, 로딩, 스크립팅, 렌더링, 레이아웃 그리고 화면에 픽셀 그리기를 포함합니다.

- -

웹 페이지 또는 어플리케이션에 대한 요청은 HTML 요청으로 시작됩니다. 서버는 응답 헤더 또는 데이터로 HTML을 반환합니다. 그리고 나서 브라우저는 HTML을 분석하고 수신된 바이츠를 DOM 트리로 변환하기 시작합니다. 브라우저는 스타일시트, 스크립트 또는 포함된 이미지 참조인 외부 자원에 대한 링크를 찾을때마다 요청을 시작합니다. 불러온 에셋을 다룰 때까지 나머지 HTML을 분석하는 작업하는 일부 요청은 중단되며 차단됩니다. 브라우저는 CSS 오브젝트 모델을 구축하는 작업이 끝날때까지 요청을 만들고 DOM을 생성하는 HTML을 계속해서 분석합니다. DOM과 CSSOM이 완료되면 브라우저는 렌더 트리를 생성하고 보여지는 컨텐츠를 위해 스타일을 계산합니다. 렌더트리가 완료된 후 모든 렌더 트리 요소들에 대한 위치와 크기가 정의된 레이아웃이 만들어집니다. 일단 완료되면 레이지는 렌더링되거나 또는 화면에 '그려집니다(painted)'.

- -

Document Object Model

- -

DOM 구성은 점진적으로 증가합니다. HTML 응답은 토큰으로, 토큰은 노드로, 노드는 DOM 트리로 변환됩니다.1개의 DOM 노드는 시작태그 토큰으로 시작해서 끝태그 토큰으로 끝납니다. 노드들은 HTML 요소에 대한 모두 연관성 있는 정보를 포함하고 있습니다. 그 정보는 토큰을 통해 설명됩니다. 노드들은 토큰의 위계서열을 기반으로 DOM 트리안에 연결됩니다. 만약 또 다른 시작태그와 끝태그의 묶음이 한 세트의 시작태그와 끝태그 사이에 있다면, 여러분은 DOM 트리의 위계서열을 정의하는 방법으로 노드 안에 노드를 가지게 됩니다.

- -

많은 수의 노드는 중요 렌더링 경로에서 다음의 이벤트를 더 오래 발생시킬 것입니다. 측정하세요! 몇 개의 추가 노드는 차이를 만들지 않지만 전염은 버벅거림을 유발할 수 있습니다.

- -

CSS Object Model

- -

DOM은 페이지의 모든 컨텐츠를 포함하고, CSSOM은 DOM을 스타일링 하기 위한 페이지의 모든 스타일 정보를 포함합니다. CSSOM은 DOM과 유사하지만 다릅니다. DOM의 구조는 점진적으로 증가하는 반면에 CSSOM은 그렇지 않습니다. CSS는 렌더링을 막습니다: 브라우저는 모든 CSS를 처리하고 수신할때까지 페이지 렌더링을 막습니다. CSS는 규칙을 덮어쓸수 있기 때문에 렌더링을 막습니다. 그러므로 CSSOM이 완료될때까지 콘텐츠를 렌더링 할 수 없습니다.

- -

CSS는 유효한 토크들은 인식하기 위해 스스로 규칙 세트를 가지고 있습니다. CSS의 C가 'Cascade(종속 또는 폭포)'라는 의미를 기억해두세요. CSS 규칙은 아래로 종속됩니다. 분석기는 토큰을 노드로 변환할때, 하위 노드가 스타일을 상속합니다. 연속적인 규칙들이 이전의 규칙들에 덮어쓰여질 수 있기 때문에, 증감 처리 기술은 HTML 처럼 CSS에 적용되지는 않습니다. CSS 개체 모델은 CSS를 분석할 때 빌드되지만 나중에 분석되 덮어쓸 스타일들은 화면에 렌더링 할 수 없기 때문에 완전히 분석될 때까지 렌더 트리를 생성하는데 사용할 수 없습니다.

- -

선택자 성능 측면에서, 덜 구체적인 선택자는 더 구체적인 선택자보다 더 빠릅니다. 예를 들어, 브라우저가 .foo 찾을때, .foo {}.bar .foo {} 보다 빠릅니다. 왜냐하면 두번째 시나리오에서, .foo 가 부모 객체인 .bar 를 가지고 있는지 확인하기 위해 DOM을 거슬러 올라가기 때문입니다. 더 구체적인 태그는 브라우저에게 더 많은 작업을 요구하지만 이러한 패널티는 최적화 할 가치가 없습니다.

- -

만약 CSS 분석 시간을 측정한다면, 브라우저들이 정말 빠르다는 것에 놀랄 것입니다. 규칙이 구체적일수록 DOM 트리 안에서 더 많은 노드들은 지나야 하기 때문에 더 높은 비용이 듭니다. 그러나 추가적인 비용은 일반적으로 최소입니다. 첫번째는 측정입니다. 필요할때 최적화하세요. 특정 짓는 것은 쉬운 일이 아닙니다. CSS 측면에서, 선택자 성능 최적화와 개선은 오직 microsecond 밖에 되지 않될 것입니다. 축소화와 미디어 쿼리를 사용함으로써 지연된 CSS를 논-블로킹 요청으로 분리하는 것과 같은 CSS 최적화를 위한 다른 방법이 있습니다.

- -

Render Tree

- -

렌터 트리는 콘텐츠와 스타일 둘다 캡쳐합니다. DOM과 CSSOM 트리는 렌더 트리에 결합됩니다. 렌더 트리를 구성하기 위해 브라우저는 DOM 트리의 root에서 시작해 모든 노드는 확인하면서 어떤 CSS 규칙들을 첨부할지 결정합니다.

- -

렌더 트리는 오직 보여지는 콘텐츠만은 캡쳐합니다. (일반적으로) 헤드 섹션은 보여지는 정보를 포함하고 있지 않으므로 렌더트리 안에 포함되지 않습니다. 만약 요소에 display: none 이 적용되어 있다면, 해당 요소 또는 하위 요소는 포함되지 않습니다.

- -

Layout

- -

일단 렌더 트리가 생성되고 나면, 레이아웃은 가능해지며 화면의 크기에 의존합니다. 레이아웃 단계는 요소들이 페이지에서 배치되는 위치와 방법, 각 요소의 너비와 높이 그리고 서로 관련된 위치를 결정합니다.

- -

요소의 너비는 무엇일까요? 정의에 따르면, 블럭 수준의 요소들은 그 부모 너비의 기본 너비값의 100% 입니다. 50%의 너비를 갖는 요소는 부모 요소의 절반일 것입니다. 비록 그렇게 정의되어 있지 않더라고, body 는 뷰포트 너비의 100%를 의미하는 너비 입니다. 디바이스의 너비는 레이아웃에 영향을 미칩니다.

- -

뷰포트 메타 태그는 레이아웃에 영향을 미치는 뷰포트 레이아웃의 너비로 정의합니다. 이 태그 없다면, 브라우저는 뷰포트 기본값을 사용합니다. 브라우저의 full screen 기본값은 일반적으로 960px 입니다. 기본적으로 브라우저의 full screen에서, 스마트폰의 브라우저와 같은 너비는 <meta name="Viewport" content="width=device-witdh"> 로 세팅함으로써 기본 뷰포트 너비 대신에 디바이스의 너비를 사용합니다. 디바이스 너비는 사용자가 디비이스를 가로(landscapre) 또는 세로(portrait) 모드 사이로 돌릴때마다 바뀝니다. 레이아웃은 디바이스가 회전하거나 브라우저의 사이즈가 조정될 때마다 발생합니다.

- -

레이아웃 성능은 DOM의 영향을 받습니다. 노드의 수가 많을수록 레이아웃은 더 길어지며 스크롤링 또는 다른 애니메이션들이 필요하다면 레이아웃에 쟁크(jank)를 일으키는 병목현상이 발생할 수 있습니다. 로딩 또는 방향 전환에 20ms 정도 밀릴 수 있지만 애니메이션 또는 스크롤에 쟁크(jank) 유발할 수 있습니다. 노드에 박스 모델 업데이트, 콘텐츠 대체 그리고 노드 추가와 같은 수정은 언제든지 렌더 트리를 수정할 수 있으며 레이아웃을 형성합니다.

- -

레이아웃 이벤트의 반복과 형성시간을 줄이기 위해서 일괄 업데이트 해야하고, 박스 모델 속성을 애니메이션화 하지 말아야 합니다.

- -

Paint

- -

마자믹 단계는 화면에 픽셀을 그리는 것입니다. 일단 렌더 트리가 생성되고 레이아웃나 나타나기 시작하면, 화면에 픽셀을 그릴수 있습니다. 로드시, 전체 화면을 그립니다. 그 후에는 브라우저가 필요한 최소 영역만을 다시 그리도록 최적화되어 있기 때문에 영향을 받는 영역만을 화면에 다시 그립니다. 그리는 시간은 렌터 트리에 적용되는 업데이트의 종류가 무엇있냐에 따라 달라집니다. 페인팅인 매우 빠르게 진행되는 과정이기 때문에 성능 향상에 집중해야 하는 가장 큰 영향있는 부분이 아닐 수 있지만, 애니메이션 프레임 소요시간을 측정할때, 레이아웃과 리페인트 시간을 모두 고려하는 것이 중요합니다. 각 노드에 적용된 스타일은 페인트 시간을 증가시키지만 페인트 시간을 0.001ms 증가시키는 스타일을 제거하는 것은 여러분의 최적화 비용이 매우 커지는 것을 막지 못할 수 있습니다. 첫째는 측정하는 것을 기억하고, 최적화 우선순위를 정해야할지 말지를 결정해야 합니다.

- -

Optimizing for CRP

- -

자원 로드 순서를 관리하고, 파일 사이즈를 줄이며 어떤 자원을 먼저 로드할지 정함으로써 페이지 로드 속도를 개선하세요. 성능 팁으로는 1) 자원 다운로드를 연기함으로써 중요 자원들의 수를 최소화하기 , 2) 각 요청에 대한 파일 사이즈에 따라 필수적인 요청 횟수 최적하하기, 3) 다운받을 중요 에셋의 우선순위를 정함으로써 중요 자원 불러오는 순서 최적화하고, 중요 경로 길이 최소화하기

diff --git a/files/ko/web/progressive_web_apps/introduction/index.html b/files/ko/web/progressive_web_apps/introduction/index.html new file mode 100644 index 0000000000..e253c96ce9 --- /dev/null +++ b/files/ko/web/progressive_web_apps/introduction/index.html @@ -0,0 +1,92 @@ +--- +title: 프로그레시브 웹 앱 소개 +slug: Web/Progressive_web_apps/소개 +tags: + - PWA + - js13kGames + - 소개 + - 프로그레시브 + - 프로그레시브 웹 앱 +translation_of: Web/Progressive_web_apps/Introduction +--- +
{{NextMenu("Web/Apps/Progressive/App_structure", "Web/Apps/Progressive")}}
+ +

이 문서는 프로그레시브 웹 앱(PWA)의 소개입니다. PWA가 무엇이고 일반 웹 앱에 어떤 이점을 가져다주는지 설명합니다.

+ +

프로그레시브 웹 앱이 무엇인가요?

+ +

PWA는 웹과 네이티브 앱의 기능 모두의 이점을 갖도록 수 많은 특정 기술과 표준 패턴을 사용해 개발된 웹 앱입니다.

+ +

예를 들어, 웹 앱은 발견이 쉽습니다 — 어플리케이션을 설치하는 것보다 웹사이트에 방문하는 것이 훨씬 쉽고 빠르며, 링크로 웹 앱을 공유할수도 있습니다.

+ +

반면에, 네이티브 앱은 운영체제와 보다 잘 통합되므로 더 부드러운 사용자 경험을 제공할 수 있습니다. 네이티브 앱은 설치할 수 있으므로 오프라인에서 동작하며, 사용자는 홈 화면의 아이콘을 탭하여 브라우저를 사용하여 이동하는 것보다 선호하는 앱에 더 쉽게 접근할 수 있습니다.

+ +

PWA는 이들과 동일한 이점을 즐길 수 있는 웹 앱을 생성하는 능력을 제공합니다.

+ +

완전히 새로운 개념은 아닙니다 — 이런 아이디어는 과거에 다양한 접근 방법으로 웹 플랫폼상에서 여러번 재검토되었습니다. 점진적인 향상과 반응형 디자인은 이미 우리가 모바일 친화적인 웹사이트를 구축할 수 있게 해주고 있습니다. 오프라인에서 동작하는 것과 앱을 설치하는 것은 몇 년 전 Firefox OS 생태계에서 이미 가능했었습니다.

+ +

하지만, PWA는 웹을 훌륭하게 만드는 이미 존재하는 어떤 기능도 제거하지 않은 상태로 이 모든 것 그리고 그 이상을 제공합니다.

+ +

앱을 PWA로 만드는 것은 무엇인가요?

+ +

위에서 암시했듯이, PWA는 하나의 기술로 생성된 것이 아닙니다. 이는 일부 특정 패턴, API 및 다른 기능들을 포함하는 웹 앱을 구축하는 하나의 새로운 철학을 나타냅니다. 첫눈에 웹 앱이 PWA인이 아닌지 구분하기는 쉽지 않습니다. 앱이 특정 요구 사항을 만족하거나 다음 기능들이 구현되었을 때 PWA라고 볼 수 있습니다: 오프라인에서 동작, 설치가 가능, 쉬운 동기화, 푸시 알림, 등.

+ +

게다가, 앱의 완성도를 퍼센트로 측정하는 도구들도 있습니다. (Lighthouse가 현재 가장 유명합니다.) 다양한 기술적 이점을 구현함으로써, 앱을 더 점진적이게 만들 수 있고, 더 높은 Lighthouse 점수를 받을 수 있습니다. 하지만 이는 대략적인 지표일뿐입니다.

+ +

다음은 웹 앱을 PWA로 식별되기 위해 확인해야 하는 몇 가지 핵심 원칙입니다.

+ +
    +
  • 발견 가능, 따라서 컨텐츠를 검색 엔진을 통해 찾을 수 있습니다.
  • +
  • 설치 가능, 따라서 기기의 홈 화면에서 사용할 수 있습니다.
  • +
  • 연결 가능, 따라서 간단하게 URL을 전송해 공유할 수 있습니다.
  • +
  • 네트워크 독립적, 따라서 오프라인이나 불안한 네트워크 연결에서 동작합니다.
  • +
  • 점진적, 따라서 최신 브라우저의 모든 기능은 사용할 수 없지만 이전 브라우저의 기본 기능은 여전히 사용할 수 있습니다.
  • +
  • 재 참여 가능(Re-engageable), 따라서 새 컨텐츠가 사용 가능할 때마다 알림을 보낼 수 있습니다.
  • +
  • 반응형, 따라서 모든 기기의 화면이나 브라우저에서 사용할 수 있습니다 — 모바일 폰, 태블릿, 노트북, TV, 냉장고, 등.
  • +
  • 안전, 따라서 여러분과 앱 사이의 연결이 여러분의 민감한 데이터에 접근하려는 모든 제3자로부터 안전합니다.
  • +
+ +

이 모든 것들을 할만한 가치가 있나요?

+ +

물론입니다! 비교적 적은 노력으로 PWA 핵심 기능들을 구현할 수 있으며, 그 이점은 거대합니다. 예를 들면:

+ +
    +
  • Service Workers 를 사용한 캐싱 덕분에 앱을 설치한 후에 로딩 시간이 줄어들어 소중한 데이터와 시간을 절약.
  • +
  • 앱 업데이트가 있을 때 변경된 컨텐츠만 업데이트 할 수 있음. 반면, 네이티브 앱의 경우, 아주 작은 수정에도 사용자가 어플리케이션 전체를 다시 다운로드하도록 강제함.
  • +
  • 네이티브 플랫폼에 보다 통합된 외관과 느낌 — 홈 화면의 앱 아이콘, 전체 화면으로 실행되는 앱, 등.
  • +
  • 시스템 알림 및 푸시 메시지를 통한 사용자의 재 참여. 참여율이 높은 사용자와 더 나은 전환율을 이끌어 냄.
  • +
+ +

PWA 라우트를 시도하고 네이티브 앱 보다 더 향상된 웹 사이트 경험을 선택하여 측정 가능한 의미있는 이득을 본 회사들의 성공 스토리가 많습니다. PWA Stats 웹 사이트는 이러한 이점을 나타내는 많은 사례 연구들을 공유합니다.

+ +

가장 잘 알려진 성공 스토리는 아마 Flipkart Lite 일 것입니다 — 2015년에 프로그레시브 웹 앱으로 사이트를 재구축해 전환율을 70% 상승시킨 인도의 가장 큰 전자 상거래 사이트입니다. AliExpress PWA 역시 새로운 사용자에 대한 전환율을 104% 상승시키는 것으로 웹이나 네이티브 앱보다 훨씬 더 나은 결과를 보였습니다. 이윤 증가 및 PWA로 전환을 위해 상대적으로 적은 양의 작업을 놓고 봤을 때, 이점은 분명합니다.

+ +

더 많은 예제는 pwa.rocks 의 목록에서 확인하시기 바랍니다. hnpwa.com 페이지는 특별히 언급할 가치가 있습니다 — 여기에는 일반적인 TodoMVC 앱 대신 다양한 프론트엔드 프레임워크의 사용을 볼 수 있는 Hacker News 웹사이트의 구현 예제가 나열되어 있습니다.

+ +

심지어 PWABuilder 웹사이트를 사용해 PWA를 온라인에서 생성할수도 있습니다.

+ +

Service worker와 푸시에 관련된 정보는 최신 사이트에서 service worker를 사용하는 예제를 모아둔 Service Worker Cookbook을 확인하시기 바랍니다.

+ +

PWA 접근은 시도해볼만한 가치가 있으며, 여러분의 앱에서 동작하는지 스스로 확인해보시기 바랍니다.

+ +

브라우저 호환성

+ +

앞서 언급했듯이, PWA는 하나의 API에 의존하지 않고, 가능한 최고의 웹 경험을 전달하기 위한 목표를 달성하기 위해 다양한 기술들을 사용합니다.

+ +

PWA를 위해 요구되는 핵심 요소는 service worker 지원입니다. 고맙게도 service worker는 현재 데스크탑 및 모바일의 모든 주요 브라우저에서 지원됩니다.

+ +

웹 앱 Manifest, 푸시, 알림, 홈 화면에 추가 기능과 같은 다른 기능들도 널리 지원되고 있습니다. 현재 Safari에서는 웹 앱 Manifest 및 홈 화면에 추가에 지원이 제한적이며 웹 푸시 알림은 지원하지 않습니다. 반면, 다른 주요 브라우저에서는 이 모든 기능들을 지원합니다.

+ +

이러한 API의 일부는 실험중이며 문서도 여전히 완성되지 않았지만, Flipkart 와 AliExpress와 같은 성공 스토리를 보면 여러분의 웹 앱에 PWA 기능의 일부를 시도하고 구현하는 것에 대해 이미 납득이 되었을것입니다.

+ +

무엇보다도 여러분은 프로그레시브 향상 규칙을 따라야 합니다 — 이러한 향상을 제공하는 기술들은 지원이 되는 경우에만 사용하고, 그렇지 않은 경우에도 여전히 기본 기능을 제공하시기 바랍니다. 이 방법으로 모든 사용자가 앱을 사용할 수 있지만, 최신 브라우저를 사용하는 사용자는 PWA 기능으로부터 더 많은 이점을 얻을 수 있습니다.

+ +

예시 어플리케이션

+ +

이 문서 시리즈에서는 js13kGames 2017 대회의 A-Frame 카테고리에 제출된 게임에 대한 정보를 나열하는 아주 간단한 웹사이트의 소스코드를 살펴볼 것입니다. 여러분은 웹 사이트의 실제 컨텐츠가 무엇인지에 대해서는 생각할 필요가 없습니다 — 중요한 점은 여러분의 프로젝트에 PWA 기능을 어떻게 사용하는지를 배우는 것입니다.

+ +

온라인 버전은 mdn.github.io/pwa-examples/js13kpwa (소스 코드도 확인하세요)에서 확인하실 수 있으며, 다음 몇 가지 문서에서 자세히 설명할 것입니다.

+ +

이제, 우리의 예제 앱의 구조에 대해 살펴볼 이 시리즈의 두 번째 파트로 이동합시다.

+ +

{{NextMenu("Web/Apps/Progressive/App_structure", "Web/Apps/Progressive")}}

diff --git a/files/ko/web/progressive_web_apps/responsive/media_types/index.html b/files/ko/web/progressive_web_apps/responsive/media_types/index.html new file mode 100644 index 0000000000..2c9fceaca0 --- /dev/null +++ b/files/ko/web/progressive_web_apps/responsive/media_types/index.html @@ -0,0 +1,346 @@ +--- +title: 미디어 +slug: Web/CSS/시작하기/미디어 +translation_of: Web/Progressive_web_apps/Responsive/Media_types +--- +

{{ CSSTutorialTOC() }}

+
+ 중요: 번역은 제가 필요한 부분 및 확인 가능한 부분만 진행 하였으며 변역된 날자는(2013/03/21)이며 문서 변경이 잦아 오늘 이후는 원문과 번역이 다를 수 있습니다. 참고하세요. 미 번역/변경된 부분은 추가로 다른 분이 해 주실 것으로 믿습니다.
+

{{ previousPage("/en-US/docs/CSS/Getting_Started/Tables", "테이블") }}CSS 시작하기 안내서의 14번쨰 장. 지금까지 이번 안내서에서는 많은 부분을 Document를 어떻게 보여 줄것인지 결정하는 CSS의 속성과 변수에 관해 소개 했다. 이번에는 Stylesheet의 구조와 목적에 대해 다시 살펴 보자.

+

정보 : 미디어

+

CSS의 목적은 Document가 사용자에게 어떻게 보여질 것인가를 설정하는 것이다. 전시되는 형태는 하나 이상의 형식이 있다.

+

예를 들면, 아마도 이 페이지도 화면 표시 장치를 통해 보여질 것이다. 그러나 큰 화면용으로 프로젝터나 프린트해서 보는 경우도 있을 것이다. 이런 다양한 미디어의 경우 그 고유의 문자셋같은 특징이 있을 것이다. CSS는 document를 각각의 미디어에 표시하기 위한 다양한 방법을 제공한다.

+

미디어의 특정 타입을 정하는 규칙을 추가 하려면 {{ CSSXref("@media") }} 다음에 미디어 타입 넣고, 그 다음에 대괄호({})로 해당 규칙을 추가 하라.

+
+
+ 예제
+

웹사이트에 있는 document는 그 사이트 전체를 살펴볼수 있도록 조절 할 수 있는 영역을 제공한다.

+

마크업 언어에서는, 조정영역의 부모 element의 idnav-area이다. ({{ HTMLVersionInline(5) }}에서는 id 속성이 포함된 {{ HTMLElement("div") }}대신에 {{ HTMLElement("nav") }} element로 사용 할 수 있다.)

+

Document가 프린트 될 경우는 이 조정 영역이 필요 없으므로 stylesheet에서는 완전히 이 영역을 제거한다.

+
@media print {
+  #nav-area {display: none;}
+  }
+
+
+

일반적인 미디어 타입은 아래와 같다.

+ + + + + + + + + + + + + + + + + + + +
screen컬러 컴퓨터 표시 장치
print출력 장치
projection프로젝트 출력 장치
all그외 모든 미디어 장치(기본 설정)
+
+
+ 좀더 자세히
+

한 무리의 규칙들의 미디어 타입을 설정하는데는 다른 방법들도 있다.

+

Stylesheet가 document로 연결되어 있을때 document의 마크업 언어는 미디어 타입을 설정하는 것을 허용한다. 예를 들면, HTML내의 LINK 태그에서 media속성으로 옵션항목으로 미디어 타입을 설정 할 수 있다.

+

CSS에서 stylesheet의 앞부분에 {{ CSSXref("@import") }}로 URL로 부터 다른 stylesheet를 불러 올 수 있다. 추가적으로 미디어 타입도 사용 가능하다.

+

이와 같은 규직으로, 미디어 타입별로 다른 파일에 분리하여 관리 가능하다. 이렇게 함으로써 stylesheet를 구조화하는데 유용하게 사용한다.

+

좀더 자세한 미디어 타입에 대해서는 CSS의 사양서중 Media를 참고하라.

+

{{ cssxref("display") }}속성에 대해서 좀더 자세한 사항은 이 안내서 나중에 소개될 XML data를 참고하라.

+
+

출력

+

CSS에는 인쇄 매체나 프린터 출력을 위한 특별 지원을 한다

+

{{ cssxref("@page") }} 규칙을 통해 여백을 설정할 수 있다. 양면출력을 위해서는 @page:left@page:right로 각각의 여백을 개별로 설정 할 수 있다.

+

출력 매체를 위해 사용되는 단위는 인치 (in), 포인트(pt = 1/72 inch), 센티미터(cm)와 밀리미터(mm)등을 사용 할 수 있다. 글자 크기 설정과 맞추기 위해 사용하는 ems(em)과 퍼센트(%)도 사용하기에 적절하다.

+

Document의 내용중 페이지 분할을 위해서는 { cssxref("page-break-before") }}나 {{ cssxref("page-break-after") }}, {{ cssxref("page-break-inside") }}속성을 사용할 수 있다.

+
+
+ 예제
+

아래 예제는 페이지 여백 4방향 모두를 1인치로 설정한다.

+
@page {margin: 1in;}
+
+

 

+

아래 규칙은 모든 H1 element는 새 페이지에서 시작하도록 한다.

+
h1 {page-break-before: always;}
+
+
+
+
+ 좀더 자세히
+

CSS의 출판 매체 지원에 대한 사항은 CSS사양서의 Paged media를 확인 하라.

+

CSS의 다른 특징처럼 프린트 출력도 브라우저의 설정에 따라 다르다. 예를 들어 모질라 브라주저는 프린트 출력시 기본 바깥 여백과 머릿말, 꼬릿말이 지원된다. 사용자가 어떤 브라우저를 사용하는지, 그 브라우저의 설정값 또한 알수 없기 때문에 해당 페이지 출력물 결과를 알수 없다.

+
+

사용자 인터페이스

+

CSS는 컴퓨터 모니터같은 표시장치를 위한 특별한 사용자 인터페이스를 지원한다. 이 속성으로 Document를 동적으로 사용자가 사용자 인터페이스로 동작 할 수 있도록 변경한다.

+

사용자 인터페이스 장치에 대한 특별한 미디어 타입은 없다.

+

단지 5가지 설렉터가 있을 뿐이다.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
설렉터선택
E{{ cssxref(":hover") }}포인터가 E로 명시된 element위에 놓일 경우
E{{ cssxref(":focus") }}키보드 포커스를 가진 E element
E{{ cssxref(":active") }}사용자 현재 동작에 개임된 E element
E{{ cssxref(":link") }}최근에 방문하지 않은 URL을 가진 Hyperlink인 E element
E{{ cssxref(":visited") }}최근에 방문한 URL을 가진 Hyperlink인 E element
+
+

주의: :visited 설렉터에서 획득한 정보는 {{ gecko("2.0") }}에만 해당된다. 좀더 자세한 사항은 Privacy and the :visited selector을 보라.

+
+

{{ cssxref("cursor") }}속성은 포인터의 모양을 설정한다. 몇몇 일반적인 모양은 다음과 같다. 브라우저에서 마우스를 아래 리스트에 각각 아이템으로 옮기면 그 모양을 확인 할 수 있다.

+ + + + + + + + + + + + + + + + + + + + + + + +
설렉터선택
pointer링크임을 나타낼때
wait프로그램이 실행중이라 입력을 받지 못하는 상태일때
progress프로그램이 작업을 수행하고 있지만 입력을 받을 수 있는 상태
default기본 상태(보통 화살표 모양)
+

{{ cssxref("outline") }}속성은 키보드 포커스를 가리키는 외곽선을 생성할때 사용한다. 그 값은 사용자가 방향을 설정할 수 없다는 것을 제외하고는 {{ cssxref("border") }}속성과 유사하다.

+

Some other features of user interfaces are implemented using attributes, in the normal way. For example, an element that is disabled or read-only has the disabled attribute or the readonly attribute. Selectors can specify these attributes like any other attributes, by using square brackets: {{ mediawiki.external('disabled') }} or {{ mediawiki.external('readonly') }}.

+
+
+ Example
+

These rules specify styles for a button that changes dynamically as the user interacts with it:

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

 

+

This wiki does not support a user interface on the page, so these buttons do not "click". Here are some static images to illustrate the idea:

+ + + + + + +
+ + + + + + + + + + + + + + + + +
Click MeClick MeClick Me
 
disablednormalactive
+
+

 

+

A fully functional button also has a dark outline around the entire button when it is the default, and a dotted outline on the face of the button when it has keyboard focus. It might also have a hover effect when the pointer is over it.

+
+
+
+ More details
+

For more information about user interfaces in CSS, see User interface in the CSS Specification.

+

There is an example of Mozilla's markup language for user interfaces, XUL, in Part II of this tutorial.

+
+

Action: Printing a document

+
    +
  1. Make a new HTML document, doc4.html. Copy and paste the content from here: +
    <!DOCTYPE html>
    +<html>
    +  <head>
    +    <title>Print sample</title>
    +    <link rel="stylesheet" href="style4.css">
    +  </head>
    +  <body>
    +    <h1>Section A</h11>
    +    <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. Make a new stylesheet, style4.css. Copy and paste the content from here: +
    /*** 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. View this document in your browser; it uses your browser's default style.
  6. +
  7. Print (or print preview) the document; the stylesheet places each section on a separate page, and it adds a header and footer to each page. If your browser supports counters, it adds a page number in the footer. + + + + + + + +
    + + + + + + +
    + + + + + + +
    +
    + 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. +
+ + + + + + + +
+ Challenges
Move the print-specific style rules to a separate CSS file. +

Read the {{ CSSXref("@import") }} reference page to find details of how to import the new print-specific CSS file into your style4.css stylesheet.

+

Make the headings turn blue when the mouse pointer is over them.

+
+

 See solutions to these challenges.

+

What next?

+

If you had difficulty understanding this page, or if you have other comments about it, please contribute to its Discussion page.

+

So far, all the style rules in this tutorial have been specified in files. The rules and their values are fixed. The next page describes how you can change rules dynamically by using a programming language: JavaScript

diff --git "a/files/ko/web/progressive_web_apps/\354\206\214\352\260\234/index.html" "b/files/ko/web/progressive_web_apps/\354\206\214\352\260\234/index.html" deleted file mode 100644 index e253c96ce9..0000000000 --- "a/files/ko/web/progressive_web_apps/\354\206\214\352\260\234/index.html" +++ /dev/null @@ -1,92 +0,0 @@ ---- -title: 프로그레시브 웹 앱 소개 -slug: Web/Progressive_web_apps/소개 -tags: - - PWA - - js13kGames - - 소개 - - 프로그레시브 - - 프로그레시브 웹 앱 -translation_of: Web/Progressive_web_apps/Introduction ---- -
{{NextMenu("Web/Apps/Progressive/App_structure", "Web/Apps/Progressive")}}
- -

이 문서는 프로그레시브 웹 앱(PWA)의 소개입니다. PWA가 무엇이고 일반 웹 앱에 어떤 이점을 가져다주는지 설명합니다.

- -

프로그레시브 웹 앱이 무엇인가요?

- -

PWA는 웹과 네이티브 앱의 기능 모두의 이점을 갖도록 수 많은 특정 기술과 표준 패턴을 사용해 개발된 웹 앱입니다.

- -

예를 들어, 웹 앱은 발견이 쉽습니다 — 어플리케이션을 설치하는 것보다 웹사이트에 방문하는 것이 훨씬 쉽고 빠르며, 링크로 웹 앱을 공유할수도 있습니다.

- -

반면에, 네이티브 앱은 운영체제와 보다 잘 통합되므로 더 부드러운 사용자 경험을 제공할 수 있습니다. 네이티브 앱은 설치할 수 있으므로 오프라인에서 동작하며, 사용자는 홈 화면의 아이콘을 탭하여 브라우저를 사용하여 이동하는 것보다 선호하는 앱에 더 쉽게 접근할 수 있습니다.

- -

PWA는 이들과 동일한 이점을 즐길 수 있는 웹 앱을 생성하는 능력을 제공합니다.

- -

완전히 새로운 개념은 아닙니다 — 이런 아이디어는 과거에 다양한 접근 방법으로 웹 플랫폼상에서 여러번 재검토되었습니다. 점진적인 향상과 반응형 디자인은 이미 우리가 모바일 친화적인 웹사이트를 구축할 수 있게 해주고 있습니다. 오프라인에서 동작하는 것과 앱을 설치하는 것은 몇 년 전 Firefox OS 생태계에서 이미 가능했었습니다.

- -

하지만, PWA는 웹을 훌륭하게 만드는 이미 존재하는 어떤 기능도 제거하지 않은 상태로 이 모든 것 그리고 그 이상을 제공합니다.

- -

앱을 PWA로 만드는 것은 무엇인가요?

- -

위에서 암시했듯이, PWA는 하나의 기술로 생성된 것이 아닙니다. 이는 일부 특정 패턴, API 및 다른 기능들을 포함하는 웹 앱을 구축하는 하나의 새로운 철학을 나타냅니다. 첫눈에 웹 앱이 PWA인이 아닌지 구분하기는 쉽지 않습니다. 앱이 특정 요구 사항을 만족하거나 다음 기능들이 구현되었을 때 PWA라고 볼 수 있습니다: 오프라인에서 동작, 설치가 가능, 쉬운 동기화, 푸시 알림, 등.

- -

게다가, 앱의 완성도를 퍼센트로 측정하는 도구들도 있습니다. (Lighthouse가 현재 가장 유명합니다.) 다양한 기술적 이점을 구현함으로써, 앱을 더 점진적이게 만들 수 있고, 더 높은 Lighthouse 점수를 받을 수 있습니다. 하지만 이는 대략적인 지표일뿐입니다.

- -

다음은 웹 앱을 PWA로 식별되기 위해 확인해야 하는 몇 가지 핵심 원칙입니다.

- -
    -
  • 발견 가능, 따라서 컨텐츠를 검색 엔진을 통해 찾을 수 있습니다.
  • -
  • 설치 가능, 따라서 기기의 홈 화면에서 사용할 수 있습니다.
  • -
  • 연결 가능, 따라서 간단하게 URL을 전송해 공유할 수 있습니다.
  • -
  • 네트워크 독립적, 따라서 오프라인이나 불안한 네트워크 연결에서 동작합니다.
  • -
  • 점진적, 따라서 최신 브라우저의 모든 기능은 사용할 수 없지만 이전 브라우저의 기본 기능은 여전히 사용할 수 있습니다.
  • -
  • 재 참여 가능(Re-engageable), 따라서 새 컨텐츠가 사용 가능할 때마다 알림을 보낼 수 있습니다.
  • -
  • 반응형, 따라서 모든 기기의 화면이나 브라우저에서 사용할 수 있습니다 — 모바일 폰, 태블릿, 노트북, TV, 냉장고, 등.
  • -
  • 안전, 따라서 여러분과 앱 사이의 연결이 여러분의 민감한 데이터에 접근하려는 모든 제3자로부터 안전합니다.
  • -
- -

이 모든 것들을 할만한 가치가 있나요?

- -

물론입니다! 비교적 적은 노력으로 PWA 핵심 기능들을 구현할 수 있으며, 그 이점은 거대합니다. 예를 들면:

- -
    -
  • Service Workers 를 사용한 캐싱 덕분에 앱을 설치한 후에 로딩 시간이 줄어들어 소중한 데이터와 시간을 절약.
  • -
  • 앱 업데이트가 있을 때 변경된 컨텐츠만 업데이트 할 수 있음. 반면, 네이티브 앱의 경우, 아주 작은 수정에도 사용자가 어플리케이션 전체를 다시 다운로드하도록 강제함.
  • -
  • 네이티브 플랫폼에 보다 통합된 외관과 느낌 — 홈 화면의 앱 아이콘, 전체 화면으로 실행되는 앱, 등.
  • -
  • 시스템 알림 및 푸시 메시지를 통한 사용자의 재 참여. 참여율이 높은 사용자와 더 나은 전환율을 이끌어 냄.
  • -
- -

PWA 라우트를 시도하고 네이티브 앱 보다 더 향상된 웹 사이트 경험을 선택하여 측정 가능한 의미있는 이득을 본 회사들의 성공 스토리가 많습니다. PWA Stats 웹 사이트는 이러한 이점을 나타내는 많은 사례 연구들을 공유합니다.

- -

가장 잘 알려진 성공 스토리는 아마 Flipkart Lite 일 것입니다 — 2015년에 프로그레시브 웹 앱으로 사이트를 재구축해 전환율을 70% 상승시킨 인도의 가장 큰 전자 상거래 사이트입니다. AliExpress PWA 역시 새로운 사용자에 대한 전환율을 104% 상승시키는 것으로 웹이나 네이티브 앱보다 훨씬 더 나은 결과를 보였습니다. 이윤 증가 및 PWA로 전환을 위해 상대적으로 적은 양의 작업을 놓고 봤을 때, 이점은 분명합니다.

- -

더 많은 예제는 pwa.rocks 의 목록에서 확인하시기 바랍니다. hnpwa.com 페이지는 특별히 언급할 가치가 있습니다 — 여기에는 일반적인 TodoMVC 앱 대신 다양한 프론트엔드 프레임워크의 사용을 볼 수 있는 Hacker News 웹사이트의 구현 예제가 나열되어 있습니다.

- -

심지어 PWABuilder 웹사이트를 사용해 PWA를 온라인에서 생성할수도 있습니다.

- -

Service worker와 푸시에 관련된 정보는 최신 사이트에서 service worker를 사용하는 예제를 모아둔 Service Worker Cookbook을 확인하시기 바랍니다.

- -

PWA 접근은 시도해볼만한 가치가 있으며, 여러분의 앱에서 동작하는지 스스로 확인해보시기 바랍니다.

- -

브라우저 호환성

- -

앞서 언급했듯이, PWA는 하나의 API에 의존하지 않고, 가능한 최고의 웹 경험을 전달하기 위한 목표를 달성하기 위해 다양한 기술들을 사용합니다.

- -

PWA를 위해 요구되는 핵심 요소는 service worker 지원입니다. 고맙게도 service worker는 현재 데스크탑 및 모바일의 모든 주요 브라우저에서 지원됩니다.

- -

웹 앱 Manifest, 푸시, 알림, 홈 화면에 추가 기능과 같은 다른 기능들도 널리 지원되고 있습니다. 현재 Safari에서는 웹 앱 Manifest 및 홈 화면에 추가에 지원이 제한적이며 웹 푸시 알림은 지원하지 않습니다. 반면, 다른 주요 브라우저에서는 이 모든 기능들을 지원합니다.

- -

이러한 API의 일부는 실험중이며 문서도 여전히 완성되지 않았지만, Flipkart 와 AliExpress와 같은 성공 스토리를 보면 여러분의 웹 앱에 PWA 기능의 일부를 시도하고 구현하는 것에 대해 이미 납득이 되었을것입니다.

- -

무엇보다도 여러분은 프로그레시브 향상 규칙을 따라야 합니다 — 이러한 향상을 제공하는 기술들은 지원이 되는 경우에만 사용하고, 그렇지 않은 경우에도 여전히 기본 기능을 제공하시기 바랍니다. 이 방법으로 모든 사용자가 앱을 사용할 수 있지만, 최신 브라우저를 사용하는 사용자는 PWA 기능으로부터 더 많은 이점을 얻을 수 있습니다.

- -

예시 어플리케이션

- -

이 문서 시리즈에서는 js13kGames 2017 대회의 A-Frame 카테고리에 제출된 게임에 대한 정보를 나열하는 아주 간단한 웹사이트의 소스코드를 살펴볼 것입니다. 여러분은 웹 사이트의 실제 컨텐츠가 무엇인지에 대해서는 생각할 필요가 없습니다 — 중요한 점은 여러분의 프로젝트에 PWA 기능을 어떻게 사용하는지를 배우는 것입니다.

- -

온라인 버전은 mdn.github.io/pwa-examples/js13kpwa (소스 코드도 확인하세요)에서 확인하실 수 있으며, 다음 몇 가지 문서에서 자세히 설명할 것입니다.

- -

이제, 우리의 예제 앱의 구조에 대해 살펴볼 이 시리즈의 두 번째 파트로 이동합시다.

- -

{{NextMenu("Web/Apps/Progressive/App_structure", "Web/Apps/Progressive")}}

diff --git a/files/ko/web/reference/api/index.html b/files/ko/web/reference/api/index.html new file mode 100644 index 0000000000..363fa9d3e9 --- /dev/null +++ b/files/ko/web/reference/api/index.html @@ -0,0 +1,65 @@ +--- +title: Web API 설명집 +slug: Web/참조/API +tags: + - API + - 대문 + - 웹 + - 편람 +translation_of: Web/Reference/API +--- +

여러분이 알고 있는 웹에는 여러 유용한 작업을 수행할 수 있는 다양한 API가 제공됩니다. 이러한 API는 자바스크립트(JavaScript) 코드를 사용하여 접근할 수 있으며 {{domxref("window")}}나 {{domxref("element")}}에 대한 간단한 작업에서부터 WebGL이나 Web Audio와 같은 API를 사용해 복잡한 그래픽 및 오디오 효과를 만들어내는 것까지 가능합니다.

+ +

모든 API에 대한 각각의 인터페이스는 색인에 열거돼 있습니다.

+ +

또한 이벤트 레퍼런스에 이용가능한 모든 이벤트 목록도 있습니다.

+ +
+
+
+
문서 객체 모델(Document Object Model)
+
DOM은 문서를 조회하거나 수정할 수 있는 API입니다. 문서의 {{domxref("Node")}} 및 {{domxref("Element")}}를 조작할 수 있습니다. HTML, XML, SVG는 DOM을 확장함으로써 각각의 실제적인 요소(element)를 조작합니다.
+
디바이스 API
+
본 API는 웹 페이지 및 애플리케이션에서 사용할 수 있는 다양한 하드웨어 기능을 조작합니다. 예: 주변 조명 센서 API, 배터리 상태 API, 지리적 위치 API, 포인터 잠금 API, 근접 API, 디바이스 방향성 API, 화면 방향성 API, 진동 API.
+
커뮤니케이션 API
+
본 API는 웹 페이지 및 애플리케이션에서 다른 페이지나 기기와 통신할 수 있습니다. 예: 네트워크 정보 API, 웹 알림, 단순 푸시 API.
+
데이터 관리 API
+
본 API는 사용자 데이터를 보관하고 관리할 수 있습니다. 예: FileHandle API, IndexedDB.
+
+ +

이러한 API는 어떠한 웹 사이트나 앱에서도 사용할 수 있지만 한정 권한 및 공인 애플리케이션에서는 더 강력한 Mozilla API 셋을 사용하실 수 있습니다.

+ +
+
한정 권한 API
+
한정 권한 애플리케이션은 설치 방식 앱으로서 사용자가 특정 권리를 허용한 것입니다. 한정 권한 API로는 TCP 소켓 API, 주소록 API, 디바이스 스토리지 API, 브라우저 API 등이 있습니다.
+
공인 API
+
공인된 애플리케이션은 파이어폭스 OS와 같은 운영체제에 중요한 조작을 수행하는 저층(low-level) 애플리케이션입니다. 한정 권한이 낮은 애플리케이션은 Web Activities를 사용하여 이러한 애플리케이션과 소통합니다. 공인 API로는 블루투스 API, 모바일 연결 API, 네트워크 상태 API, 전화 기능,WebSMS, 와이파이 정보 API, 카메라 API, 전원 관리 API, 설정 API, 대기 API,사용 권한 API, 시간/시계 API 등이 있습니다.
+
+
+ +
+

커뮤니티

+ +

저희 메일링 리스트나 뉴스그룹를 통해 Web API 커뮤니티에 참여하세요.

+ + + +

IRC에서 #webapi 채널의 실시간 토론도 꼭 참여하세요.

+ + + +

다음 주제도 확인해보세요.

+ + +
+
+ +

 

diff --git a/files/ko/web/reference/index.html b/files/ko/web/reference/index.html new file mode 100644 index 0000000000..f8d1a1dc35 --- /dev/null +++ b/files/ko/web/reference/index.html @@ -0,0 +1,30 @@ +--- +title: 웹 기술 문서 목록 +slug: Web/참조 +tags: + - Landing + - Reference + - Web +translation_of: Web/Reference +--- +

{{draft()}}
+ 오픈 웹은 많은 기술을 사용하여 구축됩니다. 이 기술들을 사용하기 위해서는 적절한 지식이 필요합니다.
+ 아래에서 각각의 참조 자료에 대한 링크를 찾아볼 수 있습니다.

+ +

웹 기술들

+ +

여러분에게 웹과 함께 시작하기를 추천하지만, 필수는 아닙니다.

+ +
+
HTML — Structuring the web
+
하이퍼텍스트 마크업언어(HyperText Markup Language)는 의미론적으로 웹 페이지의 콘텐츠(마크업)를 잘 구조화된 형식으로 의미론적으로 정의하고 표현하는데 사용됩니다. HTML은 HTML 요소(HTML elements)라고 불리는 불록으로 구성된 구조화된 문서를 작성하는 방법을 제공합니다. HTML요소는 태그로 구분되며, 꺽쇠괄호(<>)를 사용하여 표현합니다. 일부는 페이지에 직접 내용을 소개하고, 다른 일부는 문서 텍스트에 대한 정보를 제공하고, 다른 태그는 하위 요소로 포함할 수 있습니다. 분명히, 브라우저는 페이지 내용을 해석하는데 사용하기 때문에, 그대로 문서에 보여주지 않습니다.
+
+ HTML 소개| HTML 배우기 | HTML5 | 개발자 가이드 | HTML 요소 레퍼런스 | HTML 참조
+
CSS — Styling the web
+
Cascading Style Sheets 는 웹 컨텐츠의 모양을 꾸미는데 사용합니다.
+
+ CSS 소개 | CSS 시작하기 | CSS 배우기 | CSS3 | 개발자 가이드 | 일반적인 CSS 질문들 | CSS 참조
+
JavaScript — Dynamic client-side scripting
+
JavaScript 프로그래밍 언어는 사용자와의 대화식 이용 및 그외 동적 기능을 웹 사이트에 추가하는데 사용됩니다.
+
자바스크립트 배우기 | 개발자 가이드 | 자바스크립트 참조
+
diff --git "a/files/ko/web/security/\354\240\225\353\263\264_\353\263\264\354\225\210_\352\270\260\353\263\270/index.html" "b/files/ko/web/security/\354\240\225\353\263\264_\353\263\264\354\225\210_\352\270\260\353\263\270/index.html" deleted file mode 100644 index 48eeaed961..0000000000 --- "a/files/ko/web/security/\354\240\225\353\263\264_\353\263\264\354\225\210_\352\270\260\353\263\270/index.html" +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Information Security Basics -slug: Web/Security/정보_보안_기본 -translation_of: Web/Security/Information_Security_Basics ---- -

 정보 보안에 대한 기본적인 이해는 불안전하거나 취약점으로 인해 생긴 약점이 악의적인 이유로 악용되지 않게 당신을 도와줄 것입니다. 이 기사는 당신이 알아야 할 것을 배우는데 도움을 줄 것 입니다. 이 정보를 이용하면, 웹 개발주기 및 콘텐츠 배포를 넘어 보안의 역할과 중요성을 알게될 것입니다.

- -
-
신뢰성, 무결성, 가용성
-
보안을 이해하기 위해 필수적이고 기본적인 보안의 목적에 대해 설명합니다. 
-
취약점
-
취약점의 주요 카테고리를 정의하고, 모든 소프트웨어에 있는 취약점에 대해서 논의합니다. 
-
위협
-
주요한 위협의 개념에 대해 간단히 소개합니다.
-
보안 제어
-
보안 제어의 주요 카테고리를 정의하고, 잠재적인 단점에 대해서 논의합니다. 
-
TCP/IP 보안
-
SSL에 대한 보안 고려 사항에 초점을 맞춘 TCP / IP 모델의 개요.
-
- -

참고

- - diff --git a/files/ko/web/svg/element/rect/index.html b/files/ko/web/svg/element/rect/index.html new file mode 100644 index 0000000000..90a3d08d24 --- /dev/null +++ b/files/ko/web/svg/element/rect/index.html @@ -0,0 +1,95 @@ +--- +title: +slug: Web/SVG/Element/사각형 +translation_of: Web/SVG/Element/rect +--- +
{{SVGRef}}
+ +

<rect> 요소는 SVG 기본 모형이고 코너의 위치와 폭과 높이에 따라 사각형을 만드는데 사용된다. 또한 모서리가 둥근 사각형을 만들 수 있다.

+ +
+ + +
<svg viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
+  <!-- Simple rect element -->
+  <rect x="0" y="0" width="100" height="100" />
+
+  <!-- Rounded corner rect element -->
+  <rect x="120" y="0" width="100" height="100" rx="15" ry="15" />
+</svg>
+ +

{{EmbedLiveSample('Example', 100, '100%')}}

+
+ +

컨택스트 사용해보기

+ + + + + + + + + + + + + + + + +
카테고리기본 도형 요소, 그래픽 요소, 모형 요소
허용 된 콘텐츠Any number of the following elements, in any order:
+ Animation elements »
+ Descriptive elements »
규범 문서SVG 1.1 (2nd Edition)
+ +

Example

+ +

간단한 rect 사용하기

+ +

» rect-1.svg

+ +

라운드 코너와 rect 사용하기

+ +

» rect-2.svg

+ +

속성

+ +

전역 속성

+ + + +

지정 속성

+ +
    +
  • {{ SVGAttr("x") }}
  • +
  • {{ SVGAttr("y") }}
  • +
  • {{ SVGAttr("width") }}
  • +
  • {{ SVGAttr("height") }}
  • +
  • {{ SVGAttr("rx") }}
  • +
  • {{ SVGAttr("ry") }}
  • +
+ +

DOM Interface

+ +

This element implements the SVGRectElement interface.

+ +

Browser compatibility

+ +

{{Compat("svg.elements.rect")}}

+ +

See also

+ +
    +
  • {{ SVGElement("path") }}
  • +
diff --git "a/files/ko/web/svg/element/\354\202\254\352\260\201\355\230\225/index.html" "b/files/ko/web/svg/element/\354\202\254\352\260\201\355\230\225/index.html" deleted file mode 100644 index 90a3d08d24..0000000000 --- "a/files/ko/web/svg/element/\354\202\254\352\260\201\355\230\225/index.html" +++ /dev/null @@ -1,95 +0,0 @@ ---- -title: -slug: Web/SVG/Element/사각형 -translation_of: Web/SVG/Element/rect ---- -
{{SVGRef}}
- -

<rect> 요소는 SVG 기본 모형이고 코너의 위치와 폭과 높이에 따라 사각형을 만드는데 사용된다. 또한 모서리가 둥근 사각형을 만들 수 있다.

- -
- - -
<svg viewBox="0 0 220 100" xmlns="http://www.w3.org/2000/svg">
-  <!-- Simple rect element -->
-  <rect x="0" y="0" width="100" height="100" />
-
-  <!-- Rounded corner rect element -->
-  <rect x="120" y="0" width="100" height="100" rx="15" ry="15" />
-</svg>
- -

{{EmbedLiveSample('Example', 100, '100%')}}

-
- -

컨택스트 사용해보기

- - - - - - - - - - - - - - - - -
카테고리기본 도형 요소, 그래픽 요소, 모형 요소
허용 된 콘텐츠Any number of the following elements, in any order:
- Animation elements »
- Descriptive elements »
규범 문서SVG 1.1 (2nd Edition)
- -

Example

- -

간단한 rect 사용하기

- -

» rect-1.svg

- -

라운드 코너와 rect 사용하기

- -

» rect-2.svg

- -

속성

- -

전역 속성

- - - -

지정 속성

- -
    -
  • {{ SVGAttr("x") }}
  • -
  • {{ SVGAttr("y") }}
  • -
  • {{ SVGAttr("width") }}
  • -
  • {{ SVGAttr("height") }}
  • -
  • {{ SVGAttr("rx") }}
  • -
  • {{ SVGAttr("ry") }}
  • -
- -

DOM Interface

- -

This element implements the SVGRectElement interface.

- -

Browser compatibility

- -

{{Compat("svg.elements.rect")}}

- -

See also

- -
    -
  • {{ SVGElement("path") }}
  • -
diff --git a/files/ko/web/svg/svg_1.1_support_in_firefox/index.html b/files/ko/web/svg/svg_1.1_support_in_firefox/index.html new file mode 100644 index 0000000000..f8c31a2a8c --- /dev/null +++ b/files/ko/web/svg/svg_1.1_support_in_firefox/index.html @@ -0,0 +1,845 @@ +--- +title: SVG in Firefox +slug: SVG_in_Firefox +tags: + - SVG +translation_of: Web/SVG/SVG_1.1_Support_in_Firefox +--- +

Firefox 2는 더욱 폭넓은 Scalable Vector Graphics (SVG) 기능 구현을 위해서 계속해서 향상시켜 나가고 있습니다. 많은 스펙과 버그 수정들이 포함되었지만 Firefox 1.5이후 새로이 추가된 유일한 특징이 바로 <textPath>입니다. -- 아래 참조.

+

Firefox SVG는 SVG 1.1의 부분집합이지만 그렇다고 공식 프로필(Tiny, Basic, Full)들중 어느 것도 아닙니다. 각 내용들과 그것들이 Firefox 2에서 구현되었는지 아닌지에 대한 전체 내용은 문서의 마지막에서 찾을 수 있습니다. 문서의 나머지 부분은 우리의 구현상 제약사항들에 대한 정보를 제공할 것입니다.

+

우리들의 구현의 특이한 점들이 컨텐츠를 개발함에 있어서 번거로울 수도 있다는 것을 알고 있습니다. 하지만 커다란 스펙의 완전한 구현이 될 때까지 여러분의 인내를 부탁드립니다.

+

이 문서를 읽을때 이들 구현들의 세부사항들이 언제 바뀔지 궁금해할지도 모릅니다. 불행히도 현재 로드맵에 따르면 Gecko의 다음 버전에 기반한 Firefox의 공식 출시일이 꽤 나중이 되겠지만 2007년 1/4분기라고 나와있습니다. 그러나 새로운 기능을 시험해보고 싶다면 현재 개발중인 nightly builds를 사용해볼 수 있습니다.

+

성능

+

Firefox가 출시하는 모든 플랫폼은 같은 렌더링 백엔드 cairo를 사용합니다. 그래서 이들 간에 성능에 관한 특징은 일반적으로 유사할 것입니다. Linux에서의 성능은 예측하기가 가장 힘든데 이는 다양한 X서버마다 RENDER 확장의 구현이 다양하기 때문입니다.

+

Windows에서 SVG 렌더링은 다른 플랫폼상에서 보다도 상당히 빠릅니다.

+

좌표 범위

+

당신의 컨텐츠가 상당히 넓은 범위의 좌표를 가지는 구조를 가지고 있다면 cairo가 내부적으로 계산할 때 수를 16.16비트의 고정 소수점 표현 방식을 사용하기 때문에 발생할 수 있는 문제점들에 대해서 주의 깊게 고려해야 합니다. Cairo는 rasterization하기 전에 primitives들에 대한 클리핑을 하지 않기 때문에 변환과정 후 최종적으로 -32678에서 32677의 범위를 벗어나는 좌표들에 대해서는 렌더링 오류나 아주 느린 성능을 보여주기도 합니다.

+

Windows 98에서의 Text

+

안타깝게도 윈도우즈에서 cairo를 렌더링 엔진으로 사용한다면 Windows 98에서 텍스트 렌더링이 되지않는 버그가 있다. 사실, 그것보다 더 심각한 문제가 있다 : SVG 컨텐츠를 렌더링하는 도중에 텍스트를 만나면 모든 그리기 기능이 정지되어버리는 것이다.

+

폰트 선택

+

CSS에 익숙하다면 특정 폰트에서 들어있지 않은 기호들의 경우 폰트 속성에서 예비 폰트들을 지정할수 있다는 것을 알고 있을 것입니다. 현재 SVG 렌더링 백엔드는 단지 지정된 첫번째 폰트를 사용하도록 시도하며 만약 그 폰트가 없다면 플랫폼의 폰트를 사용하게 됩니다. 예비 폰트는 사용되지 않습니다; 그래서 예를 들면 font-family="Arial,LucidaSansUnicode" 이 코드는 Arial 폰트를 사용할 수 없는 경우 LucidaSansUnicode가 사용되게끔 하는 것은 아닙니다.

+

인쇄

+

아쉽지만 현재 인쇄는 SVG의 벡터 속성을 이용해서 매우 선명하게 출력해내도록 하는 부분은 완료되지 않았습니다. 하지만 화면 해상도정도로 그려져서 그 이미지처럼 출력됩니다.

+

Windows상에서 출력했을 때 폰트의 크기는 SVG에서 지정된 것보다도 훨씬 크게 출력됩니다.

+

그룹 opacity

+

그룹 opacity 속성인 opacity는 SVG 컨테이너 객체들을 부분적으로는 투명한 레이어로 다루어질 수 있도록 해주며, fill-opacitystroke-opacity들과는 독립적인 속성입니다. 현재 opacity의 구현은 꽤 느려서, 참으면서 사용을 해야할 겁니다. fill-opacitystroke-opacity는 훨씬 빠르며 컨텐츠에 따라서 같은 결과를 만들어 낼 수도 있습니다.

+

그룹 opacity는 현재 <g>에만 구현되어 있으며 <text><svg>는 구현되어 있지 않습니다.

+

폰트 기울이기

+

Microsoft Windows나 Mac OSX 플랫폼상에서는 문장의 기울였을때 내부의 채워짐이 정확히 일치하지 않습니다. 이 오차는 보통 매우 작은데 약간 더 기울이거나 함으로써 해결할 수 있습니다. 이 오차에 대한 예입니다:

+

그림:그림-text-fill-stroke.png

+

<image>

+

<image>는 Firefox 1.5의 SVG 이미지들에는 지원되지 않습니다; 대신에 Firefox에서 사용되는 유일한 raster 이미지 포맷입니다.

+

<image>의 모든 인스터스들은 사용되는 이미지와는 별도의 복사본을 가지는데 이는 만약 컨텐츠내에 아이콘과 같은 이미지에 대해 다수의 복사본을 사용한다면 새겨두어야 할 부분입니다. 안타깝게도 이 경우에 <image><use>는 또 다른 다른 복사본으로 간주합니다.

+

덧붙여, Firefox 1.5에서는 SVG에서 다수의 raster 이미지를 사용하면 성능히 심각하게 떨어질 수 있습니다.

+

Events

+

We support the SVG event attributes with the exception of onfocusin, onfocusout, and onactivate.

+

Our onload handling is currently somewhat nonstandard, but hopefully not in a way that hurts its use. While the code specified by the onload attribute is called for each element, an SVGLoad event is only fired for the root <svg> element. Some DOM methods will return garbage or an error if called before the corresponding element has been rendered, which you may need to take into account when writing onload code. Such methods are getBBox, getScreenCTM, etc.

+

We do not support the Adobe specific key events (onkeydown, onkeyup).

+

Interoperability

+

If you're working with current SVG content, you may encounter problems loading it into Firefox. Most of the problems tend to be fairly trivial, and are the result of Firefox being a stricter implementation. Jonathan Watt's SVG Authoring Guidelines explains the common problems.

+

SVG usage situations

+

Firefox 1.5 handles SVG as entire documents or when referenced by embed, object, or iframe. It cannot currently be used as source for an HTML or XHTML img element or for CSS properties that take an image reference.

+

Animation

+

Firefox 1.5 does not implement declarative animation, but does support dynamic scripting. Doug Shepers has used this to create SmilScript, a small Javascript library that implements a subset of SVG's declarative animation.

+

Bugs fixed in Firefox 2

+

Firefox 2 fixes some bugs in its SVG implementation. This section provides a quick overview of the most interesting ones.

+
    +
  • A problem filling and stroking text in which the drawing position isn't reset correctly between the two operations has been fixed (bug 333615).
  • +
+
    +
  • Radial gradients now properly clamp the fx and fy attributes to ensure that they're within the circumference of a circle (bug 330682).
  • +
+
    +
  • Text spans' and text elements' lengths can now be computed using their getComputedTextLength() methods, which improves compatibility with certain web sites (bugs 311031 and 264380).
  • +
+
    +
  • <tspan> elements now properly support the dx and dy attributes, and work if the x and y attributes aren't specified (bug 311063).
  • +
+
    +
  • Improved invalidation logic on redraws, which prevents dropped pixels in certain cases (bug 312269).
  • +
+
    +
  • Fixed a bug that prevented events from being handled properly for objects exposed by the clip path of another object (bug 315861).
  • +
+
    +
  • Fixed a bug that would crash if a <path> element had a d attribute with an empty string (bug 318379).
  • +
+
    +
  • The overflow attribute now works for the marker element, using the syntax overflow="visible", which did not previously work correctly (bug 320623).
  • +
+
    +
  • You can now access the <style> attribute of marker elements without throwing an exception (bug 323589).
  • +
+
    +
  • You can now use percent values for the radius of a radial gradient (bug 323669).
  • +
+
    +
  • The documentElement.createSVGAngle() method is now implemented (bug 327437).
  • +
+
    +
  • Making a <stop> element a child of another <stop> element no longer asserts (bug 328137).
  • +
+
    +
  • Changes to the height and width of markers, as well as to the orientation of the marker, now work (bug 325728).
  • +
+
    +
  • Font sizes when printing on Windows are no longer much larger than specified for SVG (bug 314707).
  • +
+

Element implementation status

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ElementNotes
Structure Module
svg +
    +
  • Implemented.
  • +
  • currentScale and currentTranslate DOM attributes are implemented, but there is no pan and zoom user interface.
  • +
  • SVGSVGElement +
      +
    • Unimplemented attributes: contentScriptType, contentStyleType, viewport, useCurrentView, currentView
    • +
    • Unimplemented bindings: pauseAnimations, unpauseAnimations, animationsPaused, getCurrentTime, setCurrentTime, getIntersectionList, getEnclosureList, checkIntersection, checkEnclosure, deselectAll, createSVGAngle, getElementById
    • +
    +
  • +
+
g +
    +
  • Implemented.
  • +
+
defs +
    +
  • Implemented.
  • +
+
desc +
    +
  • Implemented.
  • +
  • Only stored in the DOM, no user interface.</td>
  • +
+
title +
    +
  • Implemented.
  • +
+
metadata +
    +
  • Implemented.
  • +
  • Only stored in the DOM, no user interface.</td>
  • +
+
symbol +
    +
  • Implemented.
  • +
+
use +
    +
  • Implemented.
  • +
  • Only works for internal document references (bug 269482).
  • +
  • Doesn't completely follow <svg:use> cascading rules (bug 265894).
  • +
  • Doesn't deliver events to a SVGElementInstance tree (bug 265895).
  • +
+
Conditional Processing Module
switch +
    +
  • Implemented.
  • +
+
Image Module
image +
    +
  • Implemented.
  • +
  • Only works for raster images (bug 272288).
  • +
+
Style Module
style +
    +
  • Implemented.
  • +
+
Shape Module
path +
    +
  • Implemented.
  • +
  • SVGPathElement Interface +
      +
    • Unimplemented attributes: pathLength, normalizedPathSegList, animatedPathSegList, animatedNormalizedPathSegList
    • +
    • Unimplemented bindings: getTotalLength, getPointAtLength, getPathSegAtLength
    • +
    +
  • +
  • SVGPathSegList Interface +
      +
    • Unimplemented bindings: replaceItem()
    • +
    +
  • +
+
rect +
    +
  • Implemented.
  • +
+
circle +
    +
  • Implemented.
  • +
+
line +
    +
  • Implemented.
  • +
+
ellipse +
    +
  • Implemented.
  • +
+
polyline +
    +
  • Implemented.
  • +
+
polygon +
    +
  • Implemented.
  • +
+
Text Module
text +
    +
  • Implemented.
  • +
  • SVGTextElement +
      +
    • Unimplemented attributes: rotate, textLength, lengthAdjust
    • +
    • Unimplemented bindings: getNumberOfChars, getSubStringLength, getStartPositionOfChar, getEndPositionOfChar, getRotationOfChar, getCharNumAtPosition, selectSubString
    • +
    • Bindings not functional at onload time: getExtentOfChar
    • +
    +
  • +
+
tspan +
    +
  • Implemented.
  • +
  • SVGTSpanElement +
      +
    • Unimplemented attributes: rotate, textLength, lengthAdjust
    • +
    • Unimplemented bindings: getNumberOfChars, getComputedTextLength, getSubStringLength, getStartPositionOfChar, getEndPositionOfChar, getExtentOfChar, getRotationOfChar, getCharNumAtPosition, selectSubString
    • +
    +
  • +
+
tref +
    +
  • Not implemented.
  • +
+
textPath +
    +
  • Implemented in Firefox 2.
  • +
  • Unimplemented attributes: method, spacing, textLength, lengthAdjust
  • +
+
altGlyph +
    +
  • Not implemented.
  • +
+
altGlyphDef +
    +
  • Not implemented.
  • +
+
altGlyphItem +
    +
  • Not implemented.
  • +
+
glyphRef +
    +
  • Not implemented.
  • +
+
Marker Module
marker +
    +
  • Implemented.
  • +
+
Color Profile Module
color-profile +
    +
  • Not implemented.
  • +
+
Gradient Module
linearGradient +
    +
  • Implemented.
  • +
+
radialGradient +
    +
  • Implemented.
  • +
+
stop +
    +
  • Implemented.
  • +
+
Pattern Module
pattern +
    +
  • Not implemented.
  • +
+
Clip Module
clipPath +
    +
  • Implemented.
  • +
  • Won't handle clip paths with have elements with different clip-rule properties or that reference other clipPaths. (bug 267224).
  • +
+
Mask Module
mask +
    +
  • Not implemented.
  • +
+
Filter Module
filter +
    +
  • Not implemented.
  • +
+
feBlend +
    +
  • Not implemented.
  • +
+
feColorMatrix +
    +
  • Not implemented.
  • +
+
feComponentTransfer +
    +
  • Not implemented.
  • +
+
feComposite +
    +
  • Not implemented.
  • +
+
feConvolveMatrix +
    +
  • Not implemented.
  • +
+
feDiffuseLighting +
    +
  • Not implemented.
  • +
+
feDisplacementMap +
    +
  • Not implemented.
  • +
+
feFlood +
    +
  • Not implemented.
  • +
+
feGaussianBlur +
    +
  • Not implemented.
  • +
+
feImage +
    +
  • Not implemented.
  • +
+
feMerge +
    +
  • Not implemented.
  • +
+
feMergeNode +
    +
  • Not implemented.
  • +
+
feMorphology +
    +
  • Not implemented.
  • +
+
feOffset +
    +
  • Not implemented.
  • +
+
feSpecularLighting +
    +
  • Not implemented.
  • +
+
feTile +
    +
  • Not implemented.
  • +
+
feTurbulence +
    +
  • Not implemented.
  • +
+
feDistantLight +
    +
  • Not implemented.
  • +
+
fePointLight +
    +
  • Not implemented.
  • +
+
feSpotLight +
    +
  • Not implemented.
  • +
+
feFuncR +
    +
  • Not implemented.
  • +
+
feFuncG +
    +
  • Not implemented.
  • +
+
feFuncB +
    +
  • Not implemented.
  • +
+
feFuncA +
    +
  • Not implemented.
  • +
+
Cursor Module
cursor +
    +
  • Not implemented.
  • +
+
Hyperlinking Module
a +
    +
  • Implemented as an XBL binding - object is not of type SVGAElement.
  • +
  • Only xlink:href, xlink:show, and xlink:target (as of Firefox 2) attributes implemented.
  • +
+
View Module
view +
    +
  • Not implemented.
  • +
+
Scripting Module
script +
    +
  • Implemented.
  • +
+
Animation Module
animate +
    +
  • Not implemented.
  • +
+
set +
    +
  • Not implemented.
  • +
+
animateMotion +
    +
  • Not implemented.
  • +
+
animateTransform +
    +
  • Not implemented.
  • +
+
animateColor +
    +
  • Not implemented.
  • +
+
mpath +
    +
  • Not implemented.
  • +
+
Font Module
font +
    +
  • Not implemented.
  • +
+
font-face +
    +
  • Not implemented.
  • +
+
glyph +
    +
  • Not implemented.
  • +
+
missing-glyph +
    +
  • Not implemented.
  • +
+
hkern +
    +
  • Not implemented.
  • +
+
vkern +
    +
  • Not implemented.
  • +
+
font-face-src +
    +
  • Not implemented.
  • +
+
font-face-uri +
    +
  • Not implemented.
  • +
+
font-face-format +
    +
  • Not implemented.
  • +
+
font-face-name +
    +
  • Not implemented.
  • +
+
definition-src +
    +
  • Not implemented.
  • +
+
Extensibility Module
foreignObject +
    +
  • Implemented, but not built.
  • +
+
+

{{ languages( { "fr": "fr/SVG_dans_Firefox_1.5", "ja": "ja/SVG_in_Firefox_1.5", "pl": "pl/SVG_w_Firefoksie" } ) }}

diff --git a/files/ko/web/svg/tutorial/basic_shapes/index.html b/files/ko/web/svg/tutorial/basic_shapes/index.html new file mode 100644 index 0000000000..8169e4c890 --- /dev/null +++ b/files/ko/web/svg/tutorial/basic_shapes/index.html @@ -0,0 +1,141 @@ +--- +title: 기본 도형 +slug: Web/SVG/Tutorial/기본_도형 +translation_of: Web/SVG/Tutorial/Basic_Shapes +--- +

{{ PreviousNext("Web/SVG/Tutorial/Positions", "Web/SVG/Tutorial/Paths") }}

+ +

SVG 드로잉에는 몇 가지 기본 도형들이 있다. 도형들의 목적은 이름에서 명백하게 알 수 있다. 도형들의 위치와 크기를 지정하는 몇몇 속성들은 주어지지만, 여기에서 다뤄지지 않는 다른 속성들과 함께 더 정확하고 완전한 설명이 있는 레퍼런스를 첨부해 두겠다. 그러나, 대부분의 SVG 문서에서 사용되기 때문에 몇 가지 소개를 해줘야한다.

+ +

기본적인 도형들

+ +

도형을 삽입하기 위해서는 당신은 문서안에 요소를 만들어야 한다. 서로다른 요소들은 다른 모양에 해당하며, 서로 다른 속성들을 사용하여 해당 모양의 크기와 위치를 나타낸다. 일부는 다른 모양으로 생성 될 수 있다는 점에서 약간 중복되지만, 사용자의 편의를 위해 SVG 문서를 가능한 짧고 가독성있게 유지하기 위해서 모두 제공된다. 모든 기본 도형은 오른쪽 이미지에 표시된다. 기본 도형을 생성하는 코드는 다음과 같다:

+ +

+ +
<?xml version="1.0" standalone="no"?>
+<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
+
+  <rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
+  <rect x="60" y="10" rx="10" ry="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
+
+  <circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/>
+  <ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/>
+
+  <line x1="10" x2="50" y1="110" y2="150" stroke="orange" stroke-width="5"/>
+  <polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145"
+      stroke="orange" fill="transparent" stroke-width="5"/>
+
+  <polygon points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180"
+      stroke="green" fill="transparent" stroke-width="5"/>
+
+  <path d="M20,230 Q40,205 50,230 T90,230" fill="none" stroke="blue" stroke-width="5"/>
+</svg>
+ +
Note: stroke, stroke-width 그리고 fill 속성들은 튜토리얼 뒤쪽에서 설명한다.
+ +

Rectangles 사각형

+ +

rect 요소는 당신이 생각하는 것과 일치하며 화면에 사각형을 그린다. 여기에는 화면상에서 직사각형의 위치와 모양을 제어하는 6가지 기본 속성만 있다. 앞서 보여준 이미지는 두 개의 rect 요소를 보여주며 약간 중복된다. 오른쪽에 있는 이미지는 rx 와  ry 속성이 설정되어 있어서 모서리가 둥글다. rx 와 ry 가 설정되지 않은 경우에는 기본값 0으로 들어간다.

+ +
<rect x="10" y="10" width="30" height="30"/>
+<rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
+ +
+
x
+
사각형의 좌측 상단의 x 값을 의미한다.
+
y
+
사각형의 좌측 상단의 y 값을 의미한다.
+
width
+
사각형의 폭을 나타낸다.
+
height
+
사각형의 높이를 나타낸다. 
+
rx
+
사각형의 둥근 꼭짓점의 x 방향으로의 반지름이다.
+
ry
+
사각형의 둥근 꼭짓점의 y 방향으로의 반지름이다.
+
+ +

Circle 원

+ +

당신이 추측한 것 처럼, circle 요소는 화면에 원을 그린다. circle 요소에 실제로 적용할 수 있는 속성은 세 가지 뿐이다.

+ +
<circle cx="25" cy="75" r="20"/>
+ +
+
r
+
원의 반지름을 의미한다.
+
cx
+
원의 중심 중 x 값을 의미한다.
+
cy
+
원의 중심 중 y 값을 의미한다.
+
+ +

Ellipse 타원

+ +

Ellipses은 원의 x와 y 반경 (수학자들은 장반경, 단반경 이라고 함)을 개별적으로 확장 할 수 있는 circle 요소의 좀 더 일반적인 형태이다.

+ +
<ellipse cx="75" cy="75" rx="20" ry="5"/>
+ +
+
rx
+
타원의 x 방향으로의 반지름의 길이를 의미한다.
+
ry
+
타원의 y 방향으로의 반지름의 길이를 의미한다.
+
cx
+
타원의 중심 중 x 값을 의미한다.
+
cy
+
타원의 중심 중 y 값을 의미한다.
+
+ +

Line 선

+ +

Lines은 단지 직선이다. line 요소는 선의 시작과 끝 지점을 지정하는 두 점을 속성으로 갖는다.

+ +
<line x1="10" x2="50" y1="110" y2="150"/>
+ +
+
x1
+
점 1의 x 값이다.
+
y1
+
점 1의 y 값이다.
+
x2 
+
점 2의 x 값이다.
+
y2
+
점 2의 y 값이다.
+
+ +

Polyline

+ +

Polylines은 연결된 직선들의 그룹이다. 그 목록(직선들)은 꽤 길어질 수 있기 때문에 모든 포인트가 하나의 속성에 포함된다.

+ +
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
+ +
+
points
+
포인트들의 목록, 각 숫자는 공백, 쉼표, EOL 또는 줄 바꿈 문자로 구분된다. 각 포인트는 반드시 x 좌표와 y 좌표를 가지고 있어야 한다. 따라서 포인트 목록 (0,0), (1,1) 및 (2,2)는 "0 0, 1 1, 2 2"라고 쓸 수 있다.
+
+ +

Polygon 다각형

+ +

Polygons은 점을 연결하는 직선으로 구성된다는 점에서 polyline과 매우 유사하다. 하지만 다각형의 경우, 자동으로 마지막 포인트로부터 첫 번째 포인트로 직선을 만들어서 닫힌 모양을 만든다. 사각형은 다각형의 하나이므로, 융통성있는 사각형을 필요로 하는 경우 polygon 요소를 사용해서 rect 요소를 만들 수 있다.

+ +
<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>
+ +
+
points
+
포인트들의 목록, 각 숫자는 공백, 쉼표, EOL 또는 줄 바꿈 문자로 구분된다. 각 포인트는 반드시 x 좌표와 y 좌표를 가지고 있어야 한다. 따라서 포인트 목록 (0,0), (1,1) 및 (2,2)는 "0 0, 1 1, 2 2"라고 쓸 수 있다. 그러면 (2,2)에서 (0,0)으로 최종 직선이 그려져서 다각형이 완성된다.
+
+ +

Path

+ +

Path 는 아마 SVG에서 사용할 수 있는 가장 일반적인 형태일 것이다. path 요소를 사용해서 당신은 사각형(둥근 모서리가 있거나 없는), 원, 타원, 폴리라인 및 다각형을 그릴 수 있다. 기본적으로 다른 모든 종류의 모양, 베지에 곡선, 2차원 곡선 등이 가능하다. 그러한 이유로, paths 는 튜토리얼의 the next section 에 들어가지만, 지금은 모양을 제어하는 데 사용되는 단일 속성이 있음을 알려주겠다.

+ +
<path d="M 20 230 Q 40 205, 50 230 T 90230"/>
+ +
+
d
+
A list of points and other information about how to draw the path. See the Paths section for more information.
+
+ +
{{ PreviousNext("Web/SVG/Tutorial/Positions", "Web/SVG/Tutorial/Paths") }}
diff --git a/files/ko/web/svg/tutorial/getting_started/index.html b/files/ko/web/svg/tutorial/getting_started/index.html new file mode 100644 index 0000000000..8a0b5c82b7 --- /dev/null +++ b/files/ko/web/svg/tutorial/getting_started/index.html @@ -0,0 +1,94 @@ +--- +title: 시작하기 +slug: Web/SVG/Tutorial/시작하기 +tags: + - SVG + - 'SVG:Tutorial' + - 초보자 + - 튜토리얼 +translation_of: Web/SVG/Tutorial/Getting_Started +--- +

{{ PreviousNext("Web/SVG/Tutorial/Introduction", "Web/SVG/Tutorial/Positions") }}

+ +

간단한 예제

+ +

다음의 코드와 같이 간단한 예제로 시작해보겠습니다.

+ +
<svg version="1.1"
+     baseProfile="full"
+     width="300" height="200"
+     xmlns="http://www.w3.org/2000/svg">
+
+  <rect width="100%" height="100%" fill="red" />
+
+  <circle cx="150" cy="100" r="80" fill="green" />
+
+  <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
+
+</svg>
+
+ +

코드를 복사하여 demo1.svg로 저장하고, 파이어폭스 에서 실행해 봅시다. 아래와 같은 화면이 그려질 것입니다.(파이어 폭스 사용자 : 링크)

+ +

svgdemo1.png

+ +

화면이 그려지는 과정은 다음과 같습니다.

+ +
    +
  1. SVG 루트 요소(Element)부터 시작합니다. +
      +
    • DTD기반의 SVG유효성 검사는 해결할 수 있는 것보다 많은 문제를 야기하기 때문에 (X)HTML로 알려진 Doctype 선언은 사용하지 않습니다.
    • +
    • 다른 유형의 유효성 검사를 위해 SVG버전을 식별하려면 항상 version과 baseProfile 속성(Attribute)을 사용해야 합니다.
    • +
    • XML 특수언어(dialect)로서 SVG는 (xmlsn 속성에서) 항상 네임 스페이스(namespace)를 올바르게 바인딩 해야합니다. 자세한 내용은 네임 스페이스 충돌 과정 페이지를 참조하십시오.
    • +
    +
  2. +
  3. 전체 이미지 영역을 포함하는 사각형 <rect />을 그려 배경을 빨간색으로 설정합니다.
  4. +
  5. 빨간색 직사각형의 중앙에 반경 80px의 녹색 원 <circle />이 그려집니다
  6. +
  7. 텍스트 "SVG"가 그려집니다. 각 문자의 내부는 흰색으로 채워집니다. 텍스트는 중심점이 되고자 하는 지점에 앵커를 설정하여 배치됩니다.이 경우 중심점은 녹색 원의 중심에 일치해야합니다. 글꼴 크기와 수직 위치를 미세 조정하여 심미적으로 뛰어난 최종 결과를 얻을 수 있습니다.
  8. +
+ +

SVG 파일의 기본 속성

+ +
    +
  • 가장 먼저 주목해야 할 것은 요소를 렌더링하는 순서입니다. SVG 파일 전체에서 유효한 규칙은, 내용의 위에서 부터 아래로 렌더링된다는 것입니다. 요소는 아래에 위치할수록 더 잘보이게 됩니다.
  • +
  • 웹의 SVG 파일은 브라우저에 직접 표시되거나 HTML파일에 여러가지 방법을 통해 포함될 수 있습니다: +
      +
    • HTML이 XHTML이고 application/xhtml+xml 유형으로 제공되는 경우 SVG는 XML 소스에 직접 포함될 수 있습니다.
    • +
    • HTML이 HTML5이고 브라우저가 HTML5 브라우저를 준수하는 경우 SVG를 직접 삽입 할 수도 있습니다. 그러나 HTML5 사양을 준수하는 데 필요한 구문 변경이 있을 수 있습니다.
    • +
    • SVG 파일은 object 요소로 참조 할 수 있습니다: +
              <object data="image.svg" type="image/svg+xml" />
      +
    • +
    • 마찬가지로 iframe 요소로 사용할 수 있습니다: +
              <iframe src="image.svg"></iframe>
      +
    • +
    • 이론적으로, img 요소로 사용될 수 있습니다만 4.0 이전의 Firefox에서는 작동하지 않습니다.
    • +
    • 마지막으로 SVG는 JavaScript로 동적으로 생성되어 HTML DOM에 삽입 될 수 있습니다. 이는 SVG를 처리 할 수없는 브라우저에서 대체하여 구현할 수 있다는 장점이 있습니다.
    • +
    + 이 주제에 대해 깊이있게 다루기 위해 이 문서를 참조하십시오.
  • +
  • SVG에서 크기와 단위를 처리하는 방법에 대해서는 다음 페이지에서 설명 할 것입니다.
  • +
+ +

SVG 파일 형식

+ +

SVG 파일은 두 가지 형태로 제공됩니다. 일반 SVG 파일은 SVG 마크업이 포함 된 간단한 텍스트 파일입니다. 이러한 파일의 권장 파일 확장자는 소문자로 ".svg"입니다.

+ +

일부 응용 프로그램 (예 : 지리적 응용 프로그램)에 사용될 때 매우 큰 크기의 SVG 파일이 있을 수 있기 때문에 SVG 사양에서는 gzip으로 압축 된 SVG 파일을 허용합니다. 이러한 파일의 권장 파일 확장자는 소문자로 ".svgz"입니다. 하지만 안타깝게도 gzip으로 압축 된 SVG 파일을 Microsoft IIS 서버에서 서비스 할 때 모든 SVG 가능 브라우저(사용자 에이전트)에서 안정적으로 작동하게 하려면 문제가 많습니다. 그리고 Firefox는 로컬 컴퓨터에서 gzip으로 압축 된 SVG를 로드 할 수 없습니다. 웹 서버에 게시 할 때를 제외하고는 gzip으로 압축 된 SVG를 피하십시오 (아래 참조).

+ +

웹서버 관련 한 마디

+ +

이제 기본 SVG 파일을 만드는 방법에 대해 알아봤으므로 다음 단계는 웹 서버에 업로드하는 것입니다. 이 단계에서는 몇 가지 문제가 있습니다. 보통, SVG 파일의 경우 서버는 다음과 같이 HTTP 헤더를 보내야합니다.

+ +
Content-Type: image/svg+xml
+Vary: Accept-Encoding
+ +

gzip으로 압축 된 SVG 파일의 경우, 서버는 다음과 같이 HTTP 헤더를 보내야합니다.

+ +
Content-Type: image/svg+xml
+Content-Encoding: gzip
+Vary: Accept-Encoding
+ +

네트워크 모니터 패널이나 web-sniffer.net과 같은 사이트를 사용하여 서버가 SVG 파일과 함께 올바른 HTTP 헤더를 보내고 있는지 확인할 수 있습니다. SVG 파일 중 하나의 URL을 전송하고 HTTP 응답 헤더를 확인해 보십시오. 서버가 위의 값으로 헤더를 보내지 않으면 웹 호스트에 문의해야합니다. 서버에 SVG를 올바르게 구성하도록하는 데 문제가 있으면 직접 할 수있는 방법이있을 수 있습니다. 다양한 간단한 솔루션에 대해서는 w3.org의 서버 구성 페이지를 참조하십시오.

+ +

SVG를 사용하는데 있어 서버 구성 오류가 SVG로드에 실패하는 가장 일반적인 이유이기에 확인하십시오. 서버가 SVG 파일을 제공하면서 올바른 헤더를 보내도록 설정되어 있지 않다면 Firefox는 SVG파일의 마크업을 텍스트 또는 인코딩된 의미없는 값으로 표시하거나 뷰어에게 열어 볼 응용 프로그램을 선택하도록 요청할 가능성이 큽니다.

+ +

{{ PreviousNext("Web/SVG/Tutorial/Introduction", "Web/SVG/Tutorial/Positions") }}

diff --git a/files/ko/web/svg/tutorial/positions/index.html b/files/ko/web/svg/tutorial/positions/index.html new file mode 100644 index 0000000000..391765175c --- /dev/null +++ b/files/ko/web/svg/tutorial/positions/index.html @@ -0,0 +1,45 @@ +--- +title: 위치 +slug: Web/SVG/Tutorial/위치 +translation_of: Web/SVG/Tutorial/Positions +--- +

{{ PreviousNext("Web/SVG/Tutorial/Getting_Started", "Web/SVG/Tutorial/Basic_Shapes") }}

+ +

그리드

+ +

모든 요소(Element)에 대해 SVG는 캔버스를 포함한 컴퓨터에서 무언가 그리고자 할때 많이 사용되는 것과 유사한 좌표계 또는 그리드 시스템을 사용합니다. 즉, 문서의 왼쪽 위 모서리는 (0,0)으로 간주되며 한 지점의 위치는 왼쪽 상단 모서리에서 픽셀 단위로 표시되고 X축의 양의 방향은 오른쪽, Y축의  양의 방향은 아래쪽으로 향하게됩니다. 어린시절 배웠던 그래프와는 반대라는 점을 기억하세요. 그러나 이것은 HTML의 요소가 배치되는 것과는 같은 방법입니다 (기본적으로 LTR 문서는 X를 오른쪽에서 왼쪽으로 배치하는 RTL 문서가 아닙니다).

+ +

예제:

+ +

아래 요소는

+ +
<rect x="0" y="0" width="100" height="100" />
+
+ +

왼쪽 상단에서 100px의 정사각형을 정의합니다.

+ +

"픽셀"이란?

+ +

기본적으로 SVG 문서에서 1픽셀은 출력 장치(화면)의 1픽셀에 매핑됩니다. 하지만 이러한 방식만 가능했다면 SVG의 이름에 "확장성(Scalable)"이란 단어가 들어가 있지는 않았겠죠. CSS의 절대 및 상대 글꼴 크기와 매우 흡사하게 SVG는 절대적인 단위 ( "pt"또는 "cm"와 같은 식별자가있는 것)를 정의하고 이것을 사용자 단위(User Unit)로 명칭하며, 이것은 별도의 식별자 없이 숫자 그대로를 사용합니다.

+ +

별도로 명시하지 않았다면, 사용자 단위와 화면 단위는 1:1의 비율로 동작합니다. SVG에는 이 비율을 변경하기 위한 몇가지 방법이 있습니다.

+ +
<svg width="100" height="100">
+
+ +

위 요소는 100x100px 의 SVG 캔버스를 정의합니다. 사용자 단위와 화면 단위는 1:1의 비율로 동작합니다.

+ +
<svg width="200" height="200" viewBox="0 0 100 100">
+
+ +

SVG 캔버스 전체 크기는 200x200 픽셀입니다. 그러나 viewBox속성을 사용하여 (0,0)에서 시작하는 100x100px의 화면을 200x200px의 화면에 출력합니다. 이렇게하면 100x100 단위 영역을 효과적으로 확대하고 이미지를 두 배 크기로 확대 할 수 있습니다.

+ +

이러한 요소 혹은 전체 이미지의 사용자 단위와 화면 단위의 매핑을 사용자 좌표계(User coordinate system)이라고 합니다. 스케일링 외에도 회전, 기울이기, 뒤집기가 가능합니다. 기본 사용자 좌표계는 하나의 사용자 픽셀을 하나의 장치 픽셀에 매핑합니다. SVG파일에서 "in"또는 "cm"과 같은 특정 치수는 결과 이미지에서 1:1로 보이도록 계산됩니다.

+ +

SVG 1.1 스펙에서는 다음과 같이 인용합니다:

+ +
+

[...] 사용자 환경에서 "1px"이 "0.2822222mm" 에 대응한다고 가정했을때(90dpi), SVG는 다음과 같이 처리한다: [...] "1cm"는 "35.43307px"과 같다. (그리고 35.43307 사용자 단위와 같다.)

+
+ +

{{ PreviousNext("Web/SVG/Tutorial/Getting_Started", "Web/SVG/Tutorial/Basic_Shapes") }}

diff --git a/files/ko/web/svg/tutorial/svg_and_css/index.html b/files/ko/web/svg/tutorial/svg_and_css/index.html new file mode 100644 index 0000000000..d8ca001fb2 --- /dev/null +++ b/files/ko/web/svg/tutorial/svg_and_css/index.html @@ -0,0 +1,195 @@ +--- +title: SVG graphics +slug: Web/CSS/Getting_Started/SVG_graphics +tags: + - 'CSS:Getting_Started' +translation_of: Web/SVG/Tutorial/SVG_and_CSS +--- +

이 페이지는 그래픽을 만들기 위한 특별한 언어 SVG를 설명합니다.

+

SVG 기능이 있는 모질라 브라우저에서 작동하는 간단한 예제를 만듭니다.

+

정보: SVG

+

+ + SVG + (Scalable Vector Graphics, 스케일러블 벡터 그래픽)은 그래픽을 만들어내기 위한 XML-기반 언어입니다.

+

움직이지 않는 이미지(static image)를 위해 사용될 수 있으며, 또한 애니메이션 과 사용자 인터페이스를 위해서도 사용될 수 있습니다.

+

다른 XML-기반 언어들과 같이, SVG는 CSS 스타일 시트를 지원하여 그래픽에 사용되는 스타일을 그래픽의 내용물과 분리시킬 수 있게 합니다.

+

또한, 다른 문서 마크업 언어들과 함께 사용되는 스타일 시트들도 이미지가 요구되는 곳에 SVG 그래픽의 URL을 지정할 수 있습니다. 예를들면, HTML 문서와 함께 사용하는 스타일 시트에서 background 속성 값에 SVG값의 URL을 지정할 수 있습니다.

+ + + + + + + +
+ More details
이글을 쓰는 시점에서(2005년 중반), 모질라 브라우저의 몇몇 최근 빌드만이 SVG 지원을 내장하고 있었습니다. +

Adobe에서 제공되는 것 같은 플럭인(plugin)을 인스톨하면 다른 버전에서도 SVG 지원을 추가할 수 있습니다.

+

모질라에서의 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 기능이 있는(SVG-enabled) 브라우저에서 여세요. 마우스 포인터(mouse pointer)를 그래픽위로 움직여 보세요.

+

이 위키페이지는 SVG를 지원하지 않습니다. 따라서 예제가 어떻게 실행되는 지 보여드릴 수 없습니다. 다음과 같이 보입니다:

+ + + + + + +
SVG demonstration
+

이 예제에서 주의할 점:

+
    +
  • SVG 문서는 전처럼 스타일 시트에 링크되어 있습니다.
  • +
  • SVG는 그 자신만의 CSS 스타일 시트와 값을 가지고 있습니다. 이들중 몇가지는 HTML을 위한 CSS의 속성과 비슷합니다.
  • +
+ + + + + + + +
+ Challenge
스타일 시트를 변경해서, 마우스 포인터가 안쪽 꽃잎들 중 한개 위에 오게 되면, 바깥 쪽 꽃잎이 작동하는 방식은 바뀌지 않은채 모든 안쪽꽃잎 색이 핑크(pink)색으로 변하게 하세요
+

그럼 다음은?

+

If you had difficulty understanding this page, or if you have other comments about it, please contribute to its Discussion page.

+

이 예제에서 SVG 기능이 있는(SVG enabled) 브라우저는 이미 SVG 엘리먼트를 디스플레이하는 방법을 알고 있습니다. 스타일 시트는 단지 그 디스플레이를 특정 방식으로 수정할 뿐 입니다. 그러나 디스플레이하는 방식이 미리 지정되어 있지 않은 범용(general-purpose) XML 문서를 위해서 CSS를 사용할 수있습니다. 다음 페이지에서는 이를 실행해 봅니다: XML data

+

{{ languages( { "fr": "fr/CSS/Premiers_pas/Graphiques_SVG", "pl": "pl/CSS/Na_pocz\u0105tek/Grafika_SVG" } ) }}

diff --git "a/files/ko/web/svg/tutorial/\352\270\260\353\263\270_\353\217\204\355\230\225/index.html" "b/files/ko/web/svg/tutorial/\352\270\260\353\263\270_\353\217\204\355\230\225/index.html" deleted file mode 100644 index 8169e4c890..0000000000 --- "a/files/ko/web/svg/tutorial/\352\270\260\353\263\270_\353\217\204\355\230\225/index.html" +++ /dev/null @@ -1,141 +0,0 @@ ---- -title: 기본 도형 -slug: Web/SVG/Tutorial/기본_도형 -translation_of: Web/SVG/Tutorial/Basic_Shapes ---- -

{{ PreviousNext("Web/SVG/Tutorial/Positions", "Web/SVG/Tutorial/Paths") }}

- -

SVG 드로잉에는 몇 가지 기본 도형들이 있다. 도형들의 목적은 이름에서 명백하게 알 수 있다. 도형들의 위치와 크기를 지정하는 몇몇 속성들은 주어지지만, 여기에서 다뤄지지 않는 다른 속성들과 함께 더 정확하고 완전한 설명이 있는 레퍼런스를 첨부해 두겠다. 그러나, 대부분의 SVG 문서에서 사용되기 때문에 몇 가지 소개를 해줘야한다.

- -

기본적인 도형들

- -

도형을 삽입하기 위해서는 당신은 문서안에 요소를 만들어야 한다. 서로다른 요소들은 다른 모양에 해당하며, 서로 다른 속성들을 사용하여 해당 모양의 크기와 위치를 나타낸다. 일부는 다른 모양으로 생성 될 수 있다는 점에서 약간 중복되지만, 사용자의 편의를 위해 SVG 문서를 가능한 짧고 가독성있게 유지하기 위해서 모두 제공된다. 모든 기본 도형은 오른쪽 이미지에 표시된다. 기본 도형을 생성하는 코드는 다음과 같다:

- -

- -
<?xml version="1.0" standalone="no"?>
-<svg width="200" height="250" version="1.1" xmlns="http://www.w3.org/2000/svg">
-
-  <rect x="10" y="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
-  <rect x="60" y="10" rx="10" ry="10" width="30" height="30" stroke="black" fill="transparent" stroke-width="5"/>
-
-  <circle cx="25" cy="75" r="20" stroke="red" fill="transparent" stroke-width="5"/>
-  <ellipse cx="75" cy="75" rx="20" ry="5" stroke="red" fill="transparent" stroke-width="5"/>
-
-  <line x1="10" x2="50" y1="110" y2="150" stroke="orange" stroke-width="5"/>
-  <polyline points="60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145"
-      stroke="orange" fill="transparent" stroke-width="5"/>
-
-  <polygon points="50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180"
-      stroke="green" fill="transparent" stroke-width="5"/>
-
-  <path d="M20,230 Q40,205 50,230 T90,230" fill="none" stroke="blue" stroke-width="5"/>
-</svg>
- -
Note: stroke, stroke-width 그리고 fill 속성들은 튜토리얼 뒤쪽에서 설명한다.
- -

Rectangles 사각형

- -

rect 요소는 당신이 생각하는 것과 일치하며 화면에 사각형을 그린다. 여기에는 화면상에서 직사각형의 위치와 모양을 제어하는 6가지 기본 속성만 있다. 앞서 보여준 이미지는 두 개의 rect 요소를 보여주며 약간 중복된다. 오른쪽에 있는 이미지는 rx 와  ry 속성이 설정되어 있어서 모서리가 둥글다. rx 와 ry 가 설정되지 않은 경우에는 기본값 0으로 들어간다.

- -
<rect x="10" y="10" width="30" height="30"/>
-<rect x="60" y="10" rx="10" ry="10" width="30" height="30"/>
- -
-
x
-
사각형의 좌측 상단의 x 값을 의미한다.
-
y
-
사각형의 좌측 상단의 y 값을 의미한다.
-
width
-
사각형의 폭을 나타낸다.
-
height
-
사각형의 높이를 나타낸다. 
-
rx
-
사각형의 둥근 꼭짓점의 x 방향으로의 반지름이다.
-
ry
-
사각형의 둥근 꼭짓점의 y 방향으로의 반지름이다.
-
- -

Circle 원

- -

당신이 추측한 것 처럼, circle 요소는 화면에 원을 그린다. circle 요소에 실제로 적용할 수 있는 속성은 세 가지 뿐이다.

- -
<circle cx="25" cy="75" r="20"/>
- -
-
r
-
원의 반지름을 의미한다.
-
cx
-
원의 중심 중 x 값을 의미한다.
-
cy
-
원의 중심 중 y 값을 의미한다.
-
- -

Ellipse 타원

- -

Ellipses은 원의 x와 y 반경 (수학자들은 장반경, 단반경 이라고 함)을 개별적으로 확장 할 수 있는 circle 요소의 좀 더 일반적인 형태이다.

- -
<ellipse cx="75" cy="75" rx="20" ry="5"/>
- -
-
rx
-
타원의 x 방향으로의 반지름의 길이를 의미한다.
-
ry
-
타원의 y 방향으로의 반지름의 길이를 의미한다.
-
cx
-
타원의 중심 중 x 값을 의미한다.
-
cy
-
타원의 중심 중 y 값을 의미한다.
-
- -

Line 선

- -

Lines은 단지 직선이다. line 요소는 선의 시작과 끝 지점을 지정하는 두 점을 속성으로 갖는다.

- -
<line x1="10" x2="50" y1="110" y2="150"/>
- -
-
x1
-
점 1의 x 값이다.
-
y1
-
점 1의 y 값이다.
-
x2 
-
점 2의 x 값이다.
-
y2
-
점 2의 y 값이다.
-
- -

Polyline

- -

Polylines은 연결된 직선들의 그룹이다. 그 목록(직선들)은 꽤 길어질 수 있기 때문에 모든 포인트가 하나의 속성에 포함된다.

- -
<polyline points="60 110, 65 120, 70 115, 75 130, 80 125, 85 140, 90 135, 95 150, 100 145"/>
- -
-
points
-
포인트들의 목록, 각 숫자는 공백, 쉼표, EOL 또는 줄 바꿈 문자로 구분된다. 각 포인트는 반드시 x 좌표와 y 좌표를 가지고 있어야 한다. 따라서 포인트 목록 (0,0), (1,1) 및 (2,2)는 "0 0, 1 1, 2 2"라고 쓸 수 있다.
-
- -

Polygon 다각형

- -

Polygons은 점을 연결하는 직선으로 구성된다는 점에서 polyline과 매우 유사하다. 하지만 다각형의 경우, 자동으로 마지막 포인트로부터 첫 번째 포인트로 직선을 만들어서 닫힌 모양을 만든다. 사각형은 다각형의 하나이므로, 융통성있는 사각형을 필요로 하는 경우 polygon 요소를 사용해서 rect 요소를 만들 수 있다.

- -
<polygon points="50 160, 55 180, 70 180, 60 190, 65 205, 50 195, 35 205, 40 190, 30 180, 45 180"/>
- -
-
points
-
포인트들의 목록, 각 숫자는 공백, 쉼표, EOL 또는 줄 바꿈 문자로 구분된다. 각 포인트는 반드시 x 좌표와 y 좌표를 가지고 있어야 한다. 따라서 포인트 목록 (0,0), (1,1) 및 (2,2)는 "0 0, 1 1, 2 2"라고 쓸 수 있다. 그러면 (2,2)에서 (0,0)으로 최종 직선이 그려져서 다각형이 완성된다.
-
- -

Path

- -

Path 는 아마 SVG에서 사용할 수 있는 가장 일반적인 형태일 것이다. path 요소를 사용해서 당신은 사각형(둥근 모서리가 있거나 없는), 원, 타원, 폴리라인 및 다각형을 그릴 수 있다. 기본적으로 다른 모든 종류의 모양, 베지에 곡선, 2차원 곡선 등이 가능하다. 그러한 이유로, paths 는 튜토리얼의 the next section 에 들어가지만, 지금은 모양을 제어하는 데 사용되는 단일 속성이 있음을 알려주겠다.

- -
<path d="M 20 230 Q 40 205, 50 230 T 90230"/>
- -
-
d
-
A list of points and other information about how to draw the path. See the Paths section for more information.
-
- -
{{ PreviousNext("Web/SVG/Tutorial/Positions", "Web/SVG/Tutorial/Paths") }}
diff --git "a/files/ko/web/svg/tutorial/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" "b/files/ko/web/svg/tutorial/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" deleted file mode 100644 index 8a0b5c82b7..0000000000 --- "a/files/ko/web/svg/tutorial/\354\213\234\354\236\221\355\225\230\352\270\260/index.html" +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: 시작하기 -slug: Web/SVG/Tutorial/시작하기 -tags: - - SVG - - 'SVG:Tutorial' - - 초보자 - - 튜토리얼 -translation_of: Web/SVG/Tutorial/Getting_Started ---- -

{{ PreviousNext("Web/SVG/Tutorial/Introduction", "Web/SVG/Tutorial/Positions") }}

- -

간단한 예제

- -

다음의 코드와 같이 간단한 예제로 시작해보겠습니다.

- -
<svg version="1.1"
-     baseProfile="full"
-     width="300" height="200"
-     xmlns="http://www.w3.org/2000/svg">
-
-  <rect width="100%" height="100%" fill="red" />
-
-  <circle cx="150" cy="100" r="80" fill="green" />
-
-  <text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
-
-</svg>
-
- -

코드를 복사하여 demo1.svg로 저장하고, 파이어폭스 에서 실행해 봅시다. 아래와 같은 화면이 그려질 것입니다.(파이어 폭스 사용자 : 링크)

- -

svgdemo1.png

- -

화면이 그려지는 과정은 다음과 같습니다.

- -
    -
  1. SVG 루트 요소(Element)부터 시작합니다. -
      -
    • DTD기반의 SVG유효성 검사는 해결할 수 있는 것보다 많은 문제를 야기하기 때문에 (X)HTML로 알려진 Doctype 선언은 사용하지 않습니다.
    • -
    • 다른 유형의 유효성 검사를 위해 SVG버전을 식별하려면 항상 version과 baseProfile 속성(Attribute)을 사용해야 합니다.
    • -
    • XML 특수언어(dialect)로서 SVG는 (xmlsn 속성에서) 항상 네임 스페이스(namespace)를 올바르게 바인딩 해야합니다. 자세한 내용은 네임 스페이스 충돌 과정 페이지를 참조하십시오.
    • -
    -
  2. -
  3. 전체 이미지 영역을 포함하는 사각형 <rect />을 그려 배경을 빨간색으로 설정합니다.
  4. -
  5. 빨간색 직사각형의 중앙에 반경 80px의 녹색 원 <circle />이 그려집니다
  6. -
  7. 텍스트 "SVG"가 그려집니다. 각 문자의 내부는 흰색으로 채워집니다. 텍스트는 중심점이 되고자 하는 지점에 앵커를 설정하여 배치됩니다.이 경우 중심점은 녹색 원의 중심에 일치해야합니다. 글꼴 크기와 수직 위치를 미세 조정하여 심미적으로 뛰어난 최종 결과를 얻을 수 있습니다.
  8. -
- -

SVG 파일의 기본 속성

- -
    -
  • 가장 먼저 주목해야 할 것은 요소를 렌더링하는 순서입니다. SVG 파일 전체에서 유효한 규칙은, 내용의 위에서 부터 아래로 렌더링된다는 것입니다. 요소는 아래에 위치할수록 더 잘보이게 됩니다.
  • -
  • 웹의 SVG 파일은 브라우저에 직접 표시되거나 HTML파일에 여러가지 방법을 통해 포함될 수 있습니다: -
      -
    • HTML이 XHTML이고 application/xhtml+xml 유형으로 제공되는 경우 SVG는 XML 소스에 직접 포함될 수 있습니다.
    • -
    • HTML이 HTML5이고 브라우저가 HTML5 브라우저를 준수하는 경우 SVG를 직접 삽입 할 수도 있습니다. 그러나 HTML5 사양을 준수하는 데 필요한 구문 변경이 있을 수 있습니다.
    • -
    • SVG 파일은 object 요소로 참조 할 수 있습니다: -
              <object data="image.svg" type="image/svg+xml" />
      -
    • -
    • 마찬가지로 iframe 요소로 사용할 수 있습니다: -
              <iframe src="image.svg"></iframe>
      -
    • -
    • 이론적으로, img 요소로 사용될 수 있습니다만 4.0 이전의 Firefox에서는 작동하지 않습니다.
    • -
    • 마지막으로 SVG는 JavaScript로 동적으로 생성되어 HTML DOM에 삽입 될 수 있습니다. 이는 SVG를 처리 할 수없는 브라우저에서 대체하여 구현할 수 있다는 장점이 있습니다.
    • -
    - 이 주제에 대해 깊이있게 다루기 위해 이 문서를 참조하십시오.
  • -
  • SVG에서 크기와 단위를 처리하는 방법에 대해서는 다음 페이지에서 설명 할 것입니다.
  • -
- -

SVG 파일 형식

- -

SVG 파일은 두 가지 형태로 제공됩니다. 일반 SVG 파일은 SVG 마크업이 포함 된 간단한 텍스트 파일입니다. 이러한 파일의 권장 파일 확장자는 소문자로 ".svg"입니다.

- -

일부 응용 프로그램 (예 : 지리적 응용 프로그램)에 사용될 때 매우 큰 크기의 SVG 파일이 있을 수 있기 때문에 SVG 사양에서는 gzip으로 압축 된 SVG 파일을 허용합니다. 이러한 파일의 권장 파일 확장자는 소문자로 ".svgz"입니다. 하지만 안타깝게도 gzip으로 압축 된 SVG 파일을 Microsoft IIS 서버에서 서비스 할 때 모든 SVG 가능 브라우저(사용자 에이전트)에서 안정적으로 작동하게 하려면 문제가 많습니다. 그리고 Firefox는 로컬 컴퓨터에서 gzip으로 압축 된 SVG를 로드 할 수 없습니다. 웹 서버에 게시 할 때를 제외하고는 gzip으로 압축 된 SVG를 피하십시오 (아래 참조).

- -

웹서버 관련 한 마디

- -

이제 기본 SVG 파일을 만드는 방법에 대해 알아봤으므로 다음 단계는 웹 서버에 업로드하는 것입니다. 이 단계에서는 몇 가지 문제가 있습니다. 보통, SVG 파일의 경우 서버는 다음과 같이 HTTP 헤더를 보내야합니다.

- -
Content-Type: image/svg+xml
-Vary: Accept-Encoding
- -

gzip으로 압축 된 SVG 파일의 경우, 서버는 다음과 같이 HTTP 헤더를 보내야합니다.

- -
Content-Type: image/svg+xml
-Content-Encoding: gzip
-Vary: Accept-Encoding
- -

네트워크 모니터 패널이나 web-sniffer.net과 같은 사이트를 사용하여 서버가 SVG 파일과 함께 올바른 HTTP 헤더를 보내고 있는지 확인할 수 있습니다. SVG 파일 중 하나의 URL을 전송하고 HTTP 응답 헤더를 확인해 보십시오. 서버가 위의 값으로 헤더를 보내지 않으면 웹 호스트에 문의해야합니다. 서버에 SVG를 올바르게 구성하도록하는 데 문제가 있으면 직접 할 수있는 방법이있을 수 있습니다. 다양한 간단한 솔루션에 대해서는 w3.org의 서버 구성 페이지를 참조하십시오.

- -

SVG를 사용하는데 있어 서버 구성 오류가 SVG로드에 실패하는 가장 일반적인 이유이기에 확인하십시오. 서버가 SVG 파일을 제공하면서 올바른 헤더를 보내도록 설정되어 있지 않다면 Firefox는 SVG파일의 마크업을 텍스트 또는 인코딩된 의미없는 값으로 표시하거나 뷰어에게 열어 볼 응용 프로그램을 선택하도록 요청할 가능성이 큽니다.

- -

{{ PreviousNext("Web/SVG/Tutorial/Introduction", "Web/SVG/Tutorial/Positions") }}

diff --git "a/files/ko/web/svg/tutorial/\354\234\204\354\271\230/index.html" "b/files/ko/web/svg/tutorial/\354\234\204\354\271\230/index.html" deleted file mode 100644 index 391765175c..0000000000 --- "a/files/ko/web/svg/tutorial/\354\234\204\354\271\230/index.html" +++ /dev/null @@ -1,45 +0,0 @@ ---- -title: 위치 -slug: Web/SVG/Tutorial/위치 -translation_of: Web/SVG/Tutorial/Positions ---- -

{{ PreviousNext("Web/SVG/Tutorial/Getting_Started", "Web/SVG/Tutorial/Basic_Shapes") }}

- -

그리드

- -

모든 요소(Element)에 대해 SVG는 캔버스를 포함한 컴퓨터에서 무언가 그리고자 할때 많이 사용되는 것과 유사한 좌표계 또는 그리드 시스템을 사용합니다. 즉, 문서의 왼쪽 위 모서리는 (0,0)으로 간주되며 한 지점의 위치는 왼쪽 상단 모서리에서 픽셀 단위로 표시되고 X축의 양의 방향은 오른쪽, Y축의  양의 방향은 아래쪽으로 향하게됩니다. 어린시절 배웠던 그래프와는 반대라는 점을 기억하세요. 그러나 이것은 HTML의 요소가 배치되는 것과는 같은 방법입니다 (기본적으로 LTR 문서는 X를 오른쪽에서 왼쪽으로 배치하는 RTL 문서가 아닙니다).

- -

예제:

- -

아래 요소는

- -
<rect x="0" y="0" width="100" height="100" />
-
- -

왼쪽 상단에서 100px의 정사각형을 정의합니다.

- -

"픽셀"이란?

- -

기본적으로 SVG 문서에서 1픽셀은 출력 장치(화면)의 1픽셀에 매핑됩니다. 하지만 이러한 방식만 가능했다면 SVG의 이름에 "확장성(Scalable)"이란 단어가 들어가 있지는 않았겠죠. CSS의 절대 및 상대 글꼴 크기와 매우 흡사하게 SVG는 절대적인 단위 ( "pt"또는 "cm"와 같은 식별자가있는 것)를 정의하고 이것을 사용자 단위(User Unit)로 명칭하며, 이것은 별도의 식별자 없이 숫자 그대로를 사용합니다.

- -

별도로 명시하지 않았다면, 사용자 단위와 화면 단위는 1:1의 비율로 동작합니다. SVG에는 이 비율을 변경하기 위한 몇가지 방법이 있습니다.

- -
<svg width="100" height="100">
-
- -

위 요소는 100x100px 의 SVG 캔버스를 정의합니다. 사용자 단위와 화면 단위는 1:1의 비율로 동작합니다.

- -
<svg width="200" height="200" viewBox="0 0 100 100">
-
- -

SVG 캔버스 전체 크기는 200x200 픽셀입니다. 그러나 viewBox속성을 사용하여 (0,0)에서 시작하는 100x100px의 화면을 200x200px의 화면에 출력합니다. 이렇게하면 100x100 단위 영역을 효과적으로 확대하고 이미지를 두 배 크기로 확대 할 수 있습니다.

- -

이러한 요소 혹은 전체 이미지의 사용자 단위와 화면 단위의 매핑을 사용자 좌표계(User coordinate system)이라고 합니다. 스케일링 외에도 회전, 기울이기, 뒤집기가 가능합니다. 기본 사용자 좌표계는 하나의 사용자 픽셀을 하나의 장치 픽셀에 매핑합니다. SVG파일에서 "in"또는 "cm"과 같은 특정 치수는 결과 이미지에서 1:1로 보이도록 계산됩니다.

- -

SVG 1.1 스펙에서는 다음과 같이 인용합니다:

- -
-

[...] 사용자 환경에서 "1px"이 "0.2822222mm" 에 대응한다고 가정했을때(90dpi), SVG는 다음과 같이 처리한다: [...] "1cm"는 "35.43307px"과 같다. (그리고 35.43307 사용자 단위와 같다.)

-
- -

{{ PreviousNext("Web/SVG/Tutorial/Getting_Started", "Web/SVG/Tutorial/Basic_Shapes") }}

diff --git a/files/ko/web/xpath/introduction_to_using_xpath_in_javascript/index.html b/files/ko/web/xpath/introduction_to_using_xpath_in_javascript/index.html new file mode 100644 index 0000000000..e15574b588 --- /dev/null +++ b/files/ko/web/xpath/introduction_to_using_xpath_in_javascript/index.html @@ -0,0 +1,367 @@ +--- +title: Introduction to using XPath in JavaScript +slug: Introduction_to_using_XPath_in_JavaScript +tags: + - Add-ons + - 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 개체를 반환합니다. 이 메소드를 다루는 기존 문서는 여기에 있지만 당장 우리 필요에 좀 부족하여, 더 이해가 빠른 설명을 아래에 제공합니다.

+ +
var xpathResult = document.evaluate( xpathExpression, contextNode, namespaceResolver, resultType, result );
+
+ +

매개변수

+ +

evaluate 함수는 매개변수를 총 5개 취합니다.

+ +
    +
  • xpathExpression: 평가할 XPath 식을 포함하는 문자열
  • +
+ +
    +
  • contextNode: xpathExpression이 평가될 모든 자식 노드를 포함하는 문서의 노드. document 노드가 가장 흔히 쓰입니다.
  • +
+ +
    +
  • namespaceResolver: 그 접두사와 관련된 namespace URI를 나타내는 문자열을 반환하는 xpathExpression 내에 포함되는 모든 namespace 접두사를 넘겨주는 함수. 이는 XPath 식에 쓰(이)는 접두사와 문서에 쓰(이)는 아마도 다른 접두사 사이에 변환을 가능하게 합니다. 함수는 어느 한쪽일 수 있습니다. + +
      +
    • XPathEvaluator 개체의 createNSResolver 메소드를 써서 만듭니다. 항상 가상으로 이를 쓰면 좋습니다.
    • +
    • HTML 문서를 위해서나 namespace 접두사가 없을 때 쓸 수 있는 null. 만약 xpathExpression가 namespace 접두사를 포함하면 이는 NAMESPACE_ERR 코드를 내는 DOMException을 가져옴을 유의하세요.
    • +
    • 사용자 정의 맞춤(custom) 함수. 세부 내용은 부록의 사용자 정의 Namespace Resolver 쓰기 절을 보세요.
    • +
    +
  • +
+ +
    +
  • resultType: 평가 결과로 반환되기 바랐던 결과 형을 지정하는 상수. 가장 흔히 넘겨주는 상수는 가장 자연스러운 형으로 XPath 식의 결과를 반환하는 XPathResult.ANY_TYPE입니다. 부록에 쓸 수 있는 상수 목록 전체를 포함하는 절이 있습니다. 아래 반환형 지정 절에서 설명합니다.
  • +
+ +
    +
  • result: 결과를 반환하는 데 재사용하는 기존 XPathResult 개체나 새 XPathResult 개체를 만드는 데 쓸 수 있는 null 가운데 하나.
  • +
+ +

반환값

+ +

resultType 매개변수에서 지정한 형의 XPathResult 개체인 xpathResult를 반환합니다. XPathResult 인터페이스는 여기에서 정의됩니다.

+ +

Default Namespace Resolver 구현

+ +

우리는 document 개체의 createNSResolver 메소드를 써서 namespace resolver를 만듭니다.

+ +
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 함수에 namespaceResolver 매개변수로 nsResolver 변수를 넘겨줍니다.

+ +

XPath는 null namespace의 단 하나 뿐인 요소와 일치하는 접두사 없는 QNames을 정의함을 유의하세요. XPath에는 기본 namespace를 얻는 방법이 없습니다. null이 아닌 namespace의 요소나 속성을 일치시키려면, 접두사 붙은 이름 검사를 쓰고 접두사를 namespace에 매핑하는 namespace resolver를 만들어야 합니다. 아래 사용자 정의 namespace resolver 만드는 법을 더 읽으세요.

+ +

반환형 지정

+ +

document.evaluate로부터 반환하는 변수 xpathResult는 개별 노드 (단순 형)나 노드 모음(collection) (node-set 형) 가운데 하나로 구성할 수 있습니다.

+ +

단순 형

+ +

resultType으로 바랐던 결과형을 어느 한쪽으로 지정할 때,

+ +
    +
  • NUMBER_TYPE - a double
  • +
  • STRING_TYPE - a string
  • +
  • BOOLEAN_TYPE - a boolean
  • +
+ +

우리는 XPathResult 개체의 다음 속성에 각각 접근하여 식의 반환값을 얻습니다.

+ +
    +
  • numberValue
  • +
  • stringValue
  • +
  • booleanValue
  • +
+ +
+ +

다음은 HTML 문서의 <p> 요소수를 얻기 위해 XPath 식 count(//p)을 씁니다.

+ +
var paragraphCount = document.evaluate( 'count(//p)', document, null, XPathResult.ANY_TYPE, null );
+
+alert( 'This document contains ' + paragraphCount.numberValue + ' paragraph elements' );
+
+ +

비록 Javascript가 표시를 위해 숫자를 문자열로 변환하는 것을 허용하더라도, stringValue 속성(property)을 요청하면 XPath 인터페이스는 자동으로 숫자 결과로 변환하지 않습니다. 그래서 다음 코드는 작동하지 '<big>않</big>'습니다.

+ +
var paragraphCount = document.evaluate('count(//p)', document, null, XPathResult.ANY_TYPE, null );
+
+alert( 'This document contains ' + paragraphCount.stringValue + ' paragraph elements' );
+
+ +

대신 NS_DOM_TYPE_ERROR 코드를 갖는 예외(exception)를 반환합니다.

+ +

Node-Set 형

+ +

XPathResult 개체는 주요한 3가지 서로 다른 형으로 반환될 node-set을 허용합니다.

+ + + +
반복자(훑개)
+ +

resultType 매개변수로 지정한 결과형이 어느 한쪽일 때,

+ +
    +
  • UNORDERED_NODE_ITERATOR_TYPE
  • +
  • ORDERED_NODE_ITERATOR_TYPE
  • +
+ +

반환되는 XPathResult 개체는 일치하는 노드(XPathResultiterateNext() 메소드를 써서 포함될 개별 노드에 접근함을 허용하는 반복자로 행동할)의 노드 집합입니다.

+ +

우리가 모든 일치하는 개별 노드에 반복하고 나면, iterateNext()null을 반환합니다.

+ +

그러나 주의하세요, 만약 반복 도중에 문서가 바뀌면 (문서 tree가 변경됨) 그것은 반복을 무효로 만들고(invalidate) XPathResultinvalidIteratorState 속성을 true로 지정하고 NS_ERROR_DOM_INVALID_STATE_ERR 예외를 냅니다.

+ +
반복자 예
+ +
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 iteraton ' + e );
+}
+
+ +
Snapshots
+ +

resultType 매개변수로 지정한 결과형이 어느 한쪽일 때,

+ +
    +
  • UNORDERED_NODE_SNAPSHOT_TYPE
  • +
  • ORDERED_NODE_SNAPSHOT_TYPE
  • +
+ +

반환되는 XPathResult 개체는 일치하는 노드의 static node-set이고, 그것은 itemNumber가 검색(retrieve)되는 노드의 index인 XPathResult 개체의 snapshotItem(itemNumber) 메소드를 통해 각 노드에 접근을 허용합니다. 포함되는 노드의 총수는 snapshotLength 속성을 통해 입수할 수 있습니다.

+ +

Snapshot은 변환 문서로 바꾸지 않습니다. 그래서 반복자와는 달리 snapshot은 무효로 만들지는 않지만 현재 문서와 들어맞지 않을지도 모릅니다, 예를 들어 노드가 이동됐을지도 모르고, 더 이상 존재하지 않는 노드나 추가될 수 있는 새 노드를 포함할지도 모릅니다.

+ +
Snapshot 예
+ +
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입니다.

+ +

순서 없는 subtype인 경우 반환되는 단일 노드가 문서 순으로 처음이 아닐지도 모르지만 순서 있는 subtype인 경우 문서 순으로 처음 일치하는 노드임을 보장함을 유의하세요.

+ +
First Node 예
+ +
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_TYPE, STRING_TYPE, BOOLEAN_TYPE ) 가운데 하나일 수도 있습니다, <big>하지만</big>, 만약 반환되는 결과형이 node-set이면 <big>오직</big> UNORDERED_NODE_ITERATOR_TYPE입니다.

+ +

평가 뒤 형을 결정하기 위해서, 우리는 XPathResult 개체의 resultType 속성을 씁니다. 이 속성의 상수값은 부록에서 정의합니다. None Yet =====Any_Type 예===== <pre> </pre>

+ +

+ +

HTML 문서 안에서

+ +

다음 코드는 XPath 식이 평가될 HTML 문서 안에서나 문서에 연결(link)된 어떤 JavaScript 조각(fragment)에 놓을 셈입니다.

+ +

XPath를 써서 HTML의 모든 <h2> heading 요소를 뽑아내면(extract), xpathExpression 문자열은 간단히 '//h2'입니다. 어떤 점에서, //는 요소 트리 어디에서나 노드명 h2와 요소를 일치시키는 재귀 내림 연산자(Recursive Descent Operator)입니다. 이를 위한 자세한 코드입니다. link to introductory xpath doc

+ +
var headings = document.evaluate('//h2', document, null, XPathResult.ANY_TYPE, null );
+
+ +

HTML이 namespace가 없기 때문에, 우리는 namespaceResolver 매개변수에 null을 넘겨줌을 유의하세요.

+ +

우리가 문서 전체에서 heading을 찾기를 바라기 때문에, 우리는 contextNodedocument 개체 자신을 씁니다.

+ +

이 식의 결과는 XPathResult 개체입니다. 우리가 반환되는 결과형을 알고 싶다면, 우리는 반환되는 개체의 resultType 속성을 평가할지도 모릅니다. 이 경우에는 그것은 값이 4UNORDERED_NODE_ITERATOR_TYPE로 평가합니다. 이는 XPath 식의 결과가 node-set일 때 기본 반환형입니다. 동시에 단일 노드로 접근을 제공하고 특정 순서로 노드를 반환할지도 모릅니다. 반환되는 개체에 접근하기 위해, 우리는 반환되는 개체의 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 interfaces에 접근할 수 있습니다. 우리 식에서 반환된 모든 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 문서의 컨텐트를 쓸 수 있게, 우리는 문서를 로드하는 동시에 변수 xmlDoc를 우리가 evaluate 메소드를 쓸 수 있는 XMLDocument 개체로 문서에 포함하는 XMLHttpRequest 개체를 만듭니다,

+ +

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 );
+
+ +

부록

+ +

사용자 정의 Namespace Resolver 구현

+ +

이는 단지 설명을 위한 예입니다. 이 함수는 xpathExpression에서 namespace 접두사를 취할 필요가 있고 그 접두사와 들어맞는 URI를 반환합니다. 예를 들어, 다음 식은

+ +
'//xhtml:td/mathml:math'
+
+ +

(X)HTML 표 데이터 셀 요소의 자식인 모든 MathML 식을 선택합니다.

+ +

mathml: 접두사를 namespace URI 'http://www.w3.org/1998/Math/MathML'와 html:을 URI http://www.w3.org/1999/xhtml와 관련시키기 위해 우리는 함수 하나를 제공합니다.

+ +
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 );
+
+ +

XPathResult 정의 상수

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
결과형 정의 상수설명
ANY_TYPE0식 평가에서 자연스럽게 생긴 어떤 형을 포함하는 결과 집합. 만약 결과가 node-set이면 UNORDERED_NODE_ITERATOR_TYPE이 항상 결과형임을 주의하세요.
NUMBER_TYPE1single 숫자를 포함하는 결과. 이는 예를 들어, count() 함수를 쓰는 XPath 식에 쓸모가 있습니다.
STRING_TYPE2single 문자열을 포함하는 결과.
BOOLEAN_TYPE3single boolean 값을 포함하는 결과. 이는 예를 들어, not() 함수를 쓰는 XPath 식에 쓸모가 있습니다.
UNORDERED_NODE_ITERATOR_TYPE4식과 일치하는 모든 노드를 포함하는 결과 node-set. 노드는 반드시 문서에 나타나는 순서대로가 아닐지도 모릅니다.
ORDERED_NODE_ITERATOR_TYPE5식과 일치하는 모든 노드를 포함하는 결과 node-set. 결과 집합의 노드는 문서에 나타나는 순서대로입니다.
UNORDERED_NODE_SNAPSHOT_TYPE6식과 일치하는 모든 노드의 snapshot을 포함하는 결과 node-set. 노드는 반드시 문서에 나타나는 순서대로가 아닐지도 모릅니다.
ORDERED_NODE_SNAPSHOT_TYPE7식과 일치하는 모든 노드의 snapshot을 포함하는 결과 node-set. 결과 집합의 노드는 문서에 나타나는 순서대로입니다.
ANY_UNORDERED_NODE_TYPE8식과 일치하는 어떤 단일 노드를 포함하는 결과 node-set. 노드는 식과 일치하는 문서의 첫 노드일 필요는 없습니다.
FIRST_ORDERED_NODE_TYPE9식과 일치하는 문서의 첫 노드를 포함하는 결과 node-set.
+ +
+

원본 문서 정보

+ +
    +
  • 원본 문서 Mozilla XPath 입문서를 기반으로 함
  • +
  • 원본 소스 저자: James Graham.
  • +
  • 다른 기여자: James Thompson.
  • +
  • 맨 나중 업데이트: 2006-3-25.
  • +
+
+ +

{{ languages( { "en": "en/Introduction_to_using_XPath_in_JavaScript" } ) }}

diff --git a/files/ko/web/xslt/apply-imports/index.html b/files/ko/web/xslt/apply-imports/index.html deleted file mode 100644 index 9377bd2538..0000000000 --- a/files/ko/web/xslt/apply-imports/index.html +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: apply-imports -slug: Web/XSLT/apply-imports -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/apply-imports ---- -

{{ XsltRef() }}

-


- <xsl:apply-imports> 요소는 꽤 불가사의하고 보통은 복잡한 스타일시트에 쓰입니다. 가져오기(import) 우선순위는 가져온 스타일시트 안 템플릿 규칙보다 주 스타일시트의 안 템플릿 규칙이 더 높기를 요구합니다. 그러나, 때로는 처리기(processor)가 주 스타일시트 안 규칙보다 (우선순위가 낮은) 가져온 스타일시트의 템플릿 규칙을 쓰도록 강제할 수 있는 게 유용합니다.

-

문법

-
<xsl:apply-imports/>
-

필수 속성

-

없음.

-

선택 속성

-

없음.

-

타입

-

명령, 템플릿 안에 나타남

-

정의

-

XSLT section 5.6, Overriding Template Rules

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/apply-templates/index.html b/files/ko/web/xslt/apply-templates/index.html deleted file mode 100644 index fdb8662849..0000000000 --- a/files/ko/web/xslt/apply-templates/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: apply-templates -slug: Web/XSLT/apply-templates -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/apply-templates ---- -

{{ XsltRef() }}

-

<xsl:apply-templates> 요소는 입력 트리 안 노드 집합을 선택하고 그 집합에 알맞은 템플릿을 적용하도록 처리기에게 지시합니다.

-

문법

-
<xsl:apply-templates select=EXPRESSION mode=NAME>
-	<xsl:with-param> [optional]
-	<xsl:sort> [optional]
-</xsl:apply-templates>
-

필수 속성

-

없음.

-

선택 속성

-
-
- select
-
- 처리할 노드를 지정하는 XPath 식을 씁니다. 별표(*)는 전체 노드 집합을 선택합니다. 이 속성이 없으면, 현재 노드의 모든 자식 노드를 선택합니다.
-
- mode
-
- 같은 노드를 정의하는 다양한 처리 방법이 있다면, 그 방법들을 구별합니다.
-
-

타입

-

명령, 템플릿 안에 나타남

-

정의

-

XSLT section 5.4, Applying Template Rules

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/attribute-set/index.html b/files/ko/web/xslt/attribute-set/index.html deleted file mode 100644 index e4b34b6b21..0000000000 --- a/files/ko/web/xslt/attribute-set/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: attribute-set -slug: Web/XSLT/attribute-set -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/attribute-set ---- -

{{ XsltRef() }}

-

<xsl:attribute-set> 요소는 CSS 안에 이름 붙인 스타일과 비슷한 방식으로 이름 붙인 속성 집합을 만듭니다. 그러면, 출력 문서에 전체로서 적용할 수 있습니다.

-

문법

-
<xsl:attribute-set name=NAME use-attribute-sets=LIST-OF-NAMES>
-	<xsl:attribute>
-</xsl:attribute-set>
-

필수 속성

-
-
- name
-
- 속성 집합에 이름을 지정합니다. 이름은 유효한 QName이어야 합니다.
-
-

선택 속성

-
-
- use-attribute-sets
-
- 다른 속성 집합으로부터 속성 집합을 빌드합니다. 기여한 집합의 이름은 공백 문자로 구분해야 하고 직접 혹은 간접으로 서로 임베드하지 않아야 합니다.
-
-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 7.1.4, Named Attribute Sets

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/attribute/index.html b/files/ko/web/xslt/attribute/index.html deleted file mode 100644 index 1c348584f7..0000000000 --- a/files/ko/web/xslt/attribute/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: attribute -slug: Web/XSLT/attribute -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/attribute ---- -

{{ XsltRef() }}

-

<xsl:attribute> 요소는 스타일시트에서 접근할 수 있는 어떤 값을 써서 출력 문서에 속성을 만듭니다. 요소는 속성값을 자리 잡게 하는 출력 문서 요소 안에 정의한 것 가운데 처음이어야 합니다.

-

문법

-
<xsl:attribute name=NAME namespace=URI>
-	TEMPLATE
-</xsl:attribute>
-

필수 속성

-
-
- name
-
- 출력 문서에 만들려는 속성에 이름을 지정합니다. 이름은 유효한 QName이어야 합니다.
-
-

선택 속성

-
-
- namespace
-
- 출력 문서에 이 속성을 위한 이름공간(namespace) URI를 정의합니다. 이 요소와 관련된 이름공간 접두사를 설정할 수 없습니다.
-
-

타입

-

명령, 템플릿이나 <xsl:attribute-set> 요소 안에 나타남.

-

정의

-

XSLT section 7.1.3, Creating Attributes with xsl:attribute

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/call-template/index.html b/files/ko/web/xslt/call-template/index.html deleted file mode 100644 index c5aa8c1a53..0000000000 --- a/files/ko/web/xslt/call-template/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: call-template -slug: Web/XSLT/call-template -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/call-template ---- -

{{ XsltRef() }}

-

<xsl:call-template> 요소는 이름 붙인 템플릿을 호출합니다.

-

문법

-
<xsl:call-template name=NAME>
-	<xsl:with-param> [optional]
-</xsl:call-template> 
-

필수 속성

-
-
- name
-
- 호출하고 싶은 템플릿의 이름을 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 6, Named Templates

-

Gecko 지원

-

지원함.

-

{{ languages( { "en": "en/XSLT/call-template" } ) }}

diff --git a/files/ko/web/xslt/choose/index.html b/files/ko/web/xslt/choose/index.html deleted file mode 100644 index ea615e7e15..0000000000 --- a/files/ko/web/xslt/choose/index.html +++ /dev/null @@ -1,24 +0,0 @@ ---- -title: choose -slug: Web/XSLT/choose -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/choose ---- -

{{ XsltRef() }}

-

<xsl:choose> 요소는 많은 선택 가운데 하나를 정의합니다. 그리고 절차형 언어(procedural language)의 스위치 문처럼 동작합니다.

-

문법

-
<xsl:choose>
-	<xsl:when>
-	<xsl:otherwise> [optional]
-</<xsl:choose>
-

필수 속성

-

없음.

-

선택 속성

-

없음.

-

타입

-

명령, 템플릿과 함께 나타남. 하나 이상의 <xsl:when> 요소를 포함하고 선택에 따라 마지막에 <xsl:otherwise> 요소를 포함합니다.

-

정의

-

XSLT section 9.2, Conditional Processing with xsl:choose

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/comment/index.html b/files/ko/web/xslt/comment/index.html deleted file mode 100644 index 56b12a9968..0000000000 --- a/files/ko/web/xslt/comment/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: comment -slug: Web/XSLT/comment -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/comment ---- -

{{ XsltRef() }}

-

<xsl:comment> 요소는 출력 문서에 주석을 작성합니다. 오직 텍스트만 포함해야 합니다.

-

문법

-
<xsl:comment>
-	TEMPLATE
-</xsl:comment> 
-

필수 속성

-

없음.

-

선택 속성

-

없음.

-

타입

-

명령, 템플릿과 함께 나타남.

-

정의

-

XSLT section 7.4, Creating Comments

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/copy-of/index.html b/files/ko/web/xslt/copy-of/index.html deleted file mode 100644 index cfd00ae443..0000000000 --- a/files/ko/web/xslt/copy-of/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: copy-of -slug: Web/XSLT/copy-of -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/copy-of ---- -

{{ XsltRef() }}

-

<xsl:copy-of> 요소는 select 속성이 출력 문서에 무엇을 지정하든지 (자손 노드를 포함하여) 깊게 복사(deep copy)합니다.

-

문법

-
<xsl:copy-of select=EXPRESSION /> 
-

필수 속성

-
-
- select
-
- 복사할 대상을 지정하는 XPath 식을 씁니다.
-
-

선택 속성

-

없음.

-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 11.3, Using Values of Variables and Parameters with xsl:copy-of

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/copy/index.html b/files/ko/web/xslt/copy/index.html deleted file mode 100644 index 7d6e480167..0000000000 --- a/files/ko/web/xslt/copy/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: copy -slug: Web/XSLT/copy -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/copy ---- -

{{ XsltRef() }}

-

<xsl:copy> 요소는 출력 문서에 현재 노드의 노드와 어떤 관련 이름공간 노드만을 얕게 복사(shallow copy) 전달합니다. 속성이나 자식은 복사하지 않습니다.

-

문법

-
<xsl:copy use-attribute-sets=LIST-OF-NAMES>
-	TEMPLATE
-</xsl:copy>
-

필수 속성

-

없음.

-

선택 속성

-
-
- use-attribute-sets
-
- 요소이면, 출력 노드에 적용해도 좋을 속성 집합을 나열합니다. 집합의 이름은 공백 문자로 구분해야 합니다.
-
-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 7.5, Copying

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/decimal-format/index.html b/files/ko/web/xslt/decimal-format/index.html deleted file mode 100644 index 83e51a2e90..0000000000 --- a/files/ko/web/xslt/decimal-format/index.html +++ /dev/null @@ -1,100 +0,0 @@ ---- -title: decimal-format -slug: Web/XSLT/decimal-format -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/decimal-format ---- -

{{ XsltRef() }}

-

<xsl:decimal-format> 요소는 - - format-number( ) - 함수를 써서 숫자를 문자열로 바꿀 때 쓰는 기호와 문자를 정의합니다.

-

문법

-
<xsl:decimal-format
-	name=NAME
-	decimal-separator=CHARACTER
-	grouping-separator=CHARACTER
-	infinity=STRING
-	minus-sign=CHARACTER
-	NaN=STRING
-	percent=CHARACTER
-	per-mille=CHARATER
-	zero-digit=CHARACTER
-	digit=CHARACTER
-	pattern-separator=CHARACTER />
-

필수 속성

-

없음.

-

선택 속성

-
-
- name
-
- 이 형식에 이름을 지정합니다.
-
-
-
- decimal-separator
-
- 소숫점 문자를 지정합니다. 기본값은 (.)입니다.
-
-
-
- grouping-separator
-
- 그룹 구분 문자를 지정합니다. 기본값은 (,)입니다.
-
-
-
- infinity
-
- 무한대(infinity)를 나타내는데 쓰는 문자열을 지정합니다. 기본값은 "Infinity" 문자열입니다.
-
-
-
- minus-sign
-
- 빼기 기호 문자를 지정합니다. 기본값은 (-)입니다.
-
-
-
- NaN
-
- 값이 숫자가 아닐 때 쓰는 문자열을 지정합니다. 기본값은 "NaN" 문자열입니다.
-
-
-
- percent
-
- 백분율(percentage) 기호 문자를 지정합니다. 기본값은 (%)입니다.
-
-
-
- per-mille
-
- 천분율(per thousand) 문자를 지정합니다. 기본값은 ()입니다.
-
-
-
- zero-digit
-
- 숫자 0으로 쓸 문자를 지정합니다. 기본값은 (0)입니다.
-
-
-
- digit
-
- 형식 패턴에서 숫자(digit)를 나타내는데 쓰는 문자를 지정합니다. 기본값은 (#)입니다.
-
-
-
- pattern-separator
-
- 형식 패턴에서 양수와 음수 부분패턴을 구분하는 문자를 지정합니다. 기본값은 (;)입니다.
-
-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 12.3, Number Formatting

-

Gecko 지원

-

Mozilla 1.0과 Netscape 7.0 현재 지원함.

diff --git a/files/ko/web/xslt/element/apply-imports/index.html b/files/ko/web/xslt/element/apply-imports/index.html new file mode 100644 index 0000000000..9377bd2538 --- /dev/null +++ b/files/ko/web/xslt/element/apply-imports/index.html @@ -0,0 +1,22 @@ +--- +title: apply-imports +slug: Web/XSLT/apply-imports +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/apply-imports +--- +

{{ XsltRef() }}

+


+ <xsl:apply-imports> 요소는 꽤 불가사의하고 보통은 복잡한 스타일시트에 쓰입니다. 가져오기(import) 우선순위는 가져온 스타일시트 안 템플릿 규칙보다 주 스타일시트의 안 템플릿 규칙이 더 높기를 요구합니다. 그러나, 때로는 처리기(processor)가 주 스타일시트 안 규칙보다 (우선순위가 낮은) 가져온 스타일시트의 템플릿 규칙을 쓰도록 강제할 수 있는 게 유용합니다.

+

문법

+
<xsl:apply-imports/>
+

필수 속성

+

없음.

+

선택 속성

+

없음.

+

타입

+

명령, 템플릿 안에 나타남

+

정의

+

XSLT section 5.6, Overriding Template Rules

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/apply-templates/index.html b/files/ko/web/xslt/element/apply-templates/index.html new file mode 100644 index 0000000000..fdb8662849 --- /dev/null +++ b/files/ko/web/xslt/element/apply-templates/index.html @@ -0,0 +1,33 @@ +--- +title: apply-templates +slug: Web/XSLT/apply-templates +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/apply-templates +--- +

{{ XsltRef() }}

+

<xsl:apply-templates> 요소는 입력 트리 안 노드 집합을 선택하고 그 집합에 알맞은 템플릿을 적용하도록 처리기에게 지시합니다.

+

문법

+
<xsl:apply-templates select=EXPRESSION mode=NAME>
+	<xsl:with-param> [optional]
+	<xsl:sort> [optional]
+</xsl:apply-templates>
+

필수 속성

+

없음.

+

선택 속성

+
+
+ select
+
+ 처리할 노드를 지정하는 XPath 식을 씁니다. 별표(*)는 전체 노드 집합을 선택합니다. 이 속성이 없으면, 현재 노드의 모든 자식 노드를 선택합니다.
+
+ mode
+
+ 같은 노드를 정의하는 다양한 처리 방법이 있다면, 그 방법들을 구별합니다.
+
+

타입

+

명령, 템플릿 안에 나타남

+

정의

+

XSLT section 5.4, Applying Template Rules

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/attribute-set/index.html b/files/ko/web/xslt/element/attribute-set/index.html new file mode 100644 index 0000000000..e4b34b6b21 --- /dev/null +++ b/files/ko/web/xslt/element/attribute-set/index.html @@ -0,0 +1,33 @@ +--- +title: attribute-set +slug: Web/XSLT/attribute-set +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/attribute-set +--- +

{{ XsltRef() }}

+

<xsl:attribute-set> 요소는 CSS 안에 이름 붙인 스타일과 비슷한 방식으로 이름 붙인 속성 집합을 만듭니다. 그러면, 출력 문서에 전체로서 적용할 수 있습니다.

+

문법

+
<xsl:attribute-set name=NAME use-attribute-sets=LIST-OF-NAMES>
+	<xsl:attribute>
+</xsl:attribute-set>
+

필수 속성

+
+
+ name
+
+ 속성 집합에 이름을 지정합니다. 이름은 유효한 QName이어야 합니다.
+
+

선택 속성

+
+
+ use-attribute-sets
+
+ 다른 속성 집합으로부터 속성 집합을 빌드합니다. 기여한 집합의 이름은 공백 문자로 구분해야 하고 직접 혹은 간접으로 서로 임베드하지 않아야 합니다.
+
+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 7.1.4, Named Attribute Sets

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/attribute/index.html b/files/ko/web/xslt/element/attribute/index.html new file mode 100644 index 0000000000..1c348584f7 --- /dev/null +++ b/files/ko/web/xslt/element/attribute/index.html @@ -0,0 +1,33 @@ +--- +title: attribute +slug: Web/XSLT/attribute +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/attribute +--- +

{{ XsltRef() }}

+

<xsl:attribute> 요소는 스타일시트에서 접근할 수 있는 어떤 값을 써서 출력 문서에 속성을 만듭니다. 요소는 속성값을 자리 잡게 하는 출력 문서 요소 안에 정의한 것 가운데 처음이어야 합니다.

+

문법

+
<xsl:attribute name=NAME namespace=URI>
+	TEMPLATE
+</xsl:attribute>
+

필수 속성

+
+
+ name
+
+ 출력 문서에 만들려는 속성에 이름을 지정합니다. 이름은 유효한 QName이어야 합니다.
+
+

선택 속성

+
+
+ namespace
+
+ 출력 문서에 이 속성을 위한 이름공간(namespace) URI를 정의합니다. 이 요소와 관련된 이름공간 접두사를 설정할 수 없습니다.
+
+

타입

+

명령, 템플릿이나 <xsl:attribute-set> 요소 안에 나타남.

+

정의

+

XSLT section 7.1.3, Creating Attributes with xsl:attribute

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/call-template/index.html b/files/ko/web/xslt/element/call-template/index.html new file mode 100644 index 0000000000..c5aa8c1a53 --- /dev/null +++ b/files/ko/web/xslt/element/call-template/index.html @@ -0,0 +1,29 @@ +--- +title: call-template +slug: Web/XSLT/call-template +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/call-template +--- +

{{ XsltRef() }}

+

<xsl:call-template> 요소는 이름 붙인 템플릿을 호출합니다.

+

문법

+
<xsl:call-template name=NAME>
+	<xsl:with-param> [optional]
+</xsl:call-template> 
+

필수 속성

+
+
+ name
+
+ 호출하고 싶은 템플릿의 이름을 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 6, Named Templates

+

Gecko 지원

+

지원함.

+

{{ languages( { "en": "en/XSLT/call-template" } ) }}

diff --git a/files/ko/web/xslt/element/choose/index.html b/files/ko/web/xslt/element/choose/index.html new file mode 100644 index 0000000000..ea615e7e15 --- /dev/null +++ b/files/ko/web/xslt/element/choose/index.html @@ -0,0 +1,24 @@ +--- +title: choose +slug: Web/XSLT/choose +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/choose +--- +

{{ XsltRef() }}

+

<xsl:choose> 요소는 많은 선택 가운데 하나를 정의합니다. 그리고 절차형 언어(procedural language)의 스위치 문처럼 동작합니다.

+

문법

+
<xsl:choose>
+	<xsl:when>
+	<xsl:otherwise> [optional]
+</<xsl:choose>
+

필수 속성

+

없음.

+

선택 속성

+

없음.

+

타입

+

명령, 템플릿과 함께 나타남. 하나 이상의 <xsl:when> 요소를 포함하고 선택에 따라 마지막에 <xsl:otherwise> 요소를 포함합니다.

+

정의

+

XSLT section 9.2, Conditional Processing with xsl:choose

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/comment/index.html b/files/ko/web/xslt/element/comment/index.html new file mode 100644 index 0000000000..56b12a9968 --- /dev/null +++ b/files/ko/web/xslt/element/comment/index.html @@ -0,0 +1,23 @@ +--- +title: comment +slug: Web/XSLT/comment +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/comment +--- +

{{ XsltRef() }}

+

<xsl:comment> 요소는 출력 문서에 주석을 작성합니다. 오직 텍스트만 포함해야 합니다.

+

문법

+
<xsl:comment>
+	TEMPLATE
+</xsl:comment> 
+

필수 속성

+

없음.

+

선택 속성

+

없음.

+

타입

+

명령, 템플릿과 함께 나타남.

+

정의

+

XSLT section 7.4, Creating Comments

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/copy-of/index.html b/files/ko/web/xslt/element/copy-of/index.html new file mode 100644 index 0000000000..cfd00ae443 --- /dev/null +++ b/files/ko/web/xslt/element/copy-of/index.html @@ -0,0 +1,26 @@ +--- +title: copy-of +slug: Web/XSLT/copy-of +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/copy-of +--- +

{{ XsltRef() }}

+

<xsl:copy-of> 요소는 select 속성이 출력 문서에 무엇을 지정하든지 (자손 노드를 포함하여) 깊게 복사(deep copy)합니다.

+

문법

+
<xsl:copy-of select=EXPRESSION /> 
+

필수 속성

+
+
+ select
+
+ 복사할 대상을 지정하는 XPath 식을 씁니다.
+
+

선택 속성

+

없음.

+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 11.3, Using Values of Variables and Parameters with xsl:copy-of

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/copy/index.html b/files/ko/web/xslt/element/copy/index.html new file mode 100644 index 0000000000..7d6e480167 --- /dev/null +++ b/files/ko/web/xslt/element/copy/index.html @@ -0,0 +1,28 @@ +--- +title: copy +slug: Web/XSLT/copy +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/copy +--- +

{{ XsltRef() }}

+

<xsl:copy> 요소는 출력 문서에 현재 노드의 노드와 어떤 관련 이름공간 노드만을 얕게 복사(shallow copy) 전달합니다. 속성이나 자식은 복사하지 않습니다.

+

문법

+
<xsl:copy use-attribute-sets=LIST-OF-NAMES>
+	TEMPLATE
+</xsl:copy>
+

필수 속성

+

없음.

+

선택 속성

+
+
+ use-attribute-sets
+
+ 요소이면, 출력 노드에 적용해도 좋을 속성 집합을 나열합니다. 집합의 이름은 공백 문자로 구분해야 합니다.
+
+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 7.5, Copying

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/decimal-format/index.html b/files/ko/web/xslt/element/decimal-format/index.html new file mode 100644 index 0000000000..83e51a2e90 --- /dev/null +++ b/files/ko/web/xslt/element/decimal-format/index.html @@ -0,0 +1,100 @@ +--- +title: decimal-format +slug: Web/XSLT/decimal-format +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/decimal-format +--- +

{{ XsltRef() }}

+

<xsl:decimal-format> 요소는 + + format-number( ) + 함수를 써서 숫자를 문자열로 바꿀 때 쓰는 기호와 문자를 정의합니다.

+

문법

+
<xsl:decimal-format
+	name=NAME
+	decimal-separator=CHARACTER
+	grouping-separator=CHARACTER
+	infinity=STRING
+	minus-sign=CHARACTER
+	NaN=STRING
+	percent=CHARACTER
+	per-mille=CHARATER
+	zero-digit=CHARACTER
+	digit=CHARACTER
+	pattern-separator=CHARACTER />
+

필수 속성

+

없음.

+

선택 속성

+
+
+ name
+
+ 이 형식에 이름을 지정합니다.
+
+
+
+ decimal-separator
+
+ 소숫점 문자를 지정합니다. 기본값은 (.)입니다.
+
+
+
+ grouping-separator
+
+ 그룹 구분 문자를 지정합니다. 기본값은 (,)입니다.
+
+
+
+ infinity
+
+ 무한대(infinity)를 나타내는데 쓰는 문자열을 지정합니다. 기본값은 "Infinity" 문자열입니다.
+
+
+
+ minus-sign
+
+ 빼기 기호 문자를 지정합니다. 기본값은 (-)입니다.
+
+
+
+ NaN
+
+ 값이 숫자가 아닐 때 쓰는 문자열을 지정합니다. 기본값은 "NaN" 문자열입니다.
+
+
+
+ percent
+
+ 백분율(percentage) 기호 문자를 지정합니다. 기본값은 (%)입니다.
+
+
+
+ per-mille
+
+ 천분율(per thousand) 문자를 지정합니다. 기본값은 ()입니다.
+
+
+
+ zero-digit
+
+ 숫자 0으로 쓸 문자를 지정합니다. 기본값은 (0)입니다.
+
+
+
+ digit
+
+ 형식 패턴에서 숫자(digit)를 나타내는데 쓰는 문자를 지정합니다. 기본값은 (#)입니다.
+
+
+
+ pattern-separator
+
+ 형식 패턴에서 양수와 음수 부분패턴을 구분하는 문자를 지정합니다. 기본값은 (;)입니다.
+
+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 12.3, Number Formatting

+

Gecko 지원

+

Mozilla 1.0과 Netscape 7.0 현재 지원함.

diff --git a/files/ko/web/xslt/element/fallback/index.html b/files/ko/web/xslt/element/fallback/index.html new file mode 100644 index 0000000000..af407f4512 --- /dev/null +++ b/files/ko/web/xslt/element/fallback/index.html @@ -0,0 +1,23 @@ +--- +title: fallback +slug: Web/XSLT/fallback +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/fallback +--- +

{{ XsltRef() }}

+

<xsl:fallback> 요소는 주어진 확장(이나 결국에는 새 버전) 요소에서 지원하지 않으면 쓸 템플릿을 지정합니다.

+

문법

+
<xsl:fallback>
+	TEMPLATE
+</xsl:fallback>
+

필수 속성

+

없음.

+

선택 속성

+

없음.

+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 15, Fallback

+

Gecko 지원

+

이번에 지원 안 함.

diff --git a/files/ko/web/xslt/element/for-each/index.html b/files/ko/web/xslt/element/for-each/index.html new file mode 100644 index 0000000000..6beb713190 --- /dev/null +++ b/files/ko/web/xslt/element/for-each/index.html @@ -0,0 +1,29 @@ +--- +title: for-each +slug: Web/XSLT/for-each +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/for-each +--- +

{{ XsltRef() }}

+

<xsl:for-each> 요소는 노드 집합을 선택하고 같은 방식으로 각 노드를 처리합니다. 노드 집합을 되풀이하(iterate)거나 현재 노드를 바꾸는데 자주 씁니다. 하나 이상의 <xsl:sort> 요소가 이 요소의 자식으로 나타나면, 처리에 앞서 정렬을 합니다. 그렇지 않으면, 노드는 문서 순으로 처리합니다.

+

문법

+
<xsl:for-each select=EXPRESSION>
+	<xsl:sort> [optional]
+	TEMPLATE
+</xsl:for-each>
+

필수 속성

+
+
+ select
+
+ 처리할 노드를 선택하기 위해 XPath 식을 씁니다.
+
+

선택 속성

+

없음.

+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 8, Repetition

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/if/index.html b/files/ko/web/xslt/element/if/index.html new file mode 100644 index 0000000000..2c56b7d218 --- /dev/null +++ b/files/ko/web/xslt/element/if/index.html @@ -0,0 +1,28 @@ +--- +title: if +slug: Web/XSLT/if +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/if +--- +

{{ XsltRef() }}

+

<xsl:if> 요소는 test 속성과 템플릿을 포함합니다. test 속성을 참으로 평가하면, 템플릿을 처리합니다. 이것은 다른 언어의 if 문과 비슷합니다. 그러나, <tt>if-then-else</tt> 문의 기능을 다하기 위해 <xsl:when><xsl:otherwise> 자식이 하나씩 있는 <xsl:choose> 요소를 씁니다.

+

문법

+
<xsl:if test=EXPRESSION>
+	TEMPLATE
+</xsl:if>
+

필수 속성

+
+
+ test
+
+ Boolean 값으로 (필요하다면 boolean( )으로 정의한 규칙을 써서) 평가할 수 있는 XPath 식을 포함합니다. 값이 참이면 템플릿을 처리하고 거짓이면 아무 동작도 하지 않습니다.
+
+

선택 속성

+

없음.

+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 9.1, Conditional Processing with xsl:if

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/import/index.html b/files/ko/web/xslt/element/import/index.html new file mode 100644 index 0000000000..5a469656cb --- /dev/null +++ b/files/ko/web/xslt/element/import/index.html @@ -0,0 +1,26 @@ +--- +title: import +slug: Web/XSLT/import +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/import +--- +

{{ XsltRef() }}

+

<xsl:import> 요소는 한 스타일시트의 컨텐트를 다른 스타일시트로 가져오는 역할을 하는 최상위 요소입니다. 대체로, 가져올 스타일시트의 컨텐트는 가져오는 스타일시트의 컨텐트보다 가져오기 우선순위가 낮습니다. 이는 포함되는 스타일시트의 컨텐트가 포함하는 스타일시트의 컨텐트와 우선순위가 정확히 같은 <xsl:include>와는 뚜렷이 다릅니다.

+

문법

+
<xsl:import href=URI  />
+

필수 속성

+
+
+ href
+
+ 가져올 스타일시트의 URI를 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

최상위, 가져오는 스타일시트 안 <xsl:stylesheet><xsl:transform>의 자식 가운데 가장 앞에 나타나야 함.

+

정의

+

XSLT section 2.6.2, Stylesheet Import

+

Gecko 지원

+

Mozilla 1.0 현재 최상위 변수와 매개변수에 문제가 조금 있지만 대부분 지원함.

diff --git a/files/ko/web/xslt/element/include/index.html b/files/ko/web/xslt/element/include/index.html new file mode 100644 index 0000000000..965d03a15f --- /dev/null +++ b/files/ko/web/xslt/element/include/index.html @@ -0,0 +1,26 @@ +--- +title: include +slug: Web/XSLT/include +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/include +--- +

{{ XsltRef() }}

+

<xsl:include> 요소는 한 스타일시트의 컨텐트를 다른 스타일시트에 합칩니다. <xsl:import>와는 달리, 포함되는 스타일시트의 컨텐트는 포함하는 스타일시트의 컨텐트와 우선순위가 정확히 같습니다.

+

문법

+
<xsl:include href=URI />
+

필수 속성

+
+
+ href
+
+ 포함할 스타일시트의 URI를 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식으로 나타남.

+

정의

+

XSLT section 2.6.1, Stylesheet Inclusion

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/key/index.html b/files/ko/web/xslt/element/key/index.html new file mode 100644 index 0000000000..733196810d --- /dev/null +++ b/files/ko/web/xslt/element/key/index.html @@ -0,0 +1,35 @@ +--- +title: key +slug: Web/XSLT/key +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/key +--- +

{{ XsltRef() }}

+

<xsl:key> 요소는 key( ) 함수가 있는 스타일시트 어디서나 쓸 수 있는 이름 붙은 키를 선언합니다.

+

문법

+
<xsl:key name=NAME match=EXPRESSION
+	use=EXPRESSION /> 
+

필수 속성

+
+
+ name
+
+ 이 키에 이름을 지정합니다. QName이어야 합니다.
+
+ match
+
+ 이 키를 적용할 수 있는 노드를 정의합니다.
+
+ use
+
+ 적용가능한 각 노드에 키값을 결정하는데 쓸 수 있는 XPath 식을 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 12.2, Keys

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/message/index.html b/files/ko/web/xslt/element/message/index.html new file mode 100644 index 0000000000..d533a2d3c7 --- /dev/null +++ b/files/ko/web/xslt/element/message/index.html @@ -0,0 +1,28 @@ +--- +title: message +slug: Web/XSLT/message +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/message +--- +

{{ XsltRef() }}

+

<xsl:message> 요소는 (NS에서 자바스크립트 콘솔에) 메시지를 출력하고 선택에 따라 스타일시트 실행을 끝냅니다. 디버깅에 유용할 수 있습니다.

+

문법

+
<xsl:message terminate="yes" | "no" >
+	TEMPLATE
+</xsl:message>
+

필수 속성

+

없음.

+

선택 속성

+
+
+ terminate
+
+ "yes"로 설정하면, 실행을 끝마치는 게 좋겠다는 것을 나타냅니다. 기본값은 "no"이고 어느 경우에는 메시지가 출력하고 실행을 계속합니다.
+
+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 13, Messages

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/namespace-alias/index.html b/files/ko/web/xslt/element/namespace-alias/index.html new file mode 100644 index 0000000000..e085abc4e7 --- /dev/null +++ b/files/ko/web/xslt/element/namespace-alias/index.html @@ -0,0 +1,30 @@ +--- +title: namespace-alias +slug: Web/XSLT/namespace-alias +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/namespace-alias +--- +

{{ XsltRef() }}

+

<xsl:namespace-alias> 요소는 스타일시트 이름공간을 출력 트리의 다른 이름공간으로 매기는(map) 데 드물게 쓰는 방안(device)입니다. 이 요소의 가장 평범한 쓰임은 다른 스타일시트로부터 스타일시트를 만드는 것입니다. 보통 xsl:가 접두사로 붙은 (결과 트리에 단순히 복사해도 좋을) LRE(literal result element)를 처리기가 오해하는 것을 막기 위해, 결과 트리의 XSLT 이름공간에 적당하게 도로 다시 바꿀 임시 이름공간을 할당합니다.

+

문법

+
<xsl:namespace-alias stylesheet-prefix=NAME result-prefix=NAME />
+

필수 속성

+
+
+ stylesheet-prefix
+
+ 임시 이름공간을 지정합니다.
+
+ result-prefix
+
+ 결과 트리에 사용하길 바라는 이름공간을 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 7.1.1, Literal Result Elements

+

Gecko 지원

+

이번에 지원 안 함.

diff --git a/files/ko/web/xslt/element/number/index.html b/files/ko/web/xslt/element/number/index.html new file mode 100644 index 0000000000..b822625a0e --- /dev/null +++ b/files/ko/web/xslt/element/number/index.html @@ -0,0 +1,173 @@ +--- +title: number +slug: Web/XSLT/number +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/number +--- +

{{ XsltRef() }}

+

<xsl:number> 요소는 숫자를 연속으로 셉니다. 또한 숫자를 빠르게 구성하는(format) 데도 쓸 수 있습니다.

+

구문

+
<xsl:number
+	count=EXPRESSION
+	level="single" | "multiple" | "any"
+	from=EXPRESSION
+	value=EXPRESSION
+	format=FORMAT-STRING
+	lang=XML:LANG-CODE
+	letter-value="alphabetic" | "traditional"
+	grouping-separator=CHARACTER
+	grouping-size=NUMBER  />
+

필수 속성

+

없음.

+

선택 속성

+
+
+ count
+
+ 소스 트리에서 연속으로 셀 대상을 지정합니다. XPath 식을 씁니다.
+
+
+
+ level
+
+ 일련번호를 만드는데 소스 트리의 수준을 어떻게 고려해야 하는 지를 정의합니다. 유효한 값은 single, multiple, any 세 가지. 기본값은 single입니다.
+
+
+
+
+
+ single
+
+ 목록의 항목대로 연속으로 형제 노드를 번호 매깁니다. 처리기는 count 속성과 일치하는 ancestor-or-self 축의 첫 번째 노드로 갑니다. 그리고 나서 역시 count 속성과 일치하는 앞선 형제(preceding siblings) 노드(있다면, 한 짝인 from 속성에 이르러 멈춤)를 모두 더하여 셉니다. 일치하지 않으면, sequence는 빈 목록입니다.
+
+
+
+
+
+
+
+ multiple
+
+ 노드의 계층 위치를 반영하는 복합 sequence로 노드를 셉니다. 예를 들어, 1.2.2.5 (포개진 형식은 format 속성(예, A.1.1)으로 지정할 수 있습니다). 처리기는 만약 있다면 from 속성에 이르러 멈추며 현재 노드와 현재 노드의 모든 ancestors를 조사합니다. 일치하지 않으면, sequence는 빈 목록입니다.
+
+
+
+
+
+
+
+ any (이번에 지원 안 함.)
+
+ 수준을 무시하고 연속으로 일치하는 모든 노드를 셉니다. ancestor, self, preceding 축을 모두 고려합니다. 처리기는 현재 노드에서 시작하여 from 속성과 일치할 때 멈추며 문서 역순으로 진행합니다. 발견한 count 속성과 일치하지 않으면, sequence는 빈 목록입니다. 이 수준은 이번에 지원하지 않습니다.
+
+
+
+
+
+ from
+
+ 번호 매기기를 시작하거나 다시 시작하면 좋을 곳을 지정합니다. 순서는 from 특성과 일치하는 노드의 첫 번째 자손(descendant)에서 시작합니다.
+
+
+
+ value
+
+ 숫자에 주어진 형식을 적용합니다. 이것이 사용자 제공 숫자(노드 sequence 숫자와는 반대로)를 표준 <xsl:number> 형식으로 구성하는 빠른 방법입니다.
+
+
+
+ format
+
+ 만드는 숫자의 형식을 정의합니다.
+
+
+
+
+
+ format="1"
+
+ <tt>1 2 3 . . .</tt> (이번에 지원하는 유일한 형식)
+
+
+
+
+
+
+
+ format="01"
+
+ <tt>01 02 03 . . . 09 10 11 . . .</tt>
+
+
+
+
+
+
+
+ format="a"
+
+ <tt>a b c . . .y z aa ab . . .</tt>
+
+
+
+
+
+
+
+ format="A"
+
+ <tt>A B C . . . Y Z AA AB . . .</tt>
+
+
+
+
+
+
+
+ format="i"
+
+ <tt>i ii iii iv v . . .</tt>
+
+
+
+
+
+
+
+ format="I"
+
+ <tt>I II III IV V . . .</tt>
+
+
+
+
+
+ lang (이번에는 지원 안 함)
+
+ 문자에 기반을 둔 번호 매기기 형식에 쓰면 좋을 언어의 알파벳을 지정합니다.
+
+
+
+ letter-value
+
+ 문자(letter)를 쓰는 번호 매김 열(sequence) 사이를 명확하게 합니다. 어떤 언어는 문자(letter)를 쓰는 하나 이상의 번호 매기기 시스템이 있습니다. 두 시스템이 같은 토큰으로 시작하면, 모호함이 생길 수 있습니다. 이 속성은 "alphabetic"나 "traditional" 값일 수 있습니다. 기본값은 "alphabetic"입니다.
+
+
+
+ grouping-separator
+
+ 어떤 문자를 그룹(예로 천 단위) 구분자로 쓰면 좋을지를 지정합니다. 기본값은 쉼표(,)입니다.
+
+
+
+ grouping-size
+
+ 숫자 그룹을 만드는 자릿수를 나타냅니다. 기본값은 "3"입니다.
+
+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 7.7, Numbering

+

Gecko 지원

+

부분 지원. 위 해설을 보세요.

diff --git a/files/ko/web/xslt/element/otherwise/index.html b/files/ko/web/xslt/element/otherwise/index.html new file mode 100644 index 0000000000..50249dc0b4 --- /dev/null +++ b/files/ko/web/xslt/element/otherwise/index.html @@ -0,0 +1,23 @@ +--- +title: otherwise +slug: Web/XSLT/otherwise +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/otherwise +--- +

{{ XsltRef() }}

+

<xsl:otherwise> 요소는 아무런 <xsl:when> 조건도 적용하지 않았을 때 취하면 좋을 동작을 정의하는 데 씁니다. 다른 프로그래밍 언어의 elsedefault 경우와 비슷합니다.

+

문법

+
<xsl:otherwise>
+	TEMPLATE
+</xsl:otherwise>
+

필수 속성

+

없음.

+

선택 속성

+

없음.

+

타입

+

하위명령, 템플릿 안에서 <xsl:choose> 요소의 마지막 자식으로 나타나야 함.

+

정의

+

XSLT section 9.2, Conditional Processing with xsl:choose

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/output/index.html b/files/ko/web/xslt/element/output/index.html new file mode 100644 index 0000000000..97baf3f433 --- /dev/null +++ b/files/ko/web/xslt/element/output/index.html @@ -0,0 +1,90 @@ +--- +title: output +slug: Web/XSLT/output +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/output +--- +

{{ XsltRef() }}

+

<xsl:output> 요소는 출력 문서의 특성을 조절합니다. method 속성이 있는 이 요소가 Netscape에서 정확하게 기능하도록 쓸 수 있어야 합니다. 7.0 현재, method="text"는 기대한 대로 동작합니다.

+

문법

+
<xsl:output
+	method="xml" | "html" | "text"
+	version=STRING
+	encoding=STRING
+	omit-xml-declaration="yes" | "no"
+	standalone="yes" | "no"
+	doctype-public=STRING
+	doctype-system=STRING
+	cdata-section-elements=LIST-OF-NAMES
+	indent="yes" | "no"
+	media-type=STRING  />
+

필수 속성

+

없음.

+

선택 속성

+
+
+ method
+
+ 출력 형식을 지정합니다.
+
+
+
+ version
+
+ 출력 문서에 XML이나 HTML 선언의 version 속성값을 지정합니다. 이 속성은 method="html"method="xml"일 때만 씁니다.
+
+
+
+ encoding
+
+ 출력 문서에 encoding 속성값을 지정합니다.
+
+
+
+ omit-xml-declaration
+
+ 출력에 XML 선언을 포함할 지를 나타냅니다. 가능한 값은 "yes"나 "no"입니다.
+
+
+
+ standalone (지원 안 함.)
+
+ 있으면, standalone 선언이 출력 문서에 나타나면 좋을 지를 나타내고 그 값을 줍니다. 가능한 값은 "yes"나 "no"입니다.
+
+
+
+ doctype-public
+
+ 출력 문서에 DOCTYPE 선언의 PUBLIC 속성값을 지정합니다.
+
+
+
+ doctype-system
+
+ 출력 문서에 DOCTYPE 선언의 SYSTEM 속성값을 지정합니다.
+
+
+
+ cdata-section-elements
+
+ CDATA 절에 써도 좋을 요소의 텍스트 컨텐트를 나열합니다. 요소는 공백으로 구분해야 합니다.
+
+
+
+ indent (지원 안 함.)
+
+ 출력에 계층 구조를 나타내도록 하면 좋을 지를 지정합니다.
+
+
+
+ media-type (지원 안 함.)
+
+ 출력 문서의 MIME 타입을 지정합니다.
+
+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 16, Output

+

Gecko 지원

+

부분 지원. 위 해설을 보세요.

diff --git a/files/ko/web/xslt/element/param/index.html b/files/ko/web/xslt/element/param/index.html new file mode 100644 index 0000000000..e1bcf36e19 --- /dev/null +++ b/files/ko/web/xslt/element/param/index.html @@ -0,0 +1,33 @@ +--- +title: param +slug: Web/XSLT/param +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/param +--- +

{{ XsltRef() }}

+

<xsl:param> 요소는 이름과 선택에 따라 기본값으로 매개변수를 설정합니다. 최상위 요소로 쓸 때, 매개변수는 전역입니다. <xsl:template> 요소 안에서 쓰면, 매개변수는 그 템플릿에 대해 지역입니다. 이 경우에 요소는 템플릿의 첫 자식 요소여야 합니다.

+

문법

+
<xsl:param name=NAME select=EXPRESSION>
+	TEMPLATE
+</xsl:param>
+

필수 속성

+
+
+ name
+
+ 파라미터에 이름을 붙입니다. 이름은 QName이어야 합니다.
+
+

선택 속성

+
+
+ select
+
+ none으로 지정하면 기본값을 제공하는 XPath 식을 씁니다.
+
+

타입

+

명령, 최상위 요소나 템플릿 안에 나타날 수 있음.

+

정의

+

XSLT section 11, Variables and Parameters

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/preserve-space/index.html b/files/ko/web/xslt/element/preserve-space/index.html new file mode 100644 index 0000000000..771ffe81d6 --- /dev/null +++ b/files/ko/web/xslt/element/preserve-space/index.html @@ -0,0 +1,26 @@ +--- +title: preserve-space +slug: Web/XSLT/preserve-space +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/preserve-space +--- +

{{ XsltRef() }}

+

<xsl:preserve-space> 요소는 공백을 보존하면 좋을 소스 문서의 요소를 정의합니다. 하나 이상의 요소가 있으면, 공백 문자로 이름을 구분하세요. 공백 보존하기가 기본 설정이므로 이 요소는 오직 <xsl:strip-space> 요소와 거꾸로 동작하기 위해 쓸 필요가 있습니다.

+

문법

+
<xsl:preserve-space elements=LIST-OF-ELEMENT-NAMES  />
+

필수 속성

+
+
+ elements
+
+ 공백을 보존하면 좋을 요소를 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 3.4, Whitespace Stripping

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/processing-instruction/index.html b/files/ko/web/xslt/element/processing-instruction/index.html new file mode 100644 index 0000000000..ad1c6eaaf6 --- /dev/null +++ b/files/ko/web/xslt/element/processing-instruction/index.html @@ -0,0 +1,26 @@ +--- +title: processing-instruction +slug: Web/XSLT/processing-instruction +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/processing-instruction +--- +

{{ XsltRef() }}

+

<xsl:processing-instruction> 요소는 출력 문서에 처리 명령을 씁니다.

+

문법

+

<xsl:processing-instruction name=NAME> TEMPLATE </xsl:processing-instruction>

+

필수 속성

+
+
+ name
+
+ 처리 명령에 이름을 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 7.3, Creating Processing Instructions

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/sort/index.html b/files/ko/web/xslt/element/sort/index.html new file mode 100644 index 0000000000..22217ec61f --- /dev/null +++ b/files/ko/web/xslt/element/sort/index.html @@ -0,0 +1,55 @@ +--- +title: sort +slug: Web/XSLT/sort +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/sort +--- +

{{ XsltRef() }}

+

<xsl:sort> 요소는 <xsl:apply-templates><xsl:for-each>가 선택한 노드에 정렬키를 정의하고 노드를 처리할 순서를 결정합니다.

+

문법

+
<xsl:sort
+	select=EXPRESSION
+	order="ascending" | "descending"
+	case-order="upper-first"| "lower-first"
+	lang=XML:LANG-CODE
+	data-type="html" | "xml" | "text" /> 
+

필수 속성

+

없음.

+

선택 속성

+
+
+ select
+
+ 정렬할 노드를 지정하는 XPath 식을 씁니다.
+
+
+
+ order
+
+ "ascending"나 "descending"으로 처리하면 좋을 노드를 지정합니다. 기본값은 "ascending"입니다.
+
+
+
+ case-order
+
+ 처음에 오는 게 대문자인지 소문자인지를 나타냅니다. 가능한 값은 "upper-first"와 "lower-first"입니다.
+
+
+
+ lang
+
+ 어떤 언어를 정렬에 쓸지를 지정합니다.
+
+
+
+ data-type
+
+ 어떤 항목을 알파벳순이나 숫자순으로 순서 매길지를 정의합니다. 가능한 값은 "text"와 기본값인 "text"가 있는 "number"입니다.
+
+

타입

+

하위명령, 항상 <xsl:for-each>의 자식으로 나타나고 고유(proper) 템플릿이나 <xsl:apply-templates> 앞에 나타나야 함.

+

정의

+

XSLT section 10, Sorting

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/strip-space/index.html b/files/ko/web/xslt/element/strip-space/index.html new file mode 100644 index 0000000000..7bbc485afd --- /dev/null +++ b/files/ko/web/xslt/element/strip-space/index.html @@ -0,0 +1,26 @@ +--- +title: strip-space +slug: Web/XSLT/strip-space +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/strip-space +--- +

{{ XsltRef() }}

+

<xsl:strip-space> 요소는 공백을 지웠으면 하는 소스 문서의 요소를 정의합니다.

+

문법

+
<xsl:strip-space elements=LIST-OF-ELEMENT-NAMES  />
+

필수 속성

+
+
+ elements
+
+ 지우면 좋을 공백뿐인 텍스트 노드가 있는 소스의 요소 목록(빈칸으로 구분)을 지정합니다.
+
+

선택 속성

+

없음.

+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 3.4, Whitespace Stripping

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/stylesheet/index.html b/files/ko/web/xslt/element/stylesheet/index.html new file mode 100644 index 0000000000..0119cec645 --- /dev/null +++ b/files/ko/web/xslt/element/stylesheet/index.html @@ -0,0 +1,52 @@ +--- +title: stylesheet +slug: Web/XSLT/stylesheet +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/stylesheet +--- +

{{ XsltRef() }}

+

<xsl:stylesheet>(나 동등한 <xsl:transform>) 요소는 스타일시트의 최외곽 요소입니다.

+

이름공간 선언

+

pseudo 속성은 XSLT 스타일시트로 문서를 식별하기 위해 필요합니다. 대체로 이는 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"입니다.

+

문법

+
<xsl:stylesheet
+	version=NUMBER
+	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+	id=NAME
+	extension-element-prefixes=LIST-OF-NAMES
+	exclude-result-prefixes=LIST-OF-NAMES>
+		ENTIRE STYLESHEET
+</xsl:stylesheet>
+

필수 속성

+
+
+ version
+
+ 이 스타일시트에 필요한 XSLT의 버전을 지정합니다.
+
+

선택 속성

+
+
+ id (7.0 현재 오직 inline DTD가 명시하여 호출하는 경우만 지원함.)
+
+ 이 스타일시트에 id를 지정합니다. 이는 스타일시트를 다른 XML 문서에 포함할 때 가장 자주 씁니다.
+
+
+
+ extension-element-prefixes (지원 안 함.)
+
+ 이 문서의 확장 요소에 빈칸으로 구분한 이름공간 접두사를 지정합니다.
+
+
+
+ exclude-result-prefixes
+
+ 이 문서에 쓸 출력 문서에 보내지 않았으면 하는 이름공간을 지정합니다. 목록은 공백으로 구분합니다.
+
+

타입

+

필수 최외곽 스타일시트 요소.

+

정의

+

XSLT section 2.2, Stylesheet Element

+

Gecko 지원

+

조금 지원. 위 해설을 보세요.

diff --git a/files/ko/web/xslt/element/template/index.html b/files/ko/web/xslt/element/template/index.html new file mode 100644 index 0000000000..1ce4a66d2b --- /dev/null +++ b/files/ko/web/xslt/element/template/index.html @@ -0,0 +1,51 @@ +--- +title: template +slug: Web/XSLT/template +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/template +--- +

{{ XsltRef() }}

+

<xsl:template> 요소는 출력 생성 템플릿을 정의합니다. 이 요소는 match 속성이나 name 속성 집합이 있어야 합니다.

+

문법

+
<xsl:template
+	match=PATTERN
+	name=NAME
+	mode=NAME
+	priority=NUMBER>
+	<xsl:param> [optional]
+	TEMPLATE
+</xsl:template>
+

필수 속성

+

없음.

+

선택 속성

+
+
+ match
+
+ 이 템플릿을 쓰면 좋을 요소를 결정하는 패턴을 지정합니다. name 속성이 없다면, 필수 속성입니다.
+
+
+
+ name
+
+ <xsl:call-template> 요소가 호출할 수 있는 이 템플릿에 이름을 지정합니다.
+
+
+
+ mode
+
+ 이 템플릿에 <xsl:apply-templates> 요소의 속성과 일치할 수 있는 특유한 모드를 지정합니다. 이는 같은 정보를 다양한 방식으로 처리하는데 유용합니다.
+
+
+
+ priority
+
+ 이 템플릿에 숫자로 된 우선권을 지정합니다. 이는 Infinity와 다른 아무 숫자일 수 있습니다. 처리기는 하나 이상의 템플릿이 같은 노드와 일치할 때 이 숫자를 씁니다.
+
+

타입

+

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

+

정의

+

XSLT section 5.3, Defining Template Rules

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/text/index.html b/files/ko/web/xslt/element/text/index.html new file mode 100644 index 0000000000..71bd6eceda --- /dev/null +++ b/files/ko/web/xslt/element/text/index.html @@ -0,0 +1,28 @@ +--- +title: text +slug: Web/XSLT/text +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/text +--- +

{{ XsltRef() }}

+

<xsl:text> 요소는 출력 트리에 리터럴(literal) 텍스트를 씁니다. #PCDATA, 리터럴 텍스트, 엔티티 참조를 포함할 지도 모릅니다.

+

구문

+
<xsl:text disable-output-escaping="yes" | "no">
+	TEXT
+</xsl:text> 
+

필수 속성

+

없음.

+

선택 속성

+
+
+ disable-output-escaping (Netscape은 변환 결과를 "output" 아래에 직렬하지 않습니다. 그래서 이 속성은 본래 문맥에서는 무의미합니다. HTML 엔티티를 출력하기 위해서는, 대신 숫자값을 쓰세요. 보기 &nbsp 대신 &#160)
+
+ 특수 문자를 출력에 쓸 때 해석할(escape) 지를 지정합니다. 가능한 값은 "yes"나 "no"입니다. 예를 들어, "yes"로 하면, <tt>></tt> 문자의 출력은 "&gt"가 아니라 >입니다.
+
+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 7.2, Creating Text

+

Gecko 지원

+

적힌 대로 지원함

diff --git a/files/ko/web/xslt/element/transform/index.html b/files/ko/web/xslt/element/transform/index.html new file mode 100644 index 0000000000..8071ebdad3 --- /dev/null +++ b/files/ko/web/xslt/element/transform/index.html @@ -0,0 +1,11 @@ +--- +title: transform +slug: Web/XSLT/transform +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/transform +--- +

{{ XsltRef() }}

+

<xsl:transform> 요소는 <xsl:stylesheet> 요소와 정확히 같습니다.

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/value-of/index.html b/files/ko/web/xslt/element/value-of/index.html new file mode 100644 index 0000000000..90f1777bed --- /dev/null +++ b/files/ko/web/xslt/element/value-of/index.html @@ -0,0 +1,31 @@ +--- +title: value-of +slug: Web/XSLT/value-of +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/value-of +--- +

{{ XsltRef() }}

+

<xsl:value-of> 요소는 XPath 식을 평가하여 그것을 문자열로 바꾸고 문자열을 결과 트리에 씁니다.

+

구문

+
<xsl:value-of select=EXPRESSION disable-output-escaping="yes" | "no"  />
+

필수 속성

+
+
+ select
+
+ 평가하고 출력 트리에 쓸 XPath 식을 지정합니다.
+
+

선택 속성

+
+
+ disable-output-escaping (Netscape은 변환 결과를 "output" 아래에 직렬하지 않습니다. 그래서 이 속성은 본래 문맥에서는 무의미합니다. HTML 엔티티를 출력하기 위해서는, 대신 숫자값을 쓰세요. 보기 &nbsp 대신 &#160)
+
+ 특수 문자를 출력에 쓸 때 해석할(escape) 지를 지정합니다. 가능한 값은 "yes"나 "no"입니다. 예를 들어, "yes"로 하면, <tt>></tt> 문자의 출력은 "&gt"가 아니라 >입니다.
+
+

타입

+

명령, 템플릿 안에 나타남.

+

정의

+

XSLT section 7.6.1, Generating Text with xsl:value-of

+

Gecko 지원

+

위 경우를 빼고는 지원함.

diff --git a/files/ko/web/xslt/element/variable/index.html b/files/ko/web/xslt/element/variable/index.html new file mode 100644 index 0000000000..8568f70b20 --- /dev/null +++ b/files/ko/web/xslt/element/variable/index.html @@ -0,0 +1,33 @@ +--- +title: variable +slug: Web/XSLT/variable +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/variable +--- +

{{ XsltRef() }}

+

<xsl:variable> 요소는 스타일시트에 전역 변수나 지역 변수를 선언하고 그 변수에 값을 줍니다. XSLT가 부작용(side-effect)을 허용하지 않기 때문에, 변수값을 한 번 주면 그 변수는 범위(scope)를 벗어날 때까지 같은 값입니다.

+

구문

+
<xsl:variable name=NAME select=EXPRESSION >
+	TEMPLATE
+</xsl:variable> 
+

필수 속성

+
+
+ name
+
+ 변수에 이름을 줍니다.
+
+

선택 속성

+
+
+ select
+
+ 변수값을 XPath 식으로 정의합니다. 요소가 템플릿을 포함하면, 이 속성은 무시합니다.
+
+

타입

+

최상위 또는 명령. 최상위 요소로 나타나면, 변수의 범위는 전역이고 문서 전체에서 접근할 수 있습니다. 템플릿 안에 나타나면, 번수의 범위는 지역이고 나타난 템플릿 안에서만 접근할 수 있습니다.

+

정의

+

XSLT section 11, Variables and Parameters

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/when/index.html b/files/ko/web/xslt/element/when/index.html new file mode 100644 index 0000000000..4d5f52d9c3 --- /dev/null +++ b/files/ko/web/xslt/element/when/index.html @@ -0,0 +1,28 @@ +--- +title: when +slug: Web/XSLT/when +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/when +--- +

{{ XsltRef() }}

+

<xsl:when> 요소는 항상 case 문처럼 동작하는 <xsl:choose> 요소 안에 나타납니다.

+

문법

+
<xsl:when test=EXPRESSION>
+	TEMPLATE
+</xsl:when>
+

필수 속성

+
+
+ test
+
+ 평가할 boolean 식을 지정합니다. 참이면, 요소의 컨텐트는 처리하고 거짓이면, 무시합니다.
+
+

선택 속성

+

없음.

+

타입

+

하위명령, 항상 <xsl:choose> 요소 안에 나타남.

+

정의

+

XSLT section 9.2, Conditional Processing with xsl:choose

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/element/with-param/index.html b/files/ko/web/xslt/element/with-param/index.html new file mode 100644 index 0000000000..cd96049cc5 --- /dev/null +++ b/files/ko/web/xslt/element/with-param/index.html @@ -0,0 +1,33 @@ +--- +title: with-param +slug: Web/XSLT/with-param +tags: + - XSLT_Reference +translation_of: Web/XSLT/Element/with-param +--- +

{{ XsltRef() }}

+

<xsl:with-param> 요소는 템플릿에 건네는 매개변수 값을 지정합니다.

+

문법

+
<xsl:with-param name=NAME select=EXPRESSION>
+	TEMPLATE
+</xsl:with-param>
+

필수 속성

+
+
+ name
+
+ 이 매개변수에 이름을 줍니다.
+
+

선택 속성

+
+
+ select
+
+ XPath 식을 거치는 매개변수 값을 정의합니다. 요소가 템플릿을 포함하면, 이 속성은 무시합니다.
+
+

타입

+

하위명령, 항상 <xsl:apply-templates>이나 code><xsl:call-template></code> 요소 안에 나타남.

+

정의

+

XSLT section 11.6, Passing Parameters to Templates

+

Gecko 지원

+

지원함.

diff --git a/files/ko/web/xslt/fallback/index.html b/files/ko/web/xslt/fallback/index.html deleted file mode 100644 index af407f4512..0000000000 --- a/files/ko/web/xslt/fallback/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: fallback -slug: Web/XSLT/fallback -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/fallback ---- -

{{ XsltRef() }}

-

<xsl:fallback> 요소는 주어진 확장(이나 결국에는 새 버전) 요소에서 지원하지 않으면 쓸 템플릿을 지정합니다.

-

문법

-
<xsl:fallback>
-	TEMPLATE
-</xsl:fallback>
-

필수 속성

-

없음.

-

선택 속성

-

없음.

-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 15, Fallback

-

Gecko 지원

-

이번에 지원 안 함.

diff --git a/files/ko/web/xslt/for-each/index.html b/files/ko/web/xslt/for-each/index.html deleted file mode 100644 index 6beb713190..0000000000 --- a/files/ko/web/xslt/for-each/index.html +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: for-each -slug: Web/XSLT/for-each -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/for-each ---- -

{{ XsltRef() }}

-

<xsl:for-each> 요소는 노드 집합을 선택하고 같은 방식으로 각 노드를 처리합니다. 노드 집합을 되풀이하(iterate)거나 현재 노드를 바꾸는데 자주 씁니다. 하나 이상의 <xsl:sort> 요소가 이 요소의 자식으로 나타나면, 처리에 앞서 정렬을 합니다. 그렇지 않으면, 노드는 문서 순으로 처리합니다.

-

문법

-
<xsl:for-each select=EXPRESSION>
-	<xsl:sort> [optional]
-	TEMPLATE
-</xsl:for-each>
-

필수 속성

-
-
- select
-
- 처리할 노드를 선택하기 위해 XPath 식을 씁니다.
-
-

선택 속성

-

없음.

-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 8, Repetition

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/if/index.html b/files/ko/web/xslt/if/index.html deleted file mode 100644 index 2c56b7d218..0000000000 --- a/files/ko/web/xslt/if/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: if -slug: Web/XSLT/if -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/if ---- -

{{ XsltRef() }}

-

<xsl:if> 요소는 test 속성과 템플릿을 포함합니다. test 속성을 참으로 평가하면, 템플릿을 처리합니다. 이것은 다른 언어의 if 문과 비슷합니다. 그러나, <tt>if-then-else</tt> 문의 기능을 다하기 위해 <xsl:when><xsl:otherwise> 자식이 하나씩 있는 <xsl:choose> 요소를 씁니다.

-

문법

-
<xsl:if test=EXPRESSION>
-	TEMPLATE
-</xsl:if>
-

필수 속성

-
-
- test
-
- Boolean 값으로 (필요하다면 boolean( )으로 정의한 규칙을 써서) 평가할 수 있는 XPath 식을 포함합니다. 값이 참이면 템플릿을 처리하고 거짓이면 아무 동작도 하지 않습니다.
-
-

선택 속성

-

없음.

-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 9.1, Conditional Processing with xsl:if

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/import/index.html b/files/ko/web/xslt/import/index.html deleted file mode 100644 index 5a469656cb..0000000000 --- a/files/ko/web/xslt/import/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: import -slug: Web/XSLT/import -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/import ---- -

{{ XsltRef() }}

-

<xsl:import> 요소는 한 스타일시트의 컨텐트를 다른 스타일시트로 가져오는 역할을 하는 최상위 요소입니다. 대체로, 가져올 스타일시트의 컨텐트는 가져오는 스타일시트의 컨텐트보다 가져오기 우선순위가 낮습니다. 이는 포함되는 스타일시트의 컨텐트가 포함하는 스타일시트의 컨텐트와 우선순위가 정확히 같은 <xsl:include>와는 뚜렷이 다릅니다.

-

문법

-
<xsl:import href=URI  />
-

필수 속성

-
-
- href
-
- 가져올 스타일시트의 URI를 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

최상위, 가져오는 스타일시트 안 <xsl:stylesheet><xsl:transform>의 자식 가운데 가장 앞에 나타나야 함.

-

정의

-

XSLT section 2.6.2, Stylesheet Import

-

Gecko 지원

-

Mozilla 1.0 현재 최상위 변수와 매개변수에 문제가 조금 있지만 대부분 지원함.

diff --git a/files/ko/web/xslt/include/index.html b/files/ko/web/xslt/include/index.html deleted file mode 100644 index 965d03a15f..0000000000 --- a/files/ko/web/xslt/include/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: include -slug: Web/XSLT/include -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/include ---- -

{{ XsltRef() }}

-

<xsl:include> 요소는 한 스타일시트의 컨텐트를 다른 스타일시트에 합칩니다. <xsl:import>와는 달리, 포함되는 스타일시트의 컨텐트는 포함하는 스타일시트의 컨텐트와 우선순위가 정확히 같습니다.

-

문법

-
<xsl:include href=URI />
-

필수 속성

-
-
- href
-
- 포함할 스타일시트의 URI를 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식으로 나타남.

-

정의

-

XSLT section 2.6.1, Stylesheet Inclusion

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/key/index.html b/files/ko/web/xslt/key/index.html deleted file mode 100644 index 733196810d..0000000000 --- a/files/ko/web/xslt/key/index.html +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: key -slug: Web/XSLT/key -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/key ---- -

{{ XsltRef() }}

-

<xsl:key> 요소는 key( ) 함수가 있는 스타일시트 어디서나 쓸 수 있는 이름 붙은 키를 선언합니다.

-

문법

-
<xsl:key name=NAME match=EXPRESSION
-	use=EXPRESSION /> 
-

필수 속성

-
-
- name
-
- 이 키에 이름을 지정합니다. QName이어야 합니다.
-
- match
-
- 이 키를 적용할 수 있는 노드를 정의합니다.
-
- use
-
- 적용가능한 각 노드에 키값을 결정하는데 쓸 수 있는 XPath 식을 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 12.2, Keys

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/message/index.html b/files/ko/web/xslt/message/index.html deleted file mode 100644 index d533a2d3c7..0000000000 --- a/files/ko/web/xslt/message/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: message -slug: Web/XSLT/message -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/message ---- -

{{ XsltRef() }}

-

<xsl:message> 요소는 (NS에서 자바스크립트 콘솔에) 메시지를 출력하고 선택에 따라 스타일시트 실행을 끝냅니다. 디버깅에 유용할 수 있습니다.

-

문법

-
<xsl:message terminate="yes" | "no" >
-	TEMPLATE
-</xsl:message>
-

필수 속성

-

없음.

-

선택 속성

-
-
- terminate
-
- "yes"로 설정하면, 실행을 끝마치는 게 좋겠다는 것을 나타냅니다. 기본값은 "no"이고 어느 경우에는 메시지가 출력하고 실행을 계속합니다.
-
-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 13, Messages

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/namespace-alias/index.html b/files/ko/web/xslt/namespace-alias/index.html deleted file mode 100644 index e085abc4e7..0000000000 --- a/files/ko/web/xslt/namespace-alias/index.html +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: namespace-alias -slug: Web/XSLT/namespace-alias -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/namespace-alias ---- -

{{ XsltRef() }}

-

<xsl:namespace-alias> 요소는 스타일시트 이름공간을 출력 트리의 다른 이름공간으로 매기는(map) 데 드물게 쓰는 방안(device)입니다. 이 요소의 가장 평범한 쓰임은 다른 스타일시트로부터 스타일시트를 만드는 것입니다. 보통 xsl:가 접두사로 붙은 (결과 트리에 단순히 복사해도 좋을) LRE(literal result element)를 처리기가 오해하는 것을 막기 위해, 결과 트리의 XSLT 이름공간에 적당하게 도로 다시 바꿀 임시 이름공간을 할당합니다.

-

문법

-
<xsl:namespace-alias stylesheet-prefix=NAME result-prefix=NAME />
-

필수 속성

-
-
- stylesheet-prefix
-
- 임시 이름공간을 지정합니다.
-
- result-prefix
-
- 결과 트리에 사용하길 바라는 이름공간을 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 7.1.1, Literal Result Elements

-

Gecko 지원

-

이번에 지원 안 함.

diff --git a/files/ko/web/xslt/number/index.html b/files/ko/web/xslt/number/index.html deleted file mode 100644 index b822625a0e..0000000000 --- a/files/ko/web/xslt/number/index.html +++ /dev/null @@ -1,173 +0,0 @@ ---- -title: number -slug: Web/XSLT/number -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/number ---- -

{{ XsltRef() }}

-

<xsl:number> 요소는 숫자를 연속으로 셉니다. 또한 숫자를 빠르게 구성하는(format) 데도 쓸 수 있습니다.

-

구문

-
<xsl:number
-	count=EXPRESSION
-	level="single" | "multiple" | "any"
-	from=EXPRESSION
-	value=EXPRESSION
-	format=FORMAT-STRING
-	lang=XML:LANG-CODE
-	letter-value="alphabetic" | "traditional"
-	grouping-separator=CHARACTER
-	grouping-size=NUMBER  />
-

필수 속성

-

없음.

-

선택 속성

-
-
- count
-
- 소스 트리에서 연속으로 셀 대상을 지정합니다. XPath 식을 씁니다.
-
-
-
- level
-
- 일련번호를 만드는데 소스 트리의 수준을 어떻게 고려해야 하는 지를 정의합니다. 유효한 값은 single, multiple, any 세 가지. 기본값은 single입니다.
-
-
-
-
-
- single
-
- 목록의 항목대로 연속으로 형제 노드를 번호 매깁니다. 처리기는 count 속성과 일치하는 ancestor-or-self 축의 첫 번째 노드로 갑니다. 그리고 나서 역시 count 속성과 일치하는 앞선 형제(preceding siblings) 노드(있다면, 한 짝인 from 속성에 이르러 멈춤)를 모두 더하여 셉니다. 일치하지 않으면, sequence는 빈 목록입니다.
-
-
-
-
-
-
-
- multiple
-
- 노드의 계층 위치를 반영하는 복합 sequence로 노드를 셉니다. 예를 들어, 1.2.2.5 (포개진 형식은 format 속성(예, A.1.1)으로 지정할 수 있습니다). 처리기는 만약 있다면 from 속성에 이르러 멈추며 현재 노드와 현재 노드의 모든 ancestors를 조사합니다. 일치하지 않으면, sequence는 빈 목록입니다.
-
-
-
-
-
-
-
- any (이번에 지원 안 함.)
-
- 수준을 무시하고 연속으로 일치하는 모든 노드를 셉니다. ancestor, self, preceding 축을 모두 고려합니다. 처리기는 현재 노드에서 시작하여 from 속성과 일치할 때 멈추며 문서 역순으로 진행합니다. 발견한 count 속성과 일치하지 않으면, sequence는 빈 목록입니다. 이 수준은 이번에 지원하지 않습니다.
-
-
-
-
-
- from
-
- 번호 매기기를 시작하거나 다시 시작하면 좋을 곳을 지정합니다. 순서는 from 특성과 일치하는 노드의 첫 번째 자손(descendant)에서 시작합니다.
-
-
-
- value
-
- 숫자에 주어진 형식을 적용합니다. 이것이 사용자 제공 숫자(노드 sequence 숫자와는 반대로)를 표준 <xsl:number> 형식으로 구성하는 빠른 방법입니다.
-
-
-
- format
-
- 만드는 숫자의 형식을 정의합니다.
-
-
-
-
-
- format="1"
-
- <tt>1 2 3 . . .</tt> (이번에 지원하는 유일한 형식)
-
-
-
-
-
-
-
- format="01"
-
- <tt>01 02 03 . . . 09 10 11 . . .</tt>
-
-
-
-
-
-
-
- format="a"
-
- <tt>a b c . . .y z aa ab . . .</tt>
-
-
-
-
-
-
-
- format="A"
-
- <tt>A B C . . . Y Z AA AB . . .</tt>
-
-
-
-
-
-
-
- format="i"
-
- <tt>i ii iii iv v . . .</tt>
-
-
-
-
-
-
-
- format="I"
-
- <tt>I II III IV V . . .</tt>
-
-
-
-
-
- lang (이번에는 지원 안 함)
-
- 문자에 기반을 둔 번호 매기기 형식에 쓰면 좋을 언어의 알파벳을 지정합니다.
-
-
-
- letter-value
-
- 문자(letter)를 쓰는 번호 매김 열(sequence) 사이를 명확하게 합니다. 어떤 언어는 문자(letter)를 쓰는 하나 이상의 번호 매기기 시스템이 있습니다. 두 시스템이 같은 토큰으로 시작하면, 모호함이 생길 수 있습니다. 이 속성은 "alphabetic"나 "traditional" 값일 수 있습니다. 기본값은 "alphabetic"입니다.
-
-
-
- grouping-separator
-
- 어떤 문자를 그룹(예로 천 단위) 구분자로 쓰면 좋을지를 지정합니다. 기본값은 쉼표(,)입니다.
-
-
-
- grouping-size
-
- 숫자 그룹을 만드는 자릿수를 나타냅니다. 기본값은 "3"입니다.
-
-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 7.7, Numbering

-

Gecko 지원

-

부분 지원. 위 해설을 보세요.

diff --git a/files/ko/web/xslt/otherwise/index.html b/files/ko/web/xslt/otherwise/index.html deleted file mode 100644 index 50249dc0b4..0000000000 --- a/files/ko/web/xslt/otherwise/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: otherwise -slug: Web/XSLT/otherwise -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/otherwise ---- -

{{ XsltRef() }}

-

<xsl:otherwise> 요소는 아무런 <xsl:when> 조건도 적용하지 않았을 때 취하면 좋을 동작을 정의하는 데 씁니다. 다른 프로그래밍 언어의 elsedefault 경우와 비슷합니다.

-

문법

-
<xsl:otherwise>
-	TEMPLATE
-</xsl:otherwise>
-

필수 속성

-

없음.

-

선택 속성

-

없음.

-

타입

-

하위명령, 템플릿 안에서 <xsl:choose> 요소의 마지막 자식으로 나타나야 함.

-

정의

-

XSLT section 9.2, Conditional Processing with xsl:choose

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/output/index.html b/files/ko/web/xslt/output/index.html deleted file mode 100644 index 97baf3f433..0000000000 --- a/files/ko/web/xslt/output/index.html +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: output -slug: Web/XSLT/output -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/output ---- -

{{ XsltRef() }}

-

<xsl:output> 요소는 출력 문서의 특성을 조절합니다. method 속성이 있는 이 요소가 Netscape에서 정확하게 기능하도록 쓸 수 있어야 합니다. 7.0 현재, method="text"는 기대한 대로 동작합니다.

-

문법

-
<xsl:output
-	method="xml" | "html" | "text"
-	version=STRING
-	encoding=STRING
-	omit-xml-declaration="yes" | "no"
-	standalone="yes" | "no"
-	doctype-public=STRING
-	doctype-system=STRING
-	cdata-section-elements=LIST-OF-NAMES
-	indent="yes" | "no"
-	media-type=STRING  />
-

필수 속성

-

없음.

-

선택 속성

-
-
- method
-
- 출력 형식을 지정합니다.
-
-
-
- version
-
- 출력 문서에 XML이나 HTML 선언의 version 속성값을 지정합니다. 이 속성은 method="html"method="xml"일 때만 씁니다.
-
-
-
- encoding
-
- 출력 문서에 encoding 속성값을 지정합니다.
-
-
-
- omit-xml-declaration
-
- 출력에 XML 선언을 포함할 지를 나타냅니다. 가능한 값은 "yes"나 "no"입니다.
-
-
-
- standalone (지원 안 함.)
-
- 있으면, standalone 선언이 출력 문서에 나타나면 좋을 지를 나타내고 그 값을 줍니다. 가능한 값은 "yes"나 "no"입니다.
-
-
-
- doctype-public
-
- 출력 문서에 DOCTYPE 선언의 PUBLIC 속성값을 지정합니다.
-
-
-
- doctype-system
-
- 출력 문서에 DOCTYPE 선언의 SYSTEM 속성값을 지정합니다.
-
-
-
- cdata-section-elements
-
- CDATA 절에 써도 좋을 요소의 텍스트 컨텐트를 나열합니다. 요소는 공백으로 구분해야 합니다.
-
-
-
- indent (지원 안 함.)
-
- 출력에 계층 구조를 나타내도록 하면 좋을 지를 지정합니다.
-
-
-
- media-type (지원 안 함.)
-
- 출력 문서의 MIME 타입을 지정합니다.
-
-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 16, Output

-

Gecko 지원

-

부분 지원. 위 해설을 보세요.

diff --git a/files/ko/web/xslt/param/index.html b/files/ko/web/xslt/param/index.html deleted file mode 100644 index e1bcf36e19..0000000000 --- a/files/ko/web/xslt/param/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: param -slug: Web/XSLT/param -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/param ---- -

{{ XsltRef() }}

-

<xsl:param> 요소는 이름과 선택에 따라 기본값으로 매개변수를 설정합니다. 최상위 요소로 쓸 때, 매개변수는 전역입니다. <xsl:template> 요소 안에서 쓰면, 매개변수는 그 템플릿에 대해 지역입니다. 이 경우에 요소는 템플릿의 첫 자식 요소여야 합니다.

-

문법

-
<xsl:param name=NAME select=EXPRESSION>
-	TEMPLATE
-</xsl:param>
-

필수 속성

-
-
- name
-
- 파라미터에 이름을 붙입니다. 이름은 QName이어야 합니다.
-
-

선택 속성

-
-
- select
-
- none으로 지정하면 기본값을 제공하는 XPath 식을 씁니다.
-
-

타입

-

명령, 최상위 요소나 템플릿 안에 나타날 수 있음.

-

정의

-

XSLT section 11, Variables and Parameters

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/preserve-space/index.html b/files/ko/web/xslt/preserve-space/index.html deleted file mode 100644 index 771ffe81d6..0000000000 --- a/files/ko/web/xslt/preserve-space/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: preserve-space -slug: Web/XSLT/preserve-space -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/preserve-space ---- -

{{ XsltRef() }}

-

<xsl:preserve-space> 요소는 공백을 보존하면 좋을 소스 문서의 요소를 정의합니다. 하나 이상의 요소가 있으면, 공백 문자로 이름을 구분하세요. 공백 보존하기가 기본 설정이므로 이 요소는 오직 <xsl:strip-space> 요소와 거꾸로 동작하기 위해 쓸 필요가 있습니다.

-

문법

-
<xsl:preserve-space elements=LIST-OF-ELEMENT-NAMES  />
-

필수 속성

-
-
- elements
-
- 공백을 보존하면 좋을 요소를 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 3.4, Whitespace Stripping

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/processing-instruction/index.html b/files/ko/web/xslt/processing-instruction/index.html deleted file mode 100644 index ad1c6eaaf6..0000000000 --- a/files/ko/web/xslt/processing-instruction/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: processing-instruction -slug: Web/XSLT/processing-instruction -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/processing-instruction ---- -

{{ XsltRef() }}

-

<xsl:processing-instruction> 요소는 출력 문서에 처리 명령을 씁니다.

-

문법

-

<xsl:processing-instruction name=NAME> TEMPLATE </xsl:processing-instruction>

-

필수 속성

-
-
- name
-
- 처리 명령에 이름을 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 7.3, Creating Processing Instructions

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/sort/index.html b/files/ko/web/xslt/sort/index.html deleted file mode 100644 index 22217ec61f..0000000000 --- a/files/ko/web/xslt/sort/index.html +++ /dev/null @@ -1,55 +0,0 @@ ---- -title: sort -slug: Web/XSLT/sort -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/sort ---- -

{{ XsltRef() }}

-

<xsl:sort> 요소는 <xsl:apply-templates><xsl:for-each>가 선택한 노드에 정렬키를 정의하고 노드를 처리할 순서를 결정합니다.

-

문법

-
<xsl:sort
-	select=EXPRESSION
-	order="ascending" | "descending"
-	case-order="upper-first"| "lower-first"
-	lang=XML:LANG-CODE
-	data-type="html" | "xml" | "text" /> 
-

필수 속성

-

없음.

-

선택 속성

-
-
- select
-
- 정렬할 노드를 지정하는 XPath 식을 씁니다.
-
-
-
- order
-
- "ascending"나 "descending"으로 처리하면 좋을 노드를 지정합니다. 기본값은 "ascending"입니다.
-
-
-
- case-order
-
- 처음에 오는 게 대문자인지 소문자인지를 나타냅니다. 가능한 값은 "upper-first"와 "lower-first"입니다.
-
-
-
- lang
-
- 어떤 언어를 정렬에 쓸지를 지정합니다.
-
-
-
- data-type
-
- 어떤 항목을 알파벳순이나 숫자순으로 순서 매길지를 정의합니다. 가능한 값은 "text"와 기본값인 "text"가 있는 "number"입니다.
-
-

타입

-

하위명령, 항상 <xsl:for-each>의 자식으로 나타나고 고유(proper) 템플릿이나 <xsl:apply-templates> 앞에 나타나야 함.

-

정의

-

XSLT section 10, Sorting

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/strip-space/index.html b/files/ko/web/xslt/strip-space/index.html deleted file mode 100644 index 7bbc485afd..0000000000 --- a/files/ko/web/xslt/strip-space/index.html +++ /dev/null @@ -1,26 +0,0 @@ ---- -title: strip-space -slug: Web/XSLT/strip-space -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/strip-space ---- -

{{ XsltRef() }}

-

<xsl:strip-space> 요소는 공백을 지웠으면 하는 소스 문서의 요소를 정의합니다.

-

문법

-
<xsl:strip-space elements=LIST-OF-ELEMENT-NAMES  />
-

필수 속성

-
-
- elements
-
- 지우면 좋을 공백뿐인 텍스트 노드가 있는 소스의 요소 목록(빈칸으로 구분)을 지정합니다.
-
-

선택 속성

-

없음.

-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 3.4, Whitespace Stripping

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/stylesheet/index.html b/files/ko/web/xslt/stylesheet/index.html deleted file mode 100644 index 0119cec645..0000000000 --- a/files/ko/web/xslt/stylesheet/index.html +++ /dev/null @@ -1,52 +0,0 @@ ---- -title: stylesheet -slug: Web/XSLT/stylesheet -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/stylesheet ---- -

{{ XsltRef() }}

-

<xsl:stylesheet>(나 동등한 <xsl:transform>) 요소는 스타일시트의 최외곽 요소입니다.

-

이름공간 선언

-

pseudo 속성은 XSLT 스타일시트로 문서를 식별하기 위해 필요합니다. 대체로 이는 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"입니다.

-

문법

-
<xsl:stylesheet
-	version=NUMBER
-	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-	id=NAME
-	extension-element-prefixes=LIST-OF-NAMES
-	exclude-result-prefixes=LIST-OF-NAMES>
-		ENTIRE STYLESHEET
-</xsl:stylesheet>
-

필수 속성

-
-
- version
-
- 이 스타일시트에 필요한 XSLT의 버전을 지정합니다.
-
-

선택 속성

-
-
- id (7.0 현재 오직 inline DTD가 명시하여 호출하는 경우만 지원함.)
-
- 이 스타일시트에 id를 지정합니다. 이는 스타일시트를 다른 XML 문서에 포함할 때 가장 자주 씁니다.
-
-
-
- extension-element-prefixes (지원 안 함.)
-
- 이 문서의 확장 요소에 빈칸으로 구분한 이름공간 접두사를 지정합니다.
-
-
-
- exclude-result-prefixes
-
- 이 문서에 쓸 출력 문서에 보내지 않았으면 하는 이름공간을 지정합니다. 목록은 공백으로 구분합니다.
-
-

타입

-

필수 최외곽 스타일시트 요소.

-

정의

-

XSLT section 2.2, Stylesheet Element

-

Gecko 지원

-

조금 지원. 위 해설을 보세요.

diff --git a/files/ko/web/xslt/template/index.html b/files/ko/web/xslt/template/index.html deleted file mode 100644 index 1ce4a66d2b..0000000000 --- a/files/ko/web/xslt/template/index.html +++ /dev/null @@ -1,51 +0,0 @@ ---- -title: template -slug: Web/XSLT/template -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/template ---- -

{{ XsltRef() }}

-

<xsl:template> 요소는 출력 생성 템플릿을 정의합니다. 이 요소는 match 속성이나 name 속성 집합이 있어야 합니다.

-

문법

-
<xsl:template
-	match=PATTERN
-	name=NAME
-	mode=NAME
-	priority=NUMBER>
-	<xsl:param> [optional]
-	TEMPLATE
-</xsl:template>
-

필수 속성

-

없음.

-

선택 속성

-
-
- match
-
- 이 템플릿을 쓰면 좋을 요소를 결정하는 패턴을 지정합니다. name 속성이 없다면, 필수 속성입니다.
-
-
-
- name
-
- <xsl:call-template> 요소가 호출할 수 있는 이 템플릿에 이름을 지정합니다.
-
-
-
- mode
-
- 이 템플릿에 <xsl:apply-templates> 요소의 속성과 일치할 수 있는 특유한 모드를 지정합니다. 이는 같은 정보를 다양한 방식으로 처리하는데 유용합니다.
-
-
-
- priority
-
- 이 템플릿에 숫자로 된 우선권을 지정합니다. 이는 Infinity와 다른 아무 숫자일 수 있습니다. 처리기는 하나 이상의 템플릿이 같은 노드와 일치할 때 이 숫자를 씁니다.
-
-

타입

-

최상위, <xsl:stylesheet><xsl:transform>의 자식이어야 함.

-

정의

-

XSLT section 5.3, Defining Template Rules

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/text/index.html b/files/ko/web/xslt/text/index.html deleted file mode 100644 index 71bd6eceda..0000000000 --- a/files/ko/web/xslt/text/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: text -slug: Web/XSLT/text -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/text ---- -

{{ XsltRef() }}

-

<xsl:text> 요소는 출력 트리에 리터럴(literal) 텍스트를 씁니다. #PCDATA, 리터럴 텍스트, 엔티티 참조를 포함할 지도 모릅니다.

-

구문

-
<xsl:text disable-output-escaping="yes" | "no">
-	TEXT
-</xsl:text> 
-

필수 속성

-

없음.

-

선택 속성

-
-
- disable-output-escaping (Netscape은 변환 결과를 "output" 아래에 직렬하지 않습니다. 그래서 이 속성은 본래 문맥에서는 무의미합니다. HTML 엔티티를 출력하기 위해서는, 대신 숫자값을 쓰세요. 보기 &nbsp 대신 &#160)
-
- 특수 문자를 출력에 쓸 때 해석할(escape) 지를 지정합니다. 가능한 값은 "yes"나 "no"입니다. 예를 들어, "yes"로 하면, <tt>></tt> 문자의 출력은 "&gt"가 아니라 >입니다.
-
-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 7.2, Creating Text

-

Gecko 지원

-

적힌 대로 지원함

diff --git a/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/index.html b/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/index.html deleted file mode 100644 index c3ee407348..0000000000 --- a/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/index.html +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: The XSLT/JavaScript Interface in Gecko -slug: Web/XSLT/The_XSLT_JavaScript_Interface_in_Gecko -tags: - - DOM - - XSLT -translation_of: Web/XSLT/XSLT_JS_interface_in_Gecko ---- -
    -
  1. 개요
  2. -
  3. The XSLT/JavaScript Interface in Gecko:JavaScript/XSLT Bindings
  4. -
  5. The XSLT/JavaScript Interface in Gecko:Basic Example
  6. -
  7. The XSLT/JavaScript Interface in Gecko:Setting Parameters
  8. -
  9. The XSLT/JavaScript Interface in Gecko:Advanced Example
  10. -
  11. The XSLT/JavaScript Interface in Gecko:Interface List
  12. -
  13. The XSLT/JavaScript Interface in Gecko:Resources
  14. -
diff --git a/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/introduction/index.html b/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/introduction/index.html deleted file mode 100644 index dd74a5998d..0000000000 --- a/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/introduction/index.html +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Introduction -slug: Web/XSLT/The_XSLT_JavaScript_Interface_in_Gecko/Introduction -translation_of: Web/XSLT/XSLT_JS_interface_in_Gecko/Introduction ---- -

개요

-

XSLT를 지원하는 현대의 브라우저를 가지고, 개발자는 XSLT가 제공하는 힘에 접근하기 위해 자바스크립트를 지금 사용할 수 있다. 자바스크립트는 웹 프로그램이 XML자료를 로드하고, XSLT를 통해 표현가능한 형태로 처리하고 존재하는 문서안에 넣는 것을 가능하게 한다. XML자료는 아무런 표현자료 없이 오직 날 정보만을 포함하므로, 다이얼업에서도 빠르게 로드할 수 있다.

-

XSLT는 저자가 직접 문서구조를 다루는 것을 허용한다. 예로, XSLT는 요소의 재배열과 정렬을 수행한다. 또 결과 문서구조의 좀더 세분된 제어를 제공한다.

-

Mozilla 1.2현재 Gecko는 자바스크립트가 XSLT 프로세서를 만드는 것을 가능하게 한다. 이 글은 Gecko에서 XSLT/JavaScript binding을 다룬다. 이들은 Netscape 7.0x에서는 가능하지 않지만 Netscape 7.1에서는 가능하다.

-

{{ languages( { "en": "en/The_XSLT//JavaScript_Interface_in_Gecko/Introduction" } ) }}

diff --git a/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/setting_parameters/index.html b/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/setting_parameters/index.html deleted file mode 100644 index fb2f456e70..0000000000 --- a/files/ko/web/xslt/the_xslt_javascript_interface_in_gecko/setting_parameters/index.html +++ /dev/null @@ -1,23 +0,0 @@ ---- -title: Setting Parameters -slug: Web/XSLT/The_XSLT_JavaScript_Interface_in_Gecko/Setting_Parameters -translation_of: Web/XSLT/XSLT_JS_interface_in_Gecko/Setting_Parameters ---- -

Parameter 설정

-

이미 코딩된 .xsl과 .xml 파일을 이용하여 변환을 실행하는 것은 꽤 쓸모있는데, .xml파일을 JavaScript로부터 설정하는 것은 좀 더 쓸모있다.예로, JavaScript와 XSLT는 XML데이터를 정렬하여 표시하는 데 쓸 수 있다. 정렬은 오름차순과 내림차순을 바꿀 수 있어야 할 것이다. XSLT는 xsl:param 요소를 제공하는데, 그것은 xsl:stylesheet 요소의 자식이다. XSLTProcessor()는 이 파라메터와 상호작용하기 위해 3가지 JavaScript 메소드를 제공한다: setParameter, getParameter, removeParameter.

-


- 그들 모두 첫번째 아규먼트로 xsl:param 의 namespace URI를 얻는다. (보통 그 param은 기본 namespace로 떨어져, null에 전달되어 충분하다) xsl:param의 local name이 두번째 아규먼트다. setParameter는 세번쩨 아규먼트를 필요로 한다 - 즉 파라미터가 맞추어질 값.

-

그림 7 : Parameters

-
XSLT:
-<xsl:param name="myOrder" />
-
-JavaScript:
-
-var sortVal = xsltProcessor.getParameter(null, "myOrder");
-
-if (sortVal == "" || sortVal == "descending")
-  xsltProcessor.setParameter(null, "myOrder", "ascending");
-else
-  xsltProcessor.setParameter(null, "myOrder", "descending");
-
-

{{ languages( { "en": "en/The_XSLT//JavaScript_Interface_in_Gecko/Setting_Parameters" } ) }}

diff --git a/files/ko/web/xslt/transform/index.html b/files/ko/web/xslt/transform/index.html deleted file mode 100644 index 8071ebdad3..0000000000 --- a/files/ko/web/xslt/transform/index.html +++ /dev/null @@ -1,11 +0,0 @@ ---- -title: transform -slug: Web/XSLT/transform -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/transform ---- -

{{ XsltRef() }}

-

<xsl:transform> 요소는 <xsl:stylesheet> 요소와 정확히 같습니다.

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/value-of/index.html b/files/ko/web/xslt/value-of/index.html deleted file mode 100644 index 90f1777bed..0000000000 --- a/files/ko/web/xslt/value-of/index.html +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: value-of -slug: Web/XSLT/value-of -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/value-of ---- -

{{ XsltRef() }}

-

<xsl:value-of> 요소는 XPath 식을 평가하여 그것을 문자열로 바꾸고 문자열을 결과 트리에 씁니다.

-

구문

-
<xsl:value-of select=EXPRESSION disable-output-escaping="yes" | "no"  />
-

필수 속성

-
-
- select
-
- 평가하고 출력 트리에 쓸 XPath 식을 지정합니다.
-
-

선택 속성

-
-
- disable-output-escaping (Netscape은 변환 결과를 "output" 아래에 직렬하지 않습니다. 그래서 이 속성은 본래 문맥에서는 무의미합니다. HTML 엔티티를 출력하기 위해서는, 대신 숫자값을 쓰세요. 보기 &nbsp 대신 &#160)
-
- 특수 문자를 출력에 쓸 때 해석할(escape) 지를 지정합니다. 가능한 값은 "yes"나 "no"입니다. 예를 들어, "yes"로 하면, <tt>></tt> 문자의 출력은 "&gt"가 아니라 >입니다.
-
-

타입

-

명령, 템플릿 안에 나타남.

-

정의

-

XSLT section 7.6.1, Generating Text with xsl:value-of

-

Gecko 지원

-

위 경우를 빼고는 지원함.

diff --git a/files/ko/web/xslt/variable/index.html b/files/ko/web/xslt/variable/index.html deleted file mode 100644 index 8568f70b20..0000000000 --- a/files/ko/web/xslt/variable/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: variable -slug: Web/XSLT/variable -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/variable ---- -

{{ XsltRef() }}

-

<xsl:variable> 요소는 스타일시트에 전역 변수나 지역 변수를 선언하고 그 변수에 값을 줍니다. XSLT가 부작용(side-effect)을 허용하지 않기 때문에, 변수값을 한 번 주면 그 변수는 범위(scope)를 벗어날 때까지 같은 값입니다.

-

구문

-
<xsl:variable name=NAME select=EXPRESSION >
-	TEMPLATE
-</xsl:variable> 
-

필수 속성

-
-
- name
-
- 변수에 이름을 줍니다.
-
-

선택 속성

-
-
- select
-
- 변수값을 XPath 식으로 정의합니다. 요소가 템플릿을 포함하면, 이 속성은 무시합니다.
-
-

타입

-

최상위 또는 명령. 최상위 요소로 나타나면, 변수의 범위는 전역이고 문서 전체에서 접근할 수 있습니다. 템플릿 안에 나타나면, 번수의 범위는 지역이고 나타난 템플릿 안에서만 접근할 수 있습니다.

-

정의

-

XSLT section 11, Variables and Parameters

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/when/index.html b/files/ko/web/xslt/when/index.html deleted file mode 100644 index 4d5f52d9c3..0000000000 --- a/files/ko/web/xslt/when/index.html +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: when -slug: Web/XSLT/when -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/when ---- -

{{ XsltRef() }}

-

<xsl:when> 요소는 항상 case 문처럼 동작하는 <xsl:choose> 요소 안에 나타납니다.

-

문법

-
<xsl:when test=EXPRESSION>
-	TEMPLATE
-</xsl:when>
-

필수 속성

-
-
- test
-
- 평가할 boolean 식을 지정합니다. 참이면, 요소의 컨텐트는 처리하고 거짓이면, 무시합니다.
-
-

선택 속성

-

없음.

-

타입

-

하위명령, 항상 <xsl:choose> 요소 안에 나타남.

-

정의

-

XSLT section 9.2, Conditional Processing with xsl:choose

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/with-param/index.html b/files/ko/web/xslt/with-param/index.html deleted file mode 100644 index cd96049cc5..0000000000 --- a/files/ko/web/xslt/with-param/index.html +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: with-param -slug: Web/XSLT/with-param -tags: - - XSLT_Reference -translation_of: Web/XSLT/Element/with-param ---- -

{{ XsltRef() }}

-

<xsl:with-param> 요소는 템플릿에 건네는 매개변수 값을 지정합니다.

-

문법

-
<xsl:with-param name=NAME select=EXPRESSION>
-	TEMPLATE
-</xsl:with-param>
-

필수 속성

-
-
- name
-
- 이 매개변수에 이름을 줍니다.
-
-

선택 속성

-
-
- select
-
- XPath 식을 거치는 매개변수 값을 정의합니다. 요소가 템플릿을 포함하면, 이 속성은 무시합니다.
-
-

타입

-

하위명령, 항상 <xsl:apply-templates>이나 code><xsl:call-template></code> 요소 안에 나타남.

-

정의

-

XSLT section 11.6, Passing Parameters to Templates

-

Gecko 지원

-

지원함.

diff --git a/files/ko/web/xslt/xslt_js_interface_in_gecko/index.html b/files/ko/web/xslt/xslt_js_interface_in_gecko/index.html new file mode 100644 index 0000000000..c3ee407348 --- /dev/null +++ b/files/ko/web/xslt/xslt_js_interface_in_gecko/index.html @@ -0,0 +1,17 @@ +--- +title: The XSLT/JavaScript Interface in Gecko +slug: Web/XSLT/The_XSLT_JavaScript_Interface_in_Gecko +tags: + - DOM + - XSLT +translation_of: Web/XSLT/XSLT_JS_interface_in_Gecko +--- +
    +
  1. 개요
  2. +
  3. The XSLT/JavaScript Interface in Gecko:JavaScript/XSLT Bindings
  4. +
  5. The XSLT/JavaScript Interface in Gecko:Basic Example
  6. +
  7. The XSLT/JavaScript Interface in Gecko:Setting Parameters
  8. +
  9. The XSLT/JavaScript Interface in Gecko:Advanced Example
  10. +
  11. The XSLT/JavaScript Interface in Gecko:Interface List
  12. +
  13. The XSLT/JavaScript Interface in Gecko:Resources
  14. +
diff --git a/files/ko/web/xslt/xslt_js_interface_in_gecko/introduction/index.html b/files/ko/web/xslt/xslt_js_interface_in_gecko/introduction/index.html new file mode 100644 index 0000000000..dd74a5998d --- /dev/null +++ b/files/ko/web/xslt/xslt_js_interface_in_gecko/introduction/index.html @@ -0,0 +1,10 @@ +--- +title: Introduction +slug: Web/XSLT/The_XSLT_JavaScript_Interface_in_Gecko/Introduction +translation_of: Web/XSLT/XSLT_JS_interface_in_Gecko/Introduction +--- +

개요

+

XSLT를 지원하는 현대의 브라우저를 가지고, 개발자는 XSLT가 제공하는 힘에 접근하기 위해 자바스크립트를 지금 사용할 수 있다. 자바스크립트는 웹 프로그램이 XML자료를 로드하고, XSLT를 통해 표현가능한 형태로 처리하고 존재하는 문서안에 넣는 것을 가능하게 한다. XML자료는 아무런 표현자료 없이 오직 날 정보만을 포함하므로, 다이얼업에서도 빠르게 로드할 수 있다.

+

XSLT는 저자가 직접 문서구조를 다루는 것을 허용한다. 예로, XSLT는 요소의 재배열과 정렬을 수행한다. 또 결과 문서구조의 좀더 세분된 제어를 제공한다.

+

Mozilla 1.2현재 Gecko는 자바스크립트가 XSLT 프로세서를 만드는 것을 가능하게 한다. 이 글은 Gecko에서 XSLT/JavaScript binding을 다룬다. 이들은 Netscape 7.0x에서는 가능하지 않지만 Netscape 7.1에서는 가능하다.

+

{{ languages( { "en": "en/The_XSLT//JavaScript_Interface_in_Gecko/Introduction" } ) }}

diff --git a/files/ko/web/xslt/xslt_js_interface_in_gecko/setting_parameters/index.html b/files/ko/web/xslt/xslt_js_interface_in_gecko/setting_parameters/index.html new file mode 100644 index 0000000000..fb2f456e70 --- /dev/null +++ b/files/ko/web/xslt/xslt_js_interface_in_gecko/setting_parameters/index.html @@ -0,0 +1,23 @@ +--- +title: Setting Parameters +slug: Web/XSLT/The_XSLT_JavaScript_Interface_in_Gecko/Setting_Parameters +translation_of: Web/XSLT/XSLT_JS_interface_in_Gecko/Setting_Parameters +--- +

Parameter 설정

+

이미 코딩된 .xsl과 .xml 파일을 이용하여 변환을 실행하는 것은 꽤 쓸모있는데, .xml파일을 JavaScript로부터 설정하는 것은 좀 더 쓸모있다.예로, JavaScript와 XSLT는 XML데이터를 정렬하여 표시하는 데 쓸 수 있다. 정렬은 오름차순과 내림차순을 바꿀 수 있어야 할 것이다. XSLT는 xsl:param 요소를 제공하는데, 그것은 xsl:stylesheet 요소의 자식이다. XSLTProcessor()는 이 파라메터와 상호작용하기 위해 3가지 JavaScript 메소드를 제공한다: setParameter, getParameter, removeParameter.

+


+ 그들 모두 첫번째 아규먼트로 xsl:param 의 namespace URI를 얻는다. (보통 그 param은 기본 namespace로 떨어져, null에 전달되어 충분하다) xsl:param의 local name이 두번째 아규먼트다. setParameter는 세번쩨 아규먼트를 필요로 한다 - 즉 파라미터가 맞추어질 값.

+

그림 7 : Parameters

+
XSLT:
+<xsl:param name="myOrder" />
+
+JavaScript:
+
+var sortVal = xsltProcessor.getParameter(null, "myOrder");
+
+if (sortVal == "" || sortVal == "descending")
+  xsltProcessor.setParameter(null, "myOrder", "ascending");
+else
+  xsltProcessor.setParameter(null, "myOrder", "descending");
+
+

{{ languages( { "en": "en/The_XSLT//JavaScript_Interface_in_Gecko/Setting_Parameters" } ) }}

diff --git "a/files/ko/web/\354\260\270\354\241\260/api/index.html" "b/files/ko/web/\354\260\270\354\241\260/api/index.html" deleted file mode 100644 index 363fa9d3e9..0000000000 --- "a/files/ko/web/\354\260\270\354\241\260/api/index.html" +++ /dev/null @@ -1,65 +0,0 @@ ---- -title: Web API 설명집 -slug: Web/참조/API -tags: - - API - - 대문 - - 웹 - - 편람 -translation_of: Web/Reference/API ---- -

여러분이 알고 있는 웹에는 여러 유용한 작업을 수행할 수 있는 다양한 API가 제공됩니다. 이러한 API는 자바스크립트(JavaScript) 코드를 사용하여 접근할 수 있으며 {{domxref("window")}}나 {{domxref("element")}}에 대한 간단한 작업에서부터 WebGL이나 Web Audio와 같은 API를 사용해 복잡한 그래픽 및 오디오 효과를 만들어내는 것까지 가능합니다.

- -

모든 API에 대한 각각의 인터페이스는 색인에 열거돼 있습니다.

- -

또한 이벤트 레퍼런스에 이용가능한 모든 이벤트 목록도 있습니다.

- -
-
-
-
문서 객체 모델(Document Object Model)
-
DOM은 문서를 조회하거나 수정할 수 있는 API입니다. 문서의 {{domxref("Node")}} 및 {{domxref("Element")}}를 조작할 수 있습니다. HTML, XML, SVG는 DOM을 확장함으로써 각각의 실제적인 요소(element)를 조작합니다.
-
디바이스 API
-
본 API는 웹 페이지 및 애플리케이션에서 사용할 수 있는 다양한 하드웨어 기능을 조작합니다. 예: 주변 조명 센서 API, 배터리 상태 API, 지리적 위치 API, 포인터 잠금 API, 근접 API, 디바이스 방향성 API, 화면 방향성 API, 진동 API.
-
커뮤니케이션 API
-
본 API는 웹 페이지 및 애플리케이션에서 다른 페이지나 기기와 통신할 수 있습니다. 예: 네트워크 정보 API, 웹 알림, 단순 푸시 API.
-
데이터 관리 API
-
본 API는 사용자 데이터를 보관하고 관리할 수 있습니다. 예: FileHandle API, IndexedDB.
-
- -

이러한 API는 어떠한 웹 사이트나 앱에서도 사용할 수 있지만 한정 권한 및 공인 애플리케이션에서는 더 강력한 Mozilla API 셋을 사용하실 수 있습니다.

- -
-
한정 권한 API
-
한정 권한 애플리케이션은 설치 방식 앱으로서 사용자가 특정 권리를 허용한 것입니다. 한정 권한 API로는 TCP 소켓 API, 주소록 API, 디바이스 스토리지 API, 브라우저 API 등이 있습니다.
-
공인 API
-
공인된 애플리케이션은 파이어폭스 OS와 같은 운영체제에 중요한 조작을 수행하는 저층(low-level) 애플리케이션입니다. 한정 권한이 낮은 애플리케이션은 Web Activities를 사용하여 이러한 애플리케이션과 소통합니다. 공인 API로는 블루투스 API, 모바일 연결 API, 네트워크 상태 API, 전화 기능,WebSMS, 와이파이 정보 API, 카메라 API, 전원 관리 API, 설정 API, 대기 API,사용 권한 API, 시간/시계 API 등이 있습니다.
-
-
- -
-

커뮤니티

- -

저희 메일링 리스트나 뉴스그룹를 통해 Web API 커뮤니티에 참여하세요.

- - - -

IRC에서 #webapi 채널의 실시간 토론도 꼭 참여하세요.

- - - -

다음 주제도 확인해보세요.

- - -
-
- -

 

diff --git "a/files/ko/web/\354\260\270\354\241\260/index.html" "b/files/ko/web/\354\260\270\354\241\260/index.html" deleted file mode 100644 index f8d1a1dc35..0000000000 --- "a/files/ko/web/\354\260\270\354\241\260/index.html" +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: 웹 기술 문서 목록 -slug: Web/참조 -tags: - - Landing - - Reference - - Web -translation_of: Web/Reference ---- -

{{draft()}}
- 오픈 웹은 많은 기술을 사용하여 구축됩니다. 이 기술들을 사용하기 위해서는 적절한 지식이 필요합니다.
- 아래에서 각각의 참조 자료에 대한 링크를 찾아볼 수 있습니다.

- -

웹 기술들

- -

여러분에게 웹과 함께 시작하기를 추천하지만, 필수는 아닙니다.

- -
-
HTML — Structuring the web
-
하이퍼텍스트 마크업언어(HyperText Markup Language)는 의미론적으로 웹 페이지의 콘텐츠(마크업)를 잘 구조화된 형식으로 의미론적으로 정의하고 표현하는데 사용됩니다. HTML은 HTML 요소(HTML elements)라고 불리는 불록으로 구성된 구조화된 문서를 작성하는 방법을 제공합니다. HTML요소는 태그로 구분되며, 꺽쇠괄호(<>)를 사용하여 표현합니다. 일부는 페이지에 직접 내용을 소개하고, 다른 일부는 문서 텍스트에 대한 정보를 제공하고, 다른 태그는 하위 요소로 포함할 수 있습니다. 분명히, 브라우저는 페이지 내용을 해석하는데 사용하기 때문에, 그대로 문서에 보여주지 않습니다.
-
- HTML 소개| HTML 배우기 | HTML5 | 개발자 가이드 | HTML 요소 레퍼런스 | HTML 참조
-
CSS — Styling the web
-
Cascading Style Sheets 는 웹 컨텐츠의 모양을 꾸미는데 사용합니다.
-
- CSS 소개 | CSS 시작하기 | CSS 배우기 | CSS3 | 개발자 가이드 | 일반적인 CSS 질문들 | CSS 참조
-
JavaScript — Dynamic client-side scripting
-
JavaScript 프로그래밍 언어는 사용자와의 대화식 이용 및 그외 동적 기능을 웹 사이트에 추가하는데 사용됩니다.
-
자바스크립트 배우기 | 개발자 가이드 | 자바스크립트 참조
-
-- cgit v1.2.3-54-g00ecf